Add new claymorphic component library
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import type {Snippet} from "svelte"
|
||||
import {pubkey} from "@welshman/app"
|
||||
import Dialog from "@lib/components/Dialog.svelte"
|
||||
import Dialog from "@lib/components2/Dialog.svelte"
|
||||
import Landing from "@app/components/Landing.svelte"
|
||||
import Toast from "@app/components/Toast.svelte"
|
||||
import PrimaryNav from "@app/components/PrimaryNav.svelte"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import QRCode from "@app/components/QRCode.svelte"
|
||||
import type {Nip46Controller} from "@app/nip46"
|
||||
|
||||
@@ -19,7 +20,7 @@
|
||||
{:else}
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<QRCode code={$url} />
|
||||
<p class="text-sm opacity-75">Scan with your signer to log in, or click to copy.</p>
|
||||
<Text size="sm" muted>Scan with your signer to log in, or click to copy.</Text>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script lang="ts">
|
||||
import {debounce} from "throttle-debounce"
|
||||
import Scanner from "@lib/components/Scanner.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Field from "@lib/components/Field.svelte"
|
||||
import Scanner from "@lib/components2/Scanner.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Field from "@lib/components2/Field.svelte"
|
||||
import CpuBolt from "@assets/icons/cpu-bolt.svg?dataurl"
|
||||
import QrCode from "@assets/icons/qr-code.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import InfoBunker from "@app/components/InfoBunker.svelte"
|
||||
import type {Nip46Controller} from "@app/nip46"
|
||||
import {pushModal} from "@app/modal"
|
||||
@@ -34,9 +34,9 @@
|
||||
<p>Bunker Link*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<label class="input-cl input-cl-group">
|
||||
<Icon icon={CpuBolt} />
|
||||
<input disabled={$loading} bind:value={$bunker} class="grow" placeholder="bunker://" />
|
||||
<input disabled={$loading} bind:value={$bunker} placeholder="bunker://" />
|
||||
<Button onclick={toggleScanner}>
|
||||
<Icon icon={QrCode} />
|
||||
</Button>
|
||||
@@ -45,7 +45,7 @@
|
||||
{#snippet info()}
|
||||
<p>
|
||||
A login link provided by a nostr signing app.
|
||||
<Button class="link" onclick={() => pushModal(InfoBunker)}>What is a bunker link?</Button>
|
||||
<Button class="cl-link" onclick={() => pushModal(InfoBunker)}>What is a bunker link?</Button>
|
||||
</p>
|
||||
{/snippet}
|
||||
</Field>
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
import {getTagValue, getAddress} from "@welshman/util"
|
||||
import {pubkey} from "@welshman/app"
|
||||
import Pen2 from "@assets/icons/pen-2.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import RoomName from "@app/components/RoomName.svelte"
|
||||
import ReactionSummary from "@app/components/ReactionSummary.svelte"
|
||||
import ThunkStatusOrDeleted from "@app/components/ThunkStatusOrDeleted.svelte"
|
||||
@@ -42,11 +42,11 @@
|
||||
|
||||
<div class="flex grow flex-wrap justify-end gap-2">
|
||||
{#if h && showRoom}
|
||||
<Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full">
|
||||
<Link href={makeSpacePath(url, h)} class="badge-cl badge-cl-neutral badge-cl-sm">
|
||||
Posted in #<RoomName {h} {url} />
|
||||
</Link>
|
||||
{/if}
|
||||
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" />
|
||||
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="cl-tip-left" />
|
||||
<ThunkStatusOrDeleted {event} />
|
||||
{#if showActivity}
|
||||
<EventActivity {url} {path} {event} />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import CalendarEventForm from "@app/components/CalendarEventForm.svelte"
|
||||
|
||||
type Props = {
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
{#if !isNaN(start)}
|
||||
{@const startDate = secondsToDate(start)}
|
||||
<div
|
||||
class="hidden h-32 w-32 min-w-32 flex-col items-center justify-center gap-1 rounded-box bg-base-300 p-2 sm:flex">
|
||||
class="clay-card clay-card-sm cl-surface-alt hidden h-32 w-32 min-w-32 flex-col items-center justify-center gap-1 p-2 sm:flex">
|
||||
<strong>{Intl.DateTimeFormat(LOCALE, {month: "short"}).format(startDate)}</strong>
|
||||
<span class="text-4xl">{Intl.DateTimeFormat(LOCALE, {day: "numeric"}).format(startDate)}</span>
|
||||
<span class="text-xs opacity-75"
|
||||
<span class="cl-text-muted text-xs"
|
||||
>{Intl.DateTimeFormat(LOCALE, {weekday: "long"}).format(startDate)}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script lang="ts">
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {getTagValue} from "@welshman/util"
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import CalendarEventForm from "@app/components/CalendarEventForm.svelte"
|
||||
|
||||
type Props = {
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
import GallerySend from "@assets/icons/gallery-send.svg?dataurl"
|
||||
import MapPoint from "@assets/icons/map-point.svg?dataurl"
|
||||
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Field from "@lib/components/Field.svelte"
|
||||
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 Icon from "@lib/components2/Icon.svelte"
|
||||
import Field from "@lib/components2/Field.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import DateTimeInput from "@lib/components2/DateTimeInput.svelte"
|
||||
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||
import {PROTECTED, publishRoomQuote} from "@app/groups"
|
||||
import {makeEditor} from "@app/editor"
|
||||
@@ -164,8 +164,8 @@
|
||||
<p>Title*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<input bind:value={title} class="grow" type="text" />
|
||||
<label class="input-cl input-cl-group">
|
||||
<input bind:value={title} type="text" />
|
||||
</label>
|
||||
{/snippet}
|
||||
</Field>
|
||||
@@ -174,18 +174,17 @@
|
||||
<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="cl-surface cl-border-t relative z-feature flex gap-2">
|
||||
<div class="input-editor grow overflow-hidden">
|
||||
<EditorContent {editor} />
|
||||
</div>
|
||||
<Button
|
||||
data-tip="Add an image"
|
||||
class="center btn tooltip"
|
||||
circle
|
||||
onclick={selectFiles}
|
||||
disabled={loading}>
|
||||
{#if $uploading}
|
||||
<span class="loading loading-spinner loading-xs"></span>
|
||||
<span class="cl-spinner"></span>
|
||||
{:else}
|
||||
<Icon icon={GallerySend} />
|
||||
{/if}
|
||||
@@ -214,19 +213,19 @@
|
||||
<p>Location (optional)</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<label class="input-cl input-cl-group">
|
||||
<Icon icon={MapPoint} />
|
||||
<input bind:value={location} class="grow" type="text" />
|
||||
<input bind:value={location} type="text" />
|
||||
</label>
|
||||
{/snippet}
|
||||
</Field>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back} disabled={loading}>
|
||||
<Button variant="ghost" onclick={back} disabled={loading}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={$uploading || loading}>
|
||||
<Button type="submit" variant="primary" disabled={$uploading || loading}>
|
||||
<Spinner loading={$uploading || loading}>Save Event</Spinner>
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
} from "@welshman/lib"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import ClockCircle from "@assets/icons/clock-circle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
|
||||
type Props = {
|
||||
event: TrustedEvent
|
||||
@@ -20,12 +21,12 @@
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col justify-between gap-1">
|
||||
<p class="text-lg">{meta.title || meta.name}</p>
|
||||
<Text size="lg">{meta.title || meta.name}</Text>
|
||||
{#if !isNaN(start) && !isNaN(end)}
|
||||
{@const startDateDisplay = formatTimestampAsDate(start)}
|
||||
{@const endDateDisplay = formatTimestampAsDate(end)}
|
||||
{@const isSingleDay = startDateDisplay === endDateDisplay}
|
||||
<div class="flex flex-wrap gap-2 text-xs">
|
||||
<div class="cl-text flex flex-wrap gap-2 text-xs">
|
||||
<div class="flex items-center gap-2">
|
||||
<Icon icon={ClockCircle} size={4} />
|
||||
{formatTimestampAsDate(start)}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {getTagValue, getAddress} from "@welshman/util"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import CalendarEventActions from "@app/components/CalendarEventActions.svelte"
|
||||
import CalendarEventHeader from "@app/components/CalendarEventHeader.svelte"
|
||||
import ProfileLink from "@app/components/ProfileLink.svelte"
|
||||
@@ -19,11 +19,11 @@
|
||||
</script>
|
||||
|
||||
<Link
|
||||
class="cv col-3 card2 bg-alt w-full cursor-pointer shadow-md"
|
||||
class="cv clay-card clay-card-interactive flex w-full cursor-pointer flex-col gap-3 p-4 sm:p-6"
|
||||
href={makeCalendarPath(url, getAddress(event))}>
|
||||
<CalendarEventHeader {event} />
|
||||
<div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row">
|
||||
<span class="whitespace-nowrap py-1 text-sm opacity-75">
|
||||
<span class="cl-text-muted whitespace-nowrap py-1 text-sm">
|
||||
Posted by <ProfileLink pubkey={event.pubkey} {url} />
|
||||
{#if h}
|
||||
in <RoomLink {url} {h} />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import UserCircle from "@assets/icons/user-circle.svg?dataurl"
|
||||
import MapPoint from "@assets/icons/map-point.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import ProfileLink from "@app/components/ProfileLink.svelte"
|
||||
|
||||
type Props = {
|
||||
@@ -15,7 +15,7 @@
|
||||
const meta = $derived(fromPairs(event.tags) as Record<string, string>)
|
||||
</script>
|
||||
|
||||
<div class="flex min-w-0 flex-col gap-1 text-sm opacity-75">
|
||||
<div class="cl-text-muted flex min-w-0 flex-col gap-1 text-sm">
|
||||
<span class="flex items-center gap-1">
|
||||
<Icon icon={UserCircle} size={4} />
|
||||
Posted by <ProfileLink pubkey={event.pubkey} {url} />
|
||||
|
||||
@@ -36,12 +36,16 @@
|
||||
} from "@welshman/app"
|
||||
import Danger from "@assets/icons/danger-triangle.svg?dataurl"
|
||||
import ArrowLeft from "@assets/icons/arrow-left.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import PageBar from "@lib/components/PageBar.svelte"
|
||||
import PageContent from "@lib/components/PageContent.svelte"
|
||||
import Divider from "@lib/components/Divider.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import PageBar from "@lib/components2/PageBar.svelte"
|
||||
import PageContent from "@lib/components2/PageContent.svelte"
|
||||
import Divider from "@lib/components2/Divider.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Card from "@lib/components2/Card.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import ProfileName from "@app/components/ProfileName.svelte"
|
||||
import ProfileLink from "@app/components/ProfileLink.svelte"
|
||||
import ProfileCircle from "@app/components/ProfileCircle.svelte"
|
||||
@@ -249,18 +253,18 @@
|
||||
<Icon icon={ArrowLeft} size={7} />
|
||||
</Button>
|
||||
<div class="flex items-center justify-between gap-4">
|
||||
<div class="ellipsize flex items-center gap-4 whitespace-nowrap">
|
||||
<div class="flex items-center gap-4 overflow-hidden text-ellipsis whitespace-nowrap">
|
||||
<Button class="flex flex-col gap-1 sm:flex-row sm:gap-2" onclick={showMembers}>
|
||||
{#if others.length === 0}
|
||||
<div class="row-2">
|
||||
<Row>
|
||||
<ProfileCircle pubkey={$pubkey!} size={5} />
|
||||
<ProfileName pubkey={$pubkey!} />
|
||||
</div>
|
||||
</Row>
|
||||
{:else if others.length === 1}
|
||||
<div class="row-2">
|
||||
<Row>
|
||||
<ProfileCircle pubkey={others[0]} size={5} />
|
||||
<ProfileName pubkey={others[0]} />
|
||||
</div>
|
||||
</Row>
|
||||
{:else}
|
||||
<div class="flex items-center gap-2">
|
||||
<ProfileCircles pubkeys={others} size={5} />
|
||||
@@ -285,19 +289,21 @@
|
||||
<PageContent class="flex flex-col-reverse gap-2 py-2 !mb-0">
|
||||
{#if missingRelayLists.length > 0}
|
||||
<div class="py-12">
|
||||
<div class="card2 col-2 m-auto max-w-md items-center text-center">
|
||||
<p class="row-2 text-lg text-error">
|
||||
<Icon icon={Danger} />
|
||||
Direct messages are not enabled
|
||||
</p>
|
||||
<p>
|
||||
Ask
|
||||
{#each missingRelayLists as pubkey (pubkey)}
|
||||
<ProfileLink {pubkey} />
|
||||
{/each}
|
||||
to enable direct messaging by opening this conversation in their app.
|
||||
</p>
|
||||
</div>
|
||||
<Card class="m-auto max-w-md text-center">
|
||||
<Col class="items-center">
|
||||
<Row class="text-lg cl-text-danger">
|
||||
<Icon icon={Danger} />
|
||||
Direct messages are not enabled
|
||||
</Row>
|
||||
<Text>
|
||||
Ask
|
||||
{#each missingRelayLists as pubkey (pubkey)}
|
||||
<ProfileLink {pubkey} />
|
||||
{/each}
|
||||
to enable direct messaging by opening this conversation in their app.
|
||||
</Text>
|
||||
</Col>
|
||||
</Card>
|
||||
</div>
|
||||
{/if}
|
||||
{#each elements as { type, id, value, showPubkey } (id)}
|
||||
@@ -326,7 +332,7 @@
|
||||
<div class="h-screen"></div>
|
||||
</PageContent>
|
||||
|
||||
<div class="chat__compose bg-base-200">
|
||||
<div class="chat__compose cl-surface-alt">
|
||||
<div>
|
||||
{#if parent}
|
||||
<ChatComposeParent event={parent} clear={clearParent} verb="Replying to" />
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
import {isMobile, preventDefault} from "@lib/html"
|
||||
import GallerySend from "@assets/icons/gallery-send.svg?dataurl"
|
||||
import Plane from "@assets/icons/plane-2.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||
import {makeEditor} from "@app/editor"
|
||||
import {type DraftKey} from "@app/drafts"
|
||||
@@ -112,12 +112,14 @@
|
||||
|
||||
<form class="relative z-feature flex gap-2 p-2" onsubmit={preventDefault(submit)}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
circle
|
||||
data-tip="Add an image"
|
||||
class="center tooltip tooltip-right h-10 w-10 min-w-10 rounded-box bg-base-300 transition-colors hover:bg-base-200"
|
||||
class="h-10 w-10 min-w-10"
|
||||
disabled={$uploading || disabled}
|
||||
onclick={uploadFiles}>
|
||||
{#if $uploading}
|
||||
<span class="loading loading-spinner loading-xs"></span>
|
||||
<span class="cl-spinner"></span>
|
||||
{:else}
|
||||
<Icon icon={GallerySend} />
|
||||
{/if}
|
||||
@@ -126,8 +128,10 @@
|
||||
<EditorContent {autofocus} {editor} />
|
||||
</div>
|
||||
<Button
|
||||
variant="primary"
|
||||
circle
|
||||
data-tip="{window.navigator.platform.includes('Mac') ? 'cmd' : 'ctrl'}+enter to send"
|
||||
class="center tooltip tooltip-left absolute right-4 h-10 w-10 min-w-10 rounded-full"
|
||||
class="absolute right-4 h-10 w-10 min-w-10"
|
||||
disabled={$uploading || disabled}
|
||||
onclick={submit}>
|
||||
<Icon icon={Plane} />
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import {slide} from "@lib/transition"
|
||||
import CloseCircle from "@assets/icons/close-circle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
|
||||
const {
|
||||
clear,
|
||||
@@ -12,9 +12,10 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="relative flex h-8 items-center justify-between border-l-2 border-solid border-primary bg-base-300 px-2 pr-7 text-xs"
|
||||
class="relative flex h-8 items-center justify-between border-l-2 border-solid px-2 pr-7 text-xs cl-surface-alt cl-text-primary"
|
||||
style="border-left-color: var(--cl-primary);"
|
||||
transition:slide>
|
||||
<p class="text-primary">Editing message</p>
|
||||
<p>Editing message</p>
|
||||
<Button onclick={clear} class="flex items-center">
|
||||
<Icon icon={CloseCircle} />
|
||||
</Button>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import {displayProfileByPubkey} from "@welshman/app"
|
||||
import {slide} from "@lib/transition"
|
||||
import CloseCircle from "@assets/icons/close-circle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import NoteContentMinimal from "@app/components/NoteContentMinimal.svelte"
|
||||
|
||||
const {
|
||||
@@ -19,9 +19,10 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="relative border-l-2 border-solid border-primary bg-base-300 px-2 py-1 pr-8"
|
||||
class="relative border-l-2 border-solid px-2 py-1 pr-8 cl-surface-alt"
|
||||
style="border-left-color: var(--cl-primary);"
|
||||
transition:slide>
|
||||
<p class="text-xs text-primary">{verb} @{displayProfileByPubkey(event.pubkey)}</p>
|
||||
<p class="text-xs cl-text-primary">{verb} @{displayProfileByPubkey(event.pubkey)}</p>
|
||||
{#key event.id}
|
||||
<NoteContentMinimal trimParent {event} />
|
||||
{/key}
|
||||
|
||||
@@ -4,14 +4,15 @@
|
||||
import {preventDefault} from "@lib/html"
|
||||
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 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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import {DEFAULT_RELAYS, DEFAULT_MESSAGING_RELAYS} from "@app/env"
|
||||
import {pushToast} from "@app/toast"
|
||||
|
||||
@@ -57,14 +58,14 @@
|
||||
<ModalHeader>
|
||||
<ModalTitle>Enable direct messaging?</ModalTitle>
|
||||
</ModalHeader>
|
||||
<p>Direct messaging isn't currently enabled. Would you like to turn it on?</p>
|
||||
<Text>Direct messaging isn't currently enabled. Would you like to turn it on?</Text>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back}>
|
||||
<Button variant="ghost" onclick={back}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={loading}>
|
||||
<Button type="submit" variant="primary" disabled={loading}>
|
||||
<Spinner {loading}>Enable direct messaging</Spinner>
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
<style>
|
||||
.chat-item:hover {
|
||||
background-color: var(--cl-bg-alt);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import {page} from "$app/stores"
|
||||
@@ -5,7 +11,7 @@
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {pubkey, loadMessagingRelayList} from "@welshman/app"
|
||||
import {fade} from "@lib/transition"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import ProfileName from "@app/components/ProfileName.svelte"
|
||||
import ProfileCircle from "@app/components/ProfileCircle.svelte"
|
||||
import ProfileCircles from "@app/components/ProfileCircles.svelte"
|
||||
@@ -35,8 +41,8 @@
|
||||
|
||||
<Button class="flex flex-col justify-start gap-1 w-full" onclick={openChat}>
|
||||
<div
|
||||
class="cursor-pointer border-t border-solid border-base-100 px-3 py-2 transition-colors hover:bg-base-100 {props.class}"
|
||||
class:bg-base-100={active}>
|
||||
class="chat-item cursor-pointer cl-border-t px-3 py-2 transition-colors {props.class}"
|
||||
class:cl-surface-alt={active}>
|
||||
<div class="flex flex-col justify-start gap-1">
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div class="flex min-w-0 items-center gap-2">
|
||||
@@ -56,18 +62,22 @@
|
||||
{/if}
|
||||
</div>
|
||||
{#if !active && $notifications.has(path)}
|
||||
<div class="h-2 w-2 rounded-full bg-primary" transition:fade></div>
|
||||
<div
|
||||
class="h-2 w-2 rounded-full"
|
||||
style="background-color: var(--cl-primary);"
|
||||
transition:fade>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<p class="overflow-hidden text-ellipsis whitespace-nowrap text-sm">
|
||||
<span class="opacity-70">
|
||||
<span class="cl-text-muted">
|
||||
{#if props.messages[0].pubkey === $pubkey}
|
||||
You:
|
||||
{/if}
|
||||
</span>
|
||||
{props.messages[0].content}
|
||||
</p>
|
||||
<p class="text-xs opacity-70">
|
||||
<p class="text-xs cl-text-muted">
|
||||
{formatTimestamp(props.messages[0].created_at)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<script lang="ts">
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Modal from "@lib/components/Modal.svelte"
|
||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import Card from "@lib/components2/Card.svelte"
|
||||
import Profile from "@app/components/Profile.svelte"
|
||||
|
||||
interface Props {
|
||||
@@ -21,13 +22,13 @@
|
||||
</ModalHeader>
|
||||
<div class="flex flex-col gap-2">
|
||||
{#each pubkeys as pubkey (pubkey)}
|
||||
<div class="card2 bg-alt">
|
||||
<Card sm pad={false} class="p-3">
|
||||
<Profile {pubkey} />
|
||||
</div>
|
||||
</Card>
|
||||
{/each}
|
||||
</div>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
|
||||
<Button variant="primary" onclick={() => history.back()}>Got it</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
import Check from "@assets/icons/check.svg?dataurl"
|
||||
import Bell from "@assets/icons/bell.svg?dataurl"
|
||||
import BellOff from "@assets/icons/bell-off.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 Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import {setChecked} from "@app/notifications"
|
||||
import {notificationSettings} from "@app/settings"
|
||||
|
||||
@@ -23,17 +23,17 @@
|
||||
<Modal>
|
||||
<ModalBody>
|
||||
<div class="flex flex-col gap-2">
|
||||
<Button class="btn btn-neutral" onclick={markAsRead}>
|
||||
<Button variant="secondary" onclick={markAsRead}>
|
||||
<Icon size={5} icon={Check} />
|
||||
Mark all read
|
||||
</Button>
|
||||
{#if $notificationSettings.messages}
|
||||
<Button class="btn btn-neutral" onclick={disableAlerts}>
|
||||
<Button variant="secondary" onclick={disableAlerts}>
|
||||
<Icon size={4} icon={BellOff} />
|
||||
Disable alerts
|
||||
</Button>
|
||||
{:else}
|
||||
<Button class="btn btn-neutral" onclick={enableAlerts}>
|
||||
<Button variant="secondary" onclick={enableAlerts}>
|
||||
<Icon size={4} icon={Bell} />
|
||||
Enable alerts
|
||||
</Button>
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
import {thunks, mergeThunks, pubkey, deriveProfileDisplay, sendWrapped} from "@welshman/app"
|
||||
import {isMobile} from "@lib/html"
|
||||
import MenuDots from "@assets/icons/menu-dots.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Tippy from "@lib/components/Tippy.svelte"
|
||||
import TapTarget from "@lib/components/TapTarget.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Tippy from "@lib/components2/Tippy.svelte"
|
||||
import TapTarget from "@lib/components2/TapTarget.svelte"
|
||||
import ProfileCircle from "@app/components/ProfileCircle.svelte"
|
||||
import Content from "@app/components/Content.svelte"
|
||||
import ReactionSummary from "@app/components/ReactionSummary.svelte"
|
||||
@@ -71,10 +71,8 @@
|
||||
{/if}
|
||||
<div
|
||||
data-event={event.id}
|
||||
class="group chat flex items-center justify-end gap-1 px-2"
|
||||
class:chat-start={!isOwn}
|
||||
class:flex-row-reverse={!isOwn}
|
||||
class:chat-end={isOwn}>
|
||||
class="group flex items-center justify-end gap-1 px-2"
|
||||
class:flex-row-reverse={!isOwn}>
|
||||
{#if !isMobile}
|
||||
<Tippy
|
||||
bind:popover
|
||||
@@ -101,16 +99,13 @@
|
||||
{/if}
|
||||
<div class="flex min-w-0 flex-col" class:items-end={isOwn}>
|
||||
<TapTarget
|
||||
class="bg-alt chat-bubble mx-1 mb-2 flex cursor-auto flex-col gap-1 text-left lg:max-w-2xl min-w-[100px]"
|
||||
class="cl-surface-alt mx-1 mb-2 flex min-w-[100px] cursor-auto flex-col gap-1 rounded-2xl px-4 py-3 text-left lg:max-w-2xl"
|
||||
onTap={showMobileMenu}>
|
||||
{#if showPubkey}
|
||||
<div class="flex items-center gap-2">
|
||||
{#if !isOwn}
|
||||
<Button onclick={openProfile} class="flex items-center gap-1">
|
||||
<ProfileCircle
|
||||
pubkey={event.pubkey}
|
||||
class="border border-solid border-base-content"
|
||||
size={4} />
|
||||
<ProfileCircle pubkey={event.pubkey} class="cl-border" size={4} />
|
||||
<div class="flex items-center gap-2">
|
||||
<Button onclick={openProfile} class="text-sm font-bold" style="color: {colorValue}">
|
||||
{$profileDisplay}
|
||||
@@ -118,7 +113,7 @@
|
||||
</div>
|
||||
</Button>
|
||||
{/if}
|
||||
<span class="whitespace-nowrap text-xs opacity-50"
|
||||
<span class="cl-text-subtle whitespace-nowrap text-xs"
|
||||
>{formatTimestampAsTime(event.created_at)}</span>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -126,7 +121,7 @@
|
||||
<Content showEntire {event} />
|
||||
</div>
|
||||
</TapTarget>
|
||||
<div class="row-2 z-feature -mt-4 ml-4">
|
||||
<div class="z-feature -mt-4 ml-4 flex items-center gap-2">
|
||||
<ReactionSummary {event} {deleteReaction} {createReaction} noTooltip />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {sendWrapped} from "@welshman/app"
|
||||
import SmileCircle from "@assets/icons/smile-circle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import EmojiButton from "@lib/components/EmojiButton.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import EmojiButton from "@lib/components2/EmojiButton.svelte"
|
||||
import {makeReaction} from "@app/reactions"
|
||||
|
||||
interface Props {
|
||||
@@ -22,6 +22,6 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<EmojiButton {onEmoji} class="btn join-item btn-xs">
|
||||
<EmojiButton {onEmoji} class="btn-cl-sm">
|
||||
<Icon icon={SmileCircle} size={4} />
|
||||
</EmojiButton>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import ChatMessageEmojiButton from "@app/components/ChatMessageEmojiButton.svelte"
|
||||
import EventInfo from "@app/components/EventInfo.svelte"
|
||||
import {pushModal} from "@app/modal"
|
||||
@@ -19,19 +20,19 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="join border border-solid border-neutral text-xs">
|
||||
<Row gap={1} class="cl-surface cl-border rounded-full px-1 py-1 text-xs">
|
||||
<ChatMessageEmojiButton {event} {pubkeys} />
|
||||
{#if replyTo}
|
||||
<Button class="btn join-item btn-xs" onclick={reply}>
|
||||
<Button size="sm" circle onclick={reply}>
|
||||
<Icon size={4} icon={Reply} />
|
||||
</Button>
|
||||
{/if}
|
||||
{#if edit}
|
||||
<Button class="btn join-item btn-xs" onclick={onEdit}>
|
||||
<Button size="sm" circle onclick={onEdit}>
|
||||
<Icon size={4} icon={Pen} />
|
||||
</Button>
|
||||
{/if}
|
||||
<Button class="btn join-item btn-xs" onclick={showInfo}>
|
||||
<Button size="sm" circle onclick={showInfo}>
|
||||
<Icon size={4} icon={Code2} />
|
||||
</Button>
|
||||
</div>
|
||||
</Row>
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
import Reply from "@assets/icons/reply-2.svg?dataurl"
|
||||
import Copy from "@assets/icons/copy.svg?dataurl"
|
||||
import Code2 from "@assets/icons/code-2.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Modal from "@lib/components/Modal.svelte"
|
||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import EmojiPicker from "@lib/components/EmojiPicker.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import EmojiPicker from "@lib/components2/EmojiPicker.svelte"
|
||||
import EventInfo from "@app/components/EventInfo.svelte"
|
||||
import {makeReaction} from "@app/reactions"
|
||||
import {pushModal} from "@app/modal"
|
||||
@@ -57,29 +58,29 @@
|
||||
|
||||
<Modal>
|
||||
<ModalBody>
|
||||
<div class="flex flex-col gap-2">
|
||||
<Button class="btn btn-neutral" onclick={showInfo}>
|
||||
<Col gap={2}>
|
||||
<Button variant="secondary" onclick={showInfo}>
|
||||
<Icon size={4} icon={Code2} />
|
||||
Message Info
|
||||
</Button>
|
||||
<Button class="btn btn-neutral w-full" onclick={copyText}>
|
||||
<Button variant="secondary" block onclick={copyText}>
|
||||
<Icon size={4} icon={Copy} />
|
||||
Copy Text
|
||||
</Button>
|
||||
<Button class="btn btn-neutral w-full" onclick={sendReply}>
|
||||
<Button variant="secondary" block onclick={sendReply}>
|
||||
<Icon size={4} icon={Reply} />
|
||||
Send Reply
|
||||
</Button>
|
||||
{#if edit}
|
||||
<Button class="btn btn-neutral w-full" onclick={sendEdit}>
|
||||
<Button variant="secondary" block onclick={sendEdit}>
|
||||
<Icon size={4} icon={Pen} />
|
||||
Edit Message
|
||||
</Button>
|
||||
{/if}
|
||||
<Button class="btn btn-primary w-full" onclick={showEmojiPicker}>
|
||||
<Button variant="primary" block onclick={showEmojiPicker}>
|
||||
<Icon size={4} icon={SmileCircle} />
|
||||
Send Reaction
|
||||
</Button>
|
||||
</div>
|
||||
</Col>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
import {fromNostrURI} from "@welshman/util"
|
||||
import {loadMessagingRelayList} from "@welshman/app"
|
||||
import {preventDefault} from "@lib/html"
|
||||
import Field from "@lib/components/Field.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Field from "@lib/components2/Field.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import ProfileMultiSelect from "@app/components/ProfileMultiSelect.svelte"
|
||||
import {goToChat} from "@app/routes"
|
||||
|
||||
@@ -73,11 +73,11 @@
|
||||
</Field>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back}>
|
||||
<Button variant="ghost" onclick={back}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={pubkeys.length === 0}>
|
||||
<Button type="submit" variant="primary" disabled={pubkeys.length === 0}>
|
||||
Create Chat
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
import {pubkey} from "@welshman/app"
|
||||
import Pen2 from "@assets/icons/pen-2.svg?dataurl"
|
||||
import {normalizeTopic} from "@lib/util"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Badge from "@lib/components2/Badge.svelte"
|
||||
import RoomName from "@app/components/RoomName.svelte"
|
||||
import ReactionSummary from "@app/components/ReactionSummary.svelte"
|
||||
import ClassifiedStatus from "@app/components/ClassifiedStatus.svelte"
|
||||
@@ -46,18 +47,20 @@
|
||||
|
||||
<div class="flex grow flex-wrap justify-end gap-2">
|
||||
{#if h && showRoom}
|
||||
<Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full">
|
||||
Posted in #<RoomName {h} {url} />
|
||||
<Link href={makeSpacePath(url, h)}>
|
||||
<Badge variant="neutral" sm>
|
||||
Posted in #<RoomName {h} {url} />
|
||||
</Badge>
|
||||
</Link>
|
||||
{/if}
|
||||
<div class="flex min-w-0 flex-wrap gap-2">
|
||||
{#each uniq(topics) as topic (topic)}
|
||||
<button type="button" class="btn btn-xs rounded-full font-normal">
|
||||
<button type="button" class="badge-cl badge-cl-neutral badge-cl-sm">
|
||||
#{normalizeTopic(topic)}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" />
|
||||
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="cl-tip-left" />
|
||||
<ThunkStatusOrDeleted {event}>
|
||||
<ClassifiedStatus {event} />
|
||||
</ThunkStatusOrDeleted>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ClassifiedForm from "@app/components/ClassifiedForm.svelte"
|
||||
|
||||
type Props = {
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
import {fromPairs} from "@welshman/lib"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {getTag, getTagValues} from "@welshman/util"
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ClassifiedForm from "@app/components/ClassifiedForm.svelte"
|
||||
|
||||
type Props = {
|
||||
|
||||
@@ -6,14 +6,18 @@
|
||||
import {isMobile, preventDefault} from "@lib/html"
|
||||
import {normalizeTopic} from "@lib/util"
|
||||
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Field from "@lib/components/Field.svelte"
|
||||
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 ImagesInput from "@lib/components/ImagesInput.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Field from "@lib/components2/Field.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Grid from "@lib/components2/Grid.svelte"
|
||||
import Input from "@lib/components2/Input.svelte"
|
||||
import Select from "@lib/components2/Select.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ImagesInput from "@lib/components2/ImagesInput.svelte"
|
||||
import CurrencyInput from "@app/components/CurrencyInput.svelte"
|
||||
import TopicMultiSelect from "@app/components/TopicMultiSelect.svelte"
|
||||
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||
@@ -164,21 +168,18 @@
|
||||
<Modal tag="form" onsubmit={preventDefault(submit)}>
|
||||
<ModalBody>
|
||||
{@render header?.()}
|
||||
<div class="col-8 relative">
|
||||
<Col gap={8} class="relative">
|
||||
<Field>
|
||||
{#snippet label()}
|
||||
<p>Title*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<!-- svelte-ignore a11y_autofocus -->
|
||||
<input
|
||||
autofocus={!isMobile}
|
||||
bind:value={title}
|
||||
class="grow"
|
||||
type="text"
|
||||
placeholder="What is this listing for?" />
|
||||
</label>
|
||||
<!-- svelte-ignore a11y_autofocus -->
|
||||
<Input
|
||||
autofocus={!isMobile}
|
||||
bind:value={title}
|
||||
type="text"
|
||||
placeholder="What is this listing for?" />
|
||||
{/snippet}
|
||||
</Field>
|
||||
<Field>
|
||||
@@ -204,12 +205,10 @@
|
||||
<p>Price*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<div class="join grid grid-cols-2">
|
||||
<label class="join-item input input-bordered flex w-full items-center gap-2">
|
||||
<input bind:value={price} class="grow w-32" type="number" />
|
||||
</label>
|
||||
<CurrencyInput class="join-item" bind:value={currency} />
|
||||
</div>
|
||||
<Grid cols={2} gap={2}>
|
||||
<Input bind:value={price} type="number" />
|
||||
<CurrencyInput bind:value={currency} />
|
||||
</Grid>
|
||||
{/snippet}
|
||||
</Field>
|
||||
{#if initialValues}
|
||||
@@ -218,10 +217,10 @@
|
||||
<p>Status*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<select class="select select-bordered w-full" bind:value={status}>
|
||||
<Select bind:value={status}>
|
||||
<option value="active">Active</option>
|
||||
<option value="sold">Sold</option>
|
||||
</select>
|
||||
</Select>
|
||||
{/snippet}
|
||||
</Field>
|
||||
{/if}
|
||||
@@ -233,14 +232,14 @@
|
||||
<ImagesInput bind:value={images} />
|
||||
{/snippet}
|
||||
</Field>
|
||||
</div>
|
||||
</Col>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back} disabled={loading}>
|
||||
<Button variant="ghost" onclick={back} disabled={loading}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={loading}>
|
||||
<Button type="submit" variant="primary" disabled={loading}>
|
||||
<Spinner {loading}>Save Listing</Spinner>
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import {formatTimestamp} from "@welshman/lib"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {getTag, getAddress, getTagValue, getTagValues} from "@welshman/util"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import CurrencySymbol from "@lib/components/CurrencySymbol.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import CurrencySymbol from "@lib/components2/CurrencySymbol.svelte"
|
||||
import ContentLinkBlock from "@app/components/ContentLinkBlock.svelte"
|
||||
import Content from "@app/components/Content.svelte"
|
||||
import ProfileLink from "@app/components/ProfileLink.svelte"
|
||||
@@ -25,20 +25,20 @@
|
||||
</script>
|
||||
|
||||
<Link
|
||||
class="cv col-2 card2 bg-alt w-full cursor-pointer shadow-xl"
|
||||
class="clay-card cl-surface-alt flex w-full cursor-pointer flex-col gap-2 p-4 sm:p-6"
|
||||
href={makeClassifiedPath(url, getAddress(event))}>
|
||||
{#if title}
|
||||
<div class="flex w-full items-center justify-between gap-2">
|
||||
<p class="text-xl">
|
||||
<p class="cl-text text-xl">
|
||||
{title} —
|
||||
<CurrencySymbol code={currency} />{price}
|
||||
</p>
|
||||
<p class="text-sm opacity-75">
|
||||
<p class="cl-text-muted text-sm">
|
||||
{formatTimestamp(event.created_at)}
|
||||
</p>
|
||||
</div>
|
||||
{:else}
|
||||
<p class="mb-3 h-0 text-xs opacity-75">
|
||||
<p class="cl-text-muted mb-3 h-0 text-xs">
|
||||
{formatTimestamp(event.created_at)}
|
||||
</p>
|
||||
{/if}
|
||||
@@ -49,7 +49,7 @@
|
||||
{/each}
|
||||
</div>
|
||||
<div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row">
|
||||
<span class="whitespace-nowrap py-1 text-sm opacity-75">
|
||||
<span class="cl-text-muted whitespace-nowrap py-1 text-sm">
|
||||
Posted by
|
||||
<ProfileLink pubkey={event.pubkey} {url} />
|
||||
{#if h}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import cx from "classnames"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {getTagValue} from "@welshman/util"
|
||||
import {ucFirst} from "@lib/util"
|
||||
import Badge from "@lib/components2/Badge.svelte"
|
||||
|
||||
type Props = {
|
||||
event: TrustedEvent
|
||||
@@ -14,7 +14,7 @@
|
||||
</script>
|
||||
|
||||
{#if status}
|
||||
<div class={cx("btn btn-xs rounded-full", {"btn-primary": status !== "active"})}>
|
||||
<Badge sm variant={status !== "active" ? "primary" : "neutral"}>
|
||||
{ucFirst(status)}
|
||||
</div>
|
||||
</Badge>
|
||||
{/if}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<div class="flex flex-wrap items-center justify-between gap-2">
|
||||
<div class="flex grow flex-wrap justify-end gap-2">
|
||||
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" />
|
||||
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="cl-tip-left" />
|
||||
<ThunkStatusOrDeleted {event} />
|
||||
{#if showActivity}
|
||||
<EventActivity {url} {path} {event} />
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
import NotesMinimalistic from "@assets/icons/notes-minimalistic.svg?dataurl"
|
||||
import CaseMinimalistic from "@assets/icons/case-minimalistic.svg?dataurl"
|
||||
import Revote from "@assets/icons/revote.svg?dataurl"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import {pushModal} from "@app/modal"
|
||||
import CalendarEventCreate from "@app/components/CalendarEventCreate.svelte"
|
||||
import ThreadCreate from "@app/components/ThreadCreate.svelte"
|
||||
@@ -39,33 +39,33 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<ul class="menu whitespace-nowrap rounded-box bg-base-100 p-2 shadow-md" bind:this={ul}>
|
||||
<ul class="clay-card flex flex-col gap-1 whitespace-nowrap p-2" bind:this={ul}>
|
||||
<li>
|
||||
<Button onclick={createGoal}>
|
||||
<Button block class="justify-start" onclick={createGoal}>
|
||||
<Icon size={4} icon={StarFallMinimalistic} />
|
||||
Funding Goal
|
||||
</Button>
|
||||
</li>
|
||||
<li>
|
||||
<Button onclick={createCalendarEvent}>
|
||||
<Button block class="justify-start" onclick={createCalendarEvent}>
|
||||
<Icon size={4} icon={CalendarMinimalistic} />
|
||||
Calendar Event
|
||||
</Button>
|
||||
</li>
|
||||
<li>
|
||||
<Button onclick={createClassified}>
|
||||
<Button block class="justify-start" onclick={createClassified}>
|
||||
<Icon size={4} icon={CaseMinimalistic} />
|
||||
Classified Listing
|
||||
</Button>
|
||||
</li>
|
||||
<li>
|
||||
<Button onclick={createThread}>
|
||||
<Button block class="justify-start" onclick={createThread}>
|
||||
<Icon size={4} icon={NotesMinimalistic} />
|
||||
Create Thread
|
||||
</Button>
|
||||
</li>
|
||||
<li>
|
||||
<Button onclick={createPoll}>
|
||||
<Button block class="justify-start" onclick={createPoll}>
|
||||
<Icon size={4} icon={Revote} />
|
||||
Ask a Question
|
||||
</Button>
|
||||
|
||||
@@ -21,10 +21,12 @@
|
||||
} from "@welshman/content"
|
||||
import type {Parsed} from "@welshman/content"
|
||||
import {preventDefault, stopPropagation} from "@lib/html"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Danger from "@assets/icons/danger-triangle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Alert from "@lib/components2/Alert.svelte"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import ContentToken from "@app/components/ContentToken.svelte"
|
||||
import ContentEmoji from "@app/components/ContentEmoji.svelte"
|
||||
import ContentEmail from "@app/components/ContentEmail.svelte"
|
||||
@@ -144,13 +146,15 @@
|
||||
|
||||
<div class="relative">
|
||||
{#if warning}
|
||||
<div class="card2 card2-sm bg-alt row-2">
|
||||
<Icon icon={Danger} />
|
||||
<p>
|
||||
This note has been flagged by the author as "{warning}".<br />
|
||||
<Button class="link" onclick={ignoreWarning}>Show anyway</Button>
|
||||
</p>
|
||||
</div>
|
||||
<Alert variant="warning">
|
||||
<Row gap={2}>
|
||||
<Icon icon={Danger} />
|
||||
<p>
|
||||
This note has been flagged by the author as "{warning}".<br />
|
||||
<Button class="cl-link" onclick={ignoreWarning}>Show anyway</Button>
|
||||
</p>
|
||||
</Row>
|
||||
</Alert>
|
||||
{:else}
|
||||
<div
|
||||
class="overflow-hidden text-ellipsis wrap-break-word"
|
||||
@@ -204,12 +208,9 @@
|
||||
</div>
|
||||
{#if expandBlock}
|
||||
<div class="relative z-feature -mt-6 flex justify-center py-2">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-neutral"
|
||||
onclick={stopPropagation(preventDefault(expand))}>
|
||||
<Button variant="secondary" onclick={stopPropagation(preventDefault(expand))}>
|
||||
See more
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
</script>
|
||||
|
||||
<code
|
||||
class="w-full overflow-auto whitespace-pre rounded bg-neutral px-1 text-neutral-content"
|
||||
class="cl-surface-alt cl-text w-full overflow-auto whitespace-pre rounded px-1"
|
||||
class:block={isBlock}>
|
||||
{value.trim()}
|
||||
</code>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import LinkRound from "@assets/icons/link-round.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
|
||||
export let value: string
|
||||
</script>
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
import {isRelayUrl, getTagValue} from "@welshman/util"
|
||||
import {Capacitor} from "@capacitor/core"
|
||||
import {preventDefault, stopPropagation} from "@lib/html"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Center from "@lib/components2/Center.svelte"
|
||||
import ContentLinkDetail from "@app/components/ContentLinkDetail.svelte"
|
||||
import ContentLinkUrl from "@app/components/ContentLinkUrl.svelte"
|
||||
import ContentLinkBlockImage from "@app/components/ContentLinkBlockImage.svelte"
|
||||
@@ -53,37 +54,45 @@
|
||||
|
||||
{#if isRoomOrRelay}
|
||||
<div>
|
||||
<ContentLinkUrl {url} class="link-content whitespace-nowrap" />
|
||||
<ContentLinkUrl
|
||||
{url}
|
||||
class="cl-surface-alt cl-text inline-block max-w-full overflow-hidden text-ellipsis whitespace-nowrap rounded px-1" />
|
||||
</div>
|
||||
{:else}
|
||||
<Link {external} {href} class="my-2 block">
|
||||
<div class="overflow-hidden rounded-box">
|
||||
<div class="overflow-hidden" style="border-radius: var(--cl-r-card)">
|
||||
{#if url.match(/\.(mov|webm|mp4)$/) || VIDEO_CONTENT_TYPES.includes(fileType)}
|
||||
<video
|
||||
controls
|
||||
src={url}
|
||||
poster={getVideoPoster(url)}
|
||||
preload="metadata"
|
||||
class="max-h-96 rounded-box object-contain object-center">
|
||||
class="max-h-96 object-contain object-center"
|
||||
style="border-radius: var(--cl-r-card)">
|
||||
<track kind="captions" />
|
||||
</video>
|
||||
{:else if url.match(/\.(jpe?g|png|gif|webp)$/) || IMAGE_CONTENT_TYPES.includes(fileType)}
|
||||
<button type="button" onclick={stopPropagation(preventDefault(expand))}>
|
||||
<ContentLinkBlockImage {value} {event} class="m-auto max-h-96 rounded-box" />
|
||||
<ContentLinkBlockImage
|
||||
{value}
|
||||
{event}
|
||||
class="m-auto max-h-96"
|
||||
style="border-radius: var(--cl-r-card)" />
|
||||
</button>
|
||||
{:else}
|
||||
{#await loadPreview()}
|
||||
<div class="center my-12 w-full">
|
||||
<span class="loading loading-spinner"></span>
|
||||
</div>
|
||||
<Center class="my-12 w-full">
|
||||
<span class="cl-spinner"></span>
|
||||
</Center>
|
||||
{:then preview}
|
||||
<div class="bg-alt flex max-w-xl flex-col leading-normal">
|
||||
<div class="cl-surface-alt flex max-w-xl flex-col leading-normal">
|
||||
{#if preview.image && !hideImage}
|
||||
<img
|
||||
alt=""
|
||||
onerror={onError}
|
||||
src={preview.image}
|
||||
class="bg-alt max-h-72 rounded-t-box object-contain object-center" />
|
||||
class="cl-surface-alt max-h-72 object-contain object-center"
|
||||
style="border-top-left-radius: var(--cl-r-card); border-top-right-radius: var(--cl-r-card)" />
|
||||
{/if}
|
||||
<div class="flex flex-col gap-2 p-4">
|
||||
<strong class="overflow-hidden text-ellipsis whitespace-nowrap"
|
||||
@@ -92,7 +101,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{:catch}
|
||||
<p class="bg-alt p-12 text-center leading-normal">
|
||||
<p class="cl-surface-alt p-12 text-center leading-normal">
|
||||
Unable to load a preview for {url}
|
||||
</p>
|
||||
{/await}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
} from "@welshman/util"
|
||||
import {signer} from "@welshman/app"
|
||||
import LinkRound from "@assets/icons/link-round.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
|
||||
const {value, event, ...props} = $props()
|
||||
|
||||
@@ -87,7 +87,9 @@
|
||||
</script>
|
||||
|
||||
{#if hasError}
|
||||
<a href={url} class="link-content whitespace-nowrap">
|
||||
<a
|
||||
href={url}
|
||||
class="cl-surface-alt inline-flex max-w-full items-center gap-1 overflow-hidden rounded px-1 whitespace-nowrap text-ellipsis">
|
||||
<Icon icon={LinkRound} size={3} class="inline-block" />
|
||||
{displayUrl(url)}
|
||||
</a>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import ContentLinkBlockImage from "@app/components/ContentLinkBlockImage.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
|
||||
const {value, event} = $props()
|
||||
|
||||
@@ -8,5 +8,9 @@
|
||||
</script>
|
||||
|
||||
<Button class="m-auto h-screen w-screen cursor-pointer p-4" onclick={back}>
|
||||
<ContentLinkBlockImage {value} {event} class="m-auto max-h-full max-w-full rounded-box" />
|
||||
<ContentLinkBlockImage
|
||||
{value}
|
||||
{event}
|
||||
class="m-auto max-h-full max-w-full"
|
||||
style="border-radius: var(--cl-r-card);" />
|
||||
</Button>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import {getTagValue} from "@welshman/util"
|
||||
import {preventDefault, stopPropagation} from "@lib/html"
|
||||
import LinkRound from "@assets/icons/link-round.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import ContentLinkDetail from "@app/components/ContentLinkDetail.svelte"
|
||||
import ContentLinkUrl from "@app/components/ContentLinkUrl.svelte"
|
||||
import {pushModal} from "@app/modal"
|
||||
@@ -21,11 +21,13 @@
|
||||
<!-- Use a real link so people can copy the href -->
|
||||
<a
|
||||
href={url}
|
||||
class="link-content whitespace-nowrap"
|
||||
class="cl-surface-alt inline-flex max-w-full items-center gap-1 overflow-hidden rounded px-1 whitespace-nowrap text-ellipsis"
|
||||
onclick={stopPropagation(preventDefault(expand))}>
|
||||
<Icon icon={LinkRound} size={3} class="inline-block" />
|
||||
{displayUrl(url)}
|
||||
</a>
|
||||
{:else}
|
||||
<ContentLinkUrl {url} class="link-content whitespace-nowrap" />
|
||||
<ContentLinkUrl
|
||||
{url}
|
||||
class="cl-surface-alt inline-flex max-w-full items-center gap-1 overflow-hidden rounded px-1 whitespace-nowrap text-ellipsis" />
|
||||
{/if}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import {call, displayUrl} from "@welshman/lib"
|
||||
import {displayRelayUrl, isRelayUrl, normalizeRelayUrl} from "@welshman/util"
|
||||
import LinkRound from "@assets/icons/link-round.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import {PLATFORM_URL} from "@app/env"
|
||||
import {displayRoom, isRoomId, splitRoomId} from "@app/groups"
|
||||
import {makeRoomPath, makeSpacePath} from "@app/routes"
|
||||
@@ -49,10 +49,10 @@
|
||||
|
||||
<Link {external} {href} class={className}>
|
||||
{#if roomReference}
|
||||
~<span class="text-primary">{displayRelayUrl(roomReference.url)}</span> /
|
||||
~<span class="cl-text-primary">{displayRelayUrl(roomReference.url)}</span> /
|
||||
{displayRoom(roomReference.url, roomReference.h)}
|
||||
{:else if relayReference}
|
||||
<span class="text-primary">{displayRelayUrl(relayReference)}</span>
|
||||
<span class="cl-text-primary">{displayRelayUrl(relayReference)}</span>
|
||||
{:else}
|
||||
<Icon icon={LinkRound} size={3} class="inline-block" />
|
||||
{displayUrl(url)}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import {removeUndefined} from "@welshman/lib"
|
||||
import type {ProfilePointer} from "@welshman/content"
|
||||
import {deriveProfileDisplay} from "@welshman/app"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import ProfileDetail from "@app/components/ProfileDetail.svelte"
|
||||
import {pushModal} from "@app/modal"
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
const openProfile = () => pushModal(ProfileDetail, {pubkey: value.pubkey, url})
|
||||
</script>
|
||||
|
||||
<Button onclick={openProfile} class="link-content">
|
||||
<Button onclick={openProfile} class="cl-link">
|
||||
@{$display}
|
||||
</Button>
|
||||
|
||||
@@ -19,10 +19,11 @@
|
||||
isNewline,
|
||||
} from "@welshman/content"
|
||||
import type {Parsed} from "@welshman/content"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Danger from "@assets/icons/danger-triangle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Alert from "@lib/components2/Alert.svelte"
|
||||
import ContentToken from "@app/components/ContentToken.svelte"
|
||||
import ContentEmoji from "@app/components/ContentEmoji.svelte"
|
||||
import ContentEmail from "@app/components/ContentEmail.svelte"
|
||||
@@ -96,13 +97,13 @@
|
||||
|
||||
<div class="relative">
|
||||
{#if warning}
|
||||
<div class="card2 card2-sm bg-alt row-2">
|
||||
<Alert variant="warning" class="items-center">
|
||||
<Icon icon={Danger} />
|
||||
<p>
|
||||
This note has been flagged by the author as "{warning}".<br />
|
||||
<Button class="link" onclick={ignoreWarning}>Show anyway</Button>
|
||||
<Button class="cl-link" onclick={ignoreWarning}>Show anyway</Button>
|
||||
</p>
|
||||
</div>
|
||||
</Alert>
|
||||
{:else}
|
||||
<div class="overflow-hidden text-ellipsis wrap-break-word">
|
||||
{#each shortContent as parsed, i}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import {Router} from "@welshman/router"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {Address, MESSAGE} from "@welshman/util"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import NoteCard from "@app/components/NoteCard.svelte"
|
||||
import NoteContent from "@app/components/NoteContent.svelte"
|
||||
import NoteContentMinimal from "@app/components/NoteContentMinimal.svelte"
|
||||
@@ -48,17 +48,19 @@
|
||||
<NoteContent {url} event={$quote} />
|
||||
{:else if $quote.kind === MESSAGE}
|
||||
<div
|
||||
class="border-l-2 border-solid border-l-primary py-1 pl-2 opacity-90"
|
||||
style="background-color: color-mix(in srgb, var(--color-primary) 10%, var(--color-base-300) 90%);">
|
||||
class="cl-surface-alt py-1 pl-2 opacity-90"
|
||||
style="border-left: 2px solid var(--cl-primary);">
|
||||
<NoteContentMinimal trimParent {url} event={$quote} />
|
||||
</div>
|
||||
{:else}
|
||||
<NoteCard noShadow event={$quote} {url} class="bg-alt rounded-box p-4">
|
||||
<NoteContentMinimal {url} event={$quote} />
|
||||
</NoteCard>
|
||||
<div class="cl-surface-alt overflow-hidden" style="border-radius: var(--cl-r-card);">
|
||||
<NoteCard noShadow event={$quote} {url} class="p-4">
|
||||
<NoteContentMinimal {url} event={$quote} />
|
||||
</NoteCard>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="rounded-box p-4">
|
||||
<div class="cl-surface-alt p-4" style="border-radius: var(--cl-r-card);">
|
||||
<Spinner loading>Loading event...</Spinner>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Bolt from "@assets/icons/bolt.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import {clip} from "@app/toast"
|
||||
|
||||
const {value} = $props()
|
||||
@@ -9,7 +9,7 @@
|
||||
const copy = () => clip(value)
|
||||
</script>
|
||||
|
||||
<Button onclick={copy} class="link-content">
|
||||
<Button onclick={copy} variant="secondary" size="sm" class="max-w-full truncate align-middle">
|
||||
<Icon icon={Bolt} size={3} class="inline-block translate-y-px" />
|
||||
{value.slice(0, 16)}...
|
||||
</Button>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<script lang="ts">
|
||||
import Badge from "@lib/components2/Badge.svelte"
|
||||
|
||||
const {value} = $props()
|
||||
</script>
|
||||
|
||||
<span class="link-content">
|
||||
<Badge variant="neutral">
|
||||
#{value}
|
||||
</span>
|
||||
</Badge>
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
import {preventDefault} from "@lib/html"
|
||||
import {createSearch} from "@welshman/app"
|
||||
import {currencyOptions, displayCurrency} from "@lib/currency"
|
||||
import Suggestions from "@lib/components/Suggestions.svelte"
|
||||
import Suggestions from "@lib/components2/Suggestions.svelte"
|
||||
import CurrencySuggestion from "@app/components/CurrencySuggestion.svelte"
|
||||
import AltArrowDown from "@assets/icons/alt-arrow-down.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Tippy from "@lib/components/Tippy.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Tippy from "@lib/components2/Tippy.svelte"
|
||||
|
||||
interface Props {
|
||||
value: string
|
||||
@@ -66,22 +66,18 @@
|
||||
</script>
|
||||
|
||||
<button
|
||||
class={cx(
|
||||
props.class,
|
||||
{"bg-base-200": currency},
|
||||
"input input-bordered flex items-center gap-2 cursor-pointer",
|
||||
)}
|
||||
class={cx(props.class, "input-cl input-cl-group cursor-pointer", {"cl-surface-alt": currency})}
|
||||
bind:this={wrapper}
|
||||
onfocus={preventDefault(clearAndFocus)}
|
||||
onclick={preventDefault(clearAndFocus)}>
|
||||
<Icon icon={AltArrowDown} />
|
||||
{#if currency}
|
||||
<span class="text-sm ellipsize whitespace-nowrap">
|
||||
<span class="overflow-hidden text-ellipsis whitespace-nowrap text-sm">
|
||||
{displayCurrency(currency)}
|
||||
</span>
|
||||
{:else}
|
||||
<!-- svelte-ignore a11y_autofocus -->
|
||||
<input {autofocus} class="grow" type="text" bind:value={$term} onkeydown={onKeyDown} />
|
||||
<input {autofocus} class="input-cl-bare grow" type="text" bind:value={$term} onkeydown={onKeyDown} />
|
||||
{/if}
|
||||
<Tippy
|
||||
bind:popover
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
import Bolt from "@assets/icons/bolt.svg?dataurl"
|
||||
import SmileCircle from "@assets/icons/smile-circle.svg?dataurl"
|
||||
import MenuDots from "@assets/icons/menu-dots.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Tippy from "@lib/components/Tippy.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Tippy from "@lib/components2/Tippy.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import ZapButton from "@app/components/ZapButton.svelte"
|
||||
import EmojiButton from "@lib/components/EmojiButton.svelte"
|
||||
import EmojiButton from "@lib/components2/EmojiButton.svelte"
|
||||
import EventMenu from "@app/components/EventMenu.svelte"
|
||||
import {ENABLE_ZAPS} from "@app/env"
|
||||
import {publishReaction} from "@app/reactions"
|
||||
@@ -43,13 +44,13 @@
|
||||
let popover: Instance | undefined = $state()
|
||||
</script>
|
||||
|
||||
<div class="join items-center rounded-full">
|
||||
<Row gap={1} class="cl-surface-alt cl-border rounded-full px-1 py-1">
|
||||
{#if ENABLE_ZAPS && !hideZap}
|
||||
<ZapButton {url} {event} class="btn join-item btn-neutral btn-xs">
|
||||
<ZapButton {url} {event} class="btn-cl-sm">
|
||||
<Icon icon={Bolt} size={4} />
|
||||
</ZapButton>
|
||||
{/if}
|
||||
<EmojiButton {onEmoji} class="btn join-item btn-neutral btn-xs">
|
||||
<EmojiButton {onEmoji} class="btn-cl-sm">
|
||||
<Icon icon={SmileCircle} size={4} />
|
||||
</EmojiButton>
|
||||
<Tippy
|
||||
@@ -58,8 +59,8 @@
|
||||
component={EventMenu}
|
||||
props={{url, noun, event, customActions, onClick: hidePopover}}
|
||||
params={{trigger: "manual", interactive: true}}>
|
||||
<Button class="btn join-item btn-neutral btn-xs" onclick={showPopover}>
|
||||
<Button class="btn-cl-sm" onclick={showPopover}>
|
||||
<Icon icon={MenuDots} size={4} />
|
||||
</Button>
|
||||
</Tippy>
|
||||
</div>
|
||||
</Row>
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
import {repository} from "@welshman/app"
|
||||
import {deriveChecked} from "@app/notifications"
|
||||
import Reply from "@assets/icons/reply-2.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Badge from "@lib/components2/Badge.svelte"
|
||||
|
||||
const {url, path, event}: {url: string; path: string; event: TrustedEvent} = $props()
|
||||
|
||||
@@ -22,13 +23,13 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="flex-inline btn btn-neutral btn-xs gap-1 rounded-full">
|
||||
<Icon icon={Reply} />
|
||||
<Badge sm>
|
||||
<Icon icon={Reply} size={4} />
|
||||
<span>{$replies.length} {$replies.length === 1 ? "reply" : "replies"}</span>
|
||||
</div>
|
||||
<div class="btn btn-neutral btn-xs relative rounded-full">
|
||||
</Badge>
|
||||
<Badge sm>
|
||||
{#if gt(lastActive, $checked)}
|
||||
<div class="h-2 w-2 rounded-full bg-primary"></div>
|
||||
<div class="h-2 w-2 rounded-full" style="background-color: var(--cl-primary);"></div>
|
||||
{/if}
|
||||
Active {formatTimestampRelative(lastActive)}
|
||||
</div>
|
||||
</Badge>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import Confirm from "@lib/components/Confirm.svelte"
|
||||
import Confirm from "@lib/components2/Confirm.svelte"
|
||||
import {publishDelete} from "@app/deletes"
|
||||
import {canEnforceNip70} from "@app/relays"
|
||||
import {clearModals} from "@app/modal"
|
||||
|
||||
@@ -8,15 +8,16 @@
|
||||
import FileText from "@assets/icons/file-text.svg?dataurl"
|
||||
import Copy from "@assets/icons/copy.svg?dataurl"
|
||||
import UserCircle from "@assets/icons/user-circle.svg?dataurl"
|
||||
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 ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import FieldInline from "@lib/components2/FieldInline.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Badge from "@lib/components2/Badge.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import {clip} from "@app/toast"
|
||||
|
||||
type Props = {
|
||||
@@ -60,13 +61,13 @@
|
||||
<p>Event Link</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<div class="input-cl input-cl-group w-full">
|
||||
<Icon icon={FileText} />
|
||||
<input type="text" class="ellipsize min-w-0 grow" value={nevent1} />
|
||||
<input type="text" class="input-cl-bare overflow-hidden text-ellipsis" value={nevent1} />
|
||||
<Button onclick={copyLink} class="flex items-center">
|
||||
<Icon icon={Copy} />
|
||||
</Button>
|
||||
</label>
|
||||
</div>
|
||||
{/snippet}
|
||||
</FieldInline>
|
||||
<FieldInline>
|
||||
@@ -74,13 +75,13 @@
|
||||
<p>Author Pubkey</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<div class="input-cl input-cl-group w-full">
|
||||
<Icon icon={UserCircle} />
|
||||
<input type="text" class="ellipsize min-w-0 grow" value={npub1} />
|
||||
<input type="text" class="input-cl-bare overflow-hidden text-ellipsis" value={npub1} />
|
||||
<Button onclick={copyPubkey} class="flex items-center">
|
||||
<Icon icon={Copy} />
|
||||
</Button>
|
||||
</label>
|
||||
</div>
|
||||
{/snippet}
|
||||
</FieldInline>
|
||||
{#if !url && seenOn.size > 0}
|
||||
@@ -91,24 +92,25 @@
|
||||
{#snippet input()}
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{#each seenOn as url, i (url)}
|
||||
<span class="bg-alt badge flex gap-1">
|
||||
<Badge>
|
||||
{displayRelayUrl(url)}
|
||||
</span>
|
||||
</Badge>
|
||||
{/each}
|
||||
</div>
|
||||
{/snippet}
|
||||
</FieldInline>
|
||||
{/if}
|
||||
<div class="relative">
|
||||
<pre class="card2 card2-sm bg-alt overflow-auto text-xs"><code>{json}</code></pre>
|
||||
<pre
|
||||
class="cl-surface-alt cl-border overflow-auto rounded-2xl p-4 text-xs"><code>{json}</code></pre>
|
||||
<p class="absolute right-2 top-2 flex grow items-center justify-between">
|
||||
<Button onclick={copyJson} class="btn btn-neutral btn-sm flex items-center">
|
||||
<Button variant="secondary" size="sm" onclick={copyJson} class="flex items-center">
|
||||
<Icon icon={Copy} /> Copy
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-primary grow" onclick={() => history.back()}>Got it</Button>
|
||||
<Button variant="primary" class="grow" onclick={() => history.back()}>Got it</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
import TrashBin2 from "@assets/icons/trash-bin-2.svg?dataurl"
|
||||
import Danger from "@assets/icons/danger.svg?dataurl"
|
||||
import {setKey} from "@lib/implicit"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Confirm from "@lib/components/Confirm.svelte"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Confirm from "@lib/components2/Confirm.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import EventInfo from "@app/components/EventInfo.svelte"
|
||||
import Report from "@app/components/Report.svelte"
|
||||
import EventShare from "@app/components/EventShare.svelte"
|
||||
@@ -78,43 +78,33 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<ul class="menu whitespace-nowrap rounded-box bg-base-100 p-2 shadow-md" bind:this={ul}>
|
||||
<div class="clay-card flex flex-col gap-1 whitespace-nowrap p-2" bind:this={ul}>
|
||||
{#if isRoot}
|
||||
<li>
|
||||
<Button onclick={share}>
|
||||
<Icon size={4} icon={ShareCircle} />
|
||||
Share to Chat
|
||||
</Button>
|
||||
</li>
|
||||
{/if}
|
||||
<li>
|
||||
<Button onclick={showInfo}>
|
||||
<Icon size={4} icon={Code2} />
|
||||
{noun} Details
|
||||
<Button block onclick={share}>
|
||||
<Icon size={4} icon={ShareCircle} />
|
||||
Share to Chat
|
||||
</Button>
|
||||
</li>
|
||||
{/if}
|
||||
<Button block onclick={showInfo}>
|
||||
<Icon size={4} icon={Code2} />
|
||||
{noun} Details
|
||||
</Button>
|
||||
{@render customActions?.()}
|
||||
{#if event.pubkey === $pubkey}
|
||||
<li>
|
||||
<Button onclick={showDelete} class="text-error">
|
||||
<Button block variant="danger" onclick={showDelete}>
|
||||
<Icon size={4} icon={TrashBin2} />
|
||||
Delete {noun}
|
||||
</Button>
|
||||
{:else}
|
||||
<Button block variant="danger" onclick={report}>
|
||||
<Icon size={4} icon={Danger} />
|
||||
Report Content
|
||||
</Button>
|
||||
{#if $userIsAdmin}
|
||||
<Button block variant="danger" onclick={showAdminDelete}>
|
||||
<Icon size={4} icon={TrashBin2} />
|
||||
Delete {noun}
|
||||
</Button>
|
||||
</li>
|
||||
{:else}
|
||||
<li>
|
||||
<Button class="text-error" onclick={report}>
|
||||
<Icon size={4} icon={Danger} />
|
||||
Report Content
|
||||
</Button>
|
||||
</li>
|
||||
{#if $userIsAdmin}
|
||||
<li>
|
||||
<Button class="text-error" onclick={showAdminDelete}>
|
||||
<Icon size={4} icon={TrashBin2} />
|
||||
Delete {noun}
|
||||
</Button>
|
||||
</li>
|
||||
{/if}
|
||||
{/if}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
import {isMobile, preventDefault} from "@lib/html"
|
||||
import {fly} from "@lib/transition"
|
||||
import Paperclip from "@assets/icons/paperclip-2.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||
import ChatComposeParent from "@app/components/ChatComposeParent.svelte"
|
||||
import {publishComment} from "@app/comments"
|
||||
@@ -101,7 +101,7 @@
|
||||
bind:this={form}
|
||||
onsubmit={preventDefault(submit)}
|
||||
class="left-content bottom-sai right-sai fixed z-feature mb-14 md:mb-0 w-full md:w-auto pr-2">
|
||||
<div class="card2 mx-2 my-2 bg-alt shadow-md">
|
||||
<div class="clay-card mx-2 my-2 p-4">
|
||||
{#if parent}
|
||||
<ChatComposeParent event={parent} clear={() => onClearParent?.()} verb="Replying to" />
|
||||
{/if}
|
||||
@@ -111,18 +111,19 @@
|
||||
</div>
|
||||
<Button
|
||||
data-tip="Add an image"
|
||||
class="tooltip tooltip-left absolute bottom-1 right-2"
|
||||
circle
|
||||
class="absolute bottom-1 right-2"
|
||||
onclick={selectFiles}>
|
||||
{#if $uploading}
|
||||
<span class="loading loading-spinner loading-xs"></span>
|
||||
<span class="cl-spinner"></span>
|
||||
{:else}
|
||||
<Icon icon={Paperclip} size={3} />
|
||||
{/if}
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex justify-between pt-3">
|
||||
<Button class="btn btn-link" onclick={onClose}>Cancel</Button>
|
||||
<Button type="submit" class="btn btn-primary">Post Reply</Button>
|
||||
<Button onclick={onClose}>Cancel</Button>
|
||||
<Button type="submit" variant="primary">Post Reply</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
|
||||
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
|
||||
import {setKey} from "@lib/implicit"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Modal from "@lib/components/Modal.svelte"
|
||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import RoomName from "@app/components/RoomName.svelte"
|
||||
import {roomsByUrl} from "@app/groups"
|
||||
import {makeRoomPath} from "@app/routes"
|
||||
@@ -41,23 +41,20 @@
|
||||
</ModalHeader>
|
||||
<div class="grid grid-cols-3 gap-2">
|
||||
{#each $roomsByUrl.get(url) || [] as room (room.h)}
|
||||
<button
|
||||
type="button"
|
||||
class="btn"
|
||||
class:btn-neutral={selection !== room.h}
|
||||
class:btn-primary={selection === room.h}
|
||||
<Button
|
||||
variant={selection === room.h ? "primary" : "secondary"}
|
||||
onclick={() => toggleRoom(room.h)}>
|
||||
#<RoomName {...room} />
|
||||
</button>
|
||||
</Button>
|
||||
{/each}
|
||||
</div>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back}>
|
||||
<Button onclick={back}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={!selection}>
|
||||
<Button type="submit" variant="primary" disabled={!selection}>
|
||||
Share {noun}
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import type {TrustedEvent, EventContent} from "@welshman/util"
|
||||
import {getTagValue} from "@welshman/util"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import ReactionSummary from "@app/components/ReactionSummary.svelte"
|
||||
import ThunkStatusOrDeleted from "@app/components/ThunkStatusOrDeleted.svelte"
|
||||
import EventActivity from "@app/components/EventActivity.svelte"
|
||||
@@ -34,11 +34,11 @@
|
||||
|
||||
<div class="flex grow flex-wrap justify-end gap-2">
|
||||
{#if h && showRoom}
|
||||
<Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full">
|
||||
<Link href={makeSpacePath(url, h)} class="badge-cl badge-cl-neutral badge-cl-sm">
|
||||
Posted in #<RoomName {h} {url} />
|
||||
</Link>
|
||||
{/if}
|
||||
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" />
|
||||
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="cl-tip-left" />
|
||||
<ThunkStatusOrDeleted {event} />
|
||||
{#if showActivity}
|
||||
<EventActivity {url} {path} {event} />
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
import Paperclip from "@assets/icons/paperclip-2.svg?dataurl"
|
||||
import Bolt from "@assets/icons/bolt.svg?dataurl"
|
||||
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Field from "@lib/components/Field.svelte"
|
||||
import FieldInline from "@lib/components/FieldInline.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Modal from "@lib/components/Modal.svelte"
|
||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Field from "@lib/components2/Field.svelte"
|
||||
import FieldInline from "@lib/components2/FieldInline.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import EditorContent from "@app/editor/EditorContent.svelte"
|
||||
import {pushToast} from "@app/toast"
|
||||
import {PROTECTED, publishRoomQuote} from "@app/groups"
|
||||
@@ -145,18 +145,17 @@
|
||||
<ModalTitle>Create a Funding Goal</ModalTitle>
|
||||
<ModalSubtitle>Request contributions for your fundraiser.</ModalSubtitle>
|
||||
</ModalHeader>
|
||||
<div class="col-8 relative">
|
||||
<div class="relative flex flex-col gap-8">
|
||||
<Field>
|
||||
{#snippet label()}
|
||||
<p>Title*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<label class="input-cl input-cl-group">
|
||||
<!-- svelte-ignore a11y_autofocus -->
|
||||
<input
|
||||
autofocus={!isMobile}
|
||||
bind:value={title}
|
||||
class="grow"
|
||||
type="text"
|
||||
placeholder="What do funds go towards?" />
|
||||
</label>
|
||||
@@ -175,11 +174,11 @@
|
||||
</Field>
|
||||
<Button
|
||||
data-tip="Add an image"
|
||||
class="tooltip tooltip-left absolute bottom-1 right-2"
|
||||
class="absolute bottom-1 right-2"
|
||||
onclick={selectFiles}
|
||||
disabled={loading}>
|
||||
{#if $uploading}
|
||||
<span class="loading loading-spinner loading-xs"></span>
|
||||
<span class="cl-spinner"></span>
|
||||
{:else}
|
||||
<Icon icon={Paperclip} size={3} />
|
||||
{/if}
|
||||
@@ -192,16 +191,17 @@
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<div class="flex grow justify-end">
|
||||
<label class="input input-bordered flex w-auto items-center gap-2">
|
||||
<label class="input-cl input-cl-group w-auto">
|
||||
<Icon icon={Bolt} />
|
||||
<input bind:value={amount} type="number" class="w-28 grow" />
|
||||
<p class="shrink-0 opacity-50">sats</p>
|
||||
<input bind:value={amount} type="number" class="input-cl-bare w-28" />
|
||||
<p class="cl-text-subtle shrink-0">sats</p>
|
||||
</label>
|
||||
</div>
|
||||
{/snippet}
|
||||
</FieldInline>
|
||||
<input
|
||||
class="range range-primary -mt-2 w-full"
|
||||
class="-mt-2 w-full"
|
||||
style="accent-color: var(--cl-primary);"
|
||||
type="range"
|
||||
min="1000"
|
||||
max="100000"
|
||||
@@ -211,11 +211,11 @@
|
||||
</div>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back} disabled={loading}>
|
||||
<Button variant="ghost" onclick={back} disabled={loading}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={$uploading || loading}>
|
||||
<Button type="submit" variant="primary" disabled={$uploading || loading}>
|
||||
<Spinner {loading}>Create Goal</Spinner>
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<script lang="ts">
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {getTagValue} from "@welshman/util"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import Content from "@app/components/Content.svelte"
|
||||
import ProfileLink from "@app/components/ProfileLink.svelte"
|
||||
import GoalActions from "@app/components/GoalActions.svelte"
|
||||
@@ -20,24 +22,27 @@
|
||||
const h = getTagValue("h", event.tags)
|
||||
</script>
|
||||
|
||||
<Link
|
||||
class="cv col-2 card2 bg-alt w-full cursor-pointer shadow-md"
|
||||
href={makeGoalPath(url, event.id)}>
|
||||
<p class="text-2xl">{event.content}</p>
|
||||
<Content
|
||||
event={{content: summary, tags: event.tags}}
|
||||
{url}
|
||||
expandMode="inline"
|
||||
minLength={50}
|
||||
maxLength={300} />
|
||||
<GoalSummary {url} {event} />
|
||||
<div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row">
|
||||
<span class="whitespace-nowrap py-1 text-sm opacity-75">
|
||||
Posted by <ProfileLink pubkey={event.pubkey} {url} />
|
||||
{#if h}
|
||||
in <RoomLink {url} {h} />
|
||||
{/if}
|
||||
</span>
|
||||
<GoalActions showActivity {url} {event} />
|
||||
</div>
|
||||
<Link class="w-full" href={makeGoalPath(url, event.id)}>
|
||||
<Col
|
||||
gap={2}
|
||||
class="clay-card clay-card-interactive cl-surface-alt w-full p-4 sm:p-6"
|
||||
style="content-visibility: auto;">
|
||||
<p class="text-2xl">{event.content}</p>
|
||||
<Content
|
||||
event={{content: summary, tags: event.tags}}
|
||||
{url}
|
||||
expandMode="inline"
|
||||
minLength={50}
|
||||
maxLength={300} />
|
||||
<GoalSummary {url} {event} />
|
||||
<div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row">
|
||||
<Text size="sm" muted class="whitespace-nowrap py-1">
|
||||
Posted by <ProfileLink pubkey={event.pubkey} {url} />
|
||||
{#if h}
|
||||
in <RoomLink {url} {h} />
|
||||
{/if}
|
||||
</Text>
|
||||
<GoalActions showActivity {url} {event} />
|
||||
</div>
|
||||
</Col>
|
||||
</Link>
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
import {deriveItemsByKey, deriveArray} from "@welshman/store"
|
||||
import {repository, getValidZap} from "@welshman/app"
|
||||
import Bolt from "@assets/icons/bolt.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Stat from "@lib/components2/Stat.svelte"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Progress from "@lib/components2/Progress.svelte"
|
||||
import ZapButton from "@app/components/ZapButton.svelte"
|
||||
|
||||
type Props = {
|
||||
@@ -31,24 +35,17 @@
|
||||
const daysOld = Math.ceil((now() - event.created_at) / DAY)
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-8 {props.class}">
|
||||
<div class="flex gap-8">
|
||||
<div>
|
||||
<p class="text-xl text-primary">{zapAmount} sats</p>
|
||||
<p class="text-sm opacity-75">funded of {goalAmount} sats</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-xl">{contributorsCount}</p>
|
||||
<p class="text-sm opacity-75">{contributorsCount === 1 ? "contributor" : "contributors"}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-xl">{daysOld}</p>
|
||||
<p class="text-sm opacity-75">{daysOld === 1 ? "day" : "days"} old</p>
|
||||
</div>
|
||||
</div>
|
||||
<progress class="progress progress-primary" value={zapAmount} max={goalAmount}></progress>
|
||||
<ZapButton {url} {event} class="btn btn-primary lg:m-auto lg:px-20">
|
||||
<Col gap={8} class={props.class}>
|
||||
<Row gap={8} class="items-start">
|
||||
<Stat value="{zapAmount} sats" label="funded of {goalAmount} sats" gradient />
|
||||
<Stat
|
||||
value={contributorsCount}
|
||||
label={contributorsCount === 1 ? "contributor" : "contributors"} />
|
||||
<Stat value={daysOld} label="{daysOld === 1 ? 'day' : 'days'} old" />
|
||||
</Row>
|
||||
<Progress value={zapAmount} max={goalAmount} />
|
||||
<ZapButton {url} {event} class="btn-cl btn-cl-primary lg:m-auto lg:px-20">
|
||||
<Icon icon={Bolt} />
|
||||
Contribute to this goal
|
||||
</ZapButton>
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
<style>
|
||||
.icon-tile {
|
||||
color: var(--cl-text);
|
||||
border-radius: var(--cl-r-icon);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.icon-tile:hover {
|
||||
background: var(--cl-primary);
|
||||
color: var(--cl-primary-content);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import {createSearch} from "@welshman/app"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Magnifier from "@assets/icons/magnifier.svg?dataurl"
|
||||
|
||||
const iconModules = import.meta.glob("@assets/icons/*.svg", {
|
||||
@@ -43,9 +55,9 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<label class="input-cl input-cl-group">
|
||||
<Icon icon={Magnifier} />
|
||||
<input bind:value={searchTerm} class="grow" type="text" placeholder="Search icons..." />
|
||||
<input bind:value={searchTerm} class="input-cl-bare" type="text" placeholder="Search icons..." />
|
||||
</label>
|
||||
<div class="mt-2 max-h-80 overflow-y-auto">
|
||||
<div class="grid grid-cols-8 gap-2 p-2">
|
||||
@@ -53,9 +65,9 @@
|
||||
<button
|
||||
type="button"
|
||||
title={icon.name}
|
||||
class="flex aspect-square items-center justify-center rounded-box transition-colors hover:bg-primary hover:text-primary-content"
|
||||
class="icon-tile flex aspect-square items-center justify-center"
|
||||
onclick={() => handleSelect(icon.url)}>
|
||||
<Icon icon={icon.url} class="h-6 w-6" />
|
||||
<Icon icon={icon.url} size={6} />
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Modal from "@lib/components/Modal.svelte"
|
||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import IconPicker from "@app/components/IconPicker.svelte"
|
||||
|
||||
type Props = {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import Card from "@lib/components2/Card.svelte"
|
||||
import IconPicker from "@app/components/IconPicker.svelte"
|
||||
|
||||
type Props = {
|
||||
@@ -8,6 +9,6 @@
|
||||
const {onSelect}: Props = $props()
|
||||
</script>
|
||||
|
||||
<div class="w-96 rounded-box bg-base-100 p-4 shadow-2xl">
|
||||
<Card class="w-96">
|
||||
<IconPicker {onSelect} />
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
@@ -1,41 +1,42 @@
|
||||
<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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import {PLATFORM_NAME} from "@app/env"
|
||||
</script>
|
||||
|
||||
<Modal
|
||||
><ModalBody>
|
||||
<Modal>
|
||||
<ModalBody>
|
||||
<ModalHeader>
|
||||
<ModalTitle>What is a bunker link?</ModalTitle>
|
||||
</ModalHeader>
|
||||
<p>
|
||||
<Link external class="link" href="https://nostr.com/">Nostr</Link> uses "keys" instead of passwords
|
||||
to identify users. This allows users to own their social identity instead of renting it from a tech
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
<Text>
|
||||
<Link external styled href="https://nostr.com/">Nostr</Link> uses "keys" instead of passwords
|
||||
to identify users. This allows users to own their social identity instead of renting it from a
|
||||
tech company, and can bring it with them from app to app.
|
||||
</Text>
|
||||
<Text>
|
||||
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.
|
||||
</Text>
|
||||
<Text>
|
||||
One way to log in with a remote signer is using a "bunker link" which is more secure and
|
||||
decentralized than other solutions. Check your signer for a link beginning with "bunker://",
|
||||
copy it into {PLATFORM_NAME}, and you should be good to go!
|
||||
</p>
|
||||
<p>
|
||||
If you don't have a signer yet, <Link external class="link" href="https://nsec.app/"
|
||||
>nsec.app</Link>
|
||||
</Text>
|
||||
<Text>
|
||||
If you don't have a signer yet, <Link external styled href="https://nsec.app/">nsec.app</Link>
|
||||
is a great way to get started. You can find more signers on <Link
|
||||
external
|
||||
class="link"
|
||||
styled
|
||||
href="https://nostrapps.com#signers">nostrapps.com</Link
|
||||
>.
|
||||
</p>
|
||||
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
|
||||
</ModalBody></Modal>
|
||||
</Text>
|
||||
<Button variant="primary" onclick={() => history.back()}>Got it</Button>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
<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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import {PLATFORM_NAME} from "@app/env"
|
||||
</script>
|
||||
|
||||
<Modal
|
||||
><ModalBody>
|
||||
<Modal>
|
||||
<ModalBody>
|
||||
<ModalHeader>
|
||||
<ModalTitle>What is a nostr address?</ModalTitle>
|
||||
</ModalHeader>
|
||||
<p>
|
||||
{PLATFORM_NAME} hosts spaces on the <Link external href="https://nostr.com/" class="underline"
|
||||
<Text>
|
||||
{PLATFORM_NAME} hosts spaces on the <Link external styled href="https://nostr.com/"
|
||||
>Nostr protocol</Link
|
||||
>. Nostr uses "nostr addresses" to make it easier for people to find you, without having to
|
||||
memorize your public key (your user id).
|
||||
</p>
|
||||
<p>
|
||||
</Text>
|
||||
<Text>
|
||||
There are several providers of nostr addresses, including several clients. You can find a list
|
||||
and more information on <Link
|
||||
external
|
||||
href="https://nostr.how/en/guides/get-verified"
|
||||
class="underline">nostr.how</Link
|
||||
and more information on <Link external styled href="https://nostr.how/en/guides/get-verified"
|
||||
>nostr.how</Link
|
||||
>.
|
||||
</p>
|
||||
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
|
||||
</ModalBody></Modal>
|
||||
</Text>
|
||||
<Button variant="primary" onclick={() => history.back()}>Got it</Button>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<script lang="ts">
|
||||
import {session} from "@welshman/app"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
|
||||
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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import KeyRecoveryRequest from "@app/components/KeyRecoveryRequest.svelte"
|
||||
import {PLATFORM_NAME} from "@app/env"
|
||||
import {pushModal} from "@app/modal"
|
||||
@@ -24,36 +25,36 @@
|
||||
<ModalHeader>
|
||||
<ModalTitle>What is a private key?</ModalTitle>
|
||||
</ModalHeader>
|
||||
<p>
|
||||
<Text>
|
||||
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
|
||||
</Text>
|
||||
<Text>
|
||||
On <Link external styled 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>
|
||||
</Text>
|
||||
{#if $session?.email}
|
||||
<p>
|
||||
<Text>
|
||||
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>
|
||||
</Text>
|
||||
<Text>If you'd like to switch to self-custody, please click below to get started.</Text>
|
||||
{:else}
|
||||
<Button class="btn btn-primary" onclick={back}>Got it</Button>
|
||||
<Button variant="primary" onclick={back}>Got it</Button>
|
||||
{/if}
|
||||
</ModalBody>
|
||||
{#if $session?.email}
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back}>
|
||||
<Button onclick={back}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button class="btn btn-primary" onclick={startRecoveryRequest}>
|
||||
<Button variant="primary" onclick={startRecoveryRequest}>
|
||||
<Icon icon={CheckCircle} />
|
||||
I want to hold my own keys
|
||||
</Button>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
</script>
|
||||
|
||||
<Modal
|
||||
@@ -12,21 +13,21 @@
|
||||
<ModalHeader>
|
||||
<ModalTitle>What is nostr?</ModalTitle>
|
||||
</ModalHeader>
|
||||
<p>
|
||||
<Link external href="https://nostr.com/" class="link">Nostr</Link> is way to build social apps that
|
||||
<Text>
|
||||
<Link external styled href="https://nostr.com/">Nostr</Link> is way to build social apps that
|
||||
talk to each other. Users own their social identity instead of renting it from a tech company, and
|
||||
can take it with them.
|
||||
</p>
|
||||
<p>
|
||||
</Text>
|
||||
<Text>
|
||||
If you'd like to learn more about what other apps exist in the nostr ecosystem, please visit <Link
|
||||
external
|
||||
class="link"
|
||||
styled
|
||||
href="https://nostrapps.com/">nostrapps.com</Link
|
||||
>.
|
||||
</p>
|
||||
<p>
|
||||
</Text>
|
||||
<Text>
|
||||
To learn more about how to manage your keys, or to set up an account, try
|
||||
<Link external class="link" href="https://nosta.me/">nosta.me</Link>.
|
||||
</p>
|
||||
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
|
||||
<Link external styled href="https://nosta.me/">nosta.me</Link>.
|
||||
</Text>
|
||||
<Button variant="primary" onclick={() => history.back()}>Got it</Button>
|
||||
</ModalBody></Modal>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<script lang="ts">
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Modal from "@lib/components/Modal.svelte"
|
||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import {PLATFORM_NAME} from "@app/env"
|
||||
</script>
|
||||
|
||||
@@ -14,19 +15,19 @@
|
||||
<ModalHeader>
|
||||
<ModalTitle>What is a relay?</ModalTitle>
|
||||
</ModalHeader>
|
||||
<p>
|
||||
{PLATFORM_NAME} hosts spaces on the <Link external href="https://nostr.com/" class="underline"
|
||||
<Text>
|
||||
{PLATFORM_NAME} hosts spaces on the <Link external styled href="https://nostr.com/"
|
||||
>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.
|
||||
</p>
|
||||
<p>
|
||||
</Text>
|
||||
<Text>
|
||||
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>
|
||||
</Text>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button>
|
||||
<Button variant="primary" onclick={() => history.back()}>Got it</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
|
||||
const back = () => history.back()
|
||||
</script>
|
||||
@@ -14,21 +15,21 @@
|
||||
<ModalHeader>
|
||||
<ModalTitle>What are digital signatures?</ModalTitle>
|
||||
</ModalHeader>
|
||||
<p>
|
||||
<Text>
|
||||
Most online services ask their users to trust them that they're being honest, and they usually
|
||||
are. However, traditional social media platforms have the ability to <strong
|
||||
>create forged content</strong> that can appear to be genuinely authored, but which are actually
|
||||
counterfeit.
|
||||
</p>
|
||||
<p>
|
||||
On <Link external href="https://nostr.com/">Nostr</Link>, all your content is authenticated
|
||||
</Text>
|
||||
<Text>
|
||||
On <Link external styled 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.
|
||||
</p>
|
||||
<p>
|
||||
</Text>
|
||||
<Text>
|
||||
The result is that you don't normally have to trust service providers not to tamper with the
|
||||
information flowing through the network — instead, your client software can prove that a given
|
||||
piece of data is authentic.
|
||||
</p>
|
||||
<Button class="btn btn-primary" onclick={back}>Got it</Button>
|
||||
</Text>
|
||||
<Button variant="primary" onclick={back}>Got it</Button>
|
||||
</ModalBody></Modal>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script lang="ts">
|
||||
import {deriveZapperForPubkey} from "@welshman/app"
|
||||
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Modal from "@lib/components/Modal.svelte"
|
||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ProfileLink from "@app/components/ProfileLink.svelte"
|
||||
|
||||
const {pubkey} = $props()
|
||||
@@ -23,7 +23,7 @@
|
||||
<ModalTitle>Unable to Zap</ModalTitle>
|
||||
</ModalHeader>
|
||||
<p>
|
||||
Zapping <ProfileLink {pubkey} class="text-primary!" /> isn't possible right now because
|
||||
Zapping <ProfileLink {pubkey} class="cl-text-primary" /> isn't possible right now because
|
||||
{#if $zapper}
|
||||
their zap receiver isn't correctly set up.
|
||||
{:else}
|
||||
@@ -32,7 +32,7 @@
|
||||
</p>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back}>
|
||||
<Button variant="ghost" onclick={back}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import CloseCircle from "@assets/icons/close-circle.svg?dataurl"
|
||||
import AddCircle from "@assets/icons/add-circle.svg?dataurl"
|
||||
import GallerySend from "@assets/icons/gallery-send.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import {uploadFile} from "@app/uploads"
|
||||
|
||||
interface Props {
|
||||
@@ -79,28 +79,28 @@
|
||||
<label
|
||||
for={id}
|
||||
aria-label="Drag and drop files here."
|
||||
style="background-image: url({url});"
|
||||
class="relative flex h-24 w-24 shrink-0 cursor-pointer items-center justify-center rounded-full border-2 border-solid border-base-content bg-base-300 bg-cover bg-center transition-all"
|
||||
style="background-image: url({url}); background-color: var(--cl-bg-alt); border-color: {active
|
||||
? 'var(--cl-primary)'
|
||||
: 'var(--cl-border)'};"
|
||||
class="relative flex h-24 w-24 shrink-0 cursor-pointer items-center justify-center rounded-full border-2 border-solid bg-cover bg-center transition-all"
|
||||
class:transparent={!url}
|
||||
class:border-primary={active}
|
||||
ondragenter={stopPropagation(preventDefault(onDragEnter))}
|
||||
ondragover={stopPropagation(preventDefault(onDragOver))}
|
||||
ondragleave={stopPropagation(preventDefault(onDragLeave))}
|
||||
ondrop={stopPropagation(preventDefault(onDrop))}>
|
||||
<div
|
||||
class="absolute right-0 top-0 h-5 w-5 overflow-hidden rounded-full bg-primary"
|
||||
class:bg-error={url}
|
||||
class:bg-primary={!url}>
|
||||
class="absolute right-0 top-0 h-5 w-5 overflow-hidden rounded-full"
|
||||
style="background-color: {url ? 'var(--cl-danger)' : 'var(--cl-primary)'};">
|
||||
{#if url}
|
||||
<span
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
onmousedown={stopPropagation(onClear)}
|
||||
ontouchstart={stopPropagation(onClear)}>
|
||||
<Icon icon={CloseCircle} class="scale-150 bg-base-300!" />
|
||||
<Icon icon={CloseCircle} class="scale-150 cl-surface-alt" />
|
||||
</span>
|
||||
{:else}
|
||||
<Icon icon={AddCircle} class="scale-150 bg-base-300!" />
|
||||
<Icon icon={AddCircle} class="scale-150 cl-surface-alt" />
|
||||
{/if}
|
||||
</div>
|
||||
{#if !url}
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
import ArrowDown from "@assets/icons/arrow-down.svg?dataurl"
|
||||
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 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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Field from "@lib/components2/Field.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import ProgressBar from "@app/components/ProgressBar.svelte"
|
||||
import {pushToast} from "@app/toast"
|
||||
import {PLATFORM_NAME} from "@app/env"
|
||||
@@ -129,9 +129,9 @@
|
||||
Password*
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<label class="input-cl input-cl-group w-full">
|
||||
<Icon icon={Key} />
|
||||
<input bind:value={password} onchange={onPasswordChange} class="grow" type="password" />
|
||||
<input bind:value={password} onchange={onPasswordChange} type="password" />
|
||||
</label>
|
||||
{/snippet}
|
||||
{#snippet info()}
|
||||
@@ -139,12 +139,12 @@
|
||||
{/snippet}
|
||||
</Field>
|
||||
{/if}
|
||||
<div class="flex flex-col">
|
||||
<Button class="btn {didDownload ? 'btn-neutral' : 'btn-primary'}" onclick={downloadKey}>
|
||||
<div class="flex flex-col gap-2">
|
||||
<Button variant={didDownload ? "secondary" : "primary"} onclick={downloadKey}>
|
||||
Download my key
|
||||
<Icon icon={ArrowDown} />
|
||||
</Button>
|
||||
<Button class="btn btn-link no-underline" onclick={toggleUsePassword}>
|
||||
<Button variant="ghost" onclick={toggleUsePassword}>
|
||||
{#if usePassword}
|
||||
Nevermind, I want to download the plain version
|
||||
{:else}
|
||||
@@ -157,11 +157,11 @@
|
||||
<ProgressBar current={step} total={totalSteps} />
|
||||
{/if}
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back}>
|
||||
<Button variant="ghost" onclick={back}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button disabled={!didDownload} class="btn btn-primary" type="submit">
|
||||
<Button disabled={!didDownload} variant="primary" type="submit">
|
||||
{submitText}
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
import {preventDefault} from "@lib/html"
|
||||
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 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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import StringMultiInput from "@lib/components/StringMultiInput.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import StringMultiInput from "@lib/components2/StringMultiInput.svelte"
|
||||
import KeyDownload from "@app/components/KeyDownload.svelte"
|
||||
import {pushToast} from "@app/toast"
|
||||
import {pushModal, clearModals} from "@app/modal"
|
||||
@@ -87,11 +87,11 @@
|
||||
<StringMultiInput bind:value={otps} placeholder="Enter your recovery codes..." />
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back}>
|
||||
<Button variant="ghost" onclick={back}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={loading || otps.length < 2}>
|
||||
<Button type="submit" variant="primary" disabled={loading || otps.length < 2}>
|
||||
<Spinner {loading}>Confirm recovery</Spinner>
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
import {preventDefault} from "@lib/html"
|
||||
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 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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import {pushModal} from "@app/modal"
|
||||
import KeyRecoveryConfirm from "@app/components/KeyRecoveryConfirm.svelte"
|
||||
|
||||
@@ -59,11 +59,11 @@
|
||||
</p>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back}>
|
||||
<Button variant="ghost" onclick={back}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={loading}>
|
||||
<Button type="submit" variant="primary" disabled={loading}>
|
||||
<Spinner {loading}>Request recovery</Spinner>
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
<script lang="ts">
|
||||
import Login from "@assets/icons/login-3.svg?dataurl"
|
||||
import AddCircle from "@assets/icons/add-circle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
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 CardButton from "@lib/components/CardButton.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import CardButton from "@lib/components2/CardButton.svelte"
|
||||
import Heading from "@lib/components2/Heading.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import LogIn from "@app/components/LogIn.svelte"
|
||||
import SignUp from "@app/components/SignUp.svelte"
|
||||
import {PLATFORM_TERMS, PLATFORM_PRIVACY, PLATFORM_NAME} from "@app/env"
|
||||
@@ -20,11 +22,11 @@
|
||||
<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>
|
||||
<Heading level={1} class="text-center">Welcome to {PLATFORM_NAME}!</Heading>
|
||||
<Text class="text-center">The chat app built for self-hosted communities.</Text>
|
||||
</div>
|
||||
<Button onclick={logIn}>
|
||||
<CardButton class="btn-primary">
|
||||
<Button onclick={logIn} block class="!p-0">
|
||||
<CardButton>
|
||||
{#snippet icon()}
|
||||
<div><Icon icon={Login} size={7} /></div>
|
||||
{/snippet}
|
||||
@@ -36,7 +38,7 @@
|
||||
{/snippet}
|
||||
</CardButton>
|
||||
</Button>
|
||||
<Button onclick={signUp} class="btn-neutral">
|
||||
<Button onclick={signUp} block class="!p-0">
|
||||
<CardButton>
|
||||
{#snippet icon()}
|
||||
<div><Icon icon={AddCircle} size={7} /></div>
|
||||
@@ -49,10 +51,10 @@
|
||||
{/snippet}
|
||||
</CardButton>
|
||||
</Button>
|
||||
<p class="text-center text-xs opacity-75">
|
||||
<Text size="sm" muted class="text-center">
|
||||
By using {PLATFORM_NAME}, you consent to our
|
||||
<Link external class="link" href={PLATFORM_TERMS}>Terms of Service</Link> and
|
||||
<Link external class="link" href={PLATFORM_PRIVACY}>Privacy Policy</Link>.
|
||||
</p>
|
||||
<Link external styled href={PLATFORM_TERMS}>Terms of Service</Link> and
|
||||
<Link external styled href={PLATFORM_PRIVACY}>Privacy Policy</Link>.
|
||||
</Text>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
import Cpu from "@assets/icons/cpu-bolt.svg?dataurl"
|
||||
import Compass from "@assets/icons/compass-big.svg?dataurl"
|
||||
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 Icon from "@lib/components2/Icon.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Heading from "@lib/components2/Heading.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import SignUp from "@app/components/SignUp.svelte"
|
||||
import InfoNostr from "@app/components/InfoNostr.svelte"
|
||||
import LogInBunker from "@app/components/LogInBunker.svelte"
|
||||
@@ -94,16 +96,17 @@
|
||||
|
||||
<Modal>
|
||||
<ModalBody>
|
||||
<h1 class="heading">Log in with Nostr</h1>
|
||||
<p class="m-auto max-w-sm text-center">
|
||||
<Heading level={1} class="text-center">Log in with Nostr</Heading>
|
||||
<Text 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.
|
||||
</p>
|
||||
<Button variant="ghost" class="inline cl-link" onclick={() => pushModal(InfoNostr)}
|
||||
>nostr protocol</Button
|
||||
>, which allows you to own your social identity.
|
||||
</Text>
|
||||
{#if getNip07()}
|
||||
<Button {disabled} onclick={loginWithNip07} class="btn btn-primary">
|
||||
<Button variant="primary" block {disabled} onclick={loginWithNip07}>
|
||||
{#if loading === "nip07"}
|
||||
<span class="loading loading-spinner mr-3"></span>
|
||||
<span class="cl-spinner mr-3"></span>
|
||||
{:else}
|
||||
<Icon icon={Widget} />
|
||||
{/if}
|
||||
@@ -111,9 +114,9 @@
|
||||
</Button>
|
||||
{/if}
|
||||
{#each signers as app}
|
||||
<Button {disabled} class="btn btn-primary" onclick={() => loginWithNip55(app)}>
|
||||
<Button variant="primary" block {disabled} onclick={() => loginWithNip55(app)}>
|
||||
{#if loading === "nip55"}
|
||||
<span class="loading loading-spinner mr-3"></span>
|
||||
<span class="cl-spinner mr-3"></span>
|
||||
{:else}
|
||||
<img src={app.iconUrl} alt={app.name} width="20" height="20" />
|
||||
{/if}
|
||||
@@ -121,26 +124,27 @@
|
||||
</Button>
|
||||
{/each}
|
||||
{#if hasPomade && !hasSigner}
|
||||
<Button {disabled} onclick={loginWithEmail} class="btn btn-primary">
|
||||
<Button variant="primary" block {disabled} onclick={loginWithEmail}>
|
||||
<Icon icon={Letter} />
|
||||
Log in with Email
|
||||
</Button>
|
||||
{/if}
|
||||
<Button
|
||||
variant={hasSigner || hasPomade ? "secondary" : "primary"}
|
||||
block
|
||||
onclick={loginWithBunker}
|
||||
{disabled}
|
||||
class="btn {hasSigner || hasPomade ? 'btn-neutral' : 'btn-primary'}">
|
||||
{disabled}>
|
||||
<Icon icon={Cpu} />
|
||||
Log in with Remote Signer
|
||||
</Button>
|
||||
{#if hasPomade && hasSigner}
|
||||
<Button {disabled} onclick={loginWithEmail} class="btn">
|
||||
<Button variant="ghost" block {disabled} onclick={loginWithEmail}>
|
||||
<Icon icon={Letter} />
|
||||
Log in with Email
|
||||
</Button>
|
||||
{/if}
|
||||
{#if !hasSigner}
|
||||
<Button {disabled} onclick={loginWithKey} class="btn btn-neutral">
|
||||
<Button variant="secondary" block {disabled} onclick={loginWithKey}>
|
||||
<Icon icon={Key} />
|
||||
Log in with Key
|
||||
</Button>
|
||||
@@ -150,14 +154,14 @@
|
||||
external
|
||||
{disabled}
|
||||
href="https://nostrapps.com#signers"
|
||||
class="btn {hasSigner || hasPomade ? '' : 'btn-neutral'}">
|
||||
class="btn-cl btn-cl-block {hasSigner || hasPomade ? 'btn-cl-ghost' : 'btn-cl-secondary'}">
|
||||
<Icon icon={Compass} />
|
||||
Browse Signer Apps
|
||||
</Link>
|
||||
{/if}
|
||||
<div class="text-sm">
|
||||
<Text size="sm">
|
||||
Need an account?
|
||||
<Button class="link" onclick={signUp}>Register instead</Button>
|
||||
</div>
|
||||
<Button variant="ghost" class="inline cl-link" onclick={signUp}>Register instead</Button>
|
||||
</Text>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
import {makeSecret} from "@welshman/util"
|
||||
import {loginWithNip01, loginWithNip46} from "@welshman/app"
|
||||
import {preventDefault} from "@lib/html"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import BunkerConnect from "@app/components/BunkerConnect.svelte"
|
||||
import BunkerUrl from "@app/components/BunkerUrl.svelte"
|
||||
import {Nip46Controller} from "@app/nip46"
|
||||
@@ -151,20 +151,20 @@
|
||||
<BunkerConnect {controller} />
|
||||
{:else}
|
||||
<BunkerUrl {controller} />
|
||||
<Button class="btn {$bunker ? 'btn-neutral' : 'btn-primary'}" onclick={selectConnect}
|
||||
<Button variant={$bunker ? "secondary" : "primary"} onclick={selectConnect}
|
||||
>Log in with a QR code instead</Button>
|
||||
{#if isIos}
|
||||
<Button class="btn btn-neutral" onclick={openSigner}>Open in Signer</Button>
|
||||
<Button variant="secondary" onclick={openSigner}>Open in Signer</Button>
|
||||
{/if}
|
||||
{/if}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back} disabled={$loading}>
|
||||
<Button variant="ghost" onclick={back} disabled={$loading}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
{#if mode === "bunker"}
|
||||
<Button type="submit" class="btn btn-primary" disabled={$loading || !$bunker}>
|
||||
<Button type="submit" variant="primary" disabled={$loading || !$bunker}>
|
||||
<Spinner loading={$loading}>Next</Spinner>
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -2,20 +2,20 @@
|
||||
import {uniq} from "@welshman/lib"
|
||||
import {Client} from "@pomade/core"
|
||||
import {preventDefault} from "@lib/html"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import FieldInline from "@lib/components/FieldInline.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import FieldInline from "@lib/components2/FieldInline.svelte"
|
||||
import Letter from "@assets/icons/letter.svg?dataurl"
|
||||
import Key from "@assets/icons/key.svg?dataurl"
|
||||
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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import LogInOTP from "@app/components/LogInOTP.svelte"
|
||||
import LogInSelect from "@app/components/LogInSelect.svelte"
|
||||
import {deleteDeactivatedPomadeSessions, loginWithPomade} from "@app/pomade"
|
||||
@@ -96,9 +96,9 @@
|
||||
<p>Email*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<label class="input-cl input-cl-group">
|
||||
<Icon icon={Letter} />
|
||||
<input type="email" bind:value={email} />
|
||||
<input type="email" class="input-cl-bare" bind:value={email} />
|
||||
</label>
|
||||
{/snippet}
|
||||
</FieldInline>
|
||||
@@ -107,24 +107,24 @@
|
||||
<p>Password*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<label class="input-cl input-cl-group">
|
||||
<Icon icon={Key} />
|
||||
<input type="password" bind:value={password} />
|
||||
<input type="password" class="input-cl-bare" bind:value={password} />
|
||||
</label>
|
||||
{/snippet}
|
||||
</FieldInline>
|
||||
<p class="text-sm">
|
||||
Forgot your password? <Button class="link" onclick={loginWithOTP}
|
||||
Forgot your password? <Button class="cl-link p-0" onclick={loginWithOTP}
|
||||
>Log in with a one-time access code</Button
|
||||
>.
|
||||
</p>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back} disabled={loading}>
|
||||
<Button variant="ghost" onclick={back} disabled={loading}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={loading || !email || !password}>
|
||||
<Button type="submit" variant="primary" disabled={loading || !email || !password}>
|
||||
<Spinner {loading}>Log in</Spinner>
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -4,21 +4,22 @@
|
||||
import {decrypt} from "nostr-tools/nip49"
|
||||
import {preventDefault} from "@lib/html"
|
||||
import {nsecDecode} from "@lib/util"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import FieldInline from "@lib/components/FieldInline.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import FieldInline from "@lib/components2/FieldInline.svelte"
|
||||
import Alert from "@lib/components2/Alert.svelte"
|
||||
import Key from "@assets/icons/key.svg?dataurl"
|
||||
import Danger from "@assets/icons/danger-triangle.svg?dataurl"
|
||||
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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import {clearModals} from "@app/modal"
|
||||
import {setChecked} from "@app/notifications"
|
||||
import {pushToast} from "@app/toast"
|
||||
@@ -85,7 +86,7 @@
|
||||
<p>Your Key*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<label class="input-cl input-cl-group w-full">
|
||||
<Icon icon={Key} />
|
||||
<input type="password" bind:value={keyInput} placeholder="nsec1..." />
|
||||
</label>
|
||||
@@ -97,31 +98,31 @@
|
||||
<p>Password*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<label class="input-cl input-cl-group w-full">
|
||||
<Icon icon={Key} />
|
||||
<input type="password" bind:value={password} placeholder="Your password" />
|
||||
</label>
|
||||
{/snippet}
|
||||
</FieldInline>
|
||||
{/if}
|
||||
<div class="card2 card2-sm bg-alt flex flex-col gap-2 text-sm">
|
||||
<Alert variant="warning" class="flex-col text-sm">
|
||||
<strong class="flex items-center gap-2">
|
||||
<Icon icon={Danger} />
|
||||
Please note!
|
||||
</strong>
|
||||
<p>
|
||||
Logging in this way is not a best practice. For better security, please consider using a
|
||||
<Link external href="https://nostrapps.com#signers" class="link">signer app</Link>
|
||||
<Link external styled href="https://nostrapps.com#signers">signer app</Link>
|
||||
to keep your keys safe.
|
||||
</p>
|
||||
</div>
|
||||
</Alert>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back} disabled={loading}>
|
||||
<Button variant="ghost" onclick={back} disabled={loading}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={!canSubmit}>
|
||||
<Button type="submit" variant="primary" disabled={!canSubmit}>
|
||||
<Spinner {loading}>Log in</Spinner>
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<script lang="ts">
|
||||
import {Client} from "@pomade/core"
|
||||
import {preventDefault} from "@lib/html"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import FieldInline from "@lib/components/FieldInline.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import FieldInline from "@lib/components2/FieldInline.svelte"
|
||||
import Letter from "@assets/icons/letter.svg?dataurl"
|
||||
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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import LogInOTPConfirm from "@app/components/LogInOTPConfirm.svelte"
|
||||
import {POMADE_NETWORK_ERROR_MESSAGE} from "@app/pomade"
|
||||
import {pushModal} from "@app/modal"
|
||||
@@ -69,7 +69,7 @@
|
||||
<p>Email*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<label class="input-cl input-cl-group w-full">
|
||||
<Icon icon={Letter} />
|
||||
<input type="email" bind:value={email} />
|
||||
</label>
|
||||
@@ -77,11 +77,11 @@
|
||||
</FieldInline>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back} disabled={loading}>
|
||||
<Button variant="ghost" onclick={back} disabled={loading}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={loading || !email}>
|
||||
<Button type="submit" variant="primary" disabled={loading || !email}>
|
||||
<Spinner {loading}>Log in</Spinner>
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
import {uniq} from "@welshman/lib"
|
||||
import {Client} from "@pomade/core"
|
||||
import {preventDefault} from "@lib/html"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import StringMultiInput from "@lib/components/StringMultiInput.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import StringMultiInput from "@lib/components2/StringMultiInput.svelte"
|
||||
import LogInSelect from "@app/components/LogInSelect.svelte"
|
||||
import {pushModal, clearModals} from "@app/modal"
|
||||
import {setChecked} from "@app/notifications"
|
||||
@@ -99,11 +99,11 @@
|
||||
<StringMultiInput bind:value={otps} placeholder="Enter your login codes..." />
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back} disabled={loading}>
|
||||
<Button variant="ghost" onclick={back} disabled={loading}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={loading || otps.length < 3}>
|
||||
<Button type="submit" variant="primary" disabled={loading || otps.length < 3}>
|
||||
<Spinner {loading}>Log In</Spinner>
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
import type {AccountOption} from "@pomade/core"
|
||||
import {Client} from "@pomade/core"
|
||||
import {uniqBy} from "@welshman/lib"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import Profile from "@app/components/Profile.svelte"
|
||||
import {deleteDeactivatedPomadeSessions, loginWithPomade} from "@app/pomade"
|
||||
import {getPomadeLoginFailureMessage, POMADE_NETWORK_ERROR_MESSAGE} from "@app/pomade"
|
||||
@@ -73,16 +73,17 @@
|
||||
<div class="flex flex-col gap-2">
|
||||
{#each uniqBy(o => o.pubkey, options) as option (option.pubkey)}
|
||||
<Button
|
||||
variant="secondary"
|
||||
onclick={() => selectAccount(option)}
|
||||
disabled={loading}
|
||||
class="card2 bg-alt flex w-full items-center p-3 text-left">
|
||||
class="flex w-full items-center p-3 text-left">
|
||||
<Profile inert pubkey={option.pubkey} />
|
||||
</Button>
|
||||
{/each}
|
||||
</div>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back} disabled={loading}>
|
||||
<Button variant="ghost" onclick={back} disabled={loading}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<script lang="ts">
|
||||
import {preventDefault} from "@lib/html"
|
||||
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
|
||||
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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import {logout} from "@app/session"
|
||||
|
||||
const back = () => history.back()
|
||||
@@ -32,14 +33,14 @@
|
||||
<ModalHeader>
|
||||
<ModalTitle>Are you sure you want<br />to log out?</ModalTitle>
|
||||
</ModalHeader>
|
||||
<p class="text-center">Your local database will be cleared.</p>
|
||||
<Text class="text-center">Your local database will be cleared.</Text>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back}>
|
||||
<Button variant="ghost" onclick={back}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={loading}>
|
||||
<Button type="submit" variant="primary" disabled={loading}>
|
||||
<Spinner {loading}>Log Out</Spinner>
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
import Shield from "@assets/icons/shield-minimalistic.svg?dataurl"
|
||||
import Bell from "@assets/icons/bell.svg?dataurl"
|
||||
import Wallet from "@assets/icons/wallet.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
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 Icon from "@lib/components2/Icon.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import Grid from "@lib/components2/Grid.svelte"
|
||||
import Profile from "@app/components/Profile.svelte"
|
||||
import LogOut from "@app/components/LogOut.svelte"
|
||||
import {pushModal} from "@app/modal"
|
||||
@@ -28,11 +29,11 @@
|
||||
<Profile inert pubkey={$pubkey} />
|
||||
</Link>
|
||||
{/if}
|
||||
<div class="grid grid-cols-3 gap-3 w-full">
|
||||
<Grid cols={3} gap={3} class="w-full">
|
||||
<Link
|
||||
replaceState
|
||||
href="/settings/alerts"
|
||||
class="aspect-square btn h-[unset] btn-neutral flex flex-col gap-2 text-center">
|
||||
class="clay-card clay-card-sm clay-card-interactive aspect-square flex flex-col gap-2 items-center justify-center text-center p-3 cl-text">
|
||||
<Icon icon={Bell} size={5} />
|
||||
Alerts
|
||||
</Link>
|
||||
@@ -40,7 +41,7 @@
|
||||
<Link
|
||||
replaceState
|
||||
href="/settings/wallet"
|
||||
class="aspect-square btn h-[unset] btn-neutral flex flex-col gap-2 text-center">
|
||||
class="clay-card clay-card-sm clay-card-interactive aspect-square flex flex-col gap-2 items-center justify-center text-center p-3 cl-text">
|
||||
<Icon icon={Wallet} size={5} />
|
||||
Wallet
|
||||
</Link>
|
||||
@@ -48,29 +49,29 @@
|
||||
<Link
|
||||
replaceState
|
||||
href="/settings/relays"
|
||||
class="aspect-square btn h-[unset] btn-neutral flex flex-col gap-2 text-center">
|
||||
class="clay-card clay-card-sm clay-card-interactive aspect-square flex flex-col gap-2 items-center justify-center text-center p-3 cl-text">
|
||||
<Icon icon={Server} size={5} />
|
||||
Relays
|
||||
</Link>
|
||||
<Link
|
||||
replaceState
|
||||
href="/settings/content"
|
||||
class="aspect-square btn h-[unset] btn-neutral flex flex-col gap-2 text-center">
|
||||
class="clay-card clay-card-sm clay-card-interactive aspect-square flex flex-col gap-2 items-center justify-center text-center p-3 cl-text">
|
||||
<Icon icon={GalleryMinimalistic} size={5} />
|
||||
Content
|
||||
</Link>
|
||||
<Link
|
||||
replaceState
|
||||
href="/settings/privacy"
|
||||
class="aspect-square btn h-[unset] btn-neutral flex flex-col gap-2 text-center">
|
||||
class="clay-card clay-card-sm clay-card-interactive aspect-square flex flex-col gap-2 items-center justify-center text-center p-3 cl-text">
|
||||
<Icon icon={Shield} size={5} />
|
||||
Privacy
|
||||
</Link>
|
||||
</div>
|
||||
</Grid>
|
||||
<div class="flex gap-3 items-center opacity-75 text-sm">
|
||||
<Button onclick={toggleTheme}>Theme</Button>
|
||||
/
|
||||
<Link replaceState href="/settings/about">About</Link>
|
||||
<Link replaceState styled href="/settings/about">About</Link>
|
||||
/
|
||||
<Button onclick={logout}>Log Out</Button>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import {onMount, mount, unmount} from "svelte"
|
||||
import Drawer from "@lib/components/Drawer.svelte"
|
||||
import Dialog from "@lib/components/Dialog.svelte"
|
||||
import Drawer from "@lib/components2/Drawer.svelte"
|
||||
import Dialog from "@lib/components2/Dialog.svelte"
|
||||
import {modal, modalStack, popModal} from "@app/modal"
|
||||
|
||||
const closeModal = () => {
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
import {formatTimestamp} from "@welshman/lib"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import Danger from "@assets/icons/danger-triangle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import Profile from "@app/components/Profile.svelte"
|
||||
import ProfileName from "@app/components/ProfileName.svelte"
|
||||
import {goToEvent} from "@app/routes"
|
||||
@@ -39,11 +40,11 @@
|
||||
<div class="flex flex-col gap-2 {restProps.class}" class:shadow-md={!noShadow}>
|
||||
{#if muted}
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="row-2 relative">
|
||||
<Row class="relative">
|
||||
<Icon icon={Danger} class="mt-1" />
|
||||
<p>You have muted this person.</p>
|
||||
</div>
|
||||
<Button class="link ml-8" onclick={ignoreMute}>Show anyway</Button>
|
||||
</Row>
|
||||
<Button class="cl-link ml-8" onclick={ignoreMute}>Show anyway</Button>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import type {ComponentProps} from "svelte"
|
||||
import {getTag, getTagValue, getTagValues} from "@welshman/util"
|
||||
import CurrencySymbol from "@lib/components/CurrencySymbol.svelte"
|
||||
import CurrencySymbol from "@lib/components2/CurrencySymbol.svelte"
|
||||
import Content from "@app/components/Content.svelte"
|
||||
import ContentLinkBlock from "@app/components/ContentLinkBlock.svelte"
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
<CalendarEventDate event={props.event} />
|
||||
<div class="flex grow flex-col">
|
||||
<CalendarEventHeader event={props.event} />
|
||||
<div class="flex py-2 opacity-50">
|
||||
<div class="h-px grow bg-base-content opacity-25"></div>
|
||||
<div class="flex py-2">
|
||||
<div class="cl-divider-soft grow"></div>
|
||||
</div>
|
||||
<Content {...props} />
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
formatTimestampAsTime,
|
||||
} from "@welshman/lib"
|
||||
import ClockCircle from "@assets/icons/clock-circle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import ContentMinimal from "@app/components/ContentMinimal.svelte"
|
||||
|
||||
const props: ComponentProps<typeof ContentMinimal> = $props()
|
||||
@@ -16,21 +19,21 @@
|
||||
const end = $derived(parseInt(meta.end))
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<Col>
|
||||
<div class="flex grow flex-wrap justify-between gap-2">
|
||||
<p class="text-sm">{meta.title || meta.name}</p>
|
||||
<Text size="sm">{meta.title || meta.name}</Text>
|
||||
{#if !isNaN(start) && !isNaN(end)}
|
||||
{@const startDateDisplay = formatTimestampAsDate(start)}
|
||||
{@const endDateDisplay = formatTimestampAsDate(end)}
|
||||
{@const isSingleDay = startDateDisplay === endDateDisplay}
|
||||
<div class="flex items-center gap-2">
|
||||
<Row>
|
||||
<Icon icon={ClockCircle} size={4} />
|
||||
<span class="hidden sm:block">{formatTimestampAsDate(start)}</span>
|
||||
{formatTimestampAsTime(start)} — {isSingleDay
|
||||
? formatTimestampAsTime(end)
|
||||
: formatTimestamp(end)}
|
||||
</div>
|
||||
</Row>
|
||||
{/if}
|
||||
</div>
|
||||
<ContentMinimal {...props} />
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
import {deriveItemsByKey, deriveArray} from "@welshman/store"
|
||||
import {repository, getValidZap} from "@welshman/app"
|
||||
import Bolt from "@assets/icons/bolt.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import ContentMinimal from "@app/components/ContentMinimal.svelte"
|
||||
|
||||
const props: ComponentProps<typeof ContentMinimal> = $props()
|
||||
@@ -29,9 +31,9 @@
|
||||
|
||||
<div class="flex justify-between">
|
||||
<span class="text-sm">{props.event.content}</span>
|
||||
<div class="flex items-center gap-1">
|
||||
<Row gap={1}>
|
||||
<Icon icon={Bolt} size={4} />
|
||||
{zapAmount}/{goalAmount} sats funded
|
||||
</div>
|
||||
</Row>
|
||||
</div>
|
||||
<ContentMinimal {...props} event={fakeEvent} />
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
import {derived} from "svelte/store"
|
||||
import {POLL_RESPONSE} from "@welshman/util"
|
||||
import ContentMinimal from "@app/components/ContentMinimal.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import {deriveEvents} from "@app/repository"
|
||||
import {getPollResults} from "@app/polls"
|
||||
|
||||
@@ -13,7 +15,7 @@
|
||||
const results = derived(responses, $responses => getPollResults(props.event, $responses))
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-0">
|
||||
<Col gap={0}>
|
||||
<ContentMinimal {...props} />
|
||||
<span class="text-xs opacity-50">{$results.voters} voter{$results.voters === 1 ? "" : "s"}</span>
|
||||
</div>
|
||||
<Text size="xs" subtle>{$results.voters} voter{$results.voters === 1 ? "" : "s"}</Text>
|
||||
</Col>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import type {ComponentProps} from "svelte"
|
||||
import {getTagValue} from "@welshman/util"
|
||||
import ContentMinimal from "@app/components/ContentMinimal.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
|
||||
const props: ComponentProps<typeof ContentMinimal> = $props()
|
||||
|
||||
@@ -9,7 +10,7 @@
|
||||
</script>
|
||||
|
||||
{#if title}
|
||||
<span class="text-sm">{title}</span>
|
||||
<Text size="sm">{title}</Text>
|
||||
{/if}
|
||||
{#if props.event.content}
|
||||
<ContentMinimal {...props} />
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import {POLL_RESPONSE} from "@welshman/util"
|
||||
import PollVotes from "@app/components/PollVotes.svelte"
|
||||
import Content from "@app/components/Content.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
|
||||
const props: ComponentProps<typeof Content> = $props()
|
||||
|
||||
@@ -20,10 +21,10 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-3">
|
||||
<Col gap={3}>
|
||||
<Content event={props.event} showEntire url={props.url} />
|
||||
|
||||
{#if props.url}
|
||||
<PollVotes url={props.url} event={props.event} />
|
||||
{/if}
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
@@ -2,17 +2,19 @@
|
||||
import type {ComponentProps} from "svelte"
|
||||
import {getTagValue} from "@welshman/util"
|
||||
import Content from "@app/components/Content.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
|
||||
const props: ComponentProps<typeof Content> = $props()
|
||||
|
||||
const title = getTagValue("title", props.event.tags)
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<Col gap={2}>
|
||||
{#if title}
|
||||
<p class="text-xl">{title}</p>
|
||||
<Text size="xl">{title}</Text>
|
||||
{/if}
|
||||
{#if props.event.content}
|
||||
<Content {...props} />
|
||||
{/if}
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
import type {TrustedEvent, EventContent} from "@welshman/util"
|
||||
import {Router} from "@welshman/router"
|
||||
import SmileCircle from "@assets/icons/smile-circle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import EmojiButton from "@lib/components/EmojiButton.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import EmojiButton from "@lib/components2/EmojiButton.svelte"
|
||||
import NoteContent from "@app/components/NoteContent.svelte"
|
||||
import NoteCard from "@app/components/NoteCard.svelte"
|
||||
import ReactionSummary from "@app/components/ReactionSummary.svelte"
|
||||
@@ -40,11 +40,11 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<NoteCard {event} {url} class="cv card2 bg-alt">
|
||||
<NoteCard {event} {url} class="cv clay-card cl-surface-alt p-4">
|
||||
<NoteContent {event} expandMode="inline" />
|
||||
<div class="flex w-full justify-between gap-2">
|
||||
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-right">
|
||||
<EmojiButton {onEmoji} class="btn btn-neutral btn-xs h-[26px] rounded-box">
|
||||
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="cl-tip-right">
|
||||
<EmojiButton {onEmoji} variant="secondary" size="sm" circle>
|
||||
<Icon icon={SmileCircle} size={4} />
|
||||
</EmojiButton>
|
||||
</ReactionSummary>
|
||||
|
||||
@@ -5,16 +5,16 @@
|
||||
import {preventDefault} from "@lib/html"
|
||||
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 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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import StringMultiInput from "@lib/components/StringMultiInput.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import StringMultiInput from "@lib/components2/StringMultiInput.svelte"
|
||||
import PasswordResetConfirm from "@app/components/PasswordResetConfirm.svelte"
|
||||
import {pushToast} from "@app/toast"
|
||||
import {pushModal} from "@app/modal"
|
||||
@@ -94,11 +94,11 @@
|
||||
<StringMultiInput bind:value={otps} placeholder="Enter your confirmation codes..." />
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back}>
|
||||
<Button variant="ghost" onclick={back}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={loading || otps.length < 2}>
|
||||
<Button type="submit" variant="primary" disabled={loading || otps.length < 2}>
|
||||
<Spinner {loading}>Continue</Spinner>
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
import Key from "@assets/icons/key.svg?dataurl"
|
||||
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 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 ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import FieldInline from "@lib/components2/FieldInline.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import {loginWithPomade, deleteCurrentPomadeSession} from "@app/pomade"
|
||||
import {clearModals} from "@app/modal"
|
||||
import {pushToast} from "@app/toast"
|
||||
@@ -98,7 +98,7 @@
|
||||
<p>New Password*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<label class="input-cl input-cl-group w-full">
|
||||
<Icon icon={Key} />
|
||||
<input type="password" bind:value={password} />
|
||||
</label>
|
||||
@@ -106,11 +106,11 @@
|
||||
</FieldInline>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back}>
|
||||
<Button variant="ghost" onclick={back}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button class="btn btn-primary" type="submit" disabled={loading || !password}>
|
||||
<Button variant="primary" type="submit" disabled={loading || !password}>
|
||||
<Spinner {loading}>Continue</Spinner>
|
||||
<Icon icon={AltArrowRight} />
|
||||
</Button>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<script lang="ts">
|
||||
import UserCircle from "@assets/icons/user-circle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Card from "@lib/components2/Card.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Profile from "@app/components/Profile.svelte"
|
||||
import ProfileInfo from "@app/components/ProfileInfo.svelte"
|
||||
import ProfileBadges from "@app/components/ProfileBadges.svelte"
|
||||
@@ -18,18 +20,20 @@
|
||||
const openProfile = () => pushModal(ProfileDetail, {pubkey, url})
|
||||
</script>
|
||||
|
||||
<div class="card2 bg-alt flex flex-col gap-4 shadow-md">
|
||||
<div class="flex justify-between">
|
||||
<Profile {pubkey} {url} />
|
||||
<Button onclick={openProfile} class="btn btn-primary hidden sm:flex">
|
||||
<Card>
|
||||
<Col gap={4}>
|
||||
<div class="flex justify-between">
|
||||
<Profile {pubkey} {url} />
|
||||
<Button onclick={openProfile} variant="primary" class="hidden sm:flex">
|
||||
<Icon icon={UserCircle} />
|
||||
View Profile
|
||||
</Button>
|
||||
</div>
|
||||
<ProfileInfo {pubkey} {url} />
|
||||
<ProfileBadges {pubkey} {url} />
|
||||
<Button onclick={openProfile} variant="primary" class="sm:hidden">
|
||||
<Icon icon={UserCircle} />
|
||||
View Profile
|
||||
</Button>
|
||||
</div>
|
||||
<ProfileInfo {pubkey} {url} />
|
||||
<ProfileBadges {pubkey} {url} />
|
||||
<Button onclick={openProfile} class="btn btn-primary sm:hidden">
|
||||
<Icon icon={UserCircle} />
|
||||
View Profile
|
||||
</Button>
|
||||
</div>
|
||||
</Col>
|
||||
</Card>
|
||||
|
||||
@@ -7,18 +7,22 @@
|
||||
import HamburgerMenu from "@assets/icons/hamburger-menu.svg?dataurl"
|
||||
import PlusCircle from "@assets/icons/add-circle.svg?dataurl"
|
||||
import MinusCircle from "@assets/icons/minus-circle.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Field from "@lib/components/Field.svelte"
|
||||
import FieldInline from "@lib/components/FieldInline.svelte"
|
||||
import DateTimeInput from "@lib/components/DateTimeInput.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Modal from "@lib/components/Modal.svelte"
|
||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import Field from "@lib/components2/Field.svelte"
|
||||
import FieldInline from "@lib/components2/FieldInline.svelte"
|
||||
import Input from "@lib/components2/Input.svelte"
|
||||
import Select from "@lib/components2/Select.svelte"
|
||||
import DateTimeInput from "@lib/components2/DateTimeInput.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Spinner from "@lib/components2/Spinner.svelte"
|
||||
import ModalHeader from "@lib/components2/ModalHeader.svelte"
|
||||
import ModalTitle from "@lib/components2/ModalTitle.svelte"
|
||||
import ModalSubtitle from "@lib/components2/ModalSubtitle.svelte"
|
||||
import ModalFooter from "@lib/components2/ModalFooter.svelte"
|
||||
import Modal from "@lib/components2/Modal.svelte"
|
||||
import ModalBody from "@lib/components2/ModalBody.svelte"
|
||||
import {pushToast} from "@app/toast"
|
||||
import {PROTECTED, publishRoomQuote} from "@app/groups"
|
||||
import {canEnforceNip70} from "@app/relays"
|
||||
@@ -188,21 +192,18 @@
|
||||
<ModalTitle>Create a Poll</ModalTitle>
|
||||
<ModalSubtitle>Ask a question and collect votes right in the feed.</ModalSubtitle>
|
||||
</ModalHeader>
|
||||
<div class="col-8 relative">
|
||||
<Col gap={8} class="relative">
|
||||
<Field>
|
||||
{#snippet label()}
|
||||
<p>Question*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<!-- svelte-ignore a11y_autofocus -->
|
||||
<input
|
||||
autofocus={!isMobile}
|
||||
bind:value={title}
|
||||
class="grow"
|
||||
type="text"
|
||||
placeholder="What would you like to ask?" />
|
||||
</label>
|
||||
<!-- svelte-ignore a11y_autofocus -->
|
||||
<Input
|
||||
autofocus={!isMobile}
|
||||
bind:value={title}
|
||||
type="text"
|
||||
placeholder="What would you like to ask?" />
|
||||
{/snippet}
|
||||
</Field>
|
||||
|
||||
@@ -211,7 +212,7 @@
|
||||
<p>Options*</p>
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<div class="flex flex-col gap-2" role="list">
|
||||
<Col gap={2} role="list">
|
||||
{#each options as option, index (option.id)}
|
||||
<div
|
||||
class="flex items-center gap-2"
|
||||
@@ -224,37 +225,34 @@
|
||||
<div class="cursor-move opacity-70" aria-label="Drag handle">
|
||||
<Icon icon={HamburgerMenu} size={4} />
|
||||
</div>
|
||||
<label class="input input-bordered flex w-full items-center gap-2">
|
||||
<input
|
||||
value={option.value}
|
||||
class="grow"
|
||||
type="text"
|
||||
placeholder={`Option ${index + 1}`}
|
||||
oninput={e => updateOption(option.id, e.currentTarget.value)} />
|
||||
</label>
|
||||
<Button class="btn btn-ghost btn-sm" onclick={() => removeOption(option.id)}>
|
||||
<Input
|
||||
value={option.value}
|
||||
type="text"
|
||||
placeholder={`Option ${index + 1}`}
|
||||
oninput={e => updateOption(option.id, e.currentTarget.value)} />
|
||||
<Button variant="ghost" size="sm" onclick={() => removeOption(option.id)}>
|
||||
<Icon icon={MinusCircle} size={4} />
|
||||
</Button>
|
||||
</div>
|
||||
{/each}
|
||||
<Button class="btn btn-outline btn-sm self-end" onclick={addOption}>
|
||||
<Button variant="secondary" size="sm" class="self-end" onclick={addOption}>
|
||||
<Icon icon={PlusCircle} size={4} />
|
||||
Add option
|
||||
</Button>
|
||||
</div>
|
||||
</Col>
|
||||
{/snippet}
|
||||
</Field>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<Col gap={2}>
|
||||
<FieldInline>
|
||||
{#snippet label()}
|
||||
Poll type
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<select class="select select-bordered w-full max-w-xs" bind:value={pollType}>
|
||||
<Select class="w-full max-w-xs" bind:value={pollType}>
|
||||
<option value="singlechoice">Single choice</option>
|
||||
<option value="multiplechoice">Multiple choice</option>
|
||||
</select>
|
||||
</Select>
|
||||
{/snippet}
|
||||
</FieldInline>
|
||||
<FieldInline>
|
||||
@@ -265,15 +263,15 @@
|
||||
<DateTimeInput bind:value={endsAt} />
|
||||
{/snippet}
|
||||
</FieldInline>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Col>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button class="btn btn-link" onclick={back} disabled={loading}>
|
||||
<Button variant="ghost" onclick={back} disabled={loading}>
|
||||
<Icon icon={AltArrowLeft} />
|
||||
Go back
|
||||
</Button>
|
||||
<Button type="submit" class="btn btn-primary" disabled={loading}>
|
||||
<Button type="submit" variant="primary" disabled={loading}>
|
||||
<Spinner {loading}>Create Poll</Spinner>
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<script lang="ts">
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {getTagValue} from "@welshman/util"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Link from "@lib/components2/Link.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import NoteContent from "@app/components/NoteContent.svelte"
|
||||
import CommentActions from "@app/components/CommentActions.svelte"
|
||||
import RoomLink from "@app/components/RoomLink.svelte"
|
||||
@@ -18,17 +20,17 @@
|
||||
const h = getTagValue("h", event.tags)
|
||||
</script>
|
||||
|
||||
<Link
|
||||
class="cv col-2 card2 bg-alt w-full cursor-pointer shadow-md"
|
||||
href={makePollPath(url, event.id)}>
|
||||
<NoteContent {event} {url} />
|
||||
<div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row">
|
||||
<span class="whitespace-nowrap py-1 text-sm opacity-75">
|
||||
Posted by <ProfileLink pubkey={event.pubkey} {url} />
|
||||
{#if h}
|
||||
in <RoomLink {url} {h} />
|
||||
{/if}
|
||||
</span>
|
||||
<CommentActions segment="polls" showActivity {url} {event} />
|
||||
</div>
|
||||
<Link class="clay-card w-full cursor-pointer p-4 sm:p-6" href={makePollPath(url, event.id)}>
|
||||
<Col>
|
||||
<NoteContent {event} {url} />
|
||||
<div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row">
|
||||
<Text size="sm" muted class="whitespace-nowrap py-1">
|
||||
Posted by <ProfileLink pubkey={event.pubkey} {url} />
|
||||
{#if h}
|
||||
in <RoomLink {url} {h} />
|
||||
{/if}
|
||||
</Text>
|
||||
<CommentActions segment="polls" showActivity {url} {event} />
|
||||
</div>
|
||||
</Col>
|
||||
</Link>
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
import {tweened} from "svelte/motion"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import {noop} from "@welshman/lib"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import {stopPropagation} from "@lib/html"
|
||||
import {getPollType, isPollClosed} from "@app/polls"
|
||||
|
||||
@@ -41,7 +44,7 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-2 card2 card2-sm bg-alt">
|
||||
<Col class="clay-card clay-card-sm cl-surface-alt p-3">
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<label class="flex min-w-0 grow items-center gap-2">
|
||||
{#if !closed}
|
||||
@@ -49,22 +52,28 @@
|
||||
<input
|
||||
name={event.id}
|
||||
type="radio"
|
||||
class="radio radio-primary radio-sm"
|
||||
class="h-4 w-4 shrink-0"
|
||||
style="accent-color: var(--cl-primary)"
|
||||
checked={selected}
|
||||
onclick={stopPropagation(noop)}
|
||||
onchange={onselect} />
|
||||
{:else}
|
||||
<input
|
||||
type="checkbox"
|
||||
class="checkbox checkbox-primary checkbox-sm"
|
||||
class="h-4 w-4 shrink-0"
|
||||
style="accent-color: var(--cl-primary)"
|
||||
checked={selected}
|
||||
onclick={stopPropagation(noop)}
|
||||
onchange={onselect} />
|
||||
{/if}
|
||||
{/if}
|
||||
<span class="truncate">{option.label}</span>
|
||||
<span class="cl-text truncate">{option.label}</span>
|
||||
</label>
|
||||
<span class="whitespace-nowrap text-xs opacity-75">{votes} vote{votes === 1 ? "" : "s"}</span>
|
||||
<Text size="sm" muted class="whitespace-nowrap">{votes} vote{votes === 1 ? "" : "s"}</Text>
|
||||
</div>
|
||||
<progress class="progress progress-primary" value={$tweenedVotes} max={$tweenedMax}></progress>
|
||||
</div>
|
||||
<progress
|
||||
class="h-2 w-full overflow-hidden"
|
||||
style="accent-color: var(--cl-primary); border-radius: var(--cl-r-pill)"
|
||||
value={$tweenedVotes}
|
||||
max={$tweenedMax}></progress>
|
||||
</Col>
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
import {pushToast} from "@app/toast"
|
||||
import {makePollResponse} from "@app/polls"
|
||||
import PollOption from "@app/components/PollOption.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import Text from "@lib/components2/Text.svelte"
|
||||
import {
|
||||
getPollEndsAt,
|
||||
getPollOptions,
|
||||
@@ -107,12 +110,12 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<Col gap={2}>
|
||||
{#each options as option (option.id)}
|
||||
<PollOption {event} {option} {results} {selectedIds} {setSingleChoice} {toggleMultipleChoice} />
|
||||
{/each}
|
||||
<div class="flex flex-wrap items-center justify-between gap-2">
|
||||
<div class="text-sm opacity-75">
|
||||
<Row gap={2} class="flex-wrap justify-between">
|
||||
<Text muted size="sm">
|
||||
{pollType === "multiplechoice" ? "Multiple choice" : "Single choice"}
|
||||
{#if endsAt}
|
||||
{#if closed}
|
||||
@@ -121,7 +124,7 @@
|
||||
• Ends {formatTimestampRelative(endsAt)}
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
<div class="text-sm opacity-75">{results.voters} vote{results.voters === 1 ? "" : "s"}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Text>
|
||||
<Text muted size="sm">{results.voters} vote{results.voters === 1 ? "" : "s"}</Text>
|
||||
</Row>
|
||||
</Col>
|
||||
|
||||
@@ -4,9 +4,12 @@
|
||||
import {session, isPomadeSession} from "@welshman/app"
|
||||
import MenuDots from "@assets/icons/menu-dots.svg?dataurl"
|
||||
import {fly} from "@lib/transition"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Popover from "@lib/components/Popover.svelte"
|
||||
import Icon from "@lib/components2/Icon.svelte"
|
||||
import Button from "@lib/components2/Button.svelte"
|
||||
import Popover from "@lib/components2/Popover.svelte"
|
||||
import Badge from "@lib/components2/Badge.svelte"
|
||||
import Row from "@lib/components2/Row.svelte"
|
||||
import Col from "@lib/components2/Col.svelte"
|
||||
import TrashBin2 from "@assets/icons/trash-bin-2.svg?dataurl"
|
||||
import {pushToast} from "@app/toast"
|
||||
import {loadOtherPomadeSessions} from "@app/pomade"
|
||||
@@ -69,50 +72,46 @@
|
||||
</script>
|
||||
|
||||
{#if sessions.length > 0}
|
||||
<div class="flex flex-col gap-4 border-t border-solid border-base-100 pt-4">
|
||||
<Col gap={4} class="cl-border-t pt-4">
|
||||
<strong>Other Sessions</strong>
|
||||
{#each sessions as sessionItem (sessionItem.client)}
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="flex gap-3 items-center text-sm">
|
||||
<Col gap={2}>
|
||||
<Row class="justify-between">
|
||||
<Row gap={3} class="text-sm">
|
||||
<span>Session {sessionItem.client.slice(0, 8)}</span>
|
||||
<span class="opacity-75">
|
||||
<span class="cl-text-subtle">
|
||||
{#if sessionItem.deactivated_at}
|
||||
Deactivated
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</Row>
|
||||
<div class="relative">
|
||||
<Button
|
||||
class="btn btn-circle btn-ghost btn-sm"
|
||||
onclick={() => toggleMenu(sessionItem.client)}>
|
||||
<Button circle size="sm" onclick={() => toggleMenu(sessionItem.client)}>
|
||||
<Icon icon={MenuDots} />
|
||||
</Button>
|
||||
{#if menuClient === sessionItem.client}
|
||||
<Popover hideOnClick onClose={closeMenu}>
|
||||
<ul
|
||||
<div
|
||||
transition:fly
|
||||
class="menu absolute right-0 z-popover mt-2 w-48 gap-1 rounded-box bg-base-100 p-2 shadow-md">
|
||||
<li>
|
||||
<Button onclick={() => deleteSession(sessionItem)}>
|
||||
<Icon icon={TrashBin2} />
|
||||
Delete Session
|
||||
</Button>
|
||||
</li>
|
||||
</ul>
|
||||
class="clay-card absolute right-0 z-popover mt-2 w-48 p-2">
|
||||
<Button block class="justify-start" onclick={() => deleteSession(sessionItem)}>
|
||||
<Icon icon={TrashBin2} />
|
||||
Delete Session
|
||||
</Button>
|
||||
</div>
|
||||
</Popover>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-1">
|
||||
<div class="badge badge-neutral">
|
||||
</Row>
|
||||
<Row gap={1}>
|
||||
<Badge variant="neutral">
|
||||
Created {formatDate(sessionItem.created_at)}
|
||||
</div>
|
||||
<div class="badge badge-neutral">
|
||||
</Badge>
|
||||
<Badge variant="neutral">
|
||||
Active {formatDate(sessionItem.last_activity)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Badge>
|
||||
</Row>
|
||||
</Col>
|
||||
{/each}
|
||||
</div>
|
||||
</Col>
|
||||
{/if}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user