no message

This commit is contained in:
Peter
2017-08-21 23:28:37 +03:00
parent 8471016caf
commit d02b75a0c5
11 changed files with 281 additions and 81 deletions

View File

@@ -473,6 +473,10 @@
D0C0B58B1ED9DA6B000F4D2C /* ManagedLocalizationUpdatesOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B5891ED9DA6B000F4D2C /* ManagedLocalizationUpdatesOperations.swift */; };
D0C0B58D1ED9DC5A000F4D2C /* SynchronizeLocalizationUpdatesOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B58C1ED9DC5A000F4D2C /* SynchronizeLocalizationUpdatesOperation.swift */; };
D0C0B58E1ED9DC5A000F4D2C /* SynchronizeLocalizationUpdatesOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C0B58C1ED9DC5A000F4D2C /* SynchronizeLocalizationUpdatesOperation.swift */; };
D0C27B3F1F4B51D000A4E170 /* CachedStickerPack.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C27B3E1F4B51D000A4E170 /* CachedStickerPack.swift */; };
D0C27B401F4B51D000A4E170 /* CachedStickerPack.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C27B3E1F4B51D000A4E170 /* CachedStickerPack.swift */; };
D0C27B421F4B58C000A4E170 /* PeerSpecificStickerPack.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C27B411F4B58C000A4E170 /* PeerSpecificStickerPack.swift */; };
D0C27B431F4B58C000A4E170 /* PeerSpecificStickerPack.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C27B411F4B58C000A4E170 /* PeerSpecificStickerPack.swift */; };
D0C48F391E8138DF0075317D /* ArchivedStickerPacksInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C48F381E8138DF0075317D /* ArchivedStickerPacksInfo.swift */; };
D0C48F3A1E8138DF0075317D /* ArchivedStickerPacksInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C48F381E8138DF0075317D /* ArchivedStickerPacksInfo.swift */; };
D0C48F3C1E8142EF0075317D /* LoadedPeerFromMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C48F3B1E8142EF0075317D /* LoadedPeerFromMessage.swift */; };
@@ -839,6 +843,8 @@
D0BEAF5F1E54ACF900BD963D /* AccountManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountManager.swift; sourceTree = "<group>"; };
D0C0B5891ED9DA6B000F4D2C /* ManagedLocalizationUpdatesOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedLocalizationUpdatesOperations.swift; sourceTree = "<group>"; };
D0C0B58C1ED9DC5A000F4D2C /* SynchronizeLocalizationUpdatesOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizeLocalizationUpdatesOperation.swift; sourceTree = "<group>"; };
D0C27B3E1F4B51D000A4E170 /* CachedStickerPack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedStickerPack.swift; sourceTree = "<group>"; };
D0C27B411F4B58C000A4E170 /* PeerSpecificStickerPack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerSpecificStickerPack.swift; sourceTree = "<group>"; };
D0C48F381E8138DF0075317D /* ArchivedStickerPacksInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArchivedStickerPacksInfo.swift; sourceTree = "<group>"; };
D0C48F3B1E8142EF0075317D /* LoadedPeerFromMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadedPeerFromMessage.swift; sourceTree = "<group>"; };
D0C50E331E93A86600F62E39 /* CallSessionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallSessionManager.swift; sourceTree = "<group>"; };
@@ -962,6 +968,8 @@
D0D748011E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift */,
D05452061E7B5093006EEF19 /* LoadedStickerPack.swift */,
D0E23DDE1E8082A400B9B6D2 /* ArchivedStickerPacks.swift */,
D0C27B3E1F4B51D000A4E170 /* CachedStickerPack.swift */,
D0C27B411F4B58C000A4E170 /* PeerSpecificStickerPack.swift */,
);
name = "Sticker Management";
sourceTree = "<group>";
@@ -1754,6 +1762,7 @@
D02ABC7B1E30058F00CAE539 /* DeleteMessagesInteractively.swift in Sources */,
C2E064681ECEEF0A00387BB8 /* TelegramMediaInvoice.swift in Sources */,
D0448C9F1E27F5EB005A61A7 /* Random.swift in Sources */,
D0C27B3F1F4B51D000A4E170 /* CachedStickerPack.swift in Sources */,
D0B843B21DA7FF30005F29E1 /* NBAsYouTypeFormatter.m in Sources */,
D07047B71F3DF2CD00F6A8D4 /* ManagedConsumePersonalMessagesActions.swift in Sources */,
D03B0CDB1D62245F00955575 /* ApiUtils.swift in Sources */,
@@ -1875,6 +1884,7 @@
D0177B7B1DF8A16C00A5083A /* SecretChatState.swift in Sources */,
D0AAD1AA1E32638500D5B9DE /* ApplyMaxReadIndexInteractively.swift in Sources */,
D03B0D5C1D631A6900955575 /* Download.swift in Sources */,
D0C27B421F4B58C000A4E170 /* PeerSpecificStickerPack.swift in Sources */,
D01749591E1092BC0057C89A /* RequestStartBot.swift in Sources */,
D01B27A21E394D8B0022A4C0 /* PrivacySettings.swift in Sources */,
D0223A9B1EA5654D00211D94 /* TelegramMediaResource.swift in Sources */,
@@ -2052,6 +2062,7 @@
D001F3F31E128A1C007A8C60 /* UpdateMessageService.swift in Sources */,
D0C50E351E93A86600F62E39 /* CallSessionManager.swift in Sources */,
D0B8442D1DAB91E0005F29E1 /* NBMetadataCoreTest.m in Sources */,
D0C27B431F4B58C000A4E170 /* PeerSpecificStickerPack.swift in Sources */,
D0B844131DAB91CD005F29E1 /* StringFormat.swift in Sources */,
D0C0B58E1ED9DC5A000F4D2C /* SynchronizeLocalizationUpdatesOperation.swift in Sources */,
D0E35A131DE4C69100BC6096 /* OutgoingChatContextResultMessageAttribute.swift in Sources */,
@@ -2183,6 +2194,7 @@
D0C0B58B1ED9DA6B000F4D2C /* ManagedLocalizationUpdatesOperations.swift in Sources */,
D0B844331DAB91E0005F29E1 /* NBPhoneNumber.m in Sources */,
D001F3F51E128A1C007A8C60 /* PendingMessageManager.swift in Sources */,
D0C27B401F4B51D000A4E170 /* CachedStickerPack.swift in Sources */,
D001F3F61E128A1C007A8C60 /* PendingMessageUploadedContent.swift in Sources */,
D01C7ED71EF5E468008305F1 /* ProxySettings.swift in Sources */,
C2366C871E4F403C0097CCFF /* AddressNames.swift in Sources */,

View File

@@ -67,7 +67,7 @@ enum AccountStateMutationOperation {
case ReadSecretOutbox(peerId: PeerId, maxTimestamp: Int32, actionTimestamp: Int32)
case AddPeerInputActivity(chatPeerId: PeerId, peerId: PeerId?, activity: PeerInputActivity?)
case UpdatePinnedPeerIds(AccountStateUpdatePinnerPeerIdsOperation)
case ReadGlobalMessageContents([Int32])
case ReadMessageContents((PeerId?, [Int32]))
case UpdateMessageImpressionCount(MessageId, Int32)
case UpdateInstalledStickerPacks(AccountStateUpdateStickerPacksOperation)
case UpdateChatInputState(PeerId, SynchronizeableChatInputState?)
@@ -245,8 +245,8 @@ struct AccountMutableState {
self.addOperation(.UpdatePinnedPeerIds(operation))
}
mutating func addReadGlobalMessagesContents(_ globalIds: [Int32]) {
self.addOperation(.ReadGlobalMessageContents(globalIds))
mutating func addReadMessagesContents(_ peerIdsAndMessageIds: (PeerId?, [Int32])) {
self.addOperation(.ReadMessageContents(peerIdsAndMessageIds))
}
mutating func addUpdateMessageImpressionCount(id: MessageId, count: Int32) {
@@ -267,7 +267,7 @@ struct AccountMutableState {
mutating func addOperation(_ operation: AccountStateMutationOperation) {
switch operation {
case .AddHole, .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMedia, .ReadOutbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedPeerIds, .ReadGlobalMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateChatInputState, .UpdateCall, .UpdateLangPack:
case .AddHole, .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMedia, .ReadOutbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedPeerIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateChatInputState, .UpdateCall, .UpdateLangPack:
break
case let .AddMessages(messages, _):
for message in messages {

View File

@@ -970,7 +970,9 @@ private func finalStateWithUpdates(account: Account, state: AccountMutableState,
updatedState.addUpdatePinnedPeerIds(.sync)
}
case let .updateReadMessagesContents(messages, _, _):
updatedState.addReadGlobalMessagesContents(messages)
updatedState.addReadMessagesContents((nil, messages))
case let .updateChannelReadMessagesContents(channelId, messages):
updatedState.addReadMessagesContents((PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), messages))
case let .updateChannelMessageViews(channelId, id, views):
updatedState.addUpdateMessageImpressionCount(id: MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), namespace: Namespaces.Message.Cloud, id: id), count: views)
case let .updateNewStickerSet(stickerset):
@@ -1421,7 +1423,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
var currentAddMessages: OptimizeAddMessagesState?
for operation in operations {
switch operation {
case .AddHole, .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ResetReadState, .UpdatePeerNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedPeerIds, .ReadGlobalMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateChatInputState, .UpdateCall, .UpdateLangPack:
case .AddHole, .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ResetReadState, .UpdatePeerNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedPeerIds, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateInstalledStickerPacks, .UpdateChatInputState, .UpdateCall, .UpdateLangPack:
if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty {
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
}
@@ -1598,9 +1600,15 @@ func replayFinalState(accountPeerId: PeerId, mediaBox: MediaBox, modifier: Modif
case .sync:
addSynchronizePinnedChatsOperation(modifier: modifier)
}
case let .ReadGlobalMessageContents(globalIds):
for messageId in modifier.messageIdsForGlobalIds(globalIds) {
markMessageContentAsConsumedRemotely(modifier: modifier, messageId: messageId)
case let .ReadMessageContents(peerId, messageIds):
if let peerId = peerId {
for id in messageIds {
markMessageContentAsConsumedRemotely(modifier: modifier, messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: id))
}
} else {
for messageId in modifier.messageIdsForGlobalIds(messageIds) {
markMessageContentAsConsumedRemotely(modifier: modifier, messageId: messageId)
}
}
case let .UpdateMessageImpressionCount(id, count):
modifier.updateMessage(id, update: { currentMessage in

View File

@@ -0,0 +1,77 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
#else
import Postbox
import SwiftSignalKit
#endif
private final class CachedStickerPack: Coding {
let items: [StickerPackItem]
let hash: Int32
init(items: [StickerPackItem], hash: Int32) {
self.items = items
self.hash = hash
}
init(decoder: Decoder) {
self.items = decoder.decodeObjectArrayForKey("it").map { $0 as! StickerPackItem }
self.hash = decoder.decodeInt32ForKey("h", orElse: 0)
}
func encode(_ encoder: Encoder) {
encoder.encodeObjectArray(self.items, forKey: "it")
encoder.encodeInt32(self.hash, forKey: "h")
}
static func cacheKey(_ info: StickerPackCollectionInfo) -> ValueBoxKey {
let key = ValueBoxKey(length: 4 + 8)
key.setInt32(0, value: info.id.namespace)
key.setInt64(4, value: info.id.id)
return key
}
}
private let collectionSpec = ItemCacheCollectionSpec(lowWaterItemCount: 100, highWaterItemCount: 200)
public func cachedStickerPack(postbox: Postbox, network: Network, info: StickerPackCollectionInfo) -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem])?, NoError> {
return postbox.modify { modifier -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem])?, NoError> in
if let currentInfo = modifier.getItemCollectionInfo(collectionId: info.id) as? StickerPackCollectionInfo {
let items = modifier.getItemCollectionItems(collectionId: info.id)
return .single((currentInfo, items))
} else {
let current: Signal<(StickerPackCollectionInfo, [ItemCollectionItem])?, NoError>
var loadRemote = false
if let cached = modifier.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(info))) as? CachedStickerPack {
current = .single((info, cached.items))
if cached.hash != info.hash {
loadRemote = true
}
} else {
current = .complete()
loadRemote = true
}
var signal = current
if loadRemote {
let appliedRemote = remoteStickerPack(network: network, reference: .id(id: info.id.id, accessHash: info.accessHash))
|> mapToSignal { result -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem])?, NoError> in
return postbox.modify { modifier -> (StickerPackCollectionInfo, [ItemCollectionItem])? in
if let result = result {
modifier.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(result.0)), entry: CachedStickerPack(items: result.1.map { $0 as! StickerPackItem }, hash: result.0.hash), collectionSpec: collectionSpec)
}
return result
}
}
signal = signal |> then(appliedRemote)
}
return signal
}
} |> switchToLatest
}

View File

@@ -13,14 +13,22 @@ public func installInteractiveReadMessagesAction(postbox: Postbox, peerId: PeerI
for message in messages {
if case let .Id(id) = message.id {
var hasUnconsumedMention = false
var hasUnconsumedContent = false
if message.tags.contains(.unseenPersonalMessage) {
inner: for attribute in message.attributes {
if let attribute = attribute as? ConsumablePersonalMentionMessageAttribute, !attribute.consumed, !attribute.pending {
consumeMessageIds.append(id)
break inner
hasUnconsumedMention = true
} else if let attribute = attribute as? ConsumableContentMessageAttribute, !attribute.consumed {
hasUnconsumedContent = true
}
}
}
if hasUnconsumedMention && !hasUnconsumedContent {
consumeMessageIds.append(id)
}
}
}

View File

@@ -28,6 +28,64 @@ public enum LoadedStickerPack {
case result(info: StickerPackCollectionInfo, items: [ItemCollectionItem], installed: Bool)
}
func remoteStickerPack(network: Network, reference: StickerPackReference) -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem])?, NoError> {
return network.request(Api.functions.messages.getStickerSet(stickerset: reference.apiInputStickerSet))
|> map { Optional($0) }
|> `catch` { _ -> Signal<Api.messages.StickerSet?, NoError> in
return .single(nil)
}
|> map { result -> (StickerPackCollectionInfo, [ItemCollectionItem])? in
guard let result = result else {
return nil
}
let info: StickerPackCollectionInfo
var items: [ItemCollectionItem] = []
switch result {
case let .stickerSet(set, packs, documents):
let namespace: ItemCollectionId.Namespace
switch set {
case let .stickerSet(flags, _, _, _, _, _, _):
if (flags & (1 << 3)) != 0 {
namespace = Namespaces.ItemCollection.CloudMaskPacks
} else {
namespace = Namespaces.ItemCollection.CloudStickerPacks
}
}
info = StickerPackCollectionInfo(apiSet: set, namespace: namespace)
var indexKeysByFile: [MediaId: [MemoryBuffer]] = [:]
for pack in packs {
switch pack {
case let .stickerPack(text, fileIds):
let key = ValueBoxKey(text).toMemoryBuffer()
for fileId in fileIds {
let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)
if indexKeysByFile[mediaId] == nil {
indexKeysByFile[mediaId] = [key]
} else {
indexKeysByFile[mediaId]!.append(key)
}
}
}
}
for apiDocument in documents {
if let file = telegramMediaFileFromApiDocument(apiDocument), let id = file.id {
let fileIndexKeys: [MemoryBuffer]
if let indexKeys = indexKeysByFile[id] {
fileIndexKeys = indexKeys
} else {
fileIndexKeys = []
}
items.append(StickerPackItem(index: ItemCollectionItemIndex(index: Int32(items.count), id: id.id), file: file, indexKeys: fileIndexKeys))
}
}
}
return (info, items)
}
}
public func loadedStickerPack(account: Account, reference: StickerPackReference) -> Signal<LoadedStickerPack, NoError> {
return account.postbox.modify { modifier -> Signal<LoadedStickerPack, NoError> in
switch reference {
@@ -57,68 +115,21 @@ public func loadedStickerPack(account: Account, reference: StickerPackReference)
break
}
let signal: Signal<LoadedStickerPack, NoError> = account.network.request(Api.functions.messages.getStickerSet(stickerset: reference.apiInputStickerSet))
|> map { Optional($0) }
|> `catch` { _ -> Signal<Api.messages.StickerSet?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<LoadedStickerPack, NoError> in
guard let result = result else {
return .single(.none)
}
let info: StickerPackCollectionInfo
var items: [ItemCollectionItem] = []
switch result {
case let .stickerSet(set, packs, documents):
let namespace: ItemCollectionId.Namespace
switch set {
case let .stickerSet(flags, _, _, _, _, _, _):
if (flags & (1 << 3)) != 0 {
namespace = Namespaces.ItemCollection.CloudMaskPacks
} else {
namespace = Namespaces.ItemCollection.CloudStickerPacks
}
}
info = StickerPackCollectionInfo(apiSet: set, namespace: namespace)
var indexKeysByFile: [MediaId: [MemoryBuffer]] = [:]
for pack in packs {
switch pack {
case let .stickerPack(text, fileIds):
let key = ValueBoxKey(text).toMemoryBuffer()
for fileId in fileIds {
let mediaId = MediaId(namespace: Namespaces.Media.CloudFile, id: fileId)
if indexKeysByFile[mediaId] == nil {
indexKeysByFile[mediaId] = [key]
} else {
indexKeysByFile[mediaId]!.append(key)
}
}
}
}
for apiDocument in documents {
if let file = telegramMediaFileFromApiDocument(apiDocument), let id = file.id {
let fileIndexKeys: [MemoryBuffer]
if let indexKeys = indexKeysByFile[id] {
fileIndexKeys = indexKeys
} else {
fileIndexKeys = []
}
items.append(StickerPackItem(index: ItemCollectionItemIndex(index: Int32(items.count), id: id.id), file: file, indexKeys: fileIndexKeys))
}
}
}
return account.postbox.combinedView(keys: [PostboxViewKey.itemCollectionInfo(id: info.id)])
|> map { view in
if let view = view.views[PostboxViewKey.itemCollectionInfo(id: info.id)] as? ItemCollectionInfoView, let info = view.info as? StickerPackCollectionInfo {
return .result(info: info, items: items, installed: true)
} else {
return .result(info: info, items: items, installed: false)
}
let signal = remoteStickerPack(network: account.network, reference: reference) |> mapToSignal { result -> Signal<LoadedStickerPack, NoError> in
if let result = result {
return account.postbox.combinedView(keys: [PostboxViewKey.itemCollectionInfo(id: result.0.id)])
|> map { view in
if let view = view.views[PostboxViewKey.itemCollectionInfo(id: result.0.id)] as? ItemCollectionInfoView, let info = view.info as? StickerPackCollectionInfo {
return .result(info: info, items: result.1, installed: true)
} else {
return .result(info: result.0, items: result.1, installed: false)
}
}
}
} else {
return .single(.none)
}
}
return .single(.fetching) |> then(signal)
} |> switchToLatest
}

View File

@@ -37,12 +37,14 @@ final class ManagedDeviceContactEntryContents: Coding {
let lastName: String
let phoneNumber: String
let peerId: PeerId?
let importDelayedUntil: Int32?
init(firstName: String, lastName: String, phoneNumber: String, peerId: PeerId?) {
init(firstName: String, lastName: String, phoneNumber: String, peerId: PeerId?, importDelayedUntil: Int32?) {
self.firstName = firstName
self.lastName = lastName
self.phoneNumber = phoneNumber
self.peerId = peerId
self.importDelayedUntil = importDelayedUntil
}
init(decoder: Decoder) {
@@ -54,6 +56,7 @@ final class ManagedDeviceContactEntryContents: Coding {
} else {
self.peerId = nil
}
self.importDelayedUntil = decoder.decodeOptionalInt32ForKey("dt")
}
func encode(_ encoder: Encoder) {
@@ -65,10 +68,19 @@ final class ManagedDeviceContactEntryContents: Coding {
} else {
encoder.encodeNil(forKey: "p")
}
if let importDelayedUntil = self.importDelayedUntil {
encoder.encodeInt32(importDelayedUntil, forKey: "dt")
} else {
encoder.encodeNil(forKey: "dt")
}
}
func withUpdatedPeerId(_ peerId: PeerId?) -> ManagedDeviceContactEntryContents {
return ManagedDeviceContactEntryContents(firstName: self.firstName, lastName: self.lastName, phoneNumber: self.phoneNumber, peerId: peerId)
return ManagedDeviceContactEntryContents(firstName: self.firstName, lastName: self.lastName, phoneNumber: self.phoneNumber, peerId: peerId, importDelayedUntil: self.importDelayedUntil)
}
func withUpdatedImportDelayedUntil(_ importDelayedUntil: Int32?) -> ManagedDeviceContactEntryContents {
return ManagedDeviceContactEntryContents(firstName: self.firstName, lastName: self.lastName, phoneNumber: self.phoneNumber, peerId: self.peerId, importDelayedUntil: importDelayedUntil)
}
}
@@ -76,7 +88,7 @@ private func unorderedListEntriesForDeviceContact(_ deviceContact: DeviceContact
var entries: [UnorderedItemListEntry] = []
for phoneNumber in deviceContact.phoneNumbers {
let stringToHash = "\(deviceContact.firstName):\(deviceContact.lastName):\(phoneNumber.number)"
entries.append(UnorderedItemListEntry(id: ValueBoxKey(phoneNumber.number), info: UnorderedItemListEntryInfo(hashValue: Int64(stringToHash.hashValue)), contents: ManagedDeviceContactEntryContents(firstName: deviceContact.firstName, lastName: deviceContact.lastName, phoneNumber: phoneNumber.number, peerId: nil)))
entries.append(UnorderedItemListEntry(id: ValueBoxKey(phoneNumber.number), info: UnorderedItemListEntryInfo(hashValue: Int64(stringToHash.hashValue)), contents: ManagedDeviceContactEntryContents(firstName: deviceContact.firstName, lastName: deviceContact.lastName, phoneNumber: phoneNumber.number, peerId: nil, importDelayedUntil: nil)))
}
return entries
}
@@ -106,9 +118,21 @@ func managedDeviceContacts(postbox: Postbox, network: Network, deviceContacts: S
let appliedDifference = postbox.modify { modifier -> Signal<Void, ManagedDeviceContactsError> in
let (metaInfo, added, removed, updated) = modifier.unorderedItemListDifference(tag: Namespaces.UnorderedItemList.synchronizedDeviceContacts, updatedEntryInfos: infos)
let timestamp = Int32(CFAbsoluteTimeGetCurrent())
var reimportKeys = Set<ValueBoxKey>()
modifier.unorderedItemListScan(tag: Namespaces.UnorderedItemList.synchronizedDeviceContacts, { entry in
if let contents = entry.contents as? ManagedDeviceContactEntryContents {
if let importDelayedUntil = contents.importDelayedUntil, importDelayedUntil <= timestamp {
reimportKeys.insert(entry.id)
}
}
})
var addedOrUpdatedContacts: [ManagedDeviceContactEntryContents] = []
for id in added {
reimportKeys.remove(id)
if let entry = entries[id], let contents = entry.contents as? ManagedDeviceContactEntryContents {
addedOrUpdatedContacts.append(contents)
} else {
@@ -117,6 +141,8 @@ func managedDeviceContacts(postbox: Postbox, network: Network, deviceContacts: S
}
for previousEntry in updated {
reimportKeys.remove(previousEntry.id)
if let entry = entries[previousEntry.id], let contents = entry.contents as? ManagedDeviceContactEntryContents {
addedOrUpdatedContacts.append(contents)
} else {
@@ -126,6 +152,8 @@ func managedDeviceContacts(postbox: Postbox, network: Network, deviceContacts: S
var removedPeerIds: [PeerId] = []
for entry in removed {
reimportKeys.remove(entry.id)
if let contents = entry.contents as? ManagedDeviceContactEntryContents {
if let peerId = contents.peerId {
removedPeerIds.append(peerId)
@@ -133,6 +161,12 @@ func managedDeviceContacts(postbox: Postbox, network: Network, deviceContacts: S
}
}
for id in reimportKeys {
if let entry = entries[id], let contents = entry.contents as? ManagedDeviceContactEntryContents {
addedOrUpdatedContacts.append(contents)
}
}
return (applyRemovedContacts(postbox: postbox, network: network, peerIds: removedPeerIds)
|> map { _ -> ([Peer], [PeerId: PeerPresence], [ValueBoxKey: ManagedDeviceContactEntryContents]) in
assertionFailure()
@@ -264,9 +298,14 @@ private func applyAddedOrUpdatedContacts(network: Network, contacts: [ManagedDev
let reimportClientIds = Set(retryContacts)
let reimportTimestamp = Int32(CFAbsoluteTimeGetCurrent()) + Int32(1 * 60 * 60)
for (clientId, contents) in clientIdToContact {
if !importedClientIds.contains(clientId) && !reimportClientIds.contains(clientId) {
importedContents[ValueBoxKey(contents.phoneNumber)] = contents
if !importedClientIds.contains(clientId) {
var updatedContents = contents
if reimportClientIds.contains(clientId) {
updatedContents = updatedContents.withUpdatedImportDelayedUntil(reimportTimestamp)
}
importedContents[ValueBoxKey(contents.phoneNumber)] = updatedContents
}
}

View File

@@ -21,7 +21,9 @@ public func markMessageContentAsConsumedInteractively(postbox: Postbox, messageI
addSynchronizeConsumeMessageContentsOperation(modifier: modifier, messageIds: [message.id])
}
break
} else if let attribute = updatedAttributes[i] as? ConsumablePersonalMentionMessageAttribute, !attribute.consumed {
modifier.setPendingMessageAction(type: .consumeUnseenPersonalMessage, id: messageId, action: ConsumePersonalMessageAction())
updatedAttributes[i] = ConsumablePersonalMentionMessageAttribute(consumed: attribute.consumed, pending: true)
}
}
@@ -78,6 +80,7 @@ func markMessageContentAsConsumedRemotely(modifier: Modifier, messageId: Message
var updateMessage = false
var updatedAttributes = message.attributes
var updatedMedia = message.media
var updatedTags = message.tags
for i in 0 ..< updatedAttributes.count {
if let attribute = updatedAttributes[i] as? ConsumableContentMessageAttribute {
@@ -85,7 +88,12 @@ func markMessageContentAsConsumedRemotely(modifier: Modifier, messageId: Message
updatedAttributes[i] = ConsumableContentMessageAttribute(consumed: true)
updateMessage = true
}
break
} else if let attribute = updatedAttributes[i] as? ConsumablePersonalMentionMessageAttribute, !attribute.consumed {
if attribute.pending {
modifier.setPendingMessageAction(type: .consumeUnseenPersonalMessage, id: messageId, action: nil)
}
updatedAttributes[i] = ConsumablePersonalMentionMessageAttribute(consumed: true, pending: false)
updatedTags.remove(.unseenPersonalMessage)
}
}
@@ -118,7 +126,7 @@ func markMessageContentAsConsumedRemotely(modifier: Modifier, messageId: Message
if let forwardInfo = currentMessage.forwardInfo {
storeForwardInfo = StoreMessageForwardInfo(authorId: forwardInfo.author.id, sourceId: forwardInfo.source?.id, sourceMessageId: forwardInfo.sourceMessageId, date: forwardInfo.date, authorSignature: forwardInfo.authorSignature)
}
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: updatedAttributes, media: updatedMedia))
return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: updatedTags, globalTags: currentMessage.globalTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: updatedAttributes, media: updatedMedia))
})
}
}

View File

@@ -55,6 +55,7 @@ public struct Namespaces {
struct CachedItemCollection {
public static let resolvedByNamePeers: Int8 = 0
public static let cachedTwoStepToken: Int8 = 1
public static let cachedStickerPacks: Int8 = 2
}
struct UnorderedItemList {

View File

@@ -0,0 +1,36 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
#else
import Postbox
import SwiftSignalKit
#endif
private struct WrappedStickerPackCollectionInfo: Equatable {
let info: StickerPackCollectionInfo?
static func ==(lhs: WrappedStickerPackCollectionInfo, rhs: WrappedStickerPackCollectionInfo) -> Bool {
return lhs.info == rhs.info
}
}
public func peerSpecificStickerPack(postbox: Postbox, network: Network, peerId: PeerId) -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem])?, NoError> {
if peerId.namespace == Namespaces.Peer.CloudChannel {
return postbox.combinedView(keys: [.cachedPeerData(peerId: peerId)])
|> map { view -> WrappedStickerPackCollectionInfo in
let dataView = view.views[.cachedPeerData(peerId: peerId)] as? CachedPeerDataView
return WrappedStickerPackCollectionInfo(info: (dataView?.cachedPeerData as? CachedChannelData)?.stickerPack)
}
|> distinctUntilChanged
|> mapToSignal { info -> Signal<(StickerPackCollectionInfo, [ItemCollectionItem])?, NoError> in
if let info = info.info {
return cachedStickerPack(postbox: postbox, network: network, info: info)
} else {
return .single(nil)
}
}
} else {
return .single(nil)
}
}

View File

@@ -428,7 +428,7 @@ extension StoreMessage {
}
for case let file as TelegramMediaFile in medias {
if peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.CloudGroup {
if peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.CloudGroup || peerId.namespace == Namespaces.Peer.CloudChannel {
if file.isVoice {
consumableContent = (true, (flags & (1 << 5)) == 0)
break