diff --git a/Makefile b/Makefile index 221d259..30dc763 100644 --- a/Makefile +++ b/Makefile @@ -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/*)) diff --git a/assets/main.js b/assets/main.js index 2c17567..7185cb1 100644 --- a/assets/main.js +++ b/assets/main.js @@ -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(); diff --git a/src/filemgr.c b/src/filemgr.c index d39daee..4834d84 100644 --- a/src/filemgr.c +++ b/src/filemgr.c @@ -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); diff --git a/src/filemgr_internal.h b/src/filemgr_internal.h index 484eb03..9ba08f4 100644 --- a/src/filemgr_internal.h +++ b/src/filemgr_internal.h @@ -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, diff --git a/src/version.c b/src/version.c new file mode 100644 index 0000000..fdbc7de --- /dev/null +++ b/src/version.c @@ -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 + +#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"); +}