Various improvements

This commit is contained in:
Isaac 2023-12-28 19:55:39 +04:00
parent 1d7bf5aa12
commit d8e5ff4f58
13 changed files with 212 additions and 25 deletions

View File

@ -474,9 +474,10 @@ public final class NavigateToChatControllerParams {
public let changeColors: Bool public let changeColors: Bool
public let setupController: (ChatController) -> Void public let setupController: (ChatController) -> Void
public let completion: (ChatController) -> Void public let completion: (ChatController) -> Void
public let chatListCompletion: ((ChatListController) -> Void)?
public let pushController: ((ChatController, Bool, @escaping () -> Void) -> Void)? public let pushController: ((ChatController, Bool, @escaping () -> Void) -> Void)?
public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: Location, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, attachBotStart: ChatControllerInitialAttachBotStart? = nil, botAppStart: ChatControllerInitialBotAppStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: ChatControllerActivateInput? = nil, keepStack: NavigateToChatKeepStack = .default, useExisting: Bool = true, useBackAnimation: Bool = false, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, activateMessageSearch: (ChatSearchDomain, String)? = nil, peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, reportReason: ReportReason? = nil, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, chatListFilter: Int32? = nil, chatNavigationStack: [ChatNavigationStackItem] = [], changeColors: Bool = false, setupController: @escaping (ChatController) -> Void = { _ in }, pushController: ((ChatController, Bool, @escaping () -> Void) -> Void)? = nil, completion: @escaping (ChatController) -> Void = { _ in }) { public init(navigationController: NavigationController, chatController: ChatController? = nil, context: AccountContext, chatLocation: Location, chatLocationContextHolder: Atomic<ChatLocationContextHolder?> = Atomic<ChatLocationContextHolder?>(value: nil), subject: ChatControllerSubject? = nil, botStart: ChatControllerInitialBotStart? = nil, attachBotStart: ChatControllerInitialAttachBotStart? = nil, botAppStart: ChatControllerInitialBotAppStart? = nil, updateTextInputState: ChatTextInputState? = nil, activateInput: ChatControllerActivateInput? = nil, keepStack: NavigateToChatKeepStack = .default, useExisting: Bool = true, useBackAnimation: Bool = false, purposefulAction: (() -> Void)? = nil, scrollToEndIfExists: Bool = false, activateMessageSearch: (ChatSearchDomain, String)? = nil, peekData: ChatPeekTimeout? = nil, peerNearbyData: ChatPeerNearbyData? = nil, reportReason: ReportReason? = nil, animated: Bool = true, options: NavigationAnimationOptions = [], parentGroupId: PeerGroupId? = nil, chatListFilter: Int32? = nil, chatNavigationStack: [ChatNavigationStackItem] = [], changeColors: Bool = false, setupController: @escaping (ChatController) -> Void = { _ in }, pushController: ((ChatController, Bool, @escaping () -> Void) -> Void)? = nil, completion: @escaping (ChatController) -> Void = { _ in }, chatListCompletion: @escaping (ChatListController) -> Void = { _ in }) {
self.navigationController = navigationController self.navigationController = navigationController
self.chatController = chatController self.chatController = chatController
self.chatLocationContextHolder = chatLocationContextHolder self.chatLocationContextHolder = chatLocationContextHolder
@ -506,6 +507,7 @@ public final class NavigateToChatControllerParams {
self.setupController = setupController self.setupController = setupController
self.pushController = pushController self.pushController = pushController
self.completion = completion self.completion = completion
self.chatListCompletion = chatListCompletion
} }
} }

View File

@ -93,6 +93,7 @@ enum AccountStateMutationOperation {
case ReadSecretOutbox(peerId: PeerId, maxTimestamp: Int32, actionTimestamp: Int32) case ReadSecretOutbox(peerId: PeerId, maxTimestamp: Int32, actionTimestamp: Int32)
case AddPeerInputActivity(chatPeerId: PeerActivitySpace, peerId: PeerId?, activity: PeerInputActivity?) case AddPeerInputActivity(chatPeerId: PeerActivitySpace, peerId: PeerId?, activity: PeerInputActivity?)
case UpdatePinnedItemIds(PeerGroupId, AccountStateUpdatePinnedItemIdsOperation) case UpdatePinnedItemIds(PeerGroupId, AccountStateUpdatePinnedItemIdsOperation)
case UpdatePinnedSavedItemIds(AccountStateUpdatePinnedItemIdsOperation)
case UpdatePinnedTopic(peerId: PeerId, threadId: Int64, isPinned: Bool) case UpdatePinnedTopic(peerId: PeerId, threadId: Int64, isPinned: Bool)
case UpdatePinnedTopicOrder(peerId: PeerId, threadIds: [Int64]) case UpdatePinnedTopicOrder(peerId: PeerId, threadIds: [Int64])
case ReadMessageContents(peerIdsAndMessageIds: (PeerId?, [Int32]), date: Int32?) case ReadMessageContents(peerIdsAndMessageIds: (PeerId?, [Int32]), date: Int32?)
@ -571,6 +572,10 @@ struct AccountMutableState {
self.addOperation(.UpdatePinnedItemIds(groupId, operation)) self.addOperation(.UpdatePinnedItemIds(groupId, operation))
} }
mutating func addUpdatePinnedSavedItemIds(operation: AccountStateUpdatePinnedItemIdsOperation) {
self.addOperation(.UpdatePinnedSavedItemIds(operation))
}
mutating func addUpdatePinnedTopic(peerId: PeerId, threadId: Int64, isPinned: Bool) { mutating func addUpdatePinnedTopic(peerId: PeerId, threadId: Int64, isPinned: Bool) {
self.addOperation(.UpdatePinnedTopic(peerId: peerId, threadId: threadId, isPinned: isPinned)) self.addOperation(.UpdatePinnedTopic(peerId: peerId, threadId: threadId, isPinned: isPinned))
} }
@ -665,7 +670,7 @@ struct AccountMutableState {
mutating func addOperation(_ operation: AccountStateMutationOperation) { mutating func addOperation(_ operation: AccountStateMutationOperation) {
switch operation { switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .UpdateWallpaper, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .UpdateWallpaper, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization:
break break
case let .AddMessages(messages, location): case let .AddMessages(messages, location):
for message in messages { for message in messages {

View File

@ -839,6 +839,8 @@ func revalidateMediaResourceReference(accountPeerId: PeerId, postbox: Postbox, n
} }
if let updatedResource = findUpdatedMediaResource(media: media, previousMedia: nil, resource: resource) { if let updatedResource = findUpdatedMediaResource(media: media, previousMedia: nil, resource: resource) {
return .single(RevalidatedMediaResource(updatedResource: updatedResource, updatedReference: nil)) return .single(RevalidatedMediaResource(updatedResource: updatedResource, updatedReference: nil))
} else if let alternativeMedia = item.alternativeMedia, let updatedResource = findUpdatedMediaResource(media: alternativeMedia, previousMedia: nil, resource: resource) {
return .single(RevalidatedMediaResource(updatedResource: updatedResource, updatedReference: nil))
} else { } else {
return .fail(.generic) return .fail(.generic)
} }

View File

@ -1490,6 +1490,27 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
} else { } else {
updatedState.addUpdatePinnedItemIds(groupId: groupId, operation: .sync) updatedState.addUpdatePinnedItemIds(groupId: groupId, operation: .sync)
} }
case let .updateSavedDialogPinned(flags, peer):
if case let .dialogPeer(peer) = peer {
if (flags & (1 << 0)) != 0 {
updatedState.addUpdatePinnedSavedItemIds(operation: .pin(.peer(peer.peerId)))
} else {
updatedState.addUpdatePinnedSavedItemIds(operation: .unpin(.peer(peer.peerId)))
}
}
case let .updatePinnedSavedDialogs(_, order):
if let order = order {
updatedState.addUpdatePinnedSavedItemIds(operation: .reorder(order.compactMap {
switch $0 {
case let .dialogPeer(peer):
return .peer(peer.peerId)
case .dialogPeerFolder:
return nil
}
}))
} else {
updatedState.addUpdatePinnedSavedItemIds(operation: .sync)
}
case let .updateChannelPinnedTopic(flags, channelId, topicId): case let .updateChannelPinnedTopic(flags, channelId, topicId):
let isPinned = (flags & (1 << 0)) != 0 let isPinned = (flags & (1 << 0)) != 0
updatedState.addUpdatePinnedTopic(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)), threadId: Int64(topicId), isPinned: isPinned) updatedState.addUpdatePinnedTopic(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)), threadId: Int64(topicId), isPinned: isPinned)
@ -3231,7 +3252,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
var currentAddScheduledMessages: OptimizeAddMessagesState? var currentAddScheduledMessages: OptimizeAddMessagesState?
for operation in operations { for operation in operations {
switch operation { switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateWallpaper: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedSavedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories, .UpdateStoryStealthMode, .UpdateStorySentReaction, .UpdateNewAuthorization, .UpdateWallpaper:
if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty { if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty {
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location)) result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
} }
@ -4228,6 +4249,44 @@ func replayFinalState(
case .sync: case .sync:
addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId) addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId)
} }
case let .UpdatePinnedSavedItemIds(pinnedOperation):
switch pinnedOperation {
case let .pin(itemId):
switch itemId {
case let .peer(peerId):
var currentItemIds = transaction.getPeerPinnedThreads(peerId: accountPeerId)
if !currentItemIds.contains(peerId.toInt64()) {
currentItemIds.insert(peerId.toInt64(), at: 0)
transaction.setPeerPinnedThreads(peerId: accountPeerId, threadIds: currentItemIds)
}
}
case let .unpin(itemId):
switch itemId {
case let .peer(peerId):
var currentItemIds = transaction.getPeerPinnedThreads(peerId: accountPeerId)
if let index = currentItemIds.firstIndex(of: peerId.toInt64()) {
currentItemIds.remove(at: index)
transaction.setPeerPinnedThreads(peerId: accountPeerId, threadIds: currentItemIds)
} else {
addSynchronizePinnedSavedChatsOperation(transaction: transaction, accountPeerId: accountPeerId)
}
}
case let .reorder(itemIds):
let itemIds = itemIds.compactMap({
switch $0 {
case let .peer(peerId):
return peerId
}
})
let currentItemIds = transaction.getPeerPinnedThreads(peerId: accountPeerId)
if Set(itemIds) == Set(currentItemIds.map(PeerId.init)) {
transaction.setPeerPinnedThreads(peerId: accountPeerId, threadIds: itemIds.map { $0.toInt64() })
} else {
addSynchronizePinnedSavedChatsOperation(transaction: transaction, accountPeerId: accountPeerId)
}
case .sync:
addSynchronizePinnedSavedChatsOperation(transaction: transaction, accountPeerId: accountPeerId)
}
case let .UpdatePinnedTopic(peerId, threadId, isPinned): case let .UpdatePinnedTopic(peerId, threadId, isPinned):
var currentThreadIds = transaction.getPeerPinnedThreads(peerId: peerId) var currentThreadIds = transaction.getPeerPinnedThreads(peerId: peerId)
if isPinned { if isPinned {

View File

@ -69,7 +69,8 @@ final class AccountTaskManager {
tasks.add(managedSynchronizeGroupMessageStats(network: self.stateManager.network, postbox: self.stateManager.postbox, stateManager: self.stateManager).start()) tasks.add(managedSynchronizeGroupMessageStats(network: self.stateManager.network, postbox: self.stateManager.postbox, stateManager: self.stateManager).start())
tasks.add(managedGlobalNotificationSettings(postbox: self.stateManager.postbox, network: self.stateManager.network).start()) tasks.add(managedGlobalNotificationSettings(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedSynchronizePinnedChatsOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, accountPeerId: self.stateManager.accountPeerId, stateManager: self.stateManager).start()) tasks.add(managedSynchronizePinnedChatsOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, accountPeerId: self.stateManager.accountPeerId, stateManager: self.stateManager, tag: OperationLogTags.SynchronizePinnedChats).start())
tasks.add(managedSynchronizePinnedChatsOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, accountPeerId: self.stateManager.accountPeerId, stateManager: self.stateManager, tag: OperationLogTags.SynchronizePinnedSavedChats).start())
tasks.add(managedSynchronizeGroupedPeersOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start()) tasks.add(managedSynchronizeGroupedPeersOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager).start())
tasks.add(managedSynchronizeInstalledStickerPacksOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager, namespace: .stickers).start()) tasks.add(managedSynchronizeInstalledStickerPacksOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager, namespace: .stickers).start())
tasks.add(managedSynchronizeInstalledStickerPacksOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager, namespace: .masks).start()) tasks.add(managedSynchronizeInstalledStickerPacksOperations(postbox: self.stateManager.postbox, network: self.stateManager.network, stateManager: self.stateManager, namespace: .masks).start())

View File

@ -4,7 +4,6 @@ import SwiftSignalKit
import TelegramApi import TelegramApi
import MtProtoKit import MtProtoKit
private final class ManagedSynchronizePinnedChatsOperationsHelper { private final class ManagedSynchronizePinnedChatsOperationsHelper {
var operationDisposables: [Int32: Disposable] = [:] var operationDisposables: [Int32: Disposable] = [:]
@ -49,10 +48,10 @@ private final class ManagedSynchronizePinnedChatsOperationsHelper {
} }
} }
private func withTakenOperation(postbox: Postbox, peerId: PeerId, tagLocalIndex: Int32, _ f: @escaping (Transaction, PeerMergedOperationLogEntry?) -> Signal<Void, NoError>) -> Signal<Void, NoError> { private func withTakenOperation(postbox: Postbox, tag: PeerOperationLogTag, peerId: PeerId, tagLocalIndex: Int32, _ f: @escaping (Transaction, PeerMergedOperationLogEntry?) -> Signal<Void, NoError>) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Signal<Void, NoError> in return postbox.transaction { transaction -> Signal<Void, NoError> in
var result: PeerMergedOperationLogEntry? var result: PeerMergedOperationLogEntry?
transaction.operationLogUpdateEntry(peerId: peerId, tag: OperationLogTags.SynchronizePinnedChats, tagLocalIndex: tagLocalIndex, { entry in transaction.operationLogUpdateEntry(peerId: peerId, tag: tag, tagLocalIndex: tagLocalIndex, { entry in
if let entry = entry, let _ = entry.mergedIndex, entry.contents is SynchronizePinnedChatsOperation { if let entry = entry, let _ = entry.mergedIndex, entry.contents is SynchronizePinnedChatsOperation {
result = entry.mergedEntry! result = entry.mergedEntry!
return PeerOperationLogEntryUpdate(mergedIndex: .none, contents: .none) return PeerOperationLogEntryUpdate(mergedIndex: .none, contents: .none)
@ -65,11 +64,11 @@ private func withTakenOperation(postbox: Postbox, peerId: PeerId, tagLocalIndex:
} |> switchToLatest } |> switchToLatest
} }
func managedSynchronizePinnedChatsOperations(postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager) -> Signal<Void, NoError> { func managedSynchronizePinnedChatsOperations(postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager, tag: PeerOperationLogTag) -> Signal<Void, NoError> {
return Signal { _ in return Signal { _ in
let helper = Atomic<ManagedSynchronizePinnedChatsOperationsHelper>(value: ManagedSynchronizePinnedChatsOperationsHelper()) let helper = Atomic<ManagedSynchronizePinnedChatsOperationsHelper>(value: ManagedSynchronizePinnedChatsOperationsHelper())
let disposable = postbox.mergedOperationLogView(tag: OperationLogTags.SynchronizePinnedChats, limit: 10).start(next: { view in let disposable = postbox.mergedOperationLogView(tag: tag, limit: 10).start(next: { view in
let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(PeerMergedOperationLogEntry, MetaDisposable)]) in let (disposeOperations, beginOperations) = helper.with { helper -> (disposeOperations: [Disposable], beginOperations: [(PeerMergedOperationLogEntry, MetaDisposable)]) in
return helper.update(view.entries) return helper.update(view.entries)
} }
@ -79,10 +78,14 @@ func managedSynchronizePinnedChatsOperations(postbox: Postbox, network: Network,
} }
for (entry, disposable) in beginOperations { for (entry, disposable) in beginOperations {
let signal = withTakenOperation(postbox: postbox, peerId: entry.peerId, tagLocalIndex: entry.tagLocalIndex, { transaction, entry -> Signal<Void, NoError> in let signal = withTakenOperation(postbox: postbox, tag: tag, peerId: entry.peerId, tagLocalIndex: entry.tagLocalIndex, { transaction, entry -> Signal<Void, NoError> in
if let entry = entry { if let entry = entry {
if let operation = entry.contents as? SynchronizePinnedChatsOperation { if let operation = entry.contents as? SynchronizePinnedChatsOperation {
if tag == OperationLogTags.SynchronizePinnedChats {
return synchronizePinnedChats(transaction: transaction, postbox: postbox, network: network, accountPeerId: accountPeerId, stateManager: stateManager, groupId: PeerGroupId(rawValue: Int32(entry.peerId.id._internalGetInt64Value())), operation: operation) return synchronizePinnedChats(transaction: transaction, postbox: postbox, network: network, accountPeerId: accountPeerId, stateManager: stateManager, groupId: PeerGroupId(rawValue: Int32(entry.peerId.id._internalGetInt64Value())), operation: operation)
} else if tag == OperationLogTags.SynchronizePinnedSavedChats {
return synchronizePinnedSavedChats(transaction: transaction, postbox: postbox, network: network, accountPeerId: accountPeerId, stateManager: stateManager, operation: operation)
}
} else { } else {
assertionFailure() assertionFailure()
} }
@ -90,7 +93,7 @@ func managedSynchronizePinnedChatsOperations(postbox: Postbox, network: Network,
return .complete() return .complete()
}) })
|> then(postbox.transaction { transaction -> Void in |> then(postbox.transaction { transaction -> Void in
let _ = transaction.operationLogRemoveEntry(peerId: entry.peerId, tag: OperationLogTags.SynchronizePinnedChats, tagLocalIndex: entry.tagLocalIndex) let _ = transaction.operationLogRemoveEntry(peerId: entry.peerId, tag: tag, tagLocalIndex: entry.tagLocalIndex)
}) })
disposable.set((signal |> delay(2.0, queue: Queue.concurrentDefaultQueue())).start()) disposable.set((signal |> delay(2.0, queue: Queue.concurrentDefaultQueue())).start())
@ -279,3 +282,65 @@ private func synchronizePinnedChats(transaction: Transaction, postbox: Postbox,
|> switchToLatest |> switchToLatest
} }
} }
private func synchronizePinnedSavedChats(transaction: Transaction, postbox: Postbox, network: Network, accountPeerId: PeerId, stateManager: AccountStateManager, operation: SynchronizePinnedChatsOperation) -> Signal<Void, NoError> {
return network.request(Api.functions.messages.getPinnedSavedDialogs())
|> map(Optional.init)
|> `catch` { _ -> Signal<Api.messages.SavedDialogs?, NoError> in
return .single(nil)
}
|> mapToSignal { dialogs -> Signal<Void, NoError> in
guard let dialogs = dialogs else {
return .never()
}
let _ = dialogs
/*return postbox.transaction { transaction -> Signal<Void, NoError> in
var storeMessages: [StoreMessage] = []
var remoteItemIds: [PeerId] = []
let parsedPeers: AccumulatedPeers
switch dialogs {
case .savedDialogs(let dialogs, let messages, let chats, let users), .savedDialogs(_, let dialogs, let messages, let chats, let users):
parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
loop: for dialog in dialogs {
switch dialog {
case let .savedDialog(_, peer, _):
remoteItemIds.append(peer.peerId)
}
}
for message in messages {
var peerIsForum = false
if let peerId = message.peerId, let peer = parsedPeers.get(peerId), peer.isForum {
peerIsForum = true
}
if let storeMessage = StoreMessage(apiMessage: message, accountPeerId: accountPeerId, peerIsForum: peerIsForum) {
storeMessages.append(storeMessage)
}
}
case .savedDialogsNotModified:
parsedPeers = AccumulatedPeers(transaction: transaction, chats: [], users: [])
}
let resultingItemIds: [PeerId] = remoteItemIds
return postbox.transaction { transaction -> Signal<Void, NoError> in
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
transaction.setPeerPinnedThreads(peerId: accountPeerId, threadIds: resultingItemIds.map { $0.toInt64() })
let _ = transaction.addMessages(storeMessages, location: .UpperHistoryBlock)
return .complete()
}
|> switchToLatest
}
|> switchToLatest*/
return .complete()
}
}

View File

@ -198,6 +198,7 @@ public struct OperationLogTags {
public static let SynchronizeAutosaveItems = PeerOperationLogTag(value: 23) public static let SynchronizeAutosaveItems = PeerOperationLogTag(value: 23)
public static let SynchronizeViewStories = PeerOperationLogTag(value: 24) public static let SynchronizeViewStories = PeerOperationLogTag(value: 24)
public static let SynchronizePeerStories = PeerOperationLogTag(value: 25) public static let SynchronizePeerStories = PeerOperationLogTag(value: 25)
public static let SynchronizePinnedSavedChats = PeerOperationLogTag(value: 26)
} }
public struct LegacyPeerSummaryCounterTags: OptionSet, Sequence, Hashable { public struct LegacyPeerSummaryCounterTags: OptionSet, Sequence, Hashable {

View File

@ -61,3 +61,21 @@ public func addSynchronizePinnedChatsOperation(transaction: Transaction, groupId
} }
transaction.operationLogAddEntry(peerId: PeerId(namespace: PeerId.Namespace._internalFromInt32Value(0), id: PeerId.Id._internalFromInt64Value(Int64(rawId))), tag: OperationLogTags.SynchronizePinnedChats, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: operationContents) transaction.operationLogAddEntry(peerId: PeerId(namespace: PeerId.Namespace._internalFromInt32Value(0), id: PeerId.Id._internalFromInt64Value(Int64(rawId))), tag: OperationLogTags.SynchronizePinnedChats, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: operationContents)
} }
public func addSynchronizePinnedSavedChatsOperation(transaction: Transaction, accountPeerId: PeerId) {
var previousItemIds = transaction.getPeerPinnedThreads(peerId: accountPeerId).map { PinnedItemId.peer(PeerId($0)) }
var updateLocalIndex: Int32?
transaction.operationLogEnumerateEntries(peerId: PeerId(namespace: PeerId.Namespace._internalFromInt32Value(0), id: PeerId.Id._internalFromInt64Value(0)), tag: OperationLogTags.SynchronizePinnedSavedChats, { entry in
updateLocalIndex = entry.tagLocalIndex
if let contents = entry.contents as? SynchronizePinnedChatsOperation {
previousItemIds = contents.previousItemIds
}
return false
})
let operationContents = SynchronizePinnedChatsOperation(previousItemIds: previousItemIds)
if let updateLocalIndex = updateLocalIndex {
let _ = transaction.operationLogRemoveEntry(peerId: PeerId(namespace: PeerId.Namespace._internalFromInt32Value(0), id: PeerId.Id._internalFromInt64Value(0)), tag: OperationLogTags.SynchronizePinnedSavedChats, tagLocalIndex: updateLocalIndex)
}
transaction.operationLogAddEntry(peerId: PeerId(namespace: PeerId.Namespace._internalFromInt32Value(0), id: PeerId.Id._internalFromInt64Value(0)), tag: OperationLogTags.SynchronizePinnedSavedChats, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: operationContents)
}

View File

@ -296,6 +296,18 @@ func locallyRenderedMessage(message: StoreMessage, peers: AccumulatedPeers, asso
public extension Message { public extension Message {
func effectivelyIncoming(_ accountPeerId: PeerId) -> Bool { func effectivelyIncoming(_ accountPeerId: PeerId) -> Bool {
if self.id.peerId == accountPeerId { if self.id.peerId == accountPeerId {
if let sourceAuthorInfo = self.sourceAuthorInfo {
if sourceAuthorInfo.originalOutgoing {
return false
} else if let originalAuthor = sourceAuthorInfo.originalAuthor, originalAuthor == accountPeerId {
return false
}
} else if let forwardInfo = self.forwardInfo {
if let author = forwardInfo.author, author.id == accountPeerId {
return false
}
}
if self.forwardInfo != nil { if self.forwardInfo != nil {
return true return true
} else { } else {

View File

@ -293,6 +293,8 @@ public final class PeerInfoChatListPaneNode: ASDisplayNode, PeerInfoPaneNode, UI
} }
public func scrollToTop() -> Bool { public func scrollToTop() -> Bool {
self.chatListNode.scrollToPosition(.top(adjustForTempInset: false))
return false return false
} }

View File

@ -10,6 +10,7 @@ import ChatControllerInteraction
import OverlayStatusController import OverlayStatusController
import TelegramPresentationData import TelegramPresentationData
import PresentationDataUtils import PresentationDataUtils
import UndoUI
extension ChatControllerImpl { extension ChatControllerImpl {
func navigateToMessage( func navigateToMessage(
@ -149,8 +150,13 @@ extension ChatControllerImpl {
} }
if let navigationController = self.effectiveNavigationController { if let navigationController = self.effectiveNavigationController {
var chatLocation: NavigateToChatControllerParams.Location = .peer(peer) var chatLocation: NavigateToChatControllerParams.Location = .peer(peer)
if case let .channel(channel) = peer, channel.flags.contains(.isForum), let message = message, let threadId = message.threadId { var displayMessageNotFoundToast = false
if case let .channel(channel) = peer, channel.flags.contains(.isForum) {
if let message = message, let threadId = message.threadId {
chatLocation = .replyThread(ChatReplyThreadMessage(peerId: peer.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false)) chatLocation = .replyThread(ChatReplyThreadMessage(peerId: peer.id, threadId: threadId, channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false))
} else {
displayMessageNotFoundToast = true
}
} }
var quote: ChatControllerSubject.MessageHighlight.Quote? var quote: ChatControllerSubject.MessageHighlight.Quote?
@ -158,7 +164,15 @@ extension ChatControllerImpl {
quote = params.quote.flatMap { quote in ChatControllerSubject.MessageHighlight.Quote(string: quote.string, offset: quote.offset) } quote = params.quote.flatMap { quote in ChatControllerSubject.MessageHighlight.Quote(string: quote.string, offset: quote.offset) }
} }
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: chatLocation, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: quote), timecode: nil), keepStack: .always)) let context = self.context
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: chatLocation, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: quote), timecode: nil), keepStack: .always, chatListCompletion: { chatListController in
if displayMessageNotFoundToast {
let presentationData = context.sharedContext.currentPresentationData.with({ $0 })
chatListController.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.Conversation_MessageDoesntExist, timeout: nil, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
return true
}), in: .current)
}
}))
} }
completion?() completion?()

View File

@ -3014,6 +3014,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if case let .replyThread(replyThreadMessage) = strongSelf.chatLocation, replyThreadMessage.effectiveMessageId == message.id { if case let .replyThread(replyThreadMessage) = strongSelf.chatLocation, replyThreadMessage.effectiveMessageId == message.id {
return .none return .none
} }
if case let .replyThread(replyThreadMessage) = strongSelf.chatLocation, replyThreadMessage.peerId == strongSelf.context.account.peerId {
return .none
}
if case .peer = strongSelf.chatLocation, let channel = strongSelf.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.flags.contains(.isForum) { if case .peer = strongSelf.chatLocation, let channel = strongSelf.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.flags.contains(.isForum) {
if message.threadId == nil { if message.threadId == nil {
return .none return .none
@ -17472,7 +17475,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
if options.contains(.deleteLocally) { if options.contains(.deleteLocally) {
var localOptionText = self.presentationData.strings.Conversation_DeleteMessagesForMe var localOptionText = self.presentationData.strings.Conversation_DeleteMessagesForMe
if case .scheduledMessages = self.presentationInterfaceState.subject { if case .peer(self.context.account.peerId) = self.chatLocation {
//TODO:localize
localOptionText = "Remove from Saved Messages"
} else if case .scheduledMessages = self.presentationInterfaceState.subject {
localOptionText = messageIds.count > 1 ? self.presentationData.strings.ScheduledMessages_DeleteMany : self.presentationData.strings.ScheduledMessages_Delete localOptionText = messageIds.count > 1 ? self.presentationData.strings.ScheduledMessages_DeleteMany : self.presentationData.strings.ScheduledMessages_Delete
} else { } else {
if options.contains(.unsendPersonal) { if options.contains(.unsendPersonal) {

View File

@ -76,23 +76,23 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
let controller = ChatListControllerImpl(context: params.context, location: .forum(peerId: peer.id), controlsHistoryPreload: false, enableDebugActions: false) let controller = ChatListControllerImpl(context: params.context, location: .forum(peerId: peer.id), controlsHistoryPreload: false, enableDebugActions: false)
let activateMessageSearch = params.activateMessageSearch let activateMessageSearch = params.activateMessageSearch
let chatListCompletion = params.chatListCompletion
params.navigationController.pushViewController(controller, completion: { [weak controller] in params.navigationController.pushViewController(controller, completion: { [weak controller] in
guard let controller, let activateMessageSearch else { guard let controller else {
return return
} }
if let activateMessageSearch {
controller.activateSearch(query: activateMessageSearch.1) controller.activateSearch(query: activateMessageSearch.1)
}
if let chatListCompletion {
chatListCompletion(controller)
}
}) })
return return
} }
/*if case let .peer(peer) = params.chatLocation, peer.id == params.context.account.peerId {
let savedMessagesScreen = SavedMessagesScreen(context: params.context)
params.navigationController.pushViewController(savedMessagesScreen, completion: {
})
return
}*/
var found = false var found = false
var isFirst = true var isFirst = true
if params.useExisting { if params.useExisting {