Fix several issues with multiforwarding.

* Better forwarding and animations.
* Handle audio with text.
* Increase max forwardable count to 32
* Onboarding dialog.
* Send forth link previews.
* Safety number support.
* Fix slide behaviour.
This commit is contained in:
Alex Hart
2021-08-17 16:15:09 -03:00
committed by GitHub
parent 0b37b0ee16
commit c65761a034
22 changed files with 662 additions and 117 deletions

View File

@@ -11,6 +11,7 @@ import androidx.annotation.Nullable;
import com.annimon.stream.Stream;
import org.thoughtcrime.securesms.database.model.Mention;
import org.thoughtcrime.securesms.database.model.MessageId;
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.stickers.StickerLocator;
@@ -35,6 +36,8 @@ public final class MultiShareArgs implements Parcelable {
private final boolean viewOnce;
private final LinkPreview linkPreview;
private final List<Mention> mentions;
private final long timestamp;
private final long expiresAt;
private MultiShareArgs(@NonNull Builder builder) {
shareContactAndThreads = builder.shareContactAndThreads;
@@ -47,6 +50,8 @@ public final class MultiShareArgs implements Parcelable {
viewOnce = builder.viewOnce;
linkPreview = builder.linkPreview;
mentions = builder.mentions == null ? new ArrayList<>() : new ArrayList<>(builder.mentions);
timestamp = builder.timestamp;
expiresAt = builder.expiresAt;
}
protected MultiShareArgs(Parcel in) {
@@ -59,6 +64,8 @@ public final class MultiShareArgs implements Parcelable {
dataType = in.readString();
viewOnce = in.readByte() != 0;
mentions = in.createTypedArrayList(Mention.CREATOR);
timestamp = in.readLong();
expiresAt = in.readLong();
String linkedPreviewString = in.readString();
LinkPreview preview;
@@ -111,6 +118,14 @@ public final class MultiShareArgs implements Parcelable {
return mentions;
}
public long getTimestamp() {
return timestamp;
}
public long getExpiresAt() {
return expiresAt;
}
public @NonNull InterstitialContentType getInterstitialContentType() {
if (!requiresInterstitial()) {
return InterstitialContentType.NONE;
@@ -154,6 +169,8 @@ public final class MultiShareArgs implements Parcelable {
dest.writeString(dataType);
dest.writeByte((byte) (viewOnce ? 1 : 0));
dest.writeTypedList(mentions);
dest.writeLong(timestamp);
dest.writeLong(expiresAt);
if (linkPreview != null) {
try {
@@ -179,7 +196,9 @@ public final class MultiShareArgs implements Parcelable {
.withLinkPreview(linkPreview)
.withMedia(media)
.withStickerLocator(stickerLocator)
.withMentions(mentions);
.withMentions(mentions)
.withTimestamp(timestamp)
.withExpiration(expiresAt);
}
private boolean requiresInterstitial() {
@@ -200,6 +219,8 @@ public final class MultiShareArgs implements Parcelable {
private LinkPreview linkPreview;
private boolean viewOnce;
private List<Mention> mentions;
private long timestamp;
private long expiresAt;
public Builder(@NonNull Set<ShareContactAndThread> shareContactAndThreads) {
this.shareContactAndThreads = shareContactAndThreads;
@@ -250,6 +271,16 @@ public final class MultiShareArgs implements Parcelable {
return this;
}
public @NonNull Builder withTimestamp(long timestamp) {
this.timestamp = timestamp;
return this;
}
public @NonNull Builder withExpiration(long expiresAt) {
this.expiresAt = expiresAt;
return this;
}
public @NonNull MultiShareArgs build() {
return new MultiShareArgs(this);
}

View File

@@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.database.model.Mention;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.mms.SlideFactory;
import org.thoughtcrime.securesms.mms.StickerSlide;
@@ -58,12 +59,23 @@ public final class MultiShareSender {
@WorkerThread
public static MultiShareSendResultCollection sendSync(@NonNull MultiShareArgs multiShareArgs) {
Context context = ApplicationDependencies.getApplication();
boolean isMmsEnabled = Util.isMmsCapable(context);
String message = multiShareArgs.getDraftText();
SlideDeck slideDeck = buildSlideDeck(context, multiShareArgs);
List<MultiShareSendResult> results = new ArrayList<>(multiShareArgs.getShareContactAndThreads().size());
Context context = ApplicationDependencies.getApplication();
boolean isMmsEnabled = Util.isMmsCapable(context);
String message = multiShareArgs.getDraftText();
SlideDeck slideDeck;
try {
slideDeck = buildSlideDeck(context, multiShareArgs);
} catch (SlideNotFoundException e) {
Log.w(TAG, "Could not create slide for media message");
for (ShareContactAndThread shareContactAndThread : multiShareArgs.getShareContactAndThreads()) {
results.add(new MultiShareSendResult(shareContactAndThread, MultiShareSendResult.Type.GENERIC_ERROR));
}
return new MultiShareSendResultCollection(results);
}
List<MultiShareSendResult> results = new ArrayList<>(multiShareArgs.getShareContactAndThreads().size());
for (ShareContactAndThread shareContactAndThread : multiShareArgs.getShareContactAndThreads()) {
Recipient recipient = Recipient.resolved(shareContactAndThread.getRecipientId());
@@ -91,7 +103,7 @@ public final class MultiShareSender {
sendMediaMessage(context, multiShareArgs, recipient, slideDeck, transport, shareContactAndThread.getThreadId(), forceSms, expiresIn, multiShareArgs.isViewOnce(), subscriptionId, mentions);
results.add(new MultiShareSendResult(shareContactAndThread, MultiShareSendResult.Type.SUCCESS));
} else {
sendTextMessage(context, multiShareArgs, recipient, shareContactAndThread.getThreadId() ,forceSms, expiresIn, subscriptionId);
sendTextMessage(context, multiShareArgs, recipient, shareContactAndThread.getThreadId(), forceSms, expiresIn, subscriptionId);
results.add(new MultiShareSendResult(shareContactAndThread, MultiShareSendResult.Type.SUCCESS));
}
@@ -180,16 +192,26 @@ public final class MultiShareSender {
MessageSender.send(context, outgoingTextMessage, threadId, forceSms, null);
}
private static @NonNull SlideDeck buildSlideDeck(@NonNull Context context, @NonNull MultiShareArgs multiShareArgs) {
private static @NonNull SlideDeck buildSlideDeck(@NonNull Context context, @NonNull MultiShareArgs multiShareArgs) throws SlideNotFoundException {
SlideDeck slideDeck = new SlideDeck();
if (multiShareArgs.getStickerLocator() != null) {
slideDeck.addSlide(new StickerSlide(context, multiShareArgs.getDataUri(), 0, multiShareArgs.getStickerLocator(), multiShareArgs.getDataType()));
} else if (!multiShareArgs.getMedia().isEmpty()) {
for (Media media : multiShareArgs.getMedia()) {
slideDeck.addSlide(SlideFactory.getSlide(context, media.getMimeType(), media.getUri(), media.getWidth(), media.getHeight()));
Slide slide = SlideFactory.getSlide(context, media.getMimeType(), media.getUri(), media.getWidth(), media.getHeight());
if (slide != null) {
slideDeck.addSlide(slide);
} else {
throw new SlideNotFoundException();
}
}
} else if (multiShareArgs.getDataUri() != null) {
slideDeck.addSlide(SlideFactory.getSlide(context, multiShareArgs.getDataType(), multiShareArgs.getDataUri(), 0, 0));
Slide slide = SlideFactory.getSlide(context, multiShareArgs.getDataType(), multiShareArgs.getDataUri(), 0, 0);
if (slide != null) {
slideDeck.addSlide(slide);
} else {
throw new SlideNotFoundException();
}
}
return slideDeck;
@@ -244,8 +266,12 @@ public final class MultiShareSender {
}
private enum Type {
GENERIC_ERROR,
MMS_NOT_ENABLED,
SUCCESS
}
}
private static final class SlideNotFoundException extends Exception {
}
}