release v1.3.0

fixes #4
fixes #5
fixes #6
fixes #7
may fix #3

added:
- availability check / error page
- auto switching to next available instance for multiple instances

+ linting / formatting
This commit is contained in:
mrvnklm
2020-08-12 22:56:01 +02:00
parent 634ab476a3
commit 9c93cab40e
12 changed files with 1151 additions and 873 deletions

View File

@@ -3,7 +3,7 @@ name: Build/release
on:
push:
tags:
- '*'
- "*"
jobs:
release:
@@ -30,6 +30,8 @@ jobs:
# (No need to define this secret in the repo settings)
github_token: ${{ secrets.github_token }}
args: "--ia32"
mac_certs: ${{ secrets.mac_certs }}
mac_certs_password: ${{ secrets.mac_certs_password }}

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
node_modules
dist
.idea
.DS_Store

View File

@@ -1,19 +1,26 @@
# Home Assistant - Desktop
Desktop App (Windows / macOS) for [Home Assistant](https://www.home-assistant.io/) built with [Electron](https://www.electronjs.org/)
![Home Assistant - Desktop](https://raw.githubusercontent.com/mrvnklm/homeassistant-desktop/master/media/screenshot.png)
## Installation
Just download the latest version for your platform from the [Releases Section](https://github.com/mrvnklm/homeassistant-desktop/releases) to install Home Assistant
Desktop App (Windows / macOS) for [Home Assistant](https://www.home-assistant.io/) built with [Electron](https://www.electronjs.org)
## Usage
- Click the tray icon to open Home Assistant
- Right-Click to open context menu and change some settings / reset / quit the app
- Updates are installed automatically if a new version is available (restart required)
![Home Assistant - Desktop](https://raw.githubusercontent.com/mrvnklm/homeassistant-desktop/master/media/screenshot.png)
## Installation
Just download the latest version for your platform from the [releases section](https://github.com/mrvnklm/homeassistant-desktop/releases) to install Home Assistant
## Usage / Features
- hover / click the tray icon to open the app
- supports multiple instances of Home Assistant (including automatic switching)
- right-click to open context menu and change some settings / reset / quit the app
- updates are installed automatically if a new version is available (restart required)
## License
Home Assistant Desktop is open-source and [Apache 2](https://choosealicense.com/licenses/apache-2.0/) licensed
## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
I like coffee, so if you feel like buying one for me - go ahead!

422
app.js
View File

@@ -1,196 +1,265 @@
const {app, Menu, Tray, dialog, ipcMain, BrowserWindow, shell, screen} = require('electron');
const {autoUpdater} = require('electron-updater');
const AutoLaunch = require('auto-launch');
const Positioner = require('electron-traywindow-positioner');
const Store = require('electron-store');
const {
app,
dialog,
ipcMain,
shell,
screen,
net,
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");
app.allowRendererProcessReuse = true;
// prevent multiple instances
if (!app.requestSingleInstanceLock()) {
app.quit()
app.quit();
} else {
app.on('second-instance', () => {
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`;
let autostartEnabled = false;
let forceQuit = false;
let resizeEvent = false;
const useAutoUpdater = () => {
autoUpdater.on('error', message => {
console.error('There was a problem updating the application');
console.error(message)
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(() => {
autoUpdater.checkForUpdates();
}, 1000 * 60 * 30);
}, 1000 * 60 * 60);
autoUpdater.checkForUpdates();
};
const checkAutoStart = () => {
autoLauncher.isEnabled().then((isEnabled) => {
autoLauncher
.isEnabled()
.then((isEnabled) => {
autostartEnabled = isEnabled;
}).catch((err) => {
console.error(err)
})
.catch((err) => {
console.error(err);
});
};
const startAvailabilityCheck = () => {
setInterval(() => {
const request = net.request(`${currentInstance()}/auth/providers`);
request.on("response", (response) => {
showError(response.statusCode !== 200);
});
request.on("error", (error) => {
showError(true);
if (store.get("automaticSwitching")) checkForAvailableInstance();
});
request.end();
}, 3000);
};
const checkForAvailableInstance = () => {
const instances = store.get("allInstances");
if (instances && instances.length > 1) {
instances
.filter((e) => e.url !== currentInstance())
.forEach((e) => {
const request = net.request(`${e}/auth/providers`);
request.on("response", (response) => {
if (response.statusCode === 200) currentInstance(e);
});
request.on("error", (error) => {});
request.end();
});
}
};
const getMenu = () => {
let instancesMenu = [{
label: 'Open in Browser',
let instancesMenu = [
{
label: "Open in Browser",
enabled: currentInstance(),
click: () => {
shell.openExternal(currentInstance())
}
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);
window.loadURL(e);
window.show();
}
},
});
});
instancesMenu.push(
{
type: 'separator'
type: "separator",
},
{
label: 'Add another Instance...', click: () => {
store.delete('currentInstance');
label: "Add another Instance...",
click: () => {
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"),
click: () => {
store.set("automaticSwitching", store.get("automaticSwitching"));
},
}
}
)
);
} else {
instancesMenu.push({label: 'Not Connected...', enabled: false})
instancesMenu.push({ label: "Not Connected...", enabled: false });
}
return Menu.buildFromTemplate([...instancesMenu,
return Menu.buildFromTemplate([
...instancesMenu,
{
type: 'separator'
type: "separator",
},
{
label: 'Hover to Show',
enabled: !store.get('detachedMode'),
type: 'checkbox',
checked: !store.get('disableHover'),
label: "Hover to Show",
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',
label: "Stay on Top",
type: "checkbox",
checked: window.isAlwaysOnTop(),
click: () => {
window.setAlwaysOnTop(!window.isAlwaysOnTop());
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();
checkAutoStart()
}
}, {
type: 'separator'
if (autostartEnabled) autoLauncher.disable();
else autoLauncher.enable();
checkAutoStart();
},
},
{
label: 'Use detached Window',
type: 'checkbox',
checked: store.get('detachedMode'),
type: "separator",
},
{
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"));
},
},
{
type: 'separator'
type: "separator",
},
{
label: `v${app.getVersion()} (Auto Update)`,
enabled: false
enabled: false,
},
{
label: 'Open on github.com',
label: "Open on github.com",
click: () => {
shell.openExternal('https://github.com/mrvnklm/homeassistant-desktop')
}
shell.openExternal("https://github.com/mrvnklm/homeassistant-desktop");
},
},
{
type: 'separator'
type: "separator",
},
{
label: 'Reload Window',
label: "Reload Window",
click: () => {
window.reload();
}
},
},
{
label: 'Reset Settings...',
label: "Reset Application...",
click: () => {
dialog.showMessageBox({
message: 'Are you sure you want to reset Home Assistant Desktop?',
buttons: ['Cancel', 'OK, Reset!']
}).then((res) => {
if (res.response === 1) {
dialog
.showMessageBox({
message: "Are you sure you want to reset Home Assistant Desktop?",
buttons: ["Reset Everything!", "Reset Windows", "Cancel"],
})
.then((res) => {
if (res.response === 0) {
store.clear();
window.webContents.session.clearCache();
window.webContents.session.clearStorageData();
app.relaunch();
app.exit();
}
})
if (res.response === 1) {
store.delete("windowSizeDetached");
store.delete("windowSize");
store.delete("windowPosition");
app.relaunch();
app.exit();
}
});
},
},
{
type: 'separator'
type: "separator",
},
{
label: 'Quit',
accelerator: 'Cmd+Q',
label: "Quit",
click: () => {
forceQuit = true;
app.quit();
}
}
])
},
},
]);
};
const createMainWindow = (show = false) => {
@@ -202,147 +271,216 @@ const createMainWindow = (show = false) => {
autoHideMenuBar: true,
frame: false,
webPreferences: {
nodeIntegration: true
}
nodeIntegration: true,
},
});
// window.webContents.openDevTools();
window.loadURL(indexFile);
window.webContents.on('did-finish-load', function () {
window.webContents.insertCSS('::-webkit-scrollbar { display: none; } body { -webkit-user-select: none; }');
if (store.get('detachedMode')) {
window.webContents.insertCSS('body { -webkit-app-region: drag; }');
// open extenal links in default browser
window.webContents.on("new-window", function (e, url) {
e.preventDefault();
require("electron").shell.openExternal(url);
});
// hide scrollbar
window.webContents.on("did-finish-load", function () {
window.webContents.insertCSS(
"::-webkit-scrollbar { display: none; } body { -webkit-user-select: none; }"
);
if (store.get("detachedMode")) {
window.webContents.insertCSS("body { -webkit-app-region: drag; }");
}
});
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 store.set('windowSize', window.getSize())
if (store.has("windowSize")) window.setSize(...store.get("windowSize"));
else store.set("windowSize", window.getSize());
}
window.on('resize', () => {
if (store.get('detachedMode')) {
store.set('windowSizeDetached', window.getSize());
window.on("resize", (e) => {
if (!store.get("disableHover") || resizeEvent) {
store.set("disableHover", true);
resizeEvent = e;
setTimeout(() => {
if (resizeEvent === e) {
store.set("disableHover", false);
resizeEvent = false;
}
}, 600);
}
if (store.get("detachedMode")) {
store.set("windowSizeDetached", window.getSize());
} else {
Positioner.position(window, tray.getBounds());
store.set('windowSize', window.getSize());
}
});
window.on('move', () => {
if (store.get('detachedMode')) {
store.set('windowPosition', window.getPosition())
store.set("windowSize", window.getSize());
}
});
window.on('close', (e) => {
window.on("move", () => {
if (store.get("detachedMode")) {
store.set("windowPosition", window.getPosition());
}
});
window.on("close", (e) => {
if (!forceQuit) {
window.hide();
e.preventDefault()
e.preventDefault();
}
});
window.on('blur', () => {
if (!store.get('detachedMode') && !window.isAlwaysOnTop()) window.hide();
window.on("blur", () => {
if (!store.get("detachedMode") && !window.isAlwaysOnTop()) window.hide();
});
if (show) showWindow();
};
const showWindow = () => {
if (!store.get('detachedMode')) Positioner.position(window, tray.getBounds());
if (!store.get("detachedMode")) Positioner.position(window, tray.getBounds());
if (!window.isVisible()) {
window.setVisibleOnAllWorkspaces(true); // put the window on all screens
window.show();
window.focus();
window.setVisibleOnAllWorkspaces(false); // disable all screen behavior
}
};
const createTray = () => {
tray = new Tray(process.platform === 'win32' ? `${__dirname}/assets/IconWin.png` : `${__dirname}/assets/IconTemplate.png`);
tray = new Tray(
process.platform === "win32"
? `${__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.popUpContextMenu(getMenu())
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", (e) => {
if (
store.get("detachedMode") ||
window.isAlwaysOnTop() ||
store.get("disableHover")
) {
return;
}
if (!window.isVisible()) {
showWindow();
}
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)) {
setWindowFocusTimer()
if (
!(
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(() => {
let mousePos = screen.getCursorScreenPoint();
let windowPosition = window.getPosition();
let windowSize = window.getSize();
if (!(mousePos.x >= windowPosition[0] && mousePos.x <= windowPosition[0] + windowSize[0]) || !(mousePos.y >= windowPosition[1] && mousePos.y <= windowPosition[1] + windowSize[1])) {
if (
!resizeEvent &&
(!(
mousePos.x >= windowPosition[0] &&
mousePos.x <= windowPosition[0] + windowSize[0]
) ||
!(
mousePos.y >= windowPosition[1] &&
mousePos.y <= windowPosition[1] + windowSize[1]
))
) {
window.hide();
} else {
setWindowFocusTimer()
setWindowFocusTimer();
}
}, 110)
}, 110);
};
app.on('ready', () => {
// temporary migration of instances to avoid breaking active instance
if (store.has('instance')) {
store.set('allInstances', [store.get('instance').url]);
store.set('currentInstance', 0);
store.delete('instance');
}
app.on("ready", () => {
checkAutoStart();
useAutoUpdater();
createTray();
createMainWindow(!store.has('currentInstance'));
createMainWindow(!store.has("currentInstance"));
startAvailabilityCheck();
// disable hover for first start
if (!store.has("currentInstance")) {
store.set("disableHover", true);
}
});
const currentInstance = (url = null) => {
if (url) {
store.set('currentInstance', store.get('allInstances').indexOf(url));
store.set("currentInstance", store.get("allInstances").indexOf(url));
}
if (store.has('currentInstance')) {
return store.get('allInstances')[store.get('currentInstance')];
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)) {
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)
store.set("allInstances", instances);
currentInstance(url);
};
ipcMain.on('ha-instance', (event, args) => {
if (args) addInstance(args.url);
console.log(currentInstance());
if (currentInstance()) event.reply('ha-instance', currentInstance())
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("ha-instance", (event, url) => {
if (url) addInstance(url);
if (currentInstance()) event.reply("ha-instance", currentInstance());
});

326
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "homeassistant-desktop",
"version": "1.0.0",
"version": "1.2.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -93,23 +93,23 @@
"dev": true
},
"@types/fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==",
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.1.tgz",
"integrity": "sha512-B42Sxuaz09MhC3DDeW5kubRcQ5by4iuVQ0cRRWM2lggLzAa/KVom0Aft/208NgMvNQQZ86s5rVcqDdn/SH0/mg==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/node": {
"version": "14.0.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.1.tgz",
"integrity": "sha512-FAYBGwC+W6F9+huFIDtn43cpy7+SzG+atzRiTfdp3inUKL2hXnd4rG8hylJLIh4+hqrQy1P17kvJByE/z825hA=="
"version": "14.0.27",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz",
"integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g=="
},
"@types/semver": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.2.0.tgz",
"integrity": "sha512-TbB0A8ACUWZt3Y6bQPstW9QNbhNeebdgLX4T/ZfkrswAfUzRiXrgd9seol+X379Wa589Pu4UEx9Uok0D4RjRCQ==",
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.1.tgz",
"integrity": "sha512-ooD/FJ8EuwlDKOI6D9HWxgIgJjMg2cuziXm/42npDC8y4NjxplBUn9loewZiBNCt44450lHAU0OSb51/UqXeag==",
"requires": {
"@types/node": "*"
}
@@ -130,9 +130,9 @@
"dev": true
},
"ajv": {
"version": "6.12.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
"integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
"version": "6.12.3",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz",
"integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -141,9 +141,9 @@
}
},
"ajv-keywords": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz",
"integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==",
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"dev": true
},
"ansi-align": {
@@ -185,32 +185,32 @@
}
},
"app-builder-bin": {
"version": "3.5.8",
"resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.5.8.tgz",
"integrity": "sha512-ni3q7QTfQNWHNWuyn5x3FZu6GnQZv+TFnfgk5++svqleKEhHGqS1mIaKsh7x5pBX6NFXU3/+ktk98wA/AW4EXw==",
"version": "3.5.9",
"resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.5.9.tgz",
"integrity": "sha512-NSjtqZ3x2kYiDp3Qezsgukx/AUzKPr3Xgf9by4cYt05ILWGAptepeeu0Uv+7MO+41o6ujhLixTou8979JGg2Kg==",
"dev": true
},
"app-builder-lib": {
"version": "22.6.0",
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.6.0.tgz",
"integrity": "sha512-ky2aLYy92U+Gh6dKq/e8/bNmCotp6/GMhnX8tDZPv9detLg9WuBnWWi1ktBPlpbl1DREusy+TIh+9rgvfduQoA==",
"version": "22.8.0",
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.8.0.tgz",
"integrity": "sha512-RGaIRjCUrqkmh6QOGsyekQPEOaVynHfmeh8JZuyUymFYUOFdzBbPamkA2nhBVBTkkgfjRHsxK7LhedFKPzvWEQ==",
"dev": true,
"requires": {
"7zip-bin": "~5.0.3",
"@develar/schema-utils": "~2.6.5",
"async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.9",
"builder-util": "22.6.0",
"builder-util-runtime": "8.7.0",
"builder-util": "22.8.0",
"builder-util-runtime": "8.7.2",
"chromium-pickle-js": "^0.2.0",
"debug": "^4.1.1",
"ejs": "^3.1.2",
"electron-publish": "22.6.0",
"fs-extra": "^9.0.0",
"hosted-git-info": "^3.0.4",
"ejs": "^3.1.3",
"electron-publish": "22.8.0",
"fs-extra": "^9.0.1",
"hosted-git-info": "^3.0.5",
"is-ci": "^2.0.0",
"isbinaryfile": "^4.0.6",
"js-yaml": "^3.13.1",
"js-yaml": "^3.14.0",
"lazy-val": "^1.0.4",
"minimatch": "^3.0.4",
"normalize-package-data": "^2.5.0",
@@ -355,31 +355,31 @@
"dev": true
},
"builder-util": {
"version": "22.6.0",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.6.0.tgz",
"integrity": "sha512-jgdES2ExJYkuXC3DEaGAjFctKNA81C4QDy8zdoc+rqdSqheTizuDNtZg02uMFklmUES4V4fggmqds+Y7wraqng==",
"version": "22.8.0",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.8.0.tgz",
"integrity": "sha512-H80P1JzVy3TGpi63x81epQDK24XalL034+jAZlrPb5IhLtYmnNNdxCCAVJvg3VjSISd73Y71O+uhqCxWpqbPHw==",
"dev": true,
"requires": {
"7zip-bin": "~5.0.3",
"@types/debug": "^4.1.5",
"@types/fs-extra": "^8.1.0",
"app-builder-bin": "3.5.8",
"@types/fs-extra": "^9.0.1",
"app-builder-bin": "3.5.9",
"bluebird-lst": "^1.0.9",
"builder-util-runtime": "8.7.0",
"chalk": "^4.0.0",
"builder-util-runtime": "8.7.2",
"chalk": "^4.1.0",
"debug": "^4.1.1",
"fs-extra": "^9.0.0",
"fs-extra": "^9.0.1",
"is-ci": "^2.0.0",
"js-yaml": "^3.13.1",
"js-yaml": "^3.14.0",
"source-map-support": "^0.5.19",
"stat-mode": "^1.0.0",
"temp-file": "^3.3.7"
}
},
"builder-util-runtime": {
"version": "8.7.0",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.0.tgz",
"integrity": "sha512-G1AqqVM2vYTrSFR982c1NNzwXKrGLQjVjaZaWQdn4O6Z3YKjdMDofw88aD9jpyK9ZXkrCxR0tI3Qe9wNbyTlXg==",
"version": "8.7.2",
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.2.tgz",
"integrity": "sha512-xBqv+8bg6cfnzAQK1k3OGpfaHg+QkPgIgpEkXNhouZ0WiUkyZCftuRc2LYzQrLucFywpa14Xbc6+hTbpq83yRA==",
"requires": {
"debug": "^4.1.1",
"sax": "^1.2.4"
@@ -401,9 +401,9 @@
},
"dependencies": {
"get-stream": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
"integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true,
"requires": {
"pump": "^3.0.0"
@@ -424,9 +424,9 @@
"dev": true
},
"chalk": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz",
"integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -643,16 +643,16 @@
"optional": true
},
"dmg-builder": {
"version": "22.6.0",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.6.0.tgz",
"integrity": "sha512-rJxuGhHIpcuDGBtWZMM8aLxkbZNgYO2MO5dUerDIBXebhX1K8DA23iz/uZ8ahcRNgWEv57b8GDqJbXKEfr5T0A==",
"version": "22.8.0",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.8.0.tgz",
"integrity": "sha512-orePWjcrl97SYLA8F/6UUtbXJSoZCYu5KOP1lVqD4LOomr8bjGDyEVYZmZYcg5WqKmXucdmO6OpqgzH/aRMMuA==",
"dev": true,
"requires": {
"app-builder-lib": "22.6.0",
"builder-util": "22.6.0",
"fs-extra": "^9.0.0",
"iconv-lite": "^0.5.1",
"js-yaml": "^3.13.1",
"app-builder-lib": "22.8.0",
"builder-util": "22.8.0",
"fs-extra": "^9.0.1",
"iconv-lite": "^0.6.2",
"js-yaml": "^3.14.0",
"sanitize-filename": "^1.6.3"
}
},
@@ -683,18 +683,18 @@
"dev": true
},
"ejs": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.2.tgz",
"integrity": "sha512-zFuywxrAWtX5Mk2KAuoJNkXXbfezpNA0v7i+YC971QORguPekpjpAgeOv99YWSdKXwj7JxI2QAWDeDkE8fWtXw==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz",
"integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==",
"dev": true,
"requires": {
"jake": "^10.6.1"
}
},
"electron": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-8.3.0.tgz",
"integrity": "sha512-XRjiIJICZCgUr2vKSUI2PTkfP0gPFqCtqJUaTJSfCTuE3nTrxBKOUNeRMuCzEqspKkpFQU3SB3MdbMSHmZARlQ==",
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-8.5.0.tgz",
"integrity": "sha512-ERqSTRlaQ4PqME5a1z9DWQbwQy2LbgSN1Jnau1MJCRRvHgq1FJlqbbb/ij/RGWuQuaxy4Djb2KnTs5rsemR5mQ==",
"dev": true,
"requires": {
"@electron/get": "^1.0.1",
@@ -703,27 +703,27 @@
},
"dependencies": {
"@types/node": {
"version": "12.12.39",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.39.tgz",
"integrity": "sha512-pADGfwnDkr6zagDwEiCVE4yQrv7XDkoeVa4OfA9Ju/zRTk6YNDLGtQbkdL4/56mCQQCs4AhNrBIag6jrp7ZuOg==",
"version": "12.12.54",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.54.tgz",
"integrity": "sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w==",
"dev": true
}
}
},
"electron-builder": {
"version": "22.6.0",
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.6.0.tgz",
"integrity": "sha512-aLHlB6DTfjJ3MI4AUIFeWnwIozNgNlbOk2c2sTHxB10cAKp0dBVSPZ7xF5NK0uwDhElvRzJQubnHtJD6zKg42Q==",
"version": "22.8.0",
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.8.0.tgz",
"integrity": "sha512-dUv4F3srJouqxhWivtKqSoQP4Df6vYgjooGdzms+iYMTFi9f0b4LlEbr7kgsPvte8zAglee7VOGOODkCRJDkUQ==",
"dev": true,
"requires": {
"@types/yargs": "^15.0.4",
"app-builder-lib": "22.6.0",
"@types/yargs": "^15.0.5",
"app-builder-lib": "22.8.0",
"bluebird-lst": "^1.0.9",
"builder-util": "22.6.0",
"builder-util-runtime": "8.7.0",
"chalk": "^4.0.0",
"dmg-builder": "22.6.0",
"fs-extra": "^9.0.0",
"builder-util": "22.8.0",
"builder-util-runtime": "8.7.2",
"chalk": "^4.1.0",
"dmg-builder": "22.8.0",
"fs-extra": "^9.0.1",
"is-ci": "^2.0.0",
"lazy-val": "^1.0.4",
"read-config-file": "6.0.0",
@@ -733,25 +733,25 @@
}
},
"electron-publish": {
"version": "22.6.0",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.6.0.tgz",
"integrity": "sha512-+v05SBf9qR7Os5au+fifloNHy5QxHQkUGudBj68YaTb43Pn37UkwRxSc49Lf13s4wW32ohM45g8BOVInPJEdnA==",
"version": "22.8.0",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.8.0.tgz",
"integrity": "sha512-uM0Zdi9hUqqGOrPj478v7toTvV1Kgto1w11rIiI168batiXAJvNLD8VZRfehOrZT0ibUyZlw8FtxoGCrjyHUOw==",
"dev": true,
"requires": {
"@types/fs-extra": "^8.1.0",
"@types/fs-extra": "^9.0.1",
"bluebird-lst": "^1.0.9",
"builder-util": "22.6.0",
"builder-util-runtime": "8.7.0",
"chalk": "^4.0.0",
"fs-extra": "^9.0.0",
"builder-util": "22.8.0",
"builder-util-runtime": "8.7.2",
"chalk": "^4.1.0",
"fs-extra": "^9.0.1",
"lazy-val": "^1.0.4",
"mime": "^2.4.4"
"mime": "^2.4.6"
}
},
"electron-store": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/electron-store/-/electron-store-5.1.1.tgz",
"integrity": "sha512-FLidOVE8JVCdJXHd7xY/JojKJ2r2WNmWt0O/LlX2LuSVV7dkG2RSy2/Gm2LFw8OKDfrNBd9c/s4X1ikMrJEUKg==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/electron-store/-/electron-store-5.2.0.tgz",
"integrity": "sha512-iU3WDqEDAYNYR9XV7p0tJajq/zs9z7Nrn0sAoR5nDyn8h/9dr9kusKbTxD8NtVEBD1TB1pkGMqcbIt/y6knDwQ==",
"requires": {
"conf": "^6.2.1",
"type-fest": "^0.7.1"
@@ -763,17 +763,17 @@
"integrity": "sha512-/i1jh1L8qyUJAZ1KVT67SEK/OZ+3F2Qfe8mCfuXHSVC5tAOuw3U971LuxMvAsJJS/yNW0oSQ9pCbVzqGlNCeJQ=="
},
"electron-updater": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.3.1.tgz",
"integrity": "sha512-UDC5AHCgeiHJYDYWZG/rsl1vdAFKqI/Lm7whN57LKAk8EfhTewhcEHzheRcncLgikMcQL8gFo1KeX51tf5a5Wg==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.3.4.tgz",
"integrity": "sha512-ekpgxDrYl+Wi24ktO4qfj2CtCABxrmK1C/oekp0tai6q4VR4ZdPkit4CX8+GenvKMme7uMmfPFnLp/vwhP/ThQ==",
"requires": {
"@types/semver": "^7.1.0",
"builder-util-runtime": "8.7.0",
"fs-extra": "^9.0.0",
"js-yaml": "^3.13.1",
"@types/semver": "^7.3.1",
"builder-util-runtime": "8.7.2",
"fs-extra": "^9.0.1",
"js-yaml": "^3.14.0",
"lazy-val": "^1.0.4",
"lodash.isequal": "^4.5.0",
"semver": "^7.1.3"
"semver": "^7.3.2"
},
"dependencies": {
"semver": {
@@ -824,9 +824,9 @@
"dev": true
},
"escape-string-regexp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"optional": true
},
@@ -865,9 +865,9 @@
}
},
"fast-deep-equal": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"fast-json-stable-stringify": {
"version": "2.1.0",
@@ -901,9 +901,9 @@
}
},
"fs-extra": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz",
"integrity": "sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==",
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
"integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
"requires": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
@@ -927,19 +927,19 @@
}
},
"global-agent": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.8.tgz",
"integrity": "sha512-VpBe/rhY6Rw2VDOTszAMNambg+4Qv8j0yiTNDYEXXXxkUNGWLHp8A3ztK4YDBbFNcWF4rgsec6/5gPyryya/+A==",
"version": "2.1.12",
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.12.tgz",
"integrity": "sha512-caAljRMS/qcDo69X9BfkgrihGUgGx44Fb4QQToNQjsiWh+YlQ66uqYVAdA8Olqit+5Ng0nkz09je3ZzANMZcjg==",
"dev": true,
"optional": true,
"requires": {
"boolean": "^3.0.0",
"core-js": "^3.6.4",
"boolean": "^3.0.1",
"core-js": "^3.6.5",
"es6-error": "^4.1.1",
"matcher": "^2.1.0",
"roarr": "^2.15.2",
"semver": "^7.1.2",
"serialize-error": "^5.0.0"
"matcher": "^3.0.0",
"roarr": "^2.15.3",
"semver": "^7.3.2",
"serialize-error": "^7.0.1"
},
"dependencies": {
"semver": {
@@ -1020,12 +1020,12 @@
"dev": true
},
"hosted-git-info": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz",
"integrity": "sha512-4oT62d2jwSDBbLLFLZE+1vPuQ1h8p9wjrJ8Mqx5TjsyWmBMV5B13eJqn8pvluqubLf3cJPTfiYCIwNwDNmzScQ==",
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.5.tgz",
"integrity": "sha512-i4dpK6xj9BIpVOTboXIlKG9+8HMKggcrMX7WA24xZtKwX0TPelq/rbaS5rCKeNX8sJXZJGdSxpnEGtta+wismQ==",
"dev": true,
"requires": {
"lru-cache": "^5.1.1"
"lru-cache": "^6.0.0"
}
},
"http-cache-semantics": {
@@ -1035,12 +1035,12 @@
"dev": true
},
"iconv-lite": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.1.tgz",
"integrity": "sha512-ONHr16SQvKZNSqjQT9gy5z24Jw+uqfO02/ngBSBoqChZ+W8qXX7GPRa1RoUnzGADw8K63R1BXUMzarCVQBpY8Q==",
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
"integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
"dev": true,
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
"safer-buffer": ">= 2.1.2 < 3.0.0"
}
},
"import-lazy": {
@@ -1132,9 +1132,9 @@
"dev": true
},
"jake": {
"version": "10.6.1",
"resolved": "https://registry.npmjs.org/jake/-/jake-10.6.1.tgz",
"integrity": "sha512-pHUK3+V0BjOb1XSi95rbBksrMdIqLVC9bJqDnshVyleYsET3H0XAq+3VB2E3notcYvv4wRdRHn13p7vobG+wfQ==",
"version": "10.8.2",
"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
"integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
"dev": true,
"requires": {
"async": "0.9.x",
@@ -1202,9 +1202,9 @@
}
},
"js-yaml": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
"integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
@@ -1284,9 +1284,9 @@
}
},
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true,
"optional": true
},
@@ -1302,12 +1302,12 @@
"dev": true
},
"lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^3.0.2"
"yallist": "^4.0.0"
}
},
"make-dir": {
@@ -1319,19 +1319,19 @@
}
},
"matcher": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/matcher/-/matcher-2.1.0.tgz",
"integrity": "sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
"integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
"dev": true,
"optional": true,
"requires": {
"escape-string-regexp": "^2.0.0"
"escape-string-regexp": "^4.0.0"
}
},
"mime": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz",
"integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w==",
"version": "2.4.6",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
"integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==",
"dev": true
},
"mimic-fn": {
@@ -1432,9 +1432,9 @@
}
},
"onetime": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
"integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"requires": {
"mimic-fn": "^2.1.0"
}
@@ -1605,9 +1605,9 @@
}
},
"registry-auth-token": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz",
"integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz",
"integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==",
"dev": true,
"requires": {
"rc": "^1.2.8"
@@ -1724,19 +1724,19 @@
}
},
"serialize-error": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz",
"integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==",
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
"dev": true,
"optional": true,
"requires": {
"type-fest": "^0.8.0"
"type-fest": "^0.13.1"
},
"dependencies": {
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
"dev": true,
"optional": true
}
@@ -1770,9 +1770,9 @@
}
},
"spdx-correct": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
"integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
"integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
"dev": true,
"requires": {
"spdx-expression-parse": "^3.0.0",
@@ -2148,15 +2148,15 @@
"dev": true
},
"yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"yargs": {
"version": "15.3.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
"integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
"version": "15.4.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"dev": true,
"requires": {
"cliui": "^6.0.0",
@@ -2169,7 +2169,7 @@
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.1"
"yargs-parser": "^18.1.2"
},
"dependencies": {
"find-up": {

View File

@@ -4,26 +4,26 @@
"type": "git",
"url": "https://github.com/mrvnklm/homeassistant-desktop"
},
"version": "1.2.1",
"version": "1.3.0",
"description": "Desktop App (Windows / macOS) for Home Assistant built with Electron",
"main": "app.js",
"scripts": {
"start": "electron .",
"build-local": "electron-builder build --mac --win --publish never",
"deploy": "electron-builder build --mac --win --publish always",
"build-local": "electron-builder build --mac --win --ia32 --publish never",
"deploy": "electron-builder build --mac --win --ia32 --publish always",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Marvin Kelm (https://github.com/mrvnklm)",
"license": "Apache-2.0",
"dependencies": {
"auto-launch": "^5.0.5",
"electron-store": "^5.1.1",
"electron-store": "^5.2.0",
"electron-traywindow-positioner": "^1.1.0",
"electron-updater": "^4.3.1"
"electron-updater": "^4.3.4"
},
"devDependencies": {
"electron": "^8.2.5",
"electron-builder": "^22.6.0"
"electron": "^8.5.0",
"electron-builder": "^22.8.0"
},
"build": {
"appId": "com.electron.homeassistant-desktop",

View File

@@ -13,7 +13,7 @@
position: relative;
border-radius: 50%;
box-sizing: content-box;
border: 4px solid #4CAF50;
border: 4px solid #4caf50;
}
.success-checkmark .check-icon::before {
top: 3px;
@@ -30,16 +30,17 @@
border-radius: 0 100px 100px 0;
animation: rotate-circle 4.25s ease-in;
}
.success-checkmark .check-icon::before, .success-checkmark .check-icon::after {
.success-checkmark .check-icon::before,
.success-checkmark .check-icon::after {
content: "";
height: 100px;
position: absolute;
background: #FFFFFF;
background: #ffffff;
transform: rotate(-45deg);
}
.success-checkmark .check-icon .icon-line {
height: 5px;
background-color: #4CAF50;
background-color: #4caf50;
display: block;
border-radius: 2px;
position: absolute;
@@ -78,7 +79,7 @@
height: 85px;
position: absolute;
transform: rotate(-45deg);
background-color: #FFFFFF;
background-color: #ffffff;
}
@keyframes rotate-circle {

42
web/assets/error.css Normal file
View File

@@ -0,0 +1,42 @@
svg {
width: 100px;
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;
}
100% {
stroke-dashoffset: 0;
}
}
@keyframes dash {
0% {
stroke-dashoffset: 1000;
}
100% {
stroke-dashoffset: 0;
}
}

View File

@@ -19,7 +19,7 @@ body {
.content {
padding: 20px 16px;
margin: 0 auto
margin: 0 auto;
}
.header {
@@ -33,13 +33,20 @@ body {
justify-content: center;
}
.vertical-center {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
p {
padding-top: 20px;
width: 320px;
}
.header img {
margin-right: 16px
margin-right: 16px;
}
.group {
@@ -62,7 +69,8 @@ input:focus {
outline: none;
}
input:focus ~ label, input:valid ~ label {
input:focus ~ label,
input:valid ~ label {
top: -14px;
font-size: 12px;
color: #03a9f4;

65
web/error.html Normal file
View File

@@ -0,0 +1,65 @@
<!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>
<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>
</div>
</body>
</html>

View File

@@ -1,19 +1,27 @@
<!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/checkmark.css" rel="stylesheet">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,user-scalable=no" />
<link href="assets/style.css" rel="stylesheet" />
<link href="assets/checkmark.css" rel="stylesheet" />
<script>
const {ipcRenderer} = require('electron');
const { ipcRenderer } = require("electron");
ipcRenderer.send('ha-instance');
ipcRenderer.send("ha-instance");
ipcRenderer.on('ha-instance', function (event, url) {
window.location.href = url
let showCheckmark = false;
ipcRenderer.on("ha-instance", function (event, url) {
if (showCheckmark) {
document
.getElementById("check-wrapper")
.addEventListener(
"animationend",
() => (window.location.href = url)
);
} else window.location.href = url;
});
function isValidUrl(string) {
@@ -26,34 +34,36 @@
}
function checkUrl() {
let url = document.getElementById('url').value;
const url = document.getElementById("url").value;
if (!isValidUrl(url)) {
return
return;
}
let request = new XMLHttpRequest();
request.open('GET', url + '/auth/providers', true);
request.onreadystatechange = function () {
if (request.status === 200) {
document.getElementById('check-wrapper').style.display = 'block';
document.getElementById('url-wrapper').style.display = 'none';
ipcRenderer.send('ha-instance', {url: url, name: JSON.parse(request.responseText)[0].name});
setTimeout(function () {
window.location.href = url
}, 1000)
fetch(url + "/auth/providers")
.then((response) => {
if (response.ok) {
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);
}
};
request.send();
})
.catch((err) => {});
}
</script>
</head>
<body>
<div class="content">
<div class="center header"><img src="assets/favicon.png" height="52"> Home Assistant</div>
<div class="center header">
<img src="assets/favicon.png" height="52" /> Home Assistant
</div>
<div class="center">
<p>Please enter your Home Assistant URL in the field below:</p></div>
<p>Please enter your Home Assistant URL in the field below:</p>
</div>
<div class="center">
<div id="check-wrapper" class="success-checkmark">
<div class="check-icon">
@@ -71,9 +81,13 @@
</div>
</div>
<div class="center">
<p><small class="grey">If the entered URL directs to a working Home Assistant instance, you will be forwarded to the login page automatically.</small></p>
<p>
<small class="grey"
>If the entered URL directs to a working Home Assistant instance,
you will be forwarded to the login page automatically.</small
>
</p>
</div>
</div>
</body>
</html>