a75215a937
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
88 lines
2.5 KiB
Swift
88 lines
2.5 KiB
Swift
import Foundation
|
|
import Messages
|
|
|
|
final class StickerStore {
|
|
static let shared = StickerStore()
|
|
|
|
private let packsKey = "savedPacks"
|
|
private let defaults = UserDefaults.standard
|
|
private let fileManager = FileManager.default
|
|
|
|
private init() {}
|
|
|
|
// MARK: - Pack persistence
|
|
|
|
var savedPacks: [SavedPack] {
|
|
get {
|
|
guard let data = defaults.data(forKey: packsKey) else { return [] }
|
|
return (try? JSONDecoder().decode([SavedPack].self, from: data)) ?? []
|
|
}
|
|
set {
|
|
let data = try? JSONEncoder().encode(newValue)
|
|
defaults.set(data, forKey: packsKey)
|
|
}
|
|
}
|
|
|
|
// MARK: - File management
|
|
|
|
private var stickersDirectory: URL {
|
|
let caches = fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!
|
|
return caches.appendingPathComponent("stickers", isDirectory: true)
|
|
}
|
|
|
|
private func packDirectory(name: String) -> URL {
|
|
stickersDirectory.appendingPathComponent(name, isDirectory: true)
|
|
}
|
|
|
|
// MARK: - Add / remove packs
|
|
|
|
func addPack(response: StickerSetResponse) async throws {
|
|
let pack = SavedPack(name: response.name, title: response.title, stickerCount: response.stickerCount)
|
|
|
|
// Download all sticker PNGs
|
|
let packDir = packDirectory(name: response.name)
|
|
try fileManager.createDirectory(at: packDir, withIntermediateDirectories: true)
|
|
|
|
for sticker in response.stickers {
|
|
let localURL = packDir.appendingPathComponent("\(sticker.id).png")
|
|
if fileManager.fileExists(atPath: localURL.path) { continue }
|
|
try await StickerClonerAPI.downloadSticker(from: sticker.pngUrl, to: localURL)
|
|
}
|
|
|
|
// Save metadata after successful download
|
|
var packs = savedPacks
|
|
packs.removeAll { $0.name == pack.name }
|
|
packs.append(pack)
|
|
savedPacks = packs
|
|
}
|
|
|
|
func removePack(name: String) {
|
|
var packs = savedPacks
|
|
packs.removeAll { $0.name == name }
|
|
savedPacks = packs
|
|
|
|
let packDir = packDirectory(name: name)
|
|
try? fileManager.removeItem(at: packDir)
|
|
}
|
|
|
|
// MARK: - Load stickers for display
|
|
|
|
func loadStickers() -> [MSSticker] {
|
|
var stickers: [MSSticker] = []
|
|
|
|
for pack in savedPacks {
|
|
let packDir = packDirectory(name: pack.name)
|
|
guard let files = try? fileManager.contentsOfDirectory(at: packDir, includingPropertiesForKeys: nil) else { continue }
|
|
|
|
for file in files.sorted(by: { $0.lastPathComponent < $1.lastPathComponent }) {
|
|
guard file.pathExtension == "png" else { continue }
|
|
if let sticker = try? MSSticker(contentsOfFileURL: file, localizedDescription: pack.title) {
|
|
stickers.append(sticker)
|
|
}
|
|
}
|
|
}
|
|
|
|
return stickers
|
|
}
|
|
}
|