Merge branch 'eddyizm:development' into development

This commit is contained in:
skajmer 2025-11-10 11:41:33 +01:00 committed by GitHub
commit c4bd30d512
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 86 additions and 9 deletions

View file

@ -1,10 +1,27 @@
# Changelog # Changelog
## Pending release.. ## Pending release..
* fix: reverts change causing album disc/track list to get out of order by @eddyizm in https://github.com/eddyizm/tempus/pull/237
## [4.2.0](https://github.com/eddyizm/tempo/releases/tag/v4.2.0) (2025-11-09)
## What's Changed
* fix: Equalizer fix in main build variant by @jaime-grj in https://github.com/eddyizm/tempus/pull/239
* fix: Images not filling holder by @eddyizm in https://github.com/eddyizm/tempus/pull/244
* feat: Make artist and album clickable by @eddyizm in https://github.com/eddyizm/tempus/pull/243
* feat: implement scroll to currently playing feature by @shrapnelnet in https://github.com/eddyizm/tempus/pull/247
* fix: shuffling genres only queuing 25 songs by @shrapnelnet in https://github.com/eddyizm/tempus/pull/246
## New Contributors
* @shrapnelnet made their first contribution in https://github.com/eddyizm/tempus/pull/247
**Full Changelog**: https://github.com/eddyizm/tempus/compare/v4.1.3...v4.2.0
## [4.1.3](https://github.com/eddyizm/tempo/releases/tag/v4.1.3) (2025-11-06)
## What's Changed
* [fix: equalizer missing referenced value](https://github.com/eddyizm/tempus/commit/923cfd5bc97ed7db28c90348e3619d0a784fc434)
* Fix: Album track list bug by @eddyizm in https://github.com/eddyizm/tempus/pull/237
* fix: Add listener to enable equalizer when audioSessionId changes by @jaime-grj in https://github.com/eddyizm/tempus/pull/235 * fix: Add listener to enable equalizer when audioSessionId changes by @jaime-grj in https://github.com/eddyizm/tempus/pull/235
**Full Changelog**: https://github.com/eddyizm/tempus/compare/v4.1.0...v4.1.2 **Full Changelog**: https://github.com/eddyizm/tempus/compare/v4.1.0...v4.1.3
## [4.1.0](https://github.com/eddyizm/tempo/releases/tag/v4.1.0) (2025-11-05) ## [4.1.0](https://github.com/eddyizm/tempo/releases/tag/v4.1.0) (2025-11-05)
## What's Changed ## What's Changed

View file

@ -10,8 +10,8 @@ android {
minSdkVersion 24 minSdkVersion 24
targetSdk 35 targetSdk 35
versionCode 4 versionCode 5
versionName '4.1.3' versionName '4.2.0'
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
javaCompileOptions { javaCompileOptions {

View file

@ -100,6 +100,33 @@ public class SongRepository {
return randomSongsSample; return randomSongsSample;
} }
public MutableLiveData<List<Child>> getRandomSampleWithGenre(int number, Integer fromYear, Integer toYear, String genre) {
MutableLiveData<List<Child>> randomSongsSample = new MutableLiveData<>();
App.getSubsonicClientInstance(false)
.getAlbumSongListClient()
.getRandomSongs(number, fromYear, toYear, genre)
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
List<Child> songs = new ArrayList<>();
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getRandomSongs() != null && response.body().getSubsonicResponse().getRandomSongs().getSongs() != null) {
songs.addAll(response.body().getSubsonicResponse().getRandomSongs().getSongs());
}
randomSongsSample.setValue(songs);
}
@Override
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
}
});
return randomSongsSample;
}
public void scrobble(String id, boolean submission) { public void scrobble(String id, boolean submission) {
App.getSubsonicClientInstance(false) App.getSubsonicClientInstance(false)
.getMediaAnnotationClient() .getMediaAnnotationClient()

View file

@ -34,6 +34,11 @@ public class AlbumSongListClient {
return albumSongListService.getRandomSongs(subsonic.getParams(), size, fromYear, toYear); return albumSongListService.getRandomSongs(subsonic.getParams(), size, fromYear, toYear);
} }
public Call<ApiResponse> getRandomSongs(int size, Integer fromYear, Integer toYear, String genre) {
Log.d(TAG, "getRandomSongs()");
return albumSongListService.getRandomSongs(subsonic.getParams(), size, fromYear, toYear, genre);
}
public Call<ApiResponse> getSongsByGenre(String genre, int count, int offset) { public Call<ApiResponse> getSongsByGenre(String genre, int count, int offset) {
Log.d(TAG, "getSongsByGenre()"); Log.d(TAG, "getSongsByGenre()");
return albumSongListService.getSongsByGenre(subsonic.getParams(), genre, count, offset); return albumSongListService.getSongsByGenre(subsonic.getParams(), genre, count, offset);

View file

@ -19,6 +19,9 @@ public interface AlbumSongListService {
@GET("getRandomSongs") @GET("getRandomSongs")
Call<ApiResponse> getRandomSongs(@QueryMap Map<String, String> params, @Query("size") int size, @Query("fromYear") Integer fromYear, @Query("toYear") Integer toYear); Call<ApiResponse> getRandomSongs(@QueryMap Map<String, String> params, @Query("size") int size, @Query("fromYear") Integer fromYear, @Query("toYear") Integer toYear);
@GET("getRandomSongs")
Call<ApiResponse> getRandomSongs(@QueryMap Map<String, String> params, @Query("size") int size, @Query("fromYear") Integer fromYear, @Query("toYear") Integer toYear, @Query("genre") String genre);
@GET("getSongsByGenre") @GET("getSongsByGenre")
Call<ApiResponse> getSongsByGenre(@QueryMap Map<String, String> params, @Query("genre") String genre, @Query("count") int count, @Query("offset") int offset); Call<ApiResponse> getSongsByGenre(@QueryMap Map<String, String> params, @Query("genre") String genre, @Query("count") int count, @Query("offset") int offset);

View file

@ -73,6 +73,11 @@ public class DiscoverSongAdapter extends RecyclerView.Adapter<DiscoverSongAdapte
this.item = item; this.item = item;
itemView.setOnClickListener(v -> onClick()); itemView.setOnClickListener(v -> onClick());
itemView.setOnLongClickListener(v -> {
onLongClick();
return true;
});
} }
public void onClick() { public void onClick() {
@ -82,6 +87,13 @@ public class DiscoverSongAdapter extends RecyclerView.Adapter<DiscoverSongAdapte
click.onMediaClick(bundle); click.onMediaClick(bundle);
} }
private boolean onLongClick() {
Bundle bundle = new Bundle();
bundle.putParcelable(Constants.TRACK_OBJECT, songs.get(getBindingAdapterPosition()));
click.onMediaLongClick(bundle);
return true;
}
} }
private void startAnimation(ViewHolder holder) { private void startAnimation(ViewHolder holder) {

View file

@ -2,6 +2,7 @@ package com.cappielloantonio.tempo.ui.fragment;
import android.content.ComponentName; import android.content.ComponentName;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -72,6 +73,12 @@ public class PlayerQueueFragment extends Fragment implements ClickCallback {
super.onResume(); super.onResume();
setMediaBrowserListenableFuture(); setMediaBrowserListenableFuture();
updateNowPlayingItem(); updateNowPlayingItem();
try {
long position = mediaBrowserListenableFuture.get().getCurrentMediaItemIndex();
bind.playerQueueRecyclerView.scrollToPosition((int) position);
} catch (Exception e) {
Log.e("PlayerQueueFragment", "Failed to get mediaBrowserListenableFuture in onResume", e);
}
} }
@Override @Override

View file

@ -189,7 +189,7 @@ public class SongListPageFragment extends Fragment implements ClickCallback {
bind.songListShuffleImageView.setOnClickListener(v -> { bind.songListShuffleImageView.setOnClickListener(v -> {
Collections.shuffle(songs); Collections.shuffle(songs);
MediaManager.startQueue(mediaBrowserListenableFuture, songs.subList(0, Math.min(25, songs.size())), 0); MediaManager.startQueue(mediaBrowserListenableFuture, songs.subList(0, Math.min(500, songs.size())), 0);
activity.setBottomSheetInPeek(true); activity.setBottomSheetInPeek(true);
}); });
} }

View file

@ -37,7 +37,7 @@ public class SongListPageViewModel extends AndroidViewModel {
public int year = 0; public int year = 0;
public int maxNumberByYear = 500; public int maxNumberByYear = 500;
public int maxNumberByGenre = 100; public int maxNumberByGenre = 500;
public SongListPageViewModel(@NonNull Application application) { public SongListPageViewModel(@NonNull Application application) {
super(application); super(application);
@ -51,7 +51,7 @@ public class SongListPageViewModel extends AndroidViewModel {
switch (title) { switch (title) {
case Constants.MEDIA_BY_GENRE: case Constants.MEDIA_BY_GENRE:
songList = songRepository.getSongsByGenre(genre.getGenre(), 0); songList = songRepository.getRandomSampleWithGenre(maxNumberByGenre, 0, 3000, genre.getGenre());
break; break;
case Constants.MEDIA_BY_ARTIST: case Constants.MEDIA_BY_ARTIST:
songList = artistRepository.getTopSongs(artist.getName(), 50); songList = artistRepository.getTopSongs(artist.getName(), 50);

View file

@ -379,7 +379,7 @@
<string name="settings_summary_syncing">Returns the state of the play queue for this user. This includes the tracks in the play queue, the currently playing track, and the position within this track. The server must support this feature.\n*This setting is not 100% working on all servers/devices.</string> <string name="settings_summary_syncing">Returns the state of the play queue for this user. This includes the tracks in the play queue, the currently playing track, and the position within this track. The server must support this feature.\n*This setting is not 100% working on all servers/devices.</string>
<string name="settings_summary_streaming_cache_size">%1$s \nCurrently in use: %2$s MiB</string> <string name="settings_summary_streaming_cache_size">%1$s \nCurrently in use: %2$s MiB</string>
<string name="settings_summary_transcoding">Priority given to the transcoding mode. If set to \"Direct play\" the bitrate of the file will not be changed.</string> <string name="settings_summary_transcoding">Priority given to the transcoding mode. If set to \"Direct play\" the bitrate of the file will not be changed.</string>
<string name="settings_summary_transcoding_download">Download transcoded media. If enabled, the download endpoint will not be used, but the following settings. \n\n If \"Transcode format for donwloads\" is set to \"Direct download\" the bitrate of the file will not be changed.</string> <string name="settings_summary_transcoding_download">Download transcoded media. If enabled, the download endpoint will not be used, but the following settings. \n\n If \"Transcode format for downloads\" is set to \"Direct download\" the bitrate of the file will not be changed.</string>
<string name="settings_summary_transcoding_estimate_content_length">When the file is transcoded on the fly, the client usually does not show the track length. It is possible to request the servers that support the functionality to estimate the duration of the track being played, but the response times may take longer.</string> <string name="settings_summary_transcoding_estimate_content_length">When the file is transcoded on the fly, the client usually does not show the track length. It is possible to request the servers that support the functionality to estimate the duration of the track being played, but the response times may take longer.</string>
<string name="settings_sync_starred_artists_for_offline_use_summary">If enabled, starred artists will be downloaded for offline use.</string> <string name="settings_sync_starred_artists_for_offline_use_summary">If enabled, starred artists will be downloaded for offline use.</string>
<string name="settings_sync_starred_artists_for_offline_use_title">Sync starred artists for offline use</string> <string name="settings_sync_starred_artists_for_offline_use_title">Sync starred artists for offline use</string>

View file

@ -0,0 +1,5 @@
Equalizer fix in main build variant
fix Images not filling holder in discovery
Make artist and album clickable on home discovery
Implement scroll to currently playing feature
Shuffling genres now queuing 500 tracks vs 25

View file

@ -8,7 +8,6 @@ Features
- Streaming and Offline Mode: Stream music directly from your Subsonic server. Offline mode is currently under active development and may have limitations when using multiple servers. - Streaming and Offline Mode: Stream music directly from your Subsonic server. Offline mode is currently under active development and may have limitations when using multiple servers.
- Playlist Management: Create, edit, and manage playlists to curate your perfect music collection. - Playlist Management: Create, edit, and manage playlists to curate your perfect music collection.
- Gapless Playback: Experience uninterrupted playback with gapless listening mode. - Gapless Playback: Experience uninterrupted playback with gapless listening mode.
- Chromecast Support: Stream your music to Chromecast devices. The support is currently in a rudimentary state.
- Scrobbling Integration: Optionally integrate Tempus with Last.fm or Listenbrainz.org to scrobble your played tracks, gather music insights, and further personalize your music recommendations, if supported by your Subsonic server. - Scrobbling Integration: Optionally integrate Tempus with Last.fm or Listenbrainz.org to scrobble your played tracks, gather music insights, and further personalize your music recommendations, if supported by your Subsonic server.
- Podcasts and Radio: If your Subsonic server supports it, listen to podcasts and radio shows directly within Tempus, expanding your audio entertainment options. - Podcasts and Radio: If your Subsonic server supports it, listen to podcasts and radio shows directly within Tempus, expanding your audio entertainment options.
- Transcoding Support: Activate transcoding of tracks on your Subsonic server, allowing you to set a transcoding profile for optimized streaming directly from the app. This feature requires support from your Subsonic server. - Transcoding Support: Activate transcoding of tracks on your Subsonic server, allowing you to set a transcoding profile for optimized streaming directly from the app. This feature requires support from your Subsonic server.
@ -16,3 +15,5 @@ Features
- Equalizer: Option to use in app equalizer. - Equalizer: Option to use in app equalizer.
- Widget: New widget to keeping the basic controls on your screen at all times. - Widget: New widget to keeping the basic controls on your screen at all times.
- Available in 11 languages: Currently in Chinese, French, German, Italian, Korean, Polish, Portuguese, Russion, Spanish and Turkish - Available in 11 languages: Currently in Chinese, French, German, Italian, Korean, Polish, Portuguese, Russion, Spanish and Turkish
*Chromecast/Android Auto Not Supported: These features require google libraries and are only available in the github apk.*