130 lines
4.4 KiB
Swift
130 lines
4.4 KiB
Swift
//
|
|
// RootDebug.swift
|
|
// secant
|
|
//
|
|
// Created by Lukáš Korba on 02.03.2023.
|
|
//
|
|
|
|
import Combine
|
|
import ComposableArchitecture
|
|
import Foundation
|
|
import ZcashLightClientKit
|
|
import Generated
|
|
import Models
|
|
import Pasteboard
|
|
|
|
/// In this file is a collection of helpers that control all state and action related operations
|
|
/// for the `Root` with a connection to the UI navigation.
|
|
extension Root {
|
|
public struct DebugState { }
|
|
|
|
public indirect enum DebugAction {
|
|
case cancelRescan
|
|
case cantStartSync(ZcashError)
|
|
case copySeedToPasteboard
|
|
case flagUpdated
|
|
case rateTheApp
|
|
case rescanBlockchain
|
|
case rewindDone(ZcashError?, Root.Action)
|
|
case updateFlag(FeatureFlag, Bool)
|
|
case walletConfigLoaded(WalletConfig)
|
|
}
|
|
|
|
// swiftlint:disable:next cyclomatic_complexity
|
|
public func debugReduce() -> Reduce<Root.State, Root.Action> {
|
|
Reduce { state, action in
|
|
switch action {
|
|
case .debug(.rescanBlockchain):
|
|
state.confirmationDialog = ConfirmationDialogState.rescanRequest()
|
|
return .none
|
|
|
|
case .debug(.cancelRescan):
|
|
state.confirmationDialog = nil
|
|
return .none
|
|
|
|
case .confirmationDialog(.presented(.quickRescan)):
|
|
state.destinationState.destination = .home
|
|
return rewind(policy: .quick, sourceAction: .quickRescan)
|
|
|
|
case .confirmationDialog(.presented(.fullRescan)):
|
|
state.destinationState.destination = .home
|
|
return rewind(policy: .birthday, sourceAction: .fullRescan)
|
|
|
|
case let .debug(.rewindDone(error, _)):
|
|
if let error {
|
|
state.alert = AlertState.rewindFailed(error.toZcashError())
|
|
return .none
|
|
} else {
|
|
return .run { send in
|
|
do {
|
|
try await sdkSynchronizer.start(false)
|
|
} catch {
|
|
await send(.debug(.cantStartSync(error.toZcashError())))
|
|
}
|
|
}
|
|
}
|
|
|
|
case let .debug(.updateFlag(flag, isEnabled)):
|
|
return .publisher {
|
|
walletConfigProvider.update(flag, !isEnabled)
|
|
.receive(on: mainQueue)
|
|
.map { _ in return Action.debug(.flagUpdated) }
|
|
}
|
|
.cancellable(id: WalletConfigCancelId, cancelInFlight: true)
|
|
|
|
case .debug(.flagUpdated):
|
|
return .publisher {
|
|
walletConfigProvider.load()
|
|
.receive(on: mainQueue)
|
|
.map { Action.debug(.walletConfigLoaded($0)) }
|
|
}
|
|
.cancellable(id: WalletConfigCancelId, cancelInFlight: true)
|
|
|
|
case .debug(.copySeedToPasteboard):
|
|
let storedWallet = try? walletStorage.exportWallet()
|
|
guard let phrase = storedWallet?.seedPhrase.value() else { return .none }
|
|
pasteboard.setString(phrase.redacted)
|
|
return .none
|
|
|
|
case let .debug(.walletConfigLoaded(walletConfig)):
|
|
return .send(.updateStateAfterConfigUpdate(walletConfig))
|
|
|
|
case .debug(.cantStartSync(let error)):
|
|
state.alert = AlertState.cantStartSync(error)
|
|
return .none
|
|
|
|
case .debug(.rateTheApp):
|
|
return .none
|
|
|
|
default: return .none
|
|
}
|
|
}
|
|
}
|
|
|
|
private func rewind(policy: RewindPolicy, sourceAction: Action.ConfirmationDialog) -> Effect<Root.Action> {
|
|
Effect.publisher {
|
|
sdkSynchronizer.rewind(policy)
|
|
.replaceEmpty(with: Void())
|
|
.map { _ in
|
|
Root.Action.debug(.rewindDone(nil, .confirmationDialog(.presented(sourceAction))))
|
|
}
|
|
.catch { error in
|
|
Just(
|
|
Root.Action.debug(.rewindDone(error.toZcashError(), .confirmationDialog(.presented(sourceAction))))
|
|
)
|
|
.eraseToAnyPublisher()
|
|
}
|
|
.receive(on: mainQueue)
|
|
}
|
|
.cancellable(id: SynchronizerCancelId, cancelInFlight: true)
|
|
}
|
|
}
|
|
|
|
// MARK: Placeholders
|
|
|
|
extension Root.DebugState {
|
|
public static var initial: Self {
|
|
.init()
|
|
}
|
|
}
|