2017-09-03 08:04:18 +02:00
|
|
|
package org.schabi.newpipe.fragments;
|
|
|
|
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.util.Log;
|
|
|
|
import android.view.View;
|
|
|
|
import android.widget.ProgressBar;
|
|
|
|
|
2020-11-01 13:55:20 +01:00
|
|
|
import androidx.annotation.NonNull;
|
2020-03-31 19:20:15 +02:00
|
|
|
import androidx.annotation.Nullable;
|
2021-12-01 09:43:24 +01:00
|
|
|
import androidx.fragment.app.Fragment;
|
2017-09-03 08:04:18 +02:00
|
|
|
|
|
|
|
import org.schabi.newpipe.BaseFragment;
|
|
|
|
import org.schabi.newpipe.R;
|
2020-12-09 12:42:01 +01:00
|
|
|
import org.schabi.newpipe.error.ErrorInfo;
|
2020-12-11 14:55:47 +01:00
|
|
|
import org.schabi.newpipe.error.ErrorPanelHelper;
|
2021-12-01 09:43:24 +01:00
|
|
|
import org.schabi.newpipe.error.ErrorUtil;
|
2017-09-03 08:04:18 +02:00
|
|
|
import org.schabi.newpipe.util.InfoCache;
|
|
|
|
|
|
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
|
|
|
|
import icepick.State;
|
|
|
|
|
2021-01-16 04:32:01 +01:00
|
|
|
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
2017-09-03 08:04:18 +02:00
|
|
|
|
|
|
|
public abstract class BaseStateFragment<I> extends BaseFragment implements ViewContract<I> {
|
|
|
|
@State
|
|
|
|
protected AtomicBoolean wasLoading = new AtomicBoolean();
|
|
|
|
protected AtomicBoolean isLoading = new AtomicBoolean();
|
|
|
|
|
|
|
|
@Nullable
|
2020-03-31 19:20:15 +02:00
|
|
|
private View emptyStateView;
|
2017-09-03 08:04:18 +02:00
|
|
|
@Nullable
|
2020-03-31 19:20:15 +02:00
|
|
|
private ProgressBar loadingProgressBar;
|
2021-01-15 15:38:25 +01:00
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
private ErrorPanelHelper errorPanelHelper;
|
2021-01-15 15:38:25 +01:00
|
|
|
@Nullable
|
|
|
|
@State
|
|
|
|
protected ErrorInfo lastPanelError = null;
|
2017-09-03 08:04:18 +02:00
|
|
|
|
|
|
|
@Override
|
2020-11-01 13:55:20 +01:00
|
|
|
public void onViewCreated(@NonNull final View rootView, final Bundle savedInstanceState) {
|
2017-09-03 08:04:18 +02:00
|
|
|
super.onViewCreated(rootView, savedInstanceState);
|
|
|
|
doInitialLoadLogic();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onPause() {
|
|
|
|
super.onPause();
|
|
|
|
wasLoading.set(isLoading.get());
|
|
|
|
}
|
|
|
|
|
2021-01-15 15:38:25 +01:00
|
|
|
@Override
|
|
|
|
public void onResume() {
|
|
|
|
super.onResume();
|
|
|
|
if (lastPanelError != null) {
|
|
|
|
showError(lastPanelError);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-03 08:04:18 +02:00
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Init
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
protected void initViews(final View rootView, final Bundle savedInstanceState) {
|
2017-09-03 08:04:18 +02:00
|
|
|
super.initViews(rootView, savedInstanceState);
|
|
|
|
emptyStateView = rootView.findViewById(R.id.empty_state_view);
|
|
|
|
loadingProgressBar = rootView.findViewById(R.id.loading_progress_bar);
|
2020-12-11 14:55:47 +01:00
|
|
|
errorPanelHelper = new ErrorPanelHelper(this, rootView, this::onRetryButtonClicked);
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
2021-03-24 09:27:17 +01:00
|
|
|
@Override
|
|
|
|
public void onDestroyView() {
|
|
|
|
super.onDestroyView();
|
|
|
|
if (errorPanelHelper != null) {
|
|
|
|
errorPanelHelper.dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-03 08:04:18 +02:00
|
|
|
protected void onRetryButtonClicked() {
|
|
|
|
reloadContent();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void reloadContent() {
|
|
|
|
startLoading(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Load
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
|
|
|
protected void doInitialLoadLogic() {
|
|
|
|
startLoading(true);
|
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
protected void startLoading(final boolean forceLoad) {
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.d(TAG, "startLoading() called with: forceLoad = [" + forceLoad + "]");
|
|
|
|
}
|
2017-09-03 08:04:18 +02:00
|
|
|
showLoading();
|
|
|
|
isLoading.set(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Contract
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void showLoading() {
|
2020-03-31 19:20:15 +02:00
|
|
|
if (emptyStateView != null) {
|
2021-01-16 04:32:01 +01:00
|
|
|
animate(emptyStateView, false, 150);
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
|
|
|
if (loadingProgressBar != null) {
|
2021-01-16 04:32:01 +01:00
|
|
|
animate(loadingProgressBar, true, 400);
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
2021-01-15 15:38:25 +01:00
|
|
|
hideErrorPanel();
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void hideLoading() {
|
2020-03-31 19:20:15 +02:00
|
|
|
if (emptyStateView != null) {
|
2021-01-16 04:32:01 +01:00
|
|
|
animate(emptyStateView, false, 150);
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
|
|
|
if (loadingProgressBar != null) {
|
2021-01-16 04:32:01 +01:00
|
|
|
animate(loadingProgressBar, false, 0);
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
2021-01-15 15:38:25 +01:00
|
|
|
hideErrorPanel();
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void showEmptyState() {
|
|
|
|
isLoading.set(false);
|
2020-03-31 19:20:15 +02:00
|
|
|
if (emptyStateView != null) {
|
2021-01-16 04:32:01 +01:00
|
|
|
animate(emptyStateView, true, 200);
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
|
|
|
if (loadingProgressBar != null) {
|
2021-01-16 04:32:01 +01:00
|
|
|
animate(loadingProgressBar, false, 0);
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
2021-01-15 15:38:25 +01:00
|
|
|
hideErrorPanel();
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-12-11 14:55:47 +01:00
|
|
|
public void handleResult(final I result) {
|
2020-03-31 19:20:15 +02:00
|
|
|
if (DEBUG) {
|
2020-12-11 14:55:47 +01:00
|
|
|
Log.d(TAG, "handleResult() called with: result = [" + result + "]");
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
2017-09-03 08:04:18 +02:00
|
|
|
hideLoading();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-12-11 14:55:47 +01:00
|
|
|
public void handleError() {
|
|
|
|
isLoading.set(false);
|
|
|
|
InfoCache.getInstance().clearCache();
|
2021-01-15 11:26:09 +01:00
|
|
|
if (emptyStateView != null) {
|
2021-01-15 14:55:05 +01:00
|
|
|
animate(emptyStateView, false, 150);
|
2021-01-15 11:26:09 +01:00
|
|
|
}
|
|
|
|
if (loadingProgressBar != null) {
|
2021-01-15 14:55:05 +01:00
|
|
|
animate(loadingProgressBar, false, 0);
|
2021-01-15 11:26:09 +01:00
|
|
|
}
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Error handling
|
|
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
public final void showError(final ErrorInfo errorInfo) {
|
|
|
|
handleError();
|
2017-09-03 08:04:18 +02:00
|
|
|
|
|
|
|
if (isDetached() || isRemoving()) {
|
2020-03-31 19:20:15 +02:00
|
|
|
if (DEBUG) {
|
2020-12-11 14:55:47 +01:00
|
|
|
Log.w(TAG, "showError() is detached or removing = [" + errorInfo + "]");
|
2020-03-31 19:20:15 +02:00
|
|
|
}
|
2020-12-11 14:55:47 +01:00
|
|
|
return;
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
errorPanelHelper.showError(errorInfo);
|
2021-01-15 15:38:25 +01:00
|
|
|
lastPanelError = errorInfo;
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
2021-01-09 16:33:59 +01:00
|
|
|
public final void showTextError(@NonNull final String errorString) {
|
2020-12-11 14:55:47 +01:00
|
|
|
handleError();
|
2017-09-03 08:04:18 +02:00
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
if (isDetached() || isRemoving()) {
|
|
|
|
if (DEBUG) {
|
|
|
|
Log.w(TAG, "showTextError() is detached or removing = [" + errorString + "]");
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2017-09-03 08:04:18 +02:00
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
errorPanelHelper.showTextError(errorString);
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
public final void hideErrorPanel() {
|
|
|
|
errorPanelHelper.hide();
|
2021-01-15 15:38:25 +01:00
|
|
|
lastPanelError = null;
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
2020-12-11 14:55:47 +01:00
|
|
|
public final boolean isErrorPanelVisible() {
|
|
|
|
return errorPanelHelper.isVisible();
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-12-01 09:43:24 +01:00
|
|
|
* Directly calls {@link ErrorUtil#showSnackbar(Fragment, ErrorInfo)}, that shows a snackbar if
|
|
|
|
* a valid view can be found, otherwise creates an error report notification.
|
2020-03-31 19:20:15 +02:00
|
|
|
*
|
2020-12-11 14:55:47 +01:00
|
|
|
* @param errorInfo The error information
|
2017-09-03 08:04:18 +02:00
|
|
|
*/
|
2020-12-11 14:55:47 +01:00
|
|
|
public void showSnackBarError(final ErrorInfo errorInfo) {
|
2017-09-03 08:04:18 +02:00
|
|
|
if (DEBUG) {
|
2020-12-11 14:55:47 +01:00
|
|
|
Log.d(TAG, "showSnackBarError() called with: errorInfo = [" + errorInfo + "]");
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
2021-12-01 09:43:24 +01:00
|
|
|
ErrorUtil.showSnackbar(this, errorInfo);
|
2017-09-03 08:04:18 +02:00
|
|
|
}
|
|
|
|
}
|