430 - Design review for first public TestFlight Part2 (#496)

* 430 - Design review for first public TestFlight Part2

---------

Co-authored-by: Doug <douglase@element.io>
This commit is contained in:
Gil Eluard
2023-01-30 12:51:07 +01:00
committed by GitHub
parent f29c0a9811
commit e2e69534e3
19 changed files with 412 additions and 192 deletions
@@ -50,6 +50,8 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
self.toggleAnalytics()
case .reportBug:
self.presentBugReportScreen()
case .sessionVerification:
self.verifySession()
case .logout:
self.callback?(.logout)
}
@@ -91,6 +93,23 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
parameters.navigationStackCoordinator.push(coordinator)
}
private func verifySession() {
guard let sessionVerificationController = parameters.userSession.sessionVerificationController else {
fatalError("The sessionVerificationController should aways be valid at this point")
}
let verificationParameters = SessionVerificationCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController)
let coordinator = SessionVerificationCoordinator(parameters: verificationParameters)
coordinator.callback = { [weak self] in
self?.parameters.navigationStackCoordinator.setSheetCoordinator(nil)
}
parameters.navigationStackCoordinator.setSheetCoordinator(coordinator) { [weak self] in
self?.parameters.navigationStackCoordinator.setSheetCoordinator(nil)
}
}
private func showSuccess(label: String) {
parameters.userNotificationController.submitNotification(UserNotification(title: label))
@@ -21,6 +21,7 @@ enum SettingsScreenViewModelAction {
case close
case toggleAnalytics
case reportBug
case sessionVerification
case logout
}
@@ -30,6 +31,7 @@ struct SettingsScreenViewState: BindableState {
var userID: String
var userAvatarURL: URL?
var userDisplayName: String?
var showSessionVerificationSection: Bool
}
struct SettingsScreenViewStateBindings {
@@ -40,5 +42,6 @@ enum SettingsScreenViewAction {
case close
case toggleAnalytics
case reportBug
case sessionVerification
case logout
}
@@ -26,7 +26,10 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
init(withUserSession userSession: UserSessionProtocol) {
self.userSession = userSession
let bindings = SettingsScreenViewStateBindings()
super.init(initialViewState: .init(bindings: bindings, deviceID: userSession.deviceId, userID: userSession.userID),
super.init(initialViewState: .init(bindings: bindings,
deviceID: userSession.deviceId,
userID: userSession.userID,
showSessionVerificationSection: !(userSession.sessionVerificationController?.isVerified ?? false)),
imageProvider: userSession.mediaProvider)
Task {
@@ -40,6 +43,20 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
state.userDisplayName = userDisplayName
}
}
userSession.callbacks
.receive(on: DispatchQueue.main)
.sink { [weak self] callback in
switch callback {
case .sessionVerificationNeeded:
self?.state.showSessionVerificationSection = true
case .didVerifySession:
self?.state.showSessionVerificationSection = false
default:
break
}
}
.store(in: &cancellables)
}
override func process(viewAction: SettingsScreenViewAction) async {
@@ -52,6 +69,8 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
callback?(.reportBug)
case .logout:
callback?(.logout)
case .sessionVerification:
callback?(.sessionVerification)
}
}
}
@@ -32,17 +32,16 @@ struct SettingsScreen: View {
userSection
.listRowBackground(rowBackgroundColor)
if context.viewState.showSessionVerificationSection {
sessionVerificationSection
.listRowBackground(rowBackgroundColor)
}
simplifiedSection
.listRowBackground(rowBackgroundColor)
// analyticsSection
// .listRowBackground(rowBackgroundColor)
// userInterfaceSection
// .listRowBackground(rowBackgroundColor)
// logoutSection
// .listRowBackground(rowBackgroundColor)
signOutSection
.listRowBackground(rowBackgroundColor)
}
.introspectTableView { tableView in
tableView.backgroundColor = .clear
@@ -80,10 +79,10 @@ struct SettingsScreen: View {
VStack(alignment: .leading, spacing: 4) {
Text(context.viewState.userDisplayName ?? "")
.font(.title3)
.font(.element.title3)
.foregroundColor(.element.primaryContent)
Text(context.viewState.userID)
.font(.subheadline)
.font(.element.subheadline)
.foregroundColor(.element.primaryContent)
}
}
@@ -91,14 +90,38 @@ struct SettingsScreen: View {
}
}
private var sessionVerificationSection: some View {
Section {
SettingsDefaultRow(title: ElementL10n.settingsSessionVerification,
image: Image(systemName: "checkmark.shield")) {
context.send(viewAction: .sessionVerification)
}
.accessibilityIdentifier("sessionVerificationButton")
}
}
private var simplifiedSection: some View {
Section {
SettingsPickerRow(title: ElementL10n.settingsTimelineStyle,
image: Image(systemName: "rectangle.grid.1x2"),
selection: $settings.timelineStyle) {
ForEach(TimelineStyle.allCases, id: \.self) { style in
Text(style.description)
.tag(style)
}
}
.accessibilityIdentifier("timelineStylePicker")
SettingsDefaultRow(title: ElementL10n.sendBugReport,
image: Image(systemName: "questionmark.circle")) {
context.send(viewAction: .reportBug)
}
.accessibilityIdentifier("reportBugButton")
}
}
private var signOutSection: some View {
Section {
SettingsDefaultRow(title: ElementL10n.actionSignOut,
image: Image(systemName: "rectangle.portrait.and.arrow.right")) {
showingLogoutConfirmation = true
@@ -112,76 +135,20 @@ struct SettingsScreen: View {
} message: {
Text(ElementL10n.actionSignOutConfirmationSimple)
}
}
}
private var analyticsSection: some View {
Section {
Button { context.send(viewAction: .reportBug) } label: {
HStack {
Text(ElementL10n.sendBugReport)
Spacer()
Image(systemName: "chevron.forward")
.foregroundColor(.element.tertiaryContent)
}
}
.listRowInsets(listRowInsets)
.listRowSeparator(.hidden)
.foregroundColor(.element.primaryContent)
.accessibilityIdentifier("reportBugButton")
}
}
@ViewBuilder
private var userInterfaceSection: some View {
Section {
Picker(ElementL10n.settingsTimelineStyle, selection: $settings.timelineStyle) {
ForEach(TimelineStyle.allCases, id: \.self) { style in
Text(style.description)
.tag(style)
}
}
.listRowInsets(listRowInsets)
.accessibilityIdentifier("timelineStylePicker")
}
}
private var logoutSection: some View {
Section {
Button { showingLogoutConfirmation = true } label: {
HStack {
Image(systemName: "rectangle.portrait.and.arrow.right")
.foregroundColor(.element.systemGray)
.padding(4)
.background(Color.element.systemGray6)
.clipShape(Circle())
.frame(width: menuIconSize, height: menuIconSize)
Text(ElementL10n.actionSignOut)
Spacer()
Image(systemName: "chevron.forward")
.foregroundColor(.element.tertiaryContent)
}
}
.listRowInsets(listRowInsets)
.foregroundColor(.element.primaryContent)
.accessibilityIdentifier("logoutButton")
.alert(ElementL10n.actionSignOut,
isPresented: $showingLogoutConfirmation) {
Button(ElementL10n.actionSignOut,
role: .destructive,
action: logout)
} message: {
Text(ElementL10n.actionSignOutConfirmationSimple)
}
} footer: {
VStack {
versionText
.font(.element.caption1)
.foregroundColor(.element.tertiaryContent)
.frame(maxWidth: .infinity)
if let deviceId = context.viewState.deviceID {
Text(deviceId)
.font(.element.caption1)
.foregroundColor(.element.tertiaryContent)
}
}
.padding(.top, 24)
}
}