Adapt the HealthChat hooks to the upstream 26.09.1 screen APIs

The rebase onto release/26.09.1 moved three things the fork depends on.

Upstream now owns a UserProfileScreenHook of its own (#5980), which rewrites a
screen's view state rather than injecting a view. The fork's section hook keeps
its behaviour under the fork-only name ExtendedProfileSectionHook, so both can
live side by side and upstream's file stays untouched. Upstream's new @AppHook
macro generates the same register<Name> methods, so registration is unchanged.

UserProfileScreenCoordinatorParameters lost appSettings and reordered its
arguments, and UserDetailsEditScreenCoordinator now publishes its own
UserDetailsEditScreenCoordinatorAction instead of borrowing the room one
(#5893). The members flow and the profile editor follow both.

AppSettings.override gained oAuthClientURIPath (#5934), whose default appends
apps/ios to the website URL. HealthChat passes nil to keep the registered
client_uri at https://healthchat.ch exactly as the shipped build has it —
changing what the app registers with MAS is not a side effect a rebase should
have.
This commit is contained in:
2026-09-22 18:46:08 +02:00
parent 7587fd76ee
commit a838a03a1f
6 changed files with 12 additions and 12 deletions
+2 -2
View File
@@ -43,7 +43,7 @@ final nonisolated class AppHooks: AppHooksProtocol {
@AppHook(default: DefaultUserProfileScreenHook()) @AppHook(default: DefaultUserProfileScreenHook())
var userProfileScreenHook: UserProfileScreenHookProtocol var userProfileScreenHook: UserProfileScreenHookProtocol
@AppHook(default: DefaultExtendedProfileSectionHook()) @AppHook(default: DefaultExtendedProfileSectionHook())
var extendedProfileSectionHook: ExtendedProfileSectionHookProtocol var extendedProfileSectionHook: ExtendedProfileSectionHookProtocol
@@ -52,7 +52,7 @@ final nonisolated class AppHooks: AppHooksProtocol {
@AppHook(default: DefaultUserDetailsEditScreenHook()) @AppHook(default: DefaultUserDetailsEditScreenHook())
var userDetailsEditScreenHook: UserDetailsEditScreenHookProtocol var userDetailsEditScreenHook: UserDetailsEditScreenHookProtocol
@AppHook(default: DefaultDeveloperOptionsScreenHook()) @AppHook(default: DefaultDeveloperOptionsScreenHook())
var developerOptionsScreenHook: DeveloperOptionsScreenHookProtocol var developerOptionsScreenHook: DeveloperOptionsScreenHookProtocol
@@ -20,6 +20,8 @@ struct HealthChatAppSettingsHook: AppSettingsHookProtocol {
hideBrandChrome: false, hideBrandChrome: false,
pushGatewayBaseURL: "https://sygnal.healthchat.ch", pushGatewayBaseURL: "https://sygnal.healthchat.ch",
oAuthRedirectURL: "ch.healthchat.element:/oauth/callback", oAuthRedirectURL: "ch.healthchat.element:/oauth/callback",
// nil keeps the registered client_uri at the bare website URL, as shipped before upstream's `apps/ios` default.
oAuthClientURIPath: nil,
websiteURL: "https://healthchat.ch", websiteURL: "https://healthchat.ch",
logoURL: "https://app.healthchat.ch/themes/element/img/logos/element-logo.png", logoURL: "https://app.healthchat.ch/themes/element/img/logos/element-logo.png",
copyrightURL: appSettings.copyrightURL, copyrightURL: appSettings.copyrightURL,
@@ -9,7 +9,7 @@ import SwiftUI
nonisolated protocol ExtendedProfileSectionHookProtocol: Sendable { nonisolated protocol ExtendedProfileSectionHookProtocol: Sendable {
@MainActor func configure(with userSession: UserSessionProtocol?) async @MainActor func configure(with userSession: UserSessionProtocol?) async
/// An extra Form section rendered below the header on the user profile /// An extra Form section rendered below the header on the user profile
/// and room member details screens. /// and room member details screens.
@MainActor func extendedProfileSection(userID: String) -> AnyView? @MainActor func extendedProfileSection(userID: String) -> AnyView?
@@ -17,7 +17,7 @@ nonisolated protocol ExtendedProfileSectionHookProtocol: Sendable {
struct DefaultExtendedProfileSectionHook: ExtendedProfileSectionHookProtocol { struct DefaultExtendedProfileSectionHook: ExtendedProfileSectionHookProtocol {
func configure(with userSession: UserSessionProtocol?) async { } func configure(with userSession: UserSessionProtocol?) async { }
func extendedProfileSection(userID: String) -> AnyView? { func extendedProfileSection(userID: String) -> AnyView? {
nil nil
} }
@@ -9,7 +9,7 @@ import Combine
import SwiftUI import SwiftUI
@MainActor protocol UserDetailsEditCoordinatorProtocol: CoordinatorProtocol { @MainActor protocol UserDetailsEditCoordinatorProtocol: CoordinatorProtocol {
var actions: AnyPublisher<RoomDetailsEditScreenCoordinatorAction, Never> { get } var actions: AnyPublisher<UserDetailsEditScreenCoordinatorAction, Never> { get }
} }
nonisolated protocol UserDetailsEditScreenHookProtocol: Sendable { nonisolated protocol UserDetailsEditScreenHookProtocol: Sendable {
@@ -121,10 +121,9 @@ final class HealthChatMembersFlowCoordinator {
let parameters = UserProfileScreenCoordinatorParameters(userID: userID, let parameters = UserProfileScreenCoordinatorParameters(userID: userID,
isPresentedModally: false, isPresentedModally: false,
userSession: flowParameters.userSession, userSession: flowParameters.userSession,
userIndicatorController: flowParameters.userIndicatorController, appHooks: flowParameters.appHooks,
analytics: flowParameters.analytics, analytics: flowParameters.analytics,
appSettings: flowParameters.appSettings, userIndicatorController: flowParameters.userIndicatorController)
appHooks: flowParameters.appHooks)
let coordinator = UserProfileScreenCoordinator(parameters: parameters) let coordinator = UserProfileScreenCoordinator(parameters: parameters)
coordinator.actionsPublisher.sink { [weak self] action in coordinator.actionsPublisher.sink { [weak self] action in
@@ -151,8 +150,7 @@ final class HealthChatMembersFlowCoordinator {
userSession: flowParameters.userSession, userSession: flowParameters.userSession,
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: flowParameters.appSettings), mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: flowParameters.appSettings),
navigationStackCoordinator: navigationStackCoordinator, navigationStackCoordinator: navigationStackCoordinator,
userIndicatorController: flowParameters.userIndicatorController, userIndicatorController: flowParameters.userIndicatorController)
appSettings: flowParameters.appSettings)
let coordinator = flowParameters.appHooks.userDetailsEditScreenHook.makeCoordinator(parameters: parameters) let coordinator = flowParameters.appHooks.userDetailsEditScreenHook.makeCoordinator(parameters: parameters)
coordinator.actions.sink { [weak self] action in coordinator.actions.sink { [weak self] action in
@@ -22,8 +22,8 @@ final class HealthChatProfileEditScreenCoordinator: CoordinatorProtocol, UserDet
private let viewModel: HealthChatProfileEditScreenViewModelProtocol private let viewModel: HealthChatProfileEditScreenViewModelProtocol
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
private let actionsSubject: PassthroughSubject<RoomDetailsEditScreenCoordinatorAction, Never> = .init() private let actionsSubject: PassthroughSubject<UserDetailsEditScreenCoordinatorAction, Never> = .init()
var actions: AnyPublisher<RoomDetailsEditScreenCoordinatorAction, Never> { var actions: AnyPublisher<UserDetailsEditScreenCoordinatorAction, Never> {
actionsSubject.eraseToAnyPublisher() actionsSubject.eraseToAnyPublisher()
} }