feat(board): refresh the board when the window regains focus

This commit is contained in:
Dave 2026-09-16 10:03:41 +02:00
parent 972d45d38b
commit bb39519801
2 changed files with 42 additions and 1 deletions

View file

@ -1,6 +1,6 @@
"use client";
import { useMemo, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import {
DndContext,
DragOverlay,
@ -21,6 +21,7 @@ import { CSS } from "@dnd-kit/utilities";
import { BoardColumn } from "@/components/board/board-column";
import { CardTile } from "@/components/board/card-tile";
import { ClientCardControls } from "@/components/board/client-card-controls";
import { useRefreshOnFocus } from "@/components/board/use-refresh-on-focus";
import { computeDropPosition } from "@/lib/board/move";
import type { CardRecord, ColumnRecord, Role } from "@/lib/pb/types";
@ -106,6 +107,12 @@ export function Board({
const activeCard = activeId ? cards.find((c) => c.id === activeId) : null;
useRefreshOnFocus(activeId !== null);
useEffect(() => {
if (activeId === null) setCards(initialCards);
}, [initialCards, activeId]);
function onDragStart(event: DragStartEvent) {
setActiveId(String(event.active.id));
}

View file

@ -0,0 +1,34 @@
"use client";
import { useEffect } from "react";
import { useRouter } from "next/navigation";
/**
* Re-fetch the server component tree when the tab regains focus.
*
* `router.refresh()` re-runs the page's server components, so the board is
* reloaded through the same read rules as the first render. Nothing is
* fetched client-side and no token is needed.
*
* Skipped while `paused` is true, so a refresh cannot land mid-drag and pull
* the card out from under the pointer.
*/
export function useRefreshOnFocus(paused: boolean) {
const router = useRouter();
useEffect(() => {
if (paused) return;
function onFocus() {
if (document.visibilityState === "visible") router.refresh();
}
window.addEventListener("visibilitychange", onFocus);
window.addEventListener("focus", onFocus);
return () => {
window.removeEventListener("visibilitychange", onFocus);
window.removeEventListener("focus", onFocus);
};
}, [paused, router]);
}