Add an app setting to disable rendering the chrome around the app logo/brand.

This commit is contained in:
Stefan Ceriu
2025-09-19 14:32:12 +03:00
committed by Stefan Ceriu
parent 9ac83d06c7
commit afc09fd618
10 changed files with 41 additions and 27 deletions

View File

@@ -108,6 +108,7 @@ final class AppSettings {
// swiftlint:disable:next function_parameter_count
func override(accountProviders: [String],
allowOtherAccountProviders: Bool,
hideBrandChrome: Bool,
pushGatewayBaseURL: URL,
oidcRedirectURL: URL,
websiteURL: URL,
@@ -126,6 +127,7 @@ final class AppSettings {
mapTilerConfiguration: MapTilerConfiguration) {
self.accountProviders = accountProviders
self.allowOtherAccountProviders = allowOtherAccountProviders
self.hideBrandChrome = hideBrandChrome
self.pushGatewayBaseURL = pushGatewayBaseURL
self.oidcRedirectURL = oidcRedirectURL
self.websiteURL = websiteURL
@@ -164,6 +166,8 @@ final class AppSettings {
private(set) var accountProviders = ["matrix.org"]
/// Whether or not the user is allowed to manually enter their own account provider or must select from one of `defaultAccountProviders`.
private(set) var allowOtherAccountProviders = true
/// Whether the components surrounding the app brand/logo should be hidden or not
private(set) var hideBrandChrome = false
/// The task identifier used for background app refresh. Also used in main target's the Info.plist
let backgroundAppRefreshTaskIdentifier = "io.element.elementx.background.refresh"

View File

@@ -218,7 +218,7 @@ class AppLockFlowCoordinator: CoordinatorProtocol {
/// Displays the unlock flow with the app's placeholder view to hide obscure the view hierarchy in the app switcher.
private func showPlaceholder() {
navigationCoordinator.setRootCoordinator(PlaceholderScreenCoordinator(showsBackgroundGradient: true), animated: false)
navigationCoordinator.setRootCoordinator(PlaceholderScreenCoordinator(hideBrandChrome: false), animated: false)
actionsSubject.send(.lockApp)
}

View File

@@ -37,6 +37,8 @@ struct AuthenticationStartScreenViewState: BindableState {
let showCreateAccountButton: Bool
let showQRCodeLoginButton: Bool
let hideBrandChrome: Bool
var bindings = AuthenticationStartScreenViewStateBindings()
var loginButtonTitle: String {

View File

@@ -42,17 +42,20 @@ class AuthenticationStartScreenViewModel: AuthenticationStartScreenViewModelType
// The assumption here being that if you're running a custom app, your users will already be created.
AuthenticationStartScreenViewState(serverName: appSettings.accountProviders.count == 1 ? appSettings.accountProviders[0] : nil,
showCreateAccountButton: false,
showQRCodeLoginButton: isQRCodeScanningSupported)
showQRCodeLoginButton: isQRCodeScanningSupported,
hideBrandChrome: appSettings.hideBrandChrome)
} else if let provisioningParameters {
// We only show the "Sign in to " button when using a provisioning link.
AuthenticationStartScreenViewState(serverName: provisioningParameters.accountProvider,
showCreateAccountButton: false,
showQRCodeLoginButton: false)
showQRCodeLoginButton: false,
hideBrandChrome: appSettings.hideBrandChrome)
} else {
// The default configuration.
AuthenticationStartScreenViewState(serverName: nil,
showCreateAccountButton: appSettings.showCreateAccountButton,
showQRCodeLoginButton: isQRCodeScanningSupported)
showQRCodeLoginButton: isQRCodeScanningSupported,
hideBrandChrome: appSettings.hideBrandChrome)
}
super.init(initialViewState: initialViewState)

View File

@@ -62,23 +62,25 @@ struct AuthenticationStartScreen: View {
if verticalSizeClass == .regular {
Spacer()
AuthenticationStartLogo(isOnGradient: true)
AuthenticationStartLogo(isOnGradient: !context.viewState.hideBrandChrome)
}
Spacer()
VStack(spacing: 8) {
Text(L10n.screenOnboardingWelcomeTitle)
.font(.compound.headingLGBold)
.foregroundColor(.compound.textPrimary)
.multilineTextAlignment(.center)
Text(L10n.screenOnboardingWelcomeMessage(InfoPlistReader.main.productionAppName))
.font(.compound.bodyLG)
.foregroundColor(.compound.textSecondary)
.multilineTextAlignment(.center)
if !context.viewState.hideBrandChrome {
VStack(spacing: 8) {
Text(L10n.screenOnboardingWelcomeTitle)
.font(.compound.headingLGBold)
.foregroundColor(.compound.textPrimary)
.multilineTextAlignment(.center)
Text(L10n.screenOnboardingWelcomeMessage(InfoPlistReader.main.productionAppName))
.font(.compound.bodyLG)
.foregroundColor(.compound.textSecondary)
.multilineTextAlignment(.center)
}
.padding()
.fixedSize(horizontal: false, vertical: true)
}
.padding()
.fixedSize(horizontal: false, vertical: true)
Spacer()
}

View File

@@ -8,26 +8,26 @@
import SwiftUI
class PlaceholderScreenCoordinator: CoordinatorProtocol {
private let showsBackgroundGradient: Bool
private let hideBrandChrome: Bool
init(showsBackgroundGradient: Bool = false) {
self.showsBackgroundGradient = showsBackgroundGradient
init(hideBrandChrome: Bool = true) {
self.hideBrandChrome = hideBrandChrome
}
func toPresentable() -> AnyView {
AnyView(PlaceholderScreen(showsBackgroundGradient: showsBackgroundGradient))
AnyView(PlaceholderScreen(hideBrandChrome: hideBrandChrome))
}
}
/// The screen shown in split view when the detail has no content.
struct PlaceholderScreen: View {
let showsBackgroundGradient: Bool
let hideBrandChrome: Bool
var body: some View {
AuthenticationStartLogo(isOnGradient: showsBackgroundGradient)
AuthenticationStartLogo(isOnGradient: !hideBrandChrome)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background {
if showsBackgroundGradient {
if !hideBrandChrome {
AuthenticationStartScreenBackgroundImage()
}
}
@@ -40,10 +40,10 @@ struct PlaceholderScreen: View {
struct PlaceholderScreen_Previews: PreviewProvider, TestablePreview {
static var previews: some View {
PlaceholderScreen(showsBackgroundGradient: false)
PlaceholderScreen(hideBrandChrome: true)
.previewDisplayName("Screen")
PlaceholderScreen(showsBackgroundGradient: true)
PlaceholderScreen(hideBrandChrome: false)
.previewDisplayName("With background")
NavigationSplitView {
@@ -53,7 +53,7 @@ struct PlaceholderScreen_Previews: PreviewProvider, TestablePreview {
}
}
} detail: {
PlaceholderScreen(showsBackgroundGradient: false)
PlaceholderScreen(hideBrandChrome: true)
}
.previewDisplayName("Split View")
.previewInterfaceOrientation(.landscapeLeft)

View File

@@ -127,6 +127,7 @@ class MockScreen: Identifiable {
let accountProviders = id == .singleProviderAuthenticationFlow ? ["example.com"] : ["guest.example.com", "example.com"]
appSettings.override(accountProviders: accountProviders,
allowOtherAccountProviders: false,
hideBrandChrome: false,
pushGatewayBaseURL: appSettings.pushGatewayBaseURL,
oidcRedirectURL: appSettings.oidcRedirectURL,
websiteURL: appSettings.websiteURL,

View File

@@ -159,6 +159,7 @@ class AuthenticationStartScreenViewModelTests: XCTestCase {
private func setAllowedAccountProviders(_ providers: [String]) {
appSettings.override(accountProviders: providers,
allowOtherAccountProviders: false,
hideBrandChrome: false,
pushGatewayBaseURL: appSettings.pushGatewayBaseURL,
oidcRedirectURL: appSettings.oidcRedirectURL,
websiteURL: appSettings.websiteURL,

View File

@@ -311,6 +311,7 @@ class ServerConfirmationScreenViewModelTests: XCTestCase {
if restrictedFlow {
appSettings.override(accountProviders: ["matrix.org", "beta.matrix.org"],
allowOtherAccountProviders: false,
hideBrandChrome: false,
pushGatewayBaseURL: appSettings.pushGatewayBaseURL,
oidcRedirectURL: appSettings.oidcRedirectURL,
websiteURL: appSettings.websiteURL,