mirror of
https://github.com/sascha-hemi/homeassistant-desktop.git
synced 2026-03-21 02:04:23 +01:00
refactor: Refactors the code
This commit is contained in:
652
app.js
652
app.js
@@ -9,23 +9,13 @@ const {
|
||||
Menu,
|
||||
Tray,
|
||||
BrowserWindow,
|
||||
} = require("electron");
|
||||
const { autoUpdater } = require("electron-updater");
|
||||
const AutoLaunch = require("auto-launch");
|
||||
const Positioner = require("electron-traywindow-positioner");
|
||||
const Store = require("electron-store");
|
||||
const bonjour = require("bonjour")();
|
||||
} = require('electron');
|
||||
const { autoUpdater } = require('electron-updater');
|
||||
const AutoLaunch = require('auto-launch');
|
||||
const Positioner = require('electron-traywindow-positioner');
|
||||
const Store = require('electron-store');
|
||||
const bonjour = require('bonjour')();
|
||||
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;
|
||||
|
||||
@@ -33,16 +23,20 @@ app.allowRendererProcessReuse = true;
|
||||
if (!app.requestSingleInstanceLock()) {
|
||||
app.quit();
|
||||
} else {
|
||||
app.on("second-instance", () => {
|
||||
if (window) showWindow();
|
||||
app.on('second-instance', () => {
|
||||
if (window) {
|
||||
showWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// hide dock icon on macOS
|
||||
if (process.platform === "darwin") app.dock.hide();
|
||||
if (process.platform === 'darwin') {
|
||||
app.dock.hide();
|
||||
}
|
||||
|
||||
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 errorFile = `file://${__dirname}/web/error.html`;
|
||||
@@ -51,25 +45,43 @@ let autostartEnabled = false;
|
||||
let forceQuit = false;
|
||||
let resizeEvent = false;
|
||||
|
||||
const useAutoUpdater = () => {
|
||||
autoUpdater.on("error", (message) => {
|
||||
console.error("There was a problem updating the application");
|
||||
function registerKeyboardShortcut() {
|
||||
globalShortcut.register('CommandOrControl+Alt+X', () => {
|
||||
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);
|
||||
});
|
||||
|
||||
autoUpdater.on("update-downloaded", () => {
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
forceQuit = true;
|
||||
autoUpdater.quitAndInstall();
|
||||
});
|
||||
|
||||
setInterval(() => {
|
||||
if (store.get("autoUpdate")) autoUpdater.checkForUpdates();
|
||||
if (store.get('autoUpdate')) {
|
||||
autoUpdater.checkForUpdates();
|
||||
}
|
||||
}, 1000 * 60 * 60);
|
||||
|
||||
if (store.get("autoUpdate")) autoUpdater.checkForUpdates();
|
||||
};
|
||||
if (store.get('autoUpdate')) {
|
||||
autoUpdater.checkForUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
const checkAutoStart = () => {
|
||||
function checkAutoStart() {
|
||||
autoLauncher
|
||||
.isEnabled()
|
||||
.then((isEnabled) => {
|
||||
@@ -78,23 +90,31 @@ const checkAutoStart = () => {
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
const startAvailabilityCheck = () => {
|
||||
setInterval(() => {
|
||||
function startAvailabilityCheck() {
|
||||
let interval;
|
||||
|
||||
function availabilityCheck() {
|
||||
const request = net.request(`${currentInstance()}/auth/providers`);
|
||||
request.on("response", (response) => {
|
||||
request.on('response', (response) => {
|
||||
showError(response.statusCode !== 200);
|
||||
});
|
||||
request.on("error", (error) => {
|
||||
request.on('error', (error) => {
|
||||
clearInterval(interval);
|
||||
showError(true);
|
||||
if (store.get("automaticSwitching")) checkForAvailableInstance();
|
||||
|
||||
if (store.get('automaticSwitching')) {
|
||||
checkForAvailableInstance();
|
||||
}
|
||||
});
|
||||
request.end();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
interval = setInterval(availabilityCheck, 3000);
|
||||
};
|
||||
|
||||
const changePosition = () => {
|
||||
function changePosition() {
|
||||
const trayBounds = tray.getBounds();
|
||||
const windowBounds = window.getBounds();
|
||||
const displayWorkArea = screen.getDisplayNearestPoint({
|
||||
@@ -103,77 +123,62 @@ const changePosition = () => {
|
||||
}).workArea;
|
||||
const taskBarPosition = Positioner.getTaskbarPosition(trayBounds);
|
||||
|
||||
if (taskBarPosition == "top" || taskBarPosition == "bottom") {
|
||||
if (taskBarPosition === 'top' || taskBarPosition === 'bottom') {
|
||||
const alignment = {
|
||||
x: "center",
|
||||
y: taskBarPosition == "top" ? "up" : "down",
|
||||
x: 'center',
|
||||
y: taskBarPosition === 'top' ? 'up' : 'down',
|
||||
};
|
||||
if (
|
||||
trayBounds.x + (trayBounds.width + windowBounds.width) / 2 <
|
||||
displayWorkArea.width
|
||||
)
|
||||
|
||||
if (trayBounds.x + (trayBounds.width + windowBounds.width) / 2 < displayWorkArea.width) {
|
||||
Positioner.position(window, trayBounds, alignment);
|
||||
else {
|
||||
const { y } = Positioner.calculate(
|
||||
window.getBounds(),
|
||||
trayBounds,
|
||||
alignment
|
||||
);
|
||||
} else {
|
||||
const { y } = Positioner.calculate(window.getBounds(), trayBounds, alignment);
|
||||
|
||||
window.setPosition(
|
||||
displayWorkArea.width - windowBounds.width + displayWorkArea.x,
|
||||
y + (taskBarPosition == "bottom" && displayWorkArea.y),
|
||||
false
|
||||
y + (taskBarPosition === 'bottom' && displayWorkArea.y),
|
||||
false,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const alignment = { x: taskBarPosition, y: "center" };
|
||||
if (
|
||||
trayBounds.y + (trayBounds.height + windowBounds.height) / 2 <
|
||||
displayWorkArea.height
|
||||
) {
|
||||
const { x, y } = Positioner.calculate(
|
||||
window.getBounds(),
|
||||
trayBounds,
|
||||
alignment
|
||||
);
|
||||
window.setPosition(
|
||||
x + (taskBarPosition == "right" && displayWorkArea.x),
|
||||
y
|
||||
);
|
||||
const alignment = {
|
||||
x: taskBarPosition,
|
||||
y: 'center',
|
||||
};
|
||||
|
||||
if (trayBounds.y + (trayBounds.height + windowBounds.height) / 2 < displayWorkArea.height) {
|
||||
const { x, y } = Positioner.calculate(window.getBounds(), trayBounds, alignment);
|
||||
window.setPosition(x + (taskBarPosition === 'right' && displayWorkArea.x), y);
|
||||
} else {
|
||||
const { x } = Positioner.calculate(
|
||||
window.getBounds(),
|
||||
trayBounds,
|
||||
alignment
|
||||
);
|
||||
window.setPosition(
|
||||
x,
|
||||
displayWorkArea.y + displayWorkArea.height - windowBounds.height,
|
||||
false
|
||||
);
|
||||
const { x } = Positioner.calculate(window.getBounds(), 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) {
|
||||
bonjour.find({ type: "home-assistant" }, (instance) => {
|
||||
if (instances.indexOf(instance.txt.internal_url) !== -1)
|
||||
bonjour.find({ type: 'home-assistant' }, (instance) => {
|
||||
if (instance.txt.internal_url && instances.indexOf(instance.txt.internal_url) !== -1) {
|
||||
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);
|
||||
}
|
||||
});
|
||||
let found;
|
||||
for (let instance of instances.filter((e) => e.url !== currentInstance())) {
|
||||
const request = net.request(`${instance}/auth/providers`);
|
||||
request.on("response", (response) => {
|
||||
request.on('response', (response) => {
|
||||
if (response.statusCode === 200) {
|
||||
found = instance;
|
||||
}
|
||||
});
|
||||
request.on("error", (error) => {});
|
||||
request.on('error', (_) => {
|
||||
});
|
||||
request.end();
|
||||
|
||||
if (found) {
|
||||
@@ -182,29 +187,29 @@ const checkForAvailableInstance = () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const getMenu = () => {
|
||||
function getMenu() {
|
||||
let instancesMenu = [
|
||||
{
|
||||
label: "Open in Browser",
|
||||
label: 'Open in Browser',
|
||||
enabled: currentInstance(),
|
||||
click: () => {
|
||||
shell.openExternal(currentInstance());
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "separator",
|
||||
type: 'separator',
|
||||
},
|
||||
];
|
||||
|
||||
const allInstances = store.get("allInstances");
|
||||
const allInstances = store.get('allInstances');
|
||||
|
||||
if (allInstances) {
|
||||
allInstances.forEach((e) => {
|
||||
instancesMenu.push({
|
||||
label: e,
|
||||
type: "checkbox",
|
||||
type: 'checkbox',
|
||||
checked: currentInstance() === e,
|
||||
click: () => {
|
||||
currentInstance(e);
|
||||
@@ -216,137 +221,150 @@ const getMenu = () => {
|
||||
|
||||
instancesMenu.push(
|
||||
{
|
||||
type: "separator",
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
label: "Add another Instance...",
|
||||
label: 'Add another Instance...',
|
||||
click: () => {
|
||||
store.delete("currentInstance");
|
||||
store.delete('currentInstance');
|
||||
window.loadURL(indexFile);
|
||||
window.show();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Automatic Switching",
|
||||
type: "checkbox",
|
||||
enabled:
|
||||
store.has("allInstances") && store.get("allInstances").length > 1,
|
||||
checked: store.get("automaticSwitching"),
|
||||
label: 'Automatic Switching',
|
||||
type: 'checkbox',
|
||||
enabled: store.has('allInstances') && store.get('allInstances').length > 1,
|
||||
checked: store.get('automaticSwitching'),
|
||||
click: () => {
|
||||
store.set("automaticSwitching", !store.get("automaticSwitching"));
|
||||
store.set('automaticSwitching', !store.get('automaticSwitching'));
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
instancesMenu.push({ label: "Not Connected...", enabled: false });
|
||||
instancesMenu.push({ label: 'Not Connected...', enabled: false });
|
||||
}
|
||||
|
||||
return Menu.buildFromTemplate([
|
||||
{
|
||||
label: "Show/Hide Window",
|
||||
visible: process.platform === "linux",
|
||||
label: 'Show/Hide Window',
|
||||
visible: process.platform === 'linux',
|
||||
click: () => {
|
||||
if (window.isVisible()) window.hide();
|
||||
else showWindow();
|
||||
if (window.isVisible()) {
|
||||
window.hide();
|
||||
} else {
|
||||
showWindow();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
visible: process.platform === "linux",
|
||||
type: "separator",
|
||||
visible: process.platform === 'linux',
|
||||
type: 'separator',
|
||||
},
|
||||
...instancesMenu,
|
||||
{
|
||||
type: "separator",
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
label: "Hover to Show",
|
||||
visible: process.platform !== "linux" && !store.get("detachedMode"),
|
||||
enabled: !store.get("detachedMode"),
|
||||
type: "checkbox",
|
||||
checked: !store.get("disableHover"),
|
||||
label: 'Hover to Show',
|
||||
visible: process.platform !== 'linux' && !store.get('detachedMode'),
|
||||
enabled: !store.get('detachedMode'),
|
||||
type: 'checkbox',
|
||||
checked: !store.get('disableHover'),
|
||||
click: () => {
|
||||
store.set("disableHover", !store.get("disableHover"));
|
||||
store.set('disableHover', !store.get('disableHover'));
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Stay on Top",
|
||||
type: "checkbox",
|
||||
checked: store.get("stayOnTop"),
|
||||
label: 'Stay on Top',
|
||||
type: 'checkbox',
|
||||
checked: store.get('stayOnTop'),
|
||||
click: () => {
|
||||
store.set("stayOnTop", !store.get("stayOnTop"));
|
||||
window.setAlwaysOnTop(store.get("stayOnTop"));
|
||||
if (window.isAlwaysOnTop()) showWindow();
|
||||
store.set('stayOnTop', !store.get('stayOnTop'));
|
||||
window.setAlwaysOnTop(store.get('stayOnTop'));
|
||||
|
||||
if (window.isAlwaysOnTop()) {
|
||||
showWindow();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Start at Login",
|
||||
type: "checkbox",
|
||||
label: 'Start at Login',
|
||||
type: 'checkbox',
|
||||
checked: autostartEnabled,
|
||||
click: () => {
|
||||
if (autostartEnabled) autoLauncher.disable();
|
||||
else autoLauncher.enable();
|
||||
if (autostartEnabled) {
|
||||
autoLauncher.disable();
|
||||
} else {
|
||||
autoLauncher.enable();
|
||||
}
|
||||
|
||||
checkAutoStart();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: `Enable Shortcut`,
|
||||
type: "checkbox",
|
||||
accelerator: "CommandOrControl+Alt+X",
|
||||
checked: store.get("shortcutEnabled"),
|
||||
label: 'Enable Shortcut',
|
||||
type: 'checkbox',
|
||||
accelerator: 'CommandOrControl+Alt+X',
|
||||
checked: store.get('shortcutEnabled'),
|
||||
click: () => {
|
||||
store.set("shortcutEnabled", !store.get("shortcutEnabled"));
|
||||
if (store.get("shortcutEnabled")) registerKeyboardShortcut();
|
||||
else unregisterKeyboardShortcut();
|
||||
store.set('shortcutEnabled', !store.get('shortcutEnabled'));
|
||||
|
||||
if (store.get('shortcutEnabled')) {
|
||||
registerKeyboardShortcut();
|
||||
} else {
|
||||
unregisterKeyboardShortcut();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "separator",
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
label: "Use detached Window",
|
||||
type: "checkbox",
|
||||
checked: store.get("detachedMode"),
|
||||
label: 'Use detached Window',
|
||||
type: 'checkbox',
|
||||
checked: store.get('detachedMode'),
|
||||
click: () => {
|
||||
store.set("detachedMode", !store.get("detachedMode"));
|
||||
store.set('detachedMode', !store.get('detachedMode'));
|
||||
window.hide();
|
||||
createMainWindow(store.get("detachedMode"));
|
||||
createMainWindow(store.get('detachedMode'));
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Use Fullscreen",
|
||||
type: "checkbox",
|
||||
checked: store.get("fullScreen"),
|
||||
accelerator: "CommandOrControl+Alt+Return",
|
||||
label: 'Use Fullscreen',
|
||||
type: 'checkbox',
|
||||
checked: store.get('fullScreen'),
|
||||
accelerator: 'CommandOrControl+Alt+Return',
|
||||
click: () => {
|
||||
toggleFullScreen();
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "separator",
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
label: `v${app.getVersion()}`,
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
label: "Automatic Updates",
|
||||
type: "checkbox",
|
||||
checked: store.get("autoUpdate"),
|
||||
label: 'Automatic Updates',
|
||||
type: 'checkbox',
|
||||
checked: store.get('autoUpdate'),
|
||||
click: () => {
|
||||
store.set("autoUpdate", !store.get("autoUpdate"));
|
||||
store.set('autoUpdate', !store.get('autoUpdate'));
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Open on github.com",
|
||||
label: 'Open on github.com',
|
||||
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: () => {
|
||||
window.reload();
|
||||
window.show();
|
||||
@@ -354,12 +372,12 @@ const getMenu = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Reset Application...",
|
||||
label: 'Reset Application...',
|
||||
click: () => {
|
||||
dialog
|
||||
.showMessageBox({
|
||||
message: "Are you sure you want to reset Home Assistant Desktop?",
|
||||
buttons: ["Reset Everything!", "Reset Windows", "Cancel"],
|
||||
message: 'Are you sure you want to reset Home Assistant Desktop?',
|
||||
buttons: ['Reset Everything!', 'Reset Windows', 'Cancel'],
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.response === 0) {
|
||||
@@ -369,12 +387,13 @@ const getMenu = () => {
|
||||
app.relaunch();
|
||||
app.exit();
|
||||
}
|
||||
|
||||
if (res.response === 1) {
|
||||
store.delete("windowSizeDetached");
|
||||
store.delete("windowSize");
|
||||
store.delete("windowPosition");
|
||||
store.delete("fullScreen");
|
||||
store.delete("detachedMode");
|
||||
store.delete('windowSizeDetached');
|
||||
store.delete('windowSize');
|
||||
store.delete('windowPosition');
|
||||
store.delete('fullScreen');
|
||||
store.delete('detachedMode');
|
||||
app.relaunch();
|
||||
app.exit();
|
||||
}
|
||||
@@ -382,19 +401,19 @@ const getMenu = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "separator",
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
label: "Quit",
|
||||
label: 'Quit',
|
||||
click: () => {
|
||||
forceQuit = true;
|
||||
app.quit();
|
||||
},
|
||||
},
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
const createMainWindow = (show = false) => {
|
||||
function createMainWindow(show = false) {
|
||||
window = new BrowserWindow({
|
||||
width: 420,
|
||||
height: 420,
|
||||
@@ -411,87 +430,103 @@ const createMainWindow = (show = false) => {
|
||||
// window.webContents.openDevTools();
|
||||
window.loadURL(indexFile);
|
||||
|
||||
// open extenal links in default browser
|
||||
window.webContents.on("new-window", function (e, url) {
|
||||
e.preventDefault();
|
||||
require("electron").shell.openExternal(url);
|
||||
// open external links in default browser
|
||||
window.webContents.setWindowOpenHandler(({ url }) => {
|
||||
shell.openExternal(url);
|
||||
return { action: 'deny' };
|
||||
});
|
||||
|
||||
// hide scrollbar
|
||||
window.webContents.on("did-finish-load", function () {
|
||||
window.webContents.insertCSS(
|
||||
"::-webkit-scrollbar { display: none; } body { -webkit-user-select: none; }"
|
||||
);
|
||||
window.webContents.on('did-finish-load', function () {
|
||||
window.webContents.insertCSS('::-webkit-scrollbar { display: none; } body { -webkit-user-select: none; }');
|
||||
|
||||
if (store.get("detachedMode") && process.platform === "darwin") {
|
||||
window.webContents.insertCSS("body { -webkit-app-region: drag; }");
|
||||
if (store.get('detachedMode') && process.platform === 'darwin') {
|
||||
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);
|
||||
});
|
||||
|
||||
if (store.get("detachedMode")) {
|
||||
if (store.has("windowPosition"))
|
||||
window.setSize(...store.get("windowSizeDetached"));
|
||||
else store.set("windowPosition", window.getPosition());
|
||||
if (store.has("windowSizeDetached"))
|
||||
window.setPosition(...store.get("windowPosition"));
|
||||
else store.set("windowSizeDetached", window.getSize());
|
||||
if (store.get('detachedMode')) {
|
||||
if (store.has('windowPosition')) {
|
||||
window.setSize(...store.get('windowSizeDetached'));
|
||||
} else {
|
||||
store.set('windowPosition', window.getPosition());
|
||||
}
|
||||
|
||||
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 {
|
||||
if (store.has("windowSize")) window.setSize(...store.get("windowSize"));
|
||||
else store.set("windowSize", window.getSize());
|
||||
store.set('windowSize', window.getSize());
|
||||
}
|
||||
|
||||
window.on("resize", (e) => {
|
||||
window.on('resize', (e) => {
|
||||
// ignore resize event when using fullscreen mode
|
||||
if (window.isFullScreen()) return e;
|
||||
if (window.isFullScreen()) {
|
||||
return e;
|
||||
}
|
||||
|
||||
if (!store.get("disableHover") || resizeEvent) {
|
||||
store.set("disableHover", true);
|
||||
if (!store.get('disableHover') || resizeEvent) {
|
||||
store.set('disableHover', true);
|
||||
resizeEvent = e;
|
||||
setTimeout(() => {
|
||||
if (resizeEvent === e) {
|
||||
store.set("disableHover", false);
|
||||
store.set('disableHover', false);
|
||||
resizeEvent = false;
|
||||
}
|
||||
}, 600);
|
||||
}
|
||||
|
||||
if (store.get("detachedMode")) {
|
||||
store.set("windowSizeDetached", window.getSize());
|
||||
if (store.get('detachedMode')) {
|
||||
store.set('windowSizeDetached', window.getSize());
|
||||
} else {
|
||||
if (process.platform !== "linux") changePosition();
|
||||
if (process.platform !== 'linux') {
|
||||
changePosition();
|
||||
}
|
||||
|
||||
store.set("windowSize", window.getSize());
|
||||
store.set('windowSize', window.getSize());
|
||||
}
|
||||
});
|
||||
|
||||
window.on("move", () => {
|
||||
if (store.get("detachedMode")) {
|
||||
store.set("windowPosition", window.getPosition());
|
||||
window.on('move', () => {
|
||||
if (store.get('detachedMode')) {
|
||||
store.set('windowPosition', window.getPosition());
|
||||
}
|
||||
});
|
||||
|
||||
window.on("close", (e) => {
|
||||
window.on('close', (e) => {
|
||||
if (!forceQuit) {
|
||||
window.hide();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
window.on("blur", () => {
|
||||
if (!store.get("detachedMode") && !window.isAlwaysOnTop()) window.hide();
|
||||
window.on('blur', () => {
|
||||
if (!store.get('detachedMode') && !window.isAlwaysOnTop()) {
|
||||
window.hide();
|
||||
}
|
||||
});
|
||||
|
||||
window.setAlwaysOnTop(!!store.get("stayOnTop"));
|
||||
if (window.isAlwaysOnTop() || show) showWindow();
|
||||
window.setAlwaysOnTop(!!store.get('stayOnTop'));
|
||||
|
||||
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()) {
|
||||
window.setVisibleOnAllWorkspaces(true); // put the window on all screens
|
||||
window.show();
|
||||
@@ -500,160 +535,189 @@ const showWindow = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const createTray = () => {
|
||||
function createTray() {
|
||||
tray = new Tray(
|
||||
["win32", "linux"].includes(process.platform)
|
||||
? `${__dirname}/assets/IconWin.png`
|
||||
: `${__dirname}/assets/IconTemplate.png`
|
||||
['win32', 'linux'].includes(process.platform) ? `${__dirname}/assets/IconWin.png` : `${__dirname}/assets/IconTemplate.png`,
|
||||
);
|
||||
|
||||
tray.on("click", () => {
|
||||
if (window.isVisible()) window.hide();
|
||||
else showWindow();
|
||||
tray.on('click', () => {
|
||||
if (window.isVisible()) {
|
||||
window.hide();
|
||||
} else {
|
||||
showWindow();
|
||||
}
|
||||
});
|
||||
|
||||
tray.on("right-click", () => {
|
||||
if (!store.get("detachedMode")) window.hide();
|
||||
tray.on('right-click', () => {
|
||||
if (!store.get('detachedMode')) {
|
||||
window.hide();
|
||||
}
|
||||
|
||||
tray.popUpContextMenu(getMenu());
|
||||
});
|
||||
|
||||
let timer = undefined;
|
||||
|
||||
tray.on("mouse-move", (e) => {
|
||||
if (
|
||||
store.get("detachedMode") ||
|
||||
window.isAlwaysOnTop() ||
|
||||
store.get("disableHover")
|
||||
) {
|
||||
tray.on('mouse-move', () => {
|
||||
if (store.get('detachedMode') || window.isAlwaysOnTop() || store.get('disableHover')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!window.isVisible()) {
|
||||
showWindow();
|
||||
}
|
||||
|
||||
if (timer) clearTimeout(timer);
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
|
||||
timer = setTimeout(() => {
|
||||
let mousePos = screen.getCursorScreenPoint();
|
||||
let trayBounds = tray.getBounds();
|
||||
|
||||
if (
|
||||
!(
|
||||
mousePos.x >= trayBounds.x &&
|
||||
mousePos.x <= trayBounds.x + trayBounds.width
|
||||
) ||
|
||||
!(
|
||||
mousePos.y >= trayBounds.y &&
|
||||
mousePos.y <= trayBounds.y + trayBounds.height
|
||||
)
|
||||
!(mousePos.x >= trayBounds.x && mousePos.x <= trayBounds.x + trayBounds.width) ||
|
||||
!(mousePos.y >= trayBounds.y && mousePos.y <= trayBounds.y + trayBounds.height)
|
||||
) {
|
||||
setWindowFocusTimer();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
const setWindowFocusTimer = () => {
|
||||
let timer = setTimeout(() => {
|
||||
function setWindowFocusTimer() {
|
||||
setTimeout(() => {
|
||||
let mousePos = screen.getCursorScreenPoint();
|
||||
let windowPosition = window.getPosition();
|
||||
let windowSize = window.getSize();
|
||||
|
||||
if (
|
||||
!resizeEvent &&
|
||||
(!(
|
||||
mousePos.x >= windowPosition[0] &&
|
||||
mousePos.x <= windowPosition[0] + windowSize[0]
|
||||
) ||
|
||||
!(
|
||||
mousePos.y >= windowPosition[1] &&
|
||||
mousePos.y <= windowPosition[1] + windowSize[1]
|
||||
))
|
||||
(
|
||||
!(mousePos.x >= windowPosition[ 0 ] && mousePos.x <= windowPosition[ 0 ] + windowSize[ 0 ]) ||
|
||||
!(mousePos.y >= windowPosition[ 1 ] && mousePos.y <= windowPosition[ 1 ] + windowSize[ 1 ])
|
||||
)
|
||||
) {
|
||||
window.hide();
|
||||
} else {
|
||||
setWindowFocusTimer();
|
||||
}
|
||||
}, 110);
|
||||
};
|
||||
}
|
||||
|
||||
app.on("ready", async () => {
|
||||
checkAutoStart();
|
||||
function toggleFullScreen(mode = !window.isFullScreen()) {
|
||||
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();
|
||||
checkAutoStart();
|
||||
|
||||
createTray();
|
||||
// workaround for initial window misplacement due to traybounds being incorrect
|
||||
while (tray.getBounds().x === 0 && process.uptime() <= 1) {
|
||||
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();
|
||||
|
||||
// register shortcut
|
||||
if (store.get("shortcutEnabled")) registerKeyboardShortcut();
|
||||
if (store.get('shortcutEnabled')) {
|
||||
registerKeyboardShortcut();
|
||||
}
|
||||
|
||||
globalShortcut.register("CommandOrControl+Alt+Return", () => {
|
||||
globalShortcut.register('CommandOrControl+Alt+Return', () => {
|
||||
toggleFullScreen();
|
||||
});
|
||||
|
||||
// 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
|
||||
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();
|
||||
});
|
||||
|
||||
const toggleFullScreen = (mode = !window.isFullScreen()) => {
|
||||
store.set("fullScreen", mode);
|
||||
window.setFullScreen(mode);
|
||||
if (mode) window.setAlwaysOnTop(true);
|
||||
else window.setAlwaysOnTop(store.get("stayOnTop"));
|
||||
};
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
const currentInstance = (url = null) => {
|
||||
ipcMain.on('get-instances', (event) => {
|
||||
event.reply('get-instances', store.get('allInstances') || []);
|
||||
});
|
||||
|
||||
ipcMain.on('ha-instance', (event, url) => {
|
||||
if (url) {
|
||||
store.set("currentInstance", store.get("allInstances").indexOf(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;
|
||||
addInstance(url);
|
||||
}
|
||||
|
||||
// active hover by default after adding first instance
|
||||
if (!instances.length) store.set("disableHover", false);
|
||||
|
||||
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());
|
||||
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",
|
||||
"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": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz",
|
||||
@@ -510,6 +515,19 @@
|
||||
"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": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
|
||||
@@ -602,6 +620,11 @@
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"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": {
|
||||
"version": "23.3.3",
|
||||
"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": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
|
||||
@@ -954,6 +986,19 @@
|
||||
"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": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
@@ -970,8 +1015,6 @@
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
|
||||
"integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"has-property-descriptors": "^1.0.0",
|
||||
"object-keys": "^1.1.1"
|
||||
@@ -1083,6 +1126,28 @@
|
||||
"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": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
|
||||
@@ -1511,9 +1576,12 @@
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
},
|
||||
"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": {
|
||||
"version": "2.0.5",
|
||||
@@ -1525,8 +1593,6 @@
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
|
||||
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
@@ -1657,8 +1723,6 @@
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
@@ -1673,8 +1737,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
|
||||
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.1.1"
|
||||
}
|
||||
@@ -1682,9 +1744,15 @@
|
||||
"has-symbols": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
|
||||
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
|
||||
},
|
||||
"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": {
|
||||
"version": "2.1.0",
|
||||
@@ -1789,6 +1857,20 @@
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||
"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": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
|
||||
@@ -1798,6 +1880,14 @@
|
||||
"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": {
|
||||
"version": "3.0.0",
|
||||
"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==",
|
||||
"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": {
|
||||
"version": "1.0.0",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
|
||||
@@ -2097,12 +2210,19 @@
|
||||
"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": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
@@ -2282,6 +2402,16 @@
|
||||
"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": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz",
|
||||
@@ -2353,6 +2483,11 @@
|
||||
"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": {
|
||||
"version": "2.1.2",
|
||||
"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": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"auto-launch": "^5.0.5",
|
||||
"bonjour": "^3.5.0",
|
||||
"electron-log": "^4.4.8",
|
||||
"electron-store": "^8.1.0",
|
||||
"electron-traywindow-positioner": "^1.1.1",
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
height: 80px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
@@ -15,6 +16,7 @@
|
||||
box-sizing: content-box;
|
||||
border: 4px solid #4caf50;
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon::before {
|
||||
top: 3px;
|
||||
left: -2px;
|
||||
@@ -22,6 +24,7 @@
|
||||
transform-origin: 100% 50%;
|
||||
border-radius: 100px 0 0 100px;
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon::after {
|
||||
top: 0;
|
||||
left: 30px;
|
||||
@@ -30,6 +33,7 @@
|
||||
border-radius: 0 100px 100px 0;
|
||||
animation: rotate-circle 4.25s ease-in;
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon::before,
|
||||
.success-checkmark .check-icon::after {
|
||||
content: "";
|
||||
@@ -38,6 +42,7 @@
|
||||
background: #ffffff;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon .icon-line {
|
||||
height: 5px;
|
||||
background-color: #4caf50;
|
||||
@@ -46,6 +51,7 @@
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon .icon-line.line-tip {
|
||||
top: 46px;
|
||||
left: 14px;
|
||||
@@ -53,6 +59,7 @@
|
||||
transform: rotate(45deg);
|
||||
animation: icon-line-tip 0.75s;
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon .icon-line.line-long {
|
||||
top: 38px;
|
||||
right: 8px;
|
||||
@@ -60,6 +67,7 @@
|
||||
transform: rotate(-45deg);
|
||||
animation: icon-line-long 0.75s;
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon .icon-circle {
|
||||
top: -4px;
|
||||
left: -4px;
|
||||
@@ -71,6 +79,7 @@
|
||||
box-sizing: content-box;
|
||||
border: 4px solid rgba(76, 175, 80, 0.5);
|
||||
}
|
||||
|
||||
.success-checkmark .check-icon .icon-fix {
|
||||
top: 8px;
|
||||
width: 5px;
|
||||
@@ -96,6 +105,7 @@
|
||||
transform: rotate(-405deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes icon-line-tip {
|
||||
0% {
|
||||
width: 0;
|
||||
@@ -123,6 +133,7 @@
|
||||
top: 45px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes icon-line-long {
|
||||
0% {
|
||||
width: 0;
|
||||
@@ -136,7 +147,7 @@
|
||||
}
|
||||
84% {
|
||||
width: 55px;
|
||||
right: 0px;
|
||||
right: 0;
|
||||
top: 35px;
|
||||
}
|
||||
100% {
|
||||
|
||||
@@ -3,27 +3,33 @@ svg {
|
||||
display: block;
|
||||
margin: 40px auto 0;
|
||||
}
|
||||
|
||||
.path {
|
||||
stroke-dasharray: 1000;
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
|
||||
.path.circle {
|
||||
-webkit-animation: dash 0.9s ease-in-out;
|
||||
animation: dash 0.9s ease-in-out;
|
||||
}
|
||||
|
||||
.path.line {
|
||||
stroke-dashoffset: 1000;
|
||||
-webkit-animation: dash 0.9s 0.35s ease-in-out forwards;
|
||||
animation: dash 0.9s 0.35s ease-in-out forwards;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
margin: 20px 0 60px;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
p.error {
|
||||
color: #d06079;
|
||||
}
|
||||
|
||||
@-webkit-keyframes dash {
|
||||
0% {
|
||||
stroke-dashoffset: 1000;
|
||||
@@ -32,6 +38,7 @@ p.error {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dash {
|
||||
0% {
|
||||
stroke-dashoffset: 1000;
|
||||
|
||||
@@ -44,8 +44,7 @@ body {
|
||||
text-overflow: ellipsis;
|
||||
color: rgb(var(--pure-material-onprimary-rgb, 255, 255, 255));
|
||||
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),
|
||||
0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||
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);
|
||||
font-family: var(
|
||||
--pure-material-font,
|
||||
"Roboto",
|
||||
@@ -100,8 +99,7 @@ body {
|
||||
/* Hover, Focus */
|
||||
.pure-material-button-contained:hover,
|
||||
.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),
|
||||
0 1px 10px 0 rgba(0, 0, 0, 0.12);
|
||||
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);
|
||||
}
|
||||
|
||||
.pure-material-button-contained:hover::before {
|
||||
@@ -118,8 +116,7 @@ body {
|
||||
|
||||
/* Active */
|
||||
.pure-material-button-contained:active {
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
.pure-material-button-contained:active::after {
|
||||
@@ -190,7 +187,7 @@ p {
|
||||
input {
|
||||
background: none;
|
||||
font-size: 18px;
|
||||
padding: 10px 0px 10px 0px;
|
||||
padding: 10px 0 10px 0;
|
||||
display: block;
|
||||
width: 320px;
|
||||
border: none;
|
||||
@@ -234,9 +231,9 @@ label {
|
||||
content: "";
|
||||
height: 2px;
|
||||
width: 0;
|
||||
bottom: 0px;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
background: #03a9f4;
|
||||
transition: 300ms ease all;
|
||||
left: 0%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
@@ -1,65 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Home Assistant</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||
<link href="assets/style.css" rel="stylesheet" />
|
||||
<link href="assets/error.css" rel="stylesheet" />
|
||||
</head>
|
||||
<head>
|
||||
<title>Home Assistant</title>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no"/>
|
||||
<link href="assets/style.css" rel="stylesheet"/>
|
||||
<link href="assets/error.css" rel="stylesheet"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="vertical-center">
|
||||
<div class="content">
|
||||
<div class="center">
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 130.2 130.2"
|
||||
>
|
||||
<circle
|
||||
class="path circle"
|
||||
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>
|
||||
<body>
|
||||
<div class="vertical-center">
|
||||
<div class="content">
|
||||
<div class="center">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 130.2 130.2">
|
||||
<circle class="path circle" 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>
|
||||
</body>
|
||||
<div class="center">
|
||||
<p class="error">
|
||||
Home Assistant instance is not available, please check your connection.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
152
web/index.html
152
web/index.html
@@ -8,49 +8,60 @@
|
||||
<link href="assets/style.css" rel="stylesheet" />
|
||||
<link href="assets/checkmark.css" rel="stylesheet" />
|
||||
<script>
|
||||
const { ipcRenderer } = require("electron");
|
||||
const { ipcRenderer } = require('electron');
|
||||
const bonjour = require('bonjour')()
|
||||
|
||||
function showInstance(url) {
|
||||
document.getElementById('availableInstancesContainer').style.display = "block"
|
||||
const button = document.createElement("button")
|
||||
button.onclick = () => addInstance(url)
|
||||
button.classList.add("pure-material-button-contained")
|
||||
button.textContent = url
|
||||
document.getElementById('availableInstances').append(button)
|
||||
if (url === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById('availableInstancesContainer').style.display = 'block';
|
||||
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);
|
||||
});
|
||||
|
||||
ipcRenderer.send("get-instances");
|
||||
ipcRenderer.on("get-instances", (event, result) => {
|
||||
let instances = result
|
||||
ipcRenderer.send('get-instances');
|
||||
ipcRenderer.on('get-instances', (event, result) => {
|
||||
let instances = result;
|
||||
|
||||
bonjour.find({ type: 'home-assistant' }, instance => {
|
||||
if (instances.indexOf(instance.txt.internal_url) === -1) showInstance(instance.txt.internal_url)
|
||||
if (instances.indexOf(instance.txt.external_url) === -1) showInstance(instance.txt.external_url)
|
||||
bonjour.find({type: 'home-assistant'}, instance => {
|
||||
if (instance.txt.internal_url && instances.indexOf(instance.txt.internal_url) === -1) {
|
||||
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) {
|
||||
ipcRenderer.send("ha-instance", url);
|
||||
ipcRenderer.send('ha-instance', url);
|
||||
}
|
||||
|
||||
ipcRenderer.send("ha-instance");
|
||||
ipcRenderer.send('ha-instance');
|
||||
|
||||
let showCheckmark = false;
|
||||
|
||||
ipcRenderer.on("ha-instance", function (event, url) {
|
||||
ipcRenderer.on('ha-instance', function (event, url) {
|
||||
if (showCheckmark) {
|
||||
document
|
||||
.getElementById("check-wrapper")
|
||||
.getElementById('check-wrapper')
|
||||
.addEventListener(
|
||||
"animationend",
|
||||
'animationend',
|
||||
() => (window.location.href = url)
|
||||
);
|
||||
} else window.location.href = url;
|
||||
} else {
|
||||
window.location.href = url;
|
||||
}
|
||||
});
|
||||
|
||||
function isValidUrl(string) {
|
||||
@@ -59,79 +70,84 @@
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkUrl() {
|
||||
const url = document.getElementById("url").value;
|
||||
const url = document.getElementById('url').value;
|
||||
|
||||
if (!isValidUrl(url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(url + "/auth/providers")
|
||||
fetch(`${url}/auth/providers`)
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
if (!data.includes('homeassistant')) return;
|
||||
document.getElementById("url").value = url;
|
||||
document.getElementById("url").disabled = true;
|
||||
document.getElementById("check-wrapper").style.display = "block";
|
||||
document.getElementById("url-wrapper").style.display = "none";
|
||||
if (!data.includes('homeassistant')) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
ipcRenderer.send("ha-instance", url);
|
||||
}).catch((err) => { });
|
||||
ipcRenderer.send('ha-instance', url);
|
||||
}).catch((_) => {
|
||||
});
|
||||
}
|
||||
|
||||
function showPlaceholder(status = true) {
|
||||
if (status) document.getElementById("url").placeholder = 'e.g. http://hassio.local:8123';
|
||||
else document.getElementById("url").placeholder = '';
|
||||
if (status) document.getElementById('url').placeholder = 'e.g. http://hassio.local:8123';
|
||||
else document.getElementById('url').placeholder = '';
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<div class="center header">
|
||||
<img src="assets/favicon.png" height="52" /> Home Assistant
|
||||
</div>
|
||||
<div id="availableInstancesContainer" style="display:none;">
|
||||
<div class="center">
|
||||
<p>Available Instances: </p>
|
||||
</div>
|
||||
<div class="center">
|
||||
<div id="availableInstances">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="center" style="margin-top: 30px;">
|
||||
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<div class="center header">
|
||||
<img src="assets/favicon.png" height="52"/> Home Assistant
|
||||
</div>
|
||||
<div id="availableInstancesContainer" style="display:none;">
|
||||
<div class="center">
|
||||
<p>Available Instances: </p>
|
||||
</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 id="availableInstances">
|
||||
</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 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>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user