Desktop: move folder path + Choose-folder into Settings

Library header keeps only wordmark/Settings plus the auto-transcribe
and Transcribe-all controls. Settings gains a 'Recordings folder'
section (full path + Change folder…) at the top; the empty library now
shows a card that jumps straight to Settings.
This commit is contained in:
avi 2026-09-15 10:15:28 -05:00
commit 757595aaed

View file

@ -193,7 +193,6 @@ fun LibraryScreen(state: DesktopState) {
val hits by state.searchResults.collectAsState() val hits by state.searchResults.collectAsState()
val connected by state.connected.collectAsState() val connected by state.connected.collectAsState()
var renaming by remember { mutableStateOf<File?>(null) } var renaming by remember { mutableStateOf<File?>(null) }
var showPicker by remember { mutableStateOf(false) }
var deleting by remember { mutableStateOf<File?>(null) } var deleting by remember { mutableStateOf<File?>(null) }
var deletingMany by remember { mutableStateOf(false) } var deletingMany by remember { mutableStateOf(false) }
var deleteNotice by remember { mutableStateOf<String?>(null) } var deleteNotice by remember { mutableStateOf<String?>(null) }
@ -223,14 +222,7 @@ fun LibraryScreen(state: DesktopState) {
} }
} }
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
Text(folder?.absolutePath ?: "No folder chosen", Spacer(Modifier.weight(1f))
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.weight(1f))
Spacer(Modifier.width(8.dp))
OutlinedButton({ showPicker = true }) {
Text("Choose folder…")
}
Spacer(Modifier.width(8.dp))
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
val auto = state.autoTranscribe.collectAsState().value val auto = state.autoTranscribe.collectAsState().value
Checkbox(auto, { state.setAutoTranscribe(it) }) Checkbox(auto, { state.setAutoTranscribe(it) })
@ -332,8 +324,16 @@ fun LibraryScreen(state: DesktopState) {
} }
} }
} else if (folder == null) { } else if (folder == null) {
Text("Pick the folder with your .m4a recordings to begin.", Card(Modifier.fillMaxWidth()) {
color = MaterialTheme.colorScheme.onSurfaceVariant) Row(Modifier.fillMaxWidth().padding(12.dp),
verticalAlignment = Alignment.CenterVertically) {
Text("No folder chosen — pick one in Settings.",
modifier = Modifier.weight(1f))
Button({ state.go(DesktopState.Screen.SETTINGS) }) {
Text("Open Settings")
}
}
}
} else if (entries.isEmpty()) { } else if (entries.isEmpty()) {
Text("No audio files in this folder.", Text("No audio files in this folder.",
color = MaterialTheme.colorScheme.onSurfaceVariant) color = MaterialTheme.colorScheme.onSurfaceVariant)
@ -430,16 +430,6 @@ fun LibraryScreen(state: DesktopState) {
} }
} }
if (showPicker) {
FolderPickerDialog(
startDir = folder ?: File(System.getProperty("user.home")),
onResult = { picked ->
showPicker = false
picked?.let { state.pickFolder(it) }
},
)
}
renaming?.let { target -> renaming?.let { target ->
var text by remember(target) { mutableStateOf(target.nameWithoutExtension) } var text by remember(target) { mutableStateOf(target.nameWithoutExtension) }
var error by remember(target) { mutableStateOf<String?>(null) } var error by remember(target) { mutableStateOf<String?>(null) }
@ -856,6 +846,8 @@ fun SettingsScreen(state: DesktopState) {
val models = state.models.collectAsState().value val models = state.models.collectAsState().value
val modelsError = state.modelsError.collectAsState().value val modelsError = state.modelsError.collectAsState().value
val url by state.serverUrl.collectAsState() val url by state.serverUrl.collectAsState()
val folder by state.folder.collectAsState()
var showPicker by remember { mutableStateOf(false) }
Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(12.dp)) { Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.spacedBy(12.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
@ -863,6 +855,18 @@ fun SettingsScreen(state: DesktopState) {
Text("Settings", style = MaterialTheme.typography.headlineSmall) Text("Settings", style = MaterialTheme.typography.headlineSmall)
} }
Text("Local engine: $url", style = MaterialTheme.typography.bodySmall) Text("Local engine: $url", style = MaterialTheme.typography.bodySmall)
Text("Recordings folder", style = MaterialTheme.typography.titleMedium)
Row(verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Text(folder?.absolutePath ?: "No folder chosen",
style = MaterialTheme.typography.bodySmall,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.weight(1f))
OutlinedButton({ showPicker = true }) {
Text(if (folder == null) "Choose folder…" else "Change folder…")
}
}
Spacer(Modifier.height(4.dp)) Spacer(Modifier.height(4.dp))
Text("Default transcription model", style = MaterialTheme.typography.titleMedium) Text("Default transcription model", style = MaterialTheme.typography.titleMedium)
Text("Applies to future transcriptions. Each recording keeps the model it used.", Text("Applies to future transcriptions. Each recording keeps the model it used.",
@ -912,5 +916,15 @@ fun SettingsScreen(state: DesktopState) {
} }
} }
modelsError?.let { Text(it, color = MaterialTheme.colorScheme.error) } modelsError?.let { Text(it, color = MaterialTheme.colorScheme.error) }
if (showPicker) {
FolderPickerDialog(
startDir = folder ?: File(System.getProperty("user.home")),
onResult = { picked ->
showPicker = false
picked?.let { state.pickFolder(it) }
},
)
}
} }
} }