diff --git a/src/_dev/hotReloadObserver.ts b/src/_dev/hotReloadObserver.ts
index 1b37ddac7..ac15c3c21 100644
--- a/src/_dev/hotReloadObserver.ts
+++ b/src/_dev/hotReloadObserver.ts
@@ -5,13 +5,21 @@ const HOTRELOAD_TAB_URL = browser.runtime.getURL("hotreload.html");
initHotReloadTab().catch(console.error);
async function initHotReloadTab() {
- const existing = await browser.tabs.query({ url: `${HOTRELOAD_TAB_URL}**` });
-
- if (existing.length === 0) {
- await browser.tabs.create({
- url: HOTRELOAD_TAB_URL,
- active: false,
- index: 0,
+ try {
+ const existing = await browser.tabs.query({
+ url: `${HOTRELOAD_TAB_URL}**`,
});
+
+ if (existing.length > 0) {
+ await browser.tabs.remove(existing.map((t) => t.id!));
+ }
+ } catch (err) {
+ console.warn(err);
}
+
+ await browser.tabs.create({
+ url: HOTRELOAD_TAB_URL,
+ active: false,
+ index: 0,
+ });
}
diff --git a/src/app/atoms/nav.ts b/src/app/atoms/nav.ts
index 86dd499b6..7b1b1e4d8 100644
--- a/src/app/atoms/nav.ts
+++ b/src/app/atoms/nav.ts
@@ -45,3 +45,9 @@ export const tokenSlugAtom = atomWithURLHash("token", null);
export const activityModalAtom = atomWithURLHash("activityOpened", false);
export const chainIdUrlAtom = atomWithURLHash("chainid", null);
+
+export const receiveModalAtom = atomWithURLHash("receiveOpened", false);
+export const receiveTokenAtom = atomWithURLHash(
+ "receiveToken",
+ null,
+);
diff --git a/src/app/components/MainApp.tsx b/src/app/components/MainApp.tsx
index e080bfc30..46dacc78e 100644
--- a/src/app/components/MainApp.tsx
+++ b/src/app/components/MainApp.tsx
@@ -11,6 +11,7 @@ import ContactsDialog from "./blocks/ContactsDialog";
import AddAccountModal from "./blocks/AddAccountModal";
import ActivityModal from "./blocks/activity/ActivityModal";
import AddFundsOnRampModal from "./blocks/AddFundsOnRampModal";
+import ReceivePopup from "./blocks/ReceiveModal";
// import AuthSignatureModal from "./blocks/AuthSignatureModal";
const MainApp: FC = () => (
@@ -36,6 +37,7 @@ const Modals: FC = () => {
+
{/* */}
>
diff --git a/src/app/components/PopupApp.tsx b/src/app/components/PopupApp.tsx
index 2e74af081..0d2df593c 100644
--- a/src/app/components/PopupApp.tsx
+++ b/src/app/components/PopupApp.tsx
@@ -12,6 +12,7 @@ import Unlock from "./screens/Unlock";
import Popup from "./screens/Popup";
import Dialog from "./blocks/Dialog";
import ActivityModal from "./blocks/activity/ActivityModal";
+import ReceivePopup from "./blocks/ReceiveModal";
const PopupApp: FC = () => (
@@ -37,7 +38,12 @@ const PopupModals: FC = () => {
return (
<>
- {!locked && }
+ {!locked && (
+ <>
+
+
+ >
+ )}
>
);
};
diff --git a/src/app/components/blocks/ReceiveModal.tsx b/src/app/components/blocks/ReceiveModal.tsx
new file mode 100644
index 000000000..d21f1ae37
--- /dev/null
+++ b/src/app/components/blocks/ReceiveModal.tsx
@@ -0,0 +1,71 @@
+import { FC, useCallback } from "react";
+import classNames from "clsx";
+import { useAtom, useSetAtom } from "jotai";
+import { isPopup } from "lib/ext/view";
+
+import { AccountAsset } from "core/types";
+
+import { receiveModalAtom, receiveTokenAtom } from "app/atoms";
+import { useAccountToken } from "app/hooks";
+import ShareAddress from "../screens/receiveTabs/ShareAddress";
+import SecondaryModal, {
+ SecondaryModalProps,
+} from "../elements/SecondaryModal";
+import AssetLogo from "../elements/AssetLogo";
+
+type ReceiveModalProps = Pick;
+
+const ReceiveModal: FC = (props) => {
+ const isPopupMode = isPopup();
+ const setReceiveToken = useSetAtom(receiveTokenAtom);
+ const [receiveOpened, setReceiveOpened] = useAtom(receiveModalAtom);
+
+ const handleOpenChange = useCallback(
+ (open: boolean) => {
+ setReceiveOpened([open, "replace"]);
+ setReceiveToken([null, "replace"]);
+ },
+ [setReceiveOpened, setReceiveToken],
+ );
+
+ return (
+
+ Receive{" "}
+ {receiveOpened && }
+
+ }
+ small
+ open={receiveOpened}
+ onOpenChange={handleOpenChange}
+ className={classNames("", !isPopupMode ? "max-w-[30rem]" : "")}
+ headerClassName={classNames(
+ "!m-0 !w-full",
+ isPopupMode ? "!text-lg" : "!text-[1.5rem]",
+ )}
+ >
+
+
+ );
+};
+
+export default ReceiveModal;
+
+const TokenDetails = () => {
+ const [tokenSlug] = useAtom(receiveTokenAtom);
+ const currentToken = useAccountToken(tokenSlug ?? "") as AccountAsset;
+
+ return currentToken ? (
+ <>
+
+ {currentToken.symbol}
+ >
+ ) : null;
+};
diff --git a/src/app/components/blocks/Sidebar.Links.tsx b/src/app/components/blocks/Sidebar.Links.tsx
index 2390368c7..a7b1f9674 100644
--- a/src/app/components/blocks/Sidebar.Links.tsx
+++ b/src/app/components/blocks/Sidebar.Links.tsx
@@ -9,18 +9,20 @@ import { ReactComponent as SwapIcon } from "app/icons/SwapIcon.svg";
// import { ReactComponent as AppsIcon } from "app/icons/Apps.svg";
import { ReactComponent as ContactsIcon } from "app/icons/Contacts.svg";
import { ReactComponent as WalletsIcon } from "app/icons/Wallets.svg";
+import { ReactComponent as BuyIcon } from "app/icons/Buy-page.svg";
import { ReactComponent as SettingsIcon } from "app/icons/Settings.svg";
import { ReactComponent as SupportIcon } from "app/icons/Support.svg";
import { ReactComponent as ActivityIcon } from "app/icons/ActivityIcon.svg";
import { ReactComponent as RewardsIcon } from "app/icons/Rewards.svg";
import * as SupportAlert from "app/components/elements/SupportAlert";
import { useDialog } from "app/hooks/dialog";
-import { activityModalAtom } from "app/atoms";
+import { activityModalAtom, receiveModalAtom } from "app/atoms";
import { useActivityBadge, useSwapBadge, useAccounts } from "app/hooks";
const useSidebarLinks = () => {
const { alert } = useDialog();
const setActivityOpened = useSetAtom(activityModalAtom);
+ const setReceiveOpened = useSetAtom(receiveModalAtom);
const activityBadgeAmount = useActivityBadge();
const { currentAccount } = useAccounts();
@@ -45,9 +47,14 @@ const useSidebarLinks = () => {
Icon: SendIcon,
},
{
- route: Page.Receive,
- label: "Buy",
+ label: "Receive",
Icon: ReceiveIcon,
+ action: () => setReceiveOpened([true, "replace"]),
+ },
+ {
+ route: Page.Buy,
+ label: "Buy",
+ Icon: BuyIcon,
},
{
route: Page.Swap,
@@ -67,7 +74,12 @@ const useSidebarLinks = () => {
// soon: true,
// },
];
- }, [activityBadgeAmount, swapBadgeAmount, setActivityOpened]);
+ }, [
+ activityBadgeAmount,
+ swapBadgeAmount,
+ setActivityOpened,
+ setReceiveOpened,
+ ]);
const NavLinksSecondary = useMemo(() => {
return [
diff --git a/src/app/components/blocks/overview/AssetInfo.tsx b/src/app/components/blocks/overview/AssetInfo.tsx
index 29ea7c248..c4ff9ce06 100644
--- a/src/app/components/blocks/overview/AssetInfo.tsx
+++ b/src/app/components/blocks/overview/AssetInfo.tsx
@@ -36,7 +36,8 @@ import { ReactComponent as WalletExplorerIcon } from "app/icons/external-link.sv
import { ReactComponent as CoinGeckoIcon } from "app/icons/coingecko.svg";
import { ReactComponent as SwapIcon } from "app/icons/swap.svg";
import { ReactComponent as SendIcon } from "app/icons/send-action.svg";
-import { ReactComponent as BuyIcon } from "app/icons/buy-action.svg";
+import { ReactComponent as ReceiveIcon } from "app/icons/buy-action.svg";
+import { ReactComponent as BuyIcon } from "app/icons/plus-rounded.svg";
import { ReactComponent as EyeIcon } from "app/icons/eye.svg";
import TokenActivity from "./TokenActivity";
@@ -223,16 +224,25 @@ const AssetInfo: FC = () => {
/>
-
+
+
diff --git a/src/app/components/blocks/popup/AssetCard.tsx b/src/app/components/blocks/popup/AssetCard.tsx
index caaeb7fca..519d624f0 100644
--- a/src/app/components/blocks/popup/AssetCard.tsx
+++ b/src/app/components/blocks/popup/AssetCard.tsx
@@ -35,13 +35,14 @@ import {
import { ReactComponent as ExpandIcon } from "app/icons/expand.svg";
import { ReactComponent as SwapIcon } from "app/icons/swap.svg";
import { ReactComponent as SendIcon } from "app/icons/send-action.svg";
-import { ReactComponent as BuyIcon } from "app/icons/buy-action.svg";
import { ReactComponent as CheckIcon } from "app/icons/check.svg";
import { ReactComponent as WalletExplorerIcon } from "app/icons/external-link.svg";
import { ReactComponent as CoinGeckoIcon } from "app/icons/coingecko.svg";
import { ReactComponent as SuccessIcon } from "app/icons/success.svg";
import { ReactComponent as CopyIcon } from "app/icons/copy.svg";
import { ReactComponent as EyeIcon } from "app/icons/eye.svg";
+import { ReactComponent as ReceiveIcon } from "app/icons/buy-action.svg";
+import { ReactComponent as BuyIcon } from "app/icons/plus-rounded.svg";
import FiatAmount from "app/components/elements/FiatAmount";
import AssetLogo from "app/components/elements/AssetLogo";
@@ -51,6 +52,7 @@ import PriceChange from "app/components/elements/PriceChange";
import IconedButton from "app/components/elements/IconedButton";
import PopupModal from "./PopupModal";
+import { navigate } from "lib/navigation";
type AssetCardProps = {
asset: AccountAsset;
@@ -178,6 +180,13 @@ const AssetCard = memo(
{
+ navigate((s) => ({
+ ...s,
+ receiveOpened: true,
+ receiveToken: asset.tokenSlug,
+ }));
+ }}
onClose={() => setModalOpen(false)}
asset={asset}
/>
@@ -217,11 +226,17 @@ const PopoverButton: FC = ({ Icon, children, ...rest }) => (
interface IAssetModalProps {
open: boolean;
+ onReceive: () => void;
onClose: () => void;
asset: AccountAsset;
}
-const AssetModal: FC = ({ open, asset, onClose }) => {
+const AssetModal: FC = ({
+ open,
+ onReceive,
+ asset,
+ onClose,
+}) => {
const {
balanceUSD,
name,
@@ -323,6 +338,17 @@ const AssetModal: FC = ({ open, asset, onClose }) => {
}
Icon={SendIcon}
/>
+
diff --git a/src/app/components/elements/AddressField.tsx b/src/app/components/elements/AddressField.tsx
index e363ab6ea..23b38f279 100644
--- a/src/app/components/elements/AddressField.tsx
+++ b/src/app/components/elements/AddressField.tsx
@@ -11,10 +11,22 @@ import { ReactComponent as CopyIcon } from "app/icons/copy.svg";
export type AddressFieldProps = LongTextFieldProps & {
setFromClipboard?: (value: string) => void;
+ hideLabel?: boolean;
+ labelClassName?: string;
};
const AddressField = forwardRef(
- ({ label = "Recipient", setFromClipboard, className, ...rest }, ref) => {
+ (
+ {
+ label = "Recipient",
+ setFromClipboard,
+ className,
+ hideLabel,
+ labelClassName,
+ ...rest
+ },
+ ref,
+ ) => {
const { paste, pasted } = usePasteFromClipboard(setFromClipboard);
const { copy, copied } = useCopyToClipboard(
rest.value ?? rest.defaultValue,
@@ -23,9 +35,10 @@ const AddressField = forwardRef(
return (
& {
label?: string;
labelActions?: ReactNode;
+ labelClassName?: string;
actions?: ReactNode;
textareaClassName?: string;
error?: boolean;
@@ -23,6 +24,7 @@ const LongTextField = memo(
label,
id,
labelActions,
+ labelClassName,
spellCheck = false,
actions,
error,
@@ -42,7 +44,12 @@ const LongTextField = memo(
return (
{(label || labelActions) && (
-
+
{label && (