correctly serialize custom spans to html (#2199)

This commit is contained in:
Konrad Pozniak 2021-06-14 11:00:35 +02:00 committed by GitHub
parent e84dec29b2
commit 31da851f28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 62 deletions

View file

@ -11,7 +11,7 @@ import android.text.util.Linkify
import android.widget.TextView import android.widget.TextView
import com.keylesspalace.tusky.databinding.ActivityAboutBinding import com.keylesspalace.tusky.databinding.ActivityAboutBinding
import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.di.Injectable
import com.keylesspalace.tusky.util.CustomURLSpan import com.keylesspalace.tusky.util.NoUnderlineURLSpan
import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.hide
class AboutActivity : BottomSheetActivity(), Injectable { class AboutActivity : BottomSheetActivity(), Injectable {
@ -63,7 +63,7 @@ private fun TextView.setClickableTextWithoutUnderlines(@StringRes textId: Int) {
val end = builder.getSpanEnd(span) val end = builder.getSpanEnd(span)
val flags = builder.getSpanFlags(span) val flags = builder.getSpanFlags(span)
val customSpan = object : CustomURLSpan(span.url) {} val customSpan = NoUnderlineURLSpan(span.url)
builder.removeSpan(span) builder.removeSpan(span)
builder.setSpan(customSpan, start, end, flags) builder.setSpan(customSpan, start, end, flags)

View file

@ -1,11 +0,0 @@
package com.keylesspalace.tusky.util
import android.text.TextPaint
import android.text.style.ClickableSpan
abstract class ClickableSpanNoUnderline : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.isUnderlineText = false
}
}

View file

@ -1,41 +0,0 @@
package com.keylesspalace.tusky.util;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextPaint;
import android.text.style.URLSpan;
import android.view.View;
public class CustomURLSpan extends URLSpan {
public CustomURLSpan(String url) {
super(url);
}
private CustomURLSpan(Parcel src) {
super(src);
}
public static final Parcelable.Creator<CustomURLSpan> CREATOR = new Parcelable.Creator<CustomURLSpan>() {
@Override
public CustomURLSpan createFromParcel(Parcel source) {
return new CustomURLSpan(source);
}
@Override
public CustomURLSpan[] newArray(int size) {
return new CustomURLSpan[size];
}
};
@Override
public void onClick(View view) {
LinkHelper.openLink(getURL(), view.getContext());
}
@Override public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
}

View file

@ -82,7 +82,7 @@ public class LinkHelper {
if (text.charAt(0) == '#') { if (text.charAt(0) == '#') {
final String tag = text.subSequence(1, text.length()).toString(); final String tag = text.subSequence(1, text.length()).toString();
customSpan = new ClickableSpanNoUnderline() { customSpan = new NoUnderlineURLSpan(span.getURL()) {
@Override @Override
public void onClick(@NonNull View widget) { listener.onViewTag(tag); } public void onClick(@NonNull View widget) { listener.onViewTag(tag); }
}; };
@ -102,7 +102,7 @@ public class LinkHelper {
} }
if (id != null) { if (id != null) {
final String accountId = id; final String accountId = id;
customSpan = new ClickableSpanNoUnderline() { customSpan = new NoUnderlineURLSpan(span.getURL()) {
@Override @Override
public void onClick(@NonNull View widget) { listener.onViewAccount(accountId); } public void onClick(@NonNull View widget) { listener.onViewAccount(accountId); }
}; };
@ -110,9 +110,9 @@ public class LinkHelper {
} }
if (customSpan == null) { if (customSpan == null) {
customSpan = new CustomURLSpan(span.getURL()) { customSpan = new NoUnderlineURLSpan(span.getURL()) {
@Override @Override
public void onClick(View widget) { public void onClick(@NonNull View widget) {
listener.onViewUrl(getURL()); listener.onViewUrl(getURL());
} }
}; };
@ -155,7 +155,7 @@ public class LinkHelper {
for (Status.Mention mention : mentions) { for (Status.Mention mention : mentions) {
String accountUsername = mention.getLocalUsername(); String accountUsername = mention.getLocalUsername();
final String accountId = mention.getId(); final String accountId = mention.getId();
ClickableSpan customSpan = new ClickableSpanNoUnderline() { ClickableSpan customSpan = new NoUnderlineURLSpan(mention.getUrl()) {
@Override @Override
public void onClick(@NonNull View widget) { listener.onViewAccount(accountId); } public void onClick(@NonNull View widget) { listener.onViewAccount(accountId); }
}; };
@ -181,7 +181,7 @@ public class LinkHelper {
} }
public static CharSequence createClickableText(String text, String link) { public static CharSequence createClickableText(String text, String link) {
URLSpan span = new CustomURLSpan(link); URLSpan span = new NoUnderlineURLSpan(link);
SpannableStringBuilder clickableText = new SpannableStringBuilder(text); SpannableStringBuilder clickableText = new SpannableStringBuilder(text);
clickableText.setSpan(span, 0, text.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); clickableText.setSpan(span, 0, text.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

View file

@ -0,0 +1,34 @@
/* Copyright 2021 Tusky Contributors
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.util
import android.text.TextPaint
import android.text.style.URLSpan
import android.view.View
open class NoUnderlineURLSpan(
url: String
) : URLSpan(url) {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.isUnderlineText = false
}
override fun onClick(view: View) {
LinkHelper.openLink(url, view.context)
}
}

View file

@ -117,8 +117,8 @@ private fun findEndOfPattern(string: String, result: FindCharsResult, pattern: P
private fun getSpan(matchType: FoundMatchType, string: String, colour: Int, start: Int, end: Int): CharacterStyle { private fun getSpan(matchType: FoundMatchType, string: String, colour: Int, start: Int, end: Int): CharacterStyle {
return when(matchType) { return when(matchType) {
FoundMatchType.HTTP_URL -> CustomURLSpan(string.substring(start, end)) FoundMatchType.HTTP_URL -> NoUnderlineURLSpan(string.substring(start, end))
FoundMatchType.HTTPS_URL -> CustomURLSpan(string.substring(start, end)) FoundMatchType.HTTPS_URL -> NoUnderlineURLSpan(string.substring(start, end))
else -> ForegroundColorSpan(colour) else -> ForegroundColorSpan(colour)
} }
} }