Add reaction privacy

This commit is contained in:
Isaac 2025-01-31 21:06:17 +04:00
parent 2da0f6fcc4
commit 18db7a1a58
19 changed files with 494 additions and 206 deletions

View File

@ -715,6 +715,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1282352120] = { return Api.PageRelatedArticle.parse_pageRelatedArticle($0) }
dict[878078826] = { return Api.PageTableCell.parse_pageTableCell($0) }
dict[-524237339] = { return Api.PageTableRow.parse_pageTableRow($0) }
dict[520887001] = { return Api.PaidReactionPrivacy.parse_paidReactionPrivacyAnonymous($0) }
dict[543872158] = { return Api.PaidReactionPrivacy.parse_paidReactionPrivacyDefault($0) }
dict[-596837136] = { return Api.PaidReactionPrivacy.parse_paidReactionPrivacyPeer($0) }
dict[982592842] = { return Api.PasswordKdfAlgo.parse_passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow($0) }
dict[-732254058] = { return Api.PasswordKdfAlgo.parse_passwordKdfAlgoUnknown($0) }
dict[-368917890] = { return Api.PaymentCharge.parse_paymentCharge($0) }
@ -914,7 +917,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1301522832] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) }
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
dict[46953416] = { return Api.StarGift.parse_starGift($0) }
dict[-218202550] = { return Api.StarGift.parse_starGiftUnique($0) }
dict[1549979985] = { return Api.StarGift.parse_starGiftUnique($0) }
dict[-1809377438] = { return Api.StarGiftAttribute.parse_starGiftAttributeBackdrop($0) }
dict[970559507] = { return Api.StarGiftAttribute.parse_starGiftAttributeModel($0) }
dict[-524291476] = { return Api.StarGiftAttribute.parse_starGiftAttributeOriginalDetails($0) }
@ -1068,7 +1071,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1753886890] = { return Api.Update.parse_updateNewStickerSet($0) }
dict[405070859] = { return Api.Update.parse_updateNewStoryReaction($0) }
dict[-1094555409] = { return Api.Update.parse_updateNotifySettings($0) }
dict[1372224236] = { return Api.Update.parse_updatePaidReactionPrivacy($0) }
dict[-1955438642] = { return Api.Update.parse_updatePaidReactionPrivacy($0) }
dict[-337610926] = { return Api.Update.parse_updatePeerBlocked($0) }
dict[-1147422299] = { return Api.Update.parse_updatePeerHistoryTTL($0) }
dict[-1263546448] = { return Api.Update.parse_updatePeerLocated($0) }
@ -1940,6 +1943,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.PageTableRow:
_1.serialize(buffer, boxed)
case let _1 as Api.PaidReactionPrivacy:
_1.serialize(buffer, boxed)
case let _1 as Api.PasswordKdfAlgo:
_1.serialize(buffer, boxed)
case let _1 as Api.PaymentCharge:

View File

@ -334,6 +334,68 @@ public extension Api {
}
}
public extension Api {
indirect enum PaidReactionPrivacy: TypeConstructorDescription {
case paidReactionPrivacyAnonymous
case paidReactionPrivacyDefault
case paidReactionPrivacyPeer(peer: Api.InputPeer)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .paidReactionPrivacyAnonymous:
if boxed {
buffer.appendInt32(520887001)
}
break
case .paidReactionPrivacyDefault:
if boxed {
buffer.appendInt32(543872158)
}
break
case .paidReactionPrivacyPeer(let peer):
if boxed {
buffer.appendInt32(-596837136)
}
peer.serialize(buffer, true)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .paidReactionPrivacyAnonymous:
return ("paidReactionPrivacyAnonymous", [])
case .paidReactionPrivacyDefault:
return ("paidReactionPrivacyDefault", [])
case .paidReactionPrivacyPeer(let peer):
return ("paidReactionPrivacyPeer", [("peer", peer as Any)])
}
}
public static func parse_paidReactionPrivacyAnonymous(_ reader: BufferReader) -> PaidReactionPrivacy? {
return Api.PaidReactionPrivacy.paidReactionPrivacyAnonymous
}
public static func parse_paidReactionPrivacyDefault(_ reader: BufferReader) -> PaidReactionPrivacy? {
return Api.PaidReactionPrivacy.paidReactionPrivacyDefault
}
public static func parse_paidReactionPrivacyPeer(_ reader: BufferReader) -> PaidReactionPrivacy? {
var _1: Api.InputPeer?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.InputPeer
}
let _c1 = _1 != nil
if _c1 {
return Api.PaidReactionPrivacy.paidReactionPrivacyPeer(peer: _1!)
}
else {
return nil
}
}
}
}
public extension Api {
enum PasswordKdfAlgo: TypeConstructorDescription {
case passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow(salt1: Buffer, salt2: Buffer, g: Int32, p: Buffer)
@ -1332,87 +1394,3 @@ public extension Api {
}
}
public extension Api {
enum PhoneCallDiscardReason: TypeConstructorDescription {
case phoneCallDiscardReasonAllowGroupCall(encryptedKey: Buffer)
case phoneCallDiscardReasonBusy
case phoneCallDiscardReasonDisconnect
case phoneCallDiscardReasonHangup
case phoneCallDiscardReasonMissed
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .phoneCallDiscardReasonAllowGroupCall(let encryptedKey):
if boxed {
buffer.appendInt32(-1344096199)
}
serializeBytes(encryptedKey, buffer: buffer, boxed: false)
break
case .phoneCallDiscardReasonBusy:
if boxed {
buffer.appendInt32(-84416311)
}
break
case .phoneCallDiscardReasonDisconnect:
if boxed {
buffer.appendInt32(-527056480)
}
break
case .phoneCallDiscardReasonHangup:
if boxed {
buffer.appendInt32(1471006352)
}
break
case .phoneCallDiscardReasonMissed:
if boxed {
buffer.appendInt32(-2048646399)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .phoneCallDiscardReasonAllowGroupCall(let encryptedKey):
return ("phoneCallDiscardReasonAllowGroupCall", [("encryptedKey", encryptedKey as Any)])
case .phoneCallDiscardReasonBusy:
return ("phoneCallDiscardReasonBusy", [])
case .phoneCallDiscardReasonDisconnect:
return ("phoneCallDiscardReasonDisconnect", [])
case .phoneCallDiscardReasonHangup:
return ("phoneCallDiscardReasonHangup", [])
case .phoneCallDiscardReasonMissed:
return ("phoneCallDiscardReasonMissed", [])
}
}
public static func parse_phoneCallDiscardReasonAllowGroupCall(_ reader: BufferReader) -> PhoneCallDiscardReason? {
var _1: Buffer?
_1 = parseBytes(reader)
let _c1 = _1 != nil
if _c1 {
return Api.PhoneCallDiscardReason.phoneCallDiscardReasonAllowGroupCall(encryptedKey: _1!)
}
else {
return nil
}
}
public static func parse_phoneCallDiscardReasonBusy(_ reader: BufferReader) -> PhoneCallDiscardReason? {
return Api.PhoneCallDiscardReason.phoneCallDiscardReasonBusy
}
public static func parse_phoneCallDiscardReasonDisconnect(_ reader: BufferReader) -> PhoneCallDiscardReason? {
return Api.PhoneCallDiscardReason.phoneCallDiscardReasonDisconnect
}
public static func parse_phoneCallDiscardReasonHangup(_ reader: BufferReader) -> PhoneCallDiscardReason? {
return Api.PhoneCallDiscardReason.phoneCallDiscardReasonHangup
}
public static func parse_phoneCallDiscardReasonMissed(_ reader: BufferReader) -> PhoneCallDiscardReason? {
return Api.PhoneCallDiscardReason.phoneCallDiscardReasonMissed
}
}
}

View File

@ -1,3 +1,87 @@
public extension Api {
enum PhoneCallDiscardReason: TypeConstructorDescription {
case phoneCallDiscardReasonAllowGroupCall(encryptedKey: Buffer)
case phoneCallDiscardReasonBusy
case phoneCallDiscardReasonDisconnect
case phoneCallDiscardReasonHangup
case phoneCallDiscardReasonMissed
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .phoneCallDiscardReasonAllowGroupCall(let encryptedKey):
if boxed {
buffer.appendInt32(-1344096199)
}
serializeBytes(encryptedKey, buffer: buffer, boxed: false)
break
case .phoneCallDiscardReasonBusy:
if boxed {
buffer.appendInt32(-84416311)
}
break
case .phoneCallDiscardReasonDisconnect:
if boxed {
buffer.appendInt32(-527056480)
}
break
case .phoneCallDiscardReasonHangup:
if boxed {
buffer.appendInt32(1471006352)
}
break
case .phoneCallDiscardReasonMissed:
if boxed {
buffer.appendInt32(-2048646399)
}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .phoneCallDiscardReasonAllowGroupCall(let encryptedKey):
return ("phoneCallDiscardReasonAllowGroupCall", [("encryptedKey", encryptedKey as Any)])
case .phoneCallDiscardReasonBusy:
return ("phoneCallDiscardReasonBusy", [])
case .phoneCallDiscardReasonDisconnect:
return ("phoneCallDiscardReasonDisconnect", [])
case .phoneCallDiscardReasonHangup:
return ("phoneCallDiscardReasonHangup", [])
case .phoneCallDiscardReasonMissed:
return ("phoneCallDiscardReasonMissed", [])
}
}
public static func parse_phoneCallDiscardReasonAllowGroupCall(_ reader: BufferReader) -> PhoneCallDiscardReason? {
var _1: Buffer?
_1 = parseBytes(reader)
let _c1 = _1 != nil
if _c1 {
return Api.PhoneCallDiscardReason.phoneCallDiscardReasonAllowGroupCall(encryptedKey: _1!)
}
else {
return nil
}
}
public static func parse_phoneCallDiscardReasonBusy(_ reader: BufferReader) -> PhoneCallDiscardReason? {
return Api.PhoneCallDiscardReason.phoneCallDiscardReasonBusy
}
public static func parse_phoneCallDiscardReasonDisconnect(_ reader: BufferReader) -> PhoneCallDiscardReason? {
return Api.PhoneCallDiscardReason.phoneCallDiscardReasonDisconnect
}
public static func parse_phoneCallDiscardReasonHangup(_ reader: BufferReader) -> PhoneCallDiscardReason? {
return Api.PhoneCallDiscardReason.phoneCallDiscardReasonHangup
}
public static func parse_phoneCallDiscardReasonMissed(_ reader: BufferReader) -> PhoneCallDiscardReason? {
return Api.PhoneCallDiscardReason.phoneCallDiscardReasonMissed
}
}
}
public extension Api {
enum PhoneCallProtocol: TypeConstructorDescription {
case phoneCallProtocol(flags: Int32, minLayer: Int32, maxLayer: Int32, libraryVersions: [String])

View File

@ -575,7 +575,7 @@ public extension Api {
public extension Api {
enum StarGift: TypeConstructorDescription {
case starGift(flags: Int32, id: Int64, sticker: Api.Document, stars: Int64, availabilityRemains: Int32?, availabilityTotal: Int32?, convertStars: Int64, firstSaleDate: Int32?, lastSaleDate: Int32?, upgradeStars: Int64?)
case starGiftUnique(flags: Int32, id: Int64, title: String, slug: String, num: Int32, ownerId: Api.Peer?, ownerName: String?, ownerAddress: String?, attributes: [Api.StarGiftAttribute], availabilityIssued: Int32, availabilityTotal: Int32)
case starGiftUnique(flags: Int32, id: Int64, title: String, slug: String, num: Int32, ownerId: Api.Peer?, ownerName: String?, ownerAddress: String?, attributes: [Api.StarGiftAttribute], availabilityIssued: Int32, availabilityTotal: Int32, giftAddress: String?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@ -594,9 +594,9 @@ public extension Api {
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(lastSaleDate!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 3) != 0 {serializeInt64(upgradeStars!, buffer: buffer, boxed: false)}
break
case .starGiftUnique(let flags, let id, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal):
case .starGiftUnique(let flags, let id, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress):
if boxed {
buffer.appendInt32(-218202550)
buffer.appendInt32(1549979985)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(id, buffer: buffer, boxed: false)
@ -613,6 +613,7 @@ public extension Api {
}
serializeInt32(availabilityIssued, buffer: buffer, boxed: false)
serializeInt32(availabilityTotal, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 3) != 0 {serializeString(giftAddress!, buffer: buffer, boxed: false)}
break
}
}
@ -621,8 +622,8 @@ public extension Api {
switch self {
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let convertStars, let firstSaleDate, let lastSaleDate, let upgradeStars):
return ("starGift", [("flags", flags as Any), ("id", id as Any), ("sticker", sticker as Any), ("stars", stars as Any), ("availabilityRemains", availabilityRemains as Any), ("availabilityTotal", availabilityTotal as Any), ("convertStars", convertStars as Any), ("firstSaleDate", firstSaleDate as Any), ("lastSaleDate", lastSaleDate as Any), ("upgradeStars", upgradeStars as Any)])
case .starGiftUnique(let flags, let id, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal):
return ("starGiftUnique", [("flags", flags as Any), ("id", id as Any), ("title", title as Any), ("slug", slug as Any), ("num", num as Any), ("ownerId", ownerId as Any), ("ownerName", ownerName as Any), ("ownerAddress", ownerAddress as Any), ("attributes", attributes as Any), ("availabilityIssued", availabilityIssued as Any), ("availabilityTotal", availabilityTotal as Any)])
case .starGiftUnique(let flags, let id, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress):
return ("starGiftUnique", [("flags", flags as Any), ("id", id as Any), ("title", title as Any), ("slug", slug as Any), ("num", num as Any), ("ownerId", ownerId as Any), ("ownerName", ownerName as Any), ("ownerAddress", ownerAddress as Any), ("attributes", attributes as Any), ("availabilityIssued", availabilityIssued as Any), ("availabilityTotal", availabilityTotal as Any), ("giftAddress", giftAddress as Any)])
}
}
@ -693,6 +694,8 @@ public extension Api {
_10 = reader.readInt32()
var _11: Int32?
_11 = reader.readInt32()
var _12: String?
if Int(_1!) & Int(1 << 3) != 0 {_12 = parseString(reader) }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
@ -704,8 +707,9 @@ public extension Api {
let _c9 = _9 != nil
let _c10 = _10 != nil
let _c11 = _11 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 {
return Api.StarGift.starGiftUnique(flags: _1!, id: _2!, title: _3!, slug: _4!, num: _5!, ownerId: _6, ownerName: _7, ownerAddress: _8, attributes: _9!, availabilityIssued: _10!, availabilityTotal: _11!)
let _c12 = (Int(_1!) & Int(1 << 3) == 0) || _12 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 {
return Api.StarGift.starGiftUnique(flags: _1!, id: _2!, title: _3!, slug: _4!, num: _5!, ownerId: _6, ownerName: _7, ownerAddress: _8, attributes: _9!, availabilityIssued: _10!, availabilityTotal: _11!, giftAddress: _12)
}
else {
return nil

View File

@ -1069,7 +1069,7 @@ public extension Api {
case updateNewStickerSet(stickerset: Api.messages.StickerSet)
case updateNewStoryReaction(storyId: Int32, peer: Api.Peer, reaction: Api.Reaction)
case updateNotifySettings(peer: Api.NotifyPeer, notifySettings: Api.PeerNotifySettings)
case updatePaidReactionPrivacy(private: Api.Bool)
case updatePaidReactionPrivacy(private: Api.PaidReactionPrivacy)
case updatePeerBlocked(flags: Int32, peerId: Api.Peer)
case updatePeerHistoryTTL(flags: Int32, peer: Api.Peer, ttlPeriod: Int32?)
case updatePeerLocated(peers: [Api.PeerLocated])
@ -1912,7 +1912,7 @@ public extension Api {
break
case .updatePaidReactionPrivacy(let `private`):
if boxed {
buffer.appendInt32(1372224236)
buffer.appendInt32(-1955438642)
}
`private`.serialize(buffer, true)
break
@ -4305,9 +4305,9 @@ public extension Api {
}
}
public static func parse_updatePaidReactionPrivacy(_ reader: BufferReader) -> Update? {
var _1: Api.Bool?
var _1: Api.PaidReactionPrivacy?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.Bool
_1 = Api.parse(reader, signature: signature) as? Api.PaidReactionPrivacy
}
let _c1 = _1 != nil
if _c1 {

View File

@ -8152,9 +8152,9 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func sendPaidReaction(flags: Int32, peer: Api.InputPeer, msgId: Int32, count: Int32, randomId: Int64, `private`: Api.Bool?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
static func sendPaidReaction(flags: Int32, peer: Api.InputPeer, msgId: Int32, count: Int32, randomId: Int64, `private`: Api.PaidReactionPrivacy?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(-1646877061)
buffer.appendInt32(1488702288)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeInt32(msgId, buffer: buffer, boxed: false)
@ -8664,9 +8664,9 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func togglePaidReactionPrivacy(peer: Api.InputPeer, msgId: Int32, `private`: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
static func togglePaidReactionPrivacy(peer: Api.InputPeer, msgId: Int32, `private`: Api.PaidReactionPrivacy) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-2070228073)
buffer.appendInt32(1129874869)
peer.serialize(buffer, true)
serializeInt32(msgId, buffer: buffer, boxed: false)
`private`.serialize(buffer, true)

View File

@ -131,7 +131,7 @@ enum AccountStateMutationOperation {
case UpdateRevenueBalances(peerId: PeerId, balances: RevenueStats.Balances)
case UpdateStarsBalance(peerId: PeerId, balance: Api.StarsAmount)
case UpdateStarsRevenueStatus(peerId: PeerId, status: StarsRevenueStats.Balances)
case UpdateStarsReactionsAreAnonymousByDefault(isAnonymous: Bool)
case UpdateStarsReactionsDefaultPrivacy(privacy: TelegramPaidReactionPrivacy)
case ReportMessageDelivery([MessageId])
}
@ -699,8 +699,8 @@ struct AccountMutableState {
self.addOperation(.UpdateStarsRevenueStatus(peerId: peerId, status: status))
}
mutating func updateStarsReactionsAreAnonymousByDefault(isAnonymous: Bool) {
self.addOperation(.UpdateStarsReactionsAreAnonymousByDefault(isAnonymous: isAnonymous))
mutating func updateStarsReactionsDefaultPrivacy(privacy: TelegramPaidReactionPrivacy) {
self.addOperation(.UpdateStarsReactionsDefaultPrivacy(privacy: privacy))
}
mutating func addReportMessageDelivery(messageIds: [MessageId]) {
@ -709,7 +709,7 @@ struct AccountMutableState {
mutating func addOperation(_ operation: AccountStateMutationOperation) {
switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .UpdateWallpaper, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateRevenueBalances, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsAreAnonymousByDefault, .ReportMessageDelivery:
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .UpdateWallpaper, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateRevenueBalances, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsDefaultPrivacy, .ReportMessageDelivery:
break
case let .AddMessages(messages, location):
for message in messages {

View File

@ -215,12 +215,40 @@ public func mergedMessageReactions(attributes: [MessageAttribute], isTags: Bool)
if let index = topPeers.firstIndex(where: { $0.isMy }) {
topPeers[index].count += pendingStars.count
} else {
topPeers.append(ReactionsMessageAttribute.TopPeer(peerId: pendingStars.accountPeerId, count: pendingStars.count, isTop: false, isMy: true, isAnonymous: pendingStars.isAnonymous))
let isAnonymous: Bool
let topPeerId: PeerId?
switch pendingStars.privacy {
case .anonymous:
isAnonymous = true
topPeerId = pendingStars.accountPeerId
case .default:
isAnonymous = false
topPeerId = pendingStars.accountPeerId
case let .peer(peerId):
isAnonymous = false
topPeerId = peerId
}
topPeers.append(ReactionsMessageAttribute.TopPeer(peerId: topPeerId, count: pendingStars.count, isTop: false, isMy: true, isAnonymous: isAnonymous))
}
reactions.insert(MessageReaction(value: .stars, count: updatedCount, chosenOrder: -1), at: 0)
return ReactionsMessageAttribute(canViewList: current?.canViewList ?? false, isTags: current?.isTags ?? isTags, reactions: reactions, recentPeers: result.recentPeers, topPeers: topPeers)
} else {
return ReactionsMessageAttribute(canViewList: current?.canViewList ?? false, isTags: current?.isTags ?? isTags, reactions: [MessageReaction(value: .stars, count: pendingStars.count, chosenOrder: -1)], recentPeers: [], topPeers: [ReactionsMessageAttribute.TopPeer(peerId: pendingStars.accountPeerId, count: pendingStars.count, isTop: false, isMy: true, isAnonymous: pendingStars.isAnonymous)])
let isAnonymous: Bool
let topPeerId: PeerId?
switch pendingStars.privacy {
case .anonymous:
isAnonymous = true
topPeerId = pendingStars.accountPeerId
case .default:
isAnonymous = false
topPeerId = pendingStars.accountPeerId
case let .peer(peerId):
isAnonymous = false
topPeerId = peerId
}
return ReactionsMessageAttribute(canViewList: current?.canViewList ?? false, isTags: current?.isTags ?? isTags, reactions: [MessageReaction(value: .stars, count: pendingStars.count, chosenOrder: -1)], recentPeers: [], topPeers: [ReactionsMessageAttribute.TopPeer(peerId: topPeerId, count: pendingStars.count, isTop: false, isMy: true, isAnonymous: isAnonymous)])
}
} else {
return result

View File

@ -1803,8 +1803,34 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
updatedState.updateStarsBalance(peerId: accountPeerId, balance: balance)
case let .updateStarsRevenueStatus(peer, status):
updatedState.updateStarsRevenueStatus(peerId: peer.peerId, status: StarsRevenueStats.Balances(apiStarsRevenueStatus: status))
case let .updatePaidReactionPrivacy(isPrivate):
updatedState.updateStarsReactionsAreAnonymousByDefault(isAnonymous: isPrivate == .boolTrue)
case let .updatePaidReactionPrivacy(privacy):
let mappedPrivacy: TelegramPaidReactionPrivacy
switch privacy {
case .paidReactionPrivacyDefault:
mappedPrivacy = .default
case .paidReactionPrivacyAnonymous:
mappedPrivacy = .anonymous
case let .paidReactionPrivacyPeer(peer):
let peerId: PeerId
switch peer {
case let .inputPeerChannel(channelId, _):
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
case let .inputPeerChannelFromMessage(_, _, channelId):
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
case let .inputPeerChat(chatId):
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId))
case .inputPeerEmpty:
peerId = accountPeerId
case .inputPeerSelf:
peerId = accountPeerId
case let .inputPeerUser(userId, _):
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))
case let .inputPeerUserFromMessage(_, _, userId):
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))
}
mappedPrivacy = .peer(peerId)
}
updatedState.updateStarsReactionsDefaultPrivacy(privacy: mappedPrivacy)
default:
break
}
@ -3296,7 +3322,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
var currentAddQuickReplyMessages: OptimizeAddMessagesState?
for operation in operations {
switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateWallpaper, .UpdateRevenueBalances, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsAreAnonymousByDefault, .ReportMessageDelivery:
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateWallpaper, .UpdateRevenueBalances, .UpdateStarsBalance, .UpdateStarsRevenueStatus, .UpdateStarsReactionsDefaultPrivacy, .ReportMessageDelivery:
if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty {
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
}
@ -3434,7 +3460,7 @@ func replayFinalState(
var updatedRevenueBalances: [PeerId: RevenueStats.Balances] = [:]
var updatedStarsBalance: [PeerId: StarsAmount] = [:]
var updatedStarsRevenueStatus: [PeerId: StarsRevenueStats.Balances] = [:]
var updatedStarsReactionsAreAnonymousByDefault: Bool?
var updatedStarsReactionsDefaultPrivacy: TelegramPaidReactionPrivacy?
var reportMessageDelivery = Set<MessageId>()
var holesFromPreviousStateMessageIds: [MessageId] = []
@ -4868,8 +4894,8 @@ func replayFinalState(
updatedStarsBalance[peerId] = StarsAmount(apiAmount: balance)
case let .UpdateStarsRevenueStatus(peerId, status):
updatedStarsRevenueStatus[peerId] = status
case let .UpdateStarsReactionsAreAnonymousByDefault(value):
updatedStarsReactionsAreAnonymousByDefault = value
case let .UpdateStarsReactionsDefaultPrivacy(value):
updatedStarsReactionsDefaultPrivacy = value
case let .ReportMessageDelivery(messageIds):
reportMessageDelivery = Set(messageIds)
}
@ -5366,8 +5392,8 @@ func replayFinalState(
}
}
if let updatedStarsReactionsAreAnonymousByDefault {
_internal_setStarsReactionDefaultToPrivate(isPrivate: updatedStarsReactionsAreAnonymousByDefault, transaction: transaction)
if let updatedStarsReactionsDefaultPrivacy {
_internal_setStarsReactionDefaultPrivacy(privacy: updatedStarsReactionsDefaultPrivacy, transaction: transaction)
}
return AccountReplayedFinalState(

View File

@ -172,10 +172,10 @@ public func updateMessageReactionsInteractively(account: Account, messageIds: [M
|> ignoreValues
}
func _internal_sendStarsReactionsInteractively(account: Account, messageId: MessageId, count: Int, isAnonymous: Bool?) -> Signal<Bool, NoError> {
return account.postbox.transaction { transaction -> Bool in
func _internal_sendStarsReactionsInteractively(account: Account, messageId: MessageId, count: Int, privacy: TelegramPaidReactionPrivacy?) -> Signal<TelegramPaidReactionPrivacy, NoError> {
return account.postbox.transaction { transaction -> TelegramPaidReactionPrivacy in
transaction.setPendingMessageAction(type: .sendStarsReaction, id: messageId, action: SendStarsReactionsAction(randomId: Int64.random(in: Int64.min ... Int64.max)))
var resolvedIsAnonymousValue = false
var resolvedPrivacyValue: TelegramPaidReactionPrivacy = .default
transaction.updateMessage(messageId, update: { currentMessage in
var storeForwardInfo: StoreMessageForwardInfo?
if let forwardInfo = currentMessage.forwardInfo {
@ -183,36 +183,36 @@ func _internal_sendStarsReactionsInteractively(account: Account, messageId: Mess
}
var mappedCount = Int32(count)
var attributes = currentMessage.attributes
var resolvedIsAnonymous = _internal_getStarsReactionDefaultToPrivate(transaction: transaction)
var resolvedPrivacy = _internal_getStarsReactionDefaultPrivacy(transaction: transaction)
for attribute in attributes {
if let attribute = attribute as? ReactionsMessageAttribute {
if let myReaction = attribute.topPeers.first(where: { $0.isMy }) {
resolvedIsAnonymous = myReaction.isAnonymous
resolvedPrivacy = myReaction.isAnonymous ? .anonymous : .default
}
}
}
loop: for j in 0 ..< attributes.count {
if let current = attributes[j] as? PendingStarsReactionsMessageAttribute {
mappedCount += current.count
resolvedIsAnonymous = current.isAnonymous
resolvedPrivacy = current.privacy
attributes.remove(at: j)
break loop
}
}
if let isAnonymous {
resolvedIsAnonymous = isAnonymous
_internal_setStarsReactionDefaultToPrivate(isPrivate: isAnonymous, transaction: transaction)
if let privacy {
resolvedPrivacy = privacy
_internal_setStarsReactionDefaultPrivacy(privacy: privacy, transaction: transaction)
}
attributes.append(PendingStarsReactionsMessageAttribute(accountPeerId: account.peerId, count: mappedCount, isAnonymous: resolvedIsAnonymous))
attributes.append(PendingStarsReactionsMessageAttribute(accountPeerId: account.peerId, count: mappedCount, privacy: resolvedPrivacy))
resolvedIsAnonymousValue = resolvedIsAnonymous
resolvedPrivacyValue = resolvedPrivacy
return .update(StoreMessage(id: currentMessage.id, 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))
})
return resolvedIsAnonymousValue
return resolvedPrivacyValue
}
}
@ -244,9 +244,9 @@ func _internal_forceSendPendingSendStarsReaction(account: Account, messageId: Me
return .complete()
}
func _internal_updateStarsReactionIsAnonymous(account: Account, messageId: MessageId, isAnonymous: Bool) -> Signal<Never, NoError> {
return account.postbox.transaction { transaction -> Api.InputPeer? in
_internal_setStarsReactionDefaultToPrivate(isPrivate: isAnonymous, transaction: transaction)
func _internal_updateStarsReactionPrivacy(account: Account, messageId: MessageId, privacy: TelegramPaidReactionPrivacy) -> Signal<Never, NoError> {
return account.postbox.transaction { transaction -> (Api.InputPeer?, Api.InputPeer?) in
_internal_setStarsReactionDefaultPrivacy(privacy: privacy, transaction: transaction)
transaction.updateMessage(messageId, update: { currentMessage in
var storeForwardInfo: StoreMessageForwardInfo?
@ -258,7 +258,17 @@ func _internal_updateStarsReactionIsAnonymous(account: Account, messageId: Messa
if let attribute = attributes[j] as? ReactionsMessageAttribute {
var updatedTopPeers = attribute.topPeers
if let index = updatedTopPeers.firstIndex(where: { $0.isMy }) {
updatedTopPeers[index].isAnonymous = isAnonymous
switch privacy {
case .anonymous:
updatedTopPeers[index].isAnonymous = true
updatedTopPeers[index].peerId = nil
case .default:
updatedTopPeers[index].isAnonymous = false
updatedTopPeers[index].peerId = account.peerId
case let .peer(peerId):
updatedTopPeers[index].isAnonymous = false
updatedTopPeers[index].peerId = peerId
}
}
attributes[j] = ReactionsMessageAttribute(canViewList: attribute.canViewList, isTags: attribute.isTags, reactions: attribute.reactions, recentPeers: attribute.recentPeers, topPeers: updatedTopPeers)
}
@ -266,14 +276,35 @@ func _internal_updateStarsReactionIsAnonymous(account: Account, messageId: Messa
return .update(StoreMessage(id: currentMessage.id, 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))
})
return transaction.getPeer(messageId.peerId).flatMap(apiInputPeer)
var privacyPeerId: PeerId?
if case let .peer(peerId) = privacy {
privacyPeerId = peerId
}
return (
transaction.getPeer(messageId.peerId).flatMap(apiInputPeer),
privacyPeerId.flatMap { privacyPeerId in transaction.getPeer(privacyPeerId).flatMap(apiInputPeer) }
)
}
|> mapToSignal { inputPeer -> Signal<Never, NoError> in
|> mapToSignal { inputPeer, inputPrivacyPeer -> Signal<Never, NoError> in
guard let inputPeer else {
return .complete()
}
return account.network.request(Api.functions.messages.togglePaidReactionPrivacy(peer: inputPeer, msgId: messageId.id, private: isAnonymous ? .boolTrue : .boolFalse))
let mappedPrivacy: Api.PaidReactionPrivacy
switch privacy {
case .anonymous:
mappedPrivacy = .paidReactionPrivacyAnonymous
case .default:
mappedPrivacy = .paidReactionPrivacyDefault
case .peer:
guard let inputPrivacyPeer else {
return .complete()
}
mappedPrivacy = .paidReactionPrivacyPeer(peer: inputPrivacyPeer)
}
return account.network.request(Api.functions.messages.togglePaidReactionPrivacy(peer: inputPeer, msgId: messageId.id, private: mappedPrivacy))
|> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse)
}
@ -369,7 +400,7 @@ private func requestUpdateMessageReaction(postbox: Postbox, network: Network, st
}
private func requestSendStarsReaction(postbox: Postbox, network: Network, stateManager: AccountStateManager, messageId: MessageId) -> Signal<Never, RequestUpdateMessageReactionError> {
return postbox.transaction { transaction -> (Peer, Int32, Bool)? in
return postbox.transaction { transaction -> (Peer, Int32, Api.PaidReactionPrivacy)? in
guard let peer = transaction.getPeer(messageId.peerId) else {
return nil
}
@ -377,19 +408,32 @@ private func requestSendStarsReaction(postbox: Postbox, network: Network, stateM
return nil
}
var count: Int32 = 0
var isAnonymous = false
var privacy: Api.PaidReactionPrivacy = .paidReactionPrivacyDefault
for attribute in message.attributes {
if let attribute = attribute as? PendingStarsReactionsMessageAttribute {
count += attribute.count
isAnonymous = attribute.isAnonymous
let mappedPrivacy: Api.PaidReactionPrivacy
switch attribute.privacy {
case .anonymous:
mappedPrivacy = .paidReactionPrivacyAnonymous
case .default:
mappedPrivacy = .paidReactionPrivacyDefault
case let .peer(peerId):
guard let inputPrivacyPeer = transaction.getPeer(peerId).flatMap(apiInputPeer) else {
return nil
}
mappedPrivacy = .paidReactionPrivacyPeer(peer: inputPrivacyPeer)
}
privacy = mappedPrivacy
break
}
}
return (peer, count, isAnonymous)
return (peer, count, privacy)
}
|> castError(RequestUpdateMessageReactionError.self)
|> mapToSignal { peerAndValue in
guard let (peer, count, isAnonymous) = peerAndValue else {
guard let (peer, count, privacy) = peerAndValue else {
return .fail(.generic)
}
guard let inputPeer = apiInputPeer(peer) else {
@ -407,7 +451,7 @@ private func requestSendStarsReaction(postbox: Postbox, network: Network, stateM
var flags: Int32 = 0
flags |= 1 << 0
let signal: Signal<Never, RequestUpdateMessageReactionError> = network.request(Api.functions.messages.sendPaidReaction(flags: flags, peer: inputPeer, msgId: messageId.id, count: count, randomId: Int64(bitPattern: randomId), private: isAnonymous ? .boolTrue : .boolFalse))
let signal: Signal<Never, RequestUpdateMessageReactionError> = network.request(Api.functions.messages.sendPaidReaction(flags: flags, peer: inputPeer, msgId: messageId.id, count: count, randomId: Int64(bitPattern: randomId), private: privacy))
|> mapError { _ -> RequestUpdateMessageReactionError in
return .generic
}
@ -1031,10 +1075,29 @@ func _internal_updateDefaultReaction(account: Account, reaction: MessageReaction
}
struct StarsReactionDefaultToPrivateData: Codable {
var isPrivate: Bool
private enum CodingKeys: String, CodingKey {
case isPrivate = "isPrivate"
case privacy = "p"
}
init(isPrivate: Bool) {
self.isPrivate = isPrivate
var privacy: TelegramPaidReactionPrivacy
init(privacy: TelegramPaidReactionPrivacy) {
self.privacy = privacy
}
init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let privacy = try container.decodeIfPresent(TelegramPaidReactionPrivacy.self, forKey: .privacy) {
self.privacy = privacy
} else {
self.privacy = try container.decode(Bool.self, forKey: .isPrivate) ? .anonymous : .default
}
}
func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.privacy, forKey: .privacy)
}
static func key() -> ValueBoxKey {
@ -1044,15 +1107,15 @@ struct StarsReactionDefaultToPrivateData: Codable {
}
}
func _internal_getStarsReactionDefaultToPrivate(transaction: Transaction) -> Bool {
func _internal_getStarsReactionDefaultPrivacy(transaction: Transaction) -> TelegramPaidReactionPrivacy {
guard let value = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.starsReactionDefaultToPrivate, key: StarsReactionDefaultToPrivateData.key()))?.get(StarsReactionDefaultToPrivateData.self) else {
return false
return .default
}
return value.isPrivate
return value.privacy
}
func _internal_setStarsReactionDefaultToPrivate(isPrivate: Bool, transaction: Transaction) {
guard let entry = CodableEntry(StarsReactionDefaultToPrivateData(isPrivate: isPrivate)) else {
func _internal_setStarsReactionDefaultPrivacy(privacy: TelegramPaidReactionPrivacy, transaction: Transaction) {
guard let entry = CodableEntry(StarsReactionDefaultToPrivateData(privacy: privacy)) else {
return
}
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.starsReactionDefaultToPrivate, key: StarsReactionDefaultToPrivateData.key()), entry: entry)

View File

@ -565,7 +565,7 @@ public final class PendingReactionsMessageAttribute: MessageAttribute {
public final class PendingStarsReactionsMessageAttribute: MessageAttribute {
public let accountPeerId: PeerId?
public let count: Int32
public let isAnonymous: Bool
public let privacy: TelegramPaidReactionPrivacy
public var associatedPeerIds: [PeerId] {
var peerIds: [PeerId] = []
@ -575,16 +575,21 @@ public final class PendingStarsReactionsMessageAttribute: MessageAttribute {
return peerIds
}
public init(accountPeerId: PeerId?, count: Int32, isAnonymous: Bool) {
public init(accountPeerId: PeerId?, count: Int32, privacy: TelegramPaidReactionPrivacy) {
self.accountPeerId = accountPeerId
self.count = count
self.isAnonymous = isAnonymous
self.privacy = privacy
}
required public init(decoder: PostboxDecoder) {
self.accountPeerId = decoder.decodeOptionalInt64ForKey("ap").flatMap(PeerId.init)
self.count = decoder.decodeInt32ForKey("cnt", orElse: 1)
self.isAnonymous = decoder.decodeBoolForKey("anon", orElse: false)
if let privacy = decoder.decode(TelegramPaidReactionPrivacy.self, forKey: "priv") {
self.privacy = privacy
} else {
self.privacy = decoder.decodeBoolForKey("anon", orElse: false) ? .anonymous : .default
}
}
public func encode(_ encoder: PostboxEncoder) {
@ -594,6 +599,6 @@ public final class PendingStarsReactionsMessageAttribute: MessageAttribute {
encoder.encodeNil(forKey: "ap")
}
encoder.encodeInt32(self.count, forKey: "cnt")
encoder.encodeBool(self.isAnonymous, forKey: "anon")
encoder.encodeCodable(self.privacy, forKey: "priv")
}
}

View File

@ -2279,8 +2279,8 @@ public extension TelegramEngine.EngineData.Item {
}
}
public struct StarsReactionDefaultToPrivate: TelegramEngineDataItem, PostboxViewDataItem {
public typealias Result = Bool
public struct StarsReactionDefaultPrivacy: TelegramEngineDataItem, PostboxViewDataItem {
public typealias Result = TelegramPaidReactionPrivacy
public init() {
}
@ -2291,9 +2291,9 @@ public extension TelegramEngine.EngineData.Item {
func extract(view: PostboxView) -> Result {
if let value = (view as? CachedItemView)?.value?.get(StarsReactionDefaultToPrivateData.self) {
return value.isPrivate
return value.privacy
} else {
return false
return .default
}
}
}

View File

@ -337,8 +337,8 @@ public extension TelegramEngine {
).startStandalone()
}
public func sendStarsReaction(id: EngineMessage.Id, count: Int, isAnonymous: Bool?) -> Signal<Bool, NoError> {
return _internal_sendStarsReactionsInteractively(account: self.account, messageId: id, count: count, isAnonymous: isAnonymous)
public func sendStarsReaction(id: EngineMessage.Id, count: Int, privacy: TelegramPaidReactionPrivacy?) -> Signal<TelegramPaidReactionPrivacy, NoError> {
return _internal_sendStarsReactionsInteractively(account: self.account, messageId: id, count: count, privacy: privacy)
}
public func cancelPendingSendStarsReaction(id: EngineMessage.Id) {
@ -349,8 +349,8 @@ public extension TelegramEngine {
let _ = _internal_forceSendPendingSendStarsReaction(account: self.account, messageId: id).startStandalone()
}
public func updateStarsReactionIsAnonymous(id: EngineMessage.Id, isAnonymous: Bool) -> Signal<Never, NoError> {
return _internal_updateStarsReactionIsAnonymous(account: self.account, messageId: id, isAnonymous: isAnonymous)
public func updateStarsReactionPrivacy(id: EngineMessage.Id, privacy: TelegramPaidReactionPrivacy) -> Signal<Never, NoError> {
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> {

View File

@ -615,7 +615,7 @@ extension StarGift {
return nil
}
self = .generic(StarGift.Gift(id: id, file: file, price: stars, convertStars: convertStars, availability: availability, soldOut: soldOut, flags: flags, upgradeStars: upgradeStars))
case let .starGiftUnique(_, id, title, slug, num, ownerPeerId, ownerName, ownerAddress, attributes, availabilityIssued, availabilityTotal):
case let .starGiftUnique(_, id, title, slug, num, ownerPeerId, ownerName, ownerAddress, attributes, availabilityIssued, availabilityTotal, _):
let owner: StarGift.UniqueGift.Owner
if let ownerAddress {
owner = .address(ownerAddress)

View File

@ -95,6 +95,42 @@ public final class TelegramResolvedMessageLink {
}
}
public enum TelegramPaidReactionPrivacy: Equatable, Codable {
case `default`
case anonymous
case peer(PeerId)
enum CodingKeys: String, CodingKey {
case `default` = "d"
case anonymous = "a"
case peer = "p"
}
public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if try container.decodeNil(forKey: .default) {
self = .default
} else if try container.decodeNil(forKey: .anonymous) {
self = .anonymous
} else {
let peerId = PeerId(try container.decode(Int64.self, forKey: .peer))
self = .peer(peerId)
}
}
public func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .default:
try container.encodeNil(forKey: .default)
case .anonymous:
try container.encodeNil(forKey: .anonymous)
case let .peer(peerId):
try container.encode(peerId.toInt64(), forKey: .peer)
}
}
}
public extension TelegramEngine {
enum NextUnreadChannelLocation: Equatable {
case same
@ -1650,9 +1686,9 @@ public extension TelegramEngine {
}
}
public func setStarsReactionDefaultToPrivate(isPrivate: Bool) {
public func setStarsReactionDefaultPrivacy(privacy: TelegramPaidReactionPrivacy) {
let _ = self.account.postbox.transaction({ transaction in
_internal_setStarsReactionDefaultToPrivate(isPrivate: isPrivate, transaction: transaction)
_internal_setStarsReactionDefaultPrivacy(privacy: privacy, transaction: transaction)
}).startStandalone()
}

View File

@ -822,7 +822,6 @@ private final class ChatSendStarsScreenComponent: Component {
let context: AccountContext
let peer: EnginePeer
let myPeer: EnginePeer
let sendAsPeer: EnginePeer
let channelsForPublicReaction: [EnginePeer]
let messageId: EngineMessage.Id
let maxAmount: Int
@ -830,13 +829,12 @@ private final class ChatSendStarsScreenComponent: Component {
let currentSentAmount: Int?
let topPeers: [ChatSendStarsScreen.TopPeer]
let myTopPeer: ChatSendStarsScreen.TopPeer?
let completion: (Int64, Bool, Bool, ChatSendStarsScreen.TransitionOut) -> Void
let completion: (Int64, TelegramPaidReactionPrivacy, Bool, ChatSendStarsScreen.TransitionOut) -> Void
init(
context: AccountContext,
peer: EnginePeer,
myPeer: EnginePeer,
sendAsPeer: EnginePeer,
channelsForPublicReaction: [EnginePeer],
messageId: EngineMessage.Id,
maxAmount: Int,
@ -844,12 +842,11 @@ private final class ChatSendStarsScreenComponent: Component {
currentSentAmount: Int?,
topPeers: [ChatSendStarsScreen.TopPeer],
myTopPeer: ChatSendStarsScreen.TopPeer?,
completion: @escaping (Int64, Bool, Bool, ChatSendStarsScreen.TransitionOut) -> Void
completion: @escaping (Int64, TelegramPaidReactionPrivacy, Bool, ChatSendStarsScreen.TransitionOut) -> Void
) {
self.context = context
self.peer = peer
self.myPeer = myPeer
self.sendAsPeer = sendAsPeer
self.channelsForPublicReaction = channelsForPublicReaction
self.messageId = messageId
self.maxAmount = maxAmount
@ -870,9 +867,6 @@ private final class ChatSendStarsScreenComponent: Component {
if lhs.myPeer != rhs.myPeer {
return false
}
if lhs.sendAsPeer != rhs.sendAsPeer {
return false
}
if lhs.channelsForPublicReaction != rhs.channelsForPublicReaction {
return false
}
@ -991,6 +985,12 @@ private final class ChatSendStarsScreenComponent: Component {
}
}
private enum PrivacyPeer: Equatable {
case account
case anonymous
case peer(EnginePeer)
}
final class View: UIView, UIScrollViewDelegate {
private let dimView: UIView
private let backgroundLayer: SimpleLayer
@ -1041,7 +1041,7 @@ private final class ChatSendStarsScreenComponent: Component {
private var amount: Amount = Amount(realValue: 1, maxRealValue: 1000, maxSliderValue: 1000, isLogarithmic: true)
private var didChangeAmount: Bool = false
private var isAnonymous: Bool = false
private var privacyPeer: PrivacyPeer = .account
private var cachedStarImage: (UIImage, PresentationTheme)?
private var cachedCloseImage: UIImage?
@ -1386,7 +1386,25 @@ private final class ChatSendStarsScreenComponent: Component {
if self.currentMyPeer != peer {
self.currentMyPeer = peer
let _ = component.context.engine.peers.updatePeerSendAsPeer(peerId: component.peer.id, sendAs: peer.id).startStandalone()
if peer.id == component.context.account.peerId {
self.privacyPeer = .account
} else {
self.privacyPeer = .peer(peer)
}
if component.myTopPeer != nil {
let mappedPrivacy: TelegramPaidReactionPrivacy
switch self.privacyPeer {
case .account:
mappedPrivacy = .default
case .anonymous:
mappedPrivacy = .anonymous
case let .peer(peer):
mappedPrivacy = .peer(peer.id)
}
let _ = component.context.engine.messages.updateStarsReactionPrivacy(id: component.messageId, privacy: mappedPrivacy).startStandalone()
}
}
self.state?.updated(transition: .immediate)
@ -1421,7 +1439,16 @@ private final class ChatSendStarsScreenComponent: Component {
}
self.amount = Amount(realValue: 50, maxRealValue: component.maxAmount, maxSliderValue: 999, isLogarithmic: isLogarithmic)
if let myTopPeer = component.myTopPeer {
self.isAnonymous = myTopPeer.isAnonymous
if myTopPeer.isAnonymous {
self.privacyPeer = .anonymous
} else if myTopPeer.peer?.id == component.context.account.peerId {
self.privacyPeer = .account
} else if let peer = myTopPeer.peer {
self.privacyPeer = .peer(peer)
self.currentMyPeer = peer
} else {
self.privacyPeer = .account
}
}
if let starsContext = component.context.starsContext {
@ -1439,8 +1466,7 @@ private final class ChatSendStarsScreenComponent: Component {
})
}
//TODO:wip-release
/*self.channelsForPublicReactionDisposable = (component.context.engine.peers.channelsForPublicReaction(useLocalCache: false)
self.channelsForPublicReactionDisposable = (component.context.engine.peers.channelsForPublicReaction(useLocalCache: false)
|> deliverOnMainQueue).startStrict(next: { [weak self] peers in
guard let self else {
return
@ -1449,7 +1475,7 @@ private final class ChatSendStarsScreenComponent: Component {
self.channelsForPublicReaction = peers
self.state?.updated(transition: .immediate)
}
})*/
})
}
self.component = component
@ -1861,9 +1887,19 @@ private final class ChatSendStarsScreenComponent: Component {
}
myCount += myCountAddition
if myCount != 0 {
var topPeer: EnginePeer?
switch self.privacyPeer {
case .anonymous:
topPeer = nil
case .account:
topPeer = component.myPeer
case let .peer(peer):
topPeer = peer
}
mappedTopPeers.append(ChatSendStarsScreen.TopPeer(
randomIndex: -1,
peer: self.isAnonymous ? nil : currentMyPeer,
peer: topPeer,
isMy: true,
count: myCount
))
@ -2021,7 +2057,7 @@ private final class ChatSendStarsScreenComponent: Component {
content: AnyComponent(HStack([
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(CheckComponent(
theme: checkTheme,
selected: !self.isAnonymous
selected: self.privacyPeer != .anonymous
))),
AnyComponentWithIdentity(id: AnyHashable(1), component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: environment.strings.SendStarReactions_ShowMyselfInTop, font: Font.regular(16.0), textColor: environment.theme.list.itemPrimaryTextColor))
@ -2034,11 +2070,33 @@ private final class ChatSendStarsScreenComponent: Component {
guard let self, let component = self.component else {
return
}
self.isAnonymous = !self.isAnonymous
switch self.privacyPeer {
case .anonymous:
if let currentMyPeer = self.currentMyPeer {
if currentMyPeer.id == component.context.account.peerId {
self.privacyPeer = .account
} else {
self.privacyPeer = .peer(currentMyPeer)
}
}
default:
self.privacyPeer = .anonymous
}
self.state?.updated(transition: .easeInOut(duration: 0.2))
if component.myTopPeer != nil {
let _ = component.context.engine.messages.updateStarsReactionIsAnonymous(id: component.messageId, isAnonymous: self.isAnonymous).startStandalone()
let mappedPrivacy: TelegramPaidReactionPrivacy
switch self.privacyPeer {
case .account:
mappedPrivacy = .default
case .anonymous:
mappedPrivacy = .anonymous
case let .peer(peer):
mappedPrivacy = .peer(peer.id)
}
let _ = component.context.engine.messages.updateStarsReactionPrivacy(id: component.messageId, privacy: mappedPrivacy).startStandalone()
}
},
animateAlpha: false,
@ -2132,9 +2190,19 @@ private final class ChatSendStarsScreenComponent: Component {
isBecomingTop = true
}
let mappedPrivacy: TelegramPaidReactionPrivacy
switch self.privacyPeer {
case .account:
mappedPrivacy = .default
case .anonymous:
mappedPrivacy = .anonymous
case let .peer(peer):
mappedPrivacy = .peer(peer.id)
}
component.completion(
Int64(self.amount.realValue),
self.isAnonymous,
mappedPrivacy,
isBecomingTop,
ChatSendStarsScreen.TransitionOut(
sourceView: badgeView.badgeIcon
@ -2248,7 +2316,6 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
public final class InitialData {
fileprivate let peer: EnginePeer
fileprivate let myPeer: EnginePeer
fileprivate let sendAsPeer: EnginePeer
fileprivate let channelsForPublicReaction: [EnginePeer]
fileprivate let messageId: EngineMessage.Id
fileprivate let balance: StarsAmount?
@ -2259,7 +2326,6 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
fileprivate init(
peer: EnginePeer,
myPeer: EnginePeer,
sendAsPeer: EnginePeer,
channelsForPublicReaction: [EnginePeer],
messageId: EngineMessage.Id,
balance: StarsAmount?,
@ -2269,7 +2335,6 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
) {
self.peer = peer
self.myPeer = myPeer
self.sendAsPeer = sendAsPeer
self.channelsForPublicReaction = channelsForPublicReaction
self.messageId = messageId
self.balance = balance
@ -2344,7 +2409,7 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
private var presenceDisposable: Disposable?
public init(context: AccountContext, initialData: InitialData, completion: @escaping (Int64, Bool, Bool, TransitionOut) -> Void) {
public init(context: AccountContext, initialData: InitialData, completion: @escaping (Int64, TelegramPaidReactionPrivacy, Bool, TransitionOut) -> Void) {
self.context = context
var maxAmount = 2500
@ -2356,7 +2421,6 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
context: context,
peer: initialData.peer,
myPeer: initialData.myPeer,
sendAsPeer: initialData.sendAsPeer,
channelsForPublicReaction: initialData.channelsForPublicReaction,
messageId: initialData.messageId,
maxAmount: maxAmount,
@ -2420,10 +2484,7 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
topPeers = Array(topPeers.prefix(3))
}
//TODO:wip-release
//let channelsForPublicReaction = context.engine.peers.channelsForPublicReaction(useLocalCache: true)
let channelsForPublicReaction: Signal<[EnginePeer], NoError> = .single([])
let sendAsPeer: Signal<EnginePeer?, NoError> = .single(nil)
let channelsForPublicReaction = context.engine.peers.channelsForPublicReaction(useLocalCache: true)
return combineLatest(
context.engine.data.get(
@ -2432,10 +2493,9 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
EngineDataMap(allPeerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
),
balance,
sendAsPeer,
channelsForPublicReaction
)
|> map { peerAndTopPeerMap, balance, sendAsPeer, channelsForPublicReaction -> InitialData? in
|> map { peerAndTopPeerMap, balance, channelsForPublicReaction -> InitialData? in
let (peer, myPeer, topPeerMap) = peerAndTopPeerMap
guard let peer, let myPeer else {
return nil
@ -2445,7 +2505,6 @@ public class ChatSendStarsScreen: ViewControllerComponentContainer {
return InitialData(
peer: peer,
myPeer: myPeer,
sendAsPeer: sendAsPeer ?? myPeer,
channelsForPublicReaction: channelsForPublicReaction,
messageId: messageId,
balance: balance,

View File

@ -457,12 +457,12 @@ extension ChatControllerImpl {
return
}
let _ = (strongSelf.context.engine.messages.sendStarsReaction(id: message.id, count: 1, isAnonymous: nil)
|> deliverOnMainQueue).startStandalone(next: { isAnonymous in
let _ = (strongSelf.context.engine.messages.sendStarsReaction(id: message.id, count: 1, privacy: nil)
|> deliverOnMainQueue).startStandalone(next: { privacy in
guard let strongSelf = self else {
return
}
strongSelf.displayOrUpdateSendStarsUndo(messageId: message.id, count: 1, isAnonymous: isAnonymous)
strongSelf.displayOrUpdateSendStarsUndo(messageId: message.id, count: 1, privacy: privacy)
})
})
} else {

View File

@ -1787,12 +1787,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
let _ = (strongSelf.context.engine.messages.sendStarsReaction(id: message.id, count: 1, isAnonymous: nil)
|> deliverOnMainQueue).startStandalone(next: { isAnonymous in
let _ = (strongSelf.context.engine.messages.sendStarsReaction(id: message.id, count: 1, privacy: nil)
|> deliverOnMainQueue).startStandalone(next: { privacy in
guard let strongSelf = self else {
return
}
strongSelf.displayOrUpdateSendStarsUndo(messageId: message.id, count: 1, isAnonymous: isAnonymous)
strongSelf.displayOrUpdateSendStarsUndo(messageId: message.id, count: 1, privacy: privacy)
})
})
} else {

View File

@ -391,7 +391,7 @@ extension ChatControllerImpl {
return
}
HapticFeedback().tap()
self.push(ChatSendStarsScreen(context: self.context, initialData: initialData, completion: { [weak self] amount, isAnonymous, isBecomingTop, transitionOut in
self.push(ChatSendStarsScreen(context: self.context, initialData: initialData, completion: { [weak self] amount, privacy, isBecomingTop, transitionOut in
guard let self, amount > 0 else {
return
}
@ -485,14 +485,14 @@ extension ChatControllerImpl {
}
}
let _ = self.context.engine.messages.sendStarsReaction(id: message.id, count: Int(amount), isAnonymous: isAnonymous).startStandalone()
self.displayOrUpdateSendStarsUndo(messageId: message.id, count: Int(amount), isAnonymous: isAnonymous)
let _ = self.context.engine.messages.sendStarsReaction(id: message.id, count: Int(amount), privacy: privacy).startStandalone()
self.displayOrUpdateSendStarsUndo(messageId: message.id, count: Int(amount), privacy: privacy)
}))
})
})
}
func displayOrUpdateSendStarsUndo(messageId: EngineMessage.Id, count: Int, isAnonymous: Bool) {
func displayOrUpdateSendStarsUndo(messageId: EngineMessage.Id, count: Int, privacy: TelegramPaidReactionPrivacy) {
if self.currentSendStarsUndoMessageId != messageId {
if let current = self.currentSendStarsUndoController {
self.currentSendStarsUndoController = nil
@ -507,7 +507,7 @@ extension ChatControllerImpl {
}
let title: String
if isAnonymous {
if case .anonymous = privacy {
title = self.presentationData.strings.Chat_ToastStarsSent_AnonymousTitle(Int32(self.currentSendStarsUndoCount))
} else {
title = self.presentationData.strings.Chat_ToastStarsSent_Title(Int32(self.currentSendStarsUndoCount))