From 1ef7ef737799bb099092f57022d37c8b4214c16a Mon Sep 17 00:00:00 2001 From: Joril Date: Tue, 17 Mar 2026 20:26:07 +0000 Subject: [PATCH] Add preference to shuffle songs on the 'genre' page --- .../repository/AutomotiveRepository.java | 68 ++++++++++++------- .../tempo/util/Preferences.kt | 11 +++ app/src/main/res/values-fr/strings.xml | 3 +- app/src/main/res/values-ru/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/global_preferences.xml | 7 +- .../tempo/service/MediaBrowserTree.kt | 5 +- 7 files changed, 72 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/cappielloantonio/tempo/repository/AutomotiveRepository.java b/app/src/main/java/com/cappielloantonio/tempo/repository/AutomotiveRepository.java index c4dc829c..3d938862 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/repository/AutomotiveRepository.java +++ b/app/src/main/java/com/cappielloantonio/tempo/repository/AutomotiveRepository.java @@ -1008,39 +1008,61 @@ public class AutomotiveRepository { return listenableFuture; } - public ListenableFuture>> getSongsByGenre(String genre, int count) { + public ListenableFuture>> getSongsByGenre(String genre, int count, boolean shuffle) { final SettableFuture>> listenableFuture = SettableFuture.create(); - App.getSubsonicClientInstance(false) - .getAlbumSongListClient() - .getSongsByGenre(genre, count, 0) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getSongsByGenre() != null && response.body().getSubsonicResponse().getSongsByGenre().getSongs() != null) { - List songs = response.body().getSubsonicResponse().getSongsByGenre().getSongs(); + Call call; + if (shuffle) { + call = App.getSubsonicClientInstance(false) + .getAlbumSongListClient() + .getRandomSongs(count, null, null, genre); + } else { + call = App.getSubsonicClientInstance(false) + .getAlbumSongListClient() + .getSongsByGenre(genre, count, 0); + } - setChildrenMetadata(songs); - - List mediaItems = MappingUtil.mapMediaItems(songs); - - LibraryResult> libraryResult = LibraryResult.ofItemList(ImmutableList.copyOf(mediaItems), null); - - listenableFuture.set(libraryResult); - } else { - listenableFuture.set(LibraryResult.ofError(LibraryResult.RESULT_ERROR_BAD_VALUE)); - } + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful() && response.body() != null) { + List songs; + if (shuffle) { + songs = response.body().getSubsonicResponse().getRandomSongs() != null + ? response.body().getSubsonicResponse().getRandomSongs().getSongs() + : null; + } else { + songs = response.body().getSubsonicResponse().getSongsByGenre() != null + ? response.body().getSubsonicResponse().getSongsByGenre().getSongs() + : null; } - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - listenableFuture.setException(t); + if (songs != null) { + setChildrenMetadata(songs); + List mediaItems = MappingUtil.mapMediaItems(songs); + LibraryResult> libraryResult = LibraryResult.ofItemList(ImmutableList.copyOf(mediaItems), null); + listenableFuture.set(libraryResult); + } else { + listenableFuture.set(LibraryResult.ofError(LibraryResult.RESULT_ERROR_BAD_VALUE)); } - }); + } else { + listenableFuture.set(LibraryResult.ofError(LibraryResult.RESULT_ERROR_BAD_VALUE)); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + listenableFuture.setException(t); + } + }); return listenableFuture; } + public ListenableFuture>> getSongsByGenre(String genre, int count) { + return getSongsByGenre(genre, count, false); + } + private static class GetMediaItemThreadSafe implements Runnable { private final SessionMediaItemDao sessionMediaItemDao; private final String id; diff --git a/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt b/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt index 9f40758c..e05d66a3 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt +++ b/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt @@ -102,6 +102,7 @@ object Preferences { private const val AA_SECOND_TAB = "androidauto_second_tab" private const val AA_THIRD_TAB = "androidauto_third_tab" private const val AA_FOURTH_TAB = "androidauto_fourth_tab" + private const val AA_SHUFFLE_GENRE_SONGS = "androidauto_shuffle_genre_songs" @JvmStatic fun getServer(): String? { @@ -818,4 +819,14 @@ object Preferences { return App.getInstance().preferences.getString(AA_FOURTH_TAB, "3")!!.toInt() } + @JvmStatic + fun isAndroidAutoShuffleGenreSongsEnabled(): Boolean { + return App.getInstance().preferences.getBoolean(AA_SHUFFLE_GENRE_SONGS, false) + } + + @JvmStatic + fun setAndroidAutoShuffleGenreSongsEnabled(enabled: Boolean) { + App.getInstance().preferences.edit().putBoolean(AA_SHUFFLE_GENRE_SONGS, enabled).apply() + } + } \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 9cc61079..07639ef9 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -338,6 +338,8 @@ Affichage du deuxième onglet Affichage du troisième onglet Affichage du quatrième onglet + Mélanger les chansons par genre + Lire des chansons aléatoires lors de la sélection d\'un genre Format de transcodage Si activé, Tempus ne forcera pas le téléchargement de la piste avec les paramètres de transcodage ci-dessous. Prioriser les paramètres du serveurs, utilisés pour le streaming, dans les téléchargements @@ -434,7 +436,6 @@ Thème Taille des vignettes Données - Données Géneral Playlist Note diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 9315a180..ee27227c 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -402,6 +402,8 @@ Second tab display Third tab display Fourth tab display + Перемешивать треки по жанру + Воспроизводить случайные треки при выборе жанра Показывать качество аудио Битрейт и формат аудио будут отображаться для каждого трека. Показывать рейтинг трека diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8768dd1e..2662e9e7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -403,6 +403,8 @@ Second tab display Third tab display Fourth tab display + Shuffle genre songs + Play random songs when selecting a genre Show audio quality The bitrate and audio format will be shown for each audio track. Show song star rating diff --git a/app/src/main/res/xml/global_preferences.xml b/app/src/main/res/xml/global_preferences.xml index 0b7c53d6..7e90ccf8 100644 --- a/app/src/main/res/xml/global_preferences.xml +++ b/app/src/main/res/xml/global_preferences.xml @@ -519,7 +519,12 @@ app:entryValues="@array/aa_tab_values" app:key="androidauto_fourth_tab" app:title="@string/settings_androidauto_fourth_tab" - app:useSimpleSummaryProvider="true" /> + app:useSimpleSummaryProvider="true" /> + + diff --git a/app/src/tempus/java/com/cappielloantonio/tempo/service/MediaBrowserTree.kt b/app/src/tempus/java/com/cappielloantonio/tempo/service/MediaBrowserTree.kt index 5b3fe879..a417e739 100644 --- a/app/src/tempus/java/com/cappielloantonio/tempo/service/MediaBrowserTree.kt +++ b/app/src/tempus/java/com/cappielloantonio/tempo/service/MediaBrowserTree.kt @@ -529,7 +529,10 @@ object MediaBrowserTree { } if (id.startsWith(GENRES_ID)) { - return automotiveRepository.getSongsByGenre(id.removePrefix(GENRES_ID), 100) + val shuffle = Preferences.isAndroidAutoShuffleGenreSongsEnabled() + // If the user doesn't want random songs, it's likely it's for perusing them, so provide as many as possible + val count = if (shuffle) 100 else 500 + return automotiveRepository.getSongsByGenre(id.removePrefix(GENRES_ID), count, shuffle) } if (id.startsWith(PLAYLIST_ID)) {