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
@@ -45,6 +45,11 @@
*/
@property(nonatomic) BOOL showBubbleDateTimeOnSelection;
/**
Flag to decide displaying typing row in the data source. Default is YES.
*/
@property (nonatomic, assign) BOOL showTypingRow;
/**
Current room members trust level for an encrypted room.
*/
+17 -13
View File
@@ -132,6 +132,8 @@ const CGFloat kTypingCellHeight = 24;
[self.room.summary enableTrustTracking:YES];
[self fetchEncryptionTrustedLevel];
}
self.showTypingRow = YES;
}
- (id<RoomDataSourceDelegate>)roomDataSourceDelegate
@@ -269,7 +271,7 @@ const CGFloat kTypingCellHeight = 24;
else if (RiotSettings.shared.enableThreads)
{
// if not in a thread, ignore all threaded events
if (event.threadId)
if (event.isInThread)
{
// ignore the event
return NO;
@@ -279,7 +281,7 @@ const CGFloat kTypingCellHeight = 24;
{
MXEvent *relatedEvent = [self.mxSession.store eventWithEventId:event.relatesTo.eventId
inRoom:event.roomId];
if (relatedEvent.threadId)
if (relatedEvent.isInThread)
{
// ignore the event
return NO;
@@ -325,28 +327,30 @@ const CGFloat kTypingCellHeight = 24;
[self updateStatusInfo];
}
if (!self.currentTypingUsers)
if (self.showTypingRow && self.currentTypingUsers)
{
self.typingCellIndex = bubbles.count;
return bubbles.count + 1;
}
else
{
self.typingCellIndex = -1;
// we may have changed the number of bubbles in this block, consider that change
return bubbles.count;
}
self.typingCellIndex = bubbles.count;
return bubbles.count + 1;
}
if (!self.currentTypingUsers)
if (self.showTypingRow && self.currentTypingUsers)
{
self.typingCellIndex = count;
return count + 1;
}
else
{
self.typingCellIndex = -1;
// leave it as is, if coming as 0 from super
return count;
}
self.typingCellIndex = count;
return count + 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
@@ -19,6 +19,27 @@ import Foundation
@objcMembers
public class ThreadDataSource: RoomDataSource {
public override func finalizeInitialization() {
super.finalizeInitialization()
showReadMarker = false
showBubbleReceipts = false
showTypingRow = false
}
public override var showReadMarker: Bool {
get {
return false
} set {
_ = newValue
}
}
public override var showBubbleReceipts: Bool {
get {
return false
} set {
_ = newValue
}
}
}
@@ -54,7 +54,7 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat
override func awakeFromNib() {
super.awakeFromNib()
mapView = MGLMapView(frame: .zero, styleURL: BuildSettings.tileServerMapURL)
mapView = MGLMapView(frame: .zero)
mapView.delegate = self
mapView.logoView.isHidden = true
mapView.attributionButton.isHidden = true
@@ -72,7 +72,11 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat
// MARK: - Public
public func displayLocation(_ location: CLLocationCoordinate2D, userAvatarData: AvatarViewData? = nil) {
public func displayLocation(_ location: CLLocationCoordinate2D,
userAvatarData: AvatarViewData? = nil,
mapStyleURL: URL) {
mapView.styleURL = mapStyleURL
annotationView = LocationMarkerView.loadFromNib()
@@ -214,7 +214,7 @@
if (membersListener)
{
MXWeakify(self);
[self.mxRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
[self.mxRoom liveTimeline:^(id<MXEventTimeline> liveTimeline) {
MXStrongifyAndReturnIfNil(self);
[liveTimeline removeListener:self->membersListener];
@@ -333,7 +333,7 @@
if (self->membersListener)
{
MXWeakify(self);
[self.mxRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
[self.mxRoom liveTimeline:^(id<MXEventTimeline> liveTimeline) {
MXStrongifyAndReturnIfNil(self);
[liveTimeline removeListener:self->membersListener];
@@ -399,7 +399,7 @@
NSArray *mxMembersEvents = @[kMXEventTypeStringRoomMember, kMXEventTypeStringRoomThirdPartyInvite, kMXEventTypeStringRoomPowerLevels];
MXWeakify(self);
[self.mxRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
[self.mxRoom liveTimeline:^(id<MXEventTimeline> liveTimeline) {
MXStrongifyAndReturnIfNil(self);
self->membersListener = [liveTimeline listenToEventsOfTypes:mxMembersEvents onEvent:^(MXEvent *event, MXTimelineDirection direction, id customObject) {
+10 -2
View File
@@ -206,9 +206,9 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol {
// Present activity indicator when retrieving roomDataSource for given room ID
self.activityIndicatorPresenter.presentActivityIndicator(on: roomViewController.view, animated: false)
// Open the room on the requested event
// Open the thread on the requested event
ThreadDataSource.load(withRoomId: roomId,
initialEventId: nil,
initialEventId: eventId,
threadId: threadId,
andMatrixSession: self.parameters.session) { [weak self] (dataSource) in
@@ -386,6 +386,14 @@ extension RoomCoordinator: RoomViewControllerDelegate {
startLocationCoordinatorWithEvent(event, bubbleData: bubbleData)
}
func roomViewController(_ roomViewController: RoomViewController, locationShareActivityViewControllerFor event: MXEvent) -> UIActivityViewController? {
guard let location = event.location else {
return nil
}
return LocationSharingCoordinator.shareLocationActivityController(CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude))
}
func roomViewController(_ roomViewController: RoomViewController, canEndPollWithEventIdentifier eventIdentifier: String) -> Bool {
guard #available(iOS 14.0, *) else {
return false
+3
View File
@@ -219,6 +219,9 @@ handleUniversalLinkWithParameters:(UniversalLinkParameters*)parameters;
didRequestLocationPresentationForEvent:(MXEvent *)event
bubbleData:(id<MXKRoomBubbleCellDataStoring>)bubbleData;
- (nullable UIActivityViewController *)roomViewController:(RoomViewController *)roomViewController
locationShareActivityViewControllerForEvent:(MXEvent *)event;
- (BOOL)roomViewController:(RoomViewController *)roomViewController
canEndPollWithEventIdentifier:(NSString *)eventIdentifier;
+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
@@ -57,33 +57,69 @@
{
// Prepare text font used to highlight the search pattern.
UIFont *patternFont = [roomDataSource.eventFormatter bingTextFont];
dispatch_group_t group = dispatch_group_create();
// Convert the HS results into `RoomViewController` cells
for (MXSearchResult *result in roomEventResults.results)
{
// Let the `RoomViewController` ecosystem do the job
// The search result contains only room message events, no state events.
// Thus, passing the current room state is not a huge problem. Only
// the user display name and his avatar may be wrong.
RoomBubbleCellData *cellData = [[RoomBubbleCellData alloc] initWithEvent:result.result andRoomState:roomDataSource.roomState andRoomDataSource:roomDataSource];
if (cellData)
dispatch_group_enter(group);
void(^continueBlock)(void) = ^{
// Let the `RoomViewController` ecosystem do the job
// The search result contains only room message events, no state events.
// Thus, passing the current room state is not a huge problem. Only
// the user display name and his avatar may be wrong.
RoomBubbleCellData *cellData = [[RoomBubbleCellData alloc] initWithEvent:result.result andRoomState:self->roomDataSource.roomState andRoomDataSource:self->roomDataSource];
if (cellData)
{
// Highlight the search pattern
[cellData highlightPatternInTextMessage:self.searchText
withBackgroundColor:ThemeService.shared.theme.searchResultHighlightColor
foregroundColor:ThemeService.shared.theme.textPrimaryColor
andFont:patternFont];
// Use profile information as data to display
MXSearchUserProfile *userProfile = result.context.profileInfo[result.result.sender];
cellData.senderDisplayName = userProfile.displayName;
cellData.senderAvatarUrl = userProfile.avatarUrl;
[self->cellDataArray insertObject:cellData atIndex:0];
}
dispatch_group_leave(group);
};
if (RiotSettings.shared.enableThreads)
{
// Highlight the search pattern
[cellData highlightPatternInTextMessage:self.searchText
withBackgroundColor:[UIColor clearColor]
foregroundColor:ThemeService.shared.theme.tintColor
andFont:patternFont];
// Use profile information as data to display
MXSearchUserProfile *userProfile = result.context.profileInfo[result.result.sender];
cellData.senderDisplayName = userProfile.displayName;
cellData.senderAvatarUrl = userProfile.avatarUrl;
[cellDataArray insertObject:cellData atIndex:0];
if (result.result.isInThread)
{
continueBlock();
}
else
{
[roomDataSource.room liveTimeline:^(id<MXEventTimeline> liveTimeline) {
[liveTimeline paginate:NSUIntegerMax
direction:MXTimelineDirectionBackwards
onlyFromStore:YES
complete:^{
[liveTimeline resetPagination];
continueBlock();
} failure:^(NSError * _Nonnull error) {
continueBlock();
}];
}];
}
}
else
{
continueBlock();
}
}
onComplete();
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
onComplete();
});
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
@@ -93,6 +93,9 @@
UIImage *image = [MXKTools paintImage:backgroundImageView.image withColor:ThemeService.shared.theme.matrixSearchBackgroundImageTintColor];
backgroundImageView.image = image;
}
// Match the search bar color to the navigation bar color as it extends slightly outside the frame.
self.searchBar.backgroundColor = ThemeService.shared.theme.baseColor;
}
- (void)destroy
@@ -155,15 +158,18 @@
- (void)selectEvent:(MXEvent *)event
{
ThreadParameters *threadParameters = nil;
if (event.threadId)
if (RiotSettings.shared.enableThreads)
{
threadParameters = [[ThreadParameters alloc] initWithThreadId:event.threadId
stackRoomScreen:NO];
}
else if ([self.mainSession.threadingService isEventThreadRoot:event])
{
threadParameters = [[ThreadParameters alloc] initWithThreadId:event.eventId
stackRoomScreen:NO];
if (event.threadId)
{
threadParameters = [[ThreadParameters alloc] initWithThreadId:event.threadId
stackRoomScreen:NO];
}
else if ([self.mainSession.threadingService isEventThreadRoot:event])
{
threadParameters = [[ThreadParameters alloc] initWithThreadId:event.eventId
stackRoomScreen:NO];
}
}
ScreenPresentationParameters *screenParameters = [[ScreenPresentationParameters alloc] initWithRestoreInitialDisplay:NO
@@ -429,7 +429,7 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
if (extraEventsListener)
{
MXWeakify(self);
[mxRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
[mxRoom liveTimeline:^(id<MXEventTimeline> liveTimeline) {
MXStrongifyAndReturnIfNil(self);
[liveTimeline removeListener:self->extraEventsListener];
@@ -37,6 +37,8 @@ class LocationBubbleCell: SizableBaseBubbleCell, BubbleCellReactionsDisplayable
let location = CLLocationCoordinate2D(latitude: locationContent.latitude, longitude: locationContent.longitude)
let mapStyleURL = bubbleData.mxSession.vc_homeserverConfiguration().tileServer.mapStyleURL
if locationContent.assetType == .user {
let avatarViewData = AvatarViewData(matrixItemId: bubbleData.senderId,
displayName: bubbleData.senderDisplayName,
@@ -44,9 +46,9 @@ class LocationBubbleCell: SizableBaseBubbleCell, BubbleCellReactionsDisplayable
mediaManager: bubbleData.mxSession.mediaManager,
fallbackImage: .matrixItem(bubbleData.senderId, bubbleData.senderDisplayName))
locationView.displayLocation(location, userAvatarData: avatarViewData)
locationView.displayLocation(location, userAvatarData: avatarViewData, mapStyleURL: mapStyleURL)
} else {
locationView.displayLocation(location)
locationView.displayLocation(location, mapStyleURL: mapStyleURL)
}
}
@@ -42,7 +42,7 @@
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9wW-1f-f69" customClass="UserAvatarView" customModule="Riot" customModuleProvider="target">
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9wW-1f-f69" customClass="UserAvatarView" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="44" y="4" width="24" height="24"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>