Skip to content

Commit

Permalink
Merge branch 'develop' into mauroromito/can_user_redact_own
Browse files Browse the repository at this point in the history
  • Loading branch information
Velin92 authored Jan 23, 2024
2 parents c0026b5 + 31286c7 commit 2d00e0f
Show file tree
Hide file tree
Showing 38 changed files with 541 additions and 143 deletions.
40 changes: 40 additions & 0 deletions ElementX.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@
"screen_bug_report_include_logs" = "Allow logs";
"screen_bug_report_include_screenshot" = "Send screenshot";
"screen_bug_report_logs_description" = "Logs will be included with your message to make sure that everything is working properly. To send your message without logs, turn off this setting.";
"screen_bug_report_view_logs" = "View logs";
"screen_change_account_provider_matrix_org_subtitle" = "Matrix.org is a large, free server on the public Matrix network for secure, decentralised communication, run by the Matrix.org Foundation.";
"screen_change_account_provider_other" = "Other";
"screen_change_account_provider_subtitle" = "Use a different account provider, such as your own private server or a work account.";
Expand Down
1 change: 1 addition & 0 deletions ElementX/Sources/Application/FlowCoordinatorProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Foundation
// periphery:ignore - markdown protocol
@MainActor
protocol FlowCoordinatorProtocol {
func start()
func handleAppRoute(_ appRoute: AppRoute, animated: Bool)
func clearRoute(animated: Bool)
}
127 changes: 127 additions & 0 deletions ElementX/Sources/FlowCoordinators/BugReportFlowCoordinator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//
// Copyright 2024 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Combine

struct BugReportFlowCoordinatorParameters {
enum PresentationMode {
case sheet(NavigationStackCoordinator)
case push(NavigationStackCoordinator)
}

let presentationMode: PresentationMode
let userIndicatorController: UserIndicatorControllerProtocol
let bugReportService: BugReportServiceProtocol
let userID: String?
let deviceID: String?
}

class BugReportFlowCoordinator: FlowCoordinatorProtocol {
private let parameters: BugReportFlowCoordinatorParameters
private var cancellables = Set<AnyCancellable>()

private var internalNavigationStackCoordinator: NavigationStackCoordinator?

private var isModallyPresented: Bool {
switch parameters.presentationMode {
case .sheet:
return true
case .push:
return false
}
}

init(parameters: BugReportFlowCoordinatorParameters) {
self.parameters = parameters
}

func start() {
presentBugReportScreen()
}

func handleAppRoute(_ appRoute: AppRoute, animated: Bool) {
fatalError()
}

func clearRoute(animated: Bool) {
fatalError()
}

// MARK: - Private

private func presentBugReportScreen() {
let params = BugReportScreenCoordinatorParameters(bugReportService: parameters.bugReportService,
userID: parameters.userID,
deviceID: parameters.deviceID,
userIndicatorController: parameters.userIndicatorController,
screenshot: nil,
isModallyPresented: isModallyPresented)
let coordinator = BugReportScreenCoordinator(parameters: params)
coordinator.actions.sink { [weak self] action in
guard let self else { return }

switch action {
case .cancel:
dismiss()
case .viewLogs:
presentLogViewerScreen()
case .finish:
showSuccess(label: L10n.actionDone)
dismiss()
}
}
.store(in: &cancellables)

switch parameters.presentationMode {
case .sheet(let navigationStackCoordinator):
let internalNavigationStackCoordinator = NavigationStackCoordinator()
internalNavigationStackCoordinator.setRootCoordinator(coordinator)
navigationStackCoordinator.setSheetCoordinator(internalNavigationStackCoordinator)
self.internalNavigationStackCoordinator = internalNavigationStackCoordinator
case .push(let navigationStackCoordinator):
internalNavigationStackCoordinator = navigationStackCoordinator
navigationStackCoordinator.push(coordinator)
}
}

private func presentLogViewerScreen() {
let coordinator = LogViewerScreenCoordinator(parameters: .init())
coordinator.actions.sink { [weak self] action in
guard let self else { return }

switch action {
case .done:
internalNavigationStackCoordinator?.pop()
}
}
.store(in: &cancellables)

internalNavigationStackCoordinator?.push(coordinator)
}

private func dismiss() {
switch parameters.presentationMode {
case .push(let navigationStackCoordinator):
navigationStackCoordinator.pop()
case .sheet(let navigationStackCoordinator):
navigationStackCoordinator.setSheetCoordinator(nil)
}
}

private func showSuccess(label: String) {
parameters.userIndicatorController.submitIndicator(UserIndicator(title: label))
}
}
4 changes: 4 additions & 0 deletions ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {

// MARK: - FlowCoordinatorProtocol

func start() {
fatalError("This flow coordinator expect a route")
}

func handleAppRoute(_ appRoute: AppRoute, animated: Bool) {
switch appRoute {
case .room(let roomID):
Expand Down
56 changes: 21 additions & 35 deletions ElementX/Sources/FlowCoordinators/SettingsFlowCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
// periphery:ignore - retaining purpose
private var appLockSetupFlowCoordinator: AppLockSetupFlowCoordinator?

// periphery:ignore - retaining purpose
private var bugReportFlowCoordinator: BugReportFlowCoordinator?

private let actionsSubject: PassthroughSubject<SettingsFlowCoordinatorAction, Never> = .init()
var actions: AnyPublisher<SettingsFlowCoordinatorAction, Never> {
actionsSubject.eraseToAnyPublisher()
Expand All @@ -57,6 +60,10 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
self.parameters = parameters
}

func start() {
fatalError("Unavailable")
}

func handleAppRoute(_ appRoute: AppRoute, animated: Bool) {
switch appRoute {
case .settings:
Expand All @@ -76,27 +83,27 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
}
}

func clearRoute(animated: Bool) { }
func clearRoute(animated: Bool) {
fatalError("Unavailable")
}

// MARK: - Private

private func presentSettingsScreen(animated: Bool) {
navigationStackCoordinator = NavigationStackCoordinator()

let parameters = SettingsScreenCoordinatorParameters(userSession: parameters.userSession,
appSettings: parameters.appSettings)

let settingsScreenCoordinator = SettingsScreenCoordinator(parameters: parameters)
let settingsScreenCoordinator = SettingsScreenCoordinator(parameters: .init(userSession: parameters.userSession,
appSettings: parameters.appSettings))

settingsScreenCoordinator.actions
.sink { [weak self] action in
guard let self else { return }

switch action {
case .dismiss:
self.parameters.navigationSplitCoordinator.setSheetCoordinator(nil)
parameters.navigationSplitCoordinator.setSheetCoordinator(nil)
case .logout:
self.parameters.navigationSplitCoordinator.setSheetCoordinator(nil)
parameters.navigationSplitCoordinator.setSheetCoordinator(nil)

// The settings sheet needs to be dismissed before the alert can be shown
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
Expand All @@ -113,7 +120,12 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
case .appLock:
presentAppLockSetupFlow()
case .bugReport:
presentBugReportScreen()
bugReportFlowCoordinator = BugReportFlowCoordinator(parameters: .init(presentationMode: .push(navigationStackCoordinator),
userIndicatorController: parameters.userIndicatorController,
bugReportService: parameters.bugReportService,
userID: parameters.userSession.userID,
deviceID: parameters.userSession.deviceID))
bugReportFlowCoordinator?.start()
case .about:
presentLegalInformationScreen()
case .sessionVerification:
Expand All @@ -132,7 +144,7 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {

navigationStackCoordinator.setRootCoordinator(settingsScreenCoordinator, animated: animated)

self.parameters.navigationSplitCoordinator.setSheetCoordinator(navigationStackCoordinator) { [weak self] in
parameters.navigationSplitCoordinator.setSheetCoordinator(navigationStackCoordinator) { [weak self] in
guard let self else { return }

navigationStackCoordinator = nil
Expand Down Expand Up @@ -187,28 +199,6 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
coordinator.start()
}

private func presentBugReportScreen() {
let params = BugReportScreenCoordinatorParameters(bugReportService: parameters.bugReportService,
userID: parameters.userSession.userID,
deviceID: parameters.userSession.deviceID,
userIndicatorController: parameters.userIndicatorController,
screenshot: nil,
isModallyPresented: false)
let coordinator = BugReportScreenCoordinator(parameters: params)
coordinator.completion = { [weak self] result in
switch result {
case .finish:
self?.showSuccess(label: L10n.actionDone)
default:
break
}

self?.navigationStackCoordinator.pop()
}

navigationStackCoordinator.push(coordinator)
}

private func presentLegalInformationScreen() {
navigationStackCoordinator.push(LegalInformationScreenCoordinator(appSettings: parameters.appSettings))
}
Expand Down Expand Up @@ -269,10 +259,6 @@ class SettingsFlowCoordinator: FlowCoordinatorProtocol {
navigationStackCoordinator.push(coordinator)
}

private func showSuccess(label: String) {
parameters.userIndicatorController.submitIndicator(UserIndicator(title: label))
}

// MARK: OIDC Account Management

private func presentAccountProfileURL() {
Expand Down
35 changes: 11 additions & 24 deletions ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
private let actionsSubject: PassthroughSubject<UserSessionFlowCoordinatorAction, Never> = .init()

private let stateMachine: UserSessionFlowCoordinatorStateMachine

private let roomFlowCoordinator: RoomFlowCoordinator

private let settingsFlowCoordinator: SettingsFlowCoordinator

// periphery:ignore - retaining purpose
private var bugReportFlowCoordinator: BugReportFlowCoordinator?

private var cancellables = Set<AnyCancellable>()
private var migrationCancellable: AnyCancellable?

Expand Down Expand Up @@ -250,7 +255,12 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
break

case (.roomList, .feedbackScreen, .feedbackScreen):
presentFeedbackScreen(animated: animated)
bugReportFlowCoordinator = BugReportFlowCoordinator(parameters: .init(presentationMode: .sheet(sidebarNavigationStackCoordinator),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
bugReportService: bugReportService,
userID: userSession.userID,
deviceID: userSession.deviceID))
bugReportFlowCoordinator?.start()
case (.feedbackScreen, .dismissedFeedbackScreen, .roomList):
break

Expand Down Expand Up @@ -483,30 +493,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
self?.stateMachine.processEvent(.dismissedStartChatScreen)
}
}

// MARK: Bug reporting

private func presentFeedbackScreen(animated: Bool, for image: UIImage? = nil) {
let feedbackNavigationStackCoordinator = NavigationStackCoordinator()

let parameters = BugReportScreenCoordinatorParameters(bugReportService: bugReportService,
userID: userSession.userID,
deviceID: userSession.deviceID,
userIndicatorController: ServiceLocator.shared.userIndicatorController,
screenshot: image,
isModallyPresented: true)
let coordinator = BugReportScreenCoordinator(parameters: parameters)
coordinator.completion = { [weak self] _ in
self?.navigationSplitCoordinator.setSheetCoordinator(nil)
}

feedbackNavigationStackCoordinator.setRootCoordinator(coordinator)

navigationSplitCoordinator.setSheetCoordinator(feedbackNavigationStackCoordinator, animated: animated) { [weak self] in
self?.stateMachine.processEvent(.dismissedFeedbackScreen)
}
}

// MARK: Invites list

private func presentInvitesList(animated: Bool) {
Expand Down
2 changes: 2 additions & 0 deletions ElementX/Sources/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,8 @@ public enum L10n {
public static func screenBugReportRashLogsAlertTitle(_ p1: Any) -> String {
return L10n.tr("Localizable", "screen_bug_report_rash_logs_alert_title", String(describing: p1))
}
/// View logs
public static var screenBugReportViewLogs: String { return L10n.tr("Localizable", "screen_bug_report_view_logs") }
/// Matrix.org is a large, free server on the public Matrix network for secure, decentralised communication, run by the Matrix.org Foundation.
public static var screenChangeAccountProviderMatrixOrgSubtitle: String { return L10n.tr("Localizable", "screen_change_account_provider_matrix_org_subtitle") }
/// Other
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,13 @@ class AuthenticationCoordinator: CoordinatorProtocol {
private var cancellables = Set<AnyCancellable>()

private var oidcPresenter: OIDCAuthenticationPresenter?

// periphery: ignore - used to store the coordinator to avoid deallocation
private var appLockFlowCoordinator: AppLockSetupFlowCoordinator?

// periphery:ignore - retaining purpose
private var bugReportFlowCoordinator: BugReportFlowCoordinator?

weak var delegate: AuthenticationCoordinatorDelegate?

init(authenticationService: AuthenticationServiceProxyProtocol,
Expand Down Expand Up @@ -94,24 +98,12 @@ class AuthenticationCoordinator: CoordinatorProtocol {
}

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)
bugReportFlowCoordinator = BugReportFlowCoordinator(parameters: .init(presentationMode: .sheet(navigationStackCoordinator),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
bugReportService: bugReportService,
userID: nil,
deviceID: nil))
bugReportFlowCoordinator?.start()
}

private func startAuthentication() async {
Expand Down
Loading

0 comments on commit 2d00e0f

Please sign in to comment.