mirror of
https://github.com/aljazceru/mutiny-web.git
synced 2026-01-21 07:04:28 +01:00
import / export
This commit is contained in:
75
src/components/ImportExport.tsx
Normal file
75
src/components/ImportExport.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Button, InnerCard, VStack } from "~/components/layout";
|
||||
import { createSignal } from "solid-js";
|
||||
import eify from "~/utils/eify";
|
||||
import { showToast } from "./Toaster";
|
||||
import { downloadTextFile } from "~/utils/download";
|
||||
import { createFileUploader } from "@solid-primitives/upload"
|
||||
import { ConfirmDialog } from "./Dialog";
|
||||
import { NodeManager } from "@mutinywallet/mutiny-wasm";
|
||||
|
||||
export function ImportExport() {
|
||||
const [state, _] = useMegaStore()
|
||||
|
||||
async function handleSave() {
|
||||
let json = await state.node_manager?.export_json()
|
||||
downloadTextFile(json || "", "mutiny-state.json")
|
||||
}
|
||||
|
||||
const { files, selectFiles } = createFileUploader();
|
||||
|
||||
async function importJson() {
|
||||
setConfirmLoading(true);
|
||||
const fileReader = new FileReader();
|
||||
|
||||
try {
|
||||
const file: File = files()[0].file;
|
||||
fileReader.readAsText(file, "UTF-8");
|
||||
fileReader.onload = e => {
|
||||
const text = e.target?.result?.toString();
|
||||
|
||||
if (text) {
|
||||
// This should throw if there's a parse error, so we won't end up clearing
|
||||
JSON.parse(text);
|
||||
|
||||
NodeManager.import_json(text);
|
||||
|
||||
window.location.href = "/"
|
||||
|
||||
} else {
|
||||
throw new Error("No text found in file")
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
showToast(eify(e));
|
||||
}
|
||||
setConfirmOpen(false);
|
||||
setConfirmLoading(false);
|
||||
}
|
||||
|
||||
async function uploadFile() {
|
||||
selectFiles(async files => {
|
||||
if (files.length) {
|
||||
setConfirmOpen(true);
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const [confirmOpen, setConfirmOpen] = createSignal(false);
|
||||
const [confirmLoading, setConfirmLoading] = createSignal(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<InnerCard>
|
||||
<VStack>
|
||||
<Button onClick={handleSave}>Save State As File</Button>
|
||||
<Button onClick={uploadFile}>Upload Saved State</Button>
|
||||
</VStack>
|
||||
</InnerCard>
|
||||
<ConfirmDialog loading={confirmLoading()} isOpen={confirmOpen()} onConfirm={importJson} onCancel={() => setConfirmOpen(false)}>
|
||||
Do you want to replace your state with {files()[0].name}?
|
||||
</ConfirmDialog>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -6,8 +6,9 @@ import { MutinyChannel, MutinyPeer } from "@mutinywallet/mutiny-wasm";
|
||||
import { Collapsible, TextField } from "@kobalte/core";
|
||||
import mempoolTxUrl from "~/utils/mempoolTxUrl";
|
||||
import eify from "~/utils/eify";
|
||||
import { ConfirmDialog } from "./Dialog";
|
||||
import { showToast } from "./Toaster";
|
||||
import { ConfirmDialog } from "~/components/Dialog";
|
||||
import { showToast } from "~/components/Toaster";
|
||||
import { ImportExport } from "~/components/ImportExport";
|
||||
|
||||
// TODO: hopefully I don't have to maintain this type forever but I don't know how to pass it around otherwise
|
||||
type RefetchPeersType = (info?: unknown) => MutinyPeer[] | Promise<MutinyPeer[] | undefined> | null | undefined
|
||||
@@ -326,6 +327,8 @@ function LnUrlAuth() {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default function KitchenSink() {
|
||||
return (
|
||||
<Card title="Kitchen Sink">
|
||||
@@ -336,6 +339,8 @@ export default function KitchenSink() {
|
||||
<ChannelsList />
|
||||
<Hr />
|
||||
<LnUrlAuth />
|
||||
<Hr />
|
||||
<ImportExport />
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user