mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Update tab design
This commit is contained in:
@@ -165,9 +165,9 @@ public enum ChatListEntry: Comparable {
|
||||
}
|
||||
}
|
||||
|
||||
private func processedChatListEntry(_ entry: MutableChatListEntry, cachedDataTable: CachedPeerDataTable, readStateTable: MessageHistoryReadStateTable, messageHistoryTable: MessageHistoryTable) -> MutableChatListEntry {
|
||||
/*private func processedChatListEntry(_ entry: MutableChatListEntry, cachedDataTable: CachedPeerDataTable, readStateTable: MessageHistoryReadStateTable, messageHistoryTable: MessageHistoryTable) -> MutableChatListEntry {
|
||||
switch entry {
|
||||
case let .IntermediateMessageEntry(index, message, readState, embeddedState):
|
||||
case let .IntermediateMessageEntry(index, messageIndex):
|
||||
var updatedMessage = message
|
||||
if let message = message, let cachedData = cachedDataTable.get(message.id.peerId), let associatedHistoryMessageId = cachedData.associatedHistoryMessageId, message.id.id == 1 {
|
||||
if let messageIndex = messageHistoryTable.messageHistoryIndexTable.earlierEntries(id: associatedHistoryMessageId, count: 1).first {
|
||||
@@ -180,17 +180,17 @@ private func processedChatListEntry(_ entry: MutableChatListEntry, cachedDataTab
|
||||
default:
|
||||
return entry
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
enum MutableChatListEntry: Equatable {
|
||||
case IntermediateMessageEntry(ChatListIndex, IntermediateMessage?, CombinedPeerReadState?, PeerChatListEmbeddedInterfaceState?)
|
||||
case MessageEntry(ChatListIndex, Message?, CombinedPeerReadState?, PeerNotificationSettings?, PeerChatListEmbeddedInterfaceState?, RenderedPeer, PeerPresence?, ChatListMessageTagSummaryInfo, Bool, Bool)
|
||||
case IntermediateMessageEntry(index: ChatListIndex, messageIndex: MessageIndex?)
|
||||
case MessageEntry(index: ChatListIndex, message: Message?, readState: CombinedPeerReadState?, notificationSettings: PeerNotificationSettings?, embeddedInterfaceState: PeerChatListEmbeddedInterfaceState?, renderedPeer: RenderedPeer, presence: PeerPresence?, tagSummaryInfo: ChatListMessageTagSummaryInfo, hasFailedMessages: Bool, isContact: Bool)
|
||||
case HoleEntry(ChatListHole)
|
||||
|
||||
init(_ intermediateEntry: ChatListIntermediateEntry, cachedDataTable: CachedPeerDataTable, readStateTable: MessageHistoryReadStateTable, messageHistoryTable: MessageHistoryTable) {
|
||||
switch intermediateEntry {
|
||||
case let .message(index, message, embeddedState):
|
||||
self = processedChatListEntry(.IntermediateMessageEntry(index, message, readStateTable.getCombinedState(index.messageIndex.id.peerId), embeddedState), cachedDataTable: cachedDataTable, readStateTable: readStateTable, messageHistoryTable: messageHistoryTable)
|
||||
case let .message(index, messageIndex):
|
||||
self = .IntermediateMessageEntry(index: index, messageIndex: messageIndex)
|
||||
case let .hole(hole):
|
||||
self = .HoleEntry(hole)
|
||||
}
|
||||
@@ -198,8 +198,8 @@ enum MutableChatListEntry: Equatable {
|
||||
|
||||
var index: ChatListIndex {
|
||||
switch self {
|
||||
case let .IntermediateMessageEntry(index, _, _, _):
|
||||
return index
|
||||
case let .IntermediateMessageEntry(intermediateMessageEntry):
|
||||
return intermediateMessageEntry.index
|
||||
case let .MessageEntry(index, _, _, _, _, _, _, _, _, _):
|
||||
return index
|
||||
case let .HoleEntry(hole):
|
||||
@@ -254,69 +254,32 @@ private enum ChatListEntryType {
|
||||
case groupReference
|
||||
}
|
||||
|
||||
private func updateMessagePeers(_ message: Message, updatedPeers: [PeerId: Peer]) -> Message? {
|
||||
var updated = false
|
||||
for (peerId, currentPeer) in message.peers {
|
||||
if let updatedPeer = updatedPeers[peerId], !arePeersEqual(currentPeer, updatedPeer) {
|
||||
updated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if updated {
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
for (peerId, currentPeer) in message.peers {
|
||||
if let updatedPeer = updatedPeers[peerId] {
|
||||
peers[peerId] = updatedPeer
|
||||
} else {
|
||||
peers[peerId] = currentPeer
|
||||
}
|
||||
}
|
||||
return Message(stableId: message.stableId, stableVersion: message.stableVersion, id: message.id, globallyUniqueId: message.globallyUniqueId, groupingKey: message.groupingKey, groupInfo: message.groupInfo, timestamp: message.timestamp, flags: message.flags, tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: message.forwardInfo, author: message.author, text: message.text, attributes: message.attributes, media: message.media, peers: peers, associatedMessages: message.associatedMessages, associatedMessageIds: message.associatedMessageIds)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
private func updatedRenderedPeer(_ renderedPeer: RenderedPeer, updatedPeers: [PeerId: Peer]) -> RenderedPeer? {
|
||||
var updated = false
|
||||
for (peerId, currentPeer) in renderedPeer.peers {
|
||||
if let updatedPeer = updatedPeers[peerId], !arePeersEqual(currentPeer, updatedPeer) {
|
||||
updated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if updated {
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
for (peerId, currentPeer) in renderedPeer.peers {
|
||||
if let updatedPeer = updatedPeers[peerId] {
|
||||
peers[peerId] = updatedPeer
|
||||
} else {
|
||||
peers[peerId] = currentPeer
|
||||
}
|
||||
}
|
||||
return RenderedPeer(peerId: renderedPeer.peerId, peers: peers)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public struct ChatListFilterPredicate {
|
||||
public var includePeerIds: Set<PeerId>
|
||||
public var excludePeerIds: Set<PeerId>
|
||||
public var include: (Peer, PeerNotificationSettings?, Bool, Bool, Bool) -> Bool
|
||||
public var includeAdditionalPeerGroupIds: [PeerGroupId]
|
||||
public var include: (Peer, PeerNotificationSettings?, Bool, Bool) -> Bool
|
||||
|
||||
public init(includePeerIds: Set<PeerId>, excludePeerIds: Set<PeerId>, include: @escaping (Peer, PeerNotificationSettings?, Bool, Bool, Bool) -> Bool) {
|
||||
public init(includePeerIds: Set<PeerId>, excludePeerIds: Set<PeerId>, includeAdditionalPeerGroupIds: [PeerGroupId], include: @escaping (Peer, PeerNotificationSettings?, Bool, Bool) -> Bool) {
|
||||
self.includePeerIds = includePeerIds
|
||||
self.excludePeerIds = excludePeerIds
|
||||
self.includeAdditionalPeerGroupIds = includeAdditionalPeerGroupIds
|
||||
self.include = include
|
||||
}
|
||||
|
||||
func includes(peer: Peer, notificationSettings: PeerNotificationSettings?, isUnread: Bool, isContact: Bool, isArchived: Bool) -> Bool {
|
||||
func includes(peer: Peer, groupId: PeerGroupId, notificationSettings: PeerNotificationSettings?, isUnread: Bool, isContact: Bool) -> Bool {
|
||||
if self.excludePeerIds.contains(peer.id) {
|
||||
return false
|
||||
}
|
||||
if self.includePeerIds.contains(peer.id) {
|
||||
return true
|
||||
}
|
||||
return self.include(peer, notificationSettings, isUnread, isContact, isArchived)
|
||||
if groupId != .root {
|
||||
if !self.includeAdditionalPeerGroupIds.contains(groupId) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return self.include(peer, notificationSettings, isUnread, isContact)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,64 +287,48 @@ final class MutableChatListView {
|
||||
let groupId: PeerGroupId
|
||||
let filterPredicate: ChatListFilterPredicate?
|
||||
private let summaryComponents: ChatListEntrySummaryComponents
|
||||
fileprivate var additionalItemIds: Set<PeerId>
|
||||
fileprivate var additionalItemEntries: [MutableChatListEntry]
|
||||
fileprivate var additionalMixedItemIds: Set<PeerId>
|
||||
fileprivate var additionalMixedPinnedItemIds: Set<PeerId>
|
||||
fileprivate var additionalMixedItemEntries: [MutableChatListEntry]
|
||||
fileprivate var additionalMixedPinnedEntries: [MutableChatListEntry]
|
||||
fileprivate var earlier: MutableChatListEntry?
|
||||
fileprivate var later: MutableChatListEntry?
|
||||
fileprivate var entries: [MutableChatListEntry]
|
||||
fileprivate var groupEntries: [ChatListGroupReferenceEntry]
|
||||
private var count: Int
|
||||
|
||||
private let spaces: [ChatListViewSpace]
|
||||
fileprivate var state: ChatListViewState
|
||||
fileprivate var sampledState: ChatListViewSample
|
||||
|
||||
init(postbox: Postbox, groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?, aroundIndex: ChatListIndex, count: Int, summaryComponents: ChatListEntrySummaryComponents) {
|
||||
let (entries, earlier, later) = postbox.fetchAroundChatEntries(groupId: groupId, index: aroundIndex, count: count, filterPredicate: filterPredicate)
|
||||
|
||||
self.groupId = groupId
|
||||
self.filterPredicate = filterPredicate
|
||||
self.earlier = earlier
|
||||
self.entries = entries
|
||||
self.later = later
|
||||
self.count = count
|
||||
self.summaryComponents = summaryComponents
|
||||
self.additionalItemEntries = []
|
||||
self.additionalMixedItemEntries = []
|
||||
self.additionalMixedPinnedEntries = []
|
||||
self.additionalMixedItemIds = Set()
|
||||
self.additionalMixedPinnedItemIds = Set()
|
||||
|
||||
var spaces: [ChatListViewSpace] = [
|
||||
.group(groupId: self.groupId, pinned: .notPinned)
|
||||
]
|
||||
if let filterPredicate = self.filterPredicate {
|
||||
self.additionalMixedItemIds.formUnion(filterPredicate.includePeerIds)
|
||||
for (itemId, _) in postbox.chatListTable.getPinnedItemIds(groupId: self.groupId, messageHistoryTable: postbox.messageHistoryTable, peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable) {
|
||||
switch itemId {
|
||||
case let .peer(peerId):
|
||||
self.additionalMixedPinnedItemIds.insert(peerId)
|
||||
}
|
||||
}
|
||||
}
|
||||
for peerId in self.additionalMixedItemIds {
|
||||
if let entry = postbox.chatListTable.getEntry(peerId: peerId, messageHistoryTable: postbox.messageHistoryTable, peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable) {
|
||||
self.additionalMixedItemEntries.append(MutableChatListEntry(entry, cachedDataTable: postbox.cachedPeerDataTable, readStateTable: postbox.readStateTable, messageHistoryTable: postbox.messageHistoryTable))
|
||||
}
|
||||
}
|
||||
for peerId in self.additionalMixedPinnedItemIds {
|
||||
if let entry = postbox.chatListTable.getEntry(peerId: peerId, messageHistoryTable: postbox.messageHistoryTable, peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable) {
|
||||
self.additionalMixedPinnedEntries.append(MutableChatListEntry(entry, cachedDataTable: postbox.cachedPeerDataTable, readStateTable: postbox.readStateTable, messageHistoryTable: postbox.messageHistoryTable))
|
||||
spaces.append(.group(groupId: self.groupId, pinned: .includePinnedAsUnpinned))
|
||||
for additionalGroupId in filterPredicate.includeAdditionalPeerGroupIds {
|
||||
spaces.append(.group(groupId: additionalGroupId, pinned: .notPinned))
|
||||
spaces.append(.group(groupId: additionalGroupId, pinned: .includePinnedAsUnpinned))
|
||||
}
|
||||
} else {
|
||||
spaces.append(.group(groupId: self.groupId, pinned: .includePinned))
|
||||
}
|
||||
self.spaces = spaces
|
||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: aroundIndex, filterPredicate: self.filterPredicate, summaryComponents: self.summaryComponents, halfLimit: count)
|
||||
self.sampledState = self.state.sample(postbox: postbox)
|
||||
|
||||
self.count = count
|
||||
|
||||
if case .root = groupId, self.filterPredicate == nil {
|
||||
let itemIds = postbox.additionalChatListItemsTable.get()
|
||||
/*let itemIds = postbox.additionalChatListItemsTable.get()
|
||||
self.additionalItemIds = Set(itemIds)
|
||||
for peerId in itemIds {
|
||||
if let entry = postbox.chatListTable.getStandalone(peerId: peerId, messageHistoryTable: postbox.messageHistoryTable) {
|
||||
self.additionalItemEntries.append(MutableChatListEntry(entry, cachedDataTable: postbox.cachedPeerDataTable, readStateTable: postbox.readStateTable, messageHistoryTable: postbox.messageHistoryTable))
|
||||
}
|
||||
}
|
||||
}*/
|
||||
self.groupEntries = []
|
||||
self.reloadGroups(postbox: postbox)
|
||||
} else {
|
||||
self.additionalItemIds = Set()
|
||||
//self.additionalItemIds = Set()
|
||||
self.groupEntries = []
|
||||
}
|
||||
}
|
||||
@@ -456,87 +403,31 @@ final class MutableChatListView {
|
||||
}
|
||||
|
||||
func refreshDueToExternalTransaction(postbox: Postbox) -> Bool {
|
||||
var index = ChatListIndex.absoluteUpperBound
|
||||
if !self.entries.isEmpty && self.later != nil {
|
||||
index = self.entries[self.entries.count / 2].index
|
||||
}
|
||||
var updated = false
|
||||
|
||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: .absoluteUpperBound, filterPredicate: self.filterPredicate, summaryComponents: self.summaryComponents, halfLimit: self.count)
|
||||
self.sampledState = self.state.sample(postbox: postbox)
|
||||
updated = true
|
||||
|
||||
let (entries, earlier, later) = postbox.fetchAroundChatEntries(groupId: self.groupId, index: index, count: self.count, filterPredicate: self.filterPredicate)
|
||||
let currentGroupEntries = self.groupEntries
|
||||
|
||||
self.reloadGroups(postbox: postbox)
|
||||
|
||||
var updated = false
|
||||
|
||||
if self.groupEntries != currentGroupEntries {
|
||||
updated = true
|
||||
}
|
||||
|
||||
if entries != self.entries || earlier != self.earlier || later != self.later {
|
||||
self.entries = entries
|
||||
self.earlier = earlier
|
||||
self.later = later
|
||||
updated = true
|
||||
}
|
||||
|
||||
return updated
|
||||
}
|
||||
|
||||
func replay(postbox: Postbox, operations: [PeerGroupId: [ChatListOperation]], updatedPeerNotificationSettings: [PeerId: (PeerNotificationSettings?, PeerNotificationSettings)], updatedPeers: [PeerId: Peer], updatedPeerPresences: [PeerId: PeerPresence], transaction: PostboxTransaction, context: MutableChatListViewReplayContext) -> Bool {
|
||||
var hasChanges = false
|
||||
|
||||
if let groupOperations = operations[self.groupId] {
|
||||
for operation in groupOperations {
|
||||
switch operation {
|
||||
case let .InsertEntry(index, message, combinedReadState, embeddedState):
|
||||
if self.add(.IntermediateMessageEntry(index, message, combinedReadState, embeddedState), postbox: postbox) {
|
||||
hasChanges = true
|
||||
}
|
||||
case let .InsertHole(index):
|
||||
if self.add(.HoleEntry(index), postbox: postbox) {
|
||||
hasChanges = true
|
||||
}
|
||||
case let .RemoveEntry(indices):
|
||||
if self.remove(Set(indices), type: .message, context: context) {
|
||||
hasChanges = true
|
||||
}
|
||||
case let .RemoveHoles(indices):
|
||||
if self.remove(Set(indices), type: .hole, context: context) {
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.state.replay(postbox: postbox, transaction: transaction) {
|
||||
self.sampledState = self.state.sample(postbox: postbox)
|
||||
hasChanges = true
|
||||
}
|
||||
|
||||
/*if let filterPredicate = self.filterPredicate, !filterPredicate.includePeerIds.isEmpty {
|
||||
for (groupId, groupOperations) in operations {
|
||||
if groupId == self.groupId {
|
||||
continue
|
||||
}
|
||||
for operation in groupOperations {
|
||||
switch operation {
|
||||
case let .InsertEntry(index, message, combinedReadState, embeddedState):
|
||||
if filterPredicate.includePeerIds.contains(index.messageIndex.id.peerId) {
|
||||
if self.add(.IntermediateMessageEntry(index, message, combinedReadState, embeddedState), postbox: postbox) {
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
case .InsertHole:
|
||||
break
|
||||
case let .RemoveEntry(indices):
|
||||
let updatedIndices = indices.filter { index in
|
||||
return filterPredicate.includePeerIds.contains(index.messageIndex.id.peerId)
|
||||
}
|
||||
if !updatedIndices.isEmpty && self.remove(Set(updatedIndices), type: .message, context: context) {
|
||||
hasChanges = true
|
||||
}
|
||||
case .RemoveHoles:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if case .root = self.groupId, self.filterPredicate == nil {
|
||||
var invalidatedGroups = false
|
||||
for (groupId, groupOperations) in operations {
|
||||
@@ -573,184 +464,9 @@ final class MutableChatListView {
|
||||
}
|
||||
}
|
||||
|
||||
if !updatedPeerNotificationSettings.isEmpty {
|
||||
if let filterPredicate = self.filterPredicate {
|
||||
for (peerId, settingsChange) in updatedPeerNotificationSettings {
|
||||
if let peer = postbox.peerTable.get(peerId), !self.additionalMixedItemIds.contains(peerId), !self.additionalMixedPinnedItemIds.contains(peerId) {
|
||||
let isUnread = postbox.readStateTable.getCombinedState(peerId)?.isUnread ?? false
|
||||
let wasIncluded = filterPredicate.includes(peer: peer, notificationSettings: settingsChange.0, isUnread: isUnread, isContact: postbox.contactsTable.isContact(peerId: peerId), isArchived: false)
|
||||
let isIncluded = filterPredicate.includes(peer: peer, notificationSettings: settingsChange.1, isUnread: isUnread, isContact: postbox.contactsTable.isContact(peerId: peerId), isArchived: false)
|
||||
if wasIncluded != isIncluded {
|
||||
if isIncluded {
|
||||
let tableEntry: ChatListIntermediateEntry?
|
||||
if filterPredicate.includePeerIds.contains(peerId) {
|
||||
tableEntry = postbox.chatListTable.getEntry(peerId: peerId, messageHistoryTable: postbox.messageHistoryTable, peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable)
|
||||
} else {
|
||||
tableEntry = postbox.chatListTable.getEntry(groupId: self.groupId, peerId: peerId, messageHistoryTable: postbox.messageHistoryTable, peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable)
|
||||
}
|
||||
if let entry = tableEntry {
|
||||
switch entry {
|
||||
case let .message(index, message, embeddedState):
|
||||
let combinedReadState = postbox.readStateTable.getCombinedState(index.messageIndex.id.peerId)
|
||||
if self.add(.IntermediateMessageEntry(entry.index, message, combinedReadState, embeddedState), postbox: postbox) {
|
||||
hasChanges = true
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
loop: for i in 0 ..< self.entries.count {
|
||||
switch self.entries[i] {
|
||||
case .MessageEntry(let index, _, _, _, _, _, _, _, _, _), .IntermediateMessageEntry(let index, _, _, _):
|
||||
if index.messageIndex.id.peerId == peerId {
|
||||
self.entries.remove(at: i)
|
||||
hasChanges = true
|
||||
break loop
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0 ..< self.entries.count {
|
||||
switch self.entries[i] {
|
||||
case let .MessageEntry(index, message, readState, _, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact):
|
||||
var notificationSettingsPeerId = peer.peerId
|
||||
if let peer = peer.peers[peer.peerId], let associatedPeerId = peer.associatedPeerId {
|
||||
notificationSettingsPeerId = associatedPeerId
|
||||
}
|
||||
if let (_, settings) = updatedPeerNotificationSettings[notificationSettingsPeerId] {
|
||||
self.entries[i] = .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact)
|
||||
hasChanges = true
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0 ..< self.additionalMixedItemEntries.count {
|
||||
switch self.additionalMixedItemEntries[i] {
|
||||
case let .MessageEntry(index, message, readState, _, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact):
|
||||
var notificationSettingsPeerId = peer.peerId
|
||||
if let peer = peer.peers[peer.peerId], let associatedPeerId = peer.associatedPeerId {
|
||||
notificationSettingsPeerId = associatedPeerId
|
||||
}
|
||||
if let (_, settings) = updatedPeerNotificationSettings[notificationSettingsPeerId] {
|
||||
self.additionalMixedItemEntries[i] = .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact)
|
||||
hasChanges = true
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0 ..< self.additionalMixedPinnedEntries.count {
|
||||
switch self.additionalMixedPinnedEntries[i] {
|
||||
case let .MessageEntry(index, message, readState, _, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact):
|
||||
var notificationSettingsPeerId = peer.peerId
|
||||
if let peer = peer.peers[peer.peerId], let associatedPeerId = peer.associatedPeerId {
|
||||
notificationSettingsPeerId = associatedPeerId
|
||||
}
|
||||
if let (_, settings) = updatedPeerNotificationSettings[notificationSettingsPeerId] {
|
||||
self.additionalMixedPinnedEntries[i] = .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact)
|
||||
hasChanges = true
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
if !transaction.updatedFailedMessagePeerIds.isEmpty {
|
||||
for i in 0 ..< self.entries.count {
|
||||
switch self.entries[i] {
|
||||
case let .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, summaryInfo, previousHasFailed, isContact):
|
||||
if transaction.updatedFailedMessagePeerIds.contains(index.messageIndex.id.peerId) {
|
||||
let hasFailed = postbox.messageHistoryFailedTable.contains(peerId: index.messageIndex.id.peerId)
|
||||
if previousHasFailed != hasFailed {
|
||||
self.entries[i] = .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact)
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !updatedPeers.isEmpty {
|
||||
for i in 0 ..< self.entries.count {
|
||||
switch self.entries[i] {
|
||||
case let .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact):
|
||||
var updatedMessage: Message?
|
||||
if let message = message {
|
||||
updatedMessage = updateMessagePeers(message, updatedPeers: updatedPeers)
|
||||
}
|
||||
let updatedPeer = updatedRenderedPeer(peer, updatedPeers: updatedPeers)
|
||||
if updatedMessage != nil || updatedPeer != nil {
|
||||
self.entries[i] = .MessageEntry(index, updatedMessage ?? message, readState, settings, embeddedState, updatedPeer ?? peer, peerPresence, summaryInfo, hasFailed, isContact)
|
||||
hasChanges = true
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if !updatedPeerPresences.isEmpty {
|
||||
for i in 0 ..< self.entries.count {
|
||||
switch self.entries[i] {
|
||||
case let .MessageEntry(index, message, readState, settings, embeddedState, peer, _, summaryInfo, hasFailed, isContact):
|
||||
var presencePeerId = peer.peerId
|
||||
if let peer = peer.peers[peer.peerId], let associatedPeerId = peer.associatedPeerId {
|
||||
presencePeerId = associatedPeerId
|
||||
}
|
||||
if let presence = updatedPeerPresences[presencePeerId] {
|
||||
self.entries[i] = .MessageEntry(index, message, readState, settings, embeddedState, peer, presence, summaryInfo, hasFailed, isContact)
|
||||
hasChanges = true
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if !transaction.currentUpdatedMessageTagSummaries.isEmpty || !transaction.currentUpdatedMessageActionsSummaries.isEmpty {
|
||||
for i in 0 ..< self.entries.count {
|
||||
switch self.entries[i] {
|
||||
case let .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, currentSummary, hasFailed, isContact):
|
||||
var updatedTagSummaryCount: Int32?
|
||||
var updatedActionsSummaryCount: Int32?
|
||||
|
||||
if let tagSummary = self.summaryComponents.tagSummary {
|
||||
let key = MessageHistoryTagsSummaryKey(tag: tagSummary.tag, peerId: index.messageIndex.id.peerId, namespace: tagSummary.namespace)
|
||||
if let summary = transaction.currentUpdatedMessageTagSummaries[key] {
|
||||
updatedTagSummaryCount = summary.count
|
||||
}
|
||||
}
|
||||
|
||||
if let actionsSummary = self.summaryComponents.actionsSummary {
|
||||
let key = PendingMessageActionsSummaryKey(type: actionsSummary.type, peerId: index.messageIndex.id.peerId, namespace: actionsSummary.namespace)
|
||||
if let count = transaction.currentUpdatedMessageActionsSummaries[key] {
|
||||
updatedActionsSummaryCount = count
|
||||
}
|
||||
}
|
||||
|
||||
if updatedTagSummaryCount != nil || updatedActionsSummaryCount != nil {
|
||||
let summaryInfo = ChatListMessageTagSummaryInfo(tagSummaryCount: updatedTagSummaryCount ?? currentSummary.tagSummaryCount, actionsSummaryCount: updatedActionsSummaryCount ?? currentSummary.actionsSummaryCount)
|
||||
|
||||
self.entries[i] = .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact)
|
||||
hasChanges = true
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
var updateAdditionalItems = false
|
||||
if let itemIds = transaction.replacedAdditionalChatListItems {
|
||||
self.additionalItemIds = Set(itemIds)
|
||||
@@ -803,228 +519,24 @@ final class MutableChatListView {
|
||||
}
|
||||
|
||||
hasChanges = true
|
||||
}
|
||||
return hasChanges
|
||||
}
|
||||
|
||||
func add(_ initialEntry: MutableChatListEntry, postbox: Postbox) -> Bool {
|
||||
if let filterPredicate = self.filterPredicate {
|
||||
switch initialEntry {
|
||||
case .IntermediateMessageEntry(let index, _, _, _), .MessageEntry(let index, _, _, _, _, _, _, _, _, _):
|
||||
if let peer = postbox.peerTable.get(index.messageIndex.id.peerId) {
|
||||
let isUnread = postbox.readStateTable.getCombinedState(index.messageIndex.id.peerId)?.isUnread ?? false
|
||||
let isContact = postbox.contactsTable.isContact(peerId: peer.id)
|
||||
if !filterPredicate.includes(peer: peer, notificationSettings: postbox.peerNotificationSettingsTable.getEffective(index.messageIndex.id.peerId), isUnread: isUnread, isContact: isContact, isArchived: false) {
|
||||
return false
|
||||
}
|
||||
if self.additionalMixedItemIds.contains(peer.id) {
|
||||
return false
|
||||
}
|
||||
if self.additionalMixedPinnedItemIds.contains(peer.id) {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
let entry = processedChatListEntry(initialEntry, cachedDataTable: postbox.cachedPeerDataTable, readStateTable: postbox.readStateTable, messageHistoryTable: postbox.messageHistoryTable)
|
||||
|
||||
if self.entries.count == 0 {
|
||||
self.entries.append(entry)
|
||||
return true
|
||||
} else {
|
||||
let first = self.entries[self.entries.count - 1]
|
||||
let last = self.entries[0]
|
||||
|
||||
let next = self.later
|
||||
|
||||
if entry.index < last.index {
|
||||
if self.earlier == nil || self.earlier!.index < entry.index {
|
||||
if self.entries.count < self.count {
|
||||
self.entries.insert(entry, at: 0)
|
||||
} else {
|
||||
self.earlier = entry
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else if entry.index > first.index {
|
||||
if next != nil && entry.index > next!.index {
|
||||
if self.later == nil || self.later!.index > entry.index {
|
||||
if self.entries.count < self.count {
|
||||
self.entries.append(entry)
|
||||
} else {
|
||||
self.later = entry
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
self.entries.append(entry)
|
||||
if self.entries.count > self.count {
|
||||
self.earlier = self.entries[0]
|
||||
self.entries.remove(at: 0)
|
||||
}
|
||||
return true
|
||||
}
|
||||
} else if entry != last && entry != first {
|
||||
var i = self.entries.count
|
||||
while i >= 1 {
|
||||
if self.entries[i - 1].index < entry.index {
|
||||
break
|
||||
}
|
||||
i -= 1
|
||||
}
|
||||
self.entries.insert(entry, at: i)
|
||||
if self.entries.count > self.count {
|
||||
self.earlier = self.entries[0]
|
||||
self.entries.remove(at: 0)
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func remove(_ indices: Set<ChatListIndex>, type: ChatListEntryType, context: MutableChatListViewReplayContext) -> Bool {
|
||||
var hasChanges = false
|
||||
if let earlier = self.earlier, indices.contains(earlier.index) {
|
||||
var match = false
|
||||
switch earlier {
|
||||
case .HoleEntry:
|
||||
match = type == .hole
|
||||
case .IntermediateMessageEntry, .MessageEntry:
|
||||
match = type == .message
|
||||
/*case .IntermediateGroupReferenceEntry, .GroupReferenceEntry:
|
||||
match = type == .groupReference*/
|
||||
}
|
||||
if match {
|
||||
context.invalidEarlier = true
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
|
||||
if let later = self.later, indices.contains(later.index) {
|
||||
var match = false
|
||||
switch later {
|
||||
case .HoleEntry:
|
||||
match = type == .hole
|
||||
case .IntermediateMessageEntry, .MessageEntry:
|
||||
match = type == .message
|
||||
/*case .IntermediateGroupReferenceEntry, .GroupReferenceEntry:
|
||||
match = type == .groupReference*/
|
||||
}
|
||||
if match {
|
||||
context.invalidLater = true
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
|
||||
if self.entries.count != 0 {
|
||||
var i = self.entries.count - 1
|
||||
while i >= 0 {
|
||||
if indices.contains(self.entries[i].index) {
|
||||
var match = false
|
||||
switch self.entries[i] {
|
||||
case .HoleEntry:
|
||||
match = type == .hole
|
||||
case .IntermediateMessageEntry, .MessageEntry:
|
||||
match = type == .message
|
||||
/*case .IntermediateGroupReferenceEntry, .GroupReferenceEntry:
|
||||
match = type == .groupReference*/
|
||||
}
|
||||
if match {
|
||||
self.entries.remove(at: i)
|
||||
context.removedEntries = true
|
||||
hasChanges = true
|
||||
}
|
||||
}
|
||||
i -= 1
|
||||
}
|
||||
}
|
||||
|
||||
}*/
|
||||
return hasChanges
|
||||
}
|
||||
|
||||
func complete(postbox: Postbox, context: MutableChatListViewReplayContext) {
|
||||
if context.removedEntries {
|
||||
var index = ChatListIndex.absoluteUpperBound
|
||||
if !self.entries.isEmpty && self.later != nil {
|
||||
index = self.entries[self.entries.count / 2].index
|
||||
}
|
||||
|
||||
let (entries, earlier, later) = postbox.fetchAroundChatEntries(groupId: self.groupId, index: index, count: self.count, filterPredicate: self.filterPredicate)
|
||||
var previousEntryByPeerId: [PeerId: MutableChatListEntry] = [:]
|
||||
for entry in self.entries {
|
||||
switch entry {
|
||||
case let .MessageEntry(messageEntry):
|
||||
previousEntryByPeerId[messageEntry.0.messageIndex.id.peerId] = entry
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
self.entries = entries
|
||||
for i in 0 ..< self.entries.count {
|
||||
switch self.entries[i] {
|
||||
case let .MessageEntry(messageEntry):
|
||||
if let previousEntry = previousEntryByPeerId[messageEntry.0.messageIndex.id.peerId] {
|
||||
self.entries[i] = previousEntry
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
self.earlier = earlier
|
||||
self.later = later
|
||||
} else {
|
||||
if context.invalidEarlier {
|
||||
var earlyId: ChatListIndex?
|
||||
let i = 0
|
||||
if i < self.entries.count {
|
||||
earlyId = self.entries[i].index
|
||||
}
|
||||
|
||||
let earlierEntries = postbox.fetchEarlierChatEntries(groupId: self.groupId, index: earlyId, count: 1, filterPredicate: self.filterPredicate)
|
||||
self.earlier = earlierEntries.first
|
||||
}
|
||||
|
||||
if context.invalidLater {
|
||||
var laterId: ChatListIndex?
|
||||
let i = self.entries.count - 1
|
||||
if i >= 0 {
|
||||
laterId = self.entries[i].index
|
||||
}
|
||||
|
||||
let laterEntries = postbox.fetchLaterChatEntries(groupId: self.groupId, index: laterId, count: 1, filterPredicate: self.filterPredicate)
|
||||
self.later = laterEntries.first
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func firstHole() -> ChatListHole? {
|
||||
for entry in self.entries {
|
||||
if case let .HoleEntry(hole) = entry {
|
||||
return hole
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return self.sampledState.hole
|
||||
}
|
||||
|
||||
private func renderEntry(_ entry: MutableChatListEntry, postbox: Postbox, renderMessage: (IntermediateMessage) -> Message, getPeer: (PeerId) -> Peer?, getPeerNotificationSettings: (PeerId) -> PeerNotificationSettings?, getPeerPresence: (PeerId) -> PeerPresence?) -> MutableChatListEntry? {
|
||||
/*private func renderEntry(_ entry: MutableChatListEntry, postbox: Postbox, renderMessage: (IntermediateMessage) -> Message, getPeer: (PeerId) -> Peer?, getPeerNotificationSettings: (PeerId) -> PeerNotificationSettings?, getPeerPresence: (PeerId) -> PeerPresence?) -> MutableChatListEntry? {
|
||||
switch entry {
|
||||
case let .IntermediateMessageEntry(index, message, combinedReadState, embeddedState):
|
||||
case let .IntermediateMessageEntry(index, messageIndex):
|
||||
let renderedMessage: Message?
|
||||
if let message = message {
|
||||
renderedMessage = renderMessage(message)
|
||||
if let messageIndex = messageIndex {
|
||||
renderedMessage = postbox.messageHistoryTable.getMessage(messageIndex).flatMap(renderMessage)
|
||||
} else {
|
||||
renderedMessage = nil
|
||||
}
|
||||
@@ -1063,14 +575,14 @@ final class MutableChatListView {
|
||||
actionsSummaryCount = postbox.pendingMessageActionsMetadataTable.getCount(.peerNamespaceAction(key.peerId, key.namespace, key.type))
|
||||
}
|
||||
|
||||
return .MessageEntry(index, renderedMessage, combinedReadState, notificationSettings, embeddedState, RenderedPeer(peerId: index.messageIndex.id.peerId, peers: peers), presence, ChatListMessageTagSummaryInfo(tagSummaryCount: tagSummaryCount, actionsSummaryCount: actionsSummaryCount), postbox.messageHistoryFailedTable.contains(peerId: index.messageIndex.id.peerId), isContact)
|
||||
return .MessageEntry(index: index, message: renderedMessage, readState: postbox.readStateTable.getCombinedState(index.messageIndex.id.peerId), notificationSettings: notificationSettings, embeddedInterfaceState: postbox.peerChatInterfaceStateTable.get(index.messageIndex.id.peerId)?.chatListEmbeddedState, renderedPeer: RenderedPeer(peerId: index.messageIndex.id.peerId, peers: peers), presence: presence, tagSummaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: tagSummaryCount, actionsSummaryCount: actionsSummaryCount), hasFailedMessages: postbox.messageHistoryFailedTable.contains(peerId: index.messageIndex.id.peerId), isContact: isContact)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
func render(postbox: Postbox, renderMessage: (IntermediateMessage) -> Message, getPeer: (PeerId) -> Peer?, getPeerNotificationSettings: (PeerId) -> PeerNotificationSettings?, getPeerPresence: (PeerId) -> PeerPresence?) {
|
||||
for i in 0 ..< self.entries.count {
|
||||
/*for i in 0 ..< self.entries.count {
|
||||
if let updatedEntry = self.renderEntry(self.entries[i], postbox: postbox, renderMessage: renderMessage, getPeer: getPeer, getPeerNotificationSettings: getPeerNotificationSettings, getPeerPresence: getPeerPresence) {
|
||||
self.entries[i] = updatedEntry
|
||||
}
|
||||
@@ -1089,7 +601,7 @@ final class MutableChatListView {
|
||||
if let updatedEntry = self.renderEntry(self.additionalMixedPinnedEntries[i], postbox: postbox, renderMessage: renderMessage, getPeer: getPeer, getPeerNotificationSettings: getPeerNotificationSettings, getPeerPresence: getPeerPresence) {
|
||||
self.additionalMixedPinnedEntries[i] = updatedEntry
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1105,7 +617,7 @@ public final class ChatListView {
|
||||
self.groupId = mutableView.groupId
|
||||
|
||||
var entries: [ChatListEntry] = []
|
||||
for entry in mutableView.entries {
|
||||
for entry in mutableView.sampledState.entries {
|
||||
switch entry {
|
||||
case let .MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact):
|
||||
entries.append(.MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact))
|
||||
@@ -1115,7 +627,7 @@ public final class ChatListView {
|
||||
assertionFailure()
|
||||
}
|
||||
}
|
||||
if !mutableView.additionalMixedItemEntries.isEmpty || !mutableView.additionalMixedPinnedEntries.isEmpty {
|
||||
/*if !mutableView.additionalMixedItemEntries.isEmpty || !mutableView.additionalMixedPinnedEntries.isEmpty {
|
||||
var existingIds = Set<PeerId>()
|
||||
for entry in entries {
|
||||
if case let .MessageEntry(messageEntry) = entry {
|
||||
@@ -1161,14 +673,15 @@ public final class ChatListView {
|
||||
}
|
||||
}
|
||||
entries.sort()
|
||||
}
|
||||
self.groupEntries = mutableView.groupEntries
|
||||
}*/
|
||||
self.entries = entries
|
||||
self.earlierIndex = mutableView.earlier?.index
|
||||
self.laterIndex = mutableView.later?.index
|
||||
self.earlierIndex = mutableView.sampledState.lower?.index
|
||||
self.laterIndex = mutableView.sampledState.upper?.index
|
||||
|
||||
self.groupEntries = mutableView.groupEntries
|
||||
|
||||
var additionalItemEntries: [ChatListEntry] = []
|
||||
for entry in mutableView.additionalItemEntries {
|
||||
/*for entry in mutableView.additionalItemEntries {
|
||||
switch entry {
|
||||
case let .MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact):
|
||||
additionalItemEntries.append(.MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact))
|
||||
@@ -1177,7 +690,7 @@ public final class ChatListView {
|
||||
case .IntermediateMessageEntry:
|
||||
assertionFailure()
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
self.additionalItemEntries = additionalItemEntries
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user