From 5eed437c5bc386fabd7bdbc42568a0d56897d6ca Mon Sep 17 00:00:00 2001 From: antonio Date: Fri, 6 Jan 2023 17:49:49 +0100 Subject: [PATCH] Added shortcuts to play top songs from user's favorite artists --- .../play/adapter/ArtistAdapter.java | 5 +- .../play/ui/fragment/HomeFragment.java | 53 +++++++++++++++--- .../play/ui/fragment/LibraryFragment.java | 2 +- .../play/ui/fragment/SearchFragment.java | 2 +- .../play/viewmodel/HomeViewModel.java | 25 +++++++-- app/src/main/res/layout/fragment_home.xml | 55 ++++++++++++++++--- app/src/main/res/values/strings.xml | 2 + 7 files changed, 120 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/ArtistAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/ArtistAdapter.java index 0a292236..8ed2f4dc 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/ArtistAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/ArtistAdapter.java @@ -37,13 +37,15 @@ public class ArtistAdapter extends RecyclerView.Adapter artists; - public ArtistAdapter(Context context, ClickCallback click, Boolean mix) { + public ArtistAdapter(Context context, ClickCallback click, Boolean mix, Boolean bestOf) { this.context = context; this.click = click; this.mix = mix; + this.bestOf = bestOf; this.artists = Collections.emptyList(); } @@ -124,6 +126,7 @@ public class ArtistAdapter extends RecyclerView.Adapter { + bind.radioArtistTextViewRefreshable.setOnLongClickListener(v -> { homeViewModel.refreshRadioArtistSample(getViewLifecycleOwner()); return true; }); + bind.bestOfArtistTextViewRefreshable.setOnLongClickListener(v -> { + homeViewModel.refreshBestOfArtist(getViewLifecycleOwner()); + return true; + }); + bind.starredTracksTextViewClickable.setOnClickListener(v -> { Bundle bundle = new Bundle(); bundle.putString(Media.STARRED, Media.STARRED); @@ -309,7 +314,7 @@ public class HomeFragment extends Fragment implements ClickCallback { bind.radioArtistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.radioArtistRecyclerView.setHasFixedSize(true); - radioArtistAdapter = new ArtistAdapter(requireContext(), this, true); + radioArtistAdapter = new ArtistAdapter(requireContext(), this, true, false); bind.radioArtistRecyclerView.setAdapter(radioArtistAdapter); homeViewModel.getStarredArtistsSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { if (artists == null) { @@ -330,6 +335,31 @@ public class HomeFragment extends Fragment implements ClickCallback { artistRadioSnapHelper.attachToRecyclerView(bind.radioArtistRecyclerView); } + private void initArtistBestOf() { + bind.bestOfArtistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); + bind.bestOfArtistRecyclerView.setHasFixedSize(true); + + bestOfArtistAdapter = new ArtistAdapter(requireContext(), this, false, true); + bind.bestOfArtistRecyclerView.setAdapter(bestOfArtistAdapter); + homeViewModel.getBestOfArtists(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { + if (artists == null) { + if (bind != null) + bind.homeBestOfArtistPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.homeBestOfArtistSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.homeBestOfArtistPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.homeBestOfArtistSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE); + + bestOfArtistAdapter.setItems(artists); + } + }); + + CustomLinearSnapHelper artistBestOfSnapHelper = new CustomLinearSnapHelper(); + artistBestOfSnapHelper.attachToRecyclerView(bind.bestOfArtistRecyclerView); + } + private void initStarredTracksView() { bind.starredTracksRecyclerView.setHasFixedSize(true); @@ -717,7 +747,7 @@ public class HomeFragment extends Fragment implements ClickCallback { if (mediaBrowserListenableFuture != null) { homeViewModel.getMediaInstantMix(getViewLifecycleOwner(), bundle.getParcelable("song_object")).observe(getViewLifecycleOwner(), songs -> { if (songs.size() > 0) { - MediaManager.enqueue(mediaBrowserListenableFuture, requireContext(), (ArrayList) songs, true); + MediaManager.enqueue(mediaBrowserListenableFuture, requireContext(), songs, true); } }); } @@ -754,9 +784,18 @@ public class HomeFragment extends Fragment implements ClickCallback { .show(); if (mediaBrowserListenableFuture != null) { - homeViewModel.getArtistInstantMix(getViewLifecycleOwner(), bundle.getParcelable("artist_object")).observe(getViewLifecycleOwner(), songs -> { + homeViewModel.getArtistInstantMix(bundle.getParcelable("artist_object")).observe(getViewLifecycleOwner(), songs -> { if (songs.size() > 0) { - MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), (ArrayList) songs, 0); + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), songs, 0); + activity.setBottomSheetInPeek(true); + } + }); + } + } else if (bundle.containsKey("is_best_of") && bundle.getBoolean("is_best_of")) { + if (mediaBrowserListenableFuture != null) { + homeViewModel.getArtistBestOf(bundle.getParcelable("artist_object")).observe(getViewLifecycleOwner(), songs -> { + if (songs.size() > 0) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), songs, 0); activity.setBottomSheetInPeek(true); } }); diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LibraryFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LibraryFragment.java index fb16fc85..6b2a3630 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LibraryFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LibraryFragment.java @@ -169,7 +169,7 @@ public class LibraryFragment extends Fragment implements ClickCallback { bind.artistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.artistRecyclerView.setHasFixedSize(true); - artistAdapter = new ArtistAdapter(requireContext(), this, false); + artistAdapter = new ArtistAdapter(requireContext(), this, false, false); bind.artistRecyclerView.setAdapter(artistAdapter); libraryViewModel.getArtistSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { if (artists == null) { diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java index 84f26580..c01c992f 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SearchFragment.java @@ -90,7 +90,7 @@ public class SearchFragment extends Fragment implements ClickCallback { bind.searchResultArtistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.searchResultArtistRecyclerView.setHasFixedSize(true); - artistAdapter = new ArtistAdapter(requireContext(), this, false); + artistAdapter = new ArtistAdapter(requireContext(), this, false, false); bind.searchResultArtistRecyclerView.setAdapter(artistAdapter); CustomLinearSnapHelper artistSnapHelper = new CustomLinearSnapHelper(); diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/HomeViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/HomeViewModel.java index eebe2351..f602a6e3 100644 --- a/app/src/main/java/com/cappielloantonio/play/viewmodel/HomeViewModel.java +++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/HomeViewModel.java @@ -22,6 +22,7 @@ import com.cappielloantonio.play.repository.PodcastRepository; import com.cappielloantonio.play.repository.SongRepository; import com.cappielloantonio.play.util.PreferenceUtil; +import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; @@ -41,6 +42,7 @@ public class HomeViewModel extends AndroidViewModel { private final MutableLiveData> newReleasedAlbum = new MutableLiveData<>(null); private final MutableLiveData> starredTracksSample = new MutableLiveData<>(null); private final MutableLiveData> starredArtistsSample = new MutableLiveData<>(null); + private final MutableLiveData> bestOfArtists = new MutableLiveData<>(null); private final MutableLiveData> starredTracks = new MutableLiveData<>(null); private final MutableLiveData> starredAlbums = new MutableLiveData<>(null); private final MutableLiveData> starredArtists = new MutableLiveData<>(null); @@ -54,6 +56,7 @@ public class HomeViewModel extends AndroidViewModel { private final MutableLiveData> thisGridTopSong = new MutableLiveData<>(null); private final MutableLiveData> mediaInstantMix = new MutableLiveData<>(null); private final MutableLiveData> artistInstantMix = new MutableLiveData<>(null); + private final MutableLiveData> artistBestOf = new MutableLiveData<>(null); public HomeViewModel(@NonNull Application application) { super(application); @@ -118,6 +121,14 @@ public class HomeViewModel extends AndroidViewModel { return starredArtistsSample; } + public LiveData> getBestOfArtists(LifecycleOwner owner) { + if (bestOfArtists.getValue() == null) { + artistRepository.getStarredArtists(true, 20).observe(owner, bestOfArtists::postValue); + } + + return bestOfArtists; + } + public LiveData> getStarredTracks(LifecycleOwner owner) { if (starredTracks.getValue() == null) { songRepository.getStarredSongs(true, 20).observe(owner, starredTracks::postValue); @@ -204,12 +215,12 @@ public class HomeViewModel extends AndroidViewModel { return mediaInstantMix; } - public LiveData> getArtistInstantMix(LifecycleOwner owner, Artist artist) { - artistInstantMix.setValue(Collections.emptyList()); + public LiveData> getArtistInstantMix(Artist artist) { + return artistRepository.getInstantMix(artist, 20); + } - artistRepository.getInstantMix(artist, 20).observe(owner, artistInstantMix::postValue); - - return artistInstantMix; + public LiveData> getArtistBestOf(Artist artist) { + return artistRepository.getTopSongs(artist.getName(), 10); } public void refreshDiscoverySongSample(LifecycleOwner owner) { @@ -224,6 +235,10 @@ public class HomeViewModel extends AndroidViewModel { artistRepository.getStarredArtists(true, 10).observe(owner, starredArtistsSample::postValue); } + public void refreshBestOfArtist(LifecycleOwner owner) { + artistRepository.getStarredArtists(true, 20).observe(owner, bestOfArtists::postValue); + } + public void refreshStarredTracks(LifecycleOwner owner) { songRepository.getStarredSongs(true, 20).observe(owner, starredTracks::postValue); } diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 4b88f988..851e13f6 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -129,6 +129,51 @@ layout="@layout/item_placeholder_album" android:visibility="gone" /> + + + + + + + + + + + + - - - - - - - - See all Radio stations New releases + Best of + Top songs of your favorite artists Newest podcasts Searching... Go to channel