mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 09:20:19 +01:00
Add import and tombstones for mobile coin payments.
This commit is contained in:
@@ -110,6 +110,7 @@ import org.thoughtcrime.securesms.database.MediaTable;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.Quote;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.MessageExtras;
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies;
|
||||
import org.thoughtcrime.securesms.events.PartProgressEvent;
|
||||
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicy;
|
||||
@@ -261,6 +262,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
private final TouchDelegateChangedListener touchDelegateChangedListener = new TouchDelegateChangedListener();
|
||||
private final DoubleTapEditTouchListener doubleTapEditTouchListener = new DoubleTapEditTouchListener();
|
||||
private final GiftMessageViewCallback giftMessageViewCallback = new GiftMessageViewCallback();
|
||||
private final PaymentTombstoneClickListener paymentTombstoneClickListener = new PaymentTombstoneClickListener();
|
||||
|
||||
private final Context context;
|
||||
|
||||
@@ -1038,7 +1040,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
bodyText.setText(italics);
|
||||
bodyText.setVisibility(View.VISIBLE);
|
||||
bodyText.setOverflowText(null);
|
||||
} else if (isCaptionlessMms(messageRecord) || isStoryReaction(messageRecord) || isGiftMessage(messageRecord) || messageRecord.isPaymentNotification()) {
|
||||
} else if (isCaptionlessMms(messageRecord) || isStoryReaction(messageRecord) || isGiftMessage(messageRecord) || messageRecord.isPaymentNotification() || messageRecord.isPaymentTombstone()) {
|
||||
bodyText.setText(null);
|
||||
bodyText.setOverflowText(null);
|
||||
bodyText.setVisibility(View.GONE);
|
||||
@@ -1396,8 +1398,29 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
MmsMessageRecord mediaMmsMessageRecord = (MmsMessageRecord) messageRecord;
|
||||
|
||||
paymentViewStub.setVisibility(View.VISIBLE);
|
||||
paymentViewStub.get().setOnTombstoneClickListener(paymentTombstoneClickListener);
|
||||
paymentViewStub.get().bindPayment(conversationRecipient.get(), Objects.requireNonNull(mediaMmsMessageRecord.getPayment()), colorizer);
|
||||
|
||||
footer.setVisibility(VISIBLE);
|
||||
} else if (messageRecord.isPaymentTombstone()) {
|
||||
if (mediaThumbnailStub.resolved()) mediaThumbnailStub.require().setVisibility(GONE);
|
||||
if (audioViewStub.resolved()) audioViewStub.get().setVisibility(GONE);
|
||||
if (documentViewStub.resolved()) documentViewStub.get().setVisibility(GONE);
|
||||
if (sharedContactStub.resolved()) sharedContactStub.get().setVisibility(GONE);
|
||||
if (linkPreviewStub.resolved()) linkPreviewStub.get().setVisibility(GONE);
|
||||
if (stickerStub.resolved()) stickerStub.get().setVisibility(GONE);
|
||||
if (revealableStub.resolved()) revealableStub.get().setVisibility(GONE);
|
||||
if (giftViewStub.resolved()) giftViewStub.get().setVisibility(View.GONE);
|
||||
if (joinCallLinkStub.resolved()) joinCallLinkStub.get().setVisibility(View.GONE);
|
||||
|
||||
MmsMessageRecord mediaMmsMessageRecord = (MmsMessageRecord) messageRecord;
|
||||
|
||||
paymentViewStub.setVisibility(View.VISIBLE);
|
||||
paymentViewStub.get().setOnTombstoneClickListener(paymentTombstoneClickListener);
|
||||
MessageExtras messageExtras = mediaMmsMessageRecord.getMessageExtras();
|
||||
|
||||
paymentViewStub.get().bindPaymentTombstone(mediaMmsMessageRecord.isOutgoing(), conversationRecipient.get(), messageExtras == null ? null : messageExtras.paymentTombstone, colorizer);
|
||||
|
||||
footer.setVisibility(VISIBLE);
|
||||
} else {
|
||||
if (mediaThumbnailStub.resolved()) mediaThumbnailStub.require().setVisibility(View.GONE);
|
||||
@@ -2352,6 +2375,16 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
return null;
|
||||
}
|
||||
|
||||
private class PaymentTombstoneClickListener implements View.OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (eventListener != null) {
|
||||
eventListener.onPaymentTombstoneClicked();
|
||||
} else {
|
||||
passthroughClickListener.onClick(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
private class SharedContactEventListener implements SharedContactView.EventListener {
|
||||
@Override
|
||||
public void onAddToContactsClicked(@NonNull Contact contact) {
|
||||
|
||||
@@ -135,7 +135,7 @@ public final class MenuState {
|
||||
hasGift = true;
|
||||
}
|
||||
|
||||
if (messageRecord.isPaymentNotification()) {
|
||||
if (messageRecord.isPaymentNotification() || messageRecord.isPaymentTombstone()) {
|
||||
hasPayment = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,14 @@ import org.signal.core.util.dp
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.quotes.QuoteViewColorTheme
|
||||
import org.thoughtcrime.securesms.conversation.colors.Colorizer
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.PaymentTombstone
|
||||
import org.thoughtcrime.securesms.databinding.PaymentMessageViewBinding
|
||||
import org.thoughtcrime.securesms.payments.CryptoValueUtil
|
||||
import org.thoughtcrime.securesms.payments.Direction
|
||||
import org.thoughtcrime.securesms.payments.Payment
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.visible
|
||||
import org.whispersystems.signalservice.api.payments.Money
|
||||
|
||||
/**
|
||||
* Showing payment information in conversation.
|
||||
@@ -30,11 +33,25 @@ class PaymentMessageView @JvmOverloads constructor(
|
||||
|
||||
private val binding: PaymentMessageViewBinding
|
||||
|
||||
private var onTombstoneClickListener: OnClickListener? = null
|
||||
|
||||
init {
|
||||
binding = PaymentMessageViewBinding.inflate(LayoutInflater.from(context), this, true)
|
||||
}
|
||||
|
||||
fun bindPayment(recipient: Recipient, payment: Payment, colorizer: Colorizer) {
|
||||
fun bindPayment(recipient: Recipient, payment: Payment?, colorizer: Colorizer) {
|
||||
if (payment == null) {
|
||||
binding.paymentTombstone.visible = true
|
||||
binding.paymentAmount.visible = false
|
||||
binding.paymentInprogress.visible = false
|
||||
binding.paymentAmountLayout.setOnClickListener {
|
||||
onTombstoneClickListener?.onClick(it)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
binding.paymentAmountLayout.setOnClickListener(null)
|
||||
binding.paymentTombstone.visible = false
|
||||
val outgoing = payment.direction == Direction.SENT
|
||||
|
||||
binding.paymentDirection.apply {
|
||||
@@ -69,6 +86,51 @@ class PaymentMessageView @JvmOverloads constructor(
|
||||
ViewCompat.setBackgroundTintList(binding.paymentAmountLayout, ColorStateList.valueOf(quoteViewColorTheme.getBackgroundColor(context)))
|
||||
}
|
||||
|
||||
fun bindPaymentTombstone(outgoing: Boolean, recipient: Recipient, paymentTombstone: PaymentTombstone?, colorizer: Colorizer) {
|
||||
val amount: Money? = if (paymentTombstone?.amount != null) {
|
||||
CryptoValueUtil.cryptoValueToMoney(paymentTombstone.amount)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
binding.paymentDirection.apply {
|
||||
if (outgoing) {
|
||||
text = context.getString(R.string.PaymentMessageView_you_sent_s, recipient.getShortDisplayName(context))
|
||||
setTextColor(colorizer.getOutgoingFooterTextColor(context))
|
||||
} else {
|
||||
text = context.getString(R.string.PaymentMessageView_s_sent_you, recipient.getShortDisplayName(context))
|
||||
setTextColor(colorizer.getIncomingFooterTextColor(context, recipient.hasWallpaper))
|
||||
}
|
||||
}
|
||||
if (amount == null) {
|
||||
binding.paymentTombstone.visible = true
|
||||
binding.paymentAmount.visible = false
|
||||
binding.paymentInprogress.visible = false
|
||||
binding.paymentAmountLayout.setOnClickListener {
|
||||
onTombstoneClickListener?.onClick(it)
|
||||
}
|
||||
return
|
||||
}
|
||||
val note = paymentTombstone?.note ?: ""
|
||||
binding.paymentAmountLayout.setOnClickListener(null)
|
||||
binding.paymentTombstone.visible = false
|
||||
|
||||
binding.paymentNote.apply {
|
||||
text = note
|
||||
visible = note.isNotEmpty()
|
||||
setTextColor(if (outgoing) colorizer.getOutgoingBodyTextColor(context) else colorizer.getIncomingBodyTextColor(context, recipient.hasWallpaper))
|
||||
}
|
||||
|
||||
val quoteViewColorTheme = QuoteViewColorTheme.resolveTheme(outgoing, false, recipient.hasWallpaper)
|
||||
|
||||
binding.paymentAmount.visible = true
|
||||
binding.paymentInprogress.visible = false
|
||||
binding.paymentAmount.setTextColor(quoteViewColorTheme.getForegroundColor(context))
|
||||
binding.paymentAmount.setMoney(amount, 0L, currencyTypefaceSpan)
|
||||
|
||||
ViewCompat.setBackgroundTintList(binding.paymentAmountLayout, ColorStateList.valueOf(quoteViewColorTheme.getBackgroundColor(context)))
|
||||
}
|
||||
|
||||
private fun getInProgressDrawable(@ColorInt color: Int): IndeterminateDrawable<CircularProgressIndicatorSpec> {
|
||||
val spec = CircularProgressIndicatorSpec(context, null).apply {
|
||||
indicatorInset = 0
|
||||
@@ -82,6 +144,10 @@ class PaymentMessageView @JvmOverloads constructor(
|
||||
return drawable
|
||||
}
|
||||
|
||||
fun setOnTombstoneClickListener(listener: OnClickListener?) {
|
||||
this.onTombstoneClickListener = listener
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val currencyTypefaceSpan = TypefaceSpan("sans-serif-light")
|
||||
}
|
||||
|
||||
@@ -2367,12 +2367,26 @@ class ConversationFragment :
|
||||
|
||||
private fun handleViewPaymentDetails(conversationMessage: ConversationMessage) {
|
||||
val record: MmsMessageRecord = conversationMessage.messageRecord as? MmsMessageRecord ?: return
|
||||
val payment = record.payment ?: return
|
||||
val payment = record.payment
|
||||
if (payment == null || record.isPaymentTombstone) {
|
||||
showPaymentTombstoneLearnMoreDialog()
|
||||
return
|
||||
}
|
||||
if (record.isPaymentNotification) {
|
||||
startActivity(PaymentsActivity.navigateToPaymentDetails(requireContext(), payment.uuid))
|
||||
}
|
||||
}
|
||||
|
||||
private fun showPaymentTombstoneLearnMoreDialog() {
|
||||
val dialogBuilder = MaterialAlertDialogBuilder(requireContext())
|
||||
dialogBuilder
|
||||
.setTitle(R.string.PaymentTombstoneLearnMoreDialog_title)
|
||||
.setMessage(R.string.PaymentTombstoneLearnMoreDialog_message)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
|
||||
dialogBuilder.show()
|
||||
}
|
||||
|
||||
private fun handleDisplayDetails(conversationMessage: ConversationMessage) {
|
||||
val recipientSnapshot = viewModel.recipientSnapshot ?: return
|
||||
MessageDetailsFragment.create(conversationMessage.messageRecord, recipientSnapshot.id).show(childFragmentManager, null)
|
||||
@@ -2801,6 +2815,10 @@ class ConversationFragment :
|
||||
DoubleTapEditEducationSheet(conversationMessage).show(childFragmentManager, DoubleTapEditEducationSheet.KEY)
|
||||
}
|
||||
|
||||
override fun onPaymentTombstoneClicked() {
|
||||
this@ConversationFragment.showPaymentTombstoneLearnMoreDialog()
|
||||
}
|
||||
|
||||
override fun onMessageWithErrorClicked(messageRecord: MessageRecord) {
|
||||
val recipientId = viewModel.recipientSnapshot?.id ?: return
|
||||
if (messageRecord.isIdentityMismatchFailure) {
|
||||
|
||||
Reference in New Issue
Block a user