mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 17:43:32 +00:00
feat: added filter for songs that don't meet a user defined rating threshold
This commit is contained in:
parent
612c05fabc
commit
121c2b33da
9 changed files with 73 additions and 0 deletions
|
|
@ -51,6 +51,7 @@ import com.cappielloantonio.tempo.ui.adapter.YearAdapter;
|
||||||
import com.cappielloantonio.tempo.util.Constants;
|
import com.cappielloantonio.tempo.util.Constants;
|
||||||
import com.cappielloantonio.tempo.util.DownloadUtil;
|
import com.cappielloantonio.tempo.util.DownloadUtil;
|
||||||
import com.cappielloantonio.tempo.util.MappingUtil;
|
import com.cappielloantonio.tempo.util.MappingUtil;
|
||||||
|
import com.cappielloantonio.tempo.util.MusicUtil;
|
||||||
import com.cappielloantonio.tempo.util.Preferences;
|
import com.cappielloantonio.tempo.util.Preferences;
|
||||||
import com.cappielloantonio.tempo.util.UIUtil;
|
import com.cappielloantonio.tempo.util.UIUtil;
|
||||||
import com.cappielloantonio.tempo.viewmodel.HomeViewModel;
|
import com.cappielloantonio.tempo.viewmodel.HomeViewModel;
|
||||||
|
|
@ -153,6 +154,8 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
|
|
||||||
bind.discoveryTextViewClickable.setOnClickListener(v -> {
|
bind.discoveryTextViewClickable.setOnClickListener(v -> {
|
||||||
homeViewModel.getRandomShuffleSample().observe(getViewLifecycleOwner(), songs -> {
|
homeViewModel.getRandomShuffleSample().observe(getViewLifecycleOwner(), songs -> {
|
||||||
|
MusicUtil.ratingFilter(songs);
|
||||||
|
|
||||||
if (songs.size() > 0) {
|
if (songs.size() > 0) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
||||||
activity.setBottomSheetInPeek(true);
|
activity.setBottomSheetInPeek(true);
|
||||||
|
|
@ -306,6 +309,8 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
bind.discoverSongViewPager.setAdapter(discoverSongAdapter);
|
bind.discoverSongViewPager.setAdapter(discoverSongAdapter);
|
||||||
bind.discoverSongViewPager.setOffscreenPageLimit(1);
|
bind.discoverSongViewPager.setOffscreenPageLimit(1);
|
||||||
homeViewModel.getDiscoverSongSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> {
|
homeViewModel.getDiscoverSongSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> {
|
||||||
|
MusicUtil.ratingFilter(songs);
|
||||||
|
|
||||||
if (songs == null) {
|
if (songs == null) {
|
||||||
if (bind != null)
|
if (bind != null)
|
||||||
bind.homeDiscoveryPlaceholder.placeholder.setVisibility(View.VISIBLE);
|
bind.homeDiscoveryPlaceholder.placeholder.setVisibility(View.VISIBLE);
|
||||||
|
|
@ -330,6 +335,8 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
similarMusicAdapter = new SimilarTrackAdapter(this);
|
similarMusicAdapter = new SimilarTrackAdapter(this);
|
||||||
bind.similarTracksRecyclerView.setAdapter(similarMusicAdapter);
|
bind.similarTracksRecyclerView.setAdapter(similarMusicAdapter);
|
||||||
homeViewModel.getStarredTracksSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> {
|
homeViewModel.getStarredTracksSample(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> {
|
||||||
|
MusicUtil.ratingFilter(songs);
|
||||||
|
|
||||||
if (songs == null) {
|
if (songs == null) {
|
||||||
if (bind != null)
|
if (bind != null)
|
||||||
bind.homeSimilarTracksPlaceholder.placeholder.setVisibility(View.VISIBLE);
|
bind.homeSimilarTracksPlaceholder.placeholder.setVisibility(View.VISIBLE);
|
||||||
|
|
@ -744,6 +751,8 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
|
|
||||||
if (mediaBrowserListenableFuture != null) {
|
if (mediaBrowserListenableFuture != null) {
|
||||||
homeViewModel.getMediaInstantMix(getViewLifecycleOwner(), bundle.getParcelable(Constants.TRACK_OBJECT)).observe(getViewLifecycleOwner(), songs -> {
|
homeViewModel.getMediaInstantMix(getViewLifecycleOwner(), bundle.getParcelable(Constants.TRACK_OBJECT)).observe(getViewLifecycleOwner(), songs -> {
|
||||||
|
MusicUtil.ratingFilter(songs);
|
||||||
|
|
||||||
if (songs != null && songs.size() > 0) {
|
if (songs != null && songs.size() > 0) {
|
||||||
MediaManager.enqueue(mediaBrowserListenableFuture, songs, true);
|
MediaManager.enqueue(mediaBrowserListenableFuture, songs, true);
|
||||||
}
|
}
|
||||||
|
|
@ -783,6 +792,8 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
|
|
||||||
if (mediaBrowserListenableFuture != null) {
|
if (mediaBrowserListenableFuture != null) {
|
||||||
homeViewModel.getArtistInstantMix(getViewLifecycleOwner(), bundle.getParcelable(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> {
|
homeViewModel.getArtistInstantMix(getViewLifecycleOwner(), bundle.getParcelable(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> {
|
||||||
|
MusicUtil.ratingFilter(songs);
|
||||||
|
|
||||||
if (songs.size() > 0) {
|
if (songs.size() > 0) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
||||||
activity.setBottomSheetInPeek(true);
|
activity.setBottomSheetInPeek(true);
|
||||||
|
|
@ -792,6 +803,8 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
|
||||||
} else if (bundle.containsKey(Constants.MEDIA_BEST_OF) && bundle.getBoolean(Constants.MEDIA_BEST_OF)) {
|
} else if (bundle.containsKey(Constants.MEDIA_BEST_OF) && bundle.getBoolean(Constants.MEDIA_BEST_OF)) {
|
||||||
if (mediaBrowserListenableFuture != null) {
|
if (mediaBrowserListenableFuture != null) {
|
||||||
homeViewModel.getArtistBestOf(getViewLifecycleOwner(), bundle.getParcelable(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> {
|
homeViewModel.getArtistBestOf(getViewLifecycleOwner(), bundle.getParcelable(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> {
|
||||||
|
MusicUtil.ratingFilter(songs);
|
||||||
|
|
||||||
if (songs.size() > 0) {
|
if (songs.size() > 0) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
||||||
activity.setBottomSheetInPeek(true);
|
activity.setBottomSheetInPeek(true);
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,8 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadMedia(List<?> media) {
|
public void onLoadMedia(List<?> media) {
|
||||||
|
MusicUtil.ratingFilter((ArrayList<Child>) media);
|
||||||
|
|
||||||
if (media.size() > 0) {
|
if (media.size() > 0) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, (ArrayList<Child>) media, 0);
|
MediaManager.startQueue(mediaBrowserListenableFuture, (ArrayList<Child>) media, 0);
|
||||||
((MainActivity) requireActivity()).setBottomSheetInPeek(true);
|
((MainActivity) requireActivity()).setBottomSheetInPeek(true);
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,8 @@ public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implement
|
||||||
ArtistRepository artistRepository = new ArtistRepository();
|
ArtistRepository artistRepository = new ArtistRepository();
|
||||||
|
|
||||||
artistRepository.getInstantMix(artist, 20).observe(getViewLifecycleOwner(), songs -> {
|
artistRepository.getInstantMix(artist, 20).observe(getViewLifecycleOwner(), songs -> {
|
||||||
|
MusicUtil.ratingFilter(songs);
|
||||||
|
|
||||||
if (songs.size() > 0) {
|
if (songs.size() > 0) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
||||||
((MainActivity) requireActivity()).setBottomSheetInPeek(true);
|
((MainActivity) requireActivity()).setBottomSheetInPeek(true);
|
||||||
|
|
@ -102,6 +104,8 @@ public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implement
|
||||||
playRandom.setOnClickListener(v -> {
|
playRandom.setOnClickListener(v -> {
|
||||||
ArtistRepository artistRepository = new ArtistRepository();
|
ArtistRepository artistRepository = new ArtistRepository();
|
||||||
artistRepository.getRandomSong(artist, 50).observe(getViewLifecycleOwner(), songs -> {
|
artistRepository.getRandomSong(artist, 50).observe(getViewLifecycleOwner(), songs -> {
|
||||||
|
MusicUtil.ratingFilter(songs);
|
||||||
|
|
||||||
if (songs.size() > 0) {
|
if (songs.size() > 0) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
MediaManager.startQueue(mediaBrowserListenableFuture, songs, 0);
|
||||||
((MainActivity) requireActivity()).setBottomSheetInPeek(true);
|
((MainActivity) requireActivity()).setBottomSheetInPeek(true);
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,8 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
|
||||||
((MainActivity) requireActivity()).setBottomSheetInPeek(true);
|
((MainActivity) requireActivity()).setBottomSheetInPeek(true);
|
||||||
|
|
||||||
songBottomSheetViewModel.getInstantMix(getViewLifecycleOwner(), song).observe(getViewLifecycleOwner(), songs -> {
|
songBottomSheetViewModel.getInstantMix(getViewLifecycleOwner(), song).observe(getViewLifecycleOwner(), songs -> {
|
||||||
|
MusicUtil.ratingFilter(songs);
|
||||||
|
|
||||||
if (songs == null) {
|
if (songs == null) {
|
||||||
dismissBottomSheet();
|
dismissBottomSheet();
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -307,4 +307,17 @@ public class MusicUtil {
|
||||||
private static ConnectivityManager getConnectivityManager() {
|
private static ConnectivityManager getConnectivityManager() {
|
||||||
return (ConnectivityManager) App.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
|
return (ConnectivityManager) App.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ratingFilter(List<Child> toFilter) {
|
||||||
|
if (toFilter == null || toFilter.isEmpty()) return;
|
||||||
|
|
||||||
|
List<Child> filtered = toFilter
|
||||||
|
.stream()
|
||||||
|
.filter(child -> (child.getUserRating() != null && child.getUserRating() >= Preferences.getMinStarRatingAccepted()) || (child.getUserRating() == null))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
toFilter.clear();
|
||||||
|
|
||||||
|
toFilter.addAll(filtered);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,9 @@ object Preferences {
|
||||||
private const val SCROBBLING = "scrobbling"
|
private const val SCROBBLING = "scrobbling"
|
||||||
private const val ESTIMATE_CONTENT_LENGTH = "estimate_content_length"
|
private const val ESTIMATE_CONTENT_LENGTH = "estimate_content_length"
|
||||||
private const val BUFFERING_STRATEGY = "buffering_strategy"
|
private const val BUFFERING_STRATEGY = "buffering_strategy"
|
||||||
|
private const val SKIP_MIN_STAR_RATING = "skip_min_star_rating"
|
||||||
|
private const val MIN_STAR_RATING = "min_star_rating"
|
||||||
|
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getServer(): String? {
|
fun getServer(): String? {
|
||||||
|
|
@ -338,4 +341,8 @@ object Preferences {
|
||||||
return App.getInstance().preferences.getString(BUFFERING_STRATEGY, "1")!!.toDouble()
|
return App.getInstance().preferences.getString(BUFFERING_STRATEGY, "1")!!.toDouble()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getMinStarRatingAccepted(): Int {
|
||||||
|
return App.getInstance().preferences.getInt(MIN_STAR_RATING, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -224,4 +224,19 @@
|
||||||
<item>4</item>
|
<item>4</item>
|
||||||
<item>8</item>
|
<item>8</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="skip_min_star_rating_titles">
|
||||||
|
<item>0 star minimum</item>
|
||||||
|
<item>1 star minimum</item>
|
||||||
|
<item>2 stars minimum</item>
|
||||||
|
<item>3 stars minimum</item>
|
||||||
|
<item>4 stars minimum</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="skip_min_star_rating_values">
|
||||||
|
<item>0</item>
|
||||||
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
|
<item>3</item>
|
||||||
|
<item>4</item>
|
||||||
|
</string-array>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -274,6 +274,7 @@
|
||||||
<string name="settings_scrobble_title">Enable music scrobbling</string>
|
<string name="settings_scrobble_title">Enable music scrobbling</string>
|
||||||
<string name="settings_share_title">Enable music sharing</string>
|
<string name="settings_share_title">Enable music sharing</string>
|
||||||
<string name="settings_sub_summary_scrobble">It\'s important to note that scrobbling also relies on the server being enabled to receive this data.</string>
|
<string name="settings_sub_summary_scrobble">It\'s important to note that scrobbling also relies on the server being enabled to receive this data.</string>
|
||||||
|
<string name="settings_summary_skip_min_star_rating">When listening to an artist\'s radio, an instant mix or when shuffling all, tracks below a certain user rating will be ignored.</string>
|
||||||
<string name="settings_summary_replay_gain">Replay gain is a feature that allows you to adjust the volume level of audio tracks for a consistent listening experience. This setting is only effective if the track contains the necessary metadata.</string>
|
<string name="settings_summary_replay_gain">Replay gain is a feature that allows you to adjust the volume level of audio tracks for a consistent listening experience. This setting is only effective if the track contains the necessary metadata.</string>
|
||||||
<string name="settings_summary_scrobble">Scrobbling is a feature that allows your device to send information about the songs you listen to the music server. This information helps create personalized recommendations based on your music preferences.</string>
|
<string name="settings_summary_scrobble">Scrobbling is a feature that allows your device to send information about the songs you listen to the music server. This information helps create personalized recommendations based on your music preferences.</string>
|
||||||
<string name="settings_summary_share">Allows the user to share music via a link. The functionality must be supported and enabled server-side and is limited to individual tracks, albums and playlists.</string>
|
<string name="settings_summary_share">Allows the user to share music via a link. The functionality must be supported and enabled server-side and is limited to individual tracks, albums and playlists.</string>
|
||||||
|
|
@ -286,8 +287,11 @@
|
||||||
<string name="settings_theme">Theme</string>
|
<string name="settings_theme">Theme</string>
|
||||||
<string name="settings_title_data">Data</string>
|
<string name="settings_title_data">Data</string>
|
||||||
<string name="settings_title_general">General</string>
|
<string name="settings_title_general">General</string>
|
||||||
|
<string name="settings_title_rating">Rating</string>
|
||||||
<string name="settings_title_replay_gain">Replay Gain</string>
|
<string name="settings_title_replay_gain">Replay Gain</string>
|
||||||
<string name="settings_title_scrobble">Scrobble</string>
|
<string name="settings_title_scrobble">Scrobble</string>
|
||||||
|
<string name="settings_title_skip_min_star_rating">Ignore tracks based on rating</string>
|
||||||
|
<string name="settings_title_skip_min_star_rating_dialog">Songs with a rating of:</string>
|
||||||
<string name="settings_title_share">Share</string>
|
<string name="settings_title_share">Share</string>
|
||||||
<string name="settings_title_syncing">Syncing</string>
|
<string name="settings_title_syncing">Syncing</string>
|
||||||
<string name="settings_title_transcoding">Transcoding</string>
|
<string name="settings_title_transcoding">Transcoding</string>
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,19 @@
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory app:title="@string/settings_title_rating">
|
||||||
|
<SeekBarPreference
|
||||||
|
android:key="min_star_rating"
|
||||||
|
app:defaultValue="0"
|
||||||
|
app:min="0"
|
||||||
|
android:max="4"
|
||||||
|
app:seekBarIncrement="1"
|
||||||
|
app:showSeekBarValue="true"
|
||||||
|
app:summary="@string/settings_summary_skip_min_star_rating"
|
||||||
|
app:title="@string/settings_title_skip_min_star_rating" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory app:title="@string/settings_title_scrobble">
|
<PreferenceCategory app:title="@string/settings_title_scrobble">
|
||||||
<Preference
|
<Preference
|
||||||
app:selectable="false"
|
app:selectable="false"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue