Convert to simple relay-based groups from nip29
This commit is contained in:
+24
-19
@@ -10,6 +10,7 @@
|
||||
relays,
|
||||
handles,
|
||||
loadRelay,
|
||||
db,
|
||||
initStorage,
|
||||
repository,
|
||||
session,
|
||||
@@ -27,7 +28,7 @@
|
||||
import PrimaryNav from "@app/components/PrimaryNav.svelte"
|
||||
import {modals, clearModal} from "@app/modal"
|
||||
import {theme} from "@app/theme"
|
||||
import {DEFAULT_RELAYS} from "@app/state"
|
||||
import {INDEXER_RELAYS, topicsByUrl, relaysByMessage} from "@app/state"
|
||||
import {loadUserData} from "@app/commands"
|
||||
import * as state from "@app/state"
|
||||
|
||||
@@ -60,23 +61,27 @@
|
||||
onMount(() => {
|
||||
Object.assign(window, {get, state})
|
||||
|
||||
ready = initStorage('flotilla', 3, {
|
||||
events: {
|
||||
keyPath: "id",
|
||||
store: createEventStore(repository),
|
||||
},
|
||||
relays: {
|
||||
keyPath: "url",
|
||||
store: relays,
|
||||
},
|
||||
handles: {
|
||||
keyPath: "nip05",
|
||||
store: handles,
|
||||
},
|
||||
publishStatus: storageAdapters.fromObjectStore(publishStatusData),
|
||||
freshness: storageAdapters.fromObjectStore(freshness),
|
||||
plaintext: storageAdapters.fromObjectStore(plaintext),
|
||||
}).then(() => sleep(300)) // Wait an extra few ms because of repository throttle
|
||||
ready = db
|
||||
? Promise.resolve()
|
||||
: initStorage("flotilla", 2, {
|
||||
events: {
|
||||
keyPath: "id",
|
||||
store: createEventStore(repository),
|
||||
},
|
||||
relays: {
|
||||
keyPath: "url",
|
||||
store: relays,
|
||||
},
|
||||
handles: {
|
||||
keyPath: "nip05",
|
||||
store: handles,
|
||||
},
|
||||
topicsByUrl: storageAdapters.fromMapStore(topicsByUrl),
|
||||
relaysByMessage: storageAdapters.fromMapStore(relaysByMessage),
|
||||
publishStatus: storageAdapters.fromObjectStore(publishStatusData),
|
||||
freshness: storageAdapters.fromObjectStore(freshness),
|
||||
plaintext: storageAdapters.fromObjectStore(plaintext),
|
||||
}).then(() => sleep(300)) // Wait an extra few ms because of repository throttle
|
||||
|
||||
dialog.addEventListener("close", () => {
|
||||
if (modal) {
|
||||
@@ -85,7 +90,7 @@
|
||||
})
|
||||
|
||||
ready.then(() => {
|
||||
for (const url of DEFAULT_RELAYS) {
|
||||
for (const url of INDEXER_RELAYS) {
|
||||
loadRelay(url)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,20 @@
|
||||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import Masonry from "svelte-bricks"
|
||||
import {GROUP_META, displayRelayUrl} from "@welshman/util"
|
||||
import {load, relays} from "@welshman/app"
|
||||
import {displayRelayUrl} from "@welshman/util"
|
||||
import {load, relaySearch} from "@welshman/app"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import {makeSpacePath} from "@app/routes"
|
||||
import {
|
||||
displayGroup,
|
||||
searchGroups,
|
||||
relayUrlsByNom,
|
||||
userMembership,
|
||||
DEFAULT_RELAYS,
|
||||
} from "@app/state"
|
||||
import {userMembership, discoverRelays} from "@app/state"
|
||||
|
||||
let term = ""
|
||||
|
||||
$: groups = $searchGroups.searchOptions(term).filter(g => $relayUrlsByNom.get(g.nom)?.length > 0)
|
||||
$: relays = $relaySearch.searchOptions(term)
|
||||
|
||||
onMount(() => {
|
||||
load({
|
||||
relays: [...DEFAULT_RELAYS, ...$relays.map(r => r.url)],
|
||||
filters: [{kinds: [GROUP_META]}],
|
||||
})
|
||||
const sub = discoverRelays()
|
||||
|
||||
return () => sub.close()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -34,26 +27,26 @@
|
||||
</label>
|
||||
<Masonry
|
||||
animate={false}
|
||||
items={groups}
|
||||
items={relays}
|
||||
minColWidth={250}
|
||||
maxColWidth={800}
|
||||
gap={16}
|
||||
idKey="nom"
|
||||
let:item={group}>
|
||||
idKey="url"
|
||||
let:item={relay}>
|
||||
<a
|
||||
href={makeSpacePath(group.nom)}
|
||||
href={makeSpacePath(relay.url)}
|
||||
class="card bg-base-100 shadow-xl transition-all hover:shadow-2xl hover:brightness-[1.1]">
|
||||
<div class="center avatar mt-8">
|
||||
<div
|
||||
class="center relative !flex w-20 rounded-full border-2 border-solid border-base-300 bg-base-300">
|
||||
{#if group.picture}
|
||||
<img alt="" src={group.picture} />
|
||||
{#if relay.profile?.icon}
|
||||
<img alt="" src={relay.profile.icon} />
|
||||
{:else}
|
||||
<Icon icon="ghost" size={7} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if $userMembership?.noms.has(group.nom)}
|
||||
{#if $userMembership?.topicsByUrl.has(relay.url)}
|
||||
<div class="center absolute flex w-full">
|
||||
<div
|
||||
class="tooltip relative left-8 top-[38px] h-5 w-5 rounded-full bg-primary"
|
||||
@@ -63,14 +56,9 @@
|
||||
</div>
|
||||
{/if}
|
||||
<div class="card-body">
|
||||
<h2 class="card-title justify-center">{displayGroup(group)}</h2>
|
||||
<div class="text-center text-sm">
|
||||
{#each $relayUrlsByNom.get(group.nom) || [] as url}
|
||||
<div class="badge badge-neutral">{displayRelayUrl(url)}</div>
|
||||
{/each}
|
||||
</div>
|
||||
{#if group.about}
|
||||
<p class="py-4 text-sm">{group.about}</p>
|
||||
<h2 class="card-title justify-center">{displayRelayUrl(relay.url)}</h2>
|
||||
{#if relay.profile?.description}
|
||||
<p class="py-4 text-sm text-center">{relay.profile.description}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
import {subscribe, loadRelay, relaySearch} from "@welshman/app"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import {DEFAULT_RELAYS, INDEXER_RELAYS} from "@app/state"
|
||||
import {INDEXER_RELAYS, discoverRelays} from "@app/state"
|
||||
|
||||
const relays = readable(DEFAULT_RELAYS)
|
||||
const relays = readable(INDEXER_RELAYS)
|
||||
|
||||
const removeRelay = (url: string) => null
|
||||
|
||||
@@ -17,18 +17,7 @@
|
||||
let term = ""
|
||||
|
||||
onMount(() => {
|
||||
const sub = subscribe({
|
||||
filters: [{kinds: [30166], "#N": ["29"]}],
|
||||
relays: [...INDEXER_RELAYS, ...DEFAULT_RELAYS],
|
||||
})
|
||||
|
||||
sub.emitter.on("event", (url: string, event: SignedEvent) => {
|
||||
const d = event.tags.find(t => t[0] === "d")?.[1] || ""
|
||||
|
||||
if (isShareableRelayUrl(d)) {
|
||||
loadRelay(d)
|
||||
}
|
||||
})
|
||||
const sub = discoverRelays()
|
||||
|
||||
return () => sub.close()
|
||||
})
|
||||
|
||||
+27
-13
@@ -1,5 +1,8 @@
|
||||
<script lang="ts">
|
||||
import {nip19} from 'nostr-tools'
|
||||
import {page} from "$app/stores"
|
||||
import {sort} from '@welshman/lib'
|
||||
import {displayRelayUrl} from '@welshman/util'
|
||||
import {fly} from "@lib/transition"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Page from "@lib/components/Page.svelte"
|
||||
@@ -11,8 +14,10 @@
|
||||
import SecondaryNavSection from "@lib/components/SecondaryNavSection.svelte"
|
||||
import SpaceExit from "@app/components/SpaceExit.svelte"
|
||||
import SpaceJoin from "@app/components/SpaceJoin.svelte"
|
||||
import {deriveGroup, userMembership, displayGroup} from "@app/state"
|
||||
import RoomCreate from "@app/components/RoomCreate.svelte"
|
||||
import {userMembership, decodeNEvent} from "@app/state"
|
||||
import {pushModal} from "@app/modal"
|
||||
import {makeSpacePath} from "@app/routes"
|
||||
|
||||
const openMenu = () => {
|
||||
showMenu = true
|
||||
@@ -22,22 +27,24 @@
|
||||
showMenu = !showMenu
|
||||
}
|
||||
|
||||
const leaveSpace = () => pushModal(SpaceExit, {nom})
|
||||
const leaveSpace = () => pushModal(SpaceExit, {url})
|
||||
|
||||
const joinSpace = () => pushModal(SpaceJoin, {nom})
|
||||
const joinSpace = () => pushModal(SpaceJoin, {url})
|
||||
|
||||
const addRoom = () => pushModal(RoomCreate, {url})
|
||||
|
||||
let showMenu = false
|
||||
|
||||
$: nom = $page.params.nom
|
||||
$: group = deriveGroup(nom)
|
||||
$: url = decodeNEvent($page.params.nrelay)
|
||||
$: rooms = sort($userMembership?.topicsByUrl?.get(url) || [])
|
||||
</script>
|
||||
|
||||
{#key nom}
|
||||
{#key url}
|
||||
<SecondaryNav>
|
||||
<SecondaryNavSection>
|
||||
<div>
|
||||
<SecondaryNavItem class="w-full !justify-between" on:click={openMenu}>
|
||||
<strong>{displayGroup($group)}</strong>
|
||||
<strong>{displayRelayUrl(url)}</strong>
|
||||
<Icon icon="alt-arrow-down" />
|
||||
</SecondaryNavItem>
|
||||
{#if showMenu}
|
||||
@@ -45,7 +52,7 @@
|
||||
<ul
|
||||
transition:fly|local
|
||||
class="menu absolute z-popover mt-2 w-full rounded-box bg-base-100 p-2 shadow-xl">
|
||||
{#if $userMembership?.noms.has(nom)}
|
||||
{#if $userMembership?.topicsByUrl.has(url)}
|
||||
<li class="text-error">
|
||||
<Button on:click={leaveSpace}>
|
||||
<Icon icon="exit" />
|
||||
@@ -66,22 +73,22 @@
|
||||
</div>
|
||||
<div class="my-3 h-px bg-base-200" />
|
||||
<div in:fly|local>
|
||||
<SecondaryNavItem href="/spaces/{nom}">
|
||||
<SecondaryNavItem href={makeSpacePath(url)}>
|
||||
<Icon icon="chat-round" /> Chat
|
||||
</SecondaryNavItem>
|
||||
</div>
|
||||
<div in:fly|local={{delay: 50}}>
|
||||
<SecondaryNavItem href="/spaces/{nom}/threads">
|
||||
<SecondaryNavItem href={makeSpacePath(url, "threads")}>
|
||||
<Icon icon="notes-minimalistic" /> Threads
|
||||
</SecondaryNavItem>
|
||||
</div>
|
||||
<div in:fly|local={{delay: 100}}>
|
||||
<SecondaryNavItem href="/spaces/{nom}/events">
|
||||
<SecondaryNavItem href={makeSpacePath(url, "events")}>
|
||||
<Icon icon="calendar-minimalistic" /> Calendar
|
||||
</SecondaryNavItem>
|
||||
</div>
|
||||
<div in:fly|local={{delay: 150}}>
|
||||
<SecondaryNavItem href="/spaces/{nom}/listings">
|
||||
<SecondaryNavItem href={makeSpacePath(url, "listings")}>
|
||||
<Icon icon="shop-minimalistic" /> Market
|
||||
</SecondaryNavItem>
|
||||
</div>
|
||||
@@ -89,11 +96,18 @@
|
||||
<div class="h-2" />
|
||||
<SecondaryNavHeader>
|
||||
Rooms
|
||||
<Button on:click={() => alert("Uh, I don't know how to do rooms on NIP 29")}>
|
||||
<Button on:click={addRoom}>
|
||||
<Icon icon="add-circle" />
|
||||
</Button>
|
||||
</SecondaryNavHeader>
|
||||
</div>
|
||||
{#each rooms as topic, i (topic)}
|
||||
<div transition:fly|local={{delay: 250 + i * 50}}>
|
||||
<SecondaryNavItem href={makeSpacePath(url, topic)}>
|
||||
<Icon icon="hashtag" /> {topic}
|
||||
</SecondaryNavItem>
|
||||
</div>
|
||||
{/each}
|
||||
</SecondaryNavSection>
|
||||
</SecondaryNav>
|
||||
<Page>
|
||||
+9
-9
@@ -11,16 +11,16 @@
|
||||
import {onMount} from "svelte"
|
||||
import {page} from "$app/stores"
|
||||
import {sortBy, now} from "@welshman/lib"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import type {TrustedEvent, Filter} from "@welshman/util"
|
||||
import {subscribe, formatTimestampAsDate} from "@welshman/app"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import GroupNote from "@app/components/GroupNote.svelte"
|
||||
import GroupCompose from "@app/components/GroupCompose.svelte"
|
||||
import {deriveGroupChat, userRelayUrlsByNom} from "@app/state"
|
||||
import {deriveChat, userMembership, MESSAGE, REPLY} from "@app/state"
|
||||
|
||||
const {nom} = $page.params
|
||||
const chat = deriveGroupChat(nom)
|
||||
const {url, topic} = $page.params
|
||||
const chat = deriveChat(url)
|
||||
|
||||
const assertEvent = (e: any) => e as TrustedEvent
|
||||
|
||||
@@ -60,10 +60,10 @@
|
||||
}, 3000)
|
||||
|
||||
onMount(() => {
|
||||
const sub = subscribe({
|
||||
filters: [{"#h": [nom], since: now() - 30}],
|
||||
relays: $userRelayUrlsByNom.get(nom) || [],
|
||||
})
|
||||
const since = now() - 30
|
||||
const kinds = [MESSAGE, REPLY]
|
||||
const filter = topic ? {kinds, since, "#t": [topic]} : {kinds, since} as Filter
|
||||
const sub = subscribe({filters: [filter], relays: [url]})
|
||||
|
||||
return () => sub.close()
|
||||
})
|
||||
@@ -100,5 +100,5 @@
|
||||
</Spinner>
|
||||
</p>
|
||||
</div>
|
||||
<GroupCompose {nom} />
|
||||
<GroupCompose {url} {topic} />
|
||||
</div>
|
||||
Reference in New Issue
Block a user