From 629e7b7d8bc92124365f1c2c5580e5dff7b4a942 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Fri, 22 Sep 2023 17:52:20 +0200 Subject: [PATCH] Activer l'affichage en thread (#878) --- .../PushNotificationService.m | 32 +-- .../Room/CellData/RoomBubbleCellData.m | 12 +- .../Modules/Room/DataSources/RoomDataSource.m | 131 ++++++----- Riot/Modules/Room/RoomCoordinator.swift | 11 +- Riot/Modules/Room/RoomViewController.h | 6 +- Riot/Modules/Room/RoomViewController.m | 214 +++++++++--------- .../Search/DataSources/RoomSearchDataSource.m | 118 +++++----- .../BaseRoomCell/BaseRoomCell.swift | 20 +- .../BaseRoomCell/RoomCellContentView.swift | 74 +++--- .../RoomCellThreadSummaryDisplayable.swift | 4 +- .../BubbleRoomTimelineCellDecorator.swift | 144 ++++++------ .../PlainRoomTimelineCellDecorator.swift | 96 ++++---- .../Styles/RoomTimelineCellDecorator.swift | 10 +- .../Modules/Settings/SettingsViewController.m | 77 +++---- .../RoomPreview/RoomPreviewCoordinator.swift | 7 +- changelog.d/878.feature | 1 + 16 files changed, 470 insertions(+), 487 deletions(-) create mode 100644 changelog.d/878.feature diff --git a/Riot/Managers/PushNotification/PushNotificationService.m b/Riot/Managers/PushNotification/PushNotificationService.m index efaed822fe..b118562207 100644 --- a/Riot/Managers/PushNotification/PushNotificationService.m +++ b/Riot/Managers/PushNotification/PushNotificationService.m @@ -487,28 +487,28 @@ - (void)handleNotificationInlineReplyForRoomId:(NSString*)roomId // initialize data source for a thread or a room __block MXKRoomDataSource *dataSource; dispatch_group_t dispatchGroupDataSource = dispatch_group_create(); - // Tchap: Disable Threads -// if (RiotSettings.shared.enableThreads && threadId) -// { -// dispatch_group_enter(dispatchGroupDataSource); -// [ThreadDataSource loadRoomDataSourceWithRoomId:roomId -// initialEventId:nil -// threadId:threadId -// andMatrixSession:mxSession -// onComplete:^(MXKRoomDataSource *threadDataSource) { -// dataSource = threadDataSource; -// dispatch_group_leave(dispatchGroupDataSource); -// }]; -// } -// else -// { + + if (RiotSettings.shared.enableThreads && threadId) + { + dispatch_group_enter(dispatchGroupDataSource); + [ThreadDataSource loadRoomDataSourceWithRoomId:roomId + initialEventId:nil + threadId:threadId + andMatrixSession:mxSession + onComplete:^(MXKRoomDataSource *threadDataSource) { + dataSource = threadDataSource; + dispatch_group_leave(dispatchGroupDataSource); + }]; + } + else + { dispatch_group_enter(dispatchGroupDataSource); MXKRoomDataSourceManager *manager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:mxSession]; [manager roomDataSourceForRoom:roomId create:YES onComplete:^(MXKRoomDataSource *roomDataSource) { dataSource = roomDataSource; dispatch_group_leave(dispatchGroupDataSource); }]; -// } + } dispatch_group_notify(dispatchGroupDataSource, dispatch_get_main_queue(), ^{ if (responseText != nil && responseText.length != 0) diff --git a/Riot/Modules/Room/CellData/RoomBubbleCellData.m b/Riot/Modules/Room/CellData/RoomBubbleCellData.m index 8ff04f89c0..2623476bed 100644 --- a/Riot/Modules/Room/CellData/RoomBubbleCellData.m +++ b/Riot/Modules/Room/CellData/RoomBubbleCellData.m @@ -838,9 +838,9 @@ - (CGFloat)threadSummaryViewHeightForEventId:(NSString*)eventId // component is not a thread root return 0; } - return 0; // Threads are disabled in Tchap -// return PlainRoomCellLayoutConstants.threadSummaryViewTopMargin + -// [ThreadSummaryView contentViewHeightForThread:component.thread fitting:self.maxTextViewWidth]; +// return 0; // Threads are disabled in Tchap + return PlainRoomCellLayoutConstants.threadSummaryViewTopMargin + + [ThreadSummaryView contentViewHeightForThread:component.thread fitting:self.maxTextViewWidth]; } - (CGFloat)fromAThreadViewHeightForEventId:(NSString*)eventId @@ -866,9 +866,9 @@ - (CGFloat)fromAThreadViewHeightForEventId:(NSString*)eventId // event is not in a thread return 0; } - return 0; // Threads are disabled in Tchap -// return PlainRoomCellLayoutConstants.fromAThreadViewTopMargin + -// [FromAThreadView contentViewHeightForEvent:component.event fitting:self.maxTextViewWidth]; +// return 0; // Threads are disabled in Tchap + return PlainRoomCellLayoutConstants.fromAThreadViewTopMargin + + [FromAThreadView contentViewHeightForEvent:component.event fitting:self.maxTextViewWidth]; } - (CGFloat)urlPreviewHeightForEventId:(NSString*)eventId diff --git a/Riot/Modules/Room/DataSources/RoomDataSource.m b/Riot/Modules/Room/DataSources/RoomDataSource.m index 4fac685701..b5f193f8f7 100644 --- a/Riot/Modules/Room/DataSources/RoomDataSource.m +++ b/Riot/Modules/Room/DataSources/RoomDataSource.m @@ -266,47 +266,46 @@ - (void)fetchEncryptionTrustedLevel - (BOOL)shouldQueueEventForProcessing:(MXEvent *)event roomState:(MXRoomState *)roomState direction:(MXTimelineDirection)direction { - // Tchap: Disable Threads -// if (self.threadId) -// { -// // if in a thread, ignore non-root event or events from other threads -// if (![event.eventId isEqualToString:self.threadId] && ![event.threadId isEqualToString:self.threadId]) -// { -// // Ignore the event -// return NO; -// } -// // also ignore events related to un-threaded or events from other threads -// if (!event.isInThread && event.relatesTo.eventId) -// { -// MXEvent *relatedEvent = [self.mxSession.store eventWithEventId:event.relatesTo.eventId -// inRoom:event.roomId]; -// if (![relatedEvent.threadId isEqualToString:self.threadId]) -// { -// // ignore the event -// return NO; -// } -// } -// } -// else if (RiotSettings.shared.enableThreads) -// { -// // if not in a thread, ignore all threaded events -// if (event.isInThread) -// { -// // ignore the event -// return NO; -// } -// // also ignore events related to threaded events -// if (event.relatesTo.eventId) -// { -// MXEvent *relatedEvent = [self.mxSession.store eventWithEventId:event.relatesTo.eventId -// inRoom:event.roomId]; -// if (relatedEvent.isInThread) -// { -// // ignore the event -// return NO; -// } -// } -// } + if (self.threadId) + { + // if in a thread, ignore non-root event or events from other threads + if (![event.eventId isEqualToString:self.threadId] && ![event.threadId isEqualToString:self.threadId]) + { + // Ignore the event + return NO; + } + // also ignore events related to un-threaded or events from other threads + if (!event.isInThread && event.relatesTo.eventId) + { + MXEvent *relatedEvent = [self.mxSession.store eventWithEventId:event.relatesTo.eventId + inRoom:event.roomId]; + if (![relatedEvent.threadId isEqualToString:self.threadId]) + { + // ignore the event + return NO; + } + } + } + else if (RiotSettings.shared.enableThreads) + { + // if not in a thread, ignore all threaded events + if (event.isInThread) + { + // ignore the event + return NO; + } + // also ignore events related to threaded events + if (event.relatesTo.eventId) + { + MXEvent *relatedEvent = [self.mxSession.store eventWithEventId:event.relatesTo.eventId + inRoom:event.roomId]; + if (relatedEvent.isInThread) + { + // ignore the event + return NO; + } + } + } return [super shouldQueueEventForProcessing:event roomState:roomState direction:direction]; } @@ -478,26 +477,25 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cellData:cellData contentViewPositionY:bottomPositionY upperDecorationView:urlPreviewView]; } - // Tchap: Disable Threads -// ThreadSummaryView *threadSummaryView; -// -// // display thread summary view if the component has a thread in the room timeline -// if (RiotSettings.shared.enableThreads && component.thread && !self.threadId) -// { -// threadSummaryView = [[ThreadSummaryView alloc] initWithThread:component.thread -// session:self.mxSession]; -// threadSummaryView.delegate = self; -// threadSummaryView.tag = index; -// -// [temporaryViews addObject:threadSummaryView]; -// UIView *upperDecorationView = reactionsView ?: urlPreviewView; -// -// [cellDecorator addThreadSummaryView:threadSummaryView -// toCell:bubbleCell -// cellData:cellData -// contentViewPositionY:bottomPositionY -// upperDecorationView:upperDecorationView]; -// } + ThreadSummaryView *threadSummaryView; + + // display thread summary view if the component has a thread in the room timeline + if (RiotSettings.shared.enableThreads && component.thread && !self.threadId) + { + threadSummaryView = [[ThreadSummaryView alloc] initWithThread:component.thread + session:self.mxSession]; + threadSummaryView.delegate = self; + threadSummaryView.tag = index; + + [temporaryViews addObject:threadSummaryView]; + UIView *upperDecorationView = reactionsView ?: urlPreviewView; + + [cellDecorator addThreadSummaryView:threadSummaryView + toCell:bubbleCell + cellData:cellData + contentViewPositionY:bottomPositionY + upperDecorationView:upperDecorationView]; + } MXKReceiptSendersContainer* avatarsContainer; @@ -1213,12 +1211,11 @@ - (void)didCloseURLPreviewView:(URLPreviewView *)previewView for:(NSString *)eve #pragma mark - ThreadSummaryViewDelegate -// Tchap: Disable Threads -//- (void)threadSummaryViewTapped:(ThreadSummaryView *)summaryView -//{ -// [self.roomDataSourceDelegate roomDataSource:self -// didTapThread:summaryView.thread]; -//} +- (void)threadSummaryViewTapped:(ThreadSummaryView *)summaryView +{ + [self.roomDataSourceDelegate roomDataSource:self + didTapThread:summaryView.thread]; +} #pragma mark - Location sharing diff --git a/Riot/Modules/Room/RoomCoordinator.swift b/Riot/Modules/Room/RoomCoordinator.swift index 254b3a1659..d543db3ccc 100644 --- a/Riot/Modules/Room/RoomCoordinator.swift +++ b/Riot/Modules/Room/RoomCoordinator.swift @@ -80,13 +80,12 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol { self.selectedEventId = parameters.eventId self.userIndicatorStore = UserIndicatorStore(presenter: parameters.userIndicatorPresenter) - // Tchap: Disable Threads -// if let threadId = parameters.threadId { -// self.roomViewController = ThreadViewController.instantiate(withThreadId: threadId, -// configuration: parameters.displayConfiguration) -// } else { + if let threadId = parameters.threadId { + self.roomViewController = ThreadViewController.instantiate(withThreadId: threadId, + configuration: parameters.displayConfiguration) + } else { self.roomViewController = RoomViewController.instantiate(with: parameters.displayConfiguration) -// } + } self.roomViewController.userIndicatorStore = userIndicatorStore self.roomViewController.showSettingsInitially = parameters.showSettingsInitially diff --git a/Riot/Modules/Room/RoomViewController.h b/Riot/Modules/Room/RoomViewController.h index 9029e33e72..27a28d011f 100644 --- a/Riot/Modules/Room/RoomViewController.h +++ b/Riot/Modules/Room/RoomViewController.h @@ -31,9 +31,8 @@ @class UniversalLinkParameters; @protocol RoomViewControllerDelegate; @class RoomDisplayConfiguration; -// Tchap: Disable Threads +@class ThreadsCoordinatorBridgePresenter; // Tchap: Disable Live location sharing -//@class ThreadsCoordinatorBridgePresenter; //@class LiveLocationSharingBannerView; @class VoiceBroadcastService; @class ComposerLinkActionBridgePresenter; @@ -355,8 +354,7 @@ didRequestEditForPollWithStartEvent:(MXEvent *)startEvent; - (void)roomViewControllerDidTapLiveLocationSharingBanner:(RoomViewController *)roomViewController; /// Request a threads coordinator for a given threadId, used to open a thread from within a room. -// Tchap: Disable Threads -//- (nullable ThreadsCoordinatorBridgePresenter *)threadsCoordinatorForRoomViewController:(RoomViewController *)roomViewController threadId:(nullable NSString *)threadId; + (nullable ThreadsCoordinatorBridgePresenter *)threadsCoordinatorForRoomViewController:(RoomViewController *)roomViewController threadId:(nullable NSString *)threadId; @end diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 47ca17f555..21fba07b01 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -208,9 +208,9 @@ @interface RoomViewController () thread = cellData.bubbleComponents.firstObject.thread; -// ThreadSummaryView *threadSummaryView = [[ThreadSummaryView alloc] initWithThread:thread -// session:self.mxSession]; -// [bubbleCell.tmpSubviews addObject:threadSummaryView]; -// -// threadSummaryView.translatesAutoresizingMaskIntoConstraints = NO; -// [bubbleCell.contentView addSubview:threadSummaryView]; -// -// CGFloat leftMargin = PlainRoomCellLayoutConstants.reactionsViewLeftMargin; -// CGFloat height = [ThreadSummaryView contentViewHeightForThread:thread fitting:cellData.maxTextViewWidth]; -// -// CGRect bubbleComponentFrame = [bubbleCell componentFrameInContentViewForIndex:0]; -// CGFloat bottomPositionY = bubbleComponentFrame.origin.y + bubbleComponentFrame.size.height; -// -// // Set constraints for the summary view -// [NSLayoutConstraint activateConstraints: @[ -// [threadSummaryView.leadingAnchor constraintEqualToAnchor:threadSummaryView.superview.leadingAnchor -// constant:leftMargin], -// [threadSummaryView.topAnchor constraintEqualToAnchor:threadSummaryView.superview.topAnchor -// constant:bottomPositionY + PlainRoomCellLayoutConstants.threadSummaryViewTopMargin], -// [threadSummaryView.heightAnchor constraintEqualToConstant:height], -// [threadSummaryView.trailingAnchor constraintLessThanOrEqualToAnchor:threadSummaryView.superview.trailingAnchor constant:-PlainRoomCellLayoutConstants.reactionsViewRightMargin] -// ]]; -// } -// else if (event.isInThread) -// { -// FromAThreadView *fromAThreadView = [FromAThreadView instantiate]; -// [bubbleCell.tmpSubviews addObject:fromAThreadView]; -// -// fromAThreadView.translatesAutoresizingMaskIntoConstraints = NO; -// [bubbleCell.contentView addSubview:fromAThreadView]; -// -// CGFloat leftMargin = PlainRoomCellLayoutConstants.reactionsViewLeftMargin; -// CGFloat height = [FromAThreadView contentViewHeightForEvent:event fitting:cellData.maxTextViewWidth]; -// -// CGRect bubbleComponentFrame = [bubbleCell componentFrameInContentViewForIndex:0]; -// CGFloat bottomPositionY = bubbleComponentFrame.origin.y + bubbleComponentFrame.size.height; -// -// // Set constraints for the summary view -// [NSLayoutConstraint activateConstraints: @[ -// [fromAThreadView.leadingAnchor constraintEqualToAnchor:fromAThreadView.superview.leadingAnchor -// constant:leftMargin], -// [fromAThreadView.topAnchor constraintEqualToAnchor:fromAThreadView.superview.topAnchor -// constant:bottomPositionY + PlainRoomCellLayoutConstants.fromAThreadViewTopMargin], -// [fromAThreadView.heightAnchor constraintEqualToConstant:height], -// [fromAThreadView.trailingAnchor constraintLessThanOrEqualToAnchor:fromAThreadView.superview.trailingAnchor constant:-PlainRoomCellLayoutConstants.reactionsViewRightMargin] -// ]]; -// } -// } -// } + if (RiotSettings.shared.enableThreads) + { + RoomBubbleCellData *cellData = (RoomBubbleCellData*)[self cellDataAtIndex:indexPath.row]; + MXEvent *event = cellData.events.firstObject; + + if (event) + { + if (cellData.hasThreadRoot) + { + id thread = cellData.bubbleComponents.firstObject.thread; + ThreadSummaryView *threadSummaryView = [[ThreadSummaryView alloc] initWithThread:thread + session:self.mxSession]; + [bubbleCell.tmpSubviews addObject:threadSummaryView]; + + threadSummaryView.translatesAutoresizingMaskIntoConstraints = NO; + [bubbleCell.contentView addSubview:threadSummaryView]; + + CGFloat leftMargin = PlainRoomCellLayoutConstants.reactionsViewLeftMargin; + CGFloat height = [ThreadSummaryView contentViewHeightForThread:thread fitting:cellData.maxTextViewWidth]; + + CGRect bubbleComponentFrame = [bubbleCell componentFrameInContentViewForIndex:0]; + CGFloat bottomPositionY = bubbleComponentFrame.origin.y + bubbleComponentFrame.size.height; + + // Set constraints for the summary view + [NSLayoutConstraint activateConstraints: @[ + [threadSummaryView.leadingAnchor constraintEqualToAnchor:threadSummaryView.superview.leadingAnchor + constant:leftMargin], + [threadSummaryView.topAnchor constraintEqualToAnchor:threadSummaryView.superview.topAnchor + constant:bottomPositionY + PlainRoomCellLayoutConstants.threadSummaryViewTopMargin], + [threadSummaryView.heightAnchor constraintEqualToConstant:height], + [threadSummaryView.trailingAnchor constraintLessThanOrEqualToAnchor:threadSummaryView.superview.trailingAnchor constant:-PlainRoomCellLayoutConstants.reactionsViewRightMargin] + ]]; + } + else if (event.isInThread) + { + FromAThreadView *fromAThreadView = [FromAThreadView instantiate]; + [bubbleCell.tmpSubviews addObject:fromAThreadView]; + + fromAThreadView.translatesAutoresizingMaskIntoConstraints = NO; + [bubbleCell.contentView addSubview:fromAThreadView]; + + CGFloat leftMargin = PlainRoomCellLayoutConstants.reactionsViewLeftMargin; + CGFloat height = [FromAThreadView contentViewHeightForEvent:event fitting:cellData.maxTextViewWidth]; + + CGRect bubbleComponentFrame = [bubbleCell componentFrameInContentViewForIndex:0]; + CGFloat bottomPositionY = bubbleComponentFrame.origin.y + bubbleComponentFrame.size.height; + + // Set constraints for the summary view + [NSLayoutConstraint activateConstraints: @[ + [fromAThreadView.leadingAnchor constraintEqualToAnchor:fromAThreadView.superview.leadingAnchor + constant:leftMargin], + [fromAThreadView.topAnchor constraintEqualToAnchor:fromAThreadView.superview.topAnchor + constant:bottomPositionY + PlainRoomCellLayoutConstants.fromAThreadViewTopMargin], + [fromAThreadView.heightAnchor constraintEqualToConstant:height], + [fromAThreadView.trailingAnchor constraintLessThanOrEqualToAnchor:fromAThreadView.superview.trailingAnchor constant:-PlainRoomCellLayoutConstants.reactionsViewRightMargin] + ]]; + } + } + } } return cell; diff --git a/Riot/Modules/Room/TimelineCells/BaseRoomCell/BaseRoomCell.swift b/Riot/Modules/Room/TimelineCells/BaseRoomCell/BaseRoomCell.swift index c3cf0b5a0f..a37bf69379 100644 --- a/Riot/Modules/Room/TimelineCells/BaseRoomCell/BaseRoomCell.swift +++ b/Riot/Modules/Room/TimelineCells/BaseRoomCell/BaseRoomCell.swift @@ -359,16 +359,16 @@ class BaseRoomCell: MXKRoomBubbleTableViewCell, BaseRoomCellProtocol { // MARK: - RoomCellThreadSummaryDisplayable -// func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView) { -// self.roomCellContentView?.addThreadSummaryView(threadSummaryView) -// -// // tmpSubviews is used for touch detection in MXKRoomBubbleTableViewCell -// self.addTemporarySubview(threadSummaryView) -// } -// -// func removeThreadSummaryView() { -// self.roomCellContentView?.removeThreadSummaryView() -// } + func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView) { + self.roomCellContentView?.addThreadSummaryView(threadSummaryView) + + // tmpSubviews is used for touch detection in MXKRoomBubbleTableViewCell + self.addTemporarySubview(threadSummaryView) + } + + func removeThreadSummaryView() { + self.roomCellContentView?.removeThreadSummaryView() + } // MARK: - RoomCellReadMarkerDisplayable diff --git a/Riot/Modules/Room/TimelineCells/BaseRoomCell/RoomCellContentView.swift b/Riot/Modules/Room/TimelineCells/BaseRoomCell/RoomCellContentView.swift index e188ac257f..4f89967251 100644 --- a/Riot/Modules/Room/TimelineCells/BaseRoomCell/RoomCellContentView.swift +++ b/Riot/Modules/Room/TimelineCells/BaseRoomCell/RoomCellContentView.swift @@ -240,43 +240,43 @@ extension RoomCellContentView: RoomCellReactionsDisplayable { // MARK: - RoomCellThreadSummaryDisplayable extension RoomCellContentView: RoomCellThreadSummaryDisplayable { -// func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView) { -// -// guard let containerView = self.threadSummaryContentView else { -// return -// } -// -// containerView.vc_removeAllSubviews() -// -// containerView.translatesAutoresizingMaskIntoConstraints = false -// containerView.addSubview(threadSummaryView) -// -// let leadingConstraint: NSLayoutConstraint -// let trailingConstraint: NSLayoutConstraint -// -// if self.decorationViewsAlignment == .right { -// leadingConstraint = threadSummaryView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor) -// trailingConstraint = threadSummaryView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor) -// } else { -// leadingConstraint = threadSummaryView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor) -// trailingConstraint = threadSummaryView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor) -// } -// -// NSLayoutConstraint.activate([ -// leadingConstraint, -// threadSummaryView.topAnchor.constraint(equalTo: containerView.topAnchor), -// threadSummaryView.heightAnchor.constraint(equalToConstant: PlainRoomCellLayoutConstants.threadSummaryViewHeight), -// threadSummaryView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor), -// trailingConstraint -// ]) -// -// self.showThreadSummary = true -// } -// -// func removeThreadSummaryView() { -// self.showThreadSummary = false -// self.threadSummaryContentView.vc_removeAllSubviews() -// } + func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView) { + + guard let containerView = self.threadSummaryContentView else { + return + } + + containerView.vc_removeAllSubviews() + + containerView.translatesAutoresizingMaskIntoConstraints = false + containerView.addSubview(threadSummaryView) + + let leadingConstraint: NSLayoutConstraint + let trailingConstraint: NSLayoutConstraint + + if self.decorationViewsAlignment == .right { + leadingConstraint = threadSummaryView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor) + trailingConstraint = threadSummaryView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor) + } else { + leadingConstraint = threadSummaryView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor) + trailingConstraint = threadSummaryView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor) + } + + NSLayoutConstraint.activate([ + leadingConstraint, + threadSummaryView.topAnchor.constraint(equalTo: containerView.topAnchor), + threadSummaryView.heightAnchor.constraint(equalToConstant: PlainRoomCellLayoutConstants.threadSummaryViewHeight), + threadSummaryView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor), + trailingConstraint + ]) + + self.showThreadSummary = true + } + + func removeThreadSummaryView() { + self.showThreadSummary = false + self.threadSummaryContentView.vc_removeAllSubviews() + } } // MARK: - RoomCellURLPreviewDisplayable diff --git a/Riot/Modules/Room/TimelineCells/BaseRoomCell/RoomCellThreadSummaryDisplayable.swift b/Riot/Modules/Room/TimelineCells/BaseRoomCell/RoomCellThreadSummaryDisplayable.swift index 9c7b1fca96..c84416050c 100644 --- a/Riot/Modules/Room/TimelineCells/BaseRoomCell/RoomCellThreadSummaryDisplayable.swift +++ b/Riot/Modules/Room/TimelineCells/BaseRoomCell/RoomCellThreadSummaryDisplayable.swift @@ -18,6 +18,6 @@ import Foundation /// `RoomCellThreadSummaryDisplayable` is a protocol indicating that a cell support displaying a thread summary. @objc protocol RoomCellThreadSummaryDisplayable { -// func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView) -// func removeThreadSummaryView() + func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView) + func removeThreadSummaryView() } diff --git a/Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift b/Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift index 4f2ac729fb..df25796d11 100644 --- a/Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift @@ -204,78 +204,78 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { } } -// override func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView, -// toCell cell: MXKRoomBubbleTableViewCell, -// cellData: RoomBubbleCellData, -// contentViewPositionY: CGFloat, -// upperDecorationView: UIView?) { -// -// if let threadSummaryDisplayable = cell as? RoomCellThreadSummaryDisplayable { -// threadSummaryDisplayable.addThreadSummaryView(threadSummaryView) -// } else { -// -// cell.addTemporarySubview(threadSummaryView) -// threadSummaryView.translatesAutoresizingMaskIntoConstraints = false -// -// let cellContentView = cell.contentView -// -// cellContentView.addSubview(threadSummaryView) -// -// var rightMargin: CGFloat -// var leftMargin: CGFloat -// -// let leadingConstraint: NSLayoutConstraint -// let trailingConstraint: NSLayoutConstraint -// -// // Incoming message -// if cellData.isIncoming { -// -// leftMargin = BubbleRoomCellLayoutConstants.incomingBubbleBackgroundMargins.left -// if cellData.containsBubbleComponentWithEncryptionBadge { -// leftMargin += PlainRoomCellLayoutConstants.encryptedContentLeftMargin -// } -// -// rightMargin = BubbleRoomCellLayoutConstants.incomingBubbleBackgroundMargins.right -// -// leadingConstraint = threadSummaryView.leadingAnchor.constraint(equalTo: cellContentView.leadingAnchor, -// constant: leftMargin) -// trailingConstraint = threadSummaryView.trailingAnchor.constraint(lessThanOrEqualTo: cellContentView.trailingAnchor, -// constant: -rightMargin) -// } else { -// // Outgoing message -// -// leftMargin = BubbleRoomCellLayoutConstants.outgoingBubbleBackgroundMargins.left -// rightMargin = BubbleRoomCellLayoutConstants.outgoingBubbleBackgroundMargins.right -// -// leadingConstraint = threadSummaryView.leadingAnchor.constraint(greaterThanOrEqualTo: cellContentView.leadingAnchor, -// constant: leftMargin) -// trailingConstraint = threadSummaryView.trailingAnchor.constraint(equalTo: cellContentView.trailingAnchor, -// constant: -rightMargin) -// } -// -// let topMargin = PlainRoomCellLayoutConstants.threadSummaryViewTopMargin -// -// let height = ThreadSummaryView.contentViewHeight(forThread: threadSummaryView.thread, -// fitting: cellData.maxTextViewWidth) -// -// // The top constraint may need to include the URL preview view -// let topConstraint: NSLayoutConstraint -// if let upperDecorationView = upperDecorationView { -// topConstraint = threadSummaryView.topAnchor.constraint(equalTo: upperDecorationView.bottomAnchor, -// constant: topMargin) -// } else { -// topConstraint = threadSummaryView.topAnchor.constraint(equalTo: cellContentView.topAnchor, -// constant: contentViewPositionY + topMargin) -// } -// -// NSLayoutConstraint.activate([ -// leadingConstraint, -// trailingConstraint, -// threadSummaryView.heightAnchor.constraint(equalToConstant: height), -// topConstraint -// ]) -// } -// } + override func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView, + toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData, + contentViewPositionY: CGFloat, + upperDecorationView: UIView?) { + + if let threadSummaryDisplayable = cell as? RoomCellThreadSummaryDisplayable { + threadSummaryDisplayable.addThreadSummaryView(threadSummaryView) + } else { + + cell.addTemporarySubview(threadSummaryView) + threadSummaryView.translatesAutoresizingMaskIntoConstraints = false + + let cellContentView = cell.contentView + + cellContentView.addSubview(threadSummaryView) + + var rightMargin: CGFloat + var leftMargin: CGFloat + + let leadingConstraint: NSLayoutConstraint + let trailingConstraint: NSLayoutConstraint + + // Incoming message + if cellData.isIncoming { + + leftMargin = BubbleRoomCellLayoutConstants.incomingBubbleBackgroundMargins.left + if cellData.containsBubbleComponentWithEncryptionBadge { + leftMargin += PlainRoomCellLayoutConstants.encryptedContentLeftMargin + } + + rightMargin = BubbleRoomCellLayoutConstants.incomingBubbleBackgroundMargins.right + + leadingConstraint = threadSummaryView.leadingAnchor.constraint(equalTo: cellContentView.leadingAnchor, + constant: leftMargin) + trailingConstraint = threadSummaryView.trailingAnchor.constraint(lessThanOrEqualTo: cellContentView.trailingAnchor, + constant: -rightMargin) + } else { + // Outgoing message + + leftMargin = BubbleRoomCellLayoutConstants.outgoingBubbleBackgroundMargins.left + rightMargin = BubbleRoomCellLayoutConstants.outgoingBubbleBackgroundMargins.right + + leadingConstraint = threadSummaryView.leadingAnchor.constraint(greaterThanOrEqualTo: cellContentView.leadingAnchor, + constant: leftMargin) + trailingConstraint = threadSummaryView.trailingAnchor.constraint(equalTo: cellContentView.trailingAnchor, + constant: -rightMargin) + } + + let topMargin = PlainRoomCellLayoutConstants.threadSummaryViewTopMargin + + let height = ThreadSummaryView.contentViewHeight(forThread: threadSummaryView.thread, + fitting: cellData.maxTextViewWidth) + + // The top constraint may need to include the URL preview view + let topConstraint: NSLayoutConstraint + if let upperDecorationView = upperDecorationView { + topConstraint = threadSummaryView.topAnchor.constraint(equalTo: upperDecorationView.bottomAnchor, + constant: topMargin) + } else { + topConstraint = threadSummaryView.topAnchor.constraint(equalTo: cellContentView.topAnchor, + constant: contentViewPositionY + topMargin) + } + + NSLayoutConstraint.activate([ + leadingConstraint, + trailingConstraint, + threadSummaryView.heightAnchor.constraint(equalToConstant: height), + topConstraint + ]) + } + } // MARK: - Private diff --git a/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift b/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift index 05ed2b309d..0dd54623a1 100644 --- a/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift @@ -152,54 +152,54 @@ class PlainRoomTimelineCellDecorator: RoomTimelineCellDecorator { } } -// func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView, -// toCell cell: MXKRoomBubbleTableViewCell, -// cellData: RoomBubbleCellData, -// contentViewPositionY: CGFloat, -// upperDecorationView: UIView?) { -// -// cell.addTemporarySubview(threadSummaryView) -// -// if let threadSummaryDisplayable = cell as? RoomCellThreadSummaryDisplayable { -// threadSummaryDisplayable.addThreadSummaryView(threadSummaryView) -// } else { -// threadSummaryView.translatesAutoresizingMaskIntoConstraints = false -// -// let cellContentView = cell.contentView -// -// cellContentView.addSubview(threadSummaryView) -// -// var leftMargin = PlainRoomCellLayoutConstants.reactionsViewLeftMargin -// -// if cellData.containsBubbleComponentWithEncryptionBadge { -// leftMargin += PlainRoomCellLayoutConstants.encryptedContentLeftMargin -// } -// -// let rightMargin = PlainRoomCellLayoutConstants.reactionsViewRightMargin -// let topMargin = PlainRoomCellLayoutConstants.threadSummaryViewTopMargin -// let height = ThreadSummaryView.contentViewHeight(forThread: threadSummaryView.thread, -// fitting: cellData.maxTextViewWidth) -// -// // The top constraint may need to include the URL preview view -// let topConstraint: NSLayoutConstraint -// if let upperDecorationView = upperDecorationView { -// topConstraint = threadSummaryView.topAnchor.constraint(equalTo: upperDecorationView.bottomAnchor, -// constant: topMargin) -// } else { -// topConstraint = threadSummaryView.topAnchor.constraint(equalTo: cellContentView.topAnchor, -// constant: contentViewPositionY + topMargin) -// } -// -// NSLayoutConstraint.activate([ -// threadSummaryView.leadingAnchor.constraint(equalTo: cellContentView.leadingAnchor, -// constant: leftMargin), -// threadSummaryView.trailingAnchor.constraint(lessThanOrEqualTo: cellContentView.trailingAnchor, -// constant: -rightMargin), -// threadSummaryView.heightAnchor.constraint(equalToConstant: height), -// topConstraint -// ]) -// } -// } + func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView, + toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData, + contentViewPositionY: CGFloat, + upperDecorationView: UIView?) { + + cell.addTemporarySubview(threadSummaryView) + + if let threadSummaryDisplayable = cell as? RoomCellThreadSummaryDisplayable { + threadSummaryDisplayable.addThreadSummaryView(threadSummaryView) + } else { + threadSummaryView.translatesAutoresizingMaskIntoConstraints = false + + let cellContentView = cell.contentView + + cellContentView.addSubview(threadSummaryView) + + var leftMargin = PlainRoomCellLayoutConstants.reactionsViewLeftMargin + + if cellData.containsBubbleComponentWithEncryptionBadge { + leftMargin += PlainRoomCellLayoutConstants.encryptedContentLeftMargin + } + + let rightMargin = PlainRoomCellLayoutConstants.reactionsViewRightMargin + let topMargin = PlainRoomCellLayoutConstants.threadSummaryViewTopMargin + let height = ThreadSummaryView.contentViewHeight(forThread: threadSummaryView.thread, + fitting: cellData.maxTextViewWidth) + + // The top constraint may need to include the URL preview view + let topConstraint: NSLayoutConstraint + if let upperDecorationView = upperDecorationView { + topConstraint = threadSummaryView.topAnchor.constraint(equalTo: upperDecorationView.bottomAnchor, + constant: topMargin) + } else { + topConstraint = threadSummaryView.topAnchor.constraint(equalTo: cellContentView.topAnchor, + constant: contentViewPositionY + topMargin) + } + + NSLayoutConstraint.activate([ + threadSummaryView.leadingAnchor.constraint(equalTo: cellContentView.leadingAnchor, + constant: leftMargin), + threadSummaryView.trailingAnchor.constraint(lessThanOrEqualTo: cellContentView.trailingAnchor, + constant: -rightMargin), + threadSummaryView.heightAnchor.constraint(equalToConstant: height), + topConstraint + ]) + } + } func addSendStatusView(toCell cell: MXKRoomBubbleTableViewCell, withFailedEventIds failedEventIds: Set) { cell.updateTickView(withFailedEventIds: failedEventIds) diff --git a/Riot/Modules/Room/TimelineCells/Styles/RoomTimelineCellDecorator.swift b/Riot/Modules/Room/TimelineCells/Styles/RoomTimelineCellDecorator.swift index 5f4e881dc2..fd488294ca 100644 --- a/Riot/Modules/Room/TimelineCells/Styles/RoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/TimelineCells/Styles/RoomTimelineCellDecorator.swift @@ -42,11 +42,11 @@ protocol RoomTimelineCellDecorator { contentViewPositionY: CGFloat, upperDecorationView: UIView?) -// func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView, -// toCell cell: MXKRoomBubbleTableViewCell, -// cellData: RoomBubbleCellData, -// contentViewPositionY: CGFloat, -// upperDecorationView: UIView?) + func addThreadSummaryView(_ threadSummaryView: ThreadSummaryView, + toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData, + contentViewPositionY: CGFloat, + upperDecorationView: UIView?) func addSendStatusView(toCell cell: MXKRoomBubbleTableViewCell, withFailedEventIds failedEventIds: Set) diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 16c9d8893a..bf2c751282 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -322,8 +322,7 @@ @interface SettingsViewController () ThreadsCoordinatorBridgePresenter? { -// return nil -// } + func threadsCoordinator(for roomViewController: RoomViewController, threadId: String?) -> ThreadsCoordinatorBridgePresenter? { + return nil + } } diff --git a/changelog.d/878.feature b/changelog.d/878.feature new file mode 100644 index 0000000000..111252a527 --- /dev/null +++ b/changelog.d/878.feature @@ -0,0 +1 @@ +Activer l'affichage en thread \ No newline at end of file