Add hotkeys
This commit is contained in:
@@ -1079,4 +1079,33 @@ export const languageEnglish = {
|
|||||||
axModelsDef: "Ax Models Definition",
|
axModelsDef: "Ax Models Definition",
|
||||||
doNotChangeSeperateModels: "Do Not Change Seperate Models",
|
doNotChangeSeperateModels: "Do Not Change Seperate Models",
|
||||||
tools: "Tools",
|
tools: "Tools",
|
||||||
|
action: "Action",
|
||||||
|
hotkey: "Hotkey",
|
||||||
|
hotkeyDesc: {
|
||||||
|
reroll: "Reroll",
|
||||||
|
unreroll: "Undo Reroll",
|
||||||
|
translate: "Translate",
|
||||||
|
remove: "Remove",
|
||||||
|
edit: "Edit",
|
||||||
|
copy: "Copy",
|
||||||
|
send: "Send",
|
||||||
|
settings: "Settings",
|
||||||
|
home: "Home",
|
||||||
|
presets: "Quick Presets Select",
|
||||||
|
persona: "Quick Persona Select",
|
||||||
|
modelSelect: "Quick Model Select",
|
||||||
|
toggleCSS: "Toggle CSS",
|
||||||
|
prevChar: "Previous Character",
|
||||||
|
nextChar: "Next Character",
|
||||||
|
quickMenu: "Quick Menu",
|
||||||
|
quickSettings: "Quick Settings",
|
||||||
|
toggleVoice: "Toggle Voice",
|
||||||
|
toggleLog: "Toggle Log",
|
||||||
|
previewRequest: "Preview Request",
|
||||||
|
import: "Import",
|
||||||
|
export: "Export",
|
||||||
|
webcam: "Toggle Webcam",
|
||||||
|
focusInput: "Focus Input",
|
||||||
|
},
|
||||||
|
screenTooSmall: "Screen is too small to show the interface.",
|
||||||
}
|
}
|
||||||
|
|||||||
73
src/lib/Setting/Pages/HotkeySettings.svelte
Normal file
73
src/lib/Setting/Pages/HotkeySettings.svelte
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { language } from "src/lang";
|
||||||
|
import { DBState } from "src/ts/stores.svelte";
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if window.innerWidth < 768}
|
||||||
|
<span class="text-red-500">
|
||||||
|
{language.screenTooSmall}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{:else}
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{language.hotkey}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{#each DBState.db.hotkeys as hotkey}
|
||||||
|
<tr>
|
||||||
|
<td>{language.hotkeyDesc[hotkey.action]}</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class:text-textcolor={hotkey.ctrl}
|
||||||
|
class:text-textcolor2={!hotkey.ctrl}
|
||||||
|
onclick={() => {
|
||||||
|
hotkey.ctrl = !hotkey.ctrl;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Ctrl
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
class:text-textcolor={hotkey.shift}
|
||||||
|
class:text-textcolor2={!hotkey.shift}
|
||||||
|
onclick={() => {
|
||||||
|
hotkey.shift = !hotkey.shift;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Shift
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
class:text-textcolor={hotkey.alt}
|
||||||
|
class:text-textcolor2={!hotkey.alt}
|
||||||
|
onclick={() => {
|
||||||
|
hotkey.alt = !hotkey.alt;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Alt
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
value={hotkey.key === ' ' ? "SPACE" : hotkey.key?.toLocaleUpperCase()}
|
||||||
|
class="bg-bgcolor border-none w-16"
|
||||||
|
onkeydown={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
hotkey.key = e.key;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{/if}
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
import ThanksPage from "./Pages/ThanksPage.svelte";
|
import ThanksPage from "./Pages/ThanksPage.svelte";
|
||||||
import ModuleSettings from "./Pages/Module/ModuleSettings.svelte";
|
import ModuleSettings from "./Pages/Module/ModuleSettings.svelte";
|
||||||
import { isLite } from "src/ts/lite";
|
import { isLite } from "src/ts/lite";
|
||||||
|
import HotkeySettings from "./Pages/HotkeySettings.svelte";
|
||||||
|
|
||||||
let openLoreList = $state(false)
|
let openLoreList = $state(false)
|
||||||
if(window.innerWidth >= 900 && $SettingsMenuIndex === -1 && !$MobileGUI){
|
if(window.innerWidth >= 900 && $SettingsMenuIndex === -1 && !$MobileGUI){
|
||||||
@@ -122,6 +123,15 @@
|
|||||||
<UserIcon />
|
<UserIcon />
|
||||||
<span>{language.account} & {language.files}</span>
|
<span>{language.account} & {language.files}</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||||
|
class:text-textcolor={$SettingsMenuIndex === 15}
|
||||||
|
class:text-textcolor2={$SettingsMenuIndex !== 15}
|
||||||
|
onclick={() => {
|
||||||
|
$SettingsMenuIndex = 15
|
||||||
|
}}>
|
||||||
|
<ActivityIcon />
|
||||||
|
<span>{language.hotkey}</span>
|
||||||
|
</button>
|
||||||
{#if !$isLite}
|
{#if !$isLite}
|
||||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||||
class:text-textcolor={$SettingsMenuIndex === 6}
|
class:text-textcolor={$SettingsMenuIndex === 6}
|
||||||
@@ -186,6 +196,8 @@
|
|||||||
<PromptSettings onGoBack={() => {
|
<PromptSettings onGoBack={() => {
|
||||||
$SettingsMenuIndex = 1
|
$SettingsMenuIndex = 1
|
||||||
}}/>
|
}}/>
|
||||||
|
{:else if $SettingsMenuIndex === 15}
|
||||||
|
<HotkeySettings/>
|
||||||
{:else if $SettingsMenuIndex === 77}
|
{:else if $SettingsMenuIndex === 77}
|
||||||
<ThanksPage/>
|
<ThanksPage/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
141
src/ts/defaulthotkeys.ts
Normal file
141
src/ts/defaulthotkeys.ts
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
|
||||||
|
export interface Hotkey{
|
||||||
|
key: string
|
||||||
|
ctrl?: boolean
|
||||||
|
shift?: boolean
|
||||||
|
alt?: boolean
|
||||||
|
action: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultHotkeys: Hotkey[] = [
|
||||||
|
{
|
||||||
|
key: 'r',
|
||||||
|
ctrl: true,
|
||||||
|
alt: true,
|
||||||
|
action: 'reroll'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'f',
|
||||||
|
ctrl: true,
|
||||||
|
alt: true,
|
||||||
|
action: 'unreroll'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 't',
|
||||||
|
ctrl: true,
|
||||||
|
alt: true,
|
||||||
|
action: 'translate'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'd',
|
||||||
|
ctrl: true,
|
||||||
|
alt: true,
|
||||||
|
action: 'remove'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'e',
|
||||||
|
ctrl: true,
|
||||||
|
alt: true,
|
||||||
|
action: 'edit'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'c',
|
||||||
|
ctrl: true,
|
||||||
|
alt: true,
|
||||||
|
action: 'copy'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Enter',
|
||||||
|
ctrl: true,
|
||||||
|
alt: true,
|
||||||
|
action: 'send'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 's',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'settings'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'h',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'home'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'p',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'presets'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'e',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'persona'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'm',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'modelSelect'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '.',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'toggleCSS'
|
||||||
|
},
|
||||||
|
|
||||||
|
//Needs to implement after this
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
key: '[',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'prevChar'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ']',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'nextChar'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '`',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'quickMenu'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'q',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'quickSettings'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'v',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'toggleVoice'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'l',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'toggleLog'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'u',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'previewRequest'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'i',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'import'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'x',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'export'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'w',
|
||||||
|
ctrl: true,
|
||||||
|
action: 'webcam'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: ' ',
|
||||||
|
action: 'focusInput'
|
||||||
|
},
|
||||||
|
]
|
||||||
158
src/ts/hotkey.ts
158
src/ts/hotkey.ts
@@ -4,59 +4,132 @@ import { changeToPreset as changeToPreset2, getDatabase } from "./storage/datab
|
|||||||
import { alertStore, MobileGUIStack, MobileSideBar, openPersonaList, openPresetList, SafeModeStore, selectedCharID, settingsOpen } from "./stores.svelte"
|
import { alertStore, MobileGUIStack, MobileSideBar, openPersonaList, openPresetList, SafeModeStore, selectedCharID, settingsOpen } from "./stores.svelte"
|
||||||
import { language } from "src/lang"
|
import { language } from "src/lang"
|
||||||
import { updateTextThemeAndCSS } from "./gui/colorscheme"
|
import { updateTextThemeAndCSS } from "./gui/colorscheme"
|
||||||
|
import { defaultHotkeys } from "./defaulthotkeys"
|
||||||
|
|
||||||
export function initHotkey(){
|
export function initHotkey(){
|
||||||
document.addEventListener('keydown', (ev) => {
|
document.addEventListener('keydown', (ev) => {
|
||||||
if(ev.ctrlKey){
|
if(
|
||||||
|
!ev.ctrlKey &&
|
||||||
|
!ev.altKey &&
|
||||||
|
!ev.shiftKey &&
|
||||||
|
['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)
|
||||||
|
){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if(ev.altKey){
|
|
||||||
switch(ev.key){
|
const database = getDatabase()
|
||||||
case "r":{
|
|
||||||
ev.preventDefault()
|
const hotKeys = database?.hotkeys ?? defaultHotkeys
|
||||||
|
|
||||||
|
let hotkeyRan = false
|
||||||
|
for(const hotkey of hotKeys){
|
||||||
|
let hotKeyRanThisTime = true
|
||||||
|
|
||||||
|
|
||||||
|
hotkey.ctrl = hotkey.ctrl ?? false
|
||||||
|
hotkey.alt = hotkey.alt ?? false
|
||||||
|
hotkey.shift = hotkey.shift ?? false
|
||||||
|
|
||||||
|
if(hotkey.key === ev.key){
|
||||||
|
|
||||||
|
console.log(`Hotkey: "${hotkey.key}" ${hotkey.ctrl} ${hotkey.alt} ${hotkey.shift}`)
|
||||||
|
console.log(`Event: "${ev.key}" ${ev.ctrlKey} ${ev.altKey} ${ev.shiftKey}`)
|
||||||
|
|
||||||
|
}
|
||||||
|
if(hotkey.ctrl !== ev.ctrlKey){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if(hotkey.alt !== ev.altKey){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if(hotkey.shift !== ev.shiftKey){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if(hotkey.key !== ev.key){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if(!hotkey.ctrl && !hotkey.alt && !hotkey.shift){
|
||||||
|
if(['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch(hotkey.action){
|
||||||
|
case 'reroll':{
|
||||||
clickQuery('.button-icon-reroll')
|
clickQuery('.button-icon-reroll')
|
||||||
return
|
break
|
||||||
}
|
}
|
||||||
case "f":{
|
case 'unreroll':{
|
||||||
ev.preventDefault()
|
|
||||||
clickQuery('.button-icon-unreroll')
|
clickQuery('.button-icon-unreroll')
|
||||||
return
|
break
|
||||||
}
|
}
|
||||||
case "t":{
|
case 'translate':{
|
||||||
ev.preventDefault()
|
|
||||||
clickQuery('.button-icon-translate')
|
clickQuery('.button-icon-translate')
|
||||||
return
|
break
|
||||||
}
|
}
|
||||||
case "d":{
|
case 'remove':{
|
||||||
ev.preventDefault()
|
|
||||||
clickQuery('.button-icon-remove')
|
clickQuery('.button-icon-remove')
|
||||||
return
|
break
|
||||||
}
|
}
|
||||||
case 'e':{
|
case 'edit':{
|
||||||
ev.preventDefault()
|
|
||||||
clickQuery('.button-icon-edit')
|
clickQuery('.button-icon-edit')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
focusQuery('.message-edit-area')
|
focusQuery('.message-edit-area')
|
||||||
}, 100)
|
}, 100)
|
||||||
return
|
break
|
||||||
}
|
}
|
||||||
case 'c':{
|
case 'copy':{
|
||||||
ev.preventDefault()
|
|
||||||
clickQuery('.button-icon-copy')
|
clickQuery('.button-icon-copy')
|
||||||
return
|
break
|
||||||
}
|
}
|
||||||
case 'i':{
|
case 'focusInput':{
|
||||||
ev.preventDefault()
|
|
||||||
focusQuery('.text-input-area')
|
focusQuery('.text-input-area')
|
||||||
return
|
break
|
||||||
}
|
}
|
||||||
case 'Enter':{
|
case 'send':{
|
||||||
ev.preventDefault()
|
|
||||||
clickQuery('.button-icon-send')
|
clickQuery('.button-icon-send')
|
||||||
return
|
break
|
||||||
}
|
}
|
||||||
|
case 'settings':{
|
||||||
|
settingsOpen.set(!get(settingsOpen))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'home':{
|
||||||
|
selectedCharID.set(-1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'presets':{
|
||||||
|
openPresetList.set(!get(openPresetList))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'persona':{
|
||||||
|
openPersonaList.set(!get(openPersonaList))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'toggleCSS':{
|
||||||
|
SafeModeStore.set(!get(SafeModeStore))
|
||||||
|
updateTextThemeAndCSS()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
hotKeyRanThisTime = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(hotKeyRanThisTime){
|
||||||
|
hotkeyRan = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hotkeyRan){
|
||||||
|
ev.preventDefault()
|
||||||
|
ev.stopPropagation()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(ev.ctrlKey){
|
||||||
switch (ev.key){
|
switch (ev.key){
|
||||||
case "1":{
|
case "1":{
|
||||||
changeToPreset(0)
|
changeToPreset(0)
|
||||||
@@ -112,37 +185,6 @@ export function initHotkey(){
|
|||||||
ev.stopPropagation()
|
ev.stopPropagation()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 's':{
|
|
||||||
settingsOpen.set(!get(settingsOpen))
|
|
||||||
ev.preventDefault()
|
|
||||||
ev.stopPropagation()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'h':{
|
|
||||||
selectedCharID.set(-1)
|
|
||||||
ev.preventDefault()
|
|
||||||
ev.stopPropagation()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'p':{
|
|
||||||
openPresetList.set(!get(openPresetList))
|
|
||||||
ev.preventDefault()
|
|
||||||
ev.stopPropagation()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'e':{
|
|
||||||
openPersonaList.set(!get(openPersonaList))
|
|
||||||
ev.preventDefault()
|
|
||||||
ev.stopPropagation()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case '.':{
|
|
||||||
SafeModeStore.set(!get(SafeModeStore))
|
|
||||||
updateTextThemeAndCSS()
|
|
||||||
ev.preventDefault()
|
|
||||||
ev.stopPropagation()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ev.key === 'Escape'){
|
if(ev.key === 'Escape'){
|
||||||
|
|||||||
@@ -497,6 +497,7 @@ export function setDatabase(data:Database){
|
|||||||
}
|
}
|
||||||
data.doNotChangeSeperateModels ??= false
|
data.doNotChangeSeperateModels ??= false
|
||||||
data.modelTools ??= []
|
data.modelTools ??= []
|
||||||
|
data.hotkeys ??= structuredClone(defaultHotkeys)
|
||||||
changeLanguage(data.language)
|
changeLanguage(data.language)
|
||||||
setDatabaseLite(data)
|
setDatabaseLite(data)
|
||||||
}
|
}
|
||||||
@@ -943,6 +944,7 @@ export interface Database{
|
|||||||
}
|
}
|
||||||
doNotChangeSeperateModels:boolean
|
doNotChangeSeperateModels:boolean
|
||||||
modelTools: string[]
|
modelTools: string[]
|
||||||
|
hotkeys:Hotkey[]
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SeparateParameters{
|
interface SeparateParameters{
|
||||||
@@ -1743,6 +1745,7 @@ import { LLMFlags, LLMFormat } from '../model/modellist';
|
|||||||
import type { Parameter } from '../process/request';
|
import type { Parameter } from '../process/request';
|
||||||
import type { HypaModel } from '../process/memory/hypamemory';
|
import type { HypaModel } from '../process/memory/hypamemory';
|
||||||
import type { SerializableHypaV3Data } from '../process/memory/hypav3';
|
import type { SerializableHypaV3Data } from '../process/memory/hypav3';
|
||||||
|
import { defaultHotkeys, type Hotkey } from '../defaulthotkeys';
|
||||||
|
|
||||||
export async function downloadPreset(id:number, type:'json'|'risupreset'|'return' = 'json'){
|
export async function downloadPreset(id:number, type:'json'|'risupreset'|'return' = 'json'){
|
||||||
saveCurrentPreset()
|
saveCurrentPreset()
|
||||||
|
|||||||
Reference in New Issue
Block a user