From 0bdc5eefceb093197f21b5c2dc2c32c2503b0159 Mon Sep 17 00:00:00 2001 From: Redm4x <2829180+Redm4x@users.noreply.github.com> Date: Fri, 17 May 2024 12:38:40 -0400 Subject: [PATCH] fix(deploy-web): change the broken auto-import for an import button --- .../components/home/CloudmosImportPanel.tsx | 103 ++++++++++++++++++ .../src/components/home/HomeContainer.tsx | 4 + .../SettingsProviderContext.tsx | 41 ------- 3 files changed, 107 insertions(+), 41 deletions(-) create mode 100644 deploy-web/src/components/home/CloudmosImportPanel.tsx diff --git a/deploy-web/src/components/home/CloudmosImportPanel.tsx b/deploy-web/src/components/home/CloudmosImportPanel.tsx new file mode 100644 index 000000000..c1235b769 --- /dev/null +++ b/deploy-web/src/components/home/CloudmosImportPanel.tsx @@ -0,0 +1,103 @@ +import { Card, CardContent, CardHeader, CardTitle } from "@src/components/ui/card"; + +import { Import } from "iconoir-react"; +import { Button } from "../ui/button"; +import { useEffect, useRef } from "react"; +import { z } from "zod"; + +const autoImportOrigin = "https://deploy.cloudmos.io"; + +export default function CloudmosImportPanel() { + const windowRef = useRef(null); + + useEffect(() => { + window.addEventListener("message", handleMessage); + + return () => { + window.removeEventListener("message", handleMessage); + }; + }, []); + + async function handleMessage(ev: MessageEvent) { + if (ev.origin !== autoImportOrigin) { + return; + } + + console.log(`${window.location.origin} => Received event: `, ev); + + const importDataSchema = z.record(z.string(), z.string()); + + const parsedData = await importDataSchema.safeParseAsync(ev.data); + + if (!parsedData.success) { + console.error(`${window.location.origin} => Invalid data format`, parsedData.success); + return; + } + + const existingKeys = Object.keys(localStorage); + const newKeys = Object.keys(parsedData.data).filter(key => !existingKeys.includes(key)); + + for (const key of newKeys) { + localStorage.setItem(key, parsedData.data[key]); + } + + // Merge wallet certificates + const existingNetworkWalletKeys = Object.keys(parsedData.data).filter(key => existingKeys.includes(key) && key.endsWith("/wallets")); + for (const networkWalletsKey of existingNetworkWalletKeys) { + const existingWallets = JSON.parse(localStorage.getItem(networkWalletsKey)!); + const importedWallets = JSON.parse(parsedData.data[networkWalletsKey]); + const importedWalletsWithCert = importedWallets.filter(x => x.cert); + + for (const importedWallet of importedWalletsWithCert) { + const existingWallet = existingWallets.find(x => x.address === importedWallet.address); + + if (existingWallet) { + existingWallet.cert = importedWallet.cert; + existingWallet.certKey = importedWallet.certKey; + } else { + existingWallets.push(importedWallet); + } + } + + localStorage.setItem(networkWalletsKey, JSON.stringify(existingWallets)); + } + + console.log(`${window.location.origin} => Imported ${newKeys.length} keys from ${ev.origin}`); + + if (windowRef.current) { + windowRef.current.postMessage("DONE", { targetOrigin: autoImportOrigin }); + } + + window.location.reload(); + } + + function handleImportClick() { + windowRef.current = popupWindow(autoImportOrigin + "/standalone/localstorage-export", window, 400, 500); + } + + function popupWindow(url: string, win: Window, w: number, h: number) { + const y = win.outerHeight / 2 + win.screenY - h / 2; + const x = win.outerWidth / 2 + win.screenX - w / 2; + return win.open( + url, + "_blank", + `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${w}, height=${h}, top=${y}, left=${x}` + ); + } + + return ( + + + Coming from Cloudmos? + + + + If you have existing data on Cloudmos, you can import it easily. + + + + ); +} diff --git a/deploy-web/src/components/home/HomeContainer.tsx b/deploy-web/src/components/home/HomeContainer.tsx index 82f46f8e7..fd9d74392 100644 --- a/deploy-web/src/components/home/HomeContainer.tsx +++ b/deploy-web/src/components/home/HomeContainer.tsx @@ -14,6 +14,7 @@ import { WelcomePanel } from "./WelcomePanel"; import Layout from "../layout/Layout"; import { YourAccount } from "./YourAccount"; import Spinner from "../shared/Spinner"; +import CloudmosImportPanel from "./CloudmosImportPanel"; export function HomeContainer() { const { address, isWalletLoaded } = useWallet(); @@ -68,6 +69,9 @@ export function HomeContainer() {
+
+ +
{isSettingsInit && isWalletLoaded ? ( ) : ( diff --git a/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx b/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx index d50dcf641..ab0d1c18a 100644 --- a/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx +++ b/deploy-web/src/context/SettingsProvider/SettingsProviderContext.tsx @@ -52,8 +52,6 @@ const defaultSettings: Settings = { customNode: null }; -const autoImportOrigin = "https://deploy.cloudmos.io"; - export function SettingsProvider({ children }: React.PropsWithChildren<{}>) { const [settings, setSettings] = useState(defaultSettings); const [isLoadingSettings, setIsLoadingSettings] = useState(true); @@ -62,45 +60,9 @@ export function SettingsProvider({ children }: React.PropsWithChildren<{}>) { const { getLocalStorageItem, setLocalStorageItem } = useLocalStorage(); const [selectedNetworkId, setSelectedNetworkId] = useState(mainnetId); const { isCustomNode, customNode, nodes, apiEndpoint } = settings; - const iframeRef = useRef(null); usePreviousRoute(); - useEffect(() => { - window.addEventListener("message", handleMessage); - - return () => { - window.removeEventListener("message", handleMessage); - }; - }, []); - - async function handleMessage(ev: MessageEvent) { - if (ev.origin !== autoImportOrigin) { - console.log(`${window.location.origin} => Invalid origin ${ev.origin}`, ev); - return; - } - - console.log(`${window.location.origin} => Received event: `, ev); - - const importDataSchema = z.record(z.string(), z.string()); - - const parsedData = await importDataSchema.safeParseAsync(ev.data); - - if (!parsedData.success) { - console.error(`${window.location.origin} => Invalid data format`, parsedData.success); - return; - } - - const existingKeys = Object.keys(localStorage); - const newKeys = Object.keys(parsedData.data).filter(key => !existingKeys.includes(key)); - - for (const key of newKeys) { - localStorage.setItem(key, parsedData.data[key]); - } - - console.log(`${window.location.origin} => Imported ${newKeys.length} keys from ${ev.origin}`); - } - // load settings from localStorage or set default values useEffect(() => { const initiateSettings = async () => { @@ -354,9 +316,6 @@ export function SettingsProvider({ children }: React.PropsWithChildren<{}>) { }} > {children} - - {/* iframe for localstorage automatic import */} - {isSettingsInit &&