mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Add a banner that offers the user to transition to native sliding sync (#3252)
* Fixes #2508 - Offer user to transition to SSS * Rename `HomeScreenBannerMode.shown` to `HomeScreenBannerMode.show` * Generate and use preview tests for the migration banner * Bump the RustSDK to v1.0.46 * Address PR review comment
This commit is contained in:
@@ -56,6 +56,7 @@
|
|||||||
09AAF04B27732046C755D914 /* SoftLogoutViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C5DAA1773F57653BF1C4F9 /* SoftLogoutViewModelTests.swift */; };
|
09AAF04B27732046C755D914 /* SoftLogoutViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C5DAA1773F57653BF1C4F9 /* SoftLogoutViewModelTests.swift */; };
|
||||||
09C83DDDB07C28364F325209 /* MockRoomTimelineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52D7074991B3267B26D89B22 /* MockRoomTimelineController.swift */; };
|
09C83DDDB07C28364F325209 /* MockRoomTimelineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52D7074991B3267B26D89B22 /* MockRoomTimelineController.swift */; };
|
||||||
09D3D7D115318CAD131B4FE7 /* ResolveVerifiedUserSendFailureScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57084488B03BDB33C7B7CA0E /* ResolveVerifiedUserSendFailureScreenViewModelTests.swift */; };
|
09D3D7D115318CAD131B4FE7 /* ResolveVerifiedUserSendFailureScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57084488B03BDB33C7B7CA0E /* ResolveVerifiedUserSendFailureScreenViewModelTests.swift */; };
|
||||||
|
0A0625A271EE5B06D2AAA069 /* HomeScreenSlidingSyncMigrationBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4691B8DE1D51DE152680098A /* HomeScreenSlidingSyncMigrationBanner.swift */; };
|
||||||
0A194F5E70B5A628C1BF4476 /* AdvancedSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4999B5FD50AED7CB0F590FF8 /* AdvancedSettingsScreenModels.swift */; };
|
0A194F5E70B5A628C1BF4476 /* AdvancedSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4999B5FD50AED7CB0F590FF8 /* AdvancedSettingsScreenModels.swift */; };
|
||||||
0ACAA31FD0399CEEBA3ECC21 /* UserDetailsEditScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85149F56BA333619900E2410 /* UserDetailsEditScreenViewModelProtocol.swift */; };
|
0ACAA31FD0399CEEBA3ECC21 /* UserDetailsEditScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85149F56BA333619900E2410 /* UserDetailsEditScreenViewModelProtocol.swift */; };
|
||||||
0AE0AB1952F186EB86719B4F /* HomeScreenRoomCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */; };
|
0AE0AB1952F186EB86719B4F /* HomeScreenRoomCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */; };
|
||||||
@@ -1492,6 +1493,7 @@
|
|||||||
45D8149FDDA0315CDC553B4B /* UserNotificationCenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationCenterProtocol.swift; sourceTree = "<group>"; };
|
45D8149FDDA0315CDC553B4B /* UserNotificationCenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationCenterProtocol.swift; sourceTree = "<group>"; };
|
||||||
4629710C0337ADD9C8909542 /* ka */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ka; path = ka.lproj/Localizable.strings; sourceTree = "<group>"; };
|
4629710C0337ADD9C8909542 /* ka */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ka; path = ka.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
466C71A0FED9BFF287613C82 /* RoomDetailsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenModels.swift; sourceTree = "<group>"; };
|
466C71A0FED9BFF287613C82 /* RoomDetailsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenModels.swift; sourceTree = "<group>"; };
|
||||||
|
4691B8DE1D51DE152680098A /* HomeScreenSlidingSyncMigrationBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenSlidingSyncMigrationBanner.swift; sourceTree = "<group>"; };
|
||||||
46A2AD86F7E618F468F6FAF5 /* VoiceMessageRecordingButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRecordingButton.swift; sourceTree = "<group>"; };
|
46A2AD86F7E618F468F6FAF5 /* VoiceMessageRecordingButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRecordingButton.swift; sourceTree = "<group>"; };
|
||||||
46C208DA43CE25D13E670F40 /* UITestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsAppCoordinator.swift; sourceTree = "<group>"; };
|
46C208DA43CE25D13E670F40 /* UITestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsAppCoordinator.swift; sourceTree = "<group>"; };
|
||||||
46D0BA44B1838E65B507B277 /* NotificationPermissionsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPermissionsScreen.swift; sourceTree = "<group>"; };
|
46D0BA44B1838E65B507B277 /* NotificationPermissionsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPermissionsScreen.swift; sourceTree = "<group>"; };
|
||||||
@@ -3354,6 +3356,7 @@
|
|||||||
05512FB13987D221B7205DE0 /* HomeScreenRecoveryKeyConfirmationBanner.swift */,
|
05512FB13987D221B7205DE0 /* HomeScreenRecoveryKeyConfirmationBanner.swift */,
|
||||||
ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */,
|
ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */,
|
||||||
C7661EFFCAA307A97D71132A /* HomeScreenRoomList.swift */,
|
C7661EFFCAA307A97D71132A /* HomeScreenRoomList.swift */,
|
||||||
|
4691B8DE1D51DE152680098A /* HomeScreenSlidingSyncMigrationBanner.swift */,
|
||||||
84AF32E4136FD6F159D86C2C /* RoomDirectorySearchView.swift */,
|
84AF32E4136FD6F159D86C2C /* RoomDirectorySearchView.swift */,
|
||||||
037A5661B26EC6BE068188D7 /* Filters */,
|
037A5661B26EC6BE068188D7 /* Filters */,
|
||||||
);
|
);
|
||||||
@@ -6372,6 +6375,7 @@
|
|||||||
B04E9EB589CE99C3929E817A /* HomeScreenRecoveryKeyConfirmationBanner.swift in Sources */,
|
B04E9EB589CE99C3929E817A /* HomeScreenRecoveryKeyConfirmationBanner.swift in Sources */,
|
||||||
0AE0AB1952F186EB86719B4F /* HomeScreenRoomCell.swift in Sources */,
|
0AE0AB1952F186EB86719B4F /* HomeScreenRoomCell.swift in Sources */,
|
||||||
A10D6CCDE2010C09EEA1A593 /* HomeScreenRoomList.swift in Sources */,
|
A10D6CCDE2010C09EEA1A593 /* HomeScreenRoomList.swift in Sources */,
|
||||||
|
0A0625A271EE5B06D2AAA069 /* HomeScreenSlidingSyncMigrationBanner.swift in Sources */,
|
||||||
DE4F8C4E0F1DB4832F09DE97 /* HomeScreenViewModel.swift in Sources */,
|
DE4F8C4E0F1DB4832F09DE97 /* HomeScreenViewModel.swift in Sources */,
|
||||||
56F0A22972A3BB519DA2261C /* HomeScreenViewModelProtocol.swift in Sources */,
|
56F0A22972A3BB519DA2261C /* HomeScreenViewModelProtocol.swift in Sources */,
|
||||||
2BBE320EE426A347AAE5C7DA /* IdentityConfirmationScreen.swift in Sources */,
|
2BBE320EE426A347AAE5C7DA /* IdentityConfirmationScreen.swift in Sources */,
|
||||||
@@ -7687,7 +7691,7 @@
|
|||||||
repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift";
|
repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift";
|
||||||
requirement = {
|
requirement = {
|
||||||
kind = exactVersion;
|
kind = exactVersion;
|
||||||
version = 1.0.45;
|
version = 1.0.46;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
|
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
|
||||||
|
|||||||
@@ -149,8 +149,8 @@
|
|||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/element-hq/matrix-rust-components-swift",
|
"location" : "https://github.com/element-hq/matrix-rust-components-swift",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "103b7000e5191485873a81386d0134d71bd9fc36",
|
"revision" : "50f8730000a1cc9ebe75ecf879c2b85b36adfd34",
|
||||||
"version" : "1.0.45"
|
"version" : "1.0.46"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -407,12 +407,14 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
settingsFlowCoordinator.handleAppRoute(.chatBackupSettings, animated: true)
|
settingsFlowCoordinator.handleAppRoute(.chatBackupSettings, animated: true)
|
||||||
case .presentStartChatScreen:
|
case .presentStartChatScreen:
|
||||||
stateMachine.processEvent(.showStartChatScreen)
|
stateMachine.processEvent(.showStartChatScreen)
|
||||||
case .logout:
|
|
||||||
Task { await self.runLogoutFlow() }
|
|
||||||
case .presentGlobalSearch:
|
case .presentGlobalSearch:
|
||||||
presentGlobalSearch()
|
presentGlobalSearch()
|
||||||
case .presentRoomDirectorySearch:
|
case .presentRoomDirectorySearch:
|
||||||
stateMachine.processEvent(.showRoomDirectorySearchScreen)
|
stateMachine.processEvent(.showRoomDirectorySearchScreen)
|
||||||
|
case .logoutWithoutConfirmation:
|
||||||
|
self.actionsSubject.send(.logout)
|
||||||
|
case .logout:
|
||||||
|
Task { await self.runLogoutFlow() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|||||||
@@ -63,6 +63,11 @@ extension ClientProxyMock {
|
|||||||
ignoreUserReturnValue = .success(())
|
ignoreUserReturnValue = .success(())
|
||||||
unignoreUserReturnValue = .success(())
|
unignoreUserReturnValue = .success(())
|
||||||
|
|
||||||
|
slidingSyncVersion = .native
|
||||||
|
availableSlidingSyncVersionsClosure = {
|
||||||
|
[]
|
||||||
|
}
|
||||||
|
|
||||||
trackRecentlyVisitedRoomReturnValue = .success(())
|
trackRecentlyVisitedRoomReturnValue = .success(())
|
||||||
recentlyVisitedRoomsReturnValue = .success([])
|
recentlyVisitedRoomsReturnValue = .success([])
|
||||||
recentConversationCounterpartsReturnValue = []
|
recentConversationCounterpartsReturnValue = []
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ enum HomeScreenCoordinatorAction {
|
|||||||
case presentStartChatScreen
|
case presentStartChatScreen
|
||||||
case presentGlobalSearch
|
case presentGlobalSearch
|
||||||
case presentRoomDirectorySearch
|
case presentRoomDirectorySearch
|
||||||
|
case logoutWithoutConfirmation
|
||||||
case logout
|
case logout
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,14 +65,16 @@ final class HomeScreenCoordinator: CoordinatorProtocol {
|
|||||||
actionsSubject.send(.presentSettingsScreen)
|
actionsSubject.send(.presentSettingsScreen)
|
||||||
case .presentSecureBackupSettings:
|
case .presentSecureBackupSettings:
|
||||||
actionsSubject.send(.presentSecureBackupSettings)
|
actionsSubject.send(.presentSecureBackupSettings)
|
||||||
case .logout:
|
|
||||||
actionsSubject.send(.logout)
|
|
||||||
case .presentStartChatScreen:
|
case .presentStartChatScreen:
|
||||||
actionsSubject.send(.presentStartChatScreen)
|
actionsSubject.send(.presentStartChatScreen)
|
||||||
case .presentGlobalSearch:
|
case .presentGlobalSearch:
|
||||||
actionsSubject.send(.presentGlobalSearch)
|
actionsSubject.send(.presentGlobalSearch)
|
||||||
case .presentRoomDirectorySearch:
|
case .presentRoomDirectorySearch:
|
||||||
actionsSubject.send(.presentRoomDirectorySearch)
|
actionsSubject.send(.presentRoomDirectorySearch)
|
||||||
|
case .logoutWithoutConfirmation:
|
||||||
|
actionsSubject.send(.logoutWithoutConfirmation)
|
||||||
|
case .logout:
|
||||||
|
actionsSubject.send(.logout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ enum HomeScreenViewModelAction {
|
|||||||
case presentStartChatScreen
|
case presentStartChatScreen
|
||||||
case presentGlobalSearch
|
case presentGlobalSearch
|
||||||
case presentRoomDirectorySearch
|
case presentRoomDirectorySearch
|
||||||
|
case logoutWithoutConfirmation
|
||||||
case logout
|
case logout
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,6 +32,8 @@ enum HomeScreenViewAction {
|
|||||||
case startChat
|
case startChat
|
||||||
case confirmRecoveryKey
|
case confirmRecoveryKey
|
||||||
case skipRecoveryKeyConfirmation
|
case skipRecoveryKeyConfirmation
|
||||||
|
case confirmSlidingSyncUpgrade
|
||||||
|
case skipSlidingSyncUpgrade
|
||||||
case updateVisibleItemRange(Range<Int>)
|
case updateVisibleItemRange(Range<Int>)
|
||||||
case globalSearch
|
case globalSearch
|
||||||
case markRoomAsUnread(roomIdentifier: String)
|
case markRoomAsUnread(roomIdentifier: String)
|
||||||
@@ -59,10 +62,10 @@ enum HomeScreenRoomListMode: CustomStringConvertible {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SecurityBannerMode {
|
enum HomeScreenBannerMode {
|
||||||
case none
|
case none
|
||||||
case dismissed
|
case dismissed
|
||||||
case recoveryKeyConfirmation
|
case show
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HomeScreenViewState: BindableState {
|
struct HomeScreenViewState: BindableState {
|
||||||
@@ -70,7 +73,9 @@ struct HomeScreenViewState: BindableState {
|
|||||||
var userDisplayName: String?
|
var userDisplayName: String?
|
||||||
var userAvatarURL: URL?
|
var userAvatarURL: URL?
|
||||||
|
|
||||||
var securityBannerMode = SecurityBannerMode.none
|
var securityBannerMode = HomeScreenBannerMode.none
|
||||||
|
var slidingSyncMigrationBannerMode = HomeScreenBannerMode.none
|
||||||
|
|
||||||
var requiresExtraAccountSetup = false
|
var requiresExtraAccountSetup = false
|
||||||
|
|
||||||
var rooms: [HomeScreenRoom] = []
|
var rooms: [HomeScreenRoom] = []
|
||||||
@@ -110,10 +115,6 @@ struct HomeScreenViewState: BindableState {
|
|||||||
var shouldShowFilters: Bool {
|
var shouldShowFilters: Bool {
|
||||||
!bindings.isSearchFieldFocused && roomListMode == .rooms
|
!bindings.isSearchFieldFocused && roomListMode == .rooms
|
||||||
}
|
}
|
||||||
|
|
||||||
var shouldShowRecoveryKeyConfirmationBanner: Bool {
|
|
||||||
securityBannerMode == .recoveryKeyConfirmation
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HomeScreenViewStateBindings {
|
struct HomeScreenViewStateBindings {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
import AnalyticsEvents
|
import AnalyticsEvents
|
||||||
import Combine
|
import Combine
|
||||||
|
import MatrixRustSDK
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
typealias HomeScreenViewModelType = StateStoreViewModel<HomeScreenViewState, HomeScreenViewAction>
|
typealias HomeScreenViewModelType = StateStoreViewModel<HomeScreenViewState, HomeScreenViewAction>
|
||||||
@@ -62,7 +63,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
state.requiresExtraAccountSetup = true
|
state.requiresExtraAccountSetup = true
|
||||||
|
|
||||||
if state.securityBannerMode != .dismissed {
|
if state.securityBannerMode != .dismissed {
|
||||||
state.securityBannerMode = .recoveryKeyConfirmation
|
state.securityBannerMode = .show
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
state.securityBannerMode = .none
|
state.securityBannerMode = .none
|
||||||
@@ -117,6 +118,10 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
setupRoomListSubscriptions()
|
setupRoomListSubscriptions()
|
||||||
|
|
||||||
updateRooms()
|
updateRooms()
|
||||||
|
|
||||||
|
Task {
|
||||||
|
await checkSlidingSyncMigration()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
@@ -137,6 +142,10 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
actionsSubject.send(.presentSecureBackupSettings)
|
actionsSubject.send(.presentSecureBackupSettings)
|
||||||
case .skipRecoveryKeyConfirmation:
|
case .skipRecoveryKeyConfirmation:
|
||||||
state.securityBannerMode = .dismissed
|
state.securityBannerMode = .dismissed
|
||||||
|
case .confirmSlidingSyncUpgrade:
|
||||||
|
actionsSubject.send(.logout)
|
||||||
|
case .skipSlidingSyncUpgrade:
|
||||||
|
state.slidingSyncMigrationBannerMode = .dismissed
|
||||||
case .updateVisibleItemRange(let range):
|
case .updateVisibleItemRange(let range):
|
||||||
roomSummaryProvider?.updateVisibleRange(range)
|
roomSummaryProvider?.updateVisibleRange(range)
|
||||||
case .startChat:
|
case .startChat:
|
||||||
@@ -192,12 +201,15 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
|
|
||||||
// perphery: ignore - used in release mode
|
// perphery: ignore - used in release mode
|
||||||
func presentCrashedLastRunAlert() {
|
func presentCrashedLastRunAlert() {
|
||||||
state.bindings.alertInfo = AlertInfo(id: UUID(),
|
// Delay setting the alert otherwise it automatically gets dismissed. Same as the force logout one.
|
||||||
title: L10n.crashDetectionDialogContent(InfoPlistReader.main.bundleDisplayName),
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
primaryButton: .init(title: L10n.actionNo, action: nil),
|
self.state.bindings.alertInfo = AlertInfo(id: UUID(),
|
||||||
secondaryButton: .init(title: L10n.actionYes) { [weak self] in
|
title: L10n.crashDetectionDialogContent(InfoPlistReader.main.bundleDisplayName),
|
||||||
self?.actionsSubject.send(.presentFeedbackScreen)
|
primaryButton: .init(title: L10n.actionNo, action: nil),
|
||||||
})
|
secondaryButton: .init(title: L10n.actionYes) { [weak self] in
|
||||||
|
self?.actionsSubject.send(.presentFeedbackScreen)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
@@ -287,7 +299,40 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
|
|
||||||
state.rooms = rooms
|
state.rooms = rooms
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether we can inform the user about potential migrations
|
||||||
|
/// or have him logout as his proxy is no longer available
|
||||||
|
private func checkSlidingSyncMigration() async {
|
||||||
|
// Not logged in with a proxy, don't need to do anything
|
||||||
|
guard userSession.clientProxy.slidingSyncVersion.isProxy else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let versions = await userSession.clientProxy.availableSlidingSyncVersions
|
||||||
|
|
||||||
|
// Native not available, nothing we can do
|
||||||
|
guard versions.contains(.native) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if versions.contains(.native) {
|
||||||
|
// Both available, prompt for migration
|
||||||
|
if versions.contains(where: \.isProxy) {
|
||||||
|
state.slidingSyncMigrationBannerMode = .show
|
||||||
|
} else { // The proxy has been removed and logout is needed
|
||||||
|
// Delay setting the alert otherwise it automatically gets dismissed. Same as the crashed last run one
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
|
self.state.bindings.alertInfo = AlertInfo(id: UUID(),
|
||||||
|
title: L10n.bannerMigrateToNativeSlidingSyncForceLogoutTitle,
|
||||||
|
primaryButton: .init(title: L10n.bannerMigrateToNativeSlidingSyncAction,
|
||||||
|
action: { [weak self] in
|
||||||
|
self?.actionsSubject.send(.logoutWithoutConfirmation)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func markRoomAsFavourite(_ roomID: String, isFavourite: Bool) async {
|
private func markRoomAsFavourite(_ roomID: String, isFavourite: Bool) async {
|
||||||
guard case let .joined(roomProxy) = await userSession.clientProxy.roomForIdentifier(roomID) else {
|
guard case let .joined(roomProxy) = await userSession.clientProxy.roomForIdentifier(roomID) else {
|
||||||
MXLog.error("Failed retrieving room for identifier: \(roomID)")
|
MXLog.error("Failed retrieving room for identifier: \(roomID)")
|
||||||
@@ -412,3 +457,14 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
message: L10n.errorUnknown)
|
message: L10n.errorUnknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension SlidingSyncVersion {
|
||||||
|
var isProxy: Bool {
|
||||||
|
switch self {
|
||||||
|
case .proxy:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -120,13 +120,16 @@ struct HomeScreenContent: View {
|
|||||||
private var topSection: some View {
|
private var topSection: some View {
|
||||||
// An empty VStack causes glitches within the room list
|
// An empty VStack causes glitches within the room list
|
||||||
if context.viewState.shouldShowFilters ||
|
if context.viewState.shouldShowFilters ||
|
||||||
context.viewState.shouldShowRecoveryKeyConfirmationBanner {
|
context.viewState.securityBannerMode == .show ||
|
||||||
|
context.viewState.slidingSyncMigrationBannerMode == .show {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
if context.viewState.shouldShowFilters {
|
if context.viewState.shouldShowFilters {
|
||||||
RoomListFiltersView(state: $context.filtersState)
|
RoomListFiltersView(state: $context.filtersState)
|
||||||
}
|
}
|
||||||
|
|
||||||
if context.viewState.shouldShowRecoveryKeyConfirmationBanner {
|
if context.viewState.slidingSyncMigrationBannerMode == .show {
|
||||||
|
HomeScreenSlidingSyncMigrationBanner(context: context)
|
||||||
|
} else if context.viewState.securityBannerMode == .show {
|
||||||
HomeScreenRecoveryKeyConfirmationBanner(context: context)
|
HomeScreenRecoveryKeyConfirmationBanner(context: context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ import Combine
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct HomeScreenRecoveryKeyConfirmationBanner: View {
|
struct HomeScreenRecoveryKeyConfirmationBanner: View {
|
||||||
@ObservedObject var context: HomeScreenViewModel.Context
|
var context: HomeScreenViewModel.Context
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 16) {
|
VStack(alignment: .leading, spacing: 16) {
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2024 New Vector Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
// Please see LICENSE in the repository root for full details.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct HomeScreenSlidingSyncMigrationBanner: View {
|
||||||
|
var context: HomeScreenViewModel.Context
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(alignment: .leading, spacing: 16) {
|
||||||
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
|
HStack(spacing: 16) {
|
||||||
|
Text(L10n.bannerMigrateToNativeSlidingSyncTitle)
|
||||||
|
.font(.compound.bodyLGSemibold)
|
||||||
|
.foregroundColor(.compound.textPrimary)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Button {
|
||||||
|
context.send(viewAction: .skipSlidingSyncUpgrade)
|
||||||
|
} label: {
|
||||||
|
Image(systemName: "xmark")
|
||||||
|
.foregroundColor(.compound.iconSecondary)
|
||||||
|
.frame(width: 12, height: 12)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text(L10n.bannerMigrateToNativeSlidingSyncDescription)
|
||||||
|
.font(.compound.bodyMD)
|
||||||
|
.foregroundColor(.compound.textSecondary)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(L10n.bannerMigrateToNativeSlidingSyncAction) {
|
||||||
|
context.send(viewAction: .confirmSlidingSyncUpgrade)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.buttonStyle(.compound(.primary, size: .medium))
|
||||||
|
}
|
||||||
|
.padding(16)
|
||||||
|
.background(Color.compound.bgSubtleSecondary)
|
||||||
|
.cornerRadius(14)
|
||||||
|
.padding(.horizontal, 16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HomeScreenSlidingSyncMigrationBanner_Previews: PreviewProvider, TestablePreview {
|
||||||
|
static let viewModel = buildViewModel()
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
HomeScreenSlidingSyncMigrationBanner(context: viewModel.context)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func buildViewModel() -> HomeScreenViewModel {
|
||||||
|
let clientProxy = ClientProxyMock(.init())
|
||||||
|
|
||||||
|
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||||
|
|
||||||
|
return HomeScreenViewModel(userSession: userSession,
|
||||||
|
analyticsService: ServiceLocator.shared.analytics,
|
||||||
|
appSettings: ServiceLocator.shared.settings,
|
||||||
|
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||||
|
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -267,6 +267,12 @@ class PreviewTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_homeScreenSlidingSyncMigrationBanner() {
|
||||||
|
for preview in HomeScreenSlidingSyncMigrationBanner_Previews._allPreviews {
|
||||||
|
assertSnapshots(matching: preview)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func test_homeScreen() {
|
func test_homeScreen() {
|
||||||
for preview in HomeScreen_Previews._allPreviews {
|
for preview in HomeScreen_Previews._allPreviews {
|
||||||
assertSnapshots(matching: preview)
|
assertSnapshots(matching: preview)
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:ed37c148a5a16aea018c2592948c53c4b3029f3fc6b7d618aa212192e7bc42e5
|
||||||
|
size 108471
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:18cce2502021c0927c3abbc975a24134257f23963a9197c7e6746d9745d34beb
|
||||||
|
size 130832
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:2b83edbd6f90916ebf6c5b6276676633d4f1bcf08750ee19a833ded4354981ba
|
||||||
|
size 70577
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:8bbfc3fdccf911c6737194ba02ccbd4cabd0a5d152ed572261c1dab23cfbf803
|
||||||
|
size 105804
|
||||||
+1
-1
@@ -60,7 +60,7 @@ packages:
|
|||||||
# Element/Matrix dependencies
|
# Element/Matrix dependencies
|
||||||
MatrixRustSDK:
|
MatrixRustSDK:
|
||||||
url: https://github.com/element-hq/matrix-rust-components-swift
|
url: https://github.com/element-hq/matrix-rust-components-swift
|
||||||
exactVersion: 1.0.45
|
exactVersion: 1.0.46
|
||||||
# path: ../matrix-rust-sdk
|
# path: ../matrix-rust-sdk
|
||||||
Compound:
|
Compound:
|
||||||
url: https://github.com/element-hq/compound-ios
|
url: https://github.com/element-hq/compound-ios
|
||||||
|
|||||||
Reference in New Issue
Block a user