diff --git a/src/app/components/GroupCompose.svelte b/src/app/components/GroupCompose.svelte
index 768796fd..b1318217 100644
--- a/src/app/components/GroupCompose.svelte
+++ b/src/app/components/GroupCompose.svelte
@@ -3,9 +3,9 @@
import type {Readable} from "svelte/store"
import {writable} from "svelte/store"
import {createEditor, type Editor, EditorContent} from "svelte-tiptap"
- import {NProfileExtension, ImageExtension} from "nostr-editor"
+ import {NProfileExtension, TagExtension as TopicExtension, ImageExtension} from "nostr-editor"
import {createEvent, CHAT_MESSAGE} from "@welshman/util"
- import {TopicExtension, findNodes} from "@lib/tiptap"
+ import {findNodes} from "@lib/tiptap"
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import {publishThunk, makeThunk, userRelayUrlsByNom} from "@app/state"
diff --git a/src/app/components/GroupComposeTopic.svelte b/src/app/components/GroupComposeTopic.svelte
index 6473659d..15b02752 100644
--- a/src/app/components/GroupComposeTopic.svelte
+++ b/src/app/components/GroupComposeTopic.svelte
@@ -11,8 +11,8 @@
- #{node.attrs.name}
+ #{node.attrs.topic}
diff --git a/src/app/editor.ts b/src/app/editor.ts
index b0fb57d8..2a93b81c 100644
--- a/src/app/editor.ts
+++ b/src/app/editor.ts
@@ -1,3 +1,4 @@
+import cx from 'classnames'
import type {Writable} from "svelte/store"
import {nprofileEncode} from "nostr-tools/nip19"
import {SvelteNodeViewRenderer} from "svelte-tiptap"
@@ -19,9 +20,10 @@ import {
ImageExtension,
VideoExtension,
FileUploadExtension,
+ TagExtension as TopicExtension,
} from "nostr-editor"
import type {StampedEvent} from "@welshman/util"
-import {LinkExtension, TopicExtension, asInline, createSuggestions} from "@lib/tiptap"
+import {LinkExtension, asInline, createSuggestions} from "@lib/tiptap"
import GroupComposeMention from "@app/components/GroupComposeMention.svelte"
import GroupComposeTopic from "@app/components/GroupComposeTopic.svelte"
import GroupComposeEvent from "@app/components/GroupComposeEvent.svelte"
@@ -113,6 +115,18 @@ export const getChatEditorOptions = ({uploading, sendMessage}: ChatComposeEditor
).configure({defaultUploadUrl: "https://nostr.build", defaultUploadType: "nip96"}),
TopicExtension.extend({
addNodeView: () => SvelteNodeViewRenderer(GroupComposeTopic),
+ renderHTML({mark, HTMLAttributes}) {
+ const attrs = {
+ ...mark.attrs,
+ ...HTMLAttributes,
+ target: '_blank',
+ rel: 'noopener noreferer',
+ href: `https://coracle.social/topics/${mark.attrs.tag.toLowerCase()}`,
+ class: "underline",
+ }
+
+ return ['a', attrs, 0]
+ },
addProseMirrorPlugins() {
return [
createSuggestions({
diff --git a/src/lib/tiptap/TopicExtension.ts b/src/lib/tiptap/TopicExtension.ts
deleted file mode 100644
index c1723783..00000000
--- a/src/lib/tiptap/TopicExtension.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import {Node, nodePasteRule} from "@tiptap/core"
-import type {Node as ProsemirrorNode} from "@tiptap/pm/model"
-import type {MarkdownSerializerState} from "prosemirror-markdown"
-import {createPasteRuleMatch} from "@lib/tiptap/util"
-
-export const TOPIC_REGEX = /(?:^|\s)(#[^\s]+)/g
-
-export interface TopicAttributes {
- name: string
-}
-
-declare module "@tiptap/core" {
- interface Commands {
- topic: {
- insertTopic: (options: {name: string}) => ReturnType
- }
- }
-}
-
-export const TopicExtension = Node.create({
- atom: true,
- name: "topic",
- group: "inline",
- inline: true,
- selectable: true,
- draggable: true,
- priority: 1000,
- addAttributes() {
- return {
- name: {default: null},
- }
- },
- renderText(props) {
- return "#" + props.node.attrs.name
- },
- addStorage() {
- return {
- markdown: {
- serialize(state: MarkdownSerializerState, node: ProsemirrorNode) {
- state.write(node.attrs.name)
- },
- parse: {},
- },
- }
- },
- addCommands() {
- return {
- insertTopic:
- ({name}) =>
- ({commands}) => {
- return commands.insertContent(
- {type: this.name, attrs: {name}},
- {
- updateSelection: false,
- },
- )
- },
- }
- },
- addPasteRules() {
- return [
- nodePasteRule({
- type: this.type,
- getAttributes: match => match.data,
- find: text => {
- const matches = []
-
- for (const match of text.matchAll(TOPIC_REGEX)) {
- try {
- matches.push(createPasteRuleMatch(match, {name: match[0]}))
- } catch (e) {
- continue
- }
- }
-
- return matches
- },
- }),
- ]
- },
-})
diff --git a/src/lib/tiptap/index.ts b/src/lib/tiptap/index.ts
index df36a2de..2394cc65 100644
--- a/src/lib/tiptap/index.ts
+++ b/src/lib/tiptap/index.ts
@@ -1,4 +1,3 @@
export * from "@lib/tiptap/util"
export {createSuggestions} from "@lib/tiptap/Suggestions"
-export {TopicExtension} from "@lib/tiptap/TopicExtension"
export {LinkExtension} from "@lib/tiptap/LinkExtension"