Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[redesign][ln] Send tab #3538

Merged
merged 16 commits into from Aug 24, 2021
10 changes: 10 additions & 0 deletions app/actions/LNActions.js
Expand Up @@ -1075,3 +1075,13 @@ export const changeInvoiceFilter = (newFilter) => (dispatch) =>
});
resolve();
});

export const LNWALLET_CHANGE_PAYMENT_FILTER = "LNWALLET_CHANGE_PAYMENT_FILTER";
export const changePaymentFilter = (newFilter) => (dispatch) =>
new Promise((resolve) => {
dispatch({
paymentFilter: newFilter,
type: LNWALLET_CHANGE_PAYMENT_FILTER
});
resolve();
});
9 changes: 7 additions & 2 deletions app/components/inputs/Input/Input.jsx
Expand Up @@ -25,6 +25,7 @@ const Input = ({
onChange,
showErrors,
showSuccess,
hideIcons,
invalidMessage,
successMessage,
requiredMessage,
Expand Down Expand Up @@ -81,12 +82,16 @@ const Input = ({
placeholder
}}
type={type ?? "text"}
success={showSuccess && successMessage}
success={showSuccess ? successMessage : ""}
value={value ?? ""}
onChange={(e) => onChange?.(e)}
onFocus={(e) => onFocus?.(e)}
onBlur={(e) => onBlur?.(e)}
wrapperClassNames={classNames(className, styles.wrapper)}
wrapperClassNames={classNames(
className,
styles.wrapper,
hideIcons && styles.hideIcons
)}
inputClassNames={classNames(
inputClassNames,
newBiggerFontStyle ? styles.newBiggerFontStyleInput : styles.input
Expand Down
12 changes: 11 additions & 1 deletion app/components/inputs/Input/Input.module.css
Expand Up @@ -30,5 +30,15 @@

.input:not(:focus),
.newBiggerFontStyleInput:not(:focus) {
border-bottom: 1px var(--select-stroke-color) solid !important;
border-bottom: 1px var(--select-stroke-color) solid;
}

.wrapper.hideIcons > div > svg {
display: none;
}
.wrapper.hideIcons > div > div {
right: 0 !important;
}
.wrapper.hideIcons input {
padding-right: 26px !important;
}
5 changes: 3 additions & 2 deletions app/components/modals/LNInvoiceModal/LNInvoiceModal.jsx
@@ -1,12 +1,13 @@
import Modal from "../Modal";
import { FormattedMessage as T } from "react-intl";
import { CopyableText, classNames } from "pi-ui";
import { classNames } from "pi-ui";
import styles from "./LNInvoiceModal.module.css";
import {
Balance,
LNInvoiceStatus,
FormattedRelative,
DetailsTable
DetailsTable,
CopyableText
} from "shared";
import { PiUiButton } from "buttons";
import {
Expand Down
14 changes: 3 additions & 11 deletions app/components/modals/LNInvoiceModal/helpers.js
@@ -1,19 +1,11 @@
import { FormattedMessage as T } from "react-intl";
import { SmallButton } from "buttons";
import { CopyToClipboard, TruncatedText } from "shared";
export const getInvoiceDetails = (invoice, tsDate) => {
const details = [
{
label: <T id="ln.invoicesModal.hash" m="Hash" />,
value: (
<>
<TruncatedText text={invoice?.rHashHex} max={40} showTooltip />
<CopyToClipboard
textToCopy={invoice?.rHashHex}
ButtonComponent={SmallButton}
/>
</>
)
value: invoice?.rHashHex,
copyable: true,
truncate: 40
},
{
label: <T id="ln.invoicesModal.desc" m="Description" />,
Expand Down
71 changes: 71 additions & 0 deletions app/components/modals/LNPaymentModal/LNPaymentModal.jsx
@@ -0,0 +1,71 @@
import Modal from "../Modal";
import { FormattedMessage as T } from "react-intl";
import { Message } from "pi-ui";
import styles from "./LNPaymentModal.module.css";
import { Balance, LNPaymentStatus, DetailsTable, CopyableText } from "shared";
import { getPaymentDetails } from "./helpers";

const LNPaymentModal = ({ show, onCancelModal, tsDate, payment }) => (
<Modal className={styles.modal} {...{ show, onCancelModal }}>
<div
className={styles.closeButton}
onClick={onCancelModal}
data-testid="lnpayment-close-button"
/>
<div className={styles.title}>
<T id="ln.paymentModal.title" m="Lightning Payment" />
</div>
<div className={styles.dataGrid}>
<label>
<T id="ln.paymentModal.sentAmount" m="Sent Amount" />
</label>
<label>
<T id="ln.paymentModal.status" m="Status" />
</label>
<label>
<T id="ln.paymentModal.date" m="Date" />
</label>
<label>
<T id="ln.paymentModal.fee" m="Fee" />
</label>
<Balance amount={payment?.valueAtoms} classNameWrapper={styles.amount} />
<div className={styles.status}>
<LNPaymentStatus status={payment?.status} />
</div>
<div className={styles.date}>
<T
id="ln.paymentModal.creationDate"
m="{creationDate, date, medium} {creationDate, time, short}"
values={{ creationDate: tsDate(payment?.creationDate) }}
/>
</div>
<Balance amount={payment?.fee} classNameWrapper={styles.amount} />
</div>
{payment?.paymentRequest && (
<>
<div className={styles.requestCodeLabel}>
<T
id="ln.paymentModal.requestCodeLabel"
m="Lightning Payment Request Code"
/>
</div>
<CopyableText
tooltipPlacement="top"
id="paymentRequest"
truncate={false}>
{payment.paymentRequest}
</CopyableText>
</>
)}
{payment.paymentError && (
<Message kind="error">{payment.paymentError}</Message>
)}
<DetailsTable
data={getPaymentDetails(payment, tsDate)}
className={styles.details}
title={<T id="ln.paymentModal.details" m="Details" />}
expandable
/>
</Modal>
);
export default LNPaymentModal;
96 changes: 96 additions & 0 deletions app/components/modals/LNPaymentModal/LNPaymentModal.module.css
@@ -0,0 +1,96 @@
.modal {
background-image: none;
padding: 30px 40px;
width: 764px;
overflow-x: hidden;
position: relative;
margin: 0;
max-height: calc(100% - 130px);
display: flex;
flex-direction: column;
}
.closeButton {
position: absolute;
top: 20px;
right: 20px;
height: 10px;
width: 10px;
background-image: var(--x-grey);
background-size: 10px 10px;
background-repeat: no-repeat;
cursor: pointer;
}
.title {
font-size: 28px;
color: var(--grey-7);
line-height: 35px;
}
.date {
font-size: 13px;
line-height: 16px;
color: var(--main-dark-blue);
}
.dataGrid {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
font-size: 13px;
line-height: 16px;
color: var(--main-dark-blue);
align-items: center;
grid-row-gap: 5px;
margin: 19px 0 30px 0;
}
.dataGrid label {
color: var(--grey-7);
}
.amount {
font-size: 16px;
line-height: 22px;
}
.requestCodeLabel {
font-size: 13px;
line-height: 16px;
color: var(--grey-7);
margin-bottom: 10px;
}
.paymentRequest {
padding: 0.3rem 1rem;
word-break: break-all;
background-color: var(--copyable-text-background-color);
border-radius: 0.4rem;
color: var(--text-color);
font-size: var(--font-size-normal);
line-height: var(--spacing-2);
}

.details {
margin: 20px 0 0 0;
}

@media screen and (max-width: 768px) {
.modal {
width: 355px;
padding: 30px 20px;
}
.title {
font-size: 24px;
}
.dataGrid {
grid-template-columns: 2fr;
}
.dataGrid label {
grid-column: 1;
}
.amount {
grid-column: 2;
grid-row: 1;
}
.status {
grid-column: 2;
grid-row: 2;
}
.date {
grid-column: 2;
grid-row: 3;
}
}
78 changes: 78 additions & 0 deletions app/components/modals/LNPaymentModal/helpers.js
@@ -0,0 +1,78 @@
import { FormattedMessage as T } from "react-intl";
import { Balance } from "shared";
export const getPaymentDetails = (payment) => {
const details = [
{
label: <T id="ln.paymentModal.hash" m="Hash" />,
value: payment?.paymentHash,
copyable: true,
truncate: 40
}
];

if (payment?.description) {
details.push({
label: <T id="ln.paymentModal.desc" m="Description" />,
value: payment.description
});
}

if (payment?.destination) {
details.push({
label: <T id="ln.paymentModal.destination" m="Destination" />,
value: payment.destination,
truncate: 40
});
}

payment?.htlcsList?.forEach((htlc, index) => {
const response = {
label: (
<>
<T id="ln.paymentModal.htlc" m="HTLC" /> {index}
</>
),
value: [
{
label: <T id="ln.paymentModal.htlc.status" m="Status" />,
value: htlc.status
},
{
label: <T id="ln.paymentModal.htlc.totalAmt" m="Total Amount" />,
value: <Balance amount={htlc.route.totalAmt} />
},
{
label: <T id="ln.paymentModal.htlc.totalFees" m="Total Fees" />,
value: <Balance amount={htlc.route.totalFees} />
}
]
};
// hopList
htlc.route?.hopsList?.forEach((hop, hopIndex) => {
const hopResponse = {
label: (
<>
<T id="ln.paymentModal.routeHop" m="Hop" /> {hopIndex}
</>
),
value: [
{
label: <T id="ln.paymentModal.htlc.hop.fee" m="Fee" />,
value: <Balance amount={hop.fee} />
},
{
label: <T id="ln.paymentModal.htlc.hop.pubkey" m="PubKey" />,
value: hop.pubKey,
copyable: true,
truncate: 20
}
]
};
response.value.push(hopResponse);
});

details.push(response);
});

return details;
};
1 change: 1 addition & 0 deletions app/components/modals/LNPaymentModal/index.js
@@ -0,0 +1 @@
export { default } from "./LNPaymentModal";
1 change: 1 addition & 0 deletions app/components/modals/index.js
Expand Up @@ -21,3 +21,4 @@ export { default as SetNewPassphraseModal } from "./SetNewPassphraseModal/SetNew
export { default as AppPassAndPassphraseModal } from "./AppPassAndPassphraseModal/AppPassAndPassphraseModal";
export { default as ConfirmationDialogModal } from "./ConfirmationDialogModal";
export { default as LNInvoiceModal } from "./LNInvoiceModal";
export { default as LNPaymentModal } from "./LNPaymentModal";
Expand Up @@ -20,6 +20,7 @@
}
.success {
font-size: 12px;
line-height: 16px;
color: var(--background-back-color);
background-color: var(--accent-color);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
Expand Down
11 changes: 11 additions & 0 deletions app/components/shared/CopyableText/CopyableText.jsx
@@ -0,0 +1,11 @@
import styles from "./CopyableText.module.css";
import { CopyableText as PiUiCopyableText, classNames } from "pi-ui";

const CopyableText = (props) => (
<PiUiCopyableText
className={classNames(styles.copyableText, props.className)}
{...props}
/>
);

export default CopyableText;
3 changes: 3 additions & 0 deletions app/components/shared/CopyableText/CopyableText.module.css
@@ -0,0 +1,3 @@
.copyableText > span {
padding: 10px;
}
1 change: 1 addition & 0 deletions app/components/shared/CopyableText/index.js
@@ -0,0 +1 @@
export { default } from "./CopyableText";