peer connect modal with Dismiss

This commit is contained in:
Paul Miller
2023-04-10 09:02:48 -05:00
parent e52a742fc3
commit 8c6deb171d
9 changed files with 127 additions and 34 deletions

4
.env
View File

@@ -1,3 +1,3 @@
VITE_NETWORK="regtest" VITE_NETWORK="signet"
VITE_PROXY="wss://p.mutinywallet.com" VITE_PROXY="wss://p.mutinywallet.com"
VITE_ESPLORA="http://localhost:3003" VITE_ESPLORA="https://mutinynet.com/api"

View File

@@ -32,6 +32,7 @@
"class-variance-authority": "^0.4.0", "class-variance-authority": "^0.4.0",
"nostr-tools": "^1.8.2", "nostr-tools": "^1.8.2",
"qr-scanner": "^1.4.2", "qr-scanner": "^1.4.2",
"solid-dismiss": "^1.7.11",
"solid-js": "^1.7.2", "solid-js": "^1.7.2",
"solid-qr-code": "^0.0.8", "solid-qr-code": "^0.0.8",
"solid-start": "^0.2.26", "solid-start": "^0.2.26",

11
pnpm-lock.yaml generated
View File

@@ -25,6 +25,9 @@ dependencies:
qr-scanner: qr-scanner:
specifier: ^1.4.2 specifier: ^1.4.2
version: 1.4.2 version: 1.4.2
solid-dismiss:
specifier: ^1.7.11
version: 1.7.11(solid-js@1.7.2)
solid-js: solid-js:
specifier: ^1.7.2 specifier: ^1.7.2
version: 1.7.2 version: 1.7.2
@@ -4387,6 +4390,14 @@ packages:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'} engines: {node: '>=8'}
/solid-dismiss@1.7.11(solid-js@1.7.2):
resolution: {integrity: sha512-JO05u/6Y/s+Is33Hyw4pzTRaTiUG7z3UGqpLY36JaHu9CmUSr7+8IJj6Rp/n8YpIPhjvzmCnMa6HTAZYLbfowA==}
peerDependencies:
solid-js: '1'
dependencies:
solid-js: 1.7.2
dev: false
/solid-js@1.7.2: /solid-js@1.7.2:
resolution: {integrity: sha512-01f8GIc+HTTlfDXtK+TFku3AllHyJ3hNsIpxM2qpObRP4VbEGVIP6VbULnThPlpse+J1y/I/1N9QeQ9MNkE8Ow==} resolution: {integrity: sha512-01f8GIc+HTTlfDXtK+TFku3AllHyJ3hNsIpxM2qpObRP4VbEGVIP6VbULnThPlpse+J1y/I/1N9QeQ9MNkE8Ow==}
dependencies: dependencies:

View File

@@ -3,9 +3,13 @@ import { Motion, Presence } from "@motionone/solid";
import logo from '~/assets/icons/mutiny-logo.svg'; import logo from '~/assets/icons/mutiny-logo.svg';
import send from '~/assets/icons/send.svg'; import send from '~/assets/icons/send.svg';
import BalanceBox from "./BalanceBox"; import BalanceBox from "~/components/BalanceBox";
import SafeArea from "./SafeArea"; import SafeArea from "~/components/SafeArea";
import NavBar from "./NavBar"; import NavBar from "~/components/NavBar";
import Card from "~/components/Card";
import { Button, ButtonLink } from "~/components/Button";
import Modal from "./Modal";
import PeerConnectModal from "./PeerConnectModal";
// TODO: use this reload prompt for real // TODO: use this reload prompt for real
// import ReloadPrompt from "./Reload"; // import ReloadPrompt from "./Reload";
@@ -33,30 +37,11 @@ export default function App() {
</header> </header>
{/* <ReloadPrompt /> */} {/* <ReloadPrompt /> */}
<BalanceBox /> <BalanceBox />
<div class='rounded-xl p-4 flex flex-col gap-2 bg-[rgba(0,0,0,0.5)]'> <Card title="Kitchen Sink">
<header class='text-sm font-semibold uppercase'> <PeerConnectModal />
Activity <ButtonLink target="_blank" rel="noopener noreferrer" href="https://faucet.mutinynet.com/?address=abc123">Tap the Faucet</ButtonLink>
</header> </Card>
<For each={[1, 2, 3, 4]}>
{() =>
<Presence>
<Motion
initial={{ opacity: 0, scaleY: 0 }}
animate={{ opacity: 1, scaleY: 1 }}
exit={{ opacity: 0, scaleY: 0 }}
transition={{ duration: 0.3 }}
>
<ActivityItem />
</Motion>
</Presence>
}
</For>
<div class='flex justify-end py-4'>
<a href="#" class='underline text-sm'>
MORE
</a>
</div>
</div>
{/* safety div */} {/* safety div */}
<div class="h-32" /> <div class="h-32" />
</main> </main>

View File

@@ -13,7 +13,7 @@ function prettyPrintAmount(n?: number | bigint): string {
} }
function prettyPrintBalance(b: MutinyBalance): string { function prettyPrintBalance(b: MutinyBalance): string {
return prettyPrintAmount(b.confirmed.valueOf() + b.lightning.valueOf()) return prettyPrintAmount(b.confirmed.valueOf() + b.lightning.valueOf() + b.unconfirmed.valueOf())
} }
export default function BalanceBox() { export default function BalanceBox() {

View File

@@ -1,5 +1,6 @@
import { cva, VariantProps } from "class-variance-authority"; import { cva, VariantProps } from "class-variance-authority";
import { children, JSX, ParentComponent, splitProps } from "solid-js"; import { children, JSX, ParentComponent, splitProps } from "solid-js";
import { Dynamic } from "solid-js/web";
import { A } from "solid-start"; import { A } from "solid-start";
const button = cva(["p-4", "rounded-xl", "text-xl", "font-semibold"], { const button = cva(["p-4", "rounded-xl", "text-xl", "font-semibold"], {
@@ -23,7 +24,6 @@ const button = cva(["p-4", "rounded-xl", "text-xl", "font-semibold"], {
}, },
}); });
// Help from https://github.com/arpadgabor/credee/blob/main/packages/www/src/components/ui/button.tsx // Help from https://github.com/arpadgabor/credee/blob/main/packages/www/src/components/ui/button.tsx
type StyleProps = VariantProps<typeof button> type StyleProps = VariantProps<typeof button>
@@ -49,15 +49,20 @@ export const Button: ParentComponent<ButtonProps> = props => {
interface ButtonLinkProps extends JSX.ButtonHTMLAttributes<HTMLAnchorElement>, StyleProps { interface ButtonLinkProps extends JSX.ButtonHTMLAttributes<HTMLAnchorElement>, StyleProps {
href: string href: string
target?: string
rel?: string
} }
export const ButtonLink: ParentComponent<ButtonLinkProps> = props => { export const ButtonLink: ParentComponent<ButtonLinkProps> = props => {
const slot = children(() => props.children) const slot = children(() => props.children)
const [local, attrs] = splitProps(props, ['children', 'intent', 'layout', 'class', 'href']) const [local, attrs] = splitProps(props, ['children', 'intent', 'layout', 'class', 'href', 'target', 'rel'])
return ( return (
<A <Dynamic
component={local.href?.includes('://') ? 'a' : A}
href={local.href} href={local.href}
target={local.target}
rel={local.rel}
{...attrs} {...attrs}
class={button({ class={button({
class: `flex justify-center no-underline ${local.class || ""}`, class: `flex justify-center no-underline ${local.class || ""}`,
@@ -66,6 +71,6 @@ export const ButtonLink: ParentComponent<ButtonLinkProps> = props => {
})} })}
> >
{slot()} {slot()}
</A> </Dynamic>
) )
} }

13
src/components/Card.tsx Normal file
View File

@@ -0,0 +1,13 @@
import { ParentComponent } from "solid-js"
const Card: ParentComponent<{ title?: string }> = (props) => {
return (
<div class='rounded-xl p-4 flex flex-col gap-2 bg-[rgba(0,0,0,0.5)]'>
{props.title && <header class='text-sm font-semibold uppercase'>{props.title}</header>}
{props.children}
</div>
)
}
export default Card

59
src/components/Modal.tsx Normal file
View File

@@ -0,0 +1,59 @@
import { ParentComponent, createSignal } from "solid-js";
import Dismiss from "solid-dismiss";
import { Motion, Presence } from "@motionone/solid";
import { Button } from "./Button";
const ModalToggleScrollbar: ParentComponent = (props) => {
const [open, setOpen] = createSignal(false);
let btnEl!: HTMLButtonElement;
let btnSaveEl!: HTMLButtonElement;
const onClickClose = () => {
setOpen(false);
};
const onClickOverlay = (e: Event) => {
if (e.target !== e.currentTarget) return;
setOpen(false);
};
// TODO: scrollbar toggle is a think if we're experiencing visual jank
// https://github.com/aquaductape/solid-dismiss/blob/main/demo/src/components/Examples/ModalToggleScrollbar.tsx
return (
<>
<Button ref={btnEl}>
Show Peer Connect Info
</Button>
<Dismiss
menuButton={btnEl}
open={open}
setOpen={setOpen}
modal
focusElementOnOpen={() => btnSaveEl}
>
<Presence>
<Motion
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.2 }}
>
<div
class={"fixed top-0 left-0 w-full h-full flex justify-center items-center z-50 bg-black/50"}
onClick={onClickOverlay}
role="presentation"
>
<div class={"relative w-[80vw] max-w-[800px] p-4 bg-gray shadow-xl rounded-xl border border-white"} role="dialog" aria-modal="true" tabindex="-1">
{props.children}
</div>
</div>
</Motion>
</Presence>
</Dismiss >
</>
);
};
export default ModalToggleScrollbar;

View File

@@ -0,0 +1,19 @@
import { QRCodeSVG } from "solid-qr-code";
import Modal from "./Modal";
import Card from "./Card";
export default function PeerConnectModal() {
const connectString = "mutiny:02a91f8d620f5635a65a5f0cf51279ad9f73fd30f1bfdb4739342deddfba32fb7d@p.mutinywallet.com"
return (
<Modal>
<div class="flex flex-col gap-4">
<div class="w-full bg-white rounded-xl">
<QRCodeSVG value={connectString} class="w-full h-full p-8 max-h-[400px]" />
</div>
<Card>
<code class="break-all">{connectString}</code>
</Card>
</div>
</Modal>
)
}