17 Commits
3.5.2 ... 3.5.4

Author SHA1 Message Date
antonio
8f6e775ca9 gradle: bump up code version 2023-08-30 17:53:44 +02:00
antonio
bad0fa6c23 fix: fixed a bug in the paginated song lists 2023-08-30 17:52:44 +02:00
antonio
d4caa6f209 build: dependencies update 2023-08-29 08:03:47 +02:00
antonio
723bdf9771 clean: code cleanup 2023-08-28 12:26:04 +02:00
antonio
49fbd85bb4 clean: code cleanup 2023-08-28 12:25:36 +02:00
CappielloAntonio
f040fbf0cf Merge pull request #50 from GallowsDove/main
feat: show albums instead of the artist in artist's top songs
2023-08-28 12:17:54 +02:00
antonio
efb2213ab7 fix: files without embedded cover art now display the image in the music player notification 2023-08-28 12:15:40 +02:00
GallowsDove
742ac6b17d feat: show albums instead of the artist in artist's top songs. 2023-08-28 11:28:59 +02:00
antonio
ae7761cb96 fix: null checking 2023-08-28 10:51:16 +02:00
antonio
c977982d64 gradle: bump up code version 2023-08-25 15:38:05 +02:00
antonio
28fc3dca36 fix: set initial visibility of the grid to "Gone" and make it appear once the elements are successfully loaded 2023-08-25 15:36:55 +02:00
antonio
f1cf65a371 fix: redefined proguard rules to make Retrofit work for everyone 2023-08-25 15:28:47 +02:00
antonio
beb1d29e8f fix: delayed grid display until server connectivity is confirmed 2023-08-25 15:27:39 +02:00
antonio
1eda7cef9e fix: fix a crash when clicking the dot menu of an empty playlist 2023-08-25 12:32:24 +02:00
antonio
1af92ad949 fix: now refreshing playlist view every time library is visited 2023-08-25 12:23:26 +02:00
antonio
3fc9b35fe4 fix: a callback on playlist editor dialog closing tells me when to refresh the playlist view 2023-08-25 12:22:43 +02:00
antonio
56b48dbd4d fix: fixed race condition issue in playlist update 2023-08-25 12:20:49 +02:00
20 changed files with 106 additions and 54 deletions

View File

@@ -28,8 +28,8 @@ android {
tempo { tempo {
dimension "default" dimension "default"
applicationId 'com.cappielloantonio.tempo' applicationId 'com.cappielloantonio.tempo'
versionCode 17 versionCode 19
versionName '3.5.2' versionName '3.5.4'
} }
notquitemy { notquitemy {
@@ -72,8 +72,8 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0' implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.0' implementation 'androidx.navigation:navigation-fragment-ktx:2.7.1'
implementation 'androidx.navigation:navigation-ui-ktx:2.7.0' implementation 'androidx.navigation:navigation-ui-ktx:2.7.1'
implementation 'androidx.recyclerview:recyclerview:1.3.1' implementation 'androidx.recyclerview:recyclerview:1.3.1'
implementation 'androidx.room:room-runtime:2.5.2' implementation 'androidx.room:room-runtime:2.5.2'
implementation 'androidx.core:core-splashscreen:1.0.1' implementation 'androidx.core:core-splashscreen:1.0.1'

View File

@@ -22,3 +22,4 @@
-keepattributes SourceFile, LineNumberTable -keepattributes SourceFile, LineNumberTable
-keep public class * extends java.lang.Exception -keep public class * extends java.lang.Exception
-keep class retrofit2.** { *; }

View File

@@ -0,0 +1,8 @@
package com.cappielloantonio.tempo.interfaces;
import androidx.annotation.Keep;
@Keep
public interface PlaylistCallback {
default void onDismiss() {}
}

View File

@@ -105,7 +105,9 @@ public class AlbumRepository {
List<Child> tracks = new ArrayList<>(); List<Child> tracks = new ArrayList<>();
if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getAlbum() != null) { if (response.isSuccessful() && response.body() != null && response.body().getSubsonicResponse().getAlbum() != null) {
tracks.addAll(response.body().getSubsonicResponse().getAlbum().getSongs()); if (response.body().getSubsonicResponse().getAlbum().getSongs() != null) {
tracks.addAll(response.body().getSubsonicResponse().getAlbum().getSongs());
}
} }
albumTracks.setValue(tracks); albumTracks.setValue(tracks);

View File

@@ -95,12 +95,29 @@ public class PlaylistRepository {
.enqueue(new Callback<ApiResponse>() { .enqueue(new Callback<ApiResponse>() {
@Override @Override
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) { public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
Log.d("PLAYLIST", response.toString()); Log.d("createPlaylist", "onResponse: ");
} }
@Override @Override
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
Log.d("PLAYLIST", t.toString());
}
});
}
public void updatePlaylist(String playlistId, String name, ArrayList<String> songsId) {
App.getSubsonicClientInstance(false)
.getPlaylistClient()
.deletePlaylist(playlistId)
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
createPlaylist(null, name, songsId);
}
@Override
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
} }
}); });
} }

View File

@@ -25,13 +25,15 @@ import java.util.List;
@UnstableApi @UnstableApi
public class SongHorizontalAdapter extends RecyclerView.Adapter<SongHorizontalAdapter.ViewHolder> { public class SongHorizontalAdapter extends RecyclerView.Adapter<SongHorizontalAdapter.ViewHolder> {
private final ClickCallback click; private final ClickCallback click;
private final boolean isCoverVisible; private final boolean showCoverArt;
private final boolean showAlbum;
private List<Child> songs; private List<Child> songs;
public SongHorizontalAdapter(ClickCallback click, boolean isCoverVisible) { public SongHorizontalAdapter(ClickCallback click, boolean showCoverArt, boolean showAlbum) {
this.click = click; this.click = click;
this.isCoverVisible = isCoverVisible; this.showCoverArt = showCoverArt;
this.showAlbum = showAlbum;
this.songs = Collections.emptyList(); this.songs = Collections.emptyList();
} }
@@ -47,7 +49,7 @@ public class SongHorizontalAdapter extends RecyclerView.Adapter<SongHorizontalAd
Child song = songs.get(position); Child song = songs.get(position);
holder.item.searchResultSongTitleTextView.setText(MusicUtil.getReadableString(song.getTitle())); holder.item.searchResultSongTitleTextView.setText(MusicUtil.getReadableString(song.getTitle()));
holder.item.searchResultSongSubtitleTextView.setText(holder.itemView.getContext().getString(R.string.song_subtitle_formatter, MusicUtil.getReadableString(song.getArtist()), MusicUtil.getReadableDurationString(song.getDuration() != null ? song.getDuration() : 0, false))); holder.item.searchResultSongSubtitleTextView.setText(holder.itemView.getContext().getString(R.string.song_subtitle_formatter, MusicUtil.getReadableString(this.showAlbum ? song.getAlbum() : song.getArtist()), MusicUtil.getReadableDurationString(song.getDuration() != null ? song.getDuration() : 0, false)));
holder.item.trackNumberTextView.setText(MusicUtil.getReadableTrackNumber(holder.itemView.getContext(), song.getTrack())); holder.item.trackNumberTextView.setText(MusicUtil.getReadableTrackNumber(holder.itemView.getContext(), song.getTrack()));
if (DownloadUtil.getDownloadTracker(holder.itemView.getContext()).isDownloaded(song.getId())) { if (DownloadUtil.getDownloadTracker(holder.itemView.getContext()).isDownloaded(song.getId())) {
@@ -56,16 +58,16 @@ public class SongHorizontalAdapter extends RecyclerView.Adapter<SongHorizontalAd
holder.item.searchResultDowanloadIndicatorImageView.setVisibility(View.GONE); holder.item.searchResultDowanloadIndicatorImageView.setVisibility(View.GONE);
} }
if (isCoverVisible) CustomGlideRequest.Builder if (showCoverArt) CustomGlideRequest.Builder
.from(holder.itemView.getContext(), song.getCoverArtId()) .from(holder.itemView.getContext(), song.getCoverArtId())
.build() .build()
.into(holder.item.songCoverImageView); .into(holder.item.songCoverImageView);
if (isCoverVisible) holder.item.trackNumberTextView.setVisibility(View.INVISIBLE); if (showCoverArt) holder.item.trackNumberTextView.setVisibility(View.INVISIBLE);
if (!isCoverVisible) holder.item.songCoverImageView.setVisibility(View.INVISIBLE); if (!showCoverArt) holder.item.songCoverImageView.setVisibility(View.INVISIBLE);
if (!isCoverVisible && (position > 0 && songs.get(position - 1) != null && songs.get(position - 1).getDiscNumber() != null && songs.get(position).getDiscNumber() != null && songs.get(position - 1).getDiscNumber() < songs.get(position).getDiscNumber())) { if (!showCoverArt && (position > 0 && songs.get(position - 1) != null && songs.get(position - 1).getDiscNumber() != null && songs.get(position).getDiscNumber() != null && songs.get(position - 1).getDiscNumber() < songs.get(position).getDiscNumber())) {
holder.item.differentDiskDivider.setVisibility(View.VISIBLE); holder.item.differentDiskDivider.setVisibility(View.VISIBLE);
} }
} }

View File

@@ -67,7 +67,7 @@ public class PlaylistChooserDialog extends DialogFragment implements ClickCallba
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putParcelable(Constants.TRACK_OBJECT, playlistChooserViewModel.getSongToAdd()); bundle.putParcelable(Constants.TRACK_OBJECT, playlistChooserViewModel.getSongToAdd());
PlaylistEditorDialog dialog = new PlaylistEditorDialog(); PlaylistEditorDialog dialog = new PlaylistEditorDialog(null);
dialog.setArguments(bundle); dialog.setArguments(bundle);
dialog.show(requireActivity().getSupportFragmentManager(), null); dialog.show(requireActivity().getSupportFragmentManager(), null);

View File

@@ -14,6 +14,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.cappielloantonio.tempo.R; import com.cappielloantonio.tempo.R;
import com.cappielloantonio.tempo.databinding.DialogPlaylistEditorBinding; import com.cappielloantonio.tempo.databinding.DialogPlaylistEditorBinding;
import com.cappielloantonio.tempo.interfaces.PlaylistCallback;
import com.cappielloantonio.tempo.ui.adapter.PlaylistDialogSongHorizontalAdapter; import com.cappielloantonio.tempo.ui.adapter.PlaylistDialogSongHorizontalAdapter;
import com.cappielloantonio.tempo.util.Constants; import com.cappielloantonio.tempo.util.Constants;
import com.cappielloantonio.tempo.util.MusicUtil; import com.cappielloantonio.tempo.util.MusicUtil;
@@ -25,10 +26,15 @@ import java.util.Objects;
public class PlaylistEditorDialog extends DialogFragment { public class PlaylistEditorDialog extends DialogFragment {
private DialogPlaylistEditorBinding bind; private DialogPlaylistEditorBinding bind;
private PlaylistEditorViewModel playlistEditorViewModel; private PlaylistEditorViewModel playlistEditorViewModel;
private PlaylistCallback playlistCallback;
private String playlistName; private String playlistName;
private PlaylistDialogSongHorizontalAdapter playlistDialogSongHorizontalAdapter; private PlaylistDialogSongHorizontalAdapter playlistDialogSongHorizontalAdapter;
public PlaylistEditorDialog(PlaylistCallback playlistCallback) {
this.playlistCallback = playlistCallback;
}
@NonNull @NonNull
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
@@ -85,13 +91,13 @@ public class PlaylistEditorDialog extends DialogFragment {
playlistEditorViewModel.updatePlaylist(playlistName); playlistEditorViewModel.updatePlaylist(playlistName);
} }
Objects.requireNonNull(getDialog()).dismiss(); dialogDismiss();
} }
}); });
((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(v -> { ((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(v -> {
playlistEditorViewModel.deletePlaylist(); playlistEditorViewModel.deletePlaylist();
Objects.requireNonNull(getDialog()).dismiss(); dialogDismiss();
}); });
} }
@@ -102,7 +108,9 @@ public class PlaylistEditorDialog extends DialogFragment {
playlistDialogSongHorizontalAdapter = new PlaylistDialogSongHorizontalAdapter(); playlistDialogSongHorizontalAdapter = new PlaylistDialogSongHorizontalAdapter();
bind.playlistSongRecyclerView.setAdapter(playlistDialogSongHorizontalAdapter); bind.playlistSongRecyclerView.setAdapter(playlistDialogSongHorizontalAdapter);
playlistEditorViewModel.getPlaylistSongLiveList().observe(requireActivity(), songs -> playlistDialogSongHorizontalAdapter.setItems(songs)); playlistEditorViewModel.getPlaylistSongLiveList().observe(requireActivity(), songs -> {
if (songs != null) playlistDialogSongHorizontalAdapter.setItems(songs);
});
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT) { new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT) {
int originalPosition = -1; int originalPosition = -1;
@@ -157,4 +165,9 @@ public class PlaylistEditorDialog extends DialogFragment {
return true; return true;
} }
private void dialogDismiss() {
Objects.requireNonNull(getDialog()).dismiss();
playlistCallback.onDismiss();
}
} }

View File

@@ -181,7 +181,7 @@ public class AlbumPageFragment extends Fragment implements ClickCallback {
bind.songRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.songRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
bind.songRecyclerView.setHasFixedSize(true); bind.songRecyclerView.setHasFixedSize(true);
songHorizontalAdapter = new SongHorizontalAdapter(this, false); songHorizontalAdapter = new SongHorizontalAdapter(this, false, false);
bind.songRecyclerView.setAdapter(songHorizontalAdapter); bind.songRecyclerView.setAdapter(songHorizontalAdapter);
albumPageViewModel.getAlbumSongLiveList().observe(getViewLifecycleOwner(), songs -> songHorizontalAdapter.setItems(songs)); albumPageViewModel.getAlbumSongLiveList().observe(getViewLifecycleOwner(), songs -> songHorizontalAdapter.setItems(songs));

View File

@@ -164,7 +164,7 @@ public class ArtistPageFragment extends Fragment implements ClickCallback {
private void initTopSongsView() { private void initTopSongsView() {
bind.mostStreamedSongRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.mostStreamedSongRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
songHorizontalAdapter = new SongHorizontalAdapter(this, true); songHorizontalAdapter = new SongHorizontalAdapter(this, true, true);
bind.mostStreamedSongRecyclerView.setAdapter(songHorizontalAdapter); bind.mostStreamedSongRecyclerView.setAdapter(songHorizontalAdapter);
artistPageViewModel.getArtistTopSongList().observe(getViewLifecycleOwner(), songs -> { artistPageViewModel.getArtistTopSongList().observe(getViewLifecycleOwner(), songs -> {
if (songs == null) { if (songs == null) {

View File

@@ -5,7 +5,6 @@ import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@@ -393,7 +392,7 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
private void initStarredTracksView() { private void initStarredTracksView() {
bind.starredTracksRecyclerView.setHasFixedSize(true); bind.starredTracksRecyclerView.setHasFixedSize(true);
starredSongAdapter = new SongHorizontalAdapter(this, true); starredSongAdapter = new SongHorizontalAdapter(this, true, false);
bind.starredTracksRecyclerView.setAdapter(starredSongAdapter); bind.starredTracksRecyclerView.setAdapter(starredSongAdapter);
homeViewModel.getStarredTracks(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> { homeViewModel.getStarredTracks(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> {
if (songs == null) { if (songs == null) {
@@ -619,25 +618,6 @@ public class HomeTabMusicFragment extends Fragment implements ClickCallback {
}); });
} }
public void reorder() {
if (bind != null) {
// bind.homeLinearLayoutContainer.removeAllViews();
// bind.homeLinearLayoutContainer.addView(bind.homeDiscoverSector);
// bind.homeLinearLayoutContainer.addView(bind.homeSimilarTracksSector);
// bind.homeLinearLayoutContainer.addView(bind.homeRadioArtistSector);
// bind.homeLinearLayoutContainer.addView(bind.homeGridTracksSector);
// bind.homeLinearLayoutContainer.addView(bind.starredTracksSector);
// bind.homeLinearLayoutContainer.addView(bind.starredAlbumsSector);
// bind.homeLinearLayoutContainer.addView(bind.starredArtistsSector);
// bind.homeLinearLayoutContainer.addView(bind.homeRecentlyAddedAlbumsSector);
// bind.homeLinearLayoutContainer.addView(bind.homeFlashbackSector);
// bind.homeLinearLayoutContainer.addView(bind.homeMostPlayedAlbumsSector);
// bind.homeLinearLayoutContainer.addView(bind.homeRecentlyPlayedAlbumsSector);
}
}
private void initializeMediaBrowser() { private void initializeMediaBrowser() {
mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync(); mediaBrowserListenableFuture = new MediaBrowser.Builder(requireContext(), new SessionToken(requireContext(), new ComponentName(requireContext(), MediaService.class))).buildAsync();
} }

View File

@@ -1,6 +1,7 @@
package com.cappielloantonio.tempo.ui.fragment; package com.cappielloantonio.tempo.ui.fragment;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -18,6 +19,7 @@ import com.cappielloantonio.tempo.R;
import com.cappielloantonio.tempo.databinding.FragmentLibraryBinding; import com.cappielloantonio.tempo.databinding.FragmentLibraryBinding;
import com.cappielloantonio.tempo.helper.recyclerview.CustomLinearSnapHelper; import com.cappielloantonio.tempo.helper.recyclerview.CustomLinearSnapHelper;
import com.cappielloantonio.tempo.interfaces.ClickCallback; import com.cappielloantonio.tempo.interfaces.ClickCallback;
import com.cappielloantonio.tempo.interfaces.PlaylistCallback;
import com.cappielloantonio.tempo.ui.activity.MainActivity; import com.cappielloantonio.tempo.ui.activity.MainActivity;
import com.cappielloantonio.tempo.ui.adapter.AlbumAdapter; import com.cappielloantonio.tempo.ui.adapter.AlbumAdapter;
import com.cappielloantonio.tempo.ui.adapter.ArtistAdapter; import com.cappielloantonio.tempo.ui.adapter.ArtistAdapter;
@@ -71,7 +73,7 @@ public class LibraryFragment extends Fragment implements ClickCallback {
initAlbumView(); initAlbumView();
initArtistView(); initArtistView();
initGenreView(); initGenreView();
initPlaylistSlideView(); initPlaylistView();
} }
@Override @Override
@@ -80,6 +82,12 @@ public class LibraryFragment extends Fragment implements ClickCallback {
activity.setBottomNavigationBarVisibility(true); activity.setBottomNavigationBarVisibility(true);
} }
@Override
public void onResume() {
super.onResume();
refreshPlaylistView();
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
@@ -222,7 +230,7 @@ public class LibraryFragment extends Fragment implements ClickCallback {
genreSnapHelper.attachToRecyclerView(bind.genreRecyclerView); genreSnapHelper.attachToRecyclerView(bind.genreRecyclerView);
} }
private void initPlaylistSlideView() { private void initPlaylistView() {
bind.playlistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.playlistRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
bind.playlistRecyclerView.setHasFixedSize(true); bind.playlistRecyclerView.setHasFixedSize(true);
@@ -244,6 +252,12 @@ public class LibraryFragment extends Fragment implements ClickCallback {
}); });
} }
private void refreshPlaylistView() {
final Handler handler = new Handler();
final Runnable runnable = () -> libraryViewModel.refreshPlaylistSample(getViewLifecycleOwner());
handler.postDelayed(runnable, 100);
}
@Override @Override
public void onAlbumClick(Bundle bundle) { public void onAlbumClick(Bundle bundle) {
Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle); Navigation.findNavController(requireView()).navigate(R.id.albumPageFragment, bundle);
@@ -276,7 +290,13 @@ public class LibraryFragment extends Fragment implements ClickCallback {
@Override @Override
public void onPlaylistLongClick(Bundle bundle) { public void onPlaylistLongClick(Bundle bundle) {
PlaylistEditorDialog dialog = new PlaylistEditorDialog(); PlaylistEditorDialog dialog = new PlaylistEditorDialog(new PlaylistCallback() {
@Override
public void onDismiss() {
refreshPlaylistView();
}
});
dialog.setArguments(bundle); dialog.setArguments(bundle);
dialog.show(activity.getSupportFragmentManager(), null); dialog.show(activity.getSupportFragmentManager(), null);
} }

View File

@@ -178,7 +178,7 @@ public class PlaylistCatalogueFragment extends Fragment implements ClickCallback
@Override @Override
public void onPlaylistLongClick(Bundle bundle) { public void onPlaylistLongClick(Bundle bundle) {
PlaylistEditorDialog dialog = new PlaylistEditorDialog(); PlaylistEditorDialog dialog = new PlaylistEditorDialog(null);
dialog.setArguments(bundle); dialog.setArguments(bundle);
dialog.show(activity.getSupportFragmentManager(), null); dialog.show(activity.getSupportFragmentManager(), null);
hideKeyboard(requireView()); hideKeyboard(requireView());

View File

@@ -200,7 +200,7 @@ public class PlaylistPageFragment extends Fragment implements ClickCallback {
bind.songRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.songRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
bind.songRecyclerView.setHasFixedSize(true); bind.songRecyclerView.setHasFixedSize(true);
songHorizontalAdapter = new SongHorizontalAdapter(this, true); songHorizontalAdapter = new SongHorizontalAdapter(this, true, false);
bind.songRecyclerView.setAdapter(songHorizontalAdapter); bind.songRecyclerView.setAdapter(songHorizontalAdapter);
playlistPageViewModel.getPlaylistSongLiveList().observe(getViewLifecycleOwner(), songs -> songHorizontalAdapter.setItems(songs)); playlistPageViewModel.getPlaylistSongLiveList().observe(getViewLifecycleOwner(), songs -> songHorizontalAdapter.setItems(songs));

View File

@@ -112,7 +112,7 @@ public class SearchFragment extends Fragment implements ClickCallback {
bind.searchResultTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.searchResultTracksRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
bind.searchResultTracksRecyclerView.setHasFixedSize(true); bind.searchResultTracksRecyclerView.setHasFixedSize(true);
songHorizontalAdapter = new SongHorizontalAdapter(this, true); songHorizontalAdapter = new SongHorizontalAdapter(this, true, false);
bind.searchResultTracksRecyclerView.setAdapter(songHorizontalAdapter); bind.searchResultTracksRecyclerView.setAdapter(songHorizontalAdapter);
} }

View File

@@ -166,7 +166,7 @@ public class SongListPageFragment extends Fragment implements ClickCallback {
bind.songListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); bind.songListRecyclerView.setLayoutManager(new LinearLayoutManager(requireContext()));
bind.songListRecyclerView.setHasFixedSize(true); bind.songListRecyclerView.setHasFixedSize(true);
songHorizontalAdapter = new SongHorizontalAdapter(this, true); songHorizontalAdapter = new SongHorizontalAdapter(this, true, false);
bind.songListRecyclerView.setAdapter(songHorizontalAdapter); bind.songListRecyclerView.setAdapter(songHorizontalAdapter);
songListPageViewModel.getSongList().observe(getViewLifecycleOwner(), songs -> { songListPageViewModel.getSongList().observe(getViewLifecycleOwner(), songs -> {
isLoading = false; isLoading = false;

View File

@@ -10,6 +10,7 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import com.cappielloantonio.tempo.App; import com.cappielloantonio.tempo.App;
import com.cappielloantonio.tempo.glide.CustomGlideRequest;
import com.cappielloantonio.tempo.model.Download; import com.cappielloantonio.tempo.model.Download;
import com.cappielloantonio.tempo.repository.DownloadRepository; import com.cappielloantonio.tempo.repository.DownloadRepository;
import com.cappielloantonio.tempo.subsonic.models.Child; import com.cappielloantonio.tempo.subsonic.models.Child;
@@ -33,6 +34,7 @@ public class MappingUtil {
public static MediaItem mapMediaItem(Child media) { public static MediaItem mapMediaItem(Child media) {
Uri uri = getUri(media); Uri uri = getUri(media);
Uri artworkUri = Uri.parse(CustomGlideRequest.createUrl(media.getCoverArtId(), Preferences.getImageSize()));
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putString("id", media.getId()); bundle.putString("id", media.getId());
@@ -78,6 +80,7 @@ public class MappingUtil {
.setReleaseYear(media.getYear() != null ? media.getYear() : 0) .setReleaseYear(media.getYear() != null ? media.getYear() : 0)
.setAlbumTitle(MusicUtil.getReadableString(media.getAlbum())) .setAlbumTitle(MusicUtil.getReadableString(media.getAlbum()))
.setArtist(MusicUtil.getReadableString(media.getArtist())) .setArtist(MusicUtil.getReadableString(media.getArtist()))
.setArtworkUri(artworkUri)
.setExtras(bundle) .setExtras(bundle)
.build() .build()
) )
@@ -157,6 +160,7 @@ public class MappingUtil {
public static MediaItem mapMediaItem(PodcastEpisode podcastEpisode) { public static MediaItem mapMediaItem(PodcastEpisode podcastEpisode) {
Uri uri = getUri(podcastEpisode); Uri uri = getUri(podcastEpisode);
Uri artworkUri = Uri.parse(CustomGlideRequest.createUrl(podcastEpisode.getCoverArtId(), Preferences.getImageSize()));
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putString("id", podcastEpisode.getId()); bundle.putString("id", podcastEpisode.getId());
@@ -202,6 +206,7 @@ public class MappingUtil {
.setReleaseYear(podcastEpisode.getYear() != null ? podcastEpisode.getYear() : 0) .setReleaseYear(podcastEpisode.getYear() != null ? podcastEpisode.getYear() : 0)
.setAlbumTitle(MusicUtil.getReadableString(podcastEpisode.getAlbum())) .setAlbumTitle(MusicUtil.getReadableString(podcastEpisode.getAlbum()))
.setArtist(MusicUtil.getReadableString(podcastEpisode.getArtist())) .setArtist(MusicUtil.getReadableString(podcastEpisode.getArtist()))
.setArtworkUri(artworkUri)
.setExtras(bundle) .setExtras(bundle)
.build() .build()
) )

View File

@@ -37,8 +37,7 @@ public class PlaylistEditorViewModel extends AndroidViewModel {
} }
public void updatePlaylist(String name) { public void updatePlaylist(String name) {
playlistRepository.deletePlaylist(toEdit.getId()); playlistRepository.updatePlaylist(toEdit.getId(), name, getPlaylistSongIds());
playlistRepository.createPlaylist(toEdit.getId(), name, getPlaylistSongIds());
} }
public void deletePlaylist() { public void deletePlaylist() {

View File

@@ -71,7 +71,11 @@ public class SongListPageViewModel extends AndroidViewModel {
public void getSongsByPage(LifecycleOwner owner) { public void getSongsByPage(LifecycleOwner owner) {
switch (title) { switch (title) {
case Constants.MEDIA_BY_GENRE: case Constants.MEDIA_BY_GENRE:
int page = (songList.getValue() != null ? songList.getValue().size() : 0) / 100; int songCount = songList.getValue() != null ? songList.getValue().size() : 0;
if (songCount > 0 && songCount % 100 != 0) return;
int page = songCount / 100;
songRepository.getSongsByGenre(genre.getGenre(), page).observe(owner, children -> { songRepository.getSongsByGenre(genre.getGenre(), page).observe(owner, children -> {
if (children != null && !children.isEmpty()) { if (children != null && !children.isEmpty()) {
List<Child> currentMedia = songList.getValue(); List<Child> currentMedia = songList.getValue();

View File

@@ -296,7 +296,8 @@
android:id="@+id/home_grid_tracks_sector" android:id="@+id/home_grid_tracks_sector"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical"
android:visibility="gone">
<TextView <TextView
android:id="@+id/grid_tracks_pre_text_view" android:id="@+id/grid_tracks_pre_text_view"