mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-26 07:21:54 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
e66140094e
@ -40,7 +40,7 @@ func archiveContextMenuItems(context: AccountContext, groupId: PeerGroupId, chat
|
||||
}
|
||||
|
||||
enum ChatContextMenuSource {
|
||||
case chatList(isFilter: Bool)
|
||||
case chatList(filter: ChatListFilter?)
|
||||
case search(ChatListSearchContextActionSource)
|
||||
}
|
||||
|
||||
@ -146,10 +146,16 @@ func chatContextMenuItems(context: AccountContext, peerId: PeerId, source: ChatC
|
||||
})))
|
||||
}
|
||||
|
||||
if case .chatList(false) = source {
|
||||
if case let .chatList(filter) = source {
|
||||
let isPinned = index.pinningIndex != nil
|
||||
items.append(.action(ContextMenuActionItem(text: isPinned ? strings.ChatList_Context_Unpin : strings.ChatList_Context_Pin, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isPinned ? "Chat/Context Menu/Unpin" : "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
let _ = (toggleItemPinned(postbox: context.account.postbox, groupId: group, itemId: .peer(peerId))
|
||||
let location: TogglePeerChatPinnedLocation
|
||||
if let filter = filter {
|
||||
location = .filter(filter.id)
|
||||
} else {
|
||||
location = .group(group)
|
||||
}
|
||||
let _ = (toggleItemPinned(postbox: context.account.postbox, location: location, itemId: .peer(peerId))
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
switch result {
|
||||
case .done:
|
||||
|
@ -923,7 +923,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
|
||||
case let .peer(peer):
|
||||
let chatController = strongSelf.context.sharedContext.makeChatController(context: strongSelf.context, chatLocation: .peer(peer.peer.peerId), subject: nil, botStart: nil, mode: .standard(previewing: true))
|
||||
chatController.canReadHistory.set(false)
|
||||
let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)), items: chatContextMenuItems(context: strongSelf.context, peerId: peer.peer.peerId, source: .chatList(isFilter: strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter != nil), chatListController: strongSelf), reactionItems: [], gesture: gesture)
|
||||
let contextController = ContextController(account: strongSelf.context.account, presentationData: strongSelf.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node, navigationController: strongSelf.navigationController as? NavigationController)), items: chatContextMenuItems(context: strongSelf.context, peerId: peer.peer.peerId, source: .chatList(filter: strongSelf.chatListDisplayNode.containerNode.currentItemNode.chatListFilter), chatListController: strongSelf), reactionItems: [], gesture: gesture)
|
||||
strongSelf.presentInGlobalOverlay(contextController)
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ private final class ChatListShimmerNode: ASDisplayNode {
|
||||
}, present: { _ in })
|
||||
|
||||
let items = (0 ..< 2).map { _ -> ChatListItem in
|
||||
return ChatListItem(presentationData: chatListPresentationData, context: context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: 0, messageIndex: MessageIndex(id: MessageId(peerId: peer1.id, namespace: 0, id: 0), timestamp: timestamp1)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer1.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp1, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer1, text: "Text", attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []), peer: RenderedPeer(peer: peer1), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 0, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction)
|
||||
return ChatListItem(presentationData: chatListPresentationData, context: context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: 0, messageIndex: MessageIndex(id: MessageId(peerId: peer1.id, namespace: 0, id: 0), timestamp: timestamp1)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer1.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp1, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer1, text: "Text", attributes: [], media: [], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: []), peer: RenderedPeer(peer: peer1), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 0, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction)
|
||||
}
|
||||
|
||||
var itemNodes: [ChatListItemNode] = []
|
||||
|
@ -740,7 +740,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
var state = f(current)
|
||||
if !state.changedName {
|
||||
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))
|
||||
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 ?? []))
|
||||
switch chatListFilterType(filter) {
|
||||
case .generic:
|
||||
state.name = initialName
|
||||
@ -781,7 +781,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
},
|
||||
openAddIncludePeer: {
|
||||
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))
|
||||
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 ?? []))
|
||||
|
||||
let controller = internalChatListFilterAddChatsController(context: context, filter: filter, applyAutomatically: false, updated: { filter in
|
||||
skipStateAnimation = true
|
||||
@ -797,7 +797,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
},
|
||||
openAddExcludePeer: {
|
||||
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))
|
||||
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 ?? []))
|
||||
|
||||
let controller = internalChatListFilterExcludeChatsController(context: context, filter: filter, applyAutomatically: false, updated: { filter in
|
||||
skipStateAnimation = true
|
||||
@ -918,7 +918,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
var attemptNavigationImpl: (() -> Bool)?
|
||||
var applyImpl: (() -> Void)? = {
|
||||
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))
|
||||
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
|
||||
var preset = preset
|
||||
if currentPreset == nil {
|
||||
@ -1013,7 +1013,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
||||
attemptNavigationImpl = {
|
||||
let state = stateValue.with { $0 }
|
||||
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))
|
||||
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))
|
||||
if currentPreset != filter {
|
||||
displaySaveAlert()
|
||||
return false
|
||||
|
@ -484,7 +484,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
||||
}
|
||||
})
|
||||
case let .message(message, peer, readState, presentationData):
|
||||
return ChatListItem(presentationData: presentationData, context: context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: message.index), content: .peer(message: message, peer: peer, combinedReadState: readState, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: true, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: enableHeaders ? ChatListSearchItemHeader(type: .messages, theme: presentationData.theme, strings: presentationData.strings, actionTitle: nil, action: nil) : nil, enableContextActions: false, hiddenOffset: false, interaction: interaction)
|
||||
return ChatListItem(presentationData: presentationData, context: context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: message.index), content: .peer(message: message, peer: peer, combinedReadState: readState, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: true, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: enableHeaders ? ChatListSearchItemHeader(type: .messages, theme: presentationData.theme, strings: presentationData.strings, actionTitle: nil, action: nil) : nil, enableContextActions: false, hiddenOffset: false, interaction: interaction)
|
||||
case let .addContact(phoneNumber, theme, strings):
|
||||
return ContactsAddItem(theme: theme, strings: strings, phoneNumber: phoneNumber, header: ChatListSearchItemHeader(type: .phoneNumber, theme: theme, strings: strings, actionTitle: nil, action: nil), action: {
|
||||
interaction.addContact(phoneNumber)
|
||||
|
@ -37,7 +37,7 @@ public class ChatListItem: ListViewItem, ChatListSearchItemNeighbour {
|
||||
let presentationData: ChatListPresentationData
|
||||
let context: AccountContext
|
||||
let peerGroupId: PeerGroupId
|
||||
let isInFilter: Bool
|
||||
let filterData: ChatListItemFilterData?
|
||||
let index: ChatListIndex
|
||||
public let content: ChatListItemContent
|
||||
let editing: Bool
|
||||
@ -59,10 +59,10 @@ public class ChatListItem: ListViewItem, ChatListSearchItemNeighbour {
|
||||
return self.index.pinningIndex != nil
|
||||
}
|
||||
|
||||
public init(presentationData: ChatListPresentationData, context: AccountContext, peerGroupId: PeerGroupId, isInFilter: Bool, index: ChatListIndex, content: ChatListItemContent, editing: Bool, hasActiveRevealControls: Bool, selected: Bool, header: ListViewItemHeader?, enableContextActions: Bool, hiddenOffset: Bool, interaction: ChatListNodeInteraction) {
|
||||
public init(presentationData: ChatListPresentationData, context: AccountContext, peerGroupId: PeerGroupId, filterData: ChatListItemFilterData?, index: ChatListIndex, content: ChatListItemContent, editing: Bool, hasActiveRevealControls: Bool, selected: Bool, header: ListViewItemHeader?, enableContextActions: Bool, hiddenOffset: Bool, interaction: ChatListNodeInteraction) {
|
||||
self.presentationData = presentationData
|
||||
self.peerGroupId = peerGroupId
|
||||
self.isInFilter = isInFilter
|
||||
self.filterData = filterData
|
||||
self.context = context
|
||||
self.index = index
|
||||
self.content = content
|
||||
@ -204,7 +204,15 @@ private func canArchivePeer(id: PeerId, accountPeerId: PeerId) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
private func revealOptions(strings: PresentationStrings, theme: PresentationTheme, isPinned: Bool, isMuted: Bool?, groupId: PeerGroupId, peerId: PeerId, accountPeerId: PeerId, canDelete: Bool, isEditing: Bool, isInFilter: Bool) -> [ItemListRevealOption] {
|
||||
public struct ChatListItemFilterData: Equatable {
|
||||
public var excludesArchived: Bool
|
||||
|
||||
public init(excludesArchived: Bool) {
|
||||
self.excludesArchived = excludesArchived
|
||||
}
|
||||
}
|
||||
|
||||
private func revealOptions(strings: PresentationStrings, theme: PresentationTheme, isPinned: Bool, isMuted: Bool?, groupId: PeerGroupId, peerId: PeerId, accountPeerId: PeerId, canDelete: Bool, isEditing: Bool, filterData: ChatListItemFilterData?) -> [ItemListRevealOption] {
|
||||
var options: [ItemListRevealOption] = []
|
||||
if !isEditing {
|
||||
if case .group = groupId {
|
||||
@ -226,7 +234,7 @@ private func revealOptions(strings: PresentationStrings, theme: PresentationThem
|
||||
if canDelete {
|
||||
options.append(ItemListRevealOption(key: RevealOptionKey.delete.rawValue, title: strings.Common_Delete, icon: deleteIcon, color: theme.list.itemDisclosureActions.destructive.fillColor, textColor: theme.list.itemDisclosureActions.destructive.foregroundColor))
|
||||
}
|
||||
if !isEditing && !isInFilter {
|
||||
if !isEditing && filterData == nil {
|
||||
if case .root = groupId {
|
||||
if canArchivePeer(id: peerId, accountPeerId: accountPeerId) {
|
||||
options.append(ItemListRevealOption(key: RevealOptionKey.archive.rawValue, title: strings.ChatList_ArchiveAction, icon: archiveIcon, color: theme.list.itemDisclosureActions.inactive.fillColor, textColor: theme.list.itemDisclosureActions.inactive.foregroundColor))
|
||||
@ -250,7 +258,7 @@ private func groupReferenceRevealOptions(strings: PresentationStrings, theme: Pr
|
||||
return options
|
||||
}
|
||||
|
||||
private func leftRevealOptions(strings: PresentationStrings, theme: PresentationTheme, isUnread: Bool, isEditing: Bool, isPinned: Bool, isSavedMessages: Bool, groupId: PeerGroupId, isInFilter: Bool) -> [ItemListRevealOption] {
|
||||
private func leftRevealOptions(strings: PresentationStrings, theme: PresentationTheme, isUnread: Bool, isEditing: Bool, isPinned: Bool, isSavedMessages: Bool, groupId: PeerGroupId, filterData: ChatListItemFilterData?) -> [ItemListRevealOption] {
|
||||
if case .group = groupId {
|
||||
return []
|
||||
}
|
||||
@ -260,7 +268,7 @@ private func leftRevealOptions(strings: PresentationStrings, theme: Presentation
|
||||
} else {
|
||||
options.append(ItemListRevealOption(key: RevealOptionKey.toggleMarkedUnread.rawValue, title: strings.DialogList_Unread, icon: unreadIcon, color: theme.list.itemDisclosureActions.accent.fillColor, textColor: theme.list.itemDisclosureActions.accent.foregroundColor))
|
||||
}
|
||||
if !isEditing && !isInFilter {
|
||||
if !isEditing {
|
||||
if isPinned {
|
||||
options.append(ItemListRevealOption(key: RevealOptionKey.unpin.rawValue, title: strings.DialogList_Unpin, icon: unpinIcon, color: theme.list.itemDisclosureActions.constructive.fillColor, textColor: theme.list.itemDisclosureActions.constructive.foregroundColor))
|
||||
} else {
|
||||
@ -1169,9 +1177,9 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
let isPinned = item.index.pinningIndex != nil
|
||||
|
||||
if item.enableContextActions && !isAd {
|
||||
peerRevealOptions = revealOptions(strings: item.presentationData.strings, theme: item.presentationData.theme, isPinned: isPinned, isMuted: item.context.account.peerId != item.index.messageIndex.id.peerId ? (currentMutedIconImage != nil) : nil, groupId: item.peerGroupId, peerId: renderedPeer.peerId, accountPeerId: item.context.account.peerId, canDelete: true, isEditing: item.editing, isInFilter: item.isInFilter)
|
||||
peerRevealOptions = revealOptions(strings: item.presentationData.strings, theme: item.presentationData.theme, isPinned: isPinned, isMuted: item.context.account.peerId != item.index.messageIndex.id.peerId ? (currentMutedIconImage != nil) : nil, groupId: item.peerGroupId, peerId: renderedPeer.peerId, accountPeerId: item.context.account.peerId, canDelete: true, isEditing: item.editing, filterData: item.filterData)
|
||||
if case let .chat(itemPeer) = contentPeer {
|
||||
peerLeftRevealOptions = leftRevealOptions(strings: item.presentationData.strings, theme: item.presentationData.theme, isUnread: unreadCount.unread, isEditing: item.editing, isPinned: isPinned, isSavedMessages: itemPeer.peerId == item.context.account.peerId, groupId: item.peerGroupId, isInFilter: item.isInFilter)
|
||||
peerLeftRevealOptions = leftRevealOptions(strings: item.presentationData.strings, theme: item.presentationData.theme, isUnread: unreadCount.unread, isEditing: item.editing, isPinned: isPinned, isSavedMessages: itemPeer.peerId == item.context.account.peerId, groupId: item.peerGroupId, filterData: item.filterData)
|
||||
} else {
|
||||
peerLeftRevealOptions = []
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ public struct ChatListNodeState: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, isInFilter: Bool, mode: ChatListNodeMode, entries: [ChatListNodeViewTransitionInsertEntry]) -> [ListViewInsertItem] {
|
||||
private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, filterData: ChatListItemFilterData?, mode: ChatListNodeMode, entries: [ChatListNodeViewTransitionInsertEntry]) -> [ListViewInsertItem] {
|
||||
return entries.map { entry -> ListViewInsertItem in
|
||||
switch entry.entry {
|
||||
case .HeaderEntry:
|
||||
@ -172,7 +172,7 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL
|
||||
case let .PeerEntry(index, presentationData, message, combinedReadState, isRemovedFromTotalUnreadCount, 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, isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount, 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)
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListItem(presentationData: presentationData, context: context, peerGroupId: peerGroupId, filterData: filterData, index: index, content: .peer(message: message, peer: peer, combinedReadState: combinedReadState, isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount, 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, isSelecting, _):
|
||||
let itemPeer = peer.chatMainPeer
|
||||
var chatPeer: Peer?
|
||||
@ -266,20 +266,20 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL
|
||||
case let .HoleEntry(_, theme):
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListHoleItem(theme: theme), directionHint: entry.directionHint)
|
||||
case let .GroupReferenceEntry(index, presentationData, groupId, peers, message, editing, unreadState, revealed, hiddenByDefault):
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListItem(presentationData: presentationData, context: context, peerGroupId: peerGroupId, isInFilter: isInFilter, index: index, content: .groupReference(groupId: groupId, peers: peers, message: message, unreadState: unreadState, hiddenByDefault: hiddenByDefault), editing: editing, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: true, hiddenOffset: hiddenByDefault && !revealed, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListItem(presentationData: presentationData, context: context, peerGroupId: peerGroupId, filterData: filterData, index: index, content: .groupReference(groupId: groupId, peers: peers, message: message, unreadState: unreadState, hiddenByDefault: hiddenByDefault), editing: editing, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: true, hiddenOffset: hiddenByDefault && !revealed, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
case let .ArchiveIntro(presentationData):
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListArchiveInfoItem(theme: presentationData.theme, strings: presentationData.strings), directionHint: entry.directionHint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, isInFilter: Bool, mode: ChatListNodeMode, entries: [ChatListNodeViewTransitionUpdateEntry]) -> [ListViewUpdateItem] {
|
||||
private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, filterData: ChatListItemFilterData?, mode: ChatListNodeMode, entries: [ChatListNodeViewTransitionUpdateEntry]) -> [ListViewUpdateItem] {
|
||||
return entries.map { entry -> ListViewUpdateItem in
|
||||
switch entry.entry {
|
||||
case let .PeerEntry(index, presentationData, message, combinedReadState, isRemovedFromTotalUnreadCount, 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, isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount, 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)
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListItem(presentationData: presentationData, context: context, peerGroupId: peerGroupId, filterData: filterData, index: index, content: .peer(message: message, peer: peer, combinedReadState: combinedReadState, isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount, 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, isSelecting, _):
|
||||
let itemPeer = peer.chatMainPeer
|
||||
var chatPeer: Peer?
|
||||
@ -329,7 +329,7 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL
|
||||
case let .HoleEntry(_, theme):
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListHoleItem(theme: theme), directionHint: entry.directionHint)
|
||||
case let .GroupReferenceEntry(index, presentationData, groupId, peers, message, editing, unreadState, revealed, hiddenByDefault):
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListItem(presentationData: presentationData, context: context, peerGroupId: peerGroupId, isInFilter: isInFilter, index: index, content: .groupReference(groupId: groupId, peers: peers, message: message, unreadState: unreadState, hiddenByDefault: hiddenByDefault), editing: editing, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: true, hiddenOffset: hiddenByDefault && !revealed, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListItem(presentationData: presentationData, context: context, peerGroupId: peerGroupId, filterData: filterData, index: index, content: .groupReference(groupId: groupId, peers: peers, message: message, unreadState: unreadState, hiddenByDefault: hiddenByDefault), editing: editing, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: true, hiddenOffset: hiddenByDefault && !revealed, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
case let .ArchiveIntro(presentationData):
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListArchiveInfoItem(theme: presentationData.theme, strings: presentationData.strings), directionHint: entry.directionHint)
|
||||
case .HeaderEntry:
|
||||
@ -349,8 +349,8 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL
|
||||
}
|
||||
}
|
||||
|
||||
private func mappedChatListNodeViewListTransition(context: AccountContext, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, isInFilter: Bool, mode: ChatListNodeMode, transition: ChatListNodeViewTransition) -> ChatListNodeListViewTransition {
|
||||
return ChatListNodeListViewTransition(chatListView: transition.chatListView, deleteItems: transition.deleteItems, insertItems: mappedInsertEntries(context: context, nodeInteraction: nodeInteraction, peerGroupId: peerGroupId, isInFilter: isInFilter, mode: mode, entries: transition.insertEntries), updateItems: mappedUpdateEntries(context: context, nodeInteraction: nodeInteraction, peerGroupId: peerGroupId, isInFilter: isInFilter, mode: mode, entries: transition.updateEntries), options: transition.options, scrollToItem: transition.scrollToItem, stationaryItemRange: transition.stationaryItemRange, adjustScrollToFirstItem: transition.adjustScrollToFirstItem, animateCrossfade: transition.animateCrossfade)
|
||||
private func mappedChatListNodeViewListTransition(context: AccountContext, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, filterData: ChatListItemFilterData?, mode: ChatListNodeMode, transition: ChatListNodeViewTransition) -> ChatListNodeListViewTransition {
|
||||
return ChatListNodeListViewTransition(chatListView: transition.chatListView, deleteItems: transition.deleteItems, insertItems: mappedInsertEntries(context: context, nodeInteraction: nodeInteraction, peerGroupId: peerGroupId, filterData: filterData, mode: mode, entries: transition.insertEntries), updateItems: mappedUpdateEntries(context: context, nodeInteraction: nodeInteraction, peerGroupId: peerGroupId, filterData: filterData, mode: mode, entries: transition.updateEntries), options: transition.options, scrollToItem: transition.scrollToItem, stationaryItemRange: transition.stationaryItemRange, adjustScrollToFirstItem: transition.adjustScrollToFirstItem, animateCrossfade: transition.animateCrossfade)
|
||||
}
|
||||
|
||||
private final class ChatListOpaqueTransactionState {
|
||||
@ -560,7 +560,13 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
}
|
||||
}, setItemPinned: { [weak self] itemId, _ in
|
||||
let _ = (toggleItemPinned(postbox: context.account.postbox, groupId: groupId, itemId: itemId)
|
||||
let location: TogglePeerChatPinnedLocation
|
||||
if let chatListFilter = chatListFilter {
|
||||
location = .filter(chatListFilter.id)
|
||||
} else {
|
||||
location = .group(groupId)
|
||||
}
|
||||
let _ = (toggleItemPinned(postbox: context.account.postbox, location: location, itemId: itemId)
|
||||
|> deliverOnMainQueue).start(next: { result in
|
||||
if let strongSelf = self {
|
||||
switch result {
|
||||
@ -856,10 +862,12 @@ public final class ChatListNode: ListView {
|
||||
updatedScrollPosition = nil
|
||||
}
|
||||
|
||||
let isInFilter = filter != nil
|
||||
let filterData = filter.flatMap { filter -> ChatListItemFilterData in
|
||||
return ChatListItemFilterData(excludesArchived: filter.data.excludeArchived)
|
||||
}
|
||||
|
||||
return preparedChatListNodeViewTransition(from: previousView, to: processedView, reason: reason, previewing: previewing, disableAnimations: disableAnimations, account: context.account, scrollPosition: updatedScrollPosition, searchMode: searchMode)
|
||||
|> map({ mappedChatListNodeViewListTransition(context: context, nodeInteraction: nodeInteraction, peerGroupId: groupId, isInFilter: isInFilter, mode: mode, transition: $0) })
|
||||
|> map({ mappedChatListNodeViewListTransition(context: context, nodeInteraction: nodeInteraction, peerGroupId: groupId, filterData: filterData, mode: mode, transition: $0) })
|
||||
|> runOn(prepareOnMainQueue ? Queue.mainQueue() : viewProcessingQueue)
|
||||
}
|
||||
|
||||
@ -1033,30 +1041,33 @@ public final class ChatListNode: ListView {
|
||||
var referenceId: PinnedItemId?
|
||||
var beforeAll = false
|
||||
switch toEntry {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, isAd, _, _):
|
||||
if isAd {
|
||||
beforeAll = true
|
||||
} else {
|
||||
referenceId = .peer(index.messageIndex.id.peerId)
|
||||
}
|
||||
/*case let .GroupReferenceEntry(_, _, groupId, _, _, _, _):
|
||||
referenceId = .group(groupId)*/
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, isAd, _, _):
|
||||
if isAd {
|
||||
beforeAll = true
|
||||
} else {
|
||||
referenceId = .peer(index.messageIndex.id.peerId)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
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)
|
||||
let location: TogglePeerChatPinnedLocation
|
||||
if let chatListFilter = chatListFilter {
|
||||
location = .filter(chatListFilter.id)
|
||||
} else {
|
||||
location = .group(groupId)
|
||||
}
|
||||
|
||||
var itemIds = getPinnedItemIds(transaction: transaction, location: location)
|
||||
|
||||
var itemId: PinnedItemId?
|
||||
switch fromEntry {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
itemId = .peer(index.messageIndex.id.peerId)
|
||||
/*case let .GroupReferenceEntry(_, _, groupId, _, _, _, _):
|
||||
itemId = .group(groupId)*/
|
||||
default:
|
||||
break
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
itemId = .peer(index.messageIndex.id.peerId)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if let itemId = itemId {
|
||||
@ -1082,7 +1093,7 @@ public final class ChatListNode: ListView {
|
||||
} else {
|
||||
itemIds.append(itemId)
|
||||
}
|
||||
return reorderPinnedItemIds(transaction: transaction, groupId: groupId, itemIds: itemIds)
|
||||
return reorderPinnedItemIds(transaction: transaction, location: location, itemIds: itemIds)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
|
@ -30,8 +30,14 @@ struct ChatListNodeViewUpdate {
|
||||
}
|
||||
|
||||
func chatListFilterPredicate(filter: ChatListFilterData) -> ChatListFilterPredicate {
|
||||
let includePeers = Set(filter.includePeers)
|
||||
let excludePeers = Set(filter.excludePeers)
|
||||
var includePeers = Set(filter.includePeers)
|
||||
var excludePeers = Set(filter.excludePeers)
|
||||
|
||||
if !filter.pinnedPeers.isEmpty {
|
||||
includePeers.subtract(filter.pinnedPeers)
|
||||
excludePeers.subtract(filter.pinnedPeers)
|
||||
}
|
||||
|
||||
var includeAdditionalPeerGroupIds: [PeerGroupId] = []
|
||||
if !filter.excludeArchived {
|
||||
includeAdditionalPeerGroupIds.append(Namespaces.PeerGroup.archive)
|
||||
@ -41,7 +47,7 @@ func chatListFilterPredicate(filter: ChatListFilterData) -> ChatListFilterPredic
|
||||
if filter.excludeRead {
|
||||
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, messageTagSummary: messageTagSummary, includeAdditionalPeerGroupIds: includeAdditionalPeerGroupIds, include: { peer, isMuted, isUnread, isContact, messageTagSummaryResult in
|
||||
return ChatListFilterPredicate(includePeerIds: includePeers, excludePeerIds: excludePeers, pinnedPeerIds: filter.pinnedPeers, messageTagSummary: messageTagSummary, includeAdditionalPeerGroupIds: includeAdditionalPeerGroupIds, include: { peer, isMuted, isUnread, isContact, messageTagSummaryResult in
|
||||
if filter.excludeRead {
|
||||
var effectiveUnread = isUnread
|
||||
if let messageTagSummaryResult = messageTagSummaryResult, messageTagSummaryResult {
|
||||
|
@ -188,9 +188,23 @@ func preparedChatListNodeViewTransition(from fromView: ChatListNodeView?, to toV
|
||||
}
|
||||
}
|
||||
} else if fromView.filteredEntries.isEmpty || fromView.filter != toView.filter {
|
||||
options.remove(.AnimateInsertion)
|
||||
options.remove(.AnimateAlpha)
|
||||
fromEmptyView = true
|
||||
var updateEmpty = true
|
||||
if !fromView.filteredEntries.isEmpty, let fromFilter = fromView.filter, let toFilter = toView.filter, fromFilter.data.pinnedPeers != toFilter.data.pinnedPeers {
|
||||
var fromData = fromFilter.data
|
||||
var toData = toFilter.data
|
||||
fromData.pinnedPeers = []
|
||||
toData.pinnedPeers = []
|
||||
if fromData == toData {
|
||||
options.insert(.AnimateInsertion)
|
||||
updateEmpty = false
|
||||
}
|
||||
}
|
||||
|
||||
if updateEmpty {
|
||||
options.remove(.AnimateInsertion)
|
||||
options.remove(.AnimateAlpha)
|
||||
fromEmptyView = true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fromEmptyView = true
|
||||
|
@ -174,6 +174,13 @@ open class ItemListRevealOptionsItemNode: ListViewItemNode, UIGestureRecognizerD
|
||||
}
|
||||
}
|
||||
|
||||
open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
/*if gestureRecognizer === self.recognizer && otherGestureRecognizer is InteractiveTransitionGestureRecognizer {
|
||||
return true
|
||||
}*/
|
||||
return false
|
||||
}
|
||||
|
||||
@objc private func revealTapGesture(_ recognizer: UITapGestureRecognizer) {
|
||||
if case .ended = recognizer.state {
|
||||
self.updateRevealOffsetInternal(offset: 0.0, transition: .animated(duration: 0.3, curve: .spring))
|
||||
|
@ -253,19 +253,24 @@ private enum ChatListEntryType {
|
||||
public struct ChatListFilterPredicate {
|
||||
public var includePeerIds: Set<PeerId>
|
||||
public var excludePeerIds: Set<PeerId>
|
||||
public var pinnedPeerIds: [PeerId]
|
||||
public var messageTagSummary: ChatListMessageTagSummaryResultCalculation?
|
||||
public var includeAdditionalPeerGroupIds: [PeerGroupId]
|
||||
public var include: (Peer, Bool, Bool, Bool, Bool?) -> Bool
|
||||
|
||||
public init(includePeerIds: Set<PeerId>, excludePeerIds: Set<PeerId>, messageTagSummary: ChatListMessageTagSummaryResultCalculation?, includeAdditionalPeerGroupIds: [PeerGroupId], include: @escaping (Peer, Bool, Bool, Bool, Bool?) -> Bool) {
|
||||
public init(includePeerIds: Set<PeerId>, excludePeerIds: Set<PeerId>, pinnedPeerIds: [PeerId], messageTagSummary: ChatListMessageTagSummaryResultCalculation?, includeAdditionalPeerGroupIds: [PeerGroupId], include: @escaping (Peer, Bool, Bool, Bool, Bool?) -> Bool) {
|
||||
self.includePeerIds = includePeerIds
|
||||
self.excludePeerIds = excludePeerIds
|
||||
self.pinnedPeerIds = pinnedPeerIds
|
||||
self.messageTagSummary = messageTagSummary
|
||||
self.includeAdditionalPeerGroupIds = includeAdditionalPeerGroupIds
|
||||
self.include = include
|
||||
}
|
||||
|
||||
func includes(peer: Peer, groupId: PeerGroupId, isRemovedFromTotalUnreadCount: Bool, isUnread: Bool, isContact: Bool, messageTagSummaryResult: Bool?) -> Bool {
|
||||
if self.pinnedPeerIds.contains(peer.id) {
|
||||
return false
|
||||
}
|
||||
let includePeerId = peer.associatedPeerId ?? peer.id
|
||||
if self.excludePeerIds.contains(includePeerId) {
|
||||
return false
|
||||
@ -299,19 +304,22 @@ final class MutableChatListView {
|
||||
self.summaryComponents = summaryComponents
|
||||
|
||||
var spaces: [ChatListViewSpace] = [
|
||||
.group(groupId: self.groupId, pinned: .notPinned)
|
||||
.group(groupId: self.groupId, pinned: .notPinned, predicate: filterPredicate)
|
||||
]
|
||||
if let filterPredicate = self.filterPredicate {
|
||||
spaces.append(.group(groupId: self.groupId, pinned: .includePinnedAsUnpinned))
|
||||
spaces.append(.group(groupId: self.groupId, pinned: .includePinnedAsUnpinned, predicate: filterPredicate))
|
||||
for additionalGroupId in filterPredicate.includeAdditionalPeerGroupIds {
|
||||
spaces.append(.group(groupId: additionalGroupId, pinned: .notPinned))
|
||||
spaces.append(.group(groupId: additionalGroupId, pinned: .includePinnedAsUnpinned))
|
||||
spaces.append(.group(groupId: additionalGroupId, pinned: .notPinned, predicate: filterPredicate))
|
||||
spaces.append(.group(groupId: additionalGroupId, pinned: .includePinnedAsUnpinned, predicate: filterPredicate))
|
||||
}
|
||||
if !filterPredicate.pinnedPeerIds.isEmpty {
|
||||
spaces.append(.peers(peerIds: filterPredicate.pinnedPeerIds, asPinned: true))
|
||||
}
|
||||
} else {
|
||||
spaces.append(.group(groupId: self.groupId, pinned: .includePinned))
|
||||
spaces.append(.group(groupId: self.groupId, pinned: .includePinned, predicate: filterPredicate))
|
||||
}
|
||||
self.spaces = spaces
|
||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: aroundIndex, filterPredicate: self.filterPredicate, summaryComponents: self.summaryComponents, halfLimit: count)
|
||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: aroundIndex, summaryComponents: self.summaryComponents, halfLimit: count)
|
||||
self.sampledState = self.state.sample(postbox: postbox)
|
||||
|
||||
self.count = count
|
||||
@ -404,7 +412,7 @@ final class MutableChatListView {
|
||||
func refreshDueToExternalTransaction(postbox: Postbox) -> Bool {
|
||||
var updated = false
|
||||
|
||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: .absoluteUpperBound, filterPredicate: self.filterPredicate, summaryComponents: self.summaryComponents, halfLimit: self.count)
|
||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: .absoluteUpperBound, summaryComponents: self.summaryComponents, halfLimit: self.count)
|
||||
self.sampledState = self.state.sample(postbox: postbox)
|
||||
updated = true
|
||||
|
||||
@ -423,7 +431,7 @@ final class MutableChatListView {
|
||||
var hasChanges = false
|
||||
|
||||
if transaction.updatedGlobalNotificationSettings && self.filterPredicate != nil {
|
||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: .absoluteUpperBound, filterPredicate: self.filterPredicate, summaryComponents: self.summaryComponents, halfLimit: self.count)
|
||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: .absoluteUpperBound, summaryComponents: self.summaryComponents, halfLimit: self.count)
|
||||
self.sampledState = self.state.sample(postbox: postbox)
|
||||
hasChanges = true
|
||||
} else {
|
||||
|
@ -15,7 +15,42 @@ enum ChatListViewSpacePinned {
|
||||
}
|
||||
|
||||
enum ChatListViewSpace: Hashable {
|
||||
case group(groupId: PeerGroupId, pinned: ChatListViewSpacePinned)
|
||||
case group(groupId: PeerGroupId, pinned: ChatListViewSpacePinned, predicate: ChatListFilterPredicate?)
|
||||
case peers(peerIds: [PeerId], asPinned: Bool)
|
||||
|
||||
static func ==(lhs: ChatListViewSpace, rhs: ChatListViewSpace) -> Bool {
|
||||
switch lhs {
|
||||
case let .group(groupId, pinned, _):
|
||||
if case let .group(rhsGroupId, rhsPinned, _) = rhs {
|
||||
if groupId != rhsGroupId {
|
||||
return false
|
||||
}
|
||||
if pinned != rhsPinned {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .peers(peerIds, asPinned):
|
||||
if case .peers(peerIds, asPinned) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
switch self {
|
||||
case let .group(groupId, pinned, _):
|
||||
hasher.combine(groupId)
|
||||
hasher.combine(pinned)
|
||||
case let .peers(peerIds, asPinned):
|
||||
hasher.combine(peerIds)
|
||||
hasher.combine(asPinned)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func mappedChatListFilterPredicate(postbox: Postbox, groupId: PeerGroupId, predicate: ChatListFilterPredicate) -> (ChatListIntermediateEntry) -> Bool {
|
||||
@ -91,16 +126,14 @@ private func updatedRenderedPeer(_ renderedPeer: RenderedPeer, updatedPeers: [Pe
|
||||
private final class ChatListViewSpaceState {
|
||||
private let space: ChatListViewSpace
|
||||
private let anchorIndex: MutableChatListEntryIndex
|
||||
private let filterPredicate: ChatListFilterPredicate?
|
||||
private let summaryComponents: ChatListEntrySummaryComponents
|
||||
private let halfLimit: Int
|
||||
|
||||
var orderedEntries: OrderedChatListViewEntries
|
||||
|
||||
init(postbox: Postbox, space: ChatListViewSpace, anchorIndex: MutableChatListEntryIndex, filterPredicate: ChatListFilterPredicate?, summaryComponents: ChatListEntrySummaryComponents, halfLimit: Int) {
|
||||
init(postbox: Postbox, space: ChatListViewSpace, anchorIndex: MutableChatListEntryIndex, summaryComponents: ChatListEntrySummaryComponents, halfLimit: Int) {
|
||||
self.space = space
|
||||
self.anchorIndex = anchorIndex
|
||||
self.filterPredicate = filterPredicate
|
||||
self.summaryComponents = summaryComponents
|
||||
self.halfLimit = halfLimit
|
||||
self.orderedEntries = OrderedChatListViewEntries(anchorIndex: anchorIndex.index, lowerOrAtAnchor: [], higherThanAnchor: [])
|
||||
@ -109,7 +142,7 @@ private final class ChatListViewSpaceState {
|
||||
|
||||
private func fillSpace(postbox: Postbox) {
|
||||
switch self.space {
|
||||
case let .group(groupId, pinned):
|
||||
case let .group(groupId, pinned, filterPredicate):
|
||||
let lowerBound: MutableChatListEntryIndex
|
||||
let upperBound: MutableChatListEntryIndex
|
||||
if pinned.include {
|
||||
@ -145,7 +178,7 @@ private final class ChatListViewSpaceState {
|
||||
let resolvedUnpinnedAnchorIndex = min(unpinnedUpperBound, max(self.anchorIndex, unpinnedLowerBound))
|
||||
|
||||
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: self.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, groupId: groupId, predicate: $0) }).map(mapEntry).sorted(by: { $0.entryIndex < $1.entryIndex })
|
||||
|
||||
if lowerOrAtAnchorMessages.count < self.halfLimit {
|
||||
var nextLowerIndex: MutableChatListEntryIndex
|
||||
@ -184,7 +217,7 @@ private final class ChatListViewSpaceState {
|
||||
} else {
|
||||
nextLowerIndex = resolvedAnchorIndex
|
||||
}
|
||||
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: self.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, groupId: groupId, predicate: $0) }).map(mapEntry)
|
||||
lowerOrAtAnchorMessages.append(contentsOf: loadedLowerMessages)
|
||||
}
|
||||
if higherThanAnchorMessages.count < self.halfLimit {
|
||||
@ -194,7 +227,7 @@ private final class ChatListViewSpaceState {
|
||||
} else {
|
||||
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: self.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, groupId: groupId, predicate: $0) }).map(mapEntry)
|
||||
higherThanAnchorMessages.append(contentsOf: loadedHigherMessages)
|
||||
}
|
||||
}
|
||||
@ -210,6 +243,78 @@ private final class ChatListViewSpaceState {
|
||||
|
||||
let entries = OrderedChatListViewEntries(anchorIndex: self.anchorIndex.index, lowerOrAtAnchor: lowerOrAtAnchorMessages, higherThanAnchor: higherThanAnchorMessages)
|
||||
self.orderedEntries = entries
|
||||
case let .peers(peerIds, asPinned):
|
||||
var lowerOrAtAnchorMessages: [MutableChatListEntry] = self.orderedEntries.lowerOrAtAnchor.reversed()
|
||||
var higherThanAnchorMessages: [MutableChatListEntry] = self.orderedEntries.higherThanAnchor
|
||||
|
||||
let unpinnedLowerBound: MutableChatListEntryIndex
|
||||
let unpinnedUpperBound: MutableChatListEntryIndex
|
||||
unpinnedUpperBound = .absoluteUpperBound
|
||||
unpinnedLowerBound = MutableChatListEntryIndex(index: ChatListIndex.absoluteLowerBound, isMessage: true)
|
||||
let resolvedUnpinnedAnchorIndex = min(unpinnedUpperBound, max(self.anchorIndex, unpinnedLowerBound))
|
||||
|
||||
if lowerOrAtAnchorMessages.count < self.halfLimit || higherThanAnchorMessages.count < self.halfLimit {
|
||||
func mapEntry(_ entry: ChatListIntermediateEntry, pinningIndex: UInt16?) -> MutableChatListEntry {
|
||||
switch entry {
|
||||
case let .message(index, messageIndex):
|
||||
var updatedIndex = index
|
||||
updatedIndex = ChatListIndex(pinningIndex: pinningIndex, messageIndex: index.messageIndex)
|
||||
return .IntermediateMessageEntry(index: updatedIndex, messageIndex: messageIndex)
|
||||
case let .hole(hole):
|
||||
return .HoleEntry(hole)
|
||||
}
|
||||
}
|
||||
|
||||
var loadedMessages: [MutableChatListEntry] = []
|
||||
for i in 0 ..< peerIds.count {
|
||||
let peerId = peerIds[i]
|
||||
if let entry = postbox.chatListTable.getEntry(peerId: peerId, messageHistoryTable: postbox.messageHistoryTable, peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable) {
|
||||
loadedMessages.append(mapEntry(entry, pinningIndex: asPinned ? UInt16(i) : nil))
|
||||
}
|
||||
}
|
||||
loadedMessages.sort(by: { $0.entryIndex < $1.entryIndex })
|
||||
|
||||
if lowerOrAtAnchorMessages.count < self.halfLimit {
|
||||
var nextLowerIndex: MutableChatListEntryIndex
|
||||
if let lastMessage = lowerOrAtAnchorMessages.min(by: { $0.entryIndex < $1.entryIndex }) {
|
||||
nextLowerIndex = lastMessage.entryIndex.predecessor
|
||||
} else {
|
||||
nextLowerIndex = min(resolvedUnpinnedAnchorIndex, self.anchorIndex)
|
||||
}
|
||||
var loadedLowerMessages = Array(loadedMessages.filter({ $0.entryIndex <= nextLowerIndex }).reversed())
|
||||
let lowerLimit = self.halfLimit - lowerOrAtAnchorMessages.count
|
||||
if loadedLowerMessages.count > lowerLimit {
|
||||
loadedLowerMessages.removeLast(loadedLowerMessages.count - lowerLimit)
|
||||
}
|
||||
lowerOrAtAnchorMessages.append(contentsOf: loadedLowerMessages)
|
||||
}
|
||||
if higherThanAnchorMessages.count < self.halfLimit {
|
||||
var nextHigherIndex: MutableChatListEntryIndex
|
||||
if let lastMessage = higherThanAnchorMessages.max(by: { $0.entryIndex < $1.entryIndex }) {
|
||||
nextHigherIndex = lastMessage.entryIndex.successor
|
||||
} else {
|
||||
nextHigherIndex = max(resolvedUnpinnedAnchorIndex, self.anchorIndex.successor)
|
||||
}
|
||||
var loadedHigherMessages = loadedMessages.filter({ $0.entryIndex > nextHigherIndex })
|
||||
let higherLimit = self.halfLimit - higherThanAnchorMessages.count
|
||||
if loadedHigherMessages.count > higherLimit {
|
||||
loadedHigherMessages.removeLast(loadedHigherMessages.count - higherLimit)
|
||||
}
|
||||
higherThanAnchorMessages.append(contentsOf: loadedHigherMessages)
|
||||
}
|
||||
|
||||
lowerOrAtAnchorMessages.reverse()
|
||||
|
||||
assert(lowerOrAtAnchorMessages.count <= self.halfLimit)
|
||||
assert(higherThanAnchorMessages.count <= self.halfLimit)
|
||||
|
||||
let allIndices = (lowerOrAtAnchorMessages + higherThanAnchorMessages).map { $0.entryIndex }
|
||||
assert(Set(allIndices).count == allIndices.count)
|
||||
assert(allIndices.sorted() == allIndices)
|
||||
|
||||
let entries = OrderedChatListViewEntries(anchorIndex: self.anchorIndex.index, lowerOrAtAnchor: lowerOrAtAnchorMessages, higherThanAnchor: higherThanAnchorMessages)
|
||||
self.orderedEntries = entries
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,27 +323,21 @@ private final class ChatListViewSpaceState {
|
||||
var hadRemovals = false
|
||||
var globalNotificationSettings: PostboxGlobalNotificationSettings?
|
||||
for (groupId, operations) in transaction.chatListOperations {
|
||||
let matchesSpace: Bool
|
||||
switch self.space {
|
||||
case .group(groupId, _):
|
||||
matchesSpace = true
|
||||
default:
|
||||
matchesSpace = false
|
||||
}
|
||||
if !matchesSpace {
|
||||
continue
|
||||
}
|
||||
|
||||
inner: for operation in operations {
|
||||
switch operation {
|
||||
case let .InsertEntry(index, messageIndex):
|
||||
switch self.space {
|
||||
case let .group(_, pinned) where (index.pinningIndex != nil) == pinned.include:
|
||||
case let .group(spaceGroupId, pinned, filterPredicate):
|
||||
let matchesGroup = groupId == spaceGroupId && (index.pinningIndex != nil) == pinned.include
|
||||
if !matchesGroup {
|
||||
continue inner
|
||||
}
|
||||
|
||||
var updatedIndex = index
|
||||
if case .includePinnedAsUnpinned = pinned {
|
||||
updatedIndex = ChatListIndex(pinningIndex: nil, messageIndex: index.messageIndex)
|
||||
}
|
||||
if let filterPredicate = self.filterPredicate {
|
||||
if let filterPredicate = filterPredicate {
|
||||
if let peer = postbox.peerTable.get(updatedIndex.messageIndex.id.peerId) {
|
||||
let notificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
||||
let globalNotificationSettingsValue: PostboxGlobalNotificationSettings
|
||||
@ -263,42 +362,80 @@ private final class ChatListViewSpaceState {
|
||||
if self.add(entry: .IntermediateMessageEntry(index: updatedIndex, messageIndex: messageIndex)) {
|
||||
hasUpdates = true
|
||||
}
|
||||
default:
|
||||
break
|
||||
case let .peers(peerIds, asPinned):
|
||||
if let peerIndex = peerIds.firstIndex(of: index.messageIndex.id.peerId) {
|
||||
var updatedIndex = index
|
||||
if asPinned {
|
||||
updatedIndex = ChatListIndex(pinningIndex: UInt16(peerIndex), messageIndex: index.messageIndex)
|
||||
}
|
||||
if self.add(entry: .IntermediateMessageEntry(index: updatedIndex, messageIndex: messageIndex)) {
|
||||
hasUpdates = true
|
||||
}
|
||||
} else {
|
||||
continue inner
|
||||
}
|
||||
}
|
||||
case let .InsertHole(hole):
|
||||
switch self.space {
|
||||
case let .group(_, pinned) where !pinned.include:
|
||||
if self.add(entry: .HoleEntry(hole)) {
|
||||
hasUpdates = true
|
||||
case let .group(spaceGroupId, pinned, _):
|
||||
if spaceGroupId == groupId && !pinned.include {
|
||||
if self.add(entry: .HoleEntry(hole)) {
|
||||
hasUpdates = true
|
||||
}
|
||||
}
|
||||
default:
|
||||
case .peers:
|
||||
break
|
||||
}
|
||||
case let .RemoveEntry(indices):
|
||||
for index in indices {
|
||||
var updatedIndex = index
|
||||
if case .group(_, .includePinnedAsUnpinned) = self.space {
|
||||
updatedIndex = ChatListIndex(pinningIndex: nil, messageIndex: index.messageIndex)
|
||||
switch self.space {
|
||||
case let .group(spaceGroupId, pinned, _):
|
||||
if spaceGroupId == groupId {
|
||||
for index in indices {
|
||||
var updatedIndex = index
|
||||
if case .includePinnedAsUnpinned = pinned {
|
||||
updatedIndex = ChatListIndex(pinningIndex: nil, messageIndex: index.messageIndex)
|
||||
}
|
||||
|
||||
if self.orderedEntries.remove(index: MutableChatListEntryIndex(index: updatedIndex, isMessage: true)) {
|
||||
hasUpdates = true
|
||||
hadRemovals = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.orderedEntries.remove(index: MutableChatListEntryIndex(index: updatedIndex, isMessage: true)) {
|
||||
hasUpdates = true
|
||||
hadRemovals = true
|
||||
case let .peers(peerIds, asPinned):
|
||||
for index in indices {
|
||||
if let peerIndex = peerIds.firstIndex(of: index.messageIndex.id.peerId) {
|
||||
var updatedIndex = index
|
||||
if asPinned {
|
||||
updatedIndex = ChatListIndex(pinningIndex: UInt16(peerIndex), messageIndex: index.messageIndex)
|
||||
}
|
||||
|
||||
if self.orderedEntries.remove(index: MutableChatListEntryIndex(index: updatedIndex, isMessage: true)) {
|
||||
hasUpdates = true
|
||||
hadRemovals = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case let .RemoveHoles(indices):
|
||||
for index in indices {
|
||||
if self.orderedEntries.remove(index: MutableChatListEntryIndex(index: index, isMessage: false)) {
|
||||
hasUpdates = true
|
||||
hadRemovals = true
|
||||
switch self.space {
|
||||
case let .group(spaceGroupId, pinned, _):
|
||||
if spaceGroupId == groupId && !pinned.include {
|
||||
for index in indices {
|
||||
if self.orderedEntries.remove(index: MutableChatListEntryIndex(index: index, isMessage: false)) {
|
||||
hasUpdates = true
|
||||
hadRemovals = true
|
||||
}
|
||||
}
|
||||
}
|
||||
case .peers:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !transaction.currentUpdatedPeerNotificationSettings.isEmpty, let filterPredicate = self.filterPredicate, case let .group(groupId, pinned) = self.space {
|
||||
if !transaction.currentUpdatedPeerNotificationSettings.isEmpty, case let .group(groupId, pinned, maybeFilterPredicate) = self.space, let filterPredicate = maybeFilterPredicate {
|
||||
var removeEntryIndices: [MutableChatListEntryIndex] = []
|
||||
let _ = self.orderedEntries.mutableScan { entry in
|
||||
let entryPeer: Peer
|
||||
@ -485,7 +622,7 @@ private final class ChatListViewSpaceState {
|
||||
}
|
||||
}
|
||||
|
||||
if !transaction.currentUpdatedMessageTagSummaries.isEmpty || !transaction.currentUpdatedMessageActionsSummaries.isEmpty, let filterPredicate = self.filterPredicate, let filterMessageTagSummary = filterPredicate.messageTagSummary, case let .group(groupId, pinned) = self.space {
|
||||
if !transaction.currentUpdatedMessageTagSummaries.isEmpty || !transaction.currentUpdatedMessageActionsSummaries.isEmpty, case let .group(groupId, pinned, maybeFilterPredicate) = self.space, let filterPredicate = maybeFilterPredicate, let filterMessageTagSummary = filterPredicate.messageTagSummary {
|
||||
var removeEntryIndices: [MutableChatListEntryIndex] = []
|
||||
let _ = self.orderedEntries.mutableScan { entry in
|
||||
let entryPeer: Peer
|
||||
@ -954,19 +1091,17 @@ final class ChatListViewSample {
|
||||
|
||||
struct ChatListViewState {
|
||||
private let anchorIndex: MutableChatListEntryIndex
|
||||
private let filterPredicate: ChatListFilterPredicate?
|
||||
private let summaryComponents: ChatListEntrySummaryComponents
|
||||
private let halfLimit: Int
|
||||
private var stateBySpace: [ChatListViewSpace: ChatListViewSpaceState] = [:]
|
||||
|
||||
init(postbox: Postbox, spaces: [ChatListViewSpace], anchorIndex: ChatListIndex, filterPredicate: ChatListFilterPredicate?, summaryComponents: ChatListEntrySummaryComponents, halfLimit: Int) {
|
||||
init(postbox: Postbox, spaces: [ChatListViewSpace], anchorIndex: ChatListIndex, summaryComponents: ChatListEntrySummaryComponents, halfLimit: Int) {
|
||||
self.anchorIndex = MutableChatListEntryIndex(index: anchorIndex, isMessage: true)
|
||||
self.filterPredicate = filterPredicate
|
||||
self.summaryComponents = summaryComponents
|
||||
self.halfLimit = halfLimit
|
||||
|
||||
for space in spaces {
|
||||
self.stateBySpace[space] = ChatListViewSpaceState(postbox: postbox, space: space, anchorIndex: self.anchorIndex, filterPredicate: self.filterPredicate, summaryComponents: summaryComponents, halfLimit: halfLimit)
|
||||
self.stateBySpace[space] = ChatListViewSpaceState(postbox: postbox, space: space, anchorIndex: self.anchorIndex, summaryComponents: summaryComponents, halfLimit: halfLimit)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1215,8 +1350,10 @@ struct ChatListViewState {
|
||||
|
||||
return ChatListViewSample(entries: result.map { $0.1 }, lower: lower, upper: upper, anchorIndex: self.anchorIndex.index, hole: sampledHole.flatMap { space, hole in
|
||||
switch space {
|
||||
case let .group(groupId, _):
|
||||
case let .group(groupId, _, _):
|
||||
return (groupId, hole)
|
||||
case .peers:
|
||||
return nil
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -234,22 +234,22 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView
|
||||
let timestamp = self.referenceTimestamp
|
||||
|
||||
let timestamp1 = timestamp + 120
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: 0, messageIndex: MessageIndex(id: MessageId(peerId: peer1.id, namespace: 0, id: 0), timestamp: timestamp1)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer1.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp1, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: selfPeer, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer1), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 0, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: 0, messageIndex: MessageIndex(id: MessageId(peerId: peer1.id, namespace: 0, id: 0), timestamp: timestamp1)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer1.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp1, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: selfPeer, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer1), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 0, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let presenceTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 + 60 * 60)
|
||||
let timestamp2 = timestamp + 3660
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer2.id, namespace: 0, id: 0), timestamp: timestamp2)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer2.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp2, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer2, text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer2), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: TelegramUserPresence(status: .present(until: presenceTimestamp), lastActivity: presenceTimestamp), summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: [(peer2, .typingText)], isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer2.id, namespace: 0, id: 0), timestamp: timestamp2)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer2.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp2, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer2, text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer2), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: TelegramUserPresence(status: .present(until: presenceTimestamp), lastActivity: presenceTimestamp), summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: [(peer2, .typingText)], isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let timestamp3 = timestamp + 3200
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer3.id, namespace: 0, id: 0), timestamp: timestamp3)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer3.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp3, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer3Author, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer3), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer3.id, namespace: 0, id: 0), timestamp: timestamp3)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer3.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp3, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer3Author, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer3), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let timestamp4 = timestamp + 3000
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer4.id, namespace: 0, id: 0), timestamp: timestamp4)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer4.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp4, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer4, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer4), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer4.id, namespace: 0, id: 0), timestamp: timestamp4)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer4.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp4, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer4, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer4), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let timestamp5 = timestamp + 1000
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer5.id, namespace: 0, id: 0), timestamp: timestamp5)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer4.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp5, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer5, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer5), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer5.id, namespace: 0, id: 0), timestamp: timestamp5)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer4.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp5, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer5, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer5), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer6.id, namespace: 0, id: 0), timestamp: timestamp - 360)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer6.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp - 360, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer6, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer6), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 1, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer6.id, namespace: 0, id: 0), timestamp: timestamp - 360)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer6.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp - 360, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer6, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer6), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 1, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let width: CGFloat
|
||||
if case .regular = layout.metrics.widthClass {
|
||||
|
@ -785,17 +785,17 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
||||
let timestamp = self.referenceTimestamp
|
||||
|
||||
let timestamp1 = timestamp + 120
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: 0, messageIndex: MessageIndex(id: MessageId(peerId: peer1.id, namespace: 0, id: 0), timestamp: timestamp1)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer1.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp1, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: selfPeer, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer1), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 0, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: 0, messageIndex: MessageIndex(id: MessageId(peerId: peer1.id, namespace: 0, id: 0), timestamp: timestamp1)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer1.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp1, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: selfPeer, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer1), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 0, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let presenceTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 + 60 * 60)
|
||||
let timestamp2 = timestamp + 3660
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer2.id, namespace: 0, id: 0), timestamp: timestamp2)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer2.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp2, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer2, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer2), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 1, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: TelegramUserPresence(status: .present(until: presenceTimestamp), lastActivity: presenceTimestamp), summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer2.id, namespace: 0, id: 0), timestamp: timestamp2)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer2.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp2, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer2, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_2_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer2), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 1, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: TelegramUserPresence(status: .present(until: presenceTimestamp), lastActivity: presenceTimestamp), summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let timestamp3 = timestamp + 3200
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer3.id, namespace: 0, id: 0), timestamp: timestamp3)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer3.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp3, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer3Author, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer3), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer3.id, namespace: 0, id: 0), timestamp: timestamp3)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer3.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp3, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer3Author, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer3), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let timestamp4 = timestamp + 3000
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer4.id, namespace: 0, id: 0), timestamp: timestamp4)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer4.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp4, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer4, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer4), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer4.id, namespace: 0, id: 0), timestamp: timestamp4)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer4.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp4, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer4, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer4), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let params = ListViewItemLayoutParams(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, availableHeight: layout.size.height)
|
||||
if let chatNodes = self.chatNodes {
|
||||
|
@ -372,24 +372,24 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
let timestamp = self.referenceTimestamp
|
||||
|
||||
let timestamp1 = timestamp + 120
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: 0, messageIndex: MessageIndex(id: MessageId(peerId: peer1.id, namespace: 0, id: 0), timestamp: timestamp1)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer1.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp1, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: selfPeer, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer1), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 0, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: 0, messageIndex: MessageIndex(id: MessageId(peerId: peer1.id, namespace: 0, id: 0), timestamp: timestamp1)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer1.id, namespace: 0, id: 0), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp1, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: selfPeer, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_1_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer1), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 0, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let presenceTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 + 60 * 60)
|
||||
let timestamp2 = timestamp + 3660
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer2.id, namespace: 0, id: 0), timestamp: timestamp2)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer2.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp2, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer2, text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer2), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: TelegramUserPresence(status: .present(until: presenceTimestamp), lastActivity: presenceTimestamp), summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: [(peer2, .typingText)], isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer2.id, namespace: 0, id: 0), timestamp: timestamp2)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer2.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp2, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer2, text: "", attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer2), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: TelegramUserPresence(status: .present(until: presenceTimestamp), lastActivity: presenceTimestamp), summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: [(peer2, .typingText)], isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let timestamp3 = timestamp + 3200
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer3.id, namespace: 0, id: 0), timestamp: timestamp3)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer3.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp3, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer3Author, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer3), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer3.id, namespace: 0, id: 0), timestamp: timestamp3)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer3.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp3, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer3Author, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_3_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer3), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let timestamp4 = timestamp + 3000
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer4.id, namespace: 0, id: 0), timestamp: timestamp4)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer4.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp4, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer4, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer4), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer4.id, namespace: 0, id: 0), timestamp: timestamp4)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer4.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp4, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer4, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_4_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer4), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let timestamp5 = timestamp + 1000
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer5.id, namespace: 0, id: 0), timestamp: timestamp5)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer4.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp5, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer5, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer5), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer5.id, namespace: 0, id: 0), timestamp: timestamp5)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer4.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp5, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer5, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_5_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer5), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer6.id, namespace: 0, id: 0), timestamp: timestamp - 360)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer6.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp - 360, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer6, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer6), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 1, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer6.id, namespace: 0, id: 0), timestamp: timestamp - 360)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer6.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp - 360, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer6, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_6_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer6), combinedReadState: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, PeerReadState.idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: 1, markedUnread: false))]), isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer7.id, namespace: 0, id: 0), timestamp: timestamp - 420)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer7.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp - 420, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer6, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_7_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer7), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
items.append(ChatListItem(presentationData: chatListPresentationData, context: self.context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: MessageIndex(id: MessageId(peerId: peer7.id, namespace: 0, id: 0), timestamp: timestamp - 420)), content: .peer(message: Message(stableId: 0, stableVersion: 0, id: MessageId(peerId: peer7.id, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, timestamp: timestamp - 420, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peer6, text: self.presentationData.strings.Appearance_ThemePreview_ChatList_7_Text, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: []), peer: RenderedPeer(peer: peer7), combinedReadState: nil, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(tagSummaryCount: nil, actionsSummaryCount: nil), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction))
|
||||
|
||||
let width: CGFloat
|
||||
if case .regular = layout.metrics.widthClass {
|
||||
|
@ -605,7 +605,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-1551583367] = { return Api.ReceivedNotifyMessage.parse_receivedNotifyMessage($0) }
|
||||
dict[-57668565] = { return Api.ChatParticipants.parse_chatParticipantsForbidden($0) }
|
||||
dict[1061556205] = { return Api.ChatParticipants.parse_chatParticipants($0) }
|
||||
dict[1687327098] = { return Api.DialogFilter.parse_dialogFilter($0) }
|
||||
dict[-878553771] = { return Api.DialogFilter.parse_dialogFilter($0) }
|
||||
dict[-1056001329] = { return Api.InputPaymentCredentials.parse_inputPaymentCredentialsSaved($0) }
|
||||
dict[873977640] = { return Api.InputPaymentCredentials.parse_inputPaymentCredentials($0) }
|
||||
dict[178373535] = { return Api.InputPaymentCredentials.parse_inputPaymentCredentialsApplePay($0) }
|
||||
|
@ -17276,18 +17276,23 @@ public extension Api {
|
||||
|
||||
}
|
||||
public enum DialogFilter: TypeConstructorDescription {
|
||||
case dialogFilter(flags: Int32, id: Int32, title: String, includePeers: [Api.InputPeer], excludePeers: [Api.InputPeer])
|
||||
case dialogFilter(flags: Int32, id: Int32, title: String, pinnedPeers: [Api.InputPeer], includePeers: [Api.InputPeer], excludePeers: [Api.InputPeer])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .dialogFilter(let flags, let id, let title, let includePeers, let excludePeers):
|
||||
case .dialogFilter(let flags, let id, let title, let pinnedPeers, let includePeers, let excludePeers):
|
||||
if boxed {
|
||||
buffer.appendInt32(1687327098)
|
||||
buffer.appendInt32(-878553771)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(id, buffer: buffer, boxed: false)
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(pinnedPeers.count))
|
||||
for item in pinnedPeers {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(includePeers.count))
|
||||
for item in includePeers {
|
||||
item.serialize(buffer, true)
|
||||
@ -17303,8 +17308,8 @@ public extension Api {
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .dialogFilter(let flags, let id, let title, let includePeers, let excludePeers):
|
||||
return ("dialogFilter", [("flags", flags), ("id", id), ("title", title), ("includePeers", includePeers), ("excludePeers", excludePeers)])
|
||||
case .dialogFilter(let flags, let id, let title, let pinnedPeers, let includePeers, let excludePeers):
|
||||
return ("dialogFilter", [("flags", flags), ("id", id), ("title", title), ("pinnedPeers", pinnedPeers), ("includePeers", includePeers), ("excludePeers", excludePeers)])
|
||||
}
|
||||
}
|
||||
|
||||
@ -17323,13 +17328,18 @@ public extension Api {
|
||||
if let _ = reader.readInt32() {
|
||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputPeer.self)
|
||||
}
|
||||
var _6: [Api.InputPeer]?
|
||||
if let _ = reader.readInt32() {
|
||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputPeer.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.DialogFilter.dialogFilter(flags: _1!, id: _2!, title: _3!, includePeers: _4!, excludePeers: _5!)
|
||||
let _c6 = _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.DialogFilter.dialogFilter(flags: _1!, id: _2!, title: _3!, pinnedPeers: _4!, includePeers: _5!, excludePeers: _6!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
@ -103,6 +103,7 @@ public struct ChatListFilterData: Equatable, Hashable {
|
||||
public var excludeArchived: Bool
|
||||
public var includePeers: [PeerId]
|
||||
public var excludePeers: [PeerId]
|
||||
public var pinnedPeers: [PeerId]
|
||||
|
||||
public init(
|
||||
categories: ChatListFilterPeerCategories,
|
||||
@ -110,7 +111,8 @@ public struct ChatListFilterData: Equatable, Hashable {
|
||||
excludeRead: Bool,
|
||||
excludeArchived: Bool,
|
||||
includePeers: [PeerId],
|
||||
excludePeers: [PeerId]
|
||||
excludePeers: [PeerId],
|
||||
pinnedPeers: [PeerId]
|
||||
) {
|
||||
self.categories = categories
|
||||
self.excludeMuted = excludeMuted
|
||||
@ -118,6 +120,7 @@ public struct ChatListFilterData: Equatable, Hashable {
|
||||
self.excludeArchived = excludeArchived
|
||||
self.includePeers = includePeers
|
||||
self.excludePeers = excludePeers
|
||||
self.pinnedPeers = pinnedPeers
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +148,8 @@ public struct ChatListFilter: PostboxCoding, Equatable {
|
||||
excludeRead: decoder.decodeInt32ForKey("excludeRead", orElse: 0) != 0,
|
||||
excludeArchived: decoder.decodeInt32ForKey("excludeArchived", orElse: 0) != 0,
|
||||
includePeers: decoder.decodeInt64ArrayForKey("includePeers").map(PeerId.init),
|
||||
excludePeers: decoder.decodeInt64ArrayForKey("excludePeers").map(PeerId.init)
|
||||
excludePeers: decoder.decodeInt64ArrayForKey("excludePeers").map(PeerId.init),
|
||||
pinnedPeers: decoder.decodeInt64ArrayForKey("pinnedPeers").map(PeerId.init)
|
||||
)
|
||||
}
|
||||
|
||||
@ -158,13 +162,14 @@ public struct ChatListFilter: PostboxCoding, Equatable {
|
||||
encoder.encodeInt32(self.data.excludeArchived ? 1 : 0, forKey: "excludeArchived")
|
||||
encoder.encodeInt64Array(self.data.includePeers.map { $0.toInt64() }, forKey: "includePeers")
|
||||
encoder.encodeInt64Array(self.data.excludePeers.map { $0.toInt64() }, forKey: "excludePeers")
|
||||
encoder.encodeInt64Array(self.data.pinnedPeers.map { $0.toInt64() }, forKey: "pinnedPeers")
|
||||
}
|
||||
}
|
||||
|
||||
extension ChatListFilter {
|
||||
init(apiFilter: Api.DialogFilter) {
|
||||
switch apiFilter {
|
||||
case let .dialogFilter(flags, id, title, includePeers, excludePeers):
|
||||
case let .dialogFilter(flags, id, title, pinnedPeers, includePeers, excludePeers):
|
||||
self.init(
|
||||
id: id,
|
||||
title: title,
|
||||
@ -196,6 +201,18 @@ extension ChatListFilter {
|
||||
default:
|
||||
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
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -214,7 +231,9 @@ extension ChatListFilter {
|
||||
flags |= 1 << 13
|
||||
}
|
||||
flags |= self.data.categories.apiFlags
|
||||
return .dialogFilter(flags: flags, id: self.id, title: self.title, includePeers: self.data.includePeers.compactMap { peerId -> Api.InputPeer? in
|
||||
return .dialogFilter(flags: flags, id: self.id, title: self.title, pinnedPeers: self.data.pinnedPeers.compactMap { peerId -> Api.InputPeer? in
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}, includePeers: self.data.includePeers.compactMap { peerId -> Api.InputPeer? in
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
}, excludePeers: self.data.excludePeers.compactMap { peerId -> Api.InputPeer? in
|
||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||
@ -278,27 +297,8 @@ private func requestChatListFilters(postbox: Postbox, network: Network) -> Signa
|
||||
let filter = ChatListFilter(apiFilter: apiFilter)
|
||||
filters.append(filter)
|
||||
switch apiFilter {
|
||||
case let .dialogFilter(_, _, _, includePeers, excludePeers):
|
||||
for peer in includePeers {
|
||||
var peerId: PeerId?
|
||||
switch peer {
|
||||
case let .inputPeerUser(userId, _):
|
||||
peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
|
||||
case let .inputPeerChat(chatId):
|
||||
peerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)
|
||||
case let .inputPeerChannel(channelId, _):
|
||||
peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
|
||||
default:
|
||||
break
|
||||
}
|
||||
if let peerId = peerId {
|
||||
if transaction.getPeer(peerId) == nil && !missingPeerIds.contains(peerId) {
|
||||
missingPeerIds.insert(peerId)
|
||||
missingPeers.append(peer)
|
||||
}
|
||||
}
|
||||
}
|
||||
for peer in excludePeers {
|
||||
case let .dialogFilter(_, _, _, pinnedPeers, includePeers, excludePeers):
|
||||
for peer in pinnedPeers + includePeers + excludePeers {
|
||||
var peerId: PeerId?
|
||||
switch peer {
|
||||
case let .inputPeerUser(userId, _):
|
||||
@ -509,6 +509,23 @@ public func updateChatListFiltersInteractively(postbox: Postbox, _ f: @escaping
|
||||
}
|
||||
}
|
||||
|
||||
public func updateChatListFiltersInteractively(transaction: Transaction, _ f: ([ChatListFilter]) -> [ChatListFilter]) {
|
||||
var hasUpdates = false
|
||||
transaction.updatePreferencesEntry(key: PreferencesKeys.chatListFilters, { entry in
|
||||
var state = entry as? ChatListFiltersState ?? ChatListFiltersState.default
|
||||
let updatedFilters = f(state.filters)
|
||||
if updatedFilters != state.filters {
|
||||
state.filters = updatedFilters
|
||||
hasUpdates = true
|
||||
}
|
||||
return state
|
||||
})
|
||||
if hasUpdates {
|
||||
requestChatListFiltersSync(transaction: transaction)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func updatedChatListFilters(postbox: Postbox) -> Signal<[ChatListFilter], NoError> {
|
||||
return postbox.preferencesView(keys: [PreferencesKeys.chatListFilters])
|
||||
|> map { preferences -> [ChatListFilter] in
|
||||
@ -577,7 +594,8 @@ public struct ChatListFeaturedFilter: PostboxCoding, Equatable {
|
||||
excludeRead: decoder.decodeInt32ForKey("excludeRead", orElse: 0) != 0,
|
||||
excludeArchived: decoder.decodeInt32ForKey("excludeArchived", orElse: 0) != 0,
|
||||
includePeers: decoder.decodeInt64ArrayForKey("includePeers").map(PeerId.init),
|
||||
excludePeers: decoder.decodeInt64ArrayForKey("excludePeers").map(PeerId.init)
|
||||
excludePeers: decoder.decodeInt64ArrayForKey("excludePeers").map(PeerId.init),
|
||||
pinnedPeers: decoder.decodeInt64ArrayForKey("pinnedPeers").map(PeerId.init)
|
||||
)
|
||||
}
|
||||
|
||||
@ -590,6 +608,7 @@ public struct ChatListFeaturedFilter: PostboxCoding, Equatable {
|
||||
encoder.encodeInt32(self.data.excludeArchived ? 1 : 0, forKey: "excludeArchived")
|
||||
encoder.encodeInt64Array(self.data.includePeers.map { $0.toInt64() }, forKey: "includePeers")
|
||||
encoder.encodeInt64Array(self.data.excludePeers.map { $0.toInt64() }, forKey: "excludePeers")
|
||||
encoder.encodeInt64Array(self.data.pinnedPeers.map { $0.toInt64() }, forKey: "pinnedPeers")
|
||||
}
|
||||
}
|
||||
|
||||
@ -668,8 +687,6 @@ public func updateChatListFeaturedFilters(postbox: Postbox, network: Network) ->
|
||||
}
|
||||
|
||||
private enum SynchronizeChatListFiltersOperationContentType: Int32 {
|
||||
case add
|
||||
case remove
|
||||
case sync
|
||||
}
|
||||
|
||||
@ -681,7 +698,7 @@ private enum SynchronizeChatListFiltersOperationContent: PostboxCoding {
|
||||
case SynchronizeChatListFiltersOperationContentType.sync.rawValue:
|
||||
self = .sync
|
||||
default:
|
||||
assertionFailure()
|
||||
//assertionFailure()
|
||||
self = .sync
|
||||
}
|
||||
}
|
||||
|
@ -4,62 +4,132 @@ import SwiftSignalKit
|
||||
|
||||
import SyncCore
|
||||
|
||||
public enum TogglePeerChatPinnedLocation {
|
||||
case group(PeerGroupId)
|
||||
case filter(Int32)
|
||||
}
|
||||
|
||||
public enum TogglePeerChatPinnedResult {
|
||||
case done
|
||||
case limitExceeded(Int)
|
||||
}
|
||||
|
||||
public func toggleItemPinned(postbox: Postbox, groupId: PeerGroupId, itemId: PinnedItemId) -> Signal<TogglePeerChatPinnedResult, NoError> {
|
||||
public func toggleItemPinned(postbox: Postbox, location: TogglePeerChatPinnedLocation, itemId: PinnedItemId) -> Signal<TogglePeerChatPinnedResult, NoError> {
|
||||
return postbox.transaction { transaction -> TogglePeerChatPinnedResult in
|
||||
var itemIds = transaction.getPinnedItemIds(groupId: groupId)
|
||||
let sameKind = itemIds.filter { item in
|
||||
switch itemId {
|
||||
case let .peer(lhsPeerId):
|
||||
if case let .peer(rhsPeerId) = item {
|
||||
return (lhsPeerId.namespace == Namespaces.Peer.SecretChat) == (rhsPeerId.namespace == Namespaces.Peer.SecretChat) && lhsPeerId != rhsPeerId
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
switch location {
|
||||
case let .group(groupId):
|
||||
var itemIds = transaction.getPinnedItemIds(groupId: groupId)
|
||||
let sameKind = itemIds.filter { item in
|
||||
switch itemId {
|
||||
case let .peer(lhsPeerId):
|
||||
if case let .peer(rhsPeerId) = item {
|
||||
return (lhsPeerId.namespace == Namespaces.Peer.SecretChat) == (rhsPeerId.namespace == Namespaces.Peer.SecretChat) && lhsPeerId != rhsPeerId
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let additionalCount: Int
|
||||
if let _ = itemIds.firstIndex(of: itemId) {
|
||||
additionalCount = -1
|
||||
} else {
|
||||
additionalCount = 1
|
||||
}
|
||||
|
||||
let limitsConfiguration = transaction.getPreferencesEntry(key: PreferencesKeys.limitsConfiguration) as? LimitsConfiguration ?? LimitsConfiguration.defaultValue
|
||||
let limitCount: Int
|
||||
if case .root = groupId {
|
||||
limitCount = Int(limitsConfiguration.maxPinnedChatCount)
|
||||
} else {
|
||||
limitCount = Int(limitsConfiguration.maxArchivedPinnedChatCount)
|
||||
}
|
||||
|
||||
if sameKind.count + additionalCount > limitCount {
|
||||
return .limitExceeded(limitCount)
|
||||
} else {
|
||||
if let index = itemIds.firstIndex(of: itemId) {
|
||||
itemIds.remove(at: index)
|
||||
let additionalCount: Int
|
||||
if let _ = itemIds.firstIndex(of: itemId) {
|
||||
additionalCount = -1
|
||||
} else {
|
||||
itemIds.insert(itemId, at: 0)
|
||||
additionalCount = 1
|
||||
}
|
||||
addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId)
|
||||
transaction.setPinnedItemIds(groupId: groupId, itemIds: itemIds)
|
||||
return .done
|
||||
|
||||
let limitsConfiguration = transaction.getPreferencesEntry(key: PreferencesKeys.limitsConfiguration) as? LimitsConfiguration ?? LimitsConfiguration.defaultValue
|
||||
let limitCount: Int
|
||||
if case .root = groupId {
|
||||
limitCount = Int(limitsConfiguration.maxPinnedChatCount)
|
||||
} else {
|
||||
limitCount = Int(limitsConfiguration.maxArchivedPinnedChatCount)
|
||||
}
|
||||
|
||||
if sameKind.count + additionalCount > limitCount {
|
||||
return .limitExceeded(limitCount)
|
||||
} else {
|
||||
if let index = itemIds.firstIndex(of: itemId) {
|
||||
itemIds.remove(at: index)
|
||||
} else {
|
||||
itemIds.insert(itemId, at: 0)
|
||||
}
|
||||
addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId)
|
||||
transaction.setPinnedItemIds(groupId: groupId, itemIds: itemIds)
|
||||
return .done
|
||||
}
|
||||
case let .filter(filterId):
|
||||
var result: TogglePeerChatPinnedResult = .done
|
||||
updateChatListFiltersInteractively(transaction: transaction, { filters in
|
||||
var filters = filters
|
||||
if let index = filters.firstIndex(where: { $0.id == filterId }) {
|
||||
switch itemId {
|
||||
case let .peer(peerId):
|
||||
if filters[index].data.pinnedPeers.contains(peerId) {
|
||||
filters[index].data.pinnedPeers.removeAll(where: { $0 == peerId })
|
||||
} else {
|
||||
if filters[index].data.pinnedPeers.count < 100 {
|
||||
filters[index].data.pinnedPeers.insert(peerId, at: 0)
|
||||
} else {
|
||||
result = .limitExceeded(100)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return filters
|
||||
})
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func reorderPinnedItemIds(transaction: Transaction, groupId: PeerGroupId, itemIds: [PinnedItemId]) -> Bool {
|
||||
if transaction.getPinnedItemIds(groupId: groupId) != itemIds {
|
||||
transaction.setPinnedItemIds(groupId: groupId, itemIds: itemIds)
|
||||
addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
public func getPinnedItemIds(transaction: Transaction, location: TogglePeerChatPinnedLocation) -> [PinnedItemId] {
|
||||
switch location {
|
||||
case let .group(groupId):
|
||||
return transaction.getPinnedItemIds(groupId: groupId)
|
||||
case let .filter(filterId):
|
||||
var itemIds: [PinnedItemId] = []
|
||||
let _ = updateChatListFiltersInteractively(transaction: transaction, { filters in
|
||||
if let index = filters.firstIndex(where: { $0.id == filterId }) {
|
||||
itemIds = filters[index].data.pinnedPeers.map { peerId in
|
||||
return .peer(peerId)
|
||||
}
|
||||
}
|
||||
return filters
|
||||
})
|
||||
return itemIds
|
||||
}
|
||||
}
|
||||
|
||||
public func reorderPinnedItemIds(transaction: Transaction, location: TogglePeerChatPinnedLocation, itemIds: [PinnedItemId]) -> Bool {
|
||||
switch location {
|
||||
case let .group(groupId):
|
||||
if transaction.getPinnedItemIds(groupId: groupId) != itemIds {
|
||||
transaction.setPinnedItemIds(groupId: groupId, itemIds: itemIds)
|
||||
addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .filter(filterId):
|
||||
var result: Bool = false
|
||||
updateChatListFiltersInteractively(transaction: transaction, { filters in
|
||||
var filters = filters
|
||||
if let index = filters.firstIndex(where: { $0.id == filterId }) {
|
||||
let peerIds: [PeerId] = itemIds.map { itemId -> PeerId in
|
||||
switch itemId {
|
||||
case let .peer(peerId):
|
||||
return peerId
|
||||
}
|
||||
}
|
||||
|
||||
if filters[index].data.pinnedPeers != peerIds {
|
||||
filters[index].data.pinnedPeers = peerIds
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return filters
|
||||
})
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ private enum ChatListSearchEntry: Comparable, Identifiable {
|
||||
public func item(context: AccountContext, interaction: ChatListNodeInteraction) -> ListViewItem {
|
||||
switch self {
|
||||
case let .message(message, peer, readState, presentationData):
|
||||
return ChatListItem(presentationData: presentationData, context: context, peerGroupId: .root, isInFilter: false, index: ChatListIndex(pinningIndex: nil, messageIndex: message.index), content: .peer(message: message, peer: peer, combinedReadState: readState, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: true, displayAsMessage: true, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction)
|
||||
return ChatListItem(presentationData: presentationData, context: context, peerGroupId: .root, filterData: nil, index: ChatListIndex(pinningIndex: nil, messageIndex: message.index), content: .peer(message: message, peer: peer, combinedReadState: readState, isRemovedFromTotalUnreadCount: false, presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(), embeddedState: nil, inputActivities: nil, isAd: false, ignoreUnreadBadge: true, displayAsMessage: true, hasFailedMessages: false), editing: false, hasActiveRevealControls: false, selected: false, header: nil, enableContextActions: false, hiddenOffset: false, interaction: interaction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -510,7 +510,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
||||
super.didLoad()
|
||||
|
||||
let panRecognizer = InteractiveTransitionGestureRecognizer(target: self, action: #selector(self.panGesture(_:)), allowedDirections: { [weak self] _ in
|
||||
guard let strongSelf = self, let currentPaneKey = strongSelf.currentPaneKey, let availablePanes = strongSelf.currentParams?.data?.availablePanes, let index = availablePanes.index(of: currentPaneKey) else {
|
||||
guard let strongSelf = self, let currentPaneKey = strongSelf.currentPaneKey, let availablePanes = strongSelf.currentParams?.data?.availablePanes, let index = availablePanes.firstIndex(of: currentPaneKey) else {
|
||||
return []
|
||||
}
|
||||
if index == 0 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user