diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostLinkEntryFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostLinkEntryFragment.kt index 8259919bef..c71621d6b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostLinkEntryFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediasend/v2/text/TextStoryPostLinkEntryFragment.kt @@ -8,11 +8,13 @@ import android.widget.EditText import androidx.constraintlayout.widget.Group import androidx.core.widget.addTextChangedListener import androidx.fragment.app.viewModels +import com.google.android.material.snackbar.Snackbar import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.components.KeyboardEntryDialogFragment import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel import org.thoughtcrime.securesms.stories.StoryLinkPreviewView +import org.thoughtcrime.securesms.util.LinkUtil import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.visible @@ -57,10 +59,18 @@ class TextStoryPostLinkEntryFragment : KeyboardEntryDialogFragment( val linkPreviewState = linkPreviewViewModel.linkPreviewState.value if (linkPreviewState != null) { val url = linkPreviewState.linkPreview.map { it.url }.orElseGet { linkPreviewState.activeUrlForError } - viewModel.setLinkPreview(url) - } - dismissAllowingStateLoss() + if (LinkUtil.isLegalUrl(url, false, true)) { + viewModel.setLinkPreview(url) + dismissAllowingStateLoss() + } else { + val snackbar = Snackbar.make(requireView(), R.string.TextStoryPostSendFragment__please_enter_a_valid_link, Snackbar.LENGTH_SHORT) + snackbar.anchorView = linkPreview + snackbar.show() + } + } else { + dismissAllowingStateLoss() + } } linkPreviewViewModel.linkPreviewState.observe(viewLifecycleOwner) { state -> diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/LinkUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/LinkUtil.java index ce8dcf5f2b..786f0d706a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/LinkUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/LinkUtil.java @@ -42,17 +42,17 @@ public final class LinkUtil { return url != null && !TextUtils.isEmpty(url.scheme()) && "https".equals(url.scheme()) && - isLegalUrl(linkUrl, false); + isLegalUrl(linkUrl, false, false); } /** * @return True if URL is valid, mostly useful for linkifying. */ public static boolean isLegalUrl(@NonNull String url) { - return isLegalUrl(url, true); + return isLegalUrl(url, true, false); } - private static boolean isLegalUrl(@NonNull String url, boolean skipTopLevelDomainValidation) { + public static boolean isLegalUrl(@NonNull String url, boolean skipTopLevelDomainValidation, boolean requireTopLevelDomain) { if (ILLEGAL_CHARACTERS_PATTERN.matcher(url).find()) { return false; } @@ -67,7 +67,8 @@ public final class LinkUtil { boolean validCharacters = ALL_ASCII_PATTERN.matcher(cleanedDomain).matches() || ALL_NON_ASCII_PATTERN.matcher(cleanedDomain).matches(); - boolean validTopLevelDomain = skipTopLevelDomainValidation || !INVALID_TOP_LEVEL_DOMAINS.contains(topLevelDomain); + boolean validTopLevelDomain = (skipTopLevelDomainValidation || !INVALID_TOP_LEVEL_DOMAINS.contains(topLevelDomain)) && + (!requireTopLevelDomain || topLevelDomain != null); return validCharacters && validTopLevelDomain; } else { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9fb83ea09a..efb11f3408 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4980,6 +4980,8 @@ Search An unexpected error occurred + + Please enter a valid link. All except…