mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Update Trending stickers panel
This commit is contained in:
parent
610ed62517
commit
722ce97e9a
@ -2,17 +2,7 @@
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "StickerKeyboardTrendingIcon@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "StickerKeyboardTrendingIcon@3x.png",
|
||||
"scale" : "3x"
|
||||
"filename" : "ic_addstickers.pdf"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 933 B |
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB |
BIN
submodules/TelegramUI/Images.xcassets/Chat/Input/Media/TrendingIcon.imageset/ic_addstickers.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Chat/Input/Media/TrendingIcon.imageset/ic_addstickers.pdf
vendored
Normal file
Binary file not shown.
@ -88,7 +88,7 @@ enum ChatMediaInputGridEntry: Equatable, Comparable, Identifiable {
|
||||
case search(theme: PresentationTheme, strings: PresentationStrings)
|
||||
case peerSpecificSetup(theme: PresentationTheme, strings: PresentationStrings, dismissed: Bool)
|
||||
case sticker(index: ItemCollectionViewEntryIndex, stickerItem: StickerPackItem, stickerPackInfo: StickerPackCollectionInfo?, canManagePeerSpecificPack: Bool?, theme: PresentationTheme)
|
||||
case trending(TrendingPaneEntry)
|
||||
case trending(TrendingPanePackEntry)
|
||||
|
||||
var index: ChatMediaInputGridEntryIndex {
|
||||
switch self {
|
||||
|
@ -496,7 +496,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
var getItemIsPreviewedImpl: ((StickerPackItem) -> Bool)?
|
||||
self.trendingPane = ChatMediaInputTrendingPane(context: context, controllerInteraction: controllerInteraction, getItemIsPreviewed: { item in
|
||||
return getItemIsPreviewedImpl?(item) ?? false
|
||||
})
|
||||
}, isPane: true)
|
||||
|
||||
self.paneArrangement = ChatMediaInputPaneArrangement(panes: [.gifs, .stickers, .trending], currentIndex: 1, indexTransition: 0.0)
|
||||
|
||||
@ -754,6 +754,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
strongSelf.controllerInteraction.presentController(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}, getItemIsPreviewed: { item in
|
||||
return getItemIsPreviewedImpl?(item) ?? false
|
||||
}, openSearch: {
|
||||
})
|
||||
|
||||
let previousView = Atomic<ItemCollectionsView?>(value: nil)
|
||||
@ -803,7 +804,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
var index = 0
|
||||
for item in trendingPacks {
|
||||
if !installedPacks.contains(item.info.id) {
|
||||
gridEntries.append(.trending(TrendingPaneEntry(index: index, info: item.info, theme: theme, strings: strings, topItems: item.topItems, installed: installedPacks.contains(item.info.id), unread: item.unread, topSeparator: true)))
|
||||
gridEntries.append(.trending(TrendingPanePackEntry(index: index, info: item.info, theme: theme, strings: strings, topItems: item.topItems, installed: installedPacks.contains(item.info.id), unread: item.unread, topSeparator: true)))
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
@ -877,6 +878,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
|
||||
self.stickerPane.inputNodeInteraction = self.inputNodeInteraction
|
||||
self.gifPane.inputNodeInteraction = self.inputNodeInteraction
|
||||
self.trendingPane.inputNodeInteraction = self.inputNodeInteraction
|
||||
|
||||
paneDidScrollImpl = { [weak self] pane, state, transition in
|
||||
self?.updatePaneDidScroll(pane: pane, state: state, transition: transition)
|
||||
@ -1387,14 +1389,20 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
var placeholderNode: PaneSearchBarPlaceholderNode?
|
||||
if let searchMode = searchMode {
|
||||
switch searchMode {
|
||||
case .gif:
|
||||
placeholderNode = self.gifPane.searchPlaceholderNode
|
||||
case .sticker:
|
||||
self.stickerPane.gridNode.forEachItemNode { itemNode in
|
||||
if let itemNode = itemNode as? PaneSearchBarPlaceholderNode {
|
||||
placeholderNode = itemNode
|
||||
}
|
||||
case .gif:
|
||||
placeholderNode = self.gifPane.searchPlaceholderNode
|
||||
case .sticker:
|
||||
self.stickerPane.gridNode.forEachItemNode { itemNode in
|
||||
if let itemNode = itemNode as? PaneSearchBarPlaceholderNode {
|
||||
placeholderNode = itemNode
|
||||
}
|
||||
}
|
||||
case .trending:
|
||||
self.trendingPane.gridNode.forEachItemNode { itemNode in
|
||||
if let itemNode = itemNode as? PaneSearchBarPlaceholderNode {
|
||||
placeholderNode = itemNode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1558,15 +1566,22 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
var placeholderNode: PaneSearchBarPlaceholderNode?
|
||||
if let searchMode = searchMode {
|
||||
switch searchMode {
|
||||
case .gif:
|
||||
placeholderNode = self.gifPane.searchPlaceholderNode
|
||||
paneIsEmpty = self.gifPane.isEmpty
|
||||
case .sticker:
|
||||
self.stickerPane.gridNode.forEachItemNode { itemNode in
|
||||
if let itemNode = itemNode as? PaneSearchBarPlaceholderNode {
|
||||
placeholderNode = itemNode
|
||||
}
|
||||
case .gif:
|
||||
placeholderNode = self.gifPane.searchPlaceholderNode
|
||||
paneIsEmpty = self.gifPane.isEmpty
|
||||
case .sticker:
|
||||
self.stickerPane.gridNode.forEachItemNode { itemNode in
|
||||
if let itemNode = itemNode as? PaneSearchBarPlaceholderNode {
|
||||
placeholderNode = itemNode
|
||||
}
|
||||
}
|
||||
case .trending:
|
||||
self.trendingPane.gridNode.forEachItemNode { itemNode in
|
||||
if let itemNode = itemNode as? PaneSearchBarPlaceholderNode {
|
||||
placeholderNode = itemNode
|
||||
}
|
||||
}
|
||||
paneIsEmpty = true
|
||||
}
|
||||
}
|
||||
if let placeholderNode = placeholderNode {
|
||||
|
@ -18,15 +18,17 @@ final class TrendingPaneInteraction {
|
||||
let installPack: (ItemCollectionInfo) -> Void
|
||||
let openPack: (ItemCollectionInfo) -> Void
|
||||
let getItemIsPreviewed: (StickerPackItem) -> Bool
|
||||
let openSearch: () -> Void
|
||||
|
||||
init(installPack: @escaping (ItemCollectionInfo) -> Void, openPack: @escaping (ItemCollectionInfo) -> Void, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool) {
|
||||
init(installPack: @escaping (ItemCollectionInfo) -> Void, openPack: @escaping (ItemCollectionInfo) -> Void, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool, openSearch: @escaping () -> Void) {
|
||||
self.installPack = installPack
|
||||
self.openPack = openPack
|
||||
self.getItemIsPreviewed = getItemIsPreviewed
|
||||
self.openSearch = openSearch
|
||||
}
|
||||
}
|
||||
|
||||
final class TrendingPaneEntry: Identifiable, Comparable {
|
||||
final class TrendingPanePackEntry: Identifiable, Comparable {
|
||||
let index: Int
|
||||
let info: StickerPackCollectionInfo
|
||||
let theme: PresentationTheme
|
||||
@ -51,7 +53,7 @@ final class TrendingPaneEntry: Identifiable, Comparable {
|
||||
return self.info.id
|
||||
}
|
||||
|
||||
static func ==(lhs: TrendingPaneEntry, rhs: TrendingPaneEntry) -> Bool {
|
||||
static func ==(lhs: TrendingPanePackEntry, rhs: TrendingPanePackEntry) -> Bool {
|
||||
if lhs.index != rhs.index {
|
||||
return false
|
||||
}
|
||||
@ -79,7 +81,7 @@ final class TrendingPaneEntry: Identifiable, Comparable {
|
||||
return true
|
||||
}
|
||||
|
||||
static func <(lhs: TrendingPaneEntry, rhs: TrendingPaneEntry) -> Bool {
|
||||
static func <(lhs: TrendingPanePackEntry, rhs: TrendingPanePackEntry) -> Bool {
|
||||
return lhs.index < rhs.index
|
||||
}
|
||||
|
||||
@ -95,6 +97,67 @@ final class TrendingPaneEntry: Identifiable, Comparable {
|
||||
}
|
||||
}
|
||||
|
||||
private enum TrendingPaneEntryId: Hashable {
|
||||
case search
|
||||
case pack(ItemCollectionId)
|
||||
}
|
||||
|
||||
private enum TrendingPaneEntry: Identifiable, Comparable {
|
||||
case search(theme: PresentationTheme, strings: PresentationStrings)
|
||||
case pack(TrendingPanePackEntry)
|
||||
|
||||
var stableId: TrendingPaneEntryId {
|
||||
switch self {
|
||||
case .search:
|
||||
return .search
|
||||
case let .pack(pack):
|
||||
return .pack(pack.stableId)
|
||||
}
|
||||
}
|
||||
|
||||
static func ==(lhs: TrendingPaneEntry, rhs: TrendingPaneEntry) -> Bool {
|
||||
switch lhs {
|
||||
case let .search(lhsTheme, lhsStrings):
|
||||
if case let .search(rhsTheme, rhsStrings) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .pack(pack):
|
||||
if case .pack(pack) = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static func <(lhs: TrendingPaneEntry, rhs: TrendingPaneEntry) -> Bool {
|
||||
switch lhs {
|
||||
case .search:
|
||||
return false
|
||||
case let .pack(lhsPack):
|
||||
switch rhs {
|
||||
case .search:
|
||||
return false
|
||||
case let .pack(rhsPack):
|
||||
return lhsPack < rhsPack
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func item(account: Account, interaction: TrendingPaneInteraction, grid: Bool) -> GridItem {
|
||||
switch self {
|
||||
case let .search(theme, strings):
|
||||
return PaneSearchBarPlaceholderItem(theme: theme, strings: strings, type: .stickers, activate: {
|
||||
interaction.openSearch()
|
||||
})
|
||||
case let .pack(pack):
|
||||
return pack.item(account: account, interaction: interaction, grid: grid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private struct TrendingPaneTransition {
|
||||
let deletions: [Int]
|
||||
let insertions: [GridNodeInsertItem]
|
||||
@ -112,12 +175,15 @@ private func preparedTransition(from fromEntries: [TrendingPaneEntry], to toEntr
|
||||
return TrendingPaneTransition(deletions: deletions, insertions: insertions, updates: updates, initial: initial)
|
||||
}
|
||||
|
||||
func trendingPaneEntries(trendingEntries: [FeaturedStickerPackItem], installedPacks: Set<ItemCollectionId>, theme: PresentationTheme, strings: PresentationStrings) -> [TrendingPaneEntry] {
|
||||
private func trendingPaneEntries(trendingEntries: [FeaturedStickerPackItem], installedPacks: Set<ItemCollectionId>, theme: PresentationTheme, strings: PresentationStrings, isPane: Bool) -> [TrendingPaneEntry] {
|
||||
var result: [TrendingPaneEntry] = []
|
||||
var index = 0
|
||||
if isPane {
|
||||
result.append(.search(theme: theme, strings: strings))
|
||||
}
|
||||
for item in trendingEntries {
|
||||
if !installedPacks.contains(item.info.id) {
|
||||
result.append(TrendingPaneEntry(index: index, info: item.info, theme: theme, strings: strings, topItems: item.topItems, installed: installedPacks.contains(item.info.id), unread: item.unread, topSeparator: index != 0))
|
||||
result.append(.pack(TrendingPanePackEntry(index: index, info: item.info, theme: theme, strings: strings, topItems: item.topItems, installed: installedPacks.contains(item.info.id), unread: item.unread, topSeparator: index != 0)))
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
@ -128,6 +194,7 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
||||
private let context: AccountContext
|
||||
private let controllerInteraction: ChatControllerInteraction
|
||||
private let getItemIsPreviewed: (StickerPackItem) -> Bool
|
||||
private let isPane: Bool
|
||||
|
||||
let gridNode: GridNode
|
||||
|
||||
@ -147,10 +214,11 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
||||
|
||||
private let installDisposable = MetaDisposable()
|
||||
|
||||
init(context: AccountContext, controllerInteraction: ChatControllerInteraction, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool) {
|
||||
init(context: AccountContext, controllerInteraction: ChatControllerInteraction, getItemIsPreviewed: @escaping (StickerPackItem) -> Bool, isPane: Bool) {
|
||||
self.context = context
|
||||
self.controllerInteraction = controllerInteraction
|
||||
self.getItemIsPreviewed = getItemIsPreviewed
|
||||
self.isPane = isPane
|
||||
|
||||
self.gridNode = GridNode()
|
||||
|
||||
@ -220,7 +288,7 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
||||
}
|
||||
}
|
||||
|> runOn(Queue.mainQueue())
|
||||
|> delay(0.12, queue: Queue.mainQueue())
|
||||
|> delay(1.0, queue: Queue.mainQueue())
|
||||
let progressDisposable = progressSignal.start()
|
||||
|
||||
installSignal = installSignal
|
||||
@ -267,8 +335,12 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
||||
})
|
||||
strongSelf.controllerInteraction.presentController(controller, nil)
|
||||
}
|
||||
}, getItemIsPreviewed: self.getItemIsPreviewed)
|
||||
}, getItemIsPreviewed: self.getItemIsPreviewed,
|
||||
openSearch: { [weak self] in
|
||||
self?.inputNodeInteraction?.toggleSearch(true, .trending)
|
||||
})
|
||||
|
||||
let isPane = self.isPane
|
||||
let previousEntries = Atomic<[TrendingPaneEntry]?>(value: nil)
|
||||
let context = self.context
|
||||
self.disposable = (combineLatest(context.account.viewTracker.featuredStickerPacks(), context.account.postbox.combinedView(keys: [.itemCollectionInfos(namespaces: [Namespaces.ItemCollection.CloudStickerPacks])]), context.sharedContext.presentationData)
|
||||
@ -281,7 +353,7 @@ final class ChatMediaInputTrendingPane: ChatMediaInputPane {
|
||||
}
|
||||
}
|
||||
}
|
||||
let entries = trendingPaneEntries(trendingEntries: trendingEntries, installedPacks: installedPacks, theme: presentationData.theme, strings: presentationData.strings)
|
||||
let entries = trendingPaneEntries(trendingEntries: trendingEntries, installedPacks: installedPacks, theme: presentationData.theme, strings: presentationData.strings, isPane: isPane)
|
||||
let previous = previousEntries.swap(entries)
|
||||
|
||||
return preparedTransition(from: previous ?? [], to: entries, account: context.account, interaction: interaction, initial: previous == nil)
|
||||
|
@ -49,10 +49,10 @@ final class PaneSearchContainerNode: ASDisplayNode {
|
||||
self.controllerInteraction = controllerInteraction
|
||||
self.inputNodeInteraction = inputNodeInteraction
|
||||
switch mode {
|
||||
case .gif:
|
||||
self.contentNode = GifPaneSearchContentNode(context: context, theme: theme, strings: strings, controllerInteraction: controllerInteraction, inputNodeInteraction: inputNodeInteraction, trendingPromise: trendingGifsPromise)
|
||||
case .sticker:
|
||||
self.contentNode = StickerPaneSearchContentNode(context: context, theme: theme, strings: strings, controllerInteraction: controllerInteraction, inputNodeInteraction: inputNodeInteraction)
|
||||
case .gif:
|
||||
self.contentNode = GifPaneSearchContentNode(context: context, theme: theme, strings: strings, controllerInteraction: controllerInteraction, inputNodeInteraction: inputNodeInteraction, trendingPromise: trendingGifsPromise)
|
||||
case .sticker, .trending:
|
||||
self.contentNode = StickerPaneSearchContentNode(context: context, theme: theme, strings: strings, controllerInteraction: controllerInteraction, inputNodeInteraction: inputNodeInteraction)
|
||||
}
|
||||
self.backgroundNode = ASDisplayNode()
|
||||
|
||||
@ -92,10 +92,10 @@ final class PaneSearchContainerNode: ASDisplayNode {
|
||||
|
||||
let placeholder: String
|
||||
switch mode {
|
||||
case .gif:
|
||||
placeholder = strings.Gif_Search
|
||||
case .sticker:
|
||||
placeholder = strings.Stickers_Search
|
||||
case .gif:
|
||||
placeholder = strings.Gif_Search
|
||||
case .sticker, .trending:
|
||||
placeholder = strings.Stickers_Search
|
||||
}
|
||||
self.searchBar.placeholderString = NSAttributedString(string: placeholder, font: Font.regular(17.0), textColor: theme.chat.inputMediaPanel.stickersSearchPlaceholderColor)
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ final class StickerPaneSearchContentNode: ASDisplayNode, PaneSearchContentNode {
|
||||
|
||||
self.trendingPane = ChatMediaInputTrendingPane(context: context, controllerInteraction: controllerInteraction, getItemIsPreviewed: { [weak inputNodeInteraction] item in
|
||||
return inputNodeInteraction?.previewedStickerPackItem == .pack(item)
|
||||
})
|
||||
}, isPane: false)
|
||||
|
||||
self.gridNode = GridNode()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user