aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKurt Hardin <kurthardin.dev@gmail.com>2012-08-29 13:25:20 -0700
committerKurt Hardin <kurthardin.dev@gmail.com>2012-08-29 13:25:20 -0700
commit9d2b9d39a1b43dc26d5598dab801198adbe42009 (patch)
treeeba153912e3f1821597916ef7e2896154bc349b2
parentd0e1ef7dca6fefa2815c1e633901cd369f938b63 (diff)
downloaddsub-9d2b9d39a1b43dc26d5598dab801198adbe42009.tar.gz
dsub-9d2b9d39a1b43dc26d5598dab801198adbe42009.tar.bz2
dsub-9d2b9d39a1b43dc26d5598dab801198adbe42009.zip
Added support for starring albums and songs.
Requires server version 4.7 (currently in beta) for star support. Currently the Subsonic APIs don't provide adequate star support when listing artists.
-rw-r--r--subsonic-android/res/layout-land/download.xml16
-rw-r--r--subsonic-android/res/layout-port/download.xml9
-rw-r--r--subsonic-android/res/layout/album_list_item.xml9
-rw-r--r--subsonic-android/res/layout/song_list_item.xml10
-rw-r--r--subsonic-android/res/values/strings.xml2
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java17
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/activity/SubsonicTabActivity.java42
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/domain/MusicDirectory.java9
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java5
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/service/MusicService.java2
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java5
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java11
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java1
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/util/AlbumView.java19
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/util/SongView.java18
15 files changed, 170 insertions, 5 deletions
diff --git a/subsonic-android/res/layout-land/download.xml b/subsonic-android/res/layout-land/download.xml
index 01a9b68d..b0303e52 100644
--- a/subsonic-android/res/layout-land/download.xml
+++ b/subsonic-android/res/layout-land/download.xml
@@ -14,15 +14,15 @@
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
- android:background="@color/mediaControlBackground"
- >
+ android:background="@color/mediaControlBackground">
<LinearLayout
+ android:id="@+id/download_play_controls_layout"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
- android:layout_alignParentLeft="true">
+ android:layout_centerHorizontal="true">
<ImageButton
android:id="@+id/download_previous"
@@ -87,7 +87,6 @@
android:id="@+id/download_song_title"
android:layout_width="150dip"
android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
android:layout_above="@+id/download_status"
android:layout_centerHorizontal="true"
android:layout_marginLeft="12dip"
@@ -99,6 +98,7 @@
android:textColor="@color/mediaControlForeground"/>
<LinearLayout
+ android:id="@+id/download_other_controls_layout"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -111,6 +111,7 @@
android:background="@android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_below="@+id/download_play_controls_layout"
android:padding="9dip"/>
<ImageButton
android:id="@+id/download_repeat"
@@ -120,6 +121,13 @@
android:layout_height="wrap_content"
android:padding="9dip"/>
<ImageButton
+ android:id="@+id/download_star"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:background="@null"
+ android:src="@android:drawable/star_big_off"/>
+ <ImageButton
android:id="@+id/download_toggle_list"
android:src="@drawable/media_toggle_list"
android:background="@android:color/transparent"
diff --git a/subsonic-android/res/layout-port/download.xml b/subsonic-android/res/layout-port/download.xml
index e2a198a2..e6a2358a 100644
--- a/subsonic-android/res/layout-port/download.xml
+++ b/subsonic-android/res/layout-port/download.xml
@@ -72,6 +72,15 @@
android:paddingTop="12dip"
android:paddingRight="12dip"
android:paddingBottom="12dip"/>
+
+ <ImageButton
+ android:id="@+id/download_star"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignRight="@+id/download_repeat"
+ android:layout_below="@+id/download_jukebox"
+ android:background="@null"
+ android:src="@android:drawable/star_big_off"/>
<ImageView
android:id="@+id/download_album_art_image"
diff --git a/subsonic-android/res/layout/album_list_item.xml b/subsonic-android/res/layout/album_list_item.xml
index 15d999c3..aa2ac803 100644
--- a/subsonic-android/res/layout/album_list_item.xml
+++ b/subsonic-android/res/layout/album_list_item.xml
@@ -36,6 +36,15 @@
android:singleLine="true"/>
</LinearLayout>
+
+ <ImageButton
+ android:id="@+id/album_star"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right|center_vertical"
+ android:background="@null"
+ android:focusable="false"
+ android:src="@android:drawable/star_big_off" />
<ImageView
android:src="@drawable/list_item_artist"
diff --git a/subsonic-android/res/layout/song_list_item.xml b/subsonic-android/res/layout/song_list_item.xml
index 2163ef72..87f56a22 100644
--- a/subsonic-android/res/layout/song_list_item.xml
+++ b/subsonic-android/res/layout/song_list_item.xml
@@ -73,4 +73,14 @@
</LinearLayout>
</LinearLayout>
+
+ <ImageButton
+ android:id="@+id/song_star"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right|center_vertical"
+ android:background="@null"
+ android:focusable="false"
+ android:src="@android:drawable/btn_star_big_off" />
+
</LinearLayout>
diff --git a/subsonic-android/res/values/strings.xml b/subsonic-android/res/values/strings.xml
index 7f9f6728..eef510e4 100644
--- a/subsonic-android/res/values/strings.xml
+++ b/subsonic-android/res/values/strings.xml
@@ -110,6 +110,8 @@
<string name="download.jukebox_server_too_old">Remote control is not supported. Please upgrade your Subsonic server.</string>
<string name="download.jukebox_offline">Remote control is not available in offline mode.</string>
<string name="download.jukebox_not_authorized">Remote control is not allowed. Please enable jukebox mode in <b>Users &gt; Settings</b> on your Subsonic server.</string>
+
+ <string name="starring_content_error">Failed to update \"%s\", please try later.</string>
<string name="song_details.all">%1$s %2$s</string>
<string name="song_details.kbps">%d kbps</string>
diff --git a/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java
index a657b7eb..04d710d5 100644
--- a/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java
+++ b/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java
@@ -45,6 +45,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
@@ -106,6 +107,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
private Button visualizerButton;
private Button jukeboxButton;
private View toggleListButton;
+ private ImageButton starButton;
private ScheduledExecutorService executorService;
private DownloadFile currentPlaying;
private long currentRevision;
@@ -154,6 +156,19 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
LinearLayout visualizerViewLayout = (LinearLayout) findViewById(R.id.download_visualizer_view_layout);
toggleListButton = findViewById(R.id.download_toggle_list);
+
+ starButton = (ImageButton) findViewById(R.id.download_star);
+ starButton.setVisibility(Util.isOffline(this) ? View.GONE : View.VISIBLE);
+ starButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ DownloadFile currentDownload = getDownloadService().getCurrentPlaying();
+ if (currentDownload != null) {
+ MusicDirectory.Entry currentSong = currentDownload.getSong();
+ toggleStarredInBackground(currentSong, starButton);
+ }
+ }
+ });
View.OnTouchListener touchListener = new View.OnTouchListener() {
@Override
@@ -711,11 +726,13 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
albumTextView.setText(song.getAlbum());
artistTextView.setText(song.getArtist());
getImageLoader().loadImage(albumArtImageView, song, true, true);
+ starButton.setImageResource(song.isStarred() ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
} else {
songTitleTextView.setText(null);
albumTextView.setText(null);
artistTextView.setText(null);
getImageLoader().loadImage(albumArtImageView, null, true, false);
+ starButton.setImageResource(android.R.drawable.btn_star_big_off);
}
}
diff --git a/subsonic-android/src/github/daneren2005/dsub/activity/SubsonicTabActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/SubsonicTabActivity.java
index 6afe842b..e3548302 100644
--- a/subsonic-android/src/github/daneren2005/dsub/activity/SubsonicTabActivity.java
+++ b/subsonic-android/src/github/daneren2005/dsub/activity/SubsonicTabActivity.java
@@ -39,6 +39,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
+import android.widget.ImageButton;
import android.widget.TextView;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.domain.MusicDirectory;
@@ -46,9 +47,12 @@ import github.daneren2005.dsub.service.DownloadService;
import github.daneren2005.dsub.service.DownloadServiceImpl;
import github.daneren2005.dsub.service.MusicService;
import github.daneren2005.dsub.service.MusicServiceFactory;
+import github.daneren2005.dsub.service.OfflineException;
+import github.daneren2005.dsub.service.ServerTooOldException;
import github.daneren2005.dsub.util.Constants;
import github.daneren2005.dsub.util.ImageLoader;
import github.daneren2005.dsub.util.ModalBackgroundTask;
+import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.util.Util;
/**
@@ -227,6 +231,44 @@ public class SubsonicTabActivity extends Activity {
private void updateButtonVisibility() {
int visibility = Util.isOffline(this) ? View.GONE : View.VISIBLE;
}
+
+ public void toggleStarredInBackground(final MusicDirectory.Entry entry, final ImageButton button) {
+
+ final boolean starred = !entry.isStarred();
+
+ button.setImageResource(starred ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
+ entry.setStarred(starred);
+
+ // Util.toast(SubsonicTabActivity.this, getResources().getString(R.string.starring_content, entry.getTitle()));
+ new SilentBackgroundTask<Void>(this) {
+ @Override
+ protected Void doInBackground() throws Throwable {
+ MusicService musicService = MusicServiceFactory.getMusicService(SubsonicTabActivity.this);
+ musicService.setStarred(entry.getId(), starred, SubsonicTabActivity.this, null);
+ return null;
+ }
+
+ @Override
+ protected void done(Void result) {
+ // Util.toast(SubsonicTabActivity.this, getResources().getString(R.string.starring_content_done, entry.getTitle()));
+ }
+
+ @Override
+ protected void error(Throwable error) {
+ button.setImageResource(!starred ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
+ entry.setStarred(!starred);
+
+ String msg;
+ if (error instanceof OfflineException || error instanceof ServerTooOldException) {
+ msg = getErrorMessage(error);
+ } else {
+ msg = getResources().getString(R.string.starring_content_error, entry.getTitle()) + " " + getErrorMessage(error);
+ }
+
+ Util.toast(SubsonicTabActivity.this, msg, false);
+ }
+ }.execute();
+ }
public void setProgressVisible(boolean visible) {
View view = findViewById(R.id.tab_progress);
diff --git a/subsonic-android/src/github/daneren2005/dsub/domain/MusicDirectory.java b/subsonic-android/src/github/daneren2005/dsub/domain/MusicDirectory.java
index 420ce813..da0d8cbc 100644
--- a/subsonic-android/src/github/daneren2005/dsub/domain/MusicDirectory.java
+++ b/subsonic-android/src/github/daneren2005/dsub/domain/MusicDirectory.java
@@ -80,6 +80,7 @@ public class MusicDirectory {
private Integer bitRate;
private String path;
private boolean video;
+ private boolean starred;
public String getId() {
return id;
@@ -232,6 +233,14 @@ public class MusicDirectory {
public void setVideo(boolean video) {
this.video = video;
}
+
+ public boolean isStarred() {
+ return starred;
+ }
+
+ public void setStarred(boolean starred) {
+ this.starred = starred;
+ }
@Override
public boolean equals(Object o) {
diff --git a/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java
index 094c959f..dbd421f2 100644
--- a/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java
+++ b/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java
@@ -222,6 +222,11 @@ public class CachedMusicService implements MusicService {
public JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception {
return musicService.setJukeboxGain(gain, context, progressListener);
}
+
+ @Override
+ public void setStarred(String id, boolean starred, Context context, ProgressListener progressListener) throws Exception {
+ musicService.setStarred(id, starred, context, progressListener);
+ }
private void checkSettingsChanged(Context context) {
String newUrl = Util.getRestUrl(context, null);
diff --git a/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java
index e8fca8f0..a5045b18 100644
--- a/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java
+++ b/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java
@@ -88,4 +88,6 @@ public interface MusicService {
JukeboxStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception;
JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception;
+
+ void setStarred(String id, boolean starred, Context context, ProgressListener progressListener) throws Exception;
} \ No newline at end of file
diff --git a/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java
index 9c49d550..29992029 100644
--- a/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java
+++ b/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java
@@ -308,6 +308,11 @@ public class OfflineMusicService extends RESTMusicService {
public JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception {
throw new OfflineException("Jukebox not available in offline mode");
}
+
+ @Override
+ public void setStarred(String id, boolean starred, Context context, ProgressListener progressListener) throws Exception {
+ throw new OfflineException("Starring not available in offline mode");
+ }
@Override
public MusicDirectory getRandomSongs(int size, Context context, ProgressListener progressListener) throws Exception {
diff --git a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java
index 748eacee..c24b2c06 100644
--- a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java
+++ b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java
@@ -602,6 +602,17 @@ public class RESTMusicService implements MusicService {
Util.close(reader);
}
}
+
+ @Override
+ public void setStarred(String id, boolean starred, Context context, ProgressListener progressListener) throws Exception {
+ checkServerVersion(context, "1.8", "Starring is not supported.");
+ Reader reader = getReader(context, progressListener, starred ? "star" : "unstar", null, "id", id);
+ try {
+ new ErrorParser(context).parse(reader);
+ } finally {
+ Util.close(reader);
+ }
+ }
private Reader getReader(Context context, ProgressListener progressListener, String method, HttpParams requestParams) throws Exception {
return getReader(context, progressListener, method, requestParams, Collections.<String>emptyList(), Collections.emptyList());
diff --git a/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java b/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java
index 3a1826e5..d724f63c 100644
--- a/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java
+++ b/subsonic-android/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java
@@ -38,6 +38,7 @@ public class MusicDirectoryEntryParser extends AbstractParser {
entry.setDirectory(getBoolean("isDir"));
entry.setCoverArt(get("coverArt"));
entry.setArtist(get("artist"));
+ entry.setStarred(get("starred") != null);
if (!entry.isDirectory()) {
entry.setAlbum(get("album"));
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/AlbumView.java b/subsonic-android/src/github/daneren2005/dsub/util/AlbumView.java
index 98bd500f..8c799aad 100644
--- a/subsonic-android/src/github/daneren2005/dsub/util/AlbumView.java
+++ b/subsonic-android/src/github/daneren2005/dsub/util/AlbumView.java
@@ -21,9 +21,11 @@ package github.daneren2005.dsub.util;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
+import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import github.daneren2005.dsub.R;
+import github.daneren2005.dsub.activity.SubsonicTabActivity;
import github.daneren2005.dsub.domain.MusicDirectory;
/**
@@ -32,10 +34,13 @@ import github.daneren2005.dsub.domain.MusicDirectory;
* @author Sindre Mehus
*/
public class AlbumView extends LinearLayout {
+
+ private MusicDirectory.Entry album;
private TextView titleView;
private TextView artistView;
private View coverArtView;
+ private ImageButton starButton;
public AlbumView(Context context) {
super(context);
@@ -44,12 +49,26 @@ public class AlbumView extends LinearLayout {
titleView = (TextView) findViewById(R.id.album_title);
artistView = (TextView) findViewById(R.id.album_artist);
coverArtView = findViewById(R.id.album_coverart);
+ starButton = (ImageButton) findViewById(R.id.album_star);
+ starButton.setVisibility(Util.isOffline(getContext()) ? View.GONE : View.VISIBLE);
+ starButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ SubsonicTabActivity activity = (SubsonicTabActivity) getContext();
+ activity.toggleStarredInBackground(album, starButton);
+ }
+ });
}
public void setAlbum(MusicDirectory.Entry album, ImageLoader imageLoader) {
+ this.album = album;
+
titleView.setText(album.getTitle());
artistView.setText(album.getArtist());
artistView.setVisibility(album.getArtist() == null ? View.GONE : View.VISIBLE);
imageLoader.loadImage(coverArtView, album, false, true);
+
+ starButton.setImageResource(album.isStarred() ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
+ starButton.setFocusable(false);
}
}
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/SongView.java b/subsonic-android/src/github/daneren2005/dsub/util/SongView.java
index 61846c27..1bc2b9c0 100644
--- a/subsonic-android/src/github/daneren2005/dsub/util/SongView.java
+++ b/subsonic-android/src/github/daneren2005/dsub/util/SongView.java
@@ -25,9 +25,11 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.Checkable;
import android.widget.CheckedTextView;
+import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import github.daneren2005.dsub.R;
+import github.daneren2005.dsub.activity.SubsonicTabActivity;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.service.DownloadService;
import github.daneren2005.dsub.service.DownloadServiceImpl;
@@ -46,13 +48,15 @@ public class SongView extends LinearLayout implements Checkable {
private static final String TAG = SongView.class.getSimpleName();
private static final WeakHashMap<SongView, ?> INSTANCES = new WeakHashMap<SongView, Object>();
private static Handler handler;
+
+ private MusicDirectory.Entry song;
private CheckedTextView checkedTextView;
private TextView titleTextView;
private TextView artistTextView;
private TextView durationTextView;
private TextView statusTextView;
- private MusicDirectory.Entry song;
+ private ImageButton starButton;
public SongView(Context context) {
super(context);
@@ -63,6 +67,15 @@ public class SongView extends LinearLayout implements Checkable {
artistTextView = (TextView) findViewById(R.id.song_artist);
durationTextView = (TextView) findViewById(R.id.song_duration);
statusTextView = (TextView) findViewById(R.id.song_status);
+ starButton = (ImageButton) findViewById(R.id.song_star);
+ starButton.setVisibility(Util.isOffline(getContext()) ? View.GONE : View.VISIBLE);
+ starButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ SubsonicTabActivity activity = (SubsonicTabActivity) getContext();
+ activity.toggleStarredInBackground(song, starButton);
+ }
+ });
INSTANCES.put(this, null);
int instanceCount = INSTANCES.size();
@@ -96,6 +109,9 @@ public class SongView extends LinearLayout implements Checkable {
artistTextView.setText(artist);
durationTextView.setText(Util.formatDuration(song.getDuration()));
checkedTextView.setVisibility(checkable && !song.isVideo() ? View.VISIBLE : View.GONE);
+
+ starButton.setImageResource(song.isStarred() ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
+ starButton.setFocusable(false);
update();
}