TM-SGNL-iOS/SignalServiceKit/UISupport/WallpaperStore.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

137 lines
5.3 KiB
Swift

//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
public class WallpaperStore {
public static let wallpaperDidChangeNotification = NSNotification.Name("wallpaperDidChangeNotification")
private enum Constants {
static let globalPersistenceKey = "global"
}
private let wallpaperImageStore: WallpaperImageStore
private let enumStore: KeyValueStore
private let dimmingStore: KeyValueStore
private let notificationScheduler: Scheduler
init(
notificationScheduler: Scheduler,
wallpaperImageStore: WallpaperImageStore
) {
self.enumStore = KeyValueStore(collection: "Wallpaper+Enum")
self.dimmingStore = KeyValueStore(collection: "Wallpaper+Dimming")
self.notificationScheduler = notificationScheduler
self.wallpaperImageStore = wallpaperImageStore
}
// MARK: - Persistence Keys
private static func persistenceKey(for threadUniqueId: String?) -> String {
return threadUniqueId ?? Constants.globalPersistenceKey
}
private static func threadUniqueId(for persistenceKey: String) -> String? {
if persistenceKey == Constants.globalPersistenceKey {
return nil
}
return persistenceKey
}
// MARK: - Getters & Setters
public func setBuiltIn(_ wallpaper: Wallpaper, for thread: TSThread? = nil) throws {
owsAssertDebug(wallpaper != .photo)
try _set(wallpaper, for: thread)
}
public func setPhoto(_ photo: UIImage, for thread: TSThread? = nil) throws {
try _set(.photo, photo: photo, for: thread)
}
private func _set(_ wallpaper: Wallpaper?, photo: UIImage? = nil, for thread: TSThread?) throws {
owsAssertDebug(photo == nil || wallpaper == .photo)
let onInsert = { [self] (tx: DBWriteTransaction) throws -> Void in
self.setWallpaperType(wallpaper, for: thread?.uniqueId, tx: tx)
}
if let thread {
try wallpaperImageStore.setWallpaperImage(photo, for: thread, onInsert: onInsert)
} else {
try wallpaperImageStore.setGlobalThreadWallpaperImage(photo, onInsert: onInsert)
}
}
/// Set just the type; doesn't override any wallpaper image that may be set.
public func setWallpaperType(_ wallpaper: Wallpaper?, for threadUniqueId: String?, tx: DBWriteTransaction) {
enumStore.setString(wallpaper?.rawValue, key: Self.persistenceKey(for: threadUniqueId), transaction: tx)
postWallpaperDidChangeNotification(for: threadUniqueId, tx: tx)
}
public func fetchWallpaper(for threadUniqueId: String?, tx: DBReadTransaction) -> Wallpaper? {
guard let raw = enumStore.getString(Self.persistenceKey(for: threadUniqueId), transaction: tx) else {
return nil
}
guard let wallpaper = Wallpaper(rawValue: raw) else {
owsFailDebug("Unexpected wallpaper \(raw)")
return nil
}
return wallpaper
}
/// Return either the per-thread wallpaper setting, or the global setting if none is set on the thread.
public func fetchWallpaperForRendering(
for threadUniqueId: String?,
tx: DBReadTransaction
) -> Wallpaper? {
if let wallpaper = fetchWallpaper(for: threadUniqueId, tx: tx) {
return wallpaper
}
if threadUniqueId != nil, let globalWallpaper = fetchWallpaper(for: nil, tx: tx) {
return globalWallpaper
}
return nil
}
public func fetchUniqueThreadIdsWithWallpaper(tx: DBReadTransaction) -> [String?] {
return enumStore.allKeys(transaction: tx).map { Self.threadUniqueId(for: $0) }
}
public func setDimInDarkMode(_ dimInDarkMode: Bool, for threadUniqueId: String?, tx: DBWriteTransaction) {
dimmingStore.setBool(dimInDarkMode, key: Self.persistenceKey(for: threadUniqueId), transaction: tx)
postWallpaperDidChangeNotification(for: threadUniqueId, tx: tx)
}
public func fetchOptionalDimInDarkMode(for threadUniqueId: String?, tx: DBReadTransaction) -> Bool? {
return dimmingStore.getBool(Self.persistenceKey(for: threadUniqueId), transaction: tx)
}
public func fetchDimInDarkMode(for threadUniqueId: String?, tx: DBReadTransaction) -> Bool {
return dimmingStore.getBool(Self.persistenceKey(for: threadUniqueId), transaction: tx) ?? true
}
// MARK: - Resetting Values
public func reset(for thread: TSThread?, tx: DBWriteTransaction) throws {
let threadUniqueId = thread?.uniqueId
enumStore.removeValue(forKey: Self.persistenceKey(for: threadUniqueId), transaction: tx)
dimmingStore.removeValue(forKey: Self.persistenceKey(for: threadUniqueId), transaction: tx)
postWallpaperDidChangeNotification(for: threadUniqueId, tx: tx)
}
public func resetAll(tx: DBWriteTransaction) throws {
enumStore.removeAll(transaction: tx)
dimmingStore.removeAll(transaction: tx)
postWallpaperDidChangeNotification(for: nil, tx: tx)
}
private func postWallpaperDidChangeNotification(for threadUniqueId: String?, tx: DBWriteTransaction) {
tx.addAsyncCompletion(on: notificationScheduler) {
NotificationCenter.default.post(name: Self.wallpaperDidChangeNotification, object: threadUniqueId)
}
}
}