mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:02:10 +00:00
@@ -48,23 +48,25 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
switch action {
|
||||
case .close:
|
||||
self.callback?(.dismiss)
|
||||
case .account:
|
||||
self.presentAccountSettings()
|
||||
callback?(.dismiss)
|
||||
case .accountProfile:
|
||||
presentAccountProfileURL()
|
||||
case .analytics:
|
||||
self.presentAnalyticsScreen()
|
||||
presentAnalyticsScreen()
|
||||
case .reportBug:
|
||||
self.presentBugReportScreen()
|
||||
presentBugReportScreen()
|
||||
case .about:
|
||||
self.presentLegalInformationScreen()
|
||||
presentLegalInformationScreen()
|
||||
case .sessionVerification:
|
||||
self.verifySession()
|
||||
verifySession()
|
||||
case .accountSessionsList:
|
||||
presentAccountSessionsListURL()
|
||||
case .developerOptions:
|
||||
self.presentDeveloperOptions()
|
||||
presentDeveloperOptions()
|
||||
case .logout:
|
||||
self.callback?(.logout)
|
||||
callback?(.logout)
|
||||
case .notifications:
|
||||
self.presentNotificationSettings()
|
||||
presentNotificationSettings()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,15 +77,26 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
||||
AnyView(SettingsScreen(context: viewModel.context))
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
// MARK: - OIDC Account Management
|
||||
|
||||
private var accountSettingsPresenter: OIDCAccountSettingsPresenter?
|
||||
private func presentAccountSettings() {
|
||||
guard let accountURL = viewModel.context.viewState.accountURL else {
|
||||
private func presentAccountProfileURL() {
|
||||
guard let url = viewModel.context.viewState.accountProfileURL else {
|
||||
MXLog.error("Account URL is missing.")
|
||||
return
|
||||
}
|
||||
|
||||
presentAccountManagementURL(url)
|
||||
}
|
||||
|
||||
private func presentAccountSessionsListURL() {
|
||||
guard let url = viewModel.context.viewState.accountSessionsListURL else {
|
||||
MXLog.error("Account URL is missing.")
|
||||
return
|
||||
}
|
||||
presentAccountManagementURL(url)
|
||||
}
|
||||
|
||||
private var accountSettingsPresenter: OIDCAccountSettingsPresenter?
|
||||
private func presentAccountManagementURL(_ url: URL) {
|
||||
guard let window = viewModel.context.viewState.window else {
|
||||
MXLog.error("The window is missing.")
|
||||
return
|
||||
@@ -91,10 +104,12 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
// Note to anyone in the future if you come back here to make this open in Safari instead of a WAS.
|
||||
// As of iOS 16, there is an issue on the simulator with accessing the cookie but it works on a device. 🤷♂️
|
||||
accountSettingsPresenter = OIDCAccountSettingsPresenter(accountURL: accountURL, presentationAnchor: window)
|
||||
accountSettingsPresenter = OIDCAccountSettingsPresenter(accountURL: url, presentationAnchor: window)
|
||||
accountSettingsPresenter?.start()
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func presentAnalyticsScreen() {
|
||||
let coordinator = AnalyticsSettingsScreenCoordinator(parameters: .init(appSettings: ServiceLocator.shared.settings,
|
||||
analytics: ServiceLocator.shared.analytics))
|
||||
|
||||
@@ -19,11 +19,12 @@ import UIKit
|
||||
|
||||
enum SettingsScreenViewModelAction {
|
||||
case close
|
||||
case account
|
||||
case accountProfile
|
||||
case analytics
|
||||
case reportBug
|
||||
case about
|
||||
case sessionVerification
|
||||
case accountSessionsList
|
||||
case developerOptions
|
||||
case notifications
|
||||
case logout
|
||||
@@ -33,7 +34,8 @@ struct SettingsScreenViewState: BindableState {
|
||||
var bindings: SettingsScreenViewStateBindings
|
||||
var deviceID: String?
|
||||
var userID: String
|
||||
var accountURL: URL?
|
||||
var accountProfileURL: URL?
|
||||
var accountSessionsListURL: URL?
|
||||
var userAvatarURL: URL?
|
||||
var userDisplayName: String?
|
||||
var showSessionVerificationSection: Bool
|
||||
@@ -49,13 +51,14 @@ struct SettingsScreenViewStateBindings {
|
||||
|
||||
enum SettingsScreenViewAction {
|
||||
case close
|
||||
case account
|
||||
case accountProfile
|
||||
case analytics
|
||||
case reportBug
|
||||
case about
|
||||
case sessionVerification
|
||||
case logout
|
||||
case changedTimelineStyle
|
||||
case accountSessionsList
|
||||
case developerOptions
|
||||
case notifications
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
|
||||
super.init(initialViewState: .init(bindings: bindings,
|
||||
deviceID: userSession.deviceID,
|
||||
userID: userSession.userID,
|
||||
accountURL: userSession.clientProxy.accountURL,
|
||||
accountProfileURL: userSession.clientProxy.accountURL(action: .profile),
|
||||
accountSessionsListURL: userSession.clientProxy.accountURL(action: .sessionsList),
|
||||
showSessionVerificationSection: showSessionVerificationSection,
|
||||
showDeveloperOptions: appSettings.canShowDeveloperOptions),
|
||||
imageProvider: userSession.mediaProvider)
|
||||
@@ -81,8 +82,8 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
|
||||
switch viewAction {
|
||||
case .close:
|
||||
callback?(.close)
|
||||
case .account:
|
||||
callback?(.account)
|
||||
case .accountProfile:
|
||||
callback?(.accountProfile)
|
||||
case .analytics:
|
||||
callback?(.analytics)
|
||||
case .reportBug:
|
||||
@@ -97,6 +98,8 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
|
||||
appSettings.timelineStyle = state.bindings.timelineStyle
|
||||
case .notifications:
|
||||
callback?(.notifications)
|
||||
case .accountSessionsList:
|
||||
callback?(.accountSessionsList)
|
||||
case .developerOptions:
|
||||
callback?(.developerOptions)
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
//
|
||||
|
||||
import Compound
|
||||
import SFSafeSymbols
|
||||
import SwiftUI
|
||||
|
||||
struct SettingsScreen: View {
|
||||
@@ -30,7 +31,11 @@ struct SettingsScreen: View {
|
||||
sessionVerificationSection
|
||||
}
|
||||
|
||||
simplifiedSection
|
||||
mainSection
|
||||
|
||||
if context.viewState.accountSessionsListURL != nil {
|
||||
manageSessionsSection
|
||||
}
|
||||
|
||||
if context.viewState.showDeveloperOptions {
|
||||
developerOptionsSection
|
||||
@@ -41,20 +46,12 @@ struct SettingsScreen: View {
|
||||
.compoundList()
|
||||
.navigationTitle(L10n.commonSettings)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .confirmationAction) {
|
||||
doneButton
|
||||
}
|
||||
}
|
||||
.toolbar { toolbar }
|
||||
.introspect(.window, on: .iOS(.v16, .v17)) { window in
|
||||
context.send(viewAction: .updateWindow(window))
|
||||
}
|
||||
}
|
||||
|
||||
private var versionText: Text {
|
||||
Text(L10n.settingsVersionNumber(InfoPlistReader.main.bundleShortVersionString, InfoPlistReader.main.bundleVersion))
|
||||
}
|
||||
|
||||
private var userSection: some View {
|
||||
Section {
|
||||
ListRow(kind: .custom {
|
||||
@@ -90,25 +87,13 @@ struct SettingsScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
private var developerOptionsSection: some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.commonDeveloperOptions,
|
||||
systemIcon: .hammerCircle),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .developerOptions)
|
||||
})
|
||||
.accessibilityIdentifier(A11yIdentifiers.settingsScreen.developerOptions)
|
||||
}
|
||||
}
|
||||
|
||||
private var simplifiedSection: some View {
|
||||
private var mainSection: some View {
|
||||
Section {
|
||||
// Account
|
||||
if context.viewState.accountURL != nil {
|
||||
ListRow(label: .default(title: L10n.screenSettingsOidcAccount,
|
||||
systemIcon: .person),
|
||||
if context.viewState.accountProfileURL != nil {
|
||||
ListRow(label: .default(title: L10n.actionManageAccount, systemIcon: .person),
|
||||
kind: .button {
|
||||
context.send(viewAction: .account)
|
||||
context.send(viewAction: .accountProfile)
|
||||
})
|
||||
.accessibilityIdentifier(A11yIdentifiers.settingsScreen.account)
|
||||
}
|
||||
@@ -157,6 +142,36 @@ struct SettingsScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
private var manageSessionsSection: some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.actionManageDevices, systemIcon: deviceIcon),
|
||||
kind: .button {
|
||||
context.send(viewAction: .accountSessionsList)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private var deviceIcon: SFSymbol {
|
||||
if ProcessInfo.processInfo.isiOSAppOnMac {
|
||||
return .macbookAndIphone
|
||||
} else if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
return .ipad
|
||||
} else {
|
||||
return .iphone
|
||||
}
|
||||
}
|
||||
|
||||
private var developerOptionsSection: some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.commonDeveloperOptions,
|
||||
systemIcon: .hammerCircle),
|
||||
kind: .navigationLink {
|
||||
context.send(viewAction: .developerOptions)
|
||||
})
|
||||
.accessibilityIdentifier(A11yIdentifiers.settingsScreen.developerOptions)
|
||||
}
|
||||
}
|
||||
|
||||
private var signOutSection: some View {
|
||||
Section {
|
||||
ListRow(label: .default(title: L10n.screenSignoutPreferenceItem,
|
||||
@@ -166,9 +181,9 @@ struct SettingsScreen: View {
|
||||
})
|
||||
.accessibilityIdentifier(A11yIdentifiers.settingsScreen.logout)
|
||||
.alert(L10n.screenSignoutConfirmationDialogTitle, isPresented: $showingLogoutConfirmation) {
|
||||
Button(L10n.screenSignoutConfirmationDialogSubmit,
|
||||
role: .destructive,
|
||||
action: logout)
|
||||
Button(L10n.screenSignoutConfirmationDialogSubmit, role: .destructive) {
|
||||
context.send(viewAction: .logout)
|
||||
}
|
||||
} message: {
|
||||
Text(L10n.screenSignoutConfirmationDialogContent)
|
||||
}
|
||||
@@ -186,18 +201,16 @@ struct SettingsScreen: View {
|
||||
.padding(.top, 24)
|
||||
}
|
||||
}
|
||||
|
||||
private var doneButton: some View {
|
||||
Button(L10n.actionDone, action: close)
|
||||
.accessibilityIdentifier(A11yIdentifiers.settingsScreen.done)
|
||||
|
||||
private var versionText: Text {
|
||||
Text(L10n.settingsVersionNumber(InfoPlistReader.main.bundleShortVersionString, InfoPlistReader.main.bundleVersion))
|
||||
}
|
||||
|
||||
private func close() {
|
||||
context.send(viewAction: .close)
|
||||
}
|
||||
|
||||
private func logout() {
|
||||
context.send(viewAction: .logout)
|
||||
|
||||
private var toolbar: some ToolbarContent {
|
||||
ToolbarItem(placement: .confirmationAction) {
|
||||
Button(L10n.actionDone) { context.send(viewAction: .close) }
|
||||
.accessibilityIdentifier(A11yIdentifiers.settingsScreen.done)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,8 +233,7 @@ struct SettingsScreen_Previews: PreviewProvider {
|
||||
verificationController.isVerified = false
|
||||
let userSession = MockUserSession(sessionVerificationController: verificationController,
|
||||
clientProxy: MockClientProxy(userID: "@userid:example.com",
|
||||
deviceID: "AAAAAAAAAAA",
|
||||
accountURL: "https://matrix.org/account"),
|
||||
deviceID: "AAAAAAAAAAA"),
|
||||
mediaProvider: MockMediaProvider())
|
||||
return SettingsScreenViewModel(userSession: userSession,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
Reference in New Issue
Block a user