[#1191] Refactor AdvancedSettingsReducer to latest TCA
- The reducer has been refactored - The Bindings have been refactored to not use deprecated API - View has been refactored to not rely on ViewStore - Dependency version have been bumped up in order to use latest TCA
This commit is contained in:
parent
ecad037103
commit
d46d0a4f94
|
@ -67,12 +67,12 @@ let package = Package(
|
|||
.library(name: "ZcashSDKEnvironment", targets: ["ZcashSDKEnvironment"])
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/pointfreeco/swift-composable-architecture", from: "1.7.0"),
|
||||
.package(url: "https://github.com/pointfreeco/swift-case-paths", from: "1.1.0"),
|
||||
.package(url: "https://github.com/pointfreeco/swift-composable-architecture", from: "1.9.2"),
|
||||
.package(url: "https://github.com/pointfreeco/swift-case-paths", from: "1.3.2"),
|
||||
.package(url: "https://github.com/pointfreeco/swift-url-routing", from: "0.6.0"),
|
||||
.package(url: "https://github.com/zcash-hackworks/MnemonicSwift", from: "2.2.4"),
|
||||
.package(url: "https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk", from: "2.1.3"),
|
||||
.package(url: "https://github.com/firebase/firebase-ios-sdk", from: "10.17.0")
|
||||
.package(url: "https://github.com/firebase/firebase-ios-sdk", from: "10.24.0")
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
|
|
|
@ -12,10 +12,9 @@ import RestoreWalletStorage
|
|||
import ServerSetup
|
||||
import ZcashLightClientKit
|
||||
|
||||
public typealias AdvancedSettingsStore = Store<AdvancedSettingsReducer.State, AdvancedSettingsReducer.Action>
|
||||
public typealias AdvancedSettingsViewStore = ViewStore<AdvancedSettingsReducer.State, AdvancedSettingsReducer.Action>
|
||||
|
||||
public struct AdvancedSettingsReducer: Reducer {
|
||||
@Reducer
|
||||
public struct AdvancedSettings {
|
||||
@ObservableState
|
||||
public struct State: Equatable {
|
||||
public enum Destination {
|
||||
case backupPhrase
|
||||
|
@ -56,7 +55,7 @@ public struct AdvancedSettingsReducer: Reducer {
|
|||
case restoreWalletTask
|
||||
case restoreWalletValue(Bool)
|
||||
case serverSetup(ServerSetup.Action)
|
||||
case updateDestination(AdvancedSettingsReducer.State.Destination?)
|
||||
case updateDestination(AdvancedSettings.State.Destination?)
|
||||
}
|
||||
|
||||
@Dependency(\.localAuthentication) var localAuthentication
|
||||
|
@ -73,7 +72,7 @@ public struct AdvancedSettingsReducer: Reducer {
|
|||
await send(.updateDestination(.backupPhrase))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case .deleteWallet:
|
||||
return .none
|
||||
|
||||
|
@ -138,110 +137,3 @@ public struct AdvancedSettingsReducer: Reducer {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - ViewStore
|
||||
|
||||
extension AdvancedSettingsViewStore {
|
||||
var destinationBinding: Binding<AdvancedSettingsReducer.State.Destination?> {
|
||||
self.binding(
|
||||
get: \.destination,
|
||||
send: AdvancedSettingsReducer.Action.updateDestination
|
||||
)
|
||||
}
|
||||
|
||||
var bindingForBackupPhrase: Binding<Bool> {
|
||||
self.destinationBinding.map(
|
||||
extract: { $0 == .backupPhrase },
|
||||
embed: { $0 ? .backupPhrase : nil }
|
||||
)
|
||||
}
|
||||
|
||||
var bindingForPrivateDataConsent: Binding<Bool> {
|
||||
self.destinationBinding.map(
|
||||
extract: { $0 == .privateDataConsent },
|
||||
embed: { $0 ? .privateDataConsent : nil }
|
||||
)
|
||||
}
|
||||
|
||||
var bindingForServerSetup: Binding<Bool> {
|
||||
self.destinationBinding.map(
|
||||
extract: { $0 == .serverSetup },
|
||||
embed: { $0 ? .serverSetup : nil }
|
||||
)
|
||||
}
|
||||
|
||||
var bindingDeleteWallet: Binding<Bool> {
|
||||
self.destinationBinding.map(
|
||||
extract: { $0 == .deleteWallet },
|
||||
embed: { $0 ? .deleteWallet : nil }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Store
|
||||
|
||||
extension AdvancedSettingsStore {
|
||||
func backupPhraseStore() -> StoreOf<RecoveryPhraseDisplay> {
|
||||
self.scope(
|
||||
state: \.phraseDisplayState,
|
||||
action: AdvancedSettingsReducer.Action.phraseDisplay
|
||||
)
|
||||
}
|
||||
|
||||
func privateDataConsentStore() -> PrivateDataConsentStore {
|
||||
self.scope(
|
||||
state: \.privateDataConsentState,
|
||||
action: AdvancedSettingsReducer.Action.privateDataConsent
|
||||
)
|
||||
}
|
||||
|
||||
func serverSetupStore() -> StoreOf<ServerSetup> {
|
||||
self.scope(
|
||||
state: \.serverSetupState,
|
||||
action: AdvancedSettingsReducer.Action.serverSetup
|
||||
)
|
||||
}
|
||||
|
||||
func deleteWalletStore() -> StoreOf<DeleteWallet> {
|
||||
self.scope(
|
||||
state: \.deleteWallet,
|
||||
action: AdvancedSettingsReducer.Action.deleteWallet
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Placeholders
|
||||
|
||||
extension AdvancedSettingsReducer.State {
|
||||
public static let initial = AdvancedSettingsReducer.State(
|
||||
deleteWallet: .initial,
|
||||
phraseDisplayState: RecoveryPhraseDisplay.State(
|
||||
phrase: nil,
|
||||
showBackButton: false,
|
||||
birthday: nil
|
||||
),
|
||||
privateDataConsentState: .initial,
|
||||
serverSetupState: ServerSetup.State()
|
||||
)
|
||||
}
|
||||
|
||||
extension AdvancedSettingsStore {
|
||||
public static let placeholder = AdvancedSettingsStore(
|
||||
initialState: .initial
|
||||
) {
|
||||
AdvancedSettingsReducer()
|
||||
}
|
||||
|
||||
public static let demo = AdvancedSettingsStore(
|
||||
initialState: .init(
|
||||
deleteWallet: .initial,
|
||||
phraseDisplayState: RecoveryPhraseDisplay.State(
|
||||
phrase: nil,
|
||||
birthday: nil
|
||||
),
|
||||
privateDataConsentState: .initial,
|
||||
serverSetupState: ServerSetup.State()
|
||||
)
|
||||
) {
|
||||
AdvancedSettingsReducer()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,62 +16,56 @@ import PrivateDataConsent
|
|||
import ServerSetup
|
||||
|
||||
public struct AdvancedSettingsView: View {
|
||||
@State private var isRestoringWalletBadgeOn = false
|
||||
|
||||
let store: AdvancedSettingsStore
|
||||
@Perception.Bindable var store: StoreOf<AdvancedSettings>
|
||||
|
||||
public init(store: AdvancedSettingsStore) {
|
||||
public init(store: StoreOf<AdvancedSettings>) {
|
||||
self.store = store
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
VStack {
|
||||
WithViewStore(store, observe: { $0 }) { viewStore in
|
||||
WithPerceptionTracking {
|
||||
VStack {
|
||||
Button(L10n.Settings.recoveryPhrase.uppercased()) {
|
||||
viewStore.send(.backupWalletAccessRequest)
|
||||
store.send(.backupWalletAccessRequest)
|
||||
}
|
||||
.zcashStyle()
|
||||
.padding(.vertical, 25)
|
||||
.padding(.top, 40)
|
||||
.padding(.horizontal, 70)
|
||||
.navigationLinkEmpty(
|
||||
isActive: viewStore.bindingForBackupPhrase,
|
||||
isActive: store.bindingForBackupPhrase,
|
||||
destination: {
|
||||
RecoveryPhraseDisplayView(store: store.backupPhraseStore())
|
||||
}
|
||||
)
|
||||
.navigationLinkEmpty(
|
||||
isActive: viewStore.bindingForPrivateDataConsent,
|
||||
isActive: store.bindingForPrivateDataConsent,
|
||||
destination: {
|
||||
PrivateDataConsentView(store: store.privateDataConsentStore())
|
||||
}
|
||||
)
|
||||
.navigationLinkEmpty(
|
||||
isActive: viewStore.bindingForServerSetup,
|
||||
isActive: store.bindingForServerSetup,
|
||||
destination: {
|
||||
ServerSetupView(store: store.serverSetupStore())
|
||||
}
|
||||
)
|
||||
.navigationLinkEmpty(
|
||||
isActive: viewStore.bindingDeleteWallet,
|
||||
isActive: store.bindingDeleteWallet,
|
||||
destination: {
|
||||
DeleteWalletView(store: store.deleteWalletStore())
|
||||
}
|
||||
)
|
||||
.onAppear {
|
||||
isRestoringWalletBadgeOn = viewStore.isRestoringWallet
|
||||
}
|
||||
.onChange(of: viewStore.isRestoringWallet) { isRestoringWalletBadgeOn = $0 }
|
||||
.padding(.horizontal, 70)
|
||||
|
||||
Button(L10n.Settings.exportPrivateData.uppercased()) {
|
||||
viewStore.send(.updateDestination(.privateDataConsent))
|
||||
store.send(.updateDestination(.privateDataConsent))
|
||||
}
|
||||
.zcashStyle()
|
||||
.padding(.bottom, 25)
|
||||
.padding(.horizontal, 70)
|
||||
|
||||
Button(L10n.Settings.chooseServer.uppercased()) {
|
||||
viewStore.send(.updateDestination(.serverSetup))
|
||||
store.send(.updateDestination(.serverSetup))
|
||||
}
|
||||
.zcashStyle()
|
||||
.padding(.horizontal, 70)
|
||||
|
@ -79,7 +73,7 @@ public struct AdvancedSettingsView: View {
|
|||
Spacer()
|
||||
|
||||
Button(L10n.Settings.deleteZashi.uppercased()) {
|
||||
viewStore.send(.updateDestination(.deleteWallet))
|
||||
store.send(.updateDestination(.deleteWallet))
|
||||
}
|
||||
.zcashStyle()
|
||||
.padding(.bottom, 20)
|
||||
|
@ -99,7 +93,7 @@ public struct AdvancedSettingsView: View {
|
|||
.resizable()
|
||||
.frame(width: 62, height: 17)
|
||||
}
|
||||
.restoringWalletBadge(isOn: isRestoringWalletBadgeOn)
|
||||
.restoringWalletBadge(isOn: store.isRestoringWallet)
|
||||
.task { await store.send(.restoreWalletTask).finish() }
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +102,110 @@ public struct AdvancedSettingsView: View {
|
|||
|
||||
#Preview {
|
||||
NavigationView {
|
||||
AdvancedSettingsView(store: .placeholder)
|
||||
AdvancedSettingsView(store: .initial)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - ViewStore
|
||||
extension StoreOf<AdvancedSettings> {
|
||||
var destinationBinding: Binding<AdvancedSettings.State.Destination?> {
|
||||
Binding {
|
||||
self.state.destination
|
||||
} set: {
|
||||
self.send(.updateDestination($0))
|
||||
}
|
||||
}
|
||||
|
||||
var bindingForBackupPhrase: Binding<Bool> {
|
||||
self.destinationBinding.map(
|
||||
extract: { $0 == .backupPhrase },
|
||||
embed: { $0 ? .backupPhrase : nil }
|
||||
)
|
||||
}
|
||||
|
||||
var bindingForPrivateDataConsent: Binding<Bool> {
|
||||
self.destinationBinding.map(
|
||||
extract: { $0 == .privateDataConsent },
|
||||
embed: { $0 ? .privateDataConsent : nil }
|
||||
)
|
||||
}
|
||||
|
||||
var bindingForServerSetup: Binding<Bool> {
|
||||
self.destinationBinding.map(
|
||||
extract: { $0 == .serverSetup },
|
||||
embed: { $0 ? .serverSetup : nil }
|
||||
)
|
||||
}
|
||||
|
||||
var bindingDeleteWallet: Binding<Bool> {
|
||||
self.destinationBinding.map(
|
||||
extract: { $0 == .deleteWallet },
|
||||
embed: { $0 ? .deleteWallet : nil }
|
||||
)
|
||||
}
|
||||
|
||||
func backupPhraseStore() -> StoreOf<RecoveryPhraseDisplay> {
|
||||
self.scope(
|
||||
state: \.phraseDisplayState,
|
||||
action: \.phraseDisplay
|
||||
)
|
||||
}
|
||||
|
||||
func privateDataConsentStore() -> PrivateDataConsentStore {
|
||||
self.scope(
|
||||
state: \.privateDataConsentState,
|
||||
action: \.privateDataConsent
|
||||
)
|
||||
}
|
||||
|
||||
func serverSetupStore() -> StoreOf<ServerSetup> {
|
||||
self.scope(
|
||||
state: \.serverSetupState,
|
||||
action: \.serverSetup
|
||||
)
|
||||
}
|
||||
|
||||
func deleteWalletStore() -> StoreOf<DeleteWallet> {
|
||||
self.scope(
|
||||
state: \.deleteWallet,
|
||||
action: \.deleteWallet
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Placeholders
|
||||
|
||||
extension AdvancedSettings.State {
|
||||
public static let initial = AdvancedSettings.State(
|
||||
deleteWallet: .initial,
|
||||
phraseDisplayState: RecoveryPhraseDisplay.State(
|
||||
phrase: nil,
|
||||
showBackButton: false,
|
||||
birthday: nil
|
||||
),
|
||||
privateDataConsentState: .initial,
|
||||
serverSetupState: ServerSetup.State()
|
||||
)
|
||||
}
|
||||
|
||||
extension StoreOf<AdvancedSettings> {
|
||||
public static let initial = StoreOf<AdvancedSettings>(
|
||||
initialState: .initial
|
||||
) {
|
||||
AdvancedSettings()
|
||||
}
|
||||
|
||||
public static let demo = StoreOf<AdvancedSettings>(
|
||||
initialState: .init(
|
||||
deleteWallet: .initial,
|
||||
phraseDisplayState: RecoveryPhraseDisplay.State(
|
||||
phrase: nil,
|
||||
birthday: nil
|
||||
),
|
||||
privateDataConsentState: .initial,
|
||||
serverSetupState: ServerSetup.State()
|
||||
)
|
||||
) {
|
||||
AdvancedSettings()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ public struct SettingsReducer: Reducer {
|
|||
case advanced
|
||||
}
|
||||
|
||||
public var advancedSettingsState: AdvancedSettingsReducer.State
|
||||
public var advancedSettingsState: AdvancedSettings.State
|
||||
@PresentationState public var alert: AlertState<Action>?
|
||||
public var appVersion = ""
|
||||
public var appBuild = ""
|
||||
|
@ -29,7 +29,7 @@ public struct SettingsReducer: Reducer {
|
|||
public var supportData: SupportData?
|
||||
|
||||
public init(
|
||||
advancedSettingsState: AdvancedSettingsReducer.State,
|
||||
advancedSettingsState: AdvancedSettings.State,
|
||||
appVersion: String = "",
|
||||
appBuild: String = "",
|
||||
destination: Destination? = nil,
|
||||
|
@ -46,7 +46,7 @@ public struct SettingsReducer: Reducer {
|
|||
}
|
||||
|
||||
public enum Action: Equatable {
|
||||
case advancedSettings(AdvancedSettingsReducer.Action)
|
||||
case advancedSettings(AdvancedSettings.Action)
|
||||
case alert(PresentationAction<Action>)
|
||||
case copyEmail
|
||||
case onAppear
|
||||
|
@ -119,7 +119,7 @@ public struct SettingsReducer: Reducer {
|
|||
.ifLet(\.$alert, action: /Action.alert)
|
||||
|
||||
Scope(state: \.advancedSettingsState, action: /Action.advancedSettings) {
|
||||
AdvancedSettingsReducer()
|
||||
AdvancedSettings()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ extension SettingsViewStore {
|
|||
// MARK: - Store
|
||||
|
||||
extension SettingsStore {
|
||||
func advancedSettingsStore() -> StoreOf<AdvancedSettingsReducer> {
|
||||
func advancedSettingsStore() -> StoreOf<AdvancedSettings> {
|
||||
self.scope(
|
||||
state: \.advancedSettingsState,
|
||||
action: SettingsReducer.Action.advancedSettings
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/google/abseil-cpp-binary.git",
|
||||
"state" : {
|
||||
"revision" : "bfc0b6f81adc06ce5121eb23f628473638d67c5c",
|
||||
"version" : "1.2022062300.0"
|
||||
"revision" : "748c7837511d0e6a507737353af268484e1745e2",
|
||||
"version" : "1.2024011601.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -32,8 +32,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/firebase/firebase-ios-sdk",
|
||||
"state" : {
|
||||
"revision" : "b880ec8ec927a838c51c12862c6222c30d7097d7",
|
||||
"version" : "10.20.0"
|
||||
"revision" : "42eae77a0af79e9c3f41df04a23c76f05cfdda77",
|
||||
"version" : "10.24.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -41,8 +41,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/google/GoogleAppMeasurement.git",
|
||||
"state" : {
|
||||
"revision" : "ceec9f28dea12b7cf3dabf18b5ed7621c88fd4aa",
|
||||
"version" : "10.20.0"
|
||||
"revision" : "51ba746a9d51a4bd0774b68499b0c73ef6e8570d",
|
||||
"version" : "10.24.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -68,8 +68,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/google/grpc-binary.git",
|
||||
"state" : {
|
||||
"revision" : "a673bc2937fbe886dd1f99c401b01b6d977a9c98",
|
||||
"version" : "1.49.1"
|
||||
"revision" : "e9fad491d0673bdda7063a0341fb6b47a30c5359",
|
||||
"version" : "1.62.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -158,8 +158,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/pointfreeco/swift-case-paths",
|
||||
"state" : {
|
||||
"revision" : "8cc3bc05d0cc956f7374c6c208a11f66a7cac3db",
|
||||
"version" : "1.2.2"
|
||||
"revision" : "79623dbe2c7672f5e450d8325613d231454390b3",
|
||||
"version" : "1.3.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -185,8 +185,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/pointfreeco/swift-composable-architecture",
|
||||
"state" : {
|
||||
"revision" : "776bc5c28f3beb0ab9897678b5ec63596360f786",
|
||||
"version" : "1.7.1"
|
||||
"revision" : "115fe5af41d333b6156d4924d7c7058bc77fd580",
|
||||
"version" : "1.9.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -54,14 +54,14 @@ class SettingsTests: XCTestCase {
|
|||
)
|
||||
|
||||
let store = TestStore(
|
||||
initialState: AdvancedSettingsReducer.State(
|
||||
initialState: AdvancedSettings.State(
|
||||
deleteWallet: .initial,
|
||||
phraseDisplayState: RecoveryPhraseDisplay.State(phrase: nil),
|
||||
privateDataConsentState: .initial,
|
||||
serverSetupState: .initial
|
||||
)
|
||||
) {
|
||||
AdvancedSettingsReducer()
|
||||
AdvancedSettings()
|
||||
}
|
||||
|
||||
store.dependencies.localAuthentication = .mockAuthenticationSucceeded
|
||||
|
@ -81,7 +81,7 @@ class SettingsTests: XCTestCase {
|
|||
let store = TestStore(
|
||||
initialState: .initial
|
||||
) {
|
||||
AdvancedSettingsReducer()
|
||||
AdvancedSettings()
|
||||
}
|
||||
|
||||
store.dependencies.localAuthentication = .mockAuthenticationFailed
|
||||
|
|
Loading…
Reference in New Issue