From 77bdd71d790c0867be3e4478554becd76396d0a0 Mon Sep 17 00:00:00 2001 From: eddyizm Date: Wed, 29 Oct 2025 09:29:36 -0700 Subject: [PATCH 1/3] chore: updated bug issue --- .github/ISSUE_TEMPLATE/bug_report.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 9b6d9176..5f6a4003 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -26,6 +26,7 @@ Outline the steps required to reproduce the bug, including any specific actions, - Android device: [Device Model] - Android OS version: [Android Version] - App version: [App Version] + - App variant: [goole play services, degoogled] - Other relevant details: [e.g., specific network conditions, external dependencies] ## Logs or Screenshots From 5e1a2b41e9ae4b97654449b1506c30756f46b3c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Garc=C3=ADa?= <55400857+jaime-grj@users.noreply.github.com> Date: Wed, 29 Oct 2025 22:06:13 +0100 Subject: [PATCH 2/3] chore(i18n): Update Spanish (es-ES) translation --- app/src/main/res/values-es-rES/strings.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index c9d31115..cef6b661 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -413,7 +413,9 @@ Eliminar compartición Actualizar compartición Fecha de caducidad: %1$s + Nunca El uso compartido no está soportado o no está habilitado + Enlace de recurso: %1$s Descripción Fecha de caducidad Añadir a la cola @@ -486,4 +488,21 @@ Si está habilitada, los artistas destacados se descargarán para uso sin conexión. 0:00 Eliminar de favoritos + %1$s • %2$s + Copiado %1$s al portapapeles + Mostrar los detalles del álbum + Si está habilitada, muestra los detalles del álbum, como el género, el número de pistas, etc. en la página de álbum + Enlace de recurso de Tempus + UID de la pista + UID del álbum + UID del artista + UID de la lista de reproducción + UID del género + UID del año + UID del recurso + Enlace de recurso no válido + No se ha podido abrir la pista + No se ha podido abrir el álbum + No se ha podido abrir el artista + No se ha podido abrir la lista de reproducción \ No newline at end of file From 4b2e963a81ef688409833a2e59983cf7dad54d3f Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 30 Oct 2025 19:57:05 +0800 Subject: [PATCH 3/3] fix: shuffle for artists without using getTopSongs --- .../tempo/repository/ArtistRepository.java | 34 +++++++++++++++---- .../tempo/ui/fragment/ArtistPageFragment.java | 2 -- .../ArtistBottomSheetDialog.java | 3 ++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/cappielloantonio/tempo/repository/ArtistRepository.java b/app/src/main/java/com/cappielloantonio/tempo/repository/ArtistRepository.java index 4e06fad7..5bea391f 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/repository/ArtistRepository.java +++ b/app/src/main/java/com/cappielloantonio/tempo/repository/ArtistRepository.java @@ -13,9 +13,11 @@ import com.cappielloantonio.tempo.subsonic.models.Child; import com.cappielloantonio.tempo.subsonic.models.IndexID3; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; import retrofit2.Call; import retrofit2.Callback; @@ -312,24 +314,42 @@ public class ArtistRepository { App.getSubsonicClientInstance(false) .getBrowsingClient() - .getTopSongs(artist.getName(), count) + .getArtist(artist.getId()) .enqueue(new Callback() { @Override public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getTopSongs() != null && response.body().getSubsonicResponse().getTopSongs().getSongs() != null) { - List songs = response.body().getSubsonicResponse().getTopSongs().getSongs(); + if (response.isSuccessful() && response.body() != null && + response.body().getSubsonicResponse().getArtist() != null && + response.body().getSubsonicResponse().getArtist().getAlbums() != null) { - if (songs != null && !songs.isEmpty()) { - Collections.shuffle(songs); + List albums = response.body().getSubsonicResponse().getArtist().getAlbums(); + Log.d("ArtistRepository", "Got albums directly: " + albums.size()); + if (albums.isEmpty()) { + Log.d("ArtistRepository", "No albums found in artist response"); + return; } - randomSongs.setValue(songs); + Collections.shuffle(albums); + int[] counts = albums.stream().mapToInt(AlbumID3::getSongCount).toArray(); + Arrays.parallelPrefix(counts, Integer::sum); + int albumLimit = 0; + int multiplier = 4; // get more than the limit so we can shuffle them + while (albumLimit < albums.size() && counts[albumLimit] < count * multiplier) + albumLimit++; + Log.d("ArtistRepository", String.format("Retaining %d/%d albums", albumLimit, albums.size())); + + fetchAllAlbumSongsWithCallback(albums.stream().limit(albumLimit).collect(Collectors.toList()), songs -> { + Collections.shuffle(songs); + randomSongs.setValue(songs.stream().limit(count).collect(Collectors.toList())); + }); + } else { + Log.d("ArtistRepository", "Failed to get artist info"); } } @Override public void onFailure(@NonNull Call call, @NonNull Throwable t) { - + Log.d("ArtistRepository", "Error getting artist info: " + t.getMessage()); } }); diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistPageFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistPageFragment.java index fe24f06e..2d39eea1 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/ArtistPageFragment.java @@ -188,8 +188,6 @@ public class ArtistPageFragment extends Fragment implements ClickCallback { } else { if (bind != null) bind.artistPageTopSongsSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE); - if (bind != null) - bind.artistPageShuffleButton.setEnabled(!songs.isEmpty()); songHorizontalAdapter.setItems(songs); reapplyPlayback(); } diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java index 78fc943e..9ec9b549 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java @@ -89,6 +89,9 @@ public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implement ArtistRepository artistRepository = new ArtistRepository(); artistRepository.getInstantMix(artist, 20).observe(getViewLifecycleOwner(), songs -> { + // navidrome may return null for this + if (songs == null) + return; MusicUtil.ratingFilter(songs); if (!songs.isEmpty()) {