auto-reload
This commit is contained in:
parent
ab2f2ff439
commit
e691640055
8
Makefile
8
Makefile
@ -20,9 +20,13 @@ enums:
|
|||||||
ids:
|
ids:
|
||||||
go generate models/ids.go
|
go generate models/ids.go
|
||||||
|
|
||||||
run: build
|
run-systemd: build
|
||||||
mkdir -p .run-data
|
mkdir -p .run-data
|
||||||
sudo BUNNY_LIVERELOAD="$(shell pwd)/webassets" CONF_NS="local-host" _build/bunny_backend
|
CONF_NS="production" _build/bunny_backend
|
||||||
|
|
||||||
|
run-test: build
|
||||||
|
mkdir -p .run-data
|
||||||
|
sudo BUNNY_LIVERELOAD="$(shell pwd)/webassets" BUNNY_PORT="4004" CONF_NS="local-host" _build/bunny_backend
|
||||||
|
|
||||||
gow:
|
gow:
|
||||||
# go install github.com/mitranim/gow@latest
|
# go install github.com/mitranim/gow@latest
|
||||||
|
@ -148,7 +148,7 @@ func (h WebHandler) buildScriptJSTemplate(content []byte) (webassets.ITemplate,
|
|||||||
func (h WebHandler) templateFuncMap() map[string]any {
|
func (h WebHandler) templateFuncMap() map[string]any {
|
||||||
return map[string]any{
|
return map[string]any{
|
||||||
"listServers": func() []models.Server {
|
"listServers": func() []models.Server {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), bunny.Conf.VerifyConnTimeoutHTML+2*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), bunny.Conf.VerifyConnTimeoutHTML+5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
v, err := h.app.ListServer(ctx, bunny.Conf.VerifyConnTimeoutHTML)
|
v, err := h.app.ListServer(ctx, bunny.Conf.VerifyConnTimeoutHTML)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -221,10 +221,6 @@ func (app *Application) ListServer(ctx context.Context, timeout time.Duration) (
|
|||||||
close(echan)
|
close(echan)
|
||||||
close(rchan)
|
close(rchan)
|
||||||
|
|
||||||
if err := ctx.Err(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
duplicates := make(map[int]bool, sockCount*3)
|
duplicates := make(map[int]bool, sockCount*3)
|
||||||
res := make([]models.Server, 0, sockCount*3)
|
res := make([]models.Server, 0, sockCount*3)
|
||||||
for v := range rchan {
|
for v := range rchan {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
* {
|
* {
|
||||||
font-family: 'MonaspaceXenon';
|
font-family: 'MonaspaceXenon', serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
@ -14,25 +14,38 @@ body {
|
|||||||
background-color: #EFEFEF;
|
background-color: #EFEFEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden { display: none !important; }
|
||||||
|
|
||||||
main {
|
main {
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: column;
|
grid-template-columns: auto 1fr auto;
|
||||||
|
grid-column-gap: 1rem;
|
||||||
|
grid-row-gap: 1rem;
|
||||||
|
|
||||||
margin: 1rem;
|
margin: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 3em;
|
font-size: 3em;
|
||||||
margin-bottom: 1rem;
|
|
||||||
text-shadow: 0 0 8px #888;
|
text-shadow: 0 0 8px #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader_left,
|
||||||
|
.loader_right{
|
||||||
|
display: flex;
|
||||||
|
width: 50px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
#maincontent {
|
#maincontent {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
||||||
padding: 0 2rem;
|
padding: 0 2rem;
|
||||||
|
|
||||||
|
grid-column: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.server {
|
.server {
|
||||||
@ -74,3 +87,23 @@ h1 {
|
|||||||
color: #00A;
|
color: #00A;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
border: 10px solid;
|
||||||
|
border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25) rgba(0, 0, 0, 0.35) rgba(0, 0, 0, 0.5);
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: rotation 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotation {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
@ -30,13 +30,18 @@
|
|||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
|
<span class="loader_left"></span>
|
||||||
<h1>LocalHostBunny</h1>
|
<h1>LocalHostBunny</h1>
|
||||||
|
<span class="loader_right">
|
||||||
|
<span id="loader" class="loader hidden"></span>
|
||||||
|
</span>
|
||||||
|
|
||||||
<div id="maincontent"></div>
|
<div id="maincontent"></div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
const servers = {{ listServers | json_indent | safe_js }};
|
const initialServers = {{ listServers | json_indent | safe_js }};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript" src="/scripts/script.js"></script>
|
<script type="text/javascript" src="/scripts/script.js"></script>
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
|
|
||||||
|
const refresh_delay = 2 * 60 * 1000; // 2min
|
||||||
|
|
||||||
|
let last_refresh = now();
|
||||||
|
|
||||||
|
function now() { return (new Date()).getTime(); }
|
||||||
|
|
||||||
function enc(v) { return `${v}`.replace(/[\u00A0-\u9999<>&]/g, i => '&#'+i.charCodeAt(0)+';') }
|
function enc(v) { return `${v}`.replace(/[\u00A0-\u9999<>&]/g, i => '&#'+i.charCodeAt(0)+';') }
|
||||||
|
|
||||||
function updateHTML() {
|
function updateHTML(servers) {
|
||||||
|
|
||||||
const main = document.getElementById('maincontent')
|
const main = document.getElementById('maincontent')
|
||||||
|
|
||||||
@ -20,4 +26,35 @@ function updateHTML() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", updateHTML);
|
function onVisibilityChange() {
|
||||||
|
if (!document.hidden && (now() - last_refresh) > refresh_delay) autoReload();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function autoReload() {
|
||||||
|
try {
|
||||||
|
document.getElementById('loader').classList.remove('hidden');
|
||||||
|
|
||||||
|
const res = await fetch('/api/v1/server');
|
||||||
|
if (res.status !== 200) {
|
||||||
|
console.error(`status == ${res.status}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
updateHTML(data['servers'])
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
document.getElementById('loader').classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => updateHTML(initialServers));
|
||||||
|
|
||||||
|
document.addEventListener('visibilitychange', onVisibilityChange);
|
||||||
|
|
||||||
|
setInterval(autoReload, refresh_delay);
|
Loading…
Reference in New Issue
Block a user