123 lines
4.2 KiB
Swift
123 lines
4.2 KiB
Swift
//
|
|
// TravelAlbumAutoRetouchModels.swift
|
|
// suixinkan
|
|
//
|
|
|
|
import Foundation
|
|
|
|
/// 自动修图第一级方式,页面上始终只展示“不修图”和“AI 修图”两个选项。
|
|
enum TravelAlbumRetouchMode: String, CaseIterable, Hashable, Sendable {
|
|
case disabled
|
|
case aiRetouch
|
|
|
|
/// 修图方式的用户可见名称。
|
|
var title: String {
|
|
switch self {
|
|
case .disabled:
|
|
return "不修图"
|
|
case .aiRetouch:
|
|
return "AI 修图"
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 相册自动 AI 修图配置,用于在新建相册与照片上传页之间传递模板选择。
|
|
struct TravelAlbumAutoRetouchConfiguration: Codable, Equatable, Sendable {
|
|
let isEnabled: Bool
|
|
let templateID: String?
|
|
|
|
/// 默认不启用自动修图。
|
|
static let disabled = TravelAlbumAutoRetouchConfiguration(isEnabled: false, templateID: nil)
|
|
|
|
/// 根据已选模板创建启用状态配置。
|
|
static func enabled(templateID: String) -> TravelAlbumAutoRetouchConfiguration {
|
|
TravelAlbumAutoRetouchConfiguration(isEnabled: true, templateID: templateID)
|
|
}
|
|
|
|
/// 当前配置对应的修图模板。
|
|
var template: TravelAlbumEditPreset? {
|
|
guard isEnabled, let templateID else { return nil }
|
|
return TravelAlbumEditPreset.autoRetouchOptions.first { $0.id == templateID }
|
|
}
|
|
|
|
/// 是否可以作为完整的自动修图配置提交。
|
|
var isValid: Bool {
|
|
!isEnabled || template != nil
|
|
}
|
|
|
|
/// 上传页紧凑设置项的展示文案。
|
|
var uploadOptionTitle: String {
|
|
isEnabled ? TravelAlbumRetouchMode.aiRetouch.title : TravelAlbumRetouchMode.disabled.title
|
|
}
|
|
}
|
|
|
|
extension TravelAlbumEditPreset {
|
|
/// 自动修图可选模板,不包含手动修图中的“还原为原图”。
|
|
static var autoRetouchOptions: [TravelAlbumEditPreset] {
|
|
defaultOptions.filter { $0.effect != .original }
|
|
}
|
|
}
|
|
|
|
/// 单张 OTG 照片的自动 AI 修图状态,与原有上传状态分开计算。
|
|
enum TravelAlbumAutoRetouchState: String, Codable, Equatable, Sendable {
|
|
case none = "NONE"
|
|
case processing = "PROCESSING"
|
|
case completed = "COMPLETED"
|
|
case failed = "FAILED"
|
|
}
|
|
|
|
/// 相册自动修图配置读写接口,便于 ViewModel 与单元测试注入。
|
|
protocol TravelAlbumAutoRetouchConfigurationStoring: AnyObject {
|
|
/// 读取指定服务端相册的配置。
|
|
func configuration(albumID: Int) -> TravelAlbumAutoRetouchConfiguration
|
|
|
|
/// 保存指定服务端相册的配置。
|
|
func save(_ configuration: TravelAlbumAutoRetouchConfiguration, albumID: Int)
|
|
|
|
/// 删除指定相册的本地配置。
|
|
func remove(albumID: Int)
|
|
}
|
|
|
|
/// 使用 UserDefaults 按服务端相册 ID 持久化自动 AI 修图配置。
|
|
final class TravelAlbumAutoRetouchConfigurationStore: TravelAlbumAutoRetouchConfigurationStoring {
|
|
static let shared = TravelAlbumAutoRetouchConfigurationStore()
|
|
|
|
private let userDefaults: UserDefaults
|
|
private let keyPrefix: String
|
|
|
|
/// 创建配置存储;测试可传入独立 UserDefaults suite。
|
|
init(
|
|
userDefaults: UserDefaults = .standard,
|
|
keyPrefix: String = "travelAlbum.autoRetouch.album"
|
|
) {
|
|
self.userDefaults = userDefaults
|
|
self.keyPrefix = keyPrefix
|
|
}
|
|
|
|
func configuration(albumID: Int) -> TravelAlbumAutoRetouchConfiguration {
|
|
guard albumID > 0,
|
|
let data = userDefaults.data(forKey: key(albumID: albumID)),
|
|
let configuration = try? JSONDecoder().decode(TravelAlbumAutoRetouchConfiguration.self, from: data),
|
|
configuration.isValid else {
|
|
return .disabled
|
|
}
|
|
return configuration
|
|
}
|
|
|
|
func save(_ configuration: TravelAlbumAutoRetouchConfiguration, albumID: Int) {
|
|
guard albumID > 0 else { return }
|
|
let normalized = configuration.isValid ? configuration : .disabled
|
|
guard let data = try? JSONEncoder().encode(normalized) else { return }
|
|
userDefaults.set(data, forKey: key(albumID: albumID))
|
|
}
|
|
|
|
func remove(albumID: Int) {
|
|
guard albumID > 0 else { return }
|
|
userDefaults.removeObject(forKey: key(albumID: albumID))
|
|
}
|
|
|
|
private func key(albumID: Int) -> String {
|
|
"\(keyPrefix).\(albumID)"
|
|
}
|
|
}
|