use kobalte dialog for modal instead

This commit is contained in:
Paul Miller
2023-04-10 10:29:08 -05:00
parent 8c6deb171d
commit c93e0e8332
6 changed files with 192 additions and 104 deletions

View File

@@ -24,6 +24,7 @@
"workbox-window": "^6.5.4"
},
"dependencies": {
"@kobalte/core": "^0.8.2",
"@motionone/solid": "^10.16.0",
"@mutinywallet/node-manager": "^0.2.2",
"@nostr-dev-kit/ndk": "^0.0.13",
@@ -32,7 +33,6 @@
"class-variance-authority": "^0.4.0",
"nostr-tools": "^1.8.2",
"qr-scanner": "^1.4.2",
"solid-dismiss": "^1.7.11",
"solid-js": "^1.7.2",
"solid-qr-code": "^0.0.8",
"solid-start": "^0.2.26",

130
pnpm-lock.yaml generated
View File

@@ -1,6 +1,9 @@
lockfileVersion: '6.0'
dependencies:
'@kobalte/core':
specifier: ^0.8.2
version: 0.8.2(solid-js@1.7.2)
'@motionone/solid':
specifier: ^10.16.0
version: 10.16.0(solid-js@1.7.2)
@@ -25,9 +28,6 @@ dependencies:
qr-scanner:
specifier: ^1.4.2
version: 1.4.2
solid-dismiss:
specifier: ^1.7.11
version: 1.7.11(solid-js@1.7.2)
solid-js:
specifier: ^1.7.2
version: 1.7.2
@@ -1424,6 +1424,16 @@ packages:
resolution: {integrity: sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
/@floating-ui/core@1.2.6:
resolution: {integrity: sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg==}
dev: false
/@floating-ui/dom@1.2.6:
resolution: {integrity: sha512-02vxFDuvuVPs22iJICacezYJyf7zwwOCWkPNkWNBr1U0Qt1cKFYzWvxts0AmqcOQGwt/3KJWcWIgtbUU38keyw==}
dependencies:
'@floating-ui/core': 1.2.6
dev: false
/@hapi/hoek@9.3.0:
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==}
@@ -1449,6 +1459,24 @@ packages:
/@humanwhocodes/object-schema@1.2.1:
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
/@internationalized/date@3.2.0:
resolution: {integrity: sha512-VDMHN1m33L4eqPs5BaihzgQJXyaORbMoHOtrapFxx179J8ucY5CRIHYsq5RRLKPHZWgjNfa5v6amWWDkkMFywA==}
dependencies:
'@swc/helpers': 0.4.14
dev: false
/@internationalized/number@3.2.0:
resolution: {integrity: sha512-GUXkhXSX1Ee2RURnzl+47uvbOxnlMnvP9Er+QePTjDjOPWuunmLKlEkYkEcLiiJp7y4l9QxGDLOlVr8m69LS5w==}
dependencies:
'@swc/helpers': 0.4.14
dev: false
/@internationalized/string@3.1.0:
resolution: {integrity: sha512-TJQKiyUb+wyAfKF59UNeZ/kELMnkxyecnyPCnBI1ma4NaXReJW+7Cc2mObXAqraIBJUVv7rgI46RLKrLgi35ng==}
dependencies:
'@swc/helpers': 0.4.14
dev: false
/@jridgewell/gen-mapping@0.1.1:
resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==}
engines: {node: '>=6.0.0'}
@@ -1487,6 +1515,33 @@ packages:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.14
/@kobalte/core@0.8.2(solid-js@1.7.2):
resolution: {integrity: sha512-EoBYKpYa3+Csr5Zh7l3aY3yAg7fk1O3ZM9lGyD1mdQ1FutTuwTkyj8z1CvSSj1Klb+rBL+X1N662Occ8Bmsi2w==}
peerDependencies:
solid-js: ^1.6.15
dependencies:
'@floating-ui/dom': 1.2.6
'@internationalized/date': 3.2.0
'@internationalized/number': 3.2.0
'@internationalized/string': 3.1.0
'@kobalte/utils': 0.6.1(solid-js@1.7.2)
solid-js: 1.7.2
dev: false
/@kobalte/utils@0.6.1(solid-js@1.7.2):
resolution: {integrity: sha512-YvBqe9t9j0iYFUHfKXSMLQKM3s5+nL72RvT9b75W+IOxUpSpN4rdaI8C2j97k3LsEt7qY4ktJdt8lPM1rr8JXw==}
peerDependencies:
solid-js: ^1.6.12
dependencies:
'@solid-primitives/event-listener': 2.2.10(solid-js@1.7.2)
'@solid-primitives/keyed': 1.1.10(solid-js@1.7.2)
'@solid-primitives/media': 2.1.6(solid-js@1.7.2)
'@solid-primitives/props': 3.1.4(solid-js@1.7.2)
'@solid-primitives/refs': 1.0.2(solid-js@1.7.2)
'@solid-primitives/utils': 5.5.2(solid-js@1.7.2)
solid-js: 1.7.2
dev: false
/@motionone/animation@10.15.1:
resolution: {integrity: sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==}
dependencies:
@@ -1771,6 +1826,35 @@ packages:
/@sideway/pinpoint@2.0.0:
resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==}
/@solid-primitives/event-listener@2.2.10(solid-js@1.7.2):
resolution: {integrity: sha512-rWBCeF1NRAmLJtVo2wpY9vF3IAQ8VAxGnFDOUqROSdYhUfiCeM7Hw3PKkGCELwNQzZK1W1z+MjzB7fctpjX4Sg==}
peerDependencies:
solid-js: ^1.6.12
dependencies:
'@solid-primitives/utils': 6.0.0(solid-js@1.7.2)
solid-js: 1.7.2
dev: false
/@solid-primitives/keyed@1.1.10(solid-js@1.7.2):
resolution: {integrity: sha512-J3TI4hL+C5Btc078BvlebUbUf0GQP3b/1fGfBHzfdgK32dTBsZsxCk/qU1IP03b6VJFkNteeVhK9pPeUARk80g==}
peerDependencies:
solid-js: ^1.6.12
dependencies:
solid-js: 1.7.2
dev: false
/@solid-primitives/media@2.1.6(solid-js@1.7.2):
resolution: {integrity: sha512-7yixsXmhZfbsAxk/glmTFWcacXhudYsbc/9kbC7EbaE+Jnd6i0HZmmQEkV+s/rZ32e5sE9dAHvlhPtiLbQb7Jg==}
peerDependencies:
solid-js: ^1.6.12
dependencies:
'@solid-primitives/event-listener': 2.2.10(solid-js@1.7.2)
'@solid-primitives/rootless': 1.3.2(solid-js@1.7.2)
'@solid-primitives/static-store': 0.0.2(solid-js@1.7.2)
'@solid-primitives/utils': 6.0.0(solid-js@1.7.2)
solid-js: 1.7.2
dev: false
/@solid-primitives/props@3.1.4(solid-js@1.7.2):
resolution: {integrity: sha512-RiwOZXbqb3RMmkznyfI63gwAB/iVHPk8AWN55oIEBRkjzgpuqRXIzdbsSQVy23jMbkRs91tRtzxQ/g6eoWLnuQ==}
peerDependencies:
@@ -1789,6 +1873,24 @@ packages:
solid-js: 1.7.2
dev: false
/@solid-primitives/rootless@1.3.2(solid-js@1.7.2):
resolution: {integrity: sha512-R1rncXOUcB/i3PyvKhSWcsocPRe1n3HsMIO717RpWFd2knUF8+b0cGgRDEoneGaV/a5kq4cqH3csa66klxuM3A==}
peerDependencies:
solid-js: ^1.6.12
dependencies:
'@solid-primitives/utils': 6.0.0(solid-js@1.7.2)
solid-js: 1.7.2
dev: false
/@solid-primitives/static-store@0.0.2(solid-js@1.7.2):
resolution: {integrity: sha512-JR51MmoZbFWE7fmzm0NnfS4RuLHpzXpPqAb7RJu3fHDGHp+q7v4KylseULcailINzDIosHQXbpiDQlj2Lx9zbQ==}
peerDependencies:
solid-js: ^1.6.12
dependencies:
'@solid-primitives/utils': 6.0.0(solid-js@1.7.2)
solid-js: 1.7.2
dev: false
/@solid-primitives/transition-group@1.0.1(solid-js@1.7.2):
resolution: {integrity: sha512-StVQs7BVGQa1uo6dD19wqOgfGMxu3gL/bvPHUV/NBJaiNX5R5e7dPb6lz6zR1RdTho3M+3Mv8jUHKd/aKuhL4w==}
peerDependencies:
@@ -1797,6 +1899,14 @@ packages:
solid-js: 1.7.2
dev: false
/@solid-primitives/utils@5.5.2(solid-js@1.7.2):
resolution: {integrity: sha512-L52ig3eHKU6CqbPCKJIb4lweBuINHBOERcE1duApyKozEN8+zCqEKwD1Qo9ljKeEzJTBGWClxNpwEiNTUWTGvg==}
peerDependencies:
solid-js: ^1.6.12
dependencies:
solid-js: 1.7.2
dev: false
/@solid-primitives/utils@6.0.0(solid-js@1.7.2):
resolution: {integrity: sha512-SSu12+vvU6J8SVWW9eGV+dqiMsc0WG1Oy8YYY9AWzRzssmzNXg/uexaW+0eqTuj8JcRAaGplMDjhraB01HOidA==}
peerDependencies:
@@ -1828,6 +1938,12 @@ packages:
string.prototype.matchall: 4.0.8
dev: true
/@swc/helpers@0.4.14:
resolution: {integrity: sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==}
dependencies:
tslib: 2.5.0
dev: false
/@types/babel__core@7.20.0:
resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==}
dependencies:
@@ -4390,14 +4506,6 @@ packages:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
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:
resolution: {integrity: sha512-01f8GIc+HTTlfDXtK+TFku3AllHyJ3hNsIpxM2qpObRP4VbEGVIP6VbULnThPlpse+J1y/I/1N9QeQ9MNkE8Ow==}
dependencies:

View File

@@ -1,33 +1,14 @@
import { For } from "solid-js";
import { Motion, Presence } from "@motionone/solid";
import logo from '~/assets/icons/mutiny-logo.svg';
import send from '~/assets/icons/send.svg';
import BalanceBox from "~/components/BalanceBox";
import SafeArea from "~/components/SafeArea";
import NavBar from "~/components/NavBar";
import Card from "~/components/Card";
import { Button, ButtonLink } from "~/components/Button";
import Modal from "./Modal";
import { ButtonLink } from "~/components/Button";
import PeerConnectModal from "./PeerConnectModal";
// TODO: use this reload prompt for real
// import ReloadPrompt from "./Reload";
function ActivityItem() {
return (
<div class="flex flex-row border-b border-gray-500 gap-4 py-2">
<img src={send} class="App-logo" alt="logo" />
<div class='flex flex-col flex-1'>
<h1>Bitcoin Beefsteak</h1>
<h2>-1,441,851 SAT</h2>
<h3 class='text-sm text-gray-500'>Jul 24</h3>
</div>
<div class='text-sm font-semibold uppercase text-[#E23A5E]'>SEND</div>
</div>
)
}
export default function App() {
return (
<SafeArea>
@@ -41,7 +22,6 @@ export default function App() {
<PeerConnectModal />
<ButtonLink target="_blank" rel="noopener noreferrer" href="https://faucet.mutinynet.com/?address=abc123">Tap the Faucet</ButtonLink>
</Card>
{/* safety div */}
<div class="h-32" />
</main>

View File

@@ -1,59 +0,0 @@
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

@@ -1,19 +1,65 @@
import { QRCodeSVG } from "solid-qr-code";
import Modal from "./Modal";
import Card from "./Card";
import { As, Dialog } from "@kobalte/core";
import { Button } from "./Button";
import { useMegaStore } from "~/state/megaStore";
import { Show, createResource } from "solid-js";
import { getExistingSettings } from "~/logic/nodeManagerSetup";
import getHostname from "~/utils/getHostname";
export default function PeerConnectModal() {
const connectString = "mutiny:02a91f8d620f5635a65a5f0cf51279ad9f73fd30f1bfdb4739342deddfba32fb7d@p.mutinywallet.com"
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] 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 PeerConnectModalKobalte() {
const [state, _] = useMegaStore()
const getPeerConnectString = async () => {
if (state.node_manager) {
const { proxy } = getExistingSettings();
const nodes = await state.node_manager.list_nodes();
const firstNode = nodes[0] as string || ""
const hostName = getHostname(proxy || "")
const connectString = `mutiny:${firstNode}@${hostName}`
return connectString
} else {
return undefined
}
};
const [peerConnectString] = createResource(getPeerConnectString);
// TODO: a lot of this markup is probably reusable as a "Modal" component
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]" />
<Dialog.Root>
<Dialog.Trigger asChild>
<As component={Button}>Show Peer Connect Info</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}>Peer connect info</Dialog.Title>
<Dialog.CloseButton class="dialog__close-button">
<code>X</code>
</Dialog.CloseButton>
</div>
<Dialog.Description class="flex flex-col gap-4">
<Show when={peerConnectString()}>
<div class="w-full bg-white rounded-xl">
<QRCodeSVG value={peerConnectString() || ""} class="w-full h-full p-8 max-h-[400px]" />
</div>
<Card>
<code class="break-all">{peerConnectString() || ""}</code>
</Card>
</Show>
</Dialog.Description>
</Dialog.Content>
</div>
<Card>
<code class="break-all">{connectString}</code>
</Card>
</div>
</Modal>
</Dialog.Portal>
</Dialog.Root >
)
}

13
src/utils/getHostname.ts Normal file
View File

@@ -0,0 +1,13 @@
export default function getHostname(url: string): string {
// Check if the URL begins with "ws://" or "wss://"
if (url.startsWith("ws://")) {
// If it does, remove "ws://" from the URL
url = url.slice(5);
} else if (url.startsWith("wss://")) {
// If it begins with "wss://", remove "wss://" from the URL
url = url.slice(6);
}
// Return the resulting URL
return url;
}