mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-03 05:03:45 +00:00
Input field
This commit is contained in:
parent
5efc685585
commit
948a99a143
@ -28,7 +28,7 @@ final class SendButton: HighlightTrackingButton {
|
||||
private let kind: Kind
|
||||
|
||||
private let containerView: UIView
|
||||
private let backgroundView: GlassBackgroundView
|
||||
private let backgroundView: UIImageView
|
||||
private let iconView: UIImageView
|
||||
private var activityIndicator: RadialStatusNode?
|
||||
|
||||
@ -41,7 +41,8 @@ final class SendButton: HighlightTrackingButton {
|
||||
self.containerView = UIView()
|
||||
self.containerView.isUserInteractionEnabled = false
|
||||
|
||||
self.backgroundView = GlassBackgroundView()
|
||||
self.backgroundView = UIImageView()
|
||||
self.backgroundView.image = generateStretchableFilledCircleImage(diameter: 34.0, color: .white)?.withRenderingMode(.alwaysTemplate)
|
||||
|
||||
self.iconView = UIImageView()
|
||||
self.iconView.isUserInteractionEnabled = false
|
||||
@ -69,12 +70,12 @@ final class SendButton: HighlightTrackingButton {
|
||||
size: CGSize,
|
||||
transition: ComponentTransition
|
||||
) {
|
||||
let innerSize = CGSize(width: size.width, height: size.height)
|
||||
let innerSize = CGSize(width: size.width - 3.0 * 2.0, height: size.height - 3.0 * 2.0)
|
||||
let containerFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - innerSize.width) * 0.5), y: floorToScreenPixels((size.height - innerSize.height) * 0.5)), size: innerSize)
|
||||
transition.setFrame(view: self.containerView, frame: containerFrame)
|
||||
transition.setCornerRadius(layer: self.containerView.layer, cornerRadius: innerSize.height * 0.5)
|
||||
|
||||
self.backgroundView.update(size: innerSize, cornerRadius: innerSize.height * 0.5, isDark: presentationData.theme.overallDarkAppearance, tintColor: .init(kind: .custom, color: presentationData.theme.chat.inputPanel.actionControlFillColor), transition: .immediate)
|
||||
self.backgroundView.tintColor = presentationData.theme.chat.inputPanel.actionControlFillColor
|
||||
transition.setFrame(view: self.backgroundView, frame: CGRect(origin: CGPoint(), size: innerSize))
|
||||
|
||||
if self.previousIsAnimatedIn != isAnimatedIn {
|
||||
|
||||
@ -382,7 +382,12 @@ public struct PresentationResourcesChat {
|
||||
|
||||
public static func chatInputPanelSendIconImage(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.chatInputPanelSendIconImage.rawValue, { theme in
|
||||
return generateImage(CGSize(width: 33.0, height: 33.0), rotatedContext: { size, context in
|
||||
return generateImage(CGSize(width: 34.0, height: 34.0), rotatedContext: { size, context in
|
||||
UIGraphicsPushContext(context)
|
||||
defer {
|
||||
UIGraphicsPopContext()
|
||||
}
|
||||
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
let color: UIColor
|
||||
if [.day, .night].contains(theme.referenceTheme.baseTheme) && !theme.chat.message.outgoing.bubble.withWallpaper.hasSingleFillColor {
|
||||
@ -390,13 +395,10 @@ public struct PresentationResourcesChat {
|
||||
} else {
|
||||
color = theme.chat.inputPanel.actionControlForegroundColor
|
||||
}
|
||||
context.setStrokeColor(color.cgColor)
|
||||
context.setFillColor(color.cgColor)
|
||||
context.setLineWidth(2.0)
|
||||
context.setLineCap(.round)
|
||||
context.setLineJoin(.round)
|
||||
let _ = try? drawSvgPath(context, path: "M11,14.6666667 L16.4310816,9.40016333 L16.4310816,9.40016333 C16.4694824,9.36292619 16.5305176,9.36292619 16.5689184,9.40016333 L22,14.6666667 S ")
|
||||
let _ = try? drawSvgPath(context, path: "M16.5,9.33333333 C17.0522847,9.33333333 17.5,9.78104858 17.5,10.3333333 L17.5,24 C17.5,24.5522847 17.0522847,25 16.5,25 C15.9477153,25 15.5,24.5522847 15.5,24 L15.5,10.3333333 C15.5,9.78104858 15.9477153,9.33333333 16.5,9.33333333 Z ")
|
||||
|
||||
if let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/SendIcon"), color: color) {
|
||||
image.draw(in: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - image.size.width) * 0.5), y: floorToScreenPixels((size.height - image.size.height) * 0.5)), size: image.size))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -388,7 +388,7 @@ public final class ChatRecordingPreviewInputPanelNodeImpl: ChatInputPanelNode {
|
||||
}
|
||||
|
||||
override public func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||
let waveformBackgroundFrame = CGRect(origin: CGPoint(x: 2.0, y: 2.0), size: CGSize(width: width - 2.0 * 2.0, height: 40.0 - 2.0 * 2.0))
|
||||
let waveformBackgroundFrame = CGRect(origin: CGPoint(x: 3.0, y: 3.0), size: CGSize(width: width - 3.0 * 2.0, height: 40.0 - 3.0 * 2.0))
|
||||
|
||||
if self.presentationInterfaceState != interfaceState {
|
||||
var updateWaveform = false
|
||||
@ -479,7 +479,7 @@ public final class ChatRecordingPreviewInputPanelNodeImpl: ChatInputPanelNode {
|
||||
transition: .immediate
|
||||
)
|
||||
|
||||
let waveformForegroundFrame = CGRect(origin: CGPoint(x: 2.0 + leftHandleFrame.minX, y: 2.0), size: CGSize(width: rightHandleFrame.maxX - leftHandleFrame.minX, height: 40.0 - 2.0 * 2.0))
|
||||
let waveformForegroundFrame = CGRect(origin: CGPoint(x: 3.0 + leftHandleFrame.minX, y: 3.0), size: CGSize(width: rightHandleFrame.maxX - leftHandleFrame.minX, height: 40.0 - 3.0 * 2.0))
|
||||
transition.updateFrame(node: self.waveformBackgroundNodeImpl, frame: waveformForegroundFrame)
|
||||
|
||||
self.waveformNode.updateClipping(minX: leftHandleFrame.minX - 19.0, maxX: rightHandleFrame.maxX - 19.0, transition: transition)
|
||||
@ -563,7 +563,7 @@ public final class ChatRecordingPreviewInputPanelNodeImpl: ChatInputPanelNode {
|
||||
if view.superview == nil {
|
||||
self.view.addSubview(view)
|
||||
}
|
||||
view.frame = CGRect(origin: CGPoint(x: 2.0, y: 2.0), size: scrubberSize)
|
||||
view.frame = CGRect(origin: CGPoint(x: 3.0, y: 3.0), size: scrubberSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,6 +88,8 @@ public final class ChatRecordingViewOnceButtonNode: HighlightTrackingButtonNode
|
||||
case .recordMore:
|
||||
self.iconView.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconMicrophone"), color: .white)?.withRenderingMode(.alwaysTemplate)
|
||||
}
|
||||
|
||||
self.iconView.tintColor = theme.chat.inputPanel.panelControlColor
|
||||
}
|
||||
|
||||
let backgroundFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(size.width / 2.0 - innerSize.width / 2.0), y: floorToScreenPixels(size.height / 2.0 - innerSize.height / 2.0)), size: innerSize)
|
||||
|
||||
@ -133,12 +133,11 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
private let presentationContext: ChatPresentationContext?
|
||||
private let strings: PresentationStrings
|
||||
|
||||
public let micButtonBackgroundView: GlassBackgroundView
|
||||
public let micButtonTintMaskView: UIImageView
|
||||
public let micButton: ChatTextInputMediaRecordingButton
|
||||
|
||||
public let sendContainerNode: ASDisplayNode
|
||||
public let sendButtonBackgroundView: GlassBackgroundView
|
||||
public let sendButtonBackgroundView: UIImageView
|
||||
public let sendButton: HighlightTrackingButtonNode
|
||||
public var sendButtonRadialStatusNode: ChatSendButtonRadialStatusNode?
|
||||
public var sendButtonHasApplyIcon = false
|
||||
@ -147,7 +146,6 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
public let textNode: ImmediateAnimatedCountLabelNode
|
||||
|
||||
public let expandMediaInputButton: HighlightTrackingButton
|
||||
private let expandMediaInputButtonBackgroundView: GlassBackgroundView
|
||||
private let expandMediaInputButtonIcon: GlassBackgroundView.ContentImageView
|
||||
|
||||
private var effectBadgeView: EffectBadgeView?
|
||||
@ -164,6 +162,8 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
private var micButtonPointerInteraction: PointerInteraction?
|
||||
private var sendButtonPointerInteraction: PointerInteraction?
|
||||
|
||||
let maskContentView: UIView
|
||||
|
||||
private var validLayout: CGSize?
|
||||
|
||||
public init(context: AccountContext, presentationInterfaceState: ChatPresentationInterfaceState, presentationContext: ChatPresentationContext?, presentController: @escaping (ViewController) -> Void) {
|
||||
@ -173,31 +173,31 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
let strings = presentationInterfaceState.strings
|
||||
self.strings = strings
|
||||
|
||||
self.micButtonBackgroundView = GlassBackgroundView()
|
||||
self.maskContentView = UIView()
|
||||
|
||||
self.micButtonTintMaskView = UIImageView()
|
||||
self.micButtonTintMaskView.tintColor = .black
|
||||
self.micButton = ChatTextInputMediaRecordingButton(context: context, theme: theme, pause: true, strings: strings, presentController: presentController)
|
||||
self.micButton.animationOutput = self.micButtonTintMaskView
|
||||
self.micButtonBackgroundView.maskContentView.addSubview(self.micButtonTintMaskView)
|
||||
self.maskContentView.addSubview(self.micButtonTintMaskView)
|
||||
|
||||
self.sendContainerNode = ASDisplayNode()
|
||||
self.sendContainerNode.layer.allowsGroupOpacity = true
|
||||
|
||||
self.sendButtonBackgroundView = GlassBackgroundView()
|
||||
self.sendButtonBackgroundView = UIImageView()
|
||||
self.sendButtonBackgroundView.image = generateStretchableFilledCircleImage(diameter: 34.0, color: .white)?.withRenderingMode(.alwaysTemplate)
|
||||
self.sendButton = HighlightTrackingButtonNode(pointerStyle: nil)
|
||||
|
||||
self.textNode = ImmediateAnimatedCountLabelNode()
|
||||
self.textNode.isUserInteractionEnabled = false
|
||||
|
||||
self.expandMediaInputButton = HighlightTrackingButton()
|
||||
self.expandMediaInputButtonBackgroundView = GlassBackgroundView()
|
||||
self.expandMediaInputButtonBackgroundView.isUserInteractionEnabled = false
|
||||
self.expandMediaInputButton.addSubview(self.expandMediaInputButtonBackgroundView)
|
||||
self.expandMediaInputButtonIcon = GlassBackgroundView.ContentImageView()
|
||||
self.expandMediaInputButtonBackgroundView.contentView.addSubview(self.expandMediaInputButtonIcon)
|
||||
self.maskContentView.addSubview(self.expandMediaInputButtonIcon.tintMask)
|
||||
self.expandMediaInputButtonIcon.image = PresentationResourcesChat.chatInputPanelExpandButtonImage(presentationInterfaceState.theme)
|
||||
self.expandMediaInputButtonIcon.tintColor = theme.chat.inputPanel.panelControlColor
|
||||
self.expandMediaInputButtonIcon.setMonochromaticEffect(tintColor: theme.chat.inputPanel.panelControlColor)
|
||||
self.expandMediaInputButtonIcon.tintColor = theme.chat.inputPanel.inputControlColor.withAlphaComponent(1.0)
|
||||
self.expandMediaInputButtonIcon.setMonochromaticEffect(tintColor: theme.chat.inputPanel.panelControlColor.withAlphaComponent(1.0))
|
||||
self.expandMediaInputButtonIcon.alpha = theme.chat.inputPanel.panelControlColor.alpha
|
||||
|
||||
super.init()
|
||||
|
||||
@ -225,7 +225,6 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
}
|
||||
|
||||
self.micButton.layer.allowsGroupOpacity = true
|
||||
self.view.addSubview(self.micButtonBackgroundView)
|
||||
self.view.addSubview(self.micButton)
|
||||
|
||||
self.addSubnode(self.sendContainerNode)
|
||||
@ -233,6 +232,7 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
self.sendContainerNode.addSubnode(self.sendButton)
|
||||
self.sendContainerNode.addSubnode(self.textNode)
|
||||
self.view.addSubview(self.expandMediaInputButton)
|
||||
self.expandMediaInputButton.addSubview(self.expandMediaInputButtonIcon)
|
||||
|
||||
self.expandMediaInputButton.highligthedChanged = { [weak self] highlighted in
|
||||
guard let self else {
|
||||
@ -265,8 +265,9 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
|
||||
public func updateTheme(theme: PresentationTheme, wallpaper: TelegramWallpaper) {
|
||||
self.micButton.updateTheme(theme: theme)
|
||||
self.expandMediaInputButtonIcon.tintColor = theme.chat.inputPanel.panelControlColor
|
||||
self.expandMediaInputButtonIcon.setMonochromaticEffect(tintColor: theme.chat.inputPanel.panelControlColor)
|
||||
self.expandMediaInputButtonIcon.tintColor = theme.chat.inputPanel.panelControlColor.withAlphaComponent(1.0)
|
||||
self.expandMediaInputButtonIcon.setMonochromaticEffect(tintColor: theme.chat.inputPanel.panelControlColor.withAlphaComponent(1.0))
|
||||
self.expandMediaInputButtonIcon.alpha = theme.chat.inputPanel.panelControlColor.alpha
|
||||
}
|
||||
|
||||
private var absoluteRect: (CGRect, CGSize)?
|
||||
@ -285,6 +286,7 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
self.validLayout = size
|
||||
|
||||
var innerSize = size
|
||||
innerSize.width = 38.0 + 3.0 * 2.0
|
||||
|
||||
var starsAmount: Int64?
|
||||
if let sendPaidMessageStars = interfaceState.sendPaidMessageStars, interfaceState.interfaceState.editMessage == nil {
|
||||
@ -334,15 +336,12 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
self.sendButton.imageNode.alpha = 1.0
|
||||
self.textNode.isHidden = true
|
||||
}
|
||||
|
||||
transition.updateFrame(view: self.micButtonBackgroundView, frame: CGRect(origin: CGPoint(), size: size))
|
||||
self.micButtonBackgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: ComponentTransition(transition))
|
||||
|
||||
transition.updateFrame(layer: self.micButton.layer, frame: CGRect(origin: CGPoint(), size: size))
|
||||
transition.updateFrame(layer: self.micButton.layer, frame: CGRect(origin: CGPoint(x: 7.0, y: 0.0), size: CGSize(width: size.width - 7.0, height: size.height)))
|
||||
self.micButton.layoutItems()
|
||||
|
||||
transition.updateFrame(view: self.sendButtonBackgroundView, frame: CGRect(origin: CGPoint(), size: innerSize))
|
||||
self.sendButtonBackgroundView.update(size: innerSize, cornerRadius: innerSize.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .custom, color: interfaceState.theme.chat.inputPanel.actionControlFillColor), transition: ComponentTransition(transition))
|
||||
transition.updateFrame(view: self.sendButtonBackgroundView, frame: CGRect(origin: CGPoint(), size: innerSize).insetBy(dx: 3.0, dy: 3.0))
|
||||
self.sendButtonBackgroundView.tintColor = interfaceState.theme.chat.inputPanel.panelControlAccentColor
|
||||
transition.updateFrame(layer: self.sendButton.layer, frame: CGRect(origin: CGPoint(), size: innerSize))
|
||||
transition.updateFrame(node: self.sendContainerNode, frame: CGRect(origin: CGPoint(), size: innerSize))
|
||||
|
||||
@ -350,8 +349,6 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
|
||||
let backgroundFrame = CGRect(origin: CGPoint(x: showTitle ? 5.0 + UIScreenPixel : floorToScreenPixels((size.width - backgroundSize.width) / 2.0), y: floorToScreenPixels((size.height - backgroundSize.height) / 2.0)), size: backgroundSize)
|
||||
|
||||
transition.updateFrame(view: self.expandMediaInputButton, frame: CGRect(origin: CGPoint(), size: size))
|
||||
transition.updateFrame(view: self.expandMediaInputButtonBackgroundView, frame: CGRect(origin: CGPoint(), size: size))
|
||||
self.expandMediaInputButtonBackgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: ComponentTransition(transition))
|
||||
if let image = self.expandMediaInputButtonIcon.image {
|
||||
let expandIconFrame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) * 0.5), y: floor((size.height - image.size.height) * 0.5)), size: image.size)
|
||||
self.expandMediaInputButtonIcon.center = expandIconFrame.center
|
||||
|
||||
@ -88,7 +88,7 @@ private func calclulateTextFieldMinHeight(_ presentationInterfaceState: ChatPres
|
||||
return result
|
||||
}
|
||||
|
||||
private func calculateTextFieldRealInsets(presentationInterfaceState: ChatPresentationInterfaceState, accessoryButtonsWidth: CGFloat) -> UIEdgeInsets {
|
||||
private func calculateTextFieldRealInsets(presentationInterfaceState: ChatPresentationInterfaceState, accessoryButtonsWidth: CGFloat, actionControlsWidth: CGFloat) -> UIEdgeInsets {
|
||||
var baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
if "".isEmpty {
|
||||
baseFontSize = 17.0
|
||||
@ -111,6 +111,9 @@ private func calculateTextFieldRealInsets(presentationInterfaceState: ChatPresen
|
||||
|
||||
var right: CGFloat = 0.0
|
||||
right += max(0.0, accessoryButtonsWidth - 14.0)
|
||||
if actionControlsWidth != 0.0 {
|
||||
right += actionControlsWidth
|
||||
}
|
||||
|
||||
return UIEdgeInsets(top: 4.5 + top, left: 0.0, bottom: 5.5 + bottom, right: right)
|
||||
}
|
||||
@ -201,7 +204,7 @@ private func makeTextInputTheme(context: AccountContext, interfaceState: ChatPre
|
||||
} else {
|
||||
codeBackgroundColor = UIColor(white: 0.0, alpha: 0.05)
|
||||
}
|
||||
|
||||
|
||||
return ChatInputTextView.Theme(
|
||||
quote: ChatInputTextView.Theme.Quote(
|
||||
background: authorNameColor.withMultipliedAlpha(interfaceState.theme.overallDarkAppearance ? 0.2 : 0.1),
|
||||
@ -939,7 +942,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
|
||||
if let presentationInterfaceState = self.presentationInterfaceState {
|
||||
refreshChatTextInputTypingAttributes(textInputNode.textView, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize)
|
||||
textInputNode.textContainerInset = calculateTextFieldRealInsets(presentationInterfaceState: presentationInterfaceState, accessoryButtonsWidth: accessoryButtonsWidth)
|
||||
textInputNode.textContainerInset = calculateTextFieldRealInsets(presentationInterfaceState: presentationInterfaceState, accessoryButtonsWidth: accessoryButtonsWidth, actionControlsWidth: self.actionButtons.frame.width)
|
||||
}
|
||||
|
||||
if let textInputNodeLayout = self.textInputNodeLayout {
|
||||
@ -1037,13 +1040,10 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
return max(33.0, maxHeight - (textFieldInsets.top + textFieldInsets.bottom + self.textInputViewInternalInsets.top + self.textInputViewInternalInsets.bottom))
|
||||
}
|
||||
|
||||
private func calculateTextFieldMetrics(width: CGFloat, maxHeight: CGFloat, metrics: LayoutMetrics) -> (accessoryButtonsWidth: CGFloat, textFieldHeight: CGFloat, isOverflow: Bool) {
|
||||
private func calculateTextFieldMetrics(width: CGFloat, actionControlsWidth: CGFloat, maxHeight: CGFloat, metrics: LayoutMetrics) -> (accessoryButtonsWidth: CGFloat, textFieldHeight: CGFloat, isOverflow: Bool) {
|
||||
let maxHeight = max(maxHeight, 40.0)
|
||||
|
||||
var textFieldInsets = self.textFieldInsets(metrics: metrics)
|
||||
if self.actionButtons.frame.width > 40.0 {
|
||||
textFieldInsets.right = self.actionButtons.frame.width - 2.0
|
||||
}
|
||||
let textFieldInsets = self.textFieldInsets(metrics: metrics)
|
||||
|
||||
let fieldMaxHeight = textFieldMaxHeight(maxHeight, metrics: metrics)
|
||||
|
||||
@ -1072,7 +1072,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
}
|
||||
|
||||
if let presentationInterfaceState = self.presentationInterfaceState {
|
||||
textInputViewRealInsets = calculateTextFieldRealInsets(presentationInterfaceState: presentationInterfaceState, accessoryButtonsWidth: accessoryButtonsWidth)
|
||||
textInputViewRealInsets = calculateTextFieldRealInsets(presentationInterfaceState: presentationInterfaceState, accessoryButtonsWidth: accessoryButtonsWidth, actionControlsWidth: actionControlsWidth)
|
||||
}
|
||||
|
||||
var textFieldHeight: CGFloat
|
||||
@ -1098,7 +1098,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
}
|
||||
|
||||
private func textFieldInsets(metrics: LayoutMetrics) -> UIEdgeInsets {
|
||||
let insets = UIEdgeInsets(top: 0.0, left: 54.0, bottom: 0.0, right: 54.0)
|
||||
let insets = UIEdgeInsets(top: 0.0, left: 54.0, bottom: 0.0, right: 8.0)
|
||||
return insets
|
||||
}
|
||||
|
||||
@ -1882,8 +1882,48 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
attachmentButtonX = -48.0
|
||||
}
|
||||
|
||||
self.actionButtons.micButton.updateMode(mode: interfaceState.interfaceState.mediaRecordingMode, animated: transition.isAnimated)
|
||||
|
||||
var hideMicButton = false
|
||||
if inputHasText || self.extendedSearchLayout {
|
||||
hideMicButton = true
|
||||
}
|
||||
if let mediaRecordingState {
|
||||
switch mediaRecordingState {
|
||||
case .audio:
|
||||
break
|
||||
case let .video(status, _):
|
||||
switch status {
|
||||
case .recording:
|
||||
break
|
||||
case .editing:
|
||||
hideMicButton = true
|
||||
}
|
||||
case .waitingForPreview:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
self.updateActionButtons(hasText: inputHasText, hideMicButton: hideMicButton, animated: transition.isAnimated)
|
||||
|
||||
var actionButtonsSize = CGSize(width: 40.0, height: 40.0)
|
||||
if let presentationInterfaceState = self.presentationInterfaceState {
|
||||
var showTitle = false
|
||||
if !self.actionButtons.sendContainerNode.alpha.isZero {
|
||||
if let _ = presentationInterfaceState.sendPaidMessageStars {
|
||||
showTitle = true
|
||||
} else if case let .customChatContents(customChatContents) = interfaceState.subject {
|
||||
switch customChatContents.kind {
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
actionButtonsSize = self.actionButtons.updateLayout(size: CGSize(width: 40.0, height: minimalHeight), isMediaInputExpanded: isMediaInputExpanded, showTitle: showTitle, currentMessageEffectId: presentationInterfaceState.interfaceState.sendMessageEffect, transition: transition, interfaceState: presentationInterfaceState)
|
||||
}
|
||||
|
||||
let baseWidth = width - leftInset - leftMenuInset - rightInset - rightSlowModeInset
|
||||
let (accessoryButtonsWidth, textFieldHeight, isTextFieldOverflow) = self.calculateTextFieldMetrics(width: baseWidth, maxHeight: maxHeight, metrics: metrics)
|
||||
let (accessoryButtonsWidth, textFieldHeight, isTextFieldOverflow) = self.calculateTextFieldMetrics(width: baseWidth, actionControlsWidth: actionButtonsSize.width, maxHeight: maxHeight, metrics: metrics)
|
||||
var panelHeight = self.panelHeight(textFieldHeight: textFieldHeight, metrics: metrics)
|
||||
if displayBotStartButton {
|
||||
panelHeight += 27.0
|
||||
@ -1941,57 +1981,11 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
}
|
||||
self.menuButton.isUserInteractionEnabled = hasMenuButton
|
||||
self.sendAsAvatarButtonNode.isUserInteractionEnabled = hasMenuButton && isSendAsButton
|
||||
|
||||
self.actionButtons.micButton.updateMode(mode: interfaceState.interfaceState.mediaRecordingMode, animated: transition.isAnimated)
|
||||
|
||||
var hideMicButton = false
|
||||
if inputHasText || self.extendedSearchLayout {
|
||||
hideMicButton = true
|
||||
}
|
||||
if let mediaRecordingState {
|
||||
switch mediaRecordingState {
|
||||
case .audio:
|
||||
break
|
||||
case let .video(status, _):
|
||||
switch status {
|
||||
case .recording:
|
||||
break
|
||||
case .editing:
|
||||
hideMicButton = true
|
||||
}
|
||||
case .waitingForPreview:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
self.updateActionButtons(hasText: inputHasText, hideMicButton: hideMicButton, hideMicButtonBackground: mediaRecordingState != nil, animated: transition.isAnimated)
|
||||
|
||||
var actionButtonsSize = CGSize(width: 40.0, height: 40.0)
|
||||
if let presentationInterfaceState = self.presentationInterfaceState {
|
||||
var showTitle = false
|
||||
if !self.actionButtons.sendContainerNode.alpha.isZero {
|
||||
if let _ = presentationInterfaceState.sendPaidMessageStars {
|
||||
showTitle = true
|
||||
} else if case let .customChatContents(customChatContents) = interfaceState.subject {
|
||||
switch customChatContents.kind {
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
actionButtonsSize = self.actionButtons.updateLayout(size: CGSize(width: 40.0, height: minimalHeight), isMediaInputExpanded: isMediaInputExpanded, showTitle: showTitle, currentMessageEffectId: presentationInterfaceState.interfaceState.sendMessageEffect, transition: transition, interfaceState: presentationInterfaceState)
|
||||
}
|
||||
|
||||
var textFieldInsets = self.textFieldInsets(metrics: metrics)
|
||||
if actionButtonsSize.width > 40.0 {
|
||||
textFieldInsets.right = actionButtonsSize.width + 14.0
|
||||
}
|
||||
if additionalSideInsets.right > 0.0 {
|
||||
textFieldInsets.right += additionalSideInsets.right / 3.0
|
||||
}
|
||||
if self.extendedSearchLayout {
|
||||
textFieldInsets.right = 8.0
|
||||
}
|
||||
if mediaRecordingState != nil {
|
||||
textFieldInsets.left = 8.0
|
||||
}
|
||||
@ -2257,7 +2251,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
|
||||
var textInputViewRealInsets = UIEdgeInsets()
|
||||
if let presentationInterfaceState = self.presentationInterfaceState {
|
||||
textInputViewRealInsets = calculateTextFieldRealInsets(presentationInterfaceState: presentationInterfaceState, accessoryButtonsWidth: accessoryButtonsWidth)
|
||||
textInputViewRealInsets = calculateTextFieldRealInsets(presentationInterfaceState: presentationInterfaceState, accessoryButtonsWidth: accessoryButtonsWidth, actionControlsWidth: actionButtonsSize.width)
|
||||
}
|
||||
|
||||
var contentHeight: CGFloat = 0.0
|
||||
@ -2337,7 +2331,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
}
|
||||
|
||||
if let _ = interfaceState.interfaceState.mediaDraftState {
|
||||
let mediaPreviewPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: contentHeight), size: CGSize(width: textInputWidth, height: 40.0))
|
||||
let mediaPreviewPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: contentHeight), size: CGSize(width: textInputWidth - actionButtonsSize.width - 8.0, height: 40.0))
|
||||
var mediaPreviewPanelTransition = transition
|
||||
|
||||
let mediaPreviewPanelNode: ChatRecordingPreviewInputPanelNodeImpl
|
||||
@ -2497,7 +2491,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
self.slowmodePlaceholderNode?.isHidden = true
|
||||
}
|
||||
|
||||
var nextButtonTopRight = CGPoint(x: textInputContainerBackgroundFrame.width - accessoryButtonInset - rightSlowModeInset, y: textInputContainerBackgroundFrame.height - minimalInputHeight)
|
||||
var nextButtonTopRight = CGPoint(x: textInputContainerBackgroundFrame.width - accessoryButtonInset - rightSlowModeInset - actionButtonsSize.width + (inputHasText ? 4.0 : (8.0 + 1.0)), y: textInputContainerBackgroundFrame.height - minimalInputHeight)
|
||||
if self.extendedSearchLayout {
|
||||
nextButtonTopRight.x -= 26.0
|
||||
}
|
||||
@ -2662,7 +2656,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
|
||||
let searchLayoutClearButtonSize = CGSize(width: 40.0, height: 40.0)
|
||||
self.actionButtons.micButton.isHidden = additionalSideInsets.right > 0.0
|
||||
self.actionButtons.micButtonBackgroundView.isHidden = self.actionButtons.micButton.isHidden
|
||||
|
||||
let clearButtonFrame = CGRect(origin: CGPoint(x: textInputContainerBackgroundFrame.width - searchLayoutClearButtonSize.width, y: floor((textInputContainerBackgroundFrame.height - searchLayoutClearButtonSize.height) * 0.5)), size: searchLayoutClearButtonSize)
|
||||
transition.updateFrame(layer: self.searchLayoutClearButton.layer, frame: clearButtonFrame)
|
||||
@ -3383,7 +3376,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
composeButtonsOffset = 40.0
|
||||
}
|
||||
|
||||
let (_, textFieldHeight, _) = self.calculateTextFieldMetrics(width: width - leftInset - rightInset - self.leftMenuInset - self.rightSlowModeInset + self.currentTextInputBackgroundWidthOffset, maxHeight: maxHeight, metrics: metrics)
|
||||
let (_, textFieldHeight, _) = self.calculateTextFieldMetrics(width: width - leftInset - rightInset - self.leftMenuInset - self.rightSlowModeInset + self.currentTextInputBackgroundWidthOffset, actionControlsWidth: self.actionButtons.bounds.width, maxHeight: maxHeight, metrics: metrics)
|
||||
let panelHeight = self.panelHeight(textFieldHeight: textFieldHeight, metrics: metrics)
|
||||
var textFieldMinHeight: CGFloat = 33.0
|
||||
if let presentationInterfaceState = self.presentationInterfaceState {
|
||||
@ -3679,7 +3672,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
self.updateTextHeight(animated: animated)
|
||||
}
|
||||
|
||||
private func updateActionButtons(hasText: Bool, hideMicButton: Bool, hideMicButtonBackground: Bool, animated: Bool) {
|
||||
private func updateActionButtons(hasText: Bool, hideMicButton: Bool, animated: Bool) {
|
||||
var hideMicButton = hideMicButton
|
||||
|
||||
var mediaInputIsActive = false
|
||||
@ -3842,22 +3835,16 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
if !self.actionButtons.micButton.alpha.isZero {
|
||||
alphaTransition.updateAlpha(layer: self.actionButtons.micButton.layer, alpha: 0.0)
|
||||
}
|
||||
alphaTransition.updateAlpha(layer: self.actionButtons.micButtonBackgroundView.layer, alpha: 0.0)
|
||||
} else {
|
||||
alphaTransition.updateAlpha(layer: self.actionButtons.micButtonBackgroundView.layer, alpha: hideMicButtonBackground ? 0.0 : 1.0)
|
||||
let micAlpha: CGFloat = self.actionButtons.micButton.fadeDisabled ? 0.5 : 1.0
|
||||
if !self.actionButtons.micButton.alpha.isEqual(to: micAlpha) {
|
||||
self.actionButtons.micButton.alpha = micAlpha
|
||||
self.actionButtons.micButtonBackgroundView.alpha = micAlpha
|
||||
if animated {
|
||||
self.actionButtons.micButton.layer.animateAlpha(from: 0.0, to: micAlpha, duration: 0.1)
|
||||
self.actionButtons.micButtonBackgroundView.layer.animateAlpha(from: 0.0, to: micAlpha, duration: 0.1)
|
||||
if animateWithBounce {
|
||||
self.actionButtons.micButton.layer.animateSpring(from: NSNumber(value: Float(0.1)), to: NSNumber(value: Float(1.0)), keyPath: "transform.scale", duration: 0.6)
|
||||
self.actionButtons.micButtonBackgroundView.layer.animateSpring(from: NSNumber(value: Float(0.1)), to: NSNumber(value: Float(1.0)), keyPath: "transform.scale", duration: 0.6)
|
||||
} else {
|
||||
self.actionButtons.micButton.layer.animateScale(from: 0.2, to: 1.0, duration: 0.25)
|
||||
self.actionButtons.micButtonBackgroundView.layer.animateScale(from: 0.2, to: 1.0, duration: 0.25)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3889,7 +3876,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||
|
||||
private func updateTextHeight(animated: Bool) {
|
||||
if let (width, leftInset, rightInset, _, additionalSideInsets, maxHeight, _, metrics, _, _) = self.validLayout {
|
||||
let (_, textFieldHeight, _) = self.calculateTextFieldMetrics(width: width - leftInset - rightInset - additionalSideInsets.right - self.leftMenuInset - self.rightSlowModeInset + self.currentTextInputBackgroundWidthOffset, maxHeight: maxHeight, metrics: metrics)
|
||||
let (_, textFieldHeight, _) = self.calculateTextFieldMetrics(width: width - leftInset - rightInset - additionalSideInsets.right - self.leftMenuInset - self.rightSlowModeInset + self.currentTextInputBackgroundWidthOffset, actionControlsWidth: self.actionButtons.bounds.width, maxHeight: maxHeight, metrics: metrics)
|
||||
let panelHeight = self.panelHeight(textFieldHeight: textFieldHeight, metrics: metrics)
|
||||
if !self.bounds.size.height.isEqual(to: panelHeight) {
|
||||
self.updateHeight(animated)
|
||||
|
||||
@ -750,7 +750,7 @@ public final class MediaScrubberComponent: Component {
|
||||
case .editor, .cover:
|
||||
fullTrackHeight = trackHeight
|
||||
case .videoMessage, .voiceMessage:
|
||||
fullTrackHeight = 36.0
|
||||
fullTrackHeight = 34.0
|
||||
}
|
||||
let scrubberSize = CGSize(width: availableSize.width, height: fullTrackHeight)
|
||||
|
||||
@ -873,7 +873,7 @@ public final class MediaScrubberComponent: Component {
|
||||
transition.setFrame(view: self.cursorImageView, frame: CGRect(origin: .zero, size: self.cursorView.frame.size))
|
||||
|
||||
if let (coverPosition, coverImage) = component.cover {
|
||||
let imageSize = CGSize(width: 36.0, height: 36.0)
|
||||
let imageSize = CGSize(width: 34.0, height: 34.0)
|
||||
var animateFrame = false
|
||||
if previousComponent?.cover?.position != coverPosition {
|
||||
self.coverDotWrapper.isHidden = false
|
||||
@ -1135,9 +1135,9 @@ private class TrackView: UIView, UIScrollViewDelegate, UIGestureRecognizerDelega
|
||||
if case .cover = params.style {
|
||||
fullTrackHeight = trackHeight
|
||||
} else if case .voiceMessage = params.style {
|
||||
fullTrackHeight = 36.0
|
||||
fullTrackHeight = 34.0
|
||||
} else if case .videoMessage = params.style {
|
||||
fullTrackHeight = 36.0
|
||||
fullTrackHeight = 34.0
|
||||
} else {
|
||||
fullTrackHeight = 33.0
|
||||
}
|
||||
@ -1213,7 +1213,7 @@ private class TrackView: UIView, UIScrollViewDelegate, UIGestureRecognizerDelega
|
||||
framesCornerRadius = 9.0
|
||||
self.videoTransparentFramesContainer.alpha = 0.35
|
||||
case .videoMessage, .voiceMessage:
|
||||
fullTrackHeight = 36.0
|
||||
fullTrackHeight = 34.0
|
||||
framesCornerRadius = fullTrackHeight / 2.0
|
||||
self.videoTransparentFramesContainer.alpha = 0.5
|
||||
}
|
||||
|
||||
12
submodules/TelegramUI/Images.xcassets/Chat/Input/Text/SendIcon.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Input/Text/SendIcon.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "send.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
submodules/TelegramUI/Images.xcassets/Chat/Input/Text/SendIcon.imageset/send.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Chat/Input/Text/SendIcon.imageset/send.pdf
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user