mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit '9cf17045e2edf58cb5b99e06640bce81125f42a5'
This commit is contained in:
commit
ed0d8a8409
@ -6768,3 +6768,21 @@ Sorry for the inconvenience.";
|
||||
"Chat.NavigationNoChannels" = "You have no unread channels";
|
||||
|
||||
"Message.SponsoredLabel" = "sponsored";
|
||||
|
||||
"Stickers.Favorites" = "Favorites";
|
||||
"Stickers.Recent" = "Recent";
|
||||
"Stickers.Stickers" = "Stickers";
|
||||
"Stickers.Gifs" = "GIFs";
|
||||
"Stickers.Trending" = "Trending";
|
||||
"Stickers.Settings" = "Settings";
|
||||
|
||||
"Gif.Emotion.Angry" = "Angry";
|
||||
"Gif.Emotion.Surprised" = "Surprised";
|
||||
"Gif.Emotion.Joy" = "Joy";
|
||||
"Gif.Emotion.Kiss" = "Kiss";
|
||||
"Gif.Emotion.Hearts" = "Hearts";
|
||||
"Gif.Emotion.ThumbsUp" = "Thumbs Up";
|
||||
"Gif.Emotion.ThumbsDown" = "Thumbs Down";
|
||||
"Gif.Emotion.RollEyes" = "Roll-Eyes";
|
||||
"Gif.Emotion.Cool" = "Cool";
|
||||
"Gif.Emotion.Party" = "Party";
|
||||
|
@ -328,6 +328,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
private var reorderInProgress: Bool = false
|
||||
private var reorderingItemsCompleted: (() -> Void)?
|
||||
private var reorderScrollStartTimestamp: Double?
|
||||
private var reorderScrollUpdateTimestamp: Double?
|
||||
private var reorderLastTimestamp: Double?
|
||||
public var reorderedItemHasShadow = true
|
||||
|
||||
@ -570,7 +571,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
for i in 0 ..< self.itemNodes.count {
|
||||
if let itemNodeIndex = self.itemNodes[i].index, itemNodeIndex != reorderItemIndex {
|
||||
let itemFrame = self.itemNodes[i].apparentContentFrame
|
||||
// let itemOffset = itemFrame.midY
|
||||
|
||||
let offsetToMin = itemFrame.minY - verticalOffset
|
||||
let offsetToMax = itemFrame.maxY - verticalOffset
|
||||
let deltaOffset: CGFloat
|
||||
@ -579,7 +580,6 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
} else {
|
||||
deltaOffset = offsetToMin
|
||||
}
|
||||
// let deltaOffset = min(itemFrame.minY - verticalOffset, itemFrame.maxY - verticalOffset)
|
||||
if let (_, closestOffset) = closestIndex {
|
||||
if abs(deltaOffset) < abs(closestOffset) {
|
||||
closestIndex = (itemNodeIndex, deltaOffset)
|
||||
@ -590,7 +590,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
}
|
||||
}
|
||||
if let (closestIndexValue, offset) = closestIndex {
|
||||
//print("closest \(closestIndexValue) offset \(offset)")
|
||||
// print("closest \(closestIndexValue) offset \(offset)")
|
||||
var toIndex: Int
|
||||
if offset > 0 {
|
||||
toIndex = closestIndexValue
|
||||
@ -604,7 +604,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
}
|
||||
}
|
||||
if toIndex != reorderItemNode.index {
|
||||
if let reorderLastTimestamp = self.reorderLastTimestamp, timestamp < reorderLastTimestamp + 0.1 {
|
||||
if let reorderLastTimestamp = self.reorderLastTimestamp, timestamp < reorderLastTimestamp + 0.2 {
|
||||
return
|
||||
}
|
||||
if reorderNode.currentState?.0 != reorderItemIndex || reorderNode.currentState?.1 != toIndex {
|
||||
@ -3996,7 +3996,7 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
|
||||
var offset: CGFloat = 6.0
|
||||
if let reorderScrollStartTimestamp = self.reorderScrollStartTimestamp, reorderScrollStartTimestamp + 2.0 < timestamp {
|
||||
offset *= 2.0
|
||||
offset *= 1.5
|
||||
}
|
||||
if reorderOffset < effectiveInsets.top + 10.0 {
|
||||
if self.itemNodes[0].apparentFrame.minY < effectiveInsets.top {
|
||||
@ -4101,7 +4101,13 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
self.enqueueUpdateVisibleItems(synchronous: false)
|
||||
}
|
||||
|
||||
self.checkItemReordering()
|
||||
if scrollingForReorder {
|
||||
if let reorderScrollUpdateTimestamp = self.reorderScrollUpdateTimestamp, timestamp < reorderScrollUpdateTimestamp + 0.05 {
|
||||
return
|
||||
}
|
||||
self.reorderScrollUpdateTimestamp = timestamp
|
||||
self.checkItemReordering(force: true)
|
||||
}
|
||||
}
|
||||
|
||||
override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
|
@ -47,7 +47,7 @@ public final class ListViewReorderingGestureRecognizer: UIGestureRecognizer {
|
||||
|
||||
private func startLongPressTimer() {
|
||||
self.longPressTimer?.invalidate()
|
||||
let longPressTimer = SwiftSignalKit.Timer(timeout: 0.8, repeat: false, completion: { [weak self] in
|
||||
let longPressTimer = SwiftSignalKit.Timer(timeout: 0.6, repeat: false, completion: { [weak self] in
|
||||
self?.longPressTimerFired()
|
||||
}, queue: Queue.mainQueue())
|
||||
self.longPressTimer = longPressTimer
|
||||
|
@ -858,6 +858,8 @@ public final class VoiceChatController: ViewController {
|
||||
|
||||
private var currentLoadToken: String?
|
||||
|
||||
private var scrollAtTop = true
|
||||
|
||||
private var effectiveMuteState: GroupCallParticipantsContext.Participant.MuteState? {
|
||||
if self.pushingToTalk {
|
||||
return nil
|
||||
@ -2175,6 +2177,22 @@ public final class VoiceChatController: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
self.listNode.visibleContentOffsetChanged = { [weak self] offset in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
var scrollAtTop = false
|
||||
if case let .known(value) = offset, value < 180.0 {
|
||||
scrollAtTop = true
|
||||
} else {
|
||||
scrollAtTop = false
|
||||
}
|
||||
if scrollAtTop != strongSelf.scrollAtTop {
|
||||
strongSelf.scrollAtTop = scrollAtTop
|
||||
strongSelf.updateTitle(transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
self.listNode.visibleBottomContentOffsetChanged = { [weak self] offset in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
@ -2613,8 +2631,14 @@ public final class VoiceChatController: ViewController {
|
||||
self?.controller?.present(alertController, in: .window(.root))
|
||||
}), false))
|
||||
} else {
|
||||
let text: String
|
||||
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
text = strongSelf.presentationData.strings.LiveStream_StartRecording
|
||||
} else {
|
||||
text = strongSelf.presentationData.strings.VoiceChat_StartRecording
|
||||
}
|
||||
if strongSelf.callState?.scheduleTimestamp == nil {
|
||||
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.VoiceChat_StartRecording, icon: { theme -> UIImage? in
|
||||
items.append(.action(ContextMenuActionItem(text: text, icon: { theme -> UIImage? in
|
||||
return generateStartRecordingIcon(color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
@ -2623,9 +2647,28 @@ public final class VoiceChatController: ViewController {
|
||||
return
|
||||
}
|
||||
|
||||
let controller = VoiceChatRecordingSetupController(context: strongSelf.context, completion: { [weak self] videoOrientation in
|
||||
if let strongSelf = self {
|
||||
strongSelf.call.setShouldBeRecording(true, title: "", videoOrientation: videoOrientation)
|
||||
// let controller = VoiceChatRecordingSetupController(context: strongSelf.context, completion: { [weak self] videoOrientation in
|
||||
// if let strongSelf = self {
|
||||
// strongSelf.call.setShouldBeRecording(true, title: "", videoOrientation: videoOrientation)
|
||||
//
|
||||
// strongSelf.presentUndoOverlay(content: .voiceChatRecording(text: text), action: { _ in return false })
|
||||
// strongSelf.call.playTone(.recordingStarted)
|
||||
// }
|
||||
// })
|
||||
|
||||
let title: String
|
||||
let text: String
|
||||
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
title = strongSelf.presentationData.strings.LiveStream_StartRecordingTitle
|
||||
text = strongSelf.presentationData.strings.LiveStream_StartRecordingText
|
||||
} else {
|
||||
title = strongSelf.presentationData.strings.VoiceChat_StartRecordingTitle
|
||||
text = strongSelf.presentationData.strings.VoiceChat_StartRecordingText
|
||||
}
|
||||
|
||||
let controller = voiceChatTitleEditController(sharedContext: strongSelf.context.sharedContext, account: strongSelf.context.account, forceTheme: strongSelf.darkTheme, title: title, text: text, placeholder: strongSelf.presentationData.strings.VoiceChat_RecordingTitlePlaceholder, value: nil, maxLength: 40, apply: { title in
|
||||
if let strongSelf = self, let title = title {
|
||||
strongSelf.call.setShouldBeRecording(true, title: title, videoOrientation: nil)
|
||||
|
||||
let text: String
|
||||
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
@ -2638,21 +2681,6 @@ public final class VoiceChatController: ViewController {
|
||||
strongSelf.call.playTone(.recordingStarted)
|
||||
}
|
||||
})
|
||||
// let controller = voiceChatTitleEditController(sharedContext: strongSelf.context.sharedContext, account: strongSelf.context.account, forceTheme: strongSelf.darkTheme, title: presentationData.strings.VoiceChat_StartRecordingTitle, text: presentationData.strings.VoiceChat_StartRecordingText, placeholder: presentationData.strings.VoiceChat_RecordingTitlePlaceholder, value: nil, maxLength: 40, apply: { title in
|
||||
// if let strongSelf = self, let title = title {
|
||||
// strongSelf.call.setShouldBeRecording(true, title: title)
|
||||
|
||||
// let text: String
|
||||
// if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
// text = strongSelf.presentationData.strings.LiveStream_RecordingStarted
|
||||
// } else {
|
||||
// text = strongSelf.presentationData.strings.VoiceChat_RecordingStarted
|
||||
// }
|
||||
//
|
||||
// strongSelf.presentUndoOverlay(content: .voiceChatRecording(text: text), action: { _ in return false })
|
||||
// strongSelf.call.playTone(.recordingStarted)
|
||||
// }
|
||||
// })
|
||||
self?.controller?.present(controller, in: .window(.root))
|
||||
})))
|
||||
}
|
||||
@ -4046,8 +4074,15 @@ public final class VoiceChatController: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
var subtitle = self.currentSpeakingSubtitle ?? self.currentSubtitle
|
||||
var speaking = self.currentSpeakingSubtitle != nil
|
||||
var subtitle = ""
|
||||
var speaking = false
|
||||
if self.scrollAtTop {
|
||||
subtitle = self.currentSubtitle
|
||||
speaking = false
|
||||
} else {
|
||||
subtitle = self.currentSpeakingSubtitle ?? self.currentSubtitle
|
||||
speaking = self.currentSpeakingSubtitle != nil
|
||||
}
|
||||
if self.isScheduling {
|
||||
subtitle = ""
|
||||
speaking = false
|
||||
|
@ -565,23 +565,35 @@ private class PreviewIconNode: ASDisplayNode {
|
||||
override init() {
|
||||
self.avatar1Node = ASImageNode()
|
||||
self.avatar1Node.cornerRadius = 4.0
|
||||
self.avatar1Node.clipsToBounds = true
|
||||
self.avatar1Node.displaysAsynchronously = false
|
||||
self.avatar1Node.backgroundColor = UIColor(rgb: 0x834fff)
|
||||
self.avatar1Node.image = UIImage(bundleImageName: "Call/Avatar1")
|
||||
self.avatar1Node.contentMode = .bottom
|
||||
|
||||
self.avatar2Node = ASImageNode()
|
||||
self.avatar2Node.cornerRadius = 4.0
|
||||
self.avatar2Node.clipsToBounds = true
|
||||
self.avatar2Node.displaysAsynchronously = false
|
||||
self.avatar2Node.backgroundColor = UIColor(rgb: 0x63d5c9)
|
||||
self.avatar2Node.image = UIImage(bundleImageName: "Call/Avatar2")
|
||||
self.avatar2Node.contentMode = .scaleAspectFit
|
||||
|
||||
self.avatar3Node = ASImageNode()
|
||||
self.avatar3Node.cornerRadius = 4.0
|
||||
self.avatar3Node.clipsToBounds = true
|
||||
self.avatar3Node.displaysAsynchronously = false
|
||||
self.avatar3Node.backgroundColor = UIColor(rgb: 0xccff60)
|
||||
self.avatar3Node.image = UIImage(bundleImageName: "Call/Avatar3")
|
||||
self.avatar3Node.contentMode = .scaleAspectFit
|
||||
|
||||
self.avatar4Node = ASImageNode()
|
||||
self.avatar4Node.cornerRadius = 4.0
|
||||
self.avatar4Node.clipsToBounds = true
|
||||
self.avatar4Node.displaysAsynchronously = false
|
||||
self.avatar4Node.backgroundColor = UIColor(rgb: 0xf5512a)
|
||||
self.avatar4Node.image = UIImage(bundleImageName: "Call/Avatar4")
|
||||
self.avatar4Node.contentMode = .scaleAspectFit
|
||||
|
||||
super.init()
|
||||
|
||||
|
BIN
submodules/TelegramUI/Images.xcassets/Call/Avatar1.imageset/Avatar1.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Call/Avatar1.imageset/Avatar1.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Call/Avatar1.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Call/Avatar1.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Avatar1.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
submodules/TelegramUI/Images.xcassets/Call/Avatar2.imageset/Avatar3.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Call/Avatar2.imageset/Avatar3.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Call/Avatar2.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Call/Avatar2.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Avatar3.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
submodules/TelegramUI/Images.xcassets/Call/Avatar3.imageset/Avatar2.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Call/Avatar3.imageset/Avatar2.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Call/Avatar3.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Call/Avatar3.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Avatar2.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
submodules/TelegramUI/Images.xcassets/Call/Avatar4.imageset/Avatar4.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Call/Avatar4.imageset/Avatar4.pdf
vendored
Normal file
Binary file not shown.
12
submodules/TelegramUI/Images.xcassets/Call/Avatar4.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Call/Avatar4.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Avatar4.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@ -1058,7 +1058,6 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
accessoryPanelSize = accessoryPanelNode.measure(CGSize(width: layout.size.width, height: layout.size.height))
|
||||
|
||||
accessoryPanelNode.updateState(size: layout.size, inset: layout.safeInsets.left, interfaceState: self.chatPresentationInterfaceState)
|
||||
accessoryPanelNode.animateIn()
|
||||
|
||||
if accessoryPanelNode !== self.accessoryPanelNode {
|
||||
dismissedAccessoryPanelNode = self.accessoryPanelNode
|
||||
@ -1069,6 +1068,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
} else {
|
||||
self.insertSubnode(accessoryPanelNode, aboveSubnode: self.inputPanelBackgroundNode)
|
||||
}
|
||||
accessoryPanelNode.animateIn()
|
||||
|
||||
accessoryPanelNode.dismiss = { [weak self, weak accessoryPanelNode] in
|
||||
if let strongSelf = self, let accessoryPanelNode = accessoryPanelNode, strongSelf.accessoryPanelNode === accessoryPanelNode {
|
||||
|
@ -23,6 +23,7 @@ final class ChatMediaInputMetaSectionItem: ListViewItem {
|
||||
let inputNodeInteraction: ChatMediaInputNodeInteraction
|
||||
let type: ChatMediaInputMetaSectionItemType
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
let expanded: Bool
|
||||
let selectedItem: () -> Void
|
||||
|
||||
@ -30,12 +31,13 @@ final class ChatMediaInputMetaSectionItem: ListViewItem {
|
||||
return true
|
||||
}
|
||||
|
||||
init(account: Account, inputNodeInteraction: ChatMediaInputNodeInteraction, type: ChatMediaInputMetaSectionItemType, theme: PresentationTheme, expanded: Bool, selected: @escaping () -> Void) {
|
||||
init(account: Account, inputNodeInteraction: ChatMediaInputNodeInteraction, type: ChatMediaInputMetaSectionItemType, theme: PresentationTheme, strings: PresentationStrings, expanded: Bool, selected: @escaping () -> Void) {
|
||||
self.account = account
|
||||
self.inputNodeInteraction = inputNodeInteraction
|
||||
self.type = type
|
||||
self.selectedItem = selected
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.expanded = expanded
|
||||
}
|
||||
|
||||
@ -45,7 +47,7 @@ final class ChatMediaInputMetaSectionItem: ListViewItem {
|
||||
Queue.mainQueue().async {
|
||||
node.inputNodeInteraction = self.inputNodeInteraction
|
||||
node.setItem(item: self)
|
||||
node.updateTheme(account: self.account, theme: self.theme, expanded: self.expanded)
|
||||
node.updateTheme(account: self.account, theme: self.theme, strings: self.strings, expanded: self.expanded)
|
||||
node.updateIsHighlighted()
|
||||
node.updateAppearanceTransition(transition: .immediate)
|
||||
|
||||
@ -65,7 +67,7 @@ final class ChatMediaInputMetaSectionItem: ListViewItem {
|
||||
Queue.mainQueue().async {
|
||||
completion(ListViewItemNodeLayout(contentSize: self.expanded ? expandedBoundingSize : boundingSize, insets: node().insets), { _ in
|
||||
(node() as? ChatMediaInputMetaSectionItemNode)?.setItem(item: self)
|
||||
(node() as? ChatMediaInputMetaSectionItemNode)?.updateTheme(account: self.account, theme: self.theme, expanded: self.expanded)
|
||||
(node() as? ChatMediaInputMetaSectionItemNode)?.updateTheme(account: self.account, theme: self.theme, strings: self.strings, expanded: self.expanded)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -174,7 +176,7 @@ final class ChatMediaInputMetaSectionItemNode: ListViewItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
func updateTheme(account: Account, theme: PresentationTheme, expanded: Bool) {
|
||||
func updateTheme(account: Account, theme: PresentationTheme, strings: PresentationStrings, expanded: Bool) {
|
||||
let imageSize = CGSize(width: 26.0 * 1.6, height: 26.0 * 1.6)
|
||||
self.imageNode.frame = CGRect(origin: CGPoint(x: floor((expandedBoundingSize.width - imageSize.width) / 2.0), y: floor((expandedBoundingSize.height - imageSize.height) / 2.0) + UIScreenPixel), size: imageSize)
|
||||
|
||||
@ -189,49 +191,47 @@ final class ChatMediaInputMetaSectionItemNode: ListViewItemNode {
|
||||
switch item.type {
|
||||
case .savedStickers:
|
||||
self.imageNode.image = PresentationResourcesChat.chatInputMediaPanelSavedStickersIcon(theme)
|
||||
title = "Favorites"
|
||||
title = strings.Stickers_Favorites
|
||||
case .recentStickers:
|
||||
self.imageNode.image = PresentationResourcesChat.chatInputMediaPanelRecentStickersIcon(theme)
|
||||
title = "Recent"
|
||||
title = strings.Stickers_Recent
|
||||
case .stickersMode:
|
||||
self.imageNode.image = PresentationResourcesChat.chatInputMediaPanelStickersModeIcon(theme)
|
||||
title = "Stickers"
|
||||
title = strings.Stickers_Stickers
|
||||
case .savedGifs:
|
||||
self.imageNode.image = PresentationResourcesChat.chatInputMediaPanelRecentStickersIcon(theme)
|
||||
title = "GIFs"
|
||||
title = strings.Stickers_Gifs
|
||||
case .trendingGifs:
|
||||
self.imageNode.image = PresentationResourcesChat.chatInputMediaPanelTrendingGifsIcon(theme)
|
||||
title = "Trending"
|
||||
title = strings.Stickers_Trending
|
||||
case let .gifEmoji(emoji, file):
|
||||
var emoji = emoji
|
||||
switch emoji {
|
||||
case "😡":
|
||||
title = "Angry"
|
||||
title = strings.Gif_Emotion_Angry
|
||||
case "😮":
|
||||
title = "Surprised"
|
||||
title = strings.Gif_Emotion_Surprised
|
||||
case "😂":
|
||||
title = "Joy"
|
||||
title = strings.Gif_Emotion_Joy
|
||||
case "😘":
|
||||
title = "Kiss"
|
||||
title = strings.Gif_Emotion_Kiss
|
||||
case "😍":
|
||||
title = "Hearts"
|
||||
title = strings.Gif_Emotion_Hearts
|
||||
case "👍":
|
||||
title = "Thumbs Up"
|
||||
title = strings.Gif_Emotion_ThumbsUp
|
||||
case "👎":
|
||||
title = "Thumbs Down"
|
||||
title = strings.Gif_Emotion_ThumbsDown
|
||||
case "🙄":
|
||||
title = "Roll-eyes"
|
||||
title = strings.Gif_Emotion_RollEyes
|
||||
case "😎":
|
||||
title = "Cool"
|
||||
title = strings.Gif_Emotion_Cool
|
||||
case "🥳":
|
||||
title = "Party"
|
||||
title = strings.Gif_Emotion_Party
|
||||
default:
|
||||
break
|
||||
}
|
||||
self.imageNode.image = nil
|
||||
|
||||
if let file = file {
|
||||
|
||||
let loopAnimatedStickers = self.inputNodeInteraction?.stickerSettings?.loopAnimatedStickers ?? false
|
||||
let animatedStickerNode: AnimatedStickerNode
|
||||
if let current = self.animatedStickerNode {
|
||||
@ -268,7 +268,7 @@ final class ChatMediaInputMetaSectionItemNode: ListViewItemNode {
|
||||
expandTransition.updateTransformScale(node: self.scalingNode, scale: expandScale)
|
||||
expandTransition.updatePosition(node: self.scalingNode, position: CGPoint(x: boundsSize.width / 2.0, y: boundsSize.height / 2.0 + (expanded ? -53.0 : -7.0)))
|
||||
|
||||
let titleSize = self.titleNode.updateLayout(CGSize(width: expandedBoundingSize.width, height: expandedBoundingSize.height))
|
||||
let titleSize = self.titleNode.updateLayout(CGSize(width: expandedBoundingSize.width + 10.0, height: expandedBoundingSize.height))
|
||||
|
||||
let titleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((expandedBoundingSize.width - titleSize.width) / 2.0), y: expandedBoundingSize.height - titleSize.height + 6.0), size: titleSize)
|
||||
let displayTitleFrame = expanded ? titleFrame : CGRect(origin: CGPoint(x: titleFrame.minX, y: self.imageNode.position.y - titleFrame.size.height), size: titleFrame.size)
|
||||
|
@ -162,16 +162,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?, temporaryPackOrder: [ItemCollectionId]? = nil, trendingIsDismissed: Bool = false, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, theme: PresentationTheme, hasGifs: Bool = true, hasSettings: Bool = true, expanded: Bool = false) -> [ChatMediaInputPanelEntry] {
|
||||
func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, temporaryPackOrder: [ItemCollectionId]? = nil, trendingIsDismissed: Bool = false, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, theme: PresentationTheme, strings: PresentationStrings, hasGifs: Bool = true, hasSettings: Bool = true, expanded: Bool = false) -> [ChatMediaInputPanelEntry] {
|
||||
var entries: [ChatMediaInputPanelEntry] = []
|
||||
if hasGifs {
|
||||
entries.append(.recentGifs(theme, expanded))
|
||||
entries.append(.recentGifs(theme, strings, expanded))
|
||||
}
|
||||
if trendingIsDismissed {
|
||||
entries.append(.trending(true, theme, expanded))
|
||||
entries.append(.trending(true, theme, strings, expanded))
|
||||
}
|
||||
if let savedStickers = savedStickers, !savedStickers.items.isEmpty {
|
||||
entries.append(.savedStickers(theme, expanded))
|
||||
entries.append(.savedStickers(theme, strings, expanded))
|
||||
}
|
||||
var savedStickerIds = Set<Int64>()
|
||||
if let savedStickers = savedStickers, !savedStickers.items.isEmpty {
|
||||
@ -192,7 +192,7 @@ func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: Ordere
|
||||
}
|
||||
}
|
||||
if found {
|
||||
entries.append(.recentPacks(theme, expanded))
|
||||
entries.append(.recentPacks(theme, strings, expanded))
|
||||
}
|
||||
}
|
||||
if let peerSpecificPack = peerSpecificPack {
|
||||
@ -236,25 +236,25 @@ func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: Ordere
|
||||
}
|
||||
|
||||
if hasSettings {
|
||||
entries.append(.settings(theme, expanded))
|
||||
entries.append(.settings(theme, strings, expanded))
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
func chatMediaInputPanelGifModeEntries(theme: PresentationTheme, reactions: [String], animatedEmojiStickers: [String: [StickerPackItem]], expanded: Bool) -> [ChatMediaInputPanelEntry] {
|
||||
func chatMediaInputPanelGifModeEntries(theme: PresentationTheme, strings: PresentationStrings, reactions: [String], animatedEmojiStickers: [String: [StickerPackItem]], expanded: Bool) -> [ChatMediaInputPanelEntry] {
|
||||
var entries: [ChatMediaInputPanelEntry] = []
|
||||
entries.append(.stickersMode(theme, expanded))
|
||||
entries.append(.savedGifs(theme, expanded))
|
||||
entries.append(.trendingGifs(theme, expanded))
|
||||
entries.append(.stickersMode(theme, strings, expanded))
|
||||
entries.append(.savedGifs(theme, strings, expanded))
|
||||
entries.append(.trendingGifs(theme, strings, expanded))
|
||||
|
||||
for reaction in reactions {
|
||||
entries.append(.gifEmotion(entries.count, theme, reaction, animatedEmojiStickers[reaction]?.first?.file, expanded))
|
||||
entries.append(.gifEmotion(entries.count, theme, strings, reaction, animatedEmojiStickers[reaction]?.first?.file, expanded))
|
||||
}
|
||||
|
||||
return entries
|
||||
}
|
||||
|
||||
func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, trendingPacks: [FeaturedStickerPackItem], trendingIsDismissed: Bool = false, hasSearch: Bool = true, hasAccessories: Bool = true, strings: PresentationStrings, theme: PresentationTheme) -> [ChatMediaInputGridEntry] {
|
||||
func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: OrderedItemListView?, recentStickers: OrderedItemListView?, peerSpecificPack: PeerSpecificPackData?, canInstallPeerSpecificPack: CanInstallPeerSpecificPack, trendingPacks: [FeaturedStickerPackItem], installedPacks: Set<ItemCollectionId>, trendingIsDismissed: Bool = false, hasSearch: Bool = true, hasAccessories: Bool = true, strings: PresentationStrings, theme: PresentationTheme) -> [ChatMediaInputGridEntry] {
|
||||
var entries: [ChatMediaInputGridEntry] = []
|
||||
|
||||
if hasSearch && view.lower == nil {
|
||||
@ -282,8 +282,9 @@ func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: Ordered
|
||||
}
|
||||
}
|
||||
|
||||
if !trendingIsDismissed {
|
||||
entries.append(.trendingList(theme: theme, strings: strings, packs: trendingPacks))
|
||||
let filteredTrending = trendingPacks.filter { !installedPacks.contains($0.info.id) }
|
||||
if !trendingIsDismissed && !filteredTrending.isEmpty {
|
||||
entries.append(.trendingList(theme: theme, strings: strings, packs: filteredTrending))
|
||||
}
|
||||
|
||||
if let recentStickers = recentStickers, !recentStickers.items.isEmpty {
|
||||
@ -621,7 +622,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
return .single(false)
|
||||
}
|
||||
self?.lastReorderItemIndex = toIndex
|
||||
|
||||
|
||||
let fromEntry = entries[fromIndex]
|
||||
guard case let .stickerPack(_, fromPackInfo, _, _, _) = fromEntry else {
|
||||
return .single(false)
|
||||
@ -743,7 +744,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
}
|
||||
}
|
||||
|
||||
self?.startCollapseTimer(timeout: 1.0)
|
||||
self?.startCollapseTimer(timeout: 2.0)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1133,9 +1134,9 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
trendingIsDismissed = true
|
||||
}
|
||||
|
||||
let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, temporaryPackOrder: temporaryPackOrder, trendingIsDismissed: trendingIsDismissed, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, theme: theme, expanded: panelExpanded)
|
||||
let gifPaneEntries = chatMediaInputPanelGifModeEntries(theme: theme, reactions: reactions, animatedEmojiStickers: animatedEmojiStickers, expanded: panelExpanded)
|
||||
var gridEntries = chatMediaInputGridEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, trendingPacks: trendingPacks, trendingIsDismissed: trendingIsDismissed, strings: strings, theme: theme)
|
||||
let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, temporaryPackOrder: temporaryPackOrder, trendingIsDismissed: trendingIsDismissed, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, theme: theme, strings: strings, expanded: panelExpanded)
|
||||
let gifPaneEntries = chatMediaInputPanelGifModeEntries(theme: theme, strings: strings, reactions: reactions, animatedEmojiStickers: animatedEmojiStickers, expanded: panelExpanded)
|
||||
var gridEntries = chatMediaInputGridEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: peerSpecificPack.0, canInstallPeerSpecificPack: peerSpecificPack.1, trendingPacks: trendingPacks, installedPacks: installedPacks, trendingIsDismissed: trendingIsDismissed, strings: strings, theme: theme)
|
||||
|
||||
if view.higher == nil {
|
||||
var hasTopSeparator = true
|
||||
@ -1274,7 +1275,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
strongSelf.panelFocusScrollToIndex = nil
|
||||
strongSelf.panelFocusInitialPosition = nil
|
||||
}
|
||||
strongSelf.startCollapseTimer(timeout: decelerated ? 0.5 : 2.0)
|
||||
strongSelf.startCollapseTimer(timeout: decelerated ? 0.5 : 2.5)
|
||||
|
||||
strongSelf.scrollingStickerPacksListPromise.set(false)
|
||||
}
|
||||
@ -1291,6 +1292,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
}
|
||||
if let index = index {
|
||||
strongSelf.panelFocusScrollToIndex = index
|
||||
strongSelf.panelFocusInitialPosition = position
|
||||
}
|
||||
strongSelf.interfaceInteraction?.updateTextInputStateAndMode { inputTextState, inputMode in
|
||||
if case let .media(mode, expanded, _) = inputMode {
|
||||
@ -1314,7 +1316,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
strongSelf.panelFocusScrollToIndex = nil
|
||||
strongSelf.panelFocusInitialPosition = nil
|
||||
}
|
||||
strongSelf.startCollapseTimer(timeout: decelerated ? 0.5 : 2.0)
|
||||
strongSelf.startCollapseTimer(timeout: decelerated ? 0.5 : 2.5)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2256,24 +2258,26 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
}
|
||||
|
||||
var scrollToItem: ListViewScrollToItem?
|
||||
if let targetIndex = self.panelFocusScrollToIndex, !self.listView.isReordering {
|
||||
var position: ListViewScrollPosition
|
||||
if self.panelIsFocused {
|
||||
if let initialPosition = self.panelFocusInitialPosition {
|
||||
position = .top(96.0 + (initialPosition.y - self.listView.frame.height / 2.0) * 0.5)
|
||||
if self.paneArrangement.currentIndex == 1 {
|
||||
if let targetIndex = self.panelFocusScrollToIndex, !self.listView.isReordering {
|
||||
var position: ListViewScrollPosition
|
||||
if self.panelIsFocused {
|
||||
if let initialPosition = self.panelFocusInitialPosition {
|
||||
position = .top(96.0 + (initialPosition.y - self.listView.frame.height / 2.0) * 0.5)
|
||||
} else {
|
||||
position = .top(96.0)
|
||||
}
|
||||
} else {
|
||||
position = .top(96.0)
|
||||
if let initialPosition = self.panelFocusInitialPosition {
|
||||
position = .top(self.listView.frame.height / 2.0 + 96.0 + (initialPosition.y - self.listView.frame.height / 2.0))
|
||||
} else {
|
||||
position = .top(self.listView.frame.height / 2.0 + 96.0)
|
||||
}
|
||||
self.panelFocusScrollToIndex = nil
|
||||
self.panelFocusInitialPosition = nil
|
||||
}
|
||||
} else {
|
||||
if let initialPosition = self.panelFocusInitialPosition {
|
||||
position = .top(self.listView.frame.height / 2.0 + 96.0 + (initialPosition.y - self.listView.frame.height / 2.0))
|
||||
} else {
|
||||
position = .top(self.listView.frame.height / 2.0 + 96.0)
|
||||
}
|
||||
self.panelFocusScrollToIndex = nil
|
||||
self.panelFocusInitialPosition = nil
|
||||
scrollToItem = ListViewScrollToItem(index: targetIndex, position: position, animated: true, curve: .Spring(duration: 0.4), directionHint: .Down, displayLink: true)
|
||||
}
|
||||
scrollToItem = ListViewScrollToItem(index: targetIndex, position: position, animated: true, curve: .Spring(duration: 0.4), directionHint: .Down, displayLink: true)
|
||||
}
|
||||
|
||||
self.listView.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, scrollToItem: scrollToItem, updateOpaqueState: transition.updateOpaqueState, completion: { [weak self] _ in
|
||||
@ -2289,9 +2293,37 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
|
||||
private func enqueueGifPanelTransition(_ transition: ChatMediaInputPanelTransition, firstTime: Bool) {
|
||||
var options = ListViewDeleteAndInsertOptions()
|
||||
options.insert(.Synchronous)
|
||||
options.insert(.LowLatency)
|
||||
self.gifListView.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, updateOpaqueState: nil, completion: { _ in
|
||||
if firstTime {
|
||||
options.insert(.Synchronous)
|
||||
options.insert(.LowLatency)
|
||||
} else {
|
||||
options.insert(.AnimateInsertion)
|
||||
}
|
||||
|
||||
var scrollToItem: ListViewScrollToItem?
|
||||
if self.paneArrangement.currentIndex == 0 {
|
||||
if let targetIndex = self.panelFocusScrollToIndex {
|
||||
var position: ListViewScrollPosition
|
||||
if self.panelIsFocused {
|
||||
if let initialPosition = self.panelFocusInitialPosition {
|
||||
position = .top(96.0 + (initialPosition.y - self.gifListView.frame.height / 2.0) * 0.5)
|
||||
} else {
|
||||
position = .top(96.0)
|
||||
}
|
||||
} else {
|
||||
if let initialPosition = self.panelFocusInitialPosition {
|
||||
position = .top(self.gifListView.frame.height / 2.0 + 96.0 + (initialPosition.y - self.gifListView.frame.height / 2.0))
|
||||
} else {
|
||||
position = .top(self.gifListView.frame.height / 2.0 + 96.0)
|
||||
}
|
||||
self.panelFocusScrollToIndex = nil
|
||||
self.panelFocusInitialPosition = nil
|
||||
}
|
||||
scrollToItem = ListViewScrollToItem(index: targetIndex, position: position, animated: true, curve: .Spring(duration: 0.4), directionHint: .Down, displayLink: true)
|
||||
}
|
||||
}
|
||||
|
||||
self.gifListView.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, scrollToItem: scrollToItem, updateOpaqueState: nil, completion: { _ in
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -31,18 +31,18 @@ enum ChatMediaInputPanelEntryStableId: Hashable {
|
||||
}
|
||||
|
||||
enum ChatMediaInputPanelEntry: Comparable, Identifiable {
|
||||
case recentGifs(PresentationTheme, Bool)
|
||||
case savedStickers(PresentationTheme, Bool)
|
||||
case recentPacks(PresentationTheme, Bool)
|
||||
case trending(Bool, PresentationTheme, Bool)
|
||||
case settings(PresentationTheme, Bool)
|
||||
case recentGifs(PresentationTheme, PresentationStrings, Bool)
|
||||
case savedStickers(PresentationTheme, PresentationStrings, Bool)
|
||||
case recentPacks(PresentationTheme, PresentationStrings, Bool)
|
||||
case trending(Bool, PresentationTheme, PresentationStrings, Bool)
|
||||
case settings(PresentationTheme, PresentationStrings, Bool)
|
||||
case peerSpecific(theme: PresentationTheme, peer: Peer, expanded: Bool)
|
||||
case stickerPack(index: Int, info: StickerPackCollectionInfo, topItem: StickerPackItem?, theme: PresentationTheme, expanded: Bool)
|
||||
|
||||
case stickersMode(PresentationTheme, Bool)
|
||||
case savedGifs(PresentationTheme, Bool)
|
||||
case trendingGifs(PresentationTheme, Bool)
|
||||
case gifEmotion(Int, PresentationTheme, String, TelegramMediaFile?, Bool)
|
||||
case stickersMode(PresentationTheme, PresentationStrings, Bool)
|
||||
case savedGifs(PresentationTheme, PresentationStrings, Bool)
|
||||
case trendingGifs(PresentationTheme, PresentationStrings, Bool)
|
||||
case gifEmotion(Int, PresentationTheme, PresentationStrings, String, TelegramMediaFile?, Bool)
|
||||
|
||||
var stableId: ChatMediaInputPanelEntryStableId {
|
||||
switch self {
|
||||
@ -66,39 +66,39 @@ enum ChatMediaInputPanelEntry: Comparable, Identifiable {
|
||||
return .savedGifs
|
||||
case .trendingGifs:
|
||||
return .trendingGifs
|
||||
case let .gifEmotion(_, _, emoji, _, _):
|
||||
case let .gifEmotion(_, _, _, emoji, _, _):
|
||||
return .gifEmotion(emoji)
|
||||
}
|
||||
}
|
||||
|
||||
static func ==(lhs: ChatMediaInputPanelEntry, rhs: ChatMediaInputPanelEntry) -> Bool {
|
||||
switch lhs {
|
||||
case let .recentGifs(lhsTheme, lhsExpanded):
|
||||
if case let .recentGifs(rhsTheme, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsExpanded == rhsExpanded {
|
||||
case let .recentGifs(lhsTheme, lhsStrings, lhsExpanded):
|
||||
if case let .recentGifs(rhsTheme, rhsStrings, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsExpanded == rhsExpanded {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .savedStickers(lhsTheme, lhsExpanded):
|
||||
if case let .savedStickers(rhsTheme, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsExpanded == rhsExpanded {
|
||||
case let .savedStickers(lhsTheme, lhsStrings, lhsExpanded):
|
||||
if case let .savedStickers(rhsTheme, rhsStrings, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsExpanded == rhsExpanded {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .recentPacks(lhsTheme, lhsExpanded):
|
||||
if case let .recentPacks(rhsTheme, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsExpanded == rhsExpanded {
|
||||
case let .recentPacks(lhsTheme, lhsStrings, lhsExpanded):
|
||||
if case let .recentPacks(rhsTheme, rhsStrings, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsExpanded == rhsExpanded {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .trending(lhsElevated, lhsTheme, lhsExpanded):
|
||||
if case let .trending(rhsElevated, rhsTheme, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsElevated == rhsElevated, lhsExpanded == rhsExpanded {
|
||||
case let .trending(lhsElevated, lhsTheme, lhsStrings, lhsExpanded):
|
||||
if case let .trending(rhsElevated, rhsTheme, rhsStrings, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsElevated == rhsElevated, lhsExpanded == rhsExpanded {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .settings(lhsTheme, lhsExpanded):
|
||||
if case let .settings(rhsTheme, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsExpanded == rhsExpanded {
|
||||
case let .settings(lhsTheme, lhsStrings, lhsExpanded):
|
||||
if case let .settings(rhsTheme, rhsStrings, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsExpanded == rhsExpanded {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -115,26 +115,26 @@ enum ChatMediaInputPanelEntry: Comparable, Identifiable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .stickersMode(lhsTheme, lhsExpanded):
|
||||
if case let .stickersMode(rhsTheme, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsExpanded == rhsExpanded {
|
||||
case let .stickersMode(lhsTheme, lhsStrings, lhsExpanded):
|
||||
if case let .stickersMode(rhsTheme, rhsStrings, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsExpanded == rhsExpanded {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .savedGifs(lhsTheme, lhsExpanded):
|
||||
if case let .savedGifs(rhsTheme, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsExpanded == rhsExpanded {
|
||||
case let .savedGifs(lhsTheme, lhsStrings, lhsExpanded):
|
||||
if case let .savedGifs(rhsTheme, rhsStrings, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsExpanded == rhsExpanded {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .trendingGifs(lhsTheme, lhsExpanded):
|
||||
if case let .trendingGifs(rhsTheme, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsExpanded == rhsExpanded {
|
||||
case let .trendingGifs(lhsTheme, lhsStrings, lhsExpanded):
|
||||
if case let .trendingGifs(rhsTheme, rhsStrings, rhsExpanded) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsExpanded == rhsExpanded {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .gifEmotion(lhsIndex, lhsTheme, lhsEmoji, lhsFile, lhsExpanded):
|
||||
if case let .gifEmotion(rhsIndex, rhsTheme, rhsEmoji, rhsFile, rhsExpanded) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsEmoji == rhsEmoji, lhsExpanded == rhsExpanded {
|
||||
case let .gifEmotion(lhsIndex, lhsTheme, lhsStrings, lhsEmoji, lhsFile, lhsExpanded):
|
||||
if case let .gifEmotion(rhsIndex, rhsTheme, rhsStrings, rhsEmoji, rhsFile, rhsExpanded) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsEmoji == rhsEmoji, lhsExpanded == rhsExpanded {
|
||||
if let lhsFile = lhsFile, let rhsFile = rhsFile {
|
||||
if !lhsFile.isEqual(to: rhsFile) {
|
||||
return false
|
||||
@ -162,7 +162,7 @@ enum ChatMediaInputPanelEntry: Comparable, Identifiable {
|
||||
switch rhs {
|
||||
case .recentGifs, savedStickers:
|
||||
return false
|
||||
case let .trending(elevated, _, _) where elevated:
|
||||
case let .trending(elevated, _, _, _) where elevated:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
@ -171,7 +171,7 @@ enum ChatMediaInputPanelEntry: Comparable, Identifiable {
|
||||
switch rhs {
|
||||
case .recentGifs, .savedStickers, recentPacks:
|
||||
return false
|
||||
case let .trending(elevated, _, _) where elevated:
|
||||
case let .trending(elevated, _, _, _) where elevated:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
@ -180,7 +180,7 @@ enum ChatMediaInputPanelEntry: Comparable, Identifiable {
|
||||
switch rhs {
|
||||
case .recentGifs, .savedStickers, recentPacks, .peerSpecific:
|
||||
return false
|
||||
case let .trending(elevated, _, _) where elevated:
|
||||
case let .trending(elevated, _, _, _) where elevated:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
@ -189,7 +189,7 @@ enum ChatMediaInputPanelEntry: Comparable, Identifiable {
|
||||
switch rhs {
|
||||
case .recentGifs, .savedStickers, .recentPacks, .peerSpecific:
|
||||
return false
|
||||
case let .trending(elevated, _, _):
|
||||
case let .trending(elevated, _, _, _):
|
||||
if elevated {
|
||||
return false
|
||||
} else {
|
||||
@ -206,7 +206,7 @@ enum ChatMediaInputPanelEntry: Comparable, Identifiable {
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case let .trending(elevated, _, _):
|
||||
case let .trending(elevated, _, _, _):
|
||||
if elevated {
|
||||
switch rhs {
|
||||
case .recentGifs, .trending:
|
||||
@ -237,11 +237,11 @@ enum ChatMediaInputPanelEntry: Comparable, Identifiable {
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case let .gifEmotion(lhsIndex, _, _, _, _):
|
||||
case let .gifEmotion(lhsIndex, _, _, _, _, _):
|
||||
switch rhs {
|
||||
case .stickersMode, .savedGifs, .trendingGifs:
|
||||
return false
|
||||
case let .gifEmotion(rhsIndex, _, _, _, _):
|
||||
case let .gifEmotion(rhsIndex, _, _, _, _, _):
|
||||
return lhsIndex < rhsIndex
|
||||
default:
|
||||
return true
|
||||
@ -257,28 +257,28 @@ enum ChatMediaInputPanelEntry: Comparable, Identifiable {
|
||||
|
||||
func item(context: AccountContext, inputNodeInteraction: ChatMediaInputNodeInteraction) -> ListViewItem {
|
||||
switch self {
|
||||
case let .recentGifs(theme, expanded):
|
||||
return ChatMediaInputRecentGifsItem(inputNodeInteraction: inputNodeInteraction, theme: theme, expanded: expanded, selected: {
|
||||
case let .recentGifs(theme, strings, expanded):
|
||||
return ChatMediaInputRecentGifsItem(inputNodeInteraction: inputNodeInteraction, theme: theme, strings: strings, expanded: expanded, selected: {
|
||||
let collectionId = ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.recentGifs.rawValue, id: 0)
|
||||
inputNodeInteraction.navigateToCollectionId(collectionId)
|
||||
})
|
||||
case let .savedStickers(theme, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .savedStickers, theme: theme, expanded: expanded, selected: {
|
||||
case let .savedStickers(theme, strings, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .savedStickers, theme: theme, strings: strings, expanded: expanded, selected: {
|
||||
let collectionId = ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.savedStickers.rawValue, id: 0)
|
||||
inputNodeInteraction.navigateToCollectionId(collectionId)
|
||||
})
|
||||
case let .recentPacks(theme, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .recentStickers, theme: theme, expanded: expanded, selected: {
|
||||
case let .recentPacks(theme, strings, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .recentStickers, theme: theme, strings: strings, expanded: expanded, selected: {
|
||||
let collectionId = ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.recentStickers.rawValue, id: 0)
|
||||
inputNodeInteraction.navigateToCollectionId(collectionId)
|
||||
})
|
||||
case let .trending(elevated, theme, expanded):
|
||||
return ChatMediaInputTrendingItem(inputNodeInteraction: inputNodeInteraction, elevated: elevated, theme: theme, expanded: expanded, selected: {
|
||||
case let .trending(elevated, theme, strings, expanded):
|
||||
return ChatMediaInputTrendingItem(inputNodeInteraction: inputNodeInteraction, elevated: elevated, theme: theme, strings: strings, expanded: expanded, selected: {
|
||||
let collectionId = ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.trending.rawValue, id: 0)
|
||||
inputNodeInteraction.navigateToCollectionId(collectionId)
|
||||
})
|
||||
case let .settings(theme, expanded):
|
||||
return ChatMediaInputSettingsItem(inputNodeInteraction: inputNodeInteraction, theme: theme, expanded: expanded, selected: {
|
||||
case let .settings(theme, strings, expanded):
|
||||
return ChatMediaInputSettingsItem(inputNodeInteraction: inputNodeInteraction, theme: theme, strings: strings, expanded: expanded, selected: {
|
||||
inputNodeInteraction.openSettings()
|
||||
})
|
||||
case let .peerSpecific(theme, peer, expanded):
|
||||
@ -290,20 +290,20 @@ enum ChatMediaInputPanelEntry: Comparable, Identifiable {
|
||||
return ChatMediaInputStickerPackItem(account: context.account, inputNodeInteraction: inputNodeInteraction, collectionId: info.id, collectionInfo: info, stickerPackItem: topItem, index: index, theme: theme, expanded: expanded, selected: {
|
||||
inputNodeInteraction.navigateToCollectionId(info.id)
|
||||
})
|
||||
case let .stickersMode(theme, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .stickersMode, theme: theme, expanded: expanded, selected: {
|
||||
case let .stickersMode(theme, strings, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .stickersMode, theme: theme, strings: strings, expanded: expanded, selected: {
|
||||
inputNodeInteraction.navigateBackToStickers()
|
||||
})
|
||||
case let .savedGifs(theme, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .savedGifs, theme: theme, expanded: expanded, selected: {
|
||||
case let .savedGifs(theme, strings, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .savedGifs, theme: theme, strings: strings, expanded: expanded, selected: {
|
||||
inputNodeInteraction.setGifMode(.recent)
|
||||
})
|
||||
case let .trendingGifs(theme, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .trendingGifs, theme: theme, expanded: expanded, selected: {
|
||||
case let .trendingGifs(theme, strings, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .trendingGifs, theme: theme, strings: strings, expanded: expanded, selected: {
|
||||
inputNodeInteraction.setGifMode(.trending)
|
||||
})
|
||||
case let .gifEmotion(_, theme, emoji, file, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .gifEmoji(emoji, file), theme: theme, expanded: expanded, selected: {
|
||||
case let .gifEmotion(_, theme, strings, emoji, file, expanded):
|
||||
return ChatMediaInputMetaSectionItem(account: context.account, inputNodeInteraction: inputNodeInteraction, type: .gifEmoji(emoji, file), theme: theme, strings: strings, expanded: expanded, selected: {
|
||||
inputNodeInteraction.setGifMode(.emojiSearch(emoji))
|
||||
})
|
||||
}
|
||||
|
@ -12,15 +12,17 @@ final class ChatMediaInputRecentGifsItem: ListViewItem {
|
||||
let selectedItem: () -> Void
|
||||
let expanded: Bool
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
|
||||
var selectable: Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
init(inputNodeInteraction: ChatMediaInputNodeInteraction, theme: PresentationTheme, expanded: Bool, selected: @escaping () -> Void) {
|
||||
init(inputNodeInteraction: ChatMediaInputNodeInteraction, theme: PresentationTheme, strings: PresentationStrings, expanded: Bool, selected: @escaping () -> Void) {
|
||||
self.inputNodeInteraction = inputNodeInteraction
|
||||
self.selectedItem = selected
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.expanded = expanded
|
||||
}
|
||||
|
||||
@ -33,7 +35,7 @@ final class ChatMediaInputRecentGifsItem: ListViewItem {
|
||||
node.updateIsHighlighted()
|
||||
node.updateAppearanceTransition(transition: .immediate)
|
||||
Queue.mainQueue().async {
|
||||
node.updateTheme(theme: self.theme, expanded: self.expanded)
|
||||
node.updateTheme(theme: self.theme, strings: self.strings, expanded: self.expanded)
|
||||
completion(node, {
|
||||
return (nil, { _ in })
|
||||
})
|
||||
@ -44,7 +46,7 @@ final class ChatMediaInputRecentGifsItem: ListViewItem {
|
||||
public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
|
||||
Queue.mainQueue().async {
|
||||
completion(ListViewItemNodeLayout(contentSize: self.expanded ? expandedBoundingSize : boundingSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { _ in
|
||||
(node() as? ChatMediaInputRecentGifsItemNode)?.updateTheme(theme: self.theme, expanded: self.expanded)
|
||||
(node() as? ChatMediaInputRecentGifsItemNode)?.updateTheme(theme: self.theme, strings: self.strings, expanded: self.expanded)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -105,14 +107,14 @@ final class ChatMediaInputRecentGifsItemNode: ListViewItemNode {
|
||||
deinit {
|
||||
}
|
||||
|
||||
func updateTheme(theme: PresentationTheme, expanded: Bool) {
|
||||
func updateTheme(theme: PresentationTheme, strings: PresentationStrings, expanded: Bool) {
|
||||
if self.theme !== theme {
|
||||
self.theme = theme
|
||||
|
||||
self.highlightNode.image = PresentationResourcesChat.chatMediaInputPanelHighlightedIconImage(theme)
|
||||
self.imageNode.image = PresentationResourcesChat.chatInputMediaPanelRecentGifsIconImage(theme)
|
||||
|
||||
self.titleNode.attributedText = NSAttributedString(string: "GIFs", font: Font.regular(11.0), textColor: theme.chat.inputPanel.primaryTextColor)
|
||||
self.titleNode.attributedText = NSAttributedString(string: strings.Stickers_Gifs, font: Font.regular(11.0), textColor: theme.chat.inputPanel.primaryTextColor)
|
||||
}
|
||||
|
||||
let imageSize = CGSize(width: 26.0 * 1.6, height: 26.0 * 1.6)
|
||||
|
@ -12,15 +12,17 @@ final class ChatMediaInputSettingsItem: ListViewItem {
|
||||
let selectedItem: () -> Void
|
||||
let expanded: Bool
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
|
||||
var selectable: Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
init(inputNodeInteraction: ChatMediaInputNodeInteraction, theme: PresentationTheme, expanded: Bool, selected: @escaping () -> Void) {
|
||||
init(inputNodeInteraction: ChatMediaInputNodeInteraction, theme: PresentationTheme, strings: PresentationStrings, expanded: Bool, selected: @escaping () -> Void) {
|
||||
self.inputNodeInteraction = inputNodeInteraction
|
||||
self.selectedItem = selected
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.expanded = expanded
|
||||
}
|
||||
|
||||
@ -32,7 +34,7 @@ final class ChatMediaInputSettingsItem: ListViewItem {
|
||||
node.inputNodeInteraction = self.inputNodeInteraction
|
||||
node.updateAppearanceTransition(transition: .immediate)
|
||||
Queue.mainQueue().async {
|
||||
node.updateTheme(theme: self.theme, expanded: self.expanded)
|
||||
node.updateTheme(theme: self.theme, strings: self.strings, expanded: self.expanded)
|
||||
completion(node, {
|
||||
return (nil, { _ in })
|
||||
})
|
||||
@ -43,7 +45,7 @@ final class ChatMediaInputSettingsItem: ListViewItem {
|
||||
public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
|
||||
Queue.mainQueue().async {
|
||||
completion(ListViewItemNodeLayout(contentSize: self.expanded ? expandedBoundingSize : boundingSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { _ in
|
||||
(node() as? ChatMediaInputSettingsItemNode)?.updateTheme(theme: self.theme, expanded: self.expanded)
|
||||
(node() as? ChatMediaInputSettingsItemNode)?.updateTheme(theme: self.theme, strings: self.strings, expanded: self.expanded)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -96,7 +98,7 @@ final class ChatMediaInputSettingsItemNode: ListViewItemNode {
|
||||
self.scalingNode.addSubnode(self.imageNode)
|
||||
}
|
||||
|
||||
func updateTheme(theme: PresentationTheme, expanded: Bool) {
|
||||
func updateTheme(theme: PresentationTheme, strings: PresentationStrings, expanded: Bool) {
|
||||
let imageSize = CGSize(width: 26.0 * 1.6, height: 26.0 * 1.6)
|
||||
self.imageNode.frame = CGRect(origin: CGPoint(x: floor((expandedBoundingSize.width - imageSize.width) / 2.0), y: floor((expandedBoundingSize.height - imageSize.height) / 2.0) + UIScreenPixel), size: imageSize)
|
||||
|
||||
@ -105,7 +107,7 @@ final class ChatMediaInputSettingsItemNode: ListViewItemNode {
|
||||
|
||||
self.imageNode.image = PresentationResourcesChat.chatInputMediaPanelSettingsIconImage(theme)
|
||||
|
||||
self.titleNode.attributedText = NSAttributedString(string: "Settings", font: Font.regular(11.0), textColor: theme.chat.inputPanel.primaryTextColor)
|
||||
self.titleNode.attributedText = NSAttributedString(string: strings.Stickers_Settings, font: Font.regular(11.0), textColor: theme.chat.inputPanel.primaryTextColor)
|
||||
}
|
||||
|
||||
self.containerNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: expandedBoundingSize)
|
||||
|
@ -349,7 +349,7 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
|
||||
snapshotImageNode = imageNode
|
||||
case let .animated(resource, _):
|
||||
let animatedStickerNode = AnimatedStickerNode()
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: account, resource: resource), width: 128, height: 128, mode: .direct(cachePathPrefix: nil))
|
||||
animatedStickerNode.setup(source: AnimatedStickerResourceSource(account: account, resource: resource), width: 128, height: 128, mode: .cached)
|
||||
animatedStickerNode.visibility = self.visibilityStatus && loopAnimatedStickers
|
||||
scalingNode.addSubnode(animatedStickerNode)
|
||||
|
||||
|
@ -119,6 +119,8 @@ final class ChatMediaInputStickerPane: ChatMediaInputPane {
|
||||
}
|
||||
if let itemNode = itemNode as? ChatMediaInputStickerGridItemNode {
|
||||
itemNode.updateIsPanelVisible(strongSelf.isPaneVisible)
|
||||
} else if let itemNode = itemNode as? StickerPaneTrendingListGridItemNode {
|
||||
itemNode.updateIsPanelVisible(strongSelf.isPaneVisible)
|
||||
}
|
||||
}
|
||||
self.gridNode.scrollView.alwaysBounceVertical = true
|
||||
@ -182,6 +184,8 @@ final class ChatMediaInputStickerPane: ChatMediaInputPane {
|
||||
itemNode.updateIsPanelVisible(isVisible)
|
||||
} else if let itemNode = itemNode as? StickerPaneSearchGlobalItemNode {
|
||||
itemNode.updateCanPlayMedia()
|
||||
} else if let itemNode = itemNode as? StickerPaneTrendingListGridItemNode {
|
||||
itemNode.updateIsPanelVisible(isVisible)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,17 +13,19 @@ final class ChatMediaInputTrendingItem: ListViewItem {
|
||||
let elevated: Bool
|
||||
let expanded: Bool
|
||||
let theme: PresentationTheme
|
||||
let strings: PresentationStrings
|
||||
|
||||
var selectable: Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
init(inputNodeInteraction: ChatMediaInputNodeInteraction, elevated: Bool, theme: PresentationTheme, expanded: Bool, selected: @escaping () -> Void) {
|
||||
init(inputNodeInteraction: ChatMediaInputNodeInteraction, elevated: Bool, theme: PresentationTheme, strings: PresentationStrings, expanded: Bool, selected: @escaping () -> Void) {
|
||||
self.inputNodeInteraction = inputNodeInteraction
|
||||
self.elevated = elevated
|
||||
self.selectedItem = selected
|
||||
self.expanded = expanded
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
}
|
||||
|
||||
func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||
@ -35,7 +37,7 @@ final class ChatMediaInputTrendingItem: ListViewItem {
|
||||
node.updateIsHighlighted()
|
||||
node.updateAppearanceTransition(transition: .immediate)
|
||||
Queue.mainQueue().async {
|
||||
node.updateTheme(elevated: self.elevated, theme: self.theme, expanded: self.expanded)
|
||||
node.updateTheme(elevated: self.elevated, theme: self.theme, strings: self.strings, expanded: self.expanded)
|
||||
completion(node, {
|
||||
return (nil, { _ in })
|
||||
})
|
||||
@ -46,7 +48,7 @@ final class ChatMediaInputTrendingItem: ListViewItem {
|
||||
public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
|
||||
Queue.mainQueue().async {
|
||||
completion(ListViewItemNodeLayout(contentSize: self.expanded ? expandedBoundingSize : boundingSize, insets: ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)), { _ in
|
||||
(node() as? ChatMediaInputTrendingItemNode)?.updateTheme(elevated: self.elevated, theme: self.theme, expanded: self.expanded)
|
||||
(node() as? ChatMediaInputTrendingItemNode)?.updateTheme(elevated: self.elevated, theme: self.theme, strings: self.strings, expanded: self.expanded)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -113,7 +115,7 @@ final class ChatMediaInputTrendingItemNode: ListViewItemNode {
|
||||
self.currentCollectionId = ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.trending.rawValue, id: 0)
|
||||
}
|
||||
|
||||
func updateTheme(elevated: Bool, theme: PresentationTheme, expanded: Bool) {
|
||||
func updateTheme(elevated: Bool, theme: PresentationTheme, strings: PresentationStrings, expanded: Bool) {
|
||||
let imageSize = CGSize(width: 26.0 * 1.85, height: 26.0 * 1.85)
|
||||
let imageFrame = CGRect(origin: CGPoint(x: floor((expandedBoundingSize.width - imageSize.width) / 2.0), y: floor((expandedBoundingSize.height - imageSize.height) / 2.0) + UIScreenPixel), size: imageSize)
|
||||
self.imageNode.frame = imageFrame
|
||||
@ -129,7 +131,7 @@ final class ChatMediaInputTrendingItemNode: ListViewItemNode {
|
||||
self.badgeBackground.frame = CGRect(origin: CGPoint(x: floor(imageFrame.maxX - image.size.width - 7.0), y: 18.0), size: image.size)
|
||||
}
|
||||
|
||||
self.titleNode.attributedText = NSAttributedString(string: "Trending", font: Font.regular(11.0), textColor: theme.chat.inputPanel.primaryTextColor)
|
||||
self.titleNode.attributedText = NSAttributedString(string: strings.Stickers_Trending, font: Font.regular(11.0), textColor: theme.chat.inputPanel.primaryTextColor)
|
||||
}
|
||||
|
||||
if self.elevated != elevated {
|
||||
|
@ -3560,7 +3560,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
|
||||
if let selectionState = item.controllerInteraction.selectionState, canHaveSelection {
|
||||
var selected = false
|
||||
var incoming = true
|
||||
let incoming = item.content.effectivelyIncoming(item.context.account.peerId, associatedData: item.associatedData)
|
||||
|
||||
switch item.content {
|
||||
case let .message(message, _, _, _):
|
||||
@ -3576,8 +3576,6 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
selected = allSelected
|
||||
}
|
||||
|
||||
incoming = item.message.effectivelyIncoming(item.context.account.peerId)
|
||||
|
||||
let offset: CGFloat = incoming ? 42.0 : 0.0
|
||||
|
||||
if let selectionNode = self.selectionNode {
|
||||
|
@ -589,8 +589,8 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
|
||||
installedPacks.insert(info.0)
|
||||
}
|
||||
|
||||
let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: nil, canInstallPeerSpecificPack: .none, theme: theme, hasGifs: false, hasSettings: false)
|
||||
let gridEntries = chatMediaInputGridEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: nil, canInstallPeerSpecificPack: .none, trendingPacks: trendingPacks, hasSearch: false, hasAccessories: false, strings: strings, theme: theme)
|
||||
let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: nil, canInstallPeerSpecificPack: .none, theme: theme, strings: strings, hasGifs: false, hasSettings: false)
|
||||
let gridEntries = chatMediaInputGridEntries(view: view, savedStickers: savedStickers, recentStickers: recentStickers, peerSpecificPack: nil, canInstallPeerSpecificPack: .none, trendingPacks: trendingPacks, installedPacks: installedPacks, hasSearch: false, hasAccessories: false, strings: strings, theme: theme)
|
||||
|
||||
let (previousPanelEntries, previousGridEntries) = previousStickerEntries.swap((panelEntries, gridEntries))
|
||||
return (view, preparedChatMediaInputPanelEntryTransition(context: context, from: previousPanelEntries, to: panelEntries, inputNodeInteraction: stickersInputNodeInteraction, scrollToItem: nil), previousPanelEntries.isEmpty, preparedChatMediaInputGridEntryTransition(account: context.account, view: view, from: previousGridEntries, to: gridEntries, update: update, interfaceInteraction: controllerInteraction, inputNodeInteraction: stickersInputNodeInteraction, trendingInteraction: trendingInteraction), previousGridEntries.isEmpty)
|
||||
@ -624,8 +624,8 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
|
||||
installedPacks.insert(info.0)
|
||||
}
|
||||
|
||||
let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: nil, recentStickers: nil, peerSpecificPack: nil, canInstallPeerSpecificPack: .none, theme: theme, hasGifs: false, hasSettings: false)
|
||||
let gridEntries = chatMediaInputGridEntries(view: view, savedStickers: nil, recentStickers: nil, peerSpecificPack: nil, canInstallPeerSpecificPack: .none, trendingPacks: [], hasSearch: false, hasAccessories: false, strings: strings, theme: theme)
|
||||
let panelEntries = chatMediaInputPanelEntries(view: view, savedStickers: nil, recentStickers: nil, peerSpecificPack: nil, canInstallPeerSpecificPack: .none, theme: theme, strings: strings, hasGifs: false, hasSettings: false)
|
||||
let gridEntries = chatMediaInputGridEntries(view: view, savedStickers: nil, recentStickers: nil, peerSpecificPack: nil, canInstallPeerSpecificPack: .none, trendingPacks: [], installedPacks: installedPacks, hasSearch: false, hasAccessories: false, strings: strings, theme: theme)
|
||||
|
||||
let (previousPanelEntries, previousGridEntries) = previousMaskEntries.swap((panelEntries, gridEntries))
|
||||
return (view, preparedChatMediaInputPanelEntryTransition(context: context, from: previousPanelEntries, to: panelEntries, inputNodeInteraction: masksInputNodeInteraction, scrollToItem: nil), previousPanelEntries.isEmpty, preparedChatMediaInputGridEntryTransition(account: context.account, view: view, from: previousGridEntries, to: gridEntries, update: update, interfaceInteraction: controllerInteraction, inputNodeInteraction: masksInputNodeInteraction, trendingInteraction: trendingInteraction), previousGridEntries.isEmpty)
|
||||
|
@ -3495,7 +3495,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
||||
canChangeColors = false
|
||||
}
|
||||
|
||||
if canChangeColors {
|
||||
if false, canChangeColors {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.UserInfo_ChangeColors, icon: { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ApplyTheme"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, f in
|
||||
|
@ -61,22 +61,22 @@ private enum Entry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
|
||||
func item(account: Account, inputNodeInteraction: ChatMediaInputNodeInteraction) -> ListViewItem {
|
||||
func item(account: Account, inputNodeInteraction: ChatMediaInputNodeInteraction, isVisible: @escaping () -> Bool) -> ListViewItem {
|
||||
switch self {
|
||||
case let .stickerPack(index, info, topItem, unread, theme):
|
||||
return FeaturedPackItem(account: account, inputNodeInteraction: inputNodeInteraction, collectionId: info.id, collectionInfo: info, stickerPackItem: topItem, unread: unread, index: index, theme: theme, selected: {
|
||||
inputNodeInteraction.openTrending(info.id)
|
||||
})
|
||||
}, isVisible: isVisible)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func preparedEntryTransition(account: Account, from fromEntries: [Entry], to toEntries: [Entry], inputNodeInteraction: ChatMediaInputNodeInteraction) -> Transition {
|
||||
private func preparedEntryTransition(account: Account, from fromEntries: [Entry], to toEntries: [Entry], inputNodeInteraction: ChatMediaInputNodeInteraction, isVisible: @escaping () -> Bool) -> Transition {
|
||||
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(account: account, inputNodeInteraction: inputNodeInteraction), directionHint: nil) }
|
||||
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, inputNodeInteraction: inputNodeInteraction), directionHint: nil) }
|
||||
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, inputNodeInteraction: inputNodeInteraction, isVisible: isVisible), directionHint: nil) }
|
||||
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, inputNodeInteraction: inputNodeInteraction, isVisible: isVisible), directionHint: nil) }
|
||||
|
||||
return Transition(deletions: deletions, insertions: insertions, updates: updates)
|
||||
}
|
||||
@ -101,12 +101,13 @@ private final class FeaturedPackItem: ListViewItem {
|
||||
let selectedItem: () -> Void
|
||||
let index: Int
|
||||
let theme: PresentationTheme
|
||||
let isVisible: () -> Bool
|
||||
|
||||
var selectable: Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
init(account: Account, inputNodeInteraction: ChatMediaInputNodeInteraction, collectionId: ItemCollectionId, collectionInfo: StickerPackCollectionInfo, stickerPackItem: StickerPackItem?, unread: Bool, index: Int, theme: PresentationTheme, selected: @escaping () -> Void) {
|
||||
init(account: Account, inputNodeInteraction: ChatMediaInputNodeInteraction, collectionId: ItemCollectionId, collectionInfo: StickerPackCollectionInfo, stickerPackItem: StickerPackItem?, unread: Bool, index: Int, theme: PresentationTheme, selected: @escaping () -> Void, isVisible: @escaping () -> Bool) {
|
||||
self.account = account
|
||||
self.inputNodeInteraction = inputNodeInteraction
|
||||
self.collectionId = collectionId
|
||||
@ -116,6 +117,7 @@ private final class FeaturedPackItem: ListViewItem {
|
||||
self.index = index
|
||||
self.theme = theme
|
||||
self.selectedItem = selected
|
||||
self.isVisible = isVisible
|
||||
}
|
||||
|
||||
func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||
@ -124,6 +126,7 @@ private final class FeaturedPackItem: ListViewItem {
|
||||
node.contentSize = boundingSize
|
||||
node.insets = ChatMediaInputNode.setupPanelIconInsets(item: self, previousItem: previousItem, nextItem: nextItem)
|
||||
node.inputNodeInteraction = self.inputNodeInteraction
|
||||
node.panelIsVisible = self.isVisible
|
||||
Queue.mainQueue().async {
|
||||
completion(node, {
|
||||
return (nil, { _ in
|
||||
@ -161,6 +164,10 @@ private final class FeaturedPackItemNode: ListViewItemNode {
|
||||
|
||||
private let stickerFetchedDisposable = MetaDisposable()
|
||||
|
||||
var panelIsVisible: () -> Bool = {
|
||||
return true
|
||||
}
|
||||
|
||||
override var visibility: ListViewItemNodeVisibility {
|
||||
didSet {
|
||||
self.visibilityStatus = self.visibility != .none
|
||||
@ -170,12 +177,17 @@ private final class FeaturedPackItemNode: ListViewItemNode {
|
||||
var visibilityStatus: Bool = false {
|
||||
didSet {
|
||||
if self.visibilityStatus != oldValue {
|
||||
let loopAnimatedStickers = self.inputNodeInteraction?.stickerSettings?.loopAnimatedStickers ?? false
|
||||
self.animatedStickerNode?.visibility = self.visibilityStatus && loopAnimatedStickers
|
||||
self.updateVisibility()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateVisibility() {
|
||||
let loopAnimatedStickers = self.inputNodeInteraction?.stickerSettings?.loopAnimatedStickers ?? false
|
||||
let panelVisible = self.panelIsVisible()
|
||||
self.animatedStickerNode?.visibility = self.visibilityStatus && loopAnimatedStickers && panelVisible
|
||||
}
|
||||
|
||||
init() {
|
||||
self.containerNode = ASDisplayNode()
|
||||
self.containerNode.transform = CATransform3DMakeRotation(CGFloat.pi / 2.0, 0.0, 0.0, 1.0)
|
||||
@ -278,13 +290,15 @@ private final class FeaturedPackItemNode: ListViewItemNode {
|
||||
self.imageNode.setSignal(chatMessageStickerPackThumbnail(postbox: account.postbox, resource: resource, animated: true, nilIfEmpty: true))
|
||||
|
||||
let loopAnimatedStickers = self.inputNodeInteraction?.stickerSettings?.loopAnimatedStickers ?? false
|
||||
self.imageNode.isHidden = loopAnimatedStickers
|
||||
|
||||
let animatedStickerNode: AnimatedStickerNode
|
||||
if let current = self.animatedStickerNode {
|
||||
animatedStickerNode = current
|
||||
} else {
|
||||
animatedStickerNode = AnimatedStickerNode()
|
||||
animatedStickerNode.started = { [weak self] in
|
||||
self?.imageNode.isHidden = true
|
||||
}
|
||||
self.animatedStickerNode = animatedStickerNode
|
||||
if let placeholderNode = self.placeholderNode {
|
||||
self.containerNode.insertSubnode(animatedStickerNode, belowSubnode: placeholderNode)
|
||||
@ -396,6 +410,7 @@ class StickerPaneTrendingListGridItemNode: GridItemNode {
|
||||
private var item: StickerPaneTrendingListGridItem?
|
||||
private var appliedItem: StickerPaneTrendingListGridItem?
|
||||
|
||||
private var isPanelVisible = false
|
||||
override var isVisibleInGrid: Bool {
|
||||
didSet {
|
||||
self.updateVisibility()
|
||||
@ -446,15 +461,32 @@ class StickerPaneTrendingListGridItemNode: GridItemNode {
|
||||
self.item = item
|
||||
|
||||
let entries = panelEntries(featuredPacks: item.trendingPacks, theme: item.theme)
|
||||
let transition = preparedEntryTransition(account: item.account, from: self.currentEntries, to: entries, inputNodeInteraction: item.inputNodeInteraction)
|
||||
let transition = preparedEntryTransition(account: item.account, from: self.currentEntries, to: entries, inputNodeInteraction: item.inputNodeInteraction, isVisible: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
return strongSelf.isPanelVisible && strongSelf.isVisibleInGrid
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
self.enqueuePanelTransition(transition, firstTime: self.currentEntries.isEmpty)
|
||||
self.currentEntries = entries
|
||||
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
func updateIsPanelVisible(_ isPanelVisible: Bool) {
|
||||
if self.isPanelVisible != isPanelVisible {
|
||||
self.isPanelVisible = isPanelVisible
|
||||
self.updateVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
func updateVisibility() {
|
||||
|
||||
self.listView.forEachItemNode { itemNode in
|
||||
if let itemNode = itemNode as? FeaturedPackItemNode {
|
||||
itemNode.updateVisibility()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user