feat: implement room and space mentions (#130) #154
Reference in New Issue
Block a user
Delete Branch "Khushvendra/flotilla:feat/room-mentions-130"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
This PR introduces first-class support for Room and Space mentions (Issue #130), mirroring the existing pubkey mentions behavior. It adds full rich-text editor integration via Tiptap, content parsing for display, and supporting unit tests.
Users can now type
~anywhere in the compose menu to trigger a room suggestion search overlay, which securely references NIP-29 rooms using therelay_url'room_idformat and renders appropriately across the application.Resolves #130.
Changes Included
RoomReferenceExtensionandRoomReferenceNodeViewto safely encode room mentions into therelay_url'room_idreference format.roomReferenceSearchineditor/index.tsto power the suggestion menu (RoomSuggestion.svelte) using a~char trigger, making use ofroomsByUrlanduserSpaceUrls.lib/content-text.ts) that correctly pulls apartwss://text sequences intorelay,room, ortexttypes, elegantly separating trailing punctuations.Content.svelteandContentMinimal.svelteto route valid parsed segments intoContentText.svelte.roominstances (navigating to the specific room) andrelayinstances (navigating to the overarching space).vitestto support rigorous module testing.tests/content-text.test.tsto validate proper regex extraction of relays and room combinations.Validation
pnpm run check) and linter pass seamlessly.vitest runonparseContentTextPartsensuring trailing commas/parentheses don't break clickable references.~successfully initiates the mention menu with responsive rendering.This looks quite good, the only thing I noticed is the rendering code never gets called because the room identifier includes a relay, which in turn gets parsed as a url. Which is actually nice, because you can remove the ContentText component and parser entirely and move the rendering logic into the various ContentLink* components
@hodlbod Should i keep that as a feature? Or try to implement a fix?
Yes, please go ahead and remove the rendering changes and just make the adjustments to the link renderer.
@@ -17,0 +31,4 @@}return {url: normalizeRelayUrl(roomUrl), h}}I think we can live dangerously here by adding
isRoomIdto core/state which just checks for an apostrophe, and usesplitRoomIdfrom that same file.@@ -52,0 +74,4 @@{:else if roomReference || relayReference}<div class="bg-alt p-4 leading-normal"><Icon icon={LinkRound} size={3} class="inline-block" /><span class="ml-2">{displayUrl(url)}</span>We should display url/h more helpfully. In either case, prefix with a tilde. Display the url as the space name, and if an
his included append it after the slash, like this:~Coracle Spaces / Design. Make the same change to the edit interface as well.@@ -0,0 +13,4 @@<div class="flex max-w-full flex-col gap-1"><div class="overflow-hidden text-ellipsis text-base font-semibold">~{$room.name || h}</div><div class="overflow-hidden text-ellipsis text-sm opacity-75">{displayRelayUrl(url)}'{h}</div>This should be displayed the same way we'll ultimately render it, as
~Space Name / Room Name@@ -85,0 +102,4 @@name: room.name || "",h: room.h,url: roomUrl,})I think we can safely use
RoomMetaas the type here rather than using an ad-hoc onePlease go ahead and rebase on dev to fix conflicts.
Looks like some new conflicts have cropped up, can you rebase and fix those too?
0c40be9cfcto540e9abe3d@@ -16,0 +54,4 @@}return displayUrl(url)})Let's refactor this a bit. Go ahead and add a new component called
ContentLinkUrlthat encapsulates this logic and is used in both inline and block contexts. In the block case you'll still need to detect whether the url is a room or relay, but that should be as simple asisRoomId(url) || isRelayUrl(url)Looks pretty good, just one comment.
One small change
@@ -90,0 +56,4 @@showIconlabelClass="ml-2" />{:else}<ContentLinkUrl {url} class="my-2 block">It doesn't make sense to use ContentLinkUrl in this case since because we're providing our own content, it's doing basically nothing. Remove the children and showIcon props from ContentLinkUrl. You can might be able to remove the labelClass as well, not sure.
Merged via
ec0b6a99Pull request closed