返回 presentation-ai
Compare.tsx
根目录 / src / components / presentation / agent / Compare.tsx
1 import { useEffect, useRef, useState } from "react";
2
3 import StaticPresentationEditor from "@/components/notebook/presentation/editor/presentation-editor-static";
4 import { type PlateSlide } from "@/components/notebook/presentation/utils/parser";
5 import { usePresentationState } from "@/states/presentation-state";
6 import { SlideThumbnail } from "../sidebar/SlideThumbnail";
7
8 export default function Compare({
9 left,
10 right,
11 shouldReplaceTheSlides = false,
12 }: {
13 left: PlateSlide[];
14 right: PlateSlide[];
15 shouldReplaceTheSlides?: boolean;
16 }) {
17 const [isScrolling, setIsScrolling] = useState(false);
18 const scrollStopTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
19
20 useEffect(() => {
21 return () => {
22 if (scrollStopTimerRef.current) {
23 clearTimeout(scrollStopTimerRef.current);
24 }
25 };
26 }, []);
27
28 const handleScroll: React.UIEventHandler<HTMLDivElement> = () => {
29 if (!isScrolling) setIsScrolling(true);
30 if (scrollStopTimerRef.current) clearTimeout(scrollStopTimerRef.current);
31 scrollStopTimerRef.current = setTimeout(() => {
32 setIsScrolling(false);
33 }, 150);
34 };
35
36 return (
37 <div
38 className="scrollbar-thumb-rounded-full relative scrollbar-thin h-full max-h-55 w-full max-w-95 overflow-x-clip overflow-y-auto p-2 scrollbar-thumb-muted-foreground scrollbar-track-transparent"
39 onScroll={handleScroll}
40 >
41 <div
42 className={`pointer-events-none absolute inset-0 z-10 bg-linear-to-b from-transparent to-background transition-opacity duration-150 ${isScrolling ? "opacity-0" : "opacity-100"}`}
43 />
44
45 <div className="flex h-max gap-2">
46 <button
47 type="button"
48 className="group w-1/2 cursor-pointer"
49 onClick={() => {
50 const { slides, setSlides } = usePresentationState.getState();
51 if (shouldReplaceTheSlides) {
52 setSlides(left);
53 return;
54 }
55 const updatedSlides = slides.map((slide) => {
56 const leftSlide = left.find((s) => s.id === slide.id);
57 if (leftSlide) {
58 console.log("leftSlide", leftSlide);
59 return leftSlide;
60 }
61 return slide;
62 });
63 setSlides(updatedSlides);
64 }}
65 >
66 <h3 className="text-lg font-bold">Original</h3>
67
68 <div className="pointer-events-none shrink space-y-2 rounded-md group-hover:outline group-hover:outline-primary">
69 {left.map((slide, index) => (
70 <SlideThumbnail
71 key={slide.id}
72 index={index}
73 isActive={false}
74 onClick={() => {}}
75 >
76 <StaticPresentationEditor
77 initialContent={slide}
78 className="min-h-75 border"
79 id={`preview-${slide.id}`}
80 />
81 </SlideThumbnail>
82 ))}
83 </div>
84 </button>
85 <button
86 type="button"
87 className="group w-1/2 cursor-pointer"
88 onClick={() => {
89 const { slides, setSlides } = usePresentationState.getState();
90 if (shouldReplaceTheSlides) {
91 setSlides(right);
92 return;
93 }
94 const updatedSlides = slides.map((slide) => {
95 const rightSlide = right.find((s) => s.id === slide.id);
96 if (rightSlide) {
97 return rightSlide;
98 }
99 return slide;
100 });
101 setSlides(updatedSlides);
102 }}
103 >
104 <h3 className="text-lg font-bold">Modified</h3>
105 <div className="shrink space-y-2 rounded-md group-hover:outline group-hover:outline-primary">
106 {right.map((slide, index) => (
107 <SlideThumbnail
108 key={slide.id}
109 index={index}
110 isActive={false}
111 onClick={() => {}}
112 >
113 <StaticPresentationEditor
114 initialContent={slide}
115 className="min-h-75 border"
116 id={`preview-${slide.id}`}
117 />
118 </SlideThumbnail>
119 ))}
120 </div>
121 </button>
122 </div>
123 </div>
124 );
125 }
126
126 lines Plain Text