mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-25 00:36:31 +02:00
format: auto-fix via pnpm format:fix
This commit is contained in:
parent
a74aa4da4f
commit
0e49cc33f8
37 changed files with 128 additions and 175 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { useAtomValue, useSetAtom } from "jotai";
|
||||||
import {
|
import {
|
||||||
AlertCircle,
|
AlertCircle,
|
||||||
CheckCircle2,
|
CheckCircle2,
|
||||||
|
|
@ -16,12 +17,11 @@ import {
|
||||||
Trash2,
|
Trash2,
|
||||||
User,
|
User,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useAtomValue, useSetAtom } from "jotai";
|
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { membersAtom } from "@/atoms/members/members-query.atoms";
|
|
||||||
import { openEditorPanelAtom } from "@/atoms/editor/editor-panel.atom";
|
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import { openEditorPanelAtom } from "@/atoms/editor/editor-panel.atom";
|
||||||
|
import { membersAtom } from "@/atoms/members/members-query.atoms";
|
||||||
import { useDocumentUploadDialog } from "@/components/assistant-ui/document-upload-popup";
|
import { useDocumentUploadDialog } from "@/components/assistant-ui/document-upload-popup";
|
||||||
import { JsonMetadataViewer } from "@/components/json-metadata-viewer";
|
import { JsonMetadataViewer } from "@/components/json-metadata-viewer";
|
||||||
import { MarkdownViewer } from "@/components/markdown-viewer";
|
import { MarkdownViewer } from "@/components/markdown-viewer";
|
||||||
|
|
@ -35,14 +35,9 @@ import {
|
||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/components/ui/dropdown-menu";
|
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||||
import {
|
import {
|
||||||
Drawer,
|
Drawer,
|
||||||
|
|
@ -51,7 +46,12 @@ import {
|
||||||
DrawerHeader,
|
DrawerHeader,
|
||||||
DrawerTitle,
|
DrawerTitle,
|
||||||
} from "@/components/ui/drawer";
|
} from "@/components/ui/drawer";
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from "@/components/ui/dropdown-menu";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import { Spinner } from "@/components/ui/spinner";
|
import { Spinner } from "@/components/ui/spinner";
|
||||||
import {
|
import {
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ import type { ThinkingStep } from "@/components/tool-ui/deepagent-thinking";
|
||||||
import { DisplayImageToolUI } from "@/components/tool-ui/display-image";
|
import { DisplayImageToolUI } from "@/components/tool-ui/display-image";
|
||||||
import { GeneratePodcastToolUI } from "@/components/tool-ui/generate-podcast";
|
import { GeneratePodcastToolUI } from "@/components/tool-ui/generate-podcast";
|
||||||
import { GenerateReportToolUI } from "@/components/tool-ui/generate-report";
|
import { GenerateReportToolUI } from "@/components/tool-ui/generate-report";
|
||||||
import { GenerateVideoPresentationToolUI } from "@/components/tool-ui/video-presentation";
|
|
||||||
import {
|
import {
|
||||||
CreateGoogleDriveFileToolUI,
|
CreateGoogleDriveFileToolUI,
|
||||||
DeleteGoogleDriveFileToolUI,
|
DeleteGoogleDriveFileToolUI,
|
||||||
|
|
@ -59,6 +58,7 @@ import {
|
||||||
import { SandboxExecuteToolUI } from "@/components/tool-ui/sandbox-execute";
|
import { SandboxExecuteToolUI } from "@/components/tool-ui/sandbox-execute";
|
||||||
import { ScrapeWebpageToolUI } from "@/components/tool-ui/scrape-webpage";
|
import { ScrapeWebpageToolUI } from "@/components/tool-ui/scrape-webpage";
|
||||||
import { RecallMemoryToolUI, SaveMemoryToolUI } from "@/components/tool-ui/user-memory";
|
import { RecallMemoryToolUI, SaveMemoryToolUI } from "@/components/tool-ui/user-memory";
|
||||||
|
import { GenerateVideoPresentationToolUI } from "@/components/tool-ui/video-presentation";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import { useChatSessionStateSync } from "@/hooks/use-chat-session-state";
|
import { useChatSessionStateSync } from "@/hooks/use-chat-session-state";
|
||||||
import { useMessagesSync } from "@/hooks/use-messages-sync";
|
import { useMessagesSync } from "@/hooks/use-messages-sync";
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import {
|
||||||
UserPlus,
|
UserPlus,
|
||||||
Users,
|
Users,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import {
|
import {
|
||||||
|
|
@ -44,6 +43,7 @@ import {
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
AlertDialogTrigger,
|
AlertDialogTrigger,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Calendar as CalendarComponent } from "@/components/ui/calendar";
|
import { Calendar as CalendarComponent } from "@/components/ui/calendar";
|
||||||
import {
|
import {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import posthog from "posthog-js";
|
|
||||||
import NextError from "next/error";
|
import NextError from "next/error";
|
||||||
|
import posthog from "posthog-js";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
export default function GlobalError({
|
export default function GlobalError({
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ import { RootProvider } from "fumadocs-ui/provider/next";
|
||||||
import { Roboto } from "next/font/google";
|
import { Roboto } from "next/font/google";
|
||||||
import { AnnouncementToastProvider } from "@/components/announcements/AnnouncementToastProvider";
|
import { AnnouncementToastProvider } from "@/components/announcements/AnnouncementToastProvider";
|
||||||
import { GlobalLoadingProvider } from "@/components/providers/GlobalLoadingProvider";
|
import { GlobalLoadingProvider } from "@/components/providers/GlobalLoadingProvider";
|
||||||
import { ZeroProvider } from "@/components/providers/ZeroProvider";
|
|
||||||
import { I18nProvider } from "@/components/providers/I18nProvider";
|
import { I18nProvider } from "@/components/providers/I18nProvider";
|
||||||
import { PostHogProvider } from "@/components/providers/PostHogProvider";
|
import { PostHogProvider } from "@/components/providers/PostHogProvider";
|
||||||
|
import { ZeroProvider } from "@/components/providers/ZeroProvider";
|
||||||
import { ThemeProvider } from "@/components/theme/theme-provider";
|
import { ThemeProvider } from "@/components/theme/theme-provider";
|
||||||
import { Toaster } from "@/components/ui/sonner";
|
import { Toaster } from "@/components/ui/sonner";
|
||||||
import { LocaleProvider } from "@/contexts/LocaleContext";
|
import { LocaleProvider } from "@/contexts/LocaleContext";
|
||||||
|
|
@ -140,11 +140,11 @@ export default function RootLayout({
|
||||||
defaultTheme="system"
|
defaultTheme="system"
|
||||||
>
|
>
|
||||||
<RootProvider>
|
<RootProvider>
|
||||||
<ReactQueryClientProvider>
|
<ReactQueryClientProvider>
|
||||||
<ZeroProvider>
|
<ZeroProvider>
|
||||||
<GlobalLoadingProvider>{children}</GlobalLoadingProvider>
|
<GlobalLoadingProvider>{children}</GlobalLoadingProvider>
|
||||||
</ZeroProvider>
|
</ZeroProvider>
|
||||||
</ReactQueryClientProvider>
|
</ReactQueryClientProvider>
|
||||||
<Toaster />
|
<Toaster />
|
||||||
<AnnouncementToastProvider />
|
<AnnouncementToastProvider />
|
||||||
</RootProvider>
|
</RootProvider>
|
||||||
|
|
|
||||||
|
|
@ -164,8 +164,7 @@ export const ConnectorIndicator = forwardRef<ConnectorIndicatorHandle, Connector
|
||||||
refreshConnectors: refreshConnectorsSync,
|
refreshConnectors: refreshConnectorsSync,
|
||||||
} = useConnectorsSync(searchSpaceId);
|
} = useConnectorsSync(searchSpaceId);
|
||||||
|
|
||||||
const useSyncData =
|
const useSyncData = connectorsFromSync.length > 0 || (connectorsLoading && !connectorsError);
|
||||||
connectorsFromSync.length > 0 || (connectorsLoading && !connectorsError);
|
|
||||||
const connectors = useSyncData ? connectorsFromSync : allConnectors || [];
|
const connectors = useSyncData ? connectorsFromSync : allConnectors || [];
|
||||||
|
|
||||||
const refreshConnectors = async () => {
|
const refreshConnectors = async () => {
|
||||||
|
|
|
||||||
|
|
@ -938,7 +938,13 @@ const TOOL_GROUPS: { label: string; tools: string[] }[] = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Generate",
|
label: "Generate",
|
||||||
tools: ["generate_podcast", "generate_video_presentation", "generate_report", "generate_image", "display_image"],
|
tools: [
|
||||||
|
"generate_podcast",
|
||||||
|
"generate_video_presentation",
|
||||||
|
"generate_report",
|
||||||
|
"generate_image",
|
||||||
|
"display_image",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Memory",
|
label: "Memory",
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
||||||
import { AlertTriangle, Inbox, Megaphone, SquareLibrary } from "lucide-react";
|
import { AlertTriangle, Inbox, Megaphone, SquareLibrary } from "lucide-react";
|
||||||
import { Spinner } from "@/components/ui/spinner";
|
|
||||||
import { useParams, usePathname, useRouter } from "next/navigation";
|
import { useParams, usePathname, useRouter } from "next/navigation";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { useTheme } from "next-themes";
|
import { useTheme } from "next-themes";
|
||||||
|
|
@ -22,6 +21,10 @@ import {
|
||||||
userSettingsDialogAtom,
|
userSettingsDialogAtom,
|
||||||
} from "@/atoms/settings/settings-dialog.atoms";
|
} from "@/atoms/settings/settings-dialog.atoms";
|
||||||
import { currentUserAtom } from "@/atoms/user/user-query.atoms";
|
import { currentUserAtom } from "@/atoms/user/user-query.atoms";
|
||||||
|
import { MorePagesDialog } from "@/components/settings/more-pages-dialog";
|
||||||
|
import { SearchSpaceSettingsDialog } from "@/components/settings/search-space-settings-dialog";
|
||||||
|
import { TeamDialog } from "@/components/settings/team-dialog";
|
||||||
|
import { UserSettingsDialog } from "@/components/settings/user-settings-dialog";
|
||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
|
|
@ -42,7 +45,7 @@ import {
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
} from "@/components/ui/dialog";
|
} from "@/components/ui/dialog";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Spinner } from "@/components/ui/spinner";
|
||||||
import { useAnnouncements } from "@/hooks/use-announcements";
|
import { useAnnouncements } from "@/hooks/use-announcements";
|
||||||
import { useDocumentsProcessing } from "@/hooks/use-documents-processing";
|
import { useDocumentsProcessing } from "@/hooks/use-documents-processing";
|
||||||
import { useInbox } from "@/hooks/use-inbox";
|
import { useInbox } from "@/hooks/use-inbox";
|
||||||
|
|
@ -53,10 +56,6 @@ import { logout } from "@/lib/auth-utils";
|
||||||
import { deleteThread, fetchThreads, updateThread } from "@/lib/chat/thread-persistence";
|
import { deleteThread, fetchThreads, updateThread } from "@/lib/chat/thread-persistence";
|
||||||
import { resetUser, trackLogout } from "@/lib/posthog/events";
|
import { resetUser, trackLogout } from "@/lib/posthog/events";
|
||||||
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
||||||
import { MorePagesDialog } from "@/components/settings/more-pages-dialog";
|
|
||||||
import { SearchSpaceSettingsDialog } from "@/components/settings/search-space-settings-dialog";
|
|
||||||
import { TeamDialog } from "@/components/settings/team-dialog";
|
|
||||||
import { UserSettingsDialog } from "@/components/settings/user-settings-dialog";
|
|
||||||
import type { ChatItem, NavItem, SearchSpace } from "../types/layout.types";
|
import type { ChatItem, NavItem, SearchSpace } from "../types/layout.types";
|
||||||
import { CreateSearchSpaceDialog } from "../ui/dialogs";
|
import { CreateSearchSpaceDialog } from "../ui/dialogs";
|
||||||
import { LayoutShell } from "../ui/shell";
|
import { LayoutShell } from "../ui/shell";
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import { useParams, useRouter } from "next/navigation";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/animated-tabs";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
|
|
@ -36,7 +37,6 @@ import {
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import { Spinner } from "@/components/ui/spinner";
|
import { Spinner } from "@/components/ui/spinner";
|
||||||
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/animated-tabs";
|
|
||||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
import { useDebouncedValue } from "@/hooks/use-debounced-value";
|
import { useDebouncedValue } from "@/hooks/use-debounced-value";
|
||||||
import { useLongPress } from "@/hooks/use-long-press";
|
import { useLongPress } from "@/hooks/use-long-press";
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import { useParams, useRouter } from "next/navigation";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/animated-tabs";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
|
|
@ -36,7 +37,6 @@ import {
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import { Spinner } from "@/components/ui/spinner";
|
import { Spinner } from "@/components/ui/spinner";
|
||||||
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/animated-tabs";
|
|
||||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
import { useDebouncedValue } from "@/hooks/use-debounced-value";
|
import { useDebouncedValue } from "@/hooks/use-debounced-value";
|
||||||
import { useLongPress } from "@/hooks/use-long-press";
|
import { useLongPress } from "@/hooks/use-long-press";
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ import { ReportPanel } from "@/components/report-panel/report-panel";
|
||||||
import { DisplayImageToolUI } from "@/components/tool-ui/display-image";
|
import { DisplayImageToolUI } from "@/components/tool-ui/display-image";
|
||||||
import { GeneratePodcastToolUI } from "@/components/tool-ui/generate-podcast";
|
import { GeneratePodcastToolUI } from "@/components/tool-ui/generate-podcast";
|
||||||
import { GenerateReportToolUI } from "@/components/tool-ui/generate-report";
|
import { GenerateReportToolUI } from "@/components/tool-ui/generate-report";
|
||||||
import { GenerateVideoPresentationToolUI } from "@/components/tool-ui/video-presentation";
|
|
||||||
import { LinkPreviewToolUI } from "@/components/tool-ui/link-preview";
|
import { LinkPreviewToolUI } from "@/components/tool-ui/link-preview";
|
||||||
import { ScrapeWebpageToolUI } from "@/components/tool-ui/scrape-webpage";
|
import { ScrapeWebpageToolUI } from "@/components/tool-ui/scrape-webpage";
|
||||||
|
import { GenerateVideoPresentationToolUI } from "@/components/tool-ui/video-presentation";
|
||||||
import { Spinner } from "@/components/ui/spinner";
|
import { Spinner } from "@/components/ui/spinner";
|
||||||
import { usePublicChat } from "@/hooks/use-public-chat";
|
import { usePublicChat } from "@/hooks/use-public-chat";
|
||||||
import { usePublicChatRuntime } from "@/hooks/use-public-chat-runtime";
|
import { usePublicChatRuntime } from "@/hooks/use-public-chat-runtime";
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import {
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useCallback, useMemo, useState } from "react";
|
import { useCallback, useMemo, useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
||||||
import {
|
import {
|
||||||
createImageGenConfigMutationAtom,
|
createImageGenConfigMutationAtom,
|
||||||
deleteImageGenConfigMutationAtom,
|
deleteImageGenConfigMutationAtom,
|
||||||
|
|
@ -38,6 +37,7 @@ import {
|
||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Card, CardContent } from "@/components/ui/card";
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
import {
|
import {
|
||||||
|
|
@ -69,12 +69,12 @@ import { Separator } from "@/components/ui/separator";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import { Spinner } from "@/components/ui/spinner";
|
import { Spinner } from "@/components/ui/spinner";
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
import { useMediaQuery } from "@/hooks/use-media-query";
|
|
||||||
import {
|
import {
|
||||||
getImageGenModelsByProvider,
|
getImageGenModelsByProvider,
|
||||||
IMAGE_GEN_PROVIDERS,
|
IMAGE_GEN_PROVIDERS,
|
||||||
} from "@/contracts/enums/image-gen-providers";
|
} from "@/contracts/enums/image-gen-providers";
|
||||||
import type { ImageGenerationConfig } from "@/contracts/types/new-llm-config.types";
|
import type { ImageGenerationConfig } from "@/contracts/types/new-llm-config.types";
|
||||||
|
import { useMediaQuery } from "@/hooks/use-media-query";
|
||||||
import { getProviderIcon } from "@/lib/provider-icons";
|
import { getProviderIcon } from "@/lib/provider-icons";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import {
|
||||||
Wand2,
|
Wand2,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useCallback, useMemo, useState } from "react";
|
import { useCallback, useMemo, useState } from "react";
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
|
||||||
import { membersAtom, myAccessAtom } from "@/atoms/members/members-query.atoms";
|
import { membersAtom, myAccessAtom } from "@/atoms/members/members-query.atoms";
|
||||||
import {
|
import {
|
||||||
createNewLLMConfigMutationAtom,
|
createNewLLMConfigMutationAtom,
|
||||||
|
|
@ -36,6 +35,7 @@ import {
|
||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Card, CardContent } from "@/components/ui/card";
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
import { useAtom } from "jotai";
|
import { useAtom } from "jotai";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
import { TeamContent } from "@/app/dashboard/[search_space_id]/team/team-content";
|
||||||
import { teamDialogAtom } from "@/atoms/settings/settings-dialog.atoms";
|
import { teamDialogAtom } from "@/atoms/settings/settings-dialog.atoms";
|
||||||
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
|
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
|
||||||
import { TeamContent } from "@/app/dashboard/[search_space_id]/team/team-content";
|
|
||||||
|
|
||||||
interface TeamDialogProps {
|
interface TeamDialogProps {
|
||||||
searchSpaceId: number;
|
searchSpaceId: number;
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
import { useAtom } from "jotai";
|
import { useAtom } from "jotai";
|
||||||
import { KeyRound, User } from "lucide-react";
|
import { KeyRound, User } from "lucide-react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { userSettingsDialogAtom } from "@/atoms/settings/settings-dialog.atoms";
|
|
||||||
import { ApiKeyContent } from "@/app/dashboard/[search_space_id]/user-settings/components/ApiKeyContent";
|
import { ApiKeyContent } from "@/app/dashboard/[search_space_id]/user-settings/components/ApiKeyContent";
|
||||||
import { ProfileContent } from "@/app/dashboard/[search_space_id]/user-settings/components/ProfileContent";
|
import { ProfileContent } from "@/app/dashboard/[search_space_id]/user-settings/components/ProfileContent";
|
||||||
|
import { userSettingsDialogAtom } from "@/atoms/settings/settings-dialog.atoms";
|
||||||
import { SettingsDialog } from "@/components/settings/settings-dialog";
|
import { SettingsDialog } from "@/components/settings/settings-dialog";
|
||||||
|
|
||||||
export function UserSettingsDialog() {
|
export function UserSettingsDialog() {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ export {
|
||||||
} from "./display-image";
|
} from "./display-image";
|
||||||
export { GeneratePodcastToolUI } from "./generate-podcast";
|
export { GeneratePodcastToolUI } from "./generate-podcast";
|
||||||
export { GenerateReportToolUI } from "./generate-report";
|
export { GenerateReportToolUI } from "./generate-report";
|
||||||
export { GenerateVideoPresentationToolUI } from "./video-presentation";
|
|
||||||
export { CreateGoogleDriveFileToolUI, DeleteGoogleDriveFileToolUI } from "./google-drive";
|
export { CreateGoogleDriveFileToolUI, DeleteGoogleDriveFileToolUI } from "./google-drive";
|
||||||
export {
|
export {
|
||||||
Image,
|
Image,
|
||||||
|
|
@ -106,4 +105,5 @@ export {
|
||||||
SaveMemoryResultSchema,
|
SaveMemoryResultSchema,
|
||||||
SaveMemoryToolUI,
|
SaveMemoryToolUI,
|
||||||
} from "./user-memory";
|
} from "./user-memory";
|
||||||
|
export { GenerateVideoPresentationToolUI } from "./video-presentation";
|
||||||
export { type WriteTodosData, WriteTodosSchema, WriteTodosToolUI } from "./write-todos";
|
export { type WriteTodosData, WriteTodosSchema, WriteTodosToolUI } from "./write-todos";
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useMemo } from "react";
|
|
||||||
import { Player } from "@remotion/player";
|
|
||||||
import { Sequence, AbsoluteFill, useCurrentFrame, useVideoConfig, interpolate } from "remotion";
|
|
||||||
import { Audio } from "@remotion/media";
|
import { Audio } from "@remotion/media";
|
||||||
|
import { Player } from "@remotion/player";
|
||||||
|
import type React from "react";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
import { AbsoluteFill, interpolate, Sequence, useCurrentFrame, useVideoConfig } from "remotion";
|
||||||
import { FPS } from "@/lib/remotion/constants";
|
import { FPS } from "@/lib/remotion/constants";
|
||||||
|
|
||||||
export interface CompiledSlide {
|
export interface CompiledSlide {
|
||||||
|
|
@ -64,9 +65,7 @@ function Watermark() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildSlideWithWatermark(
|
export function buildSlideWithWatermark(SlideComponent: React.ComponentType): React.FC {
|
||||||
SlideComponent: React.ComponentType,
|
|
||||||
): React.FC {
|
|
||||||
const Wrapped: React.FC = () => (
|
const Wrapped: React.FC = () => (
|
||||||
<AbsoluteFill>
|
<AbsoluteFill>
|
||||||
<SlideComponent />
|
<SlideComponent />
|
||||||
|
|
@ -115,7 +114,7 @@ export function CombinedPlayer({ slides }: CombinedPlayerProps) {
|
||||||
|
|
||||||
const totalFrames = useMemo(
|
const totalFrames = useMemo(
|
||||||
() => slides.reduce((sum, s) => sum + s.durationInFrames, 0),
|
() => slides.reduce((sum, s) => sum + s.durationInFrames, 0),
|
||||||
[slides],
|
[slides]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,9 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
||||||
import { makeAssistantToolUI } from "@assistant-ui/react";
|
import { makeAssistantToolUI } from "@assistant-ui/react";
|
||||||
import {
|
import { AlertCircleIcon, Download, Film, Loader2, Presentation, X } from "lucide-react";
|
||||||
AlertCircleIcon,
|
|
||||||
Download,
|
|
||||||
Film,
|
|
||||||
Loader2,
|
|
||||||
Presentation,
|
|
||||||
X,
|
|
||||||
} from "lucide-react";
|
|
||||||
import { useParams, usePathname } from "next/navigation";
|
import { useParams, usePathname } from "next/navigation";
|
||||||
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { Spinner } from "@/components/ui/spinner";
|
import { Spinner } from "@/components/ui/spinner";
|
||||||
import { baseApiService } from "@/lib/apis/base-api.service";
|
import { baseApiService } from "@/lib/apis/base-api.service";
|
||||||
|
|
@ -18,9 +11,9 @@ import { authenticatedFetch } from "@/lib/auth-utils";
|
||||||
import { compileCheck, compileToComponent } from "@/lib/remotion/compile-check";
|
import { compileCheck, compileToComponent } from "@/lib/remotion/compile-check";
|
||||||
import { FPS } from "@/lib/remotion/constants";
|
import { FPS } from "@/lib/remotion/constants";
|
||||||
import {
|
import {
|
||||||
CombinedPlayer,
|
|
||||||
buildCompositionComponent,
|
buildCompositionComponent,
|
||||||
buildSlideWithWatermark,
|
buildSlideWithWatermark,
|
||||||
|
CombinedPlayer,
|
||||||
type CompiledSlide,
|
type CompiledSlide,
|
||||||
} from "./combined-player";
|
} from "./combined-player";
|
||||||
|
|
||||||
|
|
@ -54,7 +47,7 @@ const VideoPresentationStatusResponseSchema = z.object({
|
||||||
audio_url: z.string().nullish(),
|
audio_url: z.string().nullish(),
|
||||||
duration_seconds: z.number().nullish(),
|
duration_seconds: z.number().nullish(),
|
||||||
duration_in_frames: z.number().nullish(),
|
duration_in_frames: z.number().nullish(),
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
.nullish(),
|
.nullish(),
|
||||||
scene_codes: z
|
scene_codes: z
|
||||||
|
|
@ -63,7 +56,7 @@ const VideoPresentationStatusResponseSchema = z.object({
|
||||||
slide_number: z.number(),
|
slide_number: z.number(),
|
||||||
code: z.string(),
|
code: z.string(),
|
||||||
title: z.string().nullish(),
|
title: z.string().nullish(),
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
.nullish(),
|
.nullish(),
|
||||||
slide_count: z.number().nullish(),
|
slide_count: z.number().nullish(),
|
||||||
|
|
@ -206,9 +199,7 @@ function VideoPresentationPlayer({
|
||||||
const durationInFrames = slide.duration_in_frames ?? 300;
|
const durationInFrames = slide.duration_in_frames ?? 300;
|
||||||
const check = compileCheck(scene.code);
|
const check = compileCheck(scene.code);
|
||||||
if (!check.success) {
|
if (!check.success) {
|
||||||
console.warn(
|
console.warn(`Slide ${slide.slide_number} failed to compile: ${check.error}`);
|
||||||
`Slide ${slide.slide_number} failed to compile: ${check.error}`,
|
|
||||||
);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -219,9 +210,7 @@ function VideoPresentationPlayer({
|
||||||
title: scene.title ?? slide.title,
|
title: scene.title ?? slide.title,
|
||||||
code: scene.code,
|
code: scene.code,
|
||||||
durationInFrames,
|
durationInFrames,
|
||||||
audioUrl: slide.audio_url
|
audioUrl: slide.audio_url ? `${backendUrl}${slide.audio_url}` : undefined,
|
||||||
? `${backendUrl}${slide.audio_url}`
|
|
||||||
: undefined,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,17 +227,13 @@ function VideoPresentationPlayer({
|
||||||
try {
|
try {
|
||||||
let blob: Blob;
|
let blob: Blob;
|
||||||
if (shareToken) {
|
if (shareToken) {
|
||||||
blob = await baseApiService.getBlob(
|
blob = await baseApiService.getBlob(new URL(slide.audioUrl).pathname);
|
||||||
new URL(slide.audioUrl).pathname,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
const resp = await authenticatedFetch(slide.audioUrl, {
|
const resp = await authenticatedFetch(slide.audioUrl, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
if (!resp.ok) {
|
if (!resp.ok) {
|
||||||
console.warn(
|
console.warn(`Audio fetch ${resp.status} for slide "${slide.title}"`);
|
||||||
`Audio fetch ${resp.status} for slide "${slide.title}"`,
|
|
||||||
);
|
|
||||||
return { ...slide, audioUrl: undefined };
|
return { ...slide, audioUrl: undefined };
|
||||||
}
|
}
|
||||||
blob = await resp.blob();
|
blob = await resp.blob();
|
||||||
|
|
@ -260,7 +245,7 @@ function VideoPresentationPlayer({
|
||||||
console.warn(`Failed to fetch audio for "${slide.title}":`, err);
|
console.warn(`Failed to fetch audio for "${slide.title}":`, err);
|
||||||
return { ...slide, audioUrl: undefined };
|
return { ...slide, audioUrl: undefined };
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
setCompiledSlides(withBlobs);
|
setCompiledSlides(withBlobs);
|
||||||
|
|
@ -284,7 +269,7 @@ function VideoPresentationPlayer({
|
||||||
|
|
||||||
const totalDuration = useMemo(
|
const totalDuration = useMemo(
|
||||||
() => compiledSlides.reduce((sum, s) => sum + s.durationInFrames / FPS, 0),
|
() => compiledSlides.reduce((sum, s) => sum + s.durationInFrames / FPS, 0),
|
||||||
[compiledSlides],
|
[compiledSlides]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleDownload = async () => {
|
const handleDownload = async () => {
|
||||||
|
|
@ -299,9 +284,7 @@ function VideoPresentationPlayer({
|
||||||
abortControllerRef.current = controller;
|
abortControllerRef.current = controller;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { canRenderMediaOnWeb, renderMediaOnWeb } = await import(
|
const { canRenderMediaOnWeb, renderMediaOnWeb } = await import("@remotion/web-renderer");
|
||||||
"@remotion/web-renderer"
|
|
||||||
);
|
|
||||||
|
|
||||||
const formats = [
|
const formats = [
|
||||||
{ container: "mp4" as const, videoCodec: "h264" as const, ext: "mp4" },
|
{ container: "mp4" as const, videoCodec: "h264" as const, ext: "mp4" },
|
||||||
|
|
@ -326,7 +309,7 @@ function VideoPresentationPlayer({
|
||||||
|
|
||||||
if (!chosen) {
|
if (!chosen) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Your browser does not support video rendering (WebCodecs). Please use Chrome, Edge, or Firefox 130+.",
|
"Your browser does not support video rendering (WebCodecs). Please use Chrome, Edge, or Firefox 130+."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -422,7 +405,7 @@ function VideoPresentationPlayer({
|
||||||
durationInFrames: slide.durationInFrames,
|
durationInFrames: slide.durationInFrames,
|
||||||
fps: FPS,
|
fps: FPS,
|
||||||
style: { width: 1920, height: 1080 },
|
style: { width: 1920, height: 1080 },
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -466,8 +449,7 @@ function VideoPresentationPlayer({
|
||||||
<div className="min-w-0">
|
<div className="min-w-0">
|
||||||
<h3 className="text-sm font-semibold text-foreground truncate">{title}</h3>
|
<h3 className="text-sm font-semibold text-foreground truncate">{title}</h3>
|
||||||
<p className="text-xs text-muted-foreground">
|
<p className="text-xs text-muted-foreground">
|
||||||
{compiledSlides.length} slides · {totalDuration.toFixed(1)}s ·{" "}
|
{compiledSlides.length} slides · {totalDuration.toFixed(1)}s · {FPS}fps
|
||||||
{FPS}fps
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -479,9 +461,7 @@ function VideoPresentationPlayer({
|
||||||
<Loader2 className="size-3.5 animate-spin text-primary" />
|
<Loader2 className="size-3.5 animate-spin text-primary" />
|
||||||
<span className="text-xs font-medium">
|
<span className="text-xs font-medium">
|
||||||
Rendering {renderFormat ?? ""}{" "}
|
Rendering {renderFormat ?? ""}{" "}
|
||||||
{renderProgress !== null
|
{renderProgress !== null ? `${Math.round(renderProgress * 100)}%` : "..."}
|
||||||
? `${Math.round(renderProgress * 100)}%`
|
|
||||||
: "..."}
|
|
||||||
</span>
|
</span>
|
||||||
<div className="h-1.5 w-20 overflow-hidden rounded-full bg-secondary">
|
<div className="h-1.5 w-20 overflow-hidden rounded-full bg-secondary">
|
||||||
<div
|
<div
|
||||||
|
|
@ -538,9 +518,7 @@ function VideoPresentationPlayer({
|
||||||
<AlertCircleIcon className="mt-0.5 size-4 shrink-0 text-destructive" />
|
<AlertCircleIcon className="mt-0.5 size-4 shrink-0 text-destructive" />
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-medium text-destructive">Download Failed</p>
|
<p className="text-sm font-medium text-destructive">Download Failed</p>
|
||||||
<p className="mt-1 text-xs text-destructive/70 whitespace-pre-wrap">
|
<p className="mt-1 text-xs text-destructive/70 whitespace-pre-wrap">{renderError}</p>
|
||||||
{renderError}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -626,8 +604,7 @@ export const GenerateVideoPresentationToolUI = makeAssistantToolUI<
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const isPublicRoute = pathname?.startsWith("/public/");
|
const isPublicRoute = pathname?.startsWith("/public/");
|
||||||
const shareToken =
|
const shareToken = isPublicRoute && typeof params?.token === "string" ? params.token : null;
|
||||||
isPublicRoute && typeof params?.token === "string" ? params.token : null;
|
|
||||||
|
|
||||||
const title = args.video_title || "SurfSense Presentation";
|
const title = args.video_title || "SurfSense Presentation";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,7 @@ const carouselItems = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Video Generation",
|
title: "Video Generation",
|
||||||
description:
|
description: "Create short videos with AI-generated visuals and narration from your sources.",
|
||||||
"Create short videos with AI-generated visuals and narration from your sources.",
|
|
||||||
src: "/homepage/hero_tutorial/video_gen_surf.mp4",
|
src: "/homepage/hero_tutorial/video_gen_surf.mp4",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -176,9 +175,7 @@ function HeroCarousel() {
|
||||||
|
|
||||||
const id = setTimeout(() => {
|
const id = setTimeout(() => {
|
||||||
directionRef.current = "forward";
|
directionRef.current = "forward";
|
||||||
setActiveIndex((prev) =>
|
setActiveIndex((prev) => (prev >= carouselItems.length - 1 ? 0 : prev + 1));
|
||||||
prev >= carouselItems.length - 1 ? 0 : prev + 1
|
|
||||||
);
|
|
||||||
}, AUTOPLAY_MS);
|
}, AUTOPLAY_MS);
|
||||||
|
|
||||||
return () => clearTimeout(id);
|
return () => clearTimeout(id);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,10 @@ const replacements = [
|
||||||
process.env.NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE || "LOCAL",
|
process.env.NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE || "LOCAL",
|
||||||
],
|
],
|
||||||
["__NEXT_PUBLIC_ETL_SERVICE__", process.env.NEXT_PUBLIC_ETL_SERVICE || "DOCLING"],
|
["__NEXT_PUBLIC_ETL_SERVICE__", process.env.NEXT_PUBLIC_ETL_SERVICE || "DOCLING"],
|
||||||
["__NEXT_PUBLIC_ZERO_CACHE_URL__", process.env.NEXT_PUBLIC_ZERO_CACHE_URL || "http://localhost:4848"],
|
[
|
||||||
|
"__NEXT_PUBLIC_ZERO_CACHE_URL__",
|
||||||
|
process.env.NEXT_PUBLIC_ZERO_CACHE_URL || "http://localhost:4848",
|
||||||
|
],
|
||||||
["__NEXT_PUBLIC_DEPLOYMENT_MODE__", process.env.NEXT_PUBLIC_DEPLOYMENT_MODE || "self-hosted"],
|
["__NEXT_PUBLIC_DEPLOYMENT_MODE__", process.env.NEXT_PUBLIC_DEPLOYMENT_MODE || "self-hosted"],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { useQuery } from "@rocicorp/zero/react";
|
||||||
import { useSetAtom } from "jotai";
|
import { useSetAtom } from "jotai";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { chatSessionStateAtom } from "@/atoms/chat/chat-session-state.atom";
|
import { chatSessionStateAtom } from "@/atoms/chat/chat-session-state.atom";
|
||||||
import { queries } from "@/zero/queries";
|
import { queries } from "@/zero/queries";
|
||||||
import { useQuery } from "@rocicorp/zero/react";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syncs chat session state for a thread via Zero.
|
* Syncs chat session state for a thread via Zero.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { useQuery } from "@rocicorp/zero/react";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
import { useAtomValue } from "jotai";
|
import { useAtomValue } from "jotai";
|
||||||
import { useCallback, useEffect, useMemo, useRef } from "react";
|
import { useCallback, useEffect, useMemo, useRef } from "react";
|
||||||
|
|
@ -9,7 +10,6 @@ import type { Author, Comment, CommentReply } from "@/contracts/types/chat-comme
|
||||||
import type { Membership } from "@/contracts/types/members.types";
|
import type { Membership } from "@/contracts/types/members.types";
|
||||||
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
import { cacheKeys } from "@/lib/query-client/cache-keys";
|
||||||
import { queries } from "@/zero/queries";
|
import { queries } from "@/zero/queries";
|
||||||
import { useQuery } from "@rocicorp/zero/react";
|
|
||||||
|
|
||||||
interface RawCommentRow {
|
interface RawCommentRow {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { useQuery } from "@rocicorp/zero/react";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import type { SearchSourceConnector } from "@/contracts/types/connector.types";
|
import type { SearchSourceConnector } from "@/contracts/types/connector.types";
|
||||||
import { queries } from "@/zero/queries";
|
import { queries } from "@/zero/queries";
|
||||||
import { useQuery } from "@rocicorp/zero/react";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syncs connectors for a search space via Zero.
|
* Syncs connectors for a search space via Zero.
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { useQuery } from "@rocicorp/zero/react";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { queries } from "@/zero/queries";
|
import { queries } from "@/zero/queries";
|
||||||
import { useQuery } from "@rocicorp/zero/react";
|
|
||||||
|
|
||||||
export type DocumentsProcessingStatus = "idle" | "processing" | "success" | "error";
|
export type DocumentsProcessingStatus = "idle" | "processing" | "success" | "error";
|
||||||
|
|
||||||
|
|
@ -20,9 +20,7 @@ export function useDocumentsProcessing(searchSpaceId: number | null): DocumentsP
|
||||||
const wasProcessingRef = useRef(false);
|
const wasProcessingRef = useRef(false);
|
||||||
const successTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
const successTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||||
|
|
||||||
const [documents] = useQuery(
|
const [documents] = useQuery(queries.documents.bySpace({ searchSpaceId: searchSpaceId ?? -1 }));
|
||||||
queries.documents.bySpace({ searchSpaceId: searchSpaceId ?? -1 })
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!searchSpaceId || !documents) return;
|
if (!searchSpaceId || !documents) return;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { useQuery } from "@rocicorp/zero/react";
|
||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import type { DocumentSortBy, DocumentTypeEnum, SortOrder } from "@/contracts/types/document.types";
|
import type { DocumentSortBy, DocumentTypeEnum, SortOrder } from "@/contracts/types/document.types";
|
||||||
import { documentsApiService } from "@/lib/apis/documents-api.service";
|
import { documentsApiService } from "@/lib/apis/documents-api.service";
|
||||||
import { queries } from "@/zero/queries";
|
import { queries } from "@/zero/queries";
|
||||||
import { useQuery } from "@rocicorp/zero/react";
|
|
||||||
|
|
||||||
export interface DocumentStatusType {
|
export interface DocumentStatusType {
|
||||||
state: "ready" | "pending" | "processing" | "failed";
|
state: "ready" | "pending" | "processing" | "failed";
|
||||||
|
|
@ -254,7 +254,9 @@ export function useDocuments(
|
||||||
...existing,
|
...existing,
|
||||||
title: liveItem.title,
|
title: liveItem.title,
|
||||||
document_type: liveItem.documentType,
|
document_type: liveItem.documentType,
|
||||||
status: (liveItem.status as unknown as DocumentStatusType) ?? { state: "ready" as const },
|
status: (liveItem.status as unknown as DocumentStatusType) ?? {
|
||||||
|
state: "ready" as const,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { useQuery } from "@rocicorp/zero/react";
|
||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import type { InboxItem, NotificationCategory } from "@/contracts/types/inbox.types";
|
import type { InboxItem, NotificationCategory } from "@/contracts/types/inbox.types";
|
||||||
import { notificationsApiService } from "@/lib/apis/notifications-api.service";
|
import { notificationsApiService } from "@/lib/apis/notifications-api.service";
|
||||||
import { queries } from "@/zero/queries";
|
import { queries } from "@/zero/queries";
|
||||||
import { useQuery } from "@rocicorp/zero/react";
|
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
InboxItem,
|
InboxItem,
|
||||||
|
|
@ -118,9 +118,7 @@ export function useInbox(
|
||||||
}, [userId, searchSpaceId, category, prefetchedUnread, prefetchedUnreadReady]);
|
}, [userId, searchSpaceId, category, prefetchedUnread, prefetchedUnreadReady]);
|
||||||
|
|
||||||
// EFFECT 2: Zero real-time sync for notification updates
|
// EFFECT 2: Zero real-time sync for notification updates
|
||||||
const [zeroNotifications] = useQuery(
|
const [zeroNotifications] = useQuery(queries.notifications.byUser({ userId: userId ?? "" }));
|
||||||
queries.notifications.byUser({ userId: userId ?? "" })
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!userId || !searchSpaceId || !zeroNotifications || !initialLoadDoneRef.current) return;
|
if (!userId || !searchSpaceId || !zeroNotifications || !initialLoadDoneRef.current) return;
|
||||||
|
|
@ -134,9 +132,7 @@ export function useInbox(
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
const recentItems = validItems.filter(
|
const recentItems = validItems.filter((item) => new Date(item.createdAt) > cutoff);
|
||||||
(item) => new Date(item.createdAt) > cutoff
|
|
||||||
);
|
|
||||||
|
|
||||||
const liveIds = new Set(recentItems.map((d) => d.id));
|
const liveIds = new Set(recentItems.map((d) => d.id));
|
||||||
|
|
||||||
|
|
@ -145,18 +141,21 @@ export function useInbox(
|
||||||
|
|
||||||
const newItems: InboxItem[] = recentItems
|
const newItems: InboxItem[] = recentItems
|
||||||
.filter((d) => !prevIds.has(d.id))
|
.filter((d) => !prevIds.has(d.id))
|
||||||
.map((item) => ({
|
.map(
|
||||||
id: item.id,
|
(item) =>
|
||||||
user_id: item.userId,
|
({
|
||||||
search_space_id: item.searchSpaceId ?? undefined,
|
id: item.id,
|
||||||
type: item.type,
|
user_id: item.userId,
|
||||||
title: item.title,
|
search_space_id: item.searchSpaceId ?? undefined,
|
||||||
message: item.message,
|
type: item.type,
|
||||||
read: item.read,
|
title: item.title,
|
||||||
metadata: item.metadata as unknown as Record<string, unknown>,
|
message: item.message,
|
||||||
created_at: new Date(item.createdAt).toISOString(),
|
read: item.read,
|
||||||
updated_at: item.updatedAt ? new Date(item.updatedAt).toISOString() : null,
|
metadata: item.metadata as unknown as Record<string, unknown>,
|
||||||
} as InboxItem));
|
created_at: new Date(item.createdAt).toISOString(),
|
||||||
|
updated_at: item.updatedAt ? new Date(item.updatedAt).toISOString() : null,
|
||||||
|
}) as InboxItem
|
||||||
|
);
|
||||||
|
|
||||||
let updated = prev.map((existing) => {
|
let updated = prev.map((existing) => {
|
||||||
const liveItem = recentItems.find((v) => v.id === existing.id);
|
const liveItem = recentItems.find((v) => v.id === existing.id);
|
||||||
|
|
@ -187,10 +186,7 @@ export function useInbox(
|
||||||
// Calibrate older-unread offset on first Zero data
|
// Calibrate older-unread offset on first Zero data
|
||||||
if (olderUnreadOffsetRef.current === null) {
|
if (olderUnreadOffsetRef.current === null) {
|
||||||
const recentUnreadCount = recentItems.filter((item) => !item.read).length;
|
const recentUnreadCount = recentItems.filter((item) => !item.read).length;
|
||||||
olderUnreadOffsetRef.current = Math.max(
|
olderUnreadOffsetRef.current = Math.max(0, apiUnreadTotalRef.current - recentUnreadCount);
|
||||||
0,
|
|
||||||
apiUnreadTotalRef.current - recentUnreadCount
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (olderUnreadOffsetRef.current !== null) {
|
if (olderUnreadOffsetRef.current !== null) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { useQuery } from "@rocicorp/zero/react";
|
||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import type { RawMessage } from "@/contracts/types/chat-messages.types";
|
import type { RawMessage } from "@/contracts/types/chat-messages.types";
|
||||||
import { queries } from "@/zero/queries";
|
import { queries } from "@/zero/queries";
|
||||||
import { useQuery } from "@rocicorp/zero/react";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syncs chat messages for a thread via Zero.
|
* Syncs chat messages for a thread via Zero.
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,12 @@ import * as Babel from "@babel/standalone";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
AbsoluteFill,
|
AbsoluteFill,
|
||||||
useCurrentFrame,
|
Easing,
|
||||||
useVideoConfig,
|
|
||||||
spring,
|
|
||||||
interpolate,
|
interpolate,
|
||||||
Sequence,
|
Sequence,
|
||||||
Easing,
|
spring,
|
||||||
|
useCurrentFrame,
|
||||||
|
useVideoConfig,
|
||||||
} from "remotion";
|
} from "remotion";
|
||||||
import { DURATION_IN_FRAMES } from "./constants";
|
import { DURATION_IN_FRAMES } from "./constants";
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@ function createStagger(totalFrames: number) {
|
||||||
frame: number,
|
frame: number,
|
||||||
fps: number,
|
fps: number,
|
||||||
index: number,
|
index: number,
|
||||||
total: number,
|
total: number
|
||||||
): { opacity: number; transform: string } {
|
): { opacity: number; transform: string } {
|
||||||
const enterPhase = Math.floor(totalFrames * 0.2);
|
const enterPhase = Math.floor(totalFrames * 0.2);
|
||||||
const exitStart = Math.floor(totalFrames * 0.8);
|
const exitStart = Math.floor(totalFrames * 0.8);
|
||||||
|
|
@ -43,9 +43,7 @@ function createStagger(totalFrames: number) {
|
||||||
|
|
||||||
const opacity = s * (1 - exit);
|
const opacity = s * (1 - exit);
|
||||||
const translateY =
|
const translateY =
|
||||||
interpolate(s, [0, 1], [40, 0]) +
|
interpolate(s, [0, 1], [40, 0]) + interpolate(exit, [0, 1], [0, -30]) + ambient;
|
||||||
interpolate(exit, [0, 1], [0, -30]) +
|
|
||||||
ambient;
|
|
||||||
const scale = interpolate(s, [0, 1], [0.97, 1]);
|
const scale = interpolate(s, [0, 1], [0.97, 1]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -97,7 +95,7 @@ export function prepareSource(code: string): string {
|
||||||
const codeWithoutImports = code.replace(/^import\s+.*$/gm, "").trim();
|
const codeWithoutImports = code.replace(/^import\s+.*$/gm, "").trim();
|
||||||
|
|
||||||
const match = codeWithoutImports.match(
|
const match = codeWithoutImports.match(
|
||||||
/export\s+(?:const|function)\s+(\w+)\s*(?::\s*React\.FC\s*)?=?\s*\(\s*\)\s*=>\s*\{([\s\S]*)\};?\s*$/,
|
/export\s+(?:const|function)\s+(\w+)\s*(?::\s*React\.FC\s*)?=?\s*\(\s*\)\s*=>\s*\{([\s\S]*)\};?\s*$/
|
||||||
);
|
);
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
|
|
@ -137,18 +135,10 @@ export function compileCheck(code: string): CompileResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function compileToComponent(
|
export function compileToComponent(code: string, durationInFrames?: number): React.ComponentType {
|
||||||
code: string,
|
const staggerFn = durationInFrames ? createStagger(durationInFrames) : defaultStagger;
|
||||||
durationInFrames?: number,
|
|
||||||
): React.ComponentType {
|
|
||||||
const staggerFn = durationInFrames
|
|
||||||
? createStagger(durationInFrames)
|
|
||||||
: defaultStagger;
|
|
||||||
|
|
||||||
const jsCode = transpile(code);
|
const jsCode = transpile(code);
|
||||||
const factory = new Function(
|
const factory = new Function(...INJECTED_NAMES, `${jsCode}\nreturn DynamicComponent;`);
|
||||||
...INJECTED_NAMES,
|
|
||||||
`${jsCode}\nreturn DynamicComponent;`,
|
|
||||||
);
|
|
||||||
return factory(...buildInjectedValues(staggerFn)) as React.ComponentType;
|
return factory(...buildInjectedValues(staggerFn)) as React.ComponentType;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
surfsense_web/lib/remotion/dom-to-pptx.d.ts
vendored
2
surfsense_web/lib/remotion/dom-to-pptx.d.ts
vendored
|
|
@ -13,6 +13,6 @@ declare module "dom-to-pptx" {
|
||||||
|
|
||||||
export function exportToPptx(
|
export function exportToPptx(
|
||||||
elementOrSelector: string | HTMLElement | Array<string | HTMLElement>,
|
elementOrSelector: string | HTMLElement | Array<string | HTMLElement>,
|
||||||
options?: ExportOptions,
|
options?: ExportOptions
|
||||||
): Promise<Blob>;
|
): Promise<Blob>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import path from "path";
|
|
||||||
import { createMDX } from "fumadocs-mdx/next";
|
import { createMDX } from "fumadocs-mdx/next";
|
||||||
import type { NextConfig } from "next";
|
import type { NextConfig } from "next";
|
||||||
import createNextIntlPlugin from "next-intl/plugin";
|
import createNextIntlPlugin from "next-intl/plugin";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
// Create the next-intl plugin
|
// Create the next-intl plugin
|
||||||
const withNextIntl = createNextIntlPlugin("./i18n/request.ts");
|
const withNextIntl = createNextIntlPlugin("./i18n/request.ts");
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,19 @@ import { z } from "zod";
|
||||||
import { zql } from "../schema/index";
|
import { zql } from "../schema/index";
|
||||||
|
|
||||||
export const messageQueries = {
|
export const messageQueries = {
|
||||||
byThread: defineQuery(
|
byThread: defineQuery(z.object({ threadId: z.number() }), ({ args: { threadId } }) =>
|
||||||
z.object({ threadId: z.number() }),
|
zql.new_chat_messages.where("threadId", threadId).orderBy("createdAt", "asc")
|
||||||
({ args: { threadId } }) =>
|
|
||||||
zql.new_chat_messages.where("threadId", threadId).orderBy("createdAt", "asc"),
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const commentQueries = {
|
export const commentQueries = {
|
||||||
byThread: defineQuery(
|
byThread: defineQuery(z.object({ threadId: z.number() }), ({ args: { threadId } }) =>
|
||||||
z.object({ threadId: z.number() }),
|
zql.chat_comments.where("threadId", threadId).orderBy("createdAt", "asc")
|
||||||
({ args: { threadId } }) =>
|
|
||||||
zql.chat_comments.where("threadId", threadId).orderBy("createdAt", "asc"),
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const chatSessionQueries = {
|
export const chatSessionQueries = {
|
||||||
byThread: defineQuery(
|
byThread: defineQuery(z.object({ threadId: z.number() }), ({ args: { threadId } }) =>
|
||||||
z.object({ threadId: z.number() }),
|
zql.chat_session_state.where("threadId", threadId).one()
|
||||||
({ args: { threadId } }) => zql.chat_session_state.where("threadId", threadId).one(),
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,13 @@ import { z } from "zod";
|
||||||
import { zql } from "../schema/index";
|
import { zql } from "../schema/index";
|
||||||
|
|
||||||
export const documentQueries = {
|
export const documentQueries = {
|
||||||
bySpace: defineQuery(
|
bySpace: defineQuery(z.object({ searchSpaceId: z.number() }), ({ args: { searchSpaceId } }) =>
|
||||||
z.object({ searchSpaceId: z.number() }),
|
zql.documents.where("searchSpaceId", searchSpaceId).orderBy("createdAt", "desc")
|
||||||
({ args: { searchSpaceId } }) =>
|
|
||||||
zql.documents.where("searchSpaceId", searchSpaceId).orderBy("createdAt", "desc"),
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const connectorQueries = {
|
export const connectorQueries = {
|
||||||
bySpace: defineQuery(
|
bySpace: defineQuery(z.object({ searchSpaceId: z.number() }), ({ args: { searchSpaceId } }) =>
|
||||||
z.object({ searchSpaceId: z.number() }),
|
zql.search_source_connectors.where("searchSpaceId", searchSpaceId).orderBy("createdAt", "desc")
|
||||||
({ args: { searchSpaceId } }) =>
|
|
||||||
zql.search_source_connectors
|
|
||||||
.where("searchSpaceId", searchSpaceId)
|
|
||||||
.orderBy("createdAt", "desc"),
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,7 @@ import { z } from "zod";
|
||||||
import { zql } from "../schema/index";
|
import { zql } from "../schema/index";
|
||||||
|
|
||||||
export const notificationQueries = {
|
export const notificationQueries = {
|
||||||
byUser: defineQuery(
|
byUser: defineQuery(z.object({ userId: z.string() }), ({ args: { userId } }) =>
|
||||||
z.object({ userId: z.string() }),
|
zql.notifications.where("userId", userId).orderBy("createdAt", "desc")
|
||||||
({ args: { userId } }) =>
|
|
||||||
zql.notifications.where("userId", userId).orderBy("createdAt", "desc"),
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { table, string, number, json } from "@rocicorp/zero";
|
import { json, number, string, table } from "@rocicorp/zero";
|
||||||
|
|
||||||
export const newChatMessageTable = table("new_chat_messages")
|
export const newChatMessageTable = table("new_chat_messages")
|
||||||
.columns({
|
.columns({
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { table, string, number, boolean, json } from "@rocicorp/zero";
|
import { boolean, json, number, string, table } from "@rocicorp/zero";
|
||||||
|
|
||||||
export const documentTable = table("documents")
|
export const documentTable = table("documents")
|
||||||
.columns({
|
.columns({
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { table, string, number, boolean, json } from "@rocicorp/zero";
|
import { boolean, json, number, string, table } from "@rocicorp/zero";
|
||||||
|
|
||||||
export const notificationTable = table("notifications")
|
export const notificationTable = table("notifications")
|
||||||
.columns({
|
.columns({
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { createSchema, createBuilder, relationships } from "@rocicorp/zero";
|
import { createBuilder, createSchema, relationships } from "@rocicorp/zero";
|
||||||
import { chatCommentTable, chatSessionStateTable, newChatMessageTable } from "./chat";
|
import { chatCommentTable, chatSessionStateTable, newChatMessageTable } from "./chat";
|
||||||
import { documentTable, searchSourceConnectorTable } from "./documents";
|
import { documentTable, searchSourceConnectorTable } from "./documents";
|
||||||
import { notificationTable } from "./inbox";
|
import { notificationTable } from "./inbox";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue