-
Notifications
You must be signed in to change notification settings - Fork 2
Add uptime information to WebUI #153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -262,7 +262,7 @@ function pollRecurringTasks() { | |
| fetch('/api/v2/server/status') | ||
| .then(response => response.json()) | ||
| .then(data => { | ||
| updateStatusIndicator(data.isRunning); | ||
| updateStatusIndicator(data.isRunning, false, data.uptime); | ||
| if (data.uuid) { | ||
| localStorage.setItem('gameserverrunID', data.uuid); | ||
| } | ||
|
|
@@ -290,13 +290,15 @@ function pollRecurringTasks() { | |
| }, 30000); | ||
| } | ||
|
|
||
| function updateStatusIndicator(isRunning, isError = false) { | ||
| function updateStatusIndicator(isRunning, isError = false, uptime = '') { | ||
| const indicator = document.getElementById('status-indicator'); | ||
| const uptimeDisplay = document.getElementById('uptime-display'); | ||
|
|
||
| if (isError) { | ||
| indicator.className = 'status-indicator error'; | ||
| indicator.title = 'Error fetching server status'; | ||
| window.gamserverstate = false; | ||
| if (uptimeDisplay) uptimeDisplay.style.display = 'none'; | ||
| return; | ||
| } | ||
|
|
||
|
|
@@ -309,4 +311,14 @@ function updateStatusIndicator(isRunning, isError = false) { | |
| indicator.title = 'Server is offline'; | ||
| window.gamserverstate = false; | ||
| } | ||
|
|
||
| // Show uptime only when server is running and uptime is not "0s" | ||
| if (uptimeDisplay) { | ||
| if (isRunning && uptime && uptime !== '0s') { | ||
| uptimeDisplay.textContent = uptime; | ||
| uptimeDisplay.style.display = 'inline-block'; | ||
| } else { | ||
| uptimeDisplay.style.display = 'none'; | ||
| } | ||
|
Comment on lines
+315
to
+322
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,6 +7,7 @@ import ( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "net/http" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "os" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "strings" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "time" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/JacksonTheMaster/StationeersServerUI/v5/src/config" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/JacksonTheMaster/StationeersServerUI/v5/src/localization" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -49,8 +50,9 @@ func StopServer(w http.ResponseWriter, r *http.Request) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func GetGameServerRunState(w http.ResponseWriter, r *http.Request) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runState := config.GetIsGameServerRunning() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response := map[string]interface{}{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response := map[string]any{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "isRunning": runState, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "uptime": prettyUptime(gamemgr.GetServerUptime()), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+53
to
+55
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response := map[string]any{ | |
| "isRunning": runState, | |
| "uptime": prettyUptime(gamemgr.GetServerUptime()), | |
| var uptime any | |
| if runState { | |
| uptime = prettyUptime(gamemgr.GetServerUptime()) | |
| } else { | |
| uptime = nil | |
| } | |
| response := map[string]any{ | |
| "isRunning": runState, | |
| "uptime": uptime, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, fine.
Copilot
AI
Feb 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prettyUptime duplicates uptime formatting logic that already exists in gamemgr (see gamemgr.FormatUptime in src/managers/gamemgr/uptime.go). Having multiple formatters risks inconsistent uptime display across CLI/Web. Prefer reusing a single formatter (and extend the existing one to support days if needed) instead of introducing a new one in the web layer.
| // helper to format the uptime in a more human readable way, e.g. "1d2h3m4s" instead of "26h3m4s" | |
| func prettyUptime(d time.Duration) string { | |
| if d <= 0 { | |
| return "0s" | |
| } | |
| d = d.Round(time.Second) // optional: round to nearest second | |
| var parts []string | |
| days := int64(d / (24 * time.Hour)) | |
| d -= time.Duration(days) * 24 * time.Hour | |
| hours := int64(d / time.Hour) | |
| d -= time.Duration(hours) * time.Hour | |
| minutes := int64(d / time.Minute) | |
| d -= time.Duration(minutes) * time.Minute | |
| seconds := int64(d / time.Second) | |
| if days > 0 { | |
| parts = append(parts, fmt.Sprintf("%dd", days)) | |
| } | |
| if hours > 0 || days > 0 { | |
| parts = append(parts, fmt.Sprintf("%dh", hours)) | |
| } | |
| if minutes > 0 || hours > 0 || days > 0 { | |
| parts = append(parts, fmt.Sprintf("%dm", minutes)) | |
| } | |
| parts = append(parts, fmt.Sprintf("%ds", seconds)) | |
| return strings.Join(parts, "") | |
| // helper to format the uptime in a more human readable way; delegates to the shared gamemgr formatter | |
| func prettyUptime(d time.Duration) string { | |
| return gamemgr.FormatUptime(d) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair, but thats also fine for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new .uptime-display is positioned at
right: 50px, but the existing update icon is atright: 45px(and the status indicator atright: 25px). When the update button is visible, these elements will overlap and the uptime text will likely be obscured. Consider moving the uptime further left (or laying these items out in a container instead of absolute positioning) and/or setting explicit spacing/z-index.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will have a look next feature-friday