diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java index 42dc29c5e..d3f48b5be 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationDataSource.java @@ -7,12 +7,14 @@ import androidx.annotation.Nullable; import com.annimon.stream.Stream; +import org.signal.core.util.Stopwatch; import org.signal.core.util.logging.Log; import org.signal.paging.PagedDataSource; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.conversation.ConversationData.MessageRequestData; import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationMessageFactory; import org.thoughtcrime.securesms.database.MessageDatabase; +import org.thoughtcrime.securesms.database.MmsSmsColumns; import org.thoughtcrime.securesms.database.MmsSmsDatabase; import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord; @@ -24,11 +26,12 @@ import org.thoughtcrime.securesms.database.model.ReactionRecord; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.database.model.UpdateDescription; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; +import org.thoughtcrime.securesms.payments.Payment; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; -import org.signal.core.util.Stopwatch; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.ArrayList; import java.util.Collection; @@ -39,6 +42,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.stream.Collectors; /** @@ -96,6 +100,7 @@ public class ConversationDataSource implements PagedDataSource referencedIds = new HashSet<>(); try (MmsSmsDatabase.Reader reader = MmsSmsDatabase.readerFor(db.getConversation(threadId, start, length))) { @@ -105,6 +110,7 @@ public class ConversationDataSource implements PagedDataSource paymentMessages = new HashMap<>(); + private final Map messageIdToPayment = new HashMap<>(); + + public void add(MessageRecord messageRecord) { + if (messageRecord.isMms() && messageRecord.isPaymentNotification()) { + UUID paymentUuid = UuidUtil.parseOrNull(messageRecord.getBody()); + if (paymentUuid != null) { + paymentMessages.put(paymentUuid, messageRecord.getId()); + } + } + } + + public void fetchPayments() { + List payments = SignalDatabase.payments().getPayments(paymentMessages.keySet()); + for (Payment payment : payments) { + if (payment != null) { + messageIdToPayment.put(paymentMessages.get(payment.getUuid()), payment); + } + } + } + + @NonNull List buildUpdatedModels(@NonNull List records) { + return records.stream() + .map(record -> { + if (record instanceof MediaMmsMessageRecord) { + Payment payment = messageIdToPayment.get(record.getId()); + if (payment != null) { + return ((MediaMmsMessageRecord) record).withPayment(payment); + } + } + return record; + }) + .collect(Collectors.toList()); + } + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java index 0d9e818d6..dc8d2bfc2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -1168,6 +1168,15 @@ public class ConversationFragment extends LoggingFragment implements Multiselect }); } + private void handleViewPaymentDetails(MessageRecord message) { + if (message instanceof MediaMmsMessageRecord) { + MediaMmsMessageRecord mediaMessage = (MediaMmsMessageRecord) message; + if (mediaMessage.isPaymentNotification() && mediaMessage.getPayment() != null) { + startActivity(PaymentsActivity.navigateToPaymentDetails(requireContext(), mediaMessage.getPayment().getUuid())); + } + } + } + private void performSave(final MediaMmsMessageRecord message) { List attachments = Stream.of(message.getSlideDeck().getSlides()) .filter(s -> s.getUri() != null && (s.hasImage() || s.hasVideo() || s.hasAudio() || s.hasDocument())) @@ -2287,6 +2296,9 @@ public class ConversationFragment extends LoggingFragment implements Multiselect case COPY: handleCopyMessage(conversationMessage.getMultiselectCollection().toSet()); break; + case PAYMENT_DETAILS: + handleViewPaymentDetails(conversationMessage.getMessageRecord()); + break; case MULTISELECT: handleEnterMultiSelect(conversationMessage); break; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index f7f279941..3fd444c00 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -95,6 +95,7 @@ import org.thoughtcrime.securesms.conversation.colors.ChatColors; import org.thoughtcrime.securesms.conversation.colors.Colorizer; import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectCollection; import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart; +import org.thoughtcrime.securesms.conversation.ui.payment.PaymentMessageView; import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.MediaDatabase; import org.thoughtcrime.securesms.database.MessageDatabase; @@ -181,14 +182,14 @@ public final class ConversationItem extends RelativeLayout implements BindableCo private static final long MAX_CLUSTERING_TIME_DIFF = TimeUnit.MINUTES.toMillis(3); private static final int CONDENSED_MODE_MAX_LINES = 3; - private ConversationMessage conversationMessage; - private MessageRecord messageRecord; - private Optional nextMessageRecord; - private Locale locale; - private boolean groupThread; - private LiveRecipient recipient; - private GlideRequests glideRequests; - private ValueAnimator pulseOutlinerAlphaAnimator; + private ConversationMessage conversationMessage; + private MessageRecord messageRecord; + private Optional nextMessageRecord; + private Locale locale; + private boolean groupThread; + private LiveRecipient recipient; + private GlideRequests glideRequests; + private ValueAnimator pulseOutlinerAlphaAnimator; private Optional previousMessage; private ConversationItemDisplayMode displayMode; @@ -224,6 +225,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo private Stub revealableStub; private Stub