diff --git a/submodules/ChatListUI/BUCK b/submodules/ChatListUI/BUCK index 78137de4c0..c37f40e0f9 100644 --- a/submodules/ChatListUI/BUCK +++ b/submodules/ChatListUI/BUCK @@ -52,6 +52,7 @@ static_library( "//submodules/TelegramUIPreferences:TelegramUIPreferences", "//submodules/GalleryData:GalleryData", "//submodules/InstantPageUI:InstantPageUI", + "//submodules/ListSectionHeaderNode:ListSectionHeaderNode", ], frameworks = [ "$SDKROOT/System/Library/Frameworks/Foundation.framework", diff --git a/submodules/ChatListUI/BUILD b/submodules/ChatListUI/BUILD index b5c6cbb79e..e34ef99e1e 100644 --- a/submodules/ChatListUI/BUILD +++ b/submodules/ChatListUI/BUILD @@ -51,6 +51,7 @@ swift_library( "//submodules/MediaPlayer:UniversalMediaPlayer", "//submodules/GalleryData:GalleryData", "//submodules/InstantPageUI:InstantPageUI", + "//submodules/ListSectionHeaderNode:ListSectionHeaderNode", ], visibility = [ "//visibility:public", diff --git a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift index 5937bae40f..c18a2229d6 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift @@ -1471,7 +1471,18 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo let isSearching = entriesAndFlags?.1 ?? false 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 newEntries = entriesAndFlags?.0 ?? [] diff --git a/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift b/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift index e5477cffad..e6790031e0 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift @@ -12,6 +12,7 @@ import RadialStatusNode import TelegramStringFormatting import UniversalMediaPlayer import ListMessageItem +import ListSectionHeaderNode import ChatMessageInteractiveMediaBadge 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 scrollNode: ASScrollNode + private var headerNode: ListSectionHeaderNode private let floatingHeaderNode: FloatingHeaderNode private var flashHeaderDelayTimer: Foundation.Timer? private var isDeceleratingAfterTracking = false @@ -624,6 +626,8 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate { self.floatingHeaderNode = FloatingHeaderNode() self.floatingHeaderNode.alpha = 0.0 + self.headerNode = ListSectionHeaderNode(theme: context.sharedContext.currentPresentationData.with { $0 }.theme) + super.init() self._itemInteraction = VisualMediaItemInteraction( @@ -649,6 +653,7 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate { self.scrollNode.view.delegate = self self.addSubnode(self.scrollNode) + self.addSubnode(self.headerNode) self.addSubnode(self.floatingHeaderNode) 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 { case .FillHole: break @@ -692,7 +697,12 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate { self.initialized = true 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.headerNode.alpha = self.mediaItems.isEmpty ? 0.0 : 1.0 if !self.didSetReady { self.didSetReady = 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) { 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 @@ -881,7 +895,7 @@ final class ChatListSearchMediaNode: ASDisplayNode, UIScrollViewDelegate { if let headerItem = headerItem { let (year, month) = listMessageDateHeaderInfo(timestamp: headerItem.timestamp) 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 } else { self.floatingHeaderNode.isHidden = true diff --git a/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift b/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift index abe25be80e..febb4683be 100644 --- a/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift +++ b/submodules/ListMessageItem/Sources/ListMessageSnippetItemNode.swift @@ -373,6 +373,50 @@ public final class ListMessageSnippetItemNode: ListMessageNode { descriptionText = mutableDescriptionText } 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[..