forked from coracle/flotilla
fix: realtime updates for room members and admins
This commit is contained in:
+68
-19
@@ -8,7 +8,6 @@ import {
|
|||||||
on,
|
on,
|
||||||
gt,
|
gt,
|
||||||
max,
|
max,
|
||||||
find,
|
|
||||||
spec,
|
spec,
|
||||||
call,
|
call,
|
||||||
first,
|
first,
|
||||||
@@ -819,15 +818,19 @@ export const deriveSpaceMembers = (url: string) =>
|
|||||||
derived(
|
derived(
|
||||||
deriveRelaySignedEvents(url, [{kinds: [RELAY_ADD_MEMBER, RELAY_REMOVE_MEMBER, RELAY_MEMBERS]}]),
|
deriveRelaySignedEvents(url, [{kinds: [RELAY_ADD_MEMBER, RELAY_REMOVE_MEMBER, RELAY_MEMBERS]}]),
|
||||||
$events => {
|
$events => {
|
||||||
const membersEvent = $events.find(spec({kind: RELAY_MEMBERS}))
|
|
||||||
|
|
||||||
if (membersEvent) {
|
|
||||||
return uniq(getTagValues("member", membersEvent.tags))
|
|
||||||
}
|
|
||||||
|
|
||||||
const members = new Set<string>()
|
const members = new Set<string>()
|
||||||
|
|
||||||
for (const event of sortBy(e => e.created_at, $events)) {
|
for (const event of sortEventsAsc($events)) {
|
||||||
|
if (event.kind === RELAY_MEMBERS) {
|
||||||
|
members.clear()
|
||||||
|
|
||||||
|
for (const pubkey of uniq(getTagValues("member", event.tags))) {
|
||||||
|
members.add(pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
const pubkeys = getPubkeyTagValues(event.tags)
|
const pubkeys = getPubkeyTagValues(event.tags)
|
||||||
|
|
||||||
if (event.kind === RELAY_ADD_MEMBER) {
|
if (event.kind === RELAY_ADD_MEMBER) {
|
||||||
@@ -872,15 +875,19 @@ export const deriveRoomMembers = (url: string, h: string) => {
|
|||||||
]
|
]
|
||||||
|
|
||||||
return derived(deriveEventsForUrl(url, filters), $events => {
|
return derived(deriveEventsForUrl(url, filters), $events => {
|
||||||
const membersEvent = find(spec({kind: ROOM_MEMBERS}), $events)
|
|
||||||
|
|
||||||
if (membersEvent) {
|
|
||||||
return uniq(getPubkeyTagValues(membersEvent.tags))
|
|
||||||
}
|
|
||||||
|
|
||||||
const members = new Set<string>()
|
const members = new Set<string>()
|
||||||
|
|
||||||
for (const event of sortEventsAsc($events)) {
|
for (const event of sortEventsAsc($events)) {
|
||||||
|
if (event.kind === ROOM_MEMBERS) {
|
||||||
|
members.clear()
|
||||||
|
|
||||||
|
for (const pubkey of uniq(getPubkeyTagValues(event.tags))) {
|
||||||
|
members.add(pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
const pubkeys = getPubkeyTagValues(event.tags)
|
const pubkeys = getPubkeyTagValues(event.tags)
|
||||||
|
|
||||||
if (event.kind === ROOM_ADD_MEMBER) {
|
if (event.kind === ROOM_ADD_MEMBER) {
|
||||||
@@ -921,7 +928,7 @@ export const deriveSpaceActionItems = (url: string) =>
|
|||||||
derived(
|
derived(
|
||||||
deriveEventsForUrl(url, [
|
deriveEventsForUrl(url, [
|
||||||
{
|
{
|
||||||
kinds: [REPORT, ROOM_JOIN, ROOM_LEAVE, ROOM_MEMBERS],
|
kinds: [REPORT, ROOM_JOIN, ROOM_LEAVE, ROOM_MEMBERS, ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER],
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
$events => {
|
$events => {
|
||||||
@@ -936,8 +943,36 @@ export const deriveSpaceActionItems = (url: string) =>
|
|||||||
|
|
||||||
const roomJoins = roomEvents.filter(spec({kind: ROOM_JOIN}))
|
const roomJoins = roomEvents.filter(spec({kind: ROOM_JOIN}))
|
||||||
const roomLeaves = roomEvents.filter(spec({kind: ROOM_LEAVE}))
|
const roomLeaves = roomEvents.filter(spec({kind: ROOM_LEAVE}))
|
||||||
const roomMembersEvent = roomEvents.find(spec({kind: ROOM_MEMBERS}))
|
const roomMembershipEvents = roomEvents.filter(event =>
|
||||||
const roomMembers = getTagValues("p", roomMembersEvent?.tags ?? [])
|
[ROOM_MEMBERS, ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER].includes(event.kind),
|
||||||
|
)
|
||||||
|
const roomMembers = new Set<string>()
|
||||||
|
|
||||||
|
for (const event of sortEventsAsc(roomMembershipEvents)) {
|
||||||
|
if (event.kind === ROOM_MEMBERS) {
|
||||||
|
roomMembers.clear()
|
||||||
|
|
||||||
|
for (const pubkey of uniq(getPubkeyTagValues(event.tags))) {
|
||||||
|
roomMembers.add(pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const pubkeys = getPubkeyTagValues(event.tags)
|
||||||
|
|
||||||
|
if (event.kind === ROOM_ADD_MEMBER) {
|
||||||
|
for (const pubkey of pubkeys) {
|
||||||
|
roomMembers.add(pubkey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.kind === ROOM_REMOVE_MEMBER) {
|
||||||
|
for (const pubkey of pubkeys) {
|
||||||
|
roomMembers.delete(pubkey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pendingJoins.push(
|
pendingJoins.push(
|
||||||
...removeUndefined(
|
...removeUndefined(
|
||||||
@@ -945,8 +980,22 @@ export const deriveSpaceActionItems = (url: string) =>
|
|||||||
.map(sortEventsDesc)
|
.map(sortEventsDesc)
|
||||||
.map(first),
|
.map(first),
|
||||||
).filter(({pubkey, created_at}) => {
|
).filter(({pubkey, created_at}) => {
|
||||||
if (roomMembers.includes(pubkey)) return false
|
if (roomMembers.has(pubkey)) return false
|
||||||
if (gt(roomMembersEvent?.created_at, created_at)) return false
|
if (
|
||||||
|
roomMembershipEvents.some(event => {
|
||||||
|
if (event.created_at <= created_at) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.kind === ROOM_MEMBERS) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return getPubkeyTagValues(event.tags).includes(pubkey)
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if (roomLeaves.some(e => e.pubkey === pubkey && e.created_at > created_at)) return false
|
if (roomLeaves.some(e => e.pubkey === pubkey && e.created_at > created_at)) return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|||||||
+16
-3
@@ -13,6 +13,8 @@ import {
|
|||||||
ROOM_MEMBERS,
|
ROOM_MEMBERS,
|
||||||
ROOM_ADD_MEMBER,
|
ROOM_ADD_MEMBER,
|
||||||
ROOM_REMOVE_MEMBER,
|
ROOM_REMOVE_MEMBER,
|
||||||
|
ROOM_JOIN,
|
||||||
|
ROOM_LEAVE,
|
||||||
ROOM_CREATE_PERMISSION,
|
ROOM_CREATE_PERMISSION,
|
||||||
RELAY_MEMBERS,
|
RELAY_MEMBERS,
|
||||||
RELAY_ADD_MEMBER,
|
RELAY_ADD_MEMBER,
|
||||||
@@ -278,8 +280,13 @@ const syncSpace = (url: string, rooms: string[]) => {
|
|||||||
url,
|
url,
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
filters: [
|
filters: [
|
||||||
|
{kinds: [ROOM_META, ROOM_ADMINS, ROOM_MEMBERS], "#d": [room]},
|
||||||
{kinds: MESSAGE_KINDS, since, "#h": [room]},
|
{kinds: MESSAGE_KINDS, since, "#h": [room]},
|
||||||
makeCommentFilter(CONTENT_KINDS, {since, "#h": [room]}),
|
makeCommentFilter(CONTENT_KINDS, {since, "#h": [room]}),
|
||||||
|
{
|
||||||
|
kinds: [ROOM_DELETE, ROOM_JOIN, ROOM_LEAVE, ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER],
|
||||||
|
"#h": [room],
|
||||||
|
},
|
||||||
{kinds: [PollResponse], since},
|
{kinds: [PollResponse], since},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
@@ -292,7 +299,7 @@ const syncSpace = (url: string, rooms: string[]) => {
|
|||||||
|
|
||||||
const relayKinds = [RELAY_MEMBERS, RELAY_ADD_MEMBER, RELAY_REMOVE_MEMBER]
|
const relayKinds = [RELAY_MEMBERS, RELAY_ADD_MEMBER, RELAY_REMOVE_MEMBER]
|
||||||
const roomMetaKinds = [ROOM_META, ROOM_ADMINS, ROOM_MEMBERS, LIVEKIT_PARTICIPANTS]
|
const roomMetaKinds = [ROOM_META, ROOM_ADMINS, ROOM_MEMBERS, LIVEKIT_PARTICIPANTS]
|
||||||
const roomMemberKinds = [ROOM_DELETE, ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER]
|
const roomMemberKinds = [ROOM_DELETE, ROOM_JOIN, ROOM_LEAVE, ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER]
|
||||||
|
|
||||||
pullAndListen({
|
pullAndListen({
|
||||||
url,
|
url,
|
||||||
@@ -325,9 +332,10 @@ const syncSpaces = () => {
|
|||||||
|
|
||||||
const unsubscribe = store.subscribe(([$userGroupList, $page]) => {
|
const unsubscribe = store.subscribe(([$userGroupList, $page]) => {
|
||||||
const urls = new Set(getSpaceUrlsFromGroupList($userGroupList))
|
const urls = new Set(getSpaceUrlsFromGroupList($userGroupList))
|
||||||
|
const currentUrl = $page.params.relay ? decodeRelay($page.params.relay) : undefined
|
||||||
|
|
||||||
if ($page.params.relay) {
|
if (currentUrl) {
|
||||||
urls.add(decodeRelay($page.params.relay))
|
urls.add(currentUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop syncing removed spaces
|
// Stop syncing removed spaces
|
||||||
@@ -342,6 +350,11 @@ const syncSpaces = () => {
|
|||||||
// Start or restart syncing for each space
|
// Start or restart syncing for each space
|
||||||
for (const url of urls) {
|
for (const url of urls) {
|
||||||
const rooms = getSpaceRoomsFromGroupList(url, $userGroupList)
|
const rooms = getSpaceRoomsFromGroupList(url, $userGroupList)
|
||||||
|
|
||||||
|
if (currentUrl === url && $page.params.h && !rooms.includes($page.params.h)) {
|
||||||
|
rooms.push($page.params.h)
|
||||||
|
}
|
||||||
|
|
||||||
const roomsKey = rooms.join(",")
|
const roomsKey = rooms.join(",")
|
||||||
|
|
||||||
if (unsubscribersByUrl.has(url) && roomsByUrl.get(url) === roomsKey) continue
|
if (unsubscribersByUrl.has(url) && roomsByUrl.get(url) === roomsKey) continue
|
||||||
|
|||||||
Reference in New Issue
Block a user