mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Add a view to show the user's account from Element Classic. (#5361)
No presentation logic yet.
This commit is contained in:
+12
@@ -14,9 +14,20 @@ struct AuthenticationStartScreenParameters {
|
||||
let provisioningParameters: AccountProvisioningParameters?
|
||||
let isBugReportServiceEnabled: Bool
|
||||
let appSettings: AppSettings
|
||||
let mediaProvider: MediaProviderProtocol?
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
}
|
||||
|
||||
enum AuthenticationStartScreenCoordinatorAction {
|
||||
case loginWithQR
|
||||
case login
|
||||
case register
|
||||
case reportProblem
|
||||
|
||||
case loginDirectlyWithOIDC(data: OIDCAuthorizationDataProxy, window: UIWindow)
|
||||
case loginDirectlyWithPassword(loginHint: String?)
|
||||
}
|
||||
|
||||
final class AuthenticationStartScreenCoordinator: CoordinatorProtocol {
|
||||
private var viewModel: AuthenticationStartScreenViewModelProtocol
|
||||
private let actionsSubject: PassthroughSubject<AuthenticationStartScreenCoordinatorAction, Never> = .init()
|
||||
@@ -31,6 +42,7 @@ final class AuthenticationStartScreenCoordinator: CoordinatorProtocol {
|
||||
provisioningParameters: parameters.provisioningParameters,
|
||||
isBugReportServiceEnabled: parameters.isBugReportServiceEnabled,
|
||||
appSettings: parameters.appSettings,
|
||||
mediaProvider: parameters.mediaProvider,
|
||||
userIndicatorController: parameters.userIndicatorController)
|
||||
}
|
||||
|
||||
|
||||
+4
-12
@@ -8,18 +8,6 @@
|
||||
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - Coordinator
|
||||
|
||||
enum AuthenticationStartScreenCoordinatorAction {
|
||||
case loginWithQR
|
||||
case login
|
||||
case register
|
||||
case reportProblem
|
||||
|
||||
case loginDirectlyWithOIDC(data: OIDCAuthorizationDataProxy, window: UIWindow)
|
||||
case loginDirectlyWithPassword(loginHint: String?)
|
||||
}
|
||||
|
||||
enum AuthenticationStartScreenViewModelAction: Equatable {
|
||||
case loginWithQR
|
||||
case login
|
||||
@@ -70,4 +58,8 @@ enum AuthenticationStartScreenViewAction {
|
||||
case login
|
||||
case register
|
||||
case reportProblem
|
||||
|
||||
case continueWithClassic(ClassicAppAccount)
|
||||
case otherOptions(ClassicAppAccount)
|
||||
case closeOtherOptions(ClassicAppAccount)
|
||||
}
|
||||
|
||||
+6
-3
@@ -24,11 +24,12 @@ class AuthenticationStartScreenViewModel: AuthenticationStartScreenViewModelType
|
||||
var actions: AnyPublisher<AuthenticationStartScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
|
||||
init(authenticationService: AuthenticationServiceProtocol,
|
||||
provisioningParameters: AccountProvisioningParameters?,
|
||||
isBugReportServiceEnabled: Bool,
|
||||
appSettings: AppSettings,
|
||||
mediaProvider: MediaProviderProtocol?,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.authenticationService = authenticationService
|
||||
self.provisioningParameters = provisioningParameters
|
||||
@@ -59,9 +60,9 @@ class AuthenticationStartScreenViewModel: AuthenticationStartScreenViewModelType
|
||||
hideBrandChrome: appSettings.hideBrandChrome)
|
||||
}
|
||||
|
||||
super.init(initialViewState: initialViewState)
|
||||
super.init(initialViewState: initialViewState, mediaProvider: mediaProvider)
|
||||
}
|
||||
|
||||
|
||||
override func process(viewAction: AuthenticationStartScreenViewAction) {
|
||||
switch viewAction {
|
||||
case .updateWindow(let window):
|
||||
@@ -77,6 +78,8 @@ class AuthenticationStartScreenViewModel: AuthenticationStartScreenViewModelType
|
||||
if canReportProblem {
|
||||
actionsSubject.send(.reportProblem)
|
||||
}
|
||||
case .continueWithClassic, .otherOptions, .closeOtherOptions:
|
||||
break // To follow.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// Copyright 2025 Element Creations 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 AuthenticationClassicAppAccountView: View {
|
||||
@Bindable var context: AuthenticationStartScreenViewModel.Context
|
||||
|
||||
let classicAppAccount: ClassicAppAccount
|
||||
|
||||
var body: some View {
|
||||
FullscreenDialog(topPadding: 25, background: .gradient) {
|
||||
VStack(spacing: 38) {
|
||||
header
|
||||
.padding(.bottom, 20)
|
||||
|
||||
profile
|
||||
|
||||
buttons
|
||||
}
|
||||
} bottomContent: {
|
||||
// Buttons are intentionally shown inline on this screen.
|
||||
}
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.alert(item: $context.alertInfo)
|
||||
.introspect(.window, on: .supportedVersions) { window in
|
||||
context.send(viewAction: .updateWindow(window))
|
||||
}
|
||||
}
|
||||
|
||||
var header: some View {
|
||||
VStack(spacing: 8) {
|
||||
AuthenticationStartLogo(size: 54, hideBrandChrome: false, isOnGradient: false)
|
||||
|
||||
Text(L10n.screenOnboardingWelcomeTitle)
|
||||
.font(.compound.headingMDBold)
|
||||
.foregroundStyle(.compound.textPrimary)
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
}
|
||||
|
||||
var profile: some View {
|
||||
VStack(spacing: 16) {
|
||||
LoadableAvatarImage(url: classicAppAccount.avatarURL,
|
||||
name: classicAppAccount.displayName,
|
||||
contentID: classicAppAccount.userID,
|
||||
avatarSize: .user(on: .classicAppAccount),
|
||||
mediaProvider: context.mediaProvider)
|
||||
|
||||
VStack(spacing: 0) {
|
||||
Text(L10n.screenOnboardingWelcomeBack)
|
||||
.font(.compound.bodyMD)
|
||||
.foregroundStyle(.compound.textSecondary)
|
||||
.multilineTextAlignment(.center)
|
||||
|
||||
Text(classicAppAccount.displayableName)
|
||||
.font(.compound.headingLGBold)
|
||||
.foregroundStyle(.compound.textPrimary)
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
|
||||
Text(classicAppAccount.userID)
|
||||
.font(.compound.bodyLGSemibold)
|
||||
.foregroundStyle(.compound.textPrimary)
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
}
|
||||
|
||||
var buttons: some View {
|
||||
VStack(spacing: 16) {
|
||||
Button(L10n.actionContinue) {
|
||||
context.send(viewAction: .continueWithClassic(classicAppAccount))
|
||||
}
|
||||
.buttonStyle(.compound(.primary))
|
||||
|
||||
Button(L10n.commonOtherOptions) {
|
||||
context.send(viewAction: .otherOptions(classicAppAccount))
|
||||
}
|
||||
.buttonStyle(.compound(.secondary))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension ClassicAppAccount {
|
||||
var displayableName: String {
|
||||
if let displayName, !displayName.isEmpty {
|
||||
displayName
|
||||
} else if let localPart = userID.dropFirst().split(separator: ":").first, !localPart.isEmpty {
|
||||
String(localPart)
|
||||
} else {
|
||||
userID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct AuthenticationClassicAppAccountView_Previews: PreviewProvider { // Not Testable – snapshots generated by main screen.
|
||||
static let viewModel = makeViewModel()
|
||||
|
||||
static var previews: some View {
|
||||
ElementNavigationStack {
|
||||
AuthenticationClassicAppAccountView(context: viewModel.context, classicAppAccount: .mockDan)
|
||||
}
|
||||
}
|
||||
|
||||
static func makeViewModel() -> AuthenticationStartScreenViewModel {
|
||||
AuthenticationStartScreenViewModel(authenticationService: AuthenticationService.mock,
|
||||
provisioningParameters: nil,
|
||||
isBugReportServiceEnabled: false,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
}
|
||||
}
|
||||
+1
@@ -69,6 +69,7 @@ struct AuthenticationClassicAppBackupInstructionsView_Previews: PreviewProvider,
|
||||
provisioningParameters: nil,
|
||||
isBugReportServiceEnabled: false,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -152,6 +152,7 @@ struct AuthenticationStartScreen_Previews: PreviewProvider, TestablePreview {
|
||||
provisioningParameters: provisionedServerName.map { .init(accountProvider: $0, loginHint: nil) },
|
||||
isBugReportServiceEnabled: true,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user