@@ -24,62 +24,44 @@ struct FeeView: View {
2424
2525 Spacer ( )
2626
27- HStack {
28- Spacer ( )
29-
30- Picker ( " Select Fee " , selection: $viewModel. selectedFeeIndex) {
31- HStack {
32- Image (
33- systemName: " bitcoinsign.gauge.chart.leftthird.topthird.rightthird " ,
34- variableValue: 0.0
35- )
36- Text (
37- " None • \( viewModel. recommendedFees? . minimumFee ?? 1 ) "
38- )
39- }
40- . tag ( 0 )
41- HStack {
42- Image (
43- systemName: " bitcoinsign.gauge.chart.leftthird.topthird.rightthird " ,
44- variableValue: 0.33
45- )
46- Text (
47- " Low • \( viewModel. recommendedFees? . hourFee ?? 1 ) "
48- )
49- }
50- . tag ( 1 )
51- HStack {
52- Image (
53- systemName: " bitcoinsign.gauge.chart.leftthird.topthird.rightthird " ,
54- variableValue: 0.66
55- )
56- Text (
57- " Medium • \( viewModel. recommendedFees? . halfHourFee ?? 1 ) "
58- )
59- }
60- . tag ( 2 )
61- HStack {
62- Image (
63- systemName: " bitcoinsign.gauge.chart.leftthird.topthird.rightthird " ,
64- variableValue: 1.0
65- )
66- Text (
67- " High • \( viewModel. recommendedFees? . fastestFee ?? 1 ) "
68- )
69- }
70- . tag ( 3 )
27+ VStack ( spacing: 12 ) {
28+ Slider (
29+ value: feeSliderBinding,
30+ in: 0 ... 3 ,
31+ step: 1
32+ ) {
33+ Text ( " Fee Priority " )
34+ } minimumValueLabel: {
35+ Text ( feeTitle ( for: 0 ) )
36+ } maximumValueLabel: {
37+ Text ( feeTitle ( for: 3 ) )
7138 }
72- . pickerStyle ( . automatic)
7339 . tint ( . primary)
7440 . accessibilityLabel ( " Select Transaction Fee " )
7541 . accessibilityValue ( " \( viewModel. selectedFee ?? 1 ) satoshis per vbyte " )
7642
77- Text ( " sat/vb " )
78- . foregroundStyle ( . secondary)
79- . fontWeight ( . thin)
43+ HStack ( spacing: 8 ) {
44+ ForEach ( 0 ..< 4 , id: \. self) { index in
45+ VStack ( spacing: 4 ) {
46+ feeIcon ( for: index)
47+ . font ( . headline)
48+ Text ( " \( feeTitle ( for: index) ) • \( feeValue ( for: index) ) " )
49+ . font ( . caption2)
50+ . multilineTextAlignment ( . center)
51+ . foregroundStyle (
52+ index == viewModel. selectedFeeIndex
53+ ? . primary : . secondary
54+ )
55+ }
56+ . frame ( maxWidth: . infinity)
57+ }
58+ }
8059
81- Spacer ( )
60+ Text ( " Selected: \( viewModel. selectedFee ?? 1 ) sat/vb fee " )
61+ . font ( . footnote)
62+ . foregroundStyle ( . secondary)
8263 }
64+ . padding ( . horizontal)
8365
8466 Spacer ( )
8567
@@ -128,6 +110,42 @@ struct FeeView: View {
128110
129111}
130112
113+ extension FeeView {
114+ fileprivate var feeSliderBinding : Binding < Double > {
115+ Binding (
116+ get: { Double ( viewModel. selectedFeeIndex) } ,
117+ set: { viewModel. selectedFeeIndex = Int ( $0. rounded ( ) ) }
118+ )
119+ }
120+
121+ fileprivate func feeValue( for index: Int ) -> Int {
122+ guard let fees = viewModel. recommendedFees else { return 1 }
123+ switch index {
124+ case 0 : return fees. minimumFee
125+ case 1 : return fees. hourFee
126+ case 2 : return fees. halfHourFee
127+ default : return fees. fastestFee
128+ }
129+ }
130+
131+ fileprivate func feeTitle( for index: Int ) -> String {
132+ switch index {
133+ case 0 : return " None "
134+ case 1 : return " Low "
135+ case 2 : return " Medium "
136+ default : return " High "
137+ }
138+ }
139+
140+ @ViewBuilder
141+ fileprivate func feeIcon( for index: Int ) -> some View {
142+ Image (
143+ systemName: " bitcoinsign.gauge.chart.leftthird.topthird.rightthird " ,
144+ variableValue: Double ( index) / 3.0
145+ )
146+ }
147+ }
148+
131149#if DEBUG
132150 #Preview {
133151 FeeView (
0 commit comments