From d585e37e11d01b61773b287ce2e6cb5ae24380a1 Mon Sep 17 00:00:00 2001 From: LukasBrilla5 <114982148+LukasBrilla5@users.noreply.github.com> Date: Fri, 18 Nov 2022 20:08:48 +0100 Subject: [PATCH] Add button to refresh episode chapters (#6177) --- .../fragment/AudioPlayerFragment.java | 2 +- .../antennapod/fragment/ChaptersFragment.java | 31 ++++++++++++---- .../antennapod/fragment/CoverFragment.java | 2 +- .../handler/MediaDownloadedHandler.java | 2 +- .../playback/PlaybackServiceTaskManager.java | 2 +- .../antennapod/core/util/ChapterUtils.java | 35 ++++++++++++------- 6 files changed, 51 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java index 7d81675b5..1539ebecf 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/AudioPlayerFragment.java @@ -263,7 +263,7 @@ public class AudioPlayerFragment extends Fragment implements Playable media = controller.getMedia(); if (media != null) { if (includingChapters) { - ChapterUtils.loadChapters(media, getContext()); + ChapterUtils.loadChapters(media, getContext(), false); } emitter.onSuccess(media); } else { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java index 0443716b0..809ca96c5 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ChaptersFragment.java @@ -1,13 +1,16 @@ package de.danoeh.antennapod.fragment; import android.app.Dialog; +import android.content.DialogInterface; import android.os.Bundle; +import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ProgressBar; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatDialogFragment; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.recyclerview.widget.DividerItemDecoration; @@ -20,6 +23,7 @@ import de.danoeh.antennapod.core.util.ChapterUtils; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.model.feed.Chapter; +import de.danoeh.antennapod.model.feed.FeedMedia; import de.danoeh.antennapod.model.playback.Playable; import de.danoeh.antennapod.playback.base.PlayerStatus; import io.reactivex.Maybe; @@ -43,11 +47,21 @@ public class ChaptersFragment extends AppCompatDialogFragment { @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { - return new MaterialAlertDialogBuilder(requireContext()) + + AlertDialog dialog = new MaterialAlertDialogBuilder(requireContext()) .setTitle(getString(R.string.chapters_label)) .setView(onCreateView(getLayoutInflater())) - .setNegativeButton(getString(R.string.close_label), null) //dismisses + .setPositiveButton(getString(R.string.close_label), null) //dismisses + .setNeutralButton(getString(R.string.refresh_label), null) .create(); + dialog.show(); + dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setVisibility(View.INVISIBLE); + dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener(v -> { + progressBar.setVisibility(View.VISIBLE); + loadMediaInfo(true); + }); + + return dialog; } @@ -86,12 +100,12 @@ public class ChaptersFragment extends AppCompatDialogFragment { controller = new PlaybackController(getActivity()) { @Override public void loadMediaInfo() { - ChaptersFragment.this.loadMediaInfo(); + ChaptersFragment.this.loadMediaInfo(false); } }; controller.init(); EventBus.getDefault().register(this); - loadMediaInfo(); + loadMediaInfo(false); } @Override @@ -119,14 +133,14 @@ public class ChaptersFragment extends AppCompatDialogFragment { return ChapterUtils.getCurrentChapterIndex(media, controller.getPosition()); } - private void loadMediaInfo() { + private void loadMediaInfo(boolean forceRefresh) { if (disposable != null) { disposable.dispose(); } disposable = Maybe.create(emitter -> { Playable media = controller.getMedia(); if (media != null) { - ChapterUtils.loadChapters(media, getContext()); + ChapterUtils.loadChapters(media, getContext(), forceRefresh); emitter.onSuccess(media); } else { emitter.onComplete(); @@ -150,6 +164,11 @@ public class ChaptersFragment extends AppCompatDialogFragment { progressBar.setVisibility(View.GONE); } adapter.setMedia(media); + ((AlertDialog) getDialog()).getButton(DialogInterface.BUTTON_NEUTRAL).setVisibility(View.INVISIBLE); + if (media instanceof FeedMedia && ((FeedMedia) media).getItem() != null + && !TextUtils.isEmpty(((FeedMedia) media).getItem().getPodcastIndexChapterUrl())) { + ((AlertDialog) getDialog()).getButton(DialogInterface.BUTTON_NEUTRAL).setVisibility(View.VISIBLE); + } int positionOfCurrentChapter = getCurrentChapter(media); updateChapterSelection(positionOfCurrentChapter, true); } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java index 1632c1fb4..f29f64b5c 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/CoverFragment.java @@ -95,7 +95,7 @@ public class CoverFragment extends Fragment { Playable media = controller.getMedia(); if (media != null) { if (includingChapters) { - ChapterUtils.loadChapters(media, getContext()); + ChapterUtils.loadChapters(media, getContext(), false); } emitter.onSuccess(media); } else { diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java index 442e3173d..897300ca8 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/handler/MediaDownloadedHandler.java @@ -59,7 +59,7 @@ public class MediaDownloadedHandler implements Runnable { } if (media.getItem() != null && media.getItem().getPodcastIndexChapterUrl() != null) { - ChapterUtils.loadChaptersFromUrl(media.getItem().getPodcastIndexChapterUrl()); + ChapterUtils.loadChaptersFromUrl(media.getItem().getPodcastIndexChapterUrl(), false); } // Get duration MediaMetadataRetriever mmr = new MediaMetadataRetriever(); diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java index 19032ba18..3111d01bc 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceTaskManager.java @@ -227,7 +227,7 @@ public class PlaybackServiceTaskManager { if (media.getChapters() == null) { chapterLoaderFuture = Completable.create(emitter -> { - ChapterUtils.loadChapters(media, context); + ChapterUtils.loadChapters(media, context, false); emitter.onComplete(); }) .subscribeOn(Schedulers.io()) diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java index cc63bf2b0..084b34e76 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java +++ b/core/src/main/java/de/danoeh/antennapod/core/util/ChapterUtils.java @@ -54,8 +54,8 @@ public class ChapterUtils { return chapters.size() - 1; } - public static void loadChapters(Playable playable, Context context) { - if (playable.getChapters() != null) { + public static void loadChapters(Playable playable, Context context, boolean forceRefresh) { + if (playable.getChapters() != null && !forceRefresh) { // Already loaded return; } @@ -73,7 +73,7 @@ public class ChapterUtils { if (!TextUtils.isEmpty(feedMedia.getItem().getPodcastIndexChapterUrl())) { chaptersFromPodcastIndex = ChapterUtils.loadChaptersFromUrl( - feedMedia.getItem().getPodcastIndexChapterUrl()); + feedMedia.getItem().getPodcastIndexChapterUrl(), forceRefresh); } } @@ -135,23 +135,32 @@ public class ChapterUtils { } } - public static List loadChaptersFromUrl(String url) { + public static List loadChaptersFromUrl(String url, boolean forceRefresh) { + if (forceRefresh) { + return loadChaptersFromUrl(url, CacheControl.FORCE_NETWORK); + } + List cachedChapters = loadChaptersFromUrl(url, CacheControl.FORCE_CACHE); + if (cachedChapters == null || cachedChapters.size() <= 1) { + // Some publishers use one dummy chapter before actual chapters are available + return loadChaptersFromUrl(url, CacheControl.FORCE_NETWORK); + } + return cachedChapters; + } + + private static List loadChaptersFromUrl(String url, CacheControl cacheControl) { + Response response = null; try { - Request request = new Request.Builder().url(url).cacheControl(CacheControl.FORCE_CACHE).build(); - Response response = AntennapodHttpClient.getHttpClient().newCall(request).execute(); - if (response.isSuccessful() && response.body() != null) { - List chapters = PodcastIndexChapterParser.parse(response.body().string()); - if (chapters != null && !chapters.isEmpty()) { - return chapters; - } - } - request = new Request.Builder().url(url).build(); + Request request = new Request.Builder().url(url).cacheControl(cacheControl).build(); response = AntennapodHttpClient.getHttpClient().newCall(request).execute(); if (response.isSuccessful() && response.body() != null) { return PodcastIndexChapterParser.parse(response.body().string()); } } catch (IOException e) { e.printStackTrace(); + } finally { + if (response != null) { + response.close(); + } } return null; }