Add button to refresh episode chapters (#6177)

This commit is contained in:
LukasBrilla5 2022-11-18 20:08:48 +01:00 committed by GitHub
parent 63ba5c458f
commit d585e37e11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 23 deletions

View File

@ -263,7 +263,7 @@ public class AudioPlayerFragment extends Fragment implements
Playable media = controller.getMedia(); Playable media = controller.getMedia();
if (media != null) { if (media != null) {
if (includingChapters) { if (includingChapters) {
ChapterUtils.loadChapters(media, getContext()); ChapterUtils.loadChapters(media, getContext(), false);
} }
emitter.onSuccess(media); emitter.onSuccess(media);
} else { } else {

View File

@ -1,13 +1,16 @@
package de.danoeh.antennapod.fragment; package de.danoeh.antennapod.fragment;
import android.app.Dialog; import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDialogFragment; import androidx.appcompat.app.AppCompatDialogFragment;
import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.recyclerview.widget.DividerItemDecoration; 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.core.util.playback.PlaybackController;
import de.danoeh.antennapod.event.playback.PlaybackPositionEvent; import de.danoeh.antennapod.event.playback.PlaybackPositionEvent;
import de.danoeh.antennapod.model.feed.Chapter; 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.model.playback.Playable;
import de.danoeh.antennapod.playback.base.PlayerStatus; import de.danoeh.antennapod.playback.base.PlayerStatus;
import io.reactivex.Maybe; import io.reactivex.Maybe;
@ -43,11 +47,21 @@ public class ChaptersFragment extends AppCompatDialogFragment {
@NonNull @NonNull
@Override @Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
return new MaterialAlertDialogBuilder(requireContext())
AlertDialog dialog = new MaterialAlertDialogBuilder(requireContext())
.setTitle(getString(R.string.chapters_label)) .setTitle(getString(R.string.chapters_label))
.setView(onCreateView(getLayoutInflater())) .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(); .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()) { controller = new PlaybackController(getActivity()) {
@Override @Override
public void loadMediaInfo() { public void loadMediaInfo() {
ChaptersFragment.this.loadMediaInfo(); ChaptersFragment.this.loadMediaInfo(false);
} }
}; };
controller.init(); controller.init();
EventBus.getDefault().register(this); EventBus.getDefault().register(this);
loadMediaInfo(); loadMediaInfo(false);
} }
@Override @Override
@ -119,14 +133,14 @@ public class ChaptersFragment extends AppCompatDialogFragment {
return ChapterUtils.getCurrentChapterIndex(media, controller.getPosition()); return ChapterUtils.getCurrentChapterIndex(media, controller.getPosition());
} }
private void loadMediaInfo() { private void loadMediaInfo(boolean forceRefresh) {
if (disposable != null) { if (disposable != null) {
disposable.dispose(); disposable.dispose();
} }
disposable = Maybe.create(emitter -> { disposable = Maybe.create(emitter -> {
Playable media = controller.getMedia(); Playable media = controller.getMedia();
if (media != null) { if (media != null) {
ChapterUtils.loadChapters(media, getContext()); ChapterUtils.loadChapters(media, getContext(), forceRefresh);
emitter.onSuccess(media); emitter.onSuccess(media);
} else { } else {
emitter.onComplete(); emitter.onComplete();
@ -150,6 +164,11 @@ public class ChaptersFragment extends AppCompatDialogFragment {
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
} }
adapter.setMedia(media); 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); int positionOfCurrentChapter = getCurrentChapter(media);
updateChapterSelection(positionOfCurrentChapter, true); updateChapterSelection(positionOfCurrentChapter, true);
} }

View File

@ -95,7 +95,7 @@ public class CoverFragment extends Fragment {
Playable media = controller.getMedia(); Playable media = controller.getMedia();
if (media != null) { if (media != null) {
if (includingChapters) { if (includingChapters) {
ChapterUtils.loadChapters(media, getContext()); ChapterUtils.loadChapters(media, getContext(), false);
} }
emitter.onSuccess(media); emitter.onSuccess(media);
} else { } else {

View File

@ -59,7 +59,7 @@ public class MediaDownloadedHandler implements Runnable {
} }
if (media.getItem() != null && media.getItem().getPodcastIndexChapterUrl() != null) { if (media.getItem() != null && media.getItem().getPodcastIndexChapterUrl() != null) {
ChapterUtils.loadChaptersFromUrl(media.getItem().getPodcastIndexChapterUrl()); ChapterUtils.loadChaptersFromUrl(media.getItem().getPodcastIndexChapterUrl(), false);
} }
// Get duration // Get duration
MediaMetadataRetriever mmr = new MediaMetadataRetriever(); MediaMetadataRetriever mmr = new MediaMetadataRetriever();

View File

@ -227,7 +227,7 @@ public class PlaybackServiceTaskManager {
if (media.getChapters() == null) { if (media.getChapters() == null) {
chapterLoaderFuture = Completable.create(emitter -> { chapterLoaderFuture = Completable.create(emitter -> {
ChapterUtils.loadChapters(media, context); ChapterUtils.loadChapters(media, context, false);
emitter.onComplete(); emitter.onComplete();
}) })
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())

View File

@ -54,8 +54,8 @@ public class ChapterUtils {
return chapters.size() - 1; return chapters.size() - 1;
} }
public static void loadChapters(Playable playable, Context context) { public static void loadChapters(Playable playable, Context context, boolean forceRefresh) {
if (playable.getChapters() != null) { if (playable.getChapters() != null && !forceRefresh) {
// Already loaded // Already loaded
return; return;
} }
@ -73,7 +73,7 @@ public class ChapterUtils {
if (!TextUtils.isEmpty(feedMedia.getItem().getPodcastIndexChapterUrl())) { if (!TextUtils.isEmpty(feedMedia.getItem().getPodcastIndexChapterUrl())) {
chaptersFromPodcastIndex = ChapterUtils.loadChaptersFromUrl( chaptersFromPodcastIndex = ChapterUtils.loadChaptersFromUrl(
feedMedia.getItem().getPodcastIndexChapterUrl()); feedMedia.getItem().getPodcastIndexChapterUrl(), forceRefresh);
} }
} }
@ -135,23 +135,32 @@ public class ChapterUtils {
} }
} }
public static List<Chapter> loadChaptersFromUrl(String url) { public static List<Chapter> loadChaptersFromUrl(String url, boolean forceRefresh) {
if (forceRefresh) {
return loadChaptersFromUrl(url, CacheControl.FORCE_NETWORK);
}
List<Chapter> 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<Chapter> loadChaptersFromUrl(String url, CacheControl cacheControl) {
Response response = null;
try { try {
Request request = new Request.Builder().url(url).cacheControl(CacheControl.FORCE_CACHE).build(); Request request = new Request.Builder().url(url).cacheControl(cacheControl).build();
Response response = AntennapodHttpClient.getHttpClient().newCall(request).execute();
if (response.isSuccessful() && response.body() != null) {
List<Chapter> chapters = PodcastIndexChapterParser.parse(response.body().string());
if (chapters != null && !chapters.isEmpty()) {
return chapters;
}
}
request = new Request.Builder().url(url).build();
response = AntennapodHttpClient.getHttpClient().newCall(request).execute(); response = AntennapodHttpClient.getHttpClient().newCall(request).execute();
if (response.isSuccessful() && response.body() != null) { if (response.isSuccessful() && response.body() != null) {
return PodcastIndexChapterParser.parse(response.body().string()); return PodcastIndexChapterParser.parse(response.body().string());
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} finally {
if (response != null) {
response.close();
}
} }
return null; return null;
} }