Skip to content

Commit

Permalink
fix(deploy-web): change the broken auto-import for an import button
Browse files Browse the repository at this point in the history
  • Loading branch information
Redm4x committed May 17, 2024
1 parent e5bd128 commit 0bdc5ee
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 41 deletions.
103 changes: 103 additions & 0 deletions deploy-web/src/components/home/CloudmosImportPanel.tsx
Original file line number Diff line number Diff line change
@@ -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<Window | null>(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 (
<Card>
<CardHeader>
<CardTitle className="text-2xl font-bold">Coming from Cloudmos?</CardTitle>
</CardHeader>

<CardContent>
If you have existing data on Cloudmos, you can import it easily.
<Button variant="default" className="ml-2" onClick={handleImportClick}>
Import
<Import className="ml-2" />
</Button>
</CardContent>
</Card>
);
}
4 changes: 4 additions & 0 deletions deploy-web/src/components/home/HomeContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -68,6 +69,9 @@ export function HomeContainer() {
<div className="mb-4">
<WelcomePanel />
</div>
<div className="mb-4">
<CloudmosImportPanel />
</div>
{isSettingsInit && isWalletLoaded ? (
<YourAccount isLoadingBalances={isLoadingBalances} balances={balances} activeDeployments={activeDeployments} leases={leases} providers={providers} />
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Settings>(defaultSettings);
const [isLoadingSettings, setIsLoadingSettings] = useState(true);
Expand All @@ -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<HTMLIFrameElement>(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 () => {
Expand Down Expand Up @@ -354,9 +316,6 @@ export function SettingsProvider({ children }: React.PropsWithChildren<{}>) {
}}
>
{children}

{/* iframe for localstorage automatic import */}
{isSettingsInit && <iframe ref={iframeRef} className="hidden" src={`${autoImportOrigin}/standalone/localstorage-export`} width={0} height={0} />}
</SettingsProviderContext.Provider>
);
}
Expand Down

0 comments on commit 0bdc5ee

Please sign in to comment.