Add task completion animations, subscription trials, and quiet debug console

- Completion animations: play user-selected animation on task card after completing,
  with DataManager guard to prevent race condition during animation playback.
  Works in both AllTasksView and ResidenceDetailView. Animation preference
  persisted via @AppStorage and configurable from Settings.
- Subscription: add trial fields (trialStart, trialEnd, trialActive) and
  subscriptionSource to model, cross-platform purchase guard, trial banner
  in upgrade prompt, and platform-aware subscription management in profile.
- Analytics: disable PostHog SDK debug logging and remove console print
  statements to reduce debug console noise.
- Documents: remove redundant nested do-catch blocks in ViewModel wrapper.
- Widgets: add debounced timeline reloads and thread-safe file I/O queue.
- Onboarding: fix animation leak on disappear, remove unused state vars.
- Remove unused files (ContentView, StateFlowExtensions, CustomView).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-03-05 11:35:08 -06:00
parent c5f2bee83f
commit 98dbacdea0
73 changed files with 1770 additions and 529 deletions
+9 -2
View File
@@ -22,6 +22,7 @@ struct CompleteTaskView: View {
@State private var showCamera: Bool = false
@State private var selectedContractor: ContractorSummary? = nil
@State private var showContractorPicker: Bool = false
@State private var observationTask: Task<Void, Never>? = nil
var body: some View {
NavigationStack {
@@ -293,6 +294,10 @@ struct CompleteTaskView: View {
.onAppear {
contractorViewModel.loadContractors()
}
.onDisappear {
observationTask?.cancel()
observationTask = nil
}
.handleErrors(
error: errorMessage,
onRetry: { handleComplete() }
@@ -333,9 +338,11 @@ struct CompleteTaskView: View {
completionViewModel.createTaskCompletion(request: request)
}
// Observe the result
Task {
// Observe the result store the Task so it can be cancelled on dismiss
observationTask?.cancel()
observationTask = Task {
for await state in completionViewModel.createCompletionState {
if Task.isCancelled { break }
await MainActor.run {
if let success = state as? ApiResultSuccess<TaskCompletionResponse> {
self.isSubmitting = false