diff --git a/iosApp/iosApp/Contractor/ContractorsListView.swift b/iosApp/iosApp/Contractor/ContractorsListView.swift index 19df4d6..438f8af 100644 --- a/iosApp/iosApp/Contractor/ContractorsListView.swift +++ b/iosApp/iosApp/Contractor/ContractorsListView.swift @@ -59,7 +59,7 @@ struct ContractorsListView: View { } // Content - if viewModel.isLoading { + if contractors.isEmpty && viewModel.isLoading { Spacer() ProgressView() .scaleEffect(1.2) @@ -95,6 +95,9 @@ struct ContractorsListView: View { .padding(AppSpacing.md) .padding(.bottom, AppSpacing.xxxl) } + .refreshable { + loadContractors(forceRefresh: true) + } .safeAreaInset(edge: .bottom) { Color.clear.frame(height: 0) } @@ -102,7 +105,7 @@ struct ContractorsListView: View { } } .navigationTitle("Contractors") - .navigationBarTitleDisplayMode(.large) + .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { HStack(spacing: AppSpacing.sm) { @@ -165,7 +168,7 @@ struct ContractorsListView: View { } } - private func loadContractors() { + private func loadContractors(forceRefresh: Bool = false) { viewModel.loadContractors( specialty: selectedSpecialty, isFavorite: showFavoritesOnly ? true : nil, diff --git a/iosApp/iosApp/Documents/Components/DocumentsTabContent.swift b/iosApp/iosApp/Documents/Components/DocumentsTabContent.swift index cd2fb5a..8563814 100644 --- a/iosApp/iosApp/Documents/Components/DocumentsTabContent.swift +++ b/iosApp/iosApp/Documents/Components/DocumentsTabContent.swift @@ -16,7 +16,7 @@ struct DocumentsTabContent: View { } var body: some View { - if viewModel.isLoading { + if filteredDocuments.isEmpty && viewModel.isLoading { Spacer() ProgressView() .scaleEffect(1.2) @@ -46,6 +46,9 @@ struct DocumentsTabContent: View { .padding(AppSpacing.md) .padding(.bottom, AppSpacing.xxxl) } + .refreshable { + viewModel.loadDocuments(forceRefresh: true) + } .safeAreaInset(edge: .bottom) { Color.clear.frame(height: 0) } diff --git a/iosApp/iosApp/Documents/Components/WarrantiesTabContent.swift b/iosApp/iosApp/Documents/Components/WarrantiesTabContent.swift index e010a13..b92f23e 100644 --- a/iosApp/iosApp/Documents/Components/WarrantiesTabContent.swift +++ b/iosApp/iosApp/Documents/Components/WarrantiesTabContent.swift @@ -18,7 +18,7 @@ struct WarrantiesTabContent: View { } var body: some View { - if viewModel.isLoading { + if filteredWarranties.isEmpty && viewModel.isLoading { Spacer() ProgressView() .scaleEffect(1.2) @@ -48,6 +48,9 @@ struct WarrantiesTabContent: View { .padding(AppSpacing.md) .padding(.bottom, AppSpacing.xxxl) } + .refreshable { + viewModel.loadDocuments(forceRefresh: true) + } .safeAreaInset(edge: .bottom) { Color.clear.frame(height: 0) } diff --git a/iosApp/iosApp/Documents/DocumentsWarrantiesView.swift b/iosApp/iosApp/Documents/DocumentsWarrantiesView.swift index c4fdaae..b72b8c7 100644 --- a/iosApp/iosApp/Documents/DocumentsWarrantiesView.swift +++ b/iosApp/iosApp/Documents/DocumentsWarrantiesView.swift @@ -93,7 +93,7 @@ struct DocumentsWarrantiesView: View { } } .navigationTitle("Documents & Warranties") - .navigationBarTitleDisplayMode(.large) + .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { HStack(spacing: AppSpacing.sm) { diff --git a/iosApp/iosApp/HomeScreenView.swift b/iosApp/iosApp/HomeScreenView.swift index f2a4189..87ed05c 100644 --- a/iosApp/iosApp/HomeScreenView.swift +++ b/iosApp/iosApp/HomeScreenView.swift @@ -70,7 +70,7 @@ struct HomeScreenView: View { } } .navigationTitle("MyCrib") - .navigationBarTitleDisplayMode(.large) + .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button(action: { diff --git a/iosApp/iosApp/Profile/ProfileView.swift b/iosApp/iosApp/Profile/ProfileView.swift index a843137..949f200 100644 --- a/iosApp/iosApp/Profile/ProfileView.swift +++ b/iosApp/iosApp/Profile/ProfileView.swift @@ -115,7 +115,7 @@ struct ProfileView: View { } } .navigationTitle("Profile") - .navigationBarTitleDisplayMode(.large) + .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("Cancel") { diff --git a/iosApp/iosApp/Register/RegisterView.swift b/iosApp/iosApp/Register/RegisterView.swift index b940e98..2d4d768 100644 --- a/iosApp/iosApp/Register/RegisterView.swift +++ b/iosApp/iosApp/Register/RegisterView.swift @@ -105,7 +105,7 @@ struct RegisterView: View { } } .navigationTitle("Create Account") - .navigationBarTitleDisplayMode(.large) + .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarLeading) { Button("Cancel") { diff --git a/iosApp/iosApp/Residence/ResidencesListView.swift b/iosApp/iosApp/Residence/ResidencesListView.swift index d41f036..fb4aa5c 100644 --- a/iosApp/iosApp/Residence/ResidencesListView.swift +++ b/iosApp/iosApp/Residence/ResidencesListView.swift @@ -11,7 +11,7 @@ struct ResidencesListView: View { AppColors.background .ignoresSafeArea() - if viewModel.isLoading { + if viewModel.myResidences == nil && viewModel.isLoading { VStack(spacing: AppSpacing.lg) { ProgressView() .scaleEffect(1.2) @@ -59,6 +59,9 @@ struct ResidencesListView: View { } .padding(.bottom, AppSpacing.xxxl) } + .refreshable { + viewModel.loadMyResidences(forceRefresh: true) + } .safeAreaInset(edge: .bottom) { Color.clear.frame(height: 0) } @@ -66,7 +69,7 @@ struct ResidencesListView: View { } } .navigationTitle("My Properties") - .navigationBarTitleDisplayMode(.large) + .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItemGroup(placement: .navigationBarTrailing) { Button(action: { diff --git a/iosApp/iosApp/Task/AllTasksView.swift b/iosApp/iosApp/Task/AllTasksView.swift index fb4c525..e0cc40f 100644 --- a/iosApp/iosApp/Task/AllTasksView.swift +++ b/iosApp/iosApp/Task/AllTasksView.swift @@ -26,7 +26,7 @@ struct AllTasksView: View { Color(.systemGroupedBackground) .ignoresSafeArea() - if isLoadingTasks { + if hasNoTasks && isLoadingTasks { ProgressView() } else if let error = tasksError { ErrorView(message: error) { @@ -126,6 +126,9 @@ struct AllTasksView: View { .padding(.horizontal, 16) } .scrollTargetBehavior(.viewAligned) + .refreshable { + loadAllTasks(forceRefresh: true) + } .safeAreaInset(edge: .bottom) { Color.clear.frame(height: 0) } @@ -144,6 +147,17 @@ struct AllTasksView: View { } .disabled(residenceViewModel.myResidences?.residences.isEmpty ?? true) } + + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: { + loadAllTasks(forceRefresh: true) + }) { + Image(systemName: "arrow.clockwise") + .rotationEffect(.degrees(isLoadingTasks ? 360 : 0)) + .animation(isLoadingTasks ? .linear(duration: 1).repeatForever(autoreverses: false) : .default, value: isLoadingTasks) + } + .disabled(residenceViewModel.myResidences?.residences.isEmpty ?? true || isLoadingTasks) + } } .sheet(isPresented: $showAddTask) { AddTaskWithResidenceView( @@ -172,13 +186,18 @@ struct AllTasksView: View { loadAllTasks() } } + .onChange(of: taskViewModel.isLoading) { isLoading in + if !isLoading { + loadAllTasks() + } + } .onAppear { loadAllTasks() residenceViewModel.loadMyResidences() } } - private func loadAllTasks() { + private func loadAllTasks(forceRefresh: Bool = false) { guard TokenStorage.shared.getToken() != nil else { return } isLoadingTasks = true @@ -186,7 +205,7 @@ struct AllTasksView: View { Task { do { - let result = try await APILayer.shared.getTasks(forceRefresh: false) + let result = try await APILayer.shared.getTasks(forceRefresh: forceRefresh) await MainActor.run { if let success = result as? ApiResultSuccess { self.tasksResponse = success.data