Skip to content

Commit

Permalink
Merge pull request #424 from PayButton/fix/disabled-prop
Browse files Browse the repository at this point in the history
Fix/disabled prop
  • Loading branch information
Klakurka authored Sep 2, 2024
2 parents c8b4840 + 396ac78 commit e4694d1
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 48 deletions.
106 changes: 75 additions & 31 deletions paybutton/dev/demo/paybutton-generator.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
<title>Paybutton Generator Test</title>
<link rel="stylesheet" type="text/css" href="style.css">
<style>
body {
body {
padding: auto;
font-family: Arial, sans-serif;
}

input,
button {
padding: 8px;
Expand All @@ -35,6 +36,32 @@
flex-grow: 1;
justify-content: space-around;
}

.loading-overlay {
top: 0;
left: 0;
background-color: rgba(255, 255, 255, 0.8);
display: flex;
justify-content: center;
align-items: center;
border-radius: 8px;
display: none;
}

.spinner {
border: 4px solid rgba(0, 0, 0, 0.1);
border-left-color: #2186fa;
border-radius: 50%;
width: 30px;
height: 30px;
animation: spin 0.6s linear infinite;
}

@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
Expand Down Expand Up @@ -65,7 +92,7 @@
</div>
<div class="form-input">
<label for="currency">Currency:</label>
<input id="currency" v-model.number="paybuttonProps.currency" type="text">
<input id="currency" v-model="paybuttonProps.currency" type="text">
</div>
</div>
<div style="display: flex; justify-content: space-between; gap:10px">
Expand Down Expand Up @@ -121,46 +148,51 @@
<label for="disable-enforce-focus">Disable enforce focus</label>
</div>
<div class="form-input toggle">
<input type="checkbox" id="disabled" v-model="paybuttonProps.disabled" true-value="1" false-value="0">
<input type="checkbox" id="disabled" v-model="paybuttonProps.disabled" true-value="true"
false-value="false">
<label for="disabled">Disabled</label>
</div>
</div>
</div>
<div style="display: flex;
justify-content: right;">
<div style="display: flex; justify-content: right; position: relative;">
<button type="submit">Generate</button>
</div>

</form>
<div class="card" style="display: flex; flex-basis: 70%; justify-content: center; align-items: center;">
<div id="paybutton-generator" class="paybutton"
:to="paybuttonProps.to"
:amount="paybuttonProps.amount"
:goal-amount="paybuttonProps.goalAmount"
:currency="paybuttonProps.currency"
:text="paybuttonProps.text"
:hover-text="paybuttonProps.hoverText"
:success-text="paybuttonProps.successText"
:theme="paybuttonProps.theme"
:animation="paybuttonProps.animation"
:editable="paybuttonProps.editable"
:disable-payment-id="paybuttonProps.disablePaymentId"
:random-satoshis="paybuttonProps.randomSatoshis"
:hide-toasts="paybuttonProps.hideToasts"
:disable-enforce-focus="paybuttonProps.disableEnforceFocus"
:on-success="mySuccessFuction"
:on-transaction="myTransactionFuction">
<div class="loading-overlay" id="loading-overlay">
<div class="spinner"></div>
</div>
<div id="paybutton-generator-container">
<div id="paybutton-generator" class="paybutton"
:to="paybuttonProps.to"
:amount="paybuttonProps.amount"
:goal-amount="paybuttonProps.goalAmount"
:currency="paybuttonProps.currency"
:text="paybuttonProps.text"
:hover-text="paybuttonProps.hoverText"
:success-text="paybuttonProps.successText"
:theme="paybuttonProps.theme"
:animation="paybuttonProps.animation"
:editable="paybuttonProps.editable"
:disable-payment-id="paybuttonProps.disablePaymentId"
:random-satoshis="paybuttonProps.randomSatoshis"
:hide-toasts="paybuttonProps.hideToasts"
:disable-enforce-focus="paybuttonProps.disableEnforceFocus"
:disabled="paybuttonProps.disabled"
:on-success="mySuccessFuction"
:on-transaction="myTransactionFuction">
</div>
</div>
</div>
</div>

<script>
const { createApp, reactive } = Vue;
const mySuccessFuction = (tx) => (console.log("Success", {tx}))
const myTransactionFuction = (tx) => (console.log("Transaction", {tx}))
const mySuccessFuction = (tx) => (console.log("Success", { tx }))
const myTransactionFuction = (tx) => (console.log("Transaction", { tx }))

createApp({
setup() {
//todo - add the missing props once it is fixed
const paybuttonProps = reactive({
to: "ecash:qrmm7edwuj4jf7tnvygjyztyy0a0qxvl7quss2vxek",
amount: undefined,
Expand All @@ -171,7 +203,8 @@
successText: "Payment Successful!",
theme: `{"palette":{"primary": "#9d00ff","secondary": "#FFF", "tertiary": "#000"}}`,
animation: "slide",
editable: true,
editable: false,
disabled: false,
disablePaymentId: false,
randomSatoshis: false,
hideToasts: false,
Expand All @@ -181,13 +214,24 @@
});

const updateProps = () => {
PayButton.render(document.getElementById("paybutton-generator"), { ...paybuttonProps });
};
const loadingOverlay = document.getElementById("loading-overlay");
const paybuttonGenerator = document.getElementById("paybutton-generator");


loadingOverlay.style.display = "flex";
paybuttonGenerator.hidden = true
setTimeout(() => {
paybuttonGenerator.hidden = false

PayButton.render(paybuttonGenerator, { ...paybuttonProps });
loadingOverlay.style.display = "none";

}, 600);
};

return { paybuttonProps, updateProps };
}
}).mount('#playground');
</script>
</body>

</html>
</html>
5 changes: 3 additions & 2 deletions react/lib/components/PayButton/PayButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
isValidXecAddress,
CurrencyObject,
generatePaymentId,
getCurrencyObject
getCurrencyObject,
isPropsTrue
} from '../../util';
import { PaymentDialog } from '../PaymentDialog';
export interface PayButtonProps extends ButtonProps {
Expand Down Expand Up @@ -121,7 +122,7 @@ export const PayButton = (props: PayButtonProps): React.ReactElement => {
const invalidAmount = props.amount !== undefined && isNaN(+props.amount);

if (to !== undefined) {
setDisabled(!!props.disabled);
setDisabled(isPropsTrue(props.disabled));
setErrorMsg('');
} else if (invalidAmount) {
setDisabled(true);
Expand Down
4 changes: 2 additions & 2 deletions react/lib/components/PaymentDialog/PaymentDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, { useState, useEffect } from 'react';
import { Theme, ThemeName, ThemeProvider, useTheme } from '../../themes';
import Button, { ButtonProps } from '../Button/Button';
import { WidgetContainer } from '../Widget/WidgetContainer';
import { Currency, CurrencyObject, Transaction, isValidCashAddress, isValidXecAddress } from '../../util';
import { Currency, CurrencyObject, Transaction, isPropsTrue, isValidCashAddress, isValidXecAddress } from '../../util';

export interface PaymentDialogProps extends ButtonProps {
to: string;
Expand Down Expand Up @@ -84,7 +84,7 @@ export const PaymentDialog = (
const invalidAmount = amount !== undefined && isNaN(+amount);

if (to !== undefined && (isValidCashAddress(to) || isValidXecAddress(to))) {
setDisabled(!!props.disabled);
setDisabled(isPropsTrue(props.disabled));
} else if (invalidAmount) {
setDisabled(true);
} else {
Expand Down
20 changes: 7 additions & 13 deletions react/lib/components/Widget/Widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import {
getCurrencyTypeFromAddress,
altpaymentListener,
CURRENCY_PREFIXES_MAP,
CRYPTO_CURRENCIES
CRYPTO_CURRENCIES,
isPropsTrue
} from '../../util';
import AltpaymentWidget from './AltpaymentWidget';
import { AltpaymentPair, AltpaymentShift, AltpaymentError, AltpaymentCoin, MINIMUM_ALTPAYMENT_DOLLAR_AMOUNT } from '../../altpayment';
Expand Down Expand Up @@ -141,13 +142,6 @@ const useStyles = makeStyles({
}),
});

const isTruthy = (value?: string | boolean) => {
if (typeof value === "string" && (value === "true" || value === "false")) {
return value === "true"
} else {
return value
}
}

export const Widget: React.FunctionComponent<WidgetProps> = props => {
const {
Expand Down Expand Up @@ -217,7 +211,7 @@ export const Widget: React.FunctionComponent<WidgetProps> = props => {
props.currencyObject,
);

const blurCSS = disabled ? { filter: 'blur(5px)' } : {};
const blurCSS = isPropsTrue(disabled) ? { filter: 'blur(5px)' } : {};

const bchSvg = useMemo((): string => {
const color = theme.palette.logo ?? theme.palette.primary;
Expand Down Expand Up @@ -313,7 +307,7 @@ export const Widget: React.FunctionComponent<WidgetProps> = props => {
if (thisAmount === undefined || thisAmount === null || thisAmount === 0) {
setAltpaymentEditable(true)
}
if (isTruthy(editable)) {
if (isPropsTrue(editable)) {
setAltpaymentEditable(true)
}
}, [])
Expand All @@ -331,7 +325,7 @@ export const Widget: React.FunctionComponent<WidgetProps> = props => {
thisAmount !== undefined && thisAmount && isNaN(+thisAmount);

if (isValidCashAddress(to) || isValidXecAddress(to)) {
setDisabled(!!props.disabled);
setDisabled(isPropsTrue(props.disabled));
setErrorMsg('');
} else if (invalidAmount) {
setDisabled(true);
Expand Down Expand Up @@ -689,7 +683,7 @@ export const Widget: React.FunctionComponent<WidgetProps> = props => {
timeout={{ enter: 0, exit: 2000 }}
>
<Box className={classes.copyTextContainer}>
{!disabled && (
{!isPropsTrue(disabled) && (
<Typography className={classes.copyText}>
{copied ? 'Payment copied!' : 'Click to copy'}
</Typography>
Expand Down Expand Up @@ -719,7 +713,7 @@ export const Widget: React.FunctionComponent<WidgetProps> = props => {
)}
</Box>

{isTruthy(editable) && (
{isPropsTrue(editable) && (
<Grid
container
spacing={2}
Expand Down
28 changes: 28 additions & 0 deletions react/lib/tests/util/format.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { isPropsTrue } from "../../util"

describe('isPropsTrue', () => {
it('returns true for "true" string', () => {
expect(isPropsTrue("true")).toBe(true)
})
it('returns true for true boolean', () => {
expect(isPropsTrue(true)).toBe(true)
})
it('returns false for "false" string', () => {
expect(isPropsTrue("false")).toBe(false)
})
it('returns false for false boolean', () => {
expect(isPropsTrue(false)).toBe(false)
})
it('returns false for other string', () => {
expect(isPropsTrue("1")).toBe(false)
})
it('returns false for empty string', () => {
expect(isPropsTrue("")).toBe(false)
})
it('returns false for "null" string', () => {
expect(isPropsTrue("null")).toBe(false)
})
it('returns false for undefined', () => {
expect(isPropsTrue(undefined)).toBe(false)
})
})
11 changes: 11 additions & 0 deletions react/lib/util/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ export const formatXEC = (xec: string) => {
return formattedString;
};

export const isPropsTrue = (value?: string | boolean) => {
switch (typeof value) {
case "string":
return value === "true"
case "boolean":
return value
case "undefined":
return false
}
}

export default {
amount,
formatPrice,
Expand Down

0 comments on commit e4694d1

Please sign in to comment.