Update themes API [skip ci]

This commit is contained in:
Ilya Laktyushin 2019-12-23 13:26:54 +03:00
parent 2e09ca0a4d
commit 88436ccb5c
8 changed files with 2198 additions and 1760 deletions

View File

@ -1,21 +1,88 @@
import Postbox
public enum TelegramBaseTheme: Int32 {
case classic
case day
case night
case tinted
}
public final class TelegramThemeSettings: PostboxCoding, Equatable {
public static func == (lhs: TelegramThemeSettings, rhs: TelegramThemeSettings) -> Bool {
if lhs.baseTheme != rhs.baseTheme {
return false
}
if lhs.accentColor != rhs.accentColor {
return false
}
if lhs.messageColors?.0 != rhs.messageColors?.0 || lhs.messageColors?.1 != rhs.messageColors?.1 {
return false
}
if lhs.wallpaper != rhs.wallpaper {
return false
}
return true
}
public let baseTheme: TelegramBaseTheme
public let accentColor: Int32
public let messageColors: (top: Int32, bottom: Int32)?
public let wallpaper: TelegramWallpaper?
public init(baseTheme: TelegramBaseTheme, accentColor: Int32, messageColors: (top: Int32, bottom: Int32)?, wallpaper: TelegramWallpaper?) {
self.baseTheme = baseTheme
self.accentColor = accentColor
self.messageColors = messageColors
self.wallpaper = wallpaper
}
public init(decoder: PostboxDecoder) {
self.baseTheme = TelegramBaseTheme(rawValue: decoder.decodeInt32ForKey("baseTheme", orElse: 0)) ?? .classic
self.accentColor = decoder.decodeInt32ForKey("accent", orElse: 0)
if let topMessageColor = decoder.decodeOptionalInt32ForKey("topMessage"), let bottomMessageColor = decoder.decodeOptionalInt32ForKey("bottomMessage") {
self.messageColors = (topMessageColor, bottomMessageColor)
} else {
self.messageColors = nil
}
self.wallpaper = decoder.decodeObjectForKey("wallpaper", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.baseTheme.rawValue, forKey: "baseTheme")
encoder.encodeInt32(self.accentColor, forKey: "accent")
if let (topMessageColor, bottomMessageColor) = self.messageColors {
encoder.encodeInt32(topMessageColor, forKey: "topMessage")
encoder.encodeInt32(bottomMessageColor, forKey: "bottomMessage")
} else {
encoder.encodeNil(forKey: "topMessage")
encoder.encodeNil(forKey: "bottomMessage")
}
if let wallpaper = self.wallpaper {
encoder.encodeObject(wallpaper, forKey: "wallpaper")
} else {
encoder.encodeNil(forKey: "wallpaper")
}
}
}
public final class TelegramTheme: OrderedItemListEntryContents, Equatable {
public let id: Int64
public let accessHash: Int64
public let slug: String
public let title: String
public let file: TelegramMediaFile?
public let settings: TelegramThemeSettings?
public let isCreator: Bool
public let isDefault: Bool
public let installCount: Int32
public init(id: Int64, accessHash: Int64, slug: String, title: String, file: TelegramMediaFile?, isCreator: Bool, isDefault: Bool, installCount: Int32) {
public init(id: Int64, accessHash: Int64, slug: String, title: String, file: TelegramMediaFile?, settings: TelegramThemeSettings?, isCreator: Bool, isDefault: Bool, installCount: Int32) {
self.id = id
self.accessHash = accessHash
self.slug = slug
self.title = title
self.file = file
self.settings = settings
self.isCreator = isCreator
self.isDefault = isDefault
self.installCount = installCount
@ -27,6 +94,7 @@ public final class TelegramTheme: OrderedItemListEntryContents, Equatable {
self.slug = decoder.decodeStringForKey("slug", orElse: "")
self.title = decoder.decodeStringForKey("title", orElse: "")
self.file = decoder.decodeObjectForKey("file", decoder: { TelegramMediaFile(decoder: $0) }) as? TelegramMediaFile
self.settings = decoder.decodeObjectForKey("settings", decoder: { TelegramThemeSettings(decoder: $0) }) as? TelegramThemeSettings
self.isCreator = decoder.decodeInt32ForKey("isCreator", orElse: 0) != 0
self.isDefault = decoder.decodeInt32ForKey("isDefault", orElse: 0) != 0
self.installCount = decoder.decodeInt32ForKey("installCount", orElse: 0)
@ -42,6 +110,11 @@ public final class TelegramTheme: OrderedItemListEntryContents, Equatable {
} else {
encoder.encodeNil(forKey: "file")
}
if let settings = self.settings {
encoder.encodeObject(settings, forKey: "settings")
} else {
encoder.encodeNil(forKey: "settings")
}
encoder.encodeInt32(self.isCreator ? 1 : 0, forKey: "isCreator")
encoder.encodeInt32(self.isDefault ? 1 : 0, forKey: "isDefault")
encoder.encodeInt32(self.installCount, forKey: "installCount")
@ -63,6 +136,9 @@ public final class TelegramTheme: OrderedItemListEntryContents, Equatable {
if lhs.file?.id != rhs.file?.id {
return false
}
if lhs.settings != rhs.settings {
return false
}
if lhs.isCreator != rhs.isCreator {
return false
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5835,41 +5835,6 @@ public extension Api {
})
}
public static func createTheme(slug: String, title: String, document: Api.InputDocument) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Theme>) {
let buffer = Buffer()
buffer.appendInt32(729808255)
serializeString(slug, buffer: buffer, boxed: false)
serializeString(title, buffer: buffer, boxed: false)
document.serialize(buffer, true)
return (FunctionDescription(name: "account.createTheme", parameters: [("slug", slug), ("title", title), ("document", document)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Theme? in
let reader = BufferReader(buffer)
var result: Api.Theme?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Theme
}
return result
})
}
public static func updateTheme(flags: Int32, format: String, theme: Api.InputTheme, slug: String?, title: String?, document: Api.InputDocument?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Theme>) {
let buffer = Buffer()
buffer.appendInt32(999203330)
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(format, buffer: buffer, boxed: false)
theme.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {serializeString(slug!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 1) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 2) != 0 {document!.serialize(buffer, true)}
return (FunctionDescription(name: "account.updateTheme", parameters: [("flags", flags), ("format", format), ("theme", theme), ("slug", slug), ("title", title), ("document", document)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Theme? in
let reader = BufferReader(buffer)
var result: Api.Theme?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Theme
}
return result
})
}
public static func saveTheme(theme: Api.InputTheme, unsave: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-229175188)
@ -5959,6 +5924,44 @@ public extension Api {
return result
})
}
public static func createTheme(flags: Int32, slug: String, title: String, document: Api.InputDocument, settings: Api.InputThemeSettings?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Theme>) {
let buffer = Buffer()
buffer.appendInt32(-1683113716)
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(slug, buffer: buffer, boxed: false)
serializeString(title, buffer: buffer, boxed: false)
document.serialize(buffer, true)
if Int(flags) & Int(1 << 3) != 0 {settings!.serialize(buffer, true)}
return (FunctionDescription(name: "account.createTheme", parameters: [("flags", flags), ("slug", slug), ("title", title), ("document", document), ("settings", settings)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Theme? in
let reader = BufferReader(buffer)
var result: Api.Theme?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Theme
}
return result
})
}
public static func updateTheme(flags: Int32, format: String, theme: Api.InputTheme, slug: String?, title: String?, document: Api.InputDocument?, settings: Api.InputThemeSettings?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Theme>) {
let buffer = Buffer()
buffer.appendInt32(1555261397)
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(format, buffer: buffer, boxed: false)
theme.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {serializeString(slug!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 1) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 2) != 0 {document!.serialize(buffer, true)}
if Int(flags) & Int(1 << 3) != 0 {settings!.serialize(buffer, true)}
return (FunctionDescription(name: "account.updateTheme", parameters: [("flags", flags), ("format", format), ("theme", theme), ("slug", slug), ("title", title), ("document", document), ("settings", settings)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Theme? in
let reader = BufferReader(buffer)
var result: Api.Theme?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Theme
}
return result
})
}
}
public struct wallet {
public static func sendLiteRequest(body: Buffer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.wallet.LiteResponse>) {

View File

@ -99,7 +99,7 @@ public func addressNameAvailability(account: Account, domain: AddressNameDomain,
return .single(.invalid)
}
case .theme:
return account.network.request(Api.functions.account.createTheme(slug: name, title: "", document: .inputDocumentEmpty))
return account.network.request(Api.functions.account.createTheme(flags: 0, slug: name, title: "", document: .inputDocumentEmpty, settings: nil))
|> map { _ -> AddressNameAvailability in
return .available
}
@ -162,7 +162,7 @@ public func updateAddressName(account: Account, domain: AddressNameDomain, name:
}
case let .theme(theme):
let flags: Int32 = 1 << 0
return account.network.request(Api.functions.account.updateTheme(flags: flags, format: telegramThemeFormat, theme: .inputTheme(id: theme.id, accessHash: theme.accessHash), slug: nil, title: nil, document: nil))
return account.network.request(Api.functions.account.updateTheme(flags: flags, format: telegramThemeFormat, theme: .inputTheme(id: theme.id, accessHash: theme.accessHash), slug: nil, title: nil, document: nil, settings: nil))
|> mapError { _ -> UpdateAddressNameError in
return .generic
}

View File

@ -8,10 +8,70 @@ import SyncCore
extension TelegramTheme {
convenience init?(apiTheme: Api.Theme) {
switch apiTheme {
case let .theme(flags, id, accessHash, slug, title, document, installCount):
self.init(id: id, accessHash: accessHash, slug: slug, title: title, file: document.flatMap(telegramMediaFileFromApiDocument), isCreator: (flags & 1 << 0) != 0, isDefault: (flags & 1 << 1) != 0, installCount: installCount)
case let .theme(flags, id, accessHash, slug, title, document, settings, installCount):
self.init(id: id, accessHash: accessHash, slug: slug, title: title, file: document.flatMap(telegramMediaFileFromApiDocument), settings: settings.flatMap(TelegramThemeSettings.init(apiThemeSettings:)), isCreator: (flags & 1 << 0) != 0, isDefault: (flags & 1 << 1) != 0, installCount: installCount)
default:
return nil
}
}
}
extension TelegramBaseTheme {
init(apiBaseTheme: Api.BaseTheme) {
switch apiBaseTheme {
case .baseThemeClassic:
self = .classic
case .baseThemeDay:
self = .day
case .baseThemeNight:
self = .night
case .baseThemeTinted:
self = .tinted
}
}
var apiBaseTheme: Api.BaseTheme {
switch self {
case .classic:
return .baseThemeClassic
case .day:
return .baseThemeDay
case .night:
return .baseThemeNight
case .tinted:
return .baseThemeTinted
}
}
}
extension TelegramThemeSettings {
convenience init?(apiThemeSettings: Api.ThemeSettings) {
switch apiThemeSettings {
case let .themeSettings(flags, baseTheme, accentColor, messageTopColor, messageBottomColor, wallpaper):
var messageColors: (Int32, Int32)?
if let messageTopColor = messageTopColor, let messageBottomColor = messageBottomColor {
messageColors = (messageTopColor, messageBottomColor)
}
self.init(baseTheme: TelegramBaseTheme(apiBaseTheme: baseTheme) ?? .classic, accentColor: accentColor, messageColors: messageColors, wallpaper: wallpaper.flatMap(TelegramWallpaper.init(apiWallpaper:)))
default:
return nil
}
}
var apiInputThemeSettings: Api.InputThemeSettings {
var flags: Int32 = 0
if let _ = self.messageColors {
flags |= 1 << 0
}
var inputWallpaper: Api.InputWallPaper?
var inputWallpaperSettings: Api.WallPaperSettings?
if let wallpaper = self.wallpaper, let inputWallpaperAndSettings = wallpaper.apiInputWallpaperAndSettings {
inputWallpaper = inputWallpaperAndSettings.0
inputWallpaperSettings = inputWallpaperAndSettings.1
flags |= 1 << 1
}
return .inputThemeSettings(flags: flags, baseTheme: self.baseTheme.apiBaseTheme, accentColor: self.accentColor, messageTopColor: self.messageColors?.0, messageBottomColor: self.messageColors?.1, wallpaper: inputWallpaper, wallpaperSettings: inputWallpaperSettings)
}
}

View File

@ -279,14 +279,22 @@ public enum CreateThemeResult {
case progress(Float)
}
public func createTheme(account: Account, title: String, resource: MediaResource, thumbnailData: Data? = nil) -> Signal<CreateThemeResult, CreateThemeError> {
public func createTheme(account: Account, title: String, resource: MediaResource, thumbnailData: Data? = nil, settings: TelegramThemeSettings?) -> Signal<CreateThemeResult, CreateThemeError> {
var flags: Int32 = 0
var inputSettings: Api.InputThemeSettings?
if let settings = settings {
flags |= 1 << 3
inputSettings = settings.apiInputThemeSettings
}
return uploadTheme(account: account, resource: resource, thumbnailData: thumbnailData)
|> mapError { _ in return CreateThemeError.generic }
|> mapToSignal { result -> Signal<CreateThemeResult, CreateThemeError> in
switch result {
case let .complete(file):
if let resource = file.resource as? CloudDocumentMediaResource {
return account.network.request(Api.functions.account.createTheme(slug: "", title: title, document: .inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference))))
return account.network.request(Api.functions.account.createTheme(flags: flags, slug: "", title: title, document: .inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference)), settings: inputSettings))
|> mapError { error in
if error.errorDescription == "THEME_SLUG_INVALID" {
return .slugInvalid
@ -325,7 +333,7 @@ public func createTheme(account: Account, title: String, resource: MediaResource
}
}
public func updateTheme(account: Account, accountManager: AccountManager, theme: TelegramTheme, title: String?, slug: String?, resource: MediaResource?, thumbnailData: Data? = nil) -> Signal<CreateThemeResult, CreateThemeError> {
public func updateTheme(account: Account, accountManager: AccountManager, theme: TelegramTheme, title: String?, slug: String?, resource: MediaResource?, thumbnailData: Data? = nil, settings: TelegramThemeSettings?) -> Signal<CreateThemeResult, CreateThemeError> {
guard title != nil || slug != nil || resource != nil else {
return .complete()
}
@ -339,6 +347,10 @@ public func updateTheme(account: Account, accountManager: AccountManager, theme:
if let _ = resource {
flags |= 1 << 2
}
var inputSettings: Api.InputThemeSettings?
if let settings = settings {
flags |= 1 << 3
}
let uploadSignal: Signal<UploadThemeResult?, UploadThemeError>
if let resource = resource {
uploadSignal = uploadTheme(account: account, resource: resource, thumbnailData: thumbnailData)
@ -367,7 +379,7 @@ public func updateTheme(account: Account, accountManager: AccountManager, theme:
inputDocument = nil
}
return account.network.request(Api.functions.account.updateTheme(flags: flags, format: telegramThemeFormat, theme: .inputTheme(id: theme.id, accessHash: theme.accessHash), slug: slug, title: title, document: inputDocument))
return account.network.request(Api.functions.account.updateTheme(flags: flags, format: telegramThemeFormat, theme: .inputTheme(id: theme.id, accessHash: theme.accessHash), slug: slug, title: title, document: inputDocument, settings: nil))
|> mapError { error in
if error.errorDescription == "THEME_SLUG_INVALID" {
return .slugInvalid

View File

@ -8,21 +8,30 @@ import SyncCore
extension WallpaperSettings {
init(apiWallpaperSettings: Api.WallPaperSettings) {
switch apiWallpaperSettings {
case let .wallPaperSettings(flags, backgroundColor, intensity):
self = WallpaperSettings(blur: (flags & 1 << 1) != 0, motion: (flags & 1 << 2) != 0, color: backgroundColor, intensity: intensity)
case let .wallPaperSettings(flags, backgroundColor, secondBackgroundColor, intensity, rotation):
self = WallpaperSettings(blur: (flags & 1 << 1) != 0, motion: (flags & 1 << 2) != 0, color: backgroundColor, bottomColor: secondBackgroundColor, intensity: intensity, rotation: rotation)
}
}
}
func apiWallpaperSettings(_ wallpaperSettings: WallpaperSettings) -> Api.WallPaperSettings {
var flags: Int32 = 0
if let _ = wallpaperSettings.color {
flags |= (1 << 0)
}
if wallpaperSettings.blur {
flags |= (1 << 1)
}
if wallpaperSettings.motion {
flags |= (1 << 2)
}
return .wallPaperSettings(flags: flags, backgroundColor: wallpaperSettings.color, intensity: wallpaperSettings.intensity)
if let _ = wallpaperSettings.bottomColor {
flags |= (1 << 4)
}
if let _ = wallpaperSettings.rotation {
flags |= (1 << 4)
}
return .wallPaperSettings(flags: flags, backgroundColor: wallpaperSettings.color, secondBackgroundColor: wallpaperSettings.bottomColor, intensity: wallpaperSettings.intensity, rotation: wallpaperSettings.rotation)
}
extension TelegramWallpaper {
@ -41,6 +50,34 @@ extension TelegramWallpaper {
assertionFailure()
self = .color(0xffffff)
}
case let .wallPaperNoFile(flags, settings):
if let settings = settings, case let .wallPaperSettings(flags, backgroundColor, secondBackgroundColor, intensity, rotation) = settings {
if let color = backgroundColor, let bottomColor = secondBackgroundColor {
self = .gradient(color, bottomColor, WallpaperSettings(rotation: rotation))
} else if let color = backgroundColor {
self = .color(color)
} else {
self = .color(0xffffff)
}
} else {
self = .color(0xffffff)
}
}
}
var apiInputWallpaperAndSettings: (Api.InputWallPaper?, Api.WallPaperSettings)? {
switch self {
case .builtin:
return nil
case let .file(file):
return (.inputWallPaperSlug(slug: file.slug), apiWallpaperSettings(file.settings))
case let .color(color):
return (.inputWallPaperNoFile, apiWallpaperSettings(WallpaperSettings(color: color)))
case let .gradient(topColor, bottomColor, settings):
return (.inputWallPaperNoFile, apiWallpaperSettings(WallpaperSettings(color: topColor, bottomColor: bottomColor, rotation: settings.rotation)))
default:
return nil
}
}
}