diff --git a/Classes/ChatConversationTableView.m b/Classes/ChatConversationTableView.m index 929b6b4b9..f450dcb04 100644 --- a/Classes/ChatConversationTableView.m +++ b/Classes/ChatConversationTableView.m @@ -168,7 +168,7 @@ //[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:(count - 1) inSection:0]]; [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(count - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom - animated:YES]; + animated:animated]; if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) [ChatConversationView markAsRead:_chatRoom]; } @@ -431,7 +431,7 @@ static const CGFloat MESSAGE_SPACING_PERCENTAGE = 1.f; title:NSLocalizedString(@"Reply", nil) handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) { LinphoneChatMessage *msg = linphone_event_log_get_chat_message(event); - [VIEW(ChatConversationView) initiateReplyViewForMessage:msg]; + [VIEW(ChatConversationViewSwift) initiateReplyViewForMessage:msg]; [self scrollToBottom:TRUE]; }]; diff --git a/Classes/LinphoneUI/UIChatBubbleTextCell.m b/Classes/LinphoneUI/UIChatBubbleTextCell.m index 7943c7d8d..aedfb3bd2 100644 --- a/Classes/LinphoneUI/UIChatBubbleTextCell.m +++ b/Classes/LinphoneUI/UIChatBubbleTextCell.m @@ -901,7 +901,7 @@ static const CGFloat REPLY_OR_FORWARD_TAG_HEIGHT = 18; [_messageActionsIcons addObject:@"menu_reply_default"]; [_messageActionsBlocks addObject:^{ [thiz dismissPopup]; - [VIEW(ChatConversationView) initiateReplyViewForMessage:message]; + [VIEW(ChatConversationViewSwift) initiateReplyViewForMessage:message]; }]; LinphoneChatRoom *chatroom = linphone_chat_message_get_chat_room(self.message); diff --git a/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift b/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift index 40441e34d..cdad7c8fc 100644 --- a/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift +++ b/Classes/Swift/Chat/Views/ChatConversationViewSwift.swift @@ -48,14 +48,6 @@ import AVFoundation @objc let tableController = ChatConversationTableView() let refreshControl = UIRefreshControl() - var replyBubble = UIChatReplyBubbleView() - - var composingVisible = false - var contentOriginY = 0.0 - var messageViewOriginY = 0.0 - var mediaSelectorHeight = 0.0 - var mediaSelectorVisible = false - var mediaCollectionView : [UIImage] = [] var mediaURLCollection : [URL] = [] @@ -136,6 +128,10 @@ import AVFoundation var newMediaCount : Int = 0 @objc var pendingForwardMessage : OpaquePointer? = nil + var replyViewOriginY = 0.0 + var replyViewHeight = 0.0 + var showReplyView = false + override func viewDidLoad() { super.viewDidLoad( @@ -218,11 +214,17 @@ import AVFoundation } override func viewDidDisappear(_ animated: Bool) { - mediaSelectorVisible = false - mediaSelectorHeight = 0.0 - self.isComposingView.transform = CGAffineTransformIdentity; - self.mediaSelector.transform = CGAffineTransformIdentity; - self.contentView.transform = CGAffineTransformIdentity; + + if(self.isComposingView.isHidden == false){ + self.isComposingView.isHidden = true + } + if(self.mediaSelector.isHidden == false){ + self.mediaSelector.isHidden = true + } + if(self.replyBubble.isHidden == false){ + self.replyBubble.isHidden = true + } + self.mediaCollectionView = [] self.mediaURLCollection = [] self.fileContext = [] @@ -672,16 +674,19 @@ import AVFoundation fileContext = [] messageView.fileContext = false - mediaSelectorVisible = false - mediaSelectorHeight = 0.0 - self.isComposingView.transform = CGAffineTransformIdentity; - self.mediaSelector.transform = CGAffineTransformIdentity; - self.contentView.transform = CGAffineTransformIdentity; self.mediaCollectionView = [] self.mediaURLCollection = [] return } - + if(self.isComposingView.isHidden == false){ + self.isComposingView.isHidden = true + } + if(self.mediaSelector.isHidden == false){ + self.mediaSelector.isHidden = true + } + if(self.replyBubble.isHidden == false){ + self.replyBubble.isHidden = true + } let result = ChatMessage.getSwiftObject(cObject: rootMessage!) sendMessageInMessageField(rootMessage: result) } @@ -778,7 +783,6 @@ import AVFoundation } func setComposingVisible(_ visible: Bool, withDelay delay: CGFloat) { - let shouldAnimate = composingVisible != visible if visible { let addresses = chatRoom!.composingAddresses var composingAddresses : String? = "" @@ -797,84 +801,42 @@ import AVFoundation isComposingTextView.text = String.localizedStringWithFormat(NSLocalizedString("%@ are writing...", comment: ""), composingAddresses!) } } - - composingVisible = visible - if !shouldAnimate { - return - } - var isBottomOfView = false - if (tableController.tableView.contentOffset.y + self.isComposingView.frame.size.height >= (tableController.tableView.contentSize.height - tableController.tableView.frame.size.height)) { + if (tableController.tableView.contentOffset.y + 1) >= (tableController.tableView.contentSize.height - tableController.tableView.frame.size.height) { isBottomOfView = true } - - UIView.animate( - withDuration: delay, - animations: { - self.contentOriginY = self.contentView.frame.origin.y - self.messageViewOriginY = self.isComposingView.frame.origin.y - - if visible { - if(isBottomOfView && self.tableController.totalNumberOfItems() > 3){ - self.contentView.transform = self.contentView.transform.translatedBy(x: 0, y: -self.mediaSelectorHeight - self.top_bar_height/2) - self.contentView.transform = CGAffineTransform(translationX: 0, y: -self.mediaSelectorHeight - self.top_bar_height/2) - } - self.isComposingView.transform = self.isComposingView.transform.translatedBy(x: 0, y: -self.mediaSelectorHeight - self.top_bar_height/2) - self.isComposingView.transform = CGAffineTransform(translationX: 0, y: -self.mediaSelectorHeight - self.top_bar_height/2) - }else{ - if(isBottomOfView && self.tableController.totalNumberOfItems() > 3){ - self.contentView.transform = self.contentView.transform.translatedBy(x: 0, y: -self.mediaSelectorHeight) - self.contentView.transform = CGAffineTransform(translationX: 0, y: -self.mediaSelectorHeight) - } - self.isComposingView.transform = self.isComposingView.transform.translatedBy(x: 0, y: 0) - self.isComposingView.transform = CGAffineTransform(translationX: 0, y: 0) - } - }) + UIView.animate(withDuration: 0.3, animations: { + self.isComposingView.isHidden = !self.isComposingView.isHidden + }) + if(isBottomOfView){ + tableController.scroll(toBottom: false) + } } func selectionMedia() { - mediaSelectorVisible = !mediaSelectorVisible - mediaSelectorHeight = mediaSelectorVisible ? top_bar_height*2 : 0.0 var isBottomOfView = false - if (tableController.tableView.contentOffset.y + self.isComposingView.frame.size.height >= (tableController.tableView.contentSize.height - tableController.tableView.frame.size.height)) { + if (tableController.tableView.contentOffset.y + 1) >= (tableController.tableView.contentSize.height - tableController.tableView.frame.size.height) { isBottomOfView = true } - - UIView.animate( - withDuration: 0.3, - animations: { [self] in - self.contentOriginY = self.contentView.frame.origin.y - self.messageViewOriginY = self.mediaSelector.frame.origin.y - - if self.mediaSelectorVisible { - - if(composingVisible){ - self.isComposingView.transform = self.isComposingView.transform.translatedBy(x: 0, y: -self.mediaSelectorHeight - self.top_bar_height/2) - self.isComposingView.transform = CGAffineTransform(translationX: 0, y: -self.mediaSelectorHeight - self.top_bar_height/2) - } - - if(isBottomOfView && tableController.totalNumberOfItems() > 3){ - self.contentView.transform = self.contentView.transform.translatedBy(x: 0, y: -self.mediaSelectorHeight) - self.contentView.transform = CGAffineTransform(translationX: 0, y: -self.mediaSelectorHeight) - } - self.mediaSelector.transform = self.mediaSelector.transform.translatedBy(x: 0, y: -self.mediaSelectorHeight) - self.mediaSelector.transform = CGAffineTransform(translationX: 0, y: -self.mediaSelectorHeight) - - }else{ - - if(self.composingVisible){ - self.isComposingView.transform = self.isComposingView.transform.translatedBy(x: 0, y: -self.top_bar_height/2) - self.isComposingView.transform = CGAffineTransform(translationX: 0, y: -self.top_bar_height/2) - } - - if(isBottomOfView && tableController.totalNumberOfItems() > 3){ - self.contentView.transform = self.contentView.transform.translatedBy(x: 0, y: 0) - self.contentView.transform = CGAffineTransform(translationX: 0, y: 0) - } - self.mediaSelector.transform = self.mediaSelector.transform.translatedBy(x: 0, y: 0) - self.mediaSelector.transform = CGAffineTransform(translationX: 0, y: 0) - } - }) + UIView.animate(withDuration: 0.3, animations: { + self.mediaSelector.isHidden = !self.mediaSelector.isHidden + }) + if(isBottomOfView){ + tableController.scroll(toBottom: false) + } + } + + func initReplyView() { + var isBottomOfView = false + if (tableController.tableView.contentOffset.y + 1) >= (tableController.tableView.contentSize.height - tableController.tableView.frame.size.height) { + isBottomOfView = true + } + UIView.animate(withDuration: 0.3, animations: { + self.replyBubble.isHidden = !self.replyBubble.isHidden + }) + if(isBottomOfView){ + tableController.scroll(toBottom: false) + } } @objc class func getKeyFromFileType(_ fileType: String?, fileName name: String?) -> String? { @@ -1317,4 +1279,36 @@ import AVFoundation d?.setSpecialColor() } } + + /* + func closePendingReply() { + if replyBubble != nil { + showReplyView = false + replyBubble!.view.removeFromSuperview() + updateFramesInclRecordingAndReplyView() + replyBubble = nil + } + } + */ + + @objc func initiateReplyView(forMessage: OpaquePointer?) { + /* + if replyBubble != nil { + closePendingReply() + } + replyBubble = UIChatReplyBubbleView(nibName: "UIChatReplyBubbleView", bundle: nil) + addChild(replyBubble) + replyView.addSubview(replyBubble.view) + replyBubble.didMove(toParent: self) + replyBubble.configure(for: message, withDimissBlock: { [self] in + closePendingReply() + }, hideDismiss: false) { + } + showReplyView = true + updateFramesInclRecordingAndReplyView() + tableController.scroll(to: message?.getCobject) + messageView.messageText.becomeFirstResponder() + */ + initReplyView() + } } diff --git a/Classes/Swift/Util/BackActionsNavigationView.swift b/Classes/Swift/Util/BackActionsNavigationView.swift index 36ef4380c..3e47da8e0 100644 --- a/Classes/Swift/Util/BackActionsNavigationView.swift +++ b/Classes/Swift/Util/BackActionsNavigationView.swift @@ -21,6 +21,7 @@ import UIKit import Foundation import linphonesw +import SnapKit @objc class BackActionsNavigationView: UIViewController { @@ -34,12 +35,12 @@ import linphonesw let participantsGroupLabel = StyledLabel(VoipTheme.chat_conversation_participants) let topBar = UIView() - let scrollView = UIScrollView() let contentView = UIView() let isComposingView = UIView() let isComposingTextView = StyledLabel(VoipTheme.chat_conversation_is_composing_text) let messageView = MessageView() let mediaSelector = UIView() + var replyBubble = UIView() var backAction : (() -> Void)? = nil var action1 : (() -> Void)? = nil var action2 : (() -> Void)? = nil @@ -56,6 +57,8 @@ import linphonesw var isSecure : Bool = false var isGroupChat : Bool = false let floatingButton = CallControlButton(buttonTheme:VoipTheme.nav_button("")) + + var stackView = UIStackView() func viewDidLoad(backAction : @escaping () -> Void, action1 : @escaping () -> Void, @@ -131,24 +134,45 @@ import linphonesw super.viewDidLoad() - view.addSubview(messageView) - messageView.alignParentBottom().height(top_bar_height).matchParentSideBorders().done() + stackView.axis = .vertical; + stackView.distribution = .fill; + stackView.alignment = .center; + stackView.spacing = 0; - view.addSubview(mediaSelector) - mediaSelector.alignParentBottom(withMargin: -top_bar_height).height(top_bar_height*2).matchParentSideBorders().done() - mediaSelector.backgroundColor = VoipTheme.voipToolbarBackgroundColor.get() + stackView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(stackView) - view.addSubview(isComposingView) - isComposingView.alignParentBottom(withMargin: top_bar_height/2).height(top_bar_height/2).matchParentSideBorders().done() + stackView.alignParentTop().alignParentBottom().matchParentSideBorders().done() + + stackView.addArrangedSubview(contentView) + contentView.alignParentTop(withMargin: top_bar_height).matchParentSideBorders().done() + + stackView.addArrangedSubview(isComposingView) + isComposingView.height(top_bar_height/2).matchParentSideBorders().done() + isComposingView.isHidden = true isComposingView.addSubview(isComposingTextView) isComposingTextView.alignParentLeft(withMargin: 10).alignParentRight(withMargin: 10).matchParentHeight().done() isComposingView.backgroundColor = VoipTheme.backgroundWhiteBlack.get() - view.addSubview(contentView) - contentView.alignParentTop(withMargin: top_bar_height).alignParentBottom(withMargin: top_bar_height).matchParentSideBorders().done() + stackView.addArrangedSubview(replyBubble) + replyBubble.height(top_bar_height*2).matchParentSideBorders().done() + replyBubble.backgroundColor = UIColor.blue + replyBubble.isHidden = true + + stackView.addArrangedSubview(mediaSelector) + mediaSelector.height(top_bar_height*2).matchParentSideBorders().done() + mediaSelector.backgroundColor = VoipTheme.voipToolbarBackgroundColor.get() + mediaSelector.isHidden = true + - view.addSubview(floatingButton) + stackView.addArrangedSubview(messageView) + messageView.alignParentBottom().height(top_bar_height).matchParentSideBorders().done() + + stackView.translatesAutoresizingMaskIntoConstraints = false; + view.addSubview(stackView) + + view.addSubview(floatingButton) floatingButton.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -1).isActive = true floatingButton.topAnchor.constraint(equalTo: self.view.layoutMarginsGuide.topAnchor, constant: top_bar_height + 4).isActive = true floatingButton.setImage(UIImage(named:"security_alert_indicator.png"), for: .normal) @@ -156,18 +180,23 @@ import linphonesw floatingButton.onClickAction = action3 + stackView.centerXAnchor.constraint(equalTo:self.view.centerXAnchor).isActive = true + stackView.centerYAnchor.constraint(equalTo:self.view.centerYAnchor).isActive = true + view.bringSubviewToFront(isComposingView) view.bringSubviewToFront(mediaSelector) + view.bringSubviewToFront(replyBubble) view.bringSubviewToFront(messageView) + view.bringSubviewToFront(contentView) + view.bringSubviewToFront(topBar) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) topBar.backgroundColor = VoipTheme.voipToolbarBackgroundColor.get() - } func changeTitle(titleString: String){