diff --git a/submodules/StatisticsUI/Sources/MessageStatsController.swift b/submodules/StatisticsUI/Sources/MessageStatsController.swift index 05828dc801..4327d8489a 100644 --- a/submodules/StatisticsUI/Sources/MessageStatsController.swift +++ b/submodules/StatisticsUI/Sources/MessageStatsController.swift @@ -215,16 +215,14 @@ private enum StatsEntry: ItemListNodeEntry { } } -private func messageStatsControllerEntries(data: PostStats?, storyViews: EngineStoryItem.Views?, messages: SearchMessagesResult?, forwards: StoryStatsPublicForwardsContext.State?, presentationData: PresentationData) -> [StatsEntry] { +private func messageStatsControllerEntries(data: PostStats?, storyViews: EngineStoryItem.Views?, forwards: StoryStatsPublicForwardsContext.State?, presentationData: PresentationData) -> [StatsEntry] { var entries: [StatsEntry] = [] if let data = data { entries.append(.overviewTitle(presentationData.theme, presentationData.strings.Stats_MessageOverview.uppercased())) var publicShares: Int32? - if let messages { - publicShares = messages.totalCount - } else if let forwards { + if let forwards { publicShares = forwards.count } entries.append(.overview(presentationData.theme, data, storyViews, publicShares)) @@ -254,15 +252,6 @@ private func messageStatsControllerEntries(data: PostStats?, storyViews: EngineS entries.append(.reactionsGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, data.reactionsGraph, .bars, isStories)) } - if let messages, !messages.messages.isEmpty { - entries.append(.publicForwardsTitle(presentationData.theme, presentationData.strings.Stats_MessagePublicForwardsTitle.uppercased())) - var index: Int32 = 0 - for message in messages.messages { - entries.append(.publicForward(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, .message(message))) - index += 1 - } - } - if let forwards, !forwards.forwards.isEmpty { entries.append(.publicForwardsTitle(presentationData.theme, presentationData.strings.Stats_MessagePublicForwardsTitle.uppercased())) var index: Int32 = 0 @@ -305,7 +294,6 @@ public func messageStatsController(context: AccountContext, updatedPresentationD let actionsDisposable = DisposableSet() let dataPromise = Promise(nil) - let messagesPromise = Promise<(SearchMessagesResult, SearchMessagesState)?>(nil) let forwardsPromise = Promise(nil) let anyStatsContext: Any @@ -314,7 +302,7 @@ public func messageStatsController(context: AccountContext, updatedPresentationD var openStoryImpl: ((EnginePeer.Id, EngineStoryItem, UIView) -> Void)? var storyContextActionImpl: ((EnginePeer.Id, ASDisplayNode, ContextGesture?, Bool) -> Void)? - var forwardsContext: StoryStatsPublicForwardsContext? + let forwardsContext: StoryStatsPublicForwardsContext let peerId: EnginePeer.Id var storyItem: EngineStoryItem? switch subject { @@ -331,19 +319,7 @@ public func messageStatsController(context: AccountContext, updatedPresentationD dataPromise.set(.single(nil) |> then(dataSignal)) anyStatsContext = statsContext - let searchSignal = context.engine.messages.searchMessages(location: .publicForwards(messageId: id), query: "", state: nil) - |> map(Optional.init) - |> afterNext { result in - if let result = result { - for message in result.0.messages { - if let peer = message.peers[message.id.peerId], let peerReference = PeerReference(peer) { - let _ = context.engine.peers.updatedRemotePeer(peer: peerReference).start() - } - } - } - } - messagesPromise.set(.single(nil) |> then(searchSignal)) - forwardsPromise.set(.single(nil)) + forwardsContext = StoryStatsPublicForwardsContext(account: context.account, subject: .message(messageId: id)) case let .story(peerIdValue, id, item, _): peerId = peerIdValue storyItem = item @@ -358,23 +334,18 @@ public func messageStatsController(context: AccountContext, updatedPresentationD } dataPromise.set(.single(nil) |> then(dataSignal)) anyStatsContext = statsContext - - messagesPromise.set(.single(nil)) - - forwardsContext = StoryStatsPublicForwardsContext(account: context.account, peerId: peerId, storyId: id) - if let forwardsContext { - forwardsPromise.set( - .single(nil) - |> then( - forwardsContext.state - |> map(Optional.init) - ) - ) - } else { - forwardsPromise.set(.single(nil)) - } + + forwardsContext = StoryStatsPublicForwardsContext(account: context.account, subject: .story(peerId: peerId, id: id)) } + forwardsPromise.set( + .single(nil) + |> then( + forwardsContext.state + |> map(Optional.init) + ) + ) + let arguments = MessageStatsControllerArguments(context: context, loadDetailedGraph: { graph, x -> Signal in return loadDetailedGraphImpl?(graph, x) ?? .single(nil) }, openMessage: { messageId in @@ -412,14 +383,13 @@ public func messageStatsController(context: AccountContext, updatedPresentationD let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData let signal = combineLatest( presentationData, - dataPromise.get(), - messagesPromise.get(), + dataPromise.get(), forwardsPromise.get(), longLoadingSignal, iconNodePromise.get() ) |> deliverOnMainQueue - |> map { presentationData, data, search, forwards, longLoading, iconNode -> (ItemListControllerState, (ItemListNodeState, Any)) in + |> map { presentationData, data, forwards, longLoading, iconNode -> (ItemListControllerState, (ItemListNodeState, Any)) in let previous = previousData.swap(data) var emptyStateItem: ItemListControllerEmptyStateItem? if data == nil { @@ -445,7 +415,7 @@ public func messageStatsController(context: AccountContext, updatedPresentationD openStoryImpl?(peerId, storyItem, iconNode.view) } }) }, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true) - let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: messageStatsControllerEntries(data: data, storyViews: storyViews, messages: search?.0, forwards: forwards, presentationData: presentationData), style: .blocks, emptyStateItem: emptyStateItem, crossfadeState: previous == nil, animateChanges: false) + let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: messageStatsControllerEntries(data: data, storyViews: storyViews, forwards: forwards, presentationData: presentationData), style: .blocks, emptyStateItem: emptyStateItem, crossfadeState: previous == nil, animateChanges: false) return (controllerState, (listState, arguments)) } @@ -464,7 +434,7 @@ public func messageStatsController(context: AccountContext, updatedPresentationD }) } controller.visibleBottomContentOffsetChanged = { [weak forwardsContext] offset in - if case let .known(value) = offset, value < 100.0, case .story = subject { + if case let .known(value) = offset, value < 100.0 { forwardsContext?.loadMore() } } diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index e29cf34d61..8d67233091 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -463,7 +463,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[695856818] = { return Api.LangPackString.parse_langPackStringDeleted($0) } dict[1816636575] = { return Api.LangPackString.parse_langPackStringPluralized($0) } dict[-1361650766] = { return Api.MaskCoords.parse_maskCoords($0) } + dict[577893055] = { return Api.MediaArea.parse_inputMediaAreaChannelPost($0) } dict[-1300094593] = { return Api.MediaArea.parse_inputMediaAreaVenue($0) } + dict[1996756655] = { return Api.MediaArea.parse_mediaAreaChannelPost($0) } dict[-544523486] = { return Api.MediaArea.parse_mediaAreaGeoPoint($0) } dict[340088945] = { return Api.MediaArea.parse_mediaAreaSuggestedReaction($0) } dict[-1098720356] = { return Api.MediaArea.parse_mediaAreaVenue($0) } diff --git a/submodules/TelegramApi/Sources/Api12.swift b/submodules/TelegramApi/Sources/Api12.swift index d7131cd5dc..70197dfd31 100644 --- a/submodules/TelegramApi/Sources/Api12.swift +++ b/submodules/TelegramApi/Sources/Api12.swift @@ -155,14 +155,24 @@ public extension Api { } } public extension Api { - enum MediaArea: TypeConstructorDescription { + indirect enum MediaArea: TypeConstructorDescription { + case inputMediaAreaChannelPost(coordinates: Api.MediaAreaCoordinates, channel: Api.InputChannel, msgId: Int32) case inputMediaAreaVenue(coordinates: Api.MediaAreaCoordinates, queryId: Int64, resultId: String) + case mediaAreaChannelPost(coordinates: Api.MediaAreaCoordinates, channelId: Int64, msgId: Int32) case mediaAreaGeoPoint(coordinates: Api.MediaAreaCoordinates, geo: Api.GeoPoint) case mediaAreaSuggestedReaction(flags: Int32, coordinates: Api.MediaAreaCoordinates, reaction: Api.Reaction) case mediaAreaVenue(coordinates: Api.MediaAreaCoordinates, geo: Api.GeoPoint, title: String, address: String, provider: String, venueId: String, venueType: String) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { + case .inputMediaAreaChannelPost(let coordinates, let channel, let msgId): + if boxed { + buffer.appendInt32(577893055) + } + coordinates.serialize(buffer, true) + channel.serialize(buffer, true) + serializeInt32(msgId, buffer: buffer, boxed: false) + break case .inputMediaAreaVenue(let coordinates, let queryId, let resultId): if boxed { buffer.appendInt32(-1300094593) @@ -171,6 +181,14 @@ public extension Api { serializeInt64(queryId, buffer: buffer, boxed: false) serializeString(resultId, buffer: buffer, boxed: false) break + case .mediaAreaChannelPost(let coordinates, let channelId, let msgId): + if boxed { + buffer.appendInt32(1996756655) + } + coordinates.serialize(buffer, true) + serializeInt64(channelId, buffer: buffer, boxed: false) + serializeInt32(msgId, buffer: buffer, boxed: false) + break case .mediaAreaGeoPoint(let coordinates, let geo): if boxed { buffer.appendInt32(-544523486) @@ -203,8 +221,12 @@ public extension Api { public func descriptionFields() -> (String, [(String, Any)]) { switch self { + case .inputMediaAreaChannelPost(let coordinates, let channel, let msgId): + return ("inputMediaAreaChannelPost", [("coordinates", coordinates as Any), ("channel", channel as Any), ("msgId", msgId as Any)]) case .inputMediaAreaVenue(let coordinates, let queryId, let resultId): return ("inputMediaAreaVenue", [("coordinates", coordinates as Any), ("queryId", queryId as Any), ("resultId", resultId as Any)]) + case .mediaAreaChannelPost(let coordinates, let channelId, let msgId): + return ("mediaAreaChannelPost", [("coordinates", coordinates as Any), ("channelId", channelId as Any), ("msgId", msgId as Any)]) case .mediaAreaGeoPoint(let coordinates, let geo): return ("mediaAreaGeoPoint", [("coordinates", coordinates as Any), ("geo", geo as Any)]) case .mediaAreaSuggestedReaction(let flags, let coordinates, let reaction): @@ -214,6 +236,27 @@ public extension Api { } } + public static func parse_inputMediaAreaChannelPost(_ reader: BufferReader) -> MediaArea? { + var _1: Api.MediaAreaCoordinates? + if let signature = reader.readInt32() { + _1 = Api.parse(reader, signature: signature) as? Api.MediaAreaCoordinates + } + var _2: Api.InputChannel? + if let signature = reader.readInt32() { + _2 = Api.parse(reader, signature: signature) as? Api.InputChannel + } + var _3: Int32? + _3 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + if _c1 && _c2 && _c3 { + return Api.MediaArea.inputMediaAreaChannelPost(coordinates: _1!, channel: _2!, msgId: _3!) + } + else { + return nil + } + } public static func parse_inputMediaAreaVenue(_ reader: BufferReader) -> MediaArea? { var _1: Api.MediaAreaCoordinates? if let signature = reader.readInt32() { @@ -233,6 +276,25 @@ public extension Api { return nil } } + public static func parse_mediaAreaChannelPost(_ reader: BufferReader) -> MediaArea? { + var _1: Api.MediaAreaCoordinates? + if let signature = reader.readInt32() { + _1 = Api.parse(reader, signature: signature) as? Api.MediaAreaCoordinates + } + var _2: Int64? + _2 = reader.readInt64() + var _3: Int32? + _3 = reader.readInt32() + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + if _c1 && _c2 && _c3 { + return Api.MediaArea.mediaAreaChannelPost(coordinates: _1!, channelId: _2!, msgId: _3!) + } + else { + return nil + } + } public static func parse_mediaAreaGeoPoint(_ reader: BufferReader) -> MediaArea? { var _1: Api.MediaAreaCoordinates? if let signature = reader.readInt32() { diff --git a/submodules/TelegramApi/Sources/Api32.swift b/submodules/TelegramApi/Sources/Api32.swift index bbd7d3331c..64e0b329df 100644 --- a/submodules/TelegramApi/Sources/Api32.swift +++ b/submodules/TelegramApi/Sources/Api32.swift @@ -8557,20 +8557,18 @@ public extension Api.functions.stats { } } public extension Api.functions.stats { - static func getMessagePublicForwards(channel: Api.InputChannel, msgId: Int32, offsetRate: Int32, offsetPeer: Api.InputPeer, offsetId: Int32, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + static func getMessagePublicForwards(channel: Api.InputChannel, msgId: Int32, offset: String, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() - buffer.appendInt32(1445996571) + buffer.appendInt32(1595212100) channel.serialize(buffer, true) serializeInt32(msgId, buffer: buffer, boxed: false) - serializeInt32(offsetRate, buffer: buffer, boxed: false) - offsetPeer.serialize(buffer, true) - serializeInt32(offsetId, buffer: buffer, boxed: false) + serializeString(offset, buffer: buffer, boxed: false) serializeInt32(limit, buffer: buffer, boxed: false) - return (FunctionDescription(name: "stats.getMessagePublicForwards", parameters: [("channel", String(describing: channel)), ("msgId", String(describing: msgId)), ("offsetRate", String(describing: offsetRate)), ("offsetPeer", String(describing: offsetPeer)), ("offsetId", String(describing: offsetId)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.Messages? in + return (FunctionDescription(name: "stats.getMessagePublicForwards", parameters: [("channel", String(describing: channel)), ("msgId", String(describing: msgId)), ("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.stats.PublicForwards? in let reader = BufferReader(buffer) - var result: Api.messages.Messages? + var result: Api.stats.PublicForwards? if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.messages.Messages + result = Api.parse(reader, signature: signature) as? Api.stats.PublicForwards } return result }) diff --git a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift index 5f6a22b9a1..7d18dc225a 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift @@ -451,6 +451,8 @@ func mediaAreaFromApiMediaArea(_ mediaArea: Api.MediaArea) -> MediaArea? { } } switch mediaArea { + case .inputMediaAreaChannelPost: + return nil case .inputMediaAreaVenue: return nil case let .mediaAreaGeoPoint(coordinates, geo): @@ -490,10 +492,12 @@ func mediaAreaFromApiMediaArea(_ mediaArea: Api.MediaArea) -> MediaArea? { } else { return nil } + case let .mediaAreaChannelPost(coordinates, channelId, messageId): + return .channelMessage(coordinates: coodinatesFromApiMediaAreaCoordinates(coordinates), messageId: EngineMessage.Id(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)), namespace: Namespaces.Message.Cloud, id: messageId)) } } -func apiMediaAreasFromMediaAreas(_ mediaAreas: [MediaArea]) -> [Api.MediaArea] { +func apiMediaAreasFromMediaAreas(_ mediaAreas: [MediaArea], transaction: Transaction) -> [Api.MediaArea] { var apiMediaAreas: [Api.MediaArea] = [] for area in mediaAreas { let coordinates = area.coordinates @@ -516,6 +520,10 @@ func apiMediaAreasFromMediaAreas(_ mediaAreas: [MediaArea]) -> [Api.MediaArea] { apiFlags |= (1 << 1) } apiMediaAreas.append(.mediaAreaSuggestedReaction(flags: apiFlags, coordinates: inputCoordinates, reaction: reaction.apiReaction)) + case let .channelMessage(_, messageId): + if let peer = transaction.getPeer(messageId.peerId), let inputChannel = apiInputChannel(peer) { + apiMediaAreas.append(.inputMediaAreaChannelPost(coordinates: inputCoordinates, channel: inputChannel, msgId: messageId.id)) + } } } return apiMediaAreas diff --git a/submodules/TelegramCore/Sources/Statistics/StoryStatistics.swift b/submodules/TelegramCore/Sources/Statistics/StoryStatistics.swift index 5ab539893b..7ad981a2c4 100644 --- a/submodules/TelegramCore/Sources/Statistics/StoryStatistics.swift +++ b/submodules/TelegramCore/Sources/Statistics/StoryStatistics.swift @@ -201,8 +201,7 @@ public final class StoryStatsContext { private final class StoryStatsPublicForwardsContextImpl { private let queue: Queue private let account: Account - private let peerId: EnginePeer.Id - private let storyId: Int32 + private let subject: StoryStatsPublicForwardsContext.Subject private let disposable = MetaDisposable() private var isLoadingMore: Bool = false private var hasLoadedOnce: Bool = false @@ -213,11 +212,10 @@ private final class StoryStatsPublicForwardsContextImpl { let state = Promise() - init(queue: Queue, account: Account, peerId: EnginePeer.Id, storyId: Int32) { + init(queue: Queue, account: Account, subject: StoryStatsPublicForwardsContext.Subject) { self.queue = queue self.account = account - self.peerId = peerId - self.storyId = storyId + self.subject = subject self.count = 0 @@ -239,22 +237,41 @@ private final class StoryStatsPublicForwardsContextImpl { self.isLoadingMore = true let account = self.account let accountPeerId = account.peerId - let peerId = self.peerId - let storyId = self.storyId + let subject = self.subject let lastOffset = self.lastOffset - self.disposable.set((self.account.postbox.transaction { transaction -> (Api.InputPeer, Int32?)? in + self.disposable.set((self.account.postbox.transaction { transaction -> (Peer, Int32?)? in + let peerId: PeerId + switch subject { + case let .story(peerIdValue, _): + peerId = peerIdValue + case let .message(messageId): + peerId = messageId.peerId + } let statsDatacenterId = (transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData)?.statsDatacenterId - guard let inputPeer = transaction.getPeer(peerId).flatMap(apiInputPeer) else { + guard let peer = transaction.getPeer(peerId) else { return nil } - return (inputPeer, statsDatacenterId) + return (peer, statsDatacenterId) } |> mapToSignal { data -> Signal<([StoryStatsPublicForwardsContext.State.Forward], Int32, String?), NoError> in - if let (inputPeer, statsDatacenterId) = data { + if let (peer, statsDatacenterId) = data { let offset = lastOffset ?? "" - let request = Api.functions.stats.getStoryPublicForwards(peer: inputPeer, id: storyId, offset: offset, limit: 50) + let request: (FunctionDescription, Buffer, DeserializeFunctionResponse) + switch subject { + case let .story(_, id): + guard let inputPeer = apiInputPeer(peer) else { + return .complete() + } + request = Api.functions.stats.getStoryPublicForwards(peer: inputPeer, id: id, offset: offset, limit: 50) + case let .message(messageId): + guard let inputChannel = apiInputChannel(peer) else { + return .complete() + } + request = Api.functions.stats.getMessagePublicForwards(channel: inputChannel, msgId: messageId.id, offset: offset, limit: 50) + } + let signal: Signal if let statsDatacenterId = statsDatacenterId, account.network.datacenterId != statsDatacenterId { signal = account.network.download(datacenterId: Int(statsDatacenterId), isMedia: false, tag: nil) @@ -298,7 +315,6 @@ private final class StoryStatsPublicForwardsContextImpl { resultForwards.append(.message(EngineMessage(renderedMessage))) } case let .publicForwardStory(apiPeer, apiStory): - if let storedItem = Stories.StoredItem(apiStoryItem: apiStory, peerId: apiPeer.peerId, transaction: transaction), case let .item(item) = storedItem, let media = item.media, let peer = peers[apiPeer.peerId] { let mappedItem = EngineStoryItem( id: item.id, @@ -404,10 +420,15 @@ public final class StoryStatsPublicForwardsContext { } } - public init(account: Account, peerId: EnginePeer.Id, storyId: Int32) { + public enum Subject { + case story(peerId: EnginePeer.Id, id: Int32) + case message(messageId: EngineMessage.Id) + } + + public init(account: Account, subject: Subject) { let queue = self.queue self.impl = QueueLocalObject(queue: queue, generate: { - return StoryStatsPublicForwardsContextImpl(queue: queue, account: account, peerId: peerId, storyId: storyId) + return StoryStatsPublicForwardsContextImpl(queue: queue, account: account, subject: subject) }) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/MediaArea.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/MediaArea.swift index 6cee707abb..7f810cccac 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/MediaArea.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/MediaArea.swift @@ -124,6 +124,7 @@ public enum MediaArea: Codable, Equatable { case venue(coordinates: Coordinates, venue: Venue) case reaction(coordinates: Coordinates, reaction: MessageReaction.Reaction, flags: ReactionFlags) + case channelMessage(coordinates: Coordinates, messageId: EngineMessage.Id) public struct ReactionFlags: OptionSet { public var rawValue: Int32 @@ -144,6 +145,7 @@ public enum MediaArea: Codable, Equatable { private enum MediaAreaType: Int32 { case venue case reaction + case channelMessage } public enum DecodingError: Error { @@ -166,6 +168,10 @@ public enum MediaArea: Codable, Equatable { let reaction = try container.decode(MessageReaction.Reaction.self, forKey: .value) let flags = ReactionFlags(rawValue: try container.decodeIfPresent(Int32.self, forKey: .flags) ?? 0) self = .reaction(coordinates: coordinates, reaction: reaction, flags: flags) + case .channelMessage: + let coordinates = try container.decode(MediaArea.Coordinates.self, forKey: .coordinates) + let messageId = try container.decode(MessageId.self, forKey: .value) + self = .channelMessage(coordinates: coordinates, messageId: messageId) } } @@ -182,6 +188,10 @@ public enum MediaArea: Codable, Equatable { try container.encode(coordinates, forKey: .coordinates) try container.encode(reaction, forKey: .value) try container.encode(flags.rawValue, forKey: .flags) + case let .channelMessage(coordinates, messageId): + try container.encode(MediaAreaType.channelMessage.rawValue, forKey: .type) + try container.encode(coordinates, forKey: .coordinates) + try container.encode(messageId, forKey: .value) } } } @@ -193,6 +203,8 @@ public extension MediaArea { return coordinates case let .reaction(coordinates, _, _): return coordinates + case let .channelMessage(coordinates, _): + return coordinates } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift index 09740d2c94..2793b3d89c 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift @@ -9,7 +9,6 @@ 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) case sentMedia(tags: MessageTags?) } @@ -354,46 +353,6 @@ func _internal_searchMessages(account: Account, location: SearchMessagesLocation return .single((nil, nil)) } } - 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, statsDatacenterId) - } else { - return (inputChannel, 0, lowerBound, .inputPeerEmpty, statsDatacenterId) - } - } - |> 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 - 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) - } - } else { - signal = account.network.request(request, automaticFloodWait: false) - } - return signal - |> map { result -> (Api.messages.Messages?, Api.messages.Messages?) in - return (result, nil) - } - |> `catch` { _ -> Signal<(Api.messages.Messages?, Api.messages.Messages?), NoError> in - return .single((nil, nil)) - } - } case let .sentMedia(tags): let filter: Api.MessagesFilter = tags.flatMap { messageFilterForTagMask($0) } ?? .inputMessagesFilterEmpty diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift index 1543dfb179..53792f22db 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/Stories.swift @@ -1092,7 +1092,7 @@ func _internal_uploadStoryImpl( flags |= 1 << 4 } - let inputMediaAreas: [Api.MediaArea] = apiMediaAreasFromMediaAreas(mediaAreas) + let inputMediaAreas: [Api.MediaArea] = apiMediaAreasFromMediaAreas(mediaAreas, transaction: transaction) if !inputMediaAreas.isEmpty { flags |= 1 << 5 } @@ -1281,7 +1281,7 @@ func _internal_editStory(account: Account, peerId: PeerId, id: Int32, media: Eng flags |= 1 << 2 } - let inputMediaAreas: [Api.MediaArea]? = mediaAreas.flatMap(apiMediaAreasFromMediaAreas) + let inputMediaAreas: [Api.MediaArea]? = mediaAreas.flatMap { apiMediaAreasFromMediaAreas($0, transaction: transaction) } if let inputMediaAreas = inputMediaAreas, !inputMediaAreas.isEmpty { flags |= 1 << 3 } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/GiftCodes.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/GiftCodes.swift index 374593993a..d98c83f208 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/GiftCodes.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/GiftCodes.swift @@ -1,4 +1,5 @@ import Foundation +import Postbox import MtProtoKit import SwiftSignalKit import TelegramApi @@ -138,13 +139,19 @@ func _internal_getPremiumGiveawayInfo(account: Account, peerId: EnginePeer.Id, m } } -func _internal_premiumGiftCodeOptions(account: Account, peerId: EnginePeer.Id) -> Signal<[PremiumGiftCodeOption], NoError> { - let flags: Int32 = 1 << 0 - return account.postbox.loadedPeerWithId(peerId) - |> mapToSignal { peer in - guard let inputPeer = apiInputPeer(peer) else { - return .complete() +func _internal_premiumGiftCodeOptions(account: Account, peerId: EnginePeer.Id?) -> Signal<[PremiumGiftCodeOption], NoError> { + var flags: Int32 = 0 + if let _ = peerId { + flags |= 1 << 0 + } + return account.postbox.transaction { transaction -> Peer? in + if let peerId = peerId { + return transaction.getPeer(peerId) } + return nil + } + |> mapToSignal { peer in + let inputPeer = peer.flatMap(apiInputPeer) return account.network.request(Api.functions.payments.getPremiumGiftCodeOptions(flags: flags, boostPeer: inputPeer)) |> map(Optional.init) |> `catch` { _ -> Signal<[Api.PremiumGiftCodeOption]?, NoError> in diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift index 07cbd5e7ff..0fe3e752ca 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/TelegramEnginePayments.swift @@ -54,7 +54,7 @@ public extension TelegramEngine { return _internal_applyPremiumGiftCode(account: self.account, slug: slug) } - public func premiumGiftCodeOptions(peerId: EnginePeer.Id) -> Signal<[PremiumGiftCodeOption], NoError> { + public func premiumGiftCodeOptions(peerId: EnginePeer.Id?) -> Signal<[PremiumGiftCodeOption], NoError> { return _internal_premiumGiftCodeOptions(account: self.account, peerId: peerId) } diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift index 832c3c040a..a6aaf19c36 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerViewSendMessage.swift @@ -3273,12 +3273,12 @@ final class StoryItemSetContainerSendMessage { let theme = defaultDarkColorPresentationTheme let updatedPresentationData: (initial: PresentationData, signal: Signal) = (component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: theme), component.context.sharedContext.presentationData |> map { $0.withUpdated(theme: theme) }) + let context = component.context + var actions: [ContextMenuAction] = [] switch mediaArea { case let .venue(_, venue): let subject = EngineMessage(stableId: 0, stableVersion: 0, id: EngineMessage.Id(peerId: PeerId(0), namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 0, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: nil, text: "", attributes: [], media: [.geo(TelegramMediaMap(latitude: venue.latitude, longitude: venue.longitude, heading: nil, accuracyRadius: nil, geoPlace: nil, venue: venue.venue, liveBroadcastingTimeout: nil, liveProximityNotificationRadius: nil))], peers: [:], associatedMessages: [:], associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:]) - - let context = component.context actions.append(ContextMenuAction(content: .textWithIcon(title: updatedPresentationData.initial.strings.Story_ViewLocation, icon: generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: .white)), action: { [weak controller, weak view] in let locationController = LocationViewController( context: context, @@ -3303,6 +3303,34 @@ final class StoryItemSetContainerSendMessage { } controller?.push(locationController) })) + case let .channelMessage(_, messageId): + actions.append(ContextMenuAction(content: .textWithIcon(title: updatedPresentationData.initial.strings.Story_ViewMessage, icon: generateTintedImage(image: UIImage(bundleImageName: "Settings/TextArrowRight"), color: .white)), action: { [weak controller] in + + let _ = ((context.engine.messages.getMessagesLoadIfNecessary([messageId], strategy: .local) + |> mapToSignal { result -> Signal in + if case let .result(messages) = result { + return .single(messages.first) + } + return .single(nil) + }) + |> deliverOnMainQueue).startStandalone(next: { [weak controller] message in + guard let controller, let message else { + return + } + let _ = context.sharedContext.openChatMessage(OpenChatMessageParams(context: context, chatLocation: .peer(id: message.id.peerId), chatLocationContextHolder: nil, message: message, standalone: false, reverseMessageGalleryOrder: false, navigationController: controller.navigationController as? NavigationController, dismissInput: {}, present: { [weak controller] c, a in + controller?.present(c, in: .window(.root)) + }, transitionNode: { _, _, _ in + return nil + }, addToTransitionSurface: { _ in + }, openUrl: { _ in + }, openPeer: { _, _ in + }, callPeer: { _, _ in + }, enqueueMessage: { _ in + }, sendSticker: nil, sendEmoji: nil, setupTemporaryHiddenMedia: { _, _, _ in + }, chatAvatarHiddenMedia: { _, _ in + })) + }) + })) case .reaction: return }