mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Update filters
This commit is contained in:
@@ -14,10 +14,11 @@ import ContactsPeerItem
|
||||
import ContextUI
|
||||
import ItemListUI
|
||||
import SearchUI
|
||||
import ChatListSearchItemHeader
|
||||
|
||||
public enum ChatListNodeMode {
|
||||
case chatList
|
||||
case peers(filter: ChatListNodePeersFilter, isSelecting: Bool)
|
||||
case peers(filter: ChatListNodePeersFilter, isSelecting: Bool, additionalCategories: [ChatListNodeAdditionalCategory])
|
||||
}
|
||||
|
||||
struct ChatListNodeListViewTransition {
|
||||
@@ -50,6 +51,7 @@ public final class ChatListNodeInteraction {
|
||||
let peerSelected: (Peer) -> Void
|
||||
let disabledPeerSelected: (Peer) -> Void
|
||||
let togglePeerSelected: (PeerId) -> Void
|
||||
let additionalCategorySelected: (Int) -> Void
|
||||
let messageSelected: (Peer, Message, Bool) -> Void
|
||||
let groupSelected: (PeerGroupId) -> Void
|
||||
let addContact: (String) -> Void
|
||||
@@ -66,11 +68,12 @@ public final class ChatListNodeInteraction {
|
||||
public var searchTextHighightState: String?
|
||||
var highlightedChatLocation: ChatListHighlightedLocation?
|
||||
|
||||
public init(activateSearch: @escaping () -> Void, peerSelected: @escaping (Peer) -> Void, disabledPeerSelected: @escaping (Peer) -> Void, togglePeerSelected: @escaping (PeerId) -> Void, messageSelected: @escaping (Peer, Message, Bool) -> Void, groupSelected: @escaping (PeerGroupId) -> Void, addContact: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, setItemPinned: @escaping (PinnedItemId, Bool) -> Void, setPeerMuted: @escaping (PeerId, Bool) -> Void, deletePeer: @escaping (PeerId) -> Void, updatePeerGrouping: @escaping (PeerId, Bool) -> Void, togglePeerMarkedUnread: @escaping (PeerId, Bool) -> Void, toggleArchivedFolderHiddenByDefault: @escaping () -> Void, activateChatPreview: @escaping (ChatListItem, ASDisplayNode, ContextGesture?) -> Void, present: @escaping (ViewController) -> Void) {
|
||||
public init(activateSearch: @escaping () -> Void, peerSelected: @escaping (Peer) -> Void, disabledPeerSelected: @escaping (Peer) -> Void, togglePeerSelected: @escaping (PeerId) -> Void, additionalCategorySelected: @escaping (Int) -> Void, messageSelected: @escaping (Peer, Message, Bool) -> Void, groupSelected: @escaping (PeerGroupId) -> Void, addContact: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, setItemPinned: @escaping (PinnedItemId, Bool) -> Void, setPeerMuted: @escaping (PeerId, Bool) -> Void, deletePeer: @escaping (PeerId) -> Void, updatePeerGrouping: @escaping (PeerId, Bool) -> Void, togglePeerMarkedUnread: @escaping (PeerId, Bool) -> Void, toggleArchivedFolderHiddenByDefault: @escaping () -> Void, activateChatPreview: @escaping (ChatListItem, ASDisplayNode, ContextGesture?) -> Void, present: @escaping (ViewController) -> Void) {
|
||||
self.activateSearch = activateSearch
|
||||
self.peerSelected = peerSelected
|
||||
self.disabledPeerSelected = disabledPeerSelected
|
||||
self.togglePeerSelected = togglePeerSelected
|
||||
self.additionalCategorySelected = additionalCategorySelected
|
||||
self.messageSelected = messageSelected
|
||||
self.groupSelected = groupSelected
|
||||
self.addContact = addContact
|
||||
@@ -103,12 +106,14 @@ public struct ChatListNodeState: Equatable {
|
||||
public var pendingRemovalPeerIds: Set<PeerId>
|
||||
public var pendingClearHistoryPeerIds: Set<PeerId>
|
||||
public var archiveShouldBeTemporaryRevealed: Bool
|
||||
public var selectedAdditionalCategoryIds: Set<Int>
|
||||
|
||||
public init(presentationData: ChatListPresentationData, editing: Bool, peerIdWithRevealedOptions: PeerId?, selectedPeerIds: Set<PeerId>, peerInputActivities: ChatListNodePeerInputActivities?, pendingRemovalPeerIds: Set<PeerId>, pendingClearHistoryPeerIds: Set<PeerId>, archiveShouldBeTemporaryRevealed: Bool) {
|
||||
public init(presentationData: ChatListPresentationData, editing: Bool, peerIdWithRevealedOptions: PeerId?, selectedPeerIds: Set<PeerId>, selectedAdditionalCategoryIds: Set<Int>, peerInputActivities: ChatListNodePeerInputActivities?, pendingRemovalPeerIds: Set<PeerId>, pendingClearHistoryPeerIds: Set<PeerId>, archiveShouldBeTemporaryRevealed: Bool) {
|
||||
self.presentationData = presentationData
|
||||
self.editing = editing
|
||||
self.peerIdWithRevealedOptions = peerIdWithRevealedOptions
|
||||
self.selectedPeerIds = selectedPeerIds
|
||||
self.selectedAdditionalCategoryIds = selectedAdditionalCategoryIds
|
||||
self.peerInputActivities = peerInputActivities
|
||||
self.pendingRemovalPeerIds = pendingRemovalPeerIds
|
||||
self.pendingClearHistoryPeerIds = pendingClearHistoryPeerIds
|
||||
@@ -128,6 +133,9 @@ public struct ChatListNodeState: Equatable {
|
||||
if lhs.selectedPeerIds != rhs.selectedPeerIds {
|
||||
return false
|
||||
}
|
||||
if lhs.selectedAdditionalCategoryIds != rhs.selectedAdditionalCategoryIds {
|
||||
return false
|
||||
}
|
||||
if lhs.peerInputActivities !== rhs.peerInputActivities {
|
||||
return false
|
||||
}
|
||||
@@ -149,11 +157,22 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL
|
||||
switch entry.entry {
|
||||
case .HeaderEntry:
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListEmptyHeaderItem(), directionHint: entry.directionHint)
|
||||
case let .PeerEntry(index, presentationData, message, combinedReadState, notificationSettings, embeddedState, peer, presence, summaryInfo, editing, hasActiveRevealControls, selected, inputActivities, isAd, hasFailedMessages):
|
||||
case let .AdditionalCategory(_, id, title, image, selected, presentationData):
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListAdditionalCategoryItem(
|
||||
presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings),
|
||||
context: context,
|
||||
title: title,
|
||||
image: image,
|
||||
isSelected: selected,
|
||||
action: {
|
||||
nodeInteraction.additionalCategorySelected(id)
|
||||
}
|
||||
), directionHint: entry.directionHint)
|
||||
case let .PeerEntry(index, presentationData, message, combinedReadState, notificationSettings, embeddedState, peer, presence, summaryInfo, editing, hasActiveRevealControls, selected, inputActivities, isAd, hasFailedMessages, isContact):
|
||||
switch mode {
|
||||
case .chatList:
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListItem(presentationData: presentationData, context: context, peerGroupId: peerGroupId, isInFilter: isInFilter, index: index, content: .peer(message: message, peer: peer, combinedReadState: combinedReadState, notificationSettings: notificationSettings, presence: presence, summaryInfo: summaryInfo, embeddedState: embeddedState, inputActivities: inputActivities, isAd: isAd, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: hasFailedMessages), editing: editing, hasActiveRevealControls: hasActiveRevealControls, selected: selected, header: nil, enableContextActions: true, hiddenOffset: false, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
case let .peers(filter, _):
|
||||
case let .peers(filter, isSelecting, _):
|
||||
let itemPeer = peer.chatMainPeer
|
||||
var chatPeer: Peer?
|
||||
if let peer = peer.peers[peer.peerId] {
|
||||
@@ -217,8 +236,23 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var header: ChatListSearchItemHeader?
|
||||
switch mode {
|
||||
case let .peers(_, _, additionalCategories):
|
||||
if !additionalCategories.isEmpty {
|
||||
header = ChatListSearchItemHeader(type: .chats, theme: presentationData.theme, strings: presentationData.strings, actionTitle: nil, action: nil)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
var status: ContactsPeerItemStatus = .none
|
||||
if isSelecting, let itemPeer = itemPeer {
|
||||
status = .custom(statusStringForPeerType(strings: presentationData.strings, peer: itemPeer, isContact: isContact))
|
||||
}
|
||||
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ContactsPeerItem(presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings), sortOrder: presentationData.nameSortOrder, displayOrder: presentationData.nameDisplayOrder, context: context, peerMode: .generalSearch, peer: .peer(peer: itemPeer, chatPeer: chatPeer), status: .none, enabled: enabled, selection: editing ? .selectable(selected: selected) : .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: nil, action: { _ in
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ContactsPeerItem(presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings), sortOrder: presentationData.nameSortOrder, displayOrder: presentationData.nameDisplayOrder, context: context, peerMode: .generalSearch, peer: .peer(peer: itemPeer, chatPeer: chatPeer), status: status, enabled: enabled, selection: editing ? .selectable(selected: selected) : .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: header, action: { _ in
|
||||
if let chatPeer = chatPeer {
|
||||
nodeInteraction.peerSelected(chatPeer)
|
||||
}
|
||||
@@ -241,11 +275,11 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL
|
||||
private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, isInFilter: Bool, mode: ChatListNodeMode, entries: [ChatListNodeViewTransitionUpdateEntry]) -> [ListViewUpdateItem] {
|
||||
return entries.map { entry -> ListViewUpdateItem in
|
||||
switch entry.entry {
|
||||
case let .PeerEntry(index, presentationData, message, combinedReadState, notificationSettings, embeddedState, peer, presence, summaryInfo, editing, hasActiveRevealControls, selected, inputActivities, isAd, hasFailedMessages):
|
||||
case let .PeerEntry(index, presentationData, message, combinedReadState, notificationSettings, embeddedState, peer, presence, summaryInfo, editing, hasActiveRevealControls, selected, inputActivities, isAd, hasFailedMessages, isContact):
|
||||
switch mode {
|
||||
case .chatList:
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListItem(presentationData: presentationData, context: context, peerGroupId: peerGroupId, isInFilter: isInFilter, index: index, content: .peer(message: message, peer: peer, combinedReadState: combinedReadState, notificationSettings: notificationSettings, presence: presence, summaryInfo: summaryInfo, embeddedState: embeddedState, inputActivities: inputActivities, isAd: isAd, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: hasFailedMessages), editing: editing, hasActiveRevealControls: hasActiveRevealControls, selected: selected, header: nil, enableContextActions: true, hiddenOffset: false, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
case let .peers(filter, _):
|
||||
case let .peers(filter, isSelecting, _):
|
||||
let itemPeer = peer.chatMainPeer
|
||||
var chatPeer: Peer?
|
||||
if let peer = peer.peers[peer.peerId] {
|
||||
@@ -266,7 +300,22 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ContactsPeerItem(presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings), sortOrder: presentationData.nameSortOrder, displayOrder: presentationData.nameDisplayOrder, context: context, peerMode: .generalSearch, peer: .peer(peer: itemPeer, chatPeer: chatPeer), status: .none, enabled: enabled, selection: editing ? .selectable(selected: selected) : .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: nil, action: { _ in
|
||||
var header: ChatListSearchItemHeader?
|
||||
switch mode {
|
||||
case let .peers(_, _, additionalCategories):
|
||||
if !additionalCategories.isEmpty {
|
||||
header = ChatListSearchItemHeader(type: .chats, theme: presentationData.theme, strings: presentationData.strings, actionTitle: nil, action: nil)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
var status: ContactsPeerItemStatus = .none
|
||||
if isSelecting, let itemPeer = itemPeer {
|
||||
status = .custom(statusStringForPeerType(strings: presentationData.strings, peer: itemPeer, isContact: isContact))
|
||||
}
|
||||
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ContactsPeerItem(presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings), sortOrder: presentationData.nameSortOrder, displayOrder: presentationData.nameDisplayOrder, context: context, peerMode: .generalSearch, peer: .peer(peer: itemPeer, chatPeer: chatPeer), status: status, enabled: enabled, selection: editing ? .selectable(selected: selected) : .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: header, action: { _ in
|
||||
if let chatPeer = chatPeer {
|
||||
nodeInteraction.peerSelected(chatPeer)
|
||||
}
|
||||
@@ -284,6 +333,17 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListArchiveInfoItem(theme: presentationData.theme, strings: presentationData.strings), directionHint: entry.directionHint)
|
||||
case .HeaderEntry:
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListEmptyHeaderItem(), directionHint: entry.directionHint)
|
||||
case let .AdditionalCategory(index: _, id, title, image, selected, presentationData):
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListAdditionalCategoryItem(
|
||||
presentationData: ItemListPresentationData(theme: presentationData.theme, fontSize: presentationData.fontSize, strings: presentationData.strings),
|
||||
context: context,
|
||||
title: title,
|
||||
image: image,
|
||||
isSelected: selected,
|
||||
action: {
|
||||
nodeInteraction.additionalCategorySelected(id)
|
||||
}
|
||||
), directionHint: entry.directionHint)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -329,11 +389,6 @@ public enum ChatListNodeEmptyState: Equatable {
|
||||
case empty(isLoading: Bool)
|
||||
}
|
||||
|
||||
enum ChatListNodePaneSwitchAnimationDirection {
|
||||
case left
|
||||
case right
|
||||
}
|
||||
|
||||
public final class ChatListNode: ListView {
|
||||
private let controlsHistoryPreload: Bool
|
||||
private let context: AccountContext
|
||||
@@ -354,6 +409,7 @@ public final class ChatListNode: ListView {
|
||||
|
||||
public var peerSelected: ((Peer, Bool, Bool) -> Void)?
|
||||
public var disabledPeerSelected: ((Peer) -> Void)?
|
||||
public var additionalCategorySelected: ((Int) -> Void)?
|
||||
public var groupSelected: ((PeerGroupId) -> Void)?
|
||||
public var addContact: ((String) -> Void)?
|
||||
public var activateSearch: (() -> Void)?
|
||||
@@ -379,16 +435,13 @@ public final class ChatListNode: ListView {
|
||||
return self.statePromise.get()
|
||||
}
|
||||
|
||||
var paneSwitchAnimation: (ChatListNodePaneSwitchAnimationDirection, ContainedViewLayoutTransition)?
|
||||
private var currentLocation: ChatListNodeLocation?
|
||||
private(set) var chatListFilter: ChatListFilter? {
|
||||
didSet {
|
||||
self.chatListFilterValue.set(.single(self.chatListFilter))
|
||||
|
||||
if self.chatListFilter != oldValue {
|
||||
if let currentLocation = self.currentLocation {
|
||||
self.setChatListLocation(.initial(count: 50, filter: self.chatListFilter))
|
||||
}
|
||||
self.setChatListLocation(.initial(count: 50, filter: self.chatListFilter))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -433,7 +486,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
}
|
||||
|
||||
var isEmptyUpdated: ((ChatListNodeEmptyState, Bool, ChatListNodePaneSwitchAnimationDirection?, ContainedViewLayoutTransition) -> Void)?
|
||||
var isEmptyUpdated: ((ChatListNodeEmptyState, Bool, ContainedViewLayoutTransition) -> Void)?
|
||||
private var currentIsEmptyState: ChatListNodeEmptyState?
|
||||
|
||||
public var addedVisibleChatsWithPeerIds: (([PeerId]) -> Void)?
|
||||
@@ -454,11 +507,11 @@ public final class ChatListNode: ListView {
|
||||
self.mode = mode
|
||||
|
||||
var isSelecting = false
|
||||
if case .peers(_, true) = mode {
|
||||
if case .peers(_, true, _) = mode {
|
||||
isSelecting = true
|
||||
}
|
||||
|
||||
self.currentState = ChatListNodeState(presentationData: ChatListPresentationData(theme: theme, fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, disableAnimations: disableAnimations), editing: isSelecting, peerIdWithRevealedOptions: nil, selectedPeerIds: Set(), peerInputActivities: nil, pendingRemovalPeerIds: Set(), pendingClearHistoryPeerIds: Set(), archiveShouldBeTemporaryRevealed: false)
|
||||
self.currentState = ChatListNodeState(presentationData: ChatListPresentationData(theme: theme, fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, disableAnimations: disableAnimations), editing: isSelecting, peerIdWithRevealedOptions: nil, selectedPeerIds: Set(), selectedAdditionalCategoryIds: Set(), peerInputActivities: nil, pendingRemovalPeerIds: Set(), pendingClearHistoryPeerIds: Set(), archiveShouldBeTemporaryRevealed: false)
|
||||
self.statePromise = ValuePromise(self.currentState, ignoreRepeated: true)
|
||||
|
||||
self.theme = theme
|
||||
@@ -494,6 +547,8 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
return state
|
||||
}
|
||||
}, additionalCategorySelected: { [weak self] id in
|
||||
self?.additionalCategorySelected?(id)
|
||||
}, messageSelected: { [weak self] peer, message, isAd in
|
||||
if let strongSelf = self, let peerSelected = strongSelf.peerSelected {
|
||||
peerSelected(peer, true, isAd)
|
||||
@@ -591,7 +646,7 @@ public final class ChatListNode: ListView {
|
||||
let currentRemovingPeerId = self.currentRemovingPeerId
|
||||
|
||||
let savedMessagesPeer: Signal<Peer?, NoError>
|
||||
if case let .peers(filter, _) = mode, filter.contains(.onlyWriteable) {
|
||||
if case let .peers(filter, _, _) = mode, filter.contains(.onlyWriteable) {
|
||||
savedMessagesPeer = context.account.postbox.loadedPeerWithId(context.account.peerId)
|
||||
|> map(Optional.init)
|
||||
} else {
|
||||
@@ -640,11 +695,11 @@ public final class ChatListNode: ListView {
|
||||
let (rawEntries, isLoading) = chatListNodeEntriesForView(update.view, state: state, savedMessagesPeer: savedMessagesPeer, hideArchivedFolderByDefault: hideArchivedFolderByDefault, displayArchiveIntro: displayArchiveIntro, mode: mode)
|
||||
let entries = rawEntries.filter { entry in
|
||||
switch entry {
|
||||
case let .PeerEntry(_, _, _, _, _, _, peer, _, _, _, _, _, _, _, _):
|
||||
case let .PeerEntry(_, _, _, _, _, _, peer, _, _, _, _, _, _, _, _, _):
|
||||
switch mode {
|
||||
case .chatList:
|
||||
return true
|
||||
case let .peers(filter, _):
|
||||
case let .peers(filter, _, _):
|
||||
guard !filter.contains(.excludeSavedMessages) || peer.peerId != currentPeerId else { return false }
|
||||
guard !filter.contains(.excludeSecretChats) || peer.peerId.namespace != Namespaces.Peer.SecretChat else { return false }
|
||||
guard !filter.contains(.onlyPrivateChats) || peer.peerId.namespace == Namespaces.Peer.CloudUser else { return false }
|
||||
@@ -750,7 +805,7 @@ public final class ChatListNode: ListView {
|
||||
var didIncludeHiddenByDefaultArchive = false
|
||||
if let previous = previousView {
|
||||
for entry in previous.filteredEntries {
|
||||
if case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _) = entry {
|
||||
if case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) = entry {
|
||||
if index.pinningIndex != nil {
|
||||
previousPinnedChats.append(index.messageIndex.id.peerId)
|
||||
}
|
||||
@@ -784,6 +839,9 @@ public final class ChatListNode: ListView {
|
||||
if previousState.selectedPeerIds != state.selectedPeerIds {
|
||||
disableAnimations = false
|
||||
}
|
||||
if previousState.selectedAdditionalCategoryIds != state.selectedAdditionalCategoryIds {
|
||||
disableAnimations = false
|
||||
}
|
||||
if doesIncludeRemovingPeerId != didIncludeRemovingPeerId {
|
||||
disableAnimations = false
|
||||
}
|
||||
@@ -828,10 +886,10 @@ public final class ChatListNode: ListView {
|
||||
let originalView = chatListView.originalView
|
||||
if let range = range.loadedRange {
|
||||
var location: ChatListNodeLocation?
|
||||
if range.firstIndex < 5 && originalView.laterIndex != nil {
|
||||
location = .navigation(index: originalView.entries[originalView.entries.count - 1].index, filter: strongSelf.chatListFilter)
|
||||
} else if range.firstIndex >= 5 && range.lastIndex >= originalView.entries.count - 5 && originalView.earlierIndex != nil {
|
||||
location = .navigation(index: originalView.entries[0].index, filter: strongSelf.chatListFilter)
|
||||
if range.firstIndex < 5, let laterIndex = originalView.laterIndex {
|
||||
location = .navigation(index: laterIndex, filter: strongSelf.chatListFilter)
|
||||
} else if range.firstIndex >= 5, range.lastIndex >= originalView.entries.count - 5, let earlierIndex = originalView.earlierIndex {
|
||||
location = .navigation(index: earlierIndex, filter: strongSelf.chatListFilter)
|
||||
}
|
||||
|
||||
if let location = location, location != strongSelf.currentLocation {
|
||||
@@ -852,7 +910,7 @@ public final class ChatListNode: ListView {
|
||||
continue
|
||||
}
|
||||
switch chatListView.filteredEntries[entryCount - i - 1] {
|
||||
case let .PeerEntry(_, _, _, readState, notificationSettings, _, _, _, _, _, _, _, _, _, _):
|
||||
case let .PeerEntry(_, _, _, readState, notificationSettings, _, _, _, _, _, _, _, _, _, _, _):
|
||||
if let readState = readState {
|
||||
let count = readState.count
|
||||
rawUnreadCount += count
|
||||
@@ -998,7 +1056,7 @@ public final class ChatListNode: ListView {
|
||||
var referenceId: PinnedItemId?
|
||||
var beforeAll = false
|
||||
switch toEntry {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, isAd, _):
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, isAd, _, _):
|
||||
if isAd {
|
||||
beforeAll = true
|
||||
} else {
|
||||
@@ -1010,13 +1068,13 @@ public final class ChatListNode: ListView {
|
||||
break
|
||||
}
|
||||
|
||||
if let _ = fromEntry.sortIndex.pinningIndex {
|
||||
if case let .index(index) = fromEntry.sortIndex, let _ = index.pinningIndex {
|
||||
return strongSelf.context.account.postbox.transaction { transaction -> Bool in
|
||||
var itemIds = transaction.getPinnedItemIds(groupId: groupId)
|
||||
|
||||
var itemId: PinnedItemId?
|
||||
switch fromEntry {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
itemId = .peer(index.messageIndex.id.peerId)
|
||||
/*case let .GroupReferenceEntry(_, _, groupId, _, _, _, _):
|
||||
itemId = .group(groupId)*/
|
||||
@@ -1268,13 +1326,6 @@ public final class ChatListNode: ListView {
|
||||
if let (transition, completion) = self.enqueuedTransition {
|
||||
self.enqueuedTransition = nil
|
||||
|
||||
let paneSwitchCopyView: UIView?
|
||||
if let (direction, transition) = self.paneSwitchAnimation, let copyView = self.view.snapshotContentTree(unhide: false, keepTransform: true) {
|
||||
paneSwitchCopyView = copyView
|
||||
} else {
|
||||
paneSwitchCopyView = nil
|
||||
}
|
||||
|
||||
let completion: (ListViewDisplayedItemRange) -> Void = { [weak self] visibleRange in
|
||||
if let strongSelf = self {
|
||||
strongSelf.chatListView = transition.chatListView
|
||||
@@ -1283,7 +1334,7 @@ public final class ChatListNode: ListView {
|
||||
if case .chatList = strongSelf.mode {
|
||||
let entryCount = transition.chatListView.filteredEntries.count
|
||||
if entryCount >= 1 {
|
||||
if transition.chatListView.filteredEntries[entryCount - 1].sortIndex.pinningIndex != nil {
|
||||
if case let .index(index) = transition.chatListView.filteredEntries[entryCount - 1].sortIndex, index.pinningIndex != nil {
|
||||
pinnedOverscroll = true
|
||||
}
|
||||
}
|
||||
@@ -1339,11 +1390,11 @@ public final class ChatListNode: ListView {
|
||||
var containsChats = false
|
||||
loop: for entry in transition.chatListView.filteredEntries {
|
||||
switch entry {
|
||||
case .GroupReferenceEntry, .HoleEntry, .PeerEntry:
|
||||
containsChats = true
|
||||
break loop
|
||||
case .ArchiveIntro, .HeaderEntry:
|
||||
break
|
||||
case .GroupReferenceEntry, .HoleEntry, .PeerEntry:
|
||||
containsChats = true
|
||||
break loop
|
||||
case .ArchiveIntro, .HeaderEntry, .AdditionalCategory:
|
||||
break
|
||||
}
|
||||
}
|
||||
isEmptyState = .notEmpty(containsChats: containsChats)
|
||||
@@ -1364,33 +1415,14 @@ public final class ChatListNode: ListView {
|
||||
strongSelf.addedVisibleChatsWithPeerIds?(insertedPeerIds)
|
||||
}
|
||||
|
||||
var isEmptyUpdate: (ChatListNodePaneSwitchAnimationDirection?, ContainedViewLayoutTransition) = (nil, .immediate)
|
||||
if let (direction, transition) = strongSelf.paneSwitchAnimation {
|
||||
strongSelf.paneSwitchAnimation = nil
|
||||
if let copyView = paneSwitchCopyView {
|
||||
let offset: CGFloat
|
||||
switch direction {
|
||||
case .left:
|
||||
offset = -strongSelf.bounds.width
|
||||
case .right:
|
||||
offset = strongSelf.bounds.width
|
||||
}
|
||||
copyView.frame = strongSelf.bounds.offsetBy(dx: offset, dy: 0.0)
|
||||
strongSelf.view.addSubview(copyView)
|
||||
transition.animateHorizontalOffsetAdditive(node: strongSelf, offset: offset, completion: { [weak copyView] in
|
||||
copyView?.removeFromSuperview()
|
||||
})
|
||||
isEmptyUpdate = (direction, transition)
|
||||
}
|
||||
} else {
|
||||
if transition.options.contains(.AnimateInsertion) {
|
||||
isEmptyUpdate.1 = .animated(duration: 0.25, curve: .easeInOut)
|
||||
}
|
||||
var isEmptyUpdate: ContainedViewLayoutTransition = .immediate
|
||||
if transition.options.contains(.AnimateInsertion) {
|
||||
isEmptyUpdate = .animated(duration: 0.25, curve: .easeInOut)
|
||||
}
|
||||
|
||||
if strongSelf.currentIsEmptyState != isEmptyState {
|
||||
strongSelf.currentIsEmptyState = isEmptyState
|
||||
strongSelf.isEmptyUpdated?(isEmptyState, transition.chatListView.filter != nil, isEmptyUpdate.0, isEmptyUpdate.1)
|
||||
strongSelf.isEmptyUpdated?(isEmptyState, transition.chatListView.filter != nil, isEmptyUpdate)
|
||||
}
|
||||
|
||||
if !strongSelf.hasUpdatedAppliedChatListFilterValueOnce || transition.chatListView.filter != strongSelf.currentAppliedChatListFilterValue {
|
||||
@@ -1429,7 +1461,7 @@ public final class ChatListNode: ListView {
|
||||
|
||||
var isNavigationHidden: Bool {
|
||||
switch self.visibleContentOffset() {
|
||||
case let .known(value) where abs(value) < navigationBarSearchContentHeight:
|
||||
case let .known(value) where abs(value) < navigationBarSearchContentHeight - 1.0:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
@@ -1568,7 +1600,7 @@ public final class ChatListNode: ListView {
|
||||
continue
|
||||
}
|
||||
switch chatListView.filteredEntries[entryCount - i - 1] {
|
||||
case let .PeerEntry(index, _, _, _, _, _, peer, _, _, _, _, _, _, _, _):
|
||||
case let .PeerEntry(index, _, _, _, _, _, peer, _, _, _, _, _, _, _, _, _):
|
||||
if interaction.highlightedChatLocation?.location == ChatLocation.peer(peer.peerId) {
|
||||
current = (index, peer.peer!, entryCount - i - 1)
|
||||
break outer
|
||||
@@ -1614,10 +1646,10 @@ public final class ChatListNode: ListView {
|
||||
case .previous(unread: false), .next(unread: false):
|
||||
var target: (ChatListIndex, Peer)? = nil
|
||||
if let current = current, entryCount > 1 {
|
||||
if current.2 > 0, case let .PeerEntry(index, _, _, _, _, _, peer, _, _, _, _, _, _, _, _) = chatListView.filteredEntries[current.2 - 1] {
|
||||
if current.2 > 0, case let .PeerEntry(index, _, _, _, _, _, peer, _, _, _, _, _, _, _, _, _) = chatListView.filteredEntries[current.2 - 1] {
|
||||
next = (index, peer.peer!)
|
||||
}
|
||||
if current.2 <= entryCount - 2, case let .PeerEntry(index, _, _, _, _, _, peer, _, _, _, _, _, _, _, _) = chatListView.filteredEntries[current.2 + 1] {
|
||||
if current.2 <= entryCount - 2, case let .PeerEntry(index, _, _, _, _, _, peer, _, _, _, _, _, _, _, _, _) = chatListView.filteredEntries[current.2 + 1] {
|
||||
previous = (index, peer.peer!)
|
||||
}
|
||||
if case .previous = option {
|
||||
@@ -1626,7 +1658,7 @@ public final class ChatListNode: ListView {
|
||||
target = next
|
||||
}
|
||||
} else if entryCount > 0 {
|
||||
if case let .PeerEntry(index, _, _, _, _, _, peer, _, _, _, _, _, _, _, _) = chatListView.filteredEntries[entryCount - 1] {
|
||||
if case let .PeerEntry(index, _, _, _, _, _, peer, _, _, _, _, _, _, _, _, _) = chatListView.filteredEntries[entryCount - 1] {
|
||||
target = (index, peer.peer!)
|
||||
}
|
||||
}
|
||||
@@ -1659,7 +1691,7 @@ public final class ChatListNode: ListView {
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { update in
|
||||
let entries = update.view.entries
|
||||
if entries.count > index, case let .MessageEntry(index, _, _, _, _, renderedPeer, _, _, _) = entries[10 - index - 1] {
|
||||
if entries.count > index, case let .MessageEntry(index, _, _, _, _, renderedPeer, _, _, _, _) = entries[10 - index - 1] {
|
||||
let location: ChatListNodeLocation = .scroll(index: index, sourceIndex: .absoluteLowerBound, scrollPosition: .center(.top), animated: true, filter: filter)
|
||||
self.setChatListLocation(location)
|
||||
self.peerSelected?(renderedPeer.peer!, false, false)
|
||||
@@ -1702,7 +1734,7 @@ public final class ChatListNode: ListView {
|
||||
continue
|
||||
}
|
||||
switch chatListView.filteredEntries[entryCount - i - 1] {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
return index
|
||||
default:
|
||||
break
|
||||
@@ -1712,3 +1744,31 @@ public final class ChatListNode: ListView {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
private func statusStringForPeerType(strings: PresentationStrings, peer: Peer, isContact: Bool) -> String {
|
||||
if let user = peer as? TelegramUser {
|
||||
if user.botInfo != nil || user.flags.contains(.isSupport) {
|
||||
return "bot"
|
||||
} else if isContact {
|
||||
return "contact"
|
||||
} else {
|
||||
return "user"
|
||||
}
|
||||
} else if peer is TelegramSecretChat {
|
||||
if isContact {
|
||||
return "contact"
|
||||
} else {
|
||||
return "user"
|
||||
}
|
||||
} else if peer is TelegramGroup {
|
||||
return "group"
|
||||
} else if let channel = peer as? TelegramChannel {
|
||||
if case .group = channel.info {
|
||||
return "group"
|
||||
} else {
|
||||
return "channel"
|
||||
}
|
||||
}
|
||||
return "user"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user