diff options
Diffstat (limited to 'subsonic-android/patches')
-rw-r--r-- | subsonic-android/patches/jukebox-patch.txt | 1234 |
1 files changed, 0 insertions, 1234 deletions
diff --git a/subsonic-android/patches/jukebox-patch.txt b/subsonic-android/patches/jukebox-patch.txt deleted file mode 100644 index cbbeb40b..00000000 --- a/subsonic-android/patches/jukebox-patch.txt +++ /dev/null @@ -1,1234 +0,0 @@ -Index: AndroidManifest.xml -=================================================================== ---- AndroidManifest.xml (revision 2441) -+++ AndroidManifest.xml (working copy) -@@ -114,7 +114,8 @@ - a:authorities="github.daneren2005.dsub.provider.SearchSuggestionProvider"/> - - <meta-data a:name="android.app.default_searchable" -- a:value="github.daneren2005.dsub.activity.QueryReceiverActivity"/> -+ a:value="github.daneren2005.dsub.activity.QueryReceiverActivity"/> -+ <activity a:name="github.daneren2005.dsub.activity.JukeboxActivity" a:launchMode="singleTask" a:configChanges="keyboardHidden"></activity> - - </application> - -Index: res/drawable/menu_jukebox.png -=================================================================== -Cannot display: file marked as a binary type. -svn:mime-type = application/octet-stream - -Property changes on: res/drawable/menu_jukebox.png -___________________________________________________________________ -Added: svn:mime-type - + application/octet-stream - -Index: res/drawable-hdpi-v4/menu_jukebox.png -=================================================================== -Cannot display: file marked as a binary type. -svn:mime-type = application/octet-stream - -Property changes on: res/drawable-hdpi-v4/menu_jukebox.png -___________________________________________________________________ -Added: svn:mime-type - + application/octet-stream - -Index: res/layout/button_bar.xml -=================================================================== ---- res/layout/button_bar.xml (revision 2441) -+++ res/layout/button_bar.xml (working copy) -@@ -47,6 +47,14 @@ - a:layout_weight="1" - a:layout_width="0dp" - a:layout_height="wrap_content"/> -+ -+ <ImageButton a:id="@+id/button_bar_jukebox" -+ a:src="@drawable/menu_jukebox" -+ a:contentDescription="@string/button_bar.jukebox" -+ a:background="@drawable/menubar_button" -+ a:layout_weight="1" -+ a:layout_width="0dp" -+ a:layout_height="wrap_content"/> - - <ImageButton a:id="@+id/button_bar_now_playing" - a:src="@drawable/menu_now_playing" -Index: res/layout/jukebox.xml -=================================================================== ---- res/layout/jukebox.xml (revision 0) -+++ res/layout/jukebox.xml (revision 0) -@@ -0,0 +1,72 @@ -+<?xml version="1.0" encoding="utf-8"?> -+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" -+ a:layout_width="fill_parent" -+ a:layout_height="fill_parent" -+ a:orientation="vertical" > -+ -+ <include layout="@layout/tab_progress"/> -+ -+ <ListView -+ a:id="@+id/jukebox_list" -+ a:layout_width="match_parent" -+ a:layout_height="0dp" -+ a:layout_weight="1" > -+ </ListView> -+ -+ <LinearLayout -+ a:layout_width="fill_parent" -+ a:layout_height="wrap_content" -+ a:layout_marginTop="0dip" -+ a:background="@color/mediaControlBackground" -+ a:gravity="center" -+ a:orientation="horizontal" -+ a:paddingBottom="0dip" -+ a:paddingTop="0dip" > -+ -+ <ImageButton -+ a:id="@+id/jukebox_shuffle" -+ a:layout_width="wrap_content" -+ a:layout_height="fill_parent" -+ a:background="@android:color/transparent" -+ a:src="@drawable/media_shuffle" /> -+ -+ <ImageButton -+ a:id="@+id/jukebox_previous" -+ a:layout_width="wrap_content" -+ a:layout_height="wrap_content" -+ a:background="@android:color/transparent" -+ a:padding="0dip" -+ a:src="@drawable/media_backward" /> -+ -+ <ImageButton -+ a:id="@+id/jukebox_stop" -+ a:layout_width="60dip" -+ a:layout_height="60dip" -+ a:padding="0dip" -+ a:background="@drawable/media_stop" /> -+ -+ <ImageButton -+ a:id="@+id/jukebox_start" -+ a:layout_width="60dip" -+ a:layout_height="60dip" -+ a:padding="0dip" -+ a:background="@drawable/media_start" /> -+ -+ <ImageButton -+ a:id="@+id/jukebox_next" -+ a:layout_width="wrap_content" -+ a:layout_height="wrap_content" -+ a:background="@android:color/transparent" -+ a:padding="0dip" -+ a:src="@drawable/media_forward" /> -+ </LinearLayout> -+ -+ <SeekBar -+ a:id="@+id/jukebox_seek" -+ a:background="@color/mediaControlBackground" -+ a:layout_width="match_parent" -+ a:layout_height="wrap_content" /> -+ -+ <include layout="@layout/button_bar" /> -+ -+</LinearLayout> -\ No newline at end of file -Index: res/menu/jukebox_context.xml -=================================================================== ---- res/menu/jukebox_context.xml (revision 0) -+++ res/menu/jukebox_context.xml (revision 0) -@@ -0,0 +1,8 @@ -+<?xml version="1.0" encoding="utf-8"?> -+<menu xmlns:android="http://schemas.android.com/apk/res/android" > -+ <item android:id="@+id/jukebox_clear" android:title="@string/jukebox_clear"></item> -+ <item android:id="@+id/jukebox_remove" android:title="@string/jukebox_remove"></item> -+ -+ -+ -+</menu> -\ No newline at end of file -Index: res/menu/select_album_context.xml -=================================================================== ---- res/menu/select_album_context.xml (revision 2441) -+++ res/menu/select_album_context.xml (working copy) -@@ -15,5 +15,6 @@ - a:id="@+id/album_menu_pin" - a:title="@string/common.pin" - /> -+ <item a:id="@+id/album_menu_jukebox_add" a:title="@string/jukebox_add"></item> - - </menu> -Index: res/menu/select_artist_context.xml -=================================================================== ---- res/menu/select_artist_context.xml (revision 2441) -+++ res/menu/select_artist_context.xml (working copy) -@@ -15,5 +15,6 @@ - a:id="@+id/artist_menu_pin" - a:title="@string/common.pin" - /> -+ <item a:id="@+id/artist_menu_jukebox_add" a:title="@string/jukebox_add"></item> - - </menu> -Index: res/menu/select_song_context.xml -=================================================================== ---- res/menu/select_song_context.xml (revision 2441) -+++ res/menu/select_song_context.xml (working copy) -@@ -15,5 +15,10 @@ - a:id="@+id/song_menu_play_last" - a:title="@string/common.play_last" - /> -+ -+ <item -+ a:id="@+id/song_menu_jukebox_add" -+ a:title="@string/jukebox_add" -+ /> - - </menu> -Index: res/values/strings.xml -=================================================================== ---- res/values/strings.xml (revision 2441) -+++ res/values/strings.xml (working copy) -@@ -226,6 +226,14 @@ - <plurals name="select_album_donate_dialog_n_trial_days_left"> - <item quantity="one">One day left of trial period</item> - <item quantity="other">%d days left of trial period</item> -- </plurals> -+ </plurals> -+ <string name="button_bar.jukebox">Jukebox</string> -+ <string name="jukebox_start">Start</string> -+ <string name="jukebox_stop">Stop</string> -+ <string name="jukebox_next">Next</string> -+ <string name="jukebox_previous">Previous</string> -+ <string name="jukebox_clear">Clear</string> -+ <string name="jukebox_remove">Remove</string> -+ <string name="jukebox_add">Add to Jukebox</string> - - </resources> -Index: src/net/sourceforge/subsonic/androidapp/activity/JukeboxActivity.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/activity/JukeboxActivity.java (revision 0) -+++ src/net/sourceforge/subsonic/androidapp/activity/JukeboxActivity.java (revision 0) -@@ -0,0 +1,235 @@ -+/* -+ 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.activity; -+ -+import java.util.List; -+ -+import github.daneren2005.dsub.R; -+import github.daneren2005.dsub.domain.Jukebox; -+import github.daneren2005.dsub.domain.MusicDirectory; -+import github.daneren2005.dsub.domain.MusicDirectory.Entry; -+import github.daneren2005.dsub.service.MusicService; -+import github.daneren2005.dsub.service.MusicServiceFactory; -+import github.daneren2005.dsub.util.BackgroundTask; -+import github.daneren2005.dsub.util.JukeboxSongView; -+import github.daneren2005.dsub.util.ProgressListener; -+import github.daneren2005.dsub.util.TabActivityBackgroundTask; -+import github.daneren2005.dsub.util.Util; -+import android.os.Bundle; -+import android.view.ContextMenu; -+import android.view.MenuInflater; -+import android.view.MenuItem; -+import android.view.View; -+import android.view.View.OnClickListener; -+import android.view.ViewGroup; -+import android.widget.AdapterView; -+import android.widget.AdapterView.OnItemClickListener; -+import android.widget.ArrayAdapter; -+import android.widget.ImageButton; -+import android.widget.ListView; -+import android.widget.SeekBar; -+import android.widget.SeekBar.OnSeekBarChangeListener; -+ -+/** -+ * @author meld0 -+ * -+ */ -+public class JukeboxActivity extends SubsonicTabActivity implements ProgressListener, OnClickListener, OnSeekBarChangeListener, OnItemClickListener{ -+ -+ private ImageButton play, stop, next, prev, shuffle; -+ private ListView entryList; -+ private SeekBar gain; -+ private Jukebox jukebox; -+ -+ @Override -+ public void onCreate(Bundle savedInstanceState){ -+ super.onCreate(savedInstanceState); -+ setContentView(R.layout.jukebox); -+ -+ jukebox = new Jukebox(); -+ -+ play = (ImageButton) findViewById(R.id.jukebox_start); -+ stop = (ImageButton) findViewById(R.id.jukebox_stop); -+ prev = (ImageButton) findViewById(R.id.jukebox_previous); -+ next = (ImageButton) findViewById(R.id.jukebox_next); -+ shuffle = (ImageButton) findViewById(R.id.jukebox_shuffle); -+ entryList = (ListView) findViewById(R.id.jukebox_list); -+ -+ gain = (SeekBar) findViewById(R.id.jukebox_seek); -+ gain.setMax(100); -+ -+ play.setOnClickListener(this); -+ stop.setOnClickListener(this); -+ next.setOnClickListener(this); -+ prev.setOnClickListener(this); -+ shuffle.setOnClickListener(this); -+ gain.setOnSeekBarChangeListener(this); -+ entryList.setOnItemClickListener(this); -+ -+ registerForContextMenu(entryList); -+ load(); -+ } -+ -+ @Override -+ public void updateProgress(int messageId){ -+ -+ } -+ -+ private void load(){ -+ load(Jukebox.GET); -+ } -+ -+ private void load(String action){ -+ load(action, ""); -+ } -+ -+ private void load(final String action, final String additional){ -+ BackgroundTask<Boolean> task = new TabActivityBackgroundTask<Boolean>(this){ -+ -+ protected Boolean doInBackground() throws Throwable{ -+ boolean update = false; -+ if (!Util.isOffline(JukeboxActivity.this)) { -+ MusicService musicService = MusicServiceFactory.getMusicService(JukeboxActivity.this); -+ jukebox.lastAction = action; -+ jukebox = musicService.getJukebox(jukebox, JukeboxActivity.this, this, additional); -+ update = true; -+ } -+ return update; -+ } -+ -+ protected void done(Boolean result){ -+ if (jukebox.isSuccess()) { -+ if (jukebox.lastAction.equals(Jukebox.SET_GAIN)) { -+ jukebox.setGain((int) (Double.valueOf(additional.split("=")[1]) * 100)); -+ gain.setProgress(jukebox.getGain()); -+ } else if (jukebox.lastAction.equals(Jukebox.REMOVE_ITEM)) ((SongListAdapter) entryList.getAdapter()).remove((Entry) entryList.getAdapter().getItem( -+ Integer.valueOf(additional.split("=")[1]))); -+ else if (jukebox.lastAction.equals(Jukebox.CLEAR_PLAYLIST)) ((SongListAdapter) entryList.getAdapter()).clear(); -+ else if (jukebox.lastAction.equals(Jukebox.SKIP_TO_INDEX)) jukebox.setCurrentIndex(Integer.valueOf(additional.split("=")[1])); -+ -+ if (jukebox.isNewPlaylist()) entryList.setAdapter(new SongListAdapter(jukebox.getChildren())); -+ } -+ } -+ }; -+ task.execute(); -+ } -+ -+ @Override -+ public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo){ -+ super.onCreateContextMenu(menu, view, menuInfo); -+ MenuInflater inflater = getMenuInflater(); -+ inflater.inflate(R.menu.jukebox_context, menu); -+ } -+ -+ @Override -+ public boolean onContextItemSelected(MenuItem menuItem){ -+ AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo(); -+ switch (menuItem.getItemId()) { -+ case R.id.jukebox_remove: -+ load(Jukebox.REMOVE_ITEM, "index=" + info.position); -+ break; -+ case R.id.jukebox_clear: -+ load(Jukebox.CLEAR_PLAYLIST); -+ break; -+ default: -+ return super.onContextItemSelected(menuItem); -+ } -+ return true; -+ } -+ -+ @Override -+ protected void onResume(){ -+ super.onResume(); -+ load(); -+ } -+ -+ @Override -+ public void onClick(View arg0){ -+ if (arg0.equals(this.play)) { -+ load(Jukebox.START_PLAYBACK); -+ } else if (arg0.equals(this.stop)) { -+ load(Jukebox.STOP_PLAYBACK); -+ } else if (arg0.equals(this.prev)) { -+ loadW(); -+ load(Jukebox.SKIP_TO_INDEX, "index=" + (jukebox.getCurrentIndex() - 1)); // TODO // MAYBE // BETTER // ? -+ } else if (arg0.equals(this.next)) { -+ loadW(); -+ load(Jukebox.SKIP_TO_INDEX, "index=" + (jukebox.getCurrentIndex() + 1)); -+ } else if (arg0.equals(this.shuffle)) { -+ load(Jukebox.SHUFFLE_PLAYLIST); -+ load(); -+ } -+ } -+ -+ @Override -+ public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2){ -+ } -+ -+ @Override -+ public void onStartTrackingTouch(SeekBar arg0){ -+ } -+ -+ @Override -+ public void onStopTrackingTouch(SeekBar arg0){ -+ load(Jukebox.SET_GAIN, "gain=" + ((double) arg0.getProgress() / 100)); -+ } -+ -+ private class SongListAdapter extends ArrayAdapter<MusicDirectory.Entry>{ -+ -+ public SongListAdapter(List<MusicDirectory.Entry> entries){ -+ super(JukeboxActivity.this, android.R.layout.simple_list_item_1, entries); -+ } -+ -+ @Override -+ public View getView(int position, View convertView, ViewGroup parent){ -+ JukeboxSongView view; -+ if (convertView != null && convertView instanceof JukeboxSongView) { -+ view = (JukeboxSongView) convertView; -+ } else { -+ view = new JukeboxSongView(JukeboxActivity.this); -+ } -+ MusicDirectory.Entry entry = getItem(position); -+ -+ if (position == jukebox.getCurrentIndex()) { -+ view.setSong(entry, false, true); -+ } else view.setSong(entry, false, false); -+ return view; -+ } -+ } -+ -+ @Override -+ public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3){ -+ load(Jukebox.SKIP_TO_INDEX, "index=" + arg3); -+ } -+ -+ public void loadW(){ -+ if (!Util.isOffline(JukeboxActivity.this)) { -+ MusicService musicService = MusicServiceFactory.getMusicService(JukeboxActivity.this); -+ jukebox.lastAction = Jukebox.GET; -+ try { -+ jukebox = musicService.getJukebox(jukebox, JukeboxActivity.this, this, ""); -+ } catch (Exception e) { -+ // TODO Auto-generated catch block -+ e.printStackTrace(); -+ } -+ } -+ } -+ -+} -Index: src/net/sourceforge/subsonic/androidapp/activity/SelectAlbumActivity.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/activity/SelectAlbumActivity.java (revision 2441) -+++ src/net/sourceforge/subsonic/androidapp/activity/SelectAlbumActivity.java (working copy) -@@ -252,6 +252,9 @@ - case R.id.album_menu_pin: - downloadRecursively(entry.getId(), true, true, false); - break; -+ case R.id.album_menu_jukebox_add: -+ addToJukebox(entry.getId()); -+ break; - case R.id.song_menu_play_now: - getDownloadService().download(songs, false, true, true); - break; -@@ -261,6 +264,8 @@ - case R.id.song_menu_play_last: - getDownloadService().download(songs, false, false, false); - break; -+ case R.id.song_menu_jukebox_add: -+ addToJukebox(entry); - default: - return super.onContextItemSelected(menuItem); - } -Index: src/net/sourceforge/subsonic/androidapp/activity/SelectArtistActivity.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/activity/SelectArtistActivity.java (revision 2441) -+++ src/net/sourceforge/subsonic/androidapp/activity/SelectArtistActivity.java (working copy) -@@ -210,6 +210,9 @@ - case R.id.artist_menu_pin: - downloadRecursively(artist.getId(), true, true, false); - break; -+ case R.id.artist_menu_jukebox_add: -+ addToJukebox(artist.getId()); -+ break; - default: - return super.onContextItemSelected(menuItem); - } -Index: src/net/sourceforge/subsonic/androidapp/activity/SubsonicTabActivity.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/activity/SubsonicTabActivity.java (revision 2441) -+++ src/net/sourceforge/subsonic/androidapp/activity/SubsonicTabActivity.java (working copy) -@@ -23,6 +23,16 @@ - import java.util.LinkedList; - import java.util.List; - -+import github.daneren2005.dsub.R; -+import github.daneren2005.dsub.domain.MusicDirectory; -+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.util.Constants; -+import github.daneren2005.dsub.util.ImageLoader; -+import github.daneren2005.dsub.util.ModalBackgroundTask; -+import github.daneren2005.dsub.util.Util; - import android.app.Activity; - import android.content.Context; - import android.content.Intent; -@@ -39,16 +49,6 @@ - import android.view.View; - import android.view.Window; - import android.widget.TextView; --import github.daneren2005.dsub.R; --import github.daneren2005.dsub.domain.MusicDirectory; --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.util.Constants; --import github.daneren2005.dsub.util.ImageLoader; --import github.daneren2005.dsub.util.ModalBackgroundTask; --import github.daneren2005.dsub.util.Util; - - /** - * @author Sindre Mehus -@@ -63,6 +63,7 @@ - private View musicButton; - private View searchButton; - private View playlistButton; -+ private View jukeboxButton; - private View nowPlayingButton; - - @Override -@@ -118,6 +119,14 @@ - Util.startActivityWithoutTransition(SubsonicTabActivity.this, intent); - } - }); -+ -+ jukeboxButton = findViewById(R.id.button_bar_jukebox); -+ jukeboxButton.setOnClickListener(new View.OnClickListener() { -+ @Override -+ public void onClick(View view) { -+ Util.startActivityWithoutTransition(SubsonicTabActivity.this, JukeboxActivity.class); -+ } -+ }); - - nowPlayingButton = findViewById(R.id.button_bar_now_playing); - nowPlayingButton.setOnClickListener(new View.OnClickListener() { -@@ -225,6 +234,22 @@ - int visibility = Util.isOffline(this) ? View.GONE : View.VISIBLE; - searchButton.setVisibility(visibility); - playlistButton.setVisibility(visibility); -+ jukeboxButton.setVisibility(visibility); -+ /* -+ * The following block would check for valid Permissions -+ * but it is called too often -> network traffic/ problems ? -+ * -+ MusicService musicService = MusicServiceFactory.getMusicService(this); -+ try { -+ User user = musicService.getUser(this, null); -+ if(!user.isJukeboxControl()){ -+ jukeboxButton.setVisibility(View.GONE); -+ } -+ } catch (Exception e) { -+ // TODO Auto-generated catch block -+ e.printStackTrace(); -+ } -+ */ - } - - public void setProgressVisible(boolean visible) { -@@ -363,5 +388,67 @@ - } - } - } -+ -+ protected void addToJukebox(String id) { -+ -+ List<MusicDirectory.Entry> entries = new LinkedList<MusicDirectory.Entry>(); -+ MusicService musicService = MusicServiceFactory.getMusicService(this); -+ MusicDirectory root; -+ -+ try { -+ root = musicService.getMusicDirectory(id, false, SubsonicTabActivity.this, null); -+ collectEntries(root, entries); -+ } catch (Exception e) { -+ // TODO Auto-generated catch block -+ e.printStackTrace(); -+ } -+ -+ -+ StringBuilder build = new StringBuilder(); -+ build.append("action=add"); -+ for(MusicDirectory.Entry entry2: entries){ -+ build.append("&id="); -+ build.append(entry2.getId()); -+ } -+ try { -+ musicService.getJukebox(null, this, null, build.toString()); -+ } catch (Exception e) { -+ // TODO Auto-generated catch block -+ e.printStackTrace(); -+ } -+ -+ } -+ -+ protected void addToJukebox(MusicDirectory.Entry entry) { -+ try { -+ MusicService musicService = MusicServiceFactory.getMusicService(this); -+ musicService.getJukebox(null, this, null, "action=add&id="+entry.getId()); -+ } catch (Exception e) { -+ // TODO Auto-generated catch block -+ e.printStackTrace(); -+ } -+ } -+ -+ private List<MusicDirectory.Entry> collectEntries(MusicDirectory parent, List<MusicDirectory.Entry> songs){ -+ for (MusicDirectory.Entry song : parent.getChildren(false, true)) { -+ if (!song.isVideo()) { -+ songs.add(song); -+ } -+ } -+ for (MusicDirectory.Entry dir : parent.getChildren(true, false)) { -+ MusicService musicService = MusicServiceFactory.getMusicService(SubsonicTabActivity.this); -+ try { -+ collectEntries(musicService.getMusicDirectory(dir.getId(), false, SubsonicTabActivity.this, null), songs); -+ } catch (Exception e) { -+ // TODO Auto-generated catch block -+ e.printStackTrace(); -+ } -+ } -+ -+ return songs; -+ } -+ -+ -+ - } - -Index: src/net/sourceforge/subsonic/androidapp/domain/Jukebox.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/domain/Jukebox.java (revision 0) -+++ src/net/sourceforge/subsonic/androidapp/domain/Jukebox.java (revision 0) -@@ -0,0 +1,113 @@ -+/* -+ 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.domain; -+ -+import java.io.Serializable; -+import java.util.List; -+ -+/** -+ * @author meld0 -+ * -+ */ -+public class Jukebox extends MusicDirectory implements Serializable{ -+ -+ public String lastAction; -+ -+ //get, start, stop, skip, add, clear, remove, shuffle, setGain -+ public static final String GET = "get"; -+ public static final String START_PLAYBACK = "start"; -+ public static final String STOP_PLAYBACK = "stop"; -+ public static final String SKIP_TO_INDEX = "skip"; -+ public static final String ADD_TO_PLAYLIST = "add"; -+ public static final String CLEAR_PLAYLIST = "clear"; -+ public static final String REMOVE_ITEM = "remove"; -+ public static final String SHUFFLE_PLAYLIST = "shuffle"; -+ public static final String SET_GAIN = "setGain"; -+ -+ public Jukebox() { -+ super(); -+ } -+ -+ public boolean isPlaying() { -+ return playing; -+ } -+ -+ public void setPlaying(boolean playing) { -+ this.playing = playing; -+ } -+ -+ public int getGain() { -+ return gain; -+ } -+ -+ public void setGain(int gain) { -+ this.gain = gain; -+ } -+ -+ public int getCurrentIndex() { -+ return currentIndex; -+ } -+ -+ public void setCurrentIndex(int currentIndex) { -+ this.currentIndex = currentIndex; -+ } -+ -+ public boolean isAvailable() { -+ return available; -+ } -+ -+ public boolean isSuccess() { -+ return success; -+ } -+ -+ public void setAvailable(boolean available) { -+ this.available = available; -+ } -+ -+ public void setSuccess(boolean success) { -+ this.success = success; -+ } -+ -+ public boolean isNewPlaylist() { -+ return newPlaylist; -+ } -+ -+ public void setNewPlaylist(boolean newPlaylist) { -+ this.newPlaylist = newPlaylist; -+ } -+ -+ private boolean playing = false; -+ private int gain = 0; -+ private int currentIndex = 0; -+ private boolean available = false; -+ private boolean success = false; -+ private boolean newPlaylist = false; -+ -+ public void addChildren(List<Entry> children){ -+ super.addChildren(children); -+ } -+ -+ public void reset(){ -+ this.available = false; -+ this.success = false; -+ this.newPlaylist = false; -+ } -+ -+} -Index: src/net/sourceforge/subsonic/androidapp/domain/MusicDirectory.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/domain/MusicDirectory.java (revision 2441) -+++ src/net/sourceforge/subsonic/androidapp/domain/MusicDirectory.java (working copy) -@@ -59,6 +59,13 @@ - } - return result; - } -+ -+ protected void addChildren(List<Entry> children){ -+ if(!children.isEmpty()) { -+ this.children.clear(); -+ this.children.addAll(children); -+ } -+ } - - public static class Entry implements Serializable { - private String id; -Index: src/net/sourceforge/subsonic/androidapp/domain/User.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/domain/User.java (revision 0) -+++ src/net/sourceforge/subsonic/androidapp/domain/User.java (revision 0) -@@ -0,0 +1,43 @@ -+/* -+ 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.domain; -+ -+import java.io.Serializable; -+ -+/** -+ * @author meld0 -+ * -+ */ -+public class User implements Serializable{ -+ -+ //TODO implement missing user attributes -+ -+ private boolean jukeboxControl; -+ -+ public boolean isJukeboxControl() { -+ return jukeboxControl; -+ } -+ -+ public void setJukeboxControl(boolean jukeboxControl) { -+ this.jukeboxControl = jukeboxControl; -+ } -+ -+ -+} -Index: src/net/sourceforge/subsonic/androidapp/service/CachedMusicService.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/service/CachedMusicService.java (revision 2441) -+++ src/net/sourceforge/subsonic/androidapp/service/CachedMusicService.java (working copy) -@@ -21,9 +21,11 @@ - import android.content.Context; - import android.graphics.Bitmap; - import github.daneren2005.dsub.domain.Indexes; -+import github.daneren2005.dsub.domain.Jukebox; - import github.daneren2005.dsub.domain.MusicDirectory; - import github.daneren2005.dsub.domain.MusicFolder; - import github.daneren2005.dsub.domain.Playlist; -+import github.daneren2005.dsub.domain.User; - import github.daneren2005.dsub.domain.Version; - import github.daneren2005.dsub.domain.SearchResult; - import github.daneren2005.dsub.domain.SearchCritera; -@@ -199,4 +201,17 @@ - restUrl = newUrl; - } - } -+ -+ @Override -+ public Jukebox getJukebox(Jukebox jukebox, Context context, -+ ProgressListener progressListener, String action) throws Exception { -+ return musicService.getJukebox(jukebox, context, progressListener, action); -+ } -+ -+ @Override -+ public User getUser(Context context, ProgressListener progressListener) -+ throws Exception { -+ return musicService.getUser(context, progressListener); -+ } -+ - } -Index: src/net/sourceforge/subsonic/androidapp/service/MusicService.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/service/MusicService.java (revision 2441) -+++ src/net/sourceforge/subsonic/androidapp/service/MusicService.java (working copy) -@@ -21,9 +21,11 @@ - import android.content.Context; - import android.graphics.Bitmap; - import github.daneren2005.dsub.domain.Indexes; -+import github.daneren2005.dsub.domain.Jukebox; - import github.daneren2005.dsub.domain.MusicDirectory; - import github.daneren2005.dsub.domain.MusicFolder; - import github.daneren2005.dsub.domain.Playlist; -+import github.daneren2005.dsub.domain.User; - import github.daneren2005.dsub.domain.Version; - import github.daneren2005.dsub.domain.SearchResult; - import github.daneren2005.dsub.domain.SearchCritera; -@@ -74,4 +76,8 @@ - Version getLatestVersion(Context context, ProgressListener progressListener) throws Exception; - - String getVideoUrl(Context context, String id); -+ -+ Jukebox getJukebox(Jukebox jukebox, Context context, ProgressListener progressListener , String action) throws Exception; -+ -+ User getUser(Context context, ProgressListener progressListener) throws Exception; - } -\ No newline at end of file -Index: src/net/sourceforge/subsonic/androidapp/service/RESTMusicService.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/service/RESTMusicService.java (revision 2441) -+++ src/net/sourceforge/subsonic/androidapp/service/RESTMusicService.java (working copy) -@@ -28,6 +28,7 @@ - import android.util.Log; - import github.daneren2005.dsub.R; - import github.daneren2005.dsub.domain.Indexes; -+import github.daneren2005.dsub.domain.Jukebox; - import github.daneren2005.dsub.domain.Lyrics; - import github.daneren2005.dsub.domain.MusicDirectory; - import github.daneren2005.dsub.domain.MusicFolder; -@@ -35,10 +36,12 @@ - import github.daneren2005.dsub.domain.SearchCritera; - import github.daneren2005.dsub.domain.SearchResult; - import github.daneren2005.dsub.domain.ServerInfo; -+import github.daneren2005.dsub.domain.User; - import github.daneren2005.dsub.domain.Version; - import github.daneren2005.dsub.service.parser.AlbumListParser; - import github.daneren2005.dsub.service.parser.ErrorParser; - import github.daneren2005.dsub.service.parser.IndexesParser; -+import github.daneren2005.dsub.service.parser.JukeboxParser; - import github.daneren2005.dsub.service.parser.LicenseParser; - import github.daneren2005.dsub.service.parser.LyricsParser; - import github.daneren2005.dsub.service.parser.MusicDirectoryParser; -@@ -48,6 +51,7 @@ - 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.UserParser; - import github.daneren2005.dsub.service.parser.VersionParser; - import github.daneren2005.dsub.service.ssl.SSLSocketFactory; - import github.daneren2005.dsub.service.ssl.TrustSelfSignedStrategy; -@@ -195,6 +199,53 @@ - Util.close(reader); - } - } -+ -+ public Jukebox getJukebox(Jukebox jukebox, Context context, ProgressListener progressListener, String action) throws Exception { -+ -+ List<String> parameterNames = new ArrayList<String>(); -+ List<Object> parameterValues = new ArrayList<Object>(); -+ if(jukebox != null){ -+ parameterNames.add("action"); -+ parameterValues.add(jukebox.lastAction); -+ } -+ if(!action.isEmpty()){ -+ String[] names_values = action.split("&"); -+ for(String name_value: names_values){ -+ String[] pair = name_value.split("="); -+ parameterNames.add(pair[0]); -+ parameterValues.add(pair[1]); -+ } -+ } -+ -+ Reader reader = getReader(context, progressListener, "jukeboxControl", null, parameterNames, parameterValues); -+ -+ try { -+ return new JukeboxParser(context).parse(jukebox, reader, progressListener); -+ } finally { -+ Util.close(reader); -+ } -+ } -+ -+ public User getUser(Context context, ProgressListener progressListener) throws Exception { -+ -+ SharedPreferences prefs = Util.getPreferences(context); -+ int instance = prefs.getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1); -+ String username = prefs.getString(Constants.PREFERENCES_KEY_USERNAME + instance, null); -+ -+ List<String> parameterNames = new ArrayList<String>(); -+ List<Object> parameterValues = new ArrayList<Object>(); -+ parameterNames.add("username"); -+ parameterValues.add(username); -+ -+ Reader reader = getReader(context, progressListener, "getUser", null, parameterNames, parameterValues); -+ -+ try { -+ return new UserParser(context).parse(reader, progressListener); -+ } finally { -+ Util.close(reader); -+ } -+ } -+ - - @Override - public Indexes getIndexes(String musicFolderId, boolean refresh, Context context, ProgressListener progressListener) throws Exception { -Index: src/net/sourceforge/subsonic/androidapp/service/parser/AbstractParser.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/service/parser/AbstractParser.java (revision 2441) -+++ src/net/sourceforge/subsonic/androidapp/service/parser/AbstractParser.java (working copy) -@@ -97,6 +97,11 @@ - String s = get(name); - return s == null ? null : Long.valueOf(s); - } -+ -+ protected Double getDouble(String name) { -+ String s = get(name); -+ return s == null ? null : Double.valueOf(s); -+ } - - protected void init(Reader reader) throws Exception { - parser = Xml.newPullParser(); -Index: src/net/sourceforge/subsonic/androidapp/service/parser/JukeboxParser.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/service/parser/JukeboxParser.java (revision 0) -+++ src/net/sourceforge/subsonic/androidapp/service/parser/JukeboxParser.java (revision 0) -@@ -0,0 +1,86 @@ -+/* -+ 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 java.io.Reader; -+ -+import github.daneren2005.dsub.R; -+import github.daneren2005.dsub.domain.Jukebox; -+import github.daneren2005.dsub.domain.MusicDirectory; -+import github.daneren2005.dsub.util.ProgressListener; -+ -+import org.xmlpull.v1.XmlPullParser; -+ -+import android.content.Context; -+ -+/** -+ * @author meld0 -+ * -+ */ -+public class JukeboxParser extends MusicDirectoryEntryParser { -+ -+ public JukeboxParser(Context context) { -+ super(context); -+ } -+ -+ public Jukebox parse(Jukebox jukebox, Reader reader, -+ ProgressListener progressListener) throws Exception { -+ updateProgress(progressListener, R.string.parser_reading); -+ -+ if (jukebox == null) -+ jukebox = new Jukebox(); -+ jukebox.reset(); -+ init(reader); -+ jukebox.setAvailable(true); -+ -+ MusicDirectory dir = new MusicDirectory(); -+ -+ int eventType; -+ do { -+ eventType = nextParseEvent(); -+ if (eventType == XmlPullParser.START_TAG) { -+ String name = getElementName(); -+ if ("entry".equals(name)) { -+ dir.addChild(parseEntry()); -+ jukebox.setNewPlaylist(true); -+ } else if ("jukeboxPlaylist".equals(name)) { -+ jukebox.setPlaying(getBoolean("playing")); -+ jukebox.setGain((int) (getDouble("gain") * 100)); -+ jukebox.setCurrentIndex(getInteger("currentIndex")); -+ } else if ("subsonic-response".equals(name)) { -+ if (get("status").equals("ok")) -+ jukebox.setSuccess(true); -+ } else if ("error".equals(name)) { -+ handleError(); -+ } -+ } -+ } while (eventType != XmlPullParser.END_DOCUMENT); -+ -+ if(jukebox.isNewPlaylist()) { -+ jukebox.addChildren(dir.getChildren()); -+ } -+ -+ validate(); -+ updateProgress(progressListener, R.string.parser_reading_done); -+ -+ return jukebox; -+ } -+ -+} -Index: src/net/sourceforge/subsonic/androidapp/service/parser/UserParser.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/service/parser/UserParser.java (revision 0) -+++ src/net/sourceforge/subsonic/androidapp/service/parser/UserParser.java (revision 0) -@@ -0,0 +1,67 @@ -+/* -+ 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 java.io.Reader; -+ -+import github.daneren2005.dsub.R; -+import github.daneren2005.dsub.domain.User; -+import github.daneren2005.dsub.util.ProgressListener; -+ -+import org.xmlpull.v1.XmlPullParser; -+ -+import android.content.Context; -+ -+/** -+ * @author meld0 -+ * -+ */ -+public class UserParser extends AbstractParser{ -+ -+ public UserParser(Context context) { -+ super(context); -+ } -+ -+ public User parse(Reader reader, ProgressListener progressListener) throws Exception { -+ updateProgress(progressListener, R.string.parser_reading); -+ init(reader); -+ -+ User user = new User(); -+ int eventType; -+ do { -+ eventType = nextParseEvent(); -+ if (eventType == XmlPullParser.START_TAG) { -+ String name = getElementName(); -+ if ("user".equals(name)) { -+ user.setJukeboxControl(getBoolean("jukeboxRole")); -+ } else if ("error".equals(name)) { -+ handleError(); -+ } -+ } -+ } while (eventType != XmlPullParser.END_DOCUMENT); -+ -+ validate(); -+ updateProgress(progressListener, R.string.parser_reading_done); -+ -+ return user; -+ } -+ -+ -+} -Index: src/net/sourceforge/subsonic/androidapp/util/JukeboxSongView.java -=================================================================== ---- src/net/sourceforge/subsonic/androidapp/util/JukeboxSongView.java (revision 0) -+++ src/net/sourceforge/subsonic/androidapp/util/JukeboxSongView.java (revision 0) -@@ -0,0 +1,88 @@ -+/* -+ 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.util; -+ -+import github.daneren2005.dsub.R; -+import github.daneren2005.dsub.domain.MusicDirectory; -+import android.content.Context; -+import android.view.LayoutInflater; -+import android.view.View; -+import android.widget.CheckedTextView; -+import android.widget.LinearLayout; -+import android.widget.TextView; -+ -+/** -+ * @author meld0 -+ * -+ */ -+public class JukeboxSongView extends LinearLayout{ -+ -+ private CheckedTextView checkedTextView; -+ private TextView titleTextView; -+ private TextView artistTextView; -+ private TextView durationTextView; -+ private TextView statusTextView; -+ private MusicDirectory.Entry song; -+ -+ public JukeboxSongView(Context context) { -+ super(context); -+ LayoutInflater.from(context).inflate(R.layout.song_list_item, this, true); -+ -+ checkedTextView = (CheckedTextView) findViewById(R.id.song_check); -+ titleTextView = (TextView) findViewById(R.id.song_title); -+ artistTextView = (TextView) findViewById(R.id.song_artist); -+ durationTextView = (TextView) findViewById(R.id.song_duration); -+ statusTextView = (TextView) findViewById(R.id.song_status); -+ -+ } -+ -+ public void setSong(MusicDirectory.Entry song, boolean checkable, boolean playing) { -+ this.song = song; -+ StringBuilder artist = new StringBuilder(40); -+ -+ String bitRate = null; -+ if (song.getBitRate() != null) { -+ bitRate = String.format(getContext().getString(R.string.song_details_kbps), song.getBitRate()); -+ } -+ -+ String fileFormat = null; -+ if (song.getTranscodedSuffix() != null && !song.getTranscodedSuffix().equals(song.getSuffix())) { -+ fileFormat = String.format("%s > %s", song.getSuffix(), song.getTranscodedSuffix()); -+ } else { -+ fileFormat = song.getSuffix(); -+ } -+ -+ artist.append(song.getArtist()).append(" (") -+ .append(String.format(getContext().getString(R.string.song_details_all), bitRate == null ? "" : bitRate, fileFormat)) -+ .append(")"); -+ -+ titleTextView.setText(song.getTitle()); -+ artistTextView.setText(artist); -+ durationTextView.setText(Util.formatDuration(song.getDuration())); -+ checkedTextView.setVisibility(checkable && !song.isVideo() ? View.VISIBLE : View.GONE); -+ -+ if(playing){ -+ titleTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.stat_notify_playing, 0, 0, 0); -+ }else{ -+ titleTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); -+ } -+ } -+ -+} |