mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Merge commit 'a3126f87a089aea6f6b35159c636ec14cc24a54c'
# Conflicts: # submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift # submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift
This commit is contained in:
commit
d4964e205c
@ -10663,7 +10663,7 @@ Sorry for the inconvenience.";
|
||||
|
||||
"Story.ViewList.ContextSortChannelInfo" = "Choose the order for the list of reactions.";
|
||||
|
||||
"Premium.Gift.MultipleDescription" = "Get **%1$@**%2$@ access to exclusive features with **Telegram Premium**.";
|
||||
"Premium.Gift.MultipleDescription" = "Get %1$@%2$@ access to exclusive features with **Telegram Premium**.";
|
||||
|
||||
"Premium.Gift.NamesAndMore_1" = " and %@ more";
|
||||
"Premium.Gift.NamesAndMore_any" = " and %@ more";
|
||||
@ -10684,3 +10684,5 @@ Sorry for the inconvenience.";
|
||||
"Message.GiveawayEndedWinners_1" = "%@ winner of the giveaway was randomly selected by Telegram";
|
||||
"Message.GiveawayEndedWinners_any" = "%@ winners of the giveaway was randomly selected by Telegram";
|
||||
"Message.GiveawayEndedNoWinners" = "Due to the giveaway terms, no winners could be selected by Telegram";
|
||||
|
||||
"Story.ViewMessage" = "View Message";
|
||||
|
@ -501,7 +501,7 @@ private enum CreateGiveawayEntry: ItemListNodeEntry {
|
||||
}
|
||||
})
|
||||
case let .prizeDescriptionText(_, placeholder, value, count):
|
||||
return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: "\(count)"), text: value, placeholder: placeholder, returnKeyType: .done, spacing: 24.0, tag: CreateGiveawayEntryTag.description, sectionId: self.section, textUpdated: { value in
|
||||
return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: "\(count)"), text: value, placeholder: placeholder, returnKeyType: .done, spacing: 24.0, maxLength: 128, tag: CreateGiveawayEntryTag.description, sectionId: self.section, textUpdated: { value in
|
||||
arguments.updateState { state in
|
||||
var updatedState = state
|
||||
updatedState.prizeDescription = value
|
||||
|
@ -266,7 +266,7 @@ class GiftAvatarComponent: Component {
|
||||
}
|
||||
|
||||
mergedAvatarsNode.update(context: component.context, peers: Array(component.peers.map { $0._asPeer() }.prefix(3)), synchronousLoad: false, imageSize: avatarSize.width, imageSpacing: 30.0, borderWidth: 2.0, avatarFontSize: 26.0)
|
||||
let avatarsSize = CGSize(width: avatarSize.width + 60.0, height: avatarSize.height)
|
||||
let avatarsSize = CGSize(width: avatarSize.width + 30.0 * CGFloat(min(3, component.peers.count) - 1), height: avatarSize.height)
|
||||
mergedAvatarsNode.updateLayout(size: avatarsSize)
|
||||
mergedAvatarsNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - avatarsSize.width) / 2.0), y: 113.0 - avatarSize.height / 2.0), size: avatarsSize)
|
||||
self.avatarNode.isHidden = true
|
||||
|
@ -222,7 +222,7 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
|
||||
} else {
|
||||
names.append(environment.strings.CreateGroup_PeersTitleLastDelimeter)
|
||||
}
|
||||
names.append(context.component.peers[i].compactDisplayTitle)
|
||||
names.append("**\(context.component.peers[i].compactDisplayTitle)**")
|
||||
}
|
||||
descriptionString = environment.strings.Premium_Gift_MultipleDescription(names, "").string
|
||||
} else {
|
||||
@ -233,10 +233,9 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
|
||||
} else {
|
||||
names.append(environment.strings.CreateGroup_PeersTitleDelimeter)
|
||||
}
|
||||
names.append(context.component.peers[i].compactDisplayTitle)
|
||||
names.append("**\(context.component.peers[i].compactDisplayTitle)**")
|
||||
}
|
||||
let more = environment.strings.Premium_Gift_NamesAndMore(Int32(context.component.peers.count - 3))
|
||||
|
||||
descriptionString = environment.strings.Premium_Gift_MultipleDescription(names, more).string
|
||||
}
|
||||
} else {
|
||||
@ -996,7 +995,7 @@ private final class PremiumGiftScreenComponent: CombinedComponent {
|
||||
|
||||
let price: String?
|
||||
if let products = state.products, let selectedProductId = state.selectedProductId, let product = products.first(where: { $0.id == selectedProductId }) {
|
||||
price = product.price
|
||||
price = product.storeProduct.multipliedPrice(count: context.component.peerIds.count)
|
||||
} else {
|
||||
price = nil
|
||||
}
|
||||
|
@ -1130,6 +1130,8 @@ public final class SolidRoundedButtonView: UIView {
|
||||
strongSelf.iconNode.alpha = 0.55
|
||||
strongSelf.animationNode?.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.animationNode?.alpha = 0.55
|
||||
strongSelf.badgeNode?.layer.removeAnimation(forKey: "opacity")
|
||||
strongSelf.badgeNode?.alpha = 0.55
|
||||
} else {
|
||||
if strongSelf.buttonBackgroundNode.alpha > 0.0 {
|
||||
strongSelf.buttonBackgroundNode.alpha = 1.0
|
||||
@ -1142,6 +1144,8 @@ public final class SolidRoundedButtonView: UIView {
|
||||
strongSelf.iconNode.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
strongSelf.animationNode?.alpha = 1.0
|
||||
strongSelf.animationNode?.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
strongSelf.badgeNode?.alpha = 1.0
|
||||
strongSelf.badgeNode?.layer.animateAlpha(from: 0.55, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<PostStats?>(nil)
|
||||
let messagesPromise = Promise<(SearchMessagesResult, SearchMessagesState)?>(nil)
|
||||
let forwardsPromise = Promise<StoryStatsPublicForwardsContext.State?>(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
|
||||
@ -359,10 +335,9 @@ public func messageStatsController(context: AccountContext, updatedPresentationD
|
||||
dataPromise.set(.single(nil) |> then(dataSignal))
|
||||
anyStatsContext = statsContext
|
||||
|
||||
messagesPromise.set(.single(nil))
|
||||
forwardsContext = StoryStatsPublicForwardsContext(account: context.account, subject: .story(peerId: peerId, id: id))
|
||||
}
|
||||
|
||||
forwardsContext = StoryStatsPublicForwardsContext(account: context.account, peerId: peerId, storyId: id)
|
||||
if let forwardsContext {
|
||||
forwardsPromise.set(
|
||||
.single(nil)
|
||||
|> then(
|
||||
@ -370,10 +345,6 @@ public func messageStatsController(context: AccountContext, updatedPresentationD
|
||||
|> map(Optional.init)
|
||||
)
|
||||
)
|
||||
} else {
|
||||
forwardsPromise.set(.single(nil))
|
||||
}
|
||||
}
|
||||
|
||||
let arguments = MessageStatsControllerArguments(context: context, loadDetailedGraph: { graph, x -> Signal<StatsGraph?, NoError> in
|
||||
return loadDetailedGraphImpl?(graph, x) ?? .single(nil)
|
||||
@ -413,13 +384,12 @@ public func messageStatsController(context: AccountContext, updatedPresentationD
|
||||
let signal = combineLatest(
|
||||
presentationData,
|
||||
dataPromise.get(),
|
||||
messagesPromise.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()
|
||||
}
|
||||
}
|
||||
|
@ -451,7 +451,9 @@ func mediaAreaFromApiMediaArea(_ mediaArea: Api.MediaArea) -> MediaArea? {
|
||||
}
|
||||
}
|
||||
switch mediaArea {
|
||||
case .inputMediaAreaVenue, .inputMediaAreaChannelPost:
|
||||
case .inputMediaAreaChannelPost:
|
||||
return nil
|
||||
case .inputMediaAreaVenue:
|
||||
return nil
|
||||
case let .mediaAreaGeoPoint(coordinates, geo):
|
||||
let latitude: Double
|
||||
@ -490,12 +492,12 @@ func mediaAreaFromApiMediaArea(_ mediaArea: Api.MediaArea) -> MediaArea? {
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case .mediaAreaChannelPost:
|
||||
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
|
||||
@ -518,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
|
||||
|
@ -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<StoryStatsPublicForwardsContext.State>()
|
||||
|
||||
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<Api.stats.PublicForwards>)
|
||||
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<Api.stats.PublicForwards, MTRpcError>
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,50 +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()
|
||||
}
|
||||
|
||||
//TODO
|
||||
let _ = inputChannel
|
||||
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 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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -8730,6 +8730,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
case .premium:
|
||||
self.controller?.push(PremiumIntroScreen(context: self.context, modal: false, source: .settings))
|
||||
case .premiumGift:
|
||||
let options = Promise<[PremiumGiftCodeOption]>()
|
||||
options.set(self.context.engine.payments.premiumGiftCodeOptions(peerId: nil))
|
||||
|
||||
let controller = self.context.sharedContext.makeContactMultiselectionController(ContactMultiselectionControllerParams(context: self.context, mode: .premiumGifting, options: [], isPeerEnabled: { peer in
|
||||
if case let .user(user) = peer, user.botInfo == nil {
|
||||
return true
|
||||
@ -8738,8 +8741,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
}
|
||||
}))
|
||||
self.controller?.push(controller)
|
||||
self.activeActionDisposable.set((controller.result
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self, weak controller] result in
|
||||
self.activeActionDisposable.set(combineLatest(queue: Queue.mainQueue(), controller.result, options.get())
|
||||
.startStrict(next: { [weak self, weak controller] result, options in
|
||||
guard let self, let controller else {
|
||||
return
|
||||
}
|
||||
@ -8762,7 +8765,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
return
|
||||
}
|
||||
|
||||
let giftController = PremiumGiftScreen(context: self.context, peerIds: peerIds, options: [], source: .settings, pushController: { [weak self] c in
|
||||
let mappedOptions = options.filter { $0.users == 1 }.map { CachedPremiumGiftOption(months: $0.months, currency: $0.currency, amount: $0.amount, botUrl: "", storeProductId: $0.storeProductId) }
|
||||
|
||||
let giftController = PremiumGiftScreen(context: self.context, peerIds: peerIds, options: mappedOptions, source: .settings, pushController: { [weak self] c in
|
||||
self?.controller?.push(c)
|
||||
}, completion: { [weak self] in
|
||||
if let self, let navigationController = self.controller?.navigationController as? NavigationController, peerIds.count == 1, let peerId = peerIds.first {
|
||||
|
@ -3273,12 +3273,12 @@ final class StoryItemSetContainerSendMessage {
|
||||
let theme = defaultDarkColorPresentationTheme
|
||||
let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>) = (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<Message?, NoError> 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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user