@@ -9,8 +9,14 @@ struct AnalyticsTimeRangeCard: View {
99 let previousRangeDescription : String
1010 @Binding var selectionType : AnalyticsHubTimeRangeSelection . SelectionType
1111
12+ /// Determines if the time range selection should be shown.
13+ ///
1214 @State private var showTimeRangeSelectionView : Bool = false
1315
16+ /// Determines if the custom range selection should be shown.
17+ ///
18+ @State private var showCustomRangeSelectionView : Bool = false
19+
1420 private let usageTracksEventEmitter : StoreStatsUsageTracksEventEmitter
1521
1622 init ( viewModel: AnalyticsTimeRangeCardViewModel , selectionType: Binding < AnalyticsHubTimeRangeSelection . SelectionType > ) {
@@ -27,10 +33,16 @@ struct AnalyticsTimeRangeCard: View {
2733 SelectionList ( title: Localization . timeRangeSelectionTitle,
2834 items: AnalyticsHubTimeRangeSelection . SelectionType. allCases,
2935 contentKeyPath: \. description,
30- selected: $selectionType ) { selection in
36+ selected: internalSelectionBinding ( ) ) { selection in
3137 usageTracksEventEmitter. interacted ( )
3238 ServiceLocator . analytics. track ( event: . AnalyticsHub. dateRangeOptionSelected ( selection. tracksIdentifier) )
3339 }
40+ . sheet ( isPresented: $showCustomRangeSelectionView) {
41+ RangedDatePicker ( ) { start, end in
42+ showTimeRangeSelectionView = false // Dismiss the initial sheet for a smooth transition
43+ self . selectionType = . custom( start: start, end: end)
44+ }
45+ }
3446 }
3547 }
3648
@@ -80,6 +92,34 @@ struct AnalyticsTimeRangeCard: View {
8092 . padding ( [ . top, . bottom] )
8193 . frame ( maxWidth: . infinity)
8294 }
95+
96+ /// Tracks the range selection internally to determine if the custom range selection should be presented or not.
97+ /// If custom range selection is not needed, the internal selection is forwarded to `selectionType`.
98+ ///
99+ private func internalSelectionBinding( ) -> Binding < AnalyticsHubTimeRangeSelection . SelectionType > {
100+ . init(
101+ get: {
102+ // Temporary
103+ switch selectionType {
104+ // If a `custom` case is set return one with nil values so the Custom row is selected
105+ case . custom:
106+ return . custom( start: nil , end: nil )
107+ default :
108+ return selectionType
109+ }
110+ } ,
111+ set: { newValue in
112+ switch newValue {
113+ // If we get a `custom` case with nil dates it is because we need to present the custom range selection
114+ case . custom( start: nil , end: nil ) :
115+ showCustomRangeSelectionView = true
116+ default :
117+ // Any other selection should be forwarded to our parent binding.
118+ selectionType = newValue
119+ }
120+ }
121+ )
122+ }
83123}
84124
85125// MARK: Constants
0 commit comments