Merge branch 'gil/SP1_space_creation' into gil/5231_SP3-1_Update_room_settings_for_Spaces

# Conflicts:
#	Podfile.lock
This commit is contained in:
Gil Eluard
2022-02-21 17:57:58 +01:00
687 changed files with 8777 additions and 3697 deletions
@@ -1,44 +0,0 @@
//
// 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 AppAlertPresenter: AlertPresentable {
// MARK: - Properties
// swiftlint:disable weak_delegate
private let legacyAppDelegate: LegacyAppDelegate
// swiftlint:enable weak_delegate
// MARK: - Setup
init(legacyAppDelegate: LegacyAppDelegate) {
self.legacyAppDelegate = legacyAppDelegate
}
// MARK: - Public
func showError(_ error: Error, animated: Bool, completion: (() -> Void)?) {
// FIXME: Present an error on coordinator.toPresentable()
self.legacyAppDelegate.showError(asAlert: error)
}
func show(title: String?, message: String?, animated: Bool, completion: (() -> Void)?) {
// FIXME: Present an error on coordinator.toPresentable()
self.legacyAppDelegate.showAlert(withTitle: title, message: message)
}
}
+40 -4
View File
@@ -16,6 +16,9 @@
import Foundation
import Intents
import MatrixSDK
import CommonKit
import UIKit
#if DEBUG
import FLEX
@@ -46,7 +49,7 @@ final class AppCoordinator: NSObject, AppCoordinatorType {
return AppNavigator(appCoordinator: self)
}()
private weak var splitViewCoordinator: SplitViewCoordinatorType?
fileprivate weak var splitViewCoordinator: SplitViewCoordinatorType?
fileprivate weak var sideMenuCoordinator: SideMenuCoordinatorType?
private let userSessionsService: UserSessionsService
@@ -79,6 +82,7 @@ final class AppCoordinator: NSObject, AppCoordinatorType {
func start() {
self.setupLogger()
self.setupTheme()
self.excludeAllItemsFromBackup()
// Setup navigation router store
_ = NavigationRouterStore.shared
@@ -129,6 +133,17 @@ final class AppCoordinator: NSObject, AppCoordinatorType {
}
}
private func excludeAllItemsFromBackup() {
let manager = FileManager.default
// Individual files and directories created by the application or SDK are excluded case-by-case,
// but sometimes the lifecycle of a file is not directly controlled by the app (e.g. plists for
// UserDefaults). For that reason the app will always exclude all top-level directories as well
// as individual files.
manager.excludeAllUserDirectoriesFromBackup()
manager.excludeAllAppGroupDirectoriesFromBackup()
}
private func showAuthentication() {
// TODO: Implement
}
@@ -275,8 +290,6 @@ fileprivate class AppNavigator: AppNavigatorProtocol {
private unowned let appCoordinator: AppCoordinator
let alert: AlertPresentable
lazy var sideMenu: SideMenuPresentable = {
guard let sideMenuCoordinator = appCoordinator.sideMenuCoordinator else {
fatalError("sideMenuCoordinator is not initialized")
@@ -285,11 +298,22 @@ fileprivate class AppNavigator: AppNavigatorProtocol {
return SideMenuPresenter(sideMenuCoordinator: sideMenuCoordinator)
}()
private var appNavigationVC: UINavigationController {
guard
let splitVC = appCoordinator.splitViewCoordinator?.toPresentable() as? UISplitViewController,
// Picking out the first view controller currently works only on iPhones, not iPads
let navigationVC = splitVC.viewControllers.first as? UINavigationController
else {
MXLog.error("[AppNavigator] Missing root split view controller")
return UINavigationController()
}
return navigationVC
}
// MARK: - Setup
init(appCoordinator: AppCoordinator) {
self.appCoordinator = appCoordinator
self.alert = AppAlertPresenter(legacyAppDelegate: appCoordinator.legacyAppDelegate)
}
// MARK: - Public
@@ -297,4 +321,16 @@ fileprivate class AppNavigator: AppNavigatorProtocol {
func navigate(to destination: AppNavigatorDestination) {
self.appCoordinator.navigate(to: destination)
}
func addLoadingActivity() -> Activity {
let presenter = ActivityIndicatorToastPresenter(
text: VectorL10n.roomParticipantsSecurityLoading,
navigationController: appNavigationVC
)
let request = ActivityRequest(
presenter: presenter,
dismissal: .manual
)
return ActivityCenter.shared.add(request)
}
}
+9 -1
View File
@@ -15,6 +15,7 @@
//
import Foundation
import CommonKit
/// AppNavigatorProtocol abstract a navigator at app level.
/// It enables to perform the navigation within the global app scope (open the side menu, open a room and so on)
@@ -22,9 +23,16 @@ import Foundation
protocol AppNavigatorProtocol {
var sideMenu: SideMenuPresentable { get }
var alert: AlertPresentable { get }
/// Navigate to a destination screen or a state
/// Do not use protocol with associatedtype for the moment like presented here https://www.swiftbysundell.com/articles/navigation-in-swift/#where-to-navigator use a separate enum
func navigate(to destination: AppNavigatorDestination)
/// Add loading activity to an app-wide queue of other activitie
///
/// If the queue is empty, the activity will be displayed immediately, otherwise it will be pending
/// until the previously added activities have completed / been cancelled.
///
/// To remove an activity indicator, cancel or deallocate the returned `Activity`
func addLoadingActivity() -> Activity
}
+92 -61
View File
@@ -232,6 +232,17 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
*/
@property (nonatomic, assign, getter=isRoomListDataReady) BOOL roomListDataReady;
/**
An observer token for `RecentsViewControllerDataReadyNotification`s notifications.
*/
@property (nonatomic, nullable) id roomListDataReadyObserver;
/**
An optional completion block that will be called when a `RecentsViewControllerDataReadyNotification`
is observed during app launch.
*/
@property (nonatomic, copy, nullable) void (^roomListDataReadyCompletion)(void);
/**
Flag to indicate whether a cache clear is being performed.
*/
@@ -838,28 +849,28 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
}
// Enable error notifications
isErrorNotificationSuspended = NO;
self->isErrorNotificationSuspended = NO;
if (noCallSupportAlert)
if (self->noCallSupportAlert)
{
MXLogDebug(@"[AppDelegate] restoreInitialDisplay: keep visible noCall support alert");
[self showNotificationAlert:noCallSupportAlert];
[self showNotificationAlert:self->noCallSupportAlert];
}
else if (cryptoDataCorruptedAlert)
else if (self->cryptoDataCorruptedAlert)
{
MXLogDebug(@"[AppDelegate] restoreInitialDisplay: keep visible log in again");
[self showNotificationAlert:cryptoDataCorruptedAlert];
[self showNotificationAlert:self->cryptoDataCorruptedAlert];
}
else if (wrongBackupVersionAlert)
else if (self->wrongBackupVersionAlert)
{
MXLogDebug(@"[AppDelegate] restoreInitialDisplay: keep visible wrongBackupVersionAlert");
[self showNotificationAlert:wrongBackupVersionAlert];
[self showNotificationAlert:self->wrongBackupVersionAlert];
}
// Check whether an error notification is pending
else if (_errorNotification)
else if (self->_errorNotification)
{
[self showNotificationAlert:_errorNotification];
[self showNotificationAlert:self->_errorNotification];
}
}];
@@ -876,10 +887,10 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
}
// Enable error notification (Check whether a notification is pending)
isErrorNotificationSuspended = NO;
if (_errorNotification)
self->isErrorNotificationSuspended = NO;
if (self->_errorNotification)
{
[self showNotificationAlert:_errorNotification];
[self showNotificationAlert:self->_errorNotification];
}
}];
}
@@ -1377,6 +1388,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
event = eventFromServer;
dispatch_group_leave(eventDispatchGroup);
} failure:^(NSError *error) {
MXLogError(@"[LegacyAppDelegate] handleUniversalLinkWithParameters: event fetch failed: %@", error);
dispatch_group_leave(eventDispatchGroup);
}];
}
@@ -1428,9 +1440,9 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
else
{
void(^findRoom)(void) = ^{
if ([_masterTabBarController.selectedViewController conformsToProtocol:@protocol(MXKViewControllerActivityHandling)])
if ([self->_masterTabBarController.selectedViewController conformsToProtocol:@protocol(MXKViewControllerActivityHandling)])
{
UIViewController<MXKViewControllerActivityHandling> *homeViewController = (UIViewController<MXKViewControllerActivityHandling>*)_masterTabBarController.selectedViewController;
UIViewController<MXKViewControllerActivityHandling> *homeViewController = (UIViewController<MXKViewControllerActivityHandling>*)self->_masterTabBarController.selectedViewController;
[homeViewController startActivityIndicator];
@@ -1438,7 +1450,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
{
// The alias may be not part of user's rooms states
// Ask the HS to resolve the room alias into a room id and then retry
universalLinkFragmentPending = fragment;
self->universalLinkFragmentPending = fragment;
MXKAccount* account = accountManager.activeAccounts.firstObject;
[account.mxSession.matrixRestClient roomIDForRoomAlias:roomIdOrAlias success:^(NSString *roomId) {
@@ -1446,7 +1458,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
[homeViewController stopActivityIndicator];
// Check that 'fragment' has not been cancelled
if ([universalLinkFragmentPending isEqualToString:fragment])
if ([self->universalLinkFragmentPending isEqualToString:fragment])
{
// Retry opening the link but with the returned room id
NSString *newUniversalLinkFragment =
@@ -1466,7 +1478,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
if (![newUniversalLinkFragment isEqualToString:fragment])
{
universalLinkFragmentPendingRoomAlias = @{roomId: roomIdOrAlias};
self->universalLinkFragmentPendingRoomAlias = @{roomId: roomIdOrAlias};
UniversalLinkParameters *newParameters = [[UniversalLinkParameters alloc] initWithFragment:newUniversalLinkFragment universalLinkURL:universalLinkURL presentationParameters:presentationParameters];
@@ -1497,12 +1509,12 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
MXKAccount* account = accountManager.activeAccounts.firstObject;
MXLogDebug(@"[AppDelegate] Universal link: Need to wait for the session to be sync'ed and running");
universalLinkFragmentPending = fragment;
self->universalLinkFragmentPending = fragment;
universalLinkWaitingObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull notif) {
self->universalLinkWaitingObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull notif) {
// Check that 'fragment' has not been cancelled
if ([universalLinkFragmentPending isEqualToString:fragment])
if ([self->universalLinkFragmentPending isEqualToString:fragment])
{
// Check whether the concerned session is the associated one
if (notif.object == account.mxSession && account.mxSession.state == MXSessionStateRunning)
@@ -1581,7 +1593,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
universalLinkWaitingObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountManagerDidAddAccountNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
// Check that 'fragment' has not been cancelled
if ([universalLinkFragmentPending isEqualToString:fragment])
if ([self->universalLinkFragmentPending isEqualToString:fragment])
{
MXLogDebug(@"[AppDelegate] Universal link: The user is now logged in. Retry the link");
[self handleUniversalLinkWithParameters:universalLinkParameters];
@@ -1646,7 +1658,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
universalLinkWaitingObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountManagerDidAddAccountNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
// Check that 'fragment' has not been cancelled
if ([universalLinkFragmentPending isEqualToString:fragment])
if ([self->universalLinkFragmentPending isEqualToString:fragment])
{
MXLogDebug(@"[AppDelegate] Universal link: The user is now logged in. Retry the link");
[self handleUniversalLinkWithParameters:universalLinkParameters];
@@ -2318,7 +2330,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
}
// Return to authentication screen
[_masterTabBarController showOnboardingFlow];
[self->_masterTabBarController showOnboardingFlow];
// Note: Keep App settings
// But enforce usage of member lazy loading
@@ -2373,6 +2385,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
case MXSessionStateInitialised:
case MXSessionStateBackgroundSyncInProgress:
self.roomListDataReady = NO;
[self listenForRoomListDataReady];
isLaunching = YES;
break;
case MXSessionStateStoreDataReady:
@@ -2397,6 +2410,12 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
MXLogDebug(@"[AppDelegate] handleAppState: isLaunching: %@", isLaunching ? @"YES" : @"NO");
if (self.masterTabBarController.isOnboardingInProgress)
{
MXLogDebug(@"[AppDelegate] handleAppState: Skipping LaunchLoadingView due to Onboarding.");
return;
}
if (isLaunching)
{
MXLogDebug(@"[AppDelegate] handleAppState: LaunchLoadingView");
@@ -2410,7 +2429,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
return;
}
[self ensureRoomListDataReadyWithCompletion:^{
void (^finishAppLaunch)(void) = ^{
[self hideLaunchAnimation];
if (self.setPinCoordinatorBridgePresenter)
@@ -2442,7 +2461,17 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
// Enable listening of incoming key verification requests
[self enableIncomingKeyVerificationObserver:mainSession];
}
}];
};
if (self.isRoomListDataReady)
{
finishAppLaunch();
}
else
{
// An observer has been set in didFinishLaunching that will call the stored block when ready
self.roomListDataReadyCompletion = finishAppLaunch;
}
}
}
@@ -2598,29 +2627,31 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
[self handleAppState];
}
/**
Ensures room list data is ready.
@param completion Completion block to be called when it's ready. Not dispatched in case the data is already ready.
*/
- (void)ensureRoomListDataReadyWithCompletion:(void(^)(void))completion
- (void)listenForRoomListDataReady
{
if (self.isRoomListDataReady)
if (self.roomListDataReadyObserver)
{
completion();
}
else
{
NSNotificationCenter * __weak notificationCenter = [NSNotificationCenter defaultCenter];
__block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:RecentsViewControllerDataReadyNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification * _Nonnull notification) {
[notificationCenter removeObserver:observer];
self.roomListDataReady = YES;
completion();
}];
return;
}
MXWeakify(self);
NSNotificationCenter * __weak notificationCenter = [NSNotificationCenter defaultCenter];
self.roomListDataReadyObserver = [[NSNotificationCenter defaultCenter] addObserverForName:RecentsViewControllerDataReadyNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification * _Nonnull notification) {
MXStrongifyAndReturnIfNil(self);
[notificationCenter removeObserver:self.roomListDataReadyObserver];
self.roomListDataReady = YES;
self.roomListDataReadyObserver = nil;
if (self.roomListDataReadyCompletion)
{
self.roomListDataReadyCompletion();
self.roomListDataReadyCompletion = nil;
}
}];
}
#pragma mark -
@@ -2729,7 +2760,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
if ([[ruleAction.parameters valueForKey:@"set_tweak"] isEqualToString:@"sound"])
{
// Play message sound
AudioServicesPlaySystemSound(_messageSound);
AudioServicesPlaySystemSound(self->_messageSound);
}
}
}
@@ -3424,9 +3455,9 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
{
case MXEventTypeCallInvite:
{
if (noCallSupportAlert)
if (self->noCallSupportAlert)
{
[noCallSupportAlert dismissViewControllerAnimated:NO completion:nil];
[self->noCallSupportAlert dismissViewControllerAnimated:NO completion:nil];
}
MXCallInviteEventContent *callInviteEventContent = [MXCallInviteEventContent modelFromJSON:event.content];
@@ -3448,15 +3479,15 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
NSString *message = [VectorL10n noVoip:callerDisplayname :appDisplayName];
noCallSupportAlert = [UIAlertController alertControllerWithTitle:[VectorL10n noVoipTitle]
message:message
preferredStyle:UIAlertControllerStyleAlert];
self->noCallSupportAlert = [UIAlertController alertControllerWithTitle:[VectorL10n noVoipTitle]
message:message
preferredStyle:UIAlertControllerStyleAlert];
__weak typeof(self) weakSelf = self;
[noCallSupportAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ignore]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self->noCallSupportAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n ignore]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
@@ -3466,9 +3497,9 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
}]];
[noCallSupportAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n rejectCall]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self->noCallSupportAlert addAction:[UIAlertAction actionWithTitle:[MatrixKitL10n rejectCall]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
// Reject the call by sending the hangup event
NSDictionary *content = @{
@@ -3489,7 +3520,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
}]];
[self showNotificationAlert:noCallSupportAlert];
[self showNotificationAlert:self->noCallSupportAlert];
break;
}
@@ -3497,10 +3528,10 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
case MXEventTypeCallHangup:
case MXEventTypeCallReject:
// The call has ended. The alert is no more needed.
if (noCallSupportAlert)
if (self->noCallSupportAlert)
{
[noCallSupportAlert dismissViewControllerAnimated:YES completion:nil];
noCallSupportAlert = nil;
[self->noCallSupportAlert dismissViewControllerAnimated:YES completion:nil];
self->noCallSupportAlert = nil;
}
break;