forked from coracle/flotilla
Add relay members list and room join/leave events
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
import {Router} from "@welshman/router"
|
||||
import {load} from "@welshman/net"
|
||||
import type {Relay} from "@welshman/app"
|
||||
import {relays, createSearch, loadRelay, loadRelaySelections} from "@welshman/app"
|
||||
import {relays, createSearch, loadRelay} from "@welshman/app"
|
||||
import {createScroller} from "@lib/html"
|
||||
import {fly} from "@lib/transition"
|
||||
import QrCode from "@assets/icons/qr-code.svg?dataurl"
|
||||
@@ -23,7 +23,12 @@
|
||||
import SpaceInviteAccept from "@app/components/SpaceInviteAccept.svelte"
|
||||
import RelaySummary from "@app/components/RelaySummary.svelte"
|
||||
import SpaceCheck from "@app/components/SpaceCheck.svelte"
|
||||
import {getMembershipUrls, loadMembership, defaultPubkeys, membersByUrl} from "@app/core/state"
|
||||
import {
|
||||
bootstrapPubkeys,
|
||||
loadGroupSelections,
|
||||
getSpaceUrlsFromGroupSelections,
|
||||
groupSelectionsPubkeysByUrl,
|
||||
} from "@app/core/state"
|
||||
import {pushModal} from "@app/util/modal"
|
||||
|
||||
const openMenu = () => pushModal(SpaceAdd)
|
||||
@@ -45,11 +50,9 @@
|
||||
filters: [{kinds: [ROOMS]}],
|
||||
relays: Router.get().Index().getUrls(),
|
||||
}),
|
||||
...$defaultPubkeys.map(async pubkey => {
|
||||
await loadRelaySelections(pubkey)
|
||||
|
||||
const membership = await loadMembership(pubkey)
|
||||
const urls = getMembershipUrls(membership)
|
||||
...$bootstrapPubkeys.map(async pubkey => {
|
||||
const list = await loadGroupSelections(pubkey)
|
||||
const urls = getSpaceUrlsFromGroupSelections(list)
|
||||
|
||||
await Promise.all(urls.map(url => loadRelay(url)))
|
||||
}),
|
||||
@@ -57,13 +60,13 @@
|
||||
|
||||
const relaySearch = $derived(
|
||||
createSearch(
|
||||
$relays.filter(r => $membersByUrl.has(r.url) && r.url !== termUrl),
|
||||
$relays.filter(r => $groupSelectionsPubkeysByUrl.has(r.url) && r.url !== termUrl),
|
||||
{
|
||||
getValue: (relay: Relay) => relay.url,
|
||||
sortFn: ({score, item}) => {
|
||||
if (score && score > 0.1) return -score!
|
||||
|
||||
const wotScore = $membersByUrl.get(item.url)?.size || 0
|
||||
const wotScore = $groupSelectionsPubkeysByUrl.get(item.url)!.size
|
||||
|
||||
return score ? dec(score) * wotScore : -wotScore
|
||||
},
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
import Page from "@lib/components/Page.svelte"
|
||||
import ContentSearch from "@lib/components/ContentSearch.svelte"
|
||||
import PeopleItem from "@app/components/PeopleItem.svelte"
|
||||
import {defaultPubkeys} from "@app/core/state"
|
||||
import {bootstrapPubkeys} from "@app/core/state"
|
||||
|
||||
let term = $state("")
|
||||
let limit = $state(10)
|
||||
let element: Element | undefined = $state()
|
||||
|
||||
const pubkeys = $derived(term ? $profileSearch.searchValues(term) : $defaultPubkeys)
|
||||
const pubkeys = $derived(term ? $profileSearch.searchValues(term) : $bootstrapPubkeys)
|
||||
|
||||
onMount(() => {
|
||||
const scroller = createScroller({
|
||||
|
||||
@@ -7,7 +7,13 @@
|
||||
import type {MakeNonOptional} from "@welshman/lib"
|
||||
import {now, formatTimestampAsDate, ago, MINUTE} from "@welshman/lib"
|
||||
import type {TrustedEvent, EventContent} from "@welshman/util"
|
||||
import {makeEvent, makeRoomMeta, MESSAGE} from "@welshman/util"
|
||||
import {
|
||||
makeEvent,
|
||||
makeRoomMeta,
|
||||
MESSAGE,
|
||||
ROOM_ADD_MEMBER,
|
||||
ROOM_REMOVE_MEMBER,
|
||||
} from "@welshman/util"
|
||||
import {pubkey, publishThunk, waitForThunkError, joinRoom, leaveRoom} from "@welshman/app"
|
||||
import {slide, fade, fly} from "@lib/transition"
|
||||
import Hashtag from "@assets/icons/hashtag.svg?dataurl"
|
||||
@@ -26,13 +32,16 @@
|
||||
import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte"
|
||||
import ChannelName from "@app/components/ChannelName.svelte"
|
||||
import ChannelItem from "@app/components/ChannelItem.svelte"
|
||||
import ChannelItemAddMember from "@src/app/components/ChannelItemAddMember.svelte"
|
||||
import ChannelItemRemoveMember from "@src/app/components/ChannelItemRemoveMember.svelte"
|
||||
import ChannelCompose from "@app/components/ChannelCompose.svelte"
|
||||
import ChannelComposeEdit from "@src/app/components/ChannelComposeEdit.svelte"
|
||||
import ChannelComposeParent from "@app/components/ChannelComposeParent.svelte"
|
||||
import {
|
||||
userRoomsByUrl,
|
||||
deriveUserRooms,
|
||||
userSettingsValues,
|
||||
decodeRelay,
|
||||
deriveUserMembershipStatus,
|
||||
deriveUserRoomMembershipStatus,
|
||||
deriveChannel,
|
||||
MembershipStatus,
|
||||
PROTECTED,
|
||||
@@ -49,16 +58,16 @@
|
||||
import {makeFeed} from "@app/core/requests"
|
||||
import {popKey} from "@lib/implicit"
|
||||
import {pushToast} from "@app/util/toast"
|
||||
import ChannelComposeEdit from "@src/app/components/ChannelComposeEdit.svelte"
|
||||
|
||||
const {room, relay} = $page.params as MakeNonOptional<typeof $page.params>
|
||||
const mounted = now()
|
||||
const lastChecked = $checked[$page.url.pathname]
|
||||
const url = decodeRelay(relay)
|
||||
const channel = deriveChannel(url, room)
|
||||
const isFavorite = $derived($userRoomsByUrl.get(url)?.has(room))
|
||||
const shouldProtect = canEnforceNip70(url)
|
||||
const membershipStatus = deriveUserMembershipStatus(url, room)
|
||||
const userRooms = deriveUserRooms(url)
|
||||
const isFavorite = $derived($userRooms.includes(room))
|
||||
const membershipStatus = deriveUserRoomMembershipStatus(url, room)
|
||||
|
||||
const addFavorite = () => addRoomMembership(url, room)
|
||||
|
||||
@@ -256,7 +265,7 @@
|
||||
const feed = makeFeed({
|
||||
url,
|
||||
element: element!,
|
||||
filters: [{kinds: MESSAGE_KINDS, "#h": [room]}],
|
||||
filters: [{kinds: [...MESSAGE_KINDS, ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER], "#h": [room]}],
|
||||
onExhausted: () => {
|
||||
loadingEvents = false
|
||||
},
|
||||
@@ -398,15 +407,22 @@
|
||||
{:else if type === "date"}
|
||||
<Divider>{value}</Divider>
|
||||
{:else}
|
||||
<div in:slide class:-mt-1={!showPubkey}>
|
||||
<ChannelItem
|
||||
{url}
|
||||
{replyTo}
|
||||
event={$state.snapshot(value as TrustedEvent)}
|
||||
{showPubkey}
|
||||
canEdit={canEditEvent}
|
||||
onEdit={onEditEvent} />
|
||||
</div>
|
||||
{@const event = $state.snapshot(value as TrustedEvent)}
|
||||
{#if event.kind === ROOM_ADD_MEMBER}
|
||||
<ChannelItemAddMember {url} {event} />
|
||||
{:else if event.kind === ROOM_REMOVE_MEMBER}
|
||||
<ChannelItemRemoveMember {url} {event} />
|
||||
{:else}
|
||||
<div in:slide class:-mt-1={!showPubkey}>
|
||||
<ChannelItem
|
||||
{url}
|
||||
{event}
|
||||
{replyTo}
|
||||
{showPubkey}
|
||||
canEdit={canEditEvent}
|
||||
onEdit={onEditEvent} />
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
<p class="flex h-10 items-center justify-center py-20">
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
import {readable} from "svelte/store"
|
||||
import {now, formatTimestampAsDate, MINUTE, ago} from "@welshman/lib"
|
||||
import type {TrustedEvent, EventContent} from "@welshman/util"
|
||||
import {makeEvent, MESSAGE} from "@welshman/util"
|
||||
import {makeEvent, MESSAGE, RELAY_ADD_MEMBER, RELAY_REMOVE_MEMBER} from "@welshman/util"
|
||||
import {pubkey, publishThunk} from "@welshman/app"
|
||||
import {slide, fade, fly} from "@lib/transition"
|
||||
import {fade, fly} from "@lib/transition"
|
||||
import ChatRound from "@assets/icons/chat-round.svg?dataurl"
|
||||
import AltArrowDown from "@assets/icons/alt-arrow-down.svg?dataurl"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
@@ -19,15 +19,17 @@
|
||||
import ThunkToast from "@app/components/ThunkToast.svelte"
|
||||
import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte"
|
||||
import ChannelItem from "@app/components/ChannelItem.svelte"
|
||||
import ChannelItemAddMember from "@src/app/components/ChannelItemAddMember.svelte"
|
||||
import ChannelItemRemoveMember from "@src/app/components/ChannelItemRemoveMember.svelte"
|
||||
import ChannelCompose from "@app/components/ChannelCompose.svelte"
|
||||
import ChannelComposeEdit from "@src/app/components/ChannelComposeEdit.svelte"
|
||||
import ChannelComposeParent from "@app/components/ChannelComposeParent.svelte"
|
||||
import {userSettingsValues, decodeRelay, MESSAGE_FILTER, PROTECTED} from "@app/core/state"
|
||||
import {userSettingsValues, decodeRelay, PROTECTED, MESSAGE_KINDS} from "@app/core/state"
|
||||
import {prependParent, canEnforceNip70, publishDelete} from "@app/core/commands"
|
||||
import {setChecked, checked} from "@app/util/notifications"
|
||||
import {pushToast} from "@app/util/toast"
|
||||
import {makeFeed} from "@app/core/requests"
|
||||
import {popKey} from "@lib/implicit"
|
||||
import ChannelComposeEdit from "@src/app/components/ChannelComposeEdit.svelte"
|
||||
|
||||
const mounted = now()
|
||||
const lastChecked = $checked[$page.url.pathname]
|
||||
@@ -218,7 +220,7 @@
|
||||
const feed = makeFeed({
|
||||
url,
|
||||
element: element!,
|
||||
filters: [MESSAGE_FILTER],
|
||||
filters: [{kinds: [...MESSAGE_KINDS, RELAY_ADD_MEMBER, RELAY_REMOVE_MEMBER]}],
|
||||
onExhausted: () => {
|
||||
loadingEvents = false
|
||||
},
|
||||
@@ -271,15 +273,21 @@
|
||||
<Divider>{value}</Divider>
|
||||
{:else}
|
||||
{@const event = $state.snapshot(value as TrustedEvent)}
|
||||
<div in:slide class:-mt-1={!showPubkey}>
|
||||
<ChannelItem
|
||||
{url}
|
||||
{event}
|
||||
{replyTo}
|
||||
{showPubkey}
|
||||
canEdit={canEditEvent}
|
||||
onEdit={onEditEvent} />
|
||||
</div>
|
||||
{#if event.kind === RELAY_ADD_MEMBER}
|
||||
<ChannelItemAddMember {url} {event} />
|
||||
{:else if event.kind === RELAY_REMOVE_MEMBER}
|
||||
<ChannelItemRemoveMember {url} {event} />
|
||||
{:else}
|
||||
<div class:-mt-1={!showPubkey}>
|
||||
<ChannelItem
|
||||
{url}
|
||||
{event}
|
||||
{replyTo}
|
||||
{showPubkey}
|
||||
canEdit={canEditEvent}
|
||||
onEdit={onEditEvent} />
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
<p class="flex h-10 items-center justify-center py-20">
|
||||
|
||||
Reference in New Issue
Block a user