mirror of
https://github.com/sascha-hemi/homeassistant-desktop.git
synced 2026-03-21 00:04:12 +01:00
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:
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -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
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
node_modules
|
||||
dist
|
||||
.idea
|
||||
.DS_Store
|
||||
|
||||
42
LICENSE.md
42
LICENSE.md
@@ -2,9 +2,9 @@
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
@@ -63,14 +63,14 @@
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
@@ -86,7 +86,7 @@
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
@@ -127,7 +127,7 @@
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
@@ -135,12 +135,12 @@
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
@@ -150,7 +150,7 @@
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
@@ -162,7 +162,7 @@
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
@@ -173,9 +173,9 @@
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
@@ -186,16 +186,16 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
Copyright [yyyy][name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
23
README.md
23
README.md
@@ -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/)
|
||||

|
||||
## 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)
|
||||

|
||||
|
||||
## 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
422
app.js
@@ -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
326
package-lock.json
generated
@@ -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": {
|
||||
|
||||
14
package.json
14
package.json
@@ -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",
|
||||
|
||||
@@ -2,64 +2,65 @@
|
||||
* Extracted from: SweetAlert
|
||||
* Modified by: Istiak Tridip
|
||||
*/
|
||||
.success-checkmark {
|
||||
.success-checkmark {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.success-checkmark .check-icon {
|
||||
}
|
||||
.success-checkmark .check-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
position: relative;
|
||||
border-radius: 50%;
|
||||
box-sizing: content-box;
|
||||
border: 4px solid #4CAF50;
|
||||
}
|
||||
.success-checkmark .check-icon::before {
|
||||
border: 4px solid #4caf50;
|
||||
}
|
||||
.success-checkmark .check-icon::before {
|
||||
top: 3px;
|
||||
left: -2px;
|
||||
width: 30px;
|
||||
transform-origin: 100% 50%;
|
||||
border-radius: 100px 0 0 100px;
|
||||
}
|
||||
.success-checkmark .check-icon::after {
|
||||
}
|
||||
.success-checkmark .check-icon::after {
|
||||
top: 0;
|
||||
left: 30px;
|
||||
width: 60px;
|
||||
transform-origin: 0 50%;
|
||||
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 {
|
||||
}
|
||||
.success-checkmark .check-icon .icon-line {
|
||||
height: 5px;
|
||||
background-color: #4CAF50;
|
||||
background-color: #4caf50;
|
||||
display: block;
|
||||
border-radius: 2px;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
.success-checkmark .check-icon .icon-line.line-tip {
|
||||
}
|
||||
.success-checkmark .check-icon .icon-line.line-tip {
|
||||
top: 46px;
|
||||
left: 14px;
|
||||
width: 25px;
|
||||
transform: rotate(45deg);
|
||||
animation: icon-line-tip 0.75s;
|
||||
}
|
||||
.success-checkmark .check-icon .icon-line.line-long {
|
||||
}
|
||||
.success-checkmark .check-icon .icon-line.line-long {
|
||||
top: 38px;
|
||||
right: 8px;
|
||||
width: 47px;
|
||||
transform: rotate(-45deg);
|
||||
animation: icon-line-long 0.75s;
|
||||
}
|
||||
.success-checkmark .check-icon .icon-circle {
|
||||
}
|
||||
.success-checkmark .check-icon .icon-circle {
|
||||
top: -4px;
|
||||
left: -4px;
|
||||
z-index: 10;
|
||||
@@ -69,8 +70,8 @@
|
||||
position: absolute;
|
||||
box-sizing: content-box;
|
||||
border: 4px solid rgba(76, 175, 80, 0.5);
|
||||
}
|
||||
.success-checkmark .check-icon .icon-fix {
|
||||
}
|
||||
.success-checkmark .check-icon .icon-fix {
|
||||
top: 8px;
|
||||
width: 5px;
|
||||
left: 26px;
|
||||
@@ -78,10 +79,10 @@
|
||||
height: 85px;
|
||||
position: absolute;
|
||||
transform: rotate(-45deg);
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
@keyframes rotate-circle {
|
||||
@keyframes rotate-circle {
|
||||
0% {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
@@ -94,8 +95,8 @@
|
||||
100% {
|
||||
transform: rotate(-405deg);
|
||||
}
|
||||
}
|
||||
@keyframes icon-line-tip {
|
||||
}
|
||||
@keyframes icon-line-tip {
|
||||
0% {
|
||||
width: 0;
|
||||
left: 1px;
|
||||
@@ -121,8 +122,8 @@
|
||||
left: 14px;
|
||||
top: 45px;
|
||||
}
|
||||
}
|
||||
@keyframes icon-line-long {
|
||||
}
|
||||
@keyframes icon-line-long {
|
||||
0% {
|
||||
width: 0;
|
||||
right: 46px;
|
||||
@@ -143,4 +144,4 @@
|
||||
right: 8px;
|
||||
top: 38px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
42
web/assets/error.css
Normal file
42
web/assets/error.css
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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
65
web/error.html
Normal 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>
|
||||
@@ -1,19 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<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/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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<div class="center header"><img src="assets/favicon.png" height="52"> Home Assistant</div>
|
||||
<body>
|
||||
<div class="content">
|
||||
<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">
|
||||
@@ -64,16 +74,20 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="url-wrapper" class="group">
|
||||
<input type="url" required="required" id="url" onkeyup="checkUrl()"/>
|
||||
<input type="url" required="required" id="url" onkeyup="checkUrl()" />
|
||||
<span class="highlight"></span>
|
||||
<span class="bar"></span>
|
||||
<label>Home Assistant URL</label>
|
||||
</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>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user