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…