improve local-app

This commit is contained in:
Anton Bracke
2022-02-22 10:05:21 +01:00
parent 6b208ceb0c
commit ac18aab773
30 changed files with 841 additions and 105 deletions
+11 -6
View File
@@ -1,12 +1,13 @@
<script lang="ts">
import { Router, Route } from "svelte-navigator";
import Sidebar from "./lib/Sidebar.svelte";
import Sidebar from "~/lib/Sidebar.svelte";
import LazyRoute from "./lib/LazyRoute.svelte";
import LazyRoute from "~/lib/LazyRoute.svelte";
const Home = () => import("./views/Home.svelte");
const AddServer = () => import("./views/AddServer.svelte");
const Home = () => import("~/views/Home.svelte");
const AddServer = () => import("~/views/AddServer.svelte");
const Settings = () => import("~/views/Settings.svelte");
let insideElectron = window?.WorkAdventureDesktopApi?.desktop;
</script>
@@ -17,6 +18,7 @@
<main class="flex flex-grow">
<LazyRoute path="/" component={Home} delayMs={500}>Loading ...</LazyRoute>
<LazyRoute path="/server/add" component={AddServer} delayMs={500}>Loading ...</LazyRoute>
<LazyRoute path="/settings" component={Settings} delayMs={500}>Loading ...</LazyRoute>
<Route>
<h3>404</h3>
<p>No Route could be matched.</p>
@@ -28,9 +30,12 @@
{/if}
<style>
@import "@fontsource/press-start-2p/index.css";
@import "@16bits/nes.css/css/nes.min.css";
:root {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
"Helvetica Neue", sans-serif;
font-family: "Press Start 2P", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell,
"Open Sans", "Helvetica Neue", sans-serif;
}
main {
@@ -0,0 +1,3 @@
# NES.icons
Source: https://github.com/nostalgic-css/NES.icons/
@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8" ?>
<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<rect x="7" y="0" width="1" height="1" fill="#000000" />
<rect x="8" y="0" width="1" height="1" fill="#000000" />
<rect x="2" y="1" width="1" height="1" fill="#000000" />
<rect x="7" y="1" width="1" height="1" fill="#000000" />
<rect x="8" y="1" width="1" height="1" fill="#000000" />
<rect x="13" y="1" width="1" height="1" fill="#000000" />
<rect x="1" y="2" width="1" height="1" fill="#000000" />
<rect x="2" y="2" width="1" height="1" fill="#000000" />
<rect x="3" y="2" width="1" height="1" fill="#000000" />
<rect x="5" y="2" width="1" height="1" fill="#000000" />
<rect x="6" y="2" width="1" height="1" fill="#000000" />
<rect x="7" y="2" width="1" height="1" fill="#000000" />
<rect x="8" y="2" width="1" height="1" fill="#000000" />
<rect x="9" y="2" width="1" height="1" fill="#000000" />
<rect x="10" y="2" width="1" height="1" fill="#000000" />
<rect x="12" y="2" width="1" height="1" fill="#000000" />
<rect x="13" y="2" width="1" height="1" fill="#000000" />
<rect x="14" y="2" width="1" height="1" fill="#000000" />
<rect x="2" y="3" width="1" height="1" fill="#000000" />
<rect x="3" y="3" width="1" height="1" fill="#000000" />
<rect x="4" y="3" width="1" height="1" fill="#000000" />
<rect x="5" y="3" width="1" height="1" fill="#000000" />
<rect x="6" y="3" width="1" height="1" fill="#000000" />
<rect x="7" y="3" width="1" height="1" fill="#000000" />
<rect x="8" y="3" width="1" height="1" fill="#000000" />
<rect x="9" y="3" width="1" height="1" fill="#000000" />
<rect x="10" y="3" width="1" height="1" fill="#000000" />
<rect x="11" y="3" width="1" height="1" fill="#000000" />
<rect x="12" y="3" width="1" height="1" fill="#000000" />
<rect x="13" y="3" width="1" height="1" fill="#000000" />
<rect x="3" y="4" width="1" height="1" fill="#000000" />
<rect x="4" y="4" width="1" height="1" fill="#000000" />
<rect x="11" y="4" width="1" height="1" fill="#000000" />
<rect x="12" y="4" width="1" height="1" fill="#000000" />
<rect x="2" y="5" width="1" height="1" fill="#000000" />
<rect x="3" y="5" width="1" height="1" fill="#000000" />
<rect x="12" y="5" width="1" height="1" fill="#000000" />
<rect x="13" y="5" width="1" height="1" fill="#000000" />
<rect x="2" y="6" width="1" height="1" fill="#000000" />
<rect x="3" y="6" width="1" height="1" fill="#000000" />
<rect x="12" y="6" width="1" height="1" fill="#000000" />
<rect x="13" y="6" width="1" height="1" fill="#000000" />
<rect x="0" y="7" width="1" height="1" fill="#000000" />
<rect x="1" y="7" width="1" height="1" fill="#000000" />
<rect x="2" y="7" width="1" height="1" fill="#000000" />
<rect x="3" y="7" width="1" height="1" fill="#000000" />
<rect x="12" y="7" width="1" height="1" fill="#000000" />
<rect x="13" y="7" width="1" height="1" fill="#000000" />
<rect x="14" y="7" width="1" height="1" fill="#000000" />
<rect x="15" y="7" width="1" height="1" fill="#000000" />
<rect x="0" y="8" width="1" height="1" fill="#000000" />
<rect x="1" y="8" width="1" height="1" fill="#000000" />
<rect x="2" y="8" width="1" height="1" fill="#000000" />
<rect x="3" y="8" width="1" height="1" fill="#000000" />
<rect x="12" y="8" width="1" height="1" fill="#000000" />
<rect x="13" y="8" width="1" height="1" fill="#000000" />
<rect x="14" y="8" width="1" height="1" fill="#000000" />
<rect x="15" y="8" width="1" height="1" fill="#000000" />
<rect x="2" y="9" width="1" height="1" fill="#000000" />
<rect x="3" y="9" width="1" height="1" fill="#000000" />
<rect x="12" y="9" width="1" height="1" fill="#000000" />
<rect x="13" y="9" width="1" height="1" fill="#000000" />
<rect x="2" y="10" width="1" height="1" fill="#000000" />
<rect x="3" y="10" width="1" height="1" fill="#000000" />
<rect x="12" y="10" width="1" height="1" fill="#000000" />
<rect x="13" y="10" width="1" height="1" fill="#000000" />
<rect x="3" y="11" width="1" height="1" fill="#000000" />
<rect x="4" y="11" width="1" height="1" fill="#000000" />
<rect x="11" y="11" width="1" height="1" fill="#000000" />
<rect x="12" y="11" width="1" height="1" fill="#000000" />
<rect x="2" y="12" width="1" height="1" fill="#000000" />
<rect x="3" y="12" width="1" height="1" fill="#000000" />
<rect x="4" y="12" width="1" height="1" fill="#000000" />
<rect x="5" y="12" width="1" height="1" fill="#000000" />
<rect x="6" y="12" width="1" height="1" fill="#000000" />
<rect x="7" y="12" width="1" height="1" fill="#000000" />
<rect x="8" y="12" width="1" height="1" fill="#000000" />
<rect x="9" y="12" width="1" height="1" fill="#000000" />
<rect x="10" y="12" width="1" height="1" fill="#000000" />
<rect x="11" y="12" width="1" height="1" fill="#000000" />
<rect x="12" y="12" width="1" height="1" fill="#000000" />
<rect x="13" y="12" width="1" height="1" fill="#000000" />
<rect x="1" y="13" width="1" height="1" fill="#000000" />
<rect x="2" y="13" width="1" height="1" fill="#000000" />
<rect x="3" y="13" width="1" height="1" fill="#000000" />
<rect x="5" y="13" width="1" height="1" fill="#000000" />
<rect x="6" y="13" width="1" height="1" fill="#000000" />
<rect x="7" y="13" width="1" height="1" fill="#000000" />
<rect x="8" y="13" width="1" height="1" fill="#000000" />
<rect x="9" y="13" width="1" height="1" fill="#000000" />
<rect x="10" y="13" width="1" height="1" fill="#000000" />
<rect x="12" y="13" width="1" height="1" fill="#000000" />
<rect x="13" y="13" width="1" height="1" fill="#000000" />
<rect x="14" y="13" width="1" height="1" fill="#000000" />
<rect x="2" y="14" width="1" height="1" fill="#000000" />
<rect x="7" y="14" width="1" height="1" fill="#000000" />
<rect x="8" y="14" width="1" height="1" fill="#000000" />
<rect x="13" y="14" width="1" height="1" fill="#000000" />
<rect x="7" y="15" width="1" height="1" fill="#000000" />
<rect x="8" y="15" width="1" height="1" fill="#000000" />
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

@@ -0,0 +1,16 @@
<script lang="ts">
export let title: string;
export let id: string;
export let description: string = "";
</script>
<div class="mb-6">
<label class="block text-gray-200 text-lg font-bold mb-1" for={id}>
{title}
</label>
<slot />
<!-- <input class="shadow appearance-none border border-red-500 rounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline" id="password" type="password" placeholder="******************"> -->
{#if description.length > 0}
<p class="text-gray-200 text-xs mt-1 italic">{description}</p>
{/if}
</div>
+178
View File
@@ -0,0 +1,178 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
export let id: string;
export let value: string = "";
const dispatch = createEventDispatcher<{
change: string;
}>();
// https://www.electronjs.org/de/docs/latest/api/accelerator
function keyCodeToElectron(key: string): string {
if (key.match(/^Key[A-Z]/)) {
return key.replace(/^Key/, "").toLocaleUpperCase();
}
if (key.match(/^Digit[0-9]/)) {
return key.replace(/^Digit/, "").toLowerCase();
}
if (key.match(/^Numpad[0-9]/)) {
return key.replace(/^Numpad/, "num").toLowerCase();
}
switch (key) {
// Modifiers
case "ControlLeft":
return "CmdOrCtrl";
case "ControlRight":
return "CmdOrCtrl";
case "AltLeft":
return "Alt";
case "AltRight":
return "AltGr";
case "ScrollLock":
return "Scrolllock";
case "ShiftLeft":
return "Shift";
case "ShiftRight":
return "Shift";
// Specialchars
case "Period":
return ".";
case "Comma":
return ",";
case "Slash":
return "/";
case "Backslash":
return "\\";
case "Minus":
return "-";
case "Equal":
return "=";
case "BracketLeft":
return "[";
case "BracketRight":
return "]";
case "Quote":
return "'";
case "Semicolon":
return ";";
case "IntlBackslash":
return "\\";
case "Backquote":
return "`";
// Numpad
case "NumpadDecimal":
return "numdec";
case "NumpadAdd":
return "numadd";
case "NumpadSubtract":
return "numsub";
case "NumpadMultiply":
return "nummult";
case "NumpadDivide":
return "numdiv";
default:
return key;
}
}
let shortCut: string[] = [];
let recording = false;
let recordingTimeout: NodeJS.Timeout;
let keyInputTimeout: NodeJS.Timeout;
function camelPad(str: string) {
return (
str
// Look for long acronyms and filter out the last letter
.replace(/([A-Z]+)([A-Z][a-z])/g, " $1 $2")
// Look for lower-case letters followed by upper-case letters
.replace(/([a-z\d])([A-Z])/g, "$1 $2")
// Look for lower-case letters followed by numbers
// .replace(/([a-zA-Z])(\d)/g, "$1 $2")
.replace(/^./, (str) => str.toUpperCase())
// Remove any white space left around the word
.trim()
);
}
function resetRecording() {
recording = false;
shortCut = [];
value = "";
}
function stopRecording() {
clearTimeout(recordingTimeout);
recording = false;
value = shortCut.map(keyCodeToElectron).join(" + ");
dispatch("change", value);
}
function startRecording() {
if (recording) {
return;
}
recording = true;
value = "";
shortCut = [];
recordingTimeout = setTimeout(() => {
stopRecording();
}, 1000 * 5);
}
function keyUp(event: KeyboardEvent) {
if (!recording) {
return;
}
shortCut = [...shortCut, event.code];
if (!keyInputTimeout) {
keyInputTimeout = setTimeout(() => {
stopRecording();
keyInputTimeout = undefined;
}, 300);
}
}
</script>
<div
class={`flex items-center w-full h-8 border-1 rounded-md overflow-hidden text-gray-200 text-xs appearance-none focus:outline-none ${
recording ? "border-red-500" : "border-gray-400"
}`}
on:keyup={keyUp}
on:click={startRecording}
tabindex="0"
>
<input
{id}
type="text"
class="flex-grow h-full border-none mx-2 bg-transparent appearance-none focus:outline-none"
disabled
{value}
/>
{#if value.length > 0}
<span
class="flex items-center justify-center w-4 h-4 p-2 mr-1 rounded-full cursor-pointer bg-gray-500 hover:bg-gray-400"
on:click|stopPropagation={resetRecording}>x</span
>
{/if}
<div
class={`flex h-6 items-center px-2 m-0.5 rounded-sm w-28 justify-center cursor-pointer ${
recording ? "bg-red-500" : "hover:bg-gray-400"
}`}
on:click={recording ? stopRecording : startRecording}
>
{#if recording}
<span>recording</span>
{:else}
<span>record</span>
{/if}
</div>
</div>
+25 -25
View File
@@ -1,35 +1,35 @@
<script>
import { onMount } from "svelte";
import { onMount } from "svelte";
export let component;
export let delayMs = null;
export let component;
export let delayMs = null;
let loadedComponent = null;
let timeout;
let showFallback = !delayMs;
let loadedComponent = null;
let timeout;
let showFallback = !delayMs;
let props;
$: {
// eslint-disable-next-line no-shadow
const { component, delayMs, ...restProps } = $$props;
props = restProps;
}
let props;
$: {
// eslint-disable-next-line no-shadow
const { component, delayMs, ...restProps } = $$props;
props = restProps;
}
onMount(() => {
if (delayMs) {
timeout = setTimeout(() => {
showFallback = true;
}, delayMs);
}
component().then(module => {
loadedComponent = module.default;
});
return () => clearTimeout(timeout);
});
onMount(() => {
if (delayMs) {
timeout = setTimeout(() => {
showFallback = true;
}, delayMs);
}
component().then((module) => {
loadedComponent = module.default;
});
return () => clearTimeout(timeout);
});
</script>
{#if loadedComponent}
<svelte:component this={loadedComponent} {...props} />
<svelte:component this={loadedComponent} {...props} />
{:else if showFallback}
<slot />
<slot />
{/if}
+14 -14
View File
@@ -1,20 +1,20 @@
<script>
import { Route } from "svelte-navigator";
import Lazy from "./Lazy.svelte";
import { Route } from "svelte-navigator";
import Lazy from "~/lib/Lazy.svelte";
export let component;
export let delayMs = null;
export let component;
export let delayMs = null;
let props;
$: {
// eslint-disable-next-line no-shadow
const { component, ...restProps } = $$props;
props = restProps;
}
let props;
$: {
// eslint-disable-next-line no-shadow
const { component, ...restProps } = $$props;
props = restProps;
}
</script>
<Route {...props}>
<Lazy {component} {delayMs}>
<slot />
</Lazy>
</Route>
<Lazy {component} {delayMs}>
<slot />
</Lazy>
</Route>
+11 -12
View File
@@ -1,18 +1,17 @@
<script>
import { navigate } from "svelte-navigator";
import { navigate } from "svelte-navigator";
let to = '/';
let clazz = '';
let to = "/";
let clazz = "";
export { clazz as class, to };
export { clazz as class, to };
async function click() {
await window?.WorkAdventureDesktopApi?.showLocalApp();
navigate(to);
}
async function click() {
await window?.WorkAdventureDesktopApi?.showLocalApp();
navigate(to);
}
</script>
<div on:click="{ click }" class="{`${clazz}`}">
<slot />
</div>
<div on:click={click} class={`${clazz}`}>
<slot />
</div>
+35 -14
View File
@@ -1,16 +1,29 @@
<script lang="ts">
import { onMount } from "svelte";
import Link from "./Link.svelte";
import { servers, selectedServer, selectServer, loadServers } from "../store";
import Link from "~/lib/Link.svelte";
import { servers, selectedServer, selectServer, loadServers, Server } from "../store";
import CogIcon from "~/assets/nes.icons/cog.svg";
let isDevelopment = false;
function getServerColor(i: number) {
const serverColors = ['bg-red-400', 'bg-yellow-500', 'bg-green-500', 'bg-blue-500', 'bg-indigo-500', 'bg-purple-500'];
const serverColors = [
"bg-red-400",
"bg-yellow-500",
"bg-green-500",
"bg-blue-500",
"bg-indigo-500",
"bg-purple-500",
];
return serverColors[i % serverColors.length];
}
selectedServer.subscribe((e) => {
console.log("selected server changed", e);
});
onMount(async () => {
await loadServers();
isDevelopment = await window?.WorkAdventureDesktopApi?.isDevelopment();
@@ -20,29 +33,37 @@
<aside class="flex flex-col bg-gray-700 items-center">
<div class="flex flex-col mt-4 space-y-4 overflow-y-auto pb-4">
{#each $servers as server, i}
<div class="flex flex-col items-center justify-center text-gray-400">
<div class="flex flex-col items-center justify-center ">
<div
class={`w-12 h-12 rounded-lg flex cursor-pointer text-center items-center justify-center text-light-50 ${getServerColor(i)} ${
$selectedServer === server._id ? "" : ""
}`}
class={`w-16 h-16 p-1 rounded-md flex cursor-pointer text-light-50 border-4 border-transparent text-gray-200 hover:text-gray-500`}
class:border-gray-400={$selectedServer === server._id}
on:click={() => selectServer(server)}
>
{server.name.slice(0, 2).toLocaleUpperCase()}
<div class={`flex w-full h-full text-center items-center justify-center rounded-md ${getServerColor(i)}`}>
{server.name.slice(0,2).toLocaleUpperCase()}
</div>
</div>
</div>
{/each}
<Link
to="/server/add"
class="flex justify-center items-center text-4xl no-underline text-gray-400 cursor-pointer">+</Link
>
</div>
<Link
to="/server/add"
class="flex justify-center items-center text-4xl no-underline text-gray-200 cursor-pointer hover:text-gray-500"
>+</Link
>
<Link
to="/settings"
class="flex mt-auto justify-center items-center text-4xl no-underline cursor-pointer"
>
<CogIcon width="30" height="30" class="fill-gray-200 hover:fill-gray-500" />
</Link>
{#if isDevelopment}
<button class="mt-auto" on:click={() => location.reload()}>Refresh</button>
<button class="text-8px text-red-500 mt-8 mb-4" on:click={() => location.reload()}>Refresh</button>
{/if}
</aside>
<style>
aside {
width: 70px;
width: 80px;
}
</style>
@@ -0,0 +1,27 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
export let id: string;
export let value: string = "";
export let required: boolean = false;
const dispatch = createEventDispatcher<{
change: string;
}>();
</script>
<div
class={`flex items-center w-full h-10 border-1 rounded-md overflow-hidden text-gray-200 text-md appearance-none focus:outline-none`}
>
<input
{id}
type="text"
class="flex-grow h-full border-none mx-2 bg-transparent appearance-none focus:outline-none"
{value}
{required}
on:change={(e) => {
value = e.target.value;
dispatch("change", { value });
}}
/>
</div>
@@ -0,0 +1,25 @@
<script lang="ts">
export let id: string;
export let value: boolean;
export let title: string = null;
</script>
<div class="flex w-full my-2">
<label for={id} class="flex items-center cursor-pointer">
<div class="relative">
<input {id} type="checkbox" class="sr-only" checked={value} />
<div class="w-10 h-4 bg-gray-400 rounded-full shadow-inner" />
<div class="dot absolute w-6 h-6 bg-gray-500 rounded-full shadow -left-1 -top-1 transition" />
</div>
{#if title}
<div class="ml-4 text-gray-200 text-sm">{title}</div>
{/if}
</label>
</div>
<style>
input:checked ~ .dot {
transform: translateX(100%);
background-color: #0369a1;
}
</style>
+7 -3
View File
@@ -1,6 +1,6 @@
import { writable, get } from "svelte/store";
type Server = {
export type Server = {
_id: string;
name: string;
url: string;
@@ -11,15 +11,19 @@ export const newServer = writable<Omit<Server, "_id">>({
url: "",
});
export const servers = writable<Server[]>([]);
export const selectedServer = writable<string | undefined>(undefined);
export const selectedServer = writable<string | undefined>("");
export async function selectServer(server: Server) {
await window.WorkAdventureDesktopApi.selectServer(server._id);
selectedServer.set(server._id);
}
export async function addServer(event: Event) {
export async function addServer() {
const addedServer = await window?.WorkAdventureDesktopApi?.addServer(get(newServer));
if (!addedServer?._id) {
console.log(addedServer);
throw new Error(addedServer);
}
newServer.set({ name: "", url: "" });
servers.update((s) => [...s, addedServer]);
await selectServer(addedServer);
+4
View File
@@ -0,0 +1,4 @@
declare module "*.svg" {
const content: string;
export default content;
}
+31 -7
View File
@@ -1,12 +1,36 @@
<script lang="ts">
import { newServer, addServer } from '../store';
import InputField from "~/lib/InputField.svelte";
import TextInput from "~/lib/TextInput.svelte";
import { newServer, addServer } from "~/store";
let error = "";
async function _addServer() {
try {
await addServer();
} catch(e) {
console.log(e);
error = e.message;
}
}
</script>
<div class="flex w-full h-full justify-center items-center">
<form class="flex flex-col justify-center space-y-2" on:submit|preventDefault={addServer}>
<input type="text" class="w-full h-12 px-4 py-2 bg-gray-200 rounded-lg" placeholder="Name" required bind:value={$newServer.name}>
<input type="text" class="w-full h-12 px-4 py-2 bg-gray-200 rounded-lg" placeholder="Url" required bind:value={$newServer.url}>
<input type="submit" value="Add server" />
</form>
<form class="flex flex-col justify-center" on:submit|preventDefault={_addServer}>
<!-- <input type="text" class="w-full h-12 px-4 py-2 bg-gray-200 rounded-lg" placeholder="Url" required > -->
<InputField title="Name" id="name">
<TextInput bind:value={$newServer.name} required id="name" />
</InputField>
<InputField title="Url" id="url">
<TextInput bind:value={$newServer.url} required id="url" />
</InputField>
{#if error}
<div class="text-red-500 text-center mb-2">{error}</div>
{/if}
<input
type="submit"
value="Add server"
class="mt-4 rounded-md p-2 bg-gray-300 cursor-pointer hover:bg-gray-400"
/>
</form>
</div>
+14 -3
View File
@@ -1,7 +1,18 @@
<script lang="ts">
import logo from "../../../assets/icons/logo-text.png";
import { onMount } from "svelte";
import Logo from "~/../../assets/icons/logo.svg";
let version = "";
onMount(async () => {
version = await window?.WorkAdventureDesktopApi?.getVersion();
});
</script>
<div class="flex w-full h-full justify-center items-center">
<img src={logo} alt="WorkAdeventure logo" />
<div class="flex flex-col w-full h-full justify-center items-center">
<Logo height="100" class="my-auto" />
<div class="flex my-4 items-center space-x-4">
<span class="text-gray-300 text-lg ">Desktop-App Version: {version}</span>
</div>
</div>
@@ -0,0 +1,59 @@
<script lang="ts">
import { onMount } from "svelte";
import { writable } from "svelte/store";
import ToggleSwitch from "~/lib/ToggleSwitch.svelte";
import InputField from "~/lib/InputField.svelte";
import KeyRecord from "~/lib/KeyRecord.svelte";
const shortCuts = writable<Record<string, string> | undefined>({});
onMount(async () => {
shortCuts.set(await window?.WorkAdventureDesktopApi?.getShortcuts());
});
async function saveShortcut(key: string, value: string) {
await window?.WorkAdventureDesktopApi?.saveShortcut(key, value);
}
</script>
<div class="flex flex-col w-full h-full justify-center items-center">
<h1 class="text-gray-200 text-2xl mb-6">Settings</h1>
<div class="flex flex-col justify-start max-w-152">
{#if $shortCuts}
<InputField
id="toggle-camera"
title="Toggle Mute"
description="Set a shortcut to turn your microphone on and off"
>
<KeyRecord
id="toggle-mute"
value={$shortCuts.mute_toggle}
on:change={(e) => saveShortcut("mute_toggle", e.detail)}
/>
</InputField>
<InputField
id="toggle-camera"
title="Toggle Camera"
description="Set a shortcut to turn your camera on and off"
>
<KeyRecord
id="toggle-camera"
value={$shortCuts.camera_toggle}
on:change={(e) => saveShortcut("camera_toggle", e.detail)}
/>
</InputField>
{/if}
<InputField id="toggle-autostart" title="Toggle autostart">
<ToggleSwitch
id="toggle-autostart"
value={true}
title="Autostart WorkAdventure after your PC started"
on:change={(e) => {}}
/>
</InputField>
</div>
</div>