diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java index f0ff0c460..44cbcd297 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java @@ -243,20 +243,13 @@ private void linkify() { LinkifyCompat.addLinks(itemContentView, Linkify.WEB_URLS); LinkifyCompat.addLinks(itemContentView, TimestampExtractor.TIMESTAMPS_PATTERN, null, null, (match, url) -> { - try { + try { //here url is like 15:38 or 01:00:00 final var timestampMatch = TimestampExtractor .getTimestampFromMatcher(match, commentText); if (timestampMatch == null) { return url; } - if(streamUrl.contains("https://api.bilibili.com/x/v2/reply")){ - return "https://m.bilibili.com/video/av" + - streamUrl.split("oid=")[1].split("&")[0] - + url.replace(Objects.requireNonNull(match.group(0)), - "#timestamp=" + timestampMatch.seconds()); - } - return streamUrl + url.replace(Objects.requireNonNull(match.group(0)), - "#timestamp=" + timestampMatch.seconds()); + return "internal://timestamp/" + timestampMatch.seconds(); } catch (final Exception ex) { Log.e(TAG, "Unable to process url='" + url + "' as timestampLink", ex); return url; diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/InternalUrlsHandler.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/InternalUrlsHandler.java index 5f1b40e08..0c2a3fb8c 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/InternalUrlsHandler.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/InternalUrlsHandler.java @@ -59,7 +59,7 @@ public static boolean handleUrlCommentsTimestamp(@NonNull final CompositeDisposa disposables, final Context context, @NonNull final String url) { - return handleUrl(context, url, HASHTAG_TIMESTAMP_PATTERN, disposables); + return handleTimestampUrl(context, url, HASHTAG_TIMESTAMP_PATTERN, disposables); } /** @@ -79,7 +79,7 @@ public static boolean handleUrlDescriptionTimestamp(@NonNull final CompositeDisp disposables, final Context context, @NonNull final String url) { - return handleUrl(context, url, AMPERSAND_TIMESTAMP_PATTERN, disposables); + return handleTimestampUrl(context, url, AMPERSAND_TIMESTAMP_PATTERN, disposables); } /** @@ -95,10 +95,16 @@ public static boolean handleUrlDescriptionTimestamp(@NonNull final CompositeDisp * @param disposables a field of the Activity/Fragment class that calls this method * @return true if the URL can be handled by NewPipe, false if it cannot */ - private static boolean handleUrl(final Context context, - @NonNull final String url, - @NonNull final Pattern pattern, - @NonNull final CompositeDisposable disposables) { + private static boolean handleTimestampUrl(final Context context, + @NonNull final String url, + @NonNull final Pattern pattern, + @NonNull final CompositeDisposable disposables) { + if(url.contains("internal://timestamp/")) { + Intent intent = new Intent(ACTION_SEEK_TO); + intent.putExtra("Timestamp", url.split("internal://timestamp/")[1]); + context.sendBroadcast(intent); + return true; + } final Matcher matcher = pattern.matcher(url); if (!matcher.matches()) { return false; @@ -124,14 +130,29 @@ private static boolean handleUrl(final Context context, } if (linkType == StreamingService.LinkType.STREAM && seconds != -1) { - Intent intent = new Intent(ACTION_SEEK_TO); - intent.putExtra("Timestamp", seconds); - context.sendBroadcast(intent); + return playOnMain(context, matchedUrl, service, seconds, disposables); } else { NavigationHelper.openRouterActivity(context, matchedUrl); } return true; } + public static boolean handleUrl(final Context context, + @NonNull final String url, + @NonNull final CompositeDisposable disposables) { + final StreamingService service; + final StreamingService.LinkType linkType; + try { + service = NewPipe.getServiceByUrl(url); + linkType = service.getLinkTypeByUrl(url); + if (linkType == StreamingService.LinkType.NONE) { + return false; + } + } catch (final ExtractionException e) { + return false; + } + NavigationHelper.openRouterActivity(context, url); + return true; + } /** * Play a content in the floating player. diff --git a/app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java b/app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java index 2672c615e..606f40155 100644 --- a/app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java +++ b/app/src/main/java/org/schabi/newpipe/util/external_communication/TextLinkifier.java @@ -1,6 +1,7 @@ package org.schabi.newpipe.util.external_communication; import android.content.Context; +import android.content.Intent; import android.text.SpannableStringBuilder; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; @@ -28,7 +29,7 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable; import io.reactivex.rxjava3.schedulers.Schedulers; -import static org.schabi.newpipe.util.external_communication.InternalUrlsHandler.playOnPopup; +import static org.schabi.newpipe.fragments.detail.VideoDetailFragment.ACTION_SEEK_TO; public final class TextLinkifier { public static final String TAG = TextLinkifier.class.getSimpleName(); @@ -192,12 +193,9 @@ private static void addClickListenersOnTimestamps(final Context context, new ClickableSpan() { @Override public void onClick(@NonNull final View view) { - playOnPopup( - context, - relatedInfo.getUrl(), - relatedInfo.getService(), - timestampMatchDTO.seconds(), - disposables); + Intent intent = new Intent(ACTION_SEEK_TO); + intent.putExtra("Timestamp", timestampMatchDTO.seconds()); + context.sendBroadcast(intent); } }, timestampMatchDTO.timestampStart(), @@ -246,7 +244,11 @@ private static void changeIntentsOfDescriptionLinks(final TextView textView, final String url = span.getURL(); final ClickableSpan clickableSpan = new ClickableSpan() { public void onClick(@NonNull final View view) { - ShareUtils.openUrlInBrowser(context, url, false); + if (!InternalUrlsHandler.handleUrlDescriptionTimestamp( + new CompositeDisposable(), context, url) + && !InternalUrlsHandler.handleUrl(context, url, new CompositeDisposable())) { + ShareUtils.openUrlInBrowser(context, url, false); + } } };