Skip to content

Commit

Permalink
feat: rewind keyword search (#1330)
Browse files Browse the repository at this point in the history
* feat: rewind keyword search

* fix: use FTS , improve request handling

* fix: ai settings and date navigation

* fix: type error

* fix: improve the suggestion feature

* feat: rtl scroll

* feat: filter by apps, improve ux while search

* fix: remove highlight keyword

* feat: add frame url

* fix: data filter broken, scroll direction, enter to search

* fix: ffmpeg error

* feat: add loading spinner when image are loading

---------

Co-authored-by: shaikzeeshan <shaikzeeshan999@gmail.com undefined>
  • Loading branch information
shaik-zeeshan and shaikzeeshan authored Feb 21, 2025
1 parent d350263 commit 67f624b
Show file tree
Hide file tree
Showing 40 changed files with 3,883 additions and 1,478 deletions.
Binary file modified pipes/rewind/bun.lockb
Binary file not shown.
17 changes: 10 additions & 7 deletions pipes/rewind/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
},
"dependencies": {
"@radix-ui/react-accordion": "^1.2.2",
"@radix-ui/react-checkbox": "^1.1.3",
"@radix-ui/react-dialog": "^1.1.3",
"@radix-ui/react-label": "^2.1.1",
"@radix-ui/react-popover": "^1.1.3",
"@radix-ui/react-checkbox": "^1.1.4",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-label": "^2.1.2",
"@radix-ui/react-popover": "^1.1.6",
"@radix-ui/react-progress": "^1.1.1",
"@radix-ui/react-scroll-area": "^1.2.2",
"@radix-ui/react-select": "^2.1.3",
"@radix-ui/react-separator": "^1.1.1",
"@radix-ui/react-slider": "^1.2.2",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-switch": "^1.1.2",
"@radix-ui/react-toast": "^1.2.3",
"@radix-ui/react-tooltip": "^1.1.5",
Expand All @@ -33,17 +33,18 @@
"ai": "^4.0.18",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "1.0.0",
"cmdk": "^1.0.4",
"date-fns": "^4.1.0",
"framer-motion": "^11.14.4",
"install": "^0.13.0",
"js-levenshtein": "^1.1.6",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
"lucide-react": "^0.468.0",
"lucide-react": "^0.475.0",
"magic-ui": "^0.1.0",
"next": "15.1.0",
"npm": "^10.9.2",
"nuqs": "^2.3.2",
"openai": "^4.76.3",
"react": "^19.0.0",
"react-day-picker": "8.10.1",
Expand All @@ -52,6 +53,7 @@
"react-syntax-highlighter": "^15.6.1",
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0",
"stopword": "^3.1.4",
"tailwind-merge": "^2.5.5",
"tailwindcss-animate": "^1.0.7",
"zustand": "^5.0.3"
Expand All @@ -61,6 +63,7 @@
"@types/node": "^22.10.2",
"@types/react": "^19",
"@types/react-dom": "^19",
"@types/stopword": "^2.0.3",
"autoprefixer": "^10.4.20",
"eslint": "^9.19.0",
"postcss": "^8.4.49",
Expand Down
85 changes: 42 additions & 43 deletions pipes/rewind/src/app/api/settings/route.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,59 @@
// app/api/settings/route.ts
import { pipe } from "@screenpipe/js";
import { NextResponse } from "next/server";
import type { Settings } from "@screenpipe/js";
import { getDefaultSettings } from "@screenpipe/browser";
// Force Node.js runtime
export const runtime = "nodejs"; // Add this line
export const dynamic = "force-dynamic";

export async function GET() {
const defaultSettings = getDefaultSettings();
try {
const settingsManager = pipe.settings;
if (!settingsManager) {
throw new Error("settingsManager not found");
}
const rawSettings = await settingsManager.getAll();
return NextResponse.json(rawSettings);
} catch (error) {
console.error("failed to get settings:", error);
return NextResponse.json(defaultSettings);
}
const defaultSettings = getDefaultSettings();
try {
const settingsManager = pipe.settings;
if (!settingsManager) {
throw new Error("settingsManager not found");
}
const rawSettings = await settingsManager.getAll();
return NextResponse.json(rawSettings);
} catch (error) {
console.error("failed to get settings:", error);
return NextResponse.json(defaultSettings);
}
}

export async function PUT(request: Request) {
try {
const settingsManager = pipe.settings;
if (!settingsManager) {
throw new Error("settingsManager not found");
}
try {
const settingsManager = pipe.settings;
if (!settingsManager) {
throw new Error("settingsManager not found");
}

const body = await request.json();
const { key, value, isPartialUpdate, reset } = body;
const body = await request.json();
const { key, value, isPartialUpdate, reset } = body;

if (reset) {
if (key) {
await settingsManager.resetKey(key);
} else {
await settingsManager.reset();
}
return NextResponse.json({ success: true });
}
if (reset) {
if (key) {
await settingsManager.resetKey(key);
} else {
await settingsManager.reset();
}
return NextResponse.json({ success: true });
}

if (isPartialUpdate) {
const serializedSettings = JSON.parse(JSON.stringify(value));
await settingsManager.update(serializedSettings);
} else {
const serializedValue = JSON.parse(JSON.stringify(value));
await settingsManager.set(key, serializedValue);
}
if (isPartialUpdate) {
const serializedSettings = JSON.parse(JSON.stringify(value));
await settingsManager.update(serializedSettings);
} else {
const serializedValue = JSON.parse(JSON.stringify(value));
await settingsManager.set(key, serializedValue);
}

return NextResponse.json({ success: true });
} catch (error) {
console.error("failed to update settings:", error);
return NextResponse.json(
{ error: "failed to update settings" },
{ status: 500 }
);
}
return NextResponse.json({ success: true });
} catch (error) {
console.error("failed to update settings:", error);
return NextResponse.json(
{ error: "failed to update settings" },
{ status: 500 },
);
}
}
39 changes: 24 additions & 15 deletions pipes/rewind/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { SearchCommand } from "@/components/search-command";
import { NuqsAdapter } from "nuqs/adapters/next/app";
import { getScreenpipeAppSettings } from "@/lib/actions/get-screenpipe-app-settings";
import { SettingsProvider } from "@/components/settings-provider";

const geistSans = Geist({
variable: "--font-geist-sans",
Expand All @@ -26,9 +30,7 @@ export default async function RootLayout({
}>) {
const checkSettings = async () => {
try {
const port = process.env.PORT || 3000;
const response = await fetch(`http://localhost:${port}/api/settings`);
const settings = await response.json();
const settings = await getScreenpipeAppSettings();

return settings.enableFrameCache;
} catch (error) {
Expand All @@ -44,19 +46,26 @@ export default async function RootLayout({
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{!enabled ? (
<div className="flex items-center justify-center h-screen">
<div className="text-center space-y-4">
<h2 className="text-xl font-medium">Frame Cache Disabled</h2>
<p className="text-muted-foreground">
Please enable frame cache in settings to use the timeline
feature.
</p>
<SettingsProvider>
{!enabled ? (
<div className="flex items-center justify-center h-screen">
<div className="text-center space-y-4">
<h2 className="text-xl font-medium">Frame Cache Disabled</h2>
<p className="text-muted-foreground">
Please enable frame cache in settings to use the timeline
feature.
</p>
</div>
</div>
</div>
) : (
<>{children}</>
)}
) : (
<>
<NuqsAdapter>
<SearchCommand />
{children}
</NuqsAdapter>
</>
)}
</SettingsProvider>
</body>
</html>
);
Expand Down
19 changes: 12 additions & 7 deletions pipes/rewind/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
"use client";
import { useEffect, useState, useRef, useMemo, useCallback } from "react";
import { Loader2, RotateCcw, AlertCircle } from "lucide-react";
import { TimelineIconsSection } from "@/components/timeline/timeline-dock-section";
import { AudioTranscript } from "@/components/timeline/audio-transcript";
import { AIPanel } from "@/components/timeline/ai-panel";
import { TimelineProvider } from "@/lib/hooks/use-timeline-selection";
import { throttle } from "lodash";
import { AGENTS } from "@/components/timeline/agents";
import { TimelineSelection } from "@/components/timeline/timeline-selection";
import { TimelineControls } from "@/components/timeline/timeline-controls";
import { TimelineSearch } from "@/components/timeline/timeline-search";
import { TimelineSearch2 } from "@/components/timeline/timeline-search-v2";
import { addDays, isAfter, isSameDay, subDays } from "date-fns";
import { getStartDate } from "@/lib/actions/get-start-date";
import { useTimelineData } from "@/lib/hooks/use-timeline-data";
import { useCurrentFrame } from "@/lib/hooks/use-current-frame";
import { TimelineSlider } from "@/components/timeline/timeline";
import { useTimelineStore } from "@/lib/hooks/use-timeline-store";
import { hasFramesForDate } from "@/lib/actions/has-frames-date";
import { CommandShortcut } from "@/components/ui/command";

export interface StreamTimeSeriesResponse {
timestamp: string;
Expand Down Expand Up @@ -265,11 +262,16 @@ export default function Timeline() {
if (!hasDateBeenFetched(newDate)) {
setCurrentFrame(null);
const frameTimeStamp = new Date(newDate);
if (frameTimeStamp.getDate() === new Date(currentDate).getDate()) {
console.log(
frameTimeStamp.getDate() === new Date(currentDate).getDate(),
startAndEndDates.start.getDate(),
newDate.getDate(),
);
if (isSameDay(frameTimeStamp, new Date(currentDate))) {
return;
}

if (isAfter(startAndEndDates.start.getDate(), newDate.getDate())) {
if (isAfter(startAndEndDates.start, newDate)) {
return;
}

Expand Down Expand Up @@ -342,6 +344,10 @@ export default function Timeline() {
onResultSelect={animateToIndex}
onSearchResults={setSearchResults}
/> */}
<div>
<CommandShortcut>⌘K</CommandShortcut>{" "}
<span className="text-xs text-muted-foreground">to search</span>
</div>
</div>
</div>

Expand Down Expand Up @@ -393,7 +399,6 @@ export default function Timeline() {
)}
{currentFrame && (
<img
//src={`data:image/png;base64,${imageFrame}`}
src={`http://localhost:3030/frames/${currentFrame.devices[0].frame_id}`}
className="absolute inset-0 w-4/5 h-auto max-h-[75vh] object-contain mx-auto border rounded-xl p-2 mt-20"
alt="Current frame"
Expand Down
Loading

0 comments on commit 67f624b

Please sign in to comment.