[#1036] Wipe wallet in advanced settings
- Wipe wallet feature integrated into advanced settings
This commit is contained in:
parent
ecc65f9a83
commit
da3687b9d1
|
@ -19,6 +19,7 @@ let package = Package(
|
|||
.library(name: "DatabaseFiles", targets: ["DatabaseFiles"]),
|
||||
.library(name: "Date", targets: ["Date"]),
|
||||
.library(name: "Deeplink", targets: ["Deeplink"]),
|
||||
.library(name: "DeleteWallet", targets: ["DeleteWallet"]),
|
||||
.library(name: "DerivationTool", targets: ["DerivationTool"]),
|
||||
.library(name: "DiskSpaceChecker", targets: ["DiskSpaceChecker"]),
|
||||
.library(name: "ExportLogs", targets: ["ExportLogs"]),
|
||||
|
@ -172,6 +173,18 @@ let package = Package(
|
|||
],
|
||||
path: "Sources/Dependencies/Deeplink"
|
||||
),
|
||||
.target(
|
||||
name: "DeleteWallet",
|
||||
dependencies: [
|
||||
"Generated",
|
||||
"SDKSynchronizer",
|
||||
"UIComponents",
|
||||
"Utils",
|
||||
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
|
||||
.product(name: "ZcashLightClientKit", package: "zcash-swift-wallet-sdk")
|
||||
],
|
||||
path: "Sources/Features/DeleteWallet"
|
||||
),
|
||||
.target(
|
||||
name: "DerivationTool",
|
||||
dependencies: [
|
||||
|
@ -504,6 +517,7 @@ let package = Package(
|
|||
name: "Settings",
|
||||
dependencies: [
|
||||
"AppVersion",
|
||||
"DeleteWallet",
|
||||
"Generated",
|
||||
"LocalAuthenticationHandler",
|
||||
"Models",
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// DeleteWalletStore.swift
|
||||
// secant-testnet
|
||||
//
|
||||
// Created by Lukáš Korba on 03-27-2024
|
||||
//
|
||||
|
||||
import ComposableArchitecture
|
||||
|
||||
import Generated
|
||||
import SDKSynchronizer
|
||||
import Utils
|
||||
import ZcashLightClientKit
|
||||
|
||||
@Reducer
|
||||
public struct DeleteWallet {
|
||||
@ObservableState
|
||||
public struct State: Equatable {
|
||||
public var isAcknowledged: Bool = false
|
||||
public var isProcessing: Bool = false
|
||||
|
||||
public init(
|
||||
isAcknowledged: Bool = false,
|
||||
isProcessing: Bool = false
|
||||
) {
|
||||
self.isAcknowledged = isAcknowledged
|
||||
self.isProcessing = isProcessing
|
||||
}
|
||||
}
|
||||
|
||||
public enum Action: BindableAction, Equatable {
|
||||
case binding(BindingAction<DeleteWallet.State>)
|
||||
case deleteTapped
|
||||
}
|
||||
|
||||
@Dependency(\.sdkSynchronizer) var sdkSynchronizer
|
||||
|
||||
public init() { }
|
||||
|
||||
public var body: some Reducer<State, Action> {
|
||||
BindingReducer()
|
||||
|
||||
Reduce { state, action in
|
||||
switch action {
|
||||
case .binding:
|
||||
return .none
|
||||
|
||||
case .deleteTapped:
|
||||
state.isProcessing = true
|
||||
return .none
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// DeleteWalletView.swift
|
||||
// secant-testnet
|
||||
//
|
||||
// Created by Lukáš Korba on 03-27-2024
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import ComposableArchitecture
|
||||
import Generated
|
||||
import UIComponents
|
||||
|
||||
public struct DeleteWalletView: View {
|
||||
@Perception.Bindable var store: StoreOf<DeleteWallet>
|
||||
|
||||
public init(store: StoreOf<DeleteWallet>) {
|
||||
self.store = store
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
WithPerceptionTracking {
|
||||
ScrollView {
|
||||
Group {
|
||||
ZashiIcon()
|
||||
|
||||
Text(L10n.DeleteWallet.title)
|
||||
.font(.custom(FontFamily.Archivo.semiBold.name, size: 25))
|
||||
.padding(.bottom, 15)
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Text(L10n.DeleteWallet.message1)
|
||||
.font(.custom(FontFamily.Inter.bold.name, size: 16))
|
||||
|
||||
Text(L10n.DeleteWallet.message2)
|
||||
.font(.custom(FontFamily.Inter.medium.name, size: 16))
|
||||
.padding(.top, 20)
|
||||
}
|
||||
|
||||
HStack {
|
||||
Toggle(isOn: $store.isAcknowledged, label: {
|
||||
Text(L10n.DeleteWallet.iUnderstand)
|
||||
.font(.custom(FontFamily.Inter.medium.name, size: 14))
|
||||
})
|
||||
.toggleStyle(CheckboxToggleStyle())
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding(.top, 30)
|
||||
|
||||
Button(L10n.DeleteWallet.actionButtonTitle.uppercased()) {
|
||||
store.send(.deleteTapped)
|
||||
}
|
||||
.zcashStyle()
|
||||
.disabled(!store.isAcknowledged || store.isProcessing)
|
||||
.padding(.vertical, 50)
|
||||
}
|
||||
.padding(.horizontal, 60)
|
||||
}
|
||||
.padding(.vertical, 1)
|
||||
.zashiBack(store.isProcessing)
|
||||
}
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.applyScreenBackground(withPattern: true)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
#Preview {
|
||||
DeleteWalletView(store: DeleteWallet.demo)
|
||||
}
|
||||
|
||||
// MARK: - Store
|
||||
|
||||
extension DeleteWallet {
|
||||
public static var demo = StoreOf<DeleteWallet>(
|
||||
initialState: .initial
|
||||
) {
|
||||
DeleteWallet()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Placeholders
|
||||
|
||||
extension DeleteWallet.State {
|
||||
public static let initial = DeleteWallet.State()
|
||||
}
|
|
@ -295,7 +295,7 @@ extension RootReducer {
|
|||
state.alert = AlertState.wipeRequest()
|
||||
return .none
|
||||
|
||||
case .initialization(.nukeWallet):
|
||||
case .initialization(.nukeWallet), .tabs(.settings(.advancedSettings(.deleteWallet(.deleteTapped)))):
|
||||
guard let wipePublisher = sdkSynchronizer.wipe() else {
|
||||
return Effect.send(.nukeWalletFailed)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import SwiftUI
|
|||
import ComposableArchitecture
|
||||
import MessageUI
|
||||
|
||||
import DeleteWallet
|
||||
import Generated
|
||||
import LocalAuthenticationHandler
|
||||
import Models
|
||||
|
@ -18,10 +19,12 @@ public struct AdvancedSettingsReducer: Reducer {
|
|||
public struct State: Equatable {
|
||||
public enum Destination {
|
||||
case backupPhrase
|
||||
case deleteWallet
|
||||
case privateDataConsent
|
||||
case serverSetup
|
||||
}
|
||||
|
||||
public var deleteWallet: DeleteWallet.State
|
||||
public var destination: Destination?
|
||||
public var isRestoringWallet = false
|
||||
public var phraseDisplayState: RecoveryPhraseDisplay.State
|
||||
|
@ -29,12 +32,14 @@ public struct AdvancedSettingsReducer: Reducer {
|
|||
public var serverSetupState: ServerSetup.State
|
||||
|
||||
public init(
|
||||
deleteWallet: DeleteWallet.State,
|
||||
destination: Destination? = nil,
|
||||
isRestoringWallet: Bool = false,
|
||||
phraseDisplayState: RecoveryPhraseDisplay.State,
|
||||
privateDataConsentState: PrivateDataConsentReducer.State,
|
||||
serverSetupState: ServerSetup.State
|
||||
) {
|
||||
self.deleteWallet = deleteWallet
|
||||
self.destination = destination
|
||||
self.isRestoringWallet = isRestoringWallet
|
||||
self.phraseDisplayState = phraseDisplayState
|
||||
|
@ -45,6 +50,7 @@ public struct AdvancedSettingsReducer: Reducer {
|
|||
|
||||
public enum Action: Equatable {
|
||||
case backupWalletAccessRequest
|
||||
case deleteWallet(DeleteWallet.Action)
|
||||
case phraseDisplay(RecoveryPhraseDisplay.Action)
|
||||
case privateDataConsent(PrivateDataConsentReducer.Action)
|
||||
case restoreWalletTask
|
||||
|
@ -68,6 +74,9 @@ public struct AdvancedSettingsReducer: Reducer {
|
|||
}
|
||||
}
|
||||
|
||||
case .deleteWallet:
|
||||
return .none
|
||||
|
||||
case .phraseDisplay(.finishedPressed):
|
||||
state.destination = nil
|
||||
return .none
|
||||
|
@ -122,6 +131,10 @@ public struct AdvancedSettingsReducer: Reducer {
|
|||
Scope(state: \.serverSetupState, action: /Action.serverSetup) {
|
||||
ServerSetup()
|
||||
}
|
||||
|
||||
Scope(state: \.deleteWallet, action: /Action.deleteWallet) {
|
||||
DeleteWallet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,6 +168,13 @@ extension AdvancedSettingsViewStore {
|
|||
embed: { $0 ? .serverSetup : nil }
|
||||
)
|
||||
}
|
||||
|
||||
var bindingDeleteWallet: Binding<Bool> {
|
||||
self.destinationBinding.map(
|
||||
extract: { $0 == .deleteWallet },
|
||||
embed: { $0 ? .deleteWallet : nil }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Store
|
||||
|
@ -180,12 +200,20 @@ extension AdvancedSettingsStore {
|
|||
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,
|
||||
|
@ -205,6 +233,7 @@ extension AdvancedSettingsStore {
|
|||
|
||||
public static let demo = AdvancedSettingsStore(
|
||||
initialState: .init(
|
||||
deleteWallet: .initial,
|
||||
phraseDisplayState: RecoveryPhraseDisplay.State(
|
||||
phrase: nil,
|
||||
birthday: nil
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
import SwiftUI
|
||||
import ComposableArchitecture
|
||||
|
||||
import DeleteWallet
|
||||
import Generated
|
||||
import RecoveryPhraseDisplay
|
||||
import UIComponents
|
||||
|
@ -49,26 +51,45 @@ public struct AdvancedSettingsView: View {
|
|||
ServerSetupView(store: store.serverSetupStore())
|
||||
}
|
||||
)
|
||||
.navigationLinkEmpty(
|
||||
isActive: viewStore.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))
|
||||
}
|
||||
.zcashStyle()
|
||||
.padding(.bottom, 25)
|
||||
.padding(.horizontal, 70)
|
||||
|
||||
Button(L10n.Settings.chooseServer.uppercased()) {
|
||||
viewStore.send(.updateDestination(.serverSetup))
|
||||
}
|
||||
.zcashStyle()
|
||||
.padding(.bottom, 80)
|
||||
.padding(.horizontal, 70)
|
||||
|
||||
Spacer()
|
||||
|
||||
Button(L10n.Settings.deleteZashi.uppercased()) {
|
||||
viewStore.send(.updateDestination(.deleteWallet))
|
||||
}
|
||||
.zcashStyle()
|
||||
.padding(.bottom, 20)
|
||||
.padding(.horizontal, 70)
|
||||
|
||||
Text(L10n.Settings.deleteZashiWarning)
|
||||
.font(.custom(FontFamily.Inter.medium.name, size: 11))
|
||||
.padding(.bottom, 50)
|
||||
.padding(.horizontal, 20)
|
||||
}
|
||||
}
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.applyScreenBackground()
|
||||
|
|
|
@ -84,6 +84,18 @@ public enum L10n {
|
|||
public static let message = L10n.tr("Localizable", "balances.hintBox.message", fallback: "Zashi uses the latest network upgrade and does not support sending transparent (unshielded) ZEC. Use the Shield and Consolidate button to shield your funds, which will add to your available balance and make your ZEC spendable.")
|
||||
}
|
||||
}
|
||||
public enum DeleteWallet {
|
||||
/// Delete Zashi
|
||||
public static let actionButtonTitle = L10n.tr("Localizable", "deleteWallet.actionButtonTitle", fallback: "Delete Zashi")
|
||||
/// I understand
|
||||
public static let iUnderstand = L10n.tr("Localizable", "deleteWallet.iUnderstand", fallback: "I understand")
|
||||
/// Please don't delete this app unless you're sure you understand the effects.
|
||||
public static let message1 = L10n.tr("Localizable", "deleteWallet.message1", fallback: "Please don't delete this app unless you're sure you understand the effects.")
|
||||
/// Deleting the Zashi app will delete the database and cached data. Any funds you have in this wallet will be lost and can only be recovered by using your Zashi secret recovery phrase in Zashi or another Zcash wallet.
|
||||
public static let message2 = L10n.tr("Localizable", "deleteWallet.message2", fallback: "Deleting the Zashi app will delete the database and cached data. Any funds you have in this wallet will be lost and can only be recovered by using your Zashi secret recovery phrase in Zashi or another Zcash wallet.")
|
||||
/// Delete Zashi
|
||||
public static let title = L10n.tr("Localizable", "deleteWallet.title", fallback: "Delete Zashi")
|
||||
}
|
||||
public enum Error {
|
||||
/// possible roll back
|
||||
public static let rollBack = L10n.tr("Localizable", "error.rollBack", fallback: "possible roll back")
|
||||
|
@ -609,6 +621,10 @@ public enum L10n {
|
|||
public static let advanced = L10n.tr("Localizable", "settings.advanced", fallback: "Advanced")
|
||||
/// Choose a server
|
||||
public static let chooseServer = L10n.tr("Localizable", "settings.chooseServer", fallback: "Choose a server")
|
||||
/// Delete Zashi
|
||||
public static let deleteZashi = L10n.tr("Localizable", "settings.deleteZashi", fallback: "Delete Zashi")
|
||||
/// (You will be asked to confirm on next screen)
|
||||
public static let deleteZashiWarning = L10n.tr("Localizable", "settings.deleteZashiWarning", fallback: "(You will be asked to confirm on next screen)")
|
||||
/// Export logs only
|
||||
public static let exportLogsOnly = L10n.tr("Localizable", "settings.exportLogsOnly", fallback: "Export logs only")
|
||||
/// Export private data
|
||||
|
|
|
@ -169,6 +169,13 @@
|
|||
"send.alert.failure.title" = "Failed to send funds";
|
||||
"send.alert.failure.message" = "Error: %@";
|
||||
|
||||
// MARK: - Delete Wallet
|
||||
"deleteWallet.title" = "Delete Zashi";
|
||||
"deleteWallet.message1" = "Please don't delete this app unless you're sure you understand the effects.";
|
||||
"deleteWallet.message2" = "Deleting the Zashi app will delete the database and cached data. Any funds you have in this wallet will be lost and can only be recovered by using your Zashi secret recovery phrase in Zashi or another Zcash wallet.";
|
||||
"deleteWallet.iUnderstand" = "I understand";
|
||||
"deleteWallet.actionButtonTitle" = "Delete Zashi";
|
||||
|
||||
// MARK: - Settings
|
||||
"settings.feedback" = "Send us feedback";
|
||||
"settings.advanced" = "Advanced";
|
||||
|
@ -177,6 +184,8 @@
|
|||
"settings.exportPrivateData" = "Export private data";
|
||||
"settings.chooseServer" = "Choose a server";
|
||||
"settings.exportLogsOnly" = "Export logs only";
|
||||
"settings.deleteZashi" = "Delete Zashi";
|
||||
"settings.deleteZashiWarning" = "(You will be asked to confirm on next screen)";
|
||||
"settings.about.info" = "Send and receive ZEC on Zashi!
|
||||
Zashi is a minimal-design, self-custody, ZEC-only shielded wallet that keeps your transaction history and wallet balance private. Built by Zcashers, for Zcashers. Developed and maintained by Electric Coin Co., the inventor of Zcash, Zashi features a built-in user-feedback mechanism to enable more features, more quickly.";
|
||||
"settings.version" = "Version %@ (%@)";
|
||||
|
|
Loading…
Reference in New Issue