refresh frontend on backend restart, fix caching statics

This commit is contained in:
Simon 2025-10-27 13:14:26 +07:00
parent 968183d216
commit f8be724e70
No known key found for this signature in database
GPG Key ID: 2C15AA5E89985DD4
6 changed files with 61 additions and 6 deletions

View File

@ -0,0 +1,13 @@
"""middleware"""
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin
class StartTimeMiddleware(MiddlewareMixin):
"""add a start time header"""
def __call__(self, request):
response = self.get_response(request)
response["X-Start-Timestamp"] = settings.TA_START
return response

View File

@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import hashlib
from datetime import datetime
from os import environ, path
from pathlib import Path
@ -76,6 +77,7 @@ MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"corsheaders.middleware.CorsMiddleware",
"config.middleware.StartTimeMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
@ -220,10 +222,13 @@ CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = list(default_headers) + [
"mode",
]
CORS_EXPOSE_HEADERS = ["X-Start-Timestamp"]
# TA application settings
TA_UPSTREAM = "https://github.com/tubearchivist/tubearchivist"
TA_VERSION = "v0.5.8-unstable"
TA_START = str(int(datetime.now().timestamp()))
# API
REST_FRAMEWORK = {

View File

@ -50,17 +50,21 @@ server {
root /app/static;
index index.html;
location ~* .(?:css|js)$ {
location ~* ^/(?!static/|cache/).*\.(?:css|js|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
try_files $uri $uri/ /index.html =404;
}
location = /index.html {
add_header Cache-Control 'no-store';
add_header Cache-Control "no-store, no-cache, must-revalidate";
add_header Pragma "no-cache";
add_header Expires 0;
expires 0;
}
location / {
add_header Cache-Control 'no-store';
add_header Cache-Control "no-store, no-cache, must-revalidate";
add_header Pragma "no-cache";
add_header Expires 0;
try_files $uri $uri/ /index.html =404;
}
}

View File

@ -4,6 +4,7 @@ import getFetchCredentials from '../configuration/getFetchCredentials';
import logOut from '../api/actions/logOut';
import getCookie from './getCookie';
import Routes from '../configuration/routes/RouteList';
import { useBackendStore } from '../stores/BackendStore';
export interface ApiClientOptions extends Omit<RequestInit, 'body'> {
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
@ -44,6 +45,12 @@ const APIClient = async <T>(
...options,
});
const backendTimestamp = response.headers.get('X-Start-Timestamp');
if (backendTimestamp) {
const { setStartTimestamp } = useBackendStore.getState();
setStartTimestamp(backendTimestamp);
}
// Handle common errors
if (response.status === 400) {
const data = await response.json();

View File

@ -0,0 +1,18 @@
import { create } from 'zustand';
interface BackendState {
startTimestamp: string | null;
setStartTimestamp: (timestamp: string) => void;
}
export const useBackendStore = create<BackendState>((set, get) => ({
startTimestamp: null,
setStartTimestamp: timestamp => {
const prev = get().startTimestamp;
if (prev && prev !== timestamp) {
console.warn('Backend restart detected — reloading frontend...');
window.location.reload();
}
set({ startTimestamp: timestamp });
},
}));

View File

@ -8,14 +8,22 @@ export default defineConfig({
base: '/',
server: {
host: true,
port: 3000, // This is the port which we will use in docker
// Thanks @sergiomoura for the window fix
// add the next lines if you're using windows and hot reload doesn't work
port: 3000,
watch: {
usePolling: true,
},
},
build: {
sourcemap: true,
outDir: 'dist',
assetsDir: 'assets',
manifest: true,
rollupOptions: {
output: {
entryFileNames: 'assets/[name].[hash].js',
chunkFileNames: 'assets/[name].[hash].js',
assetFileNames: 'assets/[name].[hash].[ext]',
},
},
},
});