Add option to play song from genre
Add the option to play a song from a genre.
This commit is contained in:
parent
95c601bf02
commit
fef8d4146e
7 changed files with 49 additions and 35 deletions
|
@ -41,9 +41,8 @@ import org.oxycblt.auxio.ui.setupSongActions
|
||||||
/**
|
/**
|
||||||
* A [Fragment] that shows a custom list of [Genre], [Artist], or [Album] data. Also allows for
|
* A [Fragment] that shows a custom list of [Genre], [Artist], or [Album] data. Also allows for
|
||||||
* search functionality.
|
* search functionality.
|
||||||
* TODO: Move search to separate tab?
|
* FIXME: Heisenleak when navving from search
|
||||||
* FIXME: Leak when navving from search
|
* FIXME: Heisen on older versions
|
||||||
* FIXME: Leak on older versions
|
|
||||||
*/
|
*/
|
||||||
class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
|
class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
|
||||||
|
|
||||||
|
@ -59,13 +58,13 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
|
||||||
val binding = FragmentLibraryBinding.inflate(inflater)
|
val binding = FragmentLibraryBinding.inflate(inflater)
|
||||||
|
|
||||||
val libraryAdapter = LibraryAdapter(
|
val libraryAdapter = LibraryAdapter(
|
||||||
doOnClick = { onItemSelection(it) },
|
doOnClick = this::onItemSelection,
|
||||||
doOnLongClick = { data, view -> showActionsForItem(data, view) }
|
doOnLongClick = this::showActionsForItem
|
||||||
)
|
)
|
||||||
|
|
||||||
val searchAdapter = SearchAdapter(
|
val searchAdapter = SearchAdapter(
|
||||||
doOnClick = { onItemSelection(it) },
|
doOnClick = this::onItemSelection,
|
||||||
doOnLongClick = { data, view -> showActionsForItem(data, view) }
|
doOnLongClick = this::showActionsForItem
|
||||||
)
|
)
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
|
|
|
@ -14,6 +14,7 @@ import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.databinding.FragmentQueueBinding
|
import org.oxycblt.auxio.databinding.FragmentQueueBinding
|
||||||
import org.oxycblt.auxio.music.BaseModel
|
import org.oxycblt.auxio.music.BaseModel
|
||||||
|
import org.oxycblt.auxio.music.Genre
|
||||||
import org.oxycblt.auxio.music.Header
|
import org.oxycblt.auxio.music.Header
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.playback.state.PlaybackMode
|
import org.oxycblt.auxio.playback.state.PlaybackMode
|
||||||
|
@ -106,13 +107,7 @@ class QueueFragment : Fragment() {
|
||||||
val queue = mutableListOf<BaseModel>()
|
val queue = mutableListOf<BaseModel>()
|
||||||
|
|
||||||
if (playbackModel.userQueue.value!!.isNotEmpty()) {
|
if (playbackModel.userQueue.value!!.isNotEmpty()) {
|
||||||
queue.add(
|
queue.add(Header(id = 0, name = getString(R.string.label_next_user_queue), isAction = true))
|
||||||
Header(
|
|
||||||
id = 0,
|
|
||||||
name = getString(R.string.label_next_user_queue),
|
|
||||||
isAction = true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
queue.addAll(playbackModel.userQueue.value!!)
|
queue.addAll(playbackModel.userQueue.value!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,13 +115,7 @@ class QueueFragment : Fragment() {
|
||||||
queue.add(
|
queue.add(
|
||||||
Header(
|
Header(
|
||||||
id = 1,
|
id = 1,
|
||||||
name = getString(
|
name = getString(R.string.format_next_from, getParentName()),
|
||||||
R.string.format_next_from,
|
|
||||||
if (playbackModel.mode.value == PlaybackMode.ALL_SONGS)
|
|
||||||
getString(R.string.label_all_songs)
|
|
||||||
else
|
|
||||||
playbackModel.parent.value!!.name
|
|
||||||
),
|
|
||||||
isAction = false
|
isAction = false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -135,4 +124,17 @@ class QueueFragment : Fragment() {
|
||||||
|
|
||||||
return queue
|
return queue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getParentName(): String {
|
||||||
|
return if (playbackModel.mode.value == PlaybackMode.ALL_SONGS) {
|
||||||
|
getString(R.string.label_all_songs)
|
||||||
|
} else {
|
||||||
|
if (playbackModel.parent.value is Genre) {
|
||||||
|
// Since t
|
||||||
|
(playbackModel.parent.value as Genre).displayName
|
||||||
|
} else {
|
||||||
|
playbackModel.parent.value!!.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@ class SongsAdapter(
|
||||||
private val doOnLongClick: (data: Song, view: View) -> Unit
|
private val doOnLongClick: (data: Song, view: View) -> Unit
|
||||||
) : RecyclerView.Adapter<SongsAdapter.SongViewHolder>() {
|
) : RecyclerView.Adapter<SongsAdapter.SongViewHolder>() {
|
||||||
|
|
||||||
private var currentSong: Song? = null
|
/* private var currentSong: Song? = null
|
||||||
private var lastHolder: Highlightable? = null
|
private var lastHolder: Highlightable? = null*/
|
||||||
|
|
||||||
override fun getItemCount(): Int = data.size
|
override fun getItemCount(): Int = data.size
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class SongsAdapter(
|
||||||
override fun onBindViewHolder(holder: SongViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: SongViewHolder, position: Int) {
|
||||||
holder.bind(data[position])
|
holder.bind(data[position])
|
||||||
|
|
||||||
if (currentSong != null) {
|
/* if (currentSong != null) {
|
||||||
if (data[position].id == currentSong?.id) {
|
if (data[position].id == currentSong?.id) {
|
||||||
// Reset the last ViewHolder before assigning the new, correct one to be highlighted
|
// Reset the last ViewHolder before assigning the new, correct one to be highlighted
|
||||||
lastHolder?.setHighlighted(false)
|
lastHolder?.setHighlighted(false)
|
||||||
|
@ -46,17 +46,17 @@ class SongsAdapter(
|
||||||
} else {
|
} else {
|
||||||
holder.setHighlighted(false)
|
holder.setHighlighted(false)
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setCurrentSong(song: Song?) {
|
/* fun setCurrentSong(song: Song?) {
|
||||||
// Clear out the last ViewHolder as a song update usually signifies that this current
|
// Clear out the last ViewHolder as a song update usually signifies that this current
|
||||||
// ViewHolder is likely invalid.
|
// ViewHolder is likely invalid.
|
||||||
lastHolder?.setHighlighted(false)
|
lastHolder?.setHighlighted(false)
|
||||||
lastHolder = null
|
lastHolder = null
|
||||||
|
|
||||||
currentSong = song
|
currentSong = song
|
||||||
}
|
}*/
|
||||||
|
|
||||||
inner class SongViewHolder(
|
inner class SongViewHolder(
|
||||||
private val binding: ItemSongBinding
|
private val binding: ItemSongBinding
|
||||||
|
|
|
@ -20,7 +20,6 @@ import org.oxycblt.auxio.detail.DetailViewModel
|
||||||
import org.oxycblt.auxio.logD
|
import org.oxycblt.auxio.logD
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.playback.state.PlaybackMode
|
|
||||||
import org.oxycblt.auxio.recycler.Highlightable
|
import org.oxycblt.auxio.recycler.Highlightable
|
||||||
import org.oxycblt.auxio.settings.SettingsManager
|
import org.oxycblt.auxio.settings.SettingsManager
|
||||||
import org.oxycblt.auxio.ui.accent
|
import org.oxycblt.auxio.ui.accent
|
||||||
|
@ -33,6 +32,8 @@ import kotlin.math.ceil
|
||||||
/**
|
/**
|
||||||
* A [Fragment] that shows a list of all songs on the device. Contains options to search/shuffle
|
* A [Fragment] that shows a list of all songs on the device. Contains options to search/shuffle
|
||||||
* them.
|
* them.
|
||||||
|
* TODO: Search
|
||||||
|
* TODO: Sorting
|
||||||
* @author OxygenCobalt
|
* @author OxygenCobalt
|
||||||
*/
|
*/
|
||||||
class SongsFragment : Fragment() {
|
class SongsFragment : Fragment() {
|
||||||
|
@ -105,9 +106,11 @@ class SongsFragment : Fragment() {
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Unused, not needed for SongsFragment
|
||||||
|
TODO: Move this code over to AlbumDetailFragment
|
||||||
playbackModel.song.observe(viewLifecycleOwner) { song ->
|
playbackModel.song.observe(viewLifecycleOwner) { song ->
|
||||||
if (playbackModel.mode.value == PlaybackMode.ALL_SONGS) {
|
if (playbackModel.mode.value == PlaybackMode.ALL_SONGS) {
|
||||||
logD(playbackModel.isInUserQueue.toString())
|
|
||||||
songAdapter.setCurrentSong(song)
|
songAdapter.setCurrentSong(song)
|
||||||
|
|
||||||
lastHolder?.setHighlighted(false)
|
lastHolder?.setHighlighted(false)
|
||||||
|
@ -126,16 +129,24 @@ class SongsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Clear the viewholders if the mode isnt ALL_SONGS
|
||||||
|
songAdapter.setCurrentSong(null)
|
||||||
|
|
||||||
|
lastHolder?.setHighlighted(false)
|
||||||
|
lastHolder = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
playbackModel.isInUserQueue.observe(viewLifecycleOwner) {
|
playbackModel.isInUserQueue.observe(viewLifecycleOwner) {
|
||||||
if (it) {
|
if (it) {
|
||||||
|
// Remove any highlighted ViewHolders if the playback is in the user queue.
|
||||||
songAdapter.setCurrentSong(null)
|
songAdapter.setCurrentSong(null)
|
||||||
lastHolder?.setHighlighted(false)
|
lastHolder?.setHighlighted(false)
|
||||||
lastHolder = null
|
lastHolder = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
setupFastScroller(binding)
|
setupFastScroller(binding)
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_play_albums"
|
||||||
|
android:icon="@drawable/ic_play"
|
||||||
|
android:title="@string/label_play"
|
||||||
|
app:showAsAction="never" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_shuffle"
|
android:id="@+id/action_shuffle"
|
||||||
android:icon="@drawable/ic_shuffle"
|
android:icon="@drawable/ic_shuffle"
|
||||||
android:title="@string/label_shuffle"
|
android:title="@string/label_shuffle"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
<item
|
|
||||||
android:id="@+id/action_play_albums"
|
|
||||||
android:icon="@drawable/ic_play"
|
|
||||||
android:title="@string/label_play_albums"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
</menu>
|
</menu>
|
|
@ -28,12 +28,14 @@
|
||||||
<item>@string/label_play_all_songs</item>
|
<item>@string/label_play_all_songs</item>
|
||||||
<item>@string/label_play_artist</item>
|
<item>@string/label_play_artist</item>
|
||||||
<item>@string/label_play_album</item>
|
<item>@string/label_play_album</item>
|
||||||
|
<item>@string/label_play_genre</item>
|
||||||
</array>
|
</array>
|
||||||
|
|
||||||
<array name="values_song_playback_mode">
|
<array name="values_song_playback_mode">
|
||||||
<item>ALL_SONGS</item>
|
<item>ALL_SONGS</item>
|
||||||
<item>IN_ARTIST</item>
|
<item>IN_ARTIST</item>
|
||||||
<item>IN_ALBUM</item>
|
<item>IN_ALBUM</item>
|
||||||
|
<item>IN_GENRE</item>
|
||||||
</array>
|
</array>
|
||||||
|
|
||||||
<array name="entries_at_end">
|
<array name="entries_at_end">
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
<string name="label_play_all_songs">Play from all songs</string>
|
<string name="label_play_all_songs">Play from all songs</string>
|
||||||
<string name="label_play_artist">Play from artist</string>
|
<string name="label_play_artist">Play from artist</string>
|
||||||
<string name="label_play_album">Play from album</string>
|
<string name="label_play_album">Play from album</string>
|
||||||
|
<string name="label_play_genre">Play from genre</string>
|
||||||
|
|
||||||
<string name="label_go_artist">Go to artist</string>
|
<string name="label_go_artist">Go to artist</string>
|
||||||
<string name="label_go_album">Go to album</string>
|
<string name="label_go_album">Go to album</string>
|
||||||
<string name="label_play_albums">Play albums</string>
|
|
||||||
|
|
||||||
<string name="label_queue">Queue</string>
|
<string name="label_queue">Queue</string>
|
||||||
<string name="label_queue_add">Add to queue</string>
|
<string name="label_queue_add">Add to queue</string>
|
||||||
|
|
Loading…
Reference in a new issue