Build and Push Docker Image / build-and-push (push) Successful in 5m7s
- Settings > Preferences: typeface, line spacing, verse numbers, highlight colour names, My Studies grid/list and sort, verse-of-the-day Bible and picture, commentary sources, study templates - Header uses one fixed width and reserves scrollbar space so the nav sits in the same place on every page Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
24 lines
1.1 KiB
JavaScript
24 lines
1.1 KiB
JavaScript
import { useEffect, useState } from 'react';
|
|
|
|
const EVENT = 'local-setting';
|
|
|
|
// A preference kept in this browser's localStorage, for settings that live in more than one place (the Settings
|
|
// page and the screen they affect). Changing it in one place updates every component that reads it.
|
|
export function useLocalSetting(key, fallback) {
|
|
const read = () => { try { return localStorage.getItem(key) ?? fallback; } catch { return fallback; } };
|
|
const [value, setValue] = useState(read);
|
|
useEffect(() => {
|
|
const on = (e) => { if (!e.detail || e.detail.key === key) setValue(read()); };
|
|
window.addEventListener(EVENT, on);
|
|
window.addEventListener('storage', on);
|
|
return () => { window.removeEventListener(EVENT, on); window.removeEventListener('storage', on); };
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [key]);
|
|
const set = (next) => {
|
|
try { localStorage.setItem(key, next); } catch { /* storage unavailable: still applies until reload */ }
|
|
setValue(next);
|
|
window.dispatchEvent(new CustomEvent(EVENT, { detail: { key } }));
|
|
};
|
|
return [value, set];
|
|
}
|