1235 lines
44 KiB
Plaintext
1235 lines
44 KiB
Plaintext
Index: AndroidManifest.xml
|
|
===================================================================
|
|
--- AndroidManifest.xml (revision 2441)
|
|
+++ AndroidManifest.xml (working copy)
|
|
@@ -114,7 +114,8 @@
|
|
a:authorities="net.sourceforge.subsonic.androidapp.provider.SearchSuggestionProvider"/>
|
|
|
|
<meta-data a:name="android.app.default_searchable"
|
|
- a:value="net.sourceforge.subsonic.androidapp.activity.QueryReceiverActivity"/>
|
|
+ a:value="net.sourceforge.subsonic.androidapp.activity.QueryReceiverActivity"/>
|
|
+ <activity a:name="net.sourceforge.subsonic.androidapp.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:a="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 net.sourceforge.subsonic.androidapp.activity;
|
|
+
|
|
+import java.util.List;
|
|
+
|
|
+import net.sourceforge.subsonic.androidapp.R;
|
|
+import net.sourceforge.subsonic.androidapp.domain.Jukebox;
|
|
+import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
|
|
+import net.sourceforge.subsonic.androidapp.domain.MusicDirectory.Entry;
|
|
+import net.sourceforge.subsonic.androidapp.service.MusicService;
|
|
+import net.sourceforge.subsonic.androidapp.service.MusicServiceFactory;
|
|
+import net.sourceforge.subsonic.androidapp.util.BackgroundTask;
|
|
+import net.sourceforge.subsonic.androidapp.util.JukeboxSongView;
|
|
+import net.sourceforge.subsonic.androidapp.util.ProgressListener;
|
|
+import net.sourceforge.subsonic.androidapp.util.TabActivityBackgroundTask;
|
|
+import net.sourceforge.subsonic.androidapp.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 net.sourceforge.subsonic.androidapp.R;
|
|
+import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
|
|
+import net.sourceforge.subsonic.androidapp.service.DownloadService;
|
|
+import net.sourceforge.subsonic.androidapp.service.DownloadServiceImpl;
|
|
+import net.sourceforge.subsonic.androidapp.service.MusicService;
|
|
+import net.sourceforge.subsonic.androidapp.service.MusicServiceFactory;
|
|
+import net.sourceforge.subsonic.androidapp.util.Constants;
|
|
+import net.sourceforge.subsonic.androidapp.util.ImageLoader;
|
|
+import net.sourceforge.subsonic.androidapp.util.ModalBackgroundTask;
|
|
+import net.sourceforge.subsonic.androidapp.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 net.sourceforge.subsonic.androidapp.R;
|
|
-import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
|
|
-import net.sourceforge.subsonic.androidapp.service.DownloadService;
|
|
-import net.sourceforge.subsonic.androidapp.service.DownloadServiceImpl;
|
|
-import net.sourceforge.subsonic.androidapp.service.MusicService;
|
|
-import net.sourceforge.subsonic.androidapp.service.MusicServiceFactory;
|
|
-import net.sourceforge.subsonic.androidapp.util.Constants;
|
|
-import net.sourceforge.subsonic.androidapp.util.ImageLoader;
|
|
-import net.sourceforge.subsonic.androidapp.util.ModalBackgroundTask;
|
|
-import net.sourceforge.subsonic.androidapp.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 net.sourceforge.subsonic.androidapp.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 net.sourceforge.subsonic.androidapp.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 net.sourceforge.subsonic.androidapp.domain.Indexes;
|
|
+import net.sourceforge.subsonic.androidapp.domain.Jukebox;
|
|
import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
|
|
import net.sourceforge.subsonic.androidapp.domain.MusicFolder;
|
|
import net.sourceforge.subsonic.androidapp.domain.Playlist;
|
|
+import net.sourceforge.subsonic.androidapp.domain.User;
|
|
import net.sourceforge.subsonic.androidapp.domain.Version;
|
|
import net.sourceforge.subsonic.androidapp.domain.SearchResult;
|
|
import net.sourceforge.subsonic.androidapp.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 net.sourceforge.subsonic.androidapp.domain.Indexes;
|
|
+import net.sourceforge.subsonic.androidapp.domain.Jukebox;
|
|
import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
|
|
import net.sourceforge.subsonic.androidapp.domain.MusicFolder;
|
|
import net.sourceforge.subsonic.androidapp.domain.Playlist;
|
|
+import net.sourceforge.subsonic.androidapp.domain.User;
|
|
import net.sourceforge.subsonic.androidapp.domain.Version;
|
|
import net.sourceforge.subsonic.androidapp.domain.SearchResult;
|
|
import net.sourceforge.subsonic.androidapp.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 net.sourceforge.subsonic.androidapp.R;
|
|
import net.sourceforge.subsonic.androidapp.domain.Indexes;
|
|
+import net.sourceforge.subsonic.androidapp.domain.Jukebox;
|
|
import net.sourceforge.subsonic.androidapp.domain.Lyrics;
|
|
import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
|
|
import net.sourceforge.subsonic.androidapp.domain.MusicFolder;
|
|
@@ -35,10 +36,12 @@
|
|
import net.sourceforge.subsonic.androidapp.domain.SearchCritera;
|
|
import net.sourceforge.subsonic.androidapp.domain.SearchResult;
|
|
import net.sourceforge.subsonic.androidapp.domain.ServerInfo;
|
|
+import net.sourceforge.subsonic.androidapp.domain.User;
|
|
import net.sourceforge.subsonic.androidapp.domain.Version;
|
|
import net.sourceforge.subsonic.androidapp.service.parser.AlbumListParser;
|
|
import net.sourceforge.subsonic.androidapp.service.parser.ErrorParser;
|
|
import net.sourceforge.subsonic.androidapp.service.parser.IndexesParser;
|
|
+import net.sourceforge.subsonic.androidapp.service.parser.JukeboxParser;
|
|
import net.sourceforge.subsonic.androidapp.service.parser.LicenseParser;
|
|
import net.sourceforge.subsonic.androidapp.service.parser.LyricsParser;
|
|
import net.sourceforge.subsonic.androidapp.service.parser.MusicDirectoryParser;
|
|
@@ -48,6 +51,7 @@
|
|
import net.sourceforge.subsonic.androidapp.service.parser.RandomSongsParser;
|
|
import net.sourceforge.subsonic.androidapp.service.parser.SearchResult2Parser;
|
|
import net.sourceforge.subsonic.androidapp.service.parser.SearchResultParser;
|
|
+import net.sourceforge.subsonic.androidapp.service.parser.UserParser;
|
|
import net.sourceforge.subsonic.androidapp.service.parser.VersionParser;
|
|
import net.sourceforge.subsonic.androidapp.service.ssl.SSLSocketFactory;
|
|
import net.sourceforge.subsonic.androidapp.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 net.sourceforge.subsonic.androidapp.service.parser;
|
|
+
|
|
+import java.io.Reader;
|
|
+
|
|
+import net.sourceforge.subsonic.androidapp.R;
|
|
+import net.sourceforge.subsonic.androidapp.domain.Jukebox;
|
|
+import net.sourceforge.subsonic.androidapp.domain.MusicDirectory;
|
|
+import net.sourceforge.subsonic.androidapp.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 net.sourceforge.subsonic.androidapp.service.parser;
|
|
+
|
|
+import java.io.Reader;
|
|
+
|
|
+import net.sourceforge.subsonic.androidapp.R;
|
|
+import net.sourceforge.subsonic.androidapp.domain.User;
|
|
+import net.sourceforge.subsonic.androidapp.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 net.sourceforge.subsonic.androidapp.util;
|
|
+
|
|
+import net.sourceforge.subsonic.androidapp.R;
|
|
+import net.sourceforge.subsonic.androidapp.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);
|
|
+ }
|
|
+ }
|
|
+
|
|
+}
|