diff --git a/apps/web/src/api/buster_rest/version/queryRequests.ts b/apps/web/src/api/buster_rest/version/queryRequests.ts new file mode 100644 index 000000000..cd85515d1 --- /dev/null +++ b/apps/web/src/api/buster_rest/version/queryRequests.ts @@ -0,0 +1,9 @@ +import { useQuery } from '@tanstack/react-query'; +import { getAppBuildId } from '@/api/server-functions/getAppVersion'; + +export const useGetAppBuildId = () => { + return useQuery({ + queryKey: ['app-version'] as const, + queryFn: getAppBuildId, + }); +}; diff --git a/apps/web/src/api/query_keys/version.ts b/apps/web/src/api/query_keys/version.ts new file mode 100644 index 000000000..eb559578d --- /dev/null +++ b/apps/web/src/api/query_keys/version.ts @@ -0,0 +1,8 @@ +import { queryOptions } from '@tanstack/react-query'; +import { getAppBuildId } from '@/api/server-functions/getAppVersion'; + +export const versionGetAppVersion = queryOptions({ + queryKey: ['app-version'] as const, + queryFn: getAppBuildId, + refetchInterval: 20000, // 20 seconds +}); diff --git a/apps/web/src/api/server-functions/getAppVersion.ts b/apps/web/src/api/server-functions/getAppVersion.ts index a76442972..ef265a408 100644 --- a/apps/web/src/api/server-functions/getAppVersion.ts +++ b/apps/web/src/api/server-functions/getAppVersion.ts @@ -2,7 +2,7 @@ import { createServerFn } from '@tanstack/react-start'; export const getAppBuildId = createServerFn({ method: 'GET' }).handler(async () => { return { - buildId: import.meta.env.VITE_BUILD_ID, - buildAt: import.meta.env.VITE_BUILD_AT, + buildId: import.meta.env.VITE_BUILD_ID as string, + buildAt: import.meta.env.VITE_BUILD_AT as string, }; }); diff --git a/apps/web/src/components/features/global/LazyErrorCard.tsx b/apps/web/src/components/features/global/LazyErrorCard.tsx new file mode 100644 index 000000000..4fba22f6e --- /dev/null +++ b/apps/web/src/components/features/global/LazyErrorCard.tsx @@ -0,0 +1,9 @@ +import type React from 'react'; +import { ErrorBoundary } from 'react-error-boundary'; +import { useIsVersionChanged } from '@/context/AppVersion/useAppVersion'; +import { ErrorCard } from './GlobalErrorCard'; + +export const LazyErrorCard: React.FC = ({ children }) => { + const isChanged = useIsVersionChanged(); + return }>{children}; +}; diff --git a/apps/web/src/context/AppVersion/useAppVersion.tsx b/apps/web/src/context/AppVersion/useAppVersion.tsx index e5e8412df..81360d614 100644 --- a/apps/web/src/context/AppVersion/useAppVersion.tsx +++ b/apps/web/src/context/AppVersion/useAppVersion.tsx @@ -1,20 +1,22 @@ -import { useQuery } from '@tanstack/react-query'; -import { useEffect, useState } from 'react'; +import { type QueryKey, useQuery } from '@tanstack/react-query'; +import { useCallback, useEffect, useState } from 'react'; +import { versionGetAppVersion } from '@/api/query_keys/version'; import { getAppBuildId } from '@/api/server-functions/getAppVersion'; import { Text } from '@/components/ui/typography'; import { useWindowFocus } from '@/hooks/useWindowFocus'; import { useBusterNotifications } from '../BusterNotifications'; -const browserBuild = import.meta.env.VITE_BUILD_ID; +const browserBuild = import.meta.env.VITE_BUILD_ID as string; + +const checkNewVersion = (buildId: string | undefined): boolean => { + if (!buildId || !browserBuild) return false; + return buildId !== browserBuild; +}; export const useAppVersion = () => { const { openInfoNotification } = useBusterNotifications(); - const { data, refetch, isFetched } = useQuery({ - queryKey: ['app-version'] as const, - queryFn: getAppBuildId, - refetchInterval: 20000, // 20 seconds - }); - const isChanged = data?.buildId !== browserBuild && isFetched && browserBuild; + const { data, refetch, isFetched } = useQuery(versionGetAppVersion); + const isChanged = checkNewVersion(data?.buildId); const reloadWindow = () => { window.location.reload(); @@ -49,16 +51,16 @@ export const useAppVersion = () => { }; const AppVersionMessage = () => { - // const [countdown, setCountdown] = useState(30); - // useEffect(() => { - // const interval = setInterval(() => { - // setCountdown((prev) => Math.max(prev - 1, 0)); - // if (countdown === 0) { - // // window.location.reload(); - // } - // }, 1000); - // return () => clearInterval(interval); - // }, []); + // const [countdown, setCountdown] = useState(180); + // useEffect(() => { + // const interval = setInterval(() => { + // setCountdown((prev) => Math.max(prev - 1, 0)); + // if (countdown === 0) { + // window.location.reload(); + // } + // }, 1000); + // return () => clearInterval(interval); + // }, []); return ( @@ -66,3 +68,11 @@ const AppVersionMessage = () => { ); }; + +export const useIsVersionChanged = () => { + const { data } = useQuery({ + ...versionGetAppVersion, + select: useCallback((data: { buildId: string }) => checkNewVersion(data.buildId), []), + }); + return data; +};