Replace svelte components with node views

This commit is contained in:
Jon Staab
2025-02-04 20:00:19 -08:00
parent 506276f594
commit fd99866b1e
16 changed files with 129 additions and 91 deletions
-20
View File
@@ -1,20 +0,0 @@
<script lang="ts">
import type {NodeViewProps} from "@tiptap/core"
import {NodeViewWrapper} from "svelte-tiptap"
import {deriveProfileDisplay} from "@welshman/app"
interface Props {
node: NodeViewProps["node"]
selected: NodeViewProps["selected"]
}
const {node, selected}: Props = $props()
const display = deriveProfileDisplay(node.attrs.pubkey)
</script>
<NodeViewWrapper as="span">
<button class="tiptap-object {selected ? 'tiptap-active' : ''}">
@{$display}
</button>
</NodeViewWrapper>
+26
View File
@@ -0,0 +1,26 @@
import type {NodeViewProps} from '@tiptap/core'
import {deriveProfileDisplay} from "@welshman/app"
export const MentionNodeView = ({node}: NodeViewProps) => {
const dom = document.createElement('span')
const display = deriveProfileDisplay(node.attrs.pubkey)
dom.classList.add('tiptap-object')
const unsubDisplay = display.subscribe($display => {
dom.textContent = '@' + $display
})
return {
dom,
destroy: () => {
unsubDisplay()
},
selectNode() {
dom.classList.add('tiptap-active')
},
deselectNode() {
dom.classList.remove('tiptap-active')
},
}
}
+3 -4
View File
@@ -1,15 +1,14 @@
import {asClassComponent} from "svelte/legacy"
import {mount} from "svelte"
import type {Writable} from "svelte/store"
import {get} from "svelte/store"
import {Editor, SvelteNodeViewRenderer} from "svelte-tiptap"
import {Editor} from "@tiptap/core"
import {ctx} from "@welshman/lib"
import type {StampedEvent} from "@welshman/util"
import {signer, profileSearch} from "@welshman/app"
import {MentionSuggestion, WelshmanExtension} from "@lib/editor"
import {getSetting, userSettingValues} from "@app/state"
import {MentionNodeView} from "./MentionNodeView"
import ProfileSuggestion from "./ProfileSuggestion.svelte"
import EditMention from "./EditMention.svelte"
export const getUploadType = () => getSetting<"nip96" | "blossom">("upload_type")
@@ -78,7 +77,7 @@ export const makeEditor = ({
},
nprofile: {
extend: {
addNodeView: () => SvelteNodeViewRenderer(asClassComponent(EditMention)),
addNodeView: () => MentionNodeView,
addProseMirrorPlugins() {
return [
MentionSuggestion({
@@ -1,13 +0,0 @@
<script lang="ts">
import type {NodeViewProps} from "@tiptap/core"
import {NodeViewWrapper} from "svelte-tiptap"
export let node: NodeViewProps["node"]
export let selected: NodeViewProps["selected"]
</script>
<NodeViewWrapper as="span">
<button class="tiptap-object {selected ? 'tiptap-active' : ''}">
{node.attrs.lnbc.slice(0, 16)}...
</button>
</NodeViewWrapper>
@@ -1,14 +0,0 @@
<script lang="ts">
import {fromNostrURI} from "@welshman/util"
import type {NodeViewProps} from "@tiptap/core"
import {NodeViewWrapper} from "svelte-tiptap"
export let node: NodeViewProps["node"]
export let selected: NodeViewProps["selected"]
</script>
<NodeViewWrapper as="span">
<button class="tiptap-object {selected ? 'tiptap-active' : ''}">
{fromNostrURI(node.attrs.bech32).slice(0, 16)}...
</button>
</NodeViewWrapper>
@@ -1,14 +0,0 @@
<script lang="ts">
import type {NodeViewProps} from "@tiptap/core"
import {NodeViewWrapper} from "svelte-tiptap"
export let node: NodeViewProps["node"]
export let selected: NodeViewProps["selected"]
$: selectedClass = selected ? "tiptap-active" : ""
$: uploadingClass = node.attrs.uploading ? "tiptap-uploading" : ""
</script>
<NodeViewWrapper as="span" class="tiptap-object {selectedClass} {uploadingClass}">
{node.attrs.file?.name || node.attrs.src}
</NodeViewWrapper>
@@ -1,13 +0,0 @@
<script lang="ts">
import type {NodeViewProps} from "@tiptap/core"
import {NodeViewWrapper} from "svelte-tiptap"
export let node: NodeViewProps["node"]
export let selected: NodeViewProps["selected"]
</script>
<NodeViewWrapper as="span">
<button class="tiptap-object {selected ? 'tiptap-active' : ''}">
@{node.attrs.bech32.slice(0, 16)}...
</button>
</NodeViewWrapper>
-4
View File
@@ -1,4 +0,0 @@
export {default as EditBolt11} from "./EditBolt11.svelte"
export {default as EditMedia} from "./EditMedia.svelte"
export {default as EditEvent} from "./EditEvent.svelte"
export {default as EditMention} from "./EditMention.svelte"
+7 -8
View File
@@ -1,6 +1,5 @@
import type {StampedEvent, SignedEvent} from "@welshman/util"
import {deepMergeLeft} from "@welshman/lib"
import {SvelteNodeViewRenderer} from "svelte-tiptap"
import type {Extensions, AnyExtension} from "@tiptap/core"
import {CodeBlock} from "@tiptap/extension-code-block"
import type {CodeBlockOptions} from "@tiptap/extension-code-block"
@@ -38,7 +37,7 @@ import {
import {WordCount} from "./WordCount.js"
import {CodeInline, type CodeInlineOptions} from "./CodeInline.js"
import {BreakOrSubmit, type BreakOrSubmitOptions} from "./BreakOrSubmit.js"
import {EditBolt11, EditMedia, EditEvent, EditMention} from "../components/index.js"
import {MentionNodeView, Bolt11NodeView, MediaNodeView, EventNodeView} from "../nodeviews/index.js"
export type ChildExtensionOptions<C = any, E = any> =
| false
@@ -115,7 +114,7 @@ export const WelshmanExtension = NostrExtension.extend<WelshmanOptions>({
group: "inline",
},
extend: {
addNodeView: () => SvelteNodeViewRenderer(EditBolt11),
addNodeView: () => Bolt11NodeView,
},
},
image: {
@@ -126,7 +125,7 @@ export const WelshmanExtension = NostrExtension.extend<WelshmanOptions>({
defaultUploadType,
},
extend: {
addNodeView: () => SvelteNodeViewRenderer(EditMedia),
addNodeView: () => MediaNodeView,
},
},
video: {
@@ -137,7 +136,7 @@ export const WelshmanExtension = NostrExtension.extend<WelshmanOptions>({
defaultUploadType,
},
extend: {
addNodeView: () => SvelteNodeViewRenderer(EditMedia),
addNodeView: () => MediaNodeView,
},
},
nevent: {
@@ -146,7 +145,7 @@ export const WelshmanExtension = NostrExtension.extend<WelshmanOptions>({
group: "inline",
},
extend: {
addNodeView: () => SvelteNodeViewRenderer(EditEvent),
addNodeView: () => EventNodeView,
},
},
naddr: {
@@ -155,12 +154,12 @@ export const WelshmanExtension = NostrExtension.extend<WelshmanOptions>({
group: "inline",
},
extend: {
addNodeView: () => SvelteNodeViewRenderer(EditEvent),
addNodeView: () => EventNodeView,
},
},
nprofile: {
extend: {
addNodeView: () => SvelteNodeViewRenderer(EditMention),
addNodeView: () => MentionNodeView,
},
},
breakOrSubmit: {
+1 -1
View File
@@ -1,5 +1,5 @@
import "./index.css"
export * from "./components/index.js"
export * from "./nodeviews/index.js"
export * from "./extensions/index.js"
export * from "./plugins/index.js"
@@ -0,0 +1,18 @@
import type {NodeViewProps} from '@tiptap/core'
export const Bolt11NodeView = ({node}: NodeViewProps) => {
const dom = document.createElement('span')
dom.classList.add('tiptap-object')
dom.innerText = `${node.attrs.lnbc.slice(0, 16)}...`
return {
dom,
selectNode() {
dom.classList.add('tiptap-active')
},
deselectNode() {
dom.classList.remove('tiptap-active')
},
}
}
+19
View File
@@ -0,0 +1,19 @@
import type {NodeViewProps} from '@tiptap/core'
import {fromNostrURI} from "@welshman/util"
export const EventNodeView = ({node}: NodeViewProps) => {
const dom = document.createElement('span')
dom.classList.add('tiptap-object')
dom.innerText = `${fromNostrURI(node.attrs.bech32).slice(0, 16)}...`
return {
dom,
selectNode() {
dom.classList.add('tiptap-active')
},
deselectNode() {
dom.classList.remove('tiptap-active')
},
}
}
+32
View File
@@ -0,0 +1,32 @@
import type {Node, NodeViewProps} from '@tiptap/core'
import {fromNostrURI} from "@welshman/util"
export const MediaNodeView = ({node}: NodeViewProps) => {
const dom = document.createElement('span')
const syncUploading = (node: NodeViewProps['node']) => {
if (node.attrs.uploading) {
dom.classList.add('tiptap-uploading')
} else {
dom.classList.remove('tiptap-uploading')
}
}
dom.classList.add('tiptap-object')
dom.innerText = node.attrs.file?.name || node.attrs.src
syncUploading(node)
return {
dom,
update(node: NodeViewProps['node']) {
syncUploading(node)
},
selectNode() {
dom.classList.add('tiptap-active')
},
deselectNode() {
dom.classList.remove('tiptap-active')
},
}
}
@@ -0,0 +1,18 @@
import type {NodeViewProps} from '@tiptap/core'
export const MentionNodeView = ({node}: NodeViewProps) => {
const dom = document.createElement('span')
dom.classList.add('tiptap-object')
dom.textContent = `@${node.attrs.bech32.slice(0, 16)}...`
return {
dom,
selectNode() {
dom.classList.add('tiptap-active')
},
deselectNode() {
dom.classList.remove('tiptap-active')
},
}
}
+4
View File
@@ -0,0 +1,4 @@
export * from './MentionNodeView.js'
export * from './Bolt11NodeView.js'
export * from './EventNodeView.js'
export * from './MediaNodeView.js'
@@ -127,6 +127,7 @@ export class DefaultSuggestionsWrapper implements ISuggestionsWrapper {
setProps(props: SuggestionsWrapperProps) {
this.props = props
this.search()
this.render()
}