Add Saving Icon
This commit is contained in:
@@ -10,8 +10,7 @@
|
||||
import Settings from './lib/Setting/Settings.svelte';
|
||||
import { showRealmInfoStore, importCharacterProcess } from './ts/characterCards';
|
||||
import RealmFrame from './lib/UI/Realm/RealmFrame.svelte';
|
||||
import { AccountWarning } from './ts/storage/accountStorage';
|
||||
import AccountWarningComp from './lib/Others/AccountWarningComp.svelte';
|
||||
import SavePopupIconComp from './lib/Others/SavePopupIcon.svelte';
|
||||
import Botpreset from './lib/Setting/botpreset.svelte';
|
||||
import ListedPersona from './lib/Setting/listedPersona.svelte';
|
||||
import MobileHeader from './lib/Mobile/MobileHeader.svelte';
|
||||
@@ -87,13 +86,11 @@
|
||||
{#if $ShowRealmFrameStore}
|
||||
<RealmFrame />
|
||||
{/if}
|
||||
{#if $AccountWarning}
|
||||
<AccountWarningComp />
|
||||
{/if}
|
||||
{#if $openPresetList}
|
||||
<Botpreset close={() => {$openPresetList = false}} />
|
||||
{/if}
|
||||
{#if $openPersonaList}
|
||||
<ListedPersona close={() => {$openPersonaList = false}} />
|
||||
{/if}
|
||||
<SavePopupIconComp />
|
||||
</main>
|
||||
@@ -833,4 +833,5 @@ export const languageEnglish = {
|
||||
noWebGPU: "Your Browser or OS doesn't support WebGPU. this will slow down the performance significantly.",
|
||||
menuSideBar: "Menu Side Bar",
|
||||
home: "Home",
|
||||
showSavingIcon: "Show Saving Icon",
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { AlertOctagon } from "lucide-svelte";
|
||||
import { alertMd } from "src/ts/alert";
|
||||
import { AccountWarning } from "src/ts/storage/accountStorage";
|
||||
|
||||
</script>
|
||||
<button class="absolute top-2 right-2 z-10 text-white bg-red-800 hover:bg-red-600 p-2 rounded" onclick={() =>{
|
||||
alertMd($AccountWarning)
|
||||
$AccountWarning = ''
|
||||
}}>
|
||||
<AlertOctagon size={24} />
|
||||
</button>
|
||||
42
src/lib/Others/SavePopupIcon.svelte
Normal file
42
src/lib/Others/SavePopupIcon.svelte
Normal file
@@ -0,0 +1,42 @@
|
||||
<script lang="ts">
|
||||
import { AlertOctagon, SaveIcon } from "lucide-svelte";
|
||||
import { alertMd } from "src/ts/alert";
|
||||
import { saving } from "src/ts/globalApi.svelte";
|
||||
import { AccountWarning } from "src/ts/storage/accountStorage";
|
||||
import { DBState } from "src/ts/stores.svelte";
|
||||
|
||||
</script>
|
||||
|
||||
{#if DBState?.db?.showSavingIcon && saving.state}
|
||||
<div
|
||||
class="absolute top-3 right-3 z-10 text-white p-2 rounded bg-gradient-to-br from-blue-500 to-purple-800 saving-animation pointer-events-none opacity-15"
|
||||
>
|
||||
<SaveIcon size={24} />
|
||||
</div>
|
||||
{:else if $AccountWarning}
|
||||
<button class="absolute top-3 right-3 z-10 text-white bg-red-800 hover:bg-red-600 p-2 rounded" onclick={() =>{
|
||||
alertMd($AccountWarning)
|
||||
$AccountWarning = ''
|
||||
}}>
|
||||
<AlertOctagon size={24} />
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.saving-animation {
|
||||
animation: saving-anime 1s infinite;
|
||||
background-size: 200% auto;
|
||||
}
|
||||
|
||||
@keyframes saving-anime {
|
||||
0% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 100%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -202,7 +202,7 @@
|
||||
<SliderInput min={50} max={200} bind:value={DBState.db.zoomsize} marginBottom/>
|
||||
|
||||
<span class="text-textcolor">{language.lineHeight}</span>
|
||||
<SliderInput min={0.5} max={3} step={0.05} bind:value={DBState.db.lineHeight} marginBottom/>
|
||||
<SliderInput min={0.5} max={3} step={0.05} fixed={2} bind:value={DBState.db.lineHeight} marginBottom/>
|
||||
|
||||
<span class="text-textcolor">{language.iconSize}</span>
|
||||
<SliderInput min={50} max={200} bind:value={DBState.db.iconsize} marginBottom/>
|
||||
@@ -300,6 +300,10 @@
|
||||
<Check bind:check={DBState.db.textScreenRounded} name={language.textScreenRound}/>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center mt-2">
|
||||
<Check bind:check={DBState.db.showSavingIcon} name={language.showSavingIcon}/>
|
||||
</div>
|
||||
|
||||
{#if DBState.db.textScreenBorder}
|
||||
<div class="flex items-center mt-2">
|
||||
<Check check={true} onChange={() => {
|
||||
|
||||
@@ -302,6 +302,9 @@ export async function loadAsset(id:string){
|
||||
}
|
||||
|
||||
let lastSave = ''
|
||||
export let saving = $state({
|
||||
state: false
|
||||
})
|
||||
|
||||
/**
|
||||
* Saves the current state of the database.
|
||||
@@ -335,19 +338,25 @@ export async function saveDb(){
|
||||
$effect.root(() => {
|
||||
|
||||
let selIdState = $state(0)
|
||||
let oldSaveHash = ''
|
||||
|
||||
selectedCharID.subscribe((v) => {
|
||||
selIdState = v
|
||||
})
|
||||
|
||||
$effect(() => {
|
||||
$state.snapshot(DBState?.db?.characters?.[selIdState])
|
||||
let newSaveHash = ''
|
||||
newSaveHash += JSON.stringify(DBState?.db?.characters?.[selIdState])
|
||||
for(const key in DBState.db){
|
||||
if(key !== 'characters'){
|
||||
$state.snapshot(DBState.db[key])
|
||||
newSaveHash += (DBState.db[key])
|
||||
}
|
||||
}
|
||||
changed = true
|
||||
|
||||
if(newSaveHash !== oldSaveHash){
|
||||
changed = true
|
||||
oldSaveHash = newSaveHash
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -356,10 +365,11 @@ export async function saveDb(){
|
||||
await sleep(1000)
|
||||
while(true){
|
||||
if(!changed){
|
||||
await sleep(1000)
|
||||
await sleep(500)
|
||||
continue
|
||||
}
|
||||
|
||||
saving.state = true
|
||||
changed = false
|
||||
|
||||
try {
|
||||
@@ -430,6 +440,8 @@ export async function saveDb(){
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
saving.state = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1392,60 +1392,68 @@ async function requestOoba(arg:RequestDataArgumentExtended):Promise<requestDataR
|
||||
}
|
||||
|
||||
async function requestPlugin(arg:RequestDataArgumentExtended):Promise<requestDataResponse> {
|
||||
const formated = arg.formated
|
||||
const db = getDatabase()
|
||||
const maxTokens = arg.maxTokens
|
||||
const bias = arg.biasString
|
||||
const v2Function = pluginV2.providers.get(db.currentPluginProvider)
|
||||
|
||||
const d = v2Function ? (await v2Function(applyParameters({
|
||||
prompt_chat: formated,
|
||||
mode: arg.mode,
|
||||
bias: []
|
||||
}, [
|
||||
'frequency_penalty','min_p','presence_penalty','repetition_penalty','top_k','top_p','temperature'
|
||||
], {}, arg.mode) as any)) : await pluginProcess({
|
||||
bias: bias,
|
||||
prompt_chat: formated,
|
||||
temperature: (db.temperature / 100),
|
||||
max_tokens: maxTokens,
|
||||
presence_penalty: (db.PresensePenalty / 100),
|
||||
frequency_penalty: (db.frequencyPenalty / 100)
|
||||
})
|
||||
|
||||
if(!d){
|
||||
return {
|
||||
type: 'fail',
|
||||
result: (language.errors.unknownModel)
|
||||
}
|
||||
}
|
||||
else if(!d.success){
|
||||
return {
|
||||
type: 'fail',
|
||||
result: d.content instanceof ReadableStream ? await (new Response(d.content)).text() : d.content
|
||||
}
|
||||
}
|
||||
else if(d.content instanceof ReadableStream){
|
||||
|
||||
let fullText = ''
|
||||
const piper = new TransformStream<string, StreamResponseChunk>( {
|
||||
transform(chunk, control) {
|
||||
fullText += chunk
|
||||
control.enqueue({
|
||||
"0": fullText
|
||||
})
|
||||
}
|
||||
try {
|
||||
const formated = arg.formated
|
||||
const maxTokens = arg.maxTokens
|
||||
const bias = arg.biasString
|
||||
const v2Function = pluginV2.providers.get(db.currentPluginProvider)
|
||||
|
||||
const d = v2Function ? (await v2Function(applyParameters({
|
||||
prompt_chat: formated,
|
||||
mode: arg.mode,
|
||||
bias: []
|
||||
}, [
|
||||
'frequency_penalty','min_p','presence_penalty','repetition_penalty','top_k','top_p','temperature'
|
||||
], {}, arg.mode) as any)) : await pluginProcess({
|
||||
bias: bias,
|
||||
prompt_chat: formated,
|
||||
temperature: (db.temperature / 100),
|
||||
max_tokens: maxTokens,
|
||||
presence_penalty: (db.PresensePenalty / 100),
|
||||
frequency_penalty: (db.frequencyPenalty / 100)
|
||||
})
|
||||
|
||||
return {
|
||||
type: 'streaming',
|
||||
result: d.content.pipeThrough(piper)
|
||||
|
||||
if(!d){
|
||||
return {
|
||||
type: 'fail',
|
||||
result: (language.errors.unknownModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
else if(!d.success){
|
||||
return {
|
||||
type: 'fail',
|
||||
result: d.content instanceof ReadableStream ? await (new Response(d.content)).text() : d.content
|
||||
}
|
||||
}
|
||||
else if(d.content instanceof ReadableStream){
|
||||
|
||||
let fullText = ''
|
||||
const piper = new TransformStream<string, StreamResponseChunk>( {
|
||||
transform(chunk, control) {
|
||||
fullText += chunk
|
||||
control.enqueue({
|
||||
"0": fullText
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
type: 'streaming',
|
||||
result: d.content.pipeThrough(piper)
|
||||
}
|
||||
}
|
||||
else{
|
||||
return {
|
||||
type: 'success',
|
||||
result: d.content
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return {
|
||||
type: 'success',
|
||||
result: d.content
|
||||
type: 'fail',
|
||||
result: `Plugin Error from ${db.currentPluginProvider}: ` + JSON.stringify(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,6 +462,7 @@ export function setDatabase(data:Database){
|
||||
data.customFlags ??= []
|
||||
data.enableCustomFlags ??= false
|
||||
data.assetMaxDifference ??= 4
|
||||
data.showSavingIcon ??= false
|
||||
changeLanguage(data.language)
|
||||
setDatabaseLite(data)
|
||||
}
|
||||
@@ -858,6 +859,7 @@ export interface Database{
|
||||
assetMaxDifference:number
|
||||
menuSideBar:boolean
|
||||
pluginV2: RisuPlugin[]
|
||||
showSavingIcon:boolean
|
||||
}
|
||||
|
||||
interface SeparateParameters{
|
||||
|
||||
Reference in New Issue
Block a user