From d9c624ad2396beb5a489193311f7275dfba2da48 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Tue, 27 Oct 2015 17:47:39 -0700 Subject: #508 Add podcast cover art for Subsonic 5.3+ --- .../dsub/adapter/PodcastChannelAdapter.java | 67 ++++++++++++++-------- .../daneren2005/dsub/adapter/SectionAdapter.java | 11 +--- .../daneren2005/dsub/domain/PodcastChannel.java | 8 +++ .../dsub/fragments/SelectPodcastsFragment.java | 11 +++- .../dsub/service/parser/PodcastChannelParser.java | 1 + .../github/daneren2005/dsub/util/ImageLoader.java | 18 +++++- .../github/daneren2005/dsub/view/AlbumView.java | 3 +- .../github/daneren2005/dsub/view/FastScroller.java | 6 ++ .../github/daneren2005/dsub/view/PlaylistView.java | 9 ++- .../daneren2005/dsub/view/PodcastChannelView.java | 23 +++++++- .../github/daneren2005/dsub/view/SongView.java | 2 +- .../github/daneren2005/dsub/view/UpdateView.java | 12 ++++ .../github/daneren2005/dsub/view/UpdateView2.java | 8 +++ app/src/main/res/layout/album_cell_item.xml | 2 +- app/src/main/res/layout/album_list_item.xml | 2 +- app/src/main/res/layout/basic_art_item.xml | 34 +++++++++++ app/src/main/res/layout/basic_cell_item.xml | 39 +++++++++++++ app/src/main/res/layout/playlist_cell_item.xml | 39 ------------- app/src/main/res/layout/playlist_list_item.xml | 34 ----------- app/src/main/res/layout/song_list_item.xml | 2 +- 20 files changed, 209 insertions(+), 122 deletions(-) create mode 100644 app/src/main/res/layout/basic_art_item.xml create mode 100644 app/src/main/res/layout/basic_cell_item.xml delete mode 100644 app/src/main/res/layout/playlist_cell_item.xml delete mode 100644 app/src/main/res/layout/playlist_list_item.xml (limited to 'app') diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/PodcastChannelAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/PodcastChannelAdapter.java index e1ca4814..f637ce39 100644 --- a/app/src/main/java/github/daneren2005/dsub/adapter/PodcastChannelAdapter.java +++ b/app/src/main/java/github/daneren2005/dsub/adapter/PodcastChannelAdapter.java @@ -17,6 +17,7 @@ package github.daneren2005.dsub.adapter; import android.content.Context; import android.view.ViewGroup; import github.daneren2005.dsub.domain.PodcastChannel; +import github.daneren2005.dsub.util.ImageLoader; import github.daneren2005.dsub.view.FastScroller; import github.daneren2005.dsub.view.PodcastChannelView; import github.daneren2005.dsub.view.UpdateView; @@ -24,30 +25,48 @@ import github.daneren2005.dsub.view.UpdateView; import java.util.List; public class PodcastChannelAdapter extends SectionAdapter implements FastScroller.BubbleTextGetter { - public static int VIEW_TYPE_PODCAST = 1; + public static int VIEW_TYPE_PODCAST = 1; + public static int VIEW_TYPE_PODCAST_LINE = 2; + public static int VIEW_TYPE_PODCAST_CELL = 3; - public PodcastChannelAdapter(Context context, List podcasts, OnItemClickedListener listener) { - super(context, podcasts); + private ImageLoader imageLoader; + private boolean largeCell; + + public PodcastChannelAdapter(Context context, List podcasts, ImageLoader imageLoader, OnItemClickedListener listener, boolean largeCell) { + super(context, podcasts); this.onItemClickedListener = listener; - } - - @Override - public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - return new UpdateView.UpdateViewHolder(new PodcastChannelView(context)); - } - - @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, PodcastChannel item, int viewType) { - holder.getUpdateView().setObject(item); - } - - @Override - public int getItemViewType(PodcastChannel item) { - return VIEW_TYPE_PODCAST; - } - - @Override - public String getTextToShowInBubble(int position) { - return getNameIndex(getItemForPosition(position).getName(), true); - } + this.imageLoader = imageLoader; + this.largeCell = largeCell; + } + + @Override + public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + PodcastChannelView view; + if(viewType == VIEW_TYPE_PODCAST) { + view = new PodcastChannelView(context); + } else { + view = new PodcastChannelView(context, imageLoader, viewType == VIEW_TYPE_PODCAST_CELL); + } + + return new UpdateView.UpdateViewHolder(view); + } + + @Override + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, PodcastChannel item, int viewType) { + holder.getUpdateView().setObject(item); + } + + @Override + public int getItemViewType(PodcastChannel item) { + if(imageLoader != null && item.getCoverArt() != null) { + return largeCell ? VIEW_TYPE_PODCAST_CELL : VIEW_TYPE_PODCAST_LINE; + } else { + return VIEW_TYPE_PODCAST; + } + } + + @Override + public String getTextToShowInBubble(int position) { + return getNameIndex(getItemForPosition(position).getName(), true); + } } diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java index 4734e8d0..c2f3c804 100644 --- a/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java +++ b/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java @@ -23,7 +23,6 @@ import android.support.v7.view.ActionMode; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.util.TypedValue; -import android.view.Gravity; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -131,10 +130,7 @@ public abstract class SectionAdapter extends RecyclerView.Adapter extends RecyclerView.Adapter { private static final String TAG = SelectPodcastsFragment.class.getSimpleName(); + + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); + if (Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_LARGE_ALBUM_ART, true) && ServerInfo.checkServerVersion(context, "1.13")) { + largeAlbums = true; + } + } @Override public boolean onOptionsItemSelected(MenuItem item) { @@ -108,7 +117,7 @@ public class SelectPodcastsFragment extends SelectRecyclerFragment channels) { - return new PodcastChannelAdapter(context, channels, this); + return new PodcastChannelAdapter(context, channels, ServerInfo.checkServerVersion(context, "1.13") ? getImageLoader() : null, this, largeAlbums); } @Override diff --git a/app/src/main/java/github/daneren2005/dsub/service/parser/PodcastChannelParser.java b/app/src/main/java/github/daneren2005/dsub/service/parser/PodcastChannelParser.java index 36ed17de..1786e034 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/parser/PodcastChannelParser.java +++ b/app/src/main/java/github/daneren2005/dsub/service/parser/PodcastChannelParser.java @@ -53,6 +53,7 @@ public class PodcastChannelParser extends AbstractParser { channel.setDescription(get("description")); channel.setStatus(get("status")); channel.setErrorMessage(get("errorMessage")); + channel.setCoverArt(get("coverArt")); channels.add(channel); } else if ("error".equals(name)) { handleError(); diff --git a/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java b/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java index 470d72fb..d4bd63ed 100644 --- a/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java +++ b/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java @@ -42,6 +42,7 @@ import github.daneren2005.dsub.R; import github.daneren2005.dsub.domain.ArtistInfo; import github.daneren2005.dsub.domain.MusicDirectory; import github.daneren2005.dsub.domain.Playlist; +import github.daneren2005.dsub.domain.PodcastChannel; import github.daneren2005.dsub.domain.ServerInfo; import github.daneren2005.dsub.service.MusicService; import github.daneren2005.dsub.service.MusicServiceFactory; @@ -56,6 +57,8 @@ import github.daneren2005.dsub.util.compat.RemoteControlClientBase; */ public class ImageLoader { private static final String TAG = ImageLoader.class.getSimpleName(); + private static final String PLAYLIST_PREFIX = "pl-"; + private static final String PODCAST_PREFIX = "pc-"; private Context context; private LruCache cache; @@ -301,10 +304,10 @@ public class ImageLoader { MusicDirectory.Entry entry = new MusicDirectory.Entry(); String id; if(Util.isOffline(context)) { - id = "pl-" + playlist.getName(); + id = PLAYLIST_PREFIX + playlist.getName(); entry.setTitle(playlist.getComment()); } else { - id = "pl-" + playlist.getId(); + id = PLAYLIST_PREFIX + playlist.getId(); entry.setTitle(playlist.getName()); } entry.setId(id); @@ -315,6 +318,17 @@ public class ImageLoader { return loadImage(view, entry, large, crossfade); } + public SilentBackgroundTask loadImage(View view, PodcastChannel channel, boolean large, boolean crossfade) { + MusicDirectory.Entry entry = new MusicDirectory.Entry(); + entry.setId(PODCAST_PREFIX + channel.getId()); + entry.setTitle(channel.getName()); + entry.setCoverArt(channel.getCoverArt()); + // So this isn't treated as a artist + entry.setParent(""); + + return loadImage(view, entry, large, crossfade); + } + private String getKey(String coverArtId, int size) { return coverArtId + size; } diff --git a/app/src/main/java/github/daneren2005/dsub/view/AlbumView.java b/app/src/main/java/github/daneren2005/dsub/view/AlbumView.java index e521babf..343a36f7 100644 --- a/app/src/main/java/github/daneren2005/dsub/view/AlbumView.java +++ b/app/src/main/java/github/daneren2005/dsub/view/AlbumView.java @@ -37,7 +37,6 @@ public class AlbumView extends UpdateView2 { private static final String TAG = AlbumView.class.getSimpleName(); private File file; - private View coverArtView; private TextView titleView; private TextView artistView; private boolean showArtist = true; @@ -59,7 +58,7 @@ public class AlbumView extends UpdateView2 { ratingBar.setFocusable(false); starButton = (ImageButton) findViewById(R.id.album_star); starButton.setFocusable(false); - moreButton = (ImageView) findViewById(R.id.more_button); + moreButton = (ImageView) findViewById(R.id.item_more); checkable = true; } diff --git a/app/src/main/java/github/daneren2005/dsub/view/FastScroller.java b/app/src/main/java/github/daneren2005/dsub/view/FastScroller.java index ba83e46c..ee5900bd 100644 --- a/app/src/main/java/github/daneren2005/dsub/view/FastScroller.java +++ b/app/src/main/java/github/daneren2005/dsub/view/FastScroller.java @@ -264,9 +264,15 @@ public class FastScroller extends LinearLayout { private class ScrollListener extends OnScrollListener { @Override public void onScrolled(RecyclerView rv,int dx,int dy) { + if(recyclerView.getWidth() == 0) { + return; + } registerAdapter(); View firstVisibleView = recyclerView.getChildAt(0); + if(firstVisibleView == null) { + return; + } int firstVisiblePosition = recyclerView.getChildPosition(firstVisibleView); if(visibleRange == -1) { visibleRange = recyclerView.getChildCount(); diff --git a/app/src/main/java/github/daneren2005/dsub/view/PlaylistView.java b/app/src/main/java/github/daneren2005/dsub/view/PlaylistView.java index b8fa3b80..7d475262 100644 --- a/app/src/main/java/github/daneren2005/dsub/view/PlaylistView.java +++ b/app/src/main/java/github/daneren2005/dsub/view/PlaylistView.java @@ -36,17 +36,16 @@ import github.daneren2005.dsub.util.SyncUtil; public class PlaylistView extends UpdateView { private static final String TAG = PlaylistView.class.getSimpleName(); - private View coverArtView; private TextView titleView; private ImageLoader imageLoader; public PlaylistView(Context context, ImageLoader imageLoader, boolean largeCell) { super(context); - LayoutInflater.from(context).inflate(largeCell ? R.layout.playlist_cell_item : R.layout.playlist_list_item, this, true); + LayoutInflater.from(context).inflate(largeCell ? R.layout.basic_cell_item : R.layout.basic_art_item, this, true); - coverArtView = findViewById(R.id.playlist_coverart); - titleView = (TextView) findViewById(R.id.playlist_title); - moreButton = (ImageView) findViewById(R.id.more_button); + coverArtView = findViewById(R.id.item_art); + titleView = (TextView) findViewById(R.id.item_name); + moreButton = (ImageView) findViewById(R.id.item_more); this.imageLoader = imageLoader; } diff --git a/app/src/main/java/github/daneren2005/dsub/view/PodcastChannelView.java b/app/src/main/java/github/daneren2005/dsub/view/PodcastChannelView.java index 4878ad67..4b19eedd 100644 --- a/app/src/main/java/github/daneren2005/dsub/view/PodcastChannelView.java +++ b/app/src/main/java/github/daneren2005/dsub/view/PodcastChannelView.java @@ -19,6 +19,7 @@ package github.daneren2005.dsub.view; import android.content.Context; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageButton; @@ -26,6 +27,7 @@ import android.widget.ImageView; import android.widget.TextView; import github.daneren2005.dsub.R; import github.daneren2005.dsub.domain.PodcastChannel; +import github.daneren2005.dsub.util.ImageLoader; import github.daneren2005.dsub.util.SyncUtil; import github.daneren2005.dsub.util.FileUtil; import java.io.File; @@ -35,20 +37,33 @@ public class PodcastChannelView extends UpdateView { private File file; private TextView titleView; + private ImageLoader imageLoader; public PodcastChannelView(Context context) { + this(context, null, false); + } + public PodcastChannelView(Context context, ImageLoader imageLoader, boolean largeCell) { super(context); - LayoutInflater.from(context).inflate(R.layout.basic_list_item, this, true); + + this.imageLoader = imageLoader; + if(imageLoader != null) { + LayoutInflater.from(context).inflate(largeCell ? R.layout.basic_cell_item : R.layout.basic_art_item, this, true); + } else { + LayoutInflater.from(context).inflate(R.layout.basic_list_item, this, true); + } titleView = (TextView) findViewById(R.id.item_name); starButton = (ImageButton) findViewById(R.id.item_star); - starButton.setFocusable(false); + if(starButton != null) { + starButton.setFocusable(false); + } moreButton = (ImageView) findViewById(R.id.item_more); moreButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { v.showContextMenu(); } }); + coverArtView = findViewById(R.id.item_art); } protected void setObjectImpl(PodcastChannel channel) { @@ -58,6 +73,10 @@ public class PodcastChannelView extends UpdateView { titleView.setText(channel.getUrl()); } file = FileUtil.getPodcastDirectory(context, channel); + + if(imageLoader != null) { + imageTask = imageLoader.loadImage(coverArtView, channel, false, true); + } } @Override diff --git a/app/src/main/java/github/daneren2005/dsub/view/SongView.java b/app/src/main/java/github/daneren2005/dsub/view/SongView.java index dda86162..1027905a 100644 --- a/app/src/main/java/github/daneren2005/dsub/view/SongView.java +++ b/app/src/main/java/github/daneren2005/dsub/view/SongView.java @@ -79,7 +79,7 @@ public class SongView extends UpdateView2 { starButton.setFocusable(false); bookmarkButton = (ImageButton) findViewById(R.id.song_bookmark); bookmarkButton.setFocusable(false); - moreButton = (ImageView) findViewById(R.id.more_button); + moreButton = (ImageView) findViewById(R.id.item_more); bottomRowView = findViewById(R.id.song_bottom); } diff --git a/app/src/main/java/github/daneren2005/dsub/view/UpdateView.java b/app/src/main/java/github/daneren2005/dsub/view/UpdateView.java index ef5edc00..d59f23d0 100644 --- a/app/src/main/java/github/daneren2005/dsub/view/UpdateView.java +++ b/app/src/main/java/github/daneren2005/dsub/view/UpdateView.java @@ -55,6 +55,7 @@ public abstract class UpdateView extends LinearLayout { protected RatingBar ratingBar; protected ImageButton starButton; protected ImageView moreButton; + protected View coverArtView; protected boolean exists = false; protected boolean pinned = false; @@ -93,7 +94,18 @@ public abstract class UpdateView extends LinearLayout { } public void setObject(T obj) { + if(item == obj) { + return; + } + item = obj; + if(imageTask != null) { + imageTask.cancel(); + imageTask = null; + } + if(coverArtView != null && coverArtView instanceof ImageView) { + ((ImageView) coverArtView).setImageDrawable(null); + } setObjectImpl(obj); updateBackground(); update(); diff --git a/app/src/main/java/github/daneren2005/dsub/view/UpdateView2.java b/app/src/main/java/github/daneren2005/dsub/view/UpdateView2.java index 0f0b5455..7dccba13 100644 --- a/app/src/main/java/github/daneren2005/dsub/view/UpdateView2.java +++ b/app/src/main/java/github/daneren2005/dsub/view/UpdateView2.java @@ -1,6 +1,7 @@ package github.daneren2005.dsub.view; import android.content.Context; +import android.widget.ImageView; public abstract class UpdateView2 extends UpdateView { protected T2 item2; @@ -18,12 +19,19 @@ public abstract class UpdateView2 extends UpdateView { } @Override public void setObject(T1 obj1, Object obj2) { + if(item == obj1 && item2 == obj2) { + return; + } + item = obj1; item2 = (T2) obj2; if(imageTask != null) { imageTask.cancel(); imageTask = null; } + if(coverArtView != null && coverArtView instanceof ImageView) { + ((ImageView) coverArtView).setImageDrawable(null); + } setObjectImpl(item, item2); backgroundHandler.post(new Runnable() { diff --git a/app/src/main/res/layout/album_cell_item.xml b/app/src/main/res/layout/album_cell_item.xml index 244c6f1f..f6693a7f 100644 --- a/app/src/main/res/layout/album_cell_item.xml +++ b/app/src/main/res/layout/album_cell_item.xml @@ -78,7 +78,7 @@ + + + + + + + + diff --git a/app/src/main/res/layout/basic_cell_item.xml b/app/src/main/res/layout/basic_cell_item.xml new file mode 100644 index 00000000..f522b196 --- /dev/null +++ b/app/src/main/res/layout/basic_cell_item.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/playlist_cell_item.xml b/app/src/main/res/layout/playlist_cell_item.xml deleted file mode 100644 index 7e6ab0cd..00000000 --- a/app/src/main/res/layout/playlist_cell_item.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/playlist_list_item.xml b/app/src/main/res/layout/playlist_list_item.xml deleted file mode 100644 index c1cc7b3c..00000000 --- a/app/src/main/res/layout/playlist_list_item.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - diff --git a/app/src/main/res/layout/song_list_item.xml b/app/src/main/res/layout/song_list_item.xml index 429dc142..6bf025b8 100644 --- a/app/src/main/res/layout/song_list_item.xml +++ b/app/src/main/res/layout/song_list_item.xml @@ -112,7 +112,7 @@