fix(Nextjs): Outline streaming issue solved
This commit is contained in:
parent
f6550b92a2
commit
1d4898cbce
7 changed files with 38 additions and 18 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
/>}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
) => {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue