feat:show rating on song view and allow setting/updating. #17 fixed a fr string error

This commit is contained in:
eddyizm 2025-08-14 21:46:33 -07:00
parent c9e0581815
commit 5fa46cc49b
No known key found for this signature in database
GPG key ID: CF5F671829E8158A
5 changed files with 37 additions and 9 deletions

View file

@ -11,7 +11,7 @@ android {
targetSdk 35 targetSdk 35
versionCode 27 versionCode 27
versionName '3.11.2' versionName '3.11.3'
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'

View file

@ -10,6 +10,8 @@ import android.widget.Button;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.TextView; import android.widget.TextView;
import android.widget.ToggleButton; import android.widget.ToggleButton;
import android.widget.RatingBar;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintLayout;
@ -36,6 +38,7 @@ import com.cappielloantonio.tempo.util.Constants;
import com.cappielloantonio.tempo.util.MusicUtil; import com.cappielloantonio.tempo.util.MusicUtil;
import com.cappielloantonio.tempo.util.Preferences; import com.cappielloantonio.tempo.util.Preferences;
import com.cappielloantonio.tempo.viewmodel.PlayerBottomSheetViewModel; import com.cappielloantonio.tempo.viewmodel.PlayerBottomSheetViewModel;
import com.cappielloantonio.tempo.viewmodel.RatingViewModel;
import com.google.android.material.chip.Chip; import com.google.android.material.chip.Chip;
import com.google.android.material.elevation.SurfaceColors; import com.google.android.material.elevation.SurfaceColors;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
@ -53,6 +56,8 @@ public class PlayerControllerFragment extends Fragment {
private InnerFragmentPlayerControllerBinding bind; private InnerFragmentPlayerControllerBinding bind;
private ViewPager2 playerMediaCoverViewPager; private ViewPager2 playerMediaCoverViewPager;
private ToggleButton buttonFavorite; private ToggleButton buttonFavorite;
private RatingViewModel ratingViewModel;
private RatingBar songRatingBar;
private TextView playerMediaTitleLabel; private TextView playerMediaTitleLabel;
private TextView playerArtistNameLabel; private TextView playerArtistNameLabel;
private Button playbackSpeedButton; private Button playbackSpeedButton;
@ -75,6 +80,7 @@ public class PlayerControllerFragment extends Fragment {
View view = bind.getRoot(); View view = bind.getRoot();
playerBottomSheetViewModel = new ViewModelProvider(requireActivity()).get(PlayerBottomSheetViewModel.class); playerBottomSheetViewModel = new ViewModelProvider(requireActivity()).get(PlayerBottomSheetViewModel.class);
ratingViewModel = new ViewModelProvider(requireActivity()).get(RatingViewModel.class);
init(); init();
initQuickActionView(); initQuickActionView();
@ -117,6 +123,7 @@ public class PlayerControllerFragment extends Fragment {
playerQuickActionView = bind.getRoot().findViewById(R.id.player_quick_action_view); playerQuickActionView = bind.getRoot().findViewById(R.id.player_quick_action_view);
playerOpenQueueButton = bind.getRoot().findViewById(R.id.player_open_queue_button); playerOpenQueueButton = bind.getRoot().findViewById(R.id.player_open_queue_button);
playerTrackInfo = bind.getRoot().findViewById(R.id.player_info_track); playerTrackInfo = bind.getRoot().findViewById(R.id.player_info_track);
songRatingBar = bind.getRoot().findViewById(R.id.song_rating_bar);
} }
private void initQuickActionView() { private void initQuickActionView() {
@ -313,6 +320,7 @@ public class PlayerControllerFragment extends Fragment {
private void initMediaListenable() { private void initMediaListenable() {
playerBottomSheetViewModel.getLiveMedia().observe(getViewLifecycleOwner(), media -> { playerBottomSheetViewModel.getLiveMedia().observe(getViewLifecycleOwner(), media -> {
if (media != null) { if (media != null) {
ratingViewModel.setSong(media);
buttonFavorite.setChecked(media.getStarred() != null); buttonFavorite.setChecked(media.getStarred() != null);
buttonFavorite.setOnClickListener(v -> playerBottomSheetViewModel.setFavorite(requireContext(), media)); buttonFavorite.setOnClickListener(v -> playerBottomSheetViewModel.setFavorite(requireContext(), media));
buttonFavorite.setOnLongClickListener(v -> { buttonFavorite.setOnLongClickListener(v -> {
@ -323,9 +331,29 @@ public class PlayerControllerFragment extends Fragment {
dialog.setArguments(bundle); dialog.setArguments(bundle);
dialog.show(requireActivity().getSupportFragmentManager(), null); dialog.show(requireActivity().getSupportFragmentManager(), null);
return true; return true;
}); });
Integer currentRating = media.getUserRating();
if (currentRating != null) {
songRatingBar.setRating(currentRating);
} else {
songRatingBar.setRating(0);
}
songRatingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
if (fromUser) {
ratingViewModel.rate((int) rating);
media.setUserRating((int) rating);
}
}
});
if (getActivity() != null) { if (getActivity() != null) {
playerBottomSheetViewModel.refreshMediaInfo(requireActivity(), media); playerBottomSheetViewModel.refreshMediaInfo(requireActivity(), media);
} }

View file

@ -2,6 +2,7 @@ package com.cappielloantonio.tempo.viewmodel;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.OptIn; import androidx.annotation.OptIn;
@ -32,6 +33,8 @@ import com.cappielloantonio.tempo.util.NetworkUtil;
import com.cappielloantonio.tempo.util.OpenSubsonicExtensionsUtil; import com.cappielloantonio.tempo.util.OpenSubsonicExtensionsUtil;
import com.cappielloantonio.tempo.util.Preferences; import com.cappielloantonio.tempo.util.Preferences;
import org.jetbrains.annotations.Nullable;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -103,7 +106,6 @@ public class PlayerBottomSheetViewModel extends AndroidViewModel {
favoriteRepository.starLater(media.getId(), null, null, false); favoriteRepository.starLater(media.getId(), null, null, false);
} }
}); });
media.setStarred(null); media.setStarred(null);
} }
@ -131,7 +133,7 @@ public class PlayerBottomSheetViewModel extends AndroidViewModel {
} }
} }
public LiveData<String> getLiveLyrics() { public LiveData<String> getLiveLyrics() {
return lyricsLiveData; return lyricsLiveData;
} }

View file

@ -108,12 +108,10 @@
android:id="@+id/rating_container" android:id="@+id/rating_container"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center_vertical" android:gravity="center"
app:layout_constraintEnd_toStartOf="@+id/button_favorite" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/player_artist_name_label"> app:layout_constraintTop_toBottomOf="@+id/player_artist_name_label">
@ -134,7 +132,7 @@
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:textSize="12sp" android:textSize="12sp"
android:textColor="?attr/colorOnSurfaceVariant" android:textColor="?attr/colorOnSurfaceVariant"
android:text="Not rated"/> android:text=""/>
</LinearLayout> </LinearLayout>
<ToggleButton <ToggleButton

View file

@ -387,7 +387,7 @@
<string name="starred_sync_dialog_neutral_button">Continuer</string> <string name="starred_sync_dialog_neutral_button">Continuer</string>
<string name="starred_sync_dialog_positive_button">Continuer et télécharger</string> <string name="starred_sync_dialog_positive_button">Continuer et télécharger</string>
<string name="starred_sync_dialog_summary">Le téléchargement des titres favoris pourrer utiliser beaucoup de données.</string> <string name="starred_sync_dialog_summary">Le téléchargement des titres favoris pourrer utiliser beaucoup de données.</string>
<string name="starred_sync_dialog_title">Synchroniser les titres favoris</string>Sync starred tracks</string> <string name="starred_sync_dialog_title">Synchroniser les titres favoris</string>
<string name="streaming_cache_storage_dialog_sub_summary">Veuillez redémarrer l\'app pour appliquer les changements.</string> <string name="streaming_cache_storage_dialog_sub_summary">Veuillez redémarrer l\'app pour appliquer les changements.</string>
<string name="streaming_cache_storage_dialog_summary">Modifier le chemin de stockage des fichiers mis en cache pourrait provoquer de tous les fichiers mis en cache précédemment.</string> <string name="streaming_cache_storage_dialog_summary">Modifier le chemin de stockage des fichiers mis en cache pourrait provoquer de tous les fichiers mis en cache précédemment.</string>
<string name="streaming_cache_storage_dialog_title">Sélectionner une option de stockage</string> <string name="streaming_cache_storage_dialog_title">Sélectionner une option de stockage</string>