diff --git a/src/app/components/RoomChat.svelte b/src/app/components/RoomChat.svelte index 4d493909..096824c0 100644 --- a/src/app/components/RoomChat.svelte +++ b/src/app/components/RoomChat.svelte @@ -6,7 +6,7 @@ import type {Readable} from "svelte/store" import {debounce} from "throttle-debounce" import cx from "classnames" - import {now, ifLet, int, formatTimestampAsDate, ago, MINUTE} from "@welshman/lib" + import {now, ifLet, ago, MINUTE} from "@welshman/lib" import type {Maybe} from "@welshman/lib" import type {TrustedEvent, EventContent} from "@welshman/util" import {makeEvent, MESSAGE, RELAY_ADD_MEMBER, ROOM_ADD_MEMBER} from "@welshman/util" @@ -40,6 +40,7 @@ RoomType, deriveUserRoomMembershipStatus, getRoomType, + groupRoomMessages, prependParent, } from "@app/rooms" import {userSettingsValues} from "@app/settings" @@ -236,9 +237,6 @@ const getElementKey = (element: {id: string}) => element.id - // The list renders from the newest message outward, so a row deep in history isn't on the page - // until it's asked for — and asking renders it on the next flush, which the lookup has to wait - // for. Messages carry the id as a data attribute; the new-messages divider as its element id. // Where a row sits inside the scroll container, in screen terms rather than scroll terms, so // the reversed layout doesn't come into it const topOf = (target: HTMLElement) => @@ -266,6 +264,9 @@ pinned = undefined } + // The list renders from the newest message outward, so a row deep in history isn't on the page + // until it's asked for — and asking renders it on the next flush, which the lookup has to wait + // for. Messages carry the id as a data attribute; the new-messages divider as its element id. const scrollToRow = ( id: string, { @@ -421,71 +422,15 @@ isUserScrolling = false }) - const elements = $derived.by(() => { - const elements = [] - const seen = new Set() - - let previousDate - let previousKind - let previousPubkey - let previousCreatedAt = 0 - let newMessagesSeen = false - - if (events) { - const lastUserEvent = $events.findLast(e => e.pubkey === $user.pubkey) - - // Adjust the boundary to account for messages that came from a different device - const adjustedAfter = - newMessagesAfter && lastUserEvent - ? Math.max(lastUserEvent.created_at, newMessagesAfter) - : newMessagesAfter - - for (const event of $events) { - if (seen.has(event.id)) { - continue - } - - const date = formatTimestampAsDate(event.created_at) - - if ( - !newMessagesSeen && - adjustedAfter && - event.pubkey !== $user.pubkey && - event.created_at > adjustedAfter && - event.created_at < newMessagesBefore - ) { - elements.push({type: "new-messages", id: "new-messages"}) - newMessagesSeen = true - } - - if (date !== previousDate) { - elements.push({type: "date", value: date, id: date, showPubkey: false}) - } - - const showPubkey = - previousPubkey !== event.pubkey || - event.created_at - previousCreatedAt > int(3, MINUTE) || - previousKind === addMemberKind - - elements.push({ - id: event.id, - type: "note", - value: event, - showPubkey, - }) - - previousDate = date - previousKind = event.kind - previousPubkey = event.pubkey - previousCreatedAt = event.created_at - seen.add(event.id) - } - } - - elements.reverse() - - return elements - }) + const elements = $derived( + groupRoomMessages({ + events: $events, + pubkey: $user.pubkey, + addMemberKind, + unreadAfter: newMessagesAfter, + unreadBefore: newMessagesBefore, + }), + ) // Newer messages are only worth waiting for when the window stops short of the present, which // only happens after jumping into history — anything published from here on arrives through the @@ -586,6 +531,24 @@ }) +{#snippet membershipButton(label: string)} + {#if $membershipStatus === MembershipStatus.Pending} + + {:else} + + {/if} +{/snippet} +
You aren't currently a member of this room.
- {#if $membershipStatus === MembershipStatus.Pending} - - {:else} - - {/if} + {@render membershipButton("Join Room")}Only members are allowed to post to this room.
- {#if $membershipStatus === MembershipStatus.Pending} - - {:else} - - {/if} + {@render membershipButton("Ask to Join")}