Skip to content

Commit

Permalink
Merge branch 'master' into feature/commando-connector
Browse files Browse the repository at this point in the history
# By Lisa Oppermann (15) and others
# Via GitHub (22) and others
* master: (57 commits)
  fix: publisher link on AllowanceView
  Translated using Weblate (Italian)
  Update all development Yarn dependencies (2022-10-29)
  fix: align reject/close function params
  fix: navigate on send
  Update dayjs to version 1.11.6
  fix: disable input fields on Create Invoice #1659 (#1668)
  Update react-i18next to version 12.0.0
  Push buttons to bottom in Send and Receive Screens (#1672)
  refactor(lnurl): getDetails - avoid typecasting (#1545)
  style: prettier
  Translated using Weblate (Italian)
  Update tailwindcss to version 3.2.1
  style: prettier
  Translated using Weblate (Portuguese (Brazil))
  style: prettier
  Translated using Weblate (Italian)
  Translated using Weblate (Swedish)
  fix: remove response and additional error message
  fix: use math floor everywhere
  ...

# Conflicts:
#	yarn.lock
  • Loading branch information
bumi committed Nov 1, 2022
2 parents 34c29aa + 76d6061 commit 3651846
Show file tree
Hide file tree
Showing 55 changed files with 2,688 additions and 744 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ Also we focus on supporting multiple different node backends (non-custodial and

#### What is WebLN?

WebLN is a library and set of specifications for lightning apps and client providers to facilitate communication between apps and users' lightning nodes in a secure way. It provides a programmatic, permissioned interface for letting applications ask users to send payments, generate invoices to receive payments, and much more. [This documentation](https://webln.dev/#/) covers how to use WebLN in your Lightning-driven applications.
WebLN is a library and set of specifications for lightning apps and client providers to facilitate communication between apps and users' lightning nodes in a secure way. It provides a programmatic, permissioned interface for letting applications ask users to send payments, generate invoices to receive payments, and much more. [This documentation](https://webln.guide/) covers how to use WebLN in your Lightning-driven applications.

#### Is there a bounty program and can I contribute?

Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"browser-polyfill": "^3.20.2",
"crypto-browserify": "^3.12.0",
"crypto-js": "^4.1.1",
"dayjs": "^1.11.5",
"dayjs": "^1.11.6",
"dexie": "^3.2.2",
"elliptic": "^6.5.4",
"html5-qrcode": "^2.2.3",
Expand All @@ -61,22 +61,22 @@
"react": "^18.2.0",
"react-confetti": "^6.1.0",
"react-dom": "^18.2.0",
"react-i18next": "^11.18.6",
"react-i18next": "^12.0.0",
"react-loading-skeleton": "^3.1.0",
"react-modal": "^3.15.1",
"react-modal": "^3.16.1",
"react-qr-code": "^2.0.8",
"react-router-dom": "^6.4.2",
"react-toastify": "^9.0.8",
"stream": "^0.0.2",
"tailwindcss": "^3.1.8",
"tailwindcss": "^3.2.1",
"uuid": "^9.0.0",
"webextension-polyfill": "^0.10.0",
"zustand": "^3.7.2"
},
"devDependencies": {
"@commitlint/cli": "^17.1.2",
"@commitlint/config-conventional": "^17.1.0",
"@jest/types": "^29.1.2",
"@jest/types": "^29.2.1",
"@playwright/test": "^1.27.1",
"@storybook/addon-actions": "^6.5.12",
"@storybook/addon-essentials": "^6.5.12",
Expand All @@ -92,7 +92,7 @@
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3",
"@trivago/prettier-plugin-sort-imports": "^3.4.0",
"@types/chrome": "^0.0.197",
"@types/chrome": "^0.0.199",
"@types/crypto-js": "^4.1.1",
"@types/elliptic": "^6.4.14",
"@types/pubsub-js": "^1.8.3",
Expand Down Expand Up @@ -126,7 +126,7 @@
"lint-staged": "^13.0.3",
"mini-css-extract-plugin": "^2.6.1",
"msw": "^0.47.4",
"postcss": "^8.4.17",
"postcss": "^8.4.18",
"postcss-cli": "^10.0.0",
"postcss-loader": "^7.0.1",
"pptr-testing-library": "^0.7.0",
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/AllowanceMenu/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as SettingsContext from "~/app/context/SettingsContext";
import type { Props } from "./index";
import AllowanceMenu from "./index";

const mockGetFiatValue = jest.fn(() => "$1,22");
const mockGetFiatValue = jest.fn(() => Promise.resolve("$1,22"));

jest.spyOn(SettingsContext, "useSettings").mockReturnValue({
settings: mockSettings,
Expand Down
10 changes: 7 additions & 3 deletions src/app/components/AllowanceMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ function AllowanceMenu({ allowance, onEdit, onDelete }: Props) {

useEffect(() => {
if (budget !== "" && showFiat) {
const res = getFiatValue(budget);
setFiatAmount(res);
const getFiat = async () => {
const res = await getFiatValue(budget);
setFiatAmount(res);
};

getFiat();
}
}, [budget, showFiat, getFiatValue]);

Expand Down Expand Up @@ -134,7 +138,7 @@ function AllowanceMenu({ allowance, onEdit, onDelete }: Props) {
label={t("new_budget.label")}
min={0}
autoFocus
placeholder={tCommon("sats")}
placeholder={tCommon("sats", { count: 0 })}
value={budget}
hint={t("hint")}
fiatValue={fiatAmount}
Expand Down
3 changes: 2 additions & 1 deletion src/app/components/BudgetControl/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ function BudgetControl({

<div>
<DualCurrencyField
autoFocus
fiatValue={fiatAmount}
id="budget"
min={0}
label={t("budget.label")}
placeholder={tCommon("sats")}
placeholder={tCommon("sats", { count: 0 })}
value={budget}
onChange={onBudgetChange}
/>
Expand Down
6 changes: 4 additions & 2 deletions src/app/components/ConfirmOrCancel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type Props = {
label?: string;
onConfirm?: MouseEventHandler;
onCancel: MouseEventHandler;
isFocused?: boolean;
};

export default function ConfirmOrCancel({
Expand All @@ -19,13 +20,14 @@ export default function ConfirmOrCancel({
label = i18n.t("actions.confirm", commonI18nNamespace) as string,
onConfirm,
onCancel,
isFocused = true,
}: Props) {
const { t: tCommon } = useTranslation("common");
const buttonRef = useRef<HTMLButtonElement>(null);

useEffect(() => {
buttonRef?.current?.focus();
}, []);
isFocused && buttonRef?.current?.focus();
}, [isFocused]);

return (
<div className="pt-2 pb-4">
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function Container({

return (
<div
className={`container mx-auto px-4 mb-4 ${getMaxWidthClass(maxWidth)} ${
className={`container mx-auto px-4 ${getMaxWidthClass(maxWidth)} ${
justifyBetween
? "h-full flex flex-col justify-between overflow-y-auto no-scrollbar"
: ""
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/PaymentSummary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const PaymentSummary: FC<Props> = ({
<dl className="mb-0">
<dt className="font-medium dark:text-white">{tCommon("amount")}</dt>
<dd className="text-gray-500 dark:text-neutral-400">
{amount} sats
{amount} {tCommon("sats", { count: amount as number })}
{!!fiatAmount && (
<span className="text-gray-400" data-testid="fiat_amount">
{" "}
Expand Down
7 changes: 5 additions & 2 deletions src/app/components/PublishersTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ export default function PublishersTable({
{tComponents("payments")}{" "}
{publisher.paymentsAmount > 0 && (
<span>
({publisher.paymentsAmount} {tCommon("sats")})
({publisher.paymentsAmount}{" "}
{tCommon("sats", { count: publisher.paymentsAmount })}
)
</span>
)}
</div>
Expand All @@ -76,7 +78,8 @@ export default function PublishersTable({
<div className="ml-40">
<p className="text-lg text-gray-500 mb-0 dark:text-neutral-400">
{publisher.usedBudget} / {publisher.totalBudget}{" "}
{tCommon("sats")} {tComponents("used")}
{tCommon("sats", { count: publisher.usedBudget })}{" "}
{tComponents("used")}
</p>
<div className="relative mt-2 ml-auto">
<div className="flex items-center justify-end">
Expand Down
4 changes: 3 additions & 1 deletion src/app/components/ResultCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ export default function ResultCard({ message, isSuccess }: Props) {
alt={isSuccess ? "success" : "failure"}
className="mb-8"
/>
<p className="text-center dark:text-white">{message}</p>
<p className="text-center dark:text-white w-full text-ellipsis line-clamp-3">
{message}
</p>
</div>
);
}
20 changes: 17 additions & 3 deletions src/app/components/TransactionsTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type Props = {
};

export default function TransactionsTable({ transactions }: Props) {
const { t: tCommon } = useTranslation("common");
const { t: tComponents } = useTranslation("components");

function renderIcon(type: string) {
Expand Down Expand Up @@ -52,7 +53,19 @@ export default function TransactionsTable({ transactions }: Props) {
className="
text-sm font-medium text-gray-900 truncate dark:text-white"
>
{tx.title || "\u00A0"}
<p className="truncate">
{tx.publisherLink && tx.title ? (
<a
target="_blank"
href={tx.publisherLink}
rel="noopener noreferrer"
>
{tx.title}
</a>
) : (
tx.title || "\u00A0"
)}
</p>
</div>
<p className="text-xs text-gray-600 capitalize dark:text-neutral-400">
{tComponents(`transactionsTable.${tx.type}`)} -{" "}
Expand All @@ -77,7 +90,8 @@ export default function TransactionsTable({ transactions }: Props) {
{[tx.type && "sent", "sending"].includes(tx.type)
? "-"
: "+"}
{tx.totalAmount} sats
{tx.totalAmount}{" "}
{tCommon("sats", { count: tx.totalAmount as number })}
</p>
{!!tx.totalAmountFiat && (
<p className="text-xs text-gray-600 dark:text-neutral-400">
Expand All @@ -103,7 +117,7 @@ export default function TransactionsTable({ transactions }: Props) {
{tx.totalFees && (
<p>
{tComponents("transactionsTable.fee")}: {tx.totalFees}{" "}
sats
{tCommon("sats", { count: tx.totalFees })}
</p>
)}
{tx.preimage && (
Expand Down
4 changes: 2 additions & 2 deletions src/app/context/AccountContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ export function AccountProvider({ children }: { children: React.ReactNode }) {
const setAccountId = (id: string) => setAccount({ id });

const updateFiatValue = useCallback(
(balance: string | number) => {
const fiat = getFiatValue(balance);
async (balance: string | number) => {
const fiat = await getFiatValue(balance);
setFiatBalance(fiat);
},
[getFiatValue]
Expand Down
57 changes: 40 additions & 17 deletions src/app/context/SettingsContext.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import dayjs from "dayjs";
import i18n from "i18next";
import { useState, useEffect, createContext, useContext } from "react";
import { useState, useEffect, createContext, useContext, useRef } from "react";
import { toast } from "react-toastify";
import { getTheme } from "~/app/utils";
import { CURRENCIES } from "~/common/constants";
import api from "~/common/lib/api";
import { getFiatValue as getFiatValueFunc } from "~/common/utils/currencyConvert";
import { getFiatValue as getFiatValueUtil } from "~/common/utils/currencyConvert";
import { DEFAULT_SETTINGS } from "~/extension/background-script/state";
import type { SettingsStorage } from "~/types";

interface SettingsContextType {
settings: SettingsStorage;
updateSetting: (setting: Setting) => void;
isLoading: boolean;
getFiatValue: (amount: number | string) => string;
getFiatValue: (amount: number | string) => Promise<string>;
}

type Setting = Partial<SettingsStorage>;
Expand All @@ -27,7 +28,11 @@ export const SettingsProvider = ({
const [settings, setSettings] =
useState<SettingsContextType["settings"]>(DEFAULT_SETTINGS);
const [isLoading, setIsLoading] = useState(true);
const [currencyRate, setCurrencyRate] = useState(0);

// store latest currency and currency rate in ref to prevent a re-render
const currencyRate = useRef<null | { rate: number; currency: CURRENCIES }>(
null
);

// call this to trigger a re-render on all occassions
const updateSetting = async (setting: Setting) => {
Expand Down Expand Up @@ -55,19 +60,37 @@ export const SettingsProvider = ({
});
}, []);

// update rate
useEffect(() => {
api.getCurrencyRate().then((response) => {
setCurrencyRate(response.rate);
});
}, [settings.currency]);

const getFiatValue = (amount: number | string) =>
getFiatValueFunc({
amount,
rate: currencyRate,
currency: settings.currency,
});
const getCurrencyRate = async (): Promise<number> => {
// ensure to get the correct rate for current currency in state
if (settings.currency !== currencyRate.current?.currency) {
const response = await api.getCurrencyRate(); // gets rate from browser.storage or API

// update local ref
currencyRate.current = {
rate: response.rate,
currency: settings.currency,
};
}

return currencyRate.current.rate;
};

const getFiatValue = async (amount: number | string) => {
try {
const rate = await getCurrencyRate();
const value = getFiatValueUtil({
amount,
rate,
currency: settings.currency,
});

return value;
} catch (e) {
console.error(e);

return "??"; // show the user that something went wrong
}
};

// update locale on every change
useEffect(() => {
Expand Down
8 changes: 4 additions & 4 deletions src/app/screens/ConfirmKeysend/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jest.spyOn(SettingsContext, "useSettings").mockReturnValue({
updateSetting: jest.fn(),
getFiatValue: jest
.fn()
.mockImplementationOnce(() => "$0.00")
.mockImplementationOnce(() => "$0.00")
.mockImplementationOnce(() => "$0.01")
.mockImplementationOnce(() => "$0.05"),
.mockImplementationOnce(() => Promise.resolve("$0.00"))
.mockImplementationOnce(() => Promise.resolve("$0.00"))
.mockImplementationOnce(() => Promise.resolve("$0.01"))
.mockImplementationOnce(() => Promise.resolve("$0.05")),
});

const mockOrigin: OriginData = {
Expand Down
Loading

0 comments on commit 3651846

Please sign in to comment.