Files
letro-ios/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift
Stefan Ceriu e918dc66ae Tracing and integration test tweaks (#3336)
* Disable image and document picker integration tests as they randomly fail to load and are flakey.

* Delete any pre-existing log files

* Various tracing tweaks and fixes:
- delete the custom tracing log levels as we can't control their ouput
- implement comparable on them
- change default levels only if the new chosen level increases their verbosity

* Make logging targets mandatory and fix their logging levels

* Switch back to using the `run_tests` reset simulator flag as `fastlane snapshot reset_simulators` was too generic and slow

* Switch all integration test taps to `tapCenter` (nee forceTap) after noticing missed taps on CI.

* Make the logging file prefix explicit, let the main app not use one.

* Rename tracing configuration `target` to `currentTarget`
2024-09-27 15:08:47 +03:00

167 lines
5.9 KiB
Swift

//
// Copyright 2022-2024 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only
// Please see LICENSE in the repository root for full details.
//
import SwiftUI
struct DeveloperOptionsScreen: View {
@ObservedObject var context: DeveloperOptionsScreenViewModel.Context
@State private var showConfetti = false
@State private var elementCallURLOverrideString: String
init(context: DeveloperOptionsScreenViewModel.Context) {
self.context = context
elementCallURLOverrideString = context.elementCallBaseURLOverride?.absoluteString ?? ""
}
var body: some View {
Form {
Section("Logging") {
LogLevelConfigurationView(logLevel: $context.logLevel)
}
Section {
Picker("Discovery", selection: $context.slidingSyncDiscovery) {
Text("Proxy only").tag(AppSettings.SlidingSyncDiscovery.proxy)
Text("Automatic").tag(AppSettings.SlidingSyncDiscovery.native)
Text("Force Native ⚠️").tag(AppSettings.SlidingSyncDiscovery.forceNative)
}
} header: {
Text("Sliding Sync")
} footer: {
Text(context.viewState.slidingSyncFooter)
}
Section("Message Pinning") {
Toggle(isOn: $context.pinningEnabled) {
Text("Enable message pinning")
Text("Requires app reboot")
}
}
Section("Room List") {
Toggle(isOn: $context.hideUnreadMessagesBadge) {
Text("Hide grey dots")
}
Toggle(isOn: $context.fuzzyRoomListSearchEnabled) {
Text("Fuzzy searching")
}
}
Section {
Toggle(isOn: $context.enableOnlySignedDeviceIsolationMode) {
Text("Exclude not secure devices when sending/receiving messages")
Text("Requires app reboot")
}
} header: {
Text("Trust and Decoration")
} footer: {
Text("This setting controls how end-to-end encryption (E2EE) keys are exchanged. Enabling it will prevent the inclusion of devices that have not been explicitly verified by their owners.")
}
Section {
TextField(context.viewState.elementCallBaseURL.absoluteString, text: $elementCallURLOverrideString)
.autocorrectionDisabled(true)
.autocapitalization(.none)
.foregroundColor(URL(string: elementCallURLOverrideString) == nil ? .red : .primary)
.submitLabel(.done)
.onSubmit {
if elementCallURLOverrideString.isEmpty {
context.elementCallBaseURLOverride = nil
} else if let url = URL(string: elementCallURLOverrideString) {
context.elementCallBaseURLOverride = url
}
}
} header: {
Text("Element Call")
} footer: {
if context.elementCallBaseURLOverride == nil {
Text("The call URL may be overridden by your homeserver.")
}
}
Section {
Button {
showConfetti = true
} label: {
Text("🥳")
.frame(maxWidth: .infinity)
.alignmentGuide(.listRowSeparatorLeading) { _ in 0 } // Fix separator alignment
}
Button {
fatalError("This crash is a test.")
} label: {
Text("💥")
.frame(maxWidth: .infinity)
}
}
Section {
Button(role: .destructive) {
context.send(viewAction: .clearCache)
} label: {
Text("Clear cache")
.frame(maxWidth: .infinity)
}
}
}
.overlay(effectsView)
.compoundList()
.navigationTitle(L10n.commonDeveloperOptions)
.navigationBarTitleDisplayMode(.inline)
}
@ViewBuilder
private var effectsView: some View {
if showConfetti {
EffectsView(effect: .confetti)
.ignoresSafeArea()
.allowsHitTesting(false)
.task { await removeConfettiAfterDelay() }
}
}
private func removeConfettiAfterDelay() async {
try? await Task.sleep(for: .seconds(4))
showConfetti = false
}
}
private struct LogLevelConfigurationView: View {
@Binding var logLevel: TracingConfiguration.LogLevel
var body: some View {
Picker(selection: $logLevel) {
ForEach(logLevels, id: \.self) { logLevel in
Text(logLevel.title)
}
} label: {
Text("Log level")
Text("Requires app reboot")
}
}
/// Allows the picker to work with associated values
private var logLevels: [TracingConfiguration.LogLevel] {
[.error, .warn, .info, .debug, .trace]
}
}
// MARK: - Previews
struct DeveloperOptionsScreen_Previews: PreviewProvider {
static let viewModel = DeveloperOptionsScreenViewModel(developerOptions: ServiceLocator.shared.settings,
elementCallBaseURL: ServiceLocator.shared.settings.elementCallBaseURL,
isUsingNativeSlidingSync: true)
static var previews: some View {
NavigationStack {
DeveloperOptionsScreen(context: viewModel.context)
}
}
}