mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-20 16:42:44 +02:00
Merge branch 'develop' into steve/5210_bubble_polls
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user