From 3a33f82220ae089351f141b38cdeeb549d024b4e Mon Sep 17 00:00:00 2001 From: Fritz Heiden Date: Mon, 7 Apr 2025 15:44:06 +0200 Subject: [PATCH] feat: add create remote modal --- www/src/data/serializer.js | 12 +++ www/src/modals/create-command-modal.jsx | 2 +- www/src/modals/create-device-modal.jsx | 2 +- www/src/modals/create-remote-modal.jsx | 92 +++++++++++++++++++++ www/src/modals/create-user-modal.jsx | 2 +- www/src/modals/delete-integration-modal.jsx | 11 +-- www/src/modals/delete-user-modal.jsx | 2 +- www/src/modals/modal-registry.jsx | 8 +- www/src/modals/user-settings-modal.jsx | 2 +- www/src/services/remotes-service.js | 12 ++- www/src/views/remotes/remotes-list-view.jsx | 11 ++- 11 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 www/src/modals/create-remote-modal.jsx diff --git a/www/src/data/serializer.js b/www/src/data/serializer.js index 4c6445d..28f1dcf 100644 --- a/www/src/data/serializer.js +++ b/www/src/data/serializer.js @@ -2,6 +2,7 @@ import PlaybackDevice from "./playback-device.js"; import User from "./user.js"; import Integration from "./integration.js"; import Command from "./command.js"; +import Remote from "./remote.js"; const Serializer = (function () { function deserializeUser(object) { @@ -39,6 +40,15 @@ const Serializer = (function () { if (!objects) return []; return objects.map((object) => deserializeCommand(object)); } + + function deserializeRemote(object) { + return new Remote(object); + } + + function deserializeRemotes(objects) { + if (!objects) return []; + return objects.map((object) => deserializeRemote(object)); + } return { deserializeUser, @@ -49,6 +59,8 @@ const Serializer = (function () { deserializeIntegrations, deserializeCommand, deserializeCommands, + deserializeRemote, + deserializeRemotes, }; })(); diff --git a/www/src/modals/create-command-modal.jsx b/www/src/modals/create-command-modal.jsx index 3351108..548a8f0 100644 --- a/www/src/modals/create-command-modal.jsx +++ b/www/src/modals/create-command-modal.jsx @@ -1,5 +1,5 @@ import { createEffect, createMemo, createSignal } from "solid-js"; -import ValidatedTextInput from "../modules/validated-text-input.jsx"; +import ValidatedTextInput from "../components/validated-text-input.jsx"; import EventEmitter from "../tools/event-emitter.js"; import ModalHandler from "./modal-handler.js"; import Modal from "./modal.jsx"; diff --git a/www/src/modals/create-device-modal.jsx b/www/src/modals/create-device-modal.jsx index 713859f..4b54910 100644 --- a/www/src/modals/create-device-modal.jsx +++ b/www/src/modals/create-device-modal.jsx @@ -1,7 +1,7 @@ import { createEffect, createSignal } from "solid-js"; import Modal from "./modal.jsx"; import EventEmitter from "../tools/event-emitter.js"; -import ValidatedTextInput from "../modules/validated-text-input.jsx"; +import ValidatedTextInput from "../components/validated-text-input.jsx"; import ModalHandler from "./modal-handler.js"; import DeviceService from "../services/device-service.js"; diff --git a/www/src/modals/create-remote-modal.jsx b/www/src/modals/create-remote-modal.jsx new file mode 100644 index 0000000..351ef9a --- /dev/null +++ b/www/src/modals/create-remote-modal.jsx @@ -0,0 +1,92 @@ +import { createMemo, createSignal } from "solid-js"; +import ValidatedTextInput from "../components/validated-text-input.jsx"; +import RemotesService from "../services/remotes-service.js"; +import EventEmitter from "../tools/event-emitter.js"; +import ModalHandler from "./modal-handler.js"; +import Modal from "./modal.jsx"; + +const eventEmitter = new EventEmitter(); +const REMOTE_CREATED_EVENT = "success"; +const MIN_TITLE_LENGTH = 3; + +function CreateRemoteModal(props) { + const [title, setTitle] = createSignal(""); + const [commands, setCommands] = createSignal([]); + const [error, setError] = createSignal(""); + + const isTitleValid = createMemo(() => title().length >= MIN_TITLE_LENGTH); + + const isFormValid = createMemo(() => isTitleValid()); + + async function handleCreateRemote() { + let remote; + try { + remote = await RemotesService.createRemote({ + title: title(), + commands: commands(), + }); + } catch (e) { + setError(e.message); + return; + } + resetFields(); + CreateRemoteModal.Handler.hide(); + eventEmitter.dispatchEvent(REMOTE_CREATED_EVENT, remote); + } + + function resetFields() { + setTitle(""); + setCommands([]); + setError(""); + } + + return ( + + + + + + ); +} + +CreateRemoteModal.Handler = new ModalHandler(); +CreateRemoteModal.onRemoteCreated = (callback) => + eventEmitter.on(REMOTE_CREATED_EVENT, callback); + +export default CreateRemoteModal; diff --git a/www/src/modals/create-user-modal.jsx b/www/src/modals/create-user-modal.jsx index 7950455..e5dbc4a 100644 --- a/www/src/modals/create-user-modal.jsx +++ b/www/src/modals/create-user-modal.jsx @@ -2,7 +2,7 @@ import { createEffect, createSignal } from "solid-js"; import Modal from "./modal.jsx"; import UserService from "../services/user-service.js"; import EventEmitter from "../tools/event-emitter.js"; -import ValidatedTextInput from "../modules/validated-text-input.jsx"; +import ValidatedTextInput from "../components/validated-text-input.jsx"; import ModalHandler from "./modal-handler.js"; const [users, setUsers] = createSignal([]); diff --git a/www/src/modals/delete-integration-modal.jsx b/www/src/modals/delete-integration-modal.jsx index 645368c..45b0457 100644 --- a/www/src/modals/delete-integration-modal.jsx +++ b/www/src/modals/delete-integration-modal.jsx @@ -1,12 +1,9 @@ -import { createEffect, createSignal } from "solid-js"; -import Modal from "./modal.jsx"; -import UserService from "../services/user-service.js"; -import EventEmitter from "../tools/event-emitter.js"; -import User from "../data/user.js"; -import ValidatedTextInput from "../modules/validated-text-input.jsx"; -import ModalHandler from "./modal-handler.js"; +import { createSignal } from "solid-js"; import Integration from "../data/integration.js"; import DeviceService from "../services/device-service.js"; +import EventEmitter from "../tools/event-emitter.js"; +import ModalHandler from "./modal-handler.js"; +import Modal from "./modal.jsx"; const [integration, setIntegration] = createSignal(new Integration()); const eventEmitter = new EventEmitter(); diff --git a/www/src/modals/delete-user-modal.jsx b/www/src/modals/delete-user-modal.jsx index e787530..9484fe9 100644 --- a/www/src/modals/delete-user-modal.jsx +++ b/www/src/modals/delete-user-modal.jsx @@ -3,7 +3,7 @@ import Modal from "./modal.jsx"; import UserService from "../services/user-service.js"; import EventEmitter from "../tools/event-emitter.js"; import User from "../data/user.js"; -import ValidatedTextInput from "../modules/validated-text-input.jsx"; +import ValidatedTextInput from "../components/validated-text-input.jsx"; import ModalHandler from "./modal-handler.js"; const [user, setUser] = createSignal(new User()); diff --git a/www/src/modals/modal-registry.jsx b/www/src/modals/modal-registry.jsx index 0b38b0a..17bb4df 100644 --- a/www/src/modals/modal-registry.jsx +++ b/www/src/modals/modal-registry.jsx @@ -8,6 +8,7 @@ import ShowRegistrationCodeModal from "./show-registration-code-modal.jsx"; import DeleteIntegrationModal from "./delete-integration-modal.jsx"; import CreateCommandModal from "./create-command-modal.jsx"; import DeleteCommandModal from "./delete-command-modal.jsx"; +import CreateRemoteModal from "./create-remote-modal.jsx"; const ModalRegistry = (function () { const modals = [ @@ -50,7 +51,12 @@ const ModalRegistry = (function () { id: "deleteCommandModal", component: DeleteCommandModal, ref: null, - } + }, + { + id: "createRemoteModal", + component: CreateRemoteModal, + ref: null, + }, ]; function getModals(props) { diff --git a/www/src/modals/user-settings-modal.jsx b/www/src/modals/user-settings-modal.jsx index d833318..8b2131c 100644 --- a/www/src/modals/user-settings-modal.jsx +++ b/www/src/modals/user-settings-modal.jsx @@ -7,7 +7,7 @@ import { import EventEmitter from "../tools/event-emitter.js"; import User from "../data/user.js"; import Modal from "./modal.jsx"; -import ValidatedTextInput from "../modules/validated-text-input.jsx"; +import ValidatedTextInput from "../components/validated-text-input.jsx"; import ModalHandler from "./modal-handler.js"; import UserService from "../services/user-service.js"; diff --git a/www/src/services/remotes-service.js b/www/src/services/remotes-service.js index a8758b4..09702f3 100644 --- a/www/src/services/remotes-service.js +++ b/www/src/services/remotes-service.js @@ -2,9 +2,18 @@ import Serializer from "../data/serializer"; function RemotesService() { let commands = []; + let remotes = []; async function getRemotes() { - return []; + return [].concat(remotes); + } + + async function createRemote(remoteObject) { + let remote = Serializer.deserializeRemote(remoteObject); + let id = Math.random().toString(36).substr(2, 9); + remote.setId(id); + remotes.push(remote); + return remote; } async function getCommands() { @@ -28,6 +37,7 @@ function RemotesService() { return { getRemotes, + createRemote, getCommands, createCommand, deleteCommand, diff --git a/www/src/views/remotes/remotes-list-view.jsx b/www/src/views/remotes/remotes-list-view.jsx index 7046729..73a3264 100644 --- a/www/src/views/remotes/remotes-list-view.jsx +++ b/www/src/views/remotes/remotes-list-view.jsx @@ -1,6 +1,7 @@ import { createResource, onMount } from "solid-js"; import List from "../../components/list"; import RemotesService from "../../services/remotes-service"; +import CreateRemoteModal from "../../modals/create-remote-modal"; function RemotesList(props) { const [remotes, { refetch: refetchRemotes }] = createResource( @@ -11,7 +12,15 @@ function RemotesList(props) { refetchRemotes(); }); - function handleNewRemote() {} + CreateRemoteModal.onRemoteCreated(() => { + refetchRemotes(); + }); + + function handleNewRemote() { + CreateRemoteModal.Handler.show(); + } + + function handleDeleteRemote(remote) {} return ( <>