From 5e3992fd414c145c0df1e29ffa3e19e89166378f Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Sun, 2 Jun 2013 21:55:32 -0700 Subject: Added Genre fragment (thanks archrival) --- subsonic-android/res/layout/main_buttons.xml | 12 ++ subsonic-android/res/layout/select_genres.xml | 29 +++++ subsonic-android/res/menu/select_genres.xml | 18 +++ subsonic-android/res/values/strings.xml | 3 + .../daneren2005/dsub/fragments/MainFragment.java | 26 ++-- .../dsub/fragments/SelectDirectoryFragment.java | 8 +- .../dsub/fragments/SelectGenreFragment.java | 141 +++++++++++++++++++++ .../github/daneren2005/dsub/util/Constants.java | 1 + .../daneren2005/dsub/view/AlbumListAdapter.java | 11 +- .../github/daneren2005/dsub/view/GenreAdapter.java | 59 +++++++++ .../github/daneren2005/dsub/view/GenreView.java | 53 ++++++++ 11 files changed, 349 insertions(+), 12 deletions(-) create mode 100644 subsonic-android/res/layout/select_genres.xml create mode 100644 subsonic-android/res/menu/select_genres.xml create mode 100644 subsonic-android/src/github/daneren2005/dsub/fragments/SelectGenreFragment.java create mode 100644 subsonic-android/src/github/daneren2005/dsub/view/GenreAdapter.java create mode 100644 subsonic-android/src/github/daneren2005/dsub/view/GenreView.java 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"/> + + + + + + + + + + + + \ 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 @@ + + + + + + + + \ 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 @@ Top rated Starred Random + Genres Press back again to exit Search @@ -114,6 +115,8 @@ Later Trial period is over + No genres found + No saved playlists on server Playlist is empty 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 . + + 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> task = new TabBackgroundTask>(this) { + @Override + protected List doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + + List genres = new ArrayList(); + + try { + genres = musicService.getGenres(context, this); + } catch (Exception x) { + Log.e(TAG, "Failed to load genres", x); + } + + return genres; + } + + @Override + protected void done(List 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 adapter; String type; + String extra; int size; int offset; List entries; - public AlbumListAdapter(Context context, ArrayAdapter adapter, String type, int size) { + public AlbumListAdapter(Context context, ArrayAdapter 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 . + + 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{ + private Context activity; + private List genres; + + public GenreAdapter(Context context, List 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 . + + 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); + } +} -- cgit v1.2.3