no message

This commit is contained in:
Peter 2017-09-19 15:17:16 +03:00
parent 98632adefd
commit 9645d068bc
22 changed files with 361 additions and 111 deletions

View File

@ -459,6 +459,8 @@
D0B8444B1DAB91FD005F29E1 /* ManagedSynchronizePeerReadStates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0AB0B991D666520002C78E7 /* ManagedSynchronizePeerReadStates.swift */; };
D0B8444C1DAB91FD005F29E1 /* UpdateCachedPeerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B843861DA6F705005F29E1 /* UpdateCachedPeerData.swift */; };
D0B844531DAC0773005F29E1 /* TelegramUserPresence.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B844521DAC0773005F29E1 /* TelegramUserPresence.swift */; };
D0B85AC51F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B85AC41F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift */; };
D0B85AC61F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B85AC41F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift */; };
D0BB7C5A1E5C8074001527C3 /* ChannelParticipants.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BB7C591E5C8074001527C3 /* ChannelParticipants.swift */; };
D0BC386E1E3FDAB70044D6FE /* CreateGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BC386D1E3FDAB70044D6FE /* CreateGroup.swift */; };
D0BC38701E40853E0044D6FE /* UpdatePeers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BC386F1E40853E0044D6FE /* UpdatePeers.swift */; };
@ -490,6 +492,8 @@
D0CAF2EA1D75EC600011F558 /* MtProtoKitDynamic.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0CAF2E91D75EC600011F558 /* MtProtoKitDynamic.framework */; };
D0D748021E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D748011E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift */; };
D0D748031E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D748011E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift */; };
D0DA1D321F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA1D311F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift */; };
D0DA1D331F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA1D311F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift */; };
D0DB7F031F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DB7F021F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift */; };
D0DB7F041F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DB7F021F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift */; };
D0DC354E1DE368F7000195EB /* RequestChatContextResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC354D1DE368F7000195EB /* RequestChatContextResults.swift */; };
@ -837,6 +841,7 @@
D0B843B01DA7FF30005F29E1 /* NBPhoneNumberUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NBPhoneNumberUtil.h; sourceTree = "<group>"; };
D0B843B11DA7FF30005F29E1 /* NBPhoneNumberUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NBPhoneNumberUtil.m; sourceTree = "<group>"; };
D0B844521DAC0773005F29E1 /* TelegramUserPresence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TelegramUserPresence.swift; sourceTree = "<group>"; };
D0B85AC41F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentlyUsedHashtags.swift; sourceTree = "<group>"; };
D0BB7C591E5C8074001527C3 /* ChannelParticipants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelParticipants.swift; sourceTree = "<group>"; };
D0BC386D1E3FDAB70044D6FE /* CreateGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateGroup.swift; sourceTree = "<group>"; };
D0BC386F1E40853E0044D6FE /* UpdatePeers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdatePeers.swift; sourceTree = "<group>"; };
@ -856,6 +861,7 @@
D0C50E331E93A86600F62E39 /* CallSessionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallSessionManager.swift; sourceTree = "<group>"; };
D0CAF2E91D75EC600011F558 /* MtProtoKitDynamic.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MtProtoKitDynamic.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D0D748011E7AE98B00F4B1F6 /* StickerPackInteractiveOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StickerPackInteractiveOperations.swift; sourceTree = "<group>"; };
D0DA1D311F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedPendingPeerNotificationSettings.swift; sourceTree = "<group>"; };
D0DB7F021F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstallInteractiveReadMessagesAction.swift; sourceTree = "<group>"; };
D0DC354D1DE368F7000195EB /* RequestChatContextResults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestChatContextResults.swift; sourceTree = "<group>"; };
D0DC354F1DE36900000195EB /* ChatContextResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatContextResult.swift; sourceTree = "<group>"; };
@ -1278,6 +1284,7 @@
D0FA35071EA632E400E56FFA /* CollectCacheUsageStats.swift */,
D0642EF81F3E05D700792790 /* EarliestUnseenPersonalMentionMessage.swift */,
D0DB7F021F43030C00591D48 /* InstallInteractiveReadMessagesAction.swift */,
D0B85AC41F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift */,
);
name = Messages;
sourceTree = "<group>";
@ -1484,6 +1491,7 @@
C205FEA71EB3B75900455808 /* ExportMessageLink.swift */,
C230BEB51EE9A3760029586C /* ChannelAdminEventLogs.swift */,
D0A472B51F4CBE8B00E0EEDA /* LoadedPeer.swift */,
D0DA1D311F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift */,
);
name = Peers;
sourceTree = "<group>";
@ -1791,6 +1799,7 @@
D053B3FE1F16534400E2D58A /* MonotonicTime.swift in Sources */,
D0C50E341E93A86600F62E39 /* CallSessionManager.swift in Sources */,
D00D34421E6EDD2E0057B307 /* ManagedSynchronizeConsumeMessageContentsOperations.swift in Sources */,
D0DA1D321F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift in Sources */,
D099D7491EEF418D00A3128C /* HistoryViewChannelStateValidation.swift in Sources */,
C23BC3871E9BE3CA00D79F92 /* ImportContact.swift in Sources */,
D03B0D0A1D62255C00955575 /* Holes.swift in Sources */,
@ -1931,6 +1940,7 @@
D03B0CBB1D62233C00955575 /* MergeLists.swift in Sources */,
C239BE971E62EE1E00C2C453 /* LoadMessagesIfNecessary.swift in Sources */,
D03B0CC11D62235000955575 /* StringFormat.swift in Sources */,
D0B85AC51F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift in Sources */,
D0B843C31DA7FF30005F29E1 /* NBPhoneMetaDataGenerator.m in Sources */,
C2366C861E4F403C0097CCFF /* AddressNames.swift in Sources */,
D0B843C11DA7FF30005F29E1 /* NBPhoneMetaData.m in Sources */,
@ -2053,6 +2063,7 @@
D001F3EA1E128A1C007A8C60 /* TelegramPeerNotificationSettings.swift in Sources */,
D0FA8BA81E1FA6DF001E855B /* TelegramSecretChat.swift in Sources */,
C23BC3881E9BE3CB00D79F92 /* ImportContact.swift in Sources */,
D0B85AC61F6B2B9400B8B5CE /* RecentlyUsedHashtags.swift in Sources */,
D001F3EB1E128A1C007A8C60 /* EnqueueMessage.swift in Sources */,
D01A21A71F38CDC700DDA104 /* SynchronizeSavedStickersOperation.swift in Sources */,
D00C7CEC1E37A8540080C3D5 /* SetSecretChatMessageAutoremoveTimeoutInteractively.swift in Sources */,
@ -2094,6 +2105,7 @@
D001F3E81E128A1C007A8C60 /* ChannelState.swift in Sources */,
C2366C8A1E4F40480097CCFF /* SupportPeerId.swift in Sources */,
D08CAA811ED80ED20000FDA8 /* SuggestedLocalizationEntry.swift in Sources */,
D0DA1D331F7043D50034E892 /* ManagedPendingPeerNotificationSettings.swift in Sources */,
D0B844451DAB91FD005F29E1 /* AccountViewTracker.swift in Sources */,
D0C48F3D1E8142EF0075317D /* LoadedPeerFromMessage.swift in Sources */,
D0F3A8A01E82C65400B4C64C /* SynchronizeChatInputStateOperation.swift in Sources */,
@ -2700,6 +2712,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_SWIFT_FLAGS = "-DDEBUG";
PRODUCT_BUNDLE_IDENTIFIER = org.telegram.Telegram.TelegramCoreMac;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;

View File

@ -214,6 +214,7 @@ private var declaredEncodables: Void = {
declareEncodable(SynchronizeConsumeMessageContentsOperation.self, f: { SynchronizeConsumeMessageContentsOperation(decoder: $0) })
declareEncodable(RecentMediaItem.self, f: { RecentMediaItem(decoder: $0) })
declareEncodable(RecentPeerItem.self, f: { RecentPeerItem(decoder: $0) })
declareEncodable(RecentHashtagItem.self, f: { RecentHashtagItem(decoder: $0) })
declareEncodable(LoggedOutAccountAttribute.self, f: { LoggedOutAccountAttribute(decoder: $0) })
declareEncodable(CloudChatClearHistoryOperation.self, f: { CloudChatClearHistoryOperation(decoder: $0) })
declareEncodable(OutgoingContentInfoMessageAttribute.self, f: { OutgoingContentInfoMessageAttribute(decoder: $0) })
@ -628,6 +629,11 @@ public class Account {
}
self.managedServiceViewsDisposable.set(serviceTasksMaster.start())
let pendingMessageManager = self.pendingMessageManager
self.managedOperationsDisposable.add(postbox.unsentMessageIdsView().start(next: { [weak pendingMessageManager] view in
pendingMessageManager?.updatePendingMessageIds(view.ids)
}))
self.managedOperationsDisposable.add(managedSecretChatOutgoingOperations(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedCloudChatRemoveMessagesOperations(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
self.managedOperationsDisposable.add(managedAutoremoveMessageOperations(postbox: self.postbox).start())
@ -646,36 +652,29 @@ public class Account {
self.managedOperationsDisposable.add(managedSynchronizeChatInputStateOperations(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedConfigurationUpdates(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedLocalizationUpdatesOperations(postbox: self.postbox, network: self.network).start())
self.managedOperationsDisposable.add(managedPendingPeerNotificationSettings(postbox: self.postbox, network: self.network).start())
let updatedPresence = self.shouldKeepOnlinePresence.get()
|> distinctUntilChanged
|> mapToSignal { [weak self] online -> Signal<Void, NoError> in
if let strongSelf = self {
if online {
let delayRequest: Signal<Void, NoError> = .complete() |> delay(60.0, queue: Queue.concurrentDefaultQueue())
let pushStatusOnce = strongSelf.network.request(Api.functions.account.updateStatus(offline: .boolFalse))
|> retryRequest
|> mapToSignal { _ -> Signal<Void, NoError> in return .complete() }
let pushStatusRepeatedly = (pushStatusOnce |> then(delayRequest)) |> restart
let peerId = strongSelf.peerId
let updatePresenceLocally = strongSelf.postbox.modify { modifier -> Void in
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 + 60.0 * 60.0 * 24.0 * 356.0
modifier.updatePeerPresences([peerId: TelegramUserPresence(status: .present(until: Int32(timestamp)))])
let delayRequest: Signal<Void, NoError> = .complete() |> delay(60.0, queue: Queue.concurrentDefaultQueue())
let pushStatusOnce = strongSelf.network.request(Api.functions.account.updateStatus(offline: online ? .boolFalse : .boolTrue))
|> retryRequest
|> mapToSignal { _ -> Signal<Void, NoError> in return .complete() }
let pushStatusRepeatedly = (pushStatusOnce |> then(delayRequest)) |> restart
let peerId = strongSelf.peerId
let updatePresenceLocally = strongSelf.postbox.modify { modifier -> Void in
let timestamp: Double
if online {
timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 + 60.0 * 60.0 * 24.0 * 356.0
} else {
timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 - 1.0
}
return combineLatest(pushStatusRepeatedly, updatePresenceLocally)
|> mapToSignal { _ -> Signal<Void, NoError> in return .complete() }
} else {
let pushStatusOnce = strongSelf.network.request(Api.functions.account.updateStatus(offline: .boolTrue))
|> retryRequest
|> mapToSignal { _ -> Signal<Void, NoError> in return .complete() }
let peerId = strongSelf.peerId
let updatePresenceLocally = strongSelf.postbox.modify { modifier -> Void in
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 - 1.0
modifier.updatePeerPresences([peerId: TelegramUserPresence(status: .present(until: Int32(timestamp)))])
}
return combineLatest(pushStatusOnce, updatePresenceLocally)
|> mapToSignal { _ -> Signal<Void, NoError> in return .complete() }
modifier.updatePeerPresences([peerId: TelegramUserPresence(status: .present(until: Int32(timestamp)))])
}
return combineLatest(pushStatusRepeatedly, updatePresenceLocally)
|> mapToSignal { _ -> Signal<Void, NoError> in return .complete() }
} else {
return .complete()
}
@ -700,6 +699,10 @@ public class Account {
return self.peerInputActivityManager.activities(peerId: peerId)
}
public func allPeerInputActivities() -> Signal<[PeerId: [PeerId: PeerInputActivity]], NoError> {
return self.peerInputActivityManager.allActivities()
}
public func updateLocalInputActivity(peerId: PeerId, activity: PeerInputActivity, isPresent: Bool) {
self.localInputActivityManager.transaction { manager in
if isPresent {

View File

@ -936,6 +936,14 @@ private func finalStateWithUpdates(account: Account, state: AccountMutableState,
return peer
}
})
case let .updateUserPhoto(userId, _, photo, _):
updatedState.updatePeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), { peer in
if let user = peer as? TelegramUser {
return user.withUpdatedPhoto(parsedTelegramProfilePhoto(photo))
} else {
return peer
}
})
case let .updateUserPhone(userId, phone):
updatedState.updatePeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), { peer in
if let user = peer as? TelegramUser {
@ -1519,7 +1527,7 @@ func replayFinalState(accountPeerId: PeerId, mediaBox: MediaBox, modifier: Modif
case let .UpdateChannelState(peerId, channelState):
modifier.setPeerChatState(peerId, state: channelState)
case let .UpdatePeerNotificationSettings(peerId, notificationSettings):
modifier.updatePeerNotificationSettings([peerId: notificationSettings])
modifier.updateCurrentPeerNotificationSettings([peerId: notificationSettings])
case let .AddHole(messageId):
modifier.addHole(messageId)
case let .MergeApiChats(chats):

View File

@ -574,27 +574,27 @@ public final class AccountViewTracker {
}
}
public func aroundMessageOfInterestHistoryViewForPeerId(_ peerId: PeerId, count: Int, tagMask: MessageTags? = nil, orderStatistics: MessageHistoryViewOrderStatistics = [], additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
public func aroundMessageOfInterestHistoryViewForPeerId(_ peerId: PeerId, count: Int, clipHoles: Bool = true, tagMask: MessageTags? = nil, orderStatistics: MessageHistoryViewOrderStatistics = [], additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
if let account = self.account {
let signal = account.postbox.aroundMessageOfInterestHistoryViewForPeerId(peerId, count: count, topTaggedMessageIdNamespaces: [Namespaces.Message.Cloud], tagMask: tagMask, orderStatistics: orderStatistics, additionalData: wrappedHistoryViewAdditionalData(peerId: peerId, additionalData: additionalData))
let signal = account.postbox.aroundMessageOfInterestHistoryViewForPeerId(peerId, count: count, clipHoles: clipHoles, topTaggedMessageIdNamespaces: [Namespaces.Message.Cloud], tagMask: tagMask, orderStatistics: orderStatistics, additionalData: wrappedHistoryViewAdditionalData(peerId: peerId, additionalData: additionalData))
return wrappedMessageHistorySignal(peerId: peerId, signal: signal)
} else {
return .never()
}
}
public func aroundIdMessageHistoryViewForPeerId(_ peerId: PeerId, count: Int, messageId: MessageId, tagMask: MessageTags? = nil, orderStatistics: MessageHistoryViewOrderStatistics = [], additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
public func aroundIdMessageHistoryViewForPeerId(_ peerId: PeerId, count: Int, clipHoles: Bool = true, messageId: MessageId, tagMask: MessageTags? = nil, orderStatistics: MessageHistoryViewOrderStatistics = [], additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
if let account = self.account {
let signal = account.postbox.aroundIdMessageHistoryViewForPeerId(peerId, count: count, messageId: messageId, topTaggedMessageIdNamespaces: [Namespaces.Message.Cloud], tagMask: tagMask, orderStatistics: orderStatistics, additionalData: wrappedHistoryViewAdditionalData(peerId: peerId, additionalData: additionalData))
let signal = account.postbox.aroundIdMessageHistoryViewForPeerId(peerId, count: count, clipHoles: clipHoles, messageId: messageId, topTaggedMessageIdNamespaces: [Namespaces.Message.Cloud], tagMask: tagMask, orderStatistics: orderStatistics, additionalData: wrappedHistoryViewAdditionalData(peerId: peerId, additionalData: additionalData))
return wrappedMessageHistorySignal(peerId: peerId, signal: signal)
} else {
return .never()
}
}
public func aroundMessageHistoryViewForPeerId(_ peerId: PeerId, index: MessageIndex, count: Int, anchorIndex: MessageIndex, fixedCombinedReadState: CombinedPeerReadState?, tagMask: MessageTags? = nil, orderStatistics: MessageHistoryViewOrderStatistics = [], additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
public func aroundMessageHistoryViewForPeerId(_ peerId: PeerId, index: MessageIndex, count: Int, clipHoles: Bool = true, anchorIndex: MessageIndex, fixedCombinedReadState: CombinedPeerReadState?, tagMask: MessageTags? = nil, orderStatistics: MessageHistoryViewOrderStatistics = [], additionalData: [AdditionalMessageHistoryViewData] = []) -> Signal<(MessageHistoryView, ViewUpdateType, InitialMessageHistoryData?), NoError> {
if let account = self.account {
let signal = account.postbox.aroundMessageHistoryViewForPeerId(peerId, index: index, count: count, anchorIndex: anchorIndex, fixedCombinedReadState: fixedCombinedReadState, topTaggedMessageIdNamespaces: [Namespaces.Message.Cloud], tagMask: tagMask, orderStatistics: orderStatistics, additionalData: wrappedHistoryViewAdditionalData(peerId: peerId, additionalData: additionalData))
let signal = account.postbox.aroundMessageHistoryViewForPeerId(peerId, index: index, count: count, clipHoles: clipHoles, anchorIndex: anchorIndex, fixedCombinedReadState: fixedCombinedReadState, topTaggedMessageIdNamespaces: [Namespaces.Message.Cloud], tagMask: tagMask, orderStatistics: orderStatistics, additionalData: wrappedHistoryViewAdditionalData(peerId: peerId, additionalData: additionalData))
return wrappedMessageHistorySignal(peerId: peerId, signal: signal)
} else {
return .never()

View File

@ -9,7 +9,8 @@ import Foundation
private func applyMediaResourceChanges(from: Media, to: Media, postbox: Postbox) {
if let fromImage = from as? TelegramMediaImage, let toImage = to as? TelegramMediaImage {
if let fromSmallestRepresentation = smallestImageRepresentation(fromImage.representations), let toSmallestRepresentation = smallestImageRepresentation(toImage.representations) {
let fromSmallestRepresentation = smallestImageRepresentation(fromImage.representations)
if let fromSmallestRepresentation = fromSmallestRepresentation, let toSmallestRepresentation = smallestImageRepresentation(toImage.representations) {
postbox.mediaBox.moveResourceData(from: fromSmallestRepresentation.resource.id, to: toSmallestRepresentation.resource.id)
}
if let fromLargestRepresentation = largestImageRepresentation(fromImage.representations), let toLargestRepresentation = largestImageRepresentation(toImage.representations) {

View File

@ -8,7 +8,7 @@ import Foundation
#endif
public func togglePeerMuted(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
return account.postbox.modify { modifier -> Signal<Void, NoError> in
return account.postbox.modify { modifier -> Void in
if let peer = modifier.getPeer(peerId) {
var notificationPeerId = peerId
if let associatedPeerId = peer.associatedPeerId {
@ -30,57 +30,13 @@ public func togglePeerMuted(account: Account, peerId: PeerId) -> Signal<Void, No
case .muted:
updatedSettings = previousSettings.withUpdatedMuteState(.unmuted)
}
return changePeerNotificationSettings(account: account, peerId: notificationPeerId, settings: updatedSettings)
} else {
return .complete()
modifier.updatePendingPeerNotificationSettings(peerId: peerId, settings: updatedSettings)
}
} |> switchToLatest
}
}
public func changePeerNotificationSettings(account: Account, peerId: PeerId, settings: TelegramPeerNotificationSettings) -> Signal<Void, NoError> {
return account.postbox.modify { modifier -> Signal<Void, NoError> in
if let peer = modifier.getPeer(peerId) {
var notificationPeerId = peerId
if let associatedPeerId = peer.associatedPeerId {
notificationPeerId = associatedPeerId
}
if let notificationPeer = modifier.getPeer(notificationPeerId), let inputPeer = apiInputPeer(notificationPeer) {
return account.network.request(Api.functions.account.getNotifySettings(peer: .inputNotifyPeer(peer: inputPeer)))
|> retryRequest
|> mapToSignal { result -> Signal<Void, NoError> in
let current = TelegramPeerNotificationSettings(apiSettings: result)
let muteUntil: Int32
switch settings.muteState {
case let .muted(until):
muteUntil = until
case .unmuted:
muteUntil = 0
}
let sound: String
switch current.messageSound {
case .none:
sound = ""
case let .bundledModern(id):
sound = "\(id)"
case let .bundledClassic(id):
sound = "\(id + 12)"
}
let inputSettings = Api.InputPeerNotifySettings.inputPeerNotifySettings(flags: Int32(1 << 0), muteUntil: muteUntil, sound: sound)
return account.network.request(Api.functions.account.updateNotifySettings(peer: .inputNotifyPeer(peer: inputPeer), settings: inputSettings))
|> retryRequest
|> mapToSignal { result -> Signal<Void, NoError> in
return account.postbox.modify { modifier -> Void in
modifier.updatePeerNotificationSettings([notificationPeerId: settings])
}
}
}
} else {
return .complete()
}
} else {
return .complete()
}
} |> switchToLatest
return account.postbox.modify { modifier -> Void in
modifier.updatePendingPeerNotificationSettings(peerId: peerId, settings: settings)
}
}

View File

@ -20,8 +20,6 @@ private func md5(_ data : Data) -> Data {
}
private func updatedRemoteContactPeers(network: Network, hash: Int32) -> Signal<([Peer], [PeerId: PeerPresence], Int32)?, NoError> {
return .never()
return network.request(Api.functions.contacts.getContacts(hash: hash))
|> retryRequest
|> map { result -> ([Peer], [PeerId: PeerPresence], Int32)? in

View File

@ -155,6 +155,8 @@ func enqueueMessages(modifier: Modifier, account: Account, peerId: PeerId, messa
break
}
var addedHashtags: [String] = []
var globallyUniqueIds: [Int64] = []
for (transformedMedia, message) in messages {
var attributes: [MessageAttribute] = []
@ -202,6 +204,29 @@ func enqueueMessages(modifier: Modifier, account: Account, peerId: PeerId, messa
for attribute in attributes {
if let attribute = attribute as? TextEntitiesMessageAttribute {
entitiesAttribute = attribute
var maybeNsText: NSString?
for entity in attribute.entities {
if case .Hashtag = entity.type {
let nsText: NSString
if let maybeNsText = maybeNsText {
nsText = maybeNsText
} else {
nsText = text as NSString
maybeNsText = nsText
}
var entityRange = NSRange(location: entity.range.lowerBound, length: entity.range.upperBound - entity.range.lowerBound)
if entityRange.location + entityRange.length > nsText.length {
entityRange.location = max(0, nsText.length - entityRange.length)
entityRange.length = nsText.length - entityRange.location
}
if entityRange.length > 1 {
entityRange.location += 1
entityRange.length -= 1
let hashtag = nsText.substring(with: entityRange)
addedHashtags.append(hashtag)
}
}
}
break
}
}
@ -272,6 +297,9 @@ func enqueueMessages(modifier: Modifier, account: Account, peerId: PeerId, messa
messageIds.append(globallyUniqueIdToMessageId[globallyUniqueId])
}
}
for hashtag in addedHashtags {
addRecentlyUsedHashtag(modifier: modifier, string: hashtag)
}
return messageIds
} else {
return []

View File

@ -448,7 +448,7 @@ func fetchChatListHole(network: Network, postbox: Postbox, hole: ChatListHole) -
})
modifier.updatePeerPresences(peerPresences)
modifier.updatePeerNotificationSettings(notificationSettings)
modifier.updateCurrentPeerNotificationSettings(notificationSettings)
var allPeersWithMessages = Set<PeerId>()
for message in storeMessages {

View File

@ -0,0 +1,151 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
import MtProtoKitMac
#else
import Postbox
import SwiftSignalKit
import MtProtoKitDynamic
#endif
private final class ManagedPendingPeerNotificationSettingsHelper {
var operationDisposables: [PeerId: (PeerNotificationSettings, Disposable)] = [:]
func update(entries: [PeerId: PeerNotificationSettings]) -> (disposeOperations: [Disposable], beginOperations: [(PeerId, PeerNotificationSettings, MetaDisposable)]) {
var disposeOperations: [Disposable] = []
var beginOperations: [(PeerId, PeerNotificationSettings, MetaDisposable)] = []
var validIds = Set<PeerId>()
for (peerId, settings) in entries {
validIds.insert(peerId)
if let (currentSettings, currentDisposable) = self.operationDisposables[peerId] {
if !currentSettings.isEqual(to: settings) {
disposeOperations.append(currentDisposable)
let disposable = MetaDisposable()
beginOperations.append((peerId, settings, disposable))
self.operationDisposables[peerId] = (settings, disposable)
}
} else {
let disposable = MetaDisposable()
beginOperations.append((peerId, settings, disposable))
self.operationDisposables[peerId] = (settings, disposable)
}
}
var removeIds: [PeerId] = []
for (id, settingsAndDisposable) in self.operationDisposables {
if !validIds.contains(id) {
removeIds.append(id)
disposeOperations.append(settingsAndDisposable.1)
}
}
for id in removeIds {
self.operationDisposables.removeValue(forKey: id)
}
return (disposeOperations, beginOperations)
}
func reset() -> [Disposable] {
let disposables = Array(self.operationDisposables.values).map { $0.1 }
self.operationDisposables.removeAll()
return disposables
}
}
func managedPendingPeerNotificationSettings(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
return Signal { _ in
let helper = Atomic<ManagedPendingPeerNotificationSettingsHelper>(value: ManagedPendingPeerNotificationSettingsHelper())
let disposable = postbox.combinedView(keys: [.pendingPeerNotificationSettings]).start(next: { view in
var entries: [PeerId: PeerNotificationSettings] = [:]
if let v = view.views[.pendingPeerNotificationSettings] as? PendingPeerNotificationSettingsView {
entries = v.entries
}
let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(PeerId, PeerNotificationSettings, MetaDisposable)]) in
return helper.update(entries: entries)
}
for disposable in disposeOperations {
disposable.dispose()
}
for (peerId, settings, disposable) in beginOperations {
let signal = pushPeerNotificationSettings(postbox: postbox, network: network, peerId: peerId, settings: settings)
disposable.set(signal.start())
}
})
return ActionDisposable {
let disposables = helper.with { helper -> [Disposable] in
return helper.reset()
}
for disposable in disposables {
disposable.dispose()
}
disposable.dispose()
}
}
}
private func pushPeerNotificationSettings(postbox: Postbox, network: Network, peerId: PeerId, settings: PeerNotificationSettings) -> Signal<Void, NoError> {
return postbox.modify { modifier -> Signal<Void, NoError> in
if let peer = modifier.getPeer(peerId) {
var notificationPeerId = peerId
if let associatedPeerId = peer.associatedPeerId {
notificationPeerId = associatedPeerId
}
if let notificationPeer = modifier.getPeer(notificationPeerId), let inputPeer = apiInputPeer(notificationPeer), let settings = settings as? TelegramPeerNotificationSettings {
return network.request(Api.functions.account.getNotifySettings(peer: .inputNotifyPeer(peer: inputPeer)))
|> retryRequest
|> mapToSignal { result -> Signal<Void, NoError> in
let current = TelegramPeerNotificationSettings(apiSettings: result)
let muteUntil: Int32
switch settings.muteState {
case let .muted(until):
muteUntil = until
case .unmuted:
muteUntil = 0
}
let sound: String
switch current.messageSound {
case .none:
sound = ""
case let .bundledModern(id):
sound = "\(id)"
case let .bundledClassic(id):
sound = "\(id + 12)"
}
let inputSettings = Api.InputPeerNotifySettings.inputPeerNotifySettings(flags: Int32(1 << 0), muteUntil: muteUntil, sound: sound)
return network.request(Api.functions.account.updateNotifySettings(peer: .inputNotifyPeer(peer: inputPeer), settings: inputSettings))
|> retryRequest
|> mapToSignal { result -> Signal<Void, NoError> in
return postbox.modify { modifier -> Void in
modifier.updateCurrentPeerNotificationSettings([notificationPeerId: settings])
if let pending = modifier.getPendingPeerNotificationSettings(peerId), pending.isEqual(to: settings) {
modifier.updatePendingPeerNotificationSettings(peerId: peerId, settings: nil)
}
}
}
}
} else {
if let pending = modifier.getPendingPeerNotificationSettings(peerId), pending.isEqual(to: settings) {
modifier.updatePendingPeerNotificationSettings(peerId: peerId, settings: nil)
}
return .complete()
}
} else {
if let pending = modifier.getPendingPeerNotificationSettings(peerId), pending.isEqual(to: settings) {
modifier.updatePendingPeerNotificationSettings(peerId: peerId, settings: nil)
}
return .complete()
}
} |> switchToLatest
}

View File

@ -14,14 +14,6 @@ func managedServiceViews(network: Network, postbox: Postbox, stateManager: Accou
disposable.add(managedChatListHoles(network: network, postbox: postbox).start())
disposable.add(managedSynchronizePeerReadStates(network: network, postbox: postbox, stateManager: stateManager).start())
let pendingMessagesDisposable = postbox.unsentMessageIdsView().start(next: { view in
pendingMessageManager.updatePendingMessageIds(view.ids)
})
disposable.add(ActionDisposable(action: {
pendingMessagesDisposable.dispose()
pendingMessageManager.updatePendingMessageIds(Set())
}))
return disposable
}
}

View File

@ -221,7 +221,7 @@ private func synchronizePinnedChats(modifier: Modifier, postbox: Postbox, networ
modifier.updatePeerPresences(peerPresences)
modifier.updatePeerNotificationSettings(notificationSettings)
modifier.updateCurrentPeerNotificationSettings(notificationSettings)
var allPeersWithMessages = Set<PeerId>()
for message in storeMessages {
@ -236,7 +236,7 @@ private func synchronizePinnedChats(modifier: Modifier, postbox: Postbox, networ
for (peerId, chatState) in chatStates {
if let chatState = chatState as? ChannelState {
if let current = modifier.getPeerChatState(peerId) as? ChannelState {
modifier.setPeerChatState(peerId, state: current.withUpdatedPts(chatState.pts))
// skip changing state
} else {
modifier.setPeerChatState(peerId, state: chatState)
}

View File

@ -506,6 +506,7 @@ private final class MultipartFetchManager {
}
processedParts.sort(by: { $0.0 < $1.0 })
var nextOffset = self.committedOffset
var requestPartSize = self.defaultPartSize
for (offset, size) in processedParts {
if offset >= self.committedOffset {
if offset == nextOffset {
@ -516,8 +517,12 @@ private final class MultipartFetchManager {
}
}
if nextOffset / (1024 * 1024) != (nextOffset + requestPartSize - 1) / (1024 * 1024) {
let nextBoundary = (nextOffset / (1024 * 1024) + 1) * (1024 * 1024)
requestPartSize = nextBoundary - nextOffset
}
if nextOffset < self.range.upperBound {
let requestPartSize = self.defaultPartSize
let partSize = min(requestPartSize, self.range.upperBound - nextOffset)
let part = self.source.request(offset: Int32(nextOffset), limit: Int32(requestPartSize))
|> deliverOn(self.queue)

View File

@ -50,6 +50,7 @@ public struct Namespaces {
public static let CloudArchivedStickerPacks: Int32 = 5
public static let CloudWallpapers: Int32 = 6
public static let CloudSavedStickers: Int32 = 7
public static let RecentlyUsedHashtags: Int32 = 8
}
struct CachedItemCollection {

View File

@ -144,7 +144,7 @@ public func outgoingMessageWithChatContextResult(_ results: ChatContextResultCol
arc4random_buf(&randomId, 8)
let thumbnailResource = HttpReferenceMediaResource(url: thumbnailUrl, size: nil)
let imageDimensions = dimensions ?? CGSize(width: 128.0, height: 128.0)
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: [TelegramMediaImageRepresentation(dimensions: aspectFitSize(imageDimensions, to: CGSize(width: 90.0, height: 90.0)), resource: thumbnailResource)])
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: [TelegramMediaImageRepresentation(dimensions: imageDimensions, resource: thumbnailResource)])
return .message(text: caption, attributes: attributes, media: tmpImage, replyToMessageId: nil)
} else {
return .message(text: caption, attributes: attributes, media: nil, replyToMessageId: nil)

View File

@ -19,6 +19,12 @@ public func removeRecentlySearchedPeer(postbox: Postbox, peerId: PeerId) -> Sign
}
}
public func clearRecentlySearchedPeers(postbox: Postbox) -> Signal<Void, NoError> {
return postbox.modify { modifier -> Void in
modifier.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.RecentlySearchedPeerIds, items: [])
}
}
public func recentlySearchedPeers(postbox: Postbox) -> Signal<[RenderedPeer], NoError> {
return postbox.combinedView(keys: [.orderedItemList(id: Namespaces.OrderedItemList.RecentlySearchedPeerIds)])
|> mapToSignal { view -> Signal<[RenderedPeer], NoError> in

View File

@ -0,0 +1,70 @@
import Foundation
#if os(macOS)
import PostboxMac
import SwiftSignalKitMac
#else
import Postbox
import SwiftSignalKit
#endif
private struct RecentHashtagItemId {
public let rawValue: MemoryBuffer
var value: String {
return String(data: self.rawValue.makeData(), encoding: .utf8) ?? ""
}
init(_ rawValue: MemoryBuffer) {
self.rawValue = rawValue
}
init?(_ value: String) {
if let data = value.data(using: .utf8) {
self.rawValue = MemoryBuffer(data: data)
} else {
return nil
}
}
}
final class RecentHashtagItem: OrderedItemListEntryContents {
init() {
}
public init(decoder: PostboxDecoder) {
}
public func encode(_ encoder: PostboxEncoder) {
}
}
func addRecentlyUsedHashtag(modifier: Modifier, string: String) {
if let itemId = RecentHashtagItemId(string) {
modifier.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlyUsedHashtags, item: OrderedItemListEntry(id: itemId.rawValue, contents: RecentHashtagItem()), removeTailIfCountExceeds: 100)
}
}
public func removeRecentlyUsedHashtag(postbox: Postbox, string: String) -> Signal<Void, NoError> {
return postbox.modify { modifier -> Void in
if let itemId = RecentHashtagItemId(string) {
modifier.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlyUsedHashtags, itemId: itemId.rawValue)
}
}
}
public func recentlyUsedHashtags(postbox: Postbox) -> Signal<[String], NoError> {
return postbox.combinedView(keys: [.orderedItemList(id: Namespaces.OrderedItemList.RecentlyUsedHashtags)])
|> mapToSignal { view -> Signal<[String], NoError> in
return postbox.modify { modifier -> [String] in
var result: [String] = []
if let view = view.views[.orderedItemList(id: Namespaces.OrderedItemList.RecentlyUsedHashtags)] as? OrderedItemListView {
for item in view.items {
let value = RecentHashtagItemId(item.id).value
result.append(value)
}
}
return result
}
}
}

View File

@ -34,6 +34,7 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
}
} else if let file = attachment as? TelegramMediaFile {
var refinedTag: MessageTags? = .file
var isAnimated = false
inner: for attribute in file.attributes {
switch attribute {
case let .Video(_, _, flags):
@ -57,10 +58,15 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
case .Sticker:
refinedTag = nil
break inner
case .Animated:
isAnimated = true
default:
break
}
}
if isAnimated {
refinedTag = nil
}
if let refinedTag = refinedTag {
tags.insert(refinedTag)
}

View File

@ -107,15 +107,20 @@ public func addSavedSticker(postbox: Postbox, network: Network, file: TelegramMe
fetchReference = packReference
case let .id(id, _):
let items = modifier.getItemCollectionItems(collectionId: ItemCollectionId(namespace: Namespaces.ItemCollection.CloudStickerPacks, id: id))
var found = false
inner: for item in items {
if let stickerItem = item as? StickerPackItem {
if stickerItem.file.fileId == file.fileId {
let stringRepresentations = stickerItem.getStringRepresentationsOfIndexKeys()
found = true
addSavedSticker(modifier: modifier, file: stickerItem.file, stringRepresentations: stringRepresentations)
break inner
}
}
}
if !found {
fetchReference = packReference
}
}
if let fetchReference = fetchReference {
return network.request(Api.functions.messages.getStickerSet(stickerset: fetchReference.apiInputStickerSet))

View File

@ -222,6 +222,22 @@ public final class TelegramUser: Peer {
}
}
func parsedTelegramProfilePhoto(_ photo: Api.UserProfilePhoto?) -> [TelegramMediaImageRepresentation] {
var telegramPhoto: [TelegramMediaImageRepresentation] = []
if let photo = photo {
switch photo {
case let .userProfilePhoto(_, photoSmall, photoBig):
if let smallResource = mediaResourceFromApiFileLocation(photoSmall, size: nil), let largeResource = mediaResourceFromApiFileLocation(photoBig, size: nil) {
telegramPhoto.append(TelegramMediaImageRepresentation(dimensions: CGSize(width: 80.0, height: 80.0), resource: smallResource))
telegramPhoto.append(TelegramMediaImageRepresentation(dimensions: CGSize(width: 640.0, height: 640.0), resource: largeResource))
}
case .userProfilePhotoEmpty:
break
}
}
return telegramPhoto
}
public extension TelegramUser {
public convenience init(user: Api.User) {
switch user {
@ -270,18 +286,7 @@ public extension TelegramUser {
if let _ = accessHash {
return TelegramUser(user: rhs)
} else {
var telegramPhoto: [TelegramMediaImageRepresentation] = []
if let photo = photo {
switch photo {
case let .userProfilePhoto(_, photoSmall, photoBig):
if let smallResource = mediaResourceFromApiFileLocation(photoSmall, size: nil), let largeResource = mediaResourceFromApiFileLocation(photoBig, size: nil) {
telegramPhoto.append(TelegramMediaImageRepresentation(dimensions: CGSize(width: 80.0, height: 80.0), resource: smallResource))
telegramPhoto.append(TelegramMediaImageRepresentation(dimensions: CGSize(width: 640.0, height: 640.0), resource: largeResource))
}
case .userProfilePhotoEmpty:
break
}
}
let telegramPhoto = parsedTelegramProfilePhoto(photo)
if let lhs = lhs {
var userFlags: UserInfoFlags = []
if (flags & (1 << 17)) != 0 {

View File

@ -114,7 +114,7 @@ func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Pos
updatePeers(modifier: modifier, peers: [telegramUser], update: { _, updated -> Peer in
return updated
})
modifier.updatePeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
modifier.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
if let presence = TelegramUserPresence(apiUser: user) {
modifier.updatePeerPresences([peer.id: presence])
}
@ -149,7 +149,7 @@ func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Pos
case let .chatFull(fullChat, chats, users):
switch fullChat {
case let .chatFull(_, _, _, notifySettings, _, _):
modifier.updatePeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
modifier.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
case .channelFull:
break
}
@ -214,7 +214,7 @@ func fetchAndUpdateCachedPeerData(peerId: PeerId, network: Network, postbox: Pos
case let .chatFull(fullChat, chats, users):
switch fullChat {
case let .channelFull(_, _, _, _, _, _, _, _, _, _, _, notifySettings, _, _, _, _, _, _):
modifier.updatePeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
modifier.updateCurrentPeerNotificationSettings([peerId: TelegramPeerNotificationSettings(apiSettings: notifySettings)])
case .chatFull:
break
}

View File

@ -252,6 +252,8 @@ extension Api.Update {
} else {
return []
}
case let .updateDraftMessage(peer: peer, draft: _):
return [peer.peerId]
default:
return []
}