Skip to content

Commit

Permalink
feat: new ui home screen and receive screen (#2983)
Browse files Browse the repository at this point in the history
* feat: new popup ui

* feat: new receive screens

* general commit

* fix: dark color css

* feat: new property to detect backup done or not

* chore: reduce api calls

* chore: reduce content gap

* feat: for existing accounts consider mnemonic backup already done

* fix: tests

---------

Co-authored-by: René Aaron <rene@twentyuno.net>
  • Loading branch information
pavanjoshi914 and reneaaron authored Feb 22, 2024
1 parent a0cac36 commit dc37cc0
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 13 deletions.
6 changes: 3 additions & 3 deletions src/app/components/IconLinkCard/IconLinkCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ export function IconLinkCard({
}: IconLinkCardProps) {
return (
<div
className="shadow rounded-md p-4 bg-white dark:bg-surface-01dp hover:bg-gray-50 dark:hover:bg-surface-02dp text-gray-800 dark:text-neutral-200 cursor-pointer flex flex-row items-center gap-3"
className="border border-gray-300 dark:border-neutral-800 rounded-xl p-4 bg-white dark:bg-surface-01dp hover:bg-gray-50 dark:hover:bg-surface-02dp text-gray-800 dark:text-neutral-200 cursor-pointer flex flex-row items-center gap-3"
onClick={onClick}
>
<div className="flex-shrink-0 flex justify-center md:px-3">{icon}</div>
<div className="flex-grow">
<div className="flex-grow space-y-0.5">
<div className="font-medium leading-5 text-sm md:text-base">
{title}
</div>
<div className="text-gray-600 dark:text-neutral-400 text-xs leading-4 md:text-sm">
{description}
</div>
</div>
<div className="flex-shrink-0 flex justify-end ">
<div className="flex-shrink-0 flex justify-end text-gray-400 dark:text-neutral-500 ">
<CaretRightIcon className="w-8" />
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/app/screens/Accounts/BackupMnemonic/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ function BackupMnemonic() {
fetchData();
}, [fetchData]);

// TODO: set isMnemonicBackupDone, once new ui for screen is merged
return loading ? (
<div className="flex justify-center mt-5">
<Loading />
Expand Down
5 changes: 4 additions & 1 deletion src/app/screens/Accounts/GenerateMnemonic/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ function GenerateMnemonic() {
}

await api.setMnemonic(id, mnemonic);
await api.editAccount(id, { useMnemonicForLnurlAuth: true });
await api.editAccount(id, {
useMnemonicForLnurlAuth: true,
isMnemonicBackupDone: true,
});

toast.success(t("saved"));
// go to account settings
Expand Down
106 changes: 104 additions & 2 deletions src/app/screens/Home/DefaultView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@ import { ArrowRightIcon } from "@bitcoin-design/bitcoin-icons-react/filled";
import Button from "@components/Button";
import Loading from "@components/Loading";
import TransactionsTable from "@components/TransactionsTable";
import {
PopiconsArrowDownLine,
PopiconsBulbLine,
PopiconsDownloadLine,
PopiconsKeyLine,
} from "@popicons/react";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
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 { IconLinkCard } from "~/app/components/IconLinkCard/IconLinkCard";
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";
import api, { GetAccountRes } from "~/common/lib/api";
import msg from "~/common/lib/msg";
import utils from "~/common/lib/utils";
import type { Battery } from "~/types";
Expand All @@ -40,6 +47,7 @@ const DefaultView: FC<Props> = (props) => {
const lightningAddress = account?.lightningAddress || "";

const [isBlockedUrl, setIsBlockedUrl] = useState<boolean>(false);
const [currentAccount, setCurrentAccount] = useState<GetAccountRes>();

const { transactions, isLoadingTransactions, loadTransactions } =
useTransactions();
Expand All @@ -62,6 +70,18 @@ const DefaultView: FC<Props> = (props) => {
}
}, [props.currentUrl]);

useEffect(() => {
(async () => {
try {
const account = await api.getAccount();
setCurrentAccount(account);
} catch (e) {
console.error(e);
if (e instanceof Error) toast.error(`Error: ${e.message}`);
}
})();
}, []);

const unblock = async () => {
try {
if (props.currentUrl?.host) {
Expand All @@ -88,6 +108,10 @@ const DefaultView: FC<Props> = (props) => {
}
}

function openOptions(path: string) {
utils.openPage(`options.html#/${path}`);
}

return (
<div className="w-full max-w-screen-sm h-full mx-auto overflow-y-auto no-scrollbar">
{props.renderPublisherWidget && !!props.lnDataFromCurrentTab?.length && (
Expand Down Expand Up @@ -164,10 +188,88 @@ const DefaultView: FC<Props> = (props) => {

{!isLoading && (
<div>
<div className="flex flex-col gap-2 md:gap-3">
{transactions.length == 0 && (
<IconLinkCard
title={t("default_view.actions.get_started.title")}
description={t(
"default_view.actions.get_started.description"
)}
icon={
<PopiconsBulbLine className="w-8 h-8 text-gray-400 dark:text-neutral-500" />
}
onClick={() => {
utils.openUrl(
"https://guides.getalby.com/user-guide/v/alby-account-and-browser-extension/"
);
}}
/>
)}

{!(
currentAccount?.hasMnemonic &&
currentAccount?.isMnemonicBackupDone
) && (
<IconLinkCard
title={t("default_view.actions.backup_masterkey.title")}
description={t(
"default_view.actions.backup_masterkey.description"
)}
icon={
<PopiconsKeyLine className="w-8 h-8 text-gray-400 dark:text-neutral-500" />
}
onClick={async () => {
if (currentAccount?.hasMnemonic) {
openOptions(
`accounts/${currentAccount?.id}/secret-key/backup`
);
} else {
openOptions(
`accounts/${currentAccount?.id}/secret-key/new`
);
}
}}
/>
)}

{transactions.length == 0 && (
<IconLinkCard
title={t("default_view.actions.receive_bitcoin.title")}
description={t(
"default_view.actions.receive_bitcoin.description"
)}
icon={
<PopiconsArrowDownLine className="w-8 h-8 text-gray-400 dark:text-neutral-500" />
}
onClick={() => {
navigate("/receive");
}}
/>
)}

{!(
currentAccount?.hasMnemonic &&
currentAccount?.isMnemonicBackupDone
) && (
<IconLinkCard
title={t("default_view.actions.import_masterkey.title")}
description={t(
"default_view.actions.import_masterkey.description"
)}
icon={
<PopiconsDownloadLine className="w-8 h-8 text-gray-400 dark:text-neutral-500" />
}
onClick={async () => {
openOptions(
`accounts/${currentAccount?.id}/secret-key/import`
);
}}
/>
)}
</div>
<TransactionsTable
transactions={transactions}
loading={isLoading}
noResultMsg={t("default_view.no_transactions")}
/>

{!isLoading && transactions.length > 0 && (
Expand Down
17 changes: 11 additions & 6 deletions src/app/screens/Receive/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {
BitcoinCircleIcon,
BitcoinIcon,
CaretLeftIcon,
CopyIcon,
LightningIcon,
} from "@bitcoin-design/bitcoin-icons-react/outline";
import Container from "@components/Container";
import Header from "@components/Header";
import IconButton from "@components/IconButton";
import { PopiconsBoltLine, PopiconsWithdrawalLine } from "@popicons/react";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
Expand All @@ -15,7 +15,6 @@ import QRCode from "~/app/components/QRCode";
import SkeletonLoader from "~/app/components/SkeletonLoader";
import toast from "~/app/components/Toast";
import { useAccount } from "~/app/context/AccountContext";
import RedeemIcon from "~/app/icons/RedeemIcon";
import { isAlbyLNDHubAccount, isAlbyOAuthAccount } from "~/app/utils";
import api from "~/common/lib/api";
import { IconLinkCard } from "../../components/IconLinkCard/IconLinkCard";
Expand Down Expand Up @@ -123,7 +122,9 @@ function Receive() {
<IconLinkCard
title={t("actions.invoice.title")}
description={t("actions.invoice.description")}
icon={<LightningIcon className="w-8" />}
icon={
<PopiconsBoltLine className="w-8 h-8 text-gray-400 dark:text-neutral-500" />
}
onClick={() => {
navigate("/receive/invoice");
}}
Expand All @@ -132,7 +133,9 @@ function Receive() {
<IconLinkCard
title={t("actions.bitcoin_address.title")}
description={t("actions.bitcoin_address.description")}
icon={<BitcoinCircleIcon className="w-8" />}
icon={
<BitcoinIcon className="w-8 h-8 text-gray-400 dark:text-neutral-500" />
}
onClick={() => {
navigate("/onChainReceive");
}}
Expand All @@ -141,7 +144,9 @@ function Receive() {
<IconLinkCard
title={t("actions.redeem.title")}
description={t("actions.redeem.description")}
icon={<RedeemIcon className="w-8" />}
icon={
<PopiconsWithdrawalLine className="w-8 h-8 text-gray-400 dark:text-neutral-500" />
}
onClick={() => {
navigate("/lnurlRedeem");
}}
Expand Down
1 change: 1 addition & 0 deletions src/common/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export interface GetAccountRes extends Pick<Account, "id" | "name"> {
liquidEnabled: boolean;
nostrEnabled: boolean;
hasMnemonic: boolean;
isMnemonicBackupDone: boolean;
hasImportedNostrKey: boolean;
bitcoinNetwork: BitcoinNetworkType;
useMnemonicForLnurlAuth: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const message: MessageAccountAdd = {
config: "123456config",
name: "purple",
nostrPrivateKey: "123456nostr",
isMnemonicBackupDone: false,
},
origin: { internal: true },
prompt: true,
Expand Down Expand Up @@ -59,6 +60,7 @@ describe("add account to account-list", () => {
config: "secret-config-string-42",
name: "purple",
nostrPrivateKey: "123456nostr",
isMnemonicBackupDone: false,
},
},
});
Expand Down Expand Up @@ -107,6 +109,7 @@ describe("add account to account-list", () => {
config: "secret-config-string-42",
name: "purple",
nostrPrivateKey: "123456nostr",
isMnemonicBackupDone: false,
},
"666": {
config: "xyz",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const mockState = {
mnemonic: btcFixture.mnemonic,
bitcoinNetwork: "regtest",
useMnemonicForLnurlAuth: true,
isMnemonicBackupDone: true,
},
"1e1e8ea6-493e-480b-9855-303d37506e97": {
config: "config-123-456",
Expand Down Expand Up @@ -65,6 +66,7 @@ describe("account info", () => {
hasImportedNostrKey: true,
bitcoinNetwork: "bitcoin",
useMnemonicForLnurlAuth: false,
isMnemonicBackupDone: true,
};

expect(await getAccount(message)).toStrictEqual({
Expand Down Expand Up @@ -92,6 +94,7 @@ describe("account info", () => {
hasImportedNostrKey: true,
bitcoinNetwork: "regtest",
useMnemonicForLnurlAuth: true,
isMnemonicBackupDone: true,
};

expect(await getAccount(message)).toStrictEqual({
Expand Down
1 change: 1 addition & 0 deletions src/extension/background-script/actions/accounts/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const add = async (message: MessageAccountAdd) => {
...newAccount,
id: accountId,
name,
isMnemonicBackupDone: false,
};

const mnemonic = await generateMnemonic({
Expand Down
5 changes: 5 additions & 0 deletions src/extension/background-script/actions/accounts/edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ const edit = async (message: MessageAccountEdit) => {
message.args.useMnemonicForLnurlAuth;
}

if (message.args.isMnemonicBackupDone !== undefined) {
accounts[accountId].isMnemonicBackupDone =
message.args.isMnemonicBackupDone;
}

state.setState({ accounts });
// make sure we immediately persist the updated accounts
await state.getState().saveToStorage();
Expand Down
4 changes: 4 additions & 0 deletions src/extension/background-script/actions/accounts/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ const get = async (message: MessageAccountGet) => {
liquidEnabled: !!account.mnemonic,
nostrEnabled: !!account.nostrPrivateKey,
hasMnemonic: !!account.mnemonic,
// for existing accounts consider mnemonic backup already done
isMnemonicBackupDone: account.isMnemonicBackupDone
? account.isMnemonicBackupDone
: true,
// Note: undefined (default for new accounts) it is also considered imported
hasImportedNostrKey: account.hasImportedNostrKey !== false,
bitcoinNetwork: account.bitcoinNetwork || "bitcoin",
Expand Down
21 changes: 20 additions & 1 deletion src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,26 @@
"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.",
"see_all": "See all"
"see_all": "See all",
"actions": {
"get_started": {
"title": "Get Started With Alby Extension",
"description": "New to Alby Extension? Check out our guides, videos, and explanations"
},
"backup_masterkey": {
"title": "Back up your Master Key",
"description": "Learn what Master Key is, how it’s used for Nostr and make sure to back up"
},

"receive_bitcoin": {
"title": "Receive bitcoin",
"description": "Get bitcoin to your lightning address, a lightning invoice or bitcoin address."
},
"import_masterkey": {
"title": "Import your Master Key",
"description": "If you already have a Master Key, you can import it using recovery phrase"
}
}
}
},
"accounts": {
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface Account {
mnemonic?: string | null;
hasImportedNostrKey?: boolean;
bitcoinNetwork?: BitcoinNetworkType;
isMnemonicBackupDone?: boolean;
useMnemonicForLnurlAuth?: boolean;
avatarUrl?: string;
}
Expand Down Expand Up @@ -231,6 +232,7 @@ export interface MessageAccountEdit extends MessageDefault {
name?: Account["name"];
bitcoinNetwork?: BitcoinNetworkType;
useMnemonicForLnurlAuth?: boolean;
isMnemonicBackupDone?: boolean;
};
action: "editAccount";
}
Expand Down

0 comments on commit dc37cc0

Please sign in to comment.