music: clean up playlist name dialog
Cleanup the playlist naming dialog to have nicer UX/implementation.
This commit is contained in:
parent
97705a37e4
commit
e2104c58b8
8 changed files with 78 additions and 105 deletions
|
@ -42,7 +42,7 @@ import org.oxycblt.auxio.list.selection.SelectionViewModel
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.music.MusicViewModel
|
import org.oxycblt.auxio.music.MusicViewModel
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.music.dialog.PendingName
|
import org.oxycblt.auxio.music.dialog.PendingPlaylist
|
||||||
import org.oxycblt.auxio.navigation.MainNavigationAction
|
import org.oxycblt.auxio.navigation.MainNavigationAction
|
||||||
import org.oxycblt.auxio.navigation.NavigationViewModel
|
import org.oxycblt.auxio.navigation.NavigationViewModel
|
||||||
import org.oxycblt.auxio.playback.PlaybackBottomSheetBehavior
|
import org.oxycblt.auxio.playback.PlaybackBottomSheetBehavior
|
||||||
|
@ -304,9 +304,10 @@ class MainFragment :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handlePlaylistNaming(args: PendingName.Args?) {
|
private fun handlePlaylistNaming(pendingPlaylist: PendingPlaylist?) {
|
||||||
if (args != null) {
|
if (pendingPlaylist != null) {
|
||||||
findNavController().navigateSafe(MainFragmentDirections.actionNewPlaylist(args))
|
findNavController()
|
||||||
|
.navigateSafe(MainFragmentDirections.actionNewPlaylist(pendingPlaylist))
|
||||||
musicModel.pendingNewPlaylist.consume()
|
musicModel.pendingNewPlaylist.consume()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import javax.inject.Inject
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.music.dialog.PendingName
|
import org.oxycblt.auxio.music.dialog.PendingPlaylist
|
||||||
import org.oxycblt.auxio.util.Event
|
import org.oxycblt.auxio.util.Event
|
||||||
import org.oxycblt.auxio.util.MutableEvent
|
import org.oxycblt.auxio.util.MutableEvent
|
||||||
|
|
||||||
|
@ -47,8 +47,8 @@ class MusicViewModel @Inject constructor(private val musicRepository: MusicRepos
|
||||||
val statistics: StateFlow<Statistics?>
|
val statistics: StateFlow<Statistics?>
|
||||||
get() = _statistics
|
get() = _statistics
|
||||||
|
|
||||||
private val _pendingNewPlaylist = MutableEvent<PendingName.Args?>()
|
private val _pendingNewPlaylist = MutableEvent<PendingPlaylist?>()
|
||||||
val pendingNewPlaylist: Event<PendingName.Args?> = _pendingNewPlaylist
|
val pendingNewPlaylist: Event<PendingPlaylist?> = _pendingNewPlaylist
|
||||||
|
|
||||||
init {
|
init {
|
||||||
musicRepository.addUpdateListener(this)
|
musicRepository.addUpdateListener(this)
|
||||||
|
@ -115,7 +115,7 @@ class MusicViewModel @Inject constructor(private val musicRepository: MusicRepos
|
||||||
*/
|
*/
|
||||||
fun createPlaylist(name: String, songs: List<Song> = listOf()) {
|
fun createPlaylist(name: String, songs: List<Song> = listOf()) {
|
||||||
// TODO: Attempt to unify playlist creation flow with dialog model
|
// TODO: Attempt to unify playlist creation flow with dialog model
|
||||||
_pendingNewPlaylist.put(PendingName.Args(name, songs.map { it.uid }))
|
_pendingNewPlaylist.put(PendingPlaylist(name, songs.map { it.uid }))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,13 +23,13 @@ import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.fragment.findNavController
|
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.databinding.DialogPlaylistNameBinding
|
import org.oxycblt.auxio.databinding.DialogPlaylistNameBinding
|
||||||
import org.oxycblt.auxio.ui.ViewBindingDialogFragment
|
import org.oxycblt.auxio.ui.ViewBindingDialogFragment
|
||||||
import org.oxycblt.auxio.util.collectImmediately
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A dialog allowing the name of a new/existing playlist to be edited.
|
* A dialog allowing the name of a new/existing playlist to be edited.
|
||||||
|
@ -44,7 +44,6 @@ class NewPlaylistDialog : ViewBindingDialogFragment<DialogPlaylistNameBinding>()
|
||||||
// Information about what playlist to name for is initially within the navigation arguments
|
// Information about what playlist to name for is initially within the navigation arguments
|
||||||
// as UIDs, as that is the only safe way to parcel playlist information.
|
// as UIDs, as that is the only safe way to parcel playlist information.
|
||||||
private val args: NewPlaylistDialogArgs by navArgs()
|
private val args: NewPlaylistDialogArgs by navArgs()
|
||||||
private var initializedInput = false
|
|
||||||
|
|
||||||
override fun onConfigDialog(builder: AlertDialog.Builder) {
|
override fun onConfigDialog(builder: AlertDialog.Builder) {
|
||||||
builder
|
builder
|
||||||
|
@ -59,26 +58,20 @@ class NewPlaylistDialog : ViewBindingDialogFragment<DialogPlaylistNameBinding>()
|
||||||
override fun onBindingCreated(binding: DialogPlaylistNameBinding, savedInstanceState: Bundle?) {
|
override fun onBindingCreated(binding: DialogPlaylistNameBinding, savedInstanceState: Bundle?) {
|
||||||
super.onBindingCreated(binding, savedInstanceState)
|
super.onBindingCreated(binding, savedInstanceState)
|
||||||
|
|
||||||
binding.playlistName.addTextChangedListener {
|
binding.playlistName.apply {
|
||||||
dialogModel.updatePendingName(it?.toString())
|
hint = args.pendingPlaylist.name
|
||||||
|
addTextChangedListener {
|
||||||
|
dialogModel.updatePendingName(
|
||||||
|
(if (it.isNullOrEmpty()) unlikelyToBeNull(hint) else it).toString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dialogModel.setPendingName(args.pendingName)
|
dialogModel.setPendingName(args.pendingPlaylist)
|
||||||
collectImmediately(dialogModel.currentPendingName, ::updatePendingName)
|
collectImmediately(dialogModel.pendingPlaylistValid, ::updateValid)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePendingName(pendingName: PendingName?) {
|
private fun updateValid(valid: Boolean) {
|
||||||
if (pendingName == null) {
|
|
||||||
findNavController().navigateUp()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Make sure we initialize the TextView with the preferred name if we haven't already.
|
|
||||||
if (!initializedInput) {
|
|
||||||
requireBinding().playlistName.setText(pendingName.name)
|
|
||||||
initializedInput = true
|
|
||||||
}
|
|
||||||
// Disable the OK button if the name is invalid (empty or whitespace)
|
// Disable the OK button if the name is invalid (empty or whitespace)
|
||||||
(dialog as AlertDialog).getButton(AlertDialog.BUTTON_POSITIVE)?.isEnabled =
|
(dialog as AlertDialog).getButton(AlertDialog.BUTTON_POSITIVE)?.isEnabled = valid
|
||||||
pendingName.valid
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import kotlinx.parcelize.Parcelize
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.music.MusicRepository
|
import org.oxycblt.auxio.music.MusicRepository
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A [ViewModel] managing the state of the playlist editing dialogs.
|
* A [ViewModel] managing the state of the playlist editing dialogs.
|
||||||
|
@ -37,33 +38,18 @@ import org.oxycblt.auxio.music.Song
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class PlaylistDialogViewModel @Inject constructor(private val musicRepository: MusicRepository) :
|
class PlaylistDialogViewModel @Inject constructor(private val musicRepository: MusicRepository) :
|
||||||
ViewModel(), MusicRepository.UpdateListener {
|
ViewModel(), MusicRepository.UpdateListener {
|
||||||
private val _currentPendingName = MutableStateFlow<PendingName?>(null)
|
var pendingPlaylist: PendingPlaylist? = null
|
||||||
val currentPendingName: StateFlow<PendingName?> = _currentPendingName
|
private set
|
||||||
|
|
||||||
|
private val _pendingPlaylistValid = MutableStateFlow(false)
|
||||||
|
val pendingPlaylistValid: StateFlow<Boolean> = _pendingPlaylistValid
|
||||||
|
|
||||||
init {
|
init {
|
||||||
musicRepository.addUpdateListener(this)
|
musicRepository.addUpdateListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMusicChanges(changes: MusicRepository.Changes) {
|
override fun onMusicChanges(changes: MusicRepository.Changes) {
|
||||||
val pendingName = _currentPendingName.value ?: return
|
pendingPlaylist?.let(::validateName)
|
||||||
|
|
||||||
val deviceLibrary = musicRepository.deviceLibrary
|
|
||||||
val newSongs =
|
|
||||||
if (changes.deviceLibrary && deviceLibrary != null) {
|
|
||||||
pendingName.songs.mapNotNull { deviceLibrary.findSong(it.uid) }
|
|
||||||
} else {
|
|
||||||
pendingName.songs
|
|
||||||
}
|
|
||||||
|
|
||||||
val userLibrary = musicRepository.userLibrary
|
|
||||||
val newValid =
|
|
||||||
if (changes.userLibrary && userLibrary != null) {
|
|
||||||
validateName(pendingName.name)
|
|
||||||
} else {
|
|
||||||
pendingName.valid
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentPendingName.value = PendingName(pendingName.name, newSongs, newValid)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
|
@ -71,58 +57,51 @@ class PlaylistDialogViewModel @Inject constructor(private val musicRepository: M
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the current [PendingName] based on the given [PendingName.Args].
|
* Update the current [PendingPlaylist]. Will do nothing if already equal.
|
||||||
*
|
*
|
||||||
* @param args The [PendingName.Args] to update with.
|
* @param pendingPlaylist The [PendingPlaylist] to update with.
|
||||||
*/
|
*/
|
||||||
fun setPendingName(args: PendingName.Args) {
|
fun setPendingName(pendingPlaylist: PendingPlaylist) {
|
||||||
val deviceLibrary = musicRepository.deviceLibrary ?: return
|
if (this.pendingPlaylist == pendingPlaylist) return
|
||||||
val name =
|
this.pendingPlaylist = pendingPlaylist
|
||||||
PendingName(
|
validateName(pendingPlaylist)
|
||||||
args.preferredName,
|
|
||||||
args.songUids.mapNotNull(deviceLibrary::findSong),
|
|
||||||
validateName(args.preferredName))
|
|
||||||
_currentPendingName.value = name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the current [PendingName] based on new user input.
|
* Update the current [PendingPlaylist] based on new user input.
|
||||||
*
|
*
|
||||||
* @param name The new user-inputted name, directly from the UI.
|
* @param name The new user-inputted name.
|
||||||
*/
|
*/
|
||||||
fun updatePendingName(name: String?) {
|
fun updatePendingName(name: String) {
|
||||||
|
val current = pendingPlaylist ?: return
|
||||||
// Remove any additional whitespace from the string to be consistent with all other
|
// Remove any additional whitespace from the string to be consistent with all other
|
||||||
// music items.
|
// music items.
|
||||||
val normalized = (name ?: return).trim()
|
val new = PendingPlaylist(name.trim(), current.songUids)
|
||||||
_currentPendingName.value =
|
pendingPlaylist = new
|
||||||
_currentPendingName.value?.run { PendingName(normalized, songs, validateName(name)) }
|
validateName(new)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Confirm the current [PendingName] operation and write it to the database. */
|
/** Confirm the current [PendingPlaylist] operation and write it to the database. */
|
||||||
fun confirmPendingName() {
|
fun confirmPendingName() {
|
||||||
val pendingName = _currentPendingName.value ?: return
|
val playlist = pendingPlaylist ?: return
|
||||||
musicRepository.createPlaylist(pendingName.name, pendingName.songs)
|
val deviceLibrary = musicRepository.deviceLibrary ?: return
|
||||||
_currentPendingName.value = null
|
musicRepository.createPlaylist(
|
||||||
|
playlist.name, playlist.songUids.mapNotNull(deviceLibrary::findSong))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validateName(name: String) =
|
private fun validateName(pendingPlaylist: PendingPlaylist) {
|
||||||
name.isNotBlank() && musicRepository.userLibrary?.findPlaylist(name) == null
|
val userLibrary = musicRepository.userLibrary
|
||||||
|
_pendingPlaylistValid.value =
|
||||||
|
pendingPlaylist.name.isNotBlank() &&
|
||||||
|
userLibrary != null &&
|
||||||
|
userLibrary.findPlaylist(pendingPlaylist.name) == null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the current state of a name operation.
|
* Represents a playlist that is currently being named before actually being completed.
|
||||||
*
|
*
|
||||||
* @param name The name of the playlist.
|
* @param name The name of the playlist.
|
||||||
* @param songs Any songs that will be in the playlist when added.
|
* @param songUids The [Music.UID]s of the [Song]s to be contained by the playlist.
|
||||||
* @param valid Whether the current configuration is valid.
|
|
||||||
*/
|
*/
|
||||||
data class PendingName(val name: String, val songs: List<Song>, val valid: Boolean) {
|
@Parcelize data class PendingPlaylist(val name: String, val songUids: List<Music.UID>) : Parcelable
|
||||||
/**
|
|
||||||
* A [Parcelable] version of [PendingName], to be used as a dialog argument.
|
|
||||||
*
|
|
||||||
* @param preferredName The name to be used initially by the dialog.
|
|
||||||
* @param songUids The [Music.UID] of any pending [Song]s that will be put in the playlist.
|
|
||||||
*/
|
|
||||||
@Parcelize
|
|
||||||
data class Args(val preferredName: String, val songUids: List<Music.UID>) : Parcelable
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 Auxio Project
|
* Copyright (c) 2022 Auxio Project
|
||||||
* ArtistNavigationPickerDialog.kt is part of Auxio.
|
* NavigateToArtistDialog.kt is part of Auxio.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -45,13 +45,13 @@ import org.oxycblt.auxio.util.collectImmediately
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class ArtistNavigationPickerDialog :
|
class NavigateToArtistDialog :
|
||||||
ViewBindingDialogFragment<DialogMusicPickerBinding>(), ClickableListListener<Artist> {
|
ViewBindingDialogFragment<DialogMusicPickerBinding>(), ClickableListListener<Artist> {
|
||||||
private val navigationModel: NavigationViewModel by activityViewModels()
|
private val navigationModel: NavigationViewModel by activityViewModels()
|
||||||
private val pickerModel: NavigationDialogViewModel by viewModels()
|
private val pickerModel: NavigationDialogViewModel by viewModels()
|
||||||
// Information about what artists to show choices for is initially within the navigation
|
// Information about what artists to show choices for is initially within the navigation
|
||||||
// arguments as UIDs, as that is the only safe way to parcel an artist.
|
// arguments as UIDs, as that is the only safe way to parcel an artist.
|
||||||
private val args: ArtistNavigationPickerDialogArgs by navArgs()
|
private val args: NavigateToArtistDialogArgs by navArgs()
|
||||||
private val choiceAdapter = ArtistChoiceAdapter(this)
|
private val choiceAdapter = ArtistChoiceAdapter(this)
|
||||||
|
|
||||||
override fun onConfigDialog(builder: AlertDialog.Builder) {
|
override fun onConfigDialog(builder: AlertDialog.Builder) {
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 Auxio Project
|
* Copyright (c) 2022 Auxio Project
|
||||||
* ArtistPlaybackPickerDialog.kt is part of Auxio.
|
* PlayFromArtistDialog.kt is part of Auxio.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -46,13 +46,13 @@ import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class ArtistPlaybackPickerDialog :
|
class PlayFromArtistDialog :
|
||||||
ViewBindingDialogFragment<DialogMusicPickerBinding>(), ClickableListListener<Artist> {
|
ViewBindingDialogFragment<DialogMusicPickerBinding>(), ClickableListListener<Artist> {
|
||||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
private val pickerModel: PlaybackDialogViewModel by viewModels()
|
private val pickerModel: PlaybackDialogViewModel by viewModels()
|
||||||
// Information about what Song to show choices for is initially within the navigation arguments
|
// Information about what Song to show choices for is initially within the navigation arguments
|
||||||
// as UIDs, as that is the only safe way to parcel a Song.
|
// as UIDs, as that is the only safe way to parcel a Song.
|
||||||
private val args: ArtistPlaybackPickerDialogArgs by navArgs()
|
private val args: PlayFromArtistDialogArgs by navArgs()
|
||||||
private val choiceAdapter = ArtistChoiceAdapter(this)
|
private val choiceAdapter = ArtistChoiceAdapter(this)
|
||||||
|
|
||||||
override fun onConfigDialog(builder: AlertDialog.Builder) {
|
override fun onConfigDialog(builder: AlertDialog.Builder) {
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 Auxio Project
|
* Copyright (c) 2022 Auxio Project
|
||||||
* GenrePlaybackPickerDialog.kt is part of Auxio.
|
* PlayFromGenreDialog.kt is part of Auxio.
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -46,13 +46,13 @@ import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class GenrePlaybackPickerDialog :
|
class PlayFromGenreDialog :
|
||||||
ViewBindingDialogFragment<DialogMusicPickerBinding>(), ClickableListListener<Genre> {
|
ViewBindingDialogFragment<DialogMusicPickerBinding>(), ClickableListListener<Genre> {
|
||||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
private val pickerModel: PlaybackDialogViewModel by viewModels()
|
private val pickerModel: PlaybackDialogViewModel by viewModels()
|
||||||
// Information about what Song to show choices for is initially within the navigation arguments
|
// Information about what Song to show choices for is initially within the navigation arguments
|
||||||
// as UIDs, as that is the only safe way to parcel a Song.
|
// as UIDs, as that is the only safe way to parcel a Song.
|
||||||
private val args: GenrePlaybackPickerDialogArgs by navArgs()
|
private val args: PlayFromGenreDialogArgs by navArgs()
|
||||||
private val choiceAdapter = GenreChoiceAdapter(this)
|
private val choiceAdapter = GenreChoiceAdapter(this)
|
||||||
|
|
||||||
override fun onConfigDialog(builder: AlertDialog.Builder) {
|
override fun onConfigDialog(builder: AlertDialog.Builder) {
|
|
@ -22,13 +22,13 @@
|
||||||
app:destination="@id/new_playlist_dialog" />
|
app:destination="@id/new_playlist_dialog" />
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_pick_navigation_artist"
|
android:id="@+id/action_pick_navigation_artist"
|
||||||
app:destination="@id/artist_navigation_picker_dialog" />
|
app:destination="@id/navigate_to_artist_dialog" />
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_pick_playback_artist"
|
android:id="@+id/action_pick_playback_artist"
|
||||||
app:destination="@id/artist_playback_picker_dialog" />
|
app:destination="@id/play_from_artist_dialog" />
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_pick_playback_genre"
|
android:id="@+id/action_pick_playback_genre"
|
||||||
app:destination="@id/genre_playback_picker_dialog" />
|
app:destination="@id/play_from_genre_dialog" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<dialog
|
<dialog
|
||||||
|
@ -47,14 +47,14 @@
|
||||||
android:label="new_playlist_dialog"
|
android:label="new_playlist_dialog"
|
||||||
tools:layout="@layout/dialog_playlist_name">
|
tools:layout="@layout/dialog_playlist_name">
|
||||||
<argument
|
<argument
|
||||||
android:name="pendingName"
|
android:name="pendingPlaylist"
|
||||||
app:argType="org.oxycblt.auxio.music.dialog.PendingName$Args" />
|
app:argType="org.oxycblt.auxio.music.dialog.PendingPlaylist" />
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<dialog
|
<dialog
|
||||||
android:id="@+id/artist_navigation_picker_dialog"
|
android:id="@+id/navigate_to_artist_dialog"
|
||||||
android:name="org.oxycblt.auxio.navigation.dialog.ArtistNavigationPickerDialog"
|
android:name="org.oxycblt.auxio.navigation.dialog.NavigateToArtistDialog"
|
||||||
android:label="artist_navigation_picker_dialog"
|
android:label="navigate_to_artist_dialog"
|
||||||
tools:layout="@layout/dialog_music_picker">
|
tools:layout="@layout/dialog_music_picker">
|
||||||
<argument
|
<argument
|
||||||
android:name="artistUid"
|
android:name="artistUid"
|
||||||
|
@ -62,9 +62,9 @@
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<dialog
|
<dialog
|
||||||
android:id="@+id/artist_playback_picker_dialog"
|
android:id="@+id/play_from_artist_dialog"
|
||||||
android:name="org.oxycblt.auxio.playback.dialog.ArtistPlaybackPickerDialog"
|
android:name="org.oxycblt.auxio.playback.dialog.PlayFromArtistDialog"
|
||||||
android:label="artist_playback_picker_dialog"
|
android:label="play_from_artist_dialog"
|
||||||
tools:layout="@layout/dialog_music_picker">
|
tools:layout="@layout/dialog_music_picker">
|
||||||
<argument
|
<argument
|
||||||
android:name="artistUid"
|
android:name="artistUid"
|
||||||
|
@ -72,9 +72,9 @@
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<dialog
|
<dialog
|
||||||
android:id="@+id/genre_playback_picker_dialog"
|
android:id="@+id/play_from_genre_dialog"
|
||||||
android:name="org.oxycblt.auxio.playback.dialog.GenrePlaybackPickerDialog"
|
android:name="org.oxycblt.auxio.playback.dialog.PlayFromGenreDialog"
|
||||||
android:label="genre_playback_picker_dialog"
|
android:label="play_from_genre_dialog"
|
||||||
tools:layout="@layout/dialog_music_picker">
|
tools:layout="@layout/dialog_music_picker">
|
||||||
<argument
|
<argument
|
||||||
android:name="genreUid"
|
android:name="genreUid"
|
||||||
|
|
Loading…
Reference in a new issue