Fixes for the feedback
This commit is contained in:
parent
c5b8f4cf1f
commit
8081ab7478
|
@ -99,7 +99,7 @@ let package = Package(
|
|||
.package(url: "https://github.com/pointfreeco/swift-url-routing", from: "0.6.2"),
|
||||
.package(url: "https://github.com/zcash-hackworks/MnemonicSwift", from: "2.2.5"),
|
||||
// .package(url: "https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk", from: "2.2.10"),
|
||||
.package(url: "https://github.com/LukasKorba/ZcashLightClientKit", revision: "16a80d2efb2fbb4921a8c6be528e6a8644d4a6d8"),
|
||||
.package(url: "https://github.com/LukasKorba/ZcashLightClientKit", revision: "1a2db6b167614fca4161f94ac1cb41cae976222f"),
|
||||
.package(url: "https://github.com/flexa/flexa-ios.git", exact: "1.0.9"),
|
||||
.package(url: "https://github.com/pacu/zcash-swift-payment-uri", from: "0.1.0-beta.10"),
|
||||
.package(url: "https://github.com/airbnb/lottie-spm.git", from: "4.5.1"),
|
||||
|
|
|
@ -16,7 +16,7 @@ extension NetworkMonitorClient: DependencyKey {
|
|||
public static func live() -> Self {
|
||||
let monitor = NWPathMonitor()
|
||||
let queue = DispatchQueue.global(qos: .background)
|
||||
let subject = PassthroughSubject<Bool, Never>()
|
||||
let subject = CurrentValueSubject<Bool, Never>(true)
|
||||
|
||||
return NetworkMonitorClient(
|
||||
networkMonitorStream: {
|
||||
|
|
|
@ -21,7 +21,7 @@ extension SDKSynchronizerClient: DependencyKey {
|
|||
databaseFiles: DatabaseFilesClient = .liveValue
|
||||
) -> Self {
|
||||
@Dependency(\.zcashSDKEnvironment) var zcashSDKEnvironment
|
||||
|
||||
|
||||
let network = zcashSDKEnvironment.network
|
||||
|
||||
#if DEBUG
|
||||
|
@ -51,12 +51,7 @@ extension SDKSynchronizerClient: DependencyKey {
|
|||
eventStream: { synchronizer.eventStream },
|
||||
exchangeRateUSDStream: { synchronizer.exchangeRateUSDStream },
|
||||
latestState: { synchronizer.latestState },
|
||||
prepareWith: {
|
||||
seedBytes,
|
||||
walletBirtday,
|
||||
walletMode,
|
||||
name,
|
||||
keySource in
|
||||
prepareWith: { seedBytes, walletBirtday, walletMode, name, keySource in
|
||||
let result = try await synchronizer.prepare(
|
||||
with: seedBytes,
|
||||
walletBirthday: walletBirtday,
|
||||
|
@ -309,10 +304,10 @@ extension SDKSynchronizerClient {
|
|||
let clearedTransactions = zcashTransactions.compactMap { rawTransaction in
|
||||
rawTransaction.accountUUID == accountUUID ? rawTransaction : nil
|
||||
}
|
||||
|
||||
|
||||
var clearedTxs: [TransactionState] = []
|
||||
|
||||
let latestBlockHeight = try await SDKSynchronizerClient.latestBlockHeight(synchronizer: synchronizer)
|
||||
|
||||
let latestBlockHeight = try? await SDKSynchronizerClient.latestBlockHeight(synchronizer: synchronizer)
|
||||
|
||||
for clearedTransaction in clearedTransactions {
|
||||
var hasTransparentOutputs = false
|
||||
|
|
|
@ -17,13 +17,15 @@ extension RequestZecCoordFlow {
|
|||
// MARK: - Request Zec
|
||||
|
||||
case .path(.element(id: _, action: .requestZec(.requestTapped))):
|
||||
for element in state.path {
|
||||
if case .requestZec(let requestZecState) = element {
|
||||
state.requestZecState.memoState = requestZecState.memoState
|
||||
break
|
||||
}
|
||||
}
|
||||
state.path.append(.requestZecSummary(state.requestZecState))
|
||||
return .none
|
||||
|
||||
case .path(.element(id: _, action: .requestZec(.onDisappearMemoStep(let memoText)))):
|
||||
state.memo = memoText
|
||||
return .none
|
||||
|
||||
// MARK: - Zec Keyboard
|
||||
|
||||
case .zecKeyboard(.nextTapped):
|
||||
|
|
|
@ -45,7 +45,7 @@ extension RestoreWalletCoordFlow {
|
|||
// MARK: - Wallet Birthday
|
||||
|
||||
case .path(.element(id: _, action: .walletBirthday(.helpSheetRequested))):
|
||||
state.isHelpSheetPreseted.toggle()
|
||||
state.isHelpSheetPresented.toggle()
|
||||
return .none
|
||||
|
||||
case .path(.element(id: _, action: .walletBirthday(.estimateHeightTapped))):
|
||||
|
@ -61,7 +61,7 @@ extension RestoreWalletCoordFlow {
|
|||
return .none
|
||||
|
||||
case .path(.element(id: _, action: .estimateBirthdaysDate(.helpSheetRequested))):
|
||||
state.isHelpSheetPreseted.toggle()
|
||||
state.isHelpSheetPresented.toggle()
|
||||
return .none
|
||||
|
||||
case .path(.element(id: _, action: .estimateBirthdaysDate(.estimateHeightReady))):
|
||||
|
|
|
@ -29,7 +29,8 @@ public struct RestoreWalletCoordFlow {
|
|||
|
||||
@ObservableState
|
||||
public struct State {
|
||||
public var isHelpSheetPreseted = false
|
||||
public var isHelpSheetPresented = false
|
||||
public var isKeyboardVisible = false
|
||||
public var isValidSeed = false
|
||||
public var nextIndex: Int?
|
||||
public var path = StackState<Path.State>()
|
||||
|
@ -54,6 +55,7 @@ public struct RestoreWalletCoordFlow {
|
|||
case successfullyRecovered
|
||||
case suggestedWordTapped(String)
|
||||
case suggestionsRequested(Int)
|
||||
case updateKeyboardFlag(Bool)
|
||||
#if DEBUG
|
||||
case debugPasteSeed
|
||||
#endif
|
||||
|
@ -91,6 +93,7 @@ public struct RestoreWalletCoordFlow {
|
|||
|
||||
case .selectedIndex(let index):
|
||||
state.selectedIndex = index
|
||||
state.nextIndex = state.selectedIndex
|
||||
if let index {
|
||||
return .send(.suggestionsRequested(index))
|
||||
}
|
||||
|
@ -109,32 +112,47 @@ public struct RestoreWalletCoordFlow {
|
|||
case .suggestedWordTapped(let word):
|
||||
if let index = state.selectedIndex {
|
||||
state.words[index] = word
|
||||
state.prevWords = state.words
|
||||
state.nextIndex = index + 1 < 24 ? index + 1 : 0
|
||||
if !state.isValidSeed && state.selectedIndex != 23 {
|
||||
state.prevWords = state.words
|
||||
state.nextIndex = index + 1 < 24 ? index + 1 : 0
|
||||
}
|
||||
return .send(.evaluateSeedValidity)
|
||||
}
|
||||
return .none
|
||||
|
||||
case .helpSheetRequested:
|
||||
state.isHelpSheetPreseted.toggle()
|
||||
state.isHelpSheetPresented.toggle()
|
||||
return .none
|
||||
|
||||
case .evaluateSeedValidity:
|
||||
do {
|
||||
try mnemonic.isValid(state.words.joined(separator: " "))
|
||||
state.isValidSeed = true
|
||||
state.isKeyboardVisible = false
|
||||
} catch {
|
||||
state.isValidSeed = false
|
||||
if let index = state.selectedIndex {
|
||||
let prefix = state.words[index]
|
||||
if let first = state.suggestedWords.first, first == prefix && !state.isValidSeed {
|
||||
state.prevWords = state.words
|
||||
state.nextIndex = index + 1 < 24 ? index + 1 : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return .none
|
||||
|
||||
case .updateKeyboardFlag(let value):
|
||||
state.isKeyboardVisible = value
|
||||
return .none
|
||||
|
||||
#if DEBUG
|
||||
case .debugPasteSeed:
|
||||
do {
|
||||
let seedToPaste = pasteboard.getString()?.data ?? ""
|
||||
try mnemonic.isValid(seedToPaste)
|
||||
state.words = seedToPaste.components(separatedBy: " ")
|
||||
state.isValidSeed = true
|
||||
state.isKeyboardVisible = false
|
||||
state.words = seedToPaste.components(separatedBy: " ")
|
||||
} catch {
|
||||
state.isValidSeed = false
|
||||
}
|
||||
|
|
|
@ -57,9 +57,16 @@ public struct RestoreWalletCoordFlowView: View {
|
|||
ForEach(0..<3, id: \.self) { i in
|
||||
HStack(spacing: 0) {
|
||||
Text("\(j * 3 + i + 1)")
|
||||
.zFont(.medium, size: 14, style: Design.Text.primary)
|
||||
.zFont(.medium, size: 14, style: Design.Tags.tcCountFg)
|
||||
.frame(minWidth: 12)
|
||||
.padding(.vertical, 2)
|
||||
.padding(.horizontal, 4)
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: Design.Radius._lg)
|
||||
.fill(Design.Tags.tcCountBg.color(colorScheme))
|
||||
}
|
||||
.padding(.trailing, 4)
|
||||
|
||||
|
||||
TextField("", text: $store.words[j * 3 + i])
|
||||
.zFont(size: 16, style: Design.Text.primary)
|
||||
.disableAutocorrection(true)
|
||||
|
@ -136,6 +143,12 @@ public struct RestoreWalletCoordFlowView: View {
|
|||
focusedField = .field(nextIndex)
|
||||
}
|
||||
}
|
||||
.onChange(of: store.isKeyboardVisible) { value in
|
||||
if keyboardVisible && !value {
|
||||
keyboardVisible = value
|
||||
focusedField = nil
|
||||
}
|
||||
}
|
||||
.applyScreenBackground()
|
||||
.overlay(
|
||||
VStack(spacing: 0) {
|
||||
|
@ -176,7 +189,6 @@ public struct RestoreWalletCoordFlowView: View {
|
|||
)
|
||||
)
|
||||
.frame(height: 38)
|
||||
//.clipped()
|
||||
|
||||
Spacer()
|
||||
|
||||
|
@ -186,7 +198,6 @@ public struct RestoreWalletCoordFlowView: View {
|
|||
Text(L10n.General.done.uppercased())
|
||||
.zFont(.regular, size: 14, style: Design.Text.primary)
|
||||
}
|
||||
// .padding(.bottom, 4)
|
||||
.padding(.trailing, 24)
|
||||
.padding(.leading, 4)
|
||||
}
|
||||
|
@ -196,7 +207,6 @@ public struct RestoreWalletCoordFlowView: View {
|
|||
.opacity(keyboardVisible ? 1 : 0)
|
||||
}
|
||||
)
|
||||
// .navigationBarHidden(true)
|
||||
} destination: { store in
|
||||
switch store.case {
|
||||
case let .estimateBirthdaysDate(store):
|
||||
|
@ -220,7 +230,7 @@ public struct RestoreWalletCoordFlowView: View {
|
|||
.padding(8)
|
||||
}
|
||||
)
|
||||
.zashiSheet(isPresented: $store.isHelpSheetPreseted) {
|
||||
.zashiSheet(isPresented: $store.isHelpSheetPresented) {
|
||||
helpSheetContent()
|
||||
.screenHorizontalPadding()
|
||||
}
|
||||
|
@ -234,11 +244,13 @@ public struct RestoreWalletCoordFlowView: View {
|
|||
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { _ in
|
||||
withAnimation {
|
||||
keyboardVisible = true
|
||||
store.send(.updateKeyboardFlag(true))
|
||||
}
|
||||
}
|
||||
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { _ in
|
||||
withAnimation {
|
||||
keyboardVisible = false
|
||||
store.send(.updateKeyboardFlag(false))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public struct WalletBackupCoordFlow {
|
|||
|
||||
@ObservableState
|
||||
public struct State {
|
||||
public var isHelpSheetPreseted = false
|
||||
public var isHelpSheetPresented = false
|
||||
public var path = StackState<Path.State>()
|
||||
public var recoveryPhraseDisplayState = RecoveryPhraseDisplay.State.initial
|
||||
|
||||
|
@ -50,7 +50,7 @@ public struct WalletBackupCoordFlow {
|
|||
Reduce { state, action in
|
||||
switch action {
|
||||
case .helpSheetRequested:
|
||||
state.isHelpSheetPreseted.toggle()
|
||||
state.isHelpSheetPresented.toggle()
|
||||
return .none
|
||||
|
||||
default: return .none
|
||||
|
|
|
@ -51,7 +51,7 @@ public struct WalletBackupCoordFlowView: View {
|
|||
.padding(8)
|
||||
}
|
||||
)
|
||||
.zashiSheet(isPresented: $store.isHelpSheetPreseted) {
|
||||
.zashiSheet(isPresented: $store.isHelpSheetPresented) {
|
||||
helpSheetContent()
|
||||
.screenHorizontalPadding()
|
||||
}
|
||||
|
|
|
@ -45,13 +45,15 @@ extension Receive {
|
|||
// MARK: - Request Zec
|
||||
|
||||
case .path(.element(id: _, action: .requestZec(.requestTapped))):
|
||||
for element in state.path {
|
||||
if case .requestZec(let requestZecState) = element {
|
||||
state.requestZecState.memoState = requestZecState.memoState
|
||||
break
|
||||
}
|
||||
}
|
||||
state.path.append(.requestZecSummary(state.requestZecState))
|
||||
return .none
|
||||
|
||||
case .path(.element(id: _, action: .requestZec(.onDisappearMemoStep(let memoText)))):
|
||||
state.memo = memoText
|
||||
return .none
|
||||
|
||||
case .path(.element(id: _, action: .requestZecSummary(.cancelRequestTapped))):
|
||||
state.path.removeAll()
|
||||
return .none
|
||||
|
|
|
@ -22,7 +22,7 @@ public struct RecoveryPhraseDisplay {
|
|||
public var birthday: Birthday?
|
||||
public var birthdayValue: String?
|
||||
public var isBirthdayHintVisible = false
|
||||
public var isHelpSheetPreseted = false
|
||||
public var isHelpSheetPresented = false
|
||||
public var isRecoveryPhraseHidden = true
|
||||
public var isWalletBackup = false
|
||||
public var phrase: RecoveryPhrase?
|
||||
|
@ -138,7 +138,7 @@ public struct RecoveryPhraseDisplay {
|
|||
return .none
|
||||
|
||||
case .helpSheetRequested:
|
||||
state.isHelpSheetPreseted.toggle()
|
||||
state.isHelpSheetPresented.toggle()
|
||||
return .none
|
||||
|
||||
case .seedSavedTapped:
|
||||
|
|
|
@ -91,7 +91,7 @@ public struct RecoveryPhraseDisplayView: View {
|
|||
.onAppear { store.send(.onAppear) }
|
||||
.alert($store.scope(state: \.alert, action: \.alert))
|
||||
.zashiBack()
|
||||
.zashiSheet(isPresented: $store.isHelpSheetPreseted) {
|
||||
.zashiSheet(isPresented: $store.isHelpSheetPresented) {
|
||||
helpSheetContent()
|
||||
.screenHorizontalPadding()
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@ public struct RequestZec {
|
|||
case memo(MessageEditor.Action)
|
||||
case onAppear
|
||||
case onDisappear
|
||||
case onDisappearMemoStep(String)
|
||||
case qrCodeTapped
|
||||
case rememberQR(CGImage?)
|
||||
case requestTapped
|
||||
|
@ -70,9 +69,6 @@ public struct RequestZec {
|
|||
case .onDisappear:
|
||||
return .cancel(id: state.cancelId)
|
||||
|
||||
case .onDisappearMemoStep:
|
||||
return .none
|
||||
|
||||
case .cancelRequestTapped:
|
||||
return .none
|
||||
|
||||
|
|
|
@ -87,7 +87,6 @@ public struct RequestZecView: View {
|
|||
observeKeyboardNotifications()
|
||||
}
|
||||
}
|
||||
.onDisappear { store.send(.onDisappearMemoStep(store.memoState.text)) }
|
||||
.overlay(
|
||||
VStack(spacing: 0) {
|
||||
Spacer()
|
||||
|
|
|
@ -195,16 +195,21 @@ extension Root {
|
|||
}
|
||||
|
||||
case .initialization(.registerForSynchronizersUpdate):
|
||||
return .merge(
|
||||
.publisher {
|
||||
sdkSynchronizer.stateStream()
|
||||
.throttle(for: .seconds(0.2), scheduler: mainQueue, latest: true)
|
||||
.map { $0.redacted }
|
||||
.map(Root.Action.synchronizerStateChanged)
|
||||
}
|
||||
.cancellable(id: CancelStateId, cancelInFlight: true),
|
||||
.send(.home(.smartBanner(.evaluatePriority1)))
|
||||
)
|
||||
let stateStreamEffect = Effect.publisher {
|
||||
sdkSynchronizer.stateStream()
|
||||
.throttle(for: .seconds(0.2), scheduler: mainQueue, latest: true)
|
||||
.map { $0.redacted }
|
||||
.map(Root.Action.synchronizerStateChanged)
|
||||
}
|
||||
.cancellable(id: CancelStateId, cancelInFlight: true)
|
||||
if state.bgTask != nil {
|
||||
return stateStreamEffect
|
||||
} else {
|
||||
return .merge(
|
||||
stateStreamEffect,
|
||||
.send(.home(.smartBanner(.evaluatePriority1)))
|
||||
)
|
||||
}
|
||||
|
||||
case .initialization(.checkWalletConfig):
|
||||
return .publisher {
|
||||
|
|
|
@ -123,6 +123,17 @@ public enum Design {
|
|||
}
|
||||
}
|
||||
|
||||
public enum Tags: Colorable {
|
||||
case tcDefaultFg
|
||||
case tcHoverBg
|
||||
case tcHoverFg
|
||||
case tcCountBg
|
||||
case tcCountFg
|
||||
case surfaceIndicator
|
||||
case surfacePrimary
|
||||
case surfaceStroke
|
||||
}
|
||||
|
||||
public enum Inputs {
|
||||
public enum Default: Colorable {
|
||||
case bg
|
||||
|
@ -515,6 +526,21 @@ public extension Design.Btns.Ghost {
|
|||
}
|
||||
}
|
||||
|
||||
public extension Design.Tags {
|
||||
func color(_ colorScheme: ColorScheme) -> Color {
|
||||
switch self {
|
||||
case .tcDefaultFg: return Design.col(Asset.Colors.ZDesign.gray400.color, Asset.Colors.ZDesign.shark500.color, colorScheme)
|
||||
case .tcHoverBg: return Design.col(Asset.Colors.ZDesign.gray50.color, Asset.Colors.ZDesign.shark800.color, colorScheme)
|
||||
case .tcHoverFg: return Design.col(Asset.Colors.ZDesign.gray600.color, Asset.Colors.ZDesign.shark200.color, colorScheme)
|
||||
case .tcCountBg: return Design.col(Asset.Colors.ZDesign.gray50.color, Asset.Colors.ZDesign.shark700.color, colorScheme)
|
||||
case .tcCountFg: return Design.col(Asset.Colors.ZDesign.gray700.color, Asset.Colors.ZDesign.shark300.color, colorScheme)
|
||||
case .surfaceIndicator: return Design.col(Asset.Colors.ZDesign.successGreen600.color, Asset.Colors.ZDesign.successGreen500.color, colorScheme)
|
||||
case .surfacePrimary: return Design.col(Asset.Colors.ZDesign.Base.bone.color, Asset.Colors.ZDesign.Base.midnight.color, colorScheme)
|
||||
case .surfaceStroke: return Design.col(Asset.Colors.ZDesign.gray300.color, Asset.Colors.ZDesign.shark700.color, colorScheme)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension Design.Inputs.Default {
|
||||
func color(_ colorScheme: ColorScheme) -> Color {
|
||||
switch self {
|
||||
|
|
|
@ -271,7 +271,7 @@ extension TransactionState {
|
|||
transaction: ZcashTransaction.Overview,
|
||||
memos: [Memo]? = nil,
|
||||
hasTransparentOutputs: Bool = false,
|
||||
latestBlockHeight: BlockHeight
|
||||
latestBlockHeight: BlockHeight?
|
||||
) {
|
||||
expiryHeight = transaction.expiryHeight
|
||||
minedHeight = transaction.minedHeight
|
||||
|
@ -293,10 +293,18 @@ extension TransactionState {
|
|||
// state of the transaction. SDK knows the latestBlockHeight so ideally ZcashTransaction.Overview
|
||||
// already knows and provides isPending as a bool value.
|
||||
// Once SDK's #1313 is done, adopt the SDK and remove latestBlockHeight here.
|
||||
let isPending = transaction.isPending(currentHeight: latestBlockHeight)
|
||||
var isPending = false
|
||||
var isExpired = false
|
||||
|
||||
if let latestBlockHeight {
|
||||
isPending = transaction.isPending(currentHeight: latestBlockHeight)
|
||||
if let expiryHeight = transaction.expiryHeight, expiryHeight <= latestBlockHeight && minedHeight == nil {
|
||||
isExpired = true
|
||||
}
|
||||
}
|
||||
|
||||
// failed check
|
||||
if let expiryHeight = transaction.expiryHeight, expiryHeight <= latestBlockHeight && minedHeight == nil {
|
||||
if isExpired {
|
||||
status = .failed
|
||||
} else if isShieldingTransaction {
|
||||
status = isPending ? .shielding : .shielded
|
||||
|
|
|
@ -464,7 +464,7 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/LukasKorba/ZcashLightClientKit",
|
||||
"state" : {
|
||||
"revision" : "16a80d2efb2fbb4921a8c6be528e6a8644d4a6d8"
|
||||
"revision" : "1a2db6b167614fca4161f94ac1cb41cae976222f"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue