From 003c262378bd2d3b571da7e209df8842522e0fbd Mon Sep 17 00:00:00 2001 From: senseiGai Date: Mon, 2 Mar 2026 19:56:09 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C=20?= =?UTF-8?q?=D0=BF=D0=BB=D0=B0=D0=B2=D0=BD=D1=83=D1=8E=20=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=BC=D0=B0=D1=86=D0=B8=D1=8E=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA?= =?UTF-8?q?=D0=B8=20send?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Chats/ChatDetail/ChatDetailView.swift | 72 +++++++++++++------ 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/Rosetta/Features/Chats/ChatDetail/ChatDetailView.swift b/Rosetta/Features/Chats/ChatDetail/ChatDetailView.swift index 459e673..6ef86f4 100644 --- a/Rosetta/Features/Chats/ChatDetail/ChatDetailView.swift +++ b/Rosetta/Features/Chats/ChatDetail/ChatDetailView.swift @@ -75,6 +75,17 @@ struct ChatDetailView: View { !messageText.isEmpty } + private var sendButtonProgress: CGFloat { + shouldShowSendButton ? 1 : 0 + } + + private var micButtonProgress: CGFloat { + shouldShowSendButton ? 0 : 1 + } + + private var sendButtonWidth: CGFloat { 38 } + private var sendButtonHeight: CGFloat { 36 } + private var composerHorizontalPadding: CGFloat { isInputFocused ? 16 : 28 } @@ -337,7 +348,7 @@ private extension ChatDetailView { .padding(.horizontal, 16) } - HStack(alignment: .bottom, spacing: 6) { + HStack(alignment: .bottom, spacing: shouldShowSendButton ? 0 : 6) { Button { // Placeholder for attachment picker } label: { @@ -366,7 +377,7 @@ private extension ChatDetailView { .padding(.bottom, 8) .frame(maxWidth: .infinity, minHeight: 36, alignment: .bottomLeading) - HStack(alignment: .center, spacing: 8) { + HStack(alignment: .center, spacing: 0) { Button { // Placeholder for quick actions } label: { @@ -381,10 +392,9 @@ private extension ChatDetailView { .accessibilityLabel("Quick actions") .buttonStyle(ChatDetailGlassPressButtonStyle()) } - .padding(.trailing, 8) + .padding(.trailing, 8 + (sendButtonWidth * sendButtonProgress)) .frame(height: 36, alignment: .center) - - if shouldShowSendButton { + .overlay(alignment: .trailing) { Button(action: sendCurrentMessage) { ZStack { // Mirrors the layered blend stack from the original SVG icon. @@ -431,8 +441,10 @@ private extension ChatDetailView { .blendMode(.overlay) } .compositingGroup() + .opacity(0.42 + (0.58 * sendButtonProgress)) + .scaleEffect(0.72 + (0.28 * sendButtonProgress)) .frame(width: 22, height: 19) - .frame(width: 44, height: 36) + .frame(width: sendButtonWidth, height: sendButtonHeight) .background { Capsule().fill(Color(hex: 0x008BFF)) } @@ -440,7 +452,18 @@ private extension ChatDetailView { .accessibilityLabel("Send") .disabled(!canSend) .buttonStyle(ChatDetailGlassPressButtonStyle()) - .transition(.move(edge: .trailing).combined(with: .opacity)) + .allowsHitTesting(shouldShowSendButton) + .opacity(Double(sendButtonProgress)) + .scaleEffect(0.74 + (0.26 * sendButtonProgress), anchor: .trailing) + .blur(radius: (1 - sendButtonProgress) * 2.1) + .mask( + Capsule() + .frame( + width: max(0.001, sendButtonWidth * sendButtonProgress), + height: max(0.001, sendButtonHeight * sendButtonProgress) + ) + .frame(width: sendButtonWidth, height: sendButtonHeight, alignment: .trailing) + ) } } .padding(3) @@ -451,21 +474,28 @@ private extension ChatDetailView { ) } - if !shouldShowSendButton { - Button(action: trailingAction) { - TelegramVectorIcon( - pathData: TelegramIconPath.microphone, - viewBox: CGSize(width: 18, height: 24), - color: Color.white - ) - .frame(width: 18, height: 24) - .frame(width: 42, height: 42) - .background { floatingCircleBackground(strokeOpacity: 0.18) } - } - .accessibilityLabel("Voice message") - .buttonStyle(ChatDetailGlassPressButtonStyle()) - .transition(.move(edge: .trailing).combined(with: .opacity)) + Button(action: trailingAction) { + TelegramVectorIcon( + pathData: TelegramIconPath.microphone, + viewBox: CGSize(width: 18, height: 24), + color: Color.white + ) + .frame(width: 18, height: 24) + .frame(width: 42, height: 42) + .background { floatingCircleBackground(strokeOpacity: 0.18) } } + .accessibilityLabel("Voice message") + .buttonStyle(ChatDetailGlassPressButtonStyle()) + .allowsHitTesting(!shouldShowSendButton) + .opacity(Double(micButtonProgress)) + .scaleEffect( + x: max(0.001, 0.42 + (0.58 * micButtonProgress)), + y: 0.78 + (0.22 * micButtonProgress), + anchor: .trailing + ) + .blur(radius: (1 - micButtonProgress) * 2.4) + .frame(width: 42 * micButtonProgress, height: 42, alignment: .trailing) + .clipped() } .padding(.horizontal, composerHorizontalPadding) .padding(.top, 4)