mirror of
https://github.com/joinmarket-webui/jam.git
synced 2026-08-20 13:28:21 +02:00
feat: payment confirm modal (#446)
* feat: payment confirm modal * dev: show success text in confirm modal if privacy is enabled * dev: improved sweep text in confirm modal * dev: display source jar in confirm modal * review: improve sweep info in confirm modal
This commit is contained in:
parent
2d9d13ea90
commit
29eca37535
3 changed files with 119 additions and 1 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState, useMemo } from 'react'
|
||||
import React, { useEffect, useState, useMemo, useRef } from 'react'
|
||||
import { Link, useLocation } from 'react-router-dom'
|
||||
import { Trans, useTranslation } from 'react-i18next'
|
||||
import * as rb from 'react-bootstrap'
|
||||
|
|
@ -19,6 +19,7 @@ import * as Api from '../libs/JmWalletApi'
|
|||
import { SATS, formatBtc, formatSats } from '../utils'
|
||||
import { routes } from '../constants/routes'
|
||||
import styles from './Send.module.css'
|
||||
import { ConfirmModal } from './Modal'
|
||||
|
||||
const IS_COINJOIN_DEFAULT_VAL = true
|
||||
// initial value for `minimum_makers` from the default joinmarket.cfg (last check on 2022-02-20 of v0.9.5)
|
||||
|
|
@ -297,6 +298,9 @@ export default function Send() {
|
|||
[isInitializing, waitForUtxosToBeSpent]
|
||||
)
|
||||
|
||||
const [showConfirmInputsModal, setShowConfirmInputsModal] = useState(false)
|
||||
const submitButtonRef = useRef(null)
|
||||
|
||||
useEffect(() => {
|
||||
setTakerStartedInfoAlert((current) => (isCoinjoinInProgress ? current : null))
|
||||
}, [isCoinjoinInProgress])
|
||||
|
|
@ -542,10 +546,19 @@ export default function Send() {
|
|||
|
||||
if (isLoading || isOperationDisabled) return
|
||||
|
||||
setPaymentSuccessfulInfoAlert(null)
|
||||
|
||||
const form = e.currentTarget
|
||||
const isValid = formIsValid
|
||||
|
||||
if (isValid) {
|
||||
if (!showConfirmInputsModal) {
|
||||
setShowConfirmInputsModal(true)
|
||||
return
|
||||
}
|
||||
|
||||
setShowConfirmInputsModal(false)
|
||||
|
||||
const counterparties = parseInt(numCollaborators, 10)
|
||||
|
||||
if (isSweep && amount !== 0) {
|
||||
|
|
@ -900,6 +913,7 @@ export default function Send() {
|
|||
/>
|
||||
)}
|
||||
<rb.Button
|
||||
ref={submitButtonRef}
|
||||
variant={isCoinjoin ? 'dark' : 'danger'}
|
||||
type="submit"
|
||||
disabled={isOperationDisabled || isLoading || isSending || !formIsValid}
|
||||
|
|
@ -917,6 +931,91 @@ export default function Send() {
|
|||
t('send.button_send_without_improved_privacy')
|
||||
)}
|
||||
</rb.Button>
|
||||
<ConfirmModal
|
||||
isShown={showConfirmInputsModal}
|
||||
title={t('send.confirm_modal.title')}
|
||||
onCancel={() => setShowConfirmInputsModal(false)}
|
||||
onConfirm={() => {
|
||||
submitButtonRef.current?.click()
|
||||
}}
|
||||
>
|
||||
<rb.Container className="mt-2">
|
||||
<rb.Row className="mt-2 mb-3">
|
||||
<rb.Col xs={12} className="text-center">
|
||||
{isCoinjoin ? (
|
||||
<strong className="text-success">{t('send.confirm_modal.text_collaborative_tx_enabled')}</strong>
|
||||
) : (
|
||||
<strong className="text-danger">{t('send.confirm_modal.text_collaborative_tx_disabled')}</strong>
|
||||
)}
|
||||
</rb.Col>
|
||||
</rb.Row>
|
||||
<rb.Row>
|
||||
<rb.Col xs={3} className="text-end">
|
||||
<strong>{t('send.confirm_modal.label_source_jar')}</strong>
|
||||
</rb.Col>
|
||||
<rb.Col xs={9} className="text-start">
|
||||
{t('send.confirm_modal.text_source_jar', {
|
||||
jarId: `#${account}`,
|
||||
})}
|
||||
</rb.Col>
|
||||
</rb.Row>
|
||||
<rb.Row>
|
||||
<rb.Col xs={3} className="text-end">
|
||||
<strong>{t('send.confirm_modal.label_recipient')}</strong>
|
||||
</rb.Col>
|
||||
<rb.Col xs={9} className="text-start text-break slashed-zeroes">
|
||||
{destination}
|
||||
</rb.Col>
|
||||
</rb.Row>
|
||||
<rb.Row>
|
||||
<rb.Col xs={3} className="text-end">
|
||||
<strong>{t('send.confirm_modal.label_amount')}</strong>
|
||||
</rb.Col>
|
||||
<rb.Col xs={9} className="text-start">
|
||||
{isSweep ? (
|
||||
<div className="d-flex justify-content-start align-items-center">
|
||||
<Trans i18nKey="send.confirm_modal.text_sweep_balance">
|
||||
Sweep
|
||||
<Balance
|
||||
valueString={amountFieldValue().toString()}
|
||||
convertToUnit={settings.unit}
|
||||
showBalance={true}
|
||||
/>
|
||||
</Trans>
|
||||
<rb.OverlayTrigger
|
||||
placement="right"
|
||||
overlay={
|
||||
<rb.Popover>
|
||||
<rb.Popover.Body>{t('send.confirm_modal.text_sweep_info_popover')}</rb.Popover.Body>
|
||||
</rb.Popover>
|
||||
}
|
||||
>
|
||||
<div className="d-inline-flex align-items-center">
|
||||
<Sprite className={styles.infoIcon} symbol="info" width="13" height="13" />
|
||||
</div>
|
||||
</rb.OverlayTrigger>
|
||||
</div>
|
||||
) : (
|
||||
<Balance
|
||||
valueString={amountFieldValue().toString()}
|
||||
convertToUnit={settings.unit}
|
||||
showBalance={true}
|
||||
/>
|
||||
)}
|
||||
</rb.Col>
|
||||
</rb.Row>
|
||||
{isCoinjoin && (
|
||||
<rb.Row>
|
||||
<rb.Col xs={3} className="text-end">
|
||||
<strong>{t('send.confirm_modal.label_num_collaborators')}</strong>
|
||||
</rb.Col>
|
||||
<rb.Col xs={9} className="text-start">
|
||||
{numCollaborators}
|
||||
</rb.Col>
|
||||
</rb.Row>
|
||||
)}
|
||||
</rb.Container>
|
||||
</ConfirmModal>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -150,6 +150,13 @@ input[type='number'] {
|
|||
filter: blur(2px);
|
||||
}
|
||||
|
||||
.infoIcon {
|
||||
margin: 2px 0 0 0.25rem;
|
||||
color: var(--bs-gray-500);
|
||||
border: 1px solid var(--bs-gray-500);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.accordion-button {
|
||||
border: none;
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -188,6 +188,18 @@
|
|||
"sweep_amount_breakdown_frozen_balance": "Frozen or locked balance",
|
||||
"sweep_amount_breakdown_estimated_amount": "Estimated amount to be sent",
|
||||
"sweep_amount_breakdown_explanation": "A sweep transaction will consume all UTXOs of a mixdepth leaving no coins behind except those that have been <1>frozen</1> or <3>time-locked</3>. Onchain transaction fees and market maker fees will be deducted from the amount so as to leave zero change. The exact transaction amount can only be calculated by JoinMarket at the point when the transaction is made. Therefore the estimated amount shown might deviate from the actually sent amount. Refer to the <5>JoinMarket documentation</5> for more details.",
|
||||
"confirm_modal": {
|
||||
"title": "Confirm payment",
|
||||
"label_amount": "Amount",
|
||||
"text_sweep_balance": "Sweep whole jar (<1></1>)",
|
||||
"text_sweep_info_popover": "The exact transaction amount can only be calculated by JoinMarket at the point when the transaction is made.",
|
||||
"label_recipient": "Recipient",
|
||||
"label_source_jar": "Send from",
|
||||
"text_source_jar": "Jar {{ jarId }}",
|
||||
"label_num_collaborators": "Collaborators",
|
||||
"text_collaborative_tx_enabled": "Payment with privacy improvement",
|
||||
"text_collaborative_tx_disabled": "Payment without privacy improvement"
|
||||
},
|
||||
"coinjoin_precondition": {
|
||||
"hint_missing_utxos": "To execute a collaborative transaction you need at least one UTXO with <2>{{ minConfirmations }}</2> confirmations in the source jar. Select another jar to send from or fund this jar and wait for <6>{{ minConfirmations }}</6> blocks.",
|
||||
"hint_missing_confirmations": "A collaborative transaction requires one of your UTXOs to have <2>{{ minConfirmations }}</2> or more confirmations. Select another jar to send from or wait for <6>{{ amountOfMissingConfirmations }}</6> more block(s).",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue