mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Initial implementation of the PSA API
This commit is contained in:
@@ -20,7 +20,7 @@ import ChatListSearchItemNode
|
||||
import ContextUI
|
||||
|
||||
public enum ChatListItemContent {
|
||||
case peer(message: Message?, peer: RenderedPeer, combinedReadState: CombinedPeerReadState?, isRemovedFromTotalUnreadCount: Bool, presence: PeerPresence?, summaryInfo: ChatListMessageTagSummaryInfo, embeddedState: PeerChatListEmbeddedInterfaceState?, inputActivities: [(Peer, PeerInputActivity)]?, isAd: Bool, ignoreUnreadBadge: Bool, displayAsMessage: Bool, hasFailedMessages: Bool)
|
||||
case peer(message: Message?, peer: RenderedPeer, combinedReadState: CombinedPeerReadState?, isRemovedFromTotalUnreadCount: Bool, presence: PeerPresence?, summaryInfo: ChatListMessageTagSummaryInfo, embeddedState: PeerChatListEmbeddedInterfaceState?, inputActivities: [(Peer, PeerInputActivity)]?, promoInfo: ChatListNodeEntryPromoInfo?, ignoreUnreadBadge: Bool, displayAsMessage: Bool, hasFailedMessages: Bool)
|
||||
case groupReference(groupId: PeerGroupId, peers: [ChatListGroupReferencePeer], message: Message?, unreadState: PeerGroupUnreadCountersCombinedSummary, hiddenByDefault: Bool)
|
||||
|
||||
public var chatLocation: ChatLocation? {
|
||||
@@ -124,9 +124,9 @@ public class ChatListItem: ListViewItem, ChatListSearchItemNeighbour {
|
||||
|
||||
public func selected(listView: ListView) {
|
||||
switch self.content {
|
||||
case let .peer(message, peer, _, _, _, _, _, _, isAd, _, _, _):
|
||||
case let .peer(message, peer, _, _, _, _, _, _, promoInfo, _, _, _):
|
||||
if let message = message, let peer = peer.peer {
|
||||
self.interaction.messageSelected(peer, message, isAd)
|
||||
self.interaction.messageSelected(peer, message, promoInfo)
|
||||
} else if let peer = peer.peer {
|
||||
self.interaction.peerSelected(peer)
|
||||
} else if let peer = peer.peers[peer.peerId] {
|
||||
@@ -192,6 +192,7 @@ private enum RevealOptionKey: Int32 {
|
||||
case unarchive
|
||||
case hide
|
||||
case unhide
|
||||
case hidePsa
|
||||
}
|
||||
|
||||
private func canArchivePeer(id: PeerId, accountPeerId: PeerId) -> Bool {
|
||||
@@ -694,23 +695,23 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
let summaryInfo: ChatListMessageTagSummaryInfo
|
||||
let inputActivities: [(Peer, PeerInputActivity)]?
|
||||
let isPeerGroup: Bool
|
||||
let isAd: Bool
|
||||
let promoInfo: ChatListNodeEntryPromoInfo?
|
||||
let displayAsMessage: Bool
|
||||
let hasFailedMessages: Bool
|
||||
|
||||
var groupHiddenByDefault = false
|
||||
|
||||
switch item.content {
|
||||
case let .peer(messageValue, peerValue, combinedReadStateValue, isRemovedFromTotalUnreadCountValue, peerPresenceValue, summaryInfoValue, embeddedStateValue, inputActivitiesValue, isAdValue, ignoreUnreadBadge, displayAsMessageValue, hasFailedMessagesValue):
|
||||
case let .peer(messageValue, peerValue, combinedReadStateValue, isRemovedFromTotalUnreadCountValue, peerPresenceValue, summaryInfoValue, embeddedStateValue, inputActivitiesValue, promoInfoValue, ignoreUnreadBadge, displayAsMessageValue, hasFailedMessagesValue):
|
||||
message = messageValue
|
||||
contentPeer = .chat(peerValue)
|
||||
combinedReadState = combinedReadStateValue
|
||||
if let combinedReadState = combinedReadState, !isAdValue && !ignoreUnreadBadge {
|
||||
if let combinedReadState = combinedReadState, promoInfoValue == nil && !ignoreUnreadBadge {
|
||||
unreadCount = (combinedReadState.count, combinedReadState.isUnread, isRemovedFromTotalUnreadCountValue, nil)
|
||||
} else {
|
||||
unreadCount = (0, false, false, nil)
|
||||
}
|
||||
if isAdValue {
|
||||
if let _ = promoInfoValue {
|
||||
isRemovedFromTotalUnreadCount = false
|
||||
} else {
|
||||
isRemovedFromTotalUnreadCount = isRemovedFromTotalUnreadCountValue
|
||||
@@ -722,7 +723,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
summaryInfo = summaryInfoValue
|
||||
inputActivities = inputActivitiesValue
|
||||
isPeerGroup = false
|
||||
isAd = isAdValue
|
||||
promoInfo = promoInfoValue
|
||||
displayAsMessage = displayAsMessageValue
|
||||
hasFailedMessages = messageValue?.flags.contains(.Failed) ?? false // hasFailedMessagesValue
|
||||
case let .groupReference(_, peers, messageValue, unreadState, hiddenByDefault):
|
||||
@@ -742,7 +743,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
let allCount = unreadState.count(countingCategory: .chats, mutedCategory: .all)
|
||||
unreadCount = (allCount, allCount != 0, true, nil)
|
||||
peerPresence = nil
|
||||
isAd = false
|
||||
promoInfo = nil
|
||||
displayAsMessage = false
|
||||
hasFailedMessages = false
|
||||
}
|
||||
@@ -786,12 +787,12 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
var reorderInset: CGFloat = 0.0
|
||||
if item.editing {
|
||||
let sizeAndApply = selectableControlLayout(item.presentationData.theme.list.itemCheckColors.strokeColor, item.presentationData.theme.list.itemCheckColors.fillColor, item.presentationData.theme.list.itemCheckColors.foregroundColor, item.selected, true)
|
||||
if !isAd && !isPeerGroup {
|
||||
if promoInfo == nil && !isPeerGroup {
|
||||
selectableControlSizeAndApply = sizeAndApply
|
||||
}
|
||||
editingOffset = sizeAndApply.0
|
||||
|
||||
if item.index.pinningIndex != nil && !isAd && !isPeerGroup {
|
||||
if item.index.pinningIndex != nil && promoInfo == nil && !isPeerGroup {
|
||||
let sizeAndApply = reorderControlLayout(item.presentationData.theme)
|
||||
reorderControlSizeAndApply = sizeAndApply
|
||||
reorderInset = sizeAndApply.0
|
||||
@@ -819,7 +820,13 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
var hideAuthor = false
|
||||
switch contentPeer {
|
||||
case let .chat(itemPeer):
|
||||
let (peer, initialHideAuthor, messageText) = chatListItemStrings(strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, message: message, chatPeer: itemPeer, accountPeerId: item.context.account.peerId, enableMediaEmoji: !enableChatListPhotos, isPeerGroup: isPeerGroup)
|
||||
var (peer, initialHideAuthor, messageText) = chatListItemStrings(strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, message: message, chatPeer: itemPeer, accountPeerId: item.context.account.peerId, enableMediaEmoji: !enableChatListPhotos, isPeerGroup: isPeerGroup)
|
||||
|
||||
if case let .psa(_, maybePsaText) = promoInfo, let psaText = maybePsaText {
|
||||
initialHideAuthor = true
|
||||
messageText = psaText
|
||||
}
|
||||
|
||||
contentData = .chat(itemPeer: itemPeer, peer: peer, hideAuthor: hideAuthor, messageText: messageText)
|
||||
hideAuthor = initialHideAuthor
|
||||
case let .group(groupPeers):
|
||||
@@ -995,8 +1002,13 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
|
||||
if isPeerGroup {
|
||||
dateAttributedString = NSAttributedString(string: "", font: dateFont, textColor: theme.dateTextColor)
|
||||
} else if isAd {
|
||||
dateAttributedString = NSAttributedString(string: item.presentationData.strings.DialogList_AdLabel, font: dateFont, textColor: theme.dateTextColor)
|
||||
} else if let promoInfo = promoInfo {
|
||||
switch promoInfo {
|
||||
case .proxy:
|
||||
dateAttributedString = NSAttributedString(string: item.presentationData.strings.DialogList_AdLabel, font: dateFont, textColor: theme.dateTextColor)
|
||||
case .psa:
|
||||
dateAttributedString = NSAttributedString(string: item.presentationData.strings.DialogList_PsaLabel, font: dateFont, textColor: theme.dateTextColor)
|
||||
}
|
||||
} else {
|
||||
dateAttributedString = NSAttributedString(string: dateText, font: dateFont, textColor: theme.dateTextColor)
|
||||
}
|
||||
@@ -1056,7 +1068,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
currentMentionBadgeImage = PresentationResourcesChatList.badgeBackgroundMention(item.presentationData.theme, diameter: badgeDiameter)
|
||||
}
|
||||
mentionBadgeContent = .mention
|
||||
} else if item.index.pinningIndex != nil && !isAd && currentBadgeBackgroundImage == nil {
|
||||
} else if item.index.pinningIndex != nil && promoInfo == nil && currentBadgeBackgroundImage == nil {
|
||||
currentPinnedIconImage = PresentationResourcesChatList.badgeBackgroundPinned(item.presentationData.theme, diameter: badgeDiameter)
|
||||
}
|
||||
}
|
||||
@@ -1192,11 +1204,21 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
|
||||
let isPinned = item.index.pinningIndex != nil
|
||||
|
||||
if item.enableContextActions && !isAd {
|
||||
peerRevealOptions = revealOptions(strings: item.presentationData.strings, theme: item.presentationData.theme, isPinned: isPinned, isMuted: item.context.account.peerId != item.index.messageIndex.id.peerId ? (currentMutedIconImage != nil) : nil, groupId: item.peerGroupId, peerId: renderedPeer.peerId, accountPeerId: item.context.account.peerId, canDelete: true, isEditing: item.editing, filterData: item.filterData)
|
||||
if case let .chat(itemPeer) = contentPeer {
|
||||
peerLeftRevealOptions = leftRevealOptions(strings: item.presentationData.strings, theme: item.presentationData.theme, isUnread: unreadCount.unread, isEditing: item.editing, isPinned: isPinned, isSavedMessages: itemPeer.peerId == item.context.account.peerId, groupId: item.peerGroupId, filterData: item.filterData)
|
||||
if item.enableContextActions {
|
||||
if case .psa = promoInfo {
|
||||
peerRevealOptions = [
|
||||
ItemListRevealOption(key: RevealOptionKey.hidePsa.rawValue, title: item.presentationData.strings.ChatList_HideAction, icon: hideIcon, color: item.presentationData.theme.list.itemDisclosureActions.inactive.fillColor, textColor: item.presentationData.theme.list.itemDisclosureActions.neutral1.foregroundColor)
|
||||
]
|
||||
peerLeftRevealOptions = []
|
||||
} else if promoInfo == nil {
|
||||
peerRevealOptions = revealOptions(strings: item.presentationData.strings, theme: item.presentationData.theme, isPinned: isPinned, isMuted: item.context.account.peerId != item.index.messageIndex.id.peerId ? (currentMutedIconImage != nil) : nil, groupId: item.peerGroupId, peerId: renderedPeer.peerId, accountPeerId: item.context.account.peerId, canDelete: true, isEditing: item.editing, filterData: item.filterData)
|
||||
if case let .chat(itemPeer) = contentPeer {
|
||||
peerLeftRevealOptions = leftRevealOptions(strings: item.presentationData.strings, theme: item.presentationData.theme, isUnread: unreadCount.unread, isEditing: item.editing, isPinned: isPinned, isSavedMessages: itemPeer.peerId == item.context.account.peerId, groupId: item.peerGroupId, filterData: item.filterData)
|
||||
} else {
|
||||
peerLeftRevealOptions = []
|
||||
}
|
||||
} else {
|
||||
peerRevealOptions = []
|
||||
peerLeftRevealOptions = []
|
||||
}
|
||||
} else {
|
||||
@@ -1839,6 +1861,17 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
case RevealOptionKey.unhide.rawValue:
|
||||
item.interaction.toggleArchivedFolderHiddenByDefault()
|
||||
close = false
|
||||
case RevealOptionKey.hidePsa.rawValue:
|
||||
if let item = self.item, case let .peer(message, _, _, _, _, _, _, _, _, _, _, _) = item.content {
|
||||
if let message = message {
|
||||
item.interaction.hidePsa(message.id)
|
||||
}
|
||||
}
|
||||
close = false
|
||||
self.skipFadeout = true
|
||||
self.animateRevealOptionsFill {
|
||||
self.revealOptionsInteractivelyClosed()
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public final class ChatListNodeInteraction {
|
||||
let disabledPeerSelected: (Peer) -> Void
|
||||
let togglePeerSelected: (PeerId) -> Void
|
||||
let additionalCategorySelected: (Int) -> Void
|
||||
let messageSelected: (Peer, Message, Bool) -> Void
|
||||
let messageSelected: (Peer, Message, ChatListNodeEntryPromoInfo?) -> Void
|
||||
let groupSelected: (PeerGroupId) -> Void
|
||||
let addContact: (String) -> Void
|
||||
let setPeerIdWithRevealedOptions: (PeerId?, PeerId?) -> Void
|
||||
@@ -63,13 +63,14 @@ public final class ChatListNodeInteraction {
|
||||
let updatePeerGrouping: (PeerId, Bool) -> Void
|
||||
let togglePeerMarkedUnread: (PeerId, Bool) -> Void
|
||||
let toggleArchivedFolderHiddenByDefault: () -> Void
|
||||
let hidePsa: (MessageId) -> Void
|
||||
let activateChatPreview: (ChatListItem, ASDisplayNode, ContextGesture?) -> Void
|
||||
let present: (ViewController) -> Void
|
||||
|
||||
public var searchTextHighightState: String?
|
||||
var highlightedChatLocation: ChatListHighlightedLocation?
|
||||
|
||||
public init(activateSearch: @escaping () -> Void, peerSelected: @escaping (Peer) -> Void, disabledPeerSelected: @escaping (Peer) -> Void, togglePeerSelected: @escaping (PeerId) -> Void, additionalCategorySelected: @escaping (Int) -> Void, messageSelected: @escaping (Peer, Message, Bool) -> Void, groupSelected: @escaping (PeerGroupId) -> Void, addContact: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, setItemPinned: @escaping (PinnedItemId, Bool) -> Void, setPeerMuted: @escaping (PeerId, Bool) -> Void, deletePeer: @escaping (PeerId) -> Void, updatePeerGrouping: @escaping (PeerId, Bool) -> Void, togglePeerMarkedUnread: @escaping (PeerId, Bool) -> Void, toggleArchivedFolderHiddenByDefault: @escaping () -> Void, activateChatPreview: @escaping (ChatListItem, ASDisplayNode, ContextGesture?) -> Void, present: @escaping (ViewController) -> Void) {
|
||||
public init(activateSearch: @escaping () -> Void, peerSelected: @escaping (Peer) -> Void, disabledPeerSelected: @escaping (Peer) -> Void, togglePeerSelected: @escaping (PeerId) -> Void, additionalCategorySelected: @escaping (Int) -> Void, messageSelected: @escaping (Peer, Message, ChatListNodeEntryPromoInfo?) -> Void, groupSelected: @escaping (PeerGroupId) -> Void, addContact: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, setItemPinned: @escaping (PinnedItemId, Bool) -> Void, setPeerMuted: @escaping (PeerId, Bool) -> Void, deletePeer: @escaping (PeerId) -> Void, updatePeerGrouping: @escaping (PeerId, Bool) -> Void, togglePeerMarkedUnread: @escaping (PeerId, Bool) -> Void, toggleArchivedFolderHiddenByDefault: @escaping () -> Void, hidePsa: @escaping (MessageId) -> Void, activateChatPreview: @escaping (ChatListItem, ASDisplayNode, ContextGesture?) -> Void, present: @escaping (ViewController) -> Void) {
|
||||
self.activateSearch = activateSearch
|
||||
self.peerSelected = peerSelected
|
||||
self.disabledPeerSelected = disabledPeerSelected
|
||||
@@ -85,6 +86,7 @@ public final class ChatListNodeInteraction {
|
||||
self.updatePeerGrouping = updatePeerGrouping
|
||||
self.togglePeerMarkedUnread = togglePeerMarkedUnread
|
||||
self.toggleArchivedFolderHiddenByDefault = toggleArchivedFolderHiddenByDefault
|
||||
self.hidePsa = hidePsa
|
||||
self.activateChatPreview = activateChatPreview
|
||||
self.present = present
|
||||
}
|
||||
@@ -108,8 +110,9 @@ public struct ChatListNodeState: Equatable {
|
||||
public var pendingClearHistoryPeerIds: Set<PeerId>
|
||||
public var archiveShouldBeTemporaryRevealed: Bool
|
||||
public var selectedAdditionalCategoryIds: Set<Int>
|
||||
public var hiddenPsaPeerId: PeerId?
|
||||
|
||||
public init(presentationData: ChatListPresentationData, editing: Bool, peerIdWithRevealedOptions: PeerId?, selectedPeerIds: Set<PeerId>, selectedAdditionalCategoryIds: Set<Int>, peerInputActivities: ChatListNodePeerInputActivities?, pendingRemovalPeerIds: Set<PeerId>, pendingClearHistoryPeerIds: Set<PeerId>, archiveShouldBeTemporaryRevealed: Bool) {
|
||||
public init(presentationData: ChatListPresentationData, editing: Bool, peerIdWithRevealedOptions: PeerId?, selectedPeerIds: Set<PeerId>, selectedAdditionalCategoryIds: Set<Int>, peerInputActivities: ChatListNodePeerInputActivities?, pendingRemovalPeerIds: Set<PeerId>, pendingClearHistoryPeerIds: Set<PeerId>, archiveShouldBeTemporaryRevealed: Bool, hiddenPsaPeerId: PeerId?) {
|
||||
self.presentationData = presentationData
|
||||
self.editing = editing
|
||||
self.peerIdWithRevealedOptions = peerIdWithRevealedOptions
|
||||
@@ -119,6 +122,7 @@ public struct ChatListNodeState: Equatable {
|
||||
self.pendingRemovalPeerIds = pendingRemovalPeerIds
|
||||
self.pendingClearHistoryPeerIds = pendingClearHistoryPeerIds
|
||||
self.archiveShouldBeTemporaryRevealed = archiveShouldBeTemporaryRevealed
|
||||
self.hiddenPsaPeerId = hiddenPsaPeerId
|
||||
}
|
||||
|
||||
public static func ==(lhs: ChatListNodeState, rhs: ChatListNodeState) -> Bool {
|
||||
@@ -149,6 +153,9 @@ public struct ChatListNodeState: Equatable {
|
||||
if lhs.archiveShouldBeTemporaryRevealed != rhs.archiveShouldBeTemporaryRevealed {
|
||||
return false
|
||||
}
|
||||
if lhs.hiddenPsaPeerId != rhs.hiddenPsaPeerId {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -169,10 +176,10 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL
|
||||
nodeInteraction.additionalCategorySelected(id)
|
||||
}
|
||||
), directionHint: entry.directionHint)
|
||||
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, promoInfo, hasFailedMessages, isContact):
|
||||
switch mode {
|
||||
case .chatList:
|
||||
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)
|
||||
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, promoInfo: promoInfo, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: hasFailedMessages), editing: editing, hasActiveRevealControls: hasActiveRevealControls, selected: selected, header: nil, enableContextActions: true, hiddenOffset: false, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
case let .peers(filter, isSelecting, _):
|
||||
let itemPeer = peer.chatMainPeer
|
||||
var chatPeer: Peer?
|
||||
@@ -280,10 +287,10 @@ private func mappedInsertEntries(context: AccountContext, nodeInteraction: ChatL
|
||||
private func mappedUpdateEntries(context: AccountContext, nodeInteraction: ChatListNodeInteraction, peerGroupId: PeerGroupId, filterData: ChatListItemFilterData?, mode: ChatListNodeMode, entries: [ChatListNodeViewTransitionUpdateEntry]) -> [ListViewUpdateItem] {
|
||||
return entries.map { entry -> ListViewUpdateItem in
|
||||
switch entry.entry {
|
||||
case let .PeerEntry(index, presentationData, message, combinedReadState, isRemovedFromTotalUnreadCount, embeddedState, peer, presence, summaryInfo, editing, hasActiveRevealControls, selected, inputActivities, isAd, hasFailedMessages, isContact):
|
||||
case let .PeerEntry(index, presentationData, message, combinedReadState, isRemovedFromTotalUnreadCount, embeddedState, peer, presence, summaryInfo, editing, hasActiveRevealControls, selected, inputActivities, promoInfo, hasFailedMessages, isContact):
|
||||
switch mode {
|
||||
case .chatList:
|
||||
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)
|
||||
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, promoInfo: promoInfo, ignoreUnreadBadge: false, displayAsMessage: false, hasFailedMessages: hasFailedMessages), editing: editing, hasActiveRevealControls: hasActiveRevealControls, selected: selected, header: nil, enableContextActions: true, hiddenOffset: false, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
case let .peers(filter, isSelecting, _):
|
||||
let itemPeer = peer.chatMainPeer
|
||||
var chatPeer: Peer?
|
||||
@@ -411,7 +418,7 @@ public final class ChatListNode: ListView {
|
||||
return _contentsReady.get()
|
||||
}
|
||||
|
||||
public var peerSelected: ((Peer, Bool, Bool) -> Void)?
|
||||
public var peerSelected: ((Peer, Bool, ChatListNodeEntryPromoInfo?) -> Void)?
|
||||
public var disabledPeerSelected: ((Peer) -> Void)?
|
||||
public var additionalCategorySelected: ((Int) -> Void)?
|
||||
public var groupSelected: ((PeerGroupId) -> Void)?
|
||||
@@ -422,6 +429,7 @@ public final class ChatListNode: ListView {
|
||||
public var presentAlert: ((String) -> Void)?
|
||||
public var present: ((ViewController) -> Void)?
|
||||
public var toggleArchivedFolderHiddenByDefault: (() -> Void)?
|
||||
public var hidePsa: ((MessageId) -> Void)?
|
||||
public var activateChatPreview: ((ChatListItem, ASDisplayNode, ContextGesture?) -> Void)?
|
||||
|
||||
private var theme: PresentationTheme
|
||||
@@ -510,7 +518,7 @@ public final class ChatListNode: ListView {
|
||||
isSelecting = true
|
||||
}
|
||||
|
||||
self.currentState = ChatListNodeState(presentationData: ChatListPresentationData(theme: theme, fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, disableAnimations: disableAnimations), editing: isSelecting, peerIdWithRevealedOptions: nil, selectedPeerIds: Set(), selectedAdditionalCategoryIds: Set(), peerInputActivities: nil, pendingRemovalPeerIds: Set(), pendingClearHistoryPeerIds: Set(), archiveShouldBeTemporaryRevealed: false)
|
||||
self.currentState = ChatListNodeState(presentationData: ChatListPresentationData(theme: theme, fontSize: fontSize, strings: strings, dateTimeFormat: dateTimeFormat, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, disableAnimations: disableAnimations), editing: isSelecting, peerIdWithRevealedOptions: nil, selectedPeerIds: Set(), selectedAdditionalCategoryIds: Set(), peerInputActivities: nil, pendingRemovalPeerIds: Set(), pendingClearHistoryPeerIds: Set(), archiveShouldBeTemporaryRevealed: false, hiddenPsaPeerId: nil)
|
||||
self.statePromise = ValuePromise(self.currentState, ignoreRepeated: true)
|
||||
|
||||
self.theme = theme
|
||||
@@ -528,7 +536,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
}, peerSelected: { [weak self] peer in
|
||||
if let strongSelf = self, let peerSelected = strongSelf.peerSelected {
|
||||
peerSelected(peer, true, false)
|
||||
peerSelected(peer, true, nil)
|
||||
}
|
||||
}, disabledPeerSelected: { [weak self] peer in
|
||||
if let strongSelf = self, let disabledPeerSelected = strongSelf.disabledPeerSelected {
|
||||
@@ -555,9 +563,9 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
}, additionalCategorySelected: { [weak self] id in
|
||||
self?.additionalCategorySelected?(id)
|
||||
}, messageSelected: { [weak self] peer, message, isAd in
|
||||
}, messageSelected: { [weak self] peer, message, promoInfo in
|
||||
if let strongSelf = self, let peerSelected = strongSelf.peerSelected {
|
||||
peerSelected(peer, true, isAd)
|
||||
peerSelected(peer, true, promoInfo)
|
||||
}
|
||||
}, groupSelected: { [weak self] groupId in
|
||||
if let strongSelf = self, let groupSelected = strongSelf.groupSelected {
|
||||
@@ -634,6 +642,8 @@ public final class ChatListNode: ListView {
|
||||
})
|
||||
}, toggleArchivedFolderHiddenByDefault: { [weak self] in
|
||||
self?.toggleArchivedFolderHiddenByDefault?()
|
||||
}, hidePsa: { [weak self] id in
|
||||
self?.hidePsa?(id)
|
||||
}, activateChatPreview: { [weak self] item, node, gesture in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
@@ -1064,8 +1074,8 @@ public final class ChatListNode: ListView {
|
||||
var referenceId: PinnedItemId?
|
||||
var beforeAll = false
|
||||
switch toEntry {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, isAd, _, _):
|
||||
if isAd {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, promoInfo, _, _):
|
||||
if promoInfo != nil {
|
||||
beforeAll = true
|
||||
} else {
|
||||
referenceId = .peer(index.messageIndex.id.peerId)
|
||||
@@ -1327,8 +1337,8 @@ public final class ChatListNode: ListView {
|
||||
if transition.chatListView.originalView.laterIndex == nil {
|
||||
for entry in filteredEntries.reversed() {
|
||||
switch entry {
|
||||
case let .PeerEntry(index, _, _, combinedReadState, isMuted, _, _, _, _, _, _, _, _, isAd, _, _):
|
||||
if !isAd {
|
||||
case let .PeerEntry(index, _, _, combinedReadState, isMuted, _, _, _, _, _, _, _, _, promoInfo, _, _):
|
||||
if promoInfo == nil {
|
||||
var hasUnread = false
|
||||
if let combinedReadState = combinedReadState {
|
||||
hasUnread = combinedReadState.count > 0
|
||||
@@ -1693,7 +1703,7 @@ public final class ChatListNode: ListView {
|
||||
}
|
||||
let location: ChatListNodeLocation = .scroll(index: index, sourceIndex: strongSelf.currentlyVisibleLatestChatListIndex() ?? .absoluteUpperBound, scrollPosition: .center(.top), animated: true, filter: strongSelf.chatListFilter)
|
||||
strongSelf.setChatListLocation(location)
|
||||
strongSelf.peerSelected?(peer, false, false)
|
||||
strongSelf.peerSelected?(peer, false, nil)
|
||||
})
|
||||
case .previous(unread: false), .next(unread: false):
|
||||
var target: (ChatListIndex, Peer)? = nil
|
||||
@@ -1717,7 +1727,7 @@ public final class ChatListNode: ListView {
|
||||
if let target = target {
|
||||
let location: ChatListNodeLocation = .scroll(index: target.0, sourceIndex: .absoluteLowerBound, scrollPosition: .center(.top), animated: true, filter: self.chatListFilter)
|
||||
self.setChatListLocation(location)
|
||||
self.peerSelected?(target.1, false, false)
|
||||
self.peerSelected?(target.1, false, nil)
|
||||
}
|
||||
case let .peerId(peerId):
|
||||
let _ = (self.context.account.postbox.transaction { transaction -> Peer? in
|
||||
@@ -1727,7 +1737,7 @@ public final class ChatListNode: ListView {
|
||||
guard let strongSelf = self, let peer = peer else {
|
||||
return
|
||||
}
|
||||
strongSelf.peerSelected?(peer, false, false)
|
||||
strongSelf.peerSelected?(peer, false, nil)
|
||||
})
|
||||
case let .index(index):
|
||||
guard index < 10 else {
|
||||
@@ -1746,7 +1756,7 @@ public final class ChatListNode: ListView {
|
||||
if entries.count > index, case let .MessageEntry(index, _, _, _, _, renderedPeer, _, _, _, _) = entries[10 - index - 1] {
|
||||
let location: ChatListNodeLocation = .scroll(index: index, sourceIndex: .absoluteLowerBound, scrollPosition: .center(.top), animated: true, filter: filter)
|
||||
self.setChatListLocation(location)
|
||||
self.peerSelected?(renderedPeer.peer!, false, false)
|
||||
self.peerSelected?(renderedPeer.peer!, false, nil)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -39,9 +39,14 @@ enum ChatListNodeEntrySortIndex: Comparable {
|
||||
}
|
||||
}
|
||||
|
||||
public enum ChatListNodeEntryPromoInfo: Equatable {
|
||||
case proxy
|
||||
case psa(type: String, message: String?)
|
||||
}
|
||||
|
||||
enum ChatListNodeEntry: Comparable, Identifiable {
|
||||
case HeaderEntry
|
||||
case PeerEntry(index: ChatListIndex, presentationData: ChatListPresentationData, message: Message?, readState: CombinedPeerReadState?, isRemovedFromTotalUnreadCount: Bool, embeddedInterfaceState: PeerChatListEmbeddedInterfaceState?, peer: RenderedPeer, presence: PeerPresence?, summaryInfo: ChatListMessageTagSummaryInfo, editing: Bool, hasActiveRevealControls: Bool, selected: Bool, inputActivities: [(Peer, PeerInputActivity)]?, isAd: Bool, hasFailedMessages: Bool, isContact: Bool)
|
||||
case PeerEntry(index: ChatListIndex, presentationData: ChatListPresentationData, message: Message?, readState: CombinedPeerReadState?, isRemovedFromTotalUnreadCount: Bool, embeddedInterfaceState: PeerChatListEmbeddedInterfaceState?, peer: RenderedPeer, presence: PeerPresence?, summaryInfo: ChatListMessageTagSummaryInfo, editing: Bool, hasActiveRevealControls: Bool, selected: Bool, inputActivities: [(Peer, PeerInputActivity)]?, promoInfo: ChatListNodeEntryPromoInfo?, hasFailedMessages: Bool, isContact: Bool)
|
||||
case HoleEntry(ChatListHole, theme: PresentationTheme)
|
||||
case GroupReferenceEntry(index: ChatListIndex, presentationData: ChatListPresentationData, groupId: PeerGroupId, peers: [ChatListGroupReferencePeer], message: Message?, editing: Bool, unreadState: PeerGroupUnreadCountersCombinedSummary, revealed: Bool, hiddenByDefault: Bool)
|
||||
case ArchiveIntro(presentationData: ChatListPresentationData)
|
||||
@@ -280,8 +285,12 @@ func chatListNodeEntriesForView(_ view: ChatListView, state: ChatListNodeState,
|
||||
pinnedIndexOffset += UInt16(groupEntryCount)
|
||||
}
|
||||
|
||||
let filteredAdditionalItemEntries = view.additionalItemEntries.filter { item -> Bool in
|
||||
return item.info.peerId != state.hiddenPsaPeerId
|
||||
}
|
||||
|
||||
if view.laterIndex == nil && savedMessagesPeer == nil {
|
||||
pinnedIndexOffset += UInt16(view.additionalItemEntries.count)
|
||||
pinnedIndexOffset += UInt16(filteredAdditionalItemEntries.count)
|
||||
}
|
||||
var filterAfterHole = false
|
||||
loop: for entry in view.entries {
|
||||
@@ -299,7 +308,7 @@ func chatListNodeEntriesForView(_ view: ChatListView, state: ChatListNodeState,
|
||||
updatedMessage = nil
|
||||
updatedCombinedReadState = nil
|
||||
}
|
||||
result.append(.PeerEntry(index: offsetPinnedIndex(index, offset: pinnedIndexOffset), presentationData: state.presentationData, message: updatedMessage, readState: updatedCombinedReadState, isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount, embeddedInterfaceState: embeddedState, peer: peer, presence: peerPresence, summaryInfo: summaryInfo, editing: state.editing, hasActiveRevealControls: index.messageIndex.id.peerId == state.peerIdWithRevealedOptions, selected: state.selectedPeerIds.contains(index.messageIndex.id.peerId), inputActivities: state.peerInputActivities?.activities[index.messageIndex.id.peerId], isAd: false, hasFailedMessages: hasFailed, isContact: isContact))
|
||||
result.append(.PeerEntry(index: offsetPinnedIndex(index, offset: pinnedIndexOffset), presentationData: state.presentationData, message: updatedMessage, readState: updatedCombinedReadState, isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount, embeddedInterfaceState: embeddedState, peer: peer, presence: peerPresence, summaryInfo: summaryInfo, editing: state.editing, hasActiveRevealControls: index.messageIndex.id.peerId == state.peerIdWithRevealedOptions, selected: state.selectedPeerIds.contains(index.messageIndex.id.peerId), inputActivities: state.peerInputActivities?.activities[index.messageIndex.id.peerId], promoInfo: nil, hasFailedMessages: hasFailed, isContact: isContact))
|
||||
case let .HoleEntry(hole):
|
||||
if hole.index.timestamp == Int32.max - 1 {
|
||||
//return ([.HeaderEntry], true)
|
||||
@@ -312,13 +321,23 @@ func chatListNodeEntriesForView(_ view: ChatListView, state: ChatListNodeState,
|
||||
var pinningIndex: UInt16 = UInt16(pinnedIndexOffset == 0 ? 0 : (pinnedIndexOffset - 1))
|
||||
|
||||
if let savedMessagesPeer = savedMessagesPeer {
|
||||
result.append(.PeerEntry(index: ChatListIndex.absoluteUpperBound.predecessor, presentationData: state.presentationData, message: nil, readState: nil, isRemovedFromTotalUnreadCount: false, embeddedInterfaceState: nil, peer: RenderedPeer(peerId: savedMessagesPeer.id, peers: SimpleDictionary([savedMessagesPeer.id: savedMessagesPeer])), presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(), editing: state.editing, hasActiveRevealControls: false, selected: false, inputActivities: nil, isAd: false, hasFailedMessages: false, isContact: false))
|
||||
result.append(.PeerEntry(index: ChatListIndex.absoluteUpperBound.predecessor, presentationData: state.presentationData, message: nil, readState: nil, isRemovedFromTotalUnreadCount: false, embeddedInterfaceState: nil, peer: RenderedPeer(peerId: savedMessagesPeer.id, peers: SimpleDictionary([savedMessagesPeer.id: savedMessagesPeer])), presence: nil, summaryInfo: ChatListMessageTagSummaryInfo(), editing: state.editing, hasActiveRevealControls: false, selected: false, inputActivities: nil, promoInfo: nil, hasFailedMessages: false, isContact: false))
|
||||
} else {
|
||||
if !view.additionalItemEntries.isEmpty {
|
||||
for entry in view.additionalItemEntries.reversed() {
|
||||
switch entry {
|
||||
if !filteredAdditionalItemEntries.isEmpty {
|
||||
for item in filteredAdditionalItemEntries.reversed() {
|
||||
guard let info = item.info as? PromoChatListItem else {
|
||||
continue
|
||||
}
|
||||
let promoInfo: ChatListNodeEntryPromoInfo
|
||||
switch info.kind {
|
||||
case .proxy:
|
||||
promoInfo = .proxy
|
||||
case let .psa(type, message):
|
||||
promoInfo = .psa(type: type, message: message)
|
||||
}
|
||||
switch item.entry {
|
||||
case let .MessageEntry(index, message, combinedReadState, isRemovedFromTotalUnreadCount, embeddedState, peer, peerPresence, summaryInfo, hasFailed, isContact):
|
||||
result.append(.PeerEntry(index: ChatListIndex(pinningIndex: pinningIndex, messageIndex: index.messageIndex), presentationData: state.presentationData, message: message, readState: combinedReadState, isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount, embeddedInterfaceState: embeddedState, peer: peer, presence: peerPresence, summaryInfo: summaryInfo, editing: state.editing, hasActiveRevealControls: index.messageIndex.id.peerId == state.peerIdWithRevealedOptions, selected: state.selectedPeerIds.contains(index.messageIndex.id.peerId), inputActivities: state.peerInputActivities?.activities[index.messageIndex.id.peerId], isAd: true, hasFailedMessages: hasFailed, isContact: isContact))
|
||||
result.append(.PeerEntry(index: ChatListIndex(pinningIndex: pinningIndex, messageIndex: index.messageIndex), presentationData: state.presentationData, message: message, readState: combinedReadState, isRemovedFromTotalUnreadCount: isRemovedFromTotalUnreadCount, embeddedInterfaceState: embeddedState, peer: peer, presence: peerPresence, summaryInfo: summaryInfo, editing: state.editing, hasActiveRevealControls: index.messageIndex.id.peerId == state.peerIdWithRevealedOptions, selected: state.selectedPeerIds.contains(index.messageIndex.id.peerId), inputActivities: state.peerInputActivities?.activities[index.messageIndex.id.peerId], promoInfo: promoInfo, hasFailedMessages: hasFailed, isContact: isContact))
|
||||
if pinningIndex != 0 {
|
||||
pinningIndex -= 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user