From 191f9512bb8e17f3aa589b11d11d684849db26fb Mon Sep 17 00:00:00 2001 From: James Wells Date: Thu, 1 Apr 2021 23:00:01 -0400 Subject: [PATCH 1/9] Introduce the SelectMusicFolderView Signed-off-by: James Wells --- .../service/CachedMusicService.java | 4 +- .../ultrasonic/service/MusicService.java | 2 +- .../service/OfflineMusicService.java | 2 +- .../ultrasonic/fragment/ArtistRowAdapter.kt | 33 +++----- .../fragment/SelectAlbumFragment.kt | 38 ++++++++- .../fragment/SelectArtistFragment.kt | 73 ++++++----------- .../ultrasonic/service/RESTMusicService.kt | 3 +- .../ultrasonic/view/SelectMusicFolderView.kt | 81 +++++++++++++++++++ ...st_header.xml => select_folder_header.xml} | 6 +- 9 files changed, 160 insertions(+), 82 deletions(-) create mode 100644 ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt rename ultrasonic/src/main/res/layout/{select_artist_header.xml => select_folder_header.xml} (90%) diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java index 13d79649..ca2a8829 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java @@ -284,9 +284,9 @@ public class CachedMusicService implements MusicService } @Override - public MusicDirectory getAlbumList(String type, int size, int offset, Context context) throws Exception + public MusicDirectory getAlbumList(String type, int size, int offset, String musicFolderId, Context context) throws Exception { - return musicService.getAlbumList(type, size, offset, context); + return musicService.getAlbumList(type, size, offset, musicFolderId, context); } @Override diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/MusicService.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/MusicService.java index 37ded458..80bf4056 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/MusicService.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/service/MusicService.java @@ -90,7 +90,7 @@ public interface MusicService void scrobble(String id, boolean submission, Context context) throws Exception; - MusicDirectory getAlbumList(String type, int size, int offset, Context context) throws Exception; + MusicDirectory getAlbumList(String type, int size, int offset, String musicFolderId, Context context) throws Exception; MusicDirectory getAlbumList2(String type, int size, int offset, Context context) throws Exception; diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/OfflineMusicService.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/OfflineMusicService.java index 500d6b6f..65fe5654 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/OfflineMusicService.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/service/OfflineMusicService.java @@ -702,7 +702,7 @@ public class OfflineMusicService implements MusicService } @Override - public MusicDirectory getAlbumList(String type, int size, int offset, Context context) throws Exception + public MusicDirectory getAlbumList(String type, int size, int offset, String musicFolderId, Context context) throws Exception { throw new OfflineException("Album lists not available in offline mode"); } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt index 671ff8d5..40d439ff 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt @@ -24,7 +24,6 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.ImageView -import android.widget.LinearLayout import android.widget.PopupMenu import android.widget.RelativeLayout import android.widget.TextView @@ -37,6 +36,7 @@ import org.moire.ultrasonic.domain.Artist import org.moire.ultrasonic.domain.MusicDirectory import org.moire.ultrasonic.util.ImageLoader import org.moire.ultrasonic.util.Util +import org.moire.ultrasonic.view.SelectMusicFolderView /** * Creates a Row in a RecyclerView which contains the details of an Artist @@ -44,10 +44,9 @@ import org.moire.ultrasonic.util.Util class ArtistRowAdapter( private var artistList: List, private var folderName: String, - private var shouldShowHeader: Boolean, + private var selectFolderHeader: SelectMusicFolderView?, val onArtistClick: (Artist) -> Unit, val onContextMenuClick: (MenuItem, Artist) -> Boolean, - val onFolderClick: (view: View) -> Unit, private val imageLoader: ImageLoader ) : RecyclerView.Adapter(), SectionedAdapter { @@ -80,16 +79,6 @@ class ArtistRowAdapter( var coverArtId: String? = null } - /** - * Holds the view properties of the Header row - */ - class HeaderViewHolder( - itemView: View - ) : RecyclerView.ViewHolder(itemView) { - var folderName: TextView = itemView.findViewById(R.id.select_artist_folder_2) - var layout: LinearLayout = itemView.findViewById(R.id.select_artist_folder) - } - override fun onCreateViewHolder( parent: ViewGroup, viewType: Int @@ -99,9 +88,7 @@ class ArtistRowAdapter( .inflate(R.layout.artist_list_item, parent, false) return ArtistViewHolder(row) } - val header = LayoutInflater.from(parent.context) - .inflate(R.layout.select_artist_header, parent, false) - return HeaderViewHolder(header) + return selectFolderHeader!! } override fun onViewRecycled(holder: RecyclerView.ViewHolder) { @@ -113,7 +100,7 @@ class ArtistRowAdapter( override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { if (holder is ArtistViewHolder) { - val listPosition = if (shouldShowHeader) position - 1 else position + val listPosition = if (selectFolderHeader != null) position - 1 else position holder.textView.text = artistList[listPosition].name holder.section.text = getSectionForArtist(listPosition) holder.layout.setOnClickListener { onArtistClick(artistList[listPosition]) } @@ -130,20 +117,20 @@ class ArtistRowAdapter( } else { holder.coverArt.visibility = View.GONE } - } else if (holder is HeaderViewHolder) { - holder.folderName.text = folderName - holder.layout.setOnClickListener { onFolderClick(holder.layout) } } } - override fun getItemCount() = if (shouldShowHeader) artistList.size + 1 else artistList.size + override fun getItemCount() = if (selectFolderHeader != null) + artistList.size + 1 + else + artistList.size override fun getItemViewType(position: Int): Int { - return if (position == 0 && shouldShowHeader) TYPE_HEADER else TYPE_ITEM + return if (position == 0 && selectFolderHeader != null) TYPE_HEADER else TYPE_ITEM } override fun getSectionName(position: Int): String { - var listPosition = if (shouldShowHeader) position - 1 else position + var listPosition = if (selectFolderHeader != null) position - 1 else position // Show the first artist's initial in the popup when the list is // scrolled up to the "Select Folder" row diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt index 515c3389..1b0eb7d0 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt @@ -24,13 +24,16 @@ import java.util.Collections import java.util.LinkedList import java.util.Random import org.koin.android.ext.android.inject +import org.koin.android.viewmodel.ext.android.viewModel import org.moire.ultrasonic.R +import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline import org.moire.ultrasonic.domain.MusicDirectory import org.moire.ultrasonic.fragment.FragmentTitle.Companion.getTitle import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle import org.moire.ultrasonic.service.MediaPlayerController import org.moire.ultrasonic.service.MusicService +import org.moire.ultrasonic.service.MusicServiceFactory import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService import org.moire.ultrasonic.subsonic.DownloadHandler import org.moire.ultrasonic.subsonic.ImageLoaderProvider @@ -45,6 +48,7 @@ import org.moire.ultrasonic.util.FragmentBackgroundTask import org.moire.ultrasonic.util.Util import org.moire.ultrasonic.view.AlbumView import org.moire.ultrasonic.view.EntryAdapter +import org.moire.ultrasonic.view.SelectMusicFolderView import org.moire.ultrasonic.view.SongView import timber.log.Timber @@ -57,6 +61,7 @@ class SelectAlbumFragment : Fragment() { private var refreshAlbumListView: SwipeRefreshLayout? = null private var albumListView: ListView? = null private var header: View? = null + private var selectFolderHeader: SelectMusicFolderView? = null private var albumButtons: View? = null private var emptyView: View? = null private var selectButton: ImageView? = null @@ -73,6 +78,7 @@ class SelectAlbumFragment : Fragment() { private var playAllButton: MenuItem? = null private var shareButton: MenuItem? = null private var showHeader = true + private var showSelectFolderHeader = false private val random: Random = SecureRandom() private val mediaPlayerController: MediaPlayerController by inject() @@ -82,6 +88,9 @@ class SelectAlbumFragment : Fragment() { private val imageLoaderProvider: ImageLoaderProvider by inject() private val shareHandler: ShareHandler by inject() private var cancellationToken: CancellationToken? = null + private val activeServerProvider: ActiveServerProvider by inject() + private val serverSettingsModel: ServerSettingsModel by viewModel() + private val artistListModel: ArtistListModel by viewModel() override fun onCreate(savedInstanceState: Bundle?) { Util.applyTheme(this.context) @@ -117,6 +126,24 @@ class SelectAlbumFragment : Fragment() { false ) + selectFolderHeader = SelectMusicFolderView( + requireContext(), albumListView!!, + MusicServiceFactory.getMusicService(requireContext()).getMusicFolders( + false, requireContext() + ), + activeServerProvider.getActiveServer().musicFolderId, + { _, selectedFolderId -> + if (!ActiveServerProvider.isOffline(context)) { + val currentSetting = activeServerProvider.getActiveServer() + currentSetting.musicFolderId = selectedFolderId + serverSettingsModel.updateItem(currentSetting) + } + artistListModel.refresh(refreshAlbumListView!!) + + this.updateDisplay(true) + } + ) + albumListView!!.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE) albumListView!!.setOnItemClickListener( OnItemClickListener @@ -735,6 +762,7 @@ class SelectAlbumFragment : Fragment() { private fun getAlbumList(albumListType: String, albumListTitle: Int, size: Int, offset: Int) { showHeader = false + showSelectFolderHeader = !isOffline(context) setTitle(this, albumListTitle) // setActionBarSubtitle(albumListTitle); @@ -747,10 +775,12 @@ class SelectAlbumFragment : Fragment() { } override fun load(service: MusicService): MusicDirectory { + val musicFolderId = + this@SelectAlbumFragment.activeServerProvider.getActiveServer().musicFolderId return if (Util.getShouldUseId3Tags(context)) service.getAlbumList2(albumListType, size, offset, context) else - service.getAlbumList(albumListType, size, offset, context) + service.getAlbumList(albumListType, size, offset, musicFolderId, context) } override fun done(result: Pair) { @@ -1012,6 +1042,12 @@ class SelectAlbumFragment : Fragment() { } } } else { + if (showSelectFolderHeader) { + if (albumListView!!.headerViewsCount == 0) { + albumListView!!.addHeaderView(selectFolderHeader!!.itemView, null, false) + } + } + pinButton!!.visibility = View.GONE unpinButton!!.visibility = View.GONE downloadButton!!.visibility = View.GONE diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt index 6c851f5c..2aba479b 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt @@ -5,7 +5,6 @@ import android.view.LayoutInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup -import android.widget.PopupMenu import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.navigation.fragment.findNavController @@ -19,10 +18,12 @@ import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.domain.Artist import org.moire.ultrasonic.domain.MusicFolder import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle +import org.moire.ultrasonic.service.MusicServiceFactory import org.moire.ultrasonic.subsonic.DownloadHandler import org.moire.ultrasonic.subsonic.ImageLoaderProvider import org.moire.ultrasonic.util.Constants import org.moire.ultrasonic.util.Util +import org.moire.ultrasonic.view.SelectMusicFolderView /** * Displays the list of Artists from the media library @@ -39,6 +40,7 @@ class SelectArtistFragment : Fragment() { private var musicFolders: List? = null private lateinit var viewManager: RecyclerView.LayoutManager private lateinit var viewAdapter: ArtistRowAdapter + private var selectFolderHeader: SelectMusicFolderView? = null @Override override fun onCreate(savedInstanceState: Bundle?) { @@ -60,10 +62,26 @@ class SelectArtistFragment : Fragment() { artistListModel.refresh(refreshArtistListView!!) } - val shouldShowHeader = ( - !ActiveServerProvider.isOffline(this.context) && - !Util.getShouldUseId3Tags(this.context) + if (!ActiveServerProvider.isOffline(this.context) && + !Util.getShouldUseId3Tags(this.context) + ) { + selectFolderHeader = SelectMusicFolderView( + requireContext(), view as ViewGroup, + MusicServiceFactory.getMusicService(requireContext()).getMusicFolders( + false, requireContext() + ), + activeServerProvider.getActiveServer().musicFolderId, + { musicFolderName, selectedFolderId -> + if (!ActiveServerProvider.isOffline(context)) { + val currentSetting = activeServerProvider.getActiveServer() + currentSetting.musicFolderId = selectedFolderId + serverSettingsModel.updateItem(currentSetting) + } + viewAdapter.setFolderName(musicFolderName) + artistListModel.refresh(refreshArtistListView!!) + } ) + } val title = arguments?.getString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE) @@ -102,10 +120,9 @@ class SelectArtistFragment : Fragment() { viewAdapter = ArtistRowAdapter( artists.value ?: listOf(), getText(R.string.select_artist_all_folders).toString(), - shouldShowHeader, + selectFolderHeader, { artist -> onItemClick(artist) }, { menuItem, artist -> onArtistMenuItemSelected(menuItem, artist) }, - { onFolderClick(it) }, imageLoaderProvider.getImageLoader() ) @@ -138,31 +155,6 @@ class SelectArtistFragment : Fragment() { findNavController().navigate(R.id.selectArtistToSelectAlbum, bundle) } - private fun onFolderClick(view: View) { - val popup = PopupMenu(this.context, view) - - val musicFolderId = activeServerProvider.getActiveServer().musicFolderId - var menuItem = popup.menu.add( - MENU_GROUP_MUSIC_FOLDER, -1, 0, R.string.select_artist_all_folders - ) - if (musicFolderId == null || musicFolderId.isEmpty()) { - menuItem.isChecked = true - } - if (musicFolders != null) { - for (i in musicFolders!!.indices) { - val (id, name) = musicFolders!![i] - menuItem = popup.menu.add(MENU_GROUP_MUSIC_FOLDER, i, i + 1, name) - if (id == musicFolderId) { - menuItem.isChecked = true - } - } - } - popup.menu.setGroupCheckable(MENU_GROUP_MUSIC_FOLDER, true, true) - - popup.setOnMenuItemClickListener { item -> onFolderMenuItemSelected(item) } - popup.show() - } - private fun onArtistMenuItemSelected(menuItem: MenuItem, artist: Artist): Boolean { when (menuItem.itemId) { R.id.artist_menu_play_now -> @@ -246,23 +238,4 @@ class SelectArtistFragment : Fragment() { } return true } - - private fun onFolderMenuItemSelected(menuItem: MenuItem): Boolean { - val selectedFolder = if (menuItem.itemId == -1) null else musicFolders!![menuItem.itemId] - val musicFolderId = selectedFolder?.id - val musicFolderName = selectedFolder?.name - ?: getString(R.string.select_artist_all_folders) - if (!ActiveServerProvider.isOffline(this.context)) { - val currentSetting = activeServerProvider.getActiveServer() - currentSetting.musicFolderId = musicFolderId - serverSettingsModel.updateItem(currentSetting) - } - viewAdapter.setFolderName(musicFolderName) - artistListModel.refresh(refreshArtistListView!!) - return true - } - - companion object { - private const val MENU_GROUP_MUSIC_FOLDER = 10 - } } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt index 6e5e1daf..5f02d287 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt @@ -445,10 +445,11 @@ open class RESTMusicService( type: String, size: Int, offset: Int, + musicFolderId: String?, context: Context ): MusicDirectory { val response = responseChecker.callWithResponseCheck { api -> - api.getAlbumList(fromName(type), size, offset, null, null, null, null) + api.getAlbumList(fromName(type), size, offset, null, null, null, musicFolderId) .execute() } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt new file mode 100644 index 00000000..f02bbeb1 --- /dev/null +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt @@ -0,0 +1,81 @@ +package org.moire.ultrasonic.view + +import android.content.Context +import android.view.LayoutInflater +import android.view.MenuItem +import android.view.ViewGroup +import android.widget.LinearLayout +import android.widget.PopupMenu +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import org.moire.ultrasonic.R +import org.moire.ultrasonic.domain.MusicFolder + +/** + * This little view shows the currently selected Folder (or catalog) on the music server. + * When clicked it will drop down a list of all available Folders and allow you to + * select one. The intended usage us to supply a filter to lists of artists, albums, etc + */ +class SelectMusicFolderView( + private val context: Context, + root: ViewGroup, + private val musicFolders: List, + private var selectedFolderId: String?, + private val onUpdate: (String, String?) -> Unit +) : RecyclerView.ViewHolder( + LayoutInflater.from(context).inflate( + R.layout.select_folder_header, root, false + ) +) { + private val folderName: TextView = itemView.findViewById(R.id.select_folder_2) + private val layout: LinearLayout = itemView.findViewById(R.id.select_folder_header) + + init { + if (selectedFolderId != null) { + for ((id, name) in musicFolders) { + if (id == selectedFolderId) { + folderName.text = name + break + } + } + } + layout.setOnClickListener { onFolderClick() } + } + + private fun onFolderClick() { + val popup = PopupMenu(context, layout) + val MENU_GROUP_MUSIC_FOLDER = 10 + + var menuItem = popup.menu.add( + MENU_GROUP_MUSIC_FOLDER, -1, 0, R.string.select_artist_all_folders + ) + if (selectedFolderId == null || selectedFolderId!!.isEmpty()) { + menuItem.isChecked = true + } + for (i in musicFolders.indices) { + val (id, name) = musicFolders[i] + menuItem = popup.menu.add(MENU_GROUP_MUSIC_FOLDER, i, i + 1, name) + if (id == selectedFolderId) { + menuItem.isChecked = true + } + } + + popup.menu.setGroupCheckable(MENU_GROUP_MUSIC_FOLDER, true, true) + + popup.setOnMenuItemClickListener { item -> onFolderMenuItemSelected(item) } + popup.show() + } + + private fun onFolderMenuItemSelected(menuItem: MenuItem): Boolean { + val selectedFolder = if (menuItem.itemId == -1) null else musicFolders[menuItem.itemId] + val musicFolderName = selectedFolder?.name + ?: context.getString(R.string.select_artist_all_folders) + selectedFolderId = selectedFolder?.id + + menuItem.isChecked = true + folderName.text = musicFolderName + onUpdate(musicFolderName, selectedFolderId) + + return true + } +} diff --git a/ultrasonic/src/main/res/layout/select_artist_header.xml b/ultrasonic/src/main/res/layout/select_folder_header.xml similarity index 90% rename from ultrasonic/src/main/res/layout/select_artist_header.xml rename to ultrasonic/src/main/res/layout/select_folder_header.xml index 7a56076e..e1c30ac2 100644 --- a/ultrasonic/src/main/res/layout/select_artist_header.xml +++ b/ultrasonic/src/main/res/layout/select_folder_header.xml @@ -1,6 +1,6 @@ Date: Sun, 4 Apr 2021 15:30:31 -0400 Subject: [PATCH 2/9] restrict header to album list only Signed-off-by: James Wells --- .../org/moire/ultrasonic/fragment/SelectAlbumFragment.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt index 1b0eb7d0..5ab40313 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt @@ -26,6 +26,7 @@ import java.util.Random import org.koin.android.ext.android.inject import org.koin.android.viewmodel.ext.android.viewModel import org.moire.ultrasonic.R +import org.moire.ultrasonic.api.subsonic.models.AlbumListType import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline import org.moire.ultrasonic.domain.MusicDirectory @@ -762,7 +763,11 @@ class SelectAlbumFragment : Fragment() { private fun getAlbumList(albumListType: String, albumListTitle: Int, size: Int, offset: Int) { showHeader = false - showSelectFolderHeader = !isOffline(context) + showSelectFolderHeader = !isOffline(context) && + ( + (albumListType == AlbumListType.SORTED_BY_NAME.toString()) || + (albumListType == AlbumListType.SORTED_BY_ARTIST.toString()) + ) setTitle(this, albumListTitle) // setActionBarSubtitle(albumListTitle); From 580fc1aa895de6054763b55d818a778e83b33b28 Mon Sep 17 00:00:00 2001 From: James Wells Date: Tue, 6 Apr 2021 22:55:21 -0400 Subject: [PATCH 3/9] review comments Signed-off-by: James Wells --- .../moire/ultrasonic/service/CachedMusicService.java | 9 ++++++--- .../org/moire/ultrasonic/service/MusicService.java | 2 +- .../moire/ultrasonic/service/OfflineMusicService.java | 2 +- .../moire/ultrasonic/fragment/SelectAlbumFragment.kt | 5 +---- .../org/moire/ultrasonic/service/RESTMusicService.kt | 3 ++- .../org/moire/ultrasonic/view/SelectMusicFolderView.kt | 10 ++++++---- .../src/main/res/layout/select_folder_header.xml | 4 ++-- 7 files changed, 19 insertions(+), 16 deletions(-) diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java index ca2a8829..d294df64 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java @@ -76,6 +76,7 @@ public class CachedMusicService implements MusicService private final TimeLimitedCache> cachedGenres = new TimeLimitedCache<>(10 * 3600, TimeUnit.SECONDS); private String restUrl; + private String musicFolderId; public CachedMusicService(MusicService musicService) { @@ -290,9 +291,9 @@ public class CachedMusicService implements MusicService } @Override - public MusicDirectory getAlbumList2(String type, int size, int offset, Context context) throws Exception + public MusicDirectory getAlbumList2(String type, int size, int offset, String musicFolderId, Context context) throws Exception { - return musicService.getAlbumList2(type, size, offset, context); + return musicService.getAlbumList2(type, size, offset, musicFolderId, context); } @Override @@ -370,7 +371,8 @@ public class CachedMusicService implements MusicService private void checkSettingsChanged() { String newUrl = activeServerProvider.getValue().getRestUrl(null); - if (!Util.equals(newUrl, restUrl)) + String newFolderId = activeServerProvider.getValue().getActiveServer().getMusicFolderId(); + if (!Util.equals(newUrl, restUrl) || !Util.equals(musicFolderId,newFolderId)) { cachedMusicFolders.clear(); cachedMusicDirectories.clear(); @@ -382,6 +384,7 @@ public class CachedMusicService implements MusicService cachedArtist.clear(); cachedUserInfo.clear(); restUrl = newUrl; + musicFolderId = newFolderId; } } diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/MusicService.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/MusicService.java index 80bf4056..8ef64e81 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/MusicService.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/service/MusicService.java @@ -92,7 +92,7 @@ public interface MusicService MusicDirectory getAlbumList(String type, int size, int offset, String musicFolderId, Context context) throws Exception; - MusicDirectory getAlbumList2(String type, int size, int offset, Context context) throws Exception; + MusicDirectory getAlbumList2(String type, int size, int offset, String musicFolderId, Context context) throws Exception; MusicDirectory getRandomSongs(int size, Context context) throws Exception; diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/OfflineMusicService.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/OfflineMusicService.java index 65fe5654..80688551 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/OfflineMusicService.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/service/OfflineMusicService.java @@ -809,7 +809,7 @@ public class OfflineMusicService implements MusicService } @Override - public MusicDirectory getAlbumList2(String type, int size, int offset, Context context) { + public MusicDirectory getAlbumList2(String type, int size, int offset, String musicFolderId, Context context) { Timber.w("OfflineMusicService.getAlbumList2 was called but it isn't available"); return null; } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt index 5ab40313..2d0da70f 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt @@ -91,7 +91,6 @@ class SelectAlbumFragment : Fragment() { private var cancellationToken: CancellationToken? = null private val activeServerProvider: ActiveServerProvider by inject() private val serverSettingsModel: ServerSettingsModel by viewModel() - private val artistListModel: ArtistListModel by viewModel() override fun onCreate(savedInstanceState: Bundle?) { Util.applyTheme(this.context) @@ -139,8 +138,6 @@ class SelectAlbumFragment : Fragment() { currentSetting.musicFolderId = selectedFolderId serverSettingsModel.updateItem(currentSetting) } - artistListModel.refresh(refreshAlbumListView!!) - this.updateDisplay(true) } ) @@ -783,7 +780,7 @@ class SelectAlbumFragment : Fragment() { val musicFolderId = this@SelectAlbumFragment.activeServerProvider.getActiveServer().musicFolderId return if (Util.getShouldUseId3Tags(context)) - service.getAlbumList2(albumListType, size, offset, context) + service.getAlbumList2(albumListType, size, offset, musicFolderId, context) else service.getAlbumList(albumListType, size, offset, musicFolderId, context) } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt index 5f02d287..a0226118 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt @@ -465,6 +465,7 @@ open class RESTMusicService( type: String, size: Int, offset: Int, + musicFolderId: String?, context: Context ): MusicDirectory { val response = responseChecker.callWithResponseCheck { api -> @@ -475,7 +476,7 @@ open class RESTMusicService( null, null, null, - null + musicFolderId ).execute() } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt index f02bbeb1..ea3d77ef 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt @@ -27,8 +27,9 @@ class SelectMusicFolderView( R.layout.select_folder_header, root, false ) ) { - private val folderName: TextView = itemView.findViewById(R.id.select_folder_2) + private val folderName: TextView = itemView.findViewById(R.id.select_folder_name) private val layout: LinearLayout = itemView.findViewById(R.id.select_folder_header) + private val MENU_GROUP_MUSIC_FOLDER = 10 init { if (selectedFolderId != null) { @@ -38,13 +39,14 @@ class SelectMusicFolderView( break } } + } else { + folderName.text = context.getString(R.string.select_artist_all_folders) } layout.setOnClickListener { onFolderClick() } } private fun onFolderClick() { val popup = PopupMenu(context, layout) - val MENU_GROUP_MUSIC_FOLDER = 10 var menuItem = popup.menu.add( MENU_GROUP_MUSIC_FOLDER, -1, 0, R.string.select_artist_all_folders @@ -52,8 +54,8 @@ class SelectMusicFolderView( if (selectedFolderId == null || selectedFolderId!!.isEmpty()) { menuItem.isChecked = true } - for (i in musicFolders.indices) { - val (id, name) = musicFolders[i] + musicFolders.forEachIndexed { i, musicFolder -> + val (id, name) = musicFolder menuItem = popup.menu.add(MENU_GROUP_MUSIC_FOLDER, i, i + 1, name) if (id == selectedFolderId) { menuItem.isChecked = true diff --git a/ultrasonic/src/main/res/layout/select_folder_header.xml b/ultrasonic/src/main/res/layout/select_folder_header.xml index e1c30ac2..68538369 100644 --- a/ultrasonic/src/main/res/layout/select_folder_header.xml +++ b/ultrasonic/src/main/res/layout/select_folder_header.xml @@ -24,7 +24,7 @@ a:orientation="vertical" > Date: Fri, 9 Apr 2021 22:41:38 -0400 Subject: [PATCH 4/9] loads music folder list Signed-off-by: James Wells --- .../service/CachedMusicService.java | 6 +-- .../ultrasonic/fragment/ArtistRowAdapter.kt | 9 ---- .../fragment/SelectAlbumFragment.kt | 53 +++++++++++++++++-- .../fragment/SelectArtistFragment.kt | 33 +++--------- .../ultrasonic/service/RESTMusicService.kt | 7 ++- .../ultrasonic/view/SelectMusicFolderView.kt | 16 ++++-- 6 files changed, 74 insertions(+), 50 deletions(-) diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java index d294df64..d8033ceb 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/service/CachedMusicService.java @@ -76,7 +76,7 @@ public class CachedMusicService implements MusicService private final TimeLimitedCache> cachedGenres = new TimeLimitedCache<>(10 * 3600, TimeUnit.SECONDS); private String restUrl; - private String musicFolderId; + private String cachedMusicFolderId; public CachedMusicService(MusicService musicService) { @@ -372,7 +372,7 @@ public class CachedMusicService implements MusicService { String newUrl = activeServerProvider.getValue().getRestUrl(null); String newFolderId = activeServerProvider.getValue().getActiveServer().getMusicFolderId(); - if (!Util.equals(newUrl, restUrl) || !Util.equals(musicFolderId,newFolderId)) + if (!Util.equals(newUrl, restUrl) || !Util.equals(cachedMusicFolderId,newFolderId)) { cachedMusicFolders.clear(); cachedMusicDirectories.clear(); @@ -384,7 +384,7 @@ public class CachedMusicService implements MusicService cachedArtist.clear(); cachedUserInfo.clear(); restUrl = newUrl; - musicFolderId = newFolderId; + cachedMusicFolderId = newFolderId; } } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt index 40d439ff..6a56e1d2 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ArtistRowAdapter.kt @@ -43,7 +43,6 @@ import org.moire.ultrasonic.view.SelectMusicFolderView */ class ArtistRowAdapter( private var artistList: List, - private var folderName: String, private var selectFolderHeader: SelectMusicFolderView?, val onArtistClick: (Artist) -> Unit, val onContextMenuClick: (MenuItem, Artist) -> Boolean, @@ -58,14 +57,6 @@ class ArtistRowAdapter( notifyDataSetChanged() } - /** - * Sets the name of the folder to be displayed n the Header (first) row - */ - fun setFolderName(name: String) { - folderName = name - notifyDataSetChanged() - } - /** * Holds the view properties of an Artist row */ diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt index 2d0da70f..7a25a207 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt @@ -1,6 +1,8 @@ package org.moire.ultrasonic.fragment import android.os.Bundle +import android.os.Handler +import android.os.Looper import android.view.ContextMenu import android.view.ContextMenu.ContextMenuInfo import android.view.LayoutInflater @@ -16,6 +18,9 @@ import android.widget.ImageView import android.widget.ListView import android.widget.TextView import androidx.fragment.app.Fragment +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.Observer +import androidx.lifecycle.viewModelScope import androidx.navigation.Navigation import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener @@ -23,6 +28,9 @@ import java.security.SecureRandom import java.util.Collections import java.util.LinkedList import java.util.Random +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.koin.android.ext.android.inject import org.koin.android.viewmodel.ext.android.viewModel import org.moire.ultrasonic.R @@ -30,8 +38,10 @@ import org.moire.ultrasonic.api.subsonic.models.AlbumListType import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline import org.moire.ultrasonic.domain.MusicDirectory +import org.moire.ultrasonic.domain.MusicFolder import org.moire.ultrasonic.fragment.FragmentTitle.Companion.getTitle import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle +import org.moire.ultrasonic.service.CommunicationErrorHandler import org.moire.ultrasonic.service.MediaPlayerController import org.moire.ultrasonic.service.MusicService import org.moire.ultrasonic.service.MusicServiceFactory @@ -81,6 +91,7 @@ class SelectAlbumFragment : Fragment() { private var showHeader = true private var showSelectFolderHeader = false private val random: Random = SecureRandom() + private val musicFolders: MutableLiveData> = MutableLiveData() private val mediaPlayerController: MediaPlayerController by inject() private val videoPlayer: VideoPlayer by inject() @@ -128,11 +139,7 @@ class SelectAlbumFragment : Fragment() { selectFolderHeader = SelectMusicFolderView( requireContext(), albumListView!!, - MusicServiceFactory.getMusicService(requireContext()).getMusicFolders( - false, requireContext() - ), - activeServerProvider.getActiveServer().musicFolderId, - { _, selectedFolderId -> + { selectedFolderId -> if (!ActiveServerProvider.isOffline(context)) { val currentSetting = activeServerProvider.getActiveServer() currentSetting.musicFolderId = selectedFolderId @@ -141,6 +148,17 @@ class SelectAlbumFragment : Fragment() { this.updateDisplay(true) } ) + musicFolders.observe( + viewLifecycleOwner, + Observer { changedFolders -> + if (changedFolders != null) { + selectFolderHeader!!.setData( + activeServerProvider.getActiveServer().musicFolderId, + changedFolders + ) + } + } + ) albumListView!!.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE) albumListView!!.setOnItemClickListener( @@ -294,6 +312,8 @@ class SelectAlbumFragment : Fragment() { Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0 ) + backgroundLoadMusicFolders(refresh) + if (playlistId != null) { getPlaylist(playlistId, playlistName) } else if (podcastChannelId != null) { @@ -323,6 +343,29 @@ class SelectAlbumFragment : Fragment() { } } + private fun backgroundLoadMusicFolders(refresh: Boolean) { + serverSettingsModel.viewModelScope.launch { + refreshAlbumListView!!.isRefreshing = true + loadMusicFolders(refresh) + 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?) { super.onCreateContextMenu(menu, view, menuInfo) val info = menuInfo as AdapterContextMenuInfo? diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt index 2aba479b..39b2ebac 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectArtistFragment.kt @@ -16,9 +16,7 @@ import org.koin.android.viewmodel.ext.android.viewModel import org.moire.ultrasonic.R import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.domain.Artist -import org.moire.ultrasonic.domain.MusicFolder import org.moire.ultrasonic.fragment.FragmentTitle.Companion.setTitle -import org.moire.ultrasonic.service.MusicServiceFactory import org.moire.ultrasonic.subsonic.DownloadHandler import org.moire.ultrasonic.subsonic.ImageLoaderProvider import org.moire.ultrasonic.util.Constants @@ -37,7 +35,6 @@ class SelectArtistFragment : Fragment() { private var refreshArtistListView: SwipeRefreshLayout? = null private var artistListView: RecyclerView? = null - private var musicFolders: List? = null private lateinit var viewManager: RecyclerView.LayoutManager private lateinit var viewAdapter: ArtistRowAdapter private var selectFolderHeader: SelectMusicFolderView? = null @@ -67,17 +64,13 @@ class SelectArtistFragment : Fragment() { ) { selectFolderHeader = SelectMusicFolderView( requireContext(), view as ViewGroup, - MusicServiceFactory.getMusicService(requireContext()).getMusicFolders( - false, requireContext() - ), - activeServerProvider.getActiveServer().musicFolderId, - { musicFolderName, selectedFolderId -> + { selectedFolderId -> if (!ActiveServerProvider.isOffline(context)) { val currentSetting = activeServerProvider.getActiveServer() currentSetting.musicFolderId = selectedFolderId serverSettingsModel.updateItem(currentSetting) } - viewAdapter.setFolderName(musicFolderName) + viewAdapter.notifyDataSetChanged() artistListModel.refresh(refreshArtistListView!!) } ) @@ -96,8 +89,6 @@ class SelectArtistFragment : Fragment() { setTitle(this, title) } - musicFolders = null - val refresh = arguments?.getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH) ?: false artistListModel.getMusicFolders() @@ -105,8 +96,11 @@ class SelectArtistFragment : Fragment() { viewLifecycleOwner, Observer { changedFolders -> if (changedFolders != null) { - musicFolders = changedFolders - viewAdapter.setFolderName(getMusicFolderName(changedFolders)) + viewAdapter.notifyDataSetChanged() + selectFolderHeader!!.setData( + activeServerProvider.getActiveServer().musicFolderId, + changedFolders + ) } } ) @@ -119,7 +113,6 @@ class SelectArtistFragment : Fragment() { viewManager = LinearLayoutManager(this.context) viewAdapter = ArtistRowAdapter( artists.value ?: listOf(), - getText(R.string.select_artist_all_folders).toString(), selectFolderHeader, { artist -> onItemClick(artist) }, { menuItem, artist -> onArtistMenuItemSelected(menuItem, artist) }, @@ -134,18 +127,6 @@ class SelectArtistFragment : Fragment() { super.onViewCreated(view, savedInstanceState) } - private fun getMusicFolderName(musicFolders: List): String { - val musicFolderId = activeServerProvider.getActiveServer().musicFolderId - if (musicFolderId != null && musicFolderId != "") { - for ((id, name) in musicFolders) { - if (id == musicFolderId) { - return name - } - } - } - return getText(R.string.select_artist_all_folders).toString() - } - private fun onItemClick(artist: Artist) { val bundle = Bundle() bundle.putString(Constants.INTENT_EXTRA_NAME_ID, artist.id) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt index a0226118..8f380d9e 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/RESTMusicService.kt @@ -114,7 +114,9 @@ open class RESTMusicService( refresh: Boolean, context: Context ): Indexes { - val cachedIndexes = fileStorage.load(INDEXES_STORAGE_NAME, getIndexesSerializer()) + val indexName = INDEXES_STORAGE_NAME + (musicFolderId ?: "") + + val cachedIndexes = fileStorage.load(indexName, getIndexesSerializer()) if (cachedIndexes != null && !refresh) return cachedIndexes val response = responseChecker.callWithResponseCheck { api -> @@ -122,7 +124,7 @@ open class RESTMusicService( } val indexes = response.body()!!.indexes.toDomainEntity() - fileStorage.store(INDEXES_STORAGE_NAME, indexes, getIndexesSerializer()) + fileStorage.store(indexName, indexes, getIndexesSerializer()) return indexes } @@ -938,6 +940,7 @@ open class RESTMusicService( companion object { private const val MUSIC_FOLDER_STORAGE_NAME = "music_folder" private const val INDEXES_STORAGE_NAME = "indexes" + private const val INDEXES_FOLDER_STORAGE_NAME = "indexes_folder" private const val ARTISTS_STORAGE_NAME = "artists" } } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt index ea3d77ef..7c2e530a 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt @@ -19,19 +19,26 @@ import org.moire.ultrasonic.domain.MusicFolder class SelectMusicFolderView( private val context: Context, root: ViewGroup, - private val musicFolders: List, - private var selectedFolderId: String?, - private val onUpdate: (String, String?) -> Unit + private val onUpdate: (String?) -> Unit ) : RecyclerView.ViewHolder( LayoutInflater.from(context).inflate( R.layout.select_folder_header, root, false ) ) { + private var musicFolders: List = mutableListOf() + private var selectedFolderId: String? = null private val folderName: TextView = itemView.findViewById(R.id.select_folder_name) private val layout: LinearLayout = itemView.findViewById(R.id.select_folder_header) private val MENU_GROUP_MUSIC_FOLDER = 10 init { + folderName.text = context.getString(R.string.select_artist_all_folders) + layout.setOnClickListener { onFolderClick() } + } + + fun setData(selectedId: String?, folders: List) { + selectedFolderId = selectedId + musicFolders = folders if (selectedFolderId != null) { for ((id, name) in musicFolders) { if (id == selectedFolderId) { @@ -42,7 +49,6 @@ class SelectMusicFolderView( } else { folderName.text = context.getString(R.string.select_artist_all_folders) } - layout.setOnClickListener { onFolderClick() } } private fun onFolderClick() { @@ -76,7 +82,7 @@ class SelectMusicFolderView( menuItem.isChecked = true folderName.text = musicFolderName - onUpdate(musicFolderName, selectedFolderId) + onUpdate(selectedFolderId) return true } From 268a41d1f4a3790cf832e3dc3cb3abf75ac73ae7 Mon Sep 17 00:00:00 2001 From: James Wells Date: Sat, 10 Apr 2021 17:48:52 -0400 Subject: [PATCH 5/9] Don't use musicFolderId in Recently Added filter Signed-off-by: James Wells --- .../org/moire/ultrasonic/fragment/SelectAlbumFragment.kt | 5 ++++- .../org/moire/ultrasonic/view/SelectMusicFolderView.kt | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt index 7a25a207..3e007898 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt @@ -820,8 +820,11 @@ class SelectAlbumFragment : Fragment() { } override fun load(service: MusicService): MusicDirectory { - val musicFolderId = + val musicFolderId = if (showSelectFolderHeader) { this@SelectAlbumFragment.activeServerProvider.getActiveServer().musicFolderId + } else { + null + } return if (Util.getShouldUseId3Tags(context)) service.getAlbumList2(albumListType, size, offset, musicFolderId, context) else diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt index 7c2e530a..28d34b2d 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/view/SelectMusicFolderView.kt @@ -14,7 +14,7 @@ import org.moire.ultrasonic.domain.MusicFolder /** * This little view shows the currently selected Folder (or catalog) on the music server. * When clicked it will drop down a list of all available Folders and allow you to - * select one. The intended usage us to supply a filter to lists of artists, albums, etc + * select one. The intended usage is to supply a filter to lists of artists, albums, etc */ class SelectMusicFolderView( private val context: Context, From 3a1e2c96fce5cc4f0e13cbdc625e539836a23ed2 Mon Sep 17 00:00:00 2001 From: James Wells Date: Sun, 11 Apr 2021 16:02:07 -0400 Subject: [PATCH 6/9] Don't show header when using ID3 tags Signed-off-by: James Wells --- .../kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt index 3e007898..5976a6d8 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt @@ -803,7 +803,7 @@ class SelectAlbumFragment : Fragment() { private fun getAlbumList(albumListType: String, albumListTitle: Int, size: Int, offset: Int) { showHeader = false - showSelectFolderHeader = !isOffline(context) && + showSelectFolderHeader = !isOffline(context) && !Util.getShouldUseId3Tags(context) && ( (albumListType == AlbumListType.SORTED_BY_NAME.toString()) || (albumListType == AlbumListType.SORTED_BY_ARTIST.toString()) From 38b6066258bbfbb89ba41a74aeaa6c2a904abdd2 Mon Sep 17 00:00:00 2001 From: James Wells Date: Tue, 13 Apr 2021 00:12:38 -0400 Subject: [PATCH 7/9] small change to view group Signed-off-by: James Wells --- .../kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt index 5976a6d8..063ec87b 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt @@ -138,7 +138,7 @@ class SelectAlbumFragment : Fragment() { ) selectFolderHeader = SelectMusicFolderView( - requireContext(), albumListView!!, + requireContext(), view as ViewGroup, { selectedFolderId -> if (!ActiveServerProvider.isOffline(context)) { val currentSetting = activeServerProvider.getActiveServer() From 39c94fe1e9805f8ca8a1288cebb4c722a9a71fa8 Mon Sep 17 00:00:00 2001 From: James Wells Date: Tue, 13 Apr 2021 22:35:06 -0400 Subject: [PATCH 8/9] Clean empty text view Signed-off-by: James Wells --- .../moire/ultrasonic/fragment/SelectAlbumFragment.kt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt index 063ec87b..413875f0 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt @@ -74,7 +74,7 @@ class SelectAlbumFragment : Fragment() { private var header: View? = null private var selectFolderHeader: SelectMusicFolderView? = null private var albumButtons: View? = null - private var emptyView: View? = null + private var emptyView: TextView? = null private var selectButton: ImageView? = null private var playNowButton: ImageView? = null private var playNextButton: ImageView? = null @@ -217,7 +217,7 @@ class SelectAlbumFragment : Fragment() { downloadButton = view.findViewById(R.id.select_album_download) deleteButton = view.findViewById(R.id.select_album_delete) moreButton = view.findViewById(R.id.select_album_more) - emptyView = view.findViewById(R.id.select_album_empty) + emptyView = TextView(requireContext()) selectButton!!.setOnClickListener( View.OnClickListener @@ -1118,7 +1118,13 @@ class SelectAlbumFragment : Fragment() { playAllButtonVisible = !(isAlbumList || entries.isEmpty()) && !allVideos shareButtonVisible = !isOffline(context) && songCount > 0 - emptyView!!.visibility = if (entries.isEmpty()) View.VISIBLE else View.GONE + if (entries.isEmpty()) { + emptyView!!.text = "No Media Found" + emptyView!!.setPadding(10, 10, 10, 10) + albumListView!!.addHeaderView(emptyView, null, false) + } else { + albumListView!!.removeHeaderView(emptyView!!) + } if (playAllButton != null) { playAllButton!!.isVisible = playAllButtonVisible From e5158c8a2f6c9c8c9ba681fb00ba91d834034962 Mon Sep 17 00:00:00 2001 From: James Wells Date: Wed, 14 Apr 2021 22:25:31 -0400 Subject: [PATCH 9/9] correct for swipe refresh Signed-off-by: James Wells --- .../org/moire/ultrasonic/fragment/SelectAlbumFragment.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt index 413875f0..6a9043aa 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SelectAlbumFragment.kt @@ -1118,12 +1118,11 @@ class SelectAlbumFragment : Fragment() { playAllButtonVisible = !(isAlbumList || entries.isEmpty()) && !allVideos shareButtonVisible = !isOffline(context) && songCount > 0 + albumListView!!.removeHeaderView(emptyView!!) if (entries.isEmpty()) { emptyView!!.text = "No Media Found" emptyView!!.setPadding(10, 10, 10, 10) albumListView!!.addHeaderView(emptyView, null, false) - } else { - albumListView!!.removeHeaderView(emptyView!!) } if (playAllButton != null) {