mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
[WIP] Topics
This commit is contained in:
parent
7ba86968c8
commit
7cd2f75827
28 changed files with 208 additions and 63 deletions
|
|
@ -1314,6 +1314,12 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||
}
|
||||
strongSelf.deletePeerChat(peerId: peerId, joined: joined)
|
||||
}
|
||||
self.chatListDisplayNode.containerNode.deletePeerThread = { [weak self] peerId, threadId in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.deletePeerThread(peerId: peerId, threadId: threadId)
|
||||
}
|
||||
|
||||
self.chatListDisplayNode.containerNode.peerSelected = { [weak self] peer, threadId, animated, activateInput, promoInfo in
|
||||
if let strongSelf = self {
|
||||
|
|
@ -3416,7 +3422,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||
return false
|
||||
}
|
||||
if value == .commit {
|
||||
let _ = strongSelf.context.engine.messages.clearHistoryInteractively(peerId: peerId, type: type).start(completed: {
|
||||
let _ = strongSelf.context.engine.messages.clearHistoryInteractively(peerId: peerId, threadId: nil, type: type).start(completed: {
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
|
|
@ -3603,6 +3609,40 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||
})
|
||||
}
|
||||
|
||||
private func deletePeerThread(peerId: EnginePeer.Id, threadId: Int64) {
|
||||
let actionSheet = ActionSheetController(presentationData: self.presentationData)
|
||||
var items: [ActionSheetItem] = []
|
||||
|
||||
//TODO:localize
|
||||
items.append(ActionSheetButtonItem(title: "Delete", color: .destructive, action: { [weak self, weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
self?.commitDeletePeerThread(peerId: peerId, threadId: threadId)
|
||||
}))
|
||||
|
||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items),
|
||||
ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
})
|
||||
])
|
||||
])
|
||||
self.present(actionSheet, in: .window(.root))
|
||||
}
|
||||
|
||||
private func commitDeletePeerThread(peerId: EnginePeer.Id, threadId: Int64) {
|
||||
let _ = self.context.engine.peers.removeForumChannelThread(id: peerId, threadId: threadId).start(completed: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.chatListDisplayNode.containerNode.updateState({ state in
|
||||
var state = state
|
||||
state.pendingRemovalPeerIds.remove(peerId)
|
||||
return state
|
||||
})
|
||||
strongSelf.chatListDisplayNode.containerNode.currentItemNode.setCurrentRemovingPeerId(nil)
|
||||
})
|
||||
}
|
||||
|
||||
public func maybeAskForPeerChatRemoval(peer: EngineRenderedPeer, joined: Bool = false, deleteGloballyIfPossible: Bool = false, completion: @escaping (Bool) -> Void, removed: @escaping () -> Void) {
|
||||
guard let chatPeer = peer.peers[peer.peerId], let mainPeer = peer.chatMainPeer else {
|
||||
completion(false)
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ private final class ChatListShimmerNode: ASDisplayNode {
|
|||
let timestamp1: Int32 = 100000
|
||||
let peers: [EnginePeer.Id: EnginePeer] = [:]
|
||||
let interaction = ChatListNodeInteraction(context: context, animationCache: animationCache, animationRenderer: animationRenderer, activateSearch: {}, peerSelected: { _, _, _, _ in }, disabledPeerSelected: { _ in }, togglePeerSelected: { _ in }, togglePeersSelection: { _, _ in }, additionalCategorySelected: { _ in
|
||||
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, deletePeer: { _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, hidePsa: { _ in }, activateChatPreview: { _, _, gesture, _ in
|
||||
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, deletePeer: { _, _ in }, deletePeerThread: { _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, hidePsa: { _ in }, activateChatPreview: { _, _, gesture, _ in
|
||||
gesture?.cancel()
|
||||
}, present: { _ in })
|
||||
|
||||
|
|
@ -504,6 +504,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||
previousItemNode.listNode.toggleArchivedFolderHiddenByDefault = nil
|
||||
previousItemNode.listNode.hidePsa = nil
|
||||
previousItemNode.listNode.deletePeerChat = nil
|
||||
previousItemNode.listNode.deletePeerThread = nil
|
||||
previousItemNode.listNode.peerSelected = nil
|
||||
previousItemNode.listNode.groupSelected = nil
|
||||
previousItemNode.listNode.updatePeerGrouping = nil
|
||||
|
|
@ -539,6 +540,9 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||
itemNode.listNode.deletePeerChat = { [weak self] peerId, joined in
|
||||
self?.deletePeerChat?(peerId, joined)
|
||||
}
|
||||
itemNode.listNode.deletePeerThread = { [weak self] peerId, threadId in
|
||||
self?.deletePeerThread?(peerId, threadId)
|
||||
}
|
||||
itemNode.listNode.peerSelected = { [weak self] peerId, threadId, animated, activateInput, promoInfo in
|
||||
self?.peerSelected?(peerId, threadId, animated, activateInput, promoInfo)
|
||||
}
|
||||
|
|
@ -597,6 +601,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
|||
var toggleArchivedFolderHiddenByDefault: (() -> Void)?
|
||||
var hidePsa: ((EnginePeer.Id) -> Void)?
|
||||
var deletePeerChat: ((EnginePeer.Id, Bool) -> Void)?
|
||||
var deletePeerThread: ((EnginePeer.Id, Int64) -> Void)?
|
||||
var peerSelected: ((EnginePeer, Int64?, Bool, Bool, ChatListNodeEntryPromoInfo?) -> Void)?
|
||||
var groupSelected: ((EngineChatList.Group) -> Void)?
|
||||
var updatePeerGrouping: ((EnginePeer.Id, Bool) -> Void)?
|
||||
|
|
|
|||
|
|
@ -1742,6 +1742,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||
}, setItemPinned: { _, _ in
|
||||
}, setPeerMuted: { _, _ in
|
||||
}, deletePeer: { _, _ in
|
||||
}, deletePeerThread: { _, _ in
|
||||
}, updatePeerGrouping: { _, _ in
|
||||
}, togglePeerMarkedUnread: { _, _ in
|
||||
}, toggleArchivedFolderHiddenByDefault: {
|
||||
|
|
@ -2951,7 +2952,7 @@ private final class ChatListSearchShimmerNode: ASDisplayNode {
|
|||
var peers: [EnginePeer.Id: EnginePeer] = [:]
|
||||
peers[peer1.id] = peer1
|
||||
let interaction = ChatListNodeInteraction(context: context, animationCache: animationCache, animationRenderer: animationRenderer, activateSearch: {}, peerSelected: { _, _, _, _ in }, disabledPeerSelected: { _ in }, togglePeerSelected: { _ in }, togglePeersSelection: { _, _ in }, additionalCategorySelected: { _ in
|
||||
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, deletePeer: { _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, hidePsa: { _ in }, activateChatPreview: { _, _, gesture, _ in
|
||||
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, deletePeer: { _, _ in }, deletePeerThread: { _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, hidePsa: { _ in }, activateChatPreview: { _, _, gesture, _ in
|
||||
gesture?.cancel()
|
||||
}, present: { _ in })
|
||||
|
||||
|
|
|
|||
|
|
@ -2562,8 +2562,12 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||
}
|
||||
|
||||
override func revealOptionSelected(_ option: ItemListRevealOption, animated: Bool) {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
}
|
||||
|
||||
var close = true
|
||||
if let item = self.item, case let .chatList(index) = item.index {
|
||||
if case let .chatList(index) = item.index {
|
||||
switch option.key {
|
||||
case RevealOptionKey.pin.rawValue:
|
||||
switch item.content {
|
||||
|
|
@ -2636,6 +2640,13 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||
default:
|
||||
break
|
||||
}
|
||||
} else if case let .forum(_, threadId, _, _) = item.index, case let .forum(peerId) = item.chatListLocation {
|
||||
switch option.key {
|
||||
case RevealOptionKey.delete.rawValue:
|
||||
item.interaction.deletePeerThread(peerId, threadId)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
if close {
|
||||
self.setRevealOptionsOpened(false, animated: true)
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ public final class ChatListNodeInteraction {
|
|||
let setItemPinned: (EngineChatList.PinnedItem.Id, Bool) -> Void
|
||||
let setPeerMuted: (EnginePeer.Id, Bool) -> Void
|
||||
let deletePeer: (EnginePeer.Id, Bool) -> Void
|
||||
let deletePeerThread: (EnginePeer.Id, Int64) -> Void
|
||||
let updatePeerGrouping: (EnginePeer.Id, Bool) -> Void
|
||||
let togglePeerMarkedUnread: (EnginePeer.Id, Bool) -> Void
|
||||
let toggleArchivedFolderHiddenByDefault: () -> Void
|
||||
|
|
@ -98,6 +99,7 @@ public final class ChatListNodeInteraction {
|
|||
setItemPinned: @escaping (EngineChatList.PinnedItem.Id, Bool) -> Void,
|
||||
setPeerMuted: @escaping (EnginePeer.Id, Bool) -> Void,
|
||||
deletePeer: @escaping (EnginePeer.Id, Bool) -> Void,
|
||||
deletePeerThread: @escaping (EnginePeer.Id, Int64) -> Void,
|
||||
updatePeerGrouping: @escaping (EnginePeer.Id, Bool) -> Void,
|
||||
togglePeerMarkedUnread: @escaping (EnginePeer.Id, Bool) -> Void,
|
||||
toggleArchivedFolderHiddenByDefault: @escaping () -> Void,
|
||||
|
|
@ -118,6 +120,7 @@ public final class ChatListNodeInteraction {
|
|||
self.setItemPinned = setItemPinned
|
||||
self.setPeerMuted = setPeerMuted
|
||||
self.deletePeer = deletePeer
|
||||
self.deletePeerThread = deletePeerThread
|
||||
self.updatePeerGrouping = updatePeerGrouping
|
||||
self.togglePeerMarkedUnread = togglePeerMarkedUnread
|
||||
self.toggleArchivedFolderHiddenByDefault = toggleArchivedFolderHiddenByDefault
|
||||
|
|
@ -655,6 +658,7 @@ public final class ChatListNode: ListView {
|
|||
public var addContact: ((String) -> Void)?
|
||||
public var activateSearch: (() -> Void)?
|
||||
public var deletePeerChat: ((EnginePeer.Id, Bool) -> Void)?
|
||||
public var deletePeerThread: ((EnginePeer.Id, Int64) -> Void)?
|
||||
public var updatePeerGrouping: ((EnginePeer.Id, Bool) -> Void)?
|
||||
public var presentAlert: ((String) -> Void)?
|
||||
public var present: ((ViewController) -> Void)?
|
||||
|
|
@ -953,6 +957,8 @@ public final class ChatListNode: ListView {
|
|||
})
|
||||
}, deletePeer: { [weak self] peerId, joined in
|
||||
self?.deletePeerChat?(peerId, joined)
|
||||
}, deletePeerThread: { [weak self] peerId, threadId in
|
||||
self?.deletePeerThread?(peerId, threadId)
|
||||
}, updatePeerGrouping: { [weak self] peerId, group in
|
||||
self?.updatePeerGrouping?(peerId, group)
|
||||
}, togglePeerMarkedUnread: { [weak self, weak context] peerId, animated in
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ public final class HashtagSearchController: TelegramBaseController {
|
|||
}, setItemPinned: { _, _ in
|
||||
}, setPeerMuted: { _, _ in
|
||||
}, deletePeer: { _, _ in
|
||||
}, deletePeerThread: { _, _ in
|
||||
}, updatePeerGrouping: { _, _ in
|
||||
}, togglePeerMarkedUnread: { _, _ in
|
||||
}, toggleArchivedFolderHiddenByDefault: {
|
||||
|
|
|
|||
|
|
@ -470,16 +470,42 @@ final class MessageHistoryTable: Table {
|
|||
self.processIndexOperations(peerId, operations: operations, processedOperationsByPeerId: &operationsByPeerId, updatedMedia: &updatedMedia, unsentMessageOperations: &unsentMessageOperations, updatedPeerReadStateOperations: &updatedPeerReadStateOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, localTagsOperations: &localTagsOperations, timestampBasedMessageAttributesOperations: ×tampBasedMessageAttributesOperations)
|
||||
}
|
||||
|
||||
func clearHistoryInRange(peerId: PeerId, minTimestamp: Int32, maxTimestamp: Int32, namespaces: MessageIdNamespaces, operationsByPeerId: inout [PeerId: [MessageHistoryOperation]], updatedMedia: inout [MediaId: Media?], unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedPeerReadStateOperations: inout [PeerId: PeerReadStateSynchronizationOperation?], globalTagsOperations: inout [GlobalMessageHistoryTagsOperation], pendingActionsOperations: inout [PendingMessageActionsOperation], updatedMessageActionsSummaries: inout [PendingMessageActionsSummaryKey: Int32], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation], timestampBasedMessageAttributesOperations: inout [TimestampBasedMessageAttributesOperation], forEachMedia: (Media) -> Void) {
|
||||
func clearHistoryInRange(peerId: PeerId, threadId: Int64?, minTimestamp: Int32, maxTimestamp: Int32, namespaces: MessageIdNamespaces, operationsByPeerId: inout [PeerId: [MessageHistoryOperation]], updatedMedia: inout [MediaId: Media?], unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedPeerReadStateOperations: inout [PeerId: PeerReadStateSynchronizationOperation?], globalTagsOperations: inout [GlobalMessageHistoryTagsOperation], pendingActionsOperations: inout [PendingMessageActionsOperation], updatedMessageActionsSummaries: inout [PendingMessageActionsSummaryKey: Int32], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation], timestampBasedMessageAttributesOperations: inout [TimestampBasedMessageAttributesOperation], forEachMedia: (Media) -> Void) {
|
||||
var indices = self.allMessageIndices(peerId: peerId).filter { namespaces.contains($0.id.namespace) }
|
||||
if let threadId = threadId {
|
||||
indices = indices.filter { index in
|
||||
if let message = self.getMessage(index) {
|
||||
if message.threadId == threadId {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
indices = indices.filter { index in
|
||||
return index.timestamp >= minTimestamp && index.timestamp <= maxTimestamp
|
||||
}
|
||||
self.removeMessages(indices.map { $0.id }, operationsByPeerId: &operationsByPeerId, updatedMedia: &updatedMedia, unsentMessageOperations: &unsentMessageOperations, updatedPeerReadStateOperations: &updatedPeerReadStateOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, localTagsOperations: &localTagsOperations, timestampBasedMessageAttributesOperations: ×tampBasedMessageAttributesOperations, forEachMedia: forEachMedia)
|
||||
}
|
||||
|
||||
func clearHistory(peerId: PeerId, namespaces: MessageIdNamespaces, operationsByPeerId: inout [PeerId: [MessageHistoryOperation]], updatedMedia: inout [MediaId: Media?], unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedPeerReadStateOperations: inout [PeerId: PeerReadStateSynchronizationOperation?], globalTagsOperations: inout [GlobalMessageHistoryTagsOperation], pendingActionsOperations: inout [PendingMessageActionsOperation], updatedMessageActionsSummaries: inout [PendingMessageActionsSummaryKey: Int32], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation], timestampBasedMessageAttributesOperations: inout [TimestampBasedMessageAttributesOperation], forEachMedia: (Media) -> Void) {
|
||||
let indices = self.allMessageIndices(peerId: peerId).filter { namespaces.contains($0.id.namespace) }
|
||||
func clearHistory(peerId: PeerId, threadId: Int64?, namespaces: MessageIdNamespaces, operationsByPeerId: inout [PeerId: [MessageHistoryOperation]], updatedMedia: inout [MediaId: Media?], unsentMessageOperations: inout [IntermediateMessageHistoryUnsentOperation], updatedPeerReadStateOperations: inout [PeerId: PeerReadStateSynchronizationOperation?], globalTagsOperations: inout [GlobalMessageHistoryTagsOperation], pendingActionsOperations: inout [PendingMessageActionsOperation], updatedMessageActionsSummaries: inout [PendingMessageActionsSummaryKey: Int32], updatedMessageTagSummaries: inout [MessageHistoryTagsSummaryKey: MessageHistoryTagNamespaceSummary], invalidateMessageTagSummaries: inout [InvalidatedMessageHistoryTagsSummaryEntryOperation], localTagsOperations: inout [IntermediateMessageHistoryLocalTagsOperation], timestampBasedMessageAttributesOperations: inout [TimestampBasedMessageAttributesOperation], forEachMedia: (Media) -> Void) {
|
||||
var indices = self.allMessageIndices(peerId: peerId).filter { namespaces.contains($0.id.namespace) }
|
||||
if let threadId = threadId {
|
||||
indices = indices.filter { index in
|
||||
if let message = self.getMessage(index) {
|
||||
if message.threadId == threadId {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
self.removeMessages(indices.map { $0.id }, operationsByPeerId: &operationsByPeerId, updatedMedia: &updatedMedia, unsentMessageOperations: &unsentMessageOperations, updatedPeerReadStateOperations: &updatedPeerReadStateOperations, globalTagsOperations: &globalTagsOperations, pendingActionsOperations: &pendingActionsOperations, updatedMessageActionsSummaries: &updatedMessageActionsSummaries, updatedMessageTagSummaries: &updatedMessageTagSummaries, invalidateMessageTagSummaries: &invalidateMessageTagSummaries, localTagsOperations: &localTagsOperations, timestampBasedMessageAttributesOperations: ×tampBasedMessageAttributesOperations, forEachMedia: forEachMedia)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,11 +64,15 @@ class MessageHistoryThreadIndexTable: Table {
|
|||
return ValueBoxTable(id: id, keyType: .binary, compactValuesOnCreation: true)
|
||||
}
|
||||
|
||||
private struct UpdatedEntry {
|
||||
var value: CodableEntry?
|
||||
}
|
||||
|
||||
private let reverseIndexTable: MessageHistoryThreadReverseIndexTable
|
||||
|
||||
private let sharedKey = ValueBoxKey(length: 8 + 4 + 8 + 4 + 4)
|
||||
|
||||
private var updatedInfoItems: [MessageHistoryThreadsTable.ItemId: CodableEntry] = [:]
|
||||
private var updatedInfoItems: [MessageHistoryThreadsTable.ItemId: UpdatedEntry] = [:]
|
||||
|
||||
init(valueBox: ValueBox, table: ValueBoxTable, reverseIndexTable: MessageHistoryThreadReverseIndexTable, useCaches: Bool) {
|
||||
self.reverseIndexTable = reverseIndexTable
|
||||
|
|
@ -112,7 +116,7 @@ class MessageHistoryThreadIndexTable: Table {
|
|||
|
||||
func get(peerId: PeerId, threadId: Int64) -> CodableEntry? {
|
||||
if let updated = self.updatedInfoItems[MessageHistoryThreadsTable.ItemId(peerId: peerId, threadId: threadId)] {
|
||||
return updated
|
||||
return updated.value
|
||||
} else {
|
||||
if let itemIndex = self.reverseIndexTable.get(peerId: peerId, threadId: threadId) {
|
||||
if let value = self.valueBox.get(self.table, key: self.key(peerId: itemIndex.id.peerId, timestamp: itemIndex.timestamp, threadId: threadId, namespace: itemIndex.id.namespace, id: itemIndex.id.id, key: self.sharedKey)) {
|
||||
|
|
@ -130,8 +134,8 @@ class MessageHistoryThreadIndexTable: Table {
|
|||
}
|
||||
}
|
||||
|
||||
func set(peerId: PeerId, threadId: Int64, info: CodableEntry) {
|
||||
self.updatedInfoItems[MessageHistoryThreadsTable.ItemId(peerId: peerId, threadId: threadId)] = info
|
||||
func set(peerId: PeerId, threadId: Int64, info: CodableEntry?) {
|
||||
self.updatedInfoItems[MessageHistoryThreadsTable.ItemId(peerId: peerId, threadId: threadId)] = UpdatedEntry(value: info)
|
||||
}
|
||||
|
||||
func replay(threadsTable: MessageHistoryThreadsTable, namespaces: Set<MessageId.Namespace>, updatedIds: Set<MessageHistoryThreadsTable.ItemId>) -> Set<PeerId> {
|
||||
|
|
@ -155,7 +159,11 @@ class MessageHistoryThreadIndexTable: Table {
|
|||
self.valueBox.remove(self.table, key: previousKey, secure: true)
|
||||
}
|
||||
if let updatedInfo = self.updatedInfoItems[itemId] {
|
||||
info = ReadBuffer(data: updatedInfo.data)
|
||||
if let value = updatedInfo.value {
|
||||
info = ReadBuffer(data: value.data)
|
||||
} else {
|
||||
info = nil
|
||||
}
|
||||
}
|
||||
|
||||
if let topIndex = topIndex, let info = info {
|
||||
|
|
|
|||
|
|
@ -151,9 +151,9 @@ public final class Transaction {
|
|||
self.postbox?.withAllMessages(peerId: peerId, namespace: namespace, f)
|
||||
}
|
||||
|
||||
public func clearHistory(_ peerId: PeerId, minTimestamp: Int32?, maxTimestamp: Int32?, namespaces: MessageIdNamespaces, forEachMedia: (Media) -> Void) {
|
||||
public func clearHistory(_ peerId: PeerId, threadId: Int64?, minTimestamp: Int32?, maxTimestamp: Int32?, namespaces: MessageIdNamespaces, forEachMedia: (Media) -> Void) {
|
||||
assert(!self.disposed)
|
||||
self.postbox?.clearHistory(peerId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, namespaces: namespaces, forEachMedia: forEachMedia)
|
||||
self.postbox?.clearHistory(peerId, threadId: threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, namespaces: namespaces, forEachMedia: forEachMedia)
|
||||
}
|
||||
|
||||
public func removeAllMessagesWithAuthor(_ peerId: PeerId, authorId: PeerId, namespace: MessageId.Namespace, forEachMedia: (Media) -> Void) {
|
||||
|
|
@ -1169,7 +1169,7 @@ public final class Transaction {
|
|||
return self.postbox!.messageHistoryThreadIndexTable.get(peerId: peerId, threadId: threadId)
|
||||
}
|
||||
|
||||
public func setMessageHistoryThreadInfo(peerId: PeerId, threadId: Int64, info: CodableEntry) {
|
||||
public func setMessageHistoryThreadInfo(peerId: PeerId, threadId: Int64, info: CodableEntry?) {
|
||||
assert(!self.disposed)
|
||||
self.postbox!.messageHistoryThreadIndexTable.set(peerId: peerId, threadId: threadId, info: info)
|
||||
}
|
||||
|
|
@ -1864,11 +1864,11 @@ final class PostboxImpl {
|
|||
}
|
||||
}
|
||||
|
||||
fileprivate func clearHistory(_ peerId: PeerId, minTimestamp: Int32?, maxTimestamp: Int32?, namespaces: MessageIdNamespaces, forEachMedia: (Media) -> Void) {
|
||||
fileprivate func clearHistory(_ peerId: PeerId, threadId: Int64?, minTimestamp: Int32?, maxTimestamp: Int32?, namespaces: MessageIdNamespaces, forEachMedia: (Media) -> Void) {
|
||||
if let minTimestamp = minTimestamp, let maxTimestamp = maxTimestamp {
|
||||
self.messageHistoryTable.clearHistoryInRange(peerId: peerId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, namespaces: namespaces, operationsByPeerId: &self.currentOperationsByPeerId, updatedMedia: &self.currentUpdatedMedia, unsentMessageOperations: ¤tUnsentOperations, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations, globalTagsOperations: &self.currentGlobalTagsOperations, pendingActionsOperations: &self.currentPendingMessageActionsOperations, updatedMessageActionsSummaries: &self.currentUpdatedMessageActionsSummaries, updatedMessageTagSummaries: &self.currentUpdatedMessageTagSummaries, invalidateMessageTagSummaries: &self.currentInvalidateMessageTagSummaries, localTagsOperations: &self.currentLocalTagsOperations, timestampBasedMessageAttributesOperations: &self.currentTimestampBasedMessageAttributesOperations, forEachMedia: forEachMedia)
|
||||
self.messageHistoryTable.clearHistoryInRange(peerId: peerId, threadId: threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, namespaces: namespaces, operationsByPeerId: &self.currentOperationsByPeerId, updatedMedia: &self.currentUpdatedMedia, unsentMessageOperations: ¤tUnsentOperations, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations, globalTagsOperations: &self.currentGlobalTagsOperations, pendingActionsOperations: &self.currentPendingMessageActionsOperations, updatedMessageActionsSummaries: &self.currentUpdatedMessageActionsSummaries, updatedMessageTagSummaries: &self.currentUpdatedMessageTagSummaries, invalidateMessageTagSummaries: &self.currentInvalidateMessageTagSummaries, localTagsOperations: &self.currentLocalTagsOperations, timestampBasedMessageAttributesOperations: &self.currentTimestampBasedMessageAttributesOperations, forEachMedia: forEachMedia)
|
||||
} else {
|
||||
self.messageHistoryTable.clearHistory(peerId: peerId, namespaces: namespaces, operationsByPeerId: &self.currentOperationsByPeerId, updatedMedia: &self.currentUpdatedMedia, unsentMessageOperations: ¤tUnsentOperations, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations, globalTagsOperations: &self.currentGlobalTagsOperations, pendingActionsOperations: &self.currentPendingMessageActionsOperations, updatedMessageActionsSummaries: &self.currentUpdatedMessageActionsSummaries, updatedMessageTagSummaries: &self.currentUpdatedMessageTagSummaries, invalidateMessageTagSummaries: &self.currentInvalidateMessageTagSummaries, localTagsOperations: &self.currentLocalTagsOperations, timestampBasedMessageAttributesOperations: &self.currentTimestampBasedMessageAttributesOperations, forEachMedia: forEachMedia)
|
||||
self.messageHistoryTable.clearHistory(peerId: peerId, threadId: threadId, namespaces: namespaces, operationsByPeerId: &self.currentOperationsByPeerId, updatedMedia: &self.currentUpdatedMedia, unsentMessageOperations: ¤tUnsentOperations, updatedPeerReadStateOperations: &self.currentUpdatedSynchronizeReadStateOperations, globalTagsOperations: &self.currentGlobalTagsOperations, pendingActionsOperations: &self.currentPendingMessageActionsOperations, updatedMessageActionsSummaries: &self.currentUpdatedMessageActionsSummaries, updatedMessageTagSummaries: &self.currentUpdatedMessageTagSummaries, invalidateMessageTagSummaries: &self.currentInvalidateMessageTagSummaries, localTagsOperations: &self.currentLocalTagsOperations, timestampBasedMessageAttributesOperations: &self.currentTimestampBasedMessageAttributesOperations, forEachMedia: forEachMedia)
|
||||
for namespace in self.messageHistoryHoleIndexTable.existingNamespaces(peerId: peerId, holeSpace: .everywhere) where namespaces.contains(namespace) {
|
||||
self.messageHistoryHoleIndexTable.remove(peerId: peerId, namespace: namespace, space: .everywhere, range: 1 ... Int32.max - 1, operations: &self.currentPeerHoleOperations)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView
|
|||
var items: [ChatListItem] = []
|
||||
|
||||
let interaction = ChatListNodeInteraction(context: self.context, animationCache: self.animationCache, animationRenderer: self.animationRenderer, activateSearch: {}, peerSelected: { _, _, _, _ in }, disabledPeerSelected: { _ in }, togglePeerSelected: { _ in }, togglePeersSelection: { _, _ in }, additionalCategorySelected: { _ in
|
||||
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, deletePeer: { _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, hidePsa: { _ in
|
||||
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, deletePeer: { _, _ in }, deletePeerThread: { _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, hidePsa: { _ in
|
||||
}, activateChatPreview: { _, _, gesture, _ in
|
||||
gesture?.cancel()
|
||||
}, present: { _ in })
|
||||
|
|
|
|||
|
|
@ -839,7 +839,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
|||
var items: [ChatListItem] = []
|
||||
|
||||
let interaction = ChatListNodeInteraction(context: self.context, animationCache: self.animationCache, animationRenderer: self.animationRenderer, activateSearch: {}, peerSelected: { _, _, _, _ in }, disabledPeerSelected: { _ in }, togglePeerSelected: { _ in }, togglePeersSelection: { _, _ in }, additionalCategorySelected: { _ in
|
||||
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, deletePeer: { _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, hidePsa: { _ in
|
||||
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, deletePeer: { _, _ in }, deletePeerThread: { _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, hidePsa: { _ in
|
||||
}, activateChatPreview: { _, _, gesture, _ in
|
||||
gesture?.cancel()
|
||||
}, present: { _ in
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||
var items: [ChatListItem] = []
|
||||
|
||||
let interaction = ChatListNodeInteraction(context: self.context, animationCache: self.animationCache, animationRenderer: self.animationRenderer, activateSearch: {}, peerSelected: { _, _, _, _ in }, disabledPeerSelected: { _ in }, togglePeerSelected: { _ in }, togglePeersSelection: { _, _ in }, additionalCategorySelected: { _ in
|
||||
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, deletePeer: { _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, hidePsa: { _ in
|
||||
}, messageSelected: { _, _, _, _ in}, groupSelected: { _ in }, addContact: { _ in }, setPeerIdWithRevealedOptions: { _, _ in }, setItemPinned: { _, _ in }, setPeerMuted: { _, _ in }, deletePeer: { _, _ in }, deletePeerThread: { _, _ in }, updatePeerGrouping: { _, _ in }, togglePeerMarkedUnread: { _, _ in}, toggleArchivedFolderHiddenByDefault: {}, hidePsa: { _ in
|
||||
}, activateChatPreview: { _, _, gesture, _ in
|
||||
gesture?.cancel()
|
||||
}, present: { _ in
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ func updateSecretChat(encryptionProvider: EncryptionProvider, accountPeerId: Pee
|
|||
|
||||
if isRemoved {
|
||||
let peerId = currentPeer.id
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId, namespaces: .all)
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId, threadId: nil, namespaces: .all)
|
||||
transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
|
||||
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlySearchedPeerIds, itemId: RecentPeerItemId(peerId).rawValue)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ func cloudChatAddRemoveChatOperation(transaction: Transaction, peerId: PeerId, r
|
|||
transaction.operationLogAddEntry(peerId: peerId, tag: OperationLogTags.CloudChatRemoveMessages, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: CloudChatRemoveChatOperation(peerId: peerId, reportChatSpam: reportChatSpam, deleteGloballyIfPossible: deleteGloballyIfPossible, topMessageId: transaction.getTopPeerMessageId(peerId: peerId, namespace: Namespaces.Message.Cloud)))
|
||||
}
|
||||
|
||||
func cloudChatAddClearHistoryOperation(transaction: Transaction, peerId: PeerId, explicitTopMessageId: MessageId?, minTimestamp: Int32?, maxTimestamp: Int32?, type: CloudChatClearHistoryType) {
|
||||
func cloudChatAddClearHistoryOperation(transaction: Transaction, peerId: PeerId, threadId: Int64?, explicitTopMessageId: MessageId?, minTimestamp: Int32?, maxTimestamp: Int32?, type: CloudChatClearHistoryType) {
|
||||
if type == .scheduledMessages {
|
||||
var messageIds: [MessageId] = []
|
||||
transaction.withAllMessages(peerId: peerId, namespace: Namespaces.Message.ScheduledCloud) { message -> Bool in
|
||||
|
|
@ -24,7 +24,7 @@ func cloudChatAddClearHistoryOperation(transaction: Transaction, peerId: PeerId,
|
|||
topMessageId = transaction.getTopPeerMessageId(peerId: peerId, namespace: Namespaces.Message.Cloud)
|
||||
}
|
||||
if let topMessageId = topMessageId {
|
||||
transaction.operationLogAddEntry(peerId: peerId, tag: OperationLogTags.CloudChatRemoveMessages, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: CloudChatClearHistoryOperation(peerId: peerId, topMessageId: topMessageId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type))
|
||||
transaction.operationLogAddEntry(peerId: peerId, tag: OperationLogTags.CloudChatRemoveMessages, tagLocalIndex: .automatic, tagMergedIndex: .automatic, contents: CloudChatClearHistoryOperation(peerId: peerId, topMessageId: topMessageId, threadId: threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ private func removeChat(transaction: Transaction, postbox: Postbox, network: Net
|
|||
|> then(deleteUser)
|
||||
|> then(reportSignal)
|
||||
|> then(postbox.transaction { transaction -> Void in
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peer.id, namespaces: .all)
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peer.id, threadId: nil, namespaces: .all)
|
||||
})
|
||||
} else if peer.id.namespace == Namespaces.Peer.CloudUser {
|
||||
if let inputPeer = apiInputPeer(peer) {
|
||||
|
|
@ -329,7 +329,7 @@ private func removeChat(transaction: Transaction, postbox: Postbox, network: Net
|
|||
return requestClearHistory(postbox: postbox, network: network, stateManager: stateManager, inputPeer: inputPeer, maxId: operation.topMessageId?.id ?? Int32.max - 1, justClear: false, minTimestamp: nil, maxTimestamp: nil, type: operation.deleteGloballyIfPossible ? .forEveryone : .forLocalPeer)
|
||||
|> then(reportSignal)
|
||||
|> then(postbox.transaction { transaction -> Void in
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peer.id, namespaces: .not(Namespaces.Message.allScheduled))
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peer.id, threadId: nil, namespaces: .not(Namespaces.Message.allScheduled))
|
||||
})
|
||||
} else {
|
||||
return .complete()
|
||||
|
|
@ -395,20 +395,33 @@ private func _internal_clearHistory(transaction: Transaction, postbox: Postbox,
|
|||
if operation.minTimestamp != nil {
|
||||
return .complete()
|
||||
} else {
|
||||
var flags: Int32 = 0
|
||||
if operation.type == .forEveryone {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
return network.request(Api.functions.channels.deleteHistory(flags: flags, channel: inputChannel, maxId: operation.topMessageId.id))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<Void, NoError> in
|
||||
if let updates = updates {
|
||||
stateManager.addUpdates(updates)
|
||||
if let threadId = operation.threadId {
|
||||
return network.request(Api.functions.channels.deleteTopicHistory(channel: inputChannel, topMsgId: Int32(clamping: threadId)))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.messages.AffectedHistory?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Void, NoError> in
|
||||
if let _ = result {
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
} else {
|
||||
var flags: Int32 = 0
|
||||
if operation.type == .forEveryone {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
return network.request(Api.functions.channels.deleteHistory(flags: flags, channel: inputChannel, maxId: operation.topMessageId.id))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<Void, NoError> in
|
||||
if let updates = updates {
|
||||
stateManager.addUpdates(updates)
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ func processSecretChatIncomingDecryptedOperations(encryptionProvider: Encryption
|
|||
_internal_deleteMessages(transaction: transaction, mediaBox: mediaBox, ids: filteredMessageIds)
|
||||
}
|
||||
case .clearHistory:
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId, namespaces: .all)
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId, threadId: nil, namespaces: .all)
|
||||
case let .markMessagesContentAsConsumed(globallyUniqueIds):
|
||||
var messageIds: [MessageId] = []
|
||||
for id in globallyUniqueIds {
|
||||
|
|
|
|||
|
|
@ -112,13 +112,15 @@ public extension CloudChatClearHistoryType {
|
|||
public final class CloudChatClearHistoryOperation: PostboxCoding {
|
||||
public let peerId: PeerId
|
||||
public let topMessageId: MessageId
|
||||
public let threadId: Int64?
|
||||
public let minTimestamp: Int32?
|
||||
public let maxTimestamp: Int32?
|
||||
public let type: CloudChatClearHistoryType
|
||||
|
||||
public init(peerId: PeerId, topMessageId: MessageId, minTimestamp: Int32?, maxTimestamp: Int32?, type: CloudChatClearHistoryType) {
|
||||
public init(peerId: PeerId, topMessageId: MessageId, threadId: Int64?, minTimestamp: Int32?, maxTimestamp: Int32?, type: CloudChatClearHistoryType) {
|
||||
self.peerId = peerId
|
||||
self.topMessageId = topMessageId
|
||||
self.threadId = threadId
|
||||
self.minTimestamp = minTimestamp
|
||||
self.maxTimestamp = maxTimestamp
|
||||
self.type = type
|
||||
|
|
@ -127,6 +129,7 @@ public final class CloudChatClearHistoryOperation: PostboxCoding {
|
|||
public init(decoder: PostboxDecoder) {
|
||||
self.peerId = PeerId(decoder.decodeInt64ForKey("p", orElse: 0))
|
||||
self.topMessageId = MessageId(peerId: PeerId(decoder.decodeInt64ForKey("m.p", orElse: 0)), namespace: decoder.decodeInt32ForKey("m.n", orElse: 0), id: decoder.decodeInt32ForKey("m.i", orElse: 0))
|
||||
self.threadId = decoder.decodeOptionalInt64ForKey("threadId")
|
||||
self.minTimestamp = decoder.decodeOptionalInt32ForKey("minTimestamp")
|
||||
self.maxTimestamp = decoder.decodeOptionalInt32ForKey("maxTimestamp")
|
||||
self.type = CloudChatClearHistoryType(rawValue: decoder.decodeInt32ForKey("type", orElse: 0)) ?? .forLocalPeer
|
||||
|
|
@ -137,6 +140,11 @@ public final class CloudChatClearHistoryOperation: PostboxCoding {
|
|||
encoder.encodeInt64(self.topMessageId.peerId.toInt64(), forKey: "m.p")
|
||||
encoder.encodeInt32(self.topMessageId.namespace, forKey: "m.n")
|
||||
encoder.encodeInt32(self.topMessageId.id, forKey: "m.i")
|
||||
if let threadId = self.threadId {
|
||||
encoder.encodeInt64(threadId, forKey: "threadId")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "threadId")
|
||||
}
|
||||
if let minTimestamp = self.minTimestamp {
|
||||
encoder.encodeInt32(minTimestamp, forKey: "minTimestamp")
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -65,6 +65,9 @@ public let telegramPostboxSeedConfiguration: SeedConfiguration = {
|
|||
case .broadcast:
|
||||
return .channel
|
||||
case .group:
|
||||
if channel.flags.contains(.isForum) {
|
||||
return []
|
||||
}
|
||||
if channel.username != nil {
|
||||
return .group
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -388,11 +388,17 @@ extension EngineChatList.Item {
|
|||
forumTopicTitle = forumTopicData.info.title
|
||||
}
|
||||
|
||||
var readCounters = readState.flatMap(EnginePeerReadCounters.init)
|
||||
|
||||
if let channel = renderedPeer.peer as? TelegramChannel, channel.flags.contains(.isForum) {
|
||||
readCounters = nil
|
||||
}
|
||||
|
||||
self.init(
|
||||
id: .chatList(index.messageIndex.id.peerId),
|
||||
index: .chatList(index),
|
||||
messages: messages.map(EngineMessage.init),
|
||||
readCounters: readState.flatMap(EnginePeerReadCounters.init),
|
||||
readCounters: readCounters,
|
||||
isMuted: isRemovedFromTotalUnreadCount,
|
||||
draft: draft,
|
||||
threadInfo: nil,
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ func _internal_deleteAllMessagesWithForwardAuthor(transaction: Transaction, medi
|
|||
}
|
||||
}
|
||||
|
||||
func _internal_clearHistory(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, namespaces: MessageIdNamespaces) {
|
||||
func _internal_clearHistory(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, threadId: Int64?, namespaces: MessageIdNamespaces) {
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
var resourceIds: [MediaResourceId] = []
|
||||
transaction.withAllMessages(peerId: peerId, { message in
|
||||
|
|
@ -87,11 +87,11 @@ func _internal_clearHistory(transaction: Transaction, mediaBox: MediaBox, peerId
|
|||
let _ = mediaBox.removeCachedResources(Set(resourceIds), force: true).start()
|
||||
}
|
||||
}
|
||||
transaction.clearHistory(peerId, minTimestamp: nil, maxTimestamp: nil, namespaces: namespaces, forEachMedia: { _ in
|
||||
transaction.clearHistory(peerId, threadId: threadId, minTimestamp: nil, maxTimestamp: nil, namespaces: namespaces, forEachMedia: { _ in
|
||||
})
|
||||
}
|
||||
|
||||
func _internal_clearHistoryInRange(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, minTimestamp: Int32, maxTimestamp: Int32, namespaces: MessageIdNamespaces) {
|
||||
func _internal_clearHistoryInRange(transaction: Transaction, mediaBox: MediaBox, peerId: PeerId, threadId: Int64?, minTimestamp: Int32, maxTimestamp: Int32, namespaces: MessageIdNamespaces) {
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
var resourceIds: [MediaResourceId] = []
|
||||
transaction.withAllMessages(peerId: peerId, { message in
|
||||
|
|
@ -104,7 +104,7 @@ func _internal_clearHistoryInRange(transaction: Transaction, mediaBox: MediaBox,
|
|||
let _ = mediaBox.removeCachedResources(Set(resourceIds), force: true).start()
|
||||
}
|
||||
}
|
||||
transaction.clearHistory(peerId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, namespaces: namespaces, forEachMedia: { _ in
|
||||
transaction.clearHistory(peerId, threadId: threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, namespaces: namespaces, forEachMedia: { _ in
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,13 +96,13 @@ func deleteMessagesInteractively(transaction: Transaction, stateManager: Account
|
|||
}
|
||||
}
|
||||
|
||||
func _internal_clearHistoryInRangeInteractively(postbox: Postbox, peerId: PeerId, minTimestamp: Int32, maxTimestamp: Int32, type: InteractiveHistoryClearingType) -> Signal<Void, NoError> {
|
||||
func _internal_clearHistoryInRangeInteractively(postbox: Postbox, peerId: PeerId, threadId: Int64?, minTimestamp: Int32, maxTimestamp: Int32, type: InteractiveHistoryClearingType) -> Signal<Void, NoError> {
|
||||
return postbox.transaction { transaction -> Void in
|
||||
if peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.CloudGroup || peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
cloudChatAddClearHistoryOperation(transaction: transaction, peerId: peerId, explicitTopMessageId: nil, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: CloudChatClearHistoryType(type))
|
||||
cloudChatAddClearHistoryOperation(transaction: transaction, peerId: peerId, threadId: threadId, explicitTopMessageId: nil, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: CloudChatClearHistoryType(type))
|
||||
if type == .scheduledMessages {
|
||||
} else {
|
||||
_internal_clearHistoryInRange(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peerId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, namespaces: .not(Namespaces.Message.allScheduled))
|
||||
_internal_clearHistoryInRange(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peerId, threadId: threadId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, namespaces: .not(Namespaces.Message.allScheduled))
|
||||
}
|
||||
} else if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
/*_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peerId, namespaces: .all)
|
||||
|
|
@ -129,22 +129,22 @@ func _internal_clearHistoryInRangeInteractively(postbox: Postbox, peerId: PeerId
|
|||
}
|
||||
}
|
||||
|
||||
func _internal_clearHistoryInteractively(postbox: Postbox, peerId: PeerId, type: InteractiveHistoryClearingType) -> Signal<Void, NoError> {
|
||||
func _internal_clearHistoryInteractively(postbox: Postbox, peerId: PeerId, threadId: Int64?, type: InteractiveHistoryClearingType) -> Signal<Void, NoError> {
|
||||
return postbox.transaction { transaction -> Void in
|
||||
if peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.CloudGroup || peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||
cloudChatAddClearHistoryOperation(transaction: transaction, peerId: peerId, explicitTopMessageId: nil, minTimestamp: nil, maxTimestamp: nil, type: CloudChatClearHistoryType(type))
|
||||
cloudChatAddClearHistoryOperation(transaction: transaction, peerId: peerId, threadId: threadId, explicitTopMessageId: nil, minTimestamp: nil, maxTimestamp: nil, type: CloudChatClearHistoryType(type))
|
||||
if type == .scheduledMessages {
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peerId, namespaces: .just(Namespaces.Message.allScheduled))
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peerId, threadId: threadId, namespaces: .just(Namespaces.Message.allScheduled))
|
||||
} else {
|
||||
var topIndex: MessageIndex?
|
||||
if let topMessageId = transaction.getTopPeerMessageId(peerId: peerId, namespace: Namespaces.Message.Cloud), let topMessage = transaction.getMessage(topMessageId) {
|
||||
topIndex = topMessage.index
|
||||
}
|
||||
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peerId, namespaces: .not(Namespaces.Message.allScheduled))
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peerId, threadId: threadId, namespaces: .not(Namespaces.Message.allScheduled))
|
||||
if let cachedData = transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData, let migrationReference = cachedData.migrationReference {
|
||||
cloudChatAddClearHistoryOperation(transaction: transaction, peerId: migrationReference.maxMessageId.peerId, explicitTopMessageId: MessageId(peerId: migrationReference.maxMessageId.peerId, namespace: migrationReference.maxMessageId.namespace, id: migrationReference.maxMessageId.id + 1), minTimestamp: nil, maxTimestamp: nil, type: CloudChatClearHistoryType(type))
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: migrationReference.maxMessageId.peerId, namespaces: .all)
|
||||
cloudChatAddClearHistoryOperation(transaction: transaction, peerId: migrationReference.maxMessageId.peerId, threadId: threadId, explicitTopMessageId: MessageId(peerId: migrationReference.maxMessageId.peerId, namespace: migrationReference.maxMessageId.namespace, id: migrationReference.maxMessageId.id + 1), minTimestamp: nil, maxTimestamp: nil, type: CloudChatClearHistoryType(type))
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: migrationReference.maxMessageId.peerId, threadId: threadId, namespaces: .all)
|
||||
}
|
||||
if let topIndex = topIndex {
|
||||
if peerId.namespace == Namespaces.Peer.CloudUser {
|
||||
|
|
@ -155,7 +155,7 @@ func _internal_clearHistoryInteractively(postbox: Postbox, peerId: PeerId, type:
|
|||
}
|
||||
}
|
||||
} else if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peerId, namespaces: .all)
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: postbox.mediaBox, peerId: peerId, threadId: nil, namespaces: .all)
|
||||
|
||||
if let state = transaction.getPeerChatState(peerId) as? SecretChatState {
|
||||
var layer: SecretChatLayer?
|
||||
|
|
|
|||
|
|
@ -886,7 +886,7 @@ public final class SparseMessageCalendar {
|
|||
|
||||
self.statePromise.set(.single(self.state))
|
||||
|
||||
return _internal_clearHistoryInRangeInteractively(postbox: self.account.postbox, peerId: self.peerId, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type).start(completed: {
|
||||
return _internal_clearHistoryInRangeInteractively(postbox: self.account.postbox, peerId: self.peerId, threadId: nil, minTimestamp: minTimestamp, maxTimestamp: maxTimestamp, type: type).start(completed: {
|
||||
completion()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,8 +77,8 @@ public extension TelegramEngine {
|
|||
return _internal_deleteMessagesInteractively(account: self.account, messageIds: messageIds, type: type, deleteAllInGroup: deleteAllInGroup)
|
||||
}
|
||||
|
||||
public func clearHistoryInteractively(peerId: PeerId, type: InteractiveHistoryClearingType) -> Signal<Void, NoError> {
|
||||
return _internal_clearHistoryInteractively(postbox: self.account.postbox, peerId: peerId, type: type)
|
||||
public func clearHistoryInteractively(peerId: PeerId, threadId: Int64?, type: InteractiveHistoryClearingType) -> Signal<Void, NoError> {
|
||||
return _internal_clearHistoryInteractively(postbox: self.account.postbox, peerId: peerId, threadId: threadId, type: type)
|
||||
}
|
||||
|
||||
public func clearAuthorHistory(peerId: PeerId, memberId: PeerId) -> Signal<Void, NoError> {
|
||||
|
|
|
|||
|
|
@ -58,17 +58,17 @@ func _internal_removePeerChat(account: Account, transaction: Transaction, mediaB
|
|||
}
|
||||
}
|
||||
}
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId, namespaces: .all)
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId, threadId: nil, namespaces: .all)
|
||||
transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
|
||||
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlySearchedPeerIds, itemId: RecentPeerItemId(peerId).rawValue)
|
||||
} else {
|
||||
cloudChatAddRemoveChatOperation(transaction: transaction, peerId: peerId, reportChatSpam: reportChatSpam, deleteGloballyIfPossible: deleteGloballyIfPossible)
|
||||
if peerId.namespace == Namespaces.Peer.CloudUser {
|
||||
transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId, namespaces: .all)
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId, threadId: nil, namespaces: .all)
|
||||
} else if peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||
transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId, namespaces: .all)
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: mediaBox, peerId: peerId, threadId: nil, namespaces: .all)
|
||||
} else {
|
||||
transaction.updatePeerChatListInclusion(peerId, inclusion: .notIncluded)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -809,6 +809,17 @@ public extension TelegramEngine {
|
|||
public func editForumChannelTopic(id: EnginePeer.Id, threadId: Int64, title: String, iconFileId: Int64?) -> Signal<Never, EditForumChannelTopicError> {
|
||||
return _internal_editForumChannelTopic(account: self.account, peerId: id, threadId: threadId, title: title, iconFileId: iconFileId)
|
||||
}
|
||||
|
||||
public func removeForumChannelThread(id: EnginePeer.Id, threadId: Int64) -> Signal<Never, NoError> {
|
||||
return self.account.postbox.transaction { transaction -> Void in
|
||||
cloudChatAddClearHistoryOperation(transaction: transaction, peerId: id, threadId: threadId, explicitTopMessageId: nil, minTimestamp: nil, maxTimestamp: nil, type: CloudChatClearHistoryType(.forEveryone))
|
||||
|
||||
transaction.setMessageHistoryThreadInfo(peerId: id, threadId: threadId, info: nil)
|
||||
|
||||
_internal_clearHistory(transaction: transaction, mediaBox: self.account.postbox.mediaBox, peerId: id, threadId: threadId, namespaces: .not(Namespaces.Message.allScheduled))
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -685,6 +685,7 @@ public class ForumCreateTopicScreen: ViewControllerComponentContainer {
|
|||
iconUpdatedImpl?(fileId)
|
||||
}), navigationBarAppearance: .transparent)
|
||||
|
||||
//TODO:localize
|
||||
let title: String
|
||||
let doneTitle: String
|
||||
switch mode {
|
||||
|
|
@ -704,6 +705,10 @@ public class ForumCreateTopicScreen: ViewControllerComponentContainer {
|
|||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: doneTitle, style: .done, target: self, action: #selector(self.createPressed))
|
||||
self.navigationItem.rightBarButtonItem?.isEnabled = false
|
||||
|
||||
if case .edit = mode {
|
||||
self.navigationItem.rightBarButtonItem?.isEnabled = true
|
||||
}
|
||||
|
||||
titleUpdatedImpl = { [weak self] title in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -10858,7 +10858,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
return false
|
||||
}
|
||||
if value == .commit {
|
||||
let _ = strongSelf.context.engine.messages.clearHistoryInteractively(peerId: peerId, type: type).start(completed: {
|
||||
let _ = strongSelf.context.engine.messages.clearHistoryInteractively(peerId: peerId, threadId: nil, type: type).start(completed: {
|
||||
self?.chatDisplayNode.historyNode.historyAppearsCleared = false
|
||||
})
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ class ChatSearchResultsControllerNode: ViewControllerTracingNode, UIScrollViewDe
|
|||
}, setItemPinned: { _, _ in
|
||||
}, setPeerMuted: { _, _ in
|
||||
}, deletePeer: { _, _ in
|
||||
}, deletePeerThread: { _, _ in
|
||||
}, updatePeerGrouping: { _, _ in
|
||||
}, togglePeerMarkedUnread: { _, _ in
|
||||
}, toggleArchivedFolderHiddenByDefault: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue