Update API

This commit is contained in:
Ilya Laktyushin 2024-04-04 02:41:40 +04:00
parent e110ebefbc
commit 06d5377bd4
29 changed files with 425 additions and 687 deletions

View File

@ -11887,3 +11887,7 @@ Sorry for the inconvenience.";
"StoryList.SubtitleArchived_1" = "1 archived post"; "StoryList.SubtitleArchived_1" = "1 archived post";
"StoryList.SubtitleArchived_any" = "%d archived posts"; "StoryList.SubtitleArchived_any" = "%d archived posts";
"Business.AdsTitle" = "ADS IN CHANNELS";
"Business.DontHideAds" = "Do Not Hide Ads";
"Business.AdsInfo" = "As a Premium subscriber, you don't see any ads on Telegram, but you can turn them on, for example, to view your own ads that you launched on the [Telegram Ad Platform >]()";

View File

@ -1808,11 +1808,8 @@ public final class ChatListNode: ListView {
self.present?(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.ChatList_BirthdayInSettingsInfo, timeout: 5.0, customUndoText: nil), elevatedLayout: false, action: { _ in self.present?(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.ChatList_BirthdayInSettingsInfo, timeout: 5.0, customUndoText: nil), elevatedLayout: false, action: { _ in
return true return true
})) }))
case let .birthdayPremiumGift(peers, _): case .birthdayPremiumGift:
let peerIds = peers.sorted { lhs, rhs in let _ = self.context.engine.notices.dismissServerProvidedSuggestion(suggestion: .todayBirthdays).startStandalone()
return lhs.id < rhs.id
}
let _ = ApplicationSpecificNotice.setDismissedBirthdayPremiumGifts(accountManager: self.context.sharedContext.accountManager, values: peerIds.map { $0.id.toInt64() }).start()
self.present?(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.ChatList_PremiumGiftInSettingsInfo, timeout: 5.0, customUndoText: nil), elevatedLayout: false, action: { _ in self.present?(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.ChatList_PremiumGiftInSettingsInfo, timeout: 5.0, customUndoText: nil), elevatedLayout: false, action: { _ in
return true return true
})) }))
@ -1909,13 +1906,13 @@ public final class ChatListNode: ListView {
let suggestedChatListNoticeSignal: Signal<ChatListNotice?, NoError> = combineLatest( let suggestedChatListNoticeSignal: Signal<ChatListNotice?, NoError> = combineLatest(
context.engine.notices.getServerProvidedSuggestions(), context.engine.notices.getServerProvidedSuggestions(),
context.engine.notices.getServerDismissedSuggestions(),
twoStepData, twoStepData,
newSessionReviews(postbox: context.account.postbox), newSessionReviews(postbox: context.account.postbox),
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Birthday(id: context.account.peerId)), context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Birthday(id: context.account.peerId)),
context.account.stateManager.contactBirthdays, context.account.stateManager.contactBirthdays
ApplicationSpecificNotice.dismissedBirthdayPremiumGifts(accountManager: context.sharedContext.accountManager)
) )
|> mapToSignal { suggestions, configuration, newSessionReviews, birthday, birthdays, dismissedBirthdayPeerIds -> Signal<ChatListNotice?, NoError> in |> mapToSignal { suggestions, dismissedSuggestions, configuration, newSessionReviews, birthday, birthdays -> Signal<ChatListNotice?, NoError> in
if let newSessionReview = newSessionReviews.first { if let newSessionReview = newSessionReviews.first {
return .single(.reviewLogin(newSessionReview: newSessionReview, totalCount: newSessionReviews.count)) return .single(.reviewLogin(newSessionReview: newSessionReview, totalCount: newSessionReviews.count))
} }
@ -1945,6 +1942,10 @@ public final class ChatListNode: ListView {
return lhs < rhs return lhs < rhs
} }
if dismissedSuggestions.contains(.todayBirthdays) {
todayBirthdayPeerIds = []
}
if suggestions.contains(.setupBirthday) && birthday == nil { if suggestions.contains(.setupBirthday) && birthday == nil {
return .single(.setupBirthday) return .single(.setupBirthday)
} else if suggestions.contains(.xmasPremiumGift) { } else if suggestions.contains(.xmasPremiumGift) {
@ -1989,7 +1990,7 @@ public final class ChatListNode: ListView {
return nil return nil
} }
} }
} else if !todayBirthdayPeerIds.isEmpty && todayBirthdayPeerIds.map({ $0.toInt64() }) != dismissedBirthdayPeerIds { } else if !todayBirthdayPeerIds.isEmpty {
return context.engine.data.get( return context.engine.data.get(
EngineDataMap(todayBirthdayPeerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:))) EngineDataMap(todayBirthdayPeerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
) )

View File

@ -1653,6 +1653,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
let optionsSection = Child(SectionGroupComponent.self) let optionsSection = Child(SectionGroupComponent.self)
let businessSection = Child(ListSectionComponent.self) let businessSection = Child(ListSectionComponent.self)
let moreBusinessSection = Child(ListSectionComponent.self) let moreBusinessSection = Child(ListSectionComponent.self)
let adsSettingsSection = Child(ListSectionComponent.self)
let perksSection = Child(ListSectionComponent.self) let perksSection = Child(ListSectionComponent.self)
let infoBackground = Child(RoundedRectangle.self) let infoBackground = Child(RoundedRectangle.self)
let infoTitle = Child(MultilineTextComponent.self) let infoTitle = Child(MultilineTextComponent.self)
@ -2464,6 +2465,69 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
size.height += 23.0 size.height += 23.0
} }
let termsFont = Font.regular(13.0)
let boldTermsFont = Font.semibold(13.0)
let italicTermsFont = Font.italic(13.0)
let boldItalicTermsFont = Font.semiboldItalic(13.0)
let monospaceTermsFont = Font.monospace(13.0)
let termsTextColor = environment.theme.list.freeTextColor
let termsMarkdownAttributes = MarkdownAttributes(body: MarkdownAttributeSet(font: termsFont, textColor: termsTextColor), bold: MarkdownAttributeSet(font: termsFont, textColor: termsTextColor), link: MarkdownAttributeSet(font: termsFont, textColor: environment.theme.list.itemAccentColor), linkAttribute: { contents in
return (TelegramTextAttributes.URL, contents)
})
let layoutAdsSettings = {
size.height += 8.0
var adsSettingsItems: [AnyComponentWithIdentity<Empty>] = []
adsSettingsItems.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(ListActionItemComponent(
theme: environment.theme,
title: AnyComponent(VStack([
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: environment.strings.Business_DontHideAds,
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
textColor: environment.theme.list.itemPrimaryTextColor
)),
maximumNumberOfLines: 1
))),
], alignment: .left, spacing: 2.0)),
accessory: .toggle(ListActionItemComponent.Toggle(style: .regular, isOn: false, action: { [weak state] value in
let _ = accountContext.engine.accountData.updateAdMessagesEnabled(enabled: value).startStandalone()
state?.updated(transition: .immediate)
})),
action: nil
))))
let adsSettingsSection = adsSettingsSection.update(
component: ListSectionComponent(
theme: environment.theme,
header: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(
string: strings.Business_AdsTitle.uppercased(),
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
textColor: environment.theme.list.freeTextColor
)),
maximumNumberOfLines: 0
)),
footer: AnyComponent(MultilineTextComponent(
text: .markdown(text: environment.strings.Business_AdsInfo, attributes: termsMarkdownAttributes),
maximumNumberOfLines: 0
)),
items: adsSettingsItems
),
environment: {},
availableSize: CGSize(width: availableWidth - sideInsets, height: .greatestFiniteMagnitude),
transition: context.transition
)
context.add(adsSettingsSection
.position(CGPoint(x: availableWidth / 2.0, y: size.height + adsSettingsSection.size.height / 2.0))
.clipsToBounds(true)
.cornerRadius(10.0)
)
size.height += adsSettingsSection.size.height
size.height += 23.0
}
let copyLink = context.component.copyLink let copyLink = context.component.copyLink
if case .emojiStatus = context.component.source { if case .emojiStatus = context.component.source {
layoutPerks() layoutPerks()
@ -2499,6 +2563,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
layoutBusinessPerks() layoutBusinessPerks()
if context.component.isPremium == true { if context.component.isPremium == true {
layoutMoreBusinessPerks() layoutMoreBusinessPerks()
layoutAdsSettings()
} }
} else { } else {
layoutPerks() layoutPerks()
@ -2556,17 +2621,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
) )
size.height += infoBackground.size.height size.height += infoBackground.size.height
size.height += 6.0 size.height += 6.0
let termsFont = Font.regular(13.0)
let boldTermsFont = Font.semibold(13.0)
let italicTermsFont = Font.italic(13.0)
let boldItalicTermsFont = Font.semiboldItalic(13.0)
let monospaceTermsFont = Font.monospace(13.0)
let termsTextColor = environment.theme.list.freeTextColor
let termsMarkdownAttributes = MarkdownAttributes(body: MarkdownAttributeSet(font: termsFont, textColor: termsTextColor), bold: MarkdownAttributeSet(font: termsFont, textColor: termsTextColor), link: MarkdownAttributeSet(font: termsFont, textColor: environment.theme.list.itemAccentColor), linkAttribute: { contents in
return (TelegramTextAttributes.URL, contents)
})
var isGiftView = false var isGiftView = false
if case let .gift(fromId, _, _, _) = context.component.source { if case let .gift(fromId, _, _, _) = context.component.source {
if fromId == context.component.context.account.peerId { if fromId == context.component.context.account.peerId {

View File

@ -198,8 +198,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1605510357] = { return Api.ChatAdminRights.parse_chatAdminRights($0) } dict[1605510357] = { return Api.ChatAdminRights.parse_chatAdminRights($0) }
dict[-219353309] = { return Api.ChatAdminWithInvites.parse_chatAdminWithInvites($0) } dict[-219353309] = { return Api.ChatAdminWithInvites.parse_chatAdminWithInvites($0) }
dict[-1626209256] = { return Api.ChatBannedRights.parse_chatBannedRights($0) } dict[-1626209256] = { return Api.ChatBannedRights.parse_chatBannedRights($0) }
dict[1153455271] = { return Api.ChatFull.parse_channelFull($0) } dict[-1146407795] = { return Api.ChatFull.parse_channelFull($0) }
dict[-908914376] = { return Api.ChatFull.parse_chatFull($0) } dict[640893467] = { return Api.ChatFull.parse_chatFull($0) }
dict[-840897472] = { return Api.ChatInvite.parse_chatInvite($0) } dict[-840897472] = { return Api.ChatInvite.parse_chatInvite($0) }
dict[1516793212] = { return Api.ChatInvite.parse_chatInviteAlready($0) } dict[1516793212] = { return Api.ChatInvite.parse_chatInviteAlready($0) }
dict[1634294960] = { return Api.ChatInvite.parse_chatInvitePeek($0) } dict[1634294960] = { return Api.ChatInvite.parse_chatInvitePeek($0) }
@ -857,9 +857,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1239335713] = { return Api.ShippingOption.parse_shippingOption($0) } dict[-1239335713] = { return Api.ShippingOption.parse_shippingOption($0) }
dict[-2010155333] = { return Api.SimpleWebViewResult.parse_simpleWebViewResultUrl($0) } dict[-2010155333] = { return Api.SimpleWebViewResult.parse_simpleWebViewResultUrl($0) }
dict[-425595208] = { return Api.SmsJob.parse_smsJob($0) } dict[-425595208] = { return Api.SmsJob.parse_smsJob($0) }
dict[-313293833] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) } dict[-1611532106] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) }
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) } dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
dict[1035529315] = { return Api.SponsoredWebPage.parse_sponsoredWebPage($0) }
dict[-884757282] = { return Api.StatsAbsValueAndPrev.parse_statsAbsValueAndPrev($0) } dict[-884757282] = { return Api.StatsAbsValueAndPrev.parse_statsAbsValueAndPrev($0) }
dict[-1237848657] = { return Api.StatsDateRangeDays.parse_statsDateRangeDays($0) } dict[-1237848657] = { return Api.StatsDateRangeDays.parse_statsDateRangeDays($0) }
dict[-1901828938] = { return Api.StatsGraph.parse_statsGraph($0) } dict[-1901828938] = { return Api.StatsGraph.parse_statsGraph($0) }
@ -1932,8 +1931,6 @@ public extension Api {
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.SponsoredMessageReportOption: case let _1 as Api.SponsoredMessageReportOption:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.SponsoredWebPage:
_1.serialize(buffer, boxed)
case let _1 as Api.StatsAbsValueAndPrev: case let _1 as Api.StatsAbsValueAndPrev:
_1.serialize(buffer, boxed) _1.serialize(buffer, boxed)
case let _1 as Api.StatsDateRangeDays: case let _1 as Api.StatsDateRangeDays:

View File

@ -477,31 +477,27 @@ public extension Api {
} }
} }
public extension Api { public extension Api {
indirect enum SponsoredMessage: TypeConstructorDescription { enum SponsoredMessage: TypeConstructorDescription {
case sponsoredMessage(flags: Int32, randomId: Buffer, fromId: Api.Peer?, chatInvite: Api.ChatInvite?, chatInviteHash: String?, channelPost: Int32?, startParam: String?, webpage: Api.SponsoredWebPage?, app: Api.BotApp?, message: String, entities: [Api.MessageEntity]?, buttonText: String?, sponsorInfo: String?, additionalInfo: String?) case sponsoredMessage(flags: Int32, randomId: Buffer, url: String, title: String, message: String, entities: [Api.MessageEntity]?, photo: Api.Photo?, buttonText: String, sponsorInfo: String?, additionalInfo: String?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
case .sponsoredMessage(let flags, let randomId, let fromId, let chatInvite, let chatInviteHash, let channelPost, let startParam, let webpage, let app, let message, let entities, let buttonText, let sponsorInfo, let additionalInfo): case .sponsoredMessage(let flags, let randomId, let url, let title, let message, let entities, let photo, let buttonText, let sponsorInfo, let additionalInfo):
if boxed { if boxed {
buffer.appendInt32(-313293833) buffer.appendInt32(-1611532106)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeBytes(randomId, buffer: buffer, boxed: false) serializeBytes(randomId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 3) != 0 {fromId!.serialize(buffer, true)} serializeString(url, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 4) != 0 {chatInvite!.serialize(buffer, true)} serializeString(title, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 4) != 0 {serializeString(chatInviteHash!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(channelPost!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 0) != 0 {serializeString(startParam!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 9) != 0 {webpage!.serialize(buffer, true)}
if Int(flags) & Int(1 << 10) != 0 {app!.serialize(buffer, true)}
serializeString(message, buffer: buffer, boxed: false) serializeString(message, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261) if Int(flags) & Int(1 << 1) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(entities!.count)) buffer.appendInt32(Int32(entities!.count))
for item in entities! { for item in entities! {
item.serialize(buffer, true) item.serialize(buffer, true)
}} }}
if Int(flags) & Int(1 << 11) != 0 {serializeString(buttonText!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 6) != 0 {photo!.serialize(buffer, true)}
serializeString(buttonText, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 7) != 0 {serializeString(sponsorInfo!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 7) != 0 {serializeString(sponsorInfo!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 8) != 0 {serializeString(additionalInfo!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 8) != 0 {serializeString(additionalInfo!, buffer: buffer, boxed: false)}
break break
@ -510,8 +506,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) { public func descriptionFields() -> (String, [(String, Any)]) {
switch self { switch self {
case .sponsoredMessage(let flags, let randomId, let fromId, let chatInvite, let chatInviteHash, let channelPost, let startParam, let webpage, let app, let message, let entities, let buttonText, let sponsorInfo, let additionalInfo): case .sponsoredMessage(let flags, let randomId, let url, let title, let message, let entities, let photo, let buttonText, let sponsorInfo, let additionalInfo):
return ("sponsoredMessage", [("flags", flags as Any), ("randomId", randomId as Any), ("fromId", fromId as Any), ("chatInvite", chatInvite as Any), ("chatInviteHash", chatInviteHash as Any), ("channelPost", channelPost as Any), ("startParam", startParam as Any), ("webpage", webpage as Any), ("app", app as Any), ("message", message as Any), ("entities", entities as Any), ("buttonText", buttonText as Any), ("sponsorInfo", sponsorInfo as Any), ("additionalInfo", additionalInfo as Any)]) return ("sponsoredMessage", [("flags", flags as Any), ("randomId", randomId as Any), ("url", url as Any), ("title", title as Any), ("message", message as Any), ("entities", entities as Any), ("photo", photo as Any), ("buttonText", buttonText as Any), ("sponsorInfo", sponsorInfo as Any), ("additionalInfo", additionalInfo as Any)])
} }
} }
@ -520,56 +516,38 @@ public extension Api {
_1 = reader.readInt32() _1 = reader.readInt32()
var _2: Buffer? var _2: Buffer?
_2 = parseBytes(reader) _2 = parseBytes(reader)
var _3: Api.Peer? var _3: String?
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() { _3 = parseString(reader)
_3 = Api.parse(reader, signature: signature) as? Api.Peer var _4: String?
} } _4 = parseString(reader)
var _4: Api.ChatInvite?
if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
_4 = Api.parse(reader, signature: signature) as? Api.ChatInvite
} }
var _5: String? var _5: String?
if Int(_1!) & Int(1 << 4) != 0 {_5 = parseString(reader) } _5 = parseString(reader)
var _6: Int32? var _6: [Api.MessageEntity]?
if Int(_1!) & Int(1 << 2) != 0 {_6 = reader.readInt32() }
var _7: String?
if Int(_1!) & Int(1 << 0) != 0 {_7 = parseString(reader) }
var _8: Api.SponsoredWebPage?
if Int(_1!) & Int(1 << 9) != 0 {if let signature = reader.readInt32() {
_8 = Api.parse(reader, signature: signature) as? Api.SponsoredWebPage
} }
var _9: Api.BotApp?
if Int(_1!) & Int(1 << 10) != 0 {if let signature = reader.readInt32() {
_9 = Api.parse(reader, signature: signature) as? Api.BotApp
} }
var _10: String?
_10 = parseString(reader)
var _11: [Api.MessageEntity]?
if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() { if Int(_1!) & Int(1 << 1) != 0 {if let _ = reader.readInt32() {
_11 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self) _6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
} } } }
var _12: String? var _7: Api.Photo?
if Int(_1!) & Int(1 << 11) != 0 {_12 = parseString(reader) } if Int(_1!) & Int(1 << 6) != 0 {if let signature = reader.readInt32() {
var _13: String? _7 = Api.parse(reader, signature: signature) as? Api.Photo
if Int(_1!) & Int(1 << 7) != 0 {_13 = parseString(reader) } } }
var _14: String? var _8: String?
if Int(_1!) & Int(1 << 8) != 0 {_14 = parseString(reader) } _8 = parseString(reader)
var _9: String?
if Int(_1!) & Int(1 << 7) != 0 {_9 = parseString(reader) }
var _10: String?
if Int(_1!) & Int(1 << 8) != 0 {_10 = parseString(reader) }
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 3) == 0) || _3 != nil let _c3 = _3 != nil
let _c4 = (Int(_1!) & Int(1 << 4) == 0) || _4 != nil let _c4 = _4 != nil
let _c5 = (Int(_1!) & Int(1 << 4) == 0) || _5 != nil let _c5 = _5 != nil
let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil let _c6 = (Int(_1!) & Int(1 << 1) == 0) || _6 != nil
let _c7 = (Int(_1!) & Int(1 << 0) == 0) || _7 != nil let _c7 = (Int(_1!) & Int(1 << 6) == 0) || _7 != nil
let _c8 = (Int(_1!) & Int(1 << 9) == 0) || _8 != nil let _c8 = _8 != nil
let _c9 = (Int(_1!) & Int(1 << 10) == 0) || _9 != nil let _c9 = (Int(_1!) & Int(1 << 7) == 0) || _9 != nil
let _c10 = _10 != nil let _c10 = (Int(_1!) & Int(1 << 8) == 0) || _10 != nil
let _c11 = (Int(_1!) & Int(1 << 1) == 0) || _11 != nil if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 {
let _c12 = (Int(_1!) & Int(1 << 11) == 0) || _12 != nil return Api.SponsoredMessage.sponsoredMessage(flags: _1!, randomId: _2!, url: _3!, title: _4!, message: _5!, entities: _6, photo: _7, buttonText: _8!, sponsorInfo: _9, additionalInfo: _10)
let _c13 = (Int(_1!) & Int(1 << 7) == 0) || _13 != nil
let _c14 = (Int(_1!) & Int(1 << 8) == 0) || _14 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 {
return Api.SponsoredMessage.sponsoredMessage(flags: _1!, randomId: _2!, fromId: _3, chatInvite: _4, chatInviteHash: _5, channelPost: _6, startParam: _7, webpage: _8, app: _9, message: _10!, entities: _11, buttonText: _12, sponsorInfo: _13, additionalInfo: _14)
} }
else { else {
return nil return nil
@ -618,56 +596,6 @@ public extension Api {
} }
} }
public extension Api {
enum SponsoredWebPage: TypeConstructorDescription {
case sponsoredWebPage(flags: Int32, url: String, siteName: String, photo: Api.Photo?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .sponsoredWebPage(let flags, let url, let siteName, let photo):
if boxed {
buffer.appendInt32(1035529315)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(url, buffer: buffer, boxed: false)
serializeString(siteName, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {photo!.serialize(buffer, true)}
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .sponsoredWebPage(let flags, let url, let siteName, let photo):
return ("sponsoredWebPage", [("flags", flags as Any), ("url", url as Any), ("siteName", siteName as Any), ("photo", photo as Any)])
}
}
public static func parse_sponsoredWebPage(_ reader: BufferReader) -> SponsoredWebPage? {
var _1: Int32?
_1 = reader.readInt32()
var _2: String?
_2 = parseString(reader)
var _3: String?
_3 = parseString(reader)
var _4: Api.Photo?
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
_4 = Api.parse(reader, signature: signature) as? Api.Photo
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.SponsoredWebPage.sponsoredWebPage(flags: _1!, url: _2!, siteName: _3!, photo: _4)
}
else {
return nil
}
}
}
}
public extension Api { public extension Api {
enum StatsAbsValueAndPrev: TypeConstructorDescription { enum StatsAbsValueAndPrev: TypeConstructorDescription {
case statsAbsValueAndPrev(current: Double, previous: Double) case statsAbsValueAndPrev(current: Double, previous: Double)
@ -922,3 +850,47 @@ public extension Api {
} }
} }
public extension Api {
enum StatsGroupTopPoster: TypeConstructorDescription {
case statsGroupTopPoster(userId: Int64, messages: Int32, avgChars: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .statsGroupTopPoster(let userId, let messages, let avgChars):
if boxed {
buffer.appendInt32(-1660637285)
}
serializeInt64(userId, buffer: buffer, boxed: false)
serializeInt32(messages, buffer: buffer, boxed: false)
serializeInt32(avgChars, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .statsGroupTopPoster(let userId, let messages, let avgChars):
return ("statsGroupTopPoster", [("userId", userId as Any), ("messages", messages as Any), ("avgChars", avgChars as Any)])
}
}
public static func parse_statsGroupTopPoster(_ reader: BufferReader) -> StatsGroupTopPoster? {
var _1: Int64?
_1 = reader.readInt64()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.StatsGroupTopPoster.statsGroupTopPoster(userId: _1!, messages: _2!, avgChars: _3!)
}
else {
return nil
}
}
}
}

View File

@ -1,47 +1,3 @@
public extension Api {
enum StatsGroupTopPoster: TypeConstructorDescription {
case statsGroupTopPoster(userId: Int64, messages: Int32, avgChars: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .statsGroupTopPoster(let userId, let messages, let avgChars):
if boxed {
buffer.appendInt32(-1660637285)
}
serializeInt64(userId, buffer: buffer, boxed: false)
serializeInt32(messages, buffer: buffer, boxed: false)
serializeInt32(avgChars, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .statsGroupTopPoster(let userId, let messages, let avgChars):
return ("statsGroupTopPoster", [("userId", userId as Any), ("messages", messages as Any), ("avgChars", avgChars as Any)])
}
}
public static func parse_statsGroupTopPoster(_ reader: BufferReader) -> StatsGroupTopPoster? {
var _1: Int64?
_1 = reader.readInt64()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.StatsGroupTopPoster.statsGroupTopPoster(userId: _1!, messages: _2!, avgChars: _3!)
}
else {
return nil
}
}
}
}
public extension Api { public extension Api {
enum StatsPercentValue: TypeConstructorDescription { enum StatsPercentValue: TypeConstructorDescription {
case statsPercentValue(part: Double, total: Double) case statsPercentValue(part: Double, total: Double)

View File

@ -1361,6 +1361,21 @@ public extension Api.functions.account {
}) })
} }
} }
public extension Api.functions.account {
static func toggleSponsoredMessages(enabled: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(-1176919155)
enabled.serialize(buffer, true)
return (FunctionDescription(name: "account.toggleSponsoredMessages", parameters: [("enabled", String(describing: enabled))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.account { public extension Api.functions.account {
static func toggleUsername(username: String, active: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) { static func toggleUsername(username: String, active: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer() let buffer = Buffer()
@ -2770,11 +2785,12 @@ public extension Api.functions.channels {
} }
} }
public extension Api.functions.channels { public extension Api.functions.channels {
static func getChannelRecommendations(channel: Api.InputChannel) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.Chats>) { static func getChannelRecommendations(flags: Int32, channel: Api.InputChannel?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.Chats>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(-2085155433) buffer.appendInt32(631707458)
channel.serialize(buffer, true) serializeInt32(flags, buffer: buffer, boxed: false)
return (FunctionDescription(name: "channels.getChannelRecommendations", parameters: [("channel", String(describing: channel))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.Chats? in if Int(flags) & Int(1 << 0) != 0 {channel!.serialize(buffer, true)}
return (FunctionDescription(name: "channels.getChannelRecommendations", parameters: [("flags", String(describing: flags)), ("channel", String(describing: channel))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.Chats? in
let reader = BufferReader(buffer) let reader = BufferReader(buffer)
var result: Api.messages.Chats? var result: Api.messages.Chats?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
@ -7816,12 +7832,14 @@ public extension Api.functions.messages {
} }
} }
public extension Api.functions.messages { public extension Api.functions.messages {
static func setChatAvailableReactions(peer: Api.InputPeer, availableReactions: Api.ChatReactions) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) { static func setChatAvailableReactions(flags: Int32, peer: Api.InputPeer, availableReactions: Api.ChatReactions, reactionsLimit: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(-21928079) buffer.appendInt32(1511328724)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true) peer.serialize(buffer, true)
availableReactions.serialize(buffer, true) availableReactions.serialize(buffer, true)
return (FunctionDescription(name: "messages.setChatAvailableReactions", parameters: [("peer", String(describing: peer)), ("availableReactions", String(describing: availableReactions))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in if Int(flags) & Int(1 << 0) != 0 {serializeInt32(reactionsLimit!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "messages.setChatAvailableReactions", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("availableReactions", String(describing: availableReactions)), ("reactionsLimit", String(describing: reactionsLimit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer) let reader = BufferReader(buffer)
var result: Api.Updates? var result: Api.Updates?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {

View File

@ -920,14 +920,14 @@ public extension Api {
} }
public extension Api { public extension Api {
enum ChatFull: TypeConstructorDescription { enum ChatFull: TypeConstructorDescription {
case channelFull(flags: Int32, flags2: Int32, id: Int64, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo], migratedFromChatId: Int64?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int64?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, call: Api.InputGroupCall?, ttlPeriod: Int32?, pendingSuggestions: [String]?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, defaultSendAs: Api.Peer?, availableReactions: Api.ChatReactions?, stories: Api.PeerStories?, wallpaper: Api.WallPaper?, boostsApplied: Int32?, boostsUnrestrict: Int32?, emojiset: Api.StickerSet?) case channelFull(flags: Int32, flags2: Int32, id: Int64, about: String, participantsCount: Int32?, adminsCount: Int32?, kickedCount: Int32?, bannedCount: Int32?, onlineCount: Int32?, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, chatPhoto: Api.Photo, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo], migratedFromChatId: Int64?, migratedFromMaxId: Int32?, pinnedMsgId: Int32?, stickerset: Api.StickerSet?, availableMinId: Int32?, folderId: Int32?, linkedChatId: Int64?, location: Api.ChannelLocation?, slowmodeSeconds: Int32?, slowmodeNextSendDate: Int32?, statsDc: Int32?, pts: Int32, call: Api.InputGroupCall?, ttlPeriod: Int32?, pendingSuggestions: [String]?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, defaultSendAs: Api.Peer?, availableReactions: Api.ChatReactions?, reactionsLimit: Int32?, stories: Api.PeerStories?, wallpaper: Api.WallPaper?, boostsApplied: Int32?, boostsUnrestrict: Int32?, emojiset: Api.StickerSet?)
case chatFull(flags: Int32, id: Int64, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?, call: Api.InputGroupCall?, ttlPeriod: Int32?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, availableReactions: Api.ChatReactions?) case chatFull(flags: Int32, id: Int64, about: String, participants: Api.ChatParticipants, chatPhoto: Api.Photo?, notifySettings: Api.PeerNotifySettings, exportedInvite: Api.ExportedChatInvite?, botInfo: [Api.BotInfo]?, pinnedMsgId: Int32?, folderId: Int32?, call: Api.InputGroupCall?, ttlPeriod: Int32?, groupcallDefaultJoinAs: Api.Peer?, themeEmoticon: String?, requestsPending: Int32?, recentRequesters: [Int64]?, availableReactions: Api.ChatReactions?, reactionsLimit: Int32?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
case .channelFull(let flags, let flags2, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttlPeriod, let pendingSuggestions, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let defaultSendAs, let availableReactions, let stories, let wallpaper, let boostsApplied, let boostsUnrestrict, let emojiset): case .channelFull(let flags, let flags2, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttlPeriod, let pendingSuggestions, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let defaultSendAs, let availableReactions, let reactionsLimit, let stories, let wallpaper, let boostsApplied, let boostsUnrestrict, let emojiset):
if boxed { if boxed {
buffer.appendInt32(1153455271) buffer.appendInt32(-1146407795)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(flags2, buffer: buffer, boxed: false) serializeInt32(flags2, buffer: buffer, boxed: false)
@ -978,15 +978,16 @@ public extension Api {
}} }}
if Int(flags) & Int(1 << 29) != 0 {defaultSendAs!.serialize(buffer, true)} if Int(flags) & Int(1 << 29) != 0 {defaultSendAs!.serialize(buffer, true)}
if Int(flags) & Int(1 << 30) != 0 {availableReactions!.serialize(buffer, true)} if Int(flags) & Int(1 << 30) != 0 {availableReactions!.serialize(buffer, true)}
if Int(flags2) & Int(1 << 13) != 0 {serializeInt32(reactionsLimit!, buffer: buffer, boxed: false)}
if Int(flags2) & Int(1 << 4) != 0 {stories!.serialize(buffer, true)} if Int(flags2) & Int(1 << 4) != 0 {stories!.serialize(buffer, true)}
if Int(flags2) & Int(1 << 7) != 0 {wallpaper!.serialize(buffer, true)} if Int(flags2) & Int(1 << 7) != 0 {wallpaper!.serialize(buffer, true)}
if Int(flags2) & Int(1 << 8) != 0 {serializeInt32(boostsApplied!, buffer: buffer, boxed: false)} if Int(flags2) & Int(1 << 8) != 0 {serializeInt32(boostsApplied!, buffer: buffer, boxed: false)}
if Int(flags2) & Int(1 << 9) != 0 {serializeInt32(boostsUnrestrict!, buffer: buffer, boxed: false)} if Int(flags2) & Int(1 << 9) != 0 {serializeInt32(boostsUnrestrict!, buffer: buffer, boxed: false)}
if Int(flags2) & Int(1 << 10) != 0 {emojiset!.serialize(buffer, true)} if Int(flags2) & Int(1 << 10) != 0 {emojiset!.serialize(buffer, true)}
break break
case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId, let call, let ttlPeriod, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let availableReactions): case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId, let call, let ttlPeriod, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let availableReactions, let reactionsLimit):
if boxed { if boxed {
buffer.appendInt32(-908914376) buffer.appendInt32(640893467)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(id, buffer: buffer, boxed: false) serializeInt64(id, buffer: buffer, boxed: false)
@ -1013,16 +1014,17 @@ public extension Api {
serializeInt64(item, buffer: buffer, boxed: false) serializeInt64(item, buffer: buffer, boxed: false)
}} }}
if Int(flags) & Int(1 << 18) != 0 {availableReactions!.serialize(buffer, true)} if Int(flags) & Int(1 << 18) != 0 {availableReactions!.serialize(buffer, true)}
if Int(flags) & Int(1 << 20) != 0 {serializeInt32(reactionsLimit!, buffer: buffer, boxed: false)}
break break
} }
} }
public func descriptionFields() -> (String, [(String, Any)]) { public func descriptionFields() -> (String, [(String, Any)]) {
switch self { switch self {
case .channelFull(let flags, let flags2, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttlPeriod, let pendingSuggestions, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let defaultSendAs, let availableReactions, let stories, let wallpaper, let boostsApplied, let boostsUnrestrict, let emojiset): case .channelFull(let flags, let flags2, let id, let about, let participantsCount, let adminsCount, let kickedCount, let bannedCount, let onlineCount, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let migratedFromChatId, let migratedFromMaxId, let pinnedMsgId, let stickerset, let availableMinId, let folderId, let linkedChatId, let location, let slowmodeSeconds, let slowmodeNextSendDate, let statsDc, let pts, let call, let ttlPeriod, let pendingSuggestions, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let defaultSendAs, let availableReactions, let reactionsLimit, let stories, let wallpaper, let boostsApplied, let boostsUnrestrict, let emojiset):
return ("channelFull", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("about", about as Any), ("participantsCount", participantsCount as Any), ("adminsCount", adminsCount as Any), ("kickedCount", kickedCount as Any), ("bannedCount", bannedCount as Any), ("onlineCount", onlineCount as Any), ("readInboxMaxId", readInboxMaxId as Any), ("readOutboxMaxId", readOutboxMaxId as Any), ("unreadCount", unreadCount as Any), ("chatPhoto", chatPhoto as Any), ("notifySettings", notifySettings as Any), ("exportedInvite", exportedInvite as Any), ("botInfo", botInfo as Any), ("migratedFromChatId", migratedFromChatId as Any), ("migratedFromMaxId", migratedFromMaxId as Any), ("pinnedMsgId", pinnedMsgId as Any), ("stickerset", stickerset as Any), ("availableMinId", availableMinId as Any), ("folderId", folderId as Any), ("linkedChatId", linkedChatId as Any), ("location", location as Any), ("slowmodeSeconds", slowmodeSeconds as Any), ("slowmodeNextSendDate", slowmodeNextSendDate as Any), ("statsDc", statsDc as Any), ("pts", pts as Any), ("call", call as Any), ("ttlPeriod", ttlPeriod as Any), ("pendingSuggestions", pendingSuggestions as Any), ("groupcallDefaultJoinAs", groupcallDefaultJoinAs as Any), ("themeEmoticon", themeEmoticon as Any), ("requestsPending", requestsPending as Any), ("recentRequesters", recentRequesters as Any), ("defaultSendAs", defaultSendAs as Any), ("availableReactions", availableReactions as Any), ("stories", stories as Any), ("wallpaper", wallpaper as Any), ("boostsApplied", boostsApplied as Any), ("boostsUnrestrict", boostsUnrestrict as Any), ("emojiset", emojiset as Any)]) return ("channelFull", [("flags", flags as Any), ("flags2", flags2 as Any), ("id", id as Any), ("about", about as Any), ("participantsCount", participantsCount as Any), ("adminsCount", adminsCount as Any), ("kickedCount", kickedCount as Any), ("bannedCount", bannedCount as Any), ("onlineCount", onlineCount as Any), ("readInboxMaxId", readInboxMaxId as Any), ("readOutboxMaxId", readOutboxMaxId as Any), ("unreadCount", unreadCount as Any), ("chatPhoto", chatPhoto as Any), ("notifySettings", notifySettings as Any), ("exportedInvite", exportedInvite as Any), ("botInfo", botInfo as Any), ("migratedFromChatId", migratedFromChatId as Any), ("migratedFromMaxId", migratedFromMaxId as Any), ("pinnedMsgId", pinnedMsgId as Any), ("stickerset", stickerset as Any), ("availableMinId", availableMinId as Any), ("folderId", folderId as Any), ("linkedChatId", linkedChatId as Any), ("location", location as Any), ("slowmodeSeconds", slowmodeSeconds as Any), ("slowmodeNextSendDate", slowmodeNextSendDate as Any), ("statsDc", statsDc as Any), ("pts", pts as Any), ("call", call as Any), ("ttlPeriod", ttlPeriod as Any), ("pendingSuggestions", pendingSuggestions as Any), ("groupcallDefaultJoinAs", groupcallDefaultJoinAs as Any), ("themeEmoticon", themeEmoticon as Any), ("requestsPending", requestsPending as Any), ("recentRequesters", recentRequesters as Any), ("defaultSendAs", defaultSendAs as Any), ("availableReactions", availableReactions as Any), ("reactionsLimit", reactionsLimit as Any), ("stories", stories as Any), ("wallpaper", wallpaper as Any), ("boostsApplied", boostsApplied as Any), ("boostsUnrestrict", boostsUnrestrict as Any), ("emojiset", emojiset as Any)])
case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId, let call, let ttlPeriod, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let availableReactions): case .chatFull(let flags, let id, let about, let participants, let chatPhoto, let notifySettings, let exportedInvite, let botInfo, let pinnedMsgId, let folderId, let call, let ttlPeriod, let groupcallDefaultJoinAs, let themeEmoticon, let requestsPending, let recentRequesters, let availableReactions, let reactionsLimit):
return ("chatFull", [("flags", flags as Any), ("id", id as Any), ("about", about as Any), ("participants", participants as Any), ("chatPhoto", chatPhoto as Any), ("notifySettings", notifySettings as Any), ("exportedInvite", exportedInvite as Any), ("botInfo", botInfo as Any), ("pinnedMsgId", pinnedMsgId as Any), ("folderId", folderId as Any), ("call", call as Any), ("ttlPeriod", ttlPeriod as Any), ("groupcallDefaultJoinAs", groupcallDefaultJoinAs as Any), ("themeEmoticon", themeEmoticon as Any), ("requestsPending", requestsPending as Any), ("recentRequesters", recentRequesters as Any), ("availableReactions", availableReactions as Any)]) return ("chatFull", [("flags", flags as Any), ("id", id as Any), ("about", about as Any), ("participants", participants as Any), ("chatPhoto", chatPhoto as Any), ("notifySettings", notifySettings as Any), ("exportedInvite", exportedInvite as Any), ("botInfo", botInfo as Any), ("pinnedMsgId", pinnedMsgId as Any), ("folderId", folderId as Any), ("call", call as Any), ("ttlPeriod", ttlPeriod as Any), ("groupcallDefaultJoinAs", groupcallDefaultJoinAs as Any), ("themeEmoticon", themeEmoticon as Any), ("requestsPending", requestsPending as Any), ("recentRequesters", recentRequesters as Any), ("availableReactions", availableReactions as Any), ("reactionsLimit", reactionsLimit as Any)])
} }
} }
@ -1125,21 +1127,23 @@ public extension Api {
if Int(_1!) & Int(1 << 30) != 0 {if let signature = reader.readInt32() { if Int(_1!) & Int(1 << 30) != 0 {if let signature = reader.readInt32() {
_37 = Api.parse(reader, signature: signature) as? Api.ChatReactions _37 = Api.parse(reader, signature: signature) as? Api.ChatReactions
} } } }
var _38: Api.PeerStories? var _38: Int32?
if Int(_2!) & Int(1 << 13) != 0 {_38 = reader.readInt32() }
var _39: Api.PeerStories?
if Int(_2!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() { if Int(_2!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
_38 = Api.parse(reader, signature: signature) as? Api.PeerStories _39 = Api.parse(reader, signature: signature) as? Api.PeerStories
} } } }
var _39: Api.WallPaper? var _40: Api.WallPaper?
if Int(_2!) & Int(1 << 7) != 0 {if let signature = reader.readInt32() { if Int(_2!) & Int(1 << 7) != 0 {if let signature = reader.readInt32() {
_39 = Api.parse(reader, signature: signature) as? Api.WallPaper _40 = Api.parse(reader, signature: signature) as? Api.WallPaper
} } } }
var _40: Int32?
if Int(_2!) & Int(1 << 8) != 0 {_40 = reader.readInt32() }
var _41: Int32? var _41: Int32?
if Int(_2!) & Int(1 << 9) != 0 {_41 = reader.readInt32() } if Int(_2!) & Int(1 << 8) != 0 {_41 = reader.readInt32() }
var _42: Api.StickerSet? var _42: Int32?
if Int(_2!) & Int(1 << 9) != 0 {_42 = reader.readInt32() }
var _43: Api.StickerSet?
if Int(_2!) & Int(1 << 10) != 0 {if let signature = reader.readInt32() { if Int(_2!) & Int(1 << 10) != 0 {if let signature = reader.readInt32() {
_42 = Api.parse(reader, signature: signature) as? Api.StickerSet _43 = Api.parse(reader, signature: signature) as? Api.StickerSet
} } } }
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
@ -1178,13 +1182,14 @@ public extension Api {
let _c35 = (Int(_1!) & Int(1 << 28) == 0) || _35 != nil let _c35 = (Int(_1!) & Int(1 << 28) == 0) || _35 != nil
let _c36 = (Int(_1!) & Int(1 << 29) == 0) || _36 != nil let _c36 = (Int(_1!) & Int(1 << 29) == 0) || _36 != nil
let _c37 = (Int(_1!) & Int(1 << 30) == 0) || _37 != nil let _c37 = (Int(_1!) & Int(1 << 30) == 0) || _37 != nil
let _c38 = (Int(_2!) & Int(1 << 4) == 0) || _38 != nil let _c38 = (Int(_2!) & Int(1 << 13) == 0) || _38 != nil
let _c39 = (Int(_2!) & Int(1 << 7) == 0) || _39 != nil let _c39 = (Int(_2!) & Int(1 << 4) == 0) || _39 != nil
let _c40 = (Int(_2!) & Int(1 << 8) == 0) || _40 != nil let _c40 = (Int(_2!) & Int(1 << 7) == 0) || _40 != nil
let _c41 = (Int(_2!) & Int(1 << 9) == 0) || _41 != nil let _c41 = (Int(_2!) & Int(1 << 8) == 0) || _41 != nil
let _c42 = (Int(_2!) & Int(1 << 10) == 0) || _42 != nil let _c42 = (Int(_2!) & Int(1 << 9) == 0) || _42 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 && _c33 && _c34 && _c35 && _c36 && _c37 && _c38 && _c39 && _c40 && _c41 && _c42 { let _c43 = (Int(_2!) & Int(1 << 10) == 0) || _43 != nil
return Api.ChatFull.channelFull(flags: _1!, flags2: _2!, id: _3!, about: _4!, participantsCount: _5, adminsCount: _6, kickedCount: _7, bannedCount: _8, onlineCount: _9, readInboxMaxId: _10!, readOutboxMaxId: _11!, unreadCount: _12!, chatPhoto: _13!, notifySettings: _14!, exportedInvite: _15, botInfo: _16!, migratedFromChatId: _17, migratedFromMaxId: _18, pinnedMsgId: _19, stickerset: _20, availableMinId: _21, folderId: _22, linkedChatId: _23, location: _24, slowmodeSeconds: _25, slowmodeNextSendDate: _26, statsDc: _27, pts: _28!, call: _29, ttlPeriod: _30, pendingSuggestions: _31, groupcallDefaultJoinAs: _32, themeEmoticon: _33, requestsPending: _34, recentRequesters: _35, defaultSendAs: _36, availableReactions: _37, stories: _38, wallpaper: _39, boostsApplied: _40, boostsUnrestrict: _41, emojiset: _42) if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 && _c33 && _c34 && _c35 && _c36 && _c37 && _c38 && _c39 && _c40 && _c41 && _c42 && _c43 {
return Api.ChatFull.channelFull(flags: _1!, flags2: _2!, id: _3!, about: _4!, participantsCount: _5, adminsCount: _6, kickedCount: _7, bannedCount: _8, onlineCount: _9, readInboxMaxId: _10!, readOutboxMaxId: _11!, unreadCount: _12!, chatPhoto: _13!, notifySettings: _14!, exportedInvite: _15, botInfo: _16!, migratedFromChatId: _17, migratedFromMaxId: _18, pinnedMsgId: _19, stickerset: _20, availableMinId: _21, folderId: _22, linkedChatId: _23, location: _24, slowmodeSeconds: _25, slowmodeNextSendDate: _26, statsDc: _27, pts: _28!, call: _29, ttlPeriod: _30, pendingSuggestions: _31, groupcallDefaultJoinAs: _32, themeEmoticon: _33, requestsPending: _34, recentRequesters: _35, defaultSendAs: _36, availableReactions: _37, reactionsLimit: _38, stories: _39, wallpaper: _40, boostsApplied: _41, boostsUnrestrict: _42, emojiset: _43)
} }
else { else {
return nil return nil
@ -1243,6 +1248,8 @@ public extension Api {
if Int(_1!) & Int(1 << 18) != 0 {if let signature = reader.readInt32() { if Int(_1!) & Int(1 << 18) != 0 {if let signature = reader.readInt32() {
_17 = Api.parse(reader, signature: signature) as? Api.ChatReactions _17 = Api.parse(reader, signature: signature) as? Api.ChatReactions
} } } }
var _18: Int32?
if Int(_1!) & Int(1 << 20) != 0 {_18 = reader.readInt32() }
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = _3 != nil let _c3 = _3 != nil
@ -1260,8 +1267,9 @@ public extension Api {
let _c15 = (Int(_1!) & Int(1 << 17) == 0) || _15 != nil let _c15 = (Int(_1!) & Int(1 << 17) == 0) || _15 != nil
let _c16 = (Int(_1!) & Int(1 << 17) == 0) || _16 != nil let _c16 = (Int(_1!) & Int(1 << 17) == 0) || _16 != nil
let _c17 = (Int(_1!) & Int(1 << 18) == 0) || _17 != nil let _c17 = (Int(_1!) & Int(1 << 18) == 0) || _17 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 { let _c18 = (Int(_1!) & Int(1 << 20) == 0) || _18 != nil
return Api.ChatFull.chatFull(flags: _1!, id: _2!, about: _3!, participants: _4!, chatPhoto: _5, notifySettings: _6!, exportedInvite: _7, botInfo: _8, pinnedMsgId: _9, folderId: _10, call: _11, ttlPeriod: _12, groupcallDefaultJoinAs: _13, themeEmoticon: _14, requestsPending: _15, recentRequesters: _16, availableReactions: _17) if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 {
return Api.ChatFull.chatFull(flags: _1!, id: _2!, about: _3!, participants: _4!, chatPhoto: _5, notifySettings: _6!, exportedInvite: _7, botInfo: _8, pinnedMsgId: _9, folderId: _10, call: _11, ttlPeriod: _12, groupcallDefaultJoinAs: _13, themeEmoticon: _14, requestsPending: _15, recentRequesters: _16, availableReactions: _17, reactionsLimit: _18)
} }
else { else {
return nil return nil

View File

@ -1278,6 +1278,7 @@ public class Account {
self.stateManager.updateConfigRequested = { [weak self] in self.stateManager.updateConfigRequested = { [weak self] in
self?.restartConfigurationUpdates() self?.restartConfigurationUpdates()
self?.taskManager?.reloadAppConfiguration()
} }
self.restartConfigurationUpdates() self.restartConfigurationUpdates()

View File

@ -7,27 +7,18 @@ public final class AdMessageAttribute: MessageAttribute {
case recommended case recommended
} }
public enum MessageTarget {
case peer(id: EnginePeer.Id, message: EngineMessage.Id?, startParam: String?)
case join(title: String, joinHash: String, peer: EnginePeer?)
case webPage(title: String, url: String)
case botApp(peerId: EnginePeer.Id, app: BotApp, startParam: String?)
}
public let opaqueId: Data public let opaqueId: Data
public let messageType: MessageType public let messageType: MessageType
public let displayAvatar: Bool public let url: String
public let target: MessageTarget public let buttonText: String
public let buttonText: String?
public let sponsorInfo: String? public let sponsorInfo: String?
public let additionalInfo: String? public let additionalInfo: String?
public let canReport: Bool public let canReport: Bool
public init(opaqueId: Data, messageType: MessageType, displayAvatar: Bool, target: MessageTarget, buttonText: String?, sponsorInfo: String?, additionalInfo: String?, canReport: Bool) { public init(opaqueId: Data, messageType: MessageType, url: String, buttonText: String, sponsorInfo: String?, additionalInfo: String?, canReport: Bool) {
self.opaqueId = opaqueId self.opaqueId = opaqueId
self.messageType = messageType self.messageType = messageType
self.displayAvatar = displayAvatar self.url = url
self.target = target
self.buttonText = buttonText self.buttonText = buttonText
self.sponsorInfo = sponsorInfo self.sponsorInfo = sponsorInfo
self.additionalInfo = additionalInfo self.additionalInfo = additionalInfo

View File

@ -18,6 +18,7 @@ final class AccountTaskManager {
private var stateDisposable: Disposable? private var stateDisposable: Disposable?
private let tasksDisposable = MetaDisposable() private let tasksDisposable = MetaDisposable()
private let configurationDisposable = MetaDisposable()
private let managedTopReactionsDisposable = MetaDisposable() private let managedTopReactionsDisposable = MetaDisposable()
@ -118,7 +119,7 @@ final class AccountTaskManager {
self.managedTopReactionsDisposable.set(managedTopReactions(postbox: self.stateManager.postbox, network: self.stateManager.network).start()) self.managedTopReactionsDisposable.set(managedTopReactions(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
//tasks.add(managedVoipConfigurationUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network).start()) //tasks.add(managedVoipConfigurationUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedAppConfigurationUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network).start()) self.reloadAppConfiguration()
tasks.add(managedPremiumPromoConfigurationUpdates(accountPeerId: self.accountPeerId, postbox: self.stateManager.postbox, network: self.stateManager.network).start()) tasks.add(managedPremiumPromoConfigurationUpdates(accountPeerId: self.accountPeerId, postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedAutodownloadSettingsUpdates(accountManager: self.accountManager, network: self.stateManager.network).start()) tasks.add(managedAutodownloadSettingsUpdates(accountManager: self.accountManager, network: self.stateManager.network).start())
tasks.add(managedTermsOfServiceUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start()) tasks.add(managedTermsOfServiceUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
@ -143,8 +144,13 @@ final class AccountTaskManager {
deinit { deinit {
self.stateDisposable?.dispose() self.stateDisposable?.dispose()
self.tasksDisposable.dispose() self.tasksDisposable.dispose()
self.configurationDisposable.dispose()
self.managedTopReactionsDisposable.dispose() self.managedTopReactionsDisposable.dispose()
} }
func reloadAppConfiguration() {
self.configurationDisposable.set(managedAppConfigurationUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
}
} }
private let queue: Queue private let queue: Queue
@ -158,4 +164,10 @@ final class AccountTaskManager {
return Impl(queue: queue, accountPeerId: stateManager.accountPeerId, stateManager: stateManager, accountManager: accountManager, networkArguments: networkArguments, viewTracker: viewTracker, mediaReferenceRevalidationContext: mediaReferenceRevalidationContext, isMainApp: isMainApp, testingEnvironment: testingEnvironment) return Impl(queue: queue, accountPeerId: stateManager.accountPeerId, stateManager: stateManager, accountManager: accountManager, networkArguments: networkArguments, viewTracker: viewTracker, mediaReferenceRevalidationContext: mediaReferenceRevalidationContext, isMainApp: isMainApp, testingEnvironment: testingEnvironment)
}) })
} }
func reloadAppConfiguration() {
self.impl.with { impl in
impl.reloadAppConfiguration()
}
}
} }

View File

@ -674,7 +674,7 @@ func _internal_updatePeerAllowedReactions(account: Account, peerId: PeerId, allo
mappedReactions = .chatReactionsNone mappedReactions = .chatReactionsNone
} }
return account.network.request(Api.functions.messages.setChatAvailableReactions(peer: inputPeer, availableReactions: mappedReactions)) return account.network.request(Api.functions.messages.setChatAvailableReactions(flags: 0, peer: inputPeer, availableReactions: mappedReactions, reactionsLimit: nil))
|> map(Optional.init) |> map(Optional.init)
|> `catch` { error -> Signal<Api.Updates?, UpdatePeerAllowedReactionsError> in |> `catch` { error -> Signal<Api.Updates?, UpdatePeerAllowedReactionsError> in
if error.errorDescription == "CHAT_NOT_MODIFIED" { if error.errorDescription == "CHAT_NOT_MODIFIED" {

View File

@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization { public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt { public func currentLayer() -> UInt {
return 177 return 178
} }
public func parseMessage(_ data: Data!) -> Any! { public func parseMessage(_ data: Data!) -> Any! {

View File

@ -14,6 +14,7 @@ public enum ServerProvidedSuggestion: String {
case restorePremium = "PREMIUM_RESTORE" case restorePremium = "PREMIUM_RESTORE"
case xmasPremiumGift = "PREMIUM_CHRISTMAS" case xmasPremiumGift = "PREMIUM_CHRISTMAS"
case setupBirthday = "BIRTHDAY_SETUP" case setupBirthday = "BIRTHDAY_SETUP"
case todayBirthdays = "BIRTHDAY_CONTACTS_TODAY"
} }
private var dismissedSuggestionsPromise = ValuePromise<[AccountRecordId: Set<ServerProvidedSuggestion>]>([:]) private var dismissedSuggestionsPromise = ValuePromise<[AccountRecordId: Set<ServerProvidedSuggestion>]>([:])
@ -45,6 +46,30 @@ func _internal_getServerProvidedSuggestions(account: Account) -> Signal<[ServerP
|> distinctUntilChanged |> distinctUntilChanged
} }
func _internal_getServerDismissedSuggestions(account: Account) -> Signal<[ServerProvidedSuggestion], NoError> {
let key: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.appConfiguration]))
return combineLatest(account.postbox.combinedView(keys: [key]), dismissedSuggestionsPromise.get())
|> map { views, dismissedSuggestionsValue -> [ServerProvidedSuggestion] in
let dismissedSuggestions = dismissedSuggestionsValue[account.id] ?? Set()
guard let view = views.views[key] as? PreferencesView else {
return []
}
guard let appConfiguration = view.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self) else {
return []
}
guard let data = appConfiguration.data, let listItems = data["hidden_suggestions"] as? [String] else {
return []
}
var items = listItems.compactMap { item -> ServerProvidedSuggestion? in
return ServerProvidedSuggestion(rawValue: item)
}
items.append(contentsOf: dismissedSuggestions)
return items
}
|> distinctUntilChanged
}
func _internal_dismissServerProvidedSuggestion(account: Account, suggestion: ServerProvidedSuggestion) -> Signal<Never, NoError> { func _internal_dismissServerProvidedSuggestion(account: Account, suggestion: ServerProvidedSuggestion) -> Signal<Never, NoError> {
if let _ = dismissedSuggestions[account.id] { if let _ = dismissedSuggestions[account.id] {
dismissedSuggestions[account.id]?.insert(suggestion) dismissedSuggestions[account.id]?.insert(suggestion)

View File

@ -297,6 +297,7 @@ public struct CachedUserFlags: OptionSet {
public static let isBlockedFromStories = CachedUserFlags(rawValue: 1 << 1) public static let isBlockedFromStories = CachedUserFlags(rawValue: 1 << 1)
public static let readDatesPrivate = CachedUserFlags(rawValue: 1 << 2) public static let readDatesPrivate = CachedUserFlags(rawValue: 1 << 2)
public static let premiumRequired = CachedUserFlags(rawValue: 1 << 3) public static let premiumRequired = CachedUserFlags(rawValue: 1 << 3)
public static let adsEnabled = CachedUserFlags(rawValue: 1 << 4)
} }
public final class EditableBotInfo: PostboxCoding, Equatable { public final class EditableBotInfo: PostboxCoding, Equatable {

View File

@ -233,5 +233,9 @@ public extension TelegramEngine {
public func updatePersonalChannel(personalChannel: TelegramPersonalChannel?) -> Signal<Never, NoError> { public func updatePersonalChannel(personalChannel: TelegramPersonalChannel?) -> Signal<Never, NoError> {
return _internal_updatePersonalChannel(account: self.account, personalChannel: personalChannel) return _internal_updatePersonalChannel(account: self.account, personalChannel: personalChannel)
} }
public func updateAdMessagesEnabled(enabled: Bool) -> Signal<Never, AdMessagesEnableError> {
return _internal_updateAdMessagesEnabled(account: self.account, enabled: enabled)
}
} }
} }

View File

@ -1868,5 +1868,33 @@ public extension TelegramEngine.EngineData.Item {
} }
} }
} }
public struct AdsEnabled: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
public typealias Result = Bool
fileprivate var id: EnginePeer.Id
public var mapKey: EnginePeer.Id {
return self.id
}
public init(id: EnginePeer.Id) {
self.id = id
}
var key: PostboxViewKey {
return .cachedPeerData(peerId: self.id)
}
func extract(view: PostboxView) -> Result {
guard let view = view as? CachedPeerDataView else {
preconditionFailure()
}
if let cachedData = view.cachedPeerData as? CachedUserData {
return cachedData.flags.contains(.adsEnabled)
} else {
return false
}
}
}
} }
} }

View File

@ -8,13 +8,11 @@ private class AdMessagesHistoryContextImpl {
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case opaqueId case opaqueId
case messageType case messageType
case displayAvatar case title
case text case text
case textEntities case textEntities
case media case media
case target case url
case messageId
case startParam
case buttonText case buttonText
case sponsorInfo case sponsorInfo
case additionalInfo case additionalInfo
@ -26,147 +24,14 @@ private class AdMessagesHistoryContextImpl {
case recommended = 1 case recommended = 1
} }
enum Target: Equatable, Codable {
enum DecodingError: Error {
case generic
}
enum CodingKeys: String, CodingKey {
case peer
case invite
case webPage
case botApp
}
struct Invite: Equatable, Codable {
enum CodingKeys: String, CodingKey {
case title
case joinHash
case nameColor
case image
case peer
}
var title: String
var joinHash: String
var nameColor: PeerNameColor?
var image: TelegramMediaImage?
var peer: Peer?
init(title: String, joinHash: String, nameColor: PeerNameColor?, image: TelegramMediaImage?, peer: Peer?) {
self.title = title
self.joinHash = joinHash
self.nameColor = nameColor
self.image = image
self.peer = peer
}
static func ==(lhs: Invite, rhs: Invite) -> Bool {
if lhs.title != rhs.title {
return false
}
if lhs.joinHash != rhs.joinHash {
return false
}
if lhs.nameColor != rhs.nameColor {
return false
}
if lhs.image != rhs.image {
return false
}
if !arePeersEqual(lhs.peer, rhs.peer) {
return false
}
return true
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.title = try container.decode(String.self, forKey: .title)
self.joinHash = try container.decode(String.self, forKey: .joinHash)
self.nameColor = try container.decodeIfPresent(Int32.self, forKey: .nameColor).flatMap { PeerNameColor(rawValue: $0) }
self.image = (try container.decodeIfPresent(Data.self, forKey: .image)).flatMap { data in
return TelegramMediaImage(decoder: PostboxDecoder(buffer: MemoryBuffer(data: data)))
}
self.peer = (try container.decodeIfPresent(Data.self, forKey: .peer)).flatMap { data in
return PostboxDecoder(buffer: MemoryBuffer(data: data)).decodeRootObject() as? Peer
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.title, forKey: .title)
try container.encode(self.joinHash, forKey: .joinHash)
try container.encodeIfPresent(self.nameColor?.rawValue, forKey: .nameColor)
try container.encodeIfPresent(self.image.flatMap { image in
let encoder = PostboxEncoder()
image.encode(encoder)
return encoder.makeData()
}, forKey: .image)
try container.encodeIfPresent(self.peer.flatMap { peer in
let encoder = PostboxEncoder()
encoder.encodeRootObject(peer)
return encoder.makeData()
}, forKey: .peer)
}
}
struct WebPage: Equatable, Codable {
var title: String
var url: String
var photo: TelegramMediaImage?
}
case peer(PeerId)
case invite(Invite)
case webPage(WebPage)
case botApp(PeerId, BotApp)
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let botApp = try container.decodeIfPresent(BotApp.self, forKey: .botApp), let peer = try container.decodeIfPresent(Int64.self, forKey: .peer) {
self = .botApp(PeerId(peer), botApp)
} else if let peer = try container.decodeIfPresent(Int64.self, forKey: .peer) {
self = .peer(PeerId(peer))
} else if let invite = try container.decodeIfPresent(Invite.self, forKey: .invite) {
self = .invite(invite)
} else if let webPage = try container.decodeIfPresent(WebPage.self, forKey: .webPage) {
self = .webPage(webPage)
} else {
throw DecodingError.generic
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case let .peer(peerId):
try container.encode(peerId.toInt64(), forKey: .peer)
case let .invite(invite):
try container.encode(invite, forKey: .invite)
case let .webPage(webPage):
try container.encode(webPage, forKey: .webPage)
case let .botApp(peerId, botApp):
try container.encode(peerId.toInt64(), forKey: .peer)
try container.encode(botApp, forKey: .botApp)
}
}
}
public let opaqueId: Data public let opaqueId: Data
public let messageType: MessageType public let messageType: MessageType
public let displayAvatar: Bool public let title: String
public let text: String public let text: String
public let textEntities: [MessageTextEntity] public let textEntities: [MessageTextEntity]
public let media: [Media] public let media: [Media]
public let target: Target public let url: String
public let messageId: MessageId? public let buttonText: String
public let startParam: String?
public let buttonText: String?
public let sponsorInfo: String? public let sponsorInfo: String?
public let additionalInfo: String? public let additionalInfo: String?
public let canReport: Bool public let canReport: Bool
@ -174,27 +39,23 @@ private class AdMessagesHistoryContextImpl {
public init( public init(
opaqueId: Data, opaqueId: Data,
messageType: MessageType, messageType: MessageType,
displayAvatar: Bool, title: String,
text: String, text: String,
textEntities: [MessageTextEntity], textEntities: [MessageTextEntity],
media: [Media], media: [Media],
target: Target, url: String,
messageId: MessageId?, buttonText: String,
startParam: String?,
buttonText: String?,
sponsorInfo: String?, sponsorInfo: String?,
additionalInfo: String?, additionalInfo: String?,
canReport: Bool canReport: Bool
) { ) {
self.opaqueId = opaqueId self.opaqueId = opaqueId
self.messageType = messageType self.messageType = messageType
self.displayAvatar = displayAvatar self.title = title
self.text = text self.text = text
self.textEntities = textEntities self.textEntities = textEntities
self.media = media self.media = media
self.target = target self.url = url
self.messageId = messageId
self.startParam = startParam
self.buttonText = buttonText self.buttonText = buttonText
self.sponsorInfo = sponsorInfo self.sponsorInfo = sponsorInfo
self.additionalInfo = additionalInfo self.additionalInfo = additionalInfo
@ -212,8 +73,7 @@ private class AdMessagesHistoryContextImpl {
self.messageType = .sponsored self.messageType = .sponsored
} }
self.displayAvatar = try container.decodeIfPresent(Bool.self, forKey: .displayAvatar) ?? false self.title = try container.decode(String.self, forKey: .title)
self.text = try container.decode(String.self, forKey: .text) self.text = try container.decode(String.self, forKey: .text)
self.textEntities = try container.decode([MessageTextEntity].self, forKey: .textEntities) self.textEntities = try container.decode([MessageTextEntity].self, forKey: .textEntities)
@ -222,10 +82,8 @@ private class AdMessagesHistoryContextImpl {
return PostboxDecoder(buffer: MemoryBuffer(data: data)).decodeRootObject() as? Media return PostboxDecoder(buffer: MemoryBuffer(data: data)).decodeRootObject() as? Media
} }
self.target = try container.decode(Target.self, forKey: .target) self.url = try container.decode(String.self, forKey: .url)
self.messageId = try container.decodeIfPresent(MessageId.self, forKey: .messageId) self.buttonText = try container.decode(String.self, forKey: .buttonText)
self.startParam = try container.decodeIfPresent(String.self, forKey: .startParam)
self.buttonText = try container.decodeIfPresent(String.self, forKey: .buttonText)
self.sponsorInfo = try container.decodeIfPresent(String.self, forKey: .sponsorInfo) self.sponsorInfo = try container.decodeIfPresent(String.self, forKey: .sponsorInfo)
self.additionalInfo = try container.decodeIfPresent(String.self, forKey: .additionalInfo) self.additionalInfo = try container.decodeIfPresent(String.self, forKey: .additionalInfo)
@ -238,7 +96,7 @@ private class AdMessagesHistoryContextImpl {
try container.encode(self.opaqueId, forKey: .opaqueId) try container.encode(self.opaqueId, forKey: .opaqueId)
try container.encode(self.messageType.rawValue, forKey: .messageType) try container.encode(self.messageType.rawValue, forKey: .messageType)
try container.encode(self.displayAvatar, forKey: .displayAvatar) try container.encode(self.title, forKey: .title)
try container.encode(self.text, forKey: .text) try container.encode(self.text, forKey: .text)
try container.encode(self.textEntities, forKey: .textEntities) try container.encode(self.textEntities, forKey: .textEntities)
@ -249,10 +107,8 @@ private class AdMessagesHistoryContextImpl {
} }
try container.encode(mediaData, forKey: .media) try container.encode(mediaData, forKey: .media)
try container.encode(self.target, forKey: .target) try container.encode(self.url, forKey: .url)
try container.encodeIfPresent(self.messageId, forKey: .messageId) try container.encode(self.buttonText, forKey: .buttonText)
try container.encodeIfPresent(self.startParam, forKey: .startParam)
try container.encodeIfPresent(self.buttonText, forKey: .buttonText)
try container.encodeIfPresent(self.sponsorInfo, forKey: .sponsorInfo) try container.encodeIfPresent(self.sponsorInfo, forKey: .sponsorInfo)
try container.encodeIfPresent(self.additionalInfo, forKey: .additionalInfo) try container.encodeIfPresent(self.additionalInfo, forKey: .additionalInfo)
@ -267,6 +123,9 @@ private class AdMessagesHistoryContextImpl {
if lhs.messageType != rhs.messageType { if lhs.messageType != rhs.messageType {
return false return false
} }
if lhs.title != rhs.title {
return false
}
if lhs.text != rhs.text { if lhs.text != rhs.text {
return false return false
} }
@ -281,13 +140,7 @@ private class AdMessagesHistoryContextImpl {
return false return false
} }
} }
if lhs.target != rhs.target { if lhs.url != rhs.url {
return false
}
if lhs.messageId != rhs.messageId {
return false
}
if lhs.startParam != rhs.startParam {
return false return false
} }
if lhs.buttonText != rhs.buttonText { if lhs.buttonText != rhs.buttonText {
@ -308,17 +161,6 @@ private class AdMessagesHistoryContextImpl {
func toMessage(peerId: PeerId, transaction: Transaction) -> Message? { func toMessage(peerId: PeerId, transaction: Transaction) -> Message? {
var attributes: [MessageAttribute] = [] var attributes: [MessageAttribute] = []
let target: AdMessageAttribute.MessageTarget
switch self.target {
case let .peer(peerId):
target = .peer(id: peerId, message: self.messageId, startParam: self.startParam)
case let .invite(invite):
target = .join(title: invite.title, joinHash: invite.joinHash, peer: invite.peer.flatMap(EnginePeer.init))
case let .webPage(webPage):
target = .webPage(title: webPage.title, url: webPage.url)
case let .botApp(peerId, botApp):
target = .botApp(peerId: peerId, app: botApp, startParam: self.startParam)
}
let mappedMessageType: AdMessageAttribute.MessageType let mappedMessageType: AdMessageAttribute.MessageType
switch self.messageType { switch self.messageType {
case .sponsored: case .sponsored:
@ -326,7 +168,7 @@ private class AdMessagesHistoryContextImpl {
case .recommended: case .recommended:
mappedMessageType = .recommended mappedMessageType = .recommended
} }
attributes.append(AdMessageAttribute(opaqueId: self.opaqueId, messageType: mappedMessageType, displayAvatar: self.displayAvatar && !self.canReport, target: target, buttonText: self.buttonText, sponsorInfo: self.sponsorInfo, additionalInfo: self.additionalInfo, canReport: self.canReport)) attributes.append(AdMessageAttribute(opaqueId: self.opaqueId, messageType: mappedMessageType, url: self.url, buttonText: self.buttonText, sponsorInfo: self.sponsorInfo, additionalInfo: self.additionalInfo, canReport: self.canReport))
if !self.textEntities.isEmpty { if !self.textEntities.isEmpty {
let attribute = TextEntitiesMessageAttribute(entities: self.textEntities) let attribute = TextEntitiesMessageAttribute(entities: self.textEntities)
attributes.append(attribute) attributes.append(attribute)
@ -338,81 +180,35 @@ private class AdMessagesHistoryContextImpl {
messagePeers[peer.id] = peer messagePeers[peer.id] = peer
} }
let author: Peer let author: Peer = TelegramChannel(
switch self.target { id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(1)),
case let .peer(peerId), let .botApp(peerId, _): accessHash: nil,
if let peer = transaction.getPeer(peerId) { title: self.title,
author = peer username: nil,
} else { photo: [],
return nil creationDate: 0,
} version: 0,
case let .invite(invite): participationStatus: .left,
author = TelegramChannel( info: .broadcast(TelegramChannelBroadcastInfo(flags: [])),
id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(1)), flags: [],
accessHash: nil, restrictionInfo: nil,
title: invite.title, adminRights: nil,
username: nil, bannedRights: nil,
photo: [], defaultBannedRights: nil,
creationDate: 0, usernames: [],
version: 0, storiesHidden: nil,
participationStatus: .left, nameColor: .blue,
info: .broadcast(TelegramChannelBroadcastInfo(flags: [])), backgroundEmojiId: nil,
flags: [], profileColor: nil,
restrictionInfo: nil, profileBackgroundEmojiId: nil,
adminRights: nil, emojiStatus: nil,
bannedRights: nil, approximateBoostLevel: nil
defaultBannedRights: nil, )
usernames: [],
storiesHidden: nil,
nameColor: invite.nameColor,
backgroundEmojiId: nil,
profileColor: nil,
profileBackgroundEmojiId: nil,
emojiStatus: nil,
approximateBoostLevel: nil
)
case let .webPage(webPage):
author = TelegramChannel(
id: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(1)),
accessHash: nil,
title: webPage.title,
username: nil,
photo: webPage.photo?.representations ?? [],
creationDate: 0,
version: 0,
participationStatus: .left,
info: .broadcast(TelegramChannelBroadcastInfo(flags: [])),
flags: [],
restrictionInfo: nil,
adminRights: nil,
bannedRights: nil,
defaultBannedRights: nil,
usernames: [],
storiesHidden: nil,
nameColor: .blue,
backgroundEmojiId: nil,
profileColor: nil,
profileBackgroundEmojiId: nil,
emojiStatus: nil,
approximateBoostLevel: nil
)
}
messagePeers[author.id] = author messagePeers[author.id] = author
let messageHash = (self.text.hashValue &+ 31 &* peerId.hashValue) &* 31 &+ author.id.hashValue let messageHash = (self.text.hashValue &+ 31 &* peerId.hashValue) &* 31 &+ author.id.hashValue
let messageStableVersion = UInt32(bitPattern: Int32(truncatingIfNeeded: messageHash)) let messageStableVersion = UInt32(bitPattern: Int32(truncatingIfNeeded: messageHash))
var media: [Media] = self.media
if media.isEmpty {
if case let .invite(invite) = self.target, let image = invite.image {
media.append(image)
} else if self.displayAvatar && self.canReport, let profileImage = author.smallProfileImage {
media.append(TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [profileImage], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []))
}
}
return Message( return Message(
stableId: 0, stableId: 0,
stableVersion: messageStableVersion, stableVersion: messageStableVersion,
@ -431,7 +227,7 @@ private class AdMessagesHistoryContextImpl {
author: author, author: author,
text: self.text, text: self.text,
attributes: attributes, attributes: attributes,
media: media, media: self.media,
peers: messagePeers, peers: messagePeers,
associatedMessages: SimpleDictionary<MessageId, Message>(), associatedMessages: SimpleDictionary<MessageId, Message>(),
associatedMessageIds: [], associatedMessageIds: [],
@ -612,100 +408,30 @@ private class AdMessagesHistoryContextImpl {
for message in messages { for message in messages {
switch message { switch message {
case let .sponsoredMessage(flags, randomId, fromId, chatInvite, chatInviteHash, channelPost, startParam, webPage, botApp, message, entities, buttonText, sponsorInfo, additionalInfo): case let .sponsoredMessage(flags, randomId, url, title, message, entities, photo, buttonText, sponsorInfo, additionalInfo):
var parsedEntities: [MessageTextEntity] = [] var parsedEntities: [MessageTextEntity] = []
if let entities = entities { if let entities = entities {
parsedEntities = messageTextEntitiesFromApiEntities(entities) parsedEntities = messageTextEntitiesFromApiEntities(entities)
} }
let isRecommended = (flags & (1 << 5)) != 0 let isRecommended = (flags & (1 << 5)) != 0
var displayAvatar = (flags & (1 << 6)) != 0
let canReport = (flags & (1 << 12)) != 0 let canReport = (flags & (1 << 12)) != 0
var target: CachedMessage.Target? let photo = photo.flatMap { telegramMediaImageFromApiPhoto($0) }
if let fromId = fromId {
if let botApp = botApp, let app = BotApp(apiBotApp: botApp) {
target = .botApp(fromId.peerId, app)
} else {
target = .peer(fromId.peerId)
}
} else if let webPage = webPage {
switch webPage {
case let .sponsoredWebPage(_, url, siteName, photo):
let photo = photo.flatMap { telegramMediaImageFromApiPhoto($0) }
target = .webPage(CachedMessage.Target.WebPage(title: siteName, url: url, photo: photo))
}
} else if let chatInvite = chatInvite, let chatInviteHash = chatInviteHash {
switch chatInvite {
case let .chatInvite(flags, title, _, photo, participantsCount, participants, nameColor):
let image = telegramMediaImageFromApiPhoto(photo)
let flags: ExternalJoiningChatState.Invite.Flags = .init(isChannel: (flags & (1 << 0)) != 0, isBroadcast: (flags & (1 << 1)) != 0, isPublic: (flags & (1 << 2)) != 0, isMegagroup: (flags & (1 << 3)) != 0, requestNeeded: (flags & (1 << 6)) != 0, isVerified: (flags & (1 << 7)) != 0, isScam: (flags & (1 << 8)) != 0, isFake: (flags & (1 << 9)) != 0)
let _ = flags
let _ = participantsCount
let _ = participants
target = .invite(CachedMessage.Target.Invite(
title: title,
joinHash: chatInviteHash,
nameColor: PeerNameColor(rawValue: nameColor),
image: displayAvatar ? image : nil,
peer: nil
))
displayAvatar = false
case let .chatInvitePeek(chat, _):
if let peer = parseTelegramGroupOrChannel(chat: chat) {
target = .invite(CachedMessage.Target.Invite(
title: peer.debugDisplayTitle,
joinHash: chatInviteHash,
nameColor: peer.nameColor,
image: nil,
peer: displayAvatar ? peer : nil
))
}
displayAvatar = false
case let .chatInviteAlready(chat):
if let peer = parseTelegramGroupOrChannel(chat: chat) {
target = .invite(CachedMessage.Target.Invite(
title: peer.debugDisplayTitle,
joinHash: chatInviteHash,
nameColor: peer.nameColor,
image: nil,
peer: displayAvatar ? peer : nil
))
}
displayAvatar = false
}
}
// else if let botApp = app.flatMap({ BotApp(apiBotApp: $0) }) {
// target = .botApp(botApp)
// }
var messageId: MessageId?
if let fromId = fromId, let channelPost = channelPost {
messageId = MessageId(peerId: fromId.peerId, namespace: Namespaces.Message.Cloud, id: channelPost)
}
if let target = target { parsedMessages.append(CachedMessage(
parsedMessages.append(CachedMessage( opaqueId: randomId.makeData(),
opaqueId: randomId.makeData(), messageType: isRecommended ? .recommended : .sponsored,
messageType: isRecommended ? .recommended : .sponsored, title: title,
displayAvatar: displayAvatar, text: message,
text: message, textEntities: parsedEntities,
textEntities: parsedEntities, media: photo.flatMap { [$0] } ?? [],
media: [], url: url,
target: target, buttonText: buttonText,
messageId: messageId, sponsorInfo: sponsorInfo,
startParam: startParam, additionalInfo: additionalInfo,
buttonText: buttonText, canReport: canReport
sponsorInfo: sponsorInfo, ))
additionalInfo: additionalInfo,
canReport: canReport
))
}
} }
} }

View File

@ -25,6 +25,10 @@ public extension TelegramEngine {
return _internal_getServerProvidedSuggestions(account: self.account) return _internal_getServerProvidedSuggestions(account: self.account)
} }
public func getServerDismissedSuggestions() -> Signal<[ServerProvidedSuggestion], NoError> {
return _internal_getServerDismissedSuggestions(account: self.account)
}
public func dismissServerProvidedSuggestion(suggestion: ServerProvidedSuggestion) -> Signal<Never, NoError> { public func dismissServerProvidedSuggestion(suggestion: ServerProvidedSuggestion) -> Signal<Never, NoError> {
return _internal_dismissServerProvidedSuggestion(account: self.account, suggestion: suggestion) return _internal_dismissServerProvidedSuggestion(account: self.account, suggestion: suggestion)
} }

View File

@ -45,3 +45,36 @@ func _internal_updateChannelRestrictAdMessages(account: Account, peerId: PeerId,
} }
} }
public enum AdMessagesEnableError {
case generic
}
func _internal_updateAdMessagesEnabled(account: Account, enabled: Bool) -> Signal<Never, AdMessagesEnableError> {
return account.network.request(Api.functions.account.toggleSponsoredMessages(enabled: enabled ? .boolTrue : .boolFalse))
|> `catch` { error -> Signal<Api.Bool, AdMessagesEnableError> in
return .fail(.generic)
}
|> mapToSignal { result -> Signal<Never, AdMessagesEnableError> in
guard case .boolTrue = result else {
return .fail(.generic)
}
return account.postbox.transaction { transaction -> Void in
transaction.updatePeerCachedData(peerIds: [account.peerId], update: { peerId, currentData in
if let currentData = currentData as? CachedUserData {
var flags = currentData.flags
if enabled {
flags.insert(.adsEnabled)
} else {
flags.remove(.adsEnabled)
}
return currentData.withUpdatedFlags(flags)
} else {
return currentData
}
})
}
|> castError(AdMessagesEnableError.self)
|> ignoreValues
}
}

View File

@ -53,7 +53,8 @@ func _internal_requestRecommendedChannels(account: Account, peerId: EnginePeer.I
guard let inputChannel = channel.flatMap(apiInputChannel) else { guard let inputChannel = channel.flatMap(apiInputChannel) else {
return .complete() return .complete()
} }
return account.network.request(Api.functions.channels.getChannelRecommendations(channel: inputChannel)) let flags: Int32 = (1 << 0)
return account.network.request(Api.functions.channels.getChannelRecommendations(flags: flags, channel: inputChannel))
|> retryRequest |> retryRequest
|> mapToSignal { result -> Signal<Never, NoError> in |> mapToSignal { result -> Signal<Never, NoError> in
return account.postbox.transaction { transaction -> [EnginePeer] in return account.postbox.transaction { transaction -> [EnginePeer] in

View File

@ -258,7 +258,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
previous = CachedUserData() previous = CachedUserData()
} }
switch fullUser { switch fullUser {
case let .userFull(userFullFlags, _, _, userFullAbout, userFullSettings, personalPhoto, profilePhoto, fallbackPhoto, _, userFullBotInfo, userFullPinnedMsgId, userFullCommonChatsCount, _, userFullTtlPeriod, userFullThemeEmoticon, _, _, _, userPremiumGiftOptions, userWallpaper, stories, businessWorkHours, businessLocation, greetingMessage, awayMessage, businessIntro, birthday, personalChannelId, personalChannelMessage): case let .userFull(userFullFlags, userFullFlags2, _, userFullAbout, userFullSettings, personalPhoto, profilePhoto, fallbackPhoto, _, userFullBotInfo, userFullPinnedMsgId, userFullCommonChatsCount, _, userFullTtlPeriod, userFullThemeEmoticon, _, _, _, userPremiumGiftOptions, userWallpaper, stories, businessWorkHours, businessLocation, greetingMessage, awayMessage, businessIntro, birthday, personalChannelId, personalChannelMessage):
let _ = stories let _ = stories
let botInfo = userFullBotInfo.flatMap(BotInfo.init(apiBotInfo:)) let botInfo = userFullBotInfo.flatMap(BotInfo.init(apiBotInfo:))
let isBlocked = (userFullFlags & (1 << 0)) != 0 let isBlocked = (userFullFlags & (1 << 0)) != 0
@ -268,6 +268,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
let readDatesPrivate = (userFullFlags & (1 << 30)) != 0 let readDatesPrivate = (userFullFlags & (1 << 30)) != 0
let premiumRequired = (userFullFlags & (1 << 29)) != 0 let premiumRequired = (userFullFlags & (1 << 29)) != 0
let translationsDisabled = (userFullFlags & (1 << 23)) != 0 let translationsDisabled = (userFullFlags & (1 << 23)) != 0
let adsEnabled = (userFullFlags2 & (1 << 7)) != 0
var flags: CachedUserFlags = previous.flags var flags: CachedUserFlags = previous.flags
if premiumRequired { if premiumRequired {
@ -285,6 +286,11 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
} else { } else {
flags.remove(.translationHidden) flags.remove(.translationHidden)
} }
if adsEnabled {
flags.insert(.adsEnabled)
} else {
flags.remove(.adsEnabled)
}
let callsPrivate = (userFullFlags & (1 << 5)) != 0 let callsPrivate = (userFullFlags & (1 << 5)) != 0
let canPinMessages = (userFullFlags & (1 << 7)) != 0 let canPinMessages = (userFullFlags & (1 << 7)) != 0
@ -409,14 +415,14 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
switch result { switch result {
case let .chatFull(fullChat, chats, users): case let .chatFull(fullChat, chats, users):
switch fullChat { switch fullChat {
case let .chatFull(_, _, _, _, _, notifySettings, _, _, _, _, _, _, _, _, _, _, _): case let .chatFull(_, _, _, _, _, notifySettings, _, _, _, _, _, _, _, _, _, _, _, _):
transaction.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)]) transaction.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
case .channelFull: case .channelFull:
break break
} }
switch fullChat { switch fullChat {
case let .chatFull(chatFullFlags, _, chatFullAbout, chatFullParticipants, chatFullChatPhoto, _, chatFullExportedInvite, chatFullBotInfo, chatFullPinnedMsgId, _, chatFullCall, chatTtlPeriod, chatFullGroupcallDefaultJoinAs, chatFullThemeEmoticon, chatFullRequestsPending, _, allowedReactions): case let .chatFull(chatFullFlags, _, chatFullAbout, chatFullParticipants, chatFullChatPhoto, _, chatFullExportedInvite, chatFullBotInfo, chatFullPinnedMsgId, _, chatFullCall, chatTtlPeriod, chatFullGroupcallDefaultJoinAs, chatFullThemeEmoticon, chatFullRequestsPending, _, allowedReactions, reactionsLimit):
var botInfos: [CachedPeerBotInfo] = [] var botInfos: [CachedPeerBotInfo] = []
for botInfo in chatFullBotInfo ?? [] { for botInfo in chatFullBotInfo ?? [] {
switch botInfo { switch botInfo {
@ -495,6 +501,8 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
mappedAllowedReactions = .empty mappedAllowedReactions = .empty
} }
let _ = reactionsLimit
return previous.withUpdatedParticipants(participants) return previous.withUpdatedParticipants(participants)
.withUpdatedExportedInvitation(exportedInvitation) .withUpdatedExportedInvitation(exportedInvitation)
.withUpdatedBotInfos(botInfos) .withUpdatedBotInfos(botInfos)
@ -540,14 +548,14 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
switch result { switch result {
case let .chatFull(fullChat, chats, users): case let .chatFull(fullChat, chats, users):
switch fullChat { switch fullChat {
case let .channelFull(_, _, _, _, _, _, _, _, _, _, _, _, _, notifySettings, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ ): case let .channelFull(_, _, _, _, _, _, _, _, _, _, _, _, _, notifySettings, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
transaction.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)]) transaction.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
case .chatFull: case .chatFull:
break break
} }
switch fullChat { switch fullChat {
case let .channelFull(flags, flags2, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, chatPhoto, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, _, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, _, inputCall, ttl, pendingSuggestions, groupcallDefaultJoinAs, themeEmoticon, requestsPending, _, defaultSendAs, allowedReactions, _, wallpaper, appliedBoosts, boostsUnrestrict, emojiSet): case let .channelFull(flags, flags2, _, about, participantsCount, adminsCount, kickedCount, bannedCount, _, _, _, _, chatPhoto, _, apiExportedInvite, apiBotInfos, migratedFromChatId, migratedFromMaxId, pinnedMsgId, stickerSet, minAvailableMsgId, _, linkedChatId, location, slowmodeSeconds, slowmodeNextSendDate, statsDc, _, inputCall, ttl, pendingSuggestions, groupcallDefaultJoinAs, themeEmoticon, requestsPending, _, defaultSendAs, allowedReactions, reactionsLimit, _, wallpaper, appliedBoosts, boostsUnrestrict, emojiSet):
var channelFlags = CachedChannelFlags() var channelFlags = CachedChannelFlags()
if (flags & (1 << 3)) != 0 { if (flags & (1 << 3)) != 0 {
channelFlags.insert(.canDisplayParticipants) channelFlags.insert(.canDisplayParticipants)
@ -734,6 +742,8 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
mappedAllowedReactions = .empty mappedAllowedReactions = .empty
} }
let _ = reactionsLimit
let membersHidden = (flags2 & (1 << 2)) != 0 let membersHidden = (flags2 & (1 << 2)) != 0
let forumViewAsMessages = (flags2 & (1 << 6)) != 0 let forumViewAsMessages = (flags2 & (1 << 6)) != 0

View File

@ -194,7 +194,6 @@ private enum ApplicationSpecificGlobalNotice: Int32 {
case outgoingVideoMessagePlayOnceTip = 63 case outgoingVideoMessagePlayOnceTip = 63
case savedMessageTagLabelSuggestion = 65 case savedMessageTagLabelSuggestion = 65
case dismissedBusinessBadge = 68 case dismissedBusinessBadge = 68
case dismissedBirthdayPremiumGifts = 69
case monetizationIntroDismissed = 70 case monetizationIntroDismissed = 70
case businessBotMessageTooltip = 71 case businessBotMessageTooltip = 71
case dismissedBusinessIntroBadge = 72 case dismissedBusinessIntroBadge = 72
@ -511,11 +510,7 @@ private struct ApplicationSpecificNoticeKeys {
static func dismissedBusinessBadge() -> NoticeEntryKey { static func dismissedBusinessBadge() -> NoticeEntryKey {
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.dismissedBusinessBadge.key) return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.dismissedBusinessBadge.key)
} }
static func dismissedBirthdayPremiumGifts() -> NoticeEntryKey {
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.dismissedBirthdayPremiumGifts.key)
}
static func dismissedBirthdayPremiumGiftTip(peerId: PeerId) -> NoticeEntryKey { static func dismissedBirthdayPremiumGiftTip(peerId: PeerId) -> NoticeEntryKey {
return NoticeEntryKey(namespace: noticeNamespace(namespace: dismissedBirthdayPremiumGiftTipNamespace), key: noticeKey(peerId: peerId, key: 0)) return NoticeEntryKey(namespace: noticeNamespace(namespace: dismissedBirthdayPremiumGiftTipNamespace), key: noticeKey(peerId: peerId, key: 0))
} }
@ -2121,25 +2116,6 @@ public struct ApplicationSpecificNotice {
|> take(1) |> take(1)
} }
public static func dismissedBirthdayPremiumGifts(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<[Int64]?, NoError> {
return accountManager.noticeEntry(key: ApplicationSpecificNoticeKeys.dismissedBirthdayPremiumGifts())
|> map { view -> [Int64]? in
if let value = view.value?.get(ApplicationSpecificInt64ArrayNotice.self) {
return value.values
} else {
return nil
}
}
}
public static func setDismissedBirthdayPremiumGifts(accountManager: AccountManager<TelegramAccountManagerTypes>, values: [Int64]) -> Signal<Void, NoError> {
return accountManager.transaction { transaction -> Void in
if let entry = CodableEntry(ApplicationSpecificInt64ArrayNotice(values: values)) {
transaction.setNotice(ApplicationSpecificNoticeKeys.dismissedBirthdayPremiumGifts(), entry)
}
}
}
public static func dismissedBirthdayPremiumGiftTip(accountManager: AccountManager<TelegramAccountManagerTypes>, peerId: PeerId) -> Signal<Int32?, NoError> { public static func dismissedBirthdayPremiumGiftTip(accountManager: AccountManager<TelegramAccountManagerTypes>, peerId: PeerId) -> Signal<Int32?, NoError> {
return accountManager.noticeEntry(key: ApplicationSpecificNoticeKeys.dismissedBirthdayPremiumGiftTip(peerId: peerId)) return accountManager.noticeEntry(key: ApplicationSpecificNoticeKeys.dismissedBirthdayPremiumGiftTip(peerId: peerId))
|> map { view -> Int32? in |> map { view -> Int32? in

View File

@ -314,9 +314,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
contentMediaAspectFilled = flags.contains(.preferMediaAspectFilled) contentMediaAspectFilled = flags.contains(.preferMediaAspectFilled)
} }
var contentMediaInline = false var contentMediaInline = false
var contentMediaImagePeer: EnginePeer?
if let (media, flags) = mediaAndFlags { if let (media, flags) = mediaAndFlags {
contentMediaInline = flags.contains(.preferMediaInline) contentMediaInline = flags.contains(.preferMediaInline)
@ -362,9 +360,6 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
} else if let _ = media as? TelegramMediaStory { } else if let _ = media as? TelegramMediaStory {
contentMediaValue = media contentMediaValue = media
} }
} else if let adAttribute = message.adAttribute, case let .join(_, _, peer) = adAttribute.target, let peer, peer.largeProfileImage != nil {
contentMediaInline = true
contentMediaImagePeer = peer
} }
var maxWidth: CGFloat = .greatestFiniteMagnitude var maxWidth: CGFloat = .greatestFiniteMagnitude
@ -408,9 +403,6 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
inlineMediaAndSize = nil inlineMediaAndSize = nil
} }
} else if let contentMediaImagePeer {
contentMediaContinueLayout = nil
inlineMediaAndSize = (.peerAvatar(contentMediaImagePeer), CGSize(width: 54.0, height: 54.0))
} else { } else {
contentMediaContinueLayout = nil contentMediaContinueLayout = nil
inlineMediaAndSize = nil inlineMediaAndSize = nil

View File

@ -1411,11 +1411,10 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
ignoreForward = true ignoreForward = true
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil) effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil)
displayAuthorInfo = !mergedTop.merged && incoming displayAuthorInfo = !mergedTop.merged && incoming
} else if let adAttribute = item.content.firstMessage.adAttribute, let author = item.content.firstMessage.author { } else if let _ = item.content.firstMessage.adAttribute, let author = item.content.firstMessage.author {
ignoreForward = true ignoreForward = true
effectiveAuthor = author effectiveAuthor = author
displayAuthorInfo = !mergedTop.merged && incoming displayAuthorInfo = !mergedTop.merged && incoming
hasAvatar = adAttribute.displayAvatar
} else { } else {
effectiveAuthor = firstMessage.author effectiveAuthor = firstMessage.author

View File

@ -340,12 +340,6 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible
hasAvatar = true hasAvatar = true
} }
if let adAttribute = message.adAttribute {
if adAttribute.displayAvatar {
hasAvatar = adAttribute.displayAvatar
}
}
if hasAvatar { if hasAvatar {
if let effectiveAuthor = effectiveAuthor { if let effectiveAuthor = effectiveAuthor {
var storyStats: PeerStoryStats? var storyStats: PeerStoryStats?

View File

@ -515,30 +515,7 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent
titleBadge = item.presentationData.strings.Message_AdWhatIsThis titleBadge = item.presentationData.strings.Message_AdWhatIsThis
} }
if let buttonText = adAttribute.buttonText { actionTitle = adAttribute.buttonText.uppercased()
actionTitle = buttonText.uppercased()
} else if let author = item.message.author as? TelegramUser, author.botInfo != nil {
if case .botApp = adAttribute.target {
actionTitle = item.presentationData.strings.Conversation_LaunchApp
} else {
actionTitle = item.presentationData.strings.Conversation_ViewBot
}
} else if let author = item.message.author as? TelegramChannel, case .group = author.info {
if case let .peer(_, messageId, _) = adAttribute.target, messageId != nil {
actionTitle = item.presentationData.strings.Conversation_ViewPost
} else {
actionTitle = item.presentationData.strings.Conversation_ViewGroup
}
} else {
if case .webPage = adAttribute.target {
actionTitle = item.presentationData.strings.Conversation_OpenLink
actionIcon = .link
} else if case let .peer(_, messageId, _) = adAttribute.target, messageId != nil {
actionTitle = item.presentationData.strings.Conversation_ViewMessage
} else {
actionTitle = item.presentationData.strings.Conversation_ViewChannel
}
}
displayLine = true displayLine = true
} }

View File

@ -4080,45 +4080,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
guard let self, let message = self.chatDisplayNode.historyNode.messageInCurrentHistoryView(messageId), let adAttribute = message.adAttribute else { guard let self, let message = self.chatDisplayNode.historyNode.messageInCurrentHistoryView(messageId), let adAttribute = message.adAttribute else {
return return
} }
self.chatDisplayNode.historyNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId) self.chatDisplayNode.historyNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId)
self.controllerInteraction?.openUrl(ChatControllerInteraction.OpenUrl(url: adAttribute.url, concealed: false, external: true))
switch adAttribute.target {
case let .peer(id, messageId, startParam):
if case let .peer(currentPeerId) = self.chatLocation, currentPeerId == id {
if let messageId {
self.navigateToMessage(from: nil, to: .id(messageId, NavigateToMessageParams(timestamp: nil, quote: nil)), rememberInStack: false)
}
} else {
let navigationData: ChatControllerInteractionNavigateToPeer
if let bot = message.author as? TelegramUser, bot.botInfo != nil, let startParam = startParam {
navigationData = .withBotStartPayload(ChatControllerInitialBotStart(payload: startParam, behavior: .interactive))
} else {
var subject: ChatControllerSubject?
if let messageId = messageId {
subject = .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil)
}
navigationData = .chat(textInputState: nil, subject: subject, peekData: nil)
}
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: id))
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
if let self, let peer = peer {
self.openPeer(peer: peer, navigation: navigationData, fromMessage: nil)
}
})
}
case let .join(_, joinHash, _):
self.controllerInteraction?.openJoinLink(joinHash)
case let .webPage(_, url):
self.controllerInteraction?.openUrl(ChatControllerInteraction.OpenUrl(url: url, concealed: false, external: true))
case let .botApp(peerId, botApp, startParam):
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
if let self, let peer {
self.presentBotApp(botApp: botApp, botPeer: peer, payload: startParam)
}
})
}
}, openRequestedPeerSelection: { [weak self] messageId, peerType, buttonId, maxQuantity in }, openRequestedPeerSelection: { [weak self] messageId, peerType, buttonId, maxQuantity in
guard let self else { guard let self else {
return return

View File

@ -2205,18 +2205,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
filterImpl?() filterImpl?()
completion?() completion?()
if let currentBirthdays { if case .chatList = source, let _ = currentBirthdays {
let today = Calendar(identifier: .gregorian).component(.day, from: Date()) let _ = context.engine.notices.dismissServerProvidedSuggestion(suggestion: .todayBirthdays).startStandalone()
var todayBirthdayPeerIds: [EnginePeer.Id] = []
for (peerId, birthday) in currentBirthdays {
if birthday.day == today {
todayBirthdayPeerIds.append(peerId)
}
}
let peerIds = todayBirthdayPeerIds.sorted { lhs, rhs in
return lhs < rhs
}
let _ = ApplicationSpecificNotice.setDismissedBirthdayPremiumGifts(accountManager: context.sharedContext.accountManager, values: peerIds.map { $0.toInt64() }).start()
} }
}) })
pushImpl = { [weak giftController] c in pushImpl = { [weak giftController] c in