feat: v3.5.0 - instant home feed, SAF display path, per-app language

- Cache home feed to SharedPreferences for instant restore on app launch
- Resolve SAF tree URIs to human-readable paths (e.g. /storage/emulated/0/Music)
- Add Android 13+ per-app language support (locale_config.xml)
- Bump version to 3.5.0+73
This commit is contained in:
zarzet
2026-02-06 21:22:00 +07:00
parent 239e073a8c
commit 5fa00c0051
8 changed files with 132 additions and 8 deletions
+2 -1
View File
@@ -21,7 +21,8 @@
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="false"
android:enableOnBackInvokedCallback="true">
android:enableOnBackInvokedCallback="true"
android:localeConfig="@xml/locale_config">
<activity
android:name=".MainActivity"
@@ -62,9 +62,37 @@ class MainActivity: FlutterFragmentActivity() {
val payload = JSONObject()
payload.put("tree_uri", uri.toString())
payload.put("display_name", resolveSafDisplayPath(uri))
result.success(payload.toString())
}
/**
* Resolve a SAF tree URI to a human-readable path.
* e.g. "content://...tree/primary%3AMusic" -> "/storage/emulated/0/Music"
* "content://...tree/1234-5678%3AMusic" -> "SD Card/Music"
*/
private fun resolveSafDisplayPath(treeUri: Uri): String {
try {
val docId = android.provider.DocumentsContract.getTreeDocumentId(treeUri)
if (docId.isNullOrEmpty()) return treeUri.toString()
val parts = docId.split(":", limit = 2)
val storageId = parts.getOrNull(0) ?: return docId
val subPath = parts.getOrNull(1) ?: ""
val prefix = if (storageId == "primary") {
"/storage/emulated/0"
} else {
"SD Card"
}
return if (subPath.isEmpty()) prefix else "$prefix/$subPath"
} catch (e: Exception) {
android.util.Log.w("SpotiFLAC", "Failed to resolve SAF display path: ${e.message}")
return treeUri.toString()
}
}
data class SafScanProgress(
var totalFiles: Int = 0,
var scannedFiles: Int = 0,
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="en" />
<locale android:name="ru" />
<locale android:name="es-ES" />
<locale android:name="id" />
<locale android:name="pt-PT" />
<locale android:name="ja" />
<locale android:name="tr" />
<locale android:name="de" />
<locale android:name="fr" />
<locale android:name="hi" />
<locale android:name="ko" />
<locale android:name="nl" />
<locale android:name="zh" />
</locale-config>