mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
refactor(healthchat): move the session hooks onto UserHooks
This commit is contained in:
@@ -12,12 +12,6 @@ import Synchronization
|
||||
|
||||
final nonisolated class AppHooks: AppHooksProtocol {
|
||||
#if IS_MAIN_APP
|
||||
func configure(with userSession: UserSessionProtocol?) async {
|
||||
await userSessionHook.configure(with: userSession)
|
||||
await extendedProfileSectionHook.configure(with: userSession)
|
||||
await settingsScreenHook.configure(with: userSession)
|
||||
}
|
||||
|
||||
@AppHook(default: DefaultAppSettingsHook())
|
||||
var appSettingsHook: AppSettingsHookProtocol
|
||||
|
||||
@@ -30,38 +24,15 @@ final nonisolated class AppHooks: AppHooksProtocol {
|
||||
@AppHook(default: DefaultOAuthPresenterHook())
|
||||
var oAuthPresenterHook: OAuthPresenterHookProtocol
|
||||
|
||||
@AppHook(default: DefaultUserSessionHook())
|
||||
var userSessionHook: UserSessionHookProtocol
|
||||
|
||||
@AppHook(default: DefaultRoomScreenHook())
|
||||
var roomScreenHook: RoomScreenHookProtocol
|
||||
|
||||
@AppHook(default: DefaultRoomDetailsScreenHook())
|
||||
var roomDetailsScreenHook: RoomDetailsScreenHookProtocol
|
||||
|
||||
@AppHook(default: DefaultRoomMemberDetailsScreenHook())
|
||||
var roomMemberDetailsScreenHook: RoomMemberDetailsScreenHookProtocol
|
||||
|
||||
@AppHook(default: DefaultUserProfileScreenHook())
|
||||
var userProfileScreenHook: UserProfileScreenHookProtocol
|
||||
|
||||
@AppHook(default: DefaultExtendedProfileSectionHook())
|
||||
var extendedProfileSectionHook: ExtendedProfileSectionHookProtocol
|
||||
|
||||
// HealthChat app-level hooks. The session-scoped ones live in `UserHooks`.
|
||||
@AppHook(default: DefaultHomeTabsHook())
|
||||
var homeTabsHook: HomeTabsHookProtocol
|
||||
|
||||
@AppHook(default: DefaultSettingsScreenHook())
|
||||
var settingsScreenHook: SettingsScreenHookProtocol
|
||||
|
||||
@AppHook(default: DefaultUserDetailsEditScreenHook())
|
||||
var userDetailsEditScreenHook: UserDetailsEditScreenHookProtocol
|
||||
|
||||
@AppHook(default: DefaultDeveloperOptionsScreenHook())
|
||||
var developerOptionsScreenHook: DeveloperOptionsScreenHookProtocol
|
||||
|
||||
@AppHook(default: DefaultRecoveryKeyScreenHook())
|
||||
var recoveryKeyScreenHook: RecoveryKeyScreenHookProtocol
|
||||
#endif
|
||||
|
||||
@AppHook(default: DefaultTracingHook())
|
||||
@@ -72,6 +43,9 @@ final nonisolated class AppHooks: AppHooksProtocol {
|
||||
|
||||
@AppHook(default: DefaultRemoteSettingsHook())
|
||||
var remoteSettingsHook: RemoteSettingsHookProtocol
|
||||
|
||||
@AppHook(default: DefaultUserSessionHook())
|
||||
var userSessionHook: UserSessionHookProtocol
|
||||
}
|
||||
|
||||
nonisolated protocol AppHooksProtocol: Sendable {
|
||||
|
||||
@@ -16,9 +16,8 @@ extension AppHooks {
|
||||
#if IS_MAIN_APP
|
||||
registerAppSettingsHook(HealthChatAppSettingsHook())
|
||||
registerCompoundHook(HealthChatCompoundHook())
|
||||
registerExtendedProfileSectionHook(HealthChatExtendedProfileSectionHook())
|
||||
registerHomeTabsHook(HealthChatHomeTabsHook())
|
||||
registerSettingsScreenHook(HealthChatSettingsScreenHook())
|
||||
registerUserSessionHook(HealthChatUserSessionHook())
|
||||
registerUserDetailsEditScreenHook(HealthChatUserDetailsEditScreenHook())
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -12,20 +12,14 @@ import SwiftUI
|
||||
// service is main-actor state — the hook's requirements are all @MainActor anyway.
|
||||
@MainActor
|
||||
final class HealthChatExtendedProfileSectionHook: ExtendedProfileSectionHookProtocol {
|
||||
private var extendedProfileService: ExtendedProfileServiceProtocol?
|
||||
private let extendedProfileService: ExtendedProfileServiceProtocol
|
||||
|
||||
// Constructed during hook registration, before the main actor is reachable.
|
||||
nonisolated init() { }
|
||||
|
||||
func configure(with userSession: UserSessionProtocol?) async {
|
||||
extendedProfileService = userSession.map { ExtendedProfileService(clientProxy: $0.clientProxy) }
|
||||
init(extendedProfileService: ExtendedProfileServiceProtocol) {
|
||||
self.extendedProfileService = extendedProfileService
|
||||
}
|
||||
|
||||
func extendedProfileSection(userID: String) -> AnyView? {
|
||||
guard let extendedProfileService else {
|
||||
return nil
|
||||
}
|
||||
return AnyView(HealthChatExtendedProfileSection(userID: userID, service: extendedProfileService))
|
||||
AnyView(HealthChatExtendedProfileSection(userID: userID, service: extendedProfileService))
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -14,28 +14,19 @@ import SwiftUI
|
||||
final class HealthChatSettingsScreenHook: SettingsScreenHookProtocol {
|
||||
// Owned here rather than by the section: the settings screen asks for the section on
|
||||
// every body pass. Nothing is fetched until the screen appears and asks for a refresh.
|
||||
private var statusLoader: HealthChatAccountStatusLoader?
|
||||
private let statusLoader: HealthChatAccountStatusLoader
|
||||
|
||||
// Constructed during hook registration, before the main actor is reachable.
|
||||
nonisolated init() { }
|
||||
|
||||
func configure(with userSession: UserSessionProtocol?) async {
|
||||
statusLoader = userSession.map {
|
||||
let apiService = HealthChatAPIService(tokenProvider: HealthChatOpenIDTokenProvider(clientProxy: $0.clientProxy))
|
||||
return HealthChatAccountStatusLoader(apiService: apiService)
|
||||
}
|
||||
init(statusLoader: HealthChatAccountStatusLoader) {
|
||||
self.statusLoader = statusLoader
|
||||
}
|
||||
|
||||
func accountStatusSection(completeProfileAction: @escaping () -> Void) -> AnyView? {
|
||||
guard let statusLoader else {
|
||||
return nil
|
||||
}
|
||||
return AnyView(HealthChatAccountStatusSection(loader: statusLoader,
|
||||
completeProfileAction: completeProfileAction))
|
||||
AnyView(HealthChatAccountStatusSection(loader: statusLoader,
|
||||
completeProfileAction: completeProfileAction))
|
||||
}
|
||||
|
||||
func refreshAccountStatus() {
|
||||
statusLoader?.load()
|
||||
statusLoader.load()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright 2026 Novaloop AG
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
#if IS_MAIN_APP
|
||||
/// Builds the HealthChat session-scoped hooks when a user session is created.
|
||||
nonisolated struct HealthChatUserSessionHook: UserSessionHookProtocol {
|
||||
func makeUserHooks(for clientProxy: ClientProxyProtocol) -> UserHooks {
|
||||
let apiService = HealthChatAPIService(tokenProvider: HealthChatOpenIDTokenProvider(clientProxy: clientProxy))
|
||||
return UserHooks(extendedProfileSectionHook: HealthChatExtendedProfileSectionHook(extendedProfileService: ExtendedProfileService(clientProxy: clientProxy)),
|
||||
settingsScreenHook: HealthChatSettingsScreenHook(statusLoader: HealthChatAccountStatusLoader(apiService: apiService)))
|
||||
}
|
||||
|
||||
func configure(_ userSettings: UserSettings, forHomeserver homeserver: String) -> UserSettings {
|
||||
userSettings
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -8,16 +8,12 @@
|
||||
import SwiftUI
|
||||
|
||||
nonisolated protocol ExtendedProfileSectionHookProtocol: Sendable {
|
||||
@MainActor func configure(with userSession: UserSessionProtocol?) async
|
||||
|
||||
/// An extra Form section rendered below the header on the user profile
|
||||
/// and room member details screens.
|
||||
@MainActor func extendedProfileSection(userID: String) -> AnyView?
|
||||
}
|
||||
|
||||
struct DefaultExtendedProfileSectionHook: ExtendedProfileSectionHookProtocol {
|
||||
func configure(with userSession: UserSessionProtocol?) async { }
|
||||
|
||||
func extendedProfileSection(userID: String) -> AnyView? {
|
||||
nil
|
||||
}
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
import SwiftUI
|
||||
|
||||
nonisolated protocol SettingsScreenHookProtocol: Sendable {
|
||||
@MainActor func configure(with userSession: UserSessionProtocol?) async
|
||||
|
||||
/// An extra Form section rendered between the user and the account sections,
|
||||
/// advertising whatever is holding the account back.
|
||||
/// - Parameter completeProfileAction: Opens the own profile editor.
|
||||
@@ -20,8 +18,6 @@ nonisolated protocol SettingsScreenHookProtocol: Sendable {
|
||||
}
|
||||
|
||||
struct DefaultSettingsScreenHook: SettingsScreenHookProtocol {
|
||||
func configure(with userSession: UserSessionProtocol?) async { }
|
||||
|
||||
func accountStatusSection(completeProfileAction: @escaping () -> Void) -> AnyView? {
|
||||
nil
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ nonisolated struct UserHooks: Sendable {
|
||||
let recoveryKeyScreenHook: RecoveryKeyScreenHookProtocol
|
||||
let createRoomScreenHook: CreateRoomScreenHookProtocol
|
||||
let securityAndPrivacyScreenHook: SecurityAndPrivacyScreenHookProtocol
|
||||
// HealthChat: session-scoped hooks of the fork. Kept here, next to upstream's, so screens reach them the same way.
|
||||
let extendedProfileSectionHook: ExtendedProfileSectionHookProtocol
|
||||
let settingsScreenHook: SettingsScreenHookProtocol
|
||||
|
||||
init(roomScreenHook: RoomScreenHookProtocol = DefaultRoomScreenHook(),
|
||||
roomDetailsScreenHook: RoomDetailsScreenHookProtocol = DefaultRoomDetailsScreenHook(),
|
||||
@@ -22,7 +25,9 @@ nonisolated struct UserHooks: Sendable {
|
||||
userProfileScreenHook: UserProfileScreenHookProtocol = DefaultUserProfileScreenHook(),
|
||||
recoveryKeyScreenHook: RecoveryKeyScreenHookProtocol = DefaultRecoveryKeyScreenHook(),
|
||||
createRoomScreenHook: CreateRoomScreenHookProtocol = DefaultCreateRoomScreenHook(),
|
||||
securityAndPrivacyScreenHook: SecurityAndPrivacyScreenHookProtocol = DefaultSecurityAndPrivacyScreenHook()) {
|
||||
securityAndPrivacyScreenHook: SecurityAndPrivacyScreenHookProtocol = DefaultSecurityAndPrivacyScreenHook(),
|
||||
extendedProfileSectionHook: ExtendedProfileSectionHookProtocol = DefaultExtendedProfileSectionHook(),
|
||||
settingsScreenHook: SettingsScreenHookProtocol = DefaultSettingsScreenHook()) {
|
||||
self.roomScreenHook = roomScreenHook
|
||||
self.roomDetailsScreenHook = roomDetailsScreenHook
|
||||
self.roomMemberDetailsScreenHook = roomMemberDetailsScreenHook
|
||||
@@ -30,5 +35,7 @@ nonisolated struct UserHooks: Sendable {
|
||||
self.recoveryKeyScreenHook = recoveryKeyScreenHook
|
||||
self.createRoomScreenHook = createRoomScreenHook
|
||||
self.securityAndPrivacyScreenHook = securityAndPrivacyScreenHook
|
||||
self.extendedProfileSectionHook = extendedProfileSectionHook
|
||||
self.settingsScreenHook = settingsScreenHook
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user