Improve beta mobile accessibility
This commit is contained in:
@@ -44,8 +44,6 @@
|
||||
</div>
|
||||
{:else if !didFirstSetup}
|
||||
<WelcomeRisu />
|
||||
{:else if $isLite}
|
||||
<LiteMain />
|
||||
{:else if $settingsOpen}
|
||||
<Settings />
|
||||
{:else if $MobileGUI}
|
||||
|
||||
@@ -7,38 +7,37 @@
|
||||
import CharConfig from "../SideBars/CharConfig.svelte";
|
||||
import { WrenchIcon } from "lucide-svelte";
|
||||
import { language } from "src/lang";
|
||||
import SideChatList from "../SideBars/SideChatList.svelte";
|
||||
import DevTool from "../SideBars/DevTool.svelte";
|
||||
let sbt = 0
|
||||
import SideChatList from "../SideBars/SideChatList.svelte";
|
||||
import DevTool from "../SideBars/DevTool.svelte";
|
||||
</script>
|
||||
|
||||
{#if $MobileSideBar}
|
||||
{#if $MobileSideBar > 0}
|
||||
<div class="w-full px-2 py-1 text-textcolor2 border-b border-b-darkborderc bg-darkbg flex justify-start items-center gap-2">
|
||||
<button class="flex-1 border-r border-r-darkborderc" class:text-textcolor={sbt === 0} on:click={() => {
|
||||
sbt = 0
|
||||
<button class="flex-1 border-r border-r-darkborderc" class:text-textcolor={$MobileSideBar === 1} on:click={() => {
|
||||
$MobileSideBar = 1
|
||||
}}>
|
||||
{language.Chat}
|
||||
</button>
|
||||
<button class="flex-1 border-r border-r-darkborderc" class:text-textcolor={sbt === 1} on:click={() => {
|
||||
sbt = 1
|
||||
<button class="flex-1 border-r border-r-darkborderc" class:text-textcolor={$MobileSideBar === 2} on:click={() => {
|
||||
$MobileSideBar = 2
|
||||
}}>
|
||||
{language.character}
|
||||
</button>
|
||||
<button class:text-textcolor={sbt === 2} on:click={() => {
|
||||
sbt = 2
|
||||
<button class:text-textcolor={$MobileSideBar === 3} on:click={() => {
|
||||
$MobileSideBar = 3
|
||||
}}>
|
||||
<WrenchIcon size={18} />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="w-full flex-1 overflow-y-auto">
|
||||
{#if $MobileSideBar}
|
||||
<div class="w-full flex-1 overflow-y-auto bg-bgcolor">
|
||||
{#if $MobileSideBar > 0}
|
||||
<div class="w-full flex flex-col p-2 mt-2 h-full">
|
||||
{#if sbt === 0}
|
||||
{#if $MobileSideBar === 1}
|
||||
<SideChatList bind:chara={$CurrentCharacter} />
|
||||
{:else if sbt === 1}
|
||||
{:else if $MobileSideBar === 2}
|
||||
<CharConfig />
|
||||
{:else if sbt === 2}
|
||||
{:else if $MobileSideBar === 3}
|
||||
<DevTool />
|
||||
{/if}
|
||||
</div>
|
||||
@@ -48,7 +47,7 @@
|
||||
<RealmMain />
|
||||
{:else if $MobileGUIStack === 1}
|
||||
<MobileCharacters />
|
||||
{:else if $MobileGUIStack === 3}
|
||||
{:else if $MobileGUIStack === 2}
|
||||
<Settings />
|
||||
{/if}
|
||||
</div>
|
||||
@@ -1,27 +1,85 @@
|
||||
<script lang="ts">
|
||||
import { DataBase } from "src/ts/storage/database";
|
||||
import { type character, DataBase, type groupChat } from "src/ts/storage/database";
|
||||
import BarIcon from "../SideBars/BarIcon.svelte";
|
||||
import { characterFormatUpdate, getCharImage } from "src/ts/characters";
|
||||
import { MobileSearch, selectedCharID } from "src/ts/stores";
|
||||
import { doingChat } from "src/ts/process";
|
||||
import { language } from "src/lang";
|
||||
import { MessageSquareIcon } from "lucide-svelte";
|
||||
function changeChar(index: number) {
|
||||
if($doingChat){
|
||||
return
|
||||
}
|
||||
characterFormatUpdate(index);
|
||||
characterFormatUpdate(index, {
|
||||
updateInteraction: true,
|
||||
});
|
||||
selectedCharID.set(index);
|
||||
}
|
||||
|
||||
const agoFormatter = new Intl.RelativeTimeFormat(navigator.languages, { style: 'short' });
|
||||
|
||||
function makeAgoText(time:number){
|
||||
if(time === 0){
|
||||
return "Unknown";
|
||||
}
|
||||
const diff = Date.now() - time;
|
||||
if(diff < 3600000){
|
||||
const min = Math.floor(diff / 60000);
|
||||
return agoFormatter.format(-min, 'minute');
|
||||
}
|
||||
if(diff < 86400000){
|
||||
const hour = Math.floor(diff / 3600000);
|
||||
return agoFormatter.format(-hour, 'hour');
|
||||
}
|
||||
if(diff < 604800000){
|
||||
const day = Math.floor(diff / 86400000);
|
||||
return agoFormatter.format(-day, 'day');
|
||||
}
|
||||
if(diff < 2592000000){
|
||||
const week = Math.floor(diff / 604800000);
|
||||
return agoFormatter.format(-week, 'week');
|
||||
}
|
||||
if(diff < 31536000000){
|
||||
const month = Math.floor(diff / 2592000000);
|
||||
return agoFormatter.format(-month, 'month');
|
||||
}
|
||||
const year = Math.floor(diff / 31536000000);
|
||||
return agoFormatter.format(-year, 'year');
|
||||
}
|
||||
|
||||
function sortChar(char: (character|groupChat)[]) {
|
||||
return char.map((c, i) => {
|
||||
return {
|
||||
name: c.name || "Unnamed",
|
||||
image: c.image,
|
||||
chats: c.chats.length,
|
||||
i: i,
|
||||
interaction: c.lastInteraction || 0,
|
||||
agoText: makeAgoText(c.lastInteraction || 0),
|
||||
}
|
||||
}).sort((a, b) => {
|
||||
if (a.interaction === b.interaction) {
|
||||
return a.name.localeCompare(b.name);
|
||||
}
|
||||
return b.interaction - a.interaction;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<div class="flex flex-col items-center w-full">
|
||||
{#each $DataBase.characters as char, i}
|
||||
{#each sortChar($DataBase.characters) as char, i}
|
||||
{#if char.name.toLocaleLowerCase().includes($MobileSearch.toLocaleLowerCase())}
|
||||
<button class="flex p-2 border-t-darkborderc gap-2 w-full" class:border-t={i !== 0} on:click={() => {
|
||||
changeChar(i)
|
||||
changeChar(char.i)
|
||||
}}>
|
||||
<BarIcon additionalStyle={getCharImage(char.image, 'css')}></BarIcon>
|
||||
<div class="flex flex-1 w-full flex-col justify-start items-start text-start">
|
||||
<span>{char.name}</span>
|
||||
<span class="text-sm text-textcolor2">{char.chats.length} Chats</span>
|
||||
<div class="text-sm text-textcolor2 flex items-center w-full flex-wrap">
|
||||
<span class="mr-1">{char.chats}</span>
|
||||
<MessageSquareIcon size={14} />
|
||||
<span class="mr-1 ml-1">|</span>
|
||||
<span>{char.agoText}</span>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
|
||||
import { SettingsIcon, GlobeIcon, HomeIcon, MessageSquare } from "lucide-svelte";
|
||||
import { SettingsIcon, GlobeIcon, HomeIcon, MessageSquare, Volume2Icon, CurlyBraces, ActivityIcon, BookIcon, SmileIcon, UserIcon } from "lucide-svelte";
|
||||
import { language } from "src/lang";
|
||||
import { MobileGUIStack, selectedCharID } from "src/ts/stores";
|
||||
import { CharConfigSubMenu, MobileGUIStack, MobileSideBar, selectedCharID } from "src/ts/stores";
|
||||
|
||||
</script>
|
||||
{#if $selectedCharID === -1}
|
||||
@@ -20,12 +20,53 @@
|
||||
<HomeIcon size={24} />
|
||||
<span class="text-xs">{language.character}</span>
|
||||
</button>
|
||||
<button class="flex justify-center items-center flex-col gap-2 w-20" class:text-textcolor={$MobileGUIStack === 3} on:click={() => {
|
||||
MobileGUIStack.set(3)
|
||||
<button class="flex justify-center items-center flex-col gap-2 w-20" class:text-textcolor={$MobileGUIStack === 2} on:click={() => {
|
||||
MobileGUIStack.set(2)
|
||||
}}>
|
||||
<SettingsIcon size={24} />
|
||||
<span class="text-xs">{language.settings}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
|
||||
{#if $selectedCharID !== -1 && $MobileSideBar === 2}
|
||||
<div class="w-full p-4 text-lg border-t border-t-darkborderc bg-darkbg flex items-center justify-center text-textcolor2 truncate">
|
||||
<button class="flex justify-center items-center flex-col gap-2 w-16 max-w-16" class:text-textcolor={$CharConfigSubMenu === 0} on:click={() => {
|
||||
CharConfigSubMenu.set(0)
|
||||
}}>
|
||||
<UserIcon size={24} />
|
||||
<span class="text-xs truncate max-w-16">{language.basicInfo}</span>
|
||||
</button>
|
||||
<button class="flex justify-center items-center flex-col gap-2 w-16 max-w-16" class:text-textcolor={$CharConfigSubMenu === 1} on:click={() => {
|
||||
CharConfigSubMenu.set(1)
|
||||
}}>
|
||||
<SmileIcon size={24} />
|
||||
<span class="text-xs truncate max-w-16">{language.characterDisplay}</span>
|
||||
</button>
|
||||
<button class="flex justify-center items-center flex-col gap-2 w-16 max-w-16" class:text-textcolor={$CharConfigSubMenu === 3} on:click={() => {
|
||||
CharConfigSubMenu.set(3)
|
||||
}}>
|
||||
<BookIcon size={24} />
|
||||
<span class="text-xs truncate max-w-16">{language.loreBook}</span>
|
||||
</button>
|
||||
<button class="flex justify-center items-center flex-col gap-2 w-16 max-w-16" class:text-textcolor={$CharConfigSubMenu === 5} on:click={() => {
|
||||
CharConfigSubMenu.set(5)
|
||||
}}>
|
||||
<Volume2Icon size={24} />
|
||||
<span class="text-xs truncate max-w-16">TTS</span>
|
||||
</button>
|
||||
<button class="flex justify-center items-center flex-col gap-2 w-16 max-w-16" class:text-textcolor={$CharConfigSubMenu === 4} on:click={() => {
|
||||
CharConfigSubMenu.set(4)
|
||||
}}>
|
||||
<CurlyBraces size={24} />
|
||||
<span class="text-xs truncate max-w-16">{language.scripts}</span>
|
||||
</button>
|
||||
<button class="flex justify-center items-center flex-col gap-2 w-16 max-w-16" class:text-textcolor={$CharConfigSubMenu === 2} on:click={() => {
|
||||
CharConfigSubMenu.set(2)
|
||||
}}>
|
||||
<ActivityIcon size={24} />
|
||||
<span class="text-xs truncate max-w-16">{language.advanced}</span>
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
</script>
|
||||
<div class="w-full px-4 h-16 border-b border-b-darkborderc bg-darkbg flex justify-start items-center gap-2">
|
||||
{#if $selectedCharID !== -1 && $MobileSideBar}
|
||||
{#if $selectedCharID !== -1 && $MobileSideBar > 0}
|
||||
<button on:click={() => {
|
||||
MobileSideBar.set(false)
|
||||
MobileSideBar.set(0)
|
||||
}}>
|
||||
<ArrowLeft />
|
||||
</button>
|
||||
@@ -21,12 +21,12 @@
|
||||
<span class="font-bold text-lg w-2/3 truncate">{$CurrentCharacter.name}</span>
|
||||
<div class="flex-1 flex justify-end">
|
||||
<button on:click={() => {
|
||||
MobileSideBar.set(true)
|
||||
MobileSideBar.set(1)
|
||||
}}>
|
||||
<MenuIcon />
|
||||
</button>
|
||||
</div>
|
||||
{:else if $MobileGUIStack === 3 && $SettingsMenuIndex > -1}
|
||||
{:else if $MobileGUIStack === 2 && $SettingsMenuIndex > -1}
|
||||
<button on:click={() => {
|
||||
SettingsMenuIndex.set(-1)
|
||||
}}>
|
||||
|
||||
@@ -20,55 +20,61 @@
|
||||
import PromptSettings from "./Pages/PromptSettings.svelte";
|
||||
import ThanksPage from "./Pages/ThanksPage.svelte";
|
||||
import ModuleSettings from "./Pages/Module/ModuleSettings.svelte";
|
||||
import { isLite } from "src/ts/lite";
|
||||
|
||||
let openLoreList = false
|
||||
if(window.innerWidth >= 900 && $SettingsMenuIndex === -1){
|
||||
if(window.innerWidth >= 900 && $SettingsMenuIndex === -1 && !$MobileGUI){
|
||||
$SettingsMenuIndex = 1
|
||||
}
|
||||
|
||||
</script>
|
||||
<div class="h-full w-full flex justify-center setting-bg rs-setting-cont">
|
||||
<div class="h-full w-full flex justify-center rs-setting-cont" class:bg-bgcolor={$MobileGUI} class:setting-bg={!$MobileGUI}>
|
||||
<div class="h-full max-w-screen-lg w-full flex relative rs-setting-cont-2">
|
||||
{#if (window.innerWidth >= 700 && !$MobileGUI) || $SettingsMenuIndex === -1}
|
||||
<div class="flex h-full flex-col p-4 pt-8 bg-darkbg gap-2 overflow-y-auto relative rs-setting-cont-3"
|
||||
class:w-full={window.innerWidth < 700}>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 1 || $SettingsMenuIndex === 13}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 1 && $SettingsMenuIndex !== 13}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 1
|
||||
|
||||
}}>
|
||||
<BotIcon />
|
||||
<span>{language.chatBot}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 12}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 12}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 12
|
||||
}}>
|
||||
<ContactIcon />
|
||||
<span>{language.persona}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 2}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 2}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 2
|
||||
}}>
|
||||
<Sailboat />
|
||||
<span>{language.otherBots}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 3}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 3}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 3
|
||||
}}>
|
||||
<MonitorIcon />
|
||||
<span>{language.display}</span>
|
||||
</button>
|
||||
<div class="flex h-full flex-col p-4 pt-8 gap-2 overflow-y-auto relative rs-setting-cont-3"
|
||||
class:w-full={window.innerWidth < 700 || $MobileGUI}
|
||||
class:bg-darkbg={!$MobileGUI} class:bg-bgcolor={$MobileGUI}
|
||||
>
|
||||
|
||||
{#if !$isLite}
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 1 || $SettingsMenuIndex === 13}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 1 && $SettingsMenuIndex !== 13}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 1
|
||||
|
||||
}}>
|
||||
<BotIcon />
|
||||
<span>{language.chatBot}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 12}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 12}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 12
|
||||
}}>
|
||||
<ContactIcon />
|
||||
<span>{language.persona}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 2}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 2}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 2
|
||||
}}>
|
||||
<Sailboat />
|
||||
<span>{language.otherBots}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 3}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 3}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 3
|
||||
}}>
|
||||
<MonitorIcon />
|
||||
<span>{language.display}</span>
|
||||
</button>
|
||||
{/if}
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 10}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 10}
|
||||
@@ -78,33 +84,35 @@
|
||||
<LanguagesIcon />
|
||||
<span>{language.language}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 11}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 11}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 11
|
||||
}}>
|
||||
<AccessibilityIcon />
|
||||
<span>{language.accessibility}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 14}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 14}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 14
|
||||
}}>
|
||||
<PackageIcon />
|
||||
<span>{language.modules}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 4}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 4}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 4
|
||||
}}>
|
||||
<CodeIcon />
|
||||
<span>{language.plugin}</span>
|
||||
</button>
|
||||
{#if !$isLite}
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 11}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 11}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 11
|
||||
}}>
|
||||
<AccessibilityIcon />
|
||||
<span>{language.accessibility}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 14}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 14}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 14
|
||||
}}>
|
||||
<PackageIcon />
|
||||
<span>{language.modules}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 4}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 4}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 4
|
||||
}}>
|
||||
<CodeIcon />
|
||||
<span>{language.plugin}</span>
|
||||
</button>
|
||||
{/if}
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 0}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 0}
|
||||
@@ -114,24 +122,26 @@
|
||||
<UserIcon />
|
||||
<span>{language.account} & {language.files}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 6}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 6}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 6
|
||||
}}>
|
||||
<ActivityIcon />
|
||||
<span>{language.advancedSettings}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 77}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 77}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 77
|
||||
}}>
|
||||
<BoxIcon />
|
||||
<span>{language.supporterThanks}</span>
|
||||
</button>
|
||||
{#if !$isLite}
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 6}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 6}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 6
|
||||
}}>
|
||||
<ActivityIcon />
|
||||
<span>{language.advancedSettings}</span>
|
||||
</button>
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 77}
|
||||
class:text-textcolor2={$SettingsMenuIndex !== 77}
|
||||
on:click={() => {
|
||||
$SettingsMenuIndex = 77
|
||||
}}>
|
||||
<BoxIcon />
|
||||
<span>{language.supporterThanks}</span>
|
||||
</button>
|
||||
{/if}
|
||||
{#if window.innerWidth < 700 && !$MobileGUI}
|
||||
<button class="absolute top-2 right-2 hover:text-green-500 text-textcolor" on:click={() => {
|
||||
settingsOpen.set(false)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { language } from "../../lang";
|
||||
import { tokenizeAccurate } from "../../ts/tokenizer";
|
||||
import { DataBase, saveImage as saveAsset, type Database, type character, type groupChat } from "../../ts/storage/database";
|
||||
import { ShowRealmFrameStore, selectedCharID } from "../../ts/stores";
|
||||
import { CharConfigSubMenu, MobileGUI, ShowRealmFrameStore, selectedCharID } from "../../ts/stores";
|
||||
import { PlusIcon, SmileIcon, TrashIcon, UserIcon, ActivityIcon, BookIcon, User, CurlyBraces, Volume2Icon, DownloadIcon, FolderUpIcon } from 'lucide-svelte'
|
||||
import Check from "../UI/GUI/CheckInput.svelte";
|
||||
import { addCharEmotion, addingEmotion, getCharImage, rmCharEmotion, selectCharImg, makeGroupImage, removeChar, changeCharImage } from "../../ts/characters";
|
||||
@@ -34,9 +34,6 @@
|
||||
import Arcodion from "../UI/Arcodion.svelte";
|
||||
import SliderInput from "../UI/GUI/SliderInput.svelte";
|
||||
|
||||
|
||||
|
||||
let subMenu = 0
|
||||
let iconRemoveMode = false
|
||||
let emos:[string, string][] = []
|
||||
let tokens = {
|
||||
@@ -187,35 +184,41 @@
|
||||
};
|
||||
}
|
||||
|
||||
$: {
|
||||
if(currentChar.type === 'group' && ($CharConfigSubMenu === 4 || $CharConfigSubMenu === 5)){
|
||||
$CharConfigSubMenu = 0
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
{#if licensed !== 'private'}
|
||||
{#if licensed !== 'private' && !$MobileGUI}
|
||||
<div class="flex gap-2 mb-2">
|
||||
<button class={subMenu === 0 ? 'text-textcolor ' : 'text-textcolor2'} on:click={() => {subMenu = 0}}>
|
||||
<button class={$CharConfigSubMenu === 0 ? 'text-textcolor ' : 'text-textcolor2'} on:click={() => {$CharConfigSubMenu = 0}}>
|
||||
<UserIcon />
|
||||
</button>
|
||||
<button class={subMenu === 1 ? 'text-textcolor' : 'text-textcolor2'} on:click={() => {subMenu = 1}}>
|
||||
<button class={$CharConfigSubMenu === 1 ? 'text-textcolor' : 'text-textcolor2'} on:click={() => {$CharConfigSubMenu = 1}}>
|
||||
<SmileIcon />
|
||||
</button>
|
||||
<button class={subMenu === 3 ? 'text-textcolor' : 'text-textcolor2'} on:click={() => {subMenu = 3}}>
|
||||
<button class={$CharConfigSubMenu === 3 ? 'text-textcolor' : 'text-textcolor2'} on:click={() => {$CharConfigSubMenu = 3}}>
|
||||
<BookIcon />
|
||||
</button>
|
||||
{#if currentChar.type === 'character'}
|
||||
<button class={subMenu === 5 ? 'text-textcolor' : 'text-textcolor2'} on:click={() => {subMenu = 5}}>
|
||||
<button class={$CharConfigSubMenu === 5 ? 'text-textcolor' : 'text-textcolor2'} on:click={() => {$CharConfigSubMenu = 5}}>
|
||||
<Volume2Icon />
|
||||
</button>
|
||||
<button class={subMenu === 4 ? 'text-textcolor' : 'text-textcolor2'} on:click={() => {subMenu = 4}}>
|
||||
<button class={$CharConfigSubMenu === 4 ? 'text-textcolor' : 'text-textcolor2'} on:click={() => {$CharConfigSubMenu = 4}}>
|
||||
<CurlyBraces />
|
||||
</button>
|
||||
{/if}
|
||||
<button class={subMenu === 2 ? 'text-textcolor' : 'text-textcolor2'} on:click={() => {subMenu = 2}}>
|
||||
<button class={$CharConfigSubMenu === 2 ? 'text-textcolor' : 'text-textcolor2'} on:click={() => {$CharConfigSubMenu = 2}}>
|
||||
<ActivityIcon />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
{#if subMenu === 0}
|
||||
{#if $CharConfigSubMenu === 0}
|
||||
{#if currentChar.type !== 'group' && licensed !== 'private'}
|
||||
<TextInput size="xl" marginBottom placeholder="Character Name" bind:value={currentChar.data.name} />
|
||||
<span class="text-textcolor">{language.description} <Help key="charDesc"/></span>
|
||||
@@ -283,41 +286,44 @@
|
||||
highlight
|
||||
placeholder={getAuthorNoteDefaultText()}
|
||||
/>
|
||||
<span class="text-textcolor2 mb-6 text-sm">{tokens.localNote} {language.tokens}</span>
|
||||
<div class="flex mt-6 items-center">
|
||||
<Check bind:check={$DataBase.jailbreakToggle} name={language.jailbreakToggle}/>
|
||||
</div>
|
||||
<span class="text-textcolor2 mb-6 text-sm">{tokens.localNote} {language.tokens}</span>
|
||||
|
||||
{#each parseKeyValue($DataBase.customPromptTemplateToggle) as toggle}
|
||||
<div class="flex mt-2 items-center">
|
||||
<Check check={$DataBase.globalChatVariables[`toggle_${toggle[0]}`] === '1'} name={toggle[1]} onChange={() => {
|
||||
$DataBase.globalChatVariables[`toggle_${toggle[0]}`] = $DataBase.globalChatVariables[`toggle_${toggle[0]}`] === '1' ? '0' : '1'
|
||||
}} />
|
||||
{#if !$MobileGUI}
|
||||
<div class="flex mt-6 items-center">
|
||||
<Check bind:check={$DataBase.jailbreakToggle} name={language.jailbreakToggle}/>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
|
||||
{#if $DataBase.supaModelType !== 'none' || $DataBase.hanuraiEnable}
|
||||
{#if $DataBase.hanuraiEnable}
|
||||
{#each parseKeyValue($DataBase.customPromptTemplateToggle) as toggle}
|
||||
<div class="flex mt-2 items-center">
|
||||
<Check bind:check={currentChar.data.supaMemory} name={ language.hanuraiMemory}/>
|
||||
<Check check={$DataBase.globalChatVariables[`toggle_${toggle[0]}`] === '1'} name={toggle[1]} onChange={() => {
|
||||
$DataBase.globalChatVariables[`toggle_${toggle[0]}`] = $DataBase.globalChatVariables[`toggle_${toggle[0]}`] === '1' ? '0' : '1'
|
||||
}} />
|
||||
</div>
|
||||
{:else if $DataBase.hypaMemory}
|
||||
{/each}
|
||||
|
||||
|
||||
{#if $DataBase.supaModelType !== 'none' || $DataBase.hanuraiEnable}
|
||||
{#if $DataBase.hanuraiEnable}
|
||||
<div class="flex mt-2 items-center">
|
||||
<Check bind:check={currentChar.data.supaMemory} name={ language.hanuraiMemory}/>
|
||||
</div>
|
||||
{:else if $DataBase.hypaMemory}
|
||||
<div class="flex mt-2 items-center">
|
||||
<Check bind:check={currentChar.data.supaMemory} name={ language.ToggleHypaMemory}/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex mt-2 items-center">
|
||||
<Check bind:check={currentChar.data.supaMemory} name={ language.ToggleSuperMemory}/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{#if currentChar.type === 'group'}
|
||||
<div class="flex mt-2 items-center">
|
||||
<Check bind:check={currentChar.data.supaMemory} name={ language.ToggleHypaMemory}/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex mt-2 items-center">
|
||||
<Check bind:check={currentChar.data.supaMemory} name={ language.ToggleSuperMemory}/>
|
||||
<Check bind:check={currentChar.data.orderByOrder} name={language.orderByOrder}/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{#if currentChar.type === 'group'}
|
||||
<div class="flex mt-2 items-center">
|
||||
<Check bind:check={currentChar.data.orderByOrder} name={language.orderByOrder}/>
|
||||
</div>
|
||||
{/if}
|
||||
{#if licensed === 'private'}
|
||||
<Button on:click={async () => {
|
||||
const conf = await alertConfirm(language.removeConfirm + currentChar.data.name)
|
||||
@@ -339,10 +345,12 @@
|
||||
{:else if licensed === 'private'}
|
||||
<span>You are not allowed</span>
|
||||
{(() => {
|
||||
subMenu = 0
|
||||
$CharConfigSubMenu = 0
|
||||
})()}
|
||||
{:else if subMenu === 1}
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.characterDisplay}</h2>
|
||||
{:else if $CharConfigSubMenu === 1}
|
||||
{#if !$MobileGUI}
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.characterDisplay}</h2>
|
||||
{/if}
|
||||
<span class="text-textcolor mt-2 mb-2">{currentChar.type !== 'group' ? language.charIcon : language.groupIcon}</span>
|
||||
{#if currentChar.type === 'group'}
|
||||
<button on:click={async () => {await selectCharImg($selectedCharID);currentChar = currentChar}}>
|
||||
@@ -549,13 +557,16 @@
|
||||
}
|
||||
}}/>
|
||||
{/if}
|
||||
{:else if subMenu === 3}
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.loreBook} <Help key="lorebook"/></h2>
|
||||
{:else if $CharConfigSubMenu === 3}
|
||||
{#if !$MobileGUI}
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.loreBook} <Help key="lorebook"/></h2>
|
||||
{/if}
|
||||
<LoreBook />
|
||||
{:else if subMenu === 4}
|
||||
{:else if $CharConfigSubMenu === 4}
|
||||
{#if currentChar.type === 'character'}
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.scripts}</h2>
|
||||
|
||||
{#if !$MobileGUI}
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.scripts}</h2>
|
||||
{/if}
|
||||
<span class="text-textcolor mt-2">Bias <Help key="bias"/></span>
|
||||
<div class="w-full max-w-full border border-selected rounded-md p-2">
|
||||
|
||||
@@ -712,9 +723,11 @@
|
||||
<TextAreaInput margin="both" autocomplete="off" bind:value={currentChar.data.virtualscript}></TextAreaInput>
|
||||
{/if}
|
||||
{/if}
|
||||
{:else if subMenu === 5}
|
||||
{:else if $CharConfigSubMenu === 5}
|
||||
{#if currentChar.type === 'character'}
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">TTS</h2>
|
||||
{#if !$MobileGUI}
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">TTS</h2>
|
||||
{/if}
|
||||
<span class="text-textcolor">{language.provider}</span>
|
||||
<SelectInput className="mb-4 mt-2" bind:value={currentChar.data.ttsMode} on:change={(e) => {
|
||||
if(currentChar.type === 'character'){
|
||||
@@ -949,8 +962,10 @@
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{:else if subMenu === 2}
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.advancedSettings}</h2>
|
||||
{:else if $CharConfigSubMenu === 2}
|
||||
{#if !$MobileGUI}
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.advancedSettings}</h2>
|
||||
{/if}
|
||||
{#if currentChar.type !== 'group'}
|
||||
<span class="text-textcolor">{language.exampleMessage} <Help key="exampleMessage"/></span>
|
||||
<TextAreaInput highlight margin="both" autocomplete="off" bind:value={currentChar.data.exampleMessage}></TextAreaInput>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import { findCharacterbyId, parseKeyValue, sleep, sortableOptions } from "src/ts/util";
|
||||
import CheckInput from "../UI/GUI/CheckInput.svelte";
|
||||
import { createMultiuserRoom } from "src/ts/sync/multiuser";
|
||||
import { CurrentCharacter } from "src/ts/stores";
|
||||
import { CurrentCharacter, MobileGUI } from "src/ts/stores";
|
||||
import Sortable from 'sortablejs/modular/sortable.core.esm.js';
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { v4 } from "uuid";
|
||||
@@ -189,18 +189,18 @@
|
||||
|
||||
{#if parseKeyValue($DataBase.customPromptTemplateToggle).length > 4}
|
||||
<div class="h-48 border-darkborderc p-2 border rounded flex flex-col items-start mt-2 overflow-y-auto">
|
||||
<div class="flex mt-2 items-center">
|
||||
<div class="flex mt-2 items-center w-full" class:justify-end={$MobileGUI}>
|
||||
<CheckInput bind:check={$DataBase.jailbreakToggle} name={language.jailbreakToggle}/>
|
||||
</div>
|
||||
{#each parseKeyValue($DataBase.customPromptTemplateToggle) as toggle}
|
||||
<div class="flex mt-2 items-center">
|
||||
<div class="flex mt-2 items-center w-full" class:justify-end={$MobileGUI}>
|
||||
<CheckInput check={$DataBase.globalChatVariables[`toggle_${toggle[0]}`] === '1'} name={toggle[1]} onChange={() => {
|
||||
$DataBase.globalChatVariables[`toggle_${toggle[0]}`] = $DataBase.globalChatVariables[`toggle_${toggle[0]}`] === '1' ? '0' : '1'
|
||||
}} />
|
||||
</div>
|
||||
{/each}
|
||||
{#if $DataBase.supaModelType !== 'none' || $DataBase.hanuraiEnable}
|
||||
<div class="flex mt-2 items-center">
|
||||
<div class="flex mt-2 items-center w-full" class:justify-end={$MobileGUI}>
|
||||
<CheckInput bind:check={chara.supaMemory} name={$DataBase.hanuraiEnable ? language.hanuraiMemory : $DataBase.hypaMemory ? language.ToggleHypaMemory : language.ToggleSuperMemory}/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -90,7 +90,9 @@
|
||||
return
|
||||
}
|
||||
reseter();
|
||||
characterFormatUpdate(index);
|
||||
characterFormatUpdate(index, {
|
||||
updateInteraction: true,
|
||||
});
|
||||
selectedCharID.set(index);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
export let margin = true
|
||||
export let name = ''
|
||||
export let hiddenName = false
|
||||
export let reverse = false
|
||||
export let className = ""
|
||||
export let grayText = false
|
||||
</script>
|
||||
@@ -16,6 +17,9 @@
|
||||
aria-describedby="{name} {check ? 'abled' : 'disabled'}"
|
||||
aria-labelledby="{name} {check ? 'abled' : 'disabled'}"
|
||||
>
|
||||
{#if !hiddenName && reverse}
|
||||
<span>{name}<slot /></span>
|
||||
{/if}
|
||||
<input
|
||||
class="hidden"
|
||||
type="checkbox"
|
||||
@@ -39,7 +43,7 @@
|
||||
</svg>
|
||||
{/if}
|
||||
</span>
|
||||
{#if !hiddenName}
|
||||
{#if !hiddenName && !reverse}
|
||||
<span>{name}<slot /></span>
|
||||
{/if}
|
||||
</label>
|
||||
|
||||
@@ -66,6 +66,8 @@ async function importCharacterProcess(f:{
|
||||
}
|
||||
}
|
||||
|
||||
let db = get(DataBase)
|
||||
db.statics.imports += 1
|
||||
|
||||
if(f.name.endsWith('charx')){
|
||||
console.log('reading charx')
|
||||
@@ -235,7 +237,6 @@ async function importCharacterProcess(f:{
|
||||
const charaData:OldTavernChar = JSON.parse(Buffer.from(readedChara, 'base64').toString('utf-8'))
|
||||
console.log(charaData)
|
||||
const imgp = await saveAsset(await reencodeImage(img))
|
||||
let db = get(DataBase)
|
||||
db.characters.push(convertOffSpecCards(charaData, imgp))
|
||||
DataBase.set(db)
|
||||
alertNormal(language.importedCharacter)
|
||||
|
||||
@@ -412,7 +412,9 @@ function formatTavernChat(chat:string, charName:string){
|
||||
return chat.replace(/<([Uu]ser)>|\{\{([Uu]ser)\}\}/g, getUserName()).replace(/((\{\{)|<)([Cc]har)(=.+)?((\}\})|>)/g, charName)
|
||||
}
|
||||
|
||||
export function characterFormatUpdate(index:number|character){
|
||||
export function characterFormatUpdate(index:number|character, arg:{
|
||||
updateInteraction?:boolean,
|
||||
} = {}){
|
||||
let db = get(DataBase)
|
||||
let cha = typeof(index) === 'number' ? db.characters[index] : index
|
||||
if(cha.chats.length === 0){
|
||||
@@ -504,6 +506,7 @@ export function characterFormatUpdate(index:number|character){
|
||||
if(checkNullish(cha.customscript)){
|
||||
cha.customscript = []
|
||||
}
|
||||
cha.lastInteraction = Date.now()
|
||||
if(typeof(index) === 'number'){
|
||||
db.characters[index] = cha
|
||||
setDatabase(db)
|
||||
|
||||
@@ -36,8 +36,8 @@ export const defaultColorScheme: ColorScheme = {
|
||||
const colorShemes = {
|
||||
"default": defaultColorScheme,
|
||||
"light": {
|
||||
bgcolor: "#f0f0f0",
|
||||
darkbg: "#ffffff",
|
||||
bgcolor: "#ffffff",
|
||||
darkbg: "#f0f0f0",
|
||||
borderc: "#0f172a",
|
||||
selected: "#e0e0e0",
|
||||
draculared: "#ff5555",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { get } from "svelte/store"
|
||||
import { alertSelect, alertToast, doingAlert } from "./alert"
|
||||
import { DataBase, changeToPreset as changeToPreset2 } from "./storage/database"
|
||||
import { openPersonaList, openPresetList, SafeModeStore, selectedCharID, settingsOpen } from "./stores"
|
||||
import { MobileGUIStack, MobileSideBar, openPersonaList, openPresetList, SafeModeStore, selectedCharID, settingsOpen } from "./stores"
|
||||
import { language } from "src/lang"
|
||||
import { updateTextThemeAndCSS } from "./gui/colorscheme"
|
||||
|
||||
@@ -143,6 +143,50 @@ export function initHotkey(){
|
||||
})
|
||||
}
|
||||
|
||||
export function initMobileGesture(){
|
||||
|
||||
let pressingPointers = new Map<number, {x:number, y:number}>()
|
||||
|
||||
document.addEventListener('pointerdown', (ev) => {
|
||||
pressingPointers.set(ev.pointerId, {x: ev.clientX, y: ev.clientY})
|
||||
}, {
|
||||
passive: true
|
||||
})
|
||||
document.addEventListener('pointerup', (ev) => {
|
||||
const d = pressingPointers.get(ev.pointerId)
|
||||
const moveX = ev.clientX - d.x
|
||||
const moveY = ev.clientY - d.y
|
||||
pressingPointers.delete(ev.pointerId)
|
||||
|
||||
if(moveX > 50 && Math.abs(moveY) < Math.abs(moveX)){
|
||||
if(get(selectedCharID) === -1){
|
||||
if(get(MobileGUIStack) > 0){
|
||||
MobileGUIStack.update(v => v - 1)
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(get(MobileSideBar) > 0){
|
||||
MobileSideBar.update(v => v - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(moveX < -50 && Math.abs(moveY) < Math.abs(moveX)){
|
||||
if(get(selectedCharID) === -1){
|
||||
if(get(MobileGUIStack) < 2){
|
||||
MobileGUIStack.update(v => v + 1)
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(get(MobileSideBar) < 3){
|
||||
MobileSideBar.update(v => v + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
passive: true
|
||||
})
|
||||
}
|
||||
|
||||
function changeToPreset(num:number){
|
||||
if(!doingAlert()){
|
||||
let db = get(DataBase)
|
||||
|
||||
@@ -122,8 +122,10 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
|
||||
let db = get(DataBase)
|
||||
db.statics.messages += 1
|
||||
let selectedChar = get(selectedCharID)
|
||||
const nowChatroom = db.characters[selectedChar]
|
||||
nowChatroom.lastInteraction = Date.now()
|
||||
let selectedChat = nowChatroom.chatPage
|
||||
nowChatroom.chats[nowChatroom.chatPage].message = nowChatroom.chats[nowChatroom.chatPage].message.map((v) => {
|
||||
v.chatId = v.chatId ?? v4()
|
||||
|
||||
@@ -436,6 +436,10 @@ export function setDatabase(data:Database){
|
||||
data.falLoraScale ??= 1
|
||||
data.customCSS ??= ''
|
||||
data.strictJsonSchema ??= true
|
||||
data.statics ??= {
|
||||
messages: 0,
|
||||
imports: 0
|
||||
}
|
||||
changeLanguage(data.language)
|
||||
DataBase.set(data)
|
||||
}
|
||||
@@ -734,6 +738,10 @@ export interface Database{
|
||||
jsonSchema:string
|
||||
strictJsonSchema:boolean
|
||||
extractJson:string
|
||||
statics: {
|
||||
messages: number
|
||||
imports: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface customscript{
|
||||
@@ -887,6 +895,7 @@ export interface character{
|
||||
defaultVariables?:string
|
||||
lowLevelAccess?:boolean
|
||||
hideChatIcon?:boolean
|
||||
lastInteraction?:number
|
||||
}
|
||||
|
||||
|
||||
@@ -935,6 +944,7 @@ export interface groupChat{
|
||||
defaultVariables?:string
|
||||
lowLevelAccess?:boolean
|
||||
hideChatIcon?:boolean
|
||||
lastInteraction?:number
|
||||
}
|
||||
|
||||
export interface botPreset{
|
||||
|
||||
@@ -35,6 +35,7 @@ import { removeDefaultHandler } from "src/main";
|
||||
import { updateGuisize } from "../gui/guisize";
|
||||
import { encodeCapKeySafe } from "./mobileStorage";
|
||||
import { updateLorebooks } from "../characters";
|
||||
import { initMobileGesture } from "../hotkey";
|
||||
|
||||
//@ts-ignore
|
||||
export const isTauri = !!window.__TAURI__
|
||||
@@ -542,7 +543,8 @@ export async function loadData() {
|
||||
if(db.botSettingAtStart){
|
||||
botMakerMode.set(true)
|
||||
}
|
||||
if(db.betaMobileGUI && window.innerWidth <= 800){
|
||||
if((db.betaMobileGUI && window.innerWidth <= 800) || import.meta.env.VITE_RISU_LITE){
|
||||
initMobileGesture()
|
||||
MobileGUI.set(true)
|
||||
}
|
||||
loadedStore.set(true)
|
||||
|
||||
@@ -30,7 +30,7 @@ export const openPresetList = writable(false)
|
||||
export const openPersonaList = writable(false)
|
||||
export const MobileGUI = writable(false)
|
||||
export const MobileGUIStack = writable(0)
|
||||
export const MobileSideBar = writable(false)
|
||||
export const MobileSideBar = writable(0)
|
||||
//optimization
|
||||
export const CurrentCharacter = writable(null) as Writable<character | groupChat>
|
||||
export const CurrentSimpleCharacter = writable(null) as Writable<simpleCharacterArgument>
|
||||
@@ -50,6 +50,7 @@ export const UserIconProtrait = writable(false)
|
||||
export const CustomCSSStore = writable('')
|
||||
export const SafeModeStore = writable(false)
|
||||
export const MobileSearch = writable('')
|
||||
export const CharConfigSubMenu = writable(0)
|
||||
|
||||
let lastGlobalEnabledModules: string[] = []
|
||||
let lastChatEnabledModules: string[] = []
|
||||
|
||||
Reference in New Issue
Block a user