diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 13f16193c1..9f490731be 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -8269,8 +8269,8 @@ Sorry for the inconvenience."; "EmojiSearch.SearchTopicIconsPlaceholder" = "Search Topic Icons"; "EmojiSearch.SearchTopicIconsEmptyResult" = "No emoji found"; -"Username.UsernamePurchaseAvailable" = "**This username is already taken.** However, it is being resold via auction. [Learn more...]()"; -"Channel.Username.UsernamePurchaseAvailable" = "**This username is already taken.** However, it is being resold via auction. [Learn more...]()"; +"Username.UsernamePurchaseAvailable" = "**This username is already taken.** However, it is currently available for purchase. [Learn more...]()"; +"Channel.Username.UsernamePurchaseAvailable" = "**This username is already taken.** However, it is currently available for purchase. [Learn more...]()"; "DownloadList.IncreaseSpeed" = "Increase Speed"; "Conversation.IncreaseSpeed" = "Increase Speed"; diff --git a/submodules/GalleryUI/Sources/GalleryTitleView.swift b/submodules/GalleryUI/Sources/GalleryTitleView.swift index 661b1ffbc2..d30da98d38 100644 --- a/submodules/GalleryUI/Sources/GalleryTitleView.swift +++ b/submodules/GalleryUI/Sources/GalleryTitleView.swift @@ -34,7 +34,7 @@ final class GalleryTitleView: UIView, NavigationBarTitleView { } func setMessage(_ message: Message, presentationData: PresentationData, accountPeerId: PeerId) { - let authorNameText = stringForFullAuthorName(message: EngineMessage(message), strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder, accountPeerId: accountPeerId) + let authorNameText = stringForFullAuthorName(message: EngineMessage(message), strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder, accountPeerId: accountPeerId).joined(separator: " → ") let dateText = humanReadableStringForTimestamp(strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, timestamp: message.timestamp).string self.authorNameNode.attributedText = NSAttributedString(string: authorNameText, font: titleFont, textColor: .white) diff --git a/submodules/ListMessageItem/Sources/ListMessageFileItemNode.swift b/submodules/ListMessageItem/Sources/ListMessageFileItemNode.swift index 3b6186dab0..398c452402 100644 --- a/submodules/ListMessageItem/Sources/ListMessageFileItemNode.swift +++ b/submodules/ListMessageItem/Sources/ListMessageFileItemNode.swift @@ -192,7 +192,7 @@ public final class ListMessageFileItemNode: ListMessageNode { self.addSubnode(self.descriptionNode) } - func asyncLayout() -> (_ context: AccountContext, _ constrainedWidth: CGFloat, _ theme: PresentationTheme, _ authorTitle: NSAttributedString?, _ topic: (title: NSAttributedString, iconId: Int64?, iconColor: Int32)?) -> (CGSize, () -> Void) { + func asyncLayout() -> (_ context: AccountContext, _ constrainedWidth: CGFloat, _ theme: PresentationTheme, _ authorTitle: NSAttributedString?, _ topic: (title: NSAttributedString, showIcon: Bool, iconId: Int64?, iconColor: Int32)?) -> (CGSize, () -> Void) { let makeDescriptionLayout = TextNode.asyncLayout(self.descriptionNode) let makeTopicTitleLayout = TextNode.asyncLayout(self.topicTitleNode) @@ -212,7 +212,7 @@ public final class ListMessageFileItemNode: ListMessageNode { remainingWidth -= 22.0 + 2.0 if authorTitle != nil { - arrowIconImage = PresentationResourcesChatList.topicArrowIcon(theme) + arrowIconImage = PresentationResourcesItemList.topicArrowDescriptionIcon(theme) if let arrowIconImage = arrowIconImage { remainingWidth -= arrowIconImage.size.width + 6.0 * 2.0 } @@ -263,7 +263,7 @@ public final class ListMessageFileItemNode: ListMessageNode { } } - if let topic { + if let topic, topic.showIcon { let titleTopicIconView: ComponentHostView if let current = self.titleTopicIconView { titleTopicIconView = current @@ -340,7 +340,7 @@ public final class ListMessageFileItemNode: ListMessageNode { public let titleNode: TextNode public let textNode: TextNode - public let descriptionNode: TextNode + public let descriptionNode: DescriptionNode private let descriptionProgressNode: ImmediateTextNode public let dateNode: TextNode @@ -379,6 +379,30 @@ public final class ListMessageFileItemNode: ListMessageNode { private var currentIsRestricted = false private var cachedSearchResult: CachedChatListSearchResult? + public override var visibility: ListViewItemNodeVisibility { + didSet { + let wasVisible = self.visibilityStatus + let isVisible: Bool + switch self.visibility { + case let .visible(fraction, _): + isVisible = fraction > 0.2 + case .none: + isVisible = false + } + if wasVisible != isVisible { + self.visibilityStatus = isVisible + } + } + } + + private var visibilityStatus: Bool = false { + didSet { + if self.visibilityStatus != oldValue { + self.descriptionNode.visibilityStatus = self.visibilityStatus + } + } + } + public required init() { self.contextSourceNode = ContextExtractedContentContainingNode() self.containerNode = ContextControllerSourceNode() @@ -407,7 +431,7 @@ public final class ListMessageFileItemNode: ListMessageNode { self.textNode.displaysAsynchronously = false self.textNode.isUserInteractionEnabled = false - self.descriptionNode = TextNode() + self.descriptionNode = DescriptionNode() self.descriptionNode.displaysAsynchronously = false self.descriptionNode.isUserInteractionEnabled = false @@ -539,8 +563,7 @@ public final class ListMessageFileItemNode: ListMessageNode { override public func asyncLayout() -> (_ item: ListMessageItem, _ params: ListViewItemLayoutParams, _ mergedTop: Bool, _ mergedBottom: Bool, _ dateHeaderAtBottom: Bool) -> (ListViewItemNodeLayout, (ListViewItemUpdateAnimation) -> Void) { let titleNodeMakeLayout = TextNode.asyncLayout(self.titleNode) let textNodeMakeLayout = TextNode.asyncLayout(self.textNode) - let descriptionNodeMakeLayout = TextNode.asyncLayout(self.descriptionNode) -// let newDescriptionNodeMakeLayout = self.descriptionNode.asyncLayout() + let descriptionNodeMakeLayout = self.descriptionNode.asyncLayout() let extensionIconTextMakeLayout = TextNode.asyncLayout(self.extensionIconText) let dateNodeMakeLayout = TextNode.asyncLayout(self.dateNode) let iconImageLayout = self.iconImageNode.asyncLayout() @@ -596,6 +619,9 @@ public final class ListMessageFileItemNode: ListMessageNode { let message = item.message + var forumThreadTitle: (title: NSAttributedString, showIcon: Bool, iconId: Int64?, iconColor: Int32)? = nil + var globalAuthorTitle: String? + var selectedMedia: Media? if let message = message { for media in message.media { @@ -626,10 +652,13 @@ public final class ListMessageFileItemNode: ListMessageNode { if item.isGlobalSearchResult || item.isDownloadList { let authorString = stringForFullAuthorName(message: EngineMessage(message), strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, accountPeerId: item.context.account.peerId) + if authorString.count > 1 { + globalAuthorTitle = authorString.last ?? "" + } if descriptionString.isEmpty { - descriptionString = authorString + descriptionString = authorString.first ?? "" } else { - descriptionString = "\(descriptionString) • \(authorString)" + descriptionString = "\(descriptionString) • \(authorString.first ?? "")" } } @@ -669,7 +698,8 @@ public final class ListMessageFileItemNode: ListMessageNode { } if item.isGlobalSearchResult || item.isDownloadList { - authorName = stringForFullAuthorName(message: EngineMessage(message), strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, accountPeerId: item.context.account.peerId) + let authorString = stringForFullAuthorName(message: EngineMessage(message), strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, accountPeerId: item.context.account.peerId) + authorName = authorString.joined(separator: " → ") } titleText = NSAttributedString(string: authorName, font: audioTitleFont, textColor: item.presentationData.theme.theme.list.itemPrimaryTextColor) @@ -726,10 +756,13 @@ public final class ListMessageFileItemNode: ListMessageNode { if item.isGlobalSearchResult || item.isDownloadList { let authorString = stringForFullAuthorName(message: EngineMessage(message), strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, accountPeerId: item.context.account.peerId) + if authorString.count > 1 { + globalAuthorTitle = authorString.last ?? "" + } if descriptionString.isEmpty { - descriptionString = authorString + descriptionString = authorString.first ?? "" } else { - descriptionString = "\(descriptionString) • \(authorString)" + descriptionString = "\(descriptionString) • \(authorString.first ?? "")" } } @@ -754,12 +787,15 @@ public final class ListMessageFileItemNode: ListMessageNode { descriptionString = "\(dateString)" } - if item.isGlobalSearchResult || item.isDownloadList { + if item.isGlobalSearchResult || item.isDownloadList { let authorString = stringForFullAuthorName(message: EngineMessage(message), strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, accountPeerId: item.context.account.peerId) + if authorString.count > 1 { + globalAuthorTitle = authorString.last ?? "" + } if descriptionString.isEmpty { - descriptionString = authorString + descriptionString = authorString.first ?? "" } else { - descriptionString = "\(descriptionString) • \(authorString)" + descriptionString = "\(descriptionString) • \(authorString.first ?? "")" } } @@ -778,6 +814,14 @@ public final class ListMessageFileItemNode: ListMessageNode { descriptionText = NSAttributedString(string: " ", font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemSecondaryTextColor) } + if !(isInstantVideo || isVoice) { + if let _ = item.message?.threadId, let threadInfo = item.message?.associatedThreadInfo { + forumThreadTitle = (NSAttributedString(string: threadInfo.title, font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemSecondaryTextColor), true, threadInfo.icon, threadInfo.iconColor) + } else if let globalAuthorTitle = globalAuthorTitle { + forumThreadTitle = (NSAttributedString(string: globalAuthorTitle, font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemSecondaryTextColor), false, nil, 0) + } + } + var mediaUpdated = false if let currentMedia = currentMedia { if let selectedMedia = selectedMedia { @@ -916,10 +960,7 @@ public final class ListMessageFileItemNode: ListMessageNode { let (textNodeLayout, textNodeApply) = textNodeMakeLayout(TextNodeLayoutArguments(attributedString: captionText, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset - 30.0, height: CGFloat.infinity), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (descriptionNodeLayout, descriptionNodeApply) = descriptionNodeMakeLayout(TextNodeLayoutArguments(attributedString: descriptionText, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - rightInset - 30.0, height: CGFloat.infinity), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - -// let forumThreadTitle: (title: NSAttributedString, iconId: Int64?, iconColor: Int32)? = nil -// let (newDescriptionNodeLayout, newDescriptionNodeApply) = newDescriptionNodeMakeLayout(item.context, params.width - leftInset - rightInset - 30.0, item.presentationData.theme.theme, descriptionText, forumThreadTitle) + let (descriptionNodeLayout, descriptionNodeApply) = descriptionNodeMakeLayout(item.context, params.width - leftInset - rightInset - 30.0, item.presentationData.theme.theme, descriptionText, forumThreadTitle) var (extensionTextLayout, extensionTextApply) = extensionIconTextMakeLayout(TextNodeLayoutArguments(attributedString: extensionText, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 38.0, height: CGFloat.infinity), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) if extensionTextLayout.truncated, let text = extensionText?.string { @@ -979,7 +1020,7 @@ public final class ListMessageFileItemNode: ListMessageNode { insets.bottom += 35.0 } - let nodeLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: 8.0 * 2.0 + titleNodeLayout.size.height + 3.0 + descriptionNodeLayout.size.height + (textNodeLayout.size.height > 0.0 ? textNodeLayout.size.height + 3.0 : 0.0)), insets: insets) + let nodeLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: 8.0 * 2.0 + titleNodeLayout.size.height + 3.0 + descriptionNodeLayout.height + (textNodeLayout.size.height > 0.0 ? textNodeLayout.size.height + 3.0 : 0.0)), insets: insets) return (nodeLayout, { animation in if let strongSelf = self { @@ -1124,7 +1165,7 @@ public final class ListMessageFileItemNode: ListMessageNode { transition.updateFrame(node: strongSelf.textNode, frame: CGRect(origin: CGPoint(x: leftOffset + leftInset + descriptionOffset, y: strongSelf.titleNode.frame.maxY + 1.0), size: textNodeLayout.size)) let _ = textNodeApply() - transition.updateFrame(node: strongSelf.descriptionNode, frame: CGRect(origin: CGPoint(x: leftOffset + leftInset + descriptionOffset, y: strongSelf.titleNode.frame.maxY + 1.0 + (textNodeLayout.size.height > 0.0 ? textNodeLayout.size.height + 3.0 : 0.0)), size: descriptionNodeLayout.size)) + transition.updateFrame(node: strongSelf.descriptionNode, frame: CGRect(origin: CGPoint(x: leftOffset + leftInset + descriptionOffset, y: strongSelf.titleNode.frame.maxY + 1.0 + (textNodeLayout.size.height > 0.0 ? textNodeLayout.size.height + 3.0 : 0.0)), size: descriptionNodeLayout)) let _ = descriptionNodeApply() let _ = dateNodeApply() diff --git a/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift b/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift index 422af3781e..9064078e87 100644 --- a/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift +++ b/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift @@ -41,7 +41,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode { private let instantViewIconNode: ASImageNode public let linkNode: TextNode private var linkHighlightingNode: LinkHighlightingNode? - public let authorNode: TextNode + public let authorNode: ListMessageFileItemNode.DescriptionNode private let iconTextBackgroundNode: ASImageNode private let iconTextNode: TextNode @@ -56,6 +56,30 @@ public final class ListMessageSnippetItemNode: ListMessageNode { private var cachedChatListSearchResult: CachedChatListSearchResult? + public override var visibility: ListViewItemNodeVisibility { + didSet { + let wasVisible = self.visibilityStatus + let isVisible: Bool + switch self.visibility { + case let .visible(fraction, _): + isVisible = fraction > 0.2 + case .none: + isVisible = false + } + if wasVisible != isVisible { + self.visibilityStatus = isVisible + } + } + } + + private var visibilityStatus: Bool = false { + didSet { + if self.visibilityStatus != oldValue { + self.authorNode.visibilityStatus = self.visibilityStatus + } + } + } + public required init() { self.contextSourceNode = ContextExtractedContentContainingNode() self.containerNode = ContextControllerSourceNode() @@ -100,7 +124,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode { self.iconImageNode = TransformImageNode() self.iconImageNode.displaysAsynchronously = false - self.authorNode = TextNode() + self.authorNode = ListMessageFileItemNode.DescriptionNode() self.authorNode.isUserInteractionEnabled = false super.init() @@ -209,7 +233,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode { let dateNodeMakeLayout = TextNode.asyncLayout(self.dateNode) let iconTextMakeLayout = TextNode.asyncLayout(self.iconTextNode) let iconImageLayout = self.iconImageNode.asyncLayout() - let authorNodeMakeLayout = TextNode.asyncLayout(self.authorNode) + let authorNodeMakeLayout = self.authorNode.asyncLayout() let currentIconImageRepresentation = self.currentIconImageRepresentation @@ -259,7 +283,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode { var selectedMedia: TelegramMediaWebpage? var processed = false - + if let message = item.message { for media in message.media { if let webpage = media as? TelegramMediaWebpage { @@ -468,6 +492,22 @@ public final class ListMessageSnippetItemNode: ListMessageNode { } } + var forumThreadTitle: (title: NSAttributedString, showIcon: Bool, iconId: Int64?, iconColor: Int32)? = nil + + var authorString = "" + if let message = item.message, let _ = message.threadId, let threadInfo = message.associatedThreadInfo { + let fullAuthorString = stringForFullAuthorName(message: EngineMessage(message), strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, accountPeerId: item.context.account.peerId) + authorString = fullAuthorString.first ?? "" + forumThreadTitle = (NSAttributedString(string: threadInfo.title, font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemSecondaryTextColor), true, threadInfo.icon, threadInfo.iconColor) + } else if item.isGlobalSearchResult, let message = item.message { + let fullAuthorString = stringForFullAuthorName(message: EngineMessage(message), strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, accountPeerId: item.context.account.peerId) + authorString = fullAuthorString.first ?? "" + + if fullAuthorString.count > 1, let globalAuthorTitle = fullAuthorString.last { + forumThreadTitle = (NSAttributedString(string: globalAuthorTitle, font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemSecondaryTextColor), false, nil, 0) + } + } + var chatListSearchResult: CachedChatListSearchResult? if let searchQuery = item.interaction.searchTextHighightState, let message = item.message { if let cached = currentChatListSearchResult, cached.matches(text: message.text, searchQuery: searchQuery) { @@ -546,19 +586,13 @@ public final class ListMessageSnippetItemNode: ListMessageNode { updateIconImageSignal = .complete() } } - - var authorString = "" - if item.isGlobalSearchResult, let message = item.message { - authorString = stringForFullAuthorName(message: EngineMessage(message), strings: item.presentationData.strings, nameDisplayOrder: item.presentationData.nameDisplayOrder, accountPeerId: item.context.account.peerId) - } - + let authorText = NSAttributedString(string: authorString, font: authorFont, textColor: item.presentationData.theme.theme.list.itemSecondaryTextColor) - - let (authorNodeLayout, authorNodeApply) = authorNodeMakeLayout(TextNodeLayoutArguments(attributedString: authorText, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - params.rightInset - 30.0, height: CGFloat.infinity), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (authorNodeLayout, authorNodeApply) = authorNodeMakeLayout(item.context, params.width - leftInset - params.rightInset - 30.0, item.presentationData.theme.theme, authorText, forumThreadTitle) var contentHeight = 9.0 + titleNodeLayout.size.height + 10.0 + descriptionNodeLayout.size.height + linkNodeLayout.size.height - if item.isGlobalSearchResult { - contentHeight += authorNodeLayout.size.height + if !authorString.isEmpty { + contentHeight += authorNodeLayout.height } var insets = UIEdgeInsets() @@ -642,8 +676,8 @@ public final class ListMessageSnippetItemNode: ListMessageNode { let _ = linkNodeApply() let _ = authorNodeApply() - transition.updateFrame(node: strongSelf.authorNode, frame: CGRect(origin: CGPoint(x: leftOffset + leftInset, y: linkFrame.maxY + 1.0), size: authorNodeLayout.size)) - strongSelf.authorNode.isHidden = !item.isGlobalSearchResult + transition.updateFrame(node: strongSelf.authorNode, frame: CGRect(origin: CGPoint(x: leftOffset + leftInset, y: linkFrame.maxY + 1.0), size: authorNodeLayout)) + strongSelf.authorNode.isHidden = authorString.isEmpty if let image = instantViewImage { strongSelf.instantViewIconNode.image = image diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift index 6a823e1cec..4dc32065c6 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/SearchMessages.swift @@ -64,7 +64,7 @@ public struct SearchMessagesState: Equatable { fileprivate let additional: SearchMessagesPeerState? } -private func mergedState(transaction: Transaction, state: SearchMessagesPeerState?, result: Api.messages.Messages?) -> SearchMessagesPeerState? { +private func mergedState(transaction: Transaction, seedConfiguration: SeedConfiguration, state: SearchMessagesPeerState?, result: Api.messages.Messages?) -> SearchMessagesPeerState? { guard let result = result else { return state } @@ -121,17 +121,23 @@ private func mergedState(transaction: Transaction, state: SearchMessagesPeerStat var renderedMessages: [Message] = [] for message in messages { - if let message = StoreMessage(apiMessage: message), let renderedMessage = locallyRenderedMessage(message: message, peers: peers) { - let peerId = renderedMessage.id.peerId - renderedMessages.append(renderedMessage) - peerIdsSet.insert(peerId) - for attribute in renderedMessage.attributes { - if let attribute = attribute as? ReplyMessageAttribute { - if let threadMessageId = attribute.threadMessageId { - let threadId = makeMessageThreadId(threadMessageId) - if let data = transaction.getMessageHistoryThreadInfo(peerId: peerId, threadId: threadId)?.data.get(MessageHistoryThreadData.self) { - threadInfo[renderedMessage.id] = data - break + if let message = StoreMessage(apiMessage: message) { + var associatedThreadInfo: Message.AssociatedThreadInfo? + if let threadId = message.threadId, let threadInfo = transaction.getMessageHistoryThreadInfo(peerId: message.id.peerId, threadId: threadId) { + associatedThreadInfo = seedConfiguration.decodeMessageThreadInfo(threadInfo.data) + } + if let renderedMessage = locallyRenderedMessage(message: message, peers: peers, associatedThreadInfo: associatedThreadInfo) { + let peerId = renderedMessage.id.peerId + renderedMessages.append(renderedMessage) + peerIdsSet.insert(peerId) + for attribute in renderedMessage.attributes { + if let attribute = attribute as? ReplyMessageAttribute { + if let threadMessageId = attribute.threadMessageId { + let threadId = makeMessageThreadId(threadMessageId) + if let data = transaction.getMessageHistoryThreadInfo(peerId: peerId, threadId: threadId)?.data.get(MessageHistoryThreadData.self) { + threadInfo[renderedMessage.id] = data + break + } } } } @@ -148,7 +154,7 @@ private func mergedState(transaction: Transaction, state: SearchMessagesPeerStat renderedMessages.sort(by: { lhs, rhs in return lhs.index > rhs.index }) - + let completed = renderedMessages.isEmpty || renderedMessages.count == totalCount if let previous = state { var currentIds = Set() @@ -399,7 +405,7 @@ func _internal_searchMessages(account: Account, location: SearchMessagesLocation return remoteSearchResult |> mapToSignal { result, additionalResult -> Signal<(SearchMessagesResult, SearchMessagesState), NoError> in return account.postbox.transaction { transaction -> (SearchMessagesResult, SearchMessagesState) in - var additional: SearchMessagesPeerState? = mergedState(transaction: transaction, state: state?.additional, result: additionalResult) + var additional: SearchMessagesPeerState? = mergedState(transaction: transaction, seedConfiguration: account.postbox.seedConfiguration, state: state?.additional, result: additionalResult) if state?.additional == nil { switch location { @@ -440,7 +446,7 @@ func _internal_searchMessages(account: Account, location: SearchMessagesLocation } } - let updatedState = SearchMessagesState(main: mergedState(transaction: transaction, state: state?.main, result: result) ?? SearchMessagesPeerState(messages: [], readStates: [:], threadInfo: [:], totalCount: 0, completed: true, nextRate: nil), additional: additional) + let updatedState = SearchMessagesState(main: mergedState(transaction: transaction, seedConfiguration: account.postbox.seedConfiguration, state: state?.main, result: result) ?? SearchMessagesPeerState(messages: [], readStates: [:], threadInfo: [:], totalCount: 0, completed: true, nextRate: nil), additional: additional) return (mergedResult(updatedState), updatedState) } } diff --git a/submodules/TelegramCore/Sources/Utils/MessageUtils.swift b/submodules/TelegramCore/Sources/Utils/MessageUtils.swift index e18032c41f..8f6a87d262 100644 --- a/submodules/TelegramCore/Sources/Utils/MessageUtils.swift +++ b/submodules/TelegramCore/Sources/Utils/MessageUtils.swift @@ -167,7 +167,7 @@ func messagesIdsGroupedByPeerId(_ ids: ReferencedReplyMessageIds) -> [PeerId: Re return dict } -func locallyRenderedMessage(message: StoreMessage, peers: [PeerId: Peer]) -> Message? { +func locallyRenderedMessage(message: StoreMessage, peers: [PeerId: Peer], associatedThreadInfo: Message.AssociatedThreadInfo? = nil) -> Message? { guard case let .Id(id) = message.id else { return nil } @@ -219,8 +219,8 @@ func locallyRenderedMessage(message: StoreMessage, peers: [PeerId: Peer]) -> Mes let first = UInt32((hashValue >> 32) & 0xffffffff) let second = UInt32(hashValue & 0xffffffff) let stableId = first &+ second - - return Message(stableId: stableId, stableVersion: 0, id: id, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: message.threadId, timestamp: message.timestamp, flags: MessageFlags(message.flags), tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: forwardInfo, author: author, text: message.text, attributes: message.attributes, media: message.media, peers: messagePeers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil) + + return Message(stableId: stableId, stableVersion: 0, id: id, globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: message.threadId, timestamp: message.timestamp, flags: MessageFlags(message.flags), tags: message.tags, globalTags: message.globalTags, localTags: message.localTags, forwardInfo: forwardInfo, author: author, text: message.text, attributes: message.attributes, media: message.media, peers: messagePeers, associatedMessages: SimpleDictionary(), associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: associatedThreadInfo) } public extension Message { diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift index e90fbe46c7..ae5d02bd5d 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourceKey.swift @@ -68,6 +68,7 @@ public enum PresentationResourceKey: Int32 { case itemListResetIcon case itemListImageIcon case itemListCloudIcon + case itemListTopicArrowIcon case itemListVoiceCallIcon case itemListVideoCallIcon diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift index 78bdbc02cf..9a3204ee0b 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesItemList.swift @@ -299,4 +299,10 @@ public struct PresentationResourcesItemList { return generateTintedImage(image: UIImage(bundleImageName: "Settings/UploadTone"), color: theme.list.itemAccentColor) }) } + + public static func topicArrowDescriptionIcon(_ theme: PresentationTheme) -> UIImage? { + return theme.image(PresentationResourceKey.itemListTopicArrowIcon.rawValue, { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Chat List/TopicArrowIcon"), color: theme.list.itemSecondaryTextColor) + }) + } } diff --git a/submodules/TelegramStringFormatting/Sources/PeerDisplayName.swift b/submodules/TelegramStringFormatting/Sources/PeerDisplayName.swift index cdc730d8b9..4d176e7f5c 100644 --- a/submodules/TelegramStringFormatting/Sources/PeerDisplayName.swift +++ b/submodules/TelegramStringFormatting/Sources/PeerDisplayName.swift @@ -3,8 +3,8 @@ import TelegramPresentationData import TelegramUIPreferences import TelegramCore -public func stringForFullAuthorName(message: EngineMessage, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, accountPeerId: EnginePeer.Id) -> String { - var authorString = "" +public func stringForFullAuthorName(message: EngineMessage, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, accountPeerId: EnginePeer.Id) -> [String] { + var authorString: [String] = [] if let author = message.author, [Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel].contains(message.id.peerId.namespace) { var authorName = "" if author.id == accountPeerId { @@ -13,20 +13,20 @@ public func stringForFullAuthorName(message: EngineMessage, strings: Presentatio authorName = author.compactDisplayTitle } if let peer = message.peers[message.id.peerId].flatMap(EnginePeer.init), author.id != peer.id { - authorString = "\(authorName) → \(peer.displayTitle(strings: strings, displayOrder: nameDisplayOrder))" + authorString = [authorName, peer.displayTitle(strings: strings, displayOrder: nameDisplayOrder)] } else { - authorString = authorName + authorString = [authorName] } } else if let peer = message.peers[message.id.peerId].flatMap(EnginePeer.init) { if message.id.peerId.namespace == Namespaces.Peer.CloudChannel { - authorString = peer.displayTitle(strings: strings, displayOrder: nameDisplayOrder) + authorString = [peer.displayTitle(strings: strings, displayOrder: nameDisplayOrder)] } else { if message.id.peerId == accountPeerId { - authorString = strings.DialogList_SavedMessages + authorString = [strings.DialogList_SavedMessages] } else if message.flags.contains(.Incoming) { - authorString = peer.displayTitle(strings: strings, displayOrder: nameDisplayOrder) + authorString = [peer.displayTitle(strings: strings, displayOrder: nameDisplayOrder)] } else { - authorString = "\(strings.DialogList_You) → \(peer.displayTitle(strings: strings, displayOrder: nameDisplayOrder))" + authorString = [strings.DialogList_You, peer.displayTitle(strings: strings, displayOrder: nameDisplayOrder)] } } } diff --git a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift index af86cf906e..100d99c963 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/Panes/PeerInfoVisualMediaPaneNode.swift @@ -1092,7 +1092,8 @@ private final class ItemView: UIView, SparseItemGridView { self.messageItemNode = messageItemNode self.buttonNode.addSubnode(messageItemNode) } - + messageItemNode.visibility = .visible(1.0, .infinite) + messageItemNode.frame = CGRect(origin: CGPoint(), size: size) self.buttonNode.frame = CGRect(origin: CGPoint(), size: size) }