@@ -11,7 +11,6 @@ struct ParksMapScreen: View {
1111 @EnvironmentObject private var parksManager : ParksManager
1212 @StateObject private var viewModel = ViewModel ( )
1313 @State private var presentation = Presentation . map
14- @State private var isLoading = false
1514 @State private var sheetItem : SheetItem ?
1615
1716 /// Отфильтрованные по выбранному городу и активным фильтрам площадки
@@ -35,37 +34,39 @@ struct ParksMapScreen: View {
3534 parksContent
3635 . overlay { noParksFoundView }
3736 }
38- . loadingOverlay ( if: isLoading || viewModel . newParkState . isProcessingNewPark )
37+ . loadingOverlay ( if: parksManager . isLoading )
3938 . background ( Color . swBackground)
4039 . onFirstAppear {
4140 viewModel. userCityDidChange ( defaults. mainUserInfo)
4241 }
43- . onChange ( of: sheetItem) { [ oldItem = sheetItem] newValue in
44- if case . createNewPark = oldItem, newValue == nil {
45- viewModel. finishCreatingNewPark ( )
46- }
47- }
4842 . onChange ( of: defaults. mainUserCityId) { _ in
4943 viewModel. userCityDidChange ( defaults. mainUserInfo)
5044 }
51- . onChange ( of: viewModel. newParkState) { newState in
52- if case let . ready( model) = newState {
53- sheetItem = . createNewPark( model)
45+ . task {
46+ do {
47+ try await parksManager. loadParksIfNeeded ( )
48+ } catch {
49+ SWAlert . shared. presentDefaultUIKit ( error)
5450 }
5551 }
56- . task { await askForParks ( ) }
52+ . onAppear {
53+ viewModel. setLocationTracking ( true )
54+ }
55+ . onDisappear {
56+ viewModel. setLocationTracking ( false )
57+ }
5758 . sheet ( item: $sheetItem) { makeContentView ( for: $0) }
5859 . toolbar {
5960 ToolbarItemGroup ( placement: . topBarLeading) {
6061 Group {
6162 filterButton
6263 Button {
63- Task { await askForParks ( refresh : true ) }
64+ onRefresh ( )
6465 } label: {
6566 Icons . Regular. refresh. view
6667 }
6768 }
68- . disabled ( isLoading)
69+ . disabled ( parksManager . isLoading)
6970 }
7071 ToolbarItem ( placement: . topBarTrailing) {
7172 rightBarButton
@@ -76,10 +77,28 @@ struct ParksMapScreen: View {
7677 }
7778 . navigationViewStyle ( . stack)
7879 }
80+
81+ private func onRefresh( ) {
82+ Task {
83+ do {
84+ try await parksManager. loadParksIfNeeded ( refresh: true )
85+ } catch {
86+ SWAlert . shared. presentDefaultUIKit ( error)
87+ }
88+ }
89+ }
90+
91+ private func onCheckForRecentUpdates( ) async {
92+ do {
93+ try await parksManager. checkForRecentUpdates ( )
94+ } catch {
95+ SWAlert . shared. presentDefaultUIKit ( error)
96+ }
97+ }
7998}
8099
81100private extension ParksMapScreen {
82- enum SheetItem : Identifiable , Equatable {
101+ enum SheetItem : Identifiable {
83102 var id : String {
84103 switch self {
85104 case . filters: " filters "
@@ -196,101 +215,22 @@ private extension ParksMapScreen {
196215 isFilterEdited: defaults. parksFilter. isEdited,
197216 isFilteredParksEmpty: filteredParks. isEmpty,
198217 didParksManagerLoad: parksManager. didLoad,
199- isLoading: isLoading
218+ isLoading: parksManager . isLoading
200219 )
201220 )
202221 }
203222 }
204223
205- /// Заполняем/обновляем дефолтный список площадок
206- func askForParks( refresh: Bool = false ) async {
207- if !filteredParks. isEmpty, !refresh { return }
208-
209- guard !parksManager. fullList. isEmpty else {
210- // Загружаем полный список площадок с нуля
211- do {
212- try await loadInitialParks ( )
213- } catch {
214- SWAlert . shared. presentDefaultUIKit ( error)
215- }
216- return
217- }
218-
219- // Если прошло больше одного дня с момента предыдущего обновления, делаем обновление
220- if parksManager. needUpdateDefaultList {
221- await getUpdatedParks ( )
222- }
223- }
224-
225- private func loadInitialParks( ) async throws {
226- isLoading = true
227- defer { isLoading = false }
228- let client = SWClient ( with: defaults)
229- var page = 1
230- let pageSize = 1000
231- var allParks : [ Park ] = [ ]
232-
233- while true {
234- let parksPage = try await client. getParksPageByPage ( page: page, pageSize: pageSize)
235- if parksPage. isEmpty {
236- break
237- }
238- allParks. append ( contentsOf: parksPage)
239- page += 1
240- }
241-
242- do {
243- try parksManager. setFullList ( allParks)
244- } catch {
245- SWAlert . shared. presentDefaultUIKit ( error)
246- }
247- }
248-
249- func deletePark( id: Int ) {
250- sheetItem = nil
251- do {
252- try parksManager. deletePark ( with: id)
253- } catch {
254- SWAlert . shared. presentDefaultUIKit ( error)
255- }
256- }
257-
258- func updatePark( _ park: Park ) {
259- do {
260- try parksManager. manuallyUpdatePark ( park)
261- } catch {
262- SWAlert . shared. presentDefaultUIKit ( error)
263- }
264- }
265-
266- /// Проверяем недавние обновления списка площадок
267- ///
268- /// Запрашиваем обновление за прошедшие 5 минут
269- func checkForRecentUpdates( ) async {
270- defaults. setUserNeedUpdate ( true )
271- await getUpdatedParks ( from: DateFormatterService . fiveMinutesAgoDateString)
272- }
273-
274- func getUpdatedParks( from dateString: String ? = nil ) async {
275- isLoading = true
276- do {
277- try await parksManager. getUpdatedParks ( with: defaults, from: dateString)
278- } catch ClientError . noConnection {
279- SWAlert . shared. presentNoConnection ( false )
280- } catch {
281- SWAlert . shared. presentDefaultUIKit ( error)
282- }
283- isLoading = false
284- }
285-
286224 @ViewBuilder
287225 var rightBarButton : some View {
288226 if defaults. isAuthorized {
289- Button ( action: viewModel. requestLocationForNewPark) {
227+ Button {
228+ sheetItem = . createNewPark( viewModel. newParkMapModel)
229+ } label: {
290230 Icons . Regular. plus. view
291231 . symbolVariant ( . circle)
292232 }
293- . disabled ( !viewModel. canCreateNewPark || isLoading)
233+ . disabled ( !viewModel. canCreateNewPark || parksManager . isLoading)
294234 }
295235 }
296236
@@ -305,12 +245,11 @@ private extension ParksMapScreen {
305245 . createNew( model) ,
306246 refreshClbk: {
307247 Task {
308- await checkForRecentUpdates ( )
248+ await onCheckForRecentUpdates ( )
309249 }
310250 }
311251 )
312252 }
313- . environment ( \. updateGeocodingCache, viewModel. updateGeocodingCache)
314253 case let . searchCity( storedCities) :
315254 NavigationView {
316255 ItemListScreen (
@@ -334,8 +273,25 @@ private extension ParksMapScreen {
334273 NavigationView {
335274 ParkDetailScreen (
336275 park: park,
337- onEdit: updatePark,
338- onDelete: deletePark
276+ onEdit: { park in
277+ Task {
278+ do {
279+ try await parksManager. updateParkAsync ( park)
280+ } catch {
281+ SWAlert . shared. presentDefaultUIKit ( error)
282+ }
283+ }
284+ } ,
285+ onDelete: { id in
286+ sheetItem = nil
287+ Task {
288+ do {
289+ try await parksManager. deleteParkAsync ( id: id)
290+ } catch {
291+ SWAlert . shared. presentDefaultUIKit ( error)
292+ }
293+ }
294+ }
339295 )
340296 }
341297 . navigationViewStyle ( . stack)
0 commit comments