Fix meal plan not populating on first login and add pull-to-refresh sync

Rewrite MealPlanSyncManager.performSync() (renamed from performInitialSync) to
discover _mealPlanAssignment metadata from all server recipes, not just locally-
known ones. On first sync all recipes are checked; on subsequent syncs only
recipes modified since lastMealPlanSyncDate are fetched (max 5 concurrent).

Trigger meal plan sync from pull-to-refresh on both the recipe and meal plan
tabs, and from the "Refresh all" toolbar button.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 11:40:31 +01:00
parent c8d9ab7397
commit 1f7f19c74b
9 changed files with 108 additions and 36 deletions

View File

@@ -73,6 +73,15 @@ struct MealPlanTabView: View {
}
}
.navigationTitle("Meal Plan")
.refreshable {
await appState.getCategories()
for category in appState.categories {
await appState.getCategory(named: category.name, fetchMode: .preferServer)
}
if UserSettings.shared.mealPlanSyncEnabled {
await mealPlan.syncManager?.performSync()
}
}
.navigationDestination(for: Recipe.self) { recipe in
RecipeView(viewModel: RecipeView.ViewModel(recipe: recipe))
.environmentObject(appState)

View File

@@ -286,6 +286,9 @@ struct RecipeTabView: View {
await appState.getCategory(named: category.name, fetchMode: .preferServer)
await appState.getCategoryImage(for: category.name)
}
if UserSettings.shared.mealPlanSyncEnabled {
await mealPlan.syncManager?.performSync()
}
}
}
@@ -342,6 +345,7 @@ struct RecipeTabView: View {
fileprivate struct RecipeTabViewToolBar: ToolbarContent {
@EnvironmentObject var appState: AppState
@EnvironmentObject var viewModel: RecipeTabView.ViewModel
@EnvironmentObject var mealPlan: MealPlanManager
var body: some ToolbarContent {
// Top left menu toolbar item
@@ -356,6 +360,9 @@ fileprivate struct RecipeTabViewToolBar: ToolbarContent {
await appState.getCategory(named: category.name, fetchMode: .preferServer)
}
await appState.updateAllRecipeDetails()
if UserSettings.shared.mealPlanSyncEnabled {
await mealPlan.syncManager?.performSync()
}
viewModel.presentLoadingIndicator = false
}
} label: {