Files
buzz/desktop/src/app/communityViewTransition.ts
Kalvin C 95478919fc feat: remember per-community navigation location (#2629)
Signed-off-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
2026-07-23 22:52:25 +00:00

59 lines
1.7 KiB
TypeScript

const COMMUNITY_TRANSITION_TIMEOUT_MS = 5_000;
let finishPendingTransition: (() => void) | null = null;
export function completeCommunityViewTransition(): void {
finishPendingTransition?.();
}
export function replaceCommunityDestinationRoute(
channelId: string,
history: { replace: (href: string) => void },
): void {
history.replace(`/channels/${encodeURIComponent(channelId)}`);
}
export async function runCommunityViewTransition(
update: () => Promise<void> | void,
options: { timeoutMs?: number } = {},
): Promise<void> {
if (!document.startViewTransition) {
try {
await update();
} catch (error) {
console.error("Community transition failed:", error);
}
return;
}
let finish: (() => void) | undefined;
const targetReady = new Promise<void>((resolve) => {
finish = resolve;
});
finishPendingTransition?.();
finishPendingTransition = finish ?? null;
const timeout = window.setTimeout(
() => completeCommunityViewTransition(),
options.timeoutMs ?? COMMUNITY_TRANSITION_TIMEOUT_MS,
);
try {
const transition = document.startViewTransition(async () => {
await update();
await targetReady;
});
await transition.updateCallbackDone;
} catch (error) {
// Event handlers intentionally fire-and-forget community switches. Contain
// navigation/apply failures here so rejection cannot escape React; update()
// either leaves the current route intact or at the deliberate Home barrier.
console.error("Community transition failed:", error);
} finally {
window.clearTimeout(timeout);
if (finishPendingTransition === finish) {
finishPendingTransition = null;
}
}
}