From 4b48627150a84f57f03a7dfeeb857f452cc9f209 Mon Sep 17 00:00:00 2001
From: master3395
{% trans "Next cache update:" %} {% trans "Calculating..." %}
+
{% trans "Next cache update:" %} {% trans "Calculating..." %}
{% endif %}
@@ -3250,8 +3250,8 @@ function updateCacheExpiryTime() { return; } - // Get user's locale preferences - const locale = navigator.language || navigator.userLanguage || 'en-US'; + // Always use Norwegian format for NO-facing UI: DD.MM.YYYY kl. HH:MM + const locale = 'nb-NO'; const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; // Format date and time according to user's locale @@ -3264,7 +3264,6 @@ function updateCacheExpiryTime() { const timeOptions = { hour: '2-digit', minute: '2-digit', - second: '2-digit', hour12: false }; @@ -3273,11 +3272,18 @@ function updateCacheExpiryTime() { const timeStr = expiryDate.toLocaleTimeString(locale, timeOptions); // Combine with timezone abbreviation - const formatted = dateStr + ' ' + timeStr; - - // Display with timezone info - expiryElement.textContent = formatted; - expiryElement.title = 'Local time: ' + formatted + ' | Timezone: ' + timezone; + const formatted = dateStr + ' kl. ' + timeStr; + const expired = expiryElement.getAttribute('data-expired') === '1'; + const refreshStarted = expiryElement.getAttribute('data-refresh-started') === '1'; + + if (expired) { + expiryElement.textContent = refreshStarted + ? ('Utlopt (' + formatted + ') - oppdaterer i bakgrunnen') + : ('Utlopt (' + formatted + ')'); + } else { + expiryElement.textContent = formatted; + } + expiryElement.title = 'Lokal tid: ' + formatted + ' | Tidssone: ' + timezone; } catch (e) { console.error('Error formatting cache expiry time:', e); expiryElement.textContent = 'Error calculating time'; diff --git a/pluginHolder/views.py b/pluginHolder/views.py index 07545cc56..8939e430f 100644 --- a/pluginHolder/views.py +++ b/pluginHolder/views.py @@ -650,8 +650,13 @@ def installed(request): for p in pluginList: logging.writeToFile(f" - {p.get('plugin_dir')}: installed={p.get('installed')}, enabled={p.get('enabled')}") - # Get cache expiry timestamp for display (will be converted to local time in browser) + # Get cache expiry timestamp for display (browser formats this as nb-NO) cache_expiry_timestamp, _ = _get_cache_expiry_time() + cache_expired = _is_cache_expired(cache_expiry_timestamp) + refresh_started = False + if cache_expired: + # If cache is stale while on Installed page, trigger best-effort background refresh. + refresh_started = _try_start_plugin_store_refresh_background() # Sort plugins A-Å by name (case-insensitive) for Grid and Table view pluginList.sort(key=lambda p: (p.get('name') or '').lower()) @@ -671,9 +676,11 @@ def installed(request): pass proc = httpProc(request, 'pluginHolder/plugins.html', - {'plugins': pluginList, 'error_plugins': errorPlugins, + {'plugins': pluginList, 'error_plugins': errorPlugins, 'installed_count': installed_count, 'active_count': active_count, - 'cache_expiry_timestamp': cache_expiry_timestamp}, 'managePlugins') + 'cache_expiry_timestamp': cache_expiry_timestamp, + 'cache_expired': cache_expired, + 'cache_refresh_started': refresh_started}, 'managePlugins') return proc.render() @csrf_exempt @@ -946,6 +953,16 @@ def _get_cache_expiry_time(): logging.writeToFile(f"Error getting cache expiry time: {str(e)}") return None, None + +def _is_cache_expired(expiry_timestamp): + """Return True if provided cache expiry timestamp is in the past.""" + try: + if not expiry_timestamp: + return False + return float(expiry_timestamp) <= time.time() + except Exception: + return False + def _get_cached_plugins(allow_expired=False): """Get plugins from cache if available and not expired