Sheet: large portrait slot, writable notes in summary and lobby
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HJhXuLD2Z6hv3Wqeq9UL9K
This commit is contained in:
@@ -524,23 +524,32 @@ function DifficultyBar({ lobby, onSet }) {
|
||||
}
|
||||
|
||||
// ---- sheet of one character, refreshed regularly so the DM sees changes the player saves
|
||||
function CharTab({ cid, rules, onRoll, tick }) {
|
||||
function CharTab({ cid, rules, onRoll, tick, editable }) {
|
||||
const [data, setData] = useState(null)
|
||||
const [err, setErr] = useState('')
|
||||
const typing = useRef(0) // time of the last keystroke: refreshes must not overwrite what is being typed
|
||||
const timer = useRef(null)
|
||||
const saveNotes = (patch) => {
|
||||
typing.current = Date.now()
|
||||
setData((d) => ({ ...d, ...patch }))
|
||||
clearTimeout(timer.current)
|
||||
timer.current = setTimeout(() => { send(`/api/characters/${cid}/notes`, 'PUT', patch).catch(() => setErr('Could not save the notes.')) }, 700)
|
||||
}
|
||||
useEffect(() => () => clearTimeout(timer.current), [])
|
||||
useEffect(() => {
|
||||
setData(null); setErr('')
|
||||
const load = () => fetch(`/api/characters/${cid}`).then((r) => { if (!r.ok) throw new Error(); return r.json() }).then(setData).catch(() => setErr('Could not load this character.'))
|
||||
const load = () => fetch(`/api/characters/${cid}`).then((r) => { if (!r.ok) throw new Error(); return r.json() }).then((d) => { if (Date.now() - typing.current > 4000) setData(d) }).catch(() => setErr('Could not load this character.'))
|
||||
load()
|
||||
const t = setInterval(() => !document.hidden && load(), 15000)
|
||||
return () => clearInterval(t)
|
||||
}, [cid])
|
||||
useEffect(() => { // pushed by the server when the player saved the character
|
||||
if (tick) fetch(`/api/characters/${cid}`).then((r) => (r.ok ? r.json() : null)).then((d) => d && setData(d)).catch(() => {})
|
||||
if (tick) fetch(`/api/characters/${cid}`).then((r) => (r.ok ? r.json() : null)).then((d) => d && Date.now() - typing.current > 4000 && setData(d)).catch(() => {})
|
||||
}, [tick]) // eslint-disable-line
|
||||
return (
|
||||
<div>
|
||||
{err && <p className="warn">{err}</p>}
|
||||
{data && <PaperSheet data={data} baseRules={rules} bare onRoll={onRoll} />}
|
||||
{data && <PaperSheet data={data} baseRules={rules} bare onRoll={onRoll} onNotes={editable ? saveNotes : undefined} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -804,7 +813,7 @@ function LobbyView({ id, rules, user }) {
|
||||
{lobby.is_dm && leftTab === 'lobby'
|
||||
? <><MapLibrary activeId={mapState.map?.id} lobbyId={id} act={act} /><SoundSettings lobby={lobby} id={id} act={act} sfx={sfx.current} /><Settings inline lobby={lobby} id={id} mine={mine} act={act} setInfo={setInfo} /></>
|
||||
: npcTok ? <CharTab key={`npc${npcTok.npc_id}`} cid={npcTok.npc_id} rules={rules} tick={sheetTick.cid === npcTok.npc_id ? sheetTick.n : 0} onRoll={(k, i, n) => check(k, i, n, npcTok.id)} />
|
||||
: cur ? <CharTab key={cur.character_id} cid={cur.character_id} rules={rules} tick={sheetTick.cid === cur.character_id ? sheetTick.n : 0} onRoll={cur.me && canCheck ? check : undefined} />
|
||||
: cur ? <CharTab key={cur.character_id} cid={cur.character_id} rules={rules} tick={sheetTick.cid === cur.character_id ? sheetTick.n : 0} onRoll={cur.me && canCheck ? check : undefined} editable={cur.me} />
|
||||
: <p className="muted small">{lobby.is_dm ? 'Pick a character in the bar to look at its sheet.' : 'You have no character in this lobby.'}</p>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user