Add category and recipe sorting with multiple modes and order inversion

Categories on the main page can be sorted by Recently Used, Alphabetical,
or Manual (drag-to-reorder). The sort menu appears inline next to the
Categories header. All Recipes is included in the sort order and manual
reorder sheet. Recipes within category and all-recipes lists can be sorted
by Recently Added or Alphabetical, with the sort button in the toolbar.
All non-manual sort modes support order inversion via a Reverse/Default
Order toggle. Date parsing handles both formatted strings and Unix
timestamps, with recipe_id as fallback when dates are unavailable.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-15 07:46:23 +01:00
parent fb6b16c1fc
commit 5307b502e9
10 changed files with 694 additions and 48 deletions

View File

@@ -151,6 +151,30 @@ class UserSettings: ObservableObject {
}
}
@Published var categorySortMode: String {
didSet {
UserDefaults.standard.set(categorySortMode, forKey: "categorySortMode")
}
}
@Published var categorySortAscending: Bool {
didSet {
UserDefaults.standard.set(categorySortAscending, forKey: "categorySortAscending")
}
}
@Published var recipeSortMode: String {
didSet {
UserDefaults.standard.set(recipeSortMode, forKey: "recipeSortMode")
}
}
@Published var recipeSortAscending: Bool {
didSet {
UserDefaults.standard.set(recipeSortAscending, forKey: "recipeSortAscending")
}
}
init() {
self.username = UserDefaults.standard.object(forKey: "username") as? String ?? ""
self.token = UserDefaults.standard.object(forKey: "token") as? String ?? ""
@@ -175,6 +199,10 @@ class UserSettings: ObservableObject {
self.grocerySyncEnabled = UserDefaults.standard.object(forKey: "grocerySyncEnabled") as? Bool ?? true
self.mealPlanSyncEnabled = UserDefaults.standard.object(forKey: "mealPlanSyncEnabled") as? Bool ?? true
self.appearanceMode = UserDefaults.standard.object(forKey: "appearanceMode") as? String ?? AppearanceMode.system.rawValue
self.categorySortMode = UserDefaults.standard.object(forKey: "categorySortMode") as? String ?? CategorySortMode.recentlyUsed.rawValue
self.categorySortAscending = UserDefaults.standard.object(forKey: "categorySortAscending") as? Bool ?? true
self.recipeSortMode = UserDefaults.standard.object(forKey: "recipeSortMode") as? String ?? RecipeSortMode.recentlyAdded.rawValue
self.recipeSortAscending = UserDefaults.standard.object(forKey: "recipeSortAscending") as? Bool ?? true
if authString == "" {
if token != "" && username != "" {