Skip to content

Commit

Permalink
feat: quick freeze/unfreeze UTXOs on send page (#771)
Browse files Browse the repository at this point in the history
  • Loading branch information
amitx13 authored Jul 22, 2024
1 parent 707f210 commit 5c8f81e
Show file tree
Hide file tree
Showing 16 changed files with 720 additions and 40 deletions.
6 changes: 6 additions & 0 deletions public/sprite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 15 additions & 4 deletions src/components/Balance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,28 @@ interface BalanceComponentProps {
symbol?: JSX.Element
showSymbol?: boolean
frozen?: boolean
isColorChange?: boolean
frozenSymbol?: boolean
}

const BalanceComponent = ({
symbol,
showSymbol = true,
frozen = false,
isColorChange = false,
frozenSymbol = true,
children,
}: PropsWithChildren<BalanceComponentProps>) => {
return (
<span
className={classNames(styles.balance, 'balance-hook', 'd-inline-flex align-items-center', {
className={classNames('balance-hook', 'd-inline-flex align-items-center', {
[styles.frozen]: frozen,
[styles.balance]: !isColorChange,
})}
>
{children}
{showSymbol && symbol}
{frozen && FROZEN_SYMBOL}
{frozen && frozenSymbol && FROZEN_SYMBOL}
</span>
)
}
Expand All @@ -75,7 +80,9 @@ const BitcoinBalance = ({ value, ...props }: BitcoinBalanceProps) => {
return (
<BalanceComponent symbol={BTC_SYMBOL} {...props}>
<span
className={`${styles.bitcoinAmount} slashed-zeroes`}
className={classNames(`slashed-zeroes`, {
[styles.bitcoinAmount]: !props.isColorChange,
})}
data-testid="bitcoin-amount"
data-integer-part-is-zero={integerPartIsZero}
data-fractional-part-starts-with-zero={fractionalPartStartsWithZero}
Expand All @@ -101,7 +108,11 @@ type SatsBalanceProps = Omit<BalanceComponentProps, 'symbol'> & { value: number
const SatsBalance = ({ value, ...props }: SatsBalanceProps) => {
return (
<BalanceComponent symbol={SAT_SYMBOL} {...props}>
<span className={`${styles.satsAmount} slashed-zeroes`} data-testid="sats-amount" data-raw-value={value}>
<span
className={classNames(`slashed-zeroes`, { [styles.satsAmount]: !props.isColorChange })}
data-testid="sats-amount"
data-raw-value={value}
>
{formatSats(value)}
</span>
</BalanceComponent>
Expand Down
23 changes: 19 additions & 4 deletions src/components/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ type BaseModalProps = {
onCancel: () => void
backdrop?: rb.ModalProps['backdrop']
size?: rb.ModalProps['size']
showCloseButton?: boolean
headerClassName?: string
titleClassName?: string
}
const BaseModal = ({
isShown,
Expand All @@ -18,6 +21,9 @@ const BaseModal = ({
onCancel,
size,
backdrop = 'static',
showCloseButton = false,
headerClassName,
titleClassName,
}: PropsWithChildren<BaseModalProps>) => {
return (
<rb.Modal
Expand All @@ -31,8 +37,8 @@ const BaseModal = ({
size={size}
className={styles.modal}
>
<rb.Modal.Header className={styles['modal-header']}>
<rb.Modal.Title className={styles['modal-title']}>{title}</rb.Modal.Title>
<rb.Modal.Header className={`${styles['modal-header']} ${headerClassName}`} closeButton={showCloseButton}>
<rb.Modal.Title className={`${styles['modal-title']} ${titleClassName}`}>{title}</rb.Modal.Title>
</rb.Modal.Header>
{children}
</rb.Modal>
Expand Down Expand Up @@ -65,9 +71,18 @@ const InfoModal = ({

export type ConfirmModalProps = BaseModalProps & {
onConfirm: () => void
disabled?: boolean
confirmVariant?: string
}

const ConfirmModal = ({ children, onCancel, onConfirm, ...baseModalProps }: PropsWithChildren<ConfirmModalProps>) => {
const ConfirmModal = ({
children,
onCancel,
onConfirm,
disabled = false,
confirmVariant = 'outline-dark',
...baseModalProps
}: PropsWithChildren<ConfirmModalProps>) => {
const { t } = useTranslation()

return (
Expand All @@ -82,7 +97,7 @@ const ConfirmModal = ({ children, onCancel, onConfirm, ...baseModalProps }: Prop
<Sprite symbol="cancel" width="26" height="26" />
<div>{t('modal.confirm_button_reject')}</div>
</rb.Button>
<rb.Button variant="outline-dark" onClick={() => onConfirm()}>
<rb.Button variant={confirmVariant} onClick={() => onConfirm()} disabled={disabled}>
{t('modal.confirm_button_accept')}
</rb.Button>
</rb.Modal.Footer>
Expand Down
21 changes: 20 additions & 1 deletion src/components/Send/AmountInputField.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useRef } from 'react'
import { useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import * as rb from 'react-bootstrap'
import { useField, useFormikContext } from 'formik'
Expand Down Expand Up @@ -35,6 +35,25 @@ export const AmountInputField = ({
const form = useFormikContext<any>()
const ref = useRef<HTMLInputElement>(null)

//Effect to change the field value whenever the sourceJarBalance changes (sourceJarBalance will change when quick freeze/unfreeze is performed or different source jar is selected)
useEffect(() => {
if (!sourceJarBalance) return

const currentValue = formatBtcDisplayValue(sourceJarBalance.calculatedAvailableBalanceInSats)

if (field.value?.isSweep && field.value.displayValue !== currentValue) {
form.setFieldValue(
field.name,
{
value: 0,
isSweep: true,
displayValue: formatBtcDisplayValue(sourceJarBalance.calculatedAvailableBalanceInSats),
},
true,
)
}
}, [sourceJarBalance, field, form])

return (
<>
<rb.Form.Group className="mb-4" controlId={name}>
Expand Down
8 changes: 7 additions & 1 deletion src/components/Send/SendForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
isValidNumCollaborators,
} from './helpers'
import { AccountBalanceSummary } from '../../context/BalanceSummary'
import { WalletInfo } from '../../context/WalletContext'
import { WalletInfo, CurrentWallet } from '../../context/WalletContext'
import { useSettings } from '../../context/SettingsContext'
import styles from './SendForm.module.css'
import { TxFeeInputField, validateTxFee } from '../settings/TxFeeInputField'
Expand Down Expand Up @@ -221,6 +221,7 @@ interface InnerSendFormProps {
className?: string
isLoading: boolean
walletInfo?: WalletInfo
wallet: CurrentWallet
loadNewWalletAddress: (props: { signal: AbortSignal; jarIndex: JarIndex }) => Promise<Api.BitcoinAddress>
minNumCollaborators: number
feeConfigValues?: FeeValues
Expand All @@ -233,6 +234,7 @@ const InnerSendForm = ({
className,
isLoading,
walletInfo,
wallet,
loadNewWalletAddress,
minNumCollaborators,
feeConfigValues,
Expand Down Expand Up @@ -272,6 +274,7 @@ const InnerSendForm = ({
name="sourceJarIndex"
label={t('send.label_source_jar')}
walletInfo={walletInfo}
wallet={wallet}
isLoading={isLoading}
disabled={disabled}
variant={showCoinjoinPreconditionViolationAlert ? 'warning' : 'default'}
Expand Down Expand Up @@ -375,6 +378,7 @@ type SendFormProps = Omit<InnerSendFormProps, 'props' | 'className'> & {
onSubmit: (values: SendFormValues) => Promise<void>
formRef?: React.Ref<FormikProps<SendFormValues>>
blurred?: boolean
wallet: CurrentWallet
}

export const SendForm = ({
Expand All @@ -383,6 +387,7 @@ export const SendForm = ({
formRef,
blurred = false,
walletInfo,
wallet,
minNumCollaborators,
...innerProps
}: SendFormProps) => {
Expand Down Expand Up @@ -446,6 +451,7 @@ export const SendForm = ({
props={props}
className={blurred ? styles.blurred : undefined}
walletInfo={walletInfo}
wallet={wallet}
minNumCollaborators={minNumCollaborators}
{...innerProps}
/>
Expand Down
88 changes: 88 additions & 0 deletions src/components/Send/ShowUtxos.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
.joinedUtxoAndCjout {
background-color: #27ae600d !important;
color: #27ae60 !important;
}

.frozenUtxo {
background-color: #2d9cdb0d !important;
color: #2d9cdb !important;
}

.depositUtxo {
background-color: var(--bs-body-bg) !important;
color: var(--bs-modal-color) !important;
}

.changeAndReuseUtxo {
background-color: #eb57570d !important;
color: #eb5757 !important;
}

.subTitle {
color: #777777 !important;
}

.utxoTagDeposit {
color: #999999;
border: 1px solid #bbbbbb;
background-color: #dedede !important;
border-radius: 0.35rem;
padding: 0rem 0.25rem;
}

.utxoTagJoinedAndCjout {
border: 1px solid #27ae60;
background-color: #c6eed7 !important;
border-radius: 0.35rem;
padding: 0rem 0.25rem;
}

.utxoTagFreeze {
border: 1px solid #2d9cdb;
background-color: #bce7ff !important;
border-radius: 0.35rem;
padding: 0rem 0.25rem;
}

.utxoTagChangeAndReuse {
border: 1px solid #eb5757;
background-color: #fac7c7 !important;
border-radius: 0.35rem;
padding: 0rem 0.25rem;
}

.squareToggleButton {
appearance: none;
width: 22px;
height: 22px;
border-radius: 3px;
border: 1px solid var(--bs-body-color);
margin-top: 0.45rem;
}

.selected {
visibility: visible !important;
background-color: var(--bs-body-color);
}

.squareFrozenToggleButton {
appearance: none;
width: 22px;
height: 22px;
border-radius: 3px;
border: 1px solid #2d9cdb;
margin-top: 0.45rem;
}

.utxoListDisplayHeight {
max-height: 17.6rem;
}

.customHeaderClass {
background-color: var(--bs-gray-800) !important;
padding: var(--bs-modal-header-padding) !important;
}

.customTitleClass {
color: var(--bs-heading-color) !important;
}
Loading

0 comments on commit 5c8f81e

Please sign in to comment.