fix(Nextjs): Outline streaming issue solved

This commit is contained in:
shiva raj badu 2025-08-06 22:31:56 +05:45
parent f6550b92a2
commit 1d4898cbce
No known key found for this signature in database
7 changed files with 38 additions and 18 deletions

View file

@ -18,7 +18,7 @@ import { Button } from "@/components/ui/button";
import { FileText } from "lucide-react";
interface OutlineContentProps {
outlines: string[] | null;
outlines: { content: string }[] | null;
isLoading: boolean;
isStreaming: boolean;
onDragEnd: (event: any) => void;
@ -83,7 +83,18 @@ const OutlineContent: React.FC<OutlineContentProps> = ({
collisionDetection={closestCenter}
onDragEnd={onDragEnd}
>
<SortableContext
{isStreaming ? (
outlines.map((item, index) => (
<OutlineItem
key={`slide-${index}`}
index={index + 1}
slideOutline={item}
isStreaming={isStreaming}
/>
))
) :
<SortableContext
items={outlines?.map((item, index) => ({ id: `slide-${index}` })) || []}
strategy={verticalListSortingStrategy}
>
@ -95,7 +106,7 @@ const OutlineContent: React.FC<OutlineContentProps> = ({
isStreaming={isStreaming}
/>
))}
</SortableContext>
</SortableContext>}
</DndContext>
<Button

View file

@ -10,7 +10,9 @@ import { useEffect } from "react"
interface OutlineItemProps {
slideOutline: string,
slideOutline: {
content: string,
},
index: number
isStreaming: boolean
}
@ -38,7 +40,7 @@ export function OutlineItem({
}
}, [outlines.length]);
const handleSlideChange = (newOutline: string) => {
const handleSlideChange = (newOutline:any) => {
if (isStreaming) return;
const newData = outlines?.map((each, idx) => {
if (idx === index - 1) {
@ -100,10 +102,10 @@ export function OutlineItem({
{isStreaming ? <p
className="text-sm flex-1 font-normal"
>
{slideOutline || ''}
{slideOutline.content || ''}
</p> : <MarkdownEditor
key={index}
content={slideOutline || ''}
content={slideOutline.content || ''}
onChange={(content) => handleSlideChange(content)}
/>}

View file

@ -3,7 +3,7 @@ import { useDispatch } from "react-redux";
import { arrayMove } from "@dnd-kit/sortable";
import { setOutlines } from "@/store/slices/presentationGeneration";
export const useOutlineManagement = (outlines: string[] | null) => {
export const useOutlineManagement = (outlines: { content: string }[] | null) => {
const dispatch = useDispatch();
const handleDragEnd = useCallback((event: any) => {
@ -12,8 +12,8 @@ export const useOutlineManagement = (outlines: string[] | null) => {
if (!active || !over || !outlines) return;
if (active.id !== over.id) {
const oldIndex = outlines.findIndex((item) => item === active.id);
const newIndex = outlines.findIndex((item) => item === over.id);
const oldIndex = outlines.findIndex((item) => item.content === active.id);
const newIndex = outlines.findIndex((item) => item.content === over.id);
const reorderedArray = arrayMove(outlines, oldIndex, newIndex);
dispatch(setOutlines(reorderedArray));
}
@ -22,7 +22,7 @@ export const useOutlineManagement = (outlines: string[] | null) => {
const handleAddSlide = useCallback(() => {
if (!outlines) return;
const updatedOutlines = [...outlines, "Outline title"];
const updatedOutlines = [...outlines, { content: "Outline title" }];
dispatch(setOutlines(updatedOutlines));
}, [outlines, dispatch]);

View file

@ -31,10 +31,13 @@ export const useOutlineStreaming = (presentationId: string | null) => {
const data = JSON.parse(event.data);
switch (data.type) {
case "chunk":
// console.log('data', data)
accumulatedChunks += data.chunk;
// console.log('accumulatedChunks', accumulatedChunks)
try {
const repairedJson = jsonrepair(accumulatedChunks);
const partialData = JSON.parse(repairedJson);
console.log('partialData', partialData)
if (partialData.slides) {
dispatch(setOutlines(partialData.slides));
setIsLoading(false)
@ -45,8 +48,9 @@ export const useOutlineStreaming = (presentationId: string | null) => {
break;
case "complete":
console.log('complete', data)
try {
const outlinesData: string[] = data.presentation.outlines.slides;
const outlinesData: { content: string }[] = data.presentation.outlines.slides;
dispatch(setOutlines(outlinesData));
setIsStreaming(false)
setIsLoading(false)
@ -60,11 +64,13 @@ export const useOutlineStreaming = (presentationId: string | null) => {
break;
case "closing":
console.log('closing', data)
setIsStreaming(false)
setIsLoading(false)
eventSource.close();
break;
case "error":
console.log('error', data)
setIsStreaming(false)
setIsLoading(false)
eventSource.close();
@ -78,18 +84,17 @@ export const useOutlineStreaming = (presentationId: string | null) => {
});
eventSource.onerror = () => {
console.log('onerror')
setIsStreaming(false)
setIsLoading(false)
eventSource.close();
toast.error("Failed to connect to the server. Please try again.");
};
} catch (error) {
console.log('error', error)
setIsStreaming(false)
setIsLoading(false)
toast.error("Failed to initialize connection");
} finally {
setIsStreaming(false)
setIsLoading(false)
}
};
initializeStream();

View file

@ -15,7 +15,7 @@ const DEFAULT_LOADING_STATE: LoadingState = {
export const usePresentationGeneration = (
presentationId: string | null,
outlines: string[] | null,
outlines: { content: string }[] | null,
selectedLayoutGroup: LayoutGroup | null,
setActiveTab: (tab: string) => void
) => {

View file

@ -131,6 +131,7 @@ const UploadPage = () => {
config,
files: responses,
}));
dispatch(clearOutlines())
router.push("/documents-preview");
};
@ -154,6 +155,7 @@ const UploadPage = () => {
});
dispatch(setPresentationId(createResponse.id));
dispatch(clearOutlines())
router.push("/outline");
};

View file

@ -18,7 +18,7 @@ interface PresentationGenerationState {
presentation_id: string | null;
isLoading: boolean;
isStreaming: boolean | null;
outlines: string[];
outlines: { content: string }[];
error: string | null;
presentationData: PresentationData | null;
isSlidesRendered: boolean;
@ -72,7 +72,7 @@ const presentationGenerationSlice = createSlice({
state.outlines = [];
},
// Set outlines
setOutlines: (state, action: PayloadAction<string[]>) => {
setOutlines: (state, action: PayloadAction<{ content: string }[]>) => {
state.outlines = action.payload;
},
// Set presentation data