feat: side panel widget #16
This commit is contained in:
@@ -93,6 +93,11 @@ const promptArgs = async (proc) => {
|
|||||||
question: "Enter WEB zoom level",
|
question: "Enter WEB zoom level",
|
||||||
fallback: "1.25",
|
fallback: "1.25",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "web_widget",
|
||||||
|
question: "Enter WEB widget enabled",
|
||||||
|
fallback: "true",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "mqtt",
|
key: "mqtt",
|
||||||
question: "\nConnect to MQTT Broker?",
|
question: "\nConnect to MQTT Broker?",
|
||||||
|
|||||||
+193
-64
@@ -1,7 +1,7 @@
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const hardware = require("./hardware");
|
const hardware = require("./hardware");
|
||||||
const integration = require("./integration");
|
const integration = require("./integration");
|
||||||
const { app, screen, nativeTheme, BaseWindow, WebContentsView } = require("electron");
|
const { app, screen, nativeTheme, ipcMain, BaseWindow, WebContentsView } = require("electron");
|
||||||
|
|
||||||
global.WEBVIEW = global.WEBVIEW || {
|
global.WEBVIEW = global.WEBVIEW || {
|
||||||
initialized: false,
|
initialized: false,
|
||||||
@@ -24,12 +24,23 @@ const init = async (args) => {
|
|||||||
console.error("Please provide the '--web-url' parameter");
|
console.error("Please provide the '--web-url' parameter");
|
||||||
return app.quit();
|
return app.quit();
|
||||||
}
|
}
|
||||||
|
if (!/^https?:\/\//.test(args.web_url)) {
|
||||||
|
console.error("Please provide the '--web-url' parameter with http(s)");
|
||||||
|
return app.quit();
|
||||||
|
}
|
||||||
const url = new URL(args.web_url);
|
const url = new URL(args.web_url);
|
||||||
const theme = args.web_theme ? args.web_theme : "dark";
|
const theme = ["light", "dark"].includes(args.web_theme) ? args.web_theme : "dark";
|
||||||
const zoom = args.web_zoom ? parseFloat(args.web_zoom) : 1.25;
|
const zoom = !isNaN(parseFloat(args.web_zoom)) ? parseFloat(args.web_zoom) : 1.25;
|
||||||
|
const widget = args.web_widget ? args.web_widget === "true" : true;
|
||||||
|
|
||||||
|
// Init global layout
|
||||||
|
WEBVIEW.viewZoom = zoom;
|
||||||
|
WEBVIEW.viewTheme = theme;
|
||||||
|
WEBVIEW.widgetTheme = theme;
|
||||||
|
WEBVIEW.widgetEnabled = widget;
|
||||||
|
nativeTheme.themeSource = WEBVIEW.viewTheme;
|
||||||
|
|
||||||
// Init global root window
|
// Init global root window
|
||||||
nativeTheme.themeSource = theme;
|
|
||||||
WEBVIEW.window = new BaseWindow({
|
WEBVIEW.window = new BaseWindow({
|
||||||
title: `TouchKio - ${url.host}`,
|
title: `TouchKio - ${url.host}`,
|
||||||
icon: path.join(__dirname, "..", "img", "icon.png"),
|
icon: path.join(__dirname, "..", "img", "icon.png"),
|
||||||
@@ -37,15 +48,34 @@ const init = async (args) => {
|
|||||||
WEBVIEW.window.setMenuBarVisibility(false);
|
WEBVIEW.window.setMenuBarVisibility(false);
|
||||||
WEBVIEW.window.setFullScreen(true);
|
WEBVIEW.window.setFullScreen(true);
|
||||||
|
|
||||||
// Init global main webview
|
// Init global webview
|
||||||
WEBVIEW.view = new WebContentsView();
|
WEBVIEW.view = new WebContentsView({
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: false,
|
||||||
|
contextIsolation: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
WEBVIEW.window.contentView.addChildView(WEBVIEW.view);
|
WEBVIEW.window.contentView.addChildView(WEBVIEW.view);
|
||||||
WEBVIEW.view.webContents.loadURL(url.toString());
|
WEBVIEW.view.webContents.loadURL(url.toString());
|
||||||
|
WEBVIEW.view.setBackgroundColor("#FFFFFFFF");
|
||||||
|
|
||||||
|
// Init global widget
|
||||||
|
WEBVIEW.widget = new WebContentsView({
|
||||||
|
transparent: true,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
contextIsolation: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
WEBVIEW.window.contentView.addChildView(WEBVIEW.widget);
|
||||||
|
WEBVIEW.widget.webContents.loadFile(path.join(__dirname, "widget.html"));
|
||||||
|
WEBVIEW.widget.setBackgroundColor("#00000000");
|
||||||
|
|
||||||
// Register events
|
// Register events
|
||||||
windowEvents(WEBVIEW.window, zoom);
|
windowEvents();
|
||||||
touchEvents(WEBVIEW.window);
|
widgetEvents();
|
||||||
viewEvents(WEBVIEW.view);
|
domEvents();
|
||||||
|
appEvents();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -69,6 +99,11 @@ const update = () => {
|
|||||||
WEBVIEW.status = "Framed";
|
WEBVIEW.status = "Framed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update widget status
|
||||||
|
if (!HARDWARE.support.keyboardVisibility) {
|
||||||
|
WEBVIEW.widget.webContents.send("button-hide", { id: "keyboard" });
|
||||||
|
}
|
||||||
|
|
||||||
// Update integration sensor
|
// Update integration sensor
|
||||||
console.log("Update Kiosk Status:", WEBVIEW.status);
|
console.log("Update Kiosk Status:", WEBVIEW.status);
|
||||||
integration.update();
|
integration.update();
|
||||||
@@ -76,67 +111,62 @@ const update = () => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Register window events and handler.
|
* Register window events and handler.
|
||||||
*
|
|
||||||
* @param {Object} window - The root window object.
|
|
||||||
* @param {number} zoom - Zoom level used for the webview.
|
|
||||||
*/
|
*/
|
||||||
const windowEvents = (window, zoom) => {
|
const windowEvents = () => {
|
||||||
// Handle window resize for webview bounds
|
// Handle window resize events
|
||||||
const resize = () => {
|
const resize = () => {
|
||||||
const { width, height } = window.getBounds();
|
const window = WEBVIEW.window.getBounds();
|
||||||
WEBVIEW.view.setBounds({ x: 0, y: 0, width: width, height: height });
|
const widget = { width: 60, height: 200 };
|
||||||
WEBVIEW.view.webContents.setZoomFactor(zoom);
|
|
||||||
|
// Update view size
|
||||||
|
WEBVIEW.view.setBounds({
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: window.width,
|
||||||
|
height: window.height,
|
||||||
|
});
|
||||||
|
WEBVIEW.view.webContents.setZoomFactor(WEBVIEW.viewZoom);
|
||||||
|
WEBVIEW.view.webContents.focus();
|
||||||
|
|
||||||
|
// Update widget size
|
||||||
|
if (WEBVIEW.widgetEnabled) {
|
||||||
|
WEBVIEW.widget.setBounds({
|
||||||
|
x: window.width - 15,
|
||||||
|
y: parseInt(window.height / 2 - widget.height / 2),
|
||||||
|
width: widget.width,
|
||||||
|
height: widget.height,
|
||||||
|
});
|
||||||
|
WEBVIEW.widget.webContents.send("data-theme", { theme: "hidden" });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
window.on("ready-to-show", resize);
|
WEBVIEW.window.on("ready-to-show", resize);
|
||||||
window.on("resize", resize);
|
WEBVIEW.window.on("resize", resize);
|
||||||
resize();
|
resize();
|
||||||
|
|
||||||
// Handle window status updates
|
// Handle window focus events
|
||||||
window.on("minimize", update);
|
WEBVIEW.window.on("focus", () => {
|
||||||
window.on("restore", update);
|
|
||||||
window.on("maximize", update);
|
|
||||||
window.on("unmaximize", update);
|
|
||||||
window.on("enter-full-screen", update);
|
|
||||||
window.on("leave-full-screen", update);
|
|
||||||
|
|
||||||
// Handle signal and exit events
|
|
||||||
process.on("SIGINT", app.quit);
|
|
||||||
app.on("before-quit", () => {
|
|
||||||
WEBVIEW.status = "Terminated";
|
|
||||||
integration.update();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Handle multiple instances
|
|
||||||
app.on("second-instance", () => {
|
|
||||||
if (window.isMinimized()) {
|
|
||||||
window.restore();
|
|
||||||
}
|
|
||||||
window.focus();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register touch events and handler.
|
|
||||||
*
|
|
||||||
* @param {Object} window - The root window object.
|
|
||||||
*/
|
|
||||||
const touchEvents = (window) => {
|
|
||||||
// Handle focus change for webview lock
|
|
||||||
window.on("focus", () => {
|
|
||||||
if (WEBVIEW.locked) {
|
if (WEBVIEW.locked) {
|
||||||
hardware.setDisplayStatus("ON");
|
hardware.setDisplayStatus("ON");
|
||||||
window.blur();
|
WEBVIEW.window.blur();
|
||||||
}
|
}
|
||||||
WEBVIEW.locked = false;
|
WEBVIEW.locked = false;
|
||||||
});
|
});
|
||||||
HARDWARE.display.notifiers.push(() => {
|
HARDWARE.display.notifiers.push(() => {
|
||||||
WEBVIEW.locked = hardware.getDisplayStatus() === "OFF";
|
WEBVIEW.locked = hardware.getDisplayStatus() === "OFF";
|
||||||
if (WEBVIEW.locked) {
|
if (WEBVIEW.locked) {
|
||||||
window.blur();
|
WEBVIEW.window.blur();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle touch events for activity tracking
|
// Handle window status updates
|
||||||
|
WEBVIEW.window.on("minimize", update);
|
||||||
|
WEBVIEW.window.on("restore", update);
|
||||||
|
WEBVIEW.window.on("maximize", update);
|
||||||
|
WEBVIEW.window.on("unmaximize", update);
|
||||||
|
WEBVIEW.window.on("enter-full-screen", update);
|
||||||
|
WEBVIEW.window.on("leave-full-screen", update);
|
||||||
|
|
||||||
|
// Handle window touch events for activity tracking
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
const posOld = WEBVIEW.pointer.position;
|
const posOld = WEBVIEW.pointer.position;
|
||||||
const posNew = screen.getCursorScreenPoint();
|
const posNew = screen.getCursorScreenPoint();
|
||||||
@@ -156,35 +186,134 @@ const touchEvents = (window) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register webview events and handler.
|
* Register widget events and handler.
|
||||||
*
|
|
||||||
* @param {Object} view - The main webview object.
|
|
||||||
*/
|
*/
|
||||||
const viewEvents = (view) => {
|
const widgetEvents = () => {
|
||||||
|
if (!WEBVIEW.widgetEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle widget focus events
|
||||||
|
WEBVIEW.widget.webContents.on("focus", () => {
|
||||||
|
const window = WEBVIEW.window.getBounds();
|
||||||
|
const widget = WEBVIEW.widget.getBounds();
|
||||||
|
|
||||||
|
// Show widget
|
||||||
|
WEBVIEW.widget.setBounds({
|
||||||
|
x: window.width - 60,
|
||||||
|
y: widget.y,
|
||||||
|
width: widget.width,
|
||||||
|
height: widget.height,
|
||||||
|
});
|
||||||
|
WEBVIEW.widget.webContents.send("data-theme", { theme: WEBVIEW.widgetTheme });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle widget blur events
|
||||||
|
WEBVIEW.widget.webContents.on("blur", () => {
|
||||||
|
const window = WEBVIEW.window.getBounds();
|
||||||
|
const widget = WEBVIEW.widget.getBounds();
|
||||||
|
|
||||||
|
// Hide widget
|
||||||
|
WEBVIEW.widget.setBounds({
|
||||||
|
x: window.width - 15,
|
||||||
|
y: widget.y,
|
||||||
|
width: widget.width,
|
||||||
|
height: widget.height,
|
||||||
|
});
|
||||||
|
WEBVIEW.widget.webContents.send("data-theme", { theme: "hidden" });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle widget button click events
|
||||||
|
ipcMain.on("button-click", (e, button) => {
|
||||||
|
switch (button.id) {
|
||||||
|
case "refresh":
|
||||||
|
WEBVIEW.view.webContents.reloadIgnoringCache();
|
||||||
|
break;
|
||||||
|
case "fullscreen":
|
||||||
|
if (WEBVIEW.window.isFullScreen()) {
|
||||||
|
WEBVIEW.window.restore();
|
||||||
|
WEBVIEW.window.unmaximize();
|
||||||
|
WEBVIEW.window.setFullScreen(false);
|
||||||
|
} else {
|
||||||
|
WEBVIEW.window.restore();
|
||||||
|
WEBVIEW.window.unmaximize();
|
||||||
|
WEBVIEW.window.setFullScreen(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "minimize":
|
||||||
|
WEBVIEW.window.restore();
|
||||||
|
WEBVIEW.window.setFullScreen(false);
|
||||||
|
WEBVIEW.window.minimize();
|
||||||
|
break;
|
||||||
|
case "keyboard":
|
||||||
|
const toggle = hardware.getKeyboardVisibility() === "ON" ? "OFF" : "ON";
|
||||||
|
hardware.setKeyboardVisibility(toggle);
|
||||||
|
switch (toggle) {
|
||||||
|
case "OFF":
|
||||||
|
WEBVIEW.window.restore();
|
||||||
|
WEBVIEW.window.unmaximize();
|
||||||
|
WEBVIEW.window.setFullScreen(true);
|
||||||
|
break;
|
||||||
|
case "ON":
|
||||||
|
WEBVIEW.window.restore();
|
||||||
|
WEBVIEW.window.setFullScreen(false);
|
||||||
|
WEBVIEW.window.maximize();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register dom events and handler.
|
||||||
|
*/
|
||||||
|
const domEvents = () => {
|
||||||
// Enable webview touch emulation
|
// Enable webview touch emulation
|
||||||
view.webContents.debugger.attach("1.1");
|
WEBVIEW.view.webContents.debugger.attach("1.1");
|
||||||
view.webContents.debugger.sendCommand("Emulation.setEmitTouchEventsForMouse", {
|
WEBVIEW.view.webContents.debugger.sendCommand("Emulation.setEmitTouchEventsForMouse", {
|
||||||
configuration: "mobile",
|
configuration: "mobile",
|
||||||
enabled: true,
|
enabled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Disable webview hyperlinks
|
// Disable webview hyperlinks
|
||||||
view.webContents.setWindowOpenHandler(() => {
|
WEBVIEW.view.webContents.setWindowOpenHandler(() => {
|
||||||
return { action: "deny" };
|
return { action: "deny" };
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove webview scrollbar
|
// Remove webview scrollbar
|
||||||
view.webContents.on("dom-ready", () => {
|
WEBVIEW.view.webContents.on("dom-ready", () => {
|
||||||
view.webContents.insertCSS("::-webkit-scrollbar { display: none; }");
|
WEBVIEW.view.webContents.insertCSS("::-webkit-scrollbar { display: none; }");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Webview fully loaded
|
// Webview fully loaded
|
||||||
view.webContents.on("did-finish-load", () => {
|
WEBVIEW.view.webContents.on("did-finish-load", () => {
|
||||||
|
// view.webContents.openDevTools();
|
||||||
WEBVIEW.initialized = true;
|
WEBVIEW.initialized = true;
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register app events and handler.
|
||||||
|
*/
|
||||||
|
const appEvents = () => {
|
||||||
|
// Handle signal and exit events
|
||||||
|
process.on("SIGINT", app.quit);
|
||||||
|
app.on("before-quit", () => {
|
||||||
|
WEBVIEW.status = "Terminated";
|
||||||
|
integration.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle multiple instances
|
||||||
|
app.on("second-instance", () => {
|
||||||
|
if (WEBVIEW.window.isMinimized()) {
|
||||||
|
WEBVIEW.window.restore();
|
||||||
|
}
|
||||||
|
WEBVIEW.window.focus();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init,
|
init,
|
||||||
update,
|
update,
|
||||||
|
|||||||
+125
@@ -0,0 +1,125 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
[data-theme="dark"] {
|
||||||
|
--primary-color: rgba(225, 225, 225, 1);
|
||||||
|
--border-color: rgba(225, 225, 225, 0.15);
|
||||||
|
--background-color: rgba(28, 28, 28, 1);
|
||||||
|
}
|
||||||
|
[data-theme="light"] {
|
||||||
|
--primary-color: rgba(33, 33, 33, 1);
|
||||||
|
--border-color: rgba(33, 33, 33, 0.15);
|
||||||
|
--background-color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
[data-theme="hidden"] {
|
||||||
|
--primary-color: rgba(0, 0, 0, 0);
|
||||||
|
--border-color: rgba(0, 0, 0, 0);
|
||||||
|
--background-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100vw;
|
||||||
|
padding: 10px;
|
||||||
|
row-gap: 10px;
|
||||||
|
list-style-type: none;
|
||||||
|
border-top-left-radius: 15px;
|
||||||
|
border-bottom-left-radius: 15px;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
border-left: 1px solid var(--border-color);
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
background: var(--background-color);
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
svg {
|
||||||
|
pointer-events: none;
|
||||||
|
fill: var(--primary-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<menu>
|
||||||
|
<li>
|
||||||
|
<button id="refresh">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<title>web-refresh</title>
|
||||||
|
<path
|
||||||
|
d="M13.82 14H9.66C9.56 13.34 9.5 12.68 9.5 12S9.56 10.65 9.66 10H14.34C14.43 10.65 14.5 11.32 14.5 12C14.5 12.5 14.46 13 14.4 13.46C15 12.96 15.72 12.57 16.5 12.32C16.5 12.21 16.5 12.11 16.5 12C16.5 11.32 16.44 10.66 16.36 10H19.74C19.9 10.64 20 11.31 20 12C20 12.06 20 12.12 20 12.18C20.7 12.35 21.35 12.63 21.95 13C22 12.68 22 12.34 22 12C22 6.5 17.5 2 12 2C6.47 2 2 6.5 2 12C2 17.5 6.5 22 12 22C12.34 22 12.68 22 13 21.95C12.59 21.29 12.29 20.55 12.13 19.75C12.09 19.82 12.05 19.89 12 19.96C11.17 18.76 10.5 17.43 10.09 16H12.5C12.81 15.25 13.26 14.58 13.82 14M18.92 8H15.97C15.65 6.75 15.19 5.55 14.59 4.44C16.43 5.07 17.96 6.34 18.92 8M12 4.03C12.83 5.23 13.5 6.57 13.91 8H10.09C10.5 6.57 11.17 5.23 12 4.03M4.26 14C4.1 13.36 4 12.69 4 12S4.1 10.64 4.26 10H7.64C7.56 10.66 7.5 11.32 7.5 12S7.56 13.34 7.64 14H4.26M5.08 16H8C8.35 17.25 8.8 18.45 9.4 19.56C7.57 18.93 6.03 17.65 5.08 16M8 8H5.08C6.03 6.34 7.57 5.06 9.4 4.44C8.8 5.55 8.35 6.75 8 8M20.83 15.67L22 14.5V18.5H18L19.77 16.73C19.32 16.28 18.69 16 18 16C16.62 16 15.5 17.12 15.5 18.5S16.62 21 18 21C18.82 21 19.54 20.61 20 20H21.71C21.12 21.47 19.68 22.5 18 22.5C15.79 22.5 14 20.71 14 18.5S15.79 14.5 18 14.5C19.11 14.5 20.11 14.95 20.83 15.67Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button id="fullscreen">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<title>overscan</title>
|
||||||
|
<path
|
||||||
|
d="M12 5.5L10 8H14L12 5.5M18 10V14L20.5 12L18 10M6 10L3.5 12L6 14V10M14 16H10L12 18.5L14 16M21 3H3C1.9 3 1 3.9 1 5V19C1 20.1 1.9 21 3 21H21C22.1 21 23 20.1 23 19V5C23 3.9 22.1 3 21 3M21 19H3V5H21V19Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button id="minimize">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<title>image-size-select-small</title>
|
||||||
|
<path
|
||||||
|
d="M23,15H21V17H23V15M23,11H21V13H23V11M23,19H21V21C22,21 23,20 23,19M15,3H13V5H15V3M23,7H21V9H23V7M21,3V5H23C23,4 22,3 21,3M3,21H11V15H1V19A2,2 0 0,0 3,21M3,7H1V9H3V7M15,19H13V21H15V19M19,3H17V5H19V3M19,19H17V21H19V19M3,3C2,3 1,4 1,5H3V3M3,11H1V13H3V11M11,3H9V5H11V3M7,3H5V5H7V3Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button id="keyboard">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||||
|
<title>keyboard-close-outline</title>
|
||||||
|
<path
|
||||||
|
d="M12 23L16 19H8M4 3C2.9 3 2 3.9 2 5V15C2 16.1 2.9 17 4 17H20C21.1 17 22 16.1 22 15V5C22 3.9 21.1 3 20 3H4M4 5H20V15H4V5M5 6V8H7V6H5M8 6V8H10V6H8M11 6V8H13V6H11M14 6V8H16V6H14M17 6V8H19V6H17M5 9V11H7V9H5M8 9V11H10V9H8M11 9V11H13V9H11M14 9V11H16V9H14M17 9V11H19V9H17M8 12V14H16V12H8Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</menu>
|
||||||
|
<script>
|
||||||
|
const { ipcRenderer } = require("electron");
|
||||||
|
|
||||||
|
// Register button click send message
|
||||||
|
document.querySelectorAll("button").forEach((button) => {
|
||||||
|
button.addEventListener("click", (e) => {
|
||||||
|
ipcRenderer.send("button-click", { id: e.target.id });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register button hide receive message
|
||||||
|
ipcRenderer.on("button-hide", (e, button) => {
|
||||||
|
document.getElementById(button.id).parentNode.hidden = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register data theme receive message
|
||||||
|
ipcRenderer.on("data-theme", (e, data) => {
|
||||||
|
document.documentElement.setAttribute("data-theme", data.theme);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user