diff --git a/Riot/Modules/Room/RoomCoordinator.swift b/Riot/Modules/Room/RoomCoordinator.swift index 03ad0b977..c8b260e5e 100644 --- a/Riot/Modules/Room/RoomCoordinator.swift +++ b/Riot/Modules/Room/RoomCoordinator.swift @@ -72,7 +72,12 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol { self.parameters = parameters self.selectedEventId = parameters.eventId - self.roomViewController = RoomViewController.instantiate() + if let threadId = parameters.threadId { + self.roomViewController = ThreadViewController.instantiate(withThreadId: threadId, + configuration: parameters.displayConfiguration) + } else { + self.roomViewController = RoomViewController.instantiate(with: parameters.displayConfiguration) + } self.activityIndicatorPresenter = ActivityIndicatorPresenter() super.init() @@ -127,6 +132,9 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol { } func toPresentable() -> UIViewController { + if parameters.threadId != nil { + return self.navigationRouter?.toPresentable() ?? self.roomViewController + } return self.roomViewController } diff --git a/Riot/Modules/Room/RoomCoordinatorBridgePresenter.swift b/Riot/Modules/Room/RoomCoordinatorBridgePresenter.swift index 7960dee18..9616969fa 100644 --- a/Riot/Modules/Room/RoomCoordinatorBridgePresenter.swift +++ b/Riot/Modules/Room/RoomCoordinatorBridgePresenter.swift @@ -37,6 +37,9 @@ class RoomCoordinatorBridgePresenterParameters: NSObject { /// If not nil, specified thread will be opened. let threadId: String? + /// Display configuration for the room + let displayConfiguration: RoomDisplayConfiguration + /// The data for the room preview. let previewData: RoomPreviewData? @@ -44,11 +47,13 @@ class RoomCoordinatorBridgePresenterParameters: NSObject { roomId: String, eventId: String?, threadId: String?, + displayConfiguration: RoomDisplayConfiguration, previewData: RoomPreviewData?) { self.session = session self.roomId = roomId self.eventId = eventId self.threadId = threadId + self.displayConfiguration = displayConfiguration self.previewData = previewData } } @@ -126,7 +131,8 @@ final class RoomCoordinatorBridgePresenter: NSObject { session: self.bridgeParameters.session, roomId: self.bridgeParameters.roomId, eventId: self.bridgeParameters.eventId, - threadId: self.bridgeParameters.threadId) + threadId: self.bridgeParameters.threadId, + displayConfiguration: self.bridgeParameters.displayConfiguration) } return RoomCoordinator(parameters: coordinatorParameters) diff --git a/Riot/Modules/Room/RoomCoordinatorParameters.swift b/Riot/Modules/Room/RoomCoordinatorParameters.swift index 1ed73f8cf..13c47a039 100644 --- a/Riot/Modules/Room/RoomCoordinatorParameters.swift +++ b/Riot/Modules/Room/RoomCoordinatorParameters.swift @@ -40,6 +40,9 @@ struct RoomCoordinatorParameters { /// If not nil, specified thread will be opened. let threadId: String? + /// Display configuration for the room + let displayConfiguration: RoomDisplayConfiguration + /// The data for the room preview. let previewData: RoomPreviewData? @@ -51,6 +54,7 @@ struct RoomCoordinatorParameters { roomId: String, eventId: String?, threadId: String?, + displayConfiguration: RoomDisplayConfiguration, previewData: RoomPreviewData?) { self.navigationRouter = navigationRouter self.navigationRouterStore = navigationRouterStore @@ -58,6 +62,7 @@ struct RoomCoordinatorParameters { self.roomId = roomId self.eventId = eventId self.threadId = threadId + self.displayConfiguration = displayConfiguration self.previewData = previewData } @@ -67,9 +72,17 @@ struct RoomCoordinatorParameters { session: MXSession, roomId: String, eventId: String? = nil, - threadId: String? = nil) { + threadId: String? = nil, + displayConfiguration: RoomDisplayConfiguration = .default) { - self.init(navigationRouter: navigationRouter, navigationRouterStore: navigationRouterStore, session: session, roomId: roomId, eventId: eventId, threadId: threadId, previewData: nil) + self.init(navigationRouter: navigationRouter, + navigationRouterStore: navigationRouterStore, + session: session, + roomId: roomId, + eventId: eventId, + threadId: threadId, + displayConfiguration: displayConfiguration, + previewData: nil) } /// Init to present a room preview @@ -77,6 +90,13 @@ struct RoomCoordinatorParameters { navigationRouterStore: NavigationRouterStoreProtocol? = nil, previewData: RoomPreviewData) { - self.init(navigationRouter: navigationRouter, navigationRouterStore: navigationRouterStore, session: previewData.mxSession, roomId: previewData.roomId, eventId: nil, threadId: nil, previewData: previewData) + self.init(navigationRouter: navigationRouter, + navigationRouterStore: navigationRouterStore, + session: previewData.mxSession, + roomId: previewData.roomId, + eventId: nil, + threadId: nil, + displayConfiguration: .default, + previewData: previewData) } } diff --git a/Riot/Modules/Room/RoomDisplayConfiguration.swift b/Riot/Modules/Room/RoomDisplayConfiguration.swift new file mode 100644 index 000000000..2c3ab1ab8 --- /dev/null +++ b/Riot/Modules/Room/RoomDisplayConfiguration.swift @@ -0,0 +1,44 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +@objcMembers +class RoomDisplayConfiguration: NSObject { + + let callsEnabled: Bool + + let integrationsEnabled: Bool + + let jitsiWidgetRemoverEnabled: Bool + + init(callsEnabled: Bool, + integrationsEnabled: Bool, + jitsiWidgetRemoverEnabled: Bool) { + self.callsEnabled = callsEnabled + self.integrationsEnabled = integrationsEnabled + self.jitsiWidgetRemoverEnabled = jitsiWidgetRemoverEnabled + super.init() + } + + static let `default`: RoomDisplayConfiguration = RoomDisplayConfiguration(callsEnabled: true, + integrationsEnabled: true, + jitsiWidgetRemoverEnabled: true) + + static let forThreads: RoomDisplayConfiguration = RoomDisplayConfiguration(callsEnabled: false, + integrationsEnabled: false, + jitsiWidgetRemoverEnabled: false) +} diff --git a/Riot/Modules/Room/RoomViewController.h b/Riot/Modules/Room/RoomViewController.h index 5016dec0f..1649e36b0 100644 --- a/Riot/Modules/Room/RoomViewController.h +++ b/Riot/Modules/Room/RoomViewController.h @@ -30,6 +30,7 @@ @class BadgeLabel; @class UniversalLinkParameters; @protocol RoomViewControllerDelegate; +@class RoomDisplayConfiguration; NS_ASSUME_NONNULL_BEGIN @@ -72,6 +73,11 @@ extern NSNotificationName const RoomGroupCallTileTappedNotification; */ @property (nonatomic, readonly, nullable) RoomPreviewData *roomPreviewData; +/** + Display configuration for the room view controller. + */ +@property (nonatomic, readonly) RoomDisplayConfiguration *displayConfiguration; + /** Tell whether a badge must be added next to the chevron (back button) showing number of unread rooms. YES by default. @@ -97,9 +103,11 @@ extern NSNotificationName const RoomGroupCallTileTappedNotification; /** Creates and returns a new `RoomViewController` object. + @param configuration display configuration for the room view controller. + @return An initialized `RoomViewController` object. */ -+ (instancetype)instantiate; ++ (instancetype)instantiateWithConfiguration:(RoomDisplayConfiguration *)configuration; @end diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 881188d63..06c42ab59 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -258,6 +258,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; @property (nonatomic, strong) UserSuggestionCoordinatorBridge *userSuggestionCoordinator; @property (nonatomic, weak) IBOutlet UIView *userSuggestionContainerView; +@property (nonatomic, readwrite) RoomDisplayConfiguration *displayConfiguration; + @end @implementation RoomViewController @@ -273,14 +275,18 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; + (instancetype)roomViewController { - return [[[self class] alloc] initWithNibName:NSStringFromClass(self.class) - bundle:[NSBundle bundleForClass:self.class]]; + RoomViewController *controller = [[[self class] alloc] initWithNibName:NSStringFromClass(self.class) + bundle:[NSBundle bundleForClass:self.class]]; + controller.displayConfiguration = [RoomDisplayConfiguration default]; + return controller; } -+ (instancetype)instantiate ++ (instancetype)instantiateWithConfiguration:(RoomDisplayConfiguration *)configuration { UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; - return [storyboard instantiateViewControllerWithIdentifier:@"RoomViewControllerStoryboardId"]; + RoomViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"RoomViewControllerStoryboardId"]; + controller.displayConfiguration = configuration; + return controller; } #pragma mark - @@ -1502,6 +1508,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; - (void)setupRemoveJitsiWidgetRemoveView { + if (!self.displayConfiguration.jitsiWidgetRemoverEnabled) + { + return; + } + self.removeJitsiWidgetView = [RemoveJitsiWidgetView instantiate]; self.removeJitsiWidgetView.delegate = self; @@ -1544,6 +1555,10 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; - (BOOL)supportCallOption { + if (!self.displayConfiguration.callsEnabled) + { + return NO; + } BOOL callOptionAllowed = (self.roomDataSource.room.isDirect && RiotSettings.shared.roomScreenAllowVoIPForDirectRoom) || (!self.roomDataSource.room.isDirect && RiotSettings.shared.roomScreenAllowVoIPForNonDirectRoom); return callOptionAllowed && BuildSettings.allowVoIPUsage && self.roomDataSource.mxSession.callManager && self.roomDataSource.room.summary.membersCount.joined >= 2; } @@ -4883,6 +4898,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; - (void)listenWidgetNotifications { + if (!self.displayConfiguration.jitsiWidgetRemoverEnabled) + { + return; + } + MXWeakify(self); kMXKWidgetManagerDidUpdateWidgetObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kWidgetManagerDidUpdateWidgetNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { @@ -4919,6 +4939,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; - (NSUInteger)widgetsCount:(BOOL)includeUserWidgets { + if (!self.displayConfiguration.integrationsEnabled) + { + return 0; + } + NSUInteger widgetsCount = [[WidgetManager sharedManager] widgetsNotOfTypes:@[kWidgetTypeJitsiV1, kWidgetTypeJitsiV2] inRoom:self.roomDataSource.room withRoomState:self.roomDataSource.roomState].count; @@ -5549,6 +5574,11 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; - (void)refreshRemoveJitsiWidgetView { + if (!self.displayConfiguration.jitsiWidgetRemoverEnabled) + { + return; + } + if (self.roomDataSource.isLive && !self.roomDataSource.isPeeking) { Widget *jitsiWidget = [customizedRoomDataSource jitsiWidget]; @@ -6287,10 +6317,12 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; self.threadBridgePresenter = nil; } + RoomDisplayConfiguration *configuration = RoomDisplayConfiguration.forThreads; RoomCoordinatorBridgePresenterParameters *parameters = [[RoomCoordinatorBridgePresenterParameters alloc] initWithSession:self.mainSession roomId:self.roomDataSource.roomId eventId:nil threadId:threadId + displayConfiguration:configuration previewData:nil]; RoomCoordinatorBridgePresenter *presenter = [[RoomCoordinatorBridgePresenter alloc] initWithParameters:parameters]; self.threadBridgePresenter = presenter; diff --git a/Riot/Modules/Thread/ThreadViewController.swift b/Riot/Modules/Thread/ThreadViewController.swift new file mode 100644 index 000000000..1639d0db9 --- /dev/null +++ b/Riot/Modules/Thread/ThreadViewController.swift @@ -0,0 +1,30 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +class ThreadViewController: RoomViewController { + + private(set) var threadId: String! + + class func instantiate(withThreadId threadId: String, + configuration: RoomDisplayConfiguration) -> ThreadViewController { + let threadVC = ThreadViewController.instantiate(with: configuration) + threadVC.threadId = threadId + return threadVC + } + +}