From 76e10a15122fd68826cdc33d18bd1a1f7e708b11 Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Sun, 22 Oct 2023 00:23:02 +0200 Subject: [PATCH] refactor: Move microphone related stuff to MicrophoneStatus --- .../molecules/MicrophoneSelection.kt | 111 +++++++++++++----- .../molecules/MicrophoneStatus.kt | 61 ++++++++++ .../organisms/RecordingStatus.kt | 57 +-------- app/src/main/res/values/strings.xml | 1 + 4 files changed, 148 insertions(+), 82 deletions(-) create mode 100644 app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/molecules/MicrophoneStatus.kt diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/molecules/MicrophoneSelection.kt b/app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/molecules/MicrophoneSelection.kt index 4530d82..e401c34 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/molecules/MicrophoneSelection.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/molecules/MicrophoneSelection.kt @@ -3,6 +3,7 @@ package app.myzel394.alibi.ui.components.AudioRecorder.molecules import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -13,22 +14,27 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Divider import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.Text import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import app.myzel394.alibi.R +import app.myzel394.alibi.dataStore +import app.myzel394.alibi.db.AppSettings import app.myzel394.alibi.ui.components.AudioRecorder.atoms.MicrophoneSelectionButton import app.myzel394.alibi.ui.components.AudioRecorder.atoms.MicrophoneTypeInfo import app.myzel394.alibi.ui.models.AudioRecorderModel @@ -37,15 +43,26 @@ import app.myzel394.alibi.ui.utils.MicrophoneInfo @OptIn(ExperimentalMaterial3Api::class) @Composable fun MicrophoneSelection( - microphones: List, - selectedMicrophone: MicrophoneInfo?, - onSelect: (MicrophoneInfo?) -> Unit, + audioRecorder: AudioRecorderModel ) { + val context = LocalContext.current + var showSelection by rememberSaveable { mutableStateOf(false) } val sheetState = rememberModalBottomSheetState() + val allMicrophones = MicrophoneInfo.fetchDeviceMicrophones(context) + val visibleMicrophones = MicrophoneInfo.filterMicrophones(allMicrophones) + val hiddenMicrophones = allMicrophones - visibleMicrophones.toSet() + + val dataStore = LocalContext.current.dataStore + val settings = dataStore + .data + .collectAsState(initial = AppSettings.getDefaultInstance()) + .value + + if (showSelection) { ModalBottomSheet( onDismissRequest = { @@ -73,26 +90,64 @@ fun MicrophoneSelection( ) { item { MicrophoneSelectionButton( - selected = selectedMicrophone == null, + selected = audioRecorder.selectedMicrophone == null, onSelect = { - onSelect(null) + audioRecorder.changeMicrophone(null) showSelection = false } ) } - items(microphones.size) { - val microphone = microphones[it] + items(visibleMicrophones.size) { + val microphone = visibleMicrophones[it] MicrophoneSelectionButton( microphone = microphone, - selected = selectedMicrophone == microphone, + selected = audioRecorder.selectedMicrophone == microphone, onSelect = { - onSelect(microphone) + audioRecorder.changeMicrophone(microphone) showSelection = false } ) } + + if (settings.audioRecorderSettings.showAllMicrophones) { + item { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier.padding(vertical = 32.dp), + ) { + Divider( + modifier = Modifier + .weight(1f) + ) + Text( + stringResource(R.string.ui_audioRecorder_info_microphone_hiddenMicrophones), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.tertiary, + textAlign = TextAlign.Center, + ) + Divider( + modifier = Modifier + .weight(1f), + ) + } + } + + items(hiddenMicrophones.size) { + val microphone = hiddenMicrophones[it] + + MicrophoneSelectionButton( + microphone = microphone, + selected = audioRecorder.selectedMicrophone == microphone, + onSelect = { + audioRecorder.changeMicrophone(microphone) + showSelection = false + } + ) + } + } } } } @@ -101,23 +156,25 @@ fun MicrophoneSelection( Box {} } - Button( - onClick = { - showSelection = true - }, - colors = ButtonDefaults.textButtonColors(), - ) { - MicrophoneTypeInfo( - type = selectedMicrophone?.type - ?: MicrophoneInfo.MicrophoneType.PHONE, - modifier = Modifier.size(ButtonDefaults.IconSize), - ) - Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing)) - Text( - text = selectedMicrophone.let { - it?.name - ?: stringResource(R.string.ui_audioRecorder_info_microphone_deviceMicrophone) - } - ) + if (visibleMicrophones.isNotEmpty() || (settings.audioRecorderSettings.showAllMicrophones && hiddenMicrophones.isNotEmpty())) { + Button( + onClick = { + showSelection = true + }, + colors = ButtonDefaults.textButtonColors(), + ) { + MicrophoneTypeInfo( + type = audioRecorder.selectedMicrophone?.type + ?: MicrophoneInfo.MicrophoneType.PHONE, + modifier = Modifier.size(ButtonDefaults.IconSize), + ) + Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing)) + Text( + text = audioRecorder.selectedMicrophone.let { + it?.name + ?: stringResource(R.string.ui_audioRecorder_info_microphone_deviceMicrophone) + } + ) + } } } \ No newline at end of file diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/molecules/MicrophoneStatus.kt b/app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/molecules/MicrophoneStatus.kt new file mode 100644 index 0000000..b18c339 --- /dev/null +++ b/app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/molecules/MicrophoneStatus.kt @@ -0,0 +1,61 @@ +package app.myzel394.alibi.ui.components.AudioRecorder.molecules + +import androidx.compose.foundation.layout.Box +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.LocalContext +import app.myzel394.alibi.dataStore +import app.myzel394.alibi.db.AppSettings +import app.myzel394.alibi.ui.components.AudioRecorder.atoms.MicrophoneDisconnectedDialog +import app.myzel394.alibi.ui.components.AudioRecorder.atoms.MicrophoneReconnectedDialog +import app.myzel394.alibi.ui.effects.rememberPrevious +import app.myzel394.alibi.ui.models.AudioRecorderModel +import app.myzel394.alibi.ui.utils.MicrophoneInfo + +@Composable +fun MicrophoneStatus( + audioRecorder: AudioRecorderModel, +) { + val microphoneStatus = audioRecorder.microphoneStatus + val previousStatus = rememberPrevious(microphoneStatus) + + var showMicrophoneStatusDialog by remember { + // null = no dialog + // `MicrophoneConnectivityStatus.CONNECTED` = Reconnected dialog + // `MicrophoneConnectivityStatus.DISCONNECTED` = Disconnected dialog + mutableStateOf(null) + } + + LaunchedEffect(microphoneStatus) { + if (microphoneStatus != previousStatus && showMicrophoneStatusDialog == null && previousStatus != null) { + showMicrophoneStatusDialog = microphoneStatus + } + } + + if (showMicrophoneStatusDialog == AudioRecorderModel.MicrophoneConnectivityStatus.DISCONNECTED) { + MicrophoneDisconnectedDialog( + onClose = { + showMicrophoneStatusDialog = null + }, + microphoneName = audioRecorder.selectedMicrophone?.name ?: "", + ) + } + + if (showMicrophoneStatusDialog == AudioRecorderModel.MicrophoneConnectivityStatus.CONNECTED) { + MicrophoneReconnectedDialog( + onClose = { + showMicrophoneStatusDialog = null + }, + microphoneName = audioRecorder.selectedMicrophone?.name ?: "", + ) + } + + MicrophoneSelection( + audioRecorder = audioRecorder, + ) +} \ No newline at end of file diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/organisms/RecordingStatus.kt b/app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/organisms/RecordingStatus.kt index c395f39..ba4d330 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/organisms/RecordingStatus.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/AudioRecorder/organisms/RecordingStatus.kt @@ -34,6 +34,7 @@ import app.myzel394.alibi.ui.components.AudioRecorder.atoms.RealtimeAudioVisuali import app.myzel394.alibi.ui.components.AudioRecorder.atoms.RecordingTime import app.myzel394.alibi.ui.components.AudioRecorder.atoms.SaveButton import app.myzel394.alibi.ui.components.AudioRecorder.molecules.MicrophoneSelection +import app.myzel394.alibi.ui.components.AudioRecorder.molecules.MicrophoneStatus import app.myzel394.alibi.ui.effects.rememberPrevious import app.myzel394.alibi.ui.models.AudioRecorderModel import app.myzel394.alibi.ui.utils.KeepScreenOn @@ -141,60 +142,6 @@ fun RecordingStatus( } } - val dataStore = LocalContext.current.dataStore - val settings = dataStore - .data - .collectAsState(initial = AppSettings.getDefaultInstance()) - .value - val microphones = MicrophoneInfo.fetchDeviceMicrophones(context).let { - if (settings.audioRecorderSettings.showAllMicrophones) { - it - } else { - MicrophoneInfo.filterMicrophones(it) - } - } - val microphoneStatus = audioRecorder.microphoneStatus - val previousStatus = rememberPrevious(microphoneStatus) - - var showMicrophoneStatusDialog by remember { - // null = no dialog - // `MicrophoneConnectivityStatus.CONNECTED` = Reconnected dialog - // `MicrophoneConnectivityStatus.DISCONNECTED` = Disconnected dialog - mutableStateOf(null) - } - - LaunchedEffect(microphoneStatus) { - if (microphoneStatus != previousStatus && showMicrophoneStatusDialog == null && previousStatus != null) { - showMicrophoneStatusDialog = microphoneStatus - } - } - - if (showMicrophoneStatusDialog == AudioRecorderModel.MicrophoneConnectivityStatus.DISCONNECTED) { - MicrophoneDisconnectedDialog( - onClose = { - showMicrophoneStatusDialog = null - }, - microphoneName = audioRecorder.selectedMicrophone?.name ?: "", - ) - } - - if (showMicrophoneStatusDialog == AudioRecorderModel.MicrophoneConnectivityStatus.CONNECTED) { - MicrophoneReconnectedDialog( - onClose = { - showMicrophoneStatusDialog = null - }, - microphoneName = audioRecorder.selectedMicrophone?.name ?: "", - ) - } - - if (microphones.isNotEmpty()) { - MicrophoneSelection( - microphones = microphones, - selectedMicrophone = audioRecorder.selectedMicrophone, - onSelect = audioRecorder::changeMicrophone, - ) - } else { - Box {} - } + MicrophoneStatus(audioRecorder) } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c56fa4f..8a45393 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -71,4 +71,5 @@ %s reconnected! Alibi automatically changed the microphone input to it. Show hidden microphones Show all microphones, including internal ones + Hidden Microphones \ No newline at end of file