diff --git a/src/app/actionItems.ts b/src/app/actionItems.ts index bd551bd4..d2c254c1 100644 --- a/src/app/actionItems.ts +++ b/src/app/actionItems.ts @@ -1,111 +1,12 @@ import {derived} from "svelte/store" -import {first, groupBy, removeUndefined, spec} from "@welshman/lib" -import { - REPORT, - ROOM_ADD_MEMBER, - ROOM_JOIN, - ROOM_LEAVE, - ROOM_MEMBERS, - ROOM_REMOVE_MEMBER, - hexTags, - sortEventsAsc, - sortEventsDesc, - tagSpec, - tagValue, - tagValues, -} from "@welshman/util" -import type {TrustedEvent} from "@welshman/util" +import {REPORT, sortEventsDesc} from "@welshman/util" +import {rooms} from "@app/core" import {deriveEventsForUrl} from "@app/repository" -// A room's membership replayed in order — each member list is a snapshot that resets -// the set, with add/remove events applied on top. -const getRoomMembers = (events: TrustedEvent[]) => { - const members = new Set() - - for (const event of sortEventsAsc(events)) { - const pubkeys = tagValues(hexTags("p"), event.tags) - - if (event.kind === ROOM_MEMBERS) { - members.clear() - pubkeys.forEach(pubkey => members.add(pubkey)) - } else if (event.kind === ROOM_ADD_MEMBER) { - pubkeys.forEach(pubkey => members.add(pubkey)) - } else if (event.kind === ROOM_REMOVE_MEMBER) { - pubkeys.forEach(pubkey => members.delete(pubkey)) - } - } - - return members -} - // Action items (admin review queue) export const deriveSpaceActionItems = (url: string) => derived( - deriveEventsForUrl(url, [ - {kinds: [REPORT, ROOM_JOIN, ROOM_LEAVE, ROOM_MEMBERS, ROOM_ADD_MEMBER, ROOM_REMOVE_MEMBER]}, - ]), - $events => { - const getRoomId = (e: TrustedEvent) => - tagValue(tagSpec(e.kind === ROOM_MEMBERS ? "d" : "h"), e.tags) - const reports = $events.filter(spec({kind: REPORT})) - const pendingJoins: TrustedEvent[] = [] - - // Room-level join requests — most recent per pubkey+h - for (const [h, roomEvents] of groupBy(getRoomId, $events)) { - if (!h) continue - - const roomJoins: TrustedEvent[] = [] - const roomLeaves: TrustedEvent[] = [] - const roomMembershipEvents: TrustedEvent[] = [] - - for (const event of roomEvents) { - switch (event.kind) { - case ROOM_JOIN: - roomJoins.push(event) - break - case ROOM_LEAVE: - roomLeaves.push(event) - break - case ROOM_MEMBERS: - case ROOM_ADD_MEMBER: - case ROOM_REMOVE_MEMBER: - roomMembershipEvents.push(event) - break - } - } - - const roomMembers = getRoomMembers(roomMembershipEvents) - - pendingJoins.push( - ...removeUndefined( - Array.from(groupBy(e => e.pubkey, roomJoins).values()).map(events => - first(sortEventsDesc(events)), - ), - ).filter(({pubkey, created_at}) => { - if (roomMembers.has(pubkey)) return false - if ( - roomMembershipEvents.some(event => { - if (event.created_at <= created_at) { - return false - } - - if (event.kind === ROOM_MEMBERS) { - return true - } - - return tagValues(hexTags("p"), event.tags).includes(pubkey) - }) - ) { - return false - } - if (roomLeaves.some(e => e.pubkey === pubkey && e.created_at > created_at)) return false - - return true - }), - ) - } - - return sortEventsDesc([...reports, ...pendingJoins]) - }, + [deriveEventsForUrl(url, [{kinds: [REPORT]}]), rooms.get().pendingJoins(url).$], + ([$reports, $pendingJoins]) => sortEventsDesc([...$reports, ...$pendingJoins]), ) diff --git a/src/app/components/ThreadBoardItem.svelte b/src/app/components/ThreadBoardItem.svelte index 7871d80f..f55b67cf 100644 --- a/src/app/components/ThreadBoardItem.svelte +++ b/src/app/components/ThreadBoardItem.svelte @@ -4,7 +4,7 @@ import type {TrustedEvent} from "@welshman/util" import {COMMENT, tagSpec, tagValue} from "@welshman/util" import {fade} from "@lib/transition" - import Link from '@lib/components/Link.svelte' + import Link from "@lib/components/Link.svelte" import ProfileCircle from "@app/components/ProfileCircle.svelte" import ProfileName from "@app/components/ProfileName.svelte" import {deriveEventsForUrl} from "@app/repository" @@ -27,7 +27,6 @@ const path = makeThreadPath(url, event.id) const onClick = () => goto(path) // notification={$notifications.has(path)} - {#if mobile}