diff --git a/CHANGES.md b/CHANGES.md
index 048c6c97b..988944819 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,22 @@
+## Changes in 1.9.1 (2022-08-29)
+
+🙌 Improvements
+
+- Added Labs flag for the new App Layout. ([#6649](https://github.com/vector-im/element-ios/issues/6649))
+
+🐛 Bugfixes
+
+- Render the PIN entry screen correctly on landscape ([#6629](https://github.com/vector-im/element-ios/pull/6629))
+- Ensure rest client async responses are processed on the main queue ([#6642](https://github.com/vector-im/element-ios/pull/6642))
+- Stop waiting for biometric unlock if disabled system wide ([#5279](https://github.com/vector-im/element-ios/issues/5279))
+- App Layout: added support for transparent avatar icons in the all chats screen ([#6556](https://github.com/vector-im/element-ios/issues/6556))
+- App Layout: fixed reactions background in timeline ([#6557](https://github.com/vector-im/element-ios/issues/6557))
+- App Layout: Removed Low Priority Rooms from Filters ([#6577](https://github.com/vector-im/element-ios/issues/6577))
+- App Layout: Updated missing image for Onboarding screen page 2 ([#6624](https://github.com/vector-im/element-ios/issues/6624))
+- App Layout: fixed limited number of invites in the All Chats screen ([#6625](https://github.com/vector-im/element-ios/issues/6625))
+- Fix notification issues for threads. ([#6628](https://github.com/vector-im/element-ios/issues/6628))
+
+
## Changes in 1.9.0 (2022-08-24)
🙌 Improvements
diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig
index 05b88688a..fba787b2a 100644
--- a/Config/AppVersion.xcconfig
+++ b/Config/AppVersion.xcconfig
@@ -15,5 +15,5 @@
//
// Version
-MARKETING_VERSION = 1.9.0
-CURRENT_PROJECT_VERSION = 1.9.0
+MARKETING_VERSION = 1.9.1
+CURRENT_PROJECT_VERSION = 1.9.1
diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift
index 7315755ac..cc648923b 100644
--- a/Config/BuildSettings.swift
+++ b/Config/BuildSettings.swift
@@ -419,8 +419,11 @@ final class BuildSettings: NSObject {
static let syncLocalContacts: Bool = false
// MARK: - New App Layout
- static let newAppLayoutEnabled = true
-
+ static let newAppLayoutEnabled = false
+
+ static var isSideMenuActivated: Bool = enableSideMenu
+ static var isNewAppLayoutActivated: Bool = newAppLayoutEnabled
+
// MARK: - Device manager
static let deviceManagerEnabled = false
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/Contents.json b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/Contents.json
index 68a004064..99aa89f84 100644
--- a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/Contents.json
+++ b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/Contents.json
@@ -1,15 +1,17 @@
{
"images" : [
{
- "filename" : "all_chats_onboarding2.svg",
+ "filename" : "all_chats_onboarding2.png",
"idiom" : "universal",
"scale" : "1x"
},
{
+ "filename" : "all_chats_onboarding2@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
+ "filename" : "all_chats_onboarding2@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2.png
new file mode 100644
index 000000000..119903ee6
Binary files /dev/null and b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2.png differ
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2.svg b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2.svg
deleted file mode 100644
index 72518cdd8..000000000
--- a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2.svg
+++ /dev/null
@@ -1,40 +0,0 @@
-
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@2x.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@2x.png
new file mode 100644
index 000000000..5e33559ac
Binary files /dev/null and b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@2x.png differ
diff --git a/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@3x.png b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@3x.png
new file mode 100644
index 000000000..b36afc879
Binary files /dev/null and b/Riot/Assets/Images.xcassets/AllChatsOnboarding/all_chats_onboarding2.imageset/all_chats_onboarding2@3x.png differ
diff --git a/Riot/Assets/Images.xcassets/Home/all_chats_edit_icon.imageset/Contents.json b/Riot/Assets/Images.xcassets/Home/all_chats_edit_icon.imageset/Contents.json
index f00e7d1d2..4716ddef7 100644
--- a/Riot/Assets/Images.xcassets/Home/all_chats_edit_icon.imageset/Contents.json
+++ b/Riot/Assets/Images.xcassets/Home/all_chats_edit_icon.imageset/Contents.json
@@ -2,16 +2,7 @@
"images" : [
{
"filename" : "all_chats_edit_icon.svg",
- "idiom" : "universal",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "scale" : "3x"
+ "idiom" : "universal"
}
],
"info" : {
diff --git a/Riot/Assets/Images.xcassets/Home/all_chats_empty_list_placeholder_icon.imageset/Contents.json b/Riot/Assets/Images.xcassets/Home/all_chats_empty_list_placeholder_icon.imageset/Contents.json
index 90791b942..49e4118aa 100644
--- a/Riot/Assets/Images.xcassets/Home/all_chats_empty_list_placeholder_icon.imageset/Contents.json
+++ b/Riot/Assets/Images.xcassets/Home/all_chats_empty_list_placeholder_icon.imageset/Contents.json
@@ -2,16 +2,7 @@
"images" : [
{
"filename" : "all_chats_empty_list_placeholder_icon.svg",
- "idiom" : "universal",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "scale" : "3x"
+ "idiom" : "universal"
}
],
"info" : {
diff --git a/Riot/Assets/Images.xcassets/Home/all_chats_spaces_icon.imageset/Contents.json b/Riot/Assets/Images.xcassets/Home/all_chats_spaces_icon.imageset/Contents.json
index 20c13cc1f..d29454793 100644
--- a/Riot/Assets/Images.xcassets/Home/all_chats_spaces_icon.imageset/Contents.json
+++ b/Riot/Assets/Images.xcassets/Home/all_chats_spaces_icon.imageset/Contents.json
@@ -2,16 +2,7 @@
"images" : [
{
"filename" : "all_chats_spaces_icon.svg",
- "idiom" : "universal",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "scale" : "3x"
+ "idiom" : "universal"
}
],
"info" : {
diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings
index 90fbf058d..f642e3993 100644
--- a/Riot/Assets/en.lproj/Vector.strings
+++ b/Riot/Assets/en.lproj/Vector.strings
@@ -761,6 +761,7 @@ Tap the + to start adding people.";
"settings_labs_enable_auto_report_decryption_errors" = "Auto Report Decryption Errors";
"settings_labs_use_only_latest_user_avatar_and_name" = "Show latest avatar and name for users in message history";
"settings_labs_enable_live_location_sharing" = "Live location sharing - share current location (active development, and temporarily, locations persist in room history)";
+"settings_labs_enable_new_app_layout" = "New Application Layout";
"settings_version" = "Version %@";
"settings_olm_version" = "Olm Version %@";
diff --git a/Riot/Categories/MXRestClient+Async.swift b/Riot/Categories/MXRestClient+Async.swift
index 6d13c798f..d72bb9ce1 100644
--- a/Riot/Categories/MXRestClient+Async.swift
+++ b/Riot/Categories/MXRestClient+Async.swift
@@ -158,6 +158,7 @@ extension MXRestClient {
// MARK: - Private
+ @MainActor
private func getResponse(_ callback: (@escaping (MXResponse) -> Void) -> MXHTTPOperation) async throws -> T {
try await withCheckedThrowingContinuation { continuation in
_ = callback { response in
@@ -171,6 +172,7 @@ extension MXRestClient {
}
}
+ @MainActor
private func getResponse(_ callback: (@escaping (T?) -> Void, @escaping (Error?) -> Void) -> MXHTTPOperation) async throws -> T {
try await withCheckedThrowingContinuation { continuation in
_ = callback { response in
@@ -186,6 +188,7 @@ extension MXRestClient {
}
}
+ @MainActor
private func getResponse(_ callback: (@escaping (T?, U?, V?) -> Void, @escaping (Error?) -> Void) -> MXHTTPOperation) async throws -> (T?, U?, V?) {
try await withCheckedThrowingContinuation { continuation in
_ = callback { arg1, arg2, arg3 in
diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift
index 086139eec..1a079a716 100644
--- a/Riot/Generated/Strings.swift
+++ b/Riot/Generated/Strings.swift
@@ -7351,6 +7351,10 @@ public class VectorL10n: NSObject {
public static var settingsLabsEnableLiveLocationSharing: String {
return VectorL10n.tr("Vector", "settings_labs_enable_live_location_sharing")
}
+ /// New Application Layout
+ public static var settingsLabsEnableNewAppLayout: String {
+ return VectorL10n.tr("Vector", "settings_labs_enable_new_app_layout")
+ }
/// Ring for group calls
public static var settingsLabsEnableRingingForGroupCalls: String {
return VectorL10n.tr("Vector", "settings_labs_enable_ringing_for_group_calls")
diff --git a/Riot/Managers/Settings/RiotSettings.swift b/Riot/Managers/Settings/RiotSettings.swift
index c3732c144..240c04a3c 100644
--- a/Riot/Managers/Settings/RiotSettings.swift
+++ b/Riot/Managers/Settings/RiotSettings.swift
@@ -46,6 +46,8 @@ final class RiotSettings: NSObject {
private override init() {
super.init()
+ BuildSettings.isSideMenuActivated = BuildSettings.enableSideMenu && !newAppLayoutBetaEnabled
+ BuildSettings.isNewAppLayoutActivated = BuildSettings.newAppLayoutEnabled || newAppLayoutBetaEnabled
}
/// Indicate if UserDefaults suite has been migrated once.
@@ -381,9 +383,21 @@ final class RiotSettings: NSObject {
@UserDefault(key: "allChatsOnboardingHasBeenDisplayed", defaultValue: false, storage: defaults)
var allChatsOnboardingHasBeenDisplayed
+
+ // MARK: - New App Layout
+ @UserDefault(key: "newAppLayoutBetaEnabled", defaultValue: false, storage: defaults)
+ var newAppLayoutBetaEnabled {
+ didSet {
+ BuildSettings.isSideMenuActivated = BuildSettings.enableSideMenu && !newAppLayoutBetaEnabled
+ BuildSettings.isNewAppLayoutActivated = BuildSettings.newAppLayoutEnabled || newAppLayoutBetaEnabled
+ NotificationCenter.default.post(name: RiotSettings.newAppLayoutBetaToggleDidChange, object: self)
+ }
+ }
+
}
// MARK: - RiotSettings notification constants
extension RiotSettings {
public static let didUpdateLiveLocationSharingActivation = Notification.Name("RiotSettingsDidUpdateLiveLocationSharingActivation")
+ public static let newAppLayoutBetaToggleDidChange = Notification.Name("RiotSettingsNewAppLayoutBetaToggleDidChange")
}
diff --git a/Riot/Managers/Theme/Themes/BlackTheme.swift b/Riot/Managers/Theme/Themes/BlackTheme.swift
index d0ff58cd9..c05964236 100644
--- a/Riot/Managers/Theme/Themes/BlackTheme.swift
+++ b/Riot/Managers/Theme/Themes/BlackTheme.swift
@@ -22,8 +22,14 @@ class BlackTheme: DarkTheme {
super.init()
self.identifier = ThemeIdentifier.black.rawValue
self.backgroundColor = UIColor(rgb: 0x000000)
- self.baseColor = UIColor(rgb: 0x000000)
- self.headerBackgroundColor = UIColor(rgb: 0x000000)
self.headerBorderColor = UIColor(rgb: 0x15191E)
}
+
+ override var baseColor: UIColor {
+ UIColor(rgb: 0x000000)
+ }
+
+ override var headerBackgroundColor: UIColor {
+ UIColor(rgb: 0x000000)
+ }
}
diff --git a/Riot/Managers/Theme/Themes/DarkTheme.swift b/Riot/Managers/Theme/Themes/DarkTheme.swift
index 35651e6b1..dc4e89f1b 100644
--- a/Riot/Managers/Theme/Themes/DarkTheme.swift
+++ b/Riot/Managers/Theme/Themes/DarkTheme.swift
@@ -26,7 +26,9 @@ class DarkTheme: NSObject, Theme {
var backgroundColor: UIColor = UIColor(rgb: 0x15191E)
- var baseColor: UIColor = BuildSettings.newAppLayoutEnabled ? UIColor(rgb: 0x15191E) : UIColor(rgb: 0x21262C)
+ var baseColor: UIColor {
+ BuildSettings.isNewAppLayoutActivated ? UIColor(rgb: 0x15191E) : UIColor(rgb: 0x21262C)
+ }
var baseIconPrimaryColor: UIColor = UIColor(rgb: 0xEDF3FF)
var baseTextPrimaryColor: UIColor = UIColor(rgb: 0xFFFFFF)
var baseTextSecondaryColor: UIColor = UIColor(rgb: 0xA9B2BC)
@@ -35,7 +37,9 @@ class DarkTheme: NSObject, Theme {
var searchPlaceholderColor: UIColor = UIColor(rgb: 0xA9B2BC)
var searchResultHighlightColor: UIColor = UIColor(rgb: 0xFCC639).withAlphaComponent(0.3)
- var headerBackgroundColor: UIColor = BuildSettings.newAppLayoutEnabled ? UIColor(rgb: 0x15191E) : UIColor(rgb: 0x21262C)
+ var headerBackgroundColor: UIColor {
+ BuildSettings.isNewAppLayoutActivated ? UIColor(rgb: 0x15191E) : UIColor(rgb: 0x21262C)
+ }
var headerBorderColor: UIColor = UIColor(rgb: 0x15191E)
var headerTextPrimaryColor: UIColor = UIColor(rgb: 0xFFFFFF)
var headerTextSecondaryColor: UIColor = UIColor(rgb: 0xA9B2BC)
diff --git a/Riot/Managers/Theme/Themes/DefaultTheme.swift b/Riot/Managers/Theme/Themes/DefaultTheme.swift
index 412390a47..d58a1a6d0 100644
--- a/Riot/Managers/Theme/Themes/DefaultTheme.swift
+++ b/Riot/Managers/Theme/Themes/DefaultTheme.swift
@@ -26,7 +26,9 @@ class DefaultTheme: NSObject, Theme {
var backgroundColor: UIColor = UIColor(rgb: 0xFFFFFF)
- var baseColor: UIColor = BuildSettings.newAppLayoutEnabled ? UIColor(rgb: 0xFFFFFF) : UIColor(rgb: 0xF5F7FA)
+ var baseColor: UIColor {
+ BuildSettings.isNewAppLayoutActivated ? UIColor(rgb: 0xFFFFFF) : UIColor(rgb: 0xF5F7FA)
+ }
var baseIconPrimaryColor: UIColor = UIColor(rgb: 0xFFFFFF)
var baseTextPrimaryColor: UIColor = UIColor(rgb: 0xFFFFFF)
var baseTextSecondaryColor: UIColor = UIColor(rgb: 0x8F97A3)
@@ -35,7 +37,9 @@ class DefaultTheme: NSObject, Theme {
var searchPlaceholderColor: UIColor = UIColor(rgb: 0x8F97A3)
var searchResultHighlightColor: UIColor = UIColor(rgb: 0xFCC639).withAlphaComponent(0.2)
- var headerBackgroundColor: UIColor = BuildSettings.newAppLayoutEnabled ? UIColor(rgb: 0xFFFFFF) : UIColor(rgb: 0xF5F7FA)
+ var headerBackgroundColor: UIColor {
+ BuildSettings.isNewAppLayoutActivated ? UIColor(rgb: 0xFFFFFF) : UIColor(rgb: 0xF5F7FA)
+ }
var headerBorderColor: UIColor = UIColor(rgb: 0xE9EDF1)
var headerTextPrimaryColor: UIColor = UIColor(rgb: 0x17191C)
var headerTextSecondaryColor: UIColor = UIColor(rgb: 0x737D8C)
@@ -169,7 +173,7 @@ class DefaultTheme: NSObject, Theme {
searchBar.backgroundImage = UIImage() // Remove top and bottom shadow
searchBar.tintColor = self.tintColor
- guard !BuildSettings.newAppLayoutEnabled else {
+ guard !BuildSettings.isNewAppLayoutActivated else {
return
}
diff --git a/Riot/Modules/Analytics/SentryMonitoringClient.swift b/Riot/Modules/Analytics/SentryMonitoringClient.swift
index b848c02a9..38b91960b 100644
--- a/Riot/Modules/Analytics/SentryMonitoringClient.swift
+++ b/Riot/Modules/Analytics/SentryMonitoringClient.swift
@@ -34,6 +34,7 @@ struct SentryMonitoringClient {
options.dsn = Self.sentryDSN
// Collecting only 10% of all events
+ options.sampleRate = 0.1
options.tracesSampleRate = 0.1
options.beforeSend = { event in
diff --git a/Riot/Modules/Application/AppCoordinator.swift b/Riot/Modules/Application/AppCoordinator.swift
index 202e698a0..3553148f3 100755
--- a/Riot/Modules/Application/AppCoordinator.swift
+++ b/Riot/Modules/Application/AppCoordinator.swift
@@ -91,7 +91,7 @@ final class AppCoordinator: NSObject, AppCoordinatorType {
// Setup user location services
_ = UserLocationServiceProvider.shared
- if BuildSettings.enableSideMenu {
+ if BuildSettings.isSideMenuActivated {
self.addSideMenu()
}
@@ -105,6 +105,8 @@ final class AppCoordinator: NSObject, AppCoordinatorType {
}
}
+ NotificationCenter.default.addObserver(self, selector: #selector(self.newAppLayoutToggleDidChange(notification:)), name: RiotSettings.newAppLayoutBetaToggleDidChange, object: nil)
+
// NOTE: When split view is shown there can be no Matrix sessions ready. Keep this behavior or use a loading screen before showing the split view.
self.showSplitView()
MXLog.debug("[AppCoordinator] Showed split view")
@@ -160,6 +162,12 @@ final class AppCoordinator: NSObject, AppCoordinatorType {
ThemePublisher.shared.republish(themeIdPublisher: themeIdPublisher)
}
+ @objc private func newAppLayoutToggleDidChange(notification: Notification) {
+ if BuildSettings.isSideMenuActivated {
+ self.addSideMenu()
+ }
+ }
+
private func excludeAllItemsFromBackup() {
let manager = FileManager.default
diff --git a/Riot/Modules/Application/LegacyAppDelegate.m b/Riot/Modules/Application/LegacyAppDelegate.m
index 8a8545a4c..1b3ce1db7 100644
--- a/Riot/Modules/Application/LegacyAppDelegate.m
+++ b/Riot/Modules/Application/LegacyAppDelegate.m
@@ -1114,21 +1114,66 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
threadId:(NSString *)threadId
sender:(NSString *)userId
{
- if (roomId)
- {
- MXRoom *room = [self.mxSessions.firstObject roomWithRoomId:roomId];
- if (room.summary.membership != MXMembershipJoin)
+ void(^sessionReadyBlock)(MXSession*) = ^(MXSession *session){
+ if (roomId)
{
- Analytics.shared.joinedRoomTrigger = AnalyticsJoinedRoomTriggerNotification;
+ MXRoom *room = [session roomWithRoomId:roomId];
+ if (room.summary.membership != MXMembershipJoin)
+ {
+ Analytics.shared.joinedRoomTrigger = AnalyticsJoinedRoomTriggerNotification;
+ }
+ else
+ {
+ Analytics.shared.viewRoomTrigger = AnalyticsViewRoomTriggerNotification;
+ }
+ }
+
+ self.lastNavigatedRoomIdFromPush = roomId;
+
+ if (threadId)
+ {
+ if(![[MXKRoomDataSourceManager sharedManagerForMatrixSession:session] hasRoomDataSourceForRoom:roomId])
+ {
+ // the room having this thread probably was not opened before, paginate room messages to build threads
+ MXRoom *room = [session roomWithRoomId:roomId];
+ [room liveTimeline:^(id liveTimeline) {
+ [liveTimeline resetPagination];
+ [liveTimeline paginate:NSUIntegerMax direction:MXTimelineDirectionBackwards onlyFromStore:YES complete:^{
+ [liveTimeline resetPagination];
+ [self navigateToRoomById:roomId threadId:threadId sender:userId];
+ } failure:^(NSError * _Nonnull error) {
+ [self navigateToRoomById:roomId threadId:threadId sender:userId];
+ }];
+ }];
+ }
+ else
+ {
+ // the room has been opened before, we should be ok to continue
+ [self navigateToRoomById:roomId threadId:threadId sender:userId];
+ }
}
else
{
- Analytics.shared.viewRoomTrigger = AnalyticsViewRoomTriggerNotification;
+ [self navigateToRoomById:roomId threadId:threadId sender:userId];
}
- }
+ };
- _lastNavigatedRoomIdFromPush = roomId;
- [self navigateToRoomById:roomId threadId:threadId sender:userId];
+ MXSession *mxSession = self.mxSessions.firstObject;
+ if (mxSession.state >= MXSessionStateSyncInProgress)
+ {
+ sessionReadyBlock(mxSession);
+ }
+ else
+ {
+ // wait for session state to be sync in progress
+ __block id sessionStateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:mxSession queue:nil usingBlock:^(NSNotification * _Nonnull note) {
+ if (mxSession.state >= MXSessionStateSyncInProgress)
+ {
+ [[NSNotificationCenter defaultCenter] removeObserver:sessionStateObserver];
+ sessionReadyBlock(mxSession);
+ }
+ }];
+ }
}
#pragma mark - Badge Count
@@ -4212,7 +4257,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
}
// Need to set `showAllRoomsInHomeSpace` to `true` for the new App Layout
- if (BuildSettings.newAppLayoutEnabled)
+ if (BuildSettings.isNewAppLayoutActivated)
{
RiotSettings.shared.showAllRoomsInHomeSpace = YES;
}
diff --git a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m
index 18ea65eca..228751d31 100644
--- a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m
+++ b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m
@@ -84,7 +84,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
_crossSigningBannerDisplay = CrossSigningBannerDisplayNone;
_secureBackupBannerDisplay = SecureBackupBannerDisplayNone;
- _areSectionsShrinkable = !BuildSettings.newAppLayoutEnabled;
+ _areSectionsShrinkable = !BuildSettings.isNewAppLayoutActivated;
shrinkedSectionsBitMask = 0;
roomTagsListenerByUserId = [[NSMutableDictionary alloc] init];
@@ -758,7 +758,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
}
- if (count && !(sectionType == RecentsDataSourceSectionTypeInvites) && !BuildSettings.newAppLayoutEnabled)
+ if (count && !(sectionType == RecentsDataSourceSectionTypeInvites) && !BuildSettings.isNewAppLayoutActivated)
{
NSString *roomCount = [NSString stringWithFormat:@" %tu", count];
@@ -987,7 +987,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
sectionHeader.bottomView = nil;
}
- if (!BuildSettings.newAppLayoutEnabled || !sectionHeader.bottomView)
+ if (!BuildSettings.isNewAppLayoutActivated || !sectionHeader.bottomView)
{
// Add label
frame.size.height = RECENTSDATASOURCE_DEFAULT_SECTION_HEADER_HEIGHT - 10;
@@ -1101,7 +1101,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
{
RecentsInvitesTableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:[RecentsInvitesTableViewCell defaultReuseIdentifier]];
- tableViewCell.invitesCount = self.recentsListService.invitedRoomListData.counts.numberOfRooms;
+ tableViewCell.invitesCount = self.recentsListService.invitedRoomListData.counts.total.numberOfRooms;
return tableViewCell;
}
diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift
index 7370f0f94..74effcd99 100644
--- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift
+++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift
@@ -132,7 +132,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
if let fetcher = conversationRoomListDataFetcherForRooms, fetcherTypes.contains(.conversationRooms) {
result.append(fetcher)
}
- if let fetcher = lowPriorityRoomListDataFetcher, fetcherTypes.contains(.lowPriority) {
+ if let fetcher = lowPriorityRoomListDataFetcher, fetcherTypes.contains(.lowPriority), shouldShowLowPriority {
result.append(fetcher)
}
if let fetcher = serverNoticeRoomListDataFetcher, fetcherTypes.contains(.serverNotice) {
@@ -482,7 +482,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol {
}
private var shouldShowLowPriority: Bool {
- return fetcherTypesForMode[mode]?.contains(.lowPriority) ?? false
+ return ((mode != .allChats) || !AllChatsLayoutSettingsManager.shared.hasAnActiveFilter) && fetcherTypesForMode[mode]?.contains(.lowPriority) ?? false
}
private var shouldShowServerNotice: Bool {
diff --git a/Riot/Modules/ContextMenu/ContextMenuProviders/PublicRoomContextMenuProvider.swift b/Riot/Modules/ContextMenu/ContextMenuProviders/PublicRoomContextMenuProvider.swift
index da2502668..d30594110 100644
--- a/Riot/Modules/ContextMenu/ContextMenuProviders/PublicRoomContextMenuProvider.swift
+++ b/Riot/Modules/ContextMenu/ContextMenuProviders/PublicRoomContextMenuProvider.swift
@@ -37,7 +37,7 @@ class PublicRoomContextMenuProvider: NSObject {
}
roomViewController.isContextPreview = true
- RoomPreviewDataSource.load(withRoomId: room.roomId, andMatrixSession: session) { [weak roomViewController] roomDataSource in
+ RoomPreviewDataSource.load(withRoomId: room.roomId, threadId: nil, andMatrixSession: session) { [weak roomViewController] roomDataSource in
guard let dataSource = roomDataSource as? RoomPreviewDataSource else {
return
}
diff --git a/Riot/Modules/ContextMenu/ContextMenuProviders/RecentCellContextMenuProvider.swift b/Riot/Modules/ContextMenu/ContextMenuProviders/RecentCellContextMenuProvider.swift
index a748b7649..c696932db 100644
--- a/Riot/Modules/ContextMenu/ContextMenuProviders/RecentCellContextMenuProvider.swift
+++ b/Riot/Modules/ContextMenu/ContextMenuProviders/RecentCellContextMenuProvider.swift
@@ -57,7 +57,7 @@ class RecentCellContextMenuProvider: NSObject {
}
roomViewController.isContextPreview = true
- RoomPreviewDataSource.load(withRoomId: room.roomId, andMatrixSession: session) { [weak roomViewController] roomDataSource in
+ RoomPreviewDataSource.load(withRoomId: room.roomId, threadId: nil, andMatrixSession: session) { [weak roomViewController] roomDataSource in
guard let dataSource = roomDataSource as? RoomPreviewDataSource else {
return
}
diff --git a/Riot/Modules/GlobalSearch/UnifiedSearchViewController.m b/Riot/Modules/GlobalSearch/UnifiedSearchViewController.m
index 8703623bb..fb27ec4b4 100644
--- a/Riot/Modules/GlobalSearch/UnifiedSearchViewController.m
+++ b/Riot/Modules/GlobalSearch/UnifiedSearchViewController.m
@@ -146,7 +146,7 @@
[self updateSearch];
- if (BuildSettings.newAppLayoutEnabled)
+ if (BuildSettings.isNewAppLayoutActivated)
{
[self.searchBar vc_searchTextField].backgroundColor = nil;
[self vc_setLargeTitleDisplayMode: UINavigationItemLargeTitleDisplayModeAutomatic];
diff --git a/Riot/Modules/Home/AllChats/AllChatsLayoutSettingsManager.swift b/Riot/Modules/Home/AllChats/AllChatsLayoutSettingsManager.swift
index 065c54cb3..33b1ee335 100644
--- a/Riot/Modules/Home/AllChats/AllChatsLayoutSettingsManager.swift
+++ b/Riot/Modules/Home/AllChats/AllChatsLayoutSettingsManager.swift
@@ -105,6 +105,11 @@ final class AllChatsLayoutSettingsManager: NSObject {
}
}
+ /// `true` if filters are activated in the All Chats Layout screen and a filter other than `.all` is active
+ var hasAnActiveFilter: Bool {
+ return !allChatLayoutSettings.filters.isEmpty && !activeFilters.isEmpty && activeFilters != .all
+ }
+
// MARK: - Private
private func track(activeFilters: AllChatsLayoutFilterType?) {
diff --git a/Riot/Modules/Home/HomeViewController.m b/Riot/Modules/Home/HomeViewController.m
index 0ef4f7c48..c46e9d577 100644
--- a/Riot/Modules/Home/HomeViewController.m
+++ b/Riot/Modules/Home/HomeViewController.m
@@ -80,6 +80,11 @@
{
[super viewDidLoad];
+ if (!BuildSettings.isNewAppLayoutActivated)
+ {
+ [self.tabBarController vc_setLargeTitleDisplayMode:UINavigationItemLargeTitleDisplayModeNever];
+ }
+
self.roomListDataReady = NO;
self.view.accessibilityIdentifier = @"HomeVCView";
diff --git a/Riot/Modules/KeyVerification/User/SessionsStatus/UserVerificationSessionStatusCell.swift b/Riot/Modules/KeyVerification/User/SessionsStatus/UserVerificationSessionStatusCell.swift
index d0b6de6e7..548ce70b0 100644
--- a/Riot/Modules/KeyVerification/User/SessionsStatus/UserVerificationSessionStatusCell.swift
+++ b/Riot/Modules/KeyVerification/User/SessionsStatus/UserVerificationSessionStatusCell.swift
@@ -63,7 +63,7 @@ final class UserVerificationSessionStatusCell: UITableViewCell, NibReusable, The
func update(theme: Theme) {
self.theme = theme
- self.backgroundColor = theme.headerBackgroundColor
+ self.backgroundColor = theme.colors.system
self.sessionNameLabel.textColor = theme.textPrimaryColor
self.updateStatusTextColor()
}
diff --git a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.h b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.h
index a5c542880..d7c4b2db2 100644
--- a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.h
+++ b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.h
@@ -261,10 +261,11 @@ extern NSString *const kMXKRoomDataSourceTimelineErrorErrorKey;
the room data source is created.
@param roomId the id of the room to get data from.
+ @param threadId the id of the thread to load. If provided, thread data source will be loaded from the room specified with `roomId`.
@param mxSession the Matrix session to get data from.
@param onComplete a block providing the newly created instance.
*/
-+ (void)loadRoomDataSourceWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete;
++ (void)loadRoomDataSourceWithRoomId:(NSString*)roomId threadId:(NSString*)threadId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete;
/**
Asynchronously create adata source to serve data corresponding to an event in the
@@ -306,10 +307,11 @@ extern NSString *const kMXKRoomDataSourceTimelineErrorErrorKey;
Initialise the data source to serve data corresponding to the passed room.
@param roomId the id of the room to get data from.
+ @param threadId the id of the thread to initialize. If provided, thread data source will be initialized from the room specified with `roomId`.
@param mxSession the Matrix session to get data from.
@return the newly created instance.
*/
-- (instancetype)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession;
+- (instancetype)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession threadId:(NSString*)threadId;
/**
Initialise the data source to serve data corresponding to an event in the
diff --git a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m
index 5872eee2d..7770efd89 100644
--- a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m
+++ b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m
@@ -208,9 +208,9 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
@implementation MXKRoomDataSource
-+ (void)loadRoomDataSourceWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete
++ (void)loadRoomDataSourceWithRoomId:(NSString*)roomId threadId:(NSString*)threadId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete
{
- MXKRoomDataSource *roomDataSource = [[self alloc] initWithRoomId:roomId andMatrixSession:mxSession];
+ MXKRoomDataSource *roomDataSource = [[self alloc] initWithRoomId:roomId andMatrixSession:mxSession threadId:threadId];
[self ensureSessionStateForDataSource:roomDataSource initialEventId:nil andMatrixSession:mxSession onComplete:onComplete];
}
@@ -284,7 +284,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
}
}
-- (instancetype)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)matrixSession
+- (instancetype)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)matrixSession threadId:(NSString *)threadId
{
self = [super initWithMatrixSession:matrixSession];
if (self)
@@ -292,6 +292,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
MXLogVerbose(@"[MXKRoomDataSource][%p] initWithRoomId: %@", self, roomId);
_roomId = roomId;
+ _threadId = threadId;
_secondaryRoomEventTypes = @[
kMXEventTypeStringCallInvite,
kMXEventTypeStringCallCandidates,
@@ -368,7 +369,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
- (instancetype)initWithRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId2 threadId:(NSString*)threadId andMatrixSession:(MXSession*)mxSession
{
- self = [self initWithRoomId:roomId andMatrixSession:mxSession];
+ self = [self initWithRoomId:roomId andMatrixSession:mxSession threadId:threadId];
if (self)
{
if (initialEventId2)
@@ -376,7 +377,6 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
initialEventId = initialEventId2;
_isLive = NO;
}
- _threadId = threadId;
}
return self;
@@ -553,6 +553,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
}
self.room = nil;
+ self.thread = nil;
self.secondaryRoom = nil;
}
@@ -584,7 +585,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
- (void)destroy
{
- MXLogDebug(@"[MXKRoomDataSource][%p] Destroy - room id: %@", self, _roomId);
+ MXLogDebug(@"[MXKRoomDataSource][%p] Destroy - room id: %@ - thread id: %@", self, _roomId, _threadId);
[self unregisterScanManagerNotifications];
[self unregisterReactionsChangeListener];
@@ -2848,11 +2849,14 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
- (void)setState:(MXKDataSourceState)newState
{
- self->state = newState;
-
- if (self.delegate && [self.delegate respondsToSelector:@selector(dataSource:didStateChange:)])
+ if (self->state != newState)
{
- [self.delegate dataSource:self didStateChange:self->state];
+ self->state = newState;
+
+ if (self.delegate && [self.delegate respondsToSelector:@selector(dataSource:didStateChange:)])
+ {
+ [self.delegate dataSource:self didStateChange:self->state];
+ }
}
}
diff --git a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSourceManager.h b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSourceManager.h
index 46f6709da..28a62e80e 100644
--- a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSourceManager.h
+++ b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSourceManager.h
@@ -78,6 +78,13 @@ typedef enum : NSUInteger {
*/
- (void)reset;
+/**
+ Flag indicating the manager has a room data source for a given room id.
+
+ @param roomId the room id to check.
+ */
+- (BOOL)hasRoomDataSourceForRoom:(NSString*)roomId;
+
/**
Get a room data source corresponding to a room id.
diff --git a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSourceManager.m b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSourceManager.m
index fd4e54c8a..181552e53 100644
--- a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSourceManager.m
+++ b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSourceManager.m
@@ -191,6 +191,11 @@ static Class _roomDataSourceClass;
}
}
+- (BOOL)hasRoomDataSourceForRoom:(NSString *)roomId
+{
+ return roomDataSources[roomId] != nil;
+}
+
- (void)roomDataSourceForRoom:(NSString *)roomId create:(BOOL)create onComplete:(void (^)(MXKRoomDataSource *roomDataSource))onComplete
{
NSParameterAssert(roomId);
@@ -200,7 +205,7 @@ static Class _roomDataSourceClass;
if (!roomDataSource && create && roomId)
{
- [_roomDataSourceClass loadRoomDataSourceWithRoomId:roomId andMatrixSession:mxSession onComplete:^(id roomDataSource) {
+ [_roomDataSourceClass loadRoomDataSourceWithRoomId:roomId threadId:nil andMatrixSession:mxSession onComplete:^(id roomDataSource) {
[self addRoomDataSource:roomDataSource];
onComplete(roomDataSource);
}];
diff --git a/Riot/Modules/Room/ContextualMenu/ReactionsMenu/ReactionsMenuView.swift b/Riot/Modules/Room/ContextualMenu/ReactionsMenu/ReactionsMenuView.swift
index b539368c3..b72b31ac0 100644
--- a/Riot/Modules/Room/ContextualMenu/ReactionsMenu/ReactionsMenuView.swift
+++ b/Riot/Modules/Room/ContextualMenu/ReactionsMenu/ReactionsMenuView.swift
@@ -73,8 +73,8 @@ final class ReactionsMenuView: UIView, Themable, NibLoadable {
// MARK: - Public
func update(theme: Theme) {
- self.reactionsBackgroundView.backgroundColor = theme.headerBackgroundColor
- self.moreReactionsBackgroundView.backgroundColor = theme.headerBackgroundColor
+ self.reactionsBackgroundView.backgroundColor = theme.colors.system
+ self.moreReactionsBackgroundView.backgroundColor = theme.colors.system
self.moreReactionsButton.tintColor = theme.tintColor
}
diff --git a/Riot/Modules/Room/DataSources/RoomDataSource.m b/Riot/Modules/Room/DataSources/RoomDataSource.m
index 958403acc..ed48741db 100644
--- a/Riot/Modules/Room/DataSources/RoomDataSource.m
+++ b/Riot/Modules/Room/DataSources/RoomDataSource.m
@@ -68,9 +68,9 @@ const CGFloat kTypingCellHeight = 24;
@implementation RoomDataSource
-- (instancetype)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)matrixSession
+- (instancetype)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)matrixSession threadId:(NSString *)threadId
{
- self = [super initWithRoomId:roomId andMatrixSession:matrixSession];
+ self = [super initWithRoomId:roomId andMatrixSession:matrixSession threadId:threadId];
if (self)
{
// Replace default Cell data class
diff --git a/Riot/Modules/Room/DataSources/ThreadDataSource.swift b/Riot/Modules/Room/DataSources/ThreadDataSource.swift
index 4c46a1f42..3f69f7a04 100644
--- a/Riot/Modules/Room/DataSources/ThreadDataSource.swift
+++ b/Riot/Modules/Room/DataSources/ThreadDataSource.swift
@@ -15,15 +15,31 @@
//
import Foundation
+import UIKit
@objcMembers
public class ThreadDataSource: RoomDataSource {
+
+ private typealias ThreadID = String
+
+ /// Map of cached data sources. Keys are thread identifiers.
+ private static var dataSourceCache: [ThreadID: ThreadDataSource] = [:]
public override func finalizeInitialization() {
super.finalizeInitialization()
showReadMarker = false
showBubbleReceipts = false
showTypingRow = false
+
+ NotificationCenter.default.addObserver(self,
+ selector: #selector(didReceiveMemoryWarning),
+ name: UIApplication.didReceiveMemoryWarningNotification,
+ object: nil)
+
+ NotificationCenter.default.addObserver(self,
+ selector: #selector(didLeaveRoom(_:)),
+ name: .mxSessionDidLeaveRoom,
+ object: nil)
}
public override var showReadMarker: Bool {
@@ -41,5 +57,47 @@ public class ThreadDataSource: RoomDataSource {
_ = newValue
}
}
+
+ public override class func load(withRoomId roomId: String!,
+ initialEventId: String!,
+ threadId: String!,
+ andMatrixSession mxSession: MXSession!,
+ onComplete: ((Any?) -> Void)!) {
+ if let dataSource = dataSourceCache[threadId] {
+ onComplete(dataSource)
+ return
+ }
+ super.load(withRoomId: roomId, initialEventId: initialEventId, threadId: threadId, andMatrixSession: mxSession) { dataSource in
+ if let dataSource = dataSource as? ThreadDataSource {
+ Self.dataSourceCache[threadId] = dataSource
+ }
+ onComplete(dataSource)
+ }
+ }
+
+ @objc
+ private func didReceiveMemoryWarning() {
+ MXLog.debug("[ThreadDataSource] didReceiveMemoryWarning. Will reload not active data sources in cache.")
+
+ Self.dataSourceCache.forEach {
+ if $1.delegate == nil {
+ $1.reload()
+ }
+ }
+ }
+
+ @objc
+ private func didLeaveRoom(_ notification: Notification) {
+ MXLog.debug("[ThreadDataSource] didReceiveMemoryWarning. Will reload not active data sources in cache.")
+
+ guard let session = notification.object as? MXSession,
+ session == mxSession,
+ let roomId = notification.userInfo?[kMXSessionNotificationRoomIdKey] as? String else {
+ return
+ }
+
+ let threadIds = Array(Self.dataSourceCache.filter { $1.roomId == roomId }.keys)
+ threadIds.forEach { Self.dataSourceCache.removeValue(forKey: $0) }
+ }
}
diff --git a/Riot/Modules/Room/MXKRoomViewController.m b/Riot/Modules/Room/MXKRoomViewController.m
index 2002d7344..e007b8595 100644
--- a/Riot/Modules/Room/MXKRoomViewController.m
+++ b/Riot/Modules/Room/MXKRoomViewController.m
@@ -291,6 +291,8 @@
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
+
+ [self.navigationController setToolbarHidden:YES animated:NO];
// Observe server sync process at room data source level too
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMatrixSessionChange) name:kMXKRoomDataSourceSyncStatusChanged object:nil];
@@ -339,7 +341,7 @@
_bubblesTableView.hidden = NO;
}
- if (BuildSettings.newAppLayoutEnabled)
+ if (BuildSettings.isNewAppLayoutActivated)
{
[self vc_setLargeTitleDisplayMode: UINavigationItemLargeTitleDisplayModeNever];
}
diff --git a/Riot/Modules/Room/RoomCoordinator.swift b/Riot/Modules/Room/RoomCoordinator.swift
index 1728aac21..643cd803e 100644
--- a/Riot/Modules/Room/RoomCoordinator.swift
+++ b/Riot/Modules/Room/RoomCoordinator.swift
@@ -67,7 +67,10 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol {
var canReleaseRoomDataSource: Bool {
// If the displayed data is not a preview, let the manager release the room data source
// (except if the view controller has the room data source ownership).
- return self.parameters.previewData == nil && self.roomViewController.roomDataSource != nil && self.roomViewController.hasRoomDataSourceOwnership == false
+ return self.parameters.previewData == nil
+ && self.roomViewController.roomDataSource != nil
+ && self.roomViewController.roomDataSource.threadId == nil
+ && self.roomViewController.hasRoomDataSourceOwnership == false
}
// MARK: - Setup
@@ -238,7 +241,7 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol {
self.roomViewController.displayRoom(threadDataSource)
// Give the data source ownership to the room view controller.
- self.roomViewController.hasRoomDataSourceOwnership = true
+ self.roomViewController.hasRoomDataSourceOwnership = false
self.mxSession?.updateBreadcrumbsWithRoom(withId: roomId, success: nil, failure: nil)
diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift
index 5d75ed1b8..44ddb735b 100644
--- a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift
+++ b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift
@@ -47,7 +47,7 @@ final class RoomInfoCoordinator: NSObject, RoomInfoCoordinatorType {
let files = RoomFilesViewController()
files.finalizeInit()
files.screenTracker = AnalyticsScreenTracker(screen: .roomUploads)
- MXKRoomDataSource.load(withRoomId: self.room.roomId, andMatrixSession: self.session) { (dataSource) in
+ MXKRoomDataSource.load(withRoomId: self.room.roomId, threadId: nil, andMatrixSession: self.session) { (dataSource) in
guard let dataSource = dataSource as? MXKRoomDataSource else { return }
dataSource.filterMessagesWithURL = true
dataSource.finalizeInitialization()
diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m
index 1c9114ab1..7d3da462f 100644
--- a/Riot/Modules/Room/RoomViewController.m
+++ b/Riot/Modules/Room/RoomViewController.m
@@ -5687,6 +5687,7 @@ static CGSize kThreadListBarButtonItemImageSize;
if (self.isContextPreview)
{
[RoomPreviewDataSource loadRoomDataSourceWithRoomId:self.roomDataSource.roomId
+ threadId:nil
andMatrixSession:self.mainSession
onComplete:^(RoomPreviewDataSource *roomDataSource)
{
diff --git a/Riot/Modules/Room/TimelineCells/KeyVerification/KeyVerificationCellInnerContentView.swift b/Riot/Modules/Room/TimelineCells/KeyVerification/KeyVerificationCellInnerContentView.swift
index cac389332..62bc9b7e6 100644
--- a/Riot/Modules/Room/TimelineCells/KeyVerification/KeyVerificationCellInnerContentView.swift
+++ b/Riot/Modules/Room/TimelineCells/KeyVerification/KeyVerificationCellInnerContentView.swift
@@ -130,7 +130,7 @@ final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
// MARK: - Public
func update(theme: Theme) {
- self.backgroundColor = theme.headerBackgroundColor
+ self.backgroundColor = theme.colors.system
self.titleLabel.textColor = theme.textPrimaryColor
self.otherUserInformationLabel.textColor = theme.textSecondaryColor
diff --git a/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionActionViewCell.swift b/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionActionViewCell.swift
index 9b966de0f..433401bca 100644
--- a/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionActionViewCell.swift
+++ b/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionActionViewCell.swift
@@ -87,6 +87,6 @@ final class RoomReactionActionViewCell: UICollectionViewCell, NibReusable, Thema
self.actionLabel.textColor = self.theme?.textSecondaryColor
self.reactionBackgroundView.layer.borderWidth = 0.0
- self.reactionBackgroundView.backgroundColor = self.theme?.headerBackgroundColor
+ self.reactionBackgroundView.backgroundColor = self.theme?.colors.system
}
}
diff --git a/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionImageViewCell.swift b/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionImageViewCell.swift
index a063db721..454822478 100644
--- a/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionImageViewCell.swift
+++ b/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionImageViewCell.swift
@@ -79,6 +79,6 @@ final class RoomReactionImageViewCell: UICollectionViewCell, NibReusable, Themab
self.imageView.tintColor = self.theme?.textSecondaryColor
self.reactionBackgroundView.layer.borderWidth = 0.0
- self.reactionBackgroundView.backgroundColor = self.theme?.headerBackgroundColor
+ self.reactionBackgroundView.backgroundColor = self.theme?.colors.system
}
}
diff --git a/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionViewCell.swift b/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionViewCell.swift
index 7e509e923..1e530b126 100644
--- a/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionViewCell.swift
+++ b/Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionViewCell.swift
@@ -97,7 +97,7 @@ final class RoomReactionViewCell: UICollectionViewCell, NibReusable, Themable {
reactionBackgroundColor = self.theme?.tintBackgroundColor
reactionBackgroundBorderWidth = Constants.selectedBorderWidth
} else {
- reactionBackgroundColor = self.theme?.headerBackgroundColor
+ reactionBackgroundColor = self.theme?.colors.system
reactionBackgroundBorderWidth = 0.0
}
diff --git a/Riot/Modules/SetPinCode/PinCodePreferences.swift b/Riot/Modules/SetPinCode/PinCodePreferences.swift
index 386dc26a0..a55530f1f 100644
--- a/Riot/Modules/SetPinCode/PinCodePreferences.swift
+++ b/Riot/Modules/SetPinCode/PinCodePreferences.swift
@@ -127,6 +127,10 @@ final class PinCodePreferences: NSObject {
var canUseBiometricsToUnlock: Bool? {
get {
+ guard isBiometricsAvailable == true else {
+ return false
+ }
+
do {
return try store.bool(forKey: StoreKeys.canUseBiometricsToUnlock)
} catch let error {
diff --git a/Riot/Modules/SetPinCode/SetPinCoordinatorBridgePresenter.swift b/Riot/Modules/SetPinCode/SetPinCoordinatorBridgePresenter.swift
index 2351e5f61..c381b76eb 100644
--- a/Riot/Modules/SetPinCode/SetPinCoordinatorBridgePresenter.swift
+++ b/Riot/Modules/SetPinCode/SetPinCoordinatorBridgePresenter.swift
@@ -95,13 +95,8 @@ final class SetPinCoordinatorBridgePresenter: NSObject {
let setPinCoordinator = SetPinCoordinator(session: self.session, viewMode: self.viewMode, pinCodePreferences: .shared)
setPinCoordinator.delegate = self
- guard let view = setPinCoordinator.toPresentable().view else { return }
- pinCoordinatorWindow.addSubview(view)
- view.leadingAnchor.constraint(equalTo: pinCoordinatorWindow.leadingAnchor, constant: 0).isActive = true
- view.trailingAnchor.constraint(equalTo: pinCoordinatorWindow.trailingAnchor, constant: 0).isActive = true
- view.topAnchor.constraint(equalTo: pinCoordinatorWindow.topAnchor, constant: 0).isActive = true
- view.bottomAnchor.constraint(equalTo: pinCoordinatorWindow.bottomAnchor, constant: 0).isActive = true
+ pinCoordinatorWindow.rootViewController = setPinCoordinator.toPresentable()
pinCoordinatorWindow.makeKeyAndVisible()
setPinCoordinator.start()
diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m
index 6b9a19f97..2da06cdf9 100644
--- a/Riot/Modules/Settings/SettingsViewController.m
+++ b/Riot/Modules/Settings/SettingsViewController.m
@@ -172,7 +172,8 @@ typedef NS_ENUM(NSUInteger, LABS_ENABLE)
LABS_ENABLE_RINGING_FOR_GROUP_CALLS_INDEX = 0,
LABS_ENABLE_THREADS_INDEX,
LABS_ENABLE_AUTO_REPORT_DECRYPTION_ERRORS,
- LABS_ENABLE_LIVE_LOCATION_SHARING
+ LABS_ENABLE_LIVE_LOCATION_SHARING,
+ LABS_ENABLE_NEW_APP_LAYOUT
};
typedef NS_ENUM(NSUInteger, SECURITY)
@@ -595,6 +596,7 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
{
[sectionLabs addRowWithTag:LABS_ENABLE_LIVE_LOCATION_SHARING];
}
+ [sectionLabs addRowWithTag:LABS_ENABLE_NEW_APP_LAYOUT];
sectionLabs.headerTitle = [VectorL10n settingsLabs];
if (sectionLabs.hasAnyRows)
{
@@ -1497,6 +1499,21 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
return labelAndSwitchCell;
}
+- (UITableViewCell *)buildNewAppLayoutCellForTableView:(UITableView*)tableView
+ atIndexPath:(NSIndexPath*)indexPath
+{
+ MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
+
+ labelAndSwitchCell.mxkLabel.text = [VectorL10n settingsLabsEnableNewAppLayout];
+
+ labelAndSwitchCell.mxkSwitch.on = RiotSettings.shared.newAppLayoutBetaEnabled;
+ labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor;
+ labelAndSwitchCell.mxkSwitch.enabled = YES;
+ [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleEnableNewAppLayout:) forControlEvents:UIControlEventTouchUpInside];
+
+ return labelAndSwitchCell;
+}
+
#pragma mark - 3Pid Add
- (void)showAuthenticationIfNeededForAdding:(MX3PIDMedium)medium withSession:(MXSession*)session completion:(void (^)(NSDictionary* authParams))completion
@@ -2532,6 +2549,10 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
{
cell = [self buildLiveLocationSharingCellForTableView:tableView atIndexPath:indexPath];
}
+ else if (row == LABS_ENABLE_NEW_APP_LAYOUT)
+ {
+ cell = [self buildNewAppLayoutCellForTableView:tableView atIndexPath:indexPath];
+ }
}
else if (section == SECTION_TAG_SECURITY)
{
@@ -3971,6 +3992,15 @@ ChangePasswordCoordinatorBridgePresenterDelegate>
RiotSettings.shared.enableLiveLocationSharing = sender.isOn;
}
+- (void)toggleEnableNewAppLayout:(UISwitch *)sender
+{
+ if (sender.isOn)
+ {
+ RiotSettings.shared.showAllRoomsInHomeSpace = YES;
+ }
+ RiotSettings.shared.newAppLayoutBetaEnabled = sender.isOn;
+}
+
#pragma mark - TextField listener
- (IBAction)textFieldDidChange:(id)sender
diff --git a/Riot/Modules/SplitView/SplitViewCoordinator.swift b/Riot/Modules/SplitView/SplitViewCoordinator.swift
index eff81d0e5..a3de10ee5 100644
--- a/Riot/Modules/SplitView/SplitViewCoordinator.swift
+++ b/Riot/Modules/SplitView/SplitViewCoordinator.swift
@@ -227,7 +227,7 @@ final class SplitViewCoordinator: NSObject, SplitViewCoordinatorType {
}
let existingRoomCoordinatorWithSameRoomId = self.detailModules.first { presentable -> Bool in
- if let currentRoomCoordinator = presentable as? RoomCoordinatorProtocol {
+ if let currentRoomCoordinator = presentable as? RoomCoordinatorProtocol, currentRoomCoordinator.threadId == nil {
return currentRoomCoordinator.roomId == roomCoordinator.roomId
}
return false
diff --git a/Riot/Modules/TabBar/MasterTabBarController.m b/Riot/Modules/TabBar/MasterTabBarController.m
index b9f926407..96cc0880f 100644
--- a/Riot/Modules/TabBar/MasterTabBarController.m
+++ b/Riot/Modules/TabBar/MasterTabBarController.m
@@ -156,7 +156,7 @@
[self userInterfaceThemeDidChange];
}
- self.tabBar.hidden = BuildSettings.newAppLayoutEnabled;
+ self.tabBar.hidden = BuildSettings.isNewAppLayoutActivated;
}
- (void)viewDidAppear:(BOOL)animated
@@ -213,8 +213,8 @@
}
[[AppDelegate theDelegate] checkAppVersion];
-
- if (BuildSettings.newAppLayoutEnabled && !RiotSettings.shared.allChatsOnboardingHasBeenDisplayed)
+
+ if (BuildSettings.isNewAppLayoutActivated && !RiotSettings.shared.allChatsOnboardingHasBeenDisplayed)
{
[self showAllChatsOnboardingScreen];
}
@@ -633,7 +633,7 @@
{
if (roomParentId) {
NSString *parentName = [mxSession roomSummaryWithRoomId:roomParentId].displayname;
- if (!BuildSettings.newAppLayoutEnabled)
+ if (!BuildSettings.isNewAppLayoutActivated)
{
NSMutableArray *breadcrumbs = [[NSMutableArray alloc] initWithObjects:parentName, nil];
@@ -649,7 +649,7 @@
}
else
{
- if (!BuildSettings.newAppLayoutEnabled)
+ if (!BuildSettings.isNewAppLayoutActivated)
{
titleView.breadcrumbView.breadcrumbs = @[];
}
@@ -661,7 +661,7 @@
- (void)updateSideMenuNotifcationIcon
{
- if (BuildSettings.newAppLayoutEnabled) { return; }
+ if (BuildSettings.isNewAppLayoutActivated) { return; }
BOOL displayNotification = NO;
@@ -693,7 +693,7 @@
-(void)setupTitleView
{
- if (!BuildSettings.newAppLayoutEnabled)
+ if (!BuildSettings.isNewAppLayoutActivated)
{
titleView = [MainTitleView new];
self.navigationItem.titleView = titleView;
diff --git a/Riot/Modules/TabBar/TabBarCoordinator.swift b/Riot/Modules/TabBar/TabBarCoordinator.swift
index d059aa5d3..711e1e1cf 100644
--- a/Riot/Modules/TabBar/TabBarCoordinator.swift
+++ b/Riot/Modules/TabBar/TabBarCoordinator.swift
@@ -116,13 +116,15 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
self.addMatrixSessionToMasterTabBarController(userSession.matrixSession)
}
- if BuildSettings.enableSideMenu {
+ if BuildSettings.isSideMenuActivated {
self.setupSideMenuGestures()
}
self.registerUserSessionsServiceNotifications()
self.registerSessionChange()
+ NotificationCenter.default.addObserver(self, selector: #selector(self.newAppLayoutToggleDidChange(notification:)), name: RiotSettings.newAppLayoutBetaToggleDidChange, object: nil)
+
self.updateMasterTabBarController(with: spaceId, forceReload: true)
} else {
self.updateMasterTabBarController(with: spaceId)
@@ -239,6 +241,15 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
// MARK: - Private methods
+ @objc private func newAppLayoutToggleDidChange(notification: Notification) {
+ self.masterTabBarController = nil
+ start()
+// updateMasterTabBarController(with: self.currentSpaceId, forceReload: true)
+// createLeftButtonItem(for: self.masterTabBarController)
+// createRightButtonItem(for: self.masterTabBarController)
+// popToHome(animated: true, completion: nil)
+ }
+
private func createMasterTabBarController() -> MasterTabBarController {
let tabBarController = MasterTabBarController()
@@ -367,10 +378,10 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
private func updateTabControllers(for tabBarController: MasterTabBarController, showCommunities: Bool) {
var viewControllers: [UIViewController] = []
- let homeViewController = BuildSettings.newAppLayoutEnabled ? self.createAllChatsViewController() : self.createHomeViewController()
+ let homeViewController = BuildSettings.isNewAppLayoutActivated ? self.createAllChatsViewController() : self.createHomeViewController()
viewControllers.append(homeViewController)
- if !BuildSettings.newAppLayoutEnabled {
+ if !BuildSettings.isNewAppLayoutActivated {
if RiotSettings.shared.homeScreenShowFavouritesTab {
let favouritesViewController = self.createFavouritesViewController()
viewControllers.append(favouritesViewController)
@@ -703,14 +714,15 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
// MARK: Navigation bar items management
private weak var rightMenuAvatarView: AvatarView?
+ private weak var rightMenuButton: UIButton?
private func createLeftButtonItem(for viewController: UIViewController) {
- guard !BuildSettings.newAppLayoutEnabled else {
+ guard !BuildSettings.isNewAppLayoutActivated else {
createAvatarButtonItem(for: viewController)
return
}
- guard BuildSettings.enableSideMenu else {
+ guard BuildSettings.isSideMenuActivated else {
let settingsBarButtonItem: MXKBarButtonItem = MXKBarButtonItem(image: Asset.Images.settingsIcon.image, style: .plain) { [weak self] in
self?.showSettings()
}
@@ -729,7 +741,7 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
}
private func createRightButtonItem(for viewController: UIViewController) {
- guard !BuildSettings.newAppLayoutEnabled else {
+ guard !BuildSettings.isNewAppLayoutActivated else {
return
}
@@ -776,6 +788,7 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
button.showsMenuAsPrimaryAction = true
button.autoresizingMask = [.flexibleHeight, .flexibleWidth]
view.addSubview(button)
+ self.rightMenuButton = button
let avatarView = UserAvatarView(frame: view.bounds.inset(by: UIEdgeInsets(top: 7, left: 7, bottom: 7, right: 7)))
avatarView.isUserInteractionEnabled = false
@@ -786,16 +799,18 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
if let avatar = userAvatarViewData(from: currentMatrixSession) {
avatarView.fill(with: avatar)
+ button.setImage(nil, for: .normal)
}
viewController.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: view)
}
private func updateAvatarButtonItem() {
- guard let avatarView = rightMenuAvatarView, let avatar = userAvatarViewData(from: currentMatrixSession) else {
+ guard let avatarView = rightMenuAvatarView, let button = rightMenuButton, let avatar = userAvatarViewData(from: currentMatrixSession) else {
return
}
+ button.setImage(nil, for: .normal)
avatarView.fill(with: avatar)
}
@@ -890,7 +905,7 @@ final class TabBarCoordinator: NSObject, TabBarCoordinatorType {
private var windowOverlay: WindowOverlayPresenter?
func showCoachMessageIfNeeded(with session: MXSession) {
- guard !BuildSettings.newAppLayoutEnabled else {
+ guard !BuildSettings.isNewAppLayoutActivated else {
// Showing coach message makes no sense with the new App Layout
return
}
@@ -937,7 +952,7 @@ extension TabBarCoordinator: MasterTabBarControllerDelegate {
}
func masterTabBarController(_ masterTabBarController: MasterTabBarController!, needsSideMenuIconWithNotification displayNotification: Bool) {
- guard BuildSettings.enableSideMenu else {
+ guard BuildSettings.isSideMenuActivated else {
return
}
diff --git a/RiotTests/MatrixKitTests/MXKRoomDataSourceTests.swift b/RiotTests/MatrixKitTests/MXKRoomDataSourceTests.swift
index ce8a3d44e..cd7f8db15 100644
--- a/RiotTests/MatrixKitTests/MXKRoomDataSourceTests.swift
+++ b/RiotTests/MatrixKitTests/MXKRoomDataSourceTests.swift
@@ -93,7 +93,7 @@ private final class StubMXKRoomDataSource: MXKRoomDataSource {
private final class FakeMXKRoomDataSource: MXKRoomDataSource {
class func make() throws -> FakeMXKRoomDataSource {
- let dataSource = try XCTUnwrap(FakeMXKRoomDataSource(roomId: "!foofoofoofoofoofoo:matrix.org", andMatrixSession: nil))
+ let dataSource = try XCTUnwrap(FakeMXKRoomDataSource(roomId: "!foofoofoofoofoofoo:matrix.org", andMatrixSession: nil, threadId: nil))
dataSource.registerCellDataClass(CollapsibleBubbleCellData.self, forCellIdentifier: kMXKRoomBubbleCellDataIdentifier)
dataSource.eventFormatter = CountingEventFormatter(matrixSession: nil)
return dataSource