diff --git a/src/app.css b/src/app.css
index cce895bd..25e6d2eb 100644
--- a/src/app.css
+++ b/src/app.css
@@ -42,36 +42,6 @@
font-family: Lato;
}
-[data-theme="dark"] {
- --stark: #111;
- --stark-content: #eee;
-}
-
-[data-theme="light"] {
- --stark: #eee;
- --stark-content: #111;
-}
-
-.text-stark,
-.hover\:text-stark:hover {
- color: var(--stark);
-}
-
-.text-stark-content,
-.hover\:text-stark-content:hover {
- color: var(--stark-content);
-}
-
-.bg-stark,
-.hover\:bg-stark:hover {
- background-color: var(--stark);
-}
-
-.bg-stark-content,
-.hover\:bg-stark-content:hover {
- background-color: var(--stark-content);
-}
-
.card2 {
padding: 1rem;
background-color: oklch(var(--b2) / 1);
@@ -87,19 +57,19 @@
}
.content {
- @apply max-w-2xl w-full p-12 m-auto;
+ @apply max-w-3xl w-full p-12 m-auto;
}
.heading {
- @apply text-2xl text-stark-content text-center;
+ @apply text-2xl text-center;
}
.subheading {
- @apply text-xl text-stark-content text-center;
+ @apply text-xl text-center;
}
.superheading {
- @apply text-4xl text-stark-content text-center;
+ @apply text-4xl text-center;
}
.link {
diff --git a/src/app/commands.ts b/src/app/commands.ts
new file mode 100644
index 00000000..c3f00d5f
--- /dev/null
+++ b/src/app/commands.ts
@@ -0,0 +1,73 @@
+import {goto} from '$app/navigation'
+import {append, uniqBy, now} from '@welshman/lib'
+import {GROUPS, asDecryptedEvent, readList, editList, makeList, createList} from "@welshman/util"
+import {pushToast} from '@app/toast'
+import {pk, signer, repository, INDEXER_RELAYS} from '@app/base'
+import {splitGroupId, loadRelay, loadGroup, getWriteRelayUrls, loadRelaySelections, publish, ensurePlaintext} from '@app/state'
+
+export type ModifyTags = (tags: string[][]) => string[][]
+
+export const updateList = async (kind: number, modifyTags: ModifyTags) => {
+ const $pk = pk.get()!
+ const $signer = signer.get()!
+ const [prev] = repository.query([{kinds: [kind], authors: [$pk]}])
+
+ // Preserve content instead of use encrypted tags because kind 3 content is used for
+ // relay selections in many places. Content isn't supported for mutes or relays so this is ok
+ const relays = [...INDEXER_RELAYS, ...getWriteRelayUrls(await loadRelaySelections($pk))]
+ const encrypt = (content: string) => $signer.nip44.encrypt($pk, content)
+
+ let encryptable
+ if (prev) {
+ const content = await ensurePlaintext(prev)
+ const list = readList(asDecryptedEvent(prev, {content}))
+ const publicTags = modifyTags(list.publicTags)
+
+ encryptable = editList({...list, publicTags})
+ } else {
+ const list = makeList({kind})
+ const publicTags = modifyTags(list.publicTags)
+
+ encryptable = createList({...list, publicTags})
+ }
+
+ const template = await encryptable.reconcile(encrypt)
+ const event = await $signer.sign({...template, created_at: now()})
+
+ await publish({event, relays})
+}
+
+export const joinGroup = async (id: string) => {
+ const [url, nom] = splitGroupId(id)
+ const relay = await loadRelay(url)
+
+ if (!relay) {
+ return pushToast({
+ theme: "error",
+ message: "Sorry, we weren't able to find that relay."
+ })
+ }
+
+ if (!relay.supported_nips?.includes(29)) {
+ return pushToast({
+ theme: "error",
+ message: "Sorry, it looks like that relay doesn't support nostr spaces."
+ })
+ }
+
+ const group = await loadGroup(nom, [url])
+
+ if (!group) {
+ return pushToast({
+ theme: "error",
+ message: "Sorry, we weren't able to find that space."
+ })
+ }
+
+ await updateList(GROUPS, (tags: string[][]) => uniqBy(t => t.join(''), append(["group", nom, url], tags)))
+
+ goto(`/spaces/${nom}`)
+ pushToast({
+ message: "Welcome to the space!"
+ })
+}
diff --git a/src/app/components/PrimaryNav.svelte b/src/app/components/PrimaryNav.svelte
index 1ff12717..94439d17 100644
--- a/src/app/components/PrimaryNav.svelte
+++ b/src/app/components/PrimaryNav.svelte
@@ -52,7 +52,7 @@
-
+
{#if $userProfile?.picture}

diff --git a/src/app/components/SecondaryNav.svelte b/src/app/components/SecondaryNav.svelte
index 433bf619..b66c9f1d 100644
--- a/src/app/components/SecondaryNav.svelte
+++ b/src/app/components/SecondaryNav.svelte
@@ -40,10 +40,10 @@
+ class="flex items-center justify-between px-4 py-2 text-sm font-bold uppercase">
Conversations
-
+
{/if}
diff --git a/src/app/components/SpaceJoin.svelte b/src/app/components/SpaceJoin.svelte
index da02e8f9..ab296f94 100644
--- a/src/app/components/SpaceJoin.svelte
+++ b/src/app/components/SpaceJoin.svelte
@@ -10,59 +10,24 @@
import SpaceCreateFinish from '@app/components/SpaceCreateFinish.svelte'
import {pushModal} from '@app/modal'
import {pushToast} from '@app/toast'
- import {GROUP_DELIMITER, splitGroupId, loadRelay, loadGroup, updateList} from '@app/state'
+ import {GROUP_DELIMITER, splitGroupId, loadRelay, loadGroup} from '@app/state'
+ import {joinGroup} from '@app/commands'
const back = () => history.back()
const browse = () => goto("/browse", {state: {}})
- const tryJoin = async () => {
- const [url, nom] = splitGroupId(id)
-
- const info = await loadRelay(url)
-
- if (!info) {
- return pushToast({
- theme: "error",
- message: "Sorry, we weren't able to find that relay."
- })
- }
-
- if (!info.supported_nips?.includes(29)) {
- return pushToast({
- theme: "error",
- message: "Sorry, it looks like that relay doesn't support nostr spaces."
- })
- }
-
- const group = await loadGroup(nom, [url])
-
- if (!group) {
- return pushToast({
- theme: "error",
- message: "Sorry, we weren't able to find that space."
- })
- }
-
- await updateList(GROUPS, (tags: string[][]) => uniqBy(t => t.join(''), append(["group", nom, url], tags)))
-
- goto(`/spaces/${nom}`)
- pushToast({
- message: "Welcome to the space!"
- })
- }
-
const join = async () => {
loading = true
try {
- await tryJoin()
+ await joinGroup(id)
} finally {
loading = false
}
}
- let id = "wss://devrelay.highlighter.com'group628195"
+ let id = ""
let loading = false
$: linkIsValid = Boolean(id.match(/.+\..+'.+/))
diff --git a/src/app/state.ts b/src/app/state.ts
index 6198e478..ff9a3b18 100644
--- a/src/app/state.ts
+++ b/src/app/state.ts
@@ -5,8 +5,8 @@ import type {Maybe} from "@welshman/lib"
import {uniq, uniqBy, groupBy, pushToMapKey, nthEq, batcher, postJson, stripProtocol, assoc, indexBy, now} from "@welshman/lib"
import {getIdentifier, getRelayTags, getRelayTagValues, normalizeRelayUrl, getPubkeyTagValues, GROUP_META, PROFILE, RELAYS, FOLLOWS, MUTES, GROUPS, getGroupTags, readProfile, readList, asDecryptedEvent, editList, makeList, createList} from "@welshman/util"
import type {Filter, SignedEvent, CustomEvent, PublishedProfile, PublishedList} from '@welshman/util'
-import type {SubscribeRequest} from '@welshman/net'
-import {publish, subscribe} from '@welshman/net'
+import type {SubscribeRequest, PublishRequest} from '@welshman/net'
+import {publish as basePublish, subscribe} from '@welshman/net'
import {decrypt} from '@welshman/signer'
import {deriveEvents, deriveEventsMapped, getter, withGetter} from "@welshman/store"
import {parseJson, createSearch} from '@lib/util'
@@ -68,6 +68,12 @@ export const createCollection = ({
return {indexStore, getIndex, deriveItem, loadItem, getItem}
}
+export const publish = (request: PublishRequest) => {
+ repository.publish(request.event)
+
+ return basePublish(request)
+}
+
export const load = (request: SubscribeRequest) =>
new Promise>(resolve => {
const sub = subscribe({closeOnEose: true, timeout: 3000, delay: 50, ...request})
@@ -81,38 +87,6 @@ export const load = (request: SubscribeRequest) =>
sub.emitter.on('complete', () => resolve(undefined))
})
-export type ModifyTags = (tags: string[][]) => string[][]
-
-export const updateList = async (kind: number, modifyTags: ModifyTags) => {
- const $pk = pk.get()!
- const $signer = signer.get()!
- const [prev] = repository.query([{kinds: [kind], authors: [$pk]}])
-
- // Preserve content instead of use encrypted tags because kind 3 content is used for
- // relay selections in many places. Content isn't supported for mutes or relays so this is ok
- const relays = [...INDEXER_RELAYS, ...getWriteRelayUrls(await loadRelaySelections($pk))]
- const encrypt = (content: string) => $signer.nip44.encrypt($pk, content)
-
- let encryptable
- if (prev) {
- const content = await ensurePlaintext(prev)
- const list = readList(asDecryptedEvent(prev, {content}))
- const publicTags = modifyTags(list.publicTags)
-
- encryptable = editList({...list, publicTags})
- } else {
- const list = makeList({kind})
- const publicTags = modifyTags(list.publicTags)
-
- encryptable = createList({...list, publicTags})
- }
-
- const template = await encryptable.reconcile(encrypt)
- const event = await $signer.sign({...template, created_at: now()})
-
- await publish({event, relays})
-}
-
// Freshness
export const freshness = withGetter(writable>({}))
diff --git a/src/app/theme.ts b/src/app/theme.ts
new file mode 100644
index 00000000..9cf17592
--- /dev/null
+++ b/src/app/theme.ts
@@ -0,0 +1,3 @@
+import {synced} from '@lib/util'
+
+export const theme = synced("theme", "dark")
diff --git a/src/lib/components/CardButton.svelte b/src/lib/components/CardButton.svelte
index 7f2e783b..27ea5984 100644
--- a/src/lib/components/CardButton.svelte
+++ b/src/lib/components/CardButton.svelte
@@ -11,7 +11,7 @@
diff --git a/src/lib/components/Field.svelte b/src/lib/components/Field.svelte
index 6eb95d17..0359efb1 100644
--- a/src/lib/components/Field.svelte
+++ b/src/lib/components/Field.svelte
@@ -3,7 +3,7 @@
-
+
diff --git a/src/lib/components/PrimaryNavItem.svelte b/src/lib/components/PrimaryNavItem.svelte
index 48323d56..b308e185 100644
--- a/src/lib/components/PrimaryNavItem.svelte
+++ b/src/lib/components/PrimaryNavItem.svelte
@@ -1,12 +1,13 @@