|
|
@@ -8,16 +8,21 @@ import SwiftData
|
|
|
struct SessionListView: View {
|
|
|
@Environment(\.modelContext) private var modelContext
|
|
|
@Query(sort: \CelestiaSession.startTime, order: .reverse) private var sessions: [CelestiaSession]
|
|
|
+ @ObservedObject private var authManager = AuthManager.shared
|
|
|
|
|
|
+ @Binding var selectedSession: CelestiaSession?
|
|
|
var onStartRecording: () -> Void = {}
|
|
|
|
|
|
@State private var searchText = ""
|
|
|
@State private var deletionError: String?
|
|
|
@State private var sessionPendingDeletion: CelestiaSession?
|
|
|
- @State private var selectedSession: CelestiaSession?
|
|
|
- @State private var showSessionDetail = false
|
|
|
@State private var deletingSessionID: UUID?
|
|
|
|
|
|
+ init(selectedSession: Binding<CelestiaSession?> = .constant(nil), onStartRecording: @escaping () -> Void = {}) {
|
|
|
+ self._selectedSession = selectedSession
|
|
|
+ self.onStartRecording = onStartRecording
|
|
|
+ }
|
|
|
+
|
|
|
var body: some View {
|
|
|
NavigationStack {
|
|
|
ZStack {
|
|
|
@@ -29,13 +34,11 @@ struct SessionListView: View {
|
|
|
sessionList
|
|
|
}
|
|
|
}
|
|
|
- .navigationTitle("历史记录")
|
|
|
+ .navigationTitle("现场记录")
|
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
|
.modifier(SessionSearchModifier(isEnabled: !sessions.isEmpty, searchText: $searchText))
|
|
|
- .navigationDestination(isPresented: $showSessionDetail) {
|
|
|
- if let selectedSession {
|
|
|
- SessionDetailView(session: selectedSession)
|
|
|
- }
|
|
|
+ .navigationDestination(item: $selectedSession) { session in
|
|
|
+ SessionDetailView(session: session)
|
|
|
}
|
|
|
.alert("删除失败", isPresented: Binding(
|
|
|
get: { deletionError != nil },
|
|
|
@@ -91,7 +94,6 @@ struct SessionListView: View {
|
|
|
ForEach(filteredSessions) { session in
|
|
|
Button {
|
|
|
selectedSession = session
|
|
|
- showSessionDetail = true
|
|
|
} label: {
|
|
|
SessionRowCard(session: session)
|
|
|
.contentShape(Rectangle())
|
|
|
@@ -113,6 +115,9 @@ struct SessionListView: View {
|
|
|
.listStyle(.plain)
|
|
|
.scrollContentBackground(.hidden)
|
|
|
.contentMargins(.bottom, 18, for: .scrollContent)
|
|
|
+ .refreshable {
|
|
|
+ await synchronizeFieldRecords()
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@MainActor
|
|
|
@@ -155,14 +160,24 @@ struct SessionListView: View {
|
|
|
|
|
|
@ViewBuilder
|
|
|
private var emptyState: some View {
|
|
|
- if sessions.isEmpty {
|
|
|
- Button(action: onStartRecording) {
|
|
|
- emptyStateContent
|
|
|
- .contentShape(Rectangle())
|
|
|
+ GeometryReader { proxy in
|
|
|
+ ScrollView {
|
|
|
+ Group {
|
|
|
+ if sessions.isEmpty {
|
|
|
+ Button(action: onStartRecording) {
|
|
|
+ emptyStateContent
|
|
|
+ .contentShape(Rectangle())
|
|
|
+ }
|
|
|
+ .buttonStyle(.plain)
|
|
|
+ } else {
|
|
|
+ emptyStateContent
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .frame(minHeight: proxy.size.height)
|
|
|
+ }
|
|
|
+ .refreshable {
|
|
|
+ await synchronizeFieldRecords()
|
|
|
}
|
|
|
- .buttonStyle(.plain)
|
|
|
- } else {
|
|
|
- emptyStateContent
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -189,6 +204,16 @@ struct SessionListView: View {
|
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
|
.padding(.bottom, 60)
|
|
|
}
|
|
|
+
|
|
|
+ @MainActor
|
|
|
+ private func synchronizeFieldRecords() async {
|
|
|
+ guard let userID = authManager.currentUser?.id else { return }
|
|
|
+ _ = await SyncManager.shared.sync(
|
|
|
+ sessions: sessions,
|
|
|
+ modelContext: modelContext,
|
|
|
+ userID: userID
|
|
|
+ )
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private struct SessionSearchModifier: ViewModifier {
|