Add stickerpack strip expansion

This commit is contained in:
Ilya Laktyushin
2021-07-07 03:12:07 +03:00
parent 21b8a066c2
commit 4a853bf13d
30 changed files with 598 additions and 358 deletions

View File

@@ -34,6 +34,7 @@ struct ChatMediaInputPanelTransition {
let deletions: [ListViewDeleteItem]
let insertions: [ListViewInsertItem]
let updates: [ListViewUpdateItem]
let scrollToItem: ListViewScrollToItem?
}
struct ChatMediaInputGridTransition {
@@ -47,14 +48,14 @@ struct ChatMediaInputGridTransition {
let animated: Bool
}
func preparedChatMediaInputPanelEntryTransition(context: AccountContext, from fromEntries: [ChatMediaInputPanelEntry], to toEntries: [ChatMediaInputPanelEntry], inputNodeInteraction: ChatMediaInputNodeInteraction) -> ChatMediaInputPanelTransition {
func preparedChatMediaInputPanelEntryTransition(context: AccountContext, from fromEntries: [ChatMediaInputPanelEntry], to toEntries: [ChatMediaInputPanelEntry], inputNodeInteraction: ChatMediaInputNodeInteraction, scrollToItem: ListViewScrollToItem?) -> ChatMediaInputPanelTransition {
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, inputNodeInteraction: inputNodeInteraction), directionHint: nil) }
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(context: context, inputNodeInteraction: inputNodeInteraction), directionHint: nil) }
return ChatMediaInputPanelTransition(deletions: deletions, insertions: insertions, updates: updates)
return ChatMediaInputPanelTransition(deletions: deletions, insertions: insertions, updates: updates, scrollToItem: scrollToItem)
}
func preparedChatMediaInputGridEntryTransition(account: Account, view: ItemCollectionsView, from fromEntries: [ChatMediaInputGridEntry], to toEntries: [ChatMediaInputGridEntry], update: StickerPacksCollectionUpdate, interfaceInteraction: ChatControllerInteraction, inputNodeInteraction: ChatMediaInputNodeInteraction, trendingInteraction: TrendingPaneInteraction) -> ChatMediaInputGridTransition {
@@ -152,16 +153,16 @@ func preparedChatMediaInputGridEntryTransition(account: Account, view: ItemColle
return ChatMediaInputGridTransition(deletions: deletions, insertions: insertions, updates: updates, updateFirstIndexInSectionOffset: firstIndexInSectionOffset, stationaryItems: stationaryItems, scrollToItem: scrollToItem, updateOpaqueState: opaqueState, animated: animated)
}
func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, hasUnreadTrending: Bool?, theme: PresentationTheme, hasGifs: Bool = true, hasSettings: Bool = true) -> [ChatMediaInputPanelEntry] {
func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, hasUnreadTrending: Bool?, theme: PresentationTheme, hasGifs: Bool = true, hasSettings: Bool = true, expanded: Bool = false) -> [ChatMediaInputPanelEntry] {
var entries: [ChatMediaInputPanelEntry] = []
if hasGifs {
entries.append(.recentGifs(theme))
entries.append(.recentGifs(theme, expanded))
}
if let hasUnreadTrending = hasUnreadTrending {
entries.append(.trending(hasUnreadTrending, theme))
entries.append(.trending(hasUnreadTrending, theme, expanded))
}
if let savedStickers = savedStickers, !savedStickers.items.isEmpty {
entries.append(.savedStickers(theme))
entries.append(.savedStickers(theme, expanded))
}
var savedStickerIds = Set<Int64>()
if let savedStickers = savedStickers, !savedStickers.items.isEmpty {
@@ -182,40 +183,40 @@ func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: Ordere
}
}
if found {
entries.append(.recentPacks(theme))
entries.append(.recentPacks(theme, expanded))
}
}
if let peerSpecificPack = peerSpecificPack {
entries.append(.peerSpecific(theme: theme, peer: peerSpecificPack.peer))
entries.append(.peerSpecific(theme: theme, peer: peerSpecificPack.peer, expanded: expanded))
} else if case let .available(peer, false) = canInstallPeerSpecificPack {
entries.append(.peerSpecific(theme: theme, peer: peer))
entries.append(.peerSpecific(theme: theme, peer: peer, expanded: expanded))
}
var index = 0
for (_, info, item) in view.collectionInfos {
if let info = info as? StickerPackCollectionInfo, item != nil {
entries.append(.stickerPack(index: index, info: info, topItem: item as? StickerPackItem, theme: theme))
entries.append(.stickerPack(index: index, info: info, topItem: item as? StickerPackItem, theme: theme, expanded: expanded))
index += 1
}
}
if peerSpecificPack == nil, case let .available(peer, true) = canInstallPeerSpecificPack {
entries.append(.peerSpecific(theme: theme, peer: peer))
entries.append(.peerSpecific(theme: theme, peer: peer, expanded: expanded))
}
if hasSettings {
entries.append(.settings(theme))
entries.append(.settings(theme, expanded))
}
return entries
}
func chatMediaInputPanelGifModeEntries(theme: PresentationTheme, reactions: [String]) -> [ChatMediaInputPanelEntry] {
func chatMediaInputPanelGifModeEntries(theme: PresentationTheme, reactions: [String], expanded: Bool) -> [ChatMediaInputPanelEntry] {
var entries: [ChatMediaInputPanelEntry] = []
entries.append(.stickersMode(theme))
entries.append(.savedGifs(theme))
entries.append(.trendingGifs(theme))
entries.append(.stickersMode(theme, expanded))
entries.append(.savedGifs(theme, expanded))
entries.append(.trendingGifs(theme, expanded))
for reaction in reactions {
entries.append(.gifEmotion(entries.count, theme, reaction))
entries.append(.gifEmotion(entries.count, theme, reaction, expanded))
}
return entries
@@ -451,6 +452,15 @@ final class ChatMediaInputNode: ChatInputNode {
private var currentView: ItemCollectionsView?
private let dismissedPeerSpecificStickerPack = Promise<Bool>()
private var panelCollapseScrollToIndex: Int?
private let panelExpandedPromise = ValuePromise<Bool>(false)
private var panelExpanded: Bool = false {
didSet {
self.panelExpandedPromise.set(self.panelExpanded)
}
}
private var panelCollapseTimer: SwiftSignalKit.Timer?
var requestDisableStickerAnimations: ((Bool) -> Void)?
private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, ChatPresentationInterfaceState, DeviceMetrics, Bool)?
@@ -495,6 +505,7 @@ final class ChatMediaInputNode: ChatInputNode {
self.collectionListContainer.clipsToBounds = true
self.listView = ListView()
// self.listView.clipsToBounds = false
self.listView.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
self.listView.scroller.panGestureRecognizer.cancelsTouchesInView = false
self.listView.accessibilityPageScrolledString = { row, count in
@@ -502,6 +513,7 @@ final class ChatMediaInputNode: ChatInputNode {
}
self.gifListView = ListView()
// self.gifListView.clipsToBounds = false
self.gifListView.transform = CATransform3DMakeRotation(-CGFloat(Double.pi / 2.0), 0.0, 0.0, 1.0)
self.gifListView.scroller.panGestureRecognizer.cancelsTouchesInView = false
self.gifListView.accessibilityPageScrolledString = { row, count in
@@ -527,7 +539,7 @@ final class ChatMediaInputNode: ChatInputNode {
var getItemIsPreviewedImpl: ((StickerPackItem) -> Bool)?
self.paneArrangement = ChatMediaInputPaneArrangement(panes: [.gifs, .stickers, /*.trending*/], currentIndex: 1, indexTransition: 0.0)
self.paneArrangement = ChatMediaInputPaneArrangement(panes: [.gifs, .stickers], currentIndex: 1, indexTransition: 0.0)
super.init()
@@ -548,7 +560,6 @@ final class ChatMediaInputNode: ChatInputNode {
}
}
))
//strongSelf.setCurrentPane(.trending, transition: .animated(duration: 0.25, curve: .spring))
} else if collectionId.namespace == ChatMediaInputPanelAuxiliaryNamespace.savedStickers.rawValue {
strongSelf.setCurrentPane(.stickers, transition: .animated(duration: 0.25, curve: .spring), collectionIdHint: collectionId.namespace)
strongSelf.currentStickerPacksCollectionPosition = .navigate(index: nil, collectionId: collectionId)
@@ -781,7 +792,7 @@ final class ChatMediaInputNode: ChatInputNode {
}
let trendingInteraction = TrendingPaneInteraction(installPack: { [weak self] info in
guard let strongSelf = self, let info = info as? StickerPackCollectionInfo else {
guard let info = info as? StickerPackCollectionInfo else {
return
}
let _ = (context.engine.stickers.loadedStickerPack(reference: .id(id: info.id.id, accessHash: info.accessHash), forceActualized: false)
@@ -846,8 +857,8 @@ final class ChatMediaInputNode: ChatInputNode {
let previousView = Atomic<ItemCollectionsView?>(value: nil)
let transitionQueue = Queue()
let transitions = combineLatest(queue: transitionQueue, itemCollectionsView, peerSpecificPack, context.account.viewTracker.featuredStickerPacks(), self.themeAndStringsPromise.get(), reactions)
|> map { viewAndUpdate, peerSpecificPack, trendingPacks, themeAndStrings, reactions -> (ItemCollectionsView, ChatMediaInputPanelTransition, ChatMediaInputPanelTransition, Bool, ChatMediaInputGridTransition, Bool) in
let transitions = combineLatest(queue: transitionQueue, itemCollectionsView, peerSpecificPack, context.account.viewTracker.featuredStickerPacks(), self.themeAndStringsPromise.get(), reactions, self.panelExpandedPromise.get())
|> map { viewAndUpdate, peerSpecificPack, trendingPacks, themeAndStrings, reactions, panelExpanded -> (ItemCollectionsView, ChatMediaInputPanelTransition, ChatMediaInputPanelTransition, Bool, ChatMediaInputGridTransition, Bool) in
let (view, viewUpdate) = viewAndUpdate
let previous = previousView.swap(view)
var update = viewUpdate
@@ -882,8 +893,8 @@ final class ChatMediaInputNode: ChatInputNode {
}
}
let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, hasUnreadTrending: hasUnreadTrending, theme: theme)
let gifPaneEntries = chatMediaInputPanelGifModeEntries(theme: theme, reactions: reactions)
let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, hasUnreadTrending: hasUnreadTrending, theme: theme, expanded: panelExpanded)
let gifPaneEntries = chatMediaInputPanelGifModeEntries(theme: theme, reactions: reactions, expanded: panelExpanded)
var gridEntries = chatMediaInputGridEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, strings: strings, theme: theme)
if view.higher == nil {
@@ -901,9 +912,9 @@ final class ChatMediaInputNode: ChatInputNode {
}
}
}
let (previousPanelEntries, previousGifPaneEntries, previousGridEntries) = previousEntries.swap((panelEntries, gifPaneEntries, gridEntries))
return (view, preparedChatMediaInputPanelEntryTransition(context: context, from: previousPanelEntries, to: panelEntries, inputNodeInteraction: inputNodeInteraction), preparedChatMediaInputPanelEntryTransition(context: context, from: previousGifPaneEntries, to: gifPaneEntries, inputNodeInteraction: inputNodeInteraction), previousPanelEntries.isEmpty, preparedChatMediaInputGridEntryTransition(account: context.account, view: view, from: previousGridEntries, to: gridEntries, update: update, interfaceInteraction: controllerInteraction, inputNodeInteraction: inputNodeInteraction, trendingInteraction: trendingInteraction), previousGridEntries.isEmpty)
return (view, preparedChatMediaInputPanelEntryTransition(context: context, from: previousPanelEntries, to: panelEntries, inputNodeInteraction: inputNodeInteraction, scrollToItem: nil), preparedChatMediaInputPanelEntryTransition(context: context, from: previousGifPaneEntries, to: gifPaneEntries, inputNodeInteraction: inputNodeInteraction, scrollToItem: nil), previousPanelEntries.isEmpty, preparedChatMediaInputGridEntryTransition(account: context.account, view: view, from: previousGridEntries, to: gridEntries, update: update, interfaceInteraction: controllerInteraction, inputNodeInteraction: inputNodeInteraction, trendingInteraction: trendingInteraction), previousGridEntries.isEmpty)
}
self.disposable.set((transitions
@@ -970,7 +981,6 @@ 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)
@@ -983,11 +993,59 @@ final class ChatMediaInputNode: ChatInputNode {
openGifContextMenuImpl = { [weak self] file, sourceNode, sourceRect, gesture, isSaved in
self?.openGifContextMenu(file: file, sourceNode: sourceNode, sourceRect: sourceRect, gesture: gesture, isSaved: isSaved)
}
self.listView.beganInteractiveDragging = { [weak self] position in
if let strongSelf = self, false {
if !strongSelf.panelExpanded, let index = strongSelf.listView.itemIndexAtPoint(CGPoint(x: 0.0, y: position.y)) {
strongSelf.panelCollapseScrollToIndex = index
}
strongSelf.updateIsExpanded(true)
}
}
self.listView.didEndScrolling = { [weak self] in
if let strongSelf = self, false {
strongSelf.setupCollapseTimer()
}
}
self.gifListView.beganInteractiveDragging = { [weak self] position in
if let strongSelf = self, false {
if !strongSelf.panelExpanded, let index = strongSelf.gifListView.itemIndexAtPoint(CGPoint(x: 0.0, y: position.y)) {
strongSelf.panelCollapseScrollToIndex = index
}
strongSelf.updateIsExpanded(true)
}
}
self.gifListView.didEndScrolling = { [weak self] in
if let strongSelf = self, false {
strongSelf.setupCollapseTimer()
}
}
}
deinit {
self.disposable.dispose()
self.searchContainerNodeLoadedDisposable.dispose()
self.panelCollapseTimer?.invalidate()
}
private func updateIsExpanded(_ isExpanded: Bool) {
self.panelCollapseTimer?.invalidate()
self.panelExpanded = isExpanded
self.updatePaneClippingContainer(size: self.paneClippingContainer.bounds.size, offset: self.currentCollectionListPanelOffset(), transition: .animated(duration: 0.3, curve: .spring))
}
private func setupCollapseTimer() {
self.panelCollapseTimer?.invalidate()
let timer = SwiftSignalKit.Timer(timeout: 1.5, repeat: false, completion: { [weak self] in
self?.updateIsExpanded(false)
}, queue: Queue.mainQueue())
self.panelCollapseTimer = timer
timer.start()
}
private func openGifContextMenu(file: MultiplexedVideoNodeFile, sourceNode: ASDisplayNode, sourceRect: CGRect, gesture: ContextGesture, isSaved: Bool) {
@@ -1215,7 +1273,7 @@ final class ChatMediaInputNode: ChatInputNode {
}
}
} else {
panes = [strongSelf.gifPane, strongSelf.stickerPane/*, strongSelf.trendingPane*/]
panes = [strongSelf.gifPane, strongSelf.stickerPane]
}
let panelPoint = strongSelf.view.convert(point, to: strongSelf.collectionListPanel.view)
if panelPoint.y < strongSelf.collectionListPanel.frame.maxY {
@@ -1367,19 +1425,11 @@ final class ChatMediaInputNode: ChatInputNode {
}
private func setCurrentPane(_ pane: ChatMediaInputPaneType, transition: ContainedViewLayoutTransition, collectionIdHint: Int32? = nil) {
var transition = transition
if let index = self.paneArrangement.panes.firstIndex(of: pane), index != self.paneArrangement.currentIndex {
let previousGifPanelWasActive = self.paneArrangement.panes[self.paneArrangement.currentIndex] == .gifs
//let previousTrendingPanelWasActive = self.paneArrangement.panes[self.paneArrangement.currentIndex] == .trending
self.paneArrangement = self.paneArrangement.withIndexTransition(0.0).withCurrentIndex(index)
let updatedGifPanelWasActive = self.paneArrangement.panes[self.paneArrangement.currentIndex] == .gifs
//let updatedTrendingPanelIsActive = self.paneArrangement.panes[self.paneArrangement.currentIndex] == .trending
/*if updatedTrendingPanelIsActive != previousTrendingPanelWasActive {
transition = .immediate
}*/
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible) = self.validLayout {
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: transition, interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible)
self.updateAppearanceTransition(transition: transition)
@@ -1396,23 +1446,7 @@ final class ChatMediaInputNode: ChatInputNode {
} else if let collectionIdHint = collectionIdHint {
self.setHighlightedItemCollectionId(ItemCollectionId(namespace: collectionIdHint, id: 0))
}
/*case .trending:
self.setHighlightedItemCollectionId(ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.trending.rawValue, id: 0))*/
}
/*if updatedTrendingPanelIsActive != previousTrendingPanelWasActive {
self.controllerInteraction.updateInputMode { current in
switch current {
case let .media(mode, _):
if updatedTrendingPanelIsActive {
return .media(mode: mode, expanded: .content)
} else {
return .media(mode: mode, expanded: nil)
}
default:
return current
}
}
}*/
} else {
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible) = self.validLayout {
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .animated(duration: 0.25, curve: .spring), interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible)
@@ -1425,10 +1459,6 @@ final class ChatMediaInputNode: ChatInputNode {
if self.paneArrangement.panes[self.paneArrangement.currentIndex] == .gifs {
self.inputNodeInteraction.highlightedItemCollectionId = collectionId
}
} else if collectionId.namespace == ChatMediaInputPanelAuxiliaryNamespace.trending.rawValue {
/*if self.paneArrangement.panes[self.paneArrangement.currentIndex] == .trending {
self.inputNodeInteraction.highlightedItemCollectionId = collectionId
}*/
} else {
self.inputNodeInteraction.highlightedStickerItemCollectionId = collectionId
if self.paneArrangement.panes[self.paneArrangement.currentIndex] == .stickers {
@@ -1469,31 +1499,56 @@ final class ChatMediaInputNode: ChatInputNode {
}
itemNode.updateIsHighlighted()
if itemNode.currentCollectionId == collectionId {
self.listView.ensureItemNodeVisible(itemNode)
if self.panelExpanded, let targetIndex = self.listView.indexOf(itemNode: itemNode) {
self.panelCollapseScrollToIndex = targetIndex
self.updateIsExpanded(false)
} else {
self.listView.ensureItemNodeVisible(itemNode)
}
ensuredNodeVisible = true
}
} else if let itemNode = itemNode as? ChatMediaInputMetaSectionItemNode {
itemNode.updateIsHighlighted()
if itemNode.currentCollectionId == collectionId {
self.listView.ensureItemNodeVisible(itemNode)
if self.panelExpanded, let targetIndex = self.listView.indexOf(itemNode: itemNode) {
self.panelCollapseScrollToIndex = targetIndex
self.updateIsExpanded(false)
} else {
self.listView.ensureItemNodeVisible(itemNode)
}
ensuredNodeVisible = true
}
} else if let itemNode = itemNode as? ChatMediaInputRecentGifsItemNode {
itemNode.updateIsHighlighted()
if itemNode.currentCollectionId == collectionId {
self.listView.ensureItemNodeVisible(itemNode)
if self.panelExpanded, let targetIndex = self.listView.indexOf(itemNode: itemNode) {
self.panelCollapseScrollToIndex = targetIndex
self.updateIsExpanded(false)
} else {
self.listView.ensureItemNodeVisible(itemNode)
}
ensuredNodeVisible = true
}
} else if let itemNode = itemNode as? ChatMediaInputTrendingItemNode {
itemNode.updateIsHighlighted()
if itemNode.currentCollectionId == collectionId {
self.listView.ensureItemNodeVisible(itemNode)
if self.panelExpanded, let targetIndex = self.listView.indexOf(itemNode: itemNode) {
self.panelCollapseScrollToIndex = targetIndex
self.updateIsExpanded(false)
} else {
self.listView.ensureItemNodeVisible(itemNode)
}
ensuredNodeVisible = true
}
} else if let itemNode = itemNode as? ChatMediaInputPeerSpecificItemNode {
itemNode.updateIsHighlighted()
if itemNode.currentCollectionId == collectionId {
self.listView.ensureItemNodeVisible(itemNode)
if self.panelExpanded, let targetIndex = self.listView.indexOf(itemNode: itemNode) {
self.panelCollapseScrollToIndex = targetIndex
self.updateIsExpanded(false)
} else {
self.listView.ensureItemNodeVisible(itemNode)
}
ensuredNodeVisible = true
}
}
@@ -1504,7 +1559,12 @@ final class ChatMediaInputNode: ChatInputNode {
let firstVisibleIndex = currentView.collectionInfos.firstIndex(where: { id, _, _ in return id == firstVisibleCollectionId })
if let targetIndex = targetIndex, let firstVisibleIndex = firstVisibleIndex {
let toRight = targetIndex > firstVisibleIndex
self.listView.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [], scrollToItem: ListViewScrollToItem(index: targetIndex, position: toRight ? .bottom(0.0) : .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: toRight ? .Down : .Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil)
if self.panelExpanded {
self.panelCollapseScrollToIndex = targetIndex
self.updateIsExpanded(false)
} else {
self.listView.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [], scrollToItem: ListViewScrollToItem(index: targetIndex, position: toRight ? .bottom(0.0) : .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: toRight ? .Down : .Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil)
}
}
}
}
@@ -1516,8 +1576,6 @@ final class ChatMediaInputNode: ChatInputNode {
return self.stickerPane.collectionListPanelOffset
case .gifs:
return self.gifPane.collectionListPanelOffset
/*case .trending:
return self.trendingPane.collectionListPanelOffset*/
}
}
@@ -1611,7 +1669,6 @@ final class ChatMediaInputNode: ChatInputNode {
}
self.stickerPane.collectionListPanelOffset = 0.0
self.gifPane.collectionListPanelOffset = 0.0
//self.trendingPane.collectionListPanelOffset = 0.0
self.updateAppearanceTransition(transition: transition)
} else {
panelHeight = standardInputHeight
@@ -1642,11 +1699,6 @@ final class ChatMediaInputNode: ChatInputNode {
}
}
case .trending:
/*self.trendingPane.gridNode.forEachItemNode { itemNode in
if let itemNode = itemNode as? PaneSearchBarPlaceholderNode {
placeholderNode = itemNode
}
}*/
break
}
}
@@ -1666,14 +1718,14 @@ final class ChatMediaInputNode: ChatInputNode {
transition.updateFrame(node: self.collectionListPanel, frame: CGRect(origin: CGPoint(x: 0.0, y: collectionListPanelOffset), size: CGSize(width: width, height: 41.0)))
transition.updateFrame(node: self.collectionListSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: 41.0 + collectionListPanelOffset), size: CGSize(width: width, height: separatorHeight)))
self.listView.bounds = CGRect(x: 0.0, y: 0.0, width: 41.0, height: width)
self.listView.bounds = CGRect(x: 0.0, y: 0.0, width: 41.0 + 31.0 + 20.0, height: width)
transition.updatePosition(node: self.listView, position: CGPoint(x: width / 2.0, y: (41.0 - collectionListPanelOffset) / 2.0))
self.gifListView.bounds = CGRect(x: 0.0, y: 0.0, width: 41.0, height: width)
self.gifListView.bounds = CGRect(x: 0.0, y: 0.0, width: 41.0 + 31.0 + 20.0, height: width)
transition.updatePosition(node: self.gifListView, position: CGPoint(x: width / 2.0, y: (41.0 - collectionListPanelOffset) / 2.0))
let (duration, curve) = listViewAnimationDurationAndCurve(transition: transition)
let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: CGSize(width: 41.0, height: width), insets: UIEdgeInsets(top: 4.0 + leftInset, left: 0.0, bottom: 4.0 + rightInset, right: 0.0), duration: duration, curve: curve)
let updateSizeAndInsets = ListViewUpdateSizeAndInsets(size: CGSize(width: 41.0 + 31.0 + 20.0, height: width), insets: UIEdgeInsets(top: 4.0 + leftInset, left: 0.0, bottom: 4.0 + rightInset, right: 0.0), duration: duration, curve: curve)
self.listView.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: nil, updateSizeAndInsets: updateSizeAndInsets, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
@@ -1721,7 +1773,6 @@ final class ChatMediaInputNode: ChatInputNode {
self.gifPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, isVisible: isVisible, deviceMetrics: deviceMetrics, transition: transition)
self.trendingInteraction?.itemContext.canPlayMedia = isVisible
self.stickerPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, isVisible: isVisible && visiblePanes.contains(where: { $0.0 == .stickers }), deviceMetrics: deviceMetrics, transition: transition)
//self.trendingPane.updateLayout(size: CGSize(width: width - leftInset - rightInset, height: panelHeight), topInset: 41.0, bottomInset: bottomInset, isExpanded: isExpanded, isVisible: isVisible, deviceMetrics: deviceMetrics, transition: transition)
if self.gifPane.supernode != nil {
if !visiblePanes.contains(where: { $0.0 == .gifs }) {
@@ -1773,31 +1824,6 @@ final class ChatMediaInputNode: ChatInputNode {
self.animatingStickerPaneOut = false
}
/*if self.trendingPane.supernode != nil {
if !visiblePanes.contains(where: { $0.0 == .trending }) {
if case .animated = transition {
if !self.animatingTrendingPaneOut {
self.animatingTrendingPaneOut = true
var toLeft = false
if let index = self.paneArrangement.panes.firstIndex(of: .trending), index < self.paneArrangement.currentIndex {
toLeft = true
}
transition.animatePosition(node: self.trendingPane, to: CGPoint(x: (toLeft ? -width : width) + width / 2.0, y: self.trendingPane.layer.position.y), removeOnCompletion: false, completion: { [weak self] value in
if let strongSelf = self, value {
strongSelf.animatingTrendingPaneOut = false
strongSelf.trendingPane.removeFromSupernode()
}
})
}
} else {
self.animatingTrendingPaneOut = false
self.trendingPane.removeFromSupernode()
}
}
} else {
self.animatingTrendingPaneOut = false
}*/
if !displaySearch, let searchContainerNode = self.searchContainerNode {
self.searchContainerNode = nil
self.searchContainerNodeLoadedDisposable.set(nil)
@@ -1820,12 +1846,6 @@ final class ChatMediaInputNode: ChatInputNode {
}
}
case .trending:
/*self.trendingPane.gridNode.forEachItemNode { itemNode in
if let itemNode = itemNode as? PaneSearchBarPlaceholderNode {
placeholderNode = itemNode
}
}
paneIsEmpty = true*/
break
}
}
@@ -1866,7 +1886,20 @@ final class ChatMediaInputNode: ChatInputNode {
} else {
options.insert(.AnimateInsertion)
}
self.listView.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, updateOpaqueState: nil, completion: { [weak self] _ in
var scrollToItem: ListViewScrollToItem?
if let targetIndex = self.panelCollapseScrollToIndex {
var position: ListViewScrollPosition
if self.panelExpanded {
position = .center(.top)
} else {
position = .top(self.listView.frame.height / 2.0 + 96.0)
}
scrollToItem = ListViewScrollToItem(index: targetIndex, position: position, animated: true, curve: .Default(duration: nil), directionHint: .Down)
self.panelCollapseScrollToIndex = nil
}
self.listView.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, scrollToItem: scrollToItem, updateOpaqueState: nil, completion: { [weak self] _ in
if let strongSelf = self {
strongSelf.enqueueGridTransition(gridTransition, firstTime: gridFirstTime)
if !strongSelf.didSetReady {
@@ -1904,7 +1937,6 @@ final class ChatMediaInputNode: ChatInputNode {
}
self.searchContainerNode?.contentNode.updatePreviewing(animated: animated)
//self.trendingPane.updatePreviewing(animated: animated)
}
}
@@ -1921,11 +1953,6 @@ final class ChatMediaInputNode: ChatInputNode {
self.animatingStickerPaneOut = false
self.stickerPane.removeFromSupernode()
}
/*self.trendingPane.layer.removeAllAnimations()
if self.animatingTrendingPaneOut {
self.animatingTrendingPaneOut = false
self.trendingPane.removeFromSupernode()
}*/
case .changed:
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible) = self.validLayout {
let translationX = -recognizer.translation(in: self.view).x
@@ -1990,20 +2017,31 @@ final class ChatMediaInputNode: ChatInputNode {
}
}
let collectionListPanelOffset = self.currentCollectionListPanelOffset()
var collectionListPanelOffset = self.currentCollectionListPanelOffset()
if self.panelExpanded {
collectionListPanelOffset = 0.0
}
var listPanelOffset = collectionListPanelOffset * 2.0
self.updateAppearanceTransition(transition: transition)
transition.updateFrame(node: self.collectionListPanel, frame: CGRect(origin: CGPoint(x: 0.0, y: collectionListPanelOffset), size: self.collectionListPanel.bounds.size))
transition.updateFrame(node: self.collectionListSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: 41.0 + collectionListPanelOffset), size: self.collectionListSeparator.bounds.size))
transition.updatePosition(node: self.listView, position: CGPoint(x: self.listView.position.x, y: (41.0 - collectionListPanelOffset) / 2.0))
transition.updatePosition(node: self.gifListView, position: CGPoint(x: self.gifListView.position.x, y: (41.0 - collectionListPanelOffset) / 2.0))
transition.updateFrame(node: self.collectionListPanel, frame: CGRect(origin: CGPoint(x: 0.0, y: listPanelOffset), size: self.collectionListPanel.bounds.size))
transition.updatePosition(node: self.listView, position: CGPoint(x: self.listView.position.x, y: (41.0 - listPanelOffset) / 2.0))
transition.updatePosition(node: self.gifListView, position: CGPoint(x: self.gifListView.position.x, y: (41.0 - listPanelOffset) / 2.0))
self.updatePaneClippingContainer(size: self.paneClippingContainer.bounds.size, offset: collectionListPanelOffset, transition: transition)
}
private func updatePaneClippingContainer(size: CGSize, offset: CGFloat, transition: ContainedViewLayoutTransition) {
transition.updateFrame(node: self.paneClippingContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: offset + 41.0), size: size))
transition.updateSublayerTransformOffset(layer: self.paneClippingContainer.layer, offset: CGPoint(x: 0.0, y: -offset - 41.0))
var offset = offset
var additionalOffset: CGFloat = 0.0
if self.panelExpanded {
offset = 0.0
additionalOffset = 31.0
}
transition.updateFrame(node: self.collectionListSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: offset + 41.0 + additionalOffset), size: self.collectionListSeparator.bounds.size))
transition.updateFrame(node: self.paneClippingContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: offset + 41.0 + additionalOffset), size: size))
transition.updateSublayerTransformOffset(layer: self.paneClippingContainer.layer, offset: CGPoint(x: 0.0, y: -offset - 41.0 - additionalOffset))
}
private func fixPaneScroll(pane: ChatMediaInputPane, state: ChatMediaInputPaneScrollState) {
@@ -2017,12 +2055,14 @@ final class ChatMediaInputNode: ChatInputNode {
}
}
let collectionListPanelOffset = self.currentCollectionListPanelOffset()
var collectionListPanelOffset = self.currentCollectionListPanelOffset()
if self.panelExpanded {
collectionListPanelOffset = 0.0
}
let transition = ContainedViewLayoutTransition.animated(duration: 0.25, curve: .spring)
self.updateAppearanceTransition(transition: transition)
transition.updateFrame(node: self.collectionListPanel, frame: CGRect(origin: CGPoint(x: 0.0, y: collectionListPanelOffset), size: self.collectionListPanel.bounds.size))
transition.updateFrame(node: self.collectionListSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: 41.0 + collectionListPanelOffset), size: self.collectionListSeparator.bounds.size))
transition.updatePosition(node: self.listView, position: CGPoint(x: self.listView.position.x, y: (41.0 - collectionListPanelOffset) / 2.0))
transition.updatePosition(node: self.gifListView, position: CGPoint(x: self.gifListView.position.x, y: (41.0 - collectionListPanelOffset) / 2.0))