Updated folder pinned chats interaction

This commit is contained in:
Ali 2020-03-16 23:42:12 +05:30
parent 899e00fc9e
commit b69ce50986
7 changed files with 146 additions and 76 deletions

View File

@ -544,7 +544,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
}) })
}) })
}))) })))
if let filter = filters.first(where: { $0.id == id }), filter.data.includePeers.count < 100 { if let filter = filters.first(where: { $0.id == id }), filter.data.includePeers.peers.count < 100 {
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.ChatList_AddChatsToFolder, icon: { theme in items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.ChatList_AddChatsToFolder, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Add"), color: theme.contextMenu.primaryColor) return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Add"), color: theme.contextMenu.primaryColor)
}, action: { c, f in }, action: { c, f in

View File

@ -543,7 +543,7 @@ private func internalChatListFilterAddChatsController(context: AccountContext, f
} }
} }
let controller = context.sharedContext.makeContactMultiselectionController(ContactMultiselectionControllerParams(context: context, mode: .chatSelection(title: presentationData.strings.ChatListFolder_IncludeChatsTitle, selectedChats: Set(filter.data.includePeers), additionalCategories: ContactMultiselectionControllerAdditionalCategories(categories: additionalCategories, selectedCategories: selectedCategories)), options: [], alwaysEnabled: true)) let controller = context.sharedContext.makeContactMultiselectionController(ContactMultiselectionControllerParams(context: context, mode: .chatSelection(title: presentationData.strings.ChatListFolder_IncludeChatsTitle, selectedChats: Set(filter.data.includePeers.peers), additionalCategories: ContactMultiselectionControllerAdditionalCategories(categories: additionalCategories, selectedCategories: selectedCategories)), options: [], alwaysEnabled: true))
controller.navigationPresentation = .modal controller.navigationPresentation = .modal
let _ = (controller.result let _ = (controller.result
|> take(1) |> take(1)
@ -579,8 +579,8 @@ private func internalChatListFilterAddChatsController(context: AccountContext, f
for i in 0 ..< filters.count { for i in 0 ..< filters.count {
if filters[i].id == filter.id { if filters[i].id == filter.id {
filters[i].data.categories = categories filters[i].data.categories = categories
filters[i].data.includePeers = includePeers filters[i].data.includePeers.setPeers(includePeers)
filters[i].data.excludePeers = filters[i].data.excludePeers.filter { !filters[i].data.includePeers.contains($0) } filters[i].data.excludePeers = filters[i].data.excludePeers.filter { !filters[i].data.includePeers.peers.contains($0) }
} }
} }
return filters return filters
@ -591,8 +591,8 @@ private func internalChatListFilterAddChatsController(context: AccountContext, f
} else { } else {
var filter = filter var filter = filter
filter.data.categories = categories filter.data.categories = categories
filter.data.includePeers = includePeers filter.data.includePeers.setPeers(includePeers)
filter.data.excludePeers = filter.data.excludePeers.filter { !filter.data.includePeers.contains($0) } filter.data.excludePeers = filter.data.excludePeers.filter { !filter.data.includePeers.peers.contains($0) }
updated(filter) updated(filter)
controller?.dismiss() controller?.dismiss()
} }
@ -660,7 +660,7 @@ private func internalChatListFilterExcludeChatsController(context: AccountContex
filters[i].data.excludeRead = additionalCategoryIds.contains(AdditionalExcludeCategoryId.read.rawValue) filters[i].data.excludeRead = additionalCategoryIds.contains(AdditionalExcludeCategoryId.read.rawValue)
filters[i].data.excludeArchived = additionalCategoryIds.contains(AdditionalExcludeCategoryId.archived.rawValue) filters[i].data.excludeArchived = additionalCategoryIds.contains(AdditionalExcludeCategoryId.archived.rawValue)
filters[i].data.excludePeers = excludePeers filters[i].data.excludePeers = excludePeers
filters[i].data.includePeers = filters[i].data.includePeers.filter { !filters[i].data.excludePeers.contains($0) } filters[i].data.includePeers.setPeers(filters[i].data.includePeers.peers.filter { !filters[i].data.excludePeers.contains($0) })
} }
} }
return filters return filters
@ -674,7 +674,7 @@ private func internalChatListFilterExcludeChatsController(context: AccountContex
filter.data.excludeRead = additionalCategoryIds.contains(AdditionalExcludeCategoryId.read.rawValue) filter.data.excludeRead = additionalCategoryIds.contains(AdditionalExcludeCategoryId.read.rawValue)
filter.data.excludeArchived = additionalCategoryIds.contains(AdditionalExcludeCategoryId.archived.rawValue) filter.data.excludeArchived = additionalCategoryIds.contains(AdditionalExcludeCategoryId.archived.rawValue)
filter.data.excludePeers = excludePeers filter.data.excludePeers = excludePeers
filter.data.includePeers = filter.data.includePeers.filter { !filter.data.excludePeers.contains($0) } filter.data.includePeers.setPeers(filter.data.includePeers.peers.filter { !filter.data.excludePeers.contains($0) })
updated(filter) updated(filter)
controller?.dismiss() controller?.dismiss()
} }
@ -695,7 +695,7 @@ enum ChatListFilterType {
func chatListFilterType(_ filter: ChatListFilter) -> ChatListFilterType { func chatListFilterType(_ filter: ChatListFilter) -> ChatListFilterType {
let filterType: ChatListFilterType let filterType: ChatListFilterType
if filter.data.includePeers.isEmpty { if filter.data.includePeers.peers.isEmpty {
if filter.data.categories == .all { if filter.data.categories == .all {
if filter.data.excludeRead { if filter.data.excludeRead {
filterType = .unread filterType = .unread
@ -732,7 +732,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
} else { } else {
initialName = "" initialName = ""
} }
let initialState = ChatListFilterPresetControllerState(name: initialName, changedName: currentPreset != nil, includeCategories: currentPreset?.data.categories ?? [], excludeMuted: currentPreset?.data.excludeMuted ?? false, excludeRead: currentPreset?.data.excludeRead ?? false, excludeArchived: currentPreset?.data.excludeArchived ?? false, additionallyIncludePeers: currentPreset?.data.includePeers ?? [], additionallyExcludePeers: currentPreset?.data.excludePeers ?? []) let initialState = ChatListFilterPresetControllerState(name: initialName, changedName: currentPreset != nil, includeCategories: currentPreset?.data.categories ?? [], excludeMuted: currentPreset?.data.excludeMuted ?? false, excludeRead: currentPreset?.data.excludeRead ?? false, excludeArchived: currentPreset?.data.excludeArchived ?? false, additionallyIncludePeers: currentPreset?.data.includePeers.peers ?? [], additionallyExcludePeers: currentPreset?.data.excludePeers ?? [])
let stateValue = Atomic(value: initialState) let stateValue = Atomic(value: initialState)
let statePromise = ValuePromise(initialState, ignoreRepeated: true) let statePromise = ValuePromise(initialState, ignoreRepeated: true)
let updateState: ((ChatListFilterPresetControllerState) -> ChatListFilterPresetControllerState) -> Void = { f in let updateState: ((ChatListFilterPresetControllerState) -> ChatListFilterPresetControllerState) -> Void = { f in
@ -740,7 +740,9 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
var state = f(current) var state = f(current)
if !state.changedName { if !state.changedName {
let presentationData = context.sharedContext.currentPresentationData.with { $0 } let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let filter = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: state.additionallyIncludePeers, excludePeers: state.additionallyExcludePeers, pinnedPeers: currentPreset?.data.pinnedPeers ?? [])) var includePeers = ChatListFilterIncludePeers()
includePeers.setPeers(state.additionallyIncludePeers)
let filter = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: includePeers, excludePeers: state.additionallyExcludePeers))
switch chatListFilterType(filter) { switch chatListFilterType(filter) {
case .generic: case .generic:
state.name = initialName state.name = initialName
@ -781,13 +783,15 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
}, },
openAddIncludePeer: { openAddIncludePeer: {
let state = stateValue.with { $0 } let state = stateValue.with { $0 }
let filter = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: state.additionallyIncludePeers, excludePeers: state.additionallyExcludePeers, pinnedPeers: currentPreset?.data.pinnedPeers ?? [])) var includePeers = ChatListFilterIncludePeers()
includePeers.setPeers(state.additionallyIncludePeers)
let filter = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: includePeers, excludePeers: state.additionallyExcludePeers))
let controller = internalChatListFilterAddChatsController(context: context, filter: filter, applyAutomatically: false, updated: { filter in let controller = internalChatListFilterAddChatsController(context: context, filter: filter, applyAutomatically: false, updated: { filter in
skipStateAnimation = true skipStateAnimation = true
updateState { state in updateState { state in
var state = state var state = state
state.additionallyIncludePeers = filter.data.includePeers state.additionallyIncludePeers = filter.data.includePeers.peers
state.additionallyExcludePeers = filter.data.excludePeers state.additionallyExcludePeers = filter.data.excludePeers
state.includeCategories = filter.data.categories state.includeCategories = filter.data.categories
return state return state
@ -797,13 +801,15 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
}, },
openAddExcludePeer: { openAddExcludePeer: {
let state = stateValue.with { $0 } let state = stateValue.with { $0 }
let filter = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: state.additionallyIncludePeers, excludePeers: state.additionallyExcludePeers, pinnedPeers: currentPreset?.data.pinnedPeers ?? [])) var includePeers = ChatListFilterIncludePeers()
includePeers.setPeers(state.additionallyIncludePeers)
let filter = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: includePeers, excludePeers: state.additionallyExcludePeers))
let controller = internalChatListFilterExcludeChatsController(context: context, filter: filter, applyAutomatically: false, updated: { filter in let controller = internalChatListFilterExcludeChatsController(context: context, filter: filter, applyAutomatically: false, updated: { filter in
skipStateAnimation = true skipStateAnimation = true
updateState { state in updateState { state in
var state = state var state = state
state.additionallyIncludePeers = filter.data.includePeers state.additionallyIncludePeers = filter.data.includePeers.peers
state.additionallyExcludePeers = filter.data.excludePeers state.additionallyExcludePeers = filter.data.excludePeers
state.includeCategories = filter.data.categories state.includeCategories = filter.data.categories
state.excludeRead = filter.data.excludeRead state.excludeRead = filter.data.excludeRead
@ -918,32 +924,36 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
var attemptNavigationImpl: (() -> Bool)? var attemptNavigationImpl: (() -> Bool)?
var applyImpl: (() -> Void)? = { var applyImpl: (() -> Void)? = {
let state = stateValue.with { $0 } let state = stateValue.with { $0 }
let preset = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: state.additionallyIncludePeers, excludePeers: state.additionallyExcludePeers, pinnedPeers: currentPreset?.data.pinnedPeers ?? []))
let _ = (updateChatListFiltersInteractively(postbox: context.account.postbox, { filters in let _ = (updateChatListFiltersInteractively(postbox: context.account.postbox, { filters in
var preset = preset var includePeers = ChatListFilterIncludePeers()
includePeers.setPeers(state.additionallyIncludePeers)
var updatedFilter = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: includePeers, excludePeers: state.additionallyExcludePeers))
if currentPreset == nil { if currentPreset == nil {
preset.id = max(2, filters.map({ $0.id + 1 }).max() ?? 2) updatedFilter.id = max(2, filters.map({ $0.id + 1 }).max() ?? 2)
} }
var filters = filters var filters = filters
if let _ = currentPreset { if let _ = currentPreset {
var found = false var found = false
for i in 0 ..< filters.count { for i in 0 ..< filters.count {
if filters[i].id == preset.id { if filters[i].id == updatedFilter.id {
filters[i] = preset var includePeers = filters[i].data.includePeers
includePeers.setPeers(state.additionallyIncludePeers)
updatedFilter.data.includePeers = includePeers
filters[i] = updatedFilter
found = true found = true
} }
} }
if !found { if !found {
filters = filters.filter { listFilter in filters = filters.filter { listFilter in
if listFilter.title == preset.title && listFilter.data == preset.data { if listFilter.title == updatedFilter.title && listFilter.data == updatedFilter.data {
return false return false
} }
return true return true
} }
filters.append(preset) filters.append(updatedFilter)
} }
} else { } else {
filters.append(preset) filters.append(updatedFilter)
} }
return filters return filters
}) })
@ -1013,8 +1023,15 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
attemptNavigationImpl = { attemptNavigationImpl = {
let state = stateValue.with { $0 } let state = stateValue.with { $0 }
if let currentPreset = currentPreset { if let currentPreset = currentPreset {
let filter = ChatListFilter(id: currentPreset.id, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: state.additionallyIncludePeers, excludePeers: state.additionallyExcludePeers, pinnedPeers: currentPreset.data.pinnedPeers)) var currentPresetWithoutPinnerPeers = currentPreset
if currentPreset != filter { var currentIncludePeers = ChatListFilterIncludePeers()
currentIncludePeers.setPeers(currentPresetWithoutPinnerPeers.data.includePeers.peers)
currentPresetWithoutPinnerPeers.data.includePeers = currentIncludePeers
var includePeers = ChatListFilterIncludePeers()
includePeers.setPeers(state.additionallyIncludePeers)
let filter = ChatListFilter(id: currentPreset.id, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: includePeers, excludePeers: state.additionallyExcludePeers))
if currentPresetWithoutPinnerPeers != filter {
displaySaveAlert() displaySaveAlert()
return false return false
} }

View File

@ -30,12 +30,12 @@ struct ChatListNodeViewUpdate {
} }
func chatListFilterPredicate(filter: ChatListFilterData) -> ChatListFilterPredicate { func chatListFilterPredicate(filter: ChatListFilterData) -> ChatListFilterPredicate {
var includePeers = Set(filter.includePeers) var includePeers = Set(filter.includePeers.peers)
var excludePeers = Set(filter.excludePeers) var excludePeers = Set(filter.excludePeers)
if !filter.pinnedPeers.isEmpty { if !filter.includePeers.pinnedPeers.isEmpty {
includePeers.subtract(filter.pinnedPeers) includePeers.subtract(filter.includePeers.pinnedPeers)
excludePeers.subtract(filter.pinnedPeers) excludePeers.subtract(filter.includePeers.pinnedPeers)
} }
var includeAdditionalPeerGroupIds: [PeerGroupId] = [] var includeAdditionalPeerGroupIds: [PeerGroupId] = []
@ -47,7 +47,7 @@ func chatListFilterPredicate(filter: ChatListFilterData) -> ChatListFilterPredic
if filter.excludeRead { if filter.excludeRead {
messageTagSummary = ChatListMessageTagSummaryResultCalculation(addCount: ChatListMessageTagSummaryResultComponent(tag: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud), subtractCount: ChatListMessageTagActionsSummaryResultComponent(type: PendingMessageActionType.consumeUnseenPersonalMessage, namespace: Namespaces.Message.Cloud)) messageTagSummary = ChatListMessageTagSummaryResultCalculation(addCount: ChatListMessageTagSummaryResultComponent(tag: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud), subtractCount: ChatListMessageTagActionsSummaryResultComponent(type: PendingMessageActionType.consumeUnseenPersonalMessage, namespace: Namespaces.Message.Cloud))
} }
return ChatListFilterPredicate(includePeerIds: includePeers, excludePeerIds: excludePeers, pinnedPeerIds: filter.pinnedPeers, messageTagSummary: messageTagSummary, includeAdditionalPeerGroupIds: includeAdditionalPeerGroupIds, include: { peer, isMuted, isUnread, isContact, messageTagSummaryResult in return ChatListFilterPredicate(includePeerIds: includePeers, excludePeerIds: excludePeers, pinnedPeerIds: filter.includePeers.pinnedPeers, messageTagSummary: messageTagSummary, includeAdditionalPeerGroupIds: includeAdditionalPeerGroupIds, include: { peer, isMuted, isUnread, isContact, messageTagSummaryResult in
if filter.excludeRead { if filter.excludeRead {
var effectiveUnread = isUnread var effectiveUnread = isUnread
if let messageTagSummaryResult = messageTagSummaryResult, messageTagSummaryResult { if let messageTagSummaryResult = messageTagSummaryResult, messageTagSummaryResult {

View File

@ -189,11 +189,10 @@ func preparedChatListNodeViewTransition(from fromView: ChatListNodeView?, to toV
} }
} else if fromView.filteredEntries.isEmpty || fromView.filter != toView.filter { } else if fromView.filteredEntries.isEmpty || fromView.filter != toView.filter {
var updateEmpty = true var updateEmpty = true
if !fromView.filteredEntries.isEmpty, let fromFilter = fromView.filter, let toFilter = toView.filter, fromFilter.data.pinnedPeers != toFilter.data.pinnedPeers { if !fromView.filteredEntries.isEmpty, let fromFilter = fromView.filter, let toFilter = toView.filter, fromFilter.data.includePeers.pinnedPeers != toFilter.data.includePeers.pinnedPeers {
var fromData = fromFilter.data var fromData = fromFilter.data
var toData = toFilter.data let toData = toFilter.data
fromData.pinnedPeers = [] fromData.includePeers = toData.includePeers
toData.pinnedPeers = []
if fromData == toData { if fromData == toData {
options.insert(.AnimateInsertion) options.insert(.AnimateInsertion)
updateEmpty = false updateEmpty = false

View File

@ -19,7 +19,7 @@ func chatListFilterItems(context: AccountContext) -> Signal<(Int, [(ChatListFilt
var additionalPeerIds = Set<PeerId>() var additionalPeerIds = Set<PeerId>()
var additionalGroupIds = Set<PeerGroupId>() var additionalGroupIds = Set<PeerGroupId>()
for filter in filters { for filter in filters {
additionalPeerIds.formUnion(filter.data.includePeers) additionalPeerIds.formUnion(filter.data.includePeers.peers)
additionalPeerIds.formUnion(filter.data.excludePeers) additionalPeerIds.formUnion(filter.data.excludePeers)
if !filter.data.excludeArchived { if !filter.data.excludeArchived {
additionalGroupIds.insert(Namespaces.PeerGroup.archive) additionalGroupIds.insert(Namespaces.PeerGroup.archive)
@ -146,7 +146,7 @@ func chatListFilterItems(context: AccountContext) -> Signal<(Int, [(ChatListFilt
} }
} }
} }
for peerId in filter.data.includePeers { for peerId in filter.data.includePeers.peers {
if let (tag, peerCount, hasUnmuted) = peerTagAndCount[peerId] { if let (tag, peerCount, hasUnmuted) = peerTagAndCount[peerId] {
if !tags.contains(tag) { if !tags.contains(tag) {
if peerCount != 0 { if peerCount != 0 {

View File

@ -96,23 +96,78 @@ extension ChatListFilterPeerCategories {
} }
} }
public struct ChatListFilterIncludePeers: Equatable, Hashable {
public private(set) var peers: [PeerId]
public private(set) var pinnedPeers: [PeerId]
public init() {
self.peers = []
self.pinnedPeers = []
}
init(peers: [PeerId], pinnedPeers: [PeerId]) {
self.peers = peers
self.pinnedPeers = pinnedPeers
}
public mutating func reorderPinnedPeers(_ pinnedPeers: [PeerId]) {
if Set(self.pinnedPeers) == Set(pinnedPeers) {
self.pinnedPeers = pinnedPeers
}
}
public mutating func addPinnedPeer(_ peerId: PeerId) -> Bool {
if self.pinnedPeers.contains(peerId) {
return false
}
if self.peers.contains(peerId) {
self.pinnedPeers.insert(peerId, at: 0)
return true
} else {
if self.peers.count < 100 {
self.peers.insert(peerId, at: 0)
self.pinnedPeers.insert(peerId, at: 0)
return true
} else {
return false
}
}
}
public mutating func removePinnedPeer(_ peerId: PeerId) {
if self.pinnedPeers.contains(peerId) {
self.pinnedPeers.removeAll(where: { $0 == peerId })
}
}
public mutating func setPeers(_ peers: [PeerId]) {
self.peers = peers
self.pinnedPeers = self.pinnedPeers.filter { peers.contains($0) }
}
}
extension ChatListFilterIncludePeers {
init(rawPeers: [PeerId], rawPinnedPeers: [PeerId]) {
self.peers = rawPinnedPeers + rawPeers.filter { !rawPinnedPeers.contains($0) }
self.pinnedPeers = rawPinnedPeers
}
}
public struct ChatListFilterData: Equatable, Hashable { public struct ChatListFilterData: Equatable, Hashable {
public var categories: ChatListFilterPeerCategories public var categories: ChatListFilterPeerCategories
public var excludeMuted: Bool public var excludeMuted: Bool
public var excludeRead: Bool public var excludeRead: Bool
public var excludeArchived: Bool public var excludeArchived: Bool
public var includePeers: [PeerId] public var includePeers: ChatListFilterIncludePeers
public var excludePeers: [PeerId] public var excludePeers: [PeerId]
public var pinnedPeers: [PeerId]
public init( public init(
categories: ChatListFilterPeerCategories, categories: ChatListFilterPeerCategories,
excludeMuted: Bool, excludeMuted: Bool,
excludeRead: Bool, excludeRead: Bool,
excludeArchived: Bool, excludeArchived: Bool,
includePeers: [PeerId], includePeers: ChatListFilterIncludePeers,
excludePeers: [PeerId], excludePeers: [PeerId]
pinnedPeers: [PeerId]
) { ) {
self.categories = categories self.categories = categories
self.excludeMuted = excludeMuted self.excludeMuted = excludeMuted
@ -120,7 +175,6 @@ public struct ChatListFilterData: Equatable, Hashable {
self.excludeArchived = excludeArchived self.excludeArchived = excludeArchived
self.includePeers = includePeers self.includePeers = includePeers
self.excludePeers = excludePeers self.excludePeers = excludePeers
self.pinnedPeers = pinnedPeers
} }
} }
@ -147,9 +201,8 @@ public struct ChatListFilter: PostboxCoding, Equatable {
excludeMuted: decoder.decodeInt32ForKey("excludeMuted", orElse: 0) != 0, excludeMuted: decoder.decodeInt32ForKey("excludeMuted", orElse: 0) != 0,
excludeRead: decoder.decodeInt32ForKey("excludeRead", orElse: 0) != 0, excludeRead: decoder.decodeInt32ForKey("excludeRead", orElse: 0) != 0,
excludeArchived: decoder.decodeInt32ForKey("excludeArchived", orElse: 0) != 0, excludeArchived: decoder.decodeInt32ForKey("excludeArchived", orElse: 0) != 0,
includePeers: decoder.decodeInt64ArrayForKey("includePeers").map(PeerId.init), includePeers: ChatListFilterIncludePeers(peers: decoder.decodeInt64ArrayForKey("includePeers").map(PeerId.init), pinnedPeers: decoder.decodeInt64ArrayForKey("pinnedPeers").map(PeerId.init)),
excludePeers: decoder.decodeInt64ArrayForKey("excludePeers").map(PeerId.init), excludePeers: decoder.decodeInt64ArrayForKey("excludePeers").map(PeerId.init)
pinnedPeers: decoder.decodeInt64ArrayForKey("pinnedPeers").map(PeerId.init)
) )
} }
@ -160,9 +213,9 @@ public struct ChatListFilter: PostboxCoding, Equatable {
encoder.encodeInt32(self.data.excludeMuted ? 1 : 0, forKey: "excludeMuted") encoder.encodeInt32(self.data.excludeMuted ? 1 : 0, forKey: "excludeMuted")
encoder.encodeInt32(self.data.excludeRead ? 1 : 0, forKey: "excludeRead") encoder.encodeInt32(self.data.excludeRead ? 1 : 0, forKey: "excludeRead")
encoder.encodeInt32(self.data.excludeArchived ? 1 : 0, forKey: "excludeArchived") encoder.encodeInt32(self.data.excludeArchived ? 1 : 0, forKey: "excludeArchived")
encoder.encodeInt64Array(self.data.includePeers.map { $0.toInt64() }, forKey: "includePeers") encoder.encodeInt64Array(self.data.includePeers.peers.map { $0.toInt64() }, forKey: "includePeers")
encoder.encodeInt64Array(self.data.includePeers.pinnedPeers.map { $0.toInt64() }, forKey: "pinnedPeers")
encoder.encodeInt64Array(self.data.excludePeers.map { $0.toInt64() }, forKey: "excludePeers") encoder.encodeInt64Array(self.data.excludePeers.map { $0.toInt64() }, forKey: "excludePeers")
encoder.encodeInt64Array(self.data.pinnedPeers.map { $0.toInt64() }, forKey: "pinnedPeers")
} }
} }
@ -178,7 +231,7 @@ extension ChatListFilter {
excludeMuted: (flags & (1 << 11)) != 0, excludeMuted: (flags & (1 << 11)) != 0,
excludeRead: (flags & (1 << 12)) != 0, excludeRead: (flags & (1 << 12)) != 0,
excludeArchived: (flags & (1 << 13)) != 0, excludeArchived: (flags & (1 << 13)) != 0,
includePeers: includePeers.compactMap { peer -> PeerId? in includePeers: ChatListFilterIncludePeers(rawPeers: includePeers.compactMap { peer -> PeerId? in
switch peer { switch peer {
case let .inputPeerUser(userId, _): case let .inputPeerUser(userId, _):
return PeerId(namespace: Namespaces.Peer.CloudUser, id: userId) return PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
@ -189,7 +242,18 @@ extension ChatListFilter {
default: default:
return nil return nil
} }
}, }, rawPinnedPeers: pinnedPeers.compactMap { peer -> PeerId? in
switch peer {
case let .inputPeerUser(userId, _):
return PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
case let .inputPeerChat(chatId):
return PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)
case let .inputPeerChannel(channelId, _):
return PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
default:
return nil
}
}),
excludePeers: excludePeers.compactMap { peer -> PeerId? in excludePeers: excludePeers.compactMap { peer -> PeerId? in
switch peer { switch peer {
case let .inputPeerUser(userId, _): case let .inputPeerUser(userId, _):
@ -201,18 +265,6 @@ extension ChatListFilter {
default: default:
return nil return nil
} }
},
pinnedPeers: pinnedPeers.compactMap { peer -> PeerId? in
switch peer {
case let .inputPeerUser(userId, _):
return PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
case let .inputPeerChat(chatId):
return PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)
case let .inputPeerChannel(channelId, _):
return PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
default:
return nil
}
} }
) )
) )
@ -231,9 +283,12 @@ extension ChatListFilter {
flags |= 1 << 13 flags |= 1 << 13
} }
flags |= self.data.categories.apiFlags flags |= self.data.categories.apiFlags
return .dialogFilter(flags: flags, id: self.id, title: self.title, pinnedPeers: self.data.pinnedPeers.compactMap { peerId -> Api.InputPeer? in return .dialogFilter(flags: flags, id: self.id, title: self.title, pinnedPeers: self.data.includePeers.pinnedPeers.compactMap { peerId -> Api.InputPeer? in
return transaction.getPeer(peerId).flatMap(apiInputPeer) return transaction.getPeer(peerId).flatMap(apiInputPeer)
}, includePeers: self.data.includePeers.compactMap { peerId -> Api.InputPeer? in }, includePeers: self.data.includePeers.peers.compactMap { peerId -> Api.InputPeer? in
if self.data.includePeers.pinnedPeers.contains(peerId) {
return nil
}
return transaction.getPeer(peerId).flatMap(apiInputPeer) return transaction.getPeer(peerId).flatMap(apiInputPeer)
}, excludePeers: self.data.excludePeers.compactMap { peerId -> Api.InputPeer? in }, excludePeers: self.data.excludePeers.compactMap { peerId -> Api.InputPeer? in
return transaction.getPeer(peerId).flatMap(apiInputPeer) return transaction.getPeer(peerId).flatMap(apiInputPeer)
@ -436,7 +491,9 @@ private func requestChatListFilters(postbox: Postbox, network: Network) -> Signa
) )
|> castError(RequestChatListFiltersError.self) |> castError(RequestChatListFiltersError.self)
|> mapToSignal { _ -> Signal<[ChatListFilter], RequestChatListFiltersError> in |> mapToSignal { _ -> Signal<[ChatListFilter], RequestChatListFiltersError> in
#if swift(<5)
return .complete() return .complete()
#endif
} }
|> then( |> then(
.single(filters) .single(filters)
@ -593,9 +650,8 @@ public struct ChatListFeaturedFilter: PostboxCoding, Equatable {
excludeMuted: decoder.decodeInt32ForKey("excludeMuted", orElse: 0) != 0, excludeMuted: decoder.decodeInt32ForKey("excludeMuted", orElse: 0) != 0,
excludeRead: decoder.decodeInt32ForKey("excludeRead", orElse: 0) != 0, excludeRead: decoder.decodeInt32ForKey("excludeRead", orElse: 0) != 0,
excludeArchived: decoder.decodeInt32ForKey("excludeArchived", orElse: 0) != 0, excludeArchived: decoder.decodeInt32ForKey("excludeArchived", orElse: 0) != 0,
includePeers: decoder.decodeInt64ArrayForKey("includePeers").map(PeerId.init), includePeers: ChatListFilterIncludePeers(peers: decoder.decodeInt64ArrayForKey("includePeers").map(PeerId.init), pinnedPeers: decoder.decodeInt64ArrayForKey("pinnedPeers").map(PeerId.init)),
excludePeers: decoder.decodeInt64ArrayForKey("excludePeers").map(PeerId.init), excludePeers: decoder.decodeInt64ArrayForKey("excludePeers").map(PeerId.init)
pinnedPeers: decoder.decodeInt64ArrayForKey("pinnedPeers").map(PeerId.init)
) )
} }
@ -606,9 +662,9 @@ public struct ChatListFeaturedFilter: PostboxCoding, Equatable {
encoder.encodeInt32(self.data.excludeMuted ? 1 : 0, forKey: "excludeMuted") encoder.encodeInt32(self.data.excludeMuted ? 1 : 0, forKey: "excludeMuted")
encoder.encodeInt32(self.data.excludeRead ? 1 : 0, forKey: "excludeRead") encoder.encodeInt32(self.data.excludeRead ? 1 : 0, forKey: "excludeRead")
encoder.encodeInt32(self.data.excludeArchived ? 1 : 0, forKey: "excludeArchived") encoder.encodeInt32(self.data.excludeArchived ? 1 : 0, forKey: "excludeArchived")
encoder.encodeInt64Array(self.data.includePeers.map { $0.toInt64() }, forKey: "includePeers") encoder.encodeInt64Array(self.data.includePeers.peers.map { $0.toInt64() }, forKey: "includePeers")
encoder.encodeInt64Array(self.data.includePeers.pinnedPeers.map { $0.toInt64() }, forKey: "pinnedPeers")
encoder.encodeInt64Array(self.data.excludePeers.map { $0.toInt64() }, forKey: "excludePeers") encoder.encodeInt64Array(self.data.excludePeers.map { $0.toInt64() }, forKey: "excludePeers")
encoder.encodeInt64Array(self.data.pinnedPeers.map { $0.toInt64() }, forKey: "pinnedPeers")
} }
} }

View File

@ -65,12 +65,10 @@ public func toggleItemPinned(postbox: Postbox, location: TogglePeerChatPinnedLoc
if let index = filters.firstIndex(where: { $0.id == filterId }) { if let index = filters.firstIndex(where: { $0.id == filterId }) {
switch itemId { switch itemId {
case let .peer(peerId): case let .peer(peerId):
if filters[index].data.pinnedPeers.contains(peerId) { if filters[index].data.includePeers.pinnedPeers.contains(peerId) {
filters[index].data.pinnedPeers.removeAll(where: { $0 == peerId }) filters[index].data.includePeers.removePinnedPeer(peerId)
} else { } else {
if filters[index].data.pinnedPeers.count < 100 { if !filters[index].data.includePeers.addPinnedPeer(peerId) {
filters[index].data.pinnedPeers.insert(peerId, at: 0)
} else {
result = .limitExceeded(100) result = .limitExceeded(100)
} }
} }
@ -91,7 +89,7 @@ public func getPinnedItemIds(transaction: Transaction, location: TogglePeerChatP
var itemIds: [PinnedItemId] = [] var itemIds: [PinnedItemId] = []
let _ = updateChatListFiltersInteractively(transaction: transaction, { filters in let _ = updateChatListFiltersInteractively(transaction: transaction, { filters in
if let index = filters.firstIndex(where: { $0.id == filterId }) { if let index = filters.firstIndex(where: { $0.id == filterId }) {
itemIds = filters[index].data.pinnedPeers.map { peerId in itemIds = filters[index].data.includePeers.pinnedPeers.map { peerId in
return .peer(peerId) return .peer(peerId)
} }
} }
@ -123,8 +121,8 @@ public func reorderPinnedItemIds(transaction: Transaction, location: TogglePeerC
} }
} }
if filters[index].data.pinnedPeers != peerIds { if filters[index].data.includePeers.pinnedPeers != peerIds {
filters[index].data.pinnedPeers = peerIds filters[index].data.includePeers.reorderPinnedPeers(peerIds)
result = true result = true
} }
} }