diff --git a/Makefile b/Makefile index 627a037..70ce9d0 100644 --- a/Makefile +++ b/Makefile @@ -20,9 +20,13 @@ enums: ids: go generate models/ids.go -run: build +run-systemd: build 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: # go install github.com/mitranim/gow@latest diff --git a/api/handler/webHandler.go b/api/handler/webHandler.go index 2fd0682..6e62ee1 100644 --- a/api/handler/webHandler.go +++ b/api/handler/webHandler.go @@ -148,7 +148,7 @@ func (h WebHandler) buildScriptJSTemplate(content []byte) (webassets.ITemplate, func (h WebHandler) templateFuncMap() map[string]any { return map[string]any{ "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() v, err := h.app.ListServer(ctx, bunny.Conf.VerifyConnTimeoutHTML) if err != nil { diff --git a/logic/application.go b/logic/application.go index 185f47e..9c64cd4 100644 --- a/logic/application.go +++ b/logic/application.go @@ -221,10 +221,6 @@ func (app *Application) ListServer(ctx context.Context, timeout time.Duration) ( close(echan) close(rchan) - if err := ctx.Err(); err != nil { - return nil, err - } - duplicates := make(map[int]bool, sockCount*3) res := make([]models.Server, 0, sockCount*3) for v := range rchan { diff --git a/webassets/css/styles.css b/webassets/css/styles.css index bf0c475..b1e119c 100644 --- a/webassets/css/styles.css +++ b/webassets/css/styles.css @@ -1,6 +1,6 @@ * { - font-family: 'MonaspaceXenon'; + font-family: 'MonaspaceXenon', serif; } html, body { @@ -14,25 +14,38 @@ body { background-color: #EFEFEF; } +.hidden { display: none !important; } + main { - display: flex; - flex-direction: column; + display: grid; + grid-template-columns: auto 1fr auto; + grid-column-gap: 1rem; + grid-row-gap: 1rem; margin: 1rem; } h1 { font-size: 3em; - margin-bottom: 1rem; text-shadow: 0 0 8px #888; } +.loader_left, +.loader_right{ + display: flex; + width: 50px; + justify-content: center; + align-items: center; +} + #maincontent { display: flex; flex-direction: column; gap: 0.5rem; padding: 0 2rem; + + grid-column: 2; } .server { @@ -74,3 +87,23 @@ h1 { 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); + } +} \ No newline at end of file diff --git a/webassets/index.html b/webassets/index.html index b553aa6..4086609 100644 --- a/webassets/index.html +++ b/webassets/index.html @@ -30,13 +30,18 @@
+

LocalHostBunny

+ + + +
diff --git a/webassets/scripts/script.js b/webassets/scripts/script.js index 1cf2953..e85e755 100644 --- a/webassets/scripts/script.js +++ b/webassets/scripts/script.js @@ -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 updateHTML() { +function updateHTML(servers) { const main = document.getElementById('maincontent') @@ -20,4 +26,35 @@ function updateHTML() { } -document.addEventListener("DOMContentLoaded", updateHTML); \ No newline at end of file +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); \ No newline at end of file