mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-02 00:17:02 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
c546792fcd
@ -1244,6 +1244,25 @@ public struct StickersSearchConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
private extension PeerNameColors.Colors {
|
||||
init?(colors: EngineAvailableColorOptions.MultiColorPack) {
|
||||
if colors.colors.isEmpty {
|
||||
return nil
|
||||
}
|
||||
self.main = UIColor(rgb: colors.colors[0])
|
||||
if colors.colors.count > 1 {
|
||||
self.secondary = UIColor(rgb: colors.colors[1])
|
||||
} else {
|
||||
self.secondary = nil
|
||||
}
|
||||
if colors.colors.count > 2 {
|
||||
self.tertiary = UIColor(rgb: colors.colors[2])
|
||||
} else {
|
||||
self.tertiary = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PeerNameColors: Equatable {
|
||||
public struct Colors: Equatable {
|
||||
public let main: UIColor
|
||||
@ -1347,8 +1366,69 @@ public class PeerNameColors: Equatable {
|
||||
self.profileDisplayOrder = profileDisplayOrder
|
||||
}
|
||||
|
||||
public static func with(appConfiguration: AppConfiguration) -> PeerNameColors {
|
||||
if let data = appConfiguration.data {
|
||||
public static func with(availableReplyColors: EngineAvailableColorOptions, availableProfileColors: EngineAvailableColorOptions) -> PeerNameColors {
|
||||
var colors: [Int32: Colors] = [:]
|
||||
var darkColors: [Int32: Colors] = [:]
|
||||
var displayOrder: [Int32] = []
|
||||
var profileColors: [Int32: Colors] = [:]
|
||||
var profileDarkColors: [Int32: Colors] = [:]
|
||||
var profileDisplayOrder: [Int32] = []
|
||||
|
||||
if !availableReplyColors.options.isEmpty {
|
||||
for option in availableReplyColors.options {
|
||||
if let parsedLight = PeerNameColors.Colors(colors: option.value.light.background) {
|
||||
colors[option.key] = parsedLight
|
||||
}
|
||||
if let parsedDark = (option.value.dark?.background).flatMap(PeerNameColors.Colors.init(colors:)) {
|
||||
darkColors[option.key] = parsedDark
|
||||
}
|
||||
|
||||
//displayOrder.append(contentsOf: availableReplyColors.options.filter({ !$0.value.isHidden }).map(\.key))
|
||||
for option in availableReplyColors.options {
|
||||
if !displayOrder.contains(option.key) {
|
||||
displayOrder.append(option.key)
|
||||
}
|
||||
}
|
||||
/*for i in (0 ..< 7).reversed() {
|
||||
if !displayOrder.contains(Int32(i)) {
|
||||
displayOrder.insert(Int32(i), at: 0)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
} else {
|
||||
let defaultValue = PeerNameColors.defaultValue
|
||||
colors = defaultValue.colors
|
||||
darkColors = defaultValue.darkColors
|
||||
displayOrder = defaultValue.displayOrder
|
||||
}
|
||||
|
||||
if !availableProfileColors.options.isEmpty {
|
||||
for option in availableProfileColors.options {
|
||||
if let parsedLight = PeerNameColors.Colors(colors: option.value.light.background) {
|
||||
profileColors[option.key] = parsedLight
|
||||
}
|
||||
if let parsedDark = (option.value.dark?.background).flatMap(PeerNameColors.Colors.init(colors:)) {
|
||||
profileDarkColors[option.key] = parsedDark
|
||||
}
|
||||
for option in availableProfileColors.options {
|
||||
if !profileDisplayOrder.contains(option.key) {
|
||||
profileDisplayOrder.append(option.key)
|
||||
}
|
||||
}
|
||||
//profileDisplayOrder = availableProfileColors.options.filter({ !$0.value.isHidden }).map(\.key)
|
||||
}
|
||||
}
|
||||
|
||||
return PeerNameColors(
|
||||
colors: colors,
|
||||
darkColors: darkColors,
|
||||
displayOrder: displayOrder,
|
||||
profileColors: profileColors,
|
||||
profileDarkColors: profileDarkColors,
|
||||
profileDisplayOrder: profileDisplayOrder
|
||||
)
|
||||
|
||||
/*if let data = appConfiguration.data {
|
||||
var colors = PeerNameColors.defaultSingleColors
|
||||
var darkColors: [Int32: Colors] = [:]
|
||||
|
||||
@ -1463,7 +1543,7 @@ public class PeerNameColors: Equatable {
|
||||
)
|
||||
} else {
|
||||
return .defaultValue
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
public static func == (lhs: PeerNameColors, rhs: PeerNameColors) -> Bool {
|
||||
|
@ -1244,7 +1244,7 @@ public extension Api {
|
||||
return parser(reader)
|
||||
}
|
||||
else {
|
||||
telegramApiLog("Type constructor \(String(signature, radix: 16, uppercase: false)) not found")
|
||||
telegramApiLog("Type constructor \(String(UInt32(bitPattern: signature), radix: 16, uppercase: false)) not found")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +108,7 @@ final class AccountTaskManager {
|
||||
tasks.add(managedRecentReactions(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||
tasks.add(_internal_loadedStickerPack(postbox: self.stateManager.postbox, network: self.stateManager.network, reference: .iconStatusEmoji, forceActualized: true).start())
|
||||
tasks.add(_internal_loadedStickerPack(postbox: self.stateManager.postbox, network: self.stateManager.network, reference: .iconTopicEmoji, forceActualized: true).start())
|
||||
tasks.add(managedPeerColorUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||
|
||||
self.managedTopReactionsDisposable.set(managedTopReactions(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||
|
||||
|
@ -27,3 +27,5 @@ func managedGenericEmojiEffects(postbox: Postbox, network: Network) -> Signal<Vo
|
||||
}
|
||||
return (poll |> then(.complete() |> suspendAwareDelay(2.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,421 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import TelegramApi
|
||||
import MtProtoKit
|
||||
|
||||
public final class EngineAvailableColorOptions: Codable, Equatable {
|
||||
public final class MultiColorPack: Codable, Equatable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case colors = "c"
|
||||
}
|
||||
|
||||
public let colors: [UInt32]
|
||||
|
||||
public init(colors: [UInt32]) {
|
||||
self.colors = colors
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
self.colors = try container.decode([Int32].self, forKey: .colors).map(UInt32.init(bitPattern:))
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(self.colors.map(Int32.init(bitPattern:)), forKey: .colors)
|
||||
}
|
||||
|
||||
public static func ==(lhs: MultiColorPack, rhs: MultiColorPack) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
}
|
||||
if lhs.colors != rhs.colors {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
public final class ColorOption: Codable, Equatable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case palette = "p"
|
||||
case background = "b"
|
||||
case stories = "s"
|
||||
}
|
||||
|
||||
public let palette: MultiColorPack
|
||||
public let background: MultiColorPack
|
||||
public let stories: MultiColorPack?
|
||||
|
||||
public init(palette: MultiColorPack, background: MultiColorPack, stories: MultiColorPack?) {
|
||||
self.palette = palette
|
||||
self.background = background
|
||||
self.stories = stories
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
self.palette = try container.decode(MultiColorPack.self, forKey: .palette)
|
||||
self.background = try container.decode(MultiColorPack.self, forKey: .background)
|
||||
self.stories = try container.decodeIfPresent(MultiColorPack.self, forKey: .stories)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(self.palette, forKey: .palette)
|
||||
try container.encode(self.background, forKey: .background)
|
||||
try container.encodeIfPresent(self.stories, forKey: .stories)
|
||||
}
|
||||
|
||||
public static func ==(lhs: ColorOption, rhs: ColorOption) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
}
|
||||
if lhs.palette != rhs.palette {
|
||||
return false
|
||||
}
|
||||
if lhs.background != rhs.background {
|
||||
return false
|
||||
}
|
||||
if lhs.stories != rhs.stories {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
public final class ColorOptionPack: Codable, Equatable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case light = "l"
|
||||
case dark = "d"
|
||||
case isHidden = "h"
|
||||
}
|
||||
|
||||
public let light: ColorOption
|
||||
public let dark: ColorOption?
|
||||
public let isHidden: Bool
|
||||
|
||||
public init(light: ColorOption, dark: ColorOption?, isHidden: Bool) {
|
||||
self.light = light
|
||||
self.dark = dark
|
||||
self.isHidden = isHidden
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
self.light = try container.decode(ColorOption.self, forKey: .light)
|
||||
self.dark = try container.decodeIfPresent(ColorOption.self, forKey: .dark)
|
||||
self.isHidden = try container.decode(Bool.self, forKey: .isHidden)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(self.light, forKey: .light)
|
||||
try container.encodeIfPresent(self.dark, forKey: .dark)
|
||||
try container.encodeIfPresent(self.isHidden, forKey: .isHidden)
|
||||
}
|
||||
|
||||
public static func ==(lhs: ColorOptionPack, rhs: ColorOptionPack) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
}
|
||||
if lhs.light != rhs.light {
|
||||
return false
|
||||
}
|
||||
if lhs.dark != rhs.dark {
|
||||
return false
|
||||
}
|
||||
if lhs.isHidden != rhs.isHidden {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case hash = "h"
|
||||
case options = "o"
|
||||
}
|
||||
|
||||
public final class Option: Codable, Equatable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key = "k"
|
||||
case value = "v"
|
||||
}
|
||||
|
||||
public let key: Int32
|
||||
public let value: ColorOptionPack
|
||||
|
||||
public init(key: Int32, value: ColorOptionPack) {
|
||||
self.key = key
|
||||
self.value = value
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
self.key = try container.decode(Int32.self, forKey: .key)
|
||||
self.value = try container.decode(ColorOptionPack.self, forKey: .value)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(self.key, forKey: .key)
|
||||
try container.encode(self.value, forKey: .value)
|
||||
}
|
||||
|
||||
public static func ==(lhs: Option, rhs: Option) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
}
|
||||
if lhs.key != rhs.key {
|
||||
return false
|
||||
}
|
||||
if lhs.value != rhs.value {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
public let hash: Int32
|
||||
public let options: [Option]
|
||||
|
||||
public init(hash: Int32, options: [Option]) {
|
||||
self.hash = hash
|
||||
self.options = options
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.hash = try container.decode(Int32.self, forKey: .hash)
|
||||
self.options = try container.decode([Option].self, forKey: .options)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(self.hash, forKey: .hash)
|
||||
try container.encode(self.options, forKey: .options)
|
||||
}
|
||||
|
||||
public static func ==(lhs: EngineAvailableColorOptions, rhs: EngineAvailableColorOptions) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
}
|
||||
if lhs.hash != rhs.hash {
|
||||
return false
|
||||
}
|
||||
if lhs.options != rhs.options {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private extension EngineAvailableColorOptions.ColorOption {
|
||||
convenience init?(apiColors: [Int32]) {
|
||||
let palette: EngineAvailableColorOptions.MultiColorPack
|
||||
let background: EngineAvailableColorOptions.MultiColorPack
|
||||
let stories: EngineAvailableColorOptions.MultiColorPack?
|
||||
|
||||
if apiColors.count == 1 {
|
||||
palette = EngineAvailableColorOptions.MultiColorPack(colors: [
|
||||
UInt32(bitPattern: apiColors[0])
|
||||
])
|
||||
background = palette
|
||||
stories = nil
|
||||
} else if apiColors.count == 2 {
|
||||
palette = EngineAvailableColorOptions.MultiColorPack(colors: [
|
||||
UInt32(bitPattern: apiColors[0]),
|
||||
UInt32(bitPattern: apiColors[1])
|
||||
])
|
||||
background = palette
|
||||
stories = nil
|
||||
} else if apiColors.count == 3 {
|
||||
palette = EngineAvailableColorOptions.MultiColorPack(colors: [
|
||||
UInt32(bitPattern: apiColors[0]),
|
||||
UInt32(bitPattern: apiColors[1]),
|
||||
UInt32(bitPattern: apiColors[2])
|
||||
])
|
||||
background = palette
|
||||
stories = nil
|
||||
} else if apiColors.count == 4 {
|
||||
palette = EngineAvailableColorOptions.MultiColorPack(colors: [
|
||||
UInt32(bitPattern: apiColors[0])
|
||||
])
|
||||
background = EngineAvailableColorOptions.MultiColorPack(colors: [
|
||||
UInt32(bitPattern: apiColors[1])
|
||||
])
|
||||
stories = EngineAvailableColorOptions.MultiColorPack(colors: [
|
||||
UInt32(bitPattern: apiColors[2]),
|
||||
UInt32(bitPattern: apiColors[3])
|
||||
])
|
||||
} else if apiColors.count == 6 {
|
||||
palette = EngineAvailableColorOptions.MultiColorPack(colors: [
|
||||
UInt32(bitPattern: apiColors[0]),
|
||||
UInt32(bitPattern: apiColors[1])
|
||||
])
|
||||
background = EngineAvailableColorOptions.MultiColorPack(colors: [
|
||||
UInt32(bitPattern: apiColors[2]),
|
||||
UInt32(bitPattern: apiColors[3])
|
||||
])
|
||||
stories = EngineAvailableColorOptions.MultiColorPack(colors: [
|
||||
UInt32(bitPattern: apiColors[4]),
|
||||
UInt32(bitPattern: apiColors[5])
|
||||
])
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.init(palette: palette, background: background, stories: stories)
|
||||
}
|
||||
}
|
||||
|
||||
private extension EngineAvailableColorOptions {
|
||||
convenience init(hash: Int32, apiColors: [Api.help.PeerColorOption]) {
|
||||
var mappedOptions: [Option] = []
|
||||
for apiColor in apiColors {
|
||||
switch apiColor {
|
||||
case let .peerColorOption(flags, colorId, colors, darkColors):
|
||||
let isHidden = (flags & (1 << 0)) != 0
|
||||
let mappedColors = colors.flatMap(EngineAvailableColorOptions.ColorOption.init(apiColors:))
|
||||
let mappedDarkColors = darkColors.flatMap(EngineAvailableColorOptions.ColorOption.init(apiColors:))
|
||||
|
||||
if let mappedColors = mappedColors {
|
||||
mappedOptions.append(Option(key: colorId, value: ColorOptionPack(light: mappedColors, dark: mappedDarkColors, isHidden: isHidden)))
|
||||
} else if colorId >= 0 && colorId <= 6 {
|
||||
let staticMap: [UInt32] = [
|
||||
0xcc5049,
|
||||
0xd67722,
|
||||
0x955cdb,
|
||||
0x40a920,
|
||||
0x309eba,
|
||||
0x368ad1,
|
||||
0xc7508b
|
||||
]
|
||||
let colorPack = MultiColorPack(colors: [staticMap[Int(colorId)]])
|
||||
let defaultColors = EngineAvailableColorOptions.ColorOption(palette: colorPack, background: colorPack, stories: nil)
|
||||
mappedOptions.append(Option(key: colorId, value: ColorOptionPack(light: defaultColors, dark: nil, isHidden: isHidden)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.init(hash: hash, options: mappedOptions)
|
||||
}
|
||||
}
|
||||
|
||||
func managedPeerColorUpdates(postbox: Postbox, network: Network) -> Signal<Never, NoError> {
|
||||
let poll = combineLatest(
|
||||
_internal_fetchPeerColors(postbox: postbox, network: network, scope: .replies),
|
||||
_internal_fetchPeerColors(postbox: postbox, network: network, scope: .profile)
|
||||
)
|
||||
|> mapToSignal { _ -> Signal<Never, NoError> in
|
||||
}
|
||||
return (poll |> then(.complete() |> suspendAwareDelay(2.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
||||
}
|
||||
|
||||
public enum PeerColorsScope {
|
||||
case replies
|
||||
case profile
|
||||
}
|
||||
|
||||
private func _internal_fetchPeerColors(postbox: Postbox, network: Network, scope: PeerColorsScope) -> Signal<Never, NoError> {
|
||||
return postbox.transaction { transaction -> Int32 in
|
||||
#if DEBUG
|
||||
if "".isEmpty {
|
||||
return 0
|
||||
}
|
||||
#endif
|
||||
return _internal_cachedAvailableColorOptions(transaction: transaction, scope: scope).hash
|
||||
}
|
||||
|> mapToSignal { hash -> Signal<Never, NoError> in
|
||||
let signal: Signal<Api.help.PeerColors, MTRpcError>
|
||||
switch scope {
|
||||
case .replies:
|
||||
signal = network.request(Api.functions.help.getPeerColors(hash: hash))
|
||||
case .profile:
|
||||
signal = network.request(Api.functions.help.getPeerProfileColors(hash: hash))
|
||||
}
|
||||
|
||||
return signal
|
||||
|> `catch` { _ -> Signal<Api.help.PeerColors, NoError> in
|
||||
return .single(.peerColorsNotModified)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Never, NoError> in
|
||||
switch result {
|
||||
case .peerColorsNotModified:
|
||||
return .complete()
|
||||
case let .peerColors(hash, colors):
|
||||
return postbox.transaction { transaction -> Void in
|
||||
let value = EngineAvailableColorOptions(hash: hash, apiColors: colors)
|
||||
_internal_setCachedAvailableColorOptions(transaction: transaction, scope: scope, value: value)
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_cachedAvailableColorOptions(postbox: Postbox, scope: PeerColorsScope) -> Signal<EngineAvailableColorOptions, NoError> {
|
||||
return postbox.transaction { transaction -> EngineAvailableColorOptions in
|
||||
return _internal_cachedAvailableColorOptions(transaction: transaction, scope: scope)
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_observeAvailableColorOptions(postbox: Postbox, scope: PeerColorsScope) -> Signal<EngineAvailableColorOptions, NoError> {
|
||||
let key = ValueBoxKey(length: 8)
|
||||
switch scope {
|
||||
case .replies:
|
||||
key.setInt64(0, value: 0)
|
||||
case .profile:
|
||||
key.setInt64(0, value: 1)
|
||||
}
|
||||
let viewKey: PostboxViewKey = .cachedItem(ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.peerColorOptions, key: key))
|
||||
return postbox.combinedView(keys: [viewKey])
|
||||
|> map { views -> EngineAvailableColorOptions in
|
||||
guard let view = views.views[viewKey] as? CachedItemView, let value = view.value?.get(EngineAvailableColorOptions.self) else {
|
||||
return EngineAvailableColorOptions(hash: 0, options: [])
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_cachedAvailableColorOptions(transaction: Transaction, scope: PeerColorsScope) -> EngineAvailableColorOptions {
|
||||
let key = ValueBoxKey(length: 8)
|
||||
switch scope {
|
||||
case .replies:
|
||||
key.setInt64(0, value: 0)
|
||||
case .profile:
|
||||
key.setInt64(0, value: 1)
|
||||
}
|
||||
|
||||
let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.peerColorOptions, key: key))?.get(EngineAvailableColorOptions.self)
|
||||
if let cached = cached {
|
||||
return cached
|
||||
} else {
|
||||
return EngineAvailableColorOptions(hash: 0, options: [])
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_setCachedAvailableColorOptions(transaction: Transaction, scope: PeerColorsScope, value: EngineAvailableColorOptions) {
|
||||
let key = ValueBoxKey(length: 8)
|
||||
switch scope {
|
||||
case .replies:
|
||||
key.setInt64(0, value: 0)
|
||||
case .profile:
|
||||
key.setInt64(0, value: 1)
|
||||
}
|
||||
|
||||
if let entry = CodableEntry(value) {
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.peerColorOptions, key: key), entry: entry)
|
||||
}
|
||||
}
|
@ -114,6 +114,7 @@ public struct Namespaces {
|
||||
public static let cachedChannelBoosts: Int8 = 31
|
||||
public static let displayedMessageNotifications: Int8 = 32
|
||||
public static let recommendedChannels: Int8 = 33
|
||||
public static let peerColorOptions: Int8 = 34
|
||||
}
|
||||
|
||||
public struct UnorderedItemList {
|
||||
|
@ -35,6 +35,10 @@ public extension TelegramEngine {
|
||||
return _internal_updateAbout(account: self.account, about: about)
|
||||
}
|
||||
|
||||
public func observeAvailableColorOptions(scope: PeerColorsScope) -> Signal<EngineAvailableColorOptions, NoError> {
|
||||
return _internal_observeAvailableColorOptions(postbox: self.account.postbox, scope: scope)
|
||||
}
|
||||
|
||||
public func updateNameColorAndEmoji(nameColor: PeerNameColor, backgroundEmojiId: Int64?, profileColor: PeerNameColor?, profileBackgroundEmojiId: Int64?) -> Signal<Void, UpdateNameColorAndEmojiError> {
|
||||
return _internal_updateNameColorAndEmoji(account: self.account, nameColor: nameColor, backgroundEmojiId: backgroundEmojiId, profileColor: profileColor, profileBackgroundEmojiId: profileBackgroundEmojiId)
|
||||
}
|
||||
|
@ -523,5 +523,37 @@ public extension TelegramEngine.EngineData.Item {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
public struct AvailableColorOptions: TelegramEngineDataItem, PostboxViewDataItem {
|
||||
public typealias Result = EngineAvailableColorOptions
|
||||
|
||||
public let scope: PeerColorsScope
|
||||
|
||||
public init(scope: PeerColorsScope) {
|
||||
self.scope = scope
|
||||
}
|
||||
|
||||
var key: PostboxViewKey {
|
||||
let key = ValueBoxKey(length: 8)
|
||||
switch scope {
|
||||
case .replies:
|
||||
key.setInt64(0, value: 0)
|
||||
case .profile:
|
||||
key.setInt64(0, value: 1)
|
||||
}
|
||||
let viewKey: PostboxViewKey = .cachedItem(ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.peerColorOptions, key: key))
|
||||
return viewKey
|
||||
}
|
||||
|
||||
func extract(view: PostboxView) -> Result {
|
||||
guard let view = view as? CachedItemView else {
|
||||
preconditionFailure()
|
||||
}
|
||||
guard let value = view.value?.get(EngineAvailableColorOptions.self) else {
|
||||
return EngineAvailableColorOptions(hash: 0, options: [])
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ public final class AccountContextImpl: AccountContext {
|
||||
|
||||
public let imageCache: AnyObject?
|
||||
|
||||
public init(sharedContext: SharedAccountContextImpl, account: Account, limitsConfiguration: LimitsConfiguration, contentSettings: ContentSettings, appConfiguration: AppConfiguration, temp: Bool = false)
|
||||
public init(sharedContext: SharedAccountContextImpl, account: Account, limitsConfiguration: LimitsConfiguration, contentSettings: ContentSettings, appConfiguration: AppConfiguration, availableReplyColors: EngineAvailableColorOptions, availableProfileColors: EngineAvailableColorOptions, temp: Bool = false)
|
||||
{
|
||||
self.sharedContextImpl = sharedContext
|
||||
self.account = account
|
||||
@ -263,7 +263,7 @@ public final class AccountContextImpl: AccountContext {
|
||||
self.imageCache = DirectMediaImageCache(account: account)
|
||||
|
||||
self.userLimits = EngineConfiguration.UserLimits(UserLimitsConfiguration.defaultValue)
|
||||
self.peerNameColors = PeerNameColors.defaultValue
|
||||
self.peerNameColors = PeerNameColors.with(availableReplyColors: availableReplyColors, availableProfileColors: availableProfileColors)
|
||||
self.audioTranscriptionTrial = AudioTranscription.TrialState.defaultValue
|
||||
self.isPremium = false
|
||||
|
||||
@ -411,12 +411,15 @@ public final class AccountContextImpl: AccountContext {
|
||||
self.userLimits = userLimits
|
||||
})
|
||||
|
||||
self.peerNameColorsConfigurationDisposable = (self._appConfiguration.get()
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] appConfiguration in
|
||||
self.peerNameColorsConfigurationDisposable = (combineLatest(
|
||||
self.engine.accountData.observeAvailableColorOptions(scope: .replies),
|
||||
self.engine.accountData.observeAvailableColorOptions(scope: .profile)
|
||||
)
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] availableReplyColors, availableProfileColors in
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
self.peerNameColors = PeerNameColors.with(appConfiguration: appConfiguration)
|
||||
self.peerNameColors = PeerNameColors.with(availableReplyColors: availableReplyColors, availableProfileColors: availableProfileColors)
|
||||
})
|
||||
|
||||
self.audioTranscriptionTrialDisposable = (self.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: account.peerId))
|
||||
|
@ -59,6 +59,8 @@ private final class AccountUserInterfaceInUseContext {
|
||||
}
|
||||
}
|
||||
|
||||
typealias AccountInitialData = (limitsConfiguration: LimitsConfiguration?, contentSettings: ContentSettings?, appConfiguration: AppConfiguration?, availableReplyColors: EngineAvailableColorOptions, availableProfileColors: EngineAvailableColorOptions)
|
||||
|
||||
private struct AccountAttributes: Equatable {
|
||||
let sortIndex: Int32
|
||||
let isTestingEnvironment: Bool
|
||||
@ -67,12 +69,12 @@ private struct AccountAttributes: Equatable {
|
||||
|
||||
private enum AddedAccountResult {
|
||||
case upgrading(Float)
|
||||
case ready(AccountRecordId, Account?, Int32, LimitsConfiguration?, ContentSettings?, AppConfiguration?)
|
||||
case ready(AccountRecordId, Account?, Int32, AccountInitialData)
|
||||
}
|
||||
|
||||
private enum AddedAccountsResult {
|
||||
case upgrading(Float)
|
||||
case ready([(AccountRecordId, Account?, Int32, LimitsConfiguration?, ContentSettings?, AppConfiguration?)])
|
||||
case ready([(AccountRecordId, Account?, Int32, AccountInitialData)])
|
||||
}
|
||||
|
||||
private var testHasInstance = false
|
||||
@ -524,15 +526,17 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
return TelegramEngine(account: account).data.get(
|
||||
TelegramEngine.EngineData.Item.Configuration.Limits(),
|
||||
TelegramEngine.EngineData.Item.Configuration.ContentSettings(),
|
||||
TelegramEngine.EngineData.Item.Configuration.App()
|
||||
TelegramEngine.EngineData.Item.Configuration.App(),
|
||||
TelegramEngine.EngineData.Item.Configuration.AvailableColorOptions(scope: .replies),
|
||||
TelegramEngine.EngineData.Item.Configuration.AvailableColorOptions(scope: .profile)
|
||||
)
|
||||
|> map { limitsConfiguration, contentSettings, appConfiguration -> AddedAccountResult in
|
||||
return .ready(id, account, attributes.sortIndex, limitsConfiguration._asLimits(), contentSettings, appConfiguration)
|
||||
|> map { limitsConfiguration, contentSettings, appConfiguration, availableReplyColors, availableProfileColors -> AddedAccountResult in
|
||||
return .ready(id, account, attributes.sortIndex, (limitsConfiguration._asLimits(), contentSettings, appConfiguration, availableReplyColors, availableProfileColors))
|
||||
}
|
||||
case let .upgrading(progress):
|
||||
return .single(.upgrading(progress))
|
||||
default:
|
||||
return .single(.ready(id, nil, attributes.sortIndex, nil, nil, nil))
|
||||
return .single(.ready(id, nil, attributes.sortIndex, (nil, nil, nil, EngineAvailableColorOptions(hash: 0, options: []), EngineAvailableColorOptions(hash: 0, options: []))))
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -553,13 +557,13 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
|
||||
let mappedAddedAccounts = combineLatest(queue: .mainQueue(), addedSignals)
|
||||
|> map { results -> AddedAccountsResult in
|
||||
var readyAccounts: [(AccountRecordId, Account?, Int32, LimitsConfiguration?, ContentSettings?, AppConfiguration?)] = []
|
||||
var readyAccounts: [(AccountRecordId, Account?, Int32, AccountInitialData)] = []
|
||||
var totalProgress: Float = 0.0
|
||||
var hasItemsWithProgress = false
|
||||
for result in results {
|
||||
switch result {
|
||||
case let .ready(id, account, sortIndex, limitsConfiguration, contentSettings, appConfiguration):
|
||||
readyAccounts.append((id, account, sortIndex, limitsConfiguration, contentSettings, appConfiguration))
|
||||
case let .ready(id, account, sortIndex, initialData):
|
||||
readyAccounts.append((id, account, sortIndex, initialData))
|
||||
totalProgress += 1.0
|
||||
case let .upgrading(progress):
|
||||
hasItemsWithProgress = true
|
||||
@ -577,7 +581,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
|> deliverOnMainQueue).start(next: { mappedAddedAccounts, authAccount in
|
||||
print("SharedAccountContextImpl: accounts processed in \(CFAbsoluteTimeGetCurrent() - startTime)")
|
||||
|
||||
var addedAccounts: [(AccountRecordId, Account?, Int32, LimitsConfiguration?, ContentSettings?, AppConfiguration?)] = []
|
||||
var addedAccounts: [(AccountRecordId, Account?, Int32, AccountInitialData)] = []
|
||||
switch mappedAddedAccounts {
|
||||
case let .upgrading(progress):
|
||||
self.displayUpgradeProgress(progress)
|
||||
@ -616,7 +620,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
assertionFailure()
|
||||
}
|
||||
|
||||
let context = AccountContextImpl(sharedContext: self, account: account, limitsConfiguration: accountRecord.3 ?? .defaultValue, contentSettings: accountRecord.4 ?? .default, appConfiguration: accountRecord.5 ?? .defaultValue)
|
||||
let context = AccountContextImpl(sharedContext: self, account: account, limitsConfiguration: accountRecord.3.limitsConfiguration ?? .defaultValue, contentSettings: accountRecord.3.contentSettings ?? .default, appConfiguration: accountRecord.3.appConfiguration ?? .defaultValue, availableReplyColors: accountRecord.3.availableReplyColors, availableProfileColors: accountRecord.3.availableProfileColors)
|
||||
|
||||
self.activeAccountsValue!.accounts.append((account.id, context, accountRecord.2))
|
||||
|
||||
@ -1221,7 +1225,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
}
|
||||
|
||||
public func makeTempAccountContext(account: Account) -> AccountContext {
|
||||
return AccountContextImpl(sharedContext: self, account: account, limitsConfiguration: .defaultValue, contentSettings: .default, appConfiguration: .defaultValue, temp: true)
|
||||
return AccountContextImpl(sharedContext: self, account: account, limitsConfiguration: .defaultValue, contentSettings: .default, appConfiguration: .defaultValue, availableReplyColors: EngineAvailableColorOptions(hash: 0, options: []), availableProfileColors: EngineAvailableColorOptions(hash: 0, options: []), temp: true)
|
||||
}
|
||||
|
||||
public func openChatMessage(_ params: OpenChatMessageParams) -> Bool {
|
||||
|
Loading…
x
Reference in New Issue
Block a user