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 00000000..65fc9a8f
Binary files /dev/null and b/Bitkit/Assets.xcassets/Illustrations/app-icon-black.imageset/app-icon-black.png differ
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 00000000..681149f9
Binary files /dev/null and b/Bitkit/Assets.xcassets/Illustrations/app-icon-orange.imageset/app-icon-orange.png differ
diff --git a/Bitkit/Assets.xcassets/Illustrations/app-icon.imageset/app-icon.png b/Bitkit/Assets.xcassets/Illustrations/app-icon.imageset/app-icon.png
deleted file mode 100644
index b13fff87..00000000
Binary files a/Bitkit/Assets.xcassets/Illustrations/app-icon.imageset/app-icon.png and /dev/null differ
diff --git a/Bitkit/Assets.xcassets/icons/bolt.imageset/bolt.pdf b/Bitkit/Assets.xcassets/icons/bolt.imageset/bolt.pdf
index 6109cbaa..8dd13d9c 100644
Binary files a/Bitkit/Assets.xcassets/icons/bolt.imageset/bolt.pdf and b/Bitkit/Assets.xcassets/icons/bolt.imageset/bolt.pdf differ
diff --git a/Bitkit/Components/Button/Button.swift b/Bitkit/Components/Button/Button.swift
index 4c8dfb50..e3b97d89 100644
--- a/Bitkit/Components/Button/Button.swift
+++ b/Bitkit/Components/Button/Button.swift
@@ -64,6 +64,7 @@ struct CustomButton: View {
let isDisabled: Bool
let isLoading: Bool
let shouldExpand: Bool
+ let background: AnyView?
let action: (() async -> 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)