This commit is contained in:
overtake
2019-01-08 19:46:14 +04:00
3 changed files with 72 additions and 27 deletions

View File

@@ -8,7 +8,7 @@ import Foundation
public struct AccountManagerModifier {
public let getRecords: () -> [AccountRecord]
public let updateRecord: (AccountRecordId, (AccountRecord?) -> (AccountRecord?)) -> Void
public let getCurrentId: () -> AccountRecordId?
public let getCurrent: () -> (AccountRecordId, [AccountRecordAttribute])?
public let setCurrentId: (AccountRecordId) -> Void
public let createRecord: ([AccountRecordAttribute]) -> AccountRecordId
public let getSharedData: (ValueBoxKey) -> AccountSharedData?
@@ -68,8 +68,13 @@ final class AccountManagerImpl {
if updated != current {
self.recordTable.setRecord(id: id, record: updated, operations: &self.currentRecordOperations)
}
}, getCurrentId: {
return self.metadataTable.getCurrentAccountId()
}, getCurrent: {
if let id = self.metadataTable.getCurrentAccountId() {
let record = self.recordTable.getRecord(id: id)
return (id, record?.attributes ?? [])
} else {
return nil
}
}, setCurrentId: { id in
self.metadataTable.setCurrentAccountId(id, operations: &self.currentMetadataOperations)
}, createRecord: { attributes in
@@ -179,32 +184,54 @@ final class AccountManagerImpl {
}
}
fileprivate func currentAccountId(allocateIfNotExists: Bool) -> Signal<AccountRecordId?, NoError> {
return self.transaction { transaction -> Signal<AccountRecordId?, NoError> in
let current = transaction.getCurrentId()
let id: AccountRecordId
fileprivate func currentAccountRecord(allocateIfNotExists: Bool) -> Signal<(AccountRecordId, [AccountRecordAttribute])?, NoError> {
return self.transaction { transaction -> Signal<(AccountRecordId, [AccountRecordAttribute])?, NoError> in
let current = transaction.getCurrent()
let record: (AccountRecordId, [AccountRecordAttribute])?
if let current = current {
id = current
record = current
} else if allocateIfNotExists {
id = generateAccountRecordId()
let id = generateAccountRecordId()
transaction.setCurrentId(id)
transaction.updateRecord(id, { _ in
return AccountRecord(id: id, attributes: [], temporarySessionId: nil)
})
record = (id, [])
} else {
return .single(nil)
}
let signal = self.accountRecordsInternal(transaction: transaction)
|> map { view -> AccountRecordId? in
return view.currentRecord?.id
|> map { view -> (AccountRecordId, [AccountRecordAttribute])? in
if let currentRecord = view.currentRecord {
return (currentRecord.id, currentRecord.attributes)
} else {
return nil
}
}
return signal
}
|> switchToLatest
|> distinctUntilChanged(isEqual: { lhs, rhs in
return lhs == rhs
if let lhs = lhs, let rhs = rhs {
if lhs.0 != rhs.0 {
return false
}
if lhs.1.count != rhs.1.count {
return false
}
for i in 0 ..< lhs.1.count {
if !lhs.1[i].isEqual(to: rhs.1[i]) {
return false
}
}
return true
} else if (lhs != nil) != (rhs != nil) {
return false
} else {
return true
}
})
}
@@ -283,11 +310,11 @@ public final class AccountManager {
}
}
public func currentAccountId(allocateIfNotExists: Bool) -> Signal<AccountRecordId?, NoError> {
public func currentAccountRecord(allocateIfNotExists: Bool) -> Signal<(AccountRecordId, [AccountRecordAttribute])?, NoError> {
return Signal { subscriber in
let disposable = MetaDisposable()
self.impl.with { impl in
disposable.set(impl.currentAccountId(allocateIfNotExists: allocateIfNotExists).start(next: { next in
disposable.set(impl.currentAccountRecord(allocateIfNotExists: allocateIfNotExists).start(next: { next in
subscriber.putNext(next)
}, completed: {
subscriber.putCompletion()

View File

@@ -146,6 +146,23 @@ public enum ChatListEntry: Comparable {
}
}
private func processedChatListEntry(_ entry: MutableChatListEntry, cachedDataTable: CachedPeerDataTable, readStateTable: MessageHistoryReadStateTable, messageHistoryTable: MessageHistoryTable) -> MutableChatListEntry {
switch entry {
case let .IntermediateMessageEntry(index, message, readState, embeddedState):
var updatedMessage = message
if let message = message, let cachedData = cachedDataTable.get(message.id.peerId), let associatedHistoryMessageId = cachedData.associatedHistoryMessageId, message.id.id == 1 {
if let indexEntry = messageHistoryTable.messageHistoryIndexTable.earlierEntries(id: associatedHistoryMessageId, count: 1).first, case let .Message(messageIndex) = indexEntry {
if let associatedMessage = messageHistoryTable.getMessage(messageIndex) {
updatedMessage = associatedMessage
}
}
}
return .IntermediateMessageEntry(index, updatedMessage, readState, embeddedState)
default:
return entry
}
}
enum MutableChatListEntry: Equatable {
case IntermediateMessageEntry(ChatListIndex, IntermediateMessage?, CombinedPeerReadState?, PeerChatListEmbeddedInterfaceState?)
case MessageEntry(ChatListIndex, Message?, CombinedPeerReadState?, PeerNotificationSettings?, PeerChatListEmbeddedInterfaceState?, RenderedPeer, ChatListMessageTagSummaryInfo)
@@ -153,10 +170,10 @@ enum MutableChatListEntry: Equatable {
case IntermediateGroupReferenceEntry(PeerGroupId, ChatListIndex, ChatListGroupReferenceUnreadCounters?)
case GroupReferenceEntry(PeerGroupId, ChatListIndex, Message?, ChatListGroupReferenceTopPeers, ChatListGroupReferenceUnreadCounters)
init(_ intermediateEntry: ChatListIntermediateEntry, readStateTable: MessageHistoryReadStateTable) {
init(_ intermediateEntry: ChatListIntermediateEntry, cachedDataTable: CachedPeerDataTable, readStateTable: MessageHistoryReadStateTable, messageHistoryTable: MessageHistoryTable) {
switch intermediateEntry {
case let .message(index, message, embeddedState):
self = .IntermediateMessageEntry(index, message, readStateTable.getCombinedState(index.messageIndex.id.peerId), embeddedState)
self = processedChatListEntry(.IntermediateMessageEntry(index, message, readStateTable.getCombinedState(index.messageIndex.id.peerId), embeddedState), cachedDataTable: cachedDataTable, readStateTable: readStateTable, messageHistoryTable: messageHistoryTable)
case let .hole(hole):
self = .HoleEntry(hole)
case let .groupReference(groupId, index):
@@ -307,7 +324,7 @@ final class MutableChatListView {
self.additionalItemIds = Set(itemIds)
for peerId in itemIds {
if let entry = postbox.chatListTable.getStandalone(peerId: peerId, messageHistoryTable: postbox.messageHistoryTable) {
self.additionalItemEntries.append(MutableChatListEntry(entry, readStateTable: postbox.readStateTable))
self.additionalItemEntries.append(MutableChatListEntry(entry, cachedDataTable: postbox.cachedPeerDataTable, readStateTable: postbox.readStateTable, messageHistoryTable: postbox.messageHistoryTable))
}
}
} else {
@@ -356,15 +373,15 @@ final class MutableChatListView {
for operation in groupOperations {
switch operation {
case let .InsertEntry(index, message, combinedReadState, embeddedState):
if self.add(.IntermediateMessageEntry(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)) {
if self.add(.HoleEntry(index), postbox: postbox) {
hasChanges = true
}
case let .InsertGroupReference(groupId, index):
if self.add(.IntermediateGroupReferenceEntry(groupId, index, cachedGroupCounters[groupId] ?? ChatListGroupReferenceUnreadCounters(postbox: postbox, groupId: groupId))) {
if self.add(.IntermediateGroupReferenceEntry(groupId, index, cachedGroupCounters[groupId] ?? ChatListGroupReferenceUnreadCounters(postbox: postbox, groupId: groupId)), postbox: postbox) {
hasChanges = true
}
case let .RemoveEntry(indices):
@@ -494,7 +511,7 @@ final class MutableChatListView {
self.additionalItemEntries.removeAll()
for peerId in postbox.additionalChatListItemsTable.get() {
if let entry = postbox.chatListTable.getStandalone(peerId: peerId, messageHistoryTable: postbox.messageHistoryTable) {
self.additionalItemEntries.append(MutableChatListEntry(entry, readStateTable: postbox.readStateTable))
self.additionalItemEntries.append(MutableChatListEntry(entry, cachedDataTable: postbox.cachedPeerDataTable, readStateTable: postbox.readStateTable, messageHistoryTable: postbox.messageHistoryTable))
}
}
hasChanges = true
@@ -502,7 +519,8 @@ final class MutableChatListView {
return hasChanges
}
func add(_ entry: MutableChatListEntry) -> Bool {
func add(_ initialEntry: MutableChatListEntry, postbox: Postbox) -> Bool {
let entry = processedChatListEntry(initialEntry, cachedDataTable: postbox.cachedPeerDataTable, readStateTable: postbox.readStateTable, messageHistoryTable: postbox.messageHistoryTable)
if self.entries.count == 0 {
self.entries.append(entry)
return true

View File

@@ -1861,13 +1861,13 @@ public final class Postbox {
func fetchAroundChatEntries(groupId: PeerGroupId?, index: ChatListIndex, count: Int) -> (entries: [MutableChatListEntry], earlier: MutableChatListEntry?, later: MutableChatListEntry?) {
let (intermediateEntries, intermediateLower, intermediateUpper) = self.chatListTable.entriesAround(groupId: groupId, index: index, messageHistoryTable: self.messageHistoryTable, peerChatInterfaceStateTable: self.peerChatInterfaceStateTable, count: count)
let entries: [MutableChatListEntry] = intermediateEntries.map { entry in
return MutableChatListEntry(entry, readStateTable: self.readStateTable)
return MutableChatListEntry(entry, cachedDataTable: self.cachedPeerDataTable, readStateTable: self.readStateTable, messageHistoryTable: self.messageHistoryTable)
}
let lower: MutableChatListEntry? = intermediateLower.flatMap { entry in
return MutableChatListEntry(entry, readStateTable: self.readStateTable)
return MutableChatListEntry(entry, cachedDataTable: self.cachedPeerDataTable, readStateTable: self.readStateTable, messageHistoryTable: self.messageHistoryTable)
}
let upper: MutableChatListEntry? = intermediateUpper.flatMap { entry in
return MutableChatListEntry(entry, readStateTable: self.readStateTable)
return MutableChatListEntry(entry, cachedDataTable: self.cachedPeerDataTable, readStateTable: self.readStateTable, messageHistoryTable: self.messageHistoryTable)
}
return (entries, lower, upper)
@@ -1876,7 +1876,7 @@ public final class Postbox {
func fetchEarlierChatEntries(groupId: PeerGroupId?, index: ChatListIndex?, count: Int) -> [MutableChatListEntry] {
let intermediateEntries = self.chatListTable.earlierEntries(groupId: groupId, index: index, messageHistoryTable: self.messageHistoryTable, peerChatInterfaceStateTable: self.peerChatInterfaceStateTable, count: count)
let entries: [MutableChatListEntry] = intermediateEntries.map { entry in
return MutableChatListEntry(entry, readStateTable: self.readStateTable)
return MutableChatListEntry(entry, cachedDataTable: self.cachedPeerDataTable, readStateTable: self.readStateTable, messageHistoryTable: self.messageHistoryTable)
}
return entries
}
@@ -1884,7 +1884,7 @@ public final class Postbox {
func fetchLaterChatEntries(groupId: PeerGroupId?, index: ChatListIndex?, count: Int) -> [MutableChatListEntry] {
let intermediateEntries = self.chatListTable.laterEntries(groupId: groupId, index: index, messageHistoryTable: self.messageHistoryTable, peerChatInterfaceStateTable: self.peerChatInterfaceStateTable, count: count)
let entries: [MutableChatListEntry] = intermediateEntries.map { entry in
return MutableChatListEntry(entry, readStateTable: self.readStateTable)
return MutableChatListEntry(entry, cachedDataTable: self.cachedPeerDataTable, readStateTable: self.readStateTable, messageHistoryTable: self.messageHistoryTable)
}
return entries
}