diff options
Diffstat (limited to 'subsonic-android')
11 files changed, 349 insertions, 12 deletions
diff --git a/subsonic-android/res/layout/main_buttons.xml b/subsonic-android/res/layout/main_buttons.xml index e8be57f0..1e60838d 100644 --- a/subsonic-android/res/layout/main_buttons.xml +++ b/subsonic-android/res/layout/main_buttons.xml @@ -128,6 +128,18 @@ android:paddingLeft="6dip"
android:paddingRight="6dip"
android:minHeight="50dip"/>
+ <TextView
+ android:id="@+id/main_albums_genres"
+ android:text="@string/main.albums_genres"
+ android:drawableRight="@drawable/list_item_more"
+ android:drawablePadding="6dip"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:gravity="center_vertical"
+ android:paddingLeft="6dip"
+ android:paddingRight="6dip"
+ android:minHeight="50dip"/>
<TextView
android:id="@+id/main_albums_random"
android:text="@string/main.albums_random"
diff --git a/subsonic-android/res/layout/select_genres.xml b/subsonic-android/res/layout/select_genres.xml new file mode 100644 index 00000000..3396d2ce --- /dev/null +++ b/subsonic-android/res/layout/select_genres.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/select_genre_layout" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" > + + <include layout="@layout/tab_progress" /> + + <TextView + android:id="@+id/select_genre_empty" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:padding="10dip" + android:text="@string/select_genre.empty" + android:visibility="gone" /> + + <ListView + android:id="@+id/select_genre_list" + android:layout_width="fill_parent" + android:layout_height="0dip" + android:layout_weight="1.0" + android:textFilterEnabled="true" /> + </LinearLayout> +</FrameLayout>
\ No newline at end of file diff --git a/subsonic-android/res/menu/select_genres.xml b/subsonic-android/res/menu/select_genres.xml new file mode 100644 index 00000000..e0f9a718 --- /dev/null +++ b/subsonic-android/res/menu/select_genres.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:id="@+id/menu_refresh" + android:icon="@drawable/action_refresh" + android:title="@string/menu.refresh" + android:showAsAction="always|withText"/> + + <item + android:id="@+id/menu_settings" + android:icon="@drawable/action_settings" + android:title="@string/menu.settings"/> + + <item + android:id="@+id/menu_exit" + android:icon="@drawable/action_exit" + android:title="@string/menu.exit"/> +</menu>
\ No newline at end of file diff --git a/subsonic-android/res/values/strings.xml b/subsonic-android/res/values/strings.xml index 01e10d6b..790bc8de 100644 --- a/subsonic-android/res/values/strings.xml +++ b/subsonic-android/res/values/strings.xml @@ -51,6 +51,7 @@ <string name="main.albums_highest">Top rated</string>
<string name="main.albums_starred">Starred</string>
<string name="main.albums_random">Random</string>
+ <string name="main.albums_genres">Genres</string>
<string name="main.back_confirm">Press back again to exit</string>
<string name="menu.search">Search</string>
@@ -114,6 +115,8 @@ <string name="select_album.donate_dialog_later">Later</string>
<string name="select_album.donate_dialog_0_trial_days_left">Trial period is over</string>
+ <string name="select_genre.empty">No genres found</string>
+
<string name="select_playlist.empty">No saved playlists on server</string>
<string name="download.empty">Playlist is empty</string>
diff --git a/subsonic-android/src/github/daneren2005/dsub/fragments/MainFragment.java b/subsonic-android/src/github/daneren2005/dsub/fragments/MainFragment.java index 869f8804..bbe3c507 100644 --- a/subsonic-android/src/github/daneren2005/dsub/fragments/MainFragment.java +++ b/subsonic-android/src/github/daneren2005/dsub/fragments/MainFragment.java @@ -133,6 +133,7 @@ public class MainFragment extends SubsonicFragment { 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 albumsGenresButton = buttons.findViewById(R.id.main_albums_genres);
final View dummyView = rootView.findViewById(R.id.main_dummy);
@@ -149,7 +150,7 @@ public class MainFragment extends SubsonicFragment { adapter.addView(offlineButton, true);
if (!Util.isOffline(context)) {
adapter.addView(albumsTitle, false);
- adapter.addViews(Arrays.asList(albumsNewestButton, albumsRandomButton, albumsHighestButton, albumsStarredButton, albumsRecentButton, albumsFrequentButton), true);
+ adapter.addViews(Arrays.asList(albumsNewestButton, albumsRandomButton, albumsHighestButton, albumsStarredButton, albumsGenresButton, albumsRecentButton, albumsFrequentButton), true);
}
list.setAdapter(adapter);
registerForContextMenu(dummyView);
@@ -173,6 +174,8 @@ public class MainFragment extends SubsonicFragment { showAlbumList("frequent");
} else if (view == albumsStarredButton) {
showAlbumList("starred");
+ } else if(view == albumsGenresButton) {
+ showAlbumList("genres");
}
}
});
@@ -194,14 +197,19 @@ public class MainFragment extends SubsonicFragment { }
private void showAlbumList(String type) {
- SubsonicFragment fragment = new SelectDirectoryFragment();
- Bundle args = new Bundle();
- args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, type);
- args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20);
- args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0);
- fragment.setArguments(args);
-
- replaceFragment(fragment, R.id.home_layout);
+ if("genres".equals(type)) {
+ SubsonicFragment fragment = new SelectGenreFragment();
+ replaceFragment(fragment, R.id.home_layout);
+ } else {
+ SubsonicFragment fragment = new SelectDirectoryFragment();
+ Bundle args = new Bundle();
+ args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, type);
+ args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20);
+ args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0);
+ fragment.setArguments(args);
+
+ replaceFragment(fragment, R.id.home_layout);
+ }
}
private void showAboutDialog() {
diff --git a/subsonic-android/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java b/subsonic-android/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java index 377026f9..13f61625 100644 --- a/subsonic-android/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java +++ b/subsonic-android/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java @@ -55,6 +55,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter String playlistId;
String playlistName;
String albumListType;
+ String albumListExtra;
int albumListSize;
@Override
@@ -100,6 +101,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter playlistId = args.getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID);
playlistName = args.getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME);
albumListType = args.getString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE);
+ albumListExtra = args.getString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA);
albumListSize = args.getInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0);
}
if(primaryFragment) {
@@ -313,6 +315,8 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter setTitle(R.string.main_albums_frequent);
} else if ("starred".equals(albumListType)) {
setTitle(R.string.main_albums_starred);
+ } else if("genres".equals(albumListType)) {
+ setTitle(albumListExtra);
}
new LoadTask() {
@@ -321,6 +325,8 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter MusicDirectory result;
if ("starred".equals(albumListType)) {
result = service.getStarredList(context, this);
+ } else if("genres".equals(albumListType)) {
+ result = service.getSongsByGenre(albumListExtra, size, 0, context, this);
} else {
result = service.getAlbumList(albumListType, size, 0, context, this);
}
@@ -373,7 +379,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter if(albumListType == null || "starred".equals(albumListType)) {
entryList.setAdapter(entryAdapter);
} else {
- entryList.setAdapter(new AlbumListAdapter(context, entryAdapter, albumListType, albumListSize));
+ entryList.setAdapter(new AlbumListAdapter(context, entryAdapter, albumListType, albumListExtra, albumListSize));
}
entryList.setVisibility(View.VISIBLE);
licenseValid = result.getSecond();
diff --git a/subsonic-android/src/github/daneren2005/dsub/fragments/SelectGenreFragment.java b/subsonic-android/src/github/daneren2005/dsub/fragments/SelectGenreFragment.java new file mode 100644 index 00000000..f4b0f213 --- /dev/null +++ b/subsonic-android/src/github/daneren2005/dsub/fragments/SelectGenreFragment.java @@ -0,0 +1,141 @@ +/*
+ 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 2010 (C) Sindre Mehus
+ */
+package github.daneren2005.dsub.fragments;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import github.daneren2005.dsub.R;
+import github.daneren2005.dsub.domain.Genre;
+import github.daneren2005.dsub.service.MusicService;
+import github.daneren2005.dsub.service.MusicServiceFactory;
+import github.daneren2005.dsub.util.BackgroundTask;
+import github.daneren2005.dsub.util.Constants;
+import github.daneren2005.dsub.util.TabBackgroundTask;
+import github.daneren2005.dsub.view.GenreAdapter;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuItem;
+import com.actionbarsherlock.view.MenuInflater;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SelectGenreFragment extends SubsonicFragment implements AdapterView.OnItemClickListener {
+ private static final String TAG = SelectGenreFragment.class.getSimpleName();
+ private ListView genreListView;
+ private View emptyView;
+
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
+ rootView = inflater.inflate(R.layout.select_genres, container, false);
+
+ genreListView = (ListView)rootView.findViewById(R.id.select_genre_list);
+ genreListView.setOnItemClickListener(this);
+ emptyView = rootView.findViewById(R.id.select_genre_empty);
+ refresh();
+
+ return rootView;
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
+ menuInflater.inflate(R.menu.select_genres, menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if(super.onOptionsItemSelected(item)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void setPrimaryFragment(boolean primary) {
+ super.setPrimaryFragment(primary);
+ if(rootView != null) {
+ if(primary) {
+ ((ViewGroup)rootView).getChildAt(0).setVisibility(View.VISIBLE);
+ } else {
+ ((ViewGroup)rootView).getChildAt(0).setVisibility(View.GONE);
+ }
+ }
+ }
+
+ @Override
+ protected void refresh(boolean refresh) {
+ load();
+ }
+
+ private void load() {
+ setTitle(R.string.main_albums_genres);
+
+ BackgroundTask<List<Genre>> task = new TabBackgroundTask<List<Genre>>(this) {
+ @Override
+ protected List<Genre> doInBackground() throws Throwable {
+ MusicService musicService = MusicServiceFactory.getMusicService(context);
+
+ List<Genre> genres = new ArrayList<Genre>();
+
+ try {
+ genres = musicService.getGenres(context, this);
+ } catch (Exception x) {
+ Log.e(TAG, "Failed to load genres", x);
+ }
+
+ return genres;
+ }
+
+ @Override
+ protected void done(List<Genre> result) {
+ emptyView.setVisibility(result == null || result.isEmpty() ? View.VISIBLE : View.GONE);
+
+ if (result != null) {
+ genreListView.setAdapter(new GenreAdapter(context, result));
+ }
+
+ }
+ };
+ task.execute();
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ Genre genre = (Genre) parent.getItemAtPosition(position);
+
+ SubsonicFragment fragment = new SelectDirectoryFragment();
+ Bundle args = new Bundle();
+ args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, "genres");
+ args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20);
+ args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0);
+ args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA, genre.getName());
+ fragment.setArguments(args);
+
+ replaceFragment(fragment, R.id.select_genre_layout);
+ }
+}
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/Constants.java b/subsonic-android/src/github/daneren2005/dsub/util/Constants.java index d5399017..5de13e73 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/Constants.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/Constants.java @@ -46,6 +46,7 @@ public final class Constants { public static final String INTENT_EXTRA_NAME_PLAYLIST_ID = "subsonic.playlist.id"; public static final String INTENT_EXTRA_NAME_PLAYLIST_NAME = "subsonic.playlist.name"; public static final String INTENT_EXTRA_NAME_ALBUM_LIST_TYPE = "subsonic.albumlisttype"; + public static final String INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA = "subsonic.albumlistextra"; public static final String INTENT_EXTRA_NAME_ALBUM_LIST_SIZE = "subsonic.albumlistsize"; public static final String INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET = "subsonic.albumlistoffset"; public static final String INTENT_EXTRA_NAME_SHUFFLE = "subsonic.shuffle"; diff --git a/subsonic-android/src/github/daneren2005/dsub/view/AlbumListAdapter.java b/subsonic-android/src/github/daneren2005/dsub/view/AlbumListAdapter.java index 6c8d315a..3ff8350b 100644 --- a/subsonic-android/src/github/daneren2005/dsub/view/AlbumListAdapter.java +++ b/subsonic-android/src/github/daneren2005/dsub/view/AlbumListAdapter.java @@ -34,15 +34,17 @@ public class AlbumListAdapter extends EndlessAdapter { Context context;
ArrayAdapter<MusicDirectory.Entry> adapter;
String type;
+ String extra;
int size;
int offset;
List<MusicDirectory.Entry> entries;
- public AlbumListAdapter(Context context, ArrayAdapter<MusicDirectory.Entry> adapter, String type, int size) {
+ public AlbumListAdapter(Context context, ArrayAdapter<MusicDirectory.Entry> adapter, String type, String extra, int size) {
super(adapter);
this.context = context;
this.adapter = adapter;
this.type = type;
+ this.extra = extra;
this.size = size;
this.offset = size;
}
@@ -50,7 +52,12 @@ public class AlbumListAdapter extends EndlessAdapter { @Override
protected boolean cacheInBackground() throws Exception {
MusicService service = MusicServiceFactory.getMusicService(context);
- MusicDirectory result = service.getAlbumList(type, size, offset, context, null);
+ MusicDirectory result;
+ if("genres".equals(type)) {
+ result = service.getSongsByGenre(extra, size, offset, context, null);
+ } else {
+ result = service.getAlbumList(type, size, offset, context, null);
+ }
entries = result.getChildren();
if(entries.size() > 0) {
return true;
diff --git a/subsonic-android/src/github/daneren2005/dsub/view/GenreAdapter.java b/subsonic-android/src/github/daneren2005/dsub/view/GenreAdapter.java new file mode 100644 index 00000000..b98efd20 --- /dev/null +++ b/subsonic-android/src/github/daneren2005/dsub/view/GenreAdapter.java @@ -0,0 +1,59 @@ +/*
+ 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 2010 (C) Sindre Mehus
+ */
+package github.daneren2005.dsub.view;
+
+import android.widget.ArrayAdapter;
+import android.widget.SectionIndexer;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import github.daneren2005.dsub.R;
+import github.daneren2005.dsub.domain.Genre;
+
+import java.util.List;
+import java.util.Set;
+import java.util.LinkedHashSet;
+import java.util.ArrayList;
+
+/**
+ * @author Sindre Mehus
+*/
+public class GenreAdapter extends ArrayAdapter<Genre>{
+ private Context activity;
+ private List<Genre> genres;
+
+ public GenreAdapter(Context context, List<Genre> genres) {
+ super(context, android.R.layout.simple_list_item_1, genres);
+ this.activity = context;
+ this.genres = genres;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ Genre genre = genres.get(position);
+ GenreView view;
+ if (convertView != null && convertView instanceof GenreView) {
+ view = (GenreView) convertView;
+ } else {
+ view = new GenreView(activity);
+ }
+ view.setGenre(genre);
+ return view;
+ }
+}
diff --git a/subsonic-android/src/github/daneren2005/dsub/view/GenreView.java b/subsonic-android/src/github/daneren2005/dsub/view/GenreView.java new file mode 100644 index 00000000..dbb0248b --- /dev/null +++ b/subsonic-android/src/github/daneren2005/dsub/view/GenreView.java @@ -0,0 +1,53 @@ +/*
+ 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.view;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+import github.daneren2005.dsub.R;
+import github.daneren2005.dsub.domain.Genre;
+
+public class GenreView extends UpdateView {
+ private static final String TAG = GenreView.class.getSimpleName();
+
+ private TextView titleView;
+ private ImageButton starButton;
+ private ImageView moreButton;
+
+ public GenreView(Context context) {
+ super(context);
+ LayoutInflater.from(context).inflate(R.layout.artist_list_item, this, true);
+
+ titleView = (TextView) findViewById(R.id.artist_name);
+ starButton = (ImageButton) findViewById(R.id.artist_star);
+ moreButton = (ImageView) findViewById(R.id.artist_more);
+ moreButton.setClickable(false);
+ }
+
+ public void setGenre(Genre genre) {
+ titleView.setText(genre.getName());
+
+ starButton.setVisibility(View.GONE);
+ starButton.setFocusable(false);
+ }
+}
|