mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-20 00:29:11 +01:00
Add support for link preview descriptions.
This commit is contained in:
@@ -22,45 +22,56 @@ public class LinkPreview {
|
||||
@JsonProperty
|
||||
private final String title;
|
||||
|
||||
@JsonProperty
|
||||
private final String description;
|
||||
|
||||
@JsonProperty
|
||||
private final AttachmentId attachmentId;
|
||||
|
||||
@JsonIgnore
|
||||
private final Optional<Attachment> thumbnail;
|
||||
|
||||
public LinkPreview(@NonNull String url, @NonNull String title, @NonNull DatabaseAttachment thumbnail) {
|
||||
public LinkPreview(@NonNull String url, @NonNull String title, @NonNull String description, @NonNull DatabaseAttachment thumbnail) {
|
||||
this.url = url;
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.thumbnail = Optional.of(thumbnail);
|
||||
this.attachmentId = thumbnail.getAttachmentId();
|
||||
}
|
||||
|
||||
public LinkPreview(@NonNull String url, @NonNull String title, @NonNull Optional<Attachment> thumbnail) {
|
||||
public LinkPreview(@NonNull String url, @NonNull String title, @NonNull String description, @NonNull Optional<Attachment> thumbnail) {
|
||||
this.url = url;
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.thumbnail = thumbnail;
|
||||
this.attachmentId = null;
|
||||
}
|
||||
|
||||
public LinkPreview(@JsonProperty("url") @NonNull String url,
|
||||
@JsonProperty("title") @NonNull String title,
|
||||
@JsonProperty("description") @Nullable String description,
|
||||
@JsonProperty("attachmentId") @Nullable AttachmentId attachmentId)
|
||||
{
|
||||
this.url = url;
|
||||
this.title = title;
|
||||
this.description = Optional.fromNullable(description).or("");
|
||||
this.attachmentId = attachmentId;
|
||||
this.thumbnail = Optional.absent();
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
public @NonNull String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
public @NonNull String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public Optional<Attachment> getThumbnail() {
|
||||
public @NonNull String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public @NonNull Optional<Attachment> getThumbnail() {
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
@@ -68,11 +79,11 @@ public class LinkPreview {
|
||||
return attachmentId;
|
||||
}
|
||||
|
||||
public String serialize() throws IOException {
|
||||
public @NonNull String serialize() throws IOException {
|
||||
return JsonUtils.toJson(this);
|
||||
}
|
||||
|
||||
public static LinkPreview deserialize(@NonNull String serialized) throws IOException {
|
||||
public static @NonNull LinkPreview deserialize(@NonNull String serialized) throws IOException {
|
||||
return JsonUtils.fromJson(serialized, LinkPreview.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public class LinkPreviewRepository {
|
||||
}
|
||||
|
||||
if (!metadata.getImageUrl().isPresent()) {
|
||||
callback.onSuccess(new LinkPreview(url, metadata.getTitle().get(), Optional.absent()));
|
||||
callback.onSuccess(new LinkPreview(url, metadata.getTitle().or(""), metadata.getDescription().or(""), Optional.absent()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ public class LinkPreviewRepository {
|
||||
if (!metadata.getTitle().isPresent() && !attachment.isPresent()) {
|
||||
callback.onError(Error.PREVIEW_NOT_AVAILABLE);
|
||||
} else {
|
||||
callback.onSuccess(new LinkPreview(url, metadata.getTitle().or(""), attachment));
|
||||
callback.onSuccess(new LinkPreview(url, metadata.getTitle().or(""), metadata.getDescription().or(""), attachment));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -147,17 +147,18 @@ public class LinkPreviewRepository {
|
||||
return;
|
||||
}
|
||||
|
||||
String body = OkHttpUtil.readAsString(response.body(), FAILSAFE_MAX_TEXT_SIZE);
|
||||
OpenGraph openGraph = LinkPreviewUtil.parseOpenGraphFields(body);
|
||||
Optional<String> title = openGraph.getTitle();
|
||||
Optional<String> imageUrl = openGraph.getImageUrl();
|
||||
String body = OkHttpUtil.readAsString(response.body(), FAILSAFE_MAX_TEXT_SIZE);
|
||||
OpenGraph openGraph = LinkPreviewUtil.parseOpenGraphFields(body);
|
||||
Optional<String> title = openGraph.getTitle();
|
||||
Optional<String> description = openGraph.getDescription();
|
||||
Optional<String> imageUrl = openGraph.getImageUrl();
|
||||
|
||||
if (imageUrl.isPresent() && !LinkPreviewUtil.isValidPreviewUrl(imageUrl.get())) {
|
||||
Log.i(TAG, "Image URL was invalid or for a non-whitelisted domain. Skipping.");
|
||||
imageUrl = Optional.absent();
|
||||
}
|
||||
|
||||
callback.accept(new Metadata(title, imageUrl));
|
||||
callback.accept(new Metadata(title, description, imageUrl));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -225,7 +226,7 @@ public class LinkPreviewRepository {
|
||||
|
||||
Optional<Attachment> thumbnail = bitmapToAttachment(bitmap, Bitmap.CompressFormat.WEBP, MediaUtil.IMAGE_WEBP);
|
||||
|
||||
callback.onSuccess(new LinkPreview(packUrl, title, thumbnail));
|
||||
callback.onSuccess(new LinkPreview(packUrl, title, "", thumbnail));
|
||||
} else {
|
||||
callback.onError(Error.PREVIEW_NOT_AVAILABLE);
|
||||
}
|
||||
@@ -268,7 +269,7 @@ public class LinkPreviewRepository {
|
||||
thumbnail = bitmapToAttachment(bitmap, Bitmap.CompressFormat.WEBP, MediaUtil.IMAGE_WEBP);
|
||||
}
|
||||
|
||||
callback.onSuccess(new LinkPreview(groupUrl, title, thumbnail));
|
||||
callback.onSuccess(new LinkPreview(groupUrl, title, "", thumbnail));
|
||||
} else {
|
||||
Log.i(TAG, "Group is not locally available for preview generation, fetching from server");
|
||||
|
||||
@@ -284,7 +285,7 @@ public class LinkPreviewRepository {
|
||||
if (bitmap != null) bitmap.recycle();
|
||||
}
|
||||
|
||||
callback.onSuccess(new LinkPreview(groupUrl, joinInfo.getTitle(), thumbnail));
|
||||
callback.onSuccess(new LinkPreview(groupUrl, joinInfo.getTitle(), "", thumbnail));
|
||||
}
|
||||
} catch (ExecutionException | InterruptedException | IOException | VerificationFailedException e) {
|
||||
Log.w(TAG, "Failed to fetch group link preview.", e);
|
||||
@@ -337,21 +338,27 @@ public class LinkPreviewRepository {
|
||||
|
||||
private static class Metadata {
|
||||
private final Optional<String> title;
|
||||
private final Optional<String> description;
|
||||
private final Optional<String> imageUrl;
|
||||
|
||||
Metadata(Optional<String> title, Optional<String> imageUrl) {
|
||||
this.title = title;
|
||||
this.imageUrl = imageUrl;
|
||||
Metadata(Optional<String> title, Optional<String> description, Optional<String> imageUrl) {
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
static Metadata empty() {
|
||||
return new Metadata(Optional.absent(), Optional.absent());
|
||||
return new Metadata(Optional.absent(), Optional.absent(), Optional.absent());
|
||||
}
|
||||
|
||||
Optional<String> getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
Optional<String> getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
Optional<String> getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
@@ -154,8 +154,9 @@ public final class LinkPreviewUtil {
|
||||
private final @Nullable String htmlTitle;
|
||||
private final @Nullable String faviconUrl;
|
||||
|
||||
private static final String KEY_TITLE = "title";
|
||||
private static final String KEY_IMAGE_URL = "image";
|
||||
private static final String KEY_TITLE = "title";
|
||||
private static final String KEY_DESCRIPTION_URL = "description";
|
||||
private static final String KEY_IMAGE_URL = "image";
|
||||
|
||||
public OpenGraph(@NonNull Map<String, String> values, @Nullable String htmlTitle, @Nullable String faviconUrl) {
|
||||
this.values = values;
|
||||
@@ -170,6 +171,10 @@ public final class LinkPreviewUtil {
|
||||
public @NonNull Optional<String> getImageUrl() {
|
||||
return OptionalUtil.absentIfEmpty(Util.getFirstNonEmpty(values.get(KEY_IMAGE_URL), faviconUrl));
|
||||
}
|
||||
|
||||
public @NonNull Optional<String> getDescription() {
|
||||
return OptionalUtil.absentIfEmpty(values.get(KEY_DESCRIPTION_URL));
|
||||
}
|
||||
}
|
||||
|
||||
public interface HtmlDecoder {
|
||||
|
||||
Reference in New Issue
Block a user