feat: gli spartiti importati restano tra gli esercizi, eliminabili

- ImportedExerciseRepository: persistenza JSON degli import (titolo dal
  nome file, note con durate/bemolli, metro; max 50, più recenti primi)
- FilePicker passa anche il nome del file (expect + 3 actual)
- PracticeSetupScreen salva la sequenza importata prima di avviare
- ExercisesScreen: sezione 'Importati' con anteprima e cestino
- fix: picker desktop su Dispatchers.Swing con finestra parent (l'import
  XML congelava l'app: dialogo Swing su thread di background)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
lucianoandClaude Fable 5 committed 2026-07-22 21:51:45 +02:00
1 parent f48a327a33
commit 3a95a3d433
12 files changed
+293 -31

No files matched your search

@@ -10,7 +10,7 @@ import com.notemusicali.scores.extractMusicXmlFromBytes
@Composable
actual fun rememberFilePickerLauncher(
mimeTypes: List<String>,
onFileContent: (String) -> Unit,
onFileContent: (fileName: String, content: String) -> Unit,
): () -> Unit {
val context = LocalContext.current
val launcher = rememberLauncherForActivityResult(
@@ -22,7 +22,7 @@ actual fun rememberFilePickerLauncher(
val bytes = stream.readBytes()
val content = extractMusicXmlFromBytes(bytes)
if (content != null) {
onFileContent(content)
onFileContent(displayNameOf(context, it), content)
}
}
} catch (_: Exception) {
@@ -33,3 +33,14 @@ actual fun rememberFilePickerLauncher(
return { launcher.launch(mimeTypes.toTypedArray()) }
}
private fun displayNameOf(context: android.content.Context, uri: Uri): String {
return try {
context.contentResolver.query(uri, null, null, null, null)?.use { cursor ->
val idx = cursor.getColumnIndex(android.provider.OpenableColumns.DISPLAY_NAME)
if (idx >= 0 && cursor.moveToFirst()) cursor.getString(idx) else null
} ?: (uri.lastPathSegment ?: "Import")
} catch (_: Exception) {
uri.lastPathSegment ?: "Import"
}
}