flotilla/src/app/editor/index.ts

111 lines
3 KiB
TypeScript
Raw Normal View History

2025-02-05 03:00:48 +00:00
import {mount} from "svelte"
2025-01-02 18:04:28 +00:00
import type {Writable} from "svelte/store"
2025-02-05 03:00:48 +00:00
import {get} from "svelte/store"
2025-01-02 18:04:28 +00:00
import type {StampedEvent} from "@welshman/util"
2025-06-02 23:33:55 +00:00
import {getTagValues, getListTags} from "@welshman/util"
import {Router} from "@welshman/router"
import {signer, profileSearch, userBlossomServers} from "@welshman/app"
2025-04-09 22:32:18 +00:00
import {Editor, MentionSuggestion, WelshmanExtension} from "@welshman/editor"
2025-04-15 18:03:27 +00:00
import {makeMentionNodeView} from "./MentionNodeView"
2025-01-02 18:04:28 +00:00
import ProfileSuggestion from "./ProfileSuggestion.svelte"
2025-06-02 23:33:55 +00:00
export const getUploadUrl = () => {
const userUrls = getTagValues("server", getListTags(userBlossomServers.get()))
2025-06-02 23:33:55 +00:00
for (const url of userUrls) {
return url.replace(/^ws/, "http")
}
return "https://cdn.satellite.earth"
}
2025-01-02 18:04:28 +00:00
export const signWithAssert = async (template: StampedEvent) => {
const event = await signer.get().sign(template)
return event!
}
export const makeEditor = async ({
2025-01-17 23:01:05 +00:00
aggressive = false,
2025-01-02 18:04:28 +00:00
autofocus = false,
charCount,
content = "",
placeholder = "",
2025-04-15 18:03:27 +00:00
url,
2025-01-02 18:04:28 +00:00
submit,
uploading,
wordCount,
}: {
2025-01-17 23:01:05 +00:00
aggressive?: boolean
2025-01-02 18:04:28 +00:00
autofocus?: boolean
charCount?: Writable<number>
content?: string
placeholder?: string
2025-04-15 18:03:27 +00:00
url?: string
2025-01-02 18:04:28 +00:00
submit: () => void
uploading?: Writable<boolean>
wordCount?: Writable<number>
}) => {
return new Editor({
2025-01-02 18:04:28 +00:00
content,
autofocus,
2025-02-05 18:47:56 +00:00
element: document.createElement("div"),
2025-01-02 18:04:28 +00:00
extensions: [
WelshmanExtension.configure({
submit,
sign: signWithAssert,
defaultUploadType: "blossom",
2025-06-02 23:33:55 +00:00
defaultUploadUrl: getUploadUrl(),
2025-01-02 18:04:28 +00:00
extensions: {
placeholder: {
config: {
placeholder,
},
},
2025-01-17 23:01:05 +00:00
breakOrSubmit: {
config: {
aggressive,
},
},
2025-06-03 17:41:38 +00:00
fileUpload: {
config: {
encryptionAlgorithm: "aes-gcm",
onDrop() {
uploading?.set(true)
},
onComplete() {
uploading?.set(false)
2025-01-02 18:04:28 +00:00
},
2025-06-03 17:41:38 +00:00
},
},
2025-01-02 18:04:28 +00:00
nprofile: {
extend: {
2025-04-15 18:03:27 +00:00
addNodeView: () => makeMentionNodeView(url),
2025-01-02 18:04:28 +00:00
addProseMirrorPlugins() {
return [
MentionSuggestion({
editor: (this as any).editor,
2025-02-05 03:00:48 +00:00
search: (term: string) => get(profileSearch).searchValues(term),
2025-04-09 22:32:18 +00:00
getRelays: (pubkey: string) => Router.get().FromPubkeys([pubkey]).getUrls(),
2025-02-05 03:37:59 +00:00
createSuggestion: (value: string) => {
2025-02-05 03:00:48 +00:00
const target = document.createElement("div")
2025-04-15 18:03:27 +00:00
mount(ProfileSuggestion, {target, props: {value, url}})
2025-02-05 03:00:48 +00:00
return target
},
2025-01-02 18:04:28 +00:00
}),
]
},
},
},
},
}),
],
onUpdate({editor}) {
wordCount?.set(editor.storage.wordCount.words)
charCount?.set(editor.storage.wordCount.chars)
},
})
}