Newer
Older
client_dwatch / lib / ui-prefs.ts
/**
 * 表示設定(ダーク/ライト・JP/EN)の保存(ユーザー決定 2026-10-19 U1。指示書BC 段階3。D-183)。
 *
 * ★保存先はブラウザの localStorage(閲覧者ごとの便利機能)★。サーバー・DB には保存しない。
 * ★読み書きは必ず try/catch★(プライベートウィンドウ・ストレージの無効化で例外になる)。使えないときは既定で描く。
 * ★キーと許す値はこのファイルだけが知る★ — `<head>` のインラインスクリプト(`app/layout.tsx`)と
 *   `ThemeProvider` が同じものを使う(片方だけ変えると、描く前と後で値が食い違う)。
 *
 * ★期待値表は `lib/__tests__/ui-prefs.test.ts`★(T1〜T5 / L1〜L4 / S1〜S4)。
 */
import type { Lang } from "@/lib/i18n";
import type { ThemeName } from "@/lib/theme";

export const THEME_STORAGE_KEY = "dwatch.theme";
export const LANG_STORAGE_KEY = "dwatch.lang";

/** 保存されていた値をテーマとして読む。★"dark" / "light" 以外(null・大文字違い・空)は null★(既定で描く) */
export function parseSavedTheme(value: string | null): ThemeName | null {
  return value === "dark" || value === "light" ? value : null;
}

/** 保存されていた値を言語として読む。★"ja" / "en" 以外は null★ */
export function parseSavedLang(value: string | null): Lang | null {
  return value === "ja" || value === "en" ? value : null;
}

/**
 * `<head>` で描く前に動かすスクリプト(文字列)。`<html>` の `data-theme` と `lang` を保存値に合わせる。
 * ★許す値は parseSaved* と同じ★。★例外はすべて握りつぶす★(使えなければ既定のまま)。
 */
export const PREFS_INLINE_SCRIPT = `(function(){try{var d=document.documentElement;var t=localStorage.getItem(${JSON.stringify(THEME_STORAGE_KEY)});if(t==="dark"||t==="light")d.setAttribute("data-theme",t);var l=localStorage.getItem(${JSON.stringify(LANG_STORAGE_KEY)});if(l==="ja"||l==="en")d.setAttribute("lang",l);}catch(e){}})()`;