Implemented star for tracks, albums and artists

This commit is contained in:
CappielloAntonio 2021-07-29 16:00:00 +02:00
parent 6f1046b137
commit f09d3b774d
14 changed files with 273 additions and 17 deletions

View file

@ -21,6 +21,7 @@ public class Album implements Parcelable {
public String artistName; public String artistName;
public String primary; public String primary;
public String blurHash; public String blurHash;
public boolean favorite;
public Album(AlbumID3 albumID3) { public Album(AlbumID3 albumID3) {
this.id = albumID3.getId(); this.id = albumID3.getId();
@ -29,6 +30,7 @@ public class Album implements Parcelable {
this.artistId = albumID3.getArtistId(); this.artistId = albumID3.getArtistId();
this.artistName = albumID3.getArtist(); this.artistName = albumID3.getArtist();
this.primary = albumID3.getCoverArtId(); this.primary = albumID3.getCoverArtId();
this.favorite = albumID3.getStarred() != null;
} }
public String getId() { public String getId() {
return id; return id;
@ -86,6 +88,14 @@ public class Album implements Parcelable {
this.blurHash = blurHash; this.blurHash = blurHash;
} }
public boolean isFavorite() {
return favorite;
}
public void setFavorite(boolean favorite) {
this.favorite = favorite;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;

View file

@ -31,6 +31,7 @@ public class Artist implements Parcelable {
public String backdrop; public String backdrop;
public String backdropBlurHash; public String backdropBlurHash;
public int albumCount; public int albumCount;
public boolean favorite;
public Artist(ArtistID3 artistID3) { public Artist(ArtistID3 artistID3) {
this.id = artistID3.getId(); this.id = artistID3.getId();
@ -38,6 +39,7 @@ public class Artist implements Parcelable {
this.primary = artistID3.getCoverArtId(); this.primary = artistID3.getCoverArtId();
this.backdrop = artistID3.getCoverArtId(); this.backdrop = artistID3.getCoverArtId();
this.albumCount = artistID3.getAlbumCount(); this.albumCount = artistID3.getAlbumCount();
this.favorite = artistID3.getStarred() != null;
} }
public Artist(ArtistWithAlbumsID3 artistWithAlbumsID3) { public Artist(ArtistWithAlbumsID3 artistWithAlbumsID3) {
@ -47,6 +49,7 @@ public class Artist implements Parcelable {
this.backdrop = artistWithAlbumsID3.getCoverArtId(); this.backdrop = artistWithAlbumsID3.getCoverArtId();
this.albumCount = artistWithAlbumsID3.getAlbumCount(); this.albumCount = artistWithAlbumsID3.getAlbumCount();
this.albums = MappingUtil.mapAlbum(artistWithAlbumsID3.getAlbums()); this.albums = MappingUtil.mapAlbum(artistWithAlbumsID3.getAlbums());
this.favorite = artistWithAlbumsID3.getStarred() != null;
} }
public Artist(String id, String name) { public Artist(String id, String name) {
@ -118,6 +121,14 @@ public class Artist implements Parcelable {
this.albums = albums; this.albums = albums;
} }
public boolean isFavorite() {
return favorite;
}
public void setFavorite(boolean favorite) {
this.favorite = favorite;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;

View file

@ -99,4 +99,55 @@ public class AlbumRepository {
return starredAlbums; return starredAlbums;
} }
public void star(String id) {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.star(null, id, null)
.enqueue(new Callback<SubsonicResponse>() {
@Override
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
}
@Override
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
}
});
}
public void unstar(String id) {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.unstar(null, id, null)
.enqueue(new Callback<SubsonicResponse>() {
@Override
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
}
@Override
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
}
});
}
public void setRating(String id, int star) {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.setRating(id, star)
.enqueue(new Callback<SubsonicResponse>() {
@Override
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
}
@Override
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
}
});
}
} }

View file

@ -103,6 +103,57 @@ public class ArtistRepository {
} }
} }
public void star(String id) {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.star(null, null, id)
.enqueue(new Callback<SubsonicResponse>() {
@Override
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
}
@Override
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
}
});
}
public void unstar(String id) {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.unstar(null, null, id)
.enqueue(new Callback<SubsonicResponse>() {
@Override
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
}
@Override
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
}
});
}
public void setRating(String id, int star) {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.setRating(id, star)
.enqueue(new Callback<SubsonicResponse>() {
@Override
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
}
@Override
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
}
});
}
private void addToMutableLiveData(MutableLiveData<List<Artist>> liveData, Artist artist) { private void addToMutableLiveData(MutableLiveData<List<Artist>> liveData, Artist artist) {
List<Artist> liveArtists = liveData.getValue(); List<Artist> liveArtists = liveData.getValue();
liveArtists.add(artist); liveArtists.add(artist);

View file

@ -117,4 +117,55 @@ public class SongRepository {
} }
}); });
} }
public void star(String id) {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.star(id, null, null)
.enqueue(new Callback<SubsonicResponse>() {
@Override
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
}
@Override
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
}
});
}
public void unstar(String id) {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.unstar(id, null, null)
.enqueue(new Callback<SubsonicResponse>() {
@Override
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
}
@Override
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
}
});
}
public void setRating(String id, int star) {
App.getSubsonicClientInstance(application, false)
.getMediaAnnotationClient()
.setRating(id, star)
.enqueue(new Callback<SubsonicResponse>() {
@Override
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
}
@Override
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
}
});
}
} }

View file

@ -32,14 +32,14 @@ public class MediaAnnotationClient {
this.mediaAnnotationService = retrofit.create(MediaAnnotationService.class); this.mediaAnnotationService = retrofit.create(MediaAnnotationService.class);
} }
public Call<SubsonicResponse> star(String id) { public Call<SubsonicResponse> star(String id, String albumId, String artistId) {
Log.d(TAG, "star()"); Log.d(TAG, "star()");
return mediaAnnotationService.star(subsonic.getParams(), id); return mediaAnnotationService.star(subsonic.getParams(), id, albumId, artistId);
} }
public Call<SubsonicResponse> unstar(String id) { public Call<SubsonicResponse> unstar(String id, String albumId, String artistId) {
Log.d(TAG, "unstar()"); Log.d(TAG, "unstar()");
return mediaAnnotationService.unstar(subsonic.getParams(), id); return mediaAnnotationService.unstar(subsonic.getParams(), id, albumId, artistId);
} }
public Call<SubsonicResponse> setRating(String id, int star) { public Call<SubsonicResponse> setRating(String id, int star) {

View file

@ -11,12 +11,12 @@ import retrofit2.http.QueryMap;
public interface MediaAnnotationService { public interface MediaAnnotationService {
@GET("star") @GET("star")
Call<SubsonicResponse> star(@QueryMap Map<String, String> params, @Query("id") String id); Call<SubsonicResponse> star(@QueryMap Map<String, String> params, @Query("id") String id, @Query("albumId") String albumId, @Query("artistId") String artistId);
@GET("stream") @GET("unstar")
Call<SubsonicResponse> unstar(@QueryMap Map<String, String> params, @Query("id") String id); Call<SubsonicResponse> unstar(@QueryMap Map<String, String> params, @Query("id") String id, @Query("albumId") String albumId, @Query("artistId") String artistId);
@GET("stream") @GET("setRating")
Call<SubsonicResponse> setRating(@QueryMap Map<String, String> params, @Query("id") String id, @Query("star") int star); Call<SubsonicResponse> setRating(@QueryMap Map<String, String> params, @Query("id") String id, @Query("star") int star);
@GET("scrobble") @GET("scrobble")

View file

@ -8,6 +8,7 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.ToggleButton;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@ -43,6 +44,7 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements
private ImageView coverAlbum; private ImageView coverAlbum;
private TextView titleAlbum; private TextView titleAlbum;
private TextView artistAlbum; private TextView artistAlbum;
private ToggleButton favoriteToggle;
private TextView playRadio; private TextView playRadio;
private TextView playRandom; private TextView playRandom;
@ -83,6 +85,13 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements
artistAlbum = view.findViewById(R.id.album_artist_text_view); artistAlbum = view.findViewById(R.id.album_artist_text_view);
artistAlbum.setText(albumBottomSheetViewModel.getAlbum().getArtistName()); artistAlbum.setText(albumBottomSheetViewModel.getAlbum().getArtistName());
favoriteToggle = view.findViewById(R.id.button_favorite);
favoriteToggle.setChecked(albumBottomSheetViewModel.getAlbum().isFavorite());
favoriteToggle.setOnClickListener(v -> {
albumBottomSheetViewModel.setFavorite();
dismissBottomSheet();
});
playRadio = view.findViewById(R.id.play_radio_text_view); playRadio = view.findViewById(R.id.play_radio_text_view);
playRadio.setOnClickListener(v -> { playRadio.setOnClickListener(v -> {
SyncUtil.getInstantMix(requireContext(), new MediaCallback() { SyncUtil.getInstantMix(requireContext(), new MediaCallback() {

View file

@ -8,6 +8,7 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.ToggleButton;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@ -39,6 +40,7 @@ public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implement
private ImageView coverArtist; private ImageView coverArtist;
private TextView nameArtist; private TextView nameArtist;
private ToggleButton favoriteToggle;
private TextView playRadio; private TextView playRadio;
private TextView playRandom; private TextView playRandom;
@ -71,6 +73,13 @@ public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implement
nameArtist.setText(artistBottomSheetViewModel.getArtist().getName()); nameArtist.setText(artistBottomSheetViewModel.getArtist().getName());
nameArtist.setSelected(true); nameArtist.setSelected(true);
favoriteToggle = view.findViewById(R.id.button_favorite);
favoriteToggle.setChecked(artistBottomSheetViewModel.getArtist().isFavorite());
favoriteToggle.setOnClickListener(v -> {
artistBottomSheetViewModel.setFavorite();
dismissBottomSheet();
});
playRadio = view.findViewById(R.id.play_radio_text_view); playRadio = view.findViewById(R.id.play_radio_text_view);
playRadio.setOnClickListener(v -> { playRadio.setOnClickListener(v -> {
SyncUtil.getInstantMix(requireContext(), new MediaCallback() { SyncUtil.getInstantMix(requireContext(), new MediaCallback() {

View file

@ -32,4 +32,14 @@ public class AlbumBottomSheetViewModel extends AndroidViewModel {
// return artistRepository.getArtistByID(album.getArtistId()); // return artistRepository.getArtistByID(album.getArtistId());
return null; return null;
} }
public void setFavorite() {
if (album.isFavorite()) {
artistRepository.unstar(album.getId());
album.setFavorite(false);
} else {
artistRepository.star(album.getId());
album.setFavorite(true);
}
}
} }

View file

@ -6,12 +6,18 @@ import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.AndroidViewModel;
import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.repository.AlbumRepository;
import com.cappielloantonio.play.repository.ArtistRepository;
public class ArtistBottomSheetViewModel extends AndroidViewModel { public class ArtistBottomSheetViewModel extends AndroidViewModel {
private AlbumRepository albumRepository;
private Artist artist; private Artist artist;
public ArtistBottomSheetViewModel(@NonNull Application application) { public ArtistBottomSheetViewModel(@NonNull Application application) {
super(application); super(application);
albumRepository = new AlbumRepository(application);
} }
public Artist getArtist() { public Artist getArtist() {
@ -21,4 +27,14 @@ public class ArtistBottomSheetViewModel extends AndroidViewModel {
public void setArtist(Artist artist) { public void setArtist(Artist artist) {
this.artist = artist; this.artist = artist;
} }
public void setFavorite() {
if (artist.isFavorite()) {
albumRepository.unstar(artist.getId());
artist.setFavorite(false);
} else {
albumRepository.star(artist.getId());
artist.setFavorite(true);
}
}
} }

View file

@ -36,8 +36,13 @@ public class SongBottomSheetViewModel extends AndroidViewModel {
} }
public void setFavorite() { public void setFavorite() {
song.setFavorite(!song.isFavorite()); if (song.isFavorite()) {
// songRepository.setFavoriteStatus(song); songRepository.unstar(song.getId());
song.setFavorite(false);
} else {
songRepository.star(song.getId());
song.setFavorite(true);
}
} }
public Album getAlbum() { public Album getAlbum() {

View file

@ -23,6 +23,22 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<ToggleButton
android:id="@+id/button_favorite"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/button_favorite_selector"
android:checked="false"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:gravity="center_vertical"
android:text=""
android:textOff=""
android:textOn=""
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/album_title_text_view" android:id="@+id/album_title_text_view"
android:layout_width="0dp" android:layout_width="0dp"
@ -41,7 +57,7 @@
android:textColor="@color/titleTextColor" android:textColor="@color/titleTextColor"
android:textSize="14sp" android:textSize="14sp"
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toStartOf="@id/button_favorite"
app:layout_constraintStart_toEndOf="@+id/album_cover_image_view" app:layout_constraintStart_toEndOf="@+id/album_cover_image_view"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -55,7 +71,7 @@
android:text="@string/label_placeholder" android:text="@string/label_placeholder"
android:textColor="@color/subtitleTextColor" android:textColor="@color/subtitleTextColor"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toStartOf="@id/button_favorite"
app:layout_constraintStart_toEndOf="@+id/album_cover_image_view" app:layout_constraintStart_toEndOf="@+id/album_cover_image_view"
app:layout_constraintTop_toBottomOf="@+id/album_title_text_view" /> app:layout_constraintTop_toBottomOf="@+id/album_title_text_view" />

View file

@ -9,9 +9,10 @@
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingStart="20dp" android:layout_marginStart="20dp"
android:paddingTop="12dp" android:layout_marginTop="12dp"
android:paddingEnd="20dp"> android:layout_marginEnd="12dp"
android:clipChildren="false">
<!-- Header --> <!-- Header -->
<ImageView <ImageView
@ -23,10 +24,27 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<ToggleButton
android:id="@+id/button_favorite"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/button_favorite_selector"
android:checked="false"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:gravity="center_vertical"
android:text=""
android:textOff=""
android:textOn=""
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/song_title_text_view" android:id="@+id/song_title_text_view"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ellipsize="marquee" android:ellipsize="marquee"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"
@ -40,11 +58,10 @@
android:textColor="@color/titleTextColor" android:textColor="@color/titleTextColor"
android:textSize="14sp" android:textSize="14sp"
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@id/button_favorite"
app:layout_constraintStart_toEndOf="@+id/artist_cover_image_view" app:layout_constraintStart_toEndOf="@+id/artist_cover_image_view"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout <LinearLayout