// // CategoryReorderSheet.swift // Nextcloud Cookbook iOS Client // import SwiftUI struct CategoryReorderSheet: View { @EnvironmentObject var appState: AppState @Environment(\.dismiss) private var dismiss private static let allRecipesSentinel = "__ALL_RECIPES__" @State private var orderedNames: [String] = [] var body: some View { NavigationStack { List { ForEach(orderedNames, id: \.self) { name in HStack { if name == Self.allRecipesSentinel { Text("All Recipes") .bold() } else { Text(name) } Spacer() if name == Self.allRecipesSentinel { let total = appState.categories.reduce(0) { $0 + $1.recipe_count } Text("\(total)") .foregroundStyle(.secondary) .font(.subheadline) } else if let count = appState.categories.first(where: { $0.name == name })?.recipe_count { Text("\(count)") .foregroundStyle(.secondary) .font(.subheadline) } } } .onMove { from, to in orderedNames.move(fromOffsets: from, toOffset: to) } } .environment(\.editMode, .constant(.active)) .navigationTitle(String(localized: "Reorder Categories")) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .cancellationAction) { Button(String(localized: "Cancel")) { dismiss() } } ToolbarItem(placement: .confirmationAction) { Button(String(localized: "Done")) { appState.updateManualCategoryOrder(orderedNames) dismiss() } .bold() } } } .onAppear { let currentCategoryNames = appState.categories .filter { $0.recipe_count > 0 } .map { $0.name } let totalCount = appState.categories.reduce(0) { $0 + $1.recipe_count } let existing = appState.manualCategoryOrder // Keep only names that still exist on the server (or are the sentinel) var reconciled = existing.filter { $0 == Self.allRecipesSentinel || currentCategoryNames.contains($0) } // Ensure the All Recipes sentinel is present if totalCount > 0 && !reconciled.contains(Self.allRecipesSentinel) { reconciled.insert(Self.allRecipesSentinel, at: 0) } // Append any new categories not yet in the manual order for name in currentCategoryNames where !reconciled.contains(name) { reconciled.append(name) } orderedNames = reconciled } } }