Merge commit 'a8c505c2f9175ae0bece1f62708e6fc31e587897' into feature/3746_merge_element_1.9.10

# Conflicts:
#	Config/AppConfiguration.swift
#	Config/AppVersion.xcconfig
#	Podfile.lock
#	Riot/Modules/Application/AppCoordinator.swift
#	Riot/Modules/Common/Avatar/AvatarView.swift
#	Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m
#	Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellProvider.m
#	Riot/Modules/Settings/Security/SecurityViewController.m
#	Riot/Modules/Settings/SettingsViewController.m
#	Riot/Modules/TabBar/TabBarCoordinator.swift
#	Riot/target.yml
#	fastlane/Fastfile
#	project.yml
This commit is contained in:
Frank Rotermund
2022-11-02 14:05:36 +01:00
467 changed files with 18708 additions and 2131 deletions
+301 -85
View File
@@ -100,7 +100,7 @@ static CGSize kThreadListBarButtonItemImageSize;
@interface RoomViewController () <UISearchBarDelegate, UIGestureRecognizerDelegate, UIScrollViewAccessibilityDelegate, RoomTitleViewTapGestureDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate, MXServerNoticesDelegate, RoomContextualMenuViewControllerDelegate,
ReactionsMenuViewModelCoordinatorDelegate, EditHistoryCoordinatorBridgePresenterDelegate, MXKDocumentPickerPresenterDelegate, EmojiPickerCoordinatorBridgePresenterDelegate,
ReactionHistoryCoordinatorBridgePresenterDelegate, CameraPresenterDelegate, MediaPickerCoordinatorBridgePresenterDelegate,
RoomDataSourceDelegate, RoomCreationModalCoordinatorBridgePresenterDelegate, RoomInfoCoordinatorBridgePresenterDelegate, DialpadViewControllerDelegate, RemoveJitsiWidgetViewDelegate, VoiceMessageControllerDelegate, SpaceDetailPresenterDelegate, UserSuggestionCoordinatorBridgeDelegate, ThreadsCoordinatorBridgePresenterDelegate, ThreadsBetaCoordinatorBridgePresenterDelegate, MXThreadingServiceDelegate, RoomParticipantsInviteCoordinatorBridgePresenterDelegate>
RoomDataSourceDelegate, RoomCreationModalCoordinatorBridgePresenterDelegate, RoomInfoCoordinatorBridgePresenterDelegate, DialpadViewControllerDelegate, RemoveJitsiWidgetViewDelegate, VoiceMessageControllerDelegate, SpaceDetailPresenterDelegate, UserSuggestionCoordinatorBridgeDelegate, ThreadsCoordinatorBridgePresenterDelegate, ThreadsBetaCoordinatorBridgePresenterDelegate, MXThreadingServiceDelegate, RoomParticipantsInviteCoordinatorBridgePresenterDelegate, RoomInputToolbarViewDelegate, ComposerCreateActionListBridgePresenterDelegate>
{
// The preview header
@@ -198,6 +198,7 @@ static CGSize kThreadListBarButtonItemImageSize;
@property (nonatomic, strong) RoomContextualMenuPresenter *roomContextualMenuPresenter;
@property (nonatomic, strong) MXKErrorAlertPresentation *errorPresenter;
@property (nonatomic, strong) NSAttributedString *textMessageBeforeEditing;
@property (nonatomic, strong) NSString *htmlTextBeforeEditing;
@property (nonatomic, strong) EditHistoryCoordinatorBridgePresenter *editHistoryPresenter;
@property (nonatomic, strong) MXKDocumentPickerPresenter *documentPickerPresenter;
@property (nonatomic, strong) EmojiPickerCoordinatorBridgePresenter *emojiPickerCoordinatorBridgePresenter;
@@ -212,6 +213,7 @@ static CGSize kThreadListBarButtonItemImageSize;
@property (nonatomic, strong) ThreadsCoordinatorBridgePresenter *threadsBridgePresenter;
@property (nonatomic, strong) ThreadsBetaCoordinatorBridgePresenter *threadsBetaBridgePresenter;
@property (nonatomic, strong) SlidingModalPresenter *threadsNoticeModalPresenter;
@property (nonatomic, strong) ComposerCreateActionListBridgePresenter *composerCreateActionListBridgePresenter;
@property (nonatomic, getter=isActivitiesViewExpanded) BOOL activitiesViewExpanded;
@property (nonatomic, getter=isScrollToBottomHidden) BOOL scrollToBottomHidden;
@property (nonatomic, getter=isMissedDiscussionsBadgeHidden) BOOL missedDiscussionsBadgeHidden;
@@ -605,6 +607,7 @@ static CGSize kThreadListBarButtonItemImageSize;
isAppeared = NO;
[VoiceMessageMediaServiceProvider.sharedProvider pauseAllServices];
[VoiceBroadcastRecorderProvider.shared pauseRecording];
if([BWIBuildSettings.shared showMentionsInRoom]) {
[Mentions setCountMentionsToZeroWithRoomID:self.roomDataSource.roomId];
@@ -685,9 +688,7 @@ static CGSize kThreadListBarButtonItemImageSize;
{
// Retrieve the potential message partially typed during last room display.
// Note: We have to wait for viewDidAppear before updating growingTextView (viewWillAppear is too early)
RoomInputToolbarView *inputToolbar = (RoomInputToolbarView *)self.inputToolbarView;
inputToolbar.attributedTextMessage = self.roomDataSource.partialAttributedTextMessage;
self.inputToolbarView.attributedTextMessage = self.roomDataSource.partialAttributedTextMessage;
}
}
@@ -1165,10 +1166,23 @@ static CGSize kThreadListBarButtonItemImageSize;
[self notifyDelegateOnLeaveRoomIfNecessary];
}
+ (Class) mainToolbarClass
{
if (RiotSettings.shared.enableWysiwygComposer)
{
return WysiwygInputToolbarView.class;
}
else
{
return RoomInputToolbarView.class;
}
}
// Set the input toolbar according to the current display
- (void)updateRoomInputToolbarViewClassIfNeeded
{
Class roomInputToolbarViewClass = RoomInputToolbarView.class;
Class roomInputToolbarViewClass = [RoomViewController mainToolbarClass];
BOOL shouldDismissContextualMenu = NO;
@@ -1211,10 +1225,10 @@ static CGSize kThreadListBarButtonItemImageSize;
{
[super setRoomInputToolbarViewClass:roomInputToolbarViewClass];
// 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];
if ([self.inputToolbarView.class conformsToProtocol:@protocol(RoomInputToolbarViewProtocol)]) {
id<RoomInputToolbarViewProtocol> inputToolbar = (id<RoomInputToolbarViewProtocol>)self.inputToolbarView;
[inputToolbar setVoiceMessageToolbarView:self.voiceMessageController.voiceMessageToolbarView];
}
[self updateInputToolBarViewHeight];
@@ -1227,9 +1241,9 @@ static CGSize kThreadListBarButtonItemImageSize;
{
CGFloat height = 0;
if ([self.inputToolbarView isKindOfClass:RoomInputToolbarView.class])
{
height = ((RoomInputToolbarView*)self.inputToolbarView).mainToolbarHeightConstraint.constant;
if ([self.inputToolbarView.class conformsToProtocol:@protocol(RoomInputToolbarViewProtocol)]) {
id<RoomInputToolbarViewProtocol> inputToolbar = (id<RoomInputToolbarViewProtocol>)self.inputToolbarView;
height = inputToolbar.toolbarHeight;
}
else if ([self.inputToolbarView isKindOfClass:DisabledRoomInputToolbarView.class])
{
@@ -1775,15 +1789,20 @@ static CGSize kThreadListBarButtonItemImageSize;
|| self.customizedRoomDataSource.jitsiWidget;
}
- (BOOL)canSendStateEventWithType:(MXEventTypeString)eventTypeString
{
MXRoomPowerLevels *powerLevels = [self.roomDataSource.roomState powerLevels];
NSInteger requiredPower = [powerLevels minimumPowerLevelForSendingEventAsStateEvent:eventTypeString];
NSInteger myPower = [powerLevels powerLevelOfUserWithUserID:self.roomDataSource.mxSession.myUserId];
return myPower >= requiredPower;
}
/**
Returns a flag for the current user whether it's privileged to add/remove Jitsi widgets to this room.
*/
- (BOOL)canEditJitsiWidget
{
MXRoomPowerLevels *powerLevels = [self.roomDataSource.roomState powerLevels];
NSInteger requiredPower = [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kWidgetModularEventTypeString];
NSInteger myPower = [powerLevels powerLevelOfUserWithUserID:self.roomDataSource.mxSession.myUserId];
return myPower >= requiredPower;
return [self canSendStateEventWithType:kWidgetModularEventTypeString];
}
- (void)registerURLPreviewNotifications
@@ -2000,9 +2019,9 @@ static CGSize kThreadListBarButtonItemImageSize;
[self updateInputToolBarVisibility];
// Check whether the input toolbar is ready before updating it.
if (self.inputToolbarView && [self.inputToolbarView isKindOfClass:RoomInputToolbarView.class])
if (self.inputToolbarView && [self inputToolbarConformsToToolbarViewProtocol])
{
RoomInputToolbarView *roomInputToolbarView = (RoomInputToolbarView*)self.inputToolbarView;
id<RoomInputToolbarViewProtocol> roomInputToolbarView = (id<RoomInputToolbarViewProtocol>) self.inputToolbarView;
// Update encryption decoration if needed
[self updateEncryptionDecorationForRoomInputToolbar:roomInputToolbarView];
@@ -2049,9 +2068,9 @@ static CGSize kThreadListBarButtonItemImageSize;
- (void)setInputToolBarSendMode:(RoomInputToolbarViewSendMode)sendMode forEventWithId:(NSString *)eventId
{
if (self.inputToolbarView && [self.inputToolbarView isKindOfClass:[RoomInputToolbarView class]])
if (self.inputToolbarView && [self inputToolbarConformsToToolbarViewProtocol])
{
RoomInputToolbarView *roomInputToolbarView = (RoomInputToolbarView*)self.inputToolbarView;
MXKRoomInputToolbarView <RoomInputToolbarViewProtocol> *roomInputToolbarView = (MXKRoomInputToolbarView <RoomInputToolbarViewProtocol> *) self.inputToolbarView;
if (eventId)
{
MXEvent *event = [self.roomDataSource eventWithEventId:eventId];
@@ -2122,9 +2141,9 @@ static CGSize kThreadListBarButtonItemImageSize;
- (void)updateInputToolbarEncryptionDecoration
{
if (self.inputToolbarView && [self.inputToolbarView isKindOfClass:RoomInputToolbarView.class])
if (self.inputToolbarView && [self inputToolbarConformsToToolbarViewProtocol])
{
RoomInputToolbarView *roomInputToolbarView = (RoomInputToolbarView*)self.inputToolbarView;
id<RoomInputToolbarViewProtocol> roomInputToolbarView = (id<RoomInputToolbarViewProtocol>)self.inputToolbarView;
[self updateEncryptionDecorationForRoomInputToolbar:roomInputToolbarView];
}
}
@@ -2140,7 +2159,7 @@ static CGSize kThreadListBarButtonItemImageSize;
roomTitleView.badgeImageView.image = self.roomEncryptionBadgeImage;
}
- (void)updateEncryptionDecorationForRoomInputToolbar:(RoomInputToolbarView*)roomInputToolbarView
- (void)updateEncryptionDecorationForRoomInputToolbar:(id<RoomInputToolbarViewProtocol>)roomInputToolbarView
{
roomInputToolbarView.isEncryptionEnabled = self.isEncryptionEnabled;
}
@@ -2185,11 +2204,9 @@ static CGSize kThreadListBarButtonItemImageSize;
UIView *sourceView;
RoomInputToolbarView *roomInputToolbarView = [self inputToolbarViewAsRoomInputToolbarView];
if (roomInputToolbarView)
if ([self.inputToolbarView isKindOfClass:RoomInputToolbarView.class])
{
sourceView = roomInputToolbarView.attachMediaButton;
sourceView = ((RoomInputToolbarView*)self.inputToolbarView).attachMediaButton;
}
else
{
@@ -2261,6 +2278,7 @@ static CGSize kThreadListBarButtonItemImageSize;
}
- (void)setupActions {
if (![self.inputToolbarView isKindOfClass:RoomInputToolbarView.class]) {
return;
}
@@ -2298,6 +2316,16 @@ static CGSize kThreadListBarButtonItemImageSize;
[self roomInputToolbarViewDidTapFileUpload];
}]];
}
if (RiotSettings.shared.enableVoiceBroadcast && !self.isNewDirectChat)
{
[actionItems addObject:[[RoomActionItem alloc] initWithImage:AssetImages.actionLive.image andAction:^{
MXStrongifyAndReturnIfNil(self);
if ([self.inputToolbarView isKindOfClass:RoomInputToolbarView.class]) {
((RoomInputToolbarView *) self.inputToolbarView).actionMenuOpened = NO;
}
[self roomInputToolbarViewDidTapVoiceBroadcast];
}]];
}
if (BuildSettings.pollsEnabled && self.displayConfiguration.sendingPollsEnabled && !self.isNewDirectChat)
{
[actionItems addObject:[[RoomActionItem alloc] initWithImage:AssetImages.actionPoll.image andAction:^{
@@ -2415,6 +2443,39 @@ static CGSize kThreadListBarButtonItemImageSize;
self.documentPickerPresenter = documentPickerPresenter;
}
- (void)roomInputToolbarViewDidTapVoiceBroadcast
{
// Check first the room permission
if (![self canSendStateEventWithType:VoiceBroadcastSettings.voiceBroadcastInfoContentKeyType])
{
[self showAlertWithTitle:[VectorL10n voiceBroadcastUnauthorizedTitle] message:[VectorL10n voiceBroadcastPermissionDeniedMessage]];
return;
}
MXSession* session = self.roomDataSource.mxSession;
// Check whether the user is not already broadcasting here or in another room
if (session.voiceBroadcastService)
{
[self showAlertWithTitle:[VectorL10n voiceBroadcastUnauthorizedTitle] message:[VectorL10n voiceBroadcastAlreadyInProgressMessage]];
return;
}
// Request the voice broadcast service to start recording - No service is returned if someone else is already broadcasting in the room
[session getOrCreateVoiceBroadcastServiceFor:self.roomDataSource.room completion:^(VoiceBroadcastService *voiceBroadcastService) {
if (voiceBroadcastService) {
[voiceBroadcastService startVoiceBroadcastWithSuccess:^(NSString * _Nullable success) {
} failure:^(NSError * _Nonnull error) {
}];
}
else
{
[self showAlertWithTitle:[VectorL10n voiceBroadcastUnauthorizedTitle] message:[VectorL10n voiceBroadcastBlockedBySomeoneElseMessage]];
}
}];
}
/**
Send a video asset via the room input toolbar prompting the user for the conversion preset to use
if the `showMediaCompressionPrompt` setting has been enabled.
@@ -2423,8 +2484,7 @@ static CGSize kThreadListBarButtonItemImageSize;
*/
- (void)sendVideoAsset:(AVAsset *)videoAsset isPhotoLibraryAsset:(BOOL)isPhotoLibraryAsset
{
RoomInputToolbarView *roomInputToolbarView = [self inputToolbarViewAsRoomInputToolbarView];
if (!roomInputToolbarView)
if (![self inputToolbarConformsToToolbarViewProtocol])
{
return;
}
@@ -2445,15 +2505,27 @@ static CGSize kThreadListBarButtonItemImageSize;
// Create before sending the message in case of a discussion (direct chat)
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
if (readyToSend)
if (readyToSend && [self inputToolbarConformsToToolbarViewProtocol])
{
[[self inputToolbarViewAsRoomInputToolbarView] sendSelectedVideoAsset:videoAsset isPhotoLibraryAsset:isPhotoLibraryAsset];
[self.inputToolbarView 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;
UIView *sourceView;
if ([self.inputToolbarView isKindOfClass:RoomInputToolbarView.class])
{
sourceView = ((RoomInputToolbarView*)self.inputToolbarView).attachMediaButton;
}
else
{
sourceView = self.inputToolbarView;
}
compressionPrompt.popoverPresentationController.sourceView = sourceView;
compressionPrompt.popoverPresentationController.sourceRect = sourceView.bounds;
[self presentViewController:compressionPrompt animated:YES completion:nil];
}
@@ -2464,9 +2536,9 @@ static CGSize kThreadListBarButtonItemImageSize;
// Create before sending the message in case of a discussion (direct chat)
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
if (readyToSend)
if (readyToSend && [self inputToolbarConformsToToolbarViewProtocol])
{
[[self inputToolbarViewAsRoomInputToolbarView] sendSelectedVideoAsset:videoAsset isPhotoLibraryAsset:isPhotoLibraryAsset];
[self.inputToolbarView sendSelectedVideoAsset:videoAsset isPhotoLibraryAsset:isPhotoLibraryAsset];
}
// Errors are handled at the request level. This should be improved in case of code rewriting.
}];
@@ -3189,6 +3261,55 @@ static CGSize kThreadListBarButtonItemImageSize;
}
}
}
else if (bubbleData.tag == RoomBubbleCellDataTagVoiceBroadcastPlayback)
{
if (bubbleData.isIncoming)
{
if (bubbleData.isPaginationFirstBubble)
{
cellIdentifier = RoomTimelineCellIdentifierIncomingVoiceBroadcastWithPaginationTitle;
}
else if (bubbleData.shouldHideSenderInformation)
{
cellIdentifier = RoomTimelineCellIdentifierIncomingVoiceBroadcastWithoutSenderInfo;
}
else
{
cellIdentifier = RoomTimelineCellIdentifierIncomingVoiceBroadcast;
}
}
else
{
if (bubbleData.isPaginationFirstBubble)
{
cellIdentifier = RoomTimelineCellIdentifierOutgoingVoiceBroadcastWithPaginationTitle;
}
else if (bubbleData.shouldHideSenderInformation)
{
cellIdentifier = RoomTimelineCellIdentifierOutgoingVoiceBroadcastWithoutSenderInfo;
}
else
{
cellIdentifier = RoomTimelineCellIdentifierOutgoingVoiceBroadcast;
}
}
}
else if (bubbleData.tag == RoomBubbleCellDataTagVoiceBroadcastRecord)
{
if (bubbleData.isPaginationFirstBubble)
{
cellIdentifier = RoomTimelineCellIdentifierOutgoingVoiceBroadcastRecorderWithPaginationTitle;
}
else if (bubbleData.shouldHideSenderInformation)
{
cellIdentifier = RoomTimelineCellIdentifierOutgoingVoiceBroadcastRecorderWithoutSenderInfo;
}
else
{
cellIdentifier = RoomTimelineCellIdentifierOutgoingVoiceBroadcastRecorder;
}
}
else if (roomBubbleCellData.getFirstBubbleComponentWithDisplay.event.isEmote)
{
if (bubbleData.isIncoming)
@@ -4509,6 +4630,9 @@ static CGSize kThreadListBarButtonItemImageSize;
// Do nothing for dummy links
shouldDoAction = NO;
break;
case RoomMessageURLTypeHttp:
shouldDoAction = YES;
break;
default:
{
MXEvent *tappedEvent = userInfo[kMXKRoomBubbleCellEventKey];
@@ -4534,16 +4658,20 @@ static CGSize kThreadListBarButtonItemImageSize;
break;
case UITextItemInteractionPresentActions:
{
// Retrieve the tapped event
MXEvent *tappedEvent = userInfo[kMXKRoomBubbleCellEventKey];
if (tappedEvent)
{
// Long press on link, present room contextual menu.
[self showContextualMenuForEvent:tappedEvent fromSingleTapGesture:NO cell:cell animated:YES];
if (roomMessageURLType == RoomMessageURLTypeHttp) {
shouldDoAction = YES;
} else {
// Retrieve the tapped event
MXEvent *tappedEvent = userInfo[kMXKRoomBubbleCellEventKey];
if (tappedEvent)
{
// Long press on link, present room contextual menu.
[self showContextualMenuForEvent:tappedEvent fromSingleTapGesture:NO cell:cell animated:YES];
}
shouldDoAction = NO;
}
shouldDoAction = NO;
}
break;
case UITextItemInteractionPreview:
@@ -4608,12 +4736,16 @@ static CGSize kThreadListBarButtonItemImageSize;
{
MXEvent *event = [self.roomDataSource eventWithEventId:eventId];
RoomInputToolbarView *roomInputToolbarView = [self inputToolbarViewAsRoomInputToolbarView];
if (roomInputToolbarView)
if ([self inputToolbarConformsToHtmlToolbarViewProtocol])
{
self.textMessageBeforeEditing = roomInputToolbarView.attributedTextMessage;
roomInputToolbarView.attributedTextMessage = [self.customizedRoomDataSource editableAttributedTextMessageFor:event];
MXKRoomInputToolbarView <HtmlRoomInputToolbarViewProtocol> *htmlInputToolBarView = (MXKRoomInputToolbarView <HtmlRoomInputToolbarViewProtocol> *) self.inputToolbarView;
self.htmlTextBeforeEditing = htmlInputToolBarView.htmlContent;
htmlInputToolBarView.htmlContent = [self.customizedRoomDataSource editableHtmlTextMessageFor:event];
}
else if ([self inputToolbarConformsToToolbarViewProtocol])
{
self.textMessageBeforeEditing = self.inputToolbarView.attributedTextMessage;
self.inputToolbarView.attributedTextMessage = [self.customizedRoomDataSource editableAttributedTextMessageFor:event];
}
[self selectEventWithId:eventId inputToolBarSendMode:RoomInputToolbarViewSendModeEdit showTimestamp:YES];
@@ -4621,26 +4753,30 @@ static CGSize kThreadListBarButtonItemImageSize;
- (void)restoreTextMessageBeforeEditing
{
RoomInputToolbarView *roomInputToolbarView = [self inputToolbarViewAsRoomInputToolbarView];
if (self.textMessageBeforeEditing)
if (self.htmlTextBeforeEditing && [self inputToolbarConformsToHtmlToolbarViewProtocol])
{
roomInputToolbarView.attributedTextMessage = self.textMessageBeforeEditing;
MXKRoomInputToolbarView <HtmlRoomInputToolbarViewProtocol> *htmlInputToolBarView = (MXKRoomInputToolbarView <HtmlRoomInputToolbarViewProtocol> *) self.inputToolbarView;
htmlInputToolBarView.htmlContent = self.htmlTextBeforeEditing;
}
else if (self.textMessageBeforeEditing && [self inputToolbarConformsToToolbarViewProtocol])
{
self.inputToolbarView.attributedTextMessage = self.textMessageBeforeEditing;
}
self.textMessageBeforeEditing = nil;
self.htmlTextBeforeEditing = nil;
}
- (RoomInputToolbarView*)inputToolbarViewAsRoomInputToolbarView
- (BOOL)inputToolbarConformsToHtmlToolbarViewProtocol
{
RoomInputToolbarView *roomInputToolbarView;
if (self.inputToolbarView && [self.inputToolbarView isKindOfClass:[RoomInputToolbarView class]])
{
roomInputToolbarView = (RoomInputToolbarView*)self.inputToolbarView;
}
return roomInputToolbarView;
return [self.inputToolbarView conformsToProtocol:@protocol(HtmlRoomInputToolbarViewProtocol)];
}
- (BOOL)inputToolbarConformsToToolbarViewProtocol
{
return [self.inputToolbarView conformsToProtocol:@protocol(RoomInputToolbarViewProtocol)];
}
- (void)showDifferentURLsAlertFor:(NSURL *)url visibleURLString:(NSString *)visibleURLString
@@ -4933,32 +5069,17 @@ static CGSize kThreadListBarButtonItemImageSize;
{
if (self.roomInputToolbarContainerHeightConstraint.constant != height)
{
// Hide temporarily the placeholder to prevent its distorsion during height animation
if (!savedInputToolbarPlaceholder)
{
savedInputToolbarPlaceholder = toolbarView.placeholder.length ? toolbarView.placeholder : @"";
}
toolbarView.placeholder = nil;
[super roomInputToolbarView:toolbarView heightDidChanged:height completion:^(BOOL finished) {
if (completion)
{
completion (finished);
}
// Consider here the saved placeholder only if no new placeholder has been defined during the height animation.
if (!toolbarView.placeholder)
{
// Restore the placeholder if any
toolbarView.placeholder = self->savedInputToolbarPlaceholder.length ? self->savedInputToolbarPlaceholder : nil;
}
self->savedInputToolbarPlaceholder = nil;
}];
}
}
- (void)roomInputToolbarViewDidTapCancel:(RoomInputToolbarView*)toolbarView
- (void)roomInputToolbarViewDidTapCancel:(MXKRoomInputToolbarView<RoomInputToolbarViewProtocol>*)toolbarView
{
[self cancelEventSelection];
}
@@ -4977,6 +5098,57 @@ static CGSize kThreadListBarButtonItemImageSize;
}
}
- (void)roomInputToolbarView:(RoomInputToolbarView *)toolbarView sendFormattedTextMessage:(NSString *)formattedTextMessage withRawText:(NSString *)rawText
{
// Create before sending the message in case of a discussion (direct chat)
MXWeakify(self);
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
MXStrongifyAndReturnIfNil(self);
if (readyToSend) {
[self sendFormattedTextMessage:rawText htmlMsg:formattedTextMessage];
}
// Errors are handled at the request level. This should be improved in case of code rewriting.
}];
}
- (void)roomInputToolbarViewShowSendMediaActions:(MXKRoomInputToolbarView *)toolbarView
{
NSMutableArray *actionItems = [NSMutableArray new];
if (RiotSettings.shared.roomScreenAllowMediaLibraryAction)
{
[actionItems addObject:@(ComposerCreateActionPhotoLibrary)];
}
if (RiotSettings.shared.roomScreenAllowStickerAction && !self.isNewDirectChat)
{
[actionItems addObject:@(ComposerCreateActionStickers)];
}
if (RiotSettings.shared.roomScreenAllowFilesAction)
{
[actionItems addObject:@(ComposerCreateActionAttachments)];
}
if (RiotSettings.shared.enableVoiceBroadcast && !self.isNewDirectChat)
{
[actionItems addObject:@(ComposerCreateActionVoiceBroadcast)];
}
if (BuildSettings.pollsEnabled && self.displayConfiguration.sendingPollsEnabled && !self.isNewDirectChat)
{
[actionItems addObject:@(ComposerCreateActionPolls)];
}
if (BuildSettings.locationSharingEnabled && !self.isNewDirectChat)
{
[actionItems addObject:@(ComposerCreateActionLocation)];
}
if (RiotSettings.shared.roomScreenAllowCameraAction)
{
[actionItems addObject:@(ComposerCreateActionCamera)];
}
self.composerCreateActionListBridgePresenter = [[ComposerCreateActionListBridgePresenter alloc] initWithActions:actionItems];
self.composerCreateActionListBridgePresenter.delegate = self;
[self.composerCreateActionListBridgePresenter presentFrom:self animated:YES];
}
- (void)roomInputToolbarView:(RoomInputToolbarView *)toolbarView sendAttributedTextMessage:(NSAttributedString *)attributedTextMessage
{
// Create before sending the message in case of a discussion (direct chat)
@@ -5323,7 +5495,7 @@ static CGSize kThreadListBarButtonItemImageSize;
else
{
// Enable back the text input
[self setRoomInputToolbarViewClass:RoomInputToolbarView.class];
[self setRoomInputToolbarViewClass:[RoomViewController mainToolbarClass]];
[self updateInputToolBarViewHeight];
// And the extra area
@@ -6122,7 +6294,13 @@ static CGSize kThreadListBarButtonItemImageSize;
// Acknowledge the existence of all devices
[self startActivityIndicator];
[self.mainSession.crypto setDevicesKnown:self->unknownDevices complete:^{
if (![self.mainSession.crypto isKindOfClass:[MXLegacyCrypto class]])
{
MXLogFailure(@"[RoomVC] eventDidChangeSentState: Only legacy crypto supports manual setting of known devices");
return;
}
[(MXLegacyCrypto *)self.mainSession.crypto setDevicesKnown:self->unknownDevices complete:^{
self->unknownDevices = nil;
[self stopActivityIndicator];
@@ -7590,9 +7768,9 @@ static CGSize kThreadListBarButtonItemImageSize;
// Create before sending the message in case of a discussion (direct chat)
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
if (readyToSend)
if (readyToSend && [self inputToolbarConformsToToolbarViewProtocol])
{
[[self inputToolbarViewAsRoomInputToolbarView] sendSelectedImage:imageData
[self.inputToolbarView sendSelectedImage:imageData
withMimeType:MXKUTI.jpeg.mimeType
andCompressionMode:MediaCompressionHelper.defaultCompressionMode
isPhotoLibraryAsset:NO];
@@ -7625,9 +7803,9 @@ static CGSize kThreadListBarButtonItemImageSize;
// Create before sending the message in case of a discussion (direct chat)
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
if (readyToSend)
if (readyToSend && [self inputToolbarConformsToToolbarViewProtocol])
{
[[self inputToolbarViewAsRoomInputToolbarView] sendSelectedImage:imageData
[self.inputToolbarView sendSelectedImage:imageData
withMimeType:uti.mimeType
andCompressionMode:MediaCompressionHelper.defaultCompressionMode
isPhotoLibraryAsset:YES];
@@ -7654,9 +7832,9 @@ static CGSize kThreadListBarButtonItemImageSize;
// Create before sending the message in case of a discussion (direct chat)
[self createDiscussionIfNeeded:^(BOOL readyToSend) {
if (readyToSend)
if (readyToSend && [self inputToolbarConformsToToolbarViewProtocol])
{
[[self inputToolbarViewAsRoomInputToolbarView] sendSelectedAssets:assets withCompressionMode:MediaCompressionHelper.defaultCompressionMode];
[self.inputToolbarView sendSelectedAssets:assets withCompressionMode:MediaCompressionHelper.defaultCompressionMode];
}
// Errors are handled at the request level. This should be improved in case of code rewriting.
}];
@@ -7920,4 +8098,42 @@ static CGSize kThreadListBarButtonItemImageSize;
}
}
#pragma mark - ComposerCreateActionListBridgePresenter
- (void)composerCreateActionListBridgePresenterDelegateDidComplete:(ComposerCreateActionListBridgePresenter *)coordinatorBridgePresenter action:(enum ComposerCreateAction)action
{
[coordinatorBridgePresenter dismissWithAnimated:true completion:^{
switch (action) {
case ComposerCreateActionPhotoLibrary:
[self showMediaPickerAnimated:YES];
break;
case ComposerCreateActionStickers:
[self roomInputToolbarViewPresentStickerPicker];
break;
case ComposerCreateActionAttachments:
[self roomInputToolbarViewDidTapFileUpload];
break;
case ComposerCreateActionVoiceBroadcast:
[self roomInputToolbarViewDidTapVoiceBroadcast];
break;
case ComposerCreateActionPolls:
[self.delegate roomViewControllerDidRequestPollCreationFormPresentation:self];
break;
case ComposerCreateActionLocation:
[self.delegate roomViewControllerDidRequestLocationSharingFormPresentation:self];
break;
case ComposerCreateActionCamera:
[self showCameraControllerAnimated:YES];
break;
}
self.composerCreateActionListBridgePresenter = nil;
}];
}
- (void)composerCreateActionListBridgePresenterDidDismissInteractively:(ComposerCreateActionListBridgePresenter *)coordinatorBridgePresenter
{
self.composerCreateActionListBridgePresenter = nil;
}
@end