mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Demo video processing
This commit is contained in:
parent
25251fc9d4
commit
71b035e6d1
@ -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()
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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?) {
|
||||||
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user