diff --git a/app/src/main/java/org/oxycblt/auxio/music/locations/LocationAdapter.kt b/app/src/main/java/org/oxycblt/auxio/music/locations/LocationAdapter.kt
index 7fd41ebef..2db1873b9 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/locations/LocationAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/locations/LocationAdapter.kt
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+
package org.oxycblt.auxio.music.locations
import android.net.Uri
@@ -27,6 +27,7 @@ import org.oxycblt.auxio.list.recycler.DialogRecyclerView
import org.oxycblt.musikr.fs.Path
import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.inflater
+import org.oxycblt.musikr.fs.MusicLocation
import timber.log.Timber as L
/**
@@ -93,8 +94,6 @@ class LocationAdapter(private val listener: Listener) : RecyclerView.Adapter(), LocationAdapter.Listener {
private val locationAdapter = LocationAdapter(this)
private var openDocumentTreeLauncher: ActivityResultLauncher? = null
- @Inject lateinit var documentPathFactory: DocumentPathFactory
+ @Inject lateinit var musicLocationFactory: MusicLocation.Factory
@Inject lateinit var musicSettings: MusicSettings
override fun onCreateBinding(inflater: LayoutInflater) =
@@ -76,17 +76,7 @@ class MusicSourcesDialog :
) {
openDocumentTreeLauncher =
registerForActivityResult(
- object : ActivityResultContracts.OpenDocumentTree() {
- override fun createIntent(context: Context, input: Uri?): Intent {
- return super.createIntent(context, input).apply {
- flags =
- Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or
- Intent.FLAG_GRANT_READ_URI_PERMISSION or
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION or
- Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
- }
- }
- },
+ ActivityResultContracts.OpenDocumentTree(),
::addDocumentTreeUriToDirs)
binding.locationsAdd.apply {
@@ -117,8 +107,7 @@ class MusicSourcesDialog :
?: musicSettings.musicLocations
val locations =
locationUris.mapNotNull {
- MusicLocation(
- it, documentPathFactory.unpackDocumentTreeUri(it) ?: return@mapNotNull null)
+ musicLocationFactory.create(it)
}
locationAdapter.addAll(locations)
@@ -160,10 +149,10 @@ class MusicSourcesDialog :
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
contentResolver.takePersistableUriPermission(uri, takeFlags)
- val path = documentPathFactory.unpackDocumentTreeUri(uri)
+ val location = musicLocationFactory.create(uri)
- if (path != null) {
- locationAdapter.add(MusicLocation(uri, path))
+ if (location != null) {
+ locationAdapter.add(location)
requireBinding().locationsEmpty.isVisible = false
} else {
requireContext().showToast(R.string.err_bad_location)
diff --git a/app/src/main/java/org/oxycblt/musikr/Indexer.kt b/app/src/main/java/org/oxycblt/musikr/Indexer.kt
index e6773a01c..426354602 100644
--- a/app/src/main/java/org/oxycblt/musikr/Indexer.kt
+++ b/app/src/main/java/org/oxycblt/musikr/Indexer.kt
@@ -26,6 +26,7 @@ import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
+import org.oxycblt.musikr.fs.MusicLocation
import org.oxycblt.musikr.model.MutableLibrary
import org.oxycblt.musikr.pipeline.EvaluateStep
import org.oxycblt.musikr.pipeline.ExploreStep
@@ -34,7 +35,7 @@ import org.oxycblt.musikr.tag.Interpretation
interface Indexer {
suspend fun run(
- uris: List,
+ locations: MusicLocation,
interpretation: Interpretation,
onProgress: suspend (IndexingProgress) -> Unit = {}
): MutableLibrary
@@ -59,7 +60,7 @@ constructor(
private val evaluateStep: EvaluateStep
) : Indexer {
override suspend fun run(
- uris: List,
+ locations: MusicLocation,
interpretation: Interpretation,
onProgress: suspend (IndexingProgress) -> Unit
) = coroutineScope {
diff --git a/app/src/main/java/org/oxycblt/musikr/fs/DeviceFiles.kt b/app/src/main/java/org/oxycblt/musikr/fs/DeviceFiles.kt
index da9d81ffc..da769f7b8 100644
--- a/app/src/main/java/org/oxycblt/musikr/fs/DeviceFiles.kt
+++ b/app/src/main/java/org/oxycblt/musikr/fs/DeviceFiles.kt
@@ -35,7 +35,7 @@ import org.oxycblt.musikr.fs.path.DocumentPathFactory
import timber.log.Timber
interface DeviceFiles {
- fun explore(uris: Flow): Flow
+ fun explore(locations: Flow): Flow
}
data class DeviceFile(
@@ -50,19 +50,17 @@ data class DeviceFile(
class DeviceFilesImpl
@Inject
constructor(
- @ApplicationContext private val context: Context,
- private val documentPathFactory: DocumentPathFactory
+ @ApplicationContext private val context: Context
) : DeviceFiles {
private val contentResolver = context.contentResolverSafe
- override fun explore(uris: Flow): Flow =
- uris.flatMapMerge { rootUri ->
- Timber.d("$rootUri")
+ override fun explore(locations: Flow): Flow =
+ locations.flatMapMerge { location ->
exploreImpl(
contentResolver,
- rootUri,
- DocumentsContract.getTreeDocumentId(rootUri),
- requireNotNull(documentPathFactory.unpackDocumentTreeUri(rootUri)))
+ location.uri,
+ DocumentsContract.getTreeDocumentId(location.uri),
+ location.path)
}
private fun exploreImpl(
diff --git a/app/src/main/java/org/oxycblt/musikr/fs/FsModule.kt b/app/src/main/java/org/oxycblt/musikr/fs/FsModule.kt
index 658c9f9a3..ff7ea4841 100644
--- a/app/src/main/java/org/oxycblt/musikr/fs/FsModule.kt
+++ b/app/src/main/java/org/oxycblt/musikr/fs/FsModule.kt
@@ -56,4 +56,6 @@ interface FsBindsModule {
fun documentPathFactory(documentTreePathFactory: DocumentPathFactoryImpl): DocumentPathFactory
@Binds fun deviceFiles(deviceFilesImpl: DeviceFilesImpl): DeviceFiles
+
+ @Binds fun musicLocationFactory(musicLocationFactoryImpl: MusicLocationFactoryImpl): MusicLocation.Factory
}
diff --git a/app/src/main/java/org/oxycblt/musikr/fs/MusicLocation.kt b/app/src/main/java/org/oxycblt/musikr/fs/MusicLocation.kt
new file mode 100644
index 000000000..90541d8f1
--- /dev/null
+++ b/app/src/main/java/org/oxycblt/musikr/fs/MusicLocation.kt
@@ -0,0 +1,36 @@
+package org.oxycblt.musikr.fs
+
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.provider.DocumentsContract
+import dagger.hilt.android.qualifiers.ApplicationContext
+import org.oxycblt.musikr.fs.path.DocumentPathFactory
+import javax.inject.Inject
+
+class MusicLocation internal constructor(val uri: Uri, val path: Path) {
+ override fun equals(other: Any?) =
+ other is MusicLocation && uri == other.uri && path == other.path
+
+ override fun hashCode() = 31 * uri.hashCode() + path.hashCode()
+ override fun toString() = "src:$uri=$path"
+
+ interface Factory {
+ fun create(uri: Uri): MusicLocation?
+ }
+}
+
+class MusicLocationFactoryImpl @Inject constructor(
+ @ApplicationContext private val context: Context,
+ private val documentPathFactory: DocumentPathFactory
+) : MusicLocation.Factory {
+ override fun create(uri: Uri): MusicLocation? {
+ check(DocumentsContract.isTreeUri(uri)) { "URI $uri is not a document tree URI" }
+ val path = documentPathFactory.unpackDocumentTreeUri(uri) ?: return null
+ context.contentResolverSafe.takePersistableUriPermission(
+ uri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ )
+ return MusicLocation(uri, path)
+ }
+}
\ No newline at end of file