mirror of
https://github.com/sascha-hemi/homeassistant-desktop.git
synced 2026-03-21 03:04:10 +01:00
refactor: Refactors the code
This commit is contained in:
652
app.js
652
app.js
@@ -9,23 +9,13 @@ const {
|
|||||||
Menu,
|
Menu,
|
||||||
Tray,
|
Tray,
|
||||||
BrowserWindow,
|
BrowserWindow,
|
||||||
} = require("electron");
|
} = require('electron');
|
||||||
const { autoUpdater } = require("electron-updater");
|
const { autoUpdater } = require('electron-updater');
|
||||||
const AutoLaunch = require("auto-launch");
|
const AutoLaunch = require('auto-launch');
|
||||||
const Positioner = require("electron-traywindow-positioner");
|
const Positioner = require('electron-traywindow-positioner');
|
||||||
const Store = require("electron-store");
|
const Store = require('electron-store');
|
||||||
const bonjour = require("bonjour")();
|
const bonjour = require('bonjour')();
|
||||||
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
const registerKeyboardShortcut = () => {
|
|
||||||
globalShortcut.register("CommandOrControl+Alt+X", () => {
|
|
||||||
if (window.isVisible()) window.hide();
|
|
||||||
else showWindow();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const unregisterKeyboardShortcut = () => {
|
|
||||||
globalShortcut.unregisterAll();
|
|
||||||
};
|
|
||||||
|
|
||||||
app.allowRendererProcessReuse = true;
|
app.allowRendererProcessReuse = true;
|
||||||
|
|
||||||
@@ -33,16 +23,20 @@ app.allowRendererProcessReuse = true;
|
|||||||
if (!app.requestSingleInstanceLock()) {
|
if (!app.requestSingleInstanceLock()) {
|
||||||
app.quit();
|
app.quit();
|
||||||
} else {
|
} else {
|
||||||
app.on("second-instance", () => {
|
app.on('second-instance', () => {
|
||||||
if (window) showWindow();
|
if (window) {
|
||||||
|
showWindow();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// hide dock icon on macOS
|
// hide dock icon on macOS
|
||||||
if (process.platform === "darwin") app.dock.hide();
|
if (process.platform === 'darwin') {
|
||||||
|
app.dock.hide();
|
||||||
|
}
|
||||||
|
|
||||||
const store = new Store();
|
const store = new Store();
|
||||||
const autoLauncher = new AutoLaunch({ name: "Home Assistant Desktop" });
|
const autoLauncher = new AutoLaunch({ name: 'Home Assistant Desktop' });
|
||||||
|
|
||||||
const indexFile = `file://${__dirname}/web/index.html`;
|
const indexFile = `file://${__dirname}/web/index.html`;
|
||||||
const errorFile = `file://${__dirname}/web/error.html`;
|
const errorFile = `file://${__dirname}/web/error.html`;
|
||||||
@@ -51,25 +45,43 @@ let autostartEnabled = false;
|
|||||||
let forceQuit = false;
|
let forceQuit = false;
|
||||||
let resizeEvent = false;
|
let resizeEvent = false;
|
||||||
|
|
||||||
const useAutoUpdater = () => {
|
function registerKeyboardShortcut() {
|
||||||
autoUpdater.on("error", (message) => {
|
globalShortcut.register('CommandOrControl+Alt+X', () => {
|
||||||
console.error("There was a problem updating the application");
|
if (window.isVisible()) {
|
||||||
|
window.hide();
|
||||||
|
} else {
|
||||||
|
showWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function unregisterKeyboardShortcut() {
|
||||||
|
globalShortcut.unregisterAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
function useAutoUpdater() {
|
||||||
|
autoUpdater.on('error', (message) => {
|
||||||
|
console.error('There was a problem updating the application');
|
||||||
console.error(message);
|
console.error(message);
|
||||||
});
|
});
|
||||||
|
|
||||||
autoUpdater.on("update-downloaded", () => {
|
autoUpdater.on('update-downloaded', () => {
|
||||||
forceQuit = true;
|
forceQuit = true;
|
||||||
autoUpdater.quitAndInstall();
|
autoUpdater.quitAndInstall();
|
||||||
});
|
});
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
if (store.get("autoUpdate")) autoUpdater.checkForUpdates();
|
if (store.get('autoUpdate')) {
|
||||||
|
autoUpdater.checkForUpdates();
|
||||||
|
}
|
||||||
}, 1000 * 60 * 60);
|
}, 1000 * 60 * 60);
|
||||||
|
|
||||||
if (store.get("autoUpdate")) autoUpdater.checkForUpdates();
|
if (store.get('autoUpdate')) {
|
||||||
};
|
autoUpdater.checkForUpdates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const checkAutoStart = () => {
|
function checkAutoStart() {
|
||||||
autoLauncher
|
autoLauncher
|
||||||
.isEnabled()
|
.isEnabled()
|
||||||
.then((isEnabled) => {
|
.then((isEnabled) => {
|
||||||
@@ -78,23 +90,31 @@ const checkAutoStart = () => {
|
|||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
const startAvailabilityCheck = () => {
|
function startAvailabilityCheck() {
|
||||||
setInterval(() => {
|
let interval;
|
||||||
|
|
||||||
|
function availabilityCheck() {
|
||||||
const request = net.request(`${currentInstance()}/auth/providers`);
|
const request = net.request(`${currentInstance()}/auth/providers`);
|
||||||
request.on("response", (response) => {
|
request.on('response', (response) => {
|
||||||
showError(response.statusCode !== 200);
|
showError(response.statusCode !== 200);
|
||||||
});
|
});
|
||||||
request.on("error", (error) => {
|
request.on('error', (error) => {
|
||||||
|
clearInterval(interval);
|
||||||
showError(true);
|
showError(true);
|
||||||
if (store.get("automaticSwitching")) checkForAvailableInstance();
|
|
||||||
|
if (store.get('automaticSwitching')) {
|
||||||
|
checkForAvailableInstance();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
request.end();
|
request.end();
|
||||||
}, 3000);
|
}
|
||||||
|
|
||||||
|
interval = setInterval(availabilityCheck, 3000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const changePosition = () => {
|
function changePosition() {
|
||||||
const trayBounds = tray.getBounds();
|
const trayBounds = tray.getBounds();
|
||||||
const windowBounds = window.getBounds();
|
const windowBounds = window.getBounds();
|
||||||
const displayWorkArea = screen.getDisplayNearestPoint({
|
const displayWorkArea = screen.getDisplayNearestPoint({
|
||||||
@@ -103,77 +123,62 @@ const changePosition = () => {
|
|||||||
}).workArea;
|
}).workArea;
|
||||||
const taskBarPosition = Positioner.getTaskbarPosition(trayBounds);
|
const taskBarPosition = Positioner.getTaskbarPosition(trayBounds);
|
||||||
|
|
||||||
if (taskBarPosition == "top" || taskBarPosition == "bottom") {
|
if (taskBarPosition === 'top' || taskBarPosition === 'bottom') {
|
||||||
const alignment = {
|
const alignment = {
|
||||||
x: "center",
|
x: 'center',
|
||||||
y: taskBarPosition == "top" ? "up" : "down",
|
y: taskBarPosition === 'top' ? 'up' : 'down',
|
||||||
};
|
};
|
||||||
if (
|
|
||||||
trayBounds.x + (trayBounds.width + windowBounds.width) / 2 <
|
if (trayBounds.x + (trayBounds.width + windowBounds.width) / 2 < displayWorkArea.width) {
|
||||||
displayWorkArea.width
|
|
||||||
)
|
|
||||||
Positioner.position(window, trayBounds, alignment);
|
Positioner.position(window, trayBounds, alignment);
|
||||||
else {
|
} else {
|
||||||
const { y } = Positioner.calculate(
|
const { y } = Positioner.calculate(window.getBounds(), trayBounds, alignment);
|
||||||
window.getBounds(),
|
|
||||||
trayBounds,
|
|
||||||
alignment
|
|
||||||
);
|
|
||||||
|
|
||||||
window.setPosition(
|
window.setPosition(
|
||||||
displayWorkArea.width - windowBounds.width + displayWorkArea.x,
|
displayWorkArea.width - windowBounds.width + displayWorkArea.x,
|
||||||
y + (taskBarPosition == "bottom" && displayWorkArea.y),
|
y + (taskBarPosition === 'bottom' && displayWorkArea.y),
|
||||||
false
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const alignment = { x: taskBarPosition, y: "center" };
|
const alignment = {
|
||||||
if (
|
x: taskBarPosition,
|
||||||
trayBounds.y + (trayBounds.height + windowBounds.height) / 2 <
|
y: 'center',
|
||||||
displayWorkArea.height
|
};
|
||||||
) {
|
|
||||||
const { x, y } = Positioner.calculate(
|
if (trayBounds.y + (trayBounds.height + windowBounds.height) / 2 < displayWorkArea.height) {
|
||||||
window.getBounds(),
|
const { x, y } = Positioner.calculate(window.getBounds(), trayBounds, alignment);
|
||||||
trayBounds,
|
window.setPosition(x + (taskBarPosition === 'right' && displayWorkArea.x), y);
|
||||||
alignment
|
|
||||||
);
|
|
||||||
window.setPosition(
|
|
||||||
x + (taskBarPosition == "right" && displayWorkArea.x),
|
|
||||||
y
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
const { x } = Positioner.calculate(
|
const { x } = Positioner.calculate(window.getBounds(), trayBounds, alignment);
|
||||||
window.getBounds(),
|
window.setPosition(x, displayWorkArea.y + displayWorkArea.height - windowBounds.height, false);
|
||||||
trayBounds,
|
|
||||||
alignment
|
|
||||||
);
|
|
||||||
window.setPosition(
|
|
||||||
x,
|
|
||||||
displayWorkArea.y + displayWorkArea.height - windowBounds.height,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
function checkForAvailableInstance() {
|
||||||
|
const instances = store.get('allInstances');
|
||||||
|
|
||||||
const checkForAvailableInstance = () => {
|
|
||||||
const instances = store.get("allInstances");
|
|
||||||
if (instances?.length > 1) {
|
if (instances?.length > 1) {
|
||||||
bonjour.find({ type: "home-assistant" }, (instance) => {
|
bonjour.find({ type: 'home-assistant' }, (instance) => {
|
||||||
if (instances.indexOf(instance.txt.internal_url) !== -1)
|
if (instance.txt.internal_url && instances.indexOf(instance.txt.internal_url) !== -1) {
|
||||||
return currentInstance(instance.txt.internal_url);
|
return currentInstance(instance.txt.internal_url);
|
||||||
if (instances.indexOf(instance.txt.external_url) !== -1)
|
}
|
||||||
|
|
||||||
|
if (instance.txt.external_url && instances.indexOf(instance.txt.external_url) !== -1) {
|
||||||
return currentInstance(instance.txt.external_url);
|
return currentInstance(instance.txt.external_url);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
let found;
|
let found;
|
||||||
for (let instance of instances.filter((e) => e.url !== currentInstance())) {
|
for (let instance of instances.filter((e) => e.url !== currentInstance())) {
|
||||||
const request = net.request(`${instance}/auth/providers`);
|
const request = net.request(`${instance}/auth/providers`);
|
||||||
request.on("response", (response) => {
|
request.on('response', (response) => {
|
||||||
if (response.statusCode === 200) {
|
if (response.statusCode === 200) {
|
||||||
found = instance;
|
found = instance;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
request.on("error", (error) => {});
|
request.on('error', (_) => {
|
||||||
|
});
|
||||||
request.end();
|
request.end();
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
@@ -182,29 +187,29 @@ const checkForAvailableInstance = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const getMenu = () => {
|
function getMenu() {
|
||||||
let instancesMenu = [
|
let instancesMenu = [
|
||||||
{
|
{
|
||||||
label: "Open in Browser",
|
label: 'Open in Browser',
|
||||||
enabled: currentInstance(),
|
enabled: currentInstance(),
|
||||||
click: () => {
|
click: () => {
|
||||||
shell.openExternal(currentInstance());
|
shell.openExternal(currentInstance());
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "separator",
|
type: 'separator',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const allInstances = store.get("allInstances");
|
const allInstances = store.get('allInstances');
|
||||||
|
|
||||||
if (allInstances) {
|
if (allInstances) {
|
||||||
allInstances.forEach((e) => {
|
allInstances.forEach((e) => {
|
||||||
instancesMenu.push({
|
instancesMenu.push({
|
||||||
label: e,
|
label: e,
|
||||||
type: "checkbox",
|
type: 'checkbox',
|
||||||
checked: currentInstance() === e,
|
checked: currentInstance() === e,
|
||||||
click: () => {
|
click: () => {
|
||||||
currentInstance(e);
|
currentInstance(e);
|
||||||
@@ -216,137 +221,150 @@ const getMenu = () => {
|
|||||||
|
|
||||||
instancesMenu.push(
|
instancesMenu.push(
|
||||||
{
|
{
|
||||||
type: "separator",
|
type: 'separator',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Add another Instance...",
|
label: 'Add another Instance...',
|
||||||
click: () => {
|
click: () => {
|
||||||
store.delete("currentInstance");
|
store.delete('currentInstance');
|
||||||
window.loadURL(indexFile);
|
window.loadURL(indexFile);
|
||||||
window.show();
|
window.show();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Automatic Switching",
|
label: 'Automatic Switching',
|
||||||
type: "checkbox",
|
type: 'checkbox',
|
||||||
enabled:
|
enabled: store.has('allInstances') && store.get('allInstances').length > 1,
|
||||||
store.has("allInstances") && store.get("allInstances").length > 1,
|
checked: store.get('automaticSwitching'),
|
||||||
checked: store.get("automaticSwitching"),
|
|
||||||
click: () => {
|
click: () => {
|
||||||
store.set("automaticSwitching", !store.get("automaticSwitching"));
|
store.set('automaticSwitching', !store.get('automaticSwitching'));
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
instancesMenu.push({ label: "Not Connected...", enabled: false });
|
instancesMenu.push({ label: 'Not Connected...', enabled: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
return Menu.buildFromTemplate([
|
return Menu.buildFromTemplate([
|
||||||
{
|
{
|
||||||
label: "Show/Hide Window",
|
label: 'Show/Hide Window',
|
||||||
visible: process.platform === "linux",
|
visible: process.platform === 'linux',
|
||||||
click: () => {
|
click: () => {
|
||||||
if (window.isVisible()) window.hide();
|
if (window.isVisible()) {
|
||||||
else showWindow();
|
window.hide();
|
||||||
|
} else {
|
||||||
|
showWindow();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
visible: process.platform === "linux",
|
visible: process.platform === 'linux',
|
||||||
type: "separator",
|
type: 'separator',
|
||||||
},
|
},
|
||||||
...instancesMenu,
|
...instancesMenu,
|
||||||
{
|
{
|
||||||
type: "separator",
|
type: 'separator',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Hover to Show",
|
label: 'Hover to Show',
|
||||||
visible: process.platform !== "linux" && !store.get("detachedMode"),
|
visible: process.platform !== 'linux' && !store.get('detachedMode'),
|
||||||
enabled: !store.get("detachedMode"),
|
enabled: !store.get('detachedMode'),
|
||||||
type: "checkbox",
|
type: 'checkbox',
|
||||||
checked: !store.get("disableHover"),
|
checked: !store.get('disableHover'),
|
||||||
click: () => {
|
click: () => {
|
||||||
store.set("disableHover", !store.get("disableHover"));
|
store.set('disableHover', !store.get('disableHover'));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Stay on Top",
|
label: 'Stay on Top',
|
||||||
type: "checkbox",
|
type: 'checkbox',
|
||||||
checked: store.get("stayOnTop"),
|
checked: store.get('stayOnTop'),
|
||||||
click: () => {
|
click: () => {
|
||||||
store.set("stayOnTop", !store.get("stayOnTop"));
|
store.set('stayOnTop', !store.get('stayOnTop'));
|
||||||
window.setAlwaysOnTop(store.get("stayOnTop"));
|
window.setAlwaysOnTop(store.get('stayOnTop'));
|
||||||
if (window.isAlwaysOnTop()) showWindow();
|
|
||||||
|
if (window.isAlwaysOnTop()) {
|
||||||
|
showWindow();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Start at Login",
|
label: 'Start at Login',
|
||||||
type: "checkbox",
|
type: 'checkbox',
|
||||||
checked: autostartEnabled,
|
checked: autostartEnabled,
|
||||||
click: () => {
|
click: () => {
|
||||||
if (autostartEnabled) autoLauncher.disable();
|
if (autostartEnabled) {
|
||||||
else autoLauncher.enable();
|
autoLauncher.disable();
|
||||||
|
} else {
|
||||||
|
autoLauncher.enable();
|
||||||
|
}
|
||||||
|
|
||||||
checkAutoStart();
|
checkAutoStart();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `Enable Shortcut`,
|
label: 'Enable Shortcut',
|
||||||
type: "checkbox",
|
type: 'checkbox',
|
||||||
accelerator: "CommandOrControl+Alt+X",
|
accelerator: 'CommandOrControl+Alt+X',
|
||||||
checked: store.get("shortcutEnabled"),
|
checked: store.get('shortcutEnabled'),
|
||||||
click: () => {
|
click: () => {
|
||||||
store.set("shortcutEnabled", !store.get("shortcutEnabled"));
|
store.set('shortcutEnabled', !store.get('shortcutEnabled'));
|
||||||
if (store.get("shortcutEnabled")) registerKeyboardShortcut();
|
|
||||||
else unregisterKeyboardShortcut();
|
if (store.get('shortcutEnabled')) {
|
||||||
|
registerKeyboardShortcut();
|
||||||
|
} else {
|
||||||
|
unregisterKeyboardShortcut();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "separator",
|
type: 'separator',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Use detached Window",
|
label: 'Use detached Window',
|
||||||
type: "checkbox",
|
type: 'checkbox',
|
||||||
checked: store.get("detachedMode"),
|
checked: store.get('detachedMode'),
|
||||||
click: () => {
|
click: () => {
|
||||||
store.set("detachedMode", !store.get("detachedMode"));
|
store.set('detachedMode', !store.get('detachedMode'));
|
||||||
window.hide();
|
window.hide();
|
||||||
createMainWindow(store.get("detachedMode"));
|
createMainWindow(store.get('detachedMode'));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Use Fullscreen",
|
label: 'Use Fullscreen',
|
||||||
type: "checkbox",
|
type: 'checkbox',
|
||||||
checked: store.get("fullScreen"),
|
checked: store.get('fullScreen'),
|
||||||
accelerator: "CommandOrControl+Alt+Return",
|
accelerator: 'CommandOrControl+Alt+Return',
|
||||||
click: () => {
|
click: () => {
|
||||||
toggleFullScreen();
|
toggleFullScreen();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "separator",
|
type: 'separator',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: `v${app.getVersion()}`,
|
label: `v${app.getVersion()}`,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Automatic Updates",
|
label: 'Automatic Updates',
|
||||||
type: "checkbox",
|
type: 'checkbox',
|
||||||
checked: store.get("autoUpdate"),
|
checked: store.get('autoUpdate'),
|
||||||
click: () => {
|
click: () => {
|
||||||
store.set("autoUpdate", !store.get("autoUpdate"));
|
store.set('autoUpdate', !store.get('autoUpdate'));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Open on github.com",
|
label: 'Open on github.com',
|
||||||
click: () => {
|
click: () => {
|
||||||
shell.openExternal("https://github.com/mrvnklm/homeassistant-desktop");
|
shell.openExternal('https://github.com/iprodanovbg/homeassistant-desktop');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "separator",
|
type: 'separator',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Reload Window",
|
label: 'Reload Window',
|
||||||
click: () => {
|
click: () => {
|
||||||
window.reload();
|
window.reload();
|
||||||
window.show();
|
window.show();
|
||||||
@@ -354,12 +372,12 @@ const getMenu = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Reset Application...",
|
label: 'Reset Application...',
|
||||||
click: () => {
|
click: () => {
|
||||||
dialog
|
dialog
|
||||||
.showMessageBox({
|
.showMessageBox({
|
||||||
message: "Are you sure you want to reset Home Assistant Desktop?",
|
message: 'Are you sure you want to reset Home Assistant Desktop?',
|
||||||
buttons: ["Reset Everything!", "Reset Windows", "Cancel"],
|
buttons: ['Reset Everything!', 'Reset Windows', 'Cancel'],
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.response === 0) {
|
if (res.response === 0) {
|
||||||
@@ -369,12 +387,13 @@ const getMenu = () => {
|
|||||||
app.relaunch();
|
app.relaunch();
|
||||||
app.exit();
|
app.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.response === 1) {
|
if (res.response === 1) {
|
||||||
store.delete("windowSizeDetached");
|
store.delete('windowSizeDetached');
|
||||||
store.delete("windowSize");
|
store.delete('windowSize');
|
||||||
store.delete("windowPosition");
|
store.delete('windowPosition');
|
||||||
store.delete("fullScreen");
|
store.delete('fullScreen');
|
||||||
store.delete("detachedMode");
|
store.delete('detachedMode');
|
||||||
app.relaunch();
|
app.relaunch();
|
||||||
app.exit();
|
app.exit();
|
||||||
}
|
}
|
||||||
@@ -382,19 +401,19 @@ const getMenu = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "separator",
|
type: 'separator',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Quit",
|
label: 'Quit',
|
||||||
click: () => {
|
click: () => {
|
||||||
forceQuit = true;
|
forceQuit = true;
|
||||||
app.quit();
|
app.quit();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
};
|
}
|
||||||
|
|
||||||
const createMainWindow = (show = false) => {
|
function createMainWindow(show = false) {
|
||||||
window = new BrowserWindow({
|
window = new BrowserWindow({
|
||||||
width: 420,
|
width: 420,
|
||||||
height: 420,
|
height: 420,
|
||||||
@@ -411,87 +430,103 @@ const createMainWindow = (show = false) => {
|
|||||||
// window.webContents.openDevTools();
|
// window.webContents.openDevTools();
|
||||||
window.loadURL(indexFile);
|
window.loadURL(indexFile);
|
||||||
|
|
||||||
// open extenal links in default browser
|
// open external links in default browser
|
||||||
window.webContents.on("new-window", function (e, url) {
|
window.webContents.setWindowOpenHandler(({ url }) => {
|
||||||
e.preventDefault();
|
shell.openExternal(url);
|
||||||
require("electron").shell.openExternal(url);
|
return { action: 'deny' };
|
||||||
});
|
});
|
||||||
|
|
||||||
// hide scrollbar
|
// hide scrollbar
|
||||||
window.webContents.on("did-finish-load", function () {
|
window.webContents.on('did-finish-load', function () {
|
||||||
window.webContents.insertCSS(
|
window.webContents.insertCSS('::-webkit-scrollbar { display: none; } body { -webkit-user-select: none; }');
|
||||||
"::-webkit-scrollbar { display: none; } body { -webkit-user-select: none; }"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (store.get("detachedMode") && process.platform === "darwin") {
|
if (store.get('detachedMode') && process.platform === 'darwin') {
|
||||||
window.webContents.insertCSS("body { -webkit-app-region: drag; }");
|
window.webContents.insertCSS('body { -webkit-app-region: drag; }');
|
||||||
}
|
}
|
||||||
|
|
||||||
// let code = `document.addEventListener("mousemove", () => { ipcRenderer.send("mousemove"); });`;
|
// let code = `document.addEventListener('mousemove', () => { ipcRenderer.send('mousemove'); });`;
|
||||||
// window.webContents.executeJavaScript(code);
|
// window.webContents.executeJavaScript(code);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (store.get("detachedMode")) {
|
if (store.get('detachedMode')) {
|
||||||
if (store.has("windowPosition"))
|
if (store.has('windowPosition')) {
|
||||||
window.setSize(...store.get("windowSizeDetached"));
|
window.setSize(...store.get('windowSizeDetached'));
|
||||||
else store.set("windowPosition", window.getPosition());
|
} else {
|
||||||
if (store.has("windowSizeDetached"))
|
store.set('windowPosition', window.getPosition());
|
||||||
window.setPosition(...store.get("windowPosition"));
|
}
|
||||||
else store.set("windowSizeDetached", window.getSize());
|
|
||||||
|
if (store.has('windowSizeDetached')) {
|
||||||
|
window.setPosition(...store.get('windowPosition'));
|
||||||
|
} else {
|
||||||
|
store.set('windowSizeDetached', window.getSize());
|
||||||
|
}
|
||||||
|
} else if (store.has('windowSize')) {
|
||||||
|
window.setSize(...store.get('windowSize'));
|
||||||
} else {
|
} else {
|
||||||
if (store.has("windowSize")) window.setSize(...store.get("windowSize"));
|
store.set('windowSize', window.getSize());
|
||||||
else store.set("windowSize", window.getSize());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.on("resize", (e) => {
|
window.on('resize', (e) => {
|
||||||
// ignore resize event when using fullscreen mode
|
// ignore resize event when using fullscreen mode
|
||||||
if (window.isFullScreen()) return e;
|
if (window.isFullScreen()) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
if (!store.get("disableHover") || resizeEvent) {
|
if (!store.get('disableHover') || resizeEvent) {
|
||||||
store.set("disableHover", true);
|
store.set('disableHover', true);
|
||||||
resizeEvent = e;
|
resizeEvent = e;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (resizeEvent === e) {
|
if (resizeEvent === e) {
|
||||||
store.set("disableHover", false);
|
store.set('disableHover', false);
|
||||||
resizeEvent = false;
|
resizeEvent = false;
|
||||||
}
|
}
|
||||||
}, 600);
|
}, 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (store.get("detachedMode")) {
|
if (store.get('detachedMode')) {
|
||||||
store.set("windowSizeDetached", window.getSize());
|
store.set('windowSizeDetached', window.getSize());
|
||||||
} else {
|
} else {
|
||||||
if (process.platform !== "linux") changePosition();
|
if (process.platform !== 'linux') {
|
||||||
|
changePosition();
|
||||||
|
}
|
||||||
|
|
||||||
store.set("windowSize", window.getSize());
|
store.set('windowSize', window.getSize());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.on("move", () => {
|
window.on('move', () => {
|
||||||
if (store.get("detachedMode")) {
|
if (store.get('detachedMode')) {
|
||||||
store.set("windowPosition", window.getPosition());
|
store.set('windowPosition', window.getPosition());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.on("close", (e) => {
|
window.on('close', (e) => {
|
||||||
if (!forceQuit) {
|
if (!forceQuit) {
|
||||||
window.hide();
|
window.hide();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.on("blur", () => {
|
window.on('blur', () => {
|
||||||
if (!store.get("detachedMode") && !window.isAlwaysOnTop()) window.hide();
|
if (!store.get('detachedMode') && !window.isAlwaysOnTop()) {
|
||||||
|
window.hide();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
window.setAlwaysOnTop(!!store.get("stayOnTop"));
|
window.setAlwaysOnTop(!!store.get('stayOnTop'));
|
||||||
if (window.isAlwaysOnTop() || show) showWindow();
|
|
||||||
|
|
||||||
toggleFullScreen(!!store.get("fullScreen"));
|
if (window.isAlwaysOnTop() || show) {
|
||||||
};
|
showWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleFullScreen(!!store.get('fullScreen'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function showWindow() {
|
||||||
|
if (!store.get('detachedMode')) {
|
||||||
|
changePosition();
|
||||||
|
}
|
||||||
|
|
||||||
const showWindow = () => {
|
|
||||||
if (!store.get("detachedMode")) changePosition();
|
|
||||||
if (!window.isVisible()) {
|
if (!window.isVisible()) {
|
||||||
window.setVisibleOnAllWorkspaces(true); // put the window on all screens
|
window.setVisibleOnAllWorkspaces(true); // put the window on all screens
|
||||||
window.show();
|
window.show();
|
||||||
@@ -500,160 +535,189 @@ const showWindow = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const createTray = () => {
|
function createTray() {
|
||||||
tray = new Tray(
|
tray = new Tray(
|
||||||
["win32", "linux"].includes(process.platform)
|
['win32', 'linux'].includes(process.platform) ? `${__dirname}/assets/IconWin.png` : `${__dirname}/assets/IconTemplate.png`,
|
||||||
? `${__dirname}/assets/IconWin.png`
|
|
||||||
: `${__dirname}/assets/IconTemplate.png`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
tray.on("click", () => {
|
tray.on('click', () => {
|
||||||
if (window.isVisible()) window.hide();
|
if (window.isVisible()) {
|
||||||
else showWindow();
|
window.hide();
|
||||||
|
} else {
|
||||||
|
showWindow();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tray.on("right-click", () => {
|
tray.on('right-click', () => {
|
||||||
if (!store.get("detachedMode")) window.hide();
|
if (!store.get('detachedMode')) {
|
||||||
|
window.hide();
|
||||||
|
}
|
||||||
|
|
||||||
tray.popUpContextMenu(getMenu());
|
tray.popUpContextMenu(getMenu());
|
||||||
});
|
});
|
||||||
|
|
||||||
let timer = undefined;
|
let timer = undefined;
|
||||||
|
|
||||||
tray.on("mouse-move", (e) => {
|
tray.on('mouse-move', () => {
|
||||||
if (
|
if (store.get('detachedMode') || window.isAlwaysOnTop() || store.get('disableHover')) {
|
||||||
store.get("detachedMode") ||
|
|
||||||
window.isAlwaysOnTop() ||
|
|
||||||
store.get("disableHover")
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!window.isVisible()) {
|
if (!window.isVisible()) {
|
||||||
showWindow();
|
showWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timer) clearTimeout(timer);
|
if (timer) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
}
|
||||||
|
|
||||||
timer = setTimeout(() => {
|
timer = setTimeout(() => {
|
||||||
let mousePos = screen.getCursorScreenPoint();
|
let mousePos = screen.getCursorScreenPoint();
|
||||||
let trayBounds = tray.getBounds();
|
let trayBounds = tray.getBounds();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!(
|
!(mousePos.x >= trayBounds.x && mousePos.x <= trayBounds.x + trayBounds.width) ||
|
||||||
mousePos.x >= trayBounds.x &&
|
!(mousePos.y >= trayBounds.y && mousePos.y <= trayBounds.y + trayBounds.height)
|
||||||
mousePos.x <= trayBounds.x + trayBounds.width
|
|
||||||
) ||
|
|
||||||
!(
|
|
||||||
mousePos.y >= trayBounds.y &&
|
|
||||||
mousePos.y <= trayBounds.y + trayBounds.height
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
setWindowFocusTimer();
|
setWindowFocusTimer();
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
const setWindowFocusTimer = () => {
|
function setWindowFocusTimer() {
|
||||||
let timer = setTimeout(() => {
|
setTimeout(() => {
|
||||||
let mousePos = screen.getCursorScreenPoint();
|
let mousePos = screen.getCursorScreenPoint();
|
||||||
let windowPosition = window.getPosition();
|
let windowPosition = window.getPosition();
|
||||||
let windowSize = window.getSize();
|
let windowSize = window.getSize();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!resizeEvent &&
|
!resizeEvent &&
|
||||||
(!(
|
(
|
||||||
mousePos.x >= windowPosition[0] &&
|
!(mousePos.x >= windowPosition[ 0 ] && mousePos.x <= windowPosition[ 0 ] + windowSize[ 0 ]) ||
|
||||||
mousePos.x <= windowPosition[0] + windowSize[0]
|
!(mousePos.y >= windowPosition[ 1 ] && mousePos.y <= windowPosition[ 1 ] + windowSize[ 1 ])
|
||||||
) ||
|
)
|
||||||
!(
|
|
||||||
mousePos.y >= windowPosition[1] &&
|
|
||||||
mousePos.y <= windowPosition[1] + windowSize[1]
|
|
||||||
))
|
|
||||||
) {
|
) {
|
||||||
window.hide();
|
window.hide();
|
||||||
} else {
|
} else {
|
||||||
setWindowFocusTimer();
|
setWindowFocusTimer();
|
||||||
}
|
}
|
||||||
}, 110);
|
}, 110);
|
||||||
};
|
}
|
||||||
|
|
||||||
app.on("ready", async () => {
|
function toggleFullScreen(mode = !window.isFullScreen()) {
|
||||||
checkAutoStart();
|
store.set('fullScreen', mode);
|
||||||
|
window.setFullScreen(mode);
|
||||||
|
|
||||||
|
if (mode) {
|
||||||
|
window.setAlwaysOnTop(true);
|
||||||
|
} else {
|
||||||
|
window.setAlwaysOnTop(store.get('stayOnTop'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function currentInstance(url = null) {
|
||||||
|
if (url) {
|
||||||
|
store.set('currentInstance', store.get('allInstances').indexOf(url));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (store.has('currentInstance')) {
|
||||||
|
return store.get('allInstances')[ store.get('currentInstance') ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addInstance(url) {
|
||||||
|
if (!store.has('allInstances')) {
|
||||||
|
store.set('allInstances', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
let instances = store.get('allInstances');
|
||||||
|
|
||||||
|
if (instances.find((e) => e === url)) {
|
||||||
|
currentInstance(url);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// active hover by default after adding first instance
|
||||||
|
if (!instances.length) {
|
||||||
|
store.set('disableHover', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
instances.push(url);
|
||||||
|
store.set('allInstances', instances);
|
||||||
|
currentInstance(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showError(isError) {
|
||||||
|
if (!isError && window.webContents.getURL().includes('error.html')) {
|
||||||
|
window.loadURL(indexFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isError && currentInstance() && !window.webContents.getURL().includes('error.html')) {
|
||||||
|
window.loadURL(errorFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.on('ready', async () => {
|
||||||
useAutoUpdater();
|
useAutoUpdater();
|
||||||
|
checkAutoStart();
|
||||||
|
|
||||||
createTray();
|
createTray();
|
||||||
// workaround for initial window misplacement due to traybounds being incorrect
|
// workaround for initial window misplacement due to traybounds being incorrect
|
||||||
while (tray.getBounds().x === 0 && process.uptime() <= 1) {
|
while (tray.getBounds().x === 0 && process.uptime() <= 1) {
|
||||||
await delay(15);
|
await delay(15);
|
||||||
}
|
}
|
||||||
createMainWindow(!store.has("currentInstance"));
|
createMainWindow(!store.has('currentInstance'));
|
||||||
|
|
||||||
|
if (process.platform === 'linux') {
|
||||||
|
tray.setContextMenu(getMenu());
|
||||||
|
}
|
||||||
|
|
||||||
if (process.platform === "linux") tray.setContextMenu(getMenu());
|
|
||||||
startAvailabilityCheck();
|
startAvailabilityCheck();
|
||||||
|
|
||||||
// register shortcut
|
// register shortcut
|
||||||
if (store.get("shortcutEnabled")) registerKeyboardShortcut();
|
if (store.get('shortcutEnabled')) {
|
||||||
|
registerKeyboardShortcut();
|
||||||
|
}
|
||||||
|
|
||||||
globalShortcut.register("CommandOrControl+Alt+Return", () => {
|
globalShortcut.register('CommandOrControl+Alt+Return', () => {
|
||||||
toggleFullScreen();
|
toggleFullScreen();
|
||||||
});
|
});
|
||||||
|
|
||||||
// disable hover for first start
|
// disable hover for first start
|
||||||
if (!store.has("currentInstance")) store.set("disableHover", true);
|
if (!store.has('currentInstance')) {
|
||||||
|
store.set('disableHover', true);
|
||||||
|
}
|
||||||
|
|
||||||
// enable auto update by default
|
// enable auto update by default
|
||||||
if (!store.has("autoUpdate")) store.set("autoUpdate", true);
|
if (!store.has('autoUpdate')) {
|
||||||
|
store.set('autoUpdate', true);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.on("will-quit", () => {
|
app.on('will-quit', () => {
|
||||||
unregisterKeyboardShortcut();
|
unregisterKeyboardShortcut();
|
||||||
});
|
});
|
||||||
|
|
||||||
const toggleFullScreen = (mode = !window.isFullScreen()) => {
|
app.on('window-all-closed', () => {
|
||||||
store.set("fullScreen", mode);
|
if (process.platform !== 'darwin') {
|
||||||
window.setFullScreen(mode);
|
app.quit();
|
||||||
if (mode) window.setAlwaysOnTop(true);
|
}
|
||||||
else window.setAlwaysOnTop(store.get("stayOnTop"));
|
});
|
||||||
};
|
|
||||||
|
|
||||||
const currentInstance = (url = null) => {
|
ipcMain.on('get-instances', (event) => {
|
||||||
|
event.reply('get-instances', store.get('allInstances') || []);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcMain.on('ha-instance', (event, url) => {
|
||||||
if (url) {
|
if (url) {
|
||||||
store.set("currentInstance", store.get("allInstances").indexOf(url));
|
addInstance(url);
|
||||||
}
|
|
||||||
if (store.has("currentInstance")) {
|
|
||||||
return store.get("allInstances")[store.get("currentInstance")];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const addInstance = (url) => {
|
|
||||||
if (!store.has("allInstances")) store.set("allInstances", []);
|
|
||||||
let instances = store.get("allInstances");
|
|
||||||
if (instances.find((e) => e === url)) {
|
|
||||||
currentInstance(url);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// active hover by default after adding first instance
|
if (currentInstance()) {
|
||||||
if (!instances.length) store.set("disableHover", false);
|
event.reply('ha-instance', currentInstance());
|
||||||
|
}
|
||||||
instances.push(url);
|
|
||||||
store.set("allInstances", instances);
|
|
||||||
currentInstance(url);
|
|
||||||
};
|
|
||||||
|
|
||||||
const showError = (isError) => {
|
|
||||||
if (!isError && window.webContents.getURL().includes("error.html"))
|
|
||||||
window.loadURL(indexFile);
|
|
||||||
if (
|
|
||||||
isError &&
|
|
||||||
currentInstance() &&
|
|
||||||
!window.webContents.getURL().includes("error.html")
|
|
||||||
)
|
|
||||||
window.loadURL(errorFile);
|
|
||||||
};
|
|
||||||
|
|
||||||
ipcMain.on("get-instances", (event) => {
|
|
||||||
event.reply("get-instances", store.get("allInstances") || []);
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on("ha-instance", (event, url) => {
|
|
||||||
if (url) addInstance(url);
|
|
||||||
if (currentInstance()) event.reply("ha-instance", currentInstance());
|
|
||||||
});
|
});
|
||||||
|
|||||||
174
package-lock.json
generated
174
package-lock.json
generated
@@ -415,6 +415,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
},
|
},
|
||||||
|
"array-flatten": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ=="
|
||||||
|
},
|
||||||
"asar": {
|
"asar": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz",
|
||||||
@@ -510,6 +515,19 @@
|
|||||||
"bluebird": "^3.5.5"
|
"bluebird": "^3.5.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bonjour": {
|
||||||
|
"version": "3.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
|
||||||
|
"integrity": "sha512-RaVTblr+OnEli0r/ud8InrU7D+G0y6aJhlxaLa6Pwty4+xoxboF1BsUI45tujvRpbj9dQVoglChqonGAsjEBYg==",
|
||||||
|
"requires": {
|
||||||
|
"array-flatten": "^2.1.0",
|
||||||
|
"deep-equal": "^1.0.1",
|
||||||
|
"dns-equal": "^1.0.0",
|
||||||
|
"dns-txt": "^2.0.2",
|
||||||
|
"multicast-dns": "^6.0.1",
|
||||||
|
"multicast-dns-service-types": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"boolean": {
|
"boolean": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
|
||||||
@@ -602,6 +620,11 @@
|
|||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"buffer-indexof": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g=="
|
||||||
|
},
|
||||||
"builder-util": {
|
"builder-util": {
|
||||||
"version": "23.3.3",
|
"version": "23.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-23.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-23.3.3.tgz",
|
||||||
@@ -697,6 +720,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"call-bind": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
|
||||||
|
"requires": {
|
||||||
|
"function-bind": "^1.1.1",
|
||||||
|
"get-intrinsic": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"camelcase": {
|
"camelcase": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
|
||||||
@@ -954,6 +986,19 @@
|
|||||||
"mimic-response": "^1.0.0"
|
"mimic-response": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"deep-equal": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
|
||||||
|
"requires": {
|
||||||
|
"is-arguments": "^1.0.4",
|
||||||
|
"is-date-object": "^1.0.1",
|
||||||
|
"is-regex": "^1.0.4",
|
||||||
|
"object-is": "^1.0.1",
|
||||||
|
"object-keys": "^1.1.1",
|
||||||
|
"regexp.prototype.flags": "^1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"deep-extend": {
|
"deep-extend": {
|
||||||
"version": "0.6.0",
|
"version": "0.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||||
@@ -970,8 +1015,6 @@
|
|||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
|
||||||
"integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
|
"integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"has-property-descriptors": "^1.0.0",
|
"has-property-descriptors": "^1.0.0",
|
||||||
"object-keys": "^1.1.1"
|
"object-keys": "^1.1.1"
|
||||||
@@ -1083,6 +1126,28 @@
|
|||||||
"verror": "^1.10.0"
|
"verror": "^1.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dns-equal": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg=="
|
||||||
|
},
|
||||||
|
"dns-packet": {
|
||||||
|
"version": "1.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz",
|
||||||
|
"integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==",
|
||||||
|
"requires": {
|
||||||
|
"ip": "^1.1.0",
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dns-txt": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ==",
|
||||||
|
"requires": {
|
||||||
|
"buffer-indexof": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dot-prop": {
|
"dot-prop": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
|
||||||
@@ -1511,9 +1576,12 @@
|
|||||||
"function-bind": {
|
"function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||||
"dev": true,
|
},
|
||||||
"optional": true
|
"functions-have-names": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="
|
||||||
},
|
},
|
||||||
"get-caller-file": {
|
"get-caller-file": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
@@ -1525,8 +1593,6 @@
|
|||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
|
||||||
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
|
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"function-bind": "^1.1.1",
|
"function-bind": "^1.1.1",
|
||||||
"has": "^1.0.3",
|
"has": "^1.0.3",
|
||||||
@@ -1657,8 +1723,6 @@
|
|||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"function-bind": "^1.1.1"
|
"function-bind": "^1.1.1"
|
||||||
}
|
}
|
||||||
@@ -1673,8 +1737,6 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
|
||||||
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
|
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
|
||||||
"dev": true,
|
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"get-intrinsic": "^1.1.1"
|
"get-intrinsic": "^1.1.1"
|
||||||
}
|
}
|
||||||
@@ -1682,9 +1744,15 @@
|
|||||||
"has-symbols": {
|
"has-symbols": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
|
||||||
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
|
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
|
||||||
"dev": true,
|
},
|
||||||
"optional": true
|
"has-tostringtag": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
|
||||||
|
"requires": {
|
||||||
|
"has-symbols": "^1.0.2"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"has-yarn": {
|
"has-yarn": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
@@ -1789,6 +1857,20 @@
|
|||||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ip": {
|
||||||
|
"version": "1.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
|
||||||
|
"integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg=="
|
||||||
|
},
|
||||||
|
"is-arguments": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
|
||||||
|
"requires": {
|
||||||
|
"call-bind": "^1.0.2",
|
||||||
|
"has-tostringtag": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"is-ci": {
|
"is-ci": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
|
||||||
@@ -1798,6 +1880,14 @@
|
|||||||
"ci-info": "^3.2.0"
|
"ci-info": "^3.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-date-object": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
|
||||||
|
"requires": {
|
||||||
|
"has-tostringtag": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"is-fullwidth-code-point": {
|
"is-fullwidth-code-point": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||||
@@ -1831,6 +1921,15 @@
|
|||||||
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"is-regex": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
|
||||||
|
"requires": {
|
||||||
|
"call-bind": "^1.0.2",
|
||||||
|
"has-tostringtag": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"is-typedarray": {
|
"is-typedarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||||
@@ -2073,6 +2172,20 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
},
|
},
|
||||||
|
"multicast-dns": {
|
||||||
|
"version": "6.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
|
||||||
|
"integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
|
||||||
|
"requires": {
|
||||||
|
"dns-packet": "^1.3.1",
|
||||||
|
"thunky": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"multicast-dns-service-types": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ=="
|
||||||
|
},
|
||||||
"node-addon-api": {
|
"node-addon-api": {
|
||||||
"version": "1.7.2",
|
"version": "1.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
|
||||||
@@ -2097,12 +2210,19 @@
|
|||||||
"pify": "^3.0.0"
|
"pify": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"object-is": {
|
||||||
|
"version": "1.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
|
||||||
|
"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
|
||||||
|
"requires": {
|
||||||
|
"call-bind": "^1.0.2",
|
||||||
|
"define-properties": "^1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"object-keys": {
|
"object-keys": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"once": {
|
"once": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
@@ -2282,6 +2402,16 @@
|
|||||||
"lazy-val": "^1.0.4"
|
"lazy-val": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"regexp.prototype.flags": {
|
||||||
|
"version": "1.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
|
||||||
|
"integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
|
||||||
|
"requires": {
|
||||||
|
"call-bind": "^1.0.2",
|
||||||
|
"define-properties": "^1.1.3",
|
||||||
|
"functions-have-names": "^1.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"registry-auth-token": {
|
"registry-auth-token": {
|
||||||
"version": "4.2.2",
|
"version": "4.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz",
|
||||||
@@ -2353,6 +2483,11 @@
|
|||||||
"tslib": "^2.1.0"
|
"tslib": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||||
|
},
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
@@ -2588,6 +2723,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"thunky": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
|
||||||
|
},
|
||||||
"tmp": {
|
"tmp": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"auto-launch": "^5.0.5",
|
"auto-launch": "^5.0.5",
|
||||||
|
"bonjour": "^3.5.0",
|
||||||
"electron-log": "^4.4.8",
|
"electron-log": "^4.4.8",
|
||||||
"electron-store": "^8.1.0",
|
"electron-store": "^8.1.0",
|
||||||
"electron-traywindow-positioner": "^1.1.1",
|
"electron-traywindow-positioner": "^1.1.1",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
height: 80px;
|
height: 80px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-checkmark .check-icon {
|
.success-checkmark .check-icon {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
border: 4px solid #4caf50;
|
border: 4px solid #4caf50;
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-checkmark .check-icon::before {
|
.success-checkmark .check-icon::before {
|
||||||
top: 3px;
|
top: 3px;
|
||||||
left: -2px;
|
left: -2px;
|
||||||
@@ -22,6 +24,7 @@
|
|||||||
transform-origin: 100% 50%;
|
transform-origin: 100% 50%;
|
||||||
border-radius: 100px 0 0 100px;
|
border-radius: 100px 0 0 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-checkmark .check-icon::after {
|
.success-checkmark .check-icon::after {
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 30px;
|
left: 30px;
|
||||||
@@ -30,6 +33,7 @@
|
|||||||
border-radius: 0 100px 100px 0;
|
border-radius: 0 100px 100px 0;
|
||||||
animation: rotate-circle 4.25s ease-in;
|
animation: rotate-circle 4.25s ease-in;
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-checkmark .check-icon::before,
|
.success-checkmark .check-icon::before,
|
||||||
.success-checkmark .check-icon::after {
|
.success-checkmark .check-icon::after {
|
||||||
content: "";
|
content: "";
|
||||||
@@ -38,6 +42,7 @@
|
|||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
transform: rotate(-45deg);
|
transform: rotate(-45deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-checkmark .check-icon .icon-line {
|
.success-checkmark .check-icon .icon-line {
|
||||||
height: 5px;
|
height: 5px;
|
||||||
background-color: #4caf50;
|
background-color: #4caf50;
|
||||||
@@ -46,6 +51,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-checkmark .check-icon .icon-line.line-tip {
|
.success-checkmark .check-icon .icon-line.line-tip {
|
||||||
top: 46px;
|
top: 46px;
|
||||||
left: 14px;
|
left: 14px;
|
||||||
@@ -53,6 +59,7 @@
|
|||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
animation: icon-line-tip 0.75s;
|
animation: icon-line-tip 0.75s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-checkmark .check-icon .icon-line.line-long {
|
.success-checkmark .check-icon .icon-line.line-long {
|
||||||
top: 38px;
|
top: 38px;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
@@ -60,6 +67,7 @@
|
|||||||
transform: rotate(-45deg);
|
transform: rotate(-45deg);
|
||||||
animation: icon-line-long 0.75s;
|
animation: icon-line-long 0.75s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-checkmark .check-icon .icon-circle {
|
.success-checkmark .check-icon .icon-circle {
|
||||||
top: -4px;
|
top: -4px;
|
||||||
left: -4px;
|
left: -4px;
|
||||||
@@ -71,6 +79,7 @@
|
|||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
border: 4px solid rgba(76, 175, 80, 0.5);
|
border: 4px solid rgba(76, 175, 80, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.success-checkmark .check-icon .icon-fix {
|
.success-checkmark .check-icon .icon-fix {
|
||||||
top: 8px;
|
top: 8px;
|
||||||
width: 5px;
|
width: 5px;
|
||||||
@@ -96,6 +105,7 @@
|
|||||||
transform: rotate(-405deg);
|
transform: rotate(-405deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes icon-line-tip {
|
@keyframes icon-line-tip {
|
||||||
0% {
|
0% {
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -123,6 +133,7 @@
|
|||||||
top: 45px;
|
top: 45px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes icon-line-long {
|
@keyframes icon-line-long {
|
||||||
0% {
|
0% {
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -136,7 +147,7 @@
|
|||||||
}
|
}
|
||||||
84% {
|
84% {
|
||||||
width: 55px;
|
width: 55px;
|
||||||
right: 0px;
|
right: 0;
|
||||||
top: 35px;
|
top: 35px;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
|
|||||||
@@ -3,27 +3,33 @@ svg {
|
|||||||
display: block;
|
display: block;
|
||||||
margin: 40px auto 0;
|
margin: 40px auto 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.path {
|
.path {
|
||||||
stroke-dasharray: 1000;
|
stroke-dasharray: 1000;
|
||||||
stroke-dashoffset: 0;
|
stroke-dashoffset: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.path.circle {
|
.path.circle {
|
||||||
-webkit-animation: dash 0.9s ease-in-out;
|
-webkit-animation: dash 0.9s ease-in-out;
|
||||||
animation: dash 0.9s ease-in-out;
|
animation: dash 0.9s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.path.line {
|
.path.line {
|
||||||
stroke-dashoffset: 1000;
|
stroke-dashoffset: 1000;
|
||||||
-webkit-animation: dash 0.9s 0.35s ease-in-out forwards;
|
-webkit-animation: dash 0.9s 0.35s ease-in-out forwards;
|
||||||
animation: dash 0.9s 0.35s ease-in-out forwards;
|
animation: dash 0.9s 0.35s ease-in-out forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 20px 0 60px;
|
margin: 20px 0 60px;
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.error {
|
p.error {
|
||||||
color: #d06079;
|
color: #d06079;
|
||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes dash {
|
@-webkit-keyframes dash {
|
||||||
0% {
|
0% {
|
||||||
stroke-dashoffset: 1000;
|
stroke-dashoffset: 1000;
|
||||||
@@ -32,6 +38,7 @@ p.error {
|
|||||||
stroke-dashoffset: 0;
|
stroke-dashoffset: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes dash {
|
@keyframes dash {
|
||||||
0% {
|
0% {
|
||||||
stroke-dashoffset: 1000;
|
stroke-dashoffset: 1000;
|
||||||
|
|||||||
@@ -44,8 +44,7 @@ body {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
color: rgb(var(--pure-material-onprimary-rgb, 255, 255, 255));
|
color: rgb(var(--pure-material-onprimary-rgb, 255, 255, 255));
|
||||||
background-color: rgb(var(--pure-material-primary-rgb, 3, 169, 244));
|
background-color: rgb(var(--pure-material-primary-rgb, 3, 169, 244));
|
||||||
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14),
|
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||||
0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
|
||||||
font-family: var(
|
font-family: var(
|
||||||
--pure-material-font,
|
--pure-material-font,
|
||||||
"Roboto",
|
"Roboto",
|
||||||
@@ -100,8 +99,7 @@ body {
|
|||||||
/* Hover, Focus */
|
/* Hover, Focus */
|
||||||
.pure-material-button-contained:hover,
|
.pure-material-button-contained:hover,
|
||||||
.pure-material-button-contained:focus {
|
.pure-material-button-contained:focus {
|
||||||
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14),
|
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);
|
||||||
0 1px 10px 0 rgba(0, 0, 0, 0.12);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pure-material-button-contained:hover::before {
|
.pure-material-button-contained:hover::before {
|
||||||
@@ -118,8 +116,7 @@ body {
|
|||||||
|
|
||||||
/* Active */
|
/* Active */
|
||||||
.pure-material-button-contained:active {
|
.pure-material-button-contained:active {
|
||||||
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
|
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
||||||
0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pure-material-button-contained:active::after {
|
.pure-material-button-contained:active::after {
|
||||||
@@ -190,7 +187,7 @@ p {
|
|||||||
input {
|
input {
|
||||||
background: none;
|
background: none;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
padding: 10px 0px 10px 0px;
|
padding: 10px 0 10px 0;
|
||||||
display: block;
|
display: block;
|
||||||
width: 320px;
|
width: 320px;
|
||||||
border: none;
|
border: none;
|
||||||
@@ -234,9 +231,9 @@ label {
|
|||||||
content: "";
|
content: "";
|
||||||
height: 2px;
|
height: 2px;
|
||||||
width: 0;
|
width: 0;
|
||||||
bottom: 0px;
|
bottom: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: #03a9f4;
|
background: #03a9f4;
|
||||||
transition: 300ms ease all;
|
transition: 300ms ease all;
|
||||||
left: 0%;
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,65 +1,31 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Home Assistant</title>
|
<title>Home Assistant</title>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
<meta name="viewport" content="width=device-width,user-scalable=no"/>
|
||||||
<link href="assets/style.css" rel="stylesheet" />
|
<link href="assets/style.css" rel="stylesheet"/>
|
||||||
<link href="assets/error.css" rel="stylesheet" />
|
<link href="assets/error.css" rel="stylesheet"/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="vertical-center">
|
<div class="vertical-center">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<svg
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 130.2 130.2">
|
||||||
version="1.1"
|
<circle class="path circle" fill="none" stroke="#D06079" stroke-width="6" stroke-miterlimit="10" cx="65.1" cy="65.1" r="62.1"/>
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
<line class="path line" fill="none" stroke="#D06079" stroke-width="6" stroke-linecap="round" stroke-miterlimit="10" x1="34.4"
|
||||||
viewBox="0 0 130.2 130.2"
|
y1="37.9" x2="95.8" y2="92.3"/>
|
||||||
>
|
<line class="path line" fill="none" stroke="#D06079" stroke-width="6" stroke-linecap="round" stroke-miterlimit="10" x1="95.8"
|
||||||
<circle
|
y1="38" x2="34.4" y2="92.2"/>
|
||||||
class="path circle"
|
</svg>
|
||||||
fill="none"
|
|
||||||
stroke="#D06079"
|
|
||||||
stroke-width="6"
|
|
||||||
stroke-miterlimit="10"
|
|
||||||
cx="65.1"
|
|
||||||
cy="65.1"
|
|
||||||
r="62.1"
|
|
||||||
/>
|
|
||||||
<line
|
|
||||||
class="path line"
|
|
||||||
fill="none"
|
|
||||||
stroke="#D06079"
|
|
||||||
stroke-width="6"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-miterlimit="10"
|
|
||||||
x1="34.4"
|
|
||||||
y1="37.9"
|
|
||||||
x2="95.8"
|
|
||||||
y2="92.3"
|
|
||||||
/>
|
|
||||||
<line
|
|
||||||
class="path line"
|
|
||||||
fill="none"
|
|
||||||
stroke="#D06079"
|
|
||||||
stroke-width="6"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-miterlimit="10"
|
|
||||||
x1="95.8"
|
|
||||||
y1="38"
|
|
||||||
x2="34.4"
|
|
||||||
y2="92.2"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div class="center">
|
|
||||||
<p class="error">
|
|
||||||
Home Assistant instance is not available, please check your
|
|
||||||
connection.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
<div class="center">
|
||||||
|
<p class="error">
|
||||||
|
Home Assistant instance is not available, please check your connection.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
152
web/index.html
152
web/index.html
@@ -8,49 +8,60 @@
|
|||||||
<link href="assets/style.css" rel="stylesheet" />
|
<link href="assets/style.css" rel="stylesheet" />
|
||||||
<link href="assets/checkmark.css" rel="stylesheet" />
|
<link href="assets/checkmark.css" rel="stylesheet" />
|
||||||
<script>
|
<script>
|
||||||
const { ipcRenderer } = require("electron");
|
const { ipcRenderer } = require('electron');
|
||||||
const bonjour = require('bonjour')()
|
const bonjour = require('bonjour')()
|
||||||
|
|
||||||
function showInstance(url) {
|
function showInstance(url) {
|
||||||
document.getElementById('availableInstancesContainer').style.display = "block"
|
if (url === '') {
|
||||||
const button = document.createElement("button")
|
return;
|
||||||
button.onclick = () => addInstance(url)
|
}
|
||||||
button.classList.add("pure-material-button-contained")
|
|
||||||
button.textContent = url
|
document.getElementById('availableInstancesContainer').style.display = 'block';
|
||||||
document.getElementById('availableInstances').append(button)
|
const button = document.createElement('button');
|
||||||
|
button.onclick = () => addInstance(url);
|
||||||
|
button.classList.add('pure-material-button-contained');
|
||||||
|
button.textContent = url;
|
||||||
|
document.getElementById('availableInstances').append(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function (event) {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
setTimeout(() => document.getElementById('url').focus(), 300);
|
setTimeout(() => document.getElementById('url').focus(), 300);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.send("get-instances");
|
ipcRenderer.send('get-instances');
|
||||||
ipcRenderer.on("get-instances", (event, result) => {
|
ipcRenderer.on('get-instances', (event, result) => {
|
||||||
let instances = result
|
let instances = result;
|
||||||
|
|
||||||
bonjour.find({ type: 'home-assistant' }, instance => {
|
bonjour.find({type: 'home-assistant'}, instance => {
|
||||||
if (instances.indexOf(instance.txt.internal_url) === -1) showInstance(instance.txt.internal_url)
|
if (instance.txt.internal_url && instances.indexOf(instance.txt.internal_url) === -1) {
|
||||||
if (instances.indexOf(instance.txt.external_url) === -1) showInstance(instance.txt.external_url)
|
showInstance(instance.txt.internal_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance.txt.external_url && instances.indexOf(instance.txt.external_url) === -1) {
|
||||||
|
showInstance(instance.txt.external_url);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function addInstance(url) {
|
function addInstance(url) {
|
||||||
ipcRenderer.send("ha-instance", url);
|
ipcRenderer.send('ha-instance', url);
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcRenderer.send("ha-instance");
|
ipcRenderer.send('ha-instance');
|
||||||
|
|
||||||
let showCheckmark = false;
|
let showCheckmark = false;
|
||||||
|
|
||||||
ipcRenderer.on("ha-instance", function (event, url) {
|
ipcRenderer.on('ha-instance', function (event, url) {
|
||||||
if (showCheckmark) {
|
if (showCheckmark) {
|
||||||
document
|
document
|
||||||
.getElementById("check-wrapper")
|
.getElementById('check-wrapper')
|
||||||
.addEventListener(
|
.addEventListener(
|
||||||
"animationend",
|
'animationend',
|
||||||
() => (window.location.href = url)
|
() => (window.location.href = url)
|
||||||
);
|
);
|
||||||
} else window.location.href = url;
|
} else {
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function isValidUrl(string) {
|
function isValidUrl(string) {
|
||||||
@@ -59,79 +70,84 @@
|
|||||||
} catch (_) {
|
} catch (_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkUrl() {
|
function checkUrl() {
|
||||||
const url = document.getElementById("url").value;
|
const url = document.getElementById('url').value;
|
||||||
|
|
||||||
if (!isValidUrl(url)) {
|
if (!isValidUrl(url)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch(url + "/auth/providers")
|
fetch(`${url}/auth/providers`)
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (!data.includes('homeassistant')) return;
|
if (!data.includes('homeassistant')) {
|
||||||
document.getElementById("url").value = url;
|
return;
|
||||||
document.getElementById("url").disabled = true;
|
}
|
||||||
document.getElementById("check-wrapper").style.display = "block";
|
|
||||||
document.getElementById("url-wrapper").style.display = "none";
|
document.getElementById('url').value = url;
|
||||||
|
document.getElementById('url').disabled = true;
|
||||||
|
document.getElementById('check-wrapper').style.display = 'block';
|
||||||
|
document.getElementById('url-wrapper').style.display = 'none';
|
||||||
showCheckmark = true;
|
showCheckmark = true;
|
||||||
ipcRenderer.send("ha-instance", url);
|
ipcRenderer.send('ha-instance', url);
|
||||||
}).catch((err) => { });
|
}).catch((_) => {
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showPlaceholder(status = true) {
|
function showPlaceholder(status = true) {
|
||||||
if (status) document.getElementById("url").placeholder = 'e.g. http://hassio.local:8123';
|
if (status) document.getElementById('url').placeholder = 'e.g. http://hassio.local:8123';
|
||||||
else document.getElementById("url").placeholder = '';
|
else document.getElementById('url').placeholder = '';
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="center header">
|
<div class="center header">
|
||||||
<img src="assets/favicon.png" height="52" /> Home Assistant
|
<img src="assets/favicon.png" height="52"/> Home Assistant
|
||||||
</div>
|
</div>
|
||||||
<div id="availableInstancesContainer" style="display:none;">
|
<div id="availableInstancesContainer" style="display:none;">
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<p>Available Instances: </p>
|
<p>Available Instances: </p>
|
||||||
</div>
|
|
||||||
<div class="center">
|
|
||||||
<div id="availableInstances">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="center" style="margin-top: 30px;">
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<div id="check-wrapper" class="success-checkmark">
|
<div id="availableInstances">
|
||||||
<div class="check-icon">
|
|
||||||
<span class="icon-line line-tip"></span>
|
|
||||||
<span class="icon-line line-long"></span>
|
|
||||||
<div class="icon-circle"></div>
|
|
||||||
<div class="icon-fix"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="url-wrapper" class="group">
|
|
||||||
<input type="url" required="required" id="url" onblur="showPlaceholder(false)" onfocus="showPlaceholder()"
|
|
||||||
onkeyup="checkUrl()" />
|
|
||||||
<span class="highlight"></span>
|
|
||||||
<span class="bar"></span>
|
|
||||||
<label>Home Assistant URL</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="center">
|
|
||||||
<p>
|
|
||||||
<small class="grey">Your URL is checked and you will be forwarded to Home Assistant automatically.</small>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="center" style="margin-top: 30px;">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="center">
|
||||||
|
<div id="check-wrapper" class="success-checkmark">
|
||||||
|
<div class="check-icon">
|
||||||
|
<span class="icon-line line-tip"></span>
|
||||||
|
<span class="icon-line line-long"></span>
|
||||||
|
<div class="icon-circle"></div>
|
||||||
|
<div class="icon-fix"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="url-wrapper" class="group">
|
||||||
|
<input type="url" required="required" id="url" onblur="showPlaceholder(false)" onfocus="showPlaceholder()"
|
||||||
|
onkeyup="checkUrl()" />
|
||||||
|
<span class="highlight"></span>
|
||||||
|
<span class="bar"></span>
|
||||||
|
<label for="url">Home Assistant URL</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="center">
|
||||||
|
<p>
|
||||||
|
<small class="grey">Your URL is checked and you will be forwarded to Home Assistant automatically.</small>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user