UI Build Polling

This page explains local UI build identity, cache invalidation, polling, refresh comparison, dismissal, and retry behavior. For the resulting refresh dialog and shared modal state, see Update Prompts and Stored State.

UI build identity is generated by getWsprryPiUiBuildId() in ui_version.php.

It hashes records for tracked UI files:

  • Extensions: css, js, php

  • Excludes directory: cache/

  • Excludes file: view_diag_logs.php

  • Record format: relative/path|mtime|size

  • Build ID format: mtime-<16-char-sha256-prefix>

The loaded page receives:

window.WSPRRYPI_UI_VERSION
window.WSPRRYPI_UI_BUILD_ID

from header.php.

Static asset URLs use wsprrypiAssetUrl(), which appends:

?v=<ui_build_id>

This busts CSS/JS/font cache when tracked UI files change.

Runtime polling is controlled by:

const UI_BUILD_POLL_INTERVAL_MS = 60 * 1000;

initUiBuildChangePolling();
checkUiBuildVersion();
maybePromptForUiRefresh();
refreshUiForVersion();

initUiBuildChangePolling() starts one interval every 60 seconds. It also binds visibilitychange; when the document becomes visible again, checkUiBuildVersion() runs immediately. Duplicate intervals are prevented by:

uiBuildPollTimer !== null

checkUiBuildVersion() fetches /version through:

getJsonWithEndpointFallback(VERSION_ENDPOINT)

It only calls maybePromptForUiRefresh() if the response includes ui_build_id or ui_version.

uiBuildVersionCheckRunning

prevents overlapping checks.

maybePromptForUiRefresh() compares:

  • Preferred: loaded window.WSPRRYPI_UI_BUILD_ID vs server ui_build_id

  • Fallback: loaded window.WSPRRYPI_UI_VERSION vs server ui_version

If different, it shows a modal titled:

UI refresh required

Confirm calls:

refreshUiForVersion(serverVersion, serverBuildId)

which reloads via:

current-url?ui_refresh=<serverBuildId-or-version>

using:

window.location.replace()

Cancel or modal hidden suppresses repeat prompts for that same server build/version in memory:

dismissedUiRefreshBuildId
dismissedUiRefreshVersion

This suppression is not persisted to localStorage.

If showConfirmationDialog() fails to show the modal, it returns false; uiRefreshPromptActive remains false, so the next poll retries. If #confirmModal is missing, the prompt is deferred and retried later.