mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-06-29 02:26:05 +01:00
Inline useNewLinkifier flag.
This commit is contained in:
+2
-2
@@ -11,10 +11,10 @@ import android.text.Spanned
|
||||
import android.text.style.URLSpan
|
||||
import android.text.util.Linkify
|
||||
import androidx.core.text.util.LinkifyCompat
|
||||
import org.signal.core.util.addDetectedLinks
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.util.InterceptableLongClickCopyLinkSpan
|
||||
import org.thoughtcrime.securesms.util.LinkUtil
|
||||
import org.thoughtcrime.securesms.util.Linkification
|
||||
import org.thoughtcrime.securesms.util.UrlClickHandler
|
||||
import org.thoughtcrime.securesms.util.hasOnlyThumbnail
|
||||
|
||||
@@ -34,7 +34,7 @@ object V2ConversationItemUtils {
|
||||
}
|
||||
|
||||
LinkifyCompat.addLinks(messageBody, Linkify.EMAIL_ADDRESSES or Linkify.PHONE_NUMBERS)
|
||||
Linkification.applyWebUrlSpans(messageBody)
|
||||
messageBody.addDetectedLinks()
|
||||
|
||||
messageBody.getSpans(0, messageBody.length, URLSpan::class.java).forEach { urlSpan ->
|
||||
val url = urlSpan.url
|
||||
|
||||
@@ -15,10 +15,10 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.text.util.LinkifyCompat;
|
||||
|
||||
import org.signal.core.util.LinkifierSpannableExtensionsKt;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
|
||||
import org.thoughtcrime.securesms.util.LinkUtil;
|
||||
import org.thoughtcrime.securesms.util.Linkification;
|
||||
import org.thoughtcrime.securesms.util.LongClickCopySpan;
|
||||
|
||||
public final class GroupDescriptionUtil {
|
||||
@@ -38,7 +38,7 @@ public final class GroupDescriptionUtil {
|
||||
|
||||
if (linkify) {
|
||||
LinkifyCompat.addLinks(descriptionSpannable, Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS);
|
||||
Linkification.applyWebUrlSpans(descriptionSpannable);
|
||||
LinkifierSpannableExtensionsKt.addDetectedLinks(descriptionSpannable);
|
||||
|
||||
for (URLSpan urlSpan : descriptionSpannable.getSpans(0, descriptionSpannable.length(), URLSpan.class)) {
|
||||
String url = urlSpan.getURL();
|
||||
|
||||
@@ -11,7 +11,6 @@ import java.util.stream.Collectors;
|
||||
import org.signal.core.util.Linkifier;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.LinkUtil;
|
||||
import org.thoughtcrime.securesms.util.Linkification;
|
||||
import org.signal.core.util.Util;
|
||||
import org.whispersystems.signalservice.api.util.OptionalUtil;
|
||||
|
||||
@@ -51,7 +50,7 @@ public final class LinkPreviewUtil {
|
||||
* @return All URLs allowed as previews in the source text.
|
||||
*/
|
||||
public static @NonNull Links findValidPreviewUrls(@NonNull String text) {
|
||||
List<Linkifier.DetectedLink> detected = Linkification.findWebLinks(text);
|
||||
List<Linkifier.DetectedLink> detected = Linkifier.findLinks(text);
|
||||
if (detected.isEmpty()) {
|
||||
return Links.EMPTY;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import org.thoughtcrime.securesms.components.ConversationSearchBottomBar;
|
||||
import org.thoughtcrime.securesms.components.ProgressCard;
|
||||
import org.thoughtcrime.securesms.components.SearchView;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.Linkification;
|
||||
import org.thoughtcrime.securesms.util.LongClickCopySpan;
|
||||
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
|
||||
import org.signal.core.ui.util.ThemeUtil;
|
||||
@@ -458,7 +457,7 @@ public class SubmitDebugLogActivity extends BaseActivity {
|
||||
TextView dialogView = new TextView(builder.getContext());
|
||||
LongClickCopySpan longClickUrl = new LongClickCopySpan(url);
|
||||
|
||||
for (Linkifier.DetectedLink link : Linkification.findWebLinks(dialogText)) {
|
||||
for (Linkifier.DetectedLink link : Linkifier.findLinks(dialogText)) {
|
||||
spannableDialogText.setSpan(longClickUrl, link.getStart(), link.getEnd(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,11 +37,11 @@ import org.signal.core.ui.compose.ComposeBottomSheetDialogFragment
|
||||
import org.signal.core.ui.compose.DayNightPreviews
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.SignalIcons
|
||||
import org.signal.core.util.addDetectedLinks
|
||||
import org.signal.core.util.getParcelableCompat
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.util.Linkification
|
||||
import org.thoughtcrime.securesms.util.viewModel
|
||||
import org.signal.core.ui.R as CoreUiR
|
||||
|
||||
@@ -163,7 +163,7 @@ private fun ViewNoteBottomSheetContent(
|
||||
if (!isInspection) {
|
||||
LinkifyCompat.addLinks(spannable, Linkify.EMAIL_ADDRESSES or Linkify.PHONE_NUMBERS)
|
||||
}
|
||||
Linkification.applyWebUrlSpans(spannable)
|
||||
spannable.addDetectedLinks()
|
||||
it.text = spannable
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -52,6 +52,7 @@ import org.signal.core.ui.permissions.Permissions
|
||||
import org.signal.core.util.Debouncer
|
||||
import org.signal.core.util.DimensionUnit
|
||||
import org.signal.core.util.ServiceUtil
|
||||
import org.signal.core.util.addDetectedLinks
|
||||
import org.signal.core.util.concurrent.LifecycleDisposable
|
||||
import org.signal.core.util.dp
|
||||
import org.signal.core.util.getParcelableCompat
|
||||
@@ -95,7 +96,6 @@ import org.thoughtcrime.securesms.stories.viewer.views.StoryViewsBottomSheetDial
|
||||
import org.thoughtcrime.securesms.util.AvatarUtil
|
||||
import org.thoughtcrime.securesms.util.DateUtils
|
||||
import org.thoughtcrime.securesms.util.LinkUtil
|
||||
import org.thoughtcrime.securesms.util.Linkification
|
||||
import org.thoughtcrime.securesms.util.LongClickCopySpan
|
||||
import org.thoughtcrime.securesms.util.LongClickMovementMethod
|
||||
import org.thoughtcrime.securesms.util.Projection
|
||||
@@ -995,7 +995,7 @@ class StoryViewerPageFragment :
|
||||
|
||||
fun linkifyUrlLinks(spannable: Spannable) {
|
||||
LinkifyCompat.addLinks(spannable, Linkify.EMAIL_ADDRESSES or Linkify.PHONE_NUMBERS)
|
||||
Linkification.applyWebUrlSpans(spannable)
|
||||
spannable.addDetectedLinks()
|
||||
|
||||
spannable.getSpans(0, spannable.length, URLSpan::class.java).forEach { urlSpan ->
|
||||
val url = urlSpan.url
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2026 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.style.URLSpan
|
||||
import android.text.util.Linkify
|
||||
import androidx.core.text.util.LinkifyCompat
|
||||
import org.signal.core.util.Linkifier
|
||||
import org.signal.core.util.Linkifier.DetectedLink
|
||||
import org.signal.core.util.addDetectedLinks
|
||||
|
||||
/**
|
||||
* Temporary abstraction while we switch over to the new [Linkifier] via remote config.
|
||||
* When the remote config is off, we fallback to the pre-existing android link logic.
|
||||
*/
|
||||
object Linkification {
|
||||
|
||||
/**
|
||||
* Adds [URLSpan]s for web URLs in [spannable]. Returns `true` if at least one span was added.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun applyWebUrlSpans(spannable: Spannable): Boolean {
|
||||
return if (RemoteConfig.useNewLinkifier) {
|
||||
spannable.addDetectedLinks()
|
||||
} else {
|
||||
LinkifyCompat.addLinks(spannable, Linkify.WEB_URLS)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds web URLs in [text].
|
||||
*/
|
||||
@JvmStatic
|
||||
fun findWebLinks(text: CharSequence): List<DetectedLink> {
|
||||
if (RemoteConfig.useNewLinkifier) {
|
||||
return Linkifier.findLinks(text)
|
||||
}
|
||||
|
||||
val spannable = SpannableString(text)
|
||||
if (!LinkifyCompat.addLinks(spannable, Linkify.WEB_URLS)) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return spannable.getSpans(0, spannable.length, URLSpan::class.java).map { span ->
|
||||
DetectedLink(
|
||||
start = spannable.getSpanStart(span),
|
||||
end = spannable.getSpanEnd(span),
|
||||
url = span.url
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1402,17 +1402,6 @@ object RemoteConfig {
|
||||
hotSwappable = true
|
||||
)
|
||||
|
||||
/**
|
||||
* Whether to use our custom [org.signal.core.util.Linkifier] for web URL detection.
|
||||
*/
|
||||
@JvmStatic
|
||||
@get:JvmName("useNewLinkifier")
|
||||
val useNewLinkifier: Boolean by remoteBoolean(
|
||||
key = "android.useNewLinkifier",
|
||||
defaultValue = false,
|
||||
hotSwappable = true
|
||||
)
|
||||
|
||||
/**
|
||||
* Whether screen sharing is available during calls.
|
||||
*/
|
||||
|
||||
-17
@@ -1,34 +1,17 @@
|
||||
package org.thoughtcrime.securesms.linkpreview
|
||||
|
||||
import android.app.Application
|
||||
import io.mockk.every
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkStatic
|
||||
import org.junit.After
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
|
||||
@Suppress("ClassName")
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(manifest = Config.NONE, application = Application::class)
|
||||
class LinkPreviewUtilTest_findValidPreviewUrls {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
mockkStatic(RemoteConfig::class)
|
||||
every { RemoteConfig.useNewLinkifier } returns true
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
unmockkStatic(RemoteConfig::class)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun no_links() {
|
||||
val links = LinkPreviewUtil.findValidPreviewUrls("No links")
|
||||
|
||||
Reference in New Issue
Block a user