diff --git a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt index 6ae724a7..dde297db 100644 --- a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt +++ b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt @@ -89,10 +89,14 @@ fun RadarDestination(navigateUp: () -> Unit) { ) == PackageManager.PERMISSION_GRANTED LaunchedEffect(hasPermission) { viewModel.onAction(RadarAction.SstvPermissionResult(hasPermission)) + viewModel.onAction(RadarAction.CwPermissionResult(hasPermission)) } val permissionLauncher = rememberLauncherForActivityResult( ActivityResultContracts.RequestPermission() - ) { granted -> viewModel.onAction(RadarAction.SstvPermissionResult(granted)) } + ) { granted -> + viewModel.onAction(RadarAction.SstvPermissionResult(granted)) + viewModel.onAction(RadarAction.CwPermissionResult(granted)) + } RadarScreen(uiState, viewModel::onAction, navigateUp, requestMicPermission = { permissionLauncher.launch(Manifest.permission.RECORD_AUDIO) }) @@ -176,7 +180,8 @@ private fun PagerCard( orbitalPos = uiState.orbitalPos, cw = uiState.cw, radioControl = uiState.radioControl, - onAction = onAction + onAction = onAction, + requestMicPermission = requestMicPermission ) RadarPage.Sstv -> SstvPage( sstv = uiState.sstv, diff --git a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarViewModel.kt b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarViewModel.kt index a0ad434d..1b2a08d2 100644 --- a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarViewModel.kt +++ b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarViewModel.kt @@ -425,6 +425,10 @@ class RadarViewModel( private fun startCwListening() { if (cwListeningJob?.isActive == true) return + if (!_uiState.value.cw.hasPermission) { + // Permission not yet granted — request it (launcher handles the result) + return + } // Stop SSTV if running (audio capture is shared) stopSstvRecording() initCwDecoder() diff --git a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/TransceiversPage.kt b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/TransceiversPage.kt index 08194fca..7c93b44c 100644 --- a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/TransceiversPage.kt +++ b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/TransceiversPage.kt @@ -86,6 +86,7 @@ fun TransceiversPage( cw: CwSubState, radioControl: RadioControlSubState, onAction: (RadarAction) -> Unit, + requestMicPermission: () -> Unit = {}, modifier: Modifier = Modifier ) { if (transceivers.isEmpty()) { @@ -112,6 +113,7 @@ fun TransceiversPage( cw = cw, radioControl = radioControl, onAction = onAction, + requestMicPermission = requestMicPermission, onToggle = { onAction(RadarAction.SelectTransmitter(radio.uuid)) } ) } @@ -150,6 +152,7 @@ private fun TransceiverItem( cw: CwSubState, radioControl: RadioControlSubState, onAction: (RadarAction) -> Unit, + requestMicPermission: () -> Unit, onToggle: () -> Unit ) { val bgColor = if (isExpanded) MaterialTheme.colorScheme.surfaceContainerHighest @@ -245,7 +248,8 @@ private fun TransceiverItem( orbitalPos = orbitalPos, cw = cw, radioControl = radioControl, - onAction = onAction + onAction = onAction, + requestMicPermission = requestMicPermission ) } @@ -317,7 +321,8 @@ private fun ExpandedRadioControl( orbitalPos: OrbitalPos?, cw: CwSubState, radioControl: RadioControlSubState, - onAction: (RadarAction) -> Unit + onAction: (RadarAction) -> Unit, + requestMicPermission: () -> Unit = {}, ) { Column( modifier = Modifier @@ -438,6 +443,7 @@ private fun ExpandedRadioControl( CwDecoderPanel( cw = cw, onAction = onAction, + requestMicPermission = requestMicPermission, modifier = Modifier.fillMaxWidth() ) } @@ -623,6 +629,7 @@ private enum class EditedField { TX, RX } private fun CwDecoderPanel( cw: CwSubState, onAction: (RadarAction) -> Unit, + requestMicPermission: () -> Unit = {}, modifier: Modifier = Modifier ) { Column( @@ -662,7 +669,13 @@ private fun CwDecoderPanel( ) { if (cw.status == CwStatus.Idle) { Button( - onClick = { onAction(RadarAction.CwStartListening) }, + onClick = { + if (!cw.hasPermission) { + requestMicPermission() + } else { + onAction(RadarAction.CwStartListening) + } + }, modifier = Modifier.weight(1f) ) { Text(stringResource(R.string.radar_cw_start))