mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Fix inline links display in global search results
Add section header in media search results
This commit is contained in:
parent
bb2e168346
commit
63679c0d46
@ -52,6 +52,7 @@ static_library(
|
|||||||
"//submodules/TelegramUIPreferences:TelegramUIPreferences",
|
"//submodules/TelegramUIPreferences:TelegramUIPreferences",
|
||||||
"//submodules/GalleryData:GalleryData",
|
"//submodules/GalleryData:GalleryData",
|
||||||
"//submodules/InstantPageUI:InstantPageUI",
|
"//submodules/InstantPageUI:InstantPageUI",
|
||||||
|
"//submodules/ListSectionHeaderNode:ListSectionHeaderNode",
|
||||||
],
|
],
|
||||||
frameworks = [
|
frameworks = [
|
||||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||||
|
@ -51,6 +51,7 @@ swift_library(
|
|||||||
"//submodules/MediaPlayer:UniversalMediaPlayer",
|
"//submodules/MediaPlayer:UniversalMediaPlayer",
|
||||||
"//submodules/GalleryData:GalleryData",
|
"//submodules/GalleryData:GalleryData",
|
||||||
"//submodules/InstantPageUI:InstantPageUI",
|
"//submodules/InstantPageUI:InstantPageUI",
|
||||||
|
"//submodules/ListSectionHeaderNode:ListSectionHeaderNode",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -1471,7 +1471,18 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
|||||||
let isSearching = entriesAndFlags?.1 ?? false
|
let isSearching = entriesAndFlags?.1 ?? false
|
||||||
strongSelf._isSearching.set(isSearching)
|
strongSelf._isSearching.set(isSearching)
|
||||||
|
|
||||||
strongSelf.mediaNode.updateHistory(entries: entriesAndFlags?.0 ?? [], updateType: .Initial)
|
if strongSelf.searchOptionsValue?.messageTags == .photoOrVideo {
|
||||||
|
var totalCount: Int32 = 0
|
||||||
|
if let entries = entriesAndFlags?.0 {
|
||||||
|
for entry in entries {
|
||||||
|
if case let .message(_, _, _, _, count) = entry {
|
||||||
|
totalCount = count
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strongSelf.mediaNode.updateHistory(entries: entriesAndFlags?.0 ?? [], totalCount: totalCount, updateType: .Initial)
|
||||||
|
}
|
||||||
|
|
||||||
let previousEntries = previousSearchItems.swap(entriesAndFlags?.0)
|
let previousEntries = previousSearchItems.swap(entriesAndFlags?.0)
|
||||||
let newEntries = entriesAndFlags?.0 ?? []
|
let newEntries = entriesAndFlags?.0 ?? []
|
||||||
|
@ -12,6 +12,7 @@ import RadialStatusNode
|
|||||||
import TelegramStringFormatting
|
import TelegramStringFormatting
|
||||||
import UniversalMediaPlayer
|
import UniversalMediaPlayer
|
||||||
import ListMessageItem
|
import ListMessageItem
|
||||||
|
import ListSectionHeaderNode
|
||||||
import ChatMessageInteractiveMediaBadge
|
import ChatMessageInteractiveMediaBadge
|
||||||
|
|
||||||
private let mediaBadgeBackgroundColor = UIColor(white: 0.0, alpha: 0.6)
|
private let mediaBadgeBackgroundColor = UIColor(white: 0.0, alpha: 0.6)
|
||||||
@ -583,6 +584,7 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
private let contentType: ContentType
|
private let contentType: ContentType
|
||||||
|
|
||||||
private let scrollNode: ASScrollNode
|
private let scrollNode: ASScrollNode
|
||||||
|
private var headerNode: ListSectionHeaderNode
|
||||||
private let floatingHeaderNode: FloatingHeaderNode
|
private let floatingHeaderNode: FloatingHeaderNode
|
||||||
private var flashHeaderDelayTimer: Foundation.Timer?
|
private var flashHeaderDelayTimer: Foundation.Timer?
|
||||||
private var isDeceleratingAfterTracking = false
|
private var isDeceleratingAfterTracking = false
|
||||||
@ -624,6 +626,8 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
self.floatingHeaderNode = FloatingHeaderNode()
|
self.floatingHeaderNode = FloatingHeaderNode()
|
||||||
self.floatingHeaderNode.alpha = 0.0
|
self.floatingHeaderNode.alpha = 0.0
|
||||||
|
|
||||||
|
self.headerNode = ListSectionHeaderNode(theme: context.sharedContext.currentPresentationData.with { $0 }.theme)
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self._itemInteraction = VisualMediaItemInteraction(
|
self._itemInteraction = VisualMediaItemInteraction(
|
||||||
@ -649,6 +653,7 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
self.scrollNode.view.delegate = self
|
self.scrollNode.view.delegate = self
|
||||||
|
|
||||||
self.addSubnode(self.scrollNode)
|
self.addSubnode(self.scrollNode)
|
||||||
|
self.addSubnode(self.headerNode)
|
||||||
self.addSubnode(self.floatingHeaderNode)
|
self.addSubnode(self.floatingHeaderNode)
|
||||||
|
|
||||||
self.hiddenMediaDisposable = context.sharedContext.mediaManager.galleryHiddenMediaManager.hiddenIds().start(next: { [weak self] ids in
|
self.hiddenMediaDisposable = context.sharedContext.mediaManager.galleryHiddenMediaManager.hiddenIds().start(next: { [weak self] ids in
|
||||||
@ -675,7 +680,7 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func updateHistory(entries: [ChatListSearchEntry], updateType: ViewUpdateType) {
|
func updateHistory(entries: [ChatListSearchEntry], totalCount: Int32, updateType: ViewUpdateType) {
|
||||||
switch updateType {
|
switch updateType {
|
||||||
case .FillHole:
|
case .FillHole:
|
||||||
break
|
break
|
||||||
@ -692,7 +697,12 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
self.initialized = true
|
self.initialized = true
|
||||||
|
|
||||||
if let (size, sideInset, bottomInset, visibleHeight, isScrollingLockedAtTop, expandProgress, presentationData) = self.currentParams {
|
if let (size, sideInset, bottomInset, visibleHeight, isScrollingLockedAtTop, expandProgress, presentationData) = self.currentParams {
|
||||||
|
if totalCount > 0 {
|
||||||
|
self.headerNode.title = presentationData.strings.ChatList_Search_Messages(totalCount).uppercased()
|
||||||
|
}
|
||||||
|
|
||||||
self.update(size: size, sideInset: sideInset, bottomInset: bottomInset, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expandProgress, presentationData: presentationData, synchronous: true, transition: .immediate)
|
self.update(size: size, sideInset: sideInset, bottomInset: bottomInset, visibleHeight: visibleHeight, isScrollingLockedAtTop: isScrollingLockedAtTop, expandProgress: expandProgress, presentationData: presentationData, synchronous: true, transition: .immediate)
|
||||||
|
self.headerNode.alpha = self.mediaItems.isEmpty ? 0.0 : 1.0
|
||||||
if !self.didSetReady {
|
if !self.didSetReady {
|
||||||
self.didSetReady = true
|
self.didSetReady = true
|
||||||
self.ready.set(.single(true))
|
self.ready.set(.single(true))
|
||||||
@ -757,7 +767,11 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
func update(size: CGSize, sideInset: CGFloat, bottomInset: CGFloat, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, presentationData: PresentationData, synchronous: Bool, transition: ContainedViewLayoutTransition) {
|
func update(size: CGSize, sideInset: CGFloat, bottomInset: CGFloat, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, presentationData: PresentationData, synchronous: Bool, transition: ContainedViewLayoutTransition) {
|
||||||
self.currentParams = (size, sideInset, bottomInset, visibleHeight, isScrollingLockedAtTop, expandProgress, presentationData)
|
self.currentParams = (size, sideInset, bottomInset, visibleHeight, isScrollingLockedAtTop, expandProgress, presentationData)
|
||||||
|
|
||||||
transition.updateFrame(node: self.scrollNode, frame: CGRect(origin: CGPoint(), size: size))
|
let headerSize = CGSize(width: size.width, height: 28.0)
|
||||||
|
self.headerNode.frame = CGRect(origin: CGPoint(), size: headerSize)
|
||||||
|
self.headerNode.updateLayout(size: headerSize, leftInset: sideInset, rightInset: sideInset)
|
||||||
|
|
||||||
|
transition.updateFrame(node: self.scrollNode, frame: CGRect(origin: CGPoint(x: 0.0, y: headerSize.height), size: CGSize(width: size.width, height: size.height - headerSize.height)))
|
||||||
|
|
||||||
let availableWidth = size.width - sideInset * 2.0
|
let availableWidth = size.width - sideInset * 2.0
|
||||||
|
|
||||||
@ -881,7 +895,7 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
if let headerItem = headerItem {
|
if let headerItem = headerItem {
|
||||||
let (year, month) = listMessageDateHeaderInfo(timestamp: headerItem.timestamp)
|
let (year, month) = listMessageDateHeaderInfo(timestamp: headerItem.timestamp)
|
||||||
let headerSize = self.floatingHeaderNode.update(constrainedWidth: size.width, year: year, month: month, theme: theme, strings: strings)
|
let headerSize = self.floatingHeaderNode.update(constrainedWidth: size.width, year: year, month: month, theme: theme, strings: strings)
|
||||||
self.floatingHeaderNode.frame = CGRect(origin: CGPoint(x: floor((size.width - headerSize.width) / 2.0), y: 7.0), size: headerSize)
|
self.floatingHeaderNode.frame = CGRect(origin: CGPoint(x: floor((size.width - headerSize.width) / 2.0), y: 7.0 + 28.0), size: headerSize)
|
||||||
self.floatingHeaderNode.isHidden = false
|
self.floatingHeaderNode.isHidden = false
|
||||||
} else {
|
} else {
|
||||||
self.floatingHeaderNode.isHidden = true
|
self.floatingHeaderNode.isHidden = true
|
||||||
|
@ -373,6 +373,50 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
|
|||||||
descriptionText = mutableDescriptionText
|
descriptionText = mutableDescriptionText
|
||||||
}
|
}
|
||||||
break loop
|
break loop
|
||||||
|
case let .TextUrl(url):
|
||||||
|
var range = NSRange(location: entity.range.lowerBound, length: entity.range.upperBound - entity.range.lowerBound)
|
||||||
|
let nsString = item.message.text as NSString
|
||||||
|
if range.location + range.length > nsString.length {
|
||||||
|
range.location = max(0, nsString.length - range.length)
|
||||||
|
range.length = nsString.length - range.location
|
||||||
|
}
|
||||||
|
let tempTitleString = (nsString.substring(with: range) as String).trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
|
||||||
|
var (urlString, concealed) = parseUrl(url: url, wasConcealed: false)
|
||||||
|
let rawUrlString = urlString
|
||||||
|
var parsedUrl = URL(string: urlString)
|
||||||
|
if parsedUrl == nil || parsedUrl!.host == nil || parsedUrl!.host!.isEmpty {
|
||||||
|
urlString = "http://" + urlString
|
||||||
|
parsedUrl = URL(string: urlString)
|
||||||
|
}
|
||||||
|
let host: String? = concealed ? urlString : parsedUrl?.host
|
||||||
|
if let url = parsedUrl, let host = host {
|
||||||
|
primaryUrl = urlString
|
||||||
|
title = NSAttributedString(string: tempTitleString as String, font: titleFont, textColor: item.presentationData.theme.theme.list.itemPrimaryTextColor)
|
||||||
|
if url.path.hasPrefix("/addstickers/") {
|
||||||
|
iconText = NSAttributedString(string: "S", font: iconFont, textColor: UIColor.white)
|
||||||
|
} else {
|
||||||
|
iconText = NSAttributedString(string: host[..<host.index(after: host.startIndex)].uppercased(), font: iconFont, textColor: UIColor.white)
|
||||||
|
}
|
||||||
|
let mutableDescriptionText = NSMutableAttributedString()
|
||||||
|
|
||||||
|
let (messageTextUrl, _) = parseUrl(url: item.message.text, wasConcealed: false)
|
||||||
|
|
||||||
|
if messageTextUrl != rawUrlString, !item.isGlobalSearchResult {
|
||||||
|
mutableDescriptionText.append(NSAttributedString(string: item.message.text + "\n", font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemSecondaryTextColor))
|
||||||
|
}
|
||||||
|
|
||||||
|
let urlAttributedString = NSMutableAttributedString()
|
||||||
|
urlAttributedString.append(NSAttributedString(string: urlString, font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemAccentColor))
|
||||||
|
if item.presentationData.theme.theme.list.itemAccentColor.isEqual(item.presentationData.theme.theme.list.itemPrimaryTextColor) {
|
||||||
|
urlAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue as NSNumber, range: NSMakeRange(0, urlAttributedString.length))
|
||||||
|
}
|
||||||
|
urlAttributedString.addAttribute(NSAttributedString.Key(rawValue: TelegramTextAttributes.URL), value: urlString, range: NSMakeRange(0, urlAttributedString.length))
|
||||||
|
linkText = urlAttributedString
|
||||||
|
|
||||||
|
descriptionText = mutableDescriptionText
|
||||||
|
}
|
||||||
|
break loop
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -423,7 +467,7 @@ public final class ListMessageSnippetItemNode: ListMessageNode {
|
|||||||
authorString = fullAuthorString(for: item)
|
authorString = fullAuthorString(for: item)
|
||||||
}
|
}
|
||||||
|
|
||||||
let authorText = NSAttributedString(string: authorString, font: descriptionFont, textColor: item.presentationData.theme.theme.list.itemSecondaryTextColor)
|
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(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()))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user