diff --git a/.idea/misc.xml b/.idea/misc.xml
index 708be2f4..e826b7cf 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -30,6 +30,7 @@
+
diff --git a/app/src/main/java/com/cappielloantonio/play/model/Song.java b/app/src/main/java/com/cappielloantonio/play/model/Song.java
index d4fdff19..8ee95003 100644
--- a/app/src/main/java/com/cappielloantonio/play/model/Song.java
+++ b/app/src/main/java/com/cappielloantonio/play/model/Song.java
@@ -42,6 +42,7 @@ public class Song implements Parcelable {
private long added;
private int playCount;
private long lastPlay;
+ private int rating;
public Song() {
this.id = UUID.randomUUID().toString();
@@ -67,6 +68,7 @@ public class Song implements Parcelable {
this.added = child.getCreated().getTime();
this.playCount = 0;
this.lastPlay = 0;
+ this.rating = child.getUserRating() != null ? child.getUserRating() : 0;
}
public Song(Queue queue) {
@@ -251,14 +253,22 @@ public class Song implements Parcelable {
this.playCount = playCount;
}
+ public int getRating() {
+ return rating;
+ }
+
+ public void setRating(int rating) {
+ this.rating = rating;
+ }
+
/*
- Log.i(TAG, "increasePlayCount: " + isIncreased);
- * Incremento il numero di ascolti solo se ho ascoltato la canzone da più tempo di:
- * tempo dell'ultimo ascolto - (durata_canzone / 2)
- * Ritorno un booleano
- * Se vero, allora SongRepository scriverà nd DB l'incremento dell'ascolto
- * Se falso, SongRepository non scriverà nulla nel db
- */
+ Log.i(TAG, "increasePlayCount: " + isIncreased);
+ * Incremento il numero di ascolti solo se ho ascoltato la canzone da più tempo di:
+ * tempo dell'ultimo ascolto - (durata_canzone / 2)
+ * Ritorno un booleano
+ * Se vero, allora SongRepository scriverà nd DB l'incremento dell'ascolto
+ * Se falso, SongRepository non scriverà nulla nel db
+ */
public boolean nowPlaying() {
long startPlayTime = Instant.now().toEpochMilli();
diff --git a/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java
index 0bd913fd..f6d2a6a4 100644
--- a/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java
+++ b/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java
@@ -230,4 +230,27 @@ public class SongRepository {
return songsByGenre;
}
+
+ public MutableLiveData getSong(String id) {
+ MutableLiveData song = new MutableLiveData<>();
+
+ App.getSubsonicClientInstance(application, false)
+ .getBrowsingClient()
+ .getSong(id)
+ .enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.body().getStatus().getValue().equals(ResponseStatus.OK)) {
+ song.setValue(MappingUtil.mapSong(response.body().getSong()));
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+
+ }
+ });
+
+ return song;
+ }
}
diff --git a/app/src/main/java/com/cappielloantonio/play/subsonic/models/SubsonicResponse.java b/app/src/main/java/com/cappielloantonio/play/subsonic/models/SubsonicResponse.java
index a496a188..97754522 100644
--- a/app/src/main/java/com/cappielloantonio/play/subsonic/models/SubsonicResponse.java
+++ b/app/src/main/java/com/cappielloantonio/play/subsonic/models/SubsonicResponse.java
@@ -56,6 +56,7 @@ public class SubsonicResponse {
private NowPlaying nowPlaying;
private VideoInfo videoInfo;
private Videos videos;
+ @Element(name = "song")
private Child song;
@Element(name = "album")
private AlbumWithSongsID3 album;
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java
index 09680c86..8265e6d6 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java
@@ -29,6 +29,7 @@ import com.cappielloantonio.play.interfaces.MusicServiceEventListener;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.ui.activity.MainActivity;
+import com.cappielloantonio.play.ui.fragment.dialog.RatingDialog;
import com.cappielloantonio.play.util.MappingUtil;
import com.cappielloantonio.play.util.MusicUtil;
import com.cappielloantonio.play.util.PreferenceUtil;
@@ -212,6 +213,16 @@ public class PlayerBottomSheetFragment extends Fragment implements MusicServiceE
private void initFavoriteButtonClick() {
bind.playerBodyLayout.buttonFavorite.setOnClickListener(v -> playerBottomSheetViewModel.setFavorite());
+ bind.playerBodyLayout.buttonFavorite.setOnLongClickListener(v -> {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable("song_object", playerBottomSheetViewModel.getCurrentSong());
+
+ RatingDialog dialog = new RatingDialog();
+ dialog.setArguments(bundle);
+ dialog.show(requireActivity().getSupportFragmentManager(), null);
+
+ return true;
+ });
}
private void initMusicCommandButton() {
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java
index c3630015..86d17cd1 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java
@@ -26,6 +26,7 @@ import com.cappielloantonio.play.repository.AlbumRepository;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.ui.activity.MainActivity;
+import com.cappielloantonio.play.ui.fragment.dialog.RatingDialog;
import com.cappielloantonio.play.util.DownloadUtil;
import com.cappielloantonio.play.util.MusicUtil;
import com.cappielloantonio.play.viewmodel.AlbumBottomSheetViewModel;
@@ -93,6 +94,17 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements
albumBottomSheetViewModel.setFavorite();
dismissBottomSheet();
});
+ favoriteToggle.setOnLongClickListener(v -> {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable("album_object", album);
+
+ RatingDialog dialog = new RatingDialog();
+ dialog.setArguments(bundle);
+ dialog.show(requireActivity().getSupportFragmentManager(), null);
+
+ dismissBottomSheet();
+ return true;
+ });
playRadio = view.findViewById(R.id.play_radio_text_view);
playRadio.setOnClickListener(v -> {
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java
index b118d1dd..685e55dc 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/ArtistBottomSheetDialog.java
@@ -25,6 +25,7 @@ import com.cappielloantonio.play.repository.ArtistRepository;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.ui.activity.MainActivity;
+import com.cappielloantonio.play.ui.fragment.dialog.RatingDialog;
import com.cappielloantonio.play.util.MusicUtil;
import com.cappielloantonio.play.viewmodel.ArtistBottomSheetViewModel;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
@@ -82,6 +83,17 @@ public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implement
artistBottomSheetViewModel.setFavorite();
dismissBottomSheet();
});
+ favoriteToggle.setOnLongClickListener(v -> {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable("artist_object", artist);
+
+ RatingDialog dialog = new RatingDialog();
+ dialog.setArguments(bundle);
+ dialog.show(requireActivity().getSupportFragmentManager(), null);
+
+ dismissBottomSheet();
+ return true;
+ });
playRadio = view.findViewById(R.id.play_radio_text_view);
playRadio.setOnClickListener(v -> {
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java
index 9248b681..cdd87170 100644
--- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java
@@ -26,6 +26,7 @@ import com.cappielloantonio.play.repository.SongRepository;
import com.cappielloantonio.play.service.MusicPlayerRemote;
import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.ui.fragment.dialog.PlaylistChooserDialog;
+import com.cappielloantonio.play.ui.fragment.dialog.RatingDialog;
import com.cappielloantonio.play.ui.fragment.dialog.ServerSignupDialog;
import com.cappielloantonio.play.util.DownloadUtil;
import com.cappielloantonio.play.util.MusicUtil;
@@ -93,6 +94,17 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
songBottomSheetViewModel.setFavorite();
dismissBottomSheet();
});
+ favoriteToggle.setOnLongClickListener(v -> {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable("song_object", song);
+
+ RatingDialog dialog = new RatingDialog();
+ dialog.setArguments(bundle);
+ dialog.show(requireActivity().getSupportFragmentManager(), null);
+
+ dismissBottomSheet();
+ return true;
+ });
playRadio = view.findViewById(R.id.play_radio_text_view);
playRadio.setOnClickListener(v -> {
diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/dialog/RatingDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/dialog/RatingDialog.java
new file mode 100644
index 00000000..3342e9f4
--- /dev/null
+++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/dialog/RatingDialog.java
@@ -0,0 +1,82 @@
+package com.cappielloantonio.play.ui.fragment.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+
+import androidx.fragment.app.DialogFragment;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.cappielloantonio.play.R;
+import com.cappielloantonio.play.databinding.DialogRatingBinding;
+import com.cappielloantonio.play.ui.activity.MainActivity;
+import com.cappielloantonio.play.viewmodel.RatingViewModel;
+
+import java.util.Objects;
+
+public class RatingDialog extends DialogFragment {
+ private static final String TAG = "ServerSignupDialog";
+
+ private DialogRatingBinding bind;
+ private MainActivity activity;
+ private Context context;
+ private RatingViewModel ratingViewModel;
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ activity = (MainActivity) getActivity();
+ context = requireContext();
+
+ bind = DialogRatingBinding.inflate(LayoutInflater.from(requireContext()));
+ ratingViewModel = new ViewModelProvider(requireActivity()).get(RatingViewModel.class);
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppTheme_AlertDialog);
+
+ builder.setView(bind.getRoot())
+ .setTitle("Rate")
+ .setNegativeButton("Cancel", (dialog, id) -> dialog.cancel())
+ .setPositiveButton("Save", (dialog, id) -> {
+ ratingViewModel.rate((int) bind.ratingBar.getRating());
+ });
+
+ return builder.create();
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ setElementInfo();
+ setButtonColor();
+ setRating();
+ }
+
+ private void setElementInfo() {
+ if (getArguments() != null) {
+ if (getArguments().getParcelable("song_object") != null) {
+ ratingViewModel.setSong(getArguments().getParcelable("song_object"));
+ } else if (getArguments().getParcelable("album_object") != null) {
+ ratingViewModel.setAlbum(getArguments().getParcelable("album_object"));
+ } else if (getArguments().getParcelable("artist_object") != null) {
+ ratingViewModel.setArtist(getArguments().getParcelable("artist_object"));
+ }
+ }
+ }
+
+ private void setButtonColor() {
+ ((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getResources().getColor(R.color.colorAccent, null));
+ ((AlertDialog) Objects.requireNonNull(getDialog())).getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getResources().getColor(R.color.colorAccent, null));
+ }
+
+ private void setRating() {
+ if (ratingViewModel.getSong() != null) {
+ ratingViewModel.getLiveSong().observe(requireActivity(), song -> bind.ratingBar.setRating(song.getRating()));
+ } else if (ratingViewModel.getAlbum() != null) {
+ ratingViewModel.getLiveAlbum().observe(requireActivity(), album -> bind.ratingBar.setRating(/*album.getRating()*/ 0));
+ } else if (ratingViewModel.getArtist() != null) {
+ ratingViewModel.getLiveArtist().observe(requireActivity(), artist -> bind.ratingBar.setRating(/*artist.getRating()*/ 0));
+ }
+ }
+}
diff --git a/app/src/main/java/com/cappielloantonio/play/util/MappingUtil.java b/app/src/main/java/com/cappielloantonio/play/util/MappingUtil.java
index a22f594a..c3858330 100644
--- a/app/src/main/java/com/cappielloantonio/play/util/MappingUtil.java
+++ b/app/src/main/java/com/cappielloantonio/play/util/MappingUtil.java
@@ -30,6 +30,10 @@ public class MappingUtil {
return songs;
}
+ public static Song mapSong(Child child) {
+ return new Song(child);
+ }
+
public static ArrayList mapAlbum(List albumID3List) {
ArrayList albums = new ArrayList();
diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java
index cfb884d1..ad48295c 100644
--- a/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java
+++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/PlayerBottomSheetViewModel.java
@@ -35,6 +35,11 @@ public class PlayerBottomSheetViewModel extends AndroidViewModel {
return queueSong;
}
+ public Song getCurrentSong() {
+ return MusicPlayerRemote.getCurrentSong();
+ }
+
+
public void setFavorite() {
Song song = MusicPlayerRemote.getCurrentSong();
diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/RatingViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/RatingViewModel.java
new file mode 100644
index 00000000..5920e63d
--- /dev/null
+++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/RatingViewModel.java
@@ -0,0 +1,96 @@
+package com.cappielloantonio.play.viewmodel;
+
+import android.app.Application;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.AndroidViewModel;
+import androidx.lifecycle.LiveData;
+
+import com.cappielloantonio.play.model.Album;
+import com.cappielloantonio.play.model.Artist;
+import com.cappielloantonio.play.model.Song;
+import com.cappielloantonio.play.repository.AlbumRepository;
+import com.cappielloantonio.play.repository.ArtistRepository;
+import com.cappielloantonio.play.repository.SongRepository;
+
+public class RatingViewModel extends AndroidViewModel {
+ private SongRepository songRepository;
+ private AlbumRepository albumRepository;
+ private ArtistRepository artistRepository;
+
+ private Song song;
+ private Album album;
+ private Artist artist;
+
+ public RatingViewModel(@NonNull Application application) {
+ super(application);
+
+ songRepository = new SongRepository(application);
+ albumRepository = new AlbumRepository(application);
+ artistRepository = new ArtistRepository(application);
+ }
+
+ public Song getSong() {
+ return song;
+ }
+
+ public LiveData getLiveSong() {
+ return songRepository.getSong(song.getId());
+ }
+
+ public void setSong(Song song) {
+ this.song = song;
+ this.album = null;
+ this.artist = null;
+ }
+
+ public Album getAlbum() {
+ return album;
+ }
+
+ public LiveData getLiveAlbum() {
+ return albumRepository.getAlbum(album.getId());
+ }
+
+ public void setAlbum(Album album) {
+ this.song = null;
+ this.album = album;
+ this.artist = null;
+ }
+
+ public Artist getArtist() {
+ return artist;
+ }
+
+ public LiveData getLiveArtist() {
+ return artistRepository.getArtist(artist.getId());
+ }
+
+ public void setArtist(Artist artist) {
+ this.song = null;
+ this.album = null;
+ this.artist = artist;
+ }
+
+ public int getItemRating() {
+ if (song != null) {
+ return song.getRating();
+ } else if (album != null) {
+ return 0;
+ } else if (artist != null) {
+ return 0;
+ } else {
+ return 0;
+ }
+ }
+
+ public void rate(int star) {
+ if (song != null) {
+ songRepository.setRating(song.getId(), star);
+ } else if (album != null) {
+ albumRepository.setRating(album.getId(), star);
+ } else if (artist != null) {
+ artistRepository.setRating(artist.getId(), star);
+ }
+ }
+}
diff --git a/app/src/main/res/layout/dialog_rating.xml b/app/src/main/res/layout/dialog_rating.xml
new file mode 100644
index 00000000..af29b0e7
--- /dev/null
+++ b/app/src/main/res/layout/dialog_rating.xml
@@ -0,0 +1,22 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml
index 72f509d2..580cbce2 100644
--- a/app/src/main/res/values-night/colors.xml
+++ b/app/src/main/res/values-night/colors.xml
@@ -31,5 +31,8 @@
#707070
#606060
#1D1D1D
+
+ #733ae6
+ #1D1D1D
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8d32cc43..9a06de73 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -37,4 +37,6 @@
#FFFFFF
+ #3700B3
+ #f0f0f0
\ No newline at end of file