Add button to refresh episode chapters (#6177)
This commit is contained in:
parent
63ba5c458f
commit
d585e37e11
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue