11import WidgetKit
22import KeychainAccess
33
4- /// Type that represents the Widget information
4+ /// Type that represents the all the possible Widget states.
55///
6- struct StoreInfoEntry : TimelineEntry {
7- /// Date to request new info
8- ///
9- var date : Date
6+ enum StoreInfoEntry : TimelineEntry {
7+ // Represents a not logged-in state
8+ case notConnected
9+
10+ // Represents a fetching error state
11+ case error
12+
13+ // Represents a fetched data state
14+ case data( StoreInfoData )
1015
16+ // Current date, needed by the `TimelineEntry` protocol.
17+ var date : Date { Date ( ) }
18+ }
19+
20+ /// Type that represents the the widget state data.
21+ ///
22+ struct StoreInfoData {
1123 /// Eg: Today, Weekly, Monthly, Yearly
1224 ///
1325 var range : String
@@ -45,13 +57,12 @@ final class StoreInfoProvider: TimelineProvider {
4557 ///
4658 func placeholder( in context: Context ) -> StoreInfoEntry {
4759 let dependencies = Self . fetchDependencies ( )
48- return StoreInfoEntry ( date: Date ( ) ,
49- range: " Today " ,
50- name: dependencies? . storeName ?? Localization . myShop,
51- revenue: " $132.234 " ,
52- visitors: " 67 " ,
53- orders: " 23 " ,
54- conversion: " 34% " )
60+ return StoreInfoEntry . data ( . init( range: Localization . today,
61+ name: dependencies? . storeName ?? Localization . myShop,
62+ revenue: " $132.234 " ,
63+ visitors: " 67 " ,
64+ orders: " 23 " ,
65+ conversion: " 34% " ) )
5566 }
5667
5768 /// Quick Snapshot. Required when previewing the widget.
@@ -65,7 +76,7 @@ final class StoreInfoProvider: TimelineProvider {
6576 ///
6677 func getTimeline( in context: Context , completion: @escaping ( Timeline < StoreInfoEntry > ) -> Void ) {
6778 guard let dependencies = Self . fetchDependencies ( ) else {
68- return // TODO: Dispatch non auth error entry
79+ return completion ( Timeline < StoreInfoEntry > ( entries : [ StoreInfoEntry . notConnected ] , policy : . never ) )
6980 }
7081
7182 let strongService = StoreInfoDataService ( authToken: dependencies. authToken)
@@ -75,13 +86,12 @@ final class StoreInfoProvider: TimelineProvider {
7586 let todayStats = try await strongService. fetchTodayStats ( for: dependencies. storeID)
7687
7788 // TODO: Use proper store formatting.
78- let entry = StoreInfoEntry ( date: Date ( ) ,
79- range: Localization . today,
80- name: dependencies. storeName,
81- revenue: " $ \( todayStats. revenue) " ,
82- visitors: " \( todayStats. totalVisitors) " ,
83- orders: " \( todayStats. totalOrders) " ,
84- conversion: " \( todayStats. conversion) % " )
89+ let entry = StoreInfoEntry . data ( . init( range: Localization . today,
90+ name: dependencies. storeName,
91+ revenue: " $ \( todayStats. revenue) " ,
92+ visitors: " \( todayStats. totalVisitors) " ,
93+ orders: " \( todayStats. totalOrders) " ,
94+ conversion: " \( todayStats. conversion) % " ) )
8595
8696 let reloadDate = Date ( timeIntervalSinceNow: 30 * 60 ) // Ask for a 15 minutes reload.
8797 let timeline = Timeline < StoreInfoEntry > ( entries: [ entry] , policy: . after( reloadDate) )
0 commit comments