Telegram-like composer: voice/circle toggle and unified attach actions
This commit is contained in:
@@ -82,6 +82,7 @@ import androidx.compose.animation.core.tween
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@@ -590,7 +591,9 @@ private fun ChatScreen(
|
||||
var showDeleteDialog by remember { mutableStateOf(false) }
|
||||
var showInlineSearch by remember { mutableStateOf(false) }
|
||||
var showEmojiPicker by remember { mutableStateOf(false) }
|
||||
var showAttachmentSheet by remember { mutableStateOf(false) }
|
||||
var emojiPickerTab by remember { mutableStateOf(ComposerPickerTab.Emoji) }
|
||||
var useCircleRecording by rememberSaveable(state.chatId) { mutableStateOf(false) }
|
||||
var gifSearchQuery by remember { mutableStateOf("") }
|
||||
var giphySearchItems by remember { mutableStateOf<List<RemotePickerItem>>(emptyList()) }
|
||||
var isGiphyLoading by remember { mutableStateOf(false) }
|
||||
@@ -605,6 +608,7 @@ private fun ChatScreen(
|
||||
val actionSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
val forwardSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
val chatInfoSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
val attachmentSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
val isTabletLayout = LocalConfiguration.current.screenWidthDp >= 840
|
||||
val adaptiveHorizontalPadding = if (isTabletLayout) 72.dp else 0.dp
|
||||
val chatInfoEntries = remember(state.messages, context) { buildChatInfoEntries(state.messages, context) }
|
||||
@@ -1769,40 +1773,7 @@ private fun ChatScreen(
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.14f),
|
||||
) {
|
||||
IconButton(
|
||||
onClick = onCapturePhoto,
|
||||
enabled = state.canSendMessages && !state.isUploadingMedia && !state.isRecordingVoice,
|
||||
) {
|
||||
Icon(imageVector = Icons.Filled.AddAPhoto, contentDescription = "Capture photo")
|
||||
}
|
||||
}
|
||||
Surface(
|
||||
shape = CircleShape,
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.14f),
|
||||
) {
|
||||
IconButton(
|
||||
onClick = onCaptureVideo,
|
||||
enabled = state.canSendMessages && !state.isUploadingMedia && !state.isRecordingVoice,
|
||||
) {
|
||||
Icon(imageVector = Icons.Filled.Movie, contentDescription = "Capture video")
|
||||
}
|
||||
}
|
||||
Surface(
|
||||
shape = CircleShape,
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.14f),
|
||||
) {
|
||||
IconButton(
|
||||
onClick = onCaptureCircleVideo,
|
||||
enabled = state.canSendMessages && !state.isUploadingMedia && !state.isRecordingVoice,
|
||||
) {
|
||||
Icon(imageVector = Icons.Filled.RadioButtonChecked, contentDescription = "Record circle video")
|
||||
}
|
||||
}
|
||||
Surface(
|
||||
shape = CircleShape,
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.14f),
|
||||
) {
|
||||
IconButton(
|
||||
onClick = onPickMedia,
|
||||
onClick = { showAttachmentSheet = true },
|
||||
enabled = state.canSendMessages && !state.isUploadingMedia && !state.isRecordingVoice,
|
||||
) {
|
||||
if (state.isUploadingMedia) {
|
||||
@@ -1812,6 +1783,28 @@ private fun ChatScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
Surface(
|
||||
shape = CircleShape,
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.14f),
|
||||
) {
|
||||
IconButton(
|
||||
onClick = { useCircleRecording = !useCircleRecording },
|
||||
enabled = state.canSendMessages && !state.isUploadingMedia && !state.isRecordingVoice,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = if (useCircleRecording) {
|
||||
Icons.Filled.RadioButtonChecked
|
||||
} else {
|
||||
Icons.Filled.Mic
|
||||
},
|
||||
contentDescription = if (useCircleRecording) {
|
||||
"Circle mode enabled"
|
||||
} else {
|
||||
"Voice mode enabled"
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
val canSend = state.canSendMessages &&
|
||||
!state.isSending &&
|
||||
!state.isUploadingMedia &&
|
||||
@@ -1828,6 +1821,21 @@ private fun ChatScreen(
|
||||
Icon(imageVector = Icons.AutoMirrored.Filled.Send, contentDescription = "Send")
|
||||
}
|
||||
}
|
||||
} else if (useCircleRecording) {
|
||||
Surface(
|
||||
shape = CircleShape,
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.18f),
|
||||
) {
|
||||
IconButton(
|
||||
onClick = onCaptureCircleVideo,
|
||||
enabled = state.canSendMessages && !state.isUploadingMedia,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.RadioButtonChecked,
|
||||
contentDescription = "Record circle video",
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
VoiceHoldToRecordButton(
|
||||
enabled = state.canSendMessages && !state.isUploadingMedia,
|
||||
@@ -1843,6 +1851,89 @@ private fun ChatScreen(
|
||||
}
|
||||
}
|
||||
|
||||
if (showAttachmentSheet) {
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = { showAttachmentSheet = false },
|
||||
sheetState = attachmentSheetState,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.chat_attachment_title),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
)
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.clickable {
|
||||
showAttachmentSheet = false
|
||||
onPickMedia()
|
||||
},
|
||||
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.35f),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 12.dp, vertical = 10.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Icon(imageVector = Icons.Filled.AttachFile, contentDescription = null)
|
||||
Text(stringResource(id = R.string.chat_attachment_gallery_file))
|
||||
}
|
||||
}
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.clickable {
|
||||
showAttachmentSheet = false
|
||||
onCapturePhoto()
|
||||
},
|
||||
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.35f),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 12.dp, vertical = 10.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Icon(imageVector = Icons.Filled.AddAPhoto, contentDescription = null)
|
||||
Text(stringResource(id = R.string.chat_attachment_take_photo))
|
||||
}
|
||||
}
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.clickable {
|
||||
showAttachmentSheet = false
|
||||
onCaptureVideo()
|
||||
},
|
||||
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.35f),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 12.dp, vertical = 10.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Icon(imageVector = Icons.Filled.Movie, contentDescription = null)
|
||||
Text(stringResource(id = R.string.chat_attachment_take_video))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!state.errorMessage.isNullOrBlank()) {
|
||||
Text(
|
||||
text = state.errorMessage,
|
||||
|
||||
@@ -147,6 +147,10 @@
|
||||
<string name="chat_member_action_kick">Кикнуть</string>
|
||||
<string name="chat_member_action_unban">Разбанить</string>
|
||||
<string name="chat_media_badge_video">Видео</string>
|
||||
<string name="chat_attachment_title">Вложение</string>
|
||||
<string name="chat_attachment_gallery_file">Галерея / Файл</string>
|
||||
<string name="chat_attachment_take_photo">Сделать фото</string>
|
||||
<string name="chat_attachment_take_video">Снять видео</string>
|
||||
<string name="chat_media_badge_gif">GIF</string>
|
||||
<string name="chat_media_badge_sticker">Стикер</string>
|
||||
<string name="chat_picker_tab_emoji">Эмодзи</string>
|
||||
|
||||
@@ -147,6 +147,10 @@
|
||||
<string name="chat_member_action_kick">Kick</string>
|
||||
<string name="chat_member_action_unban">Unban</string>
|
||||
<string name="chat_media_badge_video">Video</string>
|
||||
<string name="chat_attachment_title">Attachment</string>
|
||||
<string name="chat_attachment_gallery_file">Gallery / File</string>
|
||||
<string name="chat_attachment_take_photo">Take photo</string>
|
||||
<string name="chat_attachment_take_video">Record video</string>
|
||||
<string name="chat_media_badge_gif">GIF</string>
|
||||
<string name="chat_media_badge_sticker">Sticker</string>
|
||||
<string name="chat_picker_tab_emoji">Emoji</string>
|
||||
|
||||
Reference in New Issue
Block a user