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