import { useQueryClient } from "@tanstack/react-query" import { useEffect, useState } from "react" import "./App.css" import { validateAuthToken } from "../../utils/api" import { MESSAGE_TYPES } from "../../utils/constants" import { useDefaultProject, useProjects, useSetDefaultProject, useUserData, } from "../../utils/query-hooks" import { autoSearchEnabled as autoSearchEnabledStorage, autoCapturePromptsEnabled as autoCapturePromptsEnabledStorage, bearerToken, defaultProject as defaultProjectStorage, userData as userDataStorage, } from "../../utils/storage" import type { Project } from "../../utils/types" const Tooltip = ({ children, content, }: { children: React.ReactNode content: string }) => { const [isVisible, setIsVisible] = useState(false) return (
{isVisible && (
{content}
)}
) } function App() { const [userSignedIn, setUserSignedIn] = useState(false) const [loading, setLoading] = useState(true) const [showProjectSelector, setShowProjectSelector] = useState(false) const [currentUrl, setCurrentUrl] = useState("") const [currentTitle, setCurrentTitle] = useState("") const [saving, setSaving] = useState(false) const [activeTab, setActiveTab] = useState<"save" | "imports" | "settings">( "save", ) const [autoSearchEnabled, setAutoSearchEnabled] = useState(false) const [autoCapturePromptsEnabled, setAutoCapturePromptsEnabled] = useState(false) const [authInvalidated, setAuthInvalidated] = useState(false) const queryClient = useQueryClient() const { data: projects = [], isLoading: loadingProjects } = useProjects({ enabled: userSignedIn, }) const { data: defaultProject } = useDefaultProject({ enabled: userSignedIn, }) const { data: userData, isLoading: loadingUserData } = useUserData({ enabled: userSignedIn, }) const setDefaultProjectMutation = useSetDefaultProject() // biome-ignore lint/correctness/useExhaustiveDependencies: suppress dependency analysis useEffect(() => { const checkAuthStatus = async () => { try { const [token, autoSearch, autoCapturePrompts] = await Promise.all([ bearerToken.getValue(), autoSearchEnabledStorage.getValue(), autoCapturePromptsEnabledStorage.getValue(), ]) const hasToken = !!token if (hasToken) { const isTokenValid = await validateAuthToken() if (isTokenValid) { setUserSignedIn(true) setAuthInvalidated(false) } else { await Promise.all([ bearerToken.removeValue(), userDataStorage.removeValue(), defaultProjectStorage.removeValue(), ]) queryClient.clear() setUserSignedIn(false) setAuthInvalidated(true) } } else { setUserSignedIn(false) setAuthInvalidated(false) } setAutoSearchEnabled(autoSearch ?? false) setAutoCapturePromptsEnabled(autoCapturePrompts ?? false) } catch (error) { console.error("Error checking auth status:", error) setUserSignedIn(false) setAuthInvalidated(false) } finally { setLoading(false) } } const getCurrentTab = async () => { try { const tabs = await chrome.tabs.query({ active: true, currentWindow: true, }) if (tabs.length > 0 && tabs[0].url && tabs[0].title) { setCurrentUrl(tabs[0].url) setCurrentTitle(tabs[0].title) } } catch (error) { console.error("Error getting current tab:", error) } } checkAuthStatus() getCurrentTab() }, []) const handleProjectSelect = (project: Project) => { setDefaultProjectMutation.mutate(project, { onSuccess: () => { setShowProjectSelector(false) }, onError: (error) => { console.error("Error setting default project:", error) }, }) } const handleShowProjectSelector = () => { setShowProjectSelector(true) } useEffect(() => { if (!defaultProject && projects.length > 0) { const firstProject = projects[0] setDefaultProjectMutation.mutate(firstProject) } }, [defaultProject, projects, setDefaultProjectMutation]) const handleSaveCurrentPage = async () => { setSaving(true) try { const tabs = await chrome.tabs.query({ active: true, currentWindow: true, }) if (tabs.length > 0 && tabs[0].id) { const response = await chrome.tabs.sendMessage(tabs[0].id, { action: MESSAGE_TYPES.SAVE_MEMORY, actionSource: "popup", }) if (response?.success) { await chrome.tabs.sendMessage(tabs[0].id, { action: MESSAGE_TYPES.SHOW_TOAST, state: "success", }) } window.close() } } catch (error) { console.error("Failed to save current page:", error) try { const tabs = await chrome.tabs.query({ active: true, currentWindow: true, }) if (tabs.length > 0 && tabs[0].id) { await chrome.tabs.sendMessage(tabs[0].id, { action: MESSAGE_TYPES.SHOW_TOAST, state: "error", }) } } catch (toastError) { console.error("Failed to show error toast:", toastError) } window.close() } finally { setSaving(false) } } const handleAutoSearchToggle = async (enabled: boolean) => { try { await autoSearchEnabledStorage.setValue(enabled) setAutoSearchEnabled(enabled) } catch (error) { console.error("Error updating auto search setting:", error) } } const handleAutoCapturePromptsToggle = async (enabled: boolean) => { try { await autoCapturePromptsEnabledStorage.setValue(enabled) setAutoCapturePromptsEnabled(enabled) } catch (error) { console.error("Error updating auto capture prompts setting:", error) } } const handleSignOut = async () => { try { await Promise.all([ bearerToken.removeValue(), userDataStorage.removeValue(), defaultProjectStorage.removeValue(), ]) setUserSignedIn(false) queryClient.clear() } catch (error) { console.error("Error signing out:", error) } } if (loading) { return (
supermemory
Loading...
) } return (
supermemory {userSignedIn && ( )}
{userSignedIn ? (
{/* Tab Navigation */}
{/* Tab Content */} {activeTab === "save" ? (
{/* Current Page Info */}

{currentTitle || "Current Page"}

{currentUrl}

{/* Project Selection */}
{/* Save Button at Bottom */}
) : activeTab === "imports" ? (
{/* Import Actions */}
) : (
{/* Account Section */}

Account

{loadingUserData ? (
Loading account data...
) : userData?.email ? (
Email {userData.email}
) : (
No email found
)}
{/* Chat Integration Section */}

Chat Integration

Auto Search Memories
)} {showProjectSelector && (
Select the Project
{loadingProjects ? (
Loading projects...
) : (
{projects.map((project) => ( ))}
)}
)}
) : (
{authInvalidated ? (

Session Expired

Logged out since authentication was invalidated. Please login again.

) : (

Login to unlock all chrome extension features

  • Save any page to your supermemory
  • Import all your Twitter / X Bookmarks
  • Import your ChatGPT Memories
)}

Having trouble logging in?{" "}

)}
) } export default App