From 16b981651a9024652eebb1dbfa44f48bbcf667f3 Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Fri, 19 Sep 2025 17:51:11 +0400 Subject: [PATCH] Various improvements --- .../ChatRecordingPreviewInputPanelNode.swift | 10 +-- .../Sources/ChatTextInputPanelNode.swift | 3 - .../Sources/MediaScrubberComponent.swift | 8 +- .../Components/VideoMessageCameraScreen/BUILD | 1 + .../Sources/VideoMessageCameraScreen.swift | 80 ++++++++++++++----- 5 files changed, 68 insertions(+), 34 deletions(-) diff --git a/submodules/TelegramUI/Components/Chat/ChatRecordingPreviewInputPanelNode/Sources/ChatRecordingPreviewInputPanelNode.swift b/submodules/TelegramUI/Components/Chat/ChatRecordingPreviewInputPanelNode/Sources/ChatRecordingPreviewInputPanelNode.swift index 43e999f5ea..68021514cc 100644 --- a/submodules/TelegramUI/Components/Chat/ChatRecordingPreviewInputPanelNode/Sources/ChatRecordingPreviewInputPanelNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatRecordingPreviewInputPanelNode/Sources/ChatRecordingPreviewInputPanelNode.swift @@ -388,8 +388,6 @@ 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 innerSize = CGSize(width: 40.0, height: 40.0) - 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)) if self.presentationInterfaceState != interfaceState { @@ -558,22 +556,18 @@ public final class ChatRecordingPreviewInputPanelNodeImpl: ChatInputPanelNode { ), environment: {}, forceUpdate: false, - containerSize: CGSize(width: min(424.0, width - leftInset - rightInset - innerSize.width - 1.0), height: 40.0) + containerSize: CGSize(width: waveformBackgroundFrame.width, height: 44.0) ) if let view = self.scrubber.view { if view.superview == nil { self.view.addSubview(view) } - view.bounds = CGRect(origin: .zero, size: scrubberSize) + view.frame = CGRect(origin: CGPoint(x: 2.0, y: 2.0), size: scrubberSize) } } } } - - if let view = self.scrubber.view { - view.frame = CGRect(origin: CGPoint(x: min(width - innerSize.width - view.bounds.width, max(leftInset + 45.0, floorToScreenPixels((width - view.bounds.width) / 2.0))), y: 7.0 - UIScreenPixel), size: view.bounds.size) - } let panelHeight = 40.0 diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift index 1100f5cdf7..8ec19b92aa 100644 --- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift @@ -466,7 +466,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg private var spoilersRevealed = false private var animatingTransition = false - public var finishedTransitionToPreview: Bool? private var touchDownGestureRecognizer: TouchDownGestureRecognizer? @@ -2188,8 +2187,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg audioRecordingCancelIndicator.layer.animateAlpha(from: CGFloat(audioRecordingCancelIndicator.layer.presentation()?.opacity ?? 1), to: 0, duration: 0.15, delay: 0, removeOnCompletion: false) } } else if self.audioRecordingInfoContainerNode != nil { - self.finishedTransitionToPreview = nil - self.actionButtons.micButton.audioRecorder = nil self.actionButtons.micButton.videoRecordingStatus = nil transition.updateAlpha(layer: self.textInputBackgroundNode.layer, alpha: 1.0) diff --git a/submodules/TelegramUI/Components/MediaScrubberComponent/Sources/MediaScrubberComponent.swift b/submodules/TelegramUI/Components/MediaScrubberComponent/Sources/MediaScrubberComponent.swift index 95ac4f04d2..44066b9a0c 100644 --- a/submodules/TelegramUI/Components/MediaScrubberComponent/Sources/MediaScrubberComponent.swift +++ b/submodules/TelegramUI/Components/MediaScrubberComponent/Sources/MediaScrubberComponent.swift @@ -750,7 +750,7 @@ public final class MediaScrubberComponent: Component { case .editor, .cover: fullTrackHeight = trackHeight case .videoMessage, .voiceMessage: - fullTrackHeight = 33.0 + fullTrackHeight = 36.0 } let scrubberSize = CGSize(width: availableSize.width, height: fullTrackHeight) @@ -1134,6 +1134,10 @@ private class TrackView: UIView, UIScrollViewDelegate, UIGestureRecognizerDelega let fullTrackHeight: CGFloat if case .cover = params.style { fullTrackHeight = trackHeight + } else if case .voiceMessage = params.style { + fullTrackHeight = 36.0 + } else if case .videoMessage = params.style { + fullTrackHeight = 36.0 } else { fullTrackHeight = 33.0 } @@ -1209,7 +1213,7 @@ private class TrackView: UIView, UIScrollViewDelegate, UIGestureRecognizerDelega framesCornerRadius = 9.0 self.videoTransparentFramesContainer.alpha = 0.35 case .videoMessage, .voiceMessage: - fullTrackHeight = 33.0 + fullTrackHeight = 36.0 framesCornerRadius = fullTrackHeight / 2.0 self.videoTransparentFramesContainer.alpha = 0.5 } diff --git a/submodules/TelegramUI/Components/VideoMessageCameraScreen/BUILD b/submodules/TelegramUI/Components/VideoMessageCameraScreen/BUILD index d39746aa69..3a2073718b 100644 --- a/submodules/TelegramUI/Components/VideoMessageCameraScreen/BUILD +++ b/submodules/TelegramUI/Components/VideoMessageCameraScreen/BUILD @@ -42,6 +42,7 @@ swift_library( "//submodules/ChatSendMessageActionUI", "//submodules/TelegramUI/Components/ChatControllerInteraction", "//submodules/TelegramUI/Components/LottieComponent", + "//submodules/TelegramUI/Components/GlassBackgroundComponent", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/VideoMessageCameraScreen/Sources/VideoMessageCameraScreen.swift b/submodules/TelegramUI/Components/VideoMessageCameraScreen/Sources/VideoMessageCameraScreen.swift index 3e97459e39..43d2ec4578 100644 --- a/submodules/TelegramUI/Components/VideoMessageCameraScreen/Sources/VideoMessageCameraScreen.swift +++ b/submodules/TelegramUI/Components/VideoMessageCameraScreen/Sources/VideoMessageCameraScreen.swift @@ -30,6 +30,7 @@ import TelegramAudio import ChatSendMessageActionUI import ChatControllerInteraction import LottieComponent +import GlassBackgroundComponent struct CameraState: Equatable { enum Recording: Equatable { @@ -116,6 +117,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { let context: AccountContext let cameraState: CameraState + let containerSize: CGSize let previewFrame: CGRect let isPreviewing: Bool let isMuted: Bool @@ -131,6 +133,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { init( context: AccountContext, cameraState: CameraState, + containerSize: CGSize, previewFrame: CGRect, isPreviewing: Bool, isMuted: Bool, @@ -145,6 +148,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { ) { self.context = context self.cameraState = cameraState + self.containerSize = containerSize self.previewFrame = previewFrame self.isPreviewing = isPreviewing self.isMuted = isMuted @@ -168,6 +172,9 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { if lhs.cameraState != rhs.cameraState { return false } + if lhs.containerSize != rhs.containerSize { + return false + } if lhs.isPreviewing != rhs.isPreviewing { return false } @@ -505,7 +512,9 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { static var body: Body { let frontFlash = Child(Image.self) + let flipButtonBackground = Child(GlassBackgroundComponent.self) let flipButton = Child(CameraButton.self) + let flashButtonBackground = Child(GlassBackgroundComponent.self) let flashButton = Child(CameraButton.self) let viewOnceButton = Child(PlainButtonComponent.self) @@ -519,7 +528,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { let environment = context.environment[ViewControllerComponentContainer.Environment.self].value let component = context.component let state = context.state - let availableSize = context.availableSize + let availableSize = context.component.containerSize state.cameraState = component.cameraState @@ -558,11 +567,12 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { if case .on = component.cameraState.flashMode, case .front = component.cameraState.position { let frontFlash = frontFlash.update( component: Image(image: state.image(.flashImage, theme: environment.theme), tintColor: component.cameraState.flashTint.color), - availableSize: availableSize, + availableSize: context.availableSize, transition: .easeInOut(duration: 0.2) ) + let frontFlashFrame = CGRect(origin: CGPoint(), size: context.availableSize) context.add(frontFlash - .position(CGPoint(x: context.availableSize.width / 2.0, y: context.availableSize.height / 2.0)) + .position(frontFlashFrame.center) .scale(1.5 - component.cameraState.flashTintSize * 0.5) .appear(.default(alpha: true)) .disappear(ComponentTransition.Disappear({ view, transition, completion in @@ -574,6 +584,15 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { ) } + let flipButtonBackground = flipButtonBackground.update( + component: GlassBackgroundComponent( + size: CGSize(width: 40.0, height: 40.0), + tintColor: .init(kind: .panel, color: environment.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)) + ), + availableSize: CGSize(width: 40.0, height: 40.0), + transition: .immediate + ) + let flipButton = flipButton.update( component: CameraButton( content: AnyComponentWithIdentity( @@ -581,12 +600,12 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { component: AnyComponent( Image( image: state.image(.flip, theme: environment.theme), - tintColor: environment.theme.list.itemAccentColor, + tintColor: environment.theme.chat.inputPanel.inputControlColor, size: CGSize(width: 30.0, height: 30.0) ) ) ), - minSize: CGSize(width: 44.0, height: 44.0), + minSize: CGSize(width: 40.0, height: 40.0), isExclusive: false, action: { [weak state] in if let state { @@ -597,6 +616,12 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { availableSize: availableSize, transition: context.transition ) + + context.add(flipButtonBackground + .position(CGPoint(x: flipButton.size.width / 2.0 + 8.0, y: availableSize.height - flipButton.size.height / 2.0 - 8.0)) + .appear(.default(scale: true, alpha: true)) + .disappear(.default(scale: true, alpha: true)) + ) context.add(flipButton .position(CGPoint(x: flipButton.size.width / 2.0 + 8.0, y: availableSize.height - flipButton.size.height / 2.0 - 8.0)) .appear(.default(scale: true, alpha: true)) @@ -620,7 +645,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { component: AnyComponent( LottieComponent( content: LottieComponent.AppBundleContent(name: flashIconName), - color: environment.theme.list.itemAccentColor, + color: environment.theme.chat.inputPanel.inputControlColor, startingPosition: !component.cameraState.flashModeDidChange ? .end : .begin, size: CGSize(width: 40.0, height: 40.0), loop: false, @@ -634,7 +659,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { component: AnyComponent( Image( image: state.image(.flash, theme: environment.theme), - tintColor: environment.theme.list.itemAccentColor, + tintColor: environment.theme.chat.inputPanel.inputControlColor, size: CGSize(width: 30.0, height: 30.0) ) ) @@ -645,7 +670,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { let flashButton = flashButton.update( component: CameraButton( content: flashContentComponent, - minSize: CGSize(width: 44.0, height: 44.0), + minSize: CGSize(width: 40.0, height: 40.0), isExclusive: false, action: { [weak state] in if let state { @@ -659,6 +684,22 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { availableSize: availableSize, transition: context.transition ) + + let flashButtonBackground = flashButtonBackground.update( + component: GlassBackgroundComponent( + size: CGSize(width: 40.0, height: 40.0), + tintColor: .init(kind: .panel, color: environment.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)) + ), + availableSize: CGSize(width: 40.0, height: 40.0), + transition: .immediate + ) + + context.add(flashButtonBackground + .position(CGPoint(x: flipButton.size.width + 8.0 + flashButton.size.width / 2.0 + 11.0, y: availableSize.height - flashButton.size.height / 2.0 - 8.0)) + .appear(.default(scale: true, alpha: true)) + .disappear(.default(scale: true, alpha: true)) + ) + context.add(flashButton .position(CGPoint(x: flipButton.size.width + 8.0 + flashButton.size.width / 2.0 + 11.0, y: availableSize.height - flashButton.size.height / 2.0 - 8.0)) .appear(.default(scale: true, alpha: true)) @@ -686,7 +727,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { component: AnyComponent( BundleIconComponent( name: component.cameraState.isViewOnceEnabled ? "Media Gallery/ViewOnceEnabled" : "Media Gallery/ViewOnce", - tintColor: environment.theme.list.itemAccentColor + tintColor: environment.theme.chat.inputPanel.inputControlColor ) ) ) @@ -718,19 +759,17 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { ZStack([ AnyComponentWithIdentity( id: "background", - component: AnyComponent( - Image( - image: state.image(.buttonBackground, theme: environment.theme), - size: CGSize(width: 40.0, height: 40.0) - ) - ) + component: AnyComponent(GlassBackgroundComponent( + size: CGSize(width: 40.0, height: 40.0), + tintColor: .init(kind: .panel, color: environment.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)) + )) ), AnyComponentWithIdentity( id: "icon", component: AnyComponent( BundleIconComponent( name: "Chat/Input/Text/IconVideo", - tintColor: environment.theme.list.itemAccentColor + tintColor: environment.theme.chat.inputPanel.inputControlColor ) ) ) @@ -745,7 +784,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { transition: context.transition ) context.add(recordMoreButton - .position(CGPoint(x: availableSize.width - recordMoreButton.size.width / 2.0 - 2.0 - UIScreenPixel, y: availableSize.height - recordMoreButton.size.height / 2.0 - 22.0)) + .position(CGPoint(x: availableSize.width - recordMoreButton.size.width / 2.0 - 8.0, y: availableSize.height - recordMoreButton.size.height / 2.0 - 22.0)) .appear(.default(scale: true, alpha: true)) .disappear(.default(scale: true, alpha: true)) ) @@ -780,7 +819,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent { ) } - return availableSize + return context.availableSize } } } @@ -880,7 +919,6 @@ public class VideoMessageCameraScreen: ViewController { self.backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: self.presentationData.theme.overallDarkAppearance ? .dark : .light)) self.containerView = UIView() - self.containerView.clipsToBounds = true self.componentHost = ComponentView() @@ -1502,6 +1540,7 @@ public class VideoMessageCameraScreen: ViewController { VideoMessageCameraScreenComponent( context: self.context, cameraState: self.cameraState, + containerSize: backgroundFrame.size, previewFrame: previewFrame, isPreviewing: self.previewState != nil || self.transitioningToPreview, isMuted: self.previewState?.isMuted ?? true, @@ -1525,12 +1564,11 @@ public class VideoMessageCameraScreen: ViewController { environment }, forceUpdate: forceUpdate, - containerSize: backgroundFrame.size + containerSize: actualBackgroundFrame.size ) if let componentView = self.componentHost.view { if componentView.superview == nil { self.containerView.addSubview(componentView) - componentView.clipsToBounds = true } let componentFrame = CGRect(origin: .zero, size: componentSize)