mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-12 04:15:25 +00:00
enh: note word/char counter
This commit is contained in:
parent
6ee4274b3b
commit
3b9f4a6f5e
4 changed files with 38 additions and 1 deletions
15
package-lock.json
generated
15
package-lock.json
generated
|
|
@ -20,6 +20,7 @@
|
||||||
"@sveltejs/svelte-virtual-list": "^3.0.1",
|
"@sveltejs/svelte-virtual-list": "^3.0.1",
|
||||||
"@tiptap/core": "^2.11.9",
|
"@tiptap/core": "^2.11.9",
|
||||||
"@tiptap/extension-bubble-menu": "^2.25.0",
|
"@tiptap/extension-bubble-menu": "^2.25.0",
|
||||||
|
"@tiptap/extension-character-count": "^2.25.0",
|
||||||
"@tiptap/extension-code-block-lowlight": "^2.11.9",
|
"@tiptap/extension-code-block-lowlight": "^2.11.9",
|
||||||
"@tiptap/extension-floating-menu": "^2.25.0",
|
"@tiptap/extension-floating-menu": "^2.25.0",
|
||||||
"@tiptap/extension-highlight": "^2.10.0",
|
"@tiptap/extension-highlight": "^2.10.0",
|
||||||
|
|
@ -2986,6 +2987,20 @@
|
||||||
"@tiptap/core": "^2.7.0"
|
"@tiptap/core": "^2.7.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tiptap/extension-character-count": {
|
||||||
|
"version": "2.25.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tiptap/extension-character-count/-/extension-character-count-2.25.0.tgz",
|
||||||
|
"integrity": "sha512-F+4DxJFptbX3oioqNwS38zOTi6gH9CumV/ISeOIvr4ao7Iija3tNonGDsHhxD05njjbYNIp1OKsxtnzbWukgMA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ueberdosis"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@tiptap/core": "^2.7.0",
|
||||||
|
"@tiptap/pm": "^2.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tiptap/extension-code": {
|
"node_modules/@tiptap/extension-code": {
|
||||||
"version": "2.10.0",
|
"version": "2.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.10.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@
|
||||||
"@sveltejs/svelte-virtual-list": "^3.0.1",
|
"@sveltejs/svelte-virtual-list": "^3.0.1",
|
||||||
"@tiptap/core": "^2.11.9",
|
"@tiptap/core": "^2.11.9",
|
||||||
"@tiptap/extension-bubble-menu": "^2.25.0",
|
"@tiptap/extension-bubble-menu": "^2.25.0",
|
||||||
|
"@tiptap/extension-character-count": "^2.25.0",
|
||||||
"@tiptap/extension-code-block-lowlight": "^2.11.9",
|
"@tiptap/extension-code-block-lowlight": "^2.11.9",
|
||||||
"@tiptap/extension-floating-menu": "^2.25.0",
|
"@tiptap/extension-floating-menu": "^2.25.0",
|
||||||
"@tiptap/extension-highlight": "^2.10.0",
|
"@tiptap/extension-highlight": "^2.10.0",
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,8 @@
|
||||||
import TaskItem from '@tiptap/extension-task-item';
|
import TaskItem from '@tiptap/extension-task-item';
|
||||||
import TaskList from '@tiptap/extension-task-list';
|
import TaskList from '@tiptap/extension-task-list';
|
||||||
|
|
||||||
|
import CharacterCount from '@tiptap/extension-character-count';
|
||||||
|
|
||||||
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight';
|
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight';
|
||||||
import Placeholder from '@tiptap/extension-placeholder';
|
import Placeholder from '@tiptap/extension-placeholder';
|
||||||
import StarterKit from '@tiptap/starter-kit';
|
import StarterKit from '@tiptap/starter-kit';
|
||||||
|
|
@ -92,6 +94,8 @@
|
||||||
// create a lowlight instance with all languages loaded
|
// create a lowlight instance with all languages loaded
|
||||||
const lowlight = createLowlight(all);
|
const lowlight = createLowlight(all);
|
||||||
|
|
||||||
|
export let editor = null;
|
||||||
|
|
||||||
export let className = 'input-prose';
|
export let className = 'input-prose';
|
||||||
export let placeholder = 'Type here...';
|
export let placeholder = 'Type here...';
|
||||||
|
|
||||||
|
|
@ -116,7 +120,6 @@
|
||||||
let floatingMenuElement = null;
|
let floatingMenuElement = null;
|
||||||
let bubbleMenuElement = null;
|
let bubbleMenuElement = null;
|
||||||
let element;
|
let element;
|
||||||
let editor;
|
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
throwOnError: false
|
throwOnError: false
|
||||||
|
|
@ -496,6 +499,7 @@
|
||||||
TaskItem.configure({
|
TaskItem.configure({
|
||||||
nested: true
|
nested: true
|
||||||
}),
|
}),
|
||||||
|
CharacterCount,
|
||||||
...(autocomplete
|
...(autocomplete
|
||||||
? [
|
? [
|
||||||
AIAutocompletion.configure({
|
AIAutocompletion.configure({
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@
|
||||||
|
|
||||||
export let id: null | string = null;
|
export let id: null | string = null;
|
||||||
|
|
||||||
|
let editor = null;
|
||||||
let note = null;
|
let note = null;
|
||||||
|
|
||||||
const newNote = {
|
const newNote = {
|
||||||
|
|
@ -872,6 +873,21 @@ Provide the enhanced notes in markdown format. Use markdown syntax for headings,
|
||||||
|
|
||||||
<span> You </span>
|
<span> You </span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
{#if editor}
|
||||||
|
<div class="flex items-center gap-1 px-1">
|
||||||
|
<div>
|
||||||
|
{$i18n.t('{{count}} words', {
|
||||||
|
count: editor.storage.characterCount.words()
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{$i18n.t('{{count}} characters', {
|
||||||
|
count: editor.storage.characterCount.characters()
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -923,6 +939,7 @@ Provide the enhanced notes in markdown format. Use markdown syntax for headings,
|
||||||
|
|
||||||
<RichTextInput
|
<RichTextInput
|
||||||
bind:this={inputElement}
|
bind:this={inputElement}
|
||||||
|
bind:editor
|
||||||
className="input-prose-sm px-0.5"
|
className="input-prose-sm px-0.5"
|
||||||
bind:value={note.data.content.json}
|
bind:value={note.data.content.json}
|
||||||
html={note.data?.content?.html}
|
html={note.data?.content?.html}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue