1.0.1: add review funnel, trial onboarding, and app diagnostics

This commit is contained in:
alexandrev-tibco
2026-02-26 10:33:45 +01:00
parent c5c7e3d2e4
commit 9bdbf80e67
8 changed files with 253 additions and 27 deletions
+28 -1
View File
@@ -4,6 +4,7 @@ import SwiftData
struct HomeView: View {
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
@Environment(\.modelContext) private var context
@Environment(\.openURL) private var openURL
@Query private var dishes: [Dish]
@Query private var tags: [Tag]
@Query(sort: \WeekPlan.weekStartDate, order: .forward) private var weekPlans: [WeekPlan]
@@ -18,6 +19,8 @@ struct HomeView: View {
@State private var showWeekPicker: Bool = false
@State private var weekPickerDate: Date = Date()
@State private var showCopyPreviousConfirm: Bool = false
@State private var showReviewSentimentPrompt: Bool = false
@State private var showReviewSupportPrompt: Bool = false
private var settings: AppSettings? { allSettings.first }
@@ -248,6 +251,28 @@ struct HomeView: View {
secondaryButton: .cancel(Text("reset_cancel"))
)
}
.alert("review_funnel_title", isPresented: $showReviewSentimentPrompt) {
Button("review_funnel_positive") {
ReviewPromptService.shared.requestReview()
ReviewPromptService.shared.markReviewCompleted()
}
Button("review_funnel_negative", role: .destructive) {
showReviewSupportPrompt = true
}
Button("reset_cancel", role: .cancel) {}
} message: {
Text("review_funnel_message")
}
.alert("review_feedback_title", isPresented: $showReviewSupportPrompt) {
Button("review_feedback_contact") {
if let url = URL(string: "mailto:support@mealmood.app?subject=MealMood%20Feedback") {
openURL(url)
}
}
Button("reset_cancel", role: .cancel) {}
} message: {
Text("review_feedback_message")
}
.sheet(isPresented: $viewModel.showDishForm) {
DishFormView()
}
@@ -614,7 +639,9 @@ struct HomeView: View {
let descriptor = FetchDescriptor<WeekPlan>()
guard let plans = try? context.fetch(descriptor) else { return }
let completedWeeks = plans.filter { !$0.slots.isEmpty && $0.slots.allSatisfy { $0.dishId != nil } }.count
ReviewPromptService.shared.considerPromptAfterWeekCompletion(completedWeeks: completedWeeks)
guard ReviewPromptService.shared.shouldShowFunnelAfterWeekCompletion(completedWeeks: completedWeeks) else { return }
ReviewPromptService.shared.markFunnelShown(completedWeeks: completedWeeks)
showReviewSentimentPrompt = true
}
}