Merge branch 'develop' into steve/5210_bubble_polls

This commit is contained in:
SBiOSoftWhare
2022-02-04 16:32:33 +01:00
87 changed files with 1698 additions and 527 deletions
+183 -46
View File
@@ -93,7 +93,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
@interface RoomViewController () <UISearchBarDelegate, UIGestureRecognizerDelegate, UIScrollViewAccessibilityDelegate, RoomTitleViewTapGestureDelegate, RoomParticipantsViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate, MXServerNoticesDelegate, RoomContextualMenuViewControllerDelegate,
ReactionsMenuViewModelCoordinatorDelegate, EditHistoryCoordinatorBridgePresenterDelegate, MXKDocumentPickerPresenterDelegate, EmojiPickerCoordinatorBridgePresenterDelegate,
ReactionHistoryCoordinatorBridgePresenterDelegate, CameraPresenterDelegate, MediaPickerCoordinatorBridgePresenterDelegate,
RoomDataSourceDelegate, RoomCreationModalCoordinatorBridgePresenterDelegate, RoomInfoCoordinatorBridgePresenterDelegate, DialpadViewControllerDelegate, RemoveJitsiWidgetViewDelegate, VoiceMessageControllerDelegate, SpaceDetailPresenterDelegate, UserSuggestionCoordinatorBridgeDelegate, ThreadsCoordinatorBridgePresenterDelegate>
RoomDataSourceDelegate, RoomCreationModalCoordinatorBridgePresenterDelegate, RoomInfoCoordinatorBridgePresenterDelegate, DialpadViewControllerDelegate, RemoveJitsiWidgetViewDelegate, VoiceMessageControllerDelegate, SpaceDetailPresenterDelegate, UserSuggestionCoordinatorBridgeDelegate, ThreadsCoordinatorBridgePresenterDelegate, MXThreadingServiceDelegate>
{
// The preview header
@@ -178,6 +178,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
// Time to display notification content in the timeline
MXTaskProfile *notificationTaskProfile;
// Reference to thread list bar button item, to update it easily later
BadgedBarButtonItem *threadListBarButtonItem;
}
@property (nonatomic, weak) IBOutlet UIView *overlayContainerView;
@@ -215,6 +218,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
@property (nonatomic, readwrite) RoomDisplayConfiguration *displayConfiguration;
@property (nonatomic) AnalyticsScreenTimer *screenTimer;
// When layout of the screen changes (e.g. height), we no longer know whether
// to autoscroll to the bottom again or not. Instead we need to capture the
// scroll state just before the layout change, and restore it after the layout.
@property (nonatomic) BOOL shouldScrollToBottomAfterLayout;
@end
@implementation RoomViewController
@@ -454,6 +462,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
self.scrollToBottomBadgeLabel.badgeColor = ThemeService.shared.theme.tintColor;
[self updateThreadListBarButtonBadgeWith:self.mainSession.threadingService];
[threadListBarButtonItem updateWithTheme:ThemeService.shared.theme];
[self setNeedsStatusBarAppearanceUpdate];
}
@@ -537,6 +548,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
[self cancelEventSelection];
}
}
[self cancelEventHighlight];
// Hide preview header to restore navigation bar settings
[self showPreviewHeader:NO];
@@ -650,6 +662,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
[self.screenTimer stop];
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
self.shouldScrollToBottomAfterLayout = self.isBubblesTableScrollViewAtTheBottom;
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
@@ -715,9 +732,10 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
self.edgesForExtendedLayout = UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight;
}
// stay at the bottom if already was
if (self.isBubblesTableScrollViewAtTheBottom)
// re-scroll to the bottom, if at bottom before the most recent layout
if (self.shouldScrollToBottomAfterLayout)
{
self.shouldScrollToBottomAfterLayout = NO;
[self scrollBubblesTableViewToBottomAnimated:NO];
}
@@ -889,6 +907,21 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
#pragma mark - Override MXKRoomViewController
- (void)addMatrixSession:(MXSession *)mxSession
{
[super addMatrixSession:mxSession];
[mxSession.threadingService addDelegate:self];
[self updateThreadListBarButtonBadgeWith:mxSession.threadingService];
}
- (void)removeMatrixSession:(MXSession *)mxSession
{
[mxSession.threadingService removeDelegate:self];
[super removeMatrixSession:mxSession];
}
- (void)onMatrixSessionChange
{
[super onMatrixSessionChange];
@@ -1416,15 +1449,20 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
return item;
}
- (UIBarButtonItem *)threadListBarButtonItem
- (BadgedBarButtonItem *)threadListBarButtonItem
{
UIButton *button = [UIButton new];
UIImage *icon = [[UIImage imageNamed:@"threads_icon"] vc_resizedWith:CGSizeMake(21, 21)];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:icon
style:UIBarButtonItemStylePlain
target:self
action:@selector(onThreadListTapped:)];
item.accessibilityLabel = [VectorL10n roomAccessibilityThreads];
return item;
button.contentEdgeInsets = UIEdgeInsetsMake(4, 8, 4, 8);
[button setImage:icon
forState:UIControlStateNormal];
[button addTarget:self
action:@selector(onThreadListTapped:)
forControlEvents:UIControlEventTouchUpInside];
button.accessibilityLabel = [VectorL10n roomAccessibilityThreads];
return [[BadgedBarButtonItem alloc] initWithBaseButton:button
theme:ThemeService.shared.theme];
}
- (void)setupRemoveJitsiWidgetRemoveView
@@ -1664,14 +1702,20 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
if (self.roomDataSource.threadId)
{
// in a thread
if (rightBarButtonItems == nil)
{
rightBarButtonItems = [NSMutableArray new];
}
UIBarButtonItem *itemThreadMore = [self threadMoreBarButtonItem];
[rightBarButtonItems insertObject:itemThreadMore atIndex:0];
}
else
{
// in a regular timeline
UIBarButtonItem *itemThreadList = [self threadListBarButtonItem];
BadgedBarButtonItem *itemThreadList = [self threadListBarButtonItem];
[rightBarButtonItems insertObject:itemThreadList atIndex:0];
threadListBarButtonItem = itemThreadList;
[self updateThreadListBarButtonBadgeWith:self.mainSession.threadingService];
}
}
}
@@ -3415,9 +3459,15 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
[self cancelEventSelection];
NSArray *activityItems = @[selectedComponent.textMessage];
UIActivityViewController *activityViewController = nil;
if (selectedEvent.location) {
activityViewController = [self.delegate roomViewController:self locationShareActivityViewControllerForEvent:selectedEvent];
}
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
if (activityViewController == nil) {
NSArray *activityItems = @[selectedComponent.textMessage];
activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
}
if (activityViewController)
{
@@ -4625,24 +4675,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
[super scrollViewWillBeginDragging:scrollView];
}
// if data source is highlighting an event, dismiss the highlight when user drags the table view
if (customizedRoomDataSource.highlightedEventId)
{
NSInteger row = [self.roomDataSource indexOfCellDataWithEventId:customizedRoomDataSource.highlightedEventId];
if (row == NSNotFound)
{
customizedRoomDataSource.highlightedEventId = nil;
return;
}
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
if ([[self.bubblesTableView indexPathsForVisibleRows] containsObject:indexPath])
{
customizedRoomDataSource.highlightedEventId = nil;
[self.bubblesTableView reloadRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
[self cancelEventHighlight];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
@@ -4848,7 +4881,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
if (typingNotifListener)
{
MXWeakify(self);
[self.roomDataSource.room liveTimeline:^(MXEventTimeline *liveTimeline) {
[self.roomDataSource.room liveTimeline:^(id<MXEventTimeline> liveTimeline) {
MXStrongifyAndReturnIfNil(self);
[liveTimeline removeListener:self->typingNotifListener];
@@ -5195,7 +5228,14 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
// Retrieve the unread messages count
NSUInteger unreadCount = self.roomDataSource.room.summary.localUnreadEventCount;
self.scrollToBottomBadgeLabel.text = unreadCount ? [NSString stringWithFormat:@"%lu", unreadCount] : nil;
if (!self.roomDataSource.threadId)
{
self.scrollToBottomBadgeLabel.text = unreadCount ? [NSString stringWithFormat:@"%lu", unreadCount] : nil;
}
else
{
self.scrollToBottomBadgeLabel.text = nil;
}
self.scrollToBottomHidden = NO;
}
else
@@ -5243,33 +5283,58 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
self.updateRoomReadMarker = NO;
[self scrollBubblesTableViewToBottomAnimated:YES];
[self cancelEventHighlight];
}
else
{
// Switch back to the room live timeline managed by MXKRoomDataSourceManager
MXKRoomDataSourceManager *roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:self.mainSession];
MXWeakify(self);
[roomDataSourceManager roomDataSourceForRoom:self.roomDataSource.roomId create:YES onComplete:^(MXKRoomDataSource *roomDataSource) {
void(^continueBlock)(MXKRoomDataSource *, BOOL) = ^(MXKRoomDataSource *roomDataSource, BOOL hasRoomDataSourceOwnership){
MXStrongifyAndReturnIfNil(self);
[roomDataSource finalizeInitialization];
// Scroll to bottom the bubble history on the display refresh.
self->shouldScrollToBottomOnTableRefresh = YES;
[self displayRoom:roomDataSource];
// The room view controller do not have here the data source ownership.
self.hasRoomDataSourceOwnership = NO;
// Set the room view controller has the data source ownership here.
self.hasRoomDataSourceOwnership = hasRoomDataSourceOwnership;
[self refreshActivitiesViewDisplay];
[self refreshJumpToLastUnreadBannerDisplay];
if (self.saveProgressTextInput)
{
// Restore the potential message partially typed before jump to last unread messages.
self.inputToolbarView.textMessage = roomDataSource.partialTextMessage;
}
}];
};
if (self.roomDataSource.threadId)
{
[ThreadDataSource loadRoomDataSourceWithRoomId:self.roomDataSource.roomId
initialEventId:nil
threadId:self.roomDataSource.threadId
andMatrixSession:self.mainSession
onComplete:^(ThreadDataSource *threadDataSource)
{
continueBlock(threadDataSource, YES);
}];
}
else
{
// Switch back to the room live timeline managed by MXKRoomDataSourceManager
MXKRoomDataSourceManager *roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:self.mainSession];
[roomDataSourceManager roomDataSourceForRoom:self.roomDataSource.roomId
create:YES
onComplete:^(MXKRoomDataSource *roomDataSource) {
continueBlock(roomDataSource, NO);
}];
}
}
}
@@ -6531,6 +6596,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
andMatrixSession:self.roomDataSource.mxSession
onComplete:^(RoomDataSource *roomDataSource) {
MXStrongifyAndReturnIfNil(self);
[roomDataSource finalizeInitialization];
[self stopActivityIndicator];
roomDataSource.markTimelineInitialEvent = YES;
[self displayRoom:roomDataSource];
@@ -6550,7 +6616,10 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
if ([[self.bubblesTableView indexPathsForVisibleRows] containsObject:indexPath])
{
[self.bubblesTableView reloadRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
withRowAnimation:UITableViewRowAnimationNone];
[self.bubblesTableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionMiddle
animated:YES];
}
else if ([self.bubblesTableView vc_hasIndexPath:indexPath])
{
@@ -6564,6 +6633,67 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
}
}
- (void)cancelEventHighlight
{
// if data source is highlighting an event, dismiss the highlight when user dragges the table view
if (customizedRoomDataSource.highlightedEventId)
{
NSInteger row = [self.roomDataSource indexOfCellDataWithEventId:customizedRoomDataSource.highlightedEventId];
if (row == NSNotFound)
{
customizedRoomDataSource.highlightedEventId = nil;
return;
}
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
if ([[self.bubblesTableView indexPathsForVisibleRows] containsObject:indexPath])
{
customizedRoomDataSource.highlightedEventId = nil;
[self.bubblesTableView reloadRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
}
- (void)updateThreadListBarButtonBadgeWith:(MXThreadingService *)service
{
if (!threadListBarButtonItem || !service)
{
// there is no thread list bar button, ignore
return;
}
MXThreadNotificationsCount *notificationsCount = [service notificationsCountForRoom:self.roomDataSource.roomId];
if (notificationsCount.numberOfHighlightedThreads > 0)
{
threadListBarButtonItem.badgeText = [self threadListBadgeTextFor:notificationsCount.numberOfHighlightedThreads];
threadListBarButtonItem.badgeBackgroundColor = ThemeService.shared.theme.colors.alert;
}
else if (notificationsCount.numberOfNotifiedThreads > 0)
{
threadListBarButtonItem.badgeText = [self threadListBadgeTextFor:notificationsCount.numberOfNotifiedThreads];
threadListBarButtonItem.badgeBackgroundColor = ThemeService.shared.theme.noticeSecondaryColor;
}
else
{
// remove badge
threadListBarButtonItem.badgeText = nil;
}
}
- (NSString *)threadListBadgeTextFor:(NSUInteger)numberOfThreads
{
if (numberOfThreads < 100)
{
return [NSString stringWithFormat:@"%tu", numberOfThreads];
}
else
{
return @"···";
}
}
#pragma mark - RoomContextualMenuViewControllerDelegate
- (void)roomContextualMenuViewControllerDidTapBackgroundOverlay:(RoomContextualMenuViewController *)viewController
@@ -6988,4 +7118,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05;
self.threadsBridgePresenter = nil;
}
#pragma mark - MXThreadingServiceDelegate
- (void)threadingServiceDidUpdateThreads:(MXThreadingService *)service
{
[self updateThreadListBarButtonBadgeWith:service];
}
@end