-Revert subscription fragment merge fault

This commit is contained in:
John Zhen M 2017-09-04 06:52:55 -07:00 committed by John Zhen Mo
parent 725cedab72
commit 1ceda017c7
1 changed files with 100 additions and 136 deletions

View File

@ -1,21 +1,21 @@
package org.schabi.newpipe.fragments.subscription; package org.schabi.newpipe.fragments.subscription;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.database.subscription.SubscriptionEntity; import org.schabi.newpipe.database.subscription.SubscriptionEntity;
import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.fragments.BaseFragment; import org.schabi.newpipe.fragments.BaseStateFragment;
import org.schabi.newpipe.info_list.InfoItemBuilder; import org.schabi.newpipe.info_list.InfoItemBuilder;
import org.schabi.newpipe.info_list.InfoListAdapter; import org.schabi.newpipe.info_list.InfoListAdapter;
import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.report.UserAction;
@ -23,37 +23,32 @@ import org.schabi.newpipe.util.KioskTranslator;
import org.schabi.newpipe.report.ErrorActivity; import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import icepick.State;
import io.reactivex.Observer; import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import static org.schabi.newpipe.report.UserAction.REQUESTED_CHANNEL;
import static org.schabi.newpipe.util.AnimationUtils.animateView; import static org.schabi.newpipe.util.AnimationUtils.animateView;
public class SubscriptionFragment extends BaseFragment { public class SubscriptionFragment extends BaseStateFragment<List<SubscriptionEntity>> {
private static final String VIEW_STATE_KEY = "view_state_key";
private final String TAG = "SubscriptionFragment@" + Integer.toHexString(hashCode());
private View inflatedView;
private View emptyPanel;
private View headerRootLayout; private View headerRootLayout;
private View whatsNewView;
private InfoListAdapter infoListAdapter; private InfoListAdapter infoListAdapter;
private RecyclerView resultRecyclerView; private RecyclerView itemsList;
private Parcelable viewState;
@State
protected Parcelable itemsListState;
/* Used for independent events */ /* Used for independent events */
private CompositeDisposable disposables; private CompositeDisposable disposables = new CompositeDisposable();
private SubscriptionEngine subscriptionEngine; private SubscriptionService subscriptionService;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Fragment LifeCycle // Fragment LifeCycle
@ -71,15 +66,10 @@ public class SubscriptionFragment extends BaseFragment {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onAttach(Context context) {
super.onCreate(savedInstanceState); super.onAttach(context);
infoListAdapter = new InfoListAdapter(activity);
disposables = new CompositeDisposable(); subscriptionService = SubscriptionService.getInstance();
subscriptionEngine = SubscriptionEngine.getInstance( getContext() );
if (savedInstanceState != null) {
viewState = savedInstanceState.getParcelable(VIEW_STATE_KEY);
}
} }
@Nullable @Nullable
@ -94,19 +84,15 @@ public class SubscriptionFragment extends BaseFragment {
} }
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onPause() {
super.onSaveInstanceState(outState); super.onPause();
itemsListState = itemsList.getLayoutManager().onSaveInstanceState();
outState.putParcelable(VIEW_STATE_KEY, viewState);
} }
@Override @Override
public void onDestroyView() { public void onDestroyView() {
if (disposables != null) disposables.clear(); if (disposables != null) disposables.clear();
headerRootLayout = null;
whatsNewView = null;
super.onDestroyView(); super.onDestroyView();
} }
@ -114,8 +100,7 @@ public class SubscriptionFragment extends BaseFragment {
public void onDestroy() { public void onDestroy() {
if (disposables != null) disposables.dispose(); if (disposables != null) disposables.dispose();
disposables = null; disposables = null;
subscriptionService = null;
subscriptionEngine = null;
super.onDestroy(); super.onDestroy();
} }
@ -124,70 +109,39 @@ public class SubscriptionFragment extends BaseFragment {
// Fragment Views // Fragment Views
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
private RecyclerView.OnScrollListener getOnScrollListener() {
return new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
viewState = recyclerView.getLayoutManager().onSaveInstanceState();
}
}
};
}
private View.OnClickListener getWhatsNewOnClickListener() {
return new View.OnClickListener() {
@Override
public void onClick(View view) {
NavigationHelper.openWhatsNewFragment(getParentFragment().getFragmentManager());
}
};
}
@Override @Override
protected void initViews(View rootView, Bundle savedInstanceState) { protected void initViews(View rootView, Bundle savedInstanceState) {
super.initViews(rootView, savedInstanceState); super.initViews(rootView, savedInstanceState);
emptyPanel = rootView.findViewById(R.id.empty_panel); infoListAdapter = new InfoListAdapter(getActivity());
itemsList = rootView.findViewById(R.id.items_list);
itemsList.setLayoutManager(new LinearLayoutManager(activity));
resultRecyclerView = rootView.findViewById(R.id.result_list_view); infoListAdapter.setHeader(headerRootLayout = activity.getLayoutInflater().inflate(R.layout.subscription_header, itemsList, false));
resultRecyclerView.setLayoutManager(new LinearLayoutManager(activity)); infoListAdapter.useMiniItemVariants(true);
resultRecyclerView.addOnScrollListener(getOnScrollListener());
if (infoListAdapter == null) { itemsList.setAdapter(infoListAdapter);
infoListAdapter = new InfoListAdapter(getActivity());
infoListAdapter.setFooter(activity.getLayoutInflater().inflate(R.layout.pignate_footer, resultRecyclerView, false));
infoListAdapter.showFooter(false);
infoListAdapter.setOnChannelInfoItemSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener() {
@Override
public void selected(int serviceId, String url, String title) {
/* Requires the parent fragment to find holder for fragment replacement */
NavigationHelper.openChannelFragment(getParentFragment().getFragmentManager(), serviceId, url, title);
}
});
}
headerRootLayout = activity.getLayoutInflater().inflate(R.layout.subscription_header, resultRecyclerView, false);
infoListAdapter.setHeader(headerRootLayout);
whatsNewView = headerRootLayout.findViewById(R.id.whatsNew);
whatsNewView.setOnClickListener(getWhatsNewOnClickListener());
resultRecyclerView.setAdapter(infoListAdapter);
populateView();
} }
@Override @Override
protected void reloadContent() { protected void initListeners() {
populateView(); super.initListeners();
}
@Override infoListAdapter.setOnChannelSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener<ChannelInfoItem>() {
protected void setErrorMessage(String message, boolean showRetryButton) { @Override
super.setErrorMessage(message, showRetryButton); public void selected(ChannelInfoItem selectedItem) {
resetFragment(); // Requires the parent fragment to find holder for fragment replacement
NavigationHelper.openChannelFragment(getParentFragment().getFragmentManager(), selectedItem.service_id, selectedItem.url, selectedItem.name);
}
});
headerRootLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavigationHelper.openWhatsNewFragment(getParentFragment().getFragmentManager());
}
});
} }
private void resetFragment() { private void resetFragment() {
@ -199,13 +153,12 @@ public class SubscriptionFragment extends BaseFragment {
// Subscriptions Loader // Subscriptions Loader
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
private void populateView() { @Override
public void startLoading(boolean forceLoad) {
super.startLoading(forceLoad);
resetFragment(); resetFragment();
animateView(loadingProgressBar, true, 200); subscriptionService.getSubscription().toObservable()
animateView(errorPanel, false, 200);
subscriptionEngine.getSubscription().toObservable()
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(getSubscriptionObserver()); .subscribe(getSubscriptionObserver());
@ -215,80 +168,91 @@ public class SubscriptionFragment extends BaseFragment {
return new Observer<List<SubscriptionEntity>>() { return new Observer<List<SubscriptionEntity>>() {
@Override @Override
public void onSubscribe(Disposable d) { public void onSubscribe(Disposable d) {
animateView(loadingProgressBar, true, 200); showLoading();
disposables.add(d);
disposables.add( d );
} }
@Override @Override
public void onNext(List<SubscriptionEntity> subscriptions) { public void onNext(List<SubscriptionEntity> subscriptions) {
animateView(loadingProgressBar, true, 200); handleResult(subscriptions);
infoListAdapter.clearStreamItemList();
infoListAdapter.addInfoItemList( getSubscriptionItems(subscriptions) );
animateView(loadingProgressBar, false, 200);
emptyPanel.setVisibility(subscriptions.isEmpty() ? View.VISIBLE : View.INVISIBLE);
if (viewState != null && resultRecyclerView != null) {
resultRecyclerView.getLayoutManager().onRestoreInstanceState(viewState);
}
} }
@Override @Override
public void onError(Throwable exception) { public void onError(Throwable exception) {
if (exception instanceof IOException) { SubscriptionFragment.this.onError(exception);
onRecoverableError(R.string.network_error);
} else {
onUnrecoverableError(exception);
}
} }
@Override @Override
public void onComplete() { public void onComplete() {
} }
}; };
} }
@Override
public void handleResult(@NonNull List<SubscriptionEntity> result) {
super.handleResult(result);
infoListAdapter.clearStreamItemList();
if (result.isEmpty()) {
showEmptyState();
} else {
infoListAdapter.addInfoItemList(getSubscriptionItems(result));
if (itemsListState != null) {
itemsList.getLayoutManager().onRestoreInstanceState(itemsListState);
itemsListState = null;
}
hideLoading();
}
}
private List<InfoItem> getSubscriptionItems(List<SubscriptionEntity> subscriptions) { private List<InfoItem> getSubscriptionItems(List<SubscriptionEntity> subscriptions) {
List<InfoItem> items = new ArrayList<>(); List<InfoItem> items = new ArrayList<>();
for (final SubscriptionEntity subscription: subscriptions) { for (final SubscriptionEntity subscription : subscriptions) items.add(subscription.toChannelInfoItem());
ChannelInfoItem item = new ChannelInfoItem();
item.webPageUrl = subscription.getUrl();
item.serviceId = subscription.getServiceId();
item.channelName = subscription.getTitle();
item.thumbnailUrl = subscription.getThumbnailUrl();
item.subscriberCount = subscription.getSubscriberCount();
item.description = subscription.getDescription();
items.add( item );
}
Collections.sort(items, new Comparator<InfoItem>() { Collections.sort(items, new Comparator<InfoItem>() {
@Override @Override
public int compare(InfoItem o1, InfoItem o2) { public int compare(InfoItem o1, InfoItem o2) {
return o1.getTitle().compareToIgnoreCase(o2.getTitle()); return o1.name.compareToIgnoreCase(o2.name);
} }
}); });
return items; return items;
} }
/*//////////////////////////////////////////////////////////////////////////
// Contract
//////////////////////////////////////////////////////////////////////////*/
@Override
public void showLoading() {
super.showLoading();
animateView(itemsList, false, 100);
}
@Override
public void hideLoading() {
super.hideLoading();
animateView(itemsList, true, 200);
}
@Override
public void showEmptyState() {
super.showEmptyState();
animateView(itemsList, false, 200);
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Fragment Error Handling // Fragment Error Handling
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
private void onRecoverableError(int messageId) { @Override
if (!this.isAdded()) return; protected boolean onError(Throwable exception) {
resetFragment();
if (super.onError(exception)) return true;
if (DEBUG) Log.d(TAG, "onError() called with: messageId = [" + messageId + "]"); onUnrecoverableError(exception, UserAction.SOMETHING_ELSE, "none", "Subscriptions", R.string.general_error);
setErrorMessage(getString(messageId), true); return true;
}
private void onUnrecoverableError(Throwable exception) {
if (DEBUG) Log.d(TAG, "onUnrecoverableError() called with: exception = [" + exception + "]");
ErrorActivity.reportError(getContext(), exception, MainActivity.class, null, ErrorActivity.ErrorInfo.make(REQUESTED_CHANNEL, "unknown", "unknown", R.string.general_error));
activity.finish();
} }
} }