settings reorg

This commit is contained in:
Paul Miller
2023-06-29 10:19:22 -05:00
parent 3348db1eeb
commit 534a1ba00f
18 changed files with 430 additions and 304 deletions

View File

@@ -1,5 +1,5 @@
import { Show } from "solid-js";
import { Button, FancyCard, Hr, Indicator } from "~/components/layout";
import { Button, FancyCard, Indicator } from "~/components/layout";
import { useMegaStore } from "~/state/megaStore";
import { Amount } from "./Amount";
import { A, useNavigate } from "solid-start";

View File

@@ -1,6 +1,5 @@
import { useMegaStore } from "~/state/megaStore";
import { Hr, Button, InnerCard, VStack } from "~/components/layout";
import NostrWalletConnectModal from "~/components/NostrWalletConnectModal";
import {
For,
Match,
@@ -16,10 +15,8 @@ import mempoolTxUrl from "~/utils/mempoolTxUrl";
import eify from "~/utils/eify";
import { ConfirmDialog } from "~/components/Dialog";
import { showToast } from "~/components/Toaster";
import { ImportExport } from "~/components/ImportExport";
import { Network } from "~/logic/mutinyWalletSetup";
import { ExternalLink } from "./layout/ExternalLink";
import { Logs } from "./Logs";
import { Restart } from "./Restart";
import { ResyncOnchain } from "./ResyncOnchain";
import { MiniStringShower } from "./DetailsModal";
@@ -399,53 +396,6 @@ function OpenChannel(props: { refetchChannels: RefetchChannelsListType }) {
);
}
function LnUrlAuth() {
const [state, _] = useMegaStore();
const [value, setValue] = createSignal("");
const onSubmit = async (e: SubmitEvent) => {
e.preventDefault();
const lnurl = value().trim();
await state.mutiny_wallet?.lnurl_auth(0, lnurl);
setValue("");
};
return (
<InnerCard>
<form class="flex flex-col gap-4" onSubmit={onSubmit}>
<TextField.Root
value={value()}
onChange={setValue}
validationState={
value() == "" ||
value().toLowerCase().startsWith("lnurl")
? "valid"
: "invalid"
}
class="flex flex-col gap-4"
>
<TextField.Label class="text-sm font-semibold uppercase">
LNURL Auth
</TextField.Label>
<TextField.Input
class="w-full p-2 rounded-lg text-black"
placeholder="LNURL..."
/>
<TextField.ErrorMessage class="text-red-500">
Expecting something like LNURL...
</TextField.ErrorMessage>
</TextField.Root>
<Button layout="small" type="submit">
Auth
</Button>
</form>
</InnerCard>
);
}
function ListNodes() {
const [state, _] = useMegaStore();
@@ -470,24 +420,16 @@ function ListNodes() {
export default function KitchenSink() {
return (
<>
<Logs />
<Hr />
<ListNodes />
<Hr />
<NostrWalletConnectModal />
<Hr />
<PeersList />
<Hr />
<ChannelsList />
<Hr />
<LnUrlAuth />
<Hr />
<ResyncOnchain />
<Hr />
<Restart />
<Hr />
<ImportExport />
<Hr />
</>
);
}

View File

@@ -1,77 +0,0 @@
import { Show, createResource } from "solid-js";
import { useMegaStore } from "~/state/megaStore";
import { Card, NiceP, SmallHeader, TinyText, VStack } from "./layout";
import { AmountSmall } from "./Amount";
function BalanceBar(props: { inbound: number; outbound: number }) {
return (
<VStack smallgap>
<div class="flex justify-between">
<SmallHeader>Outbound</SmallHeader>
<SmallHeader>Inbound</SmallHeader>
</div>
<div class="flex gap-1 w-full">
<div
class="bg-m-green p-2 rounded-l-xl min-w-fit"
style={{
"flex-grow": props.outbound || 1
}}
>
<AmountSmall amountSats={props.outbound} />
</div>
<div
class="bg-m-blue p-2 rounded-r-xl min-w-fit"
style={{
"flex-grow": props.inbound || 1
}}
>
<AmountSmall amountSats={props.inbound} />
</div>
</div>
</VStack>
);
}
export function LiquidityMonitor() {
const [state, _actions] = useMegaStore();
const [channelInfo] = createResource(async () => {
try {
const channels = await state.mutiny_wallet?.list_channels();
let inbound = 0n;
for (const channel of channels) {
inbound =
inbound +
BigInt(channel.size) -
BigInt(channel.balance + channel.reserve);
}
return { inbound, channelCount: channels?.length };
} catch (e) {
console.error(e);
return { inbound: 0, channelCount: 0 };
}
});
return (
<Show when={channelInfo()?.channelCount}>
<Card>
<NiceP>
You have {channelInfo()?.channelCount} lightning{" "}
{channelInfo()?.channelCount === 1 ? "channel" : "channels"}
.
</NiceP>{" "}
<BalanceBar
inbound={Number(channelInfo()?.inbound) || 0}
outbound={Number(state.balance?.lightning) || 0}
/>
<TinyText>
Outbound is the amount of money you can spend on lightning.
Inbound is the amount you can receive without incurring a
lightning service fee.
</TinyText>
</Card>
</Show>
);
}

View File

@@ -1,83 +0,0 @@
import { QRCodeSVG } from "solid-qr-code";
import { As, Dialog } from "@kobalte/core";
import { Button, Card, InnerCard, NiceP } from "~/components/layout";
import { useMegaStore } from "~/state/megaStore";
import { createResource, Show } from "solid-js";
const OVERLAY = "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm";
const DIALOG_POSITIONER = "fixed inset-0 z-50 flex items-center justify-center";
const DIALOG_CONTENT =
"w-[80vw] max-w-[400px] max-h-[100dvh] overflow-y-auto disable-scrollbars p-4 bg-gray/50 backdrop-blur-md shadow-xl rounded-xl border border-white/10";
const SMALL_HEADER = "text-sm font-semibold uppercase";
export default function NostrWalletConnectModal() {
const [state, actions] = useMegaStore();
const getConnectionURI = () => {
if (state.mutiny_wallet) {
return state.mutiny_wallet.get_nwc_uri();
} else {
return undefined;
}
};
const [connectionURI] = createResource(getConnectionURI);
const toggleNwc = async () => {
if (state.nwc_enabled) {
actions.setNwc(false);
window.location.reload();
} else {
actions.setNwc(true);
const nodes = await state.mutiny_wallet?.list_nodes();
const firstNode = (nodes[0] as string) || "";
await state.mutiny_wallet?.start_nostr_wallet_connect(firstNode);
}
};
// TODO: a lot of this markup is probably reusable as a "Modal" component
return (
<InnerCard title="Nostr Wallet Connect">
<NiceP>Test out some nostr stuff.</NiceP>
<div />
<Dialog.Root>
<Dialog.Trigger asChild>
<As component={Button}>Show Nostr Wallet Connect URI</As>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay class={OVERLAY} />
<div class={DIALOG_POSITIONER}>
<Dialog.Content class={DIALOG_CONTENT}>
<div class="flex justify-between mb-2">
<Dialog.Title class={SMALL_HEADER}>
Nostr Wallet Connect
</Dialog.Title>
<Dialog.CloseButton class="dialog__close-button">
<code>X</code>
</Dialog.CloseButton>
</div>
<Dialog.Description class="flex flex-col gap-4">
<Show when={connectionURI()}>
<div class="w-full bg-white rounded-xl">
<QRCodeSVG
value={connectionURI() || ""}
class="w-full h-full p-8 max-h-[400px]"
/>
</div>
<Card>
<code class="break-all">
{connectionURI() || ""}
</code>
</Card>
</Show>
<Button onClick={toggleNwc}>
{state.nwc_enabled ? "Disable" : "Enable"}
</Button>
</Dialog.Description>
</Dialog.Content>
</div>
</Dialog.Portal>
</Dialog.Root>
</InnerCard>
);
}

View File

@@ -83,7 +83,7 @@ export function OnboardWarning() {
intent="blue"
layout="xs"
class="self-auto"
href="/backup"
href="/settings/backup"
>
Backup
</ButtonLink>

View File

@@ -1,109 +0,0 @@
import { createForm, url } from "@modular-forms/solid";
import { TextField } from "~/components/layout/TextField";
import {
MutinyWalletSettingStrings,
getExistingSettings,
setAndGetMutinySettings
} from "~/logic/mutinyWalletSetup";
import { Button, Card, NiceP } from "~/components/layout";
import { showToast } from "./Toaster";
import eify from "~/utils/eify";
import { ExternalLink } from "./layout/ExternalLink";
export function SettingsStringsEditor() {
const existingSettings = getExistingSettings();
const [settingsForm, { Form, Field }] =
createForm<MutinyWalletSettingStrings>({
initialValues: existingSettings
});
async function handleSubmit(values: MutinyWalletSettingStrings) {
try {
const newSettings = { ...existingSettings, ...values };
await setAndGetMutinySettings(newSettings);
window.location.reload();
} catch (e) {
console.error(e);
showToast(eify(e));
}
console.log(values);
}
return (
<Card title="Servers">
<Form onSubmit={handleSubmit} class="flex flex-col gap-4">
<NiceP>
Don't trust us! Use your own servers to back Mutiny.
</NiceP>
<ExternalLink href="https://github.com/MutinyWallet/mutiny-web/wiki/Self-hosting">
Learn more about self-hosting
</ExternalLink>
<div />
<Field
name="proxy"
validate={[url("Should be a url starting with wss://")]}
>
{(field, props) => (
<TextField
{...props}
value={field.value}
error={field.error}
label="Websockets Proxy"
caption="How your lightning node communicates with the rest of the network."
/>
)}
</Field>
<Field
name="esplora"
validate={[url("That doesn't look like a URL")]}
>
{(field, props) => (
<TextField
{...props}
value={field.value}
error={field.error}
label="Esplora"
caption="Block data for on-chain information."
/>
)}
</Field>
<Field
name="rgs"
validate={[url("That doesn't look like a URL")]}
>
{(field, props) => (
<TextField
{...props}
value={field.value}
error={field.error}
label="RGS"
caption="Rapid Gossip Sync. Network data about the lightning network used for routing."
/>
)}
</Field>
<Field
name="lsp"
validate={[url("That doesn't look like a URL")]}
>
{(field, props) => (
<TextField
{...props}
value={field.value}
error={field.error}
label="LSP"
caption="Lightning Service Provider. Automatically opens channels to you for inbound liquidity. Also wraps invoices for privacy."
/>
)}
</Field>
<div />
<Button
type="submit"
disabled={!settingsForm.dirty}
intent="blue"
>
Save
</Button>
</Form>
</Card>
);
}

View File

@@ -60,6 +60,22 @@ export const FancyCard: ParentComponent<{
);
};
export const SettingsCard: ParentComponent<{
title?: string;
}> = (props) => {
return (
<VStack smallgap>
<div class="mt-2 pl-4">
<SmallHeader>{props.title}</SmallHeader>
</div>
<div class="rounded-xl py-4 flex flex-col gap-2 bg-m-grey-800 w-full">
{props.children}
</div>
</VStack>
);
};
export const SafeArea: ParentComponent = (props) => {
return (
<div class="h-[100dvh] safe-left safe-right">