ChatListView: add message and unread states to group reference

Cleanup
This commit is contained in:
Peter
2019-05-03 17:57:15 +04:00
parent daf454401d
commit 80a7d4e524
7 changed files with 116 additions and 39 deletions

View File

@@ -10,7 +10,6 @@ enum ChatListOperation {
enum ChatListEntryInfo {
case message(ChatListIndex, MessageIndex?)
case hole(ChatListHole)
case groupReference(PeerGroupId, ChatListIndex)
var index: ChatListIndex {
switch self {
@@ -18,8 +17,6 @@ enum ChatListEntryInfo {
return index
case let .hole(hole):
return ChatListIndex(pinningIndex: nil, messageIndex: hole.index)
case let .groupReference(_, index):
return index
}
}
}
@@ -27,7 +24,6 @@ enum ChatListEntryInfo {
enum ChatListIntermediateEntry {
case message(ChatListIndex, IntermediateMessage?, PeerChatListEmbeddedInterfaceState?)
case hole(ChatListHole)
//case groupReference(PeerGroupId, ChatListIndex)
var index: ChatListIndex {
switch self {
@@ -35,8 +31,6 @@ enum ChatListIntermediateEntry {
return index
case let .hole(hole):
return ChatListIndex(pinningIndex: nil, messageIndex: hole.index)
/*case let .groupReference(_, index):
return index*/
}
}
}
@@ -538,6 +532,42 @@ final class ChatListTable: Table {
return entries
}
func earlierEntryInfos(groupId: PeerGroupId, index: (ChatListIndex, Bool)?, messageHistoryTable: MessageHistoryTable, peerChatInterfaceStateTable: PeerChatInterfaceStateTable, count: Int) -> [ChatListEntryInfo] {
self.ensureInitialized(groupId: groupId)
var entries: [ChatListEntryInfo] = []
let key: ValueBoxKey
if let (index, message) = index {
key = self.key(groupId: groupId, index: index, type: message ? .message : .hole)
} else {
key = self.upperBound(groupId: groupId)
}
self.valueBox.range(self.table, start: key, end: self.lowerBound(groupId: groupId), values: { key, value in
let (keyGroupId, pinningIndex, messageIndex, type) = extractKey(key)
assert(groupId == keyGroupId)
let index = ChatListIndex(pinningIndex: pinningIndex, messageIndex: messageIndex)
if type == ChatListEntryType.message.rawValue {
var messageIndex: MessageIndex?
if value.length != 0 {
var idNamespace: Int32 = 0
value.read(&idNamespace, offset: 0, length: 4)
var idId: Int32 = 0
value.read(&idId, offset: 0, length: 4)
var indexTimestamp: Int32 = 0
value.read(&indexTimestamp, offset: 0, length: 4)
messageIndex = MessageIndex(id: MessageId(peerId: index.messageIndex.id.peerId, namespace: idNamespace, id: idId), timestamp: indexTimestamp)
}
entries.append(.message(index, messageIndex))
} else if type == ChatListEntryType.hole.rawValue {
entries.append(.hole(ChatListHole(index: index.messageIndex)))
}
return true
}, limit: count)
return entries
}
func laterEntries(groupId: PeerGroupId, index: (ChatListIndex, Bool)?, messageHistoryTable: MessageHistoryTable, peerChatInterfaceStateTable: PeerChatInterfaceStateTable, count: Int) -> [ChatListIntermediateEntry] {
self.ensureInitialized(groupId: groupId)

View File

@@ -44,9 +44,30 @@ public struct ChatListMessageTagSummaryInfo: Equatable {
}
}
public final class ChatListGroupReferencePeer: Equatable {
public let peer: RenderedPeer
public let isUnread: Bool
init(peer: RenderedPeer, isUnread: Bool) {
self.peer = peer
self.isUnread = isUnread
}
public static func ==(lhs: ChatListGroupReferencePeer, rhs: ChatListGroupReferencePeer) -> Bool {
if lhs.peer != rhs.peer {
return false
}
if lhs.isUnread != rhs.isUnread {
return false
}
return true
}
}
public struct ChatListGroupReferenceEntry: Equatable {
public let groupId: PeerGroupId
public let renderedPeers: [RenderedPeer]
public let message: Message?
public let renderedPeers: [ChatListGroupReferencePeer]
public let unreadState: PeerGroupUnreadCountersCombinedSummary
public static func ==(lhs: ChatListGroupReferenceEntry, rhs: ChatListGroupReferenceEntry) -> Bool {
@@ -56,6 +77,9 @@ public struct ChatListGroupReferenceEntry: Equatable {
if lhs.unreadState != rhs.unreadState {
return false
}
if lhs.message?.stableVersion != rhs.message?.stableVersion {
return false
}
if lhs.renderedPeers != rhs.renderedPeers {
return false
}
@@ -63,7 +87,7 @@ public struct ChatListGroupReferenceEntry: Equatable {
}
}
public indirect enum ChatListEntry: Comparable {
public enum ChatListEntry: Comparable {
case MessageEntry(ChatListIndex, Message?, CombinedPeerReadState?, PeerNotificationSettings?, PeerChatListEmbeddedInterfaceState?, RenderedPeer, PeerPresence?, ChatListMessageTagSummaryInfo)
case HoleEntry(ChatListHole)
@@ -152,7 +176,7 @@ private func processedChatListEntry(_ entry: MutableChatListEntry, cachedDataTab
}
}
indirect enum MutableChatListEntry: Equatable {
enum MutableChatListEntry: Equatable {
case IntermediateMessageEntry(ChatListIndex, IntermediateMessage?, CombinedPeerReadState?, PeerChatListEmbeddedInterfaceState?)
case MessageEntry(ChatListIndex, Message?, CombinedPeerReadState?, PeerNotificationSettings?, PeerChatListEmbeddedInterfaceState?, RenderedPeer, PeerPresence?, ChatListMessageTagSummaryInfo)
case HoleEntry(ChatListHole)
@@ -307,43 +331,45 @@ final class MutableChatListView {
self.groupEntries.removeAll()
if case .root = self.groupId {
for groupId in postbox.chatListTable.existingGroups() {
var foundIndices: [ChatListIndex] = []
var foundIndices: [(ChatListIndex, MessageIndex)] = []
var unpinnedCount = 0
let maxCount = 8
var upperBound: (ChatListIndex, Bool)?
inner: while true {
if let entry = postbox.chatListTable.earlierEntries(groupId: groupId, index: upperBound, messageHistoryTable: postbox.messageHistoryTable, peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: 1).first {
if case let .message(index, maybeMessage, _) = entry {
foundIndices.append(index)
if index.pinningIndex == nil {
unpinnedCount += 1
}
if unpinnedCount >= maxCount {
break inner
}
if let _ = maybeMessage {
upperBound = (entry.index, true)
} else {
upperBound = (entry.index.predecessor, true)
}
} else {
upperBound = (entry.index, false)
if let entry = postbox.chatListTable.earlierEntryInfos(groupId: groupId, index: upperBound, messageHistoryTable: postbox.messageHistoryTable, peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: 1).first {
switch entry {
case let .message(index, messageIndex):
if let messageIndex = messageIndex {
foundIndices.append((index, messageIndex))
if index.pinningIndex == nil {
unpinnedCount += 1
}
if unpinnedCount >= maxCount {
break inner
}
upperBound = (entry.index, true)
} else {
upperBound = (entry.index.predecessor, true)
}
case .hole:
upperBound = (entry.index, false)
}
} else {
break inner
}
}
foundIndices.sort(by: { $0.messageIndex > $1.messageIndex })
foundIndices.sort(by: { $0.1 > $1.1 })
if foundIndices.count > maxCount {
foundIndices.removeSubrange(maxCount...)
}
var renderedPeers: [RenderedPeer] = []
for index in foundIndices {
var message: Message?
var renderedPeers: [ChatListGroupReferencePeer] = []
for (index, messageIndex) in foundIndices {
if let peer = postbox.peerTable.get(index.messageIndex.id.peerId) {
var peers = SimpleDictionary<PeerId, Peer>()
peers[peer.id] = peer
@@ -354,11 +380,16 @@ final class MutableChatListView {
}
let renderedPeer = RenderedPeer(peerId: peer.id, peers: peers)
renderedPeers.append(renderedPeer)
let isUnread = postbox.readStateTable.getCombinedState(peer.id)?.isUnread ?? false
renderedPeers.append(ChatListGroupReferencePeer(peer: renderedPeer, isUnread: isUnread))
if foundIndices.count == 1 && message == nil {
message = postbox.messageHistoryTable.getMessage(messageIndex).flatMap({ postbox.messageHistoryTable.renderMessage($0, peerTable: postbox.peerTable) })
}
}
}
self.groupEntries.append(ChatListGroupReferenceEntry(groupId: groupId, renderedPeers: renderedPeers, unreadState: postbox.groupMessageStatsTable.get(groupId: groupId)))
self.groupEntries.append(ChatListGroupReferenceEntry(groupId: groupId, message: message, renderedPeers: renderedPeers, unreadState: postbox.groupMessageStatsTable.get(groupId: groupId)))
}
}
}
@@ -423,16 +454,32 @@ final class MutableChatListView {
invalidatedGroups = true
}
}
if invalidatedGroups {
self.reloadGroups(postbox: postbox)
hasChanges = true
} else {
for i in 0 ..< self.groupEntries.count {
if let updatedState = transaction.currentUpdatedTotalUnreadSummaries[self.groupEntries[i].groupId] {
self.groupEntries[i] = ChatListGroupReferenceEntry(groupId: self.groupEntries[i].groupId, renderedPeers: self.groupEntries[i].renderedPeers, unreadState: updatedState)
self.groupEntries[i] = ChatListGroupReferenceEntry(groupId: self.groupEntries[i].groupId, message: self.groupEntries[i].message, renderedPeers: self.groupEntries[i].renderedPeers, unreadState: updatedState)
hasChanges = true
}
}
if !transaction.alteredInitialPeerCombinedReadStates.isEmpty {
for i in 0 ..< self.groupEntries.count {
for j in 0 ..< groupEntries[i].renderedPeers.count {
if transaction.alteredInitialPeerCombinedReadStates[groupEntries[i].renderedPeers[j].peer.peerId] != nil {
let isUnread = postbox.readStateTable.getCombinedState(groupEntries[i].renderedPeers[j].peer.peerId)?.isUnread ?? false
if isUnread != groupEntries[i].renderedPeers[j].isUnread {
var renderedPeers = self.groupEntries[i].renderedPeers
renderedPeers[j] = ChatListGroupReferencePeer(peer: groupEntries[i].renderedPeers[j].peer, isUnread: isUnread)
self.groupEntries[i] = ChatListGroupReferenceEntry(groupId: self.groupEntries[i].groupId, message: self.groupEntries[i].message, renderedPeers: renderedPeers, unreadState: self.groupEntries[i].unreadState)
}
}
}
}
}
}
}

View File

@@ -100,7 +100,7 @@ public protocol ItemCollectionItem: PostboxCoding {
var indexKeys: [MemoryBuffer] { get }
}
public indirect enum ItemCollectionSearchQuery {
public enum ItemCollectionSearchQuery {
case exact(ValueBoxKey)
case matching([ValueBoxKey])
}

View File

@@ -1,6 +1,6 @@
import Foundation
public indirect enum PeerIndexNameRepresentation: Equatable {
public enum PeerIndexNameRepresentation: Equatable {
case title(title: String, addressName: String?)
case personName(first: String, last: String, addressName: String?, phoneNumber: String?)

View File

@@ -1,5 +1,5 @@
public indirect enum PeerNotificationSettingsBehavior: PostboxCoding {
public enum PeerNotificationSettingsBehavior: PostboxCoding {
case none
case reset(atTimestamp: Int32, toValue: PeerNotificationSettings)

View File

@@ -10,7 +10,7 @@ private enum MutableUnreadMessageCountsItemEntry {
case peer(PeerId, CombinedPeerReadState?)
}
public indirect enum UnreadMessageCountsItemEntry {
public enum UnreadMessageCountsItemEntry {
case total(PreferencesEntry?, ChatListTotalUnreadState)
case peer(PeerId, CombinedPeerReadState?)
}

View File

@@ -5,7 +5,7 @@ import SwiftSignalKitMac
import SwiftSignalKit
#endif
indirect enum PostboxUpgradeOperation {
enum PostboxUpgradeOperation {
case inplace((MetadataTable, ValueBox, (Float) -> Void) -> Void)
case standalone((Queue, String, ValueBox, ValueBoxEncryptionParameters, (Float) -> Void) -> String?)
}