Add CodeMirror based Highlighted editor
This commit is contained in:
@@ -32,6 +32,7 @@
|
|||||||
"blueimp-md5": "^2.19.0",
|
"blueimp-md5": "^2.19.0",
|
||||||
"body-parser": "^1.20.2",
|
"body-parser": "^1.20.2",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
|
"codemirror": "^5.65.16",
|
||||||
"core-js": "^3.35.0",
|
"core-js": "^3.35.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"crc": "^4.3.2",
|
"crc": "^4.3.2",
|
||||||
|
|||||||
@@ -403,4 +403,5 @@ export const languageChinese = {
|
|||||||
"appendNameNAI": "在NAI上附加名称",
|
"appendNameNAI": "在NAI上附加名称",
|
||||||
module: "模块",
|
module: "模块",
|
||||||
modules: "模块",
|
modules: "模块",
|
||||||
|
useAdvancedEditor: "使用高级编辑器",
|
||||||
}
|
}
|
||||||
@@ -432,4 +432,5 @@ export const languageGerman = {
|
|||||||
textAdventureNAI: "Als Textabenteuer ausführen",
|
textAdventureNAI: "Als Textabenteuer ausführen",
|
||||||
appendNameNAI: "Namen an NAI anhängen",
|
appendNameNAI: "Namen an NAI anhängen",
|
||||||
customStopWords: "Benutzerdefinierte Stoppwörter",
|
customStopWords: "Benutzerdefinierte Stoppwörter",
|
||||||
|
useAdvancedEditor: "Erweiterten Editor verwenden",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -551,4 +551,5 @@ export const languageEnglish = {
|
|||||||
popularityLevelDesc: "Popularity increases with downloads, etc. to estimate, 3.7 popularity is about 1 downloads.",
|
popularityLevelDesc: "Popularity increases with downloads, etc. to estimate, 3.7 popularity is about 1 downloads.",
|
||||||
additionalParams: "Additional Parameters",
|
additionalParams: "Additional Parameters",
|
||||||
heightMode: "Height Mode",
|
heightMode: "Height Mode",
|
||||||
|
useAdvancedEditor: "Use Advanced Editor",
|
||||||
}
|
}
|
||||||
@@ -432,4 +432,5 @@ export const languageKorean = {
|
|||||||
largePersonaPortrait: "페르소나 세로 이미지",
|
largePersonaPortrait: "페르소나 세로 이미지",
|
||||||
module: "모듈",
|
module: "모듈",
|
||||||
modules: "모듈",
|
modules: "모듈",
|
||||||
|
useAdvancedEditor: "고급 에디터 사용",
|
||||||
}
|
}
|
||||||
@@ -406,4 +406,5 @@ export const LanguageVietnamese = {
|
|||||||
"defaultPrompt": "Lời nhắc mặc định",
|
"defaultPrompt": "Lời nhắc mặc định",
|
||||||
module: "Mô-đun",
|
module: "Mô-đun",
|
||||||
modules: "Mô-đun",
|
modules: "Mô-đun",
|
||||||
|
useAdvancedEditor: "Sử dụng trình biên tập nâng cao",
|
||||||
}
|
}
|
||||||
163
src/lib/ChatScreens/AdvancedChatEditor.svelte
Normal file
163
src/lib/ChatScreens/AdvancedChatEditor.svelte
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount, createEventDispatcher } from 'svelte';
|
||||||
|
import { EditIcon, LanguagesIcon } from "lucide-svelte";
|
||||||
|
import { DataBase } from "../../ts/storage/database";
|
||||||
|
import CodeMirror from 'codemirror';
|
||||||
|
import 'codemirror/lib/codemirror.css';
|
||||||
|
|
||||||
|
export let value, translate;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
let toggleTranslate = !$DataBase.useAutoTranslateInput;
|
||||||
|
let velement, veditor;
|
||||||
|
let telement, teditor;
|
||||||
|
let _value = value;
|
||||||
|
let _translate = translate;
|
||||||
|
|
||||||
|
const markdowns = [
|
||||||
|
{
|
||||||
|
regex: /["“”](.*?)(["“”]|$)/gs,
|
||||||
|
className: "ci-quote",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
regex: /`([^`]+)`/gs,
|
||||||
|
className: "ci-backtick",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
regex: /\*\*\*([^*]+)(\*\*\*|$)/gs,
|
||||||
|
className: "ci-asterisk3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
regex: /(?<!\*)\*\*([^*]+)(\*\*(?!\*)|$)/gs,
|
||||||
|
className: "ci-asterisk2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
regex: /(?<!\*)\*([^*]+)(\*(?!\*)|$)/gs,
|
||||||
|
className: "ci-asterisk1",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
veditor = initEditor(velement, value);
|
||||||
|
teditor = initEditor(telement, translate);
|
||||||
|
veditor.on('change', (_, evt) => {
|
||||||
|
if(evt.origin != 'setValue' && !toggleTranslate) {
|
||||||
|
const input = veditor.getValue('\r\n');
|
||||||
|
if(input != value) {
|
||||||
|
value = _value = input;
|
||||||
|
dispatch('change', { translate: false, value: input });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
teditor.on('change', (_, evt) => {
|
||||||
|
if(evt.origin != 'setValue' && toggleTranslate) {
|
||||||
|
const input = teditor.getValue('\r\n');
|
||||||
|
if(input != translate) {
|
||||||
|
translate = _translate = input;
|
||||||
|
dispatch('change', { translate: true, value: input });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
toggleTranslateText();
|
||||||
|
});
|
||||||
|
|
||||||
|
$: if(value != _value) {
|
||||||
|
veditor.setValue(_value = value);
|
||||||
|
}
|
||||||
|
$: if(translate != _translate) {
|
||||||
|
teditor.setValue(_translate = translate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleTranslateText() {
|
||||||
|
toggleTranslate = !toggleTranslate;
|
||||||
|
if(toggleTranslate) {
|
||||||
|
velement.style.display = "none";
|
||||||
|
telement.style.display = null;
|
||||||
|
teditor.refresh();
|
||||||
|
} else {
|
||||||
|
velement.style.display = null;
|
||||||
|
telement.style.display = "none";
|
||||||
|
veditor.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function initEditor(element, value) {
|
||||||
|
const editor = CodeMirror(element, {
|
||||||
|
lineNumbers: true,
|
||||||
|
value: value,
|
||||||
|
});
|
||||||
|
editor.on('change', (sender) => updateMarks(sender.doc));
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMarks(doc) {
|
||||||
|
const text = doc.getValue();
|
||||||
|
for (const mark of doc.getAllMarks()) {
|
||||||
|
mark.clear();
|
||||||
|
}
|
||||||
|
for(const markdown of markdowns) {
|
||||||
|
for (const match of text.matchAll(markdown.regex)) {
|
||||||
|
const start = doc.posFromIndex(match.index);
|
||||||
|
const end = doc.posFromIndex(match.index + match[0].length);
|
||||||
|
doc.markText(start, end, { className: markdown.className });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex flex-1 items-end ml-2 mr-2">
|
||||||
|
{#if $DataBase.useAutoTranslateInput}
|
||||||
|
<button
|
||||||
|
on:click={toggleTranslateText}
|
||||||
|
class="mr-2 bg-textcolor2 flex justify-center items-center text-gray-100 w-12 h-12 rounded-md hover:bg-green-500 transition-colors">
|
||||||
|
{#if toggleTranslate}
|
||||||
|
<LanguagesIcon />
|
||||||
|
{:else}
|
||||||
|
<EditIcon />
|
||||||
|
{/if}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="chatEditor" bind:this={velement}></div>
|
||||||
|
<div class="chatEditor" hidden bind:this={telement}></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<style>
|
||||||
|
.chatEditor {
|
||||||
|
display: table;
|
||||||
|
table-layout: fixed;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.chatEditor :global(.CodeMirror) {
|
||||||
|
min-height: 2em;
|
||||||
|
height: auto;
|
||||||
|
background-color: var(--risu-theme-bgcolor);
|
||||||
|
color: #DD0;
|
||||||
|
}
|
||||||
|
.chatEditor :global(.CodeMirror:focus-within) {
|
||||||
|
background-color: var(--risu-theme-textcolor2);
|
||||||
|
}
|
||||||
|
.chatEditor :global(.CodeMirror-gutters) {
|
||||||
|
background-color: var(--risu-theme-selected);
|
||||||
|
border-left-color: var(--risu-theme-borderc);
|
||||||
|
}
|
||||||
|
.chatEditor :global(.ci-quote) {
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
.chatEditor :global(.ci-backtick) {
|
||||||
|
color: #6AC;
|
||||||
|
}
|
||||||
|
.chatEditor :global(.ci-asterisk3) {
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
color: #E22;
|
||||||
|
}
|
||||||
|
.chatEditor :global(.ci-asterisk2) {
|
||||||
|
font-style: italic;
|
||||||
|
color: #E84;
|
||||||
|
}
|
||||||
|
.chatEditor :global(.ci-asterisk1) {
|
||||||
|
font-style: italic;
|
||||||
|
color: #990;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Suggestion from './Suggestion.svelte';
|
import Suggestion from './Suggestion.svelte';
|
||||||
|
import AdvancedChatEditor from './AdvancedChatEditor.svelte';
|
||||||
import { CameraIcon, DatabaseIcon, DicesIcon, GlobeIcon, ImagePlusIcon, LanguagesIcon, Laugh, MenuIcon, MicOffIcon, PackageIcon, RefreshCcwIcon, ReplyIcon, Send, StepForwardIcon } from "lucide-svelte";
|
import { CameraIcon, DatabaseIcon, DicesIcon, GlobeIcon, ImagePlusIcon, LanguagesIcon, Laugh, MenuIcon, MicOffIcon, PackageIcon, RefreshCcwIcon, ReplyIcon, Send, StepForwardIcon } from "lucide-svelte";
|
||||||
import { CurrentCharacter, CurrentChat, CurrentUsername, selectedCharID, CurrentUserIcon, CurrentShowMemoryLimit,CurrentSimpleCharacter } from "../../ts/stores";
|
import { CurrentCharacter, CurrentChat, CurrentUsername, selectedCharID, CurrentUserIcon, CurrentShowMemoryLimit,CurrentSimpleCharacter } from "../../ts/stores";
|
||||||
import Chat from "./Chat.svelte";
|
import Chat from "./Chat.svelte";
|
||||||
@@ -385,6 +386,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
<div class="w-full h-full" style={customStyle} on:click={() => {
|
<div class="w-full h-full" style={customStyle} on:click={() => {
|
||||||
openMenu = false
|
openMenu = false
|
||||||
}}>
|
}}>
|
||||||
@@ -405,6 +407,8 @@
|
|||||||
<Laugh/>
|
<Laugh/>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if !$DataBase.useAdvancedEditor}
|
||||||
<textarea class="text-textcolor p-2 min-w-0 bg-transparent input-text text-xl flex-grow ml-4 mr-2 border-darkbutton resize-none focus:bg-selected overflow-y-hidden overflow-x-hidden max-w-full"
|
<textarea class="text-textcolor p-2 min-w-0 bg-transparent input-text text-xl flex-grow ml-4 mr-2 border-darkbutton resize-none focus:bg-selected overflow-y-hidden overflow-x-hidden max-w-full"
|
||||||
bind:value={messageInput}
|
bind:value={messageInput}
|
||||||
bind:this={inputEle}
|
bind:this={inputEle}
|
||||||
@@ -423,9 +427,16 @@
|
|||||||
on:input={()=>{updateInputSizeAll();updateInputTransateMessage(false)}}
|
on:input={()=>{updateInputSizeAll();updateInputTransateMessage(false)}}
|
||||||
style:height={inputHeight}
|
style:height={inputHeight}
|
||||||
/>
|
/>
|
||||||
|
{:else}
|
||||||
|
<AdvancedChatEditor
|
||||||
|
bind:value={messageInput}
|
||||||
|
bind:translate={messageInputTranslate}
|
||||||
|
on:change={(e) => { updateInputTransateMessage(e.detail.translate);}}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
{#if $doingChat || doingChatInputTranslate}
|
{#if $doingChat || doingChatInputTranslate}
|
||||||
<div
|
<div
|
||||||
class="mr-2 bg-selected flex justify-center items-center text-gray-100 w-12 h-12 rounded-md hover:bg-green-500 transition-colors" on:click={abortChat}>
|
class="mr-2 bg-selected flex justify-center items-center text-gray-100 w-12 h-12 rounded-md hover:bg-green-500 transition-colors" on:click={abortChat}>
|
||||||
<div class="loadmove" class:autoload={autoMode}>
|
<div class="loadmove" class:autoload={autoMode}>
|
||||||
@@ -443,7 +454,7 @@
|
|||||||
class="mr-2 bg-textcolor2 flex justify-center items-center text-gray-100 w-12 h-12 rounded-md hover:bg-green-500 transition-colors"><MenuIcon />
|
class="mr-2 bg-textcolor2 flex justify-center items-center text-gray-100 w-12 h-12 rounded-md hover:bg-green-500 transition-colors"><MenuIcon />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#if $DataBase.useAutoTranslateInput}
|
{#if $DataBase.useAutoTranslateInput && !$DataBase.useAdvancedEditor}
|
||||||
<div class="flex items-center mt-2 mb-2">
|
<div class="flex items-center mt-2 mb-2">
|
||||||
<label for='messageInputTranslate' class="text-textcolor ml-4">
|
<label for='messageInputTranslate' class="text-textcolor ml-4">
|
||||||
<LanguagesIcon />
|
<LanguagesIcon />
|
||||||
|
|||||||
@@ -192,6 +192,10 @@
|
|||||||
<Check bind:check={$DataBase.roundIcons} name={language.roundIcons}/>
|
<Check bind:check={$DataBase.roundIcons} name={language.roundIcons}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center mt-2">
|
||||||
|
<Check bind:check={$DataBase.useAdvancedEditor} name={language.useAdvancedEditor}/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{#if $DataBase.textScreenColor}
|
{#if $DataBase.textScreenColor}
|
||||||
<div class="flex items-center mt-2">
|
<div class="flex items-center mt-2">
|
||||||
<Check check={true} onChange={() => {
|
<Check check={true} onChange={() => {
|
||||||
|
|||||||
@@ -604,6 +604,7 @@ export interface Database{
|
|||||||
requestInfoInsideChat?:boolean
|
requestInfoInsideChat?:boolean
|
||||||
additionalParams:[string, string][]
|
additionalParams:[string, string][]
|
||||||
heightMode:string
|
heightMode:string
|
||||||
|
useAdvancedEditor:boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface customscript{
|
export interface customscript{
|
||||||
|
|||||||
Reference in New Issue
Block a user