Partially implement GIFs

This commit is contained in:
Niels Andriesse 2019-09-16 16:11:07 +10:00
parent 023b7aca9b
commit bdb950373a
4 changed files with 49 additions and 2 deletions

View File

@ -739,7 +739,12 @@ public class AttachmentDatabase extends Database {
if (thumbnailUri != null) { if (thumbnailUri != null) {
try (InputStream attachmentStream = PartAuthority.getAttachmentStream(context, thumbnailUri)) { try (InputStream attachmentStream = PartAuthority.getAttachmentStream(context, thumbnailUri)) {
Pair<Integer, Integer> dimens = BitmapUtil.getDimensions(attachmentStream); Pair<Integer, Integer> dimens;
if (attachment.getContentType().equals(MediaUtil.IMAGE_GIF)) {
dimens = new Pair<>(attachment.getWidth(), attachment.getHeight());
} else {
dimens = BitmapUtil.getDimensions(attachmentStream);
}
updateAttachmentThumbnail(attachmentId, updateAttachmentThumbnail(attachmentId,
PartAuthority.getAttachmentStream(context, thumbnailUri), PartAuthority.getAttachmentStream(context, thumbnailUri),
(float) dimens.first / (float) dimens.second); (float) dimens.first / (float) dimens.second);

View File

@ -978,6 +978,23 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
} }
})); }));
} }
} if (LinkPreviewUtil.isWhitelistedMediaUrl(body)) {
new LinkPreviewRepository(context).fetchGIF(context, body, attachmentOrNull -> Util.runOnMain(() -> {
if (attachmentOrNull.isPresent()) {
Attachment attachment = attachmentOrNull.get();
try {
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(Address.fromExternal(context, content.getSender()), message.getTimestamp(), -1,
message.getExpiresInSeconds() * 1000L, false, content.isNeedsReceipt(), message.getBody(), message.getGroupInfo(), Optional.of(new ArrayList<>()),
Optional.absent(), Optional.absent(), Optional.absent(), Optional.absent());
mediaMessage.getAttachments().add(attachment);
handleMediaMessage(content, mediaMessage, smsMessageId, messageServerIDOrNull);
} catch (Exception e) {
// TODO: Handle
}
} else {
// TODO: Handle
}
}));
} else { } else {
Optional<InsertResult> insertResult = database.insertMessageInbox(textMessage); Optional<InsertResult> insertResult = database.insertMessageInbox(textMessage);

View File

@ -33,6 +33,7 @@ public class LinkPreviewDomains {
"redd.it", "redd.it",
"imgur.com", "imgur.com",
"pinimg.com", "pinimg.com",
"giphy.com" "giphy.com",
"tenor.com"
)); ));
} }

View File

@ -8,6 +8,7 @@ import android.text.Html;
import android.text.TextUtils; import android.text.TextUtils;
import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.FutureTarget; import com.bumptech.glide.request.FutureTarget;
import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.ApplicationContext;
@ -150,6 +151,29 @@ public class LinkPreviewRepository implements InjectableType {
return new CallRequestController(call); return new CallRequestController(call);
} }
public @NonNull RequestController fetchGIF(@NonNull Context context, @NonNull String url, @NonNull Callback<Optional<Attachment>> callback) {
FutureTarget<GifDrawable> future = GlideApp.with(context).asGif().load(new ChunkedImageUrl(url)).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE)
.centerInside().submit(1024, 1024);
RequestController controller = () -> future.cancel(false);
SignalExecutors.UNBOUNDED.execute(() -> {
try {
GifDrawable gif = future.get();
byte[] bytes = new byte[gif.getBuffer().remaining()];
gif.getBuffer().get(bytes);
Uri uri = BlobProvider.getInstance().forData(bytes).createForSingleSessionInMemory();
Optional<Attachment> thumbnail = Optional.of(new UriAttachment(uri, uri, MediaUtil.IMAGE_GIF, AttachmentDatabase.TRANSFER_PROGRESS_DONE,
bytes.length, gif.getIntrinsicWidth(), gif.getIntrinsicHeight(), null, null, false, false, null, null));
callback.onComplete(thumbnail);
} catch (CancellationException | ExecutionException | InterruptedException e) {
controller.cancel();
callback.onComplete(Optional.absent());
} finally {
future.cancel(false);
}
});
return () -> future.cancel(true);
}
private @NonNull RequestController fetchThumbnail(@NonNull Context context, @NonNull String imageUrl, @NonNull Callback<Optional<Attachment>> callback) { private @NonNull RequestController fetchThumbnail(@NonNull Context context, @NonNull String imageUrl, @NonNull Callback<Optional<Attachment>> callback) {
FutureTarget<Bitmap> bitmapFuture = GlideApp.with(context).asBitmap() FutureTarget<Bitmap> bitmapFuture = GlideApp.with(context).asBitmap()
.load(new ChunkedImageUrl(imageUrl)) .load(new ChunkedImageUrl(imageUrl))