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 LinkHelper { private LinkHelper() { } /** * Create web links for contents with an HTML description. *

* This will call * {@link LinkHelper#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. *

* This will call * {@link LinkHelper#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. *

* This will call * {@link LinkHelper#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. *

* 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)}. *

* 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()); } }