From 48d9022f9a96451cbe80de9e35e974f63ef0d2f7 Mon Sep 17 00:00:00 2001 From: CappielloAntonio Date: Sat, 23 Nov 2024 16:00:01 +0100 Subject: [PATCH] feat: add sorting and search functionality for album and artist list --- .../ui/adapter/AlbumHorizontalAdapter.java | 67 +++++++++- .../ui/adapter/ArtistHorizontalAdapter.java | 67 +++++++++- .../ui/fragment/AlbumListPageFragment.java | 120 +++++++++++++++++- .../ui/fragment/ArtistListPageFragment.java | 111 +++++++++++++++- .../ui/fragment/SongListPageFragment.java | 10 +- .../cappielloantonio/tempo/util/Constants.kt | 4 + .../viewmodel/AlbumListPageViewModel.java | 10 +- .../res/layout/fragment_album_list_page.xml | 37 +++++- .../res/layout/fragment_artist_list_page.xml | 37 +++++- .../menu/sort_horizontal_album_popup_menu.xml | 12 ++ .../sort_horizontal_artist_popup_menu.xml | 12 ++ app/src/main/res/values/strings.xml | 4 +- 12 files changed, 464 insertions(+), 27 deletions(-) create mode 100644 app/src/main/res/menu/sort_horizontal_album_popup_menu.xml create mode 100644 app/src/main/res/menu/sort_horizontal_artist_popup_menu.xml diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/AlbumHorizontalAdapter.java b/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/AlbumHorizontalAdapter.java index 130781f7..f19eae98 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/AlbumHorizontalAdapter.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/AlbumHorizontalAdapter.java @@ -3,6 +3,8 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.ViewGroup; +import android.widget.Filter; +import android.widget.Filterable; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; @@ -11,22 +13,60 @@ import com.cappielloantonio.tempo.glide.CustomGlideRequest; import com.cappielloantonio.tempo.interfaces.ClickCallback; import com.cappielloantonio.tempo.subsonic.models.AlbumID3; +import com.cappielloantonio.tempo.subsonic.models.Child; import com.cappielloantonio.tempo.util.Constants; import com.cappielloantonio.tempo.util.MusicUtil; +import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; -public class AlbumHorizontalAdapter extends RecyclerView.Adapter { +public class AlbumHorizontalAdapter extends RecyclerView.Adapter implements Filterable { private final ClickCallback click; private final boolean isOffline; + private List albumsFull; private List albums; + private String currentFilter; + + private final Filter filtering = new Filter() { + @Override + protected FilterResults performFiltering(CharSequence constraint) { + List filteredList = new ArrayList<>(); + + if (constraint == null || constraint.length() == 0) { + filteredList.addAll(albumsFull); + } else { + String filterPattern = constraint.toString().toLowerCase().trim(); + currentFilter = filterPattern; + + for (AlbumID3 item : albumsFull) { + if (item.getName().toLowerCase().contains(filterPattern)) { + filteredList.add(item); + } + } + } + + FilterResults results = new FilterResults(); + results.values = filteredList; + + return results; + } + + @Override + protected void publishResults(CharSequence constraint, FilterResults results) { + albums = (List) results.values; + notifyDataSetChanged(); + } + }; public AlbumHorizontalAdapter(ClickCallback click, boolean isOffline) { this.click = click; this.isOffline = isOffline; this.albums = Collections.emptyList(); + this.albumsFull = Collections.emptyList(); + this.currentFilter = ""; } @NonNull @@ -55,10 +95,16 @@ public int getItemCount() { } public void setItems(List albums) { - this.albums = albums; + this.albumsFull = albums != null ? albums : Collections.emptyList(); + filtering.filter(currentFilter); notifyDataSetChanged(); } + @Override + public Filter getFilter() { + return filtering; + } + public AlbumID3 getItem(int id) { return albums.get(id); } @@ -95,4 +141,21 @@ private boolean onLongClick() { return true; } } + + public void sort(String order) { + switch (order) { + case Constants.ALBUM_ORDER_BY_NAME: + albums.sort(Comparator.comparing(AlbumID3::getName)); + break; + case Constants.ALBUM_ORDER_BY_MOST_RECENTLY_STARRED: + albums.sort(Comparator.comparing(AlbumID3::getStarred, Comparator.nullsLast(Comparator.reverseOrder()))); + break; + case Constants.ALBUM_ORDER_BY_LEAST_RECENTLY_STARRED: + albums.sort(Comparator.comparing(AlbumID3::getStarred, Comparator.nullsLast(Comparator.naturalOrder()))); + + break; + } + + notifyDataSetChanged(); + } } diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/ArtistHorizontalAdapter.java b/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/ArtistHorizontalAdapter.java index 15049406..85b6fd69 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/ArtistHorizontalAdapter.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/adapter/ArtistHorizontalAdapter.java @@ -4,6 +4,8 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Filter; +import android.widget.Filterable; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; @@ -11,21 +13,59 @@ import com.cappielloantonio.tempo.databinding.ItemHorizontalArtistBinding; import com.cappielloantonio.tempo.glide.CustomGlideRequest; import com.cappielloantonio.tempo.interfaces.ClickCallback; +import com.cappielloantonio.tempo.subsonic.models.AlbumID3; import com.cappielloantonio.tempo.subsonic.models.ArtistID3; import com.cappielloantonio.tempo.util.Constants; import com.cappielloantonio.tempo.util.MusicUtil; +import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; -public class ArtistHorizontalAdapter extends RecyclerView.Adapter { +public class ArtistHorizontalAdapter extends RecyclerView.Adapter implements Filterable { private final ClickCallback click; + private List artistsFull; private List artists; + private String currentFilter; + + private final Filter filtering = new Filter() { + @Override + protected FilterResults performFiltering(CharSequence constraint) { + List filteredList = new ArrayList<>(); + + if (constraint == null || constraint.length() == 0) { + filteredList.addAll(artistsFull); + } else { + String filterPattern = constraint.toString().toLowerCase().trim(); + currentFilter = filterPattern; + + for (ArtistID3 item : artistsFull) { + if (item.getName().toLowerCase().contains(filterPattern)) { + filteredList.add(item); + } + } + } + + FilterResults results = new FilterResults(); + results.values = filteredList; + + return results; + } + + @Override + protected void publishResults(CharSequence constraint, FilterResults results) { + artists = (List) results.values; + notifyDataSetChanged(); + } + }; public ArtistHorizontalAdapter(ClickCallback click) { this.click = click; this.artists = Collections.emptyList(); + this.artistsFull = Collections.emptyList(); + this.currentFilter = ""; } @NonNull @@ -59,10 +99,16 @@ public int getItemCount() { } public void setItems(List artists) { - this.artists = artists; + this.artistsFull = artists != null ? artists : Collections.emptyList(); + filtering.filter(currentFilter); notifyDataSetChanged(); } + @Override + public Filter getFilter() { + return filtering; + } + public ArtistID3 getItem(int id) { return artists.get(id); } @@ -109,4 +155,21 @@ public boolean onLongClick() { return true; } } + + public void sort(String order) { + switch (order) { + case Constants.ARTIST_ORDER_BY_NAME: + artists.sort(Comparator.comparing(ArtistID3::getName)); + break; + case Constants.ARTIST_ORDER_BY_MOST_RECENTLY_STARRED: + artists.sort(Comparator.comparing(ArtistID3::getStarred, Comparator.nullsLast(Comparator.reverseOrder()))); + break; + case Constants.ARTIST_ORDER_BY_LEAST_RECENTLY_STARRED: + artists.sort(Comparator.comparing(ArtistID3::getStarred, Comparator.nullsLast(Comparator.naturalOrder()))); + + break; + } + + notifyDataSetChanged(); + } } diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumListPageFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumListPageFragment.java index d9ea1700..eb5b19c5 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumListPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/AlbumListPageFragment.java @@ -1,11 +1,21 @@ package com.cappielloantonio.tempo.ui.fragment; +import android.annotation.SuppressLint; +import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.PopupMenu; +import android.widget.SearchView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.OptIn; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; @@ -17,12 +27,14 @@ import com.cappielloantonio.tempo.R; import com.cappielloantonio.tempo.databinding.FragmentAlbumListPageBinding; import com.cappielloantonio.tempo.interfaces.ClickCallback; +import com.cappielloantonio.tempo.subsonic.models.AlbumID3; import com.cappielloantonio.tempo.ui.activity.MainActivity; import com.cappielloantonio.tempo.ui.adapter.AlbumHorizontalAdapter; import com.cappielloantonio.tempo.util.Constants; -import com.cappielloantonio.tempo.util.MusicUtil; import com.cappielloantonio.tempo.viewmodel.AlbumListPageViewModel; +import java.util.List; + @OptIn(markerClass = UnstableApi.class) public class AlbumListPageFragment extends Fragment implements ClickCallback { private FragmentAlbumListPageBinding bind; @@ -31,6 +43,12 @@ public class AlbumListPageFragment extends Fragment implements ClickCallback { private AlbumListPageViewModel albumListPageViewModel; private AlbumHorizontalAdapter albumHorizontalAdapter; + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { activity = (MainActivity) getActivity(); @@ -86,7 +104,10 @@ private void initAppBar() { activity.getSupportActionBar().setDisplayShowHomeEnabled(true); } - bind.toolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp()); + bind.toolbar.setNavigationOnClickListener(v -> { + hideKeyboard(v); + activity.navController.navigateUp(); + }); bind.appBarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> { if ((bind.albumInfoSector.getHeight() + verticalOffset) < (2 * ViewCompat.getMinimumHeight(bind.toolbar))) { @@ -97,6 +118,7 @@ private void initAppBar() { }); } + @SuppressLint("ClickableViewAccessibility") private void initAlbumListView() { bind.albumListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.albumListRecyclerView.setHasFixedSize(true); @@ -107,7 +129,99 @@ private void initAlbumListView() { ); bind.albumListRecyclerView.setAdapter(albumHorizontalAdapter); - albumListPageViewModel.getAlbumList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> albumHorizontalAdapter.setItems(albums)); + albumListPageViewModel.getAlbumList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), albums -> { + albumHorizontalAdapter.setItems(albums); + setAlbumListPageSubtitle(albums); + setAlbumListPageSorter(); + }); + + bind.albumListRecyclerView.setOnTouchListener((v, event) -> { + hideKeyboard(v); + return false; + }); + + bind.albumListSortImageView.setOnClickListener(view -> showPopupMenu(view, R.menu.sort_horizontal_album_popup_menu)); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.toolbar_menu, menu); + + MenuItem searchItem = menu.findItem(R.id.action_search); + + SearchView searchView = (SearchView) searchItem.getActionView(); + searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + searchView.clearFocus(); + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + albumHorizontalAdapter.getFilter().filter(newText); + return false; + } + }); + + searchView.setPadding(-32, 0, 0, 0); + } + + private void hideKeyboard(View view) { + InputMethodManager imm = (InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + } + + private void showPopupMenu(View view, int menuResource) { + PopupMenu popup = new PopupMenu(requireContext(), view); + popup.getMenuInflater().inflate(menuResource, popup.getMenu()); + + popup.setOnMenuItemClickListener(menuItem -> { + if (menuItem.getItemId() == R.id.menu_horizontal_album_sort_name) { + albumHorizontalAdapter.sort(Constants.ALBUM_ORDER_BY_NAME); + return true; + } else if (menuItem.getItemId() == R.id.menu_horizontal_album_sort_most_recently_starred) { + albumHorizontalAdapter.sort(Constants.ALBUM_ORDER_BY_MOST_RECENTLY_STARRED); + return true; + } else if (menuItem.getItemId() == R.id.menu_horizontal_album_sort_least_recently_starred) { + albumHorizontalAdapter.sort(Constants.ALBUM_ORDER_BY_LEAST_RECENTLY_STARRED); + return true; + } + + return false; + }); + + popup.show(); + } + + private void setAlbumListPageSubtitle(List albums) { + switch (albumListPageViewModel.title) { + case Constants.ALBUM_RECENTLY_PLAYED: + case Constants.ALBUM_MOST_PLAYED: + case Constants.ALBUM_RECENTLY_ADDED: + bind.pageSubtitleLabel.setText(albums.size() < albumListPageViewModel.maxNumber ? + getString(R.string.generic_list_page_count, albums.size()) : + getString(R.string.generic_list_page_count_unknown, albumListPageViewModel.maxNumber) + ); + break; + case Constants.ALBUM_STARRED: + bind.pageSubtitleLabel.setText(getString(R.string.generic_list_page_count, albums.size())); + break; + } + } + + private void setAlbumListPageSorter() { + switch (albumListPageViewModel.title) { + case Constants.ALBUM_RECENTLY_PLAYED: + case Constants.ALBUM_MOST_PLAYED: + case Constants.ALBUM_RECENTLY_ADDED: + bind.albumListSortImageView.setVisibility(View.GONE); + break; + case Constants.ALBUM_STARRED: + bind.albumListSortImageView.setVisibility(View.VISIBLE); + break; + } } @Override diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistListPageFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistListPageFragment.java index 4830c972..6b482303 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistListPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistListPageFragment.java @@ -1,11 +1,21 @@ package com.cappielloantonio.tempo.ui.fragment; +import android.annotation.SuppressLint; +import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.PopupMenu; +import android.widget.SearchView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; @@ -16,11 +26,15 @@ import com.cappielloantonio.tempo.R; import com.cappielloantonio.tempo.databinding.FragmentArtistListPageBinding; import com.cappielloantonio.tempo.interfaces.ClickCallback; +import com.cappielloantonio.tempo.subsonic.models.AlbumID3; +import com.cappielloantonio.tempo.subsonic.models.ArtistID3; import com.cappielloantonio.tempo.ui.activity.MainActivity; import com.cappielloantonio.tempo.ui.adapter.ArtistHorizontalAdapter; import com.cappielloantonio.tempo.util.Constants; import com.cappielloantonio.tempo.viewmodel.ArtistListPageViewModel; +import java.util.List; + @UnstableApi public class ArtistListPageFragment extends Fragment implements ClickCallback { private FragmentArtistListPageBinding bind; @@ -30,6 +44,12 @@ public class ArtistListPageFragment extends Fragment implements ClickCallback { private ArtistHorizontalAdapter artistHorizontalAdapter; + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { activity = (MainActivity) getActivity(); @@ -69,7 +89,10 @@ private void initAppBar() { activity.getSupportActionBar().setDisplayShowHomeEnabled(true); } - bind.toolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp()); + bind.toolbar.setNavigationOnClickListener(v -> { + hideKeyboard(v); + activity.navController.navigateUp(); + }); bind.appBarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> { if ((bind.artistInfoSector.getHeight() + verticalOffset) < (2 * ViewCompat.getMinimumHeight(bind.toolbar))) { @@ -80,18 +103,100 @@ private void initAppBar() { }); } + @SuppressLint("ClickableViewAccessibility") private void initArtistListView() { bind.artistListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.artistListRecyclerView.setHasFixedSize(true); artistHorizontalAdapter = new ArtistHorizontalAdapter(this); bind.artistListRecyclerView.setAdapter(artistHorizontalAdapter); - artistListPageViewModel.getArtistList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> artistHorizontalAdapter.setItems(artists)); + artistListPageViewModel.getArtistList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), artists -> { + artistHorizontalAdapter.setItems(artists); + setArtistListPageSubtitle(artists); + setArtistListPageSorter(); + }); + + bind.artistListRecyclerView.setOnTouchListener((v, event) -> { + hideKeyboard(v); + return false; + }); + + bind.artistListSortImageView.setOnClickListener(view -> showPopupMenu(view, R.menu.sort_horizontal_artist_popup_menu)); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.toolbar_menu, menu); + + MenuItem searchItem = menu.findItem(R.id.action_search); + + SearchView searchView = (SearchView) searchItem.getActionView(); + searchView.setImeOptions(EditorInfo.IME_ACTION_DONE); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + searchView.clearFocus(); + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + artistHorizontalAdapter.getFilter().filter(newText); + return false; + } + }); + + searchView.setPadding(-32, 0, 0, 0); + } + + private void hideKeyboard(View view) { + InputMethodManager imm = (InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + } + + private void showPopupMenu(View view, int menuResource) { + PopupMenu popup = new PopupMenu(requireContext(), view); + popup.getMenuInflater().inflate(menuResource, popup.getMenu()); + + popup.setOnMenuItemClickListener(menuItem -> { + if (menuItem.getItemId() == R.id.menu_horizontal_artist_sort_name) { + artistHorizontalAdapter.sort(Constants.ARTIST_ORDER_BY_NAME); + return true; + } else if (menuItem.getItemId() == R.id.menu_horizontal_artist_sort_most_recently_starred) { + artistHorizontalAdapter.sort(Constants.ARTIST_ORDER_BY_MOST_RECENTLY_STARRED); + return true; + } else if (menuItem.getItemId() == R.id.menu_horizontal_artist_sort_least_recently_starred) { + artistHorizontalAdapter.sort(Constants.ARTIST_ORDER_BY_LEAST_RECENTLY_STARRED); + return true; + } + + return false; + }); + + popup.show(); + } + + private void setArtistListPageSubtitle(List artists) { + switch (artistListPageViewModel.title) { + case Constants.ARTIST_STARRED: + case Constants.ARTIST_DOWNLOADED: + bind.pageSubtitleLabel.setText(getString(R.string.generic_list_page_count, artists.size())); + break; + } + } + + private void setArtistListPageSorter() { + switch (artistListPageViewModel.title) { + case Constants.ARTIST_STARRED: + case Constants.ARTIST_DOWNLOADED: + bind.artistListSortImageView.setVisibility(View.VISIBLE); + break; + } } @Override public void onArtistClick(Bundle bundle) { - Navigation.findNavController(requireView()).navigate(R.id.albumListPageFragment, bundle); + Navigation.findNavController(requireView()).navigate(R.id.artistPageFragment, bundle); } @Override diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/SongListPageFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/SongListPageFragment.java index 8d20281e..fcaeec84 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/SongListPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/SongListPageFragment.java @@ -274,20 +274,20 @@ private void setSongListPageSubtitle(List children) { switch (songListPageViewModel.title) { case Constants.MEDIA_BY_GENRE: bind.pageSubtitleLabel.setText(children.size() < songListPageViewModel.maxNumberByGenre ? - getString(R.string.song_list_page_count, children.size()) : - getString(R.string.song_list_page_count_unknown, songListPageViewModel.maxNumberByGenre) + getString(R.string.generic_list_page_count, children.size()) : + getString(R.string.generic_list_page_count_unknown, songListPageViewModel.maxNumberByGenre) ); break; case Constants.MEDIA_BY_YEAR: bind.pageSubtitleLabel.setText(children.size() < songListPageViewModel.maxNumberByYear ? - getString(R.string.song_list_page_count, children.size()) : - getString(R.string.song_list_page_count_unknown, songListPageViewModel.maxNumberByYear) + getString(R.string.generic_list_page_count, children.size()) : + getString(R.string.generic_list_page_count_unknown, songListPageViewModel.maxNumberByYear) ); break; case Constants.MEDIA_BY_ARTIST: case Constants.MEDIA_BY_GENRES: case Constants.MEDIA_STARRED: - bind.pageSubtitleLabel.setText(getString(R.string.song_list_page_count, children.size())); + bind.pageSubtitleLabel.setText(getString(R.string.generic_list_page_count, children.size())); break; } } diff --git a/app/src/main/java/com/cappielloantonio/tempo/util/Constants.kt b/app/src/main/java/com/cappielloantonio/tempo/util/Constants.kt index 7281b0fe..da8862df 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/util/Constants.kt +++ b/app/src/main/java/com/cappielloantonio/tempo/util/Constants.kt @@ -33,11 +33,15 @@ object Constants { const val ALBUM_ORDER_BY_RECENTLY_ADDED = "ALBUM_ORDER_BY_RECENTLY_ADDED" const val ALBUM_ORDER_BY_RECENTLY_PLAYED = "ALBUM_ORDER_BY_RECENTLY_PLAYED" const val ALBUM_ORDER_BY_MOST_PLAYED = "ALBUM_ORDER_BY_MOST_PLAYED" + const val ALBUM_ORDER_BY_MOST_RECENTLY_STARRED = "ALBUM_ORDER_BY_MOST_RECENTLY_STARRED" + const val ALBUM_ORDER_BY_LEAST_RECENTLY_STARRED = "ALBUM_ORDER_BY_LEAST_RECENTLY_STARRED" const val ARTIST_DOWNLOADED = "ARTIST_DOWNLOADED" const val ARTIST_STARRED = "ARTIST_STARRED" const val ARTIST_ORDER_BY_NAME = "ARTIST_ORDER_BY_NAME" const val ARTIST_ORDER_BY_RANDOM = "ARTIST_ORDER_BY_RANDOM" + const val ARTIST_ORDER_BY_MOST_RECENTLY_STARRED = "ARTIST_ORDER_BY_MOST_RECENTLY_STARRED" + const val ARTIST_ORDER_BY_LEAST_RECENTLY_STARRED = "ARTIST_ORDER_BY_LEAST_RECENTLY_STARRED" const val GENRE_ORDER_BY_NAME = "GENRE_ORDER_BY_NAME" const val GENRE_ORDER_BY_RANDOM = "GENRE_ORDER_BY_RANDOM" diff --git a/app/src/main/java/com/cappielloantonio/tempo/viewmodel/AlbumListPageViewModel.java b/app/src/main/java/com/cappielloantonio/tempo/viewmodel/AlbumListPageViewModel.java index 3bcfa9ce..956ba6fa 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/viewmodel/AlbumListPageViewModel.java +++ b/app/src/main/java/com/cappielloantonio/tempo/viewmodel/AlbumListPageViewModel.java @@ -28,6 +28,8 @@ public class AlbumListPageViewModel extends AndroidViewModel { private MutableLiveData> albumList; + public int maxNumber = 500; + public AlbumListPageViewModel(@NonNull Application application) { super(application); @@ -40,20 +42,20 @@ public LiveData> getAlbumList(LifecycleOwner owner) { switch (title) { case Constants.ALBUM_RECENTLY_PLAYED: - albumRepository.getAlbums("recent", 500, null, null).observe(owner, albums -> albumList.setValue(albums)); + albumRepository.getAlbums("recent", maxNumber, null, null).observe(owner, albums -> albumList.setValue(albums)); break; case Constants.ALBUM_MOST_PLAYED: - albumRepository.getAlbums("frequent", 500, null, null).observe(owner, albums -> albumList.setValue(albums)); + albumRepository.getAlbums("frequent", maxNumber, null, null).observe(owner, albums -> albumList.setValue(albums)); break; case Constants.ALBUM_RECENTLY_ADDED: - albumRepository.getAlbums("newest", 500, null, null).observe(owner, albums -> albumList.setValue(albums)); + albumRepository.getAlbums("newest", maxNumber, null, null).observe(owner, albums -> albumList.setValue(albums)); break; case Constants.ALBUM_STARRED: albumList = albumRepository.getStarredAlbums(false, -1); break; case Constants.ALBUM_NEW_RELEASES: int currentYear = Calendar.getInstance().get(Calendar.YEAR); - albumRepository.getAlbums("byYear", 500, currentYear, currentYear).observe(owner, albums -> { + albumRepository.getAlbums("byYear", maxNumber, currentYear, currentYear).observe(owner, albums -> { albums.sort(Comparator.comparing(AlbumID3::getCreated).reversed()); albumList.postValue(albums.subList(0, Math.min(20, albums.size()))); }); diff --git a/app/src/main/res/layout/fragment_album_list_page.xml b/app/src/main/res/layout/fragment_album_list_page.xml index 7e5f3da4..66ae7497 100644 --- a/app/src/main/res/layout/fragment_album_list_page.xml +++ b/app/src/main/res/layout/fragment_album_list_page.xml @@ -33,17 +33,48 @@ + + +