Skip to content

Commit 082fd5c

Browse files
committed
feat: save and restore theme-based topics across sessions
1 parent 7d34c8e commit 082fd5c

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

app/analyze/[videoId]/page.tsx

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,25 @@ export default function AnalyzePage() {
515515
setVideoInfo(null);
516516
}
517517

518-
setTopics(hydratedTopics);
519-
setBaseTopics(hydratedTopics);
518+
// Separate base topics and theme topics
519+
const baseTopicsFromCache = hydratedTopics.filter(topic => !topic.theme);
520+
const themeTopicsFromCache = hydratedTopics.filter(topic => topic.theme);
521+
522+
// Reconstruct themeTopicsMap
523+
const reconstructedThemeMap: Record<string, Topic[]> = {};
524+
themeTopicsFromCache.forEach(topic => {
525+
if (topic.theme) {
526+
if (!reconstructedThemeMap[topic.theme]) {
527+
reconstructedThemeMap[topic.theme] = [];
528+
}
529+
reconstructedThemeMap[topic.theme].push(topic);
530+
}
531+
});
532+
533+
setTopics(baseTopicsFromCache);
534+
setBaseTopics(baseTopicsFromCache);
535+
setThemeTopicsMap(reconstructedThemeMap);
536+
520537
const initialKeys = new Set<string>();
521538
hydratedTopics.forEach(topic => {
522539
if (topic.quote?.timestamp && topic.quote.text) {
@@ -525,7 +542,7 @@ export default function AnalyzePage() {
525542
}
526543
});
527544
setUsedTopicKeys(initialKeys);
528-
setSelectedTopic(hydratedTopics.length > 0 ? hydratedTopics[0] : null);
545+
setSelectedTopic(baseTopicsFromCache.length > 0 ? baseTopicsFromCache[0] : null);
529546

530547
// Set cached takeaways and questions
531548
if (cacheData.summary) {
@@ -1293,11 +1310,41 @@ export default function AnalyzePage() {
12931310
}
12941311
});
12951312
setUsedTopicKeys(nextUsedKeys);
1296-
themedTopics = hydratedThemeTopics;
1313+
1314+
// Tag theme topics with theme name
1315+
const themedTopicsWithTheme = hydratedThemeTopics.map(topic => ({
1316+
...topic,
1317+
theme: normalizedTheme
1318+
}));
1319+
1320+
themedTopics = themedTopicsWithTheme;
12971321
setThemeTopicsMap(prev => ({
12981322
...prev,
12991323
[normalizedTheme]: themedTopics || []
13001324
}));
1325+
1326+
// Save theme topics to database (background operation)
1327+
backgroundOperation(
1328+
'save-theme-topics',
1329+
async () => {
1330+
const allTopics = [
1331+
...baseTopics.map(t => ({ ...t, theme: null })),
1332+
...Object.entries(themeTopicsMap).flatMap(([theme, topics]) =>
1333+
topics.map(t => ({ ...t, theme }))
1334+
),
1335+
...themedTopicsWithTheme
1336+
];
1337+
1338+
await fetch("/api/update-video-analysis", {
1339+
method: "POST",
1340+
headers: { "Content-Type": "application/json" },
1341+
body: JSON.stringify({
1342+
videoId,
1343+
topics: allTopics
1344+
})
1345+
});
1346+
}
1347+
);
13011348
} catch (error) {
13021349
const isAbortError =
13031350
typeof error === "object" &&

app/api/update-video-analysis/route.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ async function handler(req: NextRequest) {
88
videoId,
99
summary,
1010
suggestedQuestions,
11-
translatedTranscripts
11+
translatedTranscripts,
12+
topics
1213
} = await req.json();
1314

1415
if (!videoId) {
@@ -37,6 +38,10 @@ async function handler(req: NextRequest) {
3738
updateData.translated_transcripts = translatedTranscripts;
3839
}
3940

41+
if (topics !== undefined) {
42+
updateData.topics = topics;
43+
}
44+
4045
const { data: updatedVideo, error: updateError } = await supabase
4146
.from('video_analyses')
4247
.update(updateData)

lib/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface Topic {
1515
title: string;
1616
description?: string;
1717
duration: number;
18+
theme?: string | null; // Theme name for theme-based topics, null/undefined for base topics
1819
segments: {
1920
start: number;
2021
end: number;

lib/validation.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ export const checkVideoCacheRequestSchema = z.object({
184184
export const updateVideoAnalysisRequestSchema = z.object({
185185
videoId: youtubeIdSchema,
186186
summary: z.any().optional(),
187-
suggestedQuestions: z.any().optional()
187+
suggestedQuestions: z.any().optional(),
188+
topics: z.array(z.any()).optional()
188189
});
189190

190191
// Rate limiting validation

0 commit comments

Comments
 (0)