Add light theme

This commit is contained in:
Jonathan Staab 2023-03-16 14:03:42 -05:00
parent b458e3b2d6
commit d0b6c77530
53 changed files with 284 additions and 239 deletions

2
.env Normal file
View File

@ -0,0 +1,2 @@
VITE_THEME_DARK=transparent:transparent,black:#0f0f0e,white:#FFFFFF,accent:#EB5E28,accent-light:#FB652C,gray-1:#FFFFFF,gray-2:#FAF6F1,gray-3:#F2EBE1,gray-4:#E9E0D3,gray-5:#B3AA98,gray-6:#565249,gray-7:#393530,gray-8:#252422,danger:#ff0000,warning:#ebd112,success:#37ab51,input:#F2EBE1,input-hover:#FAF6F1
VITE_THEME_LIGHT=transparent:transparent,black:#0f0f0e,white:#FFFFFF,accent:#EB5E28,accent-light:#FB652C,gray-8:#FFFFFF,gray-7:#FAF6F1,gray-6:#F2EBE1,gray-5:#E9E0D3,gray-4:#B3AA98,gray-3:#565249,gray-2:#393530,gray-1:#252422,danger:#ff0000,warning:#ebd112,success:#37ab51,input:#FAF6F1,input-hover:#F2EBE1

View File

@ -1,11 +1,8 @@
# Current
- [ ] Test migration
- [ ] Fix notifications
- [ ] Add quotes to notifications
- [ ] https://github.com/staab/coracle/issues/42
- [ ] Show loading/success on zap invoice screen
- [ ] Fix iOS/safari/firefox
- [ ] Light theme
- [ ] Env vars to white label
# Others
@ -31,6 +28,8 @@
# More
- [ ] Copy/share note id button
- [ ] Reposts
- [ ] Add delete button to notes. This will require tracking what relays a note was published to
- [ ] Add image proxy to avoid leaking user ips to hosts
- [ ] Show an error when something fails to load with a constructive suggestion

View File

@ -23,6 +23,7 @@
import * as tables from "src/agent/tables"
import user from "src/agent/user"
import {loadAppData} from "src/app"
import {theme, getThemeVariables} from "src/app/ui"
import {modal, routes, menuIsOpen, logUsage} from "src/app/ui"
import Anchor from "src/partials/Anchor.svelte"
import Content from "src/partials/Content.svelte"
@ -76,6 +77,12 @@
menuIsOpen.set(false)
}
const style = document.createElement("style")
document.head.append(style)
$: style.textContent = `:root { ${getThemeVariables($theme)}; background: var(--gray-8); }`
onMount(() => {
// Keep scroll position on body, but don't allow scrolling
const unsubModal = modal.subscribe($modal => {
@ -183,7 +190,7 @@
<Router {url}>
<div use:links class="h-full">
{#if ready}
<div class="h-full pt-16 text-white lg:ml-56">
<div class="h-full pt-16 text-gray-3 lg:ml-56">
<Route path="/notifications" component={Notifications} />
<Route path="/search">
<EnsureData enforcePeople={false}>

View File

@ -149,7 +149,7 @@ export class Table {
const k = item[this.pk]
if (!k) {
throw new Error(`Missing primary key on ${this.name}`)
throw new Error(`Missing gray-6 key on ${this.name}`)
}
this.cache.set(k, item)
@ -165,7 +165,7 @@ export class Table {
const k = item[this.pk]
if (!k) {
throw new Error(`Missing primary key on ${this.name}`)
throw new Error(`Missing gray-6 key on ${this.name}`)
}
this.cache.set(k, {...this.cache.get(k), ...item})

View File

@ -50,8 +50,6 @@
:root {
font-family: Montserrat;
background-color: #0f0f0e;
color: white;
}
html,
@ -66,8 +64,11 @@ body,
.tippy-box[data-theme~="dark"] {
background-color: #0f0f0e;
border: 1px solid #403d39;
box-shadow: 3px 3px 20px #0f0f0e, 3px -3px 20px #0f0f0e, -3px 3px 20px #0f0f0e,
-3px -3px 20px #0f0f0e;
box-shadow:
3px 3px 20px rgba(0, 0, 0, 0.1),
3px -3px 20px rgba(0, 0, 0, 0.1),
-3px 3px 20px rgba(0, 0, 0, 0.1),
-3px -3px 20px rgba(0, 0, 0, 0.1);
}
.tippy-box[data-theme~="dark"][data-placement^="top"] > .tippy-arrow {

View File

@ -1,19 +1,19 @@
import Bugsnag from "@bugsnag/js"
import {prop, last} from "ramda"
import {uuid} from "hurdak/lib/hurdak"
import type {Writable} from 'svelte/store'
import {prop, fromPairs, last} from "ramda"
import {uuid, switcher} from "hurdak/lib/hurdak"
import type {Writable} from "svelte/store"
import {navigate} from "svelte-routing"
import {nip19} from 'nostr-tools'
import {nip19} from "nostr-tools"
import {writable, get} from "svelte/store"
import {globalHistory} from "svelte-routing/src/history"
import {sleep, hash} from "src/util/misc"
import {warn} from 'src/util/logger'
import user from 'src/agent/user'
import {sleep, synced, hash} from "src/util/misc"
import {warn} from "src/util/logger"
import user from "src/agent/user"
// Routing
export const routes = {
person: (pubkey, tab = 'notes') => `/people/${nip19.npubEncode(pubkey)}/${tab}`,
person: (pubkey, tab = "notes") => `/people/${nip19.npubEncode(pubkey)}/${tab}`,
}
// Install prompt
@ -85,16 +85,16 @@ export const modal = {
// characters long, respectively. Put the threshold a little lower in case
// someone accidentally enters a key with the last few digits missing
const redactErrorInfo = info =>
JSON.parse(JSON.stringify(info || null).replace(/\w{60}\w+/g, '[REDACTED]'))
JSON.parse(JSON.stringify(info || null).replace(/\w{60}\w+/g, "[REDACTED]"))
// Wait for bugsnag to be started in main
setTimeout(() => {
Bugsnag.addOnError((event: any) => {
if (window.location.host.startsWith('localhost')) {
if (window.location.host.startsWith("localhost")) {
return false
}
if (!user.getSetting('reportAnalytics')) {
if (!user.getSetting("reportAnalytics")) {
return false
}
@ -117,17 +117,36 @@ export const logUsage = async name => {
// Hash the user's pubkey so we can identify unique users without knowing
// anything about them
const pubkey = user.getPubkey()
const ident = pubkey ? hash(pubkey) : 'unknown'
const ident = pubkey ? hash(pubkey) : "unknown"
const {dufflepudUrl, reportAnalytics} = user.getSettings()
if (reportAnalytics) {
try {
await fetch(`${dufflepudUrl}/usage/${ident}/${session}/${name}`, {method: 'post'})
await fetch(`${dufflepudUrl}/usage/${ident}/${session}/${name}`, {method: "post"})
} catch (e) {
if (!e.toString().includes('Failed to fetch')) {
if (!e.toString().includes("Failed to fetch")) {
warn(e)
}
}
}
}
// Themes
const parseTheme = s => fromPairs(s.split(",").map(x => x.split(":")))
const THEME_LIGHT = parseTheme(import.meta.env.VITE_THEME_LIGHT)
const THEME_DARK = parseTheme(import.meta.env.VITE_THEME_DARK)
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches
export const theme = synced("ui/theme", prefersDark ? "dark" : "light")
export const getThemeVariables = $theme => {
const colors = switcher($theme, {
light: THEME_LIGHT,
dark: THEME_DARK,
})
return Object.entries(colors)
.map(([k, v]) => `--${k}: ${v};`)
.join("\n")
}

View File

@ -15,9 +15,9 @@
{"opacity-50": loading},
switcher(type, {
anchor: "underline",
button: "py-2 px-4 rounded bg-white text-accent whitespace-nowrap",
button: "py-2 px-4 rounded bg-gray-3 text-accent whitespace-nowrap",
"button-circle":
"w-10 h-10 flex justify-center items-center rounded-full bg-white text-accent whitespace-nowrap",
"w-10 h-10 flex justify-center items-center rounded-full bg-gray-3 text-accent whitespace-nowrap",
"button-accent": "py-2 px-4 rounded bg-accent text-white whitespace-nowrap",
})
)

View File

@ -7,11 +7,11 @@
const className = cx(
$$props.class,
"py-2 px-4 rounded cursor-pointer",
{"text-light": disabled},
"py-2 px-4 rounded cursor-pointer border border-solid transition-all",
{"text-gray-5": disabled},
switcher(theme, {
default: "bg-white text-accent",
accent: "text-white bg-accent",
default: "bg-input text-accent border-gray-5 hover:bg-input-hover",
accent: "text-white bg-accent border-accent-light hover:bg-accent-light",
})
)
</script>

View File

@ -9,12 +9,12 @@
<div
on:click
in:fly={{y: 20}}
class={cx($$props.class, "card rounded-2xl bg-dark p-3 text-white", {
"border border-solid border-medium bg-dark": !invertColors,
"border border-solid border-shimmer bg-medium": invertColors,
class={cx($$props.class, "card rounded-2xl p-3 text-gray-2", {
"border border-solid border-gray-6 bg-gray-7": !invertColors,
"border border-solid border-gray-6 bg-gray-8": invertColors,
"cursor-pointer transition-all": interactive,
"hover:bg-medium": interactive && !invertColors,
"hover:bg-dark": interactive && invertColors,
"hover:bg-gray-8": interactive && !invertColors,
"hover:bg-gray-7": interactive && invertColors,
})}>
<slot />
</div>

View File

@ -130,30 +130,30 @@
</div>
<div
class="fixed top-0 z-20 w-full border-b border-solid
border-medium bg-dark p-4">
border-gray-6 bg-gray-7 p-4">
<slot name="header" />
</div>
<div
class="fixed bottom-0 z-10 flex w-full border-t border-solid border-medium border-dark bg-medium lg:-ml-56 lg:pl-56">
class="fixed bottom-0 z-10 flex w-full border-t border-solid border-gray-6 border-gray-7 bg-gray-6 lg:-ml-56 lg:pl-56">
<textarea
rows="3"
autofocus
placeholder="Type something..."
bind:this={textarea}
on:keypress={onKeyPress}
class="w-full resize-none bg-medium p-2
text-white outline-0 placeholder:text-light" />
class="w-full resize-none bg-gray-6 p-2
text-gray-3 outline-0 placeholder:text-gray-1" />
<button
on:click={send}
class="flex cursor-pointer flex-col justify-center gap-2 border-l border-solid border-dark p-4
py-8 text-white transition-all hover:bg-accent ">
class="flex cursor-pointer flex-col justify-center gap-2 border-l border-solid border-gray-7 p-4
py-8 text-gray-3 transition-all hover:bg-accent ">
<i class="fa-solid fa-paper-plane fa-xl" />
</button>
</div>
</div>
{#if showNewMessages}
<div class="fixed bottom-32 flex w-full justify-center" transition:fly|local={{y: 20}}>
<div class="rounded-full bg-accent py-2 px-4 text-white">New messages found</div>
<div class="rounded-full bg-accent py-2 px-4 text-gray-3">New messages found</div>
</div>
{/if}
</div>

View File

@ -212,7 +212,7 @@
<div class="flex">
<div
class="w-full min-w-0 p-2 text-white outline-0"
class="w-full min-w-0 p-2 text-gray-3 outline-0"
autofocus
contenteditable
bind:this={input}
@ -222,12 +222,12 @@
</div>
{#if suggestions.length > 0}
<div class="mt-2 flex flex-col rounded border border-solid border-medium" in:fly={{y: 20}}>
<div class="mt-2 flex flex-col rounded border border-solid border-gray-6" in:fly={{y: 20}}>
{#each suggestions as person, i (person.pubkey)}
<button
class="cursor-pointer border-l-2 border-solid border-black py-2 px-4"
class:bg-black={index !== i}
class:bg-dark={index === i}
class:bg-gray-8={index !== i}
class:bg-gray-7={index === i}
class:border-accent={index === i}
on:click={() => pickSuggestion(person)}>
<Badge inert {person} />

View File

@ -4,7 +4,7 @@
export let gap = 6
export let size = "2xl"
const className = `flex flex-col m-auto text-white gap-${gap}`
const className = `flex flex-col m-auto text-gray-3 gap-${gap}`
if (!["inherit", "lg", "2xl"].includes(size)) {
throw new Error(`Invalid size: ${size}`)

View File

@ -7,7 +7,8 @@
const className = cx(
$$props.class,
"rounded bg-light shadow-inset py-2 px-4 pr-10 text-black w-full placeholder:text-placeholder",
"rounded shadow-inset py-2 px-4 pr-10 w-full placeholder:text-gray-5",
"bg-input border border-solid border-gray-3 text-black",
{"pl-10": $$slots.before, "pr-10": $$slots.after}
)
</script>
@ -15,12 +16,13 @@
<div class={cx(wrapperClass, "relative")}>
<input {...$$props} class={className} bind:value on:change on:input />
{#if $$slots.before}
<div class="absolute top-0 left-0 flex gap-2 px-3 pt-3 text-dark">
<div class="absolute top-0 left-0 flex gap-2 px-3 pt-3 text-black opacity-75">
<slot name="before" />
</div>
{/if}
{#if $$slots.after}
<div class="absolute top-0 right-0 m-px flex gap-2 rounded bg-light px-3 pt-3 text-dark">
<div
class="absolute top-0 right-0 m-px flex gap-2 rounded px-3 pt-3 text-gray-1 text-black opacity-75">
<slot name="after" />
</div>
{/if}

View File

@ -13,7 +13,8 @@
}
}} />
<div class="modal fixed inset-0 z-30 bg-black/75" bind:this={root} transition:fade>
<div class="modal fixed inset-0 z-30" bind:this={root} transition:fade>
<div class="fixed inset-0 cursor-pointer bg-black opacity-75" on:click={onEscape} />
<div
class="modal-content h-full overflow-auto"
bind:this={content}
@ -25,14 +26,14 @@
<div class="pointer-events-none sticky top-0 z-10 flex w-full justify-end p-2">
<div
class="pointer-events-auto flex h-10 w-10 cursor-pointer items-center justify-center
rounded-full border border-solid border-medium bg-accent">
rounded-full border border-solid border-accent-light bg-accent text-white">
<i class="fa fa-times fa-lg" />
</div>
</div>
{/if}
<div class="absolute mt-12 h-full w-full bg-dark" />
<div class="absolute mt-12 h-full w-full bg-gray-7" />
<div
class="relative h-full w-full cursor-auto border-t border-solid border-medium bg-dark pt-2 pb-10"
class="relative h-full w-full cursor-auto border-t border-solid border-gray-6 bg-gray-7 pt-2 pb-10"
on:click|stopPropagation>
<slot />
</div>

View File

@ -6,7 +6,7 @@
import {displayPerson} from "src/util/nostr"
import Anchor from "src/partials/Anchor.svelte"
import {routes} from "src/app/ui"
import PersonCircle from "./PersonCircle.svelte";
import PersonCircle from "./PersonCircle.svelte"
export let person
export let addPetname = null
@ -16,8 +16,9 @@
<a
in:fly={{y: 20}}
href={routes.person(person.pubkey)}
class="flex gap-4 overflow-hidden border-l-2 border-solid border-dark py-3 px-4 transition-all hover:border-accent hover:bg-black">
<PersonCircle person={person} size={12} />
class="flex gap-4 overflow-hidden border-l-2 border-solid border-gray-7 py-3 px-4
transition-all hover:border-accent hover:bg-gray-8">
<PersonCircle {person} size={12} />
<div class="flex min-w-0 flex-grow flex-col gap-4">
<div class="flex items-start justify-between gap-2">
<div class="flex flex-col gap-2">
@ -25,7 +26,7 @@
{#if person.verified_as}
<div class="flex gap-1 text-sm">
<i class="fa fa-user-check text-accent" />
<span class="text-light">{last(person.verified_as.split("@"))}</span>
<span class="text-gray-1">{last(person.verified_as.split("@"))}</span>
</div>
{/if}
</div>

View File

@ -47,14 +47,14 @@
external
href={url}
style="background-color: rgba(15, 15, 14, 0.5)"
class="relative flex flex-col overflow-hidden rounded border border-solid border-medium">
class="relative flex flex-col overflow-hidden rounded border border-solid border-gray-6">
{#if preview.image}
<img alt="Link preview" src={preview.image} class="max-h-96 object-contain object-center" />
{/if}
{#if preview.video}
<video controls src={preview.video} class="max-h-96 object-contain object-center" />
{/if}
<div class="h-px bg-medium" />
<div class="h-px bg-gray-6" />
{#if preview.title}
<div class="flex flex-col bg-white px-4 py-2 text-black">
<strong class="overflow-hidden text-ellipsis whitespace-nowrap">{preview.title}</strong>
@ -64,7 +64,7 @@
<div
on:click|preventDefault={close}
class="absolute top-0 right-0 m-1 flex h-6 w-6 items-center justify-center
rounded-full border border-solid border-medium bg-white text-black opacity-50 shadow">
rounded-full border border-solid border-gray-6 bg-white text-black opacity-50 shadow">
<i class="fa fa-times" />
</div>
</Anchor>

View File

@ -20,7 +20,7 @@
</script>
<div
class="m-auto flex max-w-sm flex-col gap-4 rounded border border-solid border-medium bg-black p-4">
class="m-auto flex max-w-sm flex-col gap-4 rounded border border-solid border-gray-6 bg-gray-7 p-4">
<canvas class="m-auto rounded" bind:this={canvas} />
<Input value={code}>
<button slot="after" class="fa fa-copy" on:click={copy} />

View File

@ -9,7 +9,7 @@
import pool from "src/agent/pool"
export let relay
export let theme = "dark"
export let theme = "gray-8"
export let removeRelay = null
export let addRelay = null
@ -34,7 +34,7 @@
<div
class={cx(
`bg-${theme}`,
"flex flex-col justify-between gap-3 rounded border border-l-2 border-solid border-medium py-3 px-6 shadow"
"flex flex-col justify-between gap-3 rounded border border-l-2 border-solid border-gray-6 py-3 px-6 shadow"
)}
style={`border-left-color: ${hsl(stringToHue(relay.url))}`}
in:fly={{y: 20}}>
@ -51,25 +51,25 @@
on:mouseover={() => {
showStatus = true
}}
class="h-2 w-2 cursor-pointer rounded-full bg-medium"
class:bg-medium={message === "Not connected"}
class="h-2 w-2 cursor-pointer rounded-full bg-gray-6"
class:bg-gray-6={message === "Not connected"}
class:bg-danger={quality <= 0.3 && message !== "Not connected"}
class:bg-warning={between(0.3, 0.7, quality)}
class:bg-success={quality > 0.7} />
<p
class="hidden text-sm text-light transition-all sm:block"
class="hidden text-sm text-gray-1 transition-all sm:block"
class:opacity-0={!showStatus}
class:opacity-1={showStatus}>
{message}
</p>
</div>
{#if removeRelay}
<button class="flex items-center gap-3 text-light" on:click={() => removeRelay(relay)}>
<button class="flex items-center gap-3 text-gray-1" on:click={() => removeRelay(relay)}>
<i class="fa fa-right-from-bracket" /> Leave
</button>
{/if}
{#if addRelay}
<button class="flex items-center gap-3 text-light" on:click={() => addRelay(relay)}>
<button class="flex items-center gap-3 text-gray-1" on:click={() => addRelay(relay)}>
<i class="fa fa-right-to-bracket" /> Join
</button>
{/if}

View File

@ -8,7 +8,7 @@
<div
class="flex flex-col justify-between gap-3 rounded border border-l-2 border-solid
border-medium py-3 px-6 shadow"
border-gray-6 py-3 px-6 shadow"
style={`border-left-color: ${hsl(stringToHue(relay.url))}`}
in:fly={{y: 20}}>
<div class="flex items-center justify-between gap-2">

View File

@ -6,7 +6,7 @@
const className = cx(
$$props.class,
"rounded bg-light shadow-inset py-2 px-4 pr-10 text-black w-full text-dark",
"rounded text-gray-1 shadow-inset py-2 px-4 pr-10 text-black w-full text-gray-7",
{"pl-10": $$slots.before, "pr-10": $$slots.after}
)
</script>
@ -15,10 +15,10 @@
<select {...$$props} class={className} bind:value>
<slot />
</select>
<div class="absolute top-0 left-0 flex gap-2 px-3 pt-3 text-dark">
<div class="absolute top-0 left-0 flex gap-2 px-3 pt-3 text-gray-7">
<slot name="before" />
</div>
<div class="absolute top-0 right-0 flex gap-2 px-3 pt-3 text-dark">
<div class="absolute top-0 right-0 flex gap-2 px-3 pt-3 text-gray-7">
<slot name="after" />
</div>
</div>

View File

@ -7,11 +7,11 @@
<div>
<div class="inline-block">
<div class="flex cursor-pointer rounded border border-solid border-light">
<div class="flex cursor-pointer rounded border border-solid border-gray-1">
{#each options as option, i}
<div
class={cx("px-4 py-2 transition-all", {
"border-l border-solid border-light": i > 0,
"border-l border-solid border-gray-1": i > 0,
"bg-accent": value === option,
})}
on:click={() => {

View File

@ -8,16 +8,16 @@
export let getDisplay = tab => ({title: toTitle(tab), badge: null})
</script>
<div class="flex overflow-auto border-b border-solid border-dark pt-2" in:fly={{y: 20}}>
<div class="flex overflow-auto border-b border-solid border-gray-7 pt-2" in:fly={{y: 20}}>
{#each tabs as tab}
{@const {title, badge} = getDisplay(tab)}
<button
class="flex cursor-pointer gap-2 border-solid border-medium px-8 py-4 hover:border-b"
class="flex cursor-pointer gap-2 border-solid border-gray-6 px-8 py-4 hover:border-b"
class:border-b={activeTab === tab}
on:click={() => setActiveTab(tab)}>
<div>{title}</div>
{#if badge}
<div class="h-6 rounded-full bg-medium px-2">{badge}</div>
<div class="h-6 rounded-full bg-gray-6 px-2">{badge}</div>
{/if}
</button>
{/each}

View File

@ -8,8 +8,8 @@
const className = cx(
$$props.class,
"rounded bg-light shadow-inset py-2 px-4 pr-10 text-black w-full text-dark",
"placeholder:text-dark placeholder:opacity-75"
"rounded shadow-inset py-2 px-4 pr-10 w-full bg-gray-3 text-gray-8",
"placeholder:text-gray-7 placeholder:opacity-75"
)
</script>

View File

@ -70,8 +70,8 @@
{/if}
</div>
<div class="flex items-center gap-2">
<i class="fa fa-lock-open text-light" />
<span class="text-light">Public</span>
<i class="fa fa-lock-open text-gray-1" />
<span class="text-gray-1">Public</span>
</div>
</div>
<div>{$room.about || ""}</div>
@ -81,7 +81,7 @@
{#if message.showPerson}
<div class="flex items-center justify-between gap-4">
<Badge person={message.person} />
<p class="text-sm text-light">{formatTimestamp(message.created_at)}</p>
<p class="text-sm text-gray-1">{formatTimestamp(message.created_at)}</p>
</div>
{/if}
<div class="my-1 ml-6 overflow-hidden text-ellipsis">

View File

@ -35,7 +35,7 @@
</script>
<Content>
<div class="mt-10 flex justify-between">
<div class="flex justify-between">
<div class="flex items-center gap-2">
<i class="fa fa-server fa-lg" />
<h2 class="staatliches text-2xl">Your rooms</h2>
@ -49,7 +49,7 @@
{:else}
<p class="text-center py-8">You haven't yet joined any rooms.</p>
{/each}
<div class="mb-2 border-b border-solid border-medium pt-2" />
<div class="mb-2 border-b border-solid border-gray-6 pt-2" />
<div class="flex items-center gap-2">
<i class="fa fa-earth-asia fa-lg" />
<h2 class="staatliches text-2xl">Other rooms</h2>

View File

@ -11,7 +11,7 @@
<Content>
{#each flatten($logs) as { created_at, message }}
<div in:fly={{y: 20}} class="flex flex-col gap-2 text-sm">
<div class="text-light underline">
<div class="text-gray-1 underline">
{formatTimestamp(created_at / 1000)}
</div>
<pre>{message.map(m => JSON.stringify(m, null, 2)).join(" ")}</pre>

View File

@ -50,7 +50,7 @@
class="fa-solid fa-copy cursor-pointer"
on:click={() => copyKey("public")} />
</Input>
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
Your public key identifies your account. You can share this with people trying to find you
on nostr.
</p>
@ -64,7 +64,7 @@
class="fa-solid fa-copy cursor-pointer"
on:click={() => copyKey("private")} />
</Input>
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
Your private key is used to prove your identity by cryptographically signing messages. <strong
>Do not share this with anyone.</strong>
Be careful about copying this into other apps - instead, consider using a <Anchor

View File

@ -86,8 +86,8 @@
</Anchor>
</div>
<div class="flex items-center gap-2">
<i class="fa fa-lock text-light" />
<span class="text-light">Encrypted</span>
<i class="fa fa-lock text-gray-1" />
<span class="text-gray-1">Encrypted</span>
</div>
</div>
<div>{$person.kind0?.about || ""}</div>
@ -103,15 +103,15 @@
<div
class={cx("inline-block max-w-xl rounded-2xl py-2 px-4", {
"rounded-br-none bg-white text-end text-black": message.person.pubkey === user.getPubkey(),
"rounded-bl-none bg-dark": message.person.pubkey !== user.getPubkey(),
"rounded-bl-none bg-gray-7": message.person.pubkey !== user.getPubkey(),
})}>
<div class="break-words">
{@html renderNote(message, {showEntire: true})}
</div>
<small
class="mt-1"
class:text-dark={message.person.pubkey === user.getPubkey()}
class:text-light={message.person.pubkey !== user.getPubkey()}>
class:text-gray-7={message.person.pubkey === user.getPubkey()}
class:text-gray-1={message.person.pubkey !== user.getPubkey()}>
{formatTimestamp(message.created_at)}
</small>
</div>

View File

@ -62,8 +62,8 @@
</div>
{#if event.showLine}
<div class="flex items-center gap-4">
<small class="whitespace-nowrap text-light">Older notifications</small>
<div class="h-px w-full bg-medium" />
<small class="whitespace-nowrap text-gray-1">Older notifications</small>
<div class="h-px w-full bg-gray-6" />
</div>
{/if}
{:else}

View File

@ -183,7 +183,7 @@
{#if person.verified_as}
<div class="flex gap-1 text-sm">
<i class="fa fa-user-check text-accent" />
<span class="text-light">{last(person.verified_as.split("@"))}</span>
<span class="text-gray-1">{last(person.verified_as.split("@"))}</span>
</div>
{/if}
</div>
@ -193,7 +193,7 @@
</div>
<div class="absolute top-0 right-0 z-10 mt-12 flex flex-col gap-2 opacity-90">
<div
class="absolute inset-0 rounded-full bg-black"
class="absolute inset-0 rounded-full bg-gray-8"
class:hidden={!showActions}
style="filter: blur(15px)"
transition:fade|local />
@ -203,7 +203,7 @@
in:fly|local={{y: 20, delay: i * 30}}
out:fly|local={{y: 20, delay: (actions.length - i - 1) * 30}}
on:click={onClick}>
<div class="text-light">{label}</div>
<div class="text-gray-1">{label}</div>
<Anchor type="button-circle">
<i class={`fa fa-${icon}`} />
</Anchor>

View File

@ -54,13 +54,13 @@
on:mouseover={() => {
showStatus = true
}}
class="h-2 w-2 cursor-pointer rounded-full bg-medium"
class:bg-medium={message === "Not connected"}
class="h-2 w-2 cursor-pointer rounded-full bg-gray-6"
class:bg-gray-6={message === "Not connected"}
class:bg-danger={quality <= 0.3 && message !== "Not connected"}
class:bg-warning={between(0.3, 0.7, quality)}
class:bg-success={quality > 0.7} />
<p
class="hidden text-sm text-light transition-all sm:block"
class="hidden text-sm text-gray-1 transition-all sm:block"
class:opacity-0={!showStatus}
class:opacity-1={showStatus}>
{message}
@ -95,7 +95,7 @@
<p>{relay.description}</p>
{/if}
</Content>
<div class="border-b border-solid border-medium" />
<div class="border-b border-solid border-gray-6" />
<Content>
<Feed relays={[relay]} filter={{kinds: [1]}} />
</Content>

View File

@ -38,8 +38,8 @@
<RelayCard showControls {relay} />
{/each}
</div>
<div class="flex flex-col gap-6" in:fly={{y: 20, delay: 1000}}>
<div class="mb-2 border-b border-solid border-medium pt-2" />
<div class="flex flex-col gap-6" in:fly={{y: 20}}>
<div class="mb-2 border-b border-solid border-gray-6 pt-2" />
<div class="flex items-center gap-2">
<i class="fa fa-earth-asia fa-lg" />
<h2 class="staatliches text-2xl">Other relays</h2>

View File

@ -71,7 +71,7 @@
<i class="fa fa-camera" />
</Anchor>
</form>
<div class="text-center text-light">
<div class="text-center text-gray-1">
Enter any nostr identifier (npub, nevent, nprofile, note or user@domain.tld), or click on the
camera icon to scan with your device's camera instead.
</div>

View File

@ -53,7 +53,7 @@
<Input type="text" name="name" wrapperClass="flex-grow" bind:value={values.name}>
<i slot="before" class="fa-solid fa-user-astronaut" />
</Input>
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
Your username can be changed at any time. To prevent spoofing, a few characters of your
public key will also be displayed next to your posts.
</p>
@ -63,7 +63,7 @@
<Input type="text" name="name" wrapperClass="flex-grow" bind:value={values.nip05}>
<i slot="before" class="fa-solid fa-user-check" />
</Input>
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
Enter a <Anchor external href={nip05Url}>NIP-05</Anchor> address to verify your public key.
</p>
</div>
@ -72,7 +72,7 @@
<Input type="text" name="name" wrapperClass="flex-grow" bind:value={values.lud16}>
<i slot="before" class="fa-solid fa-bolt" />
</Input>
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
Enter a <Anchor external href={lud16Url}>LUD-16</Anchor> address to enable sending and receiving
lightning tips (LUD-06 will also work).
</p>
@ -80,7 +80,7 @@
<div class="flex flex-col gap-1">
<strong>About you</strong>
<Textarea name="about" bind:value={values.about} />
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
Tell the world about yourself. This will be shown on your profile page.
</p>
</div>
@ -91,12 +91,12 @@
icon="image-portrait"
maxWidth={480}
maxHeight={480} />
<p class="text-sm text-light">Please be mindful of others and only use small images.</p>
<p class="text-sm text-gray-1">Please be mindful of others and only use small images.</p>
</div>
<div class="flex flex-col gap-1">
<strong>Profile Banner</strong>
<ImageInput bind:value={values.banner} icon="panorama" />
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
In most clients, this image will be shown on your profile page.
</p>
</div>

View File

@ -41,7 +41,7 @@
<strong>Show images and link previews</strong>
<Toggle bind:value={values.showMedia} />
</div>
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
If enabled, coracle will automatically retrieve a link preview for the last link in any
note.
</p>
@ -51,7 +51,7 @@
<strong>Default zap amount</strong>
<Input bind:value={values.defaultZap} />
</div>
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
The default amount of sats to use when sending a lightning tip.
</p>
</div>
@ -61,7 +61,7 @@
<div>{values.relayLimit} relays</div>
</div>
<Input type="range" bind:value={values.relayLimit} min={1} max={50} />
<p class="mt-2 text-sm text-light">
<p class="mt-2 text-sm text-gray-1">
This controls how many relays to max out at when loading feeds and event context. More is
faster, but will require more bandwidth and processing power.
</p>
@ -71,7 +71,7 @@
<Input bind:value={values.dufflepudUrl}>
<i slot="before" class="fa-solid fa-server" />
</Input>
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
Enter a custom url for Coracle's helper application. Dufflepud is used for hosting images
and loading link previews.
</p>
@ -81,7 +81,7 @@
<strong>Report errors and analytics</strong>
<Toggle bind:value={values.reportAnalytics} />
</div>
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
Keep this enabled if you would like the Coracle developers to be able to know what
features are used, and to diagnose and fix bugs.
</p>

View File

@ -25,8 +25,8 @@
</script>
<ul
class="fixed top-0 bottom-0 left-0 z-20 mt-16 w-56 overflow-hidden border-r border-medium bg-dark pt-4
pb-20 text-white shadow-xl transition-all lg:mt-0 lg:ml-0"
class="fixed top-0 bottom-0 left-0 z-20 mt-16 w-56 overflow-hidden border-r border-gray-6 bg-gray-7 pt-4
pb-20 text-gray-3 shadow-xl transition-all lg:mt-0 lg:ml-0"
class:-ml-56={!$menuIsOpen}>
{#if $profile.pubkey}
<li>
@ -36,7 +36,9 @@
</a>
</li>
<li class="relative cursor-pointer">
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/notifications">
<a
class="block px-4 py-2 transition-all hover:bg-accent hover:text-white"
href="/notifications">
<i class="fa fa-bell mr-2" /> Notifications
{#if $newNotifications}
<div class="absolute top-3 left-6 h-2 w-2 rounded bg-accent" />
@ -45,17 +47,19 @@
</li>
{/if}
<li class="cursor-pointer">
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/notes/follows">
<a
class="block px-4 py-2 transition-all hover:bg-accent hover:text-white"
href="/notes/follows">
<i class="fa fa-rss mr-2" /> Feed
</a>
</li>
<li class="cursor-pointer">
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/search">
<a class="block px-4 py-2 transition-all hover:bg-accent hover:text-white" href="/search">
<i class="fa fa-search mr-2" /> Search
</a>
</li>
<li class="cursor-pointer">
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/scan">
<a class="block px-4 py-2 transition-all hover:bg-accent hover:text-white" href="/scan">
<i class="fa fa-qrcode mr-2" /> Scan
</a>
</li>
@ -64,7 +68,7 @@
"cursor-pointer": $canPublish,
"pointer-events-none opacity-75": !$canPublish,
})}>
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/messages">
<a class="block px-4 py-2 transition-all hover:bg-accent hover:text-white" href="/messages">
<i class="fa fa-envelope mr-2" /> Messages
{#if $newDirectMessages}
<div class="absolute top-2 left-7 h-2 w-2 rounded bg-accent" />
@ -76,16 +80,16 @@
"cursor-pointer": $canPublish,
"pointer-events-none opacity-75": !$canPublish,
})}>
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/chat">
<a class="block px-4 py-2 transition-all hover:bg-accent hover:text-white" href="/chat">
<i class="fa fa-comment mr-2" /> Chat
{#if $newChatMessages}
<div class="absolute top-2 left-7 h-2 w-2 rounded bg-accent" />
{/if}
</a>
</li>
<li class="mx-3 my-4 h-px bg-medium" />
<li class="mx-3 my-4 h-px bg-gray-6" />
<li class="relative cursor-pointer">
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/relays">
<a class="block px-4 py-2 transition-all hover:bg-accent hover:text-white" href="/relays">
<i class="fa fa-server mr-2" /> Relays
{#if $slowConnections.length > 0}
<div class="absolute top-2 left-8 h-2 w-2 rounded bg-accent" />
@ -94,36 +98,38 @@
</li>
{#if $profile.pubkey}
<li class="cursor-pointer">
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/keys">
<a class="block px-4 py-2 transition-all hover:bg-accent hover:text-white" href="/keys">
<i class="fa fa-key mr-2" /> Keys
</a>
</li>
<li class="cursor-pointer">
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/settings">
<a class="block px-4 py-2 transition-all hover:bg-accent hover:text-white" href="/settings">
<i class="fa fa-gear mr-2" /> Settings
</a>
</li>
<li class="cursor-pointer">
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/logout">
<a class="block px-4 py-2 transition-all hover:bg-accent hover:text-white" href="/logout">
<i class="fa fa-right-from-bracket mr-2" /> Logout
</a>
</li>
{:else}
<li class="cursor-pointer">
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/login">
<a class="block px-4 py-2 transition-all hover:bg-accent hover:text-white" href="/login">
<i class="fa fa-right-to-bracket mr-2" /> Login
</a>
</li>
{/if}
{#if import.meta.env.VITE_SHOW_DEBUG_ROUTE === "true"}
<li class="cursor-pointer">
<a class="block px-4 py-2 transition-all hover:bg-accent" href="/debug">
<a class="block px-4 py-2 transition-all hover:bg-accent hover:text-white" href="/debug">
<i class="fa fa-bug mr-2" /> Debug
</a>
</li>
{/if}
{#if $installPrompt}
<li class="cursor-pointer px-4 py-2 transition-all hover:bg-accent" on:click={install}>
<li
class="cursor-pointer px-4 py-2 transition-all hover:bg-accent hover:text-white"
on:click={install}>
<i class="fa fa-rocket mr-2" /> Install
</li>
{/if}

View File

@ -15,9 +15,9 @@
"pointer-events-auto m-2 ml-16 rounded border p-3 text-center shadow-xl sm:ml-2",
"max-w-xl flex-grow transition-all",
{
"border-medium bg-dark text-white": $toast.type === "info",
"border-warning bg-dark text-white": $toast.type === "warning",
"border-danger bg-dark text-white": $toast.type === "error",
"border-gray-6 bg-gray-7 text-gray-3": $toast.type === "info",
"border-warning bg-gray-7 text-gray-3": $toast.type === "warning",
"border-danger bg-gray-7 text-gray-3": $toast.type === "error",
}
)}>
{#if is(String, $toast.message)}

View File

@ -3,8 +3,10 @@
import Anchor from "src/partials/Anchor.svelte"
import {menuIsOpen} from "src/app/ui"
import {newNotifications} from "src/app/listener"
import {theme} from "src/app/ui"
const toggleMenu = () => menuIsOpen.update(x => !x)
const toggleTheme = () => theme.update(t => (t === "dark" ? "light" : "dark"))
onMount(() => {
document.querySelector("html").addEventListener("click", e => {
@ -17,16 +19,15 @@
<div
class="fixed top-0 z-10 flex h-16 w-full items-center justify-between border-b
border-medium bg-dark p-4 text-white">
border-gray-6 bg-gray-7 p-4 text-gray-3">
<div class="fa fa-bars fa-2xl cursor-pointer lg:hidden" on:click={toggleMenu} />
<Anchor
external
type="unstyled"
href="https://github.com/staab/coracle"
class="flex items-center gap-2">
<img alt="Coracle Logo" src="/images/logo.png" class="w-8" />
<h1 class="staatliches text-3xl">Coracle</h1>
</Anchor>
<div class="flex items-center gap-4">
<Anchor external type="unstyled" href="https://coracle.social" class="flex items-center gap-2">
<img alt="Coracle Logo" src="/images/logo.png" class="w-8" />
<h1 class="staatliches text-3xl">Coracle</h1>
</Anchor>
<i class="fa fa-lightbulb cursor-pointer text-lg" on:click={toggleTheme} />
</div>
{#if $newNotifications}
<div class="absolute top-4 left-12 h-2 w-2 rounded bg-accent lg:hidden" />
{/if}

View File

@ -64,19 +64,19 @@
<Input type="text" name="name" wrapperClass="flex-grow" bind:value={room.name}>
<i slot="before" class="fa-solid fa-tag" />
</Input>
<p class="text-sm text-light">The room's name can be changed anytime.</p>
<p class="text-sm text-gray-1">The room's name can be changed anytime.</p>
</div>
<div class="flex flex-col gap-1">
<strong>Room information</strong>
<Textarea name="about" bind:value={room.about} />
<p class="text-sm text-light">
<p class="text-sm text-gray-1">
Give people an idea of what kind of conversations will be happening here.
</p>
</div>
<div class="flex flex-col gap-1">
<strong>Picture</strong>
<input type="file" name="picture" />
<p class="text-sm text-light">A picture to help people remember your room.</p>
<p class="text-sm text-gray-1">A picture to help people remember your room.</p>
</div>
<Button type="submit" class="text-center">Done</Button>
</div>

View File

@ -14,7 +14,7 @@
</script>
<button
class="flex cursor-pointer gap-4 rounded border border-solid border-medium bg-dark px-4 py-6 transition-all hover:bg-medium"
class="flex cursor-pointer gap-4 rounded border border-solid border-gray-6 bg-gray-7 px-4 py-6 transition-all hover:bg-gray-6"
on:click={enter}
in:fly={{y: 20}}>
<div
@ -23,7 +23,7 @@
<div class="flex min-w-0 flex-grow flex-col justify-start gap-2">
<div class="flex flex-grow items-start justify-between gap-2">
<div class="flex items-center gap-2 overflow-hidden">
<i class="fa fa-lock-open text-light" />
<i class="fa fa-lock-open text-gray-1" />
<h2 class="text-lg">{room.name || ""}</h2>
</div>
{#if room.joined}
@ -51,7 +51,7 @@
{/if}
</div>
{#if room.about}
<p class="text-start text-light">
<p class="text-start text-gray-1">
{ellipsize(room.about, 300)}
</p>
{/if}

View File

@ -121,8 +121,9 @@
<div class="pointer-events-none fixed left-0 top-0 z-10 mt-20 flex w-full justify-center">
<button
in:fly={{y: 20}}
class="pointer-events-auto cursor-pointer rounded-full border border-solid border-accentl
bg-accent py-2 px-4 text-center shadow-lg transition-colors hover:bg-accentl"
class="pointer-events-auto cursor-pointer rounded-full border border-solid
border-accent-light bg-accent py-2 px-4 text-center text-white
shadow-lg transition-colors hover:bg-accent-light"
on:click={loadBufferedNotes}>
Load {quantify(notesBuffer.length, "new note")}
</button>

View File

@ -37,7 +37,7 @@
</div>
<Anchor type="button" on:click={logIn}>Log In</Anchor>
</div>
<p class="rounded border-2 border-solid border-warning bg-black py-3 px-6">
<p class="rounded border-2 border-solid border-warning bg-gray-8 py-3 px-6">
Note that sharing your private key directly is not recommended, instead you should use a <Anchor
href={nip07}
external>compatible browser extension</Anchor> to securely store your key.

View File

@ -1,12 +1,12 @@
<script>
import {nip19} from "nostr-tools"
import {navigate} from "svelte-routing"
import {fly} from "svelte/transition"
import {ellipsize} from "hurdak/lib/hurdak"
import {displayPerson} from "src/util/nostr"
import {getPersonWithFallback} from "src/agent/tables"
import {lastChecked} from "src/app/listener"
import PersonCircle from "src/partials/PersonCircle.svelte"
import Card from "src/partials/Card.svelte"
export let contact
@ -15,29 +15,27 @@
const enter = () => navigate(`/messages/${nip19.npubEncode(contact.pubkey)}`)
</script>
<button
class="flex cursor-pointer gap-4 rounded border border-solid border-medium bg-dark
px-4 py-6 transition-all hover:bg-medium"
on:click={enter}
in:fly={{y: 20}}>
<PersonCircle size={14} {person} />
<div class="flex min-w-0 flex-grow flex-col justify-start gap-2">
<div class="flex flex-grow items-start justify-between gap-2">
<div class="flex items-center gap-2 overflow-hidden">
<i class="fa fa-lock text-light" />
<h2 class="text-lg">{displayPerson(person)}</h2>
</div>
<div class="relative">
<i class="fa fa-bell" class:text-light={!newMessages} />
{#if newMessages}
<div class="absolute top-0 right-0 mt-1 h-1 w-1 rounded-full bg-accent" />
{/if}
<Card interactive on:click={enter}>
<div class="flex gap-4 px-4 py-6">
<PersonCircle size={14} {person} />
<div class="flex min-w-0 flex-grow flex-col justify-start gap-2">
<div class="flex flex-grow items-start justify-between gap-2">
<div class="flex items-center gap-2 overflow-hidden">
<i class="fa fa-lock text-gray-1" />
<h2 class="text-lg">{displayPerson(person)}</h2>
</div>
<div class="relative">
<i class="fa fa-bell" class:text-gray-5={!newMessages} />
{#if newMessages}
<div class="absolute top-0 right-0 mt-1 h-1 w-1 rounded-full bg-accent" />
{/if}
</div>
</div>
{#if person.kind0?.about}
<p class="text-start text-gray-1">
{ellipsize(person.kind0.about, 300)}
</p>
{/if}
</div>
{#if person.kind0?.about}
<p class="text-start text-light">
{ellipsize(person.kind0.about, 300)}
</p>
{/if}
</div>
</button>
</Card>

View File

@ -11,7 +11,8 @@
<div class="fixed bottom-0 right-0 m-8">
<button
class="color-white flex h-16 w-16 items-center justify-center rounded-full
border border-dark bg-accent shadow-2xl"
border border-accent-light bg-accent text-white shadow-2xl
transition-all hover:bg-accent-light"
on:click={() => modal.set({type: "note/create", pubkey})}>
<span class="fa-sold fa-plus fa-2xl" />
</button>

View File

@ -56,7 +56,7 @@
const {profile, canPublish, mutes} = user
const timestamp = formatTimestamp(note.created_at)
const borderColor = invertColors ? "medium" : "dark"
const borderColor = invertColors ? "gray-6" : "gray-7"
const links = extractUrls(note.content)
const showEntire = anchorId === note.id
const interactive = !anchorId || !showEntire
@ -367,7 +367,7 @@
</Popover>
<Anchor
href={"/" + nip19.neventEncode({id: note.id, relays: [note.seen_on]})}
class="text-sm text-light"
class="text-sm text-gray-1"
type="unstyled">
{timestamp}
</Anchor>
@ -375,25 +375,25 @@
<div class="flex flex-col gap-2">
<div class="flex gap-2">
{#if findReplyId(note) && showParent}
<small class="text-light">
<small class="text-gray-1">
<i class="fa fa-code-merge" />
<Anchor on:click={goToParent}>View Parent</Anchor>
</small>
{/if}
{#if findRootId(note) && findRootId(note) !== findReplyId(note) && showParent}
<small class="text-light">
<small class="text-gray-1">
<i class="fa fa-code-pull-request" />
<Anchor on:click={goToRoot}>View Thread</Anchor>
</small>
{/if}
</div>
{#if flag}
<p class="border-l-2 border-solid border-medium pl-4 text-light">
<p class="border-l-2 border-solid border-gray-6 pl-4 text-gray-1">
You have flagged this content as offensive.
<Anchor on:click={() => deleteReaction(flag)}>Unflag</Anchor>
</p>
{:else if muted}
<p class="border-l-2 border-solid border-medium pl-4 text-light">
<p class="border-l-2 border-solid border-gray-6 pl-4 text-gray-1">
You have muted this note.
</p>
{:else}
@ -406,7 +406,7 @@
{/if}
</div>
{/if}
<div class="flex justify-between text-light">
<div class="flex justify-between text-gray-1">
<div
class={cx("flex", {
"pointer-events-none opacity-75": !$canPublish || flag || muted,
@ -478,19 +478,22 @@
transition:slide
class={`note-reply relative z-10 border border-${borderColor} rounded border-solid`}
bind:this={replyContainer}>
<div class="bg-dark" class:rounded-b={replyMentions.length === 0} on:keydown={onReplyKeydown}>
<div
class="bg-gray-7"
class:rounded-b={replyMentions.length === 0}
on:keydown={onReplyKeydown}>
<Compose bind:this={reply} onSubmit={sendReply}>
<button
slot="addon"
on:click={sendReply}
class="flex cursor-pointer flex-col justify-center gap-2 border-l border-solid border-dark p-4
py-8 text-white transition-all hover:bg-accent">
class="flex cursor-pointer flex-col justify-center gap-2 border-l border-solid border-gray-7 p-4
py-8 text-gray-3 transition-all hover:bg-accent">
<i class="fa fa-paper-plane fa-xl" />
</button>
</Compose>
</div>
{#if image}
<div class="bg-dark p-2">
<div class="bg-gray-7 p-2">
<Preview
url={image}
onClose={() => {
@ -499,8 +502,8 @@
</div>
{/if}
<div class={`h-px bg-${borderColor}`} />
<div class="h-12 rounded-b bg-black p-2 text-sm text-white">
<div class="mr-2 inline-block border-r border-solid border-medium py-2 pl-1 pr-3">
<div class="h-12 rounded-b bg-gray-7 p-2 text-sm text-gray-3">
<div class="mr-2 inline-block border-r border-solid border-gray-6 py-2 pl-1 pr-3">
<div class="flex cursor-pointer items-center gap-3">
<ImageInput bind:value={image} icon="image" hideInput>
<i slot="button" class="fa fa-paperclip" />
@ -509,14 +512,14 @@
</div>
</div>
{#each replyMentions as p}
<div class="mr-1 inline-block rounded-full border border-solid border-light py-1 px-2">
<div class="mr-1 inline-block rounded-full border border-solid border-gray-1 py-1 px-2">
<button
class="fa fa-times cursor-pointer"
on:click|stopPropagation={() => removeMention(p)} />
{displayPerson(getPersonWithFallback(p))}
</div>
{:else}
<div class="text-light inline-block">No mentions</div>
<div class="text-gray-1 inline-block">No mentions</div>
{/each}
<div class="-mt-2" />
</div>
@ -528,7 +531,7 @@
<div class={`absolute w-px bg-${borderColor} z-10 -mt-4 ml-4 h-0`} bind:this={border} />
<div class="note-children relative ml-8 flex flex-col gap-4" bind:this={childrenContainer}>
{#if !showEntire && note.replies.length > visibleNotes.length}
<button class="ml-5 cursor-pointer py-2 text-light" on:click={onClick}>
<button class="ml-5 cursor-pointer py-2 text-gray-1" on:click={onClick}>
<i class="fa fa-up-down pr-2 text-sm" />
Show {quantify(
note.replies.length - visibleNotes.length,
@ -571,7 +574,7 @@
</div>
{#if zap.invoice}
<QRCode code={zap.invoice} />
<div class="text-center text-light">
<div class="text-center text-gray-1">
Copy or scan using a lightning wallet to pay your zap.
</div>
{:else}

View File

@ -106,7 +106,7 @@
<div class="flex w-full flex-col gap-4">
<div class="flex flex-col gap-2">
<strong>What do you want to say?</strong>
<div class="border-l-2 border-solid border-medium pl-4">
<div class="border-l-2 border-solid border-gray-6 pl-4">
<Compose bind:this={input} {onSubmit} />
</div>
</div>
@ -144,7 +144,7 @@
<div>
{#each relays as relay}
<div
class="mr-1 mb-2 inline-block rounded-full border border-solid border-light py-1 px-2">
class="mr-1 mb-2 inline-block rounded-full border border-solid border-gray-1 py-1 px-2">
<button
type="button"
class="fa fa-times cursor-pointer"

View File

@ -4,6 +4,7 @@
import {formatTimestamp, tryJson} from "src/util/misc"
import {Tags} from "src/util/nostr"
import Badge from "src/partials/Badge.svelte"
import Card from "src/partials/Card.svelte"
import Popover from "src/partials/Popover.svelte"
import NotificationSection from "src/views/notifications/NotificationSection.svelte"
import {getPersonWithFallback, userEvents} from "src/agent/tables"
@ -38,9 +39,9 @@
</script>
{#if note}
<button
class="flex w-full cursor-pointer flex-col gap-2 border border-solid border-black py-2
px-3 text-left text-white transition-all hover:border-medium hover:bg-dark"
<Card
interactive
class="flex flex-col gap-2 text-left"
on:click={() => modal.set({type: "note/detail", note})}>
<div class="relative flex w-full items-center justify-between gap-2" on:click|stopPropagation>
{#if !event.ref}
@ -66,10 +67,10 @@
</div>
</Popover>
{/if}
<p class="text-sm text-light">{formatTimestamp(timestamp)}</p>
<p class="text-sm text-gray-1">{formatTimestamp(timestamp)}</p>
</div>
<div class="ml-6 break-all text-light">
<div class="ml-6 break-all text-gray-1">
{ellipsize(note.content, 120)}
</div>
</button>
</Card>
{/if}

View File

@ -139,7 +139,7 @@
<div>
<div class="mb-2 text-lg">NIP05 Relay Configuration</div>
{#if nip05ProfileData?.relays?.length}
<p class="mb-4 text-sm text-light">
<p class="mb-4 text-sm text-gray-1">
These relays are advertised by the NIP05 identifier's validation endpoint.
</p>
@ -149,7 +149,7 @@
{/each}
</div>
{:else}
<p class="mb-4 text-sm text-light">
<p class="mb-4 text-sm text-gray-1">
<i class="fa-solid fa-info-circle" />
No relays are advertised by the NIP05 identifier's validation endpoint.
</p>
@ -162,7 +162,7 @@
</p>
{/if}
{:else}
<p class="mb-4 text-sm text-light">
<p class="mb-4 text-sm text-gray-1">
<i class="fa-solid fa-info-circle" />
NIP05 identifier not available.
</p>

View File

@ -14,5 +14,5 @@
<Content size="lg">
<QRCode code={nprofile} />
<div class="text-center text-light">Copy or scan from a nostr app to share this profile.</div>
<div class="text-center text-gray-1">Copy or scan from a nostr app to share this profile.</div>
</Content>

View File

@ -45,7 +45,7 @@
{#if $person.verified_as}
<div class="flex gap-1 text-sm">
<i class="fa fa-user-check text-accent" />
<span class="text-light">{last($person.verified_as.split("@"))}</span>
<span class="text-gray-1">{last($person.verified_as.split("@"))}</span>
</div>
{/if}
</div>

View File

@ -49,7 +49,7 @@
<Input autofocus bind:value={url} placeholder="wss://relay.example.com">
<i slot="before" class="fa-solid fa-link" />
</Input>
<p class="text-sm text-light">The url where the relay is hosted.</p>
<p class="text-sm text-gray-1">The url where the relay is hosted.</p>
</div>
<Button type="submit" class="text-center">Done</Button>
</div>

View File

@ -10,7 +10,7 @@
import {loadAppData} from "src/app"
export let relay
export let theme = "dark"
export let theme = "gray-8"
export let showControls = false
let quality = null
@ -52,12 +52,13 @@
{theme}
addRelay={!joined && !isPubkeyLogin ? addRelay : null}
removeRelay={joined && $relays.length > 1 && !isPubkeyLogin ? removeRelay : null}>
<div slot="controls" class="flex justify-between gap-2">
{#if showControls && $canPublish}
<span>Publish to this relay?</span>
<Toggle
value={relay.write}
on:change={() => user.setRelayWriteCondition(relay.url, !relay.write)} />
{/if}
<div
slot="controls"
class="flex justify-between gap-2"
class:hidden={!showControls || !$canPublish}>
<span>Publish to this relay?</span>
<Toggle
value={relay.write}
on:change={() => user.setRelayWriteCondition(relay.url, !relay.write)} />
</div>
</RelayCard>

View File

@ -1,29 +1,30 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./index.html",
"./src/**/*.{js,svelte}",
],
safelist: [
"w-4",
"h-4",
],
content: ["./index.html", "./src/**/*.{js,svelte}"],
safelist: ["w-4", "h-4"],
theme: {
extend: {},
colors: {
transparent: "transparent",
black: "#0f0f0e",
white: "#FFFCF2",
accent: "#EB5E28",
accentl: "#EE7648",
light: "#CCC5B9",
shimmer: "#544e46",
medium: "#403D39",
dark: "#252422",
danger: "#ff0000",
warning: "#ebd112",
success: "#37ab51",
placeholder: "#a19989",
transparent: "var(--transparent)",
black: "var(--black)",
white: "var(--white)",
accent: "var(--accent)",
"accent-light": "var(--accent-light)",
input: "var(--input)",
"input-hover": "var(--input-hover)",
"gray-0": "var(--gray-0)",
"gray-1": "var(--gray-1)",
"gray-2": "var(--gray-2)",
"gray-3": "var(--gray-3)",
"gray-4": "var(--gray-4)",
"gray-5": "var(--gray-5)",
"gray-6": "var(--gray-6)",
"gray-7": "var(--gray-7)",
"gray-8": "var(--gray-8)",
"gray-9": "var(--gray-9)",
danger: "var(--danger)",
warning: "var(--warning)",
success: "var(--success)",
},
},
plugins: [],