Skip to content
Open
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
Binary file modified pipes/search/bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions pipes/search/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@radix-ui/react-avatar": "^1.1.3",
"@radix-ui/react-checkbox": "^1.1.3",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.1",
"@radix-ui/react-popover": "^1.1.3",
"@radix-ui/react-progress": "^1.1.1",
Expand Down
49 changes: 33 additions & 16 deletions pipes/search/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,46 @@ import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { useSettings } from "@/lib/hooks/use-settings";
import { Terminal } from "lucide-react";
import { SearchChat } from "@/components/search-chat";
import { Sidebar } from "@/components/sidebar";
import { useSearchHistory } from "@/lib/hooks/use-search-history";
import { cn } from "@/lib/utils";

export default function SearchPage() {
const { settings } = useSettings();
const { isCollapsed } = useSearchHistory();
const aiDisabled =
settings?.aiProviderType === "screenpipe-cloud" && !settings?.user?.token;

return (
<div
className={`flex flex-col gap-4 items-center justify-center h-full ${aiDisabled ? "mt-2" : "mt-12"}`}
>
{aiDisabled && (
<Alert className="w-[70%] shadow-sm">
<Terminal className="h-4 w-4" />
<AlertTitle>heads up!</AlertTitle>
<AlertDescription className="text-muted-foreground">
your ai provider is set to &apos;screenpipe-cloud&apos; and you
don&apos;t have logged in <br />
please login to use this pipe, go to app &gt; settings &gt; login
</AlertDescription>
</Alert>
)}
<p className="text-2xl font-bold">search your screen history</p>
<SearchChat />
<div className="flex h-screen overflow-hidden">
<Sidebar />
<main
className={cn(
"flex-1 overflow-auto transition-all duration-200",
!isCollapsed ? "md:ml-80" : "ml-0"
)}
>
<div
className={`flex flex-col gap-4 items-center px-4 ${
aiDisabled ? "mt-2" : "mt-12"
}`}
>
{aiDisabled && (
<Alert className="w-[70%] max-w-2xl shadow-sm">
<Terminal className="h-4 w-4" />
<AlertTitle>heads up!</AlertTitle>
<AlertDescription className="text-muted-foreground">
your AI provider is set to &apos;screenpipe-cloud&apos;, and you
aren&apos;t logged in. <br />
please log in to use this pipe. go to app &gt; settings &gt;
log in.
</AlertDescription>
</Alert>
)}
<p className="text-2xl font-bold">search your screen history</p>
<SearchChat />
</div>
</main>
</div>
);
}
107 changes: 52 additions & 55 deletions pipes/search/src/components/search-chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ import {
Square,
Clock,
Check,
Plus,
AlertCircle,
Bot,
Settings,
Copy,
SparklesIcon,
Expand Down Expand Up @@ -75,31 +73,14 @@ import { Checkbox } from "@/components/ui/checkbox";
import { IconCode } from "@/components/ui/icons";
import { CodeBlock } from "@/components/ui/codeblock";
import { SqlAutocompleteInput } from "@/components/sql-autocomplete-input";
import { cn, removeDuplicateSelections } from "@/lib/utils";
import { removeDuplicateSelections } from "@/lib/utils";
import {
ExampleSearch,
ExampleSearchCards,
} from "@/components/example-search-cards";
import { useDebounce } from "@/lib/hooks/use-debounce";
import { useHealthCheck } from "@/lib/hooks/use-health-check";
import {
SearchHistory,
useSearchHistory,
} from "@/lib/hooks/use-search-history";
import {
CommandInput,
CommandList,
CommandEmpty,
CommandGroup,
CommandItem,
Command,
} from "./ui/command";
import { type Speaker } from "@screenpipe/browser";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { useSearchHistory } from "@/lib/hooks/use-search-history";
import { useSettings } from "@/lib/hooks/use-settings";
import { SearchFilterGenerator } from "./search-filter-generator";
import {
Expand All @@ -109,6 +90,7 @@ import {
import { AIPresetsDialog } from "./ai-presets-dialog";
import { usePipeSettings } from "@/lib/hooks/use-pipe-settings";
import type { Settings as AppSettings } from "@screenpipe/js";
import { type Speaker } from "@screenpipe/browser";
import { DEFAULT_PROMPT } from "./ai-presets-dialog";
import { AIPresetsSelector } from "./ai-presets-selector";

Expand Down Expand Up @@ -229,12 +211,12 @@ export function SearchChat() {
const {
searches,
currentSearchId,
setCurrentSearchId,
addSearch,
deleteSearch,
isCollapsed,
toggleCollapse,
addAIResponse,
addUserMessage,
setCurrentSearchId,
} = useSearchHistory();

// Search state
const { health, isServerDown } = useHealthCheck();
const [query, setQuery] = useState("");
Expand Down Expand Up @@ -705,9 +687,15 @@ export function SearchChat() {
userMessage,
{ id: generateId(), role: "assistant", content: "" },
]);

const currentInput = floatingInput;
setFloatingInput("");
setIsAiLoading(true);

if (currentSearchId && currentInput) {
addUserMessage(currentSearchId, currentInput);
}

const preset = getPreset();

if (!preset) {
Expand Down Expand Up @@ -773,7 +761,7 @@ export function SearchChat() {
)
)}

User query: ${floatingInput}`,
User query: ${currentInput}`,
},
];

Expand Down Expand Up @@ -815,6 +803,10 @@ export function SearchChat() {
]);
scrollToBottom();
}

if (currentSearchId && fullResponse) {
addAIResponse(currentSearchId, fullResponse);
}
} catch (error: any) {
if (error.toString().includes("unauthorized")) {
toast({
Expand Down Expand Up @@ -874,7 +866,7 @@ export function SearchChat() {
setChatMessages([]);
scrollToBottom();
setResults([]);
setSimilarityThreshold(1); // Reset similarity threshold to 1
setSimilarityThreshold(1);

try {
// if browserUrl contains special characters like :, /, etc, wrap in double quotes
Expand Down Expand Up @@ -914,8 +906,10 @@ export function SearchChat() {
setResults(response.data);
setTotalResults(response.pagination.total);

// Save search to history
// await onAddSearch(searchParams, response.data);
if (newOffset === 0) {
const searchId = addSearch(searchParams, response.data);
setCurrentSearchId(searchId);
}
} catch (error) {
console.error("search error:", error);
toast({
Expand Down Expand Up @@ -1242,12 +1236,36 @@ export function SearchChat() {
));
};

// Add effect to restore search when currentSearchId changes
useEffect(() => {
// if (currentSearchId) {
console.log(`currentSearchId changed: ${currentSearchId}`);

if (currentSearchId === null) {
// reset to defaults
setQuery("");
setContentType("all");
setLimit(500);
setStartDate(new Date(Date.now() - 24 * 3600000));
setEndDate(new Date());
setAppName("");
setWindowName("");
setBrowserUrl("");
setIncludeFrames(false);
setMinLength(50);
setMaxLength(10000);
setSelectedSpeakers({});
setFrameName("");

setResults([]);
setTotalResults(0);
setHasSearched(false);
setShowExamples(true);
setChatMessages([]);

return;
}

const selectedSearch = searches.find((s) => s.id === currentSearchId);
if (selectedSearch) {
// Restore search parameters
setQuery(selectedSearch.searchParams.q || "");
setContentType(selectedSearch.searchParams.content_type);
setLimit(selectedSearch.searchParams.limit);
Expand Down Expand Up @@ -1275,20 +1293,13 @@ export function SearchChat() {
}))
);
}
} else {
console.log("no search found with id:", currentSearchId);
}
// }
}, [currentSearchId, searches]);

const handleNewSearch = () => {
// setCurrentSearchId(null);
location.reload();
// Add any other reset logic you need
};

// Add this effect near other useEffect hooks
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
// Check for Cmd+Shift (macOS) or Ctrl+Shift (Windows/Linux)
if (
e.shiftKey &&
((currentPlatform === "macos" && e.metaKey) ||
Expand All @@ -1309,18 +1320,6 @@ export function SearchChat() {

return (
<div className="w-full max-w-4xl mx-auto p-4 mt-12">
<div className="fixed top-4 left-4 z-50 flex items-center gap-2">
{/* <SidebarTrigger className="h-8 w-8" /> */}
<Button
variant="ghost"
size="icon"
onClick={handleNewSearch}
className="h-8 w-8"
>
<Plus className="h-4 w-4" />
</Button>
</div>

<div className="flex items-center justify-center mb-16">
{/* Add the new SearchFilterGenerator component */}
<SearchFilterGenerator
Expand All @@ -1345,8 +1344,6 @@ export function SearchChat() {
</div>
{/* Content Type Checkboxes and Code Button */}
<div className="flex items-center justify-center mb-4 gap-4">
{/* Remove MultiSelectCombobox from here */}

{/* Add browser URL input */}
<SqlAutocompleteInput
id="browser-url"
Expand Down
Loading