From 6bccc0d706f19636348cc41c979c07a56a09abe7 Mon Sep 17 00:00:00 2001 From: Philipp Walter Date: Fri, 10 Oct 2025 11:15:24 +0200 Subject: [PATCH] fix(ui): polish UI & fixes for small screens --- .../Contents.json | 2 +- .../app-icon-black.png | Bin 0 -> 15491 bytes .../app-icon-orange.imageset/Contents.json | 21 ++++ .../app-icon-orange.png | Bin 0 -> 23946 bytes .../app-icon.imageset/app-icon.png | Bin 1984 -> 0 bytes .../icons/bolt.imageset/bolt.pdf | Bin 4068 -> 4364 bytes Bitkit/Components/Button/Button.swift | 12 ++- .../Components/Button/PrimaryButtonView.swift | 6 ++ Bitkit/Components/CopyAddressCard.swift | 8 +- Bitkit/Components/MoneyStack.swift | 17 ++- Bitkit/Components/NotificationPreview.swift | 3 +- Bitkit/Components/NumberPad.swift | 2 +- .../Views/Backup/BackupConfirmMnemonic.swift | 33 ++---- Bitkit/Views/Backup/BackupMetadata.swift | 9 +- Bitkit/Views/Backup/BackupMnemonic.swift | 41 ++++---- Bitkit/Views/Backup/BackupPassphrase.swift | 12 ++- .../Advanced/CoinSelectionSettingsView.swift | 41 +++----- .../General/LocalCurrencySettingsView.swift | 37 +++++-- .../Settings/General/TagSettingsView.swift | 3 +- Bitkit/Views/Settings/MainSettings.swift | 8 +- .../Settings/Quickpay/QuickpaySettings.swift | 19 ++-- .../Views/Settings/Support/ReportIssue.swift | 7 +- .../TransactionSpeedSettingsView.swift | 2 +- Bitkit/Views/Shop/ShopDiscover.swift | 3 +- .../Views/Transfer/FundManualAmountView.swift | 1 + .../Transfer/FundManualSuccessView.swift | 1 + .../Views/Transfer/SavingsConfirmView.swift | 1 + Bitkit/Views/Transfer/SettingUpView.swift | 99 ++++++++++-------- .../Views/Transfer/SpendingAdvancedView.swift | 1 + Bitkit/Views/Transfer/SpendingAmount.swift | 1 + Bitkit/Views/Transfer/SpendingConfirm.swift | 2 +- .../Wallets/Activity/ActivityItemView.swift | 36 ++++--- .../Activity/ActivityRowLightning.swift | 1 + Bitkit/Views/Wallets/Receive/ReceiveQr.swift | 19 ++-- .../Wallets/Send/SendConfirmationView.swift | 2 +- .../Wallets/Send/SendEnterManuallyView.swift | 2 +- Bitkit/Views/Widgets/WidgetDetailView.swift | 3 +- 37 files changed, 256 insertions(+), 199 deletions(-) rename Bitkit/Assets.xcassets/Illustrations/{app-icon.imageset => app-icon-black.imageset}/Contents.json (86%) create mode 100644 Bitkit/Assets.xcassets/Illustrations/app-icon-black.imageset/app-icon-black.png create mode 100644 Bitkit/Assets.xcassets/Illustrations/app-icon-orange.imageset/Contents.json create mode 100644 Bitkit/Assets.xcassets/Illustrations/app-icon-orange.imageset/app-icon-orange.png delete mode 100644 Bitkit/Assets.xcassets/Illustrations/app-icon.imageset/app-icon.png diff --git a/Bitkit/Assets.xcassets/Illustrations/app-icon.imageset/Contents.json b/Bitkit/Assets.xcassets/Illustrations/app-icon-black.imageset/Contents.json similarity index 86% rename from Bitkit/Assets.xcassets/Illustrations/app-icon.imageset/Contents.json rename to Bitkit/Assets.xcassets/Illustrations/app-icon-black.imageset/Contents.json index 955da45d..93240174 100644 --- a/Bitkit/Assets.xcassets/Illustrations/app-icon.imageset/Contents.json +++ b/Bitkit/Assets.xcassets/Illustrations/app-icon-black.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "app-icon.png", + "filename" : "app-icon-black.png", "idiom" : "universal", "scale" : "1x" }, diff --git a/Bitkit/Assets.xcassets/Illustrations/app-icon-black.imageset/app-icon-black.png b/Bitkit/Assets.xcassets/Illustrations/app-icon-black.imageset/app-icon-black.png new file mode 100644 index 0000000000000000000000000000000000000000..65fc9a8f66c5ebaa87b016bd8e64748cd751e0ca GIT binary patch literal 15491 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 literal 0 HcmV?d00001 diff --git a/Bitkit/Assets.xcassets/Illustrations/app-icon-orange.imageset/Contents.json b/Bitkit/Assets.xcassets/Illustrations/app-icon-orange.imageset/Contents.json new file mode 100644 index 00000000..6b698302 --- /dev/null +++ b/Bitkit/Assets.xcassets/Illustrations/app-icon-orange.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "app-icon-orange.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Bitkit/Assets.xcassets/Illustrations/app-icon-orange.imageset/app-icon-orange.png b/Bitkit/Assets.xcassets/Illustrations/app-icon-orange.imageset/app-icon-orange.png new file mode 100644 index 0000000000000000000000000000000000000000..681149f94a9b0c12742da6853831f956f487605f GIT binary patch literal 23946 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 Void)? let destination: AnyView? @@ -77,7 +78,8 @@ struct CustomButton: View { icon: (any View)? = nil, isDisabled: Bool = false, isLoading: Bool = false, - shouldExpand: Bool = false + shouldExpand: Bool = false, + background: (any View)? = nil ) { self.title = title self.variant = variant @@ -86,6 +88,7 @@ struct CustomButton: View { self.isDisabled = isDisabled self.isLoading = isLoading self.shouldExpand = shouldExpand + self.background = background.map { AnyView($0) } action = nil destination = nil } @@ -99,6 +102,7 @@ struct CustomButton: View { isDisabled: Bool = false, isLoading: Bool = false, shouldExpand: Bool = false, + background: (any View)? = nil, action: @escaping () async -> Void ) { self.title = title @@ -108,6 +112,7 @@ struct CustomButton: View { self.isDisabled = isDisabled self.isLoading = isLoading self.shouldExpand = shouldExpand + self.background = background.map { AnyView($0) } self.action = action destination = nil } @@ -121,6 +126,7 @@ struct CustomButton: View { isDisabled: Bool = false, isLoading: Bool = false, shouldExpand: Bool = false, + background: (any View)? = nil, destination: some View ) { self.title = title @@ -130,6 +136,7 @@ struct CustomButton: View { self.isDisabled = isDisabled self.isLoading = isLoading self.shouldExpand = shouldExpand + self.background = background.map { AnyView($0) } action = nil self.destination = AnyView(destination) } @@ -144,7 +151,8 @@ struct CustomButton: View { isDisabled: isDisabled, isLoading: isLoading, isPressed: isPressed, - shouldExpand: shouldExpand + shouldExpand: shouldExpand, + background: background )) case .secondary: AnyView(SecondaryButtonView( diff --git a/Bitkit/Components/Button/PrimaryButtonView.swift b/Bitkit/Components/Button/PrimaryButtonView.swift index 8317cb84..b8939370 100644 --- a/Bitkit/Components/Button/PrimaryButtonView.swift +++ b/Bitkit/Components/Button/PrimaryButtonView.swift @@ -8,6 +8,7 @@ struct PrimaryButtonView: View { let isLoading: Bool let isPressed: Bool let shouldExpand: Bool + let background: AnyView? var body: some View { HStack(spacing: 8) { @@ -38,9 +39,14 @@ struct PrimaryButtonView: View { } private var backgroundGradient: some View { + if let background { + return background + } + if isLoading { return AnyView(Color.gray6) } + if isDisabled { return AnyView(Color.clear) } diff --git a/Bitkit/Components/CopyAddressCard.swift b/Bitkit/Components/CopyAddressCard.swift index f2aebf7c..cd37873a 100644 --- a/Bitkit/Components/CopyAddressCard.swift +++ b/Bitkit/Components/CopyAddressCard.swift @@ -49,7 +49,10 @@ struct CopyAddressCard: View { onCopy(address: pair.address, index: index) } - ShareLink(item: URL(string: pair.address)!) { + ShareLink( + item: pair.address, + preview: SharePreview(pair.address, image: Image("app-icon-orange")) + ) { CustomButton( title: t("common__share"), size: .small, @@ -77,7 +80,8 @@ struct CopyAddressCard: View { Spacer() } .frame(maxWidth: .infinity, alignment: .leading) - .padding(32) + .padding(.vertical, 32) + .padding(.horizontal, UIScreen.main.isSmall ? 16 : 32) .background(Color.black) .cornerRadius(8) .aspectRatio(1, contentMode: .fit) diff --git a/Bitkit/Components/MoneyStack.swift b/Bitkit/Components/MoneyStack.swift index d1291639..b14147f4 100644 --- a/Bitkit/Components/MoneyStack.swift +++ b/Bitkit/Components/MoneyStack.swift @@ -25,6 +25,7 @@ struct MoneyStack: View { symbol: true, color: .textSecondary ) + .contentTransition(.numericText()) .transition( .move(edge: .bottom) .combined(with: .opacity) @@ -40,6 +41,7 @@ struct MoneyStack: View { prefix: prefix, color: .textPrimary ) + .contentTransition(.numericText()) Spacer() @@ -60,6 +62,7 @@ struct MoneyStack: View { symbol: true, color: .textSecondary ) + .contentTransition(.numericText()) .transition( .move(edge: .bottom) .combined(with: .opacity) @@ -75,6 +78,7 @@ struct MoneyStack: View { prefix: prefix, color: .textPrimary ) + .contentTransition(.numericText()) Spacer() @@ -179,15 +183,20 @@ private extension MoneyStack { #Preview { ScrollView { VStack(alignment: .leading, spacing: 32) { - // With toggle enabled - MoneyStack(sats: 123_456, prefix: "+", showSymbol: false) + // Large amounts to show dramatic transitions + MoneyStack(sats: 1_234_567_890, prefix: "+", showSymbol: false) .environmentObject(MoneyStack.previewCurrencyVM(primaryDisplay: .bitcoin, currency: "USD")) .environmentObject(MoneyStack.previewSettingsVM()) - // With symbol - MoneyStack(sats: 123_456, prefix: "-", showSymbol: true) + // With symbol and different amount + MoneyStack(sats: 987_654_321, prefix: "-", showSymbol: true) .environmentObject(MoneyStack.previewCurrencyVM(primaryDisplay: .fiat, currency: "EUR")) .environmentObject(MoneyStack.previewSettingsVM()) + + // Medium amount with eye icon + MoneyStack(sats: 456_789_123, showEyeIcon: true) + .environmentObject(MoneyStack.previewCurrencyVM(primaryDisplay: .bitcoin, currency: "USD", displayUnit: .classic)) + .environmentObject(MoneyStack.previewSettingsVM(hideBalance: true)) } .frame(maxWidth: .infinity, alignment: .leading) .padding() diff --git a/Bitkit/Components/NotificationPreview.swift b/Bitkit/Components/NotificationPreview.swift index ca95bf8f..b72ecdaf 100644 --- a/Bitkit/Components/NotificationPreview.swift +++ b/Bitkit/Components/NotificationPreview.swift @@ -14,9 +14,10 @@ struct NotificationPreview: View { var body: some View { HStack(alignment: .top, spacing: 8) { - Image("app-icon") + Image("app-icon-black") .resizable() .frame(width: 38, height: 38) + .cornerRadius(9) VStack(alignment: .leading, spacing: 2) { HStack { diff --git a/Bitkit/Components/NumberPad.swift b/Bitkit/Components/NumberPad.swift index 408d59d9..fba37fa4 100644 --- a/Bitkit/Components/NumberPad.swift +++ b/Bitkit/Components/NumberPad.swift @@ -17,7 +17,7 @@ struct NumberPad: View { self.onPress = onPress } - private let buttonHeight: CGFloat = 44 + 34 + private let buttonHeight: CGFloat = UIScreen.main.isSmall ? 65 : 44 + 34 private let gridItems = Array(repeating: GridItem(.flexible(), spacing: 0), count: 3) private let numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9"] diff --git a/Bitkit/Views/Backup/BackupConfirmMnemonic.swift b/Bitkit/Views/Backup/BackupConfirmMnemonic.swift index 3dd1579c..76b1c087 100644 --- a/Bitkit/Views/Backup/BackupConfirmMnemonic.swift +++ b/Bitkit/Views/Backup/BackupConfirmMnemonic.swift @@ -22,13 +22,12 @@ struct BackupConfirmMnemonic: View { WrappingHStack(spacing: 5) { ForEach(0 ..< shuffledWords.count, id: \.self) { index in - WordButton( - word: shuffledWords[index], - isPressed: pressedIndices.contains(index), - onTap: { - handleWordPress(word: shuffledWords[index], index: index) - } - ) + let word = shuffledWords[index] + let isPressed = pressedIndices.contains(index) + + CustomButton(title: word, size: .small, background: isPressed ? Color.white32 : nil) { + handleWordPress(word: word, index: index) + } } } @@ -118,26 +117,6 @@ struct BackupConfirmMnemonic: View { } } -struct WordButton: View { - let word: String - let isPressed: Bool - let onTap: () -> Void - - var body: some View { - Button(action: onTap) { - Text(word) - .font(.system(size: 15, weight: .semibold)) - .foregroundColor(.textPrimary) - .padding(.horizontal, 12) - .padding(.vertical, 12) - .frame(minWidth: 50) - .background(isPressed ? Color.white32 : Color.white16) - .cornerRadius(54) - } - .buttonStyle(PlainButtonStyle()) - } -} - struct ConfirmWordView: View { let number: Int let word: String diff --git a/Bitkit/Views/Backup/BackupMetadata.swift b/Bitkit/Views/Backup/BackupMetadata.swift index f8a544ff..c8800533 100644 --- a/Bitkit/Views/Backup/BackupMetadata.swift +++ b/Bitkit/Views/Backup/BackupMetadata.swift @@ -21,8 +21,13 @@ struct BackupMetadata: View { Spacer() // TODO: Add actual last backup time - BodySText(t("security__mnemonic_latest_backup", variables: ["time": "12/06/2025 12:00"])) - .padding(.bottom, 16) + BodySText( + tTodo("Latest full backup: {time}", variables: ["time": "12/06/2025 12:00"]), + textColor: .textPrimary, + accentColor: .textPrimary, + accentFont: Fonts.bold + ) + .padding(.bottom, 16) CustomButton(title: t("common__ok")) { sheets.hideSheet() diff --git a/Bitkit/Views/Backup/BackupMnemonic.swift b/Bitkit/Views/Backup/BackupMnemonic.swift index 4d346965..aa8c76ed 100644 --- a/Bitkit/Views/Backup/BackupMnemonic.swift +++ b/Bitkit/Views/Backup/BackupMnemonic.swift @@ -7,12 +7,24 @@ struct BackupMnemonicView: View { @State private var passphrase: String = "" @State private var showMnemonic: Bool = false + private var text: String { + showMnemonic + ? t("security__mnemonic_write", variables: ["length": "\(mnemonic.count)"]) + : t("security__mnemonic_use") + } + + private var note: String { + showMnemonic + ? "Bitkit cannot access your funds and cannot help recover them if you lose your recovery phrase. Keep it safe!" + : "Make sure no one can see your screen. Never share your recovery phrase with anyone, as it may result in loss of funds." + } + var body: some View { VStack(alignment: .leading, spacing: 0) { SheetHeader(title: t("security__mnemonic_your")) VStack(spacing: 0) { - BodyMText(t("security__mnemonic_write", variables: ["length": "\(mnemonic.count)"])) + BodyMText(text) .frame(maxWidth: .infinity, alignment: .leading) .padding(.bottom, 16) @@ -35,25 +47,18 @@ struct BackupMnemonicView: View { .frame(maxWidth: .infinity, alignment: .leading) } .padding(32) - .background(Color.white10) + .background(Color.gray6) .blur(radius: showMnemonic ? 0 : 5) .privacySensitive() if !showMnemonic { - Button(action: { + CustomButton( + title: t("security__mnemonic_reveal"), + icon: Image("eye").resizable().frame(width: 16, height: 16) + ) { showMnemonic = true - }) { - BodySSBText(t("security__mnemonic_reveal")) - .frame(width: 154, height: 56) - .background(Color.black50) - .cornerRadius(64) } - .shadow( - color: Color.black.opacity(0.25), - radius: 50, - x: 0, - y: 25 - ) + .frame(maxWidth: 180) } } .cornerRadius(16) @@ -67,15 +72,12 @@ struct BackupMnemonicView: View { } } - BodySText(t("security__mnemonic_never_share"), accentColor: .brandAccent) + BodySText(tTodo(note), textColor: .brandAccent, accentFont: Fonts.bold) Spacer() HStack(alignment: .center, spacing: 16) { - CustomButton( - title: t("common__continue"), - isDisabled: !showMnemonic - ) { + CustomButton(title: t("common__continue"), isDisabled: !showMnemonic) { let route = passphrase.isEmpty ? BackupRoute.confirmMnemonic(mnemonic: mnemonic, passphrase: passphrase) @@ -83,7 +85,6 @@ struct BackupMnemonicView: View { navigationPath.append(route) } } - .padding(.top, 32) } .padding(.horizontal, 16) } diff --git a/Bitkit/Views/Backup/BackupPassphrase.swift b/Bitkit/Views/Backup/BackupPassphrase.swift index 253eb92f..ecebb682 100644 --- a/Bitkit/Views/Backup/BackupPassphrase.swift +++ b/Bitkit/Views/Backup/BackupPassphrase.swift @@ -25,21 +25,23 @@ struct BackupPassphrase: View { } .padding(32) .frame(maxHeight: .infinity) - .background(Color.white10) + .background(Color.gray6) .cornerRadius(16) .padding(.top, 16) .padding(.bottom, 32) .privacySensitive() .frame(maxWidth: .infinity) - BodySText(t("security__pass_never_share"), accentColor: .brandAccent) + BodySText( + tTodo("Never share your passphrase with anyone, as it may result in loss of funds. Keep it secret!"), + accentColor: .brandAccent, + accentFont: Fonts.bold + ) Spacer() HStack(alignment: .center, spacing: 16) { - CustomButton( - title: t("common__continue") - ) { + CustomButton(title: t("common__continue")) { navigationPath.append(.confirmMnemonic(mnemonic: mnemonic, passphrase: passphrase)) } } diff --git a/Bitkit/Views/Settings/Advanced/CoinSelectionSettingsView.swift b/Bitkit/Views/Settings/Advanced/CoinSelectionSettingsView.swift index 9b3e00e7..8ca39f7f 100644 --- a/Bitkit/Views/Settings/Advanced/CoinSelectionSettingsView.swift +++ b/Bitkit/Views/Settings/Advanced/CoinSelectionSettingsView.swift @@ -67,10 +67,12 @@ struct CoinSelectionMethodOption: View { Spacer() if isSelected { Image("checkmark") + .resizable() + .frame(width: 32, height: 32) .foregroundColor(.brandAccent) } } - .padding(.vertical, 8) + .frame(height: 51) .contentShape(Rectangle()) } .buttonStyle(PlainButtonStyle()) @@ -84,26 +86,25 @@ struct CoinSelectionAlgorithmOption: View { var body: some View { Button(action: onTap) { - VStack(alignment: .leading, spacing: 8) { + VStack(alignment: .leading, spacing: 0) { HStack { BodyMText(algorithm.localizedTitle, textColor: .textPrimary) Spacer() if isSelected { Image("checkmark") + .resizable() + .frame(width: 32, height: 32) .foregroundColor(.brandAccent) - .frame(width: 23, height: 16) } } + .frame(height: 51) - Divider() + BodySText(algorithm.localizedDescription) + .multilineTextAlignment(.leading) + .padding(.bottom, 16) - BodySText( - algorithm.localizedDescription, - textColor: .textSecondary - ) - .multilineTextAlignment(.leading) + Divider() } - .padding(.vertical, 12) .contentShape(Rectangle()) } .buttonStyle(PlainButtonStyle()) @@ -122,19 +123,12 @@ struct CoinSelectionSettingsView: View { VStack(spacing: 0) { // COIN SELECTION METHOD Section VStack(alignment: .leading, spacing: 0) { - HStack { - BodyMText( - t("settings__adv__cs_method"), - textColor: .textSecondary - ) + CaptionMText(t("settings__adv__cs_method")) .padding(.bottom, 8) - Spacer() - } - VStack(spacing: 0) { ForEach(CoinSelectionMethod.allCases, id: \.self) { method in - VStack { + VStack(spacing: 0) { CoinSelectionMethodOption( method: method, isSelected: settingsViewModel.coinSelectionMethod == method @@ -153,17 +147,10 @@ struct CoinSelectionSettingsView: View { // AUTOPILOT MODE Section (only show if Autopilot is selected) if settingsViewModel.coinSelectionMethod == .autopilot { VStack(alignment: .leading, spacing: 0) { - HStack { - BodyMText( - t("settings__adv__cs_auto_mode"), - textColor: .textSecondary - ) + CaptionMText(t("settings__adv__cs_auto_mode")) .padding(.top, 24) .padding(.bottom, 8) - Spacer() - } - VStack(spacing: 0) { ForEach(CoinSelectionAlgorithm.supportedAlgorithms, id: \.self) { algorithm in VStack { diff --git a/Bitkit/Views/Settings/General/LocalCurrencySettingsView.swift b/Bitkit/Views/Settings/General/LocalCurrencySettingsView.swift index 3307dcff..7854bac3 100644 --- a/Bitkit/Views/Settings/General/LocalCurrencySettingsView.swift +++ b/Bitkit/Views/Settings/General/LocalCurrencySettingsView.swift @@ -42,12 +42,30 @@ struct LocalCurrencySettingsView: View { var body: some View { VStack(alignment: .leading, spacing: 0) { NavigationBar(title: t("settings__general__currency_local_title")) + .padding(.bottom, 16) + + // Custom search bar + HStack(spacing: 0) { + Image("magnifying-glass") + .resizable() + .frame(width: 24, height: 24) + .foregroundColor(!searchText.isEmpty ? .brandAccent : .white64) + TextField(t("common__search"), text: $searchText, backgroundColor: .clear, font: .custom(Fonts.regular, size: 17)) + .frame(maxWidth: .infinity) + .offset(x: -5) + } + .frame(height: 48) + .padding(.horizontal, 16) + .background(Color.gray6) + .cornerRadius(32) + .padding(.bottom, 16) ScrollView(showsIndicators: false) { if !availableMostUsed.isEmpty { - VStack(alignment: .leading, spacing: 8) { - CaptionText(t("settings__general__currency_most_used").uppercased()) - .padding(.vertical, 16) + VStack(alignment: .leading, spacing: 0) { + CaptionMText(t("settings__general__currency_most_used")) + .padding(.top, 16) + .padding(.bottom, 8) .frame(maxWidth: .infinity, alignment: .leading) ForEach(availableMostUsed, id: \.quote) { rate in @@ -56,22 +74,25 @@ struct LocalCurrencySettingsView: View { } } - VStack(alignment: .leading, spacing: 8) { - CaptionText(t("settings__general__currency_other").uppercased()) - .padding(.vertical, 16) + VStack(alignment: .leading, spacing: 0) { + CaptionMText(t("settings__general__currency_other")) + .padding(.top, 24) + .padding(.bottom, 8) .frame(maxWidth: .infinity, alignment: .leading) ForEach(otherCurrencies, id: \.quote) { rate in currencyRow(rate) } } + + CaptionText(t("settings__general__currency_footer")) + .padding(.top, 16) + .frame(maxWidth: .infinity, alignment: .leading) } } .navigationBarHidden(true) .padding(.horizontal, 16) .bottomSafeAreaPadding() - // TODO: Fix search - .searchable(text: $searchText, prompt: t("common__search")) } } diff --git a/Bitkit/Views/Settings/General/TagSettingsView.swift b/Bitkit/Views/Settings/General/TagSettingsView.swift index 2750d563..dd375a96 100644 --- a/Bitkit/Views/Settings/General/TagSettingsView.swift +++ b/Bitkit/Views/Settings/General/TagSettingsView.swift @@ -10,8 +10,7 @@ struct TagSettingsView: View { ScrollView(showsIndicators: false) { VStack(alignment: .leading, spacing: 0) { - CaptionText(t("settings__general__tags_previously")) - .textCase(.uppercase) + CaptionMText(t("settings__general__tags_previously")) .padding(.top, 24) .padding(.bottom, 16) .frame(maxWidth: .infinity, alignment: .leading) diff --git a/Bitkit/Views/Settings/MainSettings.swift b/Bitkit/Views/Settings/MainSettings.swift index d9b59ad1..1d15fba2 100644 --- a/Bitkit/Views/Settings/MainSettings.swift +++ b/Bitkit/Views/Settings/MainSettings.swift @@ -1,11 +1,7 @@ import SwiftUI struct MainSettings: View { - @EnvironmentObject var app: AppViewModel - @EnvironmentObject var activity: ActivityListViewModel - @EnvironmentObject var navigation: NavigationViewModel - @EnvironmentObject var wallet: WalletViewModel - @EnvironmentObject var widgets: WidgetsViewModel + @EnvironmentObject private var app: AppViewModel @AppStorage("showDevSettings") private var showDevSettings = Env.isDebug @State private var cogTapCount = 0 @@ -69,7 +65,6 @@ struct MainSettings: View { } Spacer() - .frame(minHeight: 32) Image("cog") .resizable() @@ -93,7 +88,6 @@ struct MainSettings: View { } Spacer() - .frame(minHeight: 32) } .frame(minHeight: geometry.size.height) } diff --git a/Bitkit/Views/Settings/Quickpay/QuickpaySettings.swift b/Bitkit/Views/Settings/Quickpay/QuickpaySettings.swift index 47427071..a375252b 100644 --- a/Bitkit/Views/Settings/Quickpay/QuickpaySettings.swift +++ b/Bitkit/Views/Settings/Quickpay/QuickpaySettings.swift @@ -1,15 +1,14 @@ import SwiftUI struct QuickpaySettings: View { - @EnvironmentObject var app: AppViewModel - @EnvironmentObject var navigation: NavigationViewModel - @EnvironmentObject var settings: SettingsViewModel + @EnvironmentObject private var settings: SettingsViewModel private let sliderSteps: [Double] = [1, 5, 10, 20, 50] var body: some View { VStack(alignment: .leading, spacing: 0) { NavigationBar(title: t("settings__quickpay__nav_title")) + .padding(.horizontal, 16) GeometryReader { geometry in ScrollView(showsIndicators: false) { @@ -25,10 +24,7 @@ struct QuickpaySettings: View { .padding(.top, 16) VStack(alignment: .leading, spacing: 16) { - CaptionText( - t("settings__quickpay__settings__label").uppercased() - ) - + CaptionMText(t("settings__quickpay__settings__label")) CustomSlider(value: $settings.quickpayAmount, steps: sliderSteps) } .padding(.top, 32) @@ -45,19 +41,16 @@ struct QuickpaySettings: View { } .frame(maxWidth: .infinity) .padding(.horizontal, 16) - .padding(.vertical, 32) + // .padding(.vertical, 32) - BodySText( - t("settings__quickpay__settings__note"), - textColor: .textSecondary - ) + BodySText(t("settings__quickpay__settings__note")) } .frame(minHeight: geometry.size.height) + .padding(.horizontal, 16) .bottomSafeAreaPadding() } } } .navigationBarHidden(true) - .padding(.horizontal, 16) } } diff --git a/Bitkit/Views/Settings/Support/ReportIssue.swift b/Bitkit/Views/Settings/Support/ReportIssue.swift index 8fe6458a..c0ee7c67 100644 --- a/Bitkit/Views/Settings/Support/ReportIssue.swift +++ b/Bitkit/Views/Settings/Support/ReportIssue.swift @@ -105,7 +105,7 @@ struct ReportIssue: View { VStack(alignment: .leading, spacing: 26) { VStack(alignment: .leading, spacing: 8) { - CaptionText(t("settings__support__label_address").uppercased()) + CaptionMText(t("settings__support__label_address")) TextField( t("settings__support__placeholder_address"), @@ -117,10 +117,7 @@ struct ReportIssue: View { } VStack(alignment: .leading, spacing: 8) { - CaptionText( - t("settings__support__label_message").uppercased(), - textColor: .textSecondary - ) + CaptionMText(t("settings__support__label_message")) ZStack(alignment: .topLeading) { if message.isEmpty { diff --git a/Bitkit/Views/Settings/TransactionSpeed/TransactionSpeedSettingsView.swift b/Bitkit/Views/Settings/TransactionSpeed/TransactionSpeedSettingsView.swift index 2ec00864..b5a4d8d9 100644 --- a/Bitkit/Views/Settings/TransactionSpeed/TransactionSpeedSettingsView.swift +++ b/Bitkit/Views/Settings/TransactionSpeed/TransactionSpeedSettingsView.swift @@ -17,7 +17,7 @@ struct TransactionSpeedSettingsRow: View { var body: some View { Button(action: onSelect) { - HStack { + HStack(spacing: 0) { Image(speed.iconName) .resizable() .scaledToFit() diff --git a/Bitkit/Views/Shop/ShopDiscover.swift b/Bitkit/Views/Shop/ShopDiscover.swift index 812874e8..cd3a4fa1 100644 --- a/Bitkit/Views/Shop/ShopDiscover.swift +++ b/Bitkit/Views/Shop/ShopDiscover.swift @@ -111,8 +111,7 @@ struct ShopDiscover: View { .padding(.bottom, 16) VStack { - CaptionText(t("other__shop__discover__label")) - .textCase(.uppercase) + CaptionMText(t("other__shop__discover__label")) .frame(maxWidth: .infinity, alignment: .leading) } .frame(height: 50) diff --git a/Bitkit/Views/Transfer/FundManualAmountView.swift b/Bitkit/Views/Transfer/FundManualAmountView.swift index 2993d34c..9d41494f 100644 --- a/Bitkit/Views/Transfer/FundManualAmountView.swift +++ b/Bitkit/Views/Transfer/FundManualAmountView.swift @@ -20,6 +20,7 @@ struct FundManualAmountView: View { VStack(alignment: .leading, spacing: 0) { DisplayText(t("lightning__external_amount__title"), accentColor: .purpleAccent) + .fixedSize(horizontal: false, vertical: true) NumberPadTextField(viewModel: amountViewModel, showConversion: false) .onTapGesture { diff --git a/Bitkit/Views/Transfer/FundManualSuccessView.swift b/Bitkit/Views/Transfer/FundManualSuccessView.swift index 5abb9e21..62043a14 100644 --- a/Bitkit/Views/Transfer/FundManualSuccessView.swift +++ b/Bitkit/Views/Transfer/FundManualSuccessView.swift @@ -17,6 +17,7 @@ struct FundManualSuccessView: View { t("lightning__external_success__title"), accentColor: .purpleAccent ) + .fixedSize(horizontal: false, vertical: true) BodyMText( t("lightning__external_success__text"), diff --git a/Bitkit/Views/Transfer/SavingsConfirmView.swift b/Bitkit/Views/Transfer/SavingsConfirmView.swift index 3d992d9c..f37260ac 100644 --- a/Bitkit/Views/Transfer/SavingsConfirmView.swift +++ b/Bitkit/Views/Transfer/SavingsConfirmView.swift @@ -40,6 +40,7 @@ struct SavingsConfirmView: View { .padding(.bottom, 16) DisplayText(t("lightning__transfer__confirm"), accentColor: .brandAccent) + .fixedSize(horizontal: false, vertical: true) CaptionMText(t("lightning__savings_confirm__label")) .padding(.top, 32) diff --git a/Bitkit/Views/Transfer/SettingUpView.swift b/Bitkit/Views/Transfer/SettingUpView.swift index d02fe7ac..9249de87 100644 --- a/Bitkit/Views/Transfer/SettingUpView.swift +++ b/Bitkit/Views/Transfer/SettingUpView.swift @@ -1,6 +1,61 @@ import BitkitCore import SwiftUI +struct SettingUpLoadingView: View { + @State private var outerRotation: Double = 0 + @State private var innerRotation: Double = 0 + @State private var transferRotation: Double = 0 + + var size: (container: CGFloat, image: CGFloat, inner: CGFloat) { + let container: CGFloat = UIScreen.main.isSmall ? 200 : 320 + let image = container * 0.8 + let inner = container * 0.7 + + return (container: container, image: image, inner: inner) + } + + var body: some View { + ZStack(alignment: .center) { + // Outer ellipse + Image("ellipse-outer-purple") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: size.container, height: size.container) + .rotationEffect(.degrees(outerRotation)) + + // Inner ellipse + Image("ellipse-inner-purple") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: size.inner, height: size.inner) + .rotationEffect(.degrees(innerRotation)) + + // Transfer image + Image("transfer-figure") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: size.image, height: size.image) + .rotationEffect(.degrees(transferRotation)) + } + .frame(width: size.container, height: size.container) + .clipped() + .frame(maxWidth: .infinity) + .onAppear { + withAnimation(.easeInOut(duration: 3).repeatForever(autoreverses: true)) { + outerRotation = -90 + } + + withAnimation(.easeInOut(duration: 3).repeatForever(autoreverses: true)) { + innerRotation = 120 + } + + withAnimation(.easeInOut(duration: 3).repeatForever(autoreverses: true)) { + transferRotation = 90 + } + } + } +} + struct ProgressSteps: View { let steps: [String] let currentStep: Int @@ -68,9 +123,6 @@ struct SettingUpView: View { @EnvironmentObject var navigation: NavigationViewModel @EnvironmentObject var transfer: TransferViewModel - @State private var outerRotation: Double = 0 - @State private var innerRotation: Double = 0 - @State private var transferRotation: Double = 0 // Keep in state so we don't get a new random text on each render @State private var randomOkText: String = localizedRandom("common__ok_random") @@ -116,44 +168,7 @@ struct SettingUpView: View { Spacer() if isTransferring { - ZStack(alignment: .center) { - // Outer ellipse - Image("ellipse-outer-purple") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 311, height: 311) - .rotationEffect(.degrees(outerRotation)) - - // Inner ellipse - Image("ellipse-inner-purple") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 207, height: 207) - .rotationEffect(.degrees(innerRotation)) - - // Transfer image - Image("transfer-figure") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 256, height: 256) - .rotationEffect(.degrees(transferRotation)) - } - .frame(width: 320, height: 320) - .clipped() - .frame(maxWidth: .infinity) - .onAppear { - withAnimation(.easeInOut(duration: 3).repeatForever(autoreverses: true)) { - outerRotation = -90 - } - - withAnimation(.easeInOut(duration: 3).repeatForever(autoreverses: true)) { - innerRotation = 120 - } - - withAnimation(.easeInOut(duration: 3).repeatForever(autoreverses: true)) { - transferRotation = 90 - } - } + SettingUpLoadingView() } else { Image("check") .resizable() @@ -167,7 +182,7 @@ struct SettingUpView: View { if isTransferring { ProgressSteps(steps: steps, currentStep: transfer.lightningSetupStep) - .padding(.bottom, 32) + .padding(.bottom, 16) } CustomButton(title: buttonTitle) { diff --git a/Bitkit/Views/Transfer/SpendingAdvancedView.swift b/Bitkit/Views/Transfer/SpendingAdvancedView.swift index eef8ed68..5e0bdbbe 100644 --- a/Bitkit/Views/Transfer/SpendingAdvancedView.swift +++ b/Bitkit/Views/Transfer/SpendingAdvancedView.swift @@ -31,6 +31,7 @@ struct SpendingAdvancedView: View { VStack(alignment: .leading, spacing: 0) { DisplayText(t("lightning__spending_advanced__title"), accentColor: .purpleAccent) + .fixedSize(horizontal: false, vertical: true) NumberPadTextField(viewModel: amountViewModel, showConversion: false) .onTapGesture { diff --git a/Bitkit/Views/Transfer/SpendingAmount.swift b/Bitkit/Views/Transfer/SpendingAmount.swift index dca230d2..7397a900 100644 --- a/Bitkit/Views/Transfer/SpendingAmount.swift +++ b/Bitkit/Views/Transfer/SpendingAmount.swift @@ -32,6 +32,7 @@ struct SpendingAmount: View { .padding(.bottom, 16) DisplayText(t("lightning__spending_amount__title"), accentColor: .purpleAccent) + .fixedSize(horizontal: false, vertical: true) NumberPadTextField(viewModel: amountViewModel, showConversion: false) .onTapGesture { diff --git a/Bitkit/Views/Transfer/SpendingConfirm.swift b/Bitkit/Views/Transfer/SpendingConfirm.swift index 8e45e7bc..9a752d33 100644 --- a/Bitkit/Views/Transfer/SpendingConfirm.swift +++ b/Bitkit/Views/Transfer/SpendingConfirm.swift @@ -25,7 +25,7 @@ struct SpendingConfirm: View { var body: some View { VStack(alignment: .leading, spacing: 0) { NavigationBar(title: t("lightning__transfer__nav_title")) - .padding(.bottom, 32) + .padding(.bottom, 16) DisplayText(t("lightning__transfer__confirm"), accentColor: .purpleAccent) diff --git a/Bitkit/Views/Wallets/Activity/ActivityItemView.swift b/Bitkit/Views/Wallets/Activity/ActivityItemView.swift index 6018085f..f691a586 100644 --- a/Bitkit/Views/Wallets/Activity/ActivityItemView.swift +++ b/Bitkit/Views/Wallets/Activity/ActivityItemView.swift @@ -101,28 +101,33 @@ struct ActivityItemView: View { } var body: some View { - VStack(alignment: .leading, spacing: 16) { + VStack(alignment: .leading, spacing: 0) { NavigationBar(title: navigationTitle) + .padding(.bottom, 16) - HStack(alignment: .bottom) { - MoneyStack(sats: amount, prefix: amountPrefix, showSymbol: false) - Spacer() - ActivityIcon(activity: viewModel.activity, size: 48) - } - .padding(.bottom, 16) + ScrollView(showsIndicators: false) { + VStack(spacing: 16) { + HStack(alignment: .bottom) { + MoneyStack(sats: amount, prefix: amountPrefix, showSymbol: false) + Spacer() + ActivityIcon(activity: viewModel.activity, size: 48) + } + .padding(.bottom, 16) - statusSection - timestampSection - feeSection - tagsSection - note - buttons + statusSection + timestampSection + feeSection + tagsSection + note + buttons - Spacer() + Spacer() + } + .bottomSafeAreaPadding() + } } .navigationBarHidden(true) .padding(.horizontal, 16) - .bottomSafeAreaPadding() .onChange(of: sheets.addTagSheetItem) { item in if item == nil { // Add tag sheet was closed, reload tags in case they were modified @@ -158,6 +163,7 @@ struct ActivityItemView: View { BodySSBText(t("wallet__activity_pending"), textColor: .purpleAccent) case .succeeded: Image("bolt") + .resizable() .foregroundColor(.purpleAccent) .frame(width: 16, height: 16) BodySSBText(t("wallet__activity_successful"), textColor: .purpleAccent) diff --git a/Bitkit/Views/Wallets/Activity/ActivityRowLightning.swift b/Bitkit/Views/Wallets/Activity/ActivityRowLightning.swift index 929f118e..c1f9e0f3 100644 --- a/Bitkit/Views/Wallets/Activity/ActivityRowLightning.swift +++ b/Bitkit/Views/Wallets/Activity/ActivityRowLightning.swift @@ -47,6 +47,7 @@ struct ActivityRowLightning: View { VStack(alignment: .leading, spacing: 2) { ActivityStatus(txType: item.txType, status: item.status) CaptionBText(item.message.isEmpty ? formattedTime : item.message) + .lineLimit(1) } Spacer() diff --git a/Bitkit/Views/Wallets/Receive/ReceiveQr.swift b/Bitkit/Views/Wallets/Receive/ReceiveQr.swift index 67728b31..ba5d5119 100644 --- a/Bitkit/Views/Wallets/Receive/ReceiveQr.swift +++ b/Bitkit/Views/Wallets/Receive/ReceiveQr.swift @@ -86,11 +86,14 @@ struct ReceiveQr: View { Spacer() - VStack(spacing: 0) { + Group { if showingCjitOnboarding { CustomButton( title: t("wallet__receive_spending"), - icon: Image("bolt").foregroundColor(.purpleAccent), + icon: Image("bolt") + .resizable() + .frame(width: 16, height: 16) + .foregroundColor(.purpleAccent), isDisabled: wallet.nodeLifecycleState != .running ) { navigationPath.append(.cjitAmount) @@ -207,11 +210,13 @@ struct ReceiveQr: View { .cornerRadius(8) .aspectRatio(1, contentMode: .fit) .overlay(alignment: .bottomLeading) { - Image("arrow-cjit") - .resizable() - .scaledToFit() - .frame(height: 210) - .offset(x: 70, y: 110) + if !UIScreen.main.isSmall { + Image("arrow-cjit") + .resizable() + .scaledToFit() + .frame(height: 210) + .offset(x: 70, y: 110) + } } } diff --git a/Bitkit/Views/Wallets/Send/SendConfirmationView.swift b/Bitkit/Views/Wallets/Send/SendConfirmationView.swift index 4ffe4f91..9f9bb37c 100644 --- a/Bitkit/Views/Wallets/Send/SendConfirmationView.swift +++ b/Bitkit/Views/Wallets/Send/SendConfirmationView.swift @@ -521,7 +521,7 @@ struct SendConfirmationView: View { BodySSBText(description) } .frame(maxWidth: .infinity, alignment: .leading) - .padding(.bottom, 16) + .padding(.vertical, 16) Divider() } diff --git a/Bitkit/Views/Wallets/Send/SendEnterManuallyView.swift b/Bitkit/Views/Wallets/Send/SendEnterManuallyView.swift index e7bf875d..9e36958f 100644 --- a/Bitkit/Views/Wallets/Send/SendEnterManuallyView.swift +++ b/Bitkit/Views/Wallets/Send/SendEnterManuallyView.swift @@ -12,7 +12,7 @@ struct SendEnterManuallyView: View { VStack { SheetHeader(title: t("wallet__send_bitcoin"), showBackButton: true) - CaptionText(t("wallet__send_to").uppercased()) + CaptionMText(t("wallet__send_to")) .frame(maxWidth: .infinity, alignment: .leading) ZStack(alignment: .topLeading) { diff --git a/Bitkit/Views/Widgets/WidgetDetailView.swift b/Bitkit/Views/Widgets/WidgetDetailView.swift index 10ce4e17..409b1182 100644 --- a/Bitkit/Views/Widgets/WidgetDetailView.swift +++ b/Bitkit/Views/Widgets/WidgetDetailView.swift @@ -122,8 +122,7 @@ struct WidgetDetailView: View { Spacer() VStack(alignment: .leading, spacing: 0) { - CaptionText(t("common__preview")) - .textCase(.uppercase) + CaptionMText(t("common__preview")) .padding(.top, 16) .padding(.bottom, 16)