fix: Improve display of "obscured" links (#194)
The previous code (a) used an emoji as the prefix character when showing the destination of an obscured link, and (b) made the destination part of the link anchor text. Using an emoji was a problem because the user can use different emoji sets and it can give strange results. Making the destination part of the link text made it difficult to distinguish at a glance where one link ends and another starts. Fix the emoji problem by replacing the emoji with a drawable. Fix the destination problem by changing the string resource so it only includes the destination part, and inserting it at the end of the link instead of replacing the whole link. This means the disclosed destination is not clickable, does not look like part of the link, and stands out more.
This commit is contained in:
parent
566b23ed06
commit
5a41cbd40f
|
@ -66,6 +66,9 @@ fun CharSequence.emojify(emojis: List<Emoji>?, view: View, animate: Boolean): Ch
|
|||
class EmojiSpan(val viewWeakReference: WeakReference<View>) : ReplacementSpan() {
|
||||
var imageDrawable: Drawable? = null
|
||||
|
||||
/** Scale the emoji up/down from the calculated size */
|
||||
var scaleFactor = 1.0f
|
||||
|
||||
override fun getSize(paint: Paint, text: CharSequence, start: Int, end: Int, fm: Paint.FontMetricsInt?): Int {
|
||||
if (fm != null) {
|
||||
/* update FontMetricsInt or otherwise span does not get drawn when
|
||||
|
@ -77,7 +80,7 @@ class EmojiSpan(val viewWeakReference: WeakReference<View>) : ReplacementSpan()
|
|||
fm.bottom = metrics.bottom
|
||||
}
|
||||
|
||||
return (paint.textSize * 1.2).toInt()
|
||||
return (paint.textSize * 1.2 * scaleFactor).toInt()
|
||||
}
|
||||
|
||||
override fun draw(canvas: Canvas, text: CharSequence, start: Int, end: Int, x: Float, top: Int, y: Int, bottom: Int, paint: Paint) {
|
||||
|
@ -100,6 +103,9 @@ class EmojiSpan(val viewWeakReference: WeakReference<View>) : ReplacementSpan()
|
|||
emojiWidth *= drawableSpace / emojiHeight
|
||||
emojiHeight = drawableSpace
|
||||
}
|
||||
emojiHeight *= scaleFactor
|
||||
emojiWidth *= scaleFactor
|
||||
|
||||
drawable.setBounds(0, 0, emojiWidth.toInt(), emojiHeight.toInt())
|
||||
|
||||
// vertically center the emoji in the line
|
||||
|
|
|
@ -44,13 +44,19 @@ import app.pachli.entity.Status.Mention
|
|||
import app.pachli.interfaces.LinkListener
|
||||
import app.pachli.settings.PrefKeys
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.mikepenz.iconics.IconicsColor
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.IconicsSize
|
||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
import com.mikepenz.iconics.utils.color
|
||||
import com.mikepenz.iconics.utils.size
|
||||
import java.lang.ref.WeakReference
|
||||
import java.net.URI
|
||||
import java.net.URISyntaxException
|
||||
|
||||
fun getDomain(urlString: String?): String {
|
||||
val host = urlString?.toUri()?.host
|
||||
val host = urlString?.toUri()?.host ?: return ""
|
||||
return when {
|
||||
host == null -> ""
|
||||
host.startsWith("www.") -> host.substring(4)
|
||||
else -> host
|
||||
}
|
||||
|
@ -66,7 +72,7 @@ fun getDomain(urlString: String?): String {
|
|||
* @param listener to notify about particular spans that are clicked
|
||||
*/
|
||||
fun setClickableText(view: TextView, content: CharSequence, mentions: List<Mention>, tags: List<HashTag>?, listener: LinkListener) {
|
||||
val spannableContent = markupHiddenUrls(view.context, content)
|
||||
val spannableContent = markupHiddenUrls(view, content)
|
||||
|
||||
view.text = spannableContent.apply {
|
||||
getSpans(0, spannableContent.length, URLSpan::class.java).forEach {
|
||||
|
@ -77,7 +83,7 @@ fun setClickableText(view: TextView, content: CharSequence, mentions: List<Menti
|
|||
}
|
||||
|
||||
@VisibleForTesting
|
||||
fun markupHiddenUrls(context: Context, content: CharSequence): SpannableStringBuilder {
|
||||
fun markupHiddenUrls(textView: TextView, content: CharSequence): SpannableStringBuilder {
|
||||
val spannableContent = SpannableStringBuilder(content)
|
||||
val originalSpans = spannableContent.getSpans(0, content.length, URLSpan::class.java)
|
||||
val obscuredLinkSpans = originalSpans.filter {
|
||||
|
@ -96,12 +102,39 @@ fun markupHiddenUrls(context: Context, content: CharSequence): SpannableStringBu
|
|||
}
|
||||
}
|
||||
|
||||
for (span in obscuredLinkSpans) {
|
||||
val start = spannableContent.getSpanStart(span)
|
||||
val end = spannableContent.getSpanEnd(span)
|
||||
val originalText = spannableContent.subSequence(start, end)
|
||||
val replacementText = context.getString(R.string.url_domain_notifier, originalText, getDomain(span.url))
|
||||
spannableContent.replace(start, end, replacementText) // this also updates the span locations
|
||||
if (obscuredLinkSpans.isNotEmpty()) {
|
||||
val context = textView.context
|
||||
|
||||
// Drawable to use to mark links. R.string.url_domain_notifier contains a Unicode emoji
|
||||
// ("🔗") that can render oddly depending on the user's choice of emoji set, so the emoji
|
||||
// is replaced with the drawable
|
||||
val iconLinkDrawable = IconicsDrawable(context, GoogleMaterial.Icon.gmd_open_in_new).apply {
|
||||
size = IconicsSize.px(textView.textSize)
|
||||
color = IconicsColor.colorInt(textView.currentTextColor)
|
||||
}
|
||||
val iconLength = "🔗".length
|
||||
|
||||
for (span in obscuredLinkSpans) {
|
||||
val end = spannableContent.getSpanEnd(span)
|
||||
val replacementText = context.getString(R.string.url_domain_notifier, getDomain(span.url))
|
||||
spannableContent.insert(end, replacementText)
|
||||
}
|
||||
|
||||
var iconIndex = -1
|
||||
while (true) {
|
||||
iconIndex = spannableContent.indexOf("🔗", iconIndex + 1)
|
||||
if (iconIndex == -1) break
|
||||
|
||||
// ImageSpan has bugs when trying to align the drawable with text, so use
|
||||
// EmojiSpan which centre-aligns it correctly. EmojiSpan default is to scale
|
||||
// the drawable to fill the text height, set scaleFactor to get a more
|
||||
// reasonable size.
|
||||
val linkSpan = EmojiSpan(WeakReference(textView)).apply {
|
||||
imageDrawable = iconLinkDrawable
|
||||
scaleFactor = 0.7f
|
||||
}
|
||||
spannableContent.setSpan(linkSpan, iconIndex, iconIndex + iconLength, 0)
|
||||
}
|
||||
}
|
||||
|
||||
return spannableContent
|
||||
|
|
|
@ -613,7 +613,7 @@
|
|||
<string name="description_post_language">لغة المنشور</string>
|
||||
<string name="delete_scheduled_post_warning">هل تريد حذف هذا المنشور المُبَرمَج؟</string>
|
||||
<string name="tips_push_notification_migration">أعد تسجيل الدخول إلى جميع الحسابات لتمكين دعم الإشعارات.</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_set_focus">ضبط نقطة التركيز</string>
|
||||
<string name="action_edit_image">تعديل الصورة</string>
|
||||
<string name="action_add_reaction">إضافة رد فعل</string>
|
||||
|
|
|
@ -596,7 +596,7 @@
|
|||
<string name="wellbeing_hide_stats_posts">Схаваць колькасную статыстыку допісаў</string>
|
||||
<string name="wellbeing_hide_stats_profile">Схаваць колькасную статыстыку профіляў</string>
|
||||
<string name="report_category_violation">Парушэнне правіла</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="instance_rule_title">Правілы %s</string>
|
||||
<string name="language_display_name_format">%s (%s)</string>
|
||||
<string name="delete_scheduled_post_warning">Выдаліць гэты запланаваны допіс\?</string>
|
||||
|
|
|
@ -580,7 +580,7 @@
|
|||
<string name="action_unfollow_hashtag_format">Deixar de seguir #%s\?</string>
|
||||
<string name="compose_unsaved_changes">Tens canvis no desats.</string>
|
||||
<string name="set_focus_description">Toqueu o arrossegueu el cercle per triar el punt focal que sempre serà visible a les miniatures.</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="pref_title_show_self_username">Mostra el nom d\'usuari a les barres d\'eines</string>
|
||||
<string name="action_set_focus">Estableix el punt d\'enfocament</string>
|
||||
<string name="description_login">Funciona en la majoria dels casos. No es filtra cap dada a altres aplicacions.</string>
|
||||
|
|
|
@ -525,7 +525,7 @@
|
|||
<string name="duration_14_days">14 dní</string>
|
||||
<string name="duration_30_days">30 dní</string>
|
||||
<string name="drafts_post_reply_removed">Příspěvek, na který jste připravili odpověď, byl odstraněn</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_set_focus">Nastavit bod zaostření</string>
|
||||
<string name="tips_push_notification_migration">Znovu se přihlaste ke všem účtům, abyste povolili podporu push oznámení.</string>
|
||||
<string name="dialog_push_notification_migration">Aby bylo možné používat push oznámení prostřednictvím UnifiedPush, Pachli potřebuje oprávnění k odběru oznámení na vašem serveru Mastodon. To vyžaduje opětovné přihlášení ke změně rozsahů OAuth udělených aplikaci Pachli. Použitím možnosti opětovného přihlášení zde nebo v předvolbách účtu zachováte všechny vaše místní koncepty a mezipaměť.</string>
|
||||
|
|
|
@ -304,7 +304,7 @@
|
|||
<string name="filter_expiration_format">%s (%s)</string>
|
||||
<string name="notification_clear_text">Ydych chi\'n siŵr eich bod chi am glirio\'ch holl hysbysiadau\'n barhaol\?</string>
|
||||
<string name="error_multimedia_size_limit">Ni all ffeiliau fideo a sain fod yn fwy na %s MB.</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="error_following_hashtag_format">Gwall wrth ddilyn #%s</string>
|
||||
<string name="error_unfollowing_hashtag_format">Gwall wrth ddad-ddilyn #%s</string>
|
||||
<string name="action_unmute_domain">Dad-dewi %s</string>
|
||||
|
|
|
@ -553,7 +553,7 @@
|
|||
<string name="pref_show_self_username_never">Niemals</string>
|
||||
<string name="filter_expiration_format">%s (%s)</string>
|
||||
<string name="description_post_language">Sprache des Beitrags</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_set_focus">Fokuspunkt setzen</string>
|
||||
<string name="action_add_reaction">Reaktion hinzufügen</string>
|
||||
<string name="failed_to_remove_from_list">Das Konto konnte nicht aus der Liste entfernt werden</string>
|
||||
|
|
|
@ -553,5 +553,5 @@
|
|||
<string name="description_post_language">Mesaĝolingvo</string>
|
||||
<string name="dialog_push_notification_migration">Por ricevi sciigoj per UnifiedPush, Pachli bezonas taŭgan permeson el Mastodon-servilo. Tio postulas re-ensaluton por ŝanĝi OAuth-rajtoj donitaj al Pachli. Se vi uzas la opcion re-ensaluti ĉi tie aŭ en la agordoj de la konto, viaj malnetoj kaj kaŝmemoroj estos konservitaj.</string>
|
||||
<string name="dialog_push_notification_migration_other_accounts">Vi re-ensalutis en tiu konto por doni sciigo-permeson al Pachli. Vi havas tamen aliajn kontojn, ĉe kiuj vi devas re-sensaluti. Iru al ili, kaj re-ensalutu por ebligi ricevon de sciigoj per UnifiedPush.</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
</resources>
|
||||
|
|
|
@ -551,7 +551,7 @@
|
|||
<string name="failed_to_pin">Fallo al fijar</string>
|
||||
<string name="failed_to_unpin">Fallo al quitarlo</string>
|
||||
<string name="pref_show_self_username_disambiguate">Cuando hay varias cuentas ingresadas</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="notification_sign_up_description">Notificaciones de nuevos usuarios</string>
|
||||
<string name="notification_update_name">Ediciones de una publicación</string>
|
||||
<string name="notification_update_description">Notificaciones cuando se editan publicaciones con las que has interactuado</string>
|
||||
|
|
|
@ -542,7 +542,7 @@
|
|||
<string name="pref_show_self_username_disambiguate">هنگام ورود چندین حساب</string>
|
||||
<string name="pref_show_self_username_never">هرگز</string>
|
||||
<string name="pref_title_show_self_username">نمایش نام کاربری در نوارابزارها</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_add_reaction">افزودن واکنش</string>
|
||||
<string name="action_set_focus">تنظیم نقطهٔ تمرکز</string>
|
||||
<string name="duration_no_change">(بدون تغییر)</string>
|
||||
|
|
|
@ -554,7 +554,7 @@
|
|||
<string name="pref_show_self_username_never">Jamais</string>
|
||||
<string name="description_post_language">Langue du message</string>
|
||||
<string name="duration_no_change">(Aucune modification)</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_add_reaction">ajouter une réaction</string>
|
||||
<string name="instance_rule_title">%s règles</string>
|
||||
<string name="a11y_label_loading_thread">Chargement du fil</string>
|
||||
|
|
|
@ -555,7 +555,7 @@
|
|||
<string name="pref_show_self_username_disambiguate">Nuair a bhios iomadh cunntas air an clàradh a-steach</string>
|
||||
<string name="pref_show_self_username_never">Chan ann idir</string>
|
||||
<string name="filter_expiration_format">%s (%s)</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_set_focus">Suidhich puing an fhòcais</string>
|
||||
<string name="delete_scheduled_post_warning">A bheil thu airson am post sgeidealaichte seo a sguabadh às\?</string>
|
||||
<string name="instance_rule_info">Le clàradh a-steach, bidh tu ag aontachadh ri riaghailtean %s.</string>
|
||||
|
|
|
@ -527,7 +527,7 @@
|
|||
<string name="filter_expiration_format">%s (%s)</string>
|
||||
<string name="error_multimedia_size_limit">Os ficheiros de vídeo e audio non poden superar os %s MB.</string>
|
||||
<string name="description_post_language">Idioma de publicación</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_set_focus">Establece foco</string>
|
||||
<string name="error_following_hashtag_format">Erro ao seguir #%s</string>
|
||||
<string name="error_unfollowing_hashtag_format">Error ao retirar seguimento de #%s</string>
|
||||
|
|
|
@ -541,7 +541,7 @@
|
|||
<string name="pref_show_self_username_disambiguate">Ha több fiók is be van jelentkezve</string>
|
||||
<string name="pref_show_self_username_never">Soha</string>
|
||||
<string name="duration_no_change">(Nincs változás)</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_set_focus">Fókuszpont beállítása</string>
|
||||
<string name="error_following_hashtag_format">Hiba a #%s követésekor</string>
|
||||
<string name="error_unfollowing_hashtag_format">Hiba a #%s követésének befejezésekor</string>
|
||||
|
|
|
@ -539,7 +539,7 @@
|
|||
<string name="failed_to_unpin">Mistókst að losa</string>
|
||||
<string name="pref_show_self_username_always">Alltaf</string>
|
||||
<string name="pref_show_self_username_disambiguate">Þegar er skráð inn á mörgum aðgöngum</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_set_focus">Setja virknistað</string>
|
||||
<string name="pref_show_self_username_never">Aldrei</string>
|
||||
<string name="pref_title_show_self_username">Birta notandanafn á verkfærastikum</string>
|
||||
|
|
|
@ -563,7 +563,7 @@
|
|||
<string name="pref_show_self_username_disambiguate">Quando connesso con più account</string>
|
||||
<string name="duration_no_change">(nessuna modifica)</string>
|
||||
<string name="pref_title_show_self_username">Mostra nome utente nelle barre strumenti</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_add_or_remove_from_list">Aggiunti o rimuovi dalla lista</string>
|
||||
<string name="failed_to_add_to_list">Aggiunta dell\'account alla lista fallita</string>
|
||||
<string name="failed_to_remove_from_list">Rimozione dell\'account dalla lista fallita</string>
|
||||
|
|
|
@ -493,7 +493,7 @@
|
|||
<string name="error_multimedia_size_limit">ビデオと音声ファイルのサイズは %s MB を超えることはできません。</string>
|
||||
<string name="error_image_edit_failed">画像が編集できませんでした。</string>
|
||||
<string name="title_login">ログイン</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_edit_image">画像の編集</string>
|
||||
<string name="instance_rule_title">%s のルール</string>
|
||||
<string name="error_following_hashtags_unsupported">このインスタンスはハッシュタグのフォローに対応していません。</string>
|
||||
|
|
|
@ -257,7 +257,7 @@
|
|||
<string name="pref_title_http_proxy_server">HTTP starpniekserveris</string>
|
||||
<string name="pref_title_http_proxy_port_message">Portam būtu jābūt starp %d un %d</string>
|
||||
<string name="action_view_account_preferences">Konta iestatījumi</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="mute_domain_warning">Vai tiešām vēlaties bloķēt visu %s\? Šī domēna saturs netiks rādīts ne publiskajās laika līnijās, ne paziņojumos. Jūsu sekotāji no šī domēna tiks noņemti.</string>
|
||||
<string name="send_post_notification_saved_content">Ieraksta kopija tika saglabāta tavos melnrakstos</string>
|
||||
<string name="restart_emoji">Lai pielietotu šīs izmaiņas, ir jāpārstartē Pachli</string>
|
||||
|
|
|
@ -531,7 +531,7 @@
|
|||
<string name="filter_expiration_format">%s (%s)</string>
|
||||
<string name="duration_no_change">(Ingen endring)</string>
|
||||
<string name="description_post_language">Innleggspråk</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_set_focus">Sett fokuspunkt</string>
|
||||
<string name="set_focus_description">Trykk eller dra sirkelen for å velge fokuspunktet som alltid skal være synlig i miniatyrbilder.</string>
|
||||
<string name="pref_show_self_username_always">Alltid</string>
|
||||
|
|
|
@ -535,7 +535,7 @@
|
|||
<string name="set_focus_description">Tik of sleep de cirkel naar een centraal focuspunt dat op elke thumbnail zichtbaar moet blijven.</string>
|
||||
<string name="dialog_push_notification_migration">Om pushmeldingen via UnifiedPush te kunnen gebruiken, moet Pachli zich op meldingen van jouw Mastodon-server abonneren. Dit betekent dat je opnieuw moet inloggen om de OAuth-toestemmingen voor Pachli te wijzigen. Het hier of onder accountvoorkeuren opnieuw inloggen behoudt jouw lokale concepten en buffer.</string>
|
||||
<string name="dialog_push_notification_migration_other_accounts">Je hebt opnieuw op jouw huidige account ingelogd om toestemming voor pushmeldingen aan Pachli te verlenen. Je hebt echter nog andere accounts die nog niet op deze manier zijn overgezet. Ga naar deze accounts en log één voor één opnieuw in om UnifiedPush-meldingen ook daar in te schakelen.</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="pref_show_self_username_always">Altijd</string>
|
||||
<string name="pref_show_self_username_disambiguate">Wanneer meerdere accounts zijn ingelogd</string>
|
||||
<string name="pref_show_self_username_never">Nooit</string>
|
||||
|
|
|
@ -515,7 +515,7 @@
|
|||
<string name="pachli_compose_post_quicksetting_label">Compausar una publicacion</string>
|
||||
<string name="account_date_joined">Arribada del %1$s</string>
|
||||
<string name="saving_draft">Enregistrament del borrolhon…</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="error_image_edit_failed">Se podiá pas modificar l’imatge.</string>
|
||||
<string name="pref_title_wellbeing_mode">Benestar</string>
|
||||
<string name="duration_no_change">(Cap de modificacion)</string>
|
||||
|
|
|
@ -560,7 +560,7 @@
|
|||
<string name="error_multimedia_size_limit">Pliki wideo i audio nie mogą przekraczać rozmiarem %s MB.</string>
|
||||
<string name="filter_expiration_format">%s (%s)</string>
|
||||
<string name="description_post_language">Język wpisu</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="duration_no_change">(bez zmian)</string>
|
||||
<string name="error_following_hashtag_format">Wystąpił błąd podczas obserwowania #%s</string>
|
||||
<string name="error_unfollowing_hashtag_format">Wystąpił błąd podczas odobserwowywania #%s</string>
|
||||
|
|
|
@ -560,7 +560,7 @@
|
|||
<string name="report_category_violation">Violação de regra</string>
|
||||
<string name="report_category_spam">Spam</string>
|
||||
<string name="report_category_other">Outros</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="pref_show_self_username_disambiguate">Quando várias contas estão conectadas</string>
|
||||
<string name="pref_title_http_proxy_port_message">A porta deve estar entre %d e %d</string>
|
||||
<string name="status_count_one_plus">1+</string>
|
||||
|
|
|
@ -541,7 +541,7 @@
|
|||
<string name="set_focus_description">Toca ou arrasta o círculo para escolher o ponto de focagem que estará sempre visível nas pré-visualizações.</string>
|
||||
<string name="filter_expiration_format">%s(%s)</string>
|
||||
<string name="duration_no_change">(Sem alteração)</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="pref_show_self_username_always">Sempre</string>
|
||||
<string name="pref_show_self_username_disambiguate">Quando autenticado em várias contas</string>
|
||||
<string name="pref_show_self_username_never">Nunca</string>
|
||||
|
|
|
@ -469,7 +469,7 @@
|
|||
<string name="duration_365_days">३६५ दिनानि</string>
|
||||
<string name="duration_no_change">(परिवर्तनं नास्ति)</string>
|
||||
<string name="review_notifications">सूचनाः सम्दृश्यन्ताम्</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="pref_show_self_username_never">न कदापि</string>
|
||||
<string name="pref_default_post_language">पूर्वनिविष्टा प्रकाशका भाषा</string>
|
||||
<string name="notification_report_name">आवेदनानि</string>
|
||||
|
|
|
@ -263,5 +263,5 @@
|
|||
<string name="action_links">සබැඳි</string>
|
||||
<string name="pref_title_browser_settings">අතිරික්සුව</string>
|
||||
<string name="abbreviated_seconds_ago">තත්. %d</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
</resources>
|
||||
|
|
|
@ -506,7 +506,7 @@
|
|||
<string name="dialog_push_notification_migration_other_accounts">Du har loggat in igen på ditt konto för att ge Pachli tillgång till push-prenumeration. Dock har du andra konton som inte har migrerats såhär ännu. Växla till dem och logga in igen för att aktivera stöd för UnifiedPush-notiser.</string>
|
||||
<string name="action_unsubscribe_account">Sluta prenumerera</string>
|
||||
<string name="description_post_language">Inläggsspråk</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="pref_show_self_username_disambiguate">När flera konton är inloggade</string>
|
||||
<string name="pref_show_self_username_never">Aldrig</string>
|
||||
<string name="notification_sign_up_name">Registreringar</string>
|
||||
|
|
|
@ -509,7 +509,7 @@
|
|||
<string name="duration_180_days">180 gün</string>
|
||||
<string name="duration_60_days">60 gün</string>
|
||||
<string name="duration_90_days">90 gün</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="pref_default_post_language">Varsayılan gönderme dili</string>
|
||||
<string name="notification_report_name">Raporlar</string>
|
||||
<string name="notification_report_description">Denetleme raporlarıyla ilgili bildirimler</string>
|
||||
|
|
|
@ -550,7 +550,7 @@
|
|||
<string name="filter_expiration_format">%s (%s)</string>
|
||||
<string name="description_post_language">Мова допису</string>
|
||||
<string name="duration_no_change">(Не змінено)</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_set_focus">Налаштувати точку фокусування</string>
|
||||
<string name="pref_show_self_username_always">Завжди</string>
|
||||
<string name="set_focus_description">Торкніться або перетягніть коло, щоб вибрати точку фокусування, яку завжди буде видно на мініатюрах.</string>
|
||||
|
|
|
@ -518,7 +518,7 @@
|
|||
<string name="filter_expiration_format">%s (%s)</string>
|
||||
<string name="duration_no_change">(Không đổi)</string>
|
||||
<string name="description_post_language">Ngôn ngữ đăng</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_set_focus">Chọn tâm điểm</string>
|
||||
<string name="set_focus_description">Nhấn hoặc kéo vòng tròn để chọn tiêu điểm sẽ hiển thị trong hình thu nhỏ.</string>
|
||||
<string name="pref_title_show_self_username">Hiện URL của tôi trên tab</string>
|
||||
|
|
|
@ -532,7 +532,7 @@
|
|||
<string name="filter_expiration_format">%s (%s)</string>
|
||||
<string name="duration_no_change">(无更改)</string>
|
||||
<string name="description_post_language">嘟文语言</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="action_set_focus">设置焦点</string>
|
||||
<string name="set_focus_description">轻按或拖动圆圈选择始终在缩略图中可见的焦点。</string>
|
||||
<string name="pref_show_self_username_disambiguate">登录多个账户时</string>
|
||||
|
|
|
@ -517,7 +517,7 @@
|
|||
<string name="filter_expiration_format">%s (%s)</string>
|
||||
<string name="set_focus_description">輕按或拖動圓圈來選擇總是在縮圖中可視的關注點。</string>
|
||||
<string name="description_post_language">嘟文語言</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
<string name="compose_save_draft_loses_media">是否要儲存草稿?(當你重開草稿時附檔將會被再次上傳。)</string>
|
||||
<string name="pachli_compose_post_quicksetting_label">編寫嘟文</string>
|
||||
<string name="failed_to_pin">釘選失敗</string>
|
||||
|
|
|
@ -753,7 +753,7 @@
|
|||
<string name="tips_push_notification_migration">Re-login all accounts to enable push notification support.</string>
|
||||
<string name="dialog_push_notification_migration">In order to use push notifications via UnifiedPush, Pachli needs permission to subscribe to notifications on your Mastodon server. This requires a re-login to change the OAuth scopes granted to Pachli. Using the re-login option here or in "Account preferences" will preserve all of your local drafts and cache.</string>
|
||||
<string name="dialog_push_notification_migration_other_accounts">You have re-logged into your current account to grant push subscription permission to Pachli. However, you still have other accounts that have not been migrated this way. Switch to them and re-login one by one in order to enable UnifiedPush notifications support.</string>
|
||||
<string name="url_domain_notifier">%s (🔗 %s)</string>
|
||||
<string name="url_domain_notifier">\u0020(🔗 %s)</string>
|
||||
|
||||
<string name="delete_scheduled_post_warning">Delete this scheduled post?</string>
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package app.pachli.util
|
|||
import android.content.Context
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.URLSpan
|
||||
import android.widget.TextView
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import app.pachli.R
|
||||
|
@ -31,8 +32,11 @@ class LinkHelperTest {
|
|||
HashTag("mastodev", "https://example.com/Tags/mastodev"),
|
||||
)
|
||||
|
||||
private val textView: TextView
|
||||
get() = TextView(InstrumentationRegistry.getInstrumentation().targetContext)
|
||||
|
||||
private val context: Context
|
||||
get() = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
get() = textView.context
|
||||
|
||||
@Test
|
||||
fun whenSettingClickableText_mentionUrlsArePreserved() {
|
||||
|
@ -166,8 +170,8 @@ class LinkHelperTest {
|
|||
content.append(displayedContent, URLSpan(maliciousUrl), 0)
|
||||
val oldContent = content.toString()
|
||||
Assert.assertEquals(
|
||||
context.getString(R.string.url_domain_notifier, displayedContent, maliciousDomain),
|
||||
markupHiddenUrls(context, content).toString(),
|
||||
"$displayedContent${context.getString(R.string.url_domain_notifier, maliciousDomain)}",
|
||||
markupHiddenUrls(textView, content).toString(),
|
||||
)
|
||||
Assert.assertEquals(oldContent, content.toString())
|
||||
}
|
||||
|
@ -180,8 +184,8 @@ class LinkHelperTest {
|
|||
val content = SpannableStringBuilder()
|
||||
content.append(displayedContent, URLSpan(maliciousUrl), 0)
|
||||
Assert.assertEquals(
|
||||
context.getString(R.string.url_domain_notifier, displayedContent, maliciousDomain),
|
||||
markupHiddenUrls(context, content).toString(),
|
||||
"$displayedContent${context.getString(R.string.url_domain_notifier, maliciousDomain)}",
|
||||
markupHiddenUrls(textView, content).toString(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -194,9 +198,9 @@ class LinkHelperTest {
|
|||
content.append(displayedContent, URLSpan("https://$domain/foo/bar"), 0)
|
||||
}
|
||||
|
||||
val markedUpContent = markupHiddenUrls(context, content)
|
||||
val markedUpContent = markupHiddenUrls(textView, content)
|
||||
for (domain in domains) {
|
||||
Assert.assertTrue(markedUpContent.contains(context.getString(R.string.url_domain_notifier, displayedContent, domain)))
|
||||
Assert.assertTrue(markedUpContent.contains(context.getString(R.string.url_domain_notifier, domain)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,7 +217,7 @@ class LinkHelperTest {
|
|||
.append("$domain/", URLSpan("https://$domain"), 0)
|
||||
.append("$domain/", URLSpan("https://www.$domain"), 0)
|
||||
|
||||
val markedUpContent = markupHiddenUrls(context, content)
|
||||
val markedUpContent = markupHiddenUrls(textView, content)
|
||||
Assert.assertFalse(markedUpContent.contains("🔗"))
|
||||
}
|
||||
|
||||
|
@ -226,7 +230,7 @@ class LinkHelperTest {
|
|||
.append("Some Place | https://some.place/", URLSpan("https://some.place/"), 0)
|
||||
.append("Some Place https://some.place/path", URLSpan("https://some.place/path"), 0)
|
||||
|
||||
val markedUpContent = markupHiddenUrls(context, content)
|
||||
val markedUpContent = markupHiddenUrls(textView, content)
|
||||
Assert.assertFalse(markedUpContent.contains("🔗"))
|
||||
}
|
||||
|
||||
|
@ -239,7 +243,7 @@ class LinkHelperTest {
|
|||
.append("Another Place | https://another.place/", URLSpan("https://some.place/"), 0)
|
||||
.append("Another Place https://another.place/path", URLSpan("https://some.place/path"), 0)
|
||||
|
||||
val markedUpContent = markupHiddenUrls(context, content)
|
||||
val markedUpContent = markupHiddenUrls(textView, content)
|
||||
val asserts = listOf(
|
||||
"Another Place: another.place",
|
||||
"Another Place: another.place/",
|
||||
|
@ -248,7 +252,7 @@ class LinkHelperTest {
|
|||
"Another Place https://another.place/path",
|
||||
)
|
||||
asserts.forEach {
|
||||
Assert.assertTrue(markedUpContent.contains(context.getString(R.string.url_domain_notifier, it, "some.place")))
|
||||
Assert.assertTrue(markedUpContent.contains(context.getString(R.string.url_domain_notifier, "some.place")))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,7 +264,7 @@ class LinkHelperTest {
|
|||
builder.append(" ")
|
||||
}
|
||||
|
||||
val markedUpContent = markupHiddenUrls(context, builder)
|
||||
val markedUpContent = markupHiddenUrls(textView, builder)
|
||||
for (mention in mentions) {
|
||||
Assert.assertFalse(markedUpContent.contains("${getDomain(mention.url)})"))
|
||||
}
|
||||
|
@ -274,7 +278,7 @@ class LinkHelperTest {
|
|||
builder.append(" ")
|
||||
}
|
||||
|
||||
val markedUpContent = markupHiddenUrls(context, builder)
|
||||
val markedUpContent = markupHiddenUrls(textView, builder)
|
||||
for (mention in mentions) {
|
||||
Assert.assertFalse(markedUpContent.contains("${getDomain(mention.url)})"))
|
||||
}
|
||||
|
@ -288,7 +292,7 @@ class LinkHelperTest {
|
|||
builder.append(" ")
|
||||
}
|
||||
|
||||
val markedUpContent = markupHiddenUrls(context, builder)
|
||||
val markedUpContent = markupHiddenUrls(textView, builder)
|
||||
for (tag in tags) {
|
||||
Assert.assertFalse(markedUpContent.contains("${getDomain(tag.url)})"))
|
||||
}
|
||||
|
@ -302,7 +306,7 @@ class LinkHelperTest {
|
|||
builder.append(" ")
|
||||
}
|
||||
|
||||
val markedUpContent = markupHiddenUrls(context, builder)
|
||||
val markedUpContent = markupHiddenUrls(textView, builder)
|
||||
for (tag in tags) {
|
||||
Assert.assertFalse(markedUpContent.contains("${getDomain(tag.url)})"))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue