mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-11 08:50:24 +00:00
Temp
This commit is contained in:
parent
8aefa19d31
commit
1fe0d4a75b
@ -1,106 +1 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
/*import PostboxCoding
|
|
||||||
import PreferencesTable
|
|
||||||
import MessageHistoryMetadataTable
|
|
||||||
import PostboxDataTypes
|
|
||||||
|
|
||||||
public enum TotalUnreadCountDisplayStyle: Int32 {
|
|
||||||
case filtered = 0
|
|
||||||
|
|
||||||
var category: ChatListTotalUnreadStateCategory {
|
|
||||||
switch self {
|
|
||||||
case .filtered:
|
|
||||||
return .filtered
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum TotalUnreadCountDisplayCategory: Int32 {
|
|
||||||
case chats = 0
|
|
||||||
case messages = 1
|
|
||||||
|
|
||||||
var statsType: ChatListTotalUnreadStateStats {
|
|
||||||
switch self {
|
|
||||||
case .chats:
|
|
||||||
return .chats
|
|
||||||
case .messages:
|
|
||||||
return .messages
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct InAppNotificationSettings: PreferencesEntry, Equatable {
|
|
||||||
public var playSounds: Bool
|
|
||||||
public var vibrate: Bool
|
|
||||||
public var displayPreviews: Bool
|
|
||||||
public var totalUnreadCountDisplayStyle: TotalUnreadCountDisplayStyle
|
|
||||||
public var totalUnreadCountDisplayCategory: TotalUnreadCountDisplayCategory
|
|
||||||
public var totalUnreadCountIncludeTags: PeerSummaryCounterTags
|
|
||||||
public var displayNameOnLockscreen: Bool
|
|
||||||
public var displayNotificationsFromAllAccounts: Bool
|
|
||||||
|
|
||||||
public static var defaultSettings: InAppNotificationSettings {
|
|
||||||
return InAppNotificationSettings(playSounds: true, vibrate: false, displayPreviews: true, totalUnreadCountDisplayStyle: .filtered, totalUnreadCountDisplayCategory: .messages, totalUnreadCountIncludeTags: [.privateChat, .secretChat, .bot, .privateGroup], displayNameOnLockscreen: true, displayNotificationsFromAllAccounts: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
public init(playSounds: Bool, vibrate: Bool, displayPreviews: Bool, totalUnreadCountDisplayStyle: TotalUnreadCountDisplayStyle, totalUnreadCountDisplayCategory: TotalUnreadCountDisplayCategory, totalUnreadCountIncludeTags: PeerSummaryCounterTags, displayNameOnLockscreen: Bool, displayNotificationsFromAllAccounts: Bool) {
|
|
||||||
self.playSounds = playSounds
|
|
||||||
self.vibrate = vibrate
|
|
||||||
self.displayPreviews = displayPreviews
|
|
||||||
self.totalUnreadCountDisplayStyle = totalUnreadCountDisplayStyle
|
|
||||||
self.totalUnreadCountDisplayCategory = totalUnreadCountDisplayCategory
|
|
||||||
self.totalUnreadCountIncludeTags = totalUnreadCountIncludeTags
|
|
||||||
self.displayNameOnLockscreen = displayNameOnLockscreen
|
|
||||||
self.displayNotificationsFromAllAccounts = displayNotificationsFromAllAccounts
|
|
||||||
}
|
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
|
||||||
self.playSounds = decoder.decodeInt32ForKey("s", orElse: 0) != 0
|
|
||||||
self.vibrate = decoder.decodeInt32ForKey("v", orElse: 0) != 0
|
|
||||||
self.displayPreviews = decoder.decodeInt32ForKey("p", orElse: 0) != 0
|
|
||||||
self.totalUnreadCountDisplayStyle = TotalUnreadCountDisplayStyle(rawValue: decoder.decodeInt32ForKey("cds", orElse: 0)) ?? .filtered
|
|
||||||
self.totalUnreadCountDisplayCategory = TotalUnreadCountDisplayCategory(rawValue: decoder.decodeInt32ForKey("totalUnreadCountDisplayCategory", orElse: 1)) ?? .messages
|
|
||||||
if let value = decoder.decodeOptionalInt32ForKey("totalUnreadCountIncludeTags_2") {
|
|
||||||
self.totalUnreadCountIncludeTags = PeerSummaryCounterTags(rawValue: value)
|
|
||||||
} else if let value = decoder.decodeOptionalInt32ForKey("totalUnreadCountIncludeTags") {
|
|
||||||
var resultTags: PeerSummaryCounterTags = []
|
|
||||||
for legacyTag in LegacyPeerSummaryCounterTags(rawValue: value) {
|
|
||||||
if legacyTag == .regularChatsAndPrivateGroups {
|
|
||||||
resultTags.insert(.privateChat)
|
|
||||||
resultTags.insert(.secretChat)
|
|
||||||
resultTags.insert(.bot)
|
|
||||||
resultTags.insert(.privateGroup)
|
|
||||||
} else if legacyTag == .publicGroups {
|
|
||||||
resultTags.insert(.publicGroup)
|
|
||||||
} else if legacyTag == .channels {
|
|
||||||
resultTags.insert(.channel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.totalUnreadCountIncludeTags = resultTags
|
|
||||||
} else {
|
|
||||||
self.totalUnreadCountIncludeTags = [.privateChat, .secretChat, .bot, .privateGroup]
|
|
||||||
}
|
|
||||||
self.displayNameOnLockscreen = decoder.decodeInt32ForKey("displayNameOnLockscreen", orElse: 1) != 0
|
|
||||||
self.displayNotificationsFromAllAccounts = decoder.decodeInt32ForKey("displayNotificationsFromAllAccounts", orElse: 1) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
|
||||||
encoder.encodeInt32(self.playSounds ? 1 : 0, forKey: "s")
|
|
||||||
encoder.encodeInt32(self.vibrate ? 1 : 0, forKey: "v")
|
|
||||||
encoder.encodeInt32(self.displayPreviews ? 1 : 0, forKey: "p")
|
|
||||||
encoder.encodeInt32(self.totalUnreadCountDisplayStyle.rawValue, forKey: "cds")
|
|
||||||
encoder.encodeInt32(self.totalUnreadCountDisplayCategory.rawValue, forKey: "totalUnreadCountDisplayCategory")
|
|
||||||
encoder.encodeInt32(self.totalUnreadCountIncludeTags.rawValue, forKey: "totalUnreadCountIncludeTags_2")
|
|
||||||
encoder.encodeInt32(self.displayNameOnLockscreen ? 1 : 0, forKey: "displayNameOnLockscreen")
|
|
||||||
encoder.encodeInt32(self.displayNotificationsFromAllAccounts ? 1 : 0, forKey: "displayNotificationsFromAllAccounts")
|
|
||||||
}
|
|
||||||
|
|
||||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
|
||||||
if let to = to as? InAppNotificationSettings {
|
|
||||||
return self == to
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|||||||
@ -6766,7 +6766,9 @@ Sorry for the inconvenience.";
|
|||||||
"Channel.AdminLog.MessageChangedThemeRemove" = "%1$@ disabled chat theme";
|
"Channel.AdminLog.MessageChangedThemeRemove" = "%1$@ disabled chat theme";
|
||||||
|
|
||||||
"SponsoredMessageMenu.Info" = "What are sponsored\nmessages?";
|
"SponsoredMessageMenu.Info" = "What are sponsored\nmessages?";
|
||||||
"SponsoredMessageInfo.Text" = "See https://telegram.org";
|
"SponsoredMessageInfo.Text" = "Unlike other apps, Telegram never uses your private data to target ads. No user data is mined or analyzed to display ads, and every user viewing a channel on Telegram sees the same sponsored message. We believe that everyone has the right to privacy, and technological platforms should respect that.
|
||||||
|
|
||||||
|
More at: https://ads.telegram.org";
|
||||||
"SponsoredMessageInfo.Action" = "Learn More";
|
"SponsoredMessageInfo.Action" = "Learn More";
|
||||||
"SponsoredMessageInfo.ActionUrl" = "https://telegram.org";
|
"SponsoredMessageInfo.ActionUrl" = "https://telegram.org";
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,9 @@ swift_library(
|
|||||||
srcs = glob([
|
srcs = glob([
|
||||||
"Sources/**/*.swift",
|
"Sources/**/*.swift",
|
||||||
]),
|
]),
|
||||||
|
copts = [
|
||||||
|
"-warnings-as-errors",
|
||||||
|
],
|
||||||
deps = [
|
deps = [
|
||||||
"//submodules/Crc32:Crc32",
|
"//submodules/Crc32:Crc32",
|
||||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||||
|
|||||||
@ -11,8 +11,8 @@ final class AccountManagerSharedDataTable: Table {
|
|||||||
func get(key: ValueBoxKey) -> PreferencesEntry? {
|
func get(key: ValueBoxKey) -> PreferencesEntry? {
|
||||||
if let object = self.values[key] {
|
if let object = self.values[key] {
|
||||||
return object
|
return object
|
||||||
} else if let value = self.valueBox.get(self.table, key: key), let object = PostboxDecoder(buffer: value).decodeRootObject() as? PreferencesEntry {
|
} else if let value = self.valueBox.get(self.table, key: key) {
|
||||||
return object
|
return PreferencesEntry(data: value.makeData())
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -20,12 +20,10 @@ final class AccountManagerSharedDataTable: Table {
|
|||||||
|
|
||||||
func set(key: ValueBoxKey, value: PreferencesEntry?, updatedKeys: inout Set<ValueBoxKey>) {
|
func set(key: ValueBoxKey, value: PreferencesEntry?, updatedKeys: inout Set<ValueBoxKey>) {
|
||||||
if let value = value {
|
if let value = value {
|
||||||
if let current = self.get(key: key), current.isEqual(to: value) {
|
if let current = self.get(key: key), current == value {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let encoder = PostboxEncoder()
|
self.valueBox.set(self.table, key: key, value: ReadBuffer(data: value.data))
|
||||||
encoder.encodeRootObject(value)
|
|
||||||
self.valueBox.set(self.table, key: key, value: encoder.makeReadBufferAndReset())
|
|
||||||
updatedKeys.insert(key)
|
updatedKeys.insert(key)
|
||||||
|
|
||||||
self.values[key] = value
|
self.values[key] = value
|
||||||
|
|||||||
@ -10,10 +10,6 @@ public struct ChatListHole: Hashable, CustomStringConvertible {
|
|||||||
public var description: String {
|
public var description: String {
|
||||||
return "ChatListHole(\(self.index.id), \(self.index.timestamp))"
|
return "ChatListHole(\(self.index.id), \(self.index.timestamp))"
|
||||||
}
|
}
|
||||||
|
|
||||||
public var hashValue: Int {
|
|
||||||
return self.index.hashValue
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func <(lhs: ChatListHole, rhs: ChatListHole) -> Bool {
|
public static func <(lhs: ChatListHole, rhs: ChatListHole) -> Bool {
|
||||||
return lhs.index < rhs.index
|
return lhs.index < rhs.index
|
||||||
|
|||||||
@ -170,7 +170,7 @@ final class ChatListIndexTable: Table {
|
|||||||
assert(self.updatedPreviousPeerCachedIndices.isEmpty)
|
assert(self.updatedPreviousPeerCachedIndices.isEmpty)
|
||||||
}
|
}
|
||||||
|
|
||||||
func commitWithTransaction(postbox: Postbox, alteredInitialPeerCombinedReadStates: [PeerId: CombinedPeerReadState], updatedPeers: [((Peer, Bool)?, (Peer, Bool))], transactionParticipationInTotalUnreadCountUpdates: (added: Set<PeerId>, removed: Set<PeerId>), updatedTotalUnreadStates: inout [PeerGroupId: ChatListTotalUnreadState], updatedGroupTotalUnreadSummaries: inout [PeerGroupId: PeerGroupUnreadCountersCombinedSummary], currentUpdatedGroupSummarySynchronizeOperations: inout [PeerGroupAndNamespace: Bool]) {
|
func commitWithTransaction(postbox: Postbox, currentTransaction: Transaction, alteredInitialPeerCombinedReadStates: [PeerId: CombinedPeerReadState], updatedPeers: [((Peer, Bool)?, (Peer, Bool))], transactionParticipationInTotalUnreadCountUpdates: (added: Set<PeerId>, removed: Set<PeerId>), updatedTotalUnreadStates: inout [PeerGroupId: ChatListTotalUnreadState], updatedGroupTotalUnreadSummaries: inout [PeerGroupId: PeerGroupUnreadCountersCombinedSummary], currentUpdatedGroupSummarySynchronizeOperations: inout [PeerGroupAndNamespace: Bool]) {
|
||||||
var updatedPeerTags: [PeerId: (previous: PeerSummaryCounterTags, updated: PeerSummaryCounterTags)] = [:]
|
var updatedPeerTags: [PeerId: (previous: PeerSummaryCounterTags, updated: PeerSummaryCounterTags)] = [:]
|
||||||
for (previous, updated) in updatedPeers {
|
for (previous, updated) in updatedPeers {
|
||||||
let previousTags: PeerSummaryCounterTags
|
let previousTags: PeerSummaryCounterTags
|
||||||
@ -339,7 +339,7 @@ final class ChatListIndexTable: Table {
|
|||||||
var updatedTotalStates: [PeerGroupId: ChatListTotalUnreadState] = [:]
|
var updatedTotalStates: [PeerGroupId: ChatListTotalUnreadState] = [:]
|
||||||
var updatedTotalUnreadSummaries: [PeerGroupId: PeerGroupUnreadCountersCombinedSummary] = [:]
|
var updatedTotalUnreadSummaries: [PeerGroupId: PeerGroupUnreadCountersCombinedSummary] = [:]
|
||||||
|
|
||||||
let globalNotificationSettings = postbox.getGlobalNotificationSettings()
|
let globalNotificationSettings = postbox.getGlobalNotificationSettings(transaction: currentTransaction)
|
||||||
|
|
||||||
for peerId in alteredPeerIds {
|
for peerId in alteredPeerIds {
|
||||||
guard let peer = postbox.peerTable.get(peerId) else {
|
guard let peer = postbox.peerTable.get(peerId) else {
|
||||||
@ -556,8 +556,8 @@ final class ChatListIndexTable: Table {
|
|||||||
assert(self.updatedPreviousPeerCachedIndices.isEmpty)
|
assert(self.updatedPreviousPeerCachedIndices.isEmpty)
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugReindexUnreadCounts(postbox: Postbox) -> ([PeerGroupId: ChatListTotalUnreadState], [PeerGroupId: PeerGroupUnreadCountersCombinedSummary]) {
|
func debugReindexUnreadCounts(postbox: Postbox, currentTransaction: Transaction) -> ([PeerGroupId: ChatListTotalUnreadState], [PeerGroupId: PeerGroupUnreadCountersCombinedSummary]) {
|
||||||
let globalNotificationSettings = postbox.getGlobalNotificationSettings()
|
let globalNotificationSettings = postbox.getGlobalNotificationSettings(transaction: currentTransaction)
|
||||||
|
|
||||||
var peerIds: [PeerId] = []
|
var peerIds: [PeerId] = []
|
||||||
for groupId in postbox.chatListTable.existingGroups() + [.root] {
|
for groupId in postbox.chatListTable.existingGroups() + [.root] {
|
||||||
@ -575,7 +575,6 @@ final class ChatListIndexTable: Table {
|
|||||||
}
|
}
|
||||||
let isContact = postbox.contactsTable.isContact(peerId: peerId)
|
let isContact = postbox.contactsTable.isContact(peerId: peerId)
|
||||||
let notificationPeerId: PeerId = peer.associatedPeerId ?? peerId
|
let notificationPeerId: PeerId = peer.associatedPeerId ?? peerId
|
||||||
let notificationSettings = postbox.peerNotificationSettingsTable.getEffective(notificationPeerId)
|
|
||||||
let inclusion = self.get(peerId: peerId)
|
let inclusion = self.get(peerId: peerId)
|
||||||
if let (groupId, _) = inclusion.includedIndex(peerId: peerId) {
|
if let (groupId, _) = inclusion.includedIndex(peerId: peerId) {
|
||||||
if totalStates[groupId] == nil {
|
if totalStates[groupId] == nil {
|
||||||
|
|||||||
@ -115,8 +115,8 @@ public enum ChatListNamespaceEntry {
|
|||||||
|
|
||||||
public var index: ChatListIndex {
|
public var index: ChatListIndex {
|
||||||
switch self {
|
switch self {
|
||||||
case let .peer(peer):
|
case let .peer(index, _, _, _, _):
|
||||||
return peer.index
|
return index
|
||||||
case let .hole(index):
|
case let .hole(index):
|
||||||
return ChatListIndex(pinningIndex: nil, messageIndex: index)
|
return ChatListIndex(pinningIndex: nil, messageIndex: index)
|
||||||
}
|
}
|
||||||
@ -245,8 +245,8 @@ final class ChatListTable: Table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUnreadChatListPeerIds(postbox: Postbox, groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?) -> [PeerId] {
|
func getUnreadChatListPeerIds(postbox: Postbox, currentTransaction: Transaction, groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?) -> [PeerId] {
|
||||||
let globalNotificationSettings = postbox.getGlobalNotificationSettings()
|
let globalNotificationSettings = postbox.getGlobalNotificationSettings(transaction: currentTransaction)
|
||||||
|
|
||||||
var result: [PeerId] = []
|
var result: [PeerId] = []
|
||||||
self.valueBox.range(self.table, start: self.upperBound(groupId: groupId), end: self.lowerBound(groupId: groupId), keys: { key in
|
self.valueBox.range(self.table, start: self.upperBound(groupId: groupId), end: self.lowerBound(groupId: groupId), keys: { key in
|
||||||
@ -797,13 +797,13 @@ final class ChatListTable: Table {
|
|||||||
return entries
|
return entries
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRelativeUnreadChatListIndex(postbox: Postbox, filtered: Bool, position: ChatListRelativePosition, groupId: PeerGroupId) -> ChatListIndex? {
|
func getRelativeUnreadChatListIndex(postbox: Postbox, currentTransaction: Transaction, filtered: Bool, position: ChatListRelativePosition, groupId: PeerGroupId) -> ChatListIndex? {
|
||||||
var result: ChatListIndex?
|
var result: ChatListIndex?
|
||||||
|
|
||||||
let lower: ValueBoxKey
|
let lower: ValueBoxKey
|
||||||
let upper: ValueBoxKey
|
let upper: ValueBoxKey
|
||||||
|
|
||||||
let globalNotificationSettings = postbox.getGlobalNotificationSettings()
|
let globalNotificationSettings = postbox.getGlobalNotificationSettings(transaction: currentTransaction)
|
||||||
|
|
||||||
switch position {
|
switch position {
|
||||||
case let .earlier(index):
|
case let .earlier(index):
|
||||||
|
|||||||
@ -337,7 +337,7 @@ final class MutableChatListView {
|
|||||||
private var additionalItems: [AdditionalChatListItem] = []
|
private var additionalItems: [AdditionalChatListItem] = []
|
||||||
fileprivate var additionalItemEntries: [MutableChatListAdditionalItemEntry] = []
|
fileprivate var additionalItemEntries: [MutableChatListAdditionalItemEntry] = []
|
||||||
|
|
||||||
init(postbox: Postbox, groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?, aroundIndex: ChatListIndex, count: Int, summaryComponents: ChatListEntrySummaryComponents) {
|
init(postbox: Postbox, currentTransaction: Transaction, groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?, aroundIndex: ChatListIndex, count: Int, summaryComponents: ChatListEntrySummaryComponents) {
|
||||||
self.groupId = groupId
|
self.groupId = groupId
|
||||||
self.filterPredicate = filterPredicate
|
self.filterPredicate = filterPredicate
|
||||||
self.summaryComponents = summaryComponents
|
self.summaryComponents = summaryComponents
|
||||||
@ -358,8 +358,8 @@ final class MutableChatListView {
|
|||||||
spaces.append(.group(groupId: self.groupId, pinned: .includePinned, predicate: filterPredicate))
|
spaces.append(.group(groupId: self.groupId, pinned: .includePinned, predicate: filterPredicate))
|
||||||
}
|
}
|
||||||
self.spaces = spaces
|
self.spaces = spaces
|
||||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: aroundIndex, summaryComponents: self.summaryComponents, halfLimit: count)
|
self.state = ChatListViewState(postbox: postbox, currentTransaction: currentTransaction, spaces: self.spaces, anchorIndex: aroundIndex, summaryComponents: self.summaryComponents, halfLimit: count)
|
||||||
self.sampledState = self.state.sample(postbox: postbox)
|
self.sampledState = self.state.sample(postbox: postbox, currentTransaction: currentTransaction)
|
||||||
|
|
||||||
self.count = count
|
self.count = count
|
||||||
|
|
||||||
@ -451,11 +451,11 @@ final class MutableChatListView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshDueToExternalTransaction(postbox: Postbox) -> Bool {
|
func refreshDueToExternalTransaction(postbox: Postbox, currentTransaction: Transaction) -> Bool {
|
||||||
var updated = false
|
var updated = false
|
||||||
|
|
||||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: .absoluteUpperBound, summaryComponents: self.summaryComponents, halfLimit: self.count)
|
self.state = ChatListViewState(postbox: postbox, currentTransaction: currentTransaction, spaces: self.spaces, anchorIndex: .absoluteUpperBound, summaryComponents: self.summaryComponents, halfLimit: self.count)
|
||||||
self.sampledState = self.state.sample(postbox: postbox)
|
self.sampledState = self.state.sample(postbox: postbox, currentTransaction: currentTransaction)
|
||||||
updated = true
|
updated = true
|
||||||
|
|
||||||
let currentGroupEntries = self.groupEntries
|
let currentGroupEntries = self.groupEntries
|
||||||
@ -469,16 +469,16 @@ final class MutableChatListView {
|
|||||||
return updated
|
return updated
|
||||||
}
|
}
|
||||||
|
|
||||||
func replay(postbox: Postbox, operations: [PeerGroupId: [ChatListOperation]], updatedPeerNotificationSettings: [PeerId: (PeerNotificationSettings?, PeerNotificationSettings)], updatedPeers: [PeerId: Peer], updatedPeerPresences: [PeerId: PeerPresence], transaction: PostboxTransaction, context: MutableChatListViewReplayContext) -> Bool {
|
func replay(postbox: Postbox, currentTransaction: Transaction, operations: [PeerGroupId: [ChatListOperation]], updatedPeerNotificationSettings: [PeerId: (PeerNotificationSettings?, PeerNotificationSettings)], updatedPeers: [PeerId: Peer], updatedPeerPresences: [PeerId: PeerPresence], transaction: PostboxTransaction, context: MutableChatListViewReplayContext) -> Bool {
|
||||||
var hasChanges = false
|
var hasChanges = false
|
||||||
|
|
||||||
if transaction.updatedGlobalNotificationSettings && self.filterPredicate != nil {
|
if transaction.updatedGlobalNotificationSettings && self.filterPredicate != nil {
|
||||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: .absoluteUpperBound, summaryComponents: self.summaryComponents, halfLimit: self.count)
|
self.state = ChatListViewState(postbox: postbox, currentTransaction: currentTransaction, spaces: self.spaces, anchorIndex: .absoluteUpperBound, summaryComponents: self.summaryComponents, halfLimit: self.count)
|
||||||
self.sampledState = self.state.sample(postbox: postbox)
|
self.sampledState = self.state.sample(postbox: postbox, currentTransaction: currentTransaction)
|
||||||
hasChanges = true
|
hasChanges = true
|
||||||
} else {
|
} else {
|
||||||
if self.state.replay(postbox: postbox, transaction: transaction) {
|
if self.state.replay(postbox: postbox, currentTransaction: currentTransaction, transaction: transaction) {
|
||||||
self.sampledState = self.state.sample(postbox: postbox)
|
self.sampledState = self.state.sample(postbox: postbox, currentTransaction: currentTransaction)
|
||||||
hasChanges = true
|
hasChanges = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,8 +53,8 @@ enum ChatListViewSpace: Hashable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func mappedChatListFilterPredicate(postbox: Postbox, groupId: PeerGroupId, predicate: ChatListFilterPredicate) -> (ChatListIntermediateEntry) -> Bool {
|
private func mappedChatListFilterPredicate(postbox: Postbox, currentTransaction: Transaction, groupId: PeerGroupId, predicate: ChatListFilterPredicate) -> (ChatListIntermediateEntry) -> Bool {
|
||||||
let globalNotificationSettings = postbox.getGlobalNotificationSettings()
|
let globalNotificationSettings = postbox.getGlobalNotificationSettings(transaction: currentTransaction)
|
||||||
return { entry in
|
return { entry in
|
||||||
switch entry {
|
switch entry {
|
||||||
case let .message(index, _):
|
case let .message(index, _):
|
||||||
@ -131,18 +131,18 @@ private final class ChatListViewSpaceState {
|
|||||||
|
|
||||||
var orderedEntries: OrderedChatListViewEntries
|
var orderedEntries: OrderedChatListViewEntries
|
||||||
|
|
||||||
init(postbox: Postbox, space: ChatListViewSpace, anchorIndex: MutableChatListEntryIndex, summaryComponents: ChatListEntrySummaryComponents, halfLimit: Int) {
|
init(postbox: Postbox, currentTransaction: Transaction, space: ChatListViewSpace, anchorIndex: MutableChatListEntryIndex, summaryComponents: ChatListEntrySummaryComponents, halfLimit: Int) {
|
||||||
self.space = space
|
self.space = space
|
||||||
self.anchorIndex = anchorIndex
|
self.anchorIndex = anchorIndex
|
||||||
self.summaryComponents = summaryComponents
|
self.summaryComponents = summaryComponents
|
||||||
self.halfLimit = halfLimit
|
self.halfLimit = halfLimit
|
||||||
self.orderedEntries = OrderedChatListViewEntries(anchorIndex: anchorIndex.index, lowerOrAtAnchor: [], higherThanAnchor: [])
|
self.orderedEntries = OrderedChatListViewEntries(anchorIndex: anchorIndex.index, lowerOrAtAnchor: [], higherThanAnchor: [])
|
||||||
self.fillSpace(postbox: postbox)
|
self.fillSpace(postbox: postbox, currentTransaction: currentTransaction)
|
||||||
|
|
||||||
self.checkEntries(postbox: postbox)
|
self.checkEntries(postbox: postbox)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func fillSpace(postbox: Postbox) {
|
private func fillSpace(postbox: Postbox, currentTransaction: Transaction) {
|
||||||
switch self.space {
|
switch self.space {
|
||||||
case let .group(groupId, pinned, filterPredicate):
|
case let .group(groupId, pinned, filterPredicate):
|
||||||
let lowerBound: MutableChatListEntryIndex
|
let lowerBound: MutableChatListEntryIndex
|
||||||
@ -180,7 +180,7 @@ private final class ChatListViewSpaceState {
|
|||||||
let resolvedUnpinnedAnchorIndex = min(unpinnedUpperBound, max(self.anchorIndex, unpinnedLowerBound))
|
let resolvedUnpinnedAnchorIndex = min(unpinnedUpperBound, max(self.anchorIndex, unpinnedLowerBound))
|
||||||
|
|
||||||
if lowerOrAtAnchorMessages.count < self.halfLimit || higherThanAnchorMessages.count < self.halfLimit {
|
if lowerOrAtAnchorMessages.count < self.halfLimit || higherThanAnchorMessages.count < self.halfLimit {
|
||||||
let loadedMessages = postbox.chatListTable.entries(groupId: groupId, from: (ChatListIndex.pinnedLowerBound, true), to: (ChatListIndex.absoluteUpperBound, true), peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: self.halfLimit * 2, predicate: filterPredicate.flatMap { mappedChatListFilterPredicate(postbox: postbox, groupId: groupId, predicate: $0) }).map(mapEntry).sorted(by: { $0.entryIndex < $1.entryIndex })
|
let loadedMessages = postbox.chatListTable.entries(groupId: groupId, from: (ChatListIndex.pinnedLowerBound, true), to: (ChatListIndex.absoluteUpperBound, true), peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: self.halfLimit * 2, predicate: filterPredicate.flatMap { mappedChatListFilterPredicate(postbox: postbox, currentTransaction: currentTransaction, groupId: groupId, predicate: $0) }).map(mapEntry).sorted(by: { $0.entryIndex < $1.entryIndex })
|
||||||
|
|
||||||
if lowerOrAtAnchorMessages.count < self.halfLimit {
|
if lowerOrAtAnchorMessages.count < self.halfLimit {
|
||||||
var nextLowerIndex: MutableChatListEntryIndex
|
var nextLowerIndex: MutableChatListEntryIndex
|
||||||
@ -219,7 +219,7 @@ private final class ChatListViewSpaceState {
|
|||||||
} else {
|
} else {
|
||||||
nextLowerIndex = resolvedAnchorIndex.successor
|
nextLowerIndex = resolvedAnchorIndex.successor
|
||||||
}
|
}
|
||||||
let loadedLowerMessages = postbox.chatListTable.entries(groupId: groupId, from: (nextLowerIndex.index, nextLowerIndex.isMessage), to: (lowerBound.index, lowerBound.isMessage), peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: self.halfLimit - lowerOrAtAnchorMessages.count, predicate: filterPredicate.flatMap { mappedChatListFilterPredicate(postbox: postbox, groupId: groupId, predicate: $0) }).map(mapEntry)
|
let loadedLowerMessages = postbox.chatListTable.entries(groupId: groupId, from: (nextLowerIndex.index, nextLowerIndex.isMessage), to: (lowerBound.index, lowerBound.isMessage), peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: self.halfLimit - lowerOrAtAnchorMessages.count, predicate: filterPredicate.flatMap { mappedChatListFilterPredicate(postbox: postbox, currentTransaction: currentTransaction, groupId: groupId, predicate: $0) }).map(mapEntry)
|
||||||
lowerOrAtAnchorMessages.append(contentsOf: loadedLowerMessages)
|
lowerOrAtAnchorMessages.append(contentsOf: loadedLowerMessages)
|
||||||
}
|
}
|
||||||
if higherThanAnchorMessages.count < self.halfLimit {
|
if higherThanAnchorMessages.count < self.halfLimit {
|
||||||
@ -229,7 +229,7 @@ private final class ChatListViewSpaceState {
|
|||||||
} else {
|
} else {
|
||||||
nextHigherIndex = resolvedAnchorIndex
|
nextHigherIndex = resolvedAnchorIndex
|
||||||
}
|
}
|
||||||
let loadedHigherMessages = postbox.chatListTable.entries(groupId: groupId, from: (nextHigherIndex.index, nextHigherIndex.isMessage), to: (upperBound.index, upperBound.isMessage), peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: self.halfLimit - higherThanAnchorMessages.count, predicate: filterPredicate.flatMap { mappedChatListFilterPredicate(postbox: postbox, groupId: groupId, predicate: $0) }).map(mapEntry)
|
let loadedHigherMessages = postbox.chatListTable.entries(groupId: groupId, from: (nextHigherIndex.index, nextHigherIndex.isMessage), to: (upperBound.index, upperBound.isMessage), peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: self.halfLimit - higherThanAnchorMessages.count, predicate: filterPredicate.flatMap { mappedChatListFilterPredicate(postbox: postbox, currentTransaction: currentTransaction, groupId: groupId, predicate: $0) }).map(mapEntry)
|
||||||
higherThanAnchorMessages.append(contentsOf: loadedHigherMessages)
|
higherThanAnchorMessages.append(contentsOf: loadedHigherMessages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,7 +370,7 @@ private final class ChatListViewSpaceState {
|
|||||||
assert(self.orderedEntries.higherThanAnchor.count <= self.halfLimit)
|
assert(self.orderedEntries.higherThanAnchor.count <= self.halfLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
func replay(postbox: Postbox, transaction: PostboxTransaction) -> Bool {
|
func replay(postbox: Postbox, currentTransaction: Transaction, transaction: PostboxTransaction) -> Bool {
|
||||||
var hasUpdates = false
|
var hasUpdates = false
|
||||||
var hadRemovals = false
|
var hadRemovals = false
|
||||||
var globalNotificationSettings: PostboxGlobalNotificationSettings?
|
var globalNotificationSettings: PostboxGlobalNotificationSettings?
|
||||||
@ -396,7 +396,7 @@ private final class ChatListViewSpaceState {
|
|||||||
if let current = globalNotificationSettings {
|
if let current = globalNotificationSettings {
|
||||||
globalNotificationSettingsValue = current
|
globalNotificationSettingsValue = current
|
||||||
} else {
|
} else {
|
||||||
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings()
|
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings(transaction: currentTransaction)
|
||||||
globalNotificationSettings = globalNotificationSettingsValue
|
globalNotificationSettings = globalNotificationSettingsValue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,15 +502,15 @@ private final class ChatListViewSpaceState {
|
|||||||
let entryPeer: Peer
|
let entryPeer: Peer
|
||||||
let entryNotificationsPeerId: PeerId
|
let entryNotificationsPeerId: PeerId
|
||||||
switch entry {
|
switch entry {
|
||||||
case let .MessageEntry(messageEntry):
|
case let .MessageEntry(_, _, _, _, _, _, renderedPeer, _, _, _, _):
|
||||||
if let peer = messageEntry.renderedPeer.peer {
|
if let peer = renderedPeer.peer {
|
||||||
entryPeer = peer
|
entryPeer = peer
|
||||||
entryNotificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
entryNotificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case let .IntermediateMessageEntry(intermediateMessageEntry):
|
case let .IntermediateMessageEntry(index, _):
|
||||||
if let peer = postbox.peerTable.get(intermediateMessageEntry.index.messageIndex.id.peerId) {
|
if let peer = postbox.peerTable.get(index.messageIndex.id.peerId) {
|
||||||
entryPeer = peer
|
entryPeer = peer
|
||||||
entryNotificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
entryNotificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
||||||
} else {
|
} else {
|
||||||
@ -526,7 +526,7 @@ private final class ChatListViewSpaceState {
|
|||||||
if let current = globalNotificationSettings {
|
if let current = globalNotificationSettings {
|
||||||
globalNotificationSettingsValue = current
|
globalNotificationSettingsValue = current
|
||||||
} else {
|
} else {
|
||||||
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings()
|
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings(transaction: currentTransaction)
|
||||||
globalNotificationSettings = globalNotificationSettingsValue
|
globalNotificationSettings = globalNotificationSettingsValue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,7 +564,7 @@ private final class ChatListViewSpaceState {
|
|||||||
if let current = globalNotificationSettings {
|
if let current = globalNotificationSettings {
|
||||||
globalNotificationSettingsValue = current
|
globalNotificationSettingsValue = current
|
||||||
} else {
|
} else {
|
||||||
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings()
|
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings(transaction: currentTransaction)
|
||||||
globalNotificationSettings = globalNotificationSettingsValue
|
globalNotificationSettings = globalNotificationSettingsValue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,11 +600,11 @@ private final class ChatListViewSpaceState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !transaction.currentUpdatedPeerNotificationSettings.isEmpty {
|
if !transaction.currentUpdatedPeerNotificationSettings.isEmpty {
|
||||||
let globalNotificationSettings = postbox.getGlobalNotificationSettings()
|
let globalNotificationSettings = postbox.getGlobalNotificationSettings(transaction: currentTransaction)
|
||||||
|
|
||||||
if self.orderedEntries.mutableScan({ entry in
|
if self.orderedEntries.mutableScan({ entry in
|
||||||
switch entry {
|
switch entry {
|
||||||
case let .MessageEntry(index, messages, readState, notificationSettings, isRemovedFromTotalUnreadCount, embeddedInterfaceState, renderedPeer, presence, tagSummaryInfo, hasFailedMessages, isContact):
|
case let .MessageEntry(index, messages, readState, _, _, embeddedInterfaceState, renderedPeer, presence, tagSummaryInfo, hasFailedMessages, isContact):
|
||||||
if let peer = renderedPeer.peer {
|
if let peer = renderedPeer.peer {
|
||||||
let notificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
let notificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
||||||
if let (_, updated) = transaction.currentUpdatedPeerNotificationSettings[notificationsPeerId] {
|
if let (_, updated) = transaction.currentUpdatedPeerNotificationSettings[notificationsPeerId] {
|
||||||
@ -628,9 +628,21 @@ private final class ChatListViewSpaceState {
|
|||||||
if !transaction.updatedFailedMessagePeerIds.isEmpty {
|
if !transaction.updatedFailedMessagePeerIds.isEmpty {
|
||||||
if self.orderedEntries.mutableScan({ entry in
|
if self.orderedEntries.mutableScan({ entry in
|
||||||
switch entry {
|
switch entry {
|
||||||
case let .MessageEntry(messageEntry):
|
case let .MessageEntry(index, messages, readState, notificationSettings, isRemovedFromTotalUnreadCount, embeddedInterfaceState, renderedPeer, presence, tagSummaryInfo, _, isContact):
|
||||||
if transaction.updatedFailedMessagePeerIds.contains(messageEntry.index.messageIndex.id.peerId) {
|
if transaction.updatedFailedMessagePeerIds.contains(index.messageIndex.id.peerId) {
|
||||||
return .MessageEntry(index: messageEntry.index, messages: messageEntry.messages, readState: messageEntry.readState, notificationSettings: messageEntry.notificationSettings, isRemovedFromTotalUnreadCount: messageEntry.isRemovedFromTotalUnreadCount, embeddedInterfaceState: messageEntry.embeddedInterfaceState, renderedPeer: messageEntry.renderedPeer, presence: messageEntry.presence, tagSummaryInfo: messageEntry.tagSummaryInfo, hasFailedMessages: postbox.messageHistoryFailedTable.contains(peerId: messageEntry.index.messageIndex.id.peerId), isContact: messageEntry.isContact)
|
return .MessageEntry(
|
||||||
|
index: index,
|
||||||
|
messages: messages,
|
||||||
|
readState: readState,
|
||||||
|
notificationSettings: notificationSettings,
|
||||||
|
isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount,
|
||||||
|
embeddedInterfaceState: embeddedInterfaceState,
|
||||||
|
renderedPeer: renderedPeer,
|
||||||
|
presence: presence,
|
||||||
|
tagSummaryInfo: tagSummaryInfo,
|
||||||
|
hasFailedMessages: postbox.messageHistoryFailedTable.contains(peerId: index.messageIndex.id.peerId),
|
||||||
|
isContact: isContact
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -645,8 +657,8 @@ private final class ChatListViewSpaceState {
|
|||||||
if !transaction.currentUpdatedPeers.isEmpty {
|
if !transaction.currentUpdatedPeers.isEmpty {
|
||||||
if self.orderedEntries.mutableScan({ entry in
|
if self.orderedEntries.mutableScan({ entry in
|
||||||
switch entry {
|
switch entry {
|
||||||
case let .MessageEntry(messageEntry):
|
case let .MessageEntry(index, messages, readState, notificationSettings, isRemovedFromTotalUnreadCount, embeddedInterfaceState, entryRenderedPeer, presence, tagSummaryInfo, hasFailedMessages, isContact):
|
||||||
var updatedMessages: [Message] = messageEntry.messages
|
var updatedMessages: [Message] = messages
|
||||||
var hasUpdatedMessages = false
|
var hasUpdatedMessages = false
|
||||||
for i in 0 ..< updatedMessages.count {
|
for i in 0 ..< updatedMessages.count {
|
||||||
if let updatedMessage = updateMessagePeers(updatedMessages[i], updatedPeers: transaction.currentUpdatedPeers) {
|
if let updatedMessage = updateMessagePeers(updatedMessages[i], updatedPeers: transaction.currentUpdatedPeers) {
|
||||||
@ -654,10 +666,21 @@ private final class ChatListViewSpaceState {
|
|||||||
hasUpdatedMessages = true
|
hasUpdatedMessages = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let renderedPeer = updatedRenderedPeer(messageEntry.renderedPeer, updatedPeers: transaction.currentUpdatedPeers)
|
let renderedPeer = updatedRenderedPeer(entryRenderedPeer, updatedPeers: transaction.currentUpdatedPeers)
|
||||||
|
|
||||||
if hasUpdatedMessages || renderedPeer != nil {
|
if hasUpdatedMessages || renderedPeer != nil {
|
||||||
return .MessageEntry(index: messageEntry.index, messages: updatedMessages, readState: messageEntry.readState, notificationSettings: messageEntry.notificationSettings, isRemovedFromTotalUnreadCount: messageEntry.isRemovedFromTotalUnreadCount, embeddedInterfaceState: messageEntry.embeddedInterfaceState, renderedPeer: renderedPeer ?? messageEntry.renderedPeer, presence: messageEntry.presence, tagSummaryInfo: messageEntry.tagSummaryInfo, hasFailedMessages: messageEntry.hasFailedMessages, isContact: messageEntry.isContact)
|
return .MessageEntry(
|
||||||
|
index: index,
|
||||||
|
messages: updatedMessages,
|
||||||
|
readState: readState,
|
||||||
|
notificationSettings: notificationSettings,
|
||||||
|
isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount,
|
||||||
|
embeddedInterfaceState: embeddedInterfaceState,
|
||||||
|
renderedPeer: renderedPeer ?? entryRenderedPeer,
|
||||||
|
presence: presence,
|
||||||
|
tagSummaryInfo: tagSummaryInfo,
|
||||||
|
hasFailedMessages: hasFailedMessages,
|
||||||
|
isContact: isContact)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -672,13 +695,25 @@ private final class ChatListViewSpaceState {
|
|||||||
if !transaction.currentUpdatedPeerPresences.isEmpty {
|
if !transaction.currentUpdatedPeerPresences.isEmpty {
|
||||||
if self.orderedEntries.mutableScan({ entry in
|
if self.orderedEntries.mutableScan({ entry in
|
||||||
switch entry {
|
switch entry {
|
||||||
case let .MessageEntry(messageEntry):
|
case let .MessageEntry(index, messages, readState, notificationSettings, isRemovedFromTotalUnreadCount, embeddedInterfaceState, entryRenderedPeer, _, tagSummaryInfo, hasFailedMessages, isContact):
|
||||||
var presencePeerId = messageEntry.renderedPeer.peerId
|
var presencePeerId = entryRenderedPeer.peerId
|
||||||
if let peer = messageEntry.renderedPeer.peers[messageEntry.renderedPeer.peerId], let associatedPeerId = peer.associatedPeerId {
|
if let peer = entryRenderedPeer.peers[entryRenderedPeer.peerId], let associatedPeerId = peer.associatedPeerId {
|
||||||
presencePeerId = associatedPeerId
|
presencePeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
if let presence = transaction.currentUpdatedPeerPresences[presencePeerId] {
|
if let presence = transaction.currentUpdatedPeerPresences[presencePeerId] {
|
||||||
return .MessageEntry(index: messageEntry.index, messages: messageEntry.messages, readState: messageEntry.readState, notificationSettings: messageEntry.notificationSettings, isRemovedFromTotalUnreadCount: messageEntry.isRemovedFromTotalUnreadCount, embeddedInterfaceState: messageEntry.embeddedInterfaceState, renderedPeer: messageEntry.renderedPeer, presence: presence, tagSummaryInfo: messageEntry.tagSummaryInfo, hasFailedMessages: messageEntry.hasFailedMessages, isContact: messageEntry.isContact)
|
return .MessageEntry(
|
||||||
|
index: index,
|
||||||
|
messages: messages,
|
||||||
|
readState: readState,
|
||||||
|
notificationSettings: notificationSettings,
|
||||||
|
isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount,
|
||||||
|
embeddedInterfaceState: embeddedInterfaceState,
|
||||||
|
renderedPeer: entryRenderedPeer,
|
||||||
|
presence: presence,
|
||||||
|
tagSummaryInfo: tagSummaryInfo,
|
||||||
|
hasFailedMessages: hasFailedMessages,
|
||||||
|
isContact: isContact
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -696,15 +731,15 @@ private final class ChatListViewSpaceState {
|
|||||||
let entryPeer: Peer
|
let entryPeer: Peer
|
||||||
let entryNotificationsPeerId: PeerId
|
let entryNotificationsPeerId: PeerId
|
||||||
switch entry {
|
switch entry {
|
||||||
case let .MessageEntry(messageEntry):
|
case let .MessageEntry(_, _, _, _, _, _, entryRenderedPeer, _, _, _, _):
|
||||||
if let peer = messageEntry.renderedPeer.peer {
|
if let peer = entryRenderedPeer.peer {
|
||||||
entryPeer = peer
|
entryPeer = peer
|
||||||
entryNotificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
entryNotificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case let .IntermediateMessageEntry(intermediateMessageEntry):
|
case let .IntermediateMessageEntry(index, _):
|
||||||
if let peer = postbox.peerTable.get(intermediateMessageEntry.index.messageIndex.id.peerId) {
|
if let peer = postbox.peerTable.get(index.messageIndex.id.peerId) {
|
||||||
entryPeer = peer
|
entryPeer = peer
|
||||||
entryNotificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
entryNotificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
||||||
} else {
|
} else {
|
||||||
@ -724,7 +759,7 @@ private final class ChatListViewSpaceState {
|
|||||||
if let current = globalNotificationSettings {
|
if let current = globalNotificationSettings {
|
||||||
globalNotificationSettingsValue = current
|
globalNotificationSettingsValue = current
|
||||||
} else {
|
} else {
|
||||||
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings()
|
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings(transaction: currentTransaction)
|
||||||
globalNotificationSettings = globalNotificationSettingsValue
|
globalNotificationSettings = globalNotificationSettingsValue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,7 +804,7 @@ private final class ChatListViewSpaceState {
|
|||||||
if let current = globalNotificationSettings {
|
if let current = globalNotificationSettings {
|
||||||
globalNotificationSettingsValue = current
|
globalNotificationSettingsValue = current
|
||||||
} else {
|
} else {
|
||||||
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings()
|
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings(transaction: currentTransaction)
|
||||||
globalNotificationSettings = globalNotificationSettingsValue
|
globalNotificationSettings = globalNotificationSettingsValue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -807,28 +842,40 @@ private final class ChatListViewSpaceState {
|
|||||||
if !transaction.currentUpdatedMessageTagSummaries.isEmpty || !transaction.currentUpdatedMessageActionsSummaries.isEmpty {
|
if !transaction.currentUpdatedMessageTagSummaries.isEmpty || !transaction.currentUpdatedMessageActionsSummaries.isEmpty {
|
||||||
if self.orderedEntries.mutableScan({ entry in
|
if self.orderedEntries.mutableScan({ entry in
|
||||||
switch entry {
|
switch entry {
|
||||||
case let .MessageEntry(messageEntry):
|
case let .MessageEntry(index, messages, readState, notificationSettings, isRemovedFromTotalUnreadCount, embeddedInterfaceState, entryRenderedPeer, presence, tagSummaryInfo, hasFailedMessages, isContact):
|
||||||
var updatedTagSummaryCount: Int32?
|
var updatedTagSummaryCount: Int32?
|
||||||
var updatedActionsSummaryCount: Int32?
|
var updatedActionsSummaryCount: Int32?
|
||||||
|
|
||||||
if let tagSummary = self.summaryComponents.tagSummary {
|
if let tagSummary = self.summaryComponents.tagSummary {
|
||||||
let key = MessageHistoryTagsSummaryKey(tag: tagSummary.tag, peerId: messageEntry.index.messageIndex.id.peerId, namespace: tagSummary.namespace)
|
let key = MessageHistoryTagsSummaryKey(tag: tagSummary.tag, peerId: index.messageIndex.id.peerId, namespace: tagSummary.namespace)
|
||||||
if let summary = transaction.currentUpdatedMessageTagSummaries[key] {
|
if let summary = transaction.currentUpdatedMessageTagSummaries[key] {
|
||||||
updatedTagSummaryCount = summary.count
|
updatedTagSummaryCount = summary.count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let actionsSummary = self.summaryComponents.actionsSummary {
|
if let actionsSummary = self.summaryComponents.actionsSummary {
|
||||||
let key = PendingMessageActionsSummaryKey(type: actionsSummary.type, peerId: messageEntry.index.messageIndex.id.peerId, namespace: actionsSummary.namespace)
|
let key = PendingMessageActionsSummaryKey(type: actionsSummary.type, peerId: index.messageIndex.id.peerId, namespace: actionsSummary.namespace)
|
||||||
if let count = transaction.currentUpdatedMessageActionsSummaries[key] {
|
if let count = transaction.currentUpdatedMessageActionsSummaries[key] {
|
||||||
updatedActionsSummaryCount = count
|
updatedActionsSummaryCount = count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if updatedTagSummaryCount != nil || updatedActionsSummaryCount != nil {
|
if updatedTagSummaryCount != nil || updatedActionsSummaryCount != nil {
|
||||||
let summaryInfo = ChatListMessageTagSummaryInfo(tagSummaryCount: updatedTagSummaryCount ?? messageEntry.tagSummaryInfo.tagSummaryCount, actionsSummaryCount: updatedActionsSummaryCount ?? messageEntry.tagSummaryInfo.actionsSummaryCount)
|
let summaryInfo = ChatListMessageTagSummaryInfo(tagSummaryCount: updatedTagSummaryCount ?? tagSummaryInfo.tagSummaryCount, actionsSummaryCount: updatedActionsSummaryCount ?? tagSummaryInfo.actionsSummaryCount)
|
||||||
|
|
||||||
return .MessageEntry(index: messageEntry.index, messages: messageEntry.messages, readState: messageEntry.readState, notificationSettings: messageEntry.notificationSettings, isRemovedFromTotalUnreadCount: messageEntry.isRemovedFromTotalUnreadCount, embeddedInterfaceState: messageEntry.embeddedInterfaceState, renderedPeer: messageEntry.renderedPeer, presence: messageEntry.presence, tagSummaryInfo: summaryInfo, hasFailedMessages: messageEntry.hasFailedMessages, isContact: messageEntry.isContact)
|
return .MessageEntry(
|
||||||
|
index: index,
|
||||||
|
messages: messages,
|
||||||
|
readState: readState,
|
||||||
|
notificationSettings: notificationSettings,
|
||||||
|
isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount,
|
||||||
|
embeddedInterfaceState: embeddedInterfaceState,
|
||||||
|
renderedPeer: entryRenderedPeer,
|
||||||
|
presence: presence,
|
||||||
|
tagSummaryInfo: summaryInfo,
|
||||||
|
hasFailedMessages: hasFailedMessages,
|
||||||
|
isContact: isContact
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -841,7 +888,7 @@ private final class ChatListViewSpaceState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if true || hadRemovals {
|
if true || hadRemovals {
|
||||||
self.fillSpace(postbox: postbox)
|
self.fillSpace(postbox: postbox, currentTransaction: currentTransaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.checkEntries(postbox: postbox)
|
self.checkEntries(postbox: postbox)
|
||||||
@ -866,7 +913,7 @@ private final class ChatListViewSpaceState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let loadedEntries = postbox.chatListTable.entries(groupId: .root, from: (allEntries[0].index.predecessor, true), to: (allEntries[allEntries.count - 1].index.successor, true), peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: 1000, predicate: nil).map(mapEntry)
|
//let loadedEntries = postbox.chatListTable.entries(groupId: .root, from: (allEntries[0].index.predecessor, true), to: (allEntries[allEntries.count - 1].index.successor, true), peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: 1000, predicate: nil).map(mapEntry)
|
||||||
|
|
||||||
//assert(loadedEntries.map({ $0.index }) == allEntries.map({ $0.index }))
|
//assert(loadedEntries.map({ $0.index }) == allEntries.map({ $0.index }))
|
||||||
}
|
}
|
||||||
@ -876,7 +923,7 @@ private final class ChatListViewSpaceState {
|
|||||||
|
|
||||||
private func checkReplayEntries(postbox: Postbox) {
|
private func checkReplayEntries(postbox: Postbox) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
let cleanState = ChatListViewSpaceState(postbox: postbox, space: self.space, anchorIndex: self.anchorIndex, summaryComponents: self.summaryComponents, halfLimit: self.halfLimit)
|
//let cleanState = ChatListViewSpaceState(postbox: postbox, space: self.space, anchorIndex: self.anchorIndex, summaryComponents: self.summaryComponents, halfLimit: self.halfLimit)
|
||||||
//assert(self.orderedEntries.lowerOrAtAnchor.map { $0.index } == cleanState.orderedEntries.lowerOrAtAnchor.map { $0.index })
|
//assert(self.orderedEntries.lowerOrAtAnchor.map { $0.index } == cleanState.orderedEntries.lowerOrAtAnchor.map { $0.index })
|
||||||
//assert(self.orderedEntries.higherThanAnchor.map { $0.index } == cleanState.orderedEntries.higherThanAnchor.map { $0.index })
|
//assert(self.orderedEntries.higherThanAnchor.map { $0.index } == cleanState.orderedEntries.higherThanAnchor.map { $0.index })
|
||||||
#endif
|
#endif
|
||||||
@ -959,10 +1006,10 @@ private enum MutableChatListEntryEntityId: Hashable {
|
|||||||
private extension MutableChatListEntry {
|
private extension MutableChatListEntry {
|
||||||
var messagePeerId: PeerId? {
|
var messagePeerId: PeerId? {
|
||||||
switch self {
|
switch self {
|
||||||
case let .IntermediateMessageEntry(intermediateMessageEntry):
|
case let .IntermediateMessageEntry(index, _):
|
||||||
return intermediateMessageEntry.0.messageIndex.id.peerId
|
return index.messageIndex.id.peerId
|
||||||
case let .MessageEntry(messageEntry):
|
case let .MessageEntry(index, _, _, _, _, _, _, _, _, _, _):
|
||||||
return messageEntry.0.messageIndex.id.peerId
|
return index.messageIndex.id.peerId
|
||||||
case .HoleEntry:
|
case .HoleEntry:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -970,10 +1017,10 @@ private extension MutableChatListEntry {
|
|||||||
|
|
||||||
var entryIndex: MutableChatListEntryIndex {
|
var entryIndex: MutableChatListEntryIndex {
|
||||||
switch self {
|
switch self {
|
||||||
case let .IntermediateMessageEntry(intermediateMessageEntry):
|
case let .IntermediateMessageEntry(index, _):
|
||||||
return MutableChatListEntryIndex(index: intermediateMessageEntry.index, isMessage: true)
|
return MutableChatListEntryIndex(index: index, isMessage: true)
|
||||||
case let .MessageEntry(messageEntry):
|
case let .MessageEntry(index, _, _, _, _, _, _, _, _, _, _):
|
||||||
return MutableChatListEntryIndex(index: messageEntry.index, isMessage: true)
|
return MutableChatListEntryIndex(index: index, isMessage: true)
|
||||||
case let .HoleEntry(hole):
|
case let .HoleEntry(hole):
|
||||||
return MutableChatListEntryIndex(index: ChatListIndex(pinningIndex: nil, messageIndex: hole.index), isMessage: false)
|
return MutableChatListEntryIndex(index: ChatListIndex(pinningIndex: nil, messageIndex: hole.index), isMessage: false)
|
||||||
}
|
}
|
||||||
@ -981,10 +1028,10 @@ private extension MutableChatListEntry {
|
|||||||
|
|
||||||
var entityId: MutableChatListEntryEntityId {
|
var entityId: MutableChatListEntryEntityId {
|
||||||
switch self {
|
switch self {
|
||||||
case let .IntermediateMessageEntry(intermediateMessageEntry):
|
case let .IntermediateMessageEntry(index, _):
|
||||||
return .peer(intermediateMessageEntry.index.messageIndex.id.peerId)
|
return .peer(index.messageIndex.id.peerId)
|
||||||
case let .MessageEntry(messageEntry):
|
case let .MessageEntry(index, _, _, _, _, _, _, _, _, _, _):
|
||||||
return .peer(messageEntry.index.messageIndex.id.peerId)
|
return .peer(index.messageIndex.id.peerId)
|
||||||
case let .HoleEntry(hole):
|
case let .HoleEntry(hole):
|
||||||
return .hole(hole.index)
|
return .hole(hole.index)
|
||||||
}
|
}
|
||||||
@ -1218,20 +1265,20 @@ struct ChatListViewState {
|
|||||||
private let halfLimit: Int
|
private let halfLimit: Int
|
||||||
private var stateBySpace: [ChatListViewSpace: ChatListViewSpaceState] = [:]
|
private var stateBySpace: [ChatListViewSpace: ChatListViewSpaceState] = [:]
|
||||||
|
|
||||||
init(postbox: Postbox, spaces: [ChatListViewSpace], anchorIndex: ChatListIndex, summaryComponents: ChatListEntrySummaryComponents, halfLimit: Int) {
|
init(postbox: Postbox, currentTransaction: Transaction, spaces: [ChatListViewSpace], anchorIndex: ChatListIndex, summaryComponents: ChatListEntrySummaryComponents, halfLimit: Int) {
|
||||||
self.anchorIndex = MutableChatListEntryIndex(index: anchorIndex, isMessage: true)
|
self.anchorIndex = MutableChatListEntryIndex(index: anchorIndex, isMessage: true)
|
||||||
self.summaryComponents = summaryComponents
|
self.summaryComponents = summaryComponents
|
||||||
self.halfLimit = halfLimit
|
self.halfLimit = halfLimit
|
||||||
|
|
||||||
for space in spaces {
|
for space in spaces {
|
||||||
self.stateBySpace[space] = ChatListViewSpaceState(postbox: postbox, space: space, anchorIndex: self.anchorIndex, summaryComponents: summaryComponents, halfLimit: halfLimit)
|
self.stateBySpace[space] = ChatListViewSpaceState(postbox: postbox, currentTransaction: currentTransaction, space: space, anchorIndex: self.anchorIndex, summaryComponents: summaryComponents, halfLimit: halfLimit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func replay(postbox: Postbox, transaction: PostboxTransaction) -> Bool {
|
func replay(postbox: Postbox, currentTransaction: Transaction, transaction: PostboxTransaction) -> Bool {
|
||||||
var updated = false
|
var updated = false
|
||||||
for (_, state) in self.stateBySpace {
|
for (_, state) in self.stateBySpace {
|
||||||
if state.replay(postbox: postbox, transaction: transaction) {
|
if state.replay(postbox: postbox, currentTransaction: currentTransaction, transaction: transaction) {
|
||||||
updated = true
|
updated = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1314,7 +1361,7 @@ struct ChatListViewState {
|
|||||||
return (backwardsResult.reversed(), result)
|
return (backwardsResult.reversed(), result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sample(postbox: Postbox) -> ChatListViewSample {
|
func sample(postbox: Postbox, currentTransaction: Transaction) -> ChatListViewSample {
|
||||||
let combinedSpacesAndIndicesByDirection = self.sampleIndices()
|
let combinedSpacesAndIndicesByDirection = self.sampleIndices()
|
||||||
|
|
||||||
var result: [(ChatListViewSpace, MutableChatListEntry)] = []
|
var result: [(ChatListViewSpace, MutableChatListEntry)] = []
|
||||||
@ -1382,7 +1429,7 @@ struct ChatListViewState {
|
|||||||
|
|
||||||
let isRemovedFromTotalUnreadCount: Bool
|
let isRemovedFromTotalUnreadCount: Bool
|
||||||
if let peer = renderedPeer.peers[notificationsPeerId] {
|
if let peer = renderedPeer.peers[notificationsPeerId] {
|
||||||
isRemovedFromTotalUnreadCount = resolvedIsRemovedFromTotalUnreadCount(globalSettings: postbox.getGlobalNotificationSettings(), peer: peer, peerSettings: notificationSettings)
|
isRemovedFromTotalUnreadCount = resolvedIsRemovedFromTotalUnreadCount(globalSettings: postbox.getGlobalNotificationSettings(transaction: currentTransaction), peer: peer, peerSettings: notificationSettings)
|
||||||
} else {
|
} else {
|
||||||
isRemovedFromTotalUnreadCount = false
|
isRemovedFromTotalUnreadCount = false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -544,7 +544,8 @@ public final class PostboxEncoder {
|
|||||||
for object in value {
|
for object in value {
|
||||||
var length: Int32 = Int32(object.count)
|
var length: Int32 = Int32(object.count)
|
||||||
self.buffer.write(&length, offset: 0, length: 4)
|
self.buffer.write(&length, offset: 0, length: 4)
|
||||||
object.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
object.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
self.buffer.write(bytes, offset: 0, length: Int(length))
|
self.buffer.write(bytes, offset: 0, length: Int(length))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -637,7 +638,8 @@ public final class PostboxEncoder {
|
|||||||
self.buffer.write(&type, offset: 0, length: 1)
|
self.buffer.write(&type, offset: 0, length: 1)
|
||||||
var bytesLength: Int32 = Int32(data.count)
|
var bytesLength: Int32 = Int32(data.count)
|
||||||
self.buffer.write(&bytesLength, offset: 0, length: 4)
|
self.buffer.write(&bytesLength, offset: 0, length: 4)
|
||||||
data.withUnsafeBytes { (bytes: UnsafePointer<Int8>) -> Void in
|
data.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
self.buffer.write(bytes, offset: 0, length: Int(bytesLength))
|
self.buffer.write(bytes, offset: 0, length: Int(bytesLength))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -812,7 +814,8 @@ public final class PostboxDecoder {
|
|||||||
|
|
||||||
let keyData = key.data(using: .utf8)!
|
let keyData = key.data(using: .utf8)!
|
||||||
|
|
||||||
return keyData.withUnsafeBytes { (keyBytes: UnsafePointer<UInt8>) -> Bool in
|
return keyData.withUnsafeBytes { rawBytes -> Bool in
|
||||||
|
let keyBytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
let keyLength: Int = keyData.count
|
let keyLength: Int = keyData.count
|
||||||
while (offset < maxOffset) {
|
while (offset < maxOffset) {
|
||||||
let readKeyLength = bytes[offset]
|
let readKeyLength = bytes[offset]
|
||||||
@ -1702,7 +1705,8 @@ public final class PostboxDecoder {
|
|||||||
memcpy(&length, self.buffer.memory + self.offset, 4)
|
memcpy(&length, self.buffer.memory + self.offset, 4)
|
||||||
self.offset += 4 + Int(length)
|
self.offset += 4 + Int(length)
|
||||||
var result = Data(count: Int(length))
|
var result = Data(count: Int(length))
|
||||||
result.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<Int8>) -> Void in
|
result.withUnsafeMutableBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
memcpy(bytes, self.buffer.memory.advanced(by: self.offset - Int(length)), Int(length))
|
memcpy(bytes, self.buffer.memory.advanced(by: self.offset - Int(length)), Int(length))
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|||||||
@ -24,7 +24,6 @@ func ipcNotifications(basePath: String) -> Signal<Int64, Void> {
|
|||||||
if fd != -1 {
|
if fd != -1 {
|
||||||
let readSource = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fd, eventMask: [.write])
|
let readSource = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fd, eventMask: [.write])
|
||||||
|
|
||||||
var previousValue: Int64 = 0
|
|
||||||
readSource.setEventHandler(handler: {
|
readSource.setEventHandler(handler: {
|
||||||
subscriber.putNext(Int64.max)
|
subscriber.putNext(Int64.max)
|
||||||
/*lseek(fd, 0, SEEK_SET)
|
/*lseek(fd, 0, SEEK_SET)
|
||||||
|
|||||||
@ -8,14 +8,15 @@ public final class ItemCacheEntryId: Equatable, Hashable {
|
|||||||
self.collectionId = collectionId
|
self.collectionId = collectionId
|
||||||
self.key = key
|
self.key = key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func hash(into hasher: inout Hasher) {
|
||||||
|
hasher.combine(self.collectionId)
|
||||||
|
hasher.combine(self.key)
|
||||||
|
}
|
||||||
|
|
||||||
public static func ==(lhs: ItemCacheEntryId, rhs: ItemCacheEntryId) -> Bool {
|
public static func ==(lhs: ItemCacheEntryId, rhs: ItemCacheEntryId) -> Bool {
|
||||||
return lhs.collectionId == rhs.collectionId && lhs.key == rhs.key
|
return lhs.collectionId == rhs.collectionId && lhs.key == rhs.key
|
||||||
}
|
}
|
||||||
|
|
||||||
public var hashValue: Int {
|
|
||||||
return self.collectionId.hashValue &* 31 &+ self.key.hashValue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum ItemCacheSection: Int8 {
|
private enum ItemCacheSection: Int8 {
|
||||||
|
|||||||
@ -24,10 +24,6 @@ public struct ItemCollectionId: Comparable, Hashable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public var hashValue: Int {
|
|
||||||
return self.id.hashValue
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func encodeArrayToBuffer(_ array: [ItemCollectionId], buffer: WriteBuffer) {
|
public static func encodeArrayToBuffer(_ array: [ItemCollectionId], buffer: WriteBuffer) {
|
||||||
var length: Int32 = Int32(array.count)
|
var length: Int32 = Int32(array.count)
|
||||||
buffer.write(&length, offset: 0, length: 4)
|
buffer.write(&length, offset: 0, length: 4)
|
||||||
|
|||||||
@ -73,7 +73,8 @@ public final class ManagedFile {
|
|||||||
assert(queue.isCurrent())
|
assert(queue.isCurrent())
|
||||||
}
|
}
|
||||||
var result = Data(count: count)
|
var result = Data(count: count)
|
||||||
result.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<Int8>) -> Void in
|
result.withUnsafeMutableBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: Int8.self)
|
||||||
let readCount = self.read(bytes, count)
|
let readCount = self.read(bytes, count)
|
||||||
assert(readCount == count)
|
assert(readCount == count)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,11 +68,11 @@ public struct MediaId: Hashable, PostboxCoding, CustomStringConvertible, Codable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol AssociatedMediaData: class, PostboxCoding {
|
public protocol AssociatedMediaData: AnyObject, PostboxCoding {
|
||||||
func isEqual(to: AssociatedMediaData) -> Bool
|
func isEqual(to: AssociatedMediaData) -> Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol Media: class, PostboxCoding {
|
public protocol Media: AnyObject, PostboxCoding {
|
||||||
var id: MediaId? { get }
|
var id: MediaId? { get }
|
||||||
var peerIds: [PeerId] { get }
|
var peerIds: [PeerId] { get }
|
||||||
|
|
||||||
|
|||||||
@ -915,8 +915,9 @@ public final class MediaBox {
|
|||||||
case let .data(dataPart):
|
case let .data(dataPart):
|
||||||
let file = ManagedFile(queue: strongSelf.dataQueue, path: paths.partial, mode: .append)
|
let file = ManagedFile(queue: strongSelf.dataQueue, path: paths.partial, mode: .append)
|
||||||
let dataCount = dataPart.count
|
let dataCount = dataPart.count
|
||||||
dataPart.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
dataPart.withUnsafeBytes { rawBytes -> Void in
|
||||||
file?.write(bytes, count: dataCount)
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
|
let _ = file?.write(bytes, count: dataCount)
|
||||||
}
|
}
|
||||||
case .done:
|
case .done:
|
||||||
link(paths.partial, paths.complete)
|
link(paths.partial, paths.complete)
|
||||||
|
|||||||
@ -46,7 +46,9 @@ private final class MediaBoxFileMap {
|
|||||||
|
|
||||||
var data = Data(count: Int(4 + count * 2 * 4))
|
var data = Data(count: Int(4 + count * 2 * 4))
|
||||||
let dataCount = data.count
|
let dataCount = data.count
|
||||||
if !(data.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> Bool in
|
if !(data.withUnsafeMutableBytes { rawBytes -> Bool in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
|
|
||||||
guard fd.read(bytes, dataCount) == dataCount else {
|
guard fd.read(bytes, dataCount) == dataCount else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -337,8 +339,6 @@ final class MediaBoxPartialFile {
|
|||||||
} else {
|
} else {
|
||||||
assertionFailure()
|
assertionFailure()
|
||||||
}
|
}
|
||||||
} catch {
|
|
||||||
assertionFailure()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +364,9 @@ final class MediaBoxPartialFile {
|
|||||||
assert(self.queue.isCurrent())
|
assert(self.queue.isCurrent())
|
||||||
|
|
||||||
self.fd.seek(position: Int64(offset))
|
self.fd.seek(position: Int64(offset))
|
||||||
let written = data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Int in
|
let written = data.withUnsafeBytes { rawBytes -> Int in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
|
|
||||||
return self.fd.write(bytes.advanced(by: dataRange.lowerBound), count: dataRange.count)
|
return self.fd.write(bytes.advanced(by: dataRange.lowerBound), count: dataRange.count)
|
||||||
}
|
}
|
||||||
assert(written == dataRange.count)
|
assert(written == dataRange.count)
|
||||||
@ -457,7 +459,8 @@ final class MediaBoxPartialFile {
|
|||||||
self.fd.seek(position: Int64(actualRange.lowerBound))
|
self.fd.seek(position: Int64(actualRange.lowerBound))
|
||||||
var data = Data(count: actualRange.count)
|
var data = Data(count: actualRange.count)
|
||||||
let dataCount = data.count
|
let dataCount = data.count
|
||||||
let readBytes = data.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<Int8>) -> Int in
|
let readBytes = data.withUnsafeMutableBytes { rawBytes -> Int in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: Int8.self)
|
||||||
return self.fd.read(bytes, dataCount)
|
return self.fd.read(bytes, dataCount)
|
||||||
}
|
}
|
||||||
if readBytes == data.count {
|
if readBytes == data.count {
|
||||||
|
|||||||
@ -296,7 +296,6 @@ final class MessageHistoryHoleIndexTable: Table {
|
|||||||
}
|
}
|
||||||
let clippedRange = clippedLowerBound ... clippedUpperBound
|
let clippedRange = clippedLowerBound ... clippedUpperBound
|
||||||
|
|
||||||
var removedIndices = IndexSet()
|
|
||||||
var insertedIndices = IndexSet()
|
var insertedIndices = IndexSet()
|
||||||
var removeKeys: [Int32] = []
|
var removeKeys: [Int32] = []
|
||||||
var insertRanges = IndexSet()
|
var insertRanges = IndexSet()
|
||||||
@ -378,8 +377,6 @@ final class MessageHistoryHoleIndexTable: Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func removeInternal(peerId: PeerId, namespace: MessageId.Namespace, space: MessageHistoryHoleSpace, range: ClosedRange<MessageId.Id>, operations: inout [MessageHistoryIndexHoleOperationKey: [MessageHistoryIndexHoleOperation]]) {
|
private func removeInternal(peerId: PeerId, namespace: MessageId.Namespace, space: MessageHistoryHoleSpace, range: ClosedRange<MessageId.Id>, operations: inout [MessageHistoryIndexHoleOperationKey: [MessageHistoryIndexHoleOperation]]) {
|
||||||
var removedIndices = IndexSet()
|
|
||||||
var insertedIndices = IndexSet()
|
|
||||||
var removeKeys: [Int32] = []
|
var removeKeys: [Int32] = []
|
||||||
var insertRanges = IndexSet()
|
var insertRanges = IndexSet()
|
||||||
|
|
||||||
|
|||||||
@ -505,7 +505,7 @@ final class MessageHistoryReadStateTable: Table {
|
|||||||
override func beforeCommit() {
|
override func beforeCommit() {
|
||||||
if !self.updatedInitialPeerReadStates.isEmpty {
|
if !self.updatedInitialPeerReadStates.isEmpty {
|
||||||
let sharedBuffer = WriteBuffer()
|
let sharedBuffer = WriteBuffer()
|
||||||
for (id, initialNamespaces) in self.updatedInitialPeerReadStates {
|
for (id, _) in self.updatedInitialPeerReadStates {
|
||||||
if let wrappedStates = self.cachedPeerReadStates[id], let states = wrappedStates {
|
if let wrappedStates = self.cachedPeerReadStates[id], let states = wrappedStates {
|
||||||
sharedBuffer.reset()
|
sharedBuffer.reset()
|
||||||
var count: Int32 = Int32(states.namespaces.count)
|
var count: Int32 = Int32(states.namespaces.count)
|
||||||
|
|||||||
@ -20,7 +20,7 @@ private enum AdjacentEntryGroupInfo {
|
|||||||
|
|
||||||
private func getAdjacentEntryGroupInfo(_ entry: IntermediateMessageHistoryEntry?, key: Int64) -> (IntermediateMessageHistoryEntry?, AdjacentEntryGroupInfo) {
|
private func getAdjacentEntryGroupInfo(_ entry: IntermediateMessageHistoryEntry?, key: Int64) -> (IntermediateMessageHistoryEntry?, AdjacentEntryGroupInfo) {
|
||||||
if let entry = entry {
|
if let entry = entry {
|
||||||
if let groupingKey = entry.message.groupingKey, let groupInfo = entry.message.groupInfo {
|
if let groupingKey = entry.message.groupingKey, let _ = entry.message.groupInfo {
|
||||||
if groupingKey == key {
|
if groupingKey == key {
|
||||||
if let groupInfo = entry.message.groupInfo {
|
if let groupInfo = entry.message.groupInfo {
|
||||||
return (entry, .sameGroup(groupInfo))
|
return (entry, .sameGroup(groupInfo))
|
||||||
@ -2516,6 +2516,10 @@ final class MessageHistoryTable: Table {
|
|||||||
if let authorId = message.author?.id {
|
if let authorId = message.author?.id {
|
||||||
author = peerTable.get(authorId)
|
author = peerTable.get(authorId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let author = author {
|
||||||
|
peers[author.id] = author
|
||||||
|
}
|
||||||
|
|
||||||
if let chatPeer = peerTable.get(message.id.peerId) {
|
if let chatPeer = peerTable.get(message.id.peerId) {
|
||||||
peers[chatPeer.id] = chatPeer
|
peers[chatPeer.id] = chatPeer
|
||||||
|
|||||||
@ -268,7 +268,6 @@ final class MessageHistoryThreadHoleIndexTable: Table {
|
|||||||
}
|
}
|
||||||
let clippedRange = clippedLowerBound ... clippedUpperBound
|
let clippedRange = clippedLowerBound ... clippedUpperBound
|
||||||
|
|
||||||
var removedIndices = IndexSet()
|
|
||||||
var insertedIndices = IndexSet()
|
var insertedIndices = IndexSet()
|
||||||
var removeKeys: [Int32] = []
|
var removeKeys: [Int32] = []
|
||||||
var insertRanges = IndexSet()
|
var insertRanges = IndexSet()
|
||||||
@ -351,8 +350,6 @@ final class MessageHistoryThreadHoleIndexTable: Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func removeInternal(peerId: PeerId, threadId: Int64, namespace: MessageId.Namespace, space: MessageHistoryHoleSpace, range: ClosedRange<MessageId.Id>, operations: inout [MessageHistoryIndexHoleOperationKey: [MessageHistoryIndexHoleOperation]]) {
|
private func removeInternal(peerId: PeerId, threadId: Int64, namespace: MessageId.Namespace, space: MessageHistoryHoleSpace, range: ClosedRange<MessageId.Id>, operations: inout [MessageHistoryIndexHoleOperationKey: [MessageHistoryIndexHoleOperation]]) {
|
||||||
var removedIndices = IndexSet()
|
|
||||||
var insertedIndices = IndexSet()
|
|
||||||
var removeKeys: [Int32] = []
|
var removeKeys: [Int32] = []
|
||||||
var insertRanges = IndexSet()
|
var insertRanges = IndexSet()
|
||||||
|
|
||||||
|
|||||||
@ -113,7 +113,7 @@ final class MutableMessageOfInterestHolesView: MutablePostboxView {
|
|||||||
}
|
}
|
||||||
var anchor: HistoryViewInputAnchor = self.anchor
|
var anchor: HistoryViewInputAnchor = self.anchor
|
||||||
if transaction.alteredInitialPeerCombinedReadStates[peerId] != nil {
|
if transaction.alteredInitialPeerCombinedReadStates[peerId] != nil {
|
||||||
var updatedAnchor: HistoryViewInputAnchor = .upperBound
|
let updatedAnchor: HistoryViewInputAnchor = .upperBound
|
||||||
if let combinedState = postbox.readStateTable.getCombinedState(peerId), let state = combinedState.states.first, state.1.count != 0 {
|
if let combinedState = postbox.readStateTable.getCombinedState(peerId), let state = combinedState.states.first, state.1.count != 0 {
|
||||||
switch state.1 {
|
switch state.1 {
|
||||||
case let .idBased(maxIncomingReadId, _, _, _, _):
|
case let .idBased(maxIncomingReadId, _, _, _, _):
|
||||||
|
|||||||
@ -19,9 +19,9 @@ public struct NoticeEntryKey: Hashable {
|
|||||||
public static func ==(lhs: NoticeEntryKey, rhs: NoticeEntryKey) -> Bool {
|
public static func ==(lhs: NoticeEntryKey, rhs: NoticeEntryKey) -> Bool {
|
||||||
return lhs.combinedKey == rhs.combinedKey
|
return lhs.combinedKey == rhs.combinedKey
|
||||||
}
|
}
|
||||||
|
|
||||||
public var hashValue: Int {
|
public func hash(into hasher: inout Hasher) {
|
||||||
return self.combinedKey.hashValue
|
hasher.combine(self.combinedKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -205,7 +205,7 @@ final class OrderedItemListTable: Table {
|
|||||||
|
|
||||||
func remove(collectionId: Int32, itemId: MemoryBuffer, operations: inout [Int32: [OrderedItemListOperation]]) {
|
func remove(collectionId: Int32, itemId: MemoryBuffer, operations: inout [Int32: [OrderedItemListOperation]]) {
|
||||||
if let index = self.getIndex(collectionId: collectionId, id: itemId) {
|
if let index = self.getIndex(collectionId: collectionId, id: itemId) {
|
||||||
var orderedIds = self.getItemIds(collectionId: collectionId)
|
let orderedIds = self.getItemIds(collectionId: collectionId)
|
||||||
|
|
||||||
if !orderedIds.isEmpty {
|
if !orderedIds.isEmpty {
|
||||||
self.valueBox.remove(self.table, key: self.keyIdToIndex(collectionId: collectionId, id: itemId), secure: false)
|
self.valueBox.remove(self.table, key: self.keyIdToIndex(collectionId: collectionId, id: itemId), secure: false)
|
||||||
|
|||||||
@ -154,7 +154,7 @@ public struct PeerId: Hashable, CustomStringConvertible, Comparable, Codable {
|
|||||||
let namespaceBits = ((data >> 32) & 0x7)
|
let namespaceBits = ((data >> 32) & 0x7)
|
||||||
self.namespace = Namespace(rawValue: UInt32(namespaceBits))
|
self.namespace = Namespace(rawValue: UInt32(namespaceBits))
|
||||||
|
|
||||||
let idHighBits = (data >> (32 + 3)) & 0xffffffff
|
//let idHighBits = (data >> (32 + 3)) & 0xffffffff
|
||||||
//assert(idHighBits == 0)
|
//assert(idHighBits == 0)
|
||||||
|
|
||||||
self.id = Id(rawValue: Int32(bitPattern: UInt32(clamping: idLowBits)))
|
self.id = Id(rawValue: Int32(bitPattern: UInt32(clamping: idLowBits)))
|
||||||
@ -260,7 +260,7 @@ public struct PeerId: Hashable, CustomStringConvertible, Comparable, Codable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol Peer: class, PostboxCoding {
|
public protocol Peer: AnyObject, PostboxCoding {
|
||||||
var id: PeerId { get }
|
var id: PeerId { get }
|
||||||
var indexName: PeerIndexNameRepresentation { get }
|
var indexName: PeerIndexNameRepresentation { get }
|
||||||
var associatedPeerId: PeerId? { get }
|
var associatedPeerId: PeerId? { get }
|
||||||
|
|||||||
@ -1,14 +1,31 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class PeerNotificationSettingsDecodeHelper {
|
||||||
|
public let decode: (_ data: Data) -> PeerNotificationSettings?
|
||||||
|
|
||||||
|
public init(decode: @escaping (_ data: Data) -> PeerNotificationSettings?) {
|
||||||
|
self.decode = decode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PeerNotificationSettingsBehavior {
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case _case = "_v"
|
||||||
|
case toValue
|
||||||
|
case atTimestamp
|
||||||
|
}
|
||||||
|
|
||||||
public enum PeerNotificationSettingsBehavior: PostboxCoding {
|
|
||||||
case none
|
case none
|
||||||
case reset(atTimestamp: Int32, toValue: PeerNotificationSettings)
|
case reset(atTimestamp: Int32, toValue: PeerNotificationSettings)
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(from decoder: Decoder, helper: PeerNotificationSettingsDecodeHelper) throws {
|
||||||
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
|
|
||||||
switch decoder.decodeInt32ForKey("_v", orElse: 0) {
|
switch decoder.decodeInt32ForKey("_v", orElse: 0) {
|
||||||
case 0:
|
case 0:
|
||||||
self = .none
|
self = .none
|
||||||
case 1:
|
case 1:
|
||||||
if let toValue = decoder.decodeObjectForKey("toValue") as? PeerNotificationSettings {
|
if let toValue = helper.decode(PeerNotificationSettings.self, forKey: "toValue") {
|
||||||
self = .reset(atTimestamp: decoder.decodeInt32ForKey("atTimestamp", orElse: 0), toValue: toValue)
|
self = .reset(atTimestamp: decoder.decodeInt32ForKey("atTimestamp", orElse: 0), toValue: toValue)
|
||||||
} else {
|
} else {
|
||||||
assertionFailure()
|
assertionFailure()
|
||||||
@ -27,26 +44,29 @@ public enum PeerNotificationSettingsBehavior: PostboxCoding {
|
|||||||
case let .reset(atTimestamp, toValue):
|
case let .reset(atTimestamp, toValue):
|
||||||
encoder.encodeInt32(1, forKey: "_v")
|
encoder.encodeInt32(1, forKey: "_v")
|
||||||
encoder.encodeInt32(atTimestamp, forKey: "atTimestamp")
|
encoder.encodeInt32(atTimestamp, forKey: "atTimestamp")
|
||||||
encoder.encodeObject(toValue, forKey: "toValue")
|
encoder.encode(toValue, forKey: "toValue")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol PeerNotificationSettings: PostboxCoding {
|
public protocol PeerNotificationSettings: Codable {
|
||||||
func isRemovedFromTotalUnreadCount(`default`: Bool) -> Bool
|
func isRemovedFromTotalUnreadCount(`default`: Bool) -> Bool
|
||||||
|
|
||||||
var behavior: PeerNotificationSettingsBehavior { get }
|
var behavior: PeerNotificationSettingsBehavior { get }
|
||||||
|
|
||||||
func isEqual(to: PeerNotificationSettings) -> Bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol PostboxGlobalNotificationSettings: PostboxCoding {
|
public final class PostboxGlobalNotificationSettings {
|
||||||
func defaultIncludePeer(peer: Peer) -> Bool
|
public let defaultIncludePeer: (_ peer: Peer) -> Bool
|
||||||
|
|
||||||
func isEqualInDefaultPeerInclusion(other: PostboxGlobalNotificationSettings) -> Bool
|
public init(
|
||||||
|
defaultIncludePeer: @escaping (_ peer: Peer) -> Bool
|
||||||
|
) {
|
||||||
|
self.defaultIncludePeer = defaultIncludePeer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func resolvedIsRemovedFromTotalUnreadCount(globalSettings: PostboxGlobalNotificationSettings, peer: Peer, peerSettings: PeerNotificationSettings?) -> Bool {
|
public func resolvedIsRemovedFromTotalUnreadCount(globalSettings: PostboxGlobalNotificationSettings, peer: Peer, peerSettings: PeerNotificationSettings?) -> Bool {
|
||||||
let defaultValue = !globalSettings.defaultIncludePeer(peer: peer)
|
let defaultValue = !globalSettings.defaultIncludePeer(peer)
|
||||||
if let peerSettings = peerSettings {
|
if let peerSettings = peerSettings {
|
||||||
return peerSettings.isRemovedFromTotalUnreadCount(default: defaultValue)
|
return peerSettings.isRemovedFromTotalUnreadCount(default: defaultValue)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -195,7 +195,7 @@ final class PeerNotificationSettingsTable: Table {
|
|||||||
self.updatedInitialSettings.removeAll()
|
self.updatedInitialSettings.removeAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
func transactionParticipationInTotalUnreadCountUpdates(postbox: Postbox) -> (added: Set<PeerId>, removed: Set<PeerId>) {
|
func transactionParticipationInTotalUnreadCountUpdates(postbox: Postbox, transaction: Transaction) -> (added: Set<PeerId>, removed: Set<PeerId>) {
|
||||||
var added = Set<PeerId>()
|
var added = Set<PeerId>()
|
||||||
var removed = Set<PeerId>()
|
var removed = Set<PeerId>()
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ final class PeerNotificationSettingsTable: Table {
|
|||||||
if let current = globalNotificationSettings {
|
if let current = globalNotificationSettings {
|
||||||
globalNotificationSettingsValue = current
|
globalNotificationSettingsValue = current
|
||||||
} else {
|
} else {
|
||||||
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings()
|
globalNotificationSettingsValue = postbox.getGlobalNotificationSettings(transaction: transaction)
|
||||||
globalNotificationSettings = globalNotificationSettingsValue
|
globalNotificationSettings = globalNotificationSettingsValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
public protocol PeerPresence: class, PostboxCoding {
|
public protocol PeerPresence: AnyObject, PostboxCoding {
|
||||||
func isEqual(to: PeerPresence) -> Bool
|
func isEqual(to: PeerPresence) -> Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,32 +3,6 @@ import Foundation
|
|||||||
enum PendingMessageActionsMetadataCountKey: Hashable {
|
enum PendingMessageActionsMetadataCountKey: Hashable {
|
||||||
case peerNamespace(PeerId, MessageId.Namespace)
|
case peerNamespace(PeerId, MessageId.Namespace)
|
||||||
case peerNamespaceAction(PeerId, MessageId.Namespace, PendingMessageActionType)
|
case peerNamespaceAction(PeerId, MessageId.Namespace, PendingMessageActionType)
|
||||||
|
|
||||||
static func ==(lhs: PendingMessageActionsMetadataCountKey, rhs: PendingMessageActionsMetadataCountKey) -> Bool {
|
|
||||||
switch lhs {
|
|
||||||
case let .peerNamespace(peerId, namespace):
|
|
||||||
if case .peerNamespace(peerId, namespace) = rhs {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .peerNamespaceAction(peerId, namespace, actionType):
|
|
||||||
if case .peerNamespaceAction(peerId, namespace, actionType) = rhs {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var hashValue: Int {
|
|
||||||
switch self {
|
|
||||||
case let .peerNamespace(peerId, namespace):
|
|
||||||
return peerId.hashValue ^ namespace.hashValue
|
|
||||||
case let .peerNamespaceAction(peerId, namespace, actionType):
|
|
||||||
return peerId.hashValue ^ namespace.hashValue ^ actionType.hashValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PendingMessageActionsMetadataKey {
|
enum PendingMessageActionsMetadataKey {
|
||||||
|
|||||||
@ -269,7 +269,7 @@ public final class Transaction {
|
|||||||
public func getGlobalNotificationSettings() -> PostboxGlobalNotificationSettings {
|
public func getGlobalNotificationSettings() -> PostboxGlobalNotificationSettings {
|
||||||
assert(!self.disposed)
|
assert(!self.disposed)
|
||||||
if let postbox = self.postbox {
|
if let postbox = self.postbox {
|
||||||
return postbox.getGlobalNotificationSettings()
|
return postbox.getGlobalNotificationSettings(transaction: self)
|
||||||
} else {
|
} else {
|
||||||
preconditionFailure()
|
preconditionFailure()
|
||||||
}
|
}
|
||||||
@ -369,7 +369,7 @@ public final class Transaction {
|
|||||||
public func getUnreadChatListPeerIds(groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?) -> [PeerId] {
|
public func getUnreadChatListPeerIds(groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate?) -> [PeerId] {
|
||||||
assert(!self.disposed)
|
assert(!self.disposed)
|
||||||
if let postbox = self.postbox {
|
if let postbox = self.postbox {
|
||||||
return postbox.chatListTable.getUnreadChatListPeerIds(postbox: postbox, groupId: groupId, filterPredicate: filterPredicate)
|
return postbox.chatListTable.getUnreadChatListPeerIds(postbox: postbox, currentTransaction: self, groupId: groupId, filterPredicate: filterPredicate)
|
||||||
} else {
|
} else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@ -805,6 +805,11 @@ public final class Transaction {
|
|||||||
assert(!self.disposed)
|
assert(!self.disposed)
|
||||||
self.postbox?.setPreferencesEntry(key: key, value: f(self.postbox?.getPreferencesEntry(key: key)))
|
self.postbox?.setPreferencesEntry(key: key, value: f(self.postbox?.getPreferencesEntry(key: key)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func globalNotificationSettingsUpdated() {
|
||||||
|
assert(!self.disposed)
|
||||||
|
self.postbox?.globalNotificationSettingsUpdated()
|
||||||
|
}
|
||||||
|
|
||||||
public func getPinnedItemIds(groupId: PeerGroupId) -> [PinnedItemId] {
|
public func getPinnedItemIds(groupId: PeerGroupId) -> [PinnedItemId] {
|
||||||
assert(!self.disposed)
|
assert(!self.disposed)
|
||||||
@ -1048,7 +1053,7 @@ public final class Transaction {
|
|||||||
|
|
||||||
public func getRelativeUnreadChatListIndex(filtered: Bool, position: ChatListRelativePosition, groupId: PeerGroupId) -> ChatListIndex? {
|
public func getRelativeUnreadChatListIndex(filtered: Bool, position: ChatListRelativePosition, groupId: PeerGroupId) -> ChatListIndex? {
|
||||||
assert(!self.disposed)
|
assert(!self.disposed)
|
||||||
return self.postbox?.getRelativeUnreadChatListIndex(filtered: filtered, position: position, groupId: groupId)
|
return self.postbox?.getRelativeUnreadChatListIndex(currentTransaction: self, filtered: filtered, position: position, groupId: groupId)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getDeviceContactImportInfo(_ identifier: ValueBoxKey) -> PostboxCoding? {
|
public func getDeviceContactImportInfo(_ identifier: ValueBoxKey) -> PostboxCoding? {
|
||||||
@ -1110,7 +1115,7 @@ public final class Transaction {
|
|||||||
|
|
||||||
public func reindexUnreadCounters() {
|
public func reindexUnreadCounters() {
|
||||||
assert(!self.disposed)
|
assert(!self.disposed)
|
||||||
self.postbox?.reindexUnreadCounters()
|
self.postbox?.reindexUnreadCounters(currentTransaction: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func searchPeers(query: String) -> [RenderedPeer] {
|
public func searchPeers(query: String) -> [RenderedPeer] {
|
||||||
@ -1215,7 +1220,7 @@ public func openPostbox(basePath: String, seedConfiguration: SeedConfiguration,
|
|||||||
let userVersion: Int32? = metadataTable.userVersion()
|
let userVersion: Int32? = metadataTable.userVersion()
|
||||||
let currentUserVersion: Int32 = 25
|
let currentUserVersion: Int32 = 25
|
||||||
|
|
||||||
postboxLog("openPostbox, current userVersion: \(userVersion ?? nil)")
|
postboxLog("openPostbox, current userVersion: \(String(describing: userVersion ?? nil))")
|
||||||
|
|
||||||
if let userVersion = userVersion {
|
if let userVersion = userVersion {
|
||||||
if userVersion != currentUserVersion {
|
if userVersion != currentUserVersion {
|
||||||
@ -1607,7 +1612,7 @@ public final class Postbox {
|
|||||||
if !isTemporary && self.messageHistoryMetadataTable.shouldReindexUnreadCounts() {
|
if !isTemporary && self.messageHistoryMetadataTable.shouldReindexUnreadCounts() {
|
||||||
self.groupMessageStatsTable.removeAll()
|
self.groupMessageStatsTable.removeAll()
|
||||||
let startTime = CFAbsoluteTimeGetCurrent()
|
let startTime = CFAbsoluteTimeGetCurrent()
|
||||||
let (totalStates, summaries) = self.chatListIndexTable.debugReindexUnreadCounts(postbox: self)
|
let (totalStates, summaries) = self.chatListIndexTable.debugReindexUnreadCounts(postbox: self, currentTransaction: transaction)
|
||||||
|
|
||||||
self.messageHistoryMetadataTable.removeAllTotalUnreadStates()
|
self.messageHistoryMetadataTable.removeAllTotalUnreadStates()
|
||||||
for (groupId, state) in totalStates {
|
for (groupId, state) in totalStates {
|
||||||
@ -1924,13 +1929,13 @@ public final class Postbox {
|
|||||||
return renderedMessage
|
return renderedMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
private func afterBegin() {
|
private func afterBegin(transaction: Transaction) {
|
||||||
let currentTransactionStateVersion = self.metadataTable.transactionStateVersion()
|
let currentTransactionStateVersion = self.metadataTable.transactionStateVersion()
|
||||||
if currentTransactionStateVersion != self.transactionStateVersion {
|
if currentTransactionStateVersion != self.transactionStateVersion {
|
||||||
for table in self.tables {
|
for table in self.tables {
|
||||||
table.clearMemoryCache()
|
table.clearMemoryCache()
|
||||||
}
|
}
|
||||||
self.viewTracker.refreshViewsDueToExternalTransaction(postbox: self, fetchUnsentMessageIds: {
|
self.viewTracker.refreshViewsDueToExternalTransaction(postbox: self, currentTransaction: transaction, fetchUnsentMessageIds: {
|
||||||
return self.messageHistoryUnsentTable.get()
|
return self.messageHistoryUnsentTable.get()
|
||||||
}, fetchSynchronizePeerReadStateOperations: {
|
}, fetchSynchronizePeerReadStateOperations: {
|
||||||
return self.synchronizeReadStateTable.get(getCombinedPeerReadState: { peerId in
|
return self.synchronizeReadStateTable.get(getCombinedPeerReadState: { peerId in
|
||||||
@ -1943,7 +1948,7 @@ public final class Postbox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func beforeCommit() -> (updatedTransactionStateVersion: Int64?, updatedMasterClientId: Int64?) {
|
private func beforeCommit(currentTransaction: Transaction) -> (updatedTransactionStateVersion: Int64?, updatedMasterClientId: Int64?) {
|
||||||
self.chatListTable.replay(historyOperationsByPeerId: self.currentOperationsByPeerId, updatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, updatedChatListInclusions: self.currentUpdatedChatListInclusions, messageHistoryTable: self.messageHistoryTable, peerChatInterfaceStateTable: self.peerChatInterfaceStateTable, operations: &self.currentChatListOperations)
|
self.chatListTable.replay(historyOperationsByPeerId: self.currentOperationsByPeerId, updatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, updatedChatListInclusions: self.currentUpdatedChatListInclusions, messageHistoryTable: self.messageHistoryTable, peerChatInterfaceStateTable: self.peerChatInterfaceStateTable, operations: &self.currentChatListOperations)
|
||||||
|
|
||||||
self.peerChatTopTaggedMessageIdsTable.replay(historyOperationsByPeerId: self.currentOperationsByPeerId)
|
self.peerChatTopTaggedMessageIdsTable.replay(historyOperationsByPeerId: self.currentOperationsByPeerId)
|
||||||
@ -1969,18 +1974,18 @@ public final class Postbox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let transactionParticipationInTotalUnreadCountUpdates = self.peerNotificationSettingsTable.transactionParticipationInTotalUnreadCountUpdates(postbox: self)
|
let transactionParticipationInTotalUnreadCountUpdates = self.peerNotificationSettingsTable.transactionParticipationInTotalUnreadCountUpdates(postbox: self, transaction: currentTransaction)
|
||||||
self.chatListIndexTable.commitWithTransaction(postbox: self, alteredInitialPeerCombinedReadStates: alteredInitialPeerCombinedReadStates, updatedPeers: updatedPeers, transactionParticipationInTotalUnreadCountUpdates: transactionParticipationInTotalUnreadCountUpdates, updatedTotalUnreadStates: &self.currentUpdatedTotalUnreadStates, updatedGroupTotalUnreadSummaries: &self.currentUpdatedGroupTotalUnreadSummaries, currentUpdatedGroupSummarySynchronizeOperations: &self.currentUpdatedGroupSummarySynchronizeOperations)
|
self.chatListIndexTable.commitWithTransaction(postbox: self, currentTransaction: currentTransaction, alteredInitialPeerCombinedReadStates: alteredInitialPeerCombinedReadStates, updatedPeers: updatedPeers, transactionParticipationInTotalUnreadCountUpdates: transactionParticipationInTotalUnreadCountUpdates, updatedTotalUnreadStates: &self.currentUpdatedTotalUnreadStates, updatedGroupTotalUnreadSummaries: &self.currentUpdatedGroupTotalUnreadSummaries, currentUpdatedGroupSummarySynchronizeOperations: &self.currentUpdatedGroupSummarySynchronizeOperations)
|
||||||
|
|
||||||
if self.currentNeedsReindexUnreadCounters {
|
if self.currentNeedsReindexUnreadCounters {
|
||||||
self.reindexUnreadCounters()
|
self.reindexUnreadCounters(currentTransaction: currentTransaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
let transaction = PostboxTransaction(currentUpdatedState: self.currentUpdatedState, currentPeerHoleOperations: self.currentPeerHoleOperations, currentOperationsByPeerId: self.currentOperationsByPeerId, chatListOperations: self.currentChatListOperations, currentUpdatedChatListInclusions: self.currentUpdatedChatListInclusions, currentUpdatedPeers: self.currentUpdatedPeers, currentUpdatedPeerNotificationSettings: self.currentUpdatedPeerNotificationSettings, currentUpdatedPeerNotificationBehaviorTimestamps: self.currentUpdatedPeerNotificationBehaviorTimestamps, currentUpdatedCachedPeerData: self.currentUpdatedCachedPeerData, currentUpdatedPeerPresences: currentUpdatedPeerPresences, currentUpdatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, currentUpdatedTotalUnreadStates: self.currentUpdatedTotalUnreadStates, currentUpdatedTotalUnreadSummaries: self.currentUpdatedGroupTotalUnreadSummaries, alteredInitialPeerCombinedReadStates: alteredInitialPeerCombinedReadStates, currentPeerMergedOperationLogOperations: self.currentPeerMergedOperationLogOperations, currentTimestampBasedMessageAttributesOperations: self.currentTimestampBasedMessageAttributesOperations, unsentMessageOperations: self.currentUnsentOperations, updatedSynchronizePeerReadStateOperations: self.currentUpdatedSynchronizeReadStateOperations, currentUpdatedGroupSummarySynchronizeOperations: self.currentUpdatedGroupSummarySynchronizeOperations, currentPreferencesOperations: self.currentPreferencesOperations, currentOrderedItemListOperations: self.currentOrderedItemListOperations, currentItemCollectionItemsOperations: self.currentItemCollectionItemsOperations, currentItemCollectionInfosOperations: self.currentItemCollectionInfosOperations, currentUpdatedPeerChatStates: self.currentUpdatedPeerChatStates, currentGlobalTagsOperations: self.currentGlobalTagsOperations, currentLocalTagsOperations: self.currentLocalTagsOperations, updatedMedia: self.currentUpdatedMedia, replaceRemoteContactCount: self.currentReplaceRemoteContactCount, replaceContactPeerIds: self.currentReplacedContactPeerIds, currentPendingMessageActionsOperations: self.currentPendingMessageActionsOperations, currentUpdatedMessageActionsSummaries: self.currentUpdatedMessageActionsSummaries, currentUpdatedMessageTagSummaries: self.currentUpdatedMessageTagSummaries, currentInvalidateMessageTagSummaries: self.currentInvalidateMessageTagSummaries, currentUpdatedPendingPeerNotificationSettings: self.currentUpdatedPendingPeerNotificationSettings, replacedAdditionalChatListItems: self.currentReplacedAdditionalChatListItems, updatedNoticeEntryKeys: self.currentUpdatedNoticeEntryKeys, updatedCacheEntryKeys: self.currentUpdatedCacheEntryKeys, currentUpdatedMasterClientId: currentUpdatedMasterClientId, updatedFailedMessagePeerIds: self.messageHistoryFailedTable.updatedPeerIds, updatedFailedMessageIds: self.messageHistoryFailedTable.updatedMessageIds, updatedGlobalNotificationSettings: self.currentNeedsReindexUnreadCounters)
|
let transaction = PostboxTransaction(currentUpdatedState: self.currentUpdatedState, currentPeerHoleOperations: self.currentPeerHoleOperations, currentOperationsByPeerId: self.currentOperationsByPeerId, chatListOperations: self.currentChatListOperations, currentUpdatedChatListInclusions: self.currentUpdatedChatListInclusions, currentUpdatedPeers: self.currentUpdatedPeers, currentUpdatedPeerNotificationSettings: self.currentUpdatedPeerNotificationSettings, currentUpdatedPeerNotificationBehaviorTimestamps: self.currentUpdatedPeerNotificationBehaviorTimestamps, currentUpdatedCachedPeerData: self.currentUpdatedCachedPeerData, currentUpdatedPeerPresences: currentUpdatedPeerPresences, currentUpdatedPeerChatListEmbeddedStates: self.currentUpdatedPeerChatListEmbeddedStates, currentUpdatedTotalUnreadStates: self.currentUpdatedTotalUnreadStates, currentUpdatedTotalUnreadSummaries: self.currentUpdatedGroupTotalUnreadSummaries, alteredInitialPeerCombinedReadStates: alteredInitialPeerCombinedReadStates, currentPeerMergedOperationLogOperations: self.currentPeerMergedOperationLogOperations, currentTimestampBasedMessageAttributesOperations: self.currentTimestampBasedMessageAttributesOperations, unsentMessageOperations: self.currentUnsentOperations, updatedSynchronizePeerReadStateOperations: self.currentUpdatedSynchronizeReadStateOperations, currentUpdatedGroupSummarySynchronizeOperations: self.currentUpdatedGroupSummarySynchronizeOperations, currentPreferencesOperations: self.currentPreferencesOperations, currentOrderedItemListOperations: self.currentOrderedItemListOperations, currentItemCollectionItemsOperations: self.currentItemCollectionItemsOperations, currentItemCollectionInfosOperations: self.currentItemCollectionInfosOperations, currentUpdatedPeerChatStates: self.currentUpdatedPeerChatStates, currentGlobalTagsOperations: self.currentGlobalTagsOperations, currentLocalTagsOperations: self.currentLocalTagsOperations, updatedMedia: self.currentUpdatedMedia, replaceRemoteContactCount: self.currentReplaceRemoteContactCount, replaceContactPeerIds: self.currentReplacedContactPeerIds, currentPendingMessageActionsOperations: self.currentPendingMessageActionsOperations, currentUpdatedMessageActionsSummaries: self.currentUpdatedMessageActionsSummaries, currentUpdatedMessageTagSummaries: self.currentUpdatedMessageTagSummaries, currentInvalidateMessageTagSummaries: self.currentInvalidateMessageTagSummaries, currentUpdatedPendingPeerNotificationSettings: self.currentUpdatedPendingPeerNotificationSettings, replacedAdditionalChatListItems: self.currentReplacedAdditionalChatListItems, updatedNoticeEntryKeys: self.currentUpdatedNoticeEntryKeys, updatedCacheEntryKeys: self.currentUpdatedCacheEntryKeys, currentUpdatedMasterClientId: currentUpdatedMasterClientId, updatedFailedMessagePeerIds: self.messageHistoryFailedTable.updatedPeerIds, updatedFailedMessageIds: self.messageHistoryFailedTable.updatedMessageIds, updatedGlobalNotificationSettings: self.currentNeedsReindexUnreadCounters)
|
||||||
var updatedTransactionState: Int64?
|
var updatedTransactionState: Int64?
|
||||||
var updatedMasterClientId: Int64?
|
var updatedMasterClientId: Int64?
|
||||||
if !transaction.isEmpty {
|
if !transaction.isEmpty {
|
||||||
self.viewTracker.updateViews(postbox: self, transaction: transaction)
|
self.viewTracker.updateViews(postbox: self, currentTransaction: currentTransaction, transaction: transaction)
|
||||||
self.transactionStateVersion = self.metadataTable.incrementTransactionStateVersion()
|
self.transactionStateVersion = self.metadataTable.incrementTransactionStateVersion()
|
||||||
updatedTransactionState = self.transactionStateVersion
|
updatedTransactionState = self.transactionStateVersion
|
||||||
|
|
||||||
@ -2466,11 +2471,11 @@ public final class Postbox {
|
|||||||
|
|
||||||
private func internalTransaction<T>(_ f: (Transaction) -> T) -> (result: T, updatedTransactionStateVersion: Int64?, updatedMasterClientId: Int64?) {
|
private func internalTransaction<T>(_ f: (Transaction) -> T) -> (result: T, updatedTransactionStateVersion: Int64?, updatedMasterClientId: Int64?) {
|
||||||
self.valueBox.begin()
|
self.valueBox.begin()
|
||||||
self.afterBegin()
|
|
||||||
let transaction = Transaction(postbox: self)
|
let transaction = Transaction(postbox: self)
|
||||||
|
self.afterBegin(transaction: transaction)
|
||||||
let result = f(transaction)
|
let result = f(transaction)
|
||||||
|
let (updatedTransactionState, updatedMasterClientId) = self.beforeCommit(currentTransaction: transaction)
|
||||||
transaction.disposed = true
|
transaction.disposed = true
|
||||||
let (updatedTransactionState, updatedMasterClientId) = self.beforeCommit()
|
|
||||||
self.valueBox.commit()
|
self.valueBox.commit()
|
||||||
|
|
||||||
if let currentUpdatedState = self.currentUpdatedState {
|
if let currentUpdatedState = self.currentUpdatedState {
|
||||||
@ -2889,7 +2894,7 @@ public final class Postbox {
|
|||||||
|
|
||||||
public func aroundChatListView(groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate? = nil, index: ChatListIndex, count: Int, summaryComponents: ChatListEntrySummaryComponents, userInteractive: Bool = false) -> Signal<(ChatListView, ViewUpdateType), NoError> {
|
public func aroundChatListView(groupId: PeerGroupId, filterPredicate: ChatListFilterPredicate? = nil, index: ChatListIndex, count: Int, summaryComponents: ChatListEntrySummaryComponents, userInteractive: Bool = false) -> Signal<(ChatListView, ViewUpdateType), NoError> {
|
||||||
return self.transactionSignal(userInteractive: userInteractive, { subscriber, transaction in
|
return self.transactionSignal(userInteractive: userInteractive, { subscriber, transaction in
|
||||||
let mutableView = MutableChatListView(postbox: self, groupId: groupId, filterPredicate: filterPredicate, aroundIndex: index, count: count, summaryComponents: summaryComponents)
|
let mutableView = MutableChatListView(postbox: self, currentTransaction: transaction, groupId: groupId, filterPredicate: filterPredicate, aroundIndex: index, count: count, summaryComponents: summaryComponents)
|
||||||
mutableView.render(postbox: self)
|
mutableView.render(postbox: self)
|
||||||
|
|
||||||
let (index, signal) = self.viewTracker.addChatListView(mutableView)
|
let (index, signal) = self.viewTracker.addChatListView(mutableView)
|
||||||
@ -3383,16 +3388,12 @@ public final class Postbox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func setPreferencesEntry(key: ValueBoxKey, value: PreferencesEntry?) {
|
fileprivate func setPreferencesEntry(key: ValueBoxKey, value: PreferencesEntry?) {
|
||||||
if key == self.seedConfiguration.globalNotificationSettingsPreferencesKey {
|
|
||||||
let current = self.getGlobalNotificationSettings()
|
|
||||||
let updated = value as? PostboxGlobalNotificationSettings ?? self.seedConfiguration.defaultGlobalNotificationSettings
|
|
||||||
if !current.isEqualInDefaultPeerInclusion(other: updated) {
|
|
||||||
self.currentNeedsReindexUnreadCounters = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.preferencesTable.set(key: key, value: value, operations: &self.currentPreferencesOperations)
|
self.preferencesTable.set(key: key, value: value, operations: &self.currentPreferencesOperations)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate func globalNotificationSettingsUpdated() {
|
||||||
|
self.currentNeedsReindexUnreadCounters = true
|
||||||
|
}
|
||||||
|
|
||||||
fileprivate func replaceOrderedItemListItems(collectionId: Int32, items: [OrderedItemListEntry]) {
|
fileprivate func replaceOrderedItemListItems(collectionId: Int32, items: [OrderedItemListEntry]) {
|
||||||
self.orderedItemListTable.replaceItems(collectionId: collectionId, items: items, operations: &self.currentOrderedItemListOperations)
|
self.orderedItemListTable.replaceItems(collectionId: collectionId, items: items, operations: &self.currentOrderedItemListOperations)
|
||||||
@ -3506,8 +3507,8 @@ public final class Postbox {
|
|||||||
self.invalidatedMessageHistoryTagsSummaryTable.remove(entry, operations: &self.currentInvalidateMessageTagSummaries)
|
self.invalidatedMessageHistoryTagsSummaryTable.remove(entry, operations: &self.currentInvalidateMessageTagSummaries)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func getRelativeUnreadChatListIndex(filtered: Bool, position: ChatListRelativePosition, groupId: PeerGroupId) -> ChatListIndex? {
|
fileprivate func getRelativeUnreadChatListIndex(currentTransaction: Transaction, filtered: Bool, position: ChatListRelativePosition, groupId: PeerGroupId) -> ChatListIndex? {
|
||||||
return self.chatListTable.getRelativeUnreadChatListIndex(postbox: self, filtered: filtered, position: position, groupId: groupId)
|
return self.chatListTable.getRelativeUnreadChatListIndex(postbox: self, currentTransaction: currentTransaction, filtered: filtered, position: position, groupId: groupId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMessage(_ id: MessageId) -> Message? {
|
func getMessage(_ id: MessageId) -> Message? {
|
||||||
@ -3561,8 +3562,8 @@ public final class Postbox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGlobalNotificationSettings() -> PostboxGlobalNotificationSettings {
|
func getGlobalNotificationSettings(transaction: Transaction) -> PostboxGlobalNotificationSettings {
|
||||||
return self.preferencesTable.get(key: self.seedConfiguration.globalNotificationSettingsPreferencesKey) as? PostboxGlobalNotificationSettings ?? self.seedConfiguration.defaultGlobalNotificationSettings
|
return self.seedConfiguration.getGlobalNotificationSettings(transaction) ?? self.seedConfiguration.defaultGlobalNotificationSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isMasterClient() -> Signal<Bool, NoError> {
|
public func isMasterClient() -> Signal<Bool, NoError> {
|
||||||
@ -3611,10 +3612,10 @@ public final class Postbox {
|
|||||||
self.timestampBasedMessageAttributesTable.remove(tag: tag, id: id, operations: &self.currentTimestampBasedMessageAttributesOperations)
|
self.timestampBasedMessageAttributesTable.remove(tag: tag, id: id, operations: &self.currentTimestampBasedMessageAttributesOperations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func reindexUnreadCounters() {
|
fileprivate func reindexUnreadCounters(currentTransaction: Transaction) {
|
||||||
self.groupMessageStatsTable.removeAll()
|
self.groupMessageStatsTable.removeAll()
|
||||||
let _ = CFAbsoluteTimeGetCurrent()
|
let _ = CFAbsoluteTimeGetCurrent()
|
||||||
let (totalStates, summaries) = self.chatListIndexTable.debugReindexUnreadCounts(postbox: self)
|
let (totalStates, summaries) = self.chatListIndexTable.debugReindexUnreadCounts(postbox: self, currentTransaction: currentTransaction)
|
||||||
|
|
||||||
self.messageHistoryMetadataTable.removeAllTotalUnreadStates()
|
self.messageHistoryMetadataTable.removeAllTotalUnreadStates()
|
||||||
for (groupId, state) in totalStates {
|
for (groupId, state) in totalStates {
|
||||||
|
|||||||
@ -154,12 +154,10 @@ private func getReadStateCount(valueBox: ValueBox, table: ValueBoxTable, peerId:
|
|||||||
if let value = valueBox.get(table, key: key) {
|
if let value = valueBox.get(table, key: key) {
|
||||||
var count: Int32 = 0
|
var count: Int32 = 0
|
||||||
value.read(&count, offset: 0, length: 4)
|
value.read(&count, offset: 0, length: 4)
|
||||||
var stateByNamespace: [MessageId.Namespace: PeerReadState] = [:]
|
|
||||||
for _ in 0 ..< count {
|
for _ in 0 ..< count {
|
||||||
var namespaceId: Int32 = 0
|
var namespaceId: Int32 = 0
|
||||||
value.read(&namespaceId, offset: 0, length: 4)
|
value.read(&namespaceId, offset: 0, length: 4)
|
||||||
|
|
||||||
let state: PeerReadState
|
|
||||||
var kind: Int8 = 0
|
var kind: Int8 = 0
|
||||||
value.read(&kind, offset: 0, length: 1)
|
value.read(&kind, offset: 0, length: 1)
|
||||||
if kind == 0 {
|
if kind == 0 {
|
||||||
@ -207,8 +205,6 @@ private func getReadStateCount(valueBox: ValueBox, table: ValueBoxTable, peerId:
|
|||||||
|
|
||||||
func postboxUpgrade_16to17(metadataTable: MetadataTable, valueBox: ValueBox, progress: (Float) -> Void) {
|
func postboxUpgrade_16to17(metadataTable: MetadataTable, valueBox: ValueBox, progress: (Float) -> Void) {
|
||||||
let chatListIndexTable = ValueBoxTable(id: 8, keyType: .int64, compactValuesOnCreation: false)
|
let chatListIndexTable = ValueBoxTable(id: 8, keyType: .int64, compactValuesOnCreation: false)
|
||||||
let notificationSettingsTable = ValueBoxTable(id: 19, keyType: .int64, compactValuesOnCreation: false)
|
|
||||||
let readStateTable = ValueBoxTable(id: 14, keyType: .int64, compactValuesOnCreation: false)
|
|
||||||
let messageHistoryMetadataTable = ValueBoxTable(id: 10, keyType: .binary, compactValuesOnCreation: true)
|
let messageHistoryMetadataTable = ValueBoxTable(id: 10, keyType: .binary, compactValuesOnCreation: true)
|
||||||
|
|
||||||
var includedPeerIds: [PeerId] = []
|
var includedPeerIds: [PeerId] = []
|
||||||
|
|||||||
@ -1,9 +1,26 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol PreferencesEntry: PostboxCoding {
|
public final class PreferencesEntry: Equatable {
|
||||||
var relatedResources: [MediaResourceId] { get }
|
public let data: Data
|
||||||
|
|
||||||
func isEqual(to: PreferencesEntry) -> Bool
|
public init(data: Data) {
|
||||||
|
self.data = data
|
||||||
|
}
|
||||||
|
|
||||||
|
public init?<T: Encodable>(_ value: T) {
|
||||||
|
let encoder = PostboxEncoder()
|
||||||
|
encoder.encode(value, forKey: "_")
|
||||||
|
self.data = encoder.makeData()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func get<T: Decodable>(_ type: T.Type) -> T? {
|
||||||
|
let decoder = PostboxDecoder(buffer: MemoryBuffer(data: self.data))
|
||||||
|
return decoder.decode(T.self, forKey: "_")
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: PreferencesEntry, rhs: PreferencesEntry) -> Bool {
|
||||||
|
return lhs.data == rhs.data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension PreferencesEntry {
|
public extension PreferencesEntry {
|
||||||
|
|||||||
@ -18,11 +18,7 @@ final class PreferencesTable: Table {
|
|||||||
|
|
||||||
func enumerateEntries(_ f: (PreferencesEntry) -> Bool) {
|
func enumerateEntries(_ f: (PreferencesEntry) -> Bool) {
|
||||||
self.valueBox.scan(self.table, values: { _, value in
|
self.valueBox.scan(self.table, values: { _, value in
|
||||||
if let object = PostboxDecoder(buffer: value).decodeRootObject() as? PreferencesEntry {
|
return f(PreferencesEntry(data: value.makeData()))
|
||||||
return f(object)
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +26,8 @@ final class PreferencesTable: Table {
|
|||||||
if let cached = self.cachedEntries[key] {
|
if let cached = self.cachedEntries[key] {
|
||||||
return cached.entry
|
return cached.entry
|
||||||
} else {
|
} else {
|
||||||
if let value = self.valueBox.get(self.table, key: key), let object = PostboxDecoder(buffer: value).decodeRootObject() as? PreferencesEntry {
|
if let value = self.valueBox.get(self.table, key: key) {
|
||||||
|
let object = PreferencesEntry(data: value.makeData())
|
||||||
self.cachedEntries[key] = CachedEntry(entry: object)
|
self.cachedEntries[key] = CachedEntry(entry: object)
|
||||||
return object
|
return object
|
||||||
} else {
|
} else {
|
||||||
@ -54,11 +51,7 @@ final class PreferencesTable: Table {
|
|||||||
if !self.updatedEntryKeys.isEmpty {
|
if !self.updatedEntryKeys.isEmpty {
|
||||||
for key in self.updatedEntryKeys {
|
for key in self.updatedEntryKeys {
|
||||||
if let value = self.cachedEntries[key]?.entry {
|
if let value = self.cachedEntries[key]?.entry {
|
||||||
let encoder = PostboxEncoder()
|
self.valueBox.set(self.table, key: key, value: ReadBuffer(data: value.data))
|
||||||
encoder.encodeRootObject(value)
|
|
||||||
withExtendedLifetime(encoder, {
|
|
||||||
self.valueBox.set(self.table, key: key, value: encoder.readBufferNoCopy())
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
self.valueBox.remove(self.table, key: key, secure: false)
|
self.valueBox.remove(self.table, key: key, secure: false)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ final class MutablePreferencesView: MutablePostboxView {
|
|||||||
let currentValue = self.values[key]
|
let currentValue = self.values[key]
|
||||||
var updatedValue = false
|
var updatedValue = false
|
||||||
if let value = value, let currentValue = currentValue {
|
if let value = value, let currentValue = currentValue {
|
||||||
if !value.isEqual(to: currentValue) {
|
if value != currentValue {
|
||||||
updatedValue = true
|
updatedValue = true
|
||||||
}
|
}
|
||||||
} else if (value != nil) != (currentValue != nil) {
|
} else if (value != nil) != (currentValue != nil) {
|
||||||
|
|||||||
@ -77,18 +77,6 @@ struct ReverseIndexNamespace: Hashable {
|
|||||||
init(_ value: Int32?) {
|
init(_ value: Int32?) {
|
||||||
self.value = value
|
self.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
var hashValue: Int {
|
|
||||||
if let value = self.value {
|
|
||||||
return value.hashValue
|
|
||||||
} else {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: ReverseIndexNamespace, rhs: ReverseIndexNamespace) -> Bool {
|
|
||||||
return lhs.value == rhs.value
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final class ReverseIndexReferenceTable<T: ReverseIndexReference>: Table {
|
final class ReverseIndexReferenceTable<T: ReverseIndexReference>: Table {
|
||||||
|
|||||||
@ -69,10 +69,10 @@ public final class SeedConfiguration {
|
|||||||
public let messageNamespacesRequiringGroupStatsValidation: Set<MessageId.Namespace>
|
public let messageNamespacesRequiringGroupStatsValidation: Set<MessageId.Namespace>
|
||||||
public let defaultMessageNamespaceReadStates: [MessageId.Namespace: PeerReadState]
|
public let defaultMessageNamespaceReadStates: [MessageId.Namespace: PeerReadState]
|
||||||
public let chatMessagesNamespaces: Set<MessageId.Namespace>
|
public let chatMessagesNamespaces: Set<MessageId.Namespace>
|
||||||
public let globalNotificationSettingsPreferencesKey: ValueBoxKey
|
public let getGlobalNotificationSettings: (Transaction) -> PostboxGlobalNotificationSettings?
|
||||||
public let defaultGlobalNotificationSettings: PostboxGlobalNotificationSettings
|
public let defaultGlobalNotificationSettings: PostboxGlobalNotificationSettings
|
||||||
|
|
||||||
public init(globalMessageIdsPeerIdNamespaces: Set<GlobalMessageIdsNamespace>, initializeChatListWithHole: (topLevel: ChatListHole?, groups: ChatListHole?), messageHoles: [PeerId.Namespace: [MessageId.Namespace: Set<MessageTags>]], upgradedMessageHoles: [PeerId.Namespace: [MessageId.Namespace: Set<MessageTags>]], messageThreadHoles: [PeerId.Namespace: [MessageId.Namespace]], existingMessageTags: MessageTags, messageTagsWithSummary: MessageTags, existingGlobalMessageTags: GlobalMessageTags, peerNamespacesRequiringMessageTextIndex: [PeerId.Namespace], peerSummaryCounterTags: @escaping (Peer, Bool) -> PeerSummaryCounterTags, additionalChatListIndexNamespace: MessageId.Namespace?, messageNamespacesRequiringGroupStatsValidation: Set<MessageId.Namespace>, defaultMessageNamespaceReadStates: [MessageId.Namespace: PeerReadState], chatMessagesNamespaces: Set<MessageId.Namespace>, globalNotificationSettingsPreferencesKey: ValueBoxKey, defaultGlobalNotificationSettings: PostboxGlobalNotificationSettings) {
|
public init(globalMessageIdsPeerIdNamespaces: Set<GlobalMessageIdsNamespace>, initializeChatListWithHole: (topLevel: ChatListHole?, groups: ChatListHole?), messageHoles: [PeerId.Namespace: [MessageId.Namespace: Set<MessageTags>]], upgradedMessageHoles: [PeerId.Namespace: [MessageId.Namespace: Set<MessageTags>]], messageThreadHoles: [PeerId.Namespace: [MessageId.Namespace]], existingMessageTags: MessageTags, messageTagsWithSummary: MessageTags, existingGlobalMessageTags: GlobalMessageTags, peerNamespacesRequiringMessageTextIndex: [PeerId.Namespace], peerSummaryCounterTags: @escaping (Peer, Bool) -> PeerSummaryCounterTags, additionalChatListIndexNamespace: MessageId.Namespace?, messageNamespacesRequiringGroupStatsValidation: Set<MessageId.Namespace>, defaultMessageNamespaceReadStates: [MessageId.Namespace: PeerReadState], chatMessagesNamespaces: Set<MessageId.Namespace>, getGlobalNotificationSettings: @escaping (Transaction) -> PostboxGlobalNotificationSettings?, defaultGlobalNotificationSettings: PostboxGlobalNotificationSettings) {
|
||||||
self.globalMessageIdsPeerIdNamespaces = globalMessageIdsPeerIdNamespaces
|
self.globalMessageIdsPeerIdNamespaces = globalMessageIdsPeerIdNamespaces
|
||||||
self.initializeChatListWithHole = initializeChatListWithHole
|
self.initializeChatListWithHole = initializeChatListWithHole
|
||||||
self.messageHoles = messageHoles
|
self.messageHoles = messageHoles
|
||||||
@ -86,7 +86,7 @@ public final class SeedConfiguration {
|
|||||||
self.messageNamespacesRequiringGroupStatsValidation = messageNamespacesRequiringGroupStatsValidation
|
self.messageNamespacesRequiringGroupStatsValidation = messageNamespacesRequiringGroupStatsValidation
|
||||||
self.defaultMessageNamespaceReadStates = defaultMessageNamespaceReadStates
|
self.defaultMessageNamespaceReadStates = defaultMessageNamespaceReadStates
|
||||||
self.chatMessagesNamespaces = chatMessagesNamespaces
|
self.chatMessagesNamespaces = chatMessagesNamespaces
|
||||||
self.globalNotificationSettingsPreferencesKey = globalNotificationSettingsPreferencesKey
|
self.getGlobalNotificationSettings = getGlobalNotificationSettings
|
||||||
self.defaultGlobalNotificationSettings = defaultGlobalNotificationSettings
|
self.defaultGlobalNotificationSettings = defaultGlobalNotificationSettings
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1326,19 +1326,23 @@ public final class SqliteValueBox: ValueBox {
|
|||||||
|
|
||||||
resultStatement.reset()
|
resultStatement.reset()
|
||||||
|
|
||||||
collectionId.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
collectionId.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
resultStatement.bindText(1, data: bytes, length: collectionId.count)
|
resultStatement.bindText(1, data: bytes, length: collectionId.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
itemId.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
itemId.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
resultStatement.bindText(2, data: bytes, length: itemId.count)
|
resultStatement.bindText(2, data: bytes, length: itemId.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
contents.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
contents.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
resultStatement.bindText(3, data: bytes, length: contents.count)
|
resultStatement.bindText(3, data: bytes, length: contents.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
tags.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
tags.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
resultStatement.bindText(4, data: bytes, length: tags.count)
|
resultStatement.bindText(4, data: bytes, length: tags.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1361,7 +1365,8 @@ public final class SqliteValueBox: ValueBox {
|
|||||||
|
|
||||||
resultStatement.reset()
|
resultStatement.reset()
|
||||||
|
|
||||||
itemId.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
itemId.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
resultStatement.bindText(1, data: bytes, length: itemId.count)
|
resultStatement.bindText(1, data: bytes, length: itemId.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1387,7 +1392,8 @@ public final class SqliteValueBox: ValueBox {
|
|||||||
|
|
||||||
resultStatement.reset()
|
resultStatement.reset()
|
||||||
|
|
||||||
contents.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
contents.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
resultStatement.bindText(1, data: bytes, length: contents.count)
|
resultStatement.bindText(1, data: bytes, length: contents.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1410,11 +1416,13 @@ public final class SqliteValueBox: ValueBox {
|
|||||||
|
|
||||||
resultStatement.reset()
|
resultStatement.reset()
|
||||||
|
|
||||||
contents.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
contents.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
resultStatement.bindText(1, data: bytes, length: contents.count)
|
resultStatement.bindText(1, data: bytes, length: contents.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
collectionId.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
collectionId.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
resultStatement.bindText(2, data: bytes, length: collectionId.count)
|
resultStatement.bindText(2, data: bytes, length: collectionId.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1437,15 +1445,18 @@ public final class SqliteValueBox: ValueBox {
|
|||||||
|
|
||||||
resultStatement.reset()
|
resultStatement.reset()
|
||||||
|
|
||||||
contents.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
contents.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
resultStatement.bindText(1, data: bytes, length: contents.count)
|
resultStatement.bindText(1, data: bytes, length: contents.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
collectionId.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
collectionId.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
resultStatement.bindText(2, data: bytes, length: collectionId.count)
|
resultStatement.bindText(2, data: bytes, length: collectionId.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
tags.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
tags.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
resultStatement.bindText(3, data: bytes, length: tags.count)
|
resultStatement.bindText(3, data: bytes, length: tags.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1653,7 +1664,6 @@ public final class SqliteValueBox: ValueBox {
|
|||||||
hadStop = true
|
hadStop = true
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}, limit: limit)
|
}, limit: limit)
|
||||||
if let lastKey = lastKey {
|
if let lastKey = lastKey {
|
||||||
currentStart = lastKey
|
currentStart = lastKey
|
||||||
@ -2229,7 +2239,8 @@ public final class SqliteValueBox: ValueBox {
|
|||||||
|
|
||||||
private func hexString(_ data: Data) -> String {
|
private func hexString(_ data: Data) -> String {
|
||||||
let hexString = NSMutableString()
|
let hexString = NSMutableString()
|
||||||
data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
data.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
for i in 0 ..< data.count {
|
for i in 0 ..< data.count {
|
||||||
hexString.appendFormat("%02x", UInt(bytes.advanced(by: i).pointee))
|
hexString.appendFormat("%02x", UInt(bytes.advanced(by: i).pointee))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -173,7 +173,7 @@ private final class TimeBasedCleanupImpl {
|
|||||||
DispatchQueue.global(qos: .background).async {
|
DispatchQueue.global(qos: .background).async {
|
||||||
var removedShortLivedCount: Int = 0
|
var removedShortLivedCount: Int = 0
|
||||||
var removedGeneralCount: Int = 0
|
var removedGeneralCount: Int = 0
|
||||||
var removedGeneralLimitCount: Int = 0
|
let removedGeneralLimitCount: Int = 0
|
||||||
|
|
||||||
let startTime = CFAbsoluteTimeGetCurrent()
|
let startTime = CFAbsoluteTimeGetCurrent()
|
||||||
|
|
||||||
|
|||||||
@ -41,7 +41,8 @@ public struct ValueBoxKey: Equatable, Hashable, CustomStringConvertible, Compara
|
|||||||
public func setData(_ offset: Int, value: Data) {
|
public func setData(_ offset: Int, value: Data) {
|
||||||
assert(offset >= 0 && offset + value.count <= self.length)
|
assert(offset >= 0 && offset + value.count <= self.length)
|
||||||
let valueLength = value.count
|
let valueLength = value.count
|
||||||
value.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Void in
|
value.withUnsafeBytes { rawBytes -> Void in
|
||||||
|
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
|
||||||
memcpy(self.memory + offset, bytes, valueLength)
|
memcpy(self.memory + offset, bytes, valueLength)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,14 +223,9 @@ public struct ValueBoxKey: Equatable, Hashable, CustomStringConvertible, Compara
|
|||||||
assert(range.lowerBound >= 0 && range.upperBound <= self.length)
|
assert(range.lowerBound >= 0 && range.upperBound <= self.length)
|
||||||
return String(data: Data(bytes: self.memory.advanced(by: range.lowerBound), count: range.count), encoding: .utf8)
|
return String(data: Data(bytes: self.memory.advanced(by: range.lowerBound), count: range.count), encoding: .utf8)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var hashValue: Int {
|
public func hash(into hasher: inout Hasher) {
|
||||||
var hash = 37
|
hasher.combine(bytes: UnsafeRawBufferPointer(start: self.memory, count: self.length))
|
||||||
let bytes = self.memory.assumingMemoryBound(to: Int8.self)
|
|
||||||
for i in 0 ..< self.length {
|
|
||||||
hash = (hash &* 54059) ^ (Int(bytes[i]) &* 76963)
|
|
||||||
}
|
|
||||||
return hash
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: ValueBoxKey, rhs: ValueBoxKey) -> Bool {
|
public static func ==(lhs: ValueBoxKey, rhs: ValueBoxKey) -> Bool {
|
||||||
|
|||||||
@ -222,7 +222,7 @@ final class ViewTracker {
|
|||||||
self.combinedViews.remove(index)
|
self.combinedViews.remove(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshViewsDueToExternalTransaction(postbox: Postbox, fetchUnsentMessageIds: () -> [MessageId], fetchSynchronizePeerReadStateOperations: () -> [PeerId: PeerReadStateSynchronizationOperation]) {
|
func refreshViewsDueToExternalTransaction(postbox: Postbox, currentTransaction: Transaction, fetchUnsentMessageIds: () -> [MessageId], fetchSynchronizePeerReadStateOperations: () -> [PeerId: PeerReadStateSynchronizationOperation]) {
|
||||||
var updateTrackedHoles = false
|
var updateTrackedHoles = false
|
||||||
|
|
||||||
for (mutableView, pipe) in self.messageHistoryViews.copyItems() {
|
for (mutableView, pipe) in self.messageHistoryViews.copyItems() {
|
||||||
@ -234,7 +234,7 @@ final class ViewTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (mutableView, pipe) in self.chatListViews.copyItems() {
|
for (mutableView, pipe) in self.chatListViews.copyItems() {
|
||||||
if mutableView.refreshDueToExternalTransaction(postbox: postbox) {
|
if mutableView.refreshDueToExternalTransaction(postbox: postbox, currentTransaction: currentTransaction) {
|
||||||
mutableView.render(postbox: postbox)
|
mutableView.render(postbox: postbox)
|
||||||
pipe.putNext((ChatListView(mutableView), .Generic))
|
pipe.putNext((ChatListView(mutableView), .Generic))
|
||||||
}
|
}
|
||||||
@ -259,7 +259,7 @@ final class ViewTracker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateViews(postbox: Postbox, transaction: PostboxTransaction) {
|
func updateViews(postbox: Postbox, currentTransaction: Transaction, transaction: PostboxTransaction) {
|
||||||
var updateTrackedHoles = false
|
var updateTrackedHoles = false
|
||||||
|
|
||||||
if let currentUpdatedState = transaction.currentUpdatedState {
|
if let currentUpdatedState = transaction.currentUpdatedState {
|
||||||
@ -337,7 +337,7 @@ final class ViewTracker {
|
|||||||
|
|
||||||
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, updatedPeerPresences: transaction.currentUpdatedPeerPresences, transaction: transaction, context: context) {
|
if mutableView.replay(postbox: postbox, currentTransaction: currentTransaction, 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)
|
mutableView.render(postbox: postbox)
|
||||||
pipe.putNext((ChatListView(mutableView), .Generic))
|
pipe.putNext((ChatListView(mutableView), .Generic))
|
||||||
|
|||||||
@ -31,69 +31,78 @@ public enum PostboxViewKey: Hashable {
|
|||||||
case allChatListHoles(PeerGroupId)
|
case allChatListHoles(PeerGroupId)
|
||||||
case historyTagInfo(peerId: PeerId, tag: MessageTags)
|
case historyTagInfo(peerId: PeerId, tag: MessageTags)
|
||||||
case topChatMessage(peerIds: [PeerId])
|
case topChatMessage(peerIds: [PeerId])
|
||||||
|
|
||||||
public var hashValue: Int {
|
public func hash(into hasher: inout Hasher) {
|
||||||
switch self {
|
switch self {
|
||||||
case .itemCollectionInfos:
|
case .itemCollectionInfos:
|
||||||
return 0
|
hasher.combine(0)
|
||||||
case .itemCollectionIds:
|
case .itemCollectionIds:
|
||||||
return 1
|
hasher.combine(1)
|
||||||
case let .peerChatState(peerId):
|
case let .peerChatState(peerId):
|
||||||
return peerId.hashValue
|
hasher.combine(peerId)
|
||||||
case let .itemCollectionInfo(id):
|
case let .itemCollectionInfo(id):
|
||||||
return id.hashValue
|
hasher.combine(id)
|
||||||
case let .orderedItemList(id):
|
case let .orderedItemList(id):
|
||||||
return id.hashValue
|
hasher.combine(id)
|
||||||
case .preferences:
|
case .preferences:
|
||||||
return 3
|
hasher.combine(3)
|
||||||
case .globalMessageTags:
|
case .globalMessageTags:
|
||||||
return 4
|
hasher.combine(4)
|
||||||
case let .peer(peerId, _):
|
case let .peer(peerId, _):
|
||||||
return peerId.hashValue
|
hasher.combine(peerId)
|
||||||
case let .pendingMessageActions(type):
|
case let .pendingMessageActions(type):
|
||||||
return type.hashValue
|
hasher.combine(type)
|
||||||
case let .invalidatedMessageHistoryTagSummaries(tagMask, namespace):
|
case let .invalidatedMessageHistoryTagSummaries(tagMask, namespace):
|
||||||
return tagMask.rawValue.hashValue ^ namespace.hashValue
|
hasher.combine(tagMask)
|
||||||
|
hasher.combine(namespace)
|
||||||
case let .pendingMessageActionsSummary(type, peerId, namespace):
|
case let .pendingMessageActionsSummary(type, peerId, namespace):
|
||||||
return type.hashValue ^ peerId.hashValue ^ namespace.hashValue
|
hasher.combine(type)
|
||||||
|
hasher.combine(peerId)
|
||||||
|
hasher.combine(namespace)
|
||||||
case let .historyTagSummaryView(tag, peerId, namespace):
|
case let .historyTagSummaryView(tag, peerId, namespace):
|
||||||
return tag.rawValue.hashValue ^ peerId.hashValue ^ namespace.hashValue
|
hasher.combine(tag)
|
||||||
|
hasher.combine(peerId)
|
||||||
|
hasher.combine(namespace)
|
||||||
case let .cachedPeerData(peerId):
|
case let .cachedPeerData(peerId):
|
||||||
return peerId.hashValue
|
hasher.combine(peerId)
|
||||||
case .unreadCounts:
|
case .unreadCounts:
|
||||||
return 5
|
hasher.combine(5)
|
||||||
case .combinedReadState:
|
case .combinedReadState:
|
||||||
return 16
|
hasher.combine(16)
|
||||||
case .peerNotificationSettings:
|
case .peerNotificationSettings:
|
||||||
return 6
|
hasher.combine(6)
|
||||||
case .pendingPeerNotificationSettings:
|
case .pendingPeerNotificationSettings:
|
||||||
return 7
|
hasher.combine(7)
|
||||||
case let .messageOfInterestHole(location, namespace, count):
|
case let .messageOfInterestHole(location, namespace, count):
|
||||||
return 8 &+ 31 &* location.hashValue &+ 31 &* namespace.hashValue &+ 31 &* count.hashValue
|
hasher.combine(8)
|
||||||
|
hasher.combine(location)
|
||||||
|
hasher.combine(namespace)
|
||||||
|
hasher.combine(count)
|
||||||
case let .localMessageTag(tag):
|
case let .localMessageTag(tag):
|
||||||
return tag.hashValue
|
hasher.combine(tag)
|
||||||
case .messages:
|
case .messages:
|
||||||
return 10
|
hasher.combine(10)
|
||||||
case .additionalChatListItems:
|
case .additionalChatListItems:
|
||||||
return 11
|
hasher.combine(11)
|
||||||
case let .cachedItem(id):
|
case let .cachedItem(id):
|
||||||
return id.hashValue
|
hasher.combine(id)
|
||||||
case .peerPresences:
|
case .peerPresences:
|
||||||
return 13
|
hasher.combine(13)
|
||||||
case .synchronizeGroupMessageStats:
|
case .synchronizeGroupMessageStats:
|
||||||
return 14
|
hasher.combine(14)
|
||||||
case .peerNotificationSettingsBehaviorTimestampView:
|
case .peerNotificationSettingsBehaviorTimestampView:
|
||||||
return 15
|
hasher.combine(15)
|
||||||
case let .peerChatInclusion(peerId):
|
case let .peerChatInclusion(peerId):
|
||||||
return peerId.hashValue
|
hasher.combine(peerId)
|
||||||
case let .basicPeer(peerId):
|
case let .basicPeer(peerId):
|
||||||
return peerId.hashValue
|
hasher.combine(peerId)
|
||||||
case let .allChatListHoles(groupId):
|
case let .allChatListHoles(groupId):
|
||||||
return groupId.hashValue
|
hasher.combine(groupId)
|
||||||
case let .historyTagInfo(peerId, tag):
|
case let .historyTagInfo(peerId, tag):
|
||||||
return peerId.hashValue ^ tag.hashValue
|
hasher.combine(peerId)
|
||||||
|
hasher.combine(tag)
|
||||||
case let .topChatMessage(peerIds):
|
case let .topChatMessage(peerIds):
|
||||||
return peerIds.hashValue
|
hasher.combine(peerIds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -151,7 +151,7 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(SynchronizeSavedGifsOperation.self, f: { SynchronizeSavedGifsOperation(decoder: $0) })
|
declareEncodable(SynchronizeSavedGifsOperation.self, f: { SynchronizeSavedGifsOperation(decoder: $0) })
|
||||||
declareEncodable(SynchronizeSavedStickersOperation.self, f: { SynchronizeSavedStickersOperation(decoder: $0) })
|
declareEncodable(SynchronizeSavedStickersOperation.self, f: { SynchronizeSavedStickersOperation(decoder: $0) })
|
||||||
declareEncodable(SynchronizeRecentlyUsedMediaOperation.self, f: { SynchronizeRecentlyUsedMediaOperation(decoder: $0) })
|
declareEncodable(SynchronizeRecentlyUsedMediaOperation.self, f: { SynchronizeRecentlyUsedMediaOperation(decoder: $0) })
|
||||||
declareEncodable(CacheStorageSettings.self, f: { CacheStorageSettings(decoder: $0) })
|
/*declareEncodable(CacheStorageSettings.self, f: { CacheStorageSettings(decoder: $0) })
|
||||||
declareEncodable(LocalizationSettings.self, f: { LocalizationSettings(decoder: $0) })
|
declareEncodable(LocalizationSettings.self, f: { LocalizationSettings(decoder: $0) })
|
||||||
declareEncodable(LocalizationListState.self, f: { LocalizationListState(decoder: $0) })
|
declareEncodable(LocalizationListState.self, f: { LocalizationListState(decoder: $0) })
|
||||||
declareEncodable(ProxySettings.self, f: { ProxySettings(decoder: $0) })
|
declareEncodable(ProxySettings.self, f: { ProxySettings(decoder: $0) })
|
||||||
@ -159,7 +159,7 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(RemoteStorageConfiguration.self, f: { RemoteStorageConfiguration(decoder: $0) })
|
declareEncodable(RemoteStorageConfiguration.self, f: { RemoteStorageConfiguration(decoder: $0) })
|
||||||
declareEncodable(LimitsConfiguration.self, f: { LimitsConfiguration(decoder: $0) })
|
declareEncodable(LimitsConfiguration.self, f: { LimitsConfiguration(decoder: $0) })
|
||||||
declareEncodable(VoipConfiguration.self, f: { VoipConfiguration(decoder: $0) })
|
declareEncodable(VoipConfiguration.self, f: { VoipConfiguration(decoder: $0) })
|
||||||
declareEncodable(SuggestedLocalizationEntry.self, f: { SuggestedLocalizationEntry(decoder: $0) })
|
declareEncodable(SuggestedLocalizationEntry.self, f: { SuggestedLocalizationEntry(decoder: $0) })*/
|
||||||
declareEncodable(SynchronizeLocalizationUpdatesOperation.self, f: { SynchronizeLocalizationUpdatesOperation(decoder: $0) })
|
declareEncodable(SynchronizeLocalizationUpdatesOperation.self, f: { SynchronizeLocalizationUpdatesOperation(decoder: $0) })
|
||||||
declareEncodable(ChannelMessageStateVersionAttribute.self, f: { ChannelMessageStateVersionAttribute(decoder: $0) })
|
declareEncodable(ChannelMessageStateVersionAttribute.self, f: { ChannelMessageStateVersionAttribute(decoder: $0) })
|
||||||
declareEncodable(PeerGroupMessageStateVersionAttribute.self, f: { PeerGroupMessageStateVersionAttribute(decoder: $0) })
|
declareEncodable(PeerGroupMessageStateVersionAttribute.self, f: { PeerGroupMessageStateVersionAttribute(decoder: $0) })
|
||||||
@ -171,31 +171,31 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(ConsumablePersonalMentionMessageAttribute.self, f: { ConsumablePersonalMentionMessageAttribute(decoder: $0) })
|
declareEncodable(ConsumablePersonalMentionMessageAttribute.self, f: { ConsumablePersonalMentionMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(ConsumePersonalMessageAction.self, f: { ConsumePersonalMessageAction(decoder: $0) })
|
declareEncodable(ConsumePersonalMessageAction.self, f: { ConsumePersonalMessageAction(decoder: $0) })
|
||||||
declareEncodable(CachedStickerPack.self, f: { CachedStickerPack(decoder: $0) })
|
declareEncodable(CachedStickerPack.self, f: { CachedStickerPack(decoder: $0) })
|
||||||
declareEncodable(LoggingSettings.self, f: { LoggingSettings(decoder: $0) })
|
//declareEncodable(LoggingSettings.self, f: { LoggingSettings(decoder: $0) })
|
||||||
declareEncodable(CachedLocalizationInfos.self, f: { CachedLocalizationInfos(decoder: $0) })
|
declareEncodable(CachedLocalizationInfos.self, f: { CachedLocalizationInfos(decoder: $0) })
|
||||||
declareEncodable(CachedSecureIdConfiguration.self, f: { CachedSecureIdConfiguration(decoder: $0) })
|
declareEncodable(CachedSecureIdConfiguration.self, f: { CachedSecureIdConfiguration(decoder: $0) })
|
||||||
declareEncodable(CachedWallpapersConfiguration.self, f: { CachedWallpapersConfiguration(decoder: $0) })
|
declareEncodable(CachedWallpapersConfiguration.self, f: { CachedWallpapersConfiguration(decoder: $0) })
|
||||||
declareEncodable(CachedThemesConfiguration.self, f: { CachedThemesConfiguration(decoder: $0) })
|
declareEncodable(CachedThemesConfiguration.self, f: { CachedThemesConfiguration(decoder: $0) })
|
||||||
declareEncodable(SynchronizeGroupedPeersOperation.self, f: { SynchronizeGroupedPeersOperation(decoder: $0) })
|
declareEncodable(SynchronizeGroupedPeersOperation.self, f: { SynchronizeGroupedPeersOperation(decoder: $0) })
|
||||||
declareEncodable(ContentPrivacySettings.self, f: { ContentPrivacySettings(decoder: $0) })
|
//declareEncodable(ContentPrivacySettings.self, f: { ContentPrivacySettings(decoder: $0) })
|
||||||
declareEncodable(TelegramDeviceContactImportedData.self, f: { TelegramDeviceContactImportedData(decoder: $0) })
|
declareEncodable(TelegramDeviceContactImportedData.self, f: { TelegramDeviceContactImportedData(decoder: $0) })
|
||||||
declareEncodable(SecureFileMediaResource.self, f: { SecureFileMediaResource(decoder: $0) })
|
declareEncodable(SecureFileMediaResource.self, f: { SecureFileMediaResource(decoder: $0) })
|
||||||
declareEncodable(CachedStickerQueryResult.self, f: { CachedStickerQueryResult(decoder: $0) })
|
declareEncodable(CachedStickerQueryResult.self, f: { CachedStickerQueryResult(decoder: $0) })
|
||||||
declareEncodable(TelegramWallpaper.self, f: { TelegramWallpaper(decoder: $0) })
|
declareEncodable(TelegramWallpaper.self, f: { TelegramWallpaper(decoder: $0) })
|
||||||
declareEncodable(TelegramTheme.self, f: { TelegramTheme(decoder: $0) })
|
declareEncodable(TelegramTheme.self, f: { TelegramTheme(decoder: $0) })
|
||||||
declareEncodable(ThemeSettings.self, f: { ThemeSettings(decoder: $0) })
|
//declareEncodable(ThemeSettings.self, f: { ThemeSettings(decoder: $0) })
|
||||||
declareEncodable(SynchronizeMarkAllUnseenPersonalMessagesOperation.self, f: { SynchronizeMarkAllUnseenPersonalMessagesOperation(decoder: $0) })
|
declareEncodable(SynchronizeMarkAllUnseenPersonalMessagesOperation.self, f: { SynchronizeMarkAllUnseenPersonalMessagesOperation(decoder: $0) })
|
||||||
declareEncodable(SynchronizeAppLogEventsOperation.self, f: { SynchronizeAppLogEventsOperation(decoder: $0) })
|
declareEncodable(SynchronizeAppLogEventsOperation.self, f: { SynchronizeAppLogEventsOperation(decoder: $0) })
|
||||||
declareEncodable(CachedRecentPeers.self, f: { CachedRecentPeers(decoder: $0) })
|
declareEncodable(CachedRecentPeers.self, f: { CachedRecentPeers(decoder: $0) })
|
||||||
declareEncodable(AppChangelogState.self, f: { AppChangelogState(decoder: $0) })
|
//declareEncodable(AppChangelogState.self, f: { AppChangelogState(decoder: $0) })
|
||||||
declareEncodable(AppConfiguration.self, f: { AppConfiguration(decoder: $0) })
|
//declareEncodable(AppConfiguration.self, f: { AppConfiguration(decoder: $0) })
|
||||||
declareEncodable(JSON.self, f: { JSON(decoder: $0) })
|
declareEncodable(JSON.self, f: { JSON(decoder: $0) })
|
||||||
declareEncodable(SearchBotsConfiguration.self, f: { SearchBotsConfiguration(decoder: $0) })
|
//declareEncodable(SearchBotsConfiguration.self, f: { SearchBotsConfiguration(decoder: $0) })
|
||||||
declareEncodable(AutodownloadSettings.self, f: { AutodownloadSettings(decoder: $0 )})
|
//declareEncodable(AutodownloadSettings.self, f: { AutodownloadSettings(decoder: $0 )})
|
||||||
declareEncodable(TelegramMediaPoll.self, f: { TelegramMediaPoll(decoder: $0) })
|
declareEncodable(TelegramMediaPoll.self, f: { TelegramMediaPoll(decoder: $0) })
|
||||||
declareEncodable(TelegramMediaUnsupported.self, f: { TelegramMediaUnsupported(decoder: $0) })
|
declareEncodable(TelegramMediaUnsupported.self, f: { TelegramMediaUnsupported(decoder: $0) })
|
||||||
declareEncodable(ContactsSettings.self, f: { ContactsSettings(decoder: $0) })
|
//declareEncodable(ContactsSettings.self, f: { ContactsSettings(decoder: $0) })
|
||||||
declareEncodable(SecretChatSettings.self, f: { SecretChatSettings(decoder: $0) })
|
//declareEncodable(SecretChatSettings.self, f: { SecretChatSettings(decoder: $0) })
|
||||||
declareEncodable(EmojiKeywordCollectionInfo.self, f: { EmojiKeywordCollectionInfo(decoder: $0) })
|
declareEncodable(EmojiKeywordCollectionInfo.self, f: { EmojiKeywordCollectionInfo(decoder: $0) })
|
||||||
declareEncodable(EmojiKeywordItem.self, f: { EmojiKeywordItem(decoder: $0) })
|
declareEncodable(EmojiKeywordItem.self, f: { EmojiKeywordItem(decoder: $0) })
|
||||||
declareEncodable(SynchronizeEmojiKeywordsOperation.self, f: { SynchronizeEmojiKeywordsOperation(decoder: $0) })
|
declareEncodable(SynchronizeEmojiKeywordsOperation.self, f: { SynchronizeEmojiKeywordsOperation(decoder: $0) })
|
||||||
@ -209,14 +209,14 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(UpdateMessageReactionsAction.self, f: { UpdateMessageReactionsAction(decoder: $0) })
|
declareEncodable(UpdateMessageReactionsAction.self, f: { UpdateMessageReactionsAction(decoder: $0) })
|
||||||
declareEncodable(RestrictedContentMessageAttribute.self, f: { RestrictedContentMessageAttribute(decoder: $0) })
|
declareEncodable(RestrictedContentMessageAttribute.self, f: { RestrictedContentMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(SendScheduledMessageImmediatelyAction.self, f: { SendScheduledMessageImmediatelyAction(decoder: $0) })
|
declareEncodable(SendScheduledMessageImmediatelyAction.self, f: { SendScheduledMessageImmediatelyAction(decoder: $0) })
|
||||||
declareEncodable(WalletCollection.self, f: { WalletCollection(decoder: $0) })
|
//declareEncodable(WalletCollection.self, f: { WalletCollection(decoder: $0) })
|
||||||
declareEncodable(EmbeddedMediaStickersMessageAttribute.self, f: { EmbeddedMediaStickersMessageAttribute(decoder: $0) })
|
declareEncodable(EmbeddedMediaStickersMessageAttribute.self, f: { EmbeddedMediaStickersMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(TelegramMediaWebpageAttribute.self, f: { TelegramMediaWebpageAttribute(decoder: $0) })
|
declareEncodable(TelegramMediaWebpageAttribute.self, f: { TelegramMediaWebpageAttribute(decoder: $0) })
|
||||||
declareEncodable(CachedPollOptionResult.self, f: { CachedPollOptionResult(decoder: $0) })
|
declareEncodable(CachedPollOptionResult.self, f: { CachedPollOptionResult(decoder: $0) })
|
||||||
declareEncodable(ChatListFiltersState.self, f: { ChatListFiltersState(decoder: $0) })
|
//declareEncodable(ChatListFiltersState.self, f: { ChatListFiltersState(decoder: $0) })
|
||||||
declareEncodable(PeersNearbyState.self, f: { PeersNearbyState(decoder: $0) })
|
//declareEncodable(PeersNearbyState.self, f: { PeersNearbyState(decoder: $0) })
|
||||||
declareEncodable(TelegramMediaDice.self, f: { TelegramMediaDice(decoder: $0) })
|
declareEncodable(TelegramMediaDice.self, f: { TelegramMediaDice(decoder: $0) })
|
||||||
declareEncodable(ChatListFiltersFeaturedState.self, f: { ChatListFiltersFeaturedState(decoder: $0) })
|
//declareEncodable(ChatListFiltersFeaturedState.self, f: { ChatListFiltersFeaturedState(decoder: $0) })
|
||||||
declareEncodable(SynchronizeChatListFiltersOperation.self, f: { SynchronizeChatListFiltersOperation(decoder: $0) })
|
declareEncodable(SynchronizeChatListFiltersOperation.self, f: { SynchronizeChatListFiltersOperation(decoder: $0) })
|
||||||
declareEncodable(PromoChatListItem.self, f: { PromoChatListItem(decoder: $0) })
|
declareEncodable(PromoChatListItem.self, f: { PromoChatListItem(decoder: $0) })
|
||||||
declareEncodable(TelegramMediaFile.VideoThumbnail.self, f: { TelegramMediaFile.VideoThumbnail(decoder: $0) })
|
declareEncodable(TelegramMediaFile.VideoThumbnail.self, f: { TelegramMediaFile.VideoThumbnail(decoder: $0) })
|
||||||
@ -225,18 +225,18 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(TelegramMediaImage.VideoRepresentation.self, f: { TelegramMediaImage.VideoRepresentation(decoder: $0) })
|
declareEncodable(TelegramMediaImage.VideoRepresentation.self, f: { TelegramMediaImage.VideoRepresentation(decoder: $0) })
|
||||||
declareEncodable(Country.self, f: { Country(decoder: $0) })
|
declareEncodable(Country.self, f: { Country(decoder: $0) })
|
||||||
declareEncodable(Country.CountryCode.self, f: { Country.CountryCode(decoder: $0) })
|
declareEncodable(Country.CountryCode.self, f: { Country.CountryCode(decoder: $0) })
|
||||||
declareEncodable(CountriesList.self, f: { CountriesList(decoder: $0) })
|
//declareEncodable(CountriesList.self, f: { CountriesList(decoder: $0) })
|
||||||
declareEncodable(ValidationMessageAttribute.self, f: { ValidationMessageAttribute(decoder: $0) })
|
declareEncodable(ValidationMessageAttribute.self, f: { ValidationMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(EmojiSearchQueryMessageAttribute.self, f: { EmojiSearchQueryMessageAttribute(decoder: $0) })
|
declareEncodable(EmojiSearchQueryMessageAttribute.self, f: { EmojiSearchQueryMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(CachedPeerInvitationImporters.self, f: { CachedPeerInvitationImporters(decoder: $0) })
|
declareEncodable(CachedPeerInvitationImporters.self, f: { CachedPeerInvitationImporters(decoder: $0) })
|
||||||
declareEncodable(CachedPeerExportedInvitations.self, f: { CachedPeerExportedInvitations(decoder: $0) })
|
declareEncodable(CachedPeerExportedInvitations.self, f: { CachedPeerExportedInvitations(decoder: $0) })
|
||||||
declareEncodable(ExportedInvitation.self, f: { ExportedInvitation(decoder: $0) })
|
declareEncodable(ExportedInvitation.self, f: { ExportedInvitation(decoder: $0) })
|
||||||
declareEncodable(CachedDisplayAsPeers.self, f: { CachedDisplayAsPeers(decoder: $0) })
|
declareEncodable(CachedDisplayAsPeers.self, f: { CachedDisplayAsPeers(decoder: $0) })
|
||||||
declareEncodable(WallpapersState.self, f: { WallpapersState(decoder: $0) })
|
//declareEncodable(WallpapersState.self, f: { WallpapersState(decoder: $0) })
|
||||||
declareEncodable(WallpaperDataResource.self, f: { WallpaperDataResource(decoder: $0) })
|
declareEncodable(WallpaperDataResource.self, f: { WallpaperDataResource(decoder: $0) })
|
||||||
declareEncodable(ForwardOptionsMessageAttribute.self, f: { ForwardOptionsMessageAttribute(decoder: $0) })
|
declareEncodable(ForwardOptionsMessageAttribute.self, f: { ForwardOptionsMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(ChatTheme.self, f: { ChatTheme(decoder: $0) })
|
declareEncodable(ChatTheme.self, f: { ChatTheme(decoder: $0) })
|
||||||
declareEncodable(ChatThemes.self, f: { ChatThemes(decoder: $0) })
|
//declareEncodable(ChatThemes.self, f: { ChatThemes(decoder: $0) })
|
||||||
|
|
||||||
return
|
return
|
||||||
}()
|
}()
|
||||||
|
|||||||
@ -11,7 +11,7 @@ func initializedAppSettingsAfterLogin(transaction: Transaction, appVersion: Stri
|
|||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
transaction.updatePreferencesEntry(key: PreferencesKeys.contactsSettings, { _ in
|
transaction.updatePreferencesEntry(key: PreferencesKeys.contactsSettings, { _ in
|
||||||
return ContactsSettings(synchronizeContacts: syncContacts)
|
return PreferencesEntry(ContactsSettings(synchronizeContacts: syncContacts))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Postbox
|
import Postbox
|
||||||
|
|
||||||
public struct AppChangelogState: PreferencesEntry, Equatable {
|
public struct AppChangelogState: Codable {
|
||||||
public var checkedVersion: String
|
public var checkedVersion: String
|
||||||
public var previousVersion: String
|
public var previousVersion: String
|
||||||
|
|
||||||
@ -11,21 +11,17 @@ public struct AppChangelogState: PreferencesEntry, Equatable {
|
|||||||
self.previousVersion = previousVersion
|
self.previousVersion = previousVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(from decoder: Decoder) throws {
|
||||||
self.checkedVersion = decoder.decodeStringForKey("checkedVersion", orElse: "")
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
self.previousVersion = decoder.decodeStringForKey("previousVersion", orElse: "")
|
|
||||||
|
self.checkedVersion = (try? container.decode(String.self, forKey: "checkedVersion")) ?? ""
|
||||||
|
self.previousVersion = (try? container.decode(String.self, forKey: "previousVersion")) ?? ""
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(to encoder: Encoder) throws {
|
||||||
encoder.encodeString(self.checkedVersion, forKey: "checkedVersion")
|
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||||
encoder.encodeString(self.previousVersion, forKey: "previousVersion")
|
|
||||||
}
|
try container.encode(self.checkedVersion, forKey: "checkedVersion")
|
||||||
|
try container.encode(self.previousVersion, forKey: "previousVersion")
|
||||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
|
||||||
guard let to = to as? AppChangelogState else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return self == to
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Postbox
|
import Postbox
|
||||||
|
|
||||||
public struct AppConfiguration: PreferencesEntry, Equatable {
|
public struct AppConfiguration: Codable {
|
||||||
public var data: JSON?
|
public var data: JSON?
|
||||||
|
|
||||||
public static var defaultValue: AppConfiguration {
|
public static var defaultValue: AppConfiguration {
|
||||||
@ -23,11 +23,4 @@ public struct AppConfiguration: PreferencesEntry, Equatable {
|
|||||||
encoder.encodeNil(forKey: "data")
|
encoder.encodeNil(forKey: "data")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
|
||||||
guard let to = to as? AppConfiguration else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return self == to
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ public enum AutodownloadPreset {
|
|||||||
case high
|
case high
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct AutodownloadPresetSettings: PostboxCoding, Equatable {
|
public struct AutodownloadPresetSettings: Codable {
|
||||||
public let disabled: Bool
|
public let disabled: Bool
|
||||||
public let photoSizeMax: Int32
|
public let photoSizeMax: Int32
|
||||||
public let videoSizeMax: Int32
|
public let videoSizeMax: Int32
|
||||||
@ -25,28 +25,32 @@ public struct AutodownloadPresetSettings: PostboxCoding, Equatable {
|
|||||||
self.videoUploadMaxbitrate = videoUploadMaxbitrate
|
self.videoUploadMaxbitrate = videoUploadMaxbitrate
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(from decoder: Decoder) throws {
|
||||||
self.disabled = decoder.decodeInt32ForKey("disabled", orElse: 0) != 0
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
self.photoSizeMax = decoder.decodeInt32ForKey("photoSizeMax", orElse: 0)
|
|
||||||
self.videoSizeMax = decoder.decodeInt32ForKey("videoSizeMax", orElse: 0)
|
self.disabled = ((try? container.decode(Int32.self, forKey: "disabled")) ?? 0) != 0
|
||||||
self.fileSizeMax = decoder.decodeInt32ForKey("fileSizeMax", orElse: 0)
|
self.photoSizeMax = (try? container.decode(Int32.self, forKey: "photoSizeMax")) ?? 0
|
||||||
self.preloadLargeVideo = decoder.decodeInt32ForKey("preloadLargeVideo", orElse: 0) != 0
|
self.videoSizeMax = (try? container.decode(Int32.self, forKey: "videoSizeMax")) ?? 0
|
||||||
self.lessDataForPhoneCalls = decoder.decodeInt32ForKey("lessDataForPhoneCalls", orElse: 0) != 0
|
self.fileSizeMax = (try? container.decode(Int32.self, forKey: "fileSizeMax")) ?? 0
|
||||||
self.videoUploadMaxbitrate = decoder.decodeInt32ForKey("videoUploadMaxbitrate", orElse: 0)
|
self.preloadLargeVideo = ((try? container.decode(Int32.self, forKey: "preloadLargeVideo")) ?? 0) != 0
|
||||||
|
self.lessDataForPhoneCalls = ((try? container.decode(Int32.self, forKey: "lessDataForPhoneCalls")) ?? 0) != 0
|
||||||
|
self.videoUploadMaxbitrate = (try? container.decode(Int32.self, forKey: "videoUploadMaxbitrate")) ?? 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(to encoder: Encoder) throws {
|
||||||
encoder.encodeInt32(self.disabled ? 1 : 0, forKey: "disabled")
|
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||||
encoder.encodeInt32(self.photoSizeMax, forKey: "photoSizeMax")
|
|
||||||
encoder.encodeInt32(self.videoSizeMax, forKey: "videoSizeMax")
|
try container.encode((self.disabled ? 1 : 0) as Int32, forKey: "disabled")
|
||||||
encoder.encodeInt32(self.fileSizeMax, forKey: "fileSizeMax")
|
try container.encode(self.photoSizeMax, forKey: "photoSizeMax")
|
||||||
encoder.encodeInt32(self.preloadLargeVideo ? 1 : 0, forKey: "preloadLargeVideo")
|
try container.encode(self.videoSizeMax, forKey: "videoSizeMax")
|
||||||
encoder.encodeInt32(self.lessDataForPhoneCalls ? 1 : 0, forKey: "lessDataForPhoneCalls")
|
try container.encode(self.fileSizeMax, forKey: "fileSizeMax")
|
||||||
encoder.encodeInt32(self.videoUploadMaxbitrate, forKey: "videoUploadMaxbitrate")
|
try container.encode((self.preloadLargeVideo ? 1 : 0) as Int32, forKey: "preloadLargeVideo")
|
||||||
|
try container.encode((self.lessDataForPhoneCalls ? 1 : 0) as Int32, forKey: "lessDataForPhoneCalls")
|
||||||
|
try container.encode(self.videoUploadMaxbitrate, forKey: "videoUploadMaxbitrate")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct AutodownloadSettings: PreferencesEntry, Equatable {
|
public struct AutodownloadSettings: Codable {
|
||||||
public let lowPreset: AutodownloadPresetSettings
|
public let lowPreset: AutodownloadPresetSettings
|
||||||
public let mediumPreset: AutodownloadPresetSettings
|
public let mediumPreset: AutodownloadPresetSettings
|
||||||
public let highPreset: AutodownloadPresetSettings
|
public let highPreset: AutodownloadPresetSettings
|
||||||
@ -64,27 +68,19 @@ public struct AutodownloadSettings: PreferencesEntry, Equatable {
|
|||||||
self.highPreset = highPreset
|
self.highPreset = highPreset
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(from decoder: Decoder) throws {
|
||||||
self.lowPreset = decoder.decodeObjectForKey("lowPreset", decoder: AutodownloadPresetSettings.init(decoder:)) as! AutodownloadPresetSettings
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
self.mediumPreset = decoder.decodeObjectForKey("mediumPreset", decoder: AutodownloadPresetSettings.init(decoder:)) as! AutodownloadPresetSettings
|
|
||||||
self.highPreset = decoder.decodeObjectForKey("highPreset", decoder: AutodownloadPresetSettings.init(decoder:)) as! AutodownloadPresetSettings
|
self.lowPreset = (try? container.decode(AutodownloadPresetSettings.self, forKey: "lowPreset")) ?? AutodownloadSettings.defaultSettings.lowPreset
|
||||||
|
self.mediumPreset = (try? container.decode(AutodownloadPresetSettings.self, forKey: "mediumPreset")) ?? AutodownloadSettings.defaultSettings.mediumPreset
|
||||||
|
self.highPreset = (try? container.decode(AutodownloadPresetSettings.self, forKey: "highPreset")) ?? AutodownloadSettings.defaultSettings.highPreset
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(to encoder: Encoder) throws {
|
||||||
encoder.encodeObject(self.lowPreset, forKey: "lowPreset")
|
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||||
encoder.encodeObject(self.mediumPreset, forKey: "mediumPreset")
|
|
||||||
encoder.encodeObject(self.highPreset, forKey: "highPreset")
|
try container.encode(self.lowPreset, forKey: "lowPreset")
|
||||||
}
|
try container.encode(self.mediumPreset, forKey: "mediumPreset")
|
||||||
|
try container.encode(self.highPreset, forKey: "highPreset")
|
||||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
|
||||||
if let to = to as? AutodownloadSettings {
|
|
||||||
return self == to
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: AutodownloadSettings, rhs: AutodownloadSettings) -> Bool {
|
|
||||||
return lhs.lowPreset == rhs.lowPreset && lhs.mediumPreset == rhs.mediumPreset && lhs.highPreset == rhs.highPreset
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Postbox
|
import Postbox
|
||||||
|
|
||||||
public struct CacheStorageSettings: PreferencesEntry, Equatable {
|
public struct CacheStorageSettings: Codable {
|
||||||
public let defaultCacheStorageTimeout: Int32
|
public let defaultCacheStorageTimeout: Int32
|
||||||
public let defaultCacheStorageLimitGigabytes: Int32
|
public let defaultCacheStorageLimitGigabytes: Int32
|
||||||
|
|
||||||
@ -13,26 +13,18 @@ public struct CacheStorageSettings: PreferencesEntry, Equatable {
|
|||||||
self.defaultCacheStorageLimitGigabytes = defaultCacheStorageLimitGigabytes
|
self.defaultCacheStorageLimitGigabytes = defaultCacheStorageLimitGigabytes
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(from decoder: Decoder) throws {
|
||||||
self.defaultCacheStorageTimeout = decoder.decodeInt32ForKey("dt", orElse: Int32.max)
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
self.defaultCacheStorageLimitGigabytes = decoder.decodeInt32ForKey("dl", orElse: Int32.max)
|
|
||||||
|
self.defaultCacheStorageTimeout = (try? container.decode(Int32.self, forKey: "dt")) ?? Int32.max
|
||||||
|
self.defaultCacheStorageLimitGigabytes = (try? container.decode(Int32.self, forKey: "dl")) ?? Int32.max
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(to encoder: Encoder) throws {
|
||||||
encoder.encodeInt32(self.defaultCacheStorageTimeout, forKey: "dt")
|
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||||
encoder.encodeInt32(self.defaultCacheStorageLimitGigabytes, forKey: "dl")
|
|
||||||
}
|
try container.encode(self.defaultCacheStorageTimeout, forKey: "dt")
|
||||||
|
try container.encode(self.defaultCacheStorageLimitGigabytes, forKey: "dl")
|
||||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
|
||||||
if let to = to as? CacheStorageSettings {
|
|
||||||
return self == to
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: CacheStorageSettings, rhs: CacheStorageSettings) -> Bool {
|
|
||||||
return lhs.defaultCacheStorageTimeout == rhs.defaultCacheStorageTimeout && lhs.defaultCacheStorageLimitGigabytes == rhs.defaultCacheStorageLimitGigabytes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func withUpdatedDefaultCacheStorageTimeout(_ defaultCacheStorageTimeout: Int32) -> CacheStorageSettings {
|
public func withUpdatedDefaultCacheStorageTimeout(_ defaultCacheStorageTimeout: Int32) -> CacheStorageSettings {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Postbox
|
import Postbox
|
||||||
|
|
||||||
public struct ContactsSettings: Equatable, PreferencesEntry {
|
public struct ContactsSettings: Codable {
|
||||||
public var synchronizeContacts: Bool
|
public var synchronizeContacts: Bool
|
||||||
|
|
||||||
public static var defaultSettings: ContactsSettings {
|
public static var defaultSettings: ContactsSettings {
|
||||||
@ -12,19 +12,15 @@ public struct ContactsSettings: Equatable, PreferencesEntry {
|
|||||||
self.synchronizeContacts = synchronizeContacts
|
self.synchronizeContacts = synchronizeContacts
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(from decoder: Decoder) throws {
|
||||||
self.synchronizeContacts = decoder.decodeInt32ForKey("synchronizeContacts", orElse: 0) != 0
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
|
|
||||||
|
self.synchronizeContacts = ((try? container.decode(Int32.self, forKey: "synchronizeContacts")) ?? 0) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(to encoder: Encoder) throws {
|
||||||
encoder.encodeInt32(self.synchronizeContacts ? 1 : 0, forKey: "synchronizeContacts")
|
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||||
}
|
|
||||||
|
try container.encode((self.synchronizeContacts ? 1 : 0) as Int32, forKey: "synchronizeContacts")
|
||||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
|
||||||
if let to = to as? ContactsSettings {
|
|
||||||
return self == to
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Postbox
|
import Postbox
|
||||||
|
|
||||||
public final class ContentPrivacySettings: PreferencesEntry, Equatable {
|
public final class ContentPrivacySettings: Codable {
|
||||||
public let enableSecretChatWebpagePreviews: Bool?
|
public let enableSecretChatWebpagePreviews: Bool?
|
||||||
|
|
||||||
public static var defaultSettings = ContentPrivacySettings(enableSecretChatWebpagePreviews: nil)
|
public static var defaultSettings = ContentPrivacySettings(enableSecretChatWebpagePreviews: nil)
|
||||||
@ -9,34 +9,27 @@ public final class ContentPrivacySettings: PreferencesEntry, Equatable {
|
|||||||
self.enableSecretChatWebpagePreviews = enableSecretChatWebpagePreviews
|
self.enableSecretChatWebpagePreviews = enableSecretChatWebpagePreviews
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(from decoder: Decoder) throws {
|
||||||
self.enableSecretChatWebpagePreviews = decoder.decodeOptionalInt32ForKey("enableSecretChatWebpagePreviews").flatMap { $0 != 0 }
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
|
|
||||||
|
if let value = try? container.decodeIfPresent(Int32.self, forKey: "enableSecretChatWebpagePreviews") {
|
||||||
|
self.enableSecretChatWebpagePreviews = value != 0
|
||||||
|
} else {
|
||||||
|
self.enableSecretChatWebpagePreviews = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||||
|
|
||||||
if let enableSecretChatWebpagePreviews = self.enableSecretChatWebpagePreviews {
|
if let enableSecretChatWebpagePreviews = self.enableSecretChatWebpagePreviews {
|
||||||
encoder.encodeInt32(enableSecretChatWebpagePreviews ? 1 : 0, forKey: "enableSecretChatWebpagePreviews")
|
try container.encode((enableSecretChatWebpagePreviews ? 1 : 0) as Int32, forKey: "enableSecretChatWebpagePreviews")
|
||||||
} else {
|
} else {
|
||||||
encoder.encodeNil(forKey: "enableSecretChatWebpagePreviews")
|
try container.encodeNil(forKey: "enableSecretChatWebpagePreviews")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func withUpdatedEnableSecretChatWebpagePreviews(_ enableSecretChatWebpagePreviews: Bool) -> ContentPrivacySettings {
|
public func withUpdatedEnableSecretChatWebpagePreviews(_ enableSecretChatWebpagePreviews: Bool) -> ContentPrivacySettings {
|
||||||
return ContentPrivacySettings(enableSecretChatWebpagePreviews: enableSecretChatWebpagePreviews)
|
return ContentPrivacySettings(enableSecretChatWebpagePreviews: enableSecretChatWebpagePreviews)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
|
||||||
guard let to = to as? ContentPrivacySettings else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return self == to
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: ContentPrivacySettings, rhs: ContentPrivacySettings) -> Bool {
|
|
||||||
if lhs.enableSecretChatWebpagePreviews != rhs.enableSecretChatWebpagePreviews {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Postbox
|
import Postbox
|
||||||
|
|
||||||
public struct MessageNotificationSettings: PostboxCoding, Equatable {
|
public struct MessageNotificationSettings: Codable {
|
||||||
public var enabled: Bool
|
public var enabled: Bool
|
||||||
public var displayPreviews: Bool
|
public var displayPreviews: Bool
|
||||||
public var sound: PeerMessageSound
|
public var sound: PeerMessageSound
|
||||||
@ -15,10 +15,13 @@ public struct MessageNotificationSettings: PostboxCoding, Equatable {
|
|||||||
self.sound = sound
|
self.sound = sound
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(from decoder: Decoder) throws {
|
||||||
self.enabled = decoder.decodeInt32ForKey("e", orElse: 0) != 0
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
self.displayPreviews = decoder.decodeInt32ForKey("p", orElse: 0) != 0
|
|
||||||
self.sound = PeerMessageSound.decodeInline(decoder)
|
self.enabled = ((try? container.decode(Int32.self, forKey: "e")) ?? 0) != 0
|
||||||
|
self.displayPreviews = ((try? container.decode(Int32.self, forKey: "p")) ?? 0) != 0
|
||||||
|
|
||||||
|
self.sound = PeerMessageSound.decodeInline(container)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
@ -28,7 +31,7 @@ public struct MessageNotificationSettings: PostboxCoding, Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct GlobalNotificationSettingsSet: PostboxCoding, Equatable {
|
public struct GlobalNotificationSettingsSet: Codable {
|
||||||
public var privateChats: MessageNotificationSettings
|
public var privateChats: MessageNotificationSettings
|
||||||
public var groupChats: MessageNotificationSettings
|
public var groupChats: MessageNotificationSettings
|
||||||
public var channels: MessageNotificationSettings
|
public var channels: MessageNotificationSettings
|
||||||
@ -45,7 +48,9 @@ public struct GlobalNotificationSettingsSet: PostboxCoding, Equatable {
|
|||||||
self.contactsJoined = contactsJoined
|
self.contactsJoined = contactsJoined
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
|
|
||||||
self.privateChats = decoder.decodeObjectForKey("p", decoder: { MessageNotificationSettings(decoder: $0) }) as! MessageNotificationSettings
|
self.privateChats = decoder.decodeObjectForKey("p", decoder: { MessageNotificationSettings(decoder: $0) }) as! MessageNotificationSettings
|
||||||
self.groupChats = decoder.decodeObjectForKey("g", decoder: { MessageNotificationSettings(decoder: $0) }) as! MessageNotificationSettings
|
self.groupChats = decoder.decodeObjectForKey("g", decoder: { MessageNotificationSettings(decoder: $0) }) as! MessageNotificationSettings
|
||||||
self.channels = (decoder.decodeObjectForKey("c", decoder: { MessageNotificationSettings(decoder: $0) }) as? MessageNotificationSettings) ?? MessageNotificationSettings.defaultSettings
|
self.channels = (decoder.decodeObjectForKey("c", decoder: { MessageNotificationSettings(decoder: $0) }) as? MessageNotificationSettings) ?? MessageNotificationSettings.defaultSettings
|
||||||
@ -60,7 +65,7 @@ public struct GlobalNotificationSettingsSet: PostboxCoding, Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct GlobalNotificationSettings: PreferencesEntry, Equatable, PostboxGlobalNotificationSettings {
|
public struct GlobalNotificationSettings: Codable {
|
||||||
public var toBeSynchronized: GlobalNotificationSettingsSet?
|
public var toBeSynchronized: GlobalNotificationSettingsSet?
|
||||||
public var remote: GlobalNotificationSettingsSet
|
public var remote: GlobalNotificationSettingsSet
|
||||||
|
|
||||||
@ -73,8 +78,16 @@ public struct GlobalNotificationSettings: PreferencesEntry, Equatable, PostboxGl
|
|||||||
return self.remote
|
return self.remote
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var postboxAccessor: PostboxGlobalNotificationSettings {
|
||||||
|
return PostboxGlobalNotificationSettings(
|
||||||
|
defaultIncludePeer: { peer in
|
||||||
|
return self.defaultIncludePeer(peer: peer)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
public func defaultIncludePeer(peer: Peer) -> Bool {
|
private func defaultIncludePeer(peer: Peer) -> Bool {
|
||||||
let settings = self.effective
|
let settings = self.effective
|
||||||
if peer is TelegramUser || peer is TelegramSecretChat {
|
if peer is TelegramUser || peer is TelegramSecretChat {
|
||||||
return settings.privateChats.enabled
|
return settings.privateChats.enabled
|
||||||
@ -92,7 +105,7 @@ public struct GlobalNotificationSettings: PreferencesEntry, Equatable, PostboxGl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isEqualInDefaultPeerInclusion(other: PostboxGlobalNotificationSettings) -> Bool {
|
/*public func isEqualInDefaultPeerInclusion(other: PostboxGlobalNotificationSettings) -> Bool {
|
||||||
guard let other = other as? GlobalNotificationSettings else {
|
guard let other = other as? GlobalNotificationSettings else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -110,19 +123,21 @@ public struct GlobalNotificationSettings: PreferencesEntry, Equatable, PostboxGl
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public init(toBeSynchronized: GlobalNotificationSettingsSet?, remote: GlobalNotificationSettingsSet) {
|
public init(toBeSynchronized: GlobalNotificationSettingsSet?, remote: GlobalNotificationSettingsSet) {
|
||||||
self.toBeSynchronized = toBeSynchronized
|
self.toBeSynchronized = toBeSynchronized
|
||||||
self.remote = remote
|
self.remote = remote
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
|
|
||||||
self.toBeSynchronized = decoder.decodeObjectForKey("s", decoder: { GlobalNotificationSettingsSet(decoder: $0) }) as? GlobalNotificationSettingsSet
|
self.toBeSynchronized = decoder.decodeObjectForKey("s", decoder: { GlobalNotificationSettingsSet(decoder: $0) }) as? GlobalNotificationSettingsSet
|
||||||
self.remote = decoder.decodeObjectForKey("r", decoder: { GlobalNotificationSettingsSet(decoder: $0) }) as! GlobalNotificationSettingsSet
|
self.remote = decoder.decodeObjectForKey("r", decoder: { GlobalNotificationSettingsSet(decoder: $0) }) as! GlobalNotificationSettingsSet
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(to encoder: Encoder) throws {
|
||||||
if let toBeSynchronized = self.toBeSynchronized {
|
if let toBeSynchronized = self.toBeSynchronized {
|
||||||
encoder.encodeObject(toBeSynchronized, forKey: "s")
|
encoder.encodeObject(toBeSynchronized, forKey: "s")
|
||||||
} else {
|
} else {
|
||||||
@ -130,12 +145,4 @@ public struct GlobalNotificationSettings: PreferencesEntry, Equatable, PostboxGl
|
|||||||
}
|
}
|
||||||
encoder.encodeObject(self.remote, forKey: "r")
|
encoder.encodeObject(self.remote, forKey: "r")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
|
||||||
if let to = to as? GlobalNotificationSettings {
|
|
||||||
return self == to
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,7 +62,9 @@ public let telegramPostboxSeedConfiguration: SeedConfiguration = {
|
|||||||
assertionFailure()
|
assertionFailure()
|
||||||
return .nonContact
|
return .nonContact
|
||||||
}
|
}
|
||||||
}, additionalChatListIndexNamespace: Namespaces.Message.Cloud, messageNamespacesRequiringGroupStatsValidation: [Namespaces.Message.Cloud], defaultMessageNamespaceReadStates: [Namespaces.Message.Local: .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 0, markedUnread: false)], chatMessagesNamespaces: Set([Namespaces.Message.Cloud, Namespaces.Message.Local, Namespaces.Message.SecretIncoming]), globalNotificationSettingsPreferencesKey: PreferencesKeys.globalNotifications, defaultGlobalNotificationSettings: GlobalNotificationSettings.defaultSettings)
|
}, additionalChatListIndexNamespace: Namespaces.Message.Cloud, messageNamespacesRequiringGroupStatsValidation: [Namespaces.Message.Cloud], defaultMessageNamespaceReadStates: [Namespaces.Message.Local: .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 0, markedUnread: false)], chatMessagesNamespaces: Set([Namespaces.Message.Cloud, Namespaces.Message.Local, Namespaces.Message.SecretIncoming]), globalNotificationSettingsPreferencesKey: { transaction in
|
||||||
|
return transaction.getPreferencesEntry(PreferencesKeys.globalNotifications)?.get(GlobalNotificationSettings.self)
|
||||||
|
}, defaultGlobalNotificationSettings: GlobalNotificationSettings.defaultSettings)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
public enum AccountTransactionError {
|
public enum AccountTransactionError {
|
||||||
|
|||||||
@ -44,14 +44,14 @@ public enum PeerMessageSound: Equatable {
|
|||||||
case bundledModern(id: Int32)
|
case bundledModern(id: Int32)
|
||||||
case bundledClassic(id: Int32)
|
case bundledClassic(id: Int32)
|
||||||
|
|
||||||
static func decodeInline(_ decoder: PostboxDecoder) -> PeerMessageSound {
|
static func decodeInline(_ container: KeyedDecodingContainer<StringCodingKey>) throws -> PeerMessageSound {
|
||||||
switch decoder.decodeInt32ForKey("s.v", orElse: 0) {
|
switch try container.decode(Int32.self, forKey: "s.v") {
|
||||||
case PeerMessageSoundValue.none.rawValue:
|
case PeerMessageSoundValue.none.rawValue:
|
||||||
return .none
|
return .none
|
||||||
case PeerMessageSoundValue.bundledModern.rawValue:
|
case PeerMessageSoundValue.bundledModern.rawValue:
|
||||||
return .bundledModern(id: decoder.decodeInt32ForKey("s.i", orElse: 0))
|
return .bundledModern(id: (try? container.decode(Int32.self, forKey: "s.i")) ?? 0)
|
||||||
case PeerMessageSoundValue.bundledClassic.rawValue:
|
case PeerMessageSoundValue.bundledClassic.rawValue:
|
||||||
return .bundledClassic(id: decoder.decodeInt32ForKey("s.i", orElse: 0))
|
return .bundledClassic(id: (try? container.decode(Int32.self, forKey: "s.i")) ?? 0)
|
||||||
case PeerMessageSoundValue.default.rawValue:
|
case PeerMessageSoundValue.default.rawValue:
|
||||||
return .default
|
return .default
|
||||||
default:
|
default:
|
||||||
@ -170,7 +170,7 @@ public final class TelegramPeerNotificationSettings: PeerNotificationSettings, E
|
|||||||
self.displayPreviews = displayPreviews
|
self.displayPreviews = displayPreviews
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init() {
|
||||||
self.muteState = PeerMuteState.decodeInline(decoder)
|
self.muteState = PeerMuteState.decodeInline(decoder)
|
||||||
self.messageSound = PeerMessageSound.decodeInline(decoder)
|
self.messageSound = PeerMessageSound.decodeInline(decoder)
|
||||||
self.displayPreviews = PeerNotificationDisplayPreviews.decodeInline(decoder)
|
self.displayPreviews = PeerNotificationDisplayPreviews.decodeInline(decoder)
|
||||||
|
|||||||
@ -63,7 +63,7 @@ private final class NetworkBroadcastPartSource: BroadcastPartSource {
|
|||||||
if timestampMilliseconds != 0 {
|
if timestampMilliseconds != 0 {
|
||||||
timestampIdMilliseconds = timestampMilliseconds
|
timestampIdMilliseconds = timestampMilliseconds
|
||||||
} else {
|
} else {
|
||||||
timestampIdMilliseconds = (Int64(Date().timeIntervalSince1970 * 1000.0) / durationMilliseconds) * durationMilliseconds
|
timestampIdMilliseconds = (Int64((Date().timeIntervalSince1970) * 1000.0) / durationMilliseconds) * durationMilliseconds
|
||||||
}
|
}
|
||||||
|
|
||||||
let dataSource: Signal<AudioBroadcastDataSource?, NoError>
|
let dataSource: Signal<AudioBroadcastDataSource?, NoError>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user