Enhance log display behavior and menu state management
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-02-11 14:37:02 +11:00
parent 9bd2b32003
commit ffd43d5217
9 changed files with 166 additions and 52 deletions

View File

@@ -467,6 +467,10 @@ nav p {
padding: 8px; padding: 8px;
border-radius: 8px; border-radius: 8px;
background: rgba(13, 31, 49, 0.72); background: rgba(13, 31, 49, 0.72);
white-space: pre-wrap;
overflow-wrap: anywhere;
word-break: break-word;
line-height: 1.45;
} }
#logScreen p { #logScreen p {
@@ -689,6 +693,45 @@ nav p {
max-height: 96px; max-height: 96px;
} }
body.menu-log-focus #clientInfo,
body.menu-log-focus .dashboard-cards,
body.menu-log-focus #myStreamsBox {
display: none;
}
body.menu-log-focus #content {
padding: 8px;
padding-bottom: calc(12px + env(safe-area-inset-bottom));
}
body.menu-log-focus #content h3 {
margin-bottom: 4px;
}
body.menu-log-focus #content-interaction {
top: 8px;
margin-bottom: 8px;
padding: 6px;
}
body.menu-log-focus #content-interaction .search {
display: none;
}
body.menu-log-focus #content-interaction input[type=button] {
min-height: 38px;
}
body.menu-log-focus #content_log {
padding: 5px;
}
body.menu-log-focus #content_log pre {
margin-bottom: 4px;
padding: 7px;
font-size: 11px;
}
.phone { .phone {
display: none; display: none;
} }

View File

@@ -21,15 +21,22 @@ function showLogs(bottom) {
var log = new Log(); var log = new Log();
var logs = SERVER["log"]["log"]; var logs = SERVER["log"]["log"];
var div = document.getElementById("content_log"); var div = document.getElementById("content_log");
var wrapper = document.getElementById("box-wrapper");
var shouldStickToBottom = bottom;
div.innerHTML = ""; div.innerHTML = "";
if (wrapper != null && shouldStickToBottom == false) {
var distanceToBottom = wrapper.scrollHeight - wrapper.scrollTop - wrapper.clientHeight;
if (distanceToBottom < 80) {
shouldStickToBottom = true;
}
}
var keys = getObjKeys(logs); var keys = getObjKeys(logs);
keys.forEach(function (logID) { keys.forEach(function (logID) {
var entry = log.createLog(logs[logID]); var entry = log.createLog(logs[logID]);
div.append(entry); div.append(entry);
}); });
setTimeout(function () { setTimeout(function () {
if (bottom == true) { if (shouldStickToBottom == true && wrapper != null) {
var wrapper = document.getElementById("box-wrapper");
wrapper.scrollTop = wrapper.scrollHeight; wrapper.scrollTop = wrapper.scrollHeight;
} }
}, 10); }, 10);

View File

@@ -895,9 +895,28 @@ function setActiveMenu(menuID) {
items[i].removeAttribute("aria-current"); items[i].removeAttribute("aria-current");
} }
var activeItem = document.getElementById(ACTIVE_MENU_ID); var activeItem = document.getElementById(ACTIVE_MENU_ID);
var activeMenuKey = "";
if (activeItem != null) { if (activeItem != null) {
activeItem.classList.add("menu-active"); activeItem.classList.add("menu-active");
activeItem.setAttribute("aria-current", "page"); activeItem.setAttribute("aria-current", "page");
var menuKeyValue = activeItem.getAttribute("data-menu");
if (menuKeyValue != null) {
activeMenuKey = menuKeyValue;
}
}
if (document.body != null) {
if (activeMenuKey.length > 0) {
document.body.setAttribute("data-active-menu", activeMenuKey);
}
else {
document.body.removeAttribute("data-active-menu");
}
if (activeMenuKey == "log") {
document.body.classList.add("menu-log-focus");
}
else {
document.body.classList.remove("menu-log-focus");
}
} }
} }
function renderStatusCards() { function renderStatusCards() {
@@ -989,6 +1008,9 @@ function PageReady() {
calculateWrapperHeight(); calculateWrapperHeight();
}, true); }, true);
setInterval(function () { setInterval(function () {
if (document.hidden == true) {
return;
}
updateLog(); updateLog();
}, 10000); }, 10000);
return; return;

View File

@@ -88,7 +88,7 @@ var Server = /** @class */ (function () {
errorState = "idle"; errorState = "idle";
} }
finishRequest(errorState, false); finishRequest(errorState, false);
if (WS_AVAILABLE == false) { if (WS_AVAILABLE == false && isLogUpdate == false) {
alert("No websocket connection to xTeVe could be established. Check your network configuration."); alert("No websocket connection to xTeVe could be established. Check your network configuration.");
} }
}; };

View File

@@ -7,6 +7,7 @@ import (
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"sync"
"crypto/hmac" "crypto/hmac"
"crypto/rand" "crypto/rand"
@@ -29,6 +30,7 @@ var databaseFile = "authentication.json"
var data = make(map[string]any) var data = make(map[string]any)
var tokens = make(map[string]any) var tokens = make(map[string]any)
var tokensMu sync.RWMutex
var initAuthentication = false var initAuthentication = false
@@ -256,20 +258,21 @@ func CheckTheValidityOfTheToken(token string) (newToken string, err error) {
err = createError(011) err = createError(011)
tokensMu.Lock()
defer tokensMu.Unlock()
if v, ok := tokens[token]; ok { if v, ok := tokens[token]; ok {
var expires = v.(map[string]any)["expires"].(time.Time) expires := v.(map[string]any)["expires"].(time.Time)
var userID = v.(map[string]any)["id"].(string)
if expires.Sub(time.Now().Local()) < 0 { if expires.Sub(time.Now().Local()) < 0 {
delete(tokens, token)
return return
} }
newToken = setToken(userID, token) // Keep a stable token per session and only refresh expiration.
v.(map[string]any)["expires"] = time.Now().Local().Add(time.Minute * time.Duration(tokenValidity))
newToken = token
err = nil err = nil
} else {
return
} }
return return
@@ -285,11 +288,15 @@ func GetUserID(token string) (userID string, err error) {
err = createError(002) err = createError(002)
tokensMu.Lock()
defer tokensMu.Unlock()
if v, ok := tokens[token]; ok { if v, ok := tokens[token]; ok {
var expires = v.(map[string]any)["expires"].(time.Time) expires := v.(map[string]any)["expires"].(time.Time)
userID = v.(map[string]any)["id"].(string) userID = v.(map[string]any)["id"].(string)
if expires.Sub(time.Now().Local()) < 0 { if expires.Sub(time.Now().Local()) < 0 {
delete(tokens, token)
return return
} }
@@ -558,7 +565,12 @@ func defaultsForNewUser(username, password string) map[string]any {
} }
func setToken(id, oldToken string) (newToken string) { func setToken(id, oldToken string) (newToken string) {
tokensMu.Lock()
defer tokensMu.Unlock()
if oldToken != "-" {
delete(tokens, oldToken) delete(tokens, oldToken)
}
loopToken: loopToken:
newToken = randomString(tokenLength) newToken = randomString(tokenLength)

File diff suppressed because one or more lines are too long

View File

@@ -29,9 +29,18 @@ function showLogs(bottom:boolean) {
var logs = SERVER["log"]["log"] var logs = SERVER["log"]["log"]
var div = document.getElementById("content_log") var div = document.getElementById("content_log")
var wrapper = document.getElementById("box-wrapper") as HTMLElement
var shouldStickToBottom:boolean = bottom
div.innerHTML = "" div.innerHTML = ""
if (wrapper != null && shouldStickToBottom == false) {
var distanceToBottom:number = wrapper.scrollHeight - wrapper.scrollTop - wrapper.clientHeight
if (distanceToBottom < 80) {
shouldStickToBottom = true
}
}
var keys = getObjKeys(logs) var keys = getObjKeys(logs)
keys.forEach(logID => { keys.forEach(logID => {
@@ -44,9 +53,8 @@ function showLogs(bottom:boolean) {
setTimeout(function(){ setTimeout(function(){
if (bottom == true) { if (shouldStickToBottom == true && wrapper != null) {
var wrapper = document.getElementById("box-wrapper");
wrapper.scrollTop = wrapper.scrollHeight; wrapper.scrollTop = wrapper.scrollHeight;
} }

View File

@@ -871,8 +871,27 @@ function setActiveMenu(menuID:string) {
} }
var activeItem = document.getElementById(ACTIVE_MENU_ID) var activeItem = document.getElementById(ACTIVE_MENU_ID)
var activeMenuKey:string = ""
if (activeItem != null) { if (activeItem != null) {
activeItem.classList.add("menu-active") activeItem.classList.add("menu-active")
var menuKeyValue = activeItem.getAttribute("data-menu")
if (menuKeyValue != null) {
activeMenuKey = menuKeyValue
}
}
if (document.body != null) {
if (activeMenuKey.length > 0) {
document.body.setAttribute("data-active-menu", activeMenuKey)
} else {
document.body.removeAttribute("data-active-menu")
}
if (activeMenuKey == "log") {
document.body.classList.add("menu-log-focus")
} else {
document.body.classList.remove("menu-log-focus")
}
} }
} }
@@ -983,6 +1002,9 @@ function PageReady() {
}, true); }, true);
setInterval(function(){ setInterval(function(){
if (document.hidden == true) {
return
}
updateLog() updateLog()
}, 10000); }, 10000);

View File

@@ -110,7 +110,7 @@ class Server {
} }
finishRequest(errorState, false) finishRequest(errorState, false)
if (WS_AVAILABLE == false) { if (WS_AVAILABLE == false && isLogUpdate == false) {
alert("No websocket connection to xTeVe could be established. Check your network configuration.") alert("No websocket connection to xTeVe could be established. Check your network configuration.")
} }