mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
178 lines
8.0 KiB
Swift
178 lines
8.0 KiB
Swift
import Foundation
|
|
import SwiftSignalKit
|
|
import Postbox
|
|
|
|
private final class PendingUpdateMessageContext {
|
|
var value: ChatUpdatingMessageMedia
|
|
let disposable: Disposable
|
|
|
|
init(value: ChatUpdatingMessageMedia, disposable: Disposable) {
|
|
self.value = value
|
|
self.disposable = disposable
|
|
}
|
|
}
|
|
|
|
private final class PendingUpdateMessageManagerImpl {
|
|
let queue: Queue
|
|
let postbox: Postbox
|
|
let network: Network
|
|
let stateManager: AccountStateManager
|
|
let messageMediaPreuploadManager: MessageMediaPreuploadManager
|
|
let mediaReferenceRevalidationContext: MediaReferenceRevalidationContext
|
|
|
|
var transformOutgoingMessageMedia: TransformOutgoingMessageMedia?
|
|
|
|
private var updatingMessageMediaValue: [MessageId: ChatUpdatingMessageMedia] = [:] {
|
|
didSet {
|
|
if self.updatingMessageMediaValue != oldValue {
|
|
self.updatingMessageMediaPromise.set(.single(self.updatingMessageMediaValue))
|
|
}
|
|
}
|
|
}
|
|
private let updatingMessageMediaPromise = Promise<[MessageId: ChatUpdatingMessageMedia]>()
|
|
var updatingMessageMedia: Signal<[MessageId: ChatUpdatingMessageMedia], NoError> {
|
|
return self.updatingMessageMediaPromise.get()
|
|
}
|
|
|
|
private var contexts: [MessageId: PendingUpdateMessageContext] = [:]
|
|
|
|
private let errorsPipe = ValuePipe<(MessageId, RequestEditMessageError)>()
|
|
var errors: Signal<(MessageId, RequestEditMessageError), NoError> {
|
|
return self.errorsPipe.signal()
|
|
}
|
|
|
|
init(queue: Queue, postbox: Postbox, network: Network, stateManager: AccountStateManager, messageMediaPreuploadManager: MessageMediaPreuploadManager, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext) {
|
|
self.queue = queue
|
|
self.postbox = postbox
|
|
self.network = network
|
|
self.stateManager = stateManager
|
|
self.messageMediaPreuploadManager = messageMediaPreuploadManager
|
|
self.mediaReferenceRevalidationContext = mediaReferenceRevalidationContext
|
|
|
|
self.updatingMessageMediaPromise.set(.single(self.updatingMessageMediaValue))
|
|
}
|
|
|
|
deinit {
|
|
for (_, context) in self.contexts {
|
|
context.disposable.dispose()
|
|
}
|
|
}
|
|
|
|
private func updateValues() {
|
|
self.updatingMessageMediaValue = self.contexts.mapValues { context in
|
|
return context.value
|
|
}
|
|
}
|
|
|
|
func add(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute?, invertMediaAttribute: InvertMediaMessageAttribute?, disableUrlPreview: Bool) {
|
|
if let context = self.contexts[messageId] {
|
|
self.contexts.removeValue(forKey: messageId)
|
|
context.disposable.dispose()
|
|
}
|
|
|
|
let disposable = MetaDisposable()
|
|
let context = PendingUpdateMessageContext(value: ChatUpdatingMessageMedia(text: text, entities: entities, disableUrlPreview: disableUrlPreview, media: media, progress: 0.0), disposable: disposable)
|
|
self.contexts[messageId] = context
|
|
|
|
let queue = self.queue
|
|
disposable.set((requestEditMessage(accountPeerId: self.stateManager.accountPeerId, postbox: self.postbox, network: self.network, stateManager: self.stateManager, transformOutgoingMessageMedia: self.transformOutgoingMessageMedia, messageMediaPreuploadManager: self.messageMediaPreuploadManager, mediaReferenceRevalidationContext: self.mediaReferenceRevalidationContext, messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, disableUrlPreview: disableUrlPreview, scheduleTime: nil, invertMediaAttribute: invertMediaAttribute)
|
|
|> deliverOn(self.queue)).start(next: { [weak self, weak context] value in
|
|
queue.async {
|
|
guard let strongSelf = self, let initialContext = context else {
|
|
return
|
|
}
|
|
if let context = strongSelf.contexts[messageId], context === initialContext {
|
|
switch value {
|
|
case .done:
|
|
strongSelf.contexts.removeValue(forKey: messageId)
|
|
context.disposable.dispose()
|
|
strongSelf.updateValues()
|
|
case let .progress(progress):
|
|
context.value = context.value.withProgress(progress)
|
|
strongSelf.updateValues()
|
|
}
|
|
}
|
|
}
|
|
}, error: { [weak self, weak context] error in
|
|
queue.async {
|
|
guard let strongSelf = self, let initialContext = context else {
|
|
return
|
|
}
|
|
if let context = strongSelf.contexts[messageId], context === initialContext {
|
|
strongSelf.contexts.removeValue(forKey: messageId)
|
|
context.disposable.dispose()
|
|
strongSelf.updateValues()
|
|
}
|
|
|
|
strongSelf.errorsPipe.putNext((messageId, error))
|
|
}
|
|
}))
|
|
}
|
|
|
|
func cancel(messageId: MessageId) {
|
|
if let context = self.contexts[messageId] {
|
|
self.contexts.removeValue(forKey: messageId)
|
|
context.disposable.dispose()
|
|
|
|
self.updateValues()
|
|
}
|
|
}
|
|
}
|
|
|
|
public final class PendingUpdateMessageManager {
|
|
private let queue = Queue()
|
|
private let impl: QueueLocalObject<PendingUpdateMessageManagerImpl>
|
|
|
|
var transformOutgoingMessageMedia: TransformOutgoingMessageMedia? {
|
|
didSet {
|
|
let transformOutgoingMessageMedia = self.transformOutgoingMessageMedia
|
|
self.impl.with { impl in
|
|
impl.transformOutgoingMessageMedia = transformOutgoingMessageMedia
|
|
}
|
|
}
|
|
}
|
|
|
|
public var updatingMessageMedia: Signal<[MessageId: ChatUpdatingMessageMedia], NoError> {
|
|
return Signal { subscriber in
|
|
let disposable = MetaDisposable()
|
|
self.impl.with { impl in
|
|
disposable.set(impl.updatingMessageMedia.start(next: { value in
|
|
subscriber.putNext(value)
|
|
}))
|
|
}
|
|
return disposable
|
|
}
|
|
}
|
|
|
|
public var errors: Signal<(MessageId, RequestEditMessageError), NoError> {
|
|
return Signal { subscriber in
|
|
let disposable = MetaDisposable()
|
|
self.impl.with { impl in
|
|
disposable.set(impl.errors.start(next: { value in
|
|
subscriber.putNext(value)
|
|
}))
|
|
}
|
|
return disposable
|
|
}
|
|
}
|
|
|
|
init(postbox: Postbox, network: Network, stateManager: AccountStateManager, messageMediaPreuploadManager: MessageMediaPreuploadManager, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext) {
|
|
let queue = self.queue
|
|
self.impl = QueueLocalObject(queue: queue, generate: {
|
|
return PendingUpdateMessageManagerImpl(queue: queue, postbox: postbox, network: network, stateManager: stateManager, messageMediaPreuploadManager: messageMediaPreuploadManager, mediaReferenceRevalidationContext: mediaReferenceRevalidationContext)
|
|
})
|
|
}
|
|
|
|
public func add(messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute?, inlineStickers: [MediaId: Media], webpagePreviewAttribute: WebpagePreviewMessageAttribute? = nil, invertMediaAttribute: InvertMediaMessageAttribute? = nil, disableUrlPreview: Bool = false) {
|
|
self.impl.with { impl in
|
|
impl.add(messageId: messageId, text: text, media: media, entities: entities, inlineStickers: inlineStickers, webpagePreviewAttribute: webpagePreviewAttribute, invertMediaAttribute: invertMediaAttribute, disableUrlPreview: disableUrlPreview)
|
|
}
|
|
}
|
|
|
|
public func cancel(messageId: MessageId) {
|
|
self.impl.with { impl in
|
|
impl.cancel(messageId: messageId)
|
|
}
|
|
}
|
|
}
|