Add basic draggable item that saves to the server
This commit is contained in:
@@ -1,214 +1,105 @@
|
||||
let delayTimeout;
|
||||
let brightnessTimeout;
|
||||
let colorTimeout;
|
||||
let color2Timeout;
|
||||
let ws; // Variable to hold the WebSocket connection
|
||||
let connectionStatusElement; // Variable to hold the connection status element
|
||||
// Import the LightComponent from light-component.js
|
||||
import { LightComponent } from "./light-component.js";
|
||||
import { getWebSocket } from "./websocket.js";
|
||||
|
||||
// Function to update the connection status indicator
|
||||
function updateConnectionStatus(status) {
|
||||
if (!connectionStatusElement) {
|
||||
connectionStatusElement = document.getElementById("connection-status");
|
||||
}
|
||||
if (connectionStatusElement) {
|
||||
connectionStatusElement.className = ""; // Clear existing classes
|
||||
connectionStatusElement.classList.add(status);
|
||||
// Optionally, you could also update text content based on status
|
||||
// connectionStatusElement.textContent = status.charAt(0).toUpperCase() + status.slice(1);
|
||||
}
|
||||
}
|
||||
// Wait for the DOM to be fully loaded
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
// Select the container where the light-components will be added
|
||||
const appContainer = document.getElementById("app");
|
||||
|
||||
// Function to establish WebSocket connection
|
||||
function connectWebSocket() {
|
||||
// Determine the WebSocket URL based on the current location
|
||||
const wsUrl = `ws://${window.location.host}/ws`;
|
||||
ws = new WebSocket(wsUrl);
|
||||
|
||||
updateConnectionStatus("connecting"); // Indicate connecting state
|
||||
|
||||
ws.onopen = function (event) {
|
||||
console.log("WebSocket connection opened:", event);
|
||||
updateConnectionStatus("open"); // Indicate open state
|
||||
// Optionally, you could send an initial message here
|
||||
};
|
||||
|
||||
ws.onmessage = function (event) {
|
||||
console.log("WebSocket message received:", event.data);
|
||||
};
|
||||
|
||||
ws.onerror = function (event) {
|
||||
console.error("WebSocket error:", event);
|
||||
updateConnectionStatus("closed"); // Indicate error state (treat as closed)
|
||||
};
|
||||
|
||||
ws.onclose = function (event) {
|
||||
if (event.wasClean) {
|
||||
console.log(
|
||||
`WebSocket connection closed cleanly, code=${event.code}, reason=${event.reason}`,
|
||||
);
|
||||
updateConnectionStatus("closed"); // Indicate closed state
|
||||
} else {
|
||||
console.error("WebSocket connection died");
|
||||
updateConnectionStatus("closed"); // Indicate closed state
|
||||
}
|
||||
// Attempt to reconnect after a delay
|
||||
setTimeout(connectWebSocket, 1000);
|
||||
};
|
||||
}
|
||||
|
||||
// Function to send data over WebSocket
|
||||
function sendWebSocketData(data) {
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
console.log("Sending data over WebSocket:", data);
|
||||
ws.send(JSON.stringify(data));
|
||||
} else {
|
||||
console.error("WebSocket is not connected. Cannot send data:", data);
|
||||
// You might want to queue messages or handle this in a different way
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the post and get functions for now, they might still be useful
|
||||
async function post(path, data) {
|
||||
console.log(`POST to ${path}`, data);
|
||||
// Fetch the JSON data from the /light endpoint
|
||||
try {
|
||||
const response = await fetch(path, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
const response = await fetch("/light");
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error during POST request:", error);
|
||||
}
|
||||
}
|
||||
const lightData = await response.json();
|
||||
|
||||
async function get(path) {
|
||||
try {
|
||||
const response = await fetch(path);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
// Map to store backend IDs and their corresponding components
|
||||
const componentMap = new Map();
|
||||
|
||||
// Function to create and configure a light component
|
||||
function createLightComponent(data, key) {
|
||||
const lightComponent = document.createElement("light-component");
|
||||
lightComponent.style.left = `${data.x}px`; // Set the x position
|
||||
lightComponent.style.top = `${data.y}px`; // Set the y position
|
||||
lightComponent.style.backgroundColor = data.settings?.color || "#4caf50"; // Set the background color
|
||||
lightComponent.textContent = data.name || "Light Me Up!"; // Set the text content
|
||||
|
||||
// Set the lightId property
|
||||
lightComponent.lightId = key; // Use the backend ID as the lightId
|
||||
|
||||
// Store the component in the map
|
||||
componentMap.set(key, lightComponent);
|
||||
|
||||
// Append the light component to the container
|
||||
appContainer.appendChild(lightComponent);
|
||||
|
||||
// Handle position change
|
||||
lightComponent.addEventListener("position-change", (event) => {
|
||||
const { lightId, x, y } = event.detail;
|
||||
updatePositionOnServer(lightId, x, y);
|
||||
});
|
||||
|
||||
// Handle color change
|
||||
lightComponent.addEventListener("color-change", (event) => {
|
||||
const { lightId, color } = event.detail;
|
||||
sendColorToServer(lightId, color);
|
||||
});
|
||||
|
||||
// Example: Add a click event listener to the light-component
|
||||
lightComponent.addEventListener("click", () => {
|
||||
console.log(`Light component clicked! ID: ${lightComponent.lightId}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Iterate over the JSON data and create light components
|
||||
for (const key in lightData) {
|
||||
if (lightData.hasOwnProperty(key)) {
|
||||
const light = lightData[key];
|
||||
createLightComponent(light, key); // Pass the backend ID
|
||||
}
|
||||
}
|
||||
|
||||
// Function to send the updated position to the server via a PATCH request
|
||||
async function updatePositionOnServer(componentId, x, y) {
|
||||
try {
|
||||
const response = await fetch(`/light/${componentId}`, {
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ x, y }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Updated position for component ${componentId}: x=${x}, y=${y}`,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error updating position on server:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// Function to send the selected color to the server via WebSocket
|
||||
function sendColorToServer(componentId, color) {
|
||||
const websocket = getWebSocket();
|
||||
const message = JSON.stringify({
|
||||
componentId,
|
||||
color: color,
|
||||
});
|
||||
|
||||
if (websocket.readyState === WebSocket.OPEN) {
|
||||
websocket.send(message);
|
||||
console.log("Sent color to server:", message);
|
||||
} else {
|
||||
console.warn("WebSocket is not open. Unable to send color.");
|
||||
}
|
||||
}
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error("Error during GET request:", error);
|
||||
console.error("Error fetching light data:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateColor(event) {
|
||||
event.preventDefault();
|
||||
clearTimeout(colorTimeout);
|
||||
colorTimeout = setTimeout(function () {
|
||||
const color = document.getElementById("color").value;
|
||||
sendWebSocketData({ color1: color });
|
||||
}, 500);
|
||||
}
|
||||
|
||||
async function updateColor2(event) {
|
||||
event.preventDefault();
|
||||
clearTimeout(color2Timeout);
|
||||
color2Timeout = setTimeout(function () {
|
||||
const color = document.getElementById("color2").value;
|
||||
sendWebSocketData({ color2: color });
|
||||
}, 500);
|
||||
}
|
||||
|
||||
async function updatePattern(pattern) {
|
||||
sendWebSocketData({ pattern: pattern });
|
||||
}
|
||||
|
||||
async function updateBrightness(event) {
|
||||
event.preventDefault();
|
||||
clearTimeout(brightnessTimeout);
|
||||
brightnessTimeout = setTimeout(function () {
|
||||
const brightness = document.getElementById("brightness").value;
|
||||
sendWebSocketData({ brightness: brightness });
|
||||
}, 500);
|
||||
}
|
||||
|
||||
async function updateDelay(event) {
|
||||
event.preventDefault();
|
||||
clearTimeout(delayTimeout);
|
||||
delayTimeout = setTimeout(function () {
|
||||
const delay = document.getElementById("delay").value;
|
||||
sendWebSocketData({ delay: delay });
|
||||
}, 500);
|
||||
}
|
||||
|
||||
async function updateNumLeds(event) {
|
||||
event.preventDefault();
|
||||
const numLeds = document.getElementById("num_leds").value;
|
||||
sendWebSocketData({ num_leds: parseInt(numLeds) });
|
||||
}
|
||||
|
||||
async function updateName(event) {
|
||||
event.preventDefault();
|
||||
const name = document.getElementById("name").value;
|
||||
sendWebSocketData({ name: name });
|
||||
}
|
||||
|
||||
function createPatternButtons(patterns) {
|
||||
const container = document.getElementById("pattern_buttons");
|
||||
container.innerHTML = ""; // Clear previous buttons
|
||||
|
||||
patterns.forEach((pattern) => {
|
||||
const button = document.createElement("button");
|
||||
button.type = "button";
|
||||
button.textContent = pattern;
|
||||
button.value = pattern;
|
||||
button.addEventListener("click", async function (event) {
|
||||
event.preventDefault();
|
||||
await updatePattern(pattern);
|
||||
});
|
||||
container.appendChild(button);
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async function () {
|
||||
// Get the connection status element once the DOM is ready
|
||||
connectionStatusElement = document.getElementById("connection-status");
|
||||
|
||||
// Establish WebSocket connection on page load
|
||||
connectWebSocket();
|
||||
|
||||
document.getElementById("color").addEventListener("input", updateColor);
|
||||
document.getElementById("color2").addEventListener("input", updateColor2);
|
||||
document.getElementById("delay").addEventListener("input", updateDelay);
|
||||
document
|
||||
.getElementById("brightness")
|
||||
.addEventListener("input", updateBrightness);
|
||||
document
|
||||
.getElementById("num_leds_form")
|
||||
.addEventListener("submit", updateNumLeds);
|
||||
document.getElementById("name_form").addEventListener("submit", updateName);
|
||||
document.getElementById("delay").addEventListener("touchend", updateDelay);
|
||||
document
|
||||
.getElementById("brightness")
|
||||
.addEventListener("touchend", updateBrightness);
|
||||
|
||||
document.querySelectorAll(".pattern_button").forEach((button) => {
|
||||
console.log(button.value);
|
||||
button.addEventListener("click", async (event) => {
|
||||
event.preventDefault();
|
||||
await updatePattern(button.value);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Function to toggle the display of the settings menu
|
||||
function selectSettings() {
|
||||
const settingsMenu = document.getElementById("settings_menu");
|
||||
controls = document.getElementById("controls");
|
||||
settingsMenu.style.display = "block";
|
||||
controls.style.display = "none";
|
||||
}
|
||||
|
||||
function selectControls() {
|
||||
const settingsMenu = document.getElementById("settings_menu");
|
||||
controls = document.getElementById("controls");
|
||||
settingsMenu.style.display = "none";
|
||||
controls.style.display = "block";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user