NewPipe-app-android/app/src/main/java/org/schabi/newpipe/util/CommentTextOnTouchListener....

135 lines
5.1 KiB
Java
Raw Normal View History

package org.schabi.newpipe.util;
2019-03-02 00:42:06 +01:00
import android.content.Context;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.Spanned;
import android.text.style.ClickableSpan;
2019-03-02 00:42:06 +01:00
import android.text.style.URLSpan;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
2019-03-02 00:42:06 +01:00
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.LinkHandlerFactory;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
2020-10-31 21:55:45 +01:00
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Single;
2020-10-31 21:55:45 +01:00
import io.reactivex.rxjava3.schedulers.Schedulers;
2019-03-02 00:42:06 +01:00
public class CommentTextOnTouchListener implements View.OnTouchListener {
public static final CommentTextOnTouchListener INSTANCE = new CommentTextOnTouchListener();
private static final Pattern TIMESTAMP_PATTERN = Pattern.compile("(.*)#timestamp=(\\d+)");
2019-03-02 00:42:06 +01:00
@Override
public boolean onTouch(final View v, final MotionEvent event) {
if (!(v instanceof TextView)) {
return false;
}
2020-08-16 10:24:58 +02:00
final TextView widget = (TextView) v;
final Object text = widget.getText();
if (text instanceof Spanned) {
2020-08-16 10:24:58 +02:00
final Spannable buffer = (Spannable) text;
2020-08-16 10:24:58 +02:00
final int action = event.getAction();
if (action == MotionEvent.ACTION_UP
|| action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
2020-08-16 10:24:58 +02:00
final Layout layout = widget.getLayout();
final int line = layout.getLineForVertical(y);
final int off = layout.getOffsetForHorizontal(line, x);
2020-08-16 10:24:58 +02:00
final ClickableSpan[] link = buffer.getSpans(off, off,
ClickableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
2019-03-02 00:42:06 +01:00
boolean handled = false;
if (link[0] instanceof URLSpan) {
2019-03-02 00:42:06 +01:00
handled = handleUrl(v.getContext(), (URLSpan) link[0]);
}
if (!handled) {
ShareUtils.openUrlInBrowser(v.getContext(),
((URLSpan) link[0]).getURL(), false);
}
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}
return true;
}
}
}
return false;
}
2019-03-02 00:42:06 +01:00
private boolean handleUrl(final Context context, final URLSpan urlSpan) {
2019-03-02 00:42:06 +01:00
String url = urlSpan.getURL();
int seconds = -1;
2020-08-16 10:24:58 +02:00
final Matcher matcher = TIMESTAMP_PATTERN.matcher(url);
if (matcher.matches()) {
url = matcher.group(1);
seconds = Integer.parseInt(matcher.group(2));
}
2020-08-16 10:24:58 +02:00
final StreamingService service;
final StreamingService.LinkType linkType;
2019-03-02 00:42:06 +01:00
try {
service = NewPipe.getServiceByUrl(url);
linkType = service.getLinkTypeByUrl(url);
2020-08-16 10:24:58 +02:00
} catch (final ExtractionException e) {
2019-03-02 00:42:06 +01:00
return false;
}
if (linkType == StreamingService.LinkType.NONE) {
2019-03-02 00:42:06 +01:00
return false;
}
if (linkType == StreamingService.LinkType.STREAM && seconds != -1) {
2019-03-02 00:42:06 +01:00
return playOnPopup(context, url, service, seconds);
} else {
2019-03-02 00:42:06 +01:00
NavigationHelper.openRouterActivity(context, url);
return true;
}
}
private boolean playOnPopup(final Context context, final String url,
final StreamingService service, final int seconds) {
2020-08-16 10:24:58 +02:00
final LinkHandlerFactory factory = service.getStreamLHFactory();
final String cleanUrl;
2019-03-02 00:42:06 +01:00
try {
cleanUrl = factory.getUrl(factory.getId(url));
2020-08-16 10:24:58 +02:00
} catch (final ParsingException e) {
2019-03-02 00:42:06 +01:00
return false;
}
2020-08-16 10:24:58 +02:00
final Single single
= ExtractorHelper.getStreamInfo(service.getServiceId(), cleanUrl, false);
2019-03-02 00:42:06 +01:00
single.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(info -> {
2020-08-16 10:24:58 +02:00
final PlayQueue playQueue
= new SinglePlayQueue((StreamInfo) info, seconds * 1000);
2019-04-13 09:31:32 +02:00
NavigationHelper.playOnPopupPlayer(context, playQueue, false);
2019-03-02 00:42:06 +01:00
});
return true;
}
}