From 4848d4f3d0637d6545884a3cdb551d8c73bcf30a Mon Sep 17 00:00:00 2001 From: Antonio Cappiello Date: Wed, 25 Nov 2020 08:21:30 +0100 Subject: [PATCH] Fix filtering --- .../play/database/dao/SongDao.java | 4 + .../com/cappielloantonio/play/model/Song.java | 3 + .../play/repository/SongRepository.java | 6 ++ .../play/ui/activities/MainActivity.java | 10 +- .../play/ui/fragment/FilterFragment.java | 31 +++++-- .../ui/fragment/GenreCatalogueFragment.java | 7 +- .../play/ui/fragment/LibraryFragment.java | 41 ++------ .../play/ui/fragment/LoginFragment.java | 5 - .../play/ui/fragment/SearchFragment.java | 4 - .../ui/fragment/SongListPageFragment.java | 17 ++-- .../play/ui/fragment/SyncFragment.java | 82 +++++++++------- .../cappielloantonio/play/util/SyncUtil.java | 13 +++ .../play/viewmodel/FilterViewModel.java | 25 ++++- .../play/viewmodel/SongListPageViewModel.java | 11 +++ .../play/viewmodel/SyncViewModel.java | 93 +++++++++++++++++++ app/src/main/res/layout/fragment_filter.xml | 41 ++++++-- .../res/layout/fragment_genre_catalogue.xml | 42 +++++++-- app/src/main/res/layout/fragment_library.xml | 17 +++- app/src/main/res/layout/fragment_search.xml | 3 +- app/src/main/res/navigation/nav_graph.xml | 19 +++- .../main/res/navigation/nav_graph_home.xml | 77 +++++++++++++++ .../main/res/navigation/nav_graph_library.xml | 82 ++++++++++++++++ .../main/res/navigation/nav_graph_search.xml | 52 +++++++++++ .../res/navigation/nav_graph_settings.xml | 12 +++ app/src/main/res/values-night/colors.xml | 2 +- 25 files changed, 575 insertions(+), 124 deletions(-) create mode 100644 app/src/main/java/com/cappielloantonio/play/viewmodel/SyncViewModel.java create mode 100644 app/src/main/res/navigation/nav_graph_home.xml create mode 100644 app/src/main/res/navigation/nav_graph_library.xml create mode 100644 app/src/main/res/navigation/nav_graph_search.xml create mode 100644 app/src/main/res/navigation/nav_graph_settings.xml diff --git a/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java b/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java index f5e8fa01..5f91eb20 100644 --- a/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java +++ b/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java @@ -10,6 +10,7 @@ import androidx.room.Update; import com.cappielloantonio.play.model.Song; +import java.util.ArrayList; import java.util.List; @Dao @@ -44,6 +45,9 @@ public interface SongDao { @Query("SELECT * FROM song INNER Join song_genre_cross ON song.id = song_genre_cross.song_id AND song_genre_cross.genre_id = :genreID") LiveData> getSongByGenre(String genreID); + @Query("SELECT * FROM song INNER Join song_genre_cross ON song.id = song_genre_cross.song_id AND song_genre_cross.genre_id IN (:filters) GROUP BY song.id") + LiveData> getFilteredSong(ArrayList filters); + @Query("SELECT EXISTS(SELECT * FROM song WHERE id = :id)") boolean exist(String id); diff --git a/app/src/main/java/com/cappielloantonio/play/model/Song.java b/app/src/main/java/com/cappielloantonio/play/model/Song.java index 9e713806..cbd04913 100644 --- a/app/src/main/java/com/cappielloantonio/play/model/Song.java +++ b/app/src/main/java/com/cappielloantonio/play/model/Song.java @@ -31,6 +31,9 @@ public class Song implements Parcelable { @Ignore public static final String BY_GENRE = "BY_GENRE"; + @Ignore + public static final String BY_GENRES = "BY_GENRES"; + @Ignore public static final String BY_ARTIST = "BY_ARTIST"; 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 0a5c9e0d..8a3e25e4 100644 --- a/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java +++ b/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java @@ -21,6 +21,7 @@ public class SongRepository { private LiveData> listLiveSampleArtistTopSongs; private LiveData> listLiveAlbumSongs; private LiveData> listLiveSongByGenre; + private LiveData> listLiveFilteredSongs; public SongRepository(Application application) { @@ -68,6 +69,11 @@ public class SongRepository { return listLiveAlbumSongs; } + public LiveData> getFilteredListLiveSong(ArrayList filters) { + listLiveFilteredSongs = songDao.getFilteredSong(filters); + return listLiveFilteredSongs; + } + public boolean exist(Song song) { boolean exist = false; diff --git a/app/src/main/java/com/cappielloantonio/play/ui/activities/MainActivity.java b/app/src/main/java/com/cappielloantonio/play/ui/activities/MainActivity.java index 39042ab1..fa02315e 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/activities/MainActivity.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/activities/MainActivity.java @@ -13,6 +13,7 @@ import com.cappielloantonio.play.R; import com.cappielloantonio.play.databinding.ActivityMainBinding; import com.cappielloantonio.play.ui.activities.base.BaseActivity; import com.cappielloantonio.play.util.PreferenceUtil; +import com.cappielloantonio.play.util.SyncUtil; import com.google.android.material.bottomnavigation.BottomNavigationView; import org.jellyfin.apiclient.interaction.EmptyResponse; @@ -86,12 +87,15 @@ public class MainActivity extends BaseActivity { } public void goToSync() { + bottomNavigationView.setVisibility(View.GONE); + Bundle bundle = SyncUtil.getSyncBundle(true, true, true, true, true, false); + if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.landingFragment) { - navController.navigate(R.id.action_landingFragment_to_syncFragment); + navController.navigate(R.id.action_landingFragment_to_syncFragment, bundle); } else if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.loginFragment) { - navController.navigate(R.id.action_loginFragment_to_syncFragment); + navController.navigate(R.id.action_loginFragment_to_syncFragment, bundle); } else if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.homeFragment) { - navController.navigate(R.id.action_homeFragment_to_syncFragment); + navController.navigate(R.id.action_homeFragment_to_syncFragment, bundle); } } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/FilterFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/FilterFragment.java index e92288ca..e18c02f0 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/FilterFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/FilterFragment.java @@ -4,6 +4,7 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.CompoundButton; import android.widget.Toast; import androidx.annotation.NonNull; @@ -14,12 +15,15 @@ import androidx.lifecycle.ViewModelProvider; import com.cappielloantonio.play.R; import com.cappielloantonio.play.databinding.FragmentFilterBinding; import com.cappielloantonio.play.model.Genre; +import com.cappielloantonio.play.model.Song; +import com.cappielloantonio.play.ui.activities.MainActivity; import com.cappielloantonio.play.viewmodel.FilterViewModel; import com.google.android.material.chip.Chip; public class FilterFragment extends Fragment { private static final String TAG = "FilterFragment"; + private MainActivity activity; private FragmentFilterBinding bind; private FilterViewModel filterViewModel; @@ -27,10 +31,12 @@ public class FilterFragment extends Fragment { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + activity = (MainActivity) getActivity(); bind = FragmentFilterBinding.inflate(inflater, container, false); View view = bind.getRoot(); filterViewModel = new ViewModelProvider(requireActivity()).get(FilterViewModel.class); + init(); setFilterChips(); return view; } @@ -41,17 +47,30 @@ public class FilterFragment extends Fragment { bind = null; } + private void init() { + Bundle bundle = new Bundle(); + bundle.putString(Song.BY_GENRES, Song.BY_GENRES); + bundle.putStringArrayList("filters_list", filterViewModel.getFilters()); + bundle.putStringArrayList("filter_name_list", filterViewModel.getFilterNames()); + bind.finishFilteringTextViewClickable.setOnClickListener(v -> { + if(filterViewModel.getFilters().size() > 1) activity.navController.navigate(R.id.action_filterFragment_to_songListPageFragment, bundle); + else Toast.makeText(requireContext(), "Select two or more filters", Toast.LENGTH_SHORT).show(); + }); + } + private void setFilterChips() { filterViewModel.getGenreList().observe(requireActivity(), genres -> { bind.loadingProgressBar.setVisibility(View.GONE); bind.filterContainer.setVisibility(View.VISIBLE); for (Genre genre : genres) { - Chip mChip = (Chip) requireActivity().getLayoutInflater().inflate(R.layout.chip_search_filter_genre, null, false); - mChip.setText(genre.getName()); - - mChip.setOnCheckedChangeListener((buttonView, isChecked) -> Toast.makeText(requireContext(), buttonView.getText() + ": " + isChecked, Toast.LENGTH_SHORT).show()); - - bind.filtersChipsGroup.addView(mChip); + Chip chip = (Chip) requireActivity().getLayoutInflater().inflate(R.layout.chip_search_filter_genre, null, false); + chip.setText(genre.getName()); + chip.setChecked(filterViewModel.getFilters().contains(genre.getId())); + chip.setOnCheckedChangeListener((buttonView, isChecked) -> { + if(isChecked) filterViewModel.addFilter(genre.getId(), buttonView.getText().toString()); + else filterViewModel.removeFilter(genre.getId(), buttonView.getText().toString()); + }); + bind.filtersChipsGroup.addView(chip); } }); } 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 999a997e..71224a9c 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 @@ -53,6 +53,7 @@ public class GenreCatalogueFragment extends Fragment { View view = bind.getRoot(); genreCatalogueViewModel = new ViewModelProvider(requireActivity()).get(GenreCatalogueViewModel.class); + init(); initArtistCatalogueView(); return view; @@ -64,9 +65,13 @@ public class GenreCatalogueFragment extends Fragment { bind = null; } + private void init() { + bind.filterGenresTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_genreCatalogueFragment_to_filterFragment)); + } + private void initArtistCatalogueView() { bind.genreCatalogueRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), 2)); - bind.genreCatalogueRecyclerView.addItemDecoration(new ItemlDecoration(2, 20, false)); + bind.genreCatalogueRecyclerView.addItemDecoration(new ItemlDecoration(2, 16, false)); bind.genreCatalogueRecyclerView.setHasFixedSize(true); genreCatalogueAdapter = new GenreCatalogueAdapter(requireContext(), new ArrayList<>()); 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 1d5a9303..937ae0e1 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 @@ -83,6 +83,7 @@ public class LibraryFragment extends Fragment { bind.albumCatalogueTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_libraryFragment_to_albumCatalogueFragment)); bind.artistCatalogueTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_libraryFragment_to_artistCatalogueFragment)); bind.genreCatalogueTextViewClickable.setOnClickListener(v -> activity.navController.navigate(R.id.action_libraryFragment_to_genreCatalogueFragment)); + bind.syncGenreButton.setOnClickListener(v -> syncSongsPerGenre()); } private void initAlbumView() { @@ -118,14 +119,11 @@ public class LibraryFragment extends Fragment { bind.genreRecyclerView.setHasFixedSize(true); genreAdapter = new GenreAdapter(requireContext(), new ArrayList<>()); - genreAdapter.setClickListener(new GenreAdapter.ItemClickListener() { - @Override - public void onItemClick(View view, int position) { - Bundle bundle = new Bundle(); - bundle.putString(Song.BY_GENRE, Song.BY_GENRE); - bundle.putParcelable("genre_object", genreAdapter.getItem(position)); - activity.navController.navigate(R.id.action_libraryFragment_to_songListPageFragment, bundle); - } + genreAdapter.setClickListener((view, position) -> { + Bundle bundle = new Bundle(); + bundle.putString(Song.BY_GENRE, Song.BY_GENRE); + bundle.putParcelable("genre_object", genreAdapter.getItem(position)); + activity.navController.navigate(R.id.action_libraryFragment_to_songListPageFragment, bundle); }); bind.genreRecyclerView.setAdapter(genreAdapter); libraryViewModel.getGenreSample().observe(requireActivity(), genres -> genreAdapter.setItems(genres)); @@ -147,32 +145,13 @@ public class LibraryFragment extends Fragment { builder.setMessage("Sync song's genres otherwise nothing will be shown in each genre category") .setTitle("Song's genres not synchronized") .setNegativeButton(R.string.ignore, null) - .setPositiveButton("Sync", (dialog, id) -> syncSongsPerGenre(libraryViewModel.getGenreList())) + .setPositiveButton("Sync", (dialog, id) -> syncSongsPerGenre()) .show(); } } - private void syncSongsPerGenre(List genres) { - Snackbar.make(requireView(), "This may take a while...", BaseTransientBottomBar.LENGTH_LONG) - .setBackgroundTint(ContextCompat.getColor(requireContext(), R.color.cardColor)) - .setTextColor(ContextCompat.getColor(requireContext(), R.color.titleTextColor)) - .show(); - - for (Genre genre : genres) { - SyncUtil.getSongsPerGenre(requireContext(), new MediaCallback() { - @Override - public void onError(Exception exception) { - Log.e(TAG, "onError: " + exception.getMessage()); - } - - @Override - public void onLoadMedia(List media) { - GenreRepository repository = new GenreRepository(App.getInstance()); - repository.insertPerGenre((ArrayList) media); - } - }, genre.id); - } - - PreferenceUtil.getInstance(requireContext()).setSongGenreSync(true); + private void syncSongsPerGenre() { + Bundle bundle = SyncUtil.getSyncBundle(false, false, true, false, false, true); + activity.navController.navigate(R.id.action_libraryFragment_to_syncFragment, bundle); } } 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 5fea757e..9f4491c6 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 @@ -26,15 +26,10 @@ public class LoginFragment extends Fragment { private FragmentLoginBinding bind; private MainActivity activity; - // private TextView usernameTextView; -// private TextView passwordTextView; -// private TextView serverTextView; private String username; private String password; private String server; -// private Button loginButton; - @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 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 893809f8..57432bf1 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 @@ -128,10 +128,6 @@ public class SearchFragment extends Fragment { bind.persistentSearchView.setOnLeftBtnClickListener(view -> { }); - bind.persistentSearchView.setOnRightBtnClickListener(view -> { - activity.navController.navigate(R.id.action_searchFragment_to_filterFragment); - }); - bind.persistentSearchView.setOnSearchConfirmedListener((searchView, query) -> { search(query); }); 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 75e8345e..f228ec05 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 @@ -9,7 +9,6 @@ import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.LinearLayoutManager; -import com.cappielloantonio.play.adapter.AlbumArtistPageAdapter; import com.cappielloantonio.play.adapter.SongResultSearchAdapter; import com.cappielloantonio.play.databinding.FragmentSongListPageBinding; import com.cappielloantonio.play.model.Song; @@ -49,25 +48,31 @@ public class SongListPageFragment extends Fragment { private void init() { if(getArguments().getString(Song.RECENTLY_PLAYED) != null) { songListPageViewModel.title = Song.RECENTLY_PLAYED; - bind.pageTitleLabel.setText(Song.RECENTLY_PLAYED); + bind.pageTitleLabel.setText("Recently played songs"); } else if(getArguments().getString(Song.MOST_PLAYED) != null) { songListPageViewModel.title = Song.MOST_PLAYED; - bind.pageTitleLabel.setText(Song.MOST_PLAYED); + bind.pageTitleLabel.setText("Most played songs"); } else if(getArguments().getString(Song.RECENTLY_ADDED) != null) { songListPageViewModel.title = Song.RECENTLY_ADDED; - bind.pageTitleLabel.setText(Song.RECENTLY_ADDED); + bind.pageTitleLabel.setText("Recently added song"); } else if(getArguments().getString(Song.BY_GENRE) != null) { songListPageViewModel.title = Song.BY_GENRE; songListPageViewModel.genre = getArguments().getParcelable("genre_object"); - bind.pageTitleLabel.setText(Song.BY_GENRE); + bind.pageTitleLabel.setText(songListPageViewModel.genre.getName() + ": all songs"); } else if(getArguments().getString(Song.BY_ARTIST) != null) { songListPageViewModel.title = Song.BY_ARTIST; songListPageViewModel.artist = getArguments().getParcelable("artist_object"); - bind.pageTitleLabel.setText(Song.BY_ARTIST); + bind.pageTitleLabel.setText(songListPageViewModel.artist.getName() + "'s top songs"); + } + else if(getArguments().getString(Song.BY_GENRES) != null) { + songListPageViewModel.title = Song.BY_GENRES; + songListPageViewModel.filters = getArguments().getStringArrayList("filters_list"); + songListPageViewModel.filterNames = getArguments().getStringArrayList("filter_name_list"); + bind.pageTitleLabel.setText(songListPageViewModel.getFiltersTitle()); } } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SyncFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SyncFragment.java index 6d76268f..dfef32af 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/SyncFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/SyncFragment.java @@ -13,6 +13,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; import com.cappielloantonio.play.App; import com.cappielloantonio.play.R; @@ -32,6 +33,7 @@ import com.cappielloantonio.play.repository.SongRepository; import com.cappielloantonio.play.ui.activities.MainActivity; import com.cappielloantonio.play.util.PreferenceUtil; import com.cappielloantonio.play.util.SyncUtil; +import com.cappielloantonio.play.viewmodel.SyncViewModel; import com.google.android.material.snackbar.BaseTransientBottomBar; import com.google.android.material.snackbar.Snackbar; @@ -45,12 +47,7 @@ public class SyncFragment extends Fragment { private MainActivity activity; private FragmentSyncBinding bind; - - private ArrayList progressing; - private List genres; - - private int stepMax = 5; - private int increment = 25; + private SyncViewModel syncViewModel; @Nullable @Override @@ -59,6 +56,7 @@ public class SyncFragment extends Fragment { bind = FragmentSyncBinding.inflate(inflater, container, false); View view = bind.getRoot(); + syncViewModel = new ViewModelProvider(requireActivity()).get(SyncViewModel.class); init(); syncLibraries(); @@ -73,13 +71,11 @@ public class SyncFragment extends Fragment { } private void init() { + syncViewModel.setArguemnts(getArguments()); bind.loadingProgressBar.setVisibility(View.VISIBLE); } private void syncLibraries() { - Log.d(TAG, "syncLibraries"); - progressing = new ArrayList<>(); - SyncUtil.getLibraries(requireContext(), new MediaCallback() { @Override public void onError(Exception exception) { @@ -101,11 +97,11 @@ public class SyncFragment extends Fragment { } private void startSyncing() { - syncAlbums(); - syncArtists(); - syncGenres(); - syncPlaylist(); - syncSongs(); + if(syncViewModel.isSyncAlbum()) syncAlbums(); + if(syncViewModel.isSyncArtist()) syncArtists(); + if(syncViewModel.isSyncGenres()) syncGenres(); + if(syncViewModel.isSyncPlaylist()) syncPlaylist(); + if(syncViewModel.isSyncSong()) syncSongs(); } private void syncAlbums() { @@ -114,14 +110,14 @@ public class SyncFragment extends Fragment { @Override public void onError(Exception exception) { Log.e(TAG, "onError: " + exception.getMessage()); - setProgress(false, "Album"); + animateProgressBar(false); } @Override public void onLoadMedia(List media) { AlbumRepository repository = new AlbumRepository(activity.getApplication()); repository.insertAll((ArrayList) media); - setProgress(true, "Album"); + animateProgressBar(true); } }); } @@ -132,14 +128,14 @@ public class SyncFragment extends Fragment { @Override public void onError(Exception exception) { Log.e(TAG, "onError: " + exception.getMessage()); - setProgress(false, "Artist"); + animateProgressBar(false); } @Override public void onLoadMedia(List media) { ArtistRepository repository = new ArtistRepository(activity.getApplication()); repository.insertAll((ArrayList) media); - setProgress(true, "Artist"); + animateProgressBar(true); } }); } @@ -150,14 +146,17 @@ public class SyncFragment extends Fragment { @Override public void onError(Exception exception) { Log.e(TAG, "onError: " + exception.getMessage()); - setProgress(false, "Genres"); + animateProgressBar(false); } @Override public void onLoadMedia(List media) { GenreRepository repository = new GenreRepository(activity.getApplication()); repository.insertAll((ArrayList) media); - setProgress(true, "Genres"); + animateProgressBar(true); + + if(syncViewModel.isCrossSyncSongGenre()) syncSongsPerGenre((ArrayList) media); + } }); } @@ -168,14 +167,14 @@ public class SyncFragment extends Fragment { @Override public void onError(Exception exception) { Log.e(TAG, "onError: " + exception.getMessage()); - setProgress(false, "PlayList"); + animateProgressBar(false); } @Override public void onLoadMedia(List media) { PlaylistRepository repository = new PlaylistRepository(activity.getApplication()); repository.insertAll((ArrayList) media); - setProgress(true, "PlayList"); + animateProgressBar(true); } }); } @@ -186,41 +185,52 @@ public class SyncFragment extends Fragment { @Override public void onError(Exception exception) { Log.e(TAG, "onError: " + exception.getMessage()); - setProgress(false, "Songs"); + animateProgressBar(false); } @Override public void onLoadMedia(List media) { SongRepository repository = new SongRepository(activity.getApplication()); repository.insertAll((ArrayList) media); - setProgress(true, "Songs"); + animateProgressBar(true); } }); } + private void syncSongsPerGenre(List genres) { + for (Genre genre : genres) { + SyncUtil.getSongsPerGenre(requireContext(), new MediaCallback() { + @Override + public void onError(Exception exception) { + Log.e(TAG, "onError: " + exception.getMessage()); + } - private void setProgress(boolean step, String who) { - if (step) { - Log.d(TAG, "setProgress " + who + ": adding " + increment); - progressing.add(increment); - bind.loadingProgressBar.setProgress(bind.loadingProgressBar.getProgress() + increment, true); - } else { - Log.d(TAG, "setProgress" + who + ": adding " + 0); - progressing.add(0); + @Override + public void onLoadMedia(List media) { + GenreRepository repository = new GenreRepository(App.getInstance()); + repository.insertPerGenre((ArrayList) media); + } + }, genre.id); } + animateProgressBar(true); + PreferenceUtil.getInstance(requireContext()).setSongGenreSync(true); + } + + + private void animateProgressBar(boolean step) { + syncViewModel.setProgress(step); + bind.loadingProgressBar.setProgress(syncViewModel.getProgressBarInfo(), true); countProgress(); } private void countProgress() { - if (progressing.size() == stepMax) { - if (bind.loadingProgressBar.getProgress() == 100) + if (syncViewModel.getProgress() == syncViewModel.getStep()) { + if (syncViewModel.getProgressBarInfo() >= 100) terminate(); else Toast.makeText(requireContext(), "Sync error", Toast.LENGTH_SHORT).show(); } - - Log.d(TAG, "countProgress: SIZE: " + progressing.size() + " - SUM: " + bind.loadingProgressBar.getProgress()); } private void terminate() { diff --git a/app/src/main/java/com/cappielloantonio/play/util/SyncUtil.java b/app/src/main/java/com/cappielloantonio/play/util/SyncUtil.java index 67d520c4..b2fc535f 100644 --- a/app/src/main/java/com/cappielloantonio/play/util/SyncUtil.java +++ b/app/src/main/java/com/cappielloantonio/play/util/SyncUtil.java @@ -1,6 +1,7 @@ package com.cappielloantonio.play.util; import android.content.Context; +import android.os.Bundle; import com.cappielloantonio.play.App; import com.cappielloantonio.play.interfaces.MediaCallback; @@ -202,4 +203,16 @@ public class SyncUtil { } }); } + + public static Bundle getSyncBundle(Boolean syncAlbum, Boolean syncArtist, Boolean syncGenres, Boolean syncPlaylist, Boolean syncSong, Boolean crossSyncSongGenre) { + Bundle bundle = new Bundle(); + bundle.putBoolean("sync_album", syncAlbum); + bundle.putBoolean("sync_artist", syncArtist); + bundle.putBoolean("sync_genres", syncGenres); + bundle.putBoolean("sync_playlist", syncPlaylist); + bundle.putBoolean("sync_song", syncSong); + bundle.putBoolean("cross_sync_song_genre", crossSyncSongGenre); + + return bundle; + } } diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/FilterViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/FilterViewModel.java index 8a9da55c..8738cd68 100644 --- a/app/src/main/java/com/cappielloantonio/play/viewmodel/FilterViewModel.java +++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/FilterViewModel.java @@ -7,18 +7,17 @@ import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import com.cappielloantonio.play.model.Genre; -import com.cappielloantonio.play.model.RecentSearch; -import com.cappielloantonio.play.model.Song; import com.cappielloantonio.play.repository.GenreRepository; -import com.cappielloantonio.play.repository.RecentSearchRepository; -import com.cappielloantonio.play.repository.SongRepository; +import java.util.ArrayList; import java.util.List; public class FilterViewModel extends AndroidViewModel { private GenreRepository genreRepository; private LiveData> allGenres; + private ArrayList selectedFiltersID = new ArrayList<>(); + private ArrayList selectedFilters = new ArrayList<>(); public FilterViewModel(@NonNull Application application) { super(application); @@ -30,4 +29,22 @@ public class FilterViewModel extends AndroidViewModel { allGenres = genreRepository.getListLiveGenres(); return allGenres; } + + public void addFilter(String filterID, String filterName) { + selectedFiltersID.add(filterID); + selectedFilters.add(filterName); + } + + public void removeFilter(String filterID, String filterName) { + selectedFiltersID.remove(filterID); + selectedFilters.remove(filterName); + } + + public ArrayList getFilters() { + return selectedFiltersID; + } + + public ArrayList getFilterNames() { + return selectedFilters; + } } diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/SongListPageViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/SongListPageViewModel.java index 907423aa..b2d97445 100644 --- a/app/src/main/java/com/cappielloantonio/play/viewmodel/SongListPageViewModel.java +++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/SongListPageViewModel.java @@ -1,6 +1,7 @@ package com.cappielloantonio.play.viewmodel; import android.app.Application; +import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; @@ -11,6 +12,7 @@ import com.cappielloantonio.play.model.Genre; import com.cappielloantonio.play.model.Song; import com.cappielloantonio.play.repository.SongRepository; +import java.util.ArrayList; import java.util.List; public class SongListPageViewModel extends AndroidViewModel { @@ -21,6 +23,8 @@ public class SongListPageViewModel extends AndroidViewModel { public String title; public Genre genre; public Artist artist; + public ArrayList filters = new ArrayList<>(); + public ArrayList filterNames = new ArrayList<>(); public SongListPageViewModel(@NonNull Application application) { super(application); @@ -45,8 +49,15 @@ public class SongListPageViewModel extends AndroidViewModel { case Song.BY_ARTIST: songList = songRepository.getArtistListLiveTopSong(artist.getId()); break; + case Song.BY_GENRES: + songList = songRepository.getFilteredListLiveSong(filters); + break; } return songList; } + + public String getFiltersTitle() { + return TextUtils.join(", ", filterNames); + } } diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/SyncViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/SyncViewModel.java new file mode 100644 index 00000000..127a209a --- /dev/null +++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/SyncViewModel.java @@ -0,0 +1,93 @@ +package com.cappielloantonio.play.viewmodel; + +import android.app.Application; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; + +import com.cappielloantonio.play.model.Song; +import com.cappielloantonio.play.repository.SongRepository; + +import java.util.List; + +public class SyncViewModel extends AndroidViewModel { + private static final String TAG = "SyncViewModel"; + + private boolean syncAlbum = false; + private boolean syncArtist = false; + private boolean syncGenres = false; + private boolean syncPlaylist = false; + private boolean syncSong = false; + private boolean crossSyncSongGenre = false; + + private int step = 0; + private int progress = 0; + + + public SyncViewModel(@NonNull Application application) { + super(application); + } + + public void setArguemnts(Bundle bundle) { + syncAlbum = bundle.getBoolean("sync_album", false); + syncArtist = bundle.getBoolean("sync_artist", false); + syncGenres = bundle.getBoolean("sync_genres", false); + syncPlaylist = bundle.getBoolean("sync_playlist", false); + syncSong = bundle.getBoolean("sync_song", false); + crossSyncSongGenre = bundle.getBoolean("cross_sync_song_genre", false); + + countStep(); + } + + private void countStep() { + if(syncAlbum) step++; + if(syncArtist) step++; + if(syncGenres) step++; + if(syncPlaylist) step++; + if(syncSong) step++; + if(crossSyncSongGenre) step++; + } + + public boolean isSyncAlbum() { + return syncAlbum; + } + + public boolean isSyncArtist() { + return syncArtist; + } + + public boolean isSyncGenres() { + return syncGenres; + } + + public boolean isSyncPlaylist() { + return syncPlaylist; + } + + public boolean isSyncSong() { + return syncSong; + } + + public boolean isCrossSyncSongGenre() { + return crossSyncSongGenre; + } + + public int getStep() { + return step; + } + + public int getProgress() { + return progress; + } + + public void setProgress(Boolean step) { + if(step) progress++; + } + + public int getProgressBarInfo() { + return progress * (100 / step); + } +} diff --git a/app/src/main/res/layout/fragment_filter.xml b/app/src/main/res/layout/fragment_filter.xml index 770220c1..cbce67a9 100644 --- a/app/src/main/res/layout/fragment_filter.xml +++ b/app/src/main/res/layout/fragment_filter.xml @@ -28,17 +28,40 @@ android:orientation="vertical" android:paddingBottom="8dp"> - + android:orientation="horizontal" + android:paddingStart="8dp" + android:paddingTop="8dp" + android:paddingEnd="8dp"> + + + + + + - + + android:orientation="horizontal" + android:paddingStart="8dp" + android:paddingTop="8dp" + android:paddingEnd="8dp"> + + + + + + + android:paddingEnd="8dp"/> + +