diff --git a/app/src/main/java/org/schabi/newpipe/ChannelActivity.java b/app/src/main/java/org/schabi/newpipe/ChannelActivity.java index e64605218..c2adea454 100644 --- a/app/src/main/java/org/schabi/newpipe/ChannelActivity.java +++ b/app/src/main/java/org/schabi/newpipe/ChannelActivity.java @@ -92,7 +92,8 @@ public class ChannelActivity extends AppCompatActivity { final LinearLayoutManager layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(infoListAdapter); - infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() { + infoListAdapter.setOnStreamItemSelectedListener( + new InfoItemBuilder.OnInfoItemSelectedListener() { @Override public void selected(String url) { Intent detailIntent = new Intent(ChannelActivity.this, VideoItemDetailActivity.class); @@ -172,7 +173,7 @@ public class ChannelActivity extends AppCompatActivity { } private void addVideos(final ChannelInfo info) { - infoListAdapter.addStreamItemList(info.related_streams); + infoListAdapter.addInfoItemList(info.related_streams); } private void postNewErrorToast(Handler h, final int stringResource) { diff --git a/app/src/main/java/org/schabi/newpipe/extractor/InfoItemCollector.java b/app/src/main/java/org/schabi/newpipe/extractor/InfoItemCollector.java index 1667e55dd..d3b0927a1 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/InfoItemCollector.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/InfoItemCollector.java @@ -28,11 +28,9 @@ import java.util.Vector; public class InfoItemCollector { private List itemList = new Vector<>(); private List errors = new Vector<>(); - private UrlIdHandler urlIdHandler; private int serviceId = -1; - public InfoItemCollector(UrlIdHandler handler, int serviceId) { - urlIdHandler = handler; + public InfoItemCollector(int serviceId) { this.serviceId = serviceId; } @@ -60,7 +58,4 @@ public class InfoItemCollector { protected int getServiceId() { return serviceId; } - protected UrlIdHandler getUrlIdHandler() { - return urlIdHandler; - } } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItem.java b/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItem.java index e598c659f..cb3f91a0f 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItem.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItem.java @@ -24,14 +24,18 @@ import org.schabi.newpipe.extractor.InfoItem; public class ChannelInfoItem implements InfoItem { + public int serviceId = -1; + public String channelName = ""; + public String webPageUrl = ""; + public int subscriberCount = -1; + public int videoAmount = -1; + public InfoType infoType() { return InfoType.CHANNEL; } - public String getTitle() { return ""; } - public String getLink() { return ""; } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItemCollector.java b/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItemCollector.java new file mode 100644 index 000000000..cf18e81af --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItemCollector.java @@ -0,0 +1,61 @@ +package org.schabi.newpipe.extractor.channel; + +import org.schabi.newpipe.extractor.InfoItemCollector; +import org.schabi.newpipe.extractor.NewPipe; +import org.schabi.newpipe.extractor.exceptions.FoundAdException; +import org.schabi.newpipe.extractor.exceptions.ParsingException; +import org.schabi.newpipe.extractor.stream_info.StreamInfoItem; +import org.schabi.newpipe.extractor.stream_info.StreamInfoItemExtractor; + +/** + * Created by Christian Schabesberger on 12.02.17. + * + * Copyright (C) Christian Schabesberger 2017 + * ChannelInfoItemCollector.java is part of NewPipe. + * + * NewPipe is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * NewPipe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NewPipe. If not, see . + */ + +public class ChannelInfoItemCollector extends InfoItemCollector { + public ChannelInfoItemCollector(int serviceId) { + super(serviceId); + } + + public void commit(ChannelInfoItemExtractor extractor) throws ParsingException { + try { + ChannelInfoItem resultItem = new ChannelInfoItem(); + // importand information + resultItem.channelName = extractor.getChannelName(); + + resultItem.serviceId = getServiceId(); + resultItem.webPageUrl = extractor.getWebPageUrl(); + + // optional information + try { + resultItem.subscriberCount = extractor.getSubscriberCount(); + } catch (Exception e) { + addError(e); + } + try { + resultItem.videoAmount = extractor.getVideoAmount(); + } catch (Exception e) { + addError(e); + } + + addItem(resultItem); + } catch (Exception e) { + addError(e); + } + } +} diff --git a/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItemExtractor.java b/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItemExtractor.java new file mode 100644 index 000000000..12608d2ca --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/extractor/channel/ChannelInfoItemExtractor.java @@ -0,0 +1,30 @@ +package org.schabi.newpipe.extractor.channel; + +import org.schabi.newpipe.extractor.exceptions.ParsingException; + +/** + * Created by Christian Schabesberger on 12.02.17. + * + * Copyright (C) Christian Schabesberger 2017 + * ChannelInfoItemExtractor.java is part of NewPipe. + * + * NewPipe is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * NewPipe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NewPipe. If not, see . + */ + +public interface ChannelInfoItemExtractor { + String getChannelName() throws ParsingException; + String getWebPageUrl() throws ParsingException; + int getSubscriberCount() throws ParsingException; + int getVideoAmount() throws ParsingException; +} diff --git a/app/src/main/java/org/schabi/newpipe/extractor/search/InfoItemSearchCollector.java b/app/src/main/java/org/schabi/newpipe/extractor/search/InfoItemSearchCollector.java index 533331719..01d4f655f 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/search/InfoItemSearchCollector.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/search/InfoItemSearchCollector.java @@ -2,6 +2,8 @@ package org.schabi.newpipe.extractor.search; import org.schabi.newpipe.extractor.InfoItemCollector; import org.schabi.newpipe.extractor.UrlIdHandler; +import org.schabi.newpipe.extractor.channel.ChannelInfoItemCollector; +import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector; @@ -30,10 +32,12 @@ import org.schabi.newpipe.extractor.stream_info.StreamInfoItemExtractor; public class InfoItemSearchCollector extends InfoItemCollector { private String suggestion = ""; private StreamInfoItemCollector streamCollector; + private ChannelInfoItemCollector channelCollector; InfoItemSearchCollector(UrlIdHandler handler, int serviceId) { - super(handler, serviceId); + super(serviceId); streamCollector = new StreamInfoItemCollector(handler, serviceId); + channelCollector = new ChannelInfoItemCollector(serviceId); } public void setSuggestion(String suggestion) { @@ -43,6 +47,7 @@ public class InfoItemSearchCollector extends InfoItemCollector { public SearchResult getSearchResult() throws ExtractionException { SearchResult result = new SearchResult(); + addFromCollector(channelCollector); addFromCollector(streamCollector); result.suggestion = suggestion; @@ -54,4 +59,8 @@ public class InfoItemSearchCollector extends InfoItemCollector { public void commit(StreamInfoItemExtractor extractor) throws ParsingException { streamCollector.commit(extractor); } + + public void commit(ChannelInfoItemExtractor extractor) throws ParsingException { + channelCollector.commit(extractor); + } } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/search/SearchEngine.java b/app/src/main/java/org/schabi/newpipe/extractor/search/SearchEngine.java index ce7e6e061..76221528e 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/search/SearchEngine.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/search/SearchEngine.java @@ -5,6 +5,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector; import java.io.IOException; +import java.util.EnumSet; /** * Created by Christian Schabesberger on 10.08.15. @@ -27,6 +28,10 @@ import java.io.IOException; */ public abstract class SearchEngine { + public enum Filter { + VIDEO, CHANNEL, PLAY_LIST + } + public static class NothingFoundException extends ExtractionException { public NothingFoundException(String message) { super(message); @@ -43,6 +48,6 @@ public abstract class SearchEngine { } //Result search(String query, int page); public abstract InfoItemSearchCollector search( - String query, int page, String contentCountry) + String query, int page, String contentCountry, EnumSet filter) throws ExtractionException, IOException; } diff --git a/app/src/main/java/org/schabi/newpipe/extractor/search/SearchResult.java b/app/src/main/java/org/schabi/newpipe/extractor/search/SearchResult.java index a3ef1fbcd..e81dc8803 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/search/SearchResult.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/search/SearchResult.java @@ -5,6 +5,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.stream_info.StreamInfoItem; import java.io.IOException; +import java.util.EnumSet; import java.util.List; import java.util.Vector; @@ -30,10 +31,12 @@ import java.util.Vector; public class SearchResult { public static SearchResult getSearchResult(SearchEngine engine, String query, - int page, String languageCode) + int page, String languageCode, EnumSet filter) throws ExtractionException, IOException { - SearchResult result = engine.search(query, page, languageCode).getSearchResult(); + SearchResult result = engine + .search(query, page, languageCode, filter) + .getSearchResult(); if(result.resultList.isEmpty()) { if(result.suggestion.isEmpty()) { throw new ExtractionException("Empty result despite no error"); diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelInfoItemExtractor.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelInfoItemExtractor.java new file mode 100644 index 000000000..51f31da6a --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelInfoItemExtractor.java @@ -0,0 +1,49 @@ +package org.schabi.newpipe.extractor.services.youtube; + +import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor; +import org.schabi.newpipe.extractor.exceptions.ParsingException; +import org.jsoup.nodes.Element; + +/** + * Created by Christian Schabesberger on 12.02.17. + * + * Copyright (C) Christian Schabesberger 2017 + * YoutubeChannelInfoItemExtractor.java is part of NewPipe. + * + * NewPipe is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * NewPipe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NewPipe. If not, see . + */ + +public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor { + private Element el; + + public YoutubeChannelInfoItemExtractor(Element el) { + this.el = el; + } + + public String getChannelName() throws ParsingException { + return ""; + } + + public String getWebPageUrl() throws ParsingException { + return ""; + } + + public int getSubscriberCount() throws ParsingException { + return 0; + } + + public int getVideoAmount() throws ParsingException { + return 0; + } +} diff --git a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java index 2b738204c..bcc94f01b 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeSearchEngine.java @@ -9,11 +9,10 @@ import org.schabi.newpipe.extractor.UrlIdHandler; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.search.InfoItemSearchCollector; import org.schabi.newpipe.extractor.search.SearchEngine; -import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector; -import org.schabi.newpipe.extractor.stream_info.StreamInfoItemExtractor; import java.net.URLEncoder; import java.io.IOException; +import java.util.EnumSet; /** @@ -46,7 +45,10 @@ public class YoutubeSearchEngine extends SearchEngine { } @Override - public InfoItemSearchCollector search(String query, int page, String languageCode) + public InfoItemSearchCollector search(String query, + int page, + String languageCode, + EnumSet filter) throws IOException, ExtractionException { InfoItemSearchCollector collector = getInfoItemSearchCollector(); @@ -54,9 +56,13 @@ public class YoutubeSearchEngine extends SearchEngine { Downloader downloader = NewPipe.getDownloader(); String url = "https://www.youtube.com/results" - + "?search_query=" + URLEncoder.encode(query, CHARSET_UTF_8) - + "&page=" + Integer.toString(page + 1) - + "&filters=" + "video"; + + "?q=" + URLEncoder.encode(query, CHARSET_UTF_8) + + "&page=" + Integer.toString(page + 1); + if(filter.contains(Filter.VIDEO) && !filter.contains(Filter.CHANNEL)) { + url += "&sp=EgIQAQ%253D%253D"; + } else if(!filter.contains(Filter.VIDEO) && filter.contains(Filter.CHANNEL)) { + url += "&sp=EgIQAg%253D%253D"; + } String site; //String url = builder.build().toString(); @@ -94,12 +100,13 @@ public class YoutubeSearchEngine extends SearchEngine { } // search message item } else if ((el = item.select("div[class*=\"search-message\"]").first()) != null) { - //result.errorMessage = el.text(); throw new NothingFoundException(el.text()); // video item type - } else if ((el = item.select("div[class*=\"yt-lockup-video\"").first()) != null) { + } else if ((el = item.select("div[class*=\"yt-lockup-video\"]").first()) != null) { collector.commit(new YoutubeStreamInfoItemExtractor(el)); + } else if((el = item.select("div[class*=\"yt-lockup-channel\"]").first()) != null) { + collector.commit(new YoutubeChannelInfoItemExtractor(el)); } else { //noinspection ConstantConditions throw new ExtractionException("unexpected element found:\"" + el + "\""); diff --git a/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java b/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java index 67db27e8a..1fc44df50 100644 --- a/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java +++ b/app/src/main/java/org/schabi/newpipe/extractor/stream_info/StreamInfoItemCollector.java @@ -31,8 +31,15 @@ import java.util.Vector; public class StreamInfoItemCollector extends InfoItemCollector { + private UrlIdHandler urlIdHandler; + public StreamInfoItemCollector(UrlIdHandler handler, int serviceId) { - super(handler, serviceId); + super(serviceId); + urlIdHandler = handler; + } + + private UrlIdHandler getUrlIdHandler() { + return urlIdHandler; } public void commit(StreamInfoItemExtractor extractor) throws ParsingException { diff --git a/app/src/main/java/org/schabi/newpipe/info_list/ChannelInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/ChannelInfoItemHolder.java new file mode 100644 index 000000000..50f4e3b24 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/info_list/ChannelInfoItemHolder.java @@ -0,0 +1,48 @@ +package org.schabi.newpipe.info_list; + +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.extractor.InfoItem; + +import de.hdodenhof.circleimageview.CircleImageView; + +/** + * Created by Christian Schabesberger on 12.02.17. + * + * Copyright (C) Christian Schabesberger 2016 + * ChannelInfoItemHolder .java is part of NewPipe. + * + * NewPipe is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * NewPipe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NewPipe. If not, see . + */ + +public class ChannelInfoItemHolder extends InfoItemHolder { + public final CircleImageView itemThumbnailView; + public final TextView itemChannelTitleView; + public final Button itemButton; + + ChannelInfoItemHolder(View v) { + super(v); + itemThumbnailView = (CircleImageView) v.findViewById(R.id.itemThumbnailView); + itemChannelTitleView = (TextView) v.findViewById(R.id.itemChannelTitleView); + itemButton = (Button) v.findViewById(R.id.item_button); + } + + @Override + public InfoItem.InfoType infoType() { + return InfoItem.InfoType.CHANNEL; + } +} diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java index dd33d4caa..901f59fa6 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java @@ -5,6 +5,7 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; @@ -13,6 +14,7 @@ import org.schabi.newpipe.ImageErrorLoadingListener; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.AbstractStreamInfo; import org.schabi.newpipe.extractor.InfoItem; +import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.extractor.stream_info.StreamInfoItem; /** @@ -37,7 +39,8 @@ import org.schabi.newpipe.extractor.stream_info.StreamInfoItem; public class InfoItemBuilder { - public interface OnItemSelectedListener { + private static final String TAG = InfoItemBuilder.class.toString(); + public interface OnInfoItemSelectedListener { void selected(String url); } @@ -46,19 +49,64 @@ public class InfoItemBuilder { private ImageLoader imageLoader = ImageLoader.getInstance(); private DisplayImageOptions displayImageOptions = new DisplayImageOptions.Builder().cacheInMemory(true).build(); - private OnItemSelectedListener onItemSelectedListener; + private OnInfoItemSelectedListener onStreamInfoItemSelectedListener; + private OnInfoItemSelectedListener onChannelInfoItemSelectedListener; public InfoItemBuilder(Activity a, View rootView) { activity = a; this.rootView = rootView; } - public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) { - this.onItemSelectedListener = onItemSelectedListener; + public void setOnStreamInfoItemSelectedListener( + OnInfoItemSelectedListener listener) { + this.onStreamInfoItemSelectedListener = listener; + } + + public void setOnChannelInfoItemSelectedListener( + OnInfoItemSelectedListener listener) { + this.onChannelInfoItemSelectedListener = listener; } public void buildByHolder(InfoItemHolder holder, final InfoItem i) { - final StreamInfoItem info = (StreamInfoItem) i; + switch(i.infoType()) { + case STREAM: + buildStreamInfoItem((StreamInfoItemHolder) holder, (StreamInfoItem) i); + break; + case CHANNEL: + buildChannelInfoItem((ChannelInfoItemHolder) holder, (ChannelInfoItem) i); + break; + case PLAYLIST: + Log.e(TAG, "Not yet implemented"); + break; + default: + Log.e(TAG, "Trollolo"); + } + } + + public View buildView(ViewGroup parent, final InfoItem info) { + View itemView = null; + InfoItemHolder holder = null; + switch(info.infoType()) { + case STREAM: + itemView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.stream_item, parent, false); + holder = new StreamInfoItemHolder(itemView); + break; + case CHANNEL: + itemView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.channel_item, parent, false); + holder = new ChannelInfoItemHolder(itemView); + break; + case PLAYLIST: + Log.e(TAG, "Not yet implemented"); + default: + Log.e(TAG, "Trollolo"); + } + buildByHolder(holder, info); + return itemView; + } + + private void buildStreamInfoItem(StreamInfoItemHolder holder, final StreamInfoItem info) { if(info.infoType() != InfoItem.InfoType.STREAM) { Log.e("InfoItemBuilder", "Info type not yet supported"); } @@ -98,20 +146,23 @@ public class InfoItemBuilder { holder.itemButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - onItemSelectedListener.selected(info.webpage_url); + onStreamInfoItemSelectedListener.selected(info.webpage_url); } }); } - public View buildView(ViewGroup parent, final InfoItem info) { - View streamPreviewView = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.video_item, parent, false); - InfoItemHolder holder = new InfoItemHolder(streamPreviewView); - buildByHolder(holder, info); - return streamPreviewView; + private void buildChannelInfoItem(ChannelInfoItemHolder holder, final ChannelInfoItem info) { + holder.itemChannelTitleView.setText(info.getTitle()); + holder.itemButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + onChannelInfoItemSelectedListener.selected(info.getLink()); + } + }); } + public static String shortViewCount(Long viewCount){ if(viewCount >= 1000000000){ return Long.toString(viewCount/1000000000)+"B views"; diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemHolder.java index 690376465..c1fab069b 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemHolder.java @@ -2,14 +2,11 @@ package org.schabi.newpipe.info_list; import android.support.v7.widget.RecyclerView; import android.view.View; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.TextView; -import org.schabi.newpipe.R; +import org.schabi.newpipe.extractor.InfoItem; /** - * Created by Christian Schabesberger on 01.08.16. + * Created by Christian Schabesberger on 12.02.17. * * Copyright (C) Christian Schabesberger 2016 * InfoItemHolder.java is part of NewPipe. @@ -28,25 +25,9 @@ import org.schabi.newpipe.R; * along with NewPipe. If not, see . */ -public class InfoItemHolder extends RecyclerView.ViewHolder { - - public final ImageView itemThumbnailView; - public final TextView itemVideoTitleView, - itemUploaderView, - itemDurationView, - itemUploadDateView, - itemViewCountView; - public final Button itemButton; - +public abstract class InfoItemHolder extends RecyclerView.ViewHolder { public InfoItemHolder(View v) { super(v); - itemThumbnailView = (ImageView) v.findViewById(R.id.itemThumbnailView); - itemVideoTitleView = (TextView) v.findViewById(R.id.itemVideoTitleView); - itemUploaderView = (TextView) v.findViewById(R.id.itemUploaderView); - itemDurationView = (TextView) v.findViewById(R.id.itemDurationView); - itemUploadDateView = (TextView) v.findViewById(R.id.itemUploadDateView); - itemViewCountView = (TextView) v.findViewById(R.id.itemViewCountView); - itemButton = (Button) v.findViewById(R.id.item_button); } - + public abstract InfoItem.InfoType infoType(); } diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java index 0daf211e5..5804fecd5 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java @@ -2,13 +2,13 @@ package org.schabi.newpipe.info_list; import android.app.Activity; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.InfoItem; -import org.schabi.newpipe.extractor.stream_info.StreamInfoItem; import java.util.List; import java.util.Vector; @@ -34,47 +34,58 @@ import java.util.Vector; */ public class InfoListAdapter extends RecyclerView.Adapter { + private static final String TAG = InfoListAdapter.class.toString(); private final InfoItemBuilder infoItemBuilder; - private final List streamList; + private final List infoItemList; public InfoListAdapter(Activity a, View rootView) { infoItemBuilder = new InfoItemBuilder(a, rootView); - streamList = new Vector<>(); + infoItemList = new Vector<>(); } - public void setOnItemSelectedListener - (InfoItemBuilder.OnItemSelectedListener onItemSelectedListener) { - infoItemBuilder.setOnItemSelectedListener(onItemSelectedListener); + public void setOnStreamItemSelectedListener + (InfoItemBuilder.OnInfoItemSelectedListener onItemSelectedListener) { + infoItemBuilder.setOnStreamInfoItemSelectedListener(onItemSelectedListener); } - public void addStreamItemList(List videos) { + public void addInfoItemList(List videos) { if(videos!= null) { - streamList.addAll(videos); + infoItemList.addAll(videos); notifyDataSetChanged(); } } public void clearSteamItemList() { - streamList.clear(); + infoItemList.clear(); notifyDataSetChanged(); } @Override public int getItemCount() { - return streamList.size(); + return infoItemList.size(); } @Override public InfoItemHolder onCreateViewHolder(ViewGroup parent, int i) { - View itemView = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.video_item, parent, false); - - return new InfoItemHolder(itemView); + switch(infoItemList.get(i).infoType()) { + case STREAM: + return new StreamInfoItemHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.stream_item, parent, false)); + case CHANNEL: + return new ChannelInfoItemHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.channel_item, parent, false)); + case PLAYLIST: + Log.e(TAG, "Playlist is not yet implemented"); + return null; + default: + Log.e(TAG, "Trollolo"); + return null; + } } @Override public void onBindViewHolder(InfoItemHolder holder, int i) { - infoItemBuilder.buildByHolder(holder, streamList.get(i)); + infoItemBuilder.buildByHolder(holder, infoItemList.get(i)); } } diff --git a/app/src/main/java/org/schabi/newpipe/info_list/StreamInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/StreamInfoItemHolder.java new file mode 100644 index 000000000..81981fd82 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/info_list/StreamInfoItemHolder.java @@ -0,0 +1,58 @@ +package org.schabi.newpipe.info_list; + +import android.icu.text.IDNA; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import org.schabi.newpipe.R; +import org.schabi.newpipe.extractor.InfoItem; + +/** + * Created by Christian Schabesberger on 01.08.16. + * + * Copyright (C) Christian Schabesberger 2016 + * StreamInfoItemHolder.java is part of NewPipe. + * + * NewPipe is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * NewPipe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with NewPipe. If not, see . + */ + +public class StreamInfoItemHolder extends InfoItemHolder { + + public final ImageView itemThumbnailView; + public final TextView itemVideoTitleView, + itemUploaderView, + itemDurationView, + itemUploadDateView, + itemViewCountView; + public final Button itemButton; + + public StreamInfoItemHolder(View v) { + super(v); + itemThumbnailView = (ImageView) v.findViewById(R.id.itemThumbnailView); + itemVideoTitleView = (TextView) v.findViewById(R.id.itemVideoTitleView); + itemUploaderView = (TextView) v.findViewById(R.id.itemUploaderView); + itemDurationView = (TextView) v.findViewById(R.id.itemDurationView); + itemUploadDateView = (TextView) v.findViewById(R.id.itemUploadDateView); + itemViewCountView = (TextView) v.findViewById(R.id.itemViewCountView); + itemButton = (Button) v.findViewById(R.id.item_button); + } + + @Override + public InfoItem.InfoType infoType() { + return InfoItem.InfoType.STREAM; + } +} diff --git a/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java b/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java index 09e7c0903..4e680d21c 100644 --- a/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java +++ b/app/src/main/java/org/schabi/newpipe/search_fragment/SearchInfoItemFragment.java @@ -21,6 +21,7 @@ import android.widget.Toast; import org.schabi.newpipe.ReCaptchaActivity; import org.schabi.newpipe.extractor.NewPipe; +import org.schabi.newpipe.extractor.search.SearchEngine; import org.schabi.newpipe.extractor.search.SearchResult; import org.schabi.newpipe.info_list.InfoItemBuilder; import org.schabi.newpipe.report.ErrorActivity; @@ -29,6 +30,8 @@ import org.schabi.newpipe.detail.VideoItemDetailActivity; import org.schabi.newpipe.detail.VideoItemDetailFragment; import org.schabi.newpipe.info_list.InfoListAdapter; +import java.util.EnumSet; + import static android.app.Activity.RESULT_OK; import static org.schabi.newpipe.ReCaptchaActivity.RECAPTCHA_REQUEST; @@ -166,7 +169,7 @@ public class SearchInfoItemFragment extends Fragment { sw.setSearchWorkerResultListener(new SearchWorker.SearchWorkerResultListener() { @Override public void onResult(SearchResult result) { - infoListAdapter.addStreamItemList(result.resultList); + infoListAdapter.addInfoItemList(result.resultList); setDoneLoading(); } @@ -213,7 +216,8 @@ public class SearchInfoItemFragment extends Fragment { infoListAdapter = new InfoListAdapter(getActivity(), getActivity().findViewById(android.R.id.content)); - infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() { + infoListAdapter.setOnStreamItemSelectedListener( + new InfoItemBuilder.OnInfoItemSelectedListener() { @Override public void selected(String url) { startDetailActivity(url); @@ -298,7 +302,11 @@ public class SearchInfoItemFragment extends Fragment { private void search(String query, int page) { isLoading = true; SearchWorker sw = SearchWorker.getInstance(); - sw.search(streamingServiceId, query, page, getActivity()); + sw.search(streamingServiceId, + query, + page, + getActivity(), + EnumSet.of(SearchEngine.Filter.CHANNEL)); } private void setDoneLoading() { diff --git a/app/src/main/java/org/schabi/newpipe/search_fragment/SearchWorker.java b/app/src/main/java/org/schabi/newpipe/search_fragment/SearchWorker.java index 9b1e8d86e..eafc0b6cf 100644 --- a/app/src/main/java/org/schabi/newpipe/search_fragment/SearchWorker.java +++ b/app/src/main/java/org/schabi/newpipe/search_fragment/SearchWorker.java @@ -16,6 +16,7 @@ import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.NewPipe; import java.io.IOException; +import java.util.EnumSet; /** * Created by Christian Schabesberger on 02.08.16. @@ -67,14 +68,21 @@ public class SearchWorker { public static final String YOUTUBE = "Youtube"; private final String query; private final int page; + private final EnumSet filter; final Handler h = new Handler(); private volatile boolean runs = true; private Activity a = null; private int serviceId = -1; - public SearchRunnable(int serviceId, String query, int page, Activity activity, int requestId) { + public SearchRunnable(int serviceId, + String query, + int page, + EnumSet filter, + Activity activity, + int requestId) { this.serviceId = serviceId; this.query = query; this.page = page; + this.filter = filter; this.a = activity; } void terminate() { @@ -102,7 +110,7 @@ public class SearchWorker { String searchLanguage = sp.getString(searchLanguageKey, a.getString(R.string.default_language_value)); result = SearchResult - .getSearchResult(engine, query, page, searchLanguage); + .getSearchResult(engine, query, page, searchLanguage, filter); if(runs) { h.post(new ResultRunnable(result, requestId)); } @@ -180,11 +188,15 @@ public class SearchWorker { } - public void search(int serviceId, String query, int page, Activity a) { + public void search(int serviceId, + String query, + int page, + Activity a, + EnumSet filter) { if(runnable != null) { terminate(); } - runnable = new SearchRunnable(serviceId, query, page, a, requestId); + runnable = new SearchRunnable(serviceId, query, page, filter, a, requestId); Thread thread = new Thread(runnable); thread.start(); } diff --git a/app/src/main/res/drawable-nodpi/buddy_channel_item.png b/app/src/main/res/drawable-nodpi/buddy_channel_item.png new file mode 100644 index 000000000..d43c2cbd9 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/buddy_channel_item.png differ diff --git a/app/src/main/res/drawable-nodpi/dummi_thumbnail_playlist.png b/app/src/main/res/drawable-nodpi/dummi_thumbnail_playlist.png new file mode 100644 index 000000000..c70e4bf14 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/dummi_thumbnail_playlist.png differ diff --git a/app/src/main/res/layout/channel_item.xml b/app/src/main/res/layout/channel_item.xml new file mode 100644 index 000000000..541cde747 --- /dev/null +++ b/app/src/main/res/layout/channel_item.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +