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

118 lines
5.2 KiB
Java

package org.schabi.newpipe.util;
import android.content.Context;
import android.text.SpannableStringBuilder;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.view.View;
import android.widget.TextView;
import androidx.core.text.HtmlCompat;
import io.noties.markwon.Markwon;
import io.noties.markwon.linkify.LinkifyPlugin;
public final class TextLinkifier {
private TextLinkifier() {
}
/**
* Create web links for contents with an HTML description.
* <p>
* This will call
* {@link TextLinkifier#changeIntentsOfDescriptionLinks(Context, CharSequence, TextView)}
* after linked the URLs with {@link HtmlCompat#fromHtml(String, int)}.
*
* @param context the context to use
* @param htmlBlock the htmlBlock to be linked
* @param textView the TextView to set the htmlBlock linked
* @param htmlCompatFlag the int flag to be set when {@link HtmlCompat#fromHtml(String, int)}
* will be called
*/
public static void createLinksFromHtmlBlock(final Context context,
final String htmlBlock,
final TextView textView,
final int htmlCompatFlag) {
changeIntentsOfDescriptionLinks(context, HtmlCompat.fromHtml(htmlBlock, htmlCompatFlag),
textView);
}
/**
* Create web links for contents with a plain text description.
* <p>
* This will call
* {@link TextLinkifier#changeIntentsOfDescriptionLinks(Context, CharSequence, TextView)}
* after linked the URLs with {@link TextView#setAutoLinkMask(int)} and
* {@link TextView#setText(CharSequence, TextView.BufferType)}.
*
* @param context the context to use
* @param plainTextBlock the block of plain text to be linked
* @param textView the TextView to set the plain text block linked
*/
public static void createLinksFromPlainText(final Context context,
final String plainTextBlock,
final TextView textView) {
textView.setAutoLinkMask(Linkify.WEB_URLS);
textView.setText(plainTextBlock, TextView.BufferType.SPANNABLE);
changeIntentsOfDescriptionLinks(context, textView.getText(), textView);
}
/**
* Create web links for contents with a markdown description.
* <p>
* This will call
* {@link TextLinkifier#changeIntentsOfDescriptionLinks(Context, CharSequence, TextView)}
* after creating an {@link Markwon} object and using
* {@link Markwon#setMarkdown(TextView, String)}.
*
* @param context the context to use
* @param markdownBlock the block of markdown text to be linked
* @param textView the TextView to set the plain text block linked
*/
public static void createLinksFromMarkdownText(final Context context,
final String markdownBlock,
final TextView textView) {
final Markwon markwon = Markwon.builder(context).usePlugin(LinkifyPlugin.create()).build();
markwon.setMarkdown(textView, markdownBlock);
changeIntentsOfDescriptionLinks(context, textView.getText(), textView);
}
/**
* Change links generated by libraries in the description of a content to a custom link action.
* <p>
* Instead of using an ACTION_VIEW intent in the description of a content, this method will
* parse the CharSequence and replace all current web links with
* {@link ShareUtils#openUrlInBrowser(Context, String, boolean)}.
* <p>
* This method is required in order to intercept links and maybe, show a confirmation dialog
* before opening a web link.
*
* @param context the context to use
* @param chars the CharSequence to be parsed
* @param textView the TextView in which the converted CharSequence will be applied
*/
private static void changeIntentsOfDescriptionLinks(final Context context,
final CharSequence chars,
final TextView textView) {
final SpannableStringBuilder textBlockLinked = new SpannableStringBuilder(chars);
final URLSpan[] urls = textBlockLinked.getSpans(0, chars.length(), URLSpan.class);
for (final URLSpan span : urls) {
final ClickableSpan clickableSpan = new ClickableSpan() {
public void onClick(final View view) {
ShareUtils.openUrlInBrowser(context, span.getURL(), false);
}
};
textBlockLinked.setSpan(clickableSpan, textBlockLinked.getSpanStart(span),
textBlockLinked.getSpanEnd(span), textBlockLinked.getSpanFlags(span));
textBlockLinked.removeSpan(span);
}
textView.setText(textBlockLinked);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}