Add Custom GUI settings, not for real use now

This commit is contained in:
kwaroran
2024-10-12 22:47:57 +09:00
parent 20f4c39beb
commit 1762e025bd
6 changed files with 278 additions and 1 deletions

View File

@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import Sidebar from './lib/SideBars/Sidebar.svelte'; import Sidebar from './lib/SideBars/Sidebar.svelte';
import { DynamicGUI, settingsOpen, sideBarStore, ShowRealmFrameStore, openPresetList, openPersonaList, MobileGUI } from './ts/stores'; import { DynamicGUI, settingsOpen, sideBarStore, ShowRealmFrameStore, openPresetList, openPersonaList, MobileGUI, CustomGUISettingMenuStore } from './ts/stores';
import { DataBase, loadedStore } from './ts/storage/database'; import { DataBase, loadedStore } from './ts/storage/database';
import ChatScreen from './lib/ChatScreens/ChatScreen.svelte'; import ChatScreen from './lib/ChatScreens/ChatScreen.svelte';
import AlertComp from './lib/Others/AlertComp.svelte'; import AlertComp from './lib/Others/AlertComp.svelte';
@@ -18,6 +18,7 @@
import MobileHeader from './lib/Mobile/MobileHeader.svelte'; import MobileHeader from './lib/Mobile/MobileHeader.svelte';
import MobileBody from './lib/Mobile/MobileBody.svelte'; import MobileBody from './lib/Mobile/MobileBody.svelte';
import MobileFooter from './lib/Mobile/MobileFooter.svelte'; import MobileFooter from './lib/Mobile/MobileFooter.svelte';
import CustomGUISettingMenu from './lib/Setting/Pages/CustomGUISettingMenu.svelte';
let didFirstSetup: boolean = false let didFirstSetup: boolean = false
@@ -40,6 +41,8 @@
</svg> </svg>
<span>Loading...</span> <span>Loading...</span>
</div> </div>
{:else if $CustomGUISettingMenuStore}
<CustomGUISettingMenu />
{:else if !didFirstSetup} {:else if !didFirstSetup}
<WelcomeRisu /> <WelcomeRisu />
{:else if $settingsOpen} {:else if $settingsOpen}

View File

@@ -748,4 +748,5 @@ export const languageEnglish = {
formatGroupInSingle: "Format Group in Single", formatGroupInSingle: "Format Group in Single",
groupInnerFormat: "Non-Speaker Inner Format", groupInnerFormat: "Non-Speaker Inner Format",
groupOtherBotRole: "Non-Speaker Role in Group", groupOtherBotRole: "Non-Speaker Role in Group",
defineCustomGUI: "Define Custom GUI",
} }

View File

@@ -0,0 +1,260 @@
<script lang="ts">
interface CustomTree {
name: string; // dom name, like div, span, etc. for component, we use 'component'
type: string; // type, used for identifying in editor
class: string[]; // classes, used for styling in tailwind
children: CustomTree[]; // children, used for nesting
}
let tree:CustomTree[] = [] //children of the main tree
let mainTree:HTMLDivElement
let menuOpen:boolean = false
let subMenu = 0
let selectedContatiner = 'root'
const builtContainerTrees:CustomTree[] = [
{
type: "leftToRightContainer",
name: "div",
class: ["flex", "flex-row", "flex-1"],
children: []
},
{
type: "topToBottomContainer",
name: "div",
class: ["flex", "flex-col", "flex-1"],
children: []
},
{
type: "centeredleftToRightContainer",
name: "div",
class: ["flex", "flex-row", "flex-1", "items-center", "justify-center"],
children: []
},
{
type: "centeredTopToBottomContainer",
name: "div",
class: ["flex", "flex-col", "flex-1", "items-center", "justify-center"],
children: []
}
]
const builtComponentTrees:CustomTree[] = [
{
type: "fullWidthChat",
name: "component",
class: ["flex", "flex-col", "flex-1"],
children: []
},
{
type: "fixedWidthChat",
name: "component",
class: ["flex", "flex-col", "w-96"],
children: []
},
{
type: "sideBarWithCharacter",
name: "component",
class: ["flex", "flex-col", "w-96"],
children: []
},
{
type: "sideBarWithoutCharacter",
name: "component",
class: ["flex", "flex-col", "w-96"],
children: []
}
]
function renderTree(dom:HTMLElement, currentTree:CustomTree, treeChain:string = "") {
let element = document.createElement(currentTree.name)
element.classList.add(...currentTree.class)
currentTree.children.forEach((child, i) => {
renderTree(element, child, treeChain + "." + i)
})
if(currentTree.type === 'custom'){
dom.appendChild(element)
}
else{
const textElement = document.createElement('p')
textElement.innerText = currentTree.type
if(treeChain === selectedContatiner){
element.classList.add("bg-blue-200", "border-2", "border-blue-400", "relative", "bg-opacity-50", "p-4", "z-20")
textElement.classList.add("absolute", "top-0", "left-0", "bg-blue-200", "p-1", "text-black")
}
else{
element.classList.add("bg-gray-200", "border-2", "border-gray-400", "relative", "bg-opacity-50", "p-4", "z-20")
textElement.classList.add("absolute", "top-0", "left-0", "bg-white", "p-1", "text-black")
}
element.appendChild(textElement)
element.setAttribute("x-tree", treeChain)
dom.appendChild(element)
element.addEventListener('mouseup', (e) => {
console.log(treeChain, e.button)
e.preventDefault()
e.stopPropagation()
switch(e.button){
case 0:
selectedContatiner = treeChain
renderMainTree(tree)
break
case 2:
tree = removeTreeChain(tree, treeChain)
renderMainTree(tree)
break
}
})
element.addEventListener('contextmenu', (e) => {
e.preventDefault()
e.stopPropagation()
})
}
}
function removeTreeChain(tree:CustomTree[], treeChain:string){
let treeChainArray = treeChain.split(".")
let currentTree = tree
for(let i = 0; i < treeChainArray.length; i++){
let index = parseInt(treeChainArray[i])
if(i === treeChainArray.length - 1){
currentTree.splice(index, 1)
}
else{
currentTree = currentTree[index].children
}
}
return tree
}
function renderMainTree(tree:CustomTree[]) {
mainTree.innerHTML = ""
tree.forEach((child, i) => {
renderTree(mainTree, child, i.toString())
})
}
function HTMLtoTree(html:string){
let parser = new DOMParser()
let doc = parser.parseFromString(html, 'text/html')
let body = doc.body
let tree:CustomTree[] = []
let children = body.children
for(let i = 0; i < children.length; i++){
let child = children[i]
let treeChild:CustomTree = {
name: child.tagName.toLowerCase(),
type: child.tagName.toLowerCase(),
class: child.className.split(" "),
children: []
}
if(child.children.length > 0){
treeChild.children = HTMLtoTree(child.innerHTML)
}
tree.push(treeChild)
}
return tree
}
function addContainerToTree(container:CustomTree, treeChain:string){
if(treeChain === 'root'){
tree.push(container)
return
}
let treeChainArray = treeChain.split(".")
let currentTree = tree
for(let i = 0; i < treeChainArray.length; i++){
let index = parseInt(treeChainArray[i])
if(i === treeChainArray.length - 1){
currentTree[index].children.push(container)
}
else{
currentTree = currentTree[index].children
}
}
}
function treeToHTML(tree:CustomTree[], indent:number = 0){
let html = ""
const noClosingTag = ["img", "input", "br", "hr"]
const ind = " ".repeat(indent)
tree.forEach(child => {
if(child.class.length > 0){
html += `${ind}<${child.name} class="${child.class.join(" ")}">\n`
}
else{
html += `${ind}<${child.name}>\n`
}
if(noClosingTag.includes(child.name)){
return
}
if(child.children.length > 0){
html += treeToHTML(child.children, indent + 1)
}
html += `${ind}</${child.name}>\n`
})
return html
}
</script>
<div class="w-full h-full relative flex p-4 border"
class:border-blue-500={selectedContatiner === 'root'}
on:click={() => {
selectedContatiner = 'root'
renderMainTree(tree)
}}
on:contextmenu|preventDefault
bind:this={mainTree}
>
</div>
{#if menuOpen}
<div class="w-138 max-w-full h-full bg-white text-black border-l border-l-black p-4 flex flex-col gap-2 z-20">
<div class="flex">
<button class="mr-2 p-2 border border-black rounded" class:text-gray-500={subMenu !== 0} on:click={() => {
subMenu = 0
}}>Component</button>
<button class="mr-2 p-2 border border-black rounded" class:text-gray-500={subMenu !== 1} on:click={() => {
subMenu = 1
}}>Container</button>
<button class="mr-2 p-2 border border-black rounded" class:text-gray-500={subMenu !== 2} on:click={() => {
subMenu = 2
}}>Help</button>
</div>
<div class="border-b border-b-gray-200">
</div>
{#if subMenu === 0}
{#each builtComponentTrees as component, i}
<button class="p-2 border border-black rounded" on:click={() => {
addContainerToTree(structuredClone(component), selectedContatiner)
renderMainTree(tree)
}}>{component.type}</button>
{/each}
{:else if subMenu === 1}
{#each builtContainerTrees as container, i}
<button class="p-2 border border-black rounded" on:click={() => {
addContainerToTree(structuredClone(container), selectedContatiner)
renderMainTree(tree)
}}>{container.type}</button>
{/each}
{:else if subMenu === 2}
<p>Left click to select, Right click to delete</p>
<p>Press a component/container in the menu to add it to the selected container</p>
{/if}
</div>
{:else}
<button class="absolute top-0 right-0 z-20 p-2 border bg-white rounded" on:click={() => {
menuOpen = !menuOpen
}}>Menu</button>
{/if}

View File

@@ -14,6 +14,9 @@
import TextInput from "src/lib/UI/GUI/TextInput.svelte"; import TextInput from "src/lib/UI/GUI/TextInput.svelte";
import ColorInput from "src/lib/UI/GUI/ColorInput.svelte"; import ColorInput from "src/lib/UI/GUI/ColorInput.svelte";
import TextAreaInput from "src/lib/UI/GUI/TextAreaInput.svelte"; import TextAreaInput from "src/lib/UI/GUI/TextAreaInput.svelte";
import Arcodion from "src/lib/UI/Arcodion.svelte";
import Button from "src/lib/UI/GUI/Button.svelte";
import { CustomGUISettingMenuStore } from "src/ts/stores";
const onSchemeInputChange = (e:Event) => { const onSchemeInputChange = (e:Event) => {
changeColorScheme((e.target as HTMLInputElement).value) changeColorScheme((e.target as HTMLInputElement).value)
@@ -50,8 +53,15 @@
<OptionInput value="" >Standard Risu</OptionInput> <OptionInput value="" >Standard Risu</OptionInput>
<OptionInput value="waifu" >Waifulike</OptionInput> <OptionInput value="waifu" >Waifulike</OptionInput>
<OptionInput value="waifuMobile" >WaifuCut</OptionInput> <OptionInput value="waifuMobile" >WaifuCut</OptionInput>
<!-- <OptionInput value="custom" >Custom GUI</OptionInput> -->
</SelectInput> </SelectInput>
{#if $DataBase.theme === "custom"}
<Button className="mt-2" on:click={() => {
CustomGUISettingMenuStore.set(true)
}}>{language.defineCustomGUI}</Button>
{/if}
{#if $DataBase.theme === "waifu"} {#if $DataBase.theme === "waifu"}
<span class="text-textcolor mt-4">{language.waifuWidth}</span> <span class="text-textcolor mt-4">{language.waifuWidth}</span>

View File

@@ -444,6 +444,7 @@ export function setDatabase(data:Database){
data.customQuotes ??= false data.customQuotes ??= false
data.customQuotesData ??= ['“','”','',''] data.customQuotesData ??= ['“','”','','']
data.groupOtherBotRole ??= 'user' data.groupOtherBotRole ??= 'user'
data.customGUI ??= ''
changeLanguage(data.language) changeLanguage(data.language)
DataBase.set(data) DataBase.set(data)
} }
@@ -752,6 +753,7 @@ export interface Database{
customQuotesData?:[string, string, string, string] customQuotesData?:[string, string, string, string]
groupTemplate?:string groupTemplate?:string
groupOtherBotRole?:string groupOtherBotRole?:string
customGUI:string
} }
export interface customscript{ export interface customscript{

View File

@@ -50,6 +50,7 @@ export const CustomCSSStore = writable('')
export const SafeModeStore = writable(false) export const SafeModeStore = writable(false)
export const MobileSearch = writable('') export const MobileSearch = writable('')
export const CharConfigSubMenu = writable(0) export const CharConfigSubMenu = writable(0)
export const CustomGUISettingMenuStore = writable(false)
let lastGlobalEnabledModules: string[] = [] let lastGlobalEnabledModules: string[] = []
let lastChatEnabledModules: string[] = [] let lastChatEnabledModules: string[] = []