From f201ea59c9fae2cb79fddc2351bc1829d6f7545e Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 20 Sep 2022 11:40:32 +0300 Subject: [PATCH] Timeline composer layout loop fix (#6743) * Publish suitable view height for user suggestions * Update container view height * Add changelog * Fix user suggestions layout for pre iOS 16 --- Riot/Modules/Room/RoomViewController.h | 1 + Riot/Modules/Room/RoomViewController.m | 10 +++++ Riot/Modules/Room/RoomViewController.xib | 3 +- .../UserSuggestionCoordinator.swift | 41 ++++++++++++++++++- .../UserSuggestionCoordinatorBridge.swift | 5 +++ changelog.d/6734.bugfix | 1 + 6 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 changelog.d/6734.bugfix diff --git a/Riot/Modules/Room/RoomViewController.h b/Riot/Modules/Room/RoomViewController.h index 2b0ad02c5..a01f6c567 100644 --- a/Riot/Modules/Room/RoomViewController.h +++ b/Riot/Modules/Room/RoomViewController.h @@ -55,6 +55,7 @@ extern NSNotificationName const RoomGroupCallTileTappedNotification; // The preview header @property (weak, nonatomic, nullable) IBOutlet UIView *previewHeaderContainer; @property (weak, nonatomic, nullable) IBOutlet NSLayoutConstraint *previewHeaderContainerHeightConstraint; +@property (weak, nonatomic, nullable) IBOutlet NSLayoutConstraint *userSuggestionContainerHeightConstraint; // The jump to last unread banner @property (weak, nonatomic, nullable) IBOutlet UIView *jumpToLastUnreadBannerContainer; diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index cb0fb1a31..542007a41 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -7757,6 +7757,16 @@ static CGSize kThreadListBarButtonItemImageSize; [self mention:member]; } +- (void)userSuggestionCoordinatorBridge:(UserSuggestionCoordinatorBridge *)coordinator didUpdateViewHeight:(CGFloat)height +{ + if (self.userSuggestionContainerHeightConstraint.constant != height) + { + self.userSuggestionContainerHeightConstraint.constant = height; + + [self.view layoutIfNeeded]; + } +} + #pragma mark - ThreadsCoordinatorBridgePresenterDelegate - (void)threadsCoordinatorBridgePresenterDelegateDidComplete:(ThreadsCoordinatorBridgePresenter *)coordinatorBridgePresenter diff --git a/Riot/Modules/Room/RoomViewController.xib b/Riot/Modules/Room/RoomViewController.xib index 888aa3b75..073276604 100644 --- a/Riot/Modules/Room/RoomViewController.xib +++ b/Riot/Modules/Room/RoomViewController.xib @@ -32,6 +32,7 @@ + @@ -171,7 +172,7 @@ - + diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift index 4d10fce83..fd7bd57b3 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift @@ -17,9 +17,11 @@ import Foundation import UIKit import SwiftUI +import Combine protocol UserSuggestionCoordinatorDelegate: AnyObject { func userSuggestionCoordinator(_ coordinator: UserSuggestionCoordinator, didRequestMentionForMember member: MXRoomMember, textTrigger: String?) + func userSuggestionCoordinator(_ coordinator: UserSuggestionCoordinator, didUpdateViewHeight height: CGFloat) } struct UserSuggestionCoordinatorParameters { @@ -35,10 +37,12 @@ final class UserSuggestionCoordinator: Coordinator, Presentable { private let parameters: UserSuggestionCoordinatorParameters - private var userSuggestionHostingController: UIViewController + private var userSuggestionHostingController: UIHostingController private var userSuggestionService: UserSuggestionServiceProtocol private var userSuggestionViewModel: UserSuggestionViewModelProtocol private var roomMemberProvider: UserSuggestionCoordinatorRoomMemberProvider + + private var cancellables = Set() // MARK: Public @@ -77,12 +81,18 @@ final class UserSuggestionCoordinator: Coordinator, Presentable { self.delegate?.userSuggestionCoordinator(self, didRequestMentionForMember: member, textTrigger: self.userSuggestionService.currentTextTrigger) } } + + userSuggestionService.items.sink { [weak self] _ in + guard let self = self else { return } + self.delegate?.userSuggestionCoordinator(self, + didUpdateViewHeight: self.calculateViewHeight()) + }.store(in: &cancellables) } func processTextMessage(_ textMessage: String) { userSuggestionService.processTextMessage(textMessage) } - + // MARK: - Public func start() { @@ -91,6 +101,33 @@ final class UserSuggestionCoordinator: Coordinator, Presentable { func toPresentable() -> UIViewController { return self.userSuggestionHostingController } + + // MARK: - Private + + private func calculateViewHeight() -> CGFloat { + let viewModel = UserSuggestionViewModel(userSuggestionService: userSuggestionService) + let view = UserSuggestionList(viewModel: viewModel.context) + .addDependency(AvatarService.instantiate(mediaManager: parameters.mediaManager)) + + let controller = VectorHostingController(rootView: view) + guard let view = controller.view else { + return 0 + } + view.isHidden = true + + toPresentable().view.addSubview(view) + controller.didMove(toParent: toPresentable()) + + view.setNeedsLayout() + view.layoutIfNeeded() + + let result = view.intrinsicContentSize.height + + controller.didMove(toParent: nil) + view.removeFromSuperview() + + return result + } } private class UserSuggestionCoordinatorRoomMemberProvider: RoomMembersProviderProtocol { diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinatorBridge.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinatorBridge.swift index 1fd88e25b..44ddaee9f 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinatorBridge.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinatorBridge.swift @@ -19,6 +19,7 @@ import Foundation @objc protocol UserSuggestionCoordinatorBridgeDelegate: AnyObject { func userSuggestionCoordinatorBridge(_ coordinator: UserSuggestionCoordinatorBridge, didRequestMentionForMember member: MXRoomMember, textTrigger: String?) + func userSuggestionCoordinatorBridge(_ coordinator: UserSuggestionCoordinatorBridge, didUpdateViewHeight height: CGFloat) } @objcMembers @@ -54,4 +55,8 @@ extension UserSuggestionCoordinatorBridge: UserSuggestionCoordinatorDelegate { func userSuggestionCoordinator(_ coordinator: UserSuggestionCoordinator, didRequestMentionForMember member: MXRoomMember, textTrigger: String?) { delegate?.userSuggestionCoordinatorBridge(self, didRequestMentionForMember: member, textTrigger: textTrigger) } + + func userSuggestionCoordinator(_ coordinator: UserSuggestionCoordinator, didUpdateViewHeight height: CGFloat) { + delegate?.userSuggestionCoordinatorBridge(self, didUpdateViewHeight: height) + } } diff --git a/changelog.d/6734.bugfix b/changelog.d/6734.bugfix new file mode 100644 index 000000000..feec00f69 --- /dev/null +++ b/changelog.d/6734.bugfix @@ -0,0 +1 @@ +Room: Fix a composer crash after long unsent messages.