mirror of
https://github.com/linsa-io/linsa.git
synced 2026-01-12 12:20:23 +01:00
chore: Enhancement + New Feature (#185)
* wip * wip page * chore: style * wip pages * wip pages * chore: toggle * chore: link * feat: topic search * chore: page section * refactor: apply tailwind class ordering * fix: handle loggedIn user for guest route * feat: folder & image schema * chore: move utils to shared * refactor: tailwind class ordering * feat: img ext for editor * refactor: remove qa * fix: tanstack start * fix: wrong import * chore: use toast * chore: schema
This commit is contained in:
116
web/shared/editor/extensions/file-handler/index.ts
Normal file
116
web/shared/editor/extensions/file-handler/index.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import { type Editor, Extension } from "@tiptap/core"
|
||||
import { Plugin, PluginKey } from "@tiptap/pm/state"
|
||||
import type { FileError, FileValidationOptions } from "@shared/editor/lib/utils"
|
||||
import { filterFiles } from "@shared/editor/lib/utils"
|
||||
|
||||
type FileHandlePluginOptions = {
|
||||
key?: PluginKey
|
||||
editor: Editor
|
||||
onPaste?: (editor: Editor, files: File[], pasteContent?: string) => void
|
||||
onDrop?: (editor: Editor, files: File[], pos: number) => void
|
||||
onValidationError?: (errors: FileError[]) => void
|
||||
} & FileValidationOptions
|
||||
|
||||
const FileHandlePlugin = (options: FileHandlePluginOptions) => {
|
||||
const {
|
||||
key,
|
||||
editor,
|
||||
onPaste,
|
||||
onDrop,
|
||||
onValidationError,
|
||||
allowedMimeTypes,
|
||||
maxFileSize,
|
||||
} = options
|
||||
|
||||
return new Plugin({
|
||||
key: key || new PluginKey("fileHandler"),
|
||||
|
||||
props: {
|
||||
handleDrop(view, event) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
const { dataTransfer } = event
|
||||
|
||||
if (!dataTransfer?.files.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const pos = view.posAtCoords({
|
||||
left: event.clientX,
|
||||
top: event.clientY,
|
||||
})
|
||||
|
||||
const [validFiles, errors] = filterFiles(
|
||||
Array.from(dataTransfer.files),
|
||||
{
|
||||
allowedMimeTypes,
|
||||
maxFileSize,
|
||||
allowBase64: options.allowBase64,
|
||||
},
|
||||
)
|
||||
|
||||
if (errors.length > 0 && onValidationError) {
|
||||
onValidationError(errors)
|
||||
}
|
||||
|
||||
if (validFiles.length > 0 && onDrop) {
|
||||
onDrop(editor, validFiles, pos?.pos ?? 0)
|
||||
}
|
||||
},
|
||||
|
||||
handlePaste(_, event) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
const { clipboardData } = event
|
||||
|
||||
if (!clipboardData?.files.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const [validFiles, errors] = filterFiles(
|
||||
Array.from(clipboardData.files),
|
||||
{
|
||||
allowedMimeTypes,
|
||||
maxFileSize,
|
||||
allowBase64: options.allowBase64,
|
||||
},
|
||||
)
|
||||
const html = clipboardData.getData("text/html")
|
||||
|
||||
if (errors.length > 0 && onValidationError) {
|
||||
onValidationError(errors)
|
||||
}
|
||||
|
||||
if (validFiles.length > 0 && onPaste) {
|
||||
onPaste(editor, validFiles, html)
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const FileHandler = Extension.create<
|
||||
Omit<FileHandlePluginOptions, "key" | "editor">
|
||||
>({
|
||||
name: "fileHandler",
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
allowBase64: false,
|
||||
allowedMimeTypes: [],
|
||||
maxFileSize: 0,
|
||||
}
|
||||
},
|
||||
|
||||
addProseMirrorPlugins() {
|
||||
return [
|
||||
FileHandlePlugin({
|
||||
key: new PluginKey(this.name),
|
||||
editor: this.editor,
|
||||
...this.options,
|
||||
}),
|
||||
]
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user