mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 21:15:48 +00:00
Allow users to confirm link preview on text story before it loads.
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
package org.thoughtcrime.securesms.linkpreview;
|
||||
|
||||
public class Link {
|
||||
|
||||
private final String url;
|
||||
private final int position;
|
||||
|
||||
public Link(String url, int position) {
|
||||
this.url = url;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.thoughtcrime.securesms.linkpreview
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
class Link(@JvmField val url: String, @JvmField val position: Int) : Parcelable
|
||||
@@ -15,7 +15,8 @@ class LinkPreviewState private constructor(
|
||||
@JvmField val isLoading: Boolean,
|
||||
private val hasLinks: Boolean,
|
||||
private val preview: LinkPreview?,
|
||||
@JvmField val error: LinkPreviewRepository.Error?
|
||||
@JvmField val error: LinkPreviewRepository.Error?,
|
||||
@JvmField val link: Link?
|
||||
) : Parcelable {
|
||||
|
||||
@IgnoredOnParcel
|
||||
@@ -30,15 +31,18 @@ class LinkPreviewState private constructor(
|
||||
return isLoading || hasLinks
|
||||
}
|
||||
|
||||
val url: String? = link?.url ?: preview?.url ?: activeUrlForError
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun forLoading(): LinkPreviewState {
|
||||
fun forLoading(link: Link): LinkPreviewState {
|
||||
return LinkPreviewState(
|
||||
activeUrlForError = null,
|
||||
isLoading = true,
|
||||
hasLinks = false,
|
||||
preview = null,
|
||||
error = null
|
||||
error = null,
|
||||
link = link
|
||||
)
|
||||
}
|
||||
|
||||
@@ -49,7 +53,8 @@ class LinkPreviewState private constructor(
|
||||
isLoading = false,
|
||||
hasLinks = true,
|
||||
preview = linkPreview,
|
||||
error = null
|
||||
error = null,
|
||||
link = null
|
||||
)
|
||||
}
|
||||
|
||||
@@ -60,7 +65,8 @@ class LinkPreviewState private constructor(
|
||||
isLoading = false,
|
||||
hasLinks = true,
|
||||
preview = null,
|
||||
error = error
|
||||
error = error,
|
||||
link = null
|
||||
)
|
||||
}
|
||||
|
||||
@@ -71,7 +77,8 @@ class LinkPreviewState private constructor(
|
||||
isLoading = false,
|
||||
hasLinks = false,
|
||||
preview = null,
|
||||
error = null
|
||||
error = null,
|
||||
link = null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public final class LinkPreviewUtil {
|
||||
|
||||
return new Links(Stream.of(spannable.getSpans(0, spannable.length(), URLSpan.class))
|
||||
.map(span -> new Link(span.getURL(), spannable.getSpanStart(span)))
|
||||
.filter(link -> LinkUtil.isValidPreviewUrl(link.getUrl()))
|
||||
.filter(link -> LinkUtil.isValidPreviewUrl(link.url))
|
||||
.toList());
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ public final class LinkPreviewUtil {
|
||||
private Links(@NonNull List<Link> links) {
|
||||
this.links = links;
|
||||
this.urlSet = Stream.of(links)
|
||||
.map(link -> trimTrailingSlash(link.getUrl()))
|
||||
.map(link -> trimTrailingSlash(link.url))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ public class LinkPreviewViewModel extends ViewModel {
|
||||
Optional<Link> link = LinkPreviewUtil.findValidPreviewUrls(text)
|
||||
.findFirst();
|
||||
|
||||
if (link.isPresent() && link.get().getUrl().equals(activeUrl)) {
|
||||
if (link.isPresent() && link.get().url.equals(activeUrl)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -139,9 +139,9 @@ public class LinkPreviewViewModel extends ViewModel {
|
||||
return;
|
||||
}
|
||||
|
||||
linkPreviewState.setValue(LinkPreviewState.forLoading());
|
||||
linkPreviewState.setValue(LinkPreviewState.forLoading(link.get()));
|
||||
|
||||
activeUrl = link.get().getUrl();
|
||||
activeUrl = link.get().url;
|
||||
activeRequest = enabled ? performRequest(activeUrl) : createPlaceholder(activeUrl);
|
||||
});
|
||||
}
|
||||
@@ -186,11 +186,11 @@ public class LinkPreviewViewModel extends ViewModel {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (text.endsWith(link.getUrl()) && cursorStart == link.getPosition() + link.getUrl().length()) {
|
||||
if (text.endsWith(link.url) && cursorStart == link.position + link.url.length()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return cursorStart < link.getPosition() || cursorStart > link.getPosition() + link.getUrl().length();
|
||||
return cursorStart < link.position || cursorStart > link.position + link.url.length();
|
||||
}
|
||||
|
||||
private @Nullable RequestController createPlaceholder(String url) {
|
||||
|
||||
@@ -88,7 +88,7 @@ class LinkPreviewViewModelV2(
|
||||
}
|
||||
|
||||
val link: Optional<Link> = LinkPreviewUtil.findValidPreviewUrls(text).findFirst()
|
||||
if (link.isPresent && link.get().url.equals(activeUrl)) {
|
||||
if (link.isPresent && link.get().url == activeUrl) {
|
||||
return@publish
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ class LinkPreviewViewModelV2(
|
||||
return@publish
|
||||
}
|
||||
|
||||
setLinkPreviewState(LinkPreviewState.forLoading())
|
||||
setLinkPreviewState(LinkPreviewState.forLoading(link.get()))
|
||||
|
||||
val activeUrl = link.get().url
|
||||
this.activeUrl = activeUrl
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.mediasend.v2.text
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import androidx.constraintlayout.widget.Group
|
||||
@@ -64,7 +63,7 @@ class TextStoryPostLinkEntryFragment(private val shouldPreset: Boolean = false)
|
||||
confirmButton.setOnClickListener {
|
||||
val linkPreviewState = linkPreviewViewModel.linkPreviewState.value
|
||||
if (linkPreviewState != null) {
|
||||
val url = linkPreviewState.linkPreview.map { it.url }.orElseGet { linkPreviewState.activeUrlForError }
|
||||
val url = linkPreviewState.url ?: ""
|
||||
|
||||
if (LinkUtil.isValidTextStoryPostPreview(url)) {
|
||||
viewModel.setLinkPreview(url)
|
||||
@@ -82,7 +81,7 @@ class TextStoryPostLinkEntryFragment(private val shouldPreset: Boolean = false)
|
||||
linkPreviewViewModel.linkPreviewState.observe(viewLifecycleOwner) { state ->
|
||||
linkPreview.bind(state, useLargeThumbnail = false)
|
||||
shareALinkGroup.visible = !state.isLoading && !state.linkPreview.isPresent && (state.error == null && state.activeUrlForError == null)
|
||||
confirmButton.isEnabled = state.linkPreview.isPresent || !TextUtils.isEmpty(state.activeUrlForError)
|
||||
confirmButton.isEnabled = state.url != null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user