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"