cs193p-emojiart/EmojiArt/PaletteStore.swift
Ching 566f3539d1 feat(view, viewmodels): 增加调色板按钮,增加报错提示
1. 增加从调色板中增加、删除、跳转和编辑 emoji 的功能
2. 增加通过 url 获取背景图时失败带报错

Signed-off-by: Ching <loooching@gmail.com>
2023-02-26 19:34:35 +08:00

80 lines
2.4 KiB
Swift

//
// PaletteStore.swift
// EmojiArt
//
// Created by ching on 2023/2/23.
//
import SwiftUI
struct Palette: Identifiable, Codable, Hashable {
var name: String
var emojis: String
var id: Int
fileprivate init(name: String, emojis: String, id: Int) {
self.name = name
self.emojis = emojis
self.id = id
}
}
class PaletteStore: ObservableObject {
let name: String
@Published var palettes = [Palette]() {
didSet {
storeInUserDefaults()
}
}
private var userDefaultsKey: String {
"PaletteStore:" + name
}
private func storeInUserDefaults() {
UserDefaults.standard.set(try? JSONEncoder().encode(palettes), forKey: userDefaultsKey)
}
private func restoreFromUserDefaults() {
if let jsonData = UserDefaults.standard.data(forKey: userDefaultsKey),
let decodedPalettes = try? JSONDecoder().decode(Array<Palette>.self, from: jsonData) {
palettes = decodedPalettes
}
}
init(named name: String) {
self.name = name
restoreFromUserDefaults()
if palettes.isEmpty {
print("using built-in palettes")
insertPalette(named: "Vehicles", emojis: "🚗🚕🚙🚌🚎🏎🚓🚑🚒🚐🛻🚚🚛🚜🦯🦽🦼🛴🚲🛵🏍🛺🚨🚔🚍🚘🚖🛞🚡🚠🚟🚃🚋🚞🚝🚄🚅🚈🚂🚆🚇🚊🚉✈️🛫🛬🛩")
insertPalette(named: "Sports", emojis: "⚽️🏀🏈⚾️🥎🎾🏐🏉🥏🎱🪀🏓🏸🏒🏑🥍🏏")
} else {
print("loaded palettes")
}
}
// Intent
func palette(at index: Int) -> Palette {
let safeIndex = min(max(index, 0), palettes.count - 1)
return palettes[safeIndex]
}
@discardableResult
func removePalette(at index: Int) -> Int {
if palettes.count > 1, palettes.indices.contains(index) {
palettes.remove(at: index)
}
return index % palettes.count
}
func insertPalette(named name: String, emojis: String? = nil, at index: Int = 0) {
let unique = (palettes.max(by: { $0.id < $1.id })?.id ?? 0) + 1
let palette = Palette(name: name, emojis: emojis ?? "", id: unique)
let safeIndex = min(max(index, 0), palettes.count)
palettes.insert(palette, at: safeIndex)
}
}