mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Stats and recommendations improvements
This commit is contained in:
parent
13baadc3e7
commit
cc2bd5ec92
@ -10508,3 +10508,9 @@ Sorry for the inconvenience.";
|
||||
"Stats.StoryTitle" = "Story Statistics";
|
||||
|
||||
"Channel.Info.Settings" = "Channel Settings";
|
||||
|
||||
"Story.Context.ViewStats" = "View Statistics";
|
||||
|
||||
"Share.RepostStory" = "Repost\nStory";
|
||||
|
||||
"PeerInfo.PaneRecommended" = "Similar Channels";
|
||||
|
@ -933,7 +933,9 @@ public protocol SharedAccountContext: AnyObject {
|
||||
|
||||
func makeInstalledStickerPacksController(context: AccountContext, mode: InstalledStickerPacksControllerMode, forceTheme: PresentationTheme?) -> ViewController
|
||||
|
||||
func makeChannelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, boosts: Bool, boostStatus: ChannelBoostStatus?, statsDatacenterId: Int32) -> ViewController
|
||||
func makeChannelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, boosts: Bool, boostStatus: ChannelBoostStatus?) -> ViewController
|
||||
func makeMessagesStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, messageId: EngineMessage.Id) -> ViewController
|
||||
func makeStoryStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, storyId: Int32) -> ViewController
|
||||
|
||||
func makeDebugSettingsController(context: AccountContext?) -> ViewController?
|
||||
|
||||
|
@ -989,14 +989,8 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
|
||||
}
|
||||
|
||||
let tooltipController = UndoOverlayController(presentationData: presentationData, content: .premiumPaywall(title: title, text: text, customUndoText: nil, timeout: nil, linkAction: { [weak navigationController] _ in
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.StatsDatacenterId(id: peerId))
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak navigationController] statsDatacenterId in
|
||||
guard let statsDatacenterId else {
|
||||
return
|
||||
}
|
||||
let statsController = context.sharedContext.makeChannelStatsController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, boosts: true, boostStatus: nil, statsDatacenterId: statsDatacenterId)
|
||||
let statsController = context.sharedContext.makeChannelStatsController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, boosts: true, boostStatus: nil)
|
||||
navigationController?.pushViewController(statsController)
|
||||
})
|
||||
}), elevatedLayout: false, action: { _ in
|
||||
return true
|
||||
})
|
||||
@ -1068,14 +1062,8 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
|
||||
let text = presentationData.strings.BoostGift_GiveawayCreated_Text
|
||||
|
||||
let tooltipController = UndoOverlayController(presentationData: presentationData, content: .premiumPaywall(title: title, text: text, customUndoText: nil, timeout: nil, linkAction: { [weak navigationController] _ in
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.StatsDatacenterId(id: peerId))
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak navigationController] statsDatacenterId in
|
||||
guard let statsDatacenterId else {
|
||||
return
|
||||
}
|
||||
let statsController = context.sharedContext.makeChannelStatsController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, boosts: true, boostStatus: nil, statsDatacenterId: statsDatacenterId)
|
||||
let statsController = context.sharedContext.makeChannelStatsController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, boosts: true, boostStatus: nil)
|
||||
navigationController?.pushViewController(statsController)
|
||||
})
|
||||
}), elevatedLayout: false, action: { _ in
|
||||
return true
|
||||
})
|
||||
|
@ -155,7 +155,7 @@ private enum StatsEntry: ItemListNodeEntry {
|
||||
case instantPageInteractionsGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsGraph, ChartType)
|
||||
|
||||
case postsTitle(PresentationTheme, String)
|
||||
case post(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, StatsPostItem, ChannelStatsMessageInteractions)
|
||||
case post(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, StatsPostItem, ChannelStatsPostInteractions)
|
||||
|
||||
case boostLevel(PresentationTheme, Int32, Int32, CGFloat)
|
||||
|
||||
@ -816,7 +816,7 @@ private struct ChannelStatsControllerState: Equatable {
|
||||
}
|
||||
|
||||
|
||||
private func channelStatsControllerEntries(state: ChannelStatsControllerState, peer: EnginePeer?, data: ChannelStats?, messages: [Message]?, stories: PeerStoryListContext.State?, interactions: [MessageId: ChannelStatsMessageInteractions]?, boostData: ChannelBoostStatus?, boostersState: ChannelBoostersContext.State?, giftsState: ChannelBoostersContext.State?, presentationData: PresentationData, giveawayAvailable: Bool) -> [StatsEntry] {
|
||||
private func channelStatsControllerEntries(state: ChannelStatsControllerState, peer: EnginePeer?, data: ChannelStats?, messages: [Message]?, stories: PeerStoryListContext.State?, interactions: [ChannelStatsPostInteractions.PostId: ChannelStatsPostInteractions]?, boostData: ChannelBoostStatus?, boostersState: ChannelBoostersContext.State?, giftsState: ChannelBoostersContext.State?, presentationData: PresentationData, giveawayAvailable: Bool) -> [StatsEntry] {
|
||||
var entries: [StatsEntry] = []
|
||||
|
||||
switch state.section {
|
||||
@ -889,37 +889,43 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
|
||||
}
|
||||
|
||||
|
||||
if let peer, let interactions {
|
||||
var posts: [StatsPostItem] = []
|
||||
if let messages, let interactions {
|
||||
if let messages {
|
||||
for message in messages {
|
||||
if let _ = interactions[message.id] {
|
||||
if let _ = interactions[.message(id: message.id)] {
|
||||
posts.append(.message(message))
|
||||
}
|
||||
}
|
||||
}
|
||||
if let stories {
|
||||
for story in stories.items {
|
||||
if let _ = interactions[.story(peerId: peer.id, id: story.id)] {
|
||||
posts.append(.story(story))
|
||||
}
|
||||
}
|
||||
}
|
||||
posts.sort(by: { $0.timestamp > $1.timestamp })
|
||||
|
||||
if !posts.isEmpty, let interactions, let peer = peer?._asPeer() {
|
||||
if !posts.isEmpty {
|
||||
entries.append(.postsTitle(presentationData.theme, presentationData.strings.Stats_PostsTitle))
|
||||
var index: Int32 = 0
|
||||
for post in posts {
|
||||
switch post {
|
||||
case let .message(message):
|
||||
if let interactions = interactions[message.id] {
|
||||
entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, post, interactions))
|
||||
if let interactions = interactions[.message(id: message.id)] {
|
||||
entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer._asPeer(), post, interactions))
|
||||
}
|
||||
case let .story(story):
|
||||
entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, post, ChannelStatsMessageInteractions(messageId: MessageId(peerId: PeerId(0), namespace: 0, id: 0), views: Int32(story.views?.seenCount ?? 0), forwards: Int32(story.views?.forwardCount ?? 0), reactions: Int32(story.views?.reactedCount ?? 0))))
|
||||
if let interactions = interactions[.story(peerId: peer.id, id: story.id)] {
|
||||
entries.append(.post(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer._asPeer(), post, interactions))
|
||||
}
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case .boosts:
|
||||
if let boostData {
|
||||
let progress: CGFloat
|
||||
@ -1032,7 +1038,7 @@ private func channelStatsControllerEntries(state: ChannelStatsControllerState, p
|
||||
return entries
|
||||
}
|
||||
|
||||
public func channelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, section: ChannelStatsSection = .stats, boostStatus: ChannelBoostStatus? = nil, statsDatacenterId: Int32?) -> ViewController {
|
||||
public func channelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, section: ChannelStatsSection = .stats, boostStatus: ChannelBoostStatus? = nil) -> ViewController {
|
||||
let statePromise = ValuePromise(ChannelStatsControllerState(section: section, boostersExpanded: false, moreBoostersDisplayed: 0, giftsSelected: false), ignoreRepeated: true)
|
||||
let stateValue = Atomic(value: ChannelStatsControllerState(section: section, boostersExpanded: false, moreBoostersDisplayed: 0, giftsSelected: false))
|
||||
let updateState: ((ChannelStatsControllerState) -> ChannelStatsControllerState) -> Void = { f in
|
||||
@ -1050,9 +1056,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
||||
|
||||
let storiesPromise = Promise<PeerStoryListContext.State?>()
|
||||
|
||||
let datacenterId: Int32 = statsDatacenterId ?? 0
|
||||
|
||||
let statsContext = ChannelStatsContext(postbox: context.account.postbox, network: context.account.network, datacenterId: datacenterId, peerId: peerId)
|
||||
let statsContext = ChannelStatsContext(postbox: context.account.postbox, network: context.account.network, peerId: peerId)
|
||||
let dataSignal: Signal<ChannelStats?, NoError> = statsContext.state
|
||||
|> map { state in
|
||||
return state.stats
|
||||
@ -1251,9 +1255,9 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
||||
let messages = messageView?.entries.map { $0.message }.sorted(by: { (lhsMessage, rhsMessage) -> Bool in
|
||||
return lhsMessage.timestamp > rhsMessage.timestamp
|
||||
})
|
||||
let interactions = data?.messageInteractions.reduce([MessageId : ChannelStatsMessageInteractions]()) { (map, interactions) -> [MessageId : ChannelStatsMessageInteractions] in
|
||||
let interactions = data?.postInteractions.reduce([ChannelStatsPostInteractions.PostId : ChannelStatsPostInteractions]()) { (map, interactions) -> [ChannelStatsPostInteractions.PostId : ChannelStatsPostInteractions] in
|
||||
var map = map
|
||||
map[interactions.messageId] = interactions
|
||||
map[interactions.postId] = interactions
|
||||
return map
|
||||
}
|
||||
|
||||
@ -1288,9 +1292,9 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
||||
case let .message(message):
|
||||
subject = .message(id: message.id)
|
||||
case let .story(story):
|
||||
subject = .story(peer: peer, storyItem: story)
|
||||
subject = .story(peerId: peerId, id: story.id)
|
||||
}
|
||||
controller?.push(messageStatsController(context: context, subject: subject, statsDatacenterId: statsDatacenterId))
|
||||
controller?.push(messageStatsController(context: context, subject: subject))
|
||||
}
|
||||
contextActionImpl = { [weak controller] messageId, sourceNode, gesture in
|
||||
guard let controller = controller, let sourceNode = sourceNode as? ContextExtractedContentContainingNode else {
|
||||
|
@ -707,7 +707,7 @@ private func canEditAdminRights(accountPeerId: EnginePeer.Id, channelPeer: Engin
|
||||
}
|
||||
}
|
||||
|
||||
public func groupStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id, statsDatacenterId: Int32?) -> ViewController {
|
||||
public func groupStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: EnginePeer.Id) -> ViewController {
|
||||
let statePromise = ValuePromise(GroupStatsState())
|
||||
let stateValue = Atomic(value: GroupStatsState())
|
||||
let updateState: ((GroupStatsState) -> GroupStatsState) -> Void = { f in
|
||||
@ -718,8 +718,6 @@ public func groupStatsController(context: AccountContext, updatedPresentationDat
|
||||
let dataPromise = Promise<GroupStats?>(nil)
|
||||
let peersPromise = Promise<[EnginePeer.Id: EnginePeer]?>(nil)
|
||||
|
||||
let datacenterId: Int32 = statsDatacenterId ?? 0
|
||||
|
||||
var openPeerImpl: ((EnginePeer) -> Void)?
|
||||
var openPeerHistoryImpl: ((EnginePeer.Id) -> Void)?
|
||||
var openPeerAdminActionsImpl: ((EnginePeer.Id) -> Void)?
|
||||
@ -727,7 +725,7 @@ public func groupStatsController(context: AccountContext, updatedPresentationDat
|
||||
|
||||
actionsDisposable.add(context.account.viewTracker.peerView(peerId, updateData: true).start())
|
||||
|
||||
let statsContext = GroupStatsContext(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, datacenterId: datacenterId, peerId: peerId)
|
||||
let statsContext = GroupStatsContext(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId)
|
||||
let dataSignal: Signal<GroupStats?, NoError> = statsContext.state
|
||||
|> map { state in
|
||||
return state.stats
|
||||
|
@ -221,7 +221,7 @@ private func messageStatsControllerEntries(data: PostStats?, messages: SearchMes
|
||||
|
||||
public enum StatsSubject {
|
||||
case message(id: EngineMessage.Id)
|
||||
case story(peer: EnginePeer, storyItem: EngineStoryItem)
|
||||
case story(peerId: EnginePeer.Id, id: Int32)
|
||||
}
|
||||
|
||||
protocol PostStats {
|
||||
@ -240,21 +240,19 @@ extension StoryStats: PostStats {
|
||||
|
||||
}
|
||||
|
||||
public func messageStatsController(context: AccountContext, subject: StatsSubject, statsDatacenterId: Int32?) -> ViewController {
|
||||
public func messageStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, subject: StatsSubject) -> ViewController {
|
||||
var navigateToMessageImpl: ((EngineMessage.Id) -> Void)?
|
||||
|
||||
let actionsDisposable = DisposableSet()
|
||||
let dataPromise = Promise<PostStats?>(nil)
|
||||
let messagesPromise = Promise<(SearchMessagesResult, SearchMessagesState)?>(nil)
|
||||
|
||||
let datacenterId: Int32 = statsDatacenterId ?? 0
|
||||
|
||||
let anyStatsContext: Any
|
||||
let dataSignal: Signal<PostStats?, NoError>
|
||||
var loadDetailedGraphImpl: ((StatsGraph, Int64) -> Signal<StatsGraph?, NoError>)?
|
||||
switch subject {
|
||||
case let .message(id):
|
||||
let statsContext = MessageStatsContext(postbox: context.account.postbox, network: context.account.network, datacenterId: datacenterId, messageId: id)
|
||||
let statsContext = MessageStatsContext(postbox: context.account.postbox, network: context.account.network, messageId: id)
|
||||
loadDetailedGraphImpl = { [weak statsContext] graph, x in
|
||||
return statsContext?.loadDetailedGraph(graph, x: x) ?? .single(nil)
|
||||
}
|
||||
@ -264,8 +262,8 @@ public func messageStatsController(context: AccountContext, subject: StatsSubjec
|
||||
}
|
||||
dataPromise.set(.single(nil) |> then(dataSignal))
|
||||
anyStatsContext = statsContext
|
||||
case let .story(peer, storyItem):
|
||||
let statsContext = StoryStatsContext(postbox: context.account.postbox, network: context.account.network, datacenterId: datacenterId, peerId: peer.id, storyId: storyItem.id)
|
||||
case let .story(peerId, id):
|
||||
let statsContext = StoryStatsContext(postbox: context.account.postbox, network: context.account.network, peerId: peerId, storyId: id)
|
||||
loadDetailedGraphImpl = { [weak statsContext] graph, x in
|
||||
return statsContext?.loadDetailedGraph(graph, x: x) ?? .single(nil)
|
||||
}
|
||||
@ -288,7 +286,7 @@ public func messageStatsController(context: AccountContext, subject: StatsSubjec
|
||||
let previousData = Atomic<PostStats?>(value: nil)
|
||||
|
||||
if case let .message(id) = subject {
|
||||
let searchSignal = context.engine.messages.searchMessages(location: .publicForwards(messageId: id, datacenterId: Int(datacenterId)), query: "", state: nil)
|
||||
let searchSignal = context.engine.messages.searchMessages(location: .publicForwards(messageId: id), query: "", state: nil)
|
||||
|> map(Optional.init)
|
||||
|> afterNext { result in
|
||||
if let result = result {
|
||||
@ -304,17 +302,31 @@ public func messageStatsController(context: AccountContext, subject: StatsSubjec
|
||||
messagesPromise.set(.single(nil))
|
||||
}
|
||||
|
||||
let iconNode: ASDisplayNode?
|
||||
if case let .story(peer, storyItem) = subject {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
iconNode = StoryIconNode(context: context, theme: presentationData.theme, peer: peer._asPeer(), storyItem: storyItem)
|
||||
let iconNodePromise = Promise<ASDisplayNode?>()
|
||||
if case let .story(peerId, id) = subject {
|
||||
let _ = id
|
||||
iconNodePromise.set(
|
||||
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue
|
||||
|> map { peer -> ASDisplayNode? in
|
||||
if let _ = peer?._asPeer() {
|
||||
// let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
// return StoryIconNode(context: context, theme: presentationData.theme, peer: peer, storyItem: storyItem)
|
||||
return nil
|
||||
} else {
|
||||
iconNode = nil
|
||||
return nil
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
} else {
|
||||
iconNodePromise.set(.single(nil))
|
||||
}
|
||||
|
||||
let signal = combineLatest(context.sharedContext.presentationData, dataPromise.get(), messagesPromise.get(), longLoadingSignal)
|
||||
let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData
|
||||
let signal = combineLatest(presentationData, dataPromise.get(), messagesPromise.get(), longLoadingSignal, iconNodePromise.get())
|
||||
|> deliverOnMainQueue
|
||||
|> map { presentationData, data, search, longLoading -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
|> map { presentationData, data, search, longLoading, iconNode -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let previous = previousData.swap(data)
|
||||
var emptyStateItem: ItemListControllerEmptyStateItem?
|
||||
if data == nil {
|
||||
|
@ -173,7 +173,14 @@ class MessageStatsOverviewItemNode: ListViewItemNode {
|
||||
leftTitleLabelLayoutAndApply = makeLeftTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Stats_Message_Views, font: titleFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 2, truncationType: .end, constrainedSize: CGSize(width: min(maxItemWidth, remainingWidth), height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
remainingWidth -= leftTitleLabelLayoutAndApply!.0.size.width - 4.0
|
||||
|
||||
centerTitleLabelLayoutAndApply = makeCenterTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Stats_Message_PublicShares, font: titleFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 2, truncationType: .end, constrainedSize: CGSize(width: min(maxItemWidth, remainingWidth), height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
let centerTitle: String
|
||||
if let _ = item.stats as? StoryStats {
|
||||
centerTitle = "Reactions"
|
||||
} else {
|
||||
centerTitle = item.presentationData.strings.Stats_Message_PublicShares
|
||||
}
|
||||
|
||||
centerTitleLabelLayoutAndApply = makeCenterTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: centerTitle, font: titleFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 2, truncationType: .end, constrainedSize: CGSize(width: min(maxItemWidth, remainingWidth), height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
remainingWidth -= centerTitleLabelLayoutAndApply!.0.size.width - 4.0
|
||||
|
||||
rightTitleLabelLayoutAndApply = makeRightTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Stats_Message_PrivateShares, font: titleFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 2, truncationType: .end, constrainedSize: CGSize(width: min(maxItemWidth, remainingWidth), height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
@ -535,7 +535,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-297296796] = { return Api.MessageExtendedMedia.parse_messageExtendedMedia($0) }
|
||||
dict[-1386050360] = { return Api.MessageExtendedMedia.parse_messageExtendedMediaPreview($0) }
|
||||
dict[1601666510] = { return Api.MessageFwdHeader.parse_messageFwdHeader($0) }
|
||||
dict[-1387279939] = { return Api.MessageInteractionCounters.parse_messageInteractionCounters($0) }
|
||||
dict[1882335561] = { return Api.MessageMedia.parse_messageMediaContact($0) }
|
||||
dict[1065280907] = { return Api.MessageMedia.parse_messageMediaDice($0) }
|
||||
dict[1291114285] = { return Api.MessageMedia.parse_messageMediaDocument($0) }
|
||||
@ -669,6 +668,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[2061444128] = { return Api.PollResults.parse_pollResults($0) }
|
||||
dict[1558266229] = { return Api.PopularContact.parse_popularContact($0) }
|
||||
dict[512535275] = { return Api.PostAddress.parse_postAddress($0) }
|
||||
dict[-419066241] = { return Api.PostInteractionCounters.parse_postInteractionCountersMessage($0) }
|
||||
dict[-1974989273] = { return Api.PostInteractionCounters.parse_postInteractionCountersStory($0) }
|
||||
dict[629052971] = { return Api.PremiumGiftCodeOption.parse_premiumGiftCodeOption($0) }
|
||||
dict[1958953753] = { return Api.PremiumGiftOption.parse_premiumGiftOption($0) }
|
||||
dict[1596792306] = { return Api.PremiumSubscriptionOption.parse_premiumSubscriptionOption($0) }
|
||||
@ -1187,7 +1188,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-2030542532] = { return Api.premium.BoostsList.parse_boostsList($0) }
|
||||
dict[1230586490] = { return Api.premium.BoostsStatus.parse_boostsStatus($0) }
|
||||
dict[-1696454430] = { return Api.premium.MyBoosts.parse_myBoosts($0) }
|
||||
dict[-886032030] = { return Api.stats.BroadcastStats.parse_broadcastStats($0) }
|
||||
dict[963421692] = { return Api.stats.BroadcastStats.parse_broadcastStats($0) }
|
||||
dict[-276825834] = { return Api.stats.MegagroupStats.parse_megagroupStats($0) }
|
||||
dict[2145983508] = { return Api.stats.MessageStats.parse_messageStats($0) }
|
||||
dict[1355613820] = { return Api.stats.StoryStats.parse_storyStats($0) }
|
||||
@ -1593,8 +1594,6 @@ public extension Api {
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.MessageFwdHeader:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.MessageInteractionCounters:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.MessageMedia:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.MessagePeerReaction:
|
||||
@ -1683,6 +1682,8 @@ public extension Api {
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.PostAddress:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.PostInteractionCounters:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.PremiumGiftCodeOption:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.PremiumGiftOption:
|
||||
|
@ -688,50 +688,6 @@ public extension Api {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum MessageInteractionCounters: TypeConstructorDescription {
|
||||
case messageInteractionCounters(msgId: Int32, views: Int32, forwards: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .messageInteractionCounters(let msgId, let views, let forwards):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1387279939)
|
||||
}
|
||||
serializeInt32(msgId, buffer: buffer, boxed: false)
|
||||
serializeInt32(views, buffer: buffer, boxed: false)
|
||||
serializeInt32(forwards, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .messageInteractionCounters(let msgId, let views, let forwards):
|
||||
return ("messageInteractionCounters", [("msgId", msgId as Any), ("views", views as Any), ("forwards", forwards as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_messageInteractionCounters(_ reader: BufferReader) -> MessageInteractionCounters? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
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.MessageInteractionCounters.messageInteractionCounters(msgId: _1!, views: _2!, forwards: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
indirect enum MessageMedia: TypeConstructorDescription {
|
||||
case messageMediaContact(phoneNumber: String, firstName: String, lastName: String, vcard: String, userId: Int64)
|
||||
|
@ -750,6 +750,86 @@ public extension Api {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum PostInteractionCounters: TypeConstructorDescription {
|
||||
case postInteractionCountersMessage(msgId: Int32, views: Int32, forwards: Int32, reactions: Int32)
|
||||
case postInteractionCountersStory(storyId: Int32, views: Int32, forwards: Int32, reactions: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .postInteractionCountersMessage(let msgId, let views, let forwards, let reactions):
|
||||
if boxed {
|
||||
buffer.appendInt32(-419066241)
|
||||
}
|
||||
serializeInt32(msgId, buffer: buffer, boxed: false)
|
||||
serializeInt32(views, buffer: buffer, boxed: false)
|
||||
serializeInt32(forwards, buffer: buffer, boxed: false)
|
||||
serializeInt32(reactions, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .postInteractionCountersStory(let storyId, let views, let forwards, let reactions):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1974989273)
|
||||
}
|
||||
serializeInt32(storyId, buffer: buffer, boxed: false)
|
||||
serializeInt32(views, buffer: buffer, boxed: false)
|
||||
serializeInt32(forwards, buffer: buffer, boxed: false)
|
||||
serializeInt32(reactions, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .postInteractionCountersMessage(let msgId, let views, let forwards, let reactions):
|
||||
return ("postInteractionCountersMessage", [("msgId", msgId as Any), ("views", views as Any), ("forwards", forwards as Any), ("reactions", reactions as Any)])
|
||||
case .postInteractionCountersStory(let storyId, let views, let forwards, let reactions):
|
||||
return ("postInteractionCountersStory", [("storyId", storyId as Any), ("views", views as Any), ("forwards", forwards as Any), ("reactions", reactions as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_postInteractionCountersMessage(_ reader: BufferReader) -> PostInteractionCounters? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.PostInteractionCounters.postInteractionCountersMessage(msgId: _1!, views: _2!, forwards: _3!, reactions: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_postInteractionCountersStory(_ reader: BufferReader) -> PostInteractionCounters? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.PostInteractionCounters.postInteractionCountersStory(storyId: _1!, views: _2!, forwards: _3!, reactions: _4!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum PremiumGiftCodeOption: TypeConstructorDescription {
|
||||
case premiumGiftCodeOption(flags: Int32, users: Int32, months: Int32, storeProduct: String?, storeQuantity: Int32?, currency: String, amount: Int64)
|
||||
@ -1110,183 +1190,3 @@ public extension Api {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum PrivacyRule: TypeConstructorDescription {
|
||||
case privacyValueAllowAll
|
||||
case privacyValueAllowChatParticipants(chats: [Int64])
|
||||
case privacyValueAllowCloseFriends
|
||||
case privacyValueAllowContacts
|
||||
case privacyValueAllowUsers(users: [Int64])
|
||||
case privacyValueDisallowAll
|
||||
case privacyValueDisallowChatParticipants(chats: [Int64])
|
||||
case privacyValueDisallowContacts
|
||||
case privacyValueDisallowUsers(users: [Int64])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .privacyValueAllowAll:
|
||||
if boxed {
|
||||
buffer.appendInt32(1698855810)
|
||||
}
|
||||
|
||||
break
|
||||
case .privacyValueAllowChatParticipants(let chats):
|
||||
if boxed {
|
||||
buffer.appendInt32(1796427406)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .privacyValueAllowCloseFriends:
|
||||
if boxed {
|
||||
buffer.appendInt32(-135735141)
|
||||
}
|
||||
|
||||
break
|
||||
case .privacyValueAllowContacts:
|
||||
if boxed {
|
||||
buffer.appendInt32(-123988)
|
||||
}
|
||||
|
||||
break
|
||||
case .privacyValueAllowUsers(let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1198497870)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .privacyValueDisallowAll:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1955338397)
|
||||
}
|
||||
|
||||
break
|
||||
case .privacyValueDisallowChatParticipants(let chats):
|
||||
if boxed {
|
||||
buffer.appendInt32(1103656293)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .privacyValueDisallowContacts:
|
||||
if boxed {
|
||||
buffer.appendInt32(-125240806)
|
||||
}
|
||||
|
||||
break
|
||||
case .privacyValueDisallowUsers(let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-463335103)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .privacyValueAllowAll:
|
||||
return ("privacyValueAllowAll", [])
|
||||
case .privacyValueAllowChatParticipants(let chats):
|
||||
return ("privacyValueAllowChatParticipants", [("chats", chats as Any)])
|
||||
case .privacyValueAllowCloseFriends:
|
||||
return ("privacyValueAllowCloseFriends", [])
|
||||
case .privacyValueAllowContacts:
|
||||
return ("privacyValueAllowContacts", [])
|
||||
case .privacyValueAllowUsers(let users):
|
||||
return ("privacyValueAllowUsers", [("users", users as Any)])
|
||||
case .privacyValueDisallowAll:
|
||||
return ("privacyValueDisallowAll", [])
|
||||
case .privacyValueDisallowChatParticipants(let chats):
|
||||
return ("privacyValueDisallowChatParticipants", [("chats", chats as Any)])
|
||||
case .privacyValueDisallowContacts:
|
||||
return ("privacyValueDisallowContacts", [])
|
||||
case .privacyValueDisallowUsers(let users):
|
||||
return ("privacyValueDisallowUsers", [("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_privacyValueAllowAll(_ reader: BufferReader) -> PrivacyRule? {
|
||||
return Api.PrivacyRule.privacyValueAllowAll
|
||||
}
|
||||
public static func parse_privacyValueAllowChatParticipants(_ reader: BufferReader) -> PrivacyRule? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.PrivacyRule.privacyValueAllowChatParticipants(chats: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_privacyValueAllowCloseFriends(_ reader: BufferReader) -> PrivacyRule? {
|
||||
return Api.PrivacyRule.privacyValueAllowCloseFriends
|
||||
}
|
||||
public static func parse_privacyValueAllowContacts(_ reader: BufferReader) -> PrivacyRule? {
|
||||
return Api.PrivacyRule.privacyValueAllowContacts
|
||||
}
|
||||
public static func parse_privacyValueAllowUsers(_ reader: BufferReader) -> PrivacyRule? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.PrivacyRule.privacyValueAllowUsers(users: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_privacyValueDisallowAll(_ reader: BufferReader) -> PrivacyRule? {
|
||||
return Api.PrivacyRule.privacyValueDisallowAll
|
||||
}
|
||||
public static func parse_privacyValueDisallowChatParticipants(_ reader: BufferReader) -> PrivacyRule? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.PrivacyRule.privacyValueDisallowChatParticipants(chats: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_privacyValueDisallowContacts(_ reader: BufferReader) -> PrivacyRule? {
|
||||
return Api.PrivacyRule.privacyValueDisallowContacts
|
||||
}
|
||||
public static func parse_privacyValueDisallowUsers(_ reader: BufferReader) -> PrivacyRule? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.PrivacyRule.privacyValueDisallowUsers(users: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,183 @@
|
||||
public extension Api {
|
||||
enum PrivacyRule: TypeConstructorDescription {
|
||||
case privacyValueAllowAll
|
||||
case privacyValueAllowChatParticipants(chats: [Int64])
|
||||
case privacyValueAllowCloseFriends
|
||||
case privacyValueAllowContacts
|
||||
case privacyValueAllowUsers(users: [Int64])
|
||||
case privacyValueDisallowAll
|
||||
case privacyValueDisallowChatParticipants(chats: [Int64])
|
||||
case privacyValueDisallowContacts
|
||||
case privacyValueDisallowUsers(users: [Int64])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .privacyValueAllowAll:
|
||||
if boxed {
|
||||
buffer.appendInt32(1698855810)
|
||||
}
|
||||
|
||||
break
|
||||
case .privacyValueAllowChatParticipants(let chats):
|
||||
if boxed {
|
||||
buffer.appendInt32(1796427406)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .privacyValueAllowCloseFriends:
|
||||
if boxed {
|
||||
buffer.appendInt32(-135735141)
|
||||
}
|
||||
|
||||
break
|
||||
case .privacyValueAllowContacts:
|
||||
if boxed {
|
||||
buffer.appendInt32(-123988)
|
||||
}
|
||||
|
||||
break
|
||||
case .privacyValueAllowUsers(let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1198497870)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .privacyValueDisallowAll:
|
||||
if boxed {
|
||||
buffer.appendInt32(-1955338397)
|
||||
}
|
||||
|
||||
break
|
||||
case .privacyValueDisallowChatParticipants(let chats):
|
||||
if boxed {
|
||||
buffer.appendInt32(1103656293)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(chats.count))
|
||||
for item in chats {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .privacyValueDisallowContacts:
|
||||
if boxed {
|
||||
buffer.appendInt32(-125240806)
|
||||
}
|
||||
|
||||
break
|
||||
case .privacyValueDisallowUsers(let users):
|
||||
if boxed {
|
||||
buffer.appendInt32(-463335103)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(users.count))
|
||||
for item in users {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .privacyValueAllowAll:
|
||||
return ("privacyValueAllowAll", [])
|
||||
case .privacyValueAllowChatParticipants(let chats):
|
||||
return ("privacyValueAllowChatParticipants", [("chats", chats as Any)])
|
||||
case .privacyValueAllowCloseFriends:
|
||||
return ("privacyValueAllowCloseFriends", [])
|
||||
case .privacyValueAllowContacts:
|
||||
return ("privacyValueAllowContacts", [])
|
||||
case .privacyValueAllowUsers(let users):
|
||||
return ("privacyValueAllowUsers", [("users", users as Any)])
|
||||
case .privacyValueDisallowAll:
|
||||
return ("privacyValueDisallowAll", [])
|
||||
case .privacyValueDisallowChatParticipants(let chats):
|
||||
return ("privacyValueDisallowChatParticipants", [("chats", chats as Any)])
|
||||
case .privacyValueDisallowContacts:
|
||||
return ("privacyValueDisallowContacts", [])
|
||||
case .privacyValueDisallowUsers(let users):
|
||||
return ("privacyValueDisallowUsers", [("users", users as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_privacyValueAllowAll(_ reader: BufferReader) -> PrivacyRule? {
|
||||
return Api.PrivacyRule.privacyValueAllowAll
|
||||
}
|
||||
public static func parse_privacyValueAllowChatParticipants(_ reader: BufferReader) -> PrivacyRule? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.PrivacyRule.privacyValueAllowChatParticipants(chats: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_privacyValueAllowCloseFriends(_ reader: BufferReader) -> PrivacyRule? {
|
||||
return Api.PrivacyRule.privacyValueAllowCloseFriends
|
||||
}
|
||||
public static func parse_privacyValueAllowContacts(_ reader: BufferReader) -> PrivacyRule? {
|
||||
return Api.PrivacyRule.privacyValueAllowContacts
|
||||
}
|
||||
public static func parse_privacyValueAllowUsers(_ reader: BufferReader) -> PrivacyRule? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.PrivacyRule.privacyValueAllowUsers(users: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_privacyValueDisallowAll(_ reader: BufferReader) -> PrivacyRule? {
|
||||
return Api.PrivacyRule.privacyValueDisallowAll
|
||||
}
|
||||
public static func parse_privacyValueDisallowChatParticipants(_ reader: BufferReader) -> PrivacyRule? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.PrivacyRule.privacyValueDisallowChatParticipants(chats: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_privacyValueDisallowContacts(_ reader: BufferReader) -> PrivacyRule? {
|
||||
return Api.PrivacyRule.privacyValueDisallowContacts
|
||||
}
|
||||
public static func parse_privacyValueDisallowUsers(_ reader: BufferReader) -> PrivacyRule? {
|
||||
var _1: [Int64]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 570911930, elementType: Int64.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.PrivacyRule.privacyValueDisallowUsers(users: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum Reaction: TypeConstructorDescription {
|
||||
case reactionCustomEmoji(documentId: Int64)
|
||||
@ -588,563 +768,3 @@ public extension Api {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum RequestPeerType: TypeConstructorDescription {
|
||||
case requestPeerTypeBroadcast(flags: Int32, hasUsername: Api.Bool?, userAdminRights: Api.ChatAdminRights?, botAdminRights: Api.ChatAdminRights?)
|
||||
case requestPeerTypeChat(flags: Int32, hasUsername: Api.Bool?, forum: Api.Bool?, userAdminRights: Api.ChatAdminRights?, botAdminRights: Api.ChatAdminRights?)
|
||||
case requestPeerTypeUser(flags: Int32, bot: Api.Bool?, premium: Api.Bool?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .requestPeerTypeBroadcast(let flags, let hasUsername, let userAdminRights, let botAdminRights):
|
||||
if boxed {
|
||||
buffer.appendInt32(865857388)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 3) != 0 {hasUsername!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {userAdminRights!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {botAdminRights!.serialize(buffer, true)}
|
||||
break
|
||||
case .requestPeerTypeChat(let flags, let hasUsername, let forum, let userAdminRights, let botAdminRights):
|
||||
if boxed {
|
||||
buffer.appendInt32(-906990053)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 3) != 0 {hasUsername!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {forum!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {userAdminRights!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 2) != 0 {botAdminRights!.serialize(buffer, true)}
|
||||
break
|
||||
case .requestPeerTypeUser(let flags, let bot, let premium):
|
||||
if boxed {
|
||||
buffer.appendInt32(1597737472)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {bot!.serialize(buffer, true)}
|
||||
if Int(flags) & Int(1 << 1) != 0 {premium!.serialize(buffer, true)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .requestPeerTypeBroadcast(let flags, let hasUsername, let userAdminRights, let botAdminRights):
|
||||
return ("requestPeerTypeBroadcast", [("flags", flags as Any), ("hasUsername", hasUsername as Any), ("userAdminRights", userAdminRights as Any), ("botAdminRights", botAdminRights as Any)])
|
||||
case .requestPeerTypeChat(let flags, let hasUsername, let forum, let userAdminRights, let botAdminRights):
|
||||
return ("requestPeerTypeChat", [("flags", flags as Any), ("hasUsername", hasUsername as Any), ("forum", forum as Any), ("userAdminRights", userAdminRights as Any), ("botAdminRights", botAdminRights as Any)])
|
||||
case .requestPeerTypeUser(let flags, let bot, let premium):
|
||||
return ("requestPeerTypeUser", [("flags", flags as Any), ("bot", bot as Any), ("premium", premium as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_requestPeerTypeBroadcast(_ reader: BufferReader) -> RequestPeerType? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Bool?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Bool
|
||||
} }
|
||||
var _3: Api.ChatAdminRights?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
|
||||
} }
|
||||
var _4: Api.ChatAdminRights?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 3) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.RequestPeerType.requestPeerTypeBroadcast(flags: _1!, hasUsername: _2, userAdminRights: _3, botAdminRights: _4)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_requestPeerTypeChat(_ reader: BufferReader) -> RequestPeerType? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Bool?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Bool
|
||||
} }
|
||||
var _3: Api.Bool?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.Bool
|
||||
} }
|
||||
var _4: Api.ChatAdminRights?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_4 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
|
||||
} }
|
||||
var _5: Api.ChatAdminRights?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 3) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 4) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 2) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.RequestPeerType.requestPeerTypeChat(flags: _1!, hasUsername: _2, forum: _3, userAdminRights: _4, botAdminRights: _5)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_requestPeerTypeUser(_ reader: BufferReader) -> RequestPeerType? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Bool?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
|
||||
_2 = Api.parse(reader, signature: signature) as? Api.Bool
|
||||
} }
|
||||
var _3: Api.Bool?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() {
|
||||
_3 = Api.parse(reader, signature: signature) as? Api.Bool
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.RequestPeerType.requestPeerTypeUser(flags: _1!, bot: _2, premium: _3)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum RestrictionReason: TypeConstructorDescription {
|
||||
case restrictionReason(platform: String, reason: String, text: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .restrictionReason(let platform, let reason, let text):
|
||||
if boxed {
|
||||
buffer.appendInt32(-797791052)
|
||||
}
|
||||
serializeString(platform, buffer: buffer, boxed: false)
|
||||
serializeString(reason, buffer: buffer, boxed: false)
|
||||
serializeString(text, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .restrictionReason(let platform, let reason, let text):
|
||||
return ("restrictionReason", [("platform", platform as Any), ("reason", reason as Any), ("text", text as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_restrictionReason(_ reader: BufferReader) -> RestrictionReason? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.RestrictionReason.restrictionReason(platform: _1!, reason: _2!, text: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
indirect enum RichText: TypeConstructorDescription {
|
||||
case textAnchor(text: Api.RichText, name: String)
|
||||
case textBold(text: Api.RichText)
|
||||
case textConcat(texts: [Api.RichText])
|
||||
case textEmail(text: Api.RichText, email: String)
|
||||
case textEmpty
|
||||
case textFixed(text: Api.RichText)
|
||||
case textImage(documentId: Int64, w: Int32, h: Int32)
|
||||
case textItalic(text: Api.RichText)
|
||||
case textMarked(text: Api.RichText)
|
||||
case textPhone(text: Api.RichText, phone: String)
|
||||
case textPlain(text: String)
|
||||
case textStrike(text: Api.RichText)
|
||||
case textSubscript(text: Api.RichText)
|
||||
case textSuperscript(text: Api.RichText)
|
||||
case textUnderline(text: Api.RichText)
|
||||
case textUrl(text: Api.RichText, url: String, webpageId: Int64)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .textAnchor(let text, let name):
|
||||
if boxed {
|
||||
buffer.appendInt32(894777186)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
serializeString(name, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .textBold(let text):
|
||||
if boxed {
|
||||
buffer.appendInt32(1730456516)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
break
|
||||
case .textConcat(let texts):
|
||||
if boxed {
|
||||
buffer.appendInt32(2120376535)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(texts.count))
|
||||
for item in texts {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
case .textEmail(let text, let email):
|
||||
if boxed {
|
||||
buffer.appendInt32(-564523562)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
serializeString(email, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .textEmpty:
|
||||
if boxed {
|
||||
buffer.appendInt32(-599948721)
|
||||
}
|
||||
|
||||
break
|
||||
case .textFixed(let text):
|
||||
if boxed {
|
||||
buffer.appendInt32(1816074681)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
break
|
||||
case .textImage(let documentId, let w, let h):
|
||||
if boxed {
|
||||
buffer.appendInt32(136105807)
|
||||
}
|
||||
serializeInt64(documentId, buffer: buffer, boxed: false)
|
||||
serializeInt32(w, buffer: buffer, boxed: false)
|
||||
serializeInt32(h, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .textItalic(let text):
|
||||
if boxed {
|
||||
buffer.appendInt32(-653089380)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
break
|
||||
case .textMarked(let text):
|
||||
if boxed {
|
||||
buffer.appendInt32(55281185)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
break
|
||||
case .textPhone(let text, let phone):
|
||||
if boxed {
|
||||
buffer.appendInt32(483104362)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
serializeString(phone, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .textPlain(let text):
|
||||
if boxed {
|
||||
buffer.appendInt32(1950782688)
|
||||
}
|
||||
serializeString(text, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .textStrike(let text):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1678197867)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
break
|
||||
case .textSubscript(let text):
|
||||
if boxed {
|
||||
buffer.appendInt32(-311786236)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
break
|
||||
case .textSuperscript(let text):
|
||||
if boxed {
|
||||
buffer.appendInt32(-939827711)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
break
|
||||
case .textUnderline(let text):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1054465340)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
break
|
||||
case .textUrl(let text, let url, let webpageId):
|
||||
if boxed {
|
||||
buffer.appendInt32(1009288385)
|
||||
}
|
||||
text.serialize(buffer, true)
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
serializeInt64(webpageId, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .textAnchor(let text, let name):
|
||||
return ("textAnchor", [("text", text as Any), ("name", name as Any)])
|
||||
case .textBold(let text):
|
||||
return ("textBold", [("text", text as Any)])
|
||||
case .textConcat(let texts):
|
||||
return ("textConcat", [("texts", texts as Any)])
|
||||
case .textEmail(let text, let email):
|
||||
return ("textEmail", [("text", text as Any), ("email", email as Any)])
|
||||
case .textEmpty:
|
||||
return ("textEmpty", [])
|
||||
case .textFixed(let text):
|
||||
return ("textFixed", [("text", text as Any)])
|
||||
case .textImage(let documentId, let w, let h):
|
||||
return ("textImage", [("documentId", documentId as Any), ("w", w as Any), ("h", h as Any)])
|
||||
case .textItalic(let text):
|
||||
return ("textItalic", [("text", text as Any)])
|
||||
case .textMarked(let text):
|
||||
return ("textMarked", [("text", text as Any)])
|
||||
case .textPhone(let text, let phone):
|
||||
return ("textPhone", [("text", text as Any), ("phone", phone as Any)])
|
||||
case .textPlain(let text):
|
||||
return ("textPlain", [("text", text as Any)])
|
||||
case .textStrike(let text):
|
||||
return ("textStrike", [("text", text as Any)])
|
||||
case .textSubscript(let text):
|
||||
return ("textSubscript", [("text", text as Any)])
|
||||
case .textSuperscript(let text):
|
||||
return ("textSuperscript", [("text", text as Any)])
|
||||
case .textUnderline(let text):
|
||||
return ("textUnderline", [("text", text as Any)])
|
||||
case .textUrl(let text, let url, let webpageId):
|
||||
return ("textUrl", [("text", text as Any), ("url", url as Any), ("webpageId", webpageId as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_textAnchor(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.RichText.textAnchor(text: _1!, name: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textBold(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.RichText.textBold(text: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textConcat(_ reader: BufferReader) -> RichText? {
|
||||
var _1: [Api.RichText]?
|
||||
if let _ = reader.readInt32() {
|
||||
_1 = Api.parseVector(reader, elementSignature: 0, elementType: Api.RichText.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.RichText.textConcat(texts: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textEmail(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.RichText.textEmail(text: _1!, email: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textEmpty(_ reader: BufferReader) -> RichText? {
|
||||
return Api.RichText.textEmpty
|
||||
}
|
||||
public static func parse_textFixed(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.RichText.textFixed(text: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textImage(_ reader: BufferReader) -> RichText? {
|
||||
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.RichText.textImage(documentId: _1!, w: _2!, h: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textItalic(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.RichText.textItalic(text: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textMarked(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.RichText.textMarked(text: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textPhone(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.RichText.textPhone(text: _1!, phone: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textPlain(_ reader: BufferReader) -> RichText? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.RichText.textPlain(text: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textStrike(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.RichText.textStrike(text: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textSubscript(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.RichText.textSubscript(text: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textSuperscript(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.RichText.textSuperscript(text: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textUnderline(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.RichText.textUnderline(text: _1!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_textUrl(_ reader: BufferReader) -> RichText? {
|
||||
var _1: Api.RichText?
|
||||
if let signature = reader.readInt32() {
|
||||
_1 = Api.parse(reader, signature: signature) as? Api.RichText
|
||||
}
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: Int64?
|
||||
_3 = reader.readInt64()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.RichText.textUrl(text: _1!, url: _2!, webpageId: _3!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
9467
submodules/TelegramApi/Sources/Api32.swift
Normal file
9467
submodules/TelegramApi/Sources/Api32.swift
Normal file
File diff suppressed because it is too large
Load Diff
@ -47,15 +47,15 @@ public struct MessageStatsContextState: Equatable {
|
||||
public var stats: MessageStats?
|
||||
}
|
||||
|
||||
private func requestMessageStats(postbox: Postbox, network: Network, datacenterId: Int32, messageId: MessageId, dark: Bool = false) -> Signal<MessageStats?, NoError> {
|
||||
return postbox.transaction { transaction -> (Peer, Message)? in
|
||||
if let peer = transaction.getPeer(messageId.peerId), let message = transaction.getMessage(messageId) {
|
||||
return (peer, message)
|
||||
private func requestMessageStats(postbox: Postbox, network: Network, messageId: MessageId, dark: Bool = false) -> Signal<MessageStats?, NoError> {
|
||||
return postbox.transaction { transaction -> (Int32, Peer, Message)? in
|
||||
if let peer = transaction.getPeer(messageId.peerId), let message = transaction.getMessage(messageId), let cachedData = transaction.getPeerCachedData(peerId: messageId.peerId) as? CachedChannelData {
|
||||
return (cachedData.statsDatacenterId, peer, message)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
} |> mapToSignal { peerAndMessage -> Signal<MessageStats?, NoError> in
|
||||
guard let (peer, message) = peerAndMessage, let inputChannel = apiInputChannel(peer) else {
|
||||
} |> mapToSignal { data -> Signal<MessageStats?, NoError> in
|
||||
guard let (datacenterId, peer, message) = data, let inputChannel = apiInputChannel(peer) else {
|
||||
return .never()
|
||||
}
|
||||
|
||||
@ -125,7 +125,6 @@ private func requestMessageStats(postbox: Postbox, network: Network, datacenterI
|
||||
private final class MessageStatsContextImpl {
|
||||
private let postbox: Postbox
|
||||
private let network: Network
|
||||
private let datacenterId: Int32
|
||||
private let messageId: MessageId
|
||||
|
||||
private var _state: MessageStatsContextState {
|
||||
@ -143,12 +142,11 @@ private final class MessageStatsContextImpl {
|
||||
private let disposable = MetaDisposable()
|
||||
private let disposables = DisposableDict<String>()
|
||||
|
||||
init(postbox: Postbox, network: Network, datacenterId: Int32, messageId: MessageId) {
|
||||
init(postbox: Postbox, network: Network, messageId: MessageId) {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
self.postbox = postbox
|
||||
self.network = network
|
||||
self.datacenterId = datacenterId
|
||||
self.messageId = messageId
|
||||
self._state = MessageStatsContextState(stats: nil)
|
||||
self._statePromise.set(.single(self._state))
|
||||
@ -165,7 +163,7 @@ private final class MessageStatsContextImpl {
|
||||
private func load() {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
self.disposable.set((requestMessageStats(postbox: self.postbox, network: self.network, datacenterId: self.datacenterId, messageId: self.messageId)
|
||||
self.disposable.set((requestMessageStats(postbox: self.postbox, network: self.network, messageId: self.messageId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] stats in
|
||||
if let strongSelf = self {
|
||||
strongSelf._state = MessageStatsContextState(stats: stats)
|
||||
@ -176,7 +174,7 @@ private final class MessageStatsContextImpl {
|
||||
|
||||
func loadDetailedGraph(_ graph: StatsGraph, x: Int64) -> Signal<StatsGraph?, NoError> {
|
||||
if let token = graph.token {
|
||||
return requestGraph(network: self.network, datacenterId: self.datacenterId, token: token, x: x)
|
||||
return requestGraph(postbox: self.postbox, network: self.network, peerId: self.messageId.peerId, token: token, x: x)
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
@ -198,9 +196,9 @@ public final class MessageStatsContext {
|
||||
}
|
||||
}
|
||||
|
||||
public init(postbox: Postbox, network: Network, datacenterId: Int32, messageId: MessageId) {
|
||||
public init(postbox: Postbox, network: Network, messageId: MessageId) {
|
||||
self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: {
|
||||
return MessageStatsContextImpl(postbox: postbox, network: network, datacenterId: datacenterId, messageId: messageId)
|
||||
return MessageStatsContextImpl(postbox: postbox, network: network, messageId: messageId)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -48,25 +48,34 @@ public enum StatsGraph: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public struct ChannelStatsMessageInteractions: Equatable {
|
||||
public let messageId: MessageId
|
||||
public struct ChannelStatsPostInteractions: Equatable {
|
||||
public enum PostId: Hashable {
|
||||
case message(id: EngineMessage.Id)
|
||||
case story(peerId: EnginePeer.Id, id: Int32)
|
||||
}
|
||||
|
||||
public let postId: PostId
|
||||
public let views: Int32
|
||||
public let forwards: Int32
|
||||
public let reactions: Int32
|
||||
|
||||
public init(messageId: MessageId, views: Int32, forwards: Int32, reactions: Int32) {
|
||||
self.messageId = messageId
|
||||
public init(postId: PostId, views: Int32, forwards: Int32, reactions: Int32) {
|
||||
self.postId = postId
|
||||
self.views = views
|
||||
self.forwards = forwards
|
||||
self.reactions = reactions
|
||||
}
|
||||
}
|
||||
|
||||
public final class ChannelStats: Equatable {
|
||||
public struct ChannelStats: Equatable {
|
||||
public let period: StatsDateRange
|
||||
public let followers: StatsValue
|
||||
public let viewsPerPost: StatsValue
|
||||
public let sharesPerPost: StatsValue
|
||||
public let reactionsPerPost: StatsValue
|
||||
public let viewsPerStory: StatsValue
|
||||
public let sharesPerStory: StatsValue
|
||||
public let reactionsPerStory: StatsValue
|
||||
public let enabledNotifications: StatsPercentValue
|
||||
public let growthGraph: StatsGraph
|
||||
public let followersGraph: StatsGraph
|
||||
@ -80,13 +89,17 @@ public final class ChannelStats: Equatable {
|
||||
public let reactionsByEmotionGraph: StatsGraph
|
||||
public let storyInteractionsGraph: StatsGraph
|
||||
public let storyReactionsByEmotionGraph: StatsGraph
|
||||
public let messageInteractions: [ChannelStatsMessageInteractions]
|
||||
public let postInteractions: [ChannelStatsPostInteractions]
|
||||
|
||||
init(
|
||||
period: StatsDateRange,
|
||||
followers: StatsValue,
|
||||
viewsPerPost: StatsValue,
|
||||
sharesPerPost: StatsValue,
|
||||
reactionsPerPost: StatsValue,
|
||||
viewsPerStory: StatsValue,
|
||||
sharesPerStory: StatsValue,
|
||||
reactionsPerStory: StatsValue,
|
||||
enabledNotifications: StatsPercentValue,
|
||||
growthGraph: StatsGraph,
|
||||
followersGraph: StatsGraph,
|
||||
@ -100,12 +113,16 @@ public final class ChannelStats: Equatable {
|
||||
reactionsByEmotionGraph: StatsGraph,
|
||||
storyInteractionsGraph: StatsGraph,
|
||||
storyReactionsByEmotionGraph: StatsGraph,
|
||||
messageInteractions: [ChannelStatsMessageInteractions]
|
||||
postInteractions: [ChannelStatsPostInteractions]
|
||||
) {
|
||||
self.period = period
|
||||
self.followers = followers
|
||||
self.viewsPerPost = viewsPerPost
|
||||
self.sharesPerPost = sharesPerPost
|
||||
self.reactionsPerPost = reactionsPerPost
|
||||
self.viewsPerStory = viewsPerStory
|
||||
self.sharesPerStory = sharesPerStory
|
||||
self.reactionsPerStory = reactionsPerStory
|
||||
self.enabledNotifications = enabledNotifications
|
||||
self.growthGraph = growthGraph
|
||||
self.followersGraph = followersGraph
|
||||
@ -119,7 +136,7 @@ public final class ChannelStats: Equatable {
|
||||
self.reactionsByEmotionGraph = reactionsByEmotionGraph
|
||||
self.storyInteractionsGraph = storyInteractionsGraph
|
||||
self.storyReactionsByEmotionGraph = storyReactionsByEmotionGraph
|
||||
self.messageInteractions = messageInteractions
|
||||
self.postInteractions = postInteractions
|
||||
}
|
||||
|
||||
public static func == (lhs: ChannelStats, rhs: ChannelStats) -> Bool {
|
||||
@ -174,56 +191,56 @@ public final class ChannelStats: Equatable {
|
||||
if lhs.storyReactionsByEmotionGraph != rhs.storyReactionsByEmotionGraph {
|
||||
return false
|
||||
}
|
||||
if lhs.messageInteractions != rhs.messageInteractions {
|
||||
if lhs.postInteractions != rhs.postInteractions {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public func withUpdatedGrowthGraph(_ growthGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
|
||||
public func withUpdatedFollowersGraph(_ followersGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
|
||||
public func withUpdatedMuteGraph(_ muteGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
|
||||
public func withUpdatedTopHoursGraph(_ viewsByHourGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: viewsByHourGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: viewsByHourGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
|
||||
public func withUpdatedInteractionsGraph(_ interactionsGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
|
||||
public func withUpdatedInstantPageInteractionsGraph(_ instantPageInteractionsGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
|
||||
public func withUpdatedViewsBySourceGraph(_ viewsBySourceGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
|
||||
public func withUpdatedNewFollowersBySourceGraph(_ newFollowersBySourceGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
|
||||
public func withUpdatedLanguagesGraph(_ languagesGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
|
||||
public func withUpdatedReactionsByEmotionGraph(_ reactionsByEmotionGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
public func withUpdatedStoryInteractionsGraph(_ storyInteractionsGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: storyInteractionsGraph, storyReactionsByEmotionGraph: self.storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
public func withUpdatedStoryReactionsByEmotionGraph(_ storyReactionsByEmotionGraph: StatsGraph) -> ChannelStats {
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: storyReactionsByEmotionGraph, messageInteractions: self.messageInteractions)
|
||||
return ChannelStats(period: self.period, followers: self.followers, viewsPerPost: self.viewsPerPost, sharesPerPost: self.sharesPerPost, reactionsPerPost: self.reactionsPerPost, viewsPerStory: self.viewsPerStory, sharesPerStory: self.sharesPerStory, reactionsPerStory: self.reactionsPerStory, enabledNotifications: self.enabledNotifications, growthGraph: self.growthGraph, followersGraph: self.followersGraph, muteGraph: self.muteGraph, topHoursGraph: self.topHoursGraph, interactionsGraph: self.interactionsGraph, instantPageInteractionsGraph: self.instantPageInteractionsGraph, viewsBySourceGraph: self.viewsBySourceGraph, newFollowersBySourceGraph: self.newFollowersBySourceGraph, languagesGraph: self.languagesGraph, reactionsByEmotionGraph: self.reactionsByEmotionGraph, storyInteractionsGraph: self.storyInteractionsGraph, storyReactionsByEmotionGraph: storyReactionsByEmotionGraph, postInteractions: self.postInteractions)
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,11 +248,14 @@ public struct ChannelStatsContextState: Equatable {
|
||||
public var stats: ChannelStats?
|
||||
}
|
||||
|
||||
private func requestChannelStats(postbox: Postbox, network: Network, datacenterId: Int32, peerId: PeerId, dark: Bool = false) -> Signal<ChannelStats?, NoError> {
|
||||
return postbox.transaction { transaction -> Peer? in
|
||||
return transaction.getPeer(peerId)
|
||||
} |> mapToSignal { peer -> Signal<ChannelStats?, NoError> in
|
||||
guard let peer = peer, let inputChannel = apiInputChannel(peer) else {
|
||||
private func requestChannelStats(postbox: Postbox, network: Network, peerId: PeerId, dark: Bool = false) -> Signal<ChannelStats?, NoError> {
|
||||
return postbox.transaction { transaction -> (Int32, Peer)? in
|
||||
if let peer = transaction.getPeer(peerId), let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData {
|
||||
return (cachedData.statsDatacenterId, peer)
|
||||
}
|
||||
return nil
|
||||
} |> mapToSignal { data -> Signal<ChannelStats?, NoError> in
|
||||
guard let (statsDatacenterId, peer) = data, let inputChannel = apiInputChannel(peer) else {
|
||||
return .never()
|
||||
}
|
||||
|
||||
@ -246,8 +266,8 @@ private func requestChannelStats(postbox: Postbox, network: Network, datacenterI
|
||||
|
||||
let request = Api.functions.stats.getBroadcastStats(flags: flags, channel: inputChannel)
|
||||
let signal: Signal<Api.stats.BroadcastStats, MTRpcError>
|
||||
if network.datacenterId != datacenterId {
|
||||
signal = network.download(datacenterId: Int(datacenterId), isMedia: false, tag: nil)
|
||||
if network.datacenterId != statsDatacenterId {
|
||||
signal = network.download(datacenterId: Int(statsDatacenterId), isMedia: false, tag: nil)
|
||||
|> castError(MTRpcError.self)
|
||||
|> mapToSignal { worker in
|
||||
return worker.request(request)
|
||||
@ -264,20 +284,33 @@ private func requestChannelStats(postbox: Postbox, network: Network, datacenterI
|
||||
}
|
||||
}
|
||||
|
||||
func requestGraph(network: Network, datacenterId: Int32, token: String, x: Int64? = nil) -> Signal<StatsGraph?, NoError> {
|
||||
func requestGraph(postbox: Postbox, network: Network, peerId: EnginePeer.Id, token: String, x: Int64? = nil) -> Signal<StatsGraph?, NoError> {
|
||||
var flags: Int32 = 0
|
||||
if let _ = x {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
let signal: Signal<Api.StatsGraph, MTRpcError>
|
||||
if network.datacenterId != datacenterId {
|
||||
signal = network.download(datacenterId: Int(datacenterId), isMedia: false, tag: nil)
|
||||
signal = postbox.transaction { transaction -> Int32? in
|
||||
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData {
|
||||
return cachedData.statsDatacenterId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|> castError(MTRpcError.self)
|
||||
|> mapToSignal { statsDatacenterId in
|
||||
if let statsDatacenterId = statsDatacenterId {
|
||||
if network.datacenterId != statsDatacenterId {
|
||||
return network.download(datacenterId: Int(statsDatacenterId), isMedia: false, tag: nil)
|
||||
|> castError(MTRpcError.self)
|
||||
|> mapToSignal { worker in
|
||||
return worker.request(Api.functions.stats.loadAsyncGraph(flags: flags, token: token, x: x))
|
||||
}
|
||||
} else {
|
||||
signal = network.request(Api.functions.stats.loadAsyncGraph(flags: flags, token: token, x: x))
|
||||
return network.request(Api.functions.stats.loadAsyncGraph(flags: flags, token: token, x: x))
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
|
||||
return signal
|
||||
@ -292,7 +325,6 @@ func requestGraph(network: Network, datacenterId: Int32, token: String, x: Int64
|
||||
private final class ChannelStatsContextImpl {
|
||||
private let postbox: Postbox
|
||||
private let network: Network
|
||||
private let datacenterId: Int32
|
||||
private let peerId: PeerId
|
||||
|
||||
private var _state: ChannelStatsContextState {
|
||||
@ -310,12 +342,11 @@ private final class ChannelStatsContextImpl {
|
||||
private let disposable = MetaDisposable()
|
||||
private let disposables = DisposableDict<String>()
|
||||
|
||||
init(postbox: Postbox, network: Network, datacenterId: Int32, peerId: PeerId) {
|
||||
init(postbox: Postbox, network: Network, peerId: PeerId) {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
self.postbox = postbox
|
||||
self.network = network
|
||||
self.datacenterId = datacenterId
|
||||
self.peerId = peerId
|
||||
self._state = ChannelStatsContextState(stats: nil)
|
||||
self._statePromise.set(.single(self._state))
|
||||
@ -332,7 +363,7 @@ private final class ChannelStatsContextImpl {
|
||||
private func load() {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
self.disposable.set((requestChannelStats(postbox: self.postbox, network: self.network, datacenterId: self.datacenterId, peerId: self.peerId)
|
||||
self.disposable.set((requestChannelStats(postbox: self.postbox, network: self.network, peerId: self.peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] stats in
|
||||
if let strongSelf = self {
|
||||
strongSelf._state = ChannelStatsContextState(stats: stats)
|
||||
@ -346,7 +377,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.growthGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedGrowthGraph(graph))
|
||||
@ -361,7 +392,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.followersGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedFollowersGraph(graph))
|
||||
@ -376,7 +407,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.muteGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedMuteGraph(graph))
|
||||
@ -391,7 +422,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.topHoursGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedTopHoursGraph(graph))
|
||||
@ -406,7 +437,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.interactionsGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedInteractionsGraph(graph))
|
||||
@ -421,7 +452,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.instantPageInteractionsGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedInstantPageInteractionsGraph(graph))
|
||||
@ -436,7 +467,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.viewsBySourceGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedViewsBySourceGraph(graph))
|
||||
@ -451,7 +482,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.newFollowersBySourceGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedNewFollowersBySourceGraph(graph))
|
||||
@ -466,7 +497,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.languagesGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedLanguagesGraph(graph))
|
||||
@ -481,7 +512,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.reactionsByEmotionGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedReactionsByEmotionGraph(graph))
|
||||
@ -496,7 +527,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.storyInteractionsGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedStoryInteractionsGraph(graph))
|
||||
@ -511,7 +542,7 @@ private final class ChannelStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.storyReactionsByEmotionGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = ChannelStatsContextState(stats: strongSelf._state.stats?.withUpdatedStoryReactionsByEmotionGraph(graph))
|
||||
@ -523,7 +554,7 @@ private final class ChannelStatsContextImpl {
|
||||
|
||||
func loadDetailedGraph(_ graph: StatsGraph, x: Int64) -> Signal<StatsGraph?, NoError> {
|
||||
if let token = graph.token {
|
||||
return requestGraph(network: self.network, datacenterId: self.datacenterId, token: token, x: x)
|
||||
return requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token, x: x)
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
@ -545,9 +576,9 @@ public final class ChannelStatsContext {
|
||||
}
|
||||
}
|
||||
|
||||
public init(postbox: Postbox, network: Network, datacenterId: Int32, peerId: PeerId) {
|
||||
public init(postbox: Postbox, network: Network, peerId: PeerId) {
|
||||
self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: {
|
||||
return ChannelStatsContextImpl(postbox: postbox, network: network, datacenterId: datacenterId, peerId: peerId)
|
||||
return ChannelStatsContextImpl(postbox: postbox, network: network, peerId: peerId)
|
||||
})
|
||||
}
|
||||
|
||||
@ -652,7 +683,7 @@ public struct GroupStatsTopInviter: Equatable {
|
||||
public let inviteCount: Int32
|
||||
}
|
||||
|
||||
public final class GroupStats: Equatable {
|
||||
public struct GroupStats: Equatable {
|
||||
public let period: StatsDateRange
|
||||
public let members: StatsValue
|
||||
public let messages: StatsValue
|
||||
@ -689,58 +720,6 @@ public final class GroupStats: Equatable {
|
||||
self.topInviters = topInviters
|
||||
}
|
||||
|
||||
public static func == (lhs: GroupStats, rhs: GroupStats) -> Bool {
|
||||
if lhs.period != rhs.period {
|
||||
return false
|
||||
}
|
||||
if lhs.members != rhs.members {
|
||||
return false
|
||||
}
|
||||
if lhs.messages != rhs.messages {
|
||||
return false
|
||||
}
|
||||
if lhs.viewers != rhs.viewers {
|
||||
return false
|
||||
}
|
||||
if lhs.posters != rhs.posters {
|
||||
return false
|
||||
}
|
||||
if lhs.growthGraph != rhs.growthGraph {
|
||||
return false
|
||||
}
|
||||
if lhs.membersGraph != rhs.membersGraph {
|
||||
return false
|
||||
}
|
||||
if lhs.newMembersBySourceGraph != rhs.newMembersBySourceGraph {
|
||||
return false
|
||||
}
|
||||
if lhs.languagesGraph != rhs.languagesGraph {
|
||||
return false
|
||||
}
|
||||
if lhs.messagesGraph != rhs.messagesGraph {
|
||||
return false
|
||||
}
|
||||
if lhs.actionsGraph != rhs.actionsGraph {
|
||||
return false
|
||||
}
|
||||
if lhs.topHoursGraph != rhs.topHoursGraph {
|
||||
return false
|
||||
}
|
||||
if lhs.topWeekdaysGraph != rhs.topWeekdaysGraph {
|
||||
return false
|
||||
}
|
||||
if lhs.topPosters != rhs.topPosters {
|
||||
return false
|
||||
}
|
||||
if lhs.topAdmins != rhs.topAdmins {
|
||||
return false
|
||||
}
|
||||
if lhs.topInviters != rhs.topInviters {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public func withUpdatedGrowthGraph(_ growthGraph: StatsGraph) -> GroupStats {
|
||||
return GroupStats(period: self.period, members: self.members, messages: self.messages, viewers: self.viewers, posters: self.posters, growthGraph: growthGraph, membersGraph: self.membersGraph, newMembersBySourceGraph: self.newMembersBySourceGraph, languagesGraph: self.languagesGraph, messagesGraph: self.messagesGraph, actionsGraph: self.actionsGraph, topHoursGraph: self.topHoursGraph, topWeekdaysGraph: self.topWeekdaysGraph, topPosters: self.topPosters, topAdmins: self.topAdmins, topInviters: self.topInviters)
|
||||
}
|
||||
@ -778,11 +757,14 @@ public struct GroupStatsContextState: Equatable {
|
||||
public var stats: GroupStats?
|
||||
}
|
||||
|
||||
private func requestGroupStats(accountPeerId: PeerId, postbox: Postbox, network: Network, datacenterId: Int32, peerId: PeerId, dark: Bool = false) -> Signal<GroupStats?, NoError> {
|
||||
return postbox.transaction { transaction -> Peer? in
|
||||
return transaction.getPeer(peerId)
|
||||
} |> mapToSignal { peer -> Signal<GroupStats?, NoError> in
|
||||
guard let peer = peer, let inputChannel = apiInputChannel(peer) else {
|
||||
private func requestGroupStats(accountPeerId: PeerId, postbox: Postbox, network: Network, peerId: PeerId, dark: Bool = false) -> Signal<GroupStats?, NoError> {
|
||||
return postbox.transaction { transaction -> (Int32, Peer)? in
|
||||
if let peer = transaction.getPeer(peerId), let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData {
|
||||
return (cachedData.statsDatacenterId, peer)
|
||||
}
|
||||
return nil
|
||||
} |> mapToSignal { data -> Signal<GroupStats?, NoError> in
|
||||
guard let (statsDatacenterId, peer) = data, let inputChannel = apiInputChannel(peer) else {
|
||||
return .never()
|
||||
}
|
||||
|
||||
@ -792,8 +774,8 @@ private func requestGroupStats(accountPeerId: PeerId, postbox: Postbox, network:
|
||||
}
|
||||
|
||||
let signal: Signal<Api.stats.MegagroupStats, MTRpcError>
|
||||
if network.datacenterId != datacenterId {
|
||||
signal = network.download(datacenterId: Int(datacenterId), isMedia: false, tag: nil)
|
||||
if network.datacenterId != statsDatacenterId {
|
||||
signal = network.download(datacenterId: Int(statsDatacenterId), isMedia: false, tag: nil)
|
||||
|> castError(MTRpcError.self)
|
||||
|> mapToSignal { worker in
|
||||
return worker.request(Api.functions.stats.getMegagroupStats(flags: flags, channel: inputChannel))
|
||||
@ -820,7 +802,6 @@ private final class GroupStatsContextImpl {
|
||||
private let postbox: Postbox
|
||||
private let network: Network
|
||||
private let accountPeerId: PeerId
|
||||
private let datacenterId: Int32
|
||||
private let peerId: PeerId
|
||||
|
||||
private var _state: GroupStatsContextState {
|
||||
@ -838,13 +819,12 @@ private final class GroupStatsContextImpl {
|
||||
private let disposable = MetaDisposable()
|
||||
private let disposables = DisposableDict<String>()
|
||||
|
||||
init(postbox: Postbox, network: Network, accountPeerId: PeerId, datacenterId: Int32, peerId: PeerId) {
|
||||
init(postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId) {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
self.postbox = postbox
|
||||
self.network = network
|
||||
self.accountPeerId = accountPeerId
|
||||
self.datacenterId = datacenterId
|
||||
self.peerId = peerId
|
||||
self._state = GroupStatsContextState(stats: nil)
|
||||
self._statePromise.set(.single(self._state))
|
||||
@ -861,7 +841,7 @@ private final class GroupStatsContextImpl {
|
||||
private func load() {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
self.disposable.set((requestGroupStats(accountPeerId: self.accountPeerId, postbox: self.postbox, network: self.network, datacenterId: self.datacenterId, peerId: self.peerId)
|
||||
self.disposable.set((requestGroupStats(accountPeerId: self.accountPeerId, postbox: self.postbox, network: self.network, peerId: self.peerId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] stats in
|
||||
if let strongSelf = self {
|
||||
strongSelf._state = GroupStatsContextState(stats: stats)
|
||||
@ -875,7 +855,7 @@ private final class GroupStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.growthGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = GroupStatsContextState(stats: strongSelf._state.stats?.withUpdatedGrowthGraph(graph))
|
||||
@ -890,7 +870,7 @@ private final class GroupStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.membersGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = GroupStatsContextState(stats: strongSelf._state.stats?.withUpdatedMembersGraph(graph))
|
||||
@ -905,7 +885,7 @@ private final class GroupStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.newMembersBySourceGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = GroupStatsContextState(stats: strongSelf._state.stats?.withUpdatedNewMembersBySourceGraph(graph))
|
||||
@ -920,7 +900,7 @@ private final class GroupStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.languagesGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = GroupStatsContextState(stats: strongSelf._state.stats?.withUpdatedLanguagesGraph(graph))
|
||||
@ -935,7 +915,7 @@ private final class GroupStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.messagesGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = GroupStatsContextState(stats: strongSelf._state.stats?.withUpdatedMessagesGraph(graph))
|
||||
@ -950,7 +930,7 @@ private final class GroupStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.actionsGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = GroupStatsContextState(stats: strongSelf._state.stats?.withUpdatedActionsGraph(graph))
|
||||
@ -965,7 +945,7 @@ private final class GroupStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.topHoursGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = GroupStatsContextState(stats: strongSelf._state.stats?.withUpdatedTopHoursGraph(graph))
|
||||
@ -980,7 +960,7 @@ private final class GroupStatsContextImpl {
|
||||
return
|
||||
}
|
||||
if case let .OnDemand(token) = stats.topWeekdaysGraph {
|
||||
self.disposables.set((requestGraph(network: self.network, datacenterId: self.datacenterId, token: token)
|
||||
self.disposables.set((requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] graph in
|
||||
if let strongSelf = self, let graph = graph {
|
||||
strongSelf._state = GroupStatsContextState(stats: strongSelf._state.stats?.withUpdatedTopWeekdaysGraph(graph))
|
||||
@ -992,7 +972,7 @@ private final class GroupStatsContextImpl {
|
||||
|
||||
func loadDetailedGraph(_ graph: StatsGraph, x: Int64) -> Signal<StatsGraph?, NoError> {
|
||||
if let token = graph.token {
|
||||
return requestGraph(network: self.network, datacenterId: self.datacenterId, token: token, x: x)
|
||||
return requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token, x: x)
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
@ -1014,9 +994,9 @@ public final class GroupStatsContext {
|
||||
}
|
||||
}
|
||||
|
||||
public init(postbox: Postbox, network: Network, accountPeerId: PeerId, datacenterId: Int32, peerId: PeerId) {
|
||||
public init(postbox: Postbox, network: Network, accountPeerId: PeerId, peerId: PeerId) {
|
||||
self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: {
|
||||
return GroupStatsContextImpl(postbox: postbox, network: network, accountPeerId: accountPeerId, datacenterId: datacenterId, peerId: peerId)
|
||||
return GroupStatsContextImpl(postbox: postbox, network: network, accountPeerId: accountPeerId, peerId: peerId)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1147,19 +1127,21 @@ extension StatsPercentValue {
|
||||
}
|
||||
}
|
||||
|
||||
extension ChannelStatsMessageInteractions {
|
||||
init(apiMessageInteractionCounters: Api.MessageInteractionCounters, peerId: PeerId) {
|
||||
switch apiMessageInteractionCounters {
|
||||
case let .messageInteractionCounters(msgId, views, forwards):
|
||||
self = ChannelStatsMessageInteractions(messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: msgId), views: views, forwards: forwards, reactions: 0)
|
||||
extension ChannelStatsPostInteractions {
|
||||
init(apiPostInteractionCounters: Api.PostInteractionCounters, peerId: PeerId) {
|
||||
switch apiPostInteractionCounters {
|
||||
case let .postInteractionCountersMessage(msgId, views, forwards, reactions):
|
||||
self = ChannelStatsPostInteractions(postId: .message(id: EngineMessage.Id(peerId: peerId, namespace: Namespaces.Message.Cloud, id: msgId)), views: views, forwards: forwards, reactions: reactions)
|
||||
case let .postInteractionCountersStory(storyId, views, forwards, reactions):
|
||||
self = ChannelStatsPostInteractions(postId: .story(peerId: peerId, id: storyId), views: views, forwards: forwards, reactions: reactions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ChannelStats {
|
||||
convenience init(apiBroadcastStats: Api.stats.BroadcastStats, peerId: PeerId) {
|
||||
init(apiBroadcastStats: Api.stats.BroadcastStats, peerId: PeerId) {
|
||||
switch apiBroadcastStats {
|
||||
case let .broadcastStats(period, followers, viewsPerPost, sharesPerPost, enabledNotifications, apiGrowthGraph, apiFollowersGraph, apiMuteGraph, apiTopHoursGraph, apiInteractionsGraph, apiInstantViewInteractionsGraph, apiViewsBySourceGraph, apiNewFollowersBySourceGraph, apiLanguagesGraph, apiReactionsByEmotionGraph, apiStoryInteractionsGraph, apiStoryReactionsByEmotionGraph, recentMessageInteractions):
|
||||
case let .broadcastStats(period, followers, viewsPerPost, sharesPerPost, reactionsPerPost, viewsPerStory, sharesPerStory, reactionsPerStory, enabledNotifications, apiGrowthGraph, apiFollowersGraph, apiMuteGraph, apiTopHoursGraph, apiInteractionsGraph, apiInstantViewInteractionsGraph, apiViewsBySourceGraph, apiNewFollowersBySourceGraph, apiLanguagesGraph, apiReactionsByEmotionGraph, apiStoryInteractionsGraph, apiStoryReactionsByEmotionGraph, recentPostInteractions):
|
||||
let growthGraph = StatsGraph(apiStatsGraph: apiGrowthGraph)
|
||||
let isEmpty = growthGraph.isEmpty
|
||||
|
||||
@ -1168,6 +1150,10 @@ extension ChannelStats {
|
||||
followers: StatsValue(apiStatsAbsValueAndPrev: followers),
|
||||
viewsPerPost: StatsValue(apiStatsAbsValueAndPrev: viewsPerPost),
|
||||
sharesPerPost: StatsValue(apiStatsAbsValueAndPrev: sharesPerPost),
|
||||
reactionsPerPost: StatsValue(apiStatsAbsValueAndPrev: reactionsPerPost),
|
||||
viewsPerStory: StatsValue(apiStatsAbsValueAndPrev: viewsPerStory),
|
||||
sharesPerStory: StatsValue(apiStatsAbsValueAndPrev: sharesPerStory),
|
||||
reactionsPerStory: StatsValue(apiStatsAbsValueAndPrev: reactionsPerStory),
|
||||
enabledNotifications: StatsPercentValue(apiPercentValue: enabledNotifications),
|
||||
growthGraph: growthGraph,
|
||||
followersGraph: StatsGraph(apiStatsGraph: apiFollowersGraph),
|
||||
@ -1181,7 +1167,7 @@ extension ChannelStats {
|
||||
reactionsByEmotionGraph: isEmpty ? .Empty : StatsGraph(apiStatsGraph: apiReactionsByEmotionGraph),
|
||||
storyInteractionsGraph: isEmpty ? .Empty : StatsGraph(apiStatsGraph: apiStoryInteractionsGraph),
|
||||
storyReactionsByEmotionGraph: isEmpty ? .Empty : StatsGraph(apiStatsGraph: apiStoryReactionsByEmotionGraph),
|
||||
messageInteractions: recentMessageInteractions.map { ChannelStatsMessageInteractions(apiMessageInteractionCounters: $0, peerId: peerId) })
|
||||
postInteractions: recentPostInteractions.map { ChannelStatsPostInteractions(apiPostInteractionCounters: $0, peerId: peerId) })
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1214,7 +1200,7 @@ extension GroupStatsTopInviter {
|
||||
}
|
||||
|
||||
extension GroupStats {
|
||||
convenience init(apiMegagroupStats: Api.stats.MegagroupStats) {
|
||||
init(apiMegagroupStats: Api.stats.MegagroupStats) {
|
||||
switch apiMegagroupStats {
|
||||
case let .megagroupStats(period, members, messages, viewers, posters, apiGrowthGraph, apiMembersGraph, apiNewMembersBySourceGraph, apiLanguagesGraph, apiMessagesGraph, apiActionsGraph, apiTopHoursGraph, apiTopWeekdaysGraph, topPosters, topAdmins, topInviters, _):
|
||||
let growthGraph = StatsGraph(apiStatsGraph: apiGrowthGraph)
|
||||
|
@ -47,15 +47,15 @@ public struct StoryStatsContextState: Equatable {
|
||||
public var stats: StoryStats?
|
||||
}
|
||||
|
||||
private func requestStoryStats(postbox: Postbox, network: Network, datacenterId: Int32, peerId: EnginePeer.Id, storyId: Int32, dark: Bool = false) -> Signal<StoryStats?, NoError> {
|
||||
return postbox.transaction { transaction -> Peer? in
|
||||
if let peer = transaction.getPeer(peerId) {
|
||||
return peer
|
||||
private func requestStoryStats(postbox: Postbox, network: Network, peerId: EnginePeer.Id, storyId: Int32, dark: Bool = false) -> Signal<StoryStats?, NoError> {
|
||||
return postbox.transaction { transaction -> (Int32, Peer, Stories.Item)? in
|
||||
if let peer = transaction.getPeer(peerId), let storedItem = transaction.getStory(id: StoryId(peerId: peerId, id: storyId))?.get(Stories.StoredItem.self), case let .item(story) = storedItem, let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData {
|
||||
return (cachedData.statsDatacenterId, peer, story)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
} |> mapToSignal { peer -> Signal<StoryStats?, NoError> in
|
||||
guard let peer = peer, let inputPeer = apiInputPeer(peer) else {
|
||||
} |> mapToSignal { data -> Signal<StoryStats?, NoError> in
|
||||
guard let (statsDatacenterId, peer, story) = data, let inputPeer = apiInputPeer(peer) else {
|
||||
return .never()
|
||||
}
|
||||
|
||||
@ -66,8 +66,8 @@ private func requestStoryStats(postbox: Postbox, network: Network, datacenterId:
|
||||
|
||||
let request = Api.functions.stats.getStoryStats(flags: flags, peer: inputPeer, id: storyId)
|
||||
let signal: Signal<Api.stats.StoryStats, MTRpcError>
|
||||
if network.datacenterId != datacenterId {
|
||||
signal = network.download(datacenterId: Int(datacenterId), isMedia: false, tag: nil)
|
||||
if network.datacenterId != statsDatacenterId {
|
||||
signal = network.download(datacenterId: Int(statsDatacenterId), isMedia: false, tag: nil)
|
||||
|> castError(MTRpcError.self)
|
||||
|> mapToSignal { worker in
|
||||
return worker.request(request)
|
||||
@ -76,15 +76,12 @@ private func requestStoryStats(postbox: Postbox, network: Network, datacenterId:
|
||||
signal = network.request(request)
|
||||
}
|
||||
|
||||
let views: Int = 0
|
||||
let forwards: Int = 0
|
||||
// for attribute in story.attributes {
|
||||
// if let viewsAttribute = attribute as? ViewCountStoryAttribute {
|
||||
// views = viewsAttribute.count
|
||||
// } else if let forwardsAttribute = attribute as? ForwardCountStoryAttribute {
|
||||
// forwards = forwardsAttribute.count
|
||||
// }
|
||||
// }
|
||||
var views: Int = 0
|
||||
var forwards: Int = 0
|
||||
if let storyViews = story.views {
|
||||
views = storyViews.seenCount
|
||||
forwards = storyViews.forwardCount
|
||||
}
|
||||
|
||||
return signal
|
||||
|> mapToSignal { result -> Signal<StoryStats?, MTRpcError> in
|
||||
@ -125,7 +122,6 @@ private func requestStoryStats(postbox: Postbox, network: Network, datacenterId:
|
||||
private final class StoryStatsContextImpl {
|
||||
private let postbox: Postbox
|
||||
private let network: Network
|
||||
private let datacenterId: Int32
|
||||
private let peerId: EnginePeer.Id
|
||||
private let storyId: Int32
|
||||
|
||||
@ -144,12 +140,11 @@ private final class StoryStatsContextImpl {
|
||||
private let disposable = MetaDisposable()
|
||||
private let disposables = DisposableDict<String>()
|
||||
|
||||
init(postbox: Postbox, network: Network, datacenterId: Int32, peerId: EnginePeer.Id, storyId: Int32) {
|
||||
init(postbox: Postbox, network: Network, peerId: EnginePeer.Id, storyId: Int32) {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
self.postbox = postbox
|
||||
self.network = network
|
||||
self.datacenterId = datacenterId
|
||||
self.peerId = peerId
|
||||
self.storyId = storyId
|
||||
self._state = StoryStatsContextState(stats: nil)
|
||||
@ -167,7 +162,7 @@ private final class StoryStatsContextImpl {
|
||||
private func load() {
|
||||
assert(Queue.mainQueue().isCurrent())
|
||||
|
||||
self.disposable.set((requestStoryStats(postbox: self.postbox, network: self.network, datacenterId: self.datacenterId, peerId: self.peerId, storyId: self.storyId)
|
||||
self.disposable.set((requestStoryStats(postbox: self.postbox, network: self.network, peerId: self.peerId, storyId: self.storyId)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] stats in
|
||||
if let strongSelf = self {
|
||||
strongSelf._state = StoryStatsContextState(stats: stats)
|
||||
@ -178,7 +173,7 @@ private final class StoryStatsContextImpl {
|
||||
|
||||
func loadDetailedGraph(_ graph: StatsGraph, x: Int64) -> Signal<StatsGraph?, NoError> {
|
||||
if let token = graph.token {
|
||||
return requestGraph(network: self.network, datacenterId: self.datacenterId, token: token, x: x)
|
||||
return requestGraph(postbox: self.postbox, network: self.network, peerId: self.peerId, token: token, x: x)
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
@ -200,9 +195,9 @@ public final class StoryStatsContext {
|
||||
}
|
||||
}
|
||||
|
||||
public init(postbox: Postbox, network: Network, datacenterId: Int32, peerId: EnginePeer.Id, storyId: Int32) {
|
||||
public init(postbox: Postbox, network: Network, peerId: EnginePeer.Id, storyId: Int32) {
|
||||
self.impl = QueueLocalObject(queue: Queue.mainQueue(), generate: {
|
||||
return StoryStatsContextImpl(postbox: postbox, network: network, datacenterId: datacenterId, peerId: peerId, storyId: storyId)
|
||||
return StoryStatsContextImpl(postbox: postbox, network: network, peerId: peerId, storyId: storyId)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ public enum SearchMessagesLocation: Equatable {
|
||||
case general(tags: MessageTags?, minDate: Int32?, maxDate: Int32?)
|
||||
case group(groupId: PeerGroupId, tags: MessageTags?, minDate: Int32?, maxDate: Int32?)
|
||||
case peer(peerId: PeerId, fromId: PeerId?, tags: MessageTags?, topMsgId: MessageId?, minDate: Int32?, maxDate: Int32?)
|
||||
case publicForwards(messageId: MessageId, datacenterId: Int?)
|
||||
case publicForwards(messageId: MessageId)
|
||||
case sentMedia(tags: MessageTags?)
|
||||
}
|
||||
|
||||
@ -354,30 +354,31 @@ func _internal_searchMessages(account: Account, location: SearchMessagesLocation
|
||||
return .single((nil, nil))
|
||||
}
|
||||
}
|
||||
case let .publicForwards(messageId, datacenterId):
|
||||
remoteSearchResult = account.postbox.transaction { transaction -> (Api.InputChannel?, Int32, MessageIndex?, Api.InputPeer) in
|
||||
case let .publicForwards(messageId):
|
||||
remoteSearchResult = account.postbox.transaction { transaction -> (Api.InputChannel?, Int32, MessageIndex?, Api.InputPeer, Int32?) in
|
||||
let sourcePeer = transaction.getPeer(messageId.peerId)
|
||||
let inputChannel = sourcePeer.flatMap { apiInputChannel($0) }
|
||||
let statsDatacenterId = (transaction.getPeerCachedData(peerId: messageId.peerId) as? CachedChannelData)?.statsDatacenterId
|
||||
|
||||
var lowerBound: MessageIndex?
|
||||
if let state = state, let message = state.main.messages.last {
|
||||
lowerBound = message.index
|
||||
}
|
||||
if let lowerBound = lowerBound, let peer = transaction.getPeer(lowerBound.id.peerId), let inputPeer = apiInputPeer(peer) {
|
||||
return (inputChannel, state?.main.nextRate ?? 0, lowerBound, inputPeer)
|
||||
return (inputChannel, state?.main.nextRate ?? 0, lowerBound, inputPeer, statsDatacenterId)
|
||||
} else {
|
||||
return (inputChannel, 0, lowerBound, .inputPeerEmpty)
|
||||
return (inputChannel, 0, lowerBound, .inputPeerEmpty, statsDatacenterId)
|
||||
}
|
||||
}
|
||||
|> mapToSignal { (inputChannel, nextRate, lowerBound, inputPeer) in
|
||||
|> mapToSignal { (inputChannel, nextRate, lowerBound, inputPeer, statsDatacenterId) in
|
||||
guard let inputChannel = inputChannel else {
|
||||
return .complete()
|
||||
}
|
||||
|
||||
let request = Api.functions.stats.getMessagePublicForwards(channel: inputChannel, msgId: messageId.id, offsetRate: nextRate, offsetPeer: inputPeer, offsetId: lowerBound?.id.id ?? 0, limit: limit)
|
||||
let signal: Signal<Api.messages.Messages, MTRpcError>
|
||||
if let datacenterId = datacenterId, account.network.datacenterId != datacenterId {
|
||||
signal = account.network.download(datacenterId: datacenterId, isMedia: false, tag: nil)
|
||||
if let statsDatacenterId = statsDatacenterId, account.network.datacenterId != statsDatacenterId {
|
||||
signal = account.network.download(datacenterId: Int(statsDatacenterId), isMedia: false, tag: nil)
|
||||
|> castError(MTRpcError.self)
|
||||
|> mapToSignal { worker in
|
||||
return worker.request(request)
|
||||
|
@ -34,12 +34,12 @@ private func entryId(peerId: EnginePeer.Id) -> ItemCacheEntryId {
|
||||
return ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.recommendedChannels, key: cacheKey)
|
||||
}
|
||||
|
||||
func _internal_requestRecommendedChannels(account: Account, peerId: EnginePeer.Id) -> Signal<Never, NoError> {
|
||||
func _internal_requestRecommendedChannels(account: Account, peerId: EnginePeer.Id, forceUpdate: Bool) -> Signal<Never, NoError> {
|
||||
return account.postbox.transaction { transaction -> Peer? in
|
||||
guard let channel = transaction.getPeer(peerId) else {
|
||||
guard let channel = transaction.getPeer(peerId) as? TelegramChannel, case .broadcast = channel.info else {
|
||||
return nil
|
||||
}
|
||||
if let entry = transaction.retrieveItemCacheEntry(id: entryId(peerId: peerId))?.get(CachedRecommendedChannels.self), !entry.peerIds.isEmpty {
|
||||
if let entry = transaction.retrieveItemCacheEntry(id: entryId(peerId: peerId))?.get(CachedRecommendedChannels.self), !entry.peerIds.isEmpty && !forceUpdate {
|
||||
return nil
|
||||
} else {
|
||||
return channel
|
||||
|
@ -79,7 +79,7 @@ func _internal_joinChannel(account: Account, peerId: PeerId, hash: String?) -> S
|
||||
}
|
||||
|> afterCompleted {
|
||||
if hash == nil {
|
||||
let _ = _internal_requestRecommendedChannels(account: account, peerId: peerId).startStandalone()
|
||||
let _ = _internal_requestRecommendedChannels(account: account, peerId: peerId, forceUpdate: true).startStandalone()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1249,8 +1249,8 @@ public extension TelegramEngine {
|
||||
return _internal_toggleRecommendedChannelsHidden(account: self.account, peerId: peerId, hidden: hidden)
|
||||
}
|
||||
|
||||
public func requestRecommendedChannels(peerId: EnginePeer.Id) -> Signal<Never, NoError> {
|
||||
return _internal_requestRecommendedChannels(account: self.account, peerId: peerId)
|
||||
public func requestRecommendedChannels(peerId: EnginePeer.Id, forceUpdate: Bool = false) -> Signal<Never, NoError> {
|
||||
return _internal_requestRecommendedChannels(account: self.account, peerId: peerId, forceUpdate: forceUpdate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ public final class BlockedPeersContext {
|
||||
}
|
||||
}
|
||||
let inputPeers = peers.compactMap { apiInputPeer($0) }
|
||||
return network.request(Api.functions.contacts.setBlocked(flags: flags, id: inputPeers, limit: Int32(peers.count)))
|
||||
return network.request(Api.functions.contacts.setBlocked(flags: flags, id: inputPeers, limit: Int32(max(currentPeers.count, peers.count))))
|
||||
|> mapError { _ -> BlockedPeersContextAddError in
|
||||
return .generic
|
||||
}
|
||||
|
@ -370,24 +370,11 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
||||
}
|
||||
|
||||
private func openBoostStats() {
|
||||
guard let component = self.component else {
|
||||
guard let component = self.component, let boostStatus = self.boostStatus else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (component.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.StatsDatacenterId(id: component.peerId)
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] statsDatacenterId in
|
||||
guard let self, let component = self.component, let boostStatus = self.boostStatus else {
|
||||
return
|
||||
}
|
||||
guard let statsDatacenterId else {
|
||||
return
|
||||
}
|
||||
|
||||
let statsController = component.context.sharedContext.makeChannelStatsController(context: component.context, updatedPresentationData: nil, peerId: component.peerId, boosts: true, boostStatus: boostStatus, statsDatacenterId: statsDatacenterId)
|
||||
let statsController = component.context.sharedContext.makeChannelStatsController(context: component.context, updatedPresentationData: nil, peerId: component.peerId, boosts: true, boostStatus: boostStatus)
|
||||
self.environment?.controller()?.push(statsController)
|
||||
})
|
||||
}
|
||||
|
||||
func update(component: PeerAllowedReactionsScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: Transition) -> CGSize {
|
||||
|
@ -890,14 +890,18 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
requestsContextPromise.get(),
|
||||
requestsStatePromise.get(),
|
||||
hasStories,
|
||||
accountIsPremium
|
||||
accountIsPremium,
|
||||
context.engine.peers.recommendedChannels(peerId: peerId)
|
||||
)
|
||||
|> map { peerView, availablePanes, globalNotificationSettings, status, currentInvitationsContext, invitations, currentRequestsContext, requests, hasStories, accountIsPremium -> PeerInfoScreenData in
|
||||
|> map { peerView, availablePanes, globalNotificationSettings, status, currentInvitationsContext, invitations, currentRequestsContext, requests, hasStories, accountIsPremium, recommendedChannels -> PeerInfoScreenData in
|
||||
var availablePanes = availablePanes
|
||||
if let hasStories {
|
||||
if hasStories {
|
||||
availablePanes?.insert(.stories, at: 0)
|
||||
}
|
||||
if let recommendedChannels, !recommendedChannels.channels.isEmpty {
|
||||
availablePanes?.append(.recommended)
|
||||
}
|
||||
} else {
|
||||
availablePanes = nil
|
||||
}
|
||||
|
@ -416,6 +416,8 @@ private final class PeerInfoPendingPane {
|
||||
} else {
|
||||
preconditionFailure()
|
||||
}
|
||||
case .recommended:
|
||||
paneNode = PeerInfoRecommendedChannelsPaneNode(context: context, peerId: peerId, chatControllerInteraction: chatControllerInteraction)
|
||||
}
|
||||
paneNode.parentController = parentController
|
||||
self.pane = PeerInfoPaneWrapper(key: key, node: paneNode)
|
||||
@ -989,6 +991,8 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
||||
title = presentationData.strings.PeerInfo_PaneGroups
|
||||
case .members:
|
||||
title = presentationData.strings.PeerInfo_PaneMembers
|
||||
case .recommended:
|
||||
title = presentationData.strings.PeerInfo_PaneRecommended
|
||||
}
|
||||
return PeerInfoPaneSpecifier(key: key, title: title)
|
||||
}, selectedPane: self.currentPaneKey, transitionFraction: self.transitionFraction, transition: transition)
|
||||
|
@ -3990,6 +3990,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] translationState in
|
||||
self?.translationState = translationState
|
||||
})
|
||||
|
||||
let _ = context.engine.peers.requestRecommendedChannels(peerId: peerId, forceUpdate: true).startStandalone()
|
||||
}
|
||||
|
||||
if peerId.namespace == Namespaces.Peer.CloudChannel || peerId.namespace == Namespaces.Peer.CloudUser {
|
||||
@ -6735,21 +6737,16 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
}
|
||||
|
||||
private func openStats(boosts: Bool = false, boostStatus: ChannelBoostStatus? = nil) {
|
||||
guard let controller = self.controller, let data = self.data, let peer = data.peer, let cachedData = data.cachedData else {
|
||||
guard let controller = self.controller, let data = self.data, let peer = data.peer else {
|
||||
return
|
||||
}
|
||||
self.view.endEditing(true)
|
||||
|
||||
var statsDatacenterId: Int32?
|
||||
if let cachedData = cachedData as? CachedChannelData {
|
||||
statsDatacenterId = cachedData.statsDatacenterId
|
||||
}
|
||||
|
||||
let statsController: ViewController
|
||||
if let channel = peer as? TelegramChannel, case .group = channel.info {
|
||||
statsController = groupStatsController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: peer.id, statsDatacenterId: statsDatacenterId)
|
||||
statsController = groupStatsController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: peer.id)
|
||||
} else {
|
||||
statsController = channelStatsController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: peer.id, section: boosts ? .boosts : .stats, boostStatus: boostStatus, statsDatacenterId: statsDatacenterId)
|
||||
statsController = channelStatsController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: peer.id, section: boosts ? .boosts : .stats, boostStatus: boostStatus)
|
||||
}
|
||||
controller.push(statsController)
|
||||
}
|
||||
|
@ -129,7 +129,8 @@ public final class StoryContentContextImpl: StoryContentContext {
|
||||
peerPresence = presencesView.presences[peerId]
|
||||
}
|
||||
|
||||
if let cachedPeerDataView = views.views[PostboxViewKey.cachedPeerData(peerId: peerId)] as? CachedPeerDataView, let cachedUserData = cachedPeerDataView.cachedPeerData as? CachedUserData {
|
||||
if let cachedPeerDataView = views.views[PostboxViewKey.cachedPeerData(peerId: peerId)] as? CachedPeerDataView {
|
||||
if let cachedUserData = cachedPeerDataView.cachedPeerData as? CachedUserData {
|
||||
var isMuted = false
|
||||
if let notificationSettings = peerView.notificationSettings as? TelegramPeerNotificationSettings {
|
||||
isMuted = resolvedAreStoriesMuted(globalSettings: globalNotificationSettings._asGlobalNotificationSettings(), peer: peer._asPeer(), peerSettings: notificationSettings, topSearchPeers: [])
|
||||
@ -139,13 +140,31 @@ public final class StoryContentContextImpl: StoryContentContext {
|
||||
additionalPeerData = StoryContentContextState.AdditionalPeerData(
|
||||
isMuted: isMuted,
|
||||
areVoiceMessagesAvailable: cachedUserData.voiceMessagesAvailable,
|
||||
presence: peerPresence.flatMap { EnginePeer.Presence($0) }
|
||||
presence: peerPresence.flatMap { EnginePeer.Presence($0) },
|
||||
canViewStats: false
|
||||
)
|
||||
} else if let cachedChannelData = cachedPeerDataView.cachedPeerData as? CachedChannelData {
|
||||
additionalPeerData = StoryContentContextState.AdditionalPeerData(
|
||||
isMuted: true,
|
||||
areVoiceMessagesAvailable: true,
|
||||
presence: peerPresence.flatMap { EnginePeer.Presence($0) },
|
||||
canViewStats: cachedChannelData.flags.contains(.canViewStats)
|
||||
)
|
||||
} else {
|
||||
additionalPeerData = StoryContentContextState.AdditionalPeerData(
|
||||
isMuted: true,
|
||||
areVoiceMessagesAvailable: true,
|
||||
presence: peerPresence.flatMap { EnginePeer.Presence($0) }
|
||||
presence: peerPresence.flatMap { EnginePeer.Presence($0) },
|
||||
canViewStats: false
|
||||
)
|
||||
}
|
||||
}
|
||||
else {
|
||||
additionalPeerData = StoryContentContextState.AdditionalPeerData(
|
||||
isMuted: true,
|
||||
areVoiceMessagesAvailable: true,
|
||||
presence: peerPresence.flatMap { EnginePeer.Presence($0) },
|
||||
canViewStats: false
|
||||
)
|
||||
}
|
||||
let state = stateView.value?.get(Stories.PeerState.self)
|
||||
@ -993,6 +1012,7 @@ public final class SingleStoryContentContextImpl: StoryContentContext {
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: storyId.peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.Presence(id: storyId.peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.AreVoiceMessagesAvailable(id: storyId.peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.CanViewStats(id: storyId.peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: storyId.peerId),
|
||||
TelegramEngine.EngineData.Item.NotificationSettings.Global()
|
||||
),
|
||||
@ -1045,7 +1065,7 @@ public final class SingleStoryContentContextImpl: StoryContentContext {
|
||||
return
|
||||
}
|
||||
|
||||
let (peer, presence, areVoiceMessagesAvailable, notificationSettings, globalNotificationSettings) = data
|
||||
let (peer, presence, areVoiceMessagesAvailable, canViewStats, notificationSettings, globalNotificationSettings) = data
|
||||
let (item, peers, allEntityFiles) = itemAndPeers
|
||||
|
||||
guard let peer else {
|
||||
@ -1057,7 +1077,8 @@ public final class SingleStoryContentContextImpl: StoryContentContext {
|
||||
let additionalPeerData = StoryContentContextState.AdditionalPeerData(
|
||||
isMuted: isMuted,
|
||||
areVoiceMessagesAvailable: areVoiceMessagesAvailable,
|
||||
presence: presence
|
||||
presence: presence,
|
||||
canViewStats: canViewStats
|
||||
)
|
||||
|
||||
if item == nil {
|
||||
@ -1201,6 +1222,7 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.Presence(id: peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.AreVoiceMessagesAvailable(id: peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.CanViewStats(id: peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peerId),
|
||||
TelegramEngine.EngineData.Item.NotificationSettings.Global()
|
||||
),
|
||||
@ -1212,7 +1234,7 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
|
||||
return
|
||||
}
|
||||
|
||||
let (peer, presence, areVoiceMessagesAvailable, notificationSettings, globalNotificationSettings) = data
|
||||
let (peer, presence, areVoiceMessagesAvailable, canViewStats, notificationSettings, globalNotificationSettings) = data
|
||||
|
||||
guard let peer else {
|
||||
return
|
||||
@ -1223,7 +1245,8 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
|
||||
let additionalPeerData = StoryContentContextState.AdditionalPeerData(
|
||||
isMuted: isMuted,
|
||||
areVoiceMessagesAvailable: areVoiceMessagesAvailable,
|
||||
presence: presence
|
||||
presence: presence,
|
||||
canViewStats: canViewStats
|
||||
)
|
||||
|
||||
self.listState = state
|
||||
|
@ -140,15 +140,18 @@ public final class StoryContentContextState {
|
||||
public let isMuted: Bool
|
||||
public let areVoiceMessagesAvailable: Bool
|
||||
public let presence: EnginePeer.Presence?
|
||||
public let canViewStats: Bool
|
||||
|
||||
public init(
|
||||
isMuted: Bool,
|
||||
areVoiceMessagesAvailable: Bool,
|
||||
presence: EnginePeer.Presence?
|
||||
presence: EnginePeer.Presence?,
|
||||
canViewStats: Bool
|
||||
) {
|
||||
self.isMuted = isMuted
|
||||
self.areVoiceMessagesAvailable = areVoiceMessagesAvailable
|
||||
self.presence = presence
|
||||
self.canViewStats = canViewStats
|
||||
}
|
||||
|
||||
public static func == (lhs: StoryContentContextState.AdditionalPeerData, rhs: StoryContentContextState.AdditionalPeerData) -> Bool {
|
||||
@ -161,6 +164,9 @@ public final class StoryContentContextState {
|
||||
if lhs.presence != rhs.presence {
|
||||
return false
|
||||
}
|
||||
if lhs.canViewStats != rhs.canViewStats {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -1796,6 +1796,12 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
return
|
||||
}
|
||||
self.sendMessageContext.performShareAction(view: self)
|
||||
},
|
||||
repostAction: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.openStoryEditing(repost: true)
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
@ -2980,6 +2986,7 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
audioRecorder: self.sendMessageContext.audioRecorderValue,
|
||||
videoRecordingStatus: !self.sendMessageContext.hasRecordedVideoPreview ? self.sendMessageContext.videoRecorderValue?.audioStatus : nil,
|
||||
isRecordingLocked: self.sendMessageContext.isMediaRecordingLocked,
|
||||
hasRecordedVideo: false,
|
||||
recordedAudioPreview: self.sendMessageContext.recordedAudioPreview,
|
||||
hasRecordedVideoPreview: self.sendMessageContext.hasRecordedVideoPreview,
|
||||
wasRecordingDismissed: self.sendMessageContext.wasRecordingDismissed,
|
||||
@ -5075,7 +5082,7 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
StoryContainerScreen.openPeerStories(context: component.context, peerId: peer.id, parentController: controller, avatarNode: avatarNode)
|
||||
}
|
||||
|
||||
private func openStoryEditing() {
|
||||
func openStoryEditing(repost: Bool = false) {
|
||||
guard let component = self.component, let peerReference = PeerReference(component.slice.peer._asPeer()) else {
|
||||
return
|
||||
}
|
||||
@ -5955,6 +5962,26 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
})))
|
||||
}
|
||||
|
||||
if component.slice.additionalPeerData.canViewStats {
|
||||
items.append(.action(ContextMenuActionItem(text: component.strings.Story_Context_ViewStats, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Statistics"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, a in
|
||||
a(.default)
|
||||
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }.withUpdated(theme: defaultDarkColorPresentationTheme)
|
||||
let statsController = component.context.sharedContext.makeStoryStatsController(
|
||||
context: component.context,
|
||||
updatedPresentationData: (presentationData, .single(presentationData)),
|
||||
peerId: component.slice.peer.id,
|
||||
storyId: component.slice.item.storyItem.id
|
||||
)
|
||||
component.controller()?.push(statsController)
|
||||
})))
|
||||
}
|
||||
|
||||
let saveText: String = component.strings.Story_Context_SaveToGallery
|
||||
items.append(.action(ContextMenuActionItem(text: saveText, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Save"), color: theme.contextMenu.primaryColor)
|
||||
|
@ -3680,21 +3680,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
let _ = strongSelf.presentVoiceMessageDiscardAlert(action: {
|
||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: id))
|
||||
|> mapToSignal { message -> Signal<(EngineMessage.Id, Int32?)?, NoError> in
|
||||
|> mapToSignal { message -> Signal<EngineMessage.Id?, NoError> in
|
||||
if let message {
|
||||
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.StatsDatacenterId(id: message.id.peerId))
|
||||
|> map { statsDatacenterId -> (EngineMessage.Id, Int32?)? in
|
||||
return (message.id, statsDatacenterId)
|
||||
}
|
||||
return .single(message.id)
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] messageIdAndStatsDatacenterId in
|
||||
guard let strongSelf = self, let (id, statsDatacenterId) = messageIdAndStatsDatacenterId, let statsDatacenterId = statsDatacenterId else {
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] messageId in
|
||||
guard let strongSelf = self, let messageId else {
|
||||
return
|
||||
}
|
||||
strongSelf.push(messageStatsController(context: context, subject: .message(id: id), statsDatacenterId: statsDatacenterId))
|
||||
strongSelf.push(messageStatsController(context: context, subject: .message(id: messageId)))
|
||||
})
|
||||
}, delay: true)
|
||||
}, editMessageMedia: { [weak self] messageId, draw in
|
||||
@ -4674,10 +4671,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
galleryController.setHintWillBePresentedInPreviewingContext(true)
|
||||
|
||||
let items: Signal<[ContextMenuItem], NoError> = context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.CanViewStats(id: peer.id),
|
||||
TelegramEngine.EngineData.Item.Peer.StatsDatacenterId(id: peer.id)
|
||||
TelegramEngine.EngineData.Item.Peer.CanViewStats(id: peer.id)
|
||||
)
|
||||
|> map { canViewStats, statsDatacenterId -> [ContextMenuItem] in
|
||||
|> map { canViewStats -> [ContextMenuItem] in
|
||||
var items: [ContextMenuItem] = [
|
||||
.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_LinkDialogOpen, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Info"), color: theme.actionSheet.primaryTextColor)
|
||||
@ -4698,9 +4694,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
let statsController: ViewController
|
||||
if let channel = peer as? TelegramChannel, case .group = channel.info {
|
||||
statsController = groupStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id, statsDatacenterId: statsDatacenterId)
|
||||
statsController = groupStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id)
|
||||
} else {
|
||||
statsController = channelStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id, statsDatacenterId: statsDatacenterId)
|
||||
statsController = channelStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id)
|
||||
}
|
||||
strongSelf.push(statsController)
|
||||
})))
|
||||
|
@ -1870,8 +1870,16 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
return installedStickerPacksController(context: context, mode: mode, forceTheme: forceTheme)
|
||||
}
|
||||
|
||||
public func makeChannelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, boosts: Bool, boostStatus: ChannelBoostStatus?, statsDatacenterId: Int32) -> ViewController {
|
||||
return channelStatsController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, section: boosts ? .boosts : .stats, boostStatus: nil, statsDatacenterId: statsDatacenterId)
|
||||
public func makeChannelStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, boosts: Bool, boostStatus: ChannelBoostStatus?) -> ViewController {
|
||||
return channelStatsController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, section: boosts ? .boosts : .stats, boostStatus: boostStatus)
|
||||
}
|
||||
|
||||
public func makeMessagesStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, messageId: EngineMessage.Id) -> ViewController {
|
||||
return messageStatsController(context: context, updatedPresentationData: updatedPresentationData, subject: .message(id: messageId))
|
||||
}
|
||||
|
||||
public func makeStoryStatsController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peerId: EnginePeer.Id, storyId: Int32) -> ViewController {
|
||||
return messageStatsController(context: context, updatedPresentationData: updatedPresentationData, subject: .story(peerId: peerId, id: storyId))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -747,8 +747,6 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode
|
||||
private let dimLayer: SimpleLayer
|
||||
private var isGeneratingPatternImage: Bool = false
|
||||
|
||||
private let bakedBackgroundView: UIImageView
|
||||
|
||||
private var validLayout: (CGSize, WallpaperDisplayMode)?
|
||||
private var wallpaper: TelegramWallpaper?
|
||||
private var isSettingUpWallpaper: Bool = false
|
||||
@ -861,9 +859,6 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode
|
||||
|
||||
self.patternImageLayer = EffectImageLayer()
|
||||
|
||||
self.bakedBackgroundView = UIImageView()
|
||||
self.bakedBackgroundView.isHidden = true
|
||||
|
||||
self.dimLayer = SimpleLayer()
|
||||
self.dimLayer.opacity = 0.0
|
||||
self.dimLayer.backgroundColor = UIColor.black.cgColor
|
||||
|
Loading…
x
Reference in New Issue
Block a user