diff --git a/app/src/main/java/org/schabi/newpipe/error/ErrorPanelHelper.kt b/app/src/main/java/org/schabi/newpipe/error/ErrorPanelHelper.kt index fcc062102..14ec41148 100644 --- a/app/src/main/java/org/schabi/newpipe/error/ErrorPanelHelper.kt +++ b/app/src/main/java/org/schabi/newpipe/error/ErrorPanelHelper.kt @@ -35,7 +35,7 @@ import java.util.concurrent.TimeUnit class ErrorPanelHelper( private val fragment: Fragment, rootView: View, - onRetry: Runnable + onRetry: Runnable?, ) { private val context: Context = rootView.context!! @@ -56,12 +56,15 @@ class ErrorPanelHelper( errorPanelRoot.findViewById(R.id.error_open_in_browser) private var errorDisposable: Disposable? = null + private var retryShouldBeShown: Boolean = (onRetry != null) init { - errorDisposable = errorRetryButton.clicks() - .debounce(300, TimeUnit.MILLISECONDS) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { onRetry.run() } + if (onRetry != null) { + errorDisposable = errorRetryButton.clicks() + .debounce(300, TimeUnit.MILLISECONDS) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { onRetry.run() } + } } private fun ensureDefaultVisibility() { @@ -101,7 +104,7 @@ class ErrorPanelHelper( errorActionButton.setOnClickListener(null) } - errorRetryButton.isVisible = true + errorRetryButton.isVisible = retryShouldBeShown showAndSetOpenInBrowserButtonAction(errorInfo) } else if (errorInfo.throwable is AccountTerminatedException) { errorTextView.setText(R.string.account_terminated) @@ -130,7 +133,7 @@ class ErrorPanelHelper( errorInfo.throwable !is ContentNotSupportedException ) { // show retry button only for content which is not unavailable or unsupported - errorRetryButton.isVisible = true + errorRetryButton.isVisible = retryShouldBeShown } showAndSetOpenInBrowserButtonAction(errorInfo) } diff --git a/app/src/main/java/org/schabi/newpipe/error/UserAction.java b/app/src/main/java/org/schabi/newpipe/error/UserAction.java index 6ca66e0d2..afb880a29 100644 --- a/app/src/main/java/org/schabi/newpipe/error/UserAction.java +++ b/app/src/main/java/org/schabi/newpipe/error/UserAction.java @@ -32,7 +32,8 @@ public enum UserAction { PREFERENCES_MIGRATION("migration of preferences"), SHARE_TO_NEWPIPE("share to newpipe"), CHECK_FOR_NEW_APP_VERSION("check for new app version"), - OPEN_INFO_ITEM_DIALOG("open info item dialog"); + OPEN_INFO_ITEM_DIALOG("open info item dialog"), + GETTING_MAIN_SCREEN_TAB("getting main screen tab"); private final String message; diff --git a/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java index fe4eef37a..6f879a7e1 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/BlankFragment.java @@ -9,14 +9,52 @@ import androidx.annotation.Nullable; import org.schabi.newpipe.BaseFragment; import org.schabi.newpipe.R; +import org.schabi.newpipe.error.ErrorInfo; +import org.schabi.newpipe.error.ErrorPanelHelper; public class BlankFragment extends BaseFragment { + + @Nullable + final ErrorInfo errorInfo; + @Nullable + ErrorPanelHelper errorPanel = null; + + /** + * Builds a blank fragment that just says the app name and suggests clicking on search. + */ + public BlankFragment() { + this(null); + } + + /** + * @param errorInfo if null acts like {@link BlankFragment}, else shows an error panel. + */ + public BlankFragment(@Nullable final ErrorInfo errorInfo) { + this.errorInfo = errorInfo; + } + @Nullable @Override public View onCreateView(final LayoutInflater inflater, @Nullable final ViewGroup container, final Bundle savedInstanceState) { setTitle("NewPipe"); - return inflater.inflate(R.layout.fragment_blank, container, false); + final View view = inflater.inflate(R.layout.fragment_blank, container, false); + if (errorInfo != null) { + errorPanel = new ErrorPanelHelper(this, view, null); + errorPanel.showError(errorInfo); + view.findViewById(R.id.blank_page_content).setVisibility(View.GONE); + } + return view; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + + if (errorPanel != null) { + errorPanel.dispose(); + errorPanel = null; + } } @Override diff --git a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java index 4df905a31..1a5e5aa45 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java @@ -36,7 +36,9 @@ import com.google.android.material.tabs.TabLayout; import org.schabi.newpipe.BaseFragment; import org.schabi.newpipe.R; import org.schabi.newpipe.databinding.FragmentMainBinding; +import org.schabi.newpipe.error.ErrorInfo; import org.schabi.newpipe.error.ErrorUtil; +import org.schabi.newpipe.error.UserAction; import org.schabi.newpipe.local.playlist.LocalPlaylistFragment; import org.schabi.newpipe.settings.tabs.Tab; import org.schabi.newpipe.settings.tabs.TabsManager; @@ -302,10 +304,9 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte final Fragment fragment; try { fragment = tab.getFragment(context); - } catch (final Exception e) { - ErrorUtil.showUiErrorSnackbar(context, "Getting fragment item", e); - // TODO: show an error fragment instead - return new BlankFragment(); + } catch (final Throwable t) { + return new BlankFragment(new ErrorInfo(t, UserAction.GETTING_MAIN_SCREEN_TAB, + "Tab " + tab.getClass().getSimpleName() + ":" + tab.getTabName(context))); } if (fragment instanceof BaseFragment) { diff --git a/app/src/main/res/layout/fragment_blank.xml b/app/src/main/res/layout/fragment_blank.xml index 6c2978e95..4d874ebdb 100644 --- a/app/src/main/res/layout/fragment_blank.xml +++ b/app/src/main/res/layout/fragment_blank.xml @@ -4,7 +4,9 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - +