Twelve: Add a data source method to do quick URI -> media type lookup

Change-Id: Ibc6669a85af75fd8a998e2441681386dce0af337
diff --git a/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt b/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt
index b2a7835..014db24 100644
--- a/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt
+++ b/app/src/main/java/org/lineageos/twelve/datasources/LocalDataSource.kt
@@ -30,6 +30,7 @@
 import org.lineageos.twelve.models.ArtistWorks
 import org.lineageos.twelve.models.Audio
 import org.lineageos.twelve.models.Genre
+import org.lineageos.twelve.models.MediaType
 import org.lineageos.twelve.models.Playlist
 import org.lineageos.twelve.models.RequestStatus
 import org.lineageos.twelve.models.Thumbnail
@@ -194,6 +195,19 @@
         mediaItemUri.toString().startsWith(it.toString())
     }
 
+    override suspend fun mediaTypeOf(mediaItemUri: Uri) = with(mediaItemUri.toString()) {
+        when {
+            startsWith(albumsUri.toString()) -> MediaType.ALBUM
+            startsWith(artistsUri.toString()) -> MediaType.ARTIST
+            startsWith(genresUri.toString()) -> MediaType.GENRE
+            startsWith(audiosUri.toString()) -> MediaType.AUDIO
+            startsWith(playlistsBaseUri.toString()) -> MediaType.PLAYLIST
+            else -> null
+        }?.let {
+            RequestStatus.Success<_, MediaError>(it)
+        } ?: RequestStatus.Error(MediaError.NOT_FOUND)
+    }
+
     override fun albums() = contentResolver.queryFlow(
         albumsUri,
         albumsProjection,
diff --git a/app/src/main/java/org/lineageos/twelve/datasources/MediaDataSource.kt b/app/src/main/java/org/lineageos/twelve/datasources/MediaDataSource.kt
index eba50ca..5fdcb70 100644
--- a/app/src/main/java/org/lineageos/twelve/datasources/MediaDataSource.kt
+++ b/app/src/main/java/org/lineageos/twelve/datasources/MediaDataSource.kt
@@ -13,6 +13,7 @@
 import org.lineageos.twelve.models.Audio
 import org.lineageos.twelve.models.Genre
 import org.lineageos.twelve.models.MediaItem
+import org.lineageos.twelve.models.MediaType
 import org.lineageos.twelve.models.Playlist
 import org.lineageos.twelve.models.RequestStatus
 
@@ -31,6 +32,14 @@
     fun isMediaItemCompatible(mediaItemUri: Uri): Boolean
 
     /**
+     * Given a compatible media item URI, get its type.
+     *
+     * @param mediaItemUri The media item to check
+     * @return [RequestStatus.Success] if success, [RequestStatus.Error] with an error otherwise
+     */
+    suspend fun mediaTypeOf(mediaItemUri: Uri): MediaRequestStatus<MediaType>
+
+    /**
      * Get all the albums. All albums must have at least one audio associated with them.
      */
     fun albums(): Flow<MediaRequestStatus<List<Album>>>
diff --git a/app/src/main/java/org/lineageos/twelve/datasources/SubsonicDataSource.kt b/app/src/main/java/org/lineageos/twelve/datasources/SubsonicDataSource.kt
index 84df2a8..8d9869c 100644
--- a/app/src/main/java/org/lineageos/twelve/datasources/SubsonicDataSource.kt
+++ b/app/src/main/java/org/lineageos/twelve/datasources/SubsonicDataSource.kt
@@ -18,12 +18,12 @@
 import org.lineageos.twelve.datasources.subsonic.models.ArtistID3
 import org.lineageos.twelve.datasources.subsonic.models.Child
 import org.lineageos.twelve.datasources.subsonic.models.Error
-import org.lineageos.twelve.datasources.subsonic.models.MediaType
 import org.lineageos.twelve.models.Album
 import org.lineageos.twelve.models.Artist
 import org.lineageos.twelve.models.ArtistWorks
 import org.lineageos.twelve.models.Audio
 import org.lineageos.twelve.models.Genre
+import org.lineageos.twelve.models.MediaType
 import org.lineageos.twelve.models.Playlist
 import org.lineageos.twelve.models.ProviderArgument
 import org.lineageos.twelve.models.ProviderArgument.Companion.requireArgument
@@ -71,6 +71,19 @@
         dataSourceBaseUri.toString()
     )
 
+    override suspend fun mediaTypeOf(mediaItemUri: Uri) = with(mediaItemUri.toString()) {
+        when {
+            startsWith(albumsUri.toString()) -> MediaType.ALBUM
+            startsWith(artistsUri.toString()) -> MediaType.ARTIST
+            startsWith(audiosUri.toString()) -> MediaType.AUDIO
+            startsWith(genresUri.toString()) -> MediaType.GENRE
+            startsWith(playlistsUri.toString()) -> MediaType.PLAYLIST
+            else -> null
+        }?.let {
+            RequestStatus.Success<_, MediaError>(it)
+        } ?: RequestStatus.Error(MediaError.NOT_FOUND)
+    }
+
     override fun albums() = suspend {
         subsonicClient.getAlbumList2("alphabeticalByName", 500).toRequestStatus {
             album.map { it.toMediaItem() }
@@ -258,11 +271,16 @@
         name = name,
     )
 
-    private fun MediaType?.toAudioType() = when (this) {
-        MediaType.MUSIC -> Audio.Type.MUSIC
-        MediaType.PODCAST -> Audio.Type.PODCAST
-        MediaType.AUDIOBOOK -> Audio.Type.AUDIOBOOK
-        MediaType.VIDEO -> throw Exception("Invalid media type, got VIDEO")
+    private fun org.lineageos.twelve.datasources.subsonic.models.MediaType?.toAudioType() = when (
+        this
+    ) {
+        org.lineageos.twelve.datasources.subsonic.models.MediaType.MUSIC -> Audio.Type.MUSIC
+        org.lineageos.twelve.datasources.subsonic.models.MediaType.PODCAST -> Audio.Type.PODCAST
+        org.lineageos.twelve.datasources.subsonic.models.MediaType.AUDIOBOOK -> Audio.Type.AUDIOBOOK
+        org.lineageos.twelve.datasources.subsonic.models.MediaType.VIDEO -> throw Exception(
+            "Invalid media type, got VIDEO"
+        )
+
         else -> Audio.Type.MUSIC
     }
 
diff --git a/app/src/main/java/org/lineageos/twelve/models/MediaType.kt b/app/src/main/java/org/lineageos/twelve/models/MediaType.kt
new file mode 100644
index 0000000..2937143
--- /dev/null
+++ b/app/src/main/java/org/lineageos/twelve/models/MediaType.kt
@@ -0,0 +1,17 @@
+/*
+ * SPDX-FileCopyrightText: 2024 The LineageOS Project
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.lineageos.twelve.models
+
+/**
+ * Media types handled by the data sources.
+ */
+enum class MediaType {
+    ALBUM,
+    ARTIST,
+    AUDIO,
+    GENRE,
+    PLAYLIST,
+}
diff --git a/app/src/main/java/org/lineageos/twelve/repositories/MediaRepository.kt b/app/src/main/java/org/lineageos/twelve/repositories/MediaRepository.kt
index 9f08828..2fa6585 100644
--- a/app/src/main/java/org/lineageos/twelve/repositories/MediaRepository.kt
+++ b/app/src/main/java/org/lineageos/twelve/repositories/MediaRepository.kt
@@ -301,6 +301,13 @@
     }
 
     /**
+     * @see MediaDataSource.mediaTypeOf
+     */
+    suspend fun mediaTypeOf(mediaItemUri: Uri) = withMediaItemsDataSource(mediaItemUri) {
+        mediaTypeOf(mediaItemUri)
+    }
+
+    /**
      * @see MediaDataSource.albums
      */
     fun albums() = navigationDataSource.flatMapLatest { it.albums() }