mirror of
https://github.com/coracle-social/flotilla.git
synced 2025-12-10 10:57:04 +00:00
Create new EditorContent component
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import {onMount, onDestroy} from "svelte"
|
||||
import {writable} from "svelte/store"
|
||||
import {EditorContent} from "svelte-tiptap"
|
||||
import {isMobile, preventDefault} from "@lib/html"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import EditorContent from "@lib/components/EditorContent.svelte"
|
||||
import {makeEditor} from "@app/editor"
|
||||
|
||||
interface Props {
|
||||
@@ -14,29 +14,35 @@
|
||||
|
||||
const {onSubmit, content = ""}: Props = $props()
|
||||
|
||||
export const focus = () => $editor.chain().focus().run()
|
||||
const autofocus = !isMobile
|
||||
|
||||
const uploading = writable(false)
|
||||
|
||||
const uploadFiles = () => $editor!.chain().selectFiles().run()
|
||||
export const focus = () => editor.chain().focus().run()
|
||||
|
||||
const uploadFiles = () => editor.chain().selectFiles().run()
|
||||
|
||||
const submit = () => {
|
||||
if ($uploading) return
|
||||
|
||||
const content = $editor!.getText({blockSeparator: "\n"}).trim()
|
||||
const tags = $editor!.storage.nostr.getEditorTags()
|
||||
const content = editor.getText({blockSeparator: "\n"}).trim()
|
||||
const tags = editor.storage.nostr.getEditorTags()
|
||||
|
||||
if (!content) return
|
||||
|
||||
onSubmit({content, tags})
|
||||
|
||||
$editor!.chain().clearContent().run()
|
||||
editor.chain().clearContent().run()
|
||||
}
|
||||
|
||||
const editor = makeEditor({autofocus: !isMobile, submit, uploading, aggressive: true})
|
||||
const editor = makeEditor({autofocus, submit, uploading, aggressive: true})
|
||||
|
||||
onMount(() => {
|
||||
$editor!.chain().setContent(content).run()
|
||||
editor.chain().setContent(content).run()
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
editor.destroy()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -53,7 +59,7 @@
|
||||
{/if}
|
||||
</Button>
|
||||
<div class="chat-editor flex-grow overflow-hidden">
|
||||
<EditorContent editor={$editor} />
|
||||
<EditorContent {editor} />
|
||||
</div>
|
||||
<Button
|
||||
data-tip="{window.navigator.platform.includes('Mac') ? 'cmd' : 'ctrl'}+enter to send"
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
const {url, event} = $props()
|
||||
|
||||
const confirm = async () => {
|
||||
await publishDelete({event, relays: [url]})
|
||||
const snapshot = $state.snapshot(event)
|
||||
|
||||
await publishDelete({event: snapshot, relays: [url]})
|
||||
|
||||
clearModals()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import {EditorContent} from "svelte-tiptap"
|
||||
import {writable} from "svelte/store"
|
||||
import {randomId} from "@welshman/lib"
|
||||
import {createEvent, EVENT_TIME} from "@welshman/util"
|
||||
@@ -11,6 +10,7 @@
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import DateTimeInput from "@lib/components/DateTimeInput.svelte"
|
||||
import EditorContent from "@lib/components/EditorContent.svelte"
|
||||
import {PROTECTED} from "@app/state"
|
||||
import {makeEditor} from "@app/editor"
|
||||
import {pushToast} from "@app/toast"
|
||||
@@ -39,14 +39,14 @@
|
||||
}
|
||||
|
||||
const event = createEvent(EVENT_TIME, {
|
||||
content: $editor.getText({blockSeparator: "\n"}).trim(),
|
||||
content: editor.getText({blockSeparator: "\n"}).trim(),
|
||||
tags: [
|
||||
["d", randomId()],
|
||||
["title", title],
|
||||
["location", location],
|
||||
["start", dateToSeconds(start).toString()],
|
||||
["end", dateToSeconds(end).toString()],
|
||||
...$editor.storage.nostr.getEditorTags(),
|
||||
...editor.storage.nostr.getEditorTags(),
|
||||
PROTECTED,
|
||||
],
|
||||
})
|
||||
@@ -89,12 +89,12 @@
|
||||
{#snippet input()}
|
||||
<div class="relative z-feature flex gap-2 border-t border-solid border-base-100 bg-base-100">
|
||||
<div class="input-editor flex-grow overflow-hidden">
|
||||
<EditorContent editor={$editor} />
|
||||
<EditorContent {editor} />
|
||||
</div>
|
||||
<Button
|
||||
data-tip="Add an image"
|
||||
class="center btn tooltip"
|
||||
onclick={() => $editor.chain().selectFiles().run()}>
|
||||
onclick={() => editor.chain().selectFiles().run()}>
|
||||
{#if $uploading}
|
||||
<span class="loading loading-spinner loading-xs"></span>
|
||||
{:else}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import {writable} from "svelte/store"
|
||||
import {EditorContent} from "svelte-tiptap"
|
||||
import {createEvent, THREAD} from "@welshman/util"
|
||||
import {publishThunk} from "@welshman/app"
|
||||
import {isMobile, preventDefault} from "@lib/html"
|
||||
@@ -9,6 +8,7 @@
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import EditorContent from "@lib/components/EditorContent.svelte"
|
||||
import {pushToast} from "@app/toast"
|
||||
import {GENERAL, tagRoom, PROTECTED} from "@app/state"
|
||||
import {makeEditor} from "@app/editor"
|
||||
@@ -29,7 +29,7 @@
|
||||
})
|
||||
}
|
||||
|
||||
const content = $editor.getText({blockSeparator: "\n"}).trim()
|
||||
const content = editor.getText({blockSeparator: "\n"}).trim()
|
||||
|
||||
if (!content.trim()) {
|
||||
return pushToast({
|
||||
@@ -39,7 +39,7 @@
|
||||
}
|
||||
|
||||
const tags = [
|
||||
...$editor.storage.nostr.getEditorTags(),
|
||||
...editor.storage.nostr.getEditorTags(),
|
||||
tagRoom(GENERAL, url),
|
||||
["title", title],
|
||||
PROTECTED,
|
||||
@@ -90,14 +90,14 @@
|
||||
{/snippet}
|
||||
{#snippet input()}
|
||||
<div class="note-editor flex-grow overflow-hidden">
|
||||
<EditorContent editor={$editor} />
|
||||
<EditorContent {editor} />
|
||||
</div>
|
||||
{/snippet}
|
||||
</Field>
|
||||
<Button
|
||||
data-tip="Add an image"
|
||||
class="tooltip tooltip-left absolute bottom-1 right-2"
|
||||
onclick={$editor.commands.selectFiles}>
|
||||
onclick={editor.commands.selectFiles}>
|
||||
{#if $uploading}
|
||||
<span class="loading loading-spinner loading-xs"></span>
|
||||
{:else}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script lang="ts">
|
||||
import {writable} from "svelte/store"
|
||||
import {EditorContent} from "svelte-tiptap"
|
||||
import {isMobile, preventDefault} from "@lib/html"
|
||||
import {fly, slideAndFade} from "@lib/transition"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import EditorContent from "@lib/components/EditorContent.svelte"
|
||||
import {publishComment} from "@app/commands"
|
||||
import {tagRoom, GENERAL, PROTECTED} from "@app/state"
|
||||
import {makeEditor} from "@app/editor"
|
||||
@@ -18,8 +18,8 @@
|
||||
const submit = () => {
|
||||
if ($uploading) return
|
||||
|
||||
const content = $editor.getText({blockSeparator: "\n"}).trim()
|
||||
const tags = [...$editor.storage.nostr.getEditorTags(), tagRoom(GENERAL, url), PROTECTED]
|
||||
const content = editor.getText({blockSeparator: "\n"}).trim()
|
||||
const tags = [...editor.storage.nostr.getEditorTags(), tagRoom(GENERAL, url), PROTECTED]
|
||||
|
||||
if (!content) {
|
||||
return pushToast({
|
||||
@@ -41,12 +41,12 @@
|
||||
class="card2 sticky bottom-2 z-feature mx-2 mt-4 bg-neutral">
|
||||
<div class="relative">
|
||||
<div class="note-editor flex-grow overflow-hidden">
|
||||
<EditorContent editor={$editor} />
|
||||
<EditorContent {editor} />
|
||||
</div>
|
||||
<Button
|
||||
data-tip="Add an image"
|
||||
class="tooltip tooltip-left absolute bottom-1 right-2"
|
||||
onclick={$editor.commands.selectFiles}>
|
||||
onclick={editor.commands.selectFiles}>
|
||||
{#if $uploading}
|
||||
<span class="loading loading-spinner loading-xs"></span>
|
||||
{:else}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {asClassComponent} from "svelte/legacy"
|
||||
import type {Writable} from "svelte/store"
|
||||
import {derived, readable} from "svelte/store"
|
||||
import {derived} from "svelte/store"
|
||||
import {Editor, SvelteNodeViewRenderer} from "svelte-tiptap"
|
||||
import {ctx} from "@welshman/lib"
|
||||
import type {StampedEvent} from "@welshman/util"
|
||||
@@ -44,10 +44,8 @@ export const makeEditor = ({
|
||||
submit: () => void
|
||||
uploading?: Writable<boolean>
|
||||
wordCount?: Writable<number>
|
||||
}) => {
|
||||
let setter: (editor: Editor) => void
|
||||
|
||||
const _editor = new Editor({
|
||||
}) =>
|
||||
new Editor({
|
||||
content,
|
||||
autofocus,
|
||||
extensions: [
|
||||
@@ -96,15 +94,7 @@ export const makeEditor = ({
|
||||
}),
|
||||
],
|
||||
onUpdate({editor}) {
|
||||
setter?.(editor)
|
||||
wordCount?.set(editor.storage.wordCount.words)
|
||||
charCount?.set(editor.storage.wordCount.chars)
|
||||
},
|
||||
})
|
||||
|
||||
return readable(_editor, set => {
|
||||
setter = set
|
||||
|
||||
return () => _editor.destroy()
|
||||
})
|
||||
}
|
||||
|
||||
22
src/lib/components/EditorContent.svelte
Normal file
22
src/lib/components/EditorContent.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<script lang="ts">
|
||||
import {onDestroy, onMount} from "svelte"
|
||||
|
||||
const {editor} = $props()
|
||||
|
||||
let element: HTMLElement
|
||||
|
||||
onMount(() => {
|
||||
if (element) {
|
||||
element.append(...(Array.from(editor.options.element.childNodes) as any))
|
||||
editor.setOptions({element})
|
||||
editor.contentElement = element
|
||||
}
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
editor.contentElement = null
|
||||
editor.setOptions({element: null})
|
||||
})
|
||||
</script>
|
||||
|
||||
<div bind:this={element}></div>
|
||||
Reference in New Issue
Block a user