mirror of
https://github.com/ultrasonic/ultrasonic
synced 2025-02-22 06:27:51 +01:00
Remove special casing of SongsForGenre and thereby fix it.
Also prevent jumping in the random albums list and don't refresh the album list on back navigation
This commit is contained in:
parent
6daa17efd5
commit
026aa79572
@ -34,6 +34,11 @@ class AlbumListFragment : EntryListFragment<MusicDirectory.Album>() {
|
|||||||
*/
|
*/
|
||||||
override val mainLayout: Int = R.layout.list_layout_generic
|
override val mainLayout: Int = R.layout.list_layout_generic
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to refresh the data onViewCreated
|
||||||
|
*/
|
||||||
|
override val refreshOnCreation: Boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The central function to pass a query to the model and return a LiveData object
|
* The central function to pass a query to the model and return a LiveData object
|
||||||
*/
|
*/
|
||||||
|
@ -71,7 +71,7 @@ abstract class EntryListFragment<T : GenericEntry> : MultiListFragment<T>() {
|
|||||||
* What to do when the list has changed
|
* What to do when the list has changed
|
||||||
*/
|
*/
|
||||||
override val defaultObserver: (List<T>) -> Unit = {
|
override val defaultObserver: (List<T>) -> Unit = {
|
||||||
emptyView.isVisible = it.isEmpty()
|
emptyView.isVisible = it.isEmpty() && !(refreshListView?.isRefreshing?:false)
|
||||||
|
|
||||||
if (showFolderHeader()) {
|
if (showFolderHeader()) {
|
||||||
val list = mutableListOf<Identifiable>(folderHeader)
|
val list = mutableListOf<Identifiable>(folderHeader)
|
||||||
|
@ -89,6 +89,11 @@ abstract class MultiListFragment<T : Identifiable> : Fragment() {
|
|||||||
open val emptyViewId = R.id.empty_list_view
|
open val emptyViewId = R.id.empty_list_view
|
||||||
open val emptyTextId = R.id.empty_list_text
|
open val emptyTextId = R.id.empty_list_text
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to refresh the data onViewCreated
|
||||||
|
*/
|
||||||
|
open val refreshOnCreation: Boolean = true
|
||||||
|
|
||||||
open fun setTitle(title: String?) {
|
open fun setTitle(title: String?) {
|
||||||
if (title == null) {
|
if (title == null) {
|
||||||
FragmentTitle.setTitle(
|
FragmentTitle.setTitle(
|
||||||
@ -106,7 +111,7 @@ abstract class MultiListFragment<T : Identifiable> : Fragment() {
|
|||||||
* What to do when the list has changed
|
* What to do when the list has changed
|
||||||
*/
|
*/
|
||||||
internal open val defaultObserver: ((List<T>) -> Unit) = {
|
internal open val defaultObserver: ((List<T>) -> Unit) = {
|
||||||
emptyView.isVisible = it.isEmpty()
|
emptyView.isVisible = it.isEmpty() && !(refreshListView?.isRefreshing?:false)
|
||||||
viewAdapter.submitList(it)
|
viewAdapter.submitList(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +128,7 @@ abstract class MultiListFragment<T : Identifiable> : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Populate the LiveData. This starts an API request in most cases
|
// Populate the LiveData. This starts an API request in most cases
|
||||||
liveDataItems = getLiveData(arguments, true)
|
liveDataItems = getLiveData(arguments, refreshOnCreation)
|
||||||
|
|
||||||
// Link view to display text if the list is empty
|
// Link view to display text if the list is empty
|
||||||
emptyView = view.findViewById(emptyViewId)
|
emptyView = view.findViewById(emptyViewId)
|
||||||
|
@ -18,7 +18,6 @@ import android.widget.ImageView
|
|||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Observer
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
@ -54,6 +53,8 @@ import org.moire.ultrasonic.util.Util
|
|||||||
* In most cases the data should be just a list of Entries, but there are some cases
|
* In most cases the data should be just a list of Entries, but there are some cases
|
||||||
* where the list can contain Albums as well. This happens especially when having ID3 tags disabled,
|
* where the list can contain Albums as well. This happens especially when having ID3 tags disabled,
|
||||||
* or using Offline mode, both in which Indexes instead of Artists are being used.
|
* or using Offline mode, both in which Indexes instead of Artists are being used.
|
||||||
|
*
|
||||||
|
* TODO: Remove more button and introduce endless scrolling
|
||||||
*/
|
*/
|
||||||
@Suppress("TooManyFunctions")
|
@Suppress("TooManyFunctions")
|
||||||
open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
||||||
@ -97,9 +98,6 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
|||||||
getLiveData(arguments, true)
|
getLiveData(arguments, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove special casing for songsForGenre
|
|
||||||
listModel.songsForGenre.observe(viewLifecycleOwner, songsForGenreObserver)
|
|
||||||
|
|
||||||
setupButtons(view)
|
setupButtons(view)
|
||||||
|
|
||||||
registerForContextMenu(listView!!)
|
registerForContextMenu(listView!!)
|
||||||
@ -424,34 +422,6 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
|||||||
mediaPlayerController.unpin(songs)
|
mediaPlayerController.unpin(songs)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val songsForGenreObserver = Observer<MusicDirectory> { musicDirectory ->
|
|
||||||
|
|
||||||
// Hide more button when results are less than album list size
|
|
||||||
if (musicDirectory.size < requireArguments().getInt(
|
|
||||||
Constants.INTENT_ALBUM_LIST_SIZE, 0
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
moreButton!!.visibility = View.GONE
|
|
||||||
} else {
|
|
||||||
moreButton!!.visibility = View.VISIBLE
|
|
||||||
}
|
|
||||||
|
|
||||||
moreButton!!.setOnClickListener {
|
|
||||||
val theGenre = requireArguments().getString(Constants.INTENT_GENRE_NAME)
|
|
||||||
val size = requireArguments().getInt(Constants.INTENT_ALBUM_LIST_SIZE, 0)
|
|
||||||
val theOffset = requireArguments().getInt(
|
|
||||||
Constants.INTENT_ALBUM_LIST_OFFSET, 0
|
|
||||||
) + size
|
|
||||||
val bundle = Bundle()
|
|
||||||
bundle.putString(Constants.INTENT_GENRE_NAME, theGenre)
|
|
||||||
bundle.putInt(Constants.INTENT_ALBUM_LIST_SIZE, size)
|
|
||||||
bundle.putInt(Constants.INTENT_ALBUM_LIST_OFFSET, theOffset)
|
|
||||||
|
|
||||||
Navigation.findNavController(requireView())
|
|
||||||
.navigate(R.id.trackCollectionFragment, bundle)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val defaultObserver: (List<MusicDirectory.Child>) -> Unit = {
|
override val defaultObserver: (List<MusicDirectory.Child>) -> Unit = {
|
||||||
|
|
||||||
val entryList: MutableList<MusicDirectory.Child> = it.toMutableList()
|
val entryList: MutableList<MusicDirectory.Child> = it.toMutableList()
|
||||||
@ -483,18 +453,9 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
|||||||
} else {
|
} else {
|
||||||
moreButton!!.visibility = View.VISIBLE
|
moreButton!!.visibility = View.VISIBLE
|
||||||
if (arguments?.getInt(Constants.INTENT_RANDOM, 0) ?: 0 > 0) {
|
if (arguments?.getInt(Constants.INTENT_RANDOM, 0) ?: 0 > 0) {
|
||||||
moreButton!!.setOnClickListener {
|
moreRandomTracks()
|
||||||
val offset = requireArguments().getInt(
|
} else if (arguments?.getString(Constants.INTENT_GENRE_NAME, "") ?: "" != "") {
|
||||||
Constants.INTENT_ALBUM_LIST_OFFSET, 0
|
moreSongsForGenre()
|
||||||
) + listSize
|
|
||||||
val bundle = Bundle()
|
|
||||||
bundle.putInt(Constants.INTENT_RANDOM, 1)
|
|
||||||
bundle.putInt(Constants.INTENT_ALBUM_LIST_SIZE, listSize)
|
|
||||||
bundle.putInt(Constants.INTENT_ALBUM_LIST_OFFSET, offset)
|
|
||||||
Navigation.findNavController(requireView()).navigate(
|
|
||||||
R.id.trackCollectionFragment, bundle
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -536,6 +497,40 @@ open class TrackCollectionFragment : MultiListFragment<MusicDirectory.Child>() {
|
|||||||
listModel.currentListIsSortable = true
|
listModel.currentListIsSortable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun moreSongsForGenre(args: Bundle = requireArguments()) {
|
||||||
|
moreButton!!.setOnClickListener {
|
||||||
|
val theGenre = args.getString(Constants.INTENT_GENRE_NAME)
|
||||||
|
val size = args.getInt(Constants.INTENT_ALBUM_LIST_SIZE, 0)
|
||||||
|
val theOffset = args.getInt(
|
||||||
|
Constants.INTENT_ALBUM_LIST_OFFSET, 0
|
||||||
|
) + size
|
||||||
|
val bundle = Bundle()
|
||||||
|
bundle.putString(Constants.INTENT_GENRE_NAME, theGenre)
|
||||||
|
bundle.putInt(Constants.INTENT_ALBUM_LIST_SIZE, size)
|
||||||
|
bundle.putInt(Constants.INTENT_ALBUM_LIST_OFFSET, theOffset)
|
||||||
|
|
||||||
|
Navigation.findNavController(requireView())
|
||||||
|
.navigate(R.id.trackCollectionFragment, bundle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun moreRandomTracks() {
|
||||||
|
val listSize = arguments?.getInt(Constants.INTENT_ALBUM_LIST_SIZE, 0) ?: 0
|
||||||
|
|
||||||
|
moreButton!!.setOnClickListener { it: View? ->
|
||||||
|
val offset = requireArguments().getInt(
|
||||||
|
Constants.INTENT_ALBUM_LIST_OFFSET, 0
|
||||||
|
) + listSize
|
||||||
|
val bundle = Bundle()
|
||||||
|
bundle.putInt(Constants.INTENT_RANDOM, 1)
|
||||||
|
bundle.putInt(Constants.INTENT_ALBUM_LIST_SIZE, listSize)
|
||||||
|
bundle.putInt(Constants.INTENT_ALBUM_LIST_OFFSET, offset)
|
||||||
|
Navigation.findNavController(requireView()).navigate(
|
||||||
|
R.id.trackCollectionFragment, bundle
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun getSelectedSongs(): List<MusicDirectory.Entry> {
|
internal fun getSelectedSongs(): List<MusicDirectory.Entry> {
|
||||||
// Walk through selected set and get the Entries based on the saved ids.
|
// Walk through selected set and get the Entries based on the saved ids.
|
||||||
return viewAdapter.getCurrentList().mapNotNull {
|
return viewAdapter.getCurrentList().mapNotNull {
|
||||||
|
@ -63,6 +63,12 @@ class AlbumListModel(application: Application) : GenericListModel(application) {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we are refreshing the random list, we want to avoid items moving across the screen,
|
||||||
|
// by clearing the list first
|
||||||
|
if (refresh && albumListType == "random") {
|
||||||
|
list.postValue(listOf())
|
||||||
|
}
|
||||||
|
|
||||||
// Handle the logic for endless scrolling:
|
// Handle the logic for endless scrolling:
|
||||||
// If appending the existing list, set the offset from where to load
|
// If appending the existing list, set the offset from where to load
|
||||||
if (append) offset += (size + loadedUntil)
|
if (append) offset += (size + loadedUntil)
|
||||||
@ -95,7 +101,7 @@ class AlbumListModel(application: Application) : GenericListModel(application) {
|
|||||||
val newList = ArrayList<MusicDirectory.Album>()
|
val newList = ArrayList<MusicDirectory.Album>()
|
||||||
newList.addAll(list.value!!)
|
newList.addAll(list.value!!)
|
||||||
newList.addAll(musicDirectory)
|
newList.addAll(musicDirectory)
|
||||||
this.list.postValue(newList)
|
list.postValue(newList)
|
||||||
} else {
|
} else {
|
||||||
list.postValue(musicDirectory)
|
list.postValue(musicDirectory)
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ import org.moire.ultrasonic.util.Util
|
|||||||
class TrackCollectionModel(application: Application) : GenericListModel(application) {
|
class TrackCollectionModel(application: Application) : GenericListModel(application) {
|
||||||
|
|
||||||
val currentList: MutableLiveData<List<MusicDirectory.Child>> = MutableLiveData()
|
val currentList: MutableLiveData<List<MusicDirectory.Child>> = MutableLiveData()
|
||||||
val songsForGenre: MutableLiveData<MusicDirectory> = MutableLiveData()
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Especially when dealing with indexes, this method can return Albums, Entries or a mix of both!
|
* Especially when dealing with indexes, this method can return Albums, Entries or a mix of both!
|
||||||
@ -56,7 +55,7 @@ class TrackCollectionModel(application: Application) : GenericListModel(applicat
|
|||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val service = MusicServiceFactory.getMusicService()
|
val service = MusicServiceFactory.getMusicService()
|
||||||
val musicDirectory = service.getSongsByGenre(genre, count, offset)
|
val musicDirectory = service.getSongsByGenre(genre, count, offset)
|
||||||
songsForGenre.postValue(musicDirectory)
|
updateList(musicDirectory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user