kopia lustrzana https://github.com/ryukoposting/Signal-Android
Fix story splitting in multishare flow.
rodzic
bdbeefe08e
commit
af0fbdd2b2
|
@ -0,0 +1,38 @@
|
||||||
|
package org.thoughtcrime.securesms.sharing
|
||||||
|
|
||||||
|
import androidx.annotation.Discouraged
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timestamp provider for distribution lists, which will reuse previous
|
||||||
|
* timestamps for identical indices.
|
||||||
|
*/
|
||||||
|
class DistributionListMultiShareTimestampProvider(
|
||||||
|
getCurrentTimeMillis: () -> Duration = { System.currentTimeMillis().milliseconds },
|
||||||
|
sleepTimeout: Duration = 5.milliseconds
|
||||||
|
) : MultiShareTimestampProvider(getCurrentTimeMillis, sleepTimeout) {
|
||||||
|
|
||||||
|
private val timestamps = mutableListOf(getCurrentTimeMillis())
|
||||||
|
|
||||||
|
override fun getMillis(index: Int): Long {
|
||||||
|
fillToIndex(index)
|
||||||
|
return timestamps[index].inWholeMilliseconds
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fillToIndex(index: Int) {
|
||||||
|
if (index in timestamps.indices) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
(timestamps.size..index).forEach {
|
||||||
|
timestamps.add(it, waitForTime())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
@Discouraged(message = "This only exists because of Java.")
|
||||||
|
fun create(): DistributionListMultiShareTimestampProvider = DistributionListMultiShareTimestampProvider()
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,7 +101,7 @@ public final class MultiShareSender {
|
||||||
return new MultiShareSendResultCollection(results);
|
return new MultiShareSendResultCollection(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
long distributionListSentTimestamp = System.currentTimeMillis();
|
DistributionListMultiShareTimestampProvider distributionListSentTimestamps = DistributionListMultiShareTimestampProvider.create();
|
||||||
for (ContactSearchKey.RecipientSearchKey recipientSearchKey : multiShareArgs.getRecipientSearchKeys()) {
|
for (ContactSearchKey.RecipientSearchKey recipientSearchKey : multiShareArgs.getRecipientSearchKeys()) {
|
||||||
Recipient recipient = Recipient.resolved(recipientSearchKey.getRecipientId());
|
Recipient recipient = Recipient.resolved(recipientSearchKey.getRecipientId());
|
||||||
|
|
||||||
|
@ -123,8 +123,9 @@ public final class MultiShareSender {
|
||||||
multiShareArgs.getLinkPreview() != null ||
|
multiShareArgs.getLinkPreview() != null ||
|
||||||
!mentions.isEmpty() ||
|
!mentions.isEmpty() ||
|
||||||
needsSplit;
|
needsSplit;
|
||||||
long sentTimestamp = recipient.isDistributionList() ? distributionListSentTimestamp : System.currentTimeMillis();
|
|
||||||
boolean canSendAsTextStory = recipientSearchKey.isStory() && multiShareArgs.isValidForTextStoryGeneration();
|
MultiShareTimestampProvider sentTimestamp = recipient.isDistributionList() ? distributionListSentTimestamps : MultiShareTimestampProvider.create();
|
||||||
|
boolean canSendAsTextStory = recipientSearchKey.isStory() && multiShareArgs.isValidForTextStoryGeneration();
|
||||||
|
|
||||||
if ((recipient.isMmsGroup() || recipient.getEmail().isPresent()) && !isMmsEnabled) {
|
if ((recipient.isMmsGroup() || recipient.getEmail().isPresent()) && !isMmsEnabled) {
|
||||||
results.add(new MultiShareSendResult(recipientSearchKey, MultiShareSendResult.Type.MMS_NOT_ENABLED));
|
results.add(new MultiShareSendResult(recipientSearchKey, MultiShareSendResult.Type.MMS_NOT_ENABLED));
|
||||||
|
@ -209,7 +210,7 @@ public final class MultiShareSender {
|
||||||
int subscriptionId,
|
int subscriptionId,
|
||||||
@NonNull List<Mention> validatedMentions,
|
@NonNull List<Mention> validatedMentions,
|
||||||
boolean isStory,
|
boolean isStory,
|
||||||
long sentTimestamp,
|
@NonNull MultiShareTimestampProvider sentTimestamps,
|
||||||
boolean canSendAsTextStory,
|
boolean canSendAsTextStory,
|
||||||
@NonNull List<OutgoingMessage> storiesToBatchSend,
|
@NonNull List<OutgoingMessage> storiesToBatchSend,
|
||||||
@NonNull ChatColors generatedTextStoryBackgroundColor)
|
@NonNull ChatColors generatedTextStoryBackgroundColor)
|
||||||
|
@ -242,7 +243,7 @@ public final class MultiShareSender {
|
||||||
OutgoingMessage outgoingMessage = new OutgoingMessage(recipient,
|
OutgoingMessage outgoingMessage = new OutgoingMessage(recipient,
|
||||||
new SlideDeck(),
|
new SlideDeck(),
|
||||||
body,
|
body,
|
||||||
sentTimestamp,
|
sentTimestamps.getMillis(0),
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
0L,
|
0L,
|
||||||
false,
|
false,
|
||||||
|
@ -253,7 +254,7 @@ public final class MultiShareSender {
|
||||||
|
|
||||||
outgoingMessages.add(outgoingMessage);
|
outgoingMessages.add(outgoingMessage);
|
||||||
} else if (canSendAsTextStory) {
|
} else if (canSendAsTextStory) {
|
||||||
outgoingMessages.add(generateTextStory(context, recipient, multiShareArgs, sentTimestamp, storyType, generatedTextStoryBackgroundColor));
|
outgoingMessages.add(generateTextStory(context, recipient, multiShareArgs, sentTimestamps.getMillis(0), storyType, generatedTextStoryBackgroundColor));
|
||||||
} else {
|
} else {
|
||||||
List<Slide> storySupportedSlides = slideDeck.getSlides()
|
List<Slide> storySupportedSlides = slideDeck.getSlides()
|
||||||
.stream()
|
.stream()
|
||||||
|
@ -269,14 +270,16 @@ public final class MultiShareSender {
|
||||||
.filter(it -> MediaUtil.isStorySupportedType(it.getContentType()))
|
.filter(it -> MediaUtil.isStorySupportedType(it.getContentType()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
for (final Slide slide : storySupportedSlides) {
|
for (int i = 0; i < storySupportedSlides.size(); i++) {
|
||||||
|
Slide slide = storySupportedSlides.get(i);
|
||||||
SlideDeck singletonDeck = new SlideDeck();
|
SlideDeck singletonDeck = new SlideDeck();
|
||||||
|
|
||||||
singletonDeck.addSlide(slide);
|
singletonDeck.addSlide(slide);
|
||||||
|
|
||||||
OutgoingMessage outgoingMessage = new OutgoingMessage(recipient,
|
OutgoingMessage outgoingMessage = new OutgoingMessage(recipient,
|
||||||
singletonDeck,
|
singletonDeck,
|
||||||
body,
|
body,
|
||||||
sentTimestamp,
|
sentTimestamps.getMillis(i),
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
0L,
|
0L,
|
||||||
false,
|
false,
|
||||||
|
@ -292,7 +295,7 @@ public final class MultiShareSender {
|
||||||
OutgoingMessage outgoingMessage = new OutgoingMessage(recipient,
|
OutgoingMessage outgoingMessage = new OutgoingMessage(recipient,
|
||||||
slideDeck,
|
slideDeck,
|
||||||
body,
|
body,
|
||||||
sentTimestamp,
|
sentTimestamps.getMillis(0),
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
expiresIn,
|
expiresIn,
|
||||||
isViewOnce,
|
isViewOnce,
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package org.thoughtcrime.securesms.sharing
|
||||||
|
|
||||||
|
import androidx.annotation.Discouraged
|
||||||
|
import org.signal.core.util.ThreadUtil
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default multi-share timestamp provider, which will return a different timestamp on each invocation.
|
||||||
|
*/
|
||||||
|
open class MultiShareTimestampProvider(
|
||||||
|
private val getCurrentTime: () -> Duration = { System.currentTimeMillis().milliseconds },
|
||||||
|
private val sleepTimeout: Duration = 5.milliseconds
|
||||||
|
) {
|
||||||
|
|
||||||
|
open fun getMillis(index: Int): Long {
|
||||||
|
return waitForTime().inWholeMilliseconds
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun waitForTime(): Duration {
|
||||||
|
ThreadUtil.sleep(sleepTimeout.inWholeMilliseconds)
|
||||||
|
return getCurrentTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
@Discouraged(message = "This only exists because of Java.")
|
||||||
|
fun create(): MultiShareTimestampProvider = MultiShareTimestampProvider()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package org.thoughtcrime.securesms.sharing
|
||||||
|
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
|
class DistributionListMultiShareTimestampProviderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `When I ask for index 4, then I expect to fill 4 new items`() {
|
||||||
|
val generator = mutableListOf(1L, 2, 3, 4, 5).map { it.seconds }.toMutableList()
|
||||||
|
val testSubject = DistributionListMultiShareTimestampProvider(getCurrentTimeMillis = { generator.removeAt(0) }, sleepTimeout = 0.seconds)
|
||||||
|
|
||||||
|
val actual = testSubject.getMillis(4).milliseconds
|
||||||
|
assertEquals(5.seconds, actual)
|
||||||
|
}
|
||||||
|
}
|
Ładowanie…
Reference in New Issue