Risuai 0.6.3 first commit
This commit is contained in:
148
src/lib/Others/AlertComp.svelte
Normal file
148
src/lib/Others/AlertComp.svelte
Normal file
@@ -0,0 +1,148 @@
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { alertStore } from "../../ts/alert";
|
||||
import { DataBase } from '../../ts/database';
|
||||
import { getCharImage } from '../../ts/characters';
|
||||
import { ParseMarkdown } from '../../ts/parser';
|
||||
import BarIcon from '../SideBars/BarIcon.svelte';
|
||||
import { User } from 'lucide-svelte';
|
||||
let btn
|
||||
let input = ''
|
||||
|
||||
$: (() => {
|
||||
if(btn){
|
||||
btn.focus()
|
||||
}
|
||||
if($alertStore.type !== 'input'){
|
||||
input = ''
|
||||
}
|
||||
|
||||
})()
|
||||
</script>
|
||||
|
||||
{#if $alertStore.type !== 'none' && $alertStore.type !== 'toast'}
|
||||
<div class="absolute w-full h-full z-50 bg-black bg-opacity-50 flex justify-center items-center" class:vis={ $alertStore.type === 'wait2'}>
|
||||
<div class="bg-darkbg p-4 break-any rounded-md flex flex-col max-w-3xl max-h-11/12 overflow-y-auto">
|
||||
{#if $alertStore.type === 'error'}
|
||||
<h2 class="text-red-700 mt-0 mb-2 w-40 max-w-full">Error</h2>
|
||||
{:else if $alertStore.type === 'ask'}
|
||||
<h2 class="text-green-700 mt-0 mb-2 w-40 max-w-full">Confirm</h2>
|
||||
{:else if $alertStore.type === 'selectChar'}
|
||||
<h2 class="text-green-700 mt-0 mb-2 w-40 max-w-full">Select</h2>
|
||||
{:else if $alertStore.type === 'input'}
|
||||
<h2 class="text-green-700 mt-0 mb-2 w-40 max-w-full">Input</h2>
|
||||
{/if}
|
||||
{#if $alertStore.type === 'markdown'}
|
||||
<span class="text-gray-300 chattext prose prose-invert chattext2">{@html ParseMarkdown($alertStore.msg)}</span>
|
||||
{:else if $alertStore.type !== 'select'}
|
||||
<span class="text-gray-300">{$alertStore.msg}</span>
|
||||
{/if}
|
||||
{#if $alertStore.type === 'ask'}
|
||||
<div class="flex gap-2 w-full">
|
||||
<button bind:this={btn} class="mt-4 border-borderc bg-transparent outline-none border-solid border-1 p-2 text-lg text-neutral-200 hover:bg-green-500 transition-colors flex-1 focus:border-3" on:click={() => {
|
||||
alertStore.set({
|
||||
type: 'none',
|
||||
msg: 'yes'
|
||||
})
|
||||
}}>YES</button>
|
||||
<button class="mt-4 border-borderc bg-transparent outline-none border-solid border-1 p-2 text-lg text-neutral-200 hover:bg-red-500 transition-colors focus:border-3 flex-1" on:click={() => {
|
||||
alertStore.set({
|
||||
type: 'none',
|
||||
msg: 'no'
|
||||
})
|
||||
}}>NO</button>
|
||||
</div>
|
||||
{:else if $alertStore.type === 'select'}
|
||||
{#each $alertStore.msg.split('||') as n, i}
|
||||
<button bind:this={btn} class="mt-4 border-borderc bg-transparent outline-none border-solid border-1 p-2 text-lg text-neutral-200 hover:bg-green-500 transition-colors focus:border-3" on:click={() => {
|
||||
alertStore.set({
|
||||
type: 'none',
|
||||
msg: i.toString()
|
||||
})
|
||||
}}>{n}</button>
|
||||
{/each}
|
||||
{:else if $alertStore.type === 'error' || $alertStore.type === 'normal' || $alertStore.type === 'markdown'}
|
||||
<button bind:this={btn} class="mt-4 border-borderc bg-transparent outline-none border-solid border-1 p-2 text-lg text-neutral-200 hover:bg-green-500 transition-colors focus:border-3" on:click={() => {
|
||||
alertStore.set({
|
||||
type: 'none',
|
||||
msg: ''
|
||||
})
|
||||
}}>OK</button>
|
||||
{:else if $alertStore.type === 'input'}
|
||||
<input class="text-neutral-200 mt-2 p-2 bg-transparent input-text focus:bg-selected" bind:value={input}>
|
||||
<button bind:this={btn} class="mt-4 border-borderc bg-transparent outline-none border-solid border-1 p-2 text-lg text-neutral-200 hover:bg-green-500 transition-colors focus:border-3" on:click={() => {
|
||||
alertStore.set({
|
||||
type: 'none',
|
||||
msg: input
|
||||
})
|
||||
}}>OK</button>
|
||||
{:else if $alertStore.type === 'selectChar'}
|
||||
<div class="flex w-full items-start flex-wrap gap-2 justify-start">
|
||||
{#each $DataBase.characters as char, i}
|
||||
{#if char.type !== 'group'}
|
||||
{#if char.image}
|
||||
{#await getCharImage($DataBase.characters[i].image, 'css')}
|
||||
<BarIcon onClick={() => {
|
||||
//@ts-ignore
|
||||
alertStore.set({type: 'none',msg: char.chaId})
|
||||
}}>
|
||||
<User/>
|
||||
</BarIcon>
|
||||
{:then im}
|
||||
<BarIcon onClick={() => {
|
||||
//@ts-ignore
|
||||
alertStore.set({type: 'none',msg: char.chaId})
|
||||
}} additionalStyle={im} />
|
||||
|
||||
{/await}
|
||||
{:else}
|
||||
<BarIcon onClick={() => {
|
||||
//@ts-ignore
|
||||
alertStore.set({type: 'none',msg: char.chaId})
|
||||
}}>
|
||||
<User/>
|
||||
</BarIcon>
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{:else if $alertStore.type === 'toast'}
|
||||
<div class="toast-anime absolute right-0 bottom-0 bg-darkbg p-4 break-any rounded-md flex flex-col max-w-3xl max-h-11/12 overflow-y-auto z-50 text-neutral-200"
|
||||
on:animationend={() => {
|
||||
alertStore.set({
|
||||
type: 'none',
|
||||
msg: ''
|
||||
})
|
||||
}}
|
||||
>{$alertStore.msg}</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.break-any{
|
||||
word-break: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
@keyframes toastAnime {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.toast-anime {
|
||||
animation: toastAnime 1s ease-out;
|
||||
}
|
||||
|
||||
.vis{
|
||||
opacity: 1 !important;
|
||||
--tw-bg-opacity: 1 !important;
|
||||
}
|
||||
</style>
|
||||
104
src/lib/Others/ChatList.svelte
Normal file
104
src/lib/Others/ChatList.svelte
Normal file
@@ -0,0 +1,104 @@
|
||||
<script>
|
||||
import { alertConfirm, alertError } from "../../ts/alert";
|
||||
import { language } from "../../lang";
|
||||
import { DataBase } from "../../ts/database";
|
||||
import { selectedCharID } from "../../ts/stores";
|
||||
import { DownloadIcon, EditIcon, FolderUpIcon, PlusIcon, TrashIcon, XIcon } from "lucide-svelte";
|
||||
import { exportChat, importChat } from "../../ts/characters";
|
||||
import { findCharacterbyId } from "../../ts/util";
|
||||
|
||||
let editMode = false
|
||||
export let close = () => {}
|
||||
</script>
|
||||
|
||||
<div class="absolute w-full h-full z-40 bg-black bg-opacity-50 flex justify-center items-center">
|
||||
<div class="bg-darkbg p-4 break-any rounded-md flex flex-col max-w-3xl w-72">
|
||||
<div class="flex items-center text-neutral-200 mb-4">
|
||||
<h2 class="mt-0 mb-0">{language.chatList}</h2>
|
||||
<div class="flex-grow flex justify-end">
|
||||
<button class="text-gray-500 hover:text-green-500 mr-2 cursor-pointer items-center" on:click={close}>
|
||||
<XIcon size={24}/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{#each $DataBase.characters[$selectedCharID].chats as chat, i}
|
||||
<button on:click={() => {
|
||||
if(!editMode){
|
||||
$DataBase.characters[$selectedCharID].chatPage = i
|
||||
close()
|
||||
}
|
||||
}} class="flex items-center text-neutral-200 border-t-1 border-solid border-0 border-gray-600 p-2 cursor-pointer" class:bg-selected={i === $DataBase.characters[$selectedCharID].chatPage}>
|
||||
{#if editMode}
|
||||
<input class="text-neutral-200 p-2 bg-transparent input-text focus:bg-selected" bind:value={$DataBase.characters[$selectedCharID].chats[i].name} placeholder="string">
|
||||
{:else}
|
||||
<span>{chat.name}</span>
|
||||
{/if}
|
||||
<div class="flex-grow flex justify-end">
|
||||
<button class="text-gray-500 hover:text-green-500 mr-2 cursor-pointer" on:click={async (e) => {
|
||||
e.stopPropagation()
|
||||
exportChat(i)
|
||||
}}>
|
||||
<DownloadIcon size={18}/>
|
||||
</button>
|
||||
<button class="text-gray-500 hover:text-green-500 cursor-pointer" on:click={async (e) => {
|
||||
e.stopPropagation()
|
||||
if($DataBase.characters[$selectedCharID].chats.length === 1){
|
||||
alertError(language.errors.onlyOneChat)
|
||||
return
|
||||
}
|
||||
const d = await alertConfirm(`${language.removeConfirm}${chat.name}`)
|
||||
if(d){
|
||||
$DataBase.characters[$selectedCharID].chatPage = 0
|
||||
let chats = $DataBase.characters[$selectedCharID].chats
|
||||
chats.splice(i, 1)
|
||||
$DataBase.characters[$selectedCharID].chats = chats
|
||||
}
|
||||
}}>
|
||||
<TrashIcon size={18}/>
|
||||
</button>
|
||||
</div>
|
||||
</button>
|
||||
{/each}
|
||||
<div class="flex mt-2 items-center">
|
||||
<button class="text-gray-500 hover:text-green-500 cursor-pointer mr-1" on:click={() => {
|
||||
const cha = $DataBase.characters[$selectedCharID]
|
||||
const len = $DataBase.characters[$selectedCharID].chats.length
|
||||
let chats = $DataBase.characters[$selectedCharID].chats
|
||||
chats.push({
|
||||
message:[], note:'', name:`New Chat ${len + 1}`, localLore:[]
|
||||
})
|
||||
if(cha.type === 'group'){
|
||||
cha.characters.map((c) => {
|
||||
chats[len].message.push({
|
||||
saying: c,
|
||||
role: 'char',
|
||||
data: findCharacterbyId(c).firstMessage
|
||||
})
|
||||
})
|
||||
}
|
||||
$DataBase.characters[$selectedCharID].chats = chats
|
||||
$DataBase.characters[$selectedCharID].chatPage = len
|
||||
close()
|
||||
}}>
|
||||
<PlusIcon/>
|
||||
</button>
|
||||
<button class="text-gray-500 hover:text-green-500 mr-2 cursor-pointer" on:click={() => {
|
||||
importChat()
|
||||
}}>
|
||||
<FolderUpIcon size={18}/>
|
||||
</button>
|
||||
<button class="text-gray-500 hover:text-green-500 cursor-pointer" on:click={() => {
|
||||
editMode = !editMode
|
||||
}}>
|
||||
<EditIcon size={18}/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.break-any{
|
||||
word-break: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
</style>
|
||||
19
src/lib/Others/Check.svelte
Normal file
19
src/lib/Others/Check.svelte
Normal file
@@ -0,0 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { CheckIcon } from "lucide-svelte";
|
||||
|
||||
export let check = false
|
||||
export let onChange = (check) => {}
|
||||
</script>
|
||||
|
||||
<label class="mr-2">
|
||||
<input type="checkbox" class="hidden" 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"></div>
|
||||
{/if}
|
||||
</label>
|
||||
52
src/lib/Others/GridCatalog.svelte
Normal file
52
src/lib/Others/GridCatalog.svelte
Normal file
@@ -0,0 +1,52 @@
|
||||
<script lang="ts">
|
||||
import { characterFormatUpdate, getCharImage } from "../../ts/characters";
|
||||
import { DataBase } from "../../ts/database";
|
||||
import BarIcon from "../SideBars/BarIcon.svelte";
|
||||
import { User, Users } from "lucide-svelte";
|
||||
import { selectedCharID } from "../../ts/stores";
|
||||
export let endGrid = () => {}
|
||||
let search = ''
|
||||
|
||||
function changeChar(index = -1){
|
||||
characterFormatUpdate(index)
|
||||
selectedCharID.set(index)
|
||||
endGrid()
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="h-full w-full flex justify-center">
|
||||
<div class="h-full p-2 bg-darkbg max-w-full w-2xl flex items-center flex-col ">
|
||||
<h1 class="text-neutral-200 text-2xl font-bold mt-2">Catalog</h1>
|
||||
<input class="text-neutral-200 mt-2 mb-4 p-2 bg-transparent input-text focus:bg-selected w-4/5 text-xl" placeholder="Search" bind:value={search}>
|
||||
<div class="w-full flex justify-center">
|
||||
<div class="flex flex-wrap gap-2 mx-auto container">
|
||||
{#each $DataBase.characters.filter((c) => {
|
||||
return c.name.toLocaleLowerCase().includes(search.toLocaleLowerCase())
|
||||
}) as char, i}
|
||||
<div class="flex items-center text-neutral-200">
|
||||
{#if char.image}
|
||||
<BarIcon onClick={() => {changeChar(i)}} additionalStyle={getCharImage($DataBase.characters[i].image, 'css')}></BarIcon>
|
||||
{:else}
|
||||
<BarIcon onClick={() => {changeChar(i)}} additionalStyle={i === $selectedCharID ? 'background:#44475a' : ''}>
|
||||
{#if char.type === 'group'}
|
||||
<Users />
|
||||
{:else}
|
||||
<User/>
|
||||
{/if}
|
||||
</BarIcon>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@media (max-width: 640px) {
|
||||
.container {
|
||||
justify-content: center;
|
||||
width: fit-content;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
19
src/lib/Others/Help.svelte
Normal file
19
src/lib/Others/Help.svelte
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
<button class="relative help inline-block cursor-default hover:text-green-500" on:click={() => {
|
||||
alertMd(language.help[key])
|
||||
}}>
|
||||
{#if key === "experimental"}
|
||||
<FlaskConicalIcon size={14} />
|
||||
{:else}
|
||||
<HelpCircleIcon size={14} />
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<script lang="ts">
|
||||
import { FlaskConicalIcon, HelpCircleIcon } from "lucide-svelte";
|
||||
import { language } from "src/lang";
|
||||
import { alertMd } from "src/ts/alert";
|
||||
|
||||
export let key: (keyof (typeof language.help))
|
||||
</script>
|
||||
191
src/lib/Others/WelcomeRisu.svelte
Normal file
191
src/lib/Others/WelcomeRisu.svelte
Normal file
@@ -0,0 +1,191 @@
|
||||
<script>
|
||||
import { ArrowBigLeftIcon } from "lucide-svelte";
|
||||
import { changeLanguage, language } from "src/lang";
|
||||
import { addDefaultCharacters } from "src/ts/characters";
|
||||
import { DataBase } from "src/ts/database";
|
||||
|
||||
let step = 0
|
||||
let provider = 0
|
||||
</script>
|
||||
|
||||
<div class="w-full h-full bg-bgcolor flex justify-center">
|
||||
<article class="max-w-screen-md w-full prose prose-invert bg-darkbg p-5 overflow-y-auto overflow-x-hidden">
|
||||
<div class="w-full justify-center flex">
|
||||
<img src="/logo.png" alt="logo">
|
||||
</div>
|
||||
<div class="w-full justify-center flex">
|
||||
<h1>Welcome to RisuAI!</h1>
|
||||
</div>
|
||||
{#if step === 0}
|
||||
<h2>Choose the language</h2>
|
||||
<div class="flex flex-col items-start ml-2">
|
||||
<button class="hover:text-green-500 transition-colors" on:click={() => {
|
||||
changeLanguage('en')
|
||||
step = 1
|
||||
}}>• English</button>
|
||||
<button class="hover:text-green-500 transition-colors" on:click={() => {
|
||||
changeLanguage('ko')
|
||||
step = 1
|
||||
}}>• 한국어</button>
|
||||
</div>
|
||||
|
||||
{:else if step === 1}
|
||||
<h2>{language.setup.chooseProvider}</h2>
|
||||
<div class="flex flex-col items-start ml-2">
|
||||
<button class="hover:text-green-500 transition-colors" on:click={() => {
|
||||
provider = 1
|
||||
step += 1
|
||||
}}>• {language.setup.openaikey}</button>
|
||||
<button class="hover:text-green-500 transition-colors"on:click={() => {
|
||||
provider = 2
|
||||
step += 1
|
||||
}}>• {language.setup.openaiProxy}</button>
|
||||
<button class="hover:text-green-500 transition-colors" on:click={() => {
|
||||
provider = 3
|
||||
step += 1
|
||||
}}>• {language.setup.setupmodelself}</button>
|
||||
</div>
|
||||
{:else if step === 2}
|
||||
{#if provider === 1}
|
||||
<h2>{language.setup.openaikey}</h2>
|
||||
<div class="w-full ml-2">
|
||||
<span>API key</span>
|
||||
<input class="text-neutral-200 mt-2 p-2 bg-transparent input-text focus:bg-selected m-0" bind:value={$DataBase.openAIKey}>
|
||||
</div>
|
||||
<span class="text-gray-400">{language.setup.apiKeyhelp} <a href="https://platform.openai.com/account/api-keys" target="_blank">https://platform.openai.com/account/api-keys</a></span>
|
||||
<div class="flex flex-col items-start ml-2 mt-6">
|
||||
<button class="hover:text-green-500 transition-colors" on:click={() => {
|
||||
provider = 1
|
||||
step += 1
|
||||
}}>• {language.confirm}</button>
|
||||
</div>
|
||||
{:else if provider === 2}
|
||||
<h2>{language.setup.openaiProxy}</h2>
|
||||
<div class="w-full ml-2">
|
||||
<span>OpenAI Reverse Proxy URL</span>
|
||||
<input class="text-neutral-200 mt-2 p-2 bg-transparent input-text focus:bg-selected m-0" bind:value={$DataBase.forceReplaceUrl} placeholder="https://...">
|
||||
</div>
|
||||
<div class="w-full ml-2 mt-4">
|
||||
<span>API key (Used for passwords)</span>
|
||||
<input class="text-neutral-200 mt-2 p-2 bg-transparent input-text focus:bg-selected m-0" bind:value={$DataBase.openAIKey} placeholder="Optional">
|
||||
</div>
|
||||
<div class="flex flex-col items-start ml-2 mt-6">
|
||||
<button class="hover:text-green-500 transition-colors" on:click={() => {
|
||||
provider = 1
|
||||
step += 1
|
||||
}}>• {language.confirm}</button>
|
||||
</div>
|
||||
{:else}
|
||||
<h2>{language.setup.setupmodelself}</h2>
|
||||
<div class="w-full ml-2">
|
||||
<span>{language.setup.setupSelfHelp}</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-start ml-2 mt-6">
|
||||
<button class="hover:text-green-500 transition-colors" on:click={() => {
|
||||
provider = 1
|
||||
step += 1
|
||||
}}>• {language.confirm}</button>
|
||||
</div>
|
||||
{/if}
|
||||
{:else if step === 3}
|
||||
<h2>{language.setup.theme}</h2>
|
||||
<div class="flex flex-col items-start ml-2">
|
||||
<button class="hover:text-green-500 transition-colors flex flex-col items-start" on:click={() => {
|
||||
$DataBase.theme = ''
|
||||
step += 1
|
||||
}}><span>• Standard Risu</span>
|
||||
<img class="w-3/4 mt-2" src="/ss2.webp" alt="example"></button>
|
||||
<button class="hover:text-green-500 transition-colors flex flex-col items-start" on:click={() => {
|
||||
$DataBase.theme = 'waifu'
|
||||
step += 1
|
||||
}}><span>• Waifulike (Not suitable for mobile)</span>
|
||||
<img class="w-3/4 mt-2" src="/ss3.webp" alt="example"></button>
|
||||
</div>
|
||||
{:else if step === 4}
|
||||
<h2>{language.setup.theme}</h2>
|
||||
<div class="flex flex-col items-start ml-2">
|
||||
<button class="hover:text-green-500 transition-colors flex flex-col items-start" on:click={() => {
|
||||
$DataBase.theme = ''
|
||||
step += 1
|
||||
}}><span>• Standard Risu</span>
|
||||
<img class="w-3/4 mt-2" src="/ss2.webp" alt="example"></button>
|
||||
<button class="hover:text-green-500 transition-colors flex flex-col items-start" on:click={() => {
|
||||
$DataBase.theme = 'waifu'
|
||||
step += 1
|
||||
}}><span>• Waifulike</span>
|
||||
<img class="w-3/4 mt-2" src="/ss3.webp" alt="example"></button>
|
||||
</div>
|
||||
{:else if step === 4}
|
||||
<h2>{language.setup.theme}</h2>
|
||||
<div class="flex flex-col items-start ml-2">
|
||||
<button class="hover:text-green-500 transition-colors flex flex-col items-start" on:click={() => {
|
||||
$DataBase.theme = ''
|
||||
step += 1
|
||||
}}><span>• Standard Risu</span>
|
||||
<img class="w-3/4 mt-2" src="/ss2.webp" alt="example"></button>
|
||||
<button class="hover:text-green-500 transition-colors flex flex-col items-start" on:click={() => {
|
||||
$DataBase.theme = 'waifu'
|
||||
step += 1
|
||||
}}><span>• Waifulike</span>
|
||||
<img class="w-3/4 mt-2" src="/ss3.webp" alt="example"></button>
|
||||
</div>
|
||||
{:else if step === 5}
|
||||
<h2>{language.setup.texttheme}</h2>
|
||||
<div class="flex flex-col items-start ml-2">
|
||||
<button class="hover:text-green-500 transition-colors flex flex-col items-start" on:click={() => {
|
||||
$DataBase.theme = ''
|
||||
step += 1
|
||||
}}><span>• {language.classicRisu}</span>
|
||||
<div class="border-borderc py-2 px-8 not-prose">
|
||||
<p class="mt-2 mb-0 classic p-0"> Normal Text</p>
|
||||
<p class="mt-2 mb-0 classic-italic italic p-0">Italic Text</p>
|
||||
<p class="mt-2 mb-0 classic font-bold p-0">Bold Text</p>
|
||||
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-col items-start ml-2 mt-2 mb-2">
|
||||
<button class="hover:text-green-500 transition-colors flex flex-col items-start" on:click={() => {
|
||||
$DataBase.theme = ''
|
||||
step += 1
|
||||
}}><span>• {language.highcontrast}</span>
|
||||
<div class="border-borderc p-2 py-2 px-8 not-prose">
|
||||
<p class="mt-2 mb-0 classic p-0" style="color:#f8f8f2"> Normal Text</p>
|
||||
<p class="mt-2 mb-0 classic-italic italic p-0" style="color:#F1FA8C">Italic Text</p>
|
||||
<p class="mt-2 mb-0 classic font-bold p-0" style="color:#FFB86C">Bold Text</p>
|
||||
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
{:else if step === 6}
|
||||
<h2>{language.setup.inputName}</h2>
|
||||
<div class="w-full ml-2">
|
||||
<input class="text-neutral-200 mt-2 p-2 bg-transparent input-text focus:bg-selected m-0" bind:value={$DataBase.username}>
|
||||
</div>
|
||||
<div class="flex flex-col items-start ml-2 mt-6">
|
||||
<button class="hover:text-green-500 transition-colors" on:click={async () => {
|
||||
$DataBase.forceReplaceUrl2 = $DataBase.forceReplaceUrl
|
||||
await addDefaultCharacters()
|
||||
$DataBase.didFirstSetup = true
|
||||
}}>• {language.confirm}</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
{#if step > 0}
|
||||
|
||||
<button class="hover:text-green-500 transition-colors ml-2" on:click={() => {
|
||||
step = step - 1
|
||||
}}>• Go Back</button>
|
||||
{/if}
|
||||
|
||||
</article>
|
||||
</div>
|
||||
<style>
|
||||
.classic{
|
||||
color: #fafafa;
|
||||
}
|
||||
.classic-italic{
|
||||
color: #8C8D93;
|
||||
}
|
||||
</style>
|
||||
83
src/lib/Others/botpreset.svelte
Normal file
83
src/lib/Others/botpreset.svelte
Normal file
@@ -0,0 +1,83 @@
|
||||
<script>
|
||||
import { alertConfirm, alertError } from "../../ts/alert";
|
||||
import { language } from "../../lang";
|
||||
import { DataBase, changeToPreset, presetTemplate } from "../../ts/database";
|
||||
import { EditIcon, PlusIcon, TrashIcon, XIcon } from "lucide-svelte";
|
||||
|
||||
let editMode = false
|
||||
export let close = () => {}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="absolute w-full h-full z-40 bg-black bg-opacity-50 flex justify-center items-center">
|
||||
<div class="bg-darkbg p-4 break-any rounded-md flex flex-col max-w-3xl w-96">
|
||||
<div class="flex items-center text-neutral-200 mb-4">
|
||||
<h2 class="mt-0 mb-0">{language.presets}</h2>
|
||||
<div class="flex-grow flex justify-end">
|
||||
<button class="text-gray-500 hover:text-green-500 mr-2 cursor-pointer items-center" on:click={close}>
|
||||
<XIcon size={24}/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{#each $DataBase.botPresets as presets, i}
|
||||
<button on:click={() => {
|
||||
if(!editMode){
|
||||
changeToPreset(i)
|
||||
close()
|
||||
}
|
||||
}} class="flex items-center text-neutral-200 border-t-1 border-solid border-0 border-gray-600 p-2 cursor-pointer" class:bg-selected={i === $DataBase.botPresetsId}>
|
||||
{#if editMode}
|
||||
<input class="text-neutral-200 p-2 bg-transparent input-text focus:bg-selected" bind:value={$DataBase.botPresets[i].name} placeholder="string">
|
||||
{:else}
|
||||
{#if i < 9}
|
||||
<span class="w-2 text-center mr-2 text-gray-400">{i + 1}</span>
|
||||
{/if}
|
||||
<span>{presets.name}</span>
|
||||
{/if}
|
||||
<div class="flex-grow flex justify-end">
|
||||
<button class="text-gray-500 hover:text-green-500 cursor-pointer" on:click={async (e) => {
|
||||
e.stopPropagation()
|
||||
if($DataBase.botPresets.length === 1){
|
||||
alertError(language.errors.onlyOneChat)
|
||||
return
|
||||
}
|
||||
const d = await alertConfirm(`${language.removeConfirm}${presets.name}`)
|
||||
if(d){
|
||||
changeToPreset(0)
|
||||
let botPresets = $DataBase.botPresets
|
||||
botPresets.splice(i, 1)
|
||||
$DataBase.botPresets = botPresets
|
||||
}
|
||||
}}>
|
||||
<TrashIcon size={18}/>
|
||||
</button>
|
||||
</div>
|
||||
</button>
|
||||
{/each}
|
||||
<div class="flex mt-2 items-center">
|
||||
<button class="text-gray-500 hover:text-green-500 cursor-pointer mr-1" on:click={() => {
|
||||
let botPresets = $DataBase.botPresets
|
||||
let newPreset = JSON.parse(JSON.stringify(presetTemplate))
|
||||
newPreset.name = `New Preset`
|
||||
botPresets.push(newPreset)
|
||||
|
||||
$DataBase.botPresets = botPresets
|
||||
}}>
|
||||
<PlusIcon/>
|
||||
</button>
|
||||
<button class="text-gray-500 hover:text-green-500 cursor-pointer" on:click={() => {
|
||||
editMode = !editMode
|
||||
}}>
|
||||
<EditIcon size={18}/>
|
||||
</button>
|
||||
</div>
|
||||
<span class="text-gray-400 text-sm">{language.quickPreset}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.break-any{
|
||||
word-break: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user