[feat] new sidebar

This commit is contained in:
kwaroran
2023-07-26 00:13:56 +09:00
parent 9d0c48574d
commit 5e9683a5e4
22 changed files with 186 additions and 57 deletions

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import Sidebar from './lib/SideBars/Sidebar.svelte';
import {ArrowRight} from 'lucide-svelte'
import { SizeStore, settingsOpen, sideBarStore } from './ts/stores';
import { DynamicGUI, settingsOpen, sideBarStore } from './ts/stores';
import { DataBase, loadedStore } from './ts/storage/database';
import ChatScreen from './lib/ChatScreens/ChatScreen.svelte';
import AlertComp from './lib/Others/AlertComp.svelte';
@@ -37,7 +37,7 @@
<GridChars endGrid={() => {gridOpen = false}} />
{:else}
{#if $sideBarStore}
{#if ($SizeStore.w > 1028)}
{#if (!$DynamicGUI)}
<Sidebar openGrid={() => {gridOpen = true}} />
{:else}
<div class="fixed top-0 w-full h-full left-0 z-30 flex flex-row items-center">
@@ -48,10 +48,6 @@
</div>
{/if}
{:else}
<button on:click={() => {sideBarStore.set(true)}} class="fixed top-3 left-0 h-12 w-12 border-none rounded-r-md bg-borderc hover:bg-green-500 transition-colors flex items-center justify-center text-neutral-200 opacity-30 hover:opacity-70 z-20">
<ArrowRight />
</button>
{/if}
<ChatScreen />
{/if}

View File

@@ -1,13 +1,14 @@
<script lang="ts">
import { getCustomBackground, getEmotion } from "../../ts/util";
import { DataBase } from "../../ts/storage/database";
import { CharEmotion, SizeStore, selectedCharID, sideBarStore } from "../../ts/stores";
import { CharEmotion, selectedCharID } from "../../ts/stores";
import ResizeBox from './ResizeBox.svelte'
import DefaultChatScreen from "./DefaultChatScreen.svelte";
import defaultWallpaper from '../../etc/bg.jpg'
import ChatList from "../Others/ChatList.svelte";
import TransitionImage from "./TransitionImage.svelte";
import BackgroundDom from "./BackgroundDom.svelte";
import SideBarArrow from "../UI/GUI/SideBarArrow.svelte";
let openChatList = false
const wallPaper = `background: url(${defaultWallpaper})`
@@ -28,6 +29,7 @@
</script>
{#if $DataBase.theme === ''}
<div class="flex-grow h-full min-w-0 relative justify-center flex">
<SideBarArrow />
<BackgroundDom />
<div style={bgImg} class="h-full w-full" class:max-w-6xl={$DataBase.classicMaxWidth}>
{#if $selectedCharID >= 0}
@@ -40,6 +42,7 @@
</div>
{:else if $DataBase.theme === 'waifu'}
<div class="flex-grow h-full flex justify-center relative" style="{bgImg.length < 4 ? wallPaper : bgImg}">
<SideBarArrow />
<BackgroundDom />
{#if $selectedCharID >= 0}
{#if $DataBase.characters[$selectedCharID].viewScreen !== 'none'}
@@ -54,6 +57,7 @@
</div>
{:else if $DataBase.theme === 'waifuMobile'}
<div class="flex-grow h-full relative" style={bgImg.length < 4 ? wallPaper : bgImg}>
<SideBarArrow />
<BackgroundDom />
<div class="w-full absolute z-10 bottom-0 left-0"
class:per33={$selectedCharID >= 0 && $DataBase.characters[$selectedCharID].viewScreen !== 'none'}

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import Check from "src/lib/UI/GUI/Check.svelte";
import Check from "src/lib/UI/GUI/CheckInput.svelte";
import { language } from "src/lang";
import { DataBase } from "src/ts/storage/database";

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import Check from "src/lib/UI/GUI/Check.svelte";
import Check from "src/lib/UI/GUI/CheckInput.svelte";
import { language } from "src/lang";
import { DataBase } from "src/ts/storage/database";
import { alertMd } from "src/ts/alert";

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import Check from "src/lib/UI/GUI/Check.svelte";
import Check from "src/lib/UI/GUI/CheckInput.svelte";
import { language } from "src/lang";
import Help from "src/lib/Others/Help.svelte";
import { DataBase } from "src/ts/storage/database";

View File

@@ -2,7 +2,7 @@
import { language } from "src/lang";
import { DataBase, saveImage, updateTextTheme } from "src/ts/storage/database";
import { changeFullscreen, selectSingleFile, sleep } from "src/ts/util";
import Check from "src/lib/UI/GUI/Check.svelte";
import Check from "src/lib/UI/GUI/CheckInput.svelte";
import Help from "src/lib/Others/Help.svelte";
import SliderInput from "src/lib/UI/GUI/SliderInput.svelte";
import SelectInput from "src/lib/UI/GUI/SelectInput.svelte";

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import Check from "src/lib/UI/GUI/Check.svelte";
import Check from "src/lib/UI/GUI/CheckInput.svelte";
import { changeLanguage, language } from "src/lang";
import { DataBase } from "src/ts/storage/database";
import { sleep } from "src/ts/util";
@@ -16,7 +16,7 @@
<span class="text-neutral-200 mt-4">{language.UiLanguage}</span>
<SelectInput className="mt-2" bind:value={$DataBase.language} on:change={async () => {
if($DataBase.language === 'translang'){
downloadFile('lang.json', Buffer.from(JSON.stringify(languageEnglish, null, 4), 'utf-8'))
downloadFile('lang.json', new TextEncoder().encode(JSON.stringify(languageEnglish, null, 4)))
alertNormal("Downloaded JSON, translate it, and send it to the dev by discord DM and email. I will add it to the next version.")
$DataBase.language = 'en'
}

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import Check from "src/lib/UI/GUI/Check.svelte";
import Check from "src/lib/UI/GUI/CheckInput.svelte";
import { language } from "src/lang";
import Help from "src/lib/Others/Help.svelte";
import { DataBase } from "src/ts/storage/database";

View File

@@ -4,7 +4,7 @@
import { alertConfirm } from "src/ts/alert";
import { DataBase } from "src/ts/storage/database";
import { importPlugin } from "src/ts/plugins/plugins";
import Check from "src/lib/UI/GUI/Check.svelte";
import Check from "src/lib/UI/GUI/CheckInput.svelte";
import TextInput from "src/lib/UI/GUI/TextInput.svelte";
import NumberInput from "src/lib/UI/GUI/NumberInput.svelte";
import SelectInput from "src/lib/UI/GUI/SelectInput.svelte";

View File

@@ -4,7 +4,7 @@
import { getCharImage, selectUserImg } from "src/ts/characters";
import { loadRisuAccountData, saveRisuAccountData } from "src/ts/drive/accounter";
import { DataBase } from "src/ts/storage/database";
import Check from "src/lib/UI/GUI/Check.svelte";
import Check from "src/lib/UI/GUI/CheckInput.svelte";
import { alertConfirm, alertSelect } from "src/ts/alert";
import { forageStorage, isNodeServer, isTauri } from "src/ts/storage/globalApi";
import { unMigrationAccount } from "src/ts/storage/accountStorage";

View File

@@ -4,7 +4,7 @@
import { DataBase, saveImage as saveAsset, type Database, type character, type groupChat } from "../../ts/storage/database";
import { selectedCharID } from "../../ts/stores";
import { PlusIcon, SmileIcon, TrashIcon, UserIcon, ActivityIcon, BookIcon, LoaderIcon, User, DnaIcon, CurlyBraces, Volume2Icon, XIcon } from 'lucide-svelte'
import Check from "../UI/GUI/Check.svelte";
import Check from "../UI/GUI/CheckInput.svelte";
import { addCharEmotion, addingEmotion, getCharImage, rmCharEmotion, selectCharImg, makeGroupImage } from "../../ts/characters";
import LoreBook from "./LoreBook/LoreBookSetting.svelte";
import { alertConfirm, alertError, alertNormal, alertSelectChar, alertTOS } from "../../ts/alert";

View File

@@ -3,7 +3,7 @@
import { language } from "../../../lang";
import type { loreBook } from "../../../ts/storage/database";
import { alertConfirm } from "../../../ts/alert";
import Check from "../../UI/GUI/Check.svelte";
import Check from "../../UI/GUI/CheckInput.svelte";
import Help from "../../Others/Help.svelte";
import TextInput from "../../UI/GUI/TextInput.svelte";
import NumberInput from "../../UI/GUI/NumberInput.svelte";

View File

@@ -4,7 +4,7 @@
import {selectedCharID} from '../../../ts/stores'
import { DownloadIcon, FolderUpIcon, ImportIcon, PlusIcon } from "lucide-svelte";
import { addLorebook, exportLoreBook, importLoreBook } from "../../../ts/process/lorebook";
import Check from "../../UI/GUI/Check.svelte";
import Check from "../../UI/GUI/CheckInput.svelte";
import NumberInput from "../../UI/GUI/NumberInput.svelte";
import LoreBookList from "./LoreBookList.svelte";

View File

@@ -3,7 +3,7 @@
import { language } from "src/lang";
import { alertConfirm } from "src/ts/alert";
import type { customscript } from "src/ts/storage/database";
import Check from "../../UI/GUI/Check.svelte";
import Check from "../../UI/GUI/CheckInput.svelte";
import TextInput from "../../UI/GUI/TextInput.svelte";
import SelectInput from "../../UI/GUI/SelectInput.svelte";
import OptionInput from "../../UI/GUI/OptionInput.svelte";

View File

@@ -0,0 +1,93 @@
<script lang="ts">
import type { character, groupChat } from "src/ts/storage/database";
import { DataBase } from "src/ts/storage/database";
import TextInput from "../UI/GUI/TextInput.svelte";
import { DownloadIcon, TrashIcon } from "lucide-svelte";
import { exportChat } from "src/ts/characters";
import { alertConfirm, alertError } from "src/ts/alert";
import { language } from "src/lang";
import Button from "../UI/GUI/Button.svelte";
import { findCharacterbyId } from "src/ts/util";
import CheckInput from "../UI/GUI/CheckInput.svelte";
export let chara:character|groupChat
let editMode = false
</script>
<div class="flex flex-col w-full h-[calc(100%-2rem)] max-h-[calc(100%-2rem)]">
<Button className="relative bottom-2" on:click={() => {
const cha = chara
const len = chara.chats.length
let chats = chara.chats
chats.unshift({
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
})
})
}
chara.chats = chats
chara.chatPage = 0
}}>New Chat</Button>
<div class="flex flex-col w-full mt-2 overflow-y-auto flex-grow">
{#each chara.chats as chat, i}
<button on:click={() => {
if(!editMode){
chara.chatPage = i
}
}} class="flex items-center text-neutral-200 border-solid border-0 border-gray-600 p-2 cursor-pointer rounded-md"class:bg-selected={i === chara.chatPage}>
{#if editMode}
<TextInput bind:value={chara.chats[i].name} padding={false}/>
{: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(chara.chats.length === 1){
alertError(language.errors.onlyOneChat)
return
}
const d = await alertConfirm(`${language.removeConfirm}${chat.name}`)
if(d){
chara.chatPage = 0
let chats = chara.chats
chats.splice(i, 1)
chara.chats = chats
}
}}>
<TrashIcon size={18}/>
</button>
</div>
</button>
{/each}
</div>
<div class="border-t border-selected mt-2">
<div class="flex mt-2 items-center">
<CheckInput bind:check={$DataBase.jailbreakToggle} name={language.jailbreakToggle}/>
</div>
{#if $DataBase.supaMemoryType !== 'none'}
<div class="flex mt-2 items-center">
<CheckInput bind:check={chara.supaMemory} name={language.ToggleSuperMemory}/>
</div>
{/if}
</div>
{#if chara.type === 'group'}
<div class="flex mt-2 items-center">
<CheckInput bind:check={chara.orderByOrder} name={language.orderByOrder}/>
</div>
{/if}
</div>

View File

@@ -1,7 +1,8 @@
<script lang="ts">
import {
CharEmotion,
SizeStore,
DynamicGUI,
botMakerMode,
selectedCharID,
settingsOpen,
sideBarStore,
@@ -41,6 +42,7 @@
import Button from "../UI/GUI/Button.svelte";
import { fly } from "svelte/transition";
import { alertInput, alertSelect } from "src/ts/alert";
import SideChatList from "./SideChatList.svelte";
let openPresetList = false;
let sideBarMode = 0;
let editMode = false;
@@ -581,7 +583,7 @@
class="setting-area flex w-96 h-full flex-col overflow-y-auto overflow-x-hidden bg-darkbg p-6 text-gray-200 max-h-full"
class:risu-sidebar={!closing}
class:risu-sidebar-close={closing}
class:minw96={$SizeStore.w > 1028}
class:minw96={!$DynamicGUI}
on:animationend={() => {
if(closing){
closing = false
@@ -598,7 +600,7 @@
closing = true;
}}
>
<button class="border-none bg-transparent p-0 text-gray-200"><X /></button>
<!-- <button class="border-none bg-transparent p-0 text-gray-200"><X /></button> -->
</button>
{#if sideBarMode === 0}
{#if $selectedCharID < 0 || $settingsOpen}
@@ -607,7 +609,15 @@
<span class="text-xs text-gray-400">Select a bot to start chating</span>
</div>
{:else}
<CharConfig />
<div class="w-full h-8 min-h-8 border-l border-b border-r border-selected relative bottom-6 rounded-b-md flex">
<button on:click={() => {botMakerMode.set(false)}} class="flex-grow border-r border-r-selected rounded-bl-md" class:text-gray-500={$botMakerMode}>Chat</button>
<button on:click={() => {botMakerMode.set(true)}} class="flex-grow rounded-br-md" class:text-gray-500={!$botMakerMode}>Bot</button>
</div>
{#if $botMakerMode}
<CharConfig />
{:else}
<SideChatList bind:chara={ $DataBase.characters[$selectedCharID]} />
{/if}
{/if}
{:else if sideBarMode === 1}
<Button
@@ -645,8 +655,13 @@
/>
{/if}
{#if $SizeStore.w <= 1028}
<div class="flex-grow h-full"
{#if $DynamicGUI}
<div class="flex-grow h-full min-w-12" on:click={() => {
if(closing){
return
}
closing = true;
}}
class:sidebar-dark-animation={!closing}
class:sidebar-dark-close-animation={closing}>
@@ -664,24 +679,18 @@
@keyframes sidebar-transition {
from {
width: 0rem;
min-width: 0rem;
}
to {
width: 24rem;
min-width: 24rem;
}
}
@keyframes sidebar-transition-close {
from {
width: 24rem;
min-width: 24rem;
max-width: 24rem;
right:0rem;
}
to {
width: 0rem;
min-width: 0rem;
max-width: 0rem;
right: 10rem;
}
}

View File

@@ -8,22 +8,6 @@
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}

View File

@@ -0,0 +1,15 @@
<script lang="ts">
import { ArrowLeft, ArrowRight } from "lucide-svelte";
import { DynamicGUI, sideBarStore } from "src/ts/stores";
</script>
{#if $sideBarStore && !$DynamicGUI}
<button on:click={() => {sideBarStore.set(false)}} class="absolute top-3 left-0 h-12 w-12 border-r border-b border-t border-borderc rounded-r-md bg-darkbg hover:border-neutral-200 transition-colors flex items-center justify-center text-neutral-200 z-20">
<ArrowLeft />
</button>
{:else}
<button on:click={() => {sideBarStore.set(true)}} class="absolute top-3 left-0 h-12 w-12 border-r border-b border-t border-borderc rounded-r-md bg-darkbg hover:border-neutral-200 transition-colors flex items-center justify-center text-neutral-200 opacity-50 hover:opacity-90 z-20">
<ArrowRight />
</button>
{/if}

View File

@@ -524,12 +524,17 @@ const blockMatcher = (p1:string,matcherArg:matcherArg) => {
const content = p1.substring(bn + 1)
const statement = logic.split(" ", 2)
if(["","0","-1"].includes(statement[1])){
return ''
switch(statement[0]){
case 'if':{
if(["","0","-1"].includes(statement[1])){
return ''
}
return content.trim()
}
}
return content.trim()
return null
}
@@ -562,6 +567,7 @@ export function risuChatParser(da:string, arg:{
let nested:string[] = [""]
let pf = performance.now()
let v = new Uint8Array(512)
let pureMode = false
const matcherObj = {
chatID: chatID,
chara: chara,
@@ -603,7 +609,7 @@ export function risuChatParser(da:string, arg:{
}
pointer++
const dat = nested.shift()
const mc = matcher(dat, matcherObj)
const mc = (pureMode) ? null :matcher(dat, matcherObj)
nested[0] += mc ?? `{{${dat}}}`
break
}
@@ -612,8 +618,21 @@ export function risuChatParser(da:string, arg:{
break
}
const dat = nested.shift()
const mc = smMatcher(dat, matcherObj)
nested[0] += mc ?? `<${dat}>`
switch(dat){
case 'Pure':{
pureMode = true
break
}
case '/Pure':{
pureMode = false
break
}
default:{
const mc = (pureMode) ? null : smMatcher(dat, matcherObj)
nested[0] += mc ?? `<${dat}>`
break
}
}
break
}
default:{

View File

@@ -39,7 +39,7 @@ interface fetchLog{
let fetchLog:fetchLog[] = []
export async function downloadFile(name:string, data:Uint8Array) {
export async function downloadFile(name:string, data:Uint8Array|ArrayBuffer) {
const downloadURL = (data:string, fileName:string) => {
const a = document.createElement('a')
a.href = data

View File

@@ -5,17 +5,20 @@ function updateSize(){
w: window.innerWidth,
h: window.innerHeight
})
DynamicGUI.set(window.innerWidth <= 1024)
}
export const SizeStore = writable({
w: 0,
h: 0
})
export const DynamicGUI = writable(false)
export const sideBarStore = writable(window.innerWidth > 1024)
export const selectedCharID = writable(-1)
export const CharEmotion = writable({} as {[key:string]: [string, string, number][]})
export const ViewBoxsize = writable({ width: 12 * 16, height: 12 * 16 }); // Default width and height in pixels
export const settingsOpen = writable(false)
export const botMakerMode = writable(false)
updateSize()
window.addEventListener("resize", updateSize);

View File

@@ -14,10 +14,15 @@ export default {
draculared: "#ff5555"
},
minWidth: {
'2': '0.5rem',
'8': '2rem',
'12': '3rem',
'20': '5rem',
'14': '3.5rem',
'half': '50%',
'5': '1.25rem'
'5': '1.25rem',
'6': '1.5rem',
},
maxWidth:{
'half': '50%',
@@ -36,6 +41,7 @@ export default {
'3xl': '72rem',
},
minHeight:{
'2': '0.5rem',
'8': '2rem',
'5': '1.25rem',
'14': '3.5rem',