Add mobile gui beta
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import Sidebar from './lib/SideBars/Sidebar.svelte';
|
||||
import { DynamicGUI, settingsOpen, sideBarStore, ShowRealmFrameStore, openPresetList, openPersonaList } from './ts/stores';
|
||||
import { DynamicGUI, settingsOpen, sideBarStore, ShowRealmFrameStore, openPresetList, openPersonaList, MobileGUI } from './ts/stores';
|
||||
import { DataBase, loadedStore } from './ts/storage/database';
|
||||
import ChatScreen from './lib/ChatScreens/ChatScreen.svelte';
|
||||
import AlertComp from './lib/Others/AlertComp.svelte';
|
||||
@@ -17,6 +17,10 @@
|
||||
import LiteMain from './LiteMain.svelte';
|
||||
import Botpreset from './lib/Setting/botpreset.svelte';
|
||||
import ListedPersona from './lib/Setting/listedPersona.svelte';
|
||||
import MobileHeader from './lib/Mobile/MobileHeader.svelte';
|
||||
import MobileBody from './lib/Mobile/MobileBody.svelte';
|
||||
import MobileFooter from './lib/Mobile/MobileFooter.svelte';
|
||||
|
||||
|
||||
let didFirstSetup: boolean = false
|
||||
let gridOpen = false
|
||||
@@ -44,7 +48,12 @@
|
||||
<LiteMain />
|
||||
{:else if $settingsOpen}
|
||||
<Settings />
|
||||
|
||||
{:else if $MobileGUI}
|
||||
<div class="w-full h-full flex flex-col">
|
||||
<MobileHeader />
|
||||
<MobileBody />
|
||||
<MobileFooter />
|
||||
</div>
|
||||
{:else}
|
||||
{#if gridOpen}
|
||||
<GridChars endGrid={() => {gridOpen = false}} />
|
||||
|
||||
@@ -144,6 +144,7 @@ export const languageEnglish = {
|
||||
namespace: "Namespace is a unique identifier for the module. it is used to prevent conflicts between modules, and for interaction of presets, other modules and etc. if you are not sure what to put, leave it blank.",
|
||||
moduleIntergration: "You can enable modules by putting the module namespace in the module intergartion sections. if you want to enable multiple modules, you can seperate them by comma. for example, `module1,module2,module3`. this is for advanced users, who wants to vary the use of modules by presets.",
|
||||
customCSS: "Custom CSS for styling. you can also disable/enable it by pressing (Ctrl + .) if something goes wrong.",
|
||||
betaMobileGUI: "If enabled, it will use beta mobile GUI on small (less than 800px) screens. requires refresh.",
|
||||
},
|
||||
setup: {
|
||||
chooseProvider: "Choose AI Provider",
|
||||
@@ -705,4 +706,6 @@ export const languageEnglish = {
|
||||
promptConvertion: "Prompt Convertion",
|
||||
convertionStep1: "Select all file related to the prompt (Context, Instruct and Sampler JSON is supported)",
|
||||
customCSS: "Custom CSS",
|
||||
betaMobileGUI: "Beta Mobile GUI",
|
||||
menu: "Menu",
|
||||
}
|
||||
54
src/lib/Mobile/MobileBody.svelte
Normal file
54
src/lib/Mobile/MobileBody.svelte
Normal file
@@ -0,0 +1,54 @@
|
||||
<script lang="ts">
|
||||
import { CurrentCharacter, MobileGUIStack, MobileSideBar, selectedCharID } from "src/ts/stores";
|
||||
import Settings from "../Setting/Settings.svelte";
|
||||
import RealmMain from "../UI/Realm/RealmMain.svelte";
|
||||
import MobileCharacters from "./MobileCharacters.svelte";
|
||||
import ChatScreen from "../ChatScreens/ChatScreen.svelte";
|
||||
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
|
||||
</script>
|
||||
|
||||
{#if $MobileSideBar}
|
||||
<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
|
||||
}}>
|
||||
{language.Chat}
|
||||
</button>
|
||||
<button class="flex-1 border-r border-r-darkborderc" class:text-textcolor={sbt === 1} on:click={() => {
|
||||
sbt = 1
|
||||
}}>
|
||||
{language.character}
|
||||
</button>
|
||||
<button class:text-textcolor={sbt === 2} on:click={() => {
|
||||
sbt = 2
|
||||
}}>
|
||||
<WrenchIcon size={18} />
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="w-full flex-1 overflow-y-auto">
|
||||
{#if $MobileSideBar}
|
||||
<div class="w-full flex flex-col p-2 mt-2 h-full">
|
||||
{#if sbt === 0}
|
||||
<SideChatList bind:chara={$CurrentCharacter} />
|
||||
{:else if sbt === 1}
|
||||
<CharConfig />
|
||||
{:else if sbt === 2}
|
||||
<DevTool />
|
||||
{/if}
|
||||
</div>
|
||||
{:else if $selectedCharID !== -1}
|
||||
<ChatScreen />
|
||||
{:else if $MobileGUIStack === 0}
|
||||
<RealmMain />
|
||||
{:else if $MobileGUIStack === 1}
|
||||
<MobileCharacters />
|
||||
{:else if $MobileGUIStack === 3}
|
||||
<Settings />
|
||||
{/if}
|
||||
</div>
|
||||
29
src/lib/Mobile/MobileCharacters.svelte
Normal file
29
src/lib/Mobile/MobileCharacters.svelte
Normal file
@@ -0,0 +1,29 @@
|
||||
<script lang="ts">
|
||||
import { DataBase } 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";
|
||||
function changeChar(index: number) {
|
||||
if($doingChat){
|
||||
return
|
||||
}
|
||||
characterFormatUpdate(index);
|
||||
selectedCharID.set(index);
|
||||
}
|
||||
</script>
|
||||
<div class="flex flex-col items-center w-full">
|
||||
{#each $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)
|
||||
}}>
|
||||
<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>
|
||||
</button>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
31
src/lib/Mobile/MobileFooter.svelte
Normal file
31
src/lib/Mobile/MobileFooter.svelte
Normal file
@@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
|
||||
import { SettingsIcon, GlobeIcon, HomeIcon, MessageSquare } from "lucide-svelte";
|
||||
import { language } from "src/lang";
|
||||
import { MobileGUIStack, selectedCharID } from "src/ts/stores";
|
||||
|
||||
</script>
|
||||
{#if $selectedCharID === -1}
|
||||
|
||||
<div class="w-full p-4 text-lg border-t border-t-darkborderc bg-darkbg flex items-center justify-center text-textcolor2">
|
||||
<button class="flex justify-center items-center flex-col gap-2 w-20" class:text-textcolor={$MobileGUIStack === 0} on:click={() => {
|
||||
MobileGUIStack.set(0)
|
||||
}}>
|
||||
<GlobeIcon size={24} />
|
||||
<span class="text-xs">RisuRealm</span>
|
||||
</button>
|
||||
<button class="flex justify-center items-center flex-col gap-2 w-20" class:text-textcolor={$MobileGUIStack === 1} on:click={() => {
|
||||
MobileGUIStack.set(1)
|
||||
}}>
|
||||
<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)
|
||||
}}>
|
||||
<SettingsIcon size={24} />
|
||||
<span class="text-xs">{language.settings}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
44
src/lib/Mobile/MobileHeader.svelte
Normal file
44
src/lib/Mobile/MobileHeader.svelte
Normal file
@@ -0,0 +1,44 @@
|
||||
<script lang="ts">
|
||||
import { ArrowLeft, MenuIcon } from "lucide-svelte";
|
||||
import { language } from "src/lang";
|
||||
import { CurrentCharacter, MobileGUIStack, MobileSearch, selectedCharID, SettingsMenuIndex, MobileSideBar } from "src/ts/stores";
|
||||
|
||||
</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}
|
||||
<button on:click={() => {
|
||||
MobileSideBar.set(false)
|
||||
}}>
|
||||
<ArrowLeft />
|
||||
</button>
|
||||
<span class="font-bold text-lg w-2/3 truncate">{language.menu}</span>
|
||||
{:else if $selectedCharID !== -1}
|
||||
<button on:click={() => {
|
||||
selectedCharID.set(-1)
|
||||
}}>
|
||||
<ArrowLeft />
|
||||
</button>
|
||||
<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)
|
||||
}}>
|
||||
<MenuIcon />
|
||||
</button>
|
||||
</div>
|
||||
{:else if $MobileGUIStack === 3 && $SettingsMenuIndex > -1}
|
||||
<button on:click={() => {
|
||||
SettingsMenuIndex.set(-1)
|
||||
}}>
|
||||
<ArrowLeft />
|
||||
</button>
|
||||
<span class="font-bold text-lg">RisuAI</span>
|
||||
{:else if $MobileGUIStack === 1}
|
||||
<div class="flex items-stretch w-2xl max-w-full">
|
||||
<input placeholder={language.search + '...'} bind:value={$MobileSearch} class="peer focus:border-textcolor transition-colors outline-none text-textcolor p-2 min-w-0 border bg-transparent rounded-md input-text text-xl flex-grow mx-4 border-darkborderc resize-none overflow-y-hidden overflow-x-hidden max-w-full">
|
||||
</div>
|
||||
{:else}
|
||||
<span class="font-bold text-lg">RisuAI</span>
|
||||
|
||||
{/if}
|
||||
</div>
|
||||
@@ -319,6 +319,11 @@
|
||||
<Check bind:check={$DataBase.unformatQuotes} name={language.unformatQuotes}/>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center mt-2">
|
||||
<Check bind:check={$DataBase.betaMobileGUI} name={language.betaMobileGUI}/>
|
||||
<Help key="betaMobileGUI"/>
|
||||
</div>
|
||||
|
||||
{#if $DataBase.useExperimental}
|
||||
<div class="flex items-center mt-2">
|
||||
<Check bind:check={$DataBase.useChatSticker} name={language.useChatSticker}/>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import PluginSettings from "./Pages/PluginSettings.svelte";
|
||||
import FilesSettings from "./Pages/FilesSettings.svelte";
|
||||
import AdvancedSettings from "./Pages/AdvancedSettings.svelte";
|
||||
import { SettingsMenuIndex, settingsOpen } from "src/ts/stores";
|
||||
import { MobileGUI, SettingsMenuIndex, settingsOpen } from "src/ts/stores";
|
||||
import Botpreset from "./botpreset.svelte";
|
||||
import Communities from "./Pages/Communities.svelte";
|
||||
import GlobalLoreBookSettings from "./Pages/GlobalLoreBookSettings.svelte";
|
||||
@@ -29,7 +29,7 @@
|
||||
</script>
|
||||
<div class="h-full w-full flex justify-center setting-bg rs-setting-cont">
|
||||
<div class="h-full max-w-screen-lg w-full flex relative rs-setting-cont-2">
|
||||
{#if window.innerWidth >= 700 || $SettingsMenuIndex === -1}
|
||||
{#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"
|
||||
@@ -132,14 +132,14 @@
|
||||
<BoxIcon />
|
||||
<span>{language.supporterThanks}</span>
|
||||
</button>
|
||||
{#if window.innerWidth < 700}
|
||||
{#if window.innerWidth < 700 && !$MobileGUI}
|
||||
<button class="absolute top-2 right-2 hover:text-green-500 text-textcolor" on:click={() => {
|
||||
settingsOpen.set(false)
|
||||
}}> <XCircleIcon /> </button>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if window.innerWidth >= 700 || $SettingsMenuIndex !== -1}
|
||||
{#if (window.innerWidth >= 700 && !$MobileGUI) || $SettingsMenuIndex !== -1}
|
||||
{#key $SettingsMenuIndex}
|
||||
<div class="flex-grow py-6 px-4 bg-bgcolor flex flex-col text-textcolor overflow-y-auto relative rs-setting-cont-4">
|
||||
{#if $SettingsMenuIndex === 0}
|
||||
@@ -181,6 +181,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
{/key}
|
||||
{#if !$MobileGUI}
|
||||
<button class="absolute top-2 right-2 hover:text-green-500 text-textcolor" on:click={() => {
|
||||
if(window.innerWidth >= 700){
|
||||
settingsOpen.set(false)
|
||||
@@ -192,6 +193,7 @@
|
||||
<XCircleIcon />
|
||||
</button>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if openLoreList}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { ArrowLeft, ArrowRight } from "lucide-svelte";
|
||||
import { DynamicGUI, sideBarClosing, sideBarStore } from "src/ts/stores";
|
||||
import { DynamicGUI, MobileGUI, sideBarClosing, sideBarStore } from "src/ts/stores";
|
||||
|
||||
</script>
|
||||
|
||||
{#if !MobileGUI}
|
||||
{#if $sideBarStore && !$DynamicGUI}
|
||||
<button on:click={() => {sideBarClosing.set(true)}} class="absolute top-3 left-0 h-12 w-12 border-r border-b border-t border-transparent rounded-r-md bg-darkbg hover:border-neutral-200 transition-colors flex items-center justify-center text-textcolor z-20">
|
||||
<ArrowLeft />
|
||||
@@ -16,3 +17,4 @@
|
||||
<ArrowRight />
|
||||
</button>
|
||||
{/if}
|
||||
{/if}
|
||||
@@ -5,7 +5,7 @@
|
||||
import { language } from "src/lang";
|
||||
import RisuHubIcon from "./RealmHubIcon.svelte";
|
||||
import TextInput from "../GUI/TextInput.svelte";
|
||||
import { SizeStore } from "src/ts/stores";
|
||||
import { MobileGUI, SizeStore } from "src/ts/stores";
|
||||
import { Capacitor } from "@capacitor/core";
|
||||
import RealmPopUp from "./RealmPopUp.svelte";
|
||||
import { googleBuild } from "src/ts/storage/globalApi";
|
||||
@@ -35,29 +35,66 @@
|
||||
|
||||
|
||||
</script>
|
||||
<div class="w-full flex justify-center mt-4">
|
||||
<div class="flex w-2xl max-w-full items-center">
|
||||
{#if $SizeStore.w < 768}
|
||||
<TextInput className="flex-grow min-w-0" placeholder="Search" bind:value={search} />
|
||||
{:else}
|
||||
<TextInput size="xl" className="flex-grow" placeholder="Search" bind:value={search} />
|
||||
|
||||
{/if}
|
||||
<button class="bg-darkbg h-14 w-14 min-w-14 rounded-lg ml-2 flex justify-center items-center hover:ring transition-shadow" on:click={() => {
|
||||
<div class="w-full flex justify-center mt-4 mb-2">
|
||||
<div class="flex items-stretch w-2xl max-w-full">
|
||||
<input bind:value={search} class="peer focus:border-textcolor transition-colors outline-none text-textcolor p-2 min-w-0 border border-r-0 bg-transparent rounded-md rounded-r-none input-text text-xl flex-grow ml-4 border-darkborderc resize-none overflow-y-hidden overflow-x-hidden max-w-full">
|
||||
<button
|
||||
on:click={() => {
|
||||
page = 0
|
||||
getHub()
|
||||
}}>
|
||||
}}
|
||||
class="flex justify-center border-y border-darkborderc items-center text-gray-100 p-3 peer-focus:border-textcolor hover:bg-blue-500 transition-colors"
|
||||
>
|
||||
<SearchIcon />
|
||||
</button>
|
||||
<button class="bg-darkbg h-14 w-14 min-w-14 rounded-lg ml-2 flex justify-center items-center hover:ring transition-shadow" on:click={() => {
|
||||
<button
|
||||
on:click={(e) => {
|
||||
menuOpen = true
|
||||
}}>
|
||||
}}
|
||||
class="peer-focus:border-textcolor mr-2 flex border-y border-r border-darkborderc justify-center items-center text-gray-100 p-3 rounded-r-md hover:bg-blue-500 transition-colors"
|
||||
>
|
||||
<MenuIcon />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{#if $MobileGUI}
|
||||
<div class="ml-4 flex items-start ">
|
||||
<div class="p-2 flex mb-3 overflow-x-auto rounded-lg border-darkborderc border gap-2">
|
||||
<button on:click={() => {
|
||||
nsfw = !nsfw
|
||||
getHub()
|
||||
}}>
|
||||
{nsfw ? 'NSFW' : 'SFW'}
|
||||
</button>
|
||||
<div class="h-full border-r border-r-selected"></div>
|
||||
<button on:click={() => {
|
||||
switch(sort){
|
||||
case '':
|
||||
sort = 'trending'
|
||||
break
|
||||
case 'trending':
|
||||
sort = 'downloads'
|
||||
break
|
||||
case 'downloads':
|
||||
sort = 'random'
|
||||
break
|
||||
default:
|
||||
sort = ''
|
||||
break
|
||||
}
|
||||
getHub()
|
||||
}}>
|
||||
{
|
||||
sort === '' ? language.recent :
|
||||
sort === 'trending' ? language.trending :
|
||||
sort === 'downloads' ? language.downloads :
|
||||
language.random
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="w-full p-1 flex mb-3 overflow-x-auto sm:justify-center">
|
||||
{#if !googleBuild}
|
||||
<button class="bg-darkbg p-2 rounded-lg ml-2 flex justify-center items-center hover:bg-selected transition-shadow" class:ring={nsfw} on:click={() => {
|
||||
nsfw = !nsfw
|
||||
getHub()
|
||||
@@ -65,7 +102,6 @@
|
||||
NSFW
|
||||
</button>
|
||||
<div class="ml-2 mr-2 h-full border-r border-r-selected"></div>
|
||||
{/if}
|
||||
<button class="bg-darkbg p-2 rounded-lg ml-2 flex justify-center items-center hover:bg-selected transition-shadow" class:ring={sort === ''} on:click={() => {
|
||||
sort = ''
|
||||
getHub()
|
||||
@@ -84,13 +120,14 @@
|
||||
}}>
|
||||
{language.downloads}
|
||||
</button>
|
||||
<button class="bg-darkbg p-2 rounded-lg ml-2 flex justify-center items-center hover:bg-selected transition-shadow" class:ring={sort === 'random'} on:click={() => {
|
||||
<button class="bg-darkbg p-2 rounded-lg ml-2 flex justify-center items-center hover:bg-selected transition-shadow min-w-0 max-w-full" class:ring={sort === 'random'} on:click={() => {
|
||||
sort = 'random'
|
||||
getHub()
|
||||
}}>
|
||||
{language.random}
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
{@html hubAdditionalHTML}
|
||||
<div class="w-full flex gap-4 p-2 flex-wrap justify-center">
|
||||
{#key charas}
|
||||
|
||||
@@ -728,6 +728,7 @@ export interface Database{
|
||||
falLoraScale: number
|
||||
moduleIntergration: string
|
||||
customCSS: string
|
||||
betaMobileGUI:boolean
|
||||
}
|
||||
|
||||
export interface customscript{
|
||||
|
||||
@@ -9,7 +9,7 @@ import {open} from '@tauri-apps/api/shell'
|
||||
import { DataBase, loadedStore, setDatabase, type Database, defaultSdDataFunc } from "./database";
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
import { checkRisuUpdate } from "../update";
|
||||
import { botMakerMode, selectedCharID } from "../stores";
|
||||
import { MobileGUI, botMakerMode, selectedCharID } from "../stores";
|
||||
import { Body, ResponseType, fetch as TauriFetch } from "@tauri-apps/api/http";
|
||||
import { loadPlugins } from "../plugins/plugins";
|
||||
import { alertConfirm, alertError, alertNormal, alertNormalWait, alertSelect, alertTOS } from "../alert";
|
||||
@@ -533,6 +533,9 @@ export async function loadData() {
|
||||
if(db.botSettingAtStart){
|
||||
botMakerMode.set(true)
|
||||
}
|
||||
if(db.betaMobileGUI && window.innerWidth <= 800){
|
||||
MobileGUI.set(true)
|
||||
}
|
||||
loadedStore.set(true)
|
||||
selectedCharID.set(-1)
|
||||
startObserveDom()
|
||||
|
||||
@@ -28,8 +28,10 @@ export const botMakerMode = writable(false)
|
||||
export const moduleBackgroundEmbedding = writable('')
|
||||
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)
|
||||
//optimization
|
||||
|
||||
export const CurrentCharacter = writable(null) as Writable<character | groupChat>
|
||||
export const CurrentSimpleCharacter = writable(null) as Writable<simpleCharacterArgument>
|
||||
export const CurrentChat = writable(null) as Writable<Chat>
|
||||
@@ -47,6 +49,7 @@ export const HideIconStore = writable(false)
|
||||
export const UserIconProtrait = writable(false)
|
||||
export const CustomCSSStore = writable('')
|
||||
export const SafeModeStore = writable(false)
|
||||
export const MobileSearch = writable('')
|
||||
|
||||
let lastGlobalEnabledModules: string[] = []
|
||||
let lastChatEnabledModules: string[] = []
|
||||
|
||||
Reference in New Issue
Block a user