mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Various improvements
This commit is contained in:
parent
845039f5e8
commit
9282469231
10 changed files with 156 additions and 67 deletions
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<Empty>
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<MessageId>()
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ public enum PresentationResourceKey: Int32 {
|
|||
case itemListResetIcon
|
||||
case itemListImageIcon
|
||||
case itemListCloudIcon
|
||||
case itemListTopicArrowIcon
|
||||
|
||||
case itemListVoiceCallIcon
|
||||
case itemListVideoCallIcon
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue