mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-08-11 16:40:22 +02:00
Update Ghostgram features
This commit is contained in:
@@ -482,12 +482,6 @@ private class AdMessagesHistoryContextImpl {
|
||||
}
|
||||
self.isActivated = true
|
||||
|
||||
// MISC: Block ads if setting enabled
|
||||
if MiscSettingsManager.shared.shouldBlockAds {
|
||||
self.stateValue = State(interPostInterval: nil, startDelay: nil, betweenDelay: nil, messages: [])
|
||||
return
|
||||
}
|
||||
|
||||
let peerId = self.peerId
|
||||
let accountPeerId = self.account.peerId
|
||||
let account = self.account
|
||||
@@ -516,7 +510,8 @@ private class AdMessagesHistoryContextImpl {
|
||||
|
||||
return account.postbox.transaction { transaction -> (interPostInterval: Int32?, startDelay: Int32?, betweenDelay: Int32?, messages: [Message]) in
|
||||
switch result {
|
||||
case let .sponsoredMessages(_, postsBetween, startDelay, betweenDelay, messages, chats, users):
|
||||
case let .sponsoredMessages(sponsoredMessagesData):
|
||||
let (postsBetween, startDelay, betweenDelay, messages, chats, users) = (sponsoredMessagesData.postsBetween, sponsoredMessagesData.startDelay, sponsoredMessagesData.betweenDelay, sponsoredMessagesData.messages, sponsoredMessagesData.chats, sponsoredMessagesData.users)
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
||||
|
||||
@@ -524,7 +519,8 @@ private class AdMessagesHistoryContextImpl {
|
||||
|
||||
for message in messages {
|
||||
switch message {
|
||||
case let .sponsoredMessage(flags, randomId, url, title, message, entities, photo, media, color, buttonText, sponsorInfo, additionalInfo, minDisplayDuration, maxDisplayDuration):
|
||||
case let .sponsoredMessage(sponsoredMessageData):
|
||||
let (flags, randomId, url, title, message, entities, apiPhoto, media, color, buttonText, sponsorInfo, additionalInfo, minDisplayDuration, maxDisplayDuration) = (sponsoredMessageData.flags, sponsoredMessageData.randomId, sponsoredMessageData.url, sponsoredMessageData.title, sponsoredMessageData.message, sponsoredMessageData.entities, sponsoredMessageData.photo, sponsoredMessageData.media, sponsoredMessageData.color, sponsoredMessageData.buttonText, sponsoredMessageData.sponsorInfo, sponsoredMessageData.additionalInfo, sponsoredMessageData.minDisplayDuration, sponsoredMessageData.maxDisplayDuration)
|
||||
var parsedEntities: [MessageTextEntity] = []
|
||||
if let entities = entities {
|
||||
parsedEntities = messageTextEntitiesFromApiEntities(entities)
|
||||
@@ -537,7 +533,8 @@ private class AdMessagesHistoryContextImpl {
|
||||
var backgroundEmojiId: Int64?
|
||||
if let color {
|
||||
switch color {
|
||||
case let .peerColor(_, color, backgroundEmojiIdValue):
|
||||
case let .peerColor(peerColorData):
|
||||
let (color, backgroundEmojiIdValue) = (peerColorData.color, peerColorData.backgroundEmojiId)
|
||||
nameColorIndex = color
|
||||
backgroundEmojiId = backgroundEmojiIdValue
|
||||
default:
|
||||
@@ -545,7 +542,7 @@ private class AdMessagesHistoryContextImpl {
|
||||
}
|
||||
}
|
||||
|
||||
let photo = photo.flatMap { telegramMediaImageFromApiPhoto($0) }
|
||||
let photo = apiPhoto.flatMap { telegramMediaImageFromApiPhoto($0) }
|
||||
let contentMedia = textMediaAndExpirationTimerFromApiMedia(media, peerId).media
|
||||
|
||||
parsedMessages.append(CachedMessage(
|
||||
|
||||
+1
-2
@@ -64,7 +64,6 @@ func _internal_applyMaxReadIndexInteractively(transaction: Transaction, stateMan
|
||||
}
|
||||
}
|
||||
} else if index.id.peerId.namespace == Namespaces.Peer.CloudUser || index.id.peerId.namespace == Namespaces.Peer.CloudGroup || index.id.peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
// GHOST MODE: Don't send read receipts (blue checkmarks)
|
||||
if !GhostModeManager.shared.shouldHideReadReceipts {
|
||||
stateManager.notifyAppliedIncomingReadMessages([index.id])
|
||||
}
|
||||
@@ -167,7 +166,7 @@ func _internal_toggleForumThreadUnreadMarkInteractively(transaction: Transaction
|
||||
if peer.isForum {
|
||||
} else if peer.isMonoForum {
|
||||
if let inputPeer = apiInputPeer(peer), let subPeer = transaction.getPeer(PeerId(threadId)).flatMap(apiInputPeer) {
|
||||
let _ = network.request(Api.functions.messages.markDialogUnread(flags: 1 << 0, parentPeer: inputPeer, peer: .inputDialogPeer(peer: subPeer))).start()
|
||||
let _ = network.request(Api.functions.messages.markDialogUnread(flags: 1 << 0, parentPeer: inputPeer, peer: .inputDialogPeer(.init(peer: subPeer)))).start()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -298,17 +298,20 @@ func managedSynchronizeAttachMenuBots(accountPeerId: PeerId, postbox: Postbox, n
|
||||
}
|
||||
return postbox.transaction { transaction -> Void in
|
||||
switch result {
|
||||
case let .attachMenuBots(hash, bots, users):
|
||||
case let .attachMenuBots(attachMenuBotsData):
|
||||
let (hash, bots, users) = (attachMenuBotsData.hash, attachMenuBotsData.bots, attachMenuBotsData.users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: AccumulatedPeers(users: users))
|
||||
|
||||
var resultBots: [AttachMenuBots.Bot] = []
|
||||
for bot in bots {
|
||||
switch bot {
|
||||
case let .attachMenuBot(apiFlags, botId, name, apiPeerTypes, botIcons):
|
||||
case let .attachMenuBot(attachMenuBotData):
|
||||
let (apiFlags, botId, name, apiPeerTypes, botIcons) = (attachMenuBotData.flags, attachMenuBotData.botId, attachMenuBotData.shortName, attachMenuBotData.peerTypes, attachMenuBotData.icons)
|
||||
var icons: [AttachMenuBots.Bot.IconName: TelegramMediaFile] = [:]
|
||||
for icon in botIcons {
|
||||
switch icon {
|
||||
case let .attachMenuBotIcon(_, name, icon, _):
|
||||
case let .attachMenuBotIcon(attachMenuBotIconData):
|
||||
let (_, name, icon, _) = (attachMenuBotIconData.flags, attachMenuBotIconData.name, attachMenuBotIconData.icon, attachMenuBotIconData.colors)
|
||||
if let iconName = AttachMenuBots.Bot.IconName(string: name), let icon = telegramMediaFileFromApiDocument(icon, altDocuments: []) {
|
||||
icons[iconName] = icon
|
||||
}
|
||||
@@ -524,7 +527,8 @@ func _internal_getAttachMenuBot(accountPeerId: PeerId, postbox: Postbox, network
|
||||
|> mapToSignal { result -> Signal<AttachMenuBot, GetAttachMenuBotError> in
|
||||
return postbox.transaction { transaction -> Signal<AttachMenuBot, GetAttachMenuBotError> in
|
||||
switch result {
|
||||
case let .attachMenuBotsBot(bot, users):
|
||||
case let .attachMenuBotsBot(attachMenuBotsBotData):
|
||||
let (bot, users) = (attachMenuBotsBotData.bot, attachMenuBotsBotData.users)
|
||||
var peer: Peer?
|
||||
for user in users {
|
||||
let telegramUser = TelegramUser(user: user)
|
||||
@@ -539,11 +543,13 @@ func _internal_getAttachMenuBot(accountPeerId: PeerId, postbox: Postbox, network
|
||||
}
|
||||
|
||||
switch bot {
|
||||
case let .attachMenuBot(apiFlags, _, name, apiPeerTypes, botIcons):
|
||||
case let .attachMenuBot(attachMenuBotData):
|
||||
let (apiFlags, _, name, apiPeerTypes, botIcons) = (attachMenuBotData.flags, attachMenuBotData.botId, attachMenuBotData.shortName, attachMenuBotData.peerTypes, attachMenuBotData.icons)
|
||||
var icons: [AttachMenuBots.Bot.IconName: TelegramMediaFile] = [:]
|
||||
for icon in botIcons {
|
||||
switch icon {
|
||||
case let .attachMenuBotIcon(_, name, icon, _):
|
||||
case let .attachMenuBotIcon(attachMenuBotIconData):
|
||||
let (_, name, icon, _) = (attachMenuBotIconData.flags, attachMenuBotIconData.name, attachMenuBotIconData.icon, attachMenuBotIconData.colors)
|
||||
if let iconName = AttachMenuBots.Bot.IconName(string: name), let icon = telegramMediaFileFromApiDocument(icon, altDocuments: []) {
|
||||
icons[iconName] = icon
|
||||
}
|
||||
@@ -727,12 +733,12 @@ func _internal_getBotApp(account: Account, reference: BotAppReference) -> Signal
|
||||
let app: Api.InputBotApp
|
||||
switch reference {
|
||||
case let .id(id, accessHash):
|
||||
app = .inputBotAppID(id: id, accessHash: accessHash)
|
||||
app = .inputBotAppID(.init(id: id, accessHash: accessHash))
|
||||
case let .shortName(peerId, shortName):
|
||||
guard let bot = transaction.getPeer(peerId), let inputBot = apiInputUser(bot) else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
app = .inputBotAppShortName(botId: inputBot, shortName: shortName)
|
||||
app = .inputBotAppShortName(.init(botId: inputBot, shortName: shortName))
|
||||
}
|
||||
|
||||
return account.network.request(Api.functions.messages.getBotApp(app: app, hash: 0))
|
||||
@@ -741,9 +747,11 @@ func _internal_getBotApp(account: Account, reference: BotAppReference) -> Signal
|
||||
}
|
||||
|> mapToSignal { result -> Signal<BotApp, GetBotAppError> in
|
||||
switch result {
|
||||
case let .botApp(botAppFlags, app):
|
||||
case let .botApp(botAppData):
|
||||
let (botAppFlags, app) = (botAppData.flags, botAppData.app)
|
||||
switch app {
|
||||
case let .botApp(flags, id, accessHash, shortName, title, description, photo, document, hash):
|
||||
case let .botApp(botAppData):
|
||||
let (flags, id, accessHash, shortName, title, description, photo, document, hash) = (botAppData.flags, botAppData.id, botAppData.accessHash, botAppData.shortName, botAppData.title, botAppData.description, botAppData.photo, botAppData.document, botAppData.hash)
|
||||
let _ = flags
|
||||
var appFlags = BotApp.Flags()
|
||||
if (botAppFlags & (1 << 0)) != 0 {
|
||||
@@ -769,7 +777,8 @@ func _internal_getBotApp(account: Account, reference: BotAppReference) -> Signal
|
||||
extension BotApp {
|
||||
convenience init?(apiBotApp: Api.BotApp) {
|
||||
switch apiBotApp {
|
||||
case let .botApp(_, id, accessHash, shortName, title, description, photo, document, hash):
|
||||
case let .botApp(botAppData):
|
||||
let (id, accessHash, shortName, title, description, photo, document, hash) = (botAppData.id, botAppData.accessHash, botAppData.shortName, botAppData.title, botAppData.description, botAppData.photo, botAppData.document, botAppData.hash)
|
||||
self.init(id: id, accessHash: accessHash, shortName: shortName, title: title, description: description, photo: telegramMediaImageFromApiPhoto(photo), document: document.flatMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }, hash: hash, flags: [])
|
||||
case .botAppNotModified:
|
||||
return nil
|
||||
|
||||
@@ -19,7 +19,7 @@ public enum RequestSimpleWebViewSource : Equatable {
|
||||
func _internal_requestSimpleWebView(postbox: Postbox, network: Network, botId: PeerId, url: String?, source: RequestSimpleWebViewSource, themeParams: [String: Any]?) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
var serializedThemeParams: Api.DataJSON?
|
||||
if let themeParams = themeParams, let data = try? JSONSerialization.data(withJSONObject: themeParams, options: []), let dataString = String(data: data, encoding: .utf8) {
|
||||
serializedThemeParams = .dataJSON(data: dataString)
|
||||
serializedThemeParams = .dataJSON(.init(data: dataString))
|
||||
}
|
||||
return postbox.transaction { transaction -> Signal<RequestWebViewResult, RequestWebViewError> in
|
||||
guard let bot = transaction.getPeer(botId), let inputUser = apiInputUser(bot) else {
|
||||
@@ -51,7 +51,8 @@ func _internal_requestSimpleWebView(postbox: Postbox, network: Network, botId: P
|
||||
}
|
||||
|> mapToSignal { result -> Signal<RequestWebViewResult, RequestWebViewError> in
|
||||
switch result {
|
||||
case let .webViewResultUrl(flags, queryId, url):
|
||||
case let .webViewResultUrl(webViewResultUrlData):
|
||||
let (flags, queryId, url) = (webViewResultUrlData.flags, webViewResultUrlData.queryId, webViewResultUrlData.url)
|
||||
var resultFlags: RequestWebViewResult.Flags = []
|
||||
if (flags & (1 << 1)) != 0 {
|
||||
resultFlags.insert(.fullSize)
|
||||
@@ -70,7 +71,7 @@ func _internal_requestSimpleWebView(postbox: Postbox, network: Network, botId: P
|
||||
func _internal_requestMainWebView(postbox: Postbox, network: Network, peerId: PeerId, botId: PeerId, source: RequestSimpleWebViewSource, themeParams: [String: Any]?) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
var serializedThemeParams: Api.DataJSON?
|
||||
if let themeParams = themeParams, let data = try? JSONSerialization.data(withJSONObject: themeParams, options: []), let dataString = String(data: data, encoding: .utf8) {
|
||||
serializedThemeParams = .dataJSON(data: dataString)
|
||||
serializedThemeParams = .dataJSON(.init(data: dataString))
|
||||
}
|
||||
return postbox.transaction { transaction -> Signal<RequestWebViewResult, RequestWebViewError> in
|
||||
guard let bot = transaction.getPeer(botId), let inputUser = apiInputUser(bot) else {
|
||||
@@ -101,7 +102,8 @@ func _internal_requestMainWebView(postbox: Postbox, network: Network, peerId: Pe
|
||||
}
|
||||
|> mapToSignal { result -> Signal<RequestWebViewResult, RequestWebViewError> in
|
||||
switch result {
|
||||
case let .webViewResultUrl(flags, queryId, url):
|
||||
case let .webViewResultUrl(webViewResultUrlData):
|
||||
let (flags, queryId, url) = (webViewResultUrlData.flags, webViewResultUrlData.queryId, webViewResultUrlData.url)
|
||||
var resultFlags: RequestWebViewResult.Flags = []
|
||||
if (flags & (1 << 1)) != 0 {
|
||||
resultFlags.insert(.fullSize)
|
||||
@@ -160,7 +162,7 @@ private func keepWebViewSignal(network: Network, stateManager: AccountStateManag
|
||||
replyFlags |= 1 << 0
|
||||
topMsgId = Int32(clamping: threadId)
|
||||
}
|
||||
replyTo = .inputReplyToMessage(flags: replyFlags, replyToMsgId: replyToMessageId.id, topMsgId: topMsgId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil, monoforumPeerId: monoforumPeerId, todoItemId: nil)
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyToMessageId.id, topMsgId: topMsgId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil, monoforumPeerId: monoforumPeerId, todoItemId: nil))
|
||||
}
|
||||
let signal: Signal<Never, KeepWebViewError> = network.request(Api.functions.messages.prolongWebView(flags: flags, peer: peer, bot: bot, queryId: queryId, replyTo: replyTo, sendAs: sendAs))
|
||||
|> mapError { _ -> KeepWebViewError in
|
||||
@@ -204,7 +206,7 @@ private func keepWebViewSignal(network: Network, stateManager: AccountStateManag
|
||||
func _internal_requestWebView(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, botId: PeerId, url: String?, payload: String?, themeParams: [String: Any]?, fromMenu: Bool, replyToMessageId: MessageId?, threadId: Int64?) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
var serializedThemeParams: Api.DataJSON?
|
||||
if let themeParams = themeParams, let data = try? JSONSerialization.data(withJSONObject: themeParams, options: []), let dataString = String(data: data, encoding: .utf8) {
|
||||
serializedThemeParams = .dataJSON(data: dataString)
|
||||
serializedThemeParams = .dataJSON(.init(data: dataString))
|
||||
}
|
||||
|
||||
return postbox.transaction { transaction -> Signal<RequestWebViewResult, RequestWebViewError> in
|
||||
@@ -248,9 +250,9 @@ func _internal_requestWebView(postbox: Postbox, network: Network, stateManager:
|
||||
} else if topMsgId != nil {
|
||||
replyFlags |= 1 << 0
|
||||
}
|
||||
replyTo = .inputReplyToMessage(flags: replyFlags, replyToMsgId: replyToMessageId.id, topMsgId: topMsgId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil, monoforumPeerId: monoforumPeerId, todoItemId: nil)
|
||||
replyTo = .inputReplyToMessage(.init(flags: replyFlags, replyToMsgId: replyToMessageId.id, topMsgId: topMsgId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil, monoforumPeerId: monoforumPeerId, todoItemId: nil))
|
||||
} else if let monoforumPeerId {
|
||||
replyTo = .inputReplyToMonoForum(monoforumPeerId: monoforumPeerId)
|
||||
replyTo = .inputReplyToMonoForum(.init(monoforumPeerId: monoforumPeerId))
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.requestWebView(flags: flags, peer: inputPeer, bot: inputBot, url: url, startParam: payload, themeParams: serializedThemeParams, platform: botWebViewPlatform, replyTo: replyTo, sendAs: nil))
|
||||
@@ -259,7 +261,8 @@ func _internal_requestWebView(postbox: Postbox, network: Network, stateManager:
|
||||
}
|
||||
|> mapToSignal { result -> Signal<RequestWebViewResult, RequestWebViewError> in
|
||||
switch result {
|
||||
case let .webViewResultUrl(webViewFlags, queryId, url):
|
||||
case let .webViewResultUrl(webViewResultUrlData):
|
||||
let (webViewFlags, queryId, url) = (webViewResultUrlData.flags, webViewResultUrlData.queryId, webViewResultUrlData.url)
|
||||
var resultFlags: RequestWebViewResult.Flags = []
|
||||
if (webViewFlags & (1 << 1)) != 0 {
|
||||
resultFlags.insert(.fullSize)
|
||||
@@ -273,7 +276,7 @@ func _internal_requestWebView(postbox: Postbox, network: Network, stateManager:
|
||||
} else {
|
||||
keepAlive = nil
|
||||
}
|
||||
|
||||
|
||||
return .single(RequestWebViewResult(flags: resultFlags, queryId: queryId, url: url, keepAliveSignal: keepAlive))
|
||||
}
|
||||
}
|
||||
@@ -309,7 +312,7 @@ func _internal_sendWebViewData(postbox: Postbox, network: Network, stateManager:
|
||||
func _internal_requestAppWebView(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, appReference: BotAppReference, payload: String?, themeParams: [String: Any]?, compact: Bool, fullscreen: Bool, allowWrite: Bool) -> Signal<RequestWebViewResult, RequestWebViewError> {
|
||||
var serializedThemeParams: Api.DataJSON?
|
||||
if let themeParams = themeParams, let data = try? JSONSerialization.data(withJSONObject: themeParams, options: []), let dataString = String(data: data, encoding: .utf8) {
|
||||
serializedThemeParams = .dataJSON(data: dataString)
|
||||
serializedThemeParams = .dataJSON(.init(data: dataString))
|
||||
}
|
||||
|
||||
return postbox.transaction { transaction -> Signal<RequestWebViewResult, RequestWebViewError> in
|
||||
@@ -320,12 +323,12 @@ func _internal_requestAppWebView(postbox: Postbox, network: Network, stateManage
|
||||
let app: Api.InputBotApp
|
||||
switch appReference {
|
||||
case let .id(id, accessHash):
|
||||
app = .inputBotAppID(id: id, accessHash: accessHash)
|
||||
app = .inputBotAppID(.init(id: id, accessHash: accessHash))
|
||||
case let .shortName(peerId, shortName):
|
||||
guard let bot = transaction.getPeer(peerId), let inputBot = apiInputUser(bot) else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
app = .inputBotAppShortName(botId: inputBot, shortName: shortName)
|
||||
app = .inputBotAppShortName(.init(botId: inputBot, shortName: shortName))
|
||||
}
|
||||
|
||||
var flags: Int32 = 0
|
||||
@@ -351,7 +354,8 @@ func _internal_requestAppWebView(postbox: Postbox, network: Network, stateManage
|
||||
}
|
||||
|> mapToSignal { result -> Signal<RequestWebViewResult, RequestWebViewError> in
|
||||
switch result {
|
||||
case let .webViewResultUrl(flags, queryId, url):
|
||||
case let .webViewResultUrl(webViewResultUrlData):
|
||||
let (flags, queryId, url) = (webViewResultUrlData.flags, webViewResultUrlData.queryId, webViewResultUrlData.url)
|
||||
var resultFlags: RequestWebViewResult.Flags = []
|
||||
if (flags & (1 << 1)) != 0 {
|
||||
resultFlags.insert(.fullSize)
|
||||
@@ -415,7 +419,7 @@ public enum InvokeBotCustomMethodError {
|
||||
}
|
||||
|
||||
func _internal_invokeBotCustomMethod(postbox: Postbox, network: Network, botId: PeerId, method: String, params: String) -> Signal<String, InvokeBotCustomMethodError> {
|
||||
let params = Api.DataJSON.dataJSON(data: params)
|
||||
let params = Api.DataJSON.dataJSON(.init(data: params))
|
||||
return postbox.transaction { transaction -> Signal<String, InvokeBotCustomMethodError> in
|
||||
guard let bot = transaction.getPeer(botId), let inputUser = apiInputUser(bot) else {
|
||||
return .fail(.generic)
|
||||
@@ -425,7 +429,8 @@ func _internal_invokeBotCustomMethod(postbox: Postbox, network: Network, botId:
|
||||
return .generic
|
||||
}
|
||||
|> map { result -> String in
|
||||
if case let .dataJSON(data) = result {
|
||||
if case let .dataJSON(dataJSONData) = result {
|
||||
let data = dataJSONData.data
|
||||
return data
|
||||
} else {
|
||||
return ""
|
||||
@@ -1164,13 +1169,15 @@ fileprivate func _internal_requestConnectedStarRefBots(account: Account, id: En
|
||||
}
|
||||
return account.postbox.transaction { transaction -> (items: [EngineConnectedStarRefBotsContext.Item], totalCount: Int, nextOffset: (timestamp: Int32, link: String)?)? in
|
||||
switch result {
|
||||
case let .connectedStarRefBots(count, connectedBots, users):
|
||||
case let .connectedStarRefBots(connectedStarRefBotsData):
|
||||
let (count, connectedBots, users) = (connectedStarRefBotsData.count, connectedStarRefBotsData.connectedBots, connectedStarRefBotsData.users)
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: AccumulatedPeers(users: users))
|
||||
|
||||
var items: [EngineConnectedStarRefBotsContext.Item] = []
|
||||
for connectedBot in connectedBots {
|
||||
switch connectedBot {
|
||||
case let .connectedBotStarRef(_, url, date, botId, commissionPermille, durationMonths, participants, revenue):
|
||||
case let .connectedBotStarRef(connectedBotStarRefData):
|
||||
let (url, date, botId, commissionPermille, durationMonths, participants, revenue) = (connectedBotStarRefData.url, connectedBotStarRefData.date, connectedBotStarRefData.botId, connectedBotStarRefData.commissionPermille, connectedBotStarRefData.durationMonths, connectedBotStarRefData.participants, connectedBotStarRefData.revenue)
|
||||
guard let botPeer = transaction.getPeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId))) else {
|
||||
continue
|
||||
}
|
||||
@@ -1233,7 +1240,8 @@ fileprivate func _internal_requestSuggestedStarRefBots(account: Account, id: Eng
|
||||
}
|
||||
return account.postbox.transaction { transaction -> (items: [EngineSuggestedStarRefBotsContext.Item], totalCount: Int, nextOffset: String?)? in
|
||||
switch result {
|
||||
case let .suggestedStarRefBots(_, count, suggestedBots, users, nextOffset):
|
||||
case let .suggestedStarRefBots(suggestedStarRefBotsData):
|
||||
let (count, suggestedBots, users, nextOffset) = (suggestedStarRefBotsData.count, suggestedStarRefBotsData.suggestedBots, suggestedStarRefBotsData.users, suggestedStarRefBotsData.nextOffset)
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: AccumulatedPeers(users: users))
|
||||
|
||||
var items: [EngineSuggestedStarRefBotsContext.Item] = []
|
||||
@@ -1278,12 +1286,14 @@ func _internal_connectStarRefBot(account: Account, id: EnginePeer.Id, botId: Eng
|
||||
|> mapToSignal { result -> Signal<EngineConnectedStarRefBotsContext.Item, ConnectStarRefBotError> in
|
||||
return account.postbox.transaction { transaction -> EngineConnectedStarRefBotsContext.Item? in
|
||||
switch result {
|
||||
case let .connectedStarRefBots(_, connectedBots, users):
|
||||
case let .connectedStarRefBots(connectedStarRefBotsData):
|
||||
let (connectedBots, users) = (connectedStarRefBotsData.connectedBots, connectedStarRefBotsData.users)
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: AccumulatedPeers(users: users))
|
||||
|
||||
|
||||
if let bot = connectedBots.first {
|
||||
switch bot {
|
||||
case let .connectedBotStarRef(_, url, date, botId, commissionPermille, durationMonths, participants, revenue):
|
||||
case let .connectedBotStarRef(connectedBotStarRefData):
|
||||
let (url, date, botId, commissionPermille, durationMonths, participants, revenue) = (connectedBotStarRefData.url, connectedBotStarRefData.date, connectedBotStarRefData.botId, connectedBotStarRefData.commissionPermille, connectedBotStarRefData.durationMonths, connectedBotStarRefData.participants, connectedBotStarRefData.revenue)
|
||||
guard let botPeer = transaction.getPeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId))) else {
|
||||
return nil
|
||||
}
|
||||
@@ -1333,9 +1343,10 @@ fileprivate func _internal_removeConnectedStarRefBot(account: Account, id: Engin
|
||||
|> mapToSignal { result -> Signal<Never, ConnectStarRefBotError> in
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
switch result {
|
||||
case let .connectedStarRefBots(_, connectedBots, users):
|
||||
case let .connectedStarRefBots(connectedStarRefBotsData):
|
||||
let (connectedBots, users) = (connectedStarRefBotsData.connectedBots, connectedStarRefBotsData.users)
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: AccumulatedPeers(users: users))
|
||||
|
||||
|
||||
let _ = connectedBots
|
||||
}
|
||||
|
||||
@@ -1369,12 +1380,14 @@ func _internal_getStarRefBotConnection(account: Account, id: EnginePeer.Id, targ
|
||||
}
|
||||
return account.postbox.transaction { transaction -> EngineConnectedStarRefBotsContext.Item? in
|
||||
switch result {
|
||||
case let .connectedStarRefBots(_, connectedBots, users):
|
||||
case let .connectedStarRefBots(connectedStarRefBotsData):
|
||||
let (connectedBots, users) = (connectedStarRefBotsData.connectedBots, connectedStarRefBotsData.users)
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: AccumulatedPeers(users: users))
|
||||
|
||||
|
||||
if let bot = connectedBots.first {
|
||||
switch bot {
|
||||
case let .connectedBotStarRef(flags, url, date, botId, commissionPermille, durationMonths, participants, revenue):
|
||||
case let .connectedBotStarRef(connectedBotStarRefData):
|
||||
let (flags, url, date, botId, commissionPermille, durationMonths, participants, revenue) = (connectedBotStarRefData.flags, connectedBotStarRefData.url, connectedBotStarRefData.date, connectedBotStarRefData.botId, connectedBotStarRefData.commissionPermille, connectedBotStarRefData.durationMonths, connectedBotStarRefData.participants, connectedBotStarRefData.revenue)
|
||||
let isRevoked = (flags & (1 << 1)) != 0
|
||||
if isRevoked {
|
||||
return nil
|
||||
@@ -1431,9 +1444,19 @@ func _internal_getPossibleStarRefBotTargets(account: Account) -> Signal<[EngineP
|
||||
|
||||
if let apiChannels {
|
||||
switch apiChannels {
|
||||
case let .chats(chats), let .chatsSlice(_, chats):
|
||||
case let .chats(chatsData):
|
||||
let chats = chatsData.chats
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: AccumulatedPeers(chats: chats, users: []))
|
||||
|
||||
|
||||
for chat in chats {
|
||||
if let peer = transaction.getPeer(chat.peerId) {
|
||||
result.append(EnginePeer(peer))
|
||||
}
|
||||
}
|
||||
case let .chatsSlice(chatsSliceData):
|
||||
let chats = chatsSliceData.chats
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: AccumulatedPeers(chats: chats, users: []))
|
||||
|
||||
for chat in chats {
|
||||
if let peer = transaction.getPeer(chat.peerId) {
|
||||
result.append(EnginePeer(peer))
|
||||
|
||||
@@ -15,12 +15,14 @@ func _internal_clearCloudDraftsInteractively(postbox: Postbox, network: Network,
|
||||
}
|
||||
var keys = Set<Key>()
|
||||
switch updates {
|
||||
case let .updates(updates, users, chats, _, _):
|
||||
case let .updates(updatesData):
|
||||
let (updates, users, chats) = (updatesData.updates, updatesData.users, updatesData.chats)
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||
|
||||
|
||||
for update in updates {
|
||||
switch update {
|
||||
case let .updateDraftMessage(_, peer, topMsgId, savedPeerId, _):
|
||||
case let .updateDraftMessage(updateDraftMessageData):
|
||||
let (peer, topMsgId, savedPeerId) = (updateDraftMessageData.peer, updateDraftMessageData.topMsgId, updateDraftMessageData.savedPeerId)
|
||||
var threadId: Int64?
|
||||
if let savedPeerId {
|
||||
threadId = savedPeerId.peerId.toInt64()
|
||||
@@ -55,10 +57,10 @@ func _internal_clearCloudDraftsInteractively(postbox: Postbox, network: Network,
|
||||
|
||||
var innerFlags: Int32 = 0
|
||||
innerFlags |= 1 << 0
|
||||
replyTo = .inputReplyToMessage(flags: innerFlags, replyToMsgId: 0, topMsgId: topMsgId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil, monoforumPeerId: nil, todoItemId: nil)
|
||||
replyTo = .inputReplyToMessage(.init(flags: innerFlags, replyToMsgId: 0, topMsgId: topMsgId, replyToPeerId: nil, quoteText: nil, quoteEntities: nil, quoteOffset: nil, monoforumPeerId: nil, todoItemId: nil))
|
||||
} else if let monoforumPeerId {
|
||||
flags |= (1 << 0)
|
||||
replyTo = .inputReplyToMonoForum(monoforumPeerId: monoforumPeerId)
|
||||
replyTo = .inputReplyToMonoForum(.init(monoforumPeerId: monoforumPeerId))
|
||||
}
|
||||
signals.append(network.request(Api.functions.messages.saveDraft(flags: flags, replyTo: replyTo, peer: inputPeer, message: "", entities: nil, media: nil, effect: nil, suggestedPost: nil))
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
|
||||
@@ -129,7 +129,8 @@ func _internal_clearCallHistory(account: Account, forEveryone: Bool) -> Signal<N
|
||||
|> mapToSignal { result -> Signal<Void, Bool> in
|
||||
if let result = result {
|
||||
switch result {
|
||||
case let .affectedFoundMessages(pts, ptsCount, offset, _):
|
||||
case let .affectedFoundMessages(affectedFoundMessagesData):
|
||||
let (pts, ptsCount, offset) = (affectedFoundMessagesData.pts, affectedFoundMessagesData.ptsCount, affectedFoundMessagesData.offset)
|
||||
account.stateManager.addUpdateGroups([.updatePts(pts: pts, ptsCount: ptsCount)])
|
||||
if offset == 0 {
|
||||
return .fail(true)
|
||||
|
||||
+2
-1
@@ -219,7 +219,8 @@ func _internal_clearAuthorHistory(account: Account, peerId: PeerId, memberId: Pe
|
||||
|> mapToSignal { result -> Signal<Void, Bool> in
|
||||
if let result = result {
|
||||
switch result {
|
||||
case let .affectedHistory(pts, ptsCount, offset):
|
||||
case let .affectedHistory(affectedHistoryData):
|
||||
let (pts, ptsCount, offset) = (affectedHistoryData.pts, affectedHistoryData.ptsCount, affectedHistoryData.offset)
|
||||
account.stateManager.addUpdateGroups([.updatePts(pts: pts, ptsCount: ptsCount)])
|
||||
if offset == 0 {
|
||||
return .fail(true)
|
||||
|
||||
+17
-9
@@ -465,17 +465,19 @@ public final class EngineStoryViewListContext {
|
||||
|> mapToSignal { result -> Signal<InternalState, NoError> in
|
||||
return account.postbox.transaction { transaction -> InternalState in
|
||||
switch result {
|
||||
case let .storyViewsList(_, count, viewsCount, forwardsCount, reactionsCount, views, chats, users, nextOffset):
|
||||
case let .storyViewsList(storyViewsListData):
|
||||
let (count, viewsCount, forwardsCount, reactionsCount, views, chats, users, nextOffset) = (storyViewsListData.count, storyViewsListData.viewsCount, storyViewsListData.forwardsCount, storyViewsListData.reactionsCount, storyViewsListData.views, storyViewsListData.chats, storyViewsListData.users, storyViewsListData.nextOffset)
|
||||
let peers = AccumulatedPeers(chats: chats, users: users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: peers)
|
||||
|
||||
var items: [Item] = []
|
||||
for view in views {
|
||||
switch view {
|
||||
case let .storyView(flags, userId, date, reaction):
|
||||
case let .storyView(storyViewData):
|
||||
let (flags, userId, date, reaction) = (storyViewData.flags, storyViewData.userId, storyViewData.date, storyViewData.reaction)
|
||||
let isBlocked = (flags & (1 << 0)) != 0
|
||||
let isBlockedFromStories = (flags & (1 << 1)) != 0
|
||||
|
||||
|
||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))
|
||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData in
|
||||
let previousData: CachedUserData
|
||||
@@ -511,7 +513,8 @@ public final class EngineStoryViewListContext {
|
||||
}
|
||||
)))
|
||||
}
|
||||
case let .storyViewPublicForward(flags, message):
|
||||
case let .storyViewPublicForward(storyViewPublicForwardData):
|
||||
let (flags, message) = (storyViewPublicForwardData.flags, storyViewPublicForwardData.message)
|
||||
let _ = flags
|
||||
if let storeMessage = StoreMessage(apiMessage: message, accountPeerId: accountPeerId, peerIsForum: false), let message = locallyRenderedMessage(message: storeMessage, peers: peers.peers) {
|
||||
items.append(.forward(Item.Forward(
|
||||
@@ -519,7 +522,8 @@ public final class EngineStoryViewListContext {
|
||||
storyStats: transaction.getPeerStoryStats(peerId: message.id.peerId)
|
||||
)))
|
||||
}
|
||||
case let .storyViewPublicRepost(flags, peerId, story):
|
||||
case let .storyViewPublicRepost(storyViewPublicRepostData):
|
||||
let (flags, peerId, story) = (storyViewPublicRepostData.flags, storyViewPublicRepostData.peerId, storyViewPublicRepostData.story)
|
||||
let _ = flags
|
||||
if let peer = transaction.getPeer(peerId.peerId) {
|
||||
if let storedItem = Stories.StoredItem(apiStoryItem: story, peerId: peer.id, transaction: transaction), case let .item(item) = storedItem, let media = item.media {
|
||||
@@ -685,14 +689,16 @@ public final class EngineStoryViewListContext {
|
||||
|> mapToSignal { result -> Signal<InternalState, NoError> in
|
||||
return account.postbox.transaction { transaction -> InternalState in
|
||||
switch result {
|
||||
case let .storyReactionsList(_, count, reactions, chats, users, nextOffset):
|
||||
case let .storyReactionsList(storyReactionsListData):
|
||||
let (count, reactions, chats, users, nextOffset) = (storyReactionsListData.count, storyReactionsListData.reactions, storyReactionsListData.chats, storyReactionsListData.users, storyReactionsListData.nextOffset)
|
||||
let peers = AccumulatedPeers(chats: chats, users: users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: peers)
|
||||
|
||||
var items: [Item] = []
|
||||
for reaction in reactions {
|
||||
switch reaction {
|
||||
case let .storyReaction(peerId, date, reaction):
|
||||
case let .storyReaction(storyReactionData):
|
||||
let (peerId, date, reaction) = (storyReactionData.peerId, storyReactionData.date, storyReactionData.reaction)
|
||||
if let peer = transaction.getPeer(peerId.peerId) {
|
||||
if let parsedReaction = MessageReaction.Reaction(apiReaction: reaction) {
|
||||
let reactionFile: TelegramMediaFile?
|
||||
@@ -713,14 +719,16 @@ public final class EngineStoryViewListContext {
|
||||
)))
|
||||
}
|
||||
}
|
||||
case let .storyReactionPublicForward(message):
|
||||
case let .storyReactionPublicForward(storyReactionPublicForwardData):
|
||||
let message = storyReactionPublicForwardData.message
|
||||
if let storeMessage = StoreMessage(apiMessage: message, accountPeerId: accountPeerId, peerIsForum: false), let message = locallyRenderedMessage(message: storeMessage, peers: peers.peers) {
|
||||
items.append(.forward(Item.Forward(
|
||||
message: EngineMessage(message),
|
||||
storyStats: transaction.getPeerStoryStats(peerId: message.id.peerId)
|
||||
)))
|
||||
}
|
||||
case let .storyReactionPublicRepost(peerId, story):
|
||||
case let .storyReactionPublicRepost(storyReactionPublicRepostData):
|
||||
let (peerId, story) = (storyReactionPublicRepostData.peerId, storyReactionPublicRepostData.story)
|
||||
if let peer = transaction.getPeer(peerId.peerId) {
|
||||
if let storedItem = Stories.StoredItem(apiStoryItem: story, peerId: peer.id, transaction: transaction), case let .item(item) = storedItem, let media = item.media {
|
||||
items.append(.repost(Item.Repost(
|
||||
|
||||
@@ -25,7 +25,8 @@ public func _internal_exportMessageLink(postbox: Postbox, network: Network, peer
|
||||
return network.request(Api.functions.channels.exportMessageLink(flags: flags, channel: input, id: sourceMessageId.id)) |> mapError { _ in return }
|
||||
|> map { res in
|
||||
switch res {
|
||||
case let .exportedMessageLink(link, _):
|
||||
case let .exportedMessageLink(exportedMessageLinkData):
|
||||
let (link, _) = (exportedMessageLinkData.link, exportedMessageLinkData.html)
|
||||
return link
|
||||
}
|
||||
} |> `catch` { _ -> Signal<String?, NoError> in
|
||||
|
||||
@@ -16,10 +16,10 @@ func _internal_editMessageFactCheck(account: Account, messageId: EngineMessage.I
|
||||
return account.network.request(Api.functions.messages.editFactCheck(
|
||||
peer: inputPeer,
|
||||
msgId: messageId.id,
|
||||
text: .textWithEntities(
|
||||
text: .textWithEntities(.init(
|
||||
text: text,
|
||||
entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary())
|
||||
)
|
||||
))
|
||||
))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
@@ -96,11 +96,13 @@ func _internal_getMessagesFactCheckByPeerId(account: Account, peerId: EnginePeer
|
||||
for result in results {
|
||||
let messageId = messageIds[index]
|
||||
switch result {
|
||||
case let .factCheck(_, country, text, hash):
|
||||
case let .factCheck(factCheckData):
|
||||
let (_, country, text, hash) = (factCheckData.flags, factCheckData.country, factCheckData.text, factCheckData.hash)
|
||||
let content: FactCheckMessageAttribute.Content
|
||||
if let text, let country {
|
||||
switch text {
|
||||
case let .textWithEntities(text, entities):
|
||||
case let .textWithEntities(textWithEntitiesData):
|
||||
let (text, entities) = (textWithEntitiesData.text, textWithEntitiesData.entities)
|
||||
content = .Loaded(text: text, entities: messageTextEntitiesFromApiEntities(entities), country: country)
|
||||
}
|
||||
} else {
|
||||
|
||||
+8
-5
@@ -61,20 +61,23 @@ func _internal_getMessagesLoadIfNecessary(_ messageIds: [MessageId], postbox: Po
|
||||
if let peer = supportPeers[peerId] {
|
||||
var signal: Signal<Api.messages.Messages, MTRpcError>?
|
||||
if peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||
signal = network.request(Api.functions.messages.getMessages(id: messageIds.map({ Api.InputMessage.inputMessageID(id: $0.id) })))
|
||||
signal = network.request(Api.functions.messages.getMessages(id: messageIds.map({ Api.InputMessage.inputMessageID(.init(id: $0.id)) })))
|
||||
} else if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if let inputChannel = apiInputChannel(peer) {
|
||||
signal = network.request(Api.functions.channels.getMessages(channel: inputChannel, id: messageIds.map({ Api.InputMessage.inputMessageID(id: $0.id) })))
|
||||
signal = network.request(Api.functions.channels.getMessages(channel: inputChannel, id: messageIds.map({ Api.InputMessage.inputMessageID(.init(id: $0.id)) })))
|
||||
}
|
||||
}
|
||||
if let signal = signal {
|
||||
signals.append(signal |> map { result in
|
||||
switch result {
|
||||
case let .messages(messages, _, chats, users):
|
||||
case let .messages(messagesData):
|
||||
let (messages, _, chats, users) = (messagesData.messages, messagesData.topics, messagesData.chats, messagesData.users)
|
||||
return (peer, messages, chats, users)
|
||||
case let .messagesSlice(_, _, _, _, _, messages, _, chats, users):
|
||||
case let .messagesSlice(messagesSliceData):
|
||||
let (_, _, _, _, _, messages, _, chats, users) = (messagesSliceData.flags, messagesSliceData.count, messagesSliceData.nextRate, messagesSliceData.offsetIdOffset, messagesSliceData.searchFlood, messagesSliceData.messages, messagesSliceData.topics, messagesSliceData.chats, messagesSliceData.users)
|
||||
return (peer, messages, chats, users)
|
||||
case let .channelMessages(_, _, _, _, messages, apiTopics, chats, users):
|
||||
case let .channelMessages(channelMessagesData):
|
||||
let (_, _, _, _, messages, apiTopics, chats, users) = (channelMessagesData.flags, channelMessagesData.pts, channelMessagesData.count, channelMessagesData.offsetIdOffset, channelMessagesData.messages, channelMessagesData.topics, channelMessagesData.chats, channelMessagesData.users)
|
||||
let _ = apiTopics
|
||||
return (peer, messages, chats, users)
|
||||
case .messagesNotModified:
|
||||
|
||||
@@ -20,7 +20,8 @@ func _internal_markAllChatsAsRead(postbox: Postbox, network: Network, stateManag
|
||||
var signals: [Signal<Void, NoError>] = []
|
||||
for peer in result {
|
||||
switch peer {
|
||||
case let .dialogPeer(peer):
|
||||
case let .dialogPeer(dialogPeerData):
|
||||
let peer = dialogPeerData.peer
|
||||
let peerId = peer.peerId
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if let inputChannel = transaction.getPeer(peerId).flatMap(apiInputChannel) {
|
||||
@@ -42,7 +43,8 @@ func _internal_markAllChatsAsRead(postbox: Postbox, network: Network, stateManag
|
||||
|> mapToSignal { result -> Signal<Void, NoError> in
|
||||
if let result = result {
|
||||
switch result {
|
||||
case let .affectedMessages(pts, ptsCount):
|
||||
case let .affectedMessages(affectedMessagesData):
|
||||
let (pts, ptsCount) = (affectedMessagesData.pts, affectedMessagesData.ptsCount)
|
||||
stateManager.addUpdateGroups([.updatePts(pts: pts, ptsCount: ptsCount)])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ func _internal_messageReadStats(account: Account, id: MessageId) -> Signal<Messa
|
||||
return MessageReadStats(reactionCount: 0, peers: [], readTimestamps: [:])
|
||||
}
|
||||
switch result {
|
||||
case let .outboxReadDate(date):
|
||||
case let .outboxReadDate(outboxReadDateData):
|
||||
let date = outboxReadDateData.date
|
||||
return MessageReadStats(reactionCount: 0, peers: [EnginePeer(peer)], readTimestamps: [peer.id: date])
|
||||
}
|
||||
}
|
||||
@@ -47,7 +48,8 @@ func _internal_messageReadStats(account: Account, id: MessageId) -> Signal<Messa
|
||||
var items: [(Int64, Int32)] = []
|
||||
for item in result {
|
||||
switch item {
|
||||
case let .readParticipantDate(userId, date):
|
||||
case let .readParticipantDate(readParticipantDateData):
|
||||
let (userId, date) = (readParticipantDateData.userId, readParticipantDateData.date)
|
||||
items.append((userId, date))
|
||||
}
|
||||
}
|
||||
@@ -60,7 +62,8 @@ func _internal_messageReadStats(account: Account, id: MessageId) -> Signal<Messa
|
||||
let reactionCount: Signal<Int, NoError> = account.network.request(Api.functions.messages.getMessageReactionsList(flags: 0, peer: inputPeer, id: id.id, reaction: nil, offset: nil, limit: 1))
|
||||
|> map { result -> Int in
|
||||
switch result {
|
||||
case let .messageReactionsList(_, count, _, _, _, _):
|
||||
case let .messageReactionsList(messageReactionsListData):
|
||||
let count = messageReactionsListData.count
|
||||
return Int(count)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,15 +23,18 @@ func _internal_requestMessageSelectPollOption(account: Account, messageId: Messa
|
||||
return account.postbox.transaction { transaction -> TelegramMediaPoll? in
|
||||
var resultPoll: TelegramMediaPoll?
|
||||
switch result {
|
||||
case let .updates(updates, _, _, _, _):
|
||||
case let .updates(updatesData):
|
||||
let updates = updatesData.updates
|
||||
for update in updates {
|
||||
switch update {
|
||||
case let .updateMessagePoll(_, id, poll, results):
|
||||
case let .updateMessagePoll(updateMessagePollData):
|
||||
let (id, poll, results) = (updateMessagePollData.pollId, updateMessagePollData.poll, updateMessagePollData.results)
|
||||
let pollId = MediaId(namespace: Namespaces.Media.CloudPoll, id: id)
|
||||
resultPoll = transaction.getMedia(pollId) as? TelegramMediaPoll
|
||||
if let poll = poll {
|
||||
switch poll {
|
||||
case let .poll(_, flags, question, answers, closePeriod, _):
|
||||
case let .poll(pollData):
|
||||
let (flags, question, answers, closePeriod) = (pollData.flags, pollData.question, pollData.answers, pollData.closePeriod)
|
||||
let publicity: TelegramMediaPollPublicity
|
||||
if (flags & (1 << 1)) != 0 {
|
||||
publicity = .public
|
||||
@@ -47,7 +50,8 @@ func _internal_requestMessageSelectPollOption(account: Account, messageId: Messa
|
||||
let questionText: String
|
||||
let questionEntities: [MessageTextEntity]
|
||||
switch question {
|
||||
case let .textWithEntities(text, entities):
|
||||
case let .textWithEntities(textWithEntitiesData):
|
||||
let (text, entities) = (textWithEntitiesData.text, textWithEntitiesData.entities)
|
||||
questionText = text
|
||||
questionEntities = messageTextEntitiesFromApiEntities(entities)
|
||||
}
|
||||
@@ -57,7 +61,8 @@ func _internal_requestMessageSelectPollOption(account: Account, messageId: Messa
|
||||
|
||||
let resultsMin: Bool
|
||||
switch results {
|
||||
case let .pollResults(flags, _, _, _, _, _):
|
||||
case let .pollResults(pollResultsData):
|
||||
let flags = pollResultsData.flags
|
||||
resultsMin = (flags & (1 << 0)) != 0
|
||||
}
|
||||
resultPoll = resultPoll?.withUpdatedResults(TelegramMediaPollResults(apiResults: results), min: resultsMin)
|
||||
@@ -142,7 +147,7 @@ func _internal_requestClosePoll(postbox: Postbox, network: Network, stateManager
|
||||
pollMediaFlags |= 1 << 1
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, media: .inputMediaPoll(flags: pollMediaFlags, poll: .poll(id: poll.pollId.id, flags: pollFlags, question: .textWithEntities(text: poll.text, entities: apiEntitiesFromMessageTextEntities(poll.textEntities, associatedPeers: SimpleDictionary())), answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: nil), correctAnswers: correctAnswers, solution: mappedSolution, solutionEntities: mappedSolutionEntities), replyMarkup: nil, entities: nil, scheduleDate: nil, scheduleRepeatPeriod: nil, quickReplyShortcutId: nil))
|
||||
return network.request(Api.functions.messages.editMessage(flags: flags, peer: inputPeer, id: messageId.id, message: nil, media: .inputMediaPoll(.init(flags: pollMediaFlags, poll: .poll(.init(id: poll.pollId.id, flags: pollFlags, question: .textWithEntities(.init(text: poll.text, entities: apiEntitiesFromMessageTextEntities(poll.textEntities, associatedPeers: SimpleDictionary()))), answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: nil)), correctAnswers: correctAnswers, solution: mappedSolution, solutionEntities: mappedSolutionEntities)), replyMarkup: nil, entities: nil, scheduleDate: nil, scheduleRepeatPeriod: nil, quickReplyShortcutId: nil))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
@@ -280,18 +285,22 @@ private final class PollResultsOptionContext {
|
||||
return ([], 0, nil)
|
||||
}
|
||||
switch result {
|
||||
case let .votesList(_, count, votes, chats, users, nextOffset):
|
||||
case let .votesList(votesListData):
|
||||
let (count, votes, chats, users, nextOffset) = (votesListData.count, votesListData.votes, votesListData.chats, votesListData.users, votesListData.nextOffset)
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
||||
var resultPeers: [RenderedPeer] = []
|
||||
for vote in votes {
|
||||
let peerId: PeerId
|
||||
switch vote {
|
||||
case let .messagePeerVote(peerIdValue, _, _):
|
||||
case let .messagePeerVote(messagePeerVoteData):
|
||||
let peerIdValue = messagePeerVoteData.peer
|
||||
peerId = peerIdValue.peerId
|
||||
case let .messagePeerVoteInputOption(peerIdValue, _):
|
||||
case let .messagePeerVoteInputOption(messagePeerVoteInputOptionData):
|
||||
let peerIdValue = messagePeerVoteInputOptionData.peer
|
||||
peerId = peerIdValue.peerId
|
||||
case let .messagePeerVoteMultiple(peerIdValue, _, _):
|
||||
case let .messagePeerVoteMultiple(messagePeerVoteMultipleData):
|
||||
let peerIdValue = messagePeerVoteMultipleData.peer
|
||||
peerId = peerIdValue.peerId
|
||||
}
|
||||
if let peer = transaction.getPeer(peerId) {
|
||||
|
||||
+2
-1
@@ -30,7 +30,8 @@ func _internal_getPreparedInlineMessage(account: Account, botId: EnginePeer.Id,
|
||||
}
|
||||
return account.postbox.transaction { transaction -> PreparedInlineMessage? in
|
||||
switch result {
|
||||
case let .preparedInlineMessage(queryId, result, apiPeerTypes, cacheTime, users):
|
||||
case let .preparedInlineMessage(preparedInlineMessageData):
|
||||
let (queryId, result, apiPeerTypes, cacheTime, users) = (preparedInlineMessageData.queryId, preparedInlineMessageData.result, preparedInlineMessageData.peerTypes, preparedInlineMessageData.cacheTime, preparedInlineMessageData.users)
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: AccumulatedPeers(users: users))
|
||||
let _ = cacheTime
|
||||
return PreparedInlineMessage(
|
||||
|
||||
@@ -152,7 +152,8 @@ func _internal_keepShortcutMessagesUpdated(account: Account) -> Signal<Never, No
|
||||
return account.postbox.transaction { transaction in
|
||||
var state = transaction.getPreferencesEntry(key: PreferencesKeys.shortcutMessages())?.get(QuickReplyMessageShortcutsState.self) ?? QuickReplyMessageShortcutsState(shortcuts: [])
|
||||
switch result {
|
||||
case let .quickReplies(quickReplies, messages, chats, users):
|
||||
case let .quickReplies(quickRepliesData):
|
||||
let (quickReplies, messages, chats, users) = (quickRepliesData.quickReplies, quickRepliesData.messages, quickRepliesData.chats, quickRepliesData.users)
|
||||
let previousShortcuts = state.shortcuts
|
||||
state.shortcuts.removeAll()
|
||||
|
||||
@@ -171,7 +172,8 @@ func _internal_keepShortcutMessagesUpdated(account: Account) -> Signal<Never, No
|
||||
|
||||
for quickReply in quickReplies {
|
||||
switch quickReply {
|
||||
case let .quickReply(shortcutId, shortcut, topMessage, _):
|
||||
case let .quickReply(quickReplyData):
|
||||
let (shortcutId, shortcut, topMessage, _) = (quickReplyData.shortcutId, quickReplyData.shortcut, quickReplyData.topMessage, quickReplyData.count)
|
||||
state.shortcuts.append(QuickReplyMessageShortcut(
|
||||
id: shortcutId,
|
||||
shortcut: shortcut
|
||||
@@ -543,7 +545,8 @@ public final class TelegramBusinessGreetingMessage: Codable, Equatable {
|
||||
extension TelegramBusinessGreetingMessage {
|
||||
convenience init(apiGreetingMessage: Api.BusinessGreetingMessage) {
|
||||
switch apiGreetingMessage {
|
||||
case let .businessGreetingMessage(shortcutId, recipients, noActivityDays):
|
||||
case let .businessGreetingMessage(businessGreetingMessageData):
|
||||
let (shortcutId, recipients, noActivityDays) = (businessGreetingMessageData.shortcutId, businessGreetingMessageData.recipients, businessGreetingMessageData.noActivityDays)
|
||||
self.init(
|
||||
shortcutId: shortcutId,
|
||||
recipients: TelegramBusinessRecipients(apiValue: recipients),
|
||||
@@ -715,14 +718,16 @@ public final class TelegramBusinessIntro: Codable, Equatable {
|
||||
extension TelegramBusinessAwayMessage {
|
||||
convenience init(apiAwayMessage: Api.BusinessAwayMessage) {
|
||||
switch apiAwayMessage {
|
||||
case let .businessAwayMessage(flags, shortcutId, schedule, recipients):
|
||||
case let .businessAwayMessage(businessAwayMessageData):
|
||||
let (flags, shortcutId, schedule, recipients) = (businessAwayMessageData.flags, businessAwayMessageData.shortcutId, businessAwayMessageData.schedule, businessAwayMessageData.recipients)
|
||||
let mappedSchedule: Schedule
|
||||
switch schedule {
|
||||
case .businessAwayMessageScheduleAlways:
|
||||
mappedSchedule = .always
|
||||
case .businessAwayMessageScheduleOutsideWorkHours:
|
||||
mappedSchedule = .outsideWorkingHours
|
||||
case let .businessAwayMessageScheduleCustom(startDate, endDate):
|
||||
case let .businessAwayMessageScheduleCustom(businessAwayMessageScheduleCustomData):
|
||||
let (startDate, endDate) = (businessAwayMessageScheduleCustomData.startDate, businessAwayMessageScheduleCustomData.endDate)
|
||||
mappedSchedule = .custom(beginTimestamp: startDate, endTimestamp: endDate)
|
||||
}
|
||||
|
||||
@@ -741,7 +746,9 @@ extension TelegramBusinessAwayMessage {
|
||||
extension TelegramBusinessIntro {
|
||||
convenience init(apiBusinessIntro: Api.BusinessIntro) {
|
||||
switch apiBusinessIntro {
|
||||
case let .businessIntro(_, title, description, sticker):
|
||||
case let .businessIntro(businessIntroData):
|
||||
let (flags, title, description, sticker) = (businessIntroData.flags, businessIntroData.title, businessIntroData.description, businessIntroData.sticker)
|
||||
let _ = flags
|
||||
self.init(title: title, text: description, stickerFile: sticker.flatMap { telegramMediaFileFromApiDocument($0, altDocuments: []) })
|
||||
}
|
||||
}
|
||||
@@ -752,15 +759,15 @@ extension TelegramBusinessIntro {
|
||||
if let stickerFile = self.stickerFile {
|
||||
if let fileResource = stickerFile.resource as? CloudDocumentMediaResource, let resource = stickerFile.resource as? TelegramCloudMediaResourceWithFileReference, let reference = resource.fileReference {
|
||||
flags |= 1 << 0
|
||||
sticker = .inputDocument(id: fileResource.fileId, accessHash: fileResource.accessHash, fileReference: Buffer(data: reference))
|
||||
sticker = .inputDocument(.init(id: fileResource.fileId, accessHash: fileResource.accessHash, fileReference: Buffer(data: reference)))
|
||||
}
|
||||
}
|
||||
return .inputBusinessIntro(
|
||||
return .inputBusinessIntro(.init(
|
||||
flags: flags,
|
||||
title: self.title,
|
||||
description: self.text,
|
||||
sticker: sticker
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -768,7 +775,8 @@ extension TelegramBusinessBotRights {
|
||||
init(apiValue: Api.BusinessBotRights) {
|
||||
var value: TelegramBusinessBotRights = []
|
||||
switch apiValue {
|
||||
case let .businessBotRights(flags):
|
||||
case let .businessBotRights(businessBotRightsData):
|
||||
let flags = businessBotRightsData.flags
|
||||
if (flags & (1 << 0)) != 0 {
|
||||
value.insert(.reply)
|
||||
}
|
||||
@@ -820,7 +828,8 @@ extension TelegramBusinessBotRights {
|
||||
extension TelegramBusinessRecipients {
|
||||
convenience init(apiValue: Api.BusinessRecipients) {
|
||||
switch apiValue {
|
||||
case let .businessRecipients(flags, users):
|
||||
case let .businessRecipients(businessRecipientsData):
|
||||
let (flags, users) = (businessRecipientsData.flags, businessRecipientsData.users)
|
||||
var categories: Categories = []
|
||||
if (flags & (1 << 0)) != 0 {
|
||||
categories.insert(.existingChats)
|
||||
@@ -846,7 +855,8 @@ extension TelegramBusinessRecipients {
|
||||
|
||||
convenience init(apiValue: Api.BusinessBotRecipients) {
|
||||
switch apiValue {
|
||||
case let .businessBotRecipients(flags, users, excludeUsers):
|
||||
case let .businessBotRecipients(businessBotRecipientsData):
|
||||
let (flags, users, excludeUsers) = (businessBotRecipientsData.flags, businessBotRecipientsData.users, businessBotRecipientsData.excludeUsers)
|
||||
var categories: Categories = []
|
||||
if (flags & (1 << 0)) != 0 {
|
||||
categories.insert(.existingChats)
|
||||
@@ -897,7 +907,7 @@ extension TelegramBusinessRecipients {
|
||||
flags |= 1 << 4
|
||||
}
|
||||
|
||||
return .inputBusinessRecipients(flags: flags, users: users)
|
||||
return .inputBusinessRecipients(.init(flags: flags, users: users))
|
||||
}
|
||||
|
||||
func apiInputBotValue(additionalPeers: [Peer], excludePeers: [Peer]) -> Api.InputBusinessBotRecipients {
|
||||
@@ -934,7 +944,7 @@ extension TelegramBusinessRecipients {
|
||||
flags |= 1 << 6
|
||||
}
|
||||
|
||||
return .inputBusinessBotRecipients(flags: flags, users: users, excludeUsers: excludeUsers)
|
||||
return .inputBusinessBotRecipients(.init(flags: flags, users: users, excludeUsers: excludeUsers))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -948,11 +958,11 @@ func _internal_updateBusinessGreetingMessage(account: Account, greetingMessage:
|
||||
|> mapToSignal { additionalPeers in
|
||||
var mappedMessage: Api.InputBusinessGreetingMessage?
|
||||
if let greetingMessage {
|
||||
mappedMessage = .inputBusinessGreetingMessage(
|
||||
mappedMessage = .inputBusinessGreetingMessage(.init(
|
||||
shortcutId: greetingMessage.shortcutId,
|
||||
recipients: greetingMessage.recipients.apiInputValue(additionalPeers: additionalPeers),
|
||||
noActivityDays: Int32(clamping: greetingMessage.inactivityDays)
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
var flags: Int32 = 0
|
||||
@@ -997,7 +1007,7 @@ func _internal_updateBusinessAwayMessage(account: Account, awayMessage: Telegram
|
||||
case .outsideWorkingHours:
|
||||
mappedSchedule = .businessAwayMessageScheduleOutsideWorkHours
|
||||
case let .custom(beginTimestamp, endTimestamp):
|
||||
mappedSchedule = .businessAwayMessageScheduleCustom(startDate: beginTimestamp, endDate: endTimestamp)
|
||||
mappedSchedule = .businessAwayMessageScheduleCustom(Api.BusinessAwayMessageSchedule.Cons_businessAwayMessageScheduleCustom(startDate: beginTimestamp, endDate: endTimestamp))
|
||||
}
|
||||
|
||||
var flags: Int32 = 0
|
||||
@@ -1005,12 +1015,12 @@ func _internal_updateBusinessAwayMessage(account: Account, awayMessage: Telegram
|
||||
flags |= 1 << 0
|
||||
}
|
||||
|
||||
mappedMessage = .inputBusinessAwayMessage(
|
||||
mappedMessage = .inputBusinessAwayMessage(.init(
|
||||
flags: flags,
|
||||
shortcutId: awayMessage.shortcutId,
|
||||
schedule: mappedSchedule,
|
||||
recipients: awayMessage.recipients.apiInputValue(additionalPeers: additionalPeers)
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
var flags: Int32 = 0
|
||||
@@ -1169,7 +1179,7 @@ public func _internal_setAccountConnectedBot(account: Account, bot: TelegramAcco
|
||||
var flags: Int32 = 0
|
||||
var mappedRights: Api.BusinessBotRights?
|
||||
var mappedBot: Api.InputUser = .inputUserEmpty
|
||||
var mappedRecipients: Api.InputBusinessBotRecipients = .inputBusinessBotRecipients(flags: 0, users: nil, excludeUsers: nil)
|
||||
var mappedRecipients: Api.InputBusinessBotRecipients = .inputBusinessBotRecipients(.init(flags: 0, users: nil, excludeUsers: nil))
|
||||
|
||||
if let bot, let inputBotUser = botUser.flatMap(apiInputUser) {
|
||||
mappedBot = inputBotUser
|
||||
@@ -1219,7 +1229,7 @@ public func _internal_setAccountConnectedBot(account: Account, bot: TelegramAcco
|
||||
if bot.rights.contains(.manageStories) {
|
||||
rightsFlags |= (1 << 13)
|
||||
}
|
||||
mappedRights = .businessBotRights(flags: rightsFlags)
|
||||
mappedRights = .businessBotRights(Api.BusinessBotRights.Cons_businessBotRights(flags: rightsFlags))
|
||||
mappedRecipients = bot.recipients.apiInputBotValue(additionalPeers: additionalPeers, excludePeers: excludePeers)
|
||||
} else {
|
||||
flags |= 1 << 1
|
||||
|
||||
@@ -156,7 +156,8 @@ private class ReplyThreadHistoryContextImpl {
|
||||
|> mapToSignal { discussionMessage -> Signal<DiscussionMessage, FetchChannelReplyThreadMessageError> in
|
||||
return account.postbox.transaction { transaction -> Signal<DiscussionMessage, FetchChannelReplyThreadMessageError> in
|
||||
switch discussionMessage {
|
||||
case let .discussionMessage(_, messages, maxId, readInboxMaxId, readOutboxMaxId, unreadCount, chats, users):
|
||||
case let .discussionMessage(discussionMessageData):
|
||||
let (messages, maxId, readInboxMaxId, readOutboxMaxId, unreadCount, chats, users) = (discussionMessageData.messages, discussionMessageData.maxId, discussionMessageData.readInboxMaxId, discussionMessageData.readOutboxMaxId, discussionMessageData.unreadCount, discussionMessageData.chats, discussionMessageData.users)
|
||||
let parsedMessages = messages.compactMap { message -> StoreMessage? in
|
||||
StoreMessage(apiMessage: message, accountPeerId: accountPeerId, peerIsForum: peer.isForumOrMonoForum)
|
||||
}
|
||||
@@ -476,7 +477,8 @@ private class ReplyThreadHistoryContextImpl {
|
||||
let validateSignal = strongSelf.account.network.request(Api.functions.messages.getDiscussionMessage(peer: inputPeer, msgId: Int32(clamping: threadId)))
|
||||
|> map { result -> (MessageId?, Int) in
|
||||
switch result {
|
||||
case let .discussionMessage(_, _, _, readInboxMaxId, _, unreadCount, _, _):
|
||||
case let .discussionMessage(discussionMessageData):
|
||||
let (readInboxMaxId, unreadCount) = (discussionMessageData.readInboxMaxId, discussionMessageData.unreadCount)
|
||||
return (readInboxMaxId.flatMap({ MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: $0) }), Int(unreadCount))
|
||||
}
|
||||
}
|
||||
@@ -670,7 +672,8 @@ func _internal_fetchChannelReplyThreadMessage(account: Account, messageId: Messa
|
||||
}
|
||||
return account.postbox.transaction { transaction -> DiscussionMessage? in
|
||||
switch discussionMessage {
|
||||
case let .discussionMessage(_, messages, maxId, readInboxMaxId, readOutboxMaxId, unreadCount, chats, users):
|
||||
case let .discussionMessage(discussionMessageData):
|
||||
let (messages, maxId, readInboxMaxId, readOutboxMaxId, unreadCount, chats, users) = (discussionMessageData.messages, discussionMessageData.maxId, discussionMessageData.readInboxMaxId, discussionMessageData.readOutboxMaxId, discussionMessageData.unreadCount, discussionMessageData.chats, discussionMessageData.users)
|
||||
let parsedMessages = messages.compactMap { message -> StoreMessage? in
|
||||
StoreMessage(apiMessage: message, accountPeerId: accountPeerId, peerIsForum: peer.isForumOrMonoForum)
|
||||
}
|
||||
|
||||
@@ -29,10 +29,12 @@ func _internal_reportAdMessage(account: Account, opaqueId: Data, option: Data?)
|
||||
}
|
||||
|> map { result -> ReportAdMessageResult in
|
||||
switch result {
|
||||
case let .sponsoredMessageReportResultChooseOption(title, options):
|
||||
case let .sponsoredMessageReportResultChooseOption(sponsoredMessageReportResultChooseOptionData):
|
||||
let (title, options) = (sponsoredMessageReportResultChooseOptionData.title, sponsoredMessageReportResultChooseOptionData.options)
|
||||
return .options(title: title, options: options.map {
|
||||
switch $0 {
|
||||
case let .sponsoredMessageReportOption(text, option):
|
||||
case let .sponsoredMessageReportOption(sponsoredMessageReportOptionData):
|
||||
let (text, option) = (sponsoredMessageReportOptionData.text, sponsoredMessageReportOptionData.option)
|
||||
return ReportAdMessageResult.Option(text: text, option: option.makeData())
|
||||
}
|
||||
})
|
||||
|
||||
@@ -63,14 +63,17 @@ func _internal_reportContent(account: Account, subject: ReportContentSubject, op
|
||||
}
|
||||
|> map { result -> ReportContentResult in
|
||||
switch result {
|
||||
case let .reportResultChooseOption(title, options):
|
||||
case let .reportResultChooseOption(reportResultChooseOptionData):
|
||||
let (title, options) = (reportResultChooseOptionData.title, reportResultChooseOptionData.options)
|
||||
return .options(title: title, options: options.map {
|
||||
switch $0 {
|
||||
case let .messageReportOption(text, option):
|
||||
case let .messageReportOption(messageReportOptionData):
|
||||
let (text, option) = (messageReportOptionData.text, messageReportOptionData.option)
|
||||
return ReportContentResult.Option(text: text, option: option.makeData())
|
||||
}
|
||||
})
|
||||
case let .reportResultAddComment(flags, option):
|
||||
case let .reportResultAddComment(reportResultAddCommentData):
|
||||
let (flags, option) = (reportResultAddCommentData.flags, reportResultAddCommentData.option)
|
||||
return .addComment(optional: (flags & (1 << 0)) != 0, option: option.makeData())
|
||||
case .reportResultReported:
|
||||
return .reported
|
||||
|
||||
+7
-2
@@ -1,3 +1,4 @@
|
||||
import SGLogging
|
||||
import Foundation
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
@@ -52,7 +53,7 @@ public struct RequestChatContextResultsResult {
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_requestChatContextResults(account: Account, botId: PeerId, peerId: PeerId, query: String, location: Signal<(Double, Double)?, NoError> = .single(nil), offset: String, incompleteResults: Bool = false, staleCachedResults: Bool = false) -> Signal<RequestChatContextResultsResult?, RequestChatContextResultsError> {
|
||||
func _internal_requestChatContextResults(IQTP: Bool = false, account: Account, botId: PeerId, peerId: PeerId, query: String, location: Signal<(Double, Double)?, NoError> = .single(nil), offset: String, incompleteResults: Bool = false, staleCachedResults: Bool = false) -> Signal<RequestChatContextResultsResult?, RequestChatContextResultsError> {
|
||||
return account.postbox.transaction { transaction -> (bot: Peer, peer: Peer)? in
|
||||
if let bot = transaction.getPeer(botId), let peer = transaction.getPeer(peerId) {
|
||||
return (bot, peer)
|
||||
@@ -119,7 +120,7 @@ func _internal_requestChatContextResults(account: Account, botId: PeerId, peerId
|
||||
if let (latitude, longitude) = location {
|
||||
flags |= (1 << 0)
|
||||
let geoPointFlags: Int32 = 0
|
||||
geoPoint = Api.InputGeoPoint.inputGeoPoint(flags: geoPointFlags, lat: latitude, long: longitude, accuracyRadius: nil)
|
||||
geoPoint = Api.InputGeoPoint.inputGeoPoint(.init(flags: geoPointFlags, lat: latitude, long: longitude, accuracyRadius: nil))
|
||||
}
|
||||
|
||||
var signal: Signal<RequestChatContextResultsResult?, RequestChatContextResultsError> = account.network.request(Api.functions.messages.getInlineBotResults(flags: flags, bot: inputBot, peer: inputPeer, geoPoint: geoPoint, query: query, offset: offset))
|
||||
@@ -127,6 +128,10 @@ func _internal_requestChatContextResults(account: Account, botId: PeerId, peerId
|
||||
return ChatContextResultCollection(apiResults: result, botId: bot.id, peerId: peerId, query: query, geoPoint: location)
|
||||
}
|
||||
|> mapError { error -> RequestChatContextResultsError in
|
||||
// MARK: Swiftgram
|
||||
if IQTP {
|
||||
SGLogger.shared.log("SGIQTP", "Error requesting inline results: \(error.errorDescription ?? "nil")")
|
||||
}
|
||||
if error.errorDescription == "BOT_INLINE_GEO_REQUIRED" {
|
||||
return .locationRequired
|
||||
} else {
|
||||
|
||||
+61
-16
@@ -104,7 +104,7 @@ func _internal_requestMessageActionCallback(account: Account, messageId: Message
|
||||
guard let kdfResult = passwordKDF(encryptionProvider: account.network.encryptionProvider, password: password, derivation: currentPasswordDerivation, srpSessionData: srpSessionData) else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
return .single(.inputCheckPasswordSRP(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1)))
|
||||
return .single(.inputCheckPasswordSRP(.init(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1))))
|
||||
} else {
|
||||
return .fail(.twoStepAuthMissing)
|
||||
}
|
||||
@@ -146,7 +146,8 @@ func _internal_requestMessageActionCallback(account: Account, messageId: Message
|
||||
return .none
|
||||
}
|
||||
switch result {
|
||||
case let .botCallbackAnswer(flags, message, url, _):
|
||||
case let .botCallbackAnswer(botCallbackAnswerData):
|
||||
let (flags, message, url) = (botCallbackAnswerData.flags, botCallbackAnswerData.message, botCallbackAnswerData.url)
|
||||
if let message = message {
|
||||
if (flags & (1 << 1)) != 0 {
|
||||
return .alert(message)
|
||||
@@ -168,9 +169,39 @@ func _internal_requestMessageActionCallback(account: Account, messageId: Message
|
||||
}
|
||||
|
||||
public enum MessageActionUrlAuthResult {
|
||||
public struct Flags: OptionSet {
|
||||
public var rawValue: Int32
|
||||
|
||||
public init(rawValue: Int32) {
|
||||
self.rawValue = rawValue
|
||||
}
|
||||
|
||||
public static let requestWriteAccess = Flags(rawValue: 1 << 0)
|
||||
public static let requestPhoneNumber = Flags(rawValue: 1 << 1)
|
||||
}
|
||||
|
||||
public struct ClientData : Equatable {
|
||||
public let browser: String
|
||||
public let platform: String
|
||||
public let ip: String
|
||||
public let region: String
|
||||
|
||||
public init(browser: String, platform: String, ip: String, region: String) {
|
||||
self.browser = browser
|
||||
self.platform = platform
|
||||
self.ip = ip
|
||||
self.region = region
|
||||
}
|
||||
}
|
||||
|
||||
case `default`
|
||||
case accepted(String)
|
||||
case request(String, Peer, Bool)
|
||||
case accepted(url: String?)
|
||||
case request(domain: String, bot: Peer, clientData: ClientData?, flags: Flags)
|
||||
}
|
||||
|
||||
public enum MessageActionUrlAuthError {
|
||||
case generic
|
||||
case urlExpired
|
||||
}
|
||||
|
||||
public enum MessageActionUrlSubject {
|
||||
@@ -212,19 +243,35 @@ func _internal_requestMessageActionUrlAuth(account: Account, subject: MessageAct
|
||||
switch result {
|
||||
case .urlAuthResultDefault:
|
||||
return .default
|
||||
case let .urlAuthResultAccepted(url):
|
||||
return .accepted(url)
|
||||
case let .urlAuthResultRequest(flags, bot, domain):
|
||||
return .request(domain, TelegramUser(user: bot), (flags & (1 << 0)) != 0)
|
||||
case let .urlAuthResultAccepted(urlAuthResultAcceptedData):
|
||||
let url = urlAuthResultAcceptedData.url
|
||||
return .accepted(url: url)
|
||||
case let .urlAuthResultRequest(urlAuthResultRequestData):
|
||||
let (apiFlags, bot, domain) = (urlAuthResultRequestData.flags, urlAuthResultRequestData.bot, urlAuthResultRequestData.domain)
|
||||
var clientData: MessageActionUrlAuthResult.ClientData?
|
||||
if let browser = urlAuthResultRequestData.browser, let platform = urlAuthResultRequestData.platform, let ip = urlAuthResultRequestData.ip, let region = urlAuthResultRequestData.region {
|
||||
clientData = MessageActionUrlAuthResult.ClientData(browser: browser, platform: platform, ip: ip, region: region)
|
||||
}
|
||||
var flags: MessageActionUrlAuthResult.Flags = []
|
||||
if (apiFlags & (1 << 0)) != 0 {
|
||||
flags.insert(.requestWriteAccess)
|
||||
}
|
||||
if (apiFlags & (1 << 1)) != 0 {
|
||||
flags.insert(.requestPhoneNumber)
|
||||
}
|
||||
return .request(domain: domain, bot: TelegramUser(user: bot), clientData: clientData, flags: flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_acceptMessageActionUrlAuth(account: Account, subject: MessageActionUrlSubject, allowWriteAccess: Bool) -> Signal<MessageActionUrlAuthResult, NoError> {
|
||||
func _internal_acceptMessageActionUrlAuth(account: Account, subject: MessageActionUrlSubject, allowWriteAccess: Bool, sharePhoneNumber: Bool) -> Signal<MessageActionUrlAuthResult, MessageActionUrlAuthError> {
|
||||
var flags: Int32 = 0
|
||||
if allowWriteAccess {
|
||||
flags |= Int32(1 << 0)
|
||||
}
|
||||
if sharePhoneNumber {
|
||||
flags |= Int32(1 << 3)
|
||||
}
|
||||
|
||||
let request: Signal<Api.UrlAuthResult?, MTRpcError>
|
||||
switch subject {
|
||||
@@ -250,16 +297,14 @@ func _internal_acceptMessageActionUrlAuth(account: Account, subject: MessageActi
|
||||
|
||||
|
||||
return request
|
||||
|> `catch` { _ -> Signal<Api.UrlAuthResult?, NoError> in
|
||||
return .single(nil)
|
||||
|> mapError { _ -> MessageActionUrlAuthError in
|
||||
return .generic
|
||||
}
|
||||
|> map { result -> MessageActionUrlAuthResult in
|
||||
guard let result = result else {
|
||||
return .default
|
||||
}
|
||||
switch result {
|
||||
case let .urlAuthResultAccepted(url):
|
||||
return .accepted(url)
|
||||
case let .urlAuthResultAccepted(urlAuthResultAcceptedData):
|
||||
let url = urlAuthResultAcceptedData.url
|
||||
return .accepted(url: url)
|
||||
default:
|
||||
return .default
|
||||
}
|
||||
|
||||
@@ -88,26 +88,30 @@ private func mergedState(transaction: Transaction, seedConfiguration: SeedConfig
|
||||
let totalCount: Int32
|
||||
let nextRate: Int32?
|
||||
switch result {
|
||||
case let .channelMessages(_, _, count, _, apiMessages, apiTopics, apiChats, apiUsers):
|
||||
case let .channelMessages(channelMessagesData):
|
||||
let (_, _, count, _, apiMessages, apiTopics, apiChats, apiUsers) = (channelMessagesData.flags, channelMessagesData.pts, channelMessagesData.count, channelMessagesData.offsetIdOffset, channelMessagesData.messages, channelMessagesData.topics, channelMessagesData.chats, channelMessagesData.users)
|
||||
messages = apiMessages
|
||||
let _ = apiTopics
|
||||
chats = apiChats
|
||||
users = apiUsers
|
||||
totalCount = count
|
||||
nextRate = nil
|
||||
case let .messages(apiMessages, _, apiChats, apiUsers):
|
||||
case let .messages(messagesData):
|
||||
let (apiMessages, _, apiChats, apiUsers) = (messagesData.messages, messagesData.topics, messagesData.chats, messagesData.users)
|
||||
messages = apiMessages
|
||||
chats = apiChats
|
||||
users = apiUsers
|
||||
totalCount = Int32(messages.count)
|
||||
nextRate = nil
|
||||
case let .messagesSlice(_, count, apiNextRate, _, _, apiMessages, _, apiChats, apiUsers):
|
||||
case let .messagesSlice(messagesSliceData):
|
||||
let (_, count, apiNextRate, _, _, apiMessages, _, apiChats, apiUsers) = (messagesSliceData.flags, messagesSliceData.count, messagesSliceData.nextRate, messagesSliceData.offsetIdOffset, messagesSliceData.searchFlood, messagesSliceData.messages, messagesSliceData.topics, messagesSliceData.chats, messagesSliceData.users)
|
||||
messages = apiMessages
|
||||
chats = apiChats
|
||||
users = apiUsers
|
||||
totalCount = count
|
||||
nextRate = apiNextRate
|
||||
case .messagesNotModified:
|
||||
case let .messagesNotModified(messagesNotModifiedData):
|
||||
let _ = messagesNotModifiedData.count
|
||||
messages = []
|
||||
chats = []
|
||||
users = []
|
||||
@@ -282,13 +286,17 @@ func _internal_getSearchMessageCount(account: Account, location: SearchMessagesL
|
||||
return account.network.request(Api.functions.messages.search(flags: flags, peer: inputPeer, q: query, fromId: fromPeer, savedPeerId: savedPeerId, savedReaction: nil, topMsgId: topMsgId, filter: .inputMessagesFilterEmpty, minDate: 0, maxDate: 0, offsetId: 0, addOffset: 0, limit: 1, maxId: 0, minId: 0, hash: 0))
|
||||
|> map { result -> Int? in
|
||||
switch result {
|
||||
case let .channelMessages(_, _, count, _, _, _, _, _):
|
||||
case let .channelMessages(channelMessagesData):
|
||||
let count = channelMessagesData.count
|
||||
return Int(count)
|
||||
case let .messages(messages, _, _, _):
|
||||
case let .messages(messagesData):
|
||||
let messages = messagesData.messages
|
||||
return messages.count
|
||||
case let .messagesNotModified(count):
|
||||
case let .messagesNotModified(messagesNotModifiedData):
|
||||
let count = messagesNotModifiedData.count
|
||||
return Int(count)
|
||||
case let .messagesSlice(_, count, _, _, _, _, _, _, _):
|
||||
case let .messagesSlice(messagesSliceData):
|
||||
let count = messagesSliceData.count
|
||||
return Int(count)
|
||||
}
|
||||
}
|
||||
@@ -298,7 +306,7 @@ func _internal_getSearchMessageCount(account: Account, location: SearchMessagesL
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_searchMessages(account: Account, location: SearchMessagesLocation, query: String, state: SearchMessagesState?, centerId: MessageId?, limit: Int32 = 100) -> Signal<(SearchMessagesResult, SearchMessagesState), NoError> {
|
||||
func _internal_searchMessages(account: Account, location: SearchMessagesLocation, query: String, state: SearchMessagesState?, centerId: MessageId?, limit: Int32 = 100, forceLocal: Bool = false) -> Signal<(SearchMessagesResult, SearchMessagesState), NoError> {
|
||||
if case let .peer(peerId, fromId, tags, reactions, threadId, minDate, maxDate) = location, fromId == nil, tags == nil, peerId == account.peerId, let reactions, let reaction = reactions.first, (minDate == nil || minDate == 0), (maxDate == nil || maxDate == 0) {
|
||||
return account.postbox.transaction { transaction -> (SearchMessagesResult, SearchMessagesState) in
|
||||
let messages = transaction.getMessagesWithCustomTag(peerId: peerId, namespace: Namespaces.Message.Cloud, threadId: threadId, customTag: ReactionsMessageAttribute.messageTag(reaction: reaction), from: MessageIndex.upperBound(peerId: peerId, namespace: Namespaces.Message.Cloud), includeFrom: false, to: MessageIndex.lowerBound(peerId: peerId, namespace: Namespaces.Message.Cloud), limit: 500)
|
||||
@@ -329,14 +337,31 @@ func _internal_searchMessages(account: Account, location: SearchMessagesLocation
|
||||
let remoteSearchResult: Signal<(Api.messages.Messages?, Api.messages.Messages?), NoError>
|
||||
switch location {
|
||||
case let .peer(peerId, fromId, tags, reactions, threadId, minDate, maxDate):
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat || forceLocal {
|
||||
return account.postbox.transaction { transaction -> (SearchMessagesResult, SearchMessagesState) in
|
||||
var readStates: [PeerId: CombinedPeerReadState] = [:]
|
||||
var threadInfo: [MessageId: MessageHistoryThreadData] = [:]
|
||||
if let readState = transaction.getCombinedPeerReadState(peerId) {
|
||||
readStates[peerId] = readState
|
||||
}
|
||||
let result = transaction.searchMessages(peerId: peerId, query: query, tags: tags)
|
||||
// MARK: Swiftgram
|
||||
var result: [Message] = []
|
||||
if forceLocal {
|
||||
transaction.withAllMessages(peerId: peerId, { message in
|
||||
if result.count >= limit {
|
||||
return false
|
||||
}
|
||||
if let tags = tags, message.tags != tags {
|
||||
return true
|
||||
}
|
||||
if message.text.contains(query) {
|
||||
result.append(message)
|
||||
}
|
||||
return true
|
||||
})
|
||||
} else {
|
||||
result = transaction.searchMessages(peerId: peerId, query: query, tags: tags)
|
||||
}
|
||||
|
||||
for message in result {
|
||||
for attribute in message.attributes {
|
||||
@@ -604,11 +629,13 @@ func _internal_searchMessages(account: Account, location: SearchMessagesLocation
|
||||
|
||||
if let result {
|
||||
switch result {
|
||||
case let .messagesSlice(_, _, _, _, searchFlood, _, _, _, _):
|
||||
case let .messagesSlice(messagesSliceData):
|
||||
let searchFlood = messagesSliceData.searchFlood
|
||||
if let searchFlood {
|
||||
transaction.updatePreferencesEntry(key: PreferencesKeys.globalPostSearchState(), { _ in
|
||||
switch searchFlood {
|
||||
case let .searchPostsFlood(_, totalDaily, remains, waitTill, starsAmount):
|
||||
case let .searchPostsFlood(searchPostsFloodData):
|
||||
let (_, totalDaily, remains, waitTill, starsAmount) = (searchPostsFloodData.flags, searchPostsFloodData.totalDaily, searchPostsFloodData.remains, searchPostsFloodData.waitTill, searchPostsFloodData.starsAmount)
|
||||
return PreferencesEntry(TelegramGlobalPostSearchState(
|
||||
totalFreeSearches: totalDaily,
|
||||
remainingFreeSearches: remains,
|
||||
@@ -673,12 +700,12 @@ func _internal_downloadMessage(accountPeerId: PeerId, postbox: Postbox, network:
|
||||
let signal: Signal<Api.messages.Messages, MTRpcError>
|
||||
if messageId.peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if let channel = apiInputChannel(peer) {
|
||||
signal = network.request(Api.functions.channels.getMessages(channel: channel, id: [Api.InputMessage.inputMessageID(id: messageId.id)]))
|
||||
signal = network.request(Api.functions.channels.getMessages(channel: channel, id: [Api.InputMessage.inputMessageID(.init(id: messageId.id))]))
|
||||
} else {
|
||||
signal = .complete()
|
||||
}
|
||||
} else {
|
||||
signal = network.request(Api.functions.messages.getMessages(id: [Api.InputMessage.inputMessageID(id: messageId.id)]))
|
||||
signal = network.request(Api.functions.messages.getMessages(id: [Api.InputMessage.inputMessageID(.init(id: messageId.id))]))
|
||||
}
|
||||
|
||||
return signal
|
||||
@@ -694,25 +721,29 @@ func _internal_downloadMessage(accountPeerId: PeerId, postbox: Postbox, network:
|
||||
let chats: [Api.Chat]
|
||||
let users: [Api.User]
|
||||
switch result {
|
||||
case let .channelMessages(_, _, _, _, apiMessages, apiTopics, apiChats, apiUsers):
|
||||
case let .channelMessages(channelMessagesData):
|
||||
let (_, _, _, _, apiMessages, apiTopics, apiChats, apiUsers) = (channelMessagesData.flags, channelMessagesData.pts, channelMessagesData.count, channelMessagesData.offsetIdOffset, channelMessagesData.messages, channelMessagesData.topics, channelMessagesData.chats, channelMessagesData.users)
|
||||
messages = apiMessages
|
||||
let _ = apiTopics
|
||||
chats = apiChats
|
||||
users = apiUsers
|
||||
case let .messages(apiMessages, _, apiChats, apiUsers):
|
||||
case let .messages(messagesData):
|
||||
let (apiMessages, _, apiChats, apiUsers) = (messagesData.messages, messagesData.topics, messagesData.chats, messagesData.users)
|
||||
messages = apiMessages
|
||||
chats = apiChats
|
||||
users = apiUsers
|
||||
case let .messagesSlice(_, _, _, _, _, apiMessages, _, apiChats, apiUsers):
|
||||
case let .messagesSlice(messagesSliceData):
|
||||
let (_, _, _, _, _, apiMessages, _, apiChats, apiUsers) = (messagesSliceData.flags, messagesSliceData.count, messagesSliceData.nextRate, messagesSliceData.offsetIdOffset, messagesSliceData.searchFlood, messagesSliceData.messages, messagesSliceData.topics, messagesSliceData.chats, messagesSliceData.users)
|
||||
messages = apiMessages
|
||||
chats = apiChats
|
||||
users = apiUsers
|
||||
case .messagesNotModified:
|
||||
case let .messagesNotModified(messagesNotModifiedData):
|
||||
let _ = messagesNotModifiedData.count
|
||||
messages = []
|
||||
chats = []
|
||||
users = []
|
||||
}
|
||||
|
||||
|
||||
let postboxSignal = postbox.transaction { transaction -> Message? in
|
||||
var peers: [PeerId: Peer] = [:]
|
||||
|
||||
@@ -762,12 +793,12 @@ func fetchRemoteMessage(accountPeerId: PeerId, postbox: Postbox, source: FetchMe
|
||||
}
|
||||
} else if id.peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
if let channel = peer.inputChannel {
|
||||
signal = source.request(Api.functions.channels.getMessages(channel: channel, id: [Api.InputMessage.inputMessageID(id: id.id)]))
|
||||
signal = source.request(Api.functions.channels.getMessages(channel: channel, id: [Api.InputMessage.inputMessageID(.init(id: id.id))]))
|
||||
} else {
|
||||
signal = .fail(MTRpcError(errorCode: 400, errorDescription: "Peer Not Found"))
|
||||
}
|
||||
} else if id.peerId.namespace == Namespaces.Peer.CloudUser || id.peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||
signal = source.request(Api.functions.messages.getMessages(id: [Api.InputMessage.inputMessageID(id: id.id)]))
|
||||
signal = source.request(Api.functions.messages.getMessages(id: [Api.InputMessage.inputMessageID(.init(id: id.id))]))
|
||||
} else {
|
||||
signal = .fail(MTRpcError(errorCode: 400, errorDescription: "Invalid Peer"))
|
||||
}
|
||||
@@ -785,25 +816,29 @@ func fetchRemoteMessage(accountPeerId: PeerId, postbox: Postbox, source: FetchMe
|
||||
let chats: [Api.Chat]
|
||||
let users: [Api.User]
|
||||
switch result {
|
||||
case let .channelMessages(_, _, _, _, apiMessages, apiTopics, apiChats, apiUsers):
|
||||
case let .channelMessages(channelMessagesData):
|
||||
let (_, _, _, _, apiMessages, apiTopics, apiChats, apiUsers) = (channelMessagesData.flags, channelMessagesData.pts, channelMessagesData.count, channelMessagesData.offsetIdOffset, channelMessagesData.messages, channelMessagesData.topics, channelMessagesData.chats, channelMessagesData.users)
|
||||
messages = apiMessages
|
||||
let _ = apiTopics
|
||||
chats = apiChats
|
||||
users = apiUsers
|
||||
case let .messages(apiMessages, _, apiChats, apiUsers):
|
||||
case let .messages(messagesData):
|
||||
let (apiMessages, _, apiChats, apiUsers) = (messagesData.messages, messagesData.topics, messagesData.chats, messagesData.users)
|
||||
messages = apiMessages
|
||||
chats = apiChats
|
||||
users = apiUsers
|
||||
case let .messagesSlice(_, _, _, _, _, apiMessages, _, apiChats, apiUsers):
|
||||
case let .messagesSlice(messagesSliceData):
|
||||
let (_, _, _, _, _, apiMessages, _, apiChats, apiUsers) = (messagesSliceData.flags, messagesSliceData.count, messagesSliceData.nextRate, messagesSliceData.offsetIdOffset, messagesSliceData.searchFlood, messagesSliceData.messages, messagesSliceData.topics, messagesSliceData.chats, messagesSliceData.users)
|
||||
messages = apiMessages
|
||||
chats = apiChats
|
||||
users = apiUsers
|
||||
case .messagesNotModified:
|
||||
case let .messagesNotModified(messagesNotModifiedData):
|
||||
let _ = messagesNotModifiedData.count
|
||||
messages = []
|
||||
chats = []
|
||||
users = []
|
||||
}
|
||||
|
||||
|
||||
return postbox.transaction { transaction -> Message? in
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
||||
@@ -856,13 +891,17 @@ func _internal_searchMessageIdByTimestamp(account: Account, peerId: PeerId, thre
|
||||
|> map { result -> MessageIndex? in
|
||||
let messages: [Api.Message]
|
||||
switch result {
|
||||
case let .messages(apiMessages, _, _, _):
|
||||
case let .messages(messagesData):
|
||||
let apiMessages = messagesData.messages
|
||||
messages = apiMessages
|
||||
case let .channelMessages(_, _, _, _, apiMessages, _, _, _):
|
||||
case let .channelMessages(channelMessagesData):
|
||||
let apiMessages = channelMessagesData.messages
|
||||
messages = apiMessages
|
||||
case let .messagesSlice(_, _, _, _, _, apiMessages, _, _, _):
|
||||
case let .messagesSlice(messagesSliceData):
|
||||
let apiMessages = messagesSliceData.messages
|
||||
messages = apiMessages
|
||||
case .messagesNotModified:
|
||||
case let .messagesNotModified(messagesNotModifiedData):
|
||||
let _ = messagesNotModifiedData.count
|
||||
messages = []
|
||||
}
|
||||
for message in messages {
|
||||
@@ -893,13 +932,17 @@ func _internal_searchMessageIdByTimestamp(account: Account, peerId: PeerId, thre
|
||||
|> map { result -> MessageIndex? in
|
||||
let messages: [Api.Message]
|
||||
switch result {
|
||||
case let .messages(apiMessages, _, _, _):
|
||||
case let .messages(messagesData):
|
||||
let apiMessages = messagesData.messages
|
||||
messages = apiMessages
|
||||
case let .channelMessages(_, _, _, _, apiMessages, _, _, _):
|
||||
case let .channelMessages(channelMessagesData):
|
||||
let apiMessages = channelMessagesData.messages
|
||||
messages = apiMessages
|
||||
case let .messagesSlice(_, _, _, _, _, apiMessages, _, _, _):
|
||||
case let .messagesSlice(messagesSliceData):
|
||||
let apiMessages = messagesSliceData.messages
|
||||
messages = apiMessages
|
||||
case .messagesNotModified:
|
||||
case let .messagesNotModified(messagesNotModifiedData):
|
||||
let _ = messagesNotModifiedData.count
|
||||
messages = []
|
||||
}
|
||||
for message in messages {
|
||||
@@ -926,13 +969,17 @@ func _internal_searchMessageIdByTimestamp(account: Account, peerId: PeerId, thre
|
||||
|> map { result -> MessageIndex? in
|
||||
let messages: [Api.Message]
|
||||
switch result {
|
||||
case let .messages(apiMessages, _, _, _):
|
||||
case let .messages(messagesData):
|
||||
let apiMessages = messagesData.messages
|
||||
messages = apiMessages
|
||||
case let .channelMessages(_, _, _, _, apiMessages, _, _, _):
|
||||
case let .channelMessages(channelMessagesData):
|
||||
let apiMessages = channelMessagesData.messages
|
||||
messages = apiMessages
|
||||
case let .messagesSlice(_, _, _, _, _, apiMessages, _, _, _):
|
||||
case let .messagesSlice(messagesSliceData):
|
||||
let apiMessages = messagesSliceData.messages
|
||||
messages = apiMessages
|
||||
case .messagesNotModified:
|
||||
case let .messagesNotModified(messagesNotModifiedData):
|
||||
let _ = messagesNotModifiedData.count
|
||||
messages = []
|
||||
}
|
||||
for message in messages {
|
||||
@@ -950,13 +997,17 @@ func _internal_searchMessageIdByTimestamp(account: Account, peerId: PeerId, thre
|
||||
|> map { result -> MessageIndex? in
|
||||
let messages: [Api.Message]
|
||||
switch result {
|
||||
case let .messages(apiMessages, _, _, _):
|
||||
case let .messages(messagesData):
|
||||
let apiMessages = messagesData.messages
|
||||
messages = apiMessages
|
||||
case let .channelMessages(_, _, _, _, apiMessages, _, _, _):
|
||||
case let .channelMessages(channelMessagesData):
|
||||
let apiMessages = channelMessagesData.messages
|
||||
messages = apiMessages
|
||||
case let .messagesSlice(_, _, _, _, _, apiMessages, _, _, _):
|
||||
case let .messagesSlice(messagesSliceData):
|
||||
let apiMessages = messagesSliceData.messages
|
||||
messages = apiMessages
|
||||
case .messagesNotModified:
|
||||
case let .messagesNotModified(messagesNotModifiedData):
|
||||
let _ = messagesNotModifiedData.count
|
||||
messages = []
|
||||
}
|
||||
for message in messages {
|
||||
@@ -1031,14 +1082,16 @@ func _internal_updatedRemotePeer(accountPeerId: PeerId, postbox: Postbox, networ
|
||||
return postbox.transaction { transaction -> Signal<Peer, UpdatedRemotePeerError> in
|
||||
let chats: [Api.Chat]
|
||||
switch result {
|
||||
case let .chats(c):
|
||||
case let .chats(chatsData):
|
||||
let c = chatsData.chats
|
||||
chats = c
|
||||
case let .chatsSlice(_, c):
|
||||
case let .chatsSlice(chatsSliceData):
|
||||
let c = chatsSliceData.chats
|
||||
chats = c
|
||||
}
|
||||
|
||||
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: [])
|
||||
|
||||
|
||||
if let firstId = chats.first?.peerId, let updatedPeer = parsedPeers.get(firstId), updatedPeer.id == peer.id {
|
||||
return postbox.transaction { transaction -> Peer in
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
||||
@@ -1062,9 +1115,11 @@ func _internal_updatedRemotePeer(accountPeerId: PeerId, postbox: Postbox, networ
|
||||
return postbox.transaction { transaction -> Signal<Peer, UpdatedRemotePeerError> in
|
||||
let chats: [Api.Chat]
|
||||
switch result {
|
||||
case let .chats(c):
|
||||
case let .chats(chatsData):
|
||||
let c = chatsData.chats
|
||||
chats = c
|
||||
case let .chatsSlice(_, c):
|
||||
case let .chatsSlice(chatsSliceData):
|
||||
let c = chatsSliceData.chats
|
||||
chats = c
|
||||
}
|
||||
|
||||
@@ -1102,7 +1157,8 @@ func _internal_refreshGlobalPostSearchState(account: Account) -> Signal<Never, N
|
||||
}
|
||||
transaction.updatePreferencesEntry(key: PreferencesKeys.globalPostSearchState(), { _ in
|
||||
switch result {
|
||||
case let .searchPostsFlood(_, totalDaily, remains, waitTill, starsAmount):
|
||||
case let .searchPostsFlood(searchPostsFloodData):
|
||||
let (_, totalDaily, remains, waitTill, starsAmount) = (searchPostsFloodData.flags, searchPostsFloodData.totalDaily, searchPostsFloodData.remains, searchPostsFloodData.waitTill, searchPostsFloodData.starsAmount)
|
||||
return PreferencesEntry(TelegramGlobalPostSearchState(
|
||||
totalFreeSearches: totalDaily,
|
||||
remainingFreeSearches: remains,
|
||||
|
||||
@@ -130,25 +130,29 @@ func _internal_peerSendAsAvailablePeers(accountPeerId: PeerId, network: Network,
|
||||
return .single([])
|
||||
}
|
||||
switch result {
|
||||
case let .sendAsPeers(sendAsPeers, chats, _):
|
||||
case let .sendAsPeers(sendAsPeersData):
|
||||
let (sendAsPeers, chats) = (sendAsPeersData.peers, sendAsPeersData.chats)
|
||||
return postbox.transaction { transaction -> [SendAsPeer] in
|
||||
var subscribers: [PeerId: Int32] = [:]
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: [])
|
||||
|
||||
|
||||
var premiumRequiredPeerIds = Set<PeerId>()
|
||||
for sendAsPeer in sendAsPeers {
|
||||
if case let .sendAsPeer(flags, peer) = sendAsPeer, (flags & (1 << 0)) != 0 {
|
||||
if case let .sendAsPeer(sendAsPeerData) = sendAsPeer, (sendAsPeerData.flags & (1 << 0)) != 0 {
|
||||
let peer = sendAsPeerData.peer
|
||||
premiumRequiredPeerIds.insert(peer.peerId)
|
||||
}
|
||||
}
|
||||
for chat in chats {
|
||||
if let groupOrChannel = parsedPeers.get(chat.peerId) {
|
||||
switch chat {
|
||||
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _):
|
||||
case let .channel(channelData):
|
||||
let participantsCount = channelData.participantsCount
|
||||
if let participantsCount = participantsCount {
|
||||
subscribers[groupOrChannel.id] = participantsCount
|
||||
}
|
||||
case let .chat(_, _, _, _, participantsCount, _, _, _, _, _):
|
||||
case let .chat(chatData):
|
||||
let participantsCount = chatData.participantsCount
|
||||
subscribers[groupOrChannel.id] = participantsCount
|
||||
default:
|
||||
break
|
||||
@@ -286,25 +290,29 @@ func _internal_liveStorySendAsAvailablePeers(account: Account, peerId: PeerId) -
|
||||
return .single([])
|
||||
}
|
||||
switch result {
|
||||
case let .sendAsPeers(sendAsPeers, chats, _):
|
||||
case let .sendAsPeers(sendAsPeersData):
|
||||
let (sendAsPeers, chats) = (sendAsPeersData.peers, sendAsPeersData.chats)
|
||||
return account.postbox.transaction { transaction -> [SendAsPeer] in
|
||||
var subscribers: [PeerId: Int32] = [:]
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: [])
|
||||
|
||||
|
||||
var premiumRequiredPeerIds = Set<PeerId>()
|
||||
for sendAsPeer in sendAsPeers {
|
||||
if case let .sendAsPeer(flags, peer) = sendAsPeer, (flags & (1 << 0)) != 0 {
|
||||
if case let .sendAsPeer(sendAsPeerData) = sendAsPeer, (sendAsPeerData.flags & (1 << 0)) != 0 {
|
||||
let peer = sendAsPeerData.peer
|
||||
premiumRequiredPeerIds.insert(peer.peerId)
|
||||
}
|
||||
}
|
||||
for chat in chats {
|
||||
if let groupOrChannel = parsedPeers.get(chat.peerId) {
|
||||
switch chat {
|
||||
case let .channel(_, _, _, _, _, _, _, _, _, _, _, _, participantsCount, _, _, _, _, _, _, _, _, _, _):
|
||||
case let .channel(channelData):
|
||||
let participantsCount = channelData.participantsCount
|
||||
if let participantsCount = participantsCount {
|
||||
subscribers[groupOrChannel.id] = participantsCount
|
||||
}
|
||||
case let .chat(_, _, _, _, participantsCount, _, _, _, _, _):
|
||||
case let .chat(chatData):
|
||||
let participantsCount = chatData.participantsCount
|
||||
subscribers[groupOrChannel.id] = participantsCount
|
||||
default:
|
||||
break
|
||||
|
||||
@@ -86,13 +86,14 @@ public final class SparseMessageList {
|
||||
}
|
||||
private let loadHoleDisposable = MetaDisposable()
|
||||
private var loadingHole: LoadingHole?
|
||||
private var isLoadingInitial: Bool = false
|
||||
|
||||
private var loadingPlaceholders: [MessageId: Disposable] = [:]
|
||||
private var loadedPlaceholders: [MessageId: Message] = [:]
|
||||
|
||||
let statePromise = Promise<SparseMessageList.State>()
|
||||
|
||||
init(queue: Queue, account: Account, peerId: PeerId, threadId: Int64?, messageTag: MessageTags) {
|
||||
init(queue: Queue, account: Account, peerId: PeerId, threadId: Int64?, messageTag: MessageTags, initialMessageIndex: MessageIndex?) {
|
||||
self.queue = queue
|
||||
self.account = account
|
||||
self.peerId = peerId
|
||||
@@ -102,6 +103,11 @@ public final class SparseMessageList {
|
||||
self.resetTopSection()
|
||||
|
||||
if self.threadId == nil {
|
||||
if initialMessageIndex != nil {
|
||||
self.isLoadingInitial = true
|
||||
self.updateState()
|
||||
}
|
||||
|
||||
self.sparseItemsDisposable = (self.account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
@@ -112,19 +118,21 @@ public final class SparseMessageList {
|
||||
guard let messageFilter = messageFilterForTagMask(messageTag) else {
|
||||
return .single(SparseItems(items: []))
|
||||
}
|
||||
//TODO:api
|
||||
|
||||
return account.network.request(Api.functions.messages.getSearchResultsPositions(flags: 0, peer: inputPeer, savedPeerId: nil, filter: messageFilter, offsetId: 0, limit: 1000))
|
||||
|> map { result -> SparseItems in
|
||||
switch result {
|
||||
case let .searchResultsPositions(totalCount, positions):
|
||||
case let .searchResultsPositions(searchResultsPositionsData):
|
||||
let (totalCount, apiPositions) = (searchResultsPositionsData.count, searchResultsPositionsData.positions)
|
||||
struct Position: Equatable {
|
||||
var id: Int32
|
||||
var date: Int32
|
||||
var offset: Int
|
||||
}
|
||||
var positions: [Position] = positions.map { position -> Position in
|
||||
var positions: [Position] = apiPositions.map { position -> Position in
|
||||
switch position {
|
||||
case let .searchResultPosition(id, date, offset):
|
||||
case let .searchResultPosition(searchResultPositionData):
|
||||
let (id, date, offset) = (searchResultPositionData.msgId, searchResultPositionData.date, searchResultPositionData.offset)
|
||||
return Position(id: id, date: date, offset: Int(offset))
|
||||
}
|
||||
}
|
||||
@@ -134,7 +142,11 @@ public final class SparseMessageList {
|
||||
|
||||
var result = SparseItems(items: [])
|
||||
for i in 0 ..< positions.count {
|
||||
if i != 0 {
|
||||
if i == 0 {
|
||||
if initialMessageIndex != nil && positions[i].offset != 0 {
|
||||
result.items.append(.range(count: positions[i].offset))
|
||||
}
|
||||
} else {
|
||||
let deltaCount = positions[i].offset - 1 - positions[i - 1].offset
|
||||
if deltaCount > 0 {
|
||||
result.items.append(.range(count: deltaCount))
|
||||
@@ -160,9 +172,34 @@ public final class SparseMessageList {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.isLoadingInitial = false
|
||||
strongSelf.sparseItems = sparseItems
|
||||
if strongSelf.topSection != nil {
|
||||
strongSelf.updateState()
|
||||
if let initialMessageIndex {
|
||||
var loadHoleAnchor: MessageId?
|
||||
loop: for item in sparseItems.items {
|
||||
switch item {
|
||||
case let .anchor(id, timestamp, _):
|
||||
let anchorIndex = MessageIndex(id: id, timestamp: timestamp)
|
||||
if anchorIndex <= initialMessageIndex {
|
||||
loadHoleAnchor = id
|
||||
break loop
|
||||
}
|
||||
case .range:
|
||||
break
|
||||
}
|
||||
}
|
||||
if let loadHoleAnchor {
|
||||
strongSelf.loadHole(anchor: loadHoleAnchor, direction: .around, completion: {
|
||||
})
|
||||
} else {
|
||||
if strongSelf.topSection != nil {
|
||||
strongSelf.updateState()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if strongSelf.topSection != nil {
|
||||
strongSelf.updateState()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -591,10 +628,22 @@ public final class SparseMessageList {
|
||||
if self.topSection != topSection {
|
||||
self.topSection = topSection
|
||||
}
|
||||
self.updateState()
|
||||
if self.loadingHole == nil && !self.isLoadingInitial {
|
||||
self.updateState()
|
||||
}
|
||||
}
|
||||
|
||||
private func updateState() {
|
||||
if self.isLoadingInitial {
|
||||
self.statePromise.set(.single(SparseMessageList.State(
|
||||
items: [],
|
||||
totalCount: 0,
|
||||
isLoading: true
|
||||
)))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
var items: [SparseMessageList.State.Item] = []
|
||||
var minMessageId: MessageId?
|
||||
if let topSection = self.topSection {
|
||||
@@ -692,11 +741,11 @@ public final class SparseMessageList {
|
||||
}
|
||||
}
|
||||
|
||||
init(account: Account, peerId: PeerId, threadId: Int64?, messageTag: MessageTags) {
|
||||
init(account: Account, peerId: PeerId, threadId: Int64?, messageTag: MessageTags, initialMessageIndex: MessageIndex?) {
|
||||
self.queue = Queue()
|
||||
let queue = self.queue
|
||||
self.impl = QueueLocalObject(queue: queue, generate: {
|
||||
return Impl(queue: queue, account: account, peerId: peerId, threadId: threadId, messageTag: messageTag)
|
||||
return Impl(queue: queue, account: account, peerId: peerId, threadId: threadId, messageTag: messageTag, initialMessageIndex: initialMessageIndex)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -836,7 +885,8 @@ public final class SparseMessageCalendar {
|
||||
}
|
||||
|
||||
switch result {
|
||||
case let .searchResultsCalendar(_, _, minDate, minMsgId, _, periods, messages, chats, users):
|
||||
case let .searchResultsCalendar(searchResultsCalendarData):
|
||||
let (minDate, minMsgId, periods, messages, chats, users) = (searchResultsCalendarData.minDate, searchResultsCalendarData.minMsgId, searchResultsCalendarData.periods, searchResultsCalendarData.messages, searchResultsCalendarData.chats, searchResultsCalendarData.users)
|
||||
var parsedMessages: [StoreMessage] = []
|
||||
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||
@@ -854,7 +904,8 @@ public final class SparseMessageCalendar {
|
||||
var messagesByDay: [Int32: SparseMessageCalendar.Entry] = [:]
|
||||
for period in periods {
|
||||
switch period {
|
||||
case let .searchResultsCalendarPeriod(date, minMsgId, _, count):
|
||||
case let .searchResultsCalendarPeriod(searchResultsCalendarPeriodData):
|
||||
let (date, minMsgId, count) = (searchResultsCalendarPeriodData.date, searchResultsCalendarPeriodData.minMsgId, searchResultsCalendarPeriodData.count)
|
||||
if let message = transaction.getMessage(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: minMsgId)) {
|
||||
messagesByDay[date] = SparseMessageCalendar.Entry(message: message, count: Int(count))
|
||||
}
|
||||
|
||||
@@ -980,7 +980,7 @@ private func apiInputPrivacyRules(privacy: EngineStoryPrivacy, transaction: Tran
|
||||
privacyRules = [.inputPrivacyValueAllowCloseFriends]
|
||||
case .nobody:
|
||||
if privacy.additionallyIncludePeers.isEmpty {
|
||||
privacyRules = [.inputPrivacyValueAllowUsers(users: [.inputUserSelf])]
|
||||
privacyRules = [.inputPrivacyValueAllowUsers(.init(users: [.inputUserSelf]))]
|
||||
} else {
|
||||
privacyRules = []
|
||||
}
|
||||
@@ -1000,15 +1000,15 @@ private func apiInputPrivacyRules(privacy: EngineStoryPrivacy, transaction: Tran
|
||||
}
|
||||
if !privacyUsers.isEmpty {
|
||||
if case .contacts = privacy.base {
|
||||
privacyRules.append(.inputPrivacyValueDisallowUsers(users: privacyUsers))
|
||||
privacyRules.append(.inputPrivacyValueDisallowUsers(.init(users: privacyUsers)))
|
||||
} else if case .everyone = privacy.base {
|
||||
privacyRules.append(.inputPrivacyValueDisallowUsers(users: privacyUsers))
|
||||
privacyRules.append(.inputPrivacyValueDisallowUsers(.init(users: privacyUsers)))
|
||||
} else {
|
||||
privacyRules.append(.inputPrivacyValueAllowUsers(users: privacyUsers))
|
||||
privacyRules.append(.inputPrivacyValueAllowUsers(.init(users: privacyUsers)))
|
||||
}
|
||||
}
|
||||
if !privacyChats.isEmpty {
|
||||
privacyRules.append(.inputPrivacyValueAllowChatParticipants(chats: privacyChats))
|
||||
privacyRules.append(.inputPrivacyValueAllowChatParticipants(.init(chats: privacyChats)))
|
||||
}
|
||||
return privacyRules
|
||||
}
|
||||
@@ -1155,7 +1155,8 @@ func _internal_beginStoryLivestream(account: Account, peerId: EnginePeer.Id, rtm
|
||||
account.stateManager.addUpdates(updates)
|
||||
|
||||
for update in updates.allUpdates {
|
||||
if case let .updateStory(_, apiStory) = update, case .storyItem = apiStory {
|
||||
if case let .updateStory(updateStoryData) = update, case .storyItem = updateStoryData.story {
|
||||
let apiStory = updateStoryData.story
|
||||
return account.postbox.transaction { transaction in
|
||||
if let storedItem = Stories.StoredItem(apiStoryItem: apiStory, peerId: peerId, transaction: transaction), case let .item(item) = storedItem, let media = item.media {
|
||||
let mappedItem = EngineStoryItem(
|
||||
@@ -1389,9 +1390,11 @@ func _internal_uploadStoryImpl(
|
||||
var id: Int32?
|
||||
if let updates = updates {
|
||||
for update in updates.allUpdates {
|
||||
if case let .updateStory(_, story) = update {
|
||||
if case let .updateStory(updateStoryData) = update {
|
||||
let story = updateStoryData.story
|
||||
switch story {
|
||||
case let .storyItem(_, idValue, _, fromId, _, _, _, _, media, _, _, _, _, _):
|
||||
case let .storyItem(storyItemData):
|
||||
let (idValue, fromId, media) = (storyItemData.id, storyItemData.fromId, storyItemData.media)
|
||||
if let parsedStory = Stories.StoredItem(apiStoryItem: story, peerId: toPeerId, transaction: transaction) {
|
||||
var items = transaction.getStoryItems(peerId: toPeerId)
|
||||
var updatedItems: [Stories.Item] = []
|
||||
@@ -1521,7 +1524,8 @@ func _internal_uploadBotPreviewImpl(
|
||||
return .single(.completed(nil))
|
||||
}
|
||||
switch resultPreviewMedia {
|
||||
case let .botPreviewMedia(date, resultMedia):
|
||||
case let .botPreviewMedia(botPreviewMediaData):
|
||||
let (date, resultMedia) = (botPreviewMediaData.date, botPreviewMediaData.media)
|
||||
return postbox.transaction { transaction -> StoryUploadResult in
|
||||
var currentState: Stories.LocalState
|
||||
if let value = transaction.getLocalStoryState()?.get(Stories.LocalState.self) {
|
||||
@@ -1591,10 +1595,10 @@ func _internal_deleteBotPreviews(account: Account, peerId: PeerId, language: Str
|
||||
var inputMedia: [Api.InputMedia] = []
|
||||
for item in media {
|
||||
if let image = item as? TelegramMediaImage, let resource = image.representations.last?.resource as? CloudPhotoSizeMediaResource {
|
||||
inputMedia.append(.inputMediaPhoto(flags: 0, id: .inputPhoto(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference)), ttlSeconds: nil))
|
||||
inputMedia.append(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference)), ttlSeconds: nil))
|
||||
inputMedia.append(.inputMediaPhoto(.init(flags: 0, id: .inputPhoto(.init(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference))), ttlSeconds: nil)))
|
||||
inputMedia.append(Api.InputMedia.inputMediaPhoto(.init(flags: 0, id: Api.InputPhoto.inputPhoto(.init(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference))), ttlSeconds: nil)))
|
||||
} else if let file = item as? TelegramMediaFile, let resource = file.resource as? CloudDocumentMediaResource {
|
||||
inputMedia.append(.inputMediaDocument(flags: 0, id: .inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data())), videoCover: nil, videoTimestamp: nil, ttlSeconds: nil, query: nil))
|
||||
inputMedia.append(.inputMediaDocument(.init(flags: 0, id: .inputDocument(.init(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data()))), videoCover: nil, videoTimestamp: nil, ttlSeconds: nil, query: nil)))
|
||||
}
|
||||
}
|
||||
if language == nil {
|
||||
@@ -1649,10 +1653,10 @@ func _internal_deleteBotPreviewsLanguage(account: Account, peerId: PeerId, langu
|
||||
var inputMedia: [Api.InputMedia] = []
|
||||
for item in media {
|
||||
if let image = item as? TelegramMediaImage, let resource = image.representations.last?.resource as? CloudPhotoSizeMediaResource {
|
||||
inputMedia.append(.inputMediaPhoto(flags: 0, id: .inputPhoto(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference)), ttlSeconds: nil))
|
||||
inputMedia.append(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference)), ttlSeconds: nil))
|
||||
inputMedia.append(.inputMediaPhoto(.init(flags: 0, id: .inputPhoto(.init(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference))), ttlSeconds: nil)))
|
||||
inputMedia.append(Api.InputMedia.inputMediaPhoto(.init(flags: 0, id: Api.InputPhoto.inputPhoto(.init(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference))), ttlSeconds: nil)))
|
||||
} else if let file = item as? TelegramMediaFile, let resource = file.resource as? CloudDocumentMediaResource {
|
||||
inputMedia.append(.inputMediaDocument(flags: 0, id: .inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data())), videoCover: nil, videoTimestamp: nil, ttlSeconds: nil, query: nil))
|
||||
inputMedia.append(.inputMediaDocument(.init(flags: 0, id: .inputDocument(.init(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data()))), videoCover: nil, videoTimestamp: nil, ttlSeconds: nil, query: nil)))
|
||||
}
|
||||
}
|
||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current -> CachedPeerData? in
|
||||
@@ -1717,7 +1721,7 @@ func _internal_editStory(account: Account, peerId: PeerId, id: Int32, media: Eng
|
||||
if let result = result, case let .content(uploadedContent) = result, case let .media(media, _) = uploadedContent.content {
|
||||
inputMedia = media
|
||||
} else if case let .existing(media) = media, let file = media as? TelegramMediaFile, let resource = file.resource as? CloudDocumentMediaResource {
|
||||
inputMedia = .inputMediaUploadedDocument(flags: 0, file: .inputFileStoryDocument(id: .inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference))), thumb: nil, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFileAttributes(file.attributes), stickers: nil, videoCover: nil, videoTimestamp: nil, ttlSeconds: nil)
|
||||
inputMedia = .inputMediaUploadedDocument(.init(flags: 0, file: .inputFileStoryDocument(.init(id: .inputDocument(.init(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference))))), thumb: nil, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFileAttributes(file.attributes), stickers: nil, videoCover: nil, videoTimestamp: nil, ttlSeconds: nil))
|
||||
updatingCoverTime = true
|
||||
} else {
|
||||
inputMedia = nil
|
||||
@@ -1779,9 +1783,11 @@ func _internal_editStory(account: Account, peerId: PeerId, id: Int32, media: Eng
|
||||
|> mapToSignal { updates -> Signal<StoryUploadResult, NoError> in
|
||||
if let updates = updates {
|
||||
for update in updates.allUpdates {
|
||||
if case let .updateStory(_, story) = update {
|
||||
if case let .updateStory(updateStoryData) = update {
|
||||
let story = updateStoryData.story
|
||||
switch story {
|
||||
case let .storyItem(_, _, _, _, _, _, _, _, media, _, _, _, _, _):
|
||||
case let .storyItem(storyItemData):
|
||||
let media = storyItemData.media
|
||||
let parsedMedia = textMediaAndExpirationTimerFromApiMedia(media, account.peerId).media
|
||||
if let parsedMedia = parsedMedia, let originalMedia = originalMedia {
|
||||
applyMediaResourceChanges(from: originalMedia, to: parsedMedia, postbox: account.postbox, force: false, skipPreviews: updatingCoverTime)
|
||||
@@ -1921,7 +1927,8 @@ func _internal_checkStoriesUploadAvailability(account: Account, target: Stories.
|
||||
return account.network.request(Api.functions.stories.canSendStory(peer: inputPeer))
|
||||
|> map { result -> StoriesUploadAvailability in
|
||||
switch result {
|
||||
case let .canSendStoryCount(countRemains):
|
||||
case let .canSendStoryCount(canSendStoryCountData):
|
||||
let countRemains = canSendStoryCountData.countRemains
|
||||
return .available(remainingCount: countRemains)
|
||||
}
|
||||
}
|
||||
@@ -2146,11 +2153,14 @@ func _internal_updatePinnedToTopStories(account: Account, peerId: PeerId, ids: [
|
||||
extension Api.StoryItem {
|
||||
var id: Int32 {
|
||||
switch self {
|
||||
case let .storyItem(_, id, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
case let .storyItem(storyItemData):
|
||||
let id = storyItemData.id
|
||||
return id
|
||||
case let .storyItemDeleted(id):
|
||||
case let .storyItemDeleted(storyItemDeletedData):
|
||||
let id = storyItemDeletedData.id
|
||||
return id
|
||||
case let .storyItemSkipped(_, id, _, _):
|
||||
case let .storyItemSkipped(storyItemSkippedData):
|
||||
let id = storyItemSkippedData.id
|
||||
return id
|
||||
}
|
||||
}
|
||||
@@ -2159,7 +2169,8 @@ extension Api.StoryItem {
|
||||
extension Stories.Item.Views {
|
||||
init(apiViews: Api.StoryViews) {
|
||||
switch apiViews {
|
||||
case let .storyViews(flags, viewsCount, forwardsCount, reactions, reactionsCount, recentViewers):
|
||||
case let .storyViews(storyViewsData):
|
||||
let (flags, viewsCount, forwardsCount, reactions, reactionsCount, recentViewers) = (storyViewsData.flags, storyViewsData.viewsCount, storyViewsData.forwardsCount, storyViewsData.reactions, storyViewsData.reactionsCount, storyViewsData.recentViewers)
|
||||
//storyViews#8d595cd6 flags:# has_viewers:flags.1?true views_count:int forwards_count:flags.2?int reactions:flags.3?Vector<ReactionCount> reactions_count:flags.4?int recent_viewers:flags.0?Vector<long> = StoryViews;
|
||||
let hasList = (flags & (1 << 1)) != 0
|
||||
var seenPeerIds: [PeerId] = []
|
||||
@@ -2170,7 +2181,8 @@ extension Stories.Item.Views {
|
||||
if let reactions = reactions {
|
||||
for result in reactions {
|
||||
switch result {
|
||||
case let .reactionCount(_, chosenOrder, reaction, count):
|
||||
case let .reactionCount(reactionCountData):
|
||||
let (chosenOrder, reaction, count) = (reactionCountData.chosenOrder, reactionCountData.reaction, reactionCountData.count)
|
||||
if let reaction = MessageReaction.Reaction(apiReaction: reaction) {
|
||||
mappedReactions.append(MessageReaction(value: reaction, count: count, chosenOrder: chosenOrder.flatMap(Int.init)))
|
||||
}
|
||||
@@ -2192,7 +2204,8 @@ extension Stories.Item.Views {
|
||||
extension Stories.Item.ForwardInfo {
|
||||
init?(apiForwardInfo: Api.StoryFwdHeader) {
|
||||
switch apiForwardInfo {
|
||||
case let .storyFwdHeader(flags, from, fromName, storyId):
|
||||
case let .storyFwdHeader(storyFwdHeaderData):
|
||||
let (flags, from, fromName, storyId) = (storyFwdHeaderData.flags, storyFwdHeaderData.from, storyFwdHeaderData.fromName, storyFwdHeaderData.storyId)
|
||||
let isModified = (flags & (1 << 3)) != 0
|
||||
if let from = from, let storyId = storyId {
|
||||
self = .known(peerId: from.peerId, storyId: storyId, isModified: isModified)
|
||||
@@ -2209,7 +2222,8 @@ extension Stories.Item.ForwardInfo {
|
||||
extension Stories.StoredItem {
|
||||
init?(apiStoryItem: Api.StoryItem, existingItem: Stories.Item? = nil, peerId: PeerId, transaction: Transaction) {
|
||||
switch apiStoryItem {
|
||||
case let .storyItem(flags, id, date, fromId, forwardFrom, expireDate, caption, entities, media, mediaAreas, privacy, views, sentReaction, albums):
|
||||
case let .storyItem(storyItemData):
|
||||
let (flags, id, date, fromId, forwardFrom, expireDate, caption, entities, media, mediaAreas, privacy, views, sentReaction, albums) = (storyItemData.flags, storyItemData.id, storyItemData.date, storyItemData.fromId, storyItemData.fwdFrom, storyItemData.expireDate, storyItemData.caption, storyItemData.entities, storyItemData.media, storyItemData.mediaAreas, storyItemData.privacy, storyItemData.views, storyItemData.sentReaction, storyItemData.albums)
|
||||
var folderIds: [Int64]?
|
||||
if let albums {
|
||||
folderIds = albums.map(Int64.init)
|
||||
@@ -2233,15 +2247,18 @@ extension Stories.StoredItem {
|
||||
base = .everyone
|
||||
case .privacyValueDisallowAll:
|
||||
base = .nobody
|
||||
case let .privacyValueAllowUsers(users):
|
||||
case let .privacyValueAllowUsers(privacyValueAllowUsersData):
|
||||
let users = privacyValueAllowUsersData.users
|
||||
for id in users {
|
||||
additionalPeerIds.append(EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(id)))
|
||||
}
|
||||
case let .privacyValueDisallowUsers(users):
|
||||
case let .privacyValueDisallowUsers(privacyValueDisallowUsersData):
|
||||
let users = privacyValueDisallowUsersData.users
|
||||
for id in users {
|
||||
additionalPeerIds.append(EnginePeer.Id(namespace: Namespaces.Peer.CloudUser, id: EnginePeer.Id.Id._internalFromInt64Value(id)))
|
||||
}
|
||||
case let .privacyValueAllowChatParticipants(chats):
|
||||
case let .privacyValueAllowChatParticipants(privacyValueAllowChatParticipantsData):
|
||||
let chats = privacyValueAllowChatParticipantsData.chats
|
||||
for id in chats {
|
||||
if let peer = transaction.getPeer(EnginePeer.Id(namespace: Namespaces.Peer.CloudGroup, id: EnginePeer.Id.Id._internalFromInt64Value(id))) {
|
||||
additionalPeerIds.append(peer.id)
|
||||
@@ -2296,7 +2313,8 @@ extension Stories.StoredItem {
|
||||
|
||||
var parsedAlternativeMedia: [Media] = []
|
||||
switch media {
|
||||
case let .messageMediaDocument(_, _, altDocuments, _, _, _):
|
||||
case let .messageMediaDocument(messageMediaDocumentData):
|
||||
let altDocuments = messageMediaDocumentData.altDocuments
|
||||
if let altDocuments {
|
||||
parsedAlternativeMedia = altDocuments.compactMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }
|
||||
}
|
||||
@@ -2333,7 +2351,8 @@ extension Stories.StoredItem {
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case let .storyItemSkipped(flags, id, date, expireDate):
|
||||
case let .storyItemSkipped(storyItemSkippedData):
|
||||
let (flags, id, date, expireDate) = (storyItemSkippedData.flags, storyItemSkippedData.id, storyItemSkippedData.date, storyItemSkippedData.expireDate)
|
||||
let isCloseFriends = (flags & (1 << 8)) != 0
|
||||
let isLiveItem = (flags & (1 << 9)) != 0
|
||||
self = .placeholder(Stories.Placeholder(id: id, timestamp: date, expirationTimestamp: expireDate, isCloseFriends: isCloseFriends, isLiveItem: isLiveItem))
|
||||
@@ -2363,9 +2382,10 @@ func _internal_getStoryById(accountPeerId: PeerId, postbox: Postbox, network: Ne
|
||||
}
|
||||
return postbox.transaction { transaction -> EngineStoryItem? in
|
||||
switch result {
|
||||
case let .stories(_, _, stories, _, chats, users):
|
||||
case let .stories(storiesData):
|
||||
let (stories, chats, users) = (storiesData.stories, storiesData.chats, storiesData.users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: AccumulatedPeers(transaction: transaction, chats: chats, users: users))
|
||||
|
||||
|
||||
if let storyItem = stories.first.flatMap({ Stories.StoredItem(apiStoryItem: $0, peerId: peerId, transaction: transaction) }) {
|
||||
if let entry = CodableEntry(storyItem) {
|
||||
transaction.setStory(id: storyId, value: entry)
|
||||
@@ -2431,9 +2451,10 @@ func _internal_getStoriesById(accountPeerId: PeerId, postbox: Postbox, network:
|
||||
}
|
||||
return postbox.transaction { transaction -> [Stories.StoredItem] in
|
||||
switch result {
|
||||
case let .stories(_, _, stories, _, chats, users):
|
||||
case let .stories(storiesData):
|
||||
let (stories, chats, users) = (storiesData.stories, storiesData.chats, storiesData.users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: AccumulatedPeers(transaction: transaction, chats: chats, users: users))
|
||||
|
||||
|
||||
return stories.compactMap { apiStoryItem -> Stories.StoredItem? in
|
||||
return Stories.StoredItem(apiStoryItem: apiStoryItem, peerId: peer.id, transaction: transaction)
|
||||
}
|
||||
@@ -2462,9 +2483,10 @@ func _internal_getStoriesById(accountPeerId: PeerId, postbox: Postbox, source: F
|
||||
}
|
||||
return postbox.transaction { transaction -> [Stories.StoredItem]? in
|
||||
switch result {
|
||||
case let .stories(_, _, stories, _, chats, users):
|
||||
case let .stories(storiesData):
|
||||
let (stories, chats, users) = (storiesData.stories, storiesData.chats, storiesData.users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: AccumulatedPeers(transaction: transaction, chats: chats, users: users))
|
||||
|
||||
|
||||
return stories.compactMap { apiStoryItem -> Stories.StoredItem? in
|
||||
return Stories.StoredItem(apiStoryItem: apiStoryItem, peerId: peerId, transaction: transaction)
|
||||
}
|
||||
@@ -2518,7 +2540,8 @@ func _internal_getStoryViews(account: Account, peerId: PeerId, ids: [Int32]) ->
|
||||
return account.postbox.transaction { transaction -> [Int32: Stories.Item.Views] in
|
||||
var parsedViews: [Int32: Stories.Item.Views] = [:]
|
||||
switch result {
|
||||
case let .storyViews(views, users):
|
||||
case let .storyViews(storyViewsData):
|
||||
let (views, users) = (storyViewsData.views, storyViewsData.users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: AccumulatedPeers(users: users))
|
||||
|
||||
for i in 0 ..< views.count {
|
||||
@@ -2587,7 +2610,8 @@ func _internal_exportStoryLink(account: Account, peerId: EnginePeer.Id, id: Int3
|
||||
return nil
|
||||
}
|
||||
switch result {
|
||||
case let .exportedStoryLink(link):
|
||||
case let .exportedStoryLink(exportedStoryLinkData):
|
||||
let link = exportedStoryLinkData.link
|
||||
return link
|
||||
}
|
||||
}
|
||||
@@ -2645,7 +2669,8 @@ func _internal_refreshSeenStories(postbox: Postbox, network: Network) -> Signal<
|
||||
return postbox.transaction { transaction -> Void in
|
||||
for update in updates.allUpdates {
|
||||
switch update {
|
||||
case let .updateReadStories(peerIdValue, maxId):
|
||||
case let .updateReadStories(updateReadStoriesData):
|
||||
let (peerIdValue, maxId) = (updateReadStoriesData.peer, updateReadStoriesData.maxId)
|
||||
let peerId = peerIdValue.peerId
|
||||
var update = false
|
||||
if let value = transaction.getPeerStoryState(peerId: peerId) {
|
||||
@@ -2693,7 +2718,8 @@ extension Stories.ConfigurationState {
|
||||
extension Stories.StealthModeState {
|
||||
init(apiMode: Api.StoriesStealthMode) {
|
||||
switch apiMode {
|
||||
case let .storiesStealthMode(_, activeUntilDate, cooldownUntilDate):
|
||||
case let .storiesStealthMode(storiesStealthModeData):
|
||||
let (activeUntilDate, cooldownUntilDate) = (storiesStealthModeData.activeUntilDate, storiesStealthModeData.cooldownUntilDate)
|
||||
self.init(
|
||||
activeUntilTimestamp: activeUntilDate,
|
||||
cooldownUntilTimestamp: cooldownUntilDate
|
||||
|
||||
@@ -402,7 +402,8 @@ public final class StorySubscriptionsContext {
|
||||
let _ = (self.postbox.transaction { transaction -> Void in
|
||||
var updatedStealthMode: Api.StoriesStealthMode?
|
||||
switch result {
|
||||
case let .allStoriesNotModified(_, state, stealthMode):
|
||||
case let .allStoriesNotModified(allStoriesNotModifiedData):
|
||||
let (state, stealthMode) = (allStoriesNotModifiedData.state, allStoriesNotModifiedData.stealthMode)
|
||||
self.loadedStateMark = .value(state)
|
||||
let (currentStateValue, _) = transaction.getAllStorySubscriptions(key: subscriptionsKey)
|
||||
let currentState = currentStateValue.flatMap { $0.get(Stories.SubscriptionsState.self) }
|
||||
@@ -421,7 +422,8 @@ public final class StorySubscriptionsContext {
|
||||
if isRefresh && !isHidden {
|
||||
updatedStealthMode = stealthMode
|
||||
}
|
||||
case let .allStories(flags, _, state, peerStories, chats, users, stealthMode):
|
||||
case let .allStories(allStoriesData):
|
||||
let (flags, state, peerStories, chats, users, stealthMode) = (allStoriesData.flags, allStoriesData.state, allStoriesData.peerStories, allStoriesData.chats, allStoriesData.users, allStoriesData.stealthMode)
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||
|
||||
let hasMore: Bool = (flags & (1 << 0)) != 0
|
||||
@@ -431,11 +433,12 @@ public final class StorySubscriptionsContext {
|
||||
|
||||
for peerStorySet in peerStories {
|
||||
switch peerStorySet {
|
||||
case let .peerStories(_, peerIdValue, maxReadId, stories):
|
||||
case let .peerStories(peerStoriesData):
|
||||
let (_, peerIdValue, maxReadId, stories) = (peerStoriesData.flags, peerStoriesData.peer, peerStoriesData.maxReadId, peerStoriesData.stories)
|
||||
let peerId = peerIdValue.peerId
|
||||
|
||||
|
||||
let previousPeerEntries: [StoryItemsTableEntry] = transaction.getStoryItems(peerId: peerId)
|
||||
|
||||
|
||||
var updatedPeerEntries: [StoryItemsTableEntry] = []
|
||||
for story in stories {
|
||||
if let storedItem = Stories.StoredItem(apiStoryItem: story, peerId: peerId, transaction: transaction) {
|
||||
@@ -889,10 +892,12 @@ public final class PeerStoryListContext: StoryListContext {
|
||||
|
||||
if let updatedFolders {
|
||||
switch updatedFolders {
|
||||
case let .albums(_, albums):
|
||||
case let .albums(albumsData):
|
||||
let albums = albumsData.albums
|
||||
for album in albums {
|
||||
switch album {
|
||||
case let .storyAlbum(_, albumId, title, iconPhoto, iconVideo):
|
||||
case let .storyAlbum(storyAlbumData):
|
||||
let (albumId, title, iconPhoto, iconVideo) = (storyAlbumData.albumId, storyAlbumData.title, storyAlbumData.iconPhoto, storyAlbumData.iconVideo)
|
||||
let _ = iconPhoto
|
||||
let _ = iconVideo
|
||||
folderItems.append(State.Folder(
|
||||
@@ -915,7 +920,8 @@ public final class PeerStoryListContext: StoryListContext {
|
||||
}
|
||||
|
||||
switch result {
|
||||
case let .stories(_, count, stories, pinnedStories, chats, users):
|
||||
case let .stories(storiesData):
|
||||
let (count, stories, pinnedStories, chats, users) = (storiesData.count, storiesData.stories, storiesData.pinnedToTop, storiesData.chats, storiesData.users)
|
||||
totalCount = Int(count)
|
||||
hasMore = stories.count >= limit
|
||||
|
||||
@@ -1410,7 +1416,8 @@ public final class PeerStoryListContext: StoryListContext {
|
||||
}
|
||||
if let result {
|
||||
switch result {
|
||||
case let .storyAlbum(_, albumId, _, _, _):
|
||||
case let .storyAlbum(storyAlbumData):
|
||||
let albumId = storyAlbumData.albumId
|
||||
var state = self.stateValue
|
||||
state.availableFolders.append(StoryListContextState.Folder(id: Int64(albumId), title: title))
|
||||
self.stateValue = state
|
||||
@@ -1914,7 +1921,8 @@ public final class PeerStoryListContext: StoryListContext {
|
||||
}).start(next: { result in
|
||||
if let result {
|
||||
switch result {
|
||||
case let .storyAlbum(_, albumId, _, _, _):
|
||||
case let .storyAlbum(storyAlbumData):
|
||||
let albumId = storyAlbumData.albumId
|
||||
let _ = (account.postbox.transaction { transaction -> Void in
|
||||
let key = ValueBoxKey(length: 8 + 1)
|
||||
key.setInt64(0, value: peerId.toInt64())
|
||||
@@ -2146,7 +2154,8 @@ public final class SearchStoryListContext: StoryListContext {
|
||||
var nextOffsetValue: String?
|
||||
|
||||
switch result {
|
||||
case let .foundStories(_, count, stories, nextOffset, chats, users):
|
||||
case let .foundStories(foundStoriesData):
|
||||
let (count, stories, nextOffset, chats, users) = (foundStoriesData.count, foundStoriesData.stories, foundStoriesData.nextOffset, foundStoriesData.chats, foundStoriesData.users)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: AccumulatedPeers(transaction: transaction, chats: chats, users: users))
|
||||
|
||||
totalCount = Int(count)
|
||||
@@ -2154,7 +2163,8 @@ public final class SearchStoryListContext: StoryListContext {
|
||||
|
||||
for story in stories {
|
||||
switch story {
|
||||
case let .foundStory(peer, story):
|
||||
case let .foundStory(foundStoryData):
|
||||
let (peer, story) = (foundStoryData.peer, foundStoryData.story)
|
||||
if let storedItem = Stories.StoredItem(apiStoryItem: story, peerId: peer.peerId, transaction: transaction) {
|
||||
if case let .item(item) = storedItem, let media = item.media {
|
||||
let mappedItem = EngineStoryItem(
|
||||
@@ -2593,15 +2603,17 @@ public final class PeerExpiringStoryListContext {
|
||||
var updatedPeerEntries: [StoryItemsTableEntry] = []
|
||||
updatedPeerEntries.removeAll()
|
||||
|
||||
if let result = result, case let .peerStories(stories, chats, users) = result {
|
||||
if let result = result, case let .peerStories(peerStoriesData) = result {
|
||||
let (stories, chats, users) = (peerStoriesData.stories, peerStoriesData.chats, peerStoriesData.users)
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||
|
||||
|
||||
switch stories {
|
||||
case let .peerStories(_, peerIdValue, maxReadId, stories):
|
||||
case let .peerStories(peerStoriesData):
|
||||
let (_, peerIdValue, maxReadId, stories) = (peerStoriesData.flags, peerStoriesData.peer, peerStoriesData.maxReadId, peerStoriesData.stories)
|
||||
let peerId = peerIdValue.peerId
|
||||
|
||||
|
||||
let previousPeerEntries: [StoryItemsTableEntry] = transaction.getStoryItems(peerId: peerId)
|
||||
|
||||
|
||||
for story in stories {
|
||||
if let storedItem = Stories.StoredItem(apiStoryItem: story, peerId: peerId, transaction: transaction) {
|
||||
if case .placeholder = storedItem, let previousEntry = previousPeerEntries.first(where: { $0.id == storedItem.id }) {
|
||||
@@ -2613,15 +2625,15 @@ public final class PeerExpiringStoryListContext {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
transaction.setPeerStoryState(peerId: peerId, state: Stories.PeerState(
|
||||
maxReadId: maxReadId ?? 0
|
||||
).postboxRepresentation)
|
||||
}
|
||||
|
||||
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
||||
}
|
||||
|
||||
|
||||
transaction.setStoryItems(peerId: peerId, items: updatedPeerEntries)
|
||||
}
|
||||
|> ignoreValues
|
||||
@@ -2774,15 +2786,17 @@ public func _internal_pollPeerStories(postbox: Postbox, network: Network, accoun
|
||||
var updatedPeerEntries: [StoryItemsTableEntry] = []
|
||||
updatedPeerEntries.removeAll()
|
||||
|
||||
if let result = result, case let .peerStories(stories, chats, users) = result {
|
||||
if let result = result, case let .peerStories(peerStoriesData) = result {
|
||||
let (stories, chats, users) = (peerStoriesData.stories, peerStoriesData.chats, peerStoriesData.users)
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||
|
||||
|
||||
switch stories {
|
||||
case let .peerStories(_, peerIdValue, maxReadId, stories):
|
||||
case let .peerStories(peerStoriesData):
|
||||
let (_, peerIdValue, maxReadId, stories) = (peerStoriesData.flags, peerStoriesData.peer, peerStoriesData.maxReadId, peerStoriesData.stories)
|
||||
let peerId = peerIdValue.peerId
|
||||
|
||||
|
||||
let previousPeerEntries: [StoryItemsTableEntry] = transaction.getStoryItems(peerId: peerId)
|
||||
|
||||
|
||||
for story in stories {
|
||||
if let storedItem = Stories.StoredItem(apiStoryItem: story, peerId: peerId, transaction: transaction) {
|
||||
if case .placeholder = storedItem, let previousEntry = previousPeerEntries.first(where: { $0.id == storedItem.id }) {
|
||||
@@ -2794,17 +2808,17 @@ public func _internal_pollPeerStories(postbox: Postbox, network: Network, accoun
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
transaction.setPeerStoryState(peerId: peerId, state: Stories.PeerState(
|
||||
maxReadId: maxReadId ?? 0
|
||||
).postboxRepresentation)
|
||||
}
|
||||
|
||||
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
||||
}
|
||||
|
||||
|
||||
transaction.setStoryItems(peerId: peerId, items: updatedPeerEntries)
|
||||
|
||||
|
||||
var isContactOrMember = false
|
||||
if transaction.isPeerContact(peerId: peerId) {
|
||||
isContactOrMember = true
|
||||
@@ -3373,10 +3387,10 @@ public final class BotPreviewStoryListContext: StoryListContext {
|
||||
var inputMedia: [Api.InputMedia] = []
|
||||
for item in media {
|
||||
if let image = item as? TelegramMediaImage, let resource = image.representations.last?.resource as? CloudPhotoSizeMediaResource {
|
||||
inputMedia.append(.inputMediaPhoto(flags: 0, id: .inputPhoto(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference)), ttlSeconds: nil))
|
||||
inputMedia.append(Api.InputMedia.inputMediaPhoto(flags: 0, id: Api.InputPhoto.inputPhoto(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference)), ttlSeconds: nil))
|
||||
inputMedia.append(.inputMediaPhoto(.init(flags: 0, id: .inputPhoto(.init(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference))), ttlSeconds: nil)))
|
||||
inputMedia.append(Api.InputMedia.inputMediaPhoto(.init(flags: 0, id: Api.InputPhoto.inputPhoto(.init(id: resource.photoId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference))), ttlSeconds: nil)))
|
||||
} else if let file = item as? TelegramMediaFile, let resource = file.resource as? CloudDocumentMediaResource {
|
||||
inputMedia.append(.inputMediaDocument(flags: 0, id: .inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data())), videoCover: nil, videoTimestamp: nil, ttlSeconds: nil, query: nil))
|
||||
inputMedia.append(.inputMediaDocument(.init(flags: 0, id: .inputDocument(.init(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data()))), videoCover: nil, videoTimestamp: nil, ttlSeconds: nil, query: nil)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,8 @@ func _internal_summarizeMessage(account: Account, messageId: EngineMessage.Id, t
|
||||
|> mapToSignal { result -> Signal<Void, SummarizeError> in
|
||||
return account.postbox.transaction { transaction in
|
||||
switch result {
|
||||
case let .textWithEntities(text, entities):
|
||||
case let .textWithEntities(textWithEntitiesData):
|
||||
let (text, entities) = (textWithEntitiesData.text, textWithEntitiesData.entities)
|
||||
transaction.updateMessage(messageId, update: { currentMessage in
|
||||
let storeForwardInfo = currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init)
|
||||
var attributes = currentMessage.attributes
|
||||
|
||||
+95
-12
@@ -1,3 +1,4 @@
|
||||
import SGSimpleSettings
|
||||
import Foundation
|
||||
import SwiftSignalKit
|
||||
import Postbox
|
||||
@@ -96,15 +97,22 @@ public extension TelegramEngine {
|
||||
}
|
||||
|
||||
public func requestMessageActionUrlAuth(subject: MessageActionUrlSubject) -> Signal<MessageActionUrlAuthResult, NoError> {
|
||||
_internal_requestMessageActionUrlAuth(account: self.account, subject: subject)
|
||||
return _internal_requestMessageActionUrlAuth(account: self.account, subject: subject)
|
||||
}
|
||||
|
||||
public func acceptMessageActionUrlAuth(subject: MessageActionUrlSubject, allowWriteAccess: Bool) -> Signal<MessageActionUrlAuthResult, NoError> {
|
||||
return _internal_acceptMessageActionUrlAuth(account: self.account, subject: subject, allowWriteAccess: allowWriteAccess)
|
||||
public func acceptMessageActionUrlAuth(subject: MessageActionUrlSubject, allowWriteAccess: Bool, sharePhoneNumber: Bool) -> Signal<MessageActionUrlAuthResult, MessageActionUrlAuthError> {
|
||||
return _internal_acceptMessageActionUrlAuth(account: self.account, subject: subject, allowWriteAccess: allowWriteAccess, sharePhoneNumber: sharePhoneNumber)
|
||||
}
|
||||
|
||||
public func searchMessages(location: SearchMessagesLocation, query: String, state: SearchMessagesState?, centerId: MessageId? = nil, limit: Int32 = 100) -> Signal<(SearchMessagesResult, SearchMessagesState), NoError> {
|
||||
return _internal_searchMessages(account: self.account, location: location, query: query, state: state, centerId: centerId, limit: limit)
|
||||
// TODO(swiftgram): Try to fallback on error when searching. RX is hard...
|
||||
|> mapToSignal { result -> Signal<(SearchMessagesResult, SearchMessagesState), NoError> in
|
||||
if (result.0.totalCount > 0) {
|
||||
return .single(result)
|
||||
}
|
||||
return _internal_searchMessages(account: self.account, location: location, query: query, state: state, centerId: centerId, limit: limit, forceLocal: true)
|
||||
}
|
||||
}
|
||||
|
||||
public func getSearchMessageCount(location: SearchMessagesLocation, query: String) -> Signal<Int?, NoError> {
|
||||
@@ -399,8 +407,8 @@ public extension TelegramEngine {
|
||||
return _internal_updateStarsReactionPrivacy(account: self.account, messageId: id, privacy: privacy)
|
||||
}
|
||||
|
||||
public func requestChatContextResults(botId: PeerId, peerId: PeerId, query: String, location: Signal<(Double, Double)?, NoError> = .single(nil), offset: String, incompleteResults: Bool = false, staleCachedResults: Bool = false) -> Signal<RequestChatContextResultsResult?, RequestChatContextResultsError> {
|
||||
return _internal_requestChatContextResults(account: self.account, botId: botId, peerId: peerId, query: query, location: location, offset: offset, incompleteResults: incompleteResults, staleCachedResults: staleCachedResults)
|
||||
public func requestChatContextResults(IQTP: Bool = false, botId: PeerId, peerId: PeerId, query: String, location: Signal<(Double, Double)?, NoError> = .single(nil), offset: String, incompleteResults: Bool = false, staleCachedResults: Bool = false) -> Signal<RequestChatContextResultsResult?, RequestChatContextResultsError> {
|
||||
return _internal_requestChatContextResults(IQTP: IQTP, account: self.account, botId: botId, peerId: peerId, query: query, location: location, offset: offset, incompleteResults: incompleteResults, staleCachedResults: staleCachedResults)
|
||||
}
|
||||
|
||||
public func removeRecentlyUsedHashtag(string: String) -> Signal<Void, NoError> {
|
||||
@@ -495,8 +503,8 @@ public extension TelegramEngine {
|
||||
}
|
||||
}
|
||||
|
||||
public func sparseMessageList(peerId: EnginePeer.Id, threadId: Int64?, tag: EngineMessage.Tags) -> SparseMessageList {
|
||||
return SparseMessageList(account: self.account, peerId: peerId, threadId: threadId, messageTag: tag)
|
||||
public func sparseMessageList(peerId: EnginePeer.Id, threadId: Int64?, tag: EngineMessage.Tags, initialMessageIndex: MessageIndex? = nil) -> SparseMessageList {
|
||||
return SparseMessageList(account: self.account, peerId: peerId, threadId: threadId, messageTag: tag, initialMessageIndex: initialMessageIndex)
|
||||
}
|
||||
|
||||
public func sparseMessageCalendar(peerId: EnginePeer.Id, threadId: Int64?, tag: EngineMessage.Tags, displayMedia: Bool) -> SparseMessageCalendar {
|
||||
@@ -544,11 +552,14 @@ public extension TelegramEngine {
|
||||
signals.append(self.account.network.request(Api.functions.messages.search(flags: flags, peer: inputPeer, q: "", fromId: nil, savedPeerId: inputSavedPeer, savedReaction: nil, topMsgId: topMsgId, filter: filter, minDate: 0, maxDate: 0, offsetId: 0, addOffset: 0, limit: 1, maxId: 0, minId: 0, hash: 0))
|
||||
|> map { result -> (count: Int32?, topId: Int32?) in
|
||||
switch result {
|
||||
case let .messagesSlice(_, count, _, _, _, messages, _, _, _):
|
||||
case let .messagesSlice(messagesSliceData):
|
||||
let (count, messages) = (messagesSliceData.count, messagesSliceData.messages)
|
||||
return (count, messages.first?.id(namespace: Namespaces.Message.Cloud)?.id)
|
||||
case let .channelMessages(_, _, count, _, messages, _, _, _):
|
||||
case let .channelMessages(channelMessagesData):
|
||||
let (count, messages) = (channelMessagesData.count, channelMessagesData.messages)
|
||||
return (count, messages.first?.id(namespace: Namespaces.Message.Cloud)?.id)
|
||||
case let .messages(messages, _, _, _):
|
||||
case let .messages(messagesData):
|
||||
let messages = messagesData.messages
|
||||
return (Int32(messages.count), messages.first?.id(namespace: Namespaces.Message.Cloud)?.id)
|
||||
case .messagesNotModified:
|
||||
return (nil, nil)
|
||||
@@ -589,11 +600,16 @@ public extension TelegramEngine {
|
||||
}
|
||||
|
||||
public func translate(text: String, toLang: String, entities: [MessageTextEntity] = []) -> Signal<(String, [MessageTextEntity])?, TranslationError> {
|
||||
return _internal_translate(network: self.account.network, text: text, toLang: toLang, entities: entities)
|
||||
return sgWrappedTranslateSingle(text: text, toLang: toLang, default: _internal_translate(network: self.account.network, text: text, toLang: toLang, entities: entities))
|
||||
}
|
||||
|
||||
public func translate(texts: [(String, [MessageTextEntity])], toLang: String) -> Signal<[(String, [MessageTextEntity])], TranslationError> {
|
||||
return _internal_translateTexts(network: self.account.network, texts: texts, toLang: toLang)
|
||||
return sgWrappedTranslateMultiple(texts: texts,toLang: toLang, default: _internal_translateTexts(network: self.account.network, texts: texts, toLang: toLang))
|
||||
}
|
||||
|
||||
// MARK: Swiftgram
|
||||
public func translateMessagesViaText(messagesDict: [EngineMessage.Id: String], fromLang: String?, toLang: String, generateEntitiesFunction: @escaping (String) -> [MessageTextEntity], enableLocalIfPossible: Bool) -> Signal<Never, TranslationError> {
|
||||
return _internal_translateMessagesViaText(account: self.account, messagesDict: messagesDict, fromLang: fromLang, toLang: toLang, enableLocalIfPossible: enableLocalIfPossible, generateEntitiesFunction: generateEntitiesFunction)
|
||||
}
|
||||
|
||||
public func translateMessages(messageIds: [EngineMessage.Id], fromLang: String?, toLang: String, enableLocalIfPossible: Bool) -> Signal<Never, TranslationError> {
|
||||
@@ -1471,6 +1487,10 @@ public extension TelegramEngine {
|
||||
}
|
||||
|
||||
public func markStoryAsSeen(peerId: EnginePeer.Id, id: Int32, asPinned: Bool) -> Signal<Never, NoError> {
|
||||
// MARK: Swiftgram
|
||||
if SGSimpleSettings.shared.isStealthModeEnabled {
|
||||
return .never()
|
||||
}
|
||||
return _internal_markStoryAsSeen(account: self.account, peerId: peerId, id: id, asPinned: asPinned)
|
||||
}
|
||||
|
||||
@@ -1707,3 +1727,66 @@ func _internal_monoforumPerformSuggestedPostAction(account: Account, id: EngineM
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// MARK: Swiftgram
|
||||
private func sgWrappedTranslateSingle(
|
||||
text: String,
|
||||
toLang: String,
|
||||
`default`: Signal<(String, [MessageTextEntity])?, TranslationError>
|
||||
) -> Signal<(String, [MessageTextEntity])?, TranslationError> {
|
||||
if SGSimpleSettings.shared.translationBackend == SGSimpleSettings.TranslationBackend.gtranslate.rawValue {
|
||||
return gtranslate(text, toLang)
|
||||
|> map { ($0, []) }
|
||||
|> mapError { _ in .generic }
|
||||
}
|
||||
|
||||
return `default`
|
||||
|> `catch` { originalError in
|
||||
gtranslate(text, toLang)
|
||||
|> map { ($0, []) }
|
||||
|> mapError { _ in originalError }
|
||||
}
|
||||
}
|
||||
|
||||
private func sgWrappedTranslateMultiple(
|
||||
texts: [(String, [MessageTextEntity])],
|
||||
toLang: String,
|
||||
`default`: Signal<[(String, [MessageTextEntity])], TranslationError>
|
||||
) -> Signal<[(String, [MessageTextEntity])], TranslationError> {
|
||||
if SGSimpleSettings.shared.translationBackend == SGSimpleSettings.TranslationBackend.gtranslate.rawValue {
|
||||
let translatedSignals: [Signal<(String, [MessageTextEntity]), TranslationError>] = texts.map { (text, _) in
|
||||
gtranslate(text, toLang)
|
||||
|> map { ($0, []) }
|
||||
|> mapError { _ in .generic }
|
||||
}
|
||||
return combineLatest(translatedSignals)
|
||||
}
|
||||
|
||||
return `default`
|
||||
|> `catch` { originalError in
|
||||
let translatedSignals: [Signal<(String, [MessageTextEntity]), TranslationError>] = texts.map { (text, _) in
|
||||
gtranslate(text, toLang)
|
||||
|> map { ($0, []) }
|
||||
|> mapError { _ in originalError }
|
||||
}
|
||||
return combineLatest(translatedSignals)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,11 +85,13 @@ func _internal_keepCachedTimeZoneListUpdated(account: Account) -> Signal<Never,
|
||||
|
||||
return account.postbox.transaction { transaction in
|
||||
switch result {
|
||||
case let .timezonesList(timezones, hash):
|
||||
case let .timezonesList(timezonesListData):
|
||||
let (timezones, hash) = (timezonesListData.timezones, timezonesListData.hash)
|
||||
var items: [TimeZoneList.Item] = []
|
||||
for item in timezones {
|
||||
switch item {
|
||||
case let .timezone(id, name, utcOffset):
|
||||
case let .timezone(timezoneData):
|
||||
let (id, name, utcOffset) = (timezoneData.id, timezoneData.name, timezoneData.utcOffset)
|
||||
items.append(TimeZoneList.Item(id: id, title: name, utcOffset: utcOffset))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ func _internal_transcribeAudio(postbox: Postbox, network: Network, messageId: Me
|
||||
switch result {
|
||||
case let .success(transcribedAudio):
|
||||
switch transcribedAudio {
|
||||
case let .transcribedAudio(flags, transcriptionId, text, trialRemainingCount, trialUntilDate):
|
||||
case let .transcribedAudio(transcribedAudioData):
|
||||
let (flags, transcriptionId, text, trialRemainingCount, trialUntilDate) = (transcribedAudioData.flags, transcribedAudioData.transcriptionId, transcribedAudioData.text, transcribedAudioData.trialRemainsNum, transcribedAudioData.trialRemainsUntilDate)
|
||||
let isPending = (flags & (1 << 0)) != 0
|
||||
updatedAttribute = AudioTranscriptionMessageAttribute(id: transcriptionId, text: text, isPending: isPending, didRate: false, error: nil)
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#if DEBUG
|
||||
import SGSimpleSettings
|
||||
#endif
|
||||
import SGTranslationLangFix
|
||||
import SwiftSoup
|
||||
|
||||
import Foundation
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
@@ -18,7 +24,7 @@ func _internal_translate(network: Network, text: String, toLang: String, entitie
|
||||
var flags: Int32 = 0
|
||||
flags |= (1 << 1)
|
||||
|
||||
return network.request(Api.functions.messages.translateText(flags: flags, peer: nil, id: nil, text: [.textWithEntities(text: text, entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary()))], toLang: toLang))
|
||||
return network.request(Api.functions.messages.translateText(flags: flags, peer: nil, id: nil, text: [.textWithEntities(.init(text: text, entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary())))], toLang: sgTranslationLangFix(toLang)))
|
||||
|> mapError { error -> TranslationError in
|
||||
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||
return .limitExceeded
|
||||
@@ -38,8 +44,10 @@ func _internal_translate(network: Network, text: String, toLang: String, entitie
|
||||
}
|
||||
|> mapToSignal { result -> Signal<(String, [MessageTextEntity])?, TranslationError> in
|
||||
switch result {
|
||||
case let .translateResult(results):
|
||||
if case let .textWithEntities(text, entities) = results.first {
|
||||
case let .translateResult(translateResultData):
|
||||
let results = translateResultData.result
|
||||
if case let .textWithEntities(textWithEntitiesData) = results.first {
|
||||
let (text, entities) = (textWithEntitiesData.text, textWithEntitiesData.entities)
|
||||
return .single((text, messageTextEntitiesFromApiEntities(entities)))
|
||||
} else {
|
||||
return .single(nil)
|
||||
@@ -54,7 +62,7 @@ func _internal_translateTexts(network: Network, texts: [(String, [MessageTextEnt
|
||||
|
||||
var apiTexts: [Api.TextWithEntities] = []
|
||||
for text in texts {
|
||||
apiTexts.append(.textWithEntities(text: text.0, entities: apiEntitiesFromMessageTextEntities(text.1, associatedPeers: SimpleDictionary())))
|
||||
apiTexts.append(.textWithEntities(.init(text: text.0, entities: apiEntitiesFromMessageTextEntities(text.1, associatedPeers: SimpleDictionary()))))
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.translateText(flags: flags, peer: nil, id: nil, text: apiTexts, toLang: toLang))
|
||||
@@ -76,9 +84,11 @@ func _internal_translateTexts(network: Network, texts: [(String, [MessageTextEnt
|
||||
|> mapToSignal { result -> Signal<[(String, [MessageTextEntity])], TranslationError> in
|
||||
var texts: [(String, [MessageTextEntity])] = []
|
||||
switch result {
|
||||
case let .translateResult(results):
|
||||
case let .translateResult(translateResultData):
|
||||
let results = translateResultData.result
|
||||
for result in results {
|
||||
if case let .textWithEntities(text, entities) = result {
|
||||
if case let .textWithEntities(textWithEntitiesData) = result {
|
||||
let (text, entities) = (textWithEntitiesData.text, textWithEntitiesData.entities)
|
||||
texts.append((text, messageTextEntitiesFromApiEntities(entities)))
|
||||
}
|
||||
}
|
||||
@@ -176,18 +186,18 @@ private func _internal_translateMessagesByPeerId(account: Account, peerId: Engin
|
||||
var result: [Api.TextWithEntities] = []
|
||||
for messageId in messageIds {
|
||||
if let text = resultTexts[AnyHashable(messageId)] {
|
||||
result.append(.textWithEntities(text: text, entities: []))
|
||||
result.append(.textWithEntities(.init(text: text, entities: [])))
|
||||
} else if let text = messageTexts[messageId] {
|
||||
result.append(.textWithEntities(text: text, entities: []))
|
||||
result.append(.textWithEntities(.init(text: text, entities: [])))
|
||||
} else {
|
||||
result.append(.textWithEntities(text: "", entities: []))
|
||||
result.append(.textWithEntities(.init(text: "", entities: [])))
|
||||
}
|
||||
}
|
||||
return .single(.translateResult(result: result))
|
||||
return .single(.translateResult(.init(result: result)))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msgs = account.network.request(Api.functions.messages.translateText(flags: flags, peer: inputPeer, id: id, text: nil, toLang: toLang))
|
||||
msgs = account.network.request(Api.functions.messages.translateText(flags: flags, peer: inputPeer, id: id, text: nil, toLang: sgTranslationLangFix(toLang)))
|
||||
|> map(Optional.init)
|
||||
|> mapError { error -> TranslationError in
|
||||
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||
@@ -210,11 +220,13 @@ private func _internal_translateMessagesByPeerId(account: Account, peerId: Engin
|
||||
return combineLatest(msgs, combineLatest(pollSignals), combineLatest(audioTranscriptionsSignals))
|
||||
|> mapToSignal { (result, pollResults, audioTranscriptionsResults) -> Signal<Void, TranslationError> in
|
||||
return account.postbox.transaction { transaction in
|
||||
if case let .translateResult(results) = result {
|
||||
if case let .translateResult(translateResultData) = result {
|
||||
let results = translateResultData.result
|
||||
var index = 0
|
||||
for result in results {
|
||||
let messageId = messageIds[index]
|
||||
if case let .textWithEntities(text, entities) = result {
|
||||
if case let .textWithEntities(textWithEntitiesData) = result {
|
||||
let (text, entities) = (textWithEntitiesData.text, textWithEntitiesData.entities)
|
||||
let updatedAttribute: TranslationMessageAttribute = TranslationMessageAttribute(text: text, entities: messageTextEntitiesFromApiEntities(entities), toLang: toLang)
|
||||
transaction.updateMessage(messageId, update: { currentMessage in
|
||||
let storeForwardInfo = currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init)
|
||||
@@ -284,6 +296,42 @@ private func _internal_translateMessagesByPeerId(account: Account, peerId: Engin
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_translateMessagesViaText(account: Account, messagesDict: [EngineMessage.Id: String], fromLang: String?, toLang: String, enableLocalIfPossible: Bool, generateEntitiesFunction: @escaping (String) -> [MessageTextEntity]) -> Signal<Never, TranslationError> {
|
||||
var listOfSignals: [Signal<Void, TranslationError>] = []
|
||||
for (messageId, text) in messagesDict {
|
||||
listOfSignals.append(
|
||||
// _internal_translate(network: account.network, text: text, toLang: toLang)
|
||||
// |> mapToSignal { result -> Signal<Void, TranslationError> in
|
||||
// guard let translatedText = result else {
|
||||
// return .complete()
|
||||
// }
|
||||
gtranslate(text, toLang)
|
||||
|> mapError { _ -> TranslationError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { translatedText -> Signal<Void, TranslationError> in
|
||||
// guard case let .result(translatedText) = result else {
|
||||
// return .complete()
|
||||
// }
|
||||
return account.postbox.transaction { transaction in
|
||||
transaction.updateMessage(messageId, update: { currentMessage in
|
||||
let updatedAttribute: TranslationMessageAttribute = TranslationMessageAttribute(text: translatedText, entities: generateEntitiesFunction(translatedText), toLang: toLang)
|
||||
let storeForwardInfo = currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init)
|
||||
var attributes = currentMessage.attributes.filter { !($0 is TranslationMessageAttribute) }
|
||||
|
||||
attributes.append(updatedAttribute)
|
||||
|
||||
return .update(StoreMessage(id: currentMessage.id, customStableId: nil, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media))
|
||||
})
|
||||
}
|
||||
|> castError(TranslationError.self)
|
||||
// |> castError(TranslateFetchError.self)
|
||||
}
|
||||
)
|
||||
}
|
||||
return combineLatest(listOfSignals) |> ignoreValues
|
||||
}
|
||||
|
||||
func _internal_togglePeerMessagesTranslationHidden(account: Account, peerId: EnginePeer.Id, hidden: Bool) -> Signal<Never, NoError> {
|
||||
return account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
||||
@@ -334,3 +382,249 @@ func _internal_togglePeerMessagesTranslationHidden(account: Account, peerId: Eng
|
||||
|> ignoreValues
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(swiftgram): Refactor
|
||||
public struct TranslateRule: Codable {
|
||||
public let name: String
|
||||
public let pattern: String
|
||||
public let data_check: String
|
||||
public let match_group: Int
|
||||
}
|
||||
|
||||
public func getTranslateUrl(_ message: String,_ toLang: String) -> String {
|
||||
let sanitizedMessage = message // message.replaceCharactersFromSet(characterSet:CharacterSet.newlines, replacementString: "<br>")
|
||||
|
||||
var queryCharSet = NSCharacterSet.urlQueryAllowed
|
||||
queryCharSet.remove(charactersIn: "+&")
|
||||
return "https://translate.google.com/m?hl=en&tl=\(toLang)&sl=auto&q=\(sanitizedMessage.addingPercentEncoding(withAllowedCharacters: queryCharSet) ?? "")"
|
||||
}
|
||||
|
||||
func prepareResultString(_ str: String) -> String {
|
||||
return str
|
||||
// return str.htmlDecoded.replacingOccurrences(of: "<br>", with: "\n").replacingOccurrences(of: "< br>", with: "\n").replacingOccurrences(of: "<br >", with: "\n")
|
||||
}
|
||||
|
||||
var regexCache: [String: NSRegularExpression] = [:]
|
||||
|
||||
public func parseTranslateResponse(_ data: String) -> String {
|
||||
do {
|
||||
let document = try SwiftSoup.parse(data)
|
||||
|
||||
if let resultContainer = try document.select("div.result-container").first() {
|
||||
// new_mobile
|
||||
return prepareResultString(try resultContainer.text())
|
||||
} else if let tZero = try document.select("div.t0").first() {
|
||||
// old_mobile
|
||||
return prepareResultString(try tZero.text())
|
||||
}
|
||||
} catch Exception.Error(let type, let message) {
|
||||
#if DEBUG
|
||||
SGtrace("translate", what: "Translation parser failure, An error of type \(type) occurred: \(message)")
|
||||
#endif
|
||||
// print("Translation parser failure, An error of type \(type) occurred: \(message)")
|
||||
} catch {
|
||||
#if DEBUG
|
||||
SGtrace("translate", what: "Translation parser failure, An error occurred: \(error)")
|
||||
#endif
|
||||
// print("Translation parser failure, An error occurred: \(error)")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
public func getGTranslateLang(_ userLang: String) -> String {
|
||||
var lang = userLang
|
||||
let rawSuffix = "-raw"
|
||||
if lang.hasSuffix(rawSuffix) {
|
||||
lang = String(lang.dropLast(rawSuffix.count))
|
||||
}
|
||||
lang = lang.lowercased()
|
||||
|
||||
// Fallback To Google lang
|
||||
switch (lang) {
|
||||
case "zh-hans", "zh":
|
||||
return "zh-CN"
|
||||
case "zh-hant":
|
||||
return "zh-TW"
|
||||
case "he":
|
||||
return "iw"
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
// Fix for pt-br and other regional langs
|
||||
// https://cloud.go
|
||||
// ogle.com/tran
|
||||
// slate/do
|
||||
// cs/lang
|
||||
// uages
|
||||
lang = lang.components(separatedBy: "-")[0].components(separatedBy: "_")[0]
|
||||
|
||||
return lang
|
||||
}
|
||||
|
||||
|
||||
public enum TranslateFetchError {
|
||||
case network
|
||||
}
|
||||
|
||||
|
||||
let TranslateSessionConfiguration = URLSessionConfiguration.ephemeral
|
||||
|
||||
// Create a URLSession with the ephemeral configuration
|
||||
let TranslateSession = URLSession(configuration: TranslateSessionConfiguration)
|
||||
|
||||
public func requestTranslateUrl(url: URL) -> Signal<String, TranslateFetchError> {
|
||||
return Signal { subscriber in
|
||||
let completed = Atomic<Bool>(value: false)
|
||||
var request = URLRequest(url: url)
|
||||
request.httpMethod = "GET"
|
||||
// Set headers
|
||||
request.setValue("Mozilla/4.0 (compatible;MSIE 6.0;Windows NT 5.1;SV1;.NET CLR 1.1.4322;.NET CLR 2.0.50727;.NET CLR 3.0.04506.30)", forHTTPHeaderField: "User-Agent")
|
||||
let downloadTask = TranslateSession.dataTask(with: request, completionHandler: { data, response, error in
|
||||
let _ = completed.swap(true)
|
||||
if let response = response as? HTTPURLResponse {
|
||||
if response.statusCode == 200 {
|
||||
if let data = data {
|
||||
if let result = String(data: data, encoding: .utf8) {
|
||||
subscriber.putNext(result)
|
||||
subscriber.putCompletion()
|
||||
} else {
|
||||
subscriber.putError(.network)
|
||||
}
|
||||
} else {
|
||||
// print("Empty data")
|
||||
subscriber.putError(.network)
|
||||
}
|
||||
} else {
|
||||
// print("Non 200 status")
|
||||
subscriber.putError(.network)
|
||||
}
|
||||
} else {
|
||||
// print("No response (??)")
|
||||
subscriber.putError(.network)
|
||||
}
|
||||
})
|
||||
downloadTask.resume()
|
||||
|
||||
return ActionDisposable {
|
||||
if !completed.with({ $0 }) {
|
||||
downloadTask.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func gtranslate(_ text: String, _ toLang: String) -> Signal<String, TranslateFetchError> {
|
||||
// 1) Preserve *all* line breaks, including empty ones
|
||||
let lines = text.components(separatedBy: "\n")
|
||||
|
||||
// 2) Map each line to either a passthrough signal or a translate signal
|
||||
let translationSignals: [Signal<String, TranslateFetchError>] = lines.map { rawLine in
|
||||
// Grab the "core" text and its leading whitespace
|
||||
let leadingWhitespace = rawLine.prefix { $0.isWhitespace }
|
||||
let core = rawLine.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
|
||||
// If there’s nothing to translate, just emit the line back
|
||||
if core.isEmpty {
|
||||
return .single(rawLine)
|
||||
}
|
||||
|
||||
// Otherwise translate the core, then re-attach the indentation
|
||||
return gtranslateSentence(core, toLang)
|
||||
|> map { translatedCore in
|
||||
return String(leadingWhitespace) + translatedCore
|
||||
}
|
||||
}
|
||||
|
||||
// 3) Combine them and re-join with newlines
|
||||
return combineLatest(translationSignals)
|
||||
|> map { results in
|
||||
let joined = results.joined(separator: "\n")
|
||||
return joined.isEmpty ? text : joined
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func gtranslateSentence(_ text: String, _ toLang: String) -> Signal<String, TranslateFetchError> {
|
||||
return Signal { subscriber in
|
||||
let urlString = getTranslateUrl(text, getGTranslateLang(toLang))
|
||||
let url = URL(string: urlString)!
|
||||
let translateSignal = requestTranslateUrl(url: url)
|
||||
var translateDisposable: Disposable? = nil
|
||||
|
||||
translateDisposable = translateSignal.start(next: {
|
||||
translatedHtml in
|
||||
#if DEBUG
|
||||
print("urlString: \(urlString)")
|
||||
let startTime = CFAbsoluteTimeGetCurrent()
|
||||
print("translatedHtml: \(translatedHtml)")
|
||||
print("decodedHtml: \(translatedHtml.htmlDecoded)")
|
||||
#endif
|
||||
let result = parseTranslateResponse(translatedHtml)
|
||||
#if DEBUG
|
||||
print("translatedResult: \(result)")
|
||||
SGtrace("translate", what: "Translation parsed in \(CFAbsoluteTimeGetCurrent() - startTime)")
|
||||
#endif
|
||||
if result.isEmpty {
|
||||
// print("EMPTY RESULT")
|
||||
subscriber.putError(.network) // Fake
|
||||
} else {
|
||||
subscriber.putNext(result)
|
||||
subscriber.putCompletion()
|
||||
}
|
||||
|
||||
}, error: { _ in
|
||||
subscriber.putError(.network)
|
||||
})
|
||||
|
||||
return ActionDisposable {
|
||||
translateDisposable?.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func gtranslateSplitTextBySentences(_ text: String, maxChunkLength: Int = 1500) -> [String] {
|
||||
if text.count <= maxChunkLength {
|
||||
return [text]
|
||||
}
|
||||
var chunks: [String] = []
|
||||
var currentChunk = ""
|
||||
|
||||
text.enumerateSubstrings(in: text.startIndex..<text.endIndex, options: .bySentences) { (substring, _, _, _) in
|
||||
guard let sentence = substring else { return }
|
||||
|
||||
if currentChunk.count + sentence.count + 1 < maxChunkLength {
|
||||
currentChunk += sentence + " "
|
||||
} else {
|
||||
if !currentChunk.isEmpty {
|
||||
chunks.append(currentChunk.trimmingCharacters(in: .whitespacesAndNewlines))
|
||||
}
|
||||
currentChunk = sentence + " "
|
||||
}
|
||||
}
|
||||
|
||||
if !currentChunk.isEmpty {
|
||||
chunks.append(currentChunk.trimmingCharacters(in: .whitespacesAndNewlines))
|
||||
}
|
||||
|
||||
return chunks
|
||||
}
|
||||
|
||||
|
||||
extension String {
|
||||
var htmlDecoded: String {
|
||||
let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
|
||||
NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html,
|
||||
NSAttributedString.DocumentReadingOptionKey.characterEncoding : String.Encoding.utf8.rawValue
|
||||
]
|
||||
|
||||
let decoded = try? NSAttributedString(data: Data(utf8), options: attributedOptions, documentAttributes: nil).string
|
||||
return decoded ?? self
|
||||
}
|
||||
|
||||
func replaceCharactersFromSet(characterSet: CharacterSet, replacementString: String = "") -> String {
|
||||
return components(separatedBy: characterSet).joined(separator: replacementString)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,8 @@ func _internal_requestUpdatePinnedMessage(account: Account, peerId: PeerId, upda
|
||||
account.stateManager.addUpdates(updates)
|
||||
return account.postbox.transaction { transaction in
|
||||
switch updates {
|
||||
case let .updates(updates, _, _, _, _):
|
||||
case let .updates(updatesData):
|
||||
let updates = updatesData.updates
|
||||
if updates.isEmpty {
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
let messageId: MessageId
|
||||
@@ -173,7 +174,8 @@ func _internal_requestUnpinAllMessages(account: Account, peerId: PeerId, threadI
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Bool, InternalError> in
|
||||
switch result {
|
||||
case let .affectedHistory(_, _, count):
|
||||
case let .affectedHistory(affectedHistoryData):
|
||||
let count = affectedHistoryData.offset
|
||||
if count != 0 {
|
||||
return .fail(.restart)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user