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 {
|
enum ChatContextMenuSource {
|
||||||
case chatList(isFilter: Bool)
|
case chatList(filter: ChatListFilter?)
|
||||||
case search(ChatListSearchContextActionSource)
|
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
|
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
|
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
|
|> deliverOnMainQueue).start(next: { result in
|
||||||
switch result {
|
switch result {
|
||||||
case .done:
|
case .done:
|
||||||
|
@ -923,7 +923,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController,
|
|||||||
case let .peer(peer):
|
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))
|
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)
|
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)
|
strongSelf.presentInGlobalOverlay(contextController)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ private final class ChatListShimmerNode: ASDisplayNode {
|
|||||||
}, present: { _ in })
|
}, present: { _ in })
|
||||||
|
|
||||||
let items = (0 ..< 2).map { _ -> ChatListItem 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] = []
|
var itemNodes: [ChatListItemNode] = []
|
||||||
|
@ -740,7 +740,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
|||||||
var state = f(current)
|
var state = f(current)
|
||||||
if !state.changedName {
|
if !state.changedName {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
let filter = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: state.additionallyIncludePeers, excludePeers: state.additionallyExcludePeers))
|
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) {
|
switch chatListFilterType(filter) {
|
||||||
case .generic:
|
case .generic:
|
||||||
state.name = initialName
|
state.name = initialName
|
||||||
@ -781,7 +781,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
|||||||
},
|
},
|
||||||
openAddIncludePeer: {
|
openAddIncludePeer: {
|
||||||
let state = stateValue.with { $0 }
|
let state = stateValue.with { $0 }
|
||||||
let filter = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: state.additionallyIncludePeers, excludePeers: state.additionallyExcludePeers))
|
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
|
let controller = internalChatListFilterAddChatsController(context: context, filter: filter, applyAutomatically: false, updated: { filter in
|
||||||
skipStateAnimation = true
|
skipStateAnimation = true
|
||||||
@ -797,7 +797,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
|||||||
},
|
},
|
||||||
openAddExcludePeer: {
|
openAddExcludePeer: {
|
||||||
let state = stateValue.with { $0 }
|
let state = stateValue.with { $0 }
|
||||||
let filter = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: state.additionallyIncludePeers, excludePeers: state.additionallyExcludePeers))
|
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
|
let controller = internalChatListFilterExcludeChatsController(context: context, filter: filter, applyAutomatically: false, updated: { filter in
|
||||||
skipStateAnimation = true
|
skipStateAnimation = true
|
||||||
@ -918,7 +918,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
|||||||
var attemptNavigationImpl: (() -> Bool)?
|
var attemptNavigationImpl: (() -> Bool)?
|
||||||
var applyImpl: (() -> Void)? = {
|
var applyImpl: (() -> Void)? = {
|
||||||
let state = stateValue.with { $0 }
|
let state = stateValue.with { $0 }
|
||||||
let preset = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: state.additionallyIncludePeers, excludePeers: state.additionallyExcludePeers))
|
let preset = ChatListFilter(id: currentPreset?.id ?? -1, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: state.additionallyIncludePeers, excludePeers: state.additionallyExcludePeers, pinnedPeers: currentPreset?.data.pinnedPeers ?? []))
|
||||||
let _ = (updateChatListFiltersInteractively(postbox: context.account.postbox, { filters in
|
let _ = (updateChatListFiltersInteractively(postbox: context.account.postbox, { filters in
|
||||||
var preset = preset
|
var preset = preset
|
||||||
if currentPreset == nil {
|
if currentPreset == nil {
|
||||||
@ -1013,7 +1013,7 @@ func chatListFilterPresetController(context: AccountContext, currentPreset: Chat
|
|||||||
attemptNavigationImpl = {
|
attemptNavigationImpl = {
|
||||||
let state = stateValue.with { $0 }
|
let state = stateValue.with { $0 }
|
||||||
if let currentPreset = currentPreset {
|
if let currentPreset = currentPreset {
|
||||||
let filter = ChatListFilter(id: currentPreset.id, title: state.name, data: ChatListFilterData(categories: state.includeCategories, excludeMuted: state.excludeMuted, excludeRead: state.excludeRead, excludeArchived: state.excludeArchived, includePeers: state.additionallyIncludePeers, excludePeers: state.additionallyExcludePeers))
|
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 {
|
if currentPreset != filter {
|
||||||
displaySaveAlert()
|
displaySaveAlert()
|
||||||
return false
|
return false
|
||||||
|
@ -484,7 +484,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
case let .message(message, peer, readState, presentationData):
|
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):
|
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: {
|
return ContactsAddItem(theme: theme, strings: strings, phoneNumber: phoneNumber, header: ChatListSearchItemHeader(type: .phoneNumber, theme: theme, strings: strings, actionTitle: nil, action: nil), action: {
|
||||||
interaction.addContact(phoneNumber)
|
interaction.addContact(phoneNumber)
|
||||||
|
@ -37,7 +37,7 @@ public class ChatListItem: ListViewItem, ChatListSearchItemNeighbour {
|
|||||||
let presentationData: ChatListPresentationData
|
let presentationData: ChatListPresentationData
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
let peerGroupId: PeerGroupId
|
let peerGroupId: PeerGroupId
|
||||||
let isInFilter: Bool
|
let filterData: ChatListItemFilterData?
|
||||||
let index: ChatListIndex
|
let index: ChatListIndex
|
||||||
public let content: ChatListItemContent
|
public let content: ChatListItemContent
|
||||||
let editing: Bool
|
let editing: Bool
|
||||||
@ -59,10 +59,10 @@ public class ChatListItem: ListViewItem, ChatListSearchItemNeighbour {
|
|||||||
return self.index.pinningIndex != nil
|
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.presentationData = presentationData
|
||||||
self.peerGroupId = peerGroupId
|
self.peerGroupId = peerGroupId
|
||||||
self.isInFilter = isInFilter
|
self.filterData = filterData
|
||||||
self.context = context
|
self.context = context
|
||||||
self.index = index
|
self.index = index
|
||||||
self.content = content
|
self.content = content
|
||||||
@ -204,7 +204,15 @@ private func canArchivePeer(id: PeerId, accountPeerId: PeerId) -> Bool {
|
|||||||
return true
|
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] = []
|
var options: [ItemListRevealOption] = []
|
||||||
if !isEditing {
|
if !isEditing {
|
||||||
if case .group = groupId {
|
if case .group = groupId {
|
||||||
@ -226,7 +234,7 @@ private func revealOptions(strings: PresentationStrings, theme: PresentationThem
|
|||||||
if canDelete {
|
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))
|
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 case .root = groupId {
|
||||||
if canArchivePeer(id: peerId, accountPeerId: accountPeerId) {
|
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))
|
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
|
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 {
|
if case .group = groupId {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@ -260,7 +268,7 @@ private func leftRevealOptions(strings: PresentationStrings, theme: Presentation
|
|||||||
} else {
|
} 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))
|
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 {
|
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))
|
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 {
|
} else {
|
||||||
@ -1169,9 +1177,9 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
let isPinned = item.index.pinningIndex != nil
|
let isPinned = item.index.pinningIndex != nil
|
||||||
|
|
||||||
if item.enableContextActions && !isAd {
|
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 {
|
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 {
|
} else {
|
||||||
peerLeftRevealOptions = []
|
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
|
return entries.map { entry -> ListViewInsertItem in
|
||||||
switch entry.entry {
|
switch entry.entry {
|
||||||
case .HeaderEntry:
|
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):
|
case let .PeerEntry(index, presentationData, message, combinedReadState, isRemovedFromTotalUnreadCount, embeddedState, peer, presence, summaryInfo, editing, hasActiveRevealControls, selected, inputActivities, isAd, hasFailedMessages, isContact):
|
||||||
switch mode {
|
switch mode {
|
||||||
case .chatList:
|
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, _):
|
case let .peers(filter, isSelecting, _):
|
||||||
let itemPeer = peer.chatMainPeer
|
let itemPeer = peer.chatMainPeer
|
||||||
var chatPeer: Peer?
|
var chatPeer: Peer?
|
||||||
@ -266,20 +266,20 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL
|
|||||||
case let .HoleEntry(_, theme):
|
case let .HoleEntry(_, theme):
|
||||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListHoleItem(theme: theme), directionHint: entry.directionHint)
|
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):
|
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):
|
case let .ArchiveIntro(presentationData):
|
||||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListArchiveInfoItem(theme: presentationData.theme, strings: presentationData.strings), directionHint: entry.directionHint)
|
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
|
return entries.map { entry -> ListViewUpdateItem in
|
||||||
switch entry.entry {
|
switch entry.entry {
|
||||||
case let .PeerEntry(index, presentationData, message, combinedReadState, isRemovedFromTotalUnreadCount, embeddedState, peer, presence, summaryInfo, editing, hasActiveRevealControls, selected, inputActivities, isAd, hasFailedMessages, isContact):
|
case let .PeerEntry(index, presentationData, message, combinedReadState, isRemovedFromTotalUnreadCount, embeddedState, peer, presence, summaryInfo, editing, hasActiveRevealControls, selected, inputActivities, isAd, hasFailedMessages, isContact):
|
||||||
switch mode {
|
switch mode {
|
||||||
case .chatList:
|
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, _):
|
case let .peers(filter, isSelecting, _):
|
||||||
let itemPeer = peer.chatMainPeer
|
let itemPeer = peer.chatMainPeer
|
||||||
var chatPeer: Peer?
|
var chatPeer: Peer?
|
||||||
@ -329,7 +329,7 @@ private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatL
|
|||||||
case let .HoleEntry(_, theme):
|
case let .HoleEntry(_, theme):
|
||||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListHoleItem(theme: theme), directionHint: entry.directionHint)
|
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):
|
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):
|
case let .ArchiveIntro(presentationData):
|
||||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListArchiveInfoItem(theme: presentationData.theme, strings: presentationData.strings), directionHint: entry.directionHint)
|
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ChatListArchiveInfoItem(theme: presentationData.theme, strings: presentationData.strings), directionHint: entry.directionHint)
|
||||||
case .HeaderEntry:
|
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 {
|
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, 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)
|
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 {
|
private final class ChatListOpaqueTransactionState {
|
||||||
@ -560,7 +560,13 @@ public final class ChatListNode: ListView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, setItemPinned: { [weak self] itemId, _ in
|
}, 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
|
|> deliverOnMainQueue).start(next: { result in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
switch result {
|
switch result {
|
||||||
@ -856,10 +862,12 @@ public final class ChatListNode: ListView {
|
|||||||
updatedScrollPosition = nil
|
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)
|
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)
|
|> runOn(prepareOnMainQueue ? Queue.mainQueue() : viewProcessingQueue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1033,30 +1041,33 @@ public final class ChatListNode: ListView {
|
|||||||
var referenceId: PinnedItemId?
|
var referenceId: PinnedItemId?
|
||||||
var beforeAll = false
|
var beforeAll = false
|
||||||
switch toEntry {
|
switch toEntry {
|
||||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, isAd, _, _):
|
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, isAd, _, _):
|
||||||
if isAd {
|
if isAd {
|
||||||
beforeAll = true
|
beforeAll = true
|
||||||
} else {
|
} else {
|
||||||
referenceId = .peer(index.messageIndex.id.peerId)
|
referenceId = .peer(index.messageIndex.id.peerId)
|
||||||
}
|
}
|
||||||
/*case let .GroupReferenceEntry(_, _, groupId, _, _, _, _):
|
|
||||||
referenceId = .group(groupId)*/
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if case let .index(index) = fromEntry.sortIndex, let _ = index.pinningIndex {
|
if case let .index(index) = fromEntry.sortIndex, let _ = index.pinningIndex {
|
||||||
return strongSelf.context.account.postbox.transaction { transaction -> Bool in
|
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?
|
var itemId: PinnedItemId?
|
||||||
switch fromEntry {
|
switch fromEntry {
|
||||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||||
itemId = .peer(index.messageIndex.id.peerId)
|
itemId = .peer(index.messageIndex.id.peerId)
|
||||||
/*case let .GroupReferenceEntry(_, _, groupId, _, _, _, _):
|
default:
|
||||||
itemId = .group(groupId)*/
|
break
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let itemId = itemId {
|
if let itemId = itemId {
|
||||||
@ -1082,7 +1093,7 @@ public final class ChatListNode: ListView {
|
|||||||
} else {
|
} else {
|
||||||
itemIds.append(itemId)
|
itemIds.append(itemId)
|
||||||
}
|
}
|
||||||
return reorderPinnedItemIds(transaction: transaction, groupId: groupId, itemIds: itemIds)
|
return reorderPinnedItemIds(transaction: transaction, location: location, itemIds: itemIds)
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,14 @@ struct ChatListNodeViewUpdate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func chatListFilterPredicate(filter: ChatListFilterData) -> ChatListFilterPredicate {
|
func chatListFilterPredicate(filter: ChatListFilterData) -> ChatListFilterPredicate {
|
||||||
let includePeers = Set(filter.includePeers)
|
var includePeers = Set(filter.includePeers)
|
||||||
let excludePeers = Set(filter.excludePeers)
|
var excludePeers = Set(filter.excludePeers)
|
||||||
|
|
||||||
|
if !filter.pinnedPeers.isEmpty {
|
||||||
|
includePeers.subtract(filter.pinnedPeers)
|
||||||
|
excludePeers.subtract(filter.pinnedPeers)
|
||||||
|
}
|
||||||
|
|
||||||
var includeAdditionalPeerGroupIds: [PeerGroupId] = []
|
var includeAdditionalPeerGroupIds: [PeerGroupId] = []
|
||||||
if !filter.excludeArchived {
|
if !filter.excludeArchived {
|
||||||
includeAdditionalPeerGroupIds.append(Namespaces.PeerGroup.archive)
|
includeAdditionalPeerGroupIds.append(Namespaces.PeerGroup.archive)
|
||||||
@ -41,7 +47,7 @@ func chatListFilterPredicate(filter: ChatListFilterData) -> ChatListFilterPredic
|
|||||||
if filter.excludeRead {
|
if filter.excludeRead {
|
||||||
messageTagSummary = ChatListMessageTagSummaryResultCalculation(addCount: ChatListMessageTagSummaryResultComponent(tag: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud), subtractCount: ChatListMessageTagActionsSummaryResultComponent(type: PendingMessageActionType.consumeUnseenPersonalMessage, namespace: Namespaces.Message.Cloud))
|
messageTagSummary = ChatListMessageTagSummaryResultCalculation(addCount: ChatListMessageTagSummaryResultComponent(tag: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud), subtractCount: ChatListMessageTagActionsSummaryResultComponent(type: PendingMessageActionType.consumeUnseenPersonalMessage, namespace: Namespaces.Message.Cloud))
|
||||||
}
|
}
|
||||||
return ChatListFilterPredicate(includePeerIds: includePeers, excludePeerIds: excludePeers, 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 {
|
if filter.excludeRead {
|
||||||
var effectiveUnread = isUnread
|
var effectiveUnread = isUnread
|
||||||
if let messageTagSummaryResult = messageTagSummaryResult, messageTagSummaryResult {
|
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 {
|
} else if fromView.filteredEntries.isEmpty || fromView.filter != toView.filter {
|
||||||
options.remove(.AnimateInsertion)
|
var updateEmpty = true
|
||||||
options.remove(.AnimateAlpha)
|
if !fromView.filteredEntries.isEmpty, let fromFilter = fromView.filter, let toFilter = toView.filter, fromFilter.data.pinnedPeers != toFilter.data.pinnedPeers {
|
||||||
fromEmptyView = true
|
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 {
|
} else {
|
||||||
fromEmptyView = true
|
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) {
|
@objc private func revealTapGesture(_ recognizer: UITapGestureRecognizer) {
|
||||||
if case .ended = recognizer.state {
|
if case .ended = recognizer.state {
|
||||||
self.updateRevealOffsetInternal(offset: 0.0, transition: .animated(duration: 0.3, curve: .spring))
|
self.updateRevealOffsetInternal(offset: 0.0, transition: .animated(duration: 0.3, curve: .spring))
|
||||||
|
@ -253,19 +253,24 @@ private enum ChatListEntryType {
|
|||||||
public struct ChatListFilterPredicate {
|
public struct ChatListFilterPredicate {
|
||||||
public var includePeerIds: Set<PeerId>
|
public var includePeerIds: Set<PeerId>
|
||||||
public var excludePeerIds: Set<PeerId>
|
public var excludePeerIds: Set<PeerId>
|
||||||
|
public var pinnedPeerIds: [PeerId]
|
||||||
public var messageTagSummary: ChatListMessageTagSummaryResultCalculation?
|
public var messageTagSummary: ChatListMessageTagSummaryResultCalculation?
|
||||||
public var includeAdditionalPeerGroupIds: [PeerGroupId]
|
public var includeAdditionalPeerGroupIds: [PeerGroupId]
|
||||||
public var include: (Peer, Bool, Bool, Bool, Bool?) -> Bool
|
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.includePeerIds = includePeerIds
|
||||||
self.excludePeerIds = excludePeerIds
|
self.excludePeerIds = excludePeerIds
|
||||||
|
self.pinnedPeerIds = pinnedPeerIds
|
||||||
self.messageTagSummary = messageTagSummary
|
self.messageTagSummary = messageTagSummary
|
||||||
self.includeAdditionalPeerGroupIds = includeAdditionalPeerGroupIds
|
self.includeAdditionalPeerGroupIds = includeAdditionalPeerGroupIds
|
||||||
self.include = include
|
self.include = include
|
||||||
}
|
}
|
||||||
|
|
||||||
func includes(peer: Peer, groupId: PeerGroupId, isRemovedFromTotalUnreadCount: Bool, isUnread: Bool, isContact: Bool, messageTagSummaryResult: Bool?) -> Bool {
|
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
|
let includePeerId = peer.associatedPeerId ?? peer.id
|
||||||
if self.excludePeerIds.contains(includePeerId) {
|
if self.excludePeerIds.contains(includePeerId) {
|
||||||
return false
|
return false
|
||||||
@ -299,19 +304,22 @@ final class MutableChatListView {
|
|||||||
self.summaryComponents = summaryComponents
|
self.summaryComponents = summaryComponents
|
||||||
|
|
||||||
var spaces: [ChatListViewSpace] = [
|
var spaces: [ChatListViewSpace] = [
|
||||||
.group(groupId: self.groupId, pinned: .notPinned)
|
.group(groupId: self.groupId, pinned: .notPinned, predicate: filterPredicate)
|
||||||
]
|
]
|
||||||
if let filterPredicate = self.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 {
|
for additionalGroupId in filterPredicate.includeAdditionalPeerGroupIds {
|
||||||
spaces.append(.group(groupId: additionalGroupId, pinned: .notPinned))
|
spaces.append(.group(groupId: additionalGroupId, pinned: .notPinned, predicate: filterPredicate))
|
||||||
spaces.append(.group(groupId: additionalGroupId, pinned: .includePinnedAsUnpinned))
|
spaces.append(.group(groupId: additionalGroupId, pinned: .includePinnedAsUnpinned, predicate: filterPredicate))
|
||||||
|
}
|
||||||
|
if !filterPredicate.pinnedPeerIds.isEmpty {
|
||||||
|
spaces.append(.peers(peerIds: filterPredicate.pinnedPeerIds, asPinned: true))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
spaces.append(.group(groupId: self.groupId, pinned: .includePinned))
|
spaces.append(.group(groupId: self.groupId, pinned: .includePinned, predicate: filterPredicate))
|
||||||
}
|
}
|
||||||
self.spaces = spaces
|
self.spaces = spaces
|
||||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: aroundIndex, 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.sampledState = self.state.sample(postbox: postbox)
|
||||||
|
|
||||||
self.count = count
|
self.count = count
|
||||||
@ -404,7 +412,7 @@ final class MutableChatListView {
|
|||||||
func refreshDueToExternalTransaction(postbox: Postbox) -> Bool {
|
func refreshDueToExternalTransaction(postbox: Postbox) -> Bool {
|
||||||
var updated = false
|
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)
|
self.sampledState = self.state.sample(postbox: postbox)
|
||||||
updated = true
|
updated = true
|
||||||
|
|
||||||
@ -423,7 +431,7 @@ final class MutableChatListView {
|
|||||||
var hasChanges = false
|
var hasChanges = false
|
||||||
|
|
||||||
if transaction.updatedGlobalNotificationSettings && self.filterPredicate != nil {
|
if transaction.updatedGlobalNotificationSettings && self.filterPredicate != nil {
|
||||||
self.state = ChatListViewState(postbox: postbox, spaces: self.spaces, anchorIndex: .absoluteUpperBound, 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)
|
self.sampledState = self.state.sample(postbox: postbox)
|
||||||
hasChanges = true
|
hasChanges = true
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,7 +15,42 @@ enum ChatListViewSpacePinned {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum ChatListViewSpace: Hashable {
|
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 {
|
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 final class ChatListViewSpaceState {
|
||||||
private let space: ChatListViewSpace
|
private let space: ChatListViewSpace
|
||||||
private let anchorIndex: MutableChatListEntryIndex
|
private let anchorIndex: MutableChatListEntryIndex
|
||||||
private let filterPredicate: ChatListFilterPredicate?
|
|
||||||
private let summaryComponents: ChatListEntrySummaryComponents
|
private let summaryComponents: ChatListEntrySummaryComponents
|
||||||
private let halfLimit: Int
|
private let halfLimit: Int
|
||||||
|
|
||||||
var orderedEntries: OrderedChatListViewEntries
|
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.space = space
|
||||||
self.anchorIndex = anchorIndex
|
self.anchorIndex = anchorIndex
|
||||||
self.filterPredicate = filterPredicate
|
|
||||||
self.summaryComponents = summaryComponents
|
self.summaryComponents = summaryComponents
|
||||||
self.halfLimit = halfLimit
|
self.halfLimit = halfLimit
|
||||||
self.orderedEntries = OrderedChatListViewEntries(anchorIndex: anchorIndex.index, lowerOrAtAnchor: [], higherThanAnchor: [])
|
self.orderedEntries = OrderedChatListViewEntries(anchorIndex: anchorIndex.index, lowerOrAtAnchor: [], higherThanAnchor: [])
|
||||||
@ -109,7 +142,7 @@ private final class ChatListViewSpaceState {
|
|||||||
|
|
||||||
private func fillSpace(postbox: Postbox) {
|
private func fillSpace(postbox: Postbox) {
|
||||||
switch self.space {
|
switch self.space {
|
||||||
case let .group(groupId, pinned):
|
case let .group(groupId, pinned, filterPredicate):
|
||||||
let lowerBound: MutableChatListEntryIndex
|
let lowerBound: MutableChatListEntryIndex
|
||||||
let upperBound: MutableChatListEntryIndex
|
let upperBound: MutableChatListEntryIndex
|
||||||
if pinned.include {
|
if pinned.include {
|
||||||
@ -145,7 +178,7 @@ private final class ChatListViewSpaceState {
|
|||||||
let resolvedUnpinnedAnchorIndex = min(unpinnedUpperBound, max(self.anchorIndex, unpinnedLowerBound))
|
let resolvedUnpinnedAnchorIndex = min(unpinnedUpperBound, max(self.anchorIndex, unpinnedLowerBound))
|
||||||
|
|
||||||
if lowerOrAtAnchorMessages.count < self.halfLimit || higherThanAnchorMessages.count < self.halfLimit {
|
if lowerOrAtAnchorMessages.count < self.halfLimit || higherThanAnchorMessages.count < self.halfLimit {
|
||||||
let loadedMessages = postbox.chatListTable.entries(groupId: groupId, from: (ChatListIndex.pinnedLowerBound, true), to: (ChatListIndex.absoluteUpperBound, true), peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: self.halfLimit * 2, predicate: 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 {
|
if lowerOrAtAnchorMessages.count < self.halfLimit {
|
||||||
var nextLowerIndex: MutableChatListEntryIndex
|
var nextLowerIndex: MutableChatListEntryIndex
|
||||||
@ -184,7 +217,7 @@ private final class ChatListViewSpaceState {
|
|||||||
} else {
|
} else {
|
||||||
nextLowerIndex = resolvedAnchorIndex
|
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)
|
lowerOrAtAnchorMessages.append(contentsOf: loadedLowerMessages)
|
||||||
}
|
}
|
||||||
if higherThanAnchorMessages.count < self.halfLimit {
|
if higherThanAnchorMessages.count < self.halfLimit {
|
||||||
@ -194,7 +227,7 @@ private final class ChatListViewSpaceState {
|
|||||||
} else {
|
} else {
|
||||||
nextHigherIndex = resolvedAnchorIndex
|
nextHigherIndex = resolvedAnchorIndex
|
||||||
}
|
}
|
||||||
let loadedHigherMessages = postbox.chatListTable.entries(groupId: groupId, from: (nextHigherIndex.index, nextHigherIndex.isMessage), to: (upperBound.index, upperBound.isMessage), peerChatInterfaceStateTable: postbox.peerChatInterfaceStateTable, count: self.halfLimit - higherThanAnchorMessages.count, predicate: 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)
|
higherThanAnchorMessages.append(contentsOf: loadedHigherMessages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,6 +243,78 @@ private final class ChatListViewSpaceState {
|
|||||||
|
|
||||||
let entries = OrderedChatListViewEntries(anchorIndex: self.anchorIndex.index, lowerOrAtAnchor: lowerOrAtAnchorMessages, higherThanAnchor: higherThanAnchorMessages)
|
let entries = OrderedChatListViewEntries(anchorIndex: self.anchorIndex.index, lowerOrAtAnchor: lowerOrAtAnchorMessages, higherThanAnchor: higherThanAnchorMessages)
|
||||||
self.orderedEntries = entries
|
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 hadRemovals = false
|
||||||
var globalNotificationSettings: PostboxGlobalNotificationSettings?
|
var globalNotificationSettings: PostboxGlobalNotificationSettings?
|
||||||
for (groupId, operations) in transaction.chatListOperations {
|
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 {
|
inner: for operation in operations {
|
||||||
switch operation {
|
switch operation {
|
||||||
case let .InsertEntry(index, messageIndex):
|
case let .InsertEntry(index, messageIndex):
|
||||||
switch self.space {
|
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
|
var updatedIndex = index
|
||||||
if case .includePinnedAsUnpinned = pinned {
|
if case .includePinnedAsUnpinned = pinned {
|
||||||
updatedIndex = ChatListIndex(pinningIndex: nil, messageIndex: index.messageIndex)
|
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) {
|
if let peer = postbox.peerTable.get(updatedIndex.messageIndex.id.peerId) {
|
||||||
let notificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
let notificationsPeerId = peer.notificationSettingsPeerId ?? peer.id
|
||||||
let globalNotificationSettingsValue: PostboxGlobalNotificationSettings
|
let globalNotificationSettingsValue: PostboxGlobalNotificationSettings
|
||||||
@ -263,42 +362,80 @@ private final class ChatListViewSpaceState {
|
|||||||
if self.add(entry: .IntermediateMessageEntry(index: updatedIndex, messageIndex: messageIndex)) {
|
if self.add(entry: .IntermediateMessageEntry(index: updatedIndex, messageIndex: messageIndex)) {
|
||||||
hasUpdates = true
|
hasUpdates = true
|
||||||
}
|
}
|
||||||
default:
|
case let .peers(peerIds, asPinned):
|
||||||
break
|
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):
|
case let .InsertHole(hole):
|
||||||
switch self.space {
|
switch self.space {
|
||||||
case let .group(_, pinned) where !pinned.include:
|
case let .group(spaceGroupId, pinned, _):
|
||||||
if self.add(entry: .HoleEntry(hole)) {
|
if spaceGroupId == groupId && !pinned.include {
|
||||||
hasUpdates = true
|
if self.add(entry: .HoleEntry(hole)) {
|
||||||
|
hasUpdates = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default:
|
case .peers:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case let .RemoveEntry(indices):
|
case let .RemoveEntry(indices):
|
||||||
for index in indices {
|
switch self.space {
|
||||||
var updatedIndex = index
|
case let .group(spaceGroupId, pinned, _):
|
||||||
if case .group(_, .includePinnedAsUnpinned) = self.space {
|
if spaceGroupId == groupId {
|
||||||
updatedIndex = ChatListIndex(pinningIndex: nil, messageIndex: index.messageIndex)
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
case let .peers(peerIds, asPinned):
|
||||||
if self.orderedEntries.remove(index: MutableChatListEntryIndex(index: updatedIndex, isMessage: true)) {
|
for index in indices {
|
||||||
hasUpdates = true
|
if let peerIndex = peerIds.firstIndex(of: index.messageIndex.id.peerId) {
|
||||||
hadRemovals = true
|
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):
|
case let .RemoveHoles(indices):
|
||||||
for index in indices {
|
switch self.space {
|
||||||
if self.orderedEntries.remove(index: MutableChatListEntryIndex(index: index, isMessage: false)) {
|
case let .group(spaceGroupId, pinned, _):
|
||||||
hasUpdates = true
|
if spaceGroupId == groupId && !pinned.include {
|
||||||
hadRemovals = true
|
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] = []
|
var removeEntryIndices: [MutableChatListEntryIndex] = []
|
||||||
let _ = self.orderedEntries.mutableScan { entry in
|
let _ = self.orderedEntries.mutableScan { entry in
|
||||||
let entryPeer: Peer
|
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] = []
|
var removeEntryIndices: [MutableChatListEntryIndex] = []
|
||||||
let _ = self.orderedEntries.mutableScan { entry in
|
let _ = self.orderedEntries.mutableScan { entry in
|
||||||
let entryPeer: Peer
|
let entryPeer: Peer
|
||||||
@ -954,19 +1091,17 @@ final class ChatListViewSample {
|
|||||||
|
|
||||||
struct ChatListViewState {
|
struct ChatListViewState {
|
||||||
private let anchorIndex: MutableChatListEntryIndex
|
private let anchorIndex: MutableChatListEntryIndex
|
||||||
private let filterPredicate: ChatListFilterPredicate?
|
|
||||||
private let summaryComponents: ChatListEntrySummaryComponents
|
private let summaryComponents: ChatListEntrySummaryComponents
|
||||||
private let halfLimit: Int
|
private let halfLimit: Int
|
||||||
private var stateBySpace: [ChatListViewSpace: ChatListViewSpaceState] = [:]
|
private var stateBySpace: [ChatListViewSpace: ChatListViewSpaceState] = [:]
|
||||||
|
|
||||||
init(postbox: Postbox, spaces: [ChatListViewSpace], anchorIndex: ChatListIndex, 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.anchorIndex = MutableChatListEntryIndex(index: anchorIndex, isMessage: true)
|
||||||
self.filterPredicate = filterPredicate
|
|
||||||
self.summaryComponents = summaryComponents
|
self.summaryComponents = summaryComponents
|
||||||
self.halfLimit = halfLimit
|
self.halfLimit = halfLimit
|
||||||
|
|
||||||
for space in spaces {
|
for space in spaces {
|
||||||
self.stateBySpace[space] = ChatListViewSpaceState(postbox: postbox, space: space, anchorIndex: self.anchorIndex, 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
|
return ChatListViewSample(entries: result.map { $0.1 }, lower: lower, upper: upper, anchorIndex: self.anchorIndex.index, hole: sampledHole.flatMap { space, hole in
|
||||||
switch space {
|
switch space {
|
||||||
case let .group(groupId, _):
|
case let .group(groupId, _, _):
|
||||||
return (groupId, hole)
|
return (groupId, hole)
|
||||||
|
case .peers:
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -234,22 +234,22 @@ private final class TextSizeSelectionControllerNode: ASDisplayNode, UIScrollView
|
|||||||
let timestamp = self.referenceTimestamp
|
let timestamp = self.referenceTimestamp
|
||||||
|
|
||||||
let timestamp1 = timestamp + 120
|
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 presenceTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 + 60 * 60)
|
||||||
let timestamp2 = timestamp + 3660
|
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
|
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
|
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
|
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
|
let width: CGFloat
|
||||||
if case .regular = layout.metrics.widthClass {
|
if case .regular = layout.metrics.widthClass {
|
||||||
|
@ -785,17 +785,17 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
|
|||||||
let timestamp = self.referenceTimestamp
|
let timestamp = self.referenceTimestamp
|
||||||
|
|
||||||
let timestamp1 = timestamp + 120
|
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 presenceTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 + 60 * 60)
|
||||||
let timestamp2 = timestamp + 3660
|
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
|
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
|
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)
|
let params = ListViewItemLayoutParams(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, availableHeight: layout.size.height)
|
||||||
if let chatNodes = self.chatNodes {
|
if let chatNodes = self.chatNodes {
|
||||||
|
@ -372,24 +372,24 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
let timestamp = self.referenceTimestamp
|
let timestamp = self.referenceTimestamp
|
||||||
|
|
||||||
let timestamp1 = timestamp + 120
|
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 presenceTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 + 60 * 60)
|
||||||
let timestamp2 = timestamp + 3660
|
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
|
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
|
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
|
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
|
let width: CGFloat
|
||||||
if case .regular = layout.metrics.widthClass {
|
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[-1551583367] = { return Api.ReceivedNotifyMessage.parse_receivedNotifyMessage($0) }
|
||||||
dict[-57668565] = { return Api.ChatParticipants.parse_chatParticipantsForbidden($0) }
|
dict[-57668565] = { return Api.ChatParticipants.parse_chatParticipantsForbidden($0) }
|
||||||
dict[1061556205] = { return Api.ChatParticipants.parse_chatParticipants($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[-1056001329] = { return Api.InputPaymentCredentials.parse_inputPaymentCredentialsSaved($0) }
|
||||||
dict[873977640] = { return Api.InputPaymentCredentials.parse_inputPaymentCredentials($0) }
|
dict[873977640] = { return Api.InputPaymentCredentials.parse_inputPaymentCredentials($0) }
|
||||||
dict[178373535] = { return Api.InputPaymentCredentials.parse_inputPaymentCredentialsApplePay($0) }
|
dict[178373535] = { return Api.InputPaymentCredentials.parse_inputPaymentCredentialsApplePay($0) }
|
||||||
|
@ -17276,18 +17276,23 @@ public extension Api {
|
|||||||
|
|
||||||
}
|
}
|
||||||
public enum DialogFilter: TypeConstructorDescription {
|
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) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
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 {
|
if boxed {
|
||||||
buffer.appendInt32(1687327098)
|
buffer.appendInt32(-878553771)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeInt32(id, buffer: buffer, boxed: false)
|
serializeInt32(id, buffer: buffer, boxed: false)
|
||||||
serializeString(title, buffer: buffer, boxed: false)
|
serializeString(title, buffer: buffer, boxed: false)
|
||||||
buffer.appendInt32(481674261)
|
buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(pinnedPeers.count))
|
||||||
|
for item in pinnedPeers {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}
|
||||||
|
buffer.appendInt32(481674261)
|
||||||
buffer.appendInt32(Int32(includePeers.count))
|
buffer.appendInt32(Int32(includePeers.count))
|
||||||
for item in includePeers {
|
for item in includePeers {
|
||||||
item.serialize(buffer, true)
|
item.serialize(buffer, true)
|
||||||
@ -17303,8 +17308,8 @@ public extension Api {
|
|||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
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):
|
||||||
return ("dialogFilter", [("flags", flags), ("id", id), ("title", title), ("includePeers", includePeers), ("excludePeers", 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() {
|
if let _ = reader.readInt32() {
|
||||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.InputPeer.self)
|
_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 _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
let _c4 = _4 != nil
|
let _c4 = _4 != nil
|
||||||
let _c5 = _5 != nil
|
let _c5 = _5 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
let _c6 = _6 != nil
|
||||||
return Api.DialogFilter.dialogFilter(flags: _1!, id: _2!, title: _3!, includePeers: _4!, excludePeers: _5!)
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||||
|
return Api.DialogFilter.dialogFilter(flags: _1!, id: _2!, title: _3!, pinnedPeers: _4!, includePeers: _5!, excludePeers: _6!)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -103,6 +103,7 @@ public struct ChatListFilterData: Equatable, Hashable {
|
|||||||
public var excludeArchived: Bool
|
public var excludeArchived: Bool
|
||||||
public var includePeers: [PeerId]
|
public var includePeers: [PeerId]
|
||||||
public var excludePeers: [PeerId]
|
public var excludePeers: [PeerId]
|
||||||
|
public var pinnedPeers: [PeerId]
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
categories: ChatListFilterPeerCategories,
|
categories: ChatListFilterPeerCategories,
|
||||||
@ -110,7 +111,8 @@ public struct ChatListFilterData: Equatable, Hashable {
|
|||||||
excludeRead: Bool,
|
excludeRead: Bool,
|
||||||
excludeArchived: Bool,
|
excludeArchived: Bool,
|
||||||
includePeers: [PeerId],
|
includePeers: [PeerId],
|
||||||
excludePeers: [PeerId]
|
excludePeers: [PeerId],
|
||||||
|
pinnedPeers: [PeerId]
|
||||||
) {
|
) {
|
||||||
self.categories = categories
|
self.categories = categories
|
||||||
self.excludeMuted = excludeMuted
|
self.excludeMuted = excludeMuted
|
||||||
@ -118,6 +120,7 @@ public struct ChatListFilterData: Equatable, Hashable {
|
|||||||
self.excludeArchived = excludeArchived
|
self.excludeArchived = excludeArchived
|
||||||
self.includePeers = includePeers
|
self.includePeers = includePeers
|
||||||
self.excludePeers = excludePeers
|
self.excludePeers = excludePeers
|
||||||
|
self.pinnedPeers = pinnedPeers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +148,8 @@ public struct ChatListFilter: PostboxCoding, Equatable {
|
|||||||
excludeRead: decoder.decodeInt32ForKey("excludeRead", orElse: 0) != 0,
|
excludeRead: decoder.decodeInt32ForKey("excludeRead", orElse: 0) != 0,
|
||||||
excludeArchived: decoder.decodeInt32ForKey("excludeArchived", orElse: 0) != 0,
|
excludeArchived: decoder.decodeInt32ForKey("excludeArchived", orElse: 0) != 0,
|
||||||
includePeers: decoder.decodeInt64ArrayForKey("includePeers").map(PeerId.init),
|
includePeers: 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.encodeInt32(self.data.excludeArchived ? 1 : 0, forKey: "excludeArchived")
|
||||||
encoder.encodeInt64Array(self.data.includePeers.map { $0.toInt64() }, forKey: "includePeers")
|
encoder.encodeInt64Array(self.data.includePeers.map { $0.toInt64() }, forKey: "includePeers")
|
||||||
encoder.encodeInt64Array(self.data.excludePeers.map { $0.toInt64() }, forKey: "excludePeers")
|
encoder.encodeInt64Array(self.data.excludePeers.map { $0.toInt64() }, forKey: "excludePeers")
|
||||||
|
encoder.encodeInt64Array(self.data.pinnedPeers.map { $0.toInt64() }, forKey: "pinnedPeers")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ChatListFilter {
|
extension ChatListFilter {
|
||||||
init(apiFilter: Api.DialogFilter) {
|
init(apiFilter: Api.DialogFilter) {
|
||||||
switch apiFilter {
|
switch apiFilter {
|
||||||
case let .dialogFilter(flags, id, title, includePeers, excludePeers):
|
case let .dialogFilter(flags, id, title, pinnedPeers, includePeers, excludePeers):
|
||||||
self.init(
|
self.init(
|
||||||
id: id,
|
id: id,
|
||||||
title: title,
|
title: title,
|
||||||
@ -196,6 +201,18 @@ extension ChatListFilter {
|
|||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
pinnedPeers: pinnedPeers.compactMap { peer -> PeerId? in
|
||||||
|
switch peer {
|
||||||
|
case let .inputPeerUser(userId, _):
|
||||||
|
return PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)
|
||||||
|
case let .inputPeerChat(chatId):
|
||||||
|
return PeerId(namespace: Namespaces.Peer.CloudGroup, id: chatId)
|
||||||
|
case let .inputPeerChannel(channelId, _):
|
||||||
|
return PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -214,7 +231,9 @@ extension ChatListFilter {
|
|||||||
flags |= 1 << 13
|
flags |= 1 << 13
|
||||||
}
|
}
|
||||||
flags |= self.data.categories.apiFlags
|
flags |= self.data.categories.apiFlags
|
||||||
return .dialogFilter(flags: flags, id: self.id, title: self.title, 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)
|
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||||
}, excludePeers: self.data.excludePeers.compactMap { peerId -> Api.InputPeer? in
|
}, excludePeers: self.data.excludePeers.compactMap { peerId -> Api.InputPeer? in
|
||||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||||
@ -278,27 +297,8 @@ private func requestChatListFilters(postbox: Postbox, network: Network) -> Signa
|
|||||||
let filter = ChatListFilter(apiFilter: apiFilter)
|
let filter = ChatListFilter(apiFilter: apiFilter)
|
||||||
filters.append(filter)
|
filters.append(filter)
|
||||||
switch apiFilter {
|
switch apiFilter {
|
||||||
case let .dialogFilter(_, _, _, includePeers, excludePeers):
|
case let .dialogFilter(_, _, _, pinnedPeers, includePeers, excludePeers):
|
||||||
for peer in includePeers {
|
for peer in pinnedPeers + includePeers + excludePeers {
|
||||||
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 {
|
|
||||||
var peerId: PeerId?
|
var peerId: PeerId?
|
||||||
switch peer {
|
switch peer {
|
||||||
case let .inputPeerUser(userId, _):
|
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> {
|
public func updatedChatListFilters(postbox: Postbox) -> Signal<[ChatListFilter], NoError> {
|
||||||
return postbox.preferencesView(keys: [PreferencesKeys.chatListFilters])
|
return postbox.preferencesView(keys: [PreferencesKeys.chatListFilters])
|
||||||
|> map { preferences -> [ChatListFilter] in
|
|> map { preferences -> [ChatListFilter] in
|
||||||
@ -577,7 +594,8 @@ public struct ChatListFeaturedFilter: PostboxCoding, Equatable {
|
|||||||
excludeRead: decoder.decodeInt32ForKey("excludeRead", orElse: 0) != 0,
|
excludeRead: decoder.decodeInt32ForKey("excludeRead", orElse: 0) != 0,
|
||||||
excludeArchived: decoder.decodeInt32ForKey("excludeArchived", orElse: 0) != 0,
|
excludeArchived: decoder.decodeInt32ForKey("excludeArchived", orElse: 0) != 0,
|
||||||
includePeers: decoder.decodeInt64ArrayForKey("includePeers").map(PeerId.init),
|
includePeers: 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.encodeInt32(self.data.excludeArchived ? 1 : 0, forKey: "excludeArchived")
|
||||||
encoder.encodeInt64Array(self.data.includePeers.map { $0.toInt64() }, forKey: "includePeers")
|
encoder.encodeInt64Array(self.data.includePeers.map { $0.toInt64() }, forKey: "includePeers")
|
||||||
encoder.encodeInt64Array(self.data.excludePeers.map { $0.toInt64() }, forKey: "excludePeers")
|
encoder.encodeInt64Array(self.data.excludePeers.map { $0.toInt64() }, forKey: "excludePeers")
|
||||||
|
encoder.encodeInt64Array(self.data.pinnedPeers.map { $0.toInt64() }, forKey: "pinnedPeers")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,8 +687,6 @@ public func updateChatListFeaturedFilters(postbox: Postbox, network: Network) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
private enum SynchronizeChatListFiltersOperationContentType: Int32 {
|
private enum SynchronizeChatListFiltersOperationContentType: Int32 {
|
||||||
case add
|
|
||||||
case remove
|
|
||||||
case sync
|
case sync
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -681,7 +698,7 @@ private enum SynchronizeChatListFiltersOperationContent: PostboxCoding {
|
|||||||
case SynchronizeChatListFiltersOperationContentType.sync.rawValue:
|
case SynchronizeChatListFiltersOperationContentType.sync.rawValue:
|
||||||
self = .sync
|
self = .sync
|
||||||
default:
|
default:
|
||||||
assertionFailure()
|
//assertionFailure()
|
||||||
self = .sync
|
self = .sync
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,62 +4,132 @@ import SwiftSignalKit
|
|||||||
|
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
|
public enum TogglePeerChatPinnedLocation {
|
||||||
|
case group(PeerGroupId)
|
||||||
|
case filter(Int32)
|
||||||
|
}
|
||||||
|
|
||||||
public enum TogglePeerChatPinnedResult {
|
public enum TogglePeerChatPinnedResult {
|
||||||
case done
|
case done
|
||||||
case limitExceeded(Int)
|
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
|
return postbox.transaction { transaction -> TogglePeerChatPinnedResult in
|
||||||
var itemIds = transaction.getPinnedItemIds(groupId: groupId)
|
switch location {
|
||||||
let sameKind = itemIds.filter { item in
|
case let .group(groupId):
|
||||||
switch itemId {
|
var itemIds = transaction.getPinnedItemIds(groupId: groupId)
|
||||||
case let .peer(lhsPeerId):
|
let sameKind = itemIds.filter { item in
|
||||||
if case let .peer(rhsPeerId) = item {
|
switch itemId {
|
||||||
return (lhsPeerId.namespace == Namespaces.Peer.SecretChat) == (rhsPeerId.namespace == Namespaces.Peer.SecretChat) && lhsPeerId != rhsPeerId
|
case let .peer(lhsPeerId):
|
||||||
} else {
|
if case let .peer(rhsPeerId) = item {
|
||||||
return false
|
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) {
|
||||||
let additionalCount: Int
|
additionalCount = -1
|
||||||
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)
|
|
||||||
} else {
|
} else {
|
||||||
itemIds.insert(itemId, at: 0)
|
additionalCount = 1
|
||||||
}
|
}
|
||||||
addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId)
|
|
||||||
transaction.setPinnedItemIds(groupId: groupId, itemIds: itemIds)
|
let limitsConfiguration = transaction.getPreferencesEntry(key: PreferencesKeys.limitsConfiguration) as? LimitsConfiguration ?? LimitsConfiguration.defaultValue
|
||||||
return .done
|
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 {
|
public func getPinnedItemIds(transaction: Transaction, location: TogglePeerChatPinnedLocation) -> [PinnedItemId] {
|
||||||
if transaction.getPinnedItemIds(groupId: groupId) != itemIds {
|
switch location {
|
||||||
transaction.setPinnedItemIds(groupId: groupId, itemIds: itemIds)
|
case let .group(groupId):
|
||||||
addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId)
|
return transaction.getPinnedItemIds(groupId: groupId)
|
||||||
return true
|
case let .filter(filterId):
|
||||||
} else {
|
var itemIds: [PinnedItemId] = []
|
||||||
return false
|
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 {
|
public func item(context: AccountContext, interaction: ChatListNodeInteraction) -> ListViewItem {
|
||||||
switch self {
|
switch self {
|
||||||
case let .message(message, peer, readState, presentationData):
|
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()
|
super.didLoad()
|
||||||
|
|
||||||
let panRecognizer = InteractiveTransitionGestureRecognizer(target: self, action: #selector(self.panGesture(_:)), allowedDirections: { [weak self] _ in
|
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 []
|
return []
|
||||||
}
|
}
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user