Merge branch 'nitehu-feature/fivestarrating' into develop
This commit is contained in:
commit
8a798ac456
|
@ -63,7 +63,9 @@ class MusicDirectory {
|
||||||
var type: String? = null,
|
var type: String? = null,
|
||||||
var created: Date? = null,
|
var created: Date? = null,
|
||||||
var closeness: Int = 0,
|
var closeness: Int = 0,
|
||||||
var bookmarkPosition: Int = 0
|
var bookmarkPosition: Int = 0,
|
||||||
|
var userRating: Int? = null,
|
||||||
|
var averageRating: Float? = null
|
||||||
) : Serializable {
|
) : Serializable {
|
||||||
fun setDuration(duration: Long) {
|
fun setDuration(duration: Long) {
|
||||||
this.duration = duration.toInt()
|
this.duration = duration.toInt()
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package org.moire.ultrasonic.api.subsonic
|
||||||
|
|
||||||
|
import org.amshove.kluent.`should be`
|
||||||
|
import org.junit.Test
|
||||||
|
import org.moire.ultrasonic.api.subsonic.response.SubsonicResponse
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration test for [SubsonicAPIClient] for setRating request.
|
||||||
|
*/
|
||||||
|
class SubsonicApiSetRatingTest : SubsonicAPIClientTest() {
|
||||||
|
@Test
|
||||||
|
fun `Should parse setRating ok response`() {
|
||||||
|
val id = "110"
|
||||||
|
val rating = 3
|
||||||
|
|
||||||
|
mockWebServerRule.enqueueResponse("ping_ok.json")
|
||||||
|
|
||||||
|
val response = client.api.setRating(id, rating).execute()
|
||||||
|
|
||||||
|
assertResponseSuccessful(response)
|
||||||
|
response.body()?.status `should be` SubsonicResponse.Status.OK
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Should parse setRating error response`() {
|
||||||
|
val id = "110223"
|
||||||
|
val rating = 5
|
||||||
|
|
||||||
|
checkErrorCallParsed(mockWebServerRule) {
|
||||||
|
client.api.setRating(id, rating).execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Should pass id parameter`() {
|
||||||
|
val id = "110"
|
||||||
|
val rating = 5
|
||||||
|
|
||||||
|
mockWebServerRule.assertRequestParam(responseResourceName = "ping_ok.json",
|
||||||
|
expectedParam = "id=$id") {
|
||||||
|
client.api.setRating(id, rating).execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Should pass rating parameter`() {
|
||||||
|
val id = "110"
|
||||||
|
val rating = 5
|
||||||
|
|
||||||
|
mockWebServerRule.assertRequestParam(responseResourceName = "ping_ok.json",
|
||||||
|
expectedParam = "rating=$rating") {
|
||||||
|
client.api.setRating(id, rating).execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -79,6 +79,12 @@ interface SubsonicAPIDefinition {
|
||||||
@Query("artistId") artistId: String? = null
|
@Query("artistId") artistId: String? = null
|
||||||
): Call<SubsonicResponse>
|
): Call<SubsonicResponse>
|
||||||
|
|
||||||
|
@GET("setRating.view")
|
||||||
|
fun setRating(
|
||||||
|
@Query("id") id: String,
|
||||||
|
@Query("rating") rating: Int
|
||||||
|
): Call<SubsonicResponse>
|
||||||
|
|
||||||
@GET("getArtist.view")
|
@GET("getArtist.view")
|
||||||
fun getArtist(@Query("id") id: String): Call<GetArtistResponse>
|
fun getArtist(@Query("id") id: String): Call<GetArtistResponse>
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,15 @@ import android.widget.TextView;
|
||||||
import android.widget.ViewFlipper;
|
import android.widget.ViewFlipper;
|
||||||
|
|
||||||
import com.mobeta.android.dslv.DragSortListView;
|
import com.mobeta.android.dslv.DragSortListView;
|
||||||
|
|
||||||
|
import org.koin.java.standalone.KoinJavaComponent;
|
||||||
import org.moire.ultrasonic.R;
|
import org.moire.ultrasonic.R;
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory;
|
import org.moire.ultrasonic.domain.MusicDirectory;
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
||||||
import org.moire.ultrasonic.domain.PlayerState;
|
import org.moire.ultrasonic.domain.PlayerState;
|
||||||
import org.moire.ultrasonic.domain.RepeatMode;
|
import org.moire.ultrasonic.domain.RepeatMode;
|
||||||
|
import org.moire.ultrasonic.featureflags.Feature;
|
||||||
|
import org.moire.ultrasonic.featureflags.FeatureStorage;
|
||||||
import org.moire.ultrasonic.service.DownloadFile;
|
import org.moire.ultrasonic.service.DownloadFile;
|
||||||
import org.moire.ultrasonic.service.DownloadService;
|
import org.moire.ultrasonic.service.DownloadService;
|
||||||
import org.moire.ultrasonic.service.MusicService;
|
import org.moire.ultrasonic.service.MusicService;
|
||||||
|
@ -119,6 +123,15 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
|
||||||
private SilentBackgroundTask<Void> onProgressChangedTask;
|
private SilentBackgroundTask<Void> onProgressChangedTask;
|
||||||
LinearLayout visualizerViewLayout;
|
LinearLayout visualizerViewLayout;
|
||||||
private MenuItem starMenuItem;
|
private MenuItem starMenuItem;
|
||||||
|
private LinearLayout ratingLinearLayout;
|
||||||
|
private ImageView fiveStar1ImageView;
|
||||||
|
private ImageView fiveStar2ImageView;
|
||||||
|
private ImageView fiveStar3ImageView;
|
||||||
|
private ImageView fiveStar4ImageView;
|
||||||
|
private ImageView fiveStar5ImageView;
|
||||||
|
private boolean useFiveStarRating;
|
||||||
|
private Drawable hollowStar;
|
||||||
|
private Drawable fullStar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the activity is first created.
|
* Called when the activity is first created.
|
||||||
|
@ -136,6 +149,8 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
|
||||||
int width = size.x;
|
int width = size.x;
|
||||||
int height = size.y;
|
int height = size.y;
|
||||||
|
|
||||||
|
useFiveStarRating = KoinJavaComponent.get(FeatureStorage.class).isFeatureEnabled(Feature.FIVE_STAR_RATING);
|
||||||
|
|
||||||
swipeDistance = (width + height) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100;
|
swipeDistance = (width + height) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100;
|
||||||
swipeVelocity = swipeDistance;
|
swipeVelocity = swipeDistance;
|
||||||
gestureScanner = new GestureDetector(this, this);
|
gestureScanner = new GestureDetector(this, this);
|
||||||
|
@ -162,6 +177,54 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
|
||||||
|
|
||||||
visualizerViewLayout = (LinearLayout) findViewById(R.id.download_visualizer_view_layout);
|
visualizerViewLayout = (LinearLayout) findViewById(R.id.download_visualizer_view_layout);
|
||||||
|
|
||||||
|
ratingLinearLayout = findViewById(R.id.song_rating);
|
||||||
|
fiveStar1ImageView = findViewById(R.id.song_five_star_1);
|
||||||
|
fiveStar2ImageView = findViewById(R.id.song_five_star_2);
|
||||||
|
fiveStar3ImageView = findViewById(R.id.song_five_star_3);
|
||||||
|
fiveStar4ImageView = findViewById(R.id.song_five_star_4);
|
||||||
|
fiveStar5ImageView = findViewById(R.id.song_five_star_5);
|
||||||
|
|
||||||
|
if (!useFiveStarRating) ratingLinearLayout.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
hollowStar = Util.getDrawableFromAttribute(SubsonicTabActivity.getInstance(), R.attr.star_hollow);
|
||||||
|
fullStar = Util.getDrawableFromAttribute(SubsonicTabActivity.getInstance(), R.attr.star_full);
|
||||||
|
|
||||||
|
fiveStar1ImageView.setOnClickListener(new View.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(final View view) {
|
||||||
|
setSongRating(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fiveStar2ImageView.setOnClickListener(new View.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(final View view) {
|
||||||
|
setSongRating(2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fiveStar3ImageView.setOnClickListener(new View.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(final View view) {
|
||||||
|
setSongRating(3);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fiveStar4ImageView.setOnClickListener(new View.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(final View view) {
|
||||||
|
setSongRating(4);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fiveStar5ImageView.setOnClickListener(new View.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(final View view) {
|
||||||
|
setSongRating(5);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
View.OnTouchListener touchListener = new View.OnTouchListener()
|
View.OnTouchListener touchListener = new View.OnTouchListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -726,22 +789,20 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
|
||||||
currentSong = downloadFile.getSong();
|
currentSong = downloadFile.getSong();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useFiveStarRating) starMenuItem.setVisible(false);
|
||||||
|
|
||||||
if (currentSong != null)
|
if (currentSong != null)
|
||||||
{
|
{
|
||||||
final Drawable starDrawable = currentSong.getStarred() ? Util.getDrawableFromAttribute(SubsonicTabActivity.getInstance(), R.attr.star_full) : Util.getDrawableFromAttribute(SubsonicTabActivity.getInstance(), R.attr.star_hollow);
|
|
||||||
|
|
||||||
if (starMenuItem != null)
|
if (starMenuItem != null)
|
||||||
{
|
{
|
||||||
starMenuItem.setIcon(starDrawable);
|
starMenuItem.setIcon(currentSong.getStarred() ? fullStar : hollowStar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
final Drawable starDrawable = Util.getDrawableFromAttribute(SubsonicTabActivity.getInstance(), R.attr.star_hollow);
|
|
||||||
|
|
||||||
if (starMenuItem != null)
|
if (starMenuItem != null)
|
||||||
{
|
{
|
||||||
starMenuItem.setIcon(starDrawable);
|
starMenuItem.setIcon(hollowStar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -974,12 +1035,12 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
|
||||||
|
|
||||||
if (isStarred)
|
if (isStarred)
|
||||||
{
|
{
|
||||||
starMenuItem.setIcon(Util.getDrawableFromAttribute(SubsonicTabActivity.getInstance(), R.attr.star_hollow));
|
starMenuItem.setIcon(hollowStar);
|
||||||
currentSong.setStarred(false);
|
currentSong.setStarred(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
starMenuItem.setIcon(Util.getDrawableFromAttribute(SubsonicTabActivity.getInstance(), R.attr.star_full));
|
starMenuItem.setIcon(fullStar);
|
||||||
currentSong.setStarred(true);
|
currentSong.setStarred(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1320,6 +1381,8 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
|
||||||
downloadTrackTextView.setText(trackFormat);
|
downloadTrackTextView.setText(trackFormat);
|
||||||
downloadTotalDurationTextView.setText(duration);
|
downloadTotalDurationTextView.setText(duration);
|
||||||
getImageLoader().loadImage(albumArtImageView, currentSong, true, 0, false, true);
|
getImageLoader().loadImage(albumArtImageView, currentSong, true, 0, false, true);
|
||||||
|
|
||||||
|
displaySongRating();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1440,6 +1503,9 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: It would be a lot nicer if DownloadService would send an event when this is necessary instead of updating every time
|
||||||
|
displaySongRating();
|
||||||
|
|
||||||
onProgressChangedTask = null;
|
onProgressChangedTask = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1580,4 +1646,23 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
|
||||||
{
|
{
|
||||||
return progressBar;
|
return progressBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void displaySongRating()
|
||||||
|
{
|
||||||
|
int rating = currentSong.getUserRating() == null ? 0 : currentSong.getUserRating();
|
||||||
|
fiveStar1ImageView.setImageDrawable(rating > 0 ? fullStar : hollowStar);
|
||||||
|
fiveStar2ImageView.setImageDrawable(rating > 1 ? fullStar : hollowStar);
|
||||||
|
fiveStar3ImageView.setImageDrawable(rating > 2 ? fullStar : hollowStar);
|
||||||
|
fiveStar4ImageView.setImageDrawable(rating > 3 ? fullStar : hollowStar);
|
||||||
|
fiveStar5ImageView.setImageDrawable(rating > 4 ? fullStar : hollowStar);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSongRating(final int rating)
|
||||||
|
{
|
||||||
|
if (currentSong == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
displaySongRating();
|
||||||
|
getDownloadService().setSongRating(rating);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,10 +172,11 @@ public class SettingsFragment extends PreferenceFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupFeatureFlagsPreferences() {
|
private void setupFeatureFlagsPreferences() {
|
||||||
|
final FeatureStorage featureStorage = KoinJavaComponent.get(FeatureStorage.class);
|
||||||
|
|
||||||
CheckBoxPreference ffImageLoader = (CheckBoxPreference) findPreference(
|
CheckBoxPreference ffImageLoader = (CheckBoxPreference) findPreference(
|
||||||
Constants.PREFERENCES_KEY_FF_IMAGE_LOADER);
|
Constants.PREFERENCES_KEY_FF_IMAGE_LOADER);
|
||||||
|
|
||||||
final FeatureStorage featureStorage = KoinJavaComponent.get(FeatureStorage.class);
|
|
||||||
if (ffImageLoader != null) {
|
if (ffImageLoader != null) {
|
||||||
ffImageLoader.setChecked(featureStorage.isFeatureEnabled(Feature.NEW_IMAGE_DOWNLOADER));
|
ffImageLoader.setChecked(featureStorage.isFeatureEnabled(Feature.NEW_IMAGE_DOWNLOADER));
|
||||||
ffImageLoader.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
ffImageLoader.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@ -187,6 +188,21 @@ public class SettingsFragment extends PreferenceFragment
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckBoxPreference useFiveStarRating = (CheckBoxPreference) findPreference(
|
||||||
|
Constants.PREFERENCES_KEY_USE_FIVE_STAR_RATING);
|
||||||
|
|
||||||
|
if (useFiveStarRating != null) {
|
||||||
|
useFiveStarRating.setChecked(featureStorage.isFeatureEnabled(Feature.FIVE_STAR_RATING));
|
||||||
|
useFiveStarRating.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||||
|
featureStorage.changeFeatureFlag(Feature.FIVE_STAR_RATING, (Boolean) o);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupGaplessControlSettingsV14() {
|
private void setupGaplessControlSettingsV14() {
|
||||||
|
|
|
@ -385,7 +385,6 @@ public class CachedMusicService implements MusicService
|
||||||
public void star(String id, String albumId, String artistId, Context context, ProgressListener progressListener) throws Exception
|
public void star(String id, String albumId, String artistId, Context context, ProgressListener progressListener) throws Exception
|
||||||
{
|
{
|
||||||
musicService.star(id, albumId, artistId, context, progressListener);
|
musicService.star(id, albumId, artistId, context, progressListener);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -394,6 +393,12 @@ public class CachedMusicService implements MusicService
|
||||||
musicService.unstar(id, albumId, artistId, context, progressListener);
|
musicService.unstar(id, albumId, artistId, context, progressListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRating(String id, int rating, Context context, ProgressListener progressListener) throws Exception
|
||||||
|
{
|
||||||
|
musicService.setRating(id, rating, context, progressListener);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Genre> getGenres(Context context, ProgressListener progressListener) throws Exception
|
public List<Genre> getGenres(Context context, ProgressListener progressListener) throws Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -144,4 +144,8 @@ public interface DownloadService
|
||||||
void stopJukeboxService();
|
void stopJukeboxService();
|
||||||
|
|
||||||
void startJukeboxService();
|
void startJukeboxService();
|
||||||
|
|
||||||
|
void updateNotification();
|
||||||
|
|
||||||
|
void setSongRating(final int rating);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,11 @@ import android.os.PowerManager;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.app.NotificationManagerCompat;
|
import android.support.v4.app.NotificationManagerCompat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
|
|
||||||
|
import org.koin.java.standalone.KoinJavaComponent;
|
||||||
import org.moire.ultrasonic.R;
|
import org.moire.ultrasonic.R;
|
||||||
import org.moire.ultrasonic.activity.DownloadActivity;
|
import org.moire.ultrasonic.activity.DownloadActivity;
|
||||||
import org.moire.ultrasonic.activity.SubsonicTabActivity;
|
import org.moire.ultrasonic.activity.SubsonicTabActivity;
|
||||||
|
@ -52,6 +54,8 @@ import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
||||||
import org.moire.ultrasonic.domain.PlayerState;
|
import org.moire.ultrasonic.domain.PlayerState;
|
||||||
import org.moire.ultrasonic.domain.RepeatMode;
|
import org.moire.ultrasonic.domain.RepeatMode;
|
||||||
import org.moire.ultrasonic.domain.UserInfo;
|
import org.moire.ultrasonic.domain.UserInfo;
|
||||||
|
import org.moire.ultrasonic.featureflags.Feature;
|
||||||
|
import org.moire.ultrasonic.featureflags.FeatureStorage;
|
||||||
import org.moire.ultrasonic.provider.UltraSonicAppWidgetProvider4x1;
|
import org.moire.ultrasonic.provider.UltraSonicAppWidgetProvider4x1;
|
||||||
import org.moire.ultrasonic.provider.UltraSonicAppWidgetProvider4x2;
|
import org.moire.ultrasonic.provider.UltraSonicAppWidgetProvider4x2;
|
||||||
import org.moire.ultrasonic.provider.UltraSonicAppWidgetProvider4x3;
|
import org.moire.ultrasonic.provider.UltraSonicAppWidgetProvider4x3;
|
||||||
|
@ -1238,11 +1242,7 @@ public class DownloadServiceImpl extends Service implements DownloadService
|
||||||
// Only update notification is player state is one that will change the icon
|
// Only update notification is player state is one that will change the icon
|
||||||
if (this.playerState == PlayerState.STARTED || this.playerState == PlayerState.PAUSED)
|
if (this.playerState == PlayerState.STARTED || this.playerState == PlayerState.PAUSED)
|
||||||
{
|
{
|
||||||
if (Util.isNotificationEnabled(this)) {
|
updateNotification();
|
||||||
final NotificationManagerCompat notificationManager =
|
|
||||||
NotificationManagerCompat.from(this);
|
|
||||||
notificationManager.notify(NOTIFICATION_ID, buildForegroundNotification());
|
|
||||||
}
|
|
||||||
tabInstance.showNowPlaying();
|
tabInstance.showNowPlaying();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2071,6 +2071,16 @@ public class DownloadServiceImpl extends Service implements DownloadService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateNotification()
|
||||||
|
{
|
||||||
|
if (Util.isNotificationEnabled(this)) {
|
||||||
|
final NotificationManagerCompat notificationManager =
|
||||||
|
NotificationManagerCompat.from(this);
|
||||||
|
notificationManager.notify(NOTIFICATION_ID, buildForegroundNotification());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("IconColors")
|
@SuppressWarnings("IconColors")
|
||||||
private Notification buildForegroundNotification() {
|
private Notification buildForegroundNotification() {
|
||||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
|
||||||
|
@ -2103,6 +2113,7 @@ public class DownloadServiceImpl extends Service implements DownloadService
|
||||||
final String title = song.getTitle();
|
final String title = song.getTitle();
|
||||||
final String text = song.getArtist();
|
final String text = song.getArtist();
|
||||||
final String album = song.getAlbum();
|
final String album = song.getAlbum();
|
||||||
|
final int rating = song.getUserRating() == null ? 0 : song.getUserRating();
|
||||||
final int imageSize = Util.getNotificationImageSize(this);
|
final int imageSize = Util.getNotificationImageSize(this);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -2127,6 +2138,17 @@ public class DownloadServiceImpl extends Service implements DownloadService
|
||||||
contentView.setTextViewText(R.id.album, album);
|
contentView.setTextViewText(R.id.album, album);
|
||||||
bigView.setTextViewText(R.id.album, album);
|
bigView.setTextViewText(R.id.album, album);
|
||||||
|
|
||||||
|
boolean useFiveStarRating = KoinJavaComponent.get(FeatureStorage.class).isFeatureEnabled(Feature.FIVE_STAR_RATING);
|
||||||
|
if (!useFiveStarRating) bigView.setViewVisibility(R.id.notification_rating, View.INVISIBLE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bigView.setImageViewResource(R.id.notification_five_star_1, rating > 0 ? R.drawable.ic_star_full_dark : R.drawable.ic_star_hollow_dark);
|
||||||
|
bigView.setImageViewResource(R.id.notification_five_star_2, rating > 1 ? R.drawable.ic_star_full_dark : R.drawable.ic_star_hollow_dark);
|
||||||
|
bigView.setImageViewResource(R.id.notification_five_star_3, rating > 2 ? R.drawable.ic_star_full_dark : R.drawable.ic_star_hollow_dark);
|
||||||
|
bigView.setImageViewResource(R.id.notification_five_star_4, rating > 3 ? R.drawable.ic_star_full_dark : R.drawable.ic_star_hollow_dark);
|
||||||
|
bigView.setImageViewResource(R.id.notification_five_star_5, rating > 4 ? R.drawable.ic_star_full_dark : R.drawable.ic_star_hollow_dark);
|
||||||
|
}
|
||||||
|
|
||||||
Notification notification = builder.build();
|
Notification notification = builder.build();
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
notification.bigContentView = bigView;
|
notification.bigContentView = bigView;
|
||||||
|
@ -2135,6 +2157,38 @@ public class DownloadServiceImpl extends Service implements DownloadService
|
||||||
return notification;
|
return notification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSongRating(final int rating)
|
||||||
|
{
|
||||||
|
if (!KoinJavaComponent.get(FeatureStorage.class).isFeatureEnabled(Feature.FIVE_STAR_RATING))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (currentPlaying == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
final Entry song = currentPlaying.getSong();
|
||||||
|
song.setUserRating(rating);
|
||||||
|
|
||||||
|
new Thread(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
final MusicService musicService = MusicServiceFactory.getMusicService(DownloadServiceImpl.this);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
musicService.setRating(song.getId(), rating, DownloadServiceImpl.this, null);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.e(TAG, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
updateNotification();
|
||||||
|
}
|
||||||
|
|
||||||
private class BufferTask extends CancellableTask
|
private class BufferTask extends CancellableTask
|
||||||
{
|
{
|
||||||
private final DownloadFile downloadFile;
|
private final DownloadFile downloadFile;
|
||||||
|
|
|
@ -329,6 +329,21 @@ public class DownloadServiceLifecycleSupport
|
||||||
case KeyEvent.KEYCODE_MEDIA_PAUSE:
|
case KeyEvent.KEYCODE_MEDIA_PAUSE:
|
||||||
downloadService.pause();
|
downloadService.pause();
|
||||||
break;
|
break;
|
||||||
|
case KeyEvent.KEYCODE_1:
|
||||||
|
downloadService.setSongRating(1);
|
||||||
|
break;
|
||||||
|
case KeyEvent.KEYCODE_2:
|
||||||
|
downloadService.setSongRating(2);
|
||||||
|
break;
|
||||||
|
case KeyEvent.KEYCODE_3:
|
||||||
|
downloadService.setSongRating(3);
|
||||||
|
break;
|
||||||
|
case KeyEvent.KEYCODE_4:
|
||||||
|
downloadService.setSongRating(4);
|
||||||
|
break;
|
||||||
|
case KeyEvent.KEYCODE_5:
|
||||||
|
downloadService.setSongRating(5);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,8 @@ public interface MusicService
|
||||||
|
|
||||||
void unstar(String id, String albumId, String artistId, Context context, ProgressListener progressListener) throws Exception;
|
void unstar(String id, String albumId, String artistId, Context context, ProgressListener progressListener) throws Exception;
|
||||||
|
|
||||||
|
void setRating(String id, int rating, Context context, ProgressListener progressListener) throws Exception;
|
||||||
|
|
||||||
List<MusicFolder> getMusicFolders(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
List<MusicFolder> getMusicFolders(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||||
|
|
||||||
Indexes getIndexes(String musicFolderId, boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
Indexes getIndexes(String musicFolderId, boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||||
|
|
|
@ -238,6 +238,17 @@ public class RESTMusicService implements MusicService {
|
||||||
checkResponseSuccessful(response);
|
checkResponseSuccessful(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRating(String id,
|
||||||
|
int rating,
|
||||||
|
Context context,
|
||||||
|
ProgressListener progressListener) throws Exception {
|
||||||
|
updateProgressListener(progressListener, R.string.parser_reading);
|
||||||
|
Response<SubsonicResponse> response = subsonicAPIClient.getApi()
|
||||||
|
.setRating(id, rating).execute();
|
||||||
|
checkResponseSuccessful(response);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MusicDirectory getMusicDirectory(String id,
|
public MusicDirectory getMusicDirectory(String id,
|
||||||
String name,
|
String name,
|
||||||
|
|
|
@ -131,6 +131,7 @@ public final class Constants
|
||||||
public static final String PREFERENCES_KEY_SCAN_MEDIA = "scanMedia";
|
public static final String PREFERENCES_KEY_SCAN_MEDIA = "scanMedia";
|
||||||
public static final String PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY = "imageLoaderConcurrency";
|
public static final String PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY = "imageLoaderConcurrency";
|
||||||
public static final String PREFERENCES_KEY_FF_IMAGE_LOADER = "ff_new_image_loader";
|
public static final String PREFERENCES_KEY_FF_IMAGE_LOADER = "ff_new_image_loader";
|
||||||
|
public static final String PREFERENCES_KEY_USE_FIVE_STAR_RATING = "use_five_star_rating";
|
||||||
|
|
||||||
// Number of free trial days for non-licensed servers.
|
// Number of free trial days for non-licensed servers.
|
||||||
public static final int FREE_TRIAL_DAYS = 30;
|
public static final int FREE_TRIAL_DAYS = 30;
|
||||||
|
|
|
@ -1306,6 +1306,36 @@ public class Util extends DownloadActivity
|
||||||
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_STOP));
|
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_STOP));
|
||||||
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
|
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
|
||||||
views.setOnClickPendingIntent(R.id.control_stop, pendingIntent);
|
views.setOnClickPendingIntent(R.id.control_stop, pendingIntent);
|
||||||
|
|
||||||
|
intent = new Intent("RATE_1");
|
||||||
|
intent.setComponent(new ComponentName(context, DownloadServiceImpl.class));
|
||||||
|
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_1));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
|
||||||
|
views.setOnClickPendingIntent(R.id.notification_five_star_1, pendingIntent);
|
||||||
|
|
||||||
|
intent = new Intent("RATE_2");
|
||||||
|
intent.setComponent(new ComponentName(context, DownloadServiceImpl.class));
|
||||||
|
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_2));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
|
||||||
|
views.setOnClickPendingIntent(R.id.notification_five_star_2, pendingIntent);
|
||||||
|
|
||||||
|
intent = new Intent("RATE_3");
|
||||||
|
intent.setComponent(new ComponentName(context, DownloadServiceImpl.class));
|
||||||
|
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_3));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
|
||||||
|
views.setOnClickPendingIntent(R.id.notification_five_star_3, pendingIntent);
|
||||||
|
|
||||||
|
intent = new Intent("RATE_4");
|
||||||
|
intent.setComponent(new ComponentName(context, DownloadServiceImpl.class));
|
||||||
|
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_4));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
|
||||||
|
views.setOnClickPendingIntent(R.id.notification_five_star_4, pendingIntent);
|
||||||
|
|
||||||
|
intent = new Intent("RATE_5");
|
||||||
|
intent.setComponent(new ComponentName(context, DownloadServiceImpl.class));
|
||||||
|
intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_5));
|
||||||
|
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
|
||||||
|
views.setOnClickPendingIntent(R.id.notification_five_star_5, pendingIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getNetworkTimeout(Context context)
|
public static int getNetworkTimeout(Context context)
|
||||||
|
|
|
@ -23,6 +23,7 @@ import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.CheckedTextView;
|
import android.widget.CheckedTextView;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import org.moire.ultrasonic.activity.SubsonicTabActivity;
|
import org.moire.ultrasonic.activity.SubsonicTabActivity;
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
||||||
|
@ -120,6 +121,12 @@ public class EntryAdapter extends ArrayAdapter<Entry>
|
||||||
TextView status;
|
TextView status;
|
||||||
TextView artist;
|
TextView artist;
|
||||||
TextView duration;
|
TextView duration;
|
||||||
|
LinearLayout rating;
|
||||||
|
ImageView fiveStar1;
|
||||||
|
ImageView fiveStar2;
|
||||||
|
ImageView fiveStar3;
|
||||||
|
ImageView fiveStar4;
|
||||||
|
ImageView fiveStar5;
|
||||||
ImageView star;
|
ImageView star;
|
||||||
ImageView drag;
|
ImageView drag;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,14 @@ import android.view.View;
|
||||||
import android.widget.Checkable;
|
import android.widget.Checkable;
|
||||||
import android.widget.CheckedTextView;
|
import android.widget.CheckedTextView;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.koin.java.standalone.KoinJavaComponent;
|
||||||
import org.moire.ultrasonic.R;
|
import org.moire.ultrasonic.R;
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
||||||
|
import org.moire.ultrasonic.featureflags.Feature;
|
||||||
|
import org.moire.ultrasonic.featureflags.FeatureStorage;
|
||||||
import org.moire.ultrasonic.service.DownloadFile;
|
import org.moire.ultrasonic.service.DownloadFile;
|
||||||
import org.moire.ultrasonic.service.DownloadService;
|
import org.moire.ultrasonic.service.DownloadService;
|
||||||
import org.moire.ultrasonic.service.DownloadServiceImpl;
|
import org.moire.ultrasonic.service.DownloadServiceImpl;
|
||||||
|
@ -73,12 +77,15 @@ public class SongView extends UpdateView implements Checkable
|
||||||
private boolean playing;
|
private boolean playing;
|
||||||
private EntryAdapter.SongViewHolder viewHolder;
|
private EntryAdapter.SongViewHolder viewHolder;
|
||||||
private boolean maximized = false;
|
private boolean maximized = false;
|
||||||
|
private boolean useFiveStarRating;
|
||||||
|
|
||||||
public SongView(Context context)
|
public SongView(Context context)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
|
useFiveStarRating = KoinJavaComponent.get(FeatureStorage.class).isFeatureEnabled(Feature.FIVE_STAR_RATING);
|
||||||
|
|
||||||
String theme = Util.getTheme(context);
|
String theme = Util.getTheme(context);
|
||||||
boolean themesMatch = theme.equals(SongView.theme);
|
boolean themesMatch = theme.equals(SongView.theme);
|
||||||
inflater = LayoutInflater.from(this.context);
|
inflater = LayoutInflater.from(this.context);
|
||||||
|
@ -124,6 +131,12 @@ public class SongView extends UpdateView implements Checkable
|
||||||
inflater.inflate(song.isVideo() ? R.layout.video_list_item : R.layout.song_list_item, this, true);
|
inflater.inflate(song.isVideo() ? R.layout.video_list_item : R.layout.song_list_item, this, true);
|
||||||
viewHolder = new EntryAdapter.SongViewHolder();
|
viewHolder = new EntryAdapter.SongViewHolder();
|
||||||
viewHolder.check = (CheckedTextView) findViewById(R.id.song_check);
|
viewHolder.check = (CheckedTextView) findViewById(R.id.song_check);
|
||||||
|
viewHolder.rating = (LinearLayout) findViewById(R.id.song_rating);
|
||||||
|
viewHolder.fiveStar1 = (ImageView) findViewById(R.id.song_five_star_1);
|
||||||
|
viewHolder.fiveStar2 = (ImageView) findViewById(R.id.song_five_star_2);
|
||||||
|
viewHolder.fiveStar3 = (ImageView) findViewById(R.id.song_five_star_3);
|
||||||
|
viewHolder.fiveStar4 = (ImageView) findViewById(R.id.song_five_star_4);
|
||||||
|
viewHolder.fiveStar5 = (ImageView) findViewById(R.id.song_five_star_5);
|
||||||
viewHolder.star = (ImageView) findViewById(R.id.song_star);
|
viewHolder.star = (ImageView) findViewById(R.id.song_star);
|
||||||
viewHolder.drag = (ImageView) findViewById(R.id.song_drag);
|
viewHolder.drag = (ImageView) findViewById(R.id.song_drag);
|
||||||
viewHolder.track = (TextView) findViewById(R.id.song_track);
|
viewHolder.track = (TextView) findViewById(R.id.song_track);
|
||||||
|
@ -237,56 +250,59 @@ public class SongView extends UpdateView implements Checkable
|
||||||
if (Util.isOffline(this.context))
|
if (Util.isOffline(this.context))
|
||||||
{
|
{
|
||||||
viewHolder.star.setVisibility(View.GONE);
|
viewHolder.star.setVisibility(View.GONE);
|
||||||
|
viewHolder.rating.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
viewHolder.star.setImageDrawable(song.getStarred() ? starDrawable : starHollowDrawable);
|
if (useFiveStarRating)
|
||||||
|
|
||||||
viewHolder.star.setOnClickListener(new View.OnClickListener()
|
|
||||||
{
|
{
|
||||||
@Override
|
viewHolder.star.setVisibility(View.GONE);
|
||||||
public void onClick(View view)
|
|
||||||
{
|
|
||||||
final boolean isStarred = song.getStarred();
|
|
||||||
final String id = song.getId();
|
|
||||||
|
|
||||||
if (!isStarred)
|
int rating = song.getUserRating() == null ? 0 : song.getUserRating();
|
||||||
{
|
viewHolder.fiveStar1.setImageDrawable(rating > 0 ? starDrawable : starHollowDrawable);
|
||||||
viewHolder.star.setImageDrawable(starDrawable);
|
viewHolder.fiveStar2.setImageDrawable(rating > 1 ? starDrawable : starHollowDrawable);
|
||||||
song.setStarred(true);
|
viewHolder.fiveStar3.setImageDrawable(rating > 2 ? starDrawable : starHollowDrawable);
|
||||||
}
|
viewHolder.fiveStar4.setImageDrawable(rating > 3 ? starDrawable : starHollowDrawable);
|
||||||
else
|
viewHolder.fiveStar5.setImageDrawable(rating > 4 ? starDrawable : starHollowDrawable);
|
||||||
{
|
|
||||||
viewHolder.star.setImageDrawable(starHollowDrawable);
|
|
||||||
song.setStarred(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
new Thread(new Runnable()
|
}
|
||||||
{
|
else {
|
||||||
@Override
|
viewHolder.rating.setVisibility(View.GONE);
|
||||||
public void run()
|
viewHolder.star.setImageDrawable(song.getStarred() ? starDrawable : starHollowDrawable);
|
||||||
{
|
|
||||||
MusicService musicService = MusicServiceFactory.getMusicService(SongView.this.context);
|
|
||||||
|
|
||||||
try
|
viewHolder.star.setOnClickListener(new View.OnClickListener() {
|
||||||
{
|
@Override
|
||||||
if (!isStarred)
|
public void onClick(View view) {
|
||||||
{
|
final boolean isStarred = song.getStarred();
|
||||||
musicService.star(id, null, null, SongView.this.context, null);
|
final String id = song.getId();
|
||||||
}
|
|
||||||
else
|
if (!isStarred) {
|
||||||
{
|
viewHolder.star.setImageDrawable(starDrawable);
|
||||||
musicService.unstar(id, null, null, SongView.this.context, null);
|
song.setStarred(true);
|
||||||
}
|
} else {
|
||||||
}
|
viewHolder.star.setImageDrawable(starHollowDrawable);
|
||||||
catch (Exception e)
|
song.setStarred(false);
|
||||||
{
|
|
||||||
Log.e(TAG, e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).start();
|
|
||||||
}
|
new Thread(new Runnable() {
|
||||||
});
|
@Override
|
||||||
|
public void run() {
|
||||||
|
MusicService musicService = MusicServiceFactory.getMusicService(SongView.this.context);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!isStarred) {
|
||||||
|
musicService.star(id, null, null, SongView.this.context, null);
|
||||||
|
} else {
|
||||||
|
musicService.unstar(id, null, null, SongView.this.context, null);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
@ -394,6 +410,13 @@ public class SongView extends UpdateView implements Checkable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rating = song.getUserRating() == null ? 0 : song.getUserRating();
|
||||||
|
viewHolder.fiveStar1.setImageDrawable(rating > 0 ? starDrawable : starHollowDrawable);
|
||||||
|
viewHolder.fiveStar2.setImageDrawable(rating > 1 ? starDrawable : starHollowDrawable);
|
||||||
|
viewHolder.fiveStar3.setImageDrawable(rating > 2 ? starDrawable : starHollowDrawable);
|
||||||
|
viewHolder.fiveStar4.setImageDrawable(rating > 3 ? starDrawable : starHollowDrawable);
|
||||||
|
viewHolder.fiveStar5.setImageDrawable(rating > 4 ? starDrawable : starHollowDrawable);
|
||||||
|
|
||||||
boolean playing = downloadService.getCurrentPlaying() == downloadFile;
|
boolean playing = downloadService.getCurrentPlaying() == downloadFile;
|
||||||
|
|
||||||
if (playing)
|
if (playing)
|
||||||
|
|
|
@ -45,6 +45,8 @@ fun MusicDirectoryChild.toDomainEntity(): MusicDirectory.Entry = MusicDirectory.
|
||||||
if (this@toDomainEntity.publishDate != null) {
|
if (this@toDomainEntity.publishDate != null) {
|
||||||
artist = dateFormat.format(this@toDomainEntity.publishDate!!.time)
|
artist = dateFormat.format(this@toDomainEntity.publishDate!!.time)
|
||||||
}
|
}
|
||||||
|
userRating = this@toDomainEntity.userRating
|
||||||
|
averageRating = this@toDomainEntity.averageRating
|
||||||
}
|
}
|
||||||
|
|
||||||
fun List<MusicDirectoryChild>.toDomainEntityList() = this.map { it.toDomainEntity() }
|
fun List<MusicDirectoryChild>.toDomainEntityList() = this.map { it.toDomainEntity() }
|
||||||
|
|
|
@ -10,5 +10,9 @@ enum class Feature(
|
||||||
/**
|
/**
|
||||||
* Enables new image downloader implementation.
|
* Enables new image downloader implementation.
|
||||||
*/
|
*/
|
||||||
NEW_IMAGE_DOWNLOADER(false)
|
NEW_IMAGE_DOWNLOADER(false),
|
||||||
|
/**
|
||||||
|
* Enables five star rating system.
|
||||||
|
*/
|
||||||
|
FIVE_STAR_RATING(false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,93 @@
|
||||||
a:contentDescription="@string/albumArt"/>
|
a:contentDescription="@string/albumArt"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
a:id="@+id/download_visualizer_view_layout"
|
a:id="@+id/album_art_inside"
|
||||||
a:layout_width="fill_parent"
|
a:layout_width="fill_parent"
|
||||||
a:layout_height="60dip"
|
a:layout_height="fill_parent"
|
||||||
a:layout_gravity="bottom|center_horizontal"
|
a:gravity="bottom"
|
||||||
a:layout_marginLeft="60dip"
|
a:orientation="vertical" >
|
||||||
a:layout_marginRight="60dip"
|
|
||||||
a:background="@color/translucent"
|
|
||||||
a:orientation="vertical"/>
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
a:id="@+id/song_rating"
|
||||||
|
a:layout_width="match_parent"
|
||||||
|
a:layout_height="60dip"
|
||||||
|
a:layout_gravity="center"
|
||||||
|
a:layout_margin="40dip"
|
||||||
|
a:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_1"
|
||||||
|
a:layout_width="0dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:layout_weight="1"
|
||||||
|
a:padding="10dip"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="fitCenter"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_2"
|
||||||
|
a:layout_width="0dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:layout_weight="1"
|
||||||
|
a:padding="10dip"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="fitCenter"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_3"
|
||||||
|
a:layout_width="0dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:layout_weight="1"
|
||||||
|
a:padding="10dip"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="fitCenter"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_4"
|
||||||
|
a:layout_width="0dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:layout_weight="1"
|
||||||
|
a:padding="10dip"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="fitCenter"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_5"
|
||||||
|
a:layout_width="0dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:layout_weight="1"
|
||||||
|
a:padding="10dip"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="fitCenter"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
a:id="@+id/download_visualizer_view_layout"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="60dip"
|
||||||
|
a:layout_gravity="bottom|center_horizontal"
|
||||||
|
a:layout_marginLeft="60dip"
|
||||||
|
a:layout_marginRight="60dip"
|
||||||
|
a:background="@color/translucent"
|
||||||
|
a:orientation="vertical"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<include layout="@layout/download_playlist"/>
|
<include layout="@layout/download_playlist"/>
|
||||||
|
|
|
@ -28,16 +28,94 @@
|
||||||
a:contentDescription="@string/albumArt"/>
|
a:contentDescription="@string/albumArt"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
a:id="@+id/download_visualizer_view_layout"
|
a:id="@+id/album_art_inside"
|
||||||
a:layout_width="fill_parent"
|
a:layout_width="fill_parent"
|
||||||
a:layout_height="60dip"
|
a:layout_height="fill_parent"
|
||||||
a:layout_alignParentBottom="true"
|
a:gravity="bottom"
|
||||||
a:layout_gravity="center_horizontal"
|
a:orientation="vertical" >
|
||||||
a:background="@color/translucent"
|
|
||||||
a:layout_marginLeft="80dip"
|
<LinearLayout
|
||||||
a:layout_marginRight="80dip"
|
a:id="@+id/song_rating"
|
||||||
a:orientation="vertical"
|
a:layout_width="match_parent"
|
||||||
/>
|
a:layout_height="60dip"
|
||||||
|
a:layout_gravity="center"
|
||||||
|
a:layout_margin="40dip"
|
||||||
|
a:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_1"
|
||||||
|
a:layout_width="0dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:layout_weight="1"
|
||||||
|
a:padding="5dip"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="fitCenter"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_2"
|
||||||
|
a:layout_width="0dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:layout_weight="1"
|
||||||
|
a:padding="5dip"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="fitCenter"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_3"
|
||||||
|
a:layout_width="0dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:layout_weight="1"
|
||||||
|
a:padding="5dip"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="fitCenter"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_4"
|
||||||
|
a:layout_width="0dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:layout_weight="1"
|
||||||
|
a:padding="5dip"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="fitCenter"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_5"
|
||||||
|
a:layout_width="0dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:layout_weight="1"
|
||||||
|
a:padding="5dip"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="fitCenter"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
a:id="@+id/download_visualizer_view_layout"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="60dip"
|
||||||
|
a:layout_gravity="center"
|
||||||
|
a:background="@color/translucent"
|
||||||
|
a:layout_marginLeft="80dip"
|
||||||
|
a:layout_marginRight="80dip"
|
||||||
|
a:orientation="vertical"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<include layout="@layout/download_playlist" />
|
<include layout="@layout/download_playlist" />
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/statusbar"
|
android:id="@+id/statusbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="128dp"
|
android:layout_height="150dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:background="@color/background_color_dark" >
|
android:background="@color/background_color_dark" >
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/notification_image"
|
android:id="@+id/notification_image"
|
||||||
android:layout_width="128dp"
|
android:layout_width="150dp"
|
||||||
android:layout_height="128dp"
|
android:layout_height="150dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
tools:background="#ff00ff"
|
tools:background="#ff00ff"
|
||||||
/>
|
/>
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:ellipsize="marquee"
|
android:ellipsize="marquee"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:maxLines="1"
|
android:singleLine="true"
|
||||||
tools:text="Track name"
|
tools:text="Track name"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -80,15 +80,75 @@
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
tools:text="Album"
|
tools:text="Album"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/notification_rating"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="30dip"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/notification_five_star_1"
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:focusable="false"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:scaleType="fitCenter" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/notification_five_star_2"
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:focusable="false"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:scaleType="fitCenter" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/notification_five_star_3"
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:focusable="false"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:scaleType="fitCenter" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/notification_five_star_4"
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:focusable="false"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:scaleType="fitCenter" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/notification_five_star_5"
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:focusable="false"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:scaleType="fitCenter" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:layout_marginTop="10dip"
|
android:layout_marginTop="5dip"
|
||||||
android:layout_marginBottom="10dip"
|
android:layout_marginBottom="10dip"
|
||||||
android:background="#DD696969"
|
android:background="#DD696969"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
|
@ -10,60 +10,59 @@
|
||||||
android:layout_height="4dip"
|
android:layout_height="4dip"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:background="@drawable/drop_shadow" />
|
android:background="@drawable/drop_shadow" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/now_playing_view"
|
android:id="@+id/now_playing_view"
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content" >
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/now_playing_image"
|
android:id="@+id/now_playing_image"
|
||||||
android:layout_width="64.0dip"
|
android:layout_width="64.0dip"
|
||||||
android:layout_height="64.0dip"
|
android:layout_height="64.0dip"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:gravity="center" />
|
android:gravity="center" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0.0dp"
|
android:layout_width="0.0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_weight="1.0"
|
android:layout_weight="1.0"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingLeft="11.0dip" >
|
android:paddingLeft="11.0dip">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/now_playing_trackname"
|
android:id="@+id/now_playing_trackname"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="left"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/now_playing_artist"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="left"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:scrollHorizontally="true"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/now_playing_control_play"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="left"
|
android:layout_gravity="center|right"
|
||||||
android:ellipsize="marquee"
|
android:layout_marginTop="2dip"
|
||||||
android:singleLine="true"
|
android:layout_marginRight="5dip"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
android:layout_weight="0.0"
|
||||||
android:textStyle="bold" />
|
android:focusable="false"
|
||||||
|
android:src="?attr/media_pause" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/now_playing_artist"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="left"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:scrollHorizontally="true"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/now_playing_control_play"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center|right"
|
|
||||||
android:layout_marginRight="5dip"
|
|
||||||
android:layout_marginTop="2dip"
|
|
||||||
android:layout_weight="0.0"
|
|
||||||
android:focusable="false"
|
|
||||||
android:src="?attr/media_pause" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -15,6 +15,66 @@
|
||||||
|
|
||||||
<include layout="@layout/song_details" />
|
<include layout="@layout/song_details" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
a:id="@+id/song_rating"
|
||||||
|
a:layout_width="wrap_content"
|
||||||
|
a:layout_height="wrap_content"
|
||||||
|
a:layout_gravity="center_vertical"
|
||||||
|
a:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_1"
|
||||||
|
a:layout_width="10dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="centerInside"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_2"
|
||||||
|
a:layout_width="10dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="centerInside"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_3"
|
||||||
|
a:layout_width="10dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="centerInside"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_4"
|
||||||
|
a:layout_width="10dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="centerInside"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/song_five_star_5"
|
||||||
|
a:layout_width="10dip"
|
||||||
|
a:layout_height="fill_parent"
|
||||||
|
a:background="@android:color/transparent"
|
||||||
|
a:focusable="false"
|
||||||
|
a:gravity="center_vertical"
|
||||||
|
a:scaleType="centerInside"
|
||||||
|
a:layout_marginRight="3dip"
|
||||||
|
a:src="?attr/star_hollow" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
a:id="@+id/song_star"
|
a:id="@+id/song_star"
|
||||||
a:layout_width="wrap_content"
|
a:layout_width="wrap_content"
|
||||||
|
|
|
@ -441,5 +441,9 @@
|
||||||
Actualmente no guarda la imagen en el almacenamiento del dispositivo y sólo utiliza caché en la memoria.
|
Actualmente no guarda la imagen en el almacenamiento del dispositivo y sólo utiliza caché en la memoria.
|
||||||
</string>
|
</string>
|
||||||
<string name="feature_flags_image_loader_title">Habilitar nuevo cargador de imágenes</string>
|
<string name="feature_flags_image_loader_title">Habilitar nuevo cargador de imágenes</string>
|
||||||
|
<string name="feature_flags_five_star_rating_title">Use cinco estrellas para las canciones.</string>
|
||||||
|
<string name="feature_flags_five_star_rating_description">Utilice el sistema de calificación de cinco estrellas para canciones
|
||||||
|
en lugar de simplemente destacar / desestimar elementos.
|
||||||
|
</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -442,6 +442,10 @@
|
||||||
Actuellement, il n\'enregistre pas l\'image dans le stockage de l\'appareil et n\'utilise que le cache en
|
Actuellement, il n\'enregistre pas l\'image dans le stockage de l\'appareil et n\'utilise que le cache en
|
||||||
mémoire.
|
mémoire.
|
||||||
</string>
|
</string>
|
||||||
|
<string name="feature_flags_five_star_rating_title">Utiliser une note de cinq étoiles pour les chansons</string>
|
||||||
|
<string name="feature_flags_five_star_rating_description">Utiliser un système de notation à cinq étoiles pour les chansons
|
||||||
|
au lieu de simplement mettre en vedette / désactiver les éléments.
|
||||||
|
</string>
|
||||||
<string name="feature_flags_category_title">Drapeaux des fonctionnalités</string>
|
<string name="feature_flags_category_title">Drapeaux des fonctionnalités</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -441,5 +441,9 @@
|
||||||
</string>
|
</string>
|
||||||
<string name="feature_flags_category_title">Jellemzők Zászlók</string>
|
<string name="feature_flags_category_title">Jellemzők Zászlók</string>
|
||||||
<string name="feature_flags_image_loader_title">Engedélyezzen új képbetöltőt</string>
|
<string name="feature_flags_image_loader_title">Engedélyezzen új képbetöltőt</string>
|
||||||
|
<string name="feature_flags_five_star_rating_title">Öt csillagos értékelés használata a dalokhoz</string>
|
||||||
|
<string name="feature_flags_five_star_rating_description">Öt csillag használata az értékeléshez az egyszerű
|
||||||
|
csillaggal jelölés helyett.
|
||||||
|
</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -442,5 +442,9 @@
|
||||||
Momenteel slaat het geen afbeeldingen op op de apparaatopslag en wordt alleen geheugencache gebruikt.
|
Momenteel slaat het geen afbeeldingen op op de apparaatopslag en wordt alleen geheugencache gebruikt.
|
||||||
</string>
|
</string>
|
||||||
<string name="feature_flags_category_title">Experimentele functies</string>
|
<string name="feature_flags_category_title">Experimentele functies</string>
|
||||||
|
<string name="feature_flags_five_star_rating_title">Gebruik vijf sterren voor nummers</string>
|
||||||
|
<string name="feature_flags_five_star_rating_description">Gebruik vijf sterren ratingsysteem voor liedjes
|
||||||
|
in plaats van items simpelweg in de hoofdrol te zetten / niet te verwijderen.
|
||||||
|
</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -455,5 +455,9 @@ ponieważ api Subsonic nie wspiera nowego sposobu autoryzacji dla użytkowników
|
||||||
<string name="feature_flags_image_loader_description">Włącza implementację modułu ładującego nowe obrazy.
|
<string name="feature_flags_image_loader_description">Włącza implementację modułu ładującego nowe obrazy.
|
||||||
Obecnie nie zapisuje obrazów w pamięci urządzenia, tylko wykorzystuje tylko pamięć podręczną.</string>
|
Obecnie nie zapisuje obrazów w pamięci urządzenia, tylko wykorzystuje tylko pamięć podręczną.</string>
|
||||||
<string name="feature_flags_category_title">Flagi funkcji</string>
|
<string name="feature_flags_category_title">Flagi funkcji</string>
|
||||||
|
<string name="feature_flags_five_star_rating_title">Użyj pięciu gwiazdek dla utworów</string>
|
||||||
|
<string name="feature_flags_five_star_rating_description">W przypadku utworów użyj systemu pięciu gwiazdek
|
||||||
|
zamiast po prostu grać gwiazdkami / bez gwiazd.
|
||||||
|
</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -441,5 +441,9 @@
|
||||||
</string>
|
</string>
|
||||||
<string name="feature_flags_category_title">Bandeiras de recursos</string>
|
<string name="feature_flags_category_title">Bandeiras de recursos</string>
|
||||||
<string name="feature_flags_image_loader_title">Ativar novo carregador de imagens</string>
|
<string name="feature_flags_image_loader_title">Ativar novo carregador de imagens</string>
|
||||||
|
<string name="feature_flags_five_star_rating_title">Use classificação de cinco estrelas para músicas</string>
|
||||||
|
<string name="feature_flags_five_star_rating_description">Use o sistema de classificação de cinco estrelas para músicas
|
||||||
|
em vez de simplesmente estrelar / não estrelar itens.
|
||||||
|
</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -441,5 +441,9 @@
|
||||||
</string>
|
</string>
|
||||||
<string name="feature_flags_category_title">Bandeiras de recursos</string>
|
<string name="feature_flags_category_title">Bandeiras de recursos</string>
|
||||||
<string name="feature_flags_image_loader_title">Ativar novo carregador de imagens</string>
|
<string name="feature_flags_image_loader_title">Ativar novo carregador de imagens</string>
|
||||||
|
<string name="feature_flags_five_star_rating_title">Use classificação de cinco estrelas para músicas</string>
|
||||||
|
<string name="feature_flags_five_star_rating_description">Use o sistema de classificação de cinco estrelas para músicas
|
||||||
|
em vez de simplesmente estrelar / não estrelar itens.
|
||||||
|
</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -445,6 +445,10 @@
|
||||||
<string name="feature_flags_image_loader_description">Enables new image loader implementation.
|
<string name="feature_flags_image_loader_description">Enables new image loader implementation.
|
||||||
Currently it doesn\'t save image in device storage and uses only cache in memory.
|
Currently it doesn\'t save image in device storage and uses only cache in memory.
|
||||||
</string>
|
</string>
|
||||||
|
<string name="feature_flags_five_star_rating_title">Use five star rating for songs</string>
|
||||||
|
<string name="feature_flags_five_star_rating_description">Use five star rating system for songs
|
||||||
|
instead of simply starring/unstarring items.
|
||||||
|
</string>
|
||||||
<string name="feature_flags_category_title">Feature Flags</string>
|
<string name="feature_flags_category_title">Feature Flags</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -291,6 +291,12 @@
|
||||||
a:title="@string/feature_flags_image_loader_title"
|
a:title="@string/feature_flags_image_loader_title"
|
||||||
a:summary="@string/feature_flags_image_loader_description"
|
a:summary="@string/feature_flags_image_loader_description"
|
||||||
/>
|
/>
|
||||||
|
<CheckBoxPreference
|
||||||
|
a:key="use_five_star_rating"
|
||||||
|
a:persistent="false"
|
||||||
|
a:title="@string/feature_flags_five_star_rating_title"
|
||||||
|
a:summary="@string/feature_flags_five_star_rating_description"
|
||||||
|
/>
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class APIMusicDirectoryConverterTest {
|
||||||
transcodedSuffix = "some-transcoded-suffix", duration = 11, bitRate = 256,
|
transcodedSuffix = "some-transcoded-suffix", duration = 11, bitRate = 256,
|
||||||
path = "some-path", isDir = true, isVideo = true, playCount = 323, discNumber = 2,
|
path = "some-path", isDir = true, isVideo = true, playCount = 323, discNumber = 2,
|
||||||
created = Calendar.getInstance(), type = "some-type",
|
created = Calendar.getInstance(), type = "some-type",
|
||||||
starred = Calendar.getInstance())
|
starred = Calendar.getInstance(), userRating = 3, averageRating = 2.99F)
|
||||||
|
|
||||||
val convertedEntity = entity.toDomainEntity()
|
val convertedEntity = entity.toDomainEntity()
|
||||||
|
|
||||||
|
@ -69,6 +69,8 @@ class APIMusicDirectoryConverterTest {
|
||||||
starred `should be equal to` (entity.starred != null)
|
starred `should be equal to` (entity.starred != null)
|
||||||
discNumber `should equal` entity.discNumber
|
discNumber `should equal` entity.discNumber
|
||||||
type `should equal` entity.type
|
type `should equal` entity.type
|
||||||
|
userRating `should equal` entity.userRating
|
||||||
|
averageRating `should equal` entity.averageRating
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue