mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-18 23:05:26 +02:00
feat: Add MicrophoneDisconnectedDialog
This commit is contained in:
parent
78453f1c4d
commit
07757f34bb
@ -0,0 +1,62 @@
|
||||
package app.myzel394.alibi.ui.components.AudioRecorder.atoms
|
||||
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.MicOff
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import app.myzel394.alibi.R
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MicrophoneDisconnectedDialog(
|
||||
microphoneName: String,
|
||||
onClose: () -> Unit,
|
||||
) {
|
||||
AlertDialog(
|
||||
onDismissRequest = onClose,
|
||||
title = {
|
||||
Text(
|
||||
stringResource(
|
||||
R.string.ui_audioRecorder_error_microphoneDisconnected_title,
|
||||
),
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
stringResource(
|
||||
R.string.ui_audioRecorder_error_microphoneDisconnected_message,
|
||||
microphoneName,
|
||||
)
|
||||
)
|
||||
},
|
||||
icon = {
|
||||
Icon(
|
||||
Icons.Default.MicOff,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
val label = stringResource(R.string.dialog_close_neutral_label)
|
||||
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.semantics {
|
||||
contentDescription = label
|
||||
},
|
||||
onClick = onClose,
|
||||
) {
|
||||
Text(label)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
@ -24,11 +24,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.myzel394.alibi.ui.components.AudioRecorder.atoms.DeleteButton
|
||||
import app.myzel394.alibi.ui.components.AudioRecorder.atoms.MicrophoneDisconnectedDialog
|
||||
import app.myzel394.alibi.ui.components.AudioRecorder.atoms.PauseResumeButton
|
||||
import app.myzel394.alibi.ui.components.AudioRecorder.atoms.RealtimeAudioVisualizer
|
||||
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.effects.rememberPrevious
|
||||
import app.myzel394.alibi.ui.models.AudioRecorderModel
|
||||
import app.myzel394.alibi.ui.utils.KeepScreenOn
|
||||
import app.myzel394.alibi.ui.utils.MicrophoneInfo
|
||||
@ -137,19 +139,41 @@ fun RecordingStatus(
|
||||
|
||||
|
||||
val microphones = MicrophoneInfo.fetchDeviceMicrophones(context)
|
||||
val microphoneStatus = audioRecorder.microphoneStatus
|
||||
val previousStatus = rememberPrevious(microphoneStatus)
|
||||
|
||||
var showMicrophoneStatusDialog by remember {
|
||||
// null = no dialog
|
||||
// `MicrophoneConnectivityStatus.CONNECTED` = Reconnected dialog
|
||||
// `MicrophoneConnectivityStatus.DISCONNECTED` = Disconnected dialog
|
||||
mutableStateOf<AudioRecorderModel.MicrophoneConnectivityStatus?>(null)
|
||||
}
|
||||
|
||||
LaunchedEffect(microphoneStatus) {
|
||||
println(microphoneStatus)
|
||||
println(previousStatus)
|
||||
if (microphoneStatus != previousStatus && showMicrophoneStatusDialog == null && previousStatus != null) {
|
||||
showMicrophoneStatusDialog = microphoneStatus
|
||||
}
|
||||
}
|
||||
|
||||
if (showMicrophoneStatusDialog == AudioRecorderModel.MicrophoneConnectivityStatus.DISCONNECTED) {
|
||||
MicrophoneDisconnectedDialog(
|
||||
onClose = {
|
||||
showMicrophoneStatusDialog = null
|
||||
},
|
||||
microphoneName = audioRecorder.selectedMicrophone?.name ?: "",
|
||||
)
|
||||
}
|
||||
|
||||
if (microphones.isNotEmpty()) {
|
||||
MicrophoneSelection(
|
||||
microphones = microphones,
|
||||
selectedMicrophone = audioRecorder.selectedMicrophone,
|
||||
onSelect = {
|
||||
audioRecorder.changeMicrophone(it)
|
||||
|
||||
if (!audioRecorder.isPaused) {
|
||||
audioRecorder.recorderService!!.startNewCycle()
|
||||
}
|
||||
}
|
||||
onSelect = audioRecorder::changeMicrophone,
|
||||
)
|
||||
} else {
|
||||
Box {}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package app.myzel394.alibi.ui.effects
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.remember
|
||||
|
||||
/**
|
||||
* Returns a dummy MutableState that does not cause render when setting it
|
||||
*/
|
||||
@Composable
|
||||
private fun <T> rememberRef(): MutableState<T?> {
|
||||
// for some reason it always recreated the value with vararg keys,
|
||||
// leaving out the keys as a parameter for remember for now
|
||||
return remember() {
|
||||
object : MutableState<T?> {
|
||||
override var value: T? = null
|
||||
|
||||
override fun component1(): T? = value
|
||||
|
||||
override fun component2(): (T?) -> Unit = { value = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T> rememberPrevious(
|
||||
current: T,
|
||||
shouldUpdate: (prev: T?, curr: T) -> Boolean = { a: T?, b: T -> a != b },
|
||||
): T? {
|
||||
val ref = rememberRef<T>()
|
||||
|
||||
// launched after render, so the current render will have the old value anyway
|
||||
SideEffect {
|
||||
if (shouldUpdate(ref.value, current)) {
|
||||
ref.value = current
|
||||
}
|
||||
}
|
||||
|
||||
return ref.value
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user