feat(ui): source the footer version from /api/version instead of a JS literal

The footer string in the browser was a hard-coded `const APP_VERSION = "v1.9"`
in assets/main.js, completely disconnected from the Makefile's VERSION_TAG.
It had already drifted: the UI kept showing "v1.9" through the entire v1.9.1
release, while the startup notification and the ELF name both said v1.9.1.
Two sources of truth for one fact is one too many.

Backend:
  * new src/version.c -- GET /api/version -> {"ok":true,"version":"v1.9.1",
    "titleId":"FMGR88888"}, built straight from the -DVERSION_TAG /
    -DTITLE_ID macros the Makefile already passes, so there is nothing left
    to forget when bumping a release.
  * registered in filemgr_api_request() next to /api/space and declared in
    filemgr_internal.h; added to COMMON_SRCS so both the PS5 and the linux
    targets link it.

Frontend:
  * the literal becomes APP_VERSION_FALLBACK and is rendered first so the
    footer is never empty, then loadVersion() refreshes it from the API in
    the background. A failed request is deliberately swallowed -- a wrong
    version string is cosmetic and should not raise an error toast.
  * both the host i18n path and the PlayStation browser branch are
    untouched; the footer element itself (#versionText) does not move.

Note the earlier answer to "does the version show in the PS5 UI?" was that it
does -- the bottom-right footer -- but it was showing the stale literal, not
the build's real tag. That is what this fixes.

Verified:
  * WSL prospero-clang 18.1.8 -- ELF 1017864 B, e_machine=0x003e, contains
    both the string "v1.9.1" and the "/api/version" route.
  * MinGW gcc 16.2.0 host tests -- ZIP 108 + RAR 27 + 7z 28 = 163 checks,
    0 failures.
This commit is contained in:
Songlx516 committed 2026-09-15 16:48:53 +08:00
1 parent 1fa2f0953f
commit 0d036a74a7
5 files changed
+56 -3

No files matched your search

+1 -1
View File
@@ -30,7 +30,7 @@ HOST_PKG_CONFIG ?= pkg-config
# and you can tell at a glance which ELF is on the USB stick.
BIN := web-file-mgr-$(VERSION_TAG).elf
LINUX_BIN := web-file-mgr-linux-$(VERSION_TAG)
COMMON_SRCS := src/main.c src/websrv.c src/filemgr.c src/file_response.c src/task.c src/upload.c src/download.c src/text.c src/list.c src/space.c src/fs_util.c src/json_util.c src/path_util.c src/asset.c src/mime.c src/notify.c src/pkg_installer.c src/pkg_info.c src/extract.c src/zip_extract.c src/rar_extract.c src/zipx_volume.c src/zipx_volstream.c src/zipx_common.c src/sevenz_extract.c src/sevenz_chain.c src/sevenz_volstream.c
COMMON_SRCS := src/main.c src/websrv.c src/filemgr.c src/file_response.c src/task.c src/upload.c src/download.c src/text.c src/list.c src/space.c src/version.c src/fs_util.c src/json_util.c src/path_util.c src/asset.c src/mime.c src/notify.c src/pkg_installer.c src/pkg_info.c src/extract.c src/zip_extract.c src/rar_extract.c src/zipx_volume.c src/zipx_volstream.c src/zipx_common.c src/sevenz_extract.c src/sevenz_chain.c src/sevenz_volstream.c
PS5_SRCS := $(COMMON_SRCS) src/app_installer.c src/cpu_support_stub.c
LINUX_SRCS := $(COMMON_SRCS)
BASE_ASSETS := $(filter-out %.dds,$(wildcard assets/*))
+19 -2
View File
@@ -35,7 +35,11 @@ let uploadXhr = null;
let uploadTerminalAbort = false;
let L = {};
const APP_VERSION = "v1.9";
// Last-resort fallback for the footer. The real value comes from
// /api/version, which reports the build's VERSION_TAG -- see loadVersion().
// Keeping a literal here used to be the only source, and it inevitably
// drifted (the footer said "v1.9" throughout the v1.9.1 release).
const APP_VERSION_FALLBACK = "v1.9.1";
const LAST_PATH_KEY = "ps5-web-file-mgr:last-path";
const SORT_KEY = "ps5-web-file-mgr:list-sort";
const LOADING_DISPLAY_DELAY = 250;
@@ -180,10 +184,22 @@ function applyStaticText() {
exitBtn.setAttribute("aria-label", t("exit"));
parentBtn.title = t("parent");
parentBtn.setAttribute("aria-label", t("parent"));
versionEl.textContent = APP_VERSION;
versionEl.textContent = APP_VERSION_FALLBACK;
if (initLoadingEl) initLoadingEl.hidden = true;
}
// Ask the backend which version it was built as, so the footer can never
// disagree with the Makefile. A failure here is cosmetic: we simply keep the
// fallback text rather than nagging the user with an error toast.
async function loadVersion() {
try {
const data = await api("/api/version");
if (data && data.version) versionEl.textContent = data.version;
} catch (err) {
/* offline or very old payload -- keep APP_VERSION_FALLBACK */
}
}
function nextPaint() {
return new Promise(resolve => {
if (window.requestAnimationFrame) {
@@ -2628,6 +2644,7 @@ contentEl.addEventListener("scroll", () => {
async function init() {
await loadLanguage();
applyStaticText();
loadVersion();
readSavedSort();
updateSortHeaders();
const savedPath = historyPath() || readSavedPath();
+1
View File
@@ -2399,6 +2399,7 @@ filemgr_api_request(struct MHD_Connection *conn, const char *url,
if(!strcmp(url, "/api/list")) return api_list(conn);
if(!strcmp(url, "/api/tasks")) return api_tasks(conn);
if(!strcmp(url, "/api/space")) return api_space(conn);
if(!strcmp(url, "/api/version")) return api_version(conn);
if(!strcmp(url, "/api/cancel")) return api_cancel(conn);
if(!strcmp(url, "/api/exit")) return api_exit(conn);
if(!strcmp(url, "/api/copy")) return api_copy(conn, body, body_size);
+1
View File
@@ -133,6 +133,7 @@ enum MHD_Result api_download_prepare(struct MHD_Connection *conn,
enum MHD_Result api_download(struct MHD_Connection *conn);
enum MHD_Result api_list(struct MHD_Connection *conn);
enum MHD_Result api_space(struct MHD_Connection *conn);
enum MHD_Result api_version(struct MHD_Connection *conn);
enum MHD_Result api_text(struct MHD_Connection *conn);
enum MHD_Result api_text_create(struct MHD_Connection *conn);
enum MHD_Result api_text_save(struct MHD_Connection *conn, const char *body,
+34
View File
@@ -0,0 +1,34 @@
/*
* /api/version -- hands the build's VERSION_TAG to the web UI.
*
* The footer in the browser shows a version string, and for a long time that
* string was a literal in assets/main.js, so it drifted out of sync the moment
* the Makefile moved on (v1.9 stayed on screen through the whole v1.9.1
* release). Exposing it over the API keeps a single source of truth: bump
* VERSION_TAG in the Makefile and every surface -- startup notification
* (src/main.c), stdout banner, ELF file name and the UI footer -- follows.
*
* The response is tiny and immutable, so the client caches it for the session.
*/
#include "filemgr_internal.h"
#include <string.h>
#include "json_util.h"
#ifndef VERSION_TAG
#define VERSION_TAG "unknown"
#endif
enum MHD_Result
api_version(struct MHD_Connection *conn) {
strbuf_t b = {0};
strbuf_append(&b, "{\"ok\":true,\"version\":");
json_escape(&b, VERSION_TAG);
strbuf_append(&b, ",\"titleId\":");
json_escape(&b, TITLE_ID);
strbuf_append(&b, "}");
return send_buffer(conn, MHD_HTTP_OK, b.data, "application/json");
}