import Foundation import UIKit import SwiftSignalKit import TelegramCore import TelegramUIPreferences import MediaEditor public final class MediaEditorStoredTextSettings: Codable { private enum CodingKeys: String, CodingKey { case style case font case fontSize case alignment } public let style: DrawingTextEntity.Style public let font: DrawingTextEntity.Font public let fontSize: CGFloat public let alignment: DrawingTextEntity.Alignment public init( style: DrawingTextEntity.Style, font: DrawingTextEntity.Font, fontSize: CGFloat, alignment: DrawingTextEntity.Alignment ) { self.style = style self.font = font self.fontSize = fontSize self.alignment = alignment } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.style = try container.decode(DrawingTextEntity.Style.self, forKey: .style) self.font = try container.decode(DrawingTextEntity.Font.self, forKey: .font) self.fontSize = try container.decode(CGFloat.self, forKey: .fontSize) self.alignment = try container.decode(DrawingTextEntity.Alignment.self, forKey: .alignment) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(self.style, forKey: .style) try container.encode(self.font, forKey: .font) try container.encode(self.fontSize, forKey: .fontSize) try container.encode(self.alignment, forKey: .alignment) } } public final class MediaEditorStoredState: Codable { private enum CodingKeys: String, CodingKey { case privacy case textSettings } public let privacy: MediaEditorResultPrivacy? public let textSettings: MediaEditorStoredTextSettings? public init(privacy: MediaEditorResultPrivacy?, textSettings: MediaEditorStoredTextSettings?) { self.privacy = privacy self.textSettings = textSettings } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) if let data = try container.decodeIfPresent(Data.self, forKey: .privacy), let privacy = try? JSONDecoder().decode(MediaEditorResultPrivacy.self, from: data) { self.privacy = privacy } else { self.privacy = nil } if let data = try container.decodeIfPresent(Data.self, forKey: .textSettings), let privacy = try? JSONDecoder().decode(MediaEditorStoredTextSettings.self, from: data) { self.textSettings = privacy } else { self.textSettings = nil } } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) if let privacy = self.privacy { if let data = try? JSONEncoder().encode(privacy) { try container.encode(data, forKey: .privacy) } else { try container.encodeNil(forKey: .privacy) } } else { try container.encodeNil(forKey: .privacy) } if let textSettings = self.textSettings { if let data = try? JSONEncoder().encode(textSettings) { try container.encode(data, forKey: .textSettings) } else { try container.encodeNil(forKey: .textSettings) } } else { try container.encodeNil(forKey: .textSettings) } } public func withUpdatedPrivacy(_ privacy: MediaEditorResultPrivacy) -> MediaEditorStoredState { return MediaEditorStoredState(privacy: privacy, textSettings: self.textSettings) } public func withUpdatedTextSettings(_ textSettings: MediaEditorStoredTextSettings) -> MediaEditorStoredState { return MediaEditorStoredState(privacy: self.privacy, textSettings: textSettings) } } func mediaEditorStoredState(engine: TelegramEngine) -> Signal { let key = EngineDataBuffer(length: 4) key.setInt32(0, value: 0) return engine.data.get(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: ApplicationSpecificItemCacheCollectionId.mediaEditorState, id: key)) |> map { entry -> MediaEditorStoredState? in return entry?.get(MediaEditorStoredState.self) } } func updateMediaEditorStoredStateInteractively(engine: TelegramEngine, _ f: @escaping (MediaEditorStoredState?) -> MediaEditorStoredState?) -> Signal { let key = EngineDataBuffer(length: 4) key.setInt32(0, value: 0) return engine.data.get(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: ApplicationSpecificItemCacheCollectionId.mediaEditorState, id: key)) |> map { entry -> MediaEditorStoredState? in return entry?.get(MediaEditorStoredState.self) } |> mapToSignal { state -> Signal in if let updatedState = f(state) { return engine.itemCache.put(collectionId: ApplicationSpecificItemCacheCollectionId.mediaEditorState, id: key, item: updatedState) } else { return engine.itemCache.remove(collectionId: ApplicationSpecificItemCacheCollectionId.mediaEditorState, id: key) } } }