Re work modal scrolling

This commit is contained in:
Jon Staab 2026-01-30 14:14:12 -08:00
parent 4169db33e6
commit 38c0a9d403
75 changed files with 2340 additions and 2030 deletions

View file

@ -2,6 +2,7 @@
import type {Snippet} from "svelte"
import {page} from "$app/stores"
import {pubkey} from "@welshman/app"
import Dialog from "@lib/components/Dialog.svelte"
import Landing from "@app/components/Landing.svelte"
import Toast from "@app/components/Toast.svelte"
import PrimaryNav from "@app/components/PrimaryNav.svelte"
@ -20,7 +21,7 @@
{@render children?.()}
</PrimaryNav>
{:else if !$modals[$page.url.hash.slice(1)]}
<Landing />
<Dialog children={{component: Landing, props: {}}} />
{/if}
</div>
<Toast />

View file

@ -14,6 +14,8 @@
import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import DateTimeInput from "@lib/components/DateTimeInput.svelte"
import EditorContent from "@app/editor/EditorContent.svelte"
import {PROTECTED} from "@app/core/state"
@ -114,7 +116,8 @@
})
</script>
<form novalidate class="column gap-4" onsubmit={preventDefault(submit)}>
<Modal tag="form" novalidate onsubmit={preventDefault(submit)}>
<ModalBody>
{@render header()}
<Field>
{#snippet label()}
@ -131,7 +134,8 @@
<p>Summary</p>
{/snippet}
{#snippet input()}
<div class="relative z-feature flex gap-2 border-t border-solid border-base-100 bg-base-100">
<div
class="relative z-feature flex gap-2 border-t border-solid border-base-100 bg-base-100">
<div class="input-editor flex-grow overflow-hidden">
<EditorContent {editor} />
</div>
@ -172,6 +176,7 @@
</label>
{/snippet}
</Field>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -181,4 +186,4 @@
<Spinner loading={$uploading}>Save Event</Spinner>
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -7,6 +7,8 @@
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {PLATFORM_NAME} from "@app/core/state"
@ -33,7 +35,8 @@
const back = () => history.back()
</script>
<form class="column gap-4" onsubmit={preventDefault(submit)}>
<Modal tag="form" onsubmit={preventDefault(submit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Enable Messages</div>
@ -47,9 +50,10 @@
{PLATFORM_NAME} to download and decrypt a lot of data.
</p>
<p>
If you'd like to enable them, please make sure your signer is set up to to auto-approve requests
to decrypt data.
If you'd like to enable them, please make sure your signer is set up to to auto-approve
requests to decrypt data.
</p>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -60,4 +64,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -1,6 +1,9 @@
<script lang="ts">
import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import Profile from "@app/components/Profile.svelte"
interface Props {
@ -10,7 +13,8 @@
const {pubkeys}: Props = $props()
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>People in this conversation</div>
@ -21,5 +25,8 @@
<Profile {pubkey} />
</div>
{/each}
</ModalBody>
<ModalFooter>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
</div>
</ModalFooter>
</Modal>

View file

@ -11,6 +11,8 @@
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import ProfileMultiSelect from "@app/components/ProfileMultiSelect.svelte"
@ -52,7 +54,8 @@
})
</script>
<form class="column gap-4" onsubmit={preventDefault(onSubmit)}>
<Modal tag="form" onsubmit={preventDefault(onSubmit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Start a Chat</div>
@ -66,6 +69,7 @@
<ProfileMultiSelect autofocus bind:value={pubkeys} {term} />
{/snippet}
</Field>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -76,4 +80,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -11,6 +11,8 @@
import Icon from "@lib/components/Icon.svelte"
import FieldInline from "@lib/components/FieldInline.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import {clip} from "@app/util/toast"
@ -36,7 +38,8 @@
})
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Event Details</div>
@ -106,4 +109,5 @@
</p>
</div>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
</div>
</ModalBody>
</Modal>

View file

@ -9,6 +9,8 @@
import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import RoomName from "@app/components/RoomName.svelte"
import {roomsByUrl} from "@app/core/state"
import {makeRoomPath} from "@app/util/routes"
@ -29,7 +31,8 @@
let selection = $state("")
</script>
<form class="column gap-4" onsubmit={preventDefault(onSubmit)}>
<Modal tag="form" onsubmit={preventDefault(onSubmit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Share {noun}</div>
@ -50,6 +53,7 @@
</button>
{/each}
</div>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -60,4 +64,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -12,6 +12,8 @@
import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import EditorContent from "@app/editor/EditorContent.svelte"
import {pushToast} from "@app/util/toast"
import {PROTECTED} from "@app/core/state"
@ -82,7 +84,8 @@
let amount = $state(1000)
</script>
<form class="column gap-4" onsubmit={preventDefault(submit)}>
<Modal tag="form" onsubmit={preventDefault(submit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Create a Funding Goal</div>
@ -154,6 +157,7 @@
bind:value={amount} />
</div>
</div>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -161,4 +165,4 @@
</Button>
<Button type="submit" class="btn btn-primary">Create Goal</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -1,11 +1,14 @@
<script lang="ts">
import Link from "@lib/components/Link.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import {PLATFORM_NAME} from "@app/core/state"
</script>
<div class="column gap-4">
<Modal
><ModalBody>
<ModalHeader>
{#snippet title()}
<div>What is a bunker link?</div>
@ -17,9 +20,9 @@
company, and can bring it with them from app to app.
</p>
<p>
A good way to manage your keys is to use a remote signing application. These apps can hold your
keys and log you in remotely to as many applications as you like, without risking loss or theft
of your keys.
A good way to manage your keys is to use a remote signing application. These apps can hold
your keys and log you in remotely to as many applications as you like, without risking loss or
theft of your keys.
</p>
<p>
One way to log in with a remote signer is using a "bunker link" which is more secure and
@ -36,4 +39,4 @@
>.
</p>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
</div>
</ModalBody></Modal>

View file

@ -1,11 +1,14 @@
<script lang="ts">
import Button from "@lib/components/Button.svelte"
import Link from "@lib/components/Link.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import {PLATFORM_NAME} from "@app/core/state"
</script>
<div class="column gap-4">
<Modal
><ModalBody>
<ModalHeader>
{#snippet title()}
<div>What is a nostr address?</div>
@ -26,4 +29,4 @@
>.
</p>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
</div>
</ModalBody></Modal>

View file

@ -5,6 +5,8 @@
import CheckCircle from "@assets/icons/check-circle.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import KeyRecoveryRequest from "@app/components/KeyRecoveryRequest.svelte"
@ -16,29 +18,37 @@
const startRecoveryRequest = () => pushModal(KeyRecoveryRequest)
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>What is a private key?</div>
{/snippet}
</ModalHeader>
<p>
Most online services keep track of users by giving them a username and password. This gives the
service <strong>total control</strong> over their users, allowing them to ban them at any time, or
sell their activity.
Most online services keep track of users by giving them a username and password. This gives
the service <strong>total control</strong> over their users, allowing them to ban them at any time,
or sell their activity.
</p>
<p>
On <Link external href="https://nostr.com/">Nostr</Link>, <strong>you</strong> control your own
identity and social data, through the magic of cryptography. The basic idea is that you have a
On <Link external href="https://nostr.com/">Nostr</Link>, <strong>you</strong> control your
own identity and social data, through the magic of cryptography. The basic idea is that you
have a
<strong>public key</strong>, which acts as your user ID, and a
<strong>private key</strong> which allows you to prove your identity.
</p>
{#if $session?.email}
<p>
It's very important to keep private keys safe, but this can sometimes be tricky, which is why {PLATFORM_NAME}
It's very important to keep private keys safe, but this can sometimes be tricky, which is
why {PLATFORM_NAME}
supports a traditional account-based login for new users.
</p>
<p>If you'd like to switch to self-custody, please click below to get started.</p>
{:else}
<Button class="btn btn-primary" onclick={back}>Got it</Button>
{/if}
</ModalBody>
{#if $session?.email}
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -49,7 +59,5 @@
I want to hold my own keys
</Button>
</ModalFooter>
{:else}
<Button class="btn btn-primary" onclick={back}>Got it</Button>
{/if}
</div>
</Modal>

View file

@ -1,10 +1,13 @@
<script lang="ts">
import Link from "@lib/components/Link.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
</script>
<div class="column gap-4">
<Modal
><ModalBody>
<ModalHeader>
{#snippet title()}
<div>What is nostr?</div>
@ -27,4 +30,4 @@
<Link external class="link" href="https://nosta.me/">nosta.me</Link>.
</p>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
</div>
</ModalBody></Modal>

View file

@ -2,10 +2,14 @@
import Button from "@lib/components/Button.svelte"
import Link from "@lib/components/Link.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import {PLATFORM_NAME} from "@app/core/state"
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>What is a relay?</div>
@ -15,12 +19,15 @@
{PLATFORM_NAME} hosts spaces on the <Link external href="https://nostr.com/" class="underline"
>Nostr protocol</Link
>. Nostr uses "relays" to host data, which are special-purpose servers that speak nostr's
language. This means that anyone can host their own data, making the web more decentralized and
resilient.
language. This means that anyone can host their own data, making the web more decentralized
and resilient.
</p>
<p>
Different relays have different policies for access control and content retention. Be sure to
double check that you have access to the relays you try to use by visiting their website.
</p>
</ModalBody>
<ModalFooter>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
</div>
</ModalFooter>
</Modal>

View file

@ -1,12 +1,15 @@
<script lang="ts">
import Link from "@lib/components/Link.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
const back = () => history.back()
</script>
<div class="column gap-4">
<Modal
><ModalBody>
<ModalHeader>
{#snippet title()}
<div>What are digital signatures?</div>
@ -20,8 +23,8 @@
</p>
<p>
On <Link external href="https://nostr.com/">Nostr</Link>, all your content is authenticated
using <strong>digital signatures</strong>, which cryptographically tie a particular person to a
given post or message.
using <strong>digital signatures</strong>, which cryptographically tie a particular person to
a given post or message.
</p>
<p>
The result is that you don't normally have to trust service providers not to tamper with the
@ -29,4 +32,4 @@
piece of data is authentic.
</p>
<Button class="btn btn-primary" onclick={back}>Got it</Button>
</div>
</ModalBody></Modal>

View file

@ -5,6 +5,8 @@
import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ProfileLink from "@app/components/ProfileLink.svelte"
const {pubkey} = $props()
@ -14,7 +16,8 @@
const back = () => history.back()
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Unable to Zap</div>
@ -28,10 +31,11 @@
they don't currently have a zap receiver set up.
{/if}
</p>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
Go back
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -10,6 +10,8 @@
import Icon from "@lib/components/Icon.svelte"
import Field from "@lib/components/Field.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {pushToast} from "@app/util/toast"
@ -104,7 +106,8 @@
let didDownload = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(next)}>
<Modal tag="form" onsubmit={preventDefault(next)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Your Keys are Ready!</div>
@ -115,8 +118,8 @@
account, while your <strong>private key</strong> acts sort of like a master password.
</p>
<p>
Securing your private key is very important, so make sure to take the time to save your key in a
secure place (like a password manager).
Securing your private key is very important, so make sure to take the time to save your key in
a secure place (like a password manager).
</p>
{#if usePassword}
<Field>
@ -147,6 +150,7 @@
{/if}
</Button>
</div>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -157,4 +161,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -9,6 +9,8 @@
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import KeyDownload from "@app/components/KeyDownload.svelte"
@ -81,7 +83,8 @@
let input = $state("")
</script>
<form class="column gap-4" onsubmit={preventDefault(submit)}>
<Modal tag="form" onsubmit={preventDefault(submit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
Recover your Key
@ -99,6 +102,7 @@
rows={POMADE_SIGNERS.length + 1}
class="textarea textarea-bordered leading-4"
bind:value={input}></textarea>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -109,4 +113,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -8,6 +8,8 @@
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {pushModal} from "@app/util/modal"
@ -39,7 +41,8 @@
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(submit)}>
<Modal tag="form" onsubmit={preventDefault(submit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
Recover your Key
@ -49,13 +52,14 @@
{/snippet}
</ModalHeader>
<p>
When you signed up, your Nostr secret key was split into multiple pieces and stored on separate
third-party servers to keep it safe.
When you signed up, your Nostr secret key was split into multiple pieces and stored on
separate third-party servers to keep it safe.
</p>
<p>
If you're ready to take control of your cryptographic identity, click below. We'll confirm your
email by sending you some recovery codes.
If you're ready to take control of your cryptographic identity, click below. We'll confirm
your email by sending you some recovery codes.
</p>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -66,4 +70,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -4,7 +4,8 @@
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Link from "@lib/components/Link.svelte"
import Dialog from "@lib/components/Dialog.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import CardButton from "@lib/components/CardButton.svelte"
import LogIn from "@app/components/LogIn.svelte"
import SignUp from "@app/components/SignUp.svelte"
@ -16,8 +17,8 @@
const signUp = () => pushModal(SignUp)
</script>
<Dialog>
<div class="column gap-4">
<Modal>
<ModalBody>
<div class="py-2">
<h1 class="heading">Welcome to {PLATFORM_NAME}!</h1>
<p class="text-center">The chat app built for self-hosted communities.</p>
@ -53,5 +54,5 @@
<Link external class="link" href={PLATFORM_TERMS}>Terms of Service</Link> and
<Link external class="link" href={PLATFORM_PRIVACY}>Privacy Policy</Link>.
</p>
</div>
</Dialog>
</ModalBody>
</Modal>

View file

@ -10,6 +10,8 @@
import Key from "@assets/icons/key.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Link from "@lib/components/Link.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import Button from "@lib/components/Button.svelte"
import SignUp from "@app/components/SignUp.svelte"
import InfoNostr from "@app/components/InfoNostr.svelte"
@ -91,12 +93,13 @@
})
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<h1 class="heading">Log in with Nostr</h1>
<p class="m-auto max-w-sm text-center">
{PLATFORM_NAME} is built using the
<Button class="link" onclick={() => pushModal(InfoNostr)}>nostr protocol</Button>, which allows
you to own your social identity.
<Button class="link" onclick={() => pushModal(InfoNostr)}>nostr protocol</Button>, which
allows you to own your social identity.
</p>
{#if getNip07()}
<Button {disabled} onclick={loginWithNip07} class="btn btn-primary">
@ -157,4 +160,5 @@
Need an account?
<Button class="link" onclick={signUp}>Register instead</Button>
</div>
</div>
</ModalBody>
</Modal>

View file

@ -10,6 +10,8 @@
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import BunkerConnect from "@app/components/BunkerConnect.svelte"
@ -120,7 +122,8 @@
})
</script>
<form class="column gap-4" onsubmit={preventDefault(onSubmit)}>
<Modal tag="form" onsubmit={preventDefault(onSubmit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Log In with a Signer</div>
@ -137,6 +140,7 @@
<Button class="btn {$bunker ? 'btn-neutral' : 'btn-primary'}" onclick={selectConnect}
>Log in with a QR code instead</Button>
{/if}
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={$loading}>
<Icon icon={AltArrowLeft} />
@ -149,4 +153,4 @@
</Button>
{/if}
</ModalFooter>
</form>
</Modal>

View file

@ -10,6 +10,8 @@
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import LogInOTP from "@app/components/LogInOTP.svelte"
@ -67,7 +69,8 @@
let password = $state("")
</script>
<form class="column gap-4" onsubmit={preventDefault(onSubmit)}>
<Modal tag="form" onsubmit={preventDefault(onSubmit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Log In</div>
@ -103,6 +106,7 @@
>Log in with a one-time access code</Button
>.
</p>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} />
@ -113,4 +117,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -13,6 +13,8 @@
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {clearModals} from "@app/util/modal"
@ -71,7 +73,8 @@
}
</script>
<form class="column gap-4" onsubmit={preventDefault(onSubmit)}>
<Modal tag="form" onsubmit={preventDefault(onSubmit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Log In with Key</div>
@ -115,6 +118,7 @@
to keep your keys safe.
</p>
</div>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} />
@ -125,4 +129,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -8,6 +8,8 @@
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import LogInOTPConfirm from "@app/components/LogInOTPConfirm.svelte"
@ -44,7 +46,8 @@
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(onSubmit)}>
<Modal tag="form" onsubmit={preventDefault(onSubmit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Log In</div>
@ -64,6 +67,7 @@
</label>
{/snippet}
</FieldInline>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} />
@ -74,4 +78,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -7,6 +7,8 @@
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {clearModals} from "@app/util/modal"
@ -79,7 +81,8 @@
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(onSubmit)}>
<Modal tag="form" onsubmit={preventDefault(onSubmit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Log In</div>
@ -97,6 +100,7 @@
rows={POMADE_SIGNERS.length + 1}
class="textarea textarea-bordered leading-4"
bind:value={input}></textarea>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} />
@ -107,4 +111,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -4,6 +4,8 @@
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {Push} from "@app/util/notifications"
@ -31,13 +33,15 @@
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(doLogout)}>
<Modal tag="form" onsubmit={preventDefault(doLogout)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Are you sure you want<br />to log out?</div>
{/snippet}
</ModalHeader>
<p class="text-center">Your local database will be cleared.</p>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -47,4 +51,4 @@
<Spinner {loading}>Log Out</Spinner>
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -35,14 +35,7 @@
props: {
onClose: closeModals,
fullscreen: options.fullscreen,
children: createRawSnippet(() => ({
render: () => "<div></div>",
setup: (target: Element) => {
const child = mount(component, {target, props})
return () => unmount(child)
},
})),
children: {component, props},
},
})
}

View file

@ -18,6 +18,8 @@
import Spinner from "@lib/components/Spinner.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import {INDEXER_RELAYS, PLATFORM_NAME, userSpaceUrls} from "@app/core/state"
import {kv, db} from "@app/core/storage"
import {pushToast} from "@app/util/toast"
@ -108,7 +110,8 @@
const back = () => history.back()
</script>
<form class="column gap-4" onsubmit={preventDefault(confirm)}>
<Modal tag="form" onsubmit={preventDefault(confirm)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
Delete your account
@ -122,13 +125,15 @@
We are currently sending deletion requests to your relay selections and space hosts. Please
wait while we complete this process. Once we're done, you'll be automatically logged out.
</p>
<progress class="progress progress-primary w-full" value={progress! * 100} max="100"></progress>
<progress class="progress progress-primary w-full" value={progress! * 100} max="100"
></progress>
{:else}
<p>
This will delete your nostr account everywhere, not just on {PLATFORM_NAME}.
</p>
<p>
To confirm, please type "{CONFIRM_TEXT}" into the text box below. This action can't be undone.
To confirm, please type "{CONFIRM_TEXT}" into the text box below. This action can't be
undone.
</p>
<label class="input input-bordered flex w-full items-center gap-2">
<input bind:value={confirmText} class="grow" type="text" />
@ -138,6 +143,7 @@
content continues to be available, please contact the offending relays directly.
</p>
{/if}
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -148,4 +154,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -15,6 +15,8 @@
import Confirm from "@lib/components/Confirm.svelte"
import Button from "@lib/components/Button.svelte"
import Popover from "@lib/components/Popover.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Profile from "@app/components/Profile.svelte"
import ProfileInfo from "@app/components/ProfileInfo.svelte"
@ -75,6 +77,8 @@
let showMenu = $state(false)
</script>
<Modal>
<ModalBody>
<div class="flex flex-col gap-4">
<div class="flex justify-between">
<Profile showPubkey avatarSize={14} {pubkey} {url} />
@ -112,6 +116,8 @@
</div>
<ProfileInfo {pubkey} {url} />
<ProfileBadges {pubkey} {url} />
</div>
</ModalBody>
<ModalFooter>
<Button onclick={back} class="hidden md:btn md:btn-link">
<Icon icon={AltArrowLeft} />
@ -128,4 +134,4 @@
</Button>
</div>
</ModalFooter>
</div>
</Modal>

View file

@ -8,6 +8,8 @@
import Field from "@lib/components/Field.svelte"
import FieldInline from "@lib/components/FieldInline.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import InputProfilePicture from "@app/components/InputProfilePicture.svelte"
import InfoHandle from "@app/components/InfoHandle.svelte"
import {pushModal} from "@app/util/modal"
@ -33,7 +35,8 @@
let file: File | undefined = $state()
</script>
<form class="col-4" onsubmit={preventDefault(submit)}>
<Modal tag="form" onsubmit={preventDefault(submit)}>
<ModalBody>
{#if isSignup}
<div class="grid grid-cols-2">
<div class="flex flex-col gap-2">
@ -119,5 +122,6 @@
{/snippet}
</FieldInline>
{/if}
</ModalBody>
{@render footer()}
</form>
</Modal>

View file

@ -1,6 +1,9 @@
<script lang="ts">
import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import Profile from "@app/components/Profile.svelte"
interface Props {
@ -13,7 +16,8 @@
const {subtitle = "", pubkeys, url, ...restProps}: Props = $props()
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>{restProps.title}</div>
@ -27,5 +31,8 @@
<Profile {pubkey} {url} />
</div>
{/each}
</ModalBody>
<ModalFooter>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
</div>
</ModalFooter>
</Modal>

View file

@ -9,6 +9,8 @@
import AddCircle from "@assets/icons/add-circle.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import RelayItem from "@app/components/RelayItem.svelte"
interface Props {
@ -39,6 +41,8 @@
})
</script>
<Modal>
<ModalBody>
<label class="input input-bordered flex w-full items-center gap-2">
<Icon icon={Magnifier} />
<input bind:value={term} class="grow" type="text" placeholder="Search for relays..." />
@ -46,7 +50,9 @@
<div class="column -m-6 mt-0 h-[50vh] gap-2 overflow-auto p-6 pt-2" bind:this={element}>
{#if customUrl && isShareableRelayUrl(customUrl) && !$relays.includes(normalizeRelayUrl(customUrl))}
<RelayItem url={term}>
<Button class="btn btn-outline btn-sm flex items-center" onclick={() => addRelay(customUrl)}>
<Button
class="btn btn-outline btn-sm flex items-center"
onclick={() => addRelay(customUrl)}>
<Icon icon={AddCircle} />
Add Relay
</Button>
@ -64,3 +70,5 @@
</RelayItem>
{/each}
</div>
</ModalBody>
</Modal>

View file

@ -8,6 +8,8 @@
import Icon from "@lib/components/Icon.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import {pushToast} from "@app/util/toast"
import {publishReport} from "@app/core/commands"
@ -38,7 +40,8 @@
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(confirm)}>
<Modal tag="form" onsubmit={preventDefault(confirm)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Report Content</div>
@ -78,6 +81,7 @@
<p>Please provide any additional details relevant to your report.</p>
{/snippet}
</Field>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -88,4 +92,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -4,7 +4,10 @@
import {deriveEventsById} from "@welshman/store"
import {repository} from "@welshman/app"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import Button from "@lib/components/Button.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import ReportItem from "@app/components/ReportItem.svelte"
type Props = {
@ -28,7 +31,8 @@
}
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Report Details</div>
@ -42,5 +46,8 @@
<ReportItem {url} event={report} {onDelete} />
</div>
{/each}
</ModalBody>
<ModalFooter>
<Button class="btn btn-primary" onclick={back}>Got it</Button>
</div>
</ModalFooter>
</Modal>

View file

@ -20,6 +20,8 @@
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Confirm from "@lib/components/Confirm.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import ProfileCircles from "@app/components/ProfileCircles.svelte"
import RoomMembers from "@app/components/RoomMembers.svelte"
@ -36,7 +38,11 @@
deriveIsMuted,
MembershipStatus,
} from "@app/core/state"
import {addRoomMembership, removeRoomMembership, toggleRoomNotifications} from "@app/core/commands"
import {
addRoomMembership,
removeRoomMembership,
toggleRoomNotifications,
} from "@app/core/commands"
import {makeSpacePath} from "@app/util/routes"
import {pushModal} from "@app/util/modal"
import {pushToast} from "@app/util/toast"
@ -114,7 +120,8 @@
let loading = $state(false)
</script>
<div class="flex flex-col gap-3">
<Modal>
<ModalBody>
<div class="flex justify-between">
<div class="flex gap-3">
<div class="pt-0.5">
@ -175,24 +182,25 @@
<Icon icon={VolumeLoud} />
<span>Notifications</span>
</div>
<Button
class={cx("btn btn-sm", {"btn-primary": !isMuted, "btn-neutral": isMuted})}
onclick={toggleMute}>
{isMuted ? "Off" : "On"}
</Button>
<input
type="checkbox"
class="toggle toggle-primary"
checked={!isMuted}
onchange={toggleMute} />
</div>
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<Icon icon={Bookmark} />
<span>Favorite</span>
</div>
<Button
class={cx("btn btn-sm", {"btn-primary": isFavorite, "btn-neutral": !isFavorite})}
onclick={toggleFavorite}>
{isFavorite ? "On" : "Off"}
</Button>
<input
type="checkbox"
class="toggle toggle-primary"
checked={isFavorite}
onchange={toggleFavorite} />
</div>
</div>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -234,4 +242,4 @@
{/if}
</div>
</ModalFooter>
</div>
</Modal>

View file

@ -11,6 +11,8 @@
import Icon from "@lib/components/Icon.svelte"
import ImageIcon from "@lib/components/ImageIcon.svelte"
import IconPickerButton from "@lib/components/IconPickerButton.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import {pushToast} from "@app/util/toast"
import {uploadFile} from "@app/core/commands"
@ -105,7 +107,8 @@
}
</script>
<form class="column gap-4" onsubmit={preventDefault(trySubmit)}>
<Modal tag="form" onsubmit={preventDefault(trySubmit)}>
<ModalBody>
{@render header()}
<FieldInline>
{#snippet label()}
@ -177,5 +180,6 @@
<input type="checkbox" class="checkbox" bind:checked={values.isClosed} />
<span class="text-sm opacity-75">Ignore requests to join</span>
</div>
</ModalBody>
{@render footer({loading})}
</form>
</Modal>

View file

@ -9,6 +9,8 @@
import Icon from "@lib/components/Icon.svelte"
import Popover from "@lib/components/Popover.svelte"
import Confirm from "@lib/components/Confirm.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Profile from "@app/components/Profile.svelte"
import RoomName from "@app/components/RoomName.svelte"
@ -59,7 +61,8 @@
let menuPubkey = $state<string | undefined>()
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<div class="flex min-w-0 flex-col gap-1">
<h1 class="ellipsize whitespace-nowrap text-2xl font-bold">Members</h1>
<p class="ellipsize text-sm opacity-75">of <RoomName {url} {h} /></p>
@ -100,10 +103,11 @@
</div>
</div>
{/each}
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
Go back
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -7,6 +7,8 @@
import Icon from "@lib/components/Icon.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import RoomName from "@app/components/RoomName.svelte"
import ProfileMultiSelect from "@app/components/ProfileMultiSelect.svelte"
import {pushToast} from "@app/util/toast"
@ -48,7 +50,8 @@
let pubkeys: string[] = $state([])
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Add Members</div>
@ -65,6 +68,7 @@
<ProfileMultiSelect bind:value={pubkeys} />
{/snippet}
</Field>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -74,4 +78,4 @@
<Spinner {loading}>Save changes</Spinner>
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -15,6 +15,8 @@
import {getKey, setKey} from "@lib/implicit"
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import LogIn from "@app/components/LogIn.svelte"
import InfoNostr from "@app/components/InfoNostr.svelte"
import SignUpKey from "@app/components/SignUpKey.svelte"
@ -92,7 +94,8 @@
}
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<h1 class="heading">Sign up with Nostr</h1>
<p class="m-auto max-w-sm text-center">
{PLATFORM_NAME} is built using the
@ -113,4 +116,5 @@
Already have an account?
<Button class="link" onclick={login}>Log in instead</Button>
</div>
</div>
</ModalBody>
</Modal>

View file

@ -4,6 +4,8 @@
import HomeSmile from "@assets/icons/home-smile.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
@ -16,7 +18,8 @@
const back = () => history.back()
</script>
<form class="column gap-4" onsubmit={preventDefault(next)}>
<Modal tag="form" onsubmit={preventDefault(next)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>You're all set!</div>
@ -27,9 +30,10 @@
without asking permission!
</p>
<p>
From your dashboard, you can use invite links, discover community spaces, and keep up-to-date on
groups you've already joined. Click below to get started!
From your dashboard, you can use invite links, discover community spaces, and keep up-to-date
on groups you've already joined. Click below to get started!
</p>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -40,4 +44,4 @@
Go to Dashboard
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -11,6 +11,8 @@
import FieldInline from "@lib/components/FieldInline.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import SignUpEmailConfirm from "@app/components/SignUpEmailConfirm.svelte"
@ -92,7 +94,8 @@
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(onSubmit)}>
<Modal tag="form" onsubmit={preventDefault(onSubmit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Sign up with Email</div>
@ -131,6 +134,7 @@
</label>
{/snippet}
</FieldInline>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -141,4 +145,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -9,6 +9,8 @@
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
@ -35,7 +37,8 @@
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(onSubmit)}>
<Modal tag="form" onsubmit={preventDefault(onSubmit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Verify your Email Address</div>
@ -59,6 +62,7 @@
We just sent a one-time confirmation code to {email}. Once you receive it, you can enter it
above.
</p>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} />
@ -69,4 +73,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -5,6 +5,8 @@
import {getKey, setKey} from "@lib/implicit"
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import ProfileEditForm from "@app/components/ProfileEditForm.svelte"
@ -26,7 +28,8 @@
}
</script>
<div class="flex flex-col gap-4">
<Modal>
<ModalBody>
<ProfileEditForm isSignup {initialValues} {onsubmit}>
{#snippet footer()}
<ModalFooter>
@ -41,4 +44,5 @@
</ModalFooter>
{/snippet}
</ProfileEditForm>
</div>
</ModalBody>
</Modal>

View file

@ -9,6 +9,8 @@
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {pushToast} from "@app/util/toast"
@ -48,7 +50,8 @@
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(join)}>
<Modal tag="form" onsubmit={preventDefault(join)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Request Access</div>
@ -68,6 +71,7 @@
</label>
{/snippet}
</Field>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -78,4 +82,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -6,6 +6,8 @@
import Link from "@lib/components/Link.svelte"
import Button from "@lib/components/Button.svelte"
import CardButton from "@lib/components/CardButton.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import SpaceInviteAccept from "@app/components/SpaceInviteAccept.svelte"
import {pushModal} from "@app/util/modal"
@ -19,7 +21,8 @@
const startJoin = () => pushModal(SpaceInviteAccept)
</script>
<div class="column gap-2">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Add a Space</div>
@ -69,4 +72,5 @@
{/snippet}
</CardButton>
</Link>
</div>
</ModalBody>
</Modal>

View file

@ -8,6 +8,8 @@
import Icon from "@lib/components/Icon.svelte"
import {preventDefault} from "@lib/html"
import {ucFirst} from "@lib/util"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import SpaceAccessRequest from "@app/components/SpaceAccessRequest.svelte"
@ -37,7 +39,8 @@
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(requestAccess)}>
<Modal tag="form" onsubmit={preventDefault(requestAccess)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Access Error</div>
@ -47,11 +50,14 @@
{/snippet}
</ModalHeader>
<p>
We received an error from the relay indicating you don't have access to {displayRelayUrl(url)}:
We received an error from the relay indicating you don't have access to {displayRelayUrl(
url,
)}:
</p>
<p class="bg-alt card2 welshman-content">
{@html renderAsHtml(parse({content: ucFirst(error)}))}
</p>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -67,4 +73,4 @@
</Button>
</div>
</ModalFooter>
</form>
</Modal>

View file

@ -8,6 +8,8 @@
import BillList from "@assets/icons/bill-list.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Link from "@lib/components/Link.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Button from "@lib/components/Button.svelte"
import RelayName from "@app/components/RelayName.svelte"
@ -33,7 +35,8 @@
const startEdit = () => pushModal(SpaceEdit, {url, initialValues: $relay || {url}})
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<div class="flex justify-between">
<div class="relative flex gap-4">
<div class="relative">
@ -91,10 +94,11 @@
</div>
{/if}
</div>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
Go back
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -11,6 +11,8 @@
import Icon from "@lib/components/Icon.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import ImageIcon from "@lib/components/ImageIcon.svelte"
@ -119,7 +121,8 @@
}
</script>
<form class="column gap-4" onsubmit={preventDefault(trySubmit)}>
<Modal tag="form" onsubmit={preventDefault(trySubmit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Edit a Space</div>
@ -183,6 +186,7 @@
</label>
{/snippet}
</FieldInline>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -192,4 +196,4 @@
<Spinner {loading}>Save Changes</Spinner>
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -6,6 +6,8 @@
import Button from "@lib/components/Button.svelte"
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {removeSpaceMembership, publishLeaveRequest, removeTrustedRelay} from "@app/core/commands"
@ -31,7 +33,8 @@
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(exit)}>
<Modal tag="form" onsubmit={preventDefault(exit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>
@ -40,6 +43,7 @@
{/snippet}
</ModalHeader>
<p class="text-center">Are you sure you want to leave?</p>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -49,4 +53,4 @@
<Spinner {loading}>Confirm</Spinner>
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -9,6 +9,8 @@
import Field from "@lib/components/Field.svelte"
import Button from "@lib/components/Button.svelte"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import QRCode from "@app/components/QRCode.svelte"
@ -52,7 +54,8 @@
})
</script>
<div class="col-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Create an Invite</div>
@ -97,7 +100,8 @@
</div>
{/if}
</div>
</ModalBody>
<ModalFooter>
<Button class="btn btn-primary flex-grow" onclick={back}>Done</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -12,6 +12,8 @@
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import RelaySummary from "@app/components/RelaySummary.svelte"
@ -24,12 +26,10 @@
type Props = {
invite: string
abortAction?: Snippet
back?: () => void
}
let {invite = "", abortAction}: Props = $props()
const back = () => history.back()
let {invite = "", back = () => history.back()}: Props = $props()
const joinRelay = async () => {
const {url, claim} = inviteData!
@ -63,7 +63,8 @@
const inviteData = $derived(parseInviteLink(invite))
</script>
<form class="column gap-4" onsubmit={preventDefault(join)}>
<Modal tag="form" onsubmit={preventDefault(join)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Join a Space</div>
@ -83,28 +84,25 @@
</label>
{/snippet}
</Field>
<div class="-my-4">
{#if inviteData}
<div class="-my-4">
<div transition:slideAndFade class="flex flex-col gap-4 py-4">
<div class="card2 bg-alt flex flex-col gap-4">
<p class="opacity-75">You're about to join:</p>
<RelaySummary url={inviteData.url} />
</div>
</div>
{/if}
</div>
{/if}
</ModalBody>
<ModalFooter>
{#if abortAction}
{@render abortAction?.()}
{:else}
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
Go back
</Button>
{/if}
<Button type="submit" class="btn btn-primary" disabled={!inviteData || loading}>
<Spinner {loading}>Join Space</Spinner>
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -12,14 +12,20 @@
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import FieldInline from "@lib/components/FieldInline.svelte"
import StatusIndicator from "@lib/components/StatusIndicator.svelte"
import RelaySummary from "@app/components/RelaySummary.svelte"
import SocketStatusIndicator from "@app/components/SocketStatusIndicator.svelte"
import SpaceAccessRequest from "@app/components/SpaceAccessRequest.svelte"
import {attemptRelayAccess, addSpaceMembership, broadcastUserData, setSpaceNotifications} from "@app/core/commands"
import {
attemptRelayAccess,
addSpaceMembership,
broadcastUserData,
setSpaceNotifications,
} from "@app/core/commands"
import {relaysMostlyRestricted, deriveSpaceMembers, notificationSettings} from "@app/core/state"
import {pushModal} from "@app/util/modal"
import {pushToast} from "@app/util/toast"
@ -83,7 +89,8 @@
})
</script>
<form class="column gap-4" onsubmit={preventDefault(join)}>
<Modal tag="form" onsubmit={preventDefault(join)}>
<ModalBody>
<RelaySummary {url} />
<div class="card2 card2-sm bg-alt">
<div class="flex justify-between gap-12">
@ -112,16 +119,17 @@
</div>
{/if}
</div>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} />
Go back
</Button>
<Button type="submit" class="btn btn-primary" disabled={loading}>
<Spinner loading={loading}>
<Spinner {loading}>
{error ? "Request Access" : "Join Space"}
</Spinner>
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -10,6 +10,8 @@
import Icon from "@lib/components/Icon.svelte"
import Popover from "@lib/components/Popover.svelte"
import Confirm from "@lib/components/Confirm.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Profile from "@app/components/Profile.svelte"
import SpaceMembersAdd from "@app/components/SpaceMembersAdd.svelte"
@ -68,7 +70,8 @@
let menuPubkey = $state<string | undefined>()
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<div class="flex min-w-0 flex-col gap-1">
<h1 class="ellipsize whitespace-nowrap text-2xl font-bold">Members</h1>
<p class="ellipsize text-sm opacity-75">of {displayRelayUrl(url)}</p>
@ -114,10 +117,11 @@
</div>
</div>
{/each}
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
Go back
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -6,6 +6,8 @@
import Button from "@lib/components/Button.svelte"
import Field from "@lib/components/Field.svelte"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import ProfileMultiSelect from "@app/components/ProfileMultiSelect.svelte"
@ -49,7 +51,8 @@
let pubkeys: string[] = $state([])
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Add Members</div>
@ -66,6 +69,7 @@
<ProfileMultiSelect bind:value={pubkeys} />
{/snippet}
</Field>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -75,4 +79,4 @@
<Spinner {loading}>Save changes</Spinner>
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -8,6 +8,8 @@
import Button from "@lib/components/Button.svelte"
import Icon from "@lib/components/Icon.svelte"
import Popover from "@lib/components/Popover.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Profile from "@app/components/Profile.svelte"
@ -49,7 +51,8 @@
let menuPubkey = $state<string | undefined>()
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Banned users</div>
@ -86,10 +89,11 @@
</div>
</div>
{/each}
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
Got it
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -3,6 +3,8 @@
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import Button from "@lib/components/Button.svelte"
import Icon from "@lib/components/Icon.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import ReportItem from "@app/components/ReportItem.svelte"
import {deriveEventsForUrl} from "@app/core/state"
@ -18,7 +20,8 @@
const back = () => history.back()
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<div class="flex min-w-0 flex-col gap-1">
<h1 class="ellipsize whitespace-nowrap text-2xl font-bold">Reports</h1>
<p class="ellipsize text-sm opacity-75">on {displayRelayUrl(url)}</p>
@ -26,10 +29,11 @@
{#each $reports as event (event.id)}
<ReportItem {url} {event} />
{/each}
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
Go back
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -8,7 +8,10 @@
import Icon from "@lib/components/Icon.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Button from "@lib/components/Button.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import InfoSignatures from "@app/components/InfoSignatures.svelte"
import {relaysPendingTrust} from "@app/core/state"
import {removeSpaceMembership, addTrustedRelay, removeTrustedRelay} from "@app/core/commands"
@ -49,7 +52,8 @@
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(trustSpace)}>
<Modal tag="form" onsubmit={preventDefault(trustSpace)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
Do you trust this space?
@ -67,11 +71,13 @@
>, which means that they have the ability to forge messages from other users.
</p>
<p>
If you trust this space's admin, you can continue. Otherwise, it may be safer not to join this
space.
If you trust this space's admin, you can continue. Otherwise, it may be safer not to join
this space.
</p>
</div>
<div class="mt-4 flex flex-col gap-2 sm:flex-row sm:justify-between">
</ModalBody>
<ModalFooter>
<div class="flex flex-col gap-2 sm:flex-row sm:justify-between">
<Button class="btn btn-neutral" onclick={untrustSpace} disabled={loading}>
{#if !loading}
<Icon icon={CloseCircle} />
@ -85,4 +91,5 @@
<Spinner {loading}>I trust this space, continue</Spinner>
</Button>
</div>
</form>
</ModalFooter>
</Modal>

View file

@ -10,6 +10,8 @@
import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import EditorContent from "@app/editor/EditorContent.svelte"
import {pushToast} from "@app/util/toast"
import {PROTECTED} from "@app/core/state"
@ -74,7 +76,8 @@
let title: string = $state("")
</script>
<form class="column gap-4" onsubmit={preventDefault(submit)}>
<Modal tag="form" onsubmit={preventDefault(submit)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Create a Thread</div>
@ -121,6 +124,7 @@
{/if}
</Button>
</div>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -128,4 +132,4 @@
</Button>
<Button type="submit" class="btn btn-primary">Create Thread</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -2,6 +2,8 @@
import {getWalletAddress} from "@welshman/util"
import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {updateProfile} from "@app/core/commands"
@ -32,7 +34,8 @@
let loading = $state(false)
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
Set as Receiving Address?
@ -43,7 +46,8 @@
Your current receiving address is different from the one provided by your connected wallet.
</p>
<p>
Would you like to update your receiving address to <span class="text-primary">{lud16}</span>?
Would you like to update your receiving address to <span class="text-primary">{lud16}</span
>?
</p>
{:else}
<p>
@ -52,10 +56,11 @@
</p>
<p>Would you like to use the one associated with your connected wallet?</p>
{/if}
</ModalBody>
<ModalFooter>
<Button class="btn btn-neutral" onclick={cancel} disabled={loading}>No, skip this</Button>
<Button class="btn btn-primary" onclick={confirm} disabled={loading}>
<Spinner {loading}>Yes, set as receiving address</Spinner>
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -15,6 +15,8 @@
import Scanner from "@lib/components/Scanner.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Field from "@lib/components/Field.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {getWebLn} from "@app/core/commands"
@ -109,7 +111,8 @@
let loading = $state(false)
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Connect a Wallet</div>
@ -164,6 +167,7 @@
{#if showScanner}
<Scanner onscan={onScan} />
{/if}
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -185,4 +189,4 @@
</Spinner>
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -8,6 +8,8 @@
import Button from "@lib/components/Button.svelte"
import FieldInline from "@lib/components/FieldInline.svelte"
import Scanner from "@lib/components/Scanner.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {payInvoice} from "@app/core/commands"
@ -48,7 +50,8 @@
let sats = $state(0)
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Pay with Lightning</div>
@ -94,6 +97,7 @@
To make a payment, scan a lightning invoice with your camera.
</p>
{/if}
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -108,4 +112,4 @@
Confirm Payment
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -5,6 +5,8 @@
import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import Wallet from "@assets/icons/wallet.svg?dataurl"
import CheckCircle from "@assets/icons/check-circle.svg?dataurl"
import {updateProfile} from "@app/core/commands"
@ -42,7 +44,8 @@
}
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
Update Lightning Address
@ -84,7 +87,7 @@
</div>
{/if}
</div>
</ModalBody>
<ModalFooter>
<Button class="btn btn-neutral" onclick={back} disabled={isLoading}>Cancel</Button>
<Button class="btn btn-primary" onclick={save} disabled={isLoading}>
@ -96,4 +99,4 @@
Save Changes
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -10,6 +10,8 @@
import Spinner from "@lib/components/Spinner.svelte"
import Button from "@lib/components/Button.svelte"
import FieldInline from "@lib/components/FieldInline.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import EmojiButton from "@lib/components/EmojiButton.svelte"
@ -109,7 +111,8 @@
})
</script>
<div class="column gap-4">
<Modal>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>Send a Zap</div>
@ -149,6 +152,7 @@
min={minPos}
max={maxPos}
bind:value={pos} />
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -165,4 +169,4 @@
</Spinner>
</Button>
</ModalFooter>
</div>
</Modal>

View file

@ -389,11 +389,11 @@ export const toggleRoomNotifications = async (url: string, h: string) => {
} else {
// Toggle exception status
const hasException = existing.exceptions.includes(h)
const exceptions = hasException ? remove(h, existing.exceptions) : append(h, existing.exceptions)
const exceptions = hasException
? remove(h, existing.exceptions)
: append(h, existing.exceptions)
updated = alerts.map((s: SpaceNotificationSettings) =>
s.url === url ? {...s, exceptions} : s,
)
updated = alerts.map((s: SpaceNotificationSettings) => (s.url === url ? {...s, exceptions} : s))
}
return publishSettings({alerts: updated})

View file

@ -533,9 +533,7 @@ class CapacitorNotifications implements IPushAdapter {
} else {
// notify=false: exceptions are opt-in (only include those rooms)
if (exceptions.length > 0) {
filters.push(
...baseFilters.map(f => ({...f, "#h": exceptions})),
)
filters.push(...baseFilters.map(f => ({...f, "#h": exceptions})))
}
}
}
@ -625,9 +623,7 @@ class CapacitorNotifications implements IPushAdapter {
await Promise.all(get(userSpaceUrls).map(url => this._unsyncRelay(url, "spaces")))
await Promise.all(
getRelaysFromList(get(userMessagingRelayList)).map(url =>
this._unsyncRelay(url, "messages"),
),
getRelaysFromList(get(userMessagingRelayList)).map(url => this._unsyncRelay(url, "messages")),
)
}
}

View file

@ -7,6 +7,8 @@
import Spinner from "@lib/components/Spinner.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte"
interface Props {
title?: string
@ -32,7 +34,8 @@
const back = () => history.back()
</script>
<form class="column gap-4" onsubmit={preventDefault(tryConfirm)}>
<Modal tag="form" onsubmit={preventDefault(tryConfirm)}>
<ModalBody>
<ModalHeader>
{#snippet title()}
<div>{restProps.title || "Are you sure?"}</div>
@ -42,6 +45,7 @@
{/snippet}
</ModalHeader>
<p class="text-center">{message}</p>
</ModalBody>
<ModalFooter>
<Button class="btn btn-link" onclick={back}>
<Icon icon={AltArrowLeft} />
@ -52,4 +56,4 @@
<Icon icon={AltArrowRight} />
</Button>
</ModalFooter>
</form>
</Modal>

View file

@ -1,12 +1,17 @@
<script lang="ts">
import type {Component} from "svelte"
import cx from "classnames"
import {onMount} from "svelte"
import {noop} from "@welshman/lib"
import {fade, fly} from "@lib/transition"
interface Props {
type Props = {
onClose?: any
fullscreen?: boolean
children?: import("svelte").Snippet
children: {
component: Component<any>
props: Record<string, any>
}
}
const {onClose = noop, fullscreen = false, children}: Props = $props()
@ -21,9 +26,9 @@
const innerClass = $derived(
cx(
"relative text-base-content text-base-content flex-grow pointer-events-auto",
"px-4 py-6 rounded-t-box sm:p-6 sm:rounded-box sm:mt-0",
"rounded-t-box sm:rounded-box",
{
"bg-alt shadow-m max-h-[90vh] scroll-container overflow-auto": !fullscreen,
"bg-alt shadow-m max-h-[90vh] flex flex-col": !fullscreen,
},
),
)
@ -39,7 +44,7 @@
</button>
<div class={wrapperClass}>
<div class={innerClass} transition:fly={{duration: 300}}>
{@render children?.()}
<children.component {...children.props} />
</div>
</div>
</div>

View file

@ -1,7 +1,16 @@
<script lang="ts">
import type {Component} from "svelte"
import {fade, translate} from "@lib/transition"
const {onClose, children} = $props()
type Props = {
onClose?: any
children: {
component: Component
props: Record<string, any>
}
}
const {onClose, children}: Props = $props()
</script>
<div class="drawer fixed inset-0 z-modal">
@ -14,6 +23,6 @@
<div
class="scroll-container py-sai pr-sair absolute bottom-0 right-0 top-0 w-72 overflow-auto bg-base-200 text-base-content lg:w-96"
transition:translate={{axis: "x", duration: 300}}>
{@render children?.()}
<children.component {...children.props} />
</div>
</div>

View file

@ -58,7 +58,12 @@
</Tippy>
{#if showIconPicker}
<Dialog onClose={close}>
<IconPicker onSelect={onClick} />
</Dialog>
<Dialog
onClose={close}
children={{
component: IconPicker,
props: {
onSelect: onClick,
},
}} />
{/if}

View file

@ -0,0 +1,17 @@
<script lang="ts">
import cx from "classnames"
import type {Snippet} from "svelte"
interface Props {
tag?: string
class?: string
children?: Snippet
[key: string]: any
}
const {children, tag = "div", ...props}: Props = $props()
</script>
<svelte:element this={tag} {...props} class={cx("flex flex-col overflow-hidden pb-6", props.class)}>
{@render children?.()}
</svelte:element>

View file

@ -0,0 +1,16 @@
<script lang="ts">
import cx from "classnames"
import type {Snippet} from "svelte"
interface Props {
class?: string
children?: Snippet
}
const {children, ...props}: Props = $props()
</script>
<div
class={cx("scroll-container overflow-y-auto min-h-0 flex flex-col gap-4 p-6 pb-0", props.class)}>
{@render children?.()}
</div>

View file

@ -8,6 +8,9 @@
const {children}: Props = $props()
</script>
<div class="row-4 mt-4 items-center justify-between">
<div class="h-20 flex-shrink-0"></div>
<div class="flex absolute bottom-0 left-0 right-0 p-6 pt-2 rounded-b-box bg-base-100">
<div class="flex flex-grow gap-4 items-center justify-between">
{@render children?.()}
</div>
</div>

View file

@ -7,7 +7,7 @@
const {title, info}: Props = $props()
</script>
<div class="column m-auto max-w-xs gap-2 py-4">
<div class="flex flex-col m-auto max-w-xs gap-2 py-4">
<h1 class="heading">{@render title?.()}</h1>
<p class="text-center text-sm opacity-75">{@render info?.()}</p>
</div>

View file

@ -1,20 +1,16 @@
<script lang="ts">
import {page} from "$app/stores"
import {goto} from "$app/navigation"
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
import Icon from "@lib/components/Icon.svelte"
import Dialog from "@lib/components/Dialog.svelte"
import Button from "@lib/components/Button.svelte"
import SpaceInviteAccept from "@app/components/SpaceInviteAccept.svelte"
const children = {
component: SpaceInviteAccept,
props: {
invite: $page.url.href,
back: () => goto("/home"),
},
}
</script>
<Dialog>
<SpaceInviteAccept invite={$page.url.href}>
{#snippet abortAction()}
<Button class="btn btn-link" onclick={() => goto("/home")}>
<Icon icon={AltArrowLeft} />
Go back
</Button>
{/snippet}
</SpaceInviteAccept>
</Dialog>
<Dialog {children} />

View file

@ -47,11 +47,7 @@
userSettingsValues,
} from "@app/core/state"
import {setChecked, checked} from "@app/util/notifications"
import {
canEnforceNip70,
prependParent,
publishDelete,
} from "@app/core/commands"
import {canEnforceNip70, prependParent, publishDelete} from "@app/core/commands"
import {makeFeed} from "@app/core/requests"
import {popKey} from "@lib/implicit"
import {pushToast} from "@app/util/toast"