Сделать плавную анимацию кнопки send
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user