From 7630aa6874b3d4e824c378eee74a851354558f41 Mon Sep 17 00:00:00 2001 From: k1ngsterr1 Date: Sun, 12 Apr 2026 00:15:09 +0500 Subject: [PATCH] =?UTF-8?q?fix:=20LOCKED=20UI=20=D0=BA=D0=B0=D0=BA=20?= =?UTF-8?q?=D0=B2=20Telegram=20=E2=80=94=20CANCEL=20=D1=82=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D1=82=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20=E2=9C=95?= =?UTF-8?q?,=20=D0=B1=D0=B5=D0=B7=20blob=20=D0=BF=D1=80=D0=B8=20lock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Telegram LOCKED layout: [timer] [waveform] [CANCEL] [⏸] [Send] Изменения: - RecordLockedControls: убрана круглая ✕ кнопка delete - Вместо неё: текст "CANCEL" синим bold 15sp (как в Telegram) - Пауза иконка увеличена 12→14dp, фон 15% alpha - Blob анимация скрыта при LOCKED/PAUSED (Telegram: solid circle) - Spacing 8→12dp между CANCEL и паузой Co-Authored-By: Claude Opus 4.6 (1M context) --- .../ui/chats/input/ChatDetailInput.kt | 89 ++++++++++--------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt b/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt index c31b1eb..2037640 100644 --- a/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt +++ b/app/src/main/java/com/rosetta/messenger/ui/chats/input/ChatDetailInput.kt @@ -781,6 +781,17 @@ private fun VoiceWaveformBar( } } +/** + * Telegram-exact locked recording controls. + * + * Layout: [CANCEL text-button] [⏸/▶ circle button] + * + * - CANCEL = blue text (15sp bold, uppercase), clickable — cancels recording + * - ⏸ = small circle button (36dp), toggles pause/resume + * - No separate delete icon — CANCEL IS delete + * + * Reference: ChatActivityEnterView recordedAudioPanel + SlideTextView cancelToProgress + */ @Composable private fun RecordLockedControls( isPaused: Boolean, @@ -789,37 +800,31 @@ private fun RecordLockedControls( onTogglePause: () -> Unit, modifier: Modifier = Modifier ) { - val deleteBgColor = if (isDarkTheme) Color(0xFF444444) else Color(0xFFE0E0E0) - val deleteIconColor = if (isDarkTheme) Color.White.copy(alpha = 0.8f) else Color(0xFF666666) - val pauseBgColor = if (isDarkTheme) Color(0xFF69CCFF).copy(alpha = 0.3f) else Color(0xFF2D9CFF).copy(alpha = 0.2f) + val cancelColor = if (isDarkTheme) Color(0xFF69CCFF) else Color(0xFF2D9CFF) + val pauseBgColor = if (isDarkTheme) Color(0xFF69CCFF).copy(alpha = 0.15f) else Color(0xFF2D9CFF).copy(alpha = 0.1f) val pauseIconColor = if (isDarkTheme) Color(0xFF69CCFF) else Color(0xFF2D9CFF) Row( modifier = modifier, verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp) + horizontalArrangement = Arrangement.spacedBy(12.dp) ) { - // Delete button - Box( + // CANCEL text button — Telegram: blue bold uppercase + Text( + text = "CANCEL", + color = cancelColor, + fontSize = 15.sp, + fontWeight = FontWeight.Bold, + maxLines = 1, modifier = Modifier - .size(36.dp) - .clip(CircleShape) - .background(deleteBgColor) .clickable( interactionSource = remember { MutableInteractionSource() }, indication = null - ) { onDelete() }, - contentAlignment = Alignment.Center - ) { - Icon( - imageVector = Icons.Default.Close, - contentDescription = "Delete recording", - tint = deleteIconColor, - modifier = Modifier.size(18.dp) - ) - } + ) { onDelete() } + .padding(horizontal = 4.dp, vertical = 8.dp) + ) - // Pause/Resume button + // Pause/Resume button — circle with icon Box( modifier = Modifier .size(36.dp) @@ -832,7 +837,8 @@ private fun RecordLockedControls( contentAlignment = Alignment.Center ) { if (isPaused) { - Canvas(modifier = Modifier.size(12.dp)) { + // Play triangle + Canvas(modifier = Modifier.size(14.dp)) { val path = Path().apply { moveTo(size.width * 0.2f, 0f) lineTo(size.width, size.height / 2f) @@ -842,19 +848,20 @@ private fun RecordLockedControls( drawPath(path, color = pauseIconColor) } } else { - Canvas(modifier = Modifier.size(12.dp)) { - val barW = size.width * 0.25f - val gap = size.width * 0.15f + // Pause bars + Canvas(modifier = Modifier.size(14.dp)) { + val barW = size.width * 0.22f + val gap = size.width * 0.14f drawRoundRect( color = pauseIconColor, - topLeft = Offset(size.width / 2f - gap - barW, 0f), - size = androidx.compose.ui.geometry.Size(barW, size.height), + topLeft = Offset(size.width / 2f - gap - barW, size.height * 0.1f), + size = androidx.compose.ui.geometry.Size(barW, size.height * 0.8f), cornerRadius = androidx.compose.ui.geometry.CornerRadius(barW / 3f) ) drawRoundRect( color = pauseIconColor, - topLeft = Offset(size.width / 2f + gap, 0f), - size = androidx.compose.ui.geometry.Size(barW, size.height), + topLeft = Offset(size.width / 2f + gap, size.height * 0.1f), + size = androidx.compose.ui.geometry.Size(barW, size.height * 0.8f), cornerRadius = androidx.compose.ui.geometry.CornerRadius(barW / 3f) ) } @@ -2240,18 +2247,20 @@ fun MessageInputBar( } } - // Blob: 48dp base → 1.7x = ~82dp visual (matches Telegram circleRadius 41dp) - VoiceButtonBlob( - voiceLevel = voiceLevel, - isDarkTheme = isDarkTheme, - modifier = Modifier - .size(48.dp) - .graphicsLayer { - scaleX = 1.7f - scaleY = 1.7f - clip = false - } - ) + // Blob: only during RECORDING (Telegram hides waves when locked) + if (recordUiState == RecordUiState.RECORDING) { + VoiceButtonBlob( + voiceLevel = voiceLevel, + isDarkTheme = isDarkTheme, + modifier = Modifier + .size(48.dp) + .graphicsLayer { + scaleX = 1.7f + scaleY = 1.7f + clip = false + } + ) + } // Solid circle: 48dp layout, scaled to 82dp visual val sendScale by animateFloatAsState(