diff --git a/Classes/Swift/Chat/Views/ChatConversationTableViewSwift.swift b/Classes/Swift/Chat/Views/ChatConversationTableViewSwift.swift index 6851bd662..dc831b8ac 100644 --- a/Classes/Swift/Chat/Views/ChatConversationTableViewSwift.swift +++ b/Classes/Swift/Chat/Views/ChatConversationTableViewSwift.swift @@ -383,6 +383,18 @@ class ChatConversationTableViewSwift: UIViewController, UICollectionViewDataSour cell.myEmojisView.isHidden = false cell.myImageView.isHidden = true cell.optionLabel.isHidden = true + + cell.myEmojiButton1.layer.cornerRadius = 10 + cell.myEmojiButton1.backgroundColor = VoipTheme.light_grey_color + cell.myEmojiButton2.layer.cornerRadius = 10 + cell.myEmojiButton2.backgroundColor = VoipTheme.light_grey_color + cell.myEmojiButton3.layer.cornerRadius = 10 + cell.myEmojiButton3.backgroundColor = VoipTheme.light_grey_color + cell.myEmojiButton4.layer.cornerRadius = 10 + cell.myEmojiButton4.backgroundColor = VoipTheme.light_grey_color + cell.myEmojiButton5.layer.cornerRadius = 10 + cell.myEmojiButton5.backgroundColor = VoipTheme.light_grey_color + cell.myEmojiButton1.onClick { do { let messageReaction = try message.createReaction(utf8Reaction: "❤️") diff --git a/Classes/Swift/Chat/Views/DropDownCell.xib b/Classes/Swift/Chat/Views/DropDownCell.xib index 219172ebc..f8b5681c1 100644 --- a/Classes/Swift/Chat/Views/DropDownCell.xib +++ b/Classes/Swift/Chat/Views/DropDownCell.xib @@ -36,34 +36,44 @@ diff --git a/Classes/Swift/Chat/Views/Fragments/ReactionCell.swift b/Classes/Swift/Chat/Views/Fragments/ReactionCell.swift new file mode 100644 index 000000000..b24c3b23e --- /dev/null +++ b/Classes/Swift/Chat/Views/Fragments/ReactionCell.swift @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2010-2020 Belledonne Communications SARL. + * + * This file is part of linphone-iphone + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +import UIKit +import Foundation +import SnapKit +import linphonesw + +class ReactionCell: UITableViewCell { + + // Layout Constants + static let cell_height = 50.0 + let avatar_left_margin = 15.0 + let texts_left_margin = 15.0 + let avatar_size = 35.0 + + let avatar = Avatar(color:VoipTheme.primaryTextColor, textStyle: VoipTheme.call_generated_avatar_small) + let displayName = StyledLabel(VoipTheme.conference_participant_name_font) + let displayEmoji = StyledLabel(VoipTheme.conference_participant_name_font) + + + var owningParticpantsListView : ParticipantsListView? = nil + + var reactionData: ChatMessageReaction? = nil { + didSet { + if let data = reactionData { + avatar.fillFromAddress(address: data.fromAddress!) + displayName.text = data.fromAddress!.addressBookEnhancedDisplayName() + displayEmoji.text = data.body + } + } + } + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + contentView.height(ReactionCell.cell_height).matchParentSideBorders().done() + + addSubview(avatar) + avatar.size(w: avatar_size, h: avatar_size).centerY().alignParentLeft(withMargin: avatar_left_margin).done() + + // Name Address + + let nameAddress = UIStackView() + nameAddress.addArrangedSubview(displayName) + nameAddress.axis = .vertical + addSubview(nameAddress) + nameAddress.toRightOf(avatar,withLeftMargin:texts_left_margin).centerY().done() + + + addSubview(displayEmoji) + displayEmoji.alignParentRight(withMargin: avatar_left_margin*2).centerY().done() + + contentView.backgroundColor = .clear + backgroundColor = .clear + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Classes/Swift/Chat/Views/Fragments/SheetViewController.swift b/Classes/Swift/Chat/Views/Fragments/SheetViewController.swift index b213cf69b..d2a1c28e7 100644 --- a/Classes/Swift/Chat/Views/Fragments/SheetViewController.swift +++ b/Classes/Swift/Chat/Views/Fragments/SheetViewController.swift @@ -35,7 +35,19 @@ final class SheetViewController: UIViewController { private var currentPosition = 0 private var tabStyle = SlidingTabStyle.fixed private let heightHeader = 40 - + var chatMessage : ChatMessage + + /// Put your custom argument labels here, not inside the `required init?` + init(chatMessageInit: ChatMessage) { + self.chatMessage = chatMessageInit + super.init(nibName: nil, bundle: nil) + } + + /// This is in case the View Controller is loaded from the Storyboard + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + override func viewDidLoad() { super.viewDidLoad() setupUI() @@ -43,24 +55,45 @@ final class SheetViewController: UIViewController { private func setupUI(){ // view - view.backgroundColor = .white + view.backgroundColor = VoipTheme.voipBackgroundBWColor.get() navigationController?.navigationBar.barTintColor = .orange navigationController?.navigationBar.isTranslucent = false navigationController?.navigationBar.shadowImage = UIImage() navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white] navigationController?.navigationBar.barStyle = .black - - // slidingTab - addItem(item: SimpleItemViewControllerOne(), title: "REACTIONS") - addItem(item: SimpleItemViewControllerOne(), title: "❤️") - addItem(item: SimpleItemViewControllerOne(), title: "👍") - addItem(item: SimpleItemViewControllerOne(), title: "😂") - addItem(item: SimpleItemViewControllerOne(), title: "😮") - addItem(item: SimpleItemViewControllerOne(), title: "😢") - setHeaderActiveColor(color: .orange) // default blue - setStyle(style: .fixed) // default fixed - build() + + if chatMessage.reactions.count <= 1 { + addItem(item: SimpleItemViewController(chatMessageReactionsListInit: chatMessage.reactions), title: "\(chatMessage.reactions.count) REACTION") + } else { + addItem(item: SimpleItemViewController(chatMessageReactionsListInit: chatMessage.reactions), title: "\(chatMessage.reactions.count) REACTIONS") + } + + let reaction1Count = chatMessage.reactions.filter({$0.body == "❤️"}).count + let reaction2Count = chatMessage.reactions.filter({$0.body == "👍"}).count + let reaction3Count = chatMessage.reactions.filter({$0.body == "😂"}).count + let reaction4Count = chatMessage.reactions.filter({$0.body == "😮"}).count + let reaction5Count = chatMessage.reactions.filter({$0.body == "😢"}).count + + if reaction1Count > 0 { + addItem(item: SimpleItemViewController(chatMessageReactionsListInit: chatMessage.reactions.filter({$0.body == "❤️"})), title: "❤️ \(reaction1Count)") + } + if reaction2Count > 0 { + addItem(item: SimpleItemViewController(chatMessageReactionsListInit: chatMessage.reactions.filter({$0.body == "👍"})), title: "👍 \(reaction2Count)") + } + if reaction3Count > 0 { + addItem(item: SimpleItemViewController(chatMessageReactionsListInit: chatMessage.reactions.filter({$0.body == "😂"})), title: "😂 \(reaction3Count)") + } + if reaction4Count > 0 { + addItem(item: SimpleItemViewController(chatMessageReactionsListInit: chatMessage.reactions.filter({$0.body == "😮"})), title: "😮 \(reaction4Count)") + } + if reaction5Count > 0 { + addItem(item: SimpleItemViewController(chatMessageReactionsListInit: chatMessage.reactions.filter({$0.body == "😢"})), title: "😢 \(reaction5Count)") + } + + setHeaderActiveColor(color: .orange) // default blue + setStyle(style: .fixed) // default fixed + build() } func addItem(item: UIViewController, title: String){ @@ -108,13 +141,13 @@ final class SheetViewController: UIViewController { // collectionHeader collectionHeader.translatesAutoresizingMaskIntoConstraints = false - collectionHeader.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40).isActive = true + collectionHeader.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20).isActive = true collectionHeader.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true collectionHeader.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true collectionHeader.heightAnchor.constraint(equalToConstant: CGFloat(heightHeader)).isActive = true (collectionHeader.collectionViewLayout as? UICollectionViewFlowLayout)?.scrollDirection = .horizontal collectionHeader.showsHorizontalScrollIndicator = false - collectionHeader.backgroundColor = colorHeaderBackground + collectionHeader.backgroundColor = VoipTheme.voipBackgroundBWColor.get() collectionHeader.register(HeaderCell.self, forCellWithReuseIdentifier: collectionHeaderIdentifier) collectionHeader.delegate = self collectionHeader.dataSource = self @@ -126,7 +159,7 @@ final class SheetViewController: UIViewController { collectionPage.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true collectionPage.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true collectionPage.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true - collectionPage.backgroundColor = .white + collectionPage.backgroundColor = VoipTheme.voipBackgroundBWColor.get() collectionPage.showsHorizontalScrollIndicator = false (collectionPage.collectionViewLayout as? UICollectionViewFlowLayout)?.scrollDirection = .horizontal collectionPage.isPagingEnabled = true @@ -144,6 +177,11 @@ final class SheetViewController: UIViewController { var text: String! { didSet { label.text = text + if label.text!.contains("REACTIONS") { + label.font = UIFont.boldSystemFont(ofSize: 8) + } else { + label.font = UIFont.boldSystemFont(ofSize: 14) + } } } @@ -177,7 +215,7 @@ final class SheetViewController: UIViewController { label.translatesAutoresizingMaskIntoConstraints = false label.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true label.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true - label.font = UIFont.boldSystemFont(ofSize: 8) + label.font = UIFont.boldSystemFont(ofSize: 14) // indicator indicator.translatesAutoresizingMaskIntoConstraints = false @@ -272,10 +310,22 @@ enum SlidingTabStyle: String { case flexible } -class SimpleItemViewControllerOne: UIViewController{ - - private let label = UILabel() - +class SimpleItemViewController: UIViewController, UITableViewDataSource { + + let reactionsListTableView = UITableView() + var chatMessageReactionsList : [ChatMessageReaction] = [] + + init(chatMessageReactionsListInit: [ChatMessageReaction]) { + self.chatMessageReactionsList = chatMessageReactionsListInit + super.init(nibName: nil, bundle: nil) + } + + /// This is in case the View Controller is loaded from the Storyboard + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { super.viewDidLoad() setupUI() @@ -283,14 +333,30 @@ class SimpleItemViewControllerOne: UIViewController{ private func setupUI(){ // view - view.backgroundColor = .white - view.addSubview(label) - - // label - label.translatesAutoresizingMaskIntoConstraints = false - label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true - label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true - label.text = "First Controller" + view.backgroundColor = VoipTheme.voipBackgroundBWColor.get() + + // ParticipantsList + view.addSubview(reactionsListTableView) + //reactionsListTableView.matchParentDimmensions().done() + reactionsListTableView.alignParentTop(withMargin: 10).alignParentBottom().alignParentLeft().alignParentRight().done() + reactionsListTableView.dataSource = self + reactionsListTableView.register(ReactionCell.self, forCellReuseIdentifier: "ReactionCell") + reactionsListTableView.allowsSelection = false + if #available(iOS 15.0, *) { + reactionsListTableView.allowsFocus = false + } + reactionsListTableView.separatorStyle = .singleLine + reactionsListTableView.separatorColor = .white } - + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return chatMessageReactionsList.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell:ReactionCell = tableView.dequeueReusableCell(withIdentifier: "ReactionCell") as! ReactionCell + cell.selectionStyle = .none + cell.reactionData = chatMessageReactionsList[indexPath.row] + return cell + } } diff --git a/Classes/Swift/Chat/Views/MultilineMessageCell.swift b/Classes/Swift/Chat/Views/MultilineMessageCell.swift index 8d8f30dbc..080c4fdf8 100644 --- a/Classes/Swift/Chat/Views/MultilineMessageCell.swift +++ b/Classes/Swift/Chat/Views/MultilineMessageCell.swift @@ -1461,41 +1461,39 @@ class MultilineMessageCell: SwipeCollectionViewCell, UICollectionViewDataSource, chatRead.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -16).isActive = true - var reactionCount = 0 event.chatMessage!.reactions.forEach { chatMessageReaction in - reactionCount += 1 switch chatMessageReaction.body { case "❤️": if stackViewReactionsItem1.isHidden == false { - stackViewReactionsCounter.text = String(reactionCount) + stackViewReactionsCounter.text = String(event.chatMessage!.reactions.count) stackViewReactionsCounter.isHidden = false } else { stackViewReactionsItem1.isHidden = false } case "👍": if stackViewReactionsItem2.isHidden == false { - stackViewReactionsCounter.text = String(reactionCount) + stackViewReactionsCounter.text = String(event.chatMessage!.reactions.count) stackViewReactionsCounter.isHidden = false } else { stackViewReactionsItem2.isHidden = false } case "😂": if stackViewReactionsItem3.isHidden == false { - stackViewReactionsCounter.text = String(reactionCount) + stackViewReactionsCounter.text = String(event.chatMessage!.reactions.count) stackViewReactionsCounter.isHidden = false } else { stackViewReactionsItem3.isHidden = false } case "😮": if stackViewReactionsItem4.isHidden == false { - stackViewReactionsCounter.text = String(reactionCount) + stackViewReactionsCounter.text = String(event.chatMessage!.reactions.count) stackViewReactionsCounter.isHidden = false } else { stackViewReactionsItem4.isHidden = false } case "😢": if stackViewReactionsItem5.isHidden == false { - stackViewReactionsCounter.text = String(reactionCount) + stackViewReactionsCounter.text = String(event.chatMessage!.reactions.count) stackViewReactionsCounter.isHidden = false } else { stackViewReactionsItem5.isHidden = false @@ -1577,9 +1575,9 @@ class MultilineMessageCell: SwipeCollectionViewCell, UICollectionViewDataSource, @objc func showMyViewControllerInACustomizedSheet(_ sender: UITapGestureRecognizer? = nil) { if #available(iOS 15.0, *) { - let sheetViewController = SheetViewController() + let sheetViewController = SheetViewController(chatMessageInit: chatMessage!) if let sheetController = sheetViewController.sheetPresentationController { - sheetController.detents = [.medium()] + sheetController.detents = [.medium()] sheetController.prefersGrabberVisible = true } PhoneMainView.instance()!.present(sheetViewController, animated: true, completion: nil)