Refactor: LoadTask to Coroutines.

This commit is contained in:
tzugen 2021-04-21 21:55:55 +02:00
parent 1dd43d857d
commit 1f57fb334b
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930

View File

@ -18,16 +18,13 @@ import android.widget.ImageView
import android.widget.ListView import android.widget.ListView
import android.widget.TextView import android.widget.TextView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.navigation.Navigation import androidx.navigation.Navigation
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
import java.security.SecureRandom
import java.util.Collections
import java.util.LinkedList
import java.util.Random
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -44,7 +41,6 @@ import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle
import org.moire.ultrasonic.service.CommunicationErrorHandler import org.moire.ultrasonic.service.CommunicationErrorHandler
import org.moire.ultrasonic.service.MediaPlayerController import org.moire.ultrasonic.service.MediaPlayerController
import org.moire.ultrasonic.service.MusicService import org.moire.ultrasonic.service.MusicService
import org.moire.ultrasonic.service.MusicServiceFactory
import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
import org.moire.ultrasonic.subsonic.DownloadHandler import org.moire.ultrasonic.subsonic.DownloadHandler
import org.moire.ultrasonic.subsonic.ImageLoaderProvider import org.moire.ultrasonic.subsonic.ImageLoaderProvider
@ -62,6 +58,10 @@ import org.moire.ultrasonic.view.EntryAdapter
import org.moire.ultrasonic.view.SelectMusicFolderView import org.moire.ultrasonic.view.SelectMusicFolderView
import org.moire.ultrasonic.view.SongView import org.moire.ultrasonic.view.SongView
import timber.log.Timber import timber.log.Timber
import java.security.SecureRandom
import java.util.Collections
import java.util.LinkedList
import java.util.Random
/** /**
* Displays a group of playable media from the library, which can be an Album, a Playlist, etc. * Displays a group of playable media from the library, which can be an Album, a Playlist, etc.
@ -91,7 +91,15 @@ class SelectAlbumFragment : Fragment() {
private var showHeader = true private var showHeader = true
private var showSelectFolderHeader = false private var showSelectFolderHeader = false
private val random: Random = SecureRandom() private val random: Random = SecureRandom()
private val musicFolders: MutableLiveData<List<MusicFolder>> = MutableLiveData() private val musicFolders: MutableLiveData<List<MusicFolder>> = MutableLiveData()
private val artists: MutableLiveData<MusicDirectory> = MutableLiveData()
private val albumList: MutableLiveData<MusicDirectory> = MutableLiveData()
private val currentDirectory: MutableLiveData<MusicDirectory> = MutableLiveData()
private val songsForGenre: MutableLiveData<MusicDirectory> = MutableLiveData()
private var currentDirectoryIsSortable = true
private val mediaPlayerController: MediaPlayerController by inject() private val mediaPlayerController: MediaPlayerController by inject()
private val videoPlayer: VideoPlayer by inject() private val videoPlayer: VideoPlayer by inject()
@ -148,17 +156,11 @@ class SelectAlbumFragment : Fragment() {
this.updateDisplay(true) this.updateDisplay(true)
} }
) )
musicFolders.observe(
viewLifecycleOwner, musicFolders.observe(viewLifecycleOwner, musicFolderObserver)
Observer { changedFolders -> currentDirectory.observe(viewLifecycleOwner, defaultObserver)
if (changedFolders != null) { songsForGenre.observe(viewLifecycleOwner, songsForGenreObserver)
selectFolderHeader!!.setData( albumList.observe(viewLifecycleOwner, albumListObserver)
activeServerProvider.getActiveServer().musicFolderId,
changedFolders
)
}
}
)
albumListView!!.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE) albumListView!!.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE)
albumListView!!.setOnItemClickListener( albumListView!!.setOnItemClickListener(
@ -312,59 +314,69 @@ class SelectAlbumFragment : Fragment() {
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0 Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0
) )
backgroundLoadMusicFolders(refresh)
triggerLoad(refresh, id, name, playlistId, playlistName, podcastChannelId, shareId, shareName, albumListType, albumListTitle, albumListSize, albumListOffset, genreName, getStarredTracks, getVideos, getRandomTracks, isAlbum, parentId)
}
private fun triggerLoad(
refresh: Boolean,
id: String?,
name: String?,
playlistId: String?,
playlistName: String?,
podcastChannelId: String?,
shareId: String?,
shareName: String?,
albumListType: String?,
albumListTitle: Int,
albumListSize: Int,
albumListOffset: Int,
genreName: String?,
getStarredTracks: Int,
getVideos: Int,
getRandomTracks: Int,
isAlbum: Boolean,
parentId: String?
) {
serverSettingsModel.viewModelScope.launch {
refreshAlbumListView!!.isRefreshing = true
this@SelectAlbumFragment.getMusicFolders(refresh)
if (playlistId != null) { if (playlistId != null) {
getPlaylist(playlistId, playlistName) this@SelectAlbumFragment.getPlaylist(playlistId, playlistName)
} else if (podcastChannelId != null) { } else if (podcastChannelId != null) {
getPodcastEpisodes(podcastChannelId) this@SelectAlbumFragment.getPodcastEpisodes(podcastChannelId)
} else if (shareId != null) { } else if (shareId != null) {
getShare(shareId, shareName) this@SelectAlbumFragment.getShare(shareId, shareName)
} else if (albumListType != null) { } else if (albumListType != null) {
getAlbumList(albumListType, albumListTitle, albumListSize, albumListOffset) this@SelectAlbumFragment.getAlbumList(albumListType, albumListTitle, albumListSize, albumListOffset)
} else if (genreName != null) { } else if (genreName != null) {
getSongsForGenre(genreName, albumListSize, albumListOffset) this@SelectAlbumFragment.getSongsForGenre(genreName, albumListSize, albumListOffset)
} else if (getStarredTracks != 0) { } else if (getStarredTracks != 0) {
starred this@SelectAlbumFragment.getStarred()
} else if (getVideos != 0) { } else if (getVideos != 0) {
getVideos(refresh) this@SelectAlbumFragment.getVideos(refresh)
} else if (getRandomTracks != 0) { } else if (getRandomTracks != 0) {
getRandom(albumListSize) this@SelectAlbumFragment.getRandom(albumListSize)
} else { } else {
if (!isOffline(activity) && Util.getShouldUseId3Tags(activity)) { if (!isOffline(activity) && Util.getShouldUseId3Tags(activity)) {
if (isAlbum) { if (isAlbum) {
getAlbum(refresh, id, name, parentId) this@SelectAlbumFragment.getAlbum(refresh, id, name, parentId)
} else { } else {
getArtist(refresh, id, name) this@SelectAlbumFragment.getArtist(refresh, id, name)
} }
} else { } else {
getMusicDirectory(refresh, id, name, parentId) this@SelectAlbumFragment.getMusicDirectory(refresh, id, name, parentId)
}
} }
} }
private fun backgroundLoadMusicFolders(refresh: Boolean) {
serverSettingsModel.viewModelScope.launch {
refreshAlbumListView!!.isRefreshing = true
loadMusicFolders(refresh)
refreshAlbumListView!!.isRefreshing = false refreshAlbumListView!!.isRefreshing = false
} }
} }
private suspend fun loadMusicFolders(refresh: Boolean) {
withContext(Dispatchers.IO) {
if (!isOffline(context)) {
val musicService = MusicServiceFactory.getMusicService(requireContext())
try {
musicFolders.postValue(musicService.getMusicFolders(refresh, context))
} catch (exception: Exception) {
Handler(Looper.getMainLooper()).post {
CommunicationErrorHandler.handleError(exception, requireContext())
}
}
}
}
}
override fun onCreateContextMenu(menu: ContextMenu, view: View, menuInfo: ContextMenuInfo?) { override fun onCreateContextMenu(menu: ContextMenu, view: View, menuInfo: ContextMenuInfo?) {
super.onCreateContextMenu(menu, view, menuInfo) super.onCreateContextMenu(menu, view, menuInfo)
@ -523,11 +535,52 @@ class SelectAlbumFragment : Fragment() {
} }
} }
private fun getMusicDirectory(refresh: Boolean, id: String?, name: String?, parentId: String?) {
private suspend fun getMusicFolders(refresh: Boolean) {
withContext(Dispatchers.IO) {
if (!isOffline(context)) {
val musicService = getMusicService(requireContext())
try {
musicFolders.postValue(musicService.getMusicFolders(refresh, context))
} catch (exception: Exception) {
Handler(Looper.getMainLooper()).post {
CommunicationErrorHandler.handleError(exception, requireContext())
}
}
}
}
}
private suspend fun getMusicDirectory(refresh: Boolean, id: String?, name: String?, parentId: String?) {
setTitle(this, name) setTitle(this, name)
object : LoadTask() { withContext(Dispatchers.IO) {
override fun load(service: MusicService): MusicDirectory { if (!isOffline(context)) {
val service = getMusicService(requireContext())
fun getSongsRecursively(
parent: MusicDirectory,
songs: MutableList<MusicDirectory.Entry>
) {
for (song in parent.getChildren(false, true)) {
if (!song.isVideo && !song.isDirectory) {
songs.add(song)
}
}
for ((id1, _, _, title) in parent.getChildren(true, false)) {
var root: MusicDirectory
if (allSongsId != id1) {
root = service.getMusicDirectory(id1, title, false, context)
getSongsRecursively(root, songs)
}
}
}
var root = MusicDirectory() var root = MusicDirectory()
if (allSongsId == id) { if (allSongsId == id) {
@ -565,39 +618,19 @@ class SelectAlbumFragment : Fragment() {
root = musicDirectory root = musicDirectory
} }
} }
return root
currentDirectory.postValue(root)
} }
private fun getSongsRecursively(
parent: MusicDirectory,
songs: MutableList<MusicDirectory.Entry>
) {
for (song in parent.getChildren(false, true)) {
if (!song.isVideo && !song.isDirectory) {
songs.add(song)
} }
} }
val musicService = getMusicService(context!!) private suspend fun getArtist(refresh: Boolean, id: String?, name: String?) {
for ((id1, _, _, title) in parent.getChildren(true, false)) {
var root: MusicDirectory
if (allSongsId != id1) {
root = musicService.getMusicDirectory(id1, title, false, context)
getSongsRecursively(root, songs)
}
}
}
}.execute()
}
private fun getArtist(refresh: Boolean, id: String?, name: String?) {
setTitle(this, name) setTitle(this, name)
object : LoadTask() { withContext(Dispatchers.IO) {
override fun load(service: MusicService): MusicDirectory { if (!isOffline(context)) {
val service = getMusicService(requireContext())
var root = MusicDirectory() var root = MusicDirectory()
@ -623,16 +656,18 @@ class SelectAlbumFragment : Fragment() {
} else { } else {
root = musicDirectory root = musicDirectory
} }
return root currentDirectory.postValue(root)
}
} }
}.execute()
} }
private fun getAlbum(refresh: Boolean, id: String?, name: String?, parentId: String?) { private suspend fun getAlbum(refresh: Boolean, id: String?, name: String?, parentId: String?) {
setTitle(this, name) setTitle(this, name)
object : LoadTask() { withContext(Dispatchers.IO) {
override fun load(service: MusicService): MusicDirectory { if (!isOffline(context)) {
val service = getMusicService(requireContext())
val musicDirectory: MusicDirectory val musicDirectory: MusicDirectory
@ -640,7 +675,19 @@ class SelectAlbumFragment : Fragment() {
val root = MusicDirectory() val root = MusicDirectory()
val songs: MutableCollection<MusicDirectory.Entry> = LinkedList() val songs: MutableCollection<MusicDirectory.Entry> = LinkedList()
getSongsForArtist(parentId, songs) val artist = service.getArtist(parentId, "", false, context)
for ((id1) in artist.getChildren()) {
if (allSongsId != id1) {
val albumDirectory = service.getAlbum(id1, "", false, context)
for (song in albumDirectory.getChildren()) {
if (!song.isVideo) {
songs.add(song)
}
}
}
}
for (song in songs) { for (song in songs) {
if (!song.isDirectory) { if (!song.isDirectory) {
@ -651,156 +698,131 @@ class SelectAlbumFragment : Fragment() {
} else { } else {
service.getAlbum(id, name, refresh, context) service.getAlbum(id, name, refresh, context)
} }
return musicDirectory currentDirectory.postValue(musicDirectory);
} }
private fun getSongsForArtist(
id: String?,
songs: MutableCollection<MusicDirectory.Entry>
) {
val musicService = getMusicService(context!!)
val artist = musicService.getArtist(id, "", false, context)
for ((id1) in artist.getChildren()) {
if (allSongsId != id1) {
val albumDirectory = musicService.getAlbum(id1, "", false, context)
for (song in albumDirectory.getChildren()) {
if (!song.isVideo) {
songs.add(song)
} }
} }
}
}
}
}.execute()
}
private fun getSongsForGenre(genre: String, count: Int, offset: Int) { private suspend fun getSongsForGenre(genre: String, count: Int, offset: Int) {
setTitle(this, genre) setTitle(this, genre)
object : LoadTask() { withContext(Dispatchers.IO) {
override fun load(service: MusicService): MusicDirectory { if (!isOffline(context)) {
return service.getSongsByGenre(genre, count, offset, context) val service = getMusicService(requireContext())
val musicDirectory: MusicDirectory
musicDirectory = service.getSongsByGenre(genre, count, offset, context)
songsForGenre.postValue(musicDirectory)
}
} }
override fun done(result: Pair<MusicDirectory, Boolean>) {
// Hide more button when results are less than album list size
if (result.first.getChildren().size < arguments!!.getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0
)
) {
moreButton!!.visibility = View.GONE
} else {
moreButton!!.visibility = View.VISIBLE
} }
moreButton!!.setOnClickListener { private suspend fun getStarred() {
val theGenre = arguments!!.getString(Constants.INTENT_EXTRA_NAME_GENRE_NAME)
val size = arguments!!.getInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0)
val theOffset = arguments!!.getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0
) + size
val bundle = Bundle()
bundle.putString(Constants.INTENT_EXTRA_NAME_GENRE_NAME, theGenre)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, size)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, theOffset)
Navigation.findNavController(view!!).navigate(R.id.selectAlbumFragment, bundle)
}
super.done(result)
}
}.execute()
}
private val starred: Unit
get() {
setTitle(this, R.string.main_songs_starred) setTitle(this, R.string.main_songs_starred)
object : LoadTask() { withContext(Dispatchers.IO) {
override fun load(service: MusicService): MusicDirectory { if (!isOffline(context)) {
return if (Util.getShouldUseId3Tags(context))
Util.getSongsFromSearchResult(service.getStarred2(context)) val service = getMusicService(requireContext())
else val musicDirectory: MusicDirectory
Util.getSongsFromSearchResult(service.getStarred(context)) val context = requireContext()
}
}.execute() if (Util.getShouldUseId3Tags(context)) {
musicDirectory = Util.getSongsFromSearchResult(service.getStarred2(context))
} else {
musicDirectory = Util.getSongsFromSearchResult(service.getStarred(context))
} }
private fun getVideos(refresh: Boolean) { currentDirectory.postValue(musicDirectory)
}
}
}
private suspend fun getVideos(refresh: Boolean) {
showHeader = false showHeader = false
setTitle(this, R.string.main_videos) setTitle(this, R.string.main_videos)
object : LoadTask() { withContext(Dispatchers.IO) {
override fun load(service: MusicService): MusicDirectory { if (!isOffline(context)) {
return service.getVideos(refresh, context) val service = getMusicService(requireContext())
currentDirectory.postValue(service.getVideos(refresh, context))
}
} }
}.execute()
} }
private fun getRandom(size: Int) { private suspend fun getRandom(size: Int) {
setTitle(this, R.string.main_songs_random) setTitle(this, R.string.main_songs_random)
object : LoadTask() { withContext(Dispatchers.IO) {
override fun sortableCollection(): Boolean { if (!isOffline(context)) {
return false val service = getMusicService(requireContext())
val musicDirectory = service.getRandomSongs(size, context)
currentDirectoryIsSortable = false
currentDirectory.postValue(musicDirectory)
}
}
} }
override fun load(service: MusicService): MusicDirectory { private suspend fun getPlaylist(playlistId: String, playlistName: String?) {
return service.getRandomSongs(size, context)
}
}.execute()
}
private fun getPlaylist(playlistId: String, playlistName: String?) {
setTitle(this, playlistName) setTitle(this, playlistName)
object : LoadTask() { withContext(Dispatchers.IO) {
override fun load(service: MusicService): MusicDirectory { if (!isOffline(context)) {
return service.getPlaylist(playlistId, playlistName, context) val service = getMusicService(requireContext())
val musicDirectory: MusicDirectory
musicDirectory = service.getPlaylist(playlistId, playlistName, context)
currentDirectory.postValue(musicDirectory)
}
} }
}.execute()
} }
private fun getPodcastEpisodes(podcastChannelId: String) { private suspend fun getPodcastEpisodes(podcastChannelId: String) {
setTitle(this, R.string.podcasts_label) setTitle(this, R.string.podcasts_label)
object : LoadTask() { withContext(Dispatchers.IO) {
override fun load(service: MusicService): MusicDirectory { if (!isOffline(context)) {
return service.getPodcastEpisodes(podcastChannelId, context) val service = getMusicService(requireContext())
val musicDirectory: MusicDirectory
musicDirectory = service.getPodcastEpisodes(podcastChannelId, context)
currentDirectory.postValue(musicDirectory)
}
} }
}.execute()
} }
private fun getShare(shareId: String, shareName: CharSequence?) { private suspend fun getShare(shareId: String, shareName: CharSequence?) {
setTitle(this, shareName) setTitle(this, shareName)
// setActionBarSubtitle(shareName); // setActionBarSubtitle(shareName);
object : LoadTask() { withContext(Dispatchers.IO) {
override fun load(service: MusicService): MusicDirectory { if (!isOffline(context)) {
val service = getMusicService(requireContext())
val musicDirectory = MusicDirectory()
val shares = service.getShares(true, context) val shares = service.getShares(true, context)
val md = MusicDirectory()
for (share in shares) { for (share in shares) {
if (share.id == shareId) { if (share.id == shareId) {
for (entry in share.getEntries()) { for (entry in share.getEntries()) {
md.addChild(entry) musicDirectory.addChild(entry)
} }
break break
} }
} }
return md currentDirectory.postValue(musicDirectory)
}
} }
}.execute()
} }
private fun getAlbumList(albumListType: String, albumListTitle: Int, size: Int, offset: Int) { private suspend fun getAlbumList(albumListType: String, albumListTitle: Int, size: Int, offset: Int) {
showHeader = false showHeader = false
showSelectFolderHeader = !isOffline(context) && !Util.getShouldUseId3Tags(context) && showSelectFolderHeader = !isOffline(context) && !Util.getShouldUseId3Tags(context) &&
@ -812,72 +834,35 @@ class SelectAlbumFragment : Fragment() {
setTitle(this, albumListTitle) setTitle(this, albumListTitle)
// setActionBarSubtitle(albumListTitle); // setActionBarSubtitle(albumListTitle);
object : LoadTask() {
override fun sortableCollection(): Boolean { fun sortableCollection(): Boolean {
return albumListType != "newest" && albumListType != "random" && return albumListType != "newest" && albumListType != "random" &&
albumListType != "highest" && albumListType != "recent" && albumListType != "highest" && albumListType != "recent" &&
albumListType != "frequent" albumListType != "frequent"
} }
override fun load(service: MusicService): MusicDirectory {
withContext(Dispatchers.IO) {
if (!isOffline(context)) {
val service = getMusicService(requireContext())
val musicDirectory: MusicDirectory
val musicFolderId = if (showSelectFolderHeader) { val musicFolderId = if (showSelectFolderHeader) {
this@SelectAlbumFragment.activeServerProvider.getActiveServer().musicFolderId this@SelectAlbumFragment.activeServerProvider.getActiveServer().musicFolderId
} else { } else {
null null
} }
return if (Util.getShouldUseId3Tags(context))
service.getAlbumList2(albumListType, size, offset, musicFolderId, context)
else
service.getAlbumList(albumListType, size, offset, musicFolderId, context)
}
override fun done(result: Pair<MusicDirectory, Boolean>) { if (Util.getShouldUseId3Tags(context)) {
if (!result.first.getChildren().isEmpty()) { musicDirectory = service.getAlbumList2(albumListType, size, offset, musicFolderId, context)
pinButton!!.visibility = View.GONE
unpinButton!!.visibility = View.GONE
downloadButton!!.visibility = View.GONE
deleteButton!!.visibility = View.GONE
// Hide more button when results are less than album list size
if (result.first.getChildren().size < arguments!!.getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0
)
) {
moreButton!!.visibility = View.GONE
} else { } else {
moreButton!!.visibility = View.VISIBLE musicDirectory = service.getAlbumList(albumListType, size, offset, musicFolderId, context)
moreButton!!.setOnClickListener { }
val theAlbumListTitle = arguments!!.getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, 0 currentDirectoryIsSortable = sortableCollection()
) albumList.postValue(musicDirectory)
val type = arguments!!.getString(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE
)
val theSize = arguments!!.getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0
)
val theOffset = arguments!!.getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0
) + theSize
val bundle = Bundle()
bundle.putInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, theAlbumListTitle
)
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, type)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, theSize)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, theOffset)
Navigation.findNavController(view!!).navigate(
R.id.selectAlbumFragment, bundle
)
} }
} }
} else {
moreButton!!.visibility = View.GONE
}
super.done(result)
}
}.execute()
} }
private fun selectAllOrNone() { private fun selectAllOrNone() {
@ -1009,27 +994,98 @@ class SelectAlbumFragment : Fragment() {
mediaPlayerController.unpin(songs) mediaPlayerController.unpin(songs)
} }
private abstract inner class LoadTask : FragmentBackgroundTask<Pair<MusicDirectory, Boolean>>( val albumListObserver = Observer<MusicDirectory> { musicDirectory ->
this@SelectAlbumFragment.activity, true, refreshAlbumListView, if (!musicDirectory.getChildren().isEmpty()) {
cancellationToken pinButton!!.visibility = View.GONE
unpinButton!!.visibility = View.GONE
downloadButton!!.visibility = View.GONE
deleteButton!!.visibility = View.GONE
// Hide more button when results are less than album list size
if (musicDirectory.getChildren().size < requireArguments().getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0
)
) { ) {
moreButton!!.visibility = View.GONE
} else {
moreButton!!.visibility = View.VISIBLE
moreButton!!.setOnClickListener {
val theAlbumListTitle = requireArguments().getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, 0
)
val type = requireArguments().getString(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE
)
val theSize = requireArguments().getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0
)
val theOffset = requireArguments().getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0
) + theSize
protected abstract fun load(service: MusicService): MusicDirectory val bundle = Bundle()
protected open fun sortableCollection(): Boolean { bundle.putInt(
return true Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE, theAlbumListTitle
)
bundle.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, type)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, theSize)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, theOffset)
Navigation.findNavController(requireView()).navigate(
R.id.selectAlbumFragment, bundle
)
}
}
} else {
moreButton!!.visibility = View.GONE
} }
override fun doInBackground(): Pair<MusicDirectory, Boolean> { updateInterfaceWithEntries(musicDirectory)
val musicService = getMusicService(context!!)
val dir = load(musicService)
val valid = musicService.isLicenseValid(context)
return Pair<MusicDirectory, Boolean>(dir, valid)
} }
protected override fun done(result: Pair<MusicDirectory, Boolean>) { val musicFolderObserver = Observer<List<MusicFolder>> { changedFolders ->
val musicDirectory = result.first if (changedFolders != null) {
selectFolderHeader!!.setData(
activeServerProvider.getActiveServer().musicFolderId,
changedFolders
)
}
}
val songsForGenreObserver = Observer<MusicDirectory> { musicDirectory ->
// Hide more button when results are less than album list size
if (musicDirectory.getChildren().size < requireArguments().getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0
)
) {
moreButton!!.visibility = View.GONE
} else {
moreButton!!.visibility = View.VISIBLE
}
moreButton!!.setOnClickListener {
val theGenre = requireArguments().getString(Constants.INTENT_EXTRA_NAME_GENRE_NAME)
val size = requireArguments().getInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0)
val theOffset = requireArguments().getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0
) + size
val bundle = Bundle()
bundle.putString(Constants.INTENT_EXTRA_NAME_GENRE_NAME, theGenre)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, size)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, theOffset)
Navigation.findNavController(requireView()).navigate(R.id.selectAlbumFragment, bundle)
}
updateInterfaceWithEntries(musicDirectory)
}
// Our old "done" function
val defaultObserver = Observer(this::updateInterfaceWithEntries)
private fun updateInterfaceWithEntries(musicDirectory: MusicDirectory) {
val entries = musicDirectory.getChildren() val entries = musicDirectory.getChildren()
// FIXME
if (sortableCollection() && Util.getShouldSortByDisc(context)) { if (sortableCollection() && Util.getShouldSortByDisc(context)) {
Collections.sort(entries, EntryByDiscAndTrackComparator()) Collections.sort(entries, EntryByDiscAndTrackComparator())
} }
@ -1046,11 +1102,11 @@ class SelectAlbumFragment : Fragment() {
} }
} }
val listSize = arguments!!.getInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0) val listSize = requireArguments().getInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0)
if (songCount > 0) { if (songCount > 0) {
if (showHeader) { if (showHeader) {
val intentAlbumName = arguments!!.getString(Constants.INTENT_EXTRA_NAME_NAME) val intentAlbumName = requireArguments().getString(Constants.INTENT_EXTRA_NAME_NAME)
val directoryName = musicDirectory.name val directoryName = musicDirectory.name
val header = createHeader( val header = createHeader(
entries, intentAlbumName ?: directoryName, entries, intentAlbumName ?: directoryName,
@ -1074,16 +1130,16 @@ class SelectAlbumFragment : Fragment() {
moreButton!!.visibility = View.GONE moreButton!!.visibility = View.GONE
} else { } else {
moreButton!!.visibility = View.VISIBLE moreButton!!.visibility = View.VISIBLE
if (arguments!!.getInt(Constants.INTENT_EXTRA_NAME_RANDOM, 0) > 0) { if (requireArguments().getInt(Constants.INTENT_EXTRA_NAME_RANDOM, 0) > 0) {
moreButton!!.setOnClickListener { moreButton!!.setOnClickListener {
val offset = arguments!!.getInt( val offset = requireArguments().getInt(
Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0 Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0
) + listSize ) + listSize
val bundle = Bundle() val bundle = Bundle()
bundle.putInt(Constants.INTENT_EXTRA_NAME_RANDOM, 1) bundle.putInt(Constants.INTENT_EXTRA_NAME_RANDOM, 1)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, listSize) bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, listSize)
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, offset) bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, offset)
Navigation.findNavController(view!!).navigate( Navigation.findNavController(requireView()).navigate(
R.id.selectAlbumFragment, bundle R.id.selectAlbumFragment, bundle
) )
} }
@ -1105,7 +1161,7 @@ class SelectAlbumFragment : Fragment() {
playNextButton!!.visibility = View.GONE playNextButton!!.visibility = View.GONE
playLastButton!!.visibility = View.GONE playLastButton!!.visibility = View.GONE
if (listSize == 0 || result.first.getChildren().size < listSize) { if (listSize == 0 || musicDirectory.getChildren().size < listSize) {
albumButtons!!.visibility = View.GONE albumButtons!!.visibility = View.GONE
} else { } else {
moreButton!!.visibility = View.VISIBLE moreButton!!.visibility = View.VISIBLE
@ -1114,7 +1170,7 @@ class SelectAlbumFragment : Fragment() {
enableButtons() enableButtons()
val isAlbumList = arguments!!.containsKey(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE) val isAlbumList = requireArguments().containsKey(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE)
playAllButtonVisible = !(isAlbumList || entries.isEmpty()) && !allVideos playAllButtonVisible = !(isAlbumList || entries.isEmpty()) && !allVideos
shareButtonVisible = !isOffline(context) && songCount > 0 shareButtonVisible = !isOffline(context) && songCount > 0
@ -1138,13 +1194,15 @@ class SelectAlbumFragment : Fragment() {
imageLoaderProvider.getImageLoader(), entries, true imageLoaderProvider.getImageLoader(), entries, true
) )
val playAll = arguments!!.getBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false) val playAll = requireArguments().getBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false)
if (playAll && songCount > 0) { if (playAll && songCount > 0) {
playAll( playAll(
arguments!!.getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, false), requireArguments().getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, false),
false false
) )
} }
currentDirectoryIsSortable = true
} }
protected fun createHeader( protected fun createHeader(
@ -1215,8 +1273,12 @@ class SelectAlbumFragment : Fragment() {
return header return header
} }
private fun sortableCollection(): Boolean {
return currentDirectoryIsSortable
} }
private fun getSelectedSongs(albumListView: ListView?): List<MusicDirectory.Entry?> { private fun getSelectedSongs(albumListView: ListView?): List<MusicDirectory.Entry?> {
val songs: MutableList<MusicDirectory.Entry?> = ArrayList(10) val songs: MutableList<MusicDirectory.Entry?> = ArrayList(10)