From 754fc69eab0bfb0ecdbfafddf32e2255e6128887 Mon Sep 17 00:00:00 2001 From: antonio Date: Wed, 4 Jan 2023 09:14:15 +0100 Subject: [PATCH] Refactoring - Removed most of the click listeners from the adapters and moved them into the appropriate fragments --- .../play/adapter/AlbumAdapter.java | 46 +++--- .../AlbumArtistPageOrSimilarAdapter.java | 39 +++-- .../play/adapter/AlbumCatalogueAdapter.java | 50 +++---- .../play/adapter/AlbumHorizontalAdapter.java | 60 +++----- .../play/adapter/ArtistAdapter.java | 92 ++++-------- .../play/adapter/ArtistCatalogueAdapter.java | 51 +++---- .../play/adapter/ArtistHorizontalAdapter.java | 58 +++----- .../play/adapter/ArtistSimilarAdapter.java | 30 +++- .../play/adapter/DiscoverSongAdapter.java | 56 ++----- .../play/adapter/GenreAdapter.java | 42 +++--- .../play/adapter/GenreCatalogueAdapter.java | 47 +++--- .../play/adapter/GridTrackAdapter.java | 44 +++--- .../play/adapter/PlayerSongQueueAdapter.java | 37 ++--- .../play/adapter/PlaylistAdapter.java | 122 --------------- .../PlaylistDialogHorizontalAdapter.java | 38 +++-- .../PlaylistDialogSongHorizontalAdapter.java | 11 +- .../adapter/PlaylistHorizontalAdapter.java | 57 ++----- .../play/adapter/PodcastEpisodeAdapter.java | 53 +++---- .../play/adapter/ServerAdapter.java | 86 +++-------- .../play/adapter/SimilarTrackAdapter.java | 72 +++------ .../play/adapter/SongHorizontalAdapter.java | 56 +++---- .../play/adapter/YearAdapter.java | 42 +++--- .../play/interfaces/ClickCallback.java | 34 +++++ .../play/model/Chronology.java | 72 ++++++++- .../play/repository/ArtistRepository.java | 14 +- .../play/repository/SongRepository.java | 18 +-- .../play/ui/dialog/PlaylistChooserDialog.java | 15 +- .../play/ui/dialog/PlaylistEditorDialog.java | 2 - .../ui/fragment/AlbumCatalogueFragment.java | 19 ++- .../ui/fragment/AlbumListPageFragment.java | 18 ++- .../play/ui/fragment/AlbumPageFragment.java | 28 ++-- .../ui/fragment/ArtistCatalogueFragment.java | 19 ++- .../ui/fragment/ArtistListPageFragment.java | 18 ++- .../play/ui/fragment/ArtistPageFragment.java | 90 +++++++----- .../play/ui/fragment/DownloadFragment.java | 61 ++++++-- .../ui/fragment/GenreCatalogueFragment.java | 22 ++- .../play/ui/fragment/HomeFragment.java | 139 +++++++++++++----- .../play/ui/fragment/LibraryFragment.java | 93 +++++++++--- .../play/ui/fragment/LoginFragment.java | 62 +++++++- .../play/ui/fragment/PlayerCoverFragment.java | 27 +--- .../play/ui/fragment/PlayerQueueFragment.java | 15 +- .../fragment/PlaylistCatalogueFragment.java | 26 +++- .../ui/fragment/PlaylistPageFragment.java | 27 ++-- .../play/ui/fragment/SearchFragment.java | 49 ++++-- .../ui/fragment/SongListPageFragment.java | 45 +++--- .../AlbumBottomSheetDialog.java | 11 +- .../ArtistBottomSheetDialog.java | 26 ++-- .../PodcastBottomSheetDialog.java | 6 +- .../SongBottomSheetDialog.java | 18 +-- .../play/viewmodel/HomeViewModel.java | 18 +++ .../viewmodel/PlayerBottomSheetViewModel.java | 11 ++ .../viewmodel/SongBottomSheetViewModel.java | 17 +++ .../main/res/layout/item_library_playlist.xml | 56 ------- .../res/layout/item_player_queue_song.xml | 15 +- 54 files changed, 1143 insertions(+), 1137 deletions(-) delete mode 100644 app/src/main/java/com/cappielloantonio/play/adapter/PlaylistAdapter.java create mode 100644 app/src/main/java/com/cappielloantonio/play/interfaces/ClickCallback.java delete mode 100644 app/src/main/res/layout/item_library_playlist.xml diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/AlbumAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/AlbumAdapter.java index 7fdb4022..2d045388 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/AlbumAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/AlbumAdapter.java @@ -9,38 +9,36 @@ import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.navigation.Navigation; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.util.MusicUtil; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Objects; public class AlbumAdapter extends RecyclerView.Adapter { - private static final String TAG = "AlbumAdapter"; - - private final LayoutInflater inflater; private final Context context; + private final ClickCallback click; private List albums; - public AlbumAdapter(Context context) { + public AlbumAdapter(Context context, ClickCallback click) { this.context = context; - this.inflater = LayoutInflater.from(context); - this.albums = new ArrayList<>(); + this.click = click; + this.albums = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = inflater.inflate(R.layout.item_library_album, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_library_album, parent, false); return new ViewHolder(view); } @@ -72,7 +70,7 @@ public class AlbumAdapter extends RecyclerView.Adapter notifyDataSetChanged(); } - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { + public class ViewHolder extends RecyclerView.ViewHolder { TextView textAlbumName; TextView textArtistName; ImageView cover; @@ -84,36 +82,28 @@ public class AlbumAdapter extends RecyclerView.Adapter textArtistName = itemView.findViewById(R.id.artist_name_label); cover = itemView.findViewById(R.id.album_cover_image_view); - itemView.setOnClickListener(this); - itemView.setOnLongClickListener(this); - textAlbumName.setSelected(true); textArtistName.setSelected(true); + + itemView.setOnClickListener(v -> onClick()); + itemView.setOnLongClickListener(v -> onLongClick()); } - @Override - public void onClick(View view) { + private void onClick() { Bundle bundle = new Bundle(); bundle.putParcelable("album_object", albums.get(getBindingAdapterPosition())); bundle.putBoolean("is_offline", false); - if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.searchFragment) { - Navigation.findNavController(view).navigate(R.id.action_searchFragment_to_albumPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.libraryFragment) { - Navigation.findNavController(view).navigate(R.id.action_libraryFragment_to_albumPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.albumCatalogueFragment) { - Navigation.findNavController(view).navigate(R.id.action_albumCatalogueFragment_to_albumPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.homeFragment) { - Navigation.findNavController(view).navigate(R.id.action_homeFragment_to_albumPageFragment, bundle); - } + click.onAlbumClick(bundle); } - @Override - public boolean onLongClick(View v) { + private boolean onLongClick() { Bundle bundle = new Bundle(); bundle.putParcelable("album_object", albums.get(getBindingAdapterPosition())); - Navigation.findNavController(v).navigate(R.id.albumBottomSheetDialog, bundle); - return true; + + click.onAlbumLongClick(bundle); + + return false; } } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/AlbumArtistPageOrSimilarAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/AlbumArtistPageOrSimilarAdapter.java index 0d2b2233..bf7f1cda 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/AlbumArtistPageOrSimilarAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/AlbumArtistPageOrSimilarAdapter.java @@ -9,37 +9,35 @@ import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.navigation.Navigation; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.util.MusicUtil; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class AlbumArtistPageOrSimilarAdapter extends RecyclerView.Adapter { - private static final String TAG = "AlbumArtistPageAdapter"; - - private final LayoutInflater inflater; private final Context context; + private final ClickCallback click; private List albums; - public AlbumArtistPageOrSimilarAdapter(Context context) { + public AlbumArtistPageOrSimilarAdapter(Context context, ClickCallback click) { this.context = context; - this.inflater = LayoutInflater.from(context); - this.albums = new ArrayList<>(); + this.click = click; + this.albums = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = inflater.inflate(R.layout.item_library_artist_page_or_similar_album, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_library_artist_page_or_similar_album, parent, false); return new ViewHolder(view); } @@ -71,7 +69,7 @@ public class AlbumArtistPageOrSimilarAdapter extends RecyclerView.Adapter onClick()); + itemView.setOnLongClickListener(v -> onLongClick()); } - @Override - public void onClick(View view) { + private void onClick() { Bundle bundle = new Bundle(); bundle.putParcelable("album_object", albums.get(getBindingAdapterPosition())); bundle.putBoolean("is_offline", false); - Navigation.findNavController(view).navigate(R.id.albumPageFragment, bundle); + + click.onAlbumClick(bundle); } - @Override - public boolean onLongClick(View view) { + private boolean onLongClick() { Bundle bundle = new Bundle(); bundle.putParcelable("album_object", albums.get(getBindingAdapterPosition())); - Navigation.findNavController(view).navigate(R.id.albumBottomSheetDialog, bundle); - return true; + + click.onAlbumLongClick(bundle); + + return false; } } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/AlbumCatalogueAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/AlbumCatalogueAdapter.java index ee98a66e..48a50392 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/AlbumCatalogueAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/AlbumCatalogueAdapter.java @@ -5,36 +5,30 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; import android.widget.Filter; import android.widget.Filterable; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.navigation.Navigation; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Album; -import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.util.MusicUtil; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; -import java.util.Objects; public class AlbumCatalogueAdapter extends RecyclerView.Adapter implements Filterable { - private static final String TAG = "AlbumCatalogueAdapter"; - - private final LayoutInflater inflater; - private final MainActivity activity; private final Context context; + private final ClickCallback click; private final Filter filtering = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { @@ -69,17 +63,16 @@ public class AlbumCatalogueAdapter extends RecyclerView.Adapter albums; private List albumsFull; - public AlbumCatalogueAdapter(MainActivity activity, Context context) { - this.activity = activity; + public AlbumCatalogueAdapter(Context context, ClickCallback click) { this.context = context; - this.inflater = LayoutInflater.from(context); - this.albums = new ArrayList<>(); + this.click = click; + this.albums = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = inflater.inflate(R.layout.item_library_catalogue_album, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_library_catalogue_album, parent, false); return new ViewHolder(view); } @@ -127,7 +120,7 @@ public class AlbumCatalogueAdapter extends RecyclerView.Adapter onClick()); + itemView.setOnLongClickListener(v -> onLongClick()); } - @Override - public void onClick(View view) { + private void onClick() { Bundle bundle = new Bundle(); bundle.putParcelable("album_object", albums.get(getBindingAdapterPosition())); bundle.putBoolean("is_offline", false); - if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.searchFragment) { - Navigation.findNavController(view).navigate(R.id.action_searchFragment_to_albumPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.libraryFragment) { - Navigation.findNavController(view).navigate(R.id.action_libraryFragment_to_albumPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.albumCatalogueFragment) { - Navigation.findNavController(view).navigate(R.id.action_albumCatalogueFragment_to_albumPageFragment, bundle); - } - - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + click.onAlbumClick(bundle); } - @Override - public boolean onLongClick(View v) { + private boolean onLongClick() { Bundle bundle = new Bundle(); bundle.putParcelable("album_object", albums.get(getBindingAdapterPosition())); - Navigation.findNavController(v).navigate(R.id.albumBottomSheetDialog, bundle); - return true; + + click.onAlbumLongClick(bundle); + + return false; } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/AlbumHorizontalAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/AlbumHorizontalAdapter.java index 9ac929b6..75edfeec 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/AlbumHorizontalAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/AlbumHorizontalAdapter.java @@ -9,39 +9,37 @@ import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.navigation.Navigation; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.util.MusicUtil; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Objects; public class AlbumHorizontalAdapter extends RecyclerView.Adapter { - private static final String TAG = "AlbumHorizontalAdapter"; - - private List albums; - private final LayoutInflater mInflater; private final Context context; + private final ClickCallback click; private final boolean isOffline; - public AlbumHorizontalAdapter(Context context, boolean isOffline) { + private List albums; + + public AlbumHorizontalAdapter(Context context, ClickCallback click, boolean isOffline) { this.context = context; - this.mInflater = LayoutInflater.from(context); - this.albums = new ArrayList<>(); + this.click = click; this.isOffline = isOffline; + this.albums = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_horizontal_album, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_horizontal_album, parent, false); return new ViewHolder(view); } @@ -73,7 +71,7 @@ public class AlbumHorizontalAdapter extends RecyclerView.Adapter onClick()); + itemView.setOnLongClickListener(v -> onLongClick()); + + more.setOnClickListener(v -> onLongClick()); } - @Override - public void onClick(View view) { + private void onClick() { Bundle bundle = new Bundle(); bundle.putParcelable("album_object", albums.get(getBindingAdapterPosition())); - bundle.putBoolean("is_offline", isOffline); + bundle.putBoolean("is_offline", false); - if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.homeFragment) { - Navigation.findNavController(view).navigate(R.id.action_homeFragment_to_albumPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.albumListPageFragment) { - Navigation.findNavController(view).navigate(R.id.action_albumListPageFragment_to_albumPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.downloadFragment) { - Navigation.findNavController(view).navigate(R.id.action_downloadFragment_to_albumPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.libraryFragment) { - Navigation.findNavController(view).navigate(R.id.action_libraryFragment_to_albumPageFragment, bundle); - } + click.onAlbumClick(bundle); } - @Override - public boolean onLongClick(View v) { - openMore(v); - return true; - } - - private void openMore(View view) { + private boolean onLongClick() { Bundle bundle = new Bundle(); bundle.putParcelable("album_object", albums.get(getBindingAdapterPosition())); - Navigation.findNavController(view).navigate(R.id.albumBottomSheetDialog, bundle); + + click.onAlbumLongClick(bundle); + + return false; } } } 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 d956d1f0..0a292236 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/ArtistAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/ArtistAdapter.java @@ -2,17 +2,16 @@ package com.cappielloantonio.play.adapter; import android.content.Context; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.Observer; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.navigation.Navigation; import androidx.recyclerview.widget.RecyclerView; @@ -22,42 +21,36 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.cappielloantonio.play.App; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; -import com.cappielloantonio.play.interfaces.MediaCallback; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Artist; -import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.repository.ArtistRepository; -import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.util.MusicUtil; -import com.google.android.material.snackbar.Snackbar; import com.google.common.util.concurrent.ListenableFuture; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; +@UnstableApi public class ArtistAdapter extends RecyclerView.Adapter { - private static final String TAG = "ArtistAdapter"; - - private final LayoutInflater inflater; - private final MainActivity mainActivity; private final Context context; + private final ClickCallback click; + private final boolean mix; private List artists; - private ListenableFuture mediaBrowserListenableFuture; - - public ArtistAdapter(MainActivity mainActivity, Context context) { - this.mainActivity = mainActivity; + public ArtistAdapter(Context context, ClickCallback click, Boolean mix) { this.context = context; - this.inflater = LayoutInflater.from(context); - this.artists = new ArrayList<>(); + this.click = click; + this.mix = mix; + this.artists = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = inflater.inflate(R.layout.item_library_artist, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_library_artist, parent, false); return new ViewHolder(view); } @@ -94,10 +87,6 @@ public class ArtistAdapter extends RecyclerView.Adapter mediaBrowserListenableFuture) { - this.mediaBrowserListenableFuture = mediaBrowserListenableFuture; - } - private void setArtistCover(Artist artist, ImageView cover) { ArtistRepository artistRepository = new ArtistRepository(App.getInstance()); LiveData livedata = artistRepository.getArtistFullInfo(artist.getId()); @@ -115,7 +104,7 @@ public class ArtistAdapter extends RecyclerView.Adapter onClick()); + itemView.setOnLongClickListener(v -> onLongClick()); } - @Override - public void onClick(View view) { + public void onClick() { + Bundle bundle = new Bundle(); + bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition())); + bundle.putBoolean("is_mix", mix); + + click.onArtistClick(bundle); + } + + public boolean onLongClick() { Bundle bundle = new Bundle(); bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition())); - if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.searchFragment) { - Navigation.findNavController(view).navigate(R.id.action_searchFragment_to_artistPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.libraryFragment) { - Navigation.findNavController(view).navigate(R.id.action_libraryFragment_to_artistPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.artistCatalogueFragment) { - Navigation.findNavController(view).navigate(R.id.action_artistCatalogueFragment_to_artistPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.homeFragment) { - Snackbar.make(mainActivity.bind.getRoot(), R.string.artist_adapter_radio_station_starting, Snackbar.LENGTH_LONG) - .setAnchorView(mainActivity.bind.playerBottomSheet) - .show(); + click.onArtistLongClick(bundle); - if (mediaBrowserListenableFuture != null) { - ArtistRepository artistRepository = new ArtistRepository(App.getInstance()); - artistRepository.getInstantMix(artists.get(getBindingAdapterPosition()), 20, new MediaCallback() { - @Override - public void onError(Exception exception) { - Log.e(TAG, "onError() " + exception.getMessage()); - } - - @Override - public void onLoadMedia(List media) { - if (media.size() > 0) { - MediaManager.startQueue(mediaBrowserListenableFuture, context, (ArrayList) media, 0); - mainActivity.setBottomSheetInPeek(true); - } else { - Toast.makeText(context, context.getString(R.string.artist_error_retrieving_radio), Toast.LENGTH_SHORT).show(); - } - } - }); - } - } - } - - @Override - public boolean onLongClick(View v) { - Bundle bundle = new Bundle(); - bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition())); - Navigation.findNavController(v).navigate(R.id.artistBottomSheetDialog, bundle); - return true; + return false; } } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/ArtistCatalogueAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/ArtistCatalogueAdapter.java index 0c99a744..540f20e4 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/ArtistCatalogueAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/ArtistCatalogueAdapter.java @@ -5,7 +5,6 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; import android.widget.Filter; import android.widget.Filterable; import android.widget.ImageView; @@ -14,29 +13,25 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.Observer; -import androidx.navigation.Navigation; import androidx.recyclerview.widget.RecyclerView; import com.cappielloantonio.play.App; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.repository.ArtistRepository; -import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.util.MusicUtil; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; -import java.util.Objects; public class ArtistCatalogueAdapter extends RecyclerView.Adapter implements Filterable { - private static final String TAG = "ArtistCatalogueAdapter"; - - private final LayoutInflater inflater; - private final MainActivity activity; private final Context context; + private final ClickCallback click; + private final Filter filtering = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { @@ -71,17 +66,16 @@ public class ArtistCatalogueAdapter extends RecyclerView.Adapter artists; private List artistFull; - public ArtistCatalogueAdapter(MainActivity activity, Context context) { - this.activity = activity; + public ArtistCatalogueAdapter(Context context, ClickCallback click) { this.context = context; - this.inflater = LayoutInflater.from(context); - this.artists = new ArrayList<>(); + this.click = click; + this.artists = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = inflater.inflate(R.layout.item_library_catalogue_artist, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_library_catalogue_artist, parent, false); return new ViewHolder(view); } @@ -145,7 +139,7 @@ public class ArtistCatalogueAdapter extends RecyclerView.Adapter onClick()); + itemView.setOnLongClickListener(v -> onLongClick()); } - @Override - public void onClick(View view) { + public void onClick() { Bundle bundle = new Bundle(); bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition())); - if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.searchFragment) { - Navigation.findNavController(view).navigate(R.id.action_searchFragment_to_artistPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.libraryFragment) { - Navigation.findNavController(view).navigate(R.id.action_libraryFragment_to_artistPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.artistCatalogueFragment) { - Navigation.findNavController(view).navigate(R.id.action_artistCatalogueFragment_to_artistPageFragment, bundle); - } - - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + click.onArtistClick(bundle); } - @Override - public boolean onLongClick(View v) { + public boolean onLongClick() { Bundle bundle = new Bundle(); bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition())); - Navigation.findNavController(v).navigate(R.id.artistBottomSheetDialog, bundle); - return true; + + click.onArtistLongClick(bundle); + + return false; } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/ArtistHorizontalAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/ArtistHorizontalAdapter.java index 4f793545..efc1e0c2 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/ArtistHorizontalAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/ArtistHorizontalAdapter.java @@ -11,7 +11,6 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; import androidx.lifecycle.Observer; -import androidx.navigation.Navigation; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.load.resource.bitmap.CenterCrop; @@ -19,33 +18,30 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.cappielloantonio.play.App; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.repository.ArtistRepository; import com.cappielloantonio.play.util.MusicUtil; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Objects; public class ArtistHorizontalAdapter extends RecyclerView.Adapter { - private static final String TAG = "ArtistHorizontalAdapter"; + private final Context context; + private final ClickCallback click; private List artists; - private final LayoutInflater mInflater; - private final Context context; - private final boolean isDownloaded; - public ArtistHorizontalAdapter(Context context, boolean isDownloaded) { + public ArtistHorizontalAdapter(Context context, ClickCallback click) { this.context = context; - this.mInflater = LayoutInflater.from(context); - this.artists = new ArrayList<>(); - this.isDownloaded = isDownloaded; + this.click = click; + this.artists = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_horizontal_artist, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_horizontal_artist, parent, false); return new ViewHolder(view); } @@ -110,7 +106,7 @@ public class ArtistHorizontalAdapter extends RecyclerView.Adapter onClick()); + itemView.setOnLongClickListener(v -> onLongClick()); + + more.setOnClickListener(v -> onLongClick()); } - @Override - public void onClick(View view) { + private void onClick() { Bundle bundle = new Bundle(); bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition())); - if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.homeFragment) { - Navigation.findNavController(view).navigate(R.id.action_homeFragment_to_artistPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.artistListPageFragment) { - if (!isDownloaded) - Navigation.findNavController(view).navigate(R.id.action_artistListPageFragment_to_artistPageFragment, bundle); - else - Navigation.findNavController(view).navigate(R.id.action_artistListPageFragment_to_albumListPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.downloadFragment) { - Navigation.findNavController(view).navigate(R.id.action_downloadFragment_to_albumListPageFragment, bundle); - } + click.onArtistClick(bundle); } - @Override - public boolean onLongClick(View v) { - openMore(v); - return true; - } - - private void openMore(View view) { + public boolean onLongClick() { Bundle bundle = new Bundle(); bundle.putParcelable("artist_object", artists.get(getBindingAdapterPosition())); - Navigation.findNavController(view).navigate(R.id.artistBottomSheetDialog, bundle); + + click.onArtistLongClick(bundle); + + return false; } } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/ArtistSimilarAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/ArtistSimilarAdapter.java index ab792f72..b330993f 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/ArtistSimilarAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/ArtistSimilarAdapter.java @@ -20,31 +20,31 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.cappielloantonio.play.App; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.repository.ArtistRepository; import com.cappielloantonio.play.util.MusicUtil; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class ArtistSimilarAdapter extends RecyclerView.Adapter { - private static final String TAG = "AlbumArtistPageAdapter"; - - private final LayoutInflater inflater; private final Context context; + private final ClickCallback click; private List artists; - public ArtistSimilarAdapter(Context context) { + public ArtistSimilarAdapter(Context context, ClickCallback click) { this.context = context; - this.inflater = LayoutInflater.from(context); - this.artists = new ArrayList<>(); + this.click = click; + this.artists = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = inflater.inflate(R.layout.item_library_similar_artist, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_library_similar_artist, parent, false); return new ViewHolder(view); } @@ -133,5 +133,21 @@ public class ArtistSimilarAdapter extends RecyclerView.Adapter { - private static final String TAG = "DiscoverSongAdapter"; - - private final LayoutInflater inflater; private final Context context; - private final MainActivity activity; - private ListenableFuture mediaBrowserListenableFuture; + private final ClickCallback click; private List songs; - public DiscoverSongAdapter(MainActivity activity, Context context) { - this.activity = activity; + public DiscoverSongAdapter(Context context, ClickCallback click) { this.context = context; - this.inflater = LayoutInflater.from(context); - this.songs = new ArrayList<>(); + this.click = click; + this.songs = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = inflater.inflate(R.layout.item_home_discover_song, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_home_discover_song, parent, false); return new ViewHolder(view); } @@ -80,11 +69,7 @@ public class DiscoverSongAdapter extends RecyclerView.Adapter mediaBrowserListenableFuture) { - this.mediaBrowserListenableFuture = mediaBrowserListenableFuture; - } - - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + public class ViewHolder extends RecyclerView.ViewHolder { TextView textTitle; TextView textAlbum; ImageView cover; @@ -96,26 +81,15 @@ public class DiscoverSongAdapter extends RecyclerView.Adapter onClick()); } - @Override - public void onClick(View view) { - MediaManager.startQueue(mediaBrowserListenableFuture, context, songs.get(getBindingAdapterPosition())); - activity.setBottomSheetInPeek(true); + public void onClick() { + Bundle bundle = new Bundle(); + bundle.putParcelable("song_object", songs.get(getBindingAdapterPosition())); + bundle.putBoolean("is_mix", true); - SongRepository songRepository = new SongRepository(App.getInstance()); - songRepository.getInstantMix(songs.get(getBindingAdapterPosition()), 20, new MediaCallback() { - @Override - public void onError(Exception exception) { - Log.e(TAG, "onError() " + exception.getMessage()); - } - - @Override - public void onLoadMedia(List media) { - MediaManager.enqueue(mediaBrowserListenableFuture, context, (List) media,false); - } - }); + click.onMediaClick(bundle); } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/GenreAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/GenreAdapter.java index ab49ed66..d5f1e874 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/GenreAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/GenreAdapter.java @@ -1,6 +1,7 @@ package com.cappielloantonio.play.adapter; import android.content.Context; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -10,29 +11,30 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.cappielloantonio.play.R; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Genre; +import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.util.MusicUtil; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class GenreAdapter extends RecyclerView.Adapter { - private static final String TAG = "GenreAdapter"; - - private final LayoutInflater mInflater; + private final Context context; + private ClickCallback click; private List genres; - private ItemClickListener itemClickListener; - public GenreAdapter(Context context) { - this.mInflater = LayoutInflater.from(context); - this.genres = new ArrayList<>(); + public GenreAdapter(Context context, ClickCallback click) { + this.context = context; + this.click = click; + this.genres = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_library_genre, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_library_genre, parent, false); return new ViewHolder(view); } @@ -57,15 +59,7 @@ public class GenreAdapter extends RecyclerView.Adapter notifyDataSetChanged(); } - public void setClickListener(ItemClickListener itemClickListener) { - this.itemClickListener = itemClickListener; - } - - public interface ItemClickListener { - void onItemClick(View view, int position); - } - - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + public class ViewHolder extends RecyclerView.ViewHolder { TextView textGenre; ViewHolder(View itemView) { @@ -73,13 +67,15 @@ public class GenreAdapter extends RecyclerView.Adapter textGenre = itemView.findViewById(R.id.genre_label); - itemView.setOnClickListener(this); + itemView.setOnClickListener(v -> onClick()); } - @Override - public void onClick(View view) { - if (itemClickListener != null) - itemClickListener.onItemClick(view, getBindingAdapterPosition()); + private void onClick() { + Bundle bundle = new Bundle(); + bundle.putString(Media.BY_GENRE, Media.BY_GENRE); + bundle.putParcelable("genre_object", genres.get(getBindingAdapterPosition())); + + click.onGenreClick(bundle); } } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/GenreCatalogueAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/GenreCatalogueAdapter.java index 294dec0b..c38aa699 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/GenreCatalogueAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/GenreCatalogueAdapter.java @@ -1,10 +1,10 @@ package com.cappielloantonio.play.adapter; import android.content.Context; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; import android.widget.Filter; import android.widget.Filterable; import android.widget.TextView; @@ -13,8 +13,9 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.cappielloantonio.play.R; -import com.cappielloantonio.play.model.Artist; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Genre; +import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.util.MusicUtil; @@ -24,10 +25,9 @@ import java.util.Comparator; import java.util.List; public class GenreCatalogueAdapter extends RecyclerView.Adapter implements Filterable { - private static final String TAG = "GenreCatalogueAdapter"; + private final Context context; + private final ClickCallback click; - private final LayoutInflater mInflater; - private final MainActivity activity; private final Filter filtering = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { @@ -61,18 +61,17 @@ public class GenreCatalogueAdapter extends RecyclerView.Adapter genres; private List genresFull; - private ItemClickListener itemClickListener; - public GenreCatalogueAdapter(MainActivity activity, Context context) { - this.activity = activity; - this.mInflater = LayoutInflater.from(context); - this.genres = new ArrayList<>(); + public GenreCatalogueAdapter(Context context, ClickCallback click) { + this.context = context; + this.click = click; + this.genres = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_library_catalogue_genre, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_library_catalogue_genre, parent, false); return new ViewHolder(view); } @@ -98,20 +97,12 @@ public class GenreCatalogueAdapter extends RecyclerView.Adapter { + Bundle bundle = new Bundle(); + bundle.putString(Media.BY_GENRE, Media.BY_GENRE); + bundle.putParcelable("genre_object", genres.get(getBindingAdapterPosition())); - @Override - public void onClick(View view) { - if (itemClickListener != null) { - itemClickListener.onItemClick(view, getBindingAdapterPosition()); - - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(view.getWindowToken(), 0); - } + click.onGenreClick(bundle); + }); } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/GridTrackAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/GridTrackAdapter.java index 0b604705..f512143d 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/GridTrackAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/GridTrackAdapter.java @@ -1,50 +1,42 @@ package com.cappielloantonio.play.adapter; import android.content.Context; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import androidx.annotation.NonNull; -import androidx.media3.session.MediaBrowser; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Chronology; -import com.cappielloantonio.play.model.Media; -import com.cappielloantonio.play.service.MediaManager; -import com.cappielloantonio.play.ui.activity.MainActivity; -import com.cappielloantonio.play.util.MappingUtil; -import com.google.common.util.concurrent.ListenableFuture; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class GridTrackAdapter extends RecyclerView.Adapter { - private static final String TAG = "SimilarTrackAdapter"; - - private final MainActivity activity; private final Context context; - private final LayoutInflater mInflater; + private final ClickCallback click; - private ListenableFuture mediaBrowserListenableFuture; private List items; - public GridTrackAdapter(MainActivity activity, Context context) { - this.activity = activity; + public GridTrackAdapter(Context context, ClickCallback click) { this.context = context; - this.mInflater = LayoutInflater.from(context); - this.items = new ArrayList<>(); + this.click = click; + this.items = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_home_grid_track, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_home_grid_track, parent, false); return new ViewHolder(view); } @@ -73,11 +65,7 @@ public class GridTrackAdapter extends RecyclerView.Adapter mediaBrowserListenableFuture) { - this.mediaBrowserListenableFuture = mediaBrowserListenableFuture; - } - - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + public class ViewHolder extends RecyclerView.ViewHolder { ImageView cover; ViewHolder(View itemView) { @@ -85,14 +73,16 @@ public class GridTrackAdapter extends RecyclerView.Adapter onClick()); } - @Override - public void onClick(View view) { - List media = MappingUtil.mapChronology(items); - MediaManager.startQueue(mediaBrowserListenableFuture, context, media, getBindingAdapterPosition()); - activity.setBottomSheetInPeek(true); + public void onClick() { + Bundle bundle = new Bundle(); + bundle.putParcelableArrayList("songs_object", new ArrayList<>(items)); + bundle.putBoolean("is_chronology", true); + bundle.putInt("position", getBindingAdapterPosition()); + + click.onMediaClick(bundle); } } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/PlayerSongQueueAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/PlayerSongQueueAdapter.java index cfcb9a7e..c9367376 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/PlayerSongQueueAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/PlayerSongQueueAdapter.java @@ -1,6 +1,7 @@ package com.cappielloantonio.play.adapter; import android.content.Context; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -15,33 +16,33 @@ import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.util.MusicUtil; import com.google.common.util.concurrent.ListenableFuture; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class PlayerSongQueueAdapter extends RecyclerView.Adapter { - private static final String TAG = "SongResultSearchAdapter"; - - private final LayoutInflater mInflater; private final Context context; + private final ClickCallback click; private ListenableFuture mediaBrowserListenableFuture; private List songs; - public PlayerSongQueueAdapter(Context context) { + public PlayerSongQueueAdapter(Context context, ClickCallback click) { this.context = context; - this.mInflater = LayoutInflater.from(context); - this.songs = new ArrayList<>(); + this.click = click; + this.songs = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_player_queue_song, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_player_queue_song, parent, false); return new ViewHolder(view); } @@ -59,10 +60,7 @@ public class PlayerSongQueueAdapter extends RecyclerView.Adapter { - if (position < index) { - holder.songTitle.setTextColor(context.getResources().getColor(R.color.songToPlayTextColor, null)); - holder.songSubtitle.setTextColor(context.getResources().getColor(R.color.songToPlayTextColor, null)); - } + holder.play.setVisibility(position == index ? View.VISIBLE : View.INVISIBLE); }); } @@ -88,10 +86,11 @@ public class PlayerSongQueueAdapter extends RecyclerView.Adapter onClick()); } - @Override - public void onClick(View view) { - MediaManager.startQueue(mediaBrowserListenableFuture, context, songs, getBindingAdapterPosition()); + public void onClick() { + Bundle bundle = new Bundle(); + bundle.putParcelableArrayList("songs_object", new ArrayList<>(songs)); + bundle.putInt("position", getBindingAdapterPosition()); + + click.onMediaClick(bundle); } } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistAdapter.java deleted file mode 100644 index 5ab49294..00000000 --- a/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistAdapter.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.cappielloantonio.play.adapter; - -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.navigation.Navigation; -import androidx.recyclerview.widget.RecyclerView; - -import com.cappielloantonio.play.R; -import com.cappielloantonio.play.glide.CustomGlideRequest; -import com.cappielloantonio.play.model.Playlist; -import com.cappielloantonio.play.ui.activity.MainActivity; -import com.cappielloantonio.play.ui.dialog.PlaylistEditorDialog; -import com.cappielloantonio.play.util.MusicUtil; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class PlaylistAdapter extends RecyclerView.Adapter { - private static final String TAG = "PlaylistAdapter"; - - private final MainActivity activity; - private final Context context; - private final LayoutInflater mInflater; - private final boolean isDownloaded; - - private List playlists; - - public PlaylistAdapter(MainActivity activity, Context context, boolean isDownloaded) { - this.activity = activity; - this.context = context; - this.mInflater = LayoutInflater.from(context); - this.playlists = new ArrayList<>(); - this.isDownloaded = isDownloaded; - } - - @NonNull - @Override - public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_library_playlist, parent, false); - return new ViewHolder(view); - } - - @Override - public void onBindViewHolder(ViewHolder holder, int position) { - Playlist playlist = playlists.get(position); - - holder.textPlaylistName.setText(MusicUtil.getReadableString(playlist.getName())); - holder.textPlaylistSongCount.setText(context.getString(R.string.playlist_info_song_count, playlist.getSongCount())); - - CustomGlideRequest.Builder - .from(context, playlist.getPrimary(), CustomGlideRequest.PLAYLIST_PIC, null) - .build() - .into(holder.cover); - - if (isDownloaded) holder.textPlaylistSongCount.setVisibility(View.GONE); - } - - @Override - public int getItemCount() { - return playlists.size(); - } - - public Playlist getItem(int position) { - return playlists.get(position); - } - - public void setItems(List playlists) { - this.playlists = playlists; - notifyDataSetChanged(); - } - - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { - TextView textPlaylistName; - TextView textPlaylistSongCount; - ImageView cover; - - ViewHolder(View itemView) { - super(itemView); - - textPlaylistName = itemView.findViewById(R.id.playlist_name_text); - textPlaylistSongCount = itemView.findViewById(R.id.playlist_song_counter_text); - cover = itemView.findViewById(R.id.playlist_cover_image_view); - - itemView.setOnClickListener(this); - if (!isDownloaded) itemView.setOnLongClickListener(this); - } - - @Override - public void onClick(View view) { - Bundle bundle = new Bundle(); - bundle.putParcelable("playlist_object", playlists.get(getBindingAdapterPosition())); - - if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.libraryFragment) { - bundle.putBoolean("is_offline", false); - Navigation.findNavController(view).navigate(R.id.action_libraryFragment_to_playlistPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.downloadFragment) { - bundle.putBoolean("is_offline", true); - Navigation.findNavController(view).navigate(R.id.action_downloadFragment_to_playlistPageFragment, bundle); - } - } - - @Override - public boolean onLongClick(View view) { - Bundle bundle = new Bundle(); - bundle.putParcelable("playlist_object", playlists.get(getBindingAdapterPosition())); - - PlaylistEditorDialog dialog = new PlaylistEditorDialog(); - dialog.setArguments(bundle); - dialog.show(activity.getSupportFragmentManager(), null); - - return true; - } - } -} diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistDialogHorizontalAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistDialogHorizontalAdapter.java index 27fc62ea..c742fea2 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistDialogHorizontalAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistDialogHorizontalAdapter.java @@ -1,6 +1,7 @@ package com.cappielloantonio.play.adapter; import android.content.Context; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -10,38 +11,32 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.cappielloantonio.play.R; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Playlist; import com.cappielloantonio.play.ui.dialog.PlaylistChooserDialog; import com.cappielloantonio.play.util.MusicUtil; import com.cappielloantonio.play.viewmodel.PlaylistChooserViewModel; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class PlaylistDialogHorizontalAdapter extends RecyclerView.Adapter { - private static final String TAG = "PlaylistDialogHorizontalAdapter"; - private final Context context; - private final LayoutInflater mInflater; - - private final PlaylistChooserViewModel playlistChooserViewModel; - private final PlaylistChooserDialog playlistChooserDialog; + private final ClickCallback click; private List playlists; - public PlaylistDialogHorizontalAdapter(Context context, PlaylistChooserViewModel playlistChooserViewModel, PlaylistChooserDialog playlistChooserDialog) { + public PlaylistDialogHorizontalAdapter(Context context,ClickCallback click) { this.context = context; - this.mInflater = LayoutInflater.from(context); - this.playlists = new ArrayList<>(); - - this.playlistChooserViewModel = playlistChooserViewModel; - this.playlistChooserDialog = playlistChooserDialog; + this.click = click; + this.playlists = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_horizontal_playlist_dialog, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_horizontal_playlist_dialog, parent, false); return new ViewHolder(view); } @@ -68,7 +63,7 @@ public class PlaylistDialogHorizontalAdapter extends RecyclerView.Adapter onClick()); } - @Override - public void onClick(View view) { - playlistChooserViewModel.addSongToPlaylist(playlists.get(getBindingAdapterPosition()).getId()); - playlistChooserDialog.dismiss(); + public void onClick() { + + + Bundle bundle = new Bundle(); + bundle.putParcelable("playlist_object", playlists.get(getBindingAdapterPosition())); + + click.onPlaylistClick(bundle); } } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistDialogSongHorizontalAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistDialogSongHorizontalAdapter.java index 9baf0cd6..fae905cb 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistDialogSongHorizontalAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistDialogSongHorizontalAdapter.java @@ -17,26 +17,23 @@ import com.cappielloantonio.play.glide.CustomGlideRequest; import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.util.MusicUtil; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class PlaylistDialogSongHorizontalAdapter extends RecyclerView.Adapter { - private static final String TAG = "PlaylistDialogSongHorizontalAdapter"; + private final Context context; private List songs; - private final LayoutInflater mInflater; - private final Context context; public PlaylistDialogSongHorizontalAdapter(Context context) { this.context = context; - this.mInflater = LayoutInflater.from(context); - this.songs = new ArrayList<>(); + this.songs = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_horizontal_playlist_dialog_track, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_horizontal_playlist_dialog_track, parent, false); return new ViewHolder(view); } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistHorizontalAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistHorizontalAdapter.java index 2483d436..cf3463e1 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistHorizontalAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/PlaylistHorizontalAdapter.java @@ -5,38 +5,30 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; import android.widget.Filter; import android.widget.Filterable; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.navigation.Navigation; import androidx.recyclerview.widget.RecyclerView; import com.cappielloantonio.play.R; -import com.cappielloantonio.play.model.Genre; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Playlist; -import com.cappielloantonio.play.ui.activity.MainActivity; -import com.cappielloantonio.play.ui.dialog.PlaylistEditorDialog; import com.cappielloantonio.play.util.MusicUtil; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; -import java.util.Objects; public class PlaylistHorizontalAdapter extends RecyclerView.Adapter implements Filterable { - private static final String TAG = "PlaylistDialogHorizontalAdapter"; + private final Context context; + private final ClickCallback click; private List playlists; private List playlistsFull; - private final MainActivity activity; - private final Context context; - private final LayoutInflater mInflater; - private final Filter filtering = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { @@ -68,17 +60,16 @@ public class PlaylistHorizontalAdapter extends RecyclerView.Adapter(); + this.click = click; + this.playlists = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_horizontal_playlist, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_horizontal_playlist, parent, false); return new ViewHolder(view); } @@ -111,7 +102,7 @@ public class PlaylistHorizontalAdapter extends RecyclerView.Adapter onClick()); + itemView.setOnLongClickListener(v -> onLongClick()); } - @Override - public void onClick(View view) { + public void onClick() { Bundle bundle = new Bundle(); bundle.putParcelable("playlist_object", playlists.get(getBindingAdapterPosition())); - if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.libraryFragment) { - bundle.putBoolean("is_offline", false); - Navigation.findNavController(view).navigate(R.id.action_libraryFragment_to_playlistPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.downloadFragment) { - bundle.putBoolean("is_offline", true); - Navigation.findNavController(view).navigate(R.id.action_downloadFragment_to_playlistPageFragment, bundle); - } else if (Objects.requireNonNull(Navigation.findNavController(view).getCurrentDestination()).getId() == R.id.playlistCatalogueFragment) { - bundle.putBoolean("is_offline", false); - Navigation.findNavController(view).navigate(R.id.action_playlistCatalogueFragment_to_playlistPageFragment, bundle); - } - - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + click.onPlaylistClick(bundle); } - @Override - public boolean onLongClick(View view) { + public boolean onLongClick() { Bundle bundle = new Bundle(); bundle.putParcelable("playlist_object", playlists.get(getBindingAdapterPosition())); - PlaylistEditorDialog dialog = new PlaylistEditorDialog(); - dialog.setArguments(bundle); - dialog.show(activity.getSupportFragmentManager(), null); + click.onPlaylistLongClick(bundle); - return true; + return false; } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/PodcastEpisodeAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/PodcastEpisodeAdapter.java index 7f640a11..a8117951 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/PodcastEpisodeAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/PodcastEpisodeAdapter.java @@ -10,45 +10,36 @@ import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.media3.session.MediaBrowser; -import androidx.navigation.Navigation; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Media; -import com.cappielloantonio.play.service.MediaManager; -import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.util.MusicUtil; -import com.google.common.util.concurrent.ListenableFuture; import java.text.SimpleDateFormat; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class PodcastEpisodeAdapter extends RecyclerView.Adapter { - private static final String TAG = "DiscoverSongAdapter"; - - private final LayoutInflater inflater; private final Context context; - private final MainActivity activity; - private ListenableFuture mediaBrowserListenableFuture; + private final ClickCallback click; private List podcastEpisodes; - public PodcastEpisodeAdapter(MainActivity activity, Context context) { - this.activity = activity; + public PodcastEpisodeAdapter(Context context, ClickCallback click) { this.context = context; - this.inflater = LayoutInflater.from(context); - this.podcastEpisodes = new ArrayList<>(); + this.click = click; + this.podcastEpisodes = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = inflater.inflate(R.layout.item_home_podcast_episode, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_home_podcast_episode, parent, false); return new ViewHolder(view); } @@ -79,11 +70,7 @@ public class PodcastEpisodeAdapter extends RecyclerView.Adapter mediaBrowserListenableFuture) { - this.mediaBrowserListenableFuture = mediaBrowserListenableFuture; - } - - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + public class ViewHolder extends RecyclerView.ViewHolder { TextView textTitle; TextView textSubtitle; TextView textReleaseAndDuration; @@ -103,21 +90,25 @@ public class PodcastEpisodeAdapter extends RecyclerView.Adapter onClick()); - moreButton.setOnClickListener(this::openMore); + moreButton.setOnLongClickListener(v -> openMore()); } - @Override - public void onClick(View view) { - MediaManager.startQueue(mediaBrowserListenableFuture, context, podcastEpisodes.get(getBindingAdapterPosition())); - activity.setBottomSheetInPeek(true); - } - - private void openMore(View view) { + public void onClick() { Bundle bundle = new Bundle(); bundle.putParcelable("podcast_object", podcastEpisodes.get(getBindingAdapterPosition())); - Navigation.findNavController(view).navigate(R.id.podcastBottomSheetDialog, bundle); + + click.onPodcastClick(bundle); + } + + private boolean openMore() { + Bundle bundle = new Bundle(); + bundle.putParcelable("podcast_object", podcastEpisodes.get(getBindingAdapterPosition())); + + click.onPodcastLongClick(bundle); + + return false; } } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/ServerAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/ServerAdapter.java index 849092b9..10a3c5f3 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/ServerAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/ServerAdapter.java @@ -6,43 +6,33 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; -import com.cappielloantonio.play.App; import com.cappielloantonio.play.R; -import com.cappielloantonio.play.interfaces.SystemCallback; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Server; -import com.cappielloantonio.play.repository.SystemRepository; -import com.cappielloantonio.play.ui.activity.MainActivity; -import com.cappielloantonio.play.ui.dialog.ServerSignupDialog; -import com.cappielloantonio.play.util.PreferenceUtil; import java.util.ArrayList; import java.util.List; public class ServerAdapter extends RecyclerView.Adapter { - private static final String TAG = "ServerAdapter"; - - private final LayoutInflater mInflater; - private final MainActivity mainActivity; private final Context context; + private final ClickCallback click; private List servers; - public ServerAdapter(MainActivity mainActivity, Context context) { - this.mInflater = LayoutInflater.from(context); - this.servers = new ArrayList<>(); - this.mainActivity = mainActivity; + public ServerAdapter(Context context, ClickCallback click) { this.context = context; + this.click = click; + this.servers = new ArrayList<>(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_login_server, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_login_server, parent, false); return new ViewHolder(view); } @@ -68,7 +58,7 @@ public class ServerAdapter extends RecyclerView.Adapter onClick()); + itemView.setOnLongClickListener(v -> onLongClick()); } - @Override - public void onClick(View view) { - Server server = servers.get(getBindingAdapterPosition()); - saveServerPreference(server.getServerId(), server.getAddress(), server.getUsername(), server.getPassword(), server.isLowSecurity()); - - SystemRepository systemRepository = new SystemRepository(App.getInstance()); - systemRepository.checkUserCredential(new SystemCallback() { - @Override - public void onError(Exception exception) { - resetServerPreference(); - Toast.makeText(context, exception.getMessage(), Toast.LENGTH_SHORT).show(); - } - - @Override - public void onSuccess(String password, String token, String salt) { - enter(); - } - }); - } - - @Override - public boolean onLongClick(View v) { + public void onClick() { Bundle bundle = new Bundle(); bundle.putParcelable("server_object", servers.get(getBindingAdapterPosition())); - ServerSignupDialog dialog = new ServerSignupDialog(); - dialog.setArguments(bundle); - dialog.show(mainActivity.getSupportFragmentManager(), null); - - return true; + click.onServerClick(bundle); } - private void enter() { - mainActivity.goFromLogin(); - } + public boolean onLongClick() { + Bundle bundle = new Bundle(); + bundle.putParcelable("server_object", servers.get(getBindingAdapterPosition())); - private void saveServerPreference(String serverId, String server, String user, String password, boolean isLowSecurity) { - PreferenceUtil.getInstance(context).setServerId(serverId); - PreferenceUtil.getInstance(context).setServer(server); - PreferenceUtil.getInstance(context).setUser(user); - PreferenceUtil.getInstance(context).setPassword(password); - PreferenceUtil.getInstance(context).setLowSecurity(isLowSecurity); + click.onServerLongClick(bundle); - App.getSubsonicClientInstance(context, true); - } - - private void resetServerPreference() { - PreferenceUtil.getInstance(context).setServerId(null); - PreferenceUtil.getInstance(context).setServer(null); - PreferenceUtil.getInstance(context).setUser(null); - PreferenceUtil.getInstance(context).setPassword(null); - PreferenceUtil.getInstance(context).setToken(null); - PreferenceUtil.getInstance(context).setSalt(null); - PreferenceUtil.getInstance(context).setLowSecurity(false); - - App.getSubsonicClientInstance(context, true); + return false; } } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/SimilarTrackAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/SimilarTrackAdapter.java index fcd02061..d9f60cdd 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/SimilarTrackAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/SimilarTrackAdapter.java @@ -2,7 +2,6 @@ package com.cappielloantonio.play.adapter; import android.content.Context; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -10,47 +9,36 @@ import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; -import androidx.media3.session.MediaBrowser; -import androidx.navigation.Navigation; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; -import com.cappielloantonio.play.App; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; -import com.cappielloantonio.play.interfaces.MediaCallback; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Media; -import com.cappielloantonio.play.repository.SongRepository; -import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.util.MusicUtil; -import com.google.common.util.concurrent.ListenableFuture; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class SimilarTrackAdapter extends RecyclerView.Adapter { - private static final String TAG = "SimilarTrackAdapter"; - - private final MainActivity activity; private final Context context; - private final LayoutInflater mInflater; + private final ClickCallback click; - private ListenableFuture mediaBrowserListenableFuture; private List songs; - public SimilarTrackAdapter(MainActivity activity, Context context) { - this.activity = activity; + public SimilarTrackAdapter(Context context, ClickCallback click) { this.context = context; - this.mInflater = LayoutInflater.from(context); - this.songs = new ArrayList<>(); + this.click = click; + this.songs = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_home_similar_track, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_home_similar_track, parent, false); return new ViewHolder(view); } @@ -81,11 +69,7 @@ public class SimilarTrackAdapter extends RecyclerView.Adapter mediaBrowserListenableFuture) { - this.mediaBrowserListenableFuture = mediaBrowserListenableFuture; - } - - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { + public class ViewHolder extends RecyclerView.ViewHolder { TextView textTitle; ImageView cover; @@ -95,35 +79,25 @@ public class SimilarTrackAdapter extends RecyclerView.Adapter onClick()); + itemView.setOnLongClickListener(v -> onLongClick()); } - @Override - public void onClick(View view) { - MediaManager.startQueue(mediaBrowserListenableFuture, context, songs.get(getBindingAdapterPosition())); - activity.setBottomSheetInPeek(true); - - SongRepository songRepository = new SongRepository(App.getInstance()); - songRepository.getInstantMix(songs.get(getBindingAdapterPosition()), 20, new MediaCallback() { - @Override - public void onError(Exception exception) { - Log.e(TAG, "onError() " + exception.getMessage()); - } - - @Override - public void onLoadMedia(List media) { - MediaManager.enqueue(mediaBrowserListenableFuture, context, (List) media, false); - } - }); - } - - @Override - public boolean onLongClick(View view) { + public void onClick() { Bundle bundle = new Bundle(); bundle.putParcelable("song_object", songs.get(getBindingAdapterPosition())); - Navigation.findNavController(view).navigate(R.id.songBottomSheetDialog, bundle); - return true; + bundle.putBoolean("is_mix", true); + + click.onMediaClick(bundle); + } + + public boolean onLongClick() { + Bundle bundle = new Bundle(); + bundle.putParcelable("song_object", songs.get(getBindingAdapterPosition())); + + click.onMediaLongClick(bundle); + + return false; } } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/SongHorizontalAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/SongHorizontalAdapter.java index 2448be3c..0b7979f0 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/SongHorizontalAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/SongHorizontalAdapter.java @@ -18,6 +18,7 @@ import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.ui.activity.MainActivity; @@ -27,32 +28,28 @@ import com.cappielloantonio.play.util.MusicUtil; import com.google.common.util.concurrent.ListenableFuture; import java.util.ArrayList; +import java.util.Collections; import java.util.List; @UnstableApi public class SongHorizontalAdapter extends RecyclerView.Adapter { - private static final String TAG = "SongHorizontalAdapter"; - - private final MainActivity mainActivity; private final Context context; - private final LayoutInflater mInflater; + private final ClickCallback click; private final boolean isCoverVisible; - private ListenableFuture mediaBrowserListenableFuture; private List songs; - public SongHorizontalAdapter(MainActivity mainActivity, Context context, boolean isCoverVisible) { - this.mainActivity = mainActivity; + public SongHorizontalAdapter(Context context, ClickCallback click, boolean isCoverVisible) { this.context = context; - this.mInflater = LayoutInflater.from(context); - this.songs = new ArrayList<>(); + this.click = click; this.isCoverVisible = isCoverVisible; + this.songs = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_horizontal_track, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_horizontal_track, parent, false); return new ViewHolder(view); } @@ -95,15 +92,11 @@ public class SongHorizontalAdapter extends RecyclerView.Adapter mediaBrowserListenableFuture) { - this.mediaBrowserListenableFuture = mediaBrowserListenableFuture; - } - public Media getItem(int id) { return songs.get(id); } - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { + public class ViewHolder extends RecyclerView.ViewHolder { View differentDiscDivider; TextView songTitle; TextView songSubtitle; @@ -125,31 +118,30 @@ public class SongHorizontalAdapter extends RecyclerView.Adapter onClick()); + itemView.setOnLongClickListener(v -> onLongClick()); + + more.setOnClickListener(v -> onLongClick()); } - @Override - public void onClick(View view) { - MediaManager.startQueue(mediaBrowserListenableFuture, context, songs, getBindingAdapterPosition()); - mainActivity.setBottomSheetInPeek(true); + public void onClick() { + Bundle bundle = new Bundle(); + bundle.putParcelableArrayList("songs_object", new ArrayList<>(songs)); + bundle.putInt("position", getBindingAdapterPosition()); + + click.onMediaClick(bundle); } - @Override - public boolean onLongClick(View v) { - openMore(v); - return true; - } - - private void openMore(View view) { + private boolean onLongClick() { Bundle bundle = new Bundle(); bundle.putParcelable("song_object", songs.get(getBindingAdapterPosition())); - Navigation.findNavController(view).navigate(R.id.songBottomSheetDialog, bundle); + + click.onMediaLongClick(bundle); + + return false; } } } diff --git a/app/src/main/java/com/cappielloantonio/play/adapter/YearAdapter.java b/app/src/main/java/com/cappielloantonio/play/adapter/YearAdapter.java index 5d0b5aea..343117e6 100644 --- a/app/src/main/java/com/cappielloantonio/play/adapter/YearAdapter.java +++ b/app/src/main/java/com/cappielloantonio/play/adapter/YearAdapter.java @@ -1,6 +1,7 @@ package com.cappielloantonio.play.adapter; import android.content.Context; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -10,27 +11,28 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.cappielloantonio.play.R; +import com.cappielloantonio.play.interfaces.ClickCallback; +import com.cappielloantonio.play.model.Media; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class YearAdapter extends RecyclerView.Adapter { - private static final String TAG = "YearAdapter"; - - private final LayoutInflater mInflater; + private final Context context; + private final ClickCallback click; private List years; - private ItemClickListener itemClickListener; - public YearAdapter(Context context) { - this.mInflater = LayoutInflater.from(context); - this.years = new ArrayList<>(); + public YearAdapter(Context context, ClickCallback click) { + this.context = context; + this.click = click; + this.years = Collections.emptyList(); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = mInflater.inflate(R.layout.item_home_year, parent, false); + View view = LayoutInflater.from(context).inflate(R.layout.item_home_year, parent, false); return new ViewHolder(view); } @@ -55,15 +57,7 @@ public class YearAdapter extends RecyclerView.Adapter { notifyDataSetChanged(); } - public void setClickListener(ItemClickListener itemClickListener) { - this.itemClickListener = itemClickListener; - } - - public interface ItemClickListener { - void onItemClick(View view, int position); - } - - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + public class ViewHolder extends RecyclerView.ViewHolder { TextView textYear; ViewHolder(View itemView) { @@ -71,13 +65,15 @@ public class YearAdapter extends RecyclerView.Adapter { textYear = itemView.findViewById(R.id.year_label); - itemView.setOnClickListener(this); + itemView.setOnClickListener(v -> onClick()); } - @Override - public void onClick(View view) { - if (itemClickListener != null) - itemClickListener.onItemClick(view, getBindingAdapterPosition()); + public void onClick() { + Bundle bundle = new Bundle(); + bundle.putString(Media.BY_YEAR, Media.BY_YEAR); + bundle.putInt("year_object", years.get(getBindingAdapterPosition())); + + click.onYearClick(bundle); } } } diff --git a/app/src/main/java/com/cappielloantonio/play/interfaces/ClickCallback.java b/app/src/main/java/com/cappielloantonio/play/interfaces/ClickCallback.java new file mode 100644 index 00000000..85a049e4 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/interfaces/ClickCallback.java @@ -0,0 +1,34 @@ +package com.cappielloantonio.play.interfaces; + + +import android.os.Bundle; + +public interface ClickCallback { + default void onMediaClick(Bundle bundle) {} + + default void onMediaLongClick(Bundle bundle) {} + + default void onAlbumClick(Bundle bundle) {} + + default void onAlbumLongClick(Bundle bundle) {} + + default void onArtistClick(Bundle bundle) {} + + default void onArtistLongClick(Bundle bundle) {} + + default void onGenreClick(Bundle bundle) {} + + default void onPlaylistClick(Bundle bundle) {} + + default void onPlaylistLongClick(Bundle bundle) {} + + default void onYearClick(Bundle bundle) {} + + default void onServerClick(Bundle bundle) {} + + default void onServerLongClick(Bundle bundle) {} + + default void onPodcastClick(Bundle bundle) {} + + default void onPodcastLongClick(Bundle bundle) {} +} diff --git a/app/src/main/java/com/cappielloantonio/play/model/Chronology.java b/app/src/main/java/com/cappielloantonio/play/model/Chronology.java index f433a517..49a81ea4 100644 --- a/app/src/main/java/com/cappielloantonio/play/model/Chronology.java +++ b/app/src/main/java/com/cappielloantonio/play/model/Chronology.java @@ -1,11 +1,15 @@ package com.cappielloantonio.play.model; +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; import androidx.room.ColumnInfo; import androidx.room.Entity; import androidx.room.PrimaryKey; @Entity(tableName = "chronology") -public class Chronology { +public class Chronology implements Parcelable { @PrimaryKey(autoGenerate = true) private int uuid; @@ -163,4 +167,70 @@ public class Chronology { public void setTimestamp(Long timestamp) { this.timestamp = timestamp; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Chronology item = (Chronology) o; + return trackId.equals(item.trackId); + } + + @Override + public int hashCode() { + return trackId.hashCode(); + } + + @NonNull + @Override + public String toString() { + return trackId; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.trackId); + dest.writeString(this.title); + dest.writeString(this.albumId); + dest.writeString(this.albumName); + dest.writeString(this.artistId); + dest.writeString(this.artistName); + dest.writeString(this.coverArtId); + dest.writeLong(this.duration); + dest.writeString(this.container); + dest.writeInt(this.bitrate); + dest.writeString(this.extension); + dest.writeLong(this.timestamp); + } + + protected Chronology(Parcel in) { + this.trackId = in.readString(); + this.title = in.readString(); + this.albumId = in.readString(); + this.albumName = in.readString(); + this.artistId = in.readString(); + this.artistName = in.readString(); + this.coverArtId = in.readString(); + this.duration = in.readLong(); + this.container = in.readString(); + this.bitrate = in.readInt(); + this.extension = in.readString(); + this.timestamp = in.readLong(); + } + + public static final Creator CREATOR = new Creator() { + public Chronology createFromParcel(Parcel source) { + return new Chronology(source); + } + + public Chronology[] newArray(int size) { + return new Chronology[size]; + } + }; } diff --git a/app/src/main/java/com/cappielloantonio/play/repository/ArtistRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/ArtistRepository.java index 10247b83..00a68b6b 100644 --- a/app/src/main/java/com/cappielloantonio/play/repository/ArtistRepository.java +++ b/app/src/main/java/com/cappielloantonio/play/repository/ArtistRepository.java @@ -245,27 +245,27 @@ public class ArtistRepository { return artist; } - public void getInstantMix(Artist artist, int count, MediaCallback callback) { + public MutableLiveData> getInstantMix(Artist artist, int count) { + MutableLiveData> instantMix = new MutableLiveData<>(); + App.getSubsonicClientInstance(application, false) .getBrowsingClient() .getSimilarSongs2(artist.getId(), count) .enqueue(new Callback() { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { - List songs = new ArrayList<>(); - if (response.isSuccessful() && response.body() != null && response.body().getSimilarSongs2() != null) { - songs.addAll(MappingUtil.mapSong(response.body().getSimilarSongs2().getSongs())); + instantMix.setValue(MappingUtil.mapSong(response.body().getSimilarSongs2().getSongs())); } - - callback.onLoadMedia(songs); } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { - callback.onLoadMedia(new ArrayList<>()); + } }); + + return instantMix; } public MutableLiveData> getArtistRandomSong(LifecycleOwner owner, Artist artist, int count) { diff --git a/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java index 21c4cba7..646adc33 100644 --- a/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java +++ b/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java @@ -59,7 +59,9 @@ public class SongRepository { return starredSongs; } - public void getInstantMix(Media song, int count, MediaCallback callback) { + public MutableLiveData> getInstantMix(Media song, int count) { + MutableLiveData> instantMix = new MutableLiveData<>(); + App.getSubsonicClientInstance(application, false) .getBrowsingClient() .getSimilarSongs2(song.getId(), count) @@ -67,23 +69,17 @@ public class SongRepository { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { if (response.isSuccessful() && response.body() != null && response.body().getSimilarSongs2() != null) { - List songs = new ArrayList<>(MappingUtil.mapSong(response.body().getSimilarSongs2().getSongs())); - - if (songs.size() <= 1) { - songs.add(song); - } - - callback.onLoadMedia(songs); + instantMix.setValue(MappingUtil.mapSong(response.body().getSimilarSongs2().getSongs())); } } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { - List songs = new ArrayList<>(); - songs.add(song); - callback.onLoadMedia(songs); + instantMix.setValue(null); } }); + + return instantMix; } public MutableLiveData> getRandomSample(int number, Integer fromYear, Integer toYear) { diff --git a/app/src/main/java/com/cappielloantonio/play/ui/dialog/PlaylistChooserDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/dialog/PlaylistChooserDialog.java index b7015409..51ffdefc 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/dialog/PlaylistChooserDialog.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/dialog/PlaylistChooserDialog.java @@ -14,13 +14,13 @@ import androidx.recyclerview.widget.LinearLayoutManager; import com.cappielloantonio.play.R; import com.cappielloantonio.play.adapter.PlaylistDialogHorizontalAdapter; import com.cappielloantonio.play.databinding.DialogPlaylistChooserBinding; +import com.cappielloantonio.play.interfaces.ClickCallback; +import com.cappielloantonio.play.model.Playlist; import com.cappielloantonio.play.viewmodel.PlaylistChooserViewModel; import java.util.Objects; -public class PlaylistChooserDialog extends DialogFragment { - private static final String TAG = "ServerSignupDialog"; - +public class PlaylistChooserDialog extends DialogFragment implements ClickCallback { private DialogPlaylistChooserBinding bind; private PlaylistChooserViewModel playlistChooserViewModel; @@ -79,7 +79,7 @@ public class PlaylistChooserDialog extends DialogFragment { bind.playlistDialogRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.playlistDialogRecyclerView.setHasFixedSize(true); - playlistDialogHorizontalAdapter = new PlaylistDialogHorizontalAdapter(requireContext(), playlistChooserViewModel, this); + playlistDialogHorizontalAdapter = new PlaylistDialogHorizontalAdapter(requireContext(), this); bind.playlistDialogRecyclerView.setAdapter(playlistDialogHorizontalAdapter); playlistChooserViewModel.getPlaylistList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), playlists -> { @@ -95,4 +95,11 @@ public class PlaylistChooserDialog extends DialogFragment { } }); } + + @Override + public void onPlaylistClick(Bundle bundle) { + Playlist playlist = requireArguments().getParcelable("playlist_object"); + playlistChooserViewModel.addSongToPlaylist(playlist.getId()); + dismiss(); + } } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/dialog/PlaylistEditorDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/dialog/PlaylistEditorDialog.java index 7f75074c..a8fa3abd 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/dialog/PlaylistEditorDialog.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/dialog/PlaylistEditorDialog.java @@ -23,8 +23,6 @@ import java.util.Collections; import java.util.Objects; public class PlaylistEditorDialog extends DialogFragment { - private static final String TAG = "ServerSignupDialog"; - private DialogPlaylistEditorBinding bind; private PlaylistEditorViewModel playlistEditorViewModel; diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumCatalogueFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumCatalogueFragment.java index e6a7cefe..deec0d64 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumCatalogueFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumCatalogueFragment.java @@ -19,6 +19,7 @@ import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -26,11 +27,12 @@ import com.cappielloantonio.play.R; import com.cappielloantonio.play.adapter.AlbumCatalogueAdapter; import com.cappielloantonio.play.databinding.FragmentAlbumCatalogueBinding; import com.cappielloantonio.play.helper.recyclerview.GridItemDecoration; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.viewmodel.AlbumCatalogueViewModel; -public class AlbumCatalogueFragment extends Fragment { +public class AlbumCatalogueFragment extends Fragment implements ClickCallback { private static final String TAG = "ArtistCatalogueFragment"; private FragmentAlbumCatalogueBinding bind; @@ -100,7 +102,7 @@ public class AlbumCatalogueFragment extends Fragment { bind.albumCatalogueRecyclerView.addItemDecoration(new GridItemDecoration(2, 20, false)); bind.albumCatalogueRecyclerView.setHasFixedSize(true); - albumAdapter = new AlbumCatalogueAdapter(activity, requireContext()); + albumAdapter = new AlbumCatalogueAdapter(requireContext(), this); albumAdapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY); bind.albumCatalogueRecyclerView.setAdapter(albumAdapter); albumCatalogueViewModel.getAlbumList().observe(getViewLifecycleOwner(), albums -> albumAdapter.setItems(albums)); @@ -139,7 +141,7 @@ public class AlbumCatalogueFragment extends Fragment { } private void hideKeyboard(View view) { - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + InputMethodManager imm = (InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } @@ -167,4 +169,15 @@ public class AlbumCatalogueFragment extends Fragment { popup.show(); } + + @Override + public void onAlbumClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle); + hideKeyboard(requireView()); + } + + @Override + public void onAlbumLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumBottomSheetDialog, bundle); + } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumListPageFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumListPageFragment.java index 85bd3da6..23f9aa29 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumListPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumListPageFragment.java @@ -9,17 +9,19 @@ import androidx.annotation.NonNull; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.LinearLayoutManager; import com.cappielloantonio.play.R; import com.cappielloantonio.play.adapter.AlbumHorizontalAdapter; import com.cappielloantonio.play.databinding.FragmentAlbumListPageBinding; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.util.MusicUtil; import com.cappielloantonio.play.viewmodel.AlbumListPageViewModel; -public class AlbumListPageFragment extends Fragment { +public class AlbumListPageFragment extends Fragment implements ClickCallback { private FragmentAlbumListPageBinding bind; private MainActivity activity; @@ -96,11 +98,23 @@ public class AlbumListPageFragment extends Fragment { bind.albumListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.albumListRecyclerView.setHasFixedSize(true); - albumHorizontalAdapter = new AlbumHorizontalAdapter(requireContext(), + albumHorizontalAdapter = new AlbumHorizontalAdapter( + requireContext(), + this, (albumListPageViewModel.title.equals(Album.DOWNLOADED) || albumListPageViewModel.title.equals(Album.FROM_ARTIST)) ); bind.albumListRecyclerView.setAdapter(albumHorizontalAdapter); albumListPageViewModel.getAlbumList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> albumHorizontalAdapter.setItems(albums)); } + + @Override + public void onAlbumClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle); + } + + @Override + public void onAlbumLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumBottomSheetDialog, bundle); + } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumPageFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumPageFragment.java index abf8b7f0..b0d8edb7 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/AlbumPageFragment.java @@ -1,6 +1,5 @@ package com.cappielloantonio.play.ui.fragment; -import android.annotation.SuppressLint; import android.content.ComponentName; import android.os.Bundle; import android.view.LayoutInflater; @@ -15,8 +14,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.LinearLayoutManager; import com.bumptech.glide.load.resource.bitmap.CenterCrop; @@ -25,6 +26,7 @@ import com.cappielloantonio.play.R; import com.cappielloantonio.play.adapter.SongHorizontalAdapter; import com.cappielloantonio.play.databinding.FragmentAlbumPageBinding; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.service.MediaService; import com.cappielloantonio.play.ui.activity.MainActivity; @@ -37,9 +39,8 @@ import com.google.common.util.concurrent.ListenableFuture; import java.util.Collections; import java.util.Objects; -public class AlbumPageFragment extends Fragment { - private static final String TAG = "AlbumPageFragment"; - +@UnstableApi +public class AlbumPageFragment extends Fragment implements ClickCallback { private FragmentAlbumPageBinding bind; private MainActivity activity; private AlbumPageViewModel albumPageViewModel; @@ -85,12 +86,6 @@ public class AlbumPageFragment extends Fragment { initializeMediaBrowser(); } - @Override - public void onResume() { - super.onResume(); - setMediaBrowserListenableFuture(); - } - @Override public void onStop() { releaseMediaBrowser(); @@ -189,7 +184,7 @@ public class AlbumPageFragment extends Fragment { bind.songRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.songRecyclerView.setHasFixedSize(true); - songHorizontalAdapter = new SongHorizontalAdapter(activity, requireContext(), false); + songHorizontalAdapter = new SongHorizontalAdapter(requireContext(), this, false); bind.songRecyclerView.setAdapter(songHorizontalAdapter); albumPageViewModel.getAlbumSongLiveList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> songHorizontalAdapter.setItems(songs)); @@ -203,7 +198,14 @@ public class AlbumPageFragment extends Fragment { MediaBrowser.releaseFuture(mediaBrowserListenableFuture); } - private void setMediaBrowserListenableFuture() { - songHorizontalAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); + @Override + public void onMediaClick(Bundle bundle) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelableArrayList("songs_object"), bundle.getInt("position")); + activity.setBottomSheetInPeek(true); + } + + @Override + public void onMediaLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle); } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistCatalogueFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistCatalogueFragment.java index cd30f88c..65c7954a 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistCatalogueFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistCatalogueFragment.java @@ -19,6 +19,8 @@ import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -26,11 +28,13 @@ import com.cappielloantonio.play.R; import com.cappielloantonio.play.adapter.ArtistCatalogueAdapter; import com.cappielloantonio.play.databinding.FragmentArtistCatalogueBinding; import com.cappielloantonio.play.helper.recyclerview.GridItemDecoration; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.viewmodel.ArtistCatalogueViewModel; -public class ArtistCatalogueFragment extends Fragment { +@UnstableApi +public class ArtistCatalogueFragment extends Fragment implements ClickCallback { private static final String TAG = "ArtistCatalogueFragment"; private FragmentArtistCatalogueBinding bind; @@ -100,7 +104,7 @@ public class ArtistCatalogueFragment extends Fragment { bind.artistCatalogueRecyclerView.addItemDecoration(new GridItemDecoration(2, 20, false)); bind.artistCatalogueRecyclerView.setHasFixedSize(true); - artistAdapter = new ArtistCatalogueAdapter(activity, requireContext()); + artistAdapter = new ArtistCatalogueAdapter(requireContext(), this); artistAdapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY); bind.artistCatalogueRecyclerView.setAdapter(artistAdapter); artistCatalogueViewModel.getArtistList().observe(getViewLifecycleOwner(), artistList -> artistAdapter.setItems(artistList)); @@ -161,4 +165,15 @@ public class ArtistCatalogueFragment extends Fragment { popup.show(); } + + @Override + public void onArtistClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.artistPageFragment, bundle); + hideKeyboard(requireView()); + } + + @Override + public void onArtistLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.artistBottomSheetDialog, bundle); + } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistListPageFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistListPageFragment.java index 96f8cd2f..b1253995 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistListPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistListPageFragment.java @@ -9,16 +9,20 @@ import androidx.annotation.NonNull; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.LinearLayoutManager; import com.cappielloantonio.play.R; import com.cappielloantonio.play.adapter.ArtistHorizontalAdapter; import com.cappielloantonio.play.databinding.FragmentArtistListPageBinding; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.viewmodel.ArtistListPageViewModel; -public class ArtistListPageFragment extends Fragment { +@UnstableApi +public class ArtistListPageFragment extends Fragment implements ClickCallback { private FragmentArtistListPageBinding bind; private MainActivity activity; @@ -80,8 +84,18 @@ public class ArtistListPageFragment extends Fragment { bind.artistListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.artistListRecyclerView.setHasFixedSize(true); - artistHorizontalAdapter = new ArtistHorizontalAdapter(requireContext(), artistListPageViewModel.title.equals(Artist.DOWNLOADED)); + artistHorizontalAdapter = new ArtistHorizontalAdapter(requireContext(), this); bind.artistListRecyclerView.setAdapter(artistHorizontalAdapter); artistListPageViewModel.getArtistList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> artistHorizontalAdapter.setItems(artists)); } + + @Override + public void onArtistClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumListPageFragment, bundle); + } + + @Override + public void onArtistLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.artistBottomSheetDialog, bundle); + } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistPageFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistPageFragment.java index 02ea15b2..2759c6be 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/ArtistPageFragment.java @@ -1,11 +1,9 @@ package com.cappielloantonio.play.ui.fragment; -import android.annotation.SuppressLint; import android.content.ComponentName; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -14,8 +12,10 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.LinearLayoutManager; import com.cappielloantonio.play.App; @@ -26,7 +26,7 @@ import com.cappielloantonio.play.adapter.SongHorizontalAdapter; import com.cappielloantonio.play.databinding.FragmentArtistPageBinding; import com.cappielloantonio.play.glide.CustomGlideRequest; import com.cappielloantonio.play.helper.recyclerview.CustomLinearSnapHelper; -import com.cappielloantonio.play.interfaces.MediaCallback; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.repository.ArtistRepository; import com.cappielloantonio.play.service.MediaManager; @@ -36,12 +36,8 @@ import com.cappielloantonio.play.util.MusicUtil; import com.cappielloantonio.play.viewmodel.ArtistPageViewModel; import com.google.common.util.concurrent.ListenableFuture; -import java.util.ArrayList; -import java.util.List; - -public class ArtistPageFragment extends Fragment { - private static final String TAG = "ArtistPageFragment"; - +@UnstableApi +public class ArtistPageFragment extends Fragment implements ClickCallback { private FragmentArtistPageBinding bind; private MainActivity activity; private ArtistPageViewModel artistPageViewModel; @@ -76,7 +72,6 @@ public class ArtistPageFragment extends Fragment { super.onStart(); initializeMediaBrowser(); - setMediaBrowserListenableFuture(); } @Override @@ -104,7 +99,8 @@ public class ArtistPageFragment extends Fragment { private void initAppBar() { activity.setSupportActionBar(bind.animToolbar); - if (activity.getSupportActionBar() != null) activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); + if (activity.getSupportActionBar() != null) + activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); bind.collapsingToolbar.setTitle(MusicUtil.getReadableString(artistPageViewModel.getArtist().getName())); bind.animToolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp()); @@ -115,8 +111,10 @@ public class ArtistPageFragment extends Fragment { artistPageViewModel.getArtistInfo(artistPageViewModel.getArtist().getId()).observe(getViewLifecycleOwner(), artist -> { String normalizedBio = MusicUtil.forceReadableString(artist.getBio()); - if (bind != null) bind.artistPageBioSector.setVisibility(!normalizedBio.trim().isEmpty() ? View.VISIBLE : View.GONE); - if (bind != null) bind.bioMoreTextViewClickable.setVisibility(artist.getLastfm() != null ? View.VISIBLE : View.GONE); + if (bind != null) + bind.artistPageBioSector.setVisibility(!normalizedBio.trim().isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.bioMoreTextViewClickable.setVisibility(artist.getLastfm() != null ? View.VISIBLE : View.GONE); if (getContext() != null && bind != null) CustomGlideRequest.Builder .from( @@ -138,6 +136,7 @@ public class ArtistPageFragment extends Fragment { }); } + // TODO Utilizzare il viewmodel come tramite ed evitare le chiamate dirette private void initPlayButtons() { bind.artistPageShuffleButton.setOnClickListener(v -> { ArtistRepository artistRepository = new ArtistRepository(App.getInstance()); @@ -153,20 +152,13 @@ public class ArtistPageFragment extends Fragment { bind.artistPageRadioButton.setOnClickListener(v -> { ArtistRepository artistRepository = new ArtistRepository(App.getInstance()); - artistRepository.getInstantMix(artistPageViewModel.getArtist(), 20, new MediaCallback() { - @Override - public void onError(Exception exception) { - Log.e(TAG, "onError() " + exception.getMessage()); - } - @Override - public void onLoadMedia(List media) { - if (media.size() > 0) { - MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), (ArrayList) media, 0); - activity.setBottomSheetInPeek(true); - } else { - Toast.makeText(requireContext(), getString(R.string.artist_error_retrieving_radio), Toast.LENGTH_SHORT).show(); - } + artistRepository.getInstantMix(artistPageViewModel.getArtist(), 20).observe(getViewLifecycleOwner(), songs -> { + if (songs.size() > 0) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), songs, 0); + activity.setBottomSheetInPeek(true); + } else { + Toast.makeText(requireContext(), getString(R.string.artist_error_retrieving_radio), Toast.LENGTH_SHORT).show(); } }); }); @@ -175,10 +167,11 @@ public class ArtistPageFragment extends Fragment { private void initTopSongsView() { bind.mostStreamedSongRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); - songHorizontalAdapter = new SongHorizontalAdapter(activity, requireContext(), true); + songHorizontalAdapter = new SongHorizontalAdapter(requireContext(), this, true); bind.mostStreamedSongRecyclerView.setAdapter(songHorizontalAdapter); artistPageViewModel.getArtistTopSongList(10).observe(getViewLifecycleOwner(), songs -> { - if (bind != null) bind.artistPageTopSongsSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.artistPageTopSongsSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE); songHorizontalAdapter.setItems(songs); }); } @@ -186,10 +179,11 @@ public class ArtistPageFragment extends Fragment { private void initAlbumsView() { bind.albumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - albumArtistPageOrSimilarAdapter = new AlbumArtistPageOrSimilarAdapter(requireContext()); + albumArtistPageOrSimilarAdapter = new AlbumArtistPageOrSimilarAdapter(requireContext(), this); bind.albumsRecyclerView.setAdapter(albumArtistPageOrSimilarAdapter); artistPageViewModel.getAlbumList().observe(getViewLifecycleOwner(), albums -> { - if (bind != null) bind.artistPageAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.artistPageAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); albumArtistPageOrSimilarAdapter.setItems(albums); }); @@ -201,10 +195,11 @@ public class ArtistPageFragment extends Fragment { bind.similarArtistsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.similarArtistsRecyclerView.setHasFixedSize(true); - artistSimilarAdapter = new ArtistSimilarAdapter(requireContext()); + artistSimilarAdapter = new ArtistSimilarAdapter(requireContext(), this); bind.similarArtistsRecyclerView.setAdapter(artistSimilarAdapter); artistPageViewModel.getArtistInfo(artistPageViewModel.getArtist().getId()).observe(getViewLifecycleOwner(), artist -> { - if (bind != null) bind.similarArtistSector.setVisibility(!artist.getSimilarArtists().isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.similarArtistSector.setVisibility(!artist.getSimilarArtists().isEmpty() ? View.VISIBLE : View.GONE); artistSimilarAdapter.setItems(artist.getSimilarArtists()); }); @@ -220,7 +215,34 @@ public class ArtistPageFragment extends Fragment { MediaBrowser.releaseFuture(mediaBrowserListenableFuture); } - private void setMediaBrowserListenableFuture() { - songHorizontalAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); + @Override + public void onMediaClick(Bundle bundle) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelableArrayList("songs_object"), bundle.getInt("position")); + activity.setBottomSheetInPeek(true); + } + + @Override + public void onMediaLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle); + } + + @Override + public void onAlbumClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle); + } + + @Override + public void onAlbumLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumBottomSheetDialog, bundle); + } + + @Override + public void onArtistClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.artistPageFragment, bundle); + } + + @Override + public void onArtistLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.artistBottomSheetDialog, bundle); } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/DownloadFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/DownloadFragment.java index e35376eb..af8caa02 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/DownloadFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/DownloadFragment.java @@ -13,8 +13,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.PagerSnapHelper; @@ -27,10 +29,12 @@ import com.cappielloantonio.play.adapter.PlaylistHorizontalAdapter; import com.cappielloantonio.play.adapter.SongHorizontalAdapter; import com.cappielloantonio.play.databinding.FragmentDownloadBinding; import com.cappielloantonio.play.helper.recyclerview.DotsIndicatorDecoration; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.model.Playlist; +import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.service.MediaService; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.util.UIUtil; @@ -40,9 +44,8 @@ import com.google.common.util.concurrent.ListenableFuture; import java.util.Objects; -public class DownloadFragment extends Fragment { - private static final String TAG = "CategoriesFragment"; - +@UnstableApi +public class DownloadFragment extends Fragment implements ClickCallback { private FragmentDownloadBinding bind; private MainActivity activity; private DownloadViewModel downloadViewModel; @@ -102,13 +105,6 @@ public class DownloadFragment extends Fragment { activity.setBottomSheetVisibility(true); } - @Override - public void onResume() { - super.onResume(); - - setMediaBrowserListenableFuture(); - } - @Override public void onStop() { releaseMediaBrowser(); @@ -168,7 +164,7 @@ public class DownloadFragment extends Fragment { private void initDownloadedArtistView() { bind.downloadedArtistRecyclerView.setHasFixedSize(true); - downloadedArtistAdapter = new ArtistHorizontalAdapter(requireContext(), false); + downloadedArtistAdapter = new ArtistHorizontalAdapter(requireContext(), this); bind.downloadedArtistRecyclerView.setAdapter(downloadedArtistAdapter); downloadViewModel.getDownloadedArtists(getViewLifecycleOwner(), 20).observe(getViewLifecycleOwner(), artists -> { if (artists == null) { @@ -203,7 +199,7 @@ public class DownloadFragment extends Fragment { private void initDownloadedAlbumView() { bind.downloadedAlbumRecyclerView.setHasFixedSize(true); - downloadedAlbumAdapter = new AlbumHorizontalAdapter(requireContext(), true); + downloadedAlbumAdapter = new AlbumHorizontalAdapter(requireContext(), this, true); bind.downloadedAlbumRecyclerView.setAdapter(downloadedAlbumAdapter); downloadViewModel.getDownloadedAlbums(getViewLifecycleOwner(), 20).observe(getViewLifecycleOwner(), albums -> { if (albums == null) { @@ -238,7 +234,7 @@ public class DownloadFragment extends Fragment { private void initDownloadedSongView() { bind.downloadedTracksRecyclerView.setHasFixedSize(true); - downloadedTrackAdapter = new SongHorizontalAdapter(activity, requireContext(), true); + downloadedTrackAdapter = new SongHorizontalAdapter(requireContext(), this, true); bind.downloadedTracksRecyclerView.setAdapter(downloadedTrackAdapter); downloadViewModel.getDownloadedTracks(getViewLifecycleOwner(), 20).observe(getViewLifecycleOwner(), songs -> { if (songs == null) { @@ -274,7 +270,7 @@ public class DownloadFragment extends Fragment { bind.downloadedPlaylistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.downloadedPlaylistRecyclerView.setHasFixedSize(true); - playlistHorizontalAdapter = new PlaylistHorizontalAdapter(activity, requireContext()); + playlistHorizontalAdapter = new PlaylistHorizontalAdapter(requireContext(), this); bind.downloadedPlaylistRecyclerView.setAdapter(playlistHorizontalAdapter); downloadViewModel.getDownloadedPlaylists(getViewLifecycleOwner(), 5).observe(getViewLifecycleOwner(), playlists -> { if (playlists == null) { @@ -312,7 +308,40 @@ public class DownloadFragment extends Fragment { MediaBrowser.releaseFuture(mediaBrowserListenableFuture); } - private void setMediaBrowserListenableFuture() { - downloadedTrackAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); + @Override + public void onMediaClick(Bundle bundle) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelableArrayList("songs_object"), bundle.getInt("position")); + activity.setBottomSheetInPeek(true); + } + + @Override + public void onMediaLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle); + } + + @Override + public void onAlbumClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle); + } + + @Override + public void onAlbumLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumBottomSheetDialog, bundle); + } + + @Override + public void onArtistClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumListPageFragment, bundle); + } + + @Override + public void onArtistLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.artistBottomSheetDialog, bundle); + } + + @Override + public void onPlaylistClick(Bundle bundle) { + bundle.putBoolean("is_offline", true); + Navigation.findNavController(requireView()).navigate(R.id.playlistPageFragment, bundle); } } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/GenreCatalogueFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/GenreCatalogueFragment.java index 3a445cc0..d01388a0 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/GenreCatalogueFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/GenreCatalogueFragment.java @@ -19,6 +19,7 @@ import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -26,15 +27,12 @@ import com.cappielloantonio.play.R; import com.cappielloantonio.play.adapter.GenreCatalogueAdapter; import com.cappielloantonio.play.databinding.FragmentGenreCatalogueBinding; import com.cappielloantonio.play.helper.recyclerview.GridItemDecoration; -import com.cappielloantonio.play.model.Artist; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Genre; -import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.viewmodel.GenreCatalogueViewModel; -public class GenreCatalogueFragment extends Fragment { - private static final String TAG = "GenreCatalogueFragment"; - +public class GenreCatalogueFragment extends Fragment implements ClickCallback { private FragmentGenreCatalogueBinding bind; private MainActivity activity; private GenreCatalogueViewModel genreCatalogueViewModel; @@ -100,15 +98,9 @@ public class GenreCatalogueFragment extends Fragment { bind.genreCatalogueRecyclerView.addItemDecoration(new GridItemDecoration(2, 16, false)); bind.genreCatalogueRecyclerView.setHasFixedSize(true); - genreCatalogueAdapter = new GenreCatalogueAdapter(activity, requireContext()); + genreCatalogueAdapter = new GenreCatalogueAdapter(requireContext(), this); genreCatalogueAdapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY); bind.genreCatalogueRecyclerView.setAdapter(genreCatalogueAdapter); - genreCatalogueAdapter.setClickListener((view, position) -> { - Bundle bundle = new Bundle(); - bundle.putString(Media.BY_GENRE, Media.BY_GENRE); - bundle.putParcelable("genre_object", genreCatalogueAdapter.getItem(position)); - activity.navController.navigate(R.id.action_genreCatalogueFragment_to_songListPageFragment, bundle); - }); genreCatalogueViewModel.getGenreList().observe(getViewLifecycleOwner(), genres -> genreCatalogueAdapter.setItems(genres)); @@ -168,4 +160,10 @@ public class GenreCatalogueFragment extends Fragment { popup.show(); } + + @Override + public void onGenreClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.songListPageFragment, bundle); + hideKeyboard(requireView()); + } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeFragment.java index 207642d7..77262b4f 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeFragment.java @@ -9,14 +9,17 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.PagerSnapHelper; @@ -39,21 +42,28 @@ import com.cappielloantonio.play.databinding.FragmentHomeBinding; import com.cappielloantonio.play.helper.recyclerview.CustomLinearSnapHelper; import com.cappielloantonio.play.helper.recyclerview.DotsIndicatorDecoration; import com.cappielloantonio.play.helper.recyclerview.GridItemDecoration; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.model.Playlist; +import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.service.MediaService; import com.cappielloantonio.play.ui.activity.MainActivity; +import com.cappielloantonio.play.util.MappingUtil; import com.cappielloantonio.play.util.MusicUtil; import com.cappielloantonio.play.util.UIUtil; import com.cappielloantonio.play.viewmodel.HomeViewModel; import com.google.android.gms.cast.framework.CastButtonFactory; +import com.google.android.material.snackbar.Snackbar; import com.google.common.util.concurrent.ListenableFuture; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; -public class HomeFragment extends Fragment { +@UnstableApi +public class HomeFragment extends Fragment implements ClickCallback { private static final String TAG = "HomeFragment"; private FragmentHomeBinding bind; @@ -133,13 +143,6 @@ public class HomeFragment extends Fragment { activity.setBottomSheetVisibility(true); } - @Override - public void onResume() { - super.onResume(); - - setMediaBrowserListenableFuture(); - } - @Override public void onStop() { releaseMediaBrowser(); @@ -256,7 +259,7 @@ public class HomeFragment extends Fragment { private void initDiscoverSongSlideView() { bind.discoverSongViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); - discoverSongAdapter = new DiscoverSongAdapter(activity, requireContext()); + discoverSongAdapter = new DiscoverSongAdapter(requireContext(), this); bind.discoverSongViewPager.setAdapter(discoverSongAdapter); bind.discoverSongViewPager.setOffscreenPageLimit(1); homeViewModel.getDiscoverSongSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { @@ -281,7 +284,7 @@ public class HomeFragment extends Fragment { bind.similarTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.similarTracksRecyclerView.setHasFixedSize(true); - similarMusicAdapter = new SimilarTrackAdapter(activity, requireContext()); + similarMusicAdapter = new SimilarTrackAdapter(requireContext(), this); bind.similarTracksRecyclerView.setAdapter(similarMusicAdapter); homeViewModel.getStarredTracksSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { if (songs == null) { @@ -306,7 +309,7 @@ public class HomeFragment extends Fragment { bind.radioArtistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.radioArtistRecyclerView.setHasFixedSize(true); - radioArtistAdapter = new ArtistAdapter((MainActivity) requireActivity(), requireContext()); + radioArtistAdapter = new ArtistAdapter(requireContext(), this, true); bind.radioArtistRecyclerView.setAdapter(radioArtistAdapter); homeViewModel.getStarredArtistsSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { if (artists == null) { @@ -330,7 +333,7 @@ public class HomeFragment extends Fragment { private void initStarredTracksView() { bind.starredTracksRecyclerView.setHasFixedSize(true); - starredSongAdapter = new SongHorizontalAdapter(activity, requireContext(), true); + starredSongAdapter = new SongHorizontalAdapter(requireContext(), this, true); bind.starredTracksRecyclerView.setAdapter(starredSongAdapter); homeViewModel.getStarredTracks(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { if (songs == null) { @@ -365,7 +368,7 @@ public class HomeFragment extends Fragment { private void initStarredAlbumsView() { bind.starredAlbumsRecyclerView.setHasFixedSize(true); - starredAlbumAdapter = new AlbumHorizontalAdapter(requireContext(), false); + starredAlbumAdapter = new AlbumHorizontalAdapter(requireContext(), this, false); bind.starredAlbumsRecyclerView.setAdapter(starredAlbumAdapter); homeViewModel.getStarredAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { if (albums == null) { @@ -400,7 +403,7 @@ public class HomeFragment extends Fragment { private void initStarredArtistsView() { bind.starredArtistsRecyclerView.setHasFixedSize(true); - starredArtistAdapter = new ArtistHorizontalAdapter(requireContext(), false); + starredArtistAdapter = new ArtistHorizontalAdapter(requireContext(), this); bind.starredArtistsRecyclerView.setAdapter(starredArtistAdapter); homeViewModel.getStarredArtists(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { if (artists == null) { @@ -435,7 +438,7 @@ public class HomeFragment extends Fragment { private void initNewReleasesView() { bind.newReleasesRecyclerView.setHasFixedSize(true); - newReleasesAlbumAdapter = new AlbumHorizontalAdapter(requireContext(), false); + newReleasesAlbumAdapter = new AlbumHorizontalAdapter(requireContext(), this, false); bind.newReleasesRecyclerView.setAdapter(newReleasesAlbumAdapter); homeViewModel.getRecentlyReleasedAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { if (albums == null) { @@ -471,13 +474,7 @@ public class HomeFragment extends Fragment { bind.yearsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.yearsRecyclerView.setHasFixedSize(true); - yearAdapter = new YearAdapter(requireContext()); - yearAdapter.setClickListener((view, position) -> { - Bundle bundle = new Bundle(); - bundle.putString(Media.BY_YEAR, Media.BY_YEAR); - bundle.putInt("year_object", yearAdapter.getItem(position)); - activity.navController.navigate(R.id.action_homeFragment_to_songListPageFragment, bundle); - }); + yearAdapter = new YearAdapter(requireContext(), this); bind.yearsRecyclerView.setAdapter(yearAdapter); homeViewModel.getYearList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), years -> { if (years == null) { @@ -502,7 +499,7 @@ public class HomeFragment extends Fragment { bind.mostPlayedAlbumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.mostPlayedAlbumsRecyclerView.setHasFixedSize(true); - mostPlayedAlbumAdapter = new AlbumAdapter(requireContext()); + mostPlayedAlbumAdapter = new AlbumAdapter(requireContext(), this); bind.mostPlayedAlbumsRecyclerView.setAdapter(mostPlayedAlbumAdapter); homeViewModel.getMostPlayedAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { if (albums == null) { @@ -528,7 +525,7 @@ public class HomeFragment extends Fragment { bind.recentlyPlayedAlbumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.recentlyPlayedAlbumsRecyclerView.setHasFixedSize(true); - recentlyPlayedAlbumAdapter = new AlbumAdapter(requireContext()); + recentlyPlayedAlbumAdapter = new AlbumAdapter(requireContext(), this); bind.recentlyPlayedAlbumsRecyclerView.setAdapter(recentlyPlayedAlbumAdapter); homeViewModel.getRecentlyPlayedAlbumList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { if (albums == null) { @@ -553,7 +550,7 @@ public class HomeFragment extends Fragment { bind.recentlyAddedAlbumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.recentlyAddedAlbumsRecyclerView.setHasFixedSize(true); - recentlyAddedAlbumAdapter = new AlbumAdapter(requireContext()); + recentlyAddedAlbumAdapter = new AlbumAdapter(requireContext(), this); bind.recentlyAddedAlbumsRecyclerView.setAdapter(recentlyAddedAlbumAdapter); homeViewModel.getMostRecentlyAddedAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { if (albums == null) { @@ -591,7 +588,7 @@ public class HomeFragment extends Fragment { genericPlaylistTitleTextView.setText(MusicUtil.getReadableString(playlist.getName())); genericPlaylistRecyclerView.setHasFixedSize(true); - SongHorizontalAdapter trackAdapter = new SongHorizontalAdapter(activity, requireContext(), true); + SongHorizontalAdapter trackAdapter = new SongHorizontalAdapter(requireContext(), this, true); genericPlaylistRecyclerView.setAdapter(trackAdapter); homeViewModel.getPlaylistSongLiveList(playlist.getId()).observe(getViewLifecycleOwner(), songs -> { @@ -603,8 +600,6 @@ public class HomeFragment extends Fragment { } }); - trackAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); - genericPlaylistCickableTextView.setOnClickListener(view -> { Bundle bundle = new Bundle(); bundle.putParcelable("playlist_object", playlist); @@ -635,7 +630,7 @@ public class HomeFragment extends Fragment { private void initNewestPodcastsView() { bind.newestPodcastsViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); - podcastEpisodeAdapter = new PodcastEpisodeAdapter(activity, requireContext()); + podcastEpisodeAdapter = new PodcastEpisodeAdapter(requireContext(), this); bind.newestPodcastsViewPager.setAdapter(podcastEpisodeAdapter); bind.newestPodcastsViewPager.setOffscreenPageLimit(1); homeViewModel.getNewestPodcastEpisodes(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), podcastEpisodes -> { @@ -657,7 +652,7 @@ public class HomeFragment extends Fragment { bind.gridTracksRecyclerView.addItemDecoration(new GridItemDecoration(3, 8, false)); bind.gridTracksRecyclerView.setHasFixedSize(true); - gridTrackAdapter = new GridTrackAdapter(activity, requireContext()); + gridTrackAdapter = new GridTrackAdapter(requireContext(), this); bind.gridTracksRecyclerView.setAdapter(gridTrackAdapter); homeViewModel.getGridSongSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), chronologies -> { @@ -713,12 +708,82 @@ public class HomeFragment extends Fragment { MediaBrowser.releaseFuture(mediaBrowserListenableFuture); } - private void setMediaBrowserListenableFuture() { - discoverSongAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); - similarMusicAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); - starredSongAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); - radioArtistAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); - podcastEpisodeAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); - gridTrackAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); + @Override + public void onMediaClick(Bundle bundle) { + if (bundle.containsKey("is_mix")) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelable("song_object")); + activity.setBottomSheetInPeek(true); + + if (mediaBrowserListenableFuture != null) { + homeViewModel.getMediaInstantMix(getViewLifecycleOwner(), bundle.getParcelable("song_object")).observe(getViewLifecycleOwner(), songs -> { + if (songs.size() > 0) { + MediaManager.enqueue(mediaBrowserListenableFuture, requireContext(), (ArrayList) songs, true); + } + }); + } + } else if (bundle.containsKey("is_chronology")) { + List media = MappingUtil.mapChronology(bundle.getParcelableArrayList("songs_object")); + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), media, bundle.getInt("position")); + activity.setBottomSheetInPeek(true); + } else { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelableArrayList("songs_object"), bundle.getInt("position")); + activity.setBottomSheetInPeek(true); + } + } + + @Override + public void onMediaLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle); + } + + @Override + public void onAlbumClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle); + } + + @Override + public void onAlbumLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumBottomSheetDialog, bundle); + } + + @Override + public void onArtistClick(Bundle bundle) { + if (bundle.containsKey("is_mix") && bundle.getBoolean("is_mix")) { + Snackbar.make(requireView(), R.string.artist_adapter_radio_station_starting, Snackbar.LENGTH_LONG) + .setAnchorView(activity.bind.playerBottomSheet) + .show(); + + if (mediaBrowserListenableFuture != null) { + homeViewModel.getArtistInstantMix(getViewLifecycleOwner(), bundle.getParcelable("artist_object")).observe(getViewLifecycleOwner(), songs -> { + if (songs.size() > 0) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), (ArrayList) songs, 0); + activity.setBottomSheetInPeek(true); + } + }); + } + } else { + Navigation.findNavController(requireView()).navigate(R.id.artistPageFragment, bundle); + } + } + + @Override + public void onArtistLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.artistBottomSheetDialog, bundle); + } + + @Override + public void onYearClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.songListPageFragment, bundle); + } + + @Override + public void onPodcastClick(Bundle bundle) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelable("podcast_object")); + activity.setBottomSheetInPeek(true); + } + + @Override + public void onPodcastLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.podcastBottomSheetDialog, bundle); } } 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 c453703e..fb16fc85 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 @@ -12,6 +12,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager; @@ -22,17 +24,17 @@ import com.cappielloantonio.play.adapter.GenreAdapter; import com.cappielloantonio.play.adapter.PlaylistHorizontalAdapter; import com.cappielloantonio.play.databinding.FragmentLibraryBinding; import com.cappielloantonio.play.helper.recyclerview.CustomLinearSnapHelper; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Playlist; -import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.ui.activity.MainActivity; +import com.cappielloantonio.play.ui.dialog.PlaylistEditorDialog; import com.cappielloantonio.play.viewmodel.LibraryViewModel; import com.google.android.gms.cast.framework.CastButtonFactory; import java.util.Objects; -public class LibraryFragment extends Fragment { - private static final String TAG = "LibraryFragment"; - +@UnstableApi +public class LibraryFragment extends Fragment implements ClickCallback { private FragmentLibraryBinding bind; private MainActivity activity; private LibraryViewModel libraryViewModel; @@ -143,15 +145,17 @@ public class LibraryFragment extends Fragment { bind.albumRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.albumRecyclerView.setHasFixedSize(true); - albumAdapter = new AlbumAdapter(requireContext()); + albumAdapter = new AlbumAdapter(requireContext(), this); bind.albumRecyclerView.setAdapter(albumAdapter); libraryViewModel.getAlbumSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { if (albums == null) { - if (bind != null) bind.libraryAlbumPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) + bind.libraryAlbumPlaceholder.placeholder.setVisibility(View.VISIBLE); if (bind != null) bind.libraryAlbumSector.setVisibility(View.GONE); } else { if (bind != null) bind.libraryAlbumPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) bind.libraryAlbumSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.libraryAlbumSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); albumAdapter.setItems(albums); } @@ -165,15 +169,18 @@ public class LibraryFragment extends Fragment { bind.artistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.artistRecyclerView.setHasFixedSize(true); - artistAdapter = new ArtistAdapter((MainActivity) requireActivity(), requireContext()); + artistAdapter = new ArtistAdapter(requireContext(), this, false); bind.artistRecyclerView.setAdapter(artistAdapter); libraryViewModel.getArtistSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { if (artists == null) { - if (bind != null) bind.libraryArtistPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) + bind.libraryArtistPlaceholder.placeholder.setVisibility(View.VISIBLE); if (bind != null) bind.libraryArtistSector.setVisibility(View.GONE); } else { - if (bind != null) bind.libraryArtistPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) bind.libraryArtistSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.libraryArtistPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.libraryArtistSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE); artistAdapter.setItems(artists); } @@ -187,21 +194,18 @@ public class LibraryFragment extends Fragment { bind.genreRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 3, GridLayoutManager.HORIZONTAL, false)); bind.genreRecyclerView.setHasFixedSize(true); - genreAdapter = new GenreAdapter(requireContext()); - genreAdapter.setClickListener((view, position) -> { - Bundle bundle = new Bundle(); - bundle.putString(Media.BY_GENRE, Media.BY_GENRE); - bundle.putParcelable("genre_object", genreAdapter.getItem(position)); - activity.navController.navigate(R.id.action_libraryFragment_to_songListPageFragment, bundle); - }); + genreAdapter = new GenreAdapter(requireContext(), this); bind.genreRecyclerView.setAdapter(genreAdapter); + libraryViewModel.getGenreSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), genres -> { if (genres == null) { - if (bind != null) bind.libraryGenrePlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) + bind.libraryGenrePlaceholder.placeholder.setVisibility(View.VISIBLE); if (bind != null) bind.libraryGenresSector.setVisibility(View.GONE); } else { if (bind != null) bind.libraryGenrePlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) bind.libraryGenresSector.setVisibility(!genres.isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.libraryGenresSector.setVisibility(!genres.isEmpty() ? View.VISIBLE : View.GONE); genreAdapter.setItems(genres); } @@ -215,18 +219,59 @@ public class LibraryFragment extends Fragment { bind.playlistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.playlistRecyclerView.setHasFixedSize(true); - playlistHorizontalAdapter = new PlaylistHorizontalAdapter(activity, requireContext()); + playlistHorizontalAdapter = new PlaylistHorizontalAdapter(requireContext(), this); bind.playlistRecyclerView.setAdapter(playlistHorizontalAdapter); libraryViewModel.getPlaylistSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), playlists -> { if (playlists == null) { - if (bind != null) bind.libraryPlaylistPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) + bind.libraryPlaylistPlaceholder.placeholder.setVisibility(View.VISIBLE); if (bind != null) bind.libraryPlaylistSector.setVisibility(View.GONE); } else { - if (bind != null) bind.libraryPlaylistPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) bind.libraryPlaylistSector.setVisibility(!playlists.isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.libraryPlaylistPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.libraryPlaylistSector.setVisibility(!playlists.isEmpty() ? View.VISIBLE : View.GONE); playlistHorizontalAdapter.setItems(playlists); } }); } + + @Override + public void onAlbumClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle); + } + + @Override + public void onAlbumLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumBottomSheetDialog, bundle); + } + + @Override + public void onArtistClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.artistPageFragment, bundle); + } + + @Override + public void onArtistLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.artistBottomSheetDialog, bundle); + } + + @Override + public void onGenreClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.songListPageFragment, bundle); + } + + @Override + public void onPlaylistClick(Bundle bundle) { + bundle.putBoolean("is_offline", false); + Navigation.findNavController(requireView()).navigate(R.id.playlistPageFragment, bundle); + } + + @Override + public void onPlaylistLongClick(Bundle bundle) { + PlaylistEditorDialog dialog = new PlaylistEditorDialog(); + dialog.setArguments(bundle); + dialog.show(activity.getSupportFragmentManager(), null); + } } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java index 5dc393dd..7b406aed 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/LoginFragment.java @@ -7,22 +7,31 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; import androidx.recyclerview.widget.LinearLayoutManager; +import com.cappielloantonio.play.App; import com.cappielloantonio.play.R; import com.cappielloantonio.play.adapter.ServerAdapter; import com.cappielloantonio.play.databinding.FragmentLoginBinding; +import com.cappielloantonio.play.interfaces.ClickCallback; +import com.cappielloantonio.play.interfaces.SystemCallback; +import com.cappielloantonio.play.model.Server; +import com.cappielloantonio.play.repository.SystemRepository; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.ui.dialog.ServerSignupDialog; +import com.cappielloantonio.play.util.PreferenceUtil; import com.cappielloantonio.play.viewmodel.LoginViewModel; -public class LoginFragment extends Fragment { +@UnstableApi +public class LoginFragment extends Fragment implements ClickCallback { private static final String TAG = "LoginFragment"; private FragmentLoginBinding bind; @@ -80,7 +89,7 @@ public class LoginFragment extends Fragment { bind.serverListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.serverListRecyclerView.setHasFixedSize(true); - serverAdapter = new ServerAdapter(activity, requireContext()); + serverAdapter = new ServerAdapter(requireContext(), this); bind.serverListRecyclerView.setAdapter(serverAdapter); loginViewModel.getServerList().observe(getViewLifecycleOwner(), servers -> { if (servers.size() > 0) { @@ -104,4 +113,53 @@ public class LoginFragment extends Fragment { return false; } + + @Override + public void onServerClick(Bundle bundle) { + Server server = bundle.getParcelable("server_object"); + saveServerPreference(server.getServerId(), server.getAddress(), server.getUsername(), server.getPassword(), server.isLowSecurity()); + + SystemRepository systemRepository = new SystemRepository(App.getInstance()); + systemRepository.checkUserCredential(new SystemCallback() { + @Override + public void onError(Exception exception) { + resetServerPreference(); + Toast.makeText(requireContext(), exception.getMessage(), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onSuccess(String password, String token, String salt) { + activity.goFromLogin(); + } + }); + } + + @Override + public void onServerLongClick(Bundle bundle) { + ServerSignupDialog dialog = new ServerSignupDialog(); + dialog.setArguments(bundle); + dialog.show(activity.getSupportFragmentManager(), null); + } + + private void saveServerPreference(String serverId, String server, String user, String password, boolean isLowSecurity) { + PreferenceUtil.getInstance(requireContext()).setServerId(serverId); + PreferenceUtil.getInstance(requireContext()).setServer(server); + PreferenceUtil.getInstance(requireContext()).setUser(user); + PreferenceUtil.getInstance(requireContext()).setPassword(password); + PreferenceUtil.getInstance(requireContext()).setLowSecurity(isLowSecurity); + + App.getSubsonicClientInstance(requireContext(), true); + } + + private void resetServerPreference() { + PreferenceUtil.getInstance(requireContext()).setServerId(null); + PreferenceUtil.getInstance(requireContext()).setServer(null); + PreferenceUtil.getInstance(requireContext()).setUser(null); + PreferenceUtil.getInstance(requireContext()).setPassword(null); + PreferenceUtil.getInstance(requireContext()).setToken(null); + PreferenceUtil.getInstance(requireContext()).setSalt(null); + PreferenceUtil.getInstance(requireContext()).setLowSecurity(false); + + App.getSubsonicClientInstance(requireContext(), true); + } } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerCoverFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerCoverFragment.java index fbf9b6bc..8c4ae49e 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerCoverFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerCoverFragment.java @@ -1,12 +1,10 @@ package com.cappielloantonio.play.ui.fragment; -import android.annotation.SuppressLint; import android.content.ComponentName; import android.os.Bundle; import android.transition.Fade; import android.transition.Transition; import android.transition.TransitionManager; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -16,17 +14,15 @@ import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.media3.common.MediaMetadata; import androidx.media3.common.Player; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; -import com.cappielloantonio.play.App; import com.cappielloantonio.play.databinding.InnerFragmentPlayerCoverBinding; import com.cappielloantonio.play.glide.CustomGlideRequest; -import com.cappielloantonio.play.interfaces.MediaCallback; import com.cappielloantonio.play.model.Media; -import com.cappielloantonio.play.repository.SongRepository; import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.service.MediaService; import com.cappielloantonio.play.ui.dialog.PlaylistChooserDialog; @@ -38,9 +34,8 @@ import com.google.common.util.concurrent.MoreExecutors; import java.util.List; +@UnstableApi public class PlayerCoverFragment extends Fragment { - private static final String TAG = "PlayerCoverFragment"; - private PlayerBottomSheetViewModel playerBottomSheetViewModel; private InnerFragmentPlayerCoverBinding bind; private ListenableFuture mediaBrowserListenableFuture; @@ -113,17 +108,8 @@ public class PlayerCoverFragment extends Fragment { ); bind.innerButtonBottomLeft.setOnClickListener(view -> { - SongRepository songRepository = new SongRepository(App.getInstance()); - songRepository.getInstantMix(song, 20, new MediaCallback() { - @Override - public void onError(Exception exception) { - Log.e(TAG, "onError() " + exception.getMessage()); - } - - @Override - public void onLoadMedia(List media) { - MediaManager.enqueue(mediaBrowserListenableFuture, requireContext(), (List) media, true); - } + playerBottomSheetViewModel.getMediaInstantMix(getViewLifecycleOwner(), song).observe(getViewLifecycleOwner(), media -> { + MediaManager.enqueue(mediaBrowserListenableFuture, requireContext(), (List) media, true); }); }); @@ -151,10 +137,9 @@ public class PlayerCoverFragment extends Fragment { mediaBrowserListenableFuture.addListener(() -> { try { MediaBrowser mediaBrowseri = mediaBrowserListenableFuture.get(); - setMediaBrowserListener(mediaBrowseri); - } catch (Exception e) { - Log.e(TAG, e.getMessage()); + } catch (Exception exception) { + exception.printStackTrace(); } }, MoreExecutors.directExecutor()); } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerQueueFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerQueueFragment.java index ef1b1761..f74ae1fc 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerQueueFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerQueueFragment.java @@ -1,6 +1,5 @@ package com.cappielloantonio.play.ui.fragment; -import android.annotation.SuppressLint; import android.content.ComponentName; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,6 +9,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; import androidx.recyclerview.widget.ItemTouchHelper; @@ -18,6 +18,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.cappielloantonio.play.adapter.PlayerSongQueueAdapter; import com.cappielloantonio.play.databinding.InnerFragmentPlayerQueueBinding; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.service.MediaService; import com.cappielloantonio.play.util.MappingUtil; @@ -26,9 +27,8 @@ import com.google.common.util.concurrent.ListenableFuture; import java.util.Collections; -public class PlayerQueueFragment extends Fragment { - private static final String TAG = "PlayerCoverFragment"; - +@UnstableApi +public class PlayerQueueFragment extends Fragment implements ClickCallback { private InnerFragmentPlayerQueueBinding bind; private PlayerBottomSheetViewModel playerBottomSheetViewModel; @@ -88,7 +88,7 @@ public class PlayerQueueFragment extends Fragment { bind.playerQueueRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.playerQueueRecyclerView.setHasFixedSize(true); - playerSongQueueAdapter = new PlayerSongQueueAdapter(requireContext()); + playerSongQueueAdapter = new PlayerSongQueueAdapter(requireContext(), this); bind.playerQueueRecyclerView.setAdapter(playerSongQueueAdapter); playerBottomSheetViewModel.getQueueSong().observe(getViewLifecycleOwner(), queue -> { if (queue != null) { @@ -147,4 +147,9 @@ public class PlayerQueueFragment extends Fragment { } }).attachToRecyclerView(bind.playerQueueRecyclerView); } + + @Override + public void onMediaClick(Bundle bundle) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelableArrayList("songs_object"), bundle.getInt("position")); + } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistCatalogueFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistCatalogueFragment.java index f14e0dec..c3d14ab0 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistCatalogueFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistCatalogueFragment.java @@ -19,22 +19,25 @@ import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.LinearLayoutManager; import com.cappielloantonio.play.R; import com.cappielloantonio.play.adapter.PlaylistHorizontalAdapter; import com.cappielloantonio.play.databinding.FragmentPlaylistCatalogueBinding; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Genre; import com.cappielloantonio.play.model.Playlist; import com.cappielloantonio.play.ui.activity.MainActivity; +import com.cappielloantonio.play.ui.dialog.PlaylistEditorDialog; import com.cappielloantonio.play.viewmodel.PlaylistCatalogueViewModel; import java.util.ArrayList; import java.util.List; -public class PlaylistCatalogueFragment extends Fragment { - private static final String TAG = "GenreCatalogueFragment"; - +@UnstableApi +public class PlaylistCatalogueFragment extends Fragment implements ClickCallback { private FragmentPlaylistCatalogueBinding bind; private MainActivity activity; private PlaylistCatalogueViewModel playlistCatalogueViewModel; @@ -104,7 +107,7 @@ public class PlaylistCatalogueFragment extends Fragment { bind.playlistCatalogueRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.playlistCatalogueRecyclerView.setHasFixedSize(true); - playlistHorizontalAdapter = new PlaylistHorizontalAdapter(activity, requireContext()); + playlistHorizontalAdapter = new PlaylistHorizontalAdapter(requireContext(), this); bind.playlistCatalogueRecyclerView.setAdapter(playlistHorizontalAdapter); if (getActivity() != null) { @@ -192,4 +195,19 @@ public class PlaylistCatalogueFragment extends Fragment { popup.show(); } + + @Override + public void onPlaylistClick(Bundle bundle) { + bundle.putBoolean("is_offline", false); + Navigation.findNavController(requireView()).navigate(R.id.playlistPageFragment, bundle); + hideKeyboard(requireView()); + } + + @Override + public void onPlaylistLongClick(Bundle bundle) { + PlaylistEditorDialog dialog = new PlaylistEditorDialog(); + dialog.setArguments(bundle); + dialog.show(activity.getSupportFragmentManager(), null); + hideKeyboard(requireView()); + } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java index 6e8bf2cd..d43c72ab 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java @@ -1,6 +1,5 @@ package com.cappielloantonio.play.ui.fragment; -import android.annotation.SuppressLint; import android.content.ComponentName; import android.os.Bundle; import android.view.LayoutInflater; @@ -14,8 +13,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.LinearLayoutManager; import com.bumptech.glide.load.resource.bitmap.CenterCrop; @@ -24,6 +25,7 @@ import com.cappielloantonio.play.R; import com.cappielloantonio.play.adapter.SongHorizontalAdapter; import com.cappielloantonio.play.databinding.FragmentPlaylistPageBinding; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.service.MediaService; import com.cappielloantonio.play.ui.activity.MainActivity; @@ -36,8 +38,8 @@ import com.google.common.util.concurrent.ListenableFuture; import java.util.Collections; import java.util.Objects; -public class PlaylistPageFragment extends Fragment { - +@UnstableApi +public class PlaylistPageFragment extends Fragment implements ClickCallback { private FragmentPlaylistPageBinding bind; private MainActivity activity; private PlaylistPageViewModel playlistPageViewModel; @@ -83,12 +85,6 @@ public class PlaylistPageFragment extends Fragment { initializeMediaBrowser(); } - @Override - public void onResume() { - super.onResume(); - setMediaBrowserListenableFuture(); - } - @Override public void onStop() { releaseMediaBrowser(); @@ -217,7 +213,7 @@ public class PlaylistPageFragment extends Fragment { bind.songRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.songRecyclerView.setHasFixedSize(true); - songHorizontalAdapter = new SongHorizontalAdapter(activity, requireContext(), true); + songHorizontalAdapter = new SongHorizontalAdapter(requireContext(), this, true); bind.songRecyclerView.setAdapter(songHorizontalAdapter); playlistPageViewModel.getPlaylistSongLiveList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> songHorizontalAdapter.setItems(songs)); @@ -231,7 +227,14 @@ public class PlaylistPageFragment extends Fragment { MediaBrowser.releaseFuture(mediaBrowserListenableFuture); } - private void setMediaBrowserListenableFuture() { - songHorizontalAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); + @Override + public void onMediaClick(Bundle bundle) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelableArrayList("songs_object"), bundle.getInt("position")); + activity.setBottomSheetInPeek(true); + } + + @Override + public void onMediaLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle); } } \ No newline at end of file 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 e93ec480..84f26580 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 @@ -1,6 +1,5 @@ package com.cappielloantonio.play.ui.fragment; -import android.annotation.SuppressLint; import android.content.ComponentName; import android.os.Bundle; import android.view.LayoutInflater; @@ -12,8 +11,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.LinearLayoutManager; import com.cappielloantonio.play.R; @@ -22,19 +23,19 @@ import com.cappielloantonio.play.adapter.ArtistAdapter; import com.cappielloantonio.play.adapter.SongHorizontalAdapter; import com.cappielloantonio.play.databinding.FragmentSearchBinding; import com.cappielloantonio.play.helper.recyclerview.CustomLinearSnapHelper; +import com.cappielloantonio.play.interfaces.ClickCallback; +import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.service.MediaService; import com.cappielloantonio.play.ui.activity.MainActivity; import com.cappielloantonio.play.util.MusicUtil; import com.cappielloantonio.play.viewmodel.SearchViewModel; -import com.google.android.material.elevation.SurfaceColors; import com.google.common.util.concurrent.ListenableFuture; import com.paulrybitskyi.persistentsearchview.adapters.model.SuggestionItem; import com.paulrybitskyi.persistentsearchview.listeners.OnSuggestionChangeListener; import com.paulrybitskyi.persistentsearchview.utils.SuggestionCreationUtil; -public class SearchFragment extends Fragment { - private static final String TAG = "SearchFragment"; - +@UnstableApi +public class SearchFragment extends Fragment implements ClickCallback { private FragmentSearchBinding bind; private MainActivity activity; private SearchViewModel searchViewModel; @@ -69,7 +70,6 @@ public class SearchFragment extends Fragment { @Override public void onResume() { super.onResume(); - setMediaBrowserListenableFuture(); inputFocus(); } @@ -90,7 +90,7 @@ public class SearchFragment extends Fragment { bind.searchResultArtistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.searchResultArtistRecyclerView.setHasFixedSize(true); - artistAdapter = new ArtistAdapter((MainActivity) requireActivity(), requireContext()); + artistAdapter = new ArtistAdapter(requireContext(), this, false); bind.searchResultArtistRecyclerView.setAdapter(artistAdapter); CustomLinearSnapHelper artistSnapHelper = new CustomLinearSnapHelper(); @@ -100,7 +100,7 @@ public class SearchFragment extends Fragment { bind.searchResultAlbumRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); bind.searchResultAlbumRecyclerView.setHasFixedSize(true); - albumAdapter = new AlbumAdapter(requireContext()); + albumAdapter = new AlbumAdapter(requireContext(), this); bind.searchResultAlbumRecyclerView.setAdapter(albumAdapter); CustomLinearSnapHelper albumSnapHelper = new CustomLinearSnapHelper(); @@ -110,7 +110,7 @@ public class SearchFragment extends Fragment { bind.searchResultTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.searchResultTracksRecyclerView.setHasFixedSize(true); - songHorizontalAdapter = new SongHorizontalAdapter(activity, requireContext(), true); + songHorizontalAdapter = new SongHorizontalAdapter(requireContext(), this, true); bind.searchResultTracksRecyclerView.setAdapter(songHorizontalAdapter); } @@ -214,7 +214,34 @@ public class SearchFragment extends Fragment { MediaBrowser.releaseFuture(mediaBrowserListenableFuture); } - private void setMediaBrowserListenableFuture() { - songHorizontalAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); + @Override + public void onMediaClick(Bundle bundle) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelableArrayList("songs_object"), bundle.getInt("position")); + activity.setBottomSheetInPeek(true); + } + + @Override + public void onMediaLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle); + } + + @Override + public void onAlbumClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle); + } + + @Override + public void onAlbumLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.albumBottomSheetDialog, bundle); + } + + @Override + public void onArtistClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.artistPageFragment, bundle); + } + + @Override + public void onArtistLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.artistBottomSheetDialog, bundle); } } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SongListPageFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SongListPageFragment.java index d6f0bd56..96079bc4 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SongListPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SongListPageFragment.java @@ -1,6 +1,5 @@ package com.cappielloantonio.play.ui.fragment; -import android.annotation.SuppressLint; import android.content.ComponentName; import android.os.Bundle; import android.view.LayoutInflater; @@ -11,13 +10,16 @@ import androidx.annotation.NonNull; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; +import androidx.navigation.Navigation; import androidx.recyclerview.widget.LinearLayoutManager; import com.cappielloantonio.play.R; import com.cappielloantonio.play.adapter.SongHorizontalAdapter; import com.cappielloantonio.play.databinding.FragmentSongListPageBinding; +import com.cappielloantonio.play.interfaces.ClickCallback; import com.cappielloantonio.play.model.Media; import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.service.MediaService; @@ -28,8 +30,8 @@ import com.google.common.util.concurrent.ListenableFuture; import java.util.Collections; -public class SongListPageFragment extends Fragment { - +@UnstableApi +public class SongListPageFragment extends Fragment implements ClickCallback { private FragmentSongListPageBinding bind; private MainActivity activity; private SongListPageViewModel songListPageViewModel; @@ -60,12 +62,6 @@ public class SongListPageFragment extends Fragment { initializeMediaBrowser(); } - @Override - public void onResume() { - super.onResume(); - setMediaBrowserListenableFuture(); - } - @Override public void onStop() { releaseMediaBrowser(); @@ -136,15 +132,17 @@ public class SongListPageFragment extends Fragment { activity.getSupportActionBar().setDisplayShowHomeEnabled(true); } - if (bind != null) bind.toolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp()); + if (bind != null) + bind.toolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp()); - if (bind != null) bind.appBarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> { - if ((bind.albumInfoSector.getHeight() + verticalOffset) < (2 * ViewCompat.getMinimumHeight(bind.toolbar))) { - bind.toolbar.setTitle(songListPageViewModel.toolbarTitle); - } else { - bind.toolbar.setTitle(R.string.empty_string); - } - }); + if (bind != null) + bind.appBarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> { + if ((bind.albumInfoSector.getHeight() + verticalOffset) < (2 * ViewCompat.getMinimumHeight(bind.toolbar))) { + bind.toolbar.setTitle(songListPageViewModel.toolbarTitle); + } else { + bind.toolbar.setTitle(R.string.empty_string); + } + }); } private void initButtons() { @@ -163,7 +161,7 @@ public class SongListPageFragment extends Fragment { bind.songListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.songListRecyclerView.setHasFixedSize(true); - songHorizontalAdapter = new SongHorizontalAdapter(activity, requireContext(), true); + songHorizontalAdapter = new SongHorizontalAdapter(requireContext(), this, true); bind.songListRecyclerView.setAdapter(songHorizontalAdapter); songListPageViewModel.getSongList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> songHorizontalAdapter.setItems(songs)); } @@ -176,7 +174,14 @@ public class SongListPageFragment extends Fragment { MediaBrowser.releaseFuture(mediaBrowserListenableFuture); } - private void setMediaBrowserListenableFuture() { - songHorizontalAdapter.setMediaBrowserListenableFuture(mediaBrowserListenableFuture); + @Override + public void onMediaClick(Bundle bundle) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelableArrayList("songs_object"), bundle.getInt("position")); + activity.setBottomSheetInPeek(true); + } + + @Override + public void onMediaLongClick(Bundle bundle) { + Navigation.findNavController(requireView()).navigate(R.id.songBottomSheetDialog, bundle); } } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java index a5d0bf70..577c4eb6 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java @@ -1,9 +1,7 @@ package com.cappielloantonio.play.ui.fragment.bottomsheetdialog; -import android.annotation.SuppressLint; import android.content.ComponentName; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -15,6 +13,7 @@ import android.widget.ToggleButton; import androidx.annotation.Nullable; import androidx.lifecycle.ViewModelProvider; import androidx.media3.common.MediaItem; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; import androidx.navigation.fragment.NavHostFragment; @@ -43,9 +42,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +@UnstableApi public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener { - private static final String TAG = "AlbumBottomSheetDialog"; - private AlbumBottomSheetViewModel albumBottomSheetViewModel; private Album album; @@ -107,8 +105,7 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements albumRepository.getInstantMix(album, 20, new MediaCallback() { @Override public void onError(Exception exception) { - Log.e(TAG, "onError() " + exception.getMessage()); - dismissBottomSheet(); + exception.printStackTrace(); } @Override @@ -116,8 +113,6 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements if (media.size() > 0) { MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), (ArrayList) media, 0); ((MainActivity) requireActivity()).setBottomSheetInPeek(true); - } else { - Toast.makeText(requireContext(), getString(R.string.album_error_retrieving_radio), Toast.LENGTH_SHORT).show(); } dismissBottomSheet(); diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java index 842af34d..9c5c0f90 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java @@ -1,6 +1,5 @@ package com.cappielloantonio.play.ui.fragment.bottomsheetdialog; -import android.annotation.SuppressLint; import android.content.ComponentName; import android.os.Bundle; import android.util.Log; @@ -14,6 +13,7 @@ import android.widget.ToggleButton; import androidx.annotation.Nullable; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; @@ -37,6 +37,7 @@ import com.google.common.util.concurrent.ListenableFuture; import java.util.ArrayList; import java.util.List; +@UnstableApi public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener { private static final String TAG = "AlbumBottomSheetDialog"; @@ -73,6 +74,7 @@ public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implement super.onStop(); } + // TODO Utilizzare il viewmodel come tramite ed evitare le chiamate dirette private void init(View view) { ImageView coverArtist = view.findViewById(R.id.artist_cover_image_view); CustomGlideRequest.Builder @@ -95,24 +97,14 @@ public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implement TextView playRadio = view.findViewById(R.id.play_radio_text_view); playRadio.setOnClickListener(v -> { ArtistRepository artistRepository = new ArtistRepository(App.getInstance()); - artistRepository.getInstantMix(artist, 20, new MediaCallback() { - @Override - public void onError(Exception exception) { - Log.e(TAG, "onError() " + exception.getMessage()); - dismissBottomSheet(); + + artistRepository.getInstantMix(artist, 20).observe(getViewLifecycleOwner(), songs -> { + if (songs.size() > 0) { + MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), songs, 0); + ((MainActivity) requireActivity()).setBottomSheetInPeek(true); } - @Override - public void onLoadMedia(List media) { - if (media.size() > 0) { - MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), (ArrayList) media, 0); - ((MainActivity) requireActivity()).setBottomSheetInPeek(true); - } else { - Toast.makeText(requireContext(), getString(R.string.artist_error_retrieving_radio), Toast.LENGTH_SHORT).show(); - } - - dismissBottomSheet(); - } + dismissBottomSheet(); }); }); diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/PodcastBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/PodcastBottomSheetDialog.java index 443aecb2..89dbb368 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/PodcastBottomSheetDialog.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/PodcastBottomSheetDialog.java @@ -1,6 +1,5 @@ package com.cappielloantonio.play.ui.fragment.bottomsheetdialog; -import android.annotation.SuppressLint; import android.content.ComponentName; import android.os.Bundle; import android.view.LayoutInflater; @@ -9,10 +8,10 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; -import android.widget.ToggleButton; import androidx.annotation.Nullable; import androidx.lifecycle.ViewModelProvider; +import androidx.media3.common.util.UnstableApi; import androidx.media3.session.MediaBrowser; import androidx.media3.session.SessionToken; @@ -31,9 +30,8 @@ import com.cappielloantonio.play.viewmodel.PodcastBottomSheetViewModel; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.common.util.concurrent.ListenableFuture; +@UnstableApi public class PodcastBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener { - private static final String TAG = "PodcastBottomSheetDialog"; - private PodcastBottomSheetViewModel podcastBottomSheetViewModel; private Media podcast; diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java index 7f966ced..fbad457f 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java @@ -2,7 +2,6 @@ package com.cappielloantonio.play.ui.fragment.bottomsheetdialog; import android.content.ComponentName; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -20,12 +19,9 @@ import androidx.navigation.fragment.NavHostFragment; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; -import com.cappielloantonio.play.App; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; -import com.cappielloantonio.play.interfaces.MediaCallback; import com.cappielloantonio.play.model.Media; -import com.cappielloantonio.play.repository.SongRepository; import com.cappielloantonio.play.service.MediaManager; import com.cappielloantonio.play.service.MediaService; import com.cappielloantonio.play.ui.activity.MainActivity; @@ -116,16 +112,14 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), song); ((MainActivity) requireActivity()).setBottomSheetInPeek(true); - SongRepository songRepository = new SongRepository(App.getInstance()); - songRepository.getInstantMix(song, 20, new MediaCallback() { - @Override - public void onError(Exception exception) { - Log.e(TAG, "onError() " + exception.getMessage()); + songBottomSheetViewModel.getInstantMix(getViewLifecycleOwner(), song).observe(getViewLifecycleOwner(), songs -> { + if (songs == null) { + dismissBottomSheet(); + return; } - @Override - public void onLoadMedia(List media) { - MediaManager.enqueue(mediaBrowserListenableFuture, requireContext(), (List) media, true); + if (songs.size() > 0) { + MediaManager.enqueue(mediaBrowserListenableFuture, requireContext(), (List) songs, true); dismissBottomSheet(); } }); 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 f0c0bd27..eebe2351 100644 --- a/app/src/main/java/com/cappielloantonio/play/viewmodel/HomeViewModel.java +++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/HomeViewModel.java @@ -52,6 +52,8 @@ public class HomeViewModel extends AndroidViewModel { private final MutableLiveData> newestPodcastEpisodes = new MutableLiveData<>(null); private final MutableLiveData> thisGridTopSong = new MutableLiveData<>(null); + private final MutableLiveData> mediaInstantMix = new MutableLiveData<>(null); + private final MutableLiveData> artistInstantMix = new MutableLiveData<>(null); public HomeViewModel(@NonNull Application application) { super(application); @@ -194,6 +196,22 @@ public class HomeViewModel extends AndroidViewModel { return newestPodcastEpisodes; } + public LiveData> getMediaInstantMix(LifecycleOwner owner, Media media) { + mediaInstantMix.setValue(Collections.emptyList()); + + songRepository.getInstantMix(media, 20).observe(owner, mediaInstantMix::postValue); + + return mediaInstantMix; + } + + public LiveData> getArtistInstantMix(LifecycleOwner owner, Artist artist) { + artistInstantMix.setValue(Collections.emptyList()); + + artistRepository.getInstantMix(artist, 20).observe(owner, artistInstantMix::postValue); + + return artistInstantMix; + } + public void refreshDiscoverySongSample(LifecycleOwner owner) { songRepository.getRandomSample(10, null, null).observe(owner, dicoverSongSample::postValue); } diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java index 1b8bbc99..d2a8e798 100644 --- a/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java +++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java @@ -19,6 +19,7 @@ import com.cappielloantonio.play.util.DownloadUtil; import com.cappielloantonio.play.util.MappingUtil; import com.cappielloantonio.play.util.PreferenceUtil; +import java.util.Collections; import java.util.List; public class PlayerBottomSheetViewModel extends AndroidViewModel { @@ -32,6 +33,8 @@ public class PlayerBottomSheetViewModel extends AndroidViewModel { private final MutableLiveData liveMedia = new MutableLiveData<>(null); private final MutableLiveData liveArtist = new MutableLiveData<>(null); + private final MutableLiveData> instantMix = new MutableLiveData<>(null); + public PlayerBottomSheetViewModel(@NonNull Application application) { super(application); @@ -105,4 +108,12 @@ public class PlayerBottomSheetViewModel extends AndroidViewModel { } } } + + public LiveData> getMediaInstantMix(LifecycleOwner owner, Media media) { + instantMix.setValue(Collections.emptyList()); + + songRepository.getInstantMix(media, 20).observe(owner, instantMix::postValue); + + return instantMix; + } } diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/SongBottomSheetViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/SongBottomSheetViewModel.java index 36684869..9c75aa2d 100644 --- a/app/src/main/java/com/cappielloantonio/play/viewmodel/SongBottomSheetViewModel.java +++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/SongBottomSheetViewModel.java @@ -5,7 +5,10 @@ import android.content.Context; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.media3.common.util.UnstableApi; import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.model.Artist; @@ -17,6 +20,10 @@ import com.cappielloantonio.play.util.DownloadUtil; import com.cappielloantonio.play.util.MappingUtil; import com.cappielloantonio.play.util.PreferenceUtil; +import java.util.Collections; +import java.util.List; + +@UnstableApi public class SongBottomSheetViewModel extends AndroidViewModel { private final SongRepository songRepository; private final AlbumRepository albumRepository; @@ -24,6 +31,8 @@ public class SongBottomSheetViewModel extends AndroidViewModel { private Media song; + private final MutableLiveData> instantMix = new MutableLiveData<>(null); + public SongBottomSheetViewModel(@NonNull Application application) { super(application); @@ -64,4 +73,12 @@ public class SongBottomSheetViewModel extends AndroidViewModel { public LiveData getArtist() { return artistRepository.getArtist(song.getArtistId()); } + + public LiveData> getInstantMix(LifecycleOwner owner, Media media) { + instantMix.setValue(Collections.emptyList()); + + songRepository.getInstantMix(media, 20).observe(owner, instantMix::postValue); + + return instantMix; + } } diff --git a/app/src/main/res/layout/item_library_playlist.xml b/app/src/main/res/layout/item_library_playlist.xml deleted file mode 100644 index a926c467..00000000 --- a/app/src/main/res/layout/item_library_playlist.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/item_player_queue_song.xml b/app/src/main/res/layout/item_player_queue_song.xml index f0e53fae..d7903c67 100644 --- a/app/src/main/res/layout/item_player_queue_song.xml +++ b/app/src/main/res/layout/item_player_queue_song.xml @@ -5,11 +5,22 @@ android:clipChildren="false" android:foreground="?attr/selectableItemBackground" android:orientation="horizontal" - android:paddingStart="24dp" android:paddingTop="3dp" android:paddingEnd="24dp" android:paddingBottom="3dp"> + +