Refactor: use relay-provided member lists as source of truth #191
@@ -33,7 +33,7 @@
|
||||
import RoomImage from "@app/components/RoomImage.svelte"
|
||||
import {
|
||||
deriveRoom,
|
||||
deriveRoomMemberList,
|
||||
deriveRoomMembers,
|
||||
deriveUserIsRoomAdmin,
|
||||
deriveUserRoomMembershipStatus,
|
||||
deriveUserRooms,
|
||||
@@ -57,7 +57,7 @@
|
||||
const {url, h}: Props = $props()
|
||||
|
||||
const room = deriveRoom(url, h)
|
||||
const members = deriveRoomMemberList(url, h)
|
||||
const members = deriveRoomMembers(url, h)
|
||||
const userIsAdmin = deriveUserIsRoomAdmin(url, h)
|
||||
const membershipStatus = deriveUserRoomMembershipStatus(url, h)
|
||||
const userRooms = deriveUserRooms(url)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
import Profile from "@app/components/Profile.svelte"
|
||||
import RoomName from "@app/components/RoomName.svelte"
|
||||
import RoomMembersAdd from "@app/components/RoomMembersAdd.svelte"
|
||||
import {deriveRoom, deriveRoomMemberList, deriveUserIsRoomAdmin} from "@app/core/state"
|
||||
import {deriveRoom, deriveRoomMembers, deriveUserIsRoomAdmin} from "@app/core/state"
|
||||
import {pushModal} from "@app/util/modal"
|
||||
import {pushToast} from "@app/util/toast"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
const {url, h}: Props = $props()
|
||||
|
||||
const room = deriveRoom(url, h)
|
||||
const members = deriveRoomMemberList(url, h)
|
||||
const members = deriveRoomMembers(url, h)
|
||||
const userIsAdmin = deriveUserIsRoomAdmin(url, h)
|
||||
|
||||
const back = () => history.back()
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
import ProfileMultiSelect from "@app/components/ProfileMultiSelect.svelte"
|
||||
import {pushToast} from "@app/util/toast"
|
||||
import {pushModal} from "@app/util/modal"
|
||||
import {deriveRoom, deriveRelayMemberList} from "@app/core/state"
|
||||
import {deriveRoom, getSpaceMembers} from "@app/core/state"
|
||||
import {addRoomMembers} from "@app/core/commands"
|
||||
|
||||
interface Props {
|
||||
@@ -31,7 +31,7 @@
|
||||
const {url, h}: Props = $props()
|
||||
|
||||
const room = deriveRoom(url, h)
|
||||
const spaceMembers = deriveRelayMemberList(url)
|
||||
const spaceMembers = getSpaceMembers(url)
|
||||
|
||||
const back = () => history.back()
|
||||
|
||||
@@ -56,12 +56,8 @@
|
||||
}
|
||||
|
||||
const onSubmit = async () => {
|
||||
// Space member list is required to add members to a room
|
||||
if (!$spaceMembers) {
|
||||
pushToast({
|
||||
theme: "error",
|
||||
message: "Cannot add members: space member list not available from this relay",
|
||||
})
|
||||
addMembers()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import SpaceMembersAdd from "@app/components/SpaceMembersAdd.svelte"
|
||||
import SpaceMembersBanned from "@app/components/SpaceMembersBanned.svelte"
|
||||
import {
|
||||
deriveRelayMemberList,
|
||||
getSpaceMembers,
|
||||
deriveSpaceBannedPubkeyItems,
|
||||
deriveUserIsSpaceAdmin,
|
||||
deriveSupportedMethods,
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
const {url}: Props = $props()
|
||||
|
||||
const members = deriveRelayMemberList(url)
|
||||
const members = getSpaceMembers(url)
|
||||
const bans = deriveSpaceBannedPubkeyItems(url)
|
||||
const userIsAdmin = deriveUserIsSpaceAdmin(url)
|
||||
const supportedMethods = deriveSupportedMethods(url)
|
||||
@@ -114,7 +114,7 @@
|
||||
<div class="flex flex-col gap-2">
|
||||
{#if $members === undefined}
|
||||
<div class="card2 bg-base-200 p-4">
|
||||
<span class="text-error">Member list not available from this relay</span>
|
||||
<span class="text-error">Member list not available from this space</span>
|
||||
|
hodlbod marked this conversation as resolved
Outdated
|
||||
</div>
|
||||
{:else if $members.length === 0}
|
||||
<div class="card2 bg-base-200 p-4">
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
import {
|
||||
ENABLE_ZAPS,
|
||||
CONTENT_KINDS,
|
||||
deriveRelayMemberList,
|
||||
getSpaceMembers,
|
||||
deriveUserRooms,
|
||||
deriveOtherRooms,
|
||||
deriveOtherVoiceRooms,
|
||||
@@ -76,7 +76,7 @@
|
||||
const userRooms = deriveUserRooms(url)
|
||||
const otherRooms = deriveOtherRooms(url)
|
||||
const otherVoiceRooms = deriveOtherVoiceRooms(url)
|
||||
const members = deriveRelayMemberList(url)
|
||||
const members = getSpaceMembers(url)
|
||||
const userIsAdmin = deriveUserIsSpaceAdmin(url)
|
||||
const actionItems = deriveSpaceActionItems(url)
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
<Button onclick={showMembers}>
|
||||
<Icon icon={UserRounded} />
|
||||
{#if $members === undefined}
|
||||
View Members (unavailable)
|
||||
View Members
|
||||
|
hodlbod
commented
Remove Remove `(unavailable)`
|
||||
{:else}
|
||||
View Members ({$members.length})
|
||||
{/if}
|
||||
|
||||
@@ -95,7 +95,7 @@ import {
|
||||
stripPrefix,
|
||||
relaysMostlyRestricted,
|
||||
deriveSocket,
|
||||
deriveRelayMemberList,
|
||||
getSpaceMembers,
|
||||
} from "@app/core/state"
|
||||
|
||||
// Utils
|
||||
@@ -765,16 +765,11 @@ export const addSpaceMembers = async (
|
||||
url: string,
|
||||
pubkeys: string[],
|
||||
): Promise<string | undefined> => {
|
||||
const spaceMembers = get(deriveRelayMemberList(url))
|
||||
|
||||
// Cannot add members without access to the member list
|
||||
if (spaceMembers === undefined) {
|
||||
return "Member list not available from this relay"
|
||||
}
|
||||
const spaceMembers = get(getSpaceMembers(url))
|
||||
|
||||
const results = await Promise.all(
|
||||
pubkeys
|
||||
.filter(pubkey => !spaceMembers.includes(pubkey))
|
||||
.filter(pubkey => spaceMembers && !spaceMembers.includes(pubkey))
|
||||
.map(pubkey =>
|
||||
|
hodlbod marked this conversation as resolved
Outdated
hodlbod
commented
Don't fail hard, just send all pubkeys (change the filter line to Don't fail hard, just send all pubkeys (change the filter line to `.filter(pubkey => spaceMembers && !spaceMembers.includes(pubkey))`)
|
||||
manageRelay(url, {
|
||||
method: ManagementMethod.AllowPubkey,
|
||||
|
||||
+9
-12
@@ -8,7 +8,6 @@ import {
|
||||
on,
|
||||
gt,
|
||||
max,
|
||||
find,
|
||||
spec,
|
||||
call,
|
||||
first,
|
||||
@@ -809,19 +808,17 @@ export const deriveOtherRooms = (url: string) =>
|
||||
|
||||
// Space/room memberships
|
||||
|
||||
|
hodlbod marked this conversation as resolved
Outdated
hodlbod
commented
Let's just keep calling this Same thing in deriveRoomMemberList (which should be deriveRoomMembers). Let's just keep calling this `getSpaceMembers`. I was thinking of using the list directly, but it's more convenient to return the uniqe list of pubkeys. However, you might change the body to:
```typescript
([event]) => uniq(getTagValues("member", event?.tags ?? []))
```
Same thing in deriveRoomMemberList (which should be deriveRoomMembers).
|
||||
export const deriveRelayMemberList = (url: string) =>
|
||||
derived(deriveRelaySignedEvents(url, [{kinds: [RELAY_MEMBERS]}]), $events => {
|
||||
const membersEvent = $events.find(spec({kind: RELAY_MEMBERS}))
|
||||
return membersEvent ? uniq(getTagValues("member", membersEvent.tags)) : undefined
|
||||
})
|
||||
export const getSpaceMembers = (url: string) =>
|
||||
|
hodlbod marked this conversation as resolved
Outdated
hodlbod
commented
This should be renamed to deriveSpaceMembers since it returns a svelte store, not the value itself. This should be renamed to deriveSpaceMembers since it returns a svelte store, not the value itself.
|
||||
derived(deriveRelaySignedEvents(url, [{kinds: [RELAY_MEMBERS]}]), ([event]) =>
|
||||
uniq(getTagValues("member", event?.tags ?? [])),
|
||||
)
|
||||
|
||||
export const deriveRoomMemberList = (url: string, h: string) => {
|
||||
export const deriveRoomMembers = (url: string, h: string) => {
|
||||
const filters: Filter[] = [{kinds: [ROOM_MEMBERS], "#d": [h]}]
|
||||
|
||||
return derived(deriveEventsForUrl(url, filters), $events => {
|
||||
const membersEvent = find(spec({kind: ROOM_MEMBERS}), $events)
|
||||
return membersEvent ? uniq(getPubkeyTagValues(membersEvent.tags)) : undefined
|
||||
})
|
||||
return derived(deriveEventsForUrl(url, filters), ([event]) =>
|
||||
uniq(getPubkeyTagValues(event?.tags ?? [])),
|
||||
)
|
||||
}
|
||||
|
||||
export type BannedPubkeyItem = {
|
||||
@@ -1063,7 +1060,7 @@ export const deriveUserRoomMembershipStatus = (url: string, h: string) => {
|
||||
return derived(
|
||||
[
|
||||
pubkey,
|
||||
deriveRoomMemberList(url, h),
|
||||
deriveRoomMembers(url, h),
|
||||
deriveEventsForUrl(url, userEventFilters),
|
||||
deriveEventsForUrl(url, joinLeaveFilters),
|
||||
deriveUserIsRoomAdmin(url, h),
|
||||
|
||||
@@ -174,9 +174,8 @@ const syncUserSpaceMembership = (url: string) => {
|
||||
url,
|
||||
signal: controller.signal,
|
||||
filters: [
|
||||
// Keep current-user membership history so status replay stays deterministic.
|
||||
{kinds: [RELAY_ADD_MEMBER], "#p": [$pubkey]},
|
||||
{kinds: [RELAY_REMOVE_MEMBER], "#p": [$pubkey]},
|
||||
{kinds: [RELAY_ADD_MEMBER], "#p": [$pubkey], limit: 1},
|
||||
{kinds: [RELAY_REMOVE_MEMBER], "#p": [$pubkey], limit: 1},
|
||||
{kinds: [ROOM_CREATE_PERMISSION], "#p": [$pubkey], limit: 1},
|
||||
|
hodlbod
commented
Keep the limit, we want that Keep the limit, we want that
|
||||
],
|
||||
})
|
||||
@@ -194,9 +193,8 @@ const syncUserRoomMembership = (url: string, h: string) => {
|
||||
url,
|
||||
signal: controller.signal,
|
||||
filters: [
|
||||
// Keep current-user membership history so status replay stays deterministic.
|
||||
{kinds: [ROOM_ADD_MEMBER], "#p": [$pubkey], "#h": [h]},
|
||||
{kinds: [ROOM_REMOVE_MEMBER], "#p": [$pubkey], "#h": [h]},
|
||||
{kinds: [ROOM_ADD_MEMBER], "#p": [$pubkey], "#h": [h], limit: 1},
|
||||
{kinds: [ROOM_REMOVE_MEMBER], "#p": [$pubkey], "#h": [h], limit: 1},
|
||||
],
|
||||
})
|
||||
|
hodlbod
commented
Keep the limit, remove the comment Keep the limit, remove the comment
|
||||
}
|
||||
|
||||
@@ -28,13 +28,7 @@ import {RoomReferenceExtension} from "@app/editor/RoomReferenceExtension"
|
||||
import RoomSuggestion from "@app/editor/RoomSuggestion.svelte"
|
||||
import {NativeClipboardPasteExtension} from "@app/editor/clipboard"
|
||||
import {uploadFile} from "@app/core/commands"
|
||||
import {
|
||||
deriveRelayMemberList,
|
||||
makeRoomId,
|
||||
splitRoomId,
|
||||
userSpaceUrls,
|
||||
roomsByUrl,
|
||||
} from "@app/core/state"
|
||||
import {getSpaceMembers, makeRoomId, splitRoomId, userSpaceUrls, roomsByUrl} from "@app/core/state"
|
||||
import {pushToast} from "@app/util/toast"
|
||||
|
||||
export const makeEditor = async ({
|
||||
@@ -64,7 +58,7 @@ export const makeEditor = async ({
|
||||
[
|
||||
throttled(800, profiles),
|
||||
throttled(800, handlesByNip05),
|
||||
throttled(800, deriveRelayMemberList(url || "")),
|
||||
throttled(800, getSpaceMembers(url || "")),
|
||||
],
|
||||
([$profiles, $handlesByNip05, $spaceMembers]) => {
|
||||
// Remove invalid nip05's from profiles
|
||||
@@ -79,7 +73,6 @@ export const makeEditor = async ({
|
||||
getValue: (profile: PublishedProfile) => profile.event.pubkey,
|
||||
sortFn: ({score = 1, item}) => {
|
||||
const wotScore = getWotGraph().get(item.event.pubkey) || 0
|
||||
// Boost score for space members. If member list is unavailable, this falls through to 1x multiplier
|
||||
const membershipScale = $spaceMembers?.includes(item.event.pubkey) ? 2 : 1
|
||||
|
||||
return dec(score) * inc(wotScore / getMaxWot()) * membershipScale
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
import RoomCompose from "@app/components/RoomCompose.svelte"
|
||||
import RoomComposeEdit from "@src/app/components/RoomComposeEdit.svelte"
|
||||
import RoomComposeParent from "@app/components/RoomComposeParent.svelte"
|
||||
import {userSettingsValues, decodeRelay, PROTECTED, CONTENT_KINDS} from "@app/core/state"
|
||||
import {userSettingsValues, decodeRelay, PROTECTED} from "@app/core/state"
|
||||
import {prependParent, canEnforceNip70, publishDelete} from "@app/core/commands"
|
||||
import {checked} from "@app/util/notifications"
|
||||
import {pushToast} from "@app/util/toast"
|
||||
@@ -258,7 +258,7 @@
|
||||
url,
|
||||
at: at || now(),
|
||||
element: element!,
|
||||
filters: [{kinds: [...CONTENT_KINDS, MESSAGE]}],
|
||||
filters: [{kinds: [MESSAGE, RELAY_ADD_MEMBER]}],
|
||||
|
hodlbod
commented
This is incorrect, it should be the way it was before. This is incorrect, it should be the way it was before.
|
||||
onBackwardExhausted: () => {
|
||||
loadingBackward = false
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user
Use "space" instead of "relay"