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 d8ba4830..228c582f 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 @@ -1,6 +1,5 @@ package com.cappielloantonio.play.ui.fragment; -import android.content.ComponentName; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; @@ -11,80 +10,24 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; -import androidx.lifecycle.Observer; -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; -import androidx.recyclerview.widget.SnapHelper; -import androidx.viewpager2.widget.ViewPager2; import com.cappielloantonio.play.R; 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.Download; -import com.cappielloantonio.play.service.DownloaderManager; -import com.cappielloantonio.play.service.MediaManager; -import com.cappielloantonio.play.service.MediaService; -import com.cappielloantonio.play.subsonic.models.Child; import com.cappielloantonio.play.ui.activity.MainActivity; -import com.cappielloantonio.play.ui.adapter.AlbumAdapter; -import com.cappielloantonio.play.ui.adapter.AlbumHorizontalAdapter; -import com.cappielloantonio.play.ui.adapter.ArtistAdapter; -import com.cappielloantonio.play.ui.adapter.ArtistHorizontalAdapter; -import com.cappielloantonio.play.ui.adapter.DiscoverSongAdapter; -import com.cappielloantonio.play.ui.adapter.GridTrackAdapter; -import com.cappielloantonio.play.ui.adapter.PodcastEpisodeAdapter; -import com.cappielloantonio.play.ui.adapter.SimilarTrackAdapter; -import com.cappielloantonio.play.ui.adapter.SongHorizontalAdapter; -import com.cappielloantonio.play.ui.adapter.YearAdapter; -import com.cappielloantonio.play.util.Constants; -import com.cappielloantonio.play.util.DownloadUtil; -import com.cappielloantonio.play.util.MappingUtil; -import com.cappielloantonio.play.util.Preferences; -import com.cappielloantonio.play.util.UIUtil; -import com.cappielloantonio.play.viewmodel.HomeViewModel; +import com.cappielloantonio.play.ui.fragment.pager.HomePager; import com.google.android.gms.cast.framework.CastButtonFactory; -import com.google.android.material.snackbar.Snackbar; -import com.google.common.util.concurrent.ListenableFuture; +import com.google.android.material.tabs.TabLayoutMediator; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; @UnstableApi -public class HomeFragment extends Fragment implements ClickCallback { +public class HomeFragment extends Fragment { private static final String TAG = "HomeFragment"; private FragmentHomeBinding bind; private MainActivity activity; - private HomeViewModel homeViewModel; - - private DiscoverSongAdapter discoverSongAdapter; - private SimilarTrackAdapter similarMusicAdapter; - private ArtistAdapter radioArtistAdapter; - private ArtistAdapter bestOfArtistAdapter; - private SongHorizontalAdapter starredSongAdapter; - private AlbumHorizontalAdapter starredAlbumAdapter; - private ArtistHorizontalAdapter starredArtistAdapter; - private AlbumAdapter recentlyAddedAlbumAdapter; - private AlbumAdapter recentlyPlayedAlbumAdapter; - private AlbumAdapter mostPlayedAlbumAdapter; - private AlbumHorizontalAdapter newReleasesAlbumAdapter; - private YearAdapter yearAdapter; - private PodcastEpisodeAdapter podcastEpisodeAdapter; - private GridTrackAdapter gridTrackAdapter; - - private ListenableFuture mediaBrowserListenableFuture; @Override public void onCreate(@Nullable Bundle savedInstanceState) { @@ -103,14 +46,8 @@ public class HomeFragment extends Fragment implements ClickCallback { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { activity = (MainActivity) getActivity(); - bind = FragmentHomeBinding.inflate(inflater, container, false); - View view = bind.getRoot(); - homeViewModel = new ViewModelProvider(requireActivity()).get(HomeViewModel.class); - - init(); - - return view; + return bind.getRoot(); } @Override @@ -118,38 +55,17 @@ public class HomeFragment extends Fragment implements ClickCallback { super.onViewCreated(view, savedInstanceState); initAppBar(); - initSyncStarredView(); - initDiscoverSongSlideView(); - initSimilarSongView(); - initArtistRadio(); - initArtistBestOf(); - initStarredTracksView(); - initStarredAlbumsView(); - initStarredArtistsView(); - initMostPlayedAlbumView(); - initRecentPlayedAlbumView(); - initNewReleasesView(); - initYearSongView(); - initRecentAddedAlbumView(); - initNewestPodcastsView(); - initGridView(); + initHomePager(); } @Override public void onStart() { super.onStart(); - initializeMediaBrowser(); activity.setBottomNavigationBarVisibility(true); activity.setBottomSheetVisibility(true); } - @Override - public void onStop() { - releaseMediaBrowser(); - super.onStop(); - } - @Override public void onDestroyView() { super.onDestroyView(); @@ -169,659 +85,26 @@ public class HomeFragment extends Fragment implements ClickCallback { return false; } - private void init() { - bind.musicDiscoveryTextViewRefreshable.setOnLongClickListener(v -> { - homeViewModel.refreshDiscoverySongSample(getViewLifecycleOwner()); - return true; - }); - - bind.similarTracksTextViewRefreshable.setOnLongClickListener(v -> { - homeViewModel.refreshSimilarSongSample(getViewLifecycleOwner()); - return true; - }); - - bind.radioArtistTextViewRefreshable.setOnLongClickListener(v -> { - homeViewModel.refreshRadioArtistSample(getViewLifecycleOwner()); - return true; - }); - - bind.bestOfArtistTextViewRefreshable.setOnLongClickListener(v -> { - homeViewModel.refreshBestOfArtist(getViewLifecycleOwner()); - return true; - }); - - bind.starredTracksTextViewClickable.setOnClickListener(v -> { - Bundle bundle = new Bundle(); - bundle.putString(Constants.MEDIA_STARRED, Constants.MEDIA_STARRED); - activity.navController.navigate(R.id.action_homeFragment_to_songListPageFragment, bundle); - }); - - bind.starredAlbumsTextViewClickable.setOnClickListener(v -> { - Bundle bundle = new Bundle(); - bundle.putString(Constants.ALBUM_STARRED, Constants.ALBUM_STARRED); - activity.navController.navigate(R.id.action_homeFragment_to_albumListPageFragment, bundle); - }); - - bind.starredArtistsTextViewClickable.setOnClickListener(v -> { - Bundle bundle = new Bundle(); - bundle.putString(Constants.ARTIST_STARRED, Constants.ARTIST_STARRED); - activity.navController.navigate(R.id.action_homeFragment_to_artistListPageFragment, bundle); - }); - - bind.recentlyAddedAlbumsTextViewClickable.setOnClickListener(v -> { - Bundle bundle = new Bundle(); - bundle.putString(Constants.ALBUM_RECENTLY_ADDED, Constants.ALBUM_RECENTLY_ADDED); - activity.navController.navigate(R.id.action_homeFragment_to_albumListPageFragment, bundle); - }); - - bind.recentlyPlayedAlbumsTextViewClickable.setOnClickListener(v -> { - Bundle bundle = new Bundle(); - bundle.putString(Constants.ALBUM_RECENTLY_PLAYED, Constants.ALBUM_RECENTLY_PLAYED); - activity.navController.navigate(R.id.action_homeFragment_to_albumListPageFragment, bundle); - }); - - bind.mostPlayedAlbumsTextViewClickable.setOnClickListener(v -> { - Bundle bundle = new Bundle(); - bundle.putString(Constants.ALBUM_MOST_PLAYED, Constants.ALBUM_MOST_PLAYED); - activity.navController.navigate(R.id.action_homeFragment_to_albumListPageFragment, bundle); - }); - - bind.starredTracksTextViewRefreshable.setOnLongClickListener(v -> { - homeViewModel.refreshStarredTracks(getViewLifecycleOwner()); - return true; - }); - - bind.starredAlbumsTextViewRefreshable.setOnLongClickListener(v -> { - homeViewModel.refreshStarredAlbums(getViewLifecycleOwner()); - return true; - }); - - bind.starredArtistsTextViewRefreshable.setOnLongClickListener(v -> { - homeViewModel.refreshStarredArtists(getViewLifecycleOwner()); - return true; - }); - - bind.recentlyPlayedAlbumsTextViewRefreshable.setOnLongClickListener(v -> { - homeViewModel.refreshRecentlyPlayedAlbumList(getViewLifecycleOwner()); - return true; - }); - - bind.mostPlayedAlbumsTextViewRefreshable.setOnLongClickListener(v -> { - homeViewModel.refreshMostPlayedAlbums(getViewLifecycleOwner()); - return true; - }); - - bind.recentlyAddedAlbumsTextViewRefreshable.setOnLongClickListener(v -> { - homeViewModel.refreshMostRecentlyAddedAlbums(getViewLifecycleOwner()); - return true; - }); - } - private void initAppBar() { activity.setSupportActionBar(bind.toolbar); Objects.requireNonNull(bind.toolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null)); } - private void initSyncStarredView() { - if (Preferences.isStarredSyncEnabled()) { - homeViewModel.getAllStarredTracks().observeForever(new Observer>() { - @Override - public void onChanged(List songs) { - if (songs != null) { - DownloaderManager manager = DownloadUtil.getDownloadTracker(requireContext()); - List toSync = new ArrayList<>(); + private void initHomePager() { + HomePager pager = new HomePager(this); - for (Child song : songs) { - if (!manager.isDownloaded(song.getId())) { - toSync.add(song.getTitle()); - } - } + pager.addFragment(new HomeTabMusicFragment(), "Music", R.drawable.ic_home); + pager.addFragment(new HomeTabPodcastFragment(), "Podcast", R.drawable.ic_graphic_eq); + pager.addFragment(new HomeTabRadioFragment(), "Radio", R.drawable.ic_play_for_work); - if (!toSync.isEmpty()) { - bind.homeSyncStarredCard.setVisibility(View.VISIBLE); - bind.homeSyncStarredTracksToSync.setText(String.join(", ", toSync)); - } - } + bind.homeViewPager.setAdapter(pager); + bind.homeViewPager.setUserInputEnabled(false); - homeViewModel.getAllStarredTracks().removeObserver(this); + new TabLayoutMediator(bind.homeTabLayout, bind.homeViewPager, + (tab, position) -> { + tab.setText(pager.getPageTitle(position)); + // tab.setIcon(pager.getPageIcon(position)); } - }); - } - - bind.homeSyncStarredCancel.setOnClickListener(v -> bind.homeSyncStarredCard.setVisibility(View.GONE)); - - bind.homeSyncStarredDownload.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - homeViewModel.getAllStarredTracks().observeForever(new Observer>() { - @Override - public void onChanged(List songs) { - if (songs != null) { - DownloaderManager manager = DownloadUtil.getDownloadTracker(requireContext()); - - for (Child song : songs) { - if (!manager.isDownloaded(song.getId())) { - manager.download(MappingUtil.mapDownload(song), new Download(song)); - } - } - } - - homeViewModel.getAllStarredTracks().removeObserver(this); - bind.homeSyncStarredCard.setVisibility(View.GONE); - } - }); - } - }); - } - - private void initDiscoverSongSlideView() { - bind.discoverSongViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); - - discoverSongAdapter = new DiscoverSongAdapter(this); - bind.discoverSongViewPager.setAdapter(discoverSongAdapter); - bind.discoverSongViewPager.setOffscreenPageLimit(1); - homeViewModel.getDiscoverSongSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { - if (songs == null) { - if (bind != null) - bind.homeDiscoveryPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.homeDiscoverSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.homeDiscoveryPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.homeDiscoverSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE); - - discoverSongAdapter.setItems(songs); - } - }); - - setSlideViewOffset(bind.discoverSongViewPager, 20, 16); - } - - private void initSimilarSongView() { - bind.similarTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - bind.similarTracksRecyclerView.setHasFixedSize(true); - - similarMusicAdapter = new SimilarTrackAdapter(this); - bind.similarTracksRecyclerView.setAdapter(similarMusicAdapter); - homeViewModel.getStarredTracksSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { - if (songs == null) { - if (bind != null) - bind.homeSimilarTracksPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.homeSimilarTracksSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.homeSimilarTracksPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.homeSimilarTracksSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE); - - similarMusicAdapter.setItems(songs); - } - }); - - CustomLinearSnapHelper similarSongSnapHelper = new CustomLinearSnapHelper(); - similarSongSnapHelper.attachToRecyclerView(bind.similarTracksRecyclerView); - } - - private void initArtistRadio() { - bind.radioArtistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - bind.radioArtistRecyclerView.setHasFixedSize(true); - - radioArtistAdapter = new ArtistAdapter(this, true, false); - bind.radioArtistRecyclerView.setAdapter(radioArtistAdapter); - homeViewModel.getStarredArtistsSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { - if (artists == null) { - if (bind != null) - bind.homeRadioArtistPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.homeRadioArtistSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.homeRadioArtistPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.homeRadioArtistSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE); - - radioArtistAdapter.setItems(artists); - } - }); - - CustomLinearSnapHelper artistRadioSnapHelper = new CustomLinearSnapHelper(); - artistRadioSnapHelper.attachToRecyclerView(bind.radioArtistRecyclerView); - } - - private void initArtistBestOf() { - bind.bestOfArtistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - bind.bestOfArtistRecyclerView.setHasFixedSize(true); - - bestOfArtistAdapter = new ArtistAdapter(this, false, true); - bind.bestOfArtistRecyclerView.setAdapter(bestOfArtistAdapter); - homeViewModel.getBestOfArtists(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { - if (artists == null) { - if (bind != null) - bind.homeBestOfArtistPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.homeBestOfArtistSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.homeBestOfArtistPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.homeBestOfArtistSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE); - - bestOfArtistAdapter.setItems(artists); - } - }); - - CustomLinearSnapHelper artistBestOfSnapHelper = new CustomLinearSnapHelper(); - artistBestOfSnapHelper.attachToRecyclerView(bind.bestOfArtistRecyclerView); - } - - private void initStarredTracksView() { - bind.starredTracksRecyclerView.setHasFixedSize(true); - - starredSongAdapter = new SongHorizontalAdapter(this, true); - bind.starredTracksRecyclerView.setAdapter(starredSongAdapter); - homeViewModel.getStarredTracks(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { - if (songs == null) { - if (bind != null) - bind.starredTracksPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.starredTracksSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.starredTracksPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.starredTracksSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE); - if (bind != null) - bind.starredTracksRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(songs.size(), 5), GridLayoutManager.HORIZONTAL, false)); - - starredSongAdapter.setItems(songs); - } - }); - - SnapHelper starredTrackSnapHelper = new PagerSnapHelper(); - starredTrackSnapHelper.attachToRecyclerView(bind.starredTracksRecyclerView); - - bind.starredTracksRecyclerView.addItemDecoration( - new DotsIndicatorDecoration( - getResources().getDimensionPixelSize(R.dimen.radius), - getResources().getDimensionPixelSize(R.dimen.radius) * 4, - getResources().getDimensionPixelSize(R.dimen.dots_height), - requireContext().getResources().getColor(R.color.titleTextColor, null), - requireContext().getResources().getColor(R.color.titleTextColor, null)) - ); - } - - private void initStarredAlbumsView() { - bind.starredAlbumsRecyclerView.setHasFixedSize(true); - - starredAlbumAdapter = new AlbumHorizontalAdapter(this, false); - bind.starredAlbumsRecyclerView.setAdapter(starredAlbumAdapter); - homeViewModel.getStarredAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { - if (albums == null) { - if (bind != null) - bind.starredAlbumsPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.starredAlbumsSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.starredAlbumsPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.starredAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); - if (bind != null) - bind.starredAlbumsRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(albums.size(), 5), GridLayoutManager.HORIZONTAL, false)); - - starredAlbumAdapter.setItems(albums); - } - }); - - SnapHelper starredAlbumSnapHelper = new PagerSnapHelper(); - starredAlbumSnapHelper.attachToRecyclerView(bind.starredAlbumsRecyclerView); - - bind.starredAlbumsRecyclerView.addItemDecoration( - new DotsIndicatorDecoration( - getResources().getDimensionPixelSize(R.dimen.radius), - getResources().getDimensionPixelSize(R.dimen.radius) * 4, - getResources().getDimensionPixelSize(R.dimen.dots_height), - requireContext().getResources().getColor(R.color.titleTextColor, null), - requireContext().getResources().getColor(R.color.titleTextColor, null)) - ); - } - - private void initStarredArtistsView() { - bind.starredArtistsRecyclerView.setHasFixedSize(true); - - starredArtistAdapter = new ArtistHorizontalAdapter(this); - bind.starredArtistsRecyclerView.setAdapter(starredArtistAdapter); - homeViewModel.getStarredArtists(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { - if (artists == null) { - if (bind != null) - bind.starredArtistsPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.starredArtistsSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.starredArtistsPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.starredArtistsSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE); - if (bind != null) - bind.starredArtistsRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(artists.size(), 5), GridLayoutManager.HORIZONTAL, false)); - - starredArtistAdapter.setItems(artists); - } - }); - - SnapHelper starredArtistSnapHelper = new PagerSnapHelper(); - starredArtistSnapHelper.attachToRecyclerView(bind.starredArtistsRecyclerView); - - bind.starredArtistsRecyclerView.addItemDecoration( - new DotsIndicatorDecoration( - getResources().getDimensionPixelSize(R.dimen.radius), - getResources().getDimensionPixelSize(R.dimen.radius) * 4, - getResources().getDimensionPixelSize(R.dimen.dots_height), - requireContext().getResources().getColor(R.color.titleTextColor, null), - requireContext().getResources().getColor(R.color.titleTextColor, null)) - ); - } - - private void initNewReleasesView() { - bind.newReleasesRecyclerView.setHasFixedSize(true); - - newReleasesAlbumAdapter = new AlbumHorizontalAdapter(this, false); - bind.newReleasesRecyclerView.setAdapter(newReleasesAlbumAdapter); - homeViewModel.getRecentlyReleasedAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { - if (albums == null) { - if (bind != null) - bind.homeNewReleasesPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.homeNewReleasesSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.homeNewReleasesPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.homeNewReleasesSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); - if (bind != null) - bind.newReleasesRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(albums.size(), 5), GridLayoutManager.HORIZONTAL, false)); - - newReleasesAlbumAdapter.setItems(albums); - } - }); - - SnapHelper newReleasesSnapHelper = new PagerSnapHelper(); - newReleasesSnapHelper.attachToRecyclerView(bind.newReleasesRecyclerView); - - bind.newReleasesRecyclerView.addItemDecoration( - new DotsIndicatorDecoration( - getResources().getDimensionPixelSize(R.dimen.radius), - getResources().getDimensionPixelSize(R.dimen.radius) * 4, - getResources().getDimensionPixelSize(R.dimen.dots_height), - requireContext().getResources().getColor(R.color.titleTextColor, null), - requireContext().getResources().getColor(R.color.titleTextColor, null)) - ); - } - - private void initYearSongView() { - bind.yearsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - bind.yearsRecyclerView.setHasFixedSize(true); - - yearAdapter = new YearAdapter(this); - bind.yearsRecyclerView.setAdapter(yearAdapter); - homeViewModel.getYearList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), years -> { - if (years == null) { - if (bind != null) - bind.homeFlashbackPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.homeFlashbackSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.homeFlashbackPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.homeFlashbackSector.setVisibility(!years.isEmpty() ? View.VISIBLE : View.GONE); - - yearAdapter.setItems(years); - } - }); - - CustomLinearSnapHelper yearSnapHelper = new CustomLinearSnapHelper(); - yearSnapHelper.attachToRecyclerView(bind.yearsRecyclerView); - } - - private void initMostPlayedAlbumView() { - bind.mostPlayedAlbumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - bind.mostPlayedAlbumsRecyclerView.setHasFixedSize(true); - - mostPlayedAlbumAdapter = new AlbumAdapter(this); - bind.mostPlayedAlbumsRecyclerView.setAdapter(mostPlayedAlbumAdapter); - homeViewModel.getMostPlayedAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { - if (albums == null) { - if (bind != null) - bind.homeMostPlayedAlbumsPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.homeMostPlayedAlbumsSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.homeMostPlayedAlbumsPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.homeMostPlayedAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); - // if (albums.size() < 5) reorder(); - - mostPlayedAlbumAdapter.setItems(albums); - } - }); - - CustomLinearSnapHelper mostPlayedAlbumSnapHelper = new CustomLinearSnapHelper(); - mostPlayedAlbumSnapHelper.attachToRecyclerView(bind.mostPlayedAlbumsRecyclerView); - } - - private void initRecentPlayedAlbumView() { - bind.recentlyPlayedAlbumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - bind.recentlyPlayedAlbumsRecyclerView.setHasFixedSize(true); - - recentlyPlayedAlbumAdapter = new AlbumAdapter(this); - bind.recentlyPlayedAlbumsRecyclerView.setAdapter(recentlyPlayedAlbumAdapter); - homeViewModel.getRecentlyPlayedAlbumList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { - if (albums == null) { - if (bind != null) - bind.homeRecentlyPlayedAlbumsPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.homeRecentlyPlayedAlbumsSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.homeRecentlyPlayedAlbumsPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.homeRecentlyPlayedAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); - - recentlyPlayedAlbumAdapter.setItems(albums); - } - }); - - CustomLinearSnapHelper recentPlayedAlbumSnapHelper = new CustomLinearSnapHelper(); - recentPlayedAlbumSnapHelper.attachToRecyclerView(bind.recentlyPlayedAlbumsRecyclerView); - } - - private void initRecentAddedAlbumView() { - bind.recentlyAddedAlbumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); - bind.recentlyAddedAlbumsRecyclerView.setHasFixedSize(true); - - recentlyAddedAlbumAdapter = new AlbumAdapter(this); - bind.recentlyAddedAlbumsRecyclerView.setAdapter(recentlyAddedAlbumAdapter); - homeViewModel.getMostRecentlyAddedAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { - if (albums == null) { - if (bind != null) - bind.homeRecentlyAddedAlbumsPlaceholder.placeholder.setVisibility(View.VISIBLE); - if (bind != null) bind.homeRecentlyAddedAlbumsSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.homeRecentlyAddedAlbumsPlaceholder.placeholder.setVisibility(View.GONE); - if (bind != null) - bind.homeRecentlyAddedAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); - - recentlyAddedAlbumAdapter.setItems(albums); - } - }); - - CustomLinearSnapHelper recentAddedAlbumSnapHelper = new CustomLinearSnapHelper(); - recentAddedAlbumSnapHelper.attachToRecyclerView(bind.recentlyAddedAlbumsRecyclerView); - } - - private void initNewestPodcastsView() { - bind.newestPodcastsViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); - - podcastEpisodeAdapter = new PodcastEpisodeAdapter(this); - bind.newestPodcastsViewPager.setAdapter(podcastEpisodeAdapter); - bind.newestPodcastsViewPager.setOffscreenPageLimit(1); - homeViewModel.getNewestPodcastEpisodes(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), podcastEpisodes -> { - if (podcastEpisodes == null) { - if (bind != null) bind.homeNewestPodcastsSector.setVisibility(View.GONE); - } else { - if (bind != null) - bind.homeNewestPodcastsSector.setVisibility(!podcastEpisodes.isEmpty() ? View.VISIBLE : View.GONE); - - podcastEpisodeAdapter.setItems(podcastEpisodes); - } - }); - - setSlideViewOffset(bind.newestPodcastsViewPager, 20, 16); - } - - private void initGridView() { - bind.gridTracksRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 3)); - bind.gridTracksRecyclerView.addItemDecoration(new GridItemDecoration(3, 8, false)); - bind.gridTracksRecyclerView.setHasFixedSize(true); - - gridTrackAdapter = new GridTrackAdapter(this); - bind.gridTracksRecyclerView.setAdapter(gridTrackAdapter); - - homeViewModel.getGridSongSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), chronologies -> { - if (chronologies == null || chronologies.size() == 0) { - if (bind != null) bind.homeGridTracksSector.setVisibility(View.GONE); - if (bind != null) bind.afterGridDivider.setVisibility(View.GONE); - } else { - if (bind != null) bind.homeGridTracksSector.setVisibility(View.VISIBLE); - if (bind != null) bind.afterGridDivider.setVisibility(View.VISIBLE); - gridTrackAdapter.setItems(chronologies); - } - }); - } - - private void setSlideViewOffset(ViewPager2 viewPager, float pageOffset, float pageMargin) { - viewPager.setPageTransformer((page, position) -> { - float myOffset = position * -(2 * pageOffset + pageMargin); - if (viewPager.getOrientation() == ViewPager2.ORIENTATION_HORIZONTAL) { - if (ViewCompat.getLayoutDirection(viewPager) == ViewCompat.LAYOUT_DIRECTION_RTL) { - page.setTranslationX(-myOffset); - } else { - page.setTranslationX(myOffset); - } - } else { - page.setTranslationY(myOffset); - } - }); - } - - public void reorder() { - if (bind != null) { - // bind.homeLinearLayoutContainer.removeAllViews(); - // bind.homeLinearLayoutContainer.addView(bind.homeDiscoverSector); - - // bind.homeLinearLayoutContainer.addView(bind.homeSimilarTracksSector); - // bind.homeLinearLayoutContainer.addView(bind.homeRadioArtistSector); - // bind.homeLinearLayoutContainer.addView(bind.homeGridTracksSector); - // bind.homeLinearLayoutContainer.addView(bind.starredTracksSector); - // bind.homeLinearLayoutContainer.addView(bind.starredAlbumsSector); - // bind.homeLinearLayoutContainer.addView(bind.starredArtistsSector); - - // bind.homeLinearLayoutContainer.addView(bind.homeRecentlyAddedAlbumsSector); - // bind.homeLinearLayoutContainer.addView(bind.homeFlashbackSector); - // bind.homeLinearLayoutContainer.addView(bind.homeMostPlayedAlbumsSector); - // bind.homeLinearLayoutContainer.addView(bind.homeRecentlyPlayedAlbumsSector); - // bind.homeLinearLayoutContainer.addView(bind.homeNewestPodcastsSector); - } - } - - private void initializeMediaBrowser() { - mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync(); - } - - private void releaseMediaBrowser() { - MediaBrowser.releaseFuture(mediaBrowserListenableFuture); - } - - @Override - public void onMediaClick(Bundle bundle) { - if (bundle.containsKey(Constants.MEDIA_MIX)) { - MediaManager.startQueue(mediaBrowserListenableFuture, bundle.getParcelable(Constants.TRACK_OBJECT)); - activity.setBottomSheetInPeek(true); - - if (mediaBrowserListenableFuture != null) { - homeViewModel.getMediaInstantMix(getViewLifecycleOwner(), bundle.getParcelable(Constants.TRACK_OBJECT)).observe(getViewLifecycleOwner(), songs -> { - if (songs != null && songs.size() > 0) { - MediaManager.enqueue(mediaBrowserListenableFuture, songs, true); - } - }); - } - } else if (bundle.containsKey(Constants.MEDIA_CHRONOLOGY)) { - List media = bundle.getParcelableArrayList(Constants.TRACKS_OBJECT); - MediaManager.startQueue(mediaBrowserListenableFuture, media, bundle.getInt(Constants.ITEM_POSITION)); - activity.setBottomSheetInPeek(true); - } else { - MediaManager.startQueue(mediaBrowserListenableFuture, bundle.getParcelableArrayList(Constants.TRACKS_OBJECT), bundle.getInt(Constants.ITEM_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(Constants.MEDIA_MIX) && bundle.getBoolean(Constants.MEDIA_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(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> { - if (songs.size() > 0) { - MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0); - activity.setBottomSheetInPeek(true); - } - }); - } - } else if (bundle.containsKey(Constants.MEDIA_BEST_OF) && bundle.getBoolean(Constants.MEDIA_BEST_OF)) { - if (mediaBrowserListenableFuture != null) { - homeViewModel.getArtistBestOf(getViewLifecycleOwner(), bundle.getParcelable(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> { - if (songs.size() > 0) { - MediaManager.startQueue(mediaBrowserListenableFuture, 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, bundle.getParcelable(Constants.PODCAST_OBJECT)); - activity.setBottomSheetInPeek(true); - } - - @Override - public void onPodcastLongClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.podcastBottomSheetDialog, bundle); + ).attach(); } } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeTabMusicFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeTabMusicFragment.java new file mode 100644 index 00000000..514efb8d --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeTabMusicFragment.java @@ -0,0 +1,788 @@ +package com.cappielloantonio.play.ui.fragment; + +import android.content.ComponentName; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.view.ViewCompat; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Observer; +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; +import androidx.recyclerview.widget.SnapHelper; +import androidx.viewpager2.widget.ViewPager2; + +import com.cappielloantonio.play.R; +import com.cappielloantonio.play.databinding.FragmentHomeTabMusicBinding; +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.Download; +import com.cappielloantonio.play.service.DownloaderManager; +import com.cappielloantonio.play.service.MediaManager; +import com.cappielloantonio.play.service.MediaService; +import com.cappielloantonio.play.subsonic.models.Child; +import com.cappielloantonio.play.ui.activity.MainActivity; +import com.cappielloantonio.play.ui.adapter.AlbumAdapter; +import com.cappielloantonio.play.ui.adapter.AlbumHorizontalAdapter; +import com.cappielloantonio.play.ui.adapter.ArtistAdapter; +import com.cappielloantonio.play.ui.adapter.ArtistHorizontalAdapter; +import com.cappielloantonio.play.ui.adapter.DiscoverSongAdapter; +import com.cappielloantonio.play.ui.adapter.GridTrackAdapter; +import com.cappielloantonio.play.ui.adapter.PodcastEpisodeAdapter; +import com.cappielloantonio.play.ui.adapter.SimilarTrackAdapter; +import com.cappielloantonio.play.ui.adapter.SongHorizontalAdapter; +import com.cappielloantonio.play.ui.adapter.YearAdapter; +import com.cappielloantonio.play.util.Constants; +import com.cappielloantonio.play.util.DownloadUtil; +import com.cappielloantonio.play.util.MappingUtil; +import com.cappielloantonio.play.util.Preferences; +import com.cappielloantonio.play.util.UIUtil; +import com.cappielloantonio.play.viewmodel.HomeViewModel; +import com.google.android.material.snackbar.Snackbar; +import com.google.common.util.concurrent.ListenableFuture; + +import java.util.ArrayList; +import java.util.List; + +@UnstableApi +public class HomeTabMusicFragment extends Fragment implements ClickCallback { + private static final String TAG = "HomeFragment"; + + private FragmentHomeTabMusicBinding bind; + private MainActivity activity; + private HomeViewModel homeViewModel; + + private DiscoverSongAdapter discoverSongAdapter; + private SimilarTrackAdapter similarMusicAdapter; + private ArtistAdapter radioArtistAdapter; + private ArtistAdapter bestOfArtistAdapter; + private SongHorizontalAdapter starredSongAdapter; + private AlbumHorizontalAdapter starredAlbumAdapter; + private ArtistHorizontalAdapter starredArtistAdapter; + private AlbumAdapter recentlyAddedAlbumAdapter; + private AlbumAdapter recentlyPlayedAlbumAdapter; + private AlbumAdapter mostPlayedAlbumAdapter; + private AlbumHorizontalAdapter newReleasesAlbumAdapter; + private YearAdapter yearAdapter; + private PodcastEpisodeAdapter podcastEpisodeAdapter; + private GridTrackAdapter gridTrackAdapter; + + private ListenableFuture mediaBrowserListenableFuture; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + activity = (MainActivity) getActivity(); + + bind = FragmentHomeTabMusicBinding.inflate(inflater, container, false); + View view = bind.getRoot(); + homeViewModel = new ViewModelProvider(requireActivity()).get(HomeViewModel.class); + + init(); + + return view; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + initSyncStarredView(); + initDiscoverSongSlideView(); + initSimilarSongView(); + initArtistRadio(); + initArtistBestOf(); + initStarredTracksView(); + initStarredAlbumsView(); + initStarredArtistsView(); + initMostPlayedAlbumView(); + initRecentPlayedAlbumView(); + initNewReleasesView(); + initYearSongView(); + initRecentAddedAlbumView(); + initNewestPodcastsView(); + initGridView(); + } + + @Override + public void onStart() { + super.onStart(); + + initializeMediaBrowser(); + } + + @Override + public void onStop() { + releaseMediaBrowser(); + super.onStop(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind = null; + } + + private void init() { + bind.musicDiscoveryTextViewRefreshable.setOnLongClickListener(v -> { + homeViewModel.refreshDiscoverySongSample(getViewLifecycleOwner()); + return true; + }); + + bind.similarTracksTextViewRefreshable.setOnLongClickListener(v -> { + homeViewModel.refreshSimilarSongSample(getViewLifecycleOwner()); + return true; + }); + + bind.radioArtistTextViewRefreshable.setOnLongClickListener(v -> { + homeViewModel.refreshRadioArtistSample(getViewLifecycleOwner()); + return true; + }); + + bind.bestOfArtistTextViewRefreshable.setOnLongClickListener(v -> { + homeViewModel.refreshBestOfArtist(getViewLifecycleOwner()); + return true; + }); + + bind.starredTracksTextViewClickable.setOnClickListener(v -> { + Bundle bundle = new Bundle(); + bundle.putString(Constants.MEDIA_STARRED, Constants.MEDIA_STARRED); + activity.navController.navigate(R.id.action_homeFragment_to_songListPageFragment, bundle); + }); + + bind.starredAlbumsTextViewClickable.setOnClickListener(v -> { + Bundle bundle = new Bundle(); + bundle.putString(Constants.ALBUM_STARRED, Constants.ALBUM_STARRED); + activity.navController.navigate(R.id.action_homeFragment_to_albumListPageFragment, bundle); + }); + + bind.starredArtistsTextViewClickable.setOnClickListener(v -> { + Bundle bundle = new Bundle(); + bundle.putString(Constants.ARTIST_STARRED, Constants.ARTIST_STARRED); + activity.navController.navigate(R.id.action_homeFragment_to_artistListPageFragment, bundle); + }); + + bind.recentlyAddedAlbumsTextViewClickable.setOnClickListener(v -> { + Bundle bundle = new Bundle(); + bundle.putString(Constants.ALBUM_RECENTLY_ADDED, Constants.ALBUM_RECENTLY_ADDED); + activity.navController.navigate(R.id.action_homeFragment_to_albumListPageFragment, bundle); + }); + + bind.recentlyPlayedAlbumsTextViewClickable.setOnClickListener(v -> { + Bundle bundle = new Bundle(); + bundle.putString(Constants.ALBUM_RECENTLY_PLAYED, Constants.ALBUM_RECENTLY_PLAYED); + activity.navController.navigate(R.id.action_homeFragment_to_albumListPageFragment, bundle); + }); + + bind.mostPlayedAlbumsTextViewClickable.setOnClickListener(v -> { + Bundle bundle = new Bundle(); + bundle.putString(Constants.ALBUM_MOST_PLAYED, Constants.ALBUM_MOST_PLAYED); + activity.navController.navigate(R.id.action_homeFragment_to_albumListPageFragment, bundle); + }); + + bind.starredTracksTextViewRefreshable.setOnLongClickListener(v -> { + homeViewModel.refreshStarredTracks(getViewLifecycleOwner()); + return true; + }); + + bind.starredAlbumsTextViewRefreshable.setOnLongClickListener(v -> { + homeViewModel.refreshStarredAlbums(getViewLifecycleOwner()); + return true; + }); + + bind.starredArtistsTextViewRefreshable.setOnLongClickListener(v -> { + homeViewModel.refreshStarredArtists(getViewLifecycleOwner()); + return true; + }); + + bind.recentlyPlayedAlbumsTextViewRefreshable.setOnLongClickListener(v -> { + homeViewModel.refreshRecentlyPlayedAlbumList(getViewLifecycleOwner()); + return true; + }); + + bind.mostPlayedAlbumsTextViewRefreshable.setOnLongClickListener(v -> { + homeViewModel.refreshMostPlayedAlbums(getViewLifecycleOwner()); + return true; + }); + + bind.recentlyAddedAlbumsTextViewRefreshable.setOnLongClickListener(v -> { + homeViewModel.refreshMostRecentlyAddedAlbums(getViewLifecycleOwner()); + return true; + }); + } + + private void initSyncStarredView() { + if (Preferences.isStarredSyncEnabled()) { + homeViewModel.getAllStarredTracks().observeForever(new Observer>() { + @Override + public void onChanged(List songs) { + if (songs != null) { + DownloaderManager manager = DownloadUtil.getDownloadTracker(requireContext()); + List toSync = new ArrayList<>(); + + for (Child song : songs) { + if (!manager.isDownloaded(song.getId())) { + toSync.add(song.getTitle()); + } + } + + if (!toSync.isEmpty()) { + bind.homeSyncStarredCard.setVisibility(View.VISIBLE); + bind.homeSyncStarredTracksToSync.setText(String.join(", ", toSync)); + } + } + + homeViewModel.getAllStarredTracks().removeObserver(this); + } + }); + } + + bind.homeSyncStarredCancel.setOnClickListener(v -> bind.homeSyncStarredCard.setVisibility(View.GONE)); + + bind.homeSyncStarredDownload.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + homeViewModel.getAllStarredTracks().observeForever(new Observer>() { + @Override + public void onChanged(List songs) { + if (songs != null) { + DownloaderManager manager = DownloadUtil.getDownloadTracker(requireContext()); + + for (Child song : songs) { + if (!manager.isDownloaded(song.getId())) { + manager.download(MappingUtil.mapDownload(song), new Download(song)); + } + } + } + + homeViewModel.getAllStarredTracks().removeObserver(this); + bind.homeSyncStarredCard.setVisibility(View.GONE); + } + }); + } + }); + } + + private void initDiscoverSongSlideView() { + bind.discoverSongViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); + + discoverSongAdapter = new DiscoverSongAdapter(this); + bind.discoverSongViewPager.setAdapter(discoverSongAdapter); + bind.discoverSongViewPager.setOffscreenPageLimit(1); + homeViewModel.getDiscoverSongSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { + if (songs == null) { + if (bind != null) + bind.homeDiscoveryPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.homeDiscoverSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.homeDiscoveryPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.homeDiscoverSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE); + + discoverSongAdapter.setItems(songs); + } + }); + + setSlideViewOffset(bind.discoverSongViewPager, 20, 16); + } + + private void initSimilarSongView() { + bind.similarTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); + bind.similarTracksRecyclerView.setHasFixedSize(true); + + similarMusicAdapter = new SimilarTrackAdapter(this); + bind.similarTracksRecyclerView.setAdapter(similarMusicAdapter); + homeViewModel.getStarredTracksSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { + if (songs == null) { + if (bind != null) + bind.homeSimilarTracksPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.homeSimilarTracksSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.homeSimilarTracksPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.homeSimilarTracksSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE); + + similarMusicAdapter.setItems(songs); + } + }); + + CustomLinearSnapHelper similarSongSnapHelper = new CustomLinearSnapHelper(); + similarSongSnapHelper.attachToRecyclerView(bind.similarTracksRecyclerView); + } + + private void initArtistRadio() { + bind.radioArtistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); + bind.radioArtistRecyclerView.setHasFixedSize(true); + + radioArtistAdapter = new ArtistAdapter(this, true, false); + bind.radioArtistRecyclerView.setAdapter(radioArtistAdapter); + homeViewModel.getStarredArtistsSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { + if (artists == null) { + if (bind != null) + bind.homeRadioArtistPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.homeRadioArtistSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.homeRadioArtistPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.homeRadioArtistSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE); + + radioArtistAdapter.setItems(artists); + } + }); + + CustomLinearSnapHelper artistRadioSnapHelper = new CustomLinearSnapHelper(); + artistRadioSnapHelper.attachToRecyclerView(bind.radioArtistRecyclerView); + } + + private void initArtistBestOf() { + bind.bestOfArtistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); + bind.bestOfArtistRecyclerView.setHasFixedSize(true); + + bestOfArtistAdapter = new ArtistAdapter(this, false, true); + bind.bestOfArtistRecyclerView.setAdapter(bestOfArtistAdapter); + homeViewModel.getBestOfArtists(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { + if (artists == null) { + if (bind != null) + bind.homeBestOfArtistPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.homeBestOfArtistSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.homeBestOfArtistPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.homeBestOfArtistSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE); + + bestOfArtistAdapter.setItems(artists); + } + }); + + CustomLinearSnapHelper artistBestOfSnapHelper = new CustomLinearSnapHelper(); + artistBestOfSnapHelper.attachToRecyclerView(bind.bestOfArtistRecyclerView); + } + + private void initStarredTracksView() { + bind.starredTracksRecyclerView.setHasFixedSize(true); + + starredSongAdapter = new SongHorizontalAdapter(this, true); + bind.starredTracksRecyclerView.setAdapter(starredSongAdapter); + homeViewModel.getStarredTracks(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { + if (songs == null) { + if (bind != null) + bind.starredTracksPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.starredTracksSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.starredTracksPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.starredTracksSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.starredTracksRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(songs.size(), 5), GridLayoutManager.HORIZONTAL, false)); + + starredSongAdapter.setItems(songs); + } + }); + + SnapHelper starredTrackSnapHelper = new PagerSnapHelper(); + starredTrackSnapHelper.attachToRecyclerView(bind.starredTracksRecyclerView); + + bind.starredTracksRecyclerView.addItemDecoration( + new DotsIndicatorDecoration( + getResources().getDimensionPixelSize(R.dimen.radius), + getResources().getDimensionPixelSize(R.dimen.radius) * 4, + getResources().getDimensionPixelSize(R.dimen.dots_height), + requireContext().getResources().getColor(R.color.titleTextColor, null), + requireContext().getResources().getColor(R.color.titleTextColor, null)) + ); + } + + private void initStarredAlbumsView() { + bind.starredAlbumsRecyclerView.setHasFixedSize(true); + + starredAlbumAdapter = new AlbumHorizontalAdapter(this, false); + bind.starredAlbumsRecyclerView.setAdapter(starredAlbumAdapter); + homeViewModel.getStarredAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { + if (albums == null) { + if (bind != null) + bind.starredAlbumsPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.starredAlbumsSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.starredAlbumsPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.starredAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.starredAlbumsRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(albums.size(), 5), GridLayoutManager.HORIZONTAL, false)); + + starredAlbumAdapter.setItems(albums); + } + }); + + SnapHelper starredAlbumSnapHelper = new PagerSnapHelper(); + starredAlbumSnapHelper.attachToRecyclerView(bind.starredAlbumsRecyclerView); + + bind.starredAlbumsRecyclerView.addItemDecoration( + new DotsIndicatorDecoration( + getResources().getDimensionPixelSize(R.dimen.radius), + getResources().getDimensionPixelSize(R.dimen.radius) * 4, + getResources().getDimensionPixelSize(R.dimen.dots_height), + requireContext().getResources().getColor(R.color.titleTextColor, null), + requireContext().getResources().getColor(R.color.titleTextColor, null)) + ); + } + + private void initStarredArtistsView() { + bind.starredArtistsRecyclerView.setHasFixedSize(true); + + starredArtistAdapter = new ArtistHorizontalAdapter(this); + bind.starredArtistsRecyclerView.setAdapter(starredArtistAdapter); + homeViewModel.getStarredArtists(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { + if (artists == null) { + if (bind != null) + bind.starredArtistsPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.starredArtistsSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.starredArtistsPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.starredArtistsSector.setVisibility(!artists.isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.starredArtistsRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(artists.size(), 5), GridLayoutManager.HORIZONTAL, false)); + + starredArtistAdapter.setItems(artists); + } + }); + + SnapHelper starredArtistSnapHelper = new PagerSnapHelper(); + starredArtistSnapHelper.attachToRecyclerView(bind.starredArtistsRecyclerView); + + bind.starredArtistsRecyclerView.addItemDecoration( + new DotsIndicatorDecoration( + getResources().getDimensionPixelSize(R.dimen.radius), + getResources().getDimensionPixelSize(R.dimen.radius) * 4, + getResources().getDimensionPixelSize(R.dimen.dots_height), + requireContext().getResources().getColor(R.color.titleTextColor, null), + requireContext().getResources().getColor(R.color.titleTextColor, null)) + ); + } + + private void initNewReleasesView() { + bind.newReleasesRecyclerView.setHasFixedSize(true); + + newReleasesAlbumAdapter = new AlbumHorizontalAdapter(this, false); + bind.newReleasesRecyclerView.setAdapter(newReleasesAlbumAdapter); + homeViewModel.getRecentlyReleasedAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { + if (albums == null) { + if (bind != null) + bind.homeNewReleasesPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.homeNewReleasesSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.homeNewReleasesPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.homeNewReleasesSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); + if (bind != null) + bind.newReleasesRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(albums.size(), 5), GridLayoutManager.HORIZONTAL, false)); + + newReleasesAlbumAdapter.setItems(albums); + } + }); + + SnapHelper newReleasesSnapHelper = new PagerSnapHelper(); + newReleasesSnapHelper.attachToRecyclerView(bind.newReleasesRecyclerView); + + bind.newReleasesRecyclerView.addItemDecoration( + new DotsIndicatorDecoration( + getResources().getDimensionPixelSize(R.dimen.radius), + getResources().getDimensionPixelSize(R.dimen.radius) * 4, + getResources().getDimensionPixelSize(R.dimen.dots_height), + requireContext().getResources().getColor(R.color.titleTextColor, null), + requireContext().getResources().getColor(R.color.titleTextColor, null)) + ); + } + + private void initYearSongView() { + bind.yearsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); + bind.yearsRecyclerView.setHasFixedSize(true); + + yearAdapter = new YearAdapter(this); + bind.yearsRecyclerView.setAdapter(yearAdapter); + homeViewModel.getYearList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), years -> { + if (years == null) { + if (bind != null) + bind.homeFlashbackPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.homeFlashbackSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.homeFlashbackPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.homeFlashbackSector.setVisibility(!years.isEmpty() ? View.VISIBLE : View.GONE); + + yearAdapter.setItems(years); + } + }); + + CustomLinearSnapHelper yearSnapHelper = new CustomLinearSnapHelper(); + yearSnapHelper.attachToRecyclerView(bind.yearsRecyclerView); + } + + private void initMostPlayedAlbumView() { + bind.mostPlayedAlbumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); + bind.mostPlayedAlbumsRecyclerView.setHasFixedSize(true); + + mostPlayedAlbumAdapter = new AlbumAdapter(this); + bind.mostPlayedAlbumsRecyclerView.setAdapter(mostPlayedAlbumAdapter); + homeViewModel.getMostPlayedAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { + if (albums == null) { + if (bind != null) + bind.homeMostPlayedAlbumsPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.homeMostPlayedAlbumsSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.homeMostPlayedAlbumsPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.homeMostPlayedAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); + // if (albums.size() < 5) reorder(); + + mostPlayedAlbumAdapter.setItems(albums); + } + }); + + CustomLinearSnapHelper mostPlayedAlbumSnapHelper = new CustomLinearSnapHelper(); + mostPlayedAlbumSnapHelper.attachToRecyclerView(bind.mostPlayedAlbumsRecyclerView); + } + + private void initRecentPlayedAlbumView() { + bind.recentlyPlayedAlbumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); + bind.recentlyPlayedAlbumsRecyclerView.setHasFixedSize(true); + + recentlyPlayedAlbumAdapter = new AlbumAdapter(this); + bind.recentlyPlayedAlbumsRecyclerView.setAdapter(recentlyPlayedAlbumAdapter); + homeViewModel.getRecentlyPlayedAlbumList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { + if (albums == null) { + if (bind != null) + bind.homeRecentlyPlayedAlbumsPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.homeRecentlyPlayedAlbumsSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.homeRecentlyPlayedAlbumsPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.homeRecentlyPlayedAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); + + recentlyPlayedAlbumAdapter.setItems(albums); + } + }); + + CustomLinearSnapHelper recentPlayedAlbumSnapHelper = new CustomLinearSnapHelper(); + recentPlayedAlbumSnapHelper.attachToRecyclerView(bind.recentlyPlayedAlbumsRecyclerView); + } + + private void initRecentAddedAlbumView() { + bind.recentlyAddedAlbumsRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); + bind.recentlyAddedAlbumsRecyclerView.setHasFixedSize(true); + + recentlyAddedAlbumAdapter = new AlbumAdapter(this); + bind.recentlyAddedAlbumsRecyclerView.setAdapter(recentlyAddedAlbumAdapter); + homeViewModel.getMostRecentlyAddedAlbums(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { + if (albums == null) { + if (bind != null) + bind.homeRecentlyAddedAlbumsPlaceholder.placeholder.setVisibility(View.VISIBLE); + if (bind != null) bind.homeRecentlyAddedAlbumsSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.homeRecentlyAddedAlbumsPlaceholder.placeholder.setVisibility(View.GONE); + if (bind != null) + bind.homeRecentlyAddedAlbumsSector.setVisibility(!albums.isEmpty() ? View.VISIBLE : View.GONE); + + recentlyAddedAlbumAdapter.setItems(albums); + } + }); + + CustomLinearSnapHelper recentAddedAlbumSnapHelper = new CustomLinearSnapHelper(); + recentAddedAlbumSnapHelper.attachToRecyclerView(bind.recentlyAddedAlbumsRecyclerView); + } + + private void initNewestPodcastsView() { + bind.newestPodcastsViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); + + podcastEpisodeAdapter = new PodcastEpisodeAdapter(this); + bind.newestPodcastsViewPager.setAdapter(podcastEpisodeAdapter); + bind.newestPodcastsViewPager.setOffscreenPageLimit(1); + homeViewModel.getNewestPodcastEpisodes(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), podcastEpisodes -> { + if (podcastEpisodes == null) { + if (bind != null) bind.homeNewestPodcastsSector.setVisibility(View.GONE); + } else { + if (bind != null) + bind.homeNewestPodcastsSector.setVisibility(!podcastEpisodes.isEmpty() ? View.VISIBLE : View.GONE); + + podcastEpisodeAdapter.setItems(podcastEpisodes); + } + }); + + setSlideViewOffset(bind.newestPodcastsViewPager, 20, 16); + } + + private void initGridView() { + bind.gridTracksRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 3)); + bind.gridTracksRecyclerView.addItemDecoration(new GridItemDecoration(3, 8, false)); + bind.gridTracksRecyclerView.setHasFixedSize(true); + + gridTrackAdapter = new GridTrackAdapter(this); + bind.gridTracksRecyclerView.setAdapter(gridTrackAdapter); + + homeViewModel.getGridSongSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), chronologies -> { + if (chronologies == null || chronologies.size() == 0) { + if (bind != null) bind.homeGridTracksSector.setVisibility(View.GONE); + if (bind != null) bind.afterGridDivider.setVisibility(View.GONE); + } else { + if (bind != null) bind.homeGridTracksSector.setVisibility(View.VISIBLE); + if (bind != null) bind.afterGridDivider.setVisibility(View.VISIBLE); + gridTrackAdapter.setItems(chronologies); + } + }); + } + + private void setSlideViewOffset(ViewPager2 viewPager, float pageOffset, float pageMargin) { + viewPager.setPageTransformer((page, position) -> { + float myOffset = position * -(2 * pageOffset + pageMargin); + if (viewPager.getOrientation() == ViewPager2.ORIENTATION_HORIZONTAL) { + if (ViewCompat.getLayoutDirection(viewPager) == ViewCompat.LAYOUT_DIRECTION_RTL) { + page.setTranslationX(-myOffset); + } else { + page.setTranslationX(myOffset); + } + } else { + page.setTranslationY(myOffset); + } + }); + } + + public void reorder() { + if (bind != null) { + // bind.homeLinearLayoutContainer.removeAllViews(); + // bind.homeLinearLayoutContainer.addView(bind.homeDiscoverSector); + + // bind.homeLinearLayoutContainer.addView(bind.homeSimilarTracksSector); + // bind.homeLinearLayoutContainer.addView(bind.homeRadioArtistSector); + // bind.homeLinearLayoutContainer.addView(bind.homeGridTracksSector); + // bind.homeLinearLayoutContainer.addView(bind.starredTracksSector); + // bind.homeLinearLayoutContainer.addView(bind.starredAlbumsSector); + // bind.homeLinearLayoutContainer.addView(bind.starredArtistsSector); + + // bind.homeLinearLayoutContainer.addView(bind.homeRecentlyAddedAlbumsSector); + // bind.homeLinearLayoutContainer.addView(bind.homeFlashbackSector); + // bind.homeLinearLayoutContainer.addView(bind.homeMostPlayedAlbumsSector); + // bind.homeLinearLayoutContainer.addView(bind.homeRecentlyPlayedAlbumsSector); + // bind.homeLinearLayoutContainer.addView(bind.homeNewestPodcastsSector); + } + } + + private void initializeMediaBrowser() { + mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync(); + } + + private void releaseMediaBrowser() { + MediaBrowser.releaseFuture(mediaBrowserListenableFuture); + } + + @Override + public void onMediaClick(Bundle bundle) { + if (bundle.containsKey(Constants.MEDIA_MIX)) { + MediaManager.startQueue(mediaBrowserListenableFuture, bundle.getParcelable(Constants.TRACK_OBJECT)); + activity.setBottomSheetInPeek(true); + + if (mediaBrowserListenableFuture != null) { + homeViewModel.getMediaInstantMix(getViewLifecycleOwner(), bundle.getParcelable(Constants.TRACK_OBJECT)).observe(getViewLifecycleOwner(), songs -> { + if (songs != null && songs.size() > 0) { + MediaManager.enqueue(mediaBrowserListenableFuture, songs, true); + } + }); + } + } else if (bundle.containsKey(Constants.MEDIA_CHRONOLOGY)) { + List media = bundle.getParcelableArrayList(Constants.TRACKS_OBJECT); + MediaManager.startQueue(mediaBrowserListenableFuture, media, bundle.getInt(Constants.ITEM_POSITION)); + activity.setBottomSheetInPeek(true); + } else { + MediaManager.startQueue(mediaBrowserListenableFuture, bundle.getParcelableArrayList(Constants.TRACKS_OBJECT), bundle.getInt(Constants.ITEM_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(Constants.MEDIA_MIX) && bundle.getBoolean(Constants.MEDIA_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(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> { + if (songs.size() > 0) { + MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0); + activity.setBottomSheetInPeek(true); + } + }); + } + } else if (bundle.containsKey(Constants.MEDIA_BEST_OF) && bundle.getBoolean(Constants.MEDIA_BEST_OF)) { + if (mediaBrowserListenableFuture != null) { + homeViewModel.getArtistBestOf(getViewLifecycleOwner(), bundle.getParcelable(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> { + if (songs.size() > 0) { + MediaManager.startQueue(mediaBrowserListenableFuture, 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, bundle.getParcelable(Constants.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/HomeTabPodcastFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeTabPodcastFragment.java new file mode 100644 index 00000000..aebc74d7 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeTabPodcastFragment.java @@ -0,0 +1,71 @@ +package com.cappielloantonio.play.ui.fragment; + +import android.content.ComponentName; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +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 com.cappielloantonio.play.databinding.FragmentHomeTabPodcastBinding; +import com.cappielloantonio.play.service.MediaService; +import com.cappielloantonio.play.ui.activity.MainActivity; +import com.cappielloantonio.play.viewmodel.HomeViewModel; +import com.google.common.util.concurrent.ListenableFuture; + +@UnstableApi +public class HomeTabPodcastFragment extends Fragment { + private static final String TAG = "HomeTabPodcastFragment"; + + private FragmentHomeTabPodcastBinding bind; + private MainActivity activity; + private HomeViewModel homeViewModel; + + private ListenableFuture mediaBrowserListenableFuture; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + activity = (MainActivity) getActivity(); + + bind = FragmentHomeTabPodcastBinding.inflate(inflater, container, false); + View view = bind.getRoot(); + homeViewModel = new ViewModelProvider(requireActivity()).get(HomeViewModel.class); + + return view; + } + + @Override + public void onStart() { + super.onStart(); + + initializeMediaBrowser(); + } + + @Override + public void onStop() { + releaseMediaBrowser(); + super.onStop(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind = null; + } + + private void initializeMediaBrowser() { + mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync(); + } + + private void releaseMediaBrowser() { + MediaBrowser.releaseFuture(mediaBrowserListenableFuture); + } +} diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeTabRadioFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeTabRadioFragment.java new file mode 100644 index 00000000..4af3ade1 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/HomeTabRadioFragment.java @@ -0,0 +1,72 @@ +package com.cappielloantonio.play.ui.fragment; + +import android.content.ComponentName; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +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 com.cappielloantonio.play.databinding.FragmentHomeTabPodcastBinding; +import com.cappielloantonio.play.databinding.FragmentHomeTabRadioBinding; +import com.cappielloantonio.play.service.MediaService; +import com.cappielloantonio.play.ui.activity.MainActivity; +import com.cappielloantonio.play.viewmodel.HomeViewModel; +import com.google.common.util.concurrent.ListenableFuture; + +@UnstableApi +public class HomeTabRadioFragment extends Fragment { + private static final String TAG = "HomeTabRadioFragment"; + + private FragmentHomeTabRadioBinding bind; + private MainActivity activity; + private HomeViewModel homeViewModel; + + private ListenableFuture mediaBrowserListenableFuture; + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + activity = (MainActivity) getActivity(); + + bind = FragmentHomeTabRadioBinding.inflate(inflater, container, false); + View view = bind.getRoot(); + homeViewModel = new ViewModelProvider(requireActivity()).get(HomeViewModel.class); + + return view; + } + + @Override + public void onStart() { + super.onStart(); + + initializeMediaBrowser(); + } + + @Override + public void onStop() { + releaseMediaBrowser(); + super.onStop(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + bind = null; + } + + private void initializeMediaBrowser() { + mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync(); + } + + private void releaseMediaBrowser() { + MediaBrowser.releaseFuture(mediaBrowserListenableFuture); + } +} diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/pager/HomePager.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/pager/HomePager.java new file mode 100644 index 00000000..f3fd6ad2 --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/pager/HomePager.java @@ -0,0 +1,54 @@ +package com.cappielloantonio.play.ui.fragment.pager; + +import android.graphics.drawable.Drawable; + +import androidx.annotation.NonNull; +import androidx.annotation.OptIn; +import androidx.fragment.app.Fragment; +import androidx.media3.common.util.UnstableApi; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +import com.cappielloantonio.play.ui.fragment.HomeTabMusicFragment; +import com.cappielloantonio.play.ui.fragment.PlayerCoverFragment; +import com.cappielloantonio.play.ui.fragment.PlayerLyricsFragment; + +import java.util.ArrayList; +import java.util.List; + +@OptIn(markerClass = UnstableApi.class) +public class HomePager extends FragmentStateAdapter { + private static final String TAG = "HomePager"; + + private final List fragments = new ArrayList<>(); + private final List titles = new ArrayList<>(); + private final List icons = new ArrayList<>(); + + public HomePager(@NonNull Fragment fragment) { + super(fragment); + } + + @NonNull + @Override + public Fragment createFragment(int position) { + return fragments.get(position); + } + + @Override + public int getItemCount() { + return fragments.size(); + } + + public void addFragment(Fragment fragment, String title, int drawable) { + fragments.add(fragment); + titles.add(title); + icons.add(drawable); + } + + public String getPageTitle(int position) { + return titles.get(position); + } + + public Integer getPageIcon(int position) { + return icons.get(position); + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index f8a5fc7f..933facf1 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -1,8 +1,10 @@ + android:layout_height="match_parent" + tools:context=".ui.fragment.HomeFragment"> - - - - + app:tabGravity="fill" + app:tabMode="fixed" /> + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_home_tab_music.xml b/app/src/main/res/layout/fragment_home_tab_music.xml new file mode 100644 index 00000000..2bed4353 --- /dev/null +++ b/app/src/main/res/layout/fragment_home_tab_music.xml @@ -0,0 +1,770 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_home_tab_podcast.xml b/app/src/main/res/layout/fragment_home_tab_podcast.xml new file mode 100644 index 00000000..48f28a10 --- /dev/null +++ b/app/src/main/res/layout/fragment_home_tab_podcast.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/app/src/main/res/layout/fragment_home_tab_radio.xml b/app/src/main/res/layout/fragment_home_tab_radio.xml new file mode 100644 index 00000000..2e028fbf --- /dev/null +++ b/app/src/main/res/layout/fragment_home_tab_radio.xml @@ -0,0 +1,18 @@ + + + + + + +