Skip to content

Commit ddf573f

Browse files
committed
feat: Added circular progress view
1 parent 2521e9d commit ddf573f

File tree

6 files changed

+111
-45
lines changed

6 files changed

+111
-45
lines changed

BDKSwiftExampleWallet.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
77F6A9E72DE248A2003568F0 /* EsploraService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77F6A9E62DE248A1003568F0 /* EsploraService.swift */; };
2020
77F6A9E92DE25C9C003568F0 /* KyotoService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77F6A9E82DE25C98003568F0 /* KyotoService.swift */; };
2121
77F6A9EB2DE5072E003568F0 /* AppStorageUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77F6A9EA2DE50727003568F0 /* AppStorageUtil.swift */; };
22+
77F80F582DFCC33D002ACBA2 /* CircularProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77F80F572DFCC33D002ACBA2 /* CircularProgressView.swift */; };
2223
A733D6D02A81113000F333B4 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = A733D6CF2A81113000F333B4 /* Localizable.xcstrings */; };
2324
A73F7A362A3B778E00B87FC6 /* Int+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A73F7A352A3B778E00B87FC6 /* Int+Extensions.swift */; };
2425
AE0C30F72A804A2D008F1EAE /* TransactionListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE0C30F62A804A2D008F1EAE /* TransactionListView.swift */; };
@@ -131,6 +132,7 @@
131132
77F6A9E62DE248A1003568F0 /* EsploraService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EsploraService.swift; sourceTree = "<group>"; };
132133
77F6A9E82DE25C98003568F0 /* KyotoService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KyotoService.swift; sourceTree = "<group>"; };
133134
77F6A9EA2DE50727003568F0 /* AppStorageUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStorageUtil.swift; sourceTree = "<group>"; };
135+
77F80F572DFCC33D002ACBA2 /* CircularProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircularProgressView.swift; sourceTree = "<group>"; };
134136
A733D6CF2A81113000F333B4 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
135137
A73F7A352A3B778E00B87FC6 /* Int+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Int+Extensions.swift"; sourceTree = "<group>"; };
136138
AE0C30F62A804A2D008F1EAE /* TransactionListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionListView.swift; sourceTree = "<group>"; };
@@ -363,6 +365,7 @@
363365
AE2381B62C61253200F6B00C /* Activity */ = {
364366
isa = PBXGroup;
365367
children = (
368+
77F80F572DFCC33D002ACBA2 /* CircularProgressView.swift */,
366369
AE2381AC2C60578500F6B00C /* ActivityListView.swift */,
367370
AE0C30F62A804A2D008F1EAE /* TransactionListView.swift */,
368371
AE29ED102BBE318A00EB9C4F /* TransactionItemView.swift */,
@@ -749,6 +752,7 @@
749752
AEB159D32D51A7E00006AE9E /* BalanceDisplayFormat.swift in Sources */,
750753
AE18E9382A9528200019D2A4 /* Bundle+Extensions.swift in Sources */,
751754
AE79538E2A2D59F000CCB277 /* Constants.swift in Sources */,
755+
77F80F582DFCC33D002ACBA2 /* CircularProgressView.swift in Sources */,
752756
AE2F255D2BED0BFB002A9AC6 /* AppError.swift in Sources */,
753757
AEE6C74F2ABCBA4600442ADD /* WalletSyncState.swift in Sources */,
754758
AE1C34242A424456008F807A /* ReceiveView.swift in Sources */,

BDKSwiftExampleWallet/Resources/Localizable.xcstrings

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@
236236
}
237237
}
238238
}
239+
},
240+
"%lld%%" : {
241+
239242
},
240243
"%llu" : {
241244
"localizations" : {
@@ -451,6 +454,9 @@
451454
}
452455
}
453456
}
457+
},
458+
"Conecting" : {
459+
454460
},
455461
"confirmed" : {
456462
"localizations" : {

BDKSwiftExampleWallet/View Model/WalletViewModel.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ class WalletViewModel {
4242
var needsFullScan: Bool {
4343
bdkClient.needsFullScan()
4444
}
45+
var syncMode: SyncMode {
46+
bdkClient.getSyncMode() ?? .esplora
47+
}
4548

4649
init(
4750
bdkClient: BDKClient = .live,
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// CircularProgressView.swift
3+
// BDKSwiftExampleWallet
4+
//
5+
// Created by Rubens Machion on 13/06/25.
6+
//
7+
8+
import SwiftUI
9+
10+
struct CircularProgressView: View {
11+
var progress: Float
12+
private let lineWidth: CGFloat = 2.0
13+
var body: some View {
14+
ZStack {
15+
Circle()
16+
.stroke(Color.gray.opacity(0.3), lineWidth: lineWidth)
17+
18+
Circle()
19+
.trim(from: 0.0, to: CGFloat(progress))
20+
.stroke(Color.blue, style: StrokeStyle(lineWidth: lineWidth, lineCap: .round))
21+
.rotationEffect(.degrees(-90))
22+
.animation(.easeInOut(duration: 0.5), value: progress)
23+
24+
Text("\(Int(progress * 100))%")
25+
.contentTransition(.numericText())
26+
.font(.system(size: 9.0))
27+
.foregroundStyle(.secondary)
28+
.fontWeight(.regular)
29+
}
30+
}
31+
}

BDKSwiftExampleWallet/View/Home/ActivityHomeHeaderView.swift

Lines changed: 65 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct ActivityHomeHeaderView: View {
1414
let inspectedScripts: UInt64
1515
let totalScripts: UInt64
1616
let needsFullScan: Bool
17+
let syncMode: SyncMode
1718

1819
let showAllTransactions: () -> Void
1920

@@ -24,60 +25,80 @@ struct ActivityHomeHeaderView: View {
2425

2526
HStack {
2627
if needsFullScan {
27-
Text("\(inspectedScripts)")
28-
.padding(.trailing, -5.0)
29-
.fontWeight(.semibold)
30-
.contentTransition(.numericText())
31-
.transition(.opacity)
28+
if syncMode == .esplora {
29+
Text("\(inspectedScripts)")
30+
.padding(.trailing, -5.0)
31+
.fontWeight(.semibold)
32+
.contentTransition(.numericText())
33+
.transition(.opacity)
34+
.fontDesign(.monospaced)
35+
.foregroundStyle(.secondary)
36+
.font(.caption2)
37+
.fontWeight(.thin)
38+
.animation(.easeInOut, value: inspectedScripts)
39+
} else if syncMode == .kyoto {
40+
CircularProgressView(
41+
progress: Float(inspectedScripts) / Float(100.0)
42+
)
43+
.frame(width: 30.0, height: 30.0)
44+
}
45+
46+
} else if walletSyncState == .syncing {
47+
if syncMode == .esplora {
48+
HStack {
49+
if progress < 1.0 {
50+
Text("\(inspectedScripts)")
51+
.padding(.trailing, -5.0)
52+
.fontWeight(.semibold)
53+
.contentTransition(.numericText())
54+
.transition(.opacity)
55+
56+
Text("/")
57+
.padding(.trailing, -5.0)
58+
.transition(.opacity)
59+
Text("\(totalScripts)")
60+
.contentTransition(.numericText())
61+
.transition(.opacity)
62+
}
63+
Text(
64+
String(
65+
format: "%.0f%%",
66+
progress * 100
67+
)
68+
)
69+
.contentTransition(.numericText())
70+
.transition(.opacity)
71+
}
3272
.fontDesign(.monospaced)
3373
.foregroundStyle(.secondary)
3474
.font(.caption2)
3575
.fontWeight(.thin)
3676
.animation(.easeInOut, value: inspectedScripts)
37-
} else if walletSyncState == .syncing {
38-
HStack {
39-
if progress < 1.0 {
40-
Text("\(inspectedScripts)")
41-
.padding(.trailing, -5.0)
42-
.fontWeight(.semibold)
43-
.contentTransition(.numericText())
44-
.transition(.opacity)
45-
46-
Text("/")
47-
.padding(.trailing, -5.0)
48-
.transition(.opacity)
49-
Text("\(totalScripts)")
50-
.contentTransition(.numericText())
51-
.transition(.opacity)
52-
}
53-
54-
Text(
55-
String(
56-
format: "%.0f%%",
57-
progress * 100
58-
)
59-
)
60-
.contentTransition(.numericText())
61-
.transition(.opacity)
77+
.animation(.easeInOut, value: totalScripts)
78+
.animation(.easeInOut, value: progress)
79+
} else if syncMode == .kyoto {
80+
Text("Conecting")
81+
.font(.caption)
82+
.foregroundStyle(.secondary)
83+
.fontWeight(.regular)
6284
}
63-
.fontDesign(.monospaced)
64-
.foregroundStyle(.secondary)
65-
.font(.caption2)
66-
.fontWeight(.thin)
67-
.animation(.easeInOut, value: inspectedScripts)
68-
.animation(.easeInOut, value: totalScripts)
69-
.animation(.easeInOut, value: progress)
7085
}
7186
}
72-
HStack {
73-
HStack(spacing: 5) {
74-
self.syncImageIndicator()
75-
}
76-
.contentTransition(.symbolEffect(.replace.offUp))
87+
switch syncMode {
88+
case .esplora:
89+
HStack {
90+
HStack(spacing: 5) {
91+
self.syncImageIndicator()
92+
}
93+
.contentTransition(.symbolEffect(.replace.offUp))
7794

95+
}
96+
.foregroundStyle(.secondary)
97+
.font(.caption)
98+
99+
case .kyoto:
100+
EmptyView()
78101
}
79-
.foregroundStyle(.secondary)
80-
.font(.caption)
81102

82103
if walletSyncState == .synced {
83104
Button {

BDKSwiftExampleWallet/View/WalletView.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ struct WalletView: View {
4747
progress: viewModel.progress,
4848
inspectedScripts: viewModel.inspectedScripts,
4949
totalScripts: viewModel.totalScripts,
50-
needsFullScan: viewModel.needsFullScan
50+
needsFullScan: viewModel.needsFullScan,
51+
syncMode: viewModel.syncMode
5152
) {
5253
showAllTransactions = true
5354
}

0 commit comments

Comments
 (0)