-Revert subscription fragment merge fault
This commit is contained in:
parent
725cedab72
commit
1ceda017c7
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue