Refactor css, lib components, add themes

This commit is contained in:
Jon Staab 2026-06-24 20:56:53 +00:00 committed by Jon Staab
parent 90561d46ad
commit 486385cf1f
276 changed files with 2988 additions and 1885 deletions

1
.env
View file

@ -10,6 +10,7 @@ VITE_PLATFORM_LOGO=static/logo.png
VITE_PLATFORM_RELAYS= VITE_PLATFORM_RELAYS=
VITE_PLATFORM_ACCENT="#7161FF" VITE_PLATFORM_ACCENT="#7161FF"
VITE_PLATFORM_SECONDARY="#EB5E28" VITE_PLATFORM_SECONDARY="#EB5E28"
VITE_THEME="clay"
VITE_PLATFORM_DESCRIPTION="Flotilla is nostr — for communities." VITE_PLATFORM_DESCRIPTION="Flotilla is nostr — for communities."
VITE_PUSH_SERVER=https://nps.flotilla.social/ VITE_PUSH_SERVER=https://nps.flotilla.social/
VITE_PUSH_BRIDGE=wss://npb.coracle.social/ VITE_PUSH_BRIDGE=wss://npb.coracle.social/

View file

@ -83,7 +83,6 @@
"@welshman/util": "^0.8.16", "@welshman/util": "^0.8.16",
"cheerio": "^1.2.0", "cheerio": "^1.2.0",
"compressorjs-next": "^1.1.2", "compressorjs-next": "^1.1.2",
"daisyui": "^5.5.19",
"date-picker-svelte": "^2.17.0", "date-picker-svelte": "^2.17.0",
"dotenv": "^16.6.1", "dotenv": "^16.6.1",
"emoji-picker-element": "^1.28.1", "emoji-picker-element": "^1.28.1",

Binary file not shown.

View file

@ -1,459 +0,0 @@
@import "tailwindcss";
@config "../tailwind.config.js";
/* root */
:root {
font-family: Lato;
--sait: var(--safe-area-inset-top, env(safe-area-inset-top));
--saib: var(--safe-area-inset-bottom, env(safe-area-inset-bottom));
--sail: var(--safe-area-inset-left, env(safe-area-inset-left));
--sair: var(--safe-area-inset-right, env(safe-area-inset-right));
}
@utility pt-sai {
padding-top: var(--sait);
}
@utility pr-sai {
padding-right: var(--sair);
}
@utility pb-sai {
padding-bottom: var(--saib);
}
@utility pl-sai {
padding-left: var(--sail);
}
@utility px-sai {
@apply pl-sai pr-sai;
}
@utility py-sai {
@apply pt-sai pb-sai;
}
@utility p-sai {
@apply py-sai px-sai;
}
@utility mt-sai {
margin-top: var(--sait);
}
@utility mr-sai {
margin-right: var(--sair);
}
@utility mb-sai {
margin-bottom: var(--saib);
}
@utility ml-sai {
margin-left: var(--sail);
}
@utility mx-sai {
@apply ml-sai mr-sai;
}
@utility my-sai {
@apply mt-sai mb-sai;
}
@utility m-sai {
@apply my-sai mx-sai;
}
@utility top-sai {
top: var(--sait);
}
@utility right-sai {
right: var(--sair);
}
@utility bottom-sai {
bottom: var(--saib);
}
@utility left-sai {
left: var(--sail);
}
@utility card2 {
@apply rounded-box text-base-content border-base-content/20 bg-base-100 border border-solid p-4 shadow-xl/5 sm:p-6;
}
@utility card2-interactive {
@apply cursor-pointer hover:scale-101 transition-all;
}
@utility column {
@apply flex flex-col;
}
@utility center {
@apply flex items-center justify-center;
}
@utility row-2 {
@apply flex items-center gap-2;
}
@utility row-3 {
@apply flex items-center gap-3;
}
@utility row-4 {
@apply flex items-center gap-4;
}
@utility col-2 {
@apply flex flex-col gap-2;
}
@utility col-3 {
@apply flex flex-col gap-3;
}
@utility col-4 {
@apply flex flex-col gap-4;
}
@utility col-8 {
@apply flex flex-col gap-8;
}
@utility ellipsize {
@apply overflow-hidden text-ellipsis;
}
@utility content-padding-x {
@apply px-4 sm:px-8 md:px-12;
}
@utility content-padding-t {
@apply pt-4 sm:pt-8 md:pt-12;
}
@utility content-padding-b {
@apply pb-4 sm:pb-8 md:pb-12;
}
@utility content-padding-y {
@apply pt-4 pb-4 sm:pt-8 sm:pb-8 md:pt-12 md:pb-12;
}
@utility content-sizing {
@apply m-auto w-full max-w-3xl;
}
@utility content {
@apply m-auto w-full max-w-3xl px-4 pt-4 pb-4 sm:px-8 sm:pt-8 sm:pb-8 md:px-12 md:pt-12 md:pb-12;
}
@utility heading {
@apply text-center text-2xl;
}
@utility subheading {
@apply text-center text-xl;
}
@utility superheading {
@apply text-center text-4xl;
}
@utility link {
@apply text-primary cursor-pointer underline;
}
/* content visibility */
@utility cv {
content-visibility: auto;
}
/*
The default border color has changed to `currentcolor` in Tailwind CSS v4,
so we've added these compatibility styles to make sure everything still
looks the same as it did with Tailwind CSS v3.
If we ever want to remove these styles, we need to add an explicit border
color utility to any element that depends on these defaults.
*/
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentcolor);
}
}
@layer utilities {
/* Fonts */
@font-face {
font-family: "Satoshis";
font-style: normal;
font-weight: 400;
src:
local(""),
url("/fonts/Satoshi Symbol.ttf") format("truetype");
}
@font-face {
font-family: "Lato";
font-style: normal;
font-weight: 400;
src:
local(""),
url("/fonts/Lato-Regular.ttf") format("truetype");
}
@font-face {
font-family: "Lato";
font-style: bold;
font-weight: 600;
src:
local(""),
url("/fonts/Lato-Bold.ttf") format("truetype");
}
@font-face {
font-family: "Lato";
font-style: italic;
font-weight: 400;
src:
local(""),
url("/fonts/Italic.ttf") format("truetype");
}
/* root */
:root {
font-family: Lato;
text-size-adjust: 100%;
--sait: var(--safe-area-inset-top, env(safe-area-inset-top));
--saib: var(--safe-area-inset-bottom, env(safe-area-inset-bottom));
--sail: var(--safe-area-inset-left, env(safe-area-inset-left));
--sair: var(--safe-area-inset-right, env(safe-area-inset-right));
}
[data-theme] {
@apply bg-base-300;
}
.mobile [data-tip]::before {
display: none !important;
}
/* safe area insets */
}
/* utilities */
.bg-alt,
.bg-alt .bg-alt .bg-alt,
.hover\:bg-alt:hover,
.bg-alt .bg-alt .hover\:bg-alt:hover,
.bg-alt .bg-alt.hover\:bg-alt:hover {
@apply bg-base-100 text-base-content transition-colors;
}
.bg-alt .bg-alt,
.bg-alt .bg-alt .bg-alt .bg-alt,
.bg-alt .hover\:bg-alt:hover,
.bg-alt .bg-alt .bg-alt .hover\:bg-alt:hover,
.bg-alt.hover\:bg-alt:hover,
.bg-alt .bg-alt .bg-alt.hover\:bg-alt:hover {
@apply bg-base-300 text-base-content transition-colors;
}
.card2.card2-sm {
@apply text-base-content p-2 sm:p-4;
}
.card2 .card2,
.dialog .card2 {
@apply shadow-none;
}
[data-tip]::before {
@apply overflow-hidden text-ellipsis;
}
.input input::placeholder {
opacity: 0.5;
}
/* tiptap */
.input-editor,
.chat-editor,
.note-editor {
@apply -m-1 p-1;
}
.tiptap {
--tiptap-object-bg: var(--color-neutral);
--tiptap-object-fg: var(--color-neutral-content);
--tiptap-active-bg: var(--color-primary);
--tiptap-active-fg: var(--color-primary-content);
}
.tiptap-suggestions {
--tiptap-object-bg: var(--color-base-100);
--tiptap-object-fg: var(--color-base-content);
--tiptap-active-bg: var(--color-base-300);
--tiptap-active-fg: var(--color-base-content);
}
.tiptap-suggestions__item {
@apply border-base-100 border-l-2 border-solid;
}
.tiptap-suggestions__selected {
@apply border-primary;
}
.tiptap {
@apply max-h-[350px] min-h-10 overflow-y-auto p-2 px-4;
}
.tiptap p.is-editor-empty:first-child::before {
opacity: 40%;
}
.chat-editor .tiptap {
@apply rounded-box bg-base-300 pr-12;
}
.note-editor .tiptap {
--tiptap-object-bg: var(--color-base-200);
@apply input rounded-box block h-auto min-h-32 w-full p-[.65rem] pb-6;
}
.input-editor .tiptap {
--tiptap-object-bg: var(--color-base-200);
@apply input block h-auto p-[.65rem];
}
/* link-content, based on tiptap */
.link-content {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
border-radius: 3px;
padding: 0 0.25rem;
background-color: var(--color-base-100);
color: var(--color-base-content);
}
/* content rendered by welshman/content */
.welshman-content a {
@apply link;
}
.welshman-content-error a {
@apply underline;
}
/* date input */
.picker {
--date-picker-foreground: var(--color-base-content);
--date-picker-background: var(--color-base-300);
--date-picker-highlight-border: var(--color-primary);
--date-picker-selected-color: var(--color-primary-content);
--date-picker-selected-background: var(--color-primary);
}
.date-time-field {
@apply input rounded-lg px-0;
}
.date-time-field input {
@apply h-full! w-full! rounded-lg! border-none! bg-inherit! px-4! text-inherit!;
}
/* tippy popover */
.tippy-target {
@apply z-tooltip pointer-events-none fixed inset-0;
}
.tippy-target > * {
pointer-events: auto;
}
.tippy-box {
@apply rounded-box shadow-xl;
}
/* emoji picker */
emoji-picker {
--background: var(--color-base-100);
--border-color: var(--color-base-100);
--border-radius: var(--rounded-box);
--button-active-background: var(--color-base-content);
--button-hover-background: var(--color-base-content);
--indicator-color: var(--color-base-content);
--input-border-color: var(--color-base-100);
--input-font-color: var(--color-base-content);
--outline-color: var(--color-base-100);
}
/* progress */
progress[value]::-webkit-progress-value {
transition: width 0.5s;
}
/* content width for fixed elements */
.left-content {
@apply left-sai md:left-[calc(18.5rem+var(--sail))];
}
.left-content-full {
@apply left-sai md:left-[calc(3.5rem+var(--sail))];
}
/* Keyboard open state adjustments */
body.keyboard-open {
--saib: 0px;
}
body.keyboard-open .hide-on-keyboard {
display: none;
}
body.keyboard-open .chat__compose {
margin-bottom: 0;
}
/* chat view */
.chat__compose {
@apply z-compose relative mb-14 shrink-0 md:mb-0;
}
.chat__compose .chat__compose-inner {
@apply min-w-0;
}
.chat__scroll-down {
@apply pb-sai z-feature fixed right-4 bottom-28 md:bottom-16;
}

View file

@ -34,7 +34,7 @@
<p>Bunker Link*</p> <p>Bunker Link*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input input-group flex w-full items-center gap-2">
<Icon icon={CpuBolt} /> <Icon icon={CpuBolt} />
<input disabled={$loading} bind:value={$bunker} class="grow" placeholder="bunker://" /> <input disabled={$loading} bind:value={$bunker} class="grow" placeholder="bunker://" />
<Button onclick={toggleScanner}> <Button onclick={toggleScanner}>
@ -45,7 +45,8 @@
{#snippet info()} {#snippet info()}
<p> <p>
A login link provided by a nostr signing app. A login link provided by a nostr signing app.
<Button class="link" onclick={() => pushModal(InfoBunker)}>What is a bunker link?</Button> <Button class="button button-link" onclick={() => pushModal(InfoBunker)}
>What is a bunker link?</Button>
</p> </p>
{/snippet} {/snippet}
</Field> </Field>

View file

@ -42,11 +42,11 @@
<div class="flex grow flex-wrap justify-end gap-2"> <div class="flex grow flex-wrap justify-end gap-2">
{#if h && showRoom} {#if h && showRoom}
<Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full"> <Link href={makeSpacePath(url, h)} class="button button-neutral button-xs rounded-full">
Posted in #<RoomName {h} {url} /> Posted in #<RoomName {h} {url} />
</Link> </Link>
{/if} {/if}
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" /> <ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tip tip-left" />
<ThunkStatusOrDeleted {event} /> <ThunkStatusOrDeleted {event} />
{#if showActivity} {#if showActivity}
<EventActivity {url} {path} {event} /> <EventActivity {url} {path} {event} />

View file

@ -14,7 +14,7 @@
{#if !isNaN(start)} {#if !isNaN(start)}
{@const startDate = secondsToDate(start)} {@const startDate = secondsToDate(start)}
<div <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="hidden h-32 w-32 min-w-32 flex-col items-center justify-center gap-1 rounded-2xl bg-surface-more p-2 sm:flex">
<strong>{Intl.DateTimeFormat(LOCALE, {month: "short"}).format(startDate)}</strong> <strong>{Intl.DateTimeFormat(LOCALE, {month: "short"}).format(startDate)}</strong>
<span class="text-4xl">{Intl.DateTimeFormat(LOCALE, {day: "numeric"}).format(startDate)}</span> <span class="text-4xl">{Intl.DateTimeFormat(LOCALE, {day: "numeric"}).format(startDate)}</span>
<span class="text-xs opacity-75" <span class="text-xs opacity-75"

View file

@ -164,7 +164,7 @@
<p>Title*</p> <p>Title*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<input bind:value={title} class="grow" type="text" /> <input bind:value={title} class="grow" type="text" />
</label> </label>
{/snippet} {/snippet}
@ -174,18 +174,17 @@
<p>Summary</p> <p>Summary</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<div <div class="relative z-feature flex gap-2">
class="relative z-feature flex gap-2 border-t border-solid border-base-100 bg-base-100">
<div class="input-editor grow overflow-hidden"> <div class="input-editor grow overflow-hidden">
<EditorContent {editor} /> <EditorContent {editor} />
</div> </div>
<Button <Button
data-tip="Add an image" data-tip="Add an image"
class="center btn tooltip" class="button button-neutral tip"
onclick={selectFiles} onclick={selectFiles}
disabled={loading}> disabled={loading}>
{#if $uploading} {#if $uploading}
<span class="loading loading-spinner loading-xs"></span> <Spinner size="xs" />
{:else} {:else}
<Icon icon={GallerySend} /> <Icon icon={GallerySend} />
{/if} {/if}
@ -214,7 +213,7 @@
<p>Location (optional)</p> <p>Location (optional)</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<Icon icon={MapPoint} /> <Icon icon={MapPoint} />
<input bind:value={location} class="grow" type="text" /> <input bind:value={location} class="grow" type="text" />
</label> </label>
@ -222,11 +221,11 @@
</Field> </Field>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}> <Button class="button button-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={$uploading || loading}> <Button class="button button-primary" type="submit" disabled={$uploading || loading}>
<Spinner loading={$uploading || loading}>Save Event</Spinner> <Spinner loading={$uploading || loading}>Save Event</Spinner>
</Button> </Button>
</ModalFooter> </ModalFooter>

View file

@ -18,7 +18,9 @@
const h = getTagValue("h", event.tags) const h = getTagValue("h", event.tags)
</script> </script>
<Link class="cv col-3 card2 w-full cursor-pointer" href={makeCalendarPath(url, getAddress(event))}> <Link
class="cv flex flex-col gap-3 card card-interactive w-full"
href={makeCalendarPath(url, getAddress(event))}>
<CalendarEventHeader {event} /> <CalendarEventHeader {event} />
<div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row"> <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="whitespace-nowrap py-1 text-sm opacity-75">

View file

@ -39,7 +39,6 @@
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Spinner from "@lib/components/Spinner.svelte" import Spinner from "@lib/components/Spinner.svelte"
import PageBar from "@lib/components/PageBar.svelte" import PageBar from "@lib/components/PageBar.svelte"
import PageContent from "@lib/components/PageContent.svelte"
import Divider from "@lib/components/Divider.svelte" import Divider from "@lib/components/Divider.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import ProfileName from "@app/components/ProfileName.svelte" import ProfileName from "@app/components/ProfileName.svelte"
@ -252,12 +251,12 @@
<div class="ellipsize flex items-center gap-4 whitespace-nowrap"> <div class="ellipsize flex items-center gap-4 whitespace-nowrap">
<Button class="flex flex-col gap-1 sm:flex-row sm:gap-2" onclick={showMembers}> <Button class="flex flex-col gap-1 sm:flex-row sm:gap-2" onclick={showMembers}>
{#if others.length === 0} {#if others.length === 0}
<div class="row-2"> <div class="flex gap-2">
<ProfileCircle pubkey={$pubkey!} size={5} /> <ProfileCircle pubkey={$pubkey!} size={5} />
<ProfileName pubkey={$pubkey!} /> <ProfileName pubkey={$pubkey!} />
</div> </div>
{:else if others.length === 1} {:else if others.length === 1}
<div class="row-2"> <div class="flex gap-2">
<ProfileCircle pubkey={others[0]} size={5} /> <ProfileCircle pubkey={others[0]} size={5} />
<ProfileName pubkey={others[0]} /> <ProfileName pubkey={others[0]} />
</div> </div>
@ -282,11 +281,11 @@
</div> </div>
</PageBar> </PageBar>
<PageContent class="flex flex-col-reverse gap-2 py-2 !mb-0"> <div class="flex flex-col-reverse gap-4 py-2 bg-surface scroll-container h-screen overflow-y-auto">
{#if missingRelayLists.length > 0} {#if missingRelayLists.length > 0}
<div class="py-12"> <div class="py-12">
<div class="card2 col-2 m-auto max-w-md items-center text-center"> <div class="card flex flex-col gap-2 m-auto max-w-md items-center text-center">
<p class="row-2 text-lg text-error"> <p class="flex gap-2 text-lg text-error">
<Icon icon={Danger} /> <Icon icon={Danger} />
Direct messages are not enabled Direct messages are not enabled
</p> </p>
@ -324,9 +323,9 @@
{@render info?.()} {@render info?.()}
</p> </p>
<div class="h-screen"></div> <div class="h-screen"></div>
</PageContent> </div>
<div class="chat__compose bg-base-200"> <div class="room__compose bg-surface">
<div> <div>
{#if parent} {#if parent}
<ChatComposeParent event={parent} clear={clearParent} verb="Replying to" /> <ChatComposeParent event={parent} clear={clearParent} verb="Replying to" />

View file

@ -8,6 +8,7 @@
import Plane from "@assets/icons/plane-2.svg?dataurl" import Plane from "@assets/icons/plane-2.svg?dataurl"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import EditorContent from "@app/editor/EditorContent.svelte" import EditorContent from "@app/editor/EditorContent.svelte"
import {makeEditor} from "@app/editor" import {makeEditor} from "@app/editor"
import {type DraftKey} from "@app/drafts" import {type DraftKey} from "@app/drafts"
@ -113,11 +114,11 @@
<form class="relative z-feature flex gap-2 p-2" onsubmit={preventDefault(submit)}> <form class="relative z-feature flex gap-2 p-2" onsubmit={preventDefault(submit)}>
<Button <Button
data-tip="Add an image" 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="button button-neutral button-square tip tip-right h-10 w-10 min-w-10 rounded-2xl transition-colors"
disabled={$uploading || disabled} disabled={$uploading || disabled}
onclick={uploadFiles}> onclick={uploadFiles}>
{#if $uploading} {#if $uploading}
<span class="loading loading-spinner loading-xs"></span> <Spinner size="xs" />
{:else} {:else}
<Icon icon={GallerySend} /> <Icon icon={GallerySend} />
{/if} {/if}
@ -127,7 +128,7 @@
</div> </div>
<Button <Button
data-tip="{window.navigator.platform.includes('Mac') ? 'cmd' : 'ctrl'}+enter to send" 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="button button-primary button-circle tip tip-left h-10 w-10 min-w-10"
disabled={$uploading || disabled} disabled={$uploading || disabled}
onclick={submit}> onclick={submit}>
<Icon icon={Plane} /> <Icon icon={Plane} />

View file

@ -12,7 +12,8 @@
</script> </script>
<div <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="bg-surface-more relative flex h-8 items-center justify-between border-l-2 border-solid px-2 pr-7 text-xs"
style="border-color: var(--primary)"
transition:slide> transition:slide>
<p class="text-primary">Editing message</p> <p class="text-primary">Editing message</p>
<Button onclick={clear} class="flex items-center"> <Button onclick={clear} class="flex items-center">

View file

@ -19,9 +19,10 @@
</script> </script>
<div <div
class="relative border-l-2 border-solid border-primary bg-base-300 px-2 py-1 pr-8" class="bg-surface-more relative border-l-2 border-solid px-2 py-1 pr-8"
style="border-color: var(--primary)"
transition:slide> transition:slide>
<p class="text-xs text-primary">{verb} @{displayProfileByPubkey(event.pubkey)}</p> <p class="text-primary text-xs">{verb} @{displayProfileByPubkey(event.pubkey)}</p>
{#key event.id} {#key event.id}
<NoteContentMinimal trimParent {event} /> <NoteContentMinimal trimParent {event} />
{/key} {/key}

View file

@ -60,11 +60,11 @@
<p>Direct messaging isn't currently enabled. Would you like to turn it on?</p> <p>Direct messaging isn't currently enabled. Would you like to turn it on?</p>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={loading}> <Button type="submit" class="button button-primary" disabled={loading}>
<Spinner {loading}>Enable direct messaging</Spinner> <Spinner {loading}>Enable direct messaging</Spinner>
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -35,8 +35,9 @@
<Button class="flex flex-col justify-start gap-1 w-full" onclick={openChat}> <Button class="flex flex-col justify-start gap-1 w-full" onclick={openChat}>
<div <div
class="cursor-pointer border-t border-solid border-base-100 px-3 py-2 transition-colors hover:bg-base-100 {props.class}" class="cursor-pointer border-t border-solid px-3 py-2 transition-colors hover:bg-surface {props.class}"
class:bg-base-100={active}> class:bg-surface={active}
style="border-color: var(--line)">
<div class="flex flex-col justify-start gap-1"> <div class="flex flex-col justify-start gap-1">
<div class="flex items-center justify-between gap-2"> <div class="flex items-center justify-between gap-2">
<div class="flex min-w-0 items-center gap-2"> <div class="flex min-w-0 items-center gap-2">
@ -56,7 +57,7 @@
{/if} {/if}
</div> </div>
{#if !active && $notifications.has(path)} {#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 bg-primary text-primary-content" transition:fade></div>
{/if} {/if}
</div> </div>
<p class="overflow-hidden text-ellipsis whitespace-nowrap text-sm"> <p class="overflow-hidden text-ellipsis whitespace-nowrap text-sm">

View file

@ -21,13 +21,13 @@
</ModalHeader> </ModalHeader>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
{#each pubkeys as pubkey (pubkey)} {#each pubkeys as pubkey (pubkey)}
<div class="card2 bg-alt"> <div class="card">
<Profile {pubkey} /> <Profile {pubkey} />
</div> </div>
{/each} {/each}
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button> <Button class="button button-primary" onclick={() => history.back()}>Got it</Button>
</ModalFooter> </ModalFooter>
</Modal> </Modal>

View file

@ -23,17 +23,17 @@
<Modal> <Modal>
<ModalBody> <ModalBody>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<Button class="btn btn-neutral" onclick={markAsRead}> <Button class="button button-neutral" onclick={markAsRead}>
<Icon size={5} icon={Check} /> <Icon size={5} icon={Check} />
Mark all read Mark all read
</Button> </Button>
{#if $notificationSettings.messages} {#if $notificationSettings.messages}
<Button class="btn btn-neutral" onclick={disableAlerts}> <Button class="button button-neutral" onclick={disableAlerts}>
<Icon size={4} icon={BellOff} /> <Icon size={4} icon={BellOff} />
Disable alerts Disable alerts
</Button> </Button>
{:else} {:else}
<Button class="btn btn-neutral" onclick={enableAlerts}> <Button class="button button-neutral" onclick={enableAlerts}>
<Icon size={4} icon={Bell} /> <Icon size={4} icon={Bell} />
Enable alerts Enable alerts
</Button> </Button>

View file

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import cx from "classnames"
import {type Instance} from "tippy.js" import {type Instance} from "tippy.js"
import {hash, formatTimestampAsTime} from "@welshman/lib" import {hash, formatTimestampAsTime} from "@welshman/lib"
import type {TrustedEvent, EventContent} from "@welshman/util" import type {TrustedEvent, EventContent} from "@welshman/util"
@ -71,10 +72,8 @@
{/if} {/if}
<div <div
data-event={event.id} data-event={event.id}
class="group chat flex items-center justify-end gap-1 px-2" class="group flex items-center justify-end gap-1 px-2"
class:chat-start={!isOwn} class:flex-row-reverse={!isOwn}>
class:flex-row-reverse={!isOwn}
class:chat-end={isOwn}>
{#if !isMobile} {#if !isMobile}
<Tippy <Tippy
bind:popover bind:popover
@ -100,16 +99,15 @@
</Tippy> </Tippy>
{/if} {/if}
<div class="flex min-w-0 flex-col" class:items-end={isOwn}> <div class="flex min-w-0 flex-col" class:items-end={isOwn}>
<TapTarget <TapTarget class={cx("chat-bubble", {"chat-bubble--user": isOwn})} onTap={showMobileMenu}>
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]"
onTap={showMobileMenu}>
{#if showPubkey} {#if showPubkey}
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
{#if !isOwn} {#if !isOwn}
<Button onclick={openProfile} class="flex items-center gap-1"> <Button onclick={openProfile} class="flex items-center gap-1">
<ProfileCircle <ProfileCircle
pubkey={event.pubkey} pubkey={event.pubkey}
class="border border-solid border-base-content" class="border border-solid"
style="border-color: var(--line)"
size={4} /> size={4} />
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<Button onclick={openProfile} class="text-sm font-bold" style="color: {colorValue}"> <Button onclick={openProfile} class="text-sm font-bold" style="color: {colorValue}">
@ -126,7 +124,7 @@
<Content showEntire {event} /> <Content showEntire {event} />
</div> </div>
</TapTarget> </TapTarget>
<div class="row-2 z-feature -mt-4 ml-4"> <div class="flex gap-2 z-feature -mt-4 ml-4">
<ReactionSummary {event} {deleteReaction} {createReaction} noTooltip /> <ReactionSummary {event} {deleteReaction} {createReaction} noTooltip />
</div> </div>
</div> </div>

View file

@ -22,6 +22,6 @@
}) })
</script> </script>
<EmojiButton {onEmoji} class="btn join-item btn-xs"> <EmojiButton {onEmoji} class="button button-neutral button-xs join-item">
<Icon icon={SmileCircle} size={4} /> <Icon icon={SmileCircle} size={4} />
</EmojiButton> </EmojiButton>

View file

@ -19,19 +19,19 @@
} }
</script> </script>
<div class="join border border-solid border-neutral text-xs"> <div class="join text-xs">
<ChatMessageEmojiButton {event} {pubkeys} /> <ChatMessageEmojiButton {event} {pubkeys} />
{#if replyTo} {#if replyTo}
<Button class="btn join-item btn-xs" onclick={reply}> <Button class="button button-neutral button-xs join-item" onclick={reply}>
<Icon size={4} icon={Reply} /> <Icon size={4} icon={Reply} />
</Button> </Button>
{/if} {/if}
{#if edit} {#if edit}
<Button class="btn join-item btn-xs" onclick={onEdit}> <Button class="button button-neutral button-xs join-item" onclick={onEdit}>
<Icon size={4} icon={Pen} /> <Icon size={4} icon={Pen} />
</Button> </Button>
{/if} {/if}
<Button class="btn join-item btn-xs" onclick={showInfo}> <Button class="button button-neutral button-xs join-item" onclick={showInfo}>
<Icon size={4} icon={Code2} /> <Icon size={4} icon={Code2} />
</Button> </Button>
</div> </div>

View file

@ -58,25 +58,25 @@
<Modal> <Modal>
<ModalBody> <ModalBody>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<Button class="btn btn-neutral" onclick={showInfo}> <Button class="button button-neutral" onclick={showInfo}>
<Icon size={4} icon={Code2} /> <Icon size={4} icon={Code2} />
Message Info Message Info
</Button> </Button>
<Button class="btn btn-neutral w-full" onclick={copyText}> <Button class="button button-neutral w-full" onclick={copyText}>
<Icon size={4} icon={Copy} /> <Icon size={4} icon={Copy} />
Copy Text Copy Text
</Button> </Button>
<Button class="btn btn-neutral w-full" onclick={sendReply}> <Button class="button button-neutral w-full" onclick={sendReply}>
<Icon size={4} icon={Reply} /> <Icon size={4} icon={Reply} />
Send Reply Send Reply
</Button> </Button>
{#if edit} {#if edit}
<Button class="btn btn-neutral w-full" onclick={sendEdit}> <Button class="button button-neutral w-full" onclick={sendEdit}>
<Icon size={4} icon={Pen} /> <Icon size={4} icon={Pen} />
Edit Message Edit Message
</Button> </Button>
{/if} {/if}
<Button class="btn btn-primary w-full" onclick={showEmojiPicker}> <Button class="button button-primary w-full" onclick={showEmojiPicker}>
<Icon size={4} icon={SmileCircle} /> <Icon size={4} icon={SmileCircle} />
Send Reaction Send Reaction
</Button> </Button>

View file

@ -73,11 +73,11 @@
</Field> </Field>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={pubkeys.length === 0}> <Button type="submit" class="button button-primary" disabled={pubkeys.length === 0}>
Create Chat Create Chat
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -46,18 +46,18 @@
<div class="flex grow flex-wrap justify-end gap-2"> <div class="flex grow flex-wrap justify-end gap-2">
{#if h && showRoom} {#if h && showRoom}
<Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full"> <Link href={makeSpacePath(url, h)} class="button button-neutral button-xs rounded-full">
Posted in #<RoomName {h} {url} /> Posted in #<RoomName {h} {url} />
</Link> </Link>
{/if} {/if}
<div class="flex min-w-0 flex-wrap gap-2"> <div class="flex min-w-0 flex-wrap gap-2">
{#each uniq(topics) as topic (topic)} {#each uniq(topics) as topic (topic)}
<button type="button" class="btn btn-xs rounded-full font-normal"> <button type="button" class="button button-xs rounded-full font-normal">
#{normalizeTopic(topic)} #{normalizeTopic(topic)}
</button> </button>
{/each} {/each}
</div> </div>
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" /> <ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tip-left" />
<ThunkStatusOrDeleted {event}> <ThunkStatusOrDeleted {event}>
<ClassifiedStatus {event} /> <ClassifiedStatus {event} />
</ThunkStatusOrDeleted> </ThunkStatusOrDeleted>

View file

@ -164,13 +164,13 @@
<Modal tag="form" onsubmit={preventDefault(submit)}> <Modal tag="form" onsubmit={preventDefault(submit)}>
<ModalBody> <ModalBody>
{@render header?.()} {@render header?.()}
<div class="col-8 relative"> <div class="flex flex-col gap-8 relative">
<Field> <Field>
{#snippet label()} {#snippet label()}
<p>Title*</p> <p>Title*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<!-- svelte-ignore a11y_autofocus --> <!-- svelte-ignore a11y_autofocus -->
<input <input
autofocus={!isMobile} autofocus={!isMobile}
@ -205,10 +205,10 @@
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<div class="join grid grid-cols-2"> <div class="join grid grid-cols-2">
<label class="join-item input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<input bind:value={price} class="grow w-32" type="number" /> <input bind:value={price} class="grow w-32" type="number" />
</label> </label>
<CurrencyInput class="join-item" bind:value={currency} /> <CurrencyInput bind:value={currency} />
</div> </div>
{/snippet} {/snippet}
</Field> </Field>
@ -218,7 +218,7 @@
<p>Status*</p> <p>Status*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<select class="select select-bordered w-full" bind:value={status}> <select class="select input w-full" bind:value={status}>
<option value="active">Active</option> <option value="active">Active</option>
<option value="sold">Sold</option> <option value="sold">Sold</option>
</select> </select>
@ -236,11 +236,11 @@
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}> <Button onclick={back} disabled={loading} class="button button-link">
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={loading}> <Button type="submit" disabled={loading} class="button button-primary">
<Spinner {loading}>Save Listing</Spinner> <Spinner {loading}>Save Listing</Spinner>
</Button> </Button>
</ModalFooter> </ModalFooter>

View file

@ -25,7 +25,7 @@
</script> </script>
<Link <Link
class="cv col-2 card2 w-full cursor-pointer" class="cv flex flex-col gap-2 card card-interactive w-full"
href={makeClassifiedPath(url, getAddress(event))}> href={makeClassifiedPath(url, getAddress(event))}>
{#if title} {#if title}
<div class="flex w-full items-center justify-between gap-2"> <div class="flex w-full items-center justify-between gap-2">

View file

@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import cx from "classnames"
import type {TrustedEvent} from "@welshman/util" import type {TrustedEvent} from "@welshman/util"
import {getTagValue} from "@welshman/util" import {getTagValue} from "@welshman/util"
import {ucFirst} from "@lib/util" import {ucFirst} from "@lib/util"
import Badge from "@lib/components/Badge.svelte"
type Props = { type Props = {
event: TrustedEvent event: TrustedEvent
@ -14,7 +14,7 @@
</script> </script>
{#if status} {#if status}
<div class={cx("btn btn-xs rounded-full", {"btn-primary": status !== "active"})}> <Badge variant={status !== "active" ? "primary" : "neutral"} class="rounded-full">
{ucFirst(status)} {ucFirst(status)}
</div> </Badge>
{/if} {/if}

View file

@ -31,7 +31,7 @@
<div class="flex flex-wrap items-center justify-between gap-2"> <div class="flex flex-wrap items-center justify-between gap-2">
<div class="flex grow flex-wrap justify-end 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="tip-left" />
<ThunkStatusOrDeleted {event} /> <ThunkStatusOrDeleted {event} />
{#if showActivity} {#if showActivity}
<EventActivity {url} {path} {event} /> <EventActivity {url} {path} {event} />

View file

@ -39,7 +39,7 @@
}) })
</script> </script>
<ul class="menu whitespace-nowrap rounded-box bg-base-100 p-2 shadow-md" bind:this={ul}> <ul class="menu whitespace-nowrap rounded-2xl bg-surface p-2" bind:this={ul}>
<li> <li>
<Button onclick={createGoal}> <Button onclick={createGoal}>
<Icon size={4} icon={StarFallMinimalistic} /> <Icon size={4} icon={StarFallMinimalistic} />

View file

@ -25,6 +25,7 @@
import Danger from "@assets/icons/danger-triangle.svg?dataurl" import Danger from "@assets/icons/danger-triangle.svg?dataurl"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import Card from "@lib/components/Card.svelte"
import ContentToken from "@app/components/ContentToken.svelte" import ContentToken from "@app/components/ContentToken.svelte"
import ContentEmoji from "@app/components/ContentEmoji.svelte" import ContentEmoji from "@app/components/ContentEmoji.svelte"
import ContentEmail from "@app/components/ContentEmail.svelte" import ContentEmail from "@app/components/ContentEmail.svelte"
@ -144,13 +145,13 @@
<div class="relative"> <div class="relative">
{#if warning} {#if warning}
<div class="card2 card2-sm shadow-none row-2"> <Card sm class="shadow-none flex gap-2">
<Icon icon={Danger} /> <Icon icon={Danger} />
<p> <p>
This note has been flagged by the author as "{warning}".<br /> This note has been flagged by the author as "{warning}".<br />
<Button class="link" onclick={ignoreWarning}>Show anyway</Button> <Button onclick={ignoreWarning} class="button button-link">Show anyway</Button>
</p> </p>
</div> </Card>
{:else} {:else}
<div <div
class="overflow-hidden text-ellipsis wrap-break-word" class="overflow-hidden text-ellipsis wrap-break-word"
@ -204,12 +205,9 @@
</div> </div>
{#if expandBlock} {#if expandBlock}
<div class="relative z-feature -mt-6 flex justify-center py-2"> <div class="relative z-feature -mt-6 flex justify-center py-2">
<button <Button onclick={stopPropagation(preventDefault(expand))} class="button button-neutral">
type="button"
class="btn btn-neutral"
onclick={stopPropagation(preventDefault(expand))}>
See more See more
</button> </Button>
</div> </div>
{/if} {/if}
{/if} {/if}

View file

@ -3,7 +3,7 @@
</script> </script>
<code <code
class="w-full overflow-auto whitespace-pre rounded bg-neutral px-1 text-neutral-content text-sm" class="bg-surface-more text-content w-full overflow-auto whitespace-pre rounded px-1 text-sm"
class:block={isBlock}> class:block={isBlock}>
{value.trim()} {value.trim()}
</code> </code>

View file

@ -4,6 +4,7 @@
import {Capacitor} from "@capacitor/core" import {Capacitor} from "@capacitor/core"
import {preventDefault, stopPropagation} from "@lib/html" import {preventDefault, stopPropagation} from "@lib/html"
import Link from "@lib/components/Link.svelte" import Link from "@lib/components/Link.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import ContentLinkDetail from "@app/components/ContentLinkDetail.svelte" import ContentLinkDetail from "@app/components/ContentLinkDetail.svelte"
import ContentLinkUrl from "@app/components/ContentLinkUrl.svelte" import ContentLinkUrl from "@app/components/ContentLinkUrl.svelte"
import ContentLinkBlockImage from "@app/components/ContentLinkBlockImage.svelte" import ContentLinkBlockImage from "@app/components/ContentLinkBlockImage.svelte"
@ -57,34 +58,35 @@
</div> </div>
{:else} {:else}
<Link {external} {href} class="my-2 block"> <Link {external} {href} class="my-2 block">
<div class="overflow-hidden rounded-box"> <div class="overflow-hidden rounded-2xl">
{#if url.match(/\.(mov|webm|mp4)$/) || VIDEO_CONTENT_TYPES.includes(fileType)} {#if url.match(/\.(mov|webm|mp4)$/) || VIDEO_CONTENT_TYPES.includes(fileType)}
<video <video
controls controls
src={url} src={url}
poster={getVideoPoster(url)} poster={getVideoPoster(url)}
preload="metadata" preload="metadata"
class="max-h-96 rounded-box object-contain object-center"> class="max-h-96 rounded-2xl object-contain object-center">
<track kind="captions" /> <track kind="captions" />
</video> </video>
{:else if url.match(/\.(jpe?g|png|gif|webp)$/) || IMAGE_CONTENT_TYPES.includes(fileType)} {:else if url.match(/\.(jpe?g|png|gif|webp)$/) || IMAGE_CONTENT_TYPES.includes(fileType)}
<button type="button" onclick={stopPropagation(preventDefault(expand))}> <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 rounded-2xl" />
</button> </button>
{:else} {:else}
{#await loadPreview()} {#await loadPreview()}
<div class="center my-12 w-full"> <div class="flex justify-center items-center my-12 w-full">
<span class="loading loading-spinner"></span> <Spinner />
</div> </div>
{:then preview} {:then preview}
<div <div
class="border border-solid border-base-content/20 flex max-w-xl flex-col leading-normal rounded-box"> class="border border-solid flex max-w-xl flex-col leading-normal rounded-2xl"
style="border-color: var(--line)">
{#if preview.image && !hideImage} {#if preview.image && !hideImage}
<img <img
alt="" alt=""
onerror={onError} onerror={onError}
src={preview.image} src={preview.image}
class="bg-alt max-h-72 rounded-t-box object-contain object-center" /> class="bg-surface max-h-72 rounded-t-2xl object-contain object-center" />
{/if} {/if}
<div class="flex flex-col gap-2 p-4"> <div class="flex flex-col gap-2 p-4">
<strong class="overflow-hidden text-ellipsis whitespace-nowrap" <strong class="overflow-hidden text-ellipsis whitespace-nowrap"
@ -93,7 +95,9 @@
</div> </div>
</div> </div>
{:catch} {:catch}
<p class="border border-solid border-base-content/20 p-12 text-center leading-normal"> <p
class="border border-solid p-12 text-center leading-normal"
style="border-color: var(--line)">
Unable to load a preview for {url} Unable to load a preview for {url}
</p> </p>
{/await} {/await}

View file

@ -8,5 +8,5 @@
</script> </script>
<Button class="m-auto h-screen w-screen cursor-pointer p-4" onclick={back}> <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 rounded-2xl" />
</Button> </Button>

View file

@ -98,11 +98,11 @@
<div class="relative"> <div class="relative">
{#if warning} {#if warning}
<div class="card2 card2-sm shadow-none row-2"> <div class="card card-sm shadow-none flex gap-2">
<Icon icon={Danger} /> <Icon icon={Danger} />
<p> <p>
This note has been flagged by the author as "{warning}".<br /> This note has been flagged by the author as "{warning}".<br />
<Button class="link" onclick={ignoreWarning}>Show anyway</Button> <Button onclick={ignoreWarning} class="button button-link">Show anyway</Button>
</p> </p>
</div> </div>
{:else} {:else}

View file

@ -48,20 +48,21 @@
<NoteContent {url} event={$quote} /> <NoteContent {url} event={$quote} />
{:else if $quote.kind === MESSAGE} {:else if $quote.kind === MESSAGE}
<div <div
class="border-l-2 border-solid border-l-primary py-1 pl-2 opacity-90" class="border-l-2 border-solid py-1 pl-2 opacity-90"
style="background-color: color-mix(in srgb, var(--color-primary) 10%, var(--color-base-300) 90%);"> style="border-left-color: var(--primary); background-color: color-mix(in srgb, var(--primary) 10%, var(--surface-more) 90%);">
<NoteContentMinimal trimParent {url} event={$quote} /> <NoteContentMinimal trimParent {url} event={$quote} />
</div> </div>
{:else} {:else}
<NoteCard <NoteCard
event={$quote} event={$quote}
{url} {url}
class="border border-solid border-base-content/20 rounded-box p-4"> class="border border-solid rounded-2xl p-4"
style="border-color: var(--line)">
<NoteContentMinimal {url} event={$quote} /> <NoteContentMinimal {url} event={$quote} />
</NoteCard> </NoteCard>
{/if} {/if}
{:else} {:else}
<div class="rounded-box p-4"> <div class="rounded-2xl p-4">
<Spinner loading>Loading event...</Spinner> <Spinner loading>Loading event...</Spinner>
</div> </div>
{/if} {/if}

View file

@ -66,11 +66,7 @@
</script> </script>
<button <button
class={cx( class={cx(props.class, {"bg-surface": currency}, "input flex items-center gap-2 cursor-pointer")}
props.class,
{"bg-base-200": currency},
"input input-bordered flex items-center gap-2 cursor-pointer",
)}
bind:this={wrapper} bind:this={wrapper}
onfocus={preventDefault(clearAndFocus)} onfocus={preventDefault(clearAndFocus)}
onclick={preventDefault(clearAndFocus)}> onclick={preventDefault(clearAndFocus)}>

View file

@ -68,11 +68,11 @@
</Field> </Field>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button class="btn btn-primary" onclick={submit} disabled={loading}> <Button class="button button-primary" onclick={submit} disabled={loading}>
<Spinner {loading}>Save changes</Spinner> <Spinner {loading}>Save changes</Spinner>
</Button> </Button>
</ModalFooter> </ModalFooter>

View file

@ -43,22 +43,22 @@
let popover: Instance | undefined = $state() let popover: Instance | undefined = $state()
</script> </script>
<div class="join items-center rounded-full"> <div class="items-center join">
{#if ENABLE_ZAPS && !hideZap} {#if ENABLE_ZAPS && !hideZap}
<ZapButton {url} {event} class="btn join-item btn-neutral btn-xs"> <ZapButton {url} {event} class="button button-neutral button-xs join-item">
<Icon icon={Bolt} size={4} /> <Icon icon={Bolt} size={4} />
</ZapButton> </ZapButton>
{/if} {/if}
<EmojiButton {onEmoji} class="btn join-item btn-neutral btn-xs"> <EmojiButton {onEmoji} class="button button-neutral button-xs join-item">
<Icon icon={SmileCircle} size={4} /> <Icon icon={SmileCircle} size={4} />
</EmojiButton> </EmojiButton>
<Tippy <Tippy
class="flex"
bind:popover bind:popover
class="flex join-item button button-neutral button-xs"
component={EventMenu} component={EventMenu}
props={{url, noun, event, customActions, onClick: hidePopover}} props={{url, noun, event, customActions, onClick: hidePopover}}
params={{trigger: "manual", interactive: true}}> params={{trigger: "manual", interactive: true}}>
<Button class="btn join-item btn-neutral btn-xs" onclick={showPopover}> <Button onclick={showPopover}>
<Icon icon={MenuDots} size={4} /> <Icon icon={MenuDots} size={4} />
</Button> </Button>
</Tippy> </Tippy>

View file

@ -22,13 +22,13 @@
}) })
</script> </script>
<div class="flex-inline btn btn-neutral btn-xs gap-1 rounded-full"> <div class="flex-inline button button-neutral button-xs gap-1 rounded-full">
<Icon icon={Reply} /> <Icon icon={Reply} />
<span>{$replies.length} {$replies.length === 1 ? "reply" : "replies"}</span> <span>{$replies.length} {$replies.length === 1 ? "reply" : "replies"}</span>
</div> </div>
<div class="btn btn-neutral btn-xs relative rounded-full"> <div class="button button-neutral button-xs relative rounded-full">
{#if gt(lastActive, $checked)} {#if gt(lastActive, $checked)}
<div class="h-2 w-2 rounded-full bg-primary"></div> <div class="h-2 w-2 rounded-full bg-primary text-primary-content"></div>
{/if} {/if}
Active {formatTimestampRelative(lastActive)} Active {formatTimestampRelative(lastActive)}
</div> </div>

View file

@ -11,6 +11,7 @@
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import FieldInline from "@lib/components/FieldInline.svelte" import FieldInline from "@lib/components/FieldInline.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import Badge from "@lib/components/Badge.svelte"
import Modal from "@lib/components/Modal.svelte" import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte" import ModalBody from "@lib/components/ModalBody.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte" import ModalHeader from "@lib/components/ModalHeader.svelte"
@ -60,7 +61,7 @@
<p>Event Link</p> <p>Event Link</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<Icon icon={FileText} /> <Icon icon={FileText} />
<input type="text" class="ellipsize min-w-0 grow" value={nevent1} /> <input type="text" class="ellipsize min-w-0 grow" value={nevent1} />
<Button onclick={copyLink} class="flex items-center"> <Button onclick={copyLink} class="flex items-center">
@ -74,7 +75,7 @@
<p>Author Pubkey</p> <p>Author Pubkey</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<Icon icon={UserCircle} /> <Icon icon={UserCircle} />
<input type="text" class="ellipsize min-w-0 grow" value={npub1} /> <input type="text" class="ellipsize min-w-0 grow" value={npub1} />
<Button onclick={copyPubkey} class="flex items-center"> <Button onclick={copyPubkey} class="flex items-center">
@ -91,24 +92,24 @@
{#snippet input()} {#snippet input()}
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
{#each seenOn as url, i (url)} {#each seenOn as url, i (url)}
<span class="bg-alt badge flex gap-1"> <Badge class="bg-surface flex gap-1">
{displayRelayUrl(url)} {displayRelayUrl(url)}
</span> </Badge>
{/each} {/each}
</div> </div>
{/snippet} {/snippet}
</FieldInline> </FieldInline>
{/if} {/if}
<div class="relative"> <div class="relative">
<pre class="card2 card2-sm bg-alt overflow-auto text-xs"><code>{json}</code></pre> <pre class="card card-sm overflow-auto text-xs"><code>{json}</code></pre>
<p class="absolute right-2 top-2 flex grow items-center justify-between"> <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 onclick={copyJson} class="button button-neutral button-sm flex items-center">
<Icon icon={Copy} /> Copy <Icon icon={Copy} /> Copy
</Button> </Button>
</p> </p>
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-primary grow" onclick={() => history.back()}>Got it</Button> <Button class="button button-primary grow" onclick={() => history.back()}>Got it</Button>
</ModalFooter> </ModalFooter>
</Modal> </Modal>

View file

@ -78,7 +78,7 @@
}) })
</script> </script>
<ul class="menu whitespace-nowrap rounded-box bg-base-100 p-2 shadow-md" bind:this={ul}> <ul class="menu whitespace-nowrap rounded-2xl bg-surface p-2" bind:this={ul}>
{#if isRoot} {#if isRoot}
<li> <li>
<Button onclick={share}> <Button onclick={share}>

View file

@ -7,6 +7,7 @@
import Paperclip from "@assets/icons/paperclip-2.svg?dataurl" import Paperclip from "@assets/icons/paperclip-2.svg?dataurl"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import EditorContent from "@app/editor/EditorContent.svelte" import EditorContent from "@app/editor/EditorContent.svelte"
import ChatComposeParent from "@app/components/ChatComposeParent.svelte" import ChatComposeParent from "@app/components/ChatComposeParent.svelte"
import {publishComment} from "@app/comments" import {publishComment} from "@app/comments"
@ -101,7 +102,7 @@
bind:this={form} bind:this={form}
onsubmit={preventDefault(submit)} 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"> 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="card mx-2 my-2 shadow-md">
{#if parent} {#if parent}
<ChatComposeParent event={parent} clear={() => onClearParent?.()} verb="Replying to" /> <ChatComposeParent event={parent} clear={() => onClearParent?.()} verb="Replying to" />
{/if} {/if}
@ -111,18 +112,18 @@
</div> </div>
<Button <Button
data-tip="Add an image" data-tip="Add an image"
class="tooltip tooltip-left absolute bottom-1 right-2" class="tip tip-left absolute bottom-1 right-2"
onclick={selectFiles}> onclick={selectFiles}>
{#if $uploading} {#if $uploading}
<span class="loading loading-spinner loading-xs"></span> <Spinner size="xs" />
{:else} {:else}
<Icon icon={Paperclip} size={3} /> <Icon icon={Paperclip} size={3} />
{/if} {/if}
</Button> </Button>
</div> </div>
<div class="flex justify-between pt-3"> <div class="flex justify-between pt-3">
<Button class="btn btn-link" onclick={onClose}>Cancel</Button> <Button class="button button-link" onclick={onClose}>Cancel</Button>
<Button type="submit" class="btn btn-primary">Post Reply</Button> <Button type="submit" class="button button-primary">Post Reply</Button>
</div> </div>
</div> </div>
</form> </form>

View file

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import cx from "classnames"
import {goto} from "$app/navigation" import {goto} from "$app/navigation"
import type {TrustedEvent} from "@welshman/util" import type {TrustedEvent} from "@welshman/util"
import {preventDefault} from "@lib/html" import {preventDefault} from "@lib/html"
@ -41,23 +42,21 @@
</ModalHeader> </ModalHeader>
<div class="grid grid-cols-3 gap-2"> <div class="grid grid-cols-3 gap-2">
{#each $roomsByUrl.get(url) || [] as room (room.h)} {#each $roomsByUrl.get(url) || [] as room (room.h)}
<button <Button
type="button" type="button"
class="btn" class={cx(`button button-${selection === room.h ? "primary" : "neutral"}`)}
class:btn-neutral={selection !== room.h}
class:btn-primary={selection === room.h}
onclick={() => toggleRoom(room.h)}> onclick={() => toggleRoom(room.h)}>
#<RoomName {...room} /> #<RoomName {...room} />
</button> </Button>
{/each} {/each}
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={!selection}> <Button type="submit" class="button button-primary" disabled={!selection}>
Share {noun} Share {noun}
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -34,11 +34,11 @@
<div class="flex grow flex-wrap justify-end gap-2"> <div class="flex grow flex-wrap justify-end gap-2">
{#if h && showRoom} {#if h && showRoom}
<Link href={makeSpacePath(url, h)} class="btn btn-neutral btn-xs rounded-full"> <Link href={makeSpacePath(url, h)} class="button button-neutral button-xs rounded-full">
Posted in #<RoomName {h} {url} /> Posted in #<RoomName {h} {url} />
</Link> </Link>
{/if} {/if}
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-left" /> <ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tip-left" />
<ThunkStatusOrDeleted {event} /> <ThunkStatusOrDeleted {event} />
{#if showActivity} {#if showActivity}
<EventActivity {url} {path} {event} /> <EventActivity {url} {path} {event} />

View file

@ -145,13 +145,13 @@
<ModalTitle>Create a Funding Goal</ModalTitle> <ModalTitle>Create a Funding Goal</ModalTitle>
<ModalSubtitle>Request contributions for your fundraiser.</ModalSubtitle> <ModalSubtitle>Request contributions for your fundraiser.</ModalSubtitle>
</ModalHeader> </ModalHeader>
<div class="col-8 relative"> <div class="flex flex-col gap-8 relative">
<Field> <Field>
{#snippet label()} {#snippet label()}
<p>Title*</p> <p>Title*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<!-- svelte-ignore a11y_autofocus --> <!-- svelte-ignore a11y_autofocus -->
<input <input
autofocus={!isMobile} autofocus={!isMobile}
@ -175,11 +175,11 @@
</Field> </Field>
<Button <Button
data-tip="Add an image" data-tip="Add an image"
class="tooltip tooltip-left absolute bottom-1 right-2" class="tip tip-left absolute bottom-1 right-2"
onclick={selectFiles} onclick={selectFiles}
disabled={loading}> disabled={loading}>
{#if $uploading} {#if $uploading}
<span class="loading loading-spinner loading-xs"></span> <Spinner size="xs" />
{:else} {:else}
<Icon icon={Paperclip} size={3} /> <Icon icon={Paperclip} size={3} />
{/if} {/if}
@ -192,7 +192,7 @@
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<div class="flex grow justify-end"> <div class="flex grow justify-end">
<label class="input input-bordered flex w-auto items-center gap-2"> <label class="input flex w-auto items-center gap-2">
<Icon icon={Bolt} /> <Icon icon={Bolt} />
<input bind:value={amount} type="number" class="w-28 grow" /> <input bind:value={amount} type="number" class="w-28 grow" />
<p class="shrink-0 opacity-50">sats</p> <p class="shrink-0 opacity-50">sats</p>
@ -201,7 +201,7 @@
{/snippet} {/snippet}
</FieldInline> </FieldInline>
<input <input
class="range range-primary -mt-2 w-full" class="range -mt-2 w-full"
type="range" type="range"
min="1000" min="1000"
max="100000" max="100000"
@ -211,11 +211,11 @@
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}> <Button class="button button-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={$uploading || loading}> <Button type="submit" class="button button-primary" disabled={$uploading || loading}>
<Spinner {loading}>Create Goal</Spinner> <Spinner {loading}>Create Goal</Spinner>
</Button> </Button>
</ModalFooter> </ModalFooter>

View file

@ -20,7 +20,9 @@
const h = getTagValue("h", event.tags) const h = getTagValue("h", event.tags)
</script> </script>
<Link class="cv col-2 card2 w-full cursor-pointer" href={makeGoalPath(url, event.id)}> <Link
class="cv flex flex-col gap-2 card card-interactive w-full"
href={makeGoalPath(url, event.id)}>
<p class="text-2xl">{event.content}</p> <p class="text-2xl">{event.content}</p>
<Content <Content
event={{content: summary, tags: event.tags}} event={{content: summary, tags: event.tags}}

View file

@ -46,8 +46,8 @@
<p class="text-sm opacity-75">{daysOld === 1 ? "day" : "days"} old</p> <p class="text-sm opacity-75">{daysOld === 1 ? "day" : "days"} old</p>
</div> </div>
</div> </div>
<progress class="progress progress-primary" value={zapAmount} max={goalAmount}></progress> <progress class="progress" value={zapAmount} max={goalAmount}></progress>
<ZapButton {url} {event} class="btn btn-primary lg:m-auto lg:px-20"> <ZapButton {url} {event} class="button button-primary lg:m-auto lg:px-20">
<Icon icon={Bolt} /> <Icon icon={Bolt} />
Contribute to this goal Contribute to this goal
</ZapButton> </ZapButton>

View file

@ -43,7 +43,7 @@
} }
</script> </script>
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<Icon icon={Magnifier} /> <Icon icon={Magnifier} />
<input bind:value={searchTerm} class="grow" type="text" placeholder="Search icons..." /> <input bind:value={searchTerm} class="grow" type="text" placeholder="Search icons..." />
</label> </label>
@ -53,7 +53,7 @@
<button <button
type="button" type="button"
title={icon.name} title={icon.name}
class="flex aspect-square items-center justify-center rounded-box transition-colors hover:bg-primary hover:text-primary-content" class="flex aspect-square items-center justify-center rounded-2xl transition-colors hover:bg-primary hover:text-primary-content"
onclick={() => handleSelect(icon.url)}> onclick={() => handleSelect(icon.url)}>
<Icon icon={icon.url} class="h-6 w-6" /> <Icon icon={icon.url} class="h-6 w-6" />
</button> </button>

View file

@ -8,6 +8,6 @@
const {onSelect}: Props = $props() const {onSelect}: Props = $props()
</script> </script>
<div class="w-96 rounded-box bg-base-100 p-4 shadow-2xl"> <div class="w-96 rounded-2xl bg-surface p-4 shadow-2xl">
<IconPicker {onSelect} /> <IconPicker {onSelect} />
</div> </div>

View file

@ -37,5 +37,5 @@
href="https://nostrapps.com#signers">nostrapps.com</Link href="https://nostrapps.com#signers">nostrapps.com</Link
>. >.
</p> </p>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button> <Button class="button button-primary" onclick={() => history.back()}>Got it</Button>
</ModalBody></Modal> </ModalBody></Modal>

View file

@ -27,5 +27,5 @@
class="underline">nostr.how</Link class="underline">nostr.how</Link
>. >.
</p> </p>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button> <Button class="button button-primary" onclick={() => history.back()}>Got it</Button>
</ModalBody></Modal> </ModalBody></Modal>

View file

@ -44,16 +44,16 @@
</p> </p>
<p>If you'd like to switch to self-custody, please click below to get started.</p> <p>If you'd like to switch to self-custody, please click below to get started.</p>
{:else} {:else}
<Button class="btn btn-primary" onclick={back}>Got it</Button> <Button class="button button-primary" onclick={back}>Got it</Button>
{/if} {/if}
</ModalBody> </ModalBody>
{#if $session?.email} {#if $session?.email}
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button class="btn btn-primary" onclick={startRecoveryRequest}> <Button class="button button-primary" onclick={startRecoveryRequest}>
<Icon icon={CheckCircle} /> <Icon icon={CheckCircle} />
I want to hold my own keys I want to hold my own keys
</Button> </Button>

View file

@ -28,5 +28,5 @@
To learn more about how to manage your keys, or to set up an account, try 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>. <Link external class="link" href="https://nosta.me/">nosta.me</Link>.
</p> </p>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button> <Button class="button button-primary" onclick={() => history.back()}>Got it</Button>
</ModalBody></Modal> </ModalBody></Modal>

View file

@ -27,6 +27,6 @@
</p> </p>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button> <Button class="button button-primary" onclick={() => history.back()}>Got it</Button>
</ModalFooter> </ModalFooter>
</Modal> </Modal>

View file

@ -30,5 +30,5 @@
information flowing through the network — instead, your client software can prove that a given information flowing through the network — instead, your client software can prove that a given
piece of data is authentic. piece of data is authentic.
</p> </p>
<Button class="btn btn-primary" onclick={back}>Got it</Button> <Button class="button button-primary" onclick={back}>Got it</Button>
</ModalBody></Modal> </ModalBody></Modal>

View file

@ -32,7 +32,7 @@
</p> </p>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>

View file

@ -79,28 +79,26 @@
<label <label
for={id} for={id}
aria-label="Drag and drop files here." aria-label="Drag and drop files here."
style="background-image: url({url});" style="background-image: url({url}); border-color: {active ? 'var(--primary)' : 'var(--line)'};"
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" class="bg-surface-more 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:transparent={!url}
class:border-primary={active}
ondragenter={stopPropagation(preventDefault(onDragEnter))} ondragenter={stopPropagation(preventDefault(onDragEnter))}
ondragover={stopPropagation(preventDefault(onDragOver))} ondragover={stopPropagation(preventDefault(onDragOver))}
ondragleave={stopPropagation(preventDefault(onDragLeave))} ondragleave={stopPropagation(preventDefault(onDragLeave))}
ondrop={stopPropagation(preventDefault(onDrop))}> ondrop={stopPropagation(preventDefault(onDrop))}>
<div <div
class="absolute right-0 top-0 h-5 w-5 overflow-hidden rounded-full bg-primary" class="absolute right-0 top-0 h-5 w-5 overflow-hidden rounded-full"
class:bg-error={url} style="background: {url ? 'var(--error)' : 'var(--primary)'};">
class:bg-primary={!url}>
{#if url} {#if url}
<span <span
role="button" role="button"
tabindex="-1" tabindex="-1"
onmousedown={stopPropagation(onClear)} onmousedown={stopPropagation(onClear)}
ontouchstart={stopPropagation(onClear)}> ontouchstart={stopPropagation(onClear)}>
<Icon icon={CloseCircle} class="scale-150 bg-base-300!" /> <Icon icon={CloseCircle} class="scale-150 bg-surface-more!" />
</span> </span>
{:else} {:else}
<Icon icon={AddCircle} class="scale-150 bg-base-300!" /> <Icon icon={AddCircle} class="scale-150 bg-surface-more!" />
{/if} {/if}
</div> </div>
{#if !url} {#if !url}

View file

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import cx from "classnames"
import {nsecEncode} from "nostr-tools/nip19" import {nsecEncode} from "nostr-tools/nip19"
import {encrypt} from "nostr-tools/nip49" import {encrypt} from "nostr-tools/nip49"
import {hexToBytes} from "@welshman/lib" import {hexToBytes} from "@welshman/lib"
@ -129,7 +130,7 @@
Password* Password*
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<Icon icon={Key} /> <Icon icon={Key} />
<input bind:value={password} onchange={onPasswordChange} class="grow" type="password" /> <input bind:value={password} onchange={onPasswordChange} class="grow" type="password" />
</label> </label>
@ -140,11 +141,13 @@
</Field> </Field>
{/if} {/if}
<div class="flex flex-col"> <div class="flex flex-col">
<Button class="btn {didDownload ? 'btn-neutral' : 'btn-primary'}" onclick={downloadKey}> <Button
class={cx(`button button-${didDownload ? "neutral" : "primary"}`)}
onclick={downloadKey}>
Download my key Download my key
<Icon icon={ArrowDown} /> <Icon icon={ArrowDown} />
</Button> </Button>
<Button class="btn btn-link no-underline" onclick={toggleUsePassword}> <Button class="button button-link no-underline" onclick={toggleUsePassword}>
{#if usePassword} {#if usePassword}
Nevermind, I want to download the plain version Nevermind, I want to download the plain version
{:else} {:else}
@ -157,11 +160,11 @@
<ProgressBar current={step} total={totalSteps} /> <ProgressBar current={step} total={totalSteps} />
{/if} {/if}
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button disabled={!didDownload} class="btn btn-primary" type="submit"> <Button class="button button-primary" disabled={!didDownload} type="submit">
{submitText} {submitText}
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -87,11 +87,11 @@
<StringMultiInput bind:value={otps} placeholder="Enter your recovery codes..." /> <StringMultiInput bind:value={otps} placeholder="Enter your recovery codes..." />
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={loading || otps.length < 2}> <Button type="submit" class="button button-primary" disabled={loading || otps.length < 2}>
<Spinner {loading}>Confirm recovery</Spinner> <Spinner {loading}>Confirm recovery</Spinner>
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -59,11 +59,11 @@
</p> </p>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={loading}> <Button type="submit" class="button button-primary" disabled={loading}>
<Spinner {loading}>Request recovery</Spinner> <Spinner {loading}>Request recovery</Spinner>
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -24,7 +24,7 @@
<p class="text-center">The chat app built for self-hosted communities.</p> <p class="text-center">The chat app built for self-hosted communities.</p>
</div> </div>
<Button onclick={logIn}> <Button onclick={logIn}>
<CardButton class="btn-primary"> <CardButton primary>
{#snippet icon()} {#snippet icon()}
<div><Icon icon={Login} size={7} /></div> <div><Icon icon={Login} size={7} /></div>
{/snippet} {/snippet}
@ -36,7 +36,7 @@
{/snippet} {/snippet}
</CardButton> </CardButton>
</Button> </Button>
<Button onclick={signUp} class="btn-neutral"> <Button onclick={signUp}>
<CardButton> <CardButton>
{#snippet icon()} {#snippet icon()}
<div><Icon icon={AddCircle} size={7} /></div> <div><Icon icon={AddCircle} size={7} /></div>

View file

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import cx from "classnames"
import {onMount} from "svelte" import {onMount} from "svelte"
import {Capacitor} from "@capacitor/core" import {Capacitor} from "@capacitor/core"
import {getNip07, getNip55, Nip55Signer} from "@welshman/signer" import {getNip07, getNip55, Nip55Signer} from "@welshman/signer"
@ -13,6 +14,7 @@
import Modal from "@lib/components/Modal.svelte" import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte" import ModalBody from "@lib/components/ModalBody.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import SignUp from "@app/components/SignUp.svelte" import SignUp from "@app/components/SignUp.svelte"
import InfoNostr from "@app/components/InfoNostr.svelte" import InfoNostr from "@app/components/InfoNostr.svelte"
import LogInBunker from "@app/components/LogInBunker.svelte" import LogInBunker from "@app/components/LogInBunker.svelte"
@ -101,9 +103,9 @@
allows you to own your social identity. allows you to own your social identity.
</p> </p>
{#if getNip07()} {#if getNip07()}
<Button {disabled} onclick={loginWithNip07} class="btn btn-primary"> <Button {disabled} onclick={loginWithNip07} class="button button-primary">
{#if loading === "nip07"} {#if loading === "nip07"}
<span class="loading loading-spinner mr-3"></span> <Spinner size="sm" class="mr-3" />
{:else} {:else}
<Icon icon={Widget} /> <Icon icon={Widget} />
{/if} {/if}
@ -111,9 +113,9 @@
</Button> </Button>
{/if} {/if}
{#each signers as app} {#each signers as app}
<Button {disabled} class="btn btn-primary" onclick={() => loginWithNip55(app)}> <Button {disabled} class="button button-primary" onclick={() => loginWithNip55(app)}>
{#if loading === "nip55"} {#if loading === "nip55"}
<span class="loading loading-spinner mr-3"></span> <Spinner size="sm" class="mr-3" />
{:else} {:else}
<img src={app.iconUrl} alt={app.name} width="20" height="20" /> <img src={app.iconUrl} alt={app.name} width="20" height="20" />
{/if} {/if}
@ -121,7 +123,7 @@
</Button> </Button>
{/each} {/each}
{#if hasPomade && !hasSigner} {#if hasPomade && !hasSigner}
<Button {disabled} onclick={loginWithEmail} class="btn btn-primary"> <Button {disabled} onclick={loginWithEmail} class="button button-primary">
<Icon icon={Letter} /> <Icon icon={Letter} />
Log in with Email Log in with Email
</Button> </Button>
@ -129,18 +131,18 @@
<Button <Button
onclick={loginWithBunker} onclick={loginWithBunker}
{disabled} {disabled}
class="btn {hasSigner || hasPomade ? 'btn-neutral' : 'btn-primary'}"> class={cx(`button button-${hasSigner || hasPomade ? "neutral" : "primary"}`)}>
<Icon icon={Cpu} /> <Icon icon={Cpu} />
Log in with Remote Signer Log in with Remote Signer
</Button> </Button>
{#if hasPomade && hasSigner} {#if hasPomade && hasSigner}
<Button {disabled} onclick={loginWithEmail} class="btn"> <Button {disabled} onclick={loginWithEmail}>
<Icon icon={Letter} /> <Icon icon={Letter} />
Log in with Email Log in with Email
</Button> </Button>
{/if} {/if}
{#if !hasSigner} {#if !hasSigner}
<Button {disabled} onclick={loginWithKey} class="btn btn-neutral"> <Button {disabled} onclick={loginWithKey} class="button button-neutral">
<Icon icon={Key} /> <Icon icon={Key} />
Log in with Key Log in with Key
</Button> </Button>
@ -150,7 +152,7 @@
external external
{disabled} {disabled}
href="https://nostrapps.com#signers" href="https://nostrapps.com#signers"
class="btn {hasSigner || hasPomade ? '' : 'btn-neutral'}"> class="button {hasSigner || hasPomade ? '' : 'button-neutral'}">
<Icon icon={Compass} /> <Icon icon={Compass} />
Browse Signer Apps Browse Signer Apps
</Link> </Link>

View file

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import cx from "classnames"
import {Capacitor} from "@capacitor/core" import {Capacitor} from "@capacitor/core"
import {onMount, onDestroy} from "svelte" import {onMount, onDestroy} from "svelte"
import type {Nip46ResponseWithResult} from "@welshman/signer" import type {Nip46ResponseWithResult} from "@welshman/signer"
@ -151,20 +152,20 @@
<BunkerConnect {controller} /> <BunkerConnect {controller} />
{:else} {:else}
<BunkerUrl {controller} /> <BunkerUrl {controller} />
<Button class="btn {$bunker ? 'btn-neutral' : 'btn-primary'}" onclick={selectConnect} <Button class={cx(`button button-${$bunker ? "neutral" : "primary"}`)} onclick={selectConnect}
>Log in with a QR code instead</Button> >Log in with a QR code instead</Button>
{#if isIos} {#if isIos}
<Button class="btn btn-neutral" onclick={openSigner}>Open in Signer</Button> <Button class="button button-neutral" onclick={openSigner}>Open in Signer</Button>
{/if} {/if}
{/if} {/if}
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={$loading}> <Button class="button button-link" onclick={back} disabled={$loading}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
{#if mode === "bunker"} {#if mode === "bunker"}
<Button type="submit" class="btn btn-primary" disabled={$loading || !$bunker}> <Button type="submit" class="button button-primary" disabled={$loading || !$bunker}>
<Spinner loading={$loading}>Next</Spinner> <Spinner loading={$loading}>Next</Spinner>
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -96,7 +96,7 @@
<p>Email*</p> <p>Email*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input input-group flex w-full items-center gap-2">
<Icon icon={Letter} /> <Icon icon={Letter} />
<input type="email" bind:value={email} /> <input type="email" bind:value={email} />
</label> </label>
@ -107,24 +107,24 @@
<p>Password*</p> <p>Password*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input input-group flex w-full items-center gap-2">
<Icon icon={Key} /> <Icon icon={Key} />
<input type="password" bind:value={password} /> <input type="password" bind:value={password} />
</label> </label>
{/snippet} {/snippet}
</FieldInline> </FieldInline>
<p class="text-sm"> <p class="text-sm">
Forgot your password? <Button class="link" onclick={loginWithOTP} Forgot your password? <Button class="button button-link" onclick={loginWithOTP}
>Log in with a one-time access code</Button >Log in with a one-time access code</Button
>. >.
</p> </p>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}> <Button class="button button-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={loading || !email || !password}> <Button type="submit" class="button button-primary" disabled={loading || !email || !password}>
<Spinner {loading}>Log in</Spinner> <Spinner {loading}>Log in</Spinner>
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -85,7 +85,7 @@
<p>Your Key*</p> <p>Your Key*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input input-group flex w-full items-center gap-2">
<Icon icon={Key} /> <Icon icon={Key} />
<input type="password" bind:value={keyInput} placeholder="nsec1..." /> <input type="password" bind:value={keyInput} placeholder="nsec1..." />
</label> </label>
@ -97,14 +97,14 @@
<p>Password*</p> <p>Password*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input input-group flex w-full items-center gap-2">
<Icon icon={Key} /> <Icon icon={Key} />
<input type="password" bind:value={password} placeholder="Your password" /> <input type="password" bind:value={password} placeholder="Your password" />
</label> </label>
{/snippet} {/snippet}
</FieldInline> </FieldInline>
{/if} {/if}
<div class="card2 card2-sm bg-alt flex flex-col gap-2 text-sm"> <div class="card card-sm flex flex-col gap-2 text-sm">
<strong class="flex items-center gap-2"> <strong class="flex items-center gap-2">
<Icon icon={Danger} /> <Icon icon={Danger} />
Please note! Please note!
@ -117,11 +117,11 @@
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}> <Button class="button button-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={!canSubmit}> <Button type="submit" class="button button-primary" disabled={!canSubmit}>
<Spinner {loading}>Log in</Spinner> <Spinner {loading}>Log in</Spinner>
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -69,7 +69,7 @@
<p>Email*</p> <p>Email*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input input-group flex w-full items-center gap-2">
<Icon icon={Letter} /> <Icon icon={Letter} />
<input type="email" bind:value={email} /> <input type="email" bind:value={email} />
</label> </label>
@ -77,11 +77,11 @@
</FieldInline> </FieldInline>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}> <Button class="button button-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={loading || !email}> <Button type="submit" class="button button-primary" disabled={loading || !email}>
<Spinner {loading}>Log in</Spinner> <Spinner {loading}>Log in</Spinner>
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -99,11 +99,11 @@
<StringMultiInput bind:value={otps} placeholder="Enter your login codes..." /> <StringMultiInput bind:value={otps} placeholder="Enter your login codes..." />
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}> <Button class="button button-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={loading || otps.length < 3}> <Button type="submit" class="button button-primary" disabled={loading || otps.length < 3}>
<Spinner {loading}>Log In</Spinner> <Spinner {loading}>Log In</Spinner>
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -75,14 +75,14 @@
<Button <Button
onclick={() => selectAccount(option)} onclick={() => selectAccount(option)}
disabled={loading} disabled={loading}
class="card2 bg-alt flex w-full items-center p-3 text-left"> class="card flex w-full items-center p-3 text-left">
<Profile inert pubkey={option.pubkey} /> <Profile inert pubkey={option.pubkey} />
</Button> </Button>
{/each} {/each}
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}> <Button class="button button-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>

View file

@ -35,11 +35,11 @@
<p class="text-center">Your local database will be cleared.</p> <p class="text-center">Your local database will be cleared.</p>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={loading}> <Button type="submit" class="button button-primary" disabled={loading}>
<Spinner {loading}>Log Out</Spinner> <Spinner {loading}>Log Out</Spinner>
</Button> </Button>
</ModalFooter> </ModalFooter>

View file

@ -32,7 +32,7 @@
<Link <Link
replaceState replaceState
href="/settings/alerts" href="/settings/alerts"
class="aspect-square btn h-[unset] btn-neutral flex flex-col gap-2 text-center"> class="aspect-square button button-neutral h-[unset] flex flex-col gap-2 text-center">
<Icon icon={Bell} size={5} /> <Icon icon={Bell} size={5} />
Alerts Alerts
</Link> </Link>
@ -40,7 +40,7 @@
<Link <Link
replaceState replaceState
href="/settings/wallet" href="/settings/wallet"
class="aspect-square btn h-[unset] btn-neutral flex flex-col gap-2 text-center"> class="aspect-square button button-neutral h-[unset] flex flex-col gap-2 text-center">
<Icon icon={Wallet} size={5} /> <Icon icon={Wallet} size={5} />
Wallet Wallet
</Link> </Link>
@ -48,21 +48,21 @@
<Link <Link
replaceState replaceState
href="/settings/relays" href="/settings/relays"
class="aspect-square btn h-[unset] btn-neutral flex flex-col gap-2 text-center"> class="aspect-square button button-neutral h-[unset] flex flex-col gap-2 text-center">
<Icon icon={Server} size={5} /> <Icon icon={Server} size={5} />
Relays Relays
</Link> </Link>
<Link <Link
replaceState replaceState
href="/settings/content" href="/settings/content"
class="aspect-square btn h-[unset] btn-neutral flex flex-col gap-2 text-center"> class="aspect-square button button-neutral h-[unset] flex flex-col gap-2 text-center">
<Icon icon={GalleryMinimalistic} size={5} /> <Icon icon={GalleryMinimalistic} size={5} />
Content Content
</Link> </Link>
<Link <Link
replaceState replaceState
href="/settings/privacy" href="/settings/privacy"
class="aspect-square btn h-[unset] btn-neutral flex flex-col gap-2 text-center"> class="aspect-square button button-neutral h-[unset] flex flex-col gap-2 text-center">
<Icon icon={Shield} size={5} /> <Icon icon={Shield} size={5} />
Privacy Privacy
</Link> </Link>

View file

@ -25,6 +25,7 @@
hideProfile?: boolean hideProfile?: boolean
url?: string url?: string
class?: string class?: string
style?: string
} = $props() } = $props()
const ignoreMute = () => { const ignoreMute = () => {
@ -34,10 +35,10 @@
let muted = $state($isEventMuted(event)) let muted = $state($isEventMuted(event))
</script> </script>
<div class="flex flex-col gap-2 {restProps.class}"> <div class="flex flex-col gap-2 {restProps.class}" style={restProps.style}>
{#if muted} {#if muted}
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="row-2 relative"> <div class="flex gap-2 relative">
<Icon icon={Danger} class="mt-1" /> <Icon icon={Danger} class="mt-1" />
<p>You have muted this person.</p> <p>You have muted this person.</p>
</div> </div>

View file

@ -12,7 +12,7 @@
<div class="flex grow flex-col"> <div class="flex grow flex-col">
<CalendarEventHeader event={props.event} /> <CalendarEventHeader event={props.event} />
<div class="flex py-2 opacity-50"> <div class="flex py-2 opacity-50">
<div class="h-px grow bg-base-content opacity-25"></div> <div class="h-px grow opacity-25" style="background-color: var(--line)"></div>
</div> </div>
<Content {...props} /> <Content {...props} />
</div> </div>

View file

@ -40,11 +40,11 @@
}) })
</script> </script>
<NoteCard {event} {url} class="cv card2"> <NoteCard {event} {url} class="cv card card-interactive">
<NoteContent {event} expandMode="inline" /> <NoteContent {event} expandMode="inline" />
<div class="flex w-full justify-between gap-2"> <div class="flex w-full justify-between gap-2">
<ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tooltip-right"> <ReactionSummary {url} {event} {deleteReaction} {createReaction} reactionClass="tip-right">
<EmojiButton {onEmoji} class="btn btn-neutral btn-xs h-[26px] rounded-box"> <EmojiButton {onEmoji} class="button button-neutral button-xs h-[26px] rounded-2xl">
<Icon icon={SmileCircle} size={4} /> <Icon icon={SmileCircle} size={4} />
</EmojiButton> </EmojiButton>
</ReactionSummary> </ReactionSummary>

View file

@ -94,11 +94,11 @@
<StringMultiInput bind:value={otps} placeholder="Enter your confirmation codes..." /> <StringMultiInput bind:value={otps} placeholder="Enter your confirmation codes..." />
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={loading || otps.length < 2}> <Button type="submit" class="button button-primary" disabled={loading || otps.length < 2}>
<Spinner {loading}>Continue</Spinner> <Spinner {loading}>Continue</Spinner>
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -98,7 +98,7 @@
<p>New Password*</p> <p>New Password*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input input-group flex w-full items-center gap-2">
<Icon icon={Key} /> <Icon icon={Key} />
<input type="password" bind:value={password} /> <input type="password" bind:value={password} />
</label> </label>
@ -106,11 +106,11 @@
</FieldInline> </FieldInline>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button class="btn btn-primary" type="submit" disabled={loading || !password}> <Button class="button button-primary" type="submit" disabled={loading || !password}>
<Spinner {loading}>Continue</Spinner> <Spinner {loading}>Continue</Spinner>
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -18,17 +18,17 @@
const openProfile = () => pushModal(ProfileDetail, {pubkey, url}) const openProfile = () => pushModal(ProfileDetail, {pubkey, url})
</script> </script>
<div class="card2 card2-interactive col-4"> <div class="card card-interactive flex flex-col gap-4">
<div class="flex justify-between"> <div class="flex justify-between">
<Profile {pubkey} {url} /> <Profile {pubkey} {url} />
<Button onclick={openProfile} class="btn btn-primary hidden sm:flex"> <Button onclick={openProfile} class="button button-primary hidden sm:flex">
<Icon icon={UserCircle} /> <Icon icon={UserCircle} />
View Profile View Profile
</Button> </Button>
</div> </div>
<ProfileInfo {pubkey} {url} /> <ProfileInfo {pubkey} {url} />
<ProfileBadges {pubkey} {url} /> <ProfileBadges {pubkey} {url} />
<Button onclick={openProfile} class="btn btn-primary sm:hidden"> <Button onclick={openProfile} class="button button-primary sm:hidden">
<Icon icon={UserCircle} /> <Icon icon={UserCircle} />
View Profile View Profile
</Button> </Button>

View file

@ -188,13 +188,13 @@
<ModalTitle>Create a Poll</ModalTitle> <ModalTitle>Create a Poll</ModalTitle>
<ModalSubtitle>Ask a question and collect votes right in the feed.</ModalSubtitle> <ModalSubtitle>Ask a question and collect votes right in the feed.</ModalSubtitle>
</ModalHeader> </ModalHeader>
<div class="col-8 relative"> <div class="flex flex-col gap-8 relative">
<Field> <Field>
{#snippet label()} {#snippet label()}
<p>Question*</p> <p>Question*</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<!-- svelte-ignore a11y_autofocus --> <!-- svelte-ignore a11y_autofocus -->
<input <input
autofocus={!isMobile} autofocus={!isMobile}
@ -224,7 +224,7 @@
<div class="cursor-move opacity-70" aria-label="Drag handle"> <div class="cursor-move opacity-70" aria-label="Drag handle">
<Icon icon={HamburgerMenu} size={4} /> <Icon icon={HamburgerMenu} size={4} />
</div> </div>
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<input <input
value={option.value} value={option.value}
class="grow" class="grow"
@ -232,12 +232,14 @@
placeholder={`Option ${index + 1}`} placeholder={`Option ${index + 1}`}
oninput={e => updateOption(option.id, e.currentTarget.value)} /> oninput={e => updateOption(option.id, e.currentTarget.value)} />
</label> </label>
<Button class="btn btn-ghost btn-sm" onclick={() => removeOption(option.id)}> <Button
class="button button-ghost button-sm"
onclick={() => removeOption(option.id)}>
<Icon icon={MinusCircle} size={4} /> <Icon icon={MinusCircle} size={4} />
</Button> </Button>
</div> </div>
{/each} {/each}
<Button class="btn btn-outline btn-sm self-end" onclick={addOption}> <Button class="button button-outline button-sm self-end" onclick={addOption}>
<Icon icon={PlusCircle} size={4} /> <Icon icon={PlusCircle} size={4} />
Add option Add option
</Button> </Button>
@ -251,7 +253,7 @@
Poll type Poll type
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<select class="select select-bordered w-full max-w-xs" bind:value={pollType}> <select class="select input w-full max-w-xs" bind:value={pollType}>
<option value="singlechoice">Single choice</option> <option value="singlechoice">Single choice</option>
<option value="multiplechoice">Multiple choice</option> <option value="multiplechoice">Multiple choice</option>
</select> </select>
@ -269,11 +271,11 @@
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back} disabled={loading}> <Button class="button button-link" onclick={back} disabled={loading}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={loading}> <Button type="submit" class="button button-primary" disabled={loading}>
<Spinner {loading}>Create Poll</Spinner> <Spinner {loading}>Create Poll</Spinner>
</Button> </Button>
</ModalFooter> </ModalFooter>

View file

@ -19,7 +19,7 @@
</script> </script>
<Link <Link
class="cv col-2 card2 bg-alt w-full cursor-pointer shadow-md" class="cv flex flex-col gap-2 card card-interactive w-full"
href={makePollPath(url, event.id)}> href={makePollPath(url, event.id)}>
<NoteContent {event} {url} /> <NoteContent {event} {url} />
<div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row"> <div class="flex w-full flex-col items-end justify-between gap-2 sm:flex-row">

View file

@ -41,7 +41,7 @@
}) })
</script> </script>
<div class="flex flex-col gap-2 card2 card2-sm bg-alt"> <div class="flex flex-col gap-2 card card-sm">
<div class="flex items-center justify-between gap-2"> <div class="flex items-center justify-between gap-2">
<label class="flex min-w-0 grow items-center gap-2"> <label class="flex min-w-0 grow items-center gap-2">
{#if !closed} {#if !closed}
@ -49,14 +49,14 @@
<input <input
name={event.id} name={event.id}
type="radio" type="radio"
class="radio radio-primary radio-sm" class="radio"
checked={selected} checked={selected}
onclick={stopPropagation(noop)} onclick={stopPropagation(noop)}
onchange={onselect} /> onchange={onselect} />
{:else} {:else}
<input <input
type="checkbox" type="checkbox"
class="checkbox checkbox-primary checkbox-sm" class="checkbox"
checked={selected} checked={selected}
onclick={stopPropagation(noop)} onclick={stopPropagation(noop)}
onchange={onselect} /> onchange={onselect} />
@ -66,5 +66,5 @@
</label> </label>
<span class="whitespace-nowrap text-xs opacity-75">{votes} vote{votes === 1 ? "" : "s"}</span> <span class="whitespace-nowrap text-xs opacity-75">{votes} vote{votes === 1 ? "" : "s"}</span>
</div> </div>
<progress class="progress progress-primary" value={$tweenedVotes} max={$tweenedMax}></progress> <progress class="progress" value={$tweenedVotes} max={$tweenedMax}></progress>
</div> </div>

View file

@ -6,6 +6,7 @@
import {fly} from "@lib/transition" import {fly} from "@lib/transition"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import Badge from "@lib/components/Badge.svelte"
import Popover from "@lib/components/Popover.svelte" import Popover from "@lib/components/Popover.svelte"
import TrashBin2 from "@assets/icons/trash-bin-2.svg?dataurl" import TrashBin2 from "@assets/icons/trash-bin-2.svg?dataurl"
import {pushToast} from "@app/toast" import {pushToast} from "@app/toast"
@ -69,7 +70,7 @@
</script> </script>
{#if sessions.length > 0} {#if sessions.length > 0}
<div class="flex flex-col gap-4 border-t border-solid border-base-100 pt-4"> <div class="flex flex-col gap-4 border-t border-solid pt-4" style="border-color: var(--line)">
<strong>Other Sessions</strong> <strong>Other Sessions</strong>
{#each sessions as sessionItem (sessionItem.client)} {#each sessions as sessionItem (sessionItem.client)}
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
@ -84,7 +85,7 @@
</div> </div>
<div class="relative"> <div class="relative">
<Button <Button
class="btn btn-circle btn-ghost btn-sm" class="button button-ghost button-sm button-circle"
onclick={() => toggleMenu(sessionItem.client)}> onclick={() => toggleMenu(sessionItem.client)}>
<Icon icon={MenuDots} /> <Icon icon={MenuDots} />
</Button> </Button>
@ -92,7 +93,7 @@
<Popover hideOnClick onClose={closeMenu}> <Popover hideOnClick onClose={closeMenu}>
<ul <ul
transition:fly transition:fly
class="menu absolute right-0 z-popover mt-2 w-48 gap-1 rounded-box bg-base-100 p-2 shadow-md"> class="menu bg-surface absolute right-0 z-popover mt-2 w-48 gap-1 rounded-2xl p-2">
<li> <li>
<Button onclick={() => deleteSession(sessionItem)}> <Button onclick={() => deleteSession(sessionItem)}>
<Icon icon={TrashBin2} /> <Icon icon={TrashBin2} />
@ -105,12 +106,12 @@
</div> </div>
</div> </div>
<div class="flex gap-1"> <div class="flex gap-1">
<div class="badge badge-neutral"> <Badge variant="neutral">
Created {formatDate(sessionItem.created_at)} Created {formatDate(sessionItem.created_at)}
</div> </Badge>
<div class="badge badge-neutral"> <Badge variant="neutral">
Active {formatDate(sessionItem.last_activity)} Active {formatDate(sessionItem.last_activity)}
</div> </Badge>
</div> </div>
</div> </div>
{/each} {/each}

View file

@ -32,43 +32,40 @@
) )
</script> </script>
<div <div class="primary-nav" class:justify-between={PLATFORM_RELAYS.length === 0}>
class="ml-sai mt-sai mb-sai relative z-popover isolate hidden w-14 shrink-0 bg-base-200 pt-2 md:block border-r border-solid border-base-content/15 dark:border-base-content/10"> <PrimaryNavSpaces />
<div class="flex h-full flex-col" class:justify-between={PLATFORM_RELAYS.length === 0}> {#if PLATFORM_RELAYS.length > 0}
<PrimaryNavSpaces /> <Divider />
{#if PLATFORM_RELAYS.length > 0} {/if}
<Divider /> <div class="flex flex-col">
{/if} <PrimaryNavItem title="Settings" href="/settings/profile" prefix="/settings">
<div class="flex flex-col"> {#if $userProfile?.picture}
<PrimaryNavItem title="Settings" href="/settings/profile" prefix="/settings"> <ImageIcon alt="Settings" src={$userProfile?.picture} class="rounded-full" size={10} />
{#if $userProfile?.picture} {:else}
<ImageIcon alt="Settings" src={$userProfile?.picture} class="rounded-full" size={10} /> <ImageIcon alt="Settings" src={UserRounded} class="rounded-full" size={8} />
{:else} {/if}
<ImageIcon alt="Settings" src={UserRounded} class="rounded-full" size={8} /> </PrimaryNavItem>
{/if} <PrimaryNavItem
</PrimaryNavItem> title="Messages"
<PrimaryNavItem onclick={chatHandler}
title="Messages" notification={$notifications.has("/chat")}>
onclick={chatHandler} <ImageIcon alt="Messages" src={Letter} size={8} />
notification={$notifications.has("/chat")}> </PrimaryNavItem>
<ImageIcon alt="Messages" src={Letter} size={8} /> <PrimaryNavItem title="Search" href="/people">
</PrimaryNavItem> <ImageIcon alt="Search" src={Magnifier} size={8} />
<PrimaryNavItem title="Search" href="/people"> </PrimaryNavItem>
<ImageIcon alt="Search" src={Magnifier} size={8} />
</PrimaryNavItem>
</div>
</div> </div>
</div> </div>
{@render children?.()} {@render children?.()}
<!-- a little extra something for ios --> <!-- a little extra something for ios -->
<div class="hide-on-keyboard fixed bottom-0 left-0 right-0 z-nav h-(--saib) bg-base-100 md:hidden"> <div class="hide-on-keyboard fixed bottom-0 left-0 right-0 z-nav h-(--saib) bg-surface md:hidden">
</div> </div>
<div <div
class="hide-on-keyboard border-top bottom-sai fixed left-0 right-0 z-nav h-14 border border-base-200 bg-base-100 md:hidden"> class="hide-on-keyboard border-top bottom-sai fixed left-0 right-0 z-nav h-14 border border-line bg-surface md:hidden">
<div class="content-padding-x content-sizing flex justify-between px-2"> <div class="flex h-full justify-between px-2">
<div class="flex gap-2 sm:gap-6"> <div class="flex items-center gap-6">
<PrimaryNavItem title="Search" href="/people"> <PrimaryNavItem title="Search" href="/people">
<ImageIcon alt="Search" src={Magnifier} size={8} /> <ImageIcon alt="Search" src={Magnifier} size={8} />
</PrimaryNavItem> </PrimaryNavItem>

View file

@ -23,7 +23,6 @@
href={path} href={path}
onclick={onClick} onclick={onClick}
title={showTooltip ? $display : ""} title={showTooltip ? $display : ""}
class="tooltip-right"
notification={$notifications.has(path)}> notification={$notifications.has(path)}>
<RelayIcon {url} size={10} class="rounded-full" /> <RelayIcon {url} size={10} class="rounded-full" />
</PrimaryNavItem> </PrimaryNavItem>

View file

@ -29,7 +29,7 @@
<svelte:window bind:innerHeight={windowHeight} /> <svelte:window bind:innerHeight={windowHeight} />
<div> <div class="flex flex-col">
{#each PLATFORM_RELAYS as url (url)} {#each PLATFORM_RELAYS as url (url)}
<PrimaryNavItemSpace {url} /> <PrimaryNavItemSpace {url} />
{:else} {:else}

View file

@ -8,8 +8,7 @@
const {urls}: Props = $props() const {urls}: Props = $props()
</script> </script>
<div <div class="flex max-h-[80vh] flex-col overflow-y-auto rounded-2xl border border-solid bg-surface p-1 shadow-xl border-line">
class="flex max-h-[80vh] flex-col overflow-y-auto rounded-box border border-solid border-base-content/15 bg-base-200 p-1 shadow-xl">
{#each urls as url (url)} {#each urls as url (url)}
<PrimaryNavItemSpace {url} showTooltip={false} /> <PrimaryNavItemSpace {url} showTooltip={false} />
{/each} {/each}

View file

@ -8,17 +8,19 @@
type Props = { type Props = {
pubkey?: string pubkey?: string
class?: string class?: string
style?: string
size?: number size?: number
url?: string url?: string
} }
const {pubkey, url, size = 7, ...props}: Props = $props() const {pubkey, url, size = 7, style = undefined, ...props}: Props = $props()
const profile = deriveProfile(pubkey, removeUndefined([url])) const profile = deriveProfile(pubkey, removeUndefined([url]))
</script> </script>
<ImageIcon <ImageIcon
{size} {size}
{style}
alt="" alt=""
class={cx(props.class, "rounded-full")} class={cx(props.class, "rounded-full")}
src={$profile?.picture || UserRounded} /> src={$profile?.picture || UserRounded} />

View file

@ -40,17 +40,17 @@
{#each displayPubkeys as pubkey (pubkey)} {#each displayPubkeys as pubkey (pubkey)}
<div <div
class={cx( class={cx(
"z-feature inline-block flex items-center justify-center rounded-full bg-base-100", "z-feature inline-block flex items-center justify-center rounded-full bg-surface",
dimensions.box, dimensions.box,
dimensions.overlap, dimensions.overlap,
)}> )}>
<ProfileCircle class={cx(dimensions.box, "bg-base-300")} {pubkey} {size} /> <ProfileCircle class={cx(dimensions.box, "bg-surface-more")} {pubkey} {size} />
</div> </div>
{/each} {/each}
{#if overflowCount > 0} {#if overflowCount > 0}
<div <div
class={cx( class={cx(
"z-feature inline-flex items-center justify-center rounded-full bg-neutral font-medium text-neutral-content", "z-feature inline-flex items-center justify-center rounded-full bg-surface font-medium text-content",
dimensions.box, dimensions.box,
dimensions.overlap, dimensions.overlap,
dimensions.overflow, dimensions.overflow,

View file

@ -117,8 +117,7 @@
We are currently sending deletion requests to your relay selections and space hosts. Please We are currently sending deletion requests to your relay selections and space hosts. Please
wait while we complete this process. Once we're done, you'll be automatically logged out. wait while we complete this process. Once we're done, you'll be automatically logged out.
</p> </p>
<progress class="progress progress-primary w-full" value={progress! * 100} max="100" <progress class="progress w-full" value={progress! * 100} max="100"></progress>
></progress>
{:else} {:else}
<p> <p>
This will delete your nostr account everywhere, not just on {PLATFORM_NAME}. This will delete your nostr account everywhere, not just on {PLATFORM_NAME}.
@ -127,7 +126,7 @@
To confirm, please type "{CONFIRM_TEXT}" into the text box below. This action can't be To confirm, please type "{CONFIRM_TEXT}" into the text box below. This action can't be
undone. undone.
</p> </p>
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input input-group flex w-full items-center gap-2">
<input bind:value={confirmText} class="grow" type="text" /> <input bind:value={confirmText} class="grow" type="text" />
</label> </label>
<p> <p>
@ -137,11 +136,11 @@
{/if} {/if}
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<Button type="submit" class="btn btn-error" disabled={showProgress || !confirmOk}> <Button type="submit" class="button button-error" disabled={showProgress || !confirmOk}>
<Spinner loading={progress !== undefined}>Confirm</Spinner> <Spinner loading={progress !== undefined}>Confirm</Spinner>
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -103,14 +103,16 @@
<Profile showPubkey avatarSize={14} {pubkey} {url} /> <Profile showPubkey avatarSize={14} {pubkey} {url} />
{#if $profile || $userIsAdmin} {#if $profile || $userIsAdmin}
<div class="relative"> <div class="relative">
<Button class="btn btn-circle btn-ghost btn-sm" onclick={() => toggleMenu(pubkey)}> <Button
class="button button-ghost button-sm button-circle"
onclick={() => toggleMenu(pubkey)}>
<Icon icon={MenuDots} /> <Icon icon={MenuDots} />
</Button> </Button>
{#if showMenu} {#if showMenu}
<Popover hideOnClick onClose={closeMenu}> <Popover hideOnClick onClose={closeMenu}>
<ul <ul
transition:fly transition:fly
class="bg-alt menu absolute right-0 z-popover w-48 gap-1 rounded-box p-2 shadow-md"> class="bg-surface menu absolute right-0 z-popover w-48 gap-1 rounded-2xl p-2 shadow-md">
{#if $profile} {#if $profile}
<li> <li>
<Button onclick={showInfo}> <Button onclick={showInfo}>
@ -147,16 +149,16 @@
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button onclick={back} class="hidden md:btn md:btn-link"> <Button onclick={back} class="button button-link hidden md:flex">
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>
<div class="flex gap-2"> <div class="flex gap-2">
<Link external href={pubkeyLink(pubkey)} class="btn btn-neutral"> <Link external href={pubkeyLink(pubkey)} class="button button-neutral">
<ImageIcon alt="" src="/coracle.png" /> <ImageIcon alt="" src="/coracle.png" />
Open in Coracle Open in Coracle
</Link> </Link>
<Button onclick={openChat} class="btn btn-primary"> <Button onclick={openChat} class="button button-primary">
<Icon icon={Letter} /> <Icon icon={Letter} />
Message Message
</Button> </Button>

View file

@ -42,11 +42,11 @@
<ProfileEditForm {initialValues} {onsubmit}> <ProfileEditForm {initialValues} {onsubmit}>
{#snippet footer()} {#snippet footer()}
<Button class="btn btn-link" onclick={back}> <Button class="button button-link" onclick={back}>
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go Back Go Back
</Button> </Button>
<Button type="submit" class="btn btn-primary" disabled={loading}> <Button type="submit" class="button button-primary" disabled={loading}>
<Spinner {loading} /> <Spinner {loading} />
Save Changes Save Changes
</Button> </Button>

View file

@ -61,7 +61,7 @@
<p>Nickname</p> <p>Nickname</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<Icon icon={UserCircle} /> <Icon icon={UserCircle} />
<input bind:value={values.profile.name} class="grow" type="text" /> <input bind:value={values.profile.name} class="grow" type="text" />
</label> </label>
@ -75,10 +75,8 @@
<p>About You</p> <p>About You</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<textarea <textarea class="textarea input leading-4 w-full" rows="5" bind:value={values.profile.about}
class="textarea textarea-bordered leading-4 w-full" ></textarea>
rows="5"
bind:value={values.profile.about}></textarea>
{/snippet} {/snippet}
{#snippet info()} {#snippet info()}
Give a brief introduction to why you're here. Give a brief introduction to why you're here.
@ -90,14 +88,14 @@
<p>Nostr Address</p> <p>Nostr Address</p>
{/snippet} {/snippet}
{#snippet input()} {#snippet input()}
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input flex w-full items-center gap-2">
<Icon icon={MapPoint} /> <Icon icon={MapPoint} />
<input bind:value={values.profile.nip05} class="grow" type="text" /> <input bind:value={values.profile.nip05} class="grow" type="text" />
</label> </label>
{/snippet} {/snippet}
{#snippet info()} {#snippet info()}
<p> <p>
<Button class="link" onclick={() => pushModal(InfoHandle)} <Button class="button button-link" onclick={() => pushModal(InfoHandle)}
>What is a nostr address?</Button> >What is a nostr address?</Button>
</p> </p>
{/snippet} {/snippet}

View file

@ -58,7 +58,7 @@
}) })
</script> </script>
<div class="col-4" bind:this={element}> <div class="flex flex-col gap-4" bind:this={element}>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
{#each events as event (event.id)} {#each events as event (event.id)}
<div in:fly> <div in:fly>
@ -66,7 +66,7 @@
</div> </div>
{/each} {/each}
{#if !hideLoading} {#if !hideLoading}
<p class="center my-12 flex"> <p class="justify-center items-center my-12 flex">
<Spinner loading /> <Spinner loading />
</p> </p>
{/if} {/if}

View file

@ -2,6 +2,7 @@
import type {Snippet} from "svelte" import type {Snippet} from "svelte"
import {load} from "@welshman/net" import {load} from "@welshman/net"
import {NOTE} from "@welshman/util" import {NOTE} from "@welshman/util"
import Spinner from "@lib/components/Spinner.svelte"
import NoteItem from "@app/components/NoteItem.svelte" import NoteItem from "@app/components/NoteItem.svelte"
interface Props { interface Props {
@ -19,11 +20,11 @@
}) })
</script> </script>
<div class="col-4"> <div class="flex flex-col gap-4">
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
{#await events} {#await events}
<p class="center flex min-h-6"> <p class="flex justify-center items-center min-h-6">
<span class="loading loading-spinner"></span> <Spinner />
</p> </p>
{:then events} {:then events}
{#each events as event (event.id)} {#each events as event (event.id)}

View file

@ -20,6 +20,6 @@
<Button <Button
onclick={preventDefault(openProfile)} onclick={preventDefault(openProfile)}
class={cx(props.class, {"link-content bg-alt": !unstyled})}> class={cx(props.class, {"link-content bg-surface": !unstyled})}>
@<ProfileName {pubkey} {url} /> @<ProfileName {pubkey} {url} />
</Button> </Button>

View file

@ -25,12 +25,12 @@
<ModalSubtitle>{subtitle}</ModalSubtitle> <ModalSubtitle>{subtitle}</ModalSubtitle>
</ModalHeader> </ModalHeader>
{#each pubkeys as pubkey (pubkey)} {#each pubkeys as pubkey (pubkey)}
<div class="card2 bg-alt"> <div class="card">
<Profile {pubkey} {url} /> <Profile {pubkey} {url} />
</div> </div>
{/each} {/each}
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-primary" onclick={() => history.back()}>Got it</Button> <Button class="button button-primary" onclick={() => history.back()}>Got it</Button>
</ModalFooter> </ModalFooter>
</Modal> </Modal>

View file

@ -11,6 +11,7 @@
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Tippy from "@lib/components/Tippy.svelte" import Tippy from "@lib/components/Tippy.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import Badge from "@lib/components/Badge.svelte"
import ProfileSuggestion from "@app/editor/ProfileSuggestion.svelte" import ProfileSuggestion from "@app/editor/ProfileSuggestion.svelte"
import ProfileName from "@app/components/ProfileName.svelte" import ProfileName from "@app/components/ProfileName.svelte"
import ProfileDetail from "@app/components/ProfileDetail.svelte" import ProfileDetail from "@app/components/ProfileDetail.svelte"
@ -78,21 +79,21 @@
}) })
</script> </script>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-1">
<div> <div>
{#each value as pubkey (pubkey)} {#each value as pubkey (pubkey)}
{@const onClick = () => pushModal(ProfileDetail, {pubkey})} {@const onClick = () => pushModal(ProfileDetail, {pubkey})}
<div class="flex-inline badge badge-neutral mr-1 gap-1"> <Badge variant="neutral" class="flex-inline mr-1 mb-1 gap-1">
<Button class="flex items-center" onclick={() => removePubkey(pubkey)}> <Button class="flex items-center" onclick={() => removePubkey(pubkey)}>
<Icon icon={CloseCircle} size={4} class="-ml-1 mt-px" /> <Icon icon={CloseCircle} size={4} class="-ml-1 mt-px" />
</Button> </Button>
<Button onclick={onClick}> <Button onclick={onClick}>
<ProfileName {pubkey} /> <ProfileName {pubkey} />
</Button> </Button>
</div> </Badge>
{/each} {/each}
</div> </div>
<label class="input input-bordered flex w-full items-center gap-2" bind:this={label}> <label class="input flex w-full items-center gap-2" bind:this={label}>
<Icon icon={Magnifier} /> <Icon icon={Magnifier} />
<!-- svelte-ignore a11y_autofocus --> <!-- svelte-ignore a11y_autofocus -->
<input <input
@ -113,7 +114,7 @@
search, search,
select: selectPubkey, select: selectPubkey,
component: ProfileSuggestion, component: ProfileSuggestion,
class: "rounded-box", class: "rounded-2xl",
style: `left: 4px; width: ${label?.clientWidth + 12}px`, style: `left: 4px; width: ${label?.clientWidth + 12}px`,
}} }}
params={{ params={{

View file

@ -24,7 +24,7 @@
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
{#each spaceUrls as url (url)} {#each spaceUrls as url (url)}
<div class="card2 bg-alt flex flex-row items-center gap-2"> <div class="card flex flex-row items-center gap-2">
<div class="shrink-0"> <div class="shrink-0">
<RelayIcon {url} size={12} /> <RelayIcon {url} size={12} />
</div> </div>
@ -34,18 +34,18 @@
{url} {url}
</div> </div>
</div> </div>
<Link class="btn btn-primary" href={makeSpacePath(url)}> <Link class="button button-primary" href={makeSpacePath(url)}>
Go to space Go to space
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Link> </Link>
</div> </div>
{:else} {:else}
<div class="card2 bg-alt text-center"> <div class="card text-center">
<p class="opacity-75">No spaces found for this user</p> <p class="opacity-75">No spaces found for this user</p>
</div> </div>
{/each} {/each}
<ModalFooter> <ModalFooter>
<Button onclick={back} class="hidden md:btn md:btn-link"> <Button onclick={back} class="button button-link hidden md:flex">
<Icon icon={AltArrowLeft} /> <Icon icon={AltArrowLeft} />
Go back Go back
</Button> </Button>

View file

@ -4,6 +4,10 @@
<div class="flex w-full"> <div class="flex w-full">
{#each Array(total) as _, i} {#each Array(total) as _, i}
<div class="h-1 flex-1 transition-colors {i < current ? 'bg-primary' : 'bg-base-300'}"></div> <div
class="h-1 flex-1 transition-colors {i < current
? 'bg-primary text-primary-content'
: 'bg-surface-more'}">
</div>
{/each} {/each}
</div> </div>

View file

@ -29,7 +29,7 @@
<Button class="flex w-full justify-center {props.class}" onclick={copy}> <Button class="flex w-full justify-center {props.class}" onclick={copy}>
<div bind:this={wrapper} class="w-md" style={`height: ${height}px`}> <div bind:this={wrapper} class="w-md" style={`height: ${height}px`}>
<canvas <canvas
class="rounded-box" class="rounded-2xl"
bind:this={canvas} bind:this={canvas}
style={`transform-origin: top left; transform: scale(${scale}, ${scale})`}> style={`transform-origin: top left; transform: scale(${scale}, ${scale})`}>
</canvas> </canvas>

View file

@ -18,9 +18,10 @@
import {deriveArray, deriveEventsById, deriveItemsByKey} from "@welshman/store" import {deriveArray, deriveEventsById, deriveItemsByKey} from "@welshman/store"
import {load} from "@welshman/net" import {load} from "@welshman/net"
import {pubkey, repository, getValidZap, displayProfileByPubkey} from "@welshman/app" import {pubkey, repository, getValidZap, displayProfileByPubkey} from "@welshman/app"
import {isMobile, preventDefault, stopPropagation} from "@lib/html" import {isMobile} from "@lib/html"
import Danger from "@assets/icons/danger-triangle.svg?dataurl" import Danger from "@assets/icons/danger-triangle.svg?dataurl"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import Reaction from "@app/components/Reaction.svelte" import Reaction from "@app/components/Reaction.svelte"
import ReportDetails from "@app/components/ReportDetails.svelte" import ReportDetails from "@app/components/ReportDetails.svelte"
import {REACTION_KINDS} from "@app/content" import {REACTION_KINDS} from "@app/content"
@ -136,15 +137,18 @@
{#if $reactions.length > 0 || $zaps.length || $reports.length > 0 || children} {#if $reactions.length > 0 || $zaps.length || $reports.length > 0 || children}
<div class="flex min-w-0 flex-wrap gap-2"> <div class="flex min-w-0 flex-wrap gap-2">
{#if url && $reports.length > 0 && $userIsAdmin} {#if url && $reports.length > 0 && $userIsAdmin}
<button <Button
type="button"
data-tip={`This content has been reported as "${displayList(reportReasons)}".`} data-tip={`This content has been reported as "${displayList(reportReasons)}".`}
class="btn btn-error btn-xs tooltip-right flex items-center gap-1 rounded-full font-normal" class={cx(
class:tooltip={!noTooltip && !isMobile} "button button-error button-xs tip-right flex items-center gap-1 rounded-full font-normal",
onclick={stopPropagation(preventDefault(onReportClick))}> {
tip: !noTooltip && !isMobile,
},
)}
onclick={onReportClick}>
<Icon icon={Danger} /> <Icon icon={Danger} />
<span>{$reports.length}</span> <span>{$reports.length}</span>
</button> </Button>
{/if} {/if}
{#each groupedZaps.entries() as [key, zaps]} {#each groupedZaps.entries() as [key, zaps]}
{@const amount = fromMsats(sum(zaps.map(zap => zap.invoiceAmount)))} {@const amount = fromMsats(sum(zaps.map(zap => zap.invoiceAmount)))}
@ -152,21 +156,20 @@
{@const isOwn = $pubkey && pubkeys.includes($pubkey)} {@const isOwn = $pubkey && pubkeys.includes($pubkey)}
{@const info = displayList(pubkeys.map(pubkey => displayProfileByPubkey(pubkey)))} {@const info = displayList(pubkeys.map(pubkey => displayProfileByPubkey(pubkey)))}
{@const tooltip = `${info} zapped`} {@const tooltip = `${info} zapped`}
<button <Button
type="button"
data-tip={tooltip} data-tip={tooltip}
class={cx( class={cx(
reactionClass, reactionClass,
"flex-inline btn btn-outline btn-neutral btn-xs flex items-center gap-1 rounded-full text-xs font-normal bg-alt", "button button-xs flex-inline flex items-center gap-1 rounded-full text-xs font-normal",
{ {
tooltip: !noTooltip && !isMobile, tip: !noTooltip && !isMobile,
"border-neutral-content/20": !isOwn, "button-primary": isOwn,
"btn-primary": isOwn, "button-neutral": !isOwn,
}, },
)}> )}>
<Reaction event={zaps[0].request} /> <Reaction event={zaps[0].request} />
<span>{amount}</span> <span>{amount}</span>
</button> </Button>
{/each} {/each}
{#each groupedReactions.entries() as [key, events]} {#each groupedReactions.entries() as [key, events]}
{@const pubkeys = events.map(e => e.pubkey)} {@const pubkeys = events.map(e => e.pubkey)}
@ -174,24 +177,19 @@
{@const info = displayList(pubkeys.map(pubkey => displayProfileByPubkey(pubkey)))} {@const info = displayList(pubkeys.map(pubkey => displayProfileByPubkey(pubkey)))}
{@const tooltip = `${info} reacted`} {@const tooltip = `${info} reacted`}
{@const onClick = () => onReactionClick(events)} {@const onClick = () => onReactionClick(events)}
<button <Button
type="button"
data-tip={tooltip} data-tip={tooltip}
class={cx( class={cx(reactionClass, "button button-xs flex-inline gap-1 rounded-full font-normal", {
reactionClass, tip: !noTooltip && !isMobile,
"flex-inline btn btn-outline btn-neutral btn-xs gap-1 rounded-full font-normal bg-alt", "button-primary": isOwn,
{ "button-neutral": !isOwn,
tooltip: !noTooltip && !isMobile, })}
"border-neutral-content/20": !isOwn, onclick={onClick}>
"btn-primary": isOwn,
},
)}
onclick={stopPropagation(preventDefault(onClick))}>
<Reaction event={events[0]} /> <Reaction event={events[0]} />
{#if events.length > 1} {#if events.length > 1}
<span>{events.length}</span> <span>{events.length}</span>
{/if} {/if}
</button> </Button>
{/each} {/each}
{@render children?.()} {@render children?.()}
</div> </div>

View file

@ -25,7 +25,7 @@
const onClick = () => goto(h ? makeRoomPath(url, h) : makeSpaceChatPath(url)) const onClick = () => goto(h ? makeRoomPath(url, h) : makeSpaceChatPath(url))
</script> </script>
<Button class="cv card2" onclick={onClick}> <Button class="cv card card-interactive" onclick={onClick}>
<div class="flex flex-col gap-3"> <div class="flex flex-col gap-3">
<div class="flex items-center gap-2 text-sm"> <div class="flex items-center gap-2 text-sm">
{#if h} {#if h}
@ -49,7 +49,7 @@
{count} {count}
recent messages{count === 1 ? "" : "s"} recent messages{count === 1 ? "" : "s"}
</span> </span>
<Button class="btn btn-xs rounded-full btn-primary" onclick={onClick}> <Button class="button button-primary button-xs button-pill" onclick={onClick}>
View Conversation View Conversation
<Icon icon={AltArrowRight} /> <Icon icon={AltArrowRight} />
</Button> </Button>

View file

@ -12,6 +12,7 @@
import AddCircle from "@assets/icons/add-circle.svg?dataurl" import AddCircle from "@assets/icons/add-circle.svg?dataurl"
import Icon from "@lib/components/Icon.svelte" import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte" import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Modal from "@lib/components/Modal.svelte" import Modal from "@lib/components/Modal.svelte"
import ModalBody from "@lib/components/ModalBody.svelte" import ModalBody from "@lib/components/ModalBody.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte" import ModalFooter from "@lib/components/ModalFooter.svelte"
@ -83,19 +84,19 @@
<Modal> <Modal>
<ModalBody> <ModalBody>
<label class="input input-bordered flex w-full items-center gap-2"> <label class="input input-group flex w-full items-center gap-2">
<Icon icon={Magnifier} /> <Icon icon={Magnifier} />
<input bind:value={term} class="grow" type="text" placeholder="Search for relays..." /> <input bind:value={term} class="grow" type="text" placeholder="Search for relays..." />
</label> </label>
<div class="column -m-6 mt-0 h-[50vh] gap-2 overflow-auto p-6 pt-2" bind:this={element}> <div class="flex flex-col -m-6 mt-0 h-[50vh] gap-2 overflow-auto p-6 pt-2" bind:this={element}>
{#if customUrl && isShareableRelayUrl(customUrl) && !$relays.includes(customUrl)} {#if customUrl && isShareableRelayUrl(customUrl) && !$relays.includes(customUrl)}
<RelayItem url={term}> <RelayItem url={term}>
<Button <Button
class="btn btn-outline btn-sm flex items-center" class="button button-outline button-sm flex items-center"
disabled={loading.has(customUrl)} disabled={loading.has(customUrl)}
onclick={() => add(customUrl)}> onclick={() => add(customUrl)}>
{#if loading.has(customUrl)} {#if loading.has(customUrl)}
<span class="loading loading-spinner loading-sm"></span> <Spinner size="sm" />
{:else} {:else}
<Icon icon={AddCircle} /> <Icon icon={AddCircle} />
{/if} {/if}
@ -106,11 +107,11 @@
{#each searchResults as url (url)} {#each searchResults as url (url)}
<RelayItem {url}> <RelayItem {url}>
<Button <Button
class="btn btn-outline btn-sm flex items-center" class="button button-outline button-sm flex items-center"
disabled={loading.has(url)} disabled={loading.has(url)}
onclick={() => add(url)}> onclick={() => add(url)}>
{#if loading.has(url)} {#if loading.has(url)}
<span class="loading loading-spinner loading-sm"></span> <Spinner size="sm" />
{:else} {:else}
<Icon icon={AddCircle} /> <Icon icon={AddCircle} />
{/if} {/if}
@ -121,6 +122,6 @@
</div> </div>
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button class="btn btn-primary grow" onclick={back}>Done</Button> <Button class="button button-primary grow" onclick={back}>Done</Button>
</ModalFooter> </ModalFooter>
</Modal> </Modal>

Some files were not shown because too many files have changed in this diff Show more