stop the Database block flickering, properly this time

It switched to the live answer as soon as `status` arrived — while
`backupsReady` was still its initial `false`, which is a REPORT of not-ready
rather than the absence of one. So it decided the section was unfinished,
painted open, and shut again a moment later when the real answer came.

`backupsReady` is now null until BackupsRow has actually answered, and the live
value is used only once every local part has. Until then the summary decides,
which is what it was added for.

And nothing but the header renders until the summary lands. The title and hint
are constants and can paint immediately; only the check and the body wait on
data — the same shape Root location settled on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-29 13:35:02 +01:00
co-authored by Claude Opus 5
parent af31b57cdf
commit 51ccf55a3c
+14 -3
View File
@@ -88,7 +88,9 @@ export const DatabaseBlock = () => {
`BackupsRow` actually know. See RootLocationBlock for why both sources are needed.
*/
const [summaryReady, setSummaryReady] = useState<boolean | null>(null);
const [backupsReady, setBackupsReady] = useState(false);
/* null until BackupsRow has actually answered. `false` would be a REPORT of not-ready, and using
it before the answer exists is what made this block paint open and then shut. */
const [backupsReady, setBackupsReady] = useState<boolean | null>(null);
const [collapsed, setCollapsed] = useState<boolean | null>(null);
useEffect(() => {
@@ -276,7 +278,16 @@ export const DatabaseBlock = () => {
(status.development.tables ?? 0) > 0 &&
backupsReady,
);
const settledNow = status ? live : summaryReady === true;
/*
The summary until EVERY local part has answered, then the live value.
Both conditions, not either. Switching as soon as `status` arrived meant using `backupsReady` while
it was still its initial value — an answer nobody had given — so the block decided it was unfinished
and opened, and shut again a moment later when the real answer came.
*/
const answered = status !== null && backupsReady !== null;
const settledNow = answered ? live : summaryReady === true;
useEffect(() => {
setCollapsed((chosen) => {
@@ -308,7 +319,7 @@ export const DatabaseBlock = () => {
) : undefined
}
>
{!status ? null : settled ? (
{summaryReady === null || !status ? null : settledNow ? (
<>
{row('Production', 'production', status.production)}
{row('Development', 'development', status.development)}