mirror of https://github.com/TeamNewPipe/NewPipe
217 lines
7.2 KiB
Java
217 lines
7.2 KiB
Java
package org.schabi.newpipe.fragments.list;
|
|
|
|
import android.os.Bundle;
|
|
import android.support.annotation.NonNull;
|
|
import android.text.TextUtils;
|
|
import android.util.Log;
|
|
import android.view.View;
|
|
|
|
import org.schabi.newpipe.extractor.ListExtractor;
|
|
import org.schabi.newpipe.extractor.ListInfo;
|
|
|
|
import java.util.Queue;
|
|
|
|
import icepick.State;
|
|
import io.reactivex.Single;
|
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
import io.reactivex.disposables.Disposable;
|
|
import io.reactivex.functions.Consumer;
|
|
import io.reactivex.schedulers.Schedulers;
|
|
|
|
public abstract class BaseListInfoFragment<I extends ListInfo> extends BaseListFragment<I, ListExtractor.NextItemsResult> {
|
|
|
|
@State
|
|
protected int serviceId = -1;
|
|
@State
|
|
protected String name;
|
|
@State
|
|
protected String url;
|
|
|
|
protected I currentInfo;
|
|
protected String currentNextItemsUrl;
|
|
protected Disposable currentWorker;
|
|
|
|
@Override
|
|
protected void initViews(View rootView, Bundle savedInstanceState) {
|
|
super.initViews(rootView, savedInstanceState);
|
|
setTitle(name);
|
|
showListFooter(hasMoreItems());
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
super.onPause();
|
|
if (currentWorker != null) currentWorker.dispose();
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
super.onResume();
|
|
// Check if it was loading when the fragment was stopped/paused,
|
|
if (wasLoading.getAndSet(false)) {
|
|
if (hasMoreItems() && infoListAdapter.getItemsList().size() > 0) {
|
|
loadMoreItems();
|
|
} else {
|
|
doInitialLoadLogic();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onDestroy() {
|
|
super.onDestroy();
|
|
if (currentWorker != null) currentWorker.dispose();
|
|
currentWorker = null;
|
|
}
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
// State Saving
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
@Override
|
|
public void writeTo(Queue<Object> objectsToSave) {
|
|
super.writeTo(objectsToSave);
|
|
objectsToSave.add(currentInfo);
|
|
objectsToSave.add(currentNextItemsUrl);
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("unchecked")
|
|
public void readFrom(@NonNull Queue<Object> savedObjects) throws Exception {
|
|
super.readFrom(savedObjects);
|
|
currentInfo = (I) savedObjects.poll();
|
|
currentNextItemsUrl = (String) savedObjects.poll();
|
|
}
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
// Utils
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
public void setTitle(String title) {
|
|
Log.d(TAG, "setTitle() called with: title = [" + title + "]");
|
|
if (activity.getSupportActionBar() != null) {
|
|
activity.getSupportActionBar().setTitle(title);
|
|
}
|
|
}
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
// Load and handle
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
protected void doInitialLoadLogic() {
|
|
if (DEBUG) Log.d(TAG, "doInitialLoadLogic() called");
|
|
if (currentInfo == null) {
|
|
startLoading(false);
|
|
} else handleResult(currentInfo);
|
|
}
|
|
|
|
/**
|
|
* Implement the logic to load the info from the network.<br/>
|
|
* You can use the default implementations from {@link org.schabi.newpipe.util.ExtractorHelper}.
|
|
*
|
|
* @param forceLoad allow or disallow the result to come from the cache
|
|
*/
|
|
protected abstract Single<I> loadResult(boolean forceLoad);
|
|
|
|
@Override
|
|
public void startLoading(boolean forceLoad) {
|
|
super.startLoading(forceLoad);
|
|
|
|
showListFooter(false);
|
|
currentInfo = null;
|
|
if (currentWorker != null) currentWorker.dispose();
|
|
currentWorker = loadResult(forceLoad)
|
|
.subscribeOn(Schedulers.io())
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
.subscribe(new Consumer<I>() {
|
|
@Override
|
|
public void accept(@NonNull I result) throws Exception {
|
|
isLoading.set(false);
|
|
currentInfo = result;
|
|
currentNextItemsUrl = result.next_streams_url;
|
|
handleResult(result);
|
|
}
|
|
}, new Consumer<Throwable>() {
|
|
@Override
|
|
public void accept(@NonNull Throwable throwable) throws Exception {
|
|
onError(throwable);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Implement the logic to load more items<br/>
|
|
* You can use the default implementations from {@link org.schabi.newpipe.util.ExtractorHelper}
|
|
*/
|
|
protected abstract Single<ListExtractor.NextItemsResult> loadMoreItemsLogic();
|
|
|
|
protected void loadMoreItems() {
|
|
isLoading.set(true);
|
|
|
|
if (currentWorker != null) currentWorker.dispose();
|
|
currentWorker = loadMoreItemsLogic()
|
|
.subscribeOn(Schedulers.io())
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
.subscribe(new Consumer<ListExtractor.NextItemsResult>() {
|
|
@Override
|
|
public void accept(@io.reactivex.annotations.NonNull ListExtractor.NextItemsResult nextItemsResult) throws Exception {
|
|
isLoading.set(false);
|
|
handleNextItems(nextItemsResult);
|
|
}
|
|
}, new Consumer<Throwable>() {
|
|
@Override
|
|
public void accept(@io.reactivex.annotations.NonNull Throwable throwable) throws Exception {
|
|
isLoading.set(false);
|
|
onError(throwable);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void handleNextItems(ListExtractor.NextItemsResult result) {
|
|
super.handleNextItems(result);
|
|
currentNextItemsUrl = result.nextItemsUrl;
|
|
infoListAdapter.addInfoItemList(result.nextItemsList);
|
|
|
|
showListFooter(hasMoreItems());
|
|
}
|
|
|
|
@Override
|
|
protected boolean hasMoreItems() {
|
|
return !TextUtils.isEmpty(currentNextItemsUrl);
|
|
}
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
// Contract
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
@Override
|
|
public void handleResult(@NonNull I result) {
|
|
super.handleResult(result);
|
|
|
|
url = result.url;
|
|
name = result.name;
|
|
setTitle(name);
|
|
|
|
if (infoListAdapter.getItemsList().size() == 0) {
|
|
if (result.related_streams.size() > 0) {
|
|
infoListAdapter.addInfoItemList(result.related_streams);
|
|
showListFooter(hasMoreItems());
|
|
} else {
|
|
infoListAdapter.clearStreamItemList();
|
|
showEmptyState();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
// Utils
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
protected void setInitialData(int serviceId, String url, String name) {
|
|
this.serviceId = serviceId;
|
|
this.url = url;
|
|
this.name = !TextUtils.isEmpty(name) ? name : "";
|
|
}
|
|
}
|