Demo video processing

This commit is contained in:
Isaac 2024-10-15 17:23:24 +04:00
parent 25251fc9d4
commit 71b035e6d1
7 changed files with 448 additions and 132 deletions

View File

@ -442,6 +442,12 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode {
self.targetSelectionIndex = nil self.targetSelectionIndex = nil
icon = nil icon = nil
isUserInteractionEnabled = action != nil isUserInteractionEnabled = action != nil
case .videoProcessing:
self.action = nil
self.text = "The video will be published once converted and optimized."
self.targetSelectionIndex = nil
icon = nil
isUserInteractionEnabled = action != nil
} }
self.iconNode = ASImageNode() self.iconNode = ASImageNode()

View File

@ -2350,6 +2350,7 @@ public final class ContextController: ViewController, StandalonePresentableContr
case animatedEmoji(text: String?, arguments: TextNodeWithEntities.Arguments?, file: TelegramMediaFile?, action: (() -> Void)?) case animatedEmoji(text: String?, arguments: TextNodeWithEntities.Arguments?, file: TelegramMediaFile?, action: (() -> Void)?)
case notificationTopicExceptions(text: String, action: (() -> Void)?) case notificationTopicExceptions(text: String, action: (() -> Void)?)
case starsReactions(topCount: Int) case starsReactions(topCount: Int)
case videoProcessing
public static func ==(lhs: Tip, rhs: Tip) -> Bool { public static func ==(lhs: Tip, rhs: Tip) -> Bool {
switch lhs { switch lhs {
@ -2401,6 +2402,12 @@ public final class ContextController: ViewController, StandalonePresentableContr
} else { } else {
return false return false
} }
case .videoProcessing:
if case .videoProcessing = rhs {
return true
} else {
return false
}
} }
} }
} }

View File

@ -95,6 +95,20 @@ public func stringForMessageTimestampStatus(accountPeerId: PeerId, message: Mess
dateText = " " dateText = " "
} }
//TODO:release
//TODO:localize
if "".isEmpty, let channel = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = channel.info {
for media in message.media {
if let file = media as? TelegramMediaFile, file.isVideo, !file.isInstantVideo, !file.isAnimated {
if message.id.namespace == Namespaces.Message.ScheduledCloud {
return "appx. \(dateText)"
} else if message.id.namespace == Namespaces.Message.ScheduledLocal {
return "processing"
}
}
}
}
if displayFullDate { if displayFullDate {
let dayText: String let dayText: String

View File

@ -1120,9 +1120,16 @@ extension ChatControllerImpl {
self.chatDisplayNode.setupSendActionOnViewUpdate = { [weak self] f, messageCorrelationId in self.chatDisplayNode.setupSendActionOnViewUpdate = { [weak self] f, messageCorrelationId in
//print("setup layoutActionOnViewTransition") //print("setup layoutActionOnViewTransition")
self?.chatDisplayNode.historyNode.layoutActionOnViewTransition = ({ [weak self] transition in guard let self else {
return
}
self.layoutActionOnViewTransitionAction = f
self.chatDisplayNode.historyNode.layoutActionOnViewTransition = ({ [weak self] transition in
f() f()
if let strongSelf = self, let validLayout = strongSelf.validLayout { if let strongSelf = self, let validLayout = strongSelf.validLayout {
strongSelf.layoutActionOnViewTransitionAction = nil
var mappedTransition: (ChatHistoryListViewTransition, ListViewUpdateSizeAndInsets?)? var mappedTransition: (ChatHistoryListViewTransition, ListViewUpdateSizeAndInsets?)?
let isScheduledMessages: Bool let isScheduledMessages: Bool
@ -1262,35 +1269,127 @@ extension ChatControllerImpl {
} }
} }
let signal: Signal<[MessageId?], NoError> let _ = (strongSelf.shouldDivertMessagesToScheduled(messages: transformedMessages)
if forwardSourcePeerIds.count > 1 { |> deliverOnMainQueue).start(next: { shouldDivert in
var signals: [Signal<[MessageId?], NoError>] = [] let signal: Signal<[MessageId?], NoError>
for messagesGroup in forwardedMessages { var stayInThisChat = false
signals.append(enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messagesGroup)) var shouldOpenScheduledMessages = false
} if forwardSourcePeerIds.count > 1 {
signal = combineLatest(signals) var forwardedMessages = forwardedMessages
|> map { results in if shouldDivert {
var ids: [MessageId?] = [] forwardedMessages = forwardedMessages.map { messageGroup -> [EnqueueMessage] in
for result in results { return messageGroup.map { message -> EnqueueMessage in
ids.append(contentsOf: result) return message.withUpdatedAttributes { attributes in
var attributes = attributes
attributes.removeAll(where: { $0 is OutgoingScheduleInfoMessageAttribute })
attributes.append(OutgoingScheduleInfoMessageAttribute(scheduleTime: Int32(Date().timeIntervalSince1970) + 10 * 24 * 60 * 60))
return attributes
}
}
}
shouldOpenScheduledMessages = true
} }
return ids
}
} else {
signal = enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: transformedMessages)
}
let _ = (signal var signals: [Signal<[MessageId?], NoError>] = []
|> deliverOnMainQueue).startStandalone(next: { messageIds in for messagesGroup in forwardedMessages {
if let strongSelf = self { signals.append(enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messagesGroup))
}
signal = combineLatest(signals)
|> map { results in
var ids: [MessageId?] = []
for result in results {
ids.append(contentsOf: result)
}
return ids
}
stayInThisChat = true
} else {
var transformedMessages = transformedMessages
if shouldDivert {
transformedMessages = transformedMessages.map { message -> EnqueueMessage in
return message.withUpdatedAttributes { attributes in
var attributes = attributes
attributes.removeAll(where: { $0 is OutgoingScheduleInfoMessageAttribute })
attributes.append(OutgoingScheduleInfoMessageAttribute(scheduleTime: Int32(Date().timeIntervalSince1970) + 10 * 24 * 60 * 60))
return attributes
}
}
shouldOpenScheduledMessages = true
}
signal = enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: transformedMessages)
}
let _ = (signal
|> deliverOnMainQueue).startStandalone(next: { messageIds in
guard let strongSelf = self else {
return
}
if case .scheduledMessages = strongSelf.presentationInterfaceState.subject { if case .scheduledMessages = strongSelf.presentationInterfaceState.subject {
} else { } else {
strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory() strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory()
}
}
})
donateSendMessageIntent(account: strongSelf.context.account, sharedContext: strongSelf.context.sharedContext, intentContext: .chat, peerIds: [peerId]) if shouldOpenScheduledMessages {
if let layoutActionOnViewTransitionAction = strongSelf.layoutActionOnViewTransitionAction {
strongSelf.layoutActionOnViewTransitionAction = nil
layoutActionOnViewTransitionAction()
}
if stayInThisChat {
strongSelf.dismissAllUndoControllers()
//TODO:localize
strongSelf.present(
UndoOverlayController(
presentationData: strongSelf.presentationData,
content: .info(
title: "Improving video...",
text: "The video will be published after it's optimized for the bese viewing experience.",
timeout: 8.0,
customUndoText: nil
),
elevatedLayout: false,
position: .top,
action: { _ in
return true
}
),
in: .current
)
} else {
strongSelf.openScheduledMessages(force: true, completion: { c in
guard let self else {
return
}
c.dismissAllUndoControllers()
//TODO:localize
c.present(
UndoOverlayController(
presentationData: self.presentationData,
content: .info(
title: "Improving video...",
text: "The video will be published after it's optimized for the bese viewing experience.",
timeout: 8.0,
customUndoText: nil
),
elevatedLayout: false,
position: .top,
action: { _ in
return true
}
),
in: .current
)
})
}
}
}
})
donateSendMessageIntent(account: strongSelf.context.account, sharedContext: strongSelf.context.sharedContext, intentContext: .chat, peerIds: [peerId])
})
} else if case let .customChatContents(customChatContents) = strongSelf.subject { } else if case let .customChatContents(customChatContents) = strongSelf.subject {
switch customChatContents.kind { switch customChatContents.kind {
case .hashTagSearch: case .hashTagSearch:

View File

@ -106,6 +106,16 @@ extension ChatControllerImpl {
} }
} }
//TODO:release
//TODO:localize
if "".isEmpty, let channel = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = channel.info {
for media in message.media {
if let file = media as? TelegramMediaFile, file.isVideo, !file.isInstantVideo, !file.isAnimated {
tip = .videoProcessing
}
}
}
if actions.tip == nil { if actions.tip == nil {
actions.tip = tip actions.tip = tip
} }

View File

@ -641,6 +641,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
} }
var layoutActionOnViewTransitionAction: (() -> Void)?
public init( public init(
context: AccountContext, context: AccountContext,
chatLocation: ChatLocation, chatLocation: ChatLocation,
@ -9114,6 +9116,55 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
} }
func shouldDivertMessagesToScheduled(targetPeer: EnginePeer? = nil, messages: [EnqueueMessage]) -> Signal<Bool, NoError> {
guard let peer = targetPeer?._asPeer() ?? self.presentationInterfaceState.renderedPeer?.peer else {
return .single(false)
}
if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
} else {
return .single(false)
}
//TODO:release
if !"".isEmpty {
return .single(false)
}
var forwardMessageIds: [EngineMessage.Id] = []
for message in messages {
if case let .message(_, _, _, mediaReference, _, _, _, _, _, _) = message, let media = mediaReference?.media {
if let file = media as? TelegramMediaFile, file.isVideo && !file.isInstantVideo && !file.isAnimated {
return .single(true)
}
} else if case let .forward(sourceId, _, _, _, _) = message {
forwardMessageIds.append(sourceId)
}
}
if forwardMessageIds.isEmpty {
return .single(false)
} else {
return self.context.engine.data.get(
EngineDataList(forwardMessageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init(id:)))
)
|> map { messages -> Bool in
for message in messages {
guard let message else {
continue
}
for media in message.media {
if let file = media as? TelegramMediaFile, file.isVideo && !file.isInstantVideo && !file.isAnimated {
return true
}
}
}
return false
}
}
}
func sendMessages(_ messages: [EnqueueMessage], media: Bool = false, commit: Bool = false) { func sendMessages(_ messages: [EnqueueMessage], media: Bool = false, commit: Bool = false) {
if case let .customChatContents(customChatContents) = self.subject { if case let .customChatContents(customChatContents) = self.subject {
customChatContents.enqueueMessages(messages: messages) customChatContents.enqueueMessages(messages: messages)
@ -9124,37 +9175,101 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return return
} }
var isScheduledMessages = false let _ = (self.shouldDivertMessagesToScheduled(messages: messages)
if case .scheduledMessages = self.presentationInterfaceState.subject { |> deliverOnMainQueue).startStandalone(next: { [weak self] shouldDivert in
isScheduledMessages = true guard let self else {
} return
}
if commit || !isScheduledMessages { var messages = messages
self.commitPurposefulAction() var shouldOpenScheduledMessages = false
let _ = (enqueueMessages(account: self.context.account, peerId: peerId, messages: self.transformEnqueueMessages(messages)) if shouldDivert {
|> deliverOnMainQueue).startStandalone(next: { [weak self] _ in messages = messages.map { message -> EnqueueMessage in
if let strongSelf = self, strongSelf.presentationInterfaceState.subject != .scheduledMessages { return message.withUpdatedAttributes { attributes in
strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory() var attributes = attributes
attributes.removeAll(where: { $0 is OutgoingScheduleInfoMessageAttribute })
attributes.append(OutgoingScheduleInfoMessageAttribute(scheduleTime: Int32(Date().timeIntervalSince1970) + 10 * 24 * 60 * 60))
return attributes
}
} }
}) shouldOpenScheduledMessages = true
}
donateSendMessageIntent(account: self.context.account, sharedContext: self.context.sharedContext, intentContext: .chat, peerIds: [peerId]) var isScheduledMessages = false
if case .scheduledMessages = self.presentationInterfaceState.subject {
isScheduledMessages = true
}
self.updateChatPresentationInterfaceState(interactive: true, { $0.updatedShowCommands(false) }) if commit || !isScheduledMessages {
} else { self.commitPurposefulAction()
self.presentScheduleTimePicker(style: media ? .media : .default, dismissByTapOutside: false, completion: { [weak self] time in
if let strongSelf = self { let _ = (enqueueMessages(account: self.context.account, peerId: peerId, messages: self.transformEnqueueMessages(messages))
strongSelf.sendMessages(strongSelf.transformEnqueueMessages(messages, silentPosting: false, scheduleTime: time), commit: true) |> deliverOnMainQueue).startStandalone(next: { [weak self] _ in
if let strongSelf = self, strongSelf.presentationInterfaceState.subject != .scheduledMessages {
strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory()
}
})
donateSendMessageIntent(account: self.context.account, sharedContext: self.context.sharedContext, intentContext: .chat, peerIds: [peerId])
self.updateChatPresentationInterfaceState(interactive: true, { $0.updatedShowCommands(false) })
if !isScheduledMessages && shouldOpenScheduledMessages {
if let layoutActionOnViewTransitionAction = self.layoutActionOnViewTransitionAction {
self.layoutActionOnViewTransitionAction = nil
layoutActionOnViewTransitionAction()
}
self.openScheduledMessages(force: true, completion: { [weak self] c in
guard let self else {
return
}
c.dismissAllUndoControllers()
//TODO:localize
c.present(
UndoOverlayController(
presentationData: self.presentationData,
content: .info(
title: "Improving video...",
text: "The video will be published after it's optimized for the bese viewing experience.",
timeout: 8.0,
customUndoText: nil
),
elevatedLayout: false,
position: .top,
action: { _ in
return true
}
),
in: .current
)
})
} }
}) } else {
} self.presentScheduleTimePicker(style: media ? .media : .default, dismissByTapOutside: false, completion: { [weak self] time in
if let strongSelf = self {
strongSelf.sendMessages(strongSelf.transformEnqueueMessages(messages, silentPosting: false, scheduleTime: time), commit: true)
}
})
}
})
} }
func enqueueMediaMessages(signals: [Any]?, silentPosting: Bool, scheduleTime: Int32? = nil, parameters: ChatSendMessageActionSheetController.SendParameters? = nil, getAnimatedTransitionSource: ((String) -> UIView?)? = nil, completion: @escaping () -> Void = {}) { func enqueueMediaMessages(signals: [Any]?, silentPosting: Bool, scheduleTime: Int32? = nil, parameters: ChatSendMessageActionSheetController.SendParameters? = nil, getAnimatedTransitionSource: ((String) -> UIView?)? = nil, completion: @escaping () -> Void = {}) {
self.enqueueMediaMessageDisposable.set((legacyAssetPickerEnqueueMessages(context: self.context, account: self.context.account, signals: signals!) self.enqueueMediaMessageDisposable.set((legacyAssetPickerEnqueueMessages(context: self.context, account: self.context.account, signals: signals!)
|> deliverOnMainQueue).startStrict(next: { [weak self] items in |> deliverOnMainQueue).startStrict(next: { [weak self] items in
if let strongSelf = self { guard let strongSelf = self else {
return
}
let _ = (strongSelf.shouldDivertMessagesToScheduled(messages: items.map(\.message))
|> deliverOnMainQueue).startStandalone(next: { shouldDivert in
guard let strongSelf = self else {
return
}
var completionImpl: (() -> Void)? = completion var completionImpl: (() -> Void)? = completion
var usedCorrelationId: Int64? var usedCorrelationId: Int64?
@ -9166,6 +9281,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var skipAddingTransitions = false var skipAddingTransitions = false
if shouldDivert {
skipAddingTransitions = true
}
for item in items { for item in items {
var message = item.message var message = item.message
if message.groupingKey != nil { if message.groupingKey != nil {
@ -9289,7 +9408,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let _ = scheduleTime { if let _ = scheduleTime {
completion() completion()
} }
} })
})) }))
} }
@ -10384,8 +10503,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
} }
func openScheduledMessages() { func openScheduledMessages(force: Bool = false, completion: @escaping (ChatControllerImpl) -> Void = { _ in }) {
guard let navigationController = self.effectiveNavigationController, navigationController.topViewController == self else { guard let navigationController = self.effectiveNavigationController else {
return
}
if navigationController.topViewController == self || force {
} else {
return return
} }
@ -10396,7 +10519,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let controller = ChatControllerImpl(context: self.context, chatLocation: mappedChatLocation, subject: .scheduledMessages) let controller = ChatControllerImpl(context: self.context, chatLocation: mappedChatLocation, subject: .scheduledMessages)
controller.navigationPresentation = .modal controller.navigationPresentation = .modal
navigationController.pushViewController(controller) navigationController.pushViewController(controller, completion: { [weak controller] in
if let controller {
completion(controller)
}
})
} }
func openPinnedMessages(at messageId: MessageId?) { func openPinnedMessages(at messageId: MessageId?) {

View File

@ -122,6 +122,9 @@ extension ChatControllerImpl {
}) })
let commit: ([EnqueueMessage]) -> Void = { result in let commit: ([EnqueueMessage]) -> Void = { result in
guard let strongSelf = self else {
return
}
var result = result var result = result
strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }).updatedSearch(nil) }) strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }).updatedSearch(nil) })
@ -133,96 +136,146 @@ extension ChatControllerImpl {
result[i] = result[i].withUpdatedCorrelationId(correlationId) result[i] = result[i].withUpdatedCorrelationId(correlationId)
} }
var displayPeers: [EnginePeer] = [] let targetPeersShouldDivertSignals: [Signal<(EnginePeer, Bool), NoError>] = peers.map { peer -> Signal<(EnginePeer, Bool), NoError> in
for peer in peers { return strongSelf.shouldDivertMessagesToScheduled(targetPeer: peer, messages: result)
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: result) |> map { shouldDivert -> (EnginePeer, Bool) in
|> deliverOnMainQueue).startStandalone(next: { messageIds in return (peer, shouldDivert)
if let strongSelf = self {
let signals: [Signal<Bool, NoError>] = messageIds.compactMap({ id -> Signal<Bool, NoError>? in
guard let id = id else {
return nil
}
return strongSelf.context.account.pendingMessageManager.pendingMessageStatus(id)
|> mapToSignal { status, _ -> Signal<Bool, NoError> in
if status != nil {
return .never()
} else {
return .single(true)
}
}
|> take(1)
})
if strongSelf.shareStatusDisposable == nil {
strongSelf.shareStatusDisposable = MetaDisposable()
}
strongSelf.shareStatusDisposable?.set((combineLatest(signals)
|> deliverOnMainQueue).startStrict())
}
})
if case let .secretChat(secretPeer) = peer {
if let peer = peerMap[secretPeer.regularPeerId] {
displayPeers.append(peer)
}
} else {
displayPeers.append(peer)
} }
} }
let targetPeersShouldDivert: Signal<[(EnginePeer, Bool)], NoError> = combineLatest(targetPeersShouldDivertSignals)
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } let _ = (targetPeersShouldDivert
let text: String |> deliverOnMainQueue).startStandalone(next: { targetPeersShouldDivert in
var savedMessages = false guard let strongSelf = self else {
if displayPeers.count == 1, let peerId = displayPeers.first?.id, peerId == strongSelf.context.account.peerId {
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many
savedMessages = true
} else {
if displayPeers.count == 1, let peer = displayPeers.first {
var peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
peerName = peerName.replacingOccurrences(of: "**", with: "")
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string : presentationData.strings.Conversation_ForwardTooltip_Chat_Many(peerName).string
} else if displayPeers.count == 2, let firstPeer = displayPeers.first, let secondPeer = displayPeers.last {
var firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
firstPeerName = firstPeerName.replacingOccurrences(of: "**", with: "")
var secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
secondPeerName = secondPeerName.replacingOccurrences(of: "**", with: "")
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.Conversation_ForwardTooltip_TwoChats_Many(firstPeerName, secondPeerName).string
} else if let peer = displayPeers.first {
var peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
peerName = peerName.replacingOccurrences(of: "**", with: "")
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(displayPeers.count - 1)").string : presentationData.strings.Conversation_ForwardTooltip_ManyChats_Many(peerName, "\(displayPeers.count - 1)").string
} else {
text = ""
}
}
let reactionItems: Signal<[ReactionItem], NoError>
if savedMessages && messages.count > 0 {
reactionItems = tagMessageReactions(context: strongSelf.context, subPeerId: nil)
} else {
reactionItems = .single([])
}
let _ = (reactionItems
|> deliverOnMainQueue).startStandalone(next: { [weak strongSelf] reactionItems in
guard let strongSelf else {
return return
} }
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, position: savedMessages && messages.count > 0 ? .top : .bottom, animateInAsReplacement: true, action: { action in var displayConvertingTooltip = false
if savedMessages, let self, action == .info {
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId)) var displayPeers: [EnginePeer] = []
|> deliverOnMainQueue).start(next: { [weak self] peer in for (peer, shouldDivert) in targetPeersShouldDivert {
guard let self, let peer else { var peerMessages = result
return if shouldDivert {
displayConvertingTooltip = true
peerMessages = peerMessages.map { message -> EnqueueMessage in
return message.withUpdatedAttributes { attributes in
var attributes = attributes
attributes.removeAll(where: { $0 is OutgoingScheduleInfoMessageAttribute })
attributes.append(OutgoingScheduleInfoMessageAttribute(scheduleTime: Int32(Date().timeIntervalSince1970) + 10 * 24 * 60 * 60))
return attributes
} }
guard let navigationController = self.navigationController as? NavigationController else { }
return
}
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), forceOpenChat: true))
})
} }
return false
}, additionalView: (savedMessages && messages.count > 0) ? chatShareToSavedMessagesAdditionalView(strongSelf, reactionItems: reactionItems, correlationIds: correlationIds) : nil), in: .current) let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: peerMessages)
|> deliverOnMainQueue).startStandalone(next: { messageIds in
if let strongSelf = self {
let signals: [Signal<Bool, NoError>] = messageIds.compactMap({ id -> Signal<Bool, NoError>? in
guard let id = id else {
return nil
}
return strongSelf.context.account.pendingMessageManager.pendingMessageStatus(id)
|> mapToSignal { status, _ -> Signal<Bool, NoError> in
if status != nil {
return .never()
} else {
return .single(true)
}
}
|> take(1)
})
if strongSelf.shareStatusDisposable == nil {
strongSelf.shareStatusDisposable = MetaDisposable()
}
strongSelf.shareStatusDisposable?.set((combineLatest(signals)
|> deliverOnMainQueue).startStrict())
}
})
if case let .secretChat(secretPeer) = peer {
if let peer = peerMap[secretPeer.regularPeerId] {
displayPeers.append(peer)
}
} else {
displayPeers.append(peer)
}
}
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let text: String
var savedMessages = false
if displayPeers.count == 1, let peerId = displayPeers.first?.id, peerId == strongSelf.context.account.peerId {
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many
savedMessages = true
} else {
if displayPeers.count == 1, let peer = displayPeers.first {
var peerName = peer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
peerName = peerName.replacingOccurrences(of: "**", with: "")
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string : presentationData.strings.Conversation_ForwardTooltip_Chat_Many(peerName).string
} else if displayPeers.count == 2, let firstPeer = displayPeers.first, let secondPeer = displayPeers.last {
var firstPeerName = firstPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
firstPeerName = firstPeerName.replacingOccurrences(of: "**", with: "")
var secondPeerName = secondPeer.id == strongSelf.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
secondPeerName = secondPeerName.replacingOccurrences(of: "**", with: "")
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.Conversation_ForwardTooltip_TwoChats_Many(firstPeerName, secondPeerName).string
} else if let peer = displayPeers.first {
var peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
peerName = peerName.replacingOccurrences(of: "**", with: "")
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(displayPeers.count - 1)").string : presentationData.strings.Conversation_ForwardTooltip_ManyChats_Many(peerName, "\(displayPeers.count - 1)").string
} else {
text = ""
}
}
let reactionItems: Signal<[ReactionItem], NoError>
if savedMessages && messages.count > 0 {
reactionItems = tagMessageReactions(context: strongSelf.context, subPeerId: nil)
} else {
reactionItems = .single([])
}
let _ = (reactionItems
|> deliverOnMainQueue).startStandalone(next: { [weak strongSelf] reactionItems in
guard let strongSelf else {
return
}
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, position: savedMessages && messages.count > 0 ? .top : .bottom, animateInAsReplacement: true, action: { action in
if savedMessages, let self, action == .info {
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: self.context.account.peerId))
|> deliverOnMainQueue).start(next: { [weak self] peer in
guard let self, let peer else {
return
}
guard let navigationController = self.navigationController as? NavigationController else {
return
}
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), forceOpenChat: true))
})
}
return false
}, additionalView: (savedMessages && messages.count > 0) ? chatShareToSavedMessagesAdditionalView(strongSelf, reactionItems: reactionItems, correlationIds: correlationIds) : nil), in: .current)
})
if displayConvertingTooltip {
//TODO:localize
strongSelf.present(
UndoOverlayController(
presentationData: strongSelf.presentationData,
content: .info(
title: "Improving video...",
text: "The video will be published after it's optimized for the bese viewing experience.",
timeout: 8.0,
customUndoText: nil
),
elevatedLayout: false,
position: .top,
action: { _ in
return true
}
),
in: .current
)
}
}) })
} }