Fix continue recording

This commit is contained in:
Isaac 2025-09-26 23:55:04 +08:00
parent aa890a14f5
commit d2f471bd35
3 changed files with 47 additions and 19 deletions

View File

@ -14,7 +14,7 @@ public final class ChatRecordingViewOnceButtonNode: HighlightTrackingButtonNode
private let icon: Icon private let icon: Icon
private let backgroundView: GlassBackgroundView private let backgroundView: GlassBackgroundView
private let iconNode: ASImageNode private let iconView: UIImageView
private var theme: PresentationTheme? private var theme: PresentationTheme?
@ -24,13 +24,12 @@ public final class ChatRecordingViewOnceButtonNode: HighlightTrackingButtonNode
self.backgroundView = GlassBackgroundView() self.backgroundView = GlassBackgroundView()
self.backgroundView.isUserInteractionEnabled = false self.backgroundView.isUserInteractionEnabled = false
self.iconNode = ASImageNode() self.iconView = UIImageView()
self.iconNode.isUserInteractionEnabled = false
super.init(pointerStyle: .default) super.init(pointerStyle: .default)
self.view.addSubview(self.backgroundView) self.view.addSubview(self.backgroundView)
self.addSubnode(self.iconNode) self.view.addSubview(self.iconView)
self.highligthedChanged = { [weak self] highlighted in self.highligthedChanged = { [weak self] highlighted in
if let self, self.bounds.width > 0.0 { if let self, self.bounds.width > 0.0 {
@ -63,21 +62,15 @@ public final class ChatRecordingViewOnceButtonNode: HighlightTrackingButtonNode
return return
} }
let updated = self.iconNode.image == nil || self.innerIsSelected != isSelected let updated = self.iconView.image == nil || self.innerIsSelected != isSelected
self.innerIsSelected = isSelected self.innerIsSelected = isSelected
if animated, updated && self.iconNode.image != nil, let snapshot = self.iconNode.view.snapshotContentTree() { self.iconView.tintColor = theme.chat.inputPanel.panelControlColor
self.view.addSubview(snapshot) self.iconView.setMonochromaticEffect(tintColor: self.iconView.tintColor)
snapshot.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in
snapshot.removeFromSuperview()
})
self.iconNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
}
if updated { if updated {
if case .viewOnce = self.icon { if case .viewOnce = self.icon {
self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: self.innerIsSelected ? "Media Gallery/ViewOnceEnabled" : "Media Gallery/ViewOnce"), color: theme.chat.inputPanel.panelControlAccentColor) self.iconView.image = generateTintedImage(image: UIImage(bundleImageName: self.innerIsSelected ? "Media Gallery/ViewOnceEnabled" : "Media Gallery/ViewOnce"), color: .white)?.withRenderingMode(.alwaysTemplate)
} }
} }
} }
@ -91,9 +84,9 @@ public final class ChatRecordingViewOnceButtonNode: HighlightTrackingButtonNode
switch self.icon { switch self.icon {
case .viewOnce: case .viewOnce:
self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: self.innerIsSelected ? "Media Gallery/ViewOnceEnabled" : "Media Gallery/ViewOnce"), color: theme.chat.inputPanel.panelControlAccentColor) self.iconView.image = generateTintedImage(image: UIImage(bundleImageName: self.innerIsSelected ? "Media Gallery/ViewOnceEnabled" : "Media Gallery/ViewOnce"), color: .white)?.withRenderingMode(.alwaysTemplate)
case .recordMore: case .recordMore:
self.iconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconMicrophone"), color: theme.chat.inputPanel.panelControlAccentColor) self.iconView.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Text/IconMicrophone"), color: .white)?.withRenderingMode(.alwaysTemplate)
} }
} }
@ -101,9 +94,9 @@ public final class ChatRecordingViewOnceButtonNode: HighlightTrackingButtonNode
self.backgroundView.frame = backgroundFrame self.backgroundView.frame = backgroundFrame
self.backgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.height * 0.5, isDark: theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: .immediate) self.backgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.height * 0.5, isDark: theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: .immediate)
if let iconImage = self.iconNode.image { if let iconImage = self.iconView.image {
let iconFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(size.width / 2.0 - iconImage.size.width / 2.0), y: floorToScreenPixels(size.height / 2.0 - iconImage.size.height / 2.0)), size: iconImage.size) let iconFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(size.width / 2.0 - iconImage.size.width / 2.0), y: floorToScreenPixels(size.height / 2.0 - iconImage.size.height / 2.0)), size: iconImage.size)
self.iconNode.frame = iconFrame self.iconView.frame = iconFrame
} }
return size return size
} }

View File

@ -265,6 +265,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
public var viewOnce = false public var viewOnce = false
public let viewOnceButton: ChatRecordingViewOnceButtonNode public let viewOnceButton: ChatRecordingViewOnceButtonNode
public let recordMoreButton: ChatRecordingViewOnceButtonNode
private var accessoryPanel: (component: AnyComponentWithIdentity<ChatInputAccessoryPanelEnvironment>, view: ComponentView<ChatInputAccessoryPanelEnvironment>)? private var accessoryPanel: (component: AnyComponentWithIdentity<ChatInputAccessoryPanelEnvironment>, view: ComponentView<ChatInputAccessoryPanelEnvironment>)?
private var contextPanel: (container: UIView, mask: UIImageView, panel: ChatInputContextPanelNode)? private var contextPanel: (container: UIView, mask: UIImageView, panel: ChatInputContextPanelNode)?
@ -569,6 +570,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
self.slowModeButton.alpha = 0.0 self.slowModeButton.alpha = 0.0
self.viewOnceButton = ChatRecordingViewOnceButtonNode(icon: .viewOnce) self.viewOnceButton = ChatRecordingViewOnceButtonNode(icon: .viewOnce)
self.recordMoreButton = ChatRecordingViewOnceButtonNode(icon: .recordMore)
super.init() super.init()
@ -842,6 +844,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
} }
self.viewOnceButton.addTarget(self, action: #selector(self.viewOncePressed), forControlEvents: [.touchUpInside]) self.viewOnceButton.addTarget(self, action: #selector(self.viewOncePressed), forControlEvents: [.touchUpInside])
self.recordMoreButton.addTarget(self, action: #selector(self.recordMorePressed), forControlEvents: [.touchUpInside])
self.addSubnode(self.recordMoreButton)
} }
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {
@ -2722,6 +2727,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
self.actionButtons.micButton.fadeDisabled = mediaInputDisabled self.actionButtons.micButton.fadeDisabled = mediaInputDisabled
var viewOnceIsVisible = false var viewOnceIsVisible = false
var recordMoreIsVisible = false
if let recordingState = interfaceState.inputTextPanelState.mediaRecordingState { if let recordingState = interfaceState.inputTextPanelState.mediaRecordingState {
if case let .audio(_, isLocked) = recordingState { if case let .audio(_, isLocked) = recordingState {
viewOnceIsVisible = isLocked viewOnceIsVisible = isLocked
@ -2729,6 +2735,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
viewOnceIsVisible = isLocked viewOnceIsVisible = isLocked
} }
} }
if interfaceState.interfaceState.mediaDraftState != nil {
recordMoreIsVisible = true
}
var clippingDelta: CGFloat = 0.0 var clippingDelta: CGFloat = 0.0
if case let .media(_, _, focused) = interfaceState.inputMode, focused { if case let .media(_, _, focused) = interfaceState.inputMode, focused {
@ -2745,6 +2754,19 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
if self.viewOnceButton.alpha.isZero && viewOnceIsVisible { if self.viewOnceButton.alpha.isZero && viewOnceIsVisible {
self.viewOnceButton.update(isSelected: self.viewOnce, animated: false) self.viewOnceButton.update(isSelected: self.viewOnce, animated: false)
} }
let recordMoreSize = self.recordMoreButton.update(theme: interfaceState.theme)
let recordMoreButtonFrame = CGRect(origin: CGPoint(x: width - rightInset - 50.0 - UIScreenPixel, y: -52.0), size: recordMoreSize)
self.recordMoreButton.bounds = CGRect(origin: .zero, size: recordMoreButtonFrame.size)
transition.updatePosition(node: self.recordMoreButton, position: recordMoreButtonFrame.center)
if self.viewOnceButton.alpha.isZero && viewOnceIsVisible {
self.viewOnceButton.update(isSelected: self.viewOnce, animated: false)
}
if self.recordMoreButton.alpha.isZero && recordMoreIsVisible {
self.recordMoreButton.update(isSelected: false, animated: false)
}
transition.updateAlpha(node: self.viewOnceButton, alpha: viewOnceIsVisible ? 1.0 : 0.0) transition.updateAlpha(node: self.viewOnceButton, alpha: viewOnceIsVisible ? 1.0 : 0.0)
transition.updateTransformScale(node: self.viewOnceButton, scale: viewOnceIsVisible ? 1.0 : 0.01) transition.updateTransformScale(node: self.viewOnceButton, scale: viewOnceIsVisible ? 1.0 : 0.01)
if let user = interfaceState.renderedPeer?.peer as? TelegramUser, user.id != interfaceState.accountPeerId && user.botInfo == nil && interfaceState.sendPaidMessageStars == nil { if let user = interfaceState.renderedPeer?.peer as? TelegramUser, user.id != interfaceState.accountPeerId && user.botInfo == nil && interfaceState.sendPaidMessageStars == nil {
@ -2753,6 +2775,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
self.viewOnceButton.isHidden = true self.viewOnceButton.isHidden = true
} }
transition.updateAlpha(node: self.recordMoreButton, alpha: recordMoreIsVisible ? 1.0 : 0.0)
transition.updateTransformScale(node: self.recordMoreButton, scale: recordMoreIsVisible ? 1.0 : 0.01)
if contextPanelNode !== previousContextPanel?.panel, let previousContextPanel { if contextPanelNode !== previousContextPanel?.panel, let previousContextPanel {
let panelContainer = previousContextPanel.container let panelContainer = previousContextPanel.container
previousContextPanel.panel.animateOut(completion: { [weak panelContainer] in previousContextPanel.panel.animateOut(completion: { [weak panelContainer] in
@ -2826,6 +2851,10 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
} }
} }
@objc private func recordMorePressed() {
self.interfaceInteraction?.resumeMediaRecording()
}
private func displayViewOnceTooltip(text: String) { private func displayViewOnceTooltip(text: String) {
guard let context = self.context, let parentController = self.interfaceInteraction?.chatController() else { guard let context = self.context, let parentController = self.interfaceInteraction?.chatController() else {
return return
@ -4628,6 +4657,12 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
} }
} }
if !self.recordMoreButton.isHidden && self.recordMoreButton.alpha > 0.0 {
if let result = self.recordMoreButton.view.hitTest(self.view.convert(point, to: self.recordMoreButton.view), with: event) {
return result
}
}
if self.bounds.contains(point), let textInputNode = self.textInputNode, let currentEmojiSuggestion = self.currentEmojiSuggestion, let currentEmojiSuggestionView = self.currentEmojiSuggestionView { if self.bounds.contains(point), let textInputNode = self.textInputNode, let currentEmojiSuggestion = self.currentEmojiSuggestion, let currentEmojiSuggestionView = self.currentEmojiSuggestionView {
if let result = currentEmojiSuggestionView.hitTest(self.view.convert(point, to: currentEmojiSuggestionView), with: event) { if let result = currentEmojiSuggestionView.hitTest(self.view.convert(point, to: currentEmojiSuggestionView), with: event) {
return result return result

View File

@ -608,7 +608,7 @@ extension ChatControllerImpl {
} }
} }
let location = CGRect(origin: CGPoint(x: screenWidth - layout.safeInsets.right - 42.0 - UIScreenPixel, y: layout.size.height - insets.bottom - 122.0), size: CGSize()) let location = CGRect(origin: CGPoint(x: screenWidth - layout.safeInsets.right - 50.0, y: layout.size.height - insets.bottom - 128.0), size: CGSize())
let tooltipController = TooltipScreen( let tooltipController = TooltipScreen(
account: self.context.account, account: self.context.account,