Allow reporting a problem from the onboarding screen
This commit is contained in:
@@ -398,11 +398,12 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
|
|||||||
encryptionKeyProvider: EncryptionKeyProvider(),
|
encryptionKeyProvider: EncryptionKeyProvider(),
|
||||||
appSettings: appSettings)
|
appSettings: appSettings)
|
||||||
authenticationCoordinator = AuthenticationCoordinator(authenticationService: authenticationService,
|
authenticationCoordinator = AuthenticationCoordinator(authenticationService: authenticationService,
|
||||||
|
appLockService: appLockFlowCoordinator.appLockService,
|
||||||
|
bugReportService: ServiceLocator.shared.bugReportService,
|
||||||
navigationStackCoordinator: authenticationNavigationStackCoordinator,
|
navigationStackCoordinator: authenticationNavigationStackCoordinator,
|
||||||
appSettings: appSettings,
|
appSettings: appSettings,
|
||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||||
appLockService: appLockFlowCoordinator.appLockService)
|
|
||||||
authenticationCoordinator?.delegate = self
|
authenticationCoordinator?.delegate = self
|
||||||
|
|
||||||
authenticationCoordinator?.start()
|
authenticationCoordinator?.start()
|
||||||
|
|||||||
@@ -24,11 +24,12 @@ protocol AuthenticationCoordinatorDelegate: AnyObject {
|
|||||||
|
|
||||||
class AuthenticationCoordinator: CoordinatorProtocol {
|
class AuthenticationCoordinator: CoordinatorProtocol {
|
||||||
private let authenticationService: AuthenticationServiceProxyProtocol
|
private let authenticationService: AuthenticationServiceProxyProtocol
|
||||||
|
private let appLockService: AppLockServiceProtocol
|
||||||
|
private let bugReportService: BugReportServiceProtocol
|
||||||
private let navigationStackCoordinator: NavigationStackCoordinator
|
private let navigationStackCoordinator: NavigationStackCoordinator
|
||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
private let analytics: AnalyticsService
|
private let analytics: AnalyticsService
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
private let appLockService: AppLockServiceProtocol
|
|
||||||
|
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
@@ -39,17 +40,19 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
|||||||
weak var delegate: AuthenticationCoordinatorDelegate?
|
weak var delegate: AuthenticationCoordinatorDelegate?
|
||||||
|
|
||||||
init(authenticationService: AuthenticationServiceProxyProtocol,
|
init(authenticationService: AuthenticationServiceProxyProtocol,
|
||||||
|
appLockService: AppLockServiceProtocol,
|
||||||
|
bugReportService: BugReportServiceProtocol,
|
||||||
navigationStackCoordinator: NavigationStackCoordinator,
|
navigationStackCoordinator: NavigationStackCoordinator,
|
||||||
appSettings: AppSettings,
|
appSettings: AppSettings,
|
||||||
analytics: AnalyticsService,
|
analytics: AnalyticsService,
|
||||||
userIndicatorController: UserIndicatorControllerProtocol,
|
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||||
appLockService: AppLockServiceProtocol) {
|
|
||||||
self.authenticationService = authenticationService
|
self.authenticationService = authenticationService
|
||||||
|
self.appLockService = appLockService
|
||||||
|
self.bugReportService = bugReportService
|
||||||
self.navigationStackCoordinator = navigationStackCoordinator
|
self.navigationStackCoordinator = navigationStackCoordinator
|
||||||
self.appSettings = appSettings
|
self.appSettings = appSettings
|
||||||
self.analytics = analytics
|
self.analytics = analytics
|
||||||
self.userIndicatorController = userIndicatorController
|
self.userIndicatorController = userIndicatorController
|
||||||
self.appLockService = appLockService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func start() {
|
func start() {
|
||||||
@@ -81,6 +84,8 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
|||||||
switch action {
|
switch action {
|
||||||
case .login:
|
case .login:
|
||||||
Task { await self.startAuthentication() }
|
Task { await self.startAuthentication() }
|
||||||
|
case .reportProblem:
|
||||||
|
showReportProblemScreen()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
@@ -88,6 +93,27 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
|||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
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 {
|
private func startAuthentication() async {
|
||||||
startLoading()
|
startLoading()
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ enum BugReportScreenCoordinatorResult {
|
|||||||
|
|
||||||
struct BugReportScreenCoordinatorParameters {
|
struct BugReportScreenCoordinatorParameters {
|
||||||
let bugReportService: BugReportServiceProtocol
|
let bugReportService: BugReportServiceProtocol
|
||||||
let userID: String
|
let userID: String?
|
||||||
let deviceID: String?
|
let deviceID: String?
|
||||||
|
|
||||||
let userIndicatorController: UserIndicatorControllerProtocol?
|
let userIndicatorController: UserIndicatorControllerProtocol?
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ typealias BugReportScreenViewModelType = StateStoreViewModel<BugReportScreenView
|
|||||||
|
|
||||||
class BugReportScreenViewModel: BugReportScreenViewModelType, BugReportScreenViewModelProtocol {
|
class BugReportScreenViewModel: BugReportScreenViewModelType, BugReportScreenViewModelProtocol {
|
||||||
private let bugReportService: BugReportServiceProtocol
|
private let bugReportService: BugReportServiceProtocol
|
||||||
private let userID: String
|
private let userID: String?
|
||||||
private let deviceID: String?
|
private let deviceID: String?
|
||||||
private let actionsSubject: PassthroughSubject<BugReportScreenViewModelAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<BugReportScreenViewModelAction, Never> = .init()
|
||||||
// periphery:ignore - when set to nil this is automatically cancelled
|
// periphery:ignore - when set to nil this is automatically cancelled
|
||||||
@@ -32,7 +32,7 @@ class BugReportScreenViewModel: BugReportScreenViewModelType, BugReportScreenVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(bugReportService: BugReportServiceProtocol,
|
init(bugReportService: BugReportServiceProtocol,
|
||||||
userID: String,
|
userID: String?,
|
||||||
deviceID: String?,
|
deviceID: String?,
|
||||||
screenshot: UIImage?,
|
screenshot: UIImage?,
|
||||||
isModallyPresented: Bool) {
|
isModallyPresented: Bool) {
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ final class OnboardingScreenCoordinator: CoordinatorProtocol {
|
|||||||
switch action {
|
switch action {
|
||||||
case .login:
|
case .login:
|
||||||
actionsSubject.send(.login)
|
actionsSubject.send(.login)
|
||||||
|
case .reportProblem:
|
||||||
|
actionsSubject.send(.reportProblem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|||||||
@@ -20,14 +20,17 @@ import SwiftUI
|
|||||||
|
|
||||||
enum OnboardingScreenCoordinatorAction {
|
enum OnboardingScreenCoordinatorAction {
|
||||||
case login
|
case login
|
||||||
|
case reportProblem
|
||||||
}
|
}
|
||||||
|
|
||||||
enum OnboardingScreenViewModelAction {
|
enum OnboardingScreenViewModelAction {
|
||||||
case login
|
case login
|
||||||
|
case reportProblem
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OnboardingScreenViewState: BindableState { }
|
struct OnboardingScreenViewState: BindableState { }
|
||||||
|
|
||||||
enum OnboardingScreenViewAction {
|
enum OnboardingScreenViewAction {
|
||||||
case login
|
case login
|
||||||
|
case reportProblem
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ class OnboardingScreenViewModel: OnboardingScreenViewModelType, OnboardingScreen
|
|||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .login:
|
case .login:
|
||||||
actionsSubject.send(.login)
|
actionsSubject.send(.login)
|
||||||
|
case .reportProblem:
|
||||||
|
actionsSubject.send(.reportProblem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,16 @@ struct OnboardingScreen: View {
|
|||||||
.frame(height: UIConstants.spacerHeight(in: geometry))
|
.frame(height: UIConstants.spacerHeight(in: geometry))
|
||||||
}
|
}
|
||||||
.frame(maxHeight: .infinity)
|
.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)
|
.navigationBarHidden(true)
|
||||||
.background {
|
.background {
|
||||||
|
|||||||
@@ -119,11 +119,14 @@ class BugReportService: NSObject, BugReportServiceProtocol {
|
|||||||
func submitBugReport(_ bugReport: BugReport,
|
func submitBugReport(_ bugReport: BugReport,
|
||||||
progressListener: CurrentValueSubject<Double, Never>) async -> Result<SubmitBugReportResponse, BugReportServiceError> {
|
progressListener: CurrentValueSubject<Double, Never>) async -> Result<SubmitBugReportResponse, BugReportServiceError> {
|
||||||
var params = [
|
var params = [
|
||||||
MultipartFormData(key: "user_id", type: .text(value: bugReport.userID)),
|
|
||||||
MultipartFormData(key: "text", type: .text(value: bugReport.text)),
|
MultipartFormData(key: "text", type: .text(value: bugReport.text)),
|
||||||
MultipartFormData(key: "can_contact", type: .text(value: "\(bugReport.canContact)"))
|
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 {
|
if let deviceID = bugReport.deviceID {
|
||||||
params.append(.init(key: "device_id", type: .text(value: deviceID)))
|
params.append(.init(key: "device_id", type: .text(value: deviceID)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
struct BugReport: Equatable {
|
struct BugReport: Equatable {
|
||||||
let userID: String
|
let userID: String?
|
||||||
let deviceID: String?
|
let deviceID: String?
|
||||||
let text: String
|
let text: String
|
||||||
let includeLogs: Bool
|
let includeLogs: Bool
|
||||||
|
|||||||
@@ -137,11 +137,12 @@ class MockScreen: Identifiable {
|
|||||||
case .authenticationFlow:
|
case .authenticationFlow:
|
||||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||||
let coordinator = AuthenticationCoordinator(authenticationService: MockAuthenticationServiceProxy(),
|
let coordinator = AuthenticationCoordinator(authenticationService: MockAuthenticationServiceProxy(),
|
||||||
|
appLockService: AppLockServiceMock(),
|
||||||
|
bugReportService: BugReportServiceMock(),
|
||||||
navigationStackCoordinator: navigationStackCoordinator,
|
navigationStackCoordinator: navigationStackCoordinator,
|
||||||
appSettings: ServiceLocator.shared.settings,
|
appSettings: ServiceLocator.shared.settings,
|
||||||
analytics: ServiceLocator.shared.analytics,
|
analytics: ServiceLocator.shared.analytics,
|
||||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||||
appLockService: AppLockServiceMock())
|
|
||||||
retainedState.append(coordinator)
|
retainedState.append(coordinator)
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:ce9979e0f1ad3ae45fac19da8d790a4b92de31ad56d07d7735b88407c354e48e
|
oid sha256:b0df6a86517b6c8c5e45d7a77ad323c7730178fdc6523f52068748b5d81eca3b
|
||||||
size 1276288
|
size 1276372
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:392d7264ceb22146a4a066ccd46a75a37c06789966bc49f23fb2fe0c23358a2b
|
oid sha256:279e06e9fbfb8670fecd2ad88f6486402067e5eb1788a5db2f7420a88adaf2d4
|
||||||
size 990811
|
size 1000272
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:3480e47e56d9487354e552fd2dc8236d48781d6f9f8dfed2b7b63c5cbe2a9448
|
oid sha256:d2de5fced9093eeef584c2c1ee3b2296e9201cb0c8132672bce778389bbae036
|
||||||
size 1296599
|
size 1298519
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:1e8c2594242d3ea72a46202703f84c0920d41491c36f12c85aeb9d54fd3f9625
|
oid sha256:b829d6b34f1bb1600e5ccefbf4f7c04fba4b1fad73671cf648ab72ae49e012de
|
||||||
size 1013586
|
size 1025995
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5f932bf95aeacda33b053111d5db67dacc992eb8cf3daedd193bc54c3edfc658
|
oid sha256:2413b7707aa285dd909981b20f7d5dbcb421ab469c217de1c1facb9bdd5b517b
|
||||||
size 828166
|
size 832592
|
||||||
|
|||||||
Reference in New Issue
Block a user