mirror of
https://github.com/sascha-hemi/homeassistant-desktop.git
synced 2026-03-21 04:06:06 +01:00
@@ -1,4 +1,5 @@
|
|||||||
html,body {
|
html,
|
||||||
|
body {
|
||||||
font-family: Roboto, sans-serif;
|
font-family: Roboto, sans-serif;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
@@ -43,8 +44,16 @@ html,body {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
color: rgb(var(--pure-material-onprimary-rgb, 255, 255, 255));
|
color: rgb(var(--pure-material-onprimary-rgb, 255, 255, 255));
|
||||||
background-color: rgb(var(--pure-material-primary-rgb, 3, 169, 244));
|
background-color: rgb(var(--pure-material-primary-rgb, 3, 169, 244));
|
||||||
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14),
|
||||||
font-family: var(--pure-material-font, "Roboto", "Segoe UI", BlinkMacSystemFont, system-ui, -apple-system);
|
0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||||
|
font-family: var(
|
||||||
|
--pure-material-font,
|
||||||
|
"Roboto",
|
||||||
|
"Segoe UI",
|
||||||
|
BlinkMacSystemFont,
|
||||||
|
system-ui,
|
||||||
|
-apple-system
|
||||||
|
);
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: 36px;
|
line-height: 36px;
|
||||||
@@ -91,7 +100,8 @@ html,body {
|
|||||||
/* Hover, Focus */
|
/* Hover, Focus */
|
||||||
.pure-material-button-contained:hover,
|
.pure-material-button-contained:hover,
|
||||||
.pure-material-button-contained:focus {
|
.pure-material-button-contained:focus {
|
||||||
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);
|
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14),
|
||||||
|
0 1px 10px 0 rgba(0, 0, 0, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pure-material-button-contained:hover::before {
|
.pure-material-button-contained:hover::before {
|
||||||
@@ -108,7 +118,8 @@ html,body {
|
|||||||
|
|
||||||
/* Active */
|
/* Active */
|
||||||
.pure-material-button-contained:active {
|
.pure-material-button-contained:active {
|
||||||
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
|
||||||
|
0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pure-material-button-contained:active::after {
|
.pure-material-button-contained:active::after {
|
||||||
|
|||||||
174
web/index.html
174
web/index.html
@@ -1,102 +1,111 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<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" />
|
|
||||||
<script>
|
|
||||||
const { ipcRenderer } = require("electron");
|
|
||||||
const bonjour = require('bonjour')()
|
|
||||||
|
|
||||||
function showInstance(url) {
|
<head>
|
||||||
document.getElementById('availableInstancesContainer').style.display = "block"
|
<title>Home Assistant</title>
|
||||||
const button = document.createElement("button")
|
<meta charset="utf-8" />
|
||||||
button.onclick = () => addInstance(url)
|
<meta name="viewport" content="width=device-width,user-scalable=no" />
|
||||||
button.classList.add("pure-material-button-contained")
|
<link href="assets/style.css" rel="stylesheet" />
|
||||||
button.textContent = url
|
<link href="assets/checkmark.css" rel="stylesheet" />
|
||||||
document.getElementById('availableInstances').append(button)
|
<script>
|
||||||
}
|
const { ipcRenderer } = require("electron");
|
||||||
|
const bonjour = require('bonjour')()
|
||||||
|
|
||||||
ipcRenderer.send("get-instances");
|
function showInstance(url) {
|
||||||
ipcRenderer.on("get-instances", (event, result) => {
|
document.getElementById('availableInstancesContainer').style.display = "block"
|
||||||
let instances = result
|
const button = document.createElement("button")
|
||||||
|
button.onclick = () => addInstance(url)
|
||||||
bonjour.find({ type: 'home-assistant' }, instance => {
|
button.classList.add("pure-material-button-contained")
|
||||||
|
button.textContent = url
|
||||||
|
document.getElementById('availableInstances').append(button)
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function (event) {
|
||||||
|
setTimeout(() => document.getElementById('url').focus(), 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcRenderer.send("get-instances");
|
||||||
|
ipcRenderer.on("get-instances", (event, result) => {
|
||||||
|
let instances = result
|
||||||
|
|
||||||
|
bonjour.find({ type: 'home-assistant' }, instance => {
|
||||||
if (instances.indexOf(instance.txt.internal_url) === -1) showInstance(instance.txt.internal_url)
|
if (instances.indexOf(instance.txt.internal_url) === -1) showInstance(instance.txt.internal_url)
|
||||||
if (instances.indexOf(instance.txt.external_url) === -1) showInstance(instance.txt.external_url)
|
if (instances.indexOf(instance.txt.external_url) === -1) showInstance(instance.txt.external_url)
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
function addInstance(url) {
|
function addInstance(url) {
|
||||||
ipcRenderer.send("ha-instance", url);
|
ipcRenderer.send("ha-instance", url);
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcRenderer.send("ha-instance");
|
ipcRenderer.send("ha-instance");
|
||||||
|
|
||||||
let showCheckmark = false;
|
let showCheckmark = false;
|
||||||
|
|
||||||
ipcRenderer.on("ha-instance", function (event, url) {
|
ipcRenderer.on("ha-instance", function (event, url) {
|
||||||
if (showCheckmark) {
|
if (showCheckmark) {
|
||||||
document
|
document
|
||||||
.getElementById("check-wrapper")
|
.getElementById("check-wrapper")
|
||||||
.addEventListener(
|
.addEventListener(
|
||||||
"animationend",
|
"animationend",
|
||||||
() => (window.location.href = url)
|
() => (window.location.href = url)
|
||||||
);
|
);
|
||||||
} else window.location.href = url;
|
} else window.location.href = url;
|
||||||
});
|
});
|
||||||
|
|
||||||
function isValidUrl(string) {
|
function isValidUrl(string) {
|
||||||
try {
|
try {
|
||||||
new URL(string);
|
new URL(string);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkUrl() {
|
||||||
|
const url = document.getElementById("url").value;
|
||||||
|
|
||||||
|
if (!isValidUrl(url)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkUrl() {
|
fetch(url + "/auth/providers")
|
||||||
const url = document.getElementById("url").value;
|
.then(response => response.text())
|
||||||
|
.then(data => {
|
||||||
|
if (!data.includes('homeassistant')) return;
|
||||||
|
document.getElementById("url").value = url;
|
||||||
|
document.getElementById("url").disabled = true;
|
||||||
|
document.getElementById("check-wrapper").style.display = "block";
|
||||||
|
document.getElementById("url-wrapper").style.display = "none";
|
||||||
|
showCheckmark = true;
|
||||||
|
ipcRenderer.send("ha-instance", url);
|
||||||
|
}).catch((err) => { });
|
||||||
|
}
|
||||||
|
|
||||||
if (!isValidUrl(url)) {
|
function showPlaceholder(status = true) {
|
||||||
return;
|
if (status) document.getElementById("url").placeholder = 'e.g. http://hassio.local:8123';
|
||||||
}
|
else document.getElementById("url").placeholder = '';
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
fetch(url + "/auth/providers")
|
<body>
|
||||||
.then((response) => {
|
<div class="container">
|
||||||
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);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="center header">
|
<div class="center header">
|
||||||
<img src="assets/favicon.png" height="52" /> Home Assistant
|
<img src="assets/favicon.png" height="52" /> Home Assistant
|
||||||
</div>
|
</div>
|
||||||
<div id="availableInstancesContainer" style="display:none;">
|
<div id="availableInstancesContainer" style="display:none;">
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<p>Available Instances: </p>
|
<p>Available Instances: </p>
|
||||||
</div>
|
</div>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<div id="availableInstances">
|
<div id="availableInstances">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="center" style="margin-top: 30px;">
|
||||||
<div class="center">
|
|
||||||
<p>Add Instance via URL</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<div id="check-wrapper" class="success-checkmark">
|
<div id="check-wrapper" class="success-checkmark">
|
||||||
@@ -108,7 +117,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="url-wrapper" class="group">
|
<div id="url-wrapper" class="group">
|
||||||
<input type="url" required="required" id="url" onkeyup="checkUrl()" />
|
<input type="url" required="required" id="url" onblur="showPlaceholder(false)" onfocus="showPlaceholder()"
|
||||||
|
onkeyup="checkUrl()" />
|
||||||
<span class="highlight"></span>
|
<span class="highlight"></span>
|
||||||
<span class="bar"></span>
|
<span class="bar"></span>
|
||||||
<label>Home Assistant URL</label>
|
<label>Home Assistant URL</label>
|
||||||
@@ -117,13 +127,11 @@
|
|||||||
|
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<p>
|
<p>
|
||||||
<small class="grey"
|
<small class="grey">Your URL is checked and you will be forwarded to Home Assistant automatically.</small>
|
||||||
>If the entered URL directs to a working Home Assistant instance,
|
|
||||||
you will be forwarded to the login page automatically.</small
|
|
||||||
>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user