diff --git a/Riot/Modules/Common/Views/BadgedBarButtonItem.swift b/Riot/Modules/Common/Views/BadgedBarButtonItem.swift index 99b8effbf..ea1fe95a2 100644 --- a/Riot/Modules/Common/Views/BadgedBarButtonItem.swift +++ b/Riot/Modules/Common/Views/BadgedBarButtonItem.swift @@ -50,6 +50,13 @@ class BadgedBarButtonItem: UIBarButtonItem { } } + private var shouldHideBadge: Bool { + guard let text = badgeText else { + return true + } + return text.isEmpty || text == "0" || text == "nil" || text == "null" + } + init(withBaseButton baseButton: UIButton) { self.baseButton = baseButton badgeBackgroundColor = .gray @@ -71,6 +78,7 @@ class BadgedBarButtonItem: UIBarButtonItem { } private func updateBadgeLabel() { + badgeLabel.isHidden = shouldHideBadge badgeLabel.backgroundColor = badgeBackgroundColor badgeLabel.font = badgeFont badgeLabel.textColor = badgeTextColor diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index f8252feed..19a68356a 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -140,7 +140,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; @interface RoomViewController () + RoomDataSourceDelegate, RoomCreationModalCoordinatorBridgePresenterDelegate, RoomInfoCoordinatorBridgePresenterDelegate, DialpadViewControllerDelegate, RemoveJitsiWidgetViewDelegate, VoiceMessageControllerDelegate, SpaceDetailPresenterDelegate, UserSuggestionCoordinatorBridgeDelegate, RoomCoordinatorBridgePresenterDelegate, ThreadsCoordinatorBridgePresenterDelegate, MXThreadingServiceDelegate> { // The preview header @@ -225,6 +225,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; @@ -565,6 +568,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; self.scrollToBottomBadgeLabel.badgeColor = ThemeService.shared.theme.tintColor; + [self updateThreadListBarButtonBadgeWith:self.mainSession.threadingService]; + [threadListBarButtonItem updateWithTheme:ThemeService.shared.theme]; + [self setNeedsStatusBarAppearanceUpdate]; } @@ -999,6 +1005,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]; @@ -1526,9 +1547,9 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; return item; } -- (UIBarButtonItem *)threadListBarButtonItem +- (BadgedBarButtonItem *)threadListBarButtonItem { - UIButton *button = [[UIButton alloc] init]; + UIButton *button = [UIButton new]; button.contentEdgeInsets = UIEdgeInsetsMake(4, 8, 4, 8); [button setImage:[UIImage imageNamed:@"room_context_menu_reply_in_thread"] forState:UIControlStateNormal]; @@ -1537,8 +1558,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; forControlEvents:UIControlEventTouchUpInside]; button.accessibilityLabel = [VectorL10n roomAccessibilityThreads]; - BadgedBarButtonItem *item = [[BadgedBarButtonItem alloc] initWithBaseButton:button]; - return item; + return [[BadgedBarButtonItem alloc] initWithBaseButton:button]; } - (void)setupRemoveJitsiWidgetRemoveView @@ -1784,8 +1804,10 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; 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]; } } } @@ -6430,6 +6452,45 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; } } +- (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:(NSInteger)numberOfThreads +{ + if (numberOfThreads < 100) + { + return [NSString stringWithFormat:@"%tu", numberOfThreads]; + } + else + { + return @"ยทยทยท"; + } +} + #pragma mark - RoomContextualMenuViewControllerDelegate - (void)roomContextualMenuViewControllerDidTapBackgroundOverlay:(RoomContextualMenuViewController *)viewController @@ -6891,4 +6952,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; self.threadsCoordinatorBridgePresenter = nil; } +#pragma mark - MXThreadingServiceDelegate + +- (void)threadingServiceDidUpdateThreads:(MXThreadingService *)service +{ + [self updateThreadListBarButtonBadgeWith:service]; +} + @end