Various improvements

This commit is contained in:
Ilya Laktyushin 2022-11-09 18:28:49 +04:00
parent 845039f5e8
commit 9282469231
10 changed files with 156 additions and 67 deletions

View file

@ -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";

View file

@ -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)

View file

@ -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()

View file

@ -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

View file

@ -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)
}
}

View file

@ -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 {

View file

@ -68,6 +68,7 @@ public enum PresentationResourceKey: Int32 {
case itemListResetIcon
case itemListImageIcon
case itemListCloudIcon
case itemListTopicArrowIcon
case itemListVoiceCallIcon
case itemListVideoCallIcon

View file

@ -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)
})
}
}

View file

@ -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)]
}
}
}

View file

@ -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)
}