From 2586a1bc7099a29b3c2d599b7dc5d1eab532ecb5 Mon Sep 17 00:00:00 2001 From: Ali <> Date: Sun, 1 Dec 2019 17:59:45 +0400 Subject: [PATCH] Report read for live locations --- .../Sources/LegacyLocationController.swift | 3 + .../Sources/AccountViewTracker.swift | 59 +++++++++++++++++++ .../TelegramUI/ChatHistoryListNode.swift | 13 ++++ 3 files changed, 75 insertions(+) diff --git a/submodules/LocationUI/Sources/LegacyLocationController.swift b/submodules/LocationUI/Sources/LegacyLocationController.swift index 10a6702474..473b1f5708 100644 --- a/submodules/LocationUI/Sources/LegacyLocationController.swift +++ b/submodules/LocationUI/Sources/LegacyLocationController.swift @@ -201,6 +201,9 @@ public func legacyLocationController(message: Message?, mapMedia: TelegramMediaM controller.setLiveLocationsSignal(.single(freezeLocations)) } else { controller.setLiveLocationsSignal(updatedLocations) + if message.flags.contains(.Incoming) { + context.account.viewTracker.updateSeenLiveLocationForMessageIds(messageIds: Set([message.id])) + } } } else { controller = TGLocationViewController(context: legacyController.context, message: legacyMessage, peer: legacyAuthor, color: venueColor)! diff --git a/submodules/TelegramCore/Sources/AccountViewTracker.swift b/submodules/TelegramCore/Sources/AccountViewTracker.swift index cc330132a9..72372cb73b 100644 --- a/submodules/TelegramCore/Sources/AccountViewTracker.swift +++ b/submodules/TelegramCore/Sources/AccountViewTracker.swift @@ -253,6 +253,10 @@ public final class AccountViewTracker { private var nextUpdatedViewCountDisposableId: Int32 = 0 private var updatedViewCountDisposables = DisposableDict() + private var updatedSeenLiveLocationMessageIdsAndTimestamps: [MessageId: Int32] = [:] + private var nextSeenLiveLocationDisposableId: Int32 = 0 + private var seenLiveLocationDisposables = DisposableDict() + private var updatedUnsupportedMediaMessageIdsAndTimestamps: [MessageId: Int32] = [:] private var nextUpdatedUnsupportedMediaDisposableId: Int32 = 0 private var updatedUnsupportedMediaDisposables = DisposableDict() @@ -584,6 +588,61 @@ public final class AccountViewTracker { } } + public func updateSeenLiveLocationForMessageIds(messageIds: Set) { + self.queue.async { + var addedMessageIds: [MessageId] = [] + let timestamp = Int32(CFAbsoluteTimeGetCurrent()) + for messageId in messageIds { + let messageTimestamp = self.updatedSeenLiveLocationMessageIdsAndTimestamps[messageId] + if messageTimestamp == nil || messageTimestamp! < timestamp - 1 * 60 { + self.updatedSeenLiveLocationMessageIdsAndTimestamps[messageId] = timestamp + addedMessageIds.append(messageId) + } + } + if !addedMessageIds.isEmpty { + for (peerId, messageIds) in messagesIdsGroupedByPeerId(Set(addedMessageIds)) { + let disposableId = self.nextSeenLiveLocationDisposableId + self.nextSeenLiveLocationDisposableId += 1 + + if let account = self.account { + let signal = (account.postbox.transaction { transaction -> Signal in + if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) { + let request: Signal + switch inputPeer { + case .inputPeerChat, .inputPeerSelf, .inputPeerUser: + request = account.network.request(Api.functions.messages.readMessageContents(id: messageIds.map { $0.id })) + |> map { _ in true } + case let .inputPeerChannel(channelId, accessHash): + request = account.network.request(Api.functions.channels.readMessageContents(channel: .inputChannel(channelId: channelId, accessHash: accessHash), id: messageIds.map { $0.id })) + |> map { _ in true } + default: + return .complete() + } + + return request + |> `catch` { _ -> Signal in + return .single(false) + } + |> mapToSignal { _ -> Signal in + return .complete() + } + } else { + return .complete() + } + } + |> switchToLatest) + |> afterDisposed { [weak self] in + self?.queue.async { + self?.seenLiveLocationDisposables.set(nil, forKey: disposableId) + } + } + self.seenLiveLocationDisposables.set(signal.start(), forKey: disposableId) + } + } + } + } + } + public func updateUnsupportedMediaForMessageIds(messageIds: Set) { self.queue.async { var addedMessageIds: [MessageId] = [] diff --git a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift index 06be57e178..9a0ffb668d 100644 --- a/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatHistoryListNode.swift @@ -398,6 +398,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { private let galleryHiddenMesageAndMediaDisposable = MetaDisposable() private let messageProcessingManager = ChatMessageThrottledProcessingManager() + private let seenLiveLocationProcessingManager = ChatMessageThrottledProcessingManager() private let unsupportedMessageProcessingManager = ChatMessageThrottledProcessingManager() private let messageMentionProcessingManager = ChatMessageThrottledProcessingManager(delay: 0.2) let prefetchManager: InChatPrefetchManager @@ -471,6 +472,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { self.messageProcessingManager.process = { [weak context] messageIds in context?.account.viewTracker.updateViewCountForMessageIds(messageIds: messageIds) } + self.seenLiveLocationProcessingManager.process = { [weak context] messageIds in + context?.account.viewTracker.updateSeenLiveLocationForMessageIds(messageIds: messageIds) + } self.unsupportedMessageProcessingManager.process = { [weak context] messageIds in context?.account.viewTracker.updateUnsupportedMediaForMessageIds(messageIds: messageIds) } @@ -898,6 +902,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let toLaterRange = (historyView.filteredEntries.count - 1 - (visible.firstIndex - 1), historyView.filteredEntries.count - 1) var messageIdsWithViewCount: [MessageId] = [] + var messageIdsWithLiveLocation: [MessageId] = [] var messageIdsWithUnsupportedMedia: [MessageId] = [] var messageIdsWithUnseenPersonalMention: [MessageId] = [] var messagesWithPreloadableMediaToEarlier: [(Message, Media)] = [] @@ -931,6 +936,11 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { for media in message.media { if let _ = media as? TelegramMediaUnsupported { contentRequiredValidation = true + } else if message.flags.contains(.Incoming), let media = media as? TelegramMediaMap, let liveBroadcastingTimeout = media.liveBroadcastingTimeout { + let timestamp = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) + if message.timestamp + liveBroadcastingTimeout > timestamp { + messageIdsWithLiveLocation.append(message.id) + } } } if contentRequiredValidation { @@ -1035,6 +1045,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { if !messageIdsWithViewCount.isEmpty { self.messageProcessingManager.add(messageIdsWithViewCount) } + if !messageIdsWithLiveLocation.isEmpty { + self.seenLiveLocationProcessingManager.add(messageIdsWithLiveLocation) + } if !messageIdsWithUnsupportedMedia.isEmpty { self.unsupportedMessageProcessingManager.add(messageIdsWithUnsupportedMedia) }