mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-01 10:50:51 +00:00
Merge commit 'e6ba681c030590e5fa095f9828610889abf08ef3'
This commit is contained in:
@@ -7,7 +7,7 @@ import TelegramApi
|
||||
extension WallpaperSettings {
|
||||
init(apiWallpaperSettings: Api.WallPaperSettings) {
|
||||
switch apiWallpaperSettings {
|
||||
case let .wallPaperSettings(flags, backgroundColor, secondBackgroundColor, thirdBackgroundColor, fourthBackgroundColor, intensity, rotation, _):
|
||||
case let .wallPaperSettings(flags, backgroundColor, secondBackgroundColor, thirdBackgroundColor, fourthBackgroundColor, intensity, rotation, emoticon):
|
||||
var colors: [UInt32] = []
|
||||
if let backgroundColor = backgroundColor {
|
||||
colors.append(UInt32(bitPattern: backgroundColor))
|
||||
@@ -21,7 +21,7 @@ extension WallpaperSettings {
|
||||
if let fourthBackgroundColor = fourthBackgroundColor {
|
||||
colors.append(UInt32(bitPattern: fourthBackgroundColor))
|
||||
}
|
||||
self = WallpaperSettings(blur: (flags & 1 << 1) != 0, motion: (flags & 1 << 2) != 0, colors: colors, intensity: intensity, rotation: rotation)
|
||||
self = WallpaperSettings(blur: (flags & 1 << 1) != 0, motion: (flags & 1 << 2) != 0, colors: colors, intensity: intensity, rotation: rotation, emoticon: emoticon)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,9 @@ func apiWallpaperSettings(_ wallpaperSettings: WallpaperSettings) -> Api.WallPap
|
||||
if let _ = wallpaperSettings.intensity {
|
||||
flags |= (1 << 3)
|
||||
}
|
||||
if let _ = wallpaperSettings.emoticon {
|
||||
flags |= (1 << 7)
|
||||
}
|
||||
var secondBackgroundColor: Int32?
|
||||
if wallpaperSettings.colors.count >= 2 {
|
||||
flags |= (1 << 4)
|
||||
@@ -57,7 +60,7 @@ func apiWallpaperSettings(_ wallpaperSettings: WallpaperSettings) -> Api.WallPap
|
||||
flags |= (1 << 6)
|
||||
fourthBackgroundColor = Int32(bitPattern: wallpaperSettings.colors[3])
|
||||
}
|
||||
return .wallPaperSettings(flags: flags, backgroundColor: backgroundColor, secondBackgroundColor: secondBackgroundColor, thirdBackgroundColor: thirdBackgroundColor, fourthBackgroundColor: fourthBackgroundColor, intensity: wallpaperSettings.intensity, rotation: wallpaperSettings.rotation ?? 0, emoticon: nil)
|
||||
return .wallPaperSettings(flags: flags, backgroundColor: backgroundColor, secondBackgroundColor: secondBackgroundColor, thirdBackgroundColor: thirdBackgroundColor, fourthBackgroundColor: fourthBackgroundColor, intensity: wallpaperSettings.intensity, rotation: wallpaperSettings.rotation ?? 0, emoticon: wallpaperSettings.emoticon)
|
||||
}
|
||||
|
||||
extension TelegramWallpaper {
|
||||
@@ -77,7 +80,11 @@ extension TelegramWallpaper {
|
||||
self = .color(0xffffff)
|
||||
}
|
||||
case let .wallPaperNoFile(id, _, settings):
|
||||
if let settings = settings, case let .wallPaperSettings(_, backgroundColor, secondBackgroundColor, thirdBackgroundColor, fourthBackgroundColor, _, rotation, _) = settings {
|
||||
if let settings = settings, case let .wallPaperSettings(_, backgroundColor, secondBackgroundColor, thirdBackgroundColor, fourthBackgroundColor, _, rotation, emoticon) = settings {
|
||||
if id == 0, let emoticon = emoticon {
|
||||
self = .emoticon(emoticon)
|
||||
return
|
||||
}
|
||||
let colors: [UInt32] = ([backgroundColor, secondBackgroundColor, thirdBackgroundColor, fourthBackgroundColor] as [Int32?]).compactMap({ color -> UInt32? in
|
||||
return color.flatMap(UInt32.init(bitPattern:))
|
||||
})
|
||||
@@ -105,6 +112,8 @@ extension TelegramWallpaper {
|
||||
return (.inputWallPaperNoFile(id: 0), apiWallpaperSettings(WallpaperSettings(colors: [color])))
|
||||
case let .gradient(gradient):
|
||||
return (.inputWallPaperNoFile(id: gradient.id ?? 0), apiWallpaperSettings(WallpaperSettings(colors: gradient.colors, rotation: gradient.settings.rotation)))
|
||||
case let .emoticon(emoticon):
|
||||
return (.inputWallPaperNoFile(id: 0), apiWallpaperSettings(WallpaperSettings(emoticon: emoticon)))
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ public enum ServerProvidedSuggestion: String {
|
||||
case upgradePremium = "PREMIUM_UPGRADE"
|
||||
case annualPremium = "PREMIUM_ANNUAL"
|
||||
case restorePremium = "PREMIUM_RESTORE"
|
||||
case xmasPremiumGift = "PREMIUM_CHRISTMAS"
|
||||
}
|
||||
|
||||
private var dismissedSuggestionsPromise = ValuePromise<[AccountRecordId: Set<ServerProvidedSuggestion>]>([:])
|
||||
|
||||
@@ -6,13 +6,15 @@ public struct WallpaperSettings: Codable, Equatable {
|
||||
public var colors: [UInt32]
|
||||
public var intensity: Int32?
|
||||
public var rotation: Int32?
|
||||
public var emoticon: String?
|
||||
|
||||
public init(blur: Bool = false, motion: Bool = false, colors: [UInt32] = [], intensity: Int32? = nil, rotation: Int32? = nil) {
|
||||
public init(blur: Bool = false, motion: Bool = false, colors: [UInt32] = [], intensity: Int32? = nil, rotation: Int32? = nil, emoticon: String? = nil) {
|
||||
self.blur = blur
|
||||
self.motion = motion
|
||||
self.colors = colors
|
||||
self.intensity = intensity
|
||||
self.rotation = rotation
|
||||
self.emoticon = emoticon
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
@@ -32,6 +34,7 @@ public struct WallpaperSettings: Codable, Equatable {
|
||||
|
||||
self.intensity = try container.decodeIfPresent(Int32.self, forKey: "i")
|
||||
self.rotation = try container.decodeIfPresent(Int32.self, forKey: "r")
|
||||
self.emoticon = try container.decodeIfPresent(String.self, forKey: "e")
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@@ -42,6 +45,7 @@ public struct WallpaperSettings: Codable, Equatable {
|
||||
try container.encode(self.colors.map(Int32.init(bitPattern:)), forKey: "colors")
|
||||
try container.encodeIfPresent(self.intensity, forKey: "i")
|
||||
try container.encodeIfPresent(self.rotation, forKey: "r")
|
||||
try container.encodeIfPresent(self.emoticon, forKey: "e")
|
||||
}
|
||||
|
||||
public static func ==(lhs: WallpaperSettings, rhs: WallpaperSettings) -> Bool {
|
||||
@@ -60,6 +64,9 @@ public struct WallpaperSettings: Codable, Equatable {
|
||||
if lhs.rotation != rhs.rotation {
|
||||
return false
|
||||
}
|
||||
if lhs.emoticon != rhs.emoticon {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -73,7 +80,7 @@ public struct TelegramWallpaperNativeCodable: Codable {
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||
|
||||
|
||||
switch try container.decode(Int32.self, forKey: "v") {
|
||||
case 0:
|
||||
let settings = try container.decode(WallpaperSettings.self, forKey: "settings")
|
||||
@@ -106,9 +113,9 @@ public struct TelegramWallpaperNativeCodable: Codable {
|
||||
}
|
||||
case 4:
|
||||
let settings = try container.decode(WallpaperSettings.self, forKey: "settings")
|
||||
|
||||
|
||||
var colors: [UInt32] = []
|
||||
|
||||
|
||||
if let topColor = (try container.decodeIfPresent(Int32.self, forKey: "c1")).flatMap(UInt32.init(bitPattern:)) {
|
||||
colors.append(topColor)
|
||||
if let bottomColor = (try container.decodeIfPresent(Int32.self, forKey: "c2")).flatMap(UInt32.init(bitPattern:)) {
|
||||
@@ -117,12 +124,14 @@ public struct TelegramWallpaperNativeCodable: Codable {
|
||||
} else {
|
||||
colors = (try container.decode([Int32].self, forKey: "colors")).map(UInt32.init(bitPattern:))
|
||||
}
|
||||
|
||||
|
||||
self.value = .gradient(TelegramWallpaper.Gradient(
|
||||
id: try container.decodeIfPresent(Int64.self, forKey: "id"),
|
||||
colors: colors,
|
||||
settings: settings
|
||||
))
|
||||
case 5:
|
||||
self.value = .emoticon(try container.decode(String.self, forKey: "e"))
|
||||
default:
|
||||
assertionFailure()
|
||||
self.value = .color(0xffffff)
|
||||
@@ -131,41 +140,48 @@ public struct TelegramWallpaperNativeCodable: Codable {
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||
|
||||
|
||||
switch self.value {
|
||||
case let .builtin(settings):
|
||||
try container.encode(0 as Int32, forKey: "v")
|
||||
try container.encode(settings, forKey: "settings")
|
||||
case let .color(color):
|
||||
try container.encode(1 as Int32, forKey: "v")
|
||||
try container.encode(Int32(bitPattern: color), forKey: "c")
|
||||
case let .gradient(gradient):
|
||||
try container.encode(4 as Int32, forKey: "v")
|
||||
try container.encodeIfPresent(gradient.id, forKey: "id")
|
||||
try container.encode(gradient.colors.map(Int32.init(bitPattern:)), forKey: "colors")
|
||||
try container.encode(gradient.settings, forKey: "settings")
|
||||
case let .image(representations, settings):
|
||||
try container.encode(2 as Int32, forKey: "v")
|
||||
try container.encode(representations.map { item in
|
||||
return PostboxEncoder().encodeObjectToRawData(item)
|
||||
}, forKey: "i")
|
||||
try container.encode(settings, forKey: "settings")
|
||||
case let .file(file):
|
||||
try container.encode(3 as Int32, forKey: "v")
|
||||
try container.encode(file.id, forKey: "id")
|
||||
try container.encode(file.accessHash, forKey: "accessHash")
|
||||
try container.encode((file.isCreator ? 1 : 0) as Int32, forKey: "isCreator")
|
||||
try container.encode((file.isDefault ? 1 : 0) as Int32, forKey: "isDefault")
|
||||
try container.encode((file.isPattern ? 1 : 0) as Int32, forKey: "isPattern")
|
||||
try container.encode((file.isDark ? 1 : 0) as Int32, forKey: "isDark")
|
||||
try container.encode(file.slug, forKey: "slug")
|
||||
try container.encode(PostboxEncoder().encodeObjectToRawData(file.file), forKey: "file")
|
||||
try container.encode(file.settings, forKey: "settings")
|
||||
case let .builtin(settings):
|
||||
try container.encode(0 as Int32, forKey: "v")
|
||||
try container.encode(settings, forKey: "settings")
|
||||
case let .color(color):
|
||||
try container.encode(1 as Int32, forKey: "v")
|
||||
try container.encode(Int32(bitPattern: color), forKey: "c")
|
||||
case let .gradient(gradient):
|
||||
try container.encode(4 as Int32, forKey: "v")
|
||||
try container.encodeIfPresent(gradient.id, forKey: "id")
|
||||
try container.encode(gradient.colors.map(Int32.init(bitPattern:)), forKey: "colors")
|
||||
try container.encode(gradient.settings, forKey: "settings")
|
||||
case let .image(representations, settings):
|
||||
try container.encode(2 as Int32, forKey: "v")
|
||||
try container.encode(representations.map { item in
|
||||
return PostboxEncoder().encodeObjectToRawData(item)
|
||||
}, forKey: "i")
|
||||
try container.encode(settings, forKey: "settings")
|
||||
case let .file(file):
|
||||
try container.encode(3 as Int32, forKey: "v")
|
||||
try container.encode(file.id, forKey: "id")
|
||||
try container.encode(file.accessHash, forKey: "accessHash")
|
||||
try container.encode((file.isCreator ? 1 : 0) as Int32, forKey: "isCreator")
|
||||
try container.encode((file.isDefault ? 1 : 0) as Int32, forKey: "isDefault")
|
||||
try container.encode((file.isPattern ? 1 : 0) as Int32, forKey: "isPattern")
|
||||
try container.encode((file.isDark ? 1 : 0) as Int32, forKey: "isDark")
|
||||
try container.encode(file.slug, forKey: "slug")
|
||||
try container.encode(PostboxEncoder().encodeObjectToRawData(file.file), forKey: "file")
|
||||
try container.encode(file.settings, forKey: "settings")
|
||||
case let .emoticon(emoticon):
|
||||
try container.encode(5 as Int32, forKey: "v")
|
||||
try container.encode(emoticon, forKey: "e")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum TelegramWallpaper: Equatable {
|
||||
public static func emoticonWallpaper(emoticon: String) -> TelegramWallpaper {
|
||||
return .file(File(id: -1, accessHash: -1, isCreator: false, isDefault: false, isPattern: false, isDark: false, slug: "", file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: EmptyMediaResource(), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "", size: nil, attributes: []), settings: WallpaperSettings(emoticon: emoticon)))
|
||||
}
|
||||
|
||||
public struct Gradient: Equatable {
|
||||
public var id: Int64?
|
||||
public var colors: [UInt32]
|
||||
@@ -221,6 +237,7 @@ public enum TelegramWallpaper: Equatable {
|
||||
case gradient(Gradient)
|
||||
case image([TelegramMediaImageRepresentation], WallpaperSettings)
|
||||
case file(File)
|
||||
case emoticon(String)
|
||||
|
||||
public var hasWallpaper: Bool {
|
||||
switch self {
|
||||
@@ -263,6 +280,12 @@ public enum TelegramWallpaper: Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .emoticon(emoticon):
|
||||
if case .emoticon(emoticon) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,6 +321,12 @@ public enum TelegramWallpaper: Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .emoticon(emoticon):
|
||||
if case .emoticon(emoticon) = wallpaper {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,6 +357,8 @@ public enum TelegramWallpaper: Equatable {
|
||||
case var .file(file):
|
||||
file.settings = settings
|
||||
return .file(file)
|
||||
case .emoticon:
|
||||
return self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ public final class EngineStoryViewListContext {
|
||||
let sortMode = self.sortMode
|
||||
let searchQuery = self.searchQuery
|
||||
let currentOffset = state.nextOffset
|
||||
let limit = state.items.isEmpty ? 50 : 100
|
||||
let limit = 50
|
||||
|
||||
let signal: Signal<InternalState, NoError>
|
||||
|
||||
@@ -662,6 +662,9 @@ public final class EngineStoryViewListContext {
|
||||
}
|
||||
|
||||
var flags: Int32 = 0
|
||||
if let _ = currentOffset {
|
||||
flags |= (1 << 1)
|
||||
}
|
||||
if case .repostsFirst = sortMode {
|
||||
flags |= (1 << 2)
|
||||
}
|
||||
@@ -887,4 +890,3 @@ public final class EngineStoryViewListContext {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,11 @@ public enum GetMessagesStrategy {
|
||||
case cloud(skipLocal: Bool)
|
||||
}
|
||||
|
||||
func _internal_getMessagesLoadIfNecessary(_ messageIds: [MessageId], postbox: Postbox, network: Network, accountPeerId: PeerId, strategy: GetMessagesStrategy = .cloud(skipLocal: false)) -> Signal<GetMessagesResult, NoError> {
|
||||
public enum GetMessagesError {
|
||||
case privateChannel
|
||||
}
|
||||
|
||||
func _internal_getMessagesLoadIfNecessary(_ messageIds: [MessageId], postbox: Postbox, network: Network, accountPeerId: PeerId, strategy: GetMessagesStrategy = .cloud(skipLocal: false)) -> Signal<GetMessagesResult, GetMessagesError> {
|
||||
let postboxSignal = postbox.transaction { transaction -> ([Message], Set<MessageId>, SimpleDictionary<PeerId, Peer>) in
|
||||
var ids = messageIds
|
||||
|
||||
@@ -50,8 +54,9 @@ func _internal_getMessagesLoadIfNecessary(_ messageIds: [MessageId], postbox: Po
|
||||
|
||||
if case .cloud = strategy {
|
||||
return postboxSignal
|
||||
|> castError(GetMessagesError.self)
|
||||
|> mapToSignal { (existMessages, missingMessageIds, supportPeers) in
|
||||
var signals: [Signal<(Peer, [Api.Message], [Api.Chat], [Api.User]), NoError>] = []
|
||||
var signals: [Signal<(Peer, [Api.Message], [Api.Chat], [Api.User]), GetMessagesError>] = []
|
||||
for (peerId, messageIds) in messagesIdsGroupedByPeerId(missingMessageIds) {
|
||||
if let peer = supportPeers[peerId] {
|
||||
var signal: Signal<Api.messages.Messages, MTRpcError>?
|
||||
@@ -75,14 +80,20 @@ func _internal_getMessagesLoadIfNecessary(_ messageIds: [MessageId], postbox: Po
|
||||
case .messagesNotModified:
|
||||
return (peer, [], [], [])
|
||||
}
|
||||
} |> `catch` { _ in
|
||||
return Signal<(Peer, [Api.Message], [Api.Chat], [Api.User]), NoError>.single((peer, [], [], []))
|
||||
} |> `catch` { error in
|
||||
if error.errorDescription == "CHANNEL_PRIVATE" {
|
||||
return .fail(.privateChannel)
|
||||
} else {
|
||||
return Signal<(Peer, [Api.Message], [Api.Chat], [Api.User]), GetMessagesError>.single((peer, [], [], []))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return .single(.progress) |> then(combineLatest(signals) |> mapToSignal { results -> Signal<GetMessagesResult, NoError> in
|
||||
return .single(.progress)
|
||||
|> castError(GetMessagesError.self)
|
||||
|> then(combineLatest(signals) |> mapToSignal { results -> Signal<GetMessagesResult, GetMessagesError> in
|
||||
return postbox.transaction { transaction -> GetMessagesResult in
|
||||
for (peer, messages, chats, users) in results {
|
||||
if !messages.isEmpty {
|
||||
@@ -108,10 +119,12 @@ func _internal_getMessagesLoadIfNecessary(_ messageIds: [MessageId], postbox: Po
|
||||
|
||||
return .result(existMessages + loadedMessages)
|
||||
}
|
||||
|> castError(GetMessagesError.self)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
return postboxSignal
|
||||
|> castError(GetMessagesError.self)
|
||||
|> map {
|
||||
return .result($0.0)
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ public extension TelegramEngine {
|
||||
return _internal_markAllChatsAsRead(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager)
|
||||
}
|
||||
|
||||
public func getMessagesLoadIfNecessary(_ messageIds: [MessageId], strategy: GetMessagesStrategy = .cloud(skipLocal: false)) -> Signal<GetMessagesResult, NoError> {
|
||||
public func getMessagesLoadIfNecessary(_ messageIds: [MessageId], strategy: GetMessagesStrategy = .cloud(skipLocal: false)) -> Signal<GetMessagesResult, GetMessagesError> {
|
||||
return _internal_getMessagesLoadIfNecessary(messageIds, postbox: self.account.postbox, network: self.account.network, accountPeerId: self.account.peerId, strategy: strategy)
|
||||
}
|
||||
|
||||
|
||||
@@ -134,6 +134,8 @@ func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager
|
||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
||||
if let current = current as? CachedUserData {
|
||||
return current.withUpdatedWallpaper(wallpaper)
|
||||
} else if let current = current as? CachedChannelData {
|
||||
return current.withUpdatedWallpaper(wallpaper)
|
||||
} else {
|
||||
return current
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user