aboutsummaryrefslogtreecommitdiff
path: root/src_frontend/Components/ModeList
diff options
context:
space:
mode:
Diffstat (limited to 'src_frontend/Components/ModeList')
-rw-r--r--src_frontend/Components/ModeList/Mode.svelte57
-rw-r--r--src_frontend/Components/ModeList/ModeList.svelte64
-rw-r--r--src_frontend/Components/ModeList/NewModeDialog.svelte153
3 files changed, 274 insertions, 0 deletions
diff --git a/src_frontend/Components/ModeList/Mode.svelte b/src_frontend/Components/ModeList/Mode.svelte
new file mode 100644
index 0000000..67752c2
--- /dev/null
+++ b/src_frontend/Components/ModeList/Mode.svelte
@@ -0,0 +1,57 @@
+<script>
+ import { push } from "svelte-spa-router";
+ import ConfirmActionDialog from "../Dialogs/ConfirmActionDialog.svelte";
+ import { authorizedSocket } from "../../stores/socketStore.js";
+ import { notif } from "../../stores/notifs";
+ export let id;
+
+ function deleteMode() {
+ authorizedSocket.emit("mode:delete", `user/${id}`, (res) => {
+ if (!res.success) {
+ notif({title: "Error", text: "Could not delete mode...", type: "danger"})
+ console.log(res);
+ }
+ });
+ }
+</script>
+
+<style>
+ .wrapper {
+ width: 100%;
+ padding: var(--theme-padding);
+ box-sizing: border-box;
+ border-radius: 15px;
+
+ display: flex;
+ align-items: center;
+ }
+ .right {
+ margin-left: auto;
+ }
+ button {
+ border: none;
+ background-color: white;
+ background-color: transparent;
+ border: none;
+ padding: 10px;
+ border-radius: 15px;
+ }
+ button:hover {
+ background-color: var(--grey-300);
+ }
+ button:active {
+ background-color: var(--grey-400);
+ }
+</style>
+
+<div class="wrapper drop-shadow">
+ {id}
+ <div class="right">
+ <ConfirmActionDialog title="Are you sure?" text="Are you sure you want to delete {id}" action={deleteMode}>
+ <svelte:fragment slot="trigger" let:open>
+ <button on:click={open}><i class="fas fa-trash"></i></button>
+ </svelte:fragment>
+ </ConfirmActionDialog>
+ <button on:click={() => {push(`/editor/${id}`)}}><i class="fas fa-edit"></i></button>
+ </div>
+</div> \ No newline at end of file
diff --git a/src_frontend/Components/ModeList/ModeList.svelte b/src_frontend/Components/ModeList/ModeList.svelte
new file mode 100644
index 0000000..8bac3f9
--- /dev/null
+++ b/src_frontend/Components/ModeList/ModeList.svelte
@@ -0,0 +1,64 @@
+<script>
+ import { onMount } from "svelte";
+ import { fade } from 'svelte/transition';
+ import FloatingButton from "../../ComponentLib/Button/FloatingButton.svelte";
+ import Mode from "./Mode.svelte";
+ import NewModeDialog from "./NewModeDialog.svelte";
+
+ import { openSocket, authorizedSocket, authorizedSocketNeeded } from "../../stores/socketStore.js";
+ authorizedSocketNeeded.set(true);
+
+ let userModes = [];
+ let remotes = [];
+
+ openSocket.on("modelist", (modes) => {
+ userModes = [];
+ remotes = [];
+ for (let i = 0; i < modes.length; i++) {
+ if (modes[i].substr(0, 4) === "user") {
+ userModes.push(modes[i].replace("user/", ""));
+ }
+ if (modes[i].substr(0, 6) === "remote") {
+ remotes.push(modes[i].replace("remote/", ""));
+ }
+ }
+ });
+ onMount(async() => {
+ openSocket.emit("modelist:get");
+ });
+</script>
+
+<style>
+ .wrapper {
+ padding-bottom: var(--theme-padding);
+ }
+ .modes > * {
+ margin-bottom: 10px;
+ }
+ .button_menu {
+ margin-top: 20px;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+</style>
+
+<div class="wrapper">
+ <h1>Modes</h1>
+ <div class="modes">
+ {#each userModes as mode}
+ <div>
+ <Mode id={mode} />
+ </div>
+ {/each}
+ </div>
+
+ <div class="button_menu">
+ <NewModeDialog>
+ <svelte:fragment slot="trigger" let:open>
+ <FloatingButton on:click={open} faIcon="fas fa-plus" label="NEW" />
+ </svelte:fragment>
+ </NewModeDialog>
+ </div>
+</div> \ No newline at end of file
diff --git a/src_frontend/Components/ModeList/NewModeDialog.svelte b/src_frontend/Components/ModeList/NewModeDialog.svelte
new file mode 100644
index 0000000..539e3ef
--- /dev/null
+++ b/src_frontend/Components/ModeList/NewModeDialog.svelte
@@ -0,0 +1,153 @@
+<script>
+ import { onMount } from "svelte";
+ import dialogPolyfill from 'dialog-polyfill'
+ import Button from "../../ComponentLib/Button/Button.svelte";
+ import PrettyVar from "../../ComponentLib/PrettyVar.svelte";
+ import { openSocket, authorizedSocket } from "../../stores/socketStore.js";
+ import { notif } from "../../stores/notifs";
+
+ let modal;
+ let activeTab = 0;
+ let name;
+ let sourceMode;
+
+ function open() {
+ modal.showModal()
+ }
+ function register(node) {
+ dialogPolyfill.registerDialog(node);
+ }
+ function createMode() {
+ let template = "template/base";
+ if (activeTab == 1) {
+ template = sourceMode;
+ }
+ authorizedSocket.emit("mode:create", name, template, (res) => {
+ if (!res.success) {
+ notif({title: "Error", text: "Could not create mode...", type: "danger"})
+ };
+
+ modal.close();
+ });
+ }
+
+ let builtinModes = [];
+ let userModes = [];
+ // let remoteModes = [];
+ openSocket.on("modelist", (modes) => {
+ builtinModes = [];
+ for (let i = 0; i < modes.length; i++) {
+ if (modes[i].substr(0, 8) === "builtin/") {
+ builtinModes.push([modes[i], modes[i].replace("builtin/", "")]);
+ }
+ if (modes[i].substr(0, 5) === "user/") {
+ userModes.push([modes[i], modes[i].replace("user/", "")]);
+ }
+ // if (modes[i].substr(0, 6) === "remote") {
+ // remotes.push(modes[i].replace("", ""));
+ // }
+ }
+ });
+ onMount(async() => {
+ openSocket.emit("modelist:get");
+ })
+</script>
+
+<style>
+ dialog {
+ padding: 0;
+ border: none;
+ border-radius: 15px;
+ }
+ .tabs {
+ display: flex;
+ width: 100%;
+ }
+ .tabs i {
+ position: relative;
+ flex-grow: 1;
+ text-align: center;
+ font-size: 20px;
+ padding: 15px;
+ }
+ .tabs i:hover {
+ color: var(--theme-primary);
+ }
+ .tabs i.active {
+ color: var(--theme-primary);
+ }
+ .tabs > *:not(:last-child):after {
+ content: "";
+ position: absolute;
+ width: 1px;
+ height: 43%;
+ border-left: 0.1px solid var(--grey-400);
+ left: 100%;
+ }
+ .divider-h {
+ margin-left: 15px;
+ margin-right: 15px;
+ border-top: 0.01px solid var(--grey-400);
+ }
+ .content {
+ padding: 15px;
+ box-sizing: border-box;
+ }
+ input, select {
+ display: block;
+ width: 100%;
+ box-sizing: border-box;
+ }
+ .buttons {
+ padding: 0 15px 15px 15px;
+ display: flex;
+ }
+ .buttons > * {
+ flex-grow: 1;
+ }
+ .buttons > *:not(:last-child) {
+ margin-right: 5px;
+ }
+ .buttons > *:not(:first-child) {
+ margin-left: 5px;
+ }
+</style>
+
+<slot name="trigger" {open}></slot>
+<dialog bind:this={modal} use:register>
+
+ <div class="tabs">
+ <i class:active={activeTab == 0} on:click={() => { activeTab = 0; }} class="far fa-file"></i>
+ <i class:active={activeTab == 1} on:click={() => { activeTab = 1; }} class="far fa-clone"></i>
+ </div>
+
+ <div class="divider-h"></div>
+ <div class="content">
+ {#if [0, 1].includes(activeTab)}
+ <div>
+ <label for="fname">Mode name</label>
+ <input type="text" id="fname" placeholder="My_Awesome_New_Mode" bind:value={name} />
+ {#if activeTab == 1}
+ <label for="sourcemode">Source</label>
+ <select bind:value={sourceMode}>
+ <optgroup label="builtin">
+ {#each builtinModes as mode}
+ <option value={mode[0]}><PrettyVar varText={mode[1]} /></option>
+ {/each}
+ </optgroup>
+ <optgroup label="user">
+ {#each userModes as mode}
+ <option value={mode[0]}><PrettyVar varText={mode[1]} /></option>
+ {/each}
+ </optgroup>
+ </select>
+ {/if}
+ </div>
+ {/if}
+ </div>
+ <div class="buttons">
+ <div><Button fullWidth=true on:click={() => modal.close() } color={"var(--theme-primary)"} backgroundColor={"white"}>Cancel</Button></div>
+ <div><Button fullWidth=true on:click={createMode}>Create</Button></div>
+ </div>
+
+</dialog> \ No newline at end of file