Open youtube links directly from search (fixes #35) (#692)

* Open youtube links directly from search (fixes #35)
This commit is contained in:
Felix Ableitner 2017-09-16 02:27:39 +09:00 committed by Christian Schabesberger
parent 5e66a66111
commit 5b8ff28556
3 changed files with 61 additions and 11 deletions

View File

@ -43,9 +43,8 @@ public class RouterActivity extends AppCompatActivity {
} }
protected void handleUrl(String url) { protected void handleUrl(String url) {
try { boolean success = NavigationHelper.openByLink(this, url);
NavigationHelper.openByLink(this, url); if (!success) {
} catch (Exception e) {
Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show(); Toast.makeText(this, R.string.url_not_supported_toast, Toast.LENGTH_LONG).show();
} }

View File

@ -34,6 +34,7 @@ import org.schabi.newpipe.ReCaptchaActivity;
import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.search.SearchEngine; import org.schabi.newpipe.extractor.search.SearchEngine;
import org.schabi.newpipe.extractor.search.SearchResult; import org.schabi.newpipe.extractor.search.SearchResult;
@ -47,12 +48,14 @@ import org.schabi.newpipe.util.StateSaver;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import icepick.State; import icepick.State;
import io.reactivex.Notification; import io.reactivex.Notification;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer; import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function; import io.reactivex.functions.Function;
@ -97,6 +100,7 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
private PublishSubject<String> suggestionPublisher = PublishSubject.create(); private PublishSubject<String> suggestionPublisher = PublishSubject.create();
private Disposable searchDisposable; private Disposable searchDisposable;
private Disposable suggestionWorkerDisposable; private Disposable suggestionWorkerDisposable;
private CompositeDisposable disposables = new CompositeDisposable();
private SuggestionListAdapter suggestionListAdapter; private SuggestionListAdapter suggestionListAdapter;
@ -149,6 +153,7 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
if (searchDisposable != null) searchDisposable.dispose(); if (searchDisposable != null) searchDisposable.dispose();
if (suggestionWorkerDisposable != null) suggestionWorkerDisposable.dispose(); if (suggestionWorkerDisposable != null) suggestionWorkerDisposable.dispose();
if (disposables != null) disposables.clear();
hideSoftKeyboard(searchEditText); hideSoftKeyboard(searchEditText);
} }
@ -192,6 +197,7 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
if (searchDisposable != null) searchDisposable.dispose(); if (searchDisposable != null) searchDisposable.dispose();
if (suggestionWorkerDisposable != null) suggestionWorkerDisposable.dispose(); if (suggestionWorkerDisposable != null) suggestionWorkerDisposable.dispose();
if (disposables != null) disposables.clear();
} }
@Override @Override
@ -514,6 +520,38 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
private void search(final String query) { private void search(final String query) {
if (DEBUG) Log.d(TAG, "search() called with: query = [" + query + "]"); if (DEBUG) Log.d(TAG, "search() called with: query = [" + query + "]");
try {
final StreamingService service = NewPipe.getServiceByUrl(query);
if (service != null) {
showLoading();
disposables.add(Observable
.fromCallable(new Callable<Intent>() {
@Override
public Intent call() throws Exception {
return NavigationHelper.getIntentByLink(activity, service, query);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Intent>() {
@Override
public void accept(Intent intent) throws Exception {
getFragmentManager().popBackStackImmediate();
activity.startActivity(intent);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
showError(getString(R.string.url_not_supported_toast), false);
hideLoading();
}
}));
return;
}
} catch (Exception e) {
// Exception occurred, it's not a url
}
hideSoftKeyboard(searchEditText); hideSoftKeyboard(searchEditText);
this.searchQuery = query; this.searchQuery = query;
this.currentPage = 0; this.currentPage = 0;
@ -532,6 +570,7 @@ public class SearchFragment extends BaseListFragment<SearchResult, ListExtractor
@Override @Override
public void startLoading(boolean forceLoad) { public void startLoading(boolean forceLoad) {
super.startLoading(forceLoad); super.startLoading(forceLoad);
if (disposables != null) disposables.clear();
if (searchDisposable != null) searchDisposable.dispose(); if (searchDisposable != null) searchDisposable.dispose();
searchDisposable = ExtractorHelper.searchFor(serviceId, searchQuery, currentPage, searchLanguage, filter) searchDisposable = ExtractorHelper.searchFor(serviceId, searchQuery, currentPage, searchLanguage, filter)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())

View File

@ -14,7 +14,9 @@ import org.schabi.newpipe.R;
import org.schabi.newpipe.about.AboutActivity; import org.schabi.newpipe.about.AboutActivity;
import org.schabi.newpipe.download.DownloadActivity; import org.schabi.newpipe.download.DownloadActivity;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.fragments.MainFragment; import org.schabi.newpipe.fragments.MainFragment;
@ -228,13 +230,17 @@ public class NavigationHelper {
// Link handling // Link handling
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
public static void openByLink(Context context, String url) throws Exception { public static boolean openByLink(Context context, String url) {
Intent intentByLink = getIntentByLink(context, url); Intent intentByLink;
if (intentByLink == null) try {
throw new NullPointerException("getIntentByLink(context = [" + context + "], url = [" + url + "]) returned null"); intentByLink = getIntentByLink(context, url);
} catch (ExtractionException e) {
return false;
}
intentByLink.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intentByLink.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intentByLink.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); intentByLink.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intentByLink); context.startActivity(intentByLink);
return true;
} }
private static Intent getOpenIntent(Context context, String url, int serviceId, StreamingService.LinkType type) { private static Intent getOpenIntent(Context context, String url, int serviceId, StreamingService.LinkType type) {
@ -245,14 +251,20 @@ public class NavigationHelper {
return mIntent; return mIntent;
} }
private static Intent getIntentByLink(Context context, String url) throws Exception { public static Intent getIntentByLink(Context context, String url) throws ExtractionException {
StreamingService service = NewPipe.getServiceByUrl(url); return getIntentByLink(context, NewPipe.getServiceByUrl(url), url);
}
public static Intent getIntentByLink(Context context, StreamingService service, String url) throws ExtractionException {
if (service != ServiceList.YouTube.getService()) {
throw new ExtractionException("Service not supported at the moment");
}
int serviceId = service.getServiceId(); int serviceId = service.getServiceId();
StreamingService.LinkType linkType = service.getLinkTypeByUrl(url); StreamingService.LinkType linkType = service.getLinkTypeByUrl(url);
if (linkType == StreamingService.LinkType.NONE) { if (linkType == StreamingService.LinkType.NONE) {
throw new Exception("Url not known to service. service=" + serviceId + " url=" + url); throw new ExtractionException("Url not known to service. service=" + serviceId + " url=" + url);
} }
url = getCleanUrl(service, url, linkType); url = getCleanUrl(service, url, linkType);
@ -268,7 +280,7 @@ public class NavigationHelper {
return rIntent; return rIntent;
} }
private static String getCleanUrl(StreamingService service, String dirtyUrl, StreamingService.LinkType linkType) throws Exception { private static String getCleanUrl(StreamingService service, String dirtyUrl, StreamingService.LinkType linkType) throws ExtractionException {
switch (linkType) { switch (linkType) {
case STREAM: case STREAM:
return service.getStreamUrlIdHandler().cleanUrl(dirtyUrl); return service.getStreamUrlIdHandler().cleanUrl(dirtyUrl);