[feat] new gui
This commit is contained in:
@@ -1,39 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import { DataBase } from "../../ts/storage/database";
|
|
||||||
|
|
||||||
let textarea;
|
|
||||||
let previousScrollHeight = 0;
|
|
||||||
export let value = ''
|
|
||||||
|
|
||||||
function resize() {
|
|
||||||
textarea.style.height = '0px'; // Reset the textarea height
|
|
||||||
textarea.style.height = `calc(${textarea.scrollHeight}px + 1rem)`; // Set the new height
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleInput() {
|
|
||||||
if (textarea.scrollHeight !== previousScrollHeight) {
|
|
||||||
previousScrollHeight = textarea.scrollHeight;
|
|
||||||
resize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
resize();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
textarea {
|
|
||||||
overflow: hidden;
|
|
||||||
resize: none;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background: transparent;
|
|
||||||
color: white;
|
|
||||||
border: 1px solid rgba(98, 114, 164, 0.5);
|
|
||||||
max-width: calc(95% - 2rem);
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<textarea bind:this={textarea} on:input={handleInput} bind:value={value} style:font-size="{0.875 * ($DataBase.zoomsize / 100)}rem" style:line-height="{1.25 * ($DataBase.zoomsize / 100)}rem" />
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ArrowLeft, ArrowRight, EditIcon, LanguagesIcon, RefreshCcwIcon, TrashIcon, CopyIcon } from "lucide-svelte";
|
import { ArrowLeft, ArrowRight, EditIcon, LanguagesIcon, RefreshCcwIcon, TrashIcon, CopyIcon } from "lucide-svelte";
|
||||||
import { ParseMarkdown } from "../../ts/parser";
|
import { ParseMarkdown } from "../../ts/parser";
|
||||||
import AutoresizeArea from "./AutoresizeArea.svelte";
|
import AutoresizeArea from "../UI/GUI/TextAreaResizable.svelte";
|
||||||
import { alertConfirm } from "../../ts/alert";
|
import { alertConfirm } from "../../ts/alert";
|
||||||
import { language } from "../../lang";
|
import { language } from "../../lang";
|
||||||
import { DataBase, type character, type groupChat } from "../../ts/storage/database";
|
import { DataBase, type character, type groupChat } from "../../ts/storage/database";
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { CheckIcon } from "lucide-svelte";
|
|
||||||
|
|
||||||
export let check = false
|
|
||||||
export let onChange = (check) => {}
|
|
||||||
export let margin = true
|
|
||||||
export let name = ''
|
|
||||||
export let hiddenName = false
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<label title={name} class:mr-2={margin} class="flex relative">
|
|
||||||
<input title={name} type="checkbox" class='absolute opacity-0 w-6 h-6' bind:checked={check} on:change={() => {
|
|
||||||
onChange(check)
|
|
||||||
}}/>
|
|
||||||
{#if check}
|
|
||||||
<div class="w-6 h-6 bg-green-500 flex justify-center items-center text-sm">
|
|
||||||
<CheckIcon />
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<div class="w-6 h-6 bg-selected flex justify-center items-center text-sm"/>
|
|
||||||
{/if}
|
|
||||||
{#if name != '' && !hiddenName}
|
|
||||||
<span class="text-neutral-200 ml-2">{name}</span>
|
|
||||||
{/if}
|
|
||||||
</label>
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Check from "src/lib/Others/Check.svelte";
|
import Check from "src/lib/UI/GUI/Check.svelte";
|
||||||
import { language } from "src/lang";
|
import { language } from "src/lang";
|
||||||
import { DataBase } from "src/ts/storage/database";
|
import { DataBase } from "src/ts/storage/database";
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Check from "src/lib/Others/Check.svelte";
|
import Check from "src/lib/UI/GUI/Check.svelte";
|
||||||
import { language } from "src/lang";
|
import { language } from "src/lang";
|
||||||
import { DataBase } from "src/ts/storage/database";
|
import { DataBase } from "src/ts/storage/database";
|
||||||
import { alertMd } from "src/ts/alert";
|
import { alertMd } from "src/ts/alert";
|
||||||
import { getRequestLog, isTauri } from "src/ts/storage/globalApi";
|
import { getRequestLog, isTauri } from "src/ts/storage/globalApi";
|
||||||
import NumberInput from "src/lib/UI/GUI/NumberInput.svelte";
|
import NumberInput from "src/lib/UI/GUI/NumberInput.svelte";
|
||||||
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
||||||
|
import SelectInput from "src/lib/UI/GUI/SelectInput.svelte";
|
||||||
|
import OptionInput from "src/lib/UI/GUI/OptionInput.svelte";
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<h2 class="text-2xl font-bold mt-2">{language.advancedSettings}</h2>
|
<h2 class="text-2xl font-bold mt-2">{language.advancedSettings}</h2>
|
||||||
<span class="text-draculared text-xs mb-2">{language.advancedSettingsWarn}</span>
|
<span class="text-draculared text-xs mb-2">{language.advancedSettingsWarn}</span>
|
||||||
@@ -27,10 +30,10 @@
|
|||||||
<NumberInput marginBottom={true} size={"sm"} min={0} max={20} bind:value={$DataBase.requestRetrys}/>
|
<NumberInput marginBottom={true} size={"sm"} min={0} max={20} bind:value={$DataBase.requestRetrys}/>
|
||||||
|
|
||||||
<span class="text-neutral-200">Request Lib</span>
|
<span class="text-neutral-200">Request Lib</span>
|
||||||
<select class="bg-transparent input-text text-gray-200 appearance-none text-sm" bind:value={$DataBase.requester}>
|
<SelectInput bind:value={$DataBase.requester}>
|
||||||
<option value="new" class="bg-darkbg appearance-none">Reqwest</option>
|
<OptionInput value="new">Reqwest</OptionInput>
|
||||||
<option value="old" class="bg-darkbg appearance-none">Tauri</option>
|
<OptionInput value="old">Tauri</OptionInput>
|
||||||
</select>
|
</SelectInput>
|
||||||
|
|
||||||
<div class="flex items-center mt-4">
|
<div class="flex items-center mt-4">
|
||||||
<Check bind:check={$DataBase.useSayNothing} name={language.sayNothing}/>
|
<Check bind:check={$DataBase.useSayNothing} name={language.sayNothing}/>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Check from "src/lib/Others/Check.svelte";
|
import Check from "src/lib/UI/GUI/Check.svelte";
|
||||||
import { language } from "src/lang";
|
import { language } from "src/lang";
|
||||||
import Help from "src/lib/Others/Help.svelte";
|
import Help from "src/lib/Others/Help.svelte";
|
||||||
import { DataBase } from "src/ts/storage/database";
|
import { DataBase } from "src/ts/storage/database";
|
||||||
@@ -10,10 +10,15 @@
|
|||||||
import DropList from "src/lib/SideBars/DropList.svelte";
|
import DropList from "src/lib/SideBars/DropList.svelte";
|
||||||
import { PlusIcon, TrashIcon } from "lucide-svelte";
|
import { PlusIcon, TrashIcon } from "lucide-svelte";
|
||||||
import { onDestroy } from "svelte";
|
import { onDestroy } from "svelte";
|
||||||
import { recommendedPresetExist, setRecommended } from "src/ts/process/templates/getRecomended";
|
import { recommendedPresetExist, setRecommended } from "src/ts/process/templates/getRecomended";
|
||||||
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
||||||
import NumberInput from "src/lib/UI/GUI/NumberInput.svelte";
|
import NumberInput from "src/lib/UI/GUI/NumberInput.svelte";
|
||||||
import SliderInput from "src/lib/UI/GUI/SliderInput.svelte";
|
import SliderInput from "src/lib/UI/GUI/SliderInput.svelte";
|
||||||
|
import TextAreaInput from "src/lib/UI/GUI/TextAreaInput.svelte";
|
||||||
|
import Button from "src/lib/UI/GUI/Button.svelte";
|
||||||
|
import SelectInput from "src/lib/UI/GUI/SelectInput.svelte";
|
||||||
|
import OptionInput from "src/lib/UI/GUI/OptionInput.svelte";
|
||||||
|
|
||||||
let tokens = {
|
let tokens = {
|
||||||
mainPrompt: 0,
|
mainPrompt: 0,
|
||||||
jailbreak: 0,
|
jailbreak: 0,
|
||||||
@@ -97,7 +102,7 @@
|
|||||||
|
|
||||||
{#if advancedBotSettings && recommendedPresetExist($DataBase.aiModel)}
|
{#if advancedBotSettings && recommendedPresetExist($DataBase.aiModel)}
|
||||||
<div>
|
<div>
|
||||||
<button class="bg-darkbg hover:ring p-1 text-sm mb-2 rounded-md" on:click={() => {setRecommended($DataBase.aiModel, 'ask')}}>{language.recommendedPreset}</button>
|
<Button size="sm" className="mb-2" on:click={() => {setRecommended($DataBase.aiModel, 'ask')}}>{language.recommendedPreset}</Button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $DataBase.aiModel === 'palm2' || $DataBase.subModel === 'palm2'}
|
{#if $DataBase.aiModel === 'palm2' || $DataBase.subModel === 'palm2'}
|
||||||
@@ -119,34 +124,34 @@
|
|||||||
<span class="text-neutral-200 mt-4"> {language.proxyAPIKey}</span>
|
<span class="text-neutral-200 mt-4"> {language.proxyAPIKey}</span>
|
||||||
<TextInput marginBottom={false} size={"sm"} placeholder="leave it blank if it hasn't password" bind:value={$DataBase.proxyKey} />
|
<TextInput marginBottom={false} size={"sm"} placeholder="leave it blank if it hasn't password" bind:value={$DataBase.proxyKey} />
|
||||||
<span class="text-neutral-200 mt-4"> {language.proxyRequestModel}</span>
|
<span class="text-neutral-200 mt-4"> {language.proxyRequestModel}</span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none text-sm" bind:value={$DataBase.proxyRequestModel}>
|
<SelectInput className="mt-2 mb-4" bind:value={$DataBase.proxyRequestModel}>
|
||||||
<option value="" class="bg-darkbg appearance-none">None</option>
|
<OptionInput value="">None</OptionInput>
|
||||||
<option value="gpt35" class="bg-darkbg appearance-none">GPT 3.5</option>
|
<OptionInput value="gpt35">GPT 3.5</OptionInput>
|
||||||
<option value="gpt35_16k" class="bg-darkbg appearance-none">GPT 3.5 16k</option>
|
<OptionInput value="gpt35_16k">GPT 3.5 16k</OptionInput>
|
||||||
<option value="gpt4" class="bg-darkbg appearance-none">GPT-4</option>
|
<OptionInput value="gpt4">GPT-4</OptionInput>
|
||||||
<option value="gpt4_32k" class="bg-darkbg appearance-none">GPT-4 32k</option>
|
<OptionInput value="gpt4_32k">GPT-4 32k</OptionInput>
|
||||||
<option value="gpt35_0301" class="bg-darkbg appearance-none">GPT-3.5 0301</option>
|
<OptionInput value="gpt35_0301">GPT-3.5 0301</OptionInput>
|
||||||
<option value="gpt4_0301" class="bg-darkbg appearance-none">GPT-4 0301</option>
|
<OptionInput value="gpt4_0301">GPT-4 0301</OptionInput>
|
||||||
<option value="gpt4_0613" class="bg-darkbg appearance-none">GPT-4 0613</option>
|
<OptionInput value="gpt4_0613">GPT-4 0613</OptionInput>
|
||||||
</select>
|
</SelectInput>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $DataBase.aiModel === 'openrouter' || $DataBase.subModel === 'openrouter'}
|
{#if $DataBase.aiModel === 'openrouter' || $DataBase.subModel === 'openrouter'}
|
||||||
<span class="text-neutral-200 mt-4">Openrouter Key</span>
|
<span class="text-neutral-200 mt-4">Openrouter Key</span>
|
||||||
<TextInput marginBottom={false} size={"sm"} bind:value={$DataBase.openrouterKey} />
|
<TextInput marginBottom={false} size={"sm"} bind:value={$DataBase.openrouterKey} />
|
||||||
|
|
||||||
<span class="text-neutral-200 mt-4">Openrouter Model</span>
|
<span class="text-neutral-200 mt-4">Openrouter Model</span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none text-sm" bind:value={$DataBase.openrouterRequestModel}>
|
<SelectInput className="mt-2 mb-4" bind:value={$DataBase.openrouterRequestModel}>
|
||||||
<option value="openai/gpt-3.5-turbo" class="bg-darkbg appearance-none">GPT 3.5</option>
|
<OptionInput value="openai/gpt-3.5-turbo">GPT 3.5</OptionInput>
|
||||||
<option value="openai/gpt-3.5-turbo-16k" class="bg-darkbg appearance-none">GPT 3.5 16k</option>
|
<OptionInput value="openai/gpt-3.5-turbo-16k">GPT 3.5 16k</OptionInput>
|
||||||
<option value="openai/gpt-4" class="bg-darkbg appearance-none">GPT-4</option>
|
<OptionInput value="openai/gpt-4">GPT-4</OptionInput>
|
||||||
<option value="openai/gpt-4-32k" class="bg-darkbg appearance-none">GPT-4 32k</option>
|
<OptionInput value="openai/gpt-4-32k">GPT-4 32k</OptionInput>
|
||||||
<option value="anthropic/claude-2" class="bg-darkbg appearance-none">Claude 2</option>
|
<OptionInput value="anthropic/claude-2">Claude 2</OptionInput>
|
||||||
<option value="anthropic/claude-instant-v1" class="bg-darkbg appearance-none">Claude Instant v1</option>
|
<OptionInput value="anthropic/claude-instant-v1">Claude Instant v1</OptionInput>
|
||||||
<option value="anthropic/claude-instant-v1-100k" class="bg-darkbg appearance-none">Claude Instant v1 100k</option>
|
<OptionInput value="anthropic/claude-instant-v1-100k">Claude Instant v1 100k</OptionInput>
|
||||||
<option value="anthropic/claude-v1" class="bg-darkbg appearance-none">Claude v1</option>
|
<OptionInput value="anthropic/claude-v1">Claude v1</OptionInput>
|
||||||
<option value="anthropic/claude-v1-100k" class="bg-darkbg appearance-none">Claude v1 100k</option>
|
<OptionInput value="anthropic/claude-v1-100k">Claude v1 100k</OptionInput>
|
||||||
<option value="anthropic/claude-1.2" class="bg-darkbg appearance-none">Claude v1.2</option>
|
<OptionInput value="anthropic/claude-1.2">Claude v1.2</OptionInput>
|
||||||
</select>
|
</SelectInput>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $DataBase.aiModel.startsWith('gpt') || $DataBase.subModel.startsWith('gpt')}
|
{#if $DataBase.aiModel.startsWith('gpt') || $DataBase.subModel.startsWith('gpt')}
|
||||||
<span class="text-neutral-200">OpenAI {language.apiKey} <Help key="oaiapikey"/></span>
|
<span class="text-neutral-200">OpenAI {language.apiKey} <Help key="oaiapikey"/></span>
|
||||||
@@ -161,12 +166,12 @@
|
|||||||
|
|
||||||
{#if $DataBase.aiModel === 'custom'}
|
{#if $DataBase.aiModel === 'custom'}
|
||||||
<span class="text-neutral-200 mt-2">{language.plugin}</span>
|
<span class="text-neutral-200 mt-2">{language.plugin}</span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none text-sm" bind:value={$DataBase.currentPluginProvider}>
|
<SelectInput className="mt-2 mb-4" bind:value={$DataBase.currentPluginProvider}>
|
||||||
<option value="" class="bg-darkbg appearance-none">None</option>
|
<OptionInput value="">None</OptionInput>
|
||||||
{#each $customProviderStore as plugin}
|
{#each $customProviderStore as plugin}
|
||||||
<option value={plugin} class="bg-darkbg appearance-none">{plugin}</option>
|
<OptionInput value={plugin}>{plugin}</OptionInput>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</SelectInput>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $DataBase.aiModel === "novelai" || $DataBase.subModel === "novelai"}
|
{#if $DataBase.aiModel === "novelai" || $DataBase.subModel === "novelai"}
|
||||||
<span class="text-neutral-200">NovelAI Bearer Token</span>
|
<span class="text-neutral-200">NovelAI Bearer Token</span>
|
||||||
@@ -196,14 +201,14 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{#if advancedBotSettings}
|
{#if advancedBotSettings}
|
||||||
<span class="text-neutral-200">{language.mainPrompt} <Help key="mainprompt"/></span>
|
<span class="text-neutral-200">{language.mainPrompt} <Help key="mainprompt"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none h-20 min-h-20 focus:bg-selected text-xs w-full" autocomplete="off" bind:value={$DataBase.mainPrompt}></textarea>
|
<TextAreaInput fullwidth autocomplete="off" height={"32"} bind:value={$DataBase.mainPrompt}></TextAreaInput>
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.mainPrompt} {language.tokens}</span>
|
<span class="text-gray-400 mb-6 text-sm mt-2">{tokens.mainPrompt} {language.tokens}</span>
|
||||||
<span class="text-neutral-200">{language.jailbreakPrompt} <Help key="jailbreak"/></span>
|
<span class="text-neutral-200">{language.jailbreakPrompt} <Help key="jailbreak"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none h-20 min-h-20 focus:bg-selected text-xs w-full" autocomplete="off" bind:value={$DataBase.jailbreak}></textarea>
|
<TextAreaInput fullwidth autocomplete="off" height={"32"} bind:value={$DataBase.jailbreak}></TextAreaInput>
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.jailbreak} {language.tokens}</span>
|
<span class="text-gray-400 mb-6 text-sm mt-2">{tokens.jailbreak} {language.tokens}</span>
|
||||||
<span class="text-neutral-200">{language.globalNote} <Help key="globalNote"/></span>
|
<span class="text-neutral-200">{language.globalNote} <Help key="globalNote"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none h-20 min-h-20 focus:bg-selected text-xs w-full" autocomplete="off" bind:value={$DataBase.globalNote}></textarea>
|
<TextAreaInput fullwidth autocomplete="off" height={"32"} bind:value={$DataBase.globalNote}></TextAreaInput>
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.globalNote} {language.tokens}</span>
|
<span class="text-gray-400 mb-6 text-sm mt-2">{tokens.globalNote} {language.tokens}</span>
|
||||||
|
|
||||||
<span class="text-neutral-200">{language.maxContextSize}</span>
|
<span class="text-neutral-200">{language.maxContextSize}</span>
|
||||||
<NumberInput min={0} max={getModelMaxContext($DataBase.aiModel)} marginBottom={true} bind:value={$DataBase.maxContext}/>
|
<NumberInput min={0} max={getModelMaxContext($DataBase.aiModel)} marginBottom={true} bind:value={$DataBase.maxContext}/>
|
||||||
@@ -303,7 +308,7 @@
|
|||||||
<span class="text-gray-400 mb-6 text-sm">{($DataBase.PresensePenalty / 100).toFixed(2)}</span>
|
<span class="text-gray-400 mb-6 text-sm">{($DataBase.PresensePenalty / 100).toFixed(2)}</span>
|
||||||
|
|
||||||
<span class="text-neutral-200 mt-2">{language.autoSuggest} <Help key="autoSuggest"/></span>
|
<span class="text-neutral-200 mt-2">{language.autoSuggest} <Help key="autoSuggest"/></span>
|
||||||
<textarea class="bg-transparent input-text mb-2 text-gray-200 resize-none h-20 min-h-20 focus:bg-selected text-xs w-full" autocomplete="off" bind:value={$DataBase.autoSuggestPrompt}></textarea>
|
<TextAreaInput height="20" autocomplete="off" bind:value={$DataBase.autoSuggestPrompt} />
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.autoSuggest} {language.tokens}</span>
|
<span class="text-gray-400 mb-6 text-sm">{tokens.autoSuggest} {language.tokens}</span>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
@@ -354,6 +359,6 @@
|
|||||||
<Check bind:check={$DataBase.promptPreprocess} name={language.promptPreprocess}/>
|
<Check bind:check={$DataBase.promptPreprocess} name={language.promptPreprocess}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button on:click={() => {openPresetList = true}} class="mt-4 drop-shadow-lg p-3 border-borderc border-solid flex justify-center items-center ml-2 mr-2 border-1 hover:bg-selected">{language.presets}</button>
|
<Button onClick={() => {openPresetList = true}} className="mt-4">{language.presets}</Button>
|
||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -2,20 +2,21 @@
|
|||||||
import { language } from "src/lang";
|
import { language } from "src/lang";
|
||||||
import { DataBase, saveImage, updateTextTheme } from "src/ts/storage/database";
|
import { DataBase, saveImage, updateTextTheme } from "src/ts/storage/database";
|
||||||
import { changeFullscreen, selectSingleFile, sleep } from "src/ts/util";
|
import { changeFullscreen, selectSingleFile, sleep } from "src/ts/util";
|
||||||
import Check from "src/lib/Others/Check.svelte";
|
import Check from "src/lib/UI/GUI/Check.svelte";
|
||||||
import Help from "src/lib/Others/Help.svelte";
|
import Help from "src/lib/Others/Help.svelte";
|
||||||
import SliderInput from "src/lib/UI/GUI/SliderInput.svelte";
|
import SliderInput from "src/lib/UI/GUI/SliderInput.svelte";
|
||||||
|
import SelectInput from "src/lib/UI/GUI/SelectInput.svelte";
|
||||||
|
import OptionInput from "src/lib/UI/GUI/OptionInput.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.display}</h2>
|
<h2 class="mb-2 text-2xl font-bold mt-2">{language.display}</h2>
|
||||||
|
|
||||||
<span class="text-neutral-200 mt-4">{language.theme}</span>
|
<span class="text-neutral-200 mt-4">{language.theme}</span>
|
||||||
<select class="bg-transparent input-text mt-2 text-gray-200 appearance-none text-sm" bind:value={$DataBase.theme}>
|
<SelectInput className="mt-2" bind:value={$DataBase.theme}>
|
||||||
<option value="" class="bg-darkbg appearance-none">Standard Risu</option>
|
<OptionInput value="" >Standard Risu</OptionInput>
|
||||||
<option value="waifu" class="bg-darkbg appearance-none">Waifulike</option>
|
<OptionInput value="waifu" >Waifulike</OptionInput>
|
||||||
<option value="waifuMobile" class="bg-darkbg appearance-none">WaifuCut</option>
|
<OptionInput value="waifuMobile" >WaifuCut</OptionInput>
|
||||||
<!-- <option value="free" class="bg-darkbg appearance-none">Freestyle</option> -->
|
</SelectInput>
|
||||||
</select>
|
|
||||||
|
|
||||||
|
|
||||||
{#if $DataBase.theme === "waifu"}
|
{#if $DataBase.theme === "waifu"}
|
||||||
@@ -29,11 +30,11 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<span class="text-neutral-200 mt-4">{language.textColor}</span>
|
<span class="text-neutral-200 mt-4">{language.textColor}</span>
|
||||||
<select class="bg-transparent input-text mt-2 text-gray-200 appearance-none" bind:value={$DataBase.textTheme} on:change={updateTextTheme}>
|
<SelectInput className="mt-2" bind:value={$DataBase.textTheme} on:change={updateTextTheme}>
|
||||||
<option value="standard" class="bg-darkbg appearance-none">{language.classicRisu}</option>
|
<OptionInput value="standard" >{language.classicRisu}</OptionInput>
|
||||||
<option value="highcontrast" class="bg-darkbg appearance-none">{language.highcontrast}</option>
|
<OptionInput value="highcontrast" >{language.highcontrast}</OptionInput>
|
||||||
<option value="custom" class="bg-darkbg appearance-none">Custom</option>
|
<OptionInput value="custom" >Custom</OptionInput>
|
||||||
</select>
|
</SelectInput>
|
||||||
|
|
||||||
{#if $DataBase.textTheme === "custom"}
|
{#if $DataBase.textTheme === "custom"}
|
||||||
<div class="flex items-center mt-2">
|
<div class="flex items-center mt-2">
|
||||||
|
|||||||
@@ -1,39 +1,41 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Check from "src/lib/Others/Check.svelte";
|
import Check from "src/lib/UI/GUI/Check.svelte";
|
||||||
import { changeLanguage, language } from "src/lang";
|
import { changeLanguage, language } from "src/lang";
|
||||||
import { DataBase } from "src/ts/storage/database";
|
import { DataBase } from "src/ts/storage/database";
|
||||||
import { sleep } from "src/ts/util";
|
import { sleep } from "src/ts/util";
|
||||||
import Help from "src/lib/Others/Help.svelte";
|
import Help from "src/lib/Others/Help.svelte";
|
||||||
|
import OptionInput from "src/lib/UI/GUI/OptionInput.svelte";
|
||||||
|
import SelectInput from "src/lib/UI/GUI/SelectInput.svelte";
|
||||||
let langChanged = false
|
let langChanged = false
|
||||||
</script>
|
</script>
|
||||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.language}</h2>
|
<h2 class="mb-2 text-2xl font-bold mt-2">{language.language}</h2>
|
||||||
|
|
||||||
<span class="text-neutral-200 mt-4">{language.UiLanguage}</span>
|
<span class="text-neutral-200 mt-4">{language.UiLanguage}</span>
|
||||||
<select class="bg-transparent input-text mt-2 text-gray-200 appearance-none text-sm" bind:value={$DataBase.language} on:change={async () => {
|
<SelectInput className="mt-2" bind:value={$DataBase.language} on:change={async () => {
|
||||||
await sleep(10)
|
await sleep(10)
|
||||||
changeLanguage($DataBase.language)
|
changeLanguage($DataBase.language)
|
||||||
langChanged = true
|
langChanged = true
|
||||||
}}>
|
}}>
|
||||||
<option value="en" class="bg-darkbg appearance-none">English</option>
|
<OptionInput value="en" >English</OptionInput>
|
||||||
<option value="ko" class="bg-darkbg appearance-none">한국어</option>
|
<OptionInput value="ko" >한국어</OptionInput>
|
||||||
<option value="cn" class="bg-darkbg appearance-none">中文</option>
|
<OptionInput value="cn" >中文</OptionInput>
|
||||||
</select>
|
</SelectInput>
|
||||||
{#if langChanged}
|
{#if langChanged}
|
||||||
<span class="bg-red-500 text-sm">Close the settings to take effect</span>
|
<span class="bg-red-500 text-sm">Close the settings to take effect</span>
|
||||||
{/if}
|
{/if}
|
||||||
<span class="text-neutral-200 mt-4">{language.translator}</span>
|
<span class="text-neutral-200 mt-4">{language.translator}</span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none text-sm" bind:value={$DataBase.translator}>
|
<SelectInput className="mt-2 mb-4" bind:value={$DataBase.translator}>
|
||||||
<option value="" class="bg-darkbg appearance-none">{language.disabled}</option>
|
<OptionInput value="" >{language.disabled}</OptionInput>
|
||||||
<option value="ko" class="bg-darkbg appearance-none">Korean</option>
|
<OptionInput value="ko" >Korean</OptionInput>
|
||||||
<option value="ru" class="bg-darkbg appearance-none">Russian</option>
|
<OptionInput value="ru" >Russian</OptionInput>
|
||||||
<option value="zh" class="bg-darkbg appearance-none">Chinese</option>
|
<OptionInput value="zh" >Chinese</OptionInput>
|
||||||
<option value="ja" class="bg-darkbg appearance-none">Japanese</option>
|
<OptionInput value="ja" >Japanese</OptionInput>
|
||||||
<option value="fr" class="bg-darkbg appearance-none">French</option>
|
<OptionInput value="fr" >French</OptionInput>
|
||||||
<option value="es" class="bg-darkbg appearance-none">Spanish</option>
|
<OptionInput value="es" >Spanish</OptionInput>
|
||||||
<option value="pt" class="bg-darkbg appearance-none">Portuguese</option>
|
<OptionInput value="pt" >Portuguese</OptionInput>
|
||||||
<option value="de" class="bg-darkbg appearance-none">German</option>
|
<OptionInput value="de" >German</OptionInput>
|
||||||
|
|
||||||
</select>
|
</SelectInput>
|
||||||
|
|
||||||
{#if $DataBase.translator}
|
{#if $DataBase.translator}
|
||||||
<div class="flex items-center mt-2">
|
<div class="flex items-center mt-2">
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Check from "src/lib/Others/Check.svelte";
|
import Check from "src/lib/UI/GUI/Check.svelte";
|
||||||
import { language } from "src/lang";
|
import { language } from "src/lang";
|
||||||
import Help from "src/lib/Others/Help.svelte";
|
import Help from "src/lib/Others/Help.svelte";
|
||||||
import { DataBase } from "src/ts/storage/database";
|
import { DataBase } from "src/ts/storage/database";
|
||||||
import { isTauri } from "src/ts/storage/globalApi";
|
import { isTauri } from "src/ts/storage/globalApi";
|
||||||
import NumberInput from "src/lib/UI/GUI/NumberInput.svelte";
|
import NumberInput from "src/lib/UI/GUI/NumberInput.svelte";
|
||||||
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
||||||
|
import SelectInput from "src/lib/UI/GUI/SelectInput.svelte";
|
||||||
|
import OptionInput from "src/lib/UI/GUI/OptionInput.svelte";
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.otherBots}</h2>
|
<h2 class="mb-2 text-2xl font-bold mt-2">{language.otherBots}</h2>
|
||||||
@@ -13,12 +15,12 @@
|
|||||||
<span class="text-neutral-200 mt-4 text-lg font-bold">{language.imageGeneration}</span>
|
<span class="text-neutral-200 mt-4 text-lg font-bold">{language.imageGeneration}</span>
|
||||||
|
|
||||||
<span class="text-neutral-200 mt-2">{language.provider} <Help key="sdProvider"/></span>
|
<span class="text-neutral-200 mt-2">{language.provider} <Help key="sdProvider"/></span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none text-sm" bind:value={$DataBase.sdProvider}>
|
<SelectInput className="mt-2 mb-4" bind:value={$DataBase.sdProvider}>
|
||||||
<option value="" class="bg-darkbg appearance-none">None</option>
|
<OptionInput value="" >None</OptionInput>
|
||||||
<option value="webui" class="bg-darkbg appearance-none">Stable Diffusion WebUI</option>
|
<OptionInput value="webui" >Stable Diffusion WebUI</OptionInput>
|
||||||
<!-- TODO -->
|
<!-- TODO -->
|
||||||
<!-- <option value="runpod" class="bg-darkbg appearance-none">Runpod Serverless</option> -->
|
<!-- <OptionInput value="runpod" >Runpod Serverless</OptionInput> -->
|
||||||
</select>
|
</SelectInput>
|
||||||
|
|
||||||
{#if $DataBase.sdProvider === 'webui'}
|
{#if $DataBase.sdProvider === 'webui'}
|
||||||
<span class="text-draculared text-xs mb-2">You must use WebUI with --api flag</span>
|
<span class="text-draculared text-xs mb-2">You must use WebUI with --api flag</span>
|
||||||
@@ -64,12 +66,12 @@
|
|||||||
|
|
||||||
<span class="text-neutral-200 mt-4 text-lg font-bold">{language.SuperMemory} <Help key="superMemory" /></span>
|
<span class="text-neutral-200 mt-4 text-lg font-bold">{language.SuperMemory} <Help key="superMemory" /></span>
|
||||||
<span class="text-neutral-200 mt-4">{language.SuperMemory} {language.model}</span>
|
<span class="text-neutral-200 mt-4">{language.SuperMemory} {language.model}</span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-2 text-gray-200 appearance-none text-sm" bind:value={$DataBase.supaMemoryType}>
|
<SelectInput className="mt-2 mb-2" bind:value={$DataBase.supaMemoryType}>
|
||||||
<option value="none" class="bg-darkbg appearance-none">None</option>
|
<OptionInput value="none" >None</OptionInput>
|
||||||
<option value="davinci" class="bg-darkbg appearance-none">OpenAI Davinci</option>
|
<OptionInput value="davinci" >OpenAI Davinci</OptionInput>
|
||||||
<option value="curie" class="bg-darkbg appearance-none">OpenAI Curie</option>
|
<OptionInput value="curie" >OpenAI Curie</OptionInput>
|
||||||
<option value="subModel" class="bg-darkbg appearance-none">{language.submodel} ({language.unrecommended})</option>
|
<OptionInput value="subModel" >{language.submodel} ({language.unrecommended})</OptionInput>
|
||||||
</select>
|
</SelectInput>
|
||||||
{#if $DataBase.supaMemoryType === 'davinci' || $DataBase.supaMemoryType === 'curie'}
|
{#if $DataBase.supaMemoryType === 'davinci' || $DataBase.supaMemoryType === 'curie'}
|
||||||
<span class="text-neutral-200">{language.SuperMemory} OpenAI Key</span>
|
<span class="text-neutral-200">{language.SuperMemory} OpenAI Key</span>
|
||||||
<TextInput size="sm" marginBottom bind:value={$DataBase.supaMemoryKey}/>
|
<TextInput size="sm" marginBottom bind:value={$DataBase.supaMemoryKey}/>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { language } from "src/lang";
|
import { language } from "src/lang";
|
||||||
import BaseRoundedButton from "src/lib/UI/BaseRoundedButton.svelte";
|
import BaseRoundedButton from "src/lib/UI/BaseRoundedButton.svelte";
|
||||||
|
import TextAreaInput from "src/lib/UI/GUI/TextAreaInput.svelte";
|
||||||
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
||||||
import { alertConfirm, alertError } from "src/ts/alert";
|
import { alertConfirm, alertError } from "src/ts/alert";
|
||||||
import { changeUserPersona, getCharImage, saveUserPersona, selectUserImg } from "src/ts/characters";
|
import { changeUserPersona, getCharImage, saveUserPersona, selectUserImg } from "src/ts/characters";
|
||||||
@@ -74,7 +75,7 @@
|
|||||||
<span class="text-sm text-gray-500">{language.name}</span>
|
<span class="text-sm text-gray-500">{language.name}</span>
|
||||||
<TextInput marginBottom size="lg" placeholder="User" bind:value={$DataBase.username} />
|
<TextInput marginBottom size="lg" placeholder="User" bind:value={$DataBase.username} />
|
||||||
<span class="text-sm text-gray-500">{language.description}</span>
|
<span class="text-sm text-gray-500">{language.description}</span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none h-32 min-h-20 focus:bg-selected text-xs w-full" autocomplete="off" bind:value={$DataBase.personaPrompt} placeholder={`Put the description of this persona here.\nExample: [<user> is a 20 year old girl.]`}></textarea>
|
<TextAreaInput height="32" autocomplete="off" bind:value={$DataBase.personaPrompt} placeholder={`Put the description of this persona here.\nExample: [<user> is a 20 year old girl.]`} />
|
||||||
<div>
|
<div>
|
||||||
<button class="float-right rounded-md border border-red-700 p-2 hover:bg-red-700 transition-colors mt-4 text-sm" on:click={async () => {
|
<button class="float-right rounded-md border border-red-700 p-2 hover:bg-red-700 transition-colors mt-4 text-sm" on:click={async () => {
|
||||||
if($DataBase.personas.length === 1){
|
if($DataBase.personas.length === 1){
|
||||||
|
|||||||
@@ -4,9 +4,11 @@
|
|||||||
import { alertConfirm } from "src/ts/alert";
|
import { alertConfirm } from "src/ts/alert";
|
||||||
import { DataBase } from "src/ts/storage/database";
|
import { DataBase } from "src/ts/storage/database";
|
||||||
import { importPlugin } from "src/ts/plugins/plugins";
|
import { importPlugin } from "src/ts/plugins/plugins";
|
||||||
import Check from "src/lib/Others/Check.svelte";
|
import Check from "src/lib/UI/GUI/Check.svelte";
|
||||||
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
|
||||||
import NumberInput from "src/lib/UI/GUI/NumberInput.svelte";
|
import NumberInput from "src/lib/UI/GUI/NumberInput.svelte";
|
||||||
|
import SelectInput from "src/lib/UI/GUI/SelectInput.svelte";
|
||||||
|
import OptionInput from "src/lib/UI/GUI/OptionInput.svelte";
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.plugin}</h2>
|
<h2 class="mb-2 text-2xl font-bold mt-2">{language.plugin}</h2>
|
||||||
@@ -44,11 +46,11 @@
|
|||||||
{#each Object.keys(plugin.arguments) as arg}
|
{#each Object.keys(plugin.arguments) as arg}
|
||||||
<span>{arg}</span>
|
<span>{arg}</span>
|
||||||
{#if Array.isArray(plugin.arguments[arg])}
|
{#if Array.isArray(plugin.arguments[arg])}
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none" bind:value={$DataBase.plugins[i].realArg[arg]}>
|
<SelectInput className="mt-2 mb-4" bind:value={$DataBase.plugins[i].realArg[arg]}>
|
||||||
{#each plugin.arguments[arg] as a}
|
{#each plugin.arguments[arg] as a}
|
||||||
<option value={a} class="bg-darkbg appearance-none">a</option>
|
<OptionInput value={a}>a</OptionInput>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</SelectInput>
|
||||||
{:else if plugin.arguments[arg] === 'string'}
|
{:else if plugin.arguments[arg] === 'string'}
|
||||||
<TextInput bind:value={$DataBase.plugins[i].realArg[arg]} />
|
<TextInput bind:value={$DataBase.plugins[i].realArg[arg]} />
|
||||||
{:else if plugin.arguments[arg] === 'int'}
|
{:else if plugin.arguments[arg] === 'int'}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import { getCharImage, selectUserImg } from "src/ts/characters";
|
import { getCharImage, selectUserImg } from "src/ts/characters";
|
||||||
import { loadRisuAccountData, saveRisuAccountData } from "src/ts/drive/accounter";
|
import { loadRisuAccountData, saveRisuAccountData } from "src/ts/drive/accounter";
|
||||||
import { DataBase } from "src/ts/storage/database";
|
import { DataBase } from "src/ts/storage/database";
|
||||||
import Check from "src/lib/Others/Check.svelte";
|
import Check from "src/lib/UI/GUI/Check.svelte";
|
||||||
import { alertConfirm, alertSelect } from "src/ts/alert";
|
import { alertConfirm, alertSelect } from "src/ts/alert";
|
||||||
import { forageStorage, isNodeServer, isTauri } from "src/ts/storage/globalApi";
|
import { forageStorage, isNodeServer, isTauri } from "src/ts/storage/globalApi";
|
||||||
import { unMigrationAccount } from "src/ts/storage/accountStorage";
|
import { unMigrationAccount } from "src/ts/storage/accountStorage";
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import { DataBase, saveImage as saveAsset, type Database, type character, type groupChat } from "../../ts/storage/database";
|
import { DataBase, saveImage as saveAsset, type Database, type character, type groupChat } from "../../ts/storage/database";
|
||||||
import { selectedCharID } from "../../ts/stores";
|
import { selectedCharID } from "../../ts/stores";
|
||||||
import { PlusIcon, SmileIcon, TrashIcon, UserIcon, ActivityIcon, BookIcon, LoaderIcon, User, DnaIcon, CurlyBraces, Volume2Icon, XIcon } from 'lucide-svelte'
|
import { PlusIcon, SmileIcon, TrashIcon, UserIcon, ActivityIcon, BookIcon, LoaderIcon, User, DnaIcon, CurlyBraces, Volume2Icon, XIcon } from 'lucide-svelte'
|
||||||
import Check from "../Others/Check.svelte";
|
import Check from "../UI/GUI/Check.svelte";
|
||||||
import { addCharEmotion, addingEmotion, getCharImage, rmCharEmotion, selectCharImg, makeGroupImage } from "../../ts/characters";
|
import { addCharEmotion, addingEmotion, getCharImage, rmCharEmotion, selectCharImg, makeGroupImage } from "../../ts/characters";
|
||||||
import LoreBook from "./LoreBookSetting.svelte";
|
import LoreBook from "./LoreBookSetting.svelte";
|
||||||
import { alertConfirm, alertError, alertSelectChar } from "../../ts/alert";
|
import { alertConfirm, alertError, alertSelectChar } from "../../ts/alert";
|
||||||
@@ -18,9 +18,13 @@
|
|||||||
import { getElevenTTSVoices, getWebSpeechTTSVoices, getVOICEVOXVoices } from "src/ts/process/tts";
|
import { getElevenTTSVoices, getWebSpeechTTSVoices, getVOICEVOXVoices } from "src/ts/process/tts";
|
||||||
import { checkCharOrder, getFileSrc } from "src/ts/storage/globalApi";
|
import { checkCharOrder, getFileSrc } from "src/ts/storage/globalApi";
|
||||||
import { addGroupChar, rmCharFromGroup } from "src/ts/process/group";
|
import { addGroupChar, rmCharFromGroup } from "src/ts/process/group";
|
||||||
import HubUpload from "../UI/HubUpload.svelte";
|
import HubUpload from "../UI/HubUpload.svelte";
|
||||||
import TextInput from "../UI/GUI/TextInput.svelte";
|
import TextInput from "../UI/GUI/TextInput.svelte";
|
||||||
import NumberInput from "../UI/GUI/NumberInput.svelte";
|
import NumberInput from "../UI/GUI/NumberInput.svelte";
|
||||||
|
import TextAreaInput from "../UI/GUI/TextAreaInput.svelte";
|
||||||
|
import Button from "../UI/GUI/Button.svelte";
|
||||||
|
import SelectInput from "../UI/GUI/SelectInput.svelte";
|
||||||
|
import OptionInput from "../UI/GUI/OptionInput.svelte";
|
||||||
|
|
||||||
let subMenu = 0
|
let subMenu = 0
|
||||||
let openHubUpload = false
|
let openHubUpload = false
|
||||||
@@ -157,10 +161,10 @@
|
|||||||
{#if currentChar.type !== 'group'}
|
{#if currentChar.type !== 'group'}
|
||||||
<TextInput size="xl" marginBottom placeholder="Character Name" bind:value={currentChar.data.name} />
|
<TextInput size="xl" marginBottom placeholder="Character Name" bind:value={currentChar.data.name} />
|
||||||
<span class="text-neutral-200">{language.description} <Help key="charDesc"/></span>
|
<span class="text-neutral-200">{language.description} <Help key="charDesc"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.desc}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.desc}></TextAreaInput>
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.desc} {language.tokens}</span>
|
<span class="text-gray-400 mb-6 text-sm">{tokens.desc} {language.tokens}</span>
|
||||||
<span class="text-neutral-200">{language.firstMessage} <Help key="charFirstMessage"/></span>
|
<span class="text-neutral-200">{language.firstMessage} <Help key="charFirstMessage"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.firstMessage}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.firstMessage}></TextAreaInput>
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.firstMsg} {language.tokens}</span>
|
<span class="text-gray-400 mb-6 text-sm">{tokens.firstMsg} {language.tokens}</span>
|
||||||
|
|
||||||
{:else}
|
{:else}
|
||||||
@@ -214,7 +218,7 @@
|
|||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
<span class="text-neutral-200">{language.authorNote} <Help key="chatNote"/></span>
|
<span class="text-neutral-200">{language.authorNote} <Help key="chatNote"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none h-20 focus:bg-selected text-xs" autocomplete="off" bind:value={currentChar.data.chats[currentChar.data.chatPage].note}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.chats[currentChar.data.chatPage].note}></TextAreaInput>
|
||||||
<span class="text-gray-400 mb-6 text-sm">{tokens.localNote} {language.tokens}</span>
|
<span class="text-gray-400 mb-6 text-sm">{tokens.localNote} {language.tokens}</span>
|
||||||
<div class="flex mt-6 items-center">
|
<div class="flex mt-6 items-center">
|
||||||
<Check bind:check={$DataBase.jailbreakToggle} name={language.jailbreakToggle}/>
|
<Check bind:check={$DataBase.jailbreakToggle} name={language.jailbreakToggle}/>
|
||||||
@@ -259,53 +263,57 @@
|
|||||||
<!-- svelte-ignore empty-block -->
|
<!-- svelte-ignore empty-block -->
|
||||||
|
|
||||||
{#if currentChar.type !== 'group'}
|
{#if currentChar.type !== 'group'}
|
||||||
<select class="bg-transparent input-text mb-4 text-gray-200 appearance-none" bind:value={currentChar.data.viewScreen}>
|
<SelectInput className="mb-2" bind:value={currentChar.data.viewScreen}>
|
||||||
<option value="none" class="bg-darkbg appearance-none">{language.none}</option>
|
<OptionInput value="none">{language.none}</OptionInput>
|
||||||
<option value="emotion" class="bg-darkbg appearance-none">{language.emotionImage}</option>
|
<OptionInput value="emotion">{language.emotionImage}</OptionInput>
|
||||||
<option value="imggen" class="bg-darkbg appearance-none">{language.imageGeneration}</option>
|
<OptionInput value="imggen">{language.imageGeneration}</OptionInput>
|
||||||
</select>
|
</SelectInput>
|
||||||
{:else}
|
{:else}
|
||||||
<select class="bg-transparent input-text mb-4 text-gray-200 appearance-none" bind:value={currentChar.data.viewScreen}>
|
<SelectInput className="mb-2" bind:value={currentChar.data.viewScreen}>
|
||||||
<option value="none" class="bg-darkbg appearance-none">{language.none}</option>
|
<OptionInput value="none">{language.none}</OptionInput>
|
||||||
<option value="single" class="bg-darkbg appearance-none">{language.singleView}</option>
|
<OptionInput value="single">{language.singleView}</OptionInput>
|
||||||
<option value="multiple" class="bg-darkbg appearance-none">{language.SpacedView}</option>
|
<OptionInput value="multiple">{language.SpacedView}</OptionInput>
|
||||||
<option value="emp" class="bg-darkbg appearance-none">{language.emphasizedView}</option>
|
<OptionInput value="emp">{language.emphasizedView}</OptionInput>
|
||||||
|
|
||||||
</select>
|
</SelectInput>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if currentChar.data.viewScreen === 'emotion'}
|
{#if currentChar.data.viewScreen === 'emotion'}
|
||||||
<span class="text-neutral-200 mt-6">{language.emotionImage} <Help key="emotion"/></span>
|
<span class="text-neutral-200 mt-6">{language.emotionImage} <Help key="emotion"/></span>
|
||||||
<span class="text-gray-400 text-xs">{language.emotionWarn}</span>
|
<span class="text-gray-400 text-xs">{language.emotionWarn}</span>
|
||||||
|
|
||||||
<table class="contain w-full max-w-full tabler">
|
<div class="w-full max-w-full border border-selected p-2 rounded-md">
|
||||||
<tr>
|
|
||||||
<th class="font-medium w-1/3">{language.image}</th>
|
<table class="w-full max-w-full tabler">
|
||||||
<th class="font-medium w-1/2">{language.emotion}</th>
|
|
||||||
<th class="font-medium"></th>
|
|
||||||
</tr>
|
|
||||||
{#if currentChar.data.emotionImages.length === 0}
|
|
||||||
<tr>
|
<tr>
|
||||||
<div class="text-gray-500">{language.noImages}</div>
|
<th class="font-medium w-1/3">{language.image}</th>
|
||||||
|
<th class="font-medium w-1/2">{language.emotion}</th>
|
||||||
|
<th class="font-medium"></th>
|
||||||
</tr>
|
</tr>
|
||||||
{:else}
|
{#if currentChar.data.emotionImages.length === 0}
|
||||||
{#each emos as emo, i}
|
|
||||||
<tr>
|
<tr>
|
||||||
{#await getCharImage(emo[1], 'plain')}
|
<div class="text-gray-500">{language.noImages}</div>
|
||||||
<td class="font-medium truncate w-1/3"></td>
|
|
||||||
{:then im}
|
|
||||||
<td class="font-medium truncate w-1/3"><img src={im} alt="img" class="w-full"></td>
|
|
||||||
{/await}
|
|
||||||
<td class="font-medium truncate w-1/2">
|
|
||||||
<TextInput marginBottom size='lg' bind:value={currentChar.data.emotionImages[i][0]} />
|
|
||||||
</td>
|
|
||||||
<button class="font-medium cursor-pointer hover:text-green-500" on:click={() => {
|
|
||||||
rmCharEmotion($selectedCharID,i)
|
|
||||||
}}><TrashIcon /></button>
|
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{:else}
|
||||||
{/if}
|
{#each emos as emo, i}
|
||||||
</table>
|
<tr>
|
||||||
|
{#await getCharImage(emo[1], 'plain')}
|
||||||
|
<td class="font-medium truncate w-1/3"></td>
|
||||||
|
{:then im}
|
||||||
|
<td class="font-medium truncate w-1/3"><img src={im} alt="img" class="w-full"></td>
|
||||||
|
{/await}
|
||||||
|
<td class="font-medium truncate w-1/2">
|
||||||
|
<TextInput marginBottom size='lg' bind:value={currentChar.data.emotionImages[i][0]} />
|
||||||
|
</td>
|
||||||
|
<button class="font-medium cursor-pointer hover:text-green-500" on:click={() => {
|
||||||
|
rmCharEmotion($selectedCharID,i)
|
||||||
|
}}><TrashIcon /></button>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="text-gray-500 hover:text-neutral-200 mt-2 flex">
|
<div class="text-gray-500 hover:text-neutral-200 mt-2 flex">
|
||||||
{#if !$addingEmotion}
|
{#if !$addingEmotion}
|
||||||
@@ -321,44 +329,44 @@
|
|||||||
<span class="text-neutral-200 mt-6">{language.imageGeneration} <Help key="imggen"/></span>
|
<span class="text-neutral-200 mt-6">{language.imageGeneration} <Help key="imggen"/></span>
|
||||||
<span class="text-gray-400 text-xs">{language.emotionWarn}</span>
|
<span class="text-gray-400 text-xs">{language.emotionWarn}</span>
|
||||||
|
|
||||||
|
<div class="w-full max-w-full border border-selected rounded-md p-2">
|
||||||
<table class="contain w-full max-w-full tabler">
|
<table class="w-full max-w-full tabler">
|
||||||
<tr>
|
|
||||||
<th class="font-medium w-1/3">{language.key}</th>
|
|
||||||
<th class="font-medium w-1/2">{language.value}</th>
|
|
||||||
<th class="font-medium"></th>
|
|
||||||
</tr>
|
|
||||||
{#if currentChar.data.sdData.length === 0}
|
|
||||||
<tr>
|
<tr>
|
||||||
<div class="text-gray-500">{language.noData}</div>
|
<th class="font-medium w-1/3">{language.key}</th>
|
||||||
|
<th class="font-medium w-1/2">{language.value}</th>
|
||||||
|
<th class="font-medium"></th>
|
||||||
</tr>
|
</tr>
|
||||||
{/if}
|
{#if currentChar.data.sdData.length === 0}
|
||||||
{#each currentChar.data.sdData as emo, i}
|
<tr>
|
||||||
<tr>
|
<div class="text-gray-500">{language.noData}</div>
|
||||||
<td class="font-medium truncate w-1/3">
|
</tr>
|
||||||
<TextInput size="sm" marginBottom bind:value={currentChar.data.sdData[i][0]} />
|
{/if}
|
||||||
</td>
|
{#each currentChar.data.sdData as emo, i}
|
||||||
<td class="font-medium truncate w-1/2">
|
<tr>
|
||||||
<TextInput size="sm" marginBottom bind:value={currentChar.data.sdData[i][1]} />
|
<td class="font-medium truncate w-1/3">
|
||||||
</td>
|
<TextInput size="sm" marginBottom bind:value={currentChar.data.sdData[i][0]} />
|
||||||
{#if (!['always','negative'].includes(currentChar.data.sdData[i][0]))}
|
</td>
|
||||||
<button class="font-medium flex justify-center items-center h-full cursor-pointer hover:text-green-500" on:click={() => {
|
<td class="font-medium truncate w-1/2">
|
||||||
let db = ($DataBase)
|
<TextInput size="sm" marginBottom bind:value={currentChar.data.sdData[i][1]} />
|
||||||
let charId = $selectedCharID
|
</td>
|
||||||
let dbChar = db.characters[charId]
|
{#if (!['always','negative'].includes(currentChar.data.sdData[i][0]))}
|
||||||
if(dbChar.type !== 'group'){
|
<button class="font-medium flex justify-center items-center h-full cursor-pointer hover:text-green-500" on:click={() => {
|
||||||
dbChar.sdData.splice(i, 1)
|
let db = ($DataBase)
|
||||||
db.characters[charId] = dbChar
|
let charId = $selectedCharID
|
||||||
}
|
let dbChar = db.characters[charId]
|
||||||
$DataBase = (db)
|
if(dbChar.type !== 'group'){
|
||||||
}}><TrashIcon /></button>
|
dbChar.sdData.splice(i, 1)
|
||||||
{:else}
|
db.characters[charId] = dbChar
|
||||||
<td></td>
|
}
|
||||||
{/if}
|
$DataBase = (db)
|
||||||
</tr>
|
}}><TrashIcon /></button>
|
||||||
{/each}
|
{:else}
|
||||||
|
<td></td>
|
||||||
</table>
|
{/if}
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
<div class="text-gray-500 hover:text-neutral-200 mt-2 flex">
|
<div class="text-gray-500 hover:text-neutral-200 mt-2 flex">
|
||||||
{#if !$addingEmotion}
|
{#if !$addingEmotion}
|
||||||
<button class="cursor-pointer hover:text-green-500" on:click={() => {
|
<button class="cursor-pointer hover:text-green-500" on:click={() => {
|
||||||
@@ -379,7 +387,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<span class="text-neutral-200 mt-6">{language.currentImageGeneration}</span>
|
<span class="text-neutral-200 mt-6">{language.currentImageGeneration}</span>
|
||||||
{#if currentChar.data.chats[currentChar.data.chatPage].sdData}
|
{#if currentChar.data.chats[currentChar.data.chatPage].sdData}
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.chats[currentChar.data.chatPage].sdData}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.chats[currentChar.data.chatPage].sdData}></TextAreaInput>
|
||||||
{:else}
|
{:else}
|
||||||
<span><div class="text-gray-500">{language.noData}</div></span>
|
<span><div class="text-gray-500">{language.noData}</div></span>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -392,7 +400,9 @@
|
|||||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.scripts}</h2>
|
<h2 class="mb-2 text-2xl font-bold mt-2">{language.scripts}</h2>
|
||||||
|
|
||||||
<span class="text-neutral-200 mt-2">Bias <Help key="bias"/></span>
|
<span class="text-neutral-200 mt-2">Bias <Help key="bias"/></span>
|
||||||
<table class="contain w-full max-w-full tabler mt-2">
|
<div class="w-full max-w-full border border-selected rounded-md p-2">
|
||||||
|
|
||||||
|
<table class="w-full max-w-full tabler mt-2">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="font-medium w-1/2">Bias</th>
|
<th class="font-medium w-1/2">Bias</th>
|
||||||
<th class="font-medium w-1/3">{language.value}</th>
|
<th class="font-medium w-1/3">{language.value}</th>
|
||||||
@@ -433,21 +443,25 @@
|
|||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<span class="text-neutral-200 mt-4">{language.regexScript} <Help key="regexScript"/></span>
|
<span class="text-neutral-200 mt-4">{language.regexScript} <Help key="regexScript"/></span>
|
||||||
<table class="contain w-full max-w-full tabler mt-2 flex flex-col p-2 gap-2">
|
<div class="w-full max-w-full border border-selected rounded-md p-2">
|
||||||
{#if currentChar.data.customscript.length === 0}
|
<table class="w-full max-w-full tabler mt-2 flex flex-col p-2 gap-2">
|
||||||
<div class="text-gray-500">No Scripts</div>
|
{#if currentChar.data.customscript.length === 0}
|
||||||
{/if}
|
<div class="text-gray-500">No Scripts</div>
|
||||||
{#each currentChar.data.customscript as customscript, i}
|
{/if}
|
||||||
<RegexData bind:value={currentChar.data.customscript[i]} onRemove={() => {
|
{#each currentChar.data.customscript as customscript, i}
|
||||||
if(currentChar.type === 'character'){
|
<RegexData bind:value={currentChar.data.customscript[i]} onRemove={() => {
|
||||||
let customscript = currentChar.data.customscript
|
if(currentChar.type === 'character'){
|
||||||
customscript.splice(i, 1)
|
let customscript = currentChar.data.customscript
|
||||||
currentChar.data.customscript = customscript
|
customscript.splice(i, 1)
|
||||||
}
|
currentChar.data.customscript = customscript
|
||||||
}}/>
|
}
|
||||||
{/each}
|
}}/>
|
||||||
</table>
|
{/each}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
<button class="font-medium cursor-pointer hover:text-green-500 mb-2" on:click={() => {
|
<button class="font-medium cursor-pointer hover:text-green-500 mb-2" on:click={() => {
|
||||||
if(currentChar.type === 'character'){
|
if(currentChar.type === 'character'){
|
||||||
let script = currentChar.data.customscript
|
let script = currentChar.data.customscript
|
||||||
@@ -465,16 +479,16 @@
|
|||||||
{#if currentChar.type === 'character'}
|
{#if currentChar.type === 'character'}
|
||||||
<h2 class="mb-2 text-2xl font-bold mt-2">TTS</h2>
|
<h2 class="mb-2 text-2xl font-bold mt-2">TTS</h2>
|
||||||
<span class="text-neutral-200">{language.provider}</span>
|
<span class="text-neutral-200">{language.provider}</span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none text-sm" bind:value={currentChar.data.ttsMode} on:change={() => {
|
<SelectInput className="mb-4 mt-2" bind:value={currentChar.data.ttsMode} on:change={() => {
|
||||||
if(currentChar.type === 'character'){
|
if(currentChar.type === 'character'){
|
||||||
currentChar.data.ttsSpeech = ''
|
currentChar.data.ttsSpeech = ''
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
<option value="" class="bg-darkbg appearance-none">{language.disabled}</option>
|
<OptionInput value="">{language.disabled}</OptionInput>
|
||||||
<option value="elevenlab" class="bg-darkbg appearance-none">ElevenLabs</option>
|
<OptionInput value="elevenlab">ElevenLabs</OptionInput>
|
||||||
<option value="webspeech" class="bg-darkbg appearance-none">Web Speech</option>
|
<OptionInput value="webspeech">Web Speech</OptionInput>
|
||||||
<option value="VOICEVOX" class="bg-darkbg appearance-none">VOICEVOX</option>
|
<OptionInput value="VOICEVOX">VOICEVOX</OptionInput>
|
||||||
</select>
|
</SelectInput>
|
||||||
|
|
||||||
|
|
||||||
{#if currentChar.data.ttsMode === 'webspeech'}
|
{#if currentChar.data.ttsMode === 'webspeech'}
|
||||||
@@ -482,12 +496,12 @@
|
|||||||
<span class="text-neutral-200">Web Speech isn't supported in your browser or OS</span>
|
<span class="text-neutral-200">Web Speech isn't supported in your browser or OS</span>
|
||||||
{:else}
|
{:else}
|
||||||
<span class="text-neutral-200">{language.Speech}</span>
|
<span class="text-neutral-200">{language.Speech}</span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none text-sm" bind:value={currentChar.data.ttsSpeech}>
|
<SelectInput className="mb-4 mt-2" bind:value={currentChar.data.ttsSpeech}>
|
||||||
<option value="" class="bg-darkbg appearance-none">Auto</option>
|
<OptionInput value="">Auto</OptionInput>
|
||||||
{#each getWebSpeechTTSVoices() as voice}
|
{#each getWebSpeechTTSVoices() as voice}
|
||||||
<option value={voice} class="bg-darkbg appearance-none">{voice}</option>
|
<OptionInput value={voice}>{voice}</OptionInput>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</SelectInput>
|
||||||
{#if currentChar.data.ttsSpeech !== ''}
|
{#if currentChar.data.ttsSpeech !== ''}
|
||||||
<span class="text-red-400 text-sm">If you do not set it to Auto, it may not work properly when importing from another OS or browser.</span>
|
<span class="text-red-400 text-sm">If you do not set it to Auto, it may not work properly when importing from another OS or browser.</span>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -496,29 +510,29 @@
|
|||||||
<span class="text-sm mb-2 text-gray-400">Please set the ElevenLabs API key in "global Settings → Bot Settings → Others → ElevenLabs API key"</span>
|
<span class="text-sm mb-2 text-gray-400">Please set the ElevenLabs API key in "global Settings → Bot Settings → Others → ElevenLabs API key"</span>
|
||||||
{#await getElevenTTSVoices() then voices}
|
{#await getElevenTTSVoices() then voices}
|
||||||
<span class="text-neutral-200">{language.Speech}</span>
|
<span class="text-neutral-200">{language.Speech}</span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none text-sm" bind:value={currentChar.data.ttsSpeech}>
|
<SelectInput className="mb-4 mt-2" bind:value={currentChar.data.ttsSpeech}>
|
||||||
<option value="" class="bg-darkbg appearance-none">Unset</option>
|
<OptionInput value="">Unset</OptionInput>
|
||||||
{#each voices as voice}
|
{#each voices as voice}
|
||||||
<option value={voice.voice_id} class="bg-darkbg appearance-none">{voice.name}</option>
|
<OptionInput value={voice.voice_id}>{voice.name}</OptionInput>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</SelectInput>
|
||||||
{/await}
|
{/await}
|
||||||
{:else if currentChar.data.ttsMode === 'VOICEVOX'}
|
{:else if currentChar.data.ttsMode === 'VOICEVOX'}
|
||||||
<span class="text-neutral-200">Speaker</span>
|
<span class="text-neutral-200">Speaker</span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none text-sm" bind:value={currentChar.data.voicevoxConfig.speaker}>
|
<SelectInput className="mb-4 mt-2" bind:value={currentChar.data.voicevoxConfig.speaker}>
|
||||||
{#await getVOICEVOXVoices() then voices}
|
{#await getVOICEVOXVoices() then voices}
|
||||||
{#each voices as voice}
|
{#each voices as voice}
|
||||||
<option value={voice.list} class="bg-darkbg appearance-none" selected={currentChar.data.voicevoxConfig.speaker === voice.list}>{voice.name}</option>
|
<OptionInput value={voice.list} selected={currentChar.data.voicevoxConfig.speaker === voice.list}>{voice.name}</OptionInput>
|
||||||
{/each}
|
{/each}
|
||||||
{/await}
|
{/await}
|
||||||
</select>
|
</SelectInput>
|
||||||
{#if currentChar.data.voicevoxConfig.speaker}
|
{#if currentChar.data.voicevoxConfig.speaker}
|
||||||
<span class="text=neutral-200">Style</span>
|
<span class="text=neutral-200">Style</span>
|
||||||
<select class="bg-transparent input-text mt-2 mb-4 text-gray-200 appearance-none text-sm" bind:value={currentChar.data.ttsSpeech}>
|
<SelectInput className="mb-4 mt-2" bind:value={currentChar.data.ttsSpeech}>
|
||||||
{#each JSON.parse(currentChar.data.voicevoxConfig.speaker) as styles}
|
{#each JSON.parse(currentChar.data.voicevoxConfig.speaker) as styles}
|
||||||
<option value={styles.id} class="bg-darkbg appearance-none" selected={currentChar.data.ttsSpeech === styles.id}>{styles.name}</option>
|
<OptionInput value={styles.id} selected={currentChar.data.ttsSpeech === styles.id}>{styles.name}</OptionInput>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</SelectInput>
|
||||||
{/if}
|
{/if}
|
||||||
<span class="text-neutral-200">Speed scale</span>
|
<span class="text-neutral-200">Speed scale</span>
|
||||||
<NumberInput size={"sm"} marginBottom bind:value={currentChar.data.voicevoxConfig.SPEED_SCALE}/>
|
<NumberInput size={"sm"} marginBottom bind:value={currentChar.data.voicevoxConfig.SPEED_SCALE}/>
|
||||||
@@ -543,35 +557,35 @@
|
|||||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.advancedSettings}</h2>
|
<h2 class="mb-2 text-2xl font-bold mt-2">{language.advancedSettings}</h2>
|
||||||
{#if currentChar.type !== 'group'}
|
{#if currentChar.type !== 'group'}
|
||||||
<span class="text-neutral-200">{language.exampleMessage} <Help key="exampleMessage"/></span>
|
<span class="text-neutral-200">{language.exampleMessage} <Help key="exampleMessage"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.exampleMessage}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.exampleMessage}></TextAreaInput>
|
||||||
|
|
||||||
<span class="text-neutral-200">{language.creatorNotes} <Help key="creatorQuotes"/></span>
|
<span class="text-neutral-200">{language.creatorNotes} <Help key="creatorQuotes"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.creatorNotes} on:input={() => {
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.creatorNotes} on:input={() => {
|
||||||
currentChar.data.removedQuotes = false
|
currentChar.data.removedQuotes = false
|
||||||
}}></textarea>
|
}}></TextAreaInput>
|
||||||
|
|
||||||
<span class="text-neutral-200">{language.systemPrompt} <Help key="systemPrompt"/></span>
|
<span class="text-neutral-200">{language.systemPrompt} <Help key="systemPrompt"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.systemPrompt}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.systemPrompt}></TextAreaInput>
|
||||||
|
|
||||||
<span class="text-neutral-200">{language.replaceGlobalNote} <Help key="replaceGlobalNote"/></span>
|
<span class="text-neutral-200">{language.replaceGlobalNote} <Help key="replaceGlobalNote"/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.replaceGlobalNote}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.replaceGlobalNote}></TextAreaInput>
|
||||||
|
|
||||||
|
|
||||||
{#if currentChar.data.chats[currentChar.data.chatPage].supaMemoryData && currentChar.data.chats[currentChar.data.chatPage].supaMemoryData.length > 4}
|
{#if currentChar.data.chats[currentChar.data.chatPage].supaMemoryData && currentChar.data.chats[currentChar.data.chatPage].supaMemoryData.length > 4}
|
||||||
<span class="text-neutral-200">{language.SuperMemory}</span>
|
<span class="text-neutral-200">{language.SuperMemory}</span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.chats[currentChar.data.chatPage].supaMemoryData}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.chats[currentChar.data.chatPage].supaMemoryData}></TextAreaInput>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $DataBase.showUnrecommended || currentChar.data.personality.length > 3}
|
{#if $DataBase.showUnrecommended || currentChar.data.personality.length > 3}
|
||||||
<span class="text-neutral-200">{language.personality} <Help key="personality" unrecommended/></span>
|
<span class="text-neutral-200">{language.personality} <Help key="personality" unrecommended/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.personality}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.personality}></TextAreaInput>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $DataBase.showUnrecommended || currentChar.data.scenario.length > 3}
|
{#if $DataBase.showUnrecommended || currentChar.data.scenario.length > 3}
|
||||||
<span class="text-neutral-200">{language.scenario} <Help key="scenario" unrecommended/></span>
|
<span class="text-neutral-200">{language.scenario} <Help key="scenario" unrecommended/></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.scenario}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.scenario}></TextAreaInput>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<span class="text-neutral-200 mt-2">{language.backgroundHTML} <Help key="backgroundHTML" /></span>
|
<span class="text-neutral-200 mt-2">{language.backgroundHTML} <Help key="backgroundHTML" /></span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.backgroundHTML}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.backgroundHTML}></TextAreaInput>
|
||||||
|
|
||||||
<span class="text-neutral-200">{language.creator}</span>
|
<span class="text-neutral-200">{language.creator}</span>
|
||||||
<TextInput size="sm" autocomplete="off" bind:value={currentChar.data.additionalData.creator} />
|
<TextInput size="sm" autocomplete="off" bind:value={currentChar.data.additionalData.creator} />
|
||||||
@@ -580,102 +594,39 @@
|
|||||||
<TextInput size="sm" bind:value={currentChar.data.additionalData.character_version}/>
|
<TextInput size="sm" bind:value={currentChar.data.additionalData.character_version}/>
|
||||||
|
|
||||||
<span class="text-neutral-200 mt-2">{language.altGreet}</span>
|
<span class="text-neutral-200 mt-2">{language.altGreet}</span>
|
||||||
<table class="contain w-full max-w-full tabler mt-2">
|
<div class="w-full max-w-full border border-selected rounded-md p-2">
|
||||||
<tr>
|
<table class="contain w-full max-w-full tabler mt-2">
|
||||||
<th class="font-medium">{language.value}</th>
|
|
||||||
<th class="font-medium cursor-pointer w-10">
|
|
||||||
<button class="hover:text-green-500" on:click={() => {
|
|
||||||
if(currentChar.type === 'character'){
|
|
||||||
let alternateGreetings = currentChar.data.alternateGreetings
|
|
||||||
alternateGreetings.push('')
|
|
||||||
currentChar.data.alternateGreetings = alternateGreetings
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
<PlusIcon />
|
|
||||||
</button>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
{#if currentChar.data.alternateGreetings.length === 0}
|
|
||||||
<tr>
|
<tr>
|
||||||
<div class="text-gray-500"> No Messages</div>
|
<th class="font-medium">{language.value}</th>
|
||||||
</tr>
|
|
||||||
{/if}
|
|
||||||
{#each currentChar.data.alternateGreetings as bias, i}
|
|
||||||
<tr>
|
|
||||||
<td class="font-medium truncate">
|
|
||||||
<textarea class="text-neutral-200 mt-2 mb-4 p-2 bg-transparent input-text focus:bg-selected w-full resize-none" bind:value={currentChar.data.alternateGreetings[i]} placeholder="..." />
|
|
||||||
</td>
|
|
||||||
<th class="font-medium cursor-pointer w-10">
|
<th class="font-medium cursor-pointer w-10">
|
||||||
<button class="hover:text-green-500" on:click={() => {
|
<button class="hover:text-green-500" on:click={() => {
|
||||||
if(currentChar.type === 'character'){
|
if(currentChar.type === 'character'){
|
||||||
currentChar.data.firstMsgIndex = -1
|
|
||||||
let alternateGreetings = currentChar.data.alternateGreetings
|
let alternateGreetings = currentChar.data.alternateGreetings
|
||||||
alternateGreetings.splice(i, 1)
|
alternateGreetings.push('')
|
||||||
currentChar.data.alternateGreetings = alternateGreetings
|
currentChar.data.alternateGreetings = alternateGreetings
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
<TrashIcon />
|
<PlusIcon />
|
||||||
</button>
|
</button>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{#if currentChar.data.alternateGreetings.length === 0}
|
||||||
</table>
|
<tr>
|
||||||
|
<div class="text-gray-500"> No Messages</div>
|
||||||
<span class="text-neutral-200 mt-2">{language.additionalAssets} <Help key="additionalAssets" /></span>
|
</tr>
|
||||||
<table class="contain w-full max-w-full tabler mt-2">
|
{/if}
|
||||||
<tr>
|
{#each currentChar.data.alternateGreetings as bias, i}
|
||||||
<th class="font-medium">{language.value}</th>
|
|
||||||
<th class="font-medium cursor-pointer w-10">
|
|
||||||
<button class="hover:text-green-500" on:click={async () => {
|
|
||||||
if(currentChar.type === 'character'){
|
|
||||||
const da = await selectMultipleFile(['png', 'webp', 'mp4', 'mp3', 'gif'])
|
|
||||||
currentChar.data.additionalAssets = currentChar.data.additionalAssets ?? []
|
|
||||||
if(!da){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for(const f of da){
|
|
||||||
console.log(f)
|
|
||||||
const img = f.data
|
|
||||||
const name = f.name
|
|
||||||
const extension = name.split('.').pop().toLowerCase()
|
|
||||||
const imgp = await saveAsset(img,'', extension)
|
|
||||||
currentChar.data.additionalAssets.push([name, imgp, extension])
|
|
||||||
currentChar.data.additionalAssets = currentChar.data.additionalAssets
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
<PlusIcon />
|
|
||||||
</button>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
{#if (!currentChar.data.additionalAssets) || currentChar.data.additionalAssets.length === 0}
|
|
||||||
<tr>
|
|
||||||
<div class="text-gray-500"> No Assets</div>
|
|
||||||
</tr>
|
|
||||||
{:else}
|
|
||||||
{#each currentChar.data.additionalAssets as assets, i}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="font-medium truncate">
|
<td class="font-medium truncate">
|
||||||
{#if assetFilePath[i] && database.useAdditionalAssetsPreview}
|
<TextAreaInput bind:value={currentChar.data.alternateGreetings[i]} placeholder="..." />
|
||||||
{#if assetFileExtensions[i] === 'mp4'}
|
|
||||||
<!-- svelte-ignore a11y-media-has-caption -->
|
|
||||||
<video controls class="mt-2 px-2 w-full m-1 rounded-md"><source src={assetFilePath[i]} type="video/mp4"></video>
|
|
||||||
{:else if assetFileExtensions[i] === 'mp3'}
|
|
||||||
<audio controls class="mt-2 px-2 w-full h-16 m-1 rounded-md" loop><source src={assetFilePath[i]} type="audio/mpeg"></audio>
|
|
||||||
{:else}
|
|
||||||
<img src={assetFilePath[i]} class="w-16 h-16 m-1 rounded-md" alt={assets[0]}/>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
||||||
<TextInput size="sm" marginBottom bind:value={currentChar.data.additionalAssets[i][0]} placeholder="..." />
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<th class="font-medium cursor-pointer w-10">
|
<th class="font-medium cursor-pointer w-10">
|
||||||
<button class="hover:text-green-500" on:click={() => {
|
<button class="hover:text-green-500" on:click={() => {
|
||||||
if(currentChar.type === 'character'){
|
if(currentChar.type === 'character'){
|
||||||
currentChar.data.firstMsgIndex = -1
|
currentChar.data.firstMsgIndex = -1
|
||||||
let additionalAssets = currentChar.data.additionalAssets
|
let alternateGreetings = currentChar.data.alternateGreetings
|
||||||
additionalAssets.splice(i, 1)
|
alternateGreetings.splice(i, 1)
|
||||||
currentChar.data.additionalAssets = additionalAssets
|
currentChar.data.alternateGreetings = alternateGreetings
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
<TrashIcon />
|
<TrashIcon />
|
||||||
@@ -683,8 +634,75 @@
|
|||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
</table>
|
||||||
</table>
|
</div>
|
||||||
|
|
||||||
|
<span class="text-neutral-200 mt-2">{language.additionalAssets} <Help key="additionalAssets" /></span>
|
||||||
|
<div class="w-full max-w-full border border-selected rounded-md p-2">
|
||||||
|
<table class="contain w-full max-w-full tabler mt-2">
|
||||||
|
<tr>
|
||||||
|
<th class="font-medium">{language.value}</th>
|
||||||
|
<th class="font-medium cursor-pointer w-10">
|
||||||
|
<button class="hover:text-green-500" on:click={async () => {
|
||||||
|
if(currentChar.type === 'character'){
|
||||||
|
const da = await selectMultipleFile(['png', 'webp', 'mp4', 'mp3', 'gif'])
|
||||||
|
currentChar.data.additionalAssets = currentChar.data.additionalAssets ?? []
|
||||||
|
if(!da){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for(const f of da){
|
||||||
|
console.log(f)
|
||||||
|
const img = f.data
|
||||||
|
const name = f.name
|
||||||
|
const extension = name.split('.').pop().toLowerCase()
|
||||||
|
const imgp = await saveAsset(img,'', extension)
|
||||||
|
currentChar.data.additionalAssets.push([name, imgp, extension])
|
||||||
|
currentChar.data.additionalAssets = currentChar.data.additionalAssets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<PlusIcon />
|
||||||
|
</button>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
{#if (!currentChar.data.additionalAssets) || currentChar.data.additionalAssets.length === 0}
|
||||||
|
<tr>
|
||||||
|
<div class="text-gray-500"> No Assets</div>
|
||||||
|
</tr>
|
||||||
|
{:else}
|
||||||
|
{#each currentChar.data.additionalAssets as assets, i}
|
||||||
|
<tr>
|
||||||
|
<td class="font-medium truncate">
|
||||||
|
{#if assetFilePath[i] && database.useAdditionalAssetsPreview}
|
||||||
|
{#if assetFileExtensions[i] === 'mp4'}
|
||||||
|
<!-- svelte-ignore a11y-media-has-caption -->
|
||||||
|
<video controls class="mt-2 px-2 w-full m-1 rounded-md"><source src={assetFilePath[i]} type="video/mp4"></video>
|
||||||
|
{:else if assetFileExtensions[i] === 'mp3'}
|
||||||
|
<audio controls class="mt-2 px-2 w-full h-16 m-1 rounded-md" loop><source src={assetFilePath[i]} type="audio/mpeg"></audio>
|
||||||
|
{:else}
|
||||||
|
<img src={assetFilePath[i]} class="w-16 h-16 m-1 rounded-md" alt={assets[0]}/>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
<TextInput size="sm" marginBottom bind:value={currentChar.data.additionalAssets[i][0]} placeholder="..." />
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<th class="font-medium cursor-pointer w-10">
|
||||||
|
<button class="hover:text-green-500" on:click={() => {
|
||||||
|
if(currentChar.type === 'character'){
|
||||||
|
currentChar.data.firstMsgIndex = -1
|
||||||
|
let additionalAssets = currentChar.data.additionalAssets
|
||||||
|
additionalAssets.splice(i, 1)
|
||||||
|
currentChar.data.additionalAssets = additionalAssets
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<TrashIcon />
|
||||||
|
</button>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
{#if $DataBase.showUnrecommended || currentChar.data.utilityBot}
|
{#if $DataBase.showUnrecommended || currentChar.data.utilityBot}
|
||||||
<div class="flex items-center mt-4">
|
<div class="flex items-center mt-4">
|
||||||
@@ -693,19 +711,19 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<button on:click={async () => {
|
<Button size="lg" onClick={async () => {
|
||||||
exportChar($selectedCharID)
|
exportChar($selectedCharID)
|
||||||
}} class="text-neutral-200 mt-6 text-lg bg-transparent border-solid border-1 border-borderc p-4 hover:bg-green-500 transition-colors cursor-pointer">{language.exportCharacter}</button>
|
}} className="mt-2">{language.exportCharacter}</Button>
|
||||||
<button on:click={async () => {
|
<Button size="lg" onClick={async () => {
|
||||||
openHubUpload = true
|
openHubUpload = true
|
||||||
}} class="text-neutral-200 mt-2 text-lg bg-transparent border-solid border-1 border-borderc p-4 hover:bg-green-500 transition-colors cursor-pointer">{language.shareCloud}</button>
|
}} className="mt-2">{language.shareCloud}</Button>
|
||||||
{#if openHubUpload}
|
{#if openHubUpload}
|
||||||
<HubUpload bind:char={currentChar.data} close={() => {openHubUpload=false}}/>
|
<HubUpload bind:char={currentChar.data} close={() => {openHubUpload=false}}/>
|
||||||
{/if}
|
{/if}
|
||||||
{:else}
|
{:else}
|
||||||
{#if currentChar.data.chats[currentChar.data.chatPage].supaMemoryData && currentChar.data.chats[currentChar.data.chatPage].supaMemoryData.length > 4}
|
{#if currentChar.data.chats[currentChar.data.chatPage].supaMemoryData && currentChar.data.chats[currentChar.data.chatPage].supaMemoryData.length > 4}
|
||||||
<span class="text-neutral-200">{language.SuperMemory}</span>
|
<span class="text-neutral-200">{language.SuperMemory}</span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 text-xs resize-none h-20 focus:bg-selected" autocomplete="off" bind:value={currentChar.data.chats[currentChar.data.chatPage].supaMemoryData}></textarea>
|
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.chats[currentChar.data.chatPage].supaMemoryData}></TextAreaInput>
|
||||||
{/if}
|
{/if}
|
||||||
{#if $DataBase.useExperimental}
|
{#if $DataBase.useExperimental}
|
||||||
<div class="flex mb-2 items-center">
|
<div class="flex mb-2 items-center">
|
||||||
@@ -714,7 +732,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
<button on:click={async () => {
|
<Button onClick={async () => {
|
||||||
const conf = await alertConfirm(language.removeConfirm + currentChar.data.name)
|
const conf = await alertConfirm(language.removeConfirm + currentChar.data.name)
|
||||||
if(!conf){
|
if(!conf){
|
||||||
return
|
return
|
||||||
@@ -729,14 +747,11 @@
|
|||||||
$selectedCharID = -1
|
$selectedCharID = -1
|
||||||
$DataBase.characters = chars
|
$DataBase.characters = chars
|
||||||
|
|
||||||
}} class="text-neutral-200 mt-2 bg-transparent border-solid border-1 border-borderc p-2 hover:bg-draculared transition-colors cursor-pointer">{ currentChar.type === 'group' ? language.removeGroup : language.removeCharacter}</button>
|
}} className="mt-2" size="sm">{ currentChar.type === 'group' ? language.removeGroup : language.removeCharacter}</Button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.contain{
|
|
||||||
border: #6272a4 1px solid
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabler {
|
.tabler {
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
export let list = []
|
export let list = []
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="list flex flex-col bg-bgcolor rounded-md">
|
<div class="list flex flex-col rounded-md border border-selected">
|
||||||
{#each list as n, i}
|
{#each list as n, i}
|
||||||
<div class="w-full h-10 flex items-center">
|
<div class="w-full h-10 flex items-center">
|
||||||
<span class="ml-2 flex-grow">{language.formating[n]}</span>
|
<span class="ml-2 flex-grow">{language.formating[n]}</span>
|
||||||
@@ -43,16 +43,7 @@
|
|||||||
}}><ChevronDown /></button>
|
}}><ChevronDown /></button>
|
||||||
</div>
|
</div>
|
||||||
{#if i !== (list.length - 1)}
|
{#if i !== (list.length - 1)}
|
||||||
<div class="seperator"></div>
|
<div class="border-t w-full border-selected"></div>
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
|
||||||
.seperator{
|
|
||||||
width: 100%;
|
|
||||||
border: none;
|
|
||||||
outline: 0;
|
|
||||||
border-bottom: 1px solid #6272a4;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
import { language } from "../../lang";
|
import { language } from "../../lang";
|
||||||
import type { loreBook } from "../../ts/storage/database";
|
import type { loreBook } from "../../ts/storage/database";
|
||||||
import { alertConfirm } from "../../ts/alert";
|
import { alertConfirm } from "../../ts/alert";
|
||||||
import Check from "../Others/Check.svelte";
|
import Check from "../UI/GUI/Check.svelte";
|
||||||
import Help from "../Others/Help.svelte";
|
import Help from "../Others/Help.svelte";
|
||||||
import TextInput from "../UI/GUI/TextInput.svelte";
|
import TextInput from "../UI/GUI/TextInput.svelte";
|
||||||
import NumberInput from "../UI/GUI/NumberInput.svelte";
|
import NumberInput from "../UI/GUI/NumberInput.svelte";
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{#if open}
|
{#if open}
|
||||||
<div class="seperator">
|
<div class="border-0 outline-none w-full mt-2 flex flex-col mb-2">
|
||||||
<span class="text-neutral-200 mt-6">{language.name} <Help key="loreName"/></span>
|
<span class="text-neutral-200 mt-6">{language.name} <Help key="loreName"/></span>
|
||||||
<TextInput size="sm" bind:value={value.comment}/>
|
<TextInput size="sm" bind:value={value.comment}/>
|
||||||
{#if !value.alwaysActive}
|
{#if !value.alwaysActive}
|
||||||
@@ -57,8 +57,8 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<span class="text-neutral-200 mt-4">{language.insertOrder} <Help key="loreorder"/></span>
|
<span class="text-neutral-200 mt-4">{language.insertOrder} <Help key="loreorder"/></span>
|
||||||
<NumberInput size="sm" bind:value={value.insertorder} min={0} max={1000}/>
|
<NumberInput size="sm" bind:value={value.insertorder} min={0} max={1000}/>
|
||||||
<span class="text-neutral-200 mt-4">{language.prompt}</span>
|
<span class="text-neutral-200 mt-4 mb-2">{language.prompt}</span>
|
||||||
<textarea class="bg-transparent input-text mt-2 text-gray-200 resize-none h-20 focus:bg-selected text-xs" autocomplete="off" bind:value={value.content}></textarea>
|
<TextInput autocomplete="off" bind:value={value.content} />
|
||||||
<div class="flex items-center mt-4">
|
<div class="flex items-center mt-4">
|
||||||
<Check bind:check={value.alwaysActive} name={language.alwaysActive}/>
|
<Check bind:check={value.alwaysActive} name={language.alwaysActive}/>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,16 +91,5 @@
|
|||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.seperator{
|
|
||||||
border: none;
|
|
||||||
outline: 0;
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
background-color: #282a36;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -5,27 +5,27 @@
|
|||||||
import { DownloadIcon, FolderUpIcon, ImportIcon, PlusIcon } from "lucide-svelte";
|
import { DownloadIcon, FolderUpIcon, ImportIcon, PlusIcon } from "lucide-svelte";
|
||||||
import { addLorebook, exportLoreBook, importLoreBook } from "../../ts/process/lorebook";
|
import { addLorebook, exportLoreBook, importLoreBook } from "../../ts/process/lorebook";
|
||||||
import LoreBookData from "./LoreBookData.svelte";
|
import LoreBookData from "./LoreBookData.svelte";
|
||||||
import Check from "../Others/Check.svelte";
|
import Check from "../UI/GUI/Check.svelte";
|
||||||
import NumberInput from "../UI/GUI/NumberInput.svelte";
|
import NumberInput from "../UI/GUI/NumberInput.svelte";
|
||||||
let submenu = 0
|
let submenu = 0
|
||||||
export let globalMode = false
|
export let globalMode = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if !globalMode}
|
{#if !globalMode}
|
||||||
<div class="flex w-full">
|
<div class="flex w-full rounded-md border border-selected">
|
||||||
<button on:click={() => {
|
<button on:click={() => {
|
||||||
submenu = 0
|
submenu = 0
|
||||||
}} class="flex-1 border-solid border-borderc border-1 p-2 flex justify-center cursor-pointer" class:bg-selected={submenu === 0}>
|
}} class="p-2 flex-1" class:bg-selected={submenu === 0}>
|
||||||
<span>{$DataBase.characters[$selectedCharID].type === 'group' ? language.group : language.character}</span>
|
<span>{$DataBase.characters[$selectedCharID].type === 'group' ? language.group : language.character}</span>
|
||||||
</button>
|
</button>
|
||||||
<button on:click={() => {
|
<button on:click={() => {
|
||||||
submenu = 1
|
submenu = 1
|
||||||
}} class="flex-1 border-solid border-borderc border-1 border-l-transparent p-2 flex justify-center cursor-pointer" class:bg-selected={submenu === 1}>
|
}} class="p2 flex-1 border-r border-l border-selected" class:bg-selected={submenu === 1}>
|
||||||
<span>{language.Chat}</span>
|
<span>{language.Chat}</span>
|
||||||
</button>
|
</button>
|
||||||
<button on:click={() => {
|
<button on:click={() => {
|
||||||
submenu = 2
|
submenu = 2
|
||||||
}} class="flex-1 border-solid border-borderc border-1 border-l-transparent p-2 flex justify-center cursor-pointer" class:bg-selected={submenu === 2}>
|
}} class="p-2 flex-1" class:bg-selected={submenu === 2}>
|
||||||
<span>{language.settings}</span>
|
<span>{language.settings}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -34,14 +34,14 @@
|
|||||||
{#if !globalMode}
|
{#if !globalMode}
|
||||||
<span class="text-gray-500 mt-2 mb-6 text-sm">{submenu === 0 ? $DataBase.characters[$selectedCharID].type === 'group' ? language.groupLoreInfo : language.globalLoreInfo : language.localLoreInfo}</span>
|
<span class="text-gray-500 mt-2 mb-6 text-sm">{submenu === 0 ? $DataBase.characters[$selectedCharID].type === 'group' ? language.groupLoreInfo : language.globalLoreInfo : language.localLoreInfo}</span>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="border-solid border-borderc p-2 flex flex-col border-1">
|
<div class="border-solid border-selected p-2 flex flex-col border-1 rounded-md">
|
||||||
{#if globalMode}
|
{#if globalMode}
|
||||||
{#if $DataBase.loreBook[$DataBase.loreBookPage].data.length === 0}
|
{#if $DataBase.loreBook[$DataBase.loreBookPage].data.length === 0}
|
||||||
<span class="text-gray-500">No Lorebook</span>
|
<span class="text-gray-500">No Lorebook</span>
|
||||||
{:else}
|
{:else}
|
||||||
{#each $DataBase.loreBook[$DataBase.loreBookPage].data as book, i}
|
{#each $DataBase.loreBook[$DataBase.loreBookPage].data as book, i}
|
||||||
{#if i !== 0}
|
{#if i !== 0}
|
||||||
<div class="border-borderc mt-2 mb-2 w-full border-solid border-b-1 seperator"></div>
|
<div class="border-selected mt-2 mb-2 w-full border-solid border-b-1 seperator"></div>
|
||||||
{/if}
|
{/if}
|
||||||
<LoreBookData bind:value={$DataBase.loreBook[$DataBase.loreBookPage].data[i]} onRemove={() => {
|
<LoreBookData bind:value={$DataBase.loreBook[$DataBase.loreBookPage].data[i]} onRemove={() => {
|
||||||
let lore = $DataBase.loreBook[$DataBase.loreBookPage].data
|
let lore = $DataBase.loreBook[$DataBase.loreBookPage].data
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
{:else}
|
{:else}
|
||||||
{#each $DataBase.characters[$selectedCharID].globalLore as book, i}
|
{#each $DataBase.characters[$selectedCharID].globalLore as book, i}
|
||||||
{#if i !== 0}
|
{#if i !== 0}
|
||||||
<div class="border-borderc mt-2 mb-2 w-full border-solid border-b-1 seperator"></div>
|
<div class="border-selected mt-2 mb-2 w-full border-solid border-b-1 seperator"></div>
|
||||||
{/if}
|
{/if}
|
||||||
<LoreBookData bind:value={$DataBase.characters[$selectedCharID].globalLore[i]} onRemove={() => {
|
<LoreBookData bind:value={$DataBase.characters[$selectedCharID].globalLore[i]} onRemove={() => {
|
||||||
let lore = $DataBase.characters[$selectedCharID].globalLore
|
let lore = $DataBase.characters[$selectedCharID].globalLore
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
{:else}
|
{:else}
|
||||||
{#each $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].localLore as book, i}
|
{#each $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].localLore as book, i}
|
||||||
{#if i !== 0}
|
{#if i !== 0}
|
||||||
<div class="border-borderc mt-2 mb-2 w-full border-solid border-b-1 seperator"></div>
|
<div class="border-selected mt-2 mb-2 w-full border-solid border-b-1 seperator"></div>
|
||||||
{/if}
|
{/if}
|
||||||
<LoreBookData bind:value={$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].localLore[i]} onRemove={() => {
|
<LoreBookData bind:value={$DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].localLore[i]} onRemove={() => {
|
||||||
let lore = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].localLore
|
let lore = $DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].localLore
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
import { language } from "src/lang";
|
import { language } from "src/lang";
|
||||||
import { alertConfirm } from "src/ts/alert";
|
import { alertConfirm } from "src/ts/alert";
|
||||||
import type { customscript } from "src/ts/storage/database";
|
import type { customscript } from "src/ts/storage/database";
|
||||||
import Check from "../Others/Check.svelte";
|
import Check from "../UI/GUI/Check.svelte";
|
||||||
import TextInput from "../UI/GUI/TextInput.svelte";
|
import TextInput from "../UI/GUI/TextInput.svelte";
|
||||||
|
import SelectInput from "../UI/GUI/SelectInput.svelte";
|
||||||
|
import OptionInput from "../UI/GUI/OptionInput.svelte";
|
||||||
|
|
||||||
export let value:customscript
|
export let value:customscript
|
||||||
export let onRemove: () => void = () => {}
|
export let onRemove: () => void = () => {}
|
||||||
@@ -32,12 +34,12 @@
|
|||||||
<span class="text-neutral-200 mt-6">{language.name}</span>
|
<span class="text-neutral-200 mt-6">{language.name}</span>
|
||||||
<TextInput size="sm" bind:value={value.comment} />
|
<TextInput size="sm" bind:value={value.comment} />
|
||||||
<span class="text-neutral-200 mt-4">Modification Type</span>
|
<span class="text-neutral-200 mt-4">Modification Type</span>
|
||||||
<select class="text-neutral-200 p-2 bg-transparent input-text focus:bg-selected text-sm" bind:value={value.type}>
|
<SelectInput bind:value={value.type}>
|
||||||
<option value="editinput">{language.editInput}</option>
|
<OptionInput value="editinput">{language.editInput}</OptionInput>
|
||||||
<option value="editoutput">{language.editOutput}</option>
|
<OptionInput value="editoutput">{language.editOutput}</OptionInput>
|
||||||
<option value="editprocess">{language.editProcess}</option>
|
<OptionInput value="editprocess">{language.editProcess}</OptionInput>
|
||||||
<option value="editdisplay">{language.editDisplay}</option>
|
<OptionInput value="editdisplay">{language.editDisplay}</OptionInput>
|
||||||
</select>
|
</SelectInput>
|
||||||
<span class="text-neutral-200 mt-6">IN:</span>
|
<span class="text-neutral-200 mt-6">IN:</span>
|
||||||
<TextInput size="sm" bind:value={value.in} />
|
<TextInput size="sm" bind:value={value.in} />
|
||||||
<span class="text-neutral-200 mt-6">OUT:</span>
|
<span class="text-neutral-200 mt-6">OUT:</span>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
import { checkCharOrder } from "src/ts/storage/globalApi";
|
import { checkCharOrder } from "src/ts/storage/globalApi";
|
||||||
import { doingChat } from "src/ts/process";
|
import { doingChat } from "src/ts/process";
|
||||||
import { BotCreator } from "src/ts/creator/creator";
|
import { BotCreator } from "src/ts/creator/creator";
|
||||||
|
import Button from "../UI/GUI/Button.svelte";
|
||||||
let openPresetList = false;
|
let openPresetList = false;
|
||||||
let sideBarMode = 0;
|
let sideBarMode = 0;
|
||||||
let editMode = false;
|
let editMode = false;
|
||||||
@@ -552,30 +553,30 @@
|
|||||||
<CharConfig />
|
<CharConfig />
|
||||||
{/if}
|
{/if}
|
||||||
{:else if sideBarMode === 1}
|
{:else if sideBarMode === 1}
|
||||||
<button
|
<Button
|
||||||
on:click={createScratch}
|
onClick={createScratch}
|
||||||
class="ml-2 mr-2 mt-2 flex items-center justify-center border-1 border-solid border-borderc p-5 text-lg drop-shadow-lg hover:bg-selected"
|
className="mt-2"
|
||||||
>
|
>
|
||||||
{language.createfromScratch}
|
{language.createfromScratch}
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button
|
||||||
on:click={createImport}
|
onClick={createImport}
|
||||||
class="ml-2 mr-2 mt-2 flex items-center justify-center border-1 border-solid border-borderc p-5 text-lg drop-shadow-lg hover:bg-selected"
|
className="mt-2"
|
||||||
>
|
>
|
||||||
{language.importCharacter}
|
{language.importCharacter}
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button
|
||||||
on:click={createGroup}
|
onClick={createGroup}
|
||||||
class="ml-2 mr-2 mt-2 flex items-center justify-center border-1 border-solid border-borderc p-3 drop-shadow-lg hover:bg-selected"
|
className="mt-2"
|
||||||
>
|
>
|
||||||
{language.createGroup}
|
{language.createGroup}
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button
|
||||||
on:click={BotCreator.createBotFromWeb}
|
onClick={BotCreator.createBotFromWeb}
|
||||||
class="ml-2 mr-2 mt-2 flex items-center justify-center border-1 border-solid border-borderc p-3 drop-shadow-lg hover:bg-selected"
|
className="mt-2"
|
||||||
>
|
>
|
||||||
{language.createBotInternet}
|
{language.createBotInternet}
|
||||||
</button>
|
</Button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
20
src/lib/UI/GUI/Button.svelte
Normal file
20
src/lib/UI/GUI/Button.svelte
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<button
|
||||||
|
on:click={onClick}
|
||||||
|
class="{selected ? 'bg-borderc' : 'bg-gray-700'} border border-gray-600 text-white rounded-md shadow-sm hover:bg-borderc focus:outline-none focus:ring-2 focus:ring-borderc transition-colors duration-200{className ? (" " + className) : ""}"
|
||||||
|
class:px-4 = {size == "md"}
|
||||||
|
class:px-2 = {size == "sm"}
|
||||||
|
class:px-6 = {size == "lg"}
|
||||||
|
class:py-2 = {size == "md"}
|
||||||
|
class:py-1 = {size == "sm"}
|
||||||
|
class:py-3 = {size == "lg"}
|
||||||
|
class:text-md = {size == "md"}
|
||||||
|
class:text-sm = {size == "sm"}
|
||||||
|
class:text-lg = {size == "lg"}>
|
||||||
|
<slot></slot>
|
||||||
|
</button>
|
||||||
|
<script lang="ts">
|
||||||
|
export let selected = false
|
||||||
|
export let onClick = () => {}
|
||||||
|
export let className = ""
|
||||||
|
export let size: "sm" | "md" | "lg" = "md"
|
||||||
|
</script>
|
||||||
52
src/lib/UI/GUI/Check.svelte
Normal file
52
src/lib/UI/GUI/Check.svelte
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { CheckIcon } from "lucide-svelte";
|
||||||
|
|
||||||
|
export let check = false
|
||||||
|
export let onChange = (check) => {}
|
||||||
|
export let margin = true
|
||||||
|
export let name = ''
|
||||||
|
export let hiddenName = false
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- <label title={name} class:mr-2={margin} class="flex relative">
|
||||||
|
<input title={name} type="checkbox" class='absolute opacity-0 w-6 h-6' bind:checked={check} on:change={() => {
|
||||||
|
onChange(check)
|
||||||
|
}}/>
|
||||||
|
{#if check}
|
||||||
|
<div class="w-6 h-6 bg-green-500 flex justify-center items-center text-sm">
|
||||||
|
<CheckIcon />
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="w-6 h-6 bg-selected flex justify-center items-center text-sm"/>
|
||||||
|
{/if}
|
||||||
|
{#if name != '' && !hiddenName}
|
||||||
|
<span class="text-neutral-200 ml-2">{name}</span>
|
||||||
|
{/if}
|
||||||
|
</label> -->
|
||||||
|
|
||||||
|
<label
|
||||||
|
class="flex items-center space-x-2 cursor-pointer text-white"
|
||||||
|
class:mr-2={margin}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
class="hidden"
|
||||||
|
type="checkbox"
|
||||||
|
alt={name}
|
||||||
|
bind:checked={check}
|
||||||
|
on:change={() => {
|
||||||
|
onChange(check)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="w-5 h-5 rounded-md border-2 border-gray-600 flex justify-center items-center {check ? 'bg-borderc' : 'bg-gray-700'} transition-colors duration-200"
|
||||||
|
>
|
||||||
|
{#if check}
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="white" class="w-3 h-3">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
|
||||||
|
</svg>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
{#if !hiddenName}
|
||||||
|
<span>{name}</span>
|
||||||
|
{/if}
|
||||||
|
</label>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<input
|
<!-- <input
|
||||||
class="text-neutral-200 bg-transparent input-text focus:bg-selected"
|
class="text-neutral-200 bg-transparent input-text focus:bg-selected"
|
||||||
class:text-sm={size === 'sm'}
|
class:text-sm={size === 'sm'}
|
||||||
class:text-md={size === 'md'}
|
class:text-md={size === 'md'}
|
||||||
@@ -13,8 +13,25 @@
|
|||||||
max={max}
|
max={max}
|
||||||
id={id}
|
id={id}
|
||||||
bind:value
|
bind:value
|
||||||
>
|
> -->
|
||||||
|
|
||||||
|
<input
|
||||||
|
class={"border border-gray-600 focus:border-borderc rounded-md shadow-sm text-white bg-transparent numinput focus:ring-borderc focus:ring-2 focus:outline-none transition-colors duration-200" + ((additionalClass) ? (' ' + additionalClass) : '')}
|
||||||
|
class:text-sm={size === 'sm'}
|
||||||
|
class:text-md={size === 'md'}
|
||||||
|
class:text-lg={size === 'lg'}
|
||||||
|
class:px-4={padding}
|
||||||
|
class:py-2={padding}
|
||||||
|
class:mb-4={marginBottom}
|
||||||
|
class:w-full={fullwidth}
|
||||||
|
class:h-full={fullh}
|
||||||
|
type="number"
|
||||||
|
min={min}
|
||||||
|
max={max}
|
||||||
|
id={id}
|
||||||
|
bind:value
|
||||||
|
on:change={onChange}
|
||||||
|
/>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let min:number = undefined
|
export let min:number = undefined
|
||||||
@@ -27,5 +44,19 @@
|
|||||||
export let fullwidth = false
|
export let fullwidth = false
|
||||||
export let fullh = false
|
export let fullh = false
|
||||||
export let onChange = () => {}
|
export let onChange = () => {}
|
||||||
|
export let additionalClass = ''
|
||||||
|
</script>
|
||||||
|
|
||||||
</script>
|
<style>
|
||||||
|
.numinput::-webkit-outer-spin-button,
|
||||||
|
.numinput::-webkit-inner-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Firefox */
|
||||||
|
.numinput {
|
||||||
|
-moz-appearance: textfield;
|
||||||
|
appearance: textfield;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
5
src/lib/UI/GUI/OptionInput.svelte
Normal file
5
src/lib/UI/GUI/OptionInput.svelte
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<option value={value} selected={selected} class="bg-darkbg appearance-none"><slot></slot></option>
|
||||||
|
<script lang="ts">
|
||||||
|
export let value:string
|
||||||
|
export let selected:boolean = false
|
||||||
|
</script>
|
||||||
22
src/lib/UI/GUI/SelectInput.svelte
Normal file
22
src/lib/UI/GUI/SelectInput.svelte
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<select
|
||||||
|
class={"border border-gray-600 focus:border-borderc rounded-md shadow-sm text-white bg-transparent focus:ring-borderc focus:ring-2 focus:outline-none transition-colors duration-200" + ((className) ? (' ' + className) : '')}
|
||||||
|
class:text-sm={size === 'sm'}
|
||||||
|
class:text-md={size === 'md'}
|
||||||
|
class:text-lg={size === 'lg'}
|
||||||
|
class:text-xl={size === 'xl'}
|
||||||
|
class:px-4={size === 'md'}
|
||||||
|
class:py-2={size === 'md'}
|
||||||
|
class:px-2={size === 'sm'}
|
||||||
|
class:py-1={size === 'sm'}
|
||||||
|
class:px-6={size === 'lg'}
|
||||||
|
class:py-3={size === 'lg'}
|
||||||
|
bind:value
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
</select>
|
||||||
|
<script lang="ts">
|
||||||
|
export let value:string
|
||||||
|
export let className:string = ""
|
||||||
|
export let size:'sm'|'md'|'lg'|'xl' = 'md'
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -1,27 +1,44 @@
|
|||||||
<input
|
<input
|
||||||
class="text-neutral-200 bg-transparent input-text focus:bg-selected"
|
class="text-neutral-200 bg-transparent input-text"
|
||||||
class:text-sm={size === 'sm'}
|
|
||||||
class:text-md={size === 'md'}
|
|
||||||
class:text-lg={size === 'lg'}
|
|
||||||
class:p-2={padding}
|
|
||||||
class:mb-4={marginBottom}
|
class:mb-4={marginBottom}
|
||||||
type="range"
|
type="range"
|
||||||
min={min}
|
min={min}
|
||||||
max={max}
|
max={max}
|
||||||
id={id}
|
|
||||||
step={step}
|
step={step}
|
||||||
bind:value
|
bind:value
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<!-- <div class="p-6 max-w-sm mx-auto bg-gray-800 rounded-xl shadow-md flex items-center space-x-4 w-full" class:mb-4={marginBottom}>
|
||||||
|
<div
|
||||||
|
class="relative w-full h-2 bg-gray-700 rounded-full cursor-pointer"
|
||||||
|
on:click={changeValue}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="absolute top-0 left-0 h-2 rounded-full bg-indigo-500 transition-width duration-200"
|
||||||
|
style="width: {(value - min) / (max - min) * 100}%;"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="absolute top-1/2 transform -translate-y-1/2 -translate-x-1/2 w-4 h-4 bg-white rounded-full shadow"
|
||||||
|
style="left: {(value - min) / (max - min) * 100}%;"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let min:number = undefined
|
export let min:number = undefined
|
||||||
export let max:number = undefined
|
export let max:number = undefined
|
||||||
export let size: 'sm'|'md'|'lg' = 'sm'
|
|
||||||
export let value:number
|
export let value:number
|
||||||
export let id:string = undefined
|
|
||||||
export let padding = true
|
|
||||||
export let marginBottom = false
|
export let marginBottom = false
|
||||||
export let step = 1
|
export let step = 1
|
||||||
|
|
||||||
|
function changeValue(event) {
|
||||||
|
const rect = event.target.getBoundingClientRect();
|
||||||
|
const x = event.clientX - rect.left;
|
||||||
|
let newValue = ((x / rect.width) * (max - min)) + min;
|
||||||
|
newValue = Math.round(newValue / step) * step;
|
||||||
|
value = Math.min(Math.max(newValue, min), max);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
64
src/lib/UI/GUI/TextAreaInput.svelte
Normal file
64
src/lib/UI/GUI/TextAreaInput.svelte
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<!-- <textarea
|
||||||
|
class={"bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none focus:bg-selected w-full" + ((additionalClass) ? (' ' + additionalClass) : '')}
|
||||||
|
class:text-sm={size === 'sm'}
|
||||||
|
class:text-md={size === 'md'}
|
||||||
|
class:text-lg={size === 'lg'}
|
||||||
|
class:text-xl={size === 'xl'}
|
||||||
|
class:text-xs={size === 'xs'}
|
||||||
|
class:p-2={padding}
|
||||||
|
class:mb-4={margin === 'bottom'}
|
||||||
|
class:mb-2={margin === 'both'}
|
||||||
|
class:mt-4={margin === 'top'}
|
||||||
|
class:mt-2={margin === 'both'}
|
||||||
|
class:w-full={fullwidth}
|
||||||
|
class:h-20={height === '20'}
|
||||||
|
class:h-32={height === '32'}
|
||||||
|
class:h-full={height === 'full'}
|
||||||
|
class:min-h-20={height === '20'}
|
||||||
|
class:min-h-32={height === '32'}
|
||||||
|
|
||||||
|
{autocomplete}
|
||||||
|
{placeholder}
|
||||||
|
id={id}
|
||||||
|
bind:value
|
||||||
|
on:input={onInput}
|
||||||
|
/> -->
|
||||||
|
|
||||||
|
<textarea
|
||||||
|
class={"border border-gray-600 focus:border-borderc resize-none rounded-md shadow-sm text-white bg-transparent focus:ring-borderc focus:ring-2 focus:outline-none transition-colors duration-200" + ((additionalClass) ? (' ' + additionalClass) : '')}
|
||||||
|
class:text-sm={size === 'sm'}
|
||||||
|
class:text-md={size === 'md'}
|
||||||
|
class:text-lg={size === 'lg'}
|
||||||
|
class:text-xl={size === 'xl'}
|
||||||
|
class:text-xs={size === 'xs'}
|
||||||
|
class:px-4={padding}
|
||||||
|
class:py-2={padding}
|
||||||
|
class:mb-4={margin === 'bottom'}
|
||||||
|
class:mb-2={margin === 'both'}
|
||||||
|
class:mt-4={margin === 'top'}
|
||||||
|
class:mt-2={margin === 'both'}
|
||||||
|
class:w-full={fullwidth}
|
||||||
|
class:h-20={height === '20'}
|
||||||
|
class:h-32={height === '32'}
|
||||||
|
class:h-full={height === 'full'}
|
||||||
|
class:min-h-20={height === '20'}
|
||||||
|
class:min-h-32={height === '32'}
|
||||||
|
{autocomplete}
|
||||||
|
{placeholder}
|
||||||
|
id={id}
|
||||||
|
bind:value
|
||||||
|
on:input={onInput}
|
||||||
|
/>
|
||||||
|
<script lang="ts">
|
||||||
|
export let size: 'xs'|'sm'|'md'|'lg'|'xl' = 'xs'
|
||||||
|
export let autocomplete: 'on'|'off' = 'off'
|
||||||
|
export let placeholder: string = ''
|
||||||
|
export let value:string
|
||||||
|
export let id:string = undefined
|
||||||
|
export let padding = true
|
||||||
|
export let margin:"none"|"top"|"bottom"|"both" = "none"
|
||||||
|
export let onInput = () => {}
|
||||||
|
export let fullwidth = false
|
||||||
|
export let height:'20'|'32'|'full' = '20'
|
||||||
|
export let additionalClass = ''
|
||||||
|
</script>
|
||||||
45
src/lib/UI/GUI/TextAreaResizable.svelte
Normal file
45
src/lib/UI/GUI/TextAreaResizable.svelte
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import { DataBase } from "../../../ts/storage/database";
|
||||||
|
|
||||||
|
let textarea;
|
||||||
|
let previousScrollHeight = 0;
|
||||||
|
export let value = ''
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
textarea.style.height = '0px'; // Reset the textarea height
|
||||||
|
textarea.style.height = `calc(${textarea.scrollHeight}px + 1rem)`; // Set the new height
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleInput() {
|
||||||
|
if (textarea.scrollHeight !== previousScrollHeight) {
|
||||||
|
previousScrollHeight = textarea.scrollHeight;
|
||||||
|
resize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
resize();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
textarea {
|
||||||
|
overflow: hidden;
|
||||||
|
resize: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: transparent;
|
||||||
|
color: white;
|
||||||
|
border: 1px solid rgba(98, 114, 164, 0.5);
|
||||||
|
max-width: calc(95% - 2rem);
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<textarea
|
||||||
|
bind:this={textarea}
|
||||||
|
on:input={handleInput}
|
||||||
|
bind:value={value}
|
||||||
|
style:font-size="{0.875 * ($DataBase.zoomsize / 100)}rem"
|
||||||
|
style:line-height="{1.25 * ($DataBase.zoomsize / 100)}rem"
|
||||||
|
/>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<input
|
<!-- <input
|
||||||
class={"text-neutral-200 bg-transparent input-text focus:bg-selected" + ((additionalClass) ? (' ' + additionalClass) : '')}
|
class={"text-neutral-200 bg-transparent input-text focus:bg-selected" + ((additionalClass) ? (' ' + additionalClass) : '')}
|
||||||
class:text-sm={size === 'sm'}
|
class:text-sm={size === 'sm'}
|
||||||
class:text-md={size === 'md'}
|
class:text-md={size === 'md'}
|
||||||
@@ -15,7 +15,27 @@
|
|||||||
type="text"
|
type="text"
|
||||||
bind:value
|
bind:value
|
||||||
on:input={onInput}
|
on:input={onInput}
|
||||||
>
|
> -->
|
||||||
|
|
||||||
|
|
||||||
|
<input
|
||||||
|
class={"border border-gray-600 focus:border-borderc rounded-md shadow-sm text-white bg-transparent focus:ring-borderc focus:ring-2 focus:outline-none transition-colors duration-200" + ((additionalClass) ? (' ' + additionalClass) : '')}
|
||||||
|
class:text-sm={size === 'sm'}
|
||||||
|
class:text-md={size === 'md'}
|
||||||
|
class:text-lg={size === 'lg'}
|
||||||
|
class:text-xl={size === 'xl'}
|
||||||
|
class:px-4={padding}
|
||||||
|
class:py-2={padding}
|
||||||
|
class:mb-4={marginBottom}
|
||||||
|
class:w-full={fullwidth}
|
||||||
|
class:h-full={fullh}
|
||||||
|
{autocomplete}
|
||||||
|
{placeholder}
|
||||||
|
id={id}
|
||||||
|
type="text"
|
||||||
|
bind:value
|
||||||
|
on:input={onInput}
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
<span class="text-neutral-200">{language.creatorNotes}</span>
|
<span class="text-neutral-200">{language.creatorNotes}</span>
|
||||||
<span class="text-gray-400 text-sm">A description that displays when you search and when you first open a bot.</span>
|
<span class="text-gray-400 text-sm">A description that displays when you search and when you first open a bot.</span>
|
||||||
<span class="text-gray-400 text-sm">More than 20 characters.</span>
|
<span class="text-gray-400 text-sm">More than 20 characters.</span>
|
||||||
<textarea class="bg-transparent input-text mt-2 mb-2 text-gray-200 resize-none h-20 min-h-20 focus:bg-selected text-xs w-full" autocomplete="off" bind:value={char.creatorNotes}></textarea>
|
<TextAreaInput autocomplete="off" bind:value={char.creatorNotes} height={"20"} />
|
||||||
<span class="text-neutral-200">{language.tags}</span>
|
<span class="text-neutral-200">{language.tags}</span>
|
||||||
<span class="text-gray-400 text-sm">Tags to search your character easily. latin alphabets only. seperate by comma.</span>
|
<span class="text-gray-400 text-sm">Tags to search your character easily. latin alphabets only. seperate by comma.</span>
|
||||||
<TextInput marginBottom placeholder="" bind:value={tags} on:input={() => {
|
<TextInput marginBottom placeholder="" bind:value={tags} on:input={() => {
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
{#if privateMode}
|
{#if privateMode}
|
||||||
<span class="text-gray-400 text-sm">Private characters can be removed from the server if there is only a few downloads.</span>
|
<span class="text-gray-400 text-sm">Private characters can be removed from the server if there is only a few downloads.</span>
|
||||||
{/if}
|
{/if}
|
||||||
<button on:click={async () => {
|
<Button onClick={async () => {
|
||||||
if(char.creatorNotes.length < 20){
|
if(char.creatorNotes.length < 20){
|
||||||
alertError("Creator Notes must be longer than 20 characters")
|
alertError("Creator Notes must be longer than 20 characters")
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
})
|
})
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
}} class="text-neutral-200 mt-2 text-lg bg-transparent border-solid border-1 border-borderc p-4 hover:bg-green-800 transition-colors cursor-pointer">{language.shareCloud}</button>
|
}} className="mt-2" size="lg">{language.shareCloud}</Button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -68,6 +68,8 @@
|
|||||||
import { shareRisuHub } from "src/ts/characterCards";
|
import { shareRisuHub } from "src/ts/characterCards";
|
||||||
import { DataBase, type character } from "src/ts/storage/database";
|
import { DataBase, type character } from "src/ts/storage/database";
|
||||||
import TextInput from "./GUI/TextInput.svelte";
|
import TextInput from "./GUI/TextInput.svelte";
|
||||||
|
import TextAreaInput from "./GUI/TextAreaInput.svelte";
|
||||||
|
import Button from "./GUI/Button.svelte";
|
||||||
export let close = () => {}
|
export let close = () => {}
|
||||||
export let char:character
|
export let char:character
|
||||||
let tags=""
|
let tags=""
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export default {
|
|||||||
'8': '2rem',
|
'8': '2rem',
|
||||||
'14': '3.5rem',
|
'14': '3.5rem',
|
||||||
'20': '5rem',
|
'20': '5rem',
|
||||||
|
'32': '9rem',
|
||||||
'4': "0.75rem"
|
'4': "0.75rem"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user