Add pull-to-refresh functionality and improve loading states across iOS views
- Added pull-to-refresh to ResidencesListView with force refresh support - Added pull-to-refresh to AllTasksView with rotating refresh button - Added pull-to-refresh to ContractorsListView with force refresh - Added pull-to-refresh to DocumentsTabContent and WarrantiesTabContent - Improved loading state checks to prevent empty list flash during initial load - Added refresh button to AllTasksView toolbar with clockwise rotation animation - Improved UX by disabling refresh button while loading is in progress 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -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<TaskColumnsResponse> {
|
||||
self.tasksResponse = success.data
|
||||
|
||||
Reference in New Issue
Block a user