Add rules edition setting for condition tooltips (5e/5.5e)
Introduce a settings modal (opened from the kebab menu) with a rules edition selector for condition tooltip descriptions and a theme picker replacing the inline cycle button. About half the conditions have meaningful mechanical differences between editions. - Add description5e field to ConditionDefinition with 5e (2014) text - Add RulesEditionProvider context with localStorage persistence - Create SettingsModal with Conditions and Theme sections - Wire condition tooltips to edition-aware descriptions - Fix 6 inaccurate 5.5e condition descriptions - Update spec 003 with stories CC-3, CC-8 and FR-095–FR-102 Closes #12 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
52
apps/web/src/hooks/use-rules-edition.ts
Normal file
52
apps/web/src/hooks/use-rules-edition.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import type { RulesEdition } from "@initiative/domain";
|
||||
import { useCallback, useSyncExternalStore } from "react";
|
||||
|
||||
const STORAGE_KEY = "initiative:rules-edition";
|
||||
|
||||
const listeners = new Set<() => void>();
|
||||
let currentEdition: RulesEdition = loadEdition();
|
||||
|
||||
function loadEdition(): RulesEdition {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY);
|
||||
if (raw === "5e" || raw === "5.5e") return raw;
|
||||
} catch {
|
||||
// storage unavailable
|
||||
}
|
||||
return "5.5e";
|
||||
}
|
||||
|
||||
function saveEdition(edition: RulesEdition): void {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, edition);
|
||||
} catch {
|
||||
// quota exceeded or storage unavailable
|
||||
}
|
||||
}
|
||||
|
||||
function notifyAll(): void {
|
||||
for (const listener of listeners) {
|
||||
listener();
|
||||
}
|
||||
}
|
||||
|
||||
function subscribe(callback: () => void): () => void {
|
||||
listeners.add(callback);
|
||||
return () => listeners.delete(callback);
|
||||
}
|
||||
|
||||
function getSnapshot(): RulesEdition {
|
||||
return currentEdition;
|
||||
}
|
||||
|
||||
export function useRulesEdition() {
|
||||
const edition = useSyncExternalStore(subscribe, getSnapshot);
|
||||
|
||||
const setEdition = useCallback((next: RulesEdition) => {
|
||||
currentEdition = next;
|
||||
saveEdition(next);
|
||||
notifyAll();
|
||||
}, []);
|
||||
|
||||
return { edition, setEdition } as const;
|
||||
}
|
||||
Reference in New Issue
Block a user