mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
State management fixes
This commit is contained in:
parent
4a045feb2f
commit
fb07f06a26
@ -10,6 +10,11 @@ public final class InteractivePhoneFormatter {
|
|||||||
public func updateText(_ text: String) -> (String?, String) {
|
public func updateText(_ text: String) -> (String?, String) {
|
||||||
self.formatter.clear()
|
self.formatter.clear()
|
||||||
let string = self.formatter.inputString(text)
|
let string = self.formatter.inputString(text)
|
||||||
return (self.formatter.regionPrefix, string ?? "")
|
|
||||||
|
var regionPrefix = self.formatter.regionPrefix
|
||||||
|
if let string = string, string.hasPrefix("+383") {
|
||||||
|
regionPrefix = "+383"
|
||||||
|
}
|
||||||
|
return (regionPrefix, string ?? "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,20 +10,24 @@ struct PeerChatInfo {
|
|||||||
var notificationSettings: PeerNotificationSettings
|
var notificationSettings: PeerNotificationSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AccountStateChannelState: Equatable {
|
||||||
|
var pts: Int32
|
||||||
|
}
|
||||||
|
|
||||||
final class AccountInitialState {
|
final class AccountInitialState {
|
||||||
let state: AuthorizedAccountState.State
|
let state: AuthorizedAccountState.State
|
||||||
let peerIds: Set<PeerId>
|
let peerIds: Set<PeerId>
|
||||||
let chatStates: [PeerId: PeerChatState]
|
let channelStates: [PeerId: AccountStateChannelState]
|
||||||
let peerChatInfos: [PeerId: PeerChatInfo]
|
let peerChatInfos: [PeerId: PeerChatInfo]
|
||||||
let peerIdsRequiringLocalChatState: Set<PeerId>
|
let peerIdsRequiringLocalChatState: Set<PeerId>
|
||||||
let locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]]
|
let locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]]
|
||||||
let cloudReadStates: [PeerId: PeerReadState]
|
let cloudReadStates: [PeerId: PeerReadState]
|
||||||
let channelsToPollExplicitely: Set<PeerId>
|
let channelsToPollExplicitely: Set<PeerId>
|
||||||
|
|
||||||
init(state: AuthorizedAccountState.State, peerIds: Set<PeerId>, peerIdsRequiringLocalChatState: Set<PeerId>, chatStates: [PeerId: PeerChatState], peerChatInfos: [PeerId: PeerChatInfo], locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]], cloudReadStates: [PeerId: PeerReadState], channelsToPollExplicitely: Set<PeerId>) {
|
init(state: AuthorizedAccountState.State, peerIds: Set<PeerId>, peerIdsRequiringLocalChatState: Set<PeerId>, channelStates: [PeerId: AccountStateChannelState], peerChatInfos: [PeerId: PeerChatInfo], locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]], cloudReadStates: [PeerId: PeerReadState], channelsToPollExplicitely: Set<PeerId>) {
|
||||||
self.state = state
|
self.state = state
|
||||||
self.peerIds = peerIds
|
self.peerIds = peerIds
|
||||||
self.chatStates = chatStates
|
self.channelStates = channelStates
|
||||||
self.peerIdsRequiringLocalChatState = peerIdsRequiringLocalChatState
|
self.peerIdsRequiringLocalChatState = peerIdsRequiringLocalChatState
|
||||||
self.peerChatInfos = peerChatInfos
|
self.peerChatInfos = peerChatInfos
|
||||||
self.locallyGeneratedMessageTimestamps = locallyGeneratedMessageTimestamps
|
self.locallyGeneratedMessageTimestamps = locallyGeneratedMessageTimestamps
|
||||||
@ -72,7 +76,9 @@ enum AccountStateMutationOperation {
|
|||||||
case ResetMessageTagSummary(PeerId, MessageId.Namespace, Int32, MessageHistoryTagNamespaceCountValidityRange)
|
case ResetMessageTagSummary(PeerId, MessageId.Namespace, Int32, MessageHistoryTagNamespaceCountValidityRange)
|
||||||
case ReadGroupFeedInbox(PeerGroupId, MessageIndex)
|
case ReadGroupFeedInbox(PeerGroupId, MessageIndex)
|
||||||
case UpdateState(AuthorizedAccountState.State)
|
case UpdateState(AuthorizedAccountState.State)
|
||||||
case UpdateChannelState(PeerId, ChannelState)
|
case UpdateChannelState(PeerId, Int32)
|
||||||
|
case UpdateChannelInvalidationPts(PeerId, Int32)
|
||||||
|
case UpdateChannelSynchronizedUntilMessage(PeerId, MessageId.Id)
|
||||||
case UpdateNotificationSettings(AccountStateNotificationSettingsSubject, PeerNotificationSettings)
|
case UpdateNotificationSettings(AccountStateNotificationSettingsSubject, PeerNotificationSettings)
|
||||||
case UpdateGlobalNotificationSettings(AccountStateGlobalNotificationSettingsSubject, MessageNotificationSettings)
|
case UpdateGlobalNotificationSettings(AccountStateGlobalNotificationSettingsSubject, MessageNotificationSettings)
|
||||||
case MergeApiChats([Api.Chat])
|
case MergeApiChats([Api.Chat])
|
||||||
@ -110,7 +116,7 @@ struct AccountMutableState {
|
|||||||
|
|
||||||
var state: AuthorizedAccountState.State
|
var state: AuthorizedAccountState.State
|
||||||
var peers: [PeerId: Peer]
|
var peers: [PeerId: Peer]
|
||||||
var chatStates: [PeerId: PeerChatState]
|
var channelStates: [PeerId: AccountStateChannelState]
|
||||||
var peerChatInfos: [PeerId: PeerChatInfo]
|
var peerChatInfos: [PeerId: PeerChatInfo]
|
||||||
var referencedMessageIds: Set<MessageId>
|
var referencedMessageIds: Set<MessageId>
|
||||||
var storedMessages: Set<MessageId>
|
var storedMessages: Set<MessageId>
|
||||||
@ -139,7 +145,7 @@ struct AccountMutableState {
|
|||||||
self.referencedMessageIds = initialReferencedMessageIds
|
self.referencedMessageIds = initialReferencedMessageIds
|
||||||
self.storedMessages = initialStoredMessages
|
self.storedMessages = initialStoredMessages
|
||||||
self.readInboxMaxIds = initialReadInboxMaxIds
|
self.readInboxMaxIds = initialReadInboxMaxIds
|
||||||
self.chatStates = initialState.chatStates
|
self.channelStates = initialState.channelStates
|
||||||
self.peerChatInfos = initialState.peerChatInfos
|
self.peerChatInfos = initialState.peerChatInfos
|
||||||
self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp
|
self.storedMessagesByPeerIdAndTimestamp = storedMessagesByPeerIdAndTimestamp
|
||||||
self.branchOperationIndex = 0
|
self.branchOperationIndex = 0
|
||||||
@ -147,12 +153,12 @@ struct AccountMutableState {
|
|||||||
self.updatedOutgoingUniqueMessageIds = [:]
|
self.updatedOutgoingUniqueMessageIds = [:]
|
||||||
}
|
}
|
||||||
|
|
||||||
init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], chatStates: [PeerId: PeerChatState], peerChatInfos: [PeerId: PeerChatInfo], referencedMessageIds: Set<MessageId>, storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>], updatedOutgoingUniqueMessageIds: [Int64: Int32], displayAlerts: [(text: String, isDropAuth: Bool)], branchOperationIndex: Int) {
|
init(initialState: AccountInitialState, operations: [AccountStateMutationOperation], state: AuthorizedAccountState.State, peers: [PeerId: Peer], channelStates: [PeerId: AccountStateChannelState], peerChatInfos: [PeerId: PeerChatInfo], referencedMessageIds: Set<MessageId>, storedMessages: Set<MessageId>, readInboxMaxIds: [PeerId: MessageId], storedMessagesByPeerIdAndTimestamp: [PeerId: Set<MessageIndex>], namespacesWithHolesFromPreviousState: [PeerId: Set<MessageId.Namespace>], updatedOutgoingUniqueMessageIds: [Int64: Int32], displayAlerts: [(text: String, isDropAuth: Bool)], branchOperationIndex: Int) {
|
||||||
self.initialState = initialState
|
self.initialState = initialState
|
||||||
self.operations = operations
|
self.operations = operations
|
||||||
self.state = state
|
self.state = state
|
||||||
self.peers = peers
|
self.peers = peers
|
||||||
self.chatStates = chatStates
|
self.channelStates = channelStates
|
||||||
self.referencedMessageIds = referencedMessageIds
|
self.referencedMessageIds = referencedMessageIds
|
||||||
self.storedMessages = storedMessages
|
self.storedMessages = storedMessages
|
||||||
self.peerChatInfos = peerChatInfos
|
self.peerChatInfos = peerChatInfos
|
||||||
@ -165,7 +171,7 @@ struct AccountMutableState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func branch() -> AccountMutableState {
|
func branch() -> AccountMutableState {
|
||||||
return AccountMutableState(initialState: self.initialState, operations: self.operations, state: self.state, peers: self.peers, chatStates: self.chatStates, peerChatInfos: self.peerChatInfos, referencedMessageIds: self.referencedMessageIds, storedMessages: self.storedMessages, readInboxMaxIds: self.readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: self.storedMessagesByPeerIdAndTimestamp, namespacesWithHolesFromPreviousState: self.namespacesWithHolesFromPreviousState, updatedOutgoingUniqueMessageIds: self.updatedOutgoingUniqueMessageIds, displayAlerts: self.displayAlerts, branchOperationIndex: self.operations.count)
|
return AccountMutableState(initialState: self.initialState, operations: self.operations, state: self.state, peers: self.peers, channelStates: self.channelStates, peerChatInfos: self.peerChatInfos, referencedMessageIds: self.referencedMessageIds, storedMessages: self.storedMessages, readInboxMaxIds: self.readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: self.storedMessagesByPeerIdAndTimestamp, namespacesWithHolesFromPreviousState: self.namespacesWithHolesFromPreviousState, updatedOutgoingUniqueMessageIds: self.updatedOutgoingUniqueMessageIds, displayAlerts: self.displayAlerts, branchOperationIndex: self.operations.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func merge(_ other: AccountMutableState) {
|
mutating func merge(_ other: AccountMutableState) {
|
||||||
@ -269,8 +275,16 @@ struct AccountMutableState {
|
|||||||
self.addOperation(.UpdateState(state))
|
self.addOperation(.UpdateState(state))
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func updateChannelState(_ peerId: PeerId, state: ChannelState) {
|
mutating func updateChannelState(_ peerId: PeerId, pts: Int32) {
|
||||||
self.addOperation(.UpdateChannelState(peerId, state))
|
self.addOperation(.UpdateChannelState(peerId, pts))
|
||||||
|
}
|
||||||
|
|
||||||
|
mutating func updateChannelInvalidationPts(_ peerId: PeerId, invalidationPts: Int32) {
|
||||||
|
self.addOperation(.UpdateChannelInvalidationPts(peerId, invalidationPts))
|
||||||
|
}
|
||||||
|
|
||||||
|
mutating func updateChannelSynchronizedUntilMessage(_ peerId: PeerId, id: MessageId.Id) {
|
||||||
|
self.addOperation(.UpdateChannelSynchronizedUntilMessage(peerId, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func updateNotificationSettings(_ subject: AccountStateNotificationSettingsSubject, notificationSettings: PeerNotificationSettings) {
|
mutating func updateNotificationSettings(_ subject: AccountStateNotificationSettingsSubject, notificationSettings: PeerNotificationSettings) {
|
||||||
@ -464,8 +478,12 @@ struct AccountMutableState {
|
|||||||
}
|
}
|
||||||
case let .UpdateState(state):
|
case let .UpdateState(state):
|
||||||
self.state = state
|
self.state = state
|
||||||
case let .UpdateChannelState(peerId, channelState):
|
case let .UpdateChannelState(peerId, pts):
|
||||||
self.chatStates[peerId] = channelState
|
self.channelStates[peerId] = AccountStateChannelState(pts: pts)
|
||||||
|
case .UpdateChannelInvalidationPts:
|
||||||
|
break
|
||||||
|
case .UpdateChannelSynchronizedUntilMessage:
|
||||||
|
break
|
||||||
case let .UpdateNotificationSettings(subject, notificationSettings):
|
case let .UpdateNotificationSettings(subject, notificationSettings):
|
||||||
if case let .peer(peerId) = subject {
|
if case let .peer(peerId) = subject {
|
||||||
if var currentInfo = self.peerChatInfos[peerId] {
|
if var currentInfo = self.peerChatInfos[peerId] {
|
||||||
|
@ -356,7 +356,7 @@ private func locallyGeneratedMessageTimestampsFromDifference(_ difference: Api.u
|
|||||||
|
|
||||||
private func initialStateWithPeerIds(_ transaction: Transaction, peerIds: Set<PeerId>, activeChannelIds: Set<PeerId>, associatedMessageIds: Set<MessageId>, peerIdsRequiringLocalChatState: Set<PeerId>, locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]]) -> AccountMutableState {
|
private func initialStateWithPeerIds(_ transaction: Transaction, peerIds: Set<PeerId>, activeChannelIds: Set<PeerId>, associatedMessageIds: Set<MessageId>, peerIdsRequiringLocalChatState: Set<PeerId>, locallyGeneratedMessageTimestamps: [PeerId: [(MessageId.Namespace, Int32)]]) -> AccountMutableState {
|
||||||
var peers: [PeerId: Peer] = [:]
|
var peers: [PeerId: Peer] = [:]
|
||||||
var chatStates: [PeerId: PeerChatState] = [:]
|
var channelStates: [PeerId: AccountStateChannelState] = [:]
|
||||||
|
|
||||||
var channelsToPollExplicitely = Set<PeerId>()
|
var channelsToPollExplicitely = Set<PeerId>()
|
||||||
|
|
||||||
@ -367,11 +367,11 @@ private func initialStateWithPeerIds(_ transaction: Transaction, peerIds: Set<Pe
|
|||||||
|
|
||||||
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
if let channelState = transaction.getPeerChatState(peerId) as? ChannelState {
|
if let channelState = transaction.getPeerChatState(peerId) as? ChannelState {
|
||||||
chatStates[peerId] = channelState
|
channelStates[peerId] = AccountStateChannelState(pts: channelState.pts)
|
||||||
}
|
}
|
||||||
} else if peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.CloudGroup {
|
} else if peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.CloudGroup {
|
||||||
if let chatState = transaction.getPeerChatState(peerId) as? RegularChatState {
|
if let _ = transaction.getPeerChatState(peerId) as? RegularChatState {
|
||||||
chatStates[peerId] = chatState
|
//chatStates[peerId] = chatState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,7 +434,7 @@ private func initialStateWithPeerIds(_ transaction: Transaction, peerIds: Set<Pe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return AccountMutableState(initialState: AccountInitialState(state: (transaction.getState() as? AuthorizedAccountState)!.state!, peerIds: peerIds, peerIdsRequiringLocalChatState: peerIdsRequiringLocalChatState, chatStates: chatStates, peerChatInfos: peerChatInfos, locallyGeneratedMessageTimestamps: locallyGeneratedMessageTimestamps, cloudReadStates: cloudReadStates, channelsToPollExplicitely: channelsToPollExplicitely), initialPeers: peers, initialReferencedMessageIds: associatedMessageIds, initialStoredMessages: storedMessages, initialReadInboxMaxIds: readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: storedMessagesByPeerIdAndTimestamp)
|
return AccountMutableState(initialState: AccountInitialState(state: (transaction.getState() as? AuthorizedAccountState)!.state!, peerIds: peerIds, peerIdsRequiringLocalChatState: peerIdsRequiringLocalChatState, channelStates: channelStates, peerChatInfos: peerChatInfos, locallyGeneratedMessageTimestamps: locallyGeneratedMessageTimestamps, cloudReadStates: cloudReadStates, channelsToPollExplicitely: channelsToPollExplicitely), initialPeers: peers, initialReferencedMessageIds: associatedMessageIds, initialStoredMessages: storedMessages, initialReadInboxMaxIds: readInboxMaxIds, storedMessagesByPeerIdAndTimestamp: storedMessagesByPeerIdAndTimestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initialStateWithUpdateGroups(postbox: Postbox, groups: [UpdateGroup]) -> Signal<AccountMutableState, NoError> {
|
func initialStateWithUpdateGroups(postbox: Postbox, groups: [UpdateGroup]) -> Signal<AccountMutableState, NoError> {
|
||||||
@ -772,7 +772,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
|||||||
case let .updateChannelTooLong(_, channelId, channelPts):
|
case let .updateChannelTooLong(_, channelId, channelPts):
|
||||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
|
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
|
||||||
if !channelsToPoll.contains(peerId) {
|
if !channelsToPoll.contains(peerId) {
|
||||||
if let channelPts = channelPts, let channelState = state.chatStates[peerId] as? ChannelState, channelState.pts >= channelPts {
|
if let channelPts = channelPts, let channelState = state.channelStates[peerId], channelState.pts >= channelPts {
|
||||||
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) skip updateChannelTooLong by pts")
|
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) skip updateChannelTooLong by pts")
|
||||||
} else {
|
} else {
|
||||||
channelsToPoll.insert(peerId)
|
channelsToPoll.insert(peerId)
|
||||||
@ -780,12 +780,12 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
|||||||
}
|
}
|
||||||
case let .updateDeleteChannelMessages(channelId, messages, pts: pts, ptsCount):
|
case let .updateDeleteChannelMessages(channelId, messages, pts: pts, ptsCount):
|
||||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
|
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
|
||||||
if let previousState = updatedState.chatStates[peerId] as? ChannelState {
|
if let previousState = updatedState.channelStates[peerId] {
|
||||||
if previousState.pts >= pts {
|
if previousState.pts >= pts {
|
||||||
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) skip old delete update")
|
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) skip old delete update")
|
||||||
} else if previousState.pts + ptsCount == pts {
|
} else if previousState.pts + ptsCount == pts {
|
||||||
updatedState.deleteMessages(messages.map({ MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: $0) }))
|
updatedState.deleteMessages(messages.map({ MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: $0) }))
|
||||||
updatedState.updateChannelState(peerId, state: previousState.withUpdatedPts(pts))
|
updatedState.updateChannelState(peerId, pts: pts)
|
||||||
} else {
|
} else {
|
||||||
if !channelsToPoll.contains(peerId) {
|
if !channelsToPoll.contains(peerId) {
|
||||||
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) delete pts hole")
|
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) delete pts hole")
|
||||||
@ -802,7 +802,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
|||||||
case let .updateEditChannelMessage(apiMessage, pts, ptsCount):
|
case let .updateEditChannelMessage(apiMessage, pts, ptsCount):
|
||||||
if let message = StoreMessage(apiMessage: apiMessage), case let .Id(messageId) = message.id {
|
if let message = StoreMessage(apiMessage: apiMessage), case let .Id(messageId) = message.id {
|
||||||
let peerId = messageId.peerId
|
let peerId = messageId.peerId
|
||||||
if let previousState = updatedState.chatStates[peerId] as? ChannelState {
|
if let previousState = updatedState.channelStates[peerId] {
|
||||||
if previousState.pts >= pts {
|
if previousState.pts >= pts {
|
||||||
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) skip old edit update")
|
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) skip old edit update")
|
||||||
} else if previousState.pts + ptsCount == pts {
|
} else if previousState.pts + ptsCount == pts {
|
||||||
@ -814,7 +814,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
|||||||
var attributes = message.attributes
|
var attributes = message.attributes
|
||||||
attributes.append(ChannelMessageStateVersionAttribute(pts: pts))
|
attributes.append(ChannelMessageStateVersionAttribute(pts: pts))
|
||||||
updatedState.editMessage(messageId, message: message.withUpdatedAttributes(attributes))
|
updatedState.editMessage(messageId, message: message.withUpdatedAttributes(attributes))
|
||||||
updatedState.updateChannelState(peerId, state: previousState.withUpdatedPts(pts))
|
updatedState.updateChannelState(peerId, pts: pts)
|
||||||
} else {
|
} else {
|
||||||
if !channelsToPoll.contains(peerId) {
|
if !channelsToPoll.contains(peerId) {
|
||||||
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) edit message pts hole")
|
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) edit message pts hole")
|
||||||
@ -833,7 +833,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
|||||||
}
|
}
|
||||||
case let .updateChannelWebPage(channelId, apiWebpage, pts, ptsCount):
|
case let .updateChannelWebPage(channelId, apiWebpage, pts, ptsCount):
|
||||||
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
|
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
|
||||||
if let previousState = updatedState.chatStates[peerId] as? ChannelState {
|
if let previousState = updatedState.channelStates[peerId] {
|
||||||
if previousState.pts >= pts {
|
if previousState.pts >= pts {
|
||||||
} else if previousState.pts + ptsCount == pts {
|
} else if previousState.pts + ptsCount == pts {
|
||||||
switch apiWebpage {
|
switch apiWebpage {
|
||||||
@ -845,7 +845,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedState.updateChannelState(peerId, state: previousState.withUpdatedPts(pts))
|
updatedState.updateChannelState(peerId, pts: pts)
|
||||||
} else {
|
} else {
|
||||||
if !channelsToPoll.contains(peerId) {
|
if !channelsToPoll.contains(peerId) {
|
||||||
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) updateWebPage pts hole")
|
Logger.shared.log("State", "channel \(peerId) (\((updatedState.peers[peerId] as? TelegramChannel)?.title ?? "nil")) updateWebPage pts hole")
|
||||||
@ -880,7 +880,7 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
|||||||
}
|
}
|
||||||
case let .updateNewChannelMessage(apiMessage, pts, ptsCount):
|
case let .updateNewChannelMessage(apiMessage, pts, ptsCount):
|
||||||
if let message = StoreMessage(apiMessage: apiMessage) {
|
if let message = StoreMessage(apiMessage: apiMessage) {
|
||||||
if let previousState = updatedState.chatStates[message.id.peerId] as? ChannelState {
|
if let previousState = updatedState.channelStates[message.id.peerId] {
|
||||||
if previousState.pts >= pts {
|
if previousState.pts >= pts {
|
||||||
let messageText: String
|
let messageText: String
|
||||||
if Logger.shared.redactSensitiveData {
|
if Logger.shared.redactSensitiveData {
|
||||||
@ -898,7 +898,10 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo
|
|||||||
var attributes = message.attributes
|
var attributes = message.attributes
|
||||||
attributes.append(ChannelMessageStateVersionAttribute(pts: pts))
|
attributes.append(ChannelMessageStateVersionAttribute(pts: pts))
|
||||||
updatedState.addMessages([message.withUpdatedAttributes(attributes)], location: .UpperHistoryBlock)
|
updatedState.addMessages([message.withUpdatedAttributes(attributes)], location: .UpperHistoryBlock)
|
||||||
updatedState.updateChannelState(message.id.peerId, state: previousState.withUpdatedPts(pts))
|
updatedState.updateChannelState(message.id.peerId, pts: pts)
|
||||||
|
if case let .Id(id) = message.id {
|
||||||
|
updatedState.updateChannelSynchronizedUntilMessage(id.peerId, id: id.id)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if !channelsToPoll.contains(message.id.peerId) {
|
if !channelsToPoll.contains(message.id.peerId) {
|
||||||
Logger.shared.log("State", "channel \(message.id.peerId) (\((updatedState.peers[message.id.peerId] as? TelegramChannel)?.title ?? "nil")) message pts hole")
|
Logger.shared.log("State", "channel \(message.id.peerId) (\((updatedState.peers[message.id.peerId] as? TelegramChannel)?.title ?? "nil")) message pts hole")
|
||||||
@ -1587,9 +1590,9 @@ private func resolveMissingPeerChatInfos(network: Network, state: AccountMutable
|
|||||||
func keepPollingChannel(postbox: Postbox, network: Network, peerId: PeerId, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
func keepPollingChannel(postbox: Postbox, network: Network, peerId: PeerId, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
||||||
return postbox.transaction { transaction -> Signal<Void, NoError> in
|
return postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||||
if let accountState = (transaction.getState() as? AuthorizedAccountState)?.state, let peer = transaction.getPeer(peerId) {
|
if let accountState = (transaction.getState() as? AuthorizedAccountState)?.state, let peer = transaction.getPeer(peerId) {
|
||||||
var chatStates: [PeerId: PeerChatState] = [:]
|
var channelStates: [PeerId: AccountStateChannelState] = [:]
|
||||||
if let channelState = transaction.getPeerChatState(peerId) as? ChannelState {
|
if let channelState = transaction.getPeerChatState(peerId) as? ChannelState {
|
||||||
chatStates[peerId] = channelState
|
channelStates[peerId] = AccountStateChannelState(pts: channelState.pts)
|
||||||
}
|
}
|
||||||
let initialPeers: [PeerId: Peer] = [peerId: peer]
|
let initialPeers: [PeerId: Peer] = [peerId: peer]
|
||||||
var peerChatInfos: [PeerId: PeerChatInfo] = [:]
|
var peerChatInfos: [PeerId: PeerChatInfo] = [:]
|
||||||
@ -1606,7 +1609,7 @@ func keepPollingChannel(postbox: Postbox, network: Network, peerId: PeerId, stat
|
|||||||
peerChatInfos[peerId] = PeerChatInfo(notificationSettings: notificationSettings)
|
peerChatInfos[peerId] = PeerChatInfo(notificationSettings: notificationSettings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let initialState = AccountMutableState(initialState: AccountInitialState(state: accountState, peerIds: Set(), peerIdsRequiringLocalChatState: Set(), chatStates: chatStates, peerChatInfos: peerChatInfos, locallyGeneratedMessageTimestamps: [:], cloudReadStates: [:], channelsToPollExplicitely: Set()), initialPeers: initialPeers, initialReferencedMessageIds: Set(), initialStoredMessages: Set(), initialReadInboxMaxIds: [:], storedMessagesByPeerIdAndTimestamp: [:])
|
let initialState = AccountMutableState(initialState: AccountInitialState(state: accountState, peerIds: Set(), peerIdsRequiringLocalChatState: Set(), channelStates: channelStates, peerChatInfos: peerChatInfos, locallyGeneratedMessageTimestamps: [:], cloudReadStates: [:], channelsToPollExplicitely: Set()), initialPeers: initialPeers, initialReferencedMessageIds: Set(), initialStoredMessages: Set(), initialReadInboxMaxIds: [:], storedMessagesByPeerIdAndTimestamp: [:])
|
||||||
return pollChannel(network: network, peer: peer, state: initialState)
|
return pollChannel(network: network, peer: peer, state: initialState)
|
||||||
|> mapToSignal { (finalState, _, timeout) -> Signal<Void, NoError> in
|
|> mapToSignal { (finalState, _, timeout) -> Signal<Void, NoError> in
|
||||||
return resolveAssociatedMessages(network: network, state: finalState)
|
return resolveAssociatedMessages(network: network, state: finalState)
|
||||||
@ -1657,7 +1660,9 @@ private func resetChannels(network: Network, peers: [Peer], state: AccountMutabl
|
|||||||
var storeMessages: [StoreMessage] = []
|
var storeMessages: [StoreMessage] = []
|
||||||
var readStates: [PeerId: [MessageId.Namespace: PeerReadState]] = [:]
|
var readStates: [PeerId: [MessageId.Namespace: PeerReadState]] = [:]
|
||||||
var mentionTagSummaries: [PeerId: MessageHistoryTagNamespaceSummary] = [:]
|
var mentionTagSummaries: [PeerId: MessageHistoryTagNamespaceSummary] = [:]
|
||||||
var channelStates: [PeerId: ChannelState] = [:]
|
var channelStates: [PeerId: AccountStateChannelState] = [:]
|
||||||
|
var invalidateChannelStates: [PeerId: Int32] = [:]
|
||||||
|
var channelSynchronizedUntilMessage: [PeerId: MessageId.Id] = [:]
|
||||||
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
||||||
|
|
||||||
if let result = result {
|
if let result = result {
|
||||||
@ -1714,7 +1719,8 @@ private func resetChannels(network: Network, peers: [Peer], state: AccountMutabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let apiChannelPts = apiChannelPts {
|
if let apiChannelPts = apiChannelPts {
|
||||||
channelStates[peerId] = ChannelState(pts: apiChannelPts, invalidatedPts: apiChannelPts, synchronizedUntilMessageId: nil)
|
channelStates[peerId] = AccountStateChannelState(pts: apiChannelPts)
|
||||||
|
invalidateChannelStates[peerId] = apiChannelPts
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings)
|
notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings)
|
||||||
@ -1744,6 +1750,7 @@ private func resetChannels(network: Network, peers: [Peer], state: AccountMutabl
|
|||||||
for message in storeMessages {
|
for message in storeMessages {
|
||||||
if case let .Id(id) = message.id, id.namespace == Namespaces.Message.Cloud {
|
if case let .Id(id) = message.id, id.namespace == Namespaces.Message.Cloud {
|
||||||
updatedState.setNeedsHoleFromPreviousState(peerId: id.peerId, namespace: id.namespace)
|
updatedState.setNeedsHoleFromPreviousState(peerId: id.peerId, namespace: id.namespace)
|
||||||
|
channelSynchronizedUntilMessage[id.peerId] = id.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1766,7 +1773,13 @@ private func resetChannels(network: Network, peers: [Peer], state: AccountMutabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (peerId, channelState) in channelStates {
|
for (peerId, channelState) in channelStates {
|
||||||
updatedState.updateChannelState(peerId, state: channelState)
|
updatedState.updateChannelState(peerId, pts: channelState.pts)
|
||||||
|
}
|
||||||
|
for (peerId, pts) in invalidateChannelStates {
|
||||||
|
updatedState.updateChannelInvalidationPts(peerId, invalidationPts: pts)
|
||||||
|
}
|
||||||
|
for (peerId, id) in channelSynchronizedUntilMessage {
|
||||||
|
updatedState.updateChannelSynchronizedUntilMessage(peerId, id: id)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (peerId, settings) in notificationSettings {
|
for (peerId, settings) in notificationSettings {
|
||||||
@ -1792,7 +1805,7 @@ private func pollChannel(network: Network, peer: Peer, state: AccountMutableStat
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
let pollPts: Int32
|
let pollPts: Int32
|
||||||
if let channelState = state.chatStates[peer.id] as? ChannelState {
|
if let channelState = state.channelStates[peer.id] {
|
||||||
pollPts = channelState.pts
|
pollPts = channelState.pts
|
||||||
} else {
|
} else {
|
||||||
pollPts = 1
|
pollPts = 1
|
||||||
@ -1814,13 +1827,13 @@ private func pollChannel(network: Network, peer: Peer, state: AccountMutableStat
|
|||||||
switch difference {
|
switch difference {
|
||||||
case let .channelDifference(_, pts, timeout, newMessages, otherUpdates, chats, users):
|
case let .channelDifference(_, pts, timeout, newMessages, otherUpdates, chats, users):
|
||||||
apiTimeout = timeout
|
apiTimeout = timeout
|
||||||
let channelState: ChannelState
|
let channelPts: Int32
|
||||||
if let previousState = updatedState.chatStates[peer.id] as? ChannelState {
|
if let _ = updatedState.channelStates[peer.id] {
|
||||||
channelState = previousState.withUpdatedPts(pts)
|
channelPts = pts
|
||||||
} else {
|
} else {
|
||||||
channelState = ChannelState(pts: pts, invalidatedPts: nil, synchronizedUntilMessageId: nil)
|
channelPts = pts
|
||||||
}
|
}
|
||||||
updatedState.updateChannelState(peer.id, state: channelState)
|
updatedState.updateChannelState(peer.id, pts: channelPts)
|
||||||
|
|
||||||
updatedState.mergeChats(chats)
|
updatedState.mergeChats(chats)
|
||||||
updatedState.mergeUsers(users)
|
updatedState.mergeUsers(users)
|
||||||
@ -1833,6 +1846,9 @@ private func pollChannel(network: Network, peer: Peer, state: AccountMutableStat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
updatedState.addMessages([message], location: .UpperHistoryBlock)
|
updatedState.addMessages([message], location: .UpperHistoryBlock)
|
||||||
|
if case let .Id(id) = message.id {
|
||||||
|
updatedState.updateChannelSynchronizedUntilMessage(id.peerId, id: id.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for update in otherUpdates {
|
for update in otherUpdates {
|
||||||
@ -1895,13 +1911,13 @@ private func pollChannel(network: Network, peer: Peer, state: AccountMutableStat
|
|||||||
case let .channelDifferenceEmpty(_, pts, timeout):
|
case let .channelDifferenceEmpty(_, pts, timeout):
|
||||||
apiTimeout = timeout
|
apiTimeout = timeout
|
||||||
|
|
||||||
let channelState: ChannelState
|
let channelPts: Int32
|
||||||
if let previousState = updatedState.chatStates[peer.id] as? ChannelState {
|
if let previousState = updatedState.channelStates[peer.id] {
|
||||||
channelState = previousState.withUpdatedPts(pts)
|
channelPts = pts
|
||||||
} else {
|
} else {
|
||||||
channelState = ChannelState(pts: pts, invalidatedPts: nil, synchronizedUntilMessageId: nil)
|
channelPts = pts
|
||||||
}
|
}
|
||||||
updatedState.updateChannelState(peer.id, state: channelState)
|
updatedState.updateChannelState(peer.id, pts: channelPts)
|
||||||
case let .channelDifferenceTooLong(_, timeout, dialog, messages, chats, users):
|
case let .channelDifferenceTooLong(_, timeout, dialog, messages, chats, users):
|
||||||
apiTimeout = timeout
|
apiTimeout = timeout
|
||||||
|
|
||||||
@ -1917,8 +1933,8 @@ private func pollChannel(network: Network, peer: Peer, state: AccountMutableStat
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let (peer, pts, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount) = parameters {
|
if let (peer, pts, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount) = parameters {
|
||||||
let channelState = ChannelState(pts: pts, invalidatedPts: pts, synchronizedUntilMessageId: nil)
|
updatedState.updateChannelState(peer.peerId, pts: pts)
|
||||||
updatedState.updateChannelState(peer.peerId, state: channelState)
|
updatedState.updateChannelInvalidationPts(peer.peerId, invalidationPts: pts)
|
||||||
|
|
||||||
updatedState.mergeChats(chats)
|
updatedState.mergeChats(chats)
|
||||||
updatedState.mergeUsers(users)
|
updatedState.mergeUsers(users)
|
||||||
@ -1936,6 +1952,7 @@ private func pollChannel(network: Network, peer: Peer, state: AccountMutableStat
|
|||||||
let location: AddMessagesLocation
|
let location: AddMessagesLocation
|
||||||
if case let .Id(id) = message.id, id.id == topMessage {
|
if case let .Id(id) = message.id, id.id == topMessage {
|
||||||
location = .UpperHistoryBlock
|
location = .UpperHistoryBlock
|
||||||
|
updatedState.updateChannelSynchronizedUntilMessage(id.peerId, id: id.id)
|
||||||
} else {
|
} else {
|
||||||
location = .Random
|
location = .Random
|
||||||
}
|
}
|
||||||
@ -2007,9 +2024,9 @@ private func verifyTransaction(_ transaction: Transaction, finalState: AccountMu
|
|||||||
for peerId in channelsWithUpdatedStates {
|
for peerId in channelsWithUpdatedStates {
|
||||||
let currentState = transaction.getPeerChatState(peerId)
|
let currentState = transaction.getPeerChatState(peerId)
|
||||||
var previousStateMatches = false
|
var previousStateMatches = false
|
||||||
let previousState = finalState.initialState.chatStates[peerId] as? ChannelState
|
let previousState = finalState.initialState.channelStates[peerId]
|
||||||
if let currentState = currentState, let previousState = previousState {
|
if let currentState = currentState as? ChannelState, let previousState = previousState {
|
||||||
if currentState.equals(previousState) {
|
if currentState.pts == previousState.pts {
|
||||||
previousStateMatches = true
|
previousStateMatches = true
|
||||||
}
|
}
|
||||||
} else if currentState == nil && previousState == nil {
|
} else if currentState == nil && previousState == nil {
|
||||||
@ -2048,7 +2065,9 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
|
|||||||
var result: [AccountStateMutationOperation] = []
|
var result: [AccountStateMutationOperation] = []
|
||||||
|
|
||||||
var updatedState: AuthorizedAccountState.State?
|
var updatedState: AuthorizedAccountState.State?
|
||||||
var updatedChannelStates: [PeerId: ChannelState] = [:]
|
var updatedChannelStates: [PeerId: AccountStateChannelState] = [:]
|
||||||
|
var invalidateChannelPts: [PeerId: Int32] = [:]
|
||||||
|
var updateChannelSynchronizedUntilMessage: [PeerId: MessageId.Id] = [:]
|
||||||
|
|
||||||
var currentAddMessages: OptimizeAddMessagesState?
|
var currentAddMessages: OptimizeAddMessagesState?
|
||||||
var currentAddScheduledMessages: OptimizeAddMessagesState?
|
var currentAddScheduledMessages: OptimizeAddMessagesState?
|
||||||
@ -2065,8 +2084,12 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
|
|||||||
result.append(operation)
|
result.append(operation)
|
||||||
case let .UpdateState(state):
|
case let .UpdateState(state):
|
||||||
updatedState = state
|
updatedState = state
|
||||||
case let .UpdateChannelState(peerId, state):
|
case let .UpdateChannelState(peerId, pts):
|
||||||
updatedChannelStates[peerId] = state
|
updatedChannelStates[peerId] = AccountStateChannelState(pts: pts)
|
||||||
|
case let .UpdateChannelInvalidationPts(peerId, pts):
|
||||||
|
invalidateChannelPts[peerId] = pts
|
||||||
|
case let .UpdateChannelSynchronizedUntilMessage(peerId, id):
|
||||||
|
updateChannelSynchronizedUntilMessage[peerId] = id
|
||||||
case let .AddMessages(messages, location):
|
case let .AddMessages(messages, location):
|
||||||
if let currentAddMessages = currentAddMessages, currentAddMessages.location == location {
|
if let currentAddMessages = currentAddMessages, currentAddMessages.location == location {
|
||||||
currentAddMessages.messages.append(contentsOf: messages)
|
currentAddMessages.messages.append(contentsOf: messages)
|
||||||
@ -2097,7 +2120,15 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (peerId, state) in updatedChannelStates {
|
for (peerId, state) in updatedChannelStates {
|
||||||
result.append(.UpdateChannelState(peerId, state))
|
result.append(.UpdateChannelState(peerId, state.pts))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (peerId, pts) in invalidateChannelPts {
|
||||||
|
result.append(.UpdateChannelInvalidationPts(peerId, pts))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (peerId, id) in updateChannelSynchronizedUntilMessage {
|
||||||
|
result.append(.UpdateChannelSynchronizedUntilMessage(peerId, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -2144,8 +2175,18 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
|
|||||||
|
|
||||||
for (peerId, namespaces) in finalState.state.namespacesWithHolesFromPreviousState {
|
for (peerId, namespaces) in finalState.state.namespacesWithHolesFromPreviousState {
|
||||||
for namespace in namespaces {
|
for namespace in namespaces {
|
||||||
if let id = transaction.getTopPeerMessageId(peerId: peerId, namespace: namespace) {
|
var topId: Int32?
|
||||||
holesFromPreviousStateMessageIds.append(MessageId(peerId: id.peerId, namespace: id.namespace, id: id.id + 1))
|
if namespace == Namespaces.Message.Cloud, let channelState = transaction.getPeerChatState(peerId) as? ChannelState {
|
||||||
|
if let synchronizedUntilMessageId = channelState.synchronizedUntilMessageId {
|
||||||
|
topId = synchronizedUntilMessageId + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if topId == nil {
|
||||||
|
topId = transaction.getTopPeerMessageId(peerId: peerId, namespace: namespace)?.id
|
||||||
|
}
|
||||||
|
|
||||||
|
if let id = topId {
|
||||||
|
holesFromPreviousStateMessageIds.append(MessageId(peerId: peerId, namespace: namespace, id: id + 1))
|
||||||
} else {
|
} else {
|
||||||
holesFromPreviousStateMessageIds.append(MessageId(peerId: peerId, namespace: namespace, id: 1))
|
holesFromPreviousStateMessageIds.append(MessageId(peerId: peerId, namespace: namespace, id: 1))
|
||||||
}
|
}
|
||||||
@ -2494,9 +2535,21 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP
|
|||||||
let currentState = transaction.getState() as! AuthorizedAccountState
|
let currentState = transaction.getState() as! AuthorizedAccountState
|
||||||
transaction.setState(currentState.changedState(state))
|
transaction.setState(currentState.changedState(state))
|
||||||
Logger.shared.log("State", "apply state \(state)")
|
Logger.shared.log("State", "apply state \(state)")
|
||||||
case let .UpdateChannelState(peerId, channelState):
|
case let .UpdateChannelState(peerId, pts):
|
||||||
transaction.setPeerChatState(peerId, state: channelState)
|
var state = (transaction.getPeerChatState(peerId) as? ChannelState) ?? ChannelState(pts: pts, invalidatedPts: nil, synchronizedUntilMessageId: nil)
|
||||||
Logger.shared.log("State", "apply channel state \(peerId): \(channelState)")
|
state = state.withUpdatedPts(pts)
|
||||||
|
transaction.setPeerChatState(peerId, state: state)
|
||||||
|
Logger.shared.log("State", "apply channel state \(peerId): \(state)")
|
||||||
|
case let .UpdateChannelInvalidationPts(peerId, pts):
|
||||||
|
var state = (transaction.getPeerChatState(peerId) as? ChannelState) ?? ChannelState(pts: 0, invalidatedPts: pts, synchronizedUntilMessageId: nil)
|
||||||
|
state = state.withUpdatedInvalidatedPts(pts)
|
||||||
|
transaction.setPeerChatState(peerId, state: state)
|
||||||
|
Logger.shared.log("State", "apply channel invalidation pts \(peerId): \(state)")
|
||||||
|
case let .UpdateChannelSynchronizedUntilMessage(peerId, id):
|
||||||
|
var state = (transaction.getPeerChatState(peerId) as? ChannelState) ?? ChannelState(pts: 0, invalidatedPts: nil, synchronizedUntilMessageId: id)
|
||||||
|
state = state.withUpdatedSynchronizedUntilMessageId(id)
|
||||||
|
transaction.setPeerChatState(peerId, state: state)
|
||||||
|
Logger.shared.log("State", "apply channel synchronized until message \(peerId): \(state)")
|
||||||
case let .UpdateNotificationSettings(subject, notificationSettings):
|
case let .UpdateNotificationSettings(subject, notificationSettings):
|
||||||
switch subject {
|
switch subject {
|
||||||
case let .peer(peerId):
|
case let .peer(peerId):
|
||||||
|
@ -564,7 +564,7 @@ private func loadAndStorePeerChatInfos(accountPeerId: PeerId, postbox: Postbox,
|
|||||||
var peers: [Peer] = []
|
var peers: [Peer] = []
|
||||||
var peerPresences: [PeerId: PeerPresence] = [:]
|
var peerPresences: [PeerId: PeerPresence] = [:]
|
||||||
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
||||||
var channelStates: [PeerId: ChannelState] = [:]
|
var channelStates: [PeerId: Int32] = [:]
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case let .peerDialogs(dialogs, messages, chats, users, _):
|
case let .peerDialogs(dialogs, messages, chats, users, _):
|
||||||
@ -644,9 +644,10 @@ private func loadAndStorePeerChatInfos(accountPeerId: PeerId, postbox: Postbox,
|
|||||||
transaction.replaceMessageTagSummary(peerId: peerId, tagMask: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud, count: unreadMentionsCount, maxId: topMessage)
|
transaction.replaceMessageTagSummary(peerId: peerId, tagMask: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud, count: unreadMentionsCount, maxId: topMessage)
|
||||||
|
|
||||||
if let pts = pts {
|
if let pts = pts {
|
||||||
let channelState = ChannelState(pts: pts, invalidatedPts: pts, synchronizedUntilMessageId: nil)
|
if transaction.getPeerChatState(peerId) == nil {
|
||||||
transaction.setPeerChatState(peerId, state: channelState)
|
transaction.setPeerChatState(peerId, state: ChannelState(pts: pts, invalidatedPts: nil, synchronizedUntilMessageId: nil))
|
||||||
channelStates[peer.peerId] = channelState
|
}
|
||||||
|
channelStates[peer.peerId] = pts
|
||||||
}
|
}
|
||||||
case .dialogFolder:
|
case .dialogFolder:
|
||||||
assertionFailure()
|
assertionFailure()
|
||||||
@ -659,9 +660,9 @@ private func loadAndStorePeerChatInfos(accountPeerId: PeerId, postbox: Postbox,
|
|||||||
if let storeMessage = StoreMessage(apiMessage: message) {
|
if let storeMessage = StoreMessage(apiMessage: message) {
|
||||||
var updatedStoreMessage = storeMessage
|
var updatedStoreMessage = storeMessage
|
||||||
if case let .Id(id) = storeMessage.id {
|
if case let .Id(id) = storeMessage.id {
|
||||||
if let channelState = channelStates[id.peerId] {
|
if let channelPts = channelStates[id.peerId] {
|
||||||
var updatedAttributes = storeMessage.attributes
|
var updatedAttributes = storeMessage.attributes
|
||||||
updatedAttributes.append(ChannelMessageStateVersionAttribute(pts: channelState.pts))
|
updatedAttributes.append(ChannelMessageStateVersionAttribute(pts: channelPts))
|
||||||
updatedStoreMessage = updatedStoreMessage.withUpdatedAttributes(updatedAttributes)
|
updatedStoreMessage = updatedStoreMessage.withUpdatedAttributes(updatedAttributes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ struct ParsedDialogs {
|
|||||||
let notificationSettings: [PeerId: PeerNotificationSettings]
|
let notificationSettings: [PeerId: PeerNotificationSettings]
|
||||||
let readStates: [PeerId: [MessageId.Namespace: PeerReadState]]
|
let readStates: [PeerId: [MessageId.Namespace: PeerReadState]]
|
||||||
let mentionTagSummaries: [PeerId: MessageHistoryTagNamespaceSummary]
|
let mentionTagSummaries: [PeerId: MessageHistoryTagNamespaceSummary]
|
||||||
let chatStates: [PeerId: PeerChatState]
|
let channelStates: [PeerId: Int32]
|
||||||
let topMessageIds: [PeerId: MessageId]
|
let topMessageIds: [PeerId: MessageId]
|
||||||
let storeMessages: [StoreMessage]
|
let storeMessages: [StoreMessage]
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ private func parseDialogs(apiDialogs: [Api.Dialog], apiMessages: [Api.Message],
|
|||||||
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
||||||
var readStates: [PeerId: [MessageId.Namespace: PeerReadState]] = [:]
|
var readStates: [PeerId: [MessageId.Namespace: PeerReadState]] = [:]
|
||||||
var mentionTagSummaries: [PeerId: MessageHistoryTagNamespaceSummary] = [:]
|
var mentionTagSummaries: [PeerId: MessageHistoryTagNamespaceSummary] = [:]
|
||||||
var chatStates: [PeerId: PeerChatState] = [:]
|
var channelStates: [PeerId: Int32] = [:]
|
||||||
var topMessageIds: [PeerId: MessageId] = [:]
|
var topMessageIds: [PeerId: MessageId] = [:]
|
||||||
|
|
||||||
var storeMessages: [StoreMessage] = []
|
var storeMessages: [StoreMessage] = []
|
||||||
@ -131,7 +131,7 @@ private func parseDialogs(apiDialogs: [Api.Dialog], apiMessages: [Api.Message],
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let apiChannelPts = apiChannelPts {
|
if let apiChannelPts = apiChannelPts {
|
||||||
chatStates[peerId] = ChannelState(pts: apiChannelPts, invalidatedPts: nil, synchronizedUntilMessageId: nil)
|
channelStates[peerId] = apiChannelPts
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings)
|
notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings)
|
||||||
@ -149,9 +149,9 @@ private func parseDialogs(apiDialogs: [Api.Dialog], apiMessages: [Api.Message],
|
|||||||
if let storeMessage = StoreMessage(apiMessage: message) {
|
if let storeMessage = StoreMessage(apiMessage: message) {
|
||||||
var updatedStoreMessage = storeMessage
|
var updatedStoreMessage = storeMessage
|
||||||
if case let .Id(id) = storeMessage.id {
|
if case let .Id(id) = storeMessage.id {
|
||||||
if let channelState = chatStates[id.peerId] as? ChannelState {
|
if let channelPts = channelStates[id.peerId] {
|
||||||
var updatedAttributes = storeMessage.attributes
|
var updatedAttributes = storeMessage.attributes
|
||||||
updatedAttributes.append(ChannelMessageStateVersionAttribute(pts: channelState.pts))
|
updatedAttributes.append(ChannelMessageStateVersionAttribute(pts: channelPts))
|
||||||
updatedStoreMessage = updatedStoreMessage.withUpdatedAttributes(updatedAttributes)
|
updatedStoreMessage = updatedStoreMessage.withUpdatedAttributes(updatedAttributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ private func parseDialogs(apiDialogs: [Api.Dialog], apiMessages: [Api.Message],
|
|||||||
notificationSettings: notificationSettings,
|
notificationSettings: notificationSettings,
|
||||||
readStates: readStates,
|
readStates: readStates,
|
||||||
mentionTagSummaries: mentionTagSummaries,
|
mentionTagSummaries: mentionTagSummaries,
|
||||||
chatStates: chatStates,
|
channelStates: channelStates,
|
||||||
topMessageIds: topMessageIds,
|
topMessageIds: topMessageIds,
|
||||||
storeMessages: storeMessages,
|
storeMessages: storeMessages,
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ struct FetchedChatList {
|
|||||||
let notificationSettings: [PeerId: PeerNotificationSettings]
|
let notificationSettings: [PeerId: PeerNotificationSettings]
|
||||||
let readStates: [PeerId: [MessageId.Namespace: PeerReadState]]
|
let readStates: [PeerId: [MessageId.Namespace: PeerReadState]]
|
||||||
let mentionTagSummaries: [PeerId: MessageHistoryTagNamespaceSummary]
|
let mentionTagSummaries: [PeerId: MessageHistoryTagNamespaceSummary]
|
||||||
let chatStates: [PeerId: PeerChatState]
|
let channelStates: [PeerId: Int32]
|
||||||
let storeMessages: [StoreMessage]
|
let storeMessages: [StoreMessage]
|
||||||
let topMessageIds: [PeerId: MessageId]
|
let topMessageIds: [PeerId: MessageId]
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ func fetchChatList(postbox: Postbox, network: Network, location: FetchChatListLo
|
|||||||
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
||||||
var readStates: [PeerId: [MessageId.Namespace: PeerReadState]] = [:]
|
var readStates: [PeerId: [MessageId.Namespace: PeerReadState]] = [:]
|
||||||
var mentionTagSummaries: [PeerId: MessageHistoryTagNamespaceSummary] = [:]
|
var mentionTagSummaries: [PeerId: MessageHistoryTagNamespaceSummary] = [:]
|
||||||
var chatStates: [PeerId: PeerChatState] = [:]
|
var channelStates: [PeerId: Int32] = [:]
|
||||||
var storeMessages: [StoreMessage] = []
|
var storeMessages: [StoreMessage] = []
|
||||||
var topMessageIds: [PeerId: MessageId] = [:]
|
var topMessageIds: [PeerId: MessageId] = [:]
|
||||||
|
|
||||||
@ -304,7 +304,7 @@ func fetchChatList(postbox: Postbox, network: Network, location: FetchChatListLo
|
|||||||
notificationSettings.merge(parsedRemoteChats.notificationSettings, uniquingKeysWith: { _, updated in updated })
|
notificationSettings.merge(parsedRemoteChats.notificationSettings, uniquingKeysWith: { _, updated in updated })
|
||||||
readStates.merge(parsedRemoteChats.readStates, uniquingKeysWith: { _, updated in updated })
|
readStates.merge(parsedRemoteChats.readStates, uniquingKeysWith: { _, updated in updated })
|
||||||
mentionTagSummaries.merge(parsedRemoteChats.mentionTagSummaries, uniquingKeysWith: { _, updated in updated })
|
mentionTagSummaries.merge(parsedRemoteChats.mentionTagSummaries, uniquingKeysWith: { _, updated in updated })
|
||||||
chatStates.merge(parsedRemoteChats.chatStates, uniquingKeysWith: { _, updated in updated })
|
channelStates.merge(parsedRemoteChats.channelStates, uniquingKeysWith: { _, updated in updated })
|
||||||
storeMessages.append(contentsOf: parsedRemoteChats.storeMessages)
|
storeMessages.append(contentsOf: parsedRemoteChats.storeMessages)
|
||||||
topMessageIds.merge(parsedRemoteChats.topMessageIds, uniquingKeysWith: { _, updated in updated })
|
topMessageIds.merge(parsedRemoteChats.topMessageIds, uniquingKeysWith: { _, updated in updated })
|
||||||
|
|
||||||
@ -314,7 +314,7 @@ func fetchChatList(postbox: Postbox, network: Network, location: FetchChatListLo
|
|||||||
notificationSettings.merge(parsedPinnedChats.notificationSettings, uniquingKeysWith: { _, updated in updated })
|
notificationSettings.merge(parsedPinnedChats.notificationSettings, uniquingKeysWith: { _, updated in updated })
|
||||||
readStates.merge(parsedPinnedChats.readStates, uniquingKeysWith: { _, updated in updated })
|
readStates.merge(parsedPinnedChats.readStates, uniquingKeysWith: { _, updated in updated })
|
||||||
mentionTagSummaries.merge(parsedPinnedChats.mentionTagSummaries, uniquingKeysWith: { _, updated in updated })
|
mentionTagSummaries.merge(parsedPinnedChats.mentionTagSummaries, uniquingKeysWith: { _, updated in updated })
|
||||||
chatStates.merge(parsedPinnedChats.chatStates, uniquingKeysWith: { _, updated in updated })
|
channelStates.merge(parsedPinnedChats.channelStates, uniquingKeysWith: { _, updated in updated })
|
||||||
storeMessages.append(contentsOf: parsedPinnedChats.storeMessages)
|
storeMessages.append(contentsOf: parsedPinnedChats.storeMessages)
|
||||||
topMessageIds.merge(parsedPinnedChats.topMessageIds, uniquingKeysWith: { _, updated in updated })
|
topMessageIds.merge(parsedPinnedChats.topMessageIds, uniquingKeysWith: { _, updated in updated })
|
||||||
}
|
}
|
||||||
@ -336,7 +336,7 @@ func fetchChatList(postbox: Postbox, network: Network, location: FetchChatListLo
|
|||||||
notificationSettings.merge(folderChats.notificationSettings, uniquingKeysWith: { _, updated in updated })
|
notificationSettings.merge(folderChats.notificationSettings, uniquingKeysWith: { _, updated in updated })
|
||||||
readStates.merge(folderChats.readStates, uniquingKeysWith: { _, updated in updated })
|
readStates.merge(folderChats.readStates, uniquingKeysWith: { _, updated in updated })
|
||||||
mentionTagSummaries.merge(folderChats.mentionTagSummaries, uniquingKeysWith: { _, updated in updated })
|
mentionTagSummaries.merge(folderChats.mentionTagSummaries, uniquingKeysWith: { _, updated in updated })
|
||||||
chatStates.merge(folderChats.chatStates, uniquingKeysWith: { _, updated in updated })
|
channelStates.merge(folderChats.channelStates, uniquingKeysWith: { _, updated in updated })
|
||||||
storeMessages.append(contentsOf: folderChats.storeMessages)
|
storeMessages.append(contentsOf: folderChats.storeMessages)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,7 +369,7 @@ func fetchChatList(postbox: Postbox, network: Network, location: FetchChatListLo
|
|||||||
notificationSettings: notificationSettings,
|
notificationSettings: notificationSettings,
|
||||||
readStates: readStates,
|
readStates: readStates,
|
||||||
mentionTagSummaries: mentionTagSummaries,
|
mentionTagSummaries: mentionTagSummaries,
|
||||||
chatStates: chatStates,
|
channelStates: channelStates,
|
||||||
storeMessages: storeMessages,
|
storeMessages: storeMessages,
|
||||||
topMessageIds: topMessageIds,
|
topMessageIds: topMessageIds,
|
||||||
|
|
||||||
|
@ -479,15 +479,11 @@ func fetchChatListHole(postbox: Postbox, network: Network, accountPeerId: PeerId
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (peerId, chatState) in fetchedChats.chatStates {
|
for (peerId, pts) in fetchedChats.channelStates {
|
||||||
if let chatState = chatState as? ChannelState {
|
if let current = transaction.getPeerChatState(peerId) as? ChannelState {
|
||||||
if let current = transaction.getPeerChatState(peerId) as? ChannelState {
|
transaction.setPeerChatState(peerId, state: current.withUpdatedPts(pts))
|
||||||
transaction.setPeerChatState(peerId, state: current.withUpdatedPts(chatState.pts))
|
|
||||||
} else {
|
|
||||||
transaction.setPeerChatState(peerId, state: chatState)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
transaction.setPeerChatState(peerId, state: chatState)
|
transaction.setPeerChatState(peerId, state: ChannelState(pts: pts, invalidatedPts: nil, synchronizedUntilMessageId: nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,70 +2,134 @@ import Foundation
|
|||||||
import Postbox
|
import Postbox
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
|
|
||||||
private final class ManagedSynchronizePeerReadStatesState {
|
private final class SynchronizePeerReadStatesContextImpl {
|
||||||
private var synchronizeDisposables: [PeerId: (PeerReadStateSynchronizationOperation, Disposable)] = [:]
|
private final class Operation {
|
||||||
|
let operation: PeerReadStateSynchronizationOperation
|
||||||
func clearDisposables() -> [Disposable] {
|
let disposable: Disposable
|
||||||
let disposables = Array(self.synchronizeDisposables.values.map({ $0.1 }))
|
|
||||||
self.synchronizeDisposables.removeAll()
|
init(
|
||||||
return disposables
|
operation: PeerReadStateSynchronizationOperation,
|
||||||
|
disposable: Disposable
|
||||||
|
) {
|
||||||
|
self.operation = operation
|
||||||
|
self.disposable = disposable
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.disposable.dispose()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func update(operations: [PeerId: PeerReadStateSynchronizationOperation]) -> (removed: [Disposable], added: [(PeerId, PeerReadStateSynchronizationOperation, MetaDisposable)]) {
|
private let queue: Queue
|
||||||
var removed: [Disposable] = []
|
private let network: Network
|
||||||
var added: [(PeerId, PeerReadStateSynchronizationOperation, MetaDisposable)] = []
|
private let postbox: Postbox
|
||||||
|
private let stateManager: AccountStateManager
|
||||||
|
|
||||||
|
private var disposable: Disposable?
|
||||||
|
|
||||||
|
private var currentState: [PeerId : PeerReadStateSynchronizationOperation] = [:]
|
||||||
|
private var activeOperations: [PeerId: Operation] = [:]
|
||||||
|
private var pendingOperations: [PeerId: PeerReadStateSynchronizationOperation] = [:]
|
||||||
|
|
||||||
|
init(queue: Queue, network: Network, postbox: Postbox, stateManager: AccountStateManager) {
|
||||||
|
self.queue = queue
|
||||||
|
self.network = network
|
||||||
|
self.postbox = postbox
|
||||||
|
self.stateManager = stateManager
|
||||||
|
|
||||||
for (peerId, (operation, disposable)) in self.synchronizeDisposables {
|
self.disposable = (postbox.synchronizePeerReadStatesView()
|
||||||
if operations[peerId] != operation {
|
|> deliverOn(self.queue)).start(next: { [weak self] view in
|
||||||
removed.append(disposable)
|
guard let strongSelf = self else {
|
||||||
self.synchronizeDisposables.removeValue(forKey: peerId)
|
return
|
||||||
|
}
|
||||||
|
strongSelf.currentState = view.operations
|
||||||
|
strongSelf.update()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.disposable?.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
func dispose() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private func update() {
|
||||||
|
let peerIds = Set(self.currentState.keys).union(Set(self.pendingOperations.keys))
|
||||||
|
|
||||||
|
for peerId in peerIds {
|
||||||
|
var maybeOperation: PeerReadStateSynchronizationOperation?
|
||||||
|
if let operation = self.currentState[peerId] {
|
||||||
|
maybeOperation = operation
|
||||||
|
} else if let operation = self.pendingOperations[peerId] {
|
||||||
|
maybeOperation = operation
|
||||||
|
self.pendingOperations.removeValue(forKey: peerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let operation = maybeOperation {
|
||||||
|
if let current = self.activeOperations[peerId] {
|
||||||
|
if current.operation != operation {
|
||||||
|
self.pendingOperations[peerId] = operation
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let operationDisposable = MetaDisposable()
|
||||||
|
let activeOperation = Operation(
|
||||||
|
operation: operation,
|
||||||
|
disposable: operationDisposable
|
||||||
|
)
|
||||||
|
self.activeOperations[peerId] = activeOperation
|
||||||
|
let signal: Signal<Never, NoError>
|
||||||
|
switch operation {
|
||||||
|
case .Validate:
|
||||||
|
signal = synchronizePeerReadState(network: self.network, postbox: self.postbox, stateManager: self.stateManager, peerId: peerId, push: false, validate: true)
|
||||||
|
|> ignoreValues
|
||||||
|
case let .Push(_, thenSync):
|
||||||
|
signal = synchronizePeerReadState(network: self.network, postbox: self.postbox, stateManager: stateManager, peerId: peerId, push: true, validate: thenSync)
|
||||||
|
|> ignoreValues
|
||||||
|
}
|
||||||
|
operationDisposable.set((signal
|
||||||
|
|> deliverOn(self.queue)).start(completed: { [weak self, weak activeOperation] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let activeOperation = activeOperation {
|
||||||
|
if let current = strongSelf.activeOperations[peerId], current === activeOperation {
|
||||||
|
strongSelf.activeOperations.removeValue(forKey: peerId)
|
||||||
|
strongSelf.update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for (peerId, operation) in operations {
|
}
|
||||||
if self.synchronizeDisposables[peerId] == nil {
|
|
||||||
let disposable = MetaDisposable()
|
private final class SynchronizePeerReadStatesStatesContext {
|
||||||
self.synchronizeDisposables[peerId] = (operation, disposable)
|
private let queue: Queue
|
||||||
added.append((peerId, operation, disposable))
|
private let impl: QueueLocalObject<SynchronizePeerReadStatesContextImpl>
|
||||||
}
|
|
||||||
|
init(network: Network, postbox: Postbox, stateManager: AccountStateManager) {
|
||||||
|
self.queue = Queue()
|
||||||
|
let queue = self.queue
|
||||||
|
self.impl = QueueLocalObject(queue: queue, generate: {
|
||||||
|
return SynchronizePeerReadStatesContextImpl(queue: queue, network: network, postbox: postbox, stateManager: stateManager)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func dispose() {
|
||||||
|
self.impl.with { impl in
|
||||||
|
impl.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
return (removed, added)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func managedSynchronizePeerReadStates(network: Network, postbox: Postbox, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
func managedSynchronizePeerReadStates(network: Network, postbox: Postbox, stateManager: AccountStateManager) -> Signal<Void, NoError> {
|
||||||
return Signal { _ in
|
return Signal { _ in
|
||||||
let state = Atomic(value: ManagedSynchronizePeerReadStatesState())
|
let context = SynchronizePeerReadStatesStatesContext(network: network, postbox: postbox, stateManager: stateManager)
|
||||||
|
|
||||||
let disposable = postbox.synchronizePeerReadStatesView().start(next: { view in
|
|
||||||
let (removed, added) = state.with { state -> (removed: [Disposable], added: [(PeerId, PeerReadStateSynchronizationOperation, MetaDisposable)]) in
|
|
||||||
return state.update(operations: view.operations)
|
|
||||||
}
|
|
||||||
|
|
||||||
for disposable in removed {
|
|
||||||
disposable.dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
for (peerId, operation, disposable) in added {
|
|
||||||
let synchronizeOperation: Signal<Void, NoError>
|
|
||||||
switch operation {
|
|
||||||
case .Validate:
|
|
||||||
synchronizeOperation = synchronizePeerReadState(network: network, postbox: postbox, stateManager: stateManager, peerId: peerId, push: false, validate: true)
|
|
||||||
case let .Push(_, thenSync):
|
|
||||||
synchronizeOperation = synchronizePeerReadState(network: network, postbox: postbox, stateManager: stateManager, peerId: peerId, push: true, validate: thenSync)
|
|
||||||
}
|
|
||||||
disposable.set(synchronizeOperation.start())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return ActionDisposable {
|
return ActionDisposable {
|
||||||
disposable.dispose()
|
context.dispose()
|
||||||
for disposable in state.with({ state -> [Disposable] in
|
|
||||||
state.clearDisposables()
|
|
||||||
}) {
|
|
||||||
disposable.dispose()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ private func synchronizePinnedChats(transaction: Transaction, postbox: Postbox,
|
|||||||
|> mapToSignal { dialogs -> Signal<Void, NoError> in
|
|> mapToSignal { dialogs -> Signal<Void, NoError> in
|
||||||
var storeMessages: [StoreMessage] = []
|
var storeMessages: [StoreMessage] = []
|
||||||
var readStates: [PeerId: [MessageId.Namespace: PeerReadState]] = [:]
|
var readStates: [PeerId: [MessageId.Namespace: PeerReadState]] = [:]
|
||||||
var chatStates: [PeerId: PeerChatState] = [:]
|
var channelStates: [PeerId: Int32] = [:]
|
||||||
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
||||||
|
|
||||||
var remoteItemIds: [PinnedItemId] = []
|
var remoteItemIds: [PinnedItemId] = []
|
||||||
@ -200,7 +200,7 @@ private func synchronizePinnedChats(transaction: Transaction, postbox: Postbox,
|
|||||||
readStates[peerId]![Namespaces.Message.Cloud] = .idBased(maxIncomingReadId: apiReadInboxMaxId, maxOutgoingReadId: apiReadOutboxMaxId, maxKnownId: apiTopMessage, count: apiUnreadCount, markedUnread: apiMarkedUnread)
|
readStates[peerId]![Namespaces.Message.Cloud] = .idBased(maxIncomingReadId: apiReadInboxMaxId, maxOutgoingReadId: apiReadOutboxMaxId, maxKnownId: apiTopMessage, count: apiUnreadCount, markedUnread: apiMarkedUnread)
|
||||||
|
|
||||||
if let apiChannelPts = apiChannelPts {
|
if let apiChannelPts = apiChannelPts {
|
||||||
chatStates[peerId] = ChannelState(pts: apiChannelPts, invalidatedPts: nil, synchronizedUntilMessageId: nil)
|
channelStates[peerId] = apiChannelPts
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings)
|
notificationSettings[peerId] = TelegramPeerNotificationSettings(apiSettings: apiNotificationSettings)
|
||||||
@ -245,15 +245,11 @@ private func synchronizePinnedChats(transaction: Transaction, postbox: Postbox,
|
|||||||
|
|
||||||
transaction.resetIncomingReadStates(readStates)
|
transaction.resetIncomingReadStates(readStates)
|
||||||
|
|
||||||
for (peerId, chatState) in chatStates {
|
for (peerId, pts) in channelStates {
|
||||||
if let chatState = chatState as? ChannelState {
|
if let _ = transaction.getPeerChatState(peerId) as? ChannelState {
|
||||||
if let _ = transaction.getPeerChatState(peerId) as? ChannelState {
|
// skip changing state
|
||||||
// skip changing state
|
|
||||||
} else {
|
|
||||||
transaction.setPeerChatState(peerId, state: chatState)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
transaction.setPeerChatState(peerId, state: chatState)
|
transaction.setPeerChatState(peerId, state: ChannelState(pts: pts, invalidatedPts: nil, synchronizedUntilMessageId: nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,8 +49,20 @@ private func canEditMessage(accountPeerId: PeerId, limitsConfiguration: LimitsCo
|
|||||||
}
|
}
|
||||||
} else if message.id.peerId.namespace == Namespaces.Peer.SecretChat || message.id.namespace != Namespaces.Message.Cloud {
|
} else if message.id.peerId.namespace == Namespaces.Peer.SecretChat || message.id.namespace != Namespaces.Message.Cloud {
|
||||||
hasEditRights = false
|
hasEditRights = false
|
||||||
} else if let author = message.author, author.id == accountPeerId {
|
} else if let author = message.author, author.id == accountPeerId, let peer = message.peers[message.id.peerId] {
|
||||||
hasEditRights = true
|
hasEditRights = true
|
||||||
|
if let peer = peer as? TelegramChannel {
|
||||||
|
switch peer.info {
|
||||||
|
case .broadcast:
|
||||||
|
if peer.hasPermission(.editAllMessages) || !message.flags.contains(.Incoming) {
|
||||||
|
unlimitedInterval = true
|
||||||
|
}
|
||||||
|
case .group:
|
||||||
|
if peer.hasPermission(.pinMessages) {
|
||||||
|
unlimitedInterval = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if message.author?.id == message.id.peerId, let peer = message.peers[message.id.peerId] {
|
} else if message.author?.id == message.id.peerId, let peer = message.peers[message.id.peerId] {
|
||||||
if let peer = peer as? TelegramChannel {
|
if let peer = peer as? TelegramChannel {
|
||||||
switch peer.info {
|
switch peer.info {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user