diff --git a/src/app/components/ChatMessage.svelte b/src/app/components/ChatMessage.svelte
index e205ef51..7e5e481b 100644
--- a/src/app/components/ChatMessage.svelte
+++ b/src/app/components/ChatMessage.svelte
@@ -1,6 +1,6 @@
{#if $relay?.icon}
{:else}
-
+
+ {relayIconInitials(url)}
+
{/if}
diff --git a/src/app/components/RelaySummary.svelte b/src/app/components/RelaySummary.svelte
index cfb612fd..d7ecdc0a 100644
--- a/src/app/components/RelaySummary.svelte
+++ b/src/app/components/RelaySummary.svelte
@@ -26,7 +26,7 @@
{#if !hideFavorites && $userSpaceUrls.includes(url)}
diff --git a/src/app/components/RoomItem.svelte b/src/app/components/RoomItem.svelte
index 8eddd2ad..dcddb134 100644
--- a/src/app/components/RoomItem.svelte
+++ b/src/app/components/RoomItem.svelte
@@ -2,7 +2,6 @@
import cx from "classnames"
import {readable} from "svelte/store"
import {
- hash,
gte,
now,
uniq,
@@ -40,7 +39,7 @@
import RoomItemContent from "@app/components/RoomItemContent.svelte"
import {profiles, thunks, user} from "@app/core"
import {noThunks, thunksByEventId} from "@app/thunks"
- import {colors} from "@app/theme"
+ import {colorFor} from "@app/theme"
import {ENABLE_ZAPS} from "@app/env"
import type {FeedContext} from "@app/feeds"
import {deriveEvent, deriveEventsForUrl} from "@app/repository"
@@ -71,7 +70,7 @@
const today = formatTimestampAsDate(now())
const profileDisplay = $profiles.display(event.pubkey, [url]).$
const thunk = $derived($thunks.merge($thunksByEventId.get(event.id) ?? noThunks))
- const [_, colorValue] = colors[hash(event.pubkey) % colors.length]
+ const colorValue = colorFor(event.pubkey)
const qTag = matchTag(tagSpec("q"), event.tags)
const isQuoteOnly = Boolean(
diff --git a/src/app/relays.ts b/src/app/relays.ts
index 33ce7840..7a4f0047 100644
--- a/src/app/relays.ts
+++ b/src/app/relays.ts
@@ -6,6 +6,7 @@ import {throttled} from "@welshman/store"
import {checkRelayHasLivekit} from "$lib/livekit"
import {app} from "@app/core"
import {relaysMostlyRestricted} from "@app/policies"
+import {colorFor} from "@app/theme"
export const encodeRelay = (url: string) =>
encodeURIComponent(
@@ -16,6 +17,23 @@ export const encodeRelay = (url: string) =>
export const decodeRelay = (url: string) => normalizeRelayUrl(decodeURIComponent(url))
+const relayIconHost = (url: string) =>
+ normalizeRelayUrl(url)
+ .replace(/^wss?:\/\//, "")
+ .replace(/[:/].*$/, "")
+
+// Darkened so white initials clear 4.5:1 on every color in the palette.
+export const relayIconColor = (url: string) =>
+ `color-mix(in oklab, ${colorFor(relayIconHost(url))} 80%, black)`
+
+export const relayIconInitials = (url: string) => {
+ const parts = relayIconHost(url).split(".")
+ const hasSubdomain = parts.length > 2
+ const [first = "", second = ""] = parts
+
+ return (hasSubdomain ? first.slice(0, 1) + second.slice(0, 1) : first.slice(0, 2)).toUpperCase()
+}
+
export const deriveSocket = (url: string) => {
const socket = app.get().pool.get(url)
diff --git a/src/app/theme.ts b/src/app/theme.ts
index a1bd5b1d..745b98e8 100644
--- a/src/app/theme.ts
+++ b/src/app/theme.ts
@@ -1,31 +1,34 @@
import twColors from "tailwindcss/colors"
import {derived, readable} from "svelte/store"
+import {hash} from "@welshman/lib"
import {synced} from "@welshman/store"
import {FL_THEME} from "@app/env"
import {kv} from "@app/storage"
-export const colors = [
- ["amber", twColors.amber[600]],
- ["blue", twColors.blue[600]],
- ["cyan", twColors.cyan[600]],
- ["emerald", twColors.emerald[600]],
- ["fuchsia", twColors.fuchsia[600]],
- ["green", twColors.green[600]],
- ["indigo", twColors.indigo[600]],
- ["sky", twColors.sky[600]],
- ["lime", twColors.lime[600]],
- ["orange", twColors.orange[600]],
- ["pink", twColors.pink[600]],
- ["purple", twColors.purple[600]],
- ["red", twColors.red[600]],
- ["rose", twColors.rose[600]],
- ["sky", twColors.sky[600]],
- ["teal", twColors.teal[600]],
- ["violet", twColors.violet[600]],
- ["yellow", twColors.yellow[600]],
- ["zinc", twColors.zinc[600]],
+const colors = [
+ twColors.amber[600],
+ twColors.blue[600],
+ twColors.cyan[600],
+ twColors.emerald[600],
+ twColors.fuchsia[600],
+ twColors.green[600],
+ twColors.indigo[600],
+ twColors.sky[600],
+ twColors.lime[600],
+ twColors.orange[600],
+ twColors.pink[600],
+ twColors.purple[600],
+ twColors.red[600],
+ twColors.rose[600],
+ twColors.sky[600],
+ twColors.teal[600],
+ twColors.violet[600],
+ twColors.yellow[600],
+ twColors.zinc[600],
]
+export const colorFor = (value: string) => colors[hash(value) % colors.length]
+
// Every theme with token values in lib/components/theme.css
export const flThemes = ["clay", "flat", "navy"]
diff --git a/src/routes/spaces/[relay]/about/+page.svelte b/src/routes/spaces/[relay]/about/+page.svelte
index 76ce8ec1..2328eb52 100644
--- a/src/routes/spaces/[relay]/about/+page.svelte
+++ b/src/routes/spaces/[relay]/about/+page.svelte
@@ -31,7 +31,7 @@