mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-23 16:40:32 +00:00
Initial work: use disposables for timestamps parsing in YouTube video descriptions and YouTube comments
This commit is contained in:
parent
f13f4cc5d2
commit
da4d379b22
@ -13,6 +13,8 @@ import android.widget.TextView;
|
||||
import org.schabi.newpipe.util.external_communication.ShareUtils;
|
||||
import org.schabi.newpipe.util.external_communication.InternalUrlsHandler;
|
||||
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
|
||||
public class CommentTextOnTouchListener implements View.OnTouchListener {
|
||||
public static final CommentTextOnTouchListener INSTANCE = new CommentTextOnTouchListener();
|
||||
|
||||
@ -50,8 +52,8 @@ public class CommentTextOnTouchListener implements View.OnTouchListener {
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
if (link[0] instanceof URLSpan) {
|
||||
final String url = ((URLSpan) link[0]).getURL();
|
||||
if (!InternalUrlsHandler.handleUrlCommentsTimestamp(v.getContext(),
|
||||
url)) {
|
||||
if (!InternalUrlsHandler.handleUrlCommentsTimestamp(
|
||||
new CompositeDisposable(), v.getContext(), url)) {
|
||||
ShareUtils.openUrlInBrowser(v.getContext(), url, false);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.core.Single;
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
@ -38,12 +39,15 @@ public final class InternalUrlsHandler {
|
||||
* popup player will be opened when the user will click on the timestamp in the comment,
|
||||
* at the time and for the video indicated in the timestamp.
|
||||
*
|
||||
* @param context the context to use
|
||||
* @param url the URL to check if it can be handled
|
||||
* @param disposables a field of the Activity/Fragment class that calls this method
|
||||
* @param context the context to use
|
||||
* @param url the URL to check if it can be handled
|
||||
* @return true if the URL can be handled by NewPipe, false if it cannot
|
||||
*/
|
||||
public static boolean handleUrlCommentsTimestamp(final Context context, final String url) {
|
||||
return handleUrl(context, url, HASHTAG_TIMESTAMP_PATTERN);
|
||||
public static boolean handleUrlCommentsTimestamp(final CompositeDisposable disposables,
|
||||
final Context context,
|
||||
final String url) {
|
||||
return handleUrl(disposables, context, url, HASHTAG_TIMESTAMP_PATTERN);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,12 +58,15 @@ public final class InternalUrlsHandler {
|
||||
* player will be opened when the user will click on the timestamp in the video description,
|
||||
* at the time and for the video indicated in the timestamp.
|
||||
*
|
||||
* @param context the context to use
|
||||
* @param url the URL to check if it can be handled
|
||||
* @param disposables a field of the Activity/Fragment class that calls this method
|
||||
* @param context the context to use
|
||||
* @param url the URL to check if it can be handled
|
||||
* @return true if the URL can be handled by NewPipe, false if it cannot
|
||||
*/
|
||||
public static boolean handleUrlDescriptionTimestamp(final Context context, final String url) {
|
||||
return handleUrl(context, url, AMPERSAND_TIMESTAMP_PATTERN);
|
||||
public static boolean handleUrlDescriptionTimestamp(final CompositeDisposable disposables,
|
||||
final Context context,
|
||||
final String url) {
|
||||
return handleUrl(disposables, context, url, AMPERSAND_TIMESTAMP_PATTERN);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,12 +76,14 @@ public final class InternalUrlsHandler {
|
||||
* service URL with a timestamp, the popup player will be opened and true will be returned;
|
||||
* else, false will be returned.
|
||||
*
|
||||
* @param context the context to use
|
||||
* @param url the URL to check if it can be handled
|
||||
* @param pattern the pattern
|
||||
* @param disposables a field of the Activity/Fragment class that calls this method
|
||||
* @param context the context to use
|
||||
* @param url the URL to check if it can be handled
|
||||
* @param pattern the pattern to use
|
||||
* @return true if the URL can be handled by NewPipe, false if it cannot
|
||||
*/
|
||||
private static boolean handleUrl(final Context context,
|
||||
private static boolean handleUrl(final CompositeDisposable disposables,
|
||||
final Context context,
|
||||
final String url,
|
||||
final Pattern pattern) {
|
||||
final String matchedUrl;
|
||||
@ -102,7 +111,7 @@ public final class InternalUrlsHandler {
|
||||
return false;
|
||||
}
|
||||
if (linkType == StreamingService.LinkType.STREAM && seconds != -1) {
|
||||
return playOnPopup(context, matchedUrl, service, seconds);
|
||||
return playOnPopup(disposables, context, matchedUrl, service, seconds);
|
||||
} else {
|
||||
NavigationHelper.openRouterActivity(context, matchedUrl);
|
||||
return true;
|
||||
@ -112,13 +121,15 @@ public final class InternalUrlsHandler {
|
||||
/**
|
||||
* Play a content in the floating player.
|
||||
*
|
||||
* @param context the context to be used
|
||||
* @param url the URL of the content
|
||||
* @param service the service of the content
|
||||
* @param seconds the position in seconds at which the floating player will start
|
||||
* @param disposables a field of the Activity/Fragment class that calls this method
|
||||
* @param context the context to be used
|
||||
* @param url the URL of the content
|
||||
* @param service the service of the content
|
||||
* @param seconds the position in seconds at which the floating player will start
|
||||
* @return true if the playback of the content has successfully started or false if not
|
||||
*/
|
||||
public static boolean playOnPopup(final Context context,
|
||||
public static boolean playOnPopup(final CompositeDisposable disposables,
|
||||
final Context context,
|
||||
final String url,
|
||||
final StreamingService service,
|
||||
final int seconds) {
|
||||
@ -133,13 +144,13 @@ public final class InternalUrlsHandler {
|
||||
|
||||
final Single<StreamInfo> single
|
||||
= ExtractorHelper.getStreamInfo(service.getServiceId(), cleanUrl, false);
|
||||
single.subscribeOn(Schedulers.io())
|
||||
disposables.add(single.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(info -> {
|
||||
final PlayQueue playQueue
|
||||
= new SinglePlayQueue(info, seconds * 1000);
|
||||
NavigationHelper.playOnPopupPlayer(context, playQueue, false);
|
||||
});
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import io.noties.markwon.Markwon;
|
||||
import io.noties.markwon.linkify.LinkifyPlugin;
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.core.Single;
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
@ -201,7 +202,8 @@ public final class TextLinkifier {
|
||||
spannableDescription.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void onClick(@NonNull final View view) {
|
||||
playOnPopup(context, contentUrl, streamingService, time);
|
||||
playOnPopup(new CompositeDisposable(), context, contentUrl, streamingService,
|
||||
time);
|
||||
}
|
||||
}, timestampStart, timestampEnd, 0);
|
||||
}
|
||||
@ -245,7 +247,8 @@ public final class TextLinkifier {
|
||||
final String url = span.getURL();
|
||||
final ClickableSpan clickableSpan = new ClickableSpan() {
|
||||
public void onClick(@NonNull final View view) {
|
||||
if (!InternalUrlsHandler.handleUrlDescriptionTimestamp(context, url)) {
|
||||
if (!InternalUrlsHandler.handleUrlDescriptionTimestamp(
|
||||
new CompositeDisposable(), context, url)) {
|
||||
ShareUtils.openUrlInBrowser(context, url, false);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user