Add report/solve-recaptcha button in error panel
It will be shown even when nothing could be loaded not due to a network error, and the user can choose to ignore or report it. Also improve error reporting arguments Also completely refactor error activity Also improve some code here and there
This commit is contained in:
parent
bb398189d6
commit
0ea6b4928c
59 changed files with 886 additions and 1262 deletions
|
|
@ -21,13 +21,11 @@ import com.nostra13.universalimageloader.core.ImageLoader;
|
|||
import org.schabi.newpipe.DownloaderImpl;
|
||||
import org.schabi.newpipe.NewPipeDatabase;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.error.ErrorActivity;
|
||||
import org.schabi.newpipe.error.ReCaptchaActivity;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.localization.ContentCountry;
|
||||
import org.schabi.newpipe.extractor.localization.Localization;
|
||||
import org.schabi.newpipe.error.ErrorActivity;
|
||||
import org.schabi.newpipe.error.ErrorInfo;
|
||||
import org.schabi.newpipe.error.UserAction;
|
||||
import org.schabi.newpipe.util.FilePickerActivityHelper;
|
||||
import org.schabi.newpipe.util.ZipHelper;
|
||||
|
||||
|
|
@ -198,7 +196,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||
|
||||
Toast.makeText(getContext(), R.string.export_complete_toast, Toast.LENGTH_SHORT).show();
|
||||
} catch (final Exception e) {
|
||||
onError(e);
|
||||
ErrorActivity.reportUiError(getActivity(), null, "Exporting database", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -243,20 +241,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||
System.exit(0);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
onError(e);
|
||||
ErrorActivity.reportUiError(getActivity(), null, "Importing database", e);
|
||||
}
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Error
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
protected void onError(final Throwable e) {
|
||||
final Activity activity = getActivity();
|
||||
ErrorActivity.reportError(activity, e,
|
||||
activity.getClass(),
|
||||
null,
|
||||
ErrorInfo.make(UserAction.UI_ERROR,
|
||||
"none", "", R.string.app_ui_crash));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package org.schabi.newpipe.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.preference.Preference;
|
||||
|
|
@ -46,120 +48,103 @@ public class HistorySettingsFragment extends BasePreferenceFragment {
|
|||
public boolean onPreferenceTreeClick(final Preference preference) {
|
||||
if (preference.getKey().equals(cacheWipeKey)) {
|
||||
InfoCache.getInstance().clearCache();
|
||||
Toast.makeText(preference.getContext(), R.string.metadata_cache_wipe_complete_notice,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(requireContext(),
|
||||
R.string.metadata_cache_wipe_complete_notice, Toast.LENGTH_SHORT).show();
|
||||
} else if (preference.getKey().equals(viewsHistoryClearKey)) {
|
||||
openDeleteWatchHistoryDialog(requireContext(), recordManager, disposables);
|
||||
} else if (preference.getKey().equals(playbackStatesClearKey)) {
|
||||
openDeletePlaybackStatesDialog(requireContext(), recordManager, disposables);
|
||||
} else if (preference.getKey().equals(searchHistoryClearKey)) {
|
||||
openDeleteSearchHistoryDialog(requireContext(), recordManager, disposables);
|
||||
} else {
|
||||
return super.onPreferenceTreeClick(preference);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (preference.getKey().equals(viewsHistoryClearKey)) {
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.delete_view_history_alert)
|
||||
.setNegativeButton(R.string.cancel, ((dialog, which) -> dialog.dismiss()))
|
||||
.setPositiveButton(R.string.delete, ((dialog, which) -> {
|
||||
final Disposable onDeletePlaybackStates
|
||||
= recordManager.deleteCompleteStreamStateHistory()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
howManyDeleted -> Toast.makeText(getActivity(),
|
||||
R.string.watch_history_states_deleted,
|
||||
Toast.LENGTH_SHORT).show(),
|
||||
throwable -> ErrorActivity.reportError(getContext(),
|
||||
throwable,
|
||||
SettingsActivity.class, null,
|
||||
ErrorInfo.make(
|
||||
UserAction.DELETE_FROM_HISTORY,
|
||||
"none",
|
||||
"Delete playback states",
|
||||
R.string.general_error)));
|
||||
private static Disposable getDeletePlaybackStatesDisposable(
|
||||
@NonNull final Context context, final HistoryRecordManager recordManager) {
|
||||
return recordManager.deleteCompleteStreamStateHistory()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
howManyDeleted -> Toast.makeText(context,
|
||||
R.string.watch_history_states_deleted, Toast.LENGTH_SHORT).show(),
|
||||
throwable -> ErrorActivity.reportError(context, SettingsActivity.class,
|
||||
null, new ErrorInfo(throwable, UserAction.DELETE_FROM_HISTORY,
|
||||
"Delete playback states")));
|
||||
}
|
||||
|
||||
final Disposable onDelete = recordManager.deleteWholeStreamHistory()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
howManyDeleted -> Toast.makeText(getActivity(),
|
||||
R.string.watch_history_deleted,
|
||||
Toast.LENGTH_SHORT).show(),
|
||||
throwable -> ErrorActivity.reportError(getContext(),
|
||||
throwable,
|
||||
SettingsActivity.class, null,
|
||||
ErrorInfo.make(
|
||||
UserAction.DELETE_FROM_HISTORY,
|
||||
"none",
|
||||
"Delete view history",
|
||||
R.string.general_error)));
|
||||
private static Disposable getWholeStreamHistoryDisposable(
|
||||
@NonNull final Context context, final HistoryRecordManager recordManager) {
|
||||
return recordManager.deleteWholeStreamHistory()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
howManyDeleted -> Toast.makeText(context,
|
||||
R.string.watch_history_deleted, Toast.LENGTH_SHORT).show(),
|
||||
throwable -> ErrorActivity.reportError(context, SettingsActivity.class,
|
||||
null, new ErrorInfo(throwable, UserAction.DELETE_FROM_HISTORY,
|
||||
"Delete from history")));
|
||||
}
|
||||
|
||||
final Disposable onClearOrphans = recordManager.removeOrphanedRecords()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
howManyDeleted -> {
|
||||
},
|
||||
throwable -> ErrorActivity.reportError(getContext(),
|
||||
throwable,
|
||||
SettingsActivity.class, null,
|
||||
ErrorInfo.make(
|
||||
UserAction.DELETE_FROM_HISTORY,
|
||||
"none",
|
||||
"Delete search history",
|
||||
R.string.general_error)));
|
||||
disposables.add(onDeletePlaybackStates);
|
||||
disposables.add(onClearOrphans);
|
||||
disposables.add(onDelete);
|
||||
}))
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
private static Disposable getRemoveOrphanedRecordsDisposable(
|
||||
@NonNull final Context context, final HistoryRecordManager recordManager) {
|
||||
return recordManager.removeOrphanedRecords()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
howManyDeleted -> {},
|
||||
throwable -> ErrorActivity.reportError(context, SettingsActivity.class,
|
||||
null, new ErrorInfo(throwable, UserAction.DELETE_FROM_HISTORY,
|
||||
"Clear orphaned records")));
|
||||
}
|
||||
|
||||
if (preference.getKey().equals(playbackStatesClearKey)) {
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.delete_playback_states_alert)
|
||||
.setNegativeButton(R.string.cancel, ((dialog, which) -> dialog.dismiss()))
|
||||
.setPositiveButton(R.string.delete, ((dialog, which) -> {
|
||||
private static Disposable getDeleteSearchHistoryDisposable(
|
||||
@NonNull final Context context, final HistoryRecordManager recordManager) {
|
||||
return recordManager.deleteCompleteSearchHistory()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
howManyDeleted -> Toast.makeText(context,
|
||||
R.string.search_history_deleted, Toast.LENGTH_SHORT).show(),
|
||||
throwable -> ErrorActivity.reportError(context, SettingsActivity.class,
|
||||
null, new ErrorInfo(throwable, UserAction.DELETE_FROM_HISTORY,
|
||||
"Delete search history")));
|
||||
}
|
||||
|
||||
final Disposable onDeletePlaybackStates
|
||||
= recordManager.deleteCompleteStreamStateHistory()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
howManyDeleted -> Toast.makeText(getActivity(),
|
||||
R.string.watch_history_states_deleted,
|
||||
Toast.LENGTH_SHORT).show(),
|
||||
throwable -> ErrorActivity.reportError(getContext(),
|
||||
throwable,
|
||||
SettingsActivity.class, null,
|
||||
ErrorInfo.make(
|
||||
UserAction.DELETE_FROM_HISTORY,
|
||||
"none",
|
||||
"Delete playback states",
|
||||
R.string.general_error)));
|
||||
public static void openDeleteWatchHistoryDialog(@NonNull final Context context,
|
||||
final HistoryRecordManager recordManager,
|
||||
final CompositeDisposable disposables) {
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.delete_view_history_alert)
|
||||
.setNegativeButton(R.string.cancel, ((dialog, which) -> dialog.dismiss()))
|
||||
.setPositiveButton(R.string.delete, ((dialog, which) -> {
|
||||
disposables.add(getDeletePlaybackStatesDisposable(context, recordManager));
|
||||
disposables.add(getWholeStreamHistoryDisposable(context, recordManager));
|
||||
disposables.add(getRemoveOrphanedRecordsDisposable(context, recordManager));
|
||||
}))
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
|
||||
disposables.add(onDeletePlaybackStates);
|
||||
}))
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
public static void openDeletePlaybackStatesDialog(@NonNull final Context context,
|
||||
final HistoryRecordManager recordManager,
|
||||
final CompositeDisposable disposables) {
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.delete_playback_states_alert)
|
||||
.setNegativeButton(R.string.cancel, ((dialog, which) -> dialog.dismiss()))
|
||||
.setPositiveButton(R.string.delete, ((dialog, which) ->
|
||||
disposables.add(getDeletePlaybackStatesDisposable(context, recordManager))))
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
|
||||
if (preference.getKey().equals(searchHistoryClearKey)) {
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.delete_search_history_alert)
|
||||
.setNegativeButton(R.string.cancel, ((dialog, which) -> dialog.dismiss()))
|
||||
.setPositiveButton(R.string.delete, ((dialog, which) -> {
|
||||
final Disposable onDelete = recordManager.deleteCompleteSearchHistory()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
howManyDeleted -> Toast.makeText(getActivity(),
|
||||
R.string.search_history_deleted,
|
||||
Toast.LENGTH_SHORT).show(),
|
||||
throwable -> ErrorActivity.reportError(getContext(),
|
||||
throwable,
|
||||
SettingsActivity.class, null,
|
||||
ErrorInfo.make(
|
||||
UserAction.DELETE_FROM_HISTORY,
|
||||
"none",
|
||||
"Delete search history",
|
||||
R.string.general_error)));
|
||||
disposables.add(onDelete);
|
||||
}))
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
|
||||
return super.onPreferenceTreeClick(preference);
|
||||
public static void openDeleteSearchHistoryDialog(@NonNull final Context context,
|
||||
final HistoryRecordManager recordManager,
|
||||
final CompositeDisposable disposables) {
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.delete_search_history_alert)
|
||||
.setNegativeButton(R.string.cancel, ((dialog, which) -> dialog.dismiss()))
|
||||
.setPositiveButton(R.string.delete, ((dialog, which) ->
|
||||
disposables.add(getDeleteSearchHistoryDisposable(context, recordManager))))
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package org.schabi.newpipe.settings;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
|
|
@ -20,10 +19,8 @@ import com.nostra13.universalimageloader.core.ImageLoader;
|
|||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
|
||||
import org.schabi.newpipe.local.subscription.SubscriptionManager;
|
||||
import org.schabi.newpipe.error.ErrorActivity;
|
||||
import org.schabi.newpipe.error.ErrorInfo;
|
||||
import org.schabi.newpipe.error.UserAction;
|
||||
import org.schabi.newpipe.local.subscription.SubscriptionManager;
|
||||
import org.schabi.newpipe.util.ThemeHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -108,7 +105,7 @@ public class SelectChannelFragment extends DialogFragment {
|
|||
emptyView.setVisibility(View.GONE);
|
||||
|
||||
|
||||
final SubscriptionManager subscriptionManager = new SubscriptionManager(getContext());
|
||||
final SubscriptionManager subscriptionManager = new SubscriptionManager(requireContext());
|
||||
subscriptionManager.subscriptions().toObservable()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
|
@ -122,7 +119,7 @@ public class SelectChannelFragment extends DialogFragment {
|
|||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Override
|
||||
public void onCancel(final DialogInterface dialogInterface) {
|
||||
public void onCancel(@NonNull final DialogInterface dialogInterface) {
|
||||
super.onCancel(dialogInterface);
|
||||
if (onCancelListener != null) {
|
||||
onCancelListener.onCancel();
|
||||
|
|
@ -156,16 +153,16 @@ public class SelectChannelFragment extends DialogFragment {
|
|||
private Observer<List<SubscriptionEntity>> getSubscriptionObserver() {
|
||||
return new Observer<List<SubscriptionEntity>>() {
|
||||
@Override
|
||||
public void onSubscribe(final Disposable d) { }
|
||||
public void onSubscribe(@NonNull final Disposable disposable) { }
|
||||
|
||||
@Override
|
||||
public void onNext(final List<SubscriptionEntity> newSubscriptions) {
|
||||
public void onNext(@NonNull final List<SubscriptionEntity> newSubscriptions) {
|
||||
displayChannels(newSubscriptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(final Throwable exception) {
|
||||
SelectChannelFragment.this.onError(exception);
|
||||
public void onError(@NonNull final Throwable exception) {
|
||||
ErrorActivity.reportUiError(requireContext(), null, "Loading subscription", exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -173,16 +170,6 @@ public class SelectChannelFragment extends DialogFragment {
|
|||
};
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Error
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
protected void onError(final Throwable e) {
|
||||
final Activity activity = getActivity();
|
||||
ErrorActivity.reportError(activity, e, activity.getClass(), null, ErrorInfo
|
||||
.make(UserAction.UI_ERROR, "none", "", R.string.app_ui_crash));
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Interfaces
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
|
@ -197,6 +184,7 @@ public class SelectChannelFragment extends DialogFragment {
|
|||
|
||||
private class SelectChannelAdapter
|
||||
extends RecyclerView.Adapter<SelectChannelAdapter.SelectChannelItemHolder> {
|
||||
@NonNull
|
||||
@Override
|
||||
public SelectChannelItemHolder onCreateViewHolder(final ViewGroup parent,
|
||||
final int viewType) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package org.schabi.newpipe.settings;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
|
|
@ -19,8 +18,6 @@ import org.schabi.newpipe.R;
|
|||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.error.ErrorActivity;
|
||||
import org.schabi.newpipe.error.ErrorInfo;
|
||||
import org.schabi.newpipe.error.UserAction;
|
||||
import org.schabi.newpipe.util.KioskTranslator;
|
||||
import org.schabi.newpipe.util.ServiceHelper;
|
||||
import org.schabi.newpipe.util.ThemeHelper;
|
||||
|
|
@ -83,7 +80,7 @@ public class SelectKioskFragment extends DialogFragment {
|
|||
try {
|
||||
selectKioskAdapter = new SelectKioskAdapter();
|
||||
} catch (final Exception e) {
|
||||
onError(e);
|
||||
ErrorActivity.reportUiError(getActivity(), null, "Selecting kiosk", e);
|
||||
}
|
||||
recyclerView.setAdapter(selectKioskAdapter);
|
||||
|
||||
|
|
@ -109,16 +106,6 @@ public class SelectKioskFragment extends DialogFragment {
|
|||
dismiss();
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Error
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
protected void onError(final Throwable e) {
|
||||
final Activity activity = getActivity();
|
||||
ErrorActivity.reportError(activity, e, activity.getClass(), null, ErrorInfo
|
||||
.make(UserAction.UI_ERROR, "none", "", R.string.app_ui_crash));
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// Interfaces
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
|
|
|||
|
|
@ -115,8 +115,8 @@ public class SelectPlaylistFragment extends DialogFragment {
|
|||
|
||||
protected void onError(final Throwable e) {
|
||||
final Activity activity = requireActivity();
|
||||
ErrorActivity.reportError(activity, e, activity.getClass(), null, ErrorInfo
|
||||
.make(UserAction.UI_ERROR, "none", "load_playlists", R.string.app_ui_crash));
|
||||
ErrorActivity.reportError(activity, activity.getClass(), null, new ErrorInfo(e,
|
||||
UserAction.UI_ERROR, "Loading playlists"));
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -95,15 +95,13 @@ public final class SettingMigrations {
|
|||
} catch (final Exception e) {
|
||||
// save the version with the last successful migration and report the error
|
||||
sp.edit().putInt(lastPrefVersionKey, currentVersion).apply();
|
||||
final ErrorInfo errorInfo = ErrorInfo.make(
|
||||
ErrorActivity.reportError(context, SettingMigrations.class, null, new ErrorInfo(
|
||||
e,
|
||||
UserAction.PREFERENCES_MIGRATION,
|
||||
"none",
|
||||
"Migrating preferences from version " + lastPrefVersion + " to "
|
||||
+ VERSION + ". "
|
||||
+ "Error at " + currentVersion + " => " + ++currentVersion,
|
||||
0
|
||||
);
|
||||
ErrorActivity.reportError(context, e, SettingMigrations.class, null, errorInfo);
|
||||
+ "Error at " + currentVersion + " => " + ++currentVersion
|
||||
));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,10 +183,9 @@ public class ChooseTabsFragment extends Fragment {
|
|||
final Tab.Type type = typeFrom(tabId);
|
||||
|
||||
if (type == null) {
|
||||
ErrorActivity.reportError(requireContext(),
|
||||
new IllegalStateException("Tab id not found: " + tabId), null, null,
|
||||
ErrorInfo.make(UserAction.SOMETHING_ELSE, "none",
|
||||
"Choosing tabs on settings", 0));
|
||||
ErrorActivity.reportError(requireContext(), null, null,
|
||||
new ErrorInfo(new IllegalStateException("Tab id not found: " + tabId),
|
||||
UserAction.SOMETHING_ELSE, "Choosing tabs on settings"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -483,9 +483,8 @@ public abstract class Tab {
|
|||
final StreamingService service = NewPipe.getService(kioskServiceId);
|
||||
kioskId = service.getKioskList().getDefaultKioskId();
|
||||
} catch (final ExtractionException e) {
|
||||
ErrorActivity.reportError(context, e, null, null,
|
||||
ErrorInfo.make(UserAction.REQUESTED_KIOSK, "none",
|
||||
"Loading default kiosk from selected service", 0));
|
||||
ErrorActivity.reportError(context, null, null, new ErrorInfo(e,
|
||||
UserAction.REQUESTED_KIOSK, "Loading default kiosk for selected service"));
|
||||
}
|
||||
return kioskId;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue