mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 10:33:45 +00:00
Add the spaces feature announcement sheet. (#4571)
This commit is contained in:
@@ -615,6 +615,10 @@ extension AccessibilityTests {
|
|||||||
try await performAccessibilityAudit(named: "SpaceScreen_Previews")
|
try await performAccessibilityAudit(named: "SpaceScreen_Previews")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testSpacesAnnouncementSheetView() async throws {
|
||||||
|
try await performAccessibilityAudit(named: "SpacesAnnouncementSheetView_Previews")
|
||||||
|
}
|
||||||
|
|
||||||
func testSplashScreen() async throws {
|
func testSplashScreen() async throws {
|
||||||
try await performAccessibilityAudit(named: "SplashScreen_Previews")
|
try await performAccessibilityAudit(named: "SplashScreen_Previews")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -881,6 +881,7 @@
|
|||||||
9D2E03DB175A6AB14589076D /* AnalyticsEvents in Frameworks */ = {isa = PBXBuildFile; productRef = 2A3F7BCCB18C15B30CCA39A9 /* AnalyticsEvents */; };
|
9D2E03DB175A6AB14589076D /* AnalyticsEvents in Frameworks */ = {isa = PBXBuildFile; productRef = 2A3F7BCCB18C15B30CCA39A9 /* AnalyticsEvents */; };
|
||||||
9D79B94493FB32249F7E472F /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C705E605EF57C19DBE86FFA1 /* PlaceholderAvatarImage.swift */; };
|
9D79B94493FB32249F7E472F /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C705E605EF57C19DBE86FFA1 /* PlaceholderAvatarImage.swift */; };
|
||||||
9D9690D2FD4CD26FF670620F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C75EF87651B00A176AB08E97 /* AppDelegate.swift */; };
|
9D9690D2FD4CD26FF670620F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C75EF87651B00A176AB08E97 /* AppDelegate.swift */; };
|
||||||
|
9DB4B303ECC05F0F33582594 /* SpacesAnnouncementSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7DA8FFD31B18324CC04A823 /* SpacesAnnouncementSheetView.swift */; };
|
||||||
9DD5AA10E85137140FEA86A3 /* MediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17EFA1D3D09FC2F9C5E1CB2 /* MediaProvider.swift */; };
|
9DD5AA10E85137140FEA86A3 /* MediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17EFA1D3D09FC2F9C5E1CB2 /* MediaProvider.swift */; };
|
||||||
9DD84E014ADFB2DD813022D5 /* RoomDetailsEditScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00E5B2CBEF8F96424F095508 /* RoomDetailsEditScreenViewModelTests.swift */; };
|
9DD84E014ADFB2DD813022D5 /* RoomDetailsEditScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00E5B2CBEF8F96424F095508 /* RoomDetailsEditScreenViewModelTests.swift */; };
|
||||||
9DE801D278AC34737467F937 /* VoiceMessageMediaManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 889DEDD63C68ABDA8AD29812 /* VoiceMessageMediaManagerProtocol.swift */; };
|
9DE801D278AC34737467F937 /* VoiceMessageMediaManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 889DEDD63C68ABDA8AD29812 /* VoiceMessageMediaManagerProtocol.swift */; };
|
||||||
@@ -2712,6 +2713,7 @@
|
|||||||
E7495E1119753B06FF2C2279 /* PhotoLibraryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryManager.swift; sourceTree = "<group>"; };
|
E7495E1119753B06FF2C2279 /* PhotoLibraryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryManager.swift; sourceTree = "<group>"; };
|
||||||
E76A706B3EEA32B882DA5E2D /* BlockedUsersScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
E76A706B3EEA32B882DA5E2D /* BlockedUsersScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
E78FC546F28E045A560F2963 /* EncryptionKeyProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionKeyProviderProtocol.swift; sourceTree = "<group>"; };
|
E78FC546F28E045A560F2963 /* EncryptionKeyProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionKeyProviderProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
E7DA8FFD31B18324CC04A823 /* SpacesAnnouncementSheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpacesAnnouncementSheetView.swift; sourceTree = "<group>"; };
|
||||||
E8294DB9E95C0C0630418466 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
|
E8294DB9E95C0C0630418466 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
E8495F37D6245AD0CFA1F60B /* AppLockTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockTests.swift; sourceTree = "<group>"; };
|
E8495F37D6245AD0CFA1F60B /* AppLockTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockTests.swift; sourceTree = "<group>"; };
|
||||||
E8A1F98AE670377B20679FF5 /* MediaPlayerProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPlayerProvider.swift; sourceTree = "<group>"; };
|
E8A1F98AE670377B20679FF5 /* MediaPlayerProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPlayerProvider.swift; sourceTree = "<group>"; };
|
||||||
@@ -6557,6 +6559,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
F52DA8CCCABA0998C8AA273C /* SpaceListScreen.swift */,
|
F52DA8CCCABA0998C8AA273C /* SpaceListScreen.swift */,
|
||||||
|
E7DA8FFD31B18324CC04A823 /* SpacesAnnouncementSheetView.swift */,
|
||||||
);
|
);
|
||||||
path = View;
|
path = View;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -8311,6 +8314,7 @@
|
|||||||
94C2B531B96493B68B976E5F /* SpaceServiceProxy.swift in Sources */,
|
94C2B531B96493B68B976E5F /* SpaceServiceProxy.swift in Sources */,
|
||||||
A2091F4B1332D9BF273B09D5 /* SpaceServiceProxyMock.swift in Sources */,
|
A2091F4B1332D9BF273B09D5 /* SpaceServiceProxyMock.swift in Sources */,
|
||||||
DB5200B87C4CE9DF0024AC4E /* SpaceServiceProxyProtocol.swift in Sources */,
|
DB5200B87C4CE9DF0024AC4E /* SpaceServiceProxyProtocol.swift in Sources */,
|
||||||
|
9DB4B303ECC05F0F33582594 /* SpacesAnnouncementSheetView.swift in Sources */,
|
||||||
DF004A5B2EABBD0574D06A04 /* SplashScreenCoordinator.swift in Sources */,
|
DF004A5B2EABBD0574D06A04 /* SplashScreenCoordinator.swift in Sources */,
|
||||||
E1C67E5D9E22135A8FEBBD60 /* StackedAvatarsView.swift in Sources */,
|
E1C67E5D9E22135A8FEBBD60 /* StackedAvatarsView.swift in Sources */,
|
||||||
3DAF325D8AE461F7CDB282BD /* StartChatScreen.swift in Sources */,
|
3DAF325D8AE461F7CDB282BD /* StartChatScreen.swift in Sources */,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ final class AppSettings {
|
|||||||
private enum UserDefaultsKeys: String {
|
private enum UserDefaultsKeys: String {
|
||||||
case lastVersionLaunched
|
case lastVersionLaunched
|
||||||
case seenInvites
|
case seenInvites
|
||||||
|
case hasSeenSpacesAnnouncement
|
||||||
case hasSeenNewSoundBanner
|
case hasSeenNewSoundBanner
|
||||||
case appLockNumberOfPINAttempts
|
case appLockNumberOfPINAttempts
|
||||||
case appLockNumberOfBiometricAttempts
|
case appLockNumberOfBiometricAttempts
|
||||||
@@ -162,6 +163,9 @@ final class AppSettings {
|
|||||||
@UserPreference(key: UserDefaultsKeys.seenInvites, defaultValue: [], storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.seenInvites, defaultValue: [], storageType: .userDefaults(store))
|
||||||
var seenInvites: Set<String>
|
var seenInvites: Set<String>
|
||||||
|
|
||||||
|
@UserPreference(key: UserDefaultsKeys.hasSeenSpacesAnnouncement, defaultValue: false, storageType: .userDefaults(store))
|
||||||
|
var hasSeenSpacesAnnouncement
|
||||||
|
|
||||||
/// Defaults to `true` for new users, and we use a migration to set it to `false` for existing users.
|
/// Defaults to `true` for new users, and we use a migration to set it to `false` for existing users.
|
||||||
@UserPreference(key: UserDefaultsKeys.hasSeenNewSoundBanner, defaultValue: true, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.hasSeenNewSoundBanner, defaultValue: true, storageType: .userDefaults(store))
|
||||||
var hasSeenNewSoundBanner
|
var hasSeenNewSoundBanner
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ class SpaceExplorerFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
private func presentSpaceList() {
|
private func presentSpaceList() {
|
||||||
let parameters = SpaceListScreenCoordinatorParameters(userSession: userSession,
|
let parameters = SpaceListScreenCoordinatorParameters(userSession: userSession,
|
||||||
selectedSpacePublisher: selectedSpaceSubject.asCurrentValuePublisher(),
|
selectedSpacePublisher: selectedSpaceSubject.asCurrentValuePublisher(),
|
||||||
|
appSettings: flowParameters.appSettings,
|
||||||
userIndicatorController: flowParameters.userIndicatorController)
|
userIndicatorController: flowParameters.userIndicatorController)
|
||||||
let coordinator = SpaceListScreenCoordinator(parameters: parameters)
|
let coordinator = SpaceListScreenCoordinator(parameters: parameters)
|
||||||
coordinator.actionsPublisher
|
coordinator.actionsPublisher
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ enum TestablePreviewsDictionary {
|
|||||||
"SpaceListScreen_Previews" : SpaceListScreen_Previews.self,
|
"SpaceListScreen_Previews" : SpaceListScreen_Previews.self,
|
||||||
"SpaceRoomCell_Previews" : SpaceRoomCell_Previews.self,
|
"SpaceRoomCell_Previews" : SpaceRoomCell_Previews.self,
|
||||||
"SpaceScreen_Previews" : SpaceScreen_Previews.self,
|
"SpaceScreen_Previews" : SpaceScreen_Previews.self,
|
||||||
|
"SpacesAnnouncementSheetView_Previews" : SpacesAnnouncementSheetView_Previews.self,
|
||||||
"SplashScreen_Previews" : SplashScreen_Previews.self,
|
"SplashScreen_Previews" : SplashScreen_Previews.self,
|
||||||
"StackedAvatarsView_Previews" : StackedAvatarsView_Previews.self,
|
"StackedAvatarsView_Previews" : StackedAvatarsView_Previews.self,
|
||||||
"StartChatScreen_Previews" : StartChatScreen_Previews.self,
|
"StartChatScreen_Previews" : StartChatScreen_Previews.self,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import SwiftUI
|
|||||||
struct SpaceListScreenCoordinatorParameters {
|
struct SpaceListScreenCoordinatorParameters {
|
||||||
let userSession: UserSessionProtocol
|
let userSession: UserSessionProtocol
|
||||||
let selectedSpacePublisher: CurrentValuePublisher<String?, Never>
|
let selectedSpacePublisher: CurrentValuePublisher<String?, Never>
|
||||||
|
let appSettings: AppSettings
|
||||||
let userIndicatorController: UserIndicatorControllerProtocol
|
let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ final class SpaceListScreenCoordinator: CoordinatorProtocol {
|
|||||||
|
|
||||||
viewModel = SpaceListScreenViewModel(userSession: parameters.userSession,
|
viewModel = SpaceListScreenViewModel(userSession: parameters.userSession,
|
||||||
selectedSpacePublisher: parameters.selectedSpacePublisher,
|
selectedSpacePublisher: parameters.selectedSpacePublisher,
|
||||||
|
appSettings: parameters.appSettings,
|
||||||
userIndicatorController: parameters.userIndicatorController)
|
userIndicatorController: parameters.userIndicatorController)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,13 @@ struct SpaceListScreenViewState: BindableState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SpaceListScreenViewStateBindings { }
|
struct SpaceListScreenViewStateBindings {
|
||||||
|
var isPresentingFeatureAnnouncement = false
|
||||||
|
}
|
||||||
|
|
||||||
enum SpaceListScreenViewAction {
|
enum SpaceListScreenViewAction {
|
||||||
case spaceAction(SpaceRoomCell.Action)
|
case spaceAction(SpaceRoomCell.Action)
|
||||||
case showSettings
|
case showSettings
|
||||||
|
case screenAppeared
|
||||||
|
case featureAnnouncementAppeared
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ typealias SpaceListScreenViewModelType = StateStoreViewModelV2<SpaceListScreenVi
|
|||||||
|
|
||||||
class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenViewModelProtocol {
|
class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenViewModelProtocol {
|
||||||
private let spaceServiceProxy: SpaceServiceProxyProtocol
|
private let spaceServiceProxy: SpaceServiceProxyProtocol
|
||||||
|
private let appSettings: AppSettings
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<SpaceListScreenViewModelAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<SpaceListScreenViewModelAction, Never> = .init()
|
||||||
@@ -21,8 +22,10 @@ class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenVie
|
|||||||
|
|
||||||
init(userSession: UserSessionProtocol,
|
init(userSession: UserSessionProtocol,
|
||||||
selectedSpacePublisher: CurrentValuePublisher<String?, Never>,
|
selectedSpacePublisher: CurrentValuePublisher<String?, Never>,
|
||||||
|
appSettings: AppSettings,
|
||||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||||
spaceServiceProxy = userSession.clientProxy.spaceService
|
spaceServiceProxy = userSession.clientProxy.spaceService
|
||||||
|
self.appSettings = appSettings
|
||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
|
|
||||||
super.init(initialViewState: SpaceListScreenViewState(userID: userSession.clientProxy.userID,
|
super.init(initialViewState: SpaceListScreenViewState(userID: userSession.clientProxy.userID,
|
||||||
@@ -62,6 +65,13 @@ class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenVie
|
|||||||
fatalError("There shouldn't be any unjoined spaces in the joined spaces list.")
|
fatalError("There shouldn't be any unjoined spaces in the joined spaces list.")
|
||||||
case .showSettings:
|
case .showSettings:
|
||||||
actionsSubject.send(.showSettings)
|
actionsSubject.send(.showSettings)
|
||||||
|
case .screenAppeared:
|
||||||
|
if !appSettings.hasSeenSpacesAnnouncement {
|
||||||
|
// Use a task otherwise the presentation isn't animated.
|
||||||
|
Task { state.bindings.isPresentingFeatureAnnouncement = true }
|
||||||
|
}
|
||||||
|
case .featureAnnouncementAppeared:
|
||||||
|
appSettings.hasSeenSpacesAnnouncement = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ struct SpaceListScreen: View {
|
|||||||
.toolbar { toolbar }
|
.toolbar { toolbar }
|
||||||
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
.background(Color.compound.bgCanvasDefault.ignoresSafeArea())
|
||||||
.bloom()
|
.bloom()
|
||||||
|
.onAppear { context.send(viewAction: .screenAppeared) }
|
||||||
|
.sheet(isPresented: $context.isPresentingFeatureAnnouncement) {
|
||||||
|
SpacesAnnouncementSheetView(context: context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var header: some View {
|
var header: some View {
|
||||||
@@ -110,6 +114,7 @@ struct SpaceListScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
|
|
||||||
let viewModel = SpaceListScreenViewModel(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
let viewModel = SpaceListScreenViewModel(userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||||
selectedSpacePublisher: .init(nil),
|
selectedSpacePublisher: .init(nil),
|
||||||
|
appSettings: ServiceLocator.shared.settings,
|
||||||
userIndicatorController: UserIndicatorControllerMock())
|
userIndicatorController: UserIndicatorControllerMock())
|
||||||
|
|
||||||
return viewModel
|
return viewModel
|
||||||
|
|||||||
+115
@@ -0,0 +1,115 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2022-2025 New Vector Ltd.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||||
|
// Please see LICENSE files in the repository root for full details.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Compound
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SpacesAnnouncementSheetView: View {
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
|
||||||
|
let context: SpaceListScreenViewModel.Context
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
FullscreenDialog(topPadding: 44, horizontalPadding: 24) {
|
||||||
|
content
|
||||||
|
} bottomContent: {
|
||||||
|
buttons
|
||||||
|
}
|
||||||
|
.background()
|
||||||
|
.backgroundStyle(.compound.bgCanvasDefault)
|
||||||
|
.padding(.top, 14) // For the drag indicator
|
||||||
|
.presentationDragIndicator(.visible)
|
||||||
|
.onAppear { context.send(viewAction: .featureAnnouncementAppeared) }
|
||||||
|
}
|
||||||
|
|
||||||
|
var content: some View {
|
||||||
|
VStack(spacing: 16) {
|
||||||
|
BigIcon(icon: \.spaceSolid, style: .defaultSolid)
|
||||||
|
|
||||||
|
VStack(spacing: 8) {
|
||||||
|
HStack(spacing: 6) {
|
||||||
|
Text(L10n.screenSpaceAnnouncementTitle)
|
||||||
|
.font(.compound.headingMDBold)
|
||||||
|
.foregroundStyle(.compound.textPrimary)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
Text(L10n.commonBeta)
|
||||||
|
.font(.compound.bodyXSSemibold)
|
||||||
|
.foregroundStyle(.compound.textInfoPrimary)
|
||||||
|
.textCase(.uppercase)
|
||||||
|
.padding(.horizontal, 10)
|
||||||
|
.padding(.vertical, 5)
|
||||||
|
.background {
|
||||||
|
RoundedRectangle(cornerRadius: 6)
|
||||||
|
.fill(.compound.bgInfoSubtle)
|
||||||
|
RoundedRectangle(cornerRadius: 6)
|
||||||
|
.stroke(.compound.borderInfoSubtle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text(L10n.screenSpaceAnnouncementSubtitle)
|
||||||
|
.font(.compound.bodyMD)
|
||||||
|
.foregroundStyle(.compound.textSecondary)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
}
|
||||||
|
|
||||||
|
visualListItems
|
||||||
|
|
||||||
|
Text(L10n.screenSpaceAnnouncementNotice)
|
||||||
|
.font(.compound.bodyMD)
|
||||||
|
.foregroundStyle(.compound.textSecondary)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var visualListItems: some View {
|
||||||
|
VStack(spacing: 4) {
|
||||||
|
VisualListItem(title: L10n.screenSpaceAnnouncementItem1, position: .top) {
|
||||||
|
CompoundIcon(\.visibilityOn)
|
||||||
|
.foregroundStyle(.compound.iconSecondary)
|
||||||
|
.alignmentGuide(.top) { _ in 2 }
|
||||||
|
}
|
||||||
|
VisualListItem(title: L10n.screenSpaceAnnouncementItem2, position: .middle) {
|
||||||
|
CompoundIcon(\.email)
|
||||||
|
.foregroundStyle(.compound.iconSecondary)
|
||||||
|
.alignmentGuide(.top) { _ in 2 }
|
||||||
|
}
|
||||||
|
VisualListItem(title: L10n.screenSpaceAnnouncementItem3, position: .middle) {
|
||||||
|
CompoundIcon(\.search)
|
||||||
|
.foregroundStyle(.compound.iconSecondary)
|
||||||
|
.alignmentGuide(.top) { _ in 2 }
|
||||||
|
}
|
||||||
|
// This isn't possible until we enabled the room directory.
|
||||||
|
// VisualListItem(title: L10n.screenSpaceAnnouncementItem4, position: .middle) {
|
||||||
|
// CompoundIcon(\.explore)
|
||||||
|
// .foregroundStyle(.compound.iconSecondary)
|
||||||
|
// .alignmentGuide(.top) { _ in 2 }
|
||||||
|
// }
|
||||||
|
VisualListItem(title: L10n.screenSpaceAnnouncementItem5, position: .bottom) {
|
||||||
|
CompoundIcon(\.leave)
|
||||||
|
.foregroundStyle(.compound.iconSecondary)
|
||||||
|
.alignmentGuide(.top) { _ in 2 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var buttons: some View {
|
||||||
|
Button(L10n.actionContinue, action: dismiss.callAsFunction)
|
||||||
|
.buttonStyle(.compound(.primary))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Previews
|
||||||
|
|
||||||
|
struct SpacesAnnouncementSheetView_Previews: PreviewProvider, TestablePreview {
|
||||||
|
static let viewModel = SpaceListScreenViewModel(userSession: UserSessionMock(.init()),
|
||||||
|
selectedSpacePublisher: .init(nil),
|
||||||
|
appSettings: ServiceLocator.shared.settings,
|
||||||
|
userIndicatorController: UserIndicatorControllerMock())
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
SpacesAnnouncementSheetView(context: viewModel.context)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -585,6 +585,7 @@ class MockScreen: Identifiable {
|
|||||||
appSettings.hasRunNotificationPermissionsOnboarding = true
|
appSettings.hasRunNotificationPermissionsOnboarding = true
|
||||||
appSettings.analyticsConsentState = .optedOut
|
appSettings.analyticsConsentState = .optedOut
|
||||||
appSettings.spacesEnabled = true
|
appSettings.spacesEnabled = true
|
||||||
|
appSettings.hasSeenSpacesAnnouncement = true
|
||||||
|
|
||||||
let clientProxy = ClientProxyMock(.init(userID: "@mock:client.com",
|
let clientProxy = ClientProxyMock(.init(userID: "@mock:client.com",
|
||||||
deviceID: "MOCKCLIENT",
|
deviceID: "MOCKCLIENT",
|
||||||
|
|||||||
@@ -923,6 +923,12 @@ extension PreviewTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testSpacesAnnouncementSheetView() async throws {
|
||||||
|
for (index, preview) in SpacesAnnouncementSheetView_Previews._allPreviews.enumerated() {
|
||||||
|
try await assertSnapshots(matching: preview, step: index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testSplashScreen() async throws {
|
func testSplashScreen() async throws {
|
||||||
for (index, preview) in SplashScreen_Previews._allPreviews.enumerated() {
|
for (index, preview) in SplashScreen_Previews._allPreviews.enumerated() {
|
||||||
try await assertSnapshots(matching: preview, step: index)
|
try await assertSnapshots(matching: preview, step: index)
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:eccd2ad5a68030a787644ec2f4e08f279ba633065101ef28f6db3363a0efd3b0
|
||||||
|
size 146453
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:560872aaa26dfa28023e7f73145ad82959dcd69a0afdc1174465108182d5e3b8
|
||||||
|
size 180990
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:07d585ad557174655a0998f915ce48eb497178482b8493cc7184179f734f9d2a
|
||||||
|
size 96164
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:c7f55a94cf459288c4a34c8b553038be8eb41acf7ad67268eea3ca68a4a5a9a5
|
||||||
|
size 143969
|
||||||
@@ -14,12 +14,22 @@ import XCTest
|
|||||||
class SpaceListScreenViewModelTests: XCTestCase {
|
class SpaceListScreenViewModelTests: XCTestCase {
|
||||||
var joinedSpacesSubject: CurrentValueSubject<[SpaceRoomProxyProtocol], Never>!
|
var joinedSpacesSubject: CurrentValueSubject<[SpaceRoomProxyProtocol], Never>!
|
||||||
var spaceServiceProxy: SpaceServiceProxyMock!
|
var spaceServiceProxy: SpaceServiceProxyMock!
|
||||||
|
var appSettings: AppSettings!
|
||||||
|
|
||||||
var viewModel: SpaceListScreenViewModelProtocol!
|
var viewModel: SpaceListScreenViewModelProtocol!
|
||||||
|
|
||||||
var context: SpaceListScreenViewModelType.Context {
|
var context: SpaceListScreenViewModelType.Context {
|
||||||
viewModel.context
|
viewModel.context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func setUp() {
|
||||||
|
AppSettings.resetAllSettings()
|
||||||
|
appSettings = AppSettings()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() {
|
||||||
|
AppSettings.resetAllSettings()
|
||||||
|
}
|
||||||
|
|
||||||
func testInitialState() {
|
func testInitialState() {
|
||||||
setupViewModel()
|
setupViewModel()
|
||||||
@@ -59,6 +69,27 @@ class SpaceListScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testFeatureAnnouncement() async throws {
|
||||||
|
setupViewModel()
|
||||||
|
XCTAssertFalse(appSettings.hasSeenSpacesAnnouncement)
|
||||||
|
XCTAssertFalse(context.isPresentingFeatureAnnouncement)
|
||||||
|
|
||||||
|
let deferred = deferFulfillment(context.observe(\.isPresentingFeatureAnnouncement)) { $0 == true }
|
||||||
|
viewModel.context.send(viewAction: .screenAppeared)
|
||||||
|
try await deferred.fulfill()
|
||||||
|
XCTAssertTrue(context.isPresentingFeatureAnnouncement)
|
||||||
|
|
||||||
|
viewModel.context.send(viewAction: .featureAnnouncementAppeared)
|
||||||
|
XCTAssertTrue(appSettings.hasSeenSpacesAnnouncement)
|
||||||
|
|
||||||
|
context.isPresentingFeatureAnnouncement = false
|
||||||
|
|
||||||
|
let deferredFailure = deferFailure(context.observe(\.isPresentingFeatureAnnouncement), timeout: 1) { $0 == true }
|
||||||
|
viewModel.context.send(viewAction: .screenAppeared)
|
||||||
|
try await deferredFailure.fulfill()
|
||||||
|
XCTAssertFalse(context.isPresentingFeatureAnnouncement)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Helpers
|
// MARK: - Helpers
|
||||||
|
|
||||||
private func setupViewModel() {
|
private func setupViewModel() {
|
||||||
@@ -80,6 +111,7 @@ class SpaceListScreenViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
viewModel = SpaceListScreenViewModel(userSession: userSession,
|
viewModel = SpaceListScreenViewModel(userSession: userSession,
|
||||||
selectedSpacePublisher: .init(nil),
|
selectedSpacePublisher: .init(nil),
|
||||||
|
appSettings: ServiceLocator.shared.settings,
|
||||||
userIndicatorController: UserIndicatorControllerMock())
|
userIndicatorController: UserIndicatorControllerMock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user