Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions apps/browser-extension/entrypoints/popup/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -845,41 +845,41 @@ function App() {
<div className="text-center py-2">
{authInvalidated ? (
<div className="mb-8">
<div className="p-3 mb-4 bg-red-50 border border-red-200 rounded-lg">
<h2 className="m-0 mb-2 text-sm font-semibold text-red-800 leading-tight">
<div className="p-3 mb-4 rounded-lg border border-red-900/60 bg-red-950/40">
<h2 className="m-0 mb-2 text-sm font-semibold text-red-200 leading-tight">
Session Expired
</h2>
<p className="m-0 text-xs text-red-600 leading-tight">
<p className="m-0 text-xs text-red-300/90 leading-tight">
Logged out since authentication was invalidated. Please
login again.
</p>
</div>
</div>
) : (
<div className="mb-8">
<h2 className="m-0 mb-4 text-sm font-normal leading-tight">
Login to unlock all chrome extension features
<h2 className="m-0 mb-4 text-sm font-medium leading-snug text-neutral-100">
Login to unlock all Chrome extension features
</h2>

<ul className="list-none p-0 m-0 text-left">
<li className="py-1.5 text-sm text-[#737373] relative pl-5 before:content-['•'] before:absolute before:left-0 before:text-[#737373] before:font-bold">
<li className="py-1.5 text-sm text-neutral-400 relative pl-5 before:content-['•'] before:absolute before:left-0 before:text-neutral-500 before:font-bold">
Save any page to your supermemory
</li>
<li className="py-1.5 text-sm text-[#737373] relative pl-5 before:content-['•'] before:absolute before:left-0 before:text-[#737373] before:font-bold">
<li className="py-1.5 text-sm text-neutral-400 relative pl-5 before:content-['•'] before:absolute before:left-0 before:text-neutral-500 before:font-bold">
Import all your Twitter / X Bookmarks
</li>
<li className="py-1.5 text-sm text-[#737373] relative pl-5 before:content-['•'] before:absolute before:left-0 before:text-[#737373] before:font-bold">
<li className="py-1.5 text-sm text-neutral-400 relative pl-5 before:content-['•'] before:absolute before:left-0 before:text-neutral-500 before:font-bold">
Import your ChatGPT Memories
</li>
</ul>
</div>
)}

<div className="mt-8">
<p className="m-0 mb-4 text-sm text-[#737373]">
<p className="m-0 mb-4 text-sm text-neutral-400">
Having trouble logging in?{" "}
<button
className="bg-transparent border-none text-blue-500 cursor-pointer underline text-sm p-0 hover:text-blue-700"
className="bg-transparent border-none text-sky-400 cursor-pointer underline text-sm p-0 hover:text-sky-300"
onClick={() => {
window.open("mailto:support@supermemory.ai", "_blank")
}}
Expand All @@ -890,7 +890,7 @@ function App() {
</p>

<button
className="w-full py-3 px-6 bg-gray-700 text-white border-none rounded-3xl text-base font-medium cursor-pointer transition-colors duration-200 hover:bg-gray-800 disabled:bg-gray-400 disabled:cursor-not-allowed"
className="w-full py-3 px-6 bg-[#2d3f5c] text-white border-none rounded-3xl text-base font-medium cursor-pointer transition-colors duration-200 hover:bg-[#3d5270] disabled:bg-neutral-600 disabled:cursor-not-allowed"
onClick={() => {
chrome.tabs.create({
url: import.meta.env.PROD
Expand Down
17 changes: 6 additions & 11 deletions apps/browser-extension/entrypoints/popup/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
line-height: 1.5;
font-weight: 400;

color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
border: 1px solid #242424;
color-scheme: dark;
color: rgba(255, 255, 255, 0.92);
background-color: #0a0e14;
border: 1px solid #0a0e14;

font-synthesis: none;
text-rendering: optimizeLegibility;
Expand All @@ -16,11 +16,6 @@
-webkit-text-size-adjust: 100%;
}

@media (prefers-color-scheme: light) {
:root {
color: #213547;
}
a:hover {
color: #747bff;
}
a:hover {
color: #93c5fd;
}
20 changes: 19 additions & 1 deletion apps/browser-extension/wxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
import path from "node:path"
import { createRequire } from "node:module"
import tailwindcss from "@tailwindcss/vite"
import { defineConfig, type WxtViteConfig } from "wxt"

const require = createRequire(import.meta.url)

function reactPackageRoot(pkg: "react" | "react-dom"): string {
return path.dirname(require.resolve(`${pkg}/package.json`))
}

// See https://wxt.dev/api/config.html
export default defineConfig({
modules: ["@wxt-dev/module-react"],
vite: () =>
({
plugins: [tailwindcss()],
resolve: {
dedupe: ["react", "react-dom"],
alias: {
react: reactPackageRoot("react"),
"react-dom": reactPackageRoot("react-dom"),
},
},
optimizeDeps: {
include: ["react", "react-dom", "@tanstack/react-query"],
},
}) as WxtViteConfig,
manifest: {
name: "supermemory",
homepage_url: "https://supermemory.ai",
version: "6.1.1",
version: "6.1.2",
permissions: ["storage", "activeTab", "webRequest", "tabs"],
host_permissions: [
"*://x.com/*",
Expand Down
66 changes: 58 additions & 8 deletions apps/web/components/memories-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { useQueryState } from "nuqs"
import type { z } from "zod"
import { Masonry, useInfiniteLoader } from "masonic"
import { dmSansClassName } from "@/lib/fonts"
import { SuperLoader } from "@/components/superloader"
import { ErrorBoundary } from "@/components/error-boundary"
import { cn } from "@lib/utils"
import { useProject } from "@/stores"
Expand Down Expand Up @@ -42,7 +41,7 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from "@ui/components/alert-dialog"
import { CheckIcon, Trash2Icon, XIcon } from "lucide-react"
import { CheckIcon, Loader, Trash2Icon, XIcon } from "lucide-react"

// Document category type
type DocumentCategory =
Expand Down Expand Up @@ -77,6 +76,55 @@ type OgData = {
const PAGE_SIZE = 100
const MAX_TOTAL = 1000

const MEMORIES_LOADING_LABELS = [
"Getting your supermemories…",
"Fetching your documents…",
"Warming up Nova…",
"Almost there…",
] as const

function useRotatingLoadingLabel(
labels: readonly string[],
intervalMs = 2400,
): string {
const [index, setIndex] = useState(0)

useEffect(() => {
const id = window.setInterval(() => {
setIndex((i) => (i + 1) % labels.length)
}, intervalMs)
return () => window.clearInterval(id)
}, [labels.length, intervalMs])

const label = labels.at(index) ?? labels.at(0)
return label ?? "Loading…"
}

function MemoriesGridLoading() {
const label = useRotatingLoadingLabel(MEMORIES_LOADING_LABELS)
return (
<output
aria-label={label}
className="h-full min-h-[min(50dvh,360px)] w-full flex items-center justify-center gap-4 px-8 py-20"
aria-live="polite"
>
<Loader
className={cn("shrink-0 animate-spin text-sky-400")}
aria-hidden
strokeWidth={2}
/>
<p
className={cn(
dmSansClassName(),
"text-center text-base text-[#A3A3A3] max-w-md leading-relaxed",
)}
>
{label}
</p>
</output>
)
}

// Discriminated union for masonry items
type MasonryItem = { type: "document"; id: string; data: DocumentWithMemories }

Expand Down Expand Up @@ -135,7 +183,7 @@ export function MemoriesGrid({
emptyStateProps,
}: MemoriesGridProps) {
const [showBulkDeleteConfirm, setShowBulkDeleteConfirm] = useState(false)
const { user } = useAuth()
const { user, isSessionPending } = useAuth()
const { effectiveContainerTags } = useProject()
const isMobile = useIsMobile()
const [selectedCategories, setSelectedCategories] = useQueryState(
Expand Down Expand Up @@ -343,6 +391,10 @@ export function MemoriesGrid({
[handleCardClick, isSelectionMode, selectedDocumentIds, onToggleSelection],
)

if (isSessionPending) {
return <MemoriesGridLoading />
}

if (!user) {
return (
<div className="flex items-center justify-center h-full">
Expand Down Expand Up @@ -504,9 +556,7 @@ export function MemoriesGrid({
</div>
</div>
) : isPending ? (
<div className="h-full flex items-center justify-center p-4">
<SuperLoader />
</div>
<MemoriesGridLoading />
) : showNovaEmptyState ? (
<NovaEmptyState
onAddMemory={emptyStateProps.onAddMemory}
Expand Down Expand Up @@ -558,8 +608,8 @@ export function MemoriesGrid({
/>

{isLoadingMore && (
<div className="py-8 flex items-center justify-center">
<SuperLoader />
<div className="py-10 flex items-center justify-center">
<Loader className="size-10 animate-spin text-sky-400" />
</div>
)}
</div>
Expand Down
10 changes: 8 additions & 2 deletions packages/lib/auth-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ interface AuthContextType {
org: Organization | null
organizations: OrganizationListItem[] | null
isRestoring: boolean
isSessionPending: boolean
setActiveOrg: (orgSlug: string) => Promise<void>
updateOrgMetadata: (partial: Record<string, unknown>) => void
refetchOrganizations: () => Promise<unknown>
Expand All @@ -32,7 +33,7 @@ interface AuthContextType {
const AuthContext = createContext<AuthContextType | undefined>(undefined)

export function AuthProvider({ children }: { children: ReactNode }) {
const { data: session } = useSession()
const { data: session, isPending: isSessionPending } = useSession()
const [org, setOrg] = useState<Organization | null>(null)
const [isRestoring, setIsRestoring] = useState(true)
const {
Expand Down Expand Up @@ -73,6 +74,10 @@ export function AuthProvider({ children }: { children: ReactNode }) {
}, [])

useEffect(() => {
if (isSessionPending) {
return
}

if (!session?.session) {
setIsRestoring(false)
setOrg(null)
Expand Down Expand Up @@ -145,7 +150,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
return () => {
cancelled = true
}
}, [session, orgsData, orgsPending, setActiveOrg])
}, [session, isSessionPending, orgsData, orgsPending, setActiveOrg])

useEffect(() => {
if (typeof window === "undefined") return
Expand Down Expand Up @@ -181,6 +186,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
org,
organizations,
isRestoring,
isSessionPending,
session: session?.session ?? null,
user: session?.user ?? null,
setActiveOrg,
Expand Down
Loading