mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-02 18:01:29 -05:00
Revalidate subscribe pages on tab back + resub
This commit is contained in:
parent
0b9e60337a
commit
78f7baf075
|
|
@ -44,6 +44,7 @@ import { Status } from "~/db/types";
|
|||
import { checkInHasStarted, teamHasCheckedIn } from "~/features/tournament";
|
||||
import clsx from "clsx";
|
||||
import { LinkButton } from "~/components/Button";
|
||||
import { useVisibilityChange } from "~/hooks/useVisibilityChange";
|
||||
|
||||
export const links: LinksFunction = () => {
|
||||
return [
|
||||
|
|
@ -131,6 +132,8 @@ export const loader = ({ params }: LoaderArgs) => {
|
|||
};
|
||||
|
||||
export default function TournamentBracketsPage() {
|
||||
const visibility = useVisibilityChange();
|
||||
const { revalidate } = useRevalidator();
|
||||
const user = useUser();
|
||||
const data = useLoaderData<typeof loader>();
|
||||
const ref = React.useRef<HTMLDivElement>(null);
|
||||
|
|
@ -212,13 +215,20 @@ export default function TournamentBracketsPage() {
|
|||
lessThanTwoTeamsRegistered,
|
||||
]);
|
||||
|
||||
// TODO: also disable autorefresh (don't render component) and don't trigger revalidate after tournament is finalized
|
||||
React.useEffect(() => {
|
||||
if (visibility !== "visible") return;
|
||||
|
||||
revalidate();
|
||||
}, [visibility, revalidate]);
|
||||
|
||||
const myTeam = parentRouteData.teams.find((team) =>
|
||||
team.members.some((m) => m.userId === user?.id)
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<AutoRefresher />
|
||||
{visibility !== "hidden" ? <AutoRefresher /> : null}
|
||||
{!data.hasStarted && !lessThanTwoTeamsRegistered ? (
|
||||
<Form method="post" className="stack items-center">
|
||||
{!canAdminTournament({ user, event: parentRouteData.event }) ? (
|
||||
|
|
@ -299,6 +309,7 @@ function useAutoRefresh() {
|
|||
// so we revalidate loader when the match is over
|
||||
revalidate();
|
||||
} else {
|
||||
// TODO: shows 1 - "-" when updating match where other score is 0
|
||||
// @ts-expect-error - brackets-viewer is not typed
|
||||
window.bracketsViewer.updateMatch({
|
||||
id: matchId,
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import { nanoid } from "nanoid";
|
|||
import { emitter } from "../core/emitters.server";
|
||||
import { useEventSource } from "remix-utils";
|
||||
import * as React from "react";
|
||||
import { useVisibilityChange } from "~/hooks/useVisibilityChange";
|
||||
|
||||
export const links: LinksFunction = () => [
|
||||
{
|
||||
|
|
@ -298,20 +299,28 @@ export const loader = ({ params }: LoaderArgs) => {
|
|||
};
|
||||
|
||||
export default function TournamentMatchPage() {
|
||||
const visibility = useVisibilityChange();
|
||||
const { revalidate } = useRevalidator();
|
||||
const parentRouteData = useOutletContext<TournamentLoaderData>();
|
||||
const data = useLoaderData<typeof loader>();
|
||||
|
||||
const matchHasTwoTeams = Boolean(
|
||||
data.match.opponentOne?.id && data.match.opponentTwo?.id
|
||||
);
|
||||
|
||||
const matchIsOver =
|
||||
data.match.opponentOne?.result === "win" ||
|
||||
data.match.opponentTwo?.result === "win";
|
||||
|
||||
const matchHasTwoTeams = Boolean(
|
||||
data.match.opponentOne?.id && data.match.opponentTwo?.id
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (visibility !== "visible" || matchIsOver) return;
|
||||
|
||||
revalidate();
|
||||
}, [visibility, revalidate, matchIsOver]);
|
||||
|
||||
return (
|
||||
<div className="stack lg">
|
||||
{!matchIsOver ? <AutoRefresher /> : null}
|
||||
{!matchIsOver && visibility !== "hidden" ? <AutoRefresher /> : null}
|
||||
<div className="flex horizontal justify-between items-center">
|
||||
{/* TODO: better title */}
|
||||
<h2 className="text-lighter text-lg">Match #{data.match.id}</h2>
|
||||
|
|
|
|||
|
|
@ -36,9 +36,8 @@ export const shouldRevalidate: ShouldRevalidateFunction = (args) => {
|
|||
}
|
||||
|
||||
const wasRevalidation = !args.formMethod;
|
||||
const wasOnBracketPage = args.currentUrl.href.includes("brackets");
|
||||
|
||||
if (wasRevalidation && wasOnBracketPage) {
|
||||
if (wasRevalidation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
23
app/hooks/useVisibilityChange.ts
Normal file
23
app/hooks/useVisibilityChange.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import React from "react";
|
||||
|
||||
// "initial" = user has not tabbed out yet
|
||||
type Visibility = "initial" | DocumentVisibilityState;
|
||||
|
||||
/** Track the `visibilitychange` event: The `visibilitychange` event is fired at the document when the contents of its tab have become visible or have been hidden. */
|
||||
export function useVisibilityChange() {
|
||||
const [visible, setVisible] = React.useState<Visibility>("initial");
|
||||
|
||||
React.useEffect(() => {
|
||||
function handleVisibilityChange() {
|
||||
setVisible(document.visibilityState);
|
||||
}
|
||||
|
||||
document.addEventListener("visibilitychange", handleVisibilityChange);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return visible;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user