Split modals out into separate components

This commit is contained in:
Jon Staab
2024-10-15 15:13:11 -07:00
parent cbf3d3566f
commit 4decb2f4d9
4 changed files with 79 additions and 100 deletions

View File

@@ -0,0 +1,17 @@
<script lang="ts">
import {pubkey} from '@welshman/app'
import Landing from "@app/components/Landing.svelte"
import Toast from "@app/components/Toast.svelte"
import PrimaryNav from "@app/components/PrimaryNav.svelte"
</script>
<div class="flex h-screen overflow-hidden">
<PrimaryNav>
{#if $pubkey}
<slot />
{:else}
<Landing />
{/if}
</PrimaryNav>
</div>
<Toast />

View File

@@ -0,0 +1,56 @@
<script lang="ts">
import {onMount} from 'svelte'
import type {SvelteComponent} from "svelte"
import {page} from "$app/stores"
import {fly} from "@lib/transition"
import Drawer from "@lib/components/Drawer.svelte"
import {modals} from "@app/modal"
import Toast from "@app/components/Toast.svelte"
let prev: any
let mounted = false
let dialog: HTMLDialogElement
let drawer: SvelteComponent
$: hash = $page.url.hash.slice(1)
$: modal = modals.get(hash)
$: prev = modal || prev
$: {
if (mounted) {
if (modal?.options?.drawer) {
drawer.open()
} else if (modal) {
dialog.showModal()
} else {
drawer.close()
dialog.close()
}
}
}
onMount(() => {
mounted = true
})
</script>
<dialog bind:this={dialog} class="modal modal-bottom !z-modal sm:modal-middle">
{#if modal && !modal.options?.drawer}
{#key hash}
<div class="bg-alt modal-box overflow-visible overflow-y-auto" transition:fly={{duration: 100}}>
<svelte:component this={modal.component} {...modal.props} />
</div>
{/key}
<Toast />
{/if}
<form method="dialog" class="modal-backdrop">
<button />
</form>
</dialog>
<Drawer bind:this={drawer}>
{#if modal && modal.options?.drawer}
{#key hash}
<svelte:component this={modal.component} {...modal.props} />
{/key}
{/if}
</Drawer>

View File

@@ -1,10 +0,0 @@
<script lang="ts">
import {fly} from "@lib/transition"
export let component
export let props = {}
</script>
<div class="bg-alt modal-box overflow-visible overflow-y-auto" transition:fly={{duration: 100}}>
<svelte:component this={component} {...props} />
</div>

View File

@@ -1,7 +1,6 @@
<script lang="ts"> <script lang="ts">
import "@src/app.css" import "@src/app.css"
import {onMount} from "svelte" import {onMount} from "svelte"
import type {SvelteComponent} from "svelte"
import {get} from "svelte/store" import {get} from "svelte/store"
import {page} from "$app/stores" import {page} from "$app/stores"
import {goto} from "$app/navigation" import {goto} from "$app/navigation"
@@ -38,40 +37,15 @@
import * as lib from "@welshman/lib" import * as lib from "@welshman/lib"
import * as util from "@welshman/util" import * as util from "@welshman/util"
import * as app from "@welshman/app" import * as app from "@welshman/app"
import ModalBox from "@lib/components/ModalBox.svelte" import AppContainer from "@app/components/AppContainer.svelte"
import Drawer from "@lib/components/Drawer.svelte" import ModalContainer from "@app/components/ModalContainer.svelte"
import Toast from "@app/components/Toast.svelte"
import Landing from "@app/components/Landing.svelte"
import PrimaryNav from "@app/components/PrimaryNav.svelte"
import {modals, clearModal} from "@app/modal" import {modals, clearModal} from "@app/modal"
import {theme} from "@app/theme" import {theme} from "@app/theme"
import {INDEXER_RELAYS} from "@app/state" import {INDEXER_RELAYS} from "@app/state"
import {loadUserData} from "@app/commands" import {loadUserData} from "@app/commands"
import * as state from "@app/state" import * as state from "@app/state"
const subs: any[] = []
const onDialogClose = (e: Event) => {
if (!$session) {
e.preventDefault()
// Prevent default doesn't always work, just re-open when needed
setTimeout(() => dialog.showModal())
} else if (modal) {
clearModal()
}
}
const onDrawerClose = (e: any) => {
if (!e.target.checked) {
clearModal()
}
}
let ready: Promise<unknown> = Promise.resolve() let ready: Promise<unknown> = Promise.resolve()
let dialog: HTMLDialogElement
let drawer: SvelteComponent
let modal: any
onMount(() => { onMount(() => {
Object.assign(window, {get, ...lib, ...util, ...app, ...state}) Object.assign(window, {get, ...lib, ...util, ...app, ...state})
@@ -163,37 +137,6 @@
loadUserData($pubkey) loadUserData($pubkey)
} }
} }
ready.then(async () => {
await sleep(1)
subs.push(
page.subscribe($page => {
modal = modals.get($page.url.hash.slice(1))
if (!$session && !modal) {
modal = {component: Landing}
}
if (modal) {
if (modal.options?.drawer) {
drawer.open()
} else {
dialog.showModal()
}
} else if ($session) {
drawer?.close()
dialog?.close()
}
})
)
})
return () => {
for (const unsub of subs) {
unsub()
}
}
}) })
</script> </script>
@@ -201,36 +144,9 @@
<div data-theme={$theme} /> <div data-theme={$theme} />
{:then} {:then}
<div data-theme={$theme}> <div data-theme={$theme}>
<div class="flex h-screen overflow-hidden"> <AppContainer>
<PrimaryNav> <slot />
{#if $pubkey} </AppContainer>
<slot /> <ModalContainer />
{/if}
</PrimaryNav>
</div>
<dialog
bind:this={dialog}
on:cancel={onDialogClose}
class="modal modal-bottom !z-modal sm:modal-middle">
{#if modal && !modal.options?.drawer}
{#key modal}
<ModalBox {...modal} />
{/key}
<Toast />
{/if}
{#if $session}
<form method="dialog" class="modal-backdrop">
<button />
</form>
{/if}
</dialog>
<Drawer bind:this={drawer} on:change={onDrawerClose}>
{#if modal && modal.options?.drawer}
{#key modal}
<svelte:component this={modal.component} {...modal.props} />
{/key}
{/if}
</Drawer>
<Toast />
</div> </div>
{/await} {/await}