mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
237f86f7ca
commit
e1b4af1461
@ -322,7 +322,7 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
|
||||
|
||||
private var spoilersRevealed = false
|
||||
|
||||
private var emojiViewProvider: ((ChatTextInputTextCustomEmojiAttribute) -> UIView)?
|
||||
public var emojiViewProvider: ((ChatTextInputTextCustomEmojiAttribute) -> UIView)?
|
||||
private let animationCache: AnimationCache
|
||||
private let animationRenderer: MultiAnimationRenderer
|
||||
|
||||
|
@ -675,6 +675,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
||||
}, schedule: { [weak textInputPanelNode] in
|
||||
textInputPanelNode?.sendMessage(.schedule)
|
||||
})
|
||||
controller.emojiViewProvider = textInputPanelNode.emojiViewProvider
|
||||
strongSelf.presentInGlobalOverlay(controller)
|
||||
}, openScheduledMessages: {
|
||||
}, openPeersNearby: {
|
||||
|
@ -489,6 +489,9 @@ private func availablePaymentMethods(form: BotPaymentForm, current: BotCheckoutP
|
||||
methods.append(.savedCredentials(savedCredentials))
|
||||
}
|
||||
}
|
||||
if !form.additionalPaymentMethods.isEmpty {
|
||||
methods.append(contentsOf: form.additionalPaymentMethods.map { .other($0) })
|
||||
}
|
||||
return methods
|
||||
}
|
||||
|
||||
@ -1416,6 +1419,9 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
}
|
||||
})
|
||||
return
|
||||
case let .other(method):
|
||||
let _ = method
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ enum BotCheckoutPaymentMethod: Equatable {
|
||||
case savedCredentials(BotPaymentSavedCredentials)
|
||||
case webToken(BotCheckoutPaymentWebToken)
|
||||
case applePay
|
||||
case other(BotPaymentMethod)
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
@ -29,6 +30,8 @@ enum BotCheckoutPaymentMethod: Equatable {
|
||||
return token.title
|
||||
case .applePay:
|
||||
return "Apple Pay"
|
||||
case let .other(method):
|
||||
return method.title
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,6 +71,9 @@ final class BotCheckoutPaymentMethodSheetController: ActionSheetController {
|
||||
case .applePay:
|
||||
title = "Apple Pay"
|
||||
icon = UIImage(bundleImageName: "Bot Payments/ApplePayLogo")?.precomposed()
|
||||
case let .other(method):
|
||||
title = method.title
|
||||
icon = nil
|
||||
}
|
||||
let value: Bool?
|
||||
if let currentMethod = currentMethod {
|
||||
|
@ -4,18 +4,23 @@ import SwiftSignalKit
|
||||
|
||||
public enum ChatTextInputAccessoryItem: Equatable {
|
||||
public enum Key: Hashable {
|
||||
case keyboard
|
||||
case stickers
|
||||
case inputButtons
|
||||
case input
|
||||
case botInput
|
||||
case commands
|
||||
case silentPost
|
||||
case messageAutoremoveTimeout
|
||||
case scheduledMessages
|
||||
}
|
||||
|
||||
public enum InputMode: Hashable {
|
||||
case keyboard
|
||||
case stickers(isEnabled: Bool, isEmoji: Bool)
|
||||
case inputButtons
|
||||
case stickers
|
||||
case emoji
|
||||
case bot
|
||||
}
|
||||
case input(isEnabled: Bool, inputMode: InputMode)
|
||||
case botInput(isEnabled: Bool, inputMode: InputMode)
|
||||
|
||||
case commands
|
||||
case silentPost(Bool)
|
||||
case messageAutoremoveTimeout(Int32?)
|
||||
@ -23,12 +28,10 @@ public enum ChatTextInputAccessoryItem: Equatable {
|
||||
|
||||
public var key: Key {
|
||||
switch self {
|
||||
case .keyboard:
|
||||
return .keyboard
|
||||
case .stickers:
|
||||
return .stickers
|
||||
case .inputButtons:
|
||||
return .inputButtons
|
||||
case .input:
|
||||
return .input
|
||||
case .botInput:
|
||||
return .botInput
|
||||
case .commands:
|
||||
return .commands
|
||||
case .silentPost:
|
||||
|
@ -19,6 +19,7 @@ swift_library(
|
||||
"//submodules/ChatPresentationInterfaceState:ChatPresentationInterfaceState",
|
||||
"//submodules/ContextUI:ContextUI",
|
||||
"//submodules/AppBundle:AppBundle",
|
||||
"//submodules/TextFormat:TextFormat",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -8,6 +8,7 @@ import AccountContext
|
||||
import ContextUI
|
||||
import TelegramCore
|
||||
import ChatPresentationInterfaceState
|
||||
import TextFormat
|
||||
|
||||
public final class ChatSendMessageActionSheetController: ViewController {
|
||||
private var controllerNode: ChatSendMessageActionSheetControllerNode {
|
||||
@ -33,6 +34,8 @@ public final class ChatSendMessageActionSheetController: ViewController {
|
||||
|
||||
private let hapticFeedback = HapticFeedback()
|
||||
|
||||
public var emojiViewProvider: ((ChatTextInputTextCustomEmojiAttribute) -> UIView)?
|
||||
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, interfaceState: ChatPresentationInterfaceState, gesture: ContextGesture, sourceSendButton: ASDisplayNode, textInputNode: EditableTextNode, attachment: Bool = false, completion: @escaping () -> Void, sendMessage: @escaping (Bool) -> Void, schedule: @escaping () -> Void) {
|
||||
self.context = context
|
||||
self.interfaceState = interfaceState
|
||||
@ -79,13 +82,18 @@ public final class ChatSendMessageActionSheetController: ViewController {
|
||||
var reminders = false
|
||||
var isSecret = false
|
||||
var canSchedule = false
|
||||
var hasEntityKeyboard = false
|
||||
if case let .peer(peerId) = self.interfaceState.chatLocation {
|
||||
reminders = peerId == context.account.peerId
|
||||
isSecret = peerId.namespace == Namespaces.Peer.SecretChat
|
||||
canSchedule = !isSecret
|
||||
}
|
||||
|
||||
self.displayNode = ChatSendMessageActionSheetControllerNode(context: self.context, presentationData: self.presentationData, reminders: reminders, gesture: gesture, sourceSendButton: self.sourceSendButton, textInputNode: self.textInputNode, attachment: self.attachment, forwardedCount: forwardedCount, send: { [weak self] in
|
||||
if case .media = self.interfaceState.inputMode {
|
||||
hasEntityKeyboard = true
|
||||
}
|
||||
|
||||
self.displayNode = ChatSendMessageActionSheetControllerNode(context: self.context, presentationData: self.presentationData, reminders: reminders, gesture: gesture, sourceSendButton: self.sourceSendButton, textInputNode: self.textInputNode, attachment: self.attachment, forwardedCount: forwardedCount, hasEntityKeyboard: hasEntityKeyboard, send: { [weak self] in
|
||||
self?.sendMessage(false)
|
||||
self?.dismiss(cancel: false)
|
||||
}, sendSilently: { [weak self] in
|
||||
|
@ -9,6 +9,7 @@ import TelegramPresentationData
|
||||
import AccountContext
|
||||
import AppBundle
|
||||
import ContextUI
|
||||
import TextFormat
|
||||
|
||||
private let leftInset: CGFloat = 16.0
|
||||
private let rightInset: CGFloat = 16.0
|
||||
@ -158,6 +159,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
private let textInputNode: EditableTextNode
|
||||
private let attachment: Bool
|
||||
private let forwardedCount: Int?
|
||||
private let hasEntityKeyboard: Bool
|
||||
|
||||
private let send: (() -> Void)?
|
||||
private let cancel: (() -> Void)?
|
||||
@ -183,7 +185,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
|
||||
private var animateInputField = false
|
||||
|
||||
init(context: AccountContext, presentationData: PresentationData, reminders: Bool, gesture: ContextGesture, sourceSendButton: ASDisplayNode, textInputNode: EditableTextNode, attachment: Bool, forwardedCount: Int?, send: (() -> Void)?, sendSilently: (() -> Void)?, schedule: (() -> Void)?, cancel: (() -> Void)?) {
|
||||
init(context: AccountContext, presentationData: PresentationData, reminders: Bool, gesture: ContextGesture, sourceSendButton: ASDisplayNode, textInputNode: EditableTextNode, attachment: Bool, forwardedCount: Int?, hasEntityKeyboard: Bool, send: (() -> Void)?, sendSilently: (() -> Void)?, schedule: (() -> Void)?, cancel: (() -> Void)?) {
|
||||
self.context = context
|
||||
self.presentationData = presentationData
|
||||
self.sourceSendButton = sourceSendButton
|
||||
@ -191,6 +193,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
self.textInputNode = textInputNode
|
||||
self.attachment = attachment
|
||||
self.forwardedCount = forwardedCount
|
||||
self.hasEntityKeyboard = hasEntityKeyboard
|
||||
|
||||
self.send = send
|
||||
self.cancel = cancel
|
||||
@ -422,7 +425,11 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
let fromFrame = CGRect(origin: CGPoint(), size: CGSize(width: initialWidth, height: self.textFieldFrame.height + 2.0))
|
||||
let delta = (fromFrame.height - self.messageClipNode.bounds.height) / 2.0
|
||||
|
||||
let inputHeight = layout.inputHeight ?? 0.0
|
||||
var inputHeight = layout.inputHeight ?? 0.0
|
||||
if self.hasEntityKeyboard {
|
||||
inputHeight = layout.standardInputHeight
|
||||
}
|
||||
|
||||
var clipDelta = delta
|
||||
if inputHeight.isZero || layout.isNonExclusive {
|
||||
clipDelta -= self.contentContainerNode.frame.height + 16.0
|
||||
@ -531,7 +538,11 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
let delta = (toFrame.height - self.messageClipNode.bounds.height) / 2.0
|
||||
|
||||
if cancel && self.animateInputField {
|
||||
let inputHeight = layout.inputHeight ?? 0.0
|
||||
var inputHeight = layout.inputHeight ?? 0.0
|
||||
if self.hasEntityKeyboard {
|
||||
inputHeight = layout.standardInputHeight
|
||||
}
|
||||
|
||||
var clipDelta = delta
|
||||
if inputHeight.isZero || layout.isNonExclusive {
|
||||
clipDelta -= self.contentContainerNode.frame.height + 16.0
|
||||
@ -589,8 +600,12 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
||||
|
||||
let menuHeightWithInset = contentSize.height + 16.0
|
||||
|
||||
let insets = layout.insets(options: [.statusBar, .input])
|
||||
let inputHeight = layout.inputHeight ?? 0.0
|
||||
var insets = layout.insets(options: [.statusBar, .input])
|
||||
var inputHeight = layout.inputHeight ?? 0.0
|
||||
if self.hasEntityKeyboard {
|
||||
insets.bottom = max(insets.bottom, layout.standardInputHeight)
|
||||
inputHeight = layout.standardInputHeight
|
||||
}
|
||||
|
||||
let contentOffset = self.scrollNode.view.contentOffset.y
|
||||
|
||||
|
@ -143,6 +143,7 @@ public final class LottieAnimationComponent: Component {
|
||||
}
|
||||
strongSelf.didPlayToCompletion = true
|
||||
let _ = strongSelf.update(component: component, availableSize: availableSize, transition: transition)
|
||||
strongSelf.currentCompletion = nil
|
||||
}
|
||||
animationView.loopMode = .playOnce
|
||||
} else {
|
||||
@ -175,9 +176,9 @@ public final class LottieAnimationComponent: Component {
|
||||
updatePlayback = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
self.component = component
|
||||
}
|
||||
|
||||
if updateColors, let animationView = self.animationView {
|
||||
if let value = component.colors["__allcolors__"] {
|
||||
|
@ -122,12 +122,14 @@ open class TooltipController: ViewController, StandalonePresentableController {
|
||||
private let dismissImmediatelyOnLayoutUpdate: Bool
|
||||
private var timeoutTimer: SwiftSignalKit.Timer?
|
||||
|
||||
private var padding: CGFloat
|
||||
|
||||
private var layout: ContainerViewLayout?
|
||||
private var initialArrowOnBottom: Bool
|
||||
|
||||
public var dismissed: ((Bool) -> Void)?
|
||||
|
||||
public init(content: TooltipControllerContent, baseFontSize: CGFloat, timeout: Double = 2.0, dismissByTapOutside: Bool = false, dismissByTapOutsideSource: Bool = false, dismissImmediatelyOnLayoutUpdate: Bool = false, arrowOnBottom: Bool = true) {
|
||||
public init(content: TooltipControllerContent, baseFontSize: CGFloat, timeout: Double = 2.0, dismissByTapOutside: Bool = false, dismissByTapOutsideSource: Bool = false, dismissImmediatelyOnLayoutUpdate: Bool = false, arrowOnBottom: Bool = true, padding: CGFloat = 8.0) {
|
||||
self.content = content
|
||||
self.baseFontSize = baseFontSize
|
||||
self.timeout = timeout
|
||||
@ -135,6 +137,7 @@ open class TooltipController: ViewController, StandalonePresentableController {
|
||||
self.dismissByTapOutsideSource = dismissByTapOutsideSource
|
||||
self.dismissImmediatelyOnLayoutUpdate = dismissImmediatelyOnLayoutUpdate
|
||||
self.initialArrowOnBottom = arrowOnBottom
|
||||
self.padding = padding
|
||||
|
||||
super.init(navigationBarPresentationData: nil)
|
||||
|
||||
@ -153,6 +156,7 @@ open class TooltipController: ViewController, StandalonePresentableController {
|
||||
self.displayNode = TooltipControllerNode(content: self.content, baseFontSize: self.baseFontSize, dismiss: { [weak self] tappedInside in
|
||||
self?.dismiss(tappedInside: tappedInside)
|
||||
}, dismissByTapOutside: self.dismissByTapOutside, dismissByTapOutsideSource: self.dismissByTapOutsideSource)
|
||||
self.controllerNode.padding = self.padding
|
||||
self.controllerNode.arrowOnBottom = self.initialArrowOnBottom
|
||||
self.displayNodeDidLoad()
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ final class TooltipControllerNode: ASDisplayNode {
|
||||
var sourceRect: CGRect?
|
||||
var arrowOnBottom: Bool = true
|
||||
|
||||
var padding: CGFloat = 8.0
|
||||
|
||||
private var dismissedByTouchOutside = false
|
||||
private var dismissByTapOutsideSource = false
|
||||
|
||||
@ -122,7 +124,7 @@ final class TooltipControllerNode: ASDisplayNode {
|
||||
}
|
||||
self.arrowOnBottom = arrowOnBottom
|
||||
|
||||
let horizontalOrigin: CGFloat = floor(min(max(8.0, sourceRect.midX - contentSize.width / 2.0), layout.size.width - contentSize.width - 8.0))
|
||||
let horizontalOrigin: CGFloat = floor(min(max(self.padding, sourceRect.midX - contentSize.width / 2.0), layout.size.width - contentSize.width - self.padding))
|
||||
|
||||
transition.updateFrame(node: self.containerNode, frame: CGRect(origin: CGPoint(x: horizontalOrigin, y: verticalOrigin), size: contentSize))
|
||||
self.containerNode.relativeArrowPosition = (sourceRect.midX - horizontalOrigin, arrowOnBottom)
|
||||
|
@ -373,8 +373,17 @@ private final class GiftComponent: CombinedComponent {
|
||||
)
|
||||
|
||||
let size = CGSize(width: context.availableSize.width, height: insets.top + title.size.height + spacing + subtitle.size.height + insets.bottom)
|
||||
let distance = context.availableSize.width - insets.left - insets.right - label.size.width - subtitle.size.width - discountSize.width - 7.0
|
||||
|
||||
let labelOriginY: CGFloat
|
||||
if distance > 8.0 {
|
||||
labelOriginY = size.height / 2.0
|
||||
} else {
|
||||
labelOriginY = insets.top + title.size.height / 2.0
|
||||
}
|
||||
|
||||
context.add(label
|
||||
.position(CGPoint(x: context.availableSize.width - insets.right - label.size.width / 2.0, y: size.height / 2.0))
|
||||
.position(CGPoint(x: context.availableSize.width - insets.right - label.size.width / 2.0, y: labelOriginY))
|
||||
)
|
||||
|
||||
context.add(check
|
||||
|
@ -348,6 +348,12 @@ final class StickerPackEmojisItemNode: GridItemNode {
|
||||
self.visibleItemLayers[id] = nil
|
||||
}
|
||||
}
|
||||
for id in self.visibleItemPlaceholderViews.keys {
|
||||
if !validIds.contains(id) {
|
||||
self.visibleItemPlaceholderViews[id]?.removeFromSuperview()
|
||||
self.visibleItemPlaceholderViews[id] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateShimmerIfNeeded() {
|
||||
|
@ -120,6 +120,21 @@ public struct BotPaymentForm : Equatable {
|
||||
public let nativeProvider: BotPaymentNativeProvider?
|
||||
public let savedInfo: BotPaymentRequestedInfo?
|
||||
public let savedCredentials: BotPaymentSavedCredentials?
|
||||
public let additionalPaymentMethods: [BotPaymentMethod]
|
||||
}
|
||||
|
||||
public struct BotPaymentMethod: Equatable {
|
||||
public let url: String
|
||||
public let title: String
|
||||
}
|
||||
|
||||
extension BotPaymentMethod {
|
||||
init(apiPaymentFormMethod: Api.PaymentFormMethod) {
|
||||
switch apiPaymentFormMethod {
|
||||
case let .paymentFormMethod(url, title):
|
||||
self.init(url: url, title: title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum BotPaymentFormRequestError {
|
||||
@ -270,7 +285,6 @@ func _internal_fetchBotPaymentForm(postbox: Postbox, network: Network, source: B
|
||||
let _ = title
|
||||
let _ = description
|
||||
let _ = photo
|
||||
let _ = additionalMethods
|
||||
|
||||
var peers: [Peer] = []
|
||||
for user in apiUsers {
|
||||
@ -297,7 +311,9 @@ func _internal_fetchBotPaymentForm(postbox: Postbox, network: Network, source: B
|
||||
parsedSavedCredentials = .card(id: id, title: title)
|
||||
}
|
||||
}
|
||||
return BotPaymentForm(id: id, canSaveCredentials: (flags & (1 << 2)) != 0, passwordMissing: (flags & (1 << 3)) != 0, invoice: parsedInvoice, paymentBotId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId)), providerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(providerId)), url: url, nativeProvider: parsedNativeProvider, savedInfo: parsedSavedInfo, savedCredentials: parsedSavedCredentials)
|
||||
|
||||
let additionalPaymentMethods = additionalMethods?.map({ BotPaymentMethod(apiPaymentFormMethod: $0) }) ?? []
|
||||
return BotPaymentForm(id: id, canSaveCredentials: (flags & (1 << 2)) != 0, passwordMissing: (flags & (1 << 3)) != 0, invoice: parsedInvoice, paymentBotId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId)), providerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(providerId)), url: url, nativeProvider: parsedNativeProvider, savedInfo: parsedSavedInfo, savedCredentials: parsedSavedCredentials, additionalPaymentMethods: additionalPaymentMethods)
|
||||
}
|
||||
}
|
||||
|> mapError { _ -> BotPaymentFormRequestError in }
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1127,6 +1127,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
guard let packReference = packReferences.first, let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.chatDisplayNode.dismissTextInput()
|
||||
let controller = StickerPackScreen(context: context, updatedPresentationData: strongSelf.updatedPresentationData, mainStickerPack: packReference, stickerPacks: Array(packReferences), parentNavigationController: strongSelf.effectiveNavigationController)
|
||||
strongSelf.present(controller, in: .window(.root))
|
||||
}
|
||||
@ -8446,6 +8447,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
strongSelf.controllerInteraction?.scheduleCurrentMessage()
|
||||
}
|
||||
})
|
||||
controller.emojiViewProvider = strongSelf.chatDisplayNode.textInputPanelNode?.emojiViewProvider
|
||||
strongSelf.sendMessageActionsController = controller
|
||||
if layout.isNonExclusive {
|
||||
strongSelf.present(controller, in: .window(.root))
|
||||
@ -15526,7 +15528,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if let tooltipController = self.mediaRecordingModeTooltipController {
|
||||
tooltipController.updateContent(.text(text), animated: true, extendTimer: true)
|
||||
} else if let rect = rect {
|
||||
let tooltipController = TooltipController(content: .text(text), baseFontSize: self.presentationData.listsFontSize.baseDisplaySize)
|
||||
let tooltipController = TooltipController(content: .text(text), baseFontSize: self.presentationData.listsFontSize.baseDisplaySize, padding: 2.0)
|
||||
self.mediaRecordingModeTooltipController = tooltipController
|
||||
tooltipController.dismissed = { [weak self, weak tooltipController] _ in
|
||||
if let strongSelf = self, let tooltipController = tooltipController, strongSelf.mediaRecordingModeTooltipController === tooltipController {
|
||||
@ -15547,7 +15549,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return
|
||||
}
|
||||
self.sendingOptionsTooltipController?.dismiss()
|
||||
let tooltipController = TooltipController(content: .text(self.presentationData.strings.Conversation_SendingOptionsTooltip), baseFontSize: self.presentationData.listsFontSize.baseDisplaySize, timeout: 3.0, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true)
|
||||
let tooltipController = TooltipController(content: .text(self.presentationData.strings.Conversation_SendingOptionsTooltip), baseFontSize: self.presentationData.listsFontSize.baseDisplaySize, timeout: 3.0, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true, padding: 2.0)
|
||||
self.sendingOptionsTooltipController = tooltipController
|
||||
tooltipController.dismissed = { [weak self, weak tooltipController] _ in
|
||||
if let strongSelf = self, let tooltipController = tooltipController, strongSelf.sendingOptionsTooltipController === tooltipController {
|
||||
|
@ -314,13 +314,13 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
|
||||
|
||||
switch chatPresentationInterfaceState.inputMode {
|
||||
case .media:
|
||||
accessoryItems.append(.keyboard)
|
||||
accessoryItems.append(.input(isEnabled: true, inputMode: .keyboard))
|
||||
return ChatTextInputPanelState(accessoryItems: accessoryItems, contextPlaceholder: contextPlaceholder, mediaRecordingState: chatPresentationInterfaceState.inputTextPanelState.mediaRecordingState)
|
||||
case .inputButtons:
|
||||
return ChatTextInputPanelState(accessoryItems: [.keyboard], contextPlaceholder: contextPlaceholder, mediaRecordingState: chatPresentationInterfaceState.inputTextPanelState.mediaRecordingState)
|
||||
return ChatTextInputPanelState(accessoryItems: [.botInput(isEnabled: true, inputMode: .keyboard)], contextPlaceholder: contextPlaceholder, mediaRecordingState: chatPresentationInterfaceState.inputTextPanelState.mediaRecordingState)
|
||||
case .none, .text:
|
||||
if let _ = chatPresentationInterfaceState.interfaceState.editMessage {
|
||||
accessoryItems.append(.stickers(isEnabled: true, isEmoji: true))
|
||||
accessoryItems.append(.input(isEnabled: true, inputMode: .emoji))
|
||||
|
||||
return ChatTextInputPanelState(accessoryItems: accessoryItems, contextPlaceholder: contextPlaceholder, mediaRecordingState: chatPresentationInterfaceState.inputTextPanelState.mediaRecordingState)
|
||||
} else {
|
||||
@ -371,13 +371,13 @@ func inputTextPanelStateForChatPresentationInterfaceState(_ chatPresentationInte
|
||||
}
|
||||
|
||||
if stickersEnabled {
|
||||
accessoryItems.append(.stickers(isEnabled: true, isEmoji: stickersAreEmoji))
|
||||
accessoryItems.append(.input(isEnabled: true, inputMode: stickersAreEmoji ? .emoji : .stickers))
|
||||
} else {
|
||||
accessoryItems.append(.stickers(isEnabled: true, isEmoji: true))
|
||||
accessoryItems.append(.input(isEnabled: true, inputMode: .emoji))
|
||||
}
|
||||
|
||||
if isTextEmpty, let message = chatPresentationInterfaceState.keyboardButtonsMessage, let _ = message.visibleButtonKeyboardMarkup, chatPresentationInterfaceState.interfaceState.messageActionsState.dismissedButtonKeyboardMessageId != message.id {
|
||||
accessoryItems.append(.inputButtons)
|
||||
accessoryItems.append(.botInput(isEnabled: true, inputMode: .bot))
|
||||
}
|
||||
}
|
||||
return ChatTextInputPanelState(accessoryItems: accessoryItems, contextPlaceholder: contextPlaceholder, mediaRecordingState: chatPresentationInterfaceState.inputTextPanelState.mediaRecordingState)
|
||||
|
@ -10,6 +10,8 @@ import AccountContext
|
||||
import ChatInterfaceState
|
||||
import AudioBlob
|
||||
import ChatPresentationInterfaceState
|
||||
import ComponentFlow
|
||||
import LottieAnimationComponent
|
||||
|
||||
private let offsetThreshold: CGFloat = 10.0
|
||||
private let dismissOffsetThreshold: CGFloat = 70.0
|
||||
@ -185,7 +187,7 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto
|
||||
|
||||
private var modeTimeoutTimer: SwiftSignalKit.Timer?
|
||||
|
||||
private let innerIconView: UIImageView
|
||||
private let animationView: ComponentView<Empty>
|
||||
|
||||
private var recordingOverlay: ChatTextInputAudioRecordingOverlay?
|
||||
private var startTouchLocation: CGPoint?
|
||||
@ -288,7 +290,7 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, presentController: @escaping (ViewController) -> Void) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.innerIconView = UIImageView()
|
||||
self.animationView = ComponentView<Empty>()
|
||||
self.presentController = presentController
|
||||
|
||||
super.init(frame: CGRect())
|
||||
@ -297,8 +299,6 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto
|
||||
|
||||
self.pallete = legacyInputMicPalette(from: theme)
|
||||
|
||||
self.insertSubview(self.innerIconView, at: 0)
|
||||
|
||||
self.disablesInteractiveTransitionGestureRecognizer = true
|
||||
|
||||
self.updateMode(mode: self.mode, animated: false, force: true)
|
||||
@ -318,51 +318,81 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto
|
||||
}
|
||||
|
||||
private func updateMode(mode: ChatTextInputMediaRecordingButtonMode, animated: Bool, force: Bool) {
|
||||
let previousMode = self.mode
|
||||
if mode != self.mode || force {
|
||||
self.mode = mode
|
||||
|
||||
if animated {
|
||||
let previousView = UIImageView(image: self.innerIconView.image)
|
||||
previousView.frame = self.innerIconView.frame
|
||||
self.addSubview(previousView)
|
||||
previousView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||
previousView.layer.animateScale(from: 1.0, to: 0.3, duration: 0.15, removeOnCompletion: false, completion: { [weak previousView] _ in
|
||||
previousView?.removeFromSuperview()
|
||||
})
|
||||
self.updateAnimation(previousMode: previousMode)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateAnimation(previousMode: ChatTextInputMediaRecordingButtonMode) {
|
||||
let image: UIImage?
|
||||
switch self.mode {
|
||||
case .audio:
|
||||
self.icon = PresentationResourcesChat.chatInputPanelVoiceActiveButtonImage(self.theme)
|
||||
self.innerIconView.image = PresentationResourcesChat.chatInputPanelVoiceButtonImage(self.theme)
|
||||
image = PresentationResourcesChat.chatInputPanelVoiceButtonImage(self.theme)
|
||||
case .video:
|
||||
self.icon = PresentationResourcesChat.chatInputPanelVideoActiveButtonImage(self.theme)
|
||||
self.innerIconView.image = PresentationResourcesChat.chatInputPanelVideoButtonImage(self.theme)
|
||||
}
|
||||
if let image = self.innerIconView.image {
|
||||
let size = self.bounds.size
|
||||
let iconSize = image.size
|
||||
self.innerIconView.frame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
image = PresentationResourcesChat.chatInputPanelVoiceButtonImage(self.theme)
|
||||
}
|
||||
|
||||
if animated {
|
||||
self.innerIconView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, removeOnCompletion: false)
|
||||
self.innerIconView.layer.animateSpring(from: 0.4 as NSNumber, to: 1.0 as NSNumber, keyPath: "transform.scale", duration: 0.4)
|
||||
let size = self.bounds.size
|
||||
let iconSize: CGSize
|
||||
if let image = image {
|
||||
iconSize = image.size
|
||||
} else {
|
||||
iconSize = size
|
||||
}
|
||||
|
||||
let animationFrame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
|
||||
let animationName: String
|
||||
switch self.mode {
|
||||
case .audio:
|
||||
animationName = "anim_videoToMic"
|
||||
case .video:
|
||||
animationName = "anim_micToVideo"
|
||||
}
|
||||
|
||||
var animationMode: LottieAnimationComponent.AnimationItem.Mode = .still(position: .end)
|
||||
if previousMode != mode {
|
||||
animationMode = .animating(loop: false)
|
||||
}
|
||||
|
||||
let colorKeys = ["__allcolors__"]
|
||||
var colors: [String: UIColor] = [:]
|
||||
for colorKey in colorKeys {
|
||||
colors[colorKey] = self.theme.chat.inputPanel.panelControlColor
|
||||
}
|
||||
|
||||
let _ = animationView.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(LottieAnimationComponent(
|
||||
animation: LottieAnimationComponent.AnimationItem(
|
||||
name: animationName,
|
||||
mode: animationMode
|
||||
),
|
||||
colors: colors,
|
||||
size: animationFrame.size
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: animationFrame.size
|
||||
)
|
||||
// self.innerIconView.frame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
if let view = animationView.view {
|
||||
view.isUserInteractionEnabled = false
|
||||
if view.superview == nil {
|
||||
self.insertSubview(view, at: 0)
|
||||
}
|
||||
view.frame = animationFrame
|
||||
}
|
||||
}
|
||||
|
||||
func updateTheme(theme: PresentationTheme) {
|
||||
self.theme = theme
|
||||
|
||||
switch self.mode {
|
||||
case .audio:
|
||||
self.icon = PresentationResourcesChat.chatInputPanelVoiceActiveButtonImage(self.theme)
|
||||
self.innerIconView.image = PresentationResourcesChat.chatInputPanelVoiceButtonImage(self.theme)
|
||||
case .video:
|
||||
self.icon = PresentationResourcesChat.chatInputPanelVideoActiveButtonImage(self.theme)
|
||||
self.innerIconView.image = PresentationResourcesChat.chatInputPanelVideoButtonImage(self.theme)
|
||||
}
|
||||
self.updateAnimation(previousMode: self.mode)
|
||||
|
||||
self.pallete = legacyInputMicPalette(from: theme)
|
||||
self.micDecorationValue?.setColor(self.theme.chat.inputPanel.actionControlFillColor)
|
||||
@ -467,8 +497,8 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto
|
||||
micDecoration.isHidden = false
|
||||
micDecoration.startAnimating()
|
||||
|
||||
innerIconView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||
innerIconView.layer.animateScale(from: 1.0, to: 0.3, duration: 0.15, removeOnCompletion: false)
|
||||
self.animationView.view?.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||
self.animationView.view?.layer.animateScale(from: 1.0, to: 0.3, duration: 0.15, removeOnCompletion: false)
|
||||
}
|
||||
|
||||
override func animateOut(_ toSmallSize: Bool) {
|
||||
@ -480,8 +510,8 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto
|
||||
micDecoration.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.03, delay: 0.15, removeOnCompletion: false)
|
||||
} else {
|
||||
micDecoration.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.18, removeOnCompletion: false)
|
||||
innerIconView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, removeOnCompletion: false)
|
||||
innerIconView.layer.animateScale(from: 0.3, to: 1.0, duration: 0.15, removeOnCompletion: false)
|
||||
self.animationView.view?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, removeOnCompletion: false)
|
||||
self.animationView.view?.layer.animateScale(from: 0.3, to: 1.0, duration: 0.15, removeOnCompletion: false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -490,8 +520,10 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto
|
||||
let size = self.bounds.size
|
||||
if size != self.previousSize {
|
||||
self.previousSize = size
|
||||
let iconSize = self.innerIconView.bounds.size
|
||||
self.innerIconView.frame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
if let view = self.animationView.view {
|
||||
let iconSize = view.bounds.size
|
||||
view.frame = CGRect(origin: CGPoint(x: floor((size.width - iconSize.width) / 2.0), y: floor((size.height - iconSize.height) / 2.0)), size: iconSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,9 +59,12 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
|
||||
self.iconImageNode.isUserInteractionEnabled = false
|
||||
self.addSubnode(self.iconImageNode)
|
||||
|
||||
if case .stickers = item {
|
||||
switch item {
|
||||
case .input, .botInput:
|
||||
self.iconImageNode.isHidden = true
|
||||
self.animationView = ComponentView<Empty>()
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if let text = text {
|
||||
@ -116,12 +119,15 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
|
||||
|
||||
static func imageAndInsets(item: ChatTextInputAccessoryItem, theme: PresentationTheme, strings: PresentationStrings) -> (UIImage?, String?, String, CGFloat, UIEdgeInsets) {
|
||||
switch item {
|
||||
case let .input(isEnabled, inputMode), let .botInput(isEnabled, inputMode):
|
||||
switch inputMode {
|
||||
case .keyboard:
|
||||
return (PresentationResourcesChat.chatInputTextFieldKeyboardImage(theme), nil, strings.VoiceOver_Keyboard, 1.0, UIEdgeInsets())
|
||||
case let .stickers(enabled, _):
|
||||
return (PresentationResourcesChat.chatInputTextFieldStickersImage(theme), nil, strings.VoiceOver_Stickers, enabled ? 1.0 : 0.4, UIEdgeInsets())
|
||||
case .inputButtons:
|
||||
case .stickers, .emoji:
|
||||
return (PresentationResourcesChat.chatInputTextFieldStickersImage(theme), nil, strings.VoiceOver_Stickers, isEnabled ? 1.0 : 0.4, UIEdgeInsets())
|
||||
case .bot:
|
||||
return (PresentationResourcesChat.chatInputTextFieldInputButtonsImage(theme), nil, strings.VoiceOver_BotKeyboard, 1.0, UIEdgeInsets())
|
||||
}
|
||||
case .commands:
|
||||
return (PresentationResourcesChat.chatInputTextFieldCommandsImage(theme), nil, strings.VoiceOver_BotCommands, 1.0, UIEdgeInsets())
|
||||
case let .silentPost(value):
|
||||
@ -143,7 +149,7 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
|
||||
|
||||
static func calculateWidth(item: ChatTextInputAccessoryItem, image: UIImage?, text: String?, strings: PresentationStrings) -> CGFloat {
|
||||
switch item {
|
||||
case .keyboard, .stickers, .inputButtons, .silentPost, .commands, .scheduledMessages:
|
||||
case .input, .botInput, .silentPost, .commands, .scheduledMessages:
|
||||
return 32.0
|
||||
case let .messageAutoremoveTimeout(timeout):
|
||||
var imageWidth = (image?.size.width ?? 0.0) + CGFloat(8.0)
|
||||
@ -156,6 +162,7 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
|
||||
}
|
||||
|
||||
func updateLayout(item: ChatTextInputAccessoryItem, size: CGSize) {
|
||||
let previousItem = self.item
|
||||
self.item = item
|
||||
|
||||
if let image = self.iconImageNode.image {
|
||||
@ -165,26 +172,112 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
|
||||
let imageFrame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) / 2.0), y: floor((size.height - image.size.height) / 2.0) - bottomInset), size: image.size)
|
||||
self.iconImageNode.frame = imageFrame
|
||||
|
||||
if case let .stickers(_, isEmoji) = item, let animationView = self.animationView {
|
||||
if let animationView = self.animationView {
|
||||
let animationFrame = imageFrame.insetBy(dx: -4.0, dy: -4.0)
|
||||
|
||||
var colors: [String: UIColor] = [:]
|
||||
let colorKeys: [String] = [
|
||||
var previousInputMode: ChatTextInputAccessoryItem.InputMode?
|
||||
var inputMode: ChatTextInputAccessoryItem.InputMode?
|
||||
|
||||
switch previousItem {
|
||||
case let .input(_, itemInputMode), let .botInput(_, itemInputMode):
|
||||
previousInputMode = itemInputMode
|
||||
default:
|
||||
break
|
||||
}
|
||||
switch item {
|
||||
case let .input(_, itemInputMode), let .botInput(_, itemInputMode):
|
||||
inputMode = itemInputMode
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
let emojiColorKeys = [
|
||||
"Ellipse 33.Ellipse 33.Stroke 1",
|
||||
"Ellipse 34.Ellipse 34.Stroke 1",
|
||||
"Oval.Oval.Fill 1",
|
||||
"Oval 2.Oval.Fill 1",
|
||||
"Path 85.Path 85.Stroke 1"
|
||||
]
|
||||
|
||||
var colorKeys: [String] = ["__allcolors__"]
|
||||
let animationName: String
|
||||
var animationMode: LottieAnimationComponent.AnimationItem.Mode = .still(position: .end)
|
||||
if let inputMode = inputMode {
|
||||
switch inputMode {
|
||||
case .keyboard:
|
||||
if let previousInputMode = previousInputMode {
|
||||
if case .stickers = previousInputMode {
|
||||
animationName = "anim_stickerToKey"
|
||||
animationMode = .animating(loop: false)
|
||||
} else if case .emoji = previousInputMode {
|
||||
animationName = "anim_smileToKey"
|
||||
animationMode = .animating(loop: false)
|
||||
} else if case .bot = previousInputMode {
|
||||
animationName = "anim_botToKey"
|
||||
animationMode = .animating(loop: false)
|
||||
} else {
|
||||
animationName = "anim_stickerToKey"
|
||||
}
|
||||
} else {
|
||||
animationName = "anim_stickerToKey"
|
||||
}
|
||||
case .stickers:
|
||||
if let previousInputMode = previousInputMode {
|
||||
if case .keyboard = previousInputMode {
|
||||
animationName = "anim_keyToSticker"
|
||||
animationMode = .animating(loop: false)
|
||||
} else if case .emoji = previousInputMode {
|
||||
animationName = "anim_smileToSticker"
|
||||
animationMode = .animating(loop: false)
|
||||
colorKeys = emojiColorKeys
|
||||
} else {
|
||||
animationName = "anim_keyToSticker"
|
||||
}
|
||||
} else {
|
||||
animationName = "anim_keyToSticker"
|
||||
}
|
||||
case .emoji:
|
||||
if let previousInputMode = previousInputMode {
|
||||
if case .keyboard = previousInputMode {
|
||||
animationName = "anim_keyToSmile"
|
||||
animationMode = .animating(loop: false)
|
||||
} else if case .stickers = previousInputMode {
|
||||
animationName = "anim_stickerToSmile"
|
||||
animationMode = .animating(loop: false)
|
||||
colorKeys = emojiColorKeys
|
||||
} else {
|
||||
animationName = "anim_keyToSmile"
|
||||
}
|
||||
} else {
|
||||
animationName = "anim_keyToSmile"
|
||||
}
|
||||
case .bot:
|
||||
if let previousInputMode = previousInputMode {
|
||||
if case .keyboard = previousInputMode {
|
||||
animationName = "anim_keyToBot"
|
||||
animationMode = .animating(loop: false)
|
||||
} else {
|
||||
animationName = "anim_keyToBot"
|
||||
}
|
||||
} else {
|
||||
animationName = "anim_keyToBot"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
animationName = ""
|
||||
}
|
||||
|
||||
var colors: [String: UIColor] = [:]
|
||||
for colorKey in colorKeys {
|
||||
colors[colorKey] = self.theme.chat.inputPanel.inputControlColor
|
||||
}
|
||||
|
||||
let _ = animationView.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(LottieAnimationComponent(
|
||||
animation: LottieAnimationComponent.AnimationItem(
|
||||
name: !isEmoji ? "anim_stickertosmile" : "anim_smiletosticker",
|
||||
mode: .animateTransitionFromPrevious
|
||||
name: animationName,
|
||||
mode: animationMode
|
||||
),
|
||||
colors: colors,
|
||||
size: animationFrame.size
|
||||
@ -193,6 +286,7 @@ private final class AccessoryItemIconButtonNode: HighlightTrackingButtonNode {
|
||||
containerSize: animationFrame.size
|
||||
)
|
||||
if let view = animationView.view {
|
||||
view.isUserInteractionEnabled = false
|
||||
if view.superview == nil {
|
||||
self.view.addSubview(view)
|
||||
}
|
||||
@ -586,7 +680,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
|
||||
private var touchDownGestureRecognizer: TouchDownGestureRecognizer?
|
||||
|
||||
private var emojiViewProvider: ((ChatTextInputTextCustomEmojiAttribute) -> UIView)?
|
||||
var emojiViewProvider: ((ChatTextInputTextCustomEmojiAttribute) -> UIView)?
|
||||
|
||||
init(presentationInterfaceState: ChatPresentationInterfaceState, presentationContext: ChatPresentationContext?, presentController: @escaping (ViewController) -> Void) {
|
||||
self.presentationInterfaceState = presentationInterfaceState
|
||||
@ -2942,20 +3036,23 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
for (item, currentButton) in self.accessoryItemButtons {
|
||||
if currentButton === button {
|
||||
switch item {
|
||||
case let .stickers(enabled, _):
|
||||
if enabled {
|
||||
self.interfaceInteraction?.openStickers()
|
||||
} else {
|
||||
self.interfaceInteraction?.displayRestrictedInfo(.stickers, .tooltip)
|
||||
}
|
||||
case let .input(isEnabled, inputMode), let .botInput(isEnabled, inputMode):
|
||||
switch inputMode {
|
||||
case .keyboard:
|
||||
self.interfaceInteraction?.updateInputModeAndDismissedButtonKeyboardMessageId({ state in
|
||||
return (.text, state.keyboardButtonsMessage?.id)
|
||||
})
|
||||
case .inputButtons:
|
||||
case .stickers, .emoji:
|
||||
if isEnabled {
|
||||
self.interfaceInteraction?.openStickers()
|
||||
} else {
|
||||
self.interfaceInteraction?.displayRestrictedInfo(.stickers, .tooltip)
|
||||
}
|
||||
case .bot:
|
||||
self.interfaceInteraction?.updateInputModeAndDismissedButtonKeyboardMessageId({ state in
|
||||
return (.inputButtons, nil)
|
||||
})
|
||||
}
|
||||
case .commands:
|
||||
self.interfaceInteraction?.updateTextInputStateAndMode { _, inputMode in
|
||||
return (ChatTextInputState(inputText: NSAttributedString(string: "/")), .text)
|
||||
@ -3011,7 +3108,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
|
||||
func frameForStickersButton() -> CGRect? {
|
||||
for (item, button) in self.accessoryItemButtons {
|
||||
if case .stickers = item {
|
||||
if case let .input(_, inputMode) = item, case .stickers = inputMode {
|
||||
return button.frame.insetBy(dx: 0.0, dy: 6.0)
|
||||
}
|
||||
}
|
||||
|
@ -329,6 +329,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
||||
}, schedule: { [weak textInputPanelNode] in
|
||||
textInputPanelNode?.sendMessage(.schedule)
|
||||
})
|
||||
controller.emojiViewProvider = textInputPanelNode.emojiViewProvider
|
||||
strongSelf.presentInGlobalOverlay(controller, nil)
|
||||
}, openScheduledMessages: {
|
||||
}, openPeersNearby: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user