SPB Git forge

spb/ka-macos

Public
3commits 1branches 0releases
6.1 MBsize
maindefault branch
1 mo agolast push
Swift 98.3% Shell 1.7%
2.8 KB · 84 lines swift
Raw Blame History
1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2// FavoritesStore.swift — favoris et collections UNIFIÉS (tous univers dans une3// même collection : « Déménagement à Val-d'Or » peut contenir un 4½, une auto4// et un resto). Persistance JSON locale (consultation hors ligne).5// Repris de l'app iOS KA, sans haptique.6import Foundation7import SwiftUI89@MainActor10final class FavoritesStore: ObservableObject {11    static let shared = FavoritesStore()1213    struct FavCollection: Identifiable, Codable, Hashable {14        var id: UUID = UUID()15        var name: String16        var items: [KAItem] = []17    }1819    @Published private(set) var collections: [FavCollection] = [] {20        didSet { save() }21    }2223    private var fileURL: URL {24        let dir = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]25            .appendingPathComponent("KA", isDirectory: true)26        try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)27        return dir.appendingPathComponent("ka-favoris.json")28    }2930    init() {31        if let data = try? Data(contentsOf: fileURL),32           let saved = try? JSONDecoder().decode([FavCollection].self, from: data) {33            collections = saved34        }35        if collections.isEmpty {36            collections = [FavCollection(name: "Mes favoris")]37        }38    }3940    private func save() {41        if let data = try? JSONEncoder().encode(collections) {42            try? data.write(to: fileURL, options: .atomic)43        }44    }4546    // MARK: API4748    var allItems: [KAItem] { collections.flatMap(\.items) }49    var count: Int { collections.reduce(0) { $0 + $1.items.count } }5051    func isFavorite(_ item: KAItem) -> Bool {52        collections.contains { $0.items.contains { $0.id == item.id } }53    }5455    func toggle(_ item: KAItem, in collectionID: UUID? = nil) {56        if isFavorite(item) {57            for i in collections.indices {58                collections[i].items.removeAll { $0.id == item.id }59            }60        } else {61            let idx = collections.firstIndex { $0.id == collectionID } ?? 062            collections[idx].items.insert(item, at: 0)63        }64    }6566    func addCollection(_ name: String) {67        let trimmed = name.trimmingCharacters(in: .whitespaces)68        guard !trimmed.isEmpty else { return }69        collections.append(FavCollection(name: trimmed))70    }7172    func removeCollection(_ id: UUID) {73        guard collections.count > 1 else { return }74        collections.removeAll { $0.id == id }75    }7677    func move(_ item: KAItem, to collectionID: UUID) {78        for i in collections.indices { collections[i].items.removeAll { $0.id == item.id } }79        if let idx = collections.firstIndex(where: { $0.id == collectionID }) {80            collections[idx].items.insert(item, at: 0)81        }82    }83}84