mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-05-02 22:26:59 +02:00
Merge commit '80bda1906235b6007b98f18fb13681fff587f4a3' into feature/basis_update_192
# Conflicts: # Config/AppVersion.xcconfig # Config/BuildSettings.swift # DesignKit/Source/ColorsSwiftUI.swift # DesignKit/Source/FontsSwiftUI.swift # DesignKit/Source/ThemeV2.swift # DesignKit/Variants/Colors/Dark/DarkColors.swift # DesignKit/Variants/Colors/Light/LightColors.swift # Podfile.lock # Riot/Assets/de.lproj/InfoPlist.strings # Riot/Assets/de.lproj/Vector.strings # Riot/Assets/en.lproj/Vector.strings # Riot/Generated/Images.swift # Riot/Generated/Strings.swift # Riot/Managers/PushNotification/PushNotificationService.m # Riot/Managers/Settings/RiotSettings.swift # Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h # Riot/Modules/Common/Recents/RecentsViewController.m # Riot/Modules/Communities/Home/GroupHomeViewController.m # Riot/Modules/Room/RoomViewController.m # Riot/Modules/SetPinCode/PinCodePreferences.swift # Riot/Modules/Settings/SettingsViewController.m # Riot/Modules/TabBar/MasterTabBarController.h # Riot/Modules/TabBar/MasterTabBarController.m # Riot/Modules/TabBar/TabBarCoordinator.swift # fastlane/Fastfile # project.yml
This commit is contained in:
@@ -227,6 +227,9 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
|
||||
@property (nonatomic, readwrite) RoomDisplayConfiguration *displayConfiguration;
|
||||
|
||||
// The direct chat target user. The room timeline is presented without an actual room until the direct chat is created
|
||||
@property (nonatomic, nullable, strong) MXUser *directChatTargetUser;
|
||||
|
||||
// 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.
|
||||
@@ -360,9 +363,11 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
|
||||
[self setupRemoveJitsiWidgetRemoveView];
|
||||
|
||||
// Replace the default input toolbar view.
|
||||
// Note: this operation will force the layout of subviews. That is why cell view classes must be registered before.
|
||||
[self updateRoomInputToolbarViewClassIfNeeded];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// Replace the default input toolbar view.
|
||||
// Note: this operation will force the layout of subviews. That is why cell view classes must be registered before.
|
||||
[self updateRoomInputToolbarViewClassIfNeeded];
|
||||
});
|
||||
|
||||
// set extra area
|
||||
[self setRoomActivitiesViewClass:RoomActivitiesView.class];
|
||||
@@ -553,6 +558,8 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
}
|
||||
|
||||
[self updateTopBanners];
|
||||
|
||||
self.bubblesTableView.clipsToBounds = NO;
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated
|
||||
@@ -1030,6 +1037,9 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
[self removeMatrixSession:self.mainSession];
|
||||
}
|
||||
|
||||
// Set potential discussion target user to nil, now use the dataSource to populate the view
|
||||
self.directChatTargetUser = nil;
|
||||
|
||||
// Enable the read marker display, and disable its update.
|
||||
dataSource.showReadMarker = YES;
|
||||
self.updateRoomReadMarker = NO;
|
||||
@@ -1108,6 +1118,10 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
[self forceLayoutRefresh];
|
||||
}
|
||||
}
|
||||
else if (self.isNewDirectChat)
|
||||
{
|
||||
[self refreshRoomInputToolbar];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self showPreviewHeader:NO];
|
||||
@@ -1193,8 +1207,8 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
{
|
||||
[super setRoomInputToolbarViewClass:roomInputToolbarViewClass];
|
||||
|
||||
// The voice message toolbar cannot be set on DisabledInputToolbarView.
|
||||
if ([self.inputToolbarView isKindOfClass:RoomInputToolbarView.class] && BuildSettings.bwiEnableVoiceMessages)
|
||||
// The voice message toolbar cannot be set on DisabledInputToolbarView and on new direct chat.
|
||||
if ([self.inputToolbarView isKindOfClass:RoomInputToolbarView.class] && !self.isNewDirectChat)
|
||||
{
|
||||
[(RoomInputToolbarView *)self.inputToolbarView setVoiceMessageToolbarView:self.voiceMessageController.voiceMessageToolbarView];
|
||||
}
|
||||
@@ -1327,40 +1341,49 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
|
||||
- (void)sendTextMessage:(NSString*)msgTxt
|
||||
{
|
||||
// The event modified is always fetch from the actual data source
|
||||
MXEvent *eventModified = [self.roomDataSource eventWithEventId:self.customizedRoomDataSource.selectedEventId];
|
||||
|
||||
// In the case the event is a reply or and edit, and it's done on a non-live timeline
|
||||
// we have to fetch live timeline in order to display the event properly
|
||||
[self setupRoomDataSourceToResolveEvent:^(MXKRoomDataSource *roomDataSource) {
|
||||
if (self.inputToolBarSendMode == RoomInputToolbarViewSendModeReply && eventModified)
|
||||
// Create before sending the message in case of a discussion (direct chat)
|
||||
MXWeakify(self);
|
||||
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
if (readyToSend)
|
||||
{
|
||||
[roomDataSource sendReplyToEvent:eventModified withTextMessage:msgTxt success:nil failure:^(NSError *error) {
|
||||
// Just log the error. The message will be displayed in red in the room history
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
// The event modified is always fetch from the actual data source
|
||||
MXEvent *eventModified = [self.roomDataSource eventWithEventId:self.customizedRoomDataSource.selectedEventId];
|
||||
|
||||
// In the case the event is a reply or and edit, and it's done on a non-live timeline
|
||||
// we have to fetch live timeline in order to display the event properly
|
||||
[self setupRoomDataSourceToResolveEvent:^(MXKRoomDataSource *roomDataSource) {
|
||||
if (self.inputToolBarSendMode == RoomInputToolbarViewSendModeReply && eventModified)
|
||||
{
|
||||
[roomDataSource sendReplyToEvent:eventModified withTextMessage:msgTxt success:nil failure:^(NSError *error) {
|
||||
// Just log the error. The message will be displayed in red in the room history
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
}];
|
||||
}
|
||||
else if (self.inputToolBarSendMode == RoomInputToolbarViewSendModeEdit && eventModified)
|
||||
{
|
||||
[roomDataSource replaceTextMessageForEvent:eventModified withTextMessage:msgTxt success:nil failure:^(NSError *error) {
|
||||
// Just log the error. The message will be displayed in red
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let the datasource send it and manage the local echo
|
||||
[roomDataSource sendTextMessage:msgTxt success:nil failure:^(NSError *error)
|
||||
{
|
||||
// Just log the error. The message will be displayed in red in the room history
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
}];
|
||||
}
|
||||
|
||||
if (self.customizedRoomDataSource.selectedEventId)
|
||||
{
|
||||
[self cancelEventSelection];
|
||||
}
|
||||
}];
|
||||
}
|
||||
else if (self.inputToolBarSendMode == RoomInputToolbarViewSendModeEdit && eventModified)
|
||||
{
|
||||
[roomDataSource replaceTextMessageForEvent:eventModified withTextMessage:msgTxt success:nil failure:^(NSError *error) {
|
||||
// Just log the error. The message will be displayed in red
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let the datasource send it and manage the local echo
|
||||
[roomDataSource sendTextMessage:msgTxt success:nil failure:^(NSError *error)
|
||||
{
|
||||
// Just log the error. The message will be displayed in red in the room history
|
||||
MXLogDebug(@"[MXKRoomViewController] sendTextMessage failed.");
|
||||
}];
|
||||
}
|
||||
|
||||
if (self.customizedRoomDataSource.selectedEventId)
|
||||
{
|
||||
[self cancelEventSelection];
|
||||
}
|
||||
// Errors are handled at the request level. This should be improved in case of code rewriting.
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -1406,6 +1429,7 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
[self setValue:titleView forKey:@"titleView"];
|
||||
titleView.delegate = self;
|
||||
titleView.mxRoom = self.roomDataSource.room;
|
||||
titleView.mxUser = self.directChatTargetUser;
|
||||
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:titleView];
|
||||
|
||||
if ([titleView isKindOfClass:RoomTitleView.class])
|
||||
@@ -1495,6 +1519,61 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
[super destroy];
|
||||
}
|
||||
|
||||
#pragma mark - Start DM
|
||||
|
||||
/**
|
||||
Create a direct chat with given user.
|
||||
*/
|
||||
- (void)createDiscussionWithUser:(MXUser*)user completion:(void (^)(BOOL success))onComplete
|
||||
{
|
||||
[self startActivityIndicator];
|
||||
|
||||
[[AppDelegate theDelegate] createDirectChatWithUserId:user.userId completion:^(NSString *roomId) {
|
||||
if (roomId)
|
||||
{
|
||||
MXKRoomDataSourceManager *roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:self.mainSession];
|
||||
[roomDataSourceManager roomDataSourceForRoom:roomId create:YES onComplete:^(MXKRoomDataSource *roomDataSource) {
|
||||
[self stopActivityIndicator];
|
||||
[self setRoomInputToolbarViewClass:nil];
|
||||
[self displayRoom:roomDataSource];
|
||||
|
||||
onComplete(YES);
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self stopActivityIndicator];
|
||||
onComplete(NO);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
/**
|
||||
Create the discussion if needed
|
||||
*/
|
||||
- (void)createDiscussionIfNeeded:(void (^)(BOOL readyToSend))onComplete
|
||||
{
|
||||
// Disable the input tool bar during this operation. This prevents us from creating several discussions, or
|
||||
// trying to send several invites.
|
||||
self.inputToolbarView.userInteractionEnabled = false;
|
||||
|
||||
void(^completion)(BOOL) = ^(BOOL readyToSend) {
|
||||
self.inputToolbarView.userInteractionEnabled = true;
|
||||
if (onComplete) {
|
||||
onComplete(readyToSend);
|
||||
}
|
||||
};
|
||||
|
||||
if (self.directChatTargetUser)
|
||||
{
|
||||
[self createDiscussionWithUser:self.directChatTargetUser completion:completion];
|
||||
}
|
||||
else
|
||||
{
|
||||
completion(YES);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
-(void)setActivitiesViewExpanded:(BOOL)activitiesViewExpanded
|
||||
@@ -1663,6 +1742,12 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Indicates if a new direct chat with a target user (without associated room) is occuring.
|
||||
- (BOOL)isNewDirectChat
|
||||
{
|
||||
return self.directChatTargetUser != nil;
|
||||
}
|
||||
|
||||
- (BOOL)isEncryptionEnabled
|
||||
{
|
||||
return self.roomDataSource.room.summary.isEncrypted && self.mainSession.crypto != nil;
|
||||
@@ -1871,14 +1956,45 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (self.isNewDirectChat)
|
||||
{
|
||||
[self showPreviewHeader:NO];
|
||||
|
||||
[self setRoomTitleViewClass:RoomTitleView.class];
|
||||
MXKImageView *userPictureView = ((RoomTitleView*)self.titleView).pictureView;
|
||||
|
||||
// Set user picture in input toolbar
|
||||
if (userPictureView)
|
||||
{
|
||||
[userPictureView vc_setRoomAvatarImageWith:self.directChatTargetUser.avatarUrl
|
||||
roomId:self.directChatTargetUser.userId
|
||||
displayName:self.directChatTargetUser.displayname
|
||||
mediaManager:self.mainSession.mediaManager];
|
||||
}
|
||||
}
|
||||
|
||||
self.navigationItem.rightBarButtonItems = rightBarButtonItems;
|
||||
}
|
||||
|
||||
- (void)updateInputToolBarVisibility
|
||||
{
|
||||
BOOL hideInputToolBar = NO;
|
||||
|
||||
if (self.roomDataSource)
|
||||
{
|
||||
hideInputToolBar = (self.roomDataSource.state != MXKDataSourceStateReady);
|
||||
}
|
||||
|
||||
self.inputToolbarView.hidden = hideInputToolBar;
|
||||
}
|
||||
|
||||
- (void)refreshRoomInputToolbar
|
||||
{
|
||||
MXKImageView *userPictureView;
|
||||
|
||||
// Show or hide input tool bar
|
||||
[self updateInputToolBarVisibility];
|
||||
|
||||
// Check whether the input toolbar is ready before updating it.
|
||||
if (self.inputToolbarView && [self.inputToolbarView isKindOfClass:RoomInputToolbarView.class])
|
||||
{
|
||||
@@ -1889,6 +2005,13 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
|
||||
// Update actions when the input toolbar refreshed
|
||||
[self setupActions];
|
||||
|
||||
// Update placeholder and hide voice message view
|
||||
if (self.isNewDirectChat)
|
||||
{
|
||||
[self setInputToolBarSendMode:RoomInputToolbarViewSendModeCreateDM forEventWithId:nil];
|
||||
[roomInputToolbarView setVoiceMessageToolbarView:nil];
|
||||
}
|
||||
}
|
||||
else if (self.inputToolbarView && [self.inputToolbarView isKindOfClass:DisabledRoomInputToolbarView.class])
|
||||
{
|
||||
@@ -2151,7 +2274,7 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
[self showMediaPickerAnimated:YES];
|
||||
}]];
|
||||
}
|
||||
if (RiotSettings.shared.roomScreenAllowStickerAction)
|
||||
if (RiotSettings.shared.roomScreenAllowStickerAction && !self.isNewDirectChat)
|
||||
{
|
||||
[actionItems addObject:[[RoomActionItem alloc] initWithImage:AssetImages.actionSticker.image andAction:^{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
@@ -2171,7 +2294,7 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
[self roomInputToolbarViewDidTapFileUpload];
|
||||
}]];
|
||||
}
|
||||
if (BuildSettings.pollsEnabled && self.displayConfiguration.sendingPollsEnabled)
|
||||
if (BuildSettings.pollsEnabled && self.displayConfiguration.sendingPollsEnabled && !self.isNewDirectChat)
|
||||
{
|
||||
[actionItems addObject:[[RoomActionItem alloc] initWithImage:AssetImages.actionPoll.image andAction:^{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
@@ -2181,7 +2304,7 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
[self.delegate roomViewControllerDidRequestPollCreationFormPresentation:self];
|
||||
}]];
|
||||
}
|
||||
if (BuildSettings.locationSharingEnabled)
|
||||
if (BuildSettings.locationSharingEnabled && !self.isNewDirectChat)
|
||||
{
|
||||
[actionItems addObject:[[RoomActionItem alloc] initWithImage:AssetImages.actionLocation.image andAction:^{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
@@ -2315,7 +2438,15 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
|
||||
// Set the chosen preset and send the video (conversion takes place in the SDK).
|
||||
[MXSDKOptions sharedInstance].videoConversionPresetName = presetName;
|
||||
[roomInputToolbarView sendSelectedVideoAsset:videoAsset isPhotoLibraryAsset:isPhotoLibraryAsset];
|
||||
|
||||
// Create before sending the message in case of a discussion (direct chat)
|
||||
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
|
||||
if (readyToSend)
|
||||
{
|
||||
[[self inputToolbarViewAsRoomInputToolbarView] sendSelectedVideoAsset:videoAsset isPhotoLibraryAsset:isPhotoLibraryAsset];
|
||||
}
|
||||
// Errors are handled at the request level. This should be improved in case of code rewriting.
|
||||
}];
|
||||
}];
|
||||
compressionPrompt.popoverPresentationController.sourceView = roomInputToolbarView.attachMediaButton;
|
||||
compressionPrompt.popoverPresentationController.sourceRect = roomInputToolbarView.attachMediaButton.bounds;
|
||||
@@ -2326,7 +2457,15 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
{
|
||||
// Otherwise default to 1080p and send the video.
|
||||
[MXSDKOptions sharedInstance].videoConversionPresetName = AVAssetExportPreset1920x1080;
|
||||
[roomInputToolbarView sendSelectedVideoAsset:videoAsset isPhotoLibraryAsset:isPhotoLibraryAsset];
|
||||
|
||||
// Create before sending the message in case of a discussion (direct chat)
|
||||
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
|
||||
if (readyToSend)
|
||||
{
|
||||
[[self inputToolbarViewAsRoomInputToolbarView] sendSelectedVideoAsset:videoAsset isPhotoLibraryAsset:isPhotoLibraryAsset];
|
||||
}
|
||||
// Errors are handled at the request level. This should be improved in case of code rewriting.
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2396,7 +2535,7 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
[[AppDelegate theDelegate] createDirectChatWithUserId:userId completion:completion];
|
||||
[[AppDelegate theDelegate] showNewDirectChat:userId withMatrixSession:self.mainSession completion:completion];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2826,6 +2965,23 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - New discussion
|
||||
|
||||
- (void)displayNewDirectChatWithTargetUser:(nonnull MXUser*)directChatTargetUser session:(nonnull MXSession*)session
|
||||
{
|
||||
// Release existing room data source or preview
|
||||
[self displayRoom:nil];
|
||||
|
||||
self.directChatTargetUser = directChatTargetUser;
|
||||
|
||||
self.eventsAcknowledgementEnabled = NO;
|
||||
|
||||
[self addMatrixSession:session];
|
||||
|
||||
[self refreshRoomTitle];
|
||||
[self refreshRoomInputToolbar];
|
||||
}
|
||||
|
||||
#pragma mark - MXKDataSourceDelegate
|
||||
|
||||
- (Class<MXKCellRendering>)cellViewClassForCellData:(MXKCellData*)cellData
|
||||
@@ -4304,20 +4460,11 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
|
||||
NSString *roomIdOrAlias = absoluteURLString;
|
||||
|
||||
// Open the room or preview it
|
||||
NSString *fragment = [NSString stringWithFormat:@"/room/%@", [MXTools encodeURIComponent:roomIdOrAlias]];
|
||||
// Create a permalink to open or preview the room.
|
||||
NSString *permalink = [MXTools permalinkToRoom:roomIdOrAlias];
|
||||
NSURL *permalinkURL = [NSURL URLWithString:permalink];
|
||||
|
||||
[self handleUniversalLinkFragment:fragment fromURL:url];
|
||||
}
|
||||
// Preview the clicked group
|
||||
else if ([MXTools isMatrixGroupIdentifier:absoluteURLString])
|
||||
{
|
||||
shouldDoAction = NO;
|
||||
|
||||
// Open the group or preview it
|
||||
NSString *fragment = [NSString stringWithFormat:@"/group/%@", [MXTools encodeURIComponent:absoluteURLString]];
|
||||
|
||||
[self handleUniversalLinkFragment:fragment fromURL:url];
|
||||
[self handleUniversalLinkURL:permalinkURL];
|
||||
}
|
||||
else if ([absoluteURLString hasPrefix:EventFormatterOnReRequestKeysLinkAction])
|
||||
{
|
||||
@@ -4828,28 +4975,37 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
|
||||
- (void)roomInputToolbarView:(RoomInputToolbarView *)toolbarView sendAttributedTextMessage:(NSAttributedString *)attributedTextMessage
|
||||
{
|
||||
BOOL isMessageAHandledCommand = NO;
|
||||
// "/me" command is supported with Pills in RoomDataSource.
|
||||
if (![attributedTextMessage.string hasPrefix:kMXKSlashCmdEmote])
|
||||
{
|
||||
// Other commands currently work with identifiers (e.g. ban, invite, op, etc).
|
||||
NSString *message;
|
||||
if (@available(iOS 15.0, *))
|
||||
{
|
||||
message = [PillsFormatter stringByReplacingPillsIn:attributedTextMessage mode:PillsReplacementTextModeIdentifier];
|
||||
// Create before sending the message in case of a discussion (direct chat)
|
||||
MXWeakify(self);
|
||||
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
if (readyToSend) {
|
||||
BOOL isMessageAHandledCommand = NO;
|
||||
// "/me" command is supported with Pills in RoomDataSource.
|
||||
if (![attributedTextMessage.string hasPrefix:kMXKSlashCmdEmote])
|
||||
{
|
||||
// Other commands currently work with identifiers (e.g. ban, invite, op, etc).
|
||||
NSString *message;
|
||||
if (@available(iOS 15.0, *))
|
||||
{
|
||||
message = [PillsFormatter stringByReplacingPillsIn:attributedTextMessage mode:PillsReplacementTextModeIdentifier];
|
||||
}
|
||||
else
|
||||
{
|
||||
message = attributedTextMessage.string;
|
||||
}
|
||||
// Try to send the slash command
|
||||
isMessageAHandledCommand = [self sendAsIRCStyleCommandIfPossible:message];
|
||||
}
|
||||
|
||||
if (!isMessageAHandledCommand)
|
||||
{
|
||||
[self sendAttributedTextMessage:attributedTextMessage];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
message = attributedTextMessage.string;
|
||||
}
|
||||
// Try to send the slash command
|
||||
isMessageAHandledCommand = [self sendAsIRCStyleCommandIfPossible:message];
|
||||
}
|
||||
|
||||
if (!isMessageAHandledCommand)
|
||||
{
|
||||
[self sendAttributedTextMessage:attributedTextMessage];
|
||||
}
|
||||
// Errors are handled at the request level. This should be improved in case of code rewriting.
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - MXKRoomMemberDetailsViewControllerDelegate
|
||||
@@ -4972,7 +5128,9 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
{
|
||||
readMarkerTableViewCell = roomBubbleTableViewCell;
|
||||
|
||||
[self checkReadMarkerVisibility];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self checkReadMarkerVisibility];
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5001,7 +5159,7 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
[self checkReadMarkerVisibility];
|
||||
|
||||
// Switch back to the live mode when the user scrolls to the bottom of the non live timeline.
|
||||
if (!self.roomDataSource.isLive && ![self isRoomPreview])
|
||||
if (!self.roomDataSource.isLive && ![self isRoomPreview] && !self.isNewDirectChat)
|
||||
{
|
||||
CGFloat contentBottomPosY = self.bubblesTableView.contentOffset.y + self.bubblesTableView.frame.size.height - self.bubblesTableView.adjustedContentInset.bottom;
|
||||
if (contentBottomPosY >= self.bubblesTableView.contentSize.height && ![self.roomDataSource.timeline canPaginate:MXTimelineDirectionForwards])
|
||||
@@ -5707,7 +5865,7 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
if (self.saveProgressTextInput)
|
||||
{
|
||||
// Restore the potential message partially typed before jump to last unread messages.
|
||||
self.inputToolbarView.textMessage = roomDataSource.partialTextMessage;
|
||||
self.inputToolbarView.attributedTextMessage = roomDataSource.partialAttributedTextMessage;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5722,25 +5880,29 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
continueBlock(threadDataSource, YES);
|
||||
}];
|
||||
}
|
||||
else if (self.isContextPreview)
|
||||
else if (self.roomDataSource.roomId)
|
||||
{
|
||||
[RoomPreviewDataSource loadRoomDataSourceWithRoomId:self.roomDataSource.roomId
|
||||
andMatrixSession:self.mainSession
|
||||
onComplete:^(RoomPreviewDataSource *roomDataSource)
|
||||
{
|
||||
continueBlock(roomDataSource, YES);
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Switch back to the room live timeline managed by MXKRoomDataSourceManager
|
||||
MXKRoomDataSourceManager *roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:self.mainSession];
|
||||
if (self.isContextPreview)
|
||||
{
|
||||
[RoomPreviewDataSource loadRoomDataSourceWithRoomId:self.roomDataSource.roomId
|
||||
threadId:nil
|
||||
andMatrixSession:self.mainSession
|
||||
onComplete:^(RoomPreviewDataSource *roomDataSource)
|
||||
{
|
||||
continueBlock(roomDataSource, 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);
|
||||
}];
|
||||
[roomDataSourceManager roomDataSourceForRoom:self.roomDataSource.roomId
|
||||
create:YES
|
||||
onComplete:^(MXKRoomDataSource *roomDataSource) {
|
||||
continueBlock(roomDataSource, NO);
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7285,24 +7447,15 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
{
|
||||
NSData *imageData = [[NSData alloc] initWithContentsOfURL:url];
|
||||
|
||||
[self.roomDataSource sendImage:imageData mimeType:mimeType success:nil failure:^(NSError *error) {
|
||||
// Nothing to do. The image is marked as unsent in the room history by the datasource
|
||||
MXLogDebug(@"[MXKRoomViewController] sendImage failed.");
|
||||
}];
|
||||
[self sendImage:imageData mimeType:mimeType];
|
||||
}
|
||||
else if (fileUTI.isVideo)
|
||||
{
|
||||
[(RoomDataSource*)self.roomDataSource sendVideo:url success:nil failure:^(NSError *error) {
|
||||
// Nothing to do. The video is marked as unsent in the room history by the datasource
|
||||
MXLogDebug(@"[MXKRoomViewController] sendVideo failed.");
|
||||
}];
|
||||
[self sendVideo:url];
|
||||
}
|
||||
else if (fileUTI.isFile)
|
||||
{
|
||||
[self.roomDataSource sendFile:url mimeType:mimeType success:nil failure:^(NSError *error) {
|
||||
// Nothing to do. The file is marked as unsent in the room history by the datasource
|
||||
MXLogDebug(@"[MXKRoomViewController] sendFile failed.");
|
||||
}];
|
||||
[self sendFile:url mimeType:mimeType];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -7313,6 +7466,57 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sendImage:(NSData *)imageData mimeType:(NSString *)mimeType {
|
||||
// Create before sending the message in case of a discussion (direct chat)
|
||||
MXWeakify(self);
|
||||
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
if (readyToSend)
|
||||
{
|
||||
// Let the datasource send it and manage the local echo
|
||||
[self.roomDataSource sendImage:imageData mimeType:mimeType success:nil failure:^(NSError *error) {
|
||||
// Nothing to do. The image is marked as unsent in the room history by the datasource
|
||||
MXLogDebug(@"[MXKRoomViewController] sendImage failed.");
|
||||
}];
|
||||
}
|
||||
// Errors are handled at the request level. This should be improved in case of code rewriting.
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)sendVideo:(NSURL * _Nonnull)url {
|
||||
// Create before sending the message in case of a discussion (direct chat)
|
||||
MXWeakify(self);
|
||||
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
if (readyToSend)
|
||||
{
|
||||
// Let the datasource send it and manage the local echo
|
||||
[(RoomDataSource*)self.roomDataSource sendVideo:url success:nil failure:^(NSError *error) {
|
||||
// Nothing to do. The video is marked as unsent in the room history by the datasource
|
||||
MXLogDebug(@"[MXKRoomViewController] sendVideo failed.");
|
||||
}];
|
||||
}
|
||||
// Errors are handled at the request level. This should be improved in case of code rewriting.
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)sendFile:(NSURL * _Nonnull)url mimeType:(NSString *)mimeType {
|
||||
// Create before sending the message in case of a discussion (direct chat)
|
||||
MXWeakify(self);
|
||||
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
if (readyToSend)
|
||||
{
|
||||
// Let the datasource send it and manage the local echo
|
||||
[self.roomDataSource sendFile:url mimeType:mimeType success:nil failure:^(NSError *error) {
|
||||
// Nothing to do. The file is marked as unsent in the room history by the datasource
|
||||
MXLogDebug(@"[MXKRoomViewController] sendFile failed.");
|
||||
}];
|
||||
}
|
||||
// Errors are handled at the request level. This should be improved in case of code rewriting.
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - EmojiPickerCoordinatorBridgePresenterDelegate
|
||||
|
||||
- (void)emojiPickerCoordinatorBridgePresenter:(EmojiPickerCoordinatorBridgePresenter *)coordinatorBridgePresenter didAddEmoji:(NSString *)emoji forEventId:(NSString *)eventId
|
||||
@@ -7378,15 +7582,19 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
[cameraPresenter dismissWithAnimated:YES completion:nil];
|
||||
self.cameraPresenter = nil;
|
||||
|
||||
RoomInputToolbarView *roomInputToolbarView = [self inputToolbarViewAsRoomInputToolbarView];
|
||||
if (roomInputToolbarView)
|
||||
{
|
||||
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
|
||||
[roomInputToolbarView sendSelectedImage:imageData
|
||||
withMimeType:MXKUTI.jpeg.mimeType
|
||||
andCompressionMode:MediaCompressionHelper.defaultCompressionMode
|
||||
isPhotoLibraryAsset:NO];
|
||||
}
|
||||
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
|
||||
|
||||
// Create before sending the message in case of a discussion (direct chat)
|
||||
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
|
||||
if (readyToSend)
|
||||
{
|
||||
[[self inputToolbarViewAsRoomInputToolbarView] sendSelectedImage:imageData
|
||||
withMimeType:MXKUTI.jpeg.mimeType
|
||||
andCompressionMode:MediaCompressionHelper.defaultCompressionMode
|
||||
isPhotoLibraryAsset:NO];
|
||||
}
|
||||
// Errors are handled at the request level. This should be improved in case of code rewriting.
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)cameraPresenter:(CameraPresenter *)cameraPresenter didSelectVideoAt:(NSURL *)url
|
||||
@@ -7411,14 +7619,17 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
[coordinatorBridgePresenter dismissWithAnimated:YES completion:nil];
|
||||
self.mediaPickerPresenter = nil;
|
||||
|
||||
RoomInputToolbarView *roomInputToolbarView = [self inputToolbarViewAsRoomInputToolbarView];
|
||||
if (roomInputToolbarView)
|
||||
{
|
||||
[roomInputToolbarView sendSelectedImage:imageData
|
||||
withMimeType:uti.mimeType
|
||||
andCompressionMode:MediaCompressionHelper.defaultCompressionMode
|
||||
isPhotoLibraryAsset:YES];
|
||||
}
|
||||
// Create before sending the message in case of a discussion (direct chat)
|
||||
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
|
||||
if (readyToSend)
|
||||
{
|
||||
[[self inputToolbarViewAsRoomInputToolbarView] sendSelectedImage:imageData
|
||||
withMimeType:uti.mimeType
|
||||
andCompressionMode:MediaCompressionHelper.defaultCompressionMode
|
||||
isPhotoLibraryAsset:YES];
|
||||
}
|
||||
// Errors are handled at the request level. This should be improved in case of code rewriting.
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)mediaPickerCoordinatorBridgePresenter:(MediaPickerCoordinatorBridgePresenter *)coordinatorBridgePresenter didSelectVideo:(AVAsset *)videoAsset
|
||||
@@ -7434,14 +7645,17 @@ static CGSize kThreadListBarButtonItemImageSize;
|
||||
[coordinatorBridgePresenter dismissWithAnimated:YES completion:nil];
|
||||
self.mediaPickerPresenter = nil;
|
||||
|
||||
RoomInputToolbarView *roomInputToolbarView = [self inputToolbarViewAsRoomInputToolbarView];
|
||||
if (roomInputToolbarView)
|
||||
{
|
||||
// Set a 1080p video conversion preset as compression mode only has an effect on the images.
|
||||
[MXSDKOptions sharedInstance].videoConversionPresetName = AVAssetExportPreset1920x1080;
|
||||
|
||||
[roomInputToolbarView sendSelectedAssets:assets withCompressionMode:MediaCompressionHelper.defaultCompressionMode];
|
||||
}
|
||||
// Set a 1080p video conversion preset as compression mode only has an effect on the images.
|
||||
[MXSDKOptions sharedInstance].videoConversionPresetName = AVAssetExportPreset1920x1080;
|
||||
|
||||
// Create before sending the message in case of a discussion (direct chat)
|
||||
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
|
||||
if (readyToSend)
|
||||
{
|
||||
[[self inputToolbarViewAsRoomInputToolbarView] sendSelectedAssets:assets withCompressionMode:MediaCompressionHelper.defaultCompressionMode];
|
||||
}
|
||||
// Errors are handled at the request level. This should be improved in case of code rewriting.
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - RoomCreationModalCoordinatorBridgePresenter
|
||||
|
||||
Reference in New Issue
Block a user