11import SwiftUI
22
3- /// Options for configuring the BlocksWidget
4- struct BlocksWidgetOptions : Codable , Equatable {
5- var height : Bool = true
6- var time : Bool = true
7- var date : Bool = true
8- var transactionCount : Bool = false
9- var size : Bool = false
10- var weight : Bool = false
11- var difficulty : Bool = false
12- var hash : Bool = false
13- var merkleRoot : Bool = false
14- var showSource : Bool = false
15- }
3+ // MARK: - Widget
164
17- /// A widget that displays Bitcoin block information
5+ /// In-app Bitcoin Blocks widget (v61). Renders the wide layout — used inside the home feed
6+ /// and the wide carousel page on the preview screen.
187struct BlocksWidget : View {
19- /// Configuration options for the widget
208 var options : BlocksWidgetOptions = . init( )
21-
22- /// Flag indicating if the widget is in editing mode
239 var isEditing : Bool = false
24-
25- /// Callback to signal when editing should end
2610 var onEditingEnd : ( ( ) -> Void ) ?
2711
28- /// View model for handling block data
2912 @StateObject private var viewModel = BlocksViewModel . shared
3013
31- /// Initialize the widget
3214 init (
3315 options: BlocksWidgetOptions = BlocksWidgetOptions ( ) ,
3416 isEditing: Bool = false ,
@@ -39,96 +21,29 @@ struct BlocksWidget: View {
3921 self . onEditingEnd = onEditingEnd
4022 }
4123
42- /// Mapping of block data keys to display labels
43- private let blocksMapping : [ String : String ] = [
44- " height " : " Block " ,
45- " time " : " Time " ,
46- " date " : " Date " ,
47- " transactionCount " : " Transactions " ,
48- " size " : " Size " ,
49- " weight " : " Weight " ,
50- " difficulty " : " Difficulty " ,
51- " hash " : " Hash " ,
52- " merkleRoot " : " Merkle Root " ,
53- ]
54-
5524 var body : some View {
5625 BaseWidget (
5726 type: . blocks,
5827 isEditing: isEditing,
5928 onEditingEnd: onEditingEnd
6029 ) {
61- VStack ( spacing: 0 ) {
62- if viewModel. isLoading {
63- WidgetContentBuilder . loadingView ( )
64- } else if viewModel. error != nil {
65- WidgetContentBuilder . errorView ( t ( " widgets__blocks__error " ) )
66- } else if let data = viewModel. blockData {
67- VStack ( spacing: 0 ) {
68- // Display block data rows based on options
69- ForEach ( getDisplayableData ( data) , id: \. key) { item in
70- HStack ( spacing: 0 ) {
71- HStack {
72- BodySSBText ( item. label, textColor: . textSecondary)
73- . lineLimit ( 1 )
74- }
75- . frame ( maxWidth: . infinity, alignment: . leading)
76-
77- HStack {
78- BodyMSBText ( item. value)
79- . lineLimit ( 1 )
80- . truncationMode ( . middle)
81- }
82- . frame ( maxWidth: . infinity, alignment: . trailing)
83- }
84- . frame ( minHeight: 28 )
85- }
86-
87- if options. showSource {
88- WidgetContentBuilder . sourceRow ( source: " mempool.space " )
89- }
90- }
91- }
92- }
30+ content
9331 }
94- . onAppear {
32+ . task {
9533 viewModel. startUpdates ( )
9634 }
9735 }
9836
99- /// Get displayable data based on current options
100- private func getDisplayableData ( _ data : BlockData ) -> [ ( key : String , label : String , value : String ) ] {
101- var items : [ ( key : String , label : String , value : String ) ] = [ ]
102-
103- if options . height {
104- items . append ( ( key : " height " , label : blocksMapping [ " height " ] ! , value : data . height ) )
105- }
106- if options. time {
107- items . append ( ( key : " time " , label : blocksMapping [ " time " ] ! , value : data . time ) )
37+ @ ViewBuilder
38+ private var content : some View {
39+ if viewModel . isLoading && viewModel . blockData == nil {
40+ WidgetContentBuilder . loadingView ( )
41+ } else if viewModel . error != nil && viewModel . blockData == nil {
42+ WidgetContentBuilder . errorView ( t ( " widgets__blocks__error " ) )
43+ } else if let data = viewModel . blockData {
44+ BlocksWidgetWideContent ( data : data , options: options )
45+ . frame ( height : BlocksWidgetWideContent . inAppContentHeight )
10846 }
109- if options. date {
110- items. append ( ( key: " date " , label: blocksMapping [ " date " ] !, value: data. date) )
111- }
112- if options. transactionCount {
113- items. append ( ( key: " transactionCount " , label: blocksMapping [ " transactionCount " ] !, value: data. transactionCount) )
114- }
115- if options. size {
116- items. append ( ( key: " size " , label: blocksMapping [ " size " ] !, value: data. size) )
117- }
118- if options. weight {
119- items. append ( ( key: " weight " , label: blocksMapping [ " weight " ] !, value: data. weight) )
120- }
121- if options. difficulty {
122- items. append ( ( key: " difficulty " , label: blocksMapping [ " difficulty " ] !, value: data. difficulty) )
123- }
124- if options. hash {
125- items. append ( ( key: " hash " , label: blocksMapping [ " hash " ] !, value: data. hash) )
126- }
127- if options. merkleRoot {
128- items. append ( ( key: " merkleRoot " , label: blocksMapping [ " merkleRoot " ] !, value: data. merkleRoot) )
129- }
130-
131- return items
13247 }
13348}
13449
0 commit comments