diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt index 56047aa1d..24b69eff9 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt @@ -470,7 +470,8 @@ class HomeFragment : when (decision) { is PlaylistDecision.New -> { logD("Creating new playlist") - HomeFragmentDirections.newPlaylist(decision.songs.map { it.uid }.toTypedArray()) + HomeFragmentDirections.newPlaylist( + decision.songs.map { it.uid }.toTypedArray(), decision.reason) } is PlaylistDecision.Import -> { logD("Importing playlist") diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt index 175959225..589d9a496 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicViewModel.kt @@ -34,6 +34,7 @@ import org.oxycblt.auxio.music.external.ExternalPlaylistManager import org.oxycblt.auxio.util.Event import org.oxycblt.auxio.util.MutableEvent import org.oxycblt.auxio.util.logD +import org.oxycblt.auxio.util.logE /** * A [ViewModel] providing data specific to the music loading process. @@ -114,17 +115,29 @@ constructor( * * @param name The name of the new [Playlist]. If null, the user will be prompted for one. * @param songs The [Song]s to be contained in the new playlist. + * @param reason The reason why a new playlist is being created. For all intensive purposes, you + * do not need to specify this. */ - fun createPlaylist(name: String? = null, songs: List = listOf()) { + fun createPlaylist( + name: String? = null, + songs: List = listOf(), + reason: PlaylistDecision.New.Reason = PlaylistDecision.New.Reason.NEW + ) { if (name != null) { logD("Creating $name with ${songs.size} songs]") viewModelScope.launch(Dispatchers.IO) { musicRepository.createPlaylist(name, songs) - _playlistMessage.put(PlaylistMessage.NewPlaylistSuccess) + val message = + when (reason) { + PlaylistDecision.New.Reason.NEW -> PlaylistMessage.NewPlaylistSuccess + PlaylistDecision.New.Reason.ADD -> PlaylistMessage.AddSuccess + PlaylistDecision.New.Reason.IMPORT -> PlaylistMessage.ImportSuccess + } + _playlistMessage.put(message) } } else { logD("Launching creation dialog for ${songs.size} songs") - _playlistDecision.put(PlaylistDecision.New(songs)) + _playlistDecision.put(PlaylistDecision.New(songs, reason)) } } @@ -142,6 +155,7 @@ constructor( viewModelScope.launch(Dispatchers.IO) { val importedPlaylist = externalPlaylistManager.import(uri) if (importedPlaylist == null) { + logE("Could not import playlist") _playlistMessage.put(PlaylistMessage.ImportFailed) return@launch } @@ -150,6 +164,7 @@ constructor( val songs = importedPlaylist.paths.mapNotNull(deviceLibrary::findSongByPath) if (songs.isEmpty()) { + logE("No songs found") _playlistMessage.put(PlaylistMessage.ImportFailed) return@launch } @@ -160,7 +175,7 @@ constructor( _playlistMessage.put(PlaylistMessage.ImportSuccess) } else { // TODO: Have to properly propagate the "Playlist Created" message - createPlaylist(importedPlaylist.name, songs) + createPlaylist(importedPlaylist.name, songs, PlaylistDecision.New.Reason.IMPORT) } } } else { @@ -321,8 +336,15 @@ sealed interface PlaylistDecision { * Navigate to a dialog that allows a user to pick a name for a new [Playlist]. * * @param songs The [Song]s to contain in the new [Playlist]. + * @param context The context in which this decision is being fulfilled. */ - data class New(val songs: List) : PlaylistDecision + data class New(val songs: List, val reason: Reason) : PlaylistDecision { + enum class Reason { + NEW, + ADD, + IMPORT + } + } /** * Navigate to a file picker to import a playlist from. diff --git a/app/src/main/java/org/oxycblt/auxio/music/decision/AddToPlaylistDialog.kt b/app/src/main/java/org/oxycblt/auxio/music/decision/AddToPlaylistDialog.kt index e84deb420..66a1d5507 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/decision/AddToPlaylistDialog.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/decision/AddToPlaylistDialog.kt @@ -32,6 +32,7 @@ import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.DialogMusicChoicesBinding import org.oxycblt.auxio.list.ClickableListListener import org.oxycblt.auxio.music.MusicViewModel +import org.oxycblt.auxio.music.PlaylistDecision import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment import org.oxycblt.auxio.util.collectImmediately @@ -98,7 +99,8 @@ class AddToPlaylistDialog : val songs = pickerModel.currentSongsToAdd.value ?: return findNavController() .navigateSafe( - AddToPlaylistDialogDirections.newPlaylist(songs.map { it.uid }.toTypedArray())) + AddToPlaylistDialogDirections.newPlaylist( + songs.map { it.uid }.toTypedArray(), PlaylistDecision.New.Reason.ADD)) } private fun updatePendingSongs(songs: List?) { diff --git a/app/src/main/java/org/oxycblt/auxio/music/decision/NewPlaylistDialog.kt b/app/src/main/java/org/oxycblt/auxio/music/decision/NewPlaylistDialog.kt index 6cefe9730..9d8a44742 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/decision/NewPlaylistDialog.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/decision/NewPlaylistDialog.kt @@ -60,7 +60,7 @@ class NewPlaylistDialog : ViewBindingMaterialDialogFragment throw IllegalStateException() } // TODO: Navigate to playlist if there are songs in it - musicModel.createPlaylist(name, pendingPlaylist.songs) + musicModel.createPlaylist(name, pendingPlaylist.songs, pendingPlaylist.reason) findNavController().apply { navigateUp() // Do an additional navigation away from the playlist addition dialog, if @@ -82,7 +82,7 @@ class NewPlaylistDialog : ViewBindingMaterialDialogFragment PendingPlaylist( pendingPlaylist.preferredName, - pendingPlaylist.songs.mapNotNull { deviceLibrary.findSong(it.uid) }) + pendingPlaylist.songs.mapNotNull { deviceLibrary.findSong(it.uid) }, + pendingPlaylist.reason) } logD("Updated pending playlist: ${_currentPendingPlaylist.value?.preferredName}") @@ -143,8 +145,13 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M * * @param context [Context] required to generate a playlist name. * @param songUids The [Music.UID]s of songs to be present in the playlist. + * @param reason The reason the playlist is being created. */ - fun setPendingPlaylist(context: Context, songUids: Array) { + fun setPendingPlaylist( + context: Context, + songUids: Array, + reason: PlaylistDecision.New.Reason + ) { logD("Opening ${songUids.size} songs to create a playlist from") val userLibrary = musicRepository.userLibrary ?: return val songs = @@ -168,7 +175,7 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M _currentPendingPlaylist.value = if (possibleName != null && songs != null) { - PendingPlaylist(possibleName, songs) + PendingPlaylist(possibleName, songs, reason) } else { logW("Given song UIDs to create were invalid") null @@ -295,9 +302,14 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M * * @param preferredName The name to be used by default if no other name is chosen. * @param songs The [Song]s to be contained in the [PendingPlaylist] + * @param reason The reason the playlist is being created. * @author Alexander Capehart (OxygenCobalt) */ -data class PendingPlaylist(val preferredName: String, val songs: List) +data class PendingPlaylist( + val preferredName: String, + val songs: List, + val reason: PlaylistDecision.New.Reason +) /** * Represents the (processed) user input from the playlist naming dialogs. diff --git a/app/src/main/res/navigation/inner.xml b/app/src/main/res/navigation/inner.xml index 64b8ff95b..95c6a7770 100644 --- a/app/src/main/res/navigation/inner.xml +++ b/app/src/main/res/navigation/inner.xml @@ -413,6 +413,9 @@ +