no message

This commit is contained in:
Peter
2017-03-21 19:58:26 +03:00
parent 1ae775b2f4
commit 5278f451f1
5 changed files with 222 additions and 42 deletions

View File

@@ -270,8 +270,6 @@
D07827CB1E02F5B200071108 /* RichText.swift in Sources */ = {isa = PBXBuildFile; fileRef = D07827CA1E02F5B200071108 /* RichText.swift */; };
D08774FC1E3E39F600A97350 /* ManagedGlobalNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08774FB1E3E39F600A97350 /* ManagedGlobalNotificationSettings.swift */; };
D08774FE1E3E3A3500A97350 /* GlobalNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08774FD1E3E3A3500A97350 /* GlobalNotificationSettings.swift */; };
D08F4A631E79C7B800A2AA15 /* StickerViewTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A621E79C7B800A2AA15 /* StickerViewTracker.swift */; };
D08F4A641E79C7B800A2AA15 /* StickerViewTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A621E79C7B800A2AA15 /* StickerViewTracker.swift */; };
D08F4A661E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */; };
D08F4A671E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */; };
D08F4A691E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D08F4A681E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift */; };
@@ -632,7 +630,6 @@
D07827CA1E02F5B200071108 /* RichText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RichText.swift; sourceTree = "<group>"; };
D08774FB1E3E39F600A97350 /* ManagedGlobalNotificationSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedGlobalNotificationSettings.swift; sourceTree = "<group>"; };
D08774FD1E3E3A3500A97350 /* GlobalNotificationSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalNotificationSettings.swift; sourceTree = "<group>"; };
D08F4A621E79C7B800A2AA15 /* StickerViewTracker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerViewTracker.swift; sourceTree = "<group>"; };
D08F4A651E79CC4A00A2AA15 /* SynchronizeInstalledStickerPacksOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizeInstalledStickerPacksOperations.swift; sourceTree = "<group>"; };
D08F4A681E79CECB00A2AA15 /* ManagedSynchronizeInstalledStickerPacksOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedSynchronizeInstalledStickerPacksOperations.swift; sourceTree = "<group>"; };
D099EA1B1DE72867001AF5A8 /* PeerCommands.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerCommands.swift; sourceTree = "<group>"; };
@@ -1044,7 +1041,6 @@
D049EAF41E44DF3300A2CD3A /* AccountState.swift */,
D03B0D621D631A8B00955575 /* AccountSettings.swift */,
D03B0D631D631A8B00955575 /* AccountViewTracker.swift */,
D08F4A621E79C7B800A2AA15 /* StickerViewTracker.swift */,
D03B0D641D631A8B00955575 /* RecentPeers.swift */,
D0AB0B911D65E9FA002C78E7 /* ManagedServiceViews.swift */,
D0AB0B931D662ECE002C78E7 /* ManagedMessageHistoryHoles.swift */,
@@ -1640,7 +1636,6 @@
D0528E651E65C82400E2FEF5 /* UpdateContactName.swift in Sources */,
D03121021DA57E93006A2A60 /* TelegramPeerNotificationSettings.swift in Sources */,
D0C48F391E8138DF0075317D /* ArchivedStickerPacksInfo.swift in Sources */,
D08F4A631E79C7B800A2AA15 /* StickerViewTracker.swift in Sources */,
D03B0CBB1D62233C00955575 /* MergeLists.swift in Sources */,
C239BE971E62EE1E00C2C453 /* LoadMessagesIfNecessary.swift in Sources */,
D03B0CC11D62235000955575 /* StringFormat.swift in Sources */,
@@ -1867,7 +1862,6 @@
D0528E661E65C82400E2FEF5 /* UpdateContactName.swift in Sources */,
D0F7B1E81E045C87007EB8A5 /* PeerParticipants.swift in Sources */,
D0C48F3A1E8138DF0075317D /* ArchivedStickerPacksInfo.swift in Sources */,
D08F4A641E79C7B800A2AA15 /* StickerViewTracker.swift in Sources */,
D049EAD61E43D98500A2CD3A /* RecentMediaItem.swift in Sources */,
D0B844331DAB91E0005F29E1 /* NBPhoneNumber.m in Sources */,
D001F3F51E128A1C007A8C60 /* PendingMessageManager.swift in Sources */,

View File

@@ -15,8 +15,16 @@ public struct PendingMessageStatus: Equatable {
}
}
private enum PendingMessageState {
case none
case waitingForUploadToStart(Signal<PendingMessageUploadedContentResult, NoError>)
case uploading
case sending
}
private final class PendingMessageContext {
var disposable: MetaDisposable?
var state: PendingMessageState = .none
let disposable = MetaDisposable()
var status: PendingMessageStatus?
var statusSubscribers = Bag<(PendingMessageStatus?) -> Void>()
}
@@ -74,10 +82,12 @@ public final class PendingMessageManager {
let addedMessageIds = messageIds.subtracting(self.pendingMessageIds)
let removedMessageIds = self.pendingMessageIds.subtracting(messageIds)
var updateUploadingPeerIds = Set<PeerId>()
for id in removedMessageIds {
if let context = self.messageContexts[id] {
context.disposable?.dispose()
context.disposable = nil
context.state = .none
updateUploadingPeerIds.insert(id.peerId)
context.disposable.dispose()
if context.statusSubscribers.isEmpty {
self.messageContexts.removeValue(forKey: id)
}
@@ -89,6 +99,12 @@ public final class PendingMessageManager {
}
self.pendingMessageIds = messageIds
if !updateUploadingPeerIds.isEmpty {
for peerId in updateUploadingPeerIds {
self.updateWaitingUploads(peerId: peerId)
}
}
}
}
@@ -102,7 +118,6 @@ public final class PendingMessageManager {
messageContext = current
} else {
messageContext = PendingMessageContext()
messageContext.disposable = MetaDisposable()
self.messageContexts[id] = messageContext
}
@@ -116,7 +131,7 @@ public final class PendingMessageManager {
self.queue.async {
if let current = self.messageContexts[id] {
current.statusSubscribers.remove(index)
if current.statusSubscribers.isEmpty && current.disposable == nil {
if case .none = current.status, current.statusSubscribers.isEmpty {
self.messageContexts.removeValue(forKey: id)
}
}
@@ -128,6 +143,24 @@ public final class PendingMessageManager {
}
}
private func canBeginUploadingMessage(id: MessageId) -> Bool {
assert(self.queue.isCurrent())
let messageIdsForPeer: [MessageId] = self.messageContexts.keys.filter({ $0.peerId == id.peerId }).sorted()
for contextId in messageIdsForPeer {
if contextId < id {
let context = self.messageContexts[contextId]!
if case .uploading = context.state {
return false
}
} else {
break
}
}
return true
}
private func beginSendingMessages(_ ids: [MessageId]) {
assert(self.queue.isCurrent())
@@ -137,7 +170,6 @@ public final class PendingMessageManager {
messageContext = current
} else {
messageContext = PendingMessageContext()
messageContext.disposable = MetaDisposable()
self.messageContexts[id] = messageContext
}
@@ -163,7 +195,7 @@ public final class PendingMessageManager {
if let strongSelf = self {
assert(strongSelf.queue.isCurrent())
for message in messages {
for message in messages.sorted(by: { $0.id < $1.id }) {
guard let messageContext = strongSelf.messageContexts[message.id] else {
continue
}
@@ -172,7 +204,20 @@ public final class PendingMessageManager {
continue
}
let uploadedContent = uploadedMessageContent(network: strongSelf.network, postbox: strongSelf.postbox, transformOutgoingMessageMedia: strongSelf.transformOutgoingMessageMedia, message: message)
let contentToUpload = messageContentToUpload(network: strongSelf.network, postbox: strongSelf.postbox, transformOutgoingMessageMedia: strongSelf.transformOutgoingMessageMedia, message: message)
switch contentToUpload {
case let .ready(message, content):
strongSelf.beginSendingMessage(messageContext: messageContext, message: message, content: content)
case let .upload(uploadSignal):
if strongSelf.canBeginUploadingMessage(id: message.id) {
strongSelf.beginUploadingMessage(messageContext: messageContext, id: message.id, uploadSignal: uploadSignal)
} else {
messageContext.state = .waitingForUploadToStart(uploadSignal)
}
}
/*let uploadedContent = uploadedMessageContent(network: strongSelf.network, postbox: strongSelf.postbox, transformOutgoingMessageMedia: strongSelf.transformOutgoingMessageMedia, message: message)
let sendMessage = uploadedContent
|> mapToSignal { contentResult -> Signal<PendingMessageResult, NoError> in
@@ -191,11 +236,10 @@ public final class PendingMessageManager {
}
}
messageContext.disposable?.set((sendMessage |> deliverOn(strongSelf.queue) |> afterDisposed {
messageContext.disposable.set((sendMessage |> deliverOn(strongSelf.queue) |> afterDisposed {
if let strongSelf = self {
assert(strongSelf.queue.isCurrent())
if let current = strongSelf.messageContexts[message.id] {
current.disposable = nil
for subscriber in current.statusSubscribers.copyItems() {
subscriber(nil)
}
@@ -219,12 +263,130 @@ public final class PendingMessageManager {
}
}
}
}))
}))*/
}
}
}))
}
private func beginSendingMessage(messageContext: PendingMessageContext, message: Message, content: PendingMessageUploadedContent) {
messageContext.state = .sending
let sendMessage: Signal<PendingMessageResult, NoError> = self.sendMessageContent(network: self.network, postbox: self.postbox, stateManager: self.stateManager, message: message, content: content)
|> map { next -> PendingMessageResult in
return .progress(1.0)
}
messageContext.disposable.set((sendMessage |> deliverOn(self.queue) |> afterDisposed { [weak self] in
if let strongSelf = self {
assert(strongSelf.queue.isCurrent())
if let current = strongSelf.messageContexts[message.id] {
current.status = .none
for subscriber in current.statusSubscribers.copyItems() {
subscriber(nil)
}
if current.statusSubscribers.isEmpty {
strongSelf.messageContexts.removeValue(forKey: message.id)
}
}
}
}).start(next: { [weak self] next in
if let strongSelf = self {
assert(strongSelf.queue.isCurrent())
switch next {
case let .progress(progress):
if let current = strongSelf.messageContexts[message.id] {
let status = PendingMessageStatus(progress: progress)
current.status = status
for subscriber in current.statusSubscribers.copyItems() {
subscriber(status)
}
}
}
}
}))
}
private func beginUploadingMessage(messageContext: PendingMessageContext, id: MessageId, uploadSignal: Signal<PendingMessageUploadedContentResult, NoError>) {
messageContext.state = .uploading
messageContext.disposable.set((uploadSignal |> deliverOn(self.queue)).start(next: { [weak self] next in
if let strongSelf = self {
assert(strongSelf.queue.isCurrent())
switch next {
case let .progress(progress):
if let current = strongSelf.messageContexts[id] {
let status = PendingMessageStatus(progress: progress)
current.status = status
for subscriber in current.statusSubscribers.copyItems() {
subscriber(status)
}
}
case let .content(message, content):
if let current = strongSelf.messageContexts[id] {
strongSelf.beginSendingMessage(messageContext: current, message: message, content: content)
strongSelf.updateWaitingUploads(peerId: id.peerId)
}
}
}
}))
}
private func updateWaitingUploads(peerId: PeerId) {
assert(self.queue.isCurrent())
let messageIdsForPeer: [MessageId] = self.messageContexts.keys.filter({ $0.peerId == peerId }).sorted()
loop: for contextId in messageIdsForPeer {
let context = self.messageContexts[contextId]!
if case let .waitingForUploadToStart(uploadSignal) = context.state {
if self.canBeginUploadingMessage(id: contextId) {
context.state = .uploading
context.disposable.set((uploadSignal |> deliverOn(self.queue)).start(next: { [weak self] next in
if let strongSelf = self {
assert(strongSelf.queue.isCurrent())
switch next {
case let .progress(progress):
if let current = strongSelf.messageContexts[contextId] {
let status = PendingMessageStatus(progress: progress)
current.status = status
for subscriber in current.statusSubscribers.copyItems() {
subscriber(status)
}
}
case let .content(message, content):
if let current = strongSelf.messageContexts[message.id] {
current.state = .sending
current.disposable.set((strongSelf.sendMessageContent(network: strongSelf.network, postbox: strongSelf.postbox, stateManager: strongSelf.stateManager, message: message, content: content)
|> map { next -> PendingMessageResult in
return .progress(1.0)
}).start(next: { next in
if let strongSelf = self {
assert(strongSelf.queue.isCurrent())
switch next {
case let .progress(progress):
if let current = strongSelf.messageContexts[message.id] {
let status = PendingMessageStatus(progress: progress)
current.status = status
for subscriber in current.statusSubscribers.copyItems() {
subscriber(status)
}
}
}
}
}))
}
}
}
}))
}
break loop
}
}
}
private func sendMessageContent(network: Network, postbox: Postbox, stateManager: AccountStateManager, message: Message, content: PendingMessageUploadedContent) -> Signal<Void, NoError> {
return postbox.modify { [weak self] modifier -> Signal<Void, NoError> in
if message.id.peerId.namespace == Namespaces.Peer.SecretChat {

View File

@@ -20,6 +20,54 @@ enum PendingMessageUploadedContentResult {
case content(Message, PendingMessageUploadedContent)
}
enum PendingMessageUploadContent {
case ready(Message, PendingMessageUploadedContent)
case upload(Signal<PendingMessageUploadedContentResult, NoError>)
}
func messageContentToUpload(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, message: Message) -> PendingMessageUploadContent {
var outgoingChatContextResultAttribute: OutgoingChatContextResultMessageAttribute?
for attribute in message.attributes {
if let attribute = attribute as? OutgoingChatContextResultMessageAttribute {
outgoingChatContextResultAttribute = attribute
}
}
if let _ = message.forwardInfo {
var forwardSourceInfo: ForwardSourceInfoAttribute?
for attribute in message.attributes {
if let attribute = attribute as? ForwardSourceInfoAttribute {
forwardSourceInfo = attribute
}
}
if let forwardSourceInfo = forwardSourceInfo {
return .ready(message, .forward(forwardSourceInfo))
} else {
assertionFailure()
return .ready(message, .text(message.text))
}
} else if let outgoingChatContextResultAttribute = outgoingChatContextResultAttribute {
return .ready(message, .chatContextResult(outgoingChatContextResultAttribute))
} else if let media = message.media.first {
if let image = media as? TelegramMediaImage, let _ = largestImageRepresentation(image.representations) {
return .upload(uploadedMediaImageContent(network: network, postbox: postbox, image: image, message: message))
} else if let file = media as? TelegramMediaFile {
if let resource = file.resource as? CloudDocumentMediaResource {
return .ready(message, .media(Api.InputMedia.inputMediaDocument(id: Api.InputDocument.inputDocument(id: resource.fileId, accessHash: resource.accessHash), caption: message.text)))
} else {
return .upload(uploadedMediaFileContent(network: network, postbox: postbox, transformOutgoingMessageMedia: transformOutgoingMessageMedia, file: file, message: message))
}
} else if let contact = media as? TelegramMediaContact {
let input = Api.InputMedia.inputMediaContact(phoneNumber: contact.phoneNumber, firstName: contact.firstName, lastName: contact.lastName)
return .ready(message, .media(input))
} else {
return .ready(message, .text(message.text))
}
} else {
return .ready(message, .text(message.text))
}
}
func uploadedMessageContent(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, message: Message) -> Signal<PendingMessageUploadedContentResult, NoError> {
var outgoingChatContextResultAttribute: OutgoingChatContextResultMessageAttribute?
for attribute in message.attributes {

View File

@@ -1,24 +0,0 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
import MtProtoKitMac
#else
import Postbox
import SwiftSignalKit
import MtProtoKitDynamic
#endif
final class StickerViewTracker {
private let postbox: Postbox
private let mediaBox: MediaBox
init(postbox: Postbox, mediaBox: MediaBox) {
self.postbox = postbox
self.mediaBox = mediaBox
}
func wrappedStickerInfosView() -> Signal<CombinedView, NoError> {
return self.postbox.combinedView(keys: [.itemCollectionInfos(namespaces: [Namespaces.ItemCollection.CloudStickerPacks])])
}
}

View File

@@ -45,7 +45,7 @@ public final class TelegramMediaImage: Media, Equatable {
for i in 0 ..< self.representations.count {
let representationDimensions = self.representations[i].dimensions
if dimensions.width >= size.width - CGFloat(FLT_EPSILON) && dimensions.height >= size.height - CGFloat(FLT_EPSILON) {
if dimensions.width >= size.width - CGFloat.ulpOfOne && dimensions.height >= size.height - CGFloat.ulpOfOne {
if representationDimensions.width >= size.width && representationDimensions.height >= dimensions.height && representationDimensions.width < dimensions.width && representationDimensions.height < dimensions.height {
dimensions = representationDimensions
index = i