ChatListView: added peer presences

This commit is contained in:
Ilya Laktyushin 2019-04-09 23:40:48 +04:00
parent 73d45d3c87
commit 97a3a77dff
3 changed files with 54 additions and 27 deletions

View File

@ -60,13 +60,13 @@ public struct ChatListMessageTagSummaryInfo: Equatable {
}*/ }*/
public enum ChatListEntry: Comparable { public enum ChatListEntry: Comparable {
case MessageEntry(ChatListIndex, Message?, CombinedPeerReadState?, PeerNotificationSettings?, PeerChatListEmbeddedInterfaceState?, RenderedPeer, ChatListMessageTagSummaryInfo) case MessageEntry(ChatListIndex, Message?, CombinedPeerReadState?, PeerNotificationSettings?, PeerChatListEmbeddedInterfaceState?, RenderedPeer, PeerPresence?, ChatListMessageTagSummaryInfo)
case HoleEntry(ChatListHole) case HoleEntry(ChatListHole)
//case GroupReferenceEntry(PeerGroupId, ChatListIndex, Message?, [Peer], GroupReferenceUnreadCounters) //case GroupReferenceEntry(PeerGroupId, ChatListIndex, Message?, [Peer], GroupReferenceUnreadCounters)
public var index: ChatListIndex { public var index: ChatListIndex {
switch self { switch self {
case let .MessageEntry(index, _, _, _, _, _, _): case let .MessageEntry(index, _, _, _, _, _, _, _):
return index return index
case let .HoleEntry(hole): case let .HoleEntry(hole):
return ChatListIndex(pinningIndex: nil, messageIndex: hole.index) return ChatListIndex(pinningIndex: nil, messageIndex: hole.index)
@ -77,9 +77,9 @@ public enum ChatListEntry: Comparable {
public static func ==(lhs: ChatListEntry, rhs: ChatListEntry) -> Bool { public static func ==(lhs: ChatListEntry, rhs: ChatListEntry) -> Bool {
switch lhs { switch lhs {
case let .MessageEntry(lhsIndex, lhsMessage, lhsReadState, lhsSettings, lhsEmbeddedState, lhsPeer, lhsInfo): case let .MessageEntry(lhsIndex, lhsMessage, lhsReadState, lhsSettings, lhsEmbeddedState, lhsPeer, lhsPresence, lhsInfo):
switch rhs { switch rhs {
case let .MessageEntry(rhsIndex, rhsMessage, rhsReadState, rhsSettings, rhsEmbeddedState, rhsPeer, rhsInfo): case let .MessageEntry(rhsIndex, rhsMessage, rhsReadState, rhsSettings, rhsEmbeddedState, rhsPeer, rhsPresence, rhsInfo):
if lhsIndex != rhsIndex { if lhsIndex != rhsIndex {
return false return false
} }
@ -106,6 +106,13 @@ public enum ChatListEntry: Comparable {
if lhsPeer != rhsPeer { if lhsPeer != rhsPeer {
return false return false
} }
if let lhsPresence = lhsPresence, let rhsPresence = rhsPresence {
if !lhsPresence.isEqual(to: rhsPresence) {
return false
}
} else if (lhsPresence != nil) != (rhsPresence != nil) {
return false
}
if lhsInfo != rhsInfo { if lhsInfo != rhsInfo {
return false return false
} }
@ -165,7 +172,7 @@ private func processedChatListEntry(_ entry: MutableChatListEntry, cachedDataTab
enum MutableChatListEntry: Equatable { enum MutableChatListEntry: Equatable {
case IntermediateMessageEntry(ChatListIndex, IntermediateMessage?, CombinedPeerReadState?, PeerChatListEmbeddedInterfaceState?) case IntermediateMessageEntry(ChatListIndex, IntermediateMessage?, CombinedPeerReadState?, PeerChatListEmbeddedInterfaceState?)
case MessageEntry(ChatListIndex, Message?, CombinedPeerReadState?, PeerNotificationSettings?, PeerChatListEmbeddedInterfaceState?, RenderedPeer, ChatListMessageTagSummaryInfo) case MessageEntry(ChatListIndex, Message?, CombinedPeerReadState?, PeerNotificationSettings?, PeerChatListEmbeddedInterfaceState?, RenderedPeer, PeerPresence?, ChatListMessageTagSummaryInfo)
case HoleEntry(ChatListHole) case HoleEntry(ChatListHole)
/*case IntermediateGroupReferenceEntry(PeerGroupId, ChatListIndex, ChatListGroupReferenceUnreadCounters?) /*case IntermediateGroupReferenceEntry(PeerGroupId, ChatListIndex, ChatListGroupReferenceUnreadCounters?)
case GroupReferenceEntry(PeerGroupId, ChatListIndex, Message?, ChatListGroupReferenceTopPeers, ChatListGroupReferenceUnreadCounters)*/ case GroupReferenceEntry(PeerGroupId, ChatListIndex, Message?, ChatListGroupReferenceTopPeers, ChatListGroupReferenceUnreadCounters)*/
@ -185,7 +192,7 @@ enum MutableChatListEntry: Equatable {
switch self { switch self {
case let .IntermediateMessageEntry(index, _, _, _): case let .IntermediateMessageEntry(index, _, _, _):
return index return index
case let .MessageEntry(index, _, _, _, _, _, _): case let .MessageEntry(index, _, _, _, _, _, _, _):
return index return index
case let .HoleEntry(hole): case let .HoleEntry(hole):
return ChatListIndex(pinningIndex: nil, messageIndex: hole.index) return ChatListIndex(pinningIndex: nil, messageIndex: hole.index)
@ -350,7 +357,7 @@ final class MutableChatListView {
} }
} }
func replay(postbox: Postbox, operations: [WrappedPeerGroupId: [ChatListOperation]], updatedPeerNotificationSettings: [PeerId: PeerNotificationSettings], updatedPeers: [PeerId: Peer], transaction: PostboxTransaction, context: MutableChatListViewReplayContext) -> Bool { func replay(postbox: Postbox, operations: [WrappedPeerGroupId: [ChatListOperation]], updatedPeerNotificationSettings: [PeerId: PeerNotificationSettings], updatedPeers: [PeerId: Peer], updatedPeerPresences: [PeerId: PeerPresence], transaction: PostboxTransaction, context: MutableChatListViewReplayContext) -> Bool {
var hasChanges = false var hasChanges = false
//var cachedGroupCounters: [PeerGroupId: ChatListGroupReferenceUnreadCounters] = [:] //var cachedGroupCounters: [PeerGroupId: ChatListGroupReferenceUnreadCounters] = [:]
@ -428,13 +435,13 @@ final class MutableChatListView {
if !updatedPeerNotificationSettings.isEmpty { if !updatedPeerNotificationSettings.isEmpty {
for i in 0 ..< self.entries.count { for i in 0 ..< self.entries.count {
switch self.entries[i] { switch self.entries[i] {
case let .MessageEntry(index, message, readState, _, embeddedState, peer, summaryInfo): case let .MessageEntry(index, message, readState, _, embeddedState, peer, peerPresence, summaryInfo):
var notificationSettingsPeerId = peer.peerId var notificationSettingsPeerId = peer.peerId
if let peer = peer.peers[peer.peerId], let associatedPeerId = peer.associatedPeerId { if let peer = peer.peers[peer.peerId], let associatedPeerId = peer.associatedPeerId {
notificationSettingsPeerId = associatedPeerId notificationSettingsPeerId = associatedPeerId
} }
if let settings = updatedPeerNotificationSettings[notificationSettingsPeerId] { if let settings = updatedPeerNotificationSettings[notificationSettingsPeerId] {
self.entries[i] = .MessageEntry(index, message, readState, settings, embeddedState, peer, summaryInfo) self.entries[i] = .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, summaryInfo)
hasChanges = true hasChanges = true
} }
default: default:
@ -445,14 +452,31 @@ final class MutableChatListView {
if !updatedPeers.isEmpty { if !updatedPeers.isEmpty {
for i in 0 ..< self.entries.count { for i in 0 ..< self.entries.count {
switch self.entries[i] { switch self.entries[i] {
case let .MessageEntry(index, message, readState, settings, embeddedState, peer, summaryInfo): case let .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, summaryInfo):
var updatedMessage: Message? var updatedMessage: Message?
if let message = message { if let message = message {
updatedMessage = updateMessagePeers(message, updatedPeers: updatedPeers) updatedMessage = updateMessagePeers(message, updatedPeers: updatedPeers)
} }
let updatedPeer = updatedRenderedPeer(peer, updatedPeers: updatedPeers) let updatedPeer = updatedRenderedPeer(peer, updatedPeers: updatedPeers)
if updatedMessage != nil || updatedPeer != nil { if updatedMessage != nil || updatedPeer != nil {
self.entries[i] = .MessageEntry(index, updatedMessage ?? message, readState, settings, embeddedState, updatedPeer ?? peer, summaryInfo) self.entries[i] = .MessageEntry(index, updatedMessage ?? message, readState, settings, embeddedState, updatedPeer ?? peer, peerPresence, summaryInfo)
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):
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)
hasChanges = true hasChanges = true
} }
default: default:
@ -463,7 +487,7 @@ final class MutableChatListView {
if !transaction.currentUpdatedMessageTagSummaries.isEmpty || !transaction.currentUpdatedMessageActionsSummaries.isEmpty { if !transaction.currentUpdatedMessageTagSummaries.isEmpty || !transaction.currentUpdatedMessageActionsSummaries.isEmpty {
for i in 0 ..< self.entries.count { for i in 0 ..< self.entries.count {
switch self.entries[i] { switch self.entries[i] {
case let .MessageEntry(index, message, readState, settings, embeddedState, peer, currentSummary): case let .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, currentSummary):
var updatedTagSummaryCount: Int32? var updatedTagSummaryCount: Int32?
var updatedActionsSummaryCount: Int32? var updatedActionsSummaryCount: Int32?
@ -484,7 +508,7 @@ final class MutableChatListView {
if updatedTagSummaryCount != nil || updatedActionsSummaryCount != nil { if updatedTagSummaryCount != nil || updatedActionsSummaryCount != nil {
let summaryInfo = ChatListMessageTagSummaryInfo(tagSummaryCount: updatedTagSummaryCount ?? currentSummary.tagSummaryCount, actionsSummaryCount: updatedActionsSummaryCount ?? currentSummary.actionsSummaryCount) let summaryInfo = ChatListMessageTagSummaryInfo(tagSummaryCount: updatedTagSummaryCount ?? currentSummary.tagSummaryCount, actionsSummaryCount: updatedActionsSummaryCount ?? currentSummary.actionsSummaryCount)
self.entries[i] = .MessageEntry(index, message, readState, settings, embeddedState, peer, summaryInfo) self.entries[i] = .MessageEntry(index, message, readState, settings, embeddedState, peer, peerPresence, summaryInfo)
hasChanges = true hasChanges = true
} }
default: default:
@ -737,7 +761,7 @@ final class MutableChatListView {
return nil return nil
} }
private func renderEntry(_ entry: MutableChatListEntry, postbox: Postbox, renderMessage: (IntermediateMessage) -> Message, getPeer: (PeerId) -> Peer?, getPeerNotificationSettings: (PeerId) -> PeerNotificationSettings?) -> MutableChatListEntry? { private func renderEntry(_ entry: MutableChatListEntry, postbox: Postbox, renderMessage: (IntermediateMessage) -> Message, getPeer: (PeerId) -> Peer?, getPeerNotificationSettings: (PeerId) -> PeerNotificationSettings?, getPeerPresence: (PeerId) -> PeerPresence?) -> MutableChatListEntry? {
switch entry { switch entry {
case let .IntermediateMessageEntry(index, message, combinedReadState, embeddedState): case let .IntermediateMessageEntry(index, message, combinedReadState, embeddedState):
let renderedMessage: Message? let renderedMessage: Message?
@ -748,6 +772,7 @@ final class MutableChatListView {
} }
var peers = SimpleDictionary<PeerId, Peer>() var peers = SimpleDictionary<PeerId, Peer>()
var notificationSettings: PeerNotificationSettings? var notificationSettings: PeerNotificationSettings?
var presence: PeerPresence?
if let peer = getPeer(index.messageIndex.id.peerId) { if let peer = getPeer(index.messageIndex.id.peerId) {
peers[peer.id] = peer peers[peer.id] = peer
if let associatedPeerId = peer.associatedPeerId { if let associatedPeerId = peer.associatedPeerId {
@ -755,8 +780,10 @@ final class MutableChatListView {
peers[associatedPeer.id] = associatedPeer peers[associatedPeer.id] = associatedPeer
} }
notificationSettings = getPeerNotificationSettings(associatedPeerId) notificationSettings = getPeerNotificationSettings(associatedPeerId)
presence = getPeerPresence(associatedPeerId)
} else { } else {
notificationSettings = getPeerNotificationSettings(index.messageIndex.id.peerId) notificationSettings = getPeerNotificationSettings(index.messageIndex.id.peerId)
presence = getPeerPresence(index.messageIndex.id.peerId)
} }
} }
@ -775,7 +802,7 @@ final class MutableChatListView {
actionsSummaryCount = postbox.pendingMessageActionsMetadataTable.getCount(.peerNamespaceAction(key.peerId, key.namespace, key.type)) 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), ChatListMessageTagSummaryInfo(tagSummaryCount: tagSummaryCount, actionsSummaryCount: actionsSummaryCount)) return .MessageEntry(index, renderedMessage, combinedReadState, notificationSettings, embeddedState, RenderedPeer(peerId: index.messageIndex.id.peerId, peers: peers), presence, ChatListMessageTagSummaryInfo(tagSummaryCount: tagSummaryCount, actionsSummaryCount: actionsSummaryCount))
/*case let .IntermediateGroupReferenceEntry(groupId, index, counters): /*case let .IntermediateGroupReferenceEntry(groupId, index, counters):
let message = postbox.messageHistoryTable.getMessage(index.messageIndex).flatMap(postbox.renderIntermediateMessage) let message = postbox.messageHistoryTable.getMessage(index.messageIndex).flatMap(postbox.renderIntermediateMessage)
return .GroupReferenceEntry(groupId, index, message, ChatListGroupReferenceTopPeers(postbox: postbox, groupId: groupId), counters ?? ChatListGroupReferenceUnreadCounters(postbox: postbox, groupId: groupId))*/ return .GroupReferenceEntry(groupId, index, message, ChatListGroupReferenceTopPeers(postbox: postbox, groupId: groupId), counters ?? ChatListGroupReferenceUnreadCounters(postbox: postbox, groupId: groupId))*/
@ -784,14 +811,14 @@ final class MutableChatListView {
} }
} }
func render(postbox: Postbox, renderMessage: (IntermediateMessage) -> Message, getPeer: (PeerId) -> Peer?, getPeerNotificationSettings: (PeerId) -> PeerNotificationSettings?) { 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) { if let updatedEntry = self.renderEntry(self.entries[i], postbox: postbox, renderMessage: renderMessage, getPeer: getPeer, getPeerNotificationSettings: getPeerNotificationSettings, getPeerPresence: getPeerPresence) {
self.entries[i] = updatedEntry self.entries[i] = updatedEntry
} }
} }
for i in 0 ..< self.additionalItemEntries.count { for i in 0 ..< self.additionalItemEntries.count {
if let updatedEntry = self.renderEntry(self.additionalItemEntries[i], postbox: postbox, renderMessage: renderMessage, getPeer: getPeer, getPeerNotificationSettings: getPeerNotificationSettings) { if let updatedEntry = self.renderEntry(self.additionalItemEntries[i], postbox: postbox, renderMessage: renderMessage, getPeer: getPeer, getPeerNotificationSettings: getPeerNotificationSettings, getPeerPresence: getPeerPresence) {
self.additionalItemEntries[i] = updatedEntry self.additionalItemEntries[i] = updatedEntry
} }
} }
@ -811,8 +838,8 @@ public final class ChatListView {
var entries: [ChatListEntry] = [] var entries: [ChatListEntry] = []
for entry in mutableView.entries { for entry in mutableView.entries {
switch entry { switch entry {
case let .MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, summaryInfo): case let .MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, peerPresence, summaryInfo):
entries.append(.MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, summaryInfo)) entries.append(.MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, peerPresence, summaryInfo))
case let .HoleEntry(hole): case let .HoleEntry(hole):
entries.append(.HoleEntry(hole)) entries.append(.HoleEntry(hole))
/*case let .GroupReferenceEntry(groupId, index, message, topPeers, counters): /*case let .GroupReferenceEntry(groupId, index, message, topPeers, counters):
@ -830,8 +857,8 @@ public final class ChatListView {
var additionalItemEntries: [ChatListEntry] = [] var additionalItemEntries: [ChatListEntry] = []
for entry in mutableView.additionalItemEntries { for entry in mutableView.additionalItemEntries {
switch entry { switch entry {
case let .MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, summaryInfo): case let .MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, peerPresence, summaryInfo):
additionalItemEntries.append(.MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, summaryInfo)) additionalItemEntries.append(.MessageEntry(index, message, combinedReadState, notificationSettings, embeddedState, peer, peerPresence, summaryInfo))
case .HoleEntry: case .HoleEntry:
assertionFailure() assertionFailure()
/*case .GroupReferenceEntry: /*case .GroupReferenceEntry:

View File

@ -2686,7 +2686,7 @@ public final class Postbox {
let mutableView = MutableChatListView(postbox: self, groupId: groupId, earlier: earlier, entries: entries, later: later, count: count, summaryComponents: summaryComponents) let mutableView = MutableChatListView(postbox: self, groupId: groupId, earlier: earlier, entries: entries, later: later, count: count, summaryComponents: summaryComponents)
mutableView.render(postbox: self, renderMessage: self.renderIntermediateMessage, getPeer: { id in mutableView.render(postbox: self, renderMessage: self.renderIntermediateMessage, getPeer: { id in
return self.peerTable.get(id) return self.peerTable.get(id)
}, getPeerNotificationSettings: { self.peerNotificationSettingsTable.getEffective($0) }) }, getPeerNotificationSettings: { self.peerNotificationSettingsTable.getEffective($0) }, getPeerPresence: { self.peerPresenceTable.get($0) })
let (index, signal) = self.viewTracker.addChatListView(mutableView) let (index, signal) = self.viewTracker.addChatListView(mutableView)

View File

@ -259,7 +259,7 @@ final class ViewTracker {
if mutableView.refreshDueToExternalTransaction(postbox: postbox) { if mutableView.refreshDueToExternalTransaction(postbox: postbox) {
mutableView.render(postbox: postbox, renderMessage: self.renderMessage, getPeer: { id in mutableView.render(postbox: postbox, renderMessage: self.renderMessage, getPeer: { id in
return self.getPeer(id) return self.getPeer(id)
}, getPeerNotificationSettings: self.getPeerNotificationSettings) }, getPeerNotificationSettings: self.getPeerNotificationSettings, getPeerPresence: self.getPeerPresence)
pipe.putNext((ChatListView(mutableView), .Generic)) pipe.putNext((ChatListView(mutableView), .Generic))
} }
} }
@ -377,14 +377,14 @@ final class ViewTracker {
} }
} }
if !transaction.chatListOperations.isEmpty || !transaction.currentUpdatedPeerNotificationSettings.isEmpty || !transaction.currentUpdatedPeers.isEmpty || !transaction.currentInvalidateMessageTagSummaries.isEmpty || !transaction.currentUpdatedMessageTagSummaries.isEmpty || !transaction.currentOperationsByPeerId.isEmpty || transaction.replacedAdditionalChatListItems != nil { if !transaction.chatListOperations.isEmpty || !transaction.currentUpdatedPeerNotificationSettings.isEmpty || !transaction.currentUpdatedPeers.isEmpty || !transaction.currentInvalidateMessageTagSummaries.isEmpty || !transaction.currentUpdatedMessageTagSummaries.isEmpty || !transaction.currentOperationsByPeerId.isEmpty || transaction.replacedAdditionalChatListItems != nil || !transaction.currentUpdatedPeerPresences.isEmpty {
for (mutableView, pipe) in self.chatListViews.copyItems() { for (mutableView, pipe) in self.chatListViews.copyItems() {
let context = MutableChatListViewReplayContext() let context = MutableChatListViewReplayContext()
if mutableView.replay(postbox: postbox, operations: transaction.chatListOperations, updatedPeerNotificationSettings: transaction.currentUpdatedPeerNotificationSettings, updatedPeers: transaction.currentUpdatedPeers, transaction: transaction, context: context) { if mutableView.replay(postbox: postbox, operations: transaction.chatListOperations, updatedPeerNotificationSettings: transaction.currentUpdatedPeerNotificationSettings, updatedPeers: transaction.currentUpdatedPeers, updatedPeerPresences: transaction.currentUpdatedPeerPresences, transaction: transaction, context: context) {
mutableView.complete(postbox: postbox, context: context) mutableView.complete(postbox: postbox, context: context)
mutableView.render(postbox: postbox, renderMessage: self.renderMessage, getPeer: { id in mutableView.render(postbox: postbox, renderMessage: self.renderMessage, getPeer: { id in
return self.getPeer(id) return self.getPeer(id)
}, getPeerNotificationSettings: self.getPeerNotificationSettings) }, getPeerNotificationSettings: self.getPeerNotificationSettings, getPeerPresence: self.getPeerPresence)
pipe.putNext((ChatListView(mutableView), .Generic)) pipe.putNext((ChatListView(mutableView), .Generic))
} }
} }