Add support for animated stickers.

master
Greyson Parrelli 2020-09-02 12:46:58 -04:00 committed by Cody Henthorne
parent bb708e0aa3
commit f4a199f621
26 changed files with 146 additions and 72 deletions

View File

@ -1425,7 +1425,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
if (stickerLocator != null && draftMedia != null) {
Log.d(TAG, "Handling shared sticker.");
sendSticker(stickerLocator, draftMedia, 0, true);
sendSticker(stickerLocator, Objects.requireNonNull(draftContentType), draftMedia, 0, true);
return new SettableFuture<>(false);
}
@ -2876,7 +2876,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
}
private void sendSticker(@NonNull StickerRecord stickerRecord, boolean clearCompose) {
sendSticker(new StickerLocator(stickerRecord.getPackId(), stickerRecord.getPackKey(), stickerRecord.getStickerId()), stickerRecord.getUri(), stickerRecord.getSize(), clearCompose);
sendSticker(new StickerLocator(stickerRecord.getPackId(), stickerRecord.getPackKey(), stickerRecord.getStickerId()), stickerRecord.getContentType(), stickerRecord.getUri(), stickerRecord.getSize(), clearCompose);
SignalExecutors.BOUNDED.execute(() ->
DatabaseFactory.getStickerDatabase(getApplicationContext())
@ -2884,9 +2884,9 @@ public class ConversationActivity extends PassphraseRequiredActivity
);
}
private void sendSticker(@NonNull StickerLocator stickerLocator, @NonNull Uri uri, long size, boolean clearCompose) {
private void sendSticker(@NonNull StickerLocator stickerLocator, @NonNull String contentType, @NonNull Uri uri, long size, boolean clearCompose) {
if (sendButton.getSelectedTransport().isSms()) {
Media media = new Media(uri, MediaUtil.IMAGE_WEBP, System.currentTimeMillis(), StickerSlide.WIDTH, StickerSlide.HEIGHT, size, 0, false, Optional.absent(), Optional.absent(), Optional.absent());
Media media = new Media(uri, contentType, System.currentTimeMillis(), StickerSlide.WIDTH, StickerSlide.HEIGHT, size, 0, false, Optional.absent(), Optional.absent(), Optional.absent());
Intent intent = MediaSendActivity.buildEditorIntent(this, Collections.singletonList(media), recipient.get(), composeText.getTextTrimmed(), sendButton.getSelectedTransport());
startActivityForResult(intent, MEDIA_SENDER);
return;
@ -2897,7 +2897,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
boolean initiating = threadId == -1;
TransportOption transport = sendButton.getSelectedTransport();
SlideDeck slideDeck = new SlideDeck();
Slide stickerSlide = new StickerSlide(this, uri, size, stickerLocator);
Slide stickerSlide = new StickerSlide(this, uri, size, stickerLocator, contentType);
slideDeck.addSlide(stickerSlide);

View File

@ -838,6 +838,7 @@ public class ConversationFragment extends LoggingFragment {
if (slide.hasSticker()) {
composeIntent.putExtra(ConversationActivity.STICKER_EXTRA, slide.asAttachment().getSticker());
composeIntent.setType(slide.asAttachment().getContentType());
}
}

View File

@ -38,21 +38,22 @@ public class StickerDatabase extends Database {
private static final String TAG = Log.tag(StickerDatabase.class);
public static final String TABLE_NAME = "sticker";
public static final String _ID = "_id";
static final String PACK_ID = "pack_id";
private static final String PACK_KEY = "pack_key";
private static final String PACK_TITLE = "pack_title";
private static final String PACK_AUTHOR = "pack_author";
private static final String STICKER_ID = "sticker_id";
private static final String EMOJI = "emoji";
private static final String COVER = "cover";
private static final String PACK_ORDER = "pack_order";
private static final String INSTALLED = "installed";
private static final String LAST_USED = "last_used";
public static final String FILE_PATH = "file_path";
public static final String FILE_LENGTH = "file_length";
public static final String FILE_RANDOM = "file_random";
public static final String TABLE_NAME = "sticker";
public static final String _ID = "_id";
static final String PACK_ID = "pack_id";
private static final String PACK_KEY = "pack_key";
private static final String PACK_TITLE = "pack_title";
private static final String PACK_AUTHOR = "pack_author";
private static final String STICKER_ID = "sticker_id";
private static final String EMOJI = "emoji";
public static final String CONTENT_TYPE = "content_type";
private static final String COVER = "cover";
private static final String PACK_ORDER = "pack_order";
private static final String INSTALLED = "installed";
private static final String LAST_USED = "last_used";
public static final String FILE_PATH = "file_path";
public static final String FILE_LENGTH = "file_length";
public static final String FILE_RANDOM = "file_random";
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
PACK_ID + " TEXT NOT NULL, " +
@ -63,6 +64,7 @@ public class StickerDatabase extends Database {
COVER + " INTEGER, " +
PACK_ORDER + " INTEGER, " +
EMOJI + " TEXT NOT NULL, " +
CONTENT_TYPE + " TEXT DEFAULT NULL, " +
LAST_USED + " INTEGER, " +
INSTALLED + " INTEGER," +
FILE_PATH + " TEXT NOT NULL, " +
@ -94,6 +96,7 @@ public class StickerDatabase extends Database {
contentValues.put(PACK_AUTHOR, sticker.getPackAuthor());
contentValues.put(STICKER_ID, sticker.getStickerId());
contentValues.put(EMOJI, sticker.getEmoji());
contentValues.put(CONTENT_TYPE, sticker.getContentType());
contentValues.put(COVER, sticker.isCover() ? 1 : 0);
contentValues.put(INSTALLED, sticker.isInstalled() ? 1 : 0);
contentValues.put(FILE_PATH, fileInfo.getFile().getAbsolutePath());
@ -460,6 +463,7 @@ public class StickerDatabase extends Database {
cursor.getString(cursor.getColumnIndexOrThrow(PACK_KEY)),
cursor.getInt(cursor.getColumnIndexOrThrow(STICKER_ID)),
cursor.getString(cursor.getColumnIndexOrThrow(EMOJI)),
cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_TYPE)),
cursor.getLong(cursor.getColumnIndexOrThrow(FILE_LENGTH)),
cursor.getInt(cursor.getColumnIndexOrThrow(COVER)) == 1);
}

View File

@ -144,8 +144,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
private static final int PINNED_CONVERSATIONS = 69;
private static final int MENTION_GLOBAL_SETTING_MIGRATION = 70;
private static final int UNKNOWN_STORAGE_FIELDS = 71;
private static final int STICKER_CONTENT_TYPE = 72;
private static final int DATABASE_VERSION = 71;
private static final int DATABASE_VERSION = 72;
private static final String DATABASE_NAME = "signal.db";
private final Context context;
@ -1013,6 +1014,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
db.execSQL("ALTER TABLE recipient ADD COLUMN storage_proto TEXT DEFAULT NULL");
}
if (oldVersion < STICKER_CONTENT_TYPE) {
db.execSQL("ALTER TABLE sticker ADD COLUMN content_type TEXT DEFAULT NULL");
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();

View File

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.database.model;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class IncomingSticker {
@ -10,6 +11,7 @@ public class IncomingSticker {
private final String packAuthor;
private final int stickerId;
private final String emoji;
private final String contentType;
private final boolean isCover;
private final boolean isInstalled;
@ -19,6 +21,7 @@ public class IncomingSticker {
@NonNull String packAuthor,
int stickerId,
@NonNull String emoji,
@Nullable String contentType,
boolean isCover,
boolean isInstalled)
{
@ -28,6 +31,7 @@ public class IncomingSticker {
this.packAuthor = packAuthor;
this.stickerId = stickerId;
this.emoji = emoji;
this.contentType = contentType;
this.isCover = isCover;
this.isInstalled = isInstalled;
}
@ -56,6 +60,10 @@ public class IncomingSticker {
return emoji;
}
public @Nullable String getContentType() {
return contentType;
}
public boolean isCover() {
return isCover;
}

View File

@ -3,8 +3,10 @@ package org.thoughtcrime.securesms.database.model;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.util.MediaUtil;
import java.util.Objects;
@ -18,6 +20,7 @@ public final class StickerRecord {
private final String packKey;
private final int stickerId;
private final String emoji;
private final String contentType;
private final long size;
private final boolean isCover;
@ -26,16 +29,18 @@ public final class StickerRecord {
@NonNull String packKey,
int stickerId,
@NonNull String emoji,
@Nullable String contentType,
long size,
boolean isCover)
{
this.rowId = rowId;
this.packId = packId;
this.packKey = packKey;
this.stickerId = stickerId;
this.emoji = emoji;
this.size = size;
this.isCover = isCover;
this.rowId = rowId;
this.packId = packId;
this.packKey = packKey;
this.stickerId = stickerId;
this.emoji = emoji;
this.contentType = contentType;
this.size = size;
this.isCover = isCover;
}
public long getRowId() {
@ -62,6 +67,10 @@ public final class StickerRecord {
return emoji;
}
public @NonNull String getContentType() {
return contentType == null ? MediaUtil.IMAGE_WEBP : contentType;
}
public long getSize() {
return size;
}
@ -81,11 +90,12 @@ public final class StickerRecord {
isCover == that.isCover &&
packId.equals(that.packId) &&
packKey.equals(that.packKey) &&
emoji.equals(that.emoji);
emoji.equals(that.emoji) &&
Objects.equals(contentType, that.contentType);
}
@Override
public int hashCode() {
return Objects.hash(rowId, packId, packKey, stickerId, emoji, size, isCover);
return Objects.hash(rowId, packId, packKey, stickerId, emoji, contentType, size, isCover);
}
}

View File

@ -1665,7 +1665,7 @@ public final class PushProcessMessageJob extends BaseJob {
if (stickerRecord != null) {
return Optional.of(new UriAttachment(stickerRecord.getUri(),
stickerRecord.getUri(),
MediaUtil.IMAGE_WEBP,
stickerRecord.getContentType(),
AttachmentDatabase.TRANSFER_PROGRESS_DONE,
stickerRecord.getSize(),
StickerSlide.WIDTH,

View File

@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.contactshare.ContactModelMapper;
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.model.Mention;
import org.thoughtcrime.securesms.database.model.StickerRecord;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.events.PartProgressEvent;
import org.thoughtcrime.securesms.jobmanager.Job;
@ -283,9 +284,11 @@ public abstract class PushSendJob extends SendJob {
byte[] packId = Hex.fromStringCondensed(stickerAttachment.getSticker().getPackId());
byte[] packKey = Hex.fromStringCondensed(stickerAttachment.getSticker().getPackKey());
int stickerId = stickerAttachment.getSticker().getStickerId();
StickerRecord record = DatabaseFactory.getStickerDatabase(context).getSticker(stickerAttachment.getSticker().getPackId(), stickerId, false);
String emoji = record != null ? record.getEmoji() : null;
SignalServiceAttachment attachment = getAttachmentPointerFor(stickerAttachment);
return Optional.of(new SignalServiceDataMessage.Sticker(packId, packKey, stickerId, attachment));
return Optional.of(new SignalServiceDataMessage.Sticker(packId, packKey, stickerId, emoji, attachment));
} catch (IOException e) {
Log.w(TAG, "Failed to decode sticker id/key", e);
return Optional.absent();

View File

@ -23,15 +23,16 @@ public class StickerDownloadJob extends BaseJob {
private static final String TAG = Log.tag(StickerDownloadJob.class);
private static final String KEY_PACK_ID = "pack_id";
private static final String KEY_PACK_KEY = "pack_key";
private static final String KEY_PACK_TITLE = "pack_title";
private static final String KEY_PACK_AUTHOR = "pack_author";
private static final String KEY_STICKER_ID = "sticker_id";
private static final String KEY_EMOJI = "emoji";
private static final String KEY_COVER = "cover";
private static final String KEY_INSTALLED = "installed";
private static final String KEY_NOTIFY = "notify";
private static final String KEY_PACK_ID = "pack_id";
private static final String KEY_PACK_KEY = "pack_key";
private static final String KEY_PACK_TITLE = "pack_title";
private static final String KEY_PACK_AUTHOR = "pack_author";
private static final String KEY_STICKER_ID = "sticker_id";
private static final String KEY_EMOJI = "emoji";
private static final String KEY_CONTENT_TYPE = "content_type";
private static final String KEY_COVER = "cover";
private static final String KEY_INSTALLED = "installed";
private static final String KEY_NOTIFY = "notify";
private final IncomingSticker sticker;
private final boolean notify;
@ -59,6 +60,7 @@ public class StickerDownloadJob extends BaseJob {
.putString(KEY_PACK_AUTHOR, sticker.getPackAuthor())
.putInt(KEY_STICKER_ID, sticker.getStickerId())
.putString(KEY_EMOJI, sticker.getEmoji())
.putString(KEY_CONTENT_TYPE, sticker.getContentType())
.putBoolean(KEY_COVER, sticker.isCover())
.putBoolean(KEY_INSTALLED, sticker.isInstalled())
.putBoolean(KEY_NOTIFY, notify)
@ -111,6 +113,7 @@ public class StickerDownloadJob extends BaseJob {
data.getString(KEY_PACK_AUTHOR),
data.getInt(KEY_STICKER_ID),
data.getString(KEY_EMOJI),
data.getString(KEY_CONTENT_TYPE),
data.getBoolean(KEY_COVER),
data.getBoolean(KEY_INSTALLED));

View File

@ -135,6 +135,7 @@ public class StickerPackDownloadJob extends BaseJob {
manifest.getAuthor().or(""),
cover.getId(),
"",
cover.getContentType(),
true,
!isReferencePack),
notify));
@ -151,6 +152,7 @@ public class StickerPackDownloadJob extends BaseJob {
manifest.getAuthor().or(""),
stickerInfo.getId(),
stickerInfo.getEmoji(),
stickerInfo.getContentType(),
false,
true),
notify));

View File

@ -61,7 +61,6 @@ public class SignalGlideModule extends AppGlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setLogLevel(Log.ERROR);
// builder.setDiskCache(new NoopDiskCacheFactory());
}
@Override

View File

@ -22,8 +22,8 @@ public class StickerSlide extends Slide {
super(context, attachment);
}
public StickerSlide(Context context, Uri uri, long size, @NonNull StickerLocator stickerLocator) {
super(context, constructAttachmentFromUri(context, uri, MediaUtil.IMAGE_WEBP, size, WIDTH, HEIGHT, true, null, null, stickerLocator, null, null, false, false, false));
public StickerSlide(Context context, Uri uri, long size, @NonNull StickerLocator stickerLocator, @NonNull String contentType) {
super(context, constructAttachmentFromUri(context, uri, contentType, size, WIDTH, HEIGHT, true, null, null, stickerLocator, null, null, false, false, false));
}
@Override
@ -41,6 +41,11 @@ public class StickerSlide extends Slide {
return true;
}
@Override
public boolean isBorderless() {
return true;
}
@Override
public @NonNull String getContentDescription() {
return context.getString(R.string.Slide_sticker);

View File

@ -314,6 +314,8 @@ public class ShareActivity extends PassphraseRequiredActivity
intent.putExtra(ConversationActivity.MEDIA_EXTRA, shareData.getMedia());
} else if (shareData != null && shareData.isForPrimitive()) {
Log.i(TAG, "Shared data is a primitive type.");
} else if (shareData == null && stickerExtra != null) {
intent.setType(getIntent().getType());
} else {
Log.i(TAG, "Shared data was not external.");
}

View File

@ -4,6 +4,7 @@ import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.whispersystems.libsignal.util.guava.Optional;
import java.util.ArrayList;
@ -66,18 +67,20 @@ public final class StickerManifest {
private final String packKey;
private final int id;
private final String emoji;
private final String contentType;
private final Optional<Uri> uri;
public Sticker(@NonNull String packId, @NonNull String packKey, int id, @NonNull String emoji) {
this(packId, packKey, id, emoji, null);
public Sticker(@NonNull String packId, @NonNull String packKey, int id, @NonNull String emoji, @Nullable String contentType) {
this(packId, packKey, id, emoji, contentType, null);
}
public Sticker(@NonNull String packId, @NonNull String packKey, int id, @NonNull String emoji, @Nullable Uri uri) {
this.packId = packId;
this.packKey = packKey;
this.id = id;
this.emoji = emoji;
this.uri = Optional.fromNullable(uri);
public Sticker(@NonNull String packId, @NonNull String packKey, int id, @NonNull String emoji, @Nullable String contentType, @Nullable Uri uri) {
this.packId = packId;
this.packKey = packKey;
this.id = id;
this.emoji = emoji;
this.contentType = contentType;
this.uri = Optional.fromNullable(uri);
}
public @NonNull String getPackId() {
@ -96,6 +99,10 @@ public final class StickerManifest {
return emoji;
}
public @Nullable String getContentType() {
return contentType;
}
public Optional<Uri> getUri() {
return uri;
}

View File

@ -126,11 +126,11 @@ public final class StickerPackPreviewRepository {
@NonNull String packKey,
@NonNull SignalServiceStickerManifest.StickerInfo remoteSticker)
{
return new StickerManifest.Sticker(packId, packKey, remoteSticker.getId(), remoteSticker.getEmoji());
return new StickerManifest.Sticker(packId, packKey, remoteSticker.getId(), remoteSticker.getEmoji(), remoteSticker.getContentType());
}
private StickerManifest.Sticker toSticker(@NonNull StickerRecord record) {
return new StickerManifest.Sticker(record.getPackId(), record.getPackKey(), record.getStickerId(), record.getEmoji(), record.getUri());
return new StickerManifest.Sticker(record.getPackId(), record.getPackKey(), record.getStickerId(), record.getEmoji(), record.getContentType(), record.getUri());
}
static class StickerManifestResult {

View File

@ -10,6 +10,8 @@ import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.mms.GlideRequests;
@ -37,6 +39,7 @@ final class StickerPreviewPopup extends PopupWindow {
void presentSticker(@NonNull Object stickerGlideModel, @Nullable String emoji) {
emojiText.setText(emoji);
glideRequests.load(stickerGlideModel)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(image);
}
}

View File

@ -14,12 +14,15 @@ import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.whispersystems.libsignal.util.Pair;
import java.lang.ref.WeakReference;
public class StickerRolloverTouchListener implements RecyclerView.OnItemTouchListener {
private final StickerPreviewPopup popup;
private final RolloverEventListener eventListener;
private final RolloverStickerRetriever stickerRetriever;
private boolean hoverMode;
private WeakReference<View> currentView;
private boolean hoverMode;
StickerRolloverTouchListener(@NonNull Context context,
@NonNull GlideRequests glideRequests,
@ -29,6 +32,8 @@ public class StickerRolloverTouchListener implements RecyclerView.OnItemTouchLis
this.eventListener = eventListener;
this.stickerRetriever = stickerRetriever;
this.popup = new StickerPreviewPopup(context, glideRequests);
this.currentView = new WeakReference<>(null);
popup.setAnimationStyle(R.style.StickerPopupAnimation);
}
@ -45,15 +50,19 @@ public class StickerRolloverTouchListener implements RecyclerView.OnItemTouchLis
hoverMode = false;
popup.dismiss();
eventListener.onStickerPopupEnded();
currentView.clear();
break;
default:
for (int i = 0, len = recyclerView.getChildCount(); i < len; i++) {
View child = recyclerView.getChildAt(i);
if (ViewUtil.isPointInsideView(recyclerView, motionEvent.getRawX(), motionEvent.getRawY()) &&
ViewUtil.isPointInsideView(child, motionEvent.getRawX(), motionEvent.getRawY()))
ViewUtil.isPointInsideView(child, motionEvent.getRawX(), motionEvent.getRawY()) &&
child != currentView.get())
{
showStickerForView(recyclerView, child);
currentView = new WeakReference<>(child);
break;
}
}
}

View File

@ -3,7 +3,4 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sticker_keyboard_page_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp">
</ImageView>
android:layout_height="wrap_content" />

View File

@ -17,7 +17,7 @@
<ImageView
android:id="@+id/sticker_install_cover"
android:layout_width="wrap_content"
android:layout_width="48dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
app:layout_constraintTop_toTopOf="@id/sticker_install_title"

View File

@ -218,11 +218,11 @@ public class SignalServiceMessageReceiver {
StickerProtos.Pack pack = StickerProtos.Pack.parseFrom(outputStream.toByteArray());
List<SignalServiceStickerManifest.StickerInfo> stickers = new ArrayList<>(pack.getStickersCount());
SignalServiceStickerManifest.StickerInfo cover = pack.hasCover() ? new SignalServiceStickerManifest.StickerInfo(pack.getCover().getId(), pack.getCover().getEmoji())
SignalServiceStickerManifest.StickerInfo cover = pack.hasCover() ? new SignalServiceStickerManifest.StickerInfo(pack.getCover().getId(), pack.getCover().getEmoji(), pack.getCover().getContentType())
: null;
for (StickerProtos.Pack.Sticker sticker : pack.getStickersList()) {
stickers.add(new SignalServiceStickerManifest.StickerInfo(sticker.getId(), sticker.getEmoji()));
stickers.add(new SignalServiceStickerManifest.StickerInfo(sticker.getId(), sticker.getEmoji(), sticker.getContentType()));
}
return new SignalServiceStickerManifest(pack.getTitle(), pack.getAuthor(), cover, stickers);

View File

@ -660,6 +660,7 @@ public class SignalServiceMessageSender {
stickerBuilder.setPackId(ByteString.copyFrom(message.getSticker().get().getPackId()));
stickerBuilder.setPackKey(ByteString.copyFrom(message.getSticker().get().getPackKey()));
stickerBuilder.setStickerId(message.getSticker().get().getStickerId());
stickerBuilder.setEmoji(message.getSticker().get().getEmoji());
if (message.getSticker().get().getAttachment().isStream()) {
stickerBuilder.setData(createAttachmentPointer(message.getSticker().get().getAttachment().asStream()));

View File

@ -736,9 +736,10 @@ public final class SignalServiceContent {
SignalServiceProtos.DataMessage.Sticker sticker = content.getSticker();
return new SignalServiceDataMessage.Sticker(sticker.getPackId().toByteArray(),
sticker.getPackKey().toByteArray(),
sticker.getStickerId(),
createAttachmentPointer(sticker.getData()));
sticker.getPackKey().toByteArray(),
sticker.getStickerId(),
sticker.getEmoji(),
createAttachmentPointer(sticker.getData()));
}
private static SignalServiceDataMessage.Reaction createReaction(SignalServiceProtos.DataMessage content) {

View File

@ -449,12 +449,14 @@ public class SignalServiceDataMessage {
private final byte[] packId;
private final byte[] packKey;
private final int stickerId;
private final String emoji;
private final SignalServiceAttachment attachment;
public Sticker(byte[] packId, byte[] packKey, int stickerId, SignalServiceAttachment attachment) {
public Sticker(byte[] packId, byte[] packKey, int stickerId, String emoji, SignalServiceAttachment attachment) {
this.packId = packId;
this.packKey = packKey;
this.stickerId = stickerId;
this.emoji = emoji;
this.attachment = attachment;
}
@ -470,6 +472,10 @@ public class SignalServiceDataMessage {
return stickerId;
}
public String getEmoji() {
return emoji;
}
public SignalServiceAttachment getAttachment() {
return attachment;
}

View File

@ -39,10 +39,12 @@ public class SignalServiceStickerManifest {
public static final class StickerInfo {
private final int id;
private final String emoji;
private final String contentType;
public StickerInfo(int id, String emoji) {
this.id = id;
this.emoji = emoji;
public StickerInfo(int id, String emoji, String contentType) {
this.id = id;
this.emoji = emoji;
this.contentType = contentType;
}
public int getId() {
@ -52,5 +54,9 @@ public class SignalServiceStickerManifest {
public String getEmoji() {
return emoji;
}
public String getContentType() {
return contentType;
}
}
}

View File

@ -215,6 +215,7 @@ message DataMessage {
optional bytes packKey = 2;
optional uint32 stickerId = 3;
optional AttachmentPointer data = 4;
optional string emoji = 5;
}
message Reaction {

View File

@ -12,8 +12,9 @@ option java_outer_classname = "StickerProtos";
message Pack {
message Sticker {
optional uint32 id = 1;
optional string emoji = 2;
optional uint32 id = 1;
optional string emoji = 2;
optional string contentType = 3;
}
optional string title = 1;