diff options
author | Kurt Hardin <kurthardin.dev@gmail.com> | 2012-09-25 11:56:19 -0700 |
---|---|---|
committer | Kurt Hardin <kurthardin.dev@gmail.com> | 2012-09-25 11:56:19 -0700 |
commit | d82f52f410c696ea8bbf39789752a8349f385722 (patch) | |
tree | 918d074cfa27ad69c62f6ab041599bb64484f8fa /subsonic-android/src/github | |
parent | 2be1e2632966490e9d1b0cde7bb51f1951710794 (diff) | |
parent | 50cbd5040bfecfbad8b46694be17e6b793094c43 (diff) | |
download | dsub-d82f52f410c696ea8bbf39789752a8349f385722.tar.gz dsub-d82f52f410c696ea8bbf39789752a8349f385722.tar.bz2 dsub-d82f52f410c696ea8bbf39789752a8349f385722.zip |
Merge branch 'master_star_support'
Diffstat (limited to 'subsonic-android/src/github')
13 files changed, 219 insertions, 3 deletions
diff --git a/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java index baee66fa..eefe03a8 100644 --- a/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java +++ b/subsonic-android/src/github/daneren2005/dsub/activity/DownloadActivity.java @@ -42,6 +42,7 @@ import android.view.GestureDetector.OnGestureListener; import android.view.LayoutInflater; 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; @@ -157,6 +159,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 @@ -714,11 +729,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/MainActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/MainActivity.java index 2fab77e7..23b1ba0d 100644 --- a/subsonic-android/src/github/daneren2005/dsub/activity/MainActivity.java +++ b/subsonic-android/src/github/daneren2005/dsub/activity/MainActivity.java @@ -79,6 +79,7 @@ public class MainActivity extends SubsonicTabActivity { final View albumsHighestButton = buttons.findViewById(R.id.main_albums_highest); final View albumsRecentButton = buttons.findViewById(R.id.main_albums_recent); final View albumsFrequentButton = buttons.findViewById(R.id.main_albums_frequent); + final View albumsStarredButton = buttons.findViewById(R.id.main_albums_starred); final View dummyView = findViewById(R.id.main_dummy); @@ -92,7 +93,7 @@ public class MainActivity extends SubsonicTabActivity { adapter.addViews(Arrays.asList(serverButton), true); if (!Util.isOffline(this)) { adapter.addView(albumsTitle, false); - adapter.addViews(Arrays.asList(albumsNewestButton, albumsRandomButton, albumsHighestButton, albumsRecentButton, albumsFrequentButton), true); + adapter.addViews(Arrays.asList(albumsNewestButton, albumsRandomButton, albumsHighestButton, albumsStarredButton, albumsRecentButton, albumsFrequentButton), true); } list.setAdapter(adapter); registerForContextMenu(dummyView); @@ -108,6 +109,8 @@ public class MainActivity extends SubsonicTabActivity { showAlbumList("random"); } else if (view == albumsHighestButton) { showAlbumList("highest"); + } else if (view == albumsStarredButton) { + showAlbumList("starred"); } else if (view == albumsRecentButton) { showAlbumList("recent"); } else if (view == albumsFrequentButton) { diff --git a/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java index b0c47a5e..ce88b5e3 100644 --- a/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java +++ b/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java @@ -305,7 +305,13 @@ public class SelectAlbumActivity extends SubsonicTabActivity { new LoadTask() { @Override protected MusicDirectory load(MusicService service) throws Exception { - return service.getAlbumList(albumListType, size, offset, SelectAlbumActivity.this, this); + MusicDirectory result; + if ("starred".equals(albumListType)) { + result = service.getStarredList(SelectAlbumActivity.this, this); + } else { + result = service.getAlbumList(albumListType, size, offset, SelectAlbumActivity.this, this); + } + return result; } @Override diff --git a/subsonic-android/src/github/daneren2005/dsub/activity/SubsonicTabActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/SubsonicTabActivity.java index 9b1ab55e..178d2b37 100644 --- a/subsonic-android/src/github/daneren2005/dsub/activity/SubsonicTabActivity.java +++ b/subsonic-android/src/github/daneren2005/dsub/activity/SubsonicTabActivity.java @@ -36,6 +36,7 @@ import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.Window; +import android.widget.ImageButton; import android.widget.TextView; import github.daneren2005.dsub.R; import com.actionbarsherlock.app.ActionBar; @@ -45,9 +46,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; /** @@ -197,6 +201,44 @@ public class SubsonicTabActivity extends SherlockActivity { 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..832b2037 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java @@ -164,6 +164,11 @@ public class CachedMusicService implements MusicService { } @Override + public MusicDirectory getStarredList(Context context, ProgressListener progressListener) throws Exception { + return musicService.getStarredList(context, progressListener); + } + + @Override public MusicDirectory getRandomSongs(int size, Context context, ProgressListener progressListener) throws Exception { return musicService.getRandomSongs(size, context, progressListener); } @@ -222,6 +227,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..15abbdf8 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java @@ -53,6 +53,8 @@ public interface MusicService { SearchResult search(SearchCritera criteria, Context context, ProgressListener progressListener) throws Exception; + MusicDirectory getStarredList(Context context, ProgressListener progressListener) throws Exception; + MusicDirectory getPlaylist(String id, String name, Context context, ProgressListener progressListener) throws Exception; List<Playlist> getPlaylists(boolean refresh, Context context, ProgressListener progressListener) throws Exception; @@ -88,4 +90,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..1ef65bb8 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java @@ -93,6 +93,7 @@ import github.daneren2005.dsub.service.parser.PlaylistsParser; import github.daneren2005.dsub.service.parser.RandomSongsParser; import github.daneren2005.dsub.service.parser.SearchResult2Parser; import github.daneren2005.dsub.service.parser.SearchResultParser; +import github.daneren2005.dsub.service.parser.StarredListParser; import github.daneren2005.dsub.service.parser.VersionParser; import github.daneren2005.dsub.service.ssl.SSLSocketFactory; import github.daneren2005.dsub.service.ssl.TrustSelfSignedStrategy; @@ -415,6 +416,16 @@ public class RESTMusicService implements MusicService { } @Override + public MusicDirectory getStarredList(Context context, ProgressListener progressListener) throws Exception { + Reader reader = getReader(context, progressListener, "getStarred", null); + try { + return new StarredListParser(context).parse(reader, progressListener); + } finally { + Util.close(reader); + } + } + + @Override public MusicDirectory getRandomSongs(int size, Context context, ProgressListener progressListener) throws Exception { HttpParams params = new BasicHttpParams(); HttpConnectionParams.setSoTimeout(params, SOCKET_READ_TIMEOUT_GET_RANDOM_SONGS); @@ -602,6 +613,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/service/parser/StarredListParser.java b/subsonic-android/src/github/daneren2005/dsub/service/parser/StarredListParser.java new file mode 100644 index 00000000..c3c16949 --- /dev/null +++ b/subsonic-android/src/github/daneren2005/dsub/service/parser/StarredListParser.java @@ -0,0 +1,62 @@ +/* + This file is part of Subsonic. + + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Subsonic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see <http://www.gnu.org/licenses/>. + + Copyright 2009 (C) Sindre Mehus + */ +package github.daneren2005.dsub.service.parser; + +import android.content.Context; +import github.daneren2005.dsub.R; +import github.daneren2005.dsub.domain.MusicDirectory; +import github.daneren2005.dsub.util.ProgressListener; +import org.xmlpull.v1.XmlPullParser; + +import java.io.Reader; + +/** + * @author Kurt Hardin + */ +public class StarredListParser extends MusicDirectoryEntryParser { + + public StarredListParser(Context context) { + super(context); + } + + public MusicDirectory parse(Reader reader, ProgressListener progressListener) throws Exception { + + updateProgress(progressListener, R.string.parser_reading); + init(reader); + + MusicDirectory dir = new MusicDirectory(); + int eventType; + do { + eventType = nextParseEvent(); + if (eventType == XmlPullParser.START_TAG) { + String name = getElementName(); + if ("album".equals(name) || "song".equals(name)) { + dir.addChild(parseEntry()); + } else if ("error".equals(name)) { + handleError(); + } + } + } while (eventType != XmlPullParser.END_DOCUMENT); + + validate(); + updateProgress(progressListener, R.string.parser_reading_done); + + return dir; + } +}
\ No newline at end of file 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(); } |