Saved message tags improvements

This commit is contained in:
Isaac 2024-01-29 11:57:26 +01:00
parent d392e51aae
commit 4594df516e
8 changed files with 201 additions and 131 deletions

View File

@ -2673,9 +2673,22 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
previousTopItemVerticalOrigin = self.topItemVerticalOrigin()
}
var previousApparentFrames: [(ListViewItemNode, CGRect)] = []
struct PreviousApparentFrame {
var frame: CGRect
var insets: UIEdgeInsets
init(frame: CGRect, insets: UIEdgeInsets) {
self.frame = frame
self.insets = insets
}
}
var previousApparentFrames: [(ListViewItemNode, PreviousApparentFrame)] = []
for itemNode in self.itemNodes {
previousApparentFrames.append((itemNode, itemNode.apparentFrame))
previousApparentFrames.append((itemNode, PreviousApparentFrame(
frame: itemNode.apparentFrame,
insets: itemNode.insets
)))
}
var takenPreviousNodes = Set<ListViewItemNode>()
@ -2699,7 +2712,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
var previousFrame: CGRect?
for (previousNode, frame) in previousApparentFrames {
if previousNode === node {
previousFrame = frame
previousFrame = frame.frame
break
}
}
@ -2764,7 +2777,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
for (node, previousFrame) in previousApparentFrames {
if node === referenceNode {
height = previousFrame.size.height
height = previousFrame.frame.size.height
previousLayout = ListViewItemNodeLayout(contentSize: node.contentSize, insets: node.insets)
break
}
@ -2830,7 +2843,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
for (previousNode, previousFrame) in previousApparentFrames {
if previousNode === self.itemNodes[index] {
removedPreviousNodes.insert(previousNode)
self.itemNodes[index].frame = previousFrame
self.itemNodes[index].frame = previousFrame.frame
break
}
}
@ -3026,7 +3039,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
if let index = itemNode.index , index == stationaryItemIndex {
for (previousNode, previousFrame) in previousApparentFrames {
if previousNode === itemNode {
let offset = previousFrame.minY - itemNode.frame.minY
let offset = previousFrame.frame.minY - itemNode.frame.minY
if abs(offset) > CGFloat.ulpOfOne {
for itemNode in self.itemNodes {
@ -3294,7 +3307,18 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
if animateFullTransition {
for (previousNode, previousFrame) in previousApparentFrames {
if !takenPreviousNodes.contains(previousNode) && !removedPreviousNodes.contains(previousNode) {
previousNode.layer.animatePosition(from: CGPoint(x: 0.0, y: previousFrame.minY - previousNode.frame.minY), to: CGPoint(), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
if previousFrame.frame.maxY < self.insets.top || previousFrame.frame.minY > self.visibleSize.height - self.insets.bottom {
previousNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
previousNode.layer.animateScale(from: 0.7, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
} else {
let boundsOffset: CGFloat
if self.rotated {
boundsOffset = previousFrame.insets.bottom - previousNode.insets.bottom
} else {
boundsOffset = previousFrame.insets.top - previousNode.insets.top
}
previousNode.layer.animatePosition(from: CGPoint(x: 0.0, y: previousFrame.frame.minY - previousNode.frame.minY + boundsOffset), to: CGPoint(), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, additive: true)
}
}
}
}
@ -3310,16 +3334,16 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
for (previousNode, previousFrame) in previousApparentFrames {
if previousNode.supernode == nil {
temporaryPreviousNodes.append(previousNode)
previousNode.updateFrame(previousFrame, within: self.visibleSize)
if previousUpperBound == nil || previousUpperBound! > previousFrame.minY {
previousUpperBound = previousFrame.minY
previousNode.updateFrame(previousFrame.frame, within: self.visibleSize)
if previousUpperBound == nil || previousUpperBound! > previousFrame.frame.minY {
previousUpperBound = previousFrame.frame.minY
}
if previousLowerBound == nil || previousLowerBound! < previousFrame.maxY {
previousLowerBound = previousFrame.maxY
if previousLowerBound == nil || previousLowerBound! < previousFrame.frame.maxY {
previousLowerBound = previousFrame.frame.maxY
}
} else {
if previousNode.canBeUsedAsScrollToItemAnchor {
offset = previousNode.apparentFrame.minY - previousFrame.minY
offset = previousNode.apparentFrame.minY - previousFrame.frame.minY
break
}
}
@ -3328,16 +3352,16 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
for (previousNode, previousFrame) in previousApparentFrames {
if previousNode.supernode == nil {
temporaryPreviousNodes.append(previousNode)
previousNode.updateFrame(previousFrame, within: self.visibleSize)
if previousUpperBound == nil || previousUpperBound! > previousFrame.minY {
previousUpperBound = previousFrame.minY
previousNode.updateFrame(previousFrame.frame, within: self.visibleSize)
if previousUpperBound == nil || previousUpperBound! > previousFrame.frame.minY {
previousUpperBound = previousFrame.frame.minY
}
if previousLowerBound == nil || previousLowerBound! < previousFrame.maxY {
previousLowerBound = previousFrame.maxY
if previousLowerBound == nil || previousLowerBound! < previousFrame.frame.maxY {
previousLowerBound = previousFrame.frame.maxY
}
} else {
if previousNode.canBeUsedAsScrollToItemAnchor {
offset = previousNode.apparentFrame.minY - previousFrame.minY
offset = previousNode.apparentFrame.minY - previousFrame.frame.minY
}
}
}

View File

@ -1851,14 +1851,15 @@ public extension Api.functions.auth {
}
}
public extension Api.functions.auth {
static func signUp(phoneNumber: String, phoneCodeHash: String, firstName: String, lastName: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.auth.Authorization>) {
static func signUp(flags: Int32, phoneNumber: String, phoneCodeHash: String, firstName: String, lastName: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.auth.Authorization>) {
let buffer = Buffer()
buffer.appendInt32(-2131827673)
buffer.appendInt32(-1429752041)
serializeInt32(flags, buffer: buffer, boxed: false)
serializeString(phoneNumber, buffer: buffer, boxed: false)
serializeString(phoneCodeHash, buffer: buffer, boxed: false)
serializeString(firstName, buffer: buffer, boxed: false)
serializeString(lastName, buffer: buffer, boxed: false)
return (FunctionDescription(name: "auth.signUp", parameters: [("phoneNumber", String(describing: phoneNumber)), ("phoneCodeHash", String(describing: phoneCodeHash)), ("firstName", String(describing: firstName)), ("lastName", String(describing: lastName))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.auth.Authorization? in
return (FunctionDescription(name: "auth.signUp", parameters: [("flags", String(describing: flags)), ("phoneNumber", String(describing: phoneNumber)), ("phoneCodeHash", String(describing: phoneCodeHash)), ("firstName", String(describing: firstName)), ("lastName", String(describing: lastName))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.auth.Authorization? in
let reader = BufferReader(buffer)
var result: Api.auth.Authorization?
if let signature = reader.readInt32() {
@ -5901,11 +5902,13 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func getSavedReactionTags(hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.SavedReactionTags>) {
static func getSavedReactionTags(flags: Int32, peer: Api.InputPeer?, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.SavedReactionTags>) {
let buffer = Buffer()
buffer.appendInt32(1981668047)
buffer.appendInt32(909631579)
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {peer!.serialize(buffer, true)}
serializeInt64(hash, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.getSavedReactionTags", parameters: [("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.SavedReactionTags? in
return (FunctionDescription(name: "messages.getSavedReactionTags", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.SavedReactionTags? in
let reader = BufferReader(buffer)
var result: Api.messages.SavedReactionTags?
if let signature = reader.readInt32() {

View File

@ -1211,7 +1211,7 @@ public enum SignUpError {
public func signUpWithName(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, firstName: String, lastName: String, avatarData: Data?, avatarVideo: Signal<UploadedPeerPhotoData?, NoError>?, videoStartTimestamp: Double?, forcedPasswordSetupNotice: @escaping (Int32) -> (NoticeEntryKey, CodableEntry)?) -> Signal<Void, SignUpError> {
return account.postbox.transaction { transaction -> Signal<Void, SignUpError> in
if let state = transaction.getState() as? UnauthorizedAccountState, case let .signUp(number, codeHash, _, _, _, syncContacts) = state.contents {
return account.network.request(Api.functions.auth.signUp(phoneNumber: number, phoneCodeHash: codeHash, firstName: firstName, lastName: lastName))
return account.network.request(Api.functions.auth.signUp(flags: 0, phoneNumber: number, phoneCodeHash: codeHash, firstName: firstName, lastName: lastName))
|> mapError { error -> SignUpError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .limitExceeded

View File

@ -89,7 +89,6 @@ final class AccountTaskManager {
tasks.add(managedSynchronizeEmojiKeywordsOperations(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedApplyPendingScheduledMessagesActions(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
tasks.add(managedSynchronizeAvailableReactions(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedSynchronizeSavedMessageTags(postbox: self.stateManager.postbox, network: self.stateManager.network, accountPeerId: self.stateManager.accountPeerId).start())
tasks.add(managedSynchronizeEmojiSearchCategories(postbox: self.stateManager.postbox, network: self.stateManager.network, kind: .emoji).start())
tasks.add(managedSynchronizeEmojiSearchCategories(postbox: self.stateManager.postbox, network: self.stateManager.network, kind: .status).start())
tasks.add(managedSynchronizeEmojiSearchCategories(postbox: self.stateManager.postbox, network: self.stateManager.network, kind: .avatar).start())

View File

@ -3,7 +3,39 @@ import Postbox
import SwiftSignalKit
import TelegramApi
import MtProtoKit
import CryptoUtils
private struct Md5Hash: Hashable {
public let data: Data
public init(data: Data) {
precondition(data.count == 16)
self.data = data
}
}
private func md5Hash(_ data: Data) -> Md5Hash {
let hashData = data.withUnsafeBytes { bytes -> Data in
return CryptoMD5(bytes.baseAddress!, Int32(bytes.count))
}
return Md5Hash(data: hashData)
}
private func md5StringHash(_ string: String) -> UInt64 {
guard let data = string.data(using: .utf8) else {
return 0
}
let hash = md5Hash(data).data
return hash.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) -> UInt64 in
let bytes = buffer.baseAddress!.assumingMemoryBound(to: UInt8.self)
var result: UInt64 = 0
for i in 0 ... 7 {
result += UInt64(bitPattern: Int64(bytes[i])) << (56 - 8 * i)
}
return result
}
}
private final class ManagedConsumePersonalMessagesActionsHelper {
var operationDisposables: [MessageId: Disposable] = [:]
@ -529,7 +561,7 @@ private func synchronizeMessageHistoryTagSummary(postbox: Postbox, network: Netw
|> switchToLatest
}
private func synchronizeSavedMessageTags(postbox: Postbox, network: Network, peerId: PeerId, threadId: Int64?) -> Signal<Never, NoError> {
func synchronizeSavedMessageTags(postbox: Postbox, network: Network, peerId: PeerId, threadId: Int64?) -> Signal<Never, NoError> {
let key: PostboxViewKey = .pendingMessageActions(type: .updateReaction)
let waitForApplySignal: Signal<Never, NoError> = postbox.combinedView(keys: [key])
|> map { views -> Bool in
@ -549,15 +581,99 @@ private func synchronizeSavedMessageTags(postbox: Postbox, network: Network, pee
|> take(1)
|> ignoreValues
let updateSignal: Signal<Never, NoError> = (postbox.transaction { transaction -> Bool in
return transaction.getPreferencesEntry(key: PreferencesKeys.didCacheSavedMessageTags(threadId: threadId)) != nil
let updateSignal: Signal<Never, NoError> = (postbox.transaction { transaction -> (Bool, Peer?, Int64) in
struct HashableTag {
var titleId: UInt64?
var count: Int
var id: UInt64
init(titleId: UInt64?, count: Int, id: UInt64) {
self.titleId = titleId
self.count = count
self.id = id
}
|> mapToSignal { alreadyCached -> Signal<Never, NoError> in
}
let savedTags = _internal_savedMessageTags(transaction: transaction)
var hashableTags: [HashableTag] = []
for tag in transaction.getMessageTagSummaryCustomTags(peerId: peerId, threadId: threadId, tagMask: [], namespace: Namespaces.Message.Cloud) {
if let summary = transaction.getMessageTagSummary(peerId: peerId, threadId: threadId, tagMask: [], namespace: Namespaces.Message.Cloud, customTag: tag), summary.count > 0 {
guard let reaction = ReactionsMessageAttribute.reactionFromMessageTag(tag: tag) else {
continue
}
var tagTitle: String?
if threadId == nil, let savedTags {
if let value = savedTags.tags.first(where: { $0.reaction == reaction }) {
tagTitle = value.title
}
}
let reactionId: UInt64
switch reaction {
case let .custom(id):
reactionId = UInt64(bitPattern: id)
case let .builtin(string):
reactionId = md5StringHash(string)
}
var titleId: UInt64?
if let tagTitle {
titleId = md5StringHash(tagTitle)
}
hashableTags.append(HashableTag(
titleId: titleId,
count: Int(summary.count),
id: reactionId
))
}
}
hashableTags.sort(by: { lhs, rhs in
if lhs.count != rhs.count {
return lhs.count > rhs.count
}
return lhs.id < rhs.id
})
var hashIds: [UInt64] = []
for tag in hashableTags {
hashIds.append(tag.id)
if let titleId = tag.titleId {
hashIds.append(titleId)
}
hashIds.append(UInt64(tag.count))
}
var hashAcc: UInt64 = 0
for id in hashIds {
combineInt64Hash(&hashAcc, with: id)
}
return (
transaction.getPreferencesEntry(key: PreferencesKeys.didCacheSavedMessageTags(threadId: threadId)) != nil,
threadId.flatMap { transaction.getPeer(PeerId($0)) },
Int64(bitPattern: hashAcc)
)
}
|> mapToSignal { alreadyCached, subPeer, currentHash -> Signal<Never, NoError> in
if alreadyCached {
return .complete()
}
return network.request(Api.functions.messages.getSavedReactionTags(hash: 0))
let inputSubPeer = subPeer.flatMap(apiInputPeer)
if threadId != nil && inputSubPeer == nil {
return .complete()
}
var flags: Int32 = 0
if inputSubPeer != nil {
flags |= 1 << 0
}
return network.request(Api.functions.messages.getSavedReactionTags(flags: flags, peer: inputSubPeer, hash: currentHash))
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.messages.SavedReactionTags?, NoError> in
return .single(nil)
@ -569,7 +685,10 @@ private func synchronizeSavedMessageTags(postbox: Postbox, network: Network, pee
switch result {
case .savedReactionTagsNotModified:
return .complete()
return postbox.transaction { transaction -> Void in
transaction.setPreferencesEntry(key: PreferencesKeys.didCacheSavedMessageTags(threadId: threadId), value: PreferencesEntry(data: Data()))
}
|> ignoreValues
case let .savedReactionTags(tags, _):
var customFileIds: [Int64] = []
var parsedTags: [SavedMessageTags.Tag] = []
@ -591,10 +710,15 @@ private func synchronizeSavedMessageTags(postbox: Postbox, network: Network, pee
}
}
let _ = customFileIds
return postbox.transaction { transaction -> Void in
let previousTags = transaction.getMessageTagSummaryCustomTags(peerId: peerId, threadId: nil, tagMask: [], namespace: Namespaces.Message.Cloud)
if threadId == nil {
_internal_setSavedMessageTags(transaction: transaction, savedMessageTags: SavedMessageTags(
hash: 0,
tags: parsedTags
))
}
let previousTags = transaction.getMessageTagSummaryCustomTags(peerId: peerId, threadId: threadId, tagMask: [], namespace: Namespaces.Message.Cloud)
let topMessageId = transaction.getTopPeerMessageId(peerId: peerId, namespace: Namespaces.Message.Cloud)?.id ?? 1
@ -602,11 +726,11 @@ private func synchronizeSavedMessageTags(postbox: Postbox, network: Network, pee
for tag in parsedTags {
let customTag = ReactionsMessageAttribute.messageTag(reaction: tag.reaction)
validTags.append(customTag)
transaction.replaceMessageTagSummary(peerId: peerId, threadId: nil, tagMask: [], namespace: Namespaces.Message.Cloud, customTag: customTag, count: Int32(tag.count), maxId: topMessageId)
transaction.replaceMessageTagSummary(peerId: peerId, threadId: threadId, tagMask: [], namespace: Namespaces.Message.Cloud, customTag: customTag, count: Int32(tag.count), maxId: topMessageId)
}
for tag in previousTags {
if !validTags.contains(tag) {
transaction.replaceMessageTagSummary(peerId: peerId, threadId: nil, tagMask: [], namespace: Namespaces.Message.Cloud, customTag: tag, count: 0, maxId: topMessageId)
transaction.replaceMessageTagSummary(peerId: peerId, threadId: threadId, tagMask: [], namespace: Namespaces.Message.Cloud, customTag: tag, count: 0, maxId: topMessageId)
}
}

View File

@ -132,95 +132,6 @@ func _internal_setSavedMessageTags(transaction: Transaction, savedMessageTags: S
}
}
func managedSynchronizeSavedMessageTags(postbox: Postbox, network: Network, accountPeerId: PeerId) -> Signal<Never, NoError> {
let poll = Signal<Never, NoError> { subscriber in
let key: PostboxViewKey = .pendingMessageActions(type: .updateReaction)
let waitForApplySignal: Signal<Never, NoError> = postbox.combinedView(keys: [key])
|> map { views -> Bool in
guard let view = views.views[key] as? PendingMessageActionsView else {
return false
}
for entry in view.entries {
if entry.id.peerId == accountPeerId {
return false
}
}
return true
}
|> filter { $0 }
|> take(1)
|> ignoreValues
let signal: Signal<Never, NoError> = _internal_savedMessageTags(postbox: postbox)
|> mapToSignal { current in
return (network.request(Api.functions.messages.getSavedReactionTags(hash: current?.hash ?? 0))
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.messages.SavedReactionTags?, NoError> in
return .single(nil)
}
|> mapToSignal { result -> Signal<Never, NoError> in
guard let result = result else {
return .complete()
}
switch result {
case .savedReactionTagsNotModified:
return .complete()
case let .savedReactionTags(tags, hash):
var customFileIds: [Int64] = []
var parsedTags: [SavedMessageTags.Tag] = []
for tag in tags {
switch tag {
case let .savedReactionTag(_, reaction, title, count):
guard let reaction = MessageReaction.Reaction(apiReaction: reaction) else {
continue
}
parsedTags.append(SavedMessageTags.Tag(
reaction: reaction,
title: title,
count: Int(count)
))
if case let .custom(fileId) = reaction {
customFileIds.append(fileId)
}
}
}
let savedMessageTags = SavedMessageTags(
hash: hash,
tags: parsedTags
)
return _internal_resolveInlineStickers(postbox: postbox, network: network, fileIds: customFileIds)
|> mapToSignal { _ -> Signal<Never, NoError> in
return postbox.transaction { transaction in
_internal_setSavedMessageTags(transaction: transaction, savedMessageTags: savedMessageTags)
}
|> ignoreValues
}
}
})
}
return (waitForApplySignal |> then(signal)).start(completed: {
subscriber.putCompletion()
})
}
return (
poll
|> then(
.complete()
|> suspendAwareDelay(1.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue())
)
)
|> restart
}
func _internal_setSavedMessageTagTitle(account: Account, reaction: MessageReaction.Reaction, title: String?) -> Signal<Never, NoError> {
return account.postbox.transaction { transaction -> Void in
let value = _internal_savedMessageTags(transaction: transaction) ?? SavedMessageTags(hash: 0, tags: [])

View File

@ -146,8 +146,8 @@ public extension TelegramEngine {
}
}
public func refreshSavedMessageTags() -> Signal<Never, NoError> {
return managedSynchronizeSavedMessageTags(postbox: self.account.postbox, network: self.account.network, accountPeerId: self.account.peerId)
public func refreshSavedMessageTags(subPeerId: EnginePeer.Id?) -> Signal<Never, NoError> {
return synchronizeSavedMessageTags(postbox: self.account.postbox, network: self.account.network, peerId: self.account.peerId, threadId: subPeerId?.toInt64())
}
public func setSavedMessageTagTitle(reaction: MessageReaction.Reaction, title: String?) -> Signal<Never, NoError> {

View File

@ -305,6 +305,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var sendAsPeersDisposable: Disposable?
var preloadAttachBotIconsDisposables: DisposableSet?
var keepMessageCountersSyncrhonizedDisposable: Disposable?
var keepSavedMessagesSyncrhonizedDisposable: Disposable?
var saveMediaDisposable: MetaDisposable?
var giveawayStatusDisposable: MetaDisposable?
var nameColorDisposable: Disposable?
@ -6617,6 +6618,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.sendAsPeersDisposable?.dispose()
self.preloadAttachBotIconsDisposables?.dispose()
self.keepMessageCountersSyncrhonizedDisposable?.dispose()
self.keepSavedMessagesSyncrhonizedDisposable?.dispose()
self.translationStateDisposable?.dispose()
self.premiumGiftSuggestionDisposable?.dispose()
self.powerSavingMonitoringDisposable?.dispose()
@ -11322,11 +11324,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if self.keepMessageCountersSyncrhonizedDisposable == nil {
self.keepMessageCountersSyncrhonizedDisposable = self.context.engine.messages.keepMessageCountersSyncrhonized(peerId: message.peerId, threadId: message.threadId).startStrict()
}
} else if case .peer(self.context.account.peerId) = self.chatLocation {
} else if self.chatLocation.peerId == self.context.account.peerId {
if self.keepMessageCountersSyncrhonizedDisposable == nil {
if let threadId = self.chatLocation.threadId {
self.keepMessageCountersSyncrhonizedDisposable = self.context.engine.messages.keepMessageCountersSyncrhonized(peerId: self.context.account.peerId, threadId: threadId).startStrict()
} else {
self.keepMessageCountersSyncrhonizedDisposable = self.context.engine.messages.keepMessageCountersSyncrhonized(peerId: self.context.account.peerId).startStrict()
}
}
if self.keepSavedMessagesSyncrhonizedDisposable == nil {
self.keepSavedMessagesSyncrhonizedDisposable = self.context.engine.stickers.refreshSavedMessageTags(subPeerId: self.chatLocation.threadId.flatMap(PeerId.init)).startStrict()
}
}
if let scheduledActivateInput = scheduledActivateInput, case .text = scheduledActivateInput {
self.scheduledActivateInput = nil