diff --git a/Bitkit/Components/MoneyStack.swift b/Bitkit/Components/MoneyStack.swift index f6160e41..dec1bf90 100644 --- a/Bitkit/Components/MoneyStack.swift +++ b/Bitkit/Components/MoneyStack.swift @@ -8,6 +8,7 @@ struct MoneyStack: View { var showEyeIcon: Bool = false var enableSwipeGesture: Bool = false + @EnvironmentObject var app: AppViewModel @EnvironmentObject var currency: CurrencyViewModel @EnvironmentObject var settings: SettingsViewModel @@ -109,10 +110,29 @@ struct MoneyStack: View { .accessibilityIdentifier("TotalBalance") .contentShape(Rectangle()) .onTapGesture { + let previousDisplay = currency.primaryDisplay + withAnimation(springAnimation) { currency.togglePrimaryDisplay() } Haptics.play(.medium) + + // Show toast on first switch + if !settings.ignoresSwitchUnitToast { + let newDisplay = currency.primaryDisplay + let toUnitText = getUnitText(for: newDisplay) + let fromUnitText = getUnitText(for: previousDisplay) + + app.toast( + type: .info, + title: t("wallet__balance_unit_switched_title", variables: ["unit": toUnitText]), + description: t("wallet__balance_unit_switched_message", variables: ["unit": fromUnitText]), + visibilityTime: 5.0, + accessibilityIdentifier: "BalanceUnitSwitchedToast" + ) + + settings.ignoresSwitchUnitToast = true + } } .animation(springAnimation, value: currency.primaryDisplay) .conditionalGesture(enableSwipeGesture) { @@ -123,10 +143,24 @@ struct MoneyStack: View { // Only trigger if horizontal swipe is more significant than vertical if abs(horizontalAmount) > abs(verticalAmount) { + let wasHidden = settings.hideBalance withAnimation(springAnimation) { settings.hideBalance.toggle() } Haptics.play(.medium) + + // Show toast on first hide (when balance becomes hidden) + if !wasHidden && settings.hideBalance && !settings.ignoresHideBalanceToast { + app.toast( + type: .info, + title: t("wallet__balance_hidden_title"), + description: t("wallet__balance_hidden_message"), + visibilityTime: 5.0, + accessibilityIdentifier: "BalanceHiddenToast" + ) + + settings.ignoresHideBalanceToast = true + } } } } @@ -158,6 +192,15 @@ private extension MoneyStack { } Haptics.play(.medium) } + + func getUnitText(for display: PrimaryDisplay) -> String { + switch display { + case .bitcoin: + return t("settings__general__unit_bitcoin") + case .fiat: + return currency.selectedCurrency + } + } } // MARK: - Helper View Modifier diff --git a/Bitkit/ViewModels/AppViewModel.swift b/Bitkit/ViewModels/AppViewModel.swift index 39e11944..79d352f4 100644 --- a/Bitkit/ViewModels/AppViewModel.swift +++ b/Bitkit/ViewModels/AppViewModel.swift @@ -364,11 +364,21 @@ extension AppViewModel { try await CoreService.shared.activity.insert(.lightning(ln)) } else { - toast(type: .lightning, title: t("lightning__channel_opened_title"), description: t("lightning__channel_opened_msg")) + toast( + type: .lightning, + title: t("lightning__channel_opened_title"), + description: t("lightning__channel_opened_msg"), + visibilityTime: 5.0 + ) } } } else { - toast(type: .lightning, title: t("lightning__channel_opened_title"), description: t("lightning__channel_opened_msg")) + toast( + type: .lightning, + title: t("lightning__channel_opened_title"), + description: t("lightning__channel_opened_msg"), + visibilityTime: 5.0 + ) } case .channelClosed(channelId: _, userChannelId: _, counterpartyNodeId: _, reason: _): break diff --git a/Bitkit/ViewModels/SettingsViewModel.swift b/Bitkit/ViewModels/SettingsViewModel.swift index bc3541ba..8eddd265 100644 --- a/Bitkit/ViewModels/SettingsViewModel.swift +++ b/Bitkit/ViewModels/SettingsViewModel.swift @@ -97,6 +97,8 @@ class SettingsViewModel: NSObject, ObservableObject { @AppStorage("quickpayAmount") var quickpayAmount: Double = 5 @AppStorage("enableNotifications") var enableNotifications: Bool = false @AppStorage("enableNotificationsAmount") var enableNotificationsAmount: Bool = false // TODO: remove this + @AppStorage("ignoresSwitchUnitToast") var ignoresSwitchUnitToast: Bool = false + @AppStorage("ignoresHideBalanceToast") var ignoresHideBalanceToast: Bool = false // PIN Management @Published internal(set) var pinEnabled: Bool = false