diff --git a/Classes/Swift/Chat/ViewModels/ChatConversationTableViewModel.swift b/Classes/Swift/Chat/ViewModels/ChatConversationTableViewModel.swift index cd9a0de5f..c66ac76cd 100644 --- a/Classes/Swift/Chat/ViewModels/ChatConversationTableViewModel.swift +++ b/Classes/Swift/Chat/ViewModels/ChatConversationTableViewModel.swift @@ -24,8 +24,11 @@ class ChatConversationTableViewModel: ControlsViewModel { var editModeOn = MutableLiveData(false) + var messageSelected = MutableLiveData(0) var messageListSelected = MutableLiveData<[Bool]>([]) + var messageListToDelete : [EventLog] = [] + override init() { super.init() } @@ -89,16 +92,34 @@ class ChatConversationTableViewModel: ControlsViewModel { } func selectAllMessages(){ - for i in 0...messageListSelected.value!.count { + for i in 0...messageListSelected.value!.count - 1 { messageListSelected.value![i] = true + messageSelected.value! += 1 } refreshIndexPath.value! += 1 } func unSelectAllMessages(){ - for i in 0...messageListSelected.value!.count { + for i in 0...messageListSelected.value!.count - 1 { messageListSelected.value![i] = false } + messageSelected.value! = 0 + refreshIndexPath.value! += 1 + } + + func deleteMessagesSelected(){ + for i in 0...(messageListSelected.value!.count - 1) { + if messageListSelected.value![i] == true { + let messageEvent = getMessage(index: i) + //if messageEvent + messageListToDelete.append((messageEvent)!) + } + } + + messageListToDelete.forEach { chatMessage in + chatMessage.deleteFromDatabase() + } + messageSelected.value! = 0 refreshIndexPath.value! += 1 } } diff --git a/Classes/Swift/Chat/Views/ChatConversationTableViewSwift.swift b/Classes/Swift/Chat/Views/ChatConversationTableViewSwift.swift index 850c1ec23..5be0acc0e 100644 --- a/Classes/Swift/Chat/Views/ChatConversationTableViewSwift.swift +++ b/Classes/Swift/Chat/Views/ChatConversationTableViewSwift.swift @@ -138,43 +138,52 @@ class ChatConversationTableViewSwift: UIViewController, UICollectionViewDataSour } func scrollToBottomWithRelaod(){ - let isDisplayingBottomOfTable = collectionView.contentOffset.y <= 20 - collectionView.reloadData() - if isDisplayingBottomOfTable { - self.collectionView.scrollToItem(at: IndexPath(item: 1, section: 0), at: .top, animated: false) - DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { - self.scrollToBottomNewMessage() - } - }else{ - DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { - self.scrollToBottom() - } - } - if ChatConversationTableViewModel.sharedModel.editModeOn.value! { - ChatConversationTableViewModel.sharedModel.messageListSelected.value!.insert(false, at: 0) + if (ChatConversationTableViewModel.sharedModel.getNBMessages() > 1){ + let isDisplayingBottomOfTable = collectionView.contentOffset.y <= 20 + collectionView.reloadData() + if isDisplayingBottomOfTable { + self.collectionView.scrollToItem(at: IndexPath(item: 1, section: 0), at: .top, animated: false) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { + self.scrollToBottomNewMessage() + } + }else{ + DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { + self.scrollToBottom() + } + } + if ChatConversationTableViewModel.sharedModel.editModeOn.value! { + ChatConversationTableViewModel.sharedModel.messageListSelected.value!.insert(false, at: 0) + } + }else{ + collectionView.reloadData() } + } func refreshData(){ - let indexBottom = collectionView.indexPathsForVisibleItems.sorted().first?.row - let isDisplayingBottomOfTable = collectionView.contentOffset.y <= 20 - let sizeCell = (self.collectionView.cellForItem(at: IndexPath(row: indexBottom!, section: 0))?.frame.size.height) - collectionView.reloadData() + if (ChatConversationTableViewModel.sharedModel.getNBMessages() > 1){ + let indexBottom = collectionView.indexPathsForVisibleItems.sorted().first?.row + let isDisplayingBottomOfTable = collectionView.contentOffset.y <= 20 + let sizeCell = (self.collectionView.cellForItem(at: IndexPath(row: indexBottom!, section: 0))?.frame.size.height) + collectionView.reloadData() - if isDisplayingBottomOfTable { - self.collectionView.scrollToItem(at: IndexPath(item: 1, section: 0), at: .top, animated: false) - DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { - self.scrollToBottomNewMessage() + if isDisplayingBottomOfTable { + self.collectionView.scrollToItem(at: IndexPath(item: 1, section: 0), at: .top, animated: false) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { + self.scrollToBottomNewMessage() + } + } else { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { + self.collectionView.contentOffset = CGPoint(x: self.collectionView.contentOffset.x, y: self.collectionView.contentOffset.y + sizeCell! + 2.0) + } + scrollBadge!.isHidden = false + scrollBadge!.text = "\(ChatConversationViewModel.sharedModel.chatRoom?.unreadMessagesCount ?? 0)" } - } else { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { - self.collectionView.contentOffset = CGPoint(x: self.collectionView.contentOffset.x, y: self.collectionView.contentOffset.y + sizeCell! + 2.0) + if ChatConversationTableViewModel.sharedModel.editModeOn.value! { + ChatConversationTableViewModel.sharedModel.messageListSelected.value!.insert(false, at: 0) } - scrollBadge!.isHidden = false - scrollBadge!.text = "\(ChatConversationViewModel.sharedModel.chatRoom?.unreadMessagesCount ?? 0)" - } - if ChatConversationTableViewModel.sharedModel.editModeOn.value! { - ChatConversationTableViewModel.sharedModel.messageListSelected.value!.insert(false, at: 0) + }else{ + collectionView.reloadData() } } @@ -225,6 +234,9 @@ class ChatConversationTableViewSwift: UIViewController, UICollectionViewDataSour cell.imageViewBubble.onClick { self.onImageClick(chatMessage: event.chatMessage!, index: indexPath.row) } + cell.imageVideoViewBubble.onClick { + self.onImageClick(chatMessage: event.chatMessage!, index: indexPath.row) + } } } @@ -432,6 +444,7 @@ class ChatConversationTableViewSwift: UIViewController, UICollectionViewDataSour if ChatConversationTableViewModel.sharedModel.editModeOn.value! { let indexDeletedMessage = ChatConversationTableViewModel.sharedModel.getIndexMessage(message: message) ChatConversationTableViewModel.sharedModel.messageListSelected.value!.remove(at: indexDeletedMessage) + ChatConversationTableViewModel.sharedModel.messageSelected.value! -= 1 } message.chatRoom?.deleteMessage(message: message) collectionView.reloadData() @@ -468,7 +481,7 @@ class ChatConversationTableViewSwift: UIViewController, UICollectionViewDataSour if (state.rawValue == LinphoneChatMessageStateNotDelivered.rawValue) { print("Messsage not delivered") } else { - if (VFSUtil.vfsEnabled(groupName: kLinphoneMsgNotificationAppGroupId) || ConfigManager.instance().lpConfigBoolForKey(key: "use_in_app_file_viewer_for_non_encrypted_files", section: "app")){ + if ((VFSUtil.vfsEnabled(groupName: kLinphoneMsgNotificationAppGroupId) || ConfigManager.instance().lpConfigBoolForKey(key: "use_in_app_file_viewer_for_non_encrypted_files", section: "app")) && chatMessage.contents.first?.type == "image"){ let view: ImageView = VIEW(ImageView.compositeViewDescription()) let image = UIImage(contentsOfFile: chatMessage.contents.first!.filePath) PhoneMainView.instance().changeCurrentView(view.compositeViewDescription()) @@ -495,7 +508,7 @@ class ChatConversationTableViewSwift: UIViewController, UICollectionViewDataSour if (state.rawValue == LinphoneChatMessageStateNotDelivered.rawValue) { print("Messsage not delivered") } else { - if (VFSUtil.vfsEnabled(groupName: kLinphoneMsgNotificationAppGroupId) || ConfigManager.instance().lpConfigBoolForKey(key: "use_in_app_file_viewer_for_non_encrypted_files", section: "app")){ + if ((VFSUtil.vfsEnabled(groupName: kLinphoneMsgNotificationAppGroupId) || ConfigManager.instance().lpConfigBoolForKey(key: "use_in_app_file_viewer_for_non_encrypted_files", section: "app")) && chatMessage!.contents[index].type == "image"){ let view: ImageView = VIEW(ImageView.compositeViewDescription()) let image = UIImage(contentsOfFile: chatMessage!.contents[index].filePath) PhoneMainView.instance().changeCurrentView(view.compositeViewDescription()) diff --git a/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift b/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift index eb2977cb1..b2d307ca9 100644 --- a/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift +++ b/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift @@ -206,6 +206,18 @@ class ChatConversationViewSwift: BackActionsNavigationView, PHPickerViewControll self.messageView.messageText.text = ChatConversationViewModel.sharedModel.shareFileMessage self.confirmShare(ChatConversationViewModel.sharedModel.nsDataRead(), url: url, fileName: nil) } + + ChatConversationTableViewModel.sharedModel.messageSelected.observe { result in + if ChatConversationTableViewModel.sharedModel.messageSelected.value! > 0 { + self.action1SelectAllButton.isHidden = true + self.action1DeselectAllButton.isHidden = false + self.action2Delete.isEnabled = true + }else{ + self.action1SelectAllButton.isHidden = false + self.action1DeselectAllButton.isHidden = true + self.action2Delete.isEnabled = false + } + } } override func viewWillAppear(_ animated: Bool) { @@ -617,9 +629,9 @@ class ChatConversationViewSwift: BackActionsNavigationView, PHPickerViewControll override func selectDeselectAll(){ super.selectDeselectAll() if(action1SelectAllButton.isHidden){ - //tableController.onSelectionToggle(action1SelectAllButton) + ChatConversationTableViewModel.sharedModel.selectAllMessages() }else{ - //tableController.onSelectionToggle(action1SelectAllButton) + ChatConversationTableViewModel.sharedModel.unSelectAllMessages() } } @@ -635,11 +647,11 @@ class ChatConversationViewSwift: BackActionsNavigationView, PHPickerViewControll cancelMessage: nil, confirmMessage: nil, onCancelClick: { [self] in - onEditionChangeClick()}, + //onEditionChangeClick() + }, onConfirmationClick: { - //self.tableController.removeSelection(nil) + ChatConversationTableViewModel.sharedModel.deleteMessagesSelected() self.editModeOff() - //self.tableController.loadData() } ) } @@ -816,6 +828,7 @@ class ChatConversationViewSwift: BackActionsNavigationView, PHPickerViewControll ChatMessage.getSwiftObject(cObject: message!).contents.forEach({ content in if(content.isFile){ let indexPath = IndexPath(row: ChatConversationViewModel.sharedModel.replyCollectionView.count, section: 0) + ChatConversationViewModel.sharedModel.replyURLCollection.append(URL(string: content.filePath.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!)!) ChatConversationViewModel.sharedModel.replyCollectionView.append(ChatConversationViewModel.sharedModel.getImageFrom(content.getCobject, filePath: content.filePath, forReplyBubble: true)!) collectionViewReply.insertItems(at: [indexPath]) diff --git a/Classes/Swift/Chat/Views/MultilineMessageCell.swift b/Classes/Swift/Chat/Views/MultilineMessageCell.swift index 83b4ef6bd..20bfc9402 100644 --- a/Classes/Swift/Chat/Views/MultilineMessageCell.swift +++ b/Classes/Swift/Chat/Views/MultilineMessageCell.swift @@ -8,7 +8,6 @@ import UIKit import Foundation import linphonesw -import SDWebImage class MultilineMessageCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate { static let reuseId = "MultilineMessageCellReuseId" @@ -925,10 +924,22 @@ class MultilineMessageCell: UICollectionViewCell, UICollectionViewDataSource, UI contentView.onClick { self.deleteItemCheckBox.isSelected = !self.deleteItemCheckBox.isSelected ChatConversationTableViewModel.sharedModel.messageListSelected.value![self.selfIndexMessage] = self.deleteItemCheckBox.isSelected + + if ChatConversationTableViewModel.sharedModel.messageListSelected.value![self.selfIndexMessage] == true { + ChatConversationTableViewModel.sharedModel.messageSelected.value! += 1 + }else{ + ChatConversationTableViewModel.sharedModel.messageSelected.value! -= 1 + } } deleteItemCheckBox.onClick { self.deleteItemCheckBox.isSelected = !self.deleteItemCheckBox.isSelected ChatConversationTableViewModel.sharedModel.messageListSelected.value![self.selfIndexMessage] = self.deleteItemCheckBox.isSelected + + if ChatConversationTableViewModel.sharedModel.messageListSelected.value![self.selfIndexMessage] == true { + ChatConversationTableViewModel.sharedModel.messageSelected.value! += 1 + }else{ + ChatConversationTableViewModel.sharedModel.messageSelected.value! -= 1 + } } }else{ deleteItemCheckBox.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 0).isActive = true @@ -1078,7 +1089,7 @@ class MultilineMessageCell: UICollectionViewCell, UICollectionViewDataSource, UI let imageCell = replyCollectionView[indexPath.row] var myImageView = UIImageView() - if(replyURLCollection[indexPath.row].type == FileType.file_picture_default.rawValue || replyURLCollection[indexPath.row].type == FileType.file_video_default.rawValue){ + if(replyURLCollection[indexPath.row].type == "image" || replyURLCollection[indexPath.row].type == "video"){ myImageView = UIImageView(image: imageCell) }else{ let fileNameText = replyURLCollection[indexPath.row].name @@ -1089,7 +1100,7 @@ class MultilineMessageCell: UICollectionViewCell, UICollectionViewDataSource, UI myImageView.size(w: (viewCell.frame.width), h: (viewCell.frame.height)).done() viewCell.addSubview(myImageView) - if(replyURLCollection[indexPath.row].type == FileType.file_video_default.rawValue){ + if(replyURLCollection[indexPath.row].type == "video"){ var imagePlay = UIImage() if #available(iOS 13.0, *) { imagePlay = (UIImage(named: "vr_play")!.withTintColor(.white)) @@ -1137,11 +1148,25 @@ class MultilineMessageCell: UICollectionViewCell, UICollectionViewDataSource, UI let myImageView = UIImageView() - if(self.chatMessage?.contents[indexPath.row].type == FileType.file_picture_default.rawValue || self.chatMessage?.contents[indexPath.row].type == FileType.file_video_default.rawValue){ + if(self.chatMessage?.contents[indexPath.row].type == "image" || self.chatMessage?.contents[indexPath.row].type == "video"){ + if #available(iOS 15.0, *) { + myImageView.image = UIImage(named: "file_picture_default") + let imageAsync: UIImage = getImageFrom(self.chatMessage?.contents[indexPath.row], forReplyBubble: false)! + imageAsync.prepareForDisplay(completionHandler: { imageAsyncResult in + DispatchQueue.main.async { + myImageView.image = imageAsyncResult + } + }) + } else { + DispatchQueue.global().async { [weak self] in + if let image = self!.getImageFrom(self!.chatMessage?.contents[indexPath.row], forReplyBubble: false) { + DispatchQueue.main.async { + myImageView.image = image + } + } + } + } - myImageView.sd_setImage(with: URL(string: (self.chatMessage?.contents[indexPath.row].filePath)!), placeholderImage: UIImage(named: "file_picture_default"), completed: {(_ image: UIImage?, _ error: Error?, _ cacheType: SDImageCacheType, _ imageURL: URL?) -> Void in - myImageView.image = self.getImageFrom(self.chatMessage?.contents[indexPath.row], forReplyBubble: false)! - }) }else{ myImageView.image = self.getImageFrom(self.chatMessage?.contents[indexPath.row], forReplyBubble: false)! } @@ -1149,18 +1174,6 @@ class MultilineMessageCell: UICollectionViewCell, UICollectionViewDataSource, UI myImageView.size(w: (viewCell.frame.width), h: (viewCell.frame.height)).done() viewCell.addSubview(myImageView) - if(self.chatMessage?.contents[indexPath.row].type == FileType.file_video_default.rawValue){ - var imagePlay = UIImage() - if #available(iOS 13.0, *) { - imagePlay = (UIImage(named: "vr_play")!.withTintColor(.white)) - } else { - imagePlay = UIImage(named: "vr_play")! - } - let myImagePlayView = UIImageView(image: imagePlay) - viewCell.addSubview(myImagePlayView) - myImagePlayView.size(w: viewCell.frame.width/4, h: viewCell.frame.height/4).done() - myImagePlayView.alignHorizontalCenterWith(viewCell).alignVerticalCenterWith(viewCell).done() - } myImageView.contentMode = .scaleAspectFill myImageView.clipsToBounds = true @@ -1170,6 +1183,19 @@ class MultilineMessageCell: UICollectionViewCell, UICollectionViewDataSource, UI uploadView.content = chatMessage?.contents[indexPath.row] uploadView.size(w: 138, h: 138).done() + if(self.chatMessage?.contents[indexPath.row].type == "video"){ + var imagePlay = UIImage() + if #available(iOS 13.0, *) { + imagePlay = (UIImage(named: "vr_play")!.withTintColor(.white)) + } else { + imagePlay = UIImage(named: "vr_play")! + } + let myImagePlayView = UIImageView(image: imagePlay) + viewCell.addSubview(myImagePlayView) + myImagePlayView.size(w: viewCell.frame.width/4, h: viewCell.frame.height/4).done() + myImagePlayView.alignHorizontalCenterWith(viewCell).alignVerticalCenterWith(viewCell).done() + } + viewCell.onClick { ChatConversationTableViewModel.sharedModel.onGridClick(indexMessage: self.selfIndexMessage, index: indexPath.row) } @@ -1332,7 +1358,6 @@ class MultilineMessageCell: UICollectionViewCell, UICollectionViewDataSource, UI DispatchQueue.main.async(execute: { [self] in if (offset == total) { downloadContentCollection[indexTransferProgress] = nil - //chatMessage?.contents[indexTransferProgress] = content imagesGridCollectionView[indexTransferProgress] = getImageFrom(content, forReplyBubble: false)! diff --git a/Podfile b/Podfile index b6017586e..30226b2a4 100644 --- a/Podfile +++ b/Podfile @@ -33,7 +33,6 @@ target 'linphone' do pod 'SnapKit', '~> 5.6.0' pod 'DropDown' pod 'IQKeyboardManager' - pod 'SDWebImage' all_pods end