diff --git a/extension/app/background.ts b/extension/app/background.ts index 1e7db061936a..d7e0ee25dac7 100644 --- a/extension/app/background.ts +++ b/extension/app/background.ts @@ -1,3 +1,6 @@ +import type { PendingUpdate } from "@extension/lib/storage"; +import { savePendingUpdate } from "@extension/lib/storage"; + import { AUTH0_AUDIENCE, AUTH0_CLIENT_DOMAIN, @@ -14,6 +17,17 @@ import { generatePKCE } from "./src/lib/utils"; const log = console.error; +/** + * Listener for force update mechanism. + */ +chrome.runtime.onUpdateAvailable.addListener(async (details) => { + const pendingUpdate: PendingUpdate = { + version: details.version, + detectedAt: Date.now(), + }; + await savePendingUpdate(pendingUpdate); +}); + /** * Listener to open/close the side panel when the user clicks on the extension icon. */ diff --git a/extension/app/src/components/auth/ProtectedRoute.tsx b/extension/app/src/components/auth/ProtectedRoute.tsx index 52636609c81a..9c144f7da899 100644 --- a/extension/app/src/components/auth/ProtectedRoute.tsx +++ b/extension/app/src/components/auth/ProtectedRoute.tsx @@ -1,9 +1,15 @@ -import { Spinner } from "@dust-tt/sparkle"; +import { + Button, + LogoHorizontalColorLogo, + Page, + Spinner, +} from "@dust-tt/sparkle"; import type { LightWorkspaceType } from "@dust-tt/types"; import { useAuth } from "@extension/components/auth/AuthProvider"; import type { StoredUser } from "@extension/lib/storage"; +import { getPendingUpdate } from "@extension/lib/storage"; import type { ReactNode } from "react"; -import { useEffect } from "react"; +import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; type ProtectedRouteProps = { @@ -27,6 +33,7 @@ export const ProtectedRoute = ({ children }: ProtectedRouteProps) => { } = useAuth(); const navigate = useNavigate(); + const [isLatestVersion, setIsLatestVersion] = useState(true); useEffect(() => { if (!isAuthenticated || !isUserSetup || !user || !workspace) { @@ -35,6 +42,26 @@ export const ProtectedRoute = ({ children }: ProtectedRouteProps) => { } }, [navigate, isLoading, isAuthenticated, isUserSetup, user, workspace]); + const checkIsLatestVersion = async () => { + const pendingUpdate = await getPendingUpdate(); + if (!pendingUpdate) { + return null; + } + if (pendingUpdate.version > chrome.runtime.getManifest().version) { + setIsLatestVersion(false); + } + }; + + useEffect(() => { + void checkIsLatestVersion(); + + chrome.storage.local.onChanged.addListener((changes) => { + if (changes.pendingUpdate) { + void checkIsLatestVersion(); + } + }); + }, []); + if (isLoading || !isAuthenticated || !isUserSetup || !user || !workspace) { return (