no message

This commit is contained in:
Peter
2017-03-28 21:45:26 +03:00
parent c55a138e0b
commit 71ff550bcc
12 changed files with 216 additions and 264 deletions

View File

@@ -243,6 +243,8 @@
D0561DE41E5737FC00E6B9E9 /* UpdatePeerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0561DE21E5737FC00E6B9E9 /* UpdatePeerInfo.swift */; }; D0561DE41E5737FC00E6B9E9 /* UpdatePeerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0561DE21E5737FC00E6B9E9 /* UpdatePeerInfo.swift */; };
D0561DEA1E5754FA00E6B9E9 /* ChannelAdmins.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0561DE91E5754FA00E6B9E9 /* ChannelAdmins.swift */; }; D0561DEA1E5754FA00E6B9E9 /* ChannelAdmins.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0561DE91E5754FA00E6B9E9 /* ChannelAdmins.swift */; };
D0561DEB1E5754FA00E6B9E9 /* ChannelAdmins.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0561DE91E5754FA00E6B9E9 /* ChannelAdmins.swift */; }; D0561DEB1E5754FA00E6B9E9 /* ChannelAdmins.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0561DE91E5754FA00E6B9E9 /* ChannelAdmins.swift */; };
D058E0D11E8AD65C00A442DE /* StandaloneSendMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D058E0D01E8AD65C00A442DE /* StandaloneSendMessage.swift */; };
D058E0D21E8AD65C00A442DE /* StandaloneSendMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D058E0D01E8AD65C00A442DE /* StandaloneSendMessage.swift */; };
D05A32E11E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E01E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift */; }; D05A32E11E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E01E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift */; };
D05A32E21E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E01E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift */; }; D05A32E21E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E01E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift */; };
D05A32E41E6F0B2E002760B4 /* RecentAccountSessions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E31E6F0B2E002760B4 /* RecentAccountSessions.swift */; }; D05A32E41E6F0B2E002760B4 /* RecentAccountSessions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05A32E31E6F0B2E002760B4 /* RecentAccountSessions.swift */; };
@@ -624,6 +626,7 @@
D05452061E7B5093006EEF19 /* LoadedStickerPack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadedStickerPack.swift; sourceTree = "<group>"; }; D05452061E7B5093006EEF19 /* LoadedStickerPack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadedStickerPack.swift; sourceTree = "<group>"; };
D0561DE21E5737FC00E6B9E9 /* UpdatePeerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdatePeerInfo.swift; sourceTree = "<group>"; }; D0561DE21E5737FC00E6B9E9 /* UpdatePeerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdatePeerInfo.swift; sourceTree = "<group>"; };
D0561DE91E5754FA00E6B9E9 /* ChannelAdmins.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelAdmins.swift; sourceTree = "<group>"; }; D0561DE91E5754FA00E6B9E9 /* ChannelAdmins.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelAdmins.swift; sourceTree = "<group>"; };
D058E0D01E8AD65C00A442DE /* StandaloneSendMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StandaloneSendMessage.swift; sourceTree = "<group>"; };
D05A32E01E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdatedAccountPrivacySettings.swift; sourceTree = "<group>"; }; D05A32E01E6F0982002760B4 /* UpdatedAccountPrivacySettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdatedAccountPrivacySettings.swift; sourceTree = "<group>"; };
D05A32E31E6F0B2E002760B4 /* RecentAccountSessions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentAccountSessions.swift; sourceTree = "<group>"; }; D05A32E31E6F0B2E002760B4 /* RecentAccountSessions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentAccountSessions.swift; sourceTree = "<group>"; };
D05A32E61E6F0B5C002760B4 /* RecentAccountSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentAccountSession.swift; sourceTree = "<group>"; }; D05A32E61E6F0B5C002760B4 /* RecentAccountSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecentAccountSession.swift; sourceTree = "<group>"; };
@@ -1013,6 +1016,7 @@
D0E23DD91E806F7700B9B6D2 /* ManagedSynchronizeMarkFeaturedStickerPacksAsSeenOperations.swift */, D0E23DD91E806F7700B9B6D2 /* ManagedSynchronizeMarkFeaturedStickerPacksAsSeenOperations.swift */,
D0F3A89E1E82C65400B4C64C /* SynchronizeChatInputStateOperation.swift */, D0F3A89E1E82C65400B4C64C /* SynchronizeChatInputStateOperation.swift */,
D0F3A8A11E82C65E00B4C64C /* ManagedSynchronizeChatInputStateOperations.swift */, D0F3A8A11E82C65E00B4C64C /* ManagedSynchronizeChatInputStateOperations.swift */,
D058E0D01E8AD65C00A442DE /* StandaloneSendMessage.swift */,
); );
name = State; name = State;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1642,6 +1646,7 @@
D0B843C71DA7FF30005F29E1 /* NBPhoneNumberDefines.m in Sources */, D0B843C71DA7FF30005F29E1 /* NBPhoneNumberDefines.m in Sources */,
D049EAF51E44DF3300A2CD3A /* AccountState.swift in Sources */, D049EAF51E44DF3300A2CD3A /* AccountState.swift in Sources */,
D03B0D5D1D631A6900955575 /* MultipartFetch.swift in Sources */, D03B0D5D1D631A6900955575 /* MultipartFetch.swift in Sources */,
D058E0D11E8AD65C00A442DE /* StandaloneSendMessage.swift in Sources */,
D0BC38751E40A7F70044D6FE /* RemovePeerChat.swift in Sources */, D0BC38751E40A7F70044D6FE /* RemovePeerChat.swift in Sources */,
D0AB0B961D662F0B002C78E7 /* ManagedChatListHoles.swift in Sources */, D0AB0B961D662F0B002C78E7 /* ManagedChatListHoles.swift in Sources */,
D05A32E41E6F0B2E002760B4 /* RecentAccountSessions.swift in Sources */, D05A32E41E6F0B2E002760B4 /* RecentAccountSessions.swift in Sources */,
@@ -1881,6 +1886,7 @@
D0F7B1E41E045C7B007EB8A5 /* InstantPage.swift in Sources */, D0F7B1E41E045C7B007EB8A5 /* InstantPage.swift in Sources */,
D03E5E0D1E55E02D0029569A /* LoggedOutAccountAttribute.swift in Sources */, D03E5E0D1E55E02D0029569A /* LoggedOutAccountAttribute.swift in Sources */,
D0B418AD1D7E0597004562A4 /* Serialization.swift in Sources */, D0B418AD1D7E0597004562A4 /* Serialization.swift in Sources */,
D058E0D21E8AD65C00A442DE /* StandaloneSendMessage.swift in Sources */,
D03C536F1DAD5CA9004C17B3 /* BotInfo.swift in Sources */, D03C536F1DAD5CA9004C17B3 /* BotInfo.swift in Sources */,
D0FA8BBA1E2240B4001E855B /* SecretChatIncomingDecryptedOperation.swift in Sources */, D0FA8BBA1E2240B4001E855B /* SecretChatIncomingDecryptedOperation.swift in Sources */,
D033FEB41E61F3C000644997 /* ReportPeer.swift in Sources */, D033FEB41E61F3C000644997 /* ReportPeer.swift in Sources */,

View File

@@ -145,7 +145,7 @@ public class UnauthorizedAccount {
postbox.removeKeychainEntryForKey(key) postbox.removeKeychainEntryForKey(key)
}) })
return initializedNetwork(apiId: self.apiId, datacenterId: Int(masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: self.basePath), testingEnvironment: self.testingEnvironment) return initializedNetwork(apiId: self.apiId, supplementary: false, datacenterId: Int(masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: self.basePath), testingEnvironment: self.testingEnvironment)
|> map { network in |> map { network in
let updated = UnauthorizedAccount(apiId: self.apiId, id: self.id, appGroupPath: self.appGroupPath, basePath: self.basePath, testingEnvironment: self.testingEnvironment, postbox: self.postbox, network: network) let updated = UnauthorizedAccount(apiId: self.apiId, id: self.id, appGroupPath: self.appGroupPath, basePath: self.basePath, testingEnvironment: self.testingEnvironment, postbox: self.postbox, network: network)
updated.shouldBeServiceTaskMaster.set(self.shouldBeServiceTaskMaster.get()) updated.shouldBeServiceTaskMaster.set(self.shouldBeServiceTaskMaster.get())
@@ -183,7 +183,6 @@ private var declaredEncodables: Void = {
declareEncodable(CachedChannelData.self, f: { CachedChannelData(decoder: $0) }) declareEncodable(CachedChannelData.self, f: { CachedChannelData(decoder: $0) })
declareEncodable(TelegramUserPresence.self, f: { TelegramUserPresence(decoder: $0) }) declareEncodable(TelegramUserPresence.self, f: { TelegramUserPresence(decoder: $0) })
declareEncodable(LocalFileMediaResource.self, f: { LocalFileMediaResource(decoder: $0) }) declareEncodable(LocalFileMediaResource.self, f: { LocalFileMediaResource(decoder: $0) })
declareEncodable(PhotoLibraryMediaResource.self, f: { PhotoLibraryMediaResource(decoder: $0) })
declareEncodable(StickerPackCollectionInfo.self, f: { StickerPackCollectionInfo(decoder: $0) }) declareEncodable(StickerPackCollectionInfo.self, f: { StickerPackCollectionInfo(decoder: $0) })
declareEncodable(StickerPackItem.self, f: { StickerPackItem(decoder: $0) }) declareEncodable(StickerPackItem.self, f: { StickerPackItem(decoder: $0) })
declareEncodable(LocalFileReferenceMediaResource.self, f: { LocalFileReferenceMediaResource(decoder: $0) }) declareEncodable(LocalFileReferenceMediaResource.self, f: { LocalFileReferenceMediaResource(decoder: $0) })
@@ -231,7 +230,7 @@ private func accountRecordIdPathName(_ id: AccountRecordId) -> String {
return "account-\(UInt64(bitPattern: id.int64))" return "account-\(UInt64(bitPattern: id.int64))"
} }
public func accountWithId(apiId: Int32, id: AccountRecordId, appGroupPath: String, testingEnvironment: Bool, auxiliaryMethods: AccountAuxiliaryMethods, shouldKeepAutoConnection: Bool = true) -> Signal<Either<UnauthorizedAccount, Account>, NoError> { public func accountWithId(apiId: Int32, id: AccountRecordId, supplementary: Bool, appGroupPath: String, testingEnvironment: Bool, auxiliaryMethods: AccountAuxiliaryMethods, shouldKeepAutoConnection: Bool = true) -> Signal<Either<UnauthorizedAccount, Account>, NoError> {
return Signal<(String, Postbox, Coding?), NoError> { subscriber in return Signal<(String, Postbox, Coding?), NoError> { subscriber in
let _ = declaredEncodables let _ = declaredEncodables
@@ -265,12 +264,12 @@ public func accountWithId(apiId: Int32, id: AccountRecordId, appGroupPath: Strin
if let accountState = accountState { if let accountState = accountState {
switch accountState { switch accountState {
case let unauthorizedState as UnauthorizedAccountState: case let unauthorizedState as UnauthorizedAccountState:
return initializedNetwork(apiId: apiId, datacenterId: Int(unauthorizedState.masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment) return initializedNetwork(apiId: apiId, supplementary: supplementary, datacenterId: Int(unauthorizedState.masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment)
|> map { network -> Either<UnauthorizedAccount, Account> in |> map { network -> Either<UnauthorizedAccount, Account> in
.left(value: UnauthorizedAccount(apiId: apiId, id: id, appGroupPath: appGroupPath, basePath: basePath, testingEnvironment: testingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection)) .left(value: UnauthorizedAccount(apiId: apiId, id: id, appGroupPath: appGroupPath, basePath: basePath, testingEnvironment: testingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection))
} }
case let authorizedState as AuthorizedAccountState: case let authorizedState as AuthorizedAccountState:
return initializedNetwork(apiId: apiId, datacenterId: Int(authorizedState.masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment) return initializedNetwork(apiId: apiId, supplementary: supplementary, datacenterId: Int(authorizedState.masterDatacenterId), keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment)
|> map { network -> Either<UnauthorizedAccount, Account> in |> map { network -> Either<UnauthorizedAccount, Account> in
return .right(value: Account(id: id, basePath: basePath, testingEnvironment: testingEnvironment, postbox: postbox, network: network, peerId: authorizedState.peerId, auxiliaryMethods: auxiliaryMethods)) return .right(value: Account(id: id, basePath: basePath, testingEnvironment: testingEnvironment, postbox: postbox, network: network, peerId: authorizedState.peerId, auxiliaryMethods: auxiliaryMethods))
} }
@@ -279,7 +278,7 @@ public func accountWithId(apiId: Int32, id: AccountRecordId, appGroupPath: Strin
} }
} }
return initializedNetwork(apiId: apiId, datacenterId: 2, keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment) return initializedNetwork(apiId: apiId, supplementary: supplementary, datacenterId: 2, keychain: keychain, networkUsageInfoPath: accountNetworkUsageInfoPath(basePath: basePath), testingEnvironment: testingEnvironment)
|> map { network -> Either<UnauthorizedAccount, Account> in |> map { network -> Either<UnauthorizedAccount, Account> in
return .left(value: UnauthorizedAccount(apiId: apiId, id: id, appGroupPath: appGroupPath, basePath: basePath, testingEnvironment: testingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection)) return .left(value: UnauthorizedAccount(apiId: apiId, id: id, appGroupPath: appGroupPath, basePath: basePath, testingEnvironment: testingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection))
} }

View File

@@ -14,7 +14,7 @@ private enum AccountKind {
case unauthorized case unauthorized
} }
public func currentAccount(apiId: Int32, manager: AccountManager, appGroupPath: String, testingEnvironment: Bool, auxiliaryMethods: AccountAuxiliaryMethods) -> Signal<Either<UnauthorizedAccount, Account>?, NoError> { public func currentAccount(apiId: Int32, supplementary: Bool, manager: AccountManager, appGroupPath: String, testingEnvironment: Bool, auxiliaryMethods: AccountAuxiliaryMethods) -> Signal<Either<UnauthorizedAccount, Account>?, NoError> {
return manager.allocatedCurrentAccountId() return manager.allocatedCurrentAccountId()
|> distinctUntilChanged(isEqual: { lhs, rhs in |> distinctUntilChanged(isEqual: { lhs, rhs in
return lhs == rhs return lhs == rhs
@@ -23,7 +23,7 @@ public func currentAccount(apiId: Int32, manager: AccountManager, appGroupPath:
if let id = id { if let id = id {
let reload = ValuePromise<Bool>(true, ignoreRepeated: false) let reload = ValuePromise<Bool>(true, ignoreRepeated: false)
return reload.get() |> mapToSignal { _ -> Signal<Either<UnauthorizedAccount, Account>?, NoError> in return reload.get() |> mapToSignal { _ -> Signal<Either<UnauthorizedAccount, Account>?, NoError> in
return accountWithId(apiId: apiId, id: id, appGroupPath: appGroupPath, testingEnvironment: testingEnvironment, auxiliaryMethods: auxiliaryMethods) return accountWithId(apiId: apiId, id: id, supplementary: supplementary, appGroupPath: appGroupPath, testingEnvironment: testingEnvironment, auxiliaryMethods: auxiliaryMethods)
|> mapToSignal { account -> Signal<Either<UnauthorizedAccount, Account>?, NoError> in |> mapToSignal { account -> Signal<Either<UnauthorizedAccount, Account>?, NoError> in
let postbox: Postbox let postbox: Postbox
let initialKind: AccountKind let initialKind: AccountKind
@@ -151,7 +151,7 @@ public func managedCleanupAccounts(apiId: Int32, accountManager: AccountManager,
private func cleanupAccount(apiId: Int32, accountManager: AccountManager, id: AccountRecordId, appGroupPath: String, auxiliaryMethods: AccountAuxiliaryMethods) -> Signal<Void, NoError> { private func cleanupAccount(apiId: Int32, accountManager: AccountManager, id: AccountRecordId, appGroupPath: String, auxiliaryMethods: AccountAuxiliaryMethods) -> Signal<Void, NoError> {
return accountWithId(apiId: apiId, id: id, appGroupPath: appGroupPath, testingEnvironment: false, auxiliaryMethods: auxiliaryMethods) return accountWithId(apiId: apiId, id: id, supplementary: true, appGroupPath: appGroupPath, testingEnvironment: false, auxiliaryMethods: auxiliaryMethods)
|> mapToSignal { account -> Signal<Void, NoError> in |> mapToSignal { account -> Signal<Void, NoError> in
switch account { switch account {
case .left: case .left:

View File

@@ -228,54 +228,6 @@ public class LocalFileMediaResource: TelegramMediaResource {
} }
} }
public struct PhotoLibraryMediaResourceId: MediaResourceId {
public let localIdentifier: String
public var uniqueId: String {
return "ph-\(self.localIdentifier.replacingOccurrences(of: "/", with: "_"))"
}
public var hashValue: Int {
return self.localIdentifier.hashValue
}
public func isEqual(to: MediaResourceId) -> Bool {
if let to = to as? PhotoLibraryMediaResourceId {
return self.localIdentifier == to.localIdentifier
} else {
return false
}
}
}
public class PhotoLibraryMediaResource: TelegramMediaResource {
let localIdentifier: String
public init(localIdentifier: String) {
self.localIdentifier = localIdentifier
}
public required init(decoder: Decoder) {
self.localIdentifier = decoder.decodeStringForKey("i")
}
public func encode(_ encoder: Encoder) {
encoder.encodeString(self.localIdentifier, forKey: "i")
}
public var id: MediaResourceId {
return PhotoLibraryMediaResourceId(localIdentifier: self.localIdentifier)
}
public func isEqual(to: TelegramMediaResource) -> Bool {
if let to = to as? PhotoLibraryMediaResource {
return self.localIdentifier == to.localIdentifier
} else {
return false
}
}
}
public struct LocalFileReferenceMediaResourceId: MediaResourceId { public struct LocalFileReferenceMediaResourceId: MediaResourceId {
public let randomId: Int64 public let randomId: Int64

View File

@@ -190,6 +190,12 @@ func enqueueMessages(modifier: Modifier, account: Account, peerId: PeerId, messa
mediaList.append(media) mediaList.append(media)
} }
if let file = media as? TelegramMediaFile, file.isVoice {
if peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.CloudGroup {
attributes.append(ConsumableContentMessageAttribute(consumed: false))
}
}
var entitiesAttribute: TextEntitiesMessageAttribute? var entitiesAttribute: TextEntitiesMessageAttribute?
for attribute in attributes { for attribute in attributes {
if let attribute = attribute as? TextEntitiesMessageAttribute { if let attribute = attribute as? TextEntitiesMessageAttribute {

View File

@@ -13,50 +13,6 @@ private func fetchCloudMediaLocation(account: Account, resource: TelegramCloudMe
return multipartFetch(account: account, resource: resource, size: size, range: range) return multipartFetch(account: account, resource: resource, size: size, range: range)
} }
#if os(iOS)
private func fetchPhotoLibraryResource(localIdentifier: String) -> Signal<MediaResourceDataFetchResult, NoError> {
return Signal { subscriber in
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: nil)
var requestId: PHImageRequestID?
if fetchResult.count != 0 {
let asset = fetchResult.object(at: 0)
let option = PHImageRequestOptions()
option.deliveryMode = .highQualityFormat
let size = CGSize(width: 1280.0, height: 1280.0)
requestId = PHImageManager.default().requestImage(for: asset, targetSize: size, contentMode: .aspectFit, options: option, resultHandler: { (image, info) -> Void in
Queue.concurrentDefaultQueue().async {
requestId = nil
if let image = image {
let scale = min(1.0, min(size.width / max(1.0, image.size.width), size.height / max(1.0, image.size.height)))
let scaledSize = CGSize(width: floor(image.size.width * scale), height: floor(image.size.height * scale))
UIGraphicsBeginImageContextWithOptions(scaledSize, true, image.scale)
image.draw(in: CGRect(origin: CGPoint(), size: scaledSize))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
if let scaledImage = scaledImage, let data = UIImageJPEGRepresentation(scaledImage, 0.6) {
subscriber.putNext(.dataPart(data: data, range: 0 ..< data.count, complete: true))
subscriber.putCompletion()
} else {
subscriber.putCompletion()
}
} else {
subscriber.putCompletion()
}
}
})
}
return ActionDisposable {
if let requestId = requestId {
PHImageManager.default().cancelImageRequest(requestId)
}
}
}
}
#endif
private func fetchLocalFileResource(path: String, move: Bool) -> Signal<MediaResourceDataFetchResult, NoError> { private func fetchLocalFileResource(path: String, move: Bool) -> Signal<MediaResourceDataFetchResult, NoError> {
return Signal { subscriber in return Signal { subscriber in
if move { if move {
@@ -81,12 +37,6 @@ func fetchResource(account: Account, resource: MediaResource, range: Range<Int>)
return .single(.dataPart(data: Data(), range: 0 ..< 0, complete: false)) |> then(fetchSecretFileResource(account: account, resource: secretFileResource, range: range)) return .single(.dataPart(data: Data(), range: 0 ..< 0, complete: false)) |> then(fetchSecretFileResource(account: account, resource: secretFileResource, range: range))
} else if let cloudResource = resource as? TelegramCloudMediaResource { } else if let cloudResource = resource as? TelegramCloudMediaResource {
return .single(.dataPart(data: Data(), range: 0 ..< 0, complete: false)) |> then(fetchCloudMediaLocation(account: account, resource: cloudResource, size: resource.size, range: range)) return .single(.dataPart(data: Data(), range: 0 ..< 0, complete: false)) |> then(fetchCloudMediaLocation(account: account, resource: cloudResource, size: resource.size, range: range))
} else if let photoLibraryResource = resource as? PhotoLibraryMediaResource {
#if os(iOS)
return .single(.dataPart(data: Data(), range: 0 ..< 0, complete: false)) |> then(fetchPhotoLibraryResource(localIdentifier: photoLibraryResource.localIdentifier))
#else
return .single(.dataPart(data: Data(), range: 0 ..< 0, complete: false))
#endif
} else if let localFileResource = resource as? LocalFileReferenceMediaResource { } else if let localFileResource = resource as? LocalFileReferenceMediaResource {
if false { if false {
//return .single(.dataPart(data: Data(), range: 0 ..< 0, complete: false)) |> then(fetchLocalFileResource(path: localFileResource.localFilePath) |> delay(10.0, queue: Queue.concurrentDefaultQueue())) //return .single(.dataPart(data: Data(), range: 0 ..< 0, complete: false)) |> then(fetchLocalFileResource(path: localFileResource.localFilePath) |> delay(10.0, queue: Queue.concurrentDefaultQueue()))

View File

@@ -7,7 +7,7 @@ import Foundation
import SwiftSignalKit import SwiftSignalKit
#endif #endif
public func markMessageContentAsConsumedInteractively(postbox: Postbox, network: Network, messageId: MessageId) -> Signal<Void, NoError> { public func markMessageContentAsConsumedInteractively(postbox: Postbox, messageId: MessageId) -> Signal<Void, NoError> {
return postbox.modify { modifier -> Void in return postbox.modify { modifier -> Void in
if let message = modifier.getMessage(messageId), message.flags.contains(.Incoming) { if let message = modifier.getMessage(messageId), message.flags.contains(.Incoming) {
var updateMessage = false var updateMessage = false

View File

@@ -94,7 +94,7 @@ private var registeredLoggingFunctions: Void = {
registerLoggingFunctions() registerLoggingFunctions()
}() }()
func initializedNetwork(apiId: Int32, datacenterId: Int, keychain: Keychain, networkUsageInfoPath: String?, testingEnvironment: Bool) -> Signal<Network, NoError> { func initializedNetwork(apiId: Int32, supplementary: Bool, datacenterId: Int, keychain: Keychain, networkUsageInfoPath: String?, testingEnvironment: Bool) -> Signal<Network, NoError> {
return Signal { subscriber in return Signal { subscriber in
Queue.concurrentDefaultQueue().async { Queue.concurrentDefaultQueue().async {
let _ = registeredLoggingFunctions let _ = registeredLoggingFunctions
@@ -105,6 +105,7 @@ func initializedNetwork(apiId: Int32, datacenterId: Int, keychain: Keychain, net
apiEnvironment.apiId = apiId apiEnvironment.apiId = apiId
apiEnvironment.layer = NSNumber(value: Int(serialization.currentLayer())) apiEnvironment.layer = NSNumber(value: Int(serialization.currentLayer()))
apiEnvironment.disableUpdates = supplementary
let context = MTContext(serialization: serialization, apiEnvironment: apiEnvironment)! let context = MTContext(serialization: serialization, apiEnvironment: apiEnvironment)!

View File

@@ -207,8 +207,8 @@ public final class PendingMessageManager {
let contentToUpload = messageContentToUpload(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 { switch contentToUpload {
case let .ready(message, content): case let .ready(content):
strongSelf.beginSendingMessage(messageContext: messageContext, message: message, content: content) strongSelf.beginSendingMessage(messageContext: messageContext, messageId: message.id, content: content)
case let .upload(uploadSignal): case let .upload(uploadSignal):
if strongSelf.canBeginUploadingMessage(id: message.id) { if strongSelf.canBeginUploadingMessage(id: message.id) {
strongSelf.beginUploadingMessage(messageContext: messageContext, id: message.id, uploadSignal: uploadSignal) strongSelf.beginUploadingMessage(messageContext: messageContext, id: message.id, uploadSignal: uploadSignal)
@@ -216,75 +216,27 @@ public final class PendingMessageManager {
messageContext.state = .waitingForUploadToStart(uploadSignal) 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
if let strongSelf = self {
switch contentResult {
case let .progress(progress):
return .single(.progress(progress))
case let .content(message, content):
return strongSelf.sendMessageContent(network: strongSelf.network, postbox: strongSelf.postbox, stateManager: strongSelf.stateManager, message: message, content: content)
|> map { next -> PendingMessageResult in
return .progress(1.0)
}
}
} else {
return .complete()
}
}
messageContext.disposable.set((sendMessage |> deliverOn(strongSelf.queue) |> afterDisposed {
if let strongSelf = self {
assert(strongSelf.queue.isCurrent())
if let current = strongSelf.messageContexts[message.id] {
for subscriber in current.statusSubscribers.copyItems() {
subscriber(nil)
}
if current.statusSubscribers.isEmpty {
strongSelf.messageContexts.removeValue(forKey: message.id)
}
}
}
}).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)
}
}
}
}
}))*/
} }
} }
})) }))
} }
private func beginSendingMessage(messageContext: PendingMessageContext, message: Message, content: PendingMessageUploadedContent) { private func beginSendingMessage(messageContext: PendingMessageContext, messageId: MessageId, content: PendingMessageUploadedContent) {
messageContext.state = .sending messageContext.state = .sending
let sendMessage: Signal<PendingMessageResult, NoError> = self.sendMessageContent(network: self.network, postbox: self.postbox, stateManager: self.stateManager, message: message, content: content) let sendMessage: Signal<PendingMessageResult, NoError> = self.sendMessageContent(network: self.network, postbox: self.postbox, stateManager: self.stateManager, messageId: messageId, content: content)
|> map { next -> PendingMessageResult in |> map { next -> PendingMessageResult in
return .progress(1.0) return .progress(1.0)
} }
messageContext.disposable.set((sendMessage |> deliverOn(self.queue) |> afterDisposed { [weak self] in messageContext.disposable.set((sendMessage |> deliverOn(self.queue) |> afterDisposed { [weak self] in
if let strongSelf = self { if let strongSelf = self {
assert(strongSelf.queue.isCurrent()) assert(strongSelf.queue.isCurrent())
if let current = strongSelf.messageContexts[message.id] { if let current = strongSelf.messageContexts[messageId] {
current.status = .none current.status = .none
for subscriber in current.statusSubscribers.copyItems() { for subscriber in current.statusSubscribers.copyItems() {
subscriber(nil) subscriber(nil)
} }
if current.statusSubscribers.isEmpty { if current.statusSubscribers.isEmpty {
strongSelf.messageContexts.removeValue(forKey: message.id) strongSelf.messageContexts.removeValue(forKey: messageId)
} }
} }
} }
@@ -294,7 +246,7 @@ public final class PendingMessageManager {
switch next { switch next {
case let .progress(progress): case let .progress(progress):
if let current = strongSelf.messageContexts[message.id] { if let current = strongSelf.messageContexts[messageId] {
let status = PendingMessageStatus(progress: progress) let status = PendingMessageStatus(progress: progress)
current.status = status current.status = status
for subscriber in current.statusSubscribers.copyItems() { for subscriber in current.statusSubscribers.copyItems() {
@@ -322,9 +274,9 @@ public final class PendingMessageManager {
subscriber(status) subscriber(status)
} }
} }
case let .content(message, content): case let .content(content):
if let current = strongSelf.messageContexts[id] { if let current = strongSelf.messageContexts[id] {
strongSelf.beginSendingMessage(messageContext: current, message: message, content: content) strongSelf.beginSendingMessage(messageContext: current, messageId: id, content: content)
strongSelf.updateWaitingUploads(peerId: id.peerId) strongSelf.updateWaitingUploads(peerId: id.peerId)
} }
} }
@@ -354,11 +306,11 @@ public final class PendingMessageManager {
subscriber(status) subscriber(status)
} }
} }
case let .content(message, content): case let .content(content):
if let current = strongSelf.messageContexts[message.id] { if let current = strongSelf.messageContexts[contextId] {
current.state = .sending current.state = .sending
current.disposable.set((strongSelf.sendMessageContent(network: strongSelf.network, postbox: strongSelf.postbox, stateManager: strongSelf.stateManager, message: message, content: content) current.disposable.set((strongSelf.sendMessageContent(network: strongSelf.network, postbox: strongSelf.postbox, stateManager: strongSelf.stateManager, messageId: contextId, content: content)
|> map { next -> PendingMessageResult in |> map { next -> PendingMessageResult in
return .progress(1.0) return .progress(1.0)
} |> deliverOn(strongSelf.queue)).start(next: { next in } |> deliverOn(strongSelf.queue)).start(next: { next in
@@ -367,7 +319,7 @@ public final class PendingMessageManager {
switch next { switch next {
case let .progress(progress): case let .progress(progress):
if let current = strongSelf.messageContexts[message.id] { if let current = strongSelf.messageContexts[contextId] {
let status = PendingMessageStatus(progress: progress) let status = PendingMessageStatus(progress: progress)
current.status = status current.status = status
for subscriber in current.statusSubscribers.copyItems() { for subscriber in current.statusSubscribers.copyItems() {
@@ -387,9 +339,13 @@ public final class PendingMessageManager {
} }
} }
private func sendMessageContent(network: Network, postbox: Postbox, stateManager: AccountStateManager, message: Message, content: PendingMessageUploadedContent) -> Signal<Void, NoError> { private func sendMessageContent(network: Network, postbox: Postbox, stateManager: AccountStateManager, messageId: MessageId, content: PendingMessageUploadedContent) -> Signal<Void, NoError> {
return postbox.modify { [weak self] modifier -> Signal<Void, NoError> in return postbox.modify { [weak self] modifier -> Signal<Void, NoError> in
if message.id.peerId.namespace == Namespaces.Peer.SecretChat { guard let message = modifier.getMessage(messageId) else {
return .complete()
}
if messageId.peerId.namespace == Namespaces.Peer.SecretChat {
var secretFile: SecretChatOutgoingFile? var secretFile: SecretChatOutgoingFile?
switch content { switch content {
case let .secretMedia(file, size, key): case let .secretMedia(file, size, key):
@@ -401,7 +357,7 @@ public final class PendingMessageManager {
} }
var layer: SecretChatLayer? var layer: SecretChatLayer?
let state = modifier.getPeerChatState(message.id.peerId) as? SecretChatState let state = modifier.getPeerChatState(messageId.peerId) as? SecretChatState
if let state = state { if let state = state {
switch state.embeddedState { switch state.embeddedState {
case .terminated, .handshake: case .terminated, .handshake:
@@ -440,11 +396,11 @@ public final class PendingMessageManager {
} }
if !sentAsAction { if !sentAsAction {
let updatedState = addSecretChatOutgoingOperation(modifier: modifier, peerId: message.id.peerId, operation: .sendMessage(layer: layer, id: message.id, file: secretFile), state: state) let updatedState = addSecretChatOutgoingOperation(modifier: modifier, peerId: messageId.peerId, operation: .sendMessage(layer: layer, id: messageId, file: secretFile), state: state)
if updatedState != state { if updatedState != state {
modifier.setPeerChatState(message.id.peerId, state: updatedState) modifier.setPeerChatState(messageId.peerId, state: updatedState)
} }
modifier.updateMessage(message.id, update: { currentMessage in modifier.updateMessage(messageId, update: { currentMessage in
var flags = StoreMessageFlags(message.flags) var flags = StoreMessageFlags(message.flags)
if !flags.contains(.Failed) { if !flags.contains(.Failed) {
flags.insert(.Sending) flags.insert(.Sending)
@@ -457,7 +413,7 @@ public final class PendingMessageManager {
}) })
} }
} else { } else {
modifier.updateMessage(message.id, update: { currentMessage in modifier.updateMessage(messageId, update: { currentMessage in
var storeForwardInfo: StoreMessageForwardInfo? var storeForwardInfo: StoreMessageForwardInfo?
if let forwardInfo = currentMessage.forwardInfo { if let forwardInfo = currentMessage.forwardInfo {
storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date) storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date)
@@ -466,7 +422,7 @@ public final class PendingMessageManager {
}) })
} }
return .complete() return .complete()
} else if let peer = modifier.getPeer(message.id.peerId), let inputPeer = apiInputPeer(peer) { } else if let peer = modifier.getPeer(messageId.peerId), let inputPeer = apiInputPeer(peer) {
var uniqueId: Int64 = 0 var uniqueId: Int64 = 0
var forwardSourceInfoAttribute: ForwardSourceInfoAttribute? var forwardSourceInfoAttribute: ForwardSourceInfoAttribute?
var messageEntities: [Api.MessageEntity]? var messageEntities: [Api.MessageEntity]?
@@ -499,7 +455,7 @@ public final class PendingMessageManager {
flags |= Int32(1 << 3) flags |= Int32(1 << 3)
} }
let dependencyTag = PendingMessageRequestDependencyTag(messageId: message.id) let dependencyTag = PendingMessageRequestDependencyTag(messageId: messageId)
let sendMessageRequest: Signal<Api.Updates, NoError> let sendMessageRequest: Signal<Api.Updates, NoError>
switch content { switch content {

View File

@@ -17,115 +17,76 @@ enum PendingMessageUploadedContent {
enum PendingMessageUploadedContentResult { enum PendingMessageUploadedContentResult {
case progress(Float) case progress(Float)
case content(Message, PendingMessageUploadedContent) case content(PendingMessageUploadedContent)
} }
enum PendingMessageUploadContent { enum PendingMessageUploadContent {
case ready(Message, PendingMessageUploadedContent) case ready(PendingMessageUploadedContent)
case upload(Signal<PendingMessageUploadedContentResult, NoError>) case upload(Signal<PendingMessageUploadedContentResult, NoError>)
} }
func messageContentToUpload(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, message: Message) -> PendingMessageUploadContent { func messageContentToUpload(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, message: Message) -> PendingMessageUploadContent {
var outgoingChatContextResultAttribute: OutgoingChatContextResultMessageAttribute? return messageContentToUpload(network: network, postbox: postbox, transformOutgoingMessageMedia: transformOutgoingMessageMedia, peerId: message.id.peerId, messageId: message.id, attributes: message.attributes, text: message.text, media: message.media)
for attribute in message.attributes { }
func messageContentToUpload(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, peerId: PeerId, messageId: MessageId?, attributes: [MessageAttribute], text: String, media: [Media]) -> PendingMessageUploadContent {
var contextResult: OutgoingChatContextResultMessageAttribute?
for attribute in attributes {
if let attribute = attribute as? OutgoingChatContextResultMessageAttribute { if let attribute = attribute as? OutgoingChatContextResultMessageAttribute {
outgoingChatContextResultAttribute = attribute contextResult = attribute
} }
} }
if let _ = message.forwardInfo { var forwardInfo: ForwardSourceInfoAttribute?
var forwardSourceInfo: ForwardSourceInfoAttribute? for attribute in attributes {
for attribute in message.attributes { if let attribute = attribute as? ForwardSourceInfoAttribute {
if let attribute = attribute as? ForwardSourceInfoAttribute { forwardInfo = attribute
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 {
if let attribute = attribute as? OutgoingChatContextResultMessageAttribute {
outgoingChatContextResultAttribute = attribute
} }
} }
if let _ = message.forwardInfo { if let forwardInfo = forwardInfo {
var forwardSourceInfo: ForwardSourceInfoAttribute? return .ready(.forward(forwardInfo))
for attribute in message.attributes { }
if let attribute = attribute as? ForwardSourceInfoAttribute {
forwardSourceInfo = attribute if let forwardInfo = forwardInfo {
} return .ready(.forward(forwardInfo))
} } else if let contextResult = contextResult {
if let forwardSourceInfo = forwardSourceInfo { return .ready(.chatContextResult(contextResult))
return .single(.content(message, .forward(forwardSourceInfo))) } else if let media = media.first {
} else {
assertionFailure()
return .never()
}
} else if let outgoingChatContextResultAttribute = outgoingChatContextResultAttribute {
return .single(.content(message, .chatContextResult(outgoingChatContextResultAttribute)))
} else if let media = message.media.first {
if let image = media as? TelegramMediaImage, let _ = largestImageRepresentation(image.representations) { if let image = media as? TelegramMediaImage, let _ = largestImageRepresentation(image.representations) {
return uploadedMediaImageContent(network: network, postbox: postbox, image: image, message: message) return .upload(uploadedMediaImageContent(network: network, postbox: postbox, peerId: peerId, image: image, text: text))
} else if let file = media as? TelegramMediaFile { } else if let file = media as? TelegramMediaFile {
if let resource = file.resource as? CloudDocumentMediaResource { if let resource = file.resource as? CloudDocumentMediaResource {
return .single(.content(message, .media(Api.InputMedia.inputMediaDocument(id: Api.InputDocument.inputDocument(id: resource.fileId, accessHash: resource.accessHash), caption: message.text)))) return .ready(.media(Api.InputMedia.inputMediaDocument(id: Api.InputDocument.inputDocument(id: resource.fileId, accessHash: resource.accessHash), caption: text)))
} else { } else {
return uploadedMediaFileContent(network: network, postbox: postbox, transformOutgoingMessageMedia: transformOutgoingMessageMedia, file: file, message: message) return .upload(uploadedMediaFileContent(network: network, postbox: postbox, transformOutgoingMessageMedia: transformOutgoingMessageMedia, peerId: peerId, messageId: messageId, text: text, attributes: attributes, file: file))
} }
} else if let contact = media as? TelegramMediaContact { } else if let contact = media as? TelegramMediaContact {
let input = Api.InputMedia.inputMediaContact(phoneNumber: contact.phoneNumber, firstName: contact.firstName, lastName: contact.lastName) let input = Api.InputMedia.inputMediaContact(phoneNumber: contact.phoneNumber, firstName: contact.firstName, lastName: contact.lastName)
return .single(.content(message, .media(input))) return .ready(.media(input))
} else { } else {
return .single(.content(message, .text(message.text))) return .ready(.text(text))
} }
} else { } else {
return .single(.content(message, .text(message.text))) return .ready(.text(text))
} }
} }
private func uploadedMediaImageContent(network: Network, postbox: Postbox, image: TelegramMediaImage, message: Message) -> Signal<PendingMessageUploadedContentResult, NoError> { private func uploadedMediaImageContent(network: Network, postbox: Postbox, peerId: PeerId, image: TelegramMediaImage, text: String) -> Signal<PendingMessageUploadedContentResult, NoError> {
if let largestRepresentation = largestImageRepresentation(image.representations) { if let largestRepresentation = largestImageRepresentation(image.representations) {
return multipartUpload(network: network, postbox: postbox, resource: largestRepresentation.resource, encrypt: message.id.peerId.namespace == Namespaces.Peer.SecretChat) return multipartUpload(network: network, postbox: postbox, resource: largestRepresentation.resource, encrypt: peerId.namespace == Namespaces.Peer.SecretChat)
|> map { next -> PendingMessageUploadedContentResult in |> map { next -> PendingMessageUploadedContentResult in
switch next { switch next {
case let .progress(progress): case let .progress(progress):
return .progress(progress) return .progress(progress)
case let .inputFile(file): case let .inputFile(file):
return .content(message, .media(Api.InputMedia.inputMediaUploadedPhoto(flags: 0, file: file, caption: message.text, stickers: nil))) return .content(.media(Api.InputMedia.inputMediaUploadedPhoto(flags: 0, file: file, caption: text, stickers: nil)))
case let .inputSecretFile(file, size, key): case let .inputSecretFile(file, size, key):
return .content(message, .secretMedia(file, size, key)) return .content(.secretMedia(file, size, key))
} }
} }
} else { } else {
return .single(.content(message, .text(message.text))) return .single(.content(.text(text)))
} }
} }
@@ -201,14 +162,14 @@ private func uploadedThumbnail(network: Network, postbox: Postbox, image: Telegr
} }
} }
private func uploadedMediaFileContent(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, file: TelegramMediaFile, message: Message) -> Signal<PendingMessageUploadedContentResult, NoError> { private func uploadedMediaFileContent(network: Network, postbox: Postbox, transformOutgoingMessageMedia: TransformOutgoingMessageMedia?, peerId: PeerId, messageId: MessageId?, text: String, attributes: [MessageAttribute], file: TelegramMediaFile) -> Signal<PendingMessageUploadedContentResult, NoError> {
var hintSize: Int? var hintSize: Int?
if let size = file.size { if let size = file.size {
hintSize = size hintSize = size
} else if let resource = file.resource as? LocalFileReferenceMediaResource, let size = resource.size { } else if let resource = file.resource as? LocalFileReferenceMediaResource, let size = resource.size {
hintSize = Int(size) hintSize = Int(size)
} }
let upload = multipartUpload(network: network, postbox: postbox, resource: file.resource, encrypt: message.id.peerId.namespace == Namespaces.Peer.SecretChat, hintFileSize: hintSize) let upload = multipartUpload(network: network, postbox: postbox, resource: file.resource, encrypt: peerId.namespace == Namespaces.Peer.SecretChat, hintFileSize: hintSize)
/*|> map { next -> UploadedMediaFileContent in /*|> map { next -> UploadedMediaFileContent in
switch next { switch next {
case let .progress(progress): case let .progress(progress):
@@ -220,7 +181,7 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, transf
} }
}*/ }*/
var alreadyTransformed = false var alreadyTransformed = false
for attribute in message.attributes { for attribute in attributes {
if let attribute = attribute as? OutgoingMessageInfoAttribute { if let attribute = attribute as? OutgoingMessageInfoAttribute {
if attribute.flags.contains(.transformedMedia) { if attribute.flags.contains(.transformedMedia) {
alreadyTransformed = true alreadyTransformed = true
@@ -230,14 +191,14 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, transf
} }
let transform: Signal<UploadedMediaTransform, Void> let transform: Signal<UploadedMediaTransform, Void>
if let transformOutgoingMessageMedia = transformOutgoingMessageMedia, !alreadyTransformed { if let transformOutgoingMessageMedia = transformOutgoingMessageMedia, let messageId = messageId, !alreadyTransformed {
transform = .single(.pending) |> then(transformOutgoingMessageMedia(postbox, network, file, false) transform = .single(.pending) |> then(transformOutgoingMessageMedia(postbox, network, file, false)
|> mapToSignal { media -> Signal<UploadedMediaTransform, NoError> in |> mapToSignal { media -> Signal<UploadedMediaTransform, NoError> in
return postbox.modify { modifier -> UploadedMediaTransform in return postbox.modify { modifier -> UploadedMediaTransform in
if let media = media { if let media = media {
if let id = media.id { if let id = media.id {
modifier.updateMedia(id, update: media) modifier.updateMedia(id, update: media)
modifier.updateMessage(message.id, update: { currentMessage in modifier.updateMessage(messageId, update: { currentMessage in
var storeForwardInfo: StoreMessageForwardInfo? var storeForwardInfo: StoreMessageForwardInfo?
if let forwardInfo = currentMessage.forwardInfo { if let forwardInfo = currentMessage.forwardInfo {
storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date) storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date)
@@ -288,17 +249,17 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, transf
if case let .done(thumbnail) = media { if case let .done(thumbnail) = media {
let inputMedia: Api.InputMedia let inputMedia: Api.InputMedia
if let thumbnail = thumbnail { if let thumbnail = thumbnail {
inputMedia = Api.InputMedia.inputMediaUploadedThumbDocument(flags: 0, file: inputFile, thumb: thumbnail, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFile(file), caption: message.text, stickers: nil) inputMedia = Api.InputMedia.inputMediaUploadedThumbDocument(flags: 0, file: inputFile, thumb: thumbnail, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFile(file), caption: text, stickers: nil)
} else { } else {
inputMedia = Api.InputMedia.inputMediaUploadedDocument(flags: 0, file: inputFile, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFile(file), caption: message.text, stickers: nil) inputMedia = Api.InputMedia.inputMediaUploadedDocument(flags: 0, file: inputFile, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFile(file), caption: text, stickers: nil)
} }
return .single(.content(message, .media(inputMedia))) return .single(.content(.media(inputMedia)))
} else { } else {
return .complete() return .complete()
} }
case let .inputSecretFile(file, size, key): case let .inputSecretFile(file, size, key):
if case .done = media { if case .done = media {
return .single(.content(message, .secretMedia(file, size, key))) return .single(.content(.secretMedia(file, size, key)))
} else { } else {
return .complete() return .complete()
} }

View File

@@ -12,10 +12,14 @@ final class CachedResolvedByNamePeer: Coding {
let timestamp: Int32 let timestamp: Int32
static func key(name: String) -> ValueBoxKey { static func key(name: String) -> ValueBoxKey {
let nameData = name.data(using: .utf8)! let key: ValueBoxKey
let key = ValueBoxKey(length: nameData.count) if let nameData = name.data(using: .utf8) {
nameData.withUnsafeBytes { (bytes: UnsafePointer<Int8>) -> Void in key = ValueBoxKey(length: nameData.count)
memcpy(key.memory, bytes, nameData.count) nameData.withUnsafeBytes { (bytes: UnsafePointer<Int8>) -> Void in
memcpy(key.memory, bytes, nameData.count)
}
} else {
key = ValueBoxKey(length: 0)
} }
return key return key
} }

View File

@@ -0,0 +1,117 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
import MtProtoKitMac
#else
import Postbox
import SwiftSignalKit
import MtProtoKitDynamic
#endif
public enum StandaloneMedia {
case image(Data)
case file(Data)
}
public func standaloneSendMessage(account: Account, peerId: PeerId, text: String, attributes: [MessageAttribute], replyToMessageId: MessageId?) -> Signal<Void, NoError> {
let contentToUpload = messageContentToUpload(network: account.network, postbox: account.postbox, transformOutgoingMessageMedia: nil, peerId: peerId, messageId: nil, attributes: attributes, text: text, media: [])
switch contentToUpload {
case let .ready(content):
return sendMessageContent(account: account, peerId: peerId, attributes: attributes, content: content)
case let .upload(uploadSignal):
return .complete()
/*if strongSelf.canBeginUploadingMessage(id: message.id) {
strongSelf.beginUploadingMessage(messageContext: messageContext, id: message.id, uploadSignal: uploadSignal)
} else {
messageContext.state = .waitingForUploadToStart(uploadSignal)
}*/
}
}
private func sendMessageContent(account: Account, peerId: PeerId, attributes: [MessageAttribute], content: PendingMessageUploadedContent) -> Signal<Void, NoError> {
return account.postbox.modify { modifier -> Signal<Void, NoError> in
if peerId.namespace == Namespaces.Peer.SecretChat {
return .complete()
} else if let peer = modifier.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
var uniqueId: Int64 = 0
var forwardSourceInfoAttribute: ForwardSourceInfoAttribute?
var messageEntities: [Api.MessageEntity]?
var replyMessageId: Int32?
var flags: Int32 = 0
flags |= (1 << 7)
for attribute in attributes {
if let replyAttribute = attribute as? ReplyMessageAttribute {
replyMessageId = replyAttribute.messageId.id
} else if let outgoingInfo = attribute as? OutgoingMessageInfoAttribute {
uniqueId = outgoingInfo.uniqueId
} else if let attribute = attribute as? ForwardSourceInfoAttribute {
forwardSourceInfoAttribute = attribute
} else if let attribute = attribute as? TextEntitiesMessageAttribute {
messageEntities = apiTextAttributeEntities(attribute, associatedPeers: SimpleDictionary())
} else if let attribute = attribute as? OutgoingContentInfoMessageAttribute {
if attribute.flags.contains(.disableLinkPreviews) {
flags |= Int32(1 << 1)
}
}
}
if let _ = replyMessageId {
flags |= Int32(1 << 0)
}
if let _ = messageEntities {
flags |= Int32(1 << 3)
}
let sendMessageRequest: Signal<Api.Updates, NoError>
switch content {
case let .text(text):
sendMessageRequest = account.network.request(Api.functions.messages.sendMessage(flags: flags, peer: inputPeer, replyToMsgId: replyMessageId, message: text, randomId: uniqueId, replyMarkup: nil, entities: messageEntities))
|> mapError { _ -> NoError in
return NoError()
}
case let .media(inputMedia):
sendMessageRequest = account.network.request(Api.functions.messages.sendMedia(flags: flags, peer: inputPeer, replyToMsgId: replyMessageId, media: inputMedia, randomId: uniqueId, replyMarkup: nil))
|> mapError { _ -> NoError in
return NoError()
}
case let .forward(sourceInfo):
if let forwardSourceInfoAttribute = forwardSourceInfoAttribute, let sourcePeer = modifier.getPeer(forwardSourceInfoAttribute.messageId.peerId), let sourceInputPeer = apiInputPeer(sourcePeer) {
sendMessageRequest = account.network.request(Api.functions.messages.forwardMessages(flags: 0, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer))
|> mapError { _ -> NoError in
return NoError()
}
} else {
sendMessageRequest = .fail(NoError())
}
case let .chatContextResult(chatContextResult):
sendMessageRequest = account.network.request(Api.functions.messages.sendInlineBotResult(flags: flags, peer: inputPeer, replyToMsgId: replyMessageId, randomId: uniqueId, queryId: chatContextResult.queryId, id: chatContextResult.id))
|> mapError { _ -> NoError in
return NoError()
}
case .secretMedia:
assertionFailure()
sendMessageRequest = .fail(NoError())
}
return sendMessageRequest
|> mapToSignal { result -> Signal<Void, NoError> in
return .complete()
/*if let strongSelf = self {
return strongSelf.applySentMessage(postbox: postbox, stateManager: stateManager, message: message, result: result)
} else {
return .never()
}*/
}
|> `catch` { _ -> Signal<Void, NoError> in
return .complete()
}
} else {
return .complete()
}
} |> switchToLatest
}