mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-11-04 09:13:00 +00:00 
			
		
		
		
	Merge pull request #1193 from TeamNewPipe/fix_page
made frontend combatible to latest extractor refactorings
This commit is contained in:
		@@ -55,7 +55,7 @@ dependencies {
 | 
			
		||||
        exclude module: 'support-annotations'
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    implementation 'com.github.TeamNewPipe:NewPipeExtractor:fce324d1bc74bc'
 | 
			
		||||
    implementation 'com.github.TeamNewPipe:NewPipeExtractor:f787b375e5fb6d'
 | 
			
		||||
 | 
			
		||||
    testImplementation 'junit:junit:4.12'
 | 
			
		||||
    testImplementation 'org.mockito:mockito-core:1.10.19'
 | 
			
		||||
 
 | 
			
		||||
@@ -71,14 +71,14 @@ public class StreamEntity implements Serializable {
 | 
			
		||||
 | 
			
		||||
    @Ignore
 | 
			
		||||
    public StreamEntity(final StreamInfoItem item) {
 | 
			
		||||
        this(item.service_id, item.name, item.url, item.stream_type, item.thumbnail_url,
 | 
			
		||||
                item.uploader_name, item.duration);
 | 
			
		||||
        this(item.getServiceId(), item.getName(), item.getUrl(), item.getStreamType(), item.getThumbnailUrl(),
 | 
			
		||||
                item.getUploaderName(), item.getDuration());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Ignore
 | 
			
		||||
    public StreamEntity(final StreamInfo info) {
 | 
			
		||||
        this(info.service_id, info.name, info.url, info.stream_type, info.thumbnail_url,
 | 
			
		||||
                info.uploader_name, info.duration);
 | 
			
		||||
        this(info.getServiceId(), info.getName(), info.getUrl(), info.getStreamType(), info.getThumbnailUrl(),
 | 
			
		||||
                info.getUploaderName(), info.getDuration());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Ignore
 | 
			
		||||
 
 | 
			
		||||
@@ -205,7 +205,7 @@ public class DownloadDialog extends DialogFragment implements RadioGroup.OnCheck
 | 
			
		||||
        if (DEBUG) Log.d(TAG, "onCheckedChanged() called with: group = [" + group + "], checkedId = [" + checkedId + "]");
 | 
			
		||||
        switch (checkedId) {
 | 
			
		||||
            case R.id.audio_button:
 | 
			
		||||
                setupAudioSpinner(currentInfo.audio_streams, streamsSpinner);
 | 
			
		||||
                setupAudioSpinner(currentInfo.getAudioStreams(), streamsSpinner);
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.video_button:
 | 
			
		||||
                setupVideoSpinner(sortedStreamVideosList, streamsSpinner);
 | 
			
		||||
 
 | 
			
		||||
@@ -383,7 +383,8 @@ public class VideoDetailFragment
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case R.id.detail_thumbnail_root_layout:
 | 
			
		||||
                if (currentInfo.video_streams.isEmpty() && currentInfo.video_only_streams.isEmpty()) {
 | 
			
		||||
                if (currentInfo.getVideoStreams().isEmpty()
 | 
			
		||||
                        && currentInfo.getVideoOnlyStreams().isEmpty()) {
 | 
			
		||||
                    openBackgroundPlayer(false);
 | 
			
		||||
                } else {
 | 
			
		||||
                    openVideoPlayer();
 | 
			
		||||
@@ -618,7 +619,8 @@ public class VideoDetailFragment
 | 
			
		||||
            relatedStreamRootLayout.setVisibility(View.VISIBLE);
 | 
			
		||||
        } else nextStreamTitle.setVisibility(View.GONE);
 | 
			
		||||
 | 
			
		||||
        if (info.related_streams != null && !info.related_streams.isEmpty() && showRelatedStreams) {
 | 
			
		||||
        if (info.getRelatedStreams() != null
 | 
			
		||||
                && !info.getRelatedStreams().isEmpty() && showRelatedStreams) {
 | 
			
		||||
            //long first = System.nanoTime(), each;
 | 
			
		||||
            int to = info.getRelatedStreams().size() >= INITIAL_RELATED_VIDEOS
 | 
			
		||||
                    ? INITIAL_RELATED_VIDEOS
 | 
			
		||||
@@ -683,7 +685,7 @@ public class VideoDetailFragment
 | 
			
		||||
        switch (id) {
 | 
			
		||||
            case R.id.menu_item_share: {
 | 
			
		||||
                if(currentInfo != null) {
 | 
			
		||||
                    shareUrl(currentInfo.name, url);
 | 
			
		||||
                    shareUrl(currentInfo.getName(), url);
 | 
			
		||||
                } else {
 | 
			
		||||
                    shareUrl(url, url);
 | 
			
		||||
                }
 | 
			
		||||
@@ -1210,7 +1212,8 @@ public class VideoDetailFragment
 | 
			
		||||
                spinnerToolbar.setVisibility(View.GONE);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                if (!info.video_streams.isEmpty() || !info.video_only_streams.isEmpty()) break;
 | 
			
		||||
                if (!info.getVideoStreams().isEmpty()
 | 
			
		||||
                        || !info.getVideoOnlyStreams().isEmpty()) break;
 | 
			
		||||
 | 
			
		||||
                detailControlsBackground.setVisibility(View.GONE);
 | 
			
		||||
                detailControlsPopup.setVisibility(View.GONE);
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ import io.reactivex.functions.Consumer;
 | 
			
		||||
import io.reactivex.schedulers.Schedulers;
 | 
			
		||||
 | 
			
		||||
public abstract class BaseListInfoFragment<I extends ListInfo>
 | 
			
		||||
        extends BaseListFragment<I, ListExtractor.InfoItemPage> {
 | 
			
		||||
        extends BaseListFragment<I, ListExtractor.InfoItemsPage> {
 | 
			
		||||
 | 
			
		||||
    @State
 | 
			
		||||
    protected int serviceId = Constants.NO_SERVICE_ID;
 | 
			
		||||
@@ -117,7 +117,7 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
 | 
			
		||||
                .subscribe((@NonNull I result) -> {
 | 
			
		||||
                    isLoading.set(false);
 | 
			
		||||
                    currentInfo = result;
 | 
			
		||||
                    currentNextPageUrl = result.next_streams_url;
 | 
			
		||||
                    currentNextPageUrl = result.getNextPageUrl();
 | 
			
		||||
                    handleResult(result);
 | 
			
		||||
                }, (@NonNull Throwable throwable) -> onError(throwable));
 | 
			
		||||
    }
 | 
			
		||||
@@ -126,7 +126,7 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
 | 
			
		||||
     * 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.InfoItemPage> loadMoreItemsLogic();
 | 
			
		||||
    protected abstract Single<ListExtractor.InfoItemsPage> loadMoreItemsLogic();
 | 
			
		||||
 | 
			
		||||
    protected void loadMoreItems() {
 | 
			
		||||
        isLoading.set(true);
 | 
			
		||||
@@ -135,9 +135,9 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
 | 
			
		||||
        currentWorker = loadMoreItemsLogic()
 | 
			
		||||
                .subscribeOn(Schedulers.io())
 | 
			
		||||
                .observeOn(AndroidSchedulers.mainThread())
 | 
			
		||||
                .subscribe((@io.reactivex.annotations.NonNull ListExtractor.InfoItemPage InfoItemPage) -> {
 | 
			
		||||
                .subscribe((@io.reactivex.annotations.NonNull ListExtractor.InfoItemsPage InfoItemsPage) -> {
 | 
			
		||||
                    isLoading.set(false);
 | 
			
		||||
                    handleNextItems(InfoItemPage);
 | 
			
		||||
                    handleNextItems(InfoItemsPage);
 | 
			
		||||
                }, (@io.reactivex.annotations.NonNull Throwable throwable) -> {
 | 
			
		||||
                    isLoading.set(false);
 | 
			
		||||
                    onError(throwable);
 | 
			
		||||
@@ -145,10 +145,10 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void handleNextItems(ListExtractor.InfoItemPage result) {
 | 
			
		||||
    public void handleNextItems(ListExtractor.InfoItemsPage result) {
 | 
			
		||||
        super.handleNextItems(result);
 | 
			
		||||
        currentNextPageUrl = result.nextPageUrl;
 | 
			
		||||
        infoListAdapter.addInfoItemList(result.infoItemList);
 | 
			
		||||
        currentNextPageUrl = result.getNextPageUrl();
 | 
			
		||||
        infoListAdapter.addInfoItemList(result.getItems());
 | 
			
		||||
 | 
			
		||||
        showListFooter(hasMoreItems());
 | 
			
		||||
    }
 | 
			
		||||
@@ -171,8 +171,8 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
 | 
			
		||||
        setTitle(name);
 | 
			
		||||
 | 
			
		||||
        if (infoListAdapter.getItemsList().size() == 0) {
 | 
			
		||||
            if (result.related_streams.size() > 0) {
 | 
			
		||||
                infoListAdapter.addInfoItemList(result.related_streams);
 | 
			
		||||
            if (result.getRelatedItems().size() > 0) {
 | 
			
		||||
                infoListAdapter.addInfoItemList(result.getRelatedItems());
 | 
			
		||||
                showListFooter(hasMoreItems());
 | 
			
		||||
            } else {
 | 
			
		||||
                infoListAdapter.clearStreamItemList();
 | 
			
		||||
 
 | 
			
		||||
@@ -27,10 +27,13 @@ import com.jakewharton.rxbinding2.view.RxView;
 | 
			
		||||
 | 
			
		||||
import org.schabi.newpipe.R;
 | 
			
		||||
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
 | 
			
		||||
import org.schabi.newpipe.extractor.InfoItem;
 | 
			
		||||
import org.schabi.newpipe.extractor.ListExtractor;
 | 
			
		||||
import org.schabi.newpipe.extractor.NewPipe;
 | 
			
		||||
import org.schabi.newpipe.extractor.channel.ChannelInfo;
 | 
			
		||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
 | 
			
		||||
import org.schabi.newpipe.extractor.stream.Stream;
 | 
			
		||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
 | 
			
		||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
 | 
			
		||||
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
 | 
			
		||||
import org.schabi.newpipe.info_list.InfoItemDialog;
 | 
			
		||||
@@ -44,6 +47,7 @@ import org.schabi.newpipe.util.ExtractorHelper;
 | 
			
		||||
import org.schabi.newpipe.util.Localization;
 | 
			
		||||
import org.schabi.newpipe.util.NavigationHelper;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
@@ -388,7 +392,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
 | 
			
		||||
    //////////////////////////////////////////////////////////////////////////*/
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected Single<ListExtractor.InfoItemPage> loadMoreItemsLogic() {
 | 
			
		||||
    protected Single<ListExtractor.InfoItemsPage> loadMoreItemsLogic() {
 | 
			
		||||
        return ExtractorHelper.getMoreChannelItems(serviceId, url, currentNextPageUrl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -415,8 +419,8 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
 | 
			
		||||
        super.handleResult(result);
 | 
			
		||||
 | 
			
		||||
        headerRootLayout.setVisibility(View.VISIBLE);
 | 
			
		||||
        imageLoader.displayImage(result.banner_url, headerChannelBanner, DISPLAY_BANNER_OPTIONS);
 | 
			
		||||
        imageLoader.displayImage(result.avatar_url, headerAvatarView, DISPLAY_AVATAR_OPTIONS);
 | 
			
		||||
        imageLoader.displayImage(result.getBannerUrl(), headerChannelBanner, DISPLAY_BANNER_OPTIONS);
 | 
			
		||||
        imageLoader.displayImage(result.getAvatarUrl(), headerAvatarView, DISPLAY_AVATAR_OPTIONS);
 | 
			
		||||
 | 
			
		||||
        if (result.getSubscriberCount() != -1) {
 | 
			
		||||
            headerSubscribersTextView.setText(Localization.localizeSubscribersCount(activity, result.getSubscriberCount()));
 | 
			
		||||
@@ -427,8 +431,8 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
 | 
			
		||||
 | 
			
		||||
        playlistCtrl.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
        if (!result.errors.isEmpty()) {
 | 
			
		||||
            showSnackBarError(result.errors, UserAction.REQUESTED_CHANNEL, NewPipe.getNameOfService(result.getServiceId()), result.getUrl(), 0);
 | 
			
		||||
        if (!result.getErrors().isEmpty()) {
 | 
			
		||||
            showSnackBarError(result.getErrors(), UserAction.REQUESTED_CHANNEL, NewPipe.getNameOfService(result.getServiceId()), result.getUrl(), 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (disposables != null) disposables.clear();
 | 
			
		||||
@@ -436,24 +440,12 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
 | 
			
		||||
        updateSubscription(result);
 | 
			
		||||
        monitorSubscription(result);
 | 
			
		||||
 | 
			
		||||
        headerPlayAllButton.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                NavigationHelper.playOnMainPlayer(activity, getPlayQueue());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        headerPopupButton.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                NavigationHelper.playOnPopupPlayer(activity, getPlayQueue());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        headerBackgroundButton.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue());
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        headerPlayAllButton.setOnClickListener(
 | 
			
		||||
                view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue()));
 | 
			
		||||
        headerPopupButton.setOnClickListener(
 | 
			
		||||
                view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue()));
 | 
			
		||||
        headerBackgroundButton.setOnClickListener(
 | 
			
		||||
                view -> NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private PlayQueue getPlayQueue() {
 | 
			
		||||
@@ -461,17 +453,23 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private PlayQueue getPlayQueue(final int index) {
 | 
			
		||||
        final List<StreamInfoItem> streamItems = new ArrayList<>();
 | 
			
		||||
        for(InfoItem i : infoListAdapter.getItemsList()) {
 | 
			
		||||
            if(i instanceof StreamInfoItem) {
 | 
			
		||||
                streamItems.add((StreamInfoItem) i);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return new ChannelPlayQueue(
 | 
			
		||||
                currentInfo.getServiceId(),
 | 
			
		||||
                currentInfo.getUrl(),
 | 
			
		||||
                currentInfo.getNextPageUrl(),
 | 
			
		||||
                infoListAdapter.getItemsList(),
 | 
			
		||||
                streamItems,
 | 
			
		||||
                index
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void handleNextItems(ListExtractor.InfoItemPage result) {
 | 
			
		||||
    public void handleNextItems(ListExtractor.InfoItemsPage result) {
 | 
			
		||||
        super.handleNextItems(result);
 | 
			
		||||
 | 
			
		||||
        if (!result.getErrors().isEmpty()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -297,12 +297,12 @@ public class FeedFragment extends BaseListFragment<List<SubscriptionEntity>, Voi
 | 
			
		||||
            // Called only when response is non-empty
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onSuccess(final ChannelInfo channelInfo) {
 | 
			
		||||
                if (infoListAdapter == null || channelInfo.getRelatedStreams().isEmpty()) {
 | 
			
		||||
                if (infoListAdapter == null || channelInfo.getRelatedItems().isEmpty()) {
 | 
			
		||||
                    onDone();
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                final InfoItem item = channelInfo.getRelatedStreams().get(0);
 | 
			
		||||
                final InfoItem item = channelInfo.getRelatedItems().get(0);
 | 
			
		||||
                // Keep requesting new items if the current one already exists
 | 
			
		||||
                boolean itemExists = doesItemExist(infoListAdapter.getItemsList(), item);
 | 
			
		||||
                if (!itemExists) {
 | 
			
		||||
@@ -411,7 +411,7 @@ public class FeedFragment extends BaseListFragment<List<SubscriptionEntity>, Voi
 | 
			
		||||
 | 
			
		||||
    private boolean doesItemExist(final List<InfoItem> items, final InfoItem item) {
 | 
			
		||||
        for (final InfoItem existingItem : items) {
 | 
			
		||||
            if (existingItem.info_type == item.info_type &&
 | 
			
		||||
            if (existingItem.getInfoType() == item.getInfoType() &&
 | 
			
		||||
                    existingItem.getServiceId() == item.getServiceId() &&
 | 
			
		||||
                    existingItem.getName().equals(item.getName()) &&
 | 
			
		||||
                    existingItem.getUrl().equals(item.getUrl())) return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -141,7 +141,7 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Single<ListExtractor.InfoItemPage> loadMoreItemsLogic() {
 | 
			
		||||
    public Single<ListExtractor.InfoItemsPage> loadMoreItemsLogic() {
 | 
			
		||||
        String contentCountry = PreferenceManager
 | 
			
		||||
                .getDefaultSharedPreferences(activity)
 | 
			
		||||
                .getString(getString(R.string.content_country_key),
 | 
			
		||||
@@ -174,7 +174,7 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void handleNextItems(ListExtractor.InfoItemPage result) {
 | 
			
		||||
    public void handleNextItems(ListExtractor.InfoItemsPage result) {
 | 
			
		||||
        super.handleNextItems(result);
 | 
			
		||||
 | 
			
		||||
        if (!result.getErrors().isEmpty()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -22,10 +22,12 @@ import org.reactivestreams.Subscription;
 | 
			
		||||
import org.schabi.newpipe.NewPipeDatabase;
 | 
			
		||||
import org.schabi.newpipe.R;
 | 
			
		||||
import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity;
 | 
			
		||||
import org.schabi.newpipe.extractor.InfoItem;
 | 
			
		||||
import org.schabi.newpipe.extractor.ListExtractor;
 | 
			
		||||
import org.schabi.newpipe.extractor.NewPipe;
 | 
			
		||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
 | 
			
		||||
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
 | 
			
		||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
 | 
			
		||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
 | 
			
		||||
import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
 | 
			
		||||
import org.schabi.newpipe.fragments.local.RemotePlaylistManager;
 | 
			
		||||
@@ -38,6 +40,7 @@ import org.schabi.newpipe.util.ExtractorHelper;
 | 
			
		||||
import org.schabi.newpipe.util.NavigationHelper;
 | 
			
		||||
import org.schabi.newpipe.util.ThemeHelper;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicBoolean;
 | 
			
		||||
 | 
			
		||||
@@ -206,7 +209,7 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
 | 
			
		||||
    //////////////////////////////////////////////////////////////////////////*/
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected Single<ListExtractor.InfoItemPage> loadMoreItemsLogic() {
 | 
			
		||||
    protected Single<ListExtractor.InfoItemsPage> loadMoreItemsLogic() {
 | 
			
		||||
        return ExtractorHelper.getMorePlaylistItems(serviceId, url, currentNextPageUrl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -269,7 +272,8 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
 | 
			
		||||
        playlistCtrl.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
        imageLoader.displayImage(result.getUploaderAvatarUrl(), headerUploaderAvatar, DISPLAY_AVATAR_OPTIONS);
 | 
			
		||||
        headerStreamCount.setText(getResources().getQuantityString(R.plurals.videos, (int) result.stream_count, (int) result.stream_count));
 | 
			
		||||
        headerStreamCount.setText(getResources().getQuantityString(R.plurals.videos,
 | 
			
		||||
                (int) result.getStreamCount(), (int) result.getStreamCount()));
 | 
			
		||||
 | 
			
		||||
        if (!result.getErrors().isEmpty()) {
 | 
			
		||||
            showSnackBarError(result.getErrors(), UserAction.REQUESTED_PLAYLIST, NewPipe.getNameOfService(result.getServiceId()), result.getUrl(), 0);
 | 
			
		||||
@@ -297,17 +301,23 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private PlayQueue getPlayQueue(final int index) {
 | 
			
		||||
        final List<StreamInfoItem> infoItems = new ArrayList<>();
 | 
			
		||||
        for(InfoItem i : infoListAdapter.getItemsList()) {
 | 
			
		||||
            if(i instanceof StreamInfoItem) {
 | 
			
		||||
                infoItems.add((StreamInfoItem) i);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return new PlaylistPlayQueue(
 | 
			
		||||
                currentInfo.getServiceId(),
 | 
			
		||||
                currentInfo.getUrl(),
 | 
			
		||||
                currentInfo.getNextPageUrl(),
 | 
			
		||||
                infoListAdapter.getItemsList(),
 | 
			
		||||
                infoItems,
 | 
			
		||||
                index
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void handleNextItems(ListExtractor.InfoItemPage result) {
 | 
			
		||||
    public void handleNextItems(ListExtractor.InfoItemsPage result) {
 | 
			
		||||
        super.handleNextItems(result);
 | 
			
		||||
 | 
			
		||||
        if (!result.getErrors().isEmpty()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,9 @@ import io.reactivex.subjects.PublishSubject;
 | 
			
		||||
 | 
			
		||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
 | 
			
		||||
 | 
			
		||||
public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor.InfoItemPage> implements BackPressable {
 | 
			
		||||
public class SearchFragment
 | 
			
		||||
        extends BaseListFragment<SearchResult, ListExtractor.InfoItemsPage>
 | 
			
		||||
        implements BackPressable {
 | 
			
		||||
 | 
			
		||||
    /*//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // Search
 | 
			
		||||
@@ -759,12 +761,7 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
 | 
			
		||||
    public void handleSuggestions(@NonNull final List<SuggestionItem> suggestions) {
 | 
			
		||||
        if (DEBUG) Log.d(TAG, "handleSuggestions() called with: suggestions = [" + suggestions + "]");
 | 
			
		||||
        suggestionsRecyclerView.smoothScrollToPosition(0);
 | 
			
		||||
        suggestionsRecyclerView.post(new Runnable() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                suggestionListAdapter.setItems(suggestions);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        suggestionsRecyclerView.post(() -> suggestionListAdapter.setItems(suggestions));
 | 
			
		||||
 | 
			
		||||
        if (errorPanelRoot.getVisibility() == View.VISIBLE) {
 | 
			
		||||
            hideLoading();
 | 
			
		||||
@@ -822,10 +819,10 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void handleNextItems(ListExtractor.InfoItemPage result) {
 | 
			
		||||
    public void handleNextItems(ListExtractor.InfoItemsPage result) {
 | 
			
		||||
        showListFooter(false);
 | 
			
		||||
        currentPage = Integer.parseInt(result.getNextPageUrl());
 | 
			
		||||
        infoListAdapter.addInfoItemList(result.getNextItemsList());
 | 
			
		||||
        infoListAdapter.addInfoItemList(result.getItems());
 | 
			
		||||
 | 
			
		||||
        if (!result.getErrors().isEmpty()) {
 | 
			
		||||
            showSnackBarError(result.getErrors(), UserAction.SEARCHED, NewPipe.getNameOfService(serviceId)
 | 
			
		||||
 
 | 
			
		||||
@@ -401,12 +401,8 @@ public class SubscriptionFragment extends BaseStateFragment<List<SubscriptionEnt
 | 
			
		||||
        List<InfoItem> items = new ArrayList<>();
 | 
			
		||||
        for (final SubscriptionEntity subscription : subscriptions) items.add(subscription.toChannelInfoItem());
 | 
			
		||||
 | 
			
		||||
        Collections.sort(items, new Comparator<InfoItem>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public int compare(InfoItem o1, InfoItem o2) {
 | 
			
		||||
                return o1.name.compareToIgnoreCase(o2.name);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        Collections.sort(items,
 | 
			
		||||
                (InfoItem o1, InfoItem o2) -> o1.getName().compareToIgnoreCase(o2.getName()));
 | 
			
		||||
        return items;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,7 @@ public class InfoItemBuilder {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public View buildView(@NonNull ViewGroup parent, @NonNull final InfoItem infoItem, boolean useMiniVariant) {
 | 
			
		||||
        InfoItemHolder holder = holderFromInfoType(parent, infoItem.info_type, useMiniVariant);
 | 
			
		||||
        InfoItemHolder holder = holderFromInfoType(parent, infoItem.getInfoType(), useMiniVariant);
 | 
			
		||||
        holder.updateFromItem(infoItem);
 | 
			
		||||
        return holder.itemView;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -203,7 +203,7 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
 | 
			
		||||
            return FOOTER_TYPE;
 | 
			
		||||
        }
 | 
			
		||||
        final InfoItem item = infoItemList.get(position);
 | 
			
		||||
        switch (item.info_type) {
 | 
			
		||||
        switch (item.getInfoType()) {
 | 
			
		||||
            case STREAM:
 | 
			
		||||
                return useMiniVariant ? MINI_STREAM_HOLDER_TYPE : STREAM_HOLDER_TYPE;
 | 
			
		||||
            case CHANNEL:
 | 
			
		||||
 
 | 
			
		||||
@@ -44,15 +44,16 @@ public class ChannelInfoItemHolder extends ChannelMiniInfoItemHolder {
 | 
			
		||||
        if (!(infoItem instanceof ChannelInfoItem)) return;
 | 
			
		||||
        final ChannelInfoItem item = (ChannelInfoItem) infoItem;
 | 
			
		||||
 | 
			
		||||
        itemChannelDescriptionView.setText(item.description);
 | 
			
		||||
        itemChannelDescriptionView.setText(item.getDescription());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected String getDetailLine(final ChannelInfoItem item) {
 | 
			
		||||
        String details = super.getDetailLine(item);
 | 
			
		||||
 | 
			
		||||
        if (item.stream_count >= 0) {
 | 
			
		||||
            String formattedVideoAmount = Localization.localizeStreamCount(itemBuilder.getContext(), item.stream_count);
 | 
			
		||||
        if (item.getStreamCount() >= 0) {
 | 
			
		||||
            String formattedVideoAmount = Localization.localizeStreamCount(itemBuilder.getContext(),
 | 
			
		||||
                    item.getStreamCount());
 | 
			
		||||
 | 
			
		||||
            if (!details.isEmpty()) {
 | 
			
		||||
                details += " • " + formattedVideoAmount;
 | 
			
		||||
 
 | 
			
		||||
@@ -40,22 +40,22 @@ public class ChannelMiniInfoItemHolder extends InfoItemHolder {
 | 
			
		||||
        itemAdditionalDetailView.setText(getDetailLine(item));
 | 
			
		||||
 | 
			
		||||
        itemBuilder.getImageLoader()
 | 
			
		||||
                .displayImage(item.thumbnail_url, itemThumbnailView, ChannelInfoItemHolder.DISPLAY_THUMBNAIL_OPTIONS);
 | 
			
		||||
                .displayImage(item.getThumbnailUrl(),
 | 
			
		||||
                        itemThumbnailView,
 | 
			
		||||
                        ChannelInfoItemHolder.DISPLAY_THUMBNAIL_OPTIONS);
 | 
			
		||||
 | 
			
		||||
        itemView.setOnClickListener(new View.OnClickListener() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onClick(View view) {
 | 
			
		||||
                if (itemBuilder.getOnChannelSelectedListener() != null) {
 | 
			
		||||
                    itemBuilder.getOnChannelSelectedListener().selected(item);
 | 
			
		||||
                }
 | 
			
		||||
        itemView.setOnClickListener(view -> {
 | 
			
		||||
            if (itemBuilder.getOnChannelSelectedListener() != null) {
 | 
			
		||||
                itemBuilder.getOnChannelSelectedListener().selected(item);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected String getDetailLine(final ChannelInfoItem item) {
 | 
			
		||||
        String details = "";
 | 
			
		||||
        if (item.subscriber_count >= 0) {
 | 
			
		||||
            details += Localization.shortSubscriberCount(itemBuilder.getContext(), item.subscriber_count);
 | 
			
		||||
        if (item.getSubscriberCount() >= 0) {
 | 
			
		||||
            details += Localization.shortSubscriberCount(itemBuilder.getContext(),
 | 
			
		||||
                    item.getSubscriberCount());
 | 
			
		||||
        }
 | 
			
		||||
        return details;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ public class PlaylistMiniInfoItemHolder extends InfoItemHolder {
 | 
			
		||||
        itemUploaderView.setText(item.getUploaderName());
 | 
			
		||||
 | 
			
		||||
        itemBuilder.getImageLoader()
 | 
			
		||||
                .displayImage(item.thumbnail_url, itemThumbnailView, DISPLAY_THUMBNAIL_OPTIONS);
 | 
			
		||||
                .displayImage(item.getThumbnailUrl(), itemThumbnailView, DISPLAY_THUMBNAIL_OPTIONS);
 | 
			
		||||
 | 
			
		||||
        itemView.setOnClickListener(view -> {
 | 
			
		||||
            if (itemBuilder.getOnPlaylistSelectedListener() != null) {
 | 
			
		||||
 
 | 
			
		||||
@@ -51,14 +51,14 @@ public class StreamInfoItemHolder extends StreamMiniInfoItemHolder {
 | 
			
		||||
 | 
			
		||||
    private String getStreamInfoDetailLine(final StreamInfoItem infoItem) {
 | 
			
		||||
        String viewsAndDate = "";
 | 
			
		||||
        if (infoItem.view_count >= 0) {
 | 
			
		||||
            viewsAndDate = Localization.shortViewCount(itemBuilder.getContext(), infoItem.view_count);
 | 
			
		||||
        if (infoItem.getViewCount() >= 0) {
 | 
			
		||||
            viewsAndDate = Localization.shortViewCount(itemBuilder.getContext(), infoItem.getViewCount());
 | 
			
		||||
        }
 | 
			
		||||
        if (!TextUtils.isEmpty(infoItem.upload_date)) {
 | 
			
		||||
        if (!TextUtils.isEmpty(infoItem.getUploadDate())) {
 | 
			
		||||
            if (viewsAndDate.isEmpty()) {
 | 
			
		||||
                viewsAndDate = infoItem.upload_date;
 | 
			
		||||
                viewsAndDate = infoItem.getUploadDate();
 | 
			
		||||
            } else {
 | 
			
		||||
                viewsAndDate += " • " + infoItem.upload_date;
 | 
			
		||||
                viewsAndDate += " • " + infoItem.getUploadDate();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return viewsAndDate;
 | 
			
		||||
 
 | 
			
		||||
@@ -41,15 +41,17 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
 | 
			
		||||
        final StreamInfoItem item = (StreamInfoItem) infoItem;
 | 
			
		||||
 | 
			
		||||
        itemVideoTitleView.setText(item.getName());
 | 
			
		||||
        itemUploaderView.setText(item.uploader_name);
 | 
			
		||||
        itemUploaderView.setText(item.getUploaderName());
 | 
			
		||||
 | 
			
		||||
        if (item.duration > 0) {
 | 
			
		||||
            itemDurationView.setText(Localization.getDurationString(item.duration));
 | 
			
		||||
            itemDurationView.setBackgroundColor(ContextCompat.getColor(itemBuilder.getContext(), R.color.duration_background_color));
 | 
			
		||||
        if (item.getDuration() > 0) {
 | 
			
		||||
            itemDurationView.setText(Localization.getDurationString(item.getDuration()));
 | 
			
		||||
            itemDurationView.setBackgroundColor(ContextCompat.getColor(itemBuilder.getContext(),
 | 
			
		||||
                    R.color.duration_background_color));
 | 
			
		||||
            itemDurationView.setVisibility(View.VISIBLE);
 | 
			
		||||
        } else if (item.stream_type == StreamType.LIVE_STREAM) {
 | 
			
		||||
        } else if (item.getStreamType() == StreamType.LIVE_STREAM) {
 | 
			
		||||
            itemDurationView.setText(R.string.duration_live);
 | 
			
		||||
            itemDurationView.setBackgroundColor(ContextCompat.getColor(itemBuilder.getContext(), R.color.live_duration_background_color));
 | 
			
		||||
            itemDurationView.setBackgroundColor(ContextCompat.getColor(itemBuilder.getContext(),
 | 
			
		||||
                    R.color.live_duration_background_color));
 | 
			
		||||
            itemDurationView.setVisibility(View.VISIBLE);
 | 
			
		||||
        } else {
 | 
			
		||||
            itemDurationView.setVisibility(View.GONE);
 | 
			
		||||
@@ -57,7 +59,9 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
 | 
			
		||||
 | 
			
		||||
        // Default thumbnail is shown on error, while loading and if the url is empty
 | 
			
		||||
        itemBuilder.getImageLoader()
 | 
			
		||||
                .displayImage(item.thumbnail_url, itemThumbnailView, StreamInfoItemHolder.DISPLAY_THUMBNAIL_OPTIONS);
 | 
			
		||||
                .displayImage(item.getThumbnailUrl(),
 | 
			
		||||
                        itemThumbnailView,
 | 
			
		||||
                        StreamInfoItemHolder.DISPLAY_THUMBNAIL_OPTIONS);
 | 
			
		||||
 | 
			
		||||
        itemView.setOnClickListener(view -> {
 | 
			
		||||
            if (itemBuilder.getOnStreamSelectedListener() != null) {
 | 
			
		||||
@@ -65,7 +69,7 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        switch (item.stream_type) {
 | 
			
		||||
        switch (item.getStreamType()) {
 | 
			
		||||
            case AUDIO_STREAM:
 | 
			
		||||
            case VIDEO_STREAM:
 | 
			
		||||
            case LIVE_STREAM:
 | 
			
		||||
 
 | 
			
		||||
@@ -407,10 +407,10 @@ public final class BackgroundPlayer extends Service {
 | 
			
		||||
            final MediaSource liveSource = super.sourceOf(item, info);
 | 
			
		||||
            if (liveSource != null) return liveSource;
 | 
			
		||||
 | 
			
		||||
            final int index = ListHelper.getDefaultAudioFormat(context, info.audio_streams);
 | 
			
		||||
            if (index < 0 || index >= info.audio_streams.size()) return null;
 | 
			
		||||
            final int index = ListHelper.getDefaultAudioFormat(context, info.getAudioStreams());
 | 
			
		||||
            if (index < 0 || index >= info.getAudioStreams().size()) return null;
 | 
			
		||||
 | 
			
		||||
            final AudioStream audio = info.audio_streams.get(index);
 | 
			
		||||
            final AudioStream audio = info.getAudioStreams().get(index);
 | 
			
		||||
            return buildMediaSource(audio.getUrl(), PlayerHelper.cacheKeyOf(info, audio),
 | 
			
		||||
                    MediaFormat.getSuffixById(audio.getFormatId()));
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -833,7 +833,7 @@ public abstract class BasePlayer implements
 | 
			
		||||
 | 
			
		||||
            // on metadata changed
 | 
			
		||||
        } else if (currentPlaylistIndex != currentPlayQueueIndex || !isPlaying()) {
 | 
			
		||||
            final long startPos = info != null ? info.start_position : C.TIME_UNSET;
 | 
			
		||||
            final long startPos = info != null ? info.getStartPosition() : C.TIME_UNSET;
 | 
			
		||||
            if (DEBUG) Log.d(TAG, "Rewinding to correct" +
 | 
			
		||||
                    " window=[" + currentPlayQueueIndex + "]," +
 | 
			
		||||
                    " at=[" + getTimeString((int)startPos) + "]," +
 | 
			
		||||
@@ -950,7 +950,7 @@ public abstract class BasePlayer implements
 | 
			
		||||
        /* If current playback has run for PLAY_PREV_ACTIVATION_LIMIT milliseconds, restart current track.
 | 
			
		||||
        * Also restart the track if the current track is the first in a queue.*/
 | 
			
		||||
        if (simpleExoPlayer.getCurrentPosition() > PLAY_PREV_ACTIVATION_LIMIT || playQueue.getIndex() == 0) {
 | 
			
		||||
            final long startPos = currentInfo == null ? 0 : currentInfo.start_position;
 | 
			
		||||
            final long startPos = currentInfo == null ? 0 : currentInfo.getStartPosition();
 | 
			
		||||
            simpleExoPlayer.seekTo(startPos);
 | 
			
		||||
        } else {
 | 
			
		||||
            playQueue.offsetIndex(-1);
 | 
			
		||||
 
 | 
			
		||||
@@ -579,7 +579,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
 | 
			
		||||
    public void onMetadataUpdate(StreamInfo info) {
 | 
			
		||||
        if (info != null) {
 | 
			
		||||
            metadataTitle.setText(info.getName());
 | 
			
		||||
            metadataArtist.setText(info.uploader_name);
 | 
			
		||||
            metadataArtist.setText(info.getUploaderName());
 | 
			
		||||
 | 
			
		||||
            progressEndTime.setVisibility(View.GONE);
 | 
			
		||||
            progressLiveSync.setVisibility(View.GONE);
 | 
			
		||||
 
 | 
			
		||||
@@ -354,10 +354,10 @@ public abstract class VideoPlayer extends BasePlayer
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case VIDEO_STREAM:
 | 
			
		||||
                if (info.video_streams.size() + info.video_only_streams.size() == 0) break;
 | 
			
		||||
                if (info.getVideoStreams().size() + info.getVideoOnlyStreams().size() == 0) break;
 | 
			
		||||
 | 
			
		||||
                final List<VideoStream> videos = ListHelper.getSortedStreamVideosList(context,
 | 
			
		||||
                        info.video_streams, info.video_only_streams, false);
 | 
			
		||||
                        info.getVideoStreams(), info.getVideoOnlyStreams(), false);
 | 
			
		||||
                availableStreams = new ArrayList<>(videos);
 | 
			
		||||
                if (playbackQuality == null) {
 | 
			
		||||
                    selectedStreamIndex = getDefaultResolutionIndex(videos);
 | 
			
		||||
@@ -388,7 +388,7 @@ public abstract class VideoPlayer extends BasePlayer
 | 
			
		||||
 | 
			
		||||
        // Create video stream source
 | 
			
		||||
        final List<VideoStream> videos = ListHelper.getSortedStreamVideosList(context,
 | 
			
		||||
                info.video_streams, info.video_only_streams, false);
 | 
			
		||||
                info.getVideoStreams(), info.getVideoOnlyStreams(), false);
 | 
			
		||||
        final int index;
 | 
			
		||||
        if (videos.isEmpty()) {
 | 
			
		||||
            index = -1;
 | 
			
		||||
 
 | 
			
		||||
@@ -417,9 +417,9 @@ public class MediaSourceManager {
 | 
			
		||||
                final Exception exception = new IllegalStateException(
 | 
			
		||||
                        "Unable to resolve source from stream info." +
 | 
			
		||||
                                " URL: " + stream.getUrl() +
 | 
			
		||||
                                ", audio count: " + streamInfo.audio_streams.size() +
 | 
			
		||||
                                ", video count: " + streamInfo.video_only_streams.size() +
 | 
			
		||||
                                streamInfo.video_streams.size());
 | 
			
		||||
                                ", audio count: " + streamInfo.getAudioStreams().size() +
 | 
			
		||||
                                ", video count: " + streamInfo.getVideoOnlyStreams().size() +
 | 
			
		||||
                                streamInfo.getVideoStreams().size());
 | 
			
		||||
                return new FailedMediaSource(stream, exception);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,13 +26,13 @@ abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> ext
 | 
			
		||||
    transient Disposable fetchReactor;
 | 
			
		||||
 | 
			
		||||
    AbstractInfoPlayQueue(final U item) {
 | 
			
		||||
        this(item.getServiceId(), item.getUrl(), null, Collections.<InfoItem>emptyList(), 0);
 | 
			
		||||
        this(item.getServiceId(), item.getUrl(), null, Collections.<StreamInfoItem>emptyList(), 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    AbstractInfoPlayQueue(final int serviceId,
 | 
			
		||||
                          final String url,
 | 
			
		||||
                          final String nextPageUrl,
 | 
			
		||||
                          final List<InfoItem> streams,
 | 
			
		||||
                          final List<StreamInfoItem> streams,
 | 
			
		||||
                          final int index) {
 | 
			
		||||
        super(index, extractListItems(streams));
 | 
			
		||||
 | 
			
		||||
@@ -65,10 +65,10 @@ abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> ext
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onSuccess(@NonNull T result) {
 | 
			
		||||
                isInitial = false;
 | 
			
		||||
                if (!result.has_more_streams) isComplete = true;
 | 
			
		||||
                nextUrl = result.next_streams_url;
 | 
			
		||||
                if (!result.hasNextPage()) isComplete = true;
 | 
			
		||||
                nextUrl = result.getNextPageUrl();
 | 
			
		||||
 | 
			
		||||
                append(extractListItems(result.related_streams));
 | 
			
		||||
                append(extractListItems(result.getRelatedItems()));
 | 
			
		||||
 | 
			
		||||
                fetchReactor.dispose();
 | 
			
		||||
                fetchReactor = null;
 | 
			
		||||
@@ -83,8 +83,8 @@ abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> ext
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SingleObserver<ListExtractor.InfoItemPage> getNextPageObserver() {
 | 
			
		||||
        return new SingleObserver<ListExtractor.InfoItemPage>() {
 | 
			
		||||
    SingleObserver<ListExtractor.InfoItemsPage> getNextPageObserver() {
 | 
			
		||||
        return new SingleObserver<ListExtractor.InfoItemsPage>() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onSubscribe(@NonNull Disposable d) {
 | 
			
		||||
                if (isComplete || isInitial || (fetchReactor != null && !fetchReactor.isDisposed())) {
 | 
			
		||||
@@ -95,11 +95,11 @@ abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> ext
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onSuccess(@NonNull ListExtractor.InfoItemPage result) {
 | 
			
		||||
            public void onSuccess(@NonNull ListExtractor.InfoItemsPage result) {
 | 
			
		||||
                if (!result.hasNextPage()) isComplete = true;
 | 
			
		||||
                nextUrl = result.nextPageUrl;
 | 
			
		||||
                nextUrl = result.getNextPageUrl();
 | 
			
		||||
 | 
			
		||||
                append(extractListItems(result.infoItemList));
 | 
			
		||||
                append(extractListItems(result.getItems()));
 | 
			
		||||
 | 
			
		||||
                fetchReactor.dispose();
 | 
			
		||||
                fetchReactor = null;
 | 
			
		||||
@@ -121,7 +121,7 @@ abstract class AbstractInfoPlayQueue<T extends ListInfo, U extends InfoItem> ext
 | 
			
		||||
        fetchReactor = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static List<PlayQueueItem> extractListItems(final List<InfoItem> infos) {
 | 
			
		||||
    private static List<PlayQueueItem> extractListItems(final List<StreamInfoItem> infos) {
 | 
			
		||||
        List<PlayQueueItem> result = new ArrayList<>();
 | 
			
		||||
        for (final InfoItem stream : infos) {
 | 
			
		||||
            if (stream instanceof StreamInfoItem) {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package org.schabi.newpipe.playlist;
 | 
			
		||||
import org.schabi.newpipe.extractor.InfoItem;
 | 
			
		||||
import org.schabi.newpipe.extractor.channel.ChannelInfo;
 | 
			
		||||
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
 | 
			
		||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
 | 
			
		||||
import org.schabi.newpipe.util.ExtractorHelper;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@@ -16,13 +17,13 @@ public final class ChannelPlayQueue extends AbstractInfoPlayQueue<ChannelInfo, C
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ChannelPlayQueue(final ChannelInfo info) {
 | 
			
		||||
        this(info.getServiceId(), info.getUrl(), info.getNextPageUrl(), info.getRelatedStreams(), 0);
 | 
			
		||||
        this(info.getServiceId(), info.getUrl(), info.getNextPageUrl(), info.getRelatedItems(), 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ChannelPlayQueue(final int serviceId,
 | 
			
		||||
                            final String url,
 | 
			
		||||
                            final String nextPageUrl,
 | 
			
		||||
                            final List<InfoItem> streams,
 | 
			
		||||
                            final List<StreamInfoItem> streams,
 | 
			
		||||
                            final int index) {
 | 
			
		||||
        super(serviceId, url, nextPageUrl, streams, index);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package org.schabi.newpipe.playlist;
 | 
			
		||||
import org.schabi.newpipe.extractor.InfoItem;
 | 
			
		||||
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
 | 
			
		||||
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
 | 
			
		||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
 | 
			
		||||
import org.schabi.newpipe.util.ExtractorHelper;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@@ -16,13 +17,13 @@ public final class PlaylistPlayQueue extends AbstractInfoPlayQueue<PlaylistInfo,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PlaylistPlayQueue(final PlaylistInfo info) {
 | 
			
		||||
        this(info.getServiceId(), info.getUrl(), info.getNextPageUrl(), info.getRelatedStreams(), 0);
 | 
			
		||||
        this(info.getServiceId(), info.getUrl(), info.getNextPageUrl(), info.getRelatedItems(), 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PlaylistPlayQueue(final int serviceId,
 | 
			
		||||
                             final String url,
 | 
			
		||||
                             final String nextPageUrl,
 | 
			
		||||
                             final List<InfoItem> streams,
 | 
			
		||||
                             final List<StreamInfoItem> streams,
 | 
			
		||||
                             final int index) {
 | 
			
		||||
        super(serviceId, url, nextPageUrl, streams, index);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ import org.schabi.newpipe.MainActivity;
 | 
			
		||||
import org.schabi.newpipe.R;
 | 
			
		||||
import org.schabi.newpipe.ReCaptchaActivity;
 | 
			
		||||
import org.schabi.newpipe.extractor.Info;
 | 
			
		||||
import org.schabi.newpipe.extractor.ListExtractor.InfoItemPage;
 | 
			
		||||
import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage;
 | 
			
		||||
import org.schabi.newpipe.extractor.NewPipe;
 | 
			
		||||
import org.schabi.newpipe.extractor.channel.ChannelInfo;
 | 
			
		||||
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
 | 
			
		||||
@@ -78,7 +78,7 @@ public final class ExtractorHelper {
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Single<InfoItemPage> getMoreSearchItems(final int serviceId,
 | 
			
		||||
    public static Single<InfoItemsPage> getMoreSearchItems(final int serviceId,
 | 
			
		||||
                                                             final String query,
 | 
			
		||||
                                                             final int nextPageNumber,
 | 
			
		||||
                                                             final String searchLanguage,
 | 
			
		||||
@@ -86,7 +86,7 @@ public final class ExtractorHelper {
 | 
			
		||||
        checkServiceId(serviceId);
 | 
			
		||||
        return searchFor(serviceId, query, nextPageNumber, searchLanguage, filter)
 | 
			
		||||
                .map((@NonNull SearchResult searchResult) ->
 | 
			
		||||
                        new InfoItemPage(searchResult.resultList,
 | 
			
		||||
                        new InfoItemsPage(searchResult.resultList,
 | 
			
		||||
                                nextPageNumber + "",
 | 
			
		||||
                                searchResult.errors));
 | 
			
		||||
    }
 | 
			
		||||
@@ -117,7 +117,7 @@ public final class ExtractorHelper {
 | 
			
		||||
                ChannelInfo.getInfo(NewPipe.getService(serviceId), url)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Single<InfoItemPage> getMoreChannelItems(final int serviceId,
 | 
			
		||||
    public static Single<InfoItemsPage> getMoreChannelItems(final int serviceId,
 | 
			
		||||
                                                              final String url,
 | 
			
		||||
                                                              final String nextStreamsUrl) {
 | 
			
		||||
        checkServiceId(serviceId);
 | 
			
		||||
@@ -133,7 +133,7 @@ public final class ExtractorHelper {
 | 
			
		||||
                PlaylistInfo.getInfo(NewPipe.getService(serviceId), url)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Single<InfoItemPage> getMorePlaylistItems(final int serviceId,
 | 
			
		||||
    public static Single<InfoItemsPage> getMorePlaylistItems(final int serviceId,
 | 
			
		||||
                                                               final String url,
 | 
			
		||||
                                                               final String nextStreamsUrl) {
 | 
			
		||||
        checkServiceId(serviceId);
 | 
			
		||||
@@ -149,7 +149,7 @@ public final class ExtractorHelper {
 | 
			
		||||
                KioskInfo.getInfo(NewPipe.getService(serviceId), url, contentCountry)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Single<InfoItemPage> getMoreKioskItems(final int serviceId,
 | 
			
		||||
    public static Single<InfoItemsPage> getMoreKioskItems(final int serviceId,
 | 
			
		||||
                                                            final String url,
 | 
			
		||||
                                                            final String nextStreamsUrl,
 | 
			
		||||
                                                            final String contentCountry) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user