#106: Add Analytics UI

This commit is contained in:
Doug
2022-09-02 10:49:59 +01:00
committed by Doug
parent df68174a32
commit 8e46d0e3d6
26 changed files with 1437 additions and 85 deletions
@@ -18,6 +18,7 @@ import SwiftUI
struct SettingsCoordinatorParameters {
let navigationRouter: NavigationRouterType
let userSession: UserSessionProtocol
let bugReportService: BugReportServiceProtocol
}
@@ -60,6 +61,8 @@ final class SettingsCoordinator: Coordinator, Presentable {
guard let self = self else { return }
MXLog.debug("SettingsViewModel did complete with result: \(result).")
switch result {
case .toggleAnalytics:
self.toggleAnalytics()
case .reportBug:
self.presentBugReportScreen()
case .crash:
@@ -82,17 +85,12 @@ final class SettingsCoordinator: Coordinator, Presentable {
// MARK: - Private
/// Show an activity indicator whilst loading.
/// - Parameters:
/// - label: The label to show on the indicator.
/// - isInteractionBlocking: Whether the indicator should block any user interaction.
private func startLoading(label: String = ElementL10n.loading, isInteractionBlocking: Bool = true) {
loadingIndicator = indicatorPresenter.present(.loading(label: label, isInteractionBlocking: isInteractionBlocking))
}
/// Hide the currently displayed activity indicator.
private func stopLoading() {
loadingIndicator = nil
private func toggleAnalytics() {
if ElementSettings.shared.enableAnalytics {
Analytics.shared.optOut()
} else {
Analytics.shared.optIn(with: parameters.userSession)
}
}
private func presentBugReportScreen() {
@@ -114,6 +112,19 @@ final class SettingsCoordinator: Coordinator, Presentable {
self.remove(childCoordinator: coordinator)
}
}
/// Show an activity indicator whilst loading.
/// - Parameters:
/// - label: The label to show on the indicator.
/// - isInteractionBlocking: Whether the indicator should block any user interaction.
private func startLoading(label: String = ElementL10n.loading, isInteractionBlocking: Bool = true) {
loadingIndicator = indicatorPresenter.present(.loading(label: label, isInteractionBlocking: isInteractionBlocking))
}
/// Hide the currently displayed activity indicator.
private func stopLoading() {
loadingIndicator = nil
}
/// Show success indicator
private func showSuccess(label: String) {
@@ -21,6 +21,7 @@ import Foundation
// MARK: View model
enum SettingsViewModelAction {
case toggleAnalytics
case reportBug
case crash
case logout
@@ -32,9 +33,12 @@ struct SettingsViewState: BindableState {
var bindings: SettingsViewStateBindings
}
struct SettingsViewStateBindings { }
struct SettingsViewStateBindings {
var enableAnalytics = ElementSettings.shared.enableAnalytics
}
enum SettingsViewAction {
case toggleAnalytics
case reportBug
case crash
case logout
@@ -40,6 +40,8 @@ class SettingsViewModel: SettingsViewModelType, SettingsViewModelProtocol {
override func process(viewAction: SettingsViewAction) async {
switch viewAction {
case .toggleAnalytics:
callback?(.toggleAnalytics)
case .reportBug:
callback?(.reportBug)
case .crash:
@@ -31,43 +31,14 @@ struct SettingsScreen: View {
var body: some View {
Form {
Section {
Button { context.send(viewAction: .reportBug) } label: {
Text(ElementL10n.sendBugReport)
}
.foregroundColor(Color.element.primaryContent)
.accessibilityIdentifier("reportBugButton")
if BuildSettings.settingsCrashButtonVisible {
Button("Crash the app",
role: .destructive) { context.send(viewAction: .crash)
}
.accessibilityIdentifier("crashButton")
}
}
.listRowBackground(rowBackgroundColor)
analyticsSection
.listRowBackground(rowBackgroundColor)
userInterfaceSection
.listRowBackground(rowBackgroundColor)
Section {
Button { showingLogoutConfirmation = true } label: {
Text(ElementL10n.actionSignOut)
}
.frame(maxWidth: .infinity)
.foregroundColor(Color.element.primaryContent)
.accessibilityIdentifier("logoutButton")
.confirmationDialog(ElementL10n.actionSignOutConfirmationSimple,
isPresented: $showingLogoutConfirmation,
titleVisibility: .visible) {
Button(ElementL10n.actionSignOut,
role: .destructive) { context.send(viewAction: .logout)
}
}
} footer: {
versionText
}
.listRowBackground(rowBackgroundColor)
logoutSection
.listRowBackground(rowBackgroundColor)
}
.introspectTableView { tableView in
tableView.backgroundColor = .clear
@@ -87,11 +58,28 @@ struct SettingsScreen: View {
private var rowBackgroundColor: Color {
colorScheme == .light ? .element.background : .element.system
}
private var analyticsSection: some View {
Section(ElementL10n.settingsAnalytics) {
Button { context.send(viewAction: .reportBug) } label: {
Text(ElementL10n.sendBugReport)
}
.foregroundColor(.element.primaryContent)
.accessibilityIdentifier("reportBugButton")
if BuildSettings.settingsCrashButtonVisible {
Button("Crash the app",
role: .destructive) { context.send(viewAction: .crash)
}
.accessibilityIdentifier("crashButton")
}
}
}
@ViewBuilder
private var userInterfaceSection: some View {
if BuildSettings.settingsShowTimelineStyle {
Section(header: Text(ElementL10n.settingsUserInterface)) {
Section(ElementL10n.settingsUserInterface) {
Picker(ElementL10n.settingsTimelineStyle, selection: $settings.timelineStyle) {
ForEach(TimelineStyle.allCases, id: \.self) { style in
Text(style.description)
@@ -100,7 +88,26 @@ struct SettingsScreen: View {
}
.accessibilityIdentifier("timelineStylePicker")
}
.listRowBackground(rowBackgroundColor)
}
}
private var logoutSection: some View {
Section {
Button { showingLogoutConfirmation = true } label: {
Text(ElementL10n.actionSignOut)
}
.frame(maxWidth: .infinity)
.foregroundColor(.element.primaryContent)
.accessibilityIdentifier("logoutButton")
.confirmationDialog(ElementL10n.actionSignOutConfirmationSimple,
isPresented: $showingLogoutConfirmation,
titleVisibility: .visible) {
Button(ElementL10n.actionSignOut,
role: .destructive) { context.send(viewAction: .logout)
}
}
} footer: {
versionText
}
}
}