@@ -11,7 +11,6 @@ import MapFeature
1111import MapKit
1212import MastodonFeedFeature
1313import NextRideFeature
14- import PathMonitorClient
1514import SettingsFeature
1615import SharedDependencies
1716import SharedModels
@@ -33,7 +32,6 @@ public struct AppFeature: ReducerProtocol {
3332 @Dependency ( \. locationManager) public var locationManager
3433 @Dependency ( \. uiApplicationClient) public var uiApplicationClient
3534 @Dependency ( \. setUserInterfaceStyle) public var setUserInterfaceStyle
36- @Dependency ( \. pathMonitorClient) public var pathMonitorClient
3735 @Dependency ( \. isNetworkAvailable) public var isNetworkAvailable
3836
3937 // MARK: State
@@ -66,17 +64,34 @@ public struct AppFeature: ReducerProtocol {
6664
6765 public var riderLocations : TaskResult < [ Rider ] > ?
6866 public var didResolveInitialLocation = false
67+ public var isRequestingRiderLocations = false
6968
7069 // Children states
7170 public var mapFeatureState = MapFeature . State (
7271 riders: [ ] ,
7372 userTrackingMode: UserTrackingFeature . State ( userTrackingMode: . follow)
7473 )
74+
75+ public var timerProgress : Double {
76+ let progress = Double ( requestTimer. secondsElapsed) / 60
77+ return progress
78+ }
79+ public var sendLocation : Bool {
80+ requestTimer. secondsElapsed == 30
81+ }
82+ public var timerValue : String {
83+ let progress = 60 - requestTimer. secondsElapsed
84+ return String ( progress)
85+ }
86+ public var ridersCount : String {
87+ let count = mapFeatureState. visibleRidersCount ?? 0
88+ return NumberFormatter . riderCountFormatter. string ( from: . init( value: count) ) ?? " "
89+ }
90+
7591 public var socialState = SocialFeature . State ( )
7692 public var settingsState = SettingsFeature . State ( userSettings: . init( ) )
7793 public var nextRideState = NextRideFeature . State ( )
7894 public var requestTimer = RequestTimer . State ( )
79- public var connectionObserverState = NetworkConnectionObserver . State ( )
8095
8196 // Navigation
8297 public var route : AppRoute ?
@@ -129,20 +144,12 @@ public struct AppFeature: ReducerProtocol {
129144 case requestTimer( RequestTimer . Action )
130145 case settings( SettingsFeature . Action )
131146 case social( SocialFeature . Action )
132- case connectionObserver( NetworkConnectionObserver . Action )
133147 }
134148
135149 // MARK: Reducer
136-
137- struct ObserveConnectionIdentifier : Hashable { }
138-
139150 public var body : some ReducerProtocol < State , Action > {
140151 BindingReducer ( )
141152
142- Scope ( state: \. connectionObserverState, action: / AppFeature. Action. connectionObserver) {
143- NetworkConnectionObserver ( )
144- }
145-
146153 Scope ( state: \. requestTimer, action: / AppFeature. Action. requestTimer) {
147154 RequestTimer ( )
148155 }
@@ -190,6 +197,15 @@ public struct AppFeature: ReducerProtocol {
190197
191198 case . onAppear:
192199 var effects : [ EffectTask < Action > ] = [
200+ EffectTask ( value: . map( . onAppear) ) ,
201+ EffectTask ( value: . requestTimer( . startTimer) ) ,
202+ . task {
203+ await . userSettingsLoaded(
204+ TaskResult {
205+ try await fileClient. loadUserSettings ( )
206+ }
207+ )
208+ } ,
193209 . run { send in
194210 await withThrowingTaskGroup ( of: Void . self) { group in
195211 group. addTask {
@@ -199,16 +215,7 @@ public struct AppFeature: ReducerProtocol {
199215 await send ( . fetchLocations)
200216 }
201217 }
202- } ,
203- . task {
204- await . userSettingsLoaded(
205- TaskResult {
206- try await fileClient. loadUserSettings ( )
207- }
208- )
209- } ,
210- EffectTask ( value: . map( . onAppear) ) ,
211- EffectTask ( value: . requestTimer( . startTimer) )
218+ }
212219 ]
213220 if !userDefaultsClient. didShowObservationModePrompt {
214221 effects. append (
@@ -222,9 +229,10 @@ public struct AppFeature: ReducerProtocol {
222229 return . merge( effects)
223230
224231 case . onDisappear:
225- return EffectTask . cancel ( id : ObserveConnectionIdentifier ( ) )
232+ return . none
226233
227234 case . fetchLocations:
235+ state. isRequestingRiderLocations = true
228236 return . task {
229237 await . fetchLocationsResponse(
230238 TaskResult {
@@ -268,11 +276,13 @@ public struct AppFeature: ReducerProtocol {
268276 return . none
269277
270278 case let . fetchLocationsResponse( . success( response) ) :
279+ state. isRequestingRiderLocations = false
271280 state. riderLocations = . success( response)
272281 state. mapFeatureState. riderLocations = response
273282 return . none
274283
275284 case let . fetchLocationsResponse( . failure( error) ) :
285+ state. isRequestingRiderLocations = false
276286 logger. info ( " FetchLocation failed: \( error) " )
277287 state. riderLocations = . failure( error)
278288 return . none
@@ -311,29 +321,8 @@ public struct AppFeature: ReducerProtocol {
311321 }
312322
313323 case . locationManager( . didUpdateLocations) :
314- let isInitialLocation = state. nextRideState. userLocation == nil
315-
316- // sync with nextRideState
317324 state. nextRideState. userLocation = state. mapFeatureState. location? . coordinate
318-
319- if
320- let coordinate = state. mapFeatureState. location? . coordinate,
321- state. settingsState. rideEventSettings. isEnabled,
322- isInitialLocation
323- {
324- return . run { send in
325- await withThrowingTaskGroup ( of: Void . self) { group in
326- group. addTask {
327- await send ( . postLocation)
328- }
329- group. addTask {
330- await send ( . nextRide( . getNextRide( coordinate) ) )
331- }
332- }
333- }
334- } else {
335- return EffectTask ( value: . postLocation)
336- }
325+ return . none
337326
338327 default :
339328 return . none
@@ -359,8 +348,17 @@ public struct AppFeature: ReducerProtocol {
359348 let userSettings = ( try ? result. value) ?? UserSettings ( )
360349 state. settingsState = . init( userSettings: userSettings)
361350 state. nextRideState. rideEventSettings = userSettings. rideEventSettings
351+
362352 let style = state. settingsState. appearanceSettings. colorScheme. userInterfaceStyle
353+ let coordinate = state. mapFeatureState. location? . coordinate
354+ let isRideEventsEnabled = state. settingsState. rideEventSettings. isEnabled
355+
363356 return . merge(
357+ . run { send in
358+ if isRideEventsEnabled, let coordinate {
359+ await send ( . nextRide( . getNextRide( coordinate) ) )
360+ }
361+ } ,
364362 . fireAndForget {
365363 await setUserInterfaceStyle ( style)
366364 }
@@ -386,19 +384,27 @@ public struct AppFeature: ReducerProtocol {
386384 case let . requestTimer( timerAction) :
387385 switch timerAction {
388386 case . timerTicked:
389- return . run { [ isChatPresented = state. isChatViewPresented, isPrentingSubView = state. route != nil ] send in
390- await withThrowingTaskGroup ( of: Void . self) { group in
391- if !isPrentingSubView {
392- group. addTask {
393- await send ( . fetchLocations)
387+ if state. requestTimer. secondsElapsed == 60 {
388+ state. requestTimer. secondsElapsed = 0
389+
390+ return . run { [ isChatPresented = state. isChatViewPresented, isPrentingSubView = state. route != nil ] send in
391+ await withThrowingTaskGroup ( of: Void . self) { group in
392+ if !isPrentingSubView {
393+ group. addTask {
394+ await send ( . fetchLocations)
395+ }
394396 }
395- }
396- if isChatPresented {
397- group . addTask {
398- await send ( . fetchChatMessages )
397+ if isChatPresented {
398+ group . addTask {
399+ await send ( . fetchChatMessages )
400+ }
399401 }
400402 }
401403 }
404+ } else if state. sendLocation {
405+ return EffectTask ( value: . postLocation)
406+ } else {
407+ return . none
402408 }
403409
404410 default :
@@ -447,10 +453,7 @@ public struct AppFeature: ReducerProtocol {
447453 default :
448454 return . none
449455 }
450-
451- case . connectionObserver:
452- return . none
453-
456+
454457 case . binding:
455458 return . none
456459 }
@@ -501,3 +504,12 @@ public extension AlertState where Action == AppFeature.Action {
501504}
502505
503506public typealias ReducerBuilderOf < R: ReducerProtocol > = ReducerBuilder < R . State , R . Action >
507+
508+ extension NumberFormatter {
509+ static let riderCountFormatter : NumberFormatter = {
510+ let formatter = NumberFormatter ( )
511+ formatter. numberStyle = . decimal
512+ formatter. groupingSeparator = " . "
513+ return formatter
514+ } ( )
515+ }
0 commit comments