2018-04-21 23:10:01 +02:00
|
|
|
package org.schabi.newpipe.player.playqueue;
|
2017-11-03 04:34:12 +01:00
|
|
|
|
|
|
|
import android.util.Log;
|
|
|
|
|
2020-07-14 21:15:29 +02:00
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
|
2017-11-03 04:34:12 +01:00
|
|
|
import org.schabi.newpipe.extractor.InfoItem;
|
|
|
|
import org.schabi.newpipe.extractor.ListExtractor;
|
|
|
|
import org.schabi.newpipe.extractor.ListInfo;
|
2020-04-15 15:31:53 +02:00
|
|
|
import org.schabi.newpipe.extractor.Page;
|
2017-11-03 04:34:12 +01:00
|
|
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
|
|
|
|
2020-10-31 21:55:45 +01:00
|
|
|
import io.reactivex.rxjava3.core.SingleObserver;
|
|
|
|
import io.reactivex.rxjava3.disposables.Disposable;
|
2017-11-03 04:34:12 +01:00
|
|
|
|
|
|
|
abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> extends PlayQueue {
|
2020-03-31 19:20:15 +02:00
|
|
|
boolean isInitial;
|
|
|
|
private boolean isComplete;
|
2020-04-02 13:51:10 +02:00
|
|
|
|
|
|
|
final int serviceId;
|
|
|
|
final String baseUrl;
|
2020-04-15 15:31:53 +02:00
|
|
|
Page nextPage;
|
2017-11-03 04:34:12 +01:00
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
private transient Disposable fetchReactor;
|
2017-11-03 04:34:12 +01:00
|
|
|
|
|
|
|
AbstractInfoPlayQueue(final U item) {
|
2018-08-28 19:17:14 +02:00
|
|
|
this(item.getServiceId(), item.getUrl(), null, Collections.emptyList(), 0);
|
2017-11-03 04:34:12 +01:00
|
|
|
}
|
|
|
|
|
2020-04-15 15:31:53 +02:00
|
|
|
AbstractInfoPlayQueue(final int serviceId, final String url, final Page nextPage,
|
2020-03-31 19:20:15 +02:00
|
|
|
final List<StreamInfoItem> streams, final int index) {
|
2017-11-03 04:34:12 +01:00
|
|
|
super(index, extractListItems(streams));
|
|
|
|
|
|
|
|
this.baseUrl = url;
|
2020-04-15 15:31:53 +02:00
|
|
|
this.nextPage = nextPage;
|
2017-11-03 04:34:12 +01:00
|
|
|
this.serviceId = serviceId;
|
|
|
|
|
|
|
|
this.isInitial = streams.isEmpty();
|
2020-04-15 15:31:53 +02:00
|
|
|
this.isComplete = !isInitial && !Page.isValid(nextPage);
|
2017-11-03 04:34:12 +01:00
|
|
|
}
|
|
|
|
|
2020-03-31 19:20:15 +02:00
|
|
|
protected abstract String getTag();
|
2017-11-03 04:34:12 +01:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isComplete() {
|
|
|
|
return isComplete;
|
|
|
|
}
|
|
|
|
|
|
|
|
SingleObserver<T> getHeadListObserver() {
|
|
|
|
return new SingleObserver<T>() {
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onSubscribe(@NonNull final Disposable d) {
|
|
|
|
if (isComplete || !isInitial || (fetchReactor != null
|
|
|
|
&& !fetchReactor.isDisposed())) {
|
2017-11-03 04:34:12 +01:00
|
|
|
d.dispose();
|
|
|
|
} else {
|
|
|
|
fetchReactor = d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onSuccess(@NonNull final T result) {
|
2017-11-04 19:30:01 +01:00
|
|
|
isInitial = false;
|
2020-03-31 19:20:15 +02:00
|
|
|
if (!result.hasNextPage()) {
|
|
|
|
isComplete = true;
|
|
|
|
}
|
2020-04-15 15:31:53 +02:00
|
|
|
nextPage = result.getNextPage();
|
2017-11-03 04:34:12 +01:00
|
|
|
|
2018-03-18 16:37:49 +01:00
|
|
|
append(extractListItems(result.getRelatedItems()));
|
2017-11-03 04:34:12 +01:00
|
|
|
|
|
|
|
fetchReactor.dispose();
|
|
|
|
fetchReactor = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onError(@NonNull final Throwable e) {
|
2017-11-03 04:34:12 +01:00
|
|
|
Log.e(getTag(), "Error fetching more playlist, marking playlist as complete.", e);
|
|
|
|
isComplete = true;
|
|
|
|
append(); // Notify change
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-03-18 16:37:49 +01:00
|
|
|
SingleObserver<ListExtractor.InfoItemsPage> getNextPageObserver() {
|
|
|
|
return new SingleObserver<ListExtractor.InfoItemsPage>() {
|
2017-11-03 04:34:12 +01:00
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onSubscribe(@NonNull final Disposable d) {
|
|
|
|
if (isComplete || isInitial || (fetchReactor != null
|
|
|
|
&& !fetchReactor.isDisposed())) {
|
2017-11-03 04:34:12 +01:00
|
|
|
d.dispose();
|
|
|
|
} else {
|
|
|
|
fetchReactor = d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onSuccess(@NonNull final ListExtractor.InfoItemsPage result) {
|
|
|
|
if (!result.hasNextPage()) {
|
|
|
|
isComplete = true;
|
|
|
|
}
|
2020-04-15 15:31:53 +02:00
|
|
|
nextPage = result.getNextPage();
|
2017-11-03 04:34:12 +01:00
|
|
|
|
2018-03-18 16:37:49 +01:00
|
|
|
append(extractListItems(result.getItems()));
|
2017-11-03 04:34:12 +01:00
|
|
|
|
|
|
|
fetchReactor.dispose();
|
|
|
|
fetchReactor = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-03-31 19:20:15 +02:00
|
|
|
public void onError(@NonNull final Throwable e) {
|
2017-11-03 04:34:12 +01:00
|
|
|
Log.e(getTag(), "Error fetching more playlist, marking playlist as complete.", e);
|
|
|
|
isComplete = true;
|
|
|
|
append(); // Notify change
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void dispose() {
|
|
|
|
super.dispose();
|
2020-03-31 19:20:15 +02:00
|
|
|
if (fetchReactor != null) {
|
|
|
|
fetchReactor.dispose();
|
2017-11-03 04:34:12 +01:00
|
|
|
}
|
2020-03-31 19:20:15 +02:00
|
|
|
fetchReactor = null;
|
2017-11-03 04:34:12 +01:00
|
|
|
}
|
2020-04-02 13:51:10 +02:00
|
|
|
|
|
|
|
private static List<PlayQueueItem> extractListItems(final List<StreamInfoItem> infos) {
|
2020-08-16 10:24:58 +02:00
|
|
|
final List<PlayQueueItem> result = new ArrayList<>();
|
2020-04-02 13:51:10 +02:00
|
|
|
for (final InfoItem stream : infos) {
|
|
|
|
if (stream instanceof StreamInfoItem) {
|
|
|
|
result.add(new PlayQueueItem((StreamInfoItem) stream));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2017-11-03 04:34:12 +01:00
|
|
|
}
|