mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Allow reporting a problem from the onboarding screen
This commit is contained in:
parent
261258dd0a
commit
0fe52fe54b
@ -398,11 +398,12 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
|
||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||
appSettings: appSettings)
|
||||
authenticationCoordinator = AuthenticationCoordinator(authenticationService: authenticationService,
|
||||
appLockService: appLockFlowCoordinator.appLockService,
|
||||
bugReportService: ServiceLocator.shared.bugReportService,
|
||||
navigationStackCoordinator: authenticationNavigationStackCoordinator,
|
||||
appSettings: appSettings,
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
appLockService: appLockFlowCoordinator.appLockService)
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
authenticationCoordinator?.delegate = self
|
||||
|
||||
authenticationCoordinator?.start()
|
||||
|
@ -24,11 +24,12 @@ protocol AuthenticationCoordinatorDelegate: AnyObject {
|
||||
|
||||
class AuthenticationCoordinator: CoordinatorProtocol {
|
||||
private let authenticationService: AuthenticationServiceProxyProtocol
|
||||
private let appLockService: AppLockServiceProtocol
|
||||
private let bugReportService: BugReportServiceProtocol
|
||||
private let navigationStackCoordinator: NavigationStackCoordinator
|
||||
private let appSettings: AppSettings
|
||||
private let analytics: AnalyticsService
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let appLockService: AppLockServiceProtocol
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
@ -39,17 +40,19 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
||||
weak var delegate: AuthenticationCoordinatorDelegate?
|
||||
|
||||
init(authenticationService: AuthenticationServiceProxyProtocol,
|
||||
appLockService: AppLockServiceProtocol,
|
||||
bugReportService: BugReportServiceProtocol,
|
||||
navigationStackCoordinator: NavigationStackCoordinator,
|
||||
appSettings: AppSettings,
|
||||
analytics: AnalyticsService,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
appLockService: AppLockServiceProtocol) {
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.authenticationService = authenticationService
|
||||
self.appLockService = appLockService
|
||||
self.bugReportService = bugReportService
|
||||
self.navigationStackCoordinator = navigationStackCoordinator
|
||||
self.appSettings = appSettings
|
||||
self.analytics = analytics
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.appLockService = appLockService
|
||||
}
|
||||
|
||||
func start() {
|
||||
@ -81,6 +84,8 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
||||
switch action {
|
||||
case .login:
|
||||
Task { await self.startAuthentication() }
|
||||
case .reportProblem:
|
||||
showReportProblemScreen()
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
@ -88,6 +93,27 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
}
|
||||
|
||||
private func showReportProblemScreen() {
|
||||
let feedbackNavigationStackCoordinator = NavigationStackCoordinator()
|
||||
|
||||
let parameters = BugReportScreenCoordinatorParameters(bugReportService: bugReportService,
|
||||
userID: nil,
|
||||
deviceID: nil,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
screenshot: nil,
|
||||
isModallyPresented: true)
|
||||
|
||||
let coordinator = BugReportScreenCoordinator(parameters: parameters)
|
||||
|
||||
coordinator.completion = { [weak self] _ in
|
||||
self?.navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
}
|
||||
|
||||
feedbackNavigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
|
||||
navigationStackCoordinator.setSheetCoordinator(feedbackNavigationStackCoordinator, animated: true)
|
||||
}
|
||||
|
||||
private func startAuthentication() async {
|
||||
startLoading()
|
||||
|
||||
|
@ -24,7 +24,7 @@ enum BugReportScreenCoordinatorResult {
|
||||
|
||||
struct BugReportScreenCoordinatorParameters {
|
||||
let bugReportService: BugReportServiceProtocol
|
||||
let userID: String
|
||||
let userID: String?
|
||||
let deviceID: String?
|
||||
|
||||
let userIndicatorController: UserIndicatorControllerProtocol?
|
||||
|
@ -21,7 +21,7 @@ typealias BugReportScreenViewModelType = StateStoreViewModel<BugReportScreenView
|
||||
|
||||
class BugReportScreenViewModel: BugReportScreenViewModelType, BugReportScreenViewModelProtocol {
|
||||
private let bugReportService: BugReportServiceProtocol
|
||||
private let userID: String
|
||||
private let userID: String?
|
||||
private let deviceID: String?
|
||||
private let actionsSubject: PassthroughSubject<BugReportScreenViewModelAction, Never> = .init()
|
||||
// periphery:ignore - when set to nil this is automatically cancelled
|
||||
@ -32,7 +32,7 @@ class BugReportScreenViewModel: BugReportScreenViewModelType, BugReportScreenVie
|
||||
}
|
||||
|
||||
init(bugReportService: BugReportServiceProtocol,
|
||||
userID: String,
|
||||
userID: String?,
|
||||
deviceID: String?,
|
||||
screenshot: UIImage?,
|
||||
isModallyPresented: Bool) {
|
||||
|
@ -40,6 +40,8 @@ final class OnboardingScreenCoordinator: CoordinatorProtocol {
|
||||
switch action {
|
||||
case .login:
|
||||
actionsSubject.send(.login)
|
||||
case .reportProblem:
|
||||
actionsSubject.send(.reportProblem)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
@ -20,14 +20,17 @@ import SwiftUI
|
||||
|
||||
enum OnboardingScreenCoordinatorAction {
|
||||
case login
|
||||
case reportProblem
|
||||
}
|
||||
|
||||
enum OnboardingScreenViewModelAction {
|
||||
case login
|
||||
case reportProblem
|
||||
}
|
||||
|
||||
struct OnboardingScreenViewState: BindableState { }
|
||||
|
||||
enum OnboardingScreenViewAction {
|
||||
case login
|
||||
case reportProblem
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ class OnboardingScreenViewModel: OnboardingScreenViewModelType, OnboardingScreen
|
||||
switch viewAction {
|
||||
case .login:
|
||||
actionsSubject.send(.login)
|
||||
case .reportProblem:
|
||||
actionsSubject.send(.reportProblem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,16 @@ struct OnboardingScreen: View {
|
||||
.frame(height: UIConstants.spacerHeight(in: geometry))
|
||||
}
|
||||
.frame(maxHeight: .infinity)
|
||||
.safeAreaInset(edge: .bottom) {
|
||||
Button {
|
||||
context.send(viewAction: .reportProblem)
|
||||
} label: {
|
||||
Text(L10n.commonReportAProblem)
|
||||
.font(.compound.bodySM)
|
||||
.foregroundColor(.compound.textSecondary)
|
||||
}
|
||||
.frame(width: geometry.size.width)
|
||||
}
|
||||
}
|
||||
.navigationBarHidden(true)
|
||||
.background {
|
||||
|
@ -119,11 +119,14 @@ class BugReportService: NSObject, BugReportServiceProtocol {
|
||||
func submitBugReport(_ bugReport: BugReport,
|
||||
progressListener: CurrentValueSubject<Double, Never>) async -> Result<SubmitBugReportResponse, BugReportServiceError> {
|
||||
var params = [
|
||||
MultipartFormData(key: "user_id", type: .text(value: bugReport.userID)),
|
||||
MultipartFormData(key: "text", type: .text(value: bugReport.text)),
|
||||
MultipartFormData(key: "can_contact", type: .text(value: "\(bugReport.canContact)"))
|
||||
]
|
||||
|
||||
if let userID = bugReport.userID {
|
||||
params.append(.init(key: "user_id", type: .text(value: userID)))
|
||||
}
|
||||
|
||||
if let deviceID = bugReport.deviceID {
|
||||
params.append(.init(key: "device_id", type: .text(value: deviceID)))
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import Foundation
|
||||
import UIKit
|
||||
|
||||
struct BugReport: Equatable {
|
||||
let userID: String
|
||||
let userID: String?
|
||||
let deviceID: String?
|
||||
let text: String
|
||||
let includeLogs: Bool
|
||||
|
@ -137,11 +137,12 @@ class MockScreen: Identifiable {
|
||||
case .authenticationFlow:
|
||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||
let coordinator = AuthenticationCoordinator(authenticationService: MockAuthenticationServiceProxy(),
|
||||
appLockService: AppLockServiceMock(),
|
||||
bugReportService: BugReportServiceMock(),
|
||||
navigationStackCoordinator: navigationStackCoordinator,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
appLockService: AppLockServiceMock())
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
retainedState.append(coordinator)
|
||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
return navigationStackCoordinator
|
||||
|
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.onboarding.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.onboarding.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.onboarding.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.onboarding.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.onboarding.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.onboarding.png
(Stored with Git LFS)
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.onboarding.png
(Stored with Git LFS)
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.onboarding.png
(Stored with Git LFS)
Binary file not shown.
BIN
UnitTests/__Snapshots__/PreviewTests/test_onboardingScreen.1.png
(Stored with Git LFS)
BIN
UnitTests/__Snapshots__/PreviewTests/test_onboardingScreen.1.png
(Stored with Git LFS)
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user