Add hotkeys
This commit is contained in:
@@ -1079,4 +1079,33 @@ export const languageEnglish = {
|
||||
axModelsDef: "Ax Models Definition",
|
||||
doNotChangeSeperateModels: "Do Not Change Seperate Models",
|
||||
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 ModuleSettings from "./Pages/Module/ModuleSettings.svelte";
|
||||
import { isLite } from "src/ts/lite";
|
||||
import HotkeySettings from "./Pages/HotkeySettings.svelte";
|
||||
|
||||
let openLoreList = $state(false)
|
||||
if(window.innerWidth >= 900 && $SettingsMenuIndex === -1 && !$MobileGUI){
|
||||
@@ -122,6 +123,15 @@
|
||||
<UserIcon />
|
||||
<span>{language.account} & {language.files}</span>
|
||||
</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}
|
||||
<button class="flex gap-2 items-center hover:text-textcolor"
|
||||
class:text-textcolor={$SettingsMenuIndex === 6}
|
||||
@@ -186,6 +196,8 @@
|
||||
<PromptSettings onGoBack={() => {
|
||||
$SettingsMenuIndex = 1
|
||||
}}/>
|
||||
{:else if $SettingsMenuIndex === 15}
|
||||
<HotkeySettings/>
|
||||
{:else if $SettingsMenuIndex === 77}
|
||||
<ThanksPage/>
|
||||
{/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'
|
||||
},
|
||||
]
|
||||
196
src/ts/hotkey.ts
196
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 { language } from "src/lang"
|
||||
import { updateTextThemeAndCSS } from "./gui/colorscheme"
|
||||
import { defaultHotkeys } from "./defaulthotkeys"
|
||||
|
||||
export function initHotkey(){
|
||||
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){
|
||||
case "r":{
|
||||
ev.preventDefault()
|
||||
clickQuery('.button-icon-reroll')
|
||||
return
|
||||
}
|
||||
case "f":{
|
||||
ev.preventDefault()
|
||||
clickQuery('.button-icon-unreroll')
|
||||
return
|
||||
}
|
||||
case "t":{
|
||||
ev.preventDefault()
|
||||
clickQuery('.button-icon-translate')
|
||||
return
|
||||
}
|
||||
case "d":{
|
||||
ev.preventDefault()
|
||||
clickQuery('.button-icon-remove')
|
||||
return
|
||||
}
|
||||
case 'e':{
|
||||
ev.preventDefault()
|
||||
clickQuery('.button-icon-edit')
|
||||
setTimeout(() => {
|
||||
focusQuery('.message-edit-area')
|
||||
}, 100)
|
||||
return
|
||||
}
|
||||
case 'c':{
|
||||
ev.preventDefault()
|
||||
clickQuery('.button-icon-copy')
|
||||
return
|
||||
}
|
||||
case 'i':{
|
||||
ev.preventDefault()
|
||||
focusQuery('.text-input-area')
|
||||
return
|
||||
}
|
||||
case 'Enter':{
|
||||
ev.preventDefault()
|
||||
clickQuery('.button-icon-send')
|
||||
return
|
||||
}
|
||||
|
||||
const database = getDatabase()
|
||||
|
||||
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')
|
||||
break
|
||||
}
|
||||
case 'unreroll':{
|
||||
clickQuery('.button-icon-unreroll')
|
||||
break
|
||||
}
|
||||
case 'translate':{
|
||||
clickQuery('.button-icon-translate')
|
||||
break
|
||||
}
|
||||
case 'remove':{
|
||||
clickQuery('.button-icon-remove')
|
||||
break
|
||||
}
|
||||
case 'edit':{
|
||||
clickQuery('.button-icon-edit')
|
||||
setTimeout(() => {
|
||||
focusQuery('.message-edit-area')
|
||||
}, 100)
|
||||
break
|
||||
}
|
||||
case 'copy':{
|
||||
clickQuery('.button-icon-copy')
|
||||
break
|
||||
}
|
||||
case 'focusInput':{
|
||||
focusQuery('.text-input-area')
|
||||
break
|
||||
}
|
||||
case 'send':{
|
||||
clickQuery('.button-icon-send')
|
||||
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){
|
||||
case "1":{
|
||||
changeToPreset(0)
|
||||
@@ -112,37 +185,6 @@ export function initHotkey(){
|
||||
ev.stopPropagation()
|
||||
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'){
|
||||
|
||||
@@ -497,6 +497,7 @@ export function setDatabase(data:Database){
|
||||
}
|
||||
data.doNotChangeSeperateModels ??= false
|
||||
data.modelTools ??= []
|
||||
data.hotkeys ??= structuredClone(defaultHotkeys)
|
||||
changeLanguage(data.language)
|
||||
setDatabaseLite(data)
|
||||
}
|
||||
@@ -943,6 +944,7 @@ export interface Database{
|
||||
}
|
||||
doNotChangeSeperateModels:boolean
|
||||
modelTools: string[]
|
||||
hotkeys:Hotkey[]
|
||||
}
|
||||
|
||||
interface SeparateParameters{
|
||||
@@ -1743,6 +1745,7 @@ import { LLMFlags, LLMFormat } from '../model/modellist';
|
||||
import type { Parameter } from '../process/request';
|
||||
import type { HypaModel } from '../process/memory/hypamemory';
|
||||
import type { SerializableHypaV3Data } from '../process/memory/hypav3';
|
||||
import { defaultHotkeys, type Hotkey } from '../defaulthotkeys';
|
||||
|
||||
export async function downloadPreset(id:number, type:'json'|'risupreset'|'return' = 'json'){
|
||||
saveCurrentPreset()
|
||||
|
||||
Reference in New Issue
Block a user