mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-01-11 01:40:59 +00:00
Merge pull request #7056 from TeamNewPipe/fix/playOnPopup
Fix handling exception in `playOnPopup` and toggle description tab
This commit is contained in:
commit
7eb5aa1bc5
@ -16,7 +16,7 @@ import leakcanary.AppWatcher;
|
|||||||
|
|
||||||
public abstract class BaseFragment extends Fragment {
|
public abstract class BaseFragment extends Fragment {
|
||||||
protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
|
protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
|
||||||
protected final boolean DEBUG = MainActivity.DEBUG;
|
protected static final boolean DEBUG = MainActivity.DEBUG;
|
||||||
protected AppCompatActivity activity;
|
protected AppCompatActivity activity;
|
||||||
//These values are used for controlling fragments when they are part of the frontpage
|
//These values are used for controlling fragments when they are part of the frontpage
|
||||||
@State
|
@State
|
||||||
|
@ -121,27 +121,14 @@ class ErrorPanelHelper(
|
|||||||
ErrorActivity.reportError(context, errorInfo)
|
ErrorActivity.reportError(context, errorInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
errorTextView.setText(
|
errorTextView.setText(getExceptionDescription(errorInfo.throwable))
|
||||||
when (errorInfo.throwable) {
|
|
||||||
is AgeRestrictedContentException -> R.string.restricted_video_no_stream
|
if (errorInfo.throwable !is ContentNotAvailableException &&
|
||||||
is GeographicRestrictionException -> R.string.georestricted_content
|
errorInfo.throwable !is ContentNotSupportedException
|
||||||
is PaidContentException -> R.string.paid_content
|
) {
|
||||||
is PrivateContentException -> R.string.private_content
|
// show retry button only for content which is not unavailable or unsupported
|
||||||
is SoundCloudGoPlusContentException -> R.string.soundcloud_go_plus_content
|
errorRetryButton.isVisible = true
|
||||||
is YoutubeMusicPremiumContentException -> R.string.youtube_music_premium_content
|
}
|
||||||
is ContentNotAvailableException -> R.string.content_not_available
|
|
||||||
is ContentNotSupportedException -> R.string.content_not_supported
|
|
||||||
else -> {
|
|
||||||
// show retry button only for content which is not unavailable or unsupported
|
|
||||||
errorRetryButton.isVisible = true
|
|
||||||
if (errorInfo.throwable != null && errorInfo.throwable!!.isNetworkRelated) {
|
|
||||||
R.string.network_error
|
|
||||||
} else {
|
|
||||||
R.string.error_snackbar_message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setRootVisible()
|
setRootVisible()
|
||||||
@ -189,5 +176,27 @@ class ErrorPanelHelper(
|
|||||||
companion object {
|
companion object {
|
||||||
val TAG: String = ErrorPanelHelper::class.simpleName!!
|
val TAG: String = ErrorPanelHelper::class.simpleName!!
|
||||||
val DEBUG: Boolean = MainActivity.DEBUG
|
val DEBUG: Boolean = MainActivity.DEBUG
|
||||||
|
|
||||||
|
@StringRes
|
||||||
|
public fun getExceptionDescription(throwable: Throwable?): Int {
|
||||||
|
return when (throwable) {
|
||||||
|
is AgeRestrictedContentException -> R.string.restricted_video_no_stream
|
||||||
|
is GeographicRestrictionException -> R.string.georestricted_content
|
||||||
|
is PaidContentException -> R.string.paid_content
|
||||||
|
is PrivateContentException -> R.string.private_content
|
||||||
|
is SoundCloudGoPlusContentException -> R.string.soundcloud_go_plus_content
|
||||||
|
is YoutubeMusicPremiumContentException -> R.string.youtube_music_premium_content
|
||||||
|
is ContentNotAvailableException -> R.string.content_not_available
|
||||||
|
is ContentNotSupportedException -> R.string.content_not_supported
|
||||||
|
else -> {
|
||||||
|
// show retry button only for content which is not unavailable or unsupported
|
||||||
|
if (throwable != null && throwable.isNetworkRelated) {
|
||||||
|
R.string.network_error
|
||||||
|
} else {
|
||||||
|
R.string.error_snackbar_message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.schabi.newpipe.error;
|
package org.schabi.newpipe.error;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -66,6 +67,7 @@ public class ReCaptchaActivity extends AppCompatActivity {
|
|||||||
private ActivityRecaptchaBinding recaptchaBinding;
|
private ActivityRecaptchaBinding recaptchaBinding;
|
||||||
private String foundCookies = "";
|
private String foundCookies = "";
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(final Bundle savedInstanceState) {
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
ThemeHelper.setTheme(this);
|
ThemeHelper.setTheme(this);
|
||||||
|
@ -423,7 +423,7 @@ public final class VideoDetailFragment
|
|||||||
showRelatedItems = sharedPreferences.getBoolean(key, true);
|
showRelatedItems = sharedPreferences.getBoolean(key, true);
|
||||||
tabSettingsChanged = true;
|
tabSettingsChanged = true;
|
||||||
} else if (key.equals(getString(R.string.show_description_key))) {
|
} else if (key.equals(getString(R.string.show_description_key))) {
|
||||||
showComments = sharedPreferences.getBoolean(key, true);
|
showDescription = sharedPreferences.getBoolean(key, true);
|
||||||
tabSettingsChanged = true;
|
tabSettingsChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,6 +215,7 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull final View rootView, final Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull final View rootView, final Bundle savedInstanceState) {
|
||||||
|
searchBinding = FragmentSearchBinding.bind(rootView);
|
||||||
super.onViewCreated(rootView, savedInstanceState);
|
super.onViewCreated(rootView, savedInstanceState);
|
||||||
showSearchOnStart();
|
showSearchOnStart();
|
||||||
initSearchListeners();
|
initSearchListeners();
|
||||||
@ -341,7 +342,6 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
|
|||||||
@Override
|
@Override
|
||||||
protected void initViews(final View rootView, final Bundle savedInstanceState) {
|
protected void initViews(final View rootView, final Bundle savedInstanceState) {
|
||||||
super.initViews(rootView, savedInstanceState);
|
super.initViews(rootView, savedInstanceState);
|
||||||
searchBinding = FragmentSearchBinding.bind(rootView);
|
|
||||||
|
|
||||||
searchBinding.suggestionsList.setAdapter(suggestionListAdapter);
|
searchBinding.suggestionsList.setAdapter(suggestionListAdapter);
|
||||||
new ItemTouchHelper(new ItemTouchHelper.Callback() {
|
new ItemTouchHelper(new ItemTouchHelper.Callback() {
|
||||||
@ -807,18 +807,21 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
|
|||||||
})
|
})
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(listNotification -> {
|
.subscribe(
|
||||||
if (listNotification.isOnNext()) {
|
listNotification -> {
|
||||||
if (listNotification.getValue() != null) {
|
if (listNotification.isOnNext()) {
|
||||||
handleSuggestions(listNotification.getValue());
|
if (listNotification.getValue() != null) {
|
||||||
}
|
handleSuggestions(listNotification.getValue());
|
||||||
} else if (listNotification.isOnError()
|
}
|
||||||
&& listNotification.getError() != null
|
} else if (listNotification.isOnError()
|
||||||
&& !ExceptionUtils.isInterruptedCaused(listNotification.getError())) {
|
&& listNotification.getError() != null
|
||||||
showSnackBarError(new ErrorInfo(listNotification.getError(),
|
&& !ExceptionUtils.isInterruptedCaused(
|
||||||
UserAction.GET_SUGGESTIONS, searchString, serviceId));
|
listNotification.getError())) {
|
||||||
}
|
showSnackBarError(new ErrorInfo(listNotification.getError(),
|
||||||
});
|
UserAction.GET_SUGGESTIONS, searchString, serviceId));
|
||||||
|
}
|
||||||
|
}, throwable -> showSnackBarError(new ErrorInfo(
|
||||||
|
throwable, UserAction.GET_SUGGESTIONS, searchString, serviceId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -614,7 +614,7 @@ public final class Player implements
|
|||||||
playQueue.append(newQueue.getStreams());
|
playQueue.append(newQueue.getStreams());
|
||||||
|
|
||||||
if ((intent.getBooleanExtra(SELECT_ON_APPEND, false)
|
if ((intent.getBooleanExtra(SELECT_ON_APPEND, false)
|
||||||
|| currentState == STATE_COMPLETED) && newQueue.getStreams().size() > 0) {
|
|| currentState == STATE_COMPLETED) && !newQueue.getStreams().isEmpty()) {
|
||||||
playQueue.setIndex(sizeBeforeAppend);
|
playQueue.setIndex(sizeBeforeAppend);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2326,7 +2326,7 @@ public final class Player implements
|
|||||||
Log.d(TAG, "ExoPlayer - onRepeatModeChanged() called with: "
|
Log.d(TAG, "ExoPlayer - onRepeatModeChanged() called with: "
|
||||||
+ "repeatMode = [" + repeatMode + "]");
|
+ "repeatMode = [" + repeatMode + "]");
|
||||||
}
|
}
|
||||||
setRepeatModeButton(((AppCompatImageButton) binding.repeatButton), repeatMode);
|
setRepeatModeButton(binding.repeatButton, repeatMode);
|
||||||
onShuffleOrRepeatModeChanged();
|
onShuffleOrRepeatModeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3189,7 +3189,7 @@ public final class Player implements
|
|||||||
private StreamSegmentAdapter.StreamSegmentListener getStreamSegmentListener() {
|
private StreamSegmentAdapter.StreamSegmentListener getStreamSegmentListener() {
|
||||||
return (item, seconds) -> {
|
return (item, seconds) -> {
|
||||||
segmentAdapter.selectSegment(item);
|
segmentAdapter.selectSegment(item);
|
||||||
seekTo(seconds * 1000);
|
seekTo(seconds * 1000L);
|
||||||
triggerProgressUpdate();
|
triggerProgressUpdate();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -3199,7 +3199,7 @@ public final class Player implements
|
|||||||
final List<StreamSegment> segments = currentMetadata.getMetadata().getStreamSegments();
|
final List<StreamSegment> segments = currentMetadata.getMetadata().getStreamSegments();
|
||||||
|
|
||||||
for (int i = 0; i < segments.size(); i++) {
|
for (int i = 0; i < segments.size(); i++) {
|
||||||
if (segments.get(i).getStartTimeSeconds() * 1000 > playbackPosition) {
|
if (segments.get(i).getStartTimeSeconds() * 1000L > playbackPosition) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nearestPosition++;
|
nearestPosition++;
|
||||||
|
@ -360,7 +360,7 @@ public final class NavigationHelper {
|
|||||||
autoPlay = false;
|
autoPlay = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final RunnableWithVideoDetailFragment onVideoDetailFragmentReady = (detailFragment) -> {
|
final RunnableWithVideoDetailFragment onVideoDetailFragmentReady = detailFragment -> {
|
||||||
expandMainPlayer(detailFragment.requireActivity());
|
expandMainPlayer(detailFragment.requireActivity());
|
||||||
detailFragment.setAutoPlay(autoPlay);
|
detailFragment.setAutoPlay(autoPlay);
|
||||||
if (switchingPlayers) {
|
if (switchingPlayers) {
|
||||||
|
@ -119,7 +119,7 @@ public final class PermissionHelper {
|
|||||||
|
|
||||||
public static boolean isPopupEnabled(final Context context) {
|
public static boolean isPopupEnabled(final Context context) {
|
||||||
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
||||||
|| PermissionHelper.checkSystemAlertWindowPermission(context);
|
|| checkSystemAlertWindowPermission(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showPopupEnablementToast(final Context context) {
|
public static void showPopupEnablementToast(final Context context) {
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
package org.schabi.newpipe.util.external_communication;
|
package org.schabi.newpipe.util.external_communication;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.MainActivity;
|
||||||
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.error.ErrorPanelHelper;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
@ -24,6 +29,9 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
|||||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
|
||||||
public final class InternalUrlsHandler {
|
public final class InternalUrlsHandler {
|
||||||
|
private static final String TAG = InternalUrlsHandler.class.getSimpleName();
|
||||||
|
private static final boolean DEBUG = MainActivity.DEBUG;
|
||||||
|
|
||||||
private static final Pattern AMPERSAND_TIMESTAMP_PATTERN = Pattern.compile("(.*)&t=(\\d+)");
|
private static final Pattern AMPERSAND_TIMESTAMP_PATTERN = Pattern.compile("(.*)&t=(\\d+)");
|
||||||
private static final Pattern HASHTAG_TIMESTAMP_PATTERN =
|
private static final Pattern HASHTAG_TIMESTAMP_PATTERN =
|
||||||
Pattern.compile("(.*)#timestamp=(\\d+)");
|
Pattern.compile("(.*)#timestamp=(\\d+)");
|
||||||
@ -93,7 +101,12 @@ public final class InternalUrlsHandler {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final String matchedUrl = matcher.group(1);
|
final String matchedUrl = matcher.group(1);
|
||||||
final int seconds = Integer.parseInt(matcher.group(2));
|
final int seconds;
|
||||||
|
if (matcher.group(2) == null) {
|
||||||
|
seconds = -1;
|
||||||
|
} else {
|
||||||
|
seconds = Integer.parseInt(matcher.group(2));
|
||||||
|
}
|
||||||
|
|
||||||
final StreamingService service;
|
final StreamingService service;
|
||||||
final StreamingService.LinkType linkType;
|
final StreamingService.LinkType linkType;
|
||||||
@ -146,8 +159,18 @@ public final class InternalUrlsHandler {
|
|||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(info -> {
|
.subscribe(info -> {
|
||||||
final PlayQueue playQueue
|
final PlayQueue playQueue
|
||||||
= new SinglePlayQueue(info, seconds * 1000);
|
= new SinglePlayQueue(info, seconds * 1000L);
|
||||||
NavigationHelper.playOnPopupPlayer(context, playQueue, false);
|
NavigationHelper.playOnPopupPlayer(context, playQueue, false);
|
||||||
|
}, throwable -> {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.e(TAG, "Could not play on popup: " + url, throwable);
|
||||||
|
}
|
||||||
|
new AlertDialog.Builder(context)
|
||||||
|
.setTitle(R.string.player_stream_failure)
|
||||||
|
.setMessage(
|
||||||
|
ErrorPanelHelper.Companion.getExceptionDescription(throwable))
|
||||||
|
.setPositiveButton(R.string.ok, (v, b) -> { })
|
||||||
|
.show();
|
||||||
}));
|
}));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user