Use shared capture icons and menus for camera and resolution selection
This commit is contained in:
1 parent
379e7731df
commit
b84561dba5
1 file changed
+46
-9
+46
-9
@@ -41,9 +41,11 @@ import com.utun.chat.ui.components.ZoomableImage
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
enum class CaptureMode { PHOTO, VIDEO }
|
||||
private enum class CapturePhase { IDLE, CAPTURING, RECORDING, PAUSED, FINALIZING, CAPTURED, SENDING }
|
||||
private enum class CameraOption { CAMERA, RESOLUTION }
|
||||
private enum class CaptureQuality(val label: String, val quality: Quality, val bitrate: Int) {
|
||||
SD_LOW("480p 512k", Quality.SD, 512_000), SD("480p 1M", Quality.SD, 1_000_000),
|
||||
HD("720p 2M", Quality.HD, 2_000_000), FHD("1080p 4.5M", Quality.FHD, 4_500_000)
|
||||
@@ -254,6 +256,9 @@ fun CameraRecordScreen(initialMode: CaptureMode, onSend: (String, CaptureMode) -
|
||||
}
|
||||
|
||||
val idle = phase == CapturePhase.IDLE
|
||||
var menu by remember(mode, lens?.cameraId) { mutableStateOf<CameraOption?>(null) }
|
||||
LaunchedEffect(idle) { if (!idle) menu = null }
|
||||
LaunchedEffect(menu) { LogManager.addLog("DEBUG", "Capture", "Toolbar menu=$menu mode=$mode camera=${lens?.cameraId}") }
|
||||
Scaffold(topBar = {
|
||||
TopAppBar(title = {
|
||||
Row(Modifier.horizontalScroll(rememberScrollState()), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
@@ -282,15 +287,47 @@ fun CameraRecordScreen(initialMode: CaptureMode, onSend: (String, CaptureMode) -
|
||||
horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
if (idle) {
|
||||
Row(Modifier.fillMaxWidth().horizontalScroll(rememberScrollState()).padding(horizontal = 12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
lenses.forEach { item -> FilterChip(selected = lens == item, onClick = { lens = item }, label = { Text(item.label) }) }
|
||||
}
|
||||
Row(Modifier.fillMaxWidth().horizontalScroll(rememberScrollState()).padding(horizontal = 12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
if (mode == CaptureMode.PHOTO) resolutions.forEach { item ->
|
||||
FilterChip(selected = resolution == item, onClick = { resolution = item }, label = { Text(item.label) })
|
||||
} else CaptureQuality.values().forEach { item ->
|
||||
FilterChip(selected = quality == item, onClick = { quality = item }, label = { Text(item.label) })
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
Box {
|
||||
val name = lens?.let { "${it.label} ${it.mm}".trim() } ?: "—"
|
||||
CaptureControlButton(stringResource(R.string.stream_camera, name), enabled = lenses.isNotEmpty(),
|
||||
onClick = { menu = CameraOption.CAMERA }) {
|
||||
val focal = lens?.eqFocal?.takeIf { it > 0 }?.let {
|
||||
stringResource(R.string.stream_camera_focal_short, it.roundToInt())
|
||||
} ?: "—"
|
||||
CaptureValueIcon(CaptureIconShape.CAMERA, focal, front = lens?.type == LensType.SELFIE)
|
||||
}
|
||||
DropdownMenu(expanded = menu == CameraOption.CAMERA, onDismissRequest = { menu = null }) {
|
||||
lenses.forEach { item ->
|
||||
CaptureOptionItem("${item.label} ${item.mm}".trim(), lens == item, onClick = {
|
||||
menu = null; lens = item
|
||||
LogManager.addLog("INFO", "Capture", "Camera selected id=${item.cameraId} mode=$mode")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Box {
|
||||
val label = if (mode == CaptureMode.PHOTO) resolution?.label ?: "—" else quality.label
|
||||
CaptureControlButton(stringResource(R.string.stream_resolution, label),
|
||||
enabled = mode == CaptureMode.VIDEO || resolutions.isNotEmpty(), onClick = { menu = CameraOption.RESOLUTION }) {
|
||||
val value = if (mode == CaptureMode.PHOTO) resolution?.let { "${minOf(it.width, it.height)}p" } ?: "—"
|
||||
else quality.label.substringBefore(' ')
|
||||
CaptureValueIcon(CaptureIconShape.SCREEN, value,
|
||||
detail = if (mode == CaptureMode.VIDEO) quality.label.substringAfter(' ') else null)
|
||||
}
|
||||
DropdownMenu(expanded = menu == CameraOption.RESOLUTION, onDismissRequest = { menu = null }) {
|
||||
if (mode == CaptureMode.PHOTO) resolutions.forEach { item ->
|
||||
CaptureOptionItem(item.label, resolution == item, onClick = {
|
||||
menu = null; resolution = item
|
||||
LogManager.addLog("INFO", "Capture", "Photo resolution selected ${item.label}")
|
||||
})
|
||||
} else CaptureQuality.values().forEach { item ->
|
||||
CaptureOptionItem(item.label, quality == item, onClick = {
|
||||
menu = null; quality = item
|
||||
LogManager.addLog("INFO", "Capture", "Video quality selected ${item.label}")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user