setup core for search channel support
This commit is contained in:
parent
f29bd0a6e7
commit
91434dd2ac
26 changed files with 930 additions and 80 deletions
|
@ -92,7 +92,8 @@ public class ChannelActivity extends AppCompatActivity {
|
||||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
||||||
recyclerView.setLayoutManager(layoutManager);
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
recyclerView.setAdapter(infoListAdapter);
|
recyclerView.setAdapter(infoListAdapter);
|
||||||
infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
infoListAdapter.setOnStreamItemSelectedListener(
|
||||||
|
new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void selected(String url) {
|
public void selected(String url) {
|
||||||
Intent detailIntent = new Intent(ChannelActivity.this, VideoItemDetailActivity.class);
|
Intent detailIntent = new Intent(ChannelActivity.this, VideoItemDetailActivity.class);
|
||||||
|
@ -172,7 +173,7 @@ public class ChannelActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addVideos(final ChannelInfo info) {
|
private void addVideos(final ChannelInfo info) {
|
||||||
infoListAdapter.addStreamItemList(info.related_streams);
|
infoListAdapter.addInfoItemList(info.related_streams);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postNewErrorToast(Handler h, final int stringResource) {
|
private void postNewErrorToast(Handler h, final int stringResource) {
|
||||||
|
|
|
@ -28,11 +28,9 @@ import java.util.Vector;
|
||||||
public class InfoItemCollector {
|
public class InfoItemCollector {
|
||||||
private List<InfoItem> itemList = new Vector<>();
|
private List<InfoItem> itemList = new Vector<>();
|
||||||
private List<Throwable> errors = new Vector<>();
|
private List<Throwable> errors = new Vector<>();
|
||||||
private UrlIdHandler urlIdHandler;
|
|
||||||
private int serviceId = -1;
|
private int serviceId = -1;
|
||||||
|
|
||||||
public InfoItemCollector(UrlIdHandler handler, int serviceId) {
|
public InfoItemCollector(int serviceId) {
|
||||||
urlIdHandler = handler;
|
|
||||||
this.serviceId = serviceId;
|
this.serviceId = serviceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +58,4 @@ public class InfoItemCollector {
|
||||||
protected int getServiceId() {
|
protected int getServiceId() {
|
||||||
return serviceId;
|
return serviceId;
|
||||||
}
|
}
|
||||||
protected UrlIdHandler getUrlIdHandler() {
|
|
||||||
return urlIdHandler;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,18 @@ import org.schabi.newpipe.extractor.InfoItem;
|
||||||
|
|
||||||
public class ChannelInfoItem implements 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() {
|
public InfoType infoType() {
|
||||||
return InfoType.CHANNEL;
|
return InfoType.CHANNEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLink() {
|
public String getLink() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <chris.schabesberger@mailbox.org>
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <chris.schabesberger@mailbox.org>
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface ChannelInfoItemExtractor {
|
||||||
|
String getChannelName() throws ParsingException;
|
||||||
|
String getWebPageUrl() throws ParsingException;
|
||||||
|
int getSubscriberCount() throws ParsingException;
|
||||||
|
int getVideoAmount() throws ParsingException;
|
||||||
|
}
|
|
@ -2,6 +2,8 @@ package org.schabi.newpipe.extractor.search;
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.InfoItemCollector;
|
import org.schabi.newpipe.extractor.InfoItemCollector;
|
||||||
import org.schabi.newpipe.extractor.UrlIdHandler;
|
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.ExtractionException;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
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 {
|
public class InfoItemSearchCollector extends InfoItemCollector {
|
||||||
private String suggestion = "";
|
private String suggestion = "";
|
||||||
private StreamInfoItemCollector streamCollector;
|
private StreamInfoItemCollector streamCollector;
|
||||||
|
private ChannelInfoItemCollector channelCollector;
|
||||||
|
|
||||||
InfoItemSearchCollector(UrlIdHandler handler, int serviceId) {
|
InfoItemSearchCollector(UrlIdHandler handler, int serviceId) {
|
||||||
super(handler, serviceId);
|
super(serviceId);
|
||||||
streamCollector = new StreamInfoItemCollector(handler, serviceId);
|
streamCollector = new StreamInfoItemCollector(handler, serviceId);
|
||||||
|
channelCollector = new ChannelInfoItemCollector(serviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSuggestion(String suggestion) {
|
public void setSuggestion(String suggestion) {
|
||||||
|
@ -43,6 +47,7 @@ public class InfoItemSearchCollector extends InfoItemCollector {
|
||||||
public SearchResult getSearchResult() throws ExtractionException {
|
public SearchResult getSearchResult() throws ExtractionException {
|
||||||
SearchResult result = new SearchResult();
|
SearchResult result = new SearchResult();
|
||||||
|
|
||||||
|
addFromCollector(channelCollector);
|
||||||
addFromCollector(streamCollector);
|
addFromCollector(streamCollector);
|
||||||
|
|
||||||
result.suggestion = suggestion;
|
result.suggestion = suggestion;
|
||||||
|
@ -54,4 +59,8 @@ public class InfoItemSearchCollector extends InfoItemCollector {
|
||||||
public void commit(StreamInfoItemExtractor extractor) throws ParsingException {
|
public void commit(StreamInfoItemExtractor extractor) throws ParsingException {
|
||||||
streamCollector.commit(extractor);
|
streamCollector.commit(extractor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void commit(ChannelInfoItemExtractor extractor) throws ParsingException {
|
||||||
|
channelCollector.commit(extractor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
import org.schabi.newpipe.extractor.stream_info.StreamInfoItemCollector;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 10.08.15.
|
* Created by Christian Schabesberger on 10.08.15.
|
||||||
|
@ -27,6 +28,10 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class SearchEngine {
|
public abstract class SearchEngine {
|
||||||
|
public enum Filter {
|
||||||
|
VIDEO, CHANNEL, PLAY_LIST
|
||||||
|
}
|
||||||
|
|
||||||
public static class NothingFoundException extends ExtractionException {
|
public static class NothingFoundException extends ExtractionException {
|
||||||
public NothingFoundException(String message) {
|
public NothingFoundException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
@ -43,6 +48,6 @@ public abstract class SearchEngine {
|
||||||
}
|
}
|
||||||
//Result search(String query, int page);
|
//Result search(String query, int page);
|
||||||
public abstract InfoItemSearchCollector search(
|
public abstract InfoItemSearchCollector search(
|
||||||
String query, int page, String contentCountry)
|
String query, int page, String contentCountry, EnumSet<Filter> filter)
|
||||||
throws ExtractionException, IOException;
|
throws ExtractionException, IOException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
@ -30,10 +31,12 @@ import java.util.Vector;
|
||||||
|
|
||||||
public class SearchResult {
|
public class SearchResult {
|
||||||
public static SearchResult getSearchResult(SearchEngine engine, String query,
|
public static SearchResult getSearchResult(SearchEngine engine, String query,
|
||||||
int page, String languageCode)
|
int page, String languageCode, EnumSet<SearchEngine.Filter> filter)
|
||||||
throws ExtractionException, IOException {
|
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.resultList.isEmpty()) {
|
||||||
if(result.suggestion.isEmpty()) {
|
if(result.suggestion.isEmpty()) {
|
||||||
throw new ExtractionException("Empty result despite no error");
|
throw new ExtractionException("Empty result despite no error");
|
||||||
|
|
|
@ -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 <chris.schabesberger@mailbox.org>
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,11 +9,10 @@ import org.schabi.newpipe.extractor.UrlIdHandler;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
import org.schabi.newpipe.extractor.search.InfoItemSearchCollector;
|
import org.schabi.newpipe.extractor.search.InfoItemSearchCollector;
|
||||||
import org.schabi.newpipe.extractor.search.SearchEngine;
|
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.net.URLEncoder;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,7 +45,10 @@ public class YoutubeSearchEngine extends SearchEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InfoItemSearchCollector search(String query, int page, String languageCode)
|
public InfoItemSearchCollector search(String query,
|
||||||
|
int page,
|
||||||
|
String languageCode,
|
||||||
|
EnumSet<Filter> filter)
|
||||||
throws IOException, ExtractionException {
|
throws IOException, ExtractionException {
|
||||||
InfoItemSearchCollector collector = getInfoItemSearchCollector();
|
InfoItemSearchCollector collector = getInfoItemSearchCollector();
|
||||||
|
|
||||||
|
@ -54,9 +56,13 @@ public class YoutubeSearchEngine extends SearchEngine {
|
||||||
Downloader downloader = NewPipe.getDownloader();
|
Downloader downloader = NewPipe.getDownloader();
|
||||||
|
|
||||||
String url = "https://www.youtube.com/results"
|
String url = "https://www.youtube.com/results"
|
||||||
+ "?search_query=" + URLEncoder.encode(query, CHARSET_UTF_8)
|
+ "?q=" + URLEncoder.encode(query, CHARSET_UTF_8)
|
||||||
+ "&page=" + Integer.toString(page + 1)
|
+ "&page=" + Integer.toString(page + 1);
|
||||||
+ "&filters=" + "video";
|
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 site;
|
||||||
//String url = builder.build().toString();
|
//String url = builder.build().toString();
|
||||||
|
@ -94,12 +100,13 @@ public class YoutubeSearchEngine extends SearchEngine {
|
||||||
}
|
}
|
||||||
// search message item
|
// search message item
|
||||||
} else if ((el = item.select("div[class*=\"search-message\"]").first()) != null) {
|
} else if ((el = item.select("div[class*=\"search-message\"]").first()) != null) {
|
||||||
//result.errorMessage = el.text();
|
|
||||||
throw new NothingFoundException(el.text());
|
throw new NothingFoundException(el.text());
|
||||||
|
|
||||||
// video item type
|
// 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));
|
collector.commit(new YoutubeStreamInfoItemExtractor(el));
|
||||||
|
} else if((el = item.select("div[class*=\"yt-lockup-channel\"]").first()) != null) {
|
||||||
|
collector.commit(new YoutubeChannelInfoItemExtractor(el));
|
||||||
} else {
|
} else {
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
throw new ExtractionException("unexpected element found:\"" + el + "\"");
|
throw new ExtractionException("unexpected element found:\"" + el + "\"");
|
||||||
|
|
|
@ -31,8 +31,15 @@ import java.util.Vector;
|
||||||
|
|
||||||
public class StreamInfoItemCollector extends InfoItemCollector {
|
public class StreamInfoItemCollector extends InfoItemCollector {
|
||||||
|
|
||||||
|
private UrlIdHandler urlIdHandler;
|
||||||
|
|
||||||
public StreamInfoItemCollector(UrlIdHandler handler, int serviceId) {
|
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 {
|
public void commit(StreamInfoItemExtractor extractor) throws ParsingException {
|
||||||
|
|
|
@ -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 <chris.schabesberger@mailbox.org>
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
@ -13,6 +14,7 @@ import org.schabi.newpipe.ImageErrorLoadingListener;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.extractor.AbstractStreamInfo;
|
import org.schabi.newpipe.extractor.AbstractStreamInfo;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
|
import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,7 +39,8 @@ import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
||||||
|
|
||||||
public class InfoItemBuilder {
|
public class InfoItemBuilder {
|
||||||
|
|
||||||
public interface OnItemSelectedListener {
|
private static final String TAG = InfoItemBuilder.class.toString();
|
||||||
|
public interface OnInfoItemSelectedListener {
|
||||||
void selected(String url);
|
void selected(String url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,19 +49,64 @@ public class InfoItemBuilder {
|
||||||
private ImageLoader imageLoader = ImageLoader.getInstance();
|
private ImageLoader imageLoader = ImageLoader.getInstance();
|
||||||
private DisplayImageOptions displayImageOptions =
|
private DisplayImageOptions displayImageOptions =
|
||||||
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
||||||
private OnItemSelectedListener onItemSelectedListener;
|
private OnInfoItemSelectedListener onStreamInfoItemSelectedListener;
|
||||||
|
private OnInfoItemSelectedListener onChannelInfoItemSelectedListener;
|
||||||
|
|
||||||
public InfoItemBuilder(Activity a, View rootView) {
|
public InfoItemBuilder(Activity a, View rootView) {
|
||||||
activity = a;
|
activity = a;
|
||||||
this.rootView = rootView;
|
this.rootView = rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
|
public void setOnStreamInfoItemSelectedListener(
|
||||||
this.onItemSelectedListener = onItemSelectedListener;
|
OnInfoItemSelectedListener listener) {
|
||||||
|
this.onStreamInfoItemSelectedListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnChannelInfoItemSelectedListener(
|
||||||
|
OnInfoItemSelectedListener listener) {
|
||||||
|
this.onChannelInfoItemSelectedListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void buildByHolder(InfoItemHolder holder, final InfoItem i) {
|
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) {
|
if(info.infoType() != InfoItem.InfoType.STREAM) {
|
||||||
Log.e("InfoItemBuilder", "Info type not yet supported");
|
Log.e("InfoItemBuilder", "Info type not yet supported");
|
||||||
}
|
}
|
||||||
|
@ -98,20 +146,23 @@ public class InfoItemBuilder {
|
||||||
holder.itemButton.setOnClickListener(new View.OnClickListener() {
|
holder.itemButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
onItemSelectedListener.selected(info.webpage_url);
|
onStreamInfoItemSelectedListener.selected(info.webpage_url);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public View buildView(ViewGroup parent, final InfoItem info) {
|
private void buildChannelInfoItem(ChannelInfoItemHolder holder, final ChannelInfoItem info) {
|
||||||
View streamPreviewView = LayoutInflater.from(parent.getContext())
|
holder.itemChannelTitleView.setText(info.getTitle());
|
||||||
.inflate(R.layout.video_item, parent, false);
|
holder.itemButton.setOnClickListener(new View.OnClickListener() {
|
||||||
InfoItemHolder holder = new InfoItemHolder(streamPreviewView);
|
@Override
|
||||||
buildByHolder(holder, info);
|
public void onClick(View view) {
|
||||||
return streamPreviewView;
|
onChannelInfoItemSelectedListener.selected(info.getLink());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static String shortViewCount(Long viewCount){
|
public static String shortViewCount(Long viewCount){
|
||||||
if(viewCount >= 1000000000){
|
if(viewCount >= 1000000000){
|
||||||
return Long.toString(viewCount/1000000000)+"B views";
|
return Long.toString(viewCount/1000000000)+"B views";
|
||||||
|
|
|
@ -2,14 +2,11 @@ package org.schabi.newpipe.info_list;
|
||||||
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
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 <chris.schabesberger@mailbox.org>
|
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||||
* InfoItemHolder.java is part of NewPipe.
|
* InfoItemHolder.java is part of NewPipe.
|
||||||
|
@ -28,25 +25,9 @@ import org.schabi.newpipe.R;
|
||||||
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class InfoItemHolder extends RecyclerView.ViewHolder {
|
public abstract class InfoItemHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
public final ImageView itemThumbnailView;
|
|
||||||
public final TextView itemVideoTitleView,
|
|
||||||
itemUploaderView,
|
|
||||||
itemDurationView,
|
|
||||||
itemUploadDateView,
|
|
||||||
itemViewCountView;
|
|
||||||
public final Button itemButton;
|
|
||||||
|
|
||||||
public InfoItemHolder(View v) {
|
public InfoItemHolder(View v) {
|
||||||
super(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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@ package org.schabi.newpipe.info_list;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.extractor.InfoItem;
|
import org.schabi.newpipe.extractor.InfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
@ -34,47 +34,58 @@ import java.util.Vector;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class InfoListAdapter extends RecyclerView.Adapter<InfoItemHolder> {
|
public class InfoListAdapter extends RecyclerView.Adapter<InfoItemHolder> {
|
||||||
|
private static final String TAG = InfoListAdapter.class.toString();
|
||||||
|
|
||||||
private final InfoItemBuilder infoItemBuilder;
|
private final InfoItemBuilder infoItemBuilder;
|
||||||
private final List<InfoItem> streamList;
|
private final List<InfoItem> infoItemList;
|
||||||
|
|
||||||
public InfoListAdapter(Activity a, View rootView) {
|
public InfoListAdapter(Activity a, View rootView) {
|
||||||
infoItemBuilder = new InfoItemBuilder(a, rootView);
|
infoItemBuilder = new InfoItemBuilder(a, rootView);
|
||||||
streamList = new Vector<>();
|
infoItemList = new Vector<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnItemSelectedListener
|
public void setOnStreamItemSelectedListener
|
||||||
(InfoItemBuilder.OnItemSelectedListener onItemSelectedListener) {
|
(InfoItemBuilder.OnInfoItemSelectedListener onItemSelectedListener) {
|
||||||
infoItemBuilder.setOnItemSelectedListener(onItemSelectedListener);
|
infoItemBuilder.setOnStreamInfoItemSelectedListener(onItemSelectedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addStreamItemList(List<InfoItem> videos) {
|
public void addInfoItemList(List<InfoItem> videos) {
|
||||||
if(videos!= null) {
|
if(videos!= null) {
|
||||||
streamList.addAll(videos);
|
infoItemList.addAll(videos);
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearSteamItemList() {
|
public void clearSteamItemList() {
|
||||||
streamList.clear();
|
infoItemList.clear();
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return streamList.size();
|
return infoItemList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InfoItemHolder onCreateViewHolder(ViewGroup parent, int i) {
|
public InfoItemHolder onCreateViewHolder(ViewGroup parent, int i) {
|
||||||
View itemView = LayoutInflater.from(parent.getContext())
|
switch(infoItemList.get(i).infoType()) {
|
||||||
.inflate(R.layout.video_item, parent, false);
|
case STREAM:
|
||||||
|
return new StreamInfoItemHolder(LayoutInflater.from(parent.getContext())
|
||||||
return new InfoItemHolder(itemView);
|
.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
|
@Override
|
||||||
public void onBindViewHolder(InfoItemHolder holder, int i) {
|
public void onBindViewHolder(InfoItemHolder holder, int i) {
|
||||||
infoItemBuilder.buildByHolder(holder, streamList.get(i));
|
infoItemBuilder.buildByHolder(holder, infoItemList.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <chris.schabesberger@mailbox.org>
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import org.schabi.newpipe.ReCaptchaActivity;
|
import org.schabi.newpipe.ReCaptchaActivity;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
|
import org.schabi.newpipe.extractor.search.SearchEngine;
|
||||||
import org.schabi.newpipe.extractor.search.SearchResult;
|
import org.schabi.newpipe.extractor.search.SearchResult;
|
||||||
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
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.detail.VideoItemDetailFragment;
|
||||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
import static android.app.Activity.RESULT_OK;
|
import static android.app.Activity.RESULT_OK;
|
||||||
import static org.schabi.newpipe.ReCaptchaActivity.RECAPTCHA_REQUEST;
|
import static org.schabi.newpipe.ReCaptchaActivity.RECAPTCHA_REQUEST;
|
||||||
|
|
||||||
|
@ -166,7 +169,7 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
sw.setSearchWorkerResultListener(new SearchWorker.SearchWorkerResultListener() {
|
sw.setSearchWorkerResultListener(new SearchWorker.SearchWorkerResultListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(SearchResult result) {
|
public void onResult(SearchResult result) {
|
||||||
infoListAdapter.addStreamItemList(result.resultList);
|
infoListAdapter.addInfoItemList(result.resultList);
|
||||||
setDoneLoading();
|
setDoneLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +216,8 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
|
|
||||||
infoListAdapter = new InfoListAdapter(getActivity(),
|
infoListAdapter = new InfoListAdapter(getActivity(),
|
||||||
getActivity().findViewById(android.R.id.content));
|
getActivity().findViewById(android.R.id.content));
|
||||||
infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
infoListAdapter.setOnStreamItemSelectedListener(
|
||||||
|
new InfoItemBuilder.OnInfoItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void selected(String url) {
|
public void selected(String url) {
|
||||||
startDetailActivity(url);
|
startDetailActivity(url);
|
||||||
|
@ -298,7 +302,11 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
private void search(String query, int page) {
|
private void search(String query, int page) {
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
SearchWorker sw = SearchWorker.getInstance();
|
SearchWorker sw = SearchWorker.getInstance();
|
||||||
sw.search(streamingServiceId, query, page, getActivity());
|
sw.search(streamingServiceId,
|
||||||
|
query,
|
||||||
|
page,
|
||||||
|
getActivity(),
|
||||||
|
EnumSet.of(SearchEngine.Filter.CHANNEL));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDoneLoading() {
|
private void setDoneLoading() {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 02.08.16.
|
* Created by Christian Schabesberger on 02.08.16.
|
||||||
|
@ -67,14 +68,21 @@ public class SearchWorker {
|
||||||
public static final String YOUTUBE = "Youtube";
|
public static final String YOUTUBE = "Youtube";
|
||||||
private final String query;
|
private final String query;
|
||||||
private final int page;
|
private final int page;
|
||||||
|
private final EnumSet<SearchEngine.Filter> filter;
|
||||||
final Handler h = new Handler();
|
final Handler h = new Handler();
|
||||||
private volatile boolean runs = true;
|
private volatile boolean runs = true;
|
||||||
private Activity a = null;
|
private Activity a = null;
|
||||||
private int serviceId = -1;
|
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<SearchEngine.Filter> filter,
|
||||||
|
Activity activity,
|
||||||
|
int requestId) {
|
||||||
this.serviceId = serviceId;
|
this.serviceId = serviceId;
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.page = page;
|
this.page = page;
|
||||||
|
this.filter = filter;
|
||||||
this.a = activity;
|
this.a = activity;
|
||||||
}
|
}
|
||||||
void terminate() {
|
void terminate() {
|
||||||
|
@ -102,7 +110,7 @@ public class SearchWorker {
|
||||||
String searchLanguage = sp.getString(searchLanguageKey,
|
String searchLanguage = sp.getString(searchLanguageKey,
|
||||||
a.getString(R.string.default_language_value));
|
a.getString(R.string.default_language_value));
|
||||||
result = SearchResult
|
result = SearchResult
|
||||||
.getSearchResult(engine, query, page, searchLanguage);
|
.getSearchResult(engine, query, page, searchLanguage, filter);
|
||||||
if(runs) {
|
if(runs) {
|
||||||
h.post(new ResultRunnable(result, requestId));
|
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<SearchEngine.Filter> filter) {
|
||||||
if(runnable != null) {
|
if(runnable != null) {
|
||||||
terminate();
|
terminate();
|
||||||
}
|
}
|
||||||
runnable = new SearchRunnable(serviceId, query, page, a, requestId);
|
runnable = new SearchRunnable(serviceId, query, page, filter, a, requestId);
|
||||||
Thread thread = new Thread(runnable);
|
Thread thread = new Thread(runnable);
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
BIN
app/src/main/res/drawable-nodpi/buddy_channel_item.png
Normal file
BIN
app/src/main/res/drawable-nodpi/buddy_channel_item.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
BIN
app/src/main/res/drawable-nodpi/dummi_thumbnail_playlist.png
Normal file
BIN
app/src/main/res/drawable-nodpi/dummi_thumbnail_playlist.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
69
app/src/main/res/layout/channel_item.xml
Normal file
69
app/src/main/res/layout/channel_item.xml
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/item_main_layout"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" >
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="12dp">
|
||||||
|
|
||||||
|
<RelativeLayout android:id="@+id/itemThumbnailViewContainer"
|
||||||
|
android:layout_marginRight="@dimen/video_item_search_image_right_margin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:ignore="RtlHardcoded">
|
||||||
|
|
||||||
|
<de.hdodenhof.circleimageview.CircleImageView android:id="@+id/itemThumbnailView"
|
||||||
|
android:contentDescription="@string/list_thumbnail_view_description"
|
||||||
|
android:layout_width="@dimen/video_item_search_thumbnail_image_width"
|
||||||
|
android:layout_height="@dimen/video_item_search_thumbnail_image_height"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:src="@drawable/buddy_channel_item"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="@dimen/video_item_search_thumbnail_image_height"
|
||||||
|
android:layout_toRightOf="@id/itemThumbnailViewContainer"
|
||||||
|
tools:ignore="RtlHardcoded">
|
||||||
|
|
||||||
|
<TextView android:id="@+id/itemChannelTitleView"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:textSize="@dimen/video_item_search_title_text_size"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/item_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/selectableItemBackground"/>
|
||||||
|
</FrameLayout>
|
71
app/src/main/res/layout/play_list_item.xml
Normal file
71
app/src/main/res/layout/play_list_item.xml
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/item_main_layout"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" >
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="12dp">
|
||||||
|
|
||||||
|
<RelativeLayout android:id="@+id/itemThumbnailViewContainer"
|
||||||
|
android:layout_marginRight="@dimen/video_item_search_image_right_margin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:ignore="RtlHardcoded">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/itemThumbnailView"
|
||||||
|
android:contentDescription="@string/list_thumbnail_view_description"
|
||||||
|
android:layout_width="@dimen/video_item_search_thumbnail_image_width"
|
||||||
|
android:layout_height="@dimen/video_item_search_thumbnail_image_height"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:src="@drawable/dummi_thumbnail_playlist"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="@dimen/video_item_search_thumbnail_image_height"
|
||||||
|
android:layout_toRightOf="@id/itemThumbnailViewContainer"
|
||||||
|
tools:ignore="RtlHardcoded">
|
||||||
|
|
||||||
|
<TextView android:id="@+id/itemTitleView"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:textSize="@dimen/video_item_search_title_text_size"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/item_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/selectableItemBackground"/>
|
||||||
|
</FrameLayout>
|
108
app/src/main/res/layout/stream_item.xml
Normal file
108
app/src/main/res/layout/stream_item.xml
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/item_main_layout"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" >
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="12dp">
|
||||||
|
|
||||||
|
<RelativeLayout android:id="@+id/itemThumbnailViewContainer"
|
||||||
|
android:layout_marginRight="@dimen/video_item_search_image_right_margin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:ignore="RtlHardcoded">
|
||||||
|
|
||||||
|
<ImageView android:id="@+id/itemThumbnailView"
|
||||||
|
android:contentDescription="@string/list_thumbnail_view_description"
|
||||||
|
android:layout_width="@dimen/video_item_search_thumbnail_image_width"
|
||||||
|
android:layout_height="@dimen/video_item_search_thumbnail_image_height"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:src="@drawable/dummy_thumbnail"/>
|
||||||
|
|
||||||
|
<TextView android:id="@+id/itemDurationView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignBottom="@id/itemThumbnailView"
|
||||||
|
android:layout_alignRight="@id/itemThumbnailView"
|
||||||
|
android:layout_alignEnd="@id/itemThumbnailView"
|
||||||
|
android:layout_marginRight="@dimen/video_item_search_duration_margin"
|
||||||
|
android:layout_marginEnd="@dimen/video_item_search_duration_margin"
|
||||||
|
android:layout_marginBottom="@dimen/video_item_search_duration_margin"
|
||||||
|
android:paddingTop="@dimen/video_item_search_duration_vertical_padding"
|
||||||
|
android:paddingBottom="@dimen/video_item_search_duration_vertical_padding"
|
||||||
|
android:paddingRight="@dimen/video_item_search_duration_horizontal_padding"
|
||||||
|
android:paddingLeft="@dimen/video_item_search_duration_horizontal_padding"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:textSize="@dimen/video_item_search_duration_text_size"
|
||||||
|
android:background="@color/duration_background_color"
|
||||||
|
android:textColor="@color/duration_text_color"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="@dimen/video_item_search_thumbnail_image_height"
|
||||||
|
android:layout_toRightOf="@id/itemThumbnailViewContainer"
|
||||||
|
tools:ignore="RtlHardcoded">
|
||||||
|
|
||||||
|
<TextView android:id="@+id/itemVideoTitleView"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:textSize="@dimen/video_item_search_title_text_size"/>
|
||||||
|
|
||||||
|
<TextView android:id="@+id/itemUploaderView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:textSize="@dimen/video_item_search_uploader_text_size"/>
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView android:id="@+id/itemUploadDateView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:textSize="@dimen/video_item_search_upload_date_text_size"/>
|
||||||
|
|
||||||
|
<TextView android:id="@+id/itemViewCountView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:textSize="@dimen/video_item_search_upload_date_text_size"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/item_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/selectableItemBackground"/>
|
||||||
|
</FrameLayout>
|
85
assets/buddy_channel_item.svg
Normal file
85
assets/buddy_channel_item.svg
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="200"
|
||||||
|
height="200"
|
||||||
|
viewBox="0 0 187.5 187.5"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.92.0 r"
|
||||||
|
sodipodi:docname="buddy_channel_item.svg"
|
||||||
|
inkscape:export-filename="/home/the-scrabi/Projects/NewPipe/app/src/main/res/drawable-nodpi/buddy_channel_item.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.6269531"
|
||||||
|
inkscape:cx="-8.1138818"
|
||||||
|
inkscape:cy="101.30232"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1012"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="32"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-864.86216)">
|
||||||
|
<rect
|
||||||
|
style="opacity:0.997;fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.6875;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect4136"
|
||||||
|
width="187.5"
|
||||||
|
height="187.5"
|
||||||
|
x="0"
|
||||||
|
y="864.86218" />
|
||||||
|
<g
|
||||||
|
id="g4487"
|
||||||
|
transform="matrix(0.5625,0,0,0.5625,37.5,418.22093)">
|
||||||
|
<ellipse
|
||||||
|
ry="75"
|
||||||
|
rx="100"
|
||||||
|
cy="1052.3622"
|
||||||
|
cx="100"
|
||||||
|
id="path4152"
|
||||||
|
style="opacity:0.997;fill:#6c6c6c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
<circle
|
||||||
|
r="60"
|
||||||
|
cy="942.36218"
|
||||||
|
cx="100"
|
||||||
|
id="path4154"
|
||||||
|
style="opacity:0.997;fill:#6c6c6c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
105
assets/dummi_thumbnail_playlist.svg
Normal file
105
assets/dummi_thumbnail_playlist.svg
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="454.39999"
|
||||||
|
height="256"
|
||||||
|
viewBox="0 0 426.00001 240"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.92.0 r"
|
||||||
|
sodipodi:docname="dummi_thumbnail_playlist.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.6106014"
|
||||||
|
inkscape:cx="305.7725"
|
||||||
|
inkscape:cy="81.056384"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1012"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="32"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-812.36212)">
|
||||||
|
<rect
|
||||||
|
style="opacity:0.997;fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect4136"
|
||||||
|
width="426"
|
||||||
|
height="240"
|
||||||
|
x="0"
|
||||||
|
y="812.36212" />
|
||||||
|
<g
|
||||||
|
id="g850"
|
||||||
|
transform="matrix(0.99796952,0,0,1,32.067586,0)">
|
||||||
|
<path
|
||||||
|
inkscape:transform-center-y="-0.54163706"
|
||||||
|
transform="matrix(0.65046494,0.01393934,-0.01048956,0.86438861,173.20818,83.099197)"
|
||||||
|
inkscape:transform-center-x="-13.894569"
|
||||||
|
d="M 122.12368,980.33878 65.844916,1014.7522 2.6244521,1052.3621 0.9609674,986.41661 -1.2793975e-6,912.86109 57.942247,944.39324 Z"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
sodipodi:arg2="0.93534698"
|
||||||
|
sodipodi:arg1="-0.018810925"
|
||||||
|
sodipodi:r2="40.877174"
|
||||||
|
sodipodi:r1="80.555222"
|
||||||
|
sodipodi:cy="981.854"
|
||||||
|
sodipodi:cx="41.58271"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
id="path4164"
|
||||||
|
style="opacity:0.997;fill:#6c6c6c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
sodipodi:type="star" />
|
||||||
|
<path
|
||||||
|
inkscape:transform-center-y="-0.54163706"
|
||||||
|
transform="matrix(0.65046494,0.01393934,-0.01048956,0.86438861,129.96106,83.099439)"
|
||||||
|
inkscape:transform-center-x="-13.894569"
|
||||||
|
d="M 122.12368,980.33878 65.844916,1014.7522 2.6244521,1052.3621 0.9609674,986.41661 -1.2793975e-6,912.86109 57.942247,944.39324 Z"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
sodipodi:arg2="0.93534698"
|
||||||
|
sodipodi:arg1="-0.018810925"
|
||||||
|
sodipodi:r2="40.877174"
|
||||||
|
sodipodi:r1="80.555222"
|
||||||
|
sodipodi:cy="981.854"
|
||||||
|
sodipodi:cx="41.58271"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
id="path4164-3"
|
||||||
|
style="opacity:0.997;fill:#6c6c6c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
sodipodi:type="star" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.7 KiB |
72
assets/dummi_thumbnail_playlist_background.svg
Normal file
72
assets/dummi_thumbnail_playlist_background.svg
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="534.39996"
|
||||||
|
height="336"
|
||||||
|
viewBox="0 0 500.99998 315"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.92.0 r"
|
||||||
|
sodipodi:docname="dummi_thumbnail_playlist_background.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.3101865"
|
||||||
|
inkscape:cx="235.67736"
|
||||||
|
inkscape:cy="200.81947"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1012"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="32"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-737.36212)">
|
||||||
|
<rect
|
||||||
|
style="opacity:0.997;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect4136-6-5"
|
||||||
|
width="426.00003"
|
||||||
|
height="240"
|
||||||
|
x="18.75"
|
||||||
|
y="756.11212" />
|
||||||
|
<rect
|
||||||
|
style="opacity:0.997;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2.81250004;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect4136-6"
|
||||||
|
width="426"
|
||||||
|
height="240"
|
||||||
|
x="28.125"
|
||||||
|
y="765.48712" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
Loading…
Reference in a new issue