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:
55
Nextcloud Cookbook iOS Client/Data/CategorySortMode.swift
Normal file
55
Nextcloud Cookbook iOS Client/Data/CategorySortMode.swift
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// CategorySortMode.swift
|
||||
// Nextcloud Cookbook iOS Client
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum CategorySortMode: String, CaseIterable {
|
||||
case recentlyUsed = "recentlyUsed"
|
||||
case alphabetical = "alphabetical"
|
||||
case manual = "manual"
|
||||
|
||||
func descriptor() -> String {
|
||||
switch self {
|
||||
case .recentlyUsed: return String(localized: "Recently Used")
|
||||
case .alphabetical: return String(localized: "Alphabetical")
|
||||
case .manual: return String(localized: "Manual")
|
||||
}
|
||||
}
|
||||
|
||||
var iconName: String {
|
||||
switch self {
|
||||
case .recentlyUsed: return "clock"
|
||||
case .alphabetical: return "textformat.abc"
|
||||
case .manual: return "line.3.horizontal"
|
||||
}
|
||||
}
|
||||
|
||||
var supportsInvert: Bool {
|
||||
self != .manual
|
||||
}
|
||||
|
||||
static let allValues: [CategorySortMode] = CategorySortMode.allCases
|
||||
}
|
||||
|
||||
enum RecipeSortMode: String, CaseIterable {
|
||||
case recentlyAdded = "recentlyAdded"
|
||||
case alphabetical = "alphabetical"
|
||||
|
||||
func descriptor() -> String {
|
||||
switch self {
|
||||
case .recentlyAdded: return String(localized: "Recently Added")
|
||||
case .alphabetical: return String(localized: "Alphabetical")
|
||||
}
|
||||
}
|
||||
|
||||
var iconName: String {
|
||||
switch self {
|
||||
case .recentlyAdded: return "clock"
|
||||
case .alphabetical: return "textformat.abc"
|
||||
}
|
||||
}
|
||||
|
||||
static let allValues: [RecipeSortMode] = RecipeSortMode.allCases
|
||||
}
|
||||
@@ -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 != "" {
|
||||
|
||||
Reference in New Issue
Block a user