mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
@@ -517,19 +517,11 @@ private class AdMessagesHistoryContextImpl {
|
||||
}
|
||||
|
||||
func markAsSeen(opaqueId: Data) {
|
||||
let signal: Signal<Never, NoError> = account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
return transaction.getPeer(self.peerId).flatMap(apiInputPeer)
|
||||
}
|
||||
|> mapToSignal { inputPeer -> Signal<Never, NoError> in
|
||||
guard let inputPeer else {
|
||||
return .complete()
|
||||
}
|
||||
return self.account.network.request(Api.functions.messages.viewSponsoredMessage(peer: inputPeer, randomId: Buffer(data: opaqueId)))
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
return .single(.boolFalse)
|
||||
}
|
||||
|> ignoreValues
|
||||
let signal: Signal<Never, NoError> = self.account.network.request(Api.functions.messages.viewSponsoredMessage(randomId: Buffer(data: opaqueId)))
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
return .single(.boolFalse)
|
||||
}
|
||||
|> ignoreValues
|
||||
self.maskAsSeenDisposables.set(signal.start(), forKey: opaqueId)
|
||||
}
|
||||
|
||||
@@ -610,25 +602,17 @@ public class AdMessagesHistoryContext {
|
||||
|
||||
|
||||
func _internal_markAdAction(account: Account, peerId: EnginePeer.Id, opaqueId: Data, media: Bool, fullscreen: Bool) {
|
||||
let signal: Signal<Never, NoError> = account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
var flags: Int32 = 0
|
||||
if media {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
|> mapToSignal { inputPeer -> Signal<Never, NoError> in
|
||||
guard let inputPeer else {
|
||||
return .complete()
|
||||
}
|
||||
var flags: Int32 = 0
|
||||
if media {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
if fullscreen {
|
||||
flags |= (1 << 1)
|
||||
}
|
||||
return account.network.request(Api.functions.messages.clickSponsoredMessage(flags: flags, peer: inputPeer, randomId: Buffer(data: opaqueId)))
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
return .single(.boolFalse)
|
||||
}
|
||||
|> ignoreValues
|
||||
if fullscreen {
|
||||
flags |= (1 << 1)
|
||||
}
|
||||
let signal = account.network.request(Api.functions.messages.clickSponsoredMessage(flags: flags, randomId: Buffer(data: opaqueId)))
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
return .single(.boolFalse)
|
||||
}
|
||||
|> ignoreValues
|
||||
let _ = signal.start()
|
||||
}
|
||||
|
||||
@@ -565,7 +565,7 @@ func _internal_removeChatManagingBot(account: Account, chatId: EnginePeer.Id) ->
|
||||
excludePeers: excludePeers,
|
||||
exclude: connectedBot.recipients.exclude
|
||||
),
|
||||
canReply: connectedBot.canReply
|
||||
rights: connectedBot.rights
|
||||
))
|
||||
} else {
|
||||
return current
|
||||
|
||||
@@ -764,6 +764,59 @@ extension TelegramBusinessIntro {
|
||||
}
|
||||
}
|
||||
|
||||
extension TelegramBusinessBotRights {
|
||||
init(apiValue: Api.BusinessBotRights) {
|
||||
var value: TelegramBusinessBotRights = []
|
||||
switch apiValue {
|
||||
case let .businessBotRights(flags):
|
||||
if (flags & (1 << 0)) != 0 {
|
||||
value.insert(.reply)
|
||||
}
|
||||
if (flags & (1 << 1)) != 0 {
|
||||
value.insert(.readMessages)
|
||||
}
|
||||
if (flags & (1 << 2)) != 0 {
|
||||
value.insert(.deleteSentMessages)
|
||||
}
|
||||
if (flags & (1 << 3)) != 0 {
|
||||
value.insert(.deleteReceivedMessages)
|
||||
}
|
||||
|
||||
if (flags & (1 << 4)) != 0 {
|
||||
value.insert(.editName)
|
||||
}
|
||||
if (flags & (1 << 5)) != 0 {
|
||||
value.insert(.editBio)
|
||||
}
|
||||
if (flags & (1 << 6)) != 0 {
|
||||
value.insert(.editProfilePhoto)
|
||||
}
|
||||
if (flags & (1 << 7)) != 0 {
|
||||
value.insert(.editUsername)
|
||||
}
|
||||
if (flags & (1 << 8)) != 0 {
|
||||
value.insert(.viewGifts)
|
||||
}
|
||||
if (flags & (1 << 9)) != 0 {
|
||||
value.insert(.sellGifts)
|
||||
}
|
||||
if (flags & (1 << 10)) != 0 {
|
||||
value.insert(.changeGiftSettings)
|
||||
}
|
||||
if (flags & (1 << 11)) != 0 {
|
||||
value.insert(.transferAndUpgradeGifts)
|
||||
}
|
||||
if (flags & (1 << 12)) != 0 {
|
||||
value.insert(.transferStars)
|
||||
}
|
||||
if (flags & (1 << 13)) != 0 {
|
||||
value.insert(.manageStories)
|
||||
}
|
||||
}
|
||||
self = value
|
||||
}
|
||||
}
|
||||
|
||||
extension TelegramBusinessRecipients {
|
||||
convenience init(apiValue: Api.BusinessRecipients) {
|
||||
switch apiValue {
|
||||
@@ -1021,12 +1074,12 @@ func _internal_updateBusinessIntro(account: Account, intro: TelegramBusinessIntr
|
||||
public final class TelegramAccountConnectedBot: Codable, Equatable {
|
||||
public let id: PeerId
|
||||
public let recipients: TelegramBusinessRecipients
|
||||
public let canReply: Bool
|
||||
public let rights: TelegramBusinessBotRights
|
||||
|
||||
public init(id: PeerId, recipients: TelegramBusinessRecipients, canReply: Bool) {
|
||||
public init(id: PeerId, recipients: TelegramBusinessRecipients, rights: TelegramBusinessBotRights) {
|
||||
self.id = id
|
||||
self.recipients = recipients
|
||||
self.canReply = canReply
|
||||
self.rights = rights
|
||||
}
|
||||
|
||||
public static func ==(lhs: TelegramAccountConnectedBot, rhs: TelegramAccountConnectedBot) -> Bool {
|
||||
@@ -1039,13 +1092,51 @@ public final class TelegramAccountConnectedBot: Codable, Equatable {
|
||||
if lhs.recipients != rhs.recipients {
|
||||
return false
|
||||
}
|
||||
if lhs.canReply != rhs.canReply {
|
||||
if lhs.rights != rhs.rights {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
public struct TelegramBusinessBotRights: OptionSet, Codable {
|
||||
public var rawValue: Int32
|
||||
|
||||
public init() {
|
||||
self.rawValue = 0
|
||||
}
|
||||
|
||||
public init(rawValue: Int32) {
|
||||
self.rawValue = rawValue
|
||||
}
|
||||
|
||||
public static let reply = TelegramBusinessBotRights(rawValue: 1 << 0)
|
||||
public static let readMessages = TelegramBusinessBotRights(rawValue: 1 << 1)
|
||||
public static let deleteSentMessages = TelegramBusinessBotRights(rawValue: 1 << 2)
|
||||
public static let deleteReceivedMessages = TelegramBusinessBotRights(rawValue: 1 << 3)
|
||||
public static let editName = TelegramBusinessBotRights(rawValue: 1 << 4)
|
||||
public static let editBio = TelegramBusinessBotRights(rawValue: 1 << 5)
|
||||
public static let editProfilePhoto = TelegramBusinessBotRights(rawValue: 1 << 6)
|
||||
public static let editUsername = TelegramBusinessBotRights(rawValue: 1 << 7)
|
||||
public static let viewGifts = TelegramBusinessBotRights(rawValue: 1 << 8)
|
||||
public static let sellGifts = TelegramBusinessBotRights(rawValue: 1 << 9)
|
||||
public static let changeGiftSettings = TelegramBusinessBotRights(rawValue: 1 << 10)
|
||||
public static let transferAndUpgradeGifts = TelegramBusinessBotRights(rawValue: 1 << 11)
|
||||
public static let transferStars = TelegramBusinessBotRights(rawValue: 1 << 12)
|
||||
public static let manageStories = TelegramBusinessBotRights(rawValue: 1 << 13)
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||
let value = try? container.decode(Int32.self, forKey: "v")
|
||||
self = TelegramBusinessBotRights(rawValue: value ?? 0)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||
try container.encode(self.rawValue, forKey: "v")
|
||||
}
|
||||
}
|
||||
|
||||
public func _internal_setAccountConnectedBot(account: Account, bot: TelegramAccountConnectedBot?) -> Signal<Never, NoError> {
|
||||
let remoteApply = account.postbox.transaction { transaction -> (Peer?, [Peer], [Peer]) in
|
||||
guard let bot else {
|
||||
@@ -1059,20 +1150,65 @@ public func _internal_setAccountConnectedBot(account: Account, bot: TelegramAcco
|
||||
}
|
||||
|> mapToSignal { botUser, additionalPeers, excludePeers in
|
||||
var flags: Int32 = 0
|
||||
var mappedRights: Api.BusinessBotRights?
|
||||
var mappedBot: Api.InputUser = .inputUserEmpty
|
||||
var mappedRecipients: Api.InputBusinessBotRecipients = .inputBusinessBotRecipients(flags: 0, users: nil, excludeUsers: nil)
|
||||
|
||||
if let bot, let inputBotUser = botUser.flatMap(apiInputUser) {
|
||||
mappedBot = inputBotUser
|
||||
if bot.canReply {
|
||||
flags |= 1 << 0
|
||||
|
||||
flags |= 1 << 0
|
||||
|
||||
var rightsFlags: Int32 = 0
|
||||
if bot.rights.contains(.reply) {
|
||||
rightsFlags |= (1 << 0)
|
||||
}
|
||||
if bot.rights.contains(.readMessages) {
|
||||
rightsFlags |= (1 << 1)
|
||||
}
|
||||
if bot.rights.contains(.deleteSentMessages) {
|
||||
rightsFlags |= (1 << 2)
|
||||
}
|
||||
if bot.rights.contains(.deleteReceivedMessages) {
|
||||
rightsFlags |= (1 << 3)
|
||||
}
|
||||
if bot.rights.contains(.editName) {
|
||||
rightsFlags |= (1 << 4)
|
||||
}
|
||||
if bot.rights.contains(.editBio) {
|
||||
rightsFlags |= (1 << 5)
|
||||
}
|
||||
if bot.rights.contains(.editProfilePhoto) {
|
||||
rightsFlags |= (1 << 6)
|
||||
}
|
||||
if bot.rights.contains(.editUsername) {
|
||||
rightsFlags |= (1 << 7)
|
||||
}
|
||||
if bot.rights.contains(.viewGifts) {
|
||||
rightsFlags |= (1 << 8)
|
||||
}
|
||||
if bot.rights.contains(.sellGifts) {
|
||||
rightsFlags |= (1 << 9)
|
||||
}
|
||||
if bot.rights.contains(.changeGiftSettings) {
|
||||
rightsFlags |= (1 << 10)
|
||||
}
|
||||
if bot.rights.contains(.transferAndUpgradeGifts) {
|
||||
rightsFlags |= (1 << 11)
|
||||
}
|
||||
if bot.rights.contains(.transferStars) {
|
||||
rightsFlags |= (1 << 12)
|
||||
}
|
||||
if bot.rights.contains(.manageStories) {
|
||||
rightsFlags |= (1 << 13)
|
||||
}
|
||||
mappedRights = .businessBotRights(flags: rightsFlags)
|
||||
mappedRecipients = bot.recipients.apiInputBotValue(additionalPeers: additionalPeers, excludePeers: excludePeers)
|
||||
} else {
|
||||
flags |= 1 << 1
|
||||
}
|
||||
|
||||
return account.network.request(Api.functions.account.updateConnectedBot(flags: flags, rights: nil, bot: mappedBot, recipients: mappedRecipients))
|
||||
return account.network.request(Api.functions.account.updateConnectedBot(flags: flags, rights: mappedRights, bot: mappedBot, recipients: mappedRecipients))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
|
||||
@@ -20,33 +20,26 @@ public enum ReportAdMessageError {
|
||||
}
|
||||
|
||||
func _internal_reportAdMessage(account: Account, peerId: EnginePeer.Id, opaqueId: Data, option: Data?) -> Signal<ReportAdMessageResult, ReportAdMessageError> {
|
||||
return account.postbox.transaction { transaction -> Signal<ReportAdMessageResult, ReportAdMessageError> in
|
||||
guard let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) else {
|
||||
return .fail(.generic)
|
||||
return account.network.request(Api.functions.messages.reportSponsoredMessage(randomId: Buffer(data: opaqueId), option: Buffer(data: option)))
|
||||
|> mapError { error -> ReportAdMessageError in
|
||||
if error.errorDescription == "PREMIUM_ACCOUNT_REQUIRED" {
|
||||
return .premiumRequired
|
||||
}
|
||||
return account.network.request(Api.functions.messages.reportSponsoredMessage(peer: inputPeer, randomId: Buffer(data: opaqueId), option: Buffer(data: option)))
|
||||
|> mapError { error -> ReportAdMessageError in
|
||||
if error.errorDescription == "PREMIUM_ACCOUNT_REQUIRED" {
|
||||
return .premiumRequired
|
||||
}
|
||||
return .generic
|
||||
}
|
||||
|> map { result -> ReportAdMessageResult in
|
||||
switch result {
|
||||
case let .sponsoredMessageReportResultChooseOption(title, options):
|
||||
return .options(title: title, options: options.map {
|
||||
switch $0 {
|
||||
case let .sponsoredMessageReportOption(text, option):
|
||||
return ReportAdMessageResult.Option(text: text, option: option.makeData())
|
||||
}
|
||||
})
|
||||
case .sponsoredMessageReportResultAdsHidden:
|
||||
return .adsHidden
|
||||
case .sponsoredMessageReportResultReported:
|
||||
return .reported
|
||||
}
|
||||
return .generic
|
||||
}
|
||||
|> map { result -> ReportAdMessageResult in
|
||||
switch result {
|
||||
case let .sponsoredMessageReportResultChooseOption(title, options):
|
||||
return .options(title: title, options: options.map {
|
||||
switch $0 {
|
||||
case let .sponsoredMessageReportOption(text, option):
|
||||
return ReportAdMessageResult.Option(text: text, option: option.makeData())
|
||||
}
|
||||
})
|
||||
case .sponsoredMessageReportResultAdsHidden:
|
||||
return .adsHidden
|
||||
case .sponsoredMessageReportResultReported:
|
||||
return .reported
|
||||
}
|
||||
}
|
||||
|> castError(ReportAdMessageError.self)
|
||||
|> switchToLatest
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import TelegramApi
|
||||
|
||||
public class AdPeer: Equatable {
|
||||
public let opaqueId: Data
|
||||
public let peer: EnginePeer
|
||||
public let sponsorInfo: String?
|
||||
public let additionalInfo: String?
|
||||
|
||||
public init(opaqueId: Data, peer: EnginePeer, sponsorInfo: String?, additionalInfo: String?) {
|
||||
self.opaqueId = opaqueId
|
||||
self.peer = peer
|
||||
self.sponsorInfo = sponsorInfo
|
||||
self.additionalInfo = additionalInfo
|
||||
}
|
||||
|
||||
public static func ==(lhs: AdPeer, rhs: AdPeer) -> Bool {
|
||||
if lhs.opaqueId != rhs.opaqueId {
|
||||
return false
|
||||
}
|
||||
if lhs.peer != rhs.peer {
|
||||
return false
|
||||
}
|
||||
if lhs.sponsorInfo != rhs.sponsorInfo {
|
||||
return false
|
||||
}
|
||||
if lhs.additionalInfo != rhs.additionalInfo {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_searchAdPeers(account: Account, query: String) -> Signal<[AdPeer], NoError> {
|
||||
return account.network.request(Api.functions.contacts.getSponsoredPeers(q: query))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result in
|
||||
guard let result else {
|
||||
return .single([])
|
||||
}
|
||||
return account.postbox.transaction { transaction -> [AdPeer] in
|
||||
switch result {
|
||||
case let .sponsoredPeers(peers, chats, users):
|
||||
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: parsedPeers)
|
||||
|
||||
var result: [AdPeer] = []
|
||||
for peer in peers {
|
||||
switch peer {
|
||||
case let .sponsoredPeer(_, randomId, apiPeer, sponsorInfo, additionalInfo):
|
||||
guard let peer = parsedPeers.peers[apiPeer.peerId] else {
|
||||
continue
|
||||
}
|
||||
result.append(
|
||||
AdPeer(
|
||||
opaqueId: randomId.makeData(),
|
||||
peer: EnginePeer(peer),
|
||||
sponsorInfo: sponsorInfo,
|
||||
additionalInfo: additionalInfo
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
return result
|
||||
default:
|
||||
return []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1522,6 +1522,10 @@ public extension TelegramEngine {
|
||||
return _internal_requestRecommendedBots(account: self.account, peerId: peerId, forceUpdate: forceUpdate)
|
||||
}
|
||||
|
||||
public func searchAdPeers(query: String) -> Signal<[AdPeer], NoError> {
|
||||
return _internal_searchAdPeers(account: self.account, query: query)
|
||||
}
|
||||
|
||||
public func isPremiumRequiredToContact(_ peerIds: [EnginePeer.Id]) -> Signal<[EnginePeer.Id: RequirementToContact], NoError> {
|
||||
return _internal_updateIsPremiumRequiredToContact(account: self.account, peerIds: peerIds)
|
||||
}
|
||||
|
||||
@@ -246,11 +246,11 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
||||
|
||||
if let apiBot = connectedBots.first {
|
||||
switch apiBot {
|
||||
case let .connectedBot(flags, botId, recipients, _):
|
||||
case let .connectedBot(_, botId, recipients, rights):
|
||||
mappedConnectedBot = TelegramAccountConnectedBot(
|
||||
id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId)),
|
||||
recipients: TelegramBusinessRecipients(apiValue: recipients),
|
||||
canReply: (flags & (1 << 0)) != 0
|
||||
rights: TelegramBusinessBotRights(apiValue: rights)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user