fix(theme): apply per-user theme_pref on login, persist toggle to server
alpine-init.js resolved the theme purely from localStorage, so it never reflected the logged-in user's theme_pref: switching user kept the previous user's theme because localStorage persists per-browser. - base.html injects window.__SERVER_THEME from the session theme (empty when anonymous, preserving OS-preference behaviour on the login page). - alpine-init.js now treats the server value as authoritative for logged-in users (server > localStorage > OS > light) and syncs localStorage to it. - The navbar toggle now persists the choice via POST /auth/set-theme, which updates the session and the user's theme_pref, so it survives navigation and matches on the next login. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"""Authentication blueprint - login, logout, profile."""
|
||||
from functools import wraps
|
||||
|
||||
from flask import Blueprint, abort, flash, redirect, render_template, request, session, url_for
|
||||
from flask import Blueprint, abort, flash, jsonify, redirect, render_template, request, session, url_for
|
||||
from flask_babel import gettext as _
|
||||
|
||||
from services.api_client import api_client
|
||||
@@ -133,6 +133,27 @@ def logout():
|
||||
return redirect(url_for("auth.login"))
|
||||
|
||||
|
||||
@auth_bp.route("/set-theme", methods=["POST"])
|
||||
@login_required
|
||||
def set_theme():
|
||||
"""Persist the user's theme toggle (light/dark) to session and profile.
|
||||
|
||||
Called via AJAX from the navbar theme switch so the choice survives
|
||||
navigation and matches on the next login. Best-effort on the API side:
|
||||
the session is updated regardless so the current browsing stays correct.
|
||||
"""
|
||||
theme = (request.get_json(silent=True) or {}).get("theme", "")
|
||||
if theme not in ("light", "dark"):
|
||||
return jsonify({"error": True, "detail": "invalid theme"}), 400
|
||||
|
||||
session["theme"] = theme
|
||||
try:
|
||||
api_client.put("/api/auth/me", data={"theme_pref": theme})
|
||||
except Exception:
|
||||
pass # Non-fatal: session theme is already updated for this session.
|
||||
return jsonify({"ok": True, "theme": theme})
|
||||
|
||||
|
||||
@auth_bp.route("/profile", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def profile():
|
||||
|
||||
Reference in New Issue
Block a user