This commit is contained in:
1 parent
1a4466d85d
commit
2f41bda41e
1 file changed
+73
-1
@@ -1,10 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
import { EditorView, basicSetup } from 'codemirror';
|
import { EditorView, basicSetup } from 'codemirror';
|
||||||
import { EditorState } from '@codemirror/state';
|
import { EditorState } from '@codemirror/state';
|
||||||
import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
|
import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
|
||||||
import { languages } from '@codemirror/language-data';
|
import { languages } from '@codemirror/language-data';
|
||||||
import { placeholder as cmPlaceholder } from '@codemirror/view';
|
import { placeholder as cmPlaceholder } from '@codemirror/view';
|
||||||
|
import { addToast } from '$lib/stores/toast.svelte';
|
||||||
|
|
||||||
let { value = $bindable(''), placeholderText = '支持 Markdown 格式...' } = $props();
|
let { value = $bindable(''), placeholderText = '支持 Markdown 格式...' } = $props();
|
||||||
|
|
||||||
@@ -12,6 +14,40 @@
|
|||||||
let view: EditorView;
|
let view: EditorView;
|
||||||
let isUpdating = false;
|
let isUpdating = false;
|
||||||
|
|
||||||
|
let showImageMenu = $state(false);
|
||||||
|
let fileInput: HTMLInputElement;
|
||||||
|
let isUploadingImage = $state(false);
|
||||||
|
|
||||||
|
async function handleImageUpload(e: Event) {
|
||||||
|
const input = e.target as HTMLInputElement;
|
||||||
|
const file = input.files?.[0];
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', file);
|
||||||
|
|
||||||
|
isUploadingImage = true;
|
||||||
|
try {
|
||||||
|
const res = await fetch('/admin/api/upload', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
const data = (await res.json()) as any;
|
||||||
|
if (data.success) {
|
||||||
|
insertAtCursor('`, file.name || '图片');
|
||||||
|
addToast('图片上传成功', 'success');
|
||||||
|
} else {
|
||||||
|
addToast(data.error || '上传失败', 'error');
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
console.error(err);
|
||||||
|
addToast('网络错误,上传失败', 'error');
|
||||||
|
} finally {
|
||||||
|
isUploadingImage = false;
|
||||||
|
input.value = '';
|
||||||
|
showImageMenu = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
const customTheme = EditorView.theme({
|
const customTheme = EditorView.theme({
|
||||||
'&': {
|
'&': {
|
||||||
color: 'var(--text-color)',
|
color: 'var(--text-color)',
|
||||||
@@ -228,10 +264,16 @@
|
|||||||
></path></svg
|
></path></svg
|
||||||
>
|
>
|
||||||
</button>
|
</button>
|
||||||
|
<div class="toolbar-dropdown-wrapper">
|
||||||
|
{#if showImageMenu}
|
||||||
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
|
<!-- svelte-ignore a11y_interactive_supports_focus -->
|
||||||
|
<div class="dropdown-overlay" onclick={() => (showImageMenu = false)} role="button"></div>
|
||||||
|
{/if}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="md-btn"
|
class="md-btn"
|
||||||
onclick={() => insertAtCursor('', '图片描述')}
|
onclick={() => (showImageMenu = !showImageMenu)}
|
||||||
title="图片"
|
title="图片"
|
||||||
>
|
>
|
||||||
<svg viewBox="0 0 24 24"
|
<svg viewBox="0 0 24 24"
|
||||||
@@ -241,6 +283,36 @@
|
|||||||
></polygon></svg
|
></polygon></svg
|
||||||
>
|
>
|
||||||
</button>
|
</button>
|
||||||
|
{#if showImageMenu}
|
||||||
|
<div class="toolbar-dropdown">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="dropdown-item"
|
||||||
|
onclick={() => {
|
||||||
|
insertAtCursor('', '图片描述');
|
||||||
|
showImageMenu = false;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
插入图片链接
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="dropdown-item"
|
||||||
|
onclick={() => fileInput.click()}
|
||||||
|
disabled={isUploadingImage}
|
||||||
|
>
|
||||||
|
{isUploadingImage ? '正在上传...' : '上传本地图片'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
style="display:none;"
|
||||||
|
bind:this={fileInput}
|
||||||
|
onchange={handleImageUpload}
|
||||||
|
/>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="md-btn"
|
class="md-btn"
|
||||||
|
|||||||
Reference in new issue
Block a user