From 6d54b5ab69378efc3db83e67f5317f969e9dd0d9 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Wed, 28 Oct 2015 20:01:22 -0700 Subject: #590 Display newest podcast episodes at top --- .../dsub/adapter/PodcastChannelAdapter.java | 61 ++++++-- .../github/daneren2005/dsub/domain/ServerInfo.java | 3 + .../dsub/fragments/SelectDirectoryFragment.java | 70 --------- .../dsub/fragments/SelectPodcastsFragment.java | 165 ++++++++++++++++----- .../dsub/fragments/SubsonicFragment.java | 68 +++++++++ .../dsub/service/CachedMusicService.java | 7 +- .../daneren2005/dsub/service/MusicService.java | 2 + .../dsub/service/OfflineMusicService.java | 7 +- .../daneren2005/dsub/service/RESTMusicService.java | 11 ++ .../dsub/service/parser/PodcastEntryParser.java | 5 +- app/src/main/res/values/strings.xml | 1 + 11 files changed, 271 insertions(+), 129 deletions(-) (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 f637ce39..6d995d56 100644 --- a/app/src/main/java/github/daneren2005/dsub/adapter/PodcastChannelAdapter.java +++ b/app/src/main/java/github/daneren2005/dsub/adapter/PodcastChannelAdapter.java @@ -16,57 +16,88 @@ package github.daneren2005.dsub.adapter; import android.content.Context; import android.view.ViewGroup; + +import github.daneren2005.dsub.domain.MusicDirectory; import github.daneren2005.dsub.domain.PodcastChannel; +import github.daneren2005.dsub.domain.PodcastEpisode; import github.daneren2005.dsub.util.ImageLoader; import github.daneren2005.dsub.view.FastScroller; import github.daneren2005.dsub.view.PodcastChannelView; +import github.daneren2005.dsub.view.SongView; import github.daneren2005.dsub.view.UpdateView; +import java.io.Serializable; import java.util.List; -public class PodcastChannelAdapter extends SectionAdapter implements FastScroller.BubbleTextGetter { - public static int VIEW_TYPE_PODCAST = 1; +public class PodcastChannelAdapter extends SectionAdapter implements FastScroller.BubbleTextGetter { + public static int VIEW_TYPE_PODCAST_LEGACY = 1; public static int VIEW_TYPE_PODCAST_LINE = 2; public static int VIEW_TYPE_PODCAST_CELL = 3; + public static int VIEW_TYPE_PODCAST_EPISODE = 4; private ImageLoader imageLoader; private boolean largeCell; - public PodcastChannelAdapter(Context context, List podcasts, ImageLoader imageLoader, OnItemClickedListener listener, boolean largeCell) { + public PodcastChannelAdapter(Context context, List podcasts, ImageLoader imageLoader, OnItemClickedListener listener, boolean largeCell) { super(context, podcasts); + this.imageLoader = imageLoader; this.onItemClickedListener = listener; + this.largeCell = largeCell; + } + public PodcastChannelAdapter(Context context, List headers, List> sections, ImageLoader imageLoader, OnItemClickedListener listener, boolean largeCell) { + super(context, headers, sections); this.imageLoader = imageLoader; + this.onItemClickedListener = listener; this.largeCell = largeCell; } @Override public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - PodcastChannelView view; - if(viewType == VIEW_TYPE_PODCAST) { - view = new PodcastChannelView(context); + UpdateView updateView; + if(viewType == VIEW_TYPE_PODCAST_EPISODE) { + updateView = new SongView(context); + } else if(viewType == VIEW_TYPE_PODCAST_LEGACY) { + updateView = new PodcastChannelView(context); } else { - view = new PodcastChannelView(context, imageLoader, viewType == VIEW_TYPE_PODCAST_CELL); + updateView = new PodcastChannelView(context, imageLoader, viewType == VIEW_TYPE_PODCAST_CELL); } - return new UpdateView.UpdateViewHolder(view); + return new UpdateView.UpdateViewHolder(updateView); } @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, PodcastChannel item, int viewType) { - holder.getUpdateView().setObject(item); + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Serializable item, int viewType) { + if(viewType == VIEW_TYPE_PODCAST_EPISODE) { + PodcastEpisode episode = (PodcastEpisode) item; + holder.getUpdateView().setObject(item, !episode.isVideo()); + } else { + 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; + public int getItemViewType(Serializable item) { + if(item instanceof PodcastChannel) { + PodcastChannel channel = (PodcastChannel) item; + + if (imageLoader != null && channel.getCoverArt() != null) { + return largeCell ? VIEW_TYPE_PODCAST_CELL : VIEW_TYPE_PODCAST_LINE; + } else { + return VIEW_TYPE_PODCAST_LEGACY; + } } else { - return VIEW_TYPE_PODCAST; + return VIEW_TYPE_PODCAST_EPISODE; } } @Override public String getTextToShowInBubble(int position) { - return getNameIndex(getItemForPosition(position).getName(), true); + Serializable item = getItemForPosition(position); + if(item instanceof PodcastChannel) { + PodcastChannel channel = (PodcastChannel) item; + return getNameIndex(channel.getName(), true); + } else { + return null; + } } } diff --git a/app/src/main/java/github/daneren2005/dsub/domain/ServerInfo.java b/app/src/main/java/github/daneren2005/dsub/domain/ServerInfo.java index 6cb5bc1f..73037c4a 100644 --- a/app/src/main/java/github/daneren2005/dsub/domain/ServerInfo.java +++ b/app/src/main/java/github/daneren2005/dsub/domain/ServerInfo.java @@ -229,4 +229,7 @@ public class ServerInfo implements Serializable { public static boolean hasSimilarArtists(Context context) { return !ServerInfo.isMadsonic(context) || ServerInfo.checkServerVersion(context, "2.0"); } + public static boolean hasNewestPodcastEpisodes(Context context) { + return ServerInfo.checkServerVersion(context, "1.13"); + } } diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java index c7d8e191..83e3e7e7 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java @@ -321,17 +321,6 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Section if((albumListType == null || (entry.getParent() == null && entry.getArtistId() == null)) && !Util.isOffline(context)) { menu.removeItem(R.id.album_menu_show_artist); } - if(podcastId != null && !Util.isOffline(context)) { - if(UserUtil.canPodcast()) { - String status = ((PodcastEpisode)entry).getStatus(); - if("completed".equals(status)) { - menu.removeItem(R.id.song_menu_server_download); - } - } else { - menu.removeItem(R.id.song_menu_server_download); - menu.removeItem(R.id.song_menu_server_delete); - } - } recreateContextMenu(menu); } @@ -345,12 +334,6 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Section case R.id.song_menu_remove_playlist: removeFromPlaylist(playlistId, playlistName, Arrays.asList(entries.indexOf(entry))); break; - case R.id.song_menu_server_download: - downloadPodcastEpisode((PodcastEpisode) entry); - break; - case R.id.song_menu_server_delete: - deletePodcastEpisode((PodcastEpisode) entry); - break; } return true; @@ -952,59 +935,6 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Section } }.execute(); } - - public void downloadPodcastEpisode(final PodcastEpisode episode) { - new LoadingTask(context, true) { - @Override - protected Void doInBackground() throws Throwable { - MusicService musicService = MusicServiceFactory.getMusicService(context); - musicService.downloadPodcastEpisode(episode.getEpisodeId(), context, null); - return null; - } - - @Override - protected void done(Void result) { - Util.toast(context, context.getResources().getString(R.string.select_podcasts_downloading, episode.getTitle())); - } - - @Override - protected void error(Throwable error) { - Util.toast(context, getErrorMessage(error), false); - } - }.execute(); - } - - public void deletePodcastEpisode(final PodcastEpisode episode) { - Util.confirmDialog(context, R.string.common_delete, episode.getTitle(), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - new LoadingTask(context, true) { - @Override - protected Void doInBackground() throws Throwable { - MusicService musicService = MusicServiceFactory.getMusicService(context); - musicService.deletePodcastEpisode(episode.getEpisodeId(), episode.getParent(), null, context); - if (getDownloadService() != null) { - List episodeList = new ArrayList(1); - episodeList.add(episode); - getDownloadService().delete(episodeList); - } - return null; - } - - @Override - protected void done(Void result) { - entryGridAdapter.removeItem(episode); - } - - @Override - protected void error(Throwable error) { - Log.w(TAG, "Failed to delete podcast episode", error); - Util.toast(context, getErrorMessage(error), false); - } - }.execute(); - } - }); - } public void unstarSelected() { List selected = getSelectedEntries(); diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectPodcastsFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectPodcastsFragment.java index 90a48e3a..82c36333 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectPodcastsFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectPodcastsFragment.java @@ -14,9 +14,12 @@ */ package github.daneren2005.dsub.fragments; +import android.content.res.Resources; import android.support.v7.app.AlertDialog; import android.content.DialogInterface; import android.os.Bundle; +import android.support.v7.widget.GridLayoutManager; +import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -26,6 +29,7 @@ import github.daneren2005.dsub.R; import github.daneren2005.dsub.adapter.SectionAdapter; import github.daneren2005.dsub.domain.MusicDirectory; import github.daneren2005.dsub.domain.PodcastChannel; +import github.daneren2005.dsub.domain.PodcastEpisode; import github.daneren2005.dsub.domain.ServerInfo; import github.daneren2005.dsub.service.MusicService; import github.daneren2005.dsub.service.MusicServiceFactory; @@ -41,12 +45,16 @@ import github.daneren2005.dsub.util.Util; import github.daneren2005.dsub.adapter.PodcastChannelAdapter; import github.daneren2005.dsub.view.UpdateView; +import java.io.Serializable; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -public class SelectPodcastsFragment extends SelectRecyclerFragment { +public class SelectPodcastsFragment extends SelectRecyclerFragment { private static final String TAG = SelectPodcastsFragment.class.getSimpleName(); + private MusicDirectory newestEpisodes; + @Override public void onCreate(Bundle bundle) { super.onCreate(bundle); @@ -74,37 +82,48 @@ public class SelectPodcastsFragment extends SelectRecyclerFragment updateView, PodcastChannel podcast) { - if(!Util.isOffline(context) && UserUtil.canPodcast()) { - menuInflater.inflate(R.menu.select_podcasts_context, menu); - - if(SyncUtil.isSyncedPodcast(context, podcast.getId())) { - menu.removeItem(R.id.podcast_menu_sync); + public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Serializable item) { + if(item instanceof PodcastChannel) { + PodcastChannel channel = (PodcastChannel) item; + if (!Util.isOffline(context) && UserUtil.canPodcast()) { + menuInflater.inflate(R.menu.select_podcasts_context, menu); + + if (SyncUtil.isSyncedPodcast(context, channel.getId())) { + menu.removeItem(R.id.podcast_menu_sync); + } else { + menu.removeItem(R.id.podcast_menu_stop_sync); + } } else { - menu.removeItem(R.id.podcast_menu_stop_sync); + menuInflater.inflate(R.menu.select_podcasts_context_offline, menu); } } else { - menuInflater.inflate(R.menu.select_podcasts_context_offline, menu); + onCreateContextMenuSupport(menu, menuInflater, updateView, item); } recreateContextMenu(menu); } @Override - public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, PodcastChannel channel) { - switch (menuItem.getItemId()) { - case R.id.podcast_menu_sync: - syncPodcast(channel); - break; - case R.id.podcast_menu_stop_sync: - stopSyncPodcast(channel); - break; - case R.id.podcast_channel_info: - displayPodcastInfo(channel); - break; - case R.id.podcast_channel_delete: - deletePodcast(channel); - break; + public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Serializable item) { + if(item instanceof PodcastChannel) { + PodcastChannel channel = (PodcastChannel) item; + + switch (menuItem.getItemId()) { + case R.id.podcast_menu_sync: + syncPodcast(channel); + break; + case R.id.podcast_menu_stop_sync: + stopSyncPodcast(channel); + break; + case R.id.podcast_channel_info: + displayPodcastInfo(channel); + break; + case R.id.podcast_channel_delete: + deletePodcast(channel); + break; + } + } else { + return onContextItemSelected(menuItem, item); } return true; @@ -116,13 +135,43 @@ public class SelectPodcastsFragment extends SelectRecyclerFragment channels) { - return new PodcastChannelAdapter(context, channels, ServerInfo.checkServerVersion(context, "1.13") ? getImageLoader() : null, this, largeAlbums); + public SectionAdapter getAdapter(List channels) { + if(newestEpisodes == null || newestEpisodes.getChildrenSize() == 0) { + return new PodcastChannelAdapter(context, channels, ServerInfo.checkServerVersion(context, "1.13") ? getImageLoader() : null, this, largeAlbums); + } else { + Resources res = context.getResources(); + List headers = Arrays.asList(res.getString(R.string.main_albums_newest), res.getString(R.string.select_podcasts_channels)); + + List serializableEpisodes = new ArrayList<>(); + serializableEpisodes.addAll(newestEpisodes.getChildren()); + + List> sections = new ArrayList<>(); + sections.add(serializableEpisodes); + sections.add(channels); + + return new PodcastChannelAdapter(context, headers, sections, ServerInfo.checkServerVersion(context, "1.13") ? getImageLoader() : null, this, largeAlbums); + } } @Override - public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { - return musicService.getPodcastChannels(refresh, context, listener); + public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { + List channels = musicService.getPodcastChannels(refresh, context, listener); + + if(!Util.isOffline(context) && ServerInfo.hasNewestPodcastEpisodes(context)) { + try { + newestEpisodes = musicService.getNewestPodcastEpisodes(3, context, listener); + } catch (Exception e) { + Log.e(TAG, "Failed to download newest episodes", e); + newestEpisodes = null; + } + } else { + newestEpisodes = null; + } + + List serializableList = new ArrayList<>(); + serializableList.addAll(channels); + + return serializableList; } @Override @@ -131,23 +180,59 @@ public class SelectPodcastsFragment extends SelectRecyclerFragment updateView, PodcastChannel channel) { - if("error".equals(channel.getStatus())) { - Util.toast(context, context.getResources().getString(R.string.select_podcasts_invalid_podcast_channel, channel.getErrorMessage() == null ? "error" : channel.getErrorMessage())); - } else if("downloading".equals(channel.getStatus())) { - Util.toast(context, R.string.select_podcasts_initializing); + public void onItemClicked(UpdateView updateView, Serializable item) { + if(item instanceof PodcastChannel) { + PodcastChannel channel = (PodcastChannel) item; + if ("error".equals(channel.getStatus())) { + Util.toast(context, context.getResources().getString(R.string.select_podcasts_invalid_podcast_channel, channel.getErrorMessage() == null ? "error" : channel.getErrorMessage())); + } else if ("downloading".equals(channel.getStatus())) { + Util.toast(context, R.string.select_podcasts_initializing); + } else { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_PODCAST_ID, channel.getId()); + args.putString(Constants.INTENT_EXTRA_NAME_PODCAST_NAME, channel.getName()); + args.putString(Constants.INTENT_EXTRA_NAME_PODCAST_DESCRIPTION, channel.getDescription()); + fragment.setArguments(args); + + replaceFragment(fragment); + } } else { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_PODCAST_ID, channel.getId()); - args.putString(Constants.INTENT_EXTRA_NAME_PODCAST_NAME, channel.getName()); - args.putString(Constants.INTENT_EXTRA_NAME_PODCAST_DESCRIPTION, channel.getDescription()); - fragment.setArguments(args); - - replaceFragment(fragment); + PodcastEpisode episode = (PodcastEpisode) item; + + String status = episode.getStatus(); + if("error".equals(status)) { + Util.toast(context, R.string.select_podcasts_error); + return; + } else if(!"completed".equals(status)) { + Util.toast(context, R.string.select_podcasts_skipped); + return; + } + + playNow(Arrays.asList((MusicDirectory.Entry) episode)); } } + @Override + public GridLayoutManager.SpanSizeLookup getSpanSizeLookup(final int columns) { + return new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + SectionAdapter adapter = getCurrentAdapter(); + if(adapter != null) { + int viewType = getCurrentAdapter().getItemViewType(position); + if (viewType == SectionAdapter.VIEW_TYPE_HEADER || viewType == PodcastChannelAdapter.VIEW_TYPE_PODCAST_EPISODE) { + return columns; + } else { + return 1; + } + } else { + return 1; + } + } + }; + } + public void refreshPodcasts() { new SilentBackgroundTask(context) { @Override diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java index 7baf9009..1b3d08cc 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java @@ -235,6 +235,15 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR if(entry.getBookmark() == null) { menu.removeItem(R.id.bookmark_menu_delete); } + if(UserUtil.canPodcast()) { + String status = ((PodcastEpisode)entry).getStatus(); + if("completed".equals(status)) { + menu.removeItem(R.id.song_menu_server_download); + } + } else { + menu.removeItem(R.id.song_menu_server_download); + menu.removeItem(R.id.song_menu_server_delete); + } } } else if (entry.isDirectory()) { @@ -408,6 +417,12 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR case R.id.song_menu_show_artist: showArtist((Entry) selectedItem); break; + case R.id.song_menu_server_download: + downloadPodcastEpisode((PodcastEpisode) entry); + break; + case R.id.song_menu_server_delete: + deletePodcastEpisode((PodcastEpisode) entry); + break; case R.id.bookmark_menu_delete: deleteBookmark(entry, null); break; @@ -1674,6 +1689,59 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR }); } + public void downloadPodcastEpisode(final PodcastEpisode episode) { + new LoadingTask(context, true) { + @Override + protected Void doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + musicService.downloadPodcastEpisode(episode.getEpisodeId(), context, null); + return null; + } + + @Override + protected void done(Void result) { + Util.toast(context, context.getResources().getString(R.string.select_podcasts_downloading, episode.getTitle())); + } + + @Override + protected void error(Throwable error) { + Util.toast(context, getErrorMessage(error), false); + } + }.execute(); + } + + public void deletePodcastEpisode(final PodcastEpisode episode) { + Util.confirmDialog(context, R.string.common_delete, episode.getTitle(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + new LoadingTask(context, true) { + @Override + protected Void doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + musicService.deletePodcastEpisode(episode.getEpisodeId(), episode.getParent(), null, context); + if (getDownloadService() != null) { + List episodeList = new ArrayList(1); + episodeList.add(episode); + getDownloadService().delete(episodeList); + } + return null; + } + + @Override + protected void done(Void result) { + getCurrentAdapter().removeItem(episode); + } + + @Override + protected void error(Throwable error) { + Log.w(TAG, "Failed to delete podcast episode", error); + Util.toast(context, getErrorMessage(error), false); + } + }.execute(); + } + }); + } + public SectionAdapter getCurrentAdapter() { return null; } public void stopActionMode() { SectionAdapter adapter = getCurrentAdapter(); diff --git a/app/src/main/java/github/daneren2005/dsub/service/CachedMusicService.java b/app/src/main/java/github/daneren2005/dsub/service/CachedMusicService.java index 8a17d8f3..1a6658e3 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/CachedMusicService.java +++ b/app/src/main/java/github/daneren2005/dsub/service/CachedMusicService.java @@ -784,7 +784,12 @@ public class CachedMusicService implements MusicService { return result; } - + + @Override + public MusicDirectory getNewestPodcastEpisodes(int count, Context context, ProgressListener progressListener) throws Exception { + return musicService.getNewestPodcastEpisodes(count, context, progressListener); + } + @Override public void refreshPodcasts(Context context, ProgressListener progressListener) throws Exception { musicService.refreshPodcasts(context, progressListener); diff --git a/app/src/main/java/github/daneren2005/dsub/service/MusicService.java b/app/src/main/java/github/daneren2005/dsub/service/MusicService.java index 0cc8d484..2972bb7c 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/MusicService.java +++ b/app/src/main/java/github/daneren2005/dsub/service/MusicService.java @@ -146,6 +146,8 @@ public interface MusicService { List getPodcastChannels(boolean refresh, Context context, ProgressListener progressListener) throws Exception; MusicDirectory getPodcastEpisodes(boolean refresh, String id, Context context, ProgressListener progressListener) throws Exception; + + MusicDirectory getNewestPodcastEpisodes(int count, Context context, ProgressListener progressListener) throws Exception; void refreshPodcasts(Context context, ProgressListener progressListener) throws Exception; diff --git a/app/src/main/java/github/daneren2005/dsub/service/OfflineMusicService.java b/app/src/main/java/github/daneren2005/dsub/service/OfflineMusicService.java index 17aaf804..156ffa71 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/OfflineMusicService.java +++ b/app/src/main/java/github/daneren2005/dsub/service/OfflineMusicService.java @@ -756,7 +756,12 @@ public class OfflineMusicService implements MusicService { public MusicDirectory getPodcastEpisodes(boolean refresh, String id, Context context, ProgressListener progressListener) throws Exception { return getMusicDirectory(FileUtil.getPodcastDirectory(context, id).getPath(), null, false, context, progressListener, true); } - + + @Override + public MusicDirectory getNewestPodcastEpisodes(int count, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } + @Override public void refreshPodcasts(Context context, ProgressListener progressListener) throws Exception { throw new OfflineException(ERRORMSG); diff --git a/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java b/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java index 24a75c73..9ec77897 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java +++ b/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java @@ -1301,6 +1301,17 @@ public class RESTMusicService implements MusicService { } @Override + public MusicDirectory getNewestPodcastEpisodes(int count, Context context, ProgressListener progressListener) throws Exception { + Reader reader = getReader(context, progressListener, "getNewestPodcasts", null, Arrays.asList("count"), Arrays.asList(count)); + + try { + return new PodcastEntryParser(context, getInstance(context)).parse(null, reader, progressListener); + } finally { + Util.close(reader); + } + } + + @Override public void refreshPodcasts(Context context, ProgressListener progressListener) throws Exception { checkServerVersion(context, "1.9", "Refresh podcasts not supported."); diff --git a/app/src/main/java/github/daneren2005/dsub/service/parser/PodcastEntryParser.java b/app/src/main/java/github/daneren2005/dsub/service/parser/PodcastEntryParser.java index 00089363..34a5bffc 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/parser/PodcastEntryParser.java +++ b/app/src/main/java/github/daneren2005/dsub/service/parser/PodcastEntryParser.java @@ -58,8 +58,9 @@ public class PodcastEntryParser extends AbstractParser { } else { valid = false; } - } - else if ("episode".equals(name) && valid) { + } else if("newestPodcasts".equals(name)) { + valid = true; + } else if ("episode".equals(name) && valid) { PodcastEpisode episode = new PodcastEpisode(); episode.setEpisodeId(get("id")); episode.setId(get("streamId")); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 33bbc1fd..303a8e0e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -179,6 +179,7 @@ Failed to add podcast Invalid podcast channel: %s Delete podcast + Podcast Channels Playlist is empty Shuffle list is loading... -- cgit v1.2.3