From 61e979ecaf6aa1b9a085e4a115e43bf48721d672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Aaron?= Date: Fri, 8 Sep 2023 11:16:12 +0200 Subject: [PATCH 01/40] feat: new transaction list --- .../components/TransactionsTable/index.tsx | 229 +++++++----------- 1 file changed, 87 insertions(+), 142 deletions(-) diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index ab155106d3..a2d786a8e1 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -1,13 +1,14 @@ -import { CaretDownIcon } from "@bitcoin-design/bitcoin-icons-react/filled"; +import { + ArrowDownIcon, + ArrowUpIcon, +} from "@bitcoin-design/bitcoin-icons-react/filled"; import Loading from "@components/Loading"; -import { Disclosure } from "@headlessui/react"; import { useTranslation } from "react-i18next"; -import Button from "~/app/components/Button"; +import Badge from "~/app/components/Badge"; import { useSettings } from "~/app/context/SettingsContext"; +import { classNames } from "~/app/utils"; import { Transaction } from "~/types"; -import Badge from "../Badge"; - export type Props = { transactions: Transaction[] | null | undefined; loading?: boolean; @@ -29,146 +30,90 @@ export default function TransactionsTable({ ) : !transactions?.length && noResultMsg ? (

{noResultMsg}

) : ( - <> -
- {transactions?.map((tx) => ( -
- - {({ open }) => ( - <> -
-
-
+ {transactions?.map((tx) => { + const type = [tx.type && "sent", "sending"].includes(tx.type) + ? "outgoing" + : "incoming"; + + return ( +
+
+
+ {type == "outgoing" ? ( +
+ +
+ ) : ( +
+ +
+ )} +
+
+
+

+ {tx.publisherLink && tx.title ? ( + -

- {tx.publisherLink && tx.title ? ( - - {tx.title} - - ) : ( - tx.title || tx.boostagram?.message || "\u00A0" - )} -

-
-

- {tx.date} -

-
- {tx.badges && ( -
- {tx.badges.map((badge) => ( - - ))} -
+ {tx.title} + + ) : ( + tx.title || + tx.boostagram?.message || + (type == "incoming" ? "Received" : "Sent") )} -
-
-

- {[tx.type && "sent", "sending"].includes(tx.type) - ? "-" - : "+"} - {getFormattedSats(tx.totalAmount)} -

- {!!tx.totalAmountFiat && ( -

- ~{tx.totalAmountFiat} -

- )} -
- {(!!tx.description || - [tx.type && "sent", "sending"].includes(tx.type) || - (tx.type === "received" && tx.boostagram)) && ( - - - - )} -
-
- -
- {(tx.description || tx.boostagram) && ( -
- {tx.description &&

{tx.description}

} - {tx.boostagram && ( -
    -
  • - {t("transactionsTable.boostagram.sender")}:{" "} - {tx.boostagram.sender_name} -
  • -
  • - {t("transactionsTable.boostagram.message")}:{" "} - {tx.boostagram.message} -
  • -
  • - {t("transactionsTable.boostagram.app")}:{" "} - {tx.boostagram.app_name} -
  • -
  • - {t("transactionsTable.boostagram.podcast")}:{" "} - {tx.boostagram.podcast} -
  • -
- )} -
- )} - {(tx.totalFees !== undefined || tx.location) && ( -
- {tx.totalFees !== undefined && ( -

- - {t("transactionsTable.fee")} - -
- {getFormattedSats(tx.totalFees)} -

- )} - {tx.location && ( - -
- )} - {tx.preimage && ( -
-

- - {t("transactionsTable.preimage")} - -
- {tx.preimage} -

-
- )} -
-
- +

+
+

+ {tx.date} +

+
+ {tx.badges && ( +
+ {tx.badges.map((badge) => ( + + ))} +
)} - +
+
+

+ {type == "outgoing" ? "-" : "+"} + {getFormattedSats(tx.totalAmount)} +

+ {!!tx.totalAmountFiat && ( +

+ ~{tx.totalAmountFiat} +

+ )} +
+
+
- ))} -
- + ); + })} +
); } From 598e356ae26ab1275009ef6a80c6a8f49c04c38a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Aaron?= Date: Fri, 8 Sep 2023 13:22:29 +0200 Subject: [PATCH 02/40] fix: remove unused badges --- src/app/components/TransactionsTable/index.tsx | 13 ------------- src/types.ts | 1 - 2 files changed, 14 deletions(-) diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index a2d786a8e1..3e08c708f7 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -4,7 +4,6 @@ import { } from "@bitcoin-design/bitcoin-icons-react/filled"; import Loading from "@components/Loading"; import { useTranslation } from "react-i18next"; -import Badge from "~/app/components/Badge"; import { useSettings } from "~/app/context/SettingsContext"; import { classNames } from "~/app/utils"; import { Transaction } from "~/types"; @@ -78,18 +77,6 @@ export default function TransactionsTable({ {tx.date}

- {tx.badges && ( -
- {tx.badges.map((badge) => ( - - ))} -
- )}

Date: Fri, 8 Sep 2023 16:52:30 +0200 Subject: [PATCH 03/40] fix: detail view --- .../components/TransactionsTable/index.tsx | 168 +++++++++++------- 1 file changed, 104 insertions(+), 64 deletions(-) diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index 3e08c708f7..0ecbaf1f8b 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -3,7 +3,9 @@ import { ArrowUpIcon, } from "@bitcoin-design/bitcoin-icons-react/filled"; import Loading from "@components/Loading"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; +import Modal from "~/app/components/Modal"; import { useSettings } from "~/app/context/SettingsContext"; import { classNames } from "~/app/utils"; import { Transaction } from "~/types"; @@ -21,6 +23,19 @@ export default function TransactionsTable({ }: Props) { const { getFormattedSats } = useSettings(); const { t } = useTranslation("components"); + const [modalOpen, setModalOpen] = useState(false); + const [transaction, setTransaction] = useState(); + + function openDetails(transaction: Transaction) { + setTransaction(transaction); + setModalOpen(true); + } + + function getTransactionType(tx: Transaction): "incoming" | "outgoing" { + return [tx.type && "sent", "sending"].includes(tx.type) + ? "outgoing" + : "incoming"; + } return loading ? (

@@ -29,78 +44,103 @@ export default function TransactionsTable({ ) : !transactions?.length && noResultMsg ? (

{noResultMsg}

) : ( -
- {transactions?.map((tx) => { - const type = [tx.type && "sent", "sending"].includes(tx.type) - ? "outgoing" - : "incoming"; + <> +
+ {transactions?.map((tx) => { + const type = getTransactionType(tx); - return ( -
-
-
- {type == "outgoing" ? ( -
- -
- ) : ( -
- -
- )} -
-
-
-

- {tx.publisherLink && tx.title ? ( - - {tx.title} - - ) : ( - tx.title || - tx.boostagram?.message || - (type == "incoming" ? "Received" : "Sent") - )} -

+ return ( +
openDetails(tx)} + > +
+
+ {type == "outgoing" ? ( +
+ +
+ ) : ( +
+ +
+ )}
-

- {tx.date} -

-
-
-
-

+

- {type == "outgoing" ? "-" : "+"} - {getFormattedSats(tx.totalAmount)} +

+ {tx.publisherLink && tx.title ? ( + + {tx.title} + + ) : ( + tx.title || + tx.boostagram?.message || + (type == "incoming" ? "Received" : "Sent") + )} +

+
+

+ {tx.date}

- {!!tx.totalAmountFiat && ( -

- ~{tx.totalAmountFiat} +

+
+
+

+ {type == "outgoing" ? "-" : "+"} + {getFormattedSats(tx.totalAmount)}

- )} + {!!tx.totalAmountFiat && ( +

+ ~{tx.totalAmountFiat} +

+ )} +
+ ); + })} +
+ setModalOpen(false)} + title={"test"} + > + {transaction && ( +
+
+
+ {getTransactionType(transaction) == "outgoing" ? ( +
+ +
+ ) : ( +
+ +
+ )} +
+
+
details
- ); - })} -
+ )} + + ); } From ae79520a519d8bdbc5735af02c6467c747a893f0 Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Wed, 20 Sep 2023 11:09:11 +0530 Subject: [PATCH 04/40] modify transaction list heading and align it to center at all places --- src/app/screens/Home/AllowanceView/index.tsx | 4 ++-- src/app/screens/Home/DefaultView/index.tsx | 4 ++-- src/app/screens/Publishers/Detail/index.tsx | 4 ++-- src/i18n/locales/en/translation.json | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/app/screens/Home/AllowanceView/index.tsx b/src/app/screens/Home/AllowanceView/index.tsx index e836e13b15..34c0d42e17 100644 --- a/src/app/screens/Home/AllowanceView/index.tsx +++ b/src/app/screens/Home/AllowanceView/index.tsx @@ -139,8 +139,8 @@ const AllowanceView: FC = (props) => { />
)} -

- {t("allowance_view.recent_transactions")} +

+ {t("allowance_view.latest_transactions")}

{isLoadingTransactions && ( diff --git a/src/app/screens/Home/DefaultView/index.tsx b/src/app/screens/Home/DefaultView/index.tsx index f8427584c9..4563ba510a 100644 --- a/src/app/screens/Home/DefaultView/index.tsx +++ b/src/app/screens/Home/DefaultView/index.tsx @@ -188,8 +188,8 @@ const DefaultView: FC = (props) => { {!isLoadingTransactions && (
-

- {t("default_view.recent_transactions")} +

+ {t("default_view.latest_transactions")}

diff --git a/src/app/screens/Publishers/Detail/index.tsx b/src/app/screens/Publishers/Detail/index.tsx index 038c6c0639..53e0cdad5f 100644 --- a/src/app/screens/Publishers/Detail/index.tsx +++ b/src/app/screens/Publishers/Detail/index.tsx @@ -85,8 +85,8 @@ function PublisherDetail() { {allowance && (
-

- {t("allowance_view.recent_transactions")} +

+ {t("allowance_view.latest_transactions")}

{transactions && transactions?.length > 0 ? ( diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index 0a0f178cd5..d215a71d36 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -352,9 +352,9 @@ "send_satoshis": "⚡️ Send Satoshis ⚡️", "enable_now": "Enable Now" }, - "recent_transactions": "Recent Transactions", + "latest_transactions": "Latest Transactions", "allowance_view": { - "recent_transactions": "Recent Transactions", + "latest_transactions": "Latest Transactions", "budget_spent": "Budget spent", "sats": "sats", "no_transactions": "No transactions on <0>{{name}} yet.", @@ -363,7 +363,7 @@ "permissions": "Permissions" }, "default_view": { - "recent_transactions": "Recent Transactions", + "latest_transactions": "Latest Transactions", "is_blocked_hint": "Alby is currently disabled on {{host}}", "block_removed": "Enabled {{host}}. Please reload the website.", "no_outgoing_transactions": "No outgoing transactions for this account yet.", From b61b91434e00f1a6065aaea9e2eafc1d1824c64d Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Thu, 21 Sep 2023 09:50:35 +0530 Subject: [PATCH 05/40] feat: unify transaction list cleanup hooks and use single hook to get transactions cleanup allowanceview, homeview and publisher card view to adapt transaction list changes add mechanism to sort, db payments and invoices signed-off-by: pavan joshi --- .../TransactionsTable/index.test.tsx | 38 ++------ src/app/hooks/useInvoices.ts | 52 ----------- src/app/hooks/useTransactions.ts | 27 +++++- src/app/router/Options/Options.tsx | 11 +-- src/app/screens/Home/AllowanceView/index.tsx | 2 +- src/app/screens/Home/DefaultView/index.tsx | 90 ++++--------------- src/app/screens/Publishers/Detail/index.tsx | 2 +- src/app/screens/Transactions/index.tsx | 32 ++----- src/app/utils/payments.ts | 1 + src/i18n/locales/en/translation.json | 10 +-- src/types.ts | 1 + 11 files changed, 63 insertions(+), 203 deletions(-) delete mode 100644 src/app/hooks/useInvoices.ts diff --git a/src/app/components/TransactionsTable/index.test.tsx b/src/app/components/TransactionsTable/index.test.tsx index c535df8d48..e6da0f5e83 100644 --- a/src/app/components/TransactionsTable/index.test.tsx +++ b/src/app/components/TransactionsTable/index.test.tsx @@ -1,14 +1,12 @@ import { render, screen } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import { act } from "react-dom/test-utils"; import { I18nextProvider } from "react-i18next"; import { BrowserRouter } from "react-router-dom"; import { settingsFixture as mockSettings } from "~/../tests/fixtures/settings"; import i18n from "~/../tests/unit/helpers/i18n"; import { SettingsProvider } from "~/app/context/SettingsContext"; -import TransactionsTable from "."; import type { Props } from "."; +import TransactionsTable from "."; jest.mock("~/common/lib/api", () => { const original = jest.requireActual("~/common/lib/api"); @@ -22,6 +20,7 @@ jest.mock("~/common/lib/api", () => { const transactions: Props = { transactions: [ { + timestamp: 1656573909064, createdAt: "1656573909064", date: "5 days ago", description: "Polar Invoice for bob", @@ -44,6 +43,7 @@ const invoices: Props = { transactions: [ { id: "lnbcrt666660n1p3tad0hpp5kkguywerj5lqspc4p2a7f53yfnkuywxmxnuawe3lu4gdg0ezc2tqdqjd3sk6cn0ypkxzmtzducqzpgxqyz5vqsp529wvk52ckjkrfkll9q3w6ep6lrsg35se66jjpm5ssmumck7xxy6s9qyyssqzq3zsstfs7gzklgkdnxy2hsp4jfavw8xj4hv5300yww3053jx76h57e3ypsuvg36zwd49xm2nfr2lrfvylwrxs7yhpckjytvlaju0hsq7p9wna", + timestamp: 1656573909064, type: "received", totalAmount: "66666", totalAmountFiat: "$13.02", @@ -53,6 +53,7 @@ const invoices: Props = { }, { id: "lnbcrt6543210n1p3tadjepp5rv6ufq4vumg66l9gcyxqhy89n6w90mx0mh6gcj0sawrf6xuep5ssdq5g9kxy7fqd9h8vmmfvdjscqzpgxqyz5vqsp5f9yzxeqjw33ule4rffuh0py32gjjsx8z48cd4xjl8ej3rn7zdtdq9qyyssqe6qvkfe260myc9ypgs5n63xzwcx82fderg8p5ysh6c2fvpz5xu4ksvhs5av0wwestk5pmucmhk8lpjhmy7wqyq9c29xgm9na2q5xv5spy5kukj", + timestamp: 1656573909064, type: "received", totalAmount: "654321", totalAmountFiat: "$127.80", @@ -67,6 +68,7 @@ const invoicesWithBoostagram: Props = { transactions: [ { id: "lnbcrt666660n1p3tad0hpp5kkguywerj5lqspc4p2a7f53yfnkuywxmxnuawe3lu4gdg0ezc2tqdqjd3sk6cn0ypkxzmtzducqzpgxqyz5vqsp529wvk52ckjkrfkll9q3w6ep6lrsg35se66jjpm5ssmumck7xxy6s9qyyssqzq3zsstfs7gzklgkdnxy2hsp4jfavw8xj4hv5300yww3053jx76h57e3ypsuvg36zwd49xm2nfr2lrfvylwrxs7yhpckjytvlaju0hsq7p9wna", + timestamp: 1656573909064, type: "received", totalAmount: "66666", totalAmountFiat: "$13.02", @@ -76,6 +78,7 @@ const invoicesWithBoostagram: Props = { }, { id: "lnbcrt888880n1p3tad30pp56j6g34wctydrfx4wwdwj3schell8uqug6jnlehlkpw02mdfd9wlqdq0v36k6urvd9hxwuccqzpgxqyz5vqsp5995q4egstsvnyetwvpax6jw8q0fnn4tyz3gp35k3yex29emhsylq9qyyssq0yxpx6peyn4vsepwj3l68w9sc5dqnkt07zff6aw4kqvcfs0fpu4jpfh929w6vqrgtjfkmrlwghq4s9t4mnwrh4dlkm6wjem5uq8eu4gpwqln0j", + timestamp: 1656573909064, type: "received", totalAmount: "88888", totalAmountFiat: "$17.36", @@ -103,8 +106,6 @@ const invoicesWithBoostagram: Props = { describe("TransactionsTable", () => { test("renders transactions", async () => { - const user = userEvent.setup(); - render( @@ -119,15 +120,6 @@ describe("TransactionsTable", () => { expect(screen.getByText(/5 days ago/)).toBeInTheDocument(); expect(await screen.findByText(/-1,234,000 sats/)).toBeInTheDocument(); expect(await screen.findByText(/~\$241.02/)).toBeInTheDocument(); - - const disclosureButton = screen.getByRole("button"); - - await act(() => { - user.click(disclosureButton); - }); - - expect(await screen.findByText("0 sats")).toBeInTheDocument(); - expect(await screen.findByText(/Open website/)).toBeInTheDocument(); }); test("renders invoice without boostagram", async () => { @@ -151,8 +143,6 @@ describe("TransactionsTable", () => { }); test("renders invoice with boostagram", async () => { - const user = userEvent.setup(); - render( @@ -167,21 +157,5 @@ describe("TransactionsTable", () => { expect(screen.getByText(/5 days ago/)).toBeInTheDocument(); expect(await screen.findByText(/\+88,888 sats/)).toBeInTheDocument(); expect(await screen.findByText(/~\$17.36/)).toBeInTheDocument(); - - const disclosureButtons = screen.getAllByRole("button"); - expect(disclosureButtons).toHaveLength(1); - - await act(() => { - user.click(disclosureButtons[0]); - }); - - expect( - await screen.findByText(/Message: Du bist so 1 geiles podcast 100%/) - ).toBeInTheDocument(); - expect( - await screen.findByText(/Sender: bumi@getalby.com/) - ).toBeInTheDocument(); - expect(await screen.findByText(/App: Fountain/)).toBeInTheDocument(); - expect(await screen.findByText(/Podcast: Honigdachs/)).toBeInTheDocument(); }); }); diff --git a/src/app/hooks/useInvoices.ts b/src/app/hooks/useInvoices.ts deleted file mode 100644 index a9c2bb3a1f..0000000000 --- a/src/app/hooks/useInvoices.ts +++ /dev/null @@ -1,52 +0,0 @@ -import dayjs from "dayjs"; -import { useCallback, useState } from "react"; -import toast from "~/app/components/Toast"; -import { useSettings } from "~/app/context/SettingsContext"; -import api from "~/common/lib/api"; -import { Transaction } from "~/types"; - -export const useInvoices = () => { - const { settings, getFormattedFiat } = useSettings(); - - const [isLoadingInvoices, setIsLoadingInvoices] = useState(false); - const [incomingTransactions, setIncomingTransactions] = useState< - Transaction[] - >([]); - - const loadInvoices = useCallback( - async (limit?: number) => { - setIsLoadingInvoices(true); - let result; - try { - result = await api.getInvoices({ isSettled: true, limit }); - } catch (e) { - if (e instanceof Error) toast.error(`Error: ${e.message}`); - setIsLoadingInvoices(false); - return; - } - - const invoices: Transaction[] = result.invoices.map((invoice) => ({ - ...invoice, - title: invoice.memo, - description: invoice.memo, - date: dayjs(invoice.settleDate).fromNow(), - })); - - for (const invoice of invoices) { - invoice.totalAmountFiat = settings.showFiat - ? await getFormattedFiat(invoice.totalAmount) - : ""; - } - - setIncomingTransactions(invoices); - setIsLoadingInvoices(false); - }, - [getFormattedFiat, settings.showFiat] - ); - - return { - isLoadingInvoices, - incomingTransactions, - loadInvoices, - }; -}; diff --git a/src/app/hooks/useTransactions.ts b/src/app/hooks/useTransactions.ts index 7fc62c0fc7..d07de8af4e 100644 --- a/src/app/hooks/useTransactions.ts +++ b/src/app/hooks/useTransactions.ts @@ -1,3 +1,4 @@ +import dayjs from "dayjs"; import { useCallback, useState } from "react"; import toast from "~/app/components/Toast"; import { useSettings } from "~/app/context/SettingsContext"; @@ -17,16 +18,38 @@ export const useTransactions = () => { accountId, limit, }); + const fetchInvoice = await api.getInvoices({ isSettled: true, limit }); + + const invoices: Transaction[] = fetchInvoice.invoices.map( + (invoice) => ({ + ...invoice, + title: invoice.memo, + description: invoice.memo, + date: dayjs(invoice.settleDate).fromNow(), + timestamp: invoice.settleDate, + }) + ); + const _transactions: Transaction[] = await convertPaymentsToTransactions(payments); - for (const transaction of _transactions) { + const finalList: Transaction[] = [..._transactions, ...invoices]; + + for (const transaction of finalList) { transaction.totalAmountFiat = settings.showFiat ? await getFormattedFiat(transaction.totalAmount) : ""; } - setTransactions(_transactions); + // Sort the final list by date in descending order. + finalList.sort((a, b) => { + const dateA = a.timestamp; + const dateB = b.timestamp; + return dateB - dateA; + }); + + setTransactions(finalList); + setIsLoadingTransactions(false); } catch (e) { console.error(e); diff --git a/src/app/router/Options/Options.tsx b/src/app/router/Options/Options.tsx index af4acba192..2eabac9606 100644 --- a/src/app/router/Options/Options.tsx +++ b/src/app/router/Options/Options.tsx @@ -76,16 +76,7 @@ function Options() { } /> } /> } /> - - } - /> - } - /> - + } /> } /> } /> } /> diff --git a/src/app/screens/Home/AllowanceView/index.tsx b/src/app/screens/Home/AllowanceView/index.tsx index 34c0d42e17..d91187dcf6 100644 --- a/src/app/screens/Home/AllowanceView/index.tsx +++ b/src/app/screens/Home/AllowanceView/index.tsx @@ -152,7 +152,7 @@ const AllowanceView: FC = (props) => { {hasTransactions && } {!isLoadingTransactions && !transactions?.length && ( -

+

= (props) => { const { t } = useTranslation("translation", { keyPrefix: "home" }); const { t: tCommon } = useTranslation("common"); - const { t: tComponents } = useTranslation("components"); + const navigate = useNavigate(); @@ -48,12 +47,7 @@ const DefaultView: FC = (props) => { const { transactions, isLoadingTransactions, loadTransactions } = useTransactions(); - const { isLoadingInvoices, incomingTransactions, loadInvoices } = - useInvoices(); - - const isLoadingOutgoing = accountLoading || isLoadingTransactions; - const isLoadingIncoming = accountLoading || isLoadingInvoices; - + const isLoading = accountLoading || isLoadingTransactions; const itemsLimit = 8; useEffect(() => { @@ -65,15 +59,6 @@ const DefaultView: FC = (props) => { itemsLimit, ]); - useEffect(() => { - loadInvoices(itemsLimit); - }, [ - account?.id, - balancesDecorated?.accountBalance, - loadInvoices, - itemsLimit, - ]); - // check if currentURL is blocked useEffect(() => { const checkBlockedUrl = async (host: string) => { @@ -180,71 +165,30 @@ const DefaultView: FC = (props) => {

)} - {isLoadingTransactions && ( + {isLoading && (
)} - {!isLoadingTransactions && ( + {!isLoading && (

{t("default_view.latest_transactions")}

- - - {[ - tComponents("transaction_list.tabs.outgoing"), - tComponents("transaction_list.tabs.incoming"), - ].map((category) => ( - - ))} - - - - - <> - - {!isLoadingOutgoing && transactions.length > 0 && ( -
- - handleViewAllLink("/transactions/outgoing") - } - > - {t("default_view.all_transactions_link")} - -
- )} - -
- - <> - - {!isLoadingIncoming && incomingTransactions.length > 0 && ( -
- - handleViewAllLink("/transactions/incoming") - } - > - {t("default_view.all_transactions_link")} - -
- )} - -
-
-
+ + {!isLoading && transactions.length > 0 && ( +
+ handleViewAllLink("/transactions")}> + {t("default_view.all_transactions_link")} + +
+ )}
)}
diff --git a/src/app/screens/Publishers/Detail/index.tsx b/src/app/screens/Publishers/Detail/index.tsx index 53e0cdad5f..a02dbe2851 100644 --- a/src/app/screens/Publishers/Detail/index.tsx +++ b/src/app/screens/Publishers/Detail/index.tsx @@ -91,7 +91,7 @@ function PublisherDetail() { {transactions && transactions?.length > 0 ? ( ) : ( -

+

{ - if (type === "incoming") { - loadInvoices(); - } else { - if (account?.id) loadTransactions(account.id); - } - }, [ - type, - account?.id, - balancesDecorated?.accountBalance, - loadTransactions, - loadInvoices, - ]); + if (account?.id) loadTransactions(account.id); + }, [account?.id, balancesDecorated?.accountBalance, loadTransactions]); return ( @@ -50,7 +30,7 @@ function Transactions({ type }: Props) {

- {t(`description.${type}`)} + {t("description")}

{isLoading ? ( diff --git a/src/app/utils/payments.ts b/src/app/utils/payments.ts index cfb0aa3941..d2fec32cce 100644 --- a/src/app/utils/payments.ts +++ b/src/app/utils/payments.ts @@ -11,6 +11,7 @@ export const convertPaymentToTransaction = ( date: dayjs(+payment.createdAt).fromNow(), title: payment.name || payment.description, publisherLink: publisherLink || payment.location, + timestamp: parseInt(payment.createdAt), }); export const convertPaymentsToTransactions = ( diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index d215a71d36..b05b80ace1 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -366,8 +366,8 @@ "latest_transactions": "Latest Transactions", "is_blocked_hint": "Alby is currently disabled on {{host}}", "block_removed": "Enabled {{host}}. Please reload the website.", - "no_outgoing_transactions": "No outgoing transactions for this account yet.", - "no_incoming_transactions": "No incoming transactions for this account yet.", + "no_transactions": "No transactions for this account yet.", + "all_transactions_link": "See all transactions" } }, @@ -954,10 +954,8 @@ }, "transactions": { "title": "Transactions", - "description": { - "outgoing": "Outgoing transactions for this account", - "incoming": "Incoming transactions for this account" - }, + "description": "Transactions for this account", + "list_empty": "No transactions available yet." }, "onboard": { diff --git a/src/types.ts b/src/types.ts index da8064fd79..7039183743 100644 --- a/src/types.ts +++ b/src/types.ts @@ -692,6 +692,7 @@ export interface RequestInvoiceArgs { } export type Transaction = { + timestamp: number; amount?: string; boostagram?: Invoice["boostagram"]; createdAt?: string; From 62b00ab3151d8b4a30b7482ca83d50e80a0cc1e6 Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Thu, 21 Sep 2023 13:40:27 +0530 Subject: [PATCH 06/40] feat: redesign sats showcase --- src/app/components/TransactionsTable/index.tsx | 16 +++++++++++----- .../utils/__tests__/currencyConvert.test.ts | 6 +++--- src/common/utils/currencyConvert.ts | 7 ++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index 0ecbaf1f8b..4492d7499a 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -22,9 +22,9 @@ export default function TransactionsTable({ loading = false, }: Props) { const { getFormattedSats } = useSettings(); - const { t } = useTranslation("components"); const [modalOpen, setModalOpen] = useState(false); const [transaction, setTransaction] = useState(); + const { t: tCommon } = useTranslation("common"); function openDetails(transaction: Transaction) { setTransaction(transaction); @@ -99,14 +99,20 @@ export default function TransactionsTable({ "text-sm font-medium", type == "incoming" ? "text-green-600 dark:color-green-400" - : "" + : "text-orange-600 dark:color-orange-400", + "inline" )} > - {type == "outgoing" ? "-" : "+"} - {getFormattedSats(tx.totalAmount)} + {type == "outgoing" ? "-" : "+"}{" "} + {getFormattedSats(tx.totalAmount)}{" "} +

+

+ {tCommon("sats", { + count: Number(tx.totalAmount), + })}

{!!tx.totalAmountFiat && ( -

+

~{tx.totalAmountFiat}

)} diff --git a/src/common/utils/__tests__/currencyConvert.test.ts b/src/common/utils/__tests__/currencyConvert.test.ts index 1f8af2a33e..a01f816828 100644 --- a/src/common/utils/__tests__/currencyConvert.test.ts +++ b/src/common/utils/__tests__/currencyConvert.test.ts @@ -110,19 +110,19 @@ describe("Currency coversion utils", () => { test("formats correctly for english", async () => { const result = getFormattedSats({ amount: 123456789, locale: "en" }); - expect(result).toBe("123,456,789 sats"); + expect(result).toBe("123,456,789"); }); test("formats correctly for spanish", async () => { const result = getFormattedSats({ amount: 123456789, locale: "es" }); - expect(result).toBe("123.456.789 sats"); + expect(result).toBe("123.456.789"); }); test("falls back to english", async () => { const result = getFormattedSats({ amount: 123456789, locale: "" }); - expect(result).toBe("123,456,789 sats"); + expect(result).toBe("123,456,789"); }); }); }); diff --git a/src/common/utils/currencyConvert.ts b/src/common/utils/currencyConvert.ts index 02d9f2b624..cb986bf359 100644 --- a/src/common/utils/currencyConvert.ts +++ b/src/common/utils/currencyConvert.ts @@ -1,9 +1,8 @@ /** * Highly inspired by: https://github.com/AryanJ-NYC/bitcoin-conversion */ -import i18n from "~/i18n/i18nConfig"; -import type { CURRENCIES, ACCOUNT_CURRENCIES } from "../constants"; +import type { ACCOUNT_CURRENCIES, CURRENCIES } from "../constants"; export const numSatsInBtc = 100_000_000; @@ -49,7 +48,5 @@ export const getFormattedSats = (params: { }) => { const formattedNumber = getFormattedNumber(params); - return `${formattedNumber} ${i18n.t("common:sats", { - count: Number(params.amount), - })}`; + return `${formattedNumber}`; }; From 95ec2b0e6a3760b61a3cc611c74e96d9514e3b88 Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Fri, 22 Sep 2023 11:54:14 +0530 Subject: [PATCH 07/40] feat: keep sats word in the currencty converter itself color sats word in transaction table using regex --- .../components/PaymentSummary/index.test.tsx | 2 +- .../TransactionsTable/index.test.tsx | 6 +- .../components/TransactionsTable/index.tsx | 99 ++++++++++++++++--- .../utils/__tests__/currencyConvert.test.ts | 6 +- src/common/utils/currencyConvert.ts | 5 +- 5 files changed, 98 insertions(+), 20 deletions(-) diff --git a/src/app/components/PaymentSummary/index.test.tsx b/src/app/components/PaymentSummary/index.test.tsx index fbbf989798..ecac0672b8 100644 --- a/src/app/components/PaymentSummary/index.test.tsx +++ b/src/app/components/PaymentSummary/index.test.tsx @@ -1,5 +1,5 @@ import PaymentSummary, { Props } from "@components/PaymentSummary"; -import { render, screen, act } from "@testing-library/react"; +import { act, render, screen } from "@testing-library/react"; import { I18nextProvider } from "react-i18next"; import { BrowserRouter } from "react-router-dom"; import { settingsFixture as mockSettings } from "~/../tests/fixtures/settings"; diff --git a/src/app/components/TransactionsTable/index.test.tsx b/src/app/components/TransactionsTable/index.test.tsx index e6da0f5e83..fd8348386e 100644 --- a/src/app/components/TransactionsTable/index.test.tsx +++ b/src/app/components/TransactionsTable/index.test.tsx @@ -118,7 +118,7 @@ describe("TransactionsTable", () => { expect(screen.getByText("Alby")).toBeInTheDocument(); expect(screen.getByText(/5 days ago/)).toBeInTheDocument(); - expect(await screen.findByText(/-1,234,000 sats/)).toBeInTheDocument(); + expect(await screen.findByText(/- 1,234,000/)).toBeInTheDocument(); expect(await screen.findByText(/~\$241.02/)).toBeInTheDocument(); }); @@ -135,7 +135,7 @@ describe("TransactionsTable", () => { expect(await screen.findByText("lambo lambo")).toBeInTheDocument(); expect(await screen.findByText(/4 days ago/)).toBeInTheDocument(); - expect(await screen.findByText(/\+66,666 sats/)).toBeInTheDocument(); + expect(await screen.findByText(/\+ 66,666/)).toBeInTheDocument(); expect(await screen.findByText(/~\$13.02/)).toBeInTheDocument(); const disclosureButtons = screen.queryByRole("button"); @@ -155,7 +155,7 @@ describe("TransactionsTable", () => { expect(screen.getByText("dumplings")).toBeInTheDocument(); expect(screen.getByText(/5 days ago/)).toBeInTheDocument(); - expect(await screen.findByText(/\+88,888 sats/)).toBeInTheDocument(); + expect(await screen.findByText(/\+ 88,888/)).toBeInTheDocument(); expect(await screen.findByText(/~\$17.36/)).toBeInTheDocument(); }); }); diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index 4492d7499a..87b9eb5e72 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -3,6 +3,7 @@ import { ArrowUpIcon, } from "@bitcoin-design/bitcoin-icons-react/filled"; import Loading from "@components/Loading"; +import dayjs from "dayjs"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import Modal from "~/app/components/Modal"; @@ -99,18 +100,18 @@ export default function TransactionsTable({ "text-sm font-medium", type == "incoming" ? "text-green-600 dark:color-green-400" - : "text-orange-600 dark:color-orange-400", - "inline" + : "text-orange-600 dark:color-orange-400" )} > {type == "outgoing" ? "-" : "+"}{" "} - {getFormattedSats(tx.totalAmount)}{" "} -

-

- {tCommon("sats", { - count: Number(tx.totalAmount), - })} + {getFormattedSats(tx.totalAmount).replace(/sats?/g, " ")} + + {tCommon("sats", { + count: Number(tx.totalAmount), + })} +

+ {!!tx.totalAmountFiat && (

~{tx.totalAmountFiat} @@ -126,7 +127,7 @@ export default function TransactionsTable({ setModalOpen(false)} - title={"test"} + title={"Transactions"} > {transaction && (

@@ -134,16 +135,90 @@ export default function TransactionsTable({
{getTransactionType(transaction) == "outgoing" ? (
- +
) : (
- +
)}
+

+ {transaction.type == "received" ? "Received" : "Sent"} +

+
+
+
+

+ {transaction.type == "sent" ? "-" : "+"}{" "} + {getFormattedSats(transaction.totalAmount).replace( + /sats?/g, + " " + )} + + {tCommon("sats", { + count: Number(transaction.amount), + })} + +

+ + {!!transaction.totalAmountFiat && ( +

+ ~{transaction.totalAmountFiat} +

+ )} +
+
+
+
+
+
+
+
+ Date & Time +
+
+ {dayjs(transaction.timestamp).format( + "D MMMM YYYY, HH:mm" + )} +
+
+
+
+ Fees +
+
+ {transaction.totalFees} Sats +
+
+
+
+ Description +
+
+ {transaction.description} +
+
+
+
+ Preimage +
+
+ {transaction.preimage} +
+
+
+
+
-
details
)} diff --git a/src/common/utils/__tests__/currencyConvert.test.ts b/src/common/utils/__tests__/currencyConvert.test.ts index a01f816828..1f8af2a33e 100644 --- a/src/common/utils/__tests__/currencyConvert.test.ts +++ b/src/common/utils/__tests__/currencyConvert.test.ts @@ -110,19 +110,19 @@ describe("Currency coversion utils", () => { test("formats correctly for english", async () => { const result = getFormattedSats({ amount: 123456789, locale: "en" }); - expect(result).toBe("123,456,789"); + expect(result).toBe("123,456,789 sats"); }); test("formats correctly for spanish", async () => { const result = getFormattedSats({ amount: 123456789, locale: "es" }); - expect(result).toBe("123.456.789"); + expect(result).toBe("123.456.789 sats"); }); test("falls back to english", async () => { const result = getFormattedSats({ amount: 123456789, locale: "" }); - expect(result).toBe("123,456,789"); + expect(result).toBe("123,456,789 sats"); }); }); }); diff --git a/src/common/utils/currencyConvert.ts b/src/common/utils/currencyConvert.ts index cb986bf359..2a83b657d5 100644 --- a/src/common/utils/currencyConvert.ts +++ b/src/common/utils/currencyConvert.ts @@ -2,6 +2,7 @@ * Highly inspired by: https://github.com/AryanJ-NYC/bitcoin-conversion */ +import i18n from "~/i18n/i18nConfig"; import type { ACCOUNT_CURRENCIES, CURRENCIES } from "../constants"; export const numSatsInBtc = 100_000_000; @@ -48,5 +49,7 @@ export const getFormattedSats = (params: { }) => { const formattedNumber = getFormattedNumber(params); - return `${formattedNumber}`; + return `${formattedNumber} ${i18n.t("common:sats", { + count: Number(params.amount), + })}`; }; From b96acbc4966c850ea74623026ac4ed782369b54a Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Mon, 25 Sep 2023 09:30:14 +0530 Subject: [PATCH 08/40] feat: add payment hash in transaction model --- .../components/TransactionsTable/index.tsx | 70 ++++++++++++------- src/types.ts | 1 + 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index 87b9eb5e72..ce361375f5 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -151,7 +151,7 @@ export default function TransactionsTable({

{!!transaction.totalAmountFiat && ( -

+

~{transaction.totalAmountFiat}

)} @@ -181,7 +181,7 @@ export default function TransactionsTable({
-
+
Date & Time
@@ -191,30 +191,46 @@ export default function TransactionsTable({ )}
-
-
- Fees -
-
- {transaction.totalFees} Sats -
-
-
-
- Description -
-
- {transaction.description} -
-
-
-
- Preimage -
-
- {transaction.preimage} -
-
+ {transaction.totalFees !== undefined && ( +
+
+ Fee +
+
+ {transaction.totalFees} Sats +
+
+ )} + {transaction.description !== undefined && ( +
+
+ Description +
+
+ {transaction.description} +
+
+ )} + {transaction.type == "sent" && ( +
+
+ Preimage +
+
+ {transaction.preimage} +
+
+ )} + {transaction.type == "sent" && ( +
+
+ Hash +
+
+ {transaction.paymentHash} +
+
+ )}
diff --git a/src/types.ts b/src/types.ts index 7039183743..e9a0796876 100644 --- a/src/types.ts +++ b/src/types.ts @@ -698,6 +698,7 @@ export type Transaction = { createdAt?: string; currency?: string; date: string; + paymentHash?: string; description?: string; host?: string; id: string; From 5e617df3e6ea1989cd85788e4312fda46d5fd313 Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Tue, 26 Sep 2023 13:08:35 +0530 Subject: [PATCH 09/40] feat: add show more button --- .../components/TransactionsTable/index.tsx | 30 +++++++++++++++++-- src/app/utils/payments.ts | 2 +- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index ce361375f5..5fd6a5972e 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -1,11 +1,14 @@ import { ArrowDownIcon, ArrowUpIcon, + CaretDownIcon, + CaretUpIcon, } from "@bitcoin-design/bitcoin-icons-react/filled"; import Loading from "@components/Loading"; import dayjs from "dayjs"; import { useState } from "react"; import { useTranslation } from "react-i18next"; +import Hyperlink from "~/app/components/Hyperlink"; import Modal from "~/app/components/Modal"; import { useSettings } from "~/app/context/SettingsContext"; import { classNames } from "~/app/utils"; @@ -26,6 +29,7 @@ export default function TransactionsTable({ const [modalOpen, setModalOpen] = useState(false); const [transaction, setTransaction] = useState(); const { t: tCommon } = useTranslation("common"); + const [showMoreFields, setShowMoreFields] = useState(false); function openDetails(transaction: Transaction) { setTransaction(transaction); @@ -38,6 +42,10 @@ export default function TransactionsTable({ : "incoming"; } + function toggleShowMoreFields() { + setShowMoreFields(!showMoreFields); + } + return loading ? (
@@ -80,7 +88,7 @@ export default function TransactionsTable({ href={tx.publisherLink} rel="noopener noreferrer" > - {tx.title} + {transactionTitle(tx)} ) : ( tx.title || @@ -211,7 +219,17 @@ export default function TransactionsTable({
)} - {transaction.type == "sent" && ( +
+ + {tCommon("actions.more")}{" "} + {showMoreFields ? ( + + ) : ( + + )} + +
+ {showMoreFields && transaction.type == "sent" && (
Preimage @@ -221,7 +239,7 @@ export default function TransactionsTable({
)} - {transaction.type == "sent" && ( + {showMoreFields && transaction.type == "sent" && (
Hash @@ -241,3 +259,9 @@ export default function TransactionsTable({ ); } + +function transactionTitle(tx: Transaction) { + const title = tx.title; + + if (title) return title; +} diff --git a/src/app/utils/payments.ts b/src/app/utils/payments.ts index d2fec32cce..16bca621e0 100644 --- a/src/app/utils/payments.ts +++ b/src/app/utils/payments.ts @@ -9,7 +9,7 @@ export const convertPaymentToTransaction = ( id: `${payment.id}`, type: "sent", date: dayjs(+payment.createdAt).fromNow(), - title: payment.name || payment.description, + title: payment.description || payment.name, publisherLink: publisherLink || payment.location, timestamp: parseInt(payment.createdAt), }); From 80a5490eae504e820b07cc99cafca8458b527f7d Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Tue, 26 Sep 2023 14:00:38 +0530 Subject: [PATCH 10/40] feat: add boostagram details --- .../components/TransactionsTable/index.tsx | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index 5fd6a5972e..101d631f13 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -209,6 +209,26 @@ export default function TransactionsTable({
)} + {transaction.boostagram?.podcast !== undefined && ( +
+
+ Podcast +
+
+ {transaction.boostagram?.podcast} +
+
+ )} + {transaction.boostagram?.episode !== undefined && ( +
+
+ Episode +
+
+ {transaction.boostagram.episode} +
+
+ )} {transaction.description !== undefined && (
From 314febcc527f33d934513d992c4ef6ea606d2503 Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Tue, 26 Sep 2023 14:56:15 +0530 Subject: [PATCH 11/40] feat: cleanup regex keep same color for now --- .../TransactionsTable/index.test.tsx | 6 ++--- .../components/TransactionsTable/index.tsx | 25 +++---------------- src/app/hooks/useTransactions.ts | 8 +++--- 3 files changed, 10 insertions(+), 29 deletions(-) diff --git a/src/app/components/TransactionsTable/index.test.tsx b/src/app/components/TransactionsTable/index.test.tsx index fd8348386e..cf29b6bf12 100644 --- a/src/app/components/TransactionsTable/index.test.tsx +++ b/src/app/components/TransactionsTable/index.test.tsx @@ -118,7 +118,7 @@ describe("TransactionsTable", () => { expect(screen.getByText("Alby")).toBeInTheDocument(); expect(screen.getByText(/5 days ago/)).toBeInTheDocument(); - expect(await screen.findByText(/- 1,234,000/)).toBeInTheDocument(); + expect(await screen.findByText(/- 1,234,000 sats/)).toBeInTheDocument(); expect(await screen.findByText(/~\$241.02/)).toBeInTheDocument(); }); @@ -135,7 +135,7 @@ describe("TransactionsTable", () => { expect(await screen.findByText("lambo lambo")).toBeInTheDocument(); expect(await screen.findByText(/4 days ago/)).toBeInTheDocument(); - expect(await screen.findByText(/\+ 66,666/)).toBeInTheDocument(); + expect(await screen.findByText(/\+ 66,666 sats/)).toBeInTheDocument(); expect(await screen.findByText(/~\$13.02/)).toBeInTheDocument(); const disclosureButtons = screen.queryByRole("button"); @@ -155,7 +155,7 @@ describe("TransactionsTable", () => { expect(screen.getByText("dumplings")).toBeInTheDocument(); expect(screen.getByText(/5 days ago/)).toBeInTheDocument(); - expect(await screen.findByText(/\+ 88,888/)).toBeInTheDocument(); + expect(await screen.findByText(/\+ 88,888 sats/)).toBeInTheDocument(); expect(await screen.findByText(/~\$17.36/)).toBeInTheDocument(); }); }); diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index 101d631f13..2da8dfe25a 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -88,7 +88,7 @@ export default function TransactionsTable({ href={tx.publisherLink} rel="noopener noreferrer" > - {transactionTitle(tx)} + {tx.title} ) : ( tx.title || @@ -112,12 +112,7 @@ export default function TransactionsTable({ )} > {type == "outgoing" ? "-" : "+"}{" "} - {getFormattedSats(tx.totalAmount).replace(/sats?/g, " ")} - - {tCommon("sats", { - count: Number(tx.totalAmount), - })} - + {getFormattedSats(tx.totalAmount)}

{!!tx.totalAmountFiat && ( @@ -167,15 +162,7 @@ export default function TransactionsTable({ )} > {transaction.type == "sent" ? "-" : "+"}{" "} - {getFormattedSats(transaction.totalAmount).replace( - /sats?/g, - " " - )} - - {tCommon("sats", { - count: Number(transaction.amount), - })} - + {getFormattedSats(transaction.totalAmount)}

{!!transaction.totalAmountFiat && ( @@ -279,9 +266,3 @@ export default function TransactionsTable({ ); } - -function transactionTitle(tx: Transaction) { - const title = tx.title; - - if (title) return title; -} diff --git a/src/app/hooks/useTransactions.ts b/src/app/hooks/useTransactions.ts index d07de8af4e..18ca597bce 100644 --- a/src/app/hooks/useTransactions.ts +++ b/src/app/hooks/useTransactions.ts @@ -33,22 +33,22 @@ export const useTransactions = () => { const _transactions: Transaction[] = await convertPaymentsToTransactions(payments); - const finalList: Transaction[] = [..._transactions, ...invoices]; + const transactionList: Transaction[] = [..._transactions, ...invoices]; - for (const transaction of finalList) { + for (const transaction of transactionList) { transaction.totalAmountFiat = settings.showFiat ? await getFormattedFiat(transaction.totalAmount) : ""; } // Sort the final list by date in descending order. - finalList.sort((a, b) => { + transactionList.sort((a, b) => { const dateA = a.timestamp; const dateB = b.timestamp; return dateB - dateA; }); - setTransactions(finalList); + setTransactions(transactionList); setIsLoadingTransactions(false); } catch (e) { From ce2980e729e806c0b57ec2dac8745cee94c03db4 Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Tue, 26 Sep 2023 15:12:25 +0530 Subject: [PATCH 12/40] chore: resolve conflict --- src/app/screens/Home/DefaultView/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/app/screens/Home/DefaultView/index.tsx b/src/app/screens/Home/DefaultView/index.tsx index 7046508857..48b97f537d 100644 --- a/src/app/screens/Home/DefaultView/index.tsx +++ b/src/app/screens/Home/DefaultView/index.tsx @@ -15,7 +15,6 @@ import BalanceBox from "~/app/components/BalanceBox"; import SkeletonLoader from "~/app/components/SkeletonLoader"; import toast from "~/app/components/Toast"; import { useAccount } from "~/app/context/AccountContext"; - import { useTransactions } from "~/app/hooks/useTransactions"; import { PublisherLnData } from "~/app/screens/Home/PublisherLnData"; import api from "~/common/lib/api"; @@ -35,7 +34,6 @@ const DefaultView: FC = (props) => { const { t } = useTranslation("translation", { keyPrefix: "home" }); const { t: tCommon } = useTranslation("common"); - const navigate = useNavigate(); const { account, balancesDecorated, accountLoading } = useAccount(); From 21df7e360448d29f8638d024d6013d6b0a0b0f77 Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Wed, 27 Sep 2023 15:13:23 +0530 Subject: [PATCH 13/40] feat: refactor transaction modal setup callback communication minor naming corrections shift publisher link in the transaction modal correct variable names, show total fees in form of formatted sats signed-off-by: pavan joshi --- .../TransactionsTable/TransactionModal.tsx | 208 ++++++++++++++++++ .../components/TransactionsTable/index.tsx | 171 +------------- src/app/hooks/useTransactions.ts | 7 +- 3 files changed, 225 insertions(+), 161 deletions(-) create mode 100644 src/app/components/TransactionsTable/TransactionModal.tsx diff --git a/src/app/components/TransactionsTable/TransactionModal.tsx b/src/app/components/TransactionsTable/TransactionModal.tsx new file mode 100644 index 0000000000..27e95685ac --- /dev/null +++ b/src/app/components/TransactionsTable/TransactionModal.tsx @@ -0,0 +1,208 @@ +import { + ArrowDownIcon, + ArrowUpIcon, + CaretDownIcon, + CaretUpIcon, +} from "@bitcoin-design/bitcoin-icons-react/filled"; +import dayjs from "dayjs"; +import { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import Hyperlink from "~/app/components/Hyperlink"; +import Modal from "~/app/components/Modal"; +import { useSettings } from "~/app/context/SettingsContext"; +import { classNames } from "~/app/utils"; +import { Transaction } from "~/types"; + +type Props = { + transaction: Transaction | undefined; + onModelClose: () => void; + isOpen: boolean; +}; + +export default function TransactionModal({ + transaction, + isOpen, + onModelClose, +}: Props) { + const { t: tCommon } = useTranslation("common"); + const [showMoreFields, setShowMoreFields] = useState(false); + const { getFormattedSats } = useSettings(); + const [_isRevealed, setRevealed] = useState(false); + + function toggleShowMoreFields() { + setShowMoreFields(!showMoreFields); + } + + function getTransactionType(tx: Transaction): "incoming" | "outgoing" { + return [tx.type && "sent", "sending"].includes(tx.type) + ? "outgoing" + : "incoming"; + } + + useEffect(() => { + if (typeof isOpen !== "undefined") { + setRevealed(isOpen); + } + }, [isOpen]); + + return ( + { + setRevealed(false); + onModelClose(); + setShowMoreFields(false); + }} + title={"Transactions"} + > + {_isRevealed && transaction && ( +
+
+
+ {getTransactionType(transaction) == "outgoing" ? ( +
+ +
+ ) : ( +
+ +
+ )} +
+

+ {transaction.type == "received" ? "Received" : "Sent"} +

+
+
+
+

+ {transaction.type == "sent" ? "-" : "+"}{" "} + {getFormattedSats(transaction.totalAmount)} +

+ + {!!transaction.totalAmountFiat && ( +

+ ~{transaction.totalAmountFiat} +

+ )} +
+
+
+
+
+
+
+
+ Date & Time +
+
+ {dayjs(transaction.timestamp).format( + "D MMMM YYYY, HH:mm" + )} +
+
+ {transaction.totalFees?.toString && ( +
+
+ Fee +
+
+ {getFormattedSats(transaction.totalFees)} +
+
+ )} + {transaction.publisherLink && transaction.title && ( +
+
+ Website +
+
+ + {transaction.title} + +
+
+ )} + + {transaction.boostagram?.podcast && ( +
+
+ Podcast +
+
+ {transaction.boostagram?.podcast} +
+
+ )} + {transaction.boostagram?.episode && ( +
+
+ Episode +
+
+ {transaction.boostagram.episode} +
+
+ )} + {transaction.description && ( +
+
+ Description +
+
+ {transaction.description} +
+
+ )} +
+ + {tCommon("actions.more")}{" "} + {showMoreFields ? ( + + ) : ( + + )} + +
+ {showMoreFields && transaction.type == "sent" && ( +
+
+ Preimage +
+
+ {transaction.preimage} +
+
+ )} + {showMoreFields && transaction.type == "sent" && ( +
+
+ Hash +
+
+ {transaction.paymentHash} +
+
+ )} +
+
+
+
+
+ )} +
+ ); +} diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index 2da8dfe25a..3433645048 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -1,15 +1,12 @@ import { ArrowDownIcon, ArrowUpIcon, - CaretDownIcon, - CaretUpIcon, } from "@bitcoin-design/bitcoin-icons-react/filled"; import Loading from "@components/Loading"; -import dayjs from "dayjs"; + import { useState } from "react"; -import { useTranslation } from "react-i18next"; -import Hyperlink from "~/app/components/Hyperlink"; -import Modal from "~/app/components/Modal"; + +import TransactionModal from "~/app/components/TransactionsTable/TransactionModal"; import { useSettings } from "~/app/context/SettingsContext"; import { classNames } from "~/app/utils"; import { Transaction } from "~/types"; @@ -28,8 +25,6 @@ export default function TransactionsTable({ const { getFormattedSats } = useSettings(); const [modalOpen, setModalOpen] = useState(false); const [transaction, setTransaction] = useState(); - const { t: tCommon } = useTranslation("common"); - const [showMoreFields, setShowMoreFields] = useState(false); function openDetails(transaction: Transaction) { setTransaction(transaction); @@ -42,10 +37,6 @@ export default function TransactionsTable({ : "incoming"; } - function toggleShowMoreFields() { - setShowMoreFields(!showMoreFields); - } - return loading ? (
@@ -82,19 +73,9 @@ export default function TransactionsTable({ text-sm font-medium text-black truncate dark:text-white" >

- {tx.publisherLink && tx.title ? ( - - {tx.title} - - ) : ( - tx.title || + {tx.title || tx.boostagram?.message || - (type == "incoming" ? "Received" : "Sent") - )} + (type == "incoming" ? "Received" : "Sent")}

@@ -127,142 +108,14 @@ export default function TransactionsTable({ ); })}

- setModalOpen(false)} - title={"Transactions"} - > - {transaction && ( -
-
-
- {getTransactionType(transaction) == "outgoing" ? ( -
- -
- ) : ( -
- -
- )} -
-

- {transaction.type == "received" ? "Received" : "Sent"} -

-
-
-
-

- {transaction.type == "sent" ? "-" : "+"}{" "} - {getFormattedSats(transaction.totalAmount)} -

- {!!transaction.totalAmountFiat && ( -

- ~{transaction.totalAmountFiat} -

- )} -
-
-
-
-
-
-
-
- Date & Time -
-
- {dayjs(transaction.timestamp).format( - "D MMMM YYYY, HH:mm" - )} -
-
- {transaction.totalFees !== undefined && ( -
-
- Fee -
-
- {transaction.totalFees} Sats -
-
- )} - {transaction.boostagram?.podcast !== undefined && ( -
-
- Podcast -
-
- {transaction.boostagram?.podcast} -
-
- )} - {transaction.boostagram?.episode !== undefined && ( -
-
- Episode -
-
- {transaction.boostagram.episode} -
-
- )} - {transaction.description !== undefined && ( -
-
- Description -
-
- {transaction.description} -
-
- )} -
- - {tCommon("actions.more")}{" "} - {showMoreFields ? ( - - ) : ( - - )} - -
- {showMoreFields && transaction.type == "sent" && ( -
-
- Preimage -
-
- {transaction.preimage} -
-
- )} - {showMoreFields && transaction.type == "sent" && ( -
-
- Hash -
-
- {transaction.paymentHash} -
-
- )} -
-
-
-
-
- )} -
+ { + setModalOpen(false); + }} + /> ); } diff --git a/src/app/hooks/useTransactions.ts b/src/app/hooks/useTransactions.ts index 18ca597bce..1bda4c0b36 100644 --- a/src/app/hooks/useTransactions.ts +++ b/src/app/hooks/useTransactions.ts @@ -18,9 +18,12 @@ export const useTransactions = () => { accountId, limit, }); - const fetchInvoice = await api.getInvoices({ isSettled: true, limit }); + const getInvoicesResponse = await api.getInvoices({ + isSettled: true, + limit, + }); - const invoices: Transaction[] = fetchInvoice.invoices.map( + const invoices: Transaction[] = getInvoicesResponse.invoices.map( (invoice) => ({ ...invoice, title: invoice.memo, From 3092cf4caf71f05111187b387bd1429ba6034cdd Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Tue, 3 Oct 2023 15:21:40 +0530 Subject: [PATCH 14/40] feat: add getTransactions Method --- src/app/hooks/useTransactions.ts | 6 +++ src/common/lib/api.ts | 4 ++ .../background-script/actions/ln/index.ts | 4 +- .../actions/ln/transactions.ts | 38 +++++++++++++++++ .../background-script/connectors/alby.ts | 41 ++++++++++++++++++- .../background-script/connectors/citadel.ts | 10 +++++ .../background-script/connectors/commando.ts | 10 +++++ .../connectors/connector.interface.ts | 8 +++- .../background-script/connectors/eclair.ts | 10 +++++ .../background-script/connectors/galoy.ts | 10 +++++ .../background-script/connectors/kollider.ts | 10 +++++ .../background-script/connectors/lnbits.ts | 10 +++++ .../background-script/connectors/lnc.ts | 10 +++++ .../background-script/connectors/lnd.ts | 10 +++++ .../background-script/connectors/lndhub.ts | 10 +++++ src/extension/background-script/router.ts | 1 + src/types.ts | 6 ++- 17 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 src/extension/background-script/actions/ln/transactions.ts diff --git a/src/app/hooks/useTransactions.ts b/src/app/hooks/useTransactions.ts index 1bda4c0b36..5d458aa5c4 100644 --- a/src/app/hooks/useTransactions.ts +++ b/src/app/hooks/useTransactions.ts @@ -33,6 +33,12 @@ export const useTransactions = () => { }) ); + // const getalltrans = await api.getTransactions({ + // isSettled: true, + // limit, + // }); + // console.log(getalltrans); + const _transactions: Transaction[] = await convertPaymentsToTransactions(payments); diff --git a/src/common/lib/api.ts b/src/common/lib/api.ts index 3211403022..d588cafab9 100644 --- a/src/common/lib/api.ts +++ b/src/common/lib/api.ts @@ -26,6 +26,7 @@ import type { MessageInvoices, MessageLnurlAuth, MessageSettingsSet, + MessageTransactions, NodeInfo, PsetPreview, SettingsStorage, @@ -168,6 +169,8 @@ export const getBlocklist = (host: string) => msg.request("getBlocklist", { host }); export const getInvoices = (options?: MessageInvoices["args"]) => msg.request<{ invoices: Invoice[] }>("getInvoices", options); +export const getTransactions = (options?: MessageTransactions["args"]) => + msg.request<{ transactions: Invoice[] }>("getTransactions", options); export const lnurlAuth = ( options: MessageLnurlAuth["args"] ): Promise => @@ -260,6 +263,7 @@ export default { unlock, getBlocklist, getInvoices, + getTransactions, lnurlAuth, getCurrencyRate, nostr: { diff --git a/src/extension/background-script/actions/ln/index.ts b/src/extension/background-script/actions/ln/index.ts index 5f26c3fe3e..8b2667de30 100644 --- a/src/extension/background-script/actions/ln/index.ts +++ b/src/extension/background-script/actions/ln/index.ts @@ -7,6 +7,7 @@ import makeInvoice from "./makeInvoice"; import request from "./request"; import sendPayment from "./sendPayment"; import signMessage from "./signMessage"; +import transactions from "./transactions"; export { checkPayment, @@ -15,7 +16,8 @@ export { invoices, keysend, makeInvoice, + request, sendPayment, signMessage, - request, + transactions, }; diff --git a/src/extension/background-script/actions/ln/transactions.ts b/src/extension/background-script/actions/ln/transactions.ts new file mode 100644 index 0000000000..1e07b67540 --- /dev/null +++ b/src/extension/background-script/actions/ln/transactions.ts @@ -0,0 +1,38 @@ +import utils from "~/common/lib/utils"; +import state from "~/extension/background-script/state"; +import type { Invoice, MessageTransactions } from "~/types"; + +const transactions = async (message: MessageTransactions) => { + const isSettled = message.args.isSettled; + const limit = message.args.limit; + + const connector = await state.getState().getConnector(); + try { + const result = await connector.getTransactions(); + let invoices: Invoice[] = result.data.transactions + .filter((invoice) => (isSettled ? invoice.settled : !invoice.settled)) + .map((invoice) => { + const boostagram = utils.getBoostagramFromInvoiceCustomRecords( + invoice.custom_records + ); + return { ...invoice, boostagram }; + }); + + if (limit) { + invoices = invoices.slice(0, limit); + } + + return { + data: { + invoices, + }, + }; + } catch (e) { + console.error(e); + if (e instanceof Error) { + return { error: e.message }; + } + } +}; + +export default transactions; diff --git a/src/extension/background-script/connectors/alby.ts b/src/extension/background-script/connectors/alby.ts index 260feebfcb..065797d380 100644 --- a/src/extension/background-script/connectors/alby.ts +++ b/src/extension/background-script/connectors/alby.ts @@ -20,6 +20,7 @@ import Connector, { GetBalanceResponse, GetInfoResponse, GetInvoicesResponse, + GetTransactionsResponse, KeysendArgs, MakeInvoiceArgs, MakeInvoiceResponse, @@ -69,7 +70,14 @@ export default class Alby implements Connector { } get supportedMethods() { - return ["getInfo", "keysend", "makeInvoice", "sendPayment", "getBalance"]; + return [ + "getInfo", + "keysend", + "makeInvoice", + "sendPayment", + "getBalance", + "getTransactions", + ]; } // not yet implemented @@ -104,6 +112,37 @@ export default class Alby implements Connector { }; } + async getTransactions(): Promise { + const incomingInvoices = (await this._request((client) => + client.incomingInvoices({}) + )) as Invoice[]; + + const outgoingInvoices = (await this._request((client) => + client.outgoingInvoices({}) + )) as Invoice[]; + + const transactions: ConnectorInvoice[] = [ + ...incomingInvoices, + ...outgoingInvoices, + ].map( + (invoice, index): ConnectorInvoice => ({ + custom_records: invoice.custom_records, + id: `${invoice.payment_request}-${index}`, + memo: invoice.comment || invoice.memo, + preimage: "", // alby wallet api doesn't support preimage (yet) + settled: invoice.settled, + settleDate: new Date(invoice.settled_at).getTime(), + totalAmount: `${invoice.amount}`, + type: invoice.type == "incoming" ? "received" : "sent", + }) + ); + return { + data: { + transactions, + }, + }; + } + async getInfo(): Promise< GetInfoResponse > { diff --git a/src/extension/background-script/connectors/citadel.ts b/src/extension/background-script/connectors/citadel.ts index 24e1a90234..5d1d5ce00b 100644 --- a/src/extension/background-script/connectors/citadel.ts +++ b/src/extension/background-script/connectors/citadel.ts @@ -7,6 +7,7 @@ import Connector, { GetBalanceResponse, GetInfoResponse, GetInvoicesResponse, + GetTransactionsResponse, KeysendArgs, MakeInvoiceArgs, MakeInvoiceResponse, @@ -85,6 +86,15 @@ class CitadelConnector implements Connector { ); } + getTransactions(): Promise { + console.error( + `Not yet supported with the currently used account: ${this.constructor.name}` + ); + throw new Error( + `${this.constructor.name}: "getTransactions" is not yet supported. Contact us if you need it.` + ); + } + // not yet implemented async connectPeer(): Promise { console.error( diff --git a/src/extension/background-script/connectors/commando.ts b/src/extension/background-script/connectors/commando.ts index 6ea545af53..1b7dc82de4 100644 --- a/src/extension/background-script/connectors/commando.ts +++ b/src/extension/background-script/connectors/commando.ts @@ -14,6 +14,7 @@ import Connector, { GetBalanceResponse, GetInfoResponse, GetInvoicesResponse, + GetTransactionsResponse, KeysendArgs, MakeInvoiceArgs, MakeInvoiceResponse, @@ -221,6 +222,15 @@ export default class Commando implements Connector { }); } + getTransactions(): Promise { + console.error( + `Not yet supported with the currently used account: ${this.constructor.name}` + ); + throw new Error( + `${this.constructor.name}: "getTransactions" is not yet supported. Contact us if you need it.` + ); + } + async getInfo(): Promise { const response = (await this.ln.commando({ method: "getinfo", diff --git a/src/extension/background-script/connectors/connector.interface.ts b/src/extension/background-script/connectors/connector.interface.ts index 03700cef9b..0bd8723ec8 100644 --- a/src/extension/background-script/connectors/connector.interface.ts +++ b/src/extension/background-script/connectors/connector.interface.ts @@ -29,7 +29,7 @@ export interface ConnectorInvoice { settled: boolean; settleDate: number; totalAmount: string; - type: "received"; + type: "received" | "sent"; } export interface MakeInvoiceArgs { @@ -61,6 +61,11 @@ export type GetInvoicesResponse = { }; }; +export type GetTransactionsResponse = { + data: { + transactions: ConnectorInvoice[]; + }; +}; export type SendPaymentResponse = { data: { preimage: string; @@ -120,6 +125,7 @@ export default interface Connector { getInfo(): Promise; getBalance(): Promise; getInvoices(): Promise; + getTransactions(): Promise; makeInvoice(args: MakeInvoiceArgs): Promise; sendPayment(args: SendPaymentArgs): Promise; keysend(args: KeysendArgs): Promise; diff --git a/src/extension/background-script/connectors/eclair.ts b/src/extension/background-script/connectors/eclair.ts index 4f73c267ff..9bff743413 100644 --- a/src/extension/background-script/connectors/eclair.ts +++ b/src/extension/background-script/connectors/eclair.ts @@ -10,6 +10,7 @@ import Connector, { GetBalanceResponse, GetInfoResponse, GetInvoicesResponse, + GetTransactionsResponse, KeysendArgs, MakeInvoiceArgs, MakeInvoiceResponse, @@ -100,6 +101,15 @@ class Eclair implements Connector { }; } + getTransactions(): Promise { + console.error( + `Not yet supported with the currently used account: ${this.constructor.name}` + ); + throw new Error( + `${this.constructor.name}: "getTransactions" is not yet supported. Contact us if you need it.` + ); + } + async getBalance(): Promise { const balances = await this.request("/usablebalances"); const total = balances diff --git a/src/extension/background-script/connectors/galoy.ts b/src/extension/background-script/connectors/galoy.ts index 9690cfdd80..74e94ba5d0 100644 --- a/src/extension/background-script/connectors/galoy.ts +++ b/src/extension/background-script/connectors/galoy.ts @@ -10,6 +10,7 @@ import Connector, { GetBalanceResponse, GetInfoResponse, GetInvoicesResponse, + GetTransactionsResponse, KeysendArgs, MakeInvoiceArgs, MakeInvoiceResponse, @@ -96,6 +97,15 @@ class Galoy implements Connector { return { data: { invoices: [] } }; } + getTransactions(): Promise { + console.error( + `Not yet supported with the currently used account: ${this.constructor.name}` + ); + throw new Error( + `${this.constructor.name}: "getTransactions" is not yet supported. Contact us if you need it.` + ); + } + async getBalance(): Promise { const query = { query: ` diff --git a/src/extension/background-script/connectors/kollider.ts b/src/extension/background-script/connectors/kollider.ts index d00c125097..049ed6229a 100644 --- a/src/extension/background-script/connectors/kollider.ts +++ b/src/extension/background-script/connectors/kollider.ts @@ -16,6 +16,7 @@ import Connector, { GetBalanceResponse, GetInfoResponse, GetInvoicesResponse, + GetTransactionsResponse, KeysendArgs, MakeInvoiceArgs, MakeInvoiceResponse, @@ -133,6 +134,15 @@ export default class Kollider implements Connector { }; } + getTransactions(): Promise { + console.error( + `Not yet supported with the currently used account: ${this.constructor.name}` + ); + throw new Error( + `${this.constructor.name}: "getTransactions" is not yet supported. Contact us if you need it.` + ); + } + async getInfo(): Promise { return { data: { alias: `Kollider (${this.currency})` } }; } diff --git a/src/extension/background-script/connectors/lnbits.ts b/src/extension/background-script/connectors/lnbits.ts index 31939584c4..ed977faea0 100644 --- a/src/extension/background-script/connectors/lnbits.ts +++ b/src/extension/background-script/connectors/lnbits.ts @@ -14,6 +14,7 @@ import Connector, { GetBalanceResponse, GetInfoResponse, GetInvoicesResponse, + GetTransactionsResponse, KeysendArgs, MakeInvoiceArgs, MakeInvoiceResponse, @@ -145,6 +146,15 @@ class LnBits implements Connector { ); } + getTransactions(): Promise { + console.error( + `Not yet supported with the currently used account: ${this.constructor.name}` + ); + throw new Error( + `${this.constructor.name}: "getTransactions" is not yet supported. Contact us if you need it.` + ); + } + getBalance(): Promise { return this.request( "GET", diff --git a/src/extension/background-script/connectors/lnc.ts b/src/extension/background-script/connectors/lnc.ts index 69789de0f6..c5bfc6e375 100644 --- a/src/extension/background-script/connectors/lnc.ts +++ b/src/extension/background-script/connectors/lnc.ts @@ -19,6 +19,7 @@ import Connector, { GetBalanceResponse, GetInfoResponse, GetInvoicesResponse, + GetTransactionsResponse, KeysendArgs, MakeInvoiceArgs, MakeInvoiceResponse, @@ -270,6 +271,15 @@ class Lnc implements Connector { }; } + getTransactions(): Promise { + console.error( + `Not yet supported with the currently used account: ${this.constructor.name}` + ); + throw new Error( + `${this.constructor.name}: "getTransactions" is not yet supported. Contact us if you need it.` + ); + } + // not yet implemented async connectPeer(): Promise { console.error( diff --git a/src/extension/background-script/connectors/lnd.ts b/src/extension/background-script/connectors/lnd.ts index a488a12951..25e79df351 100644 --- a/src/extension/background-script/connectors/lnd.ts +++ b/src/extension/background-script/connectors/lnd.ts @@ -16,6 +16,7 @@ import Connector, { GetBalanceResponse, GetInfoResponse, GetInvoicesResponse, + GetTransactionsResponse, KeysendArgs, MakeInvoiceArgs, MakeInvoiceResponse, @@ -462,6 +463,15 @@ class Lnd implements Connector { }; } + getTransactions(): Promise { + console.error( + `Not yet supported with the currently used account: ${this.constructor.name}` + ); + throw new Error( + `${this.constructor.name}: "getTransactions" is not yet supported. Contact us if you need it.` + ); + } + protected async request( method: string, path: string, diff --git a/src/extension/background-script/connectors/lndhub.ts b/src/extension/background-script/connectors/lndhub.ts index 0d0e7473bd..dc8945e97e 100644 --- a/src/extension/background-script/connectors/lndhub.ts +++ b/src/extension/background-script/connectors/lndhub.ts @@ -19,6 +19,7 @@ import Connector, { GetBalanceResponse, GetInfoResponse, GetInvoicesResponse, + GetTransactionsResponse, KeysendArgs, MakeInvoiceArgs, MakeInvoiceResponse, @@ -129,6 +130,15 @@ export default class LndHub implements Connector { }; } + getTransactions(): Promise { + console.error( + `Not yet supported with the currently used account: ${this.constructor.name}` + ); + throw new Error( + `${this.constructor.name}: "getTransactions" is not yet supported. Contact us if you need it.` + ); + } + async getInfo(): Promise { const { alias } = await this.request<{ alias: string }>( "GET", diff --git a/src/extension/background-script/router.ts b/src/extension/background-script/router.ts index 1cd1b50b4e..3a60f9898b 100644 --- a/src/extension/background-script/router.ts +++ b/src/extension/background-script/router.ts @@ -32,6 +32,7 @@ const routes = { unlock: accounts.unlock, getInfo: ln.getInfo, getInvoices: ln.invoices, + getTransactions: ln.transactions, sendPayment: ln.sendPayment, keysend: ln.keysend, checkPayment: ln.checkPayment, diff --git a/src/types.ts b/src/types.ts index e9a0796876..0bdd0e90a9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -345,6 +345,10 @@ export interface MessageInvoices extends Omit { args: { limit?: number; isSettled?: boolean }; action: "getInvoices"; } +export interface MessageTransactions extends Omit { + args: { limit?: number; isSettled?: boolean }; + action: "getTransactions"; +} export interface MessageAllowanceEnable extends MessageDefault { origin: OriginData; @@ -872,7 +876,7 @@ export type SupportedExchanges = "alby" | "coindesk" | "yadio"; export interface Invoice { id: string; memo: string; - type: "received"; + type: "received" | "sent"; settled: boolean; settleDate: number; totalAmount: string; From ef18f75e991ab3c9e295b62e0323a6c55dc79cd9 Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Tue, 3 Oct 2023 20:15:06 +0530 Subject: [PATCH 15/40] chore: some improvements --- src/app/hooks/useTransactions.ts | 29 +++++++++++++++---- .../actions/ln/transactions.ts | 21 +++++++++----- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/app/hooks/useTransactions.ts b/src/app/hooks/useTransactions.ts index 5d458aa5c4..5fe6552400 100644 --- a/src/app/hooks/useTransactions.ts +++ b/src/app/hooks/useTransactions.ts @@ -33,16 +33,33 @@ export const useTransactions = () => { }) ); - // const getalltrans = await api.getTransactions({ - // isSettled: true, - // limit, - // }); - // console.log(getalltrans); + let allTransactions = undefined; + + const getAllTransactionsResponse = await api.getTransactions({ + isSettled: true, + limit, + }); + + try { + allTransactions = getAllTransactionsResponse.transactions.map( + (transaction) => ({ + ...transaction, + title: transaction.memo, + description: transaction.memo, + date: dayjs(transaction.settleDate).fromNow(), + timestamp: transaction.settleDate, + }) + ); + } catch (e) { + console.error(e); + } const _transactions: Transaction[] = await convertPaymentsToTransactions(payments); - const transactionList: Transaction[] = [..._transactions, ...invoices]; + const transactionList: Transaction[] = allTransactions + ? allTransactions + : [..._transactions, ...invoices]; for (const transaction of transactionList) { transaction.totalAmountFiat = settings.showFiat diff --git a/src/extension/background-script/actions/ln/transactions.ts b/src/extension/background-script/actions/ln/transactions.ts index 1e07b67540..a62ac33c8b 100644 --- a/src/extension/background-script/actions/ln/transactions.ts +++ b/src/extension/background-script/actions/ln/transactions.ts @@ -8,23 +8,30 @@ const transactions = async (message: MessageTransactions) => { const connector = await state.getState().getConnector(); try { + const supportedMethods = connector.supportedMethods || []; + if (!supportedMethods.includes("getTransactions")) { + return "not supported"; + } const result = await connector.getTransactions(); - let invoices: Invoice[] = result.data.transactions - .filter((invoice) => (isSettled ? invoice.settled : !invoice.settled)) - .map((invoice) => { + + let transactions: Invoice[] = result.data.transactions + .filter((transaction) => + isSettled ? transaction.settled : !transaction.settled + ) + .map((transaction) => { const boostagram = utils.getBoostagramFromInvoiceCustomRecords( - invoice.custom_records + transaction.custom_records ); - return { ...invoice, boostagram }; + return { ...transaction, boostagram }; }); if (limit) { - invoices = invoices.slice(0, limit); + transactions = transactions.slice(0, limit); } return { data: { - invoices, + transactions, }, }; } catch (e) { From 4cd595176f66ec1ab1d1ab18d62c876b18d834a4 Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Wed, 4 Oct 2023 12:12:45 +0530 Subject: [PATCH 16/40] chore: proper error handling --- src/app/hooks/useTransactions.ts | 11 +++++------ .../background-script/actions/ln/transactions.ts | 4 ---- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/app/hooks/useTransactions.ts b/src/app/hooks/useTransactions.ts index 5fe6552400..c7c412ed43 100644 --- a/src/app/hooks/useTransactions.ts +++ b/src/app/hooks/useTransactions.ts @@ -33,14 +33,13 @@ export const useTransactions = () => { }) ); - let allTransactions = undefined; - - const getAllTransactionsResponse = await api.getTransactions({ - isSettled: true, - limit, - }); + let allTransactions; try { + const getAllTransactionsResponse = await api.getTransactions({ + isSettled: true, + limit, + }); allTransactions = getAllTransactionsResponse.transactions.map( (transaction) => ({ ...transaction, diff --git a/src/extension/background-script/actions/ln/transactions.ts b/src/extension/background-script/actions/ln/transactions.ts index a62ac33c8b..6194643a98 100644 --- a/src/extension/background-script/actions/ln/transactions.ts +++ b/src/extension/background-script/actions/ln/transactions.ts @@ -8,10 +8,6 @@ const transactions = async (message: MessageTransactions) => { const connector = await state.getState().getConnector(); try { - const supportedMethods = connector.supportedMethods || []; - if (!supportedMethods.includes("getTransactions")) { - return "not supported"; - } const result = await connector.getTransactions(); let transactions: Invoice[] = result.data.transactions From fa27b14ad0a2ebf5e80e1d73618f6a56d8a7caa6 Mon Sep 17 00:00:00 2001 From: pavanjoshi914 Date: Wed, 4 Oct 2023 12:39:15 +0530 Subject: [PATCH 17/40] feat: add strokes to the icons --- .../components/TransactionsTable/TransactionModal.tsx | 10 ++++++---- src/app/components/TransactionsTable/index.tsx | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/app/components/TransactionsTable/TransactionModal.tsx b/src/app/components/TransactionsTable/TransactionModal.tsx index 27e95685ac..20d786a01d 100644 --- a/src/app/components/TransactionsTable/TransactionModal.tsx +++ b/src/app/components/TransactionsTable/TransactionModal.tsx @@ -1,9 +1,11 @@ import { - ArrowDownIcon, - ArrowUpIcon, CaretDownIcon, CaretUpIcon, } from "@bitcoin-design/bitcoin-icons-react/filled"; +import { + ArrowDownIcon, + ArrowUpIcon, +} from "@bitcoin-design/bitcoin-icons-react/outline"; import dayjs from "dayjs"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -61,11 +63,11 @@ export default function TransactionModal({
{getTransactionType(transaction) == "outgoing" ? (
- +
) : (
- +
)}
diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index 3433645048..5137f9beb4 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -1,7 +1,7 @@ import { ArrowDownIcon, ArrowUpIcon, -} from "@bitcoin-design/bitcoin-icons-react/filled"; +} from "@bitcoin-design/bitcoin-icons-react/outline"; import Loading from "@components/Loading"; import { useState } from "react"; @@ -59,11 +59,11 @@ export default function TransactionsTable({
{type == "outgoing" ? (
- +
) : (
- +
)}
From f5dd239d5ddcec783673d470c058c5a1c06fbbe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Aaron?= Date: Wed, 4 Oct 2023 14:05:02 +0200 Subject: [PATCH 18/40] fix: style improvements --- src/app/components/Modal/index.tsx | 9 +- .../TransactionsTable/TransactionModal.tsx | 200 +++++++++--------- .../components/TransactionsTable/index.tsx | 2 +- src/app/screens/Home/DefaultView/index.tsx | 28 ++- src/i18n/locales/en/translation.json | 4 +- 5 files changed, 123 insertions(+), 120 deletions(-) diff --git a/src/app/components/Modal/index.tsx b/src/app/components/Modal/index.tsx index 9dfbded91a..bcc94b42c1 100644 --- a/src/app/components/Modal/index.tsx +++ b/src/app/components/Modal/index.tsx @@ -1,3 +1,4 @@ +import { CrossIcon } from "@bitcoin-design/bitcoin-icons-react/filled"; import ReactModal from "react-modal"; type Props = { @@ -21,9 +22,15 @@ export default function Modal({ onRequestClose={closeModal} contentLabel={title} overlayClassName="bg-black bg-opacity-50 fixed inset-0 flex justify-center items-center p-5" - className="rounded-lg bg-white dark:bg-surface-02dp w-full max-w-md overflow-hidden" + className="rounded-lg bg-white dark:bg-surface-02dp w-full max-w-md overflow-hidden relative px-4 pt-10 pb-6" style={{ content: { maxHeight: "90vh" } }} > + {children} ); diff --git a/src/app/components/TransactionsTable/TransactionModal.tsx b/src/app/components/TransactionsTable/TransactionModal.tsx index 20d786a01d..2c0b37d02a 100644 --- a/src/app/components/TransactionsTable/TransactionModal.tsx +++ b/src/app/components/TransactionsTable/TransactionModal.tsx @@ -21,6 +21,31 @@ type Props = { isOpen: boolean; }; +const Dt = ({ children }: { children: React.ReactNode }) => ( +
+ {children} +
+); + +const Dd = ({ children }: { children: React.ReactNode }) => ( +
+ {children} +
+); + +const TransactionDetailRow = ({ + title, + content, +}: { + title: React.ReactNode; + content: React.ReactNode; +}) => ( +
+
{title}
+
{content}
+
+); + export default function TransactionModal({ transaction, isOpen, @@ -97,111 +122,78 @@ export default function TransactionModal({ )}
-
-
-
-
-
-
- Date & Time -
-
- {dayjs(transaction.timestamp).format( - "D MMMM YYYY, HH:mm" - )} -
-
- {transaction.totalFees?.toString && ( -
-
- Fee -
-
- {getFormattedSats(transaction.totalFees)} -
-
- )} - {transaction.publisherLink && transaction.title && ( -
-
- Website -
-
- - {transaction.title} - -
-
- )} - - {transaction.boostagram?.podcast && ( -
-
- Podcast -
-
- {transaction.boostagram?.podcast} -
-
- )} - {transaction.boostagram?.episode && ( -
-
- Episode -
-
- {transaction.boostagram.episode} -
-
- )} - {transaction.description && ( -
-
- Description -
-
- {transaction.description} -
-
- )} -
- - {tCommon("actions.more")}{" "} - {showMoreFields ? ( - - ) : ( - - )} - -
- {showMoreFields && transaction.type == "sent" && ( -
-
- Preimage -
-
- {transaction.preimage} -
-
- )} - {showMoreFields && transaction.type == "sent" && ( -
-
- Hash -
-
- {transaction.paymentHash} -
-
- )} -
-
+ {/* List */} +
+ + {transaction.totalFees?.toString && ( + + )} + {transaction.publisherLink && transaction.title && ( + + {transaction.title} + + } + /> + )} + {transaction.boostagram?.podcast && ( + + )} + {transaction.boostagram?.episode && ( + + )} + {transaction.description && ( + + )} +
+ + {tCommon("actions.more")}{" "} + {showMoreFields ? ( + + ) : ( + + )} +
+ {showMoreFields && ( + <> + {transaction.preimage && ( + + )} + {transaction.paymentHash && ( + + )} + + )}
)} diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index 5137f9beb4..35b0f5b2ca 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -78,7 +78,7 @@ export default function TransactionsTable({ (type == "incoming" ? "Received" : "Sent")}

-

+

{tx.date}

diff --git a/src/app/screens/Home/DefaultView/index.tsx b/src/app/screens/Home/DefaultView/index.tsx index 48b97f537d..cf92fb50d3 100644 --- a/src/app/screens/Home/DefaultView/index.tsx +++ b/src/app/screens/Home/DefaultView/index.tsx @@ -1,9 +1,9 @@ import { + ArrowRightIcon, ReceiveIcon, SendIcon, } from "@bitcoin-design/bitcoin-icons-react/filled"; import Button from "@components/Button"; -import Hyperlink from "@components/Hyperlink"; import Loading from "@components/Loading"; import TransactionsTable from "@components/TransactionsTable"; import dayjs from "dayjs"; @@ -12,6 +12,7 @@ import { FC, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import BalanceBox from "~/app/components/BalanceBox"; +import Hyperlink from "~/app/components/Hyperlink"; import SkeletonLoader from "~/app/components/SkeletonLoader"; import toast from "~/app/components/Toast"; import { useAccount } from "~/app/context/AccountContext"; @@ -171,22 +172,27 @@ const DefaultView: FC = (props) => { {!isLoading && (
-

- {t("default_view.latest_transactions")} -

+
+

+ {t("default_view.latest_transactions")} +

+ + {!isLoading && transactions.length > 0 && ( + handleViewAllLink("/transactions")} + className="flex justify-between items-center" + > + {t("default_view.see_all")} + + + )} +
- {!isLoading && transactions.length > 0 && ( -
- handleViewAllLink("/transactions")}> - {t("default_view.all_transactions_link")} - -
- )}
)}
diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index d46bc544cf..b694216125 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -367,8 +367,7 @@ "is_blocked_hint": "Alby is currently disabled on {{host}}", "block_removed": "Enabled {{host}}. Please reload the website.", "no_transactions": "No transactions for this account yet.", - - "all_transactions_link": "See all transactions" + "see_all": "See all" } }, "accounts": { @@ -954,7 +953,6 @@ "transactions": { "title": "Transactions", "description": "Transactions for this account", - "list_empty": "No transactions available yet." }, "onboard": { From 7688615bc02c89e6114685017759e31274a29a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Aaron?= Date: Mon, 9 Oct 2023 11:01:32 +0200 Subject: [PATCH 19/40] fix: spacing improvements --- .../TransactionsTable/TransactionModal.tsx | 51 ++++++++++--------- .../components/TransactionsTable/index.tsx | 11 ++-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/app/components/TransactionsTable/TransactionModal.tsx b/src/app/components/TransactionsTable/TransactionModal.tsx index 2c0b37d02a..7c34e26696 100644 --- a/src/app/components/TransactionsTable/TransactionModal.tsx +++ b/src/app/components/TransactionsTable/TransactionModal.tsx @@ -116,13 +116,12 @@ export default function TransactionModal({

{!!transaction.totalAmountFiat && ( -

+

~{transaction.totalAmountFiat}

)}
- {/* List */}
)} -
- - {tCommon("actions.more")}{" "} - {showMoreFields ? ( - - ) : ( - - )} - -
- {showMoreFields && ( + {(transaction.preimage || transaction.paymentHash) && ( <> - {transaction.preimage && ( - - )} - {transaction.paymentHash && ( - +
+ + {tCommon("actions.more")}{" "} + {showMoreFields ? ( + + ) : ( + + )} + +
+ {showMoreFields && ( + <> + {transaction.preimage && ( + + )} + {transaction.paymentHash && ( + + )} + )} )} diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index 35b0f5b2ca..05d88a3856 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -55,23 +55,20 @@ export default function TransactionsTable({ className="px-3 py-2 hover:bg-gray-100 dark:hover:bg-surface-02dp cursor-pointer rounded-md" onClick={() => openDetails(tx)} > -
+
{type == "outgoing" ? (
- +
) : (
- +
)}
-
+

{tx.title || tx.boostagram?.message || From 4a1eed451631515eeed84d80b81a384f742cda29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Aaron?= Date: Wed, 11 Oct 2023 14:20:50 +0200 Subject: [PATCH 20/40] fix: translations & layout improvements --- src/app/components/Modal/index.tsx | 5 +- .../TransactionsTable/TransactionModal.tsx | 55 +++++++++++-------- .../components/TransactionsTable/index.tsx | 6 +- src/i18n/locales/cs/translation.json | 2 +- src/i18n/locales/da/translation.json | 2 +- src/i18n/locales/de/translation.json | 2 +- src/i18n/locales/en/translation.json | 11 ++-- src/i18n/locales/eo/translation.json | 2 +- src/i18n/locales/es/translation.json | 2 +- src/i18n/locales/fa/translation.json | 2 +- src/i18n/locales/fi/translation.json | 2 +- src/i18n/locales/fr/translation.json | 2 +- src/i18n/locales/hi/translation.json | 2 +- src/i18n/locales/id/translation.json | 2 +- src/i18n/locales/it/translation.json | 2 +- src/i18n/locales/mr/translation.json | 2 +- src/i18n/locales/nl/translation.json | 2 +- src/i18n/locales/pl/translation.json | 2 +- src/i18n/locales/pt_BR/translation.json | 2 +- src/i18n/locales/ro/translation.json | 2 +- src/i18n/locales/ru/translation.json | 2 +- src/i18n/locales/sv/translation.json | 2 +- src/i18n/locales/th/translation.json | 2 +- src/i18n/locales/tl/translation.json | 2 +- src/i18n/locales/uk/translation.json | 2 +- src/i18n/locales/zh_Hans/translation.json | 2 +- src/i18n/locales/zh_Hant/translation.json | 2 +- 27 files changed, 67 insertions(+), 56 deletions(-) diff --git a/src/app/components/Modal/index.tsx b/src/app/components/Modal/index.tsx index bcc94b42c1..8abacc74cb 100644 --- a/src/app/components/Modal/index.tsx +++ b/src/app/components/Modal/index.tsx @@ -18,11 +18,12 @@ export default function Modal({

@@ -107,8 +110,7 @@ export default function TransactionModal({ "text-3xl font-medium", transaction.type == "received" ? "text-green-600 dark:color-green-400" - : "text-orange-600 dark:color-orange-400", - "inline" + : "text-orange-600 dark:color-orange-400" )} > {transaction.type == "sent" ? "-" : "+"}{" "} @@ -137,15 +139,17 @@ export default function TransactionModal({ )} {transaction.publisherLink && transaction.title && ( - {transaction.title} - + <> + + {transaction.title} + + } /> )} @@ -171,29 +175,34 @@ export default function TransactionModal({ <>
- {tCommon("actions.more")}{" "} {showMoreFields ? ( - + <> + {tCommon("actions.hide")} + + ) : ( - + <> + {tCommon("actions.more")} + + )}
{showMoreFields && ( - <> +
{transaction.preimage && ( )} {transaction.paymentHash && ( )} - +
)} )} diff --git a/src/app/components/TransactionsTable/index.tsx b/src/app/components/TransactionsTable/index.tsx index 05d88a3856..9ccad8cc6b 100644 --- a/src/app/components/TransactionsTable/index.tsx +++ b/src/app/components/TransactionsTable/index.tsx @@ -5,6 +5,7 @@ import { import Loading from "@components/Loading"; import { useState } from "react"; +import { useTranslation } from "react-i18next"; import TransactionModal from "~/app/components/TransactionsTable/TransactionModal"; import { useSettings } from "~/app/context/SettingsContext"; @@ -25,6 +26,9 @@ export default function TransactionsTable({ const { getFormattedSats } = useSettings(); const [modalOpen, setModalOpen] = useState(false); const [transaction, setTransaction] = useState(); + const { t } = useTranslation("components", { + keyPrefix: "transactions_table", + }); function openDetails(transaction: Transaction) { setTransaction(transaction); @@ -72,7 +76,7 @@ export default function TransactionsTable({

{tx.title || tx.boostagram?.message || - (type == "incoming" ? "Received" : "Sent")} + (type == "incoming" ? t("received") : t("sent"))}

diff --git a/src/i18n/locales/cs/translation.json b/src/i18n/locales/cs/translation.json index 7486600627..8e5b84d8e4 100644 --- a/src/i18n/locales/cs/translation.json +++ b/src/i18n/locales/cs/translation.json @@ -820,7 +820,7 @@ "allow_camera_access": "Prosím povolte přístup kamery ve svém nastavení." } }, - "transactionsTable": { + "transactions_table": { "fee": "Poplatek", "preimage": "Preimage", "received": "Přijato", diff --git a/src/i18n/locales/da/translation.json b/src/i18n/locales/da/translation.json index fdfb7d51f4..3292b3ed4e 100644 --- a/src/i18n/locales/da/translation.json +++ b/src/i18n/locales/da/translation.json @@ -727,7 +727,7 @@ "allow_camera_access": "Giv adgang til kameraet i indstillingsvinduet." } }, - "transactionsTable": { + "transactions_table": { "fee": "Betaling", "preimage": "Præ-visning", "received": "Modtaget", diff --git a/src/i18n/locales/de/translation.json b/src/i18n/locales/de/translation.json index 66aa0f0fab..6fe4747a04 100644 --- a/src/i18n/locales/de/translation.json +++ b/src/i18n/locales/de/translation.json @@ -1038,7 +1038,7 @@ }, "title": "QR Code scannen" }, - "transactionsTable": { + "transactions_table": { "sent": "Gesendet", "boostagram": { "sender": "Sender", diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index b694216125..7eddc7024b 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -992,6 +992,7 @@ "help": "Help", "balance": "Balance", "or": "or", + "website": "Website", "actions": { "back": "Back", "delete": "Delete", @@ -1022,6 +1023,7 @@ "log_in": "Log in", "remember": "Remember my choice and don't ask again", "more": "More", + "hide": "Hide", "disconnect": "Disconnect", "review": "Review", "download": "Download" @@ -1083,9 +1085,10 @@ "allow_camera_access": "Please allow camera access in the settings screen." } }, - "transactionsTable": { + "transactions_table": { "fee": "Fee", "preimage": "Preimage", + "payment_hash": "Payment hash", "received": "Received", "sent": "Sent", "boostagram": { @@ -1096,12 +1099,6 @@ }, "open_location": "Open website" }, - "transaction_list": { - "tabs": { - "outgoing": "Outgoing", - "incoming": "Incoming" - } - }, "budget_control": { "remember": { "label": "Remember and set a budget", diff --git a/src/i18n/locales/eo/translation.json b/src/i18n/locales/eo/translation.json index d5bd956a6b..40c2e3fa67 100644 --- a/src/i18n/locales/eo/translation.json +++ b/src/i18n/locales/eo/translation.json @@ -578,7 +578,7 @@ "allow_camera_access": "" } }, - "transactionsTable": { + "transactions_table": { "fee": "Kotizo", "preimage": "", "received": "Ricevita", diff --git a/src/i18n/locales/es/translation.json b/src/i18n/locales/es/translation.json index 11540fcc32..f2dfa5c068 100644 --- a/src/i18n/locales/es/translation.json +++ b/src/i18n/locales/es/translation.json @@ -820,7 +820,7 @@ "allow_camera_access": "Permita el acceso a la cámara en la pantalla de configuración." } }, - "transactionsTable": { + "transactions_table": { "fee": "Comisión", "preimage": "Preimagen", "received": "Recibido", diff --git a/src/i18n/locales/fa/translation.json b/src/i18n/locales/fa/translation.json index 85ca212d69..3249888f96 100644 --- a/src/i18n/locales/fa/translation.json +++ b/src/i18n/locales/fa/translation.json @@ -1027,7 +1027,7 @@ "allow_camera_access": "لطفا در صفحه تنظیمات اجازه دسترسی به دوربین بدهید." } }, - "transactionsTable": { + "transactions_table": { "fee": "کارمزد", "preimage": "پیش نمایش", "received": "دریافت شد", diff --git a/src/i18n/locales/fi/translation.json b/src/i18n/locales/fi/translation.json index 2b6260f413..89c2af1063 100644 --- a/src/i18n/locales/fi/translation.json +++ b/src/i18n/locales/fi/translation.json @@ -573,7 +573,7 @@ "allow_camera_access": "Salli kameran käyttöoikeus asetusruudussa." } }, - "transactionsTable": { + "transactions_table": { "fee": "Kustannus", "preimage": "Esikuva", "received": "Vastaanotettu", diff --git a/src/i18n/locales/fr/translation.json b/src/i18n/locales/fr/translation.json index 004ca43e9b..6f5b62ef6b 100644 --- a/src/i18n/locales/fr/translation.json +++ b/src/i18n/locales/fr/translation.json @@ -733,7 +733,7 @@ "allow_camera_access": "Veuillez autoriser l'accès à la caméra dans l'écran des paramètres." } }, - "transactionsTable": { + "transactions_table": { "fee": "Frais", "preimage": "Préimage", "received": "Reçu", diff --git a/src/i18n/locales/hi/translation.json b/src/i18n/locales/hi/translation.json index 71ac701ec1..2356a6d5f5 100644 --- a/src/i18n/locales/hi/translation.json +++ b/src/i18n/locales/hi/translation.json @@ -691,7 +691,7 @@ "allow_camera_access": "कृपया सेटिंग स्क्रीन में कैमरा एक्सेस की अनुमति दें।" } }, - "transactionsTable": { + "transactions_table": { "fee": "शुल्क", "preimage": "Preimage", "received": "प्राप्त", diff --git a/src/i18n/locales/id/translation.json b/src/i18n/locales/id/translation.json index 8a95cbc789..d96cce801b 100644 --- a/src/i18n/locales/id/translation.json +++ b/src/i18n/locales/id/translation.json @@ -852,7 +852,7 @@ "screen_reader": "Toggle Dropdown", "title": "Ganti akun" }, - "transactionsTable": { + "transactions_table": { "sent": "Terkirim", "fee": "Biaya", "preimage": "Preimage", diff --git a/src/i18n/locales/it/translation.json b/src/i18n/locales/it/translation.json index d4d722c713..f2cc046c1c 100644 --- a/src/i18n/locales/it/translation.json +++ b/src/i18n/locales/it/translation.json @@ -727,7 +727,7 @@ "allow_camera_access": "Si prega di consentire l'accesso alla fotocamera nella schermata delle impostazioni." } }, - "transactionsTable": { + "transactions_table": { "fee": "Tassa", "preimage": "Preimmagine", "received": "Ricevuto", diff --git a/src/i18n/locales/mr/translation.json b/src/i18n/locales/mr/translation.json index 207bedbd2a..6204900062 100644 --- a/src/i18n/locales/mr/translation.json +++ b/src/i18n/locales/mr/translation.json @@ -754,7 +754,7 @@ "allow_camera_access": "कृपया सेटिंग्ज स्क्रीनमध्ये कॅमेरा प्रवेशास अनुमती द्या." } }, - "transactionsTable": { + "transactions_table": { "fee": "शुल्क", "preimage": "प्रीइमेज", "received": "प्राप्त", diff --git a/src/i18n/locales/nl/translation.json b/src/i18n/locales/nl/translation.json index 91d48859d3..343ef6ba74 100644 --- a/src/i18n/locales/nl/translation.json +++ b/src/i18n/locales/nl/translation.json @@ -587,7 +587,7 @@ "allow_camera_access": "" } }, - "transactionsTable": { + "transactions_table": { "fee": "", "preimage": "", "received": "", diff --git a/src/i18n/locales/pl/translation.json b/src/i18n/locales/pl/translation.json index 9813fa851a..6c0ab5e4a8 100644 --- a/src/i18n/locales/pl/translation.json +++ b/src/i18n/locales/pl/translation.json @@ -781,7 +781,7 @@ "allow_camera_access": "Proszę pozwolić na dostęp do kamery w ekranie ustawień." } }, - "transactionsTable": { + "transactions_table": { "fee": "Opłata", "preimage": "Obraz pierwotny (preimage)", "received": "Otrzymano", diff --git a/src/i18n/locales/pt_BR/translation.json b/src/i18n/locales/pt_BR/translation.json index 77e489b4bf..58ff7b081e 100644 --- a/src/i18n/locales/pt_BR/translation.json +++ b/src/i18n/locales/pt_BR/translation.json @@ -1058,7 +1058,7 @@ "allow_camera_access": "Permita o acesso à câmera na tela configurações." } }, - "transactionsTable": { + "transactions_table": { "fee": "Taxa", "preimage": "Pré-imagem", "received": "Recebida", diff --git a/src/i18n/locales/ro/translation.json b/src/i18n/locales/ro/translation.json index 9872ce37c0..0b985bb76d 100644 --- a/src/i18n/locales/ro/translation.json +++ b/src/i18n/locales/ro/translation.json @@ -727,7 +727,7 @@ "allow_camera_access": "" } }, - "transactionsTable": { + "transactions_table": { "fee": "", "preimage": "", "received": "", diff --git a/src/i18n/locales/ru/translation.json b/src/i18n/locales/ru/translation.json index 6914e56e98..05b051fa72 100644 --- a/src/i18n/locales/ru/translation.json +++ b/src/i18n/locales/ru/translation.json @@ -727,7 +727,7 @@ "allow_camera_access": "" } }, - "transactionsTable": { + "transactions_table": { "fee": "", "preimage": "", "received": "", diff --git a/src/i18n/locales/sv/translation.json b/src/i18n/locales/sv/translation.json index a48c8e6531..e36a8bfa81 100644 --- a/src/i18n/locales/sv/translation.json +++ b/src/i18n/locales/sv/translation.json @@ -1040,7 +1040,7 @@ "allow_camera_access": "Tillåt kameraåtkomst under inställningar." } }, - "transactionsTable": { + "transactions_table": { "fee": "Avgift", "preimage": "Förhandsvy", "received": "Mottaget", diff --git a/src/i18n/locales/th/translation.json b/src/i18n/locales/th/translation.json index 0101d9009d..07295e3fd9 100644 --- a/src/i18n/locales/th/translation.json +++ b/src/i18n/locales/th/translation.json @@ -1120,7 +1120,7 @@ "invalid_credentials": "รหัสผ่านไม่ถูกต้อง โปรดเช็ครหัสผ่านและอีเมลของคุณ และลองอีกครั้ง" } }, - "transactionsTable": { + "transactions_table": { "fee": "ค่าทำเนียม", "preimage": "Preimage", "received": "ได้รับ", diff --git a/src/i18n/locales/tl/translation.json b/src/i18n/locales/tl/translation.json index 53b3b8bae4..5e2d11fa43 100644 --- a/src/i18n/locales/tl/translation.json +++ b/src/i18n/locales/tl/translation.json @@ -524,7 +524,7 @@ "allow_camera_access": "" } }, - "transactionsTable": { + "transactions_table": { "fee": "", "preimage": "", "received": "", diff --git a/src/i18n/locales/uk/translation.json b/src/i18n/locales/uk/translation.json index 3a7291508c..e8ad7f7bd1 100644 --- a/src/i18n/locales/uk/translation.json +++ b/src/i18n/locales/uk/translation.json @@ -727,7 +727,7 @@ "allow_camera_access": "" } }, - "transactionsTable": { + "transactions_table": { "fee": "", "preimage": "", "received": "", diff --git a/src/i18n/locales/zh_Hans/translation.json b/src/i18n/locales/zh_Hans/translation.json index 7cb616e30b..5380ff824d 100644 --- a/src/i18n/locales/zh_Hans/translation.json +++ b/src/i18n/locales/zh_Hans/translation.json @@ -1037,7 +1037,7 @@ }, "edit_permissions": "编辑权限" }, - "transactionsTable": { + "transactions_table": { "boostagram": { "podcast": "播客", "message": "消息", diff --git a/src/i18n/locales/zh_Hant/translation.json b/src/i18n/locales/zh_Hant/translation.json index 3e811613e1..471a6fd7a3 100644 --- a/src/i18n/locales/zh_Hant/translation.json +++ b/src/i18n/locales/zh_Hant/translation.json @@ -1024,7 +1024,7 @@ "allow_camera_access": "請在設置屏幕中允許攝像頭訪問。" } }, - "transactionsTable": { + "transactions_table": { "fee": "費用", "preimage": "原像", "received": "已收到", From db98c003f2fe8df53f584e5e78242606ef4502ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Aaron?= Date: Wed, 11 Oct 2023 14:24:32 +0200 Subject: [PATCH 21/40] fix: translations --- .../components/TransactionsTable/TransactionModal.tsx | 10 +++++----- src/i18n/locales/en/translation.json | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/app/components/TransactionsTable/TransactionModal.tsx b/src/app/components/TransactionsTable/TransactionModal.tsx index 1689ed587d..82da54a5fa 100644 --- a/src/app/components/TransactionsTable/TransactionModal.tsx +++ b/src/app/components/TransactionsTable/TransactionModal.tsx @@ -126,14 +126,14 @@ export default function TransactionModal({

{transaction.totalFees?.toString && ( )} @@ -155,19 +155,19 @@ export default function TransactionModal({ )} {transaction.boostagram?.podcast && ( )} {transaction.boostagram?.episode && ( )} {transaction.description && ( )} diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index 7eddc7024b..45c9a64b38 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -1091,11 +1091,13 @@ "payment_hash": "Payment hash", "received": "Received", "sent": "Sent", + "date_time": "Date & Time", "boostagram": { "sender": "Sender", "message": "Message", "app": "App", - "podcast": "Podcast" + "podcast": "Podcast", + "episode": "Episode" }, "open_location": "Open website" }, From ce6fdadd8821ee9bfe275fe8d5834c6610382bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Aaron?= Date: Wed, 11 Oct 2023 16:13:58 +0200 Subject: [PATCH 22/40] fix: modal usage, remove headings --- src/app/components/Modal/index.tsx | 14 +- src/app/components/SitePreferences/index.tsx | 136 ++++++++---------- .../TransactionsTable/TransactionModal.tsx | 2 +- src/app/screens/Accounts/Detail/index.tsx | 57 ++++---- src/app/screens/Home/AllowanceView/index.tsx | 3 - src/app/screens/Home/DefaultView/index.tsx | 28 ++-- src/app/screens/Publishers/Detail/index.tsx | 41 +++--- src/app/screens/Settings/index.tsx | 27 ++-- src/i18n/locales/en/translation.json | 3 - 9 files changed, 133 insertions(+), 178 deletions(-) diff --git a/src/app/components/Modal/index.tsx b/src/app/components/Modal/index.tsx index 8abacc74cb..827a198d19 100644 --- a/src/app/components/Modal/index.tsx +++ b/src/app/components/Modal/index.tsx @@ -5,14 +5,15 @@ type Props = { children?: React.ReactNode; isOpen: boolean; close: () => void; - title: string; + contentLabel: string; + title?: string; }; export default function Modal({ children, isOpen, close: closeModal, - title, + contentLabel: title, }: Props) { return ( + {title && ( +

{title}

+ )} diff --git a/src/app/components/SitePreferences/index.tsx b/src/app/components/SitePreferences/index.tsx index 23f7c0f2f4..d52fd4c39b 100644 --- a/src/app/components/SitePreferences/index.tsx +++ b/src/app/components/SitePreferences/index.tsx @@ -1,4 +1,3 @@ -import { CrossIcon } from "@bitcoin-design/bitcoin-icons-react/outline"; import Button from "@components/Button"; import Hyperlink from "@components/Hyperlink"; import Setting from "@components/Setting"; @@ -179,95 +178,82 @@ function SitePreferences({ launcherType, allowance, onEdit, onDelete }: Props) { -
-

- {t("edit_allowance.title")} -

- -
-
{ e.preventDefault(); updateAllowance(); }} > -
-
- setBudget(e.target.value)} +
+ setBudget(e.target.value)} + /> +
+
+ + setLnurlAuth(!lnurlAuth)} /> -
-
- - setLnurlAuth(!lnurlAuth)} - /> - -
+ +
- {hasPermissions && ( + {hasPermissions && ( +
+

+ {t("edit_permissions")} +

-

- {t("edit_permissions")} -

-
- {permissions.map((permission) => ( - - ( + + lnd.getinfo nostr/nip04decrypt --> nostr.nip04decrypt */ - > - { - setPermissions( - permissions.map((prm) => - prm.id === permission.id - ? { ...prm, enabled: !prm.enabled } - : prm - ) - ); - }} - /> - - - ))} -
+ > + { + setPermissions( + permissions.map((prm) => + prm.id === permission.id + ? { ...prm, enabled: !prm.enabled } + : prm + ) + ); + }} + /> + + + ))}
- )} -
+
+ )} -
+
{ if (window.confirm(t("confirm_delete"))) { diff --git a/src/app/components/TransactionsTable/TransactionModal.tsx b/src/app/components/TransactionsTable/TransactionModal.tsx index 82da54a5fa..74a0594e02 100644 --- a/src/app/components/TransactionsTable/TransactionModal.tsx +++ b/src/app/components/TransactionsTable/TransactionModal.tsx @@ -83,7 +83,7 @@ export default function TransactionModal({ onModelClose(); setShowMoreFields(false); }} - title={"Transactions"} + contentLabel={"Transactions"} > {_isRevealed && transaction && (
diff --git a/src/app/screens/Accounts/Detail/index.tsx b/src/app/screens/Accounts/Detail/index.tsx index dc3fc7b193..4c39581b60 100644 --- a/src/app/screens/Accounts/Detail/index.tsx +++ b/src/app/screens/Accounts/Detail/index.tsx @@ -1,4 +1,3 @@ -import { CrossIcon } from "@bitcoin-design/bitcoin-icons-react/filled"; import Button from "@components/Button"; import Container from "@components/Container"; import Loading from "@components/Loading"; @@ -264,50 +263,42 @@ function AccountDetail() { -
-

- {t("export.title")} -

- -
- {exportLoading && ( -
+
{t("export.waiting")}
)} {!exportLoading && ( -
-
-

{t("export.scan_qr")}

+
+

{t("export.scan_qr")}

+
-
- -
- {lndHubData.lnAddress && ( -
-

- {t("export.your_ln_address")} -

- {lndHubData.lnAddress && ( -

{lndHubData.lnAddress}

- )} -
- )}
+
+ +
+ {lndHubData.lnAddress && ( +
+

+ {t("export.your_ln_address")} +

+ {lndHubData.lnAddress && ( +

{lndHubData.lnAddress}

+ )} +
+ )}
)} diff --git a/src/app/screens/Home/AllowanceView/index.tsx b/src/app/screens/Home/AllowanceView/index.tsx index d91187dcf6..7f454498ae 100644 --- a/src/app/screens/Home/AllowanceView/index.tsx +++ b/src/app/screens/Home/AllowanceView/index.tsx @@ -139,9 +139,6 @@ const AllowanceView: FC = (props) => { />
)} -

- {t("allowance_view.latest_transactions")} -

{isLoadingTransactions && (
diff --git a/src/app/screens/Home/DefaultView/index.tsx b/src/app/screens/Home/DefaultView/index.tsx index cf92fb50d3..7a303d0f2e 100644 --- a/src/app/screens/Home/DefaultView/index.tsx +++ b/src/app/screens/Home/DefaultView/index.tsx @@ -126,7 +126,7 @@ const DefaultView: FC = (props) => {
)} -
+
diff --git a/src/app/screens/Publishers/Detail/index.tsx b/src/app/screens/Publishers/Detail/index.tsx index a02dbe2851..c0909df09e 100644 --- a/src/app/screens/Publishers/Detail/index.tsx +++ b/src/app/screens/Publishers/Detail/index.tsx @@ -64,34 +64,29 @@ function PublisherDetail() { }, [fetchData, isLoadingSettings]); return ( -
-
- {allowance && ( - { - navigate("/publishers", { replace: true }); - }} - title={allowance?.name || ""} - image={allowance?.imageURL || ""} - url={allowance?.host} - isCard={false} - isSmall={false} - /> - )} -
+ <> + {allowance && ( + { + navigate("/publishers", { replace: true }); + }} + title={allowance?.name || ""} + image={allowance?.imageURL || ""} + url={allowance?.host} + isCard={false} + isSmall={false} + /> + )} {allowance && ( -
-

- {t("allowance_view.latest_transactions")} -

+
{transactions && transactions?.length > 0 ? ( ) : ( -

+

)} -

+ ); } diff --git a/src/app/screens/Settings/index.tsx b/src/app/screens/Settings/index.tsx index 291ac9eb06..680f5c0242 100644 --- a/src/app/screens/Settings/index.tsx +++ b/src/app/screens/Settings/index.tsx @@ -1,4 +1,3 @@ -import { CrossIcon } from "@bitcoin-design/bitcoin-icons-react/outline"; import Button from "@components/Button"; import Container from "@components/Container"; import LocaleSwitcher from "@components/LocaleSwitcher/LocaleSwitcher"; @@ -295,32 +294,22 @@ function Settings() { -
-

- {t("change_password.title")} -

- -
- { e.preventDefault(); updateAccountPassword(formData.password); }} > -
- -
+ -
+