viktor commited on
Commit
aa299ea
·
unverified ·
2 Parent(s): cf807cc e04e5ed

Merge pull request #3 from novitalabs/feat/interaction-optimization

Browse files
src/components/preview.tsx CHANGED
@@ -3,7 +3,7 @@
3
  import { useState, forwardRef, useImperativeHandle, useEffect, useRef } from "react"
4
  import { DEFAULT_HTML } from "@/lib/constants"
5
  import { PreviewRef, Version } from "@/lib/types"
6
- import { MinimizeIcon, MaximizeIcon, DownloadIcon } from "./ui/fullscreen-icons"
7
  import { useModel } from "@/lib/contexts/model-context"
8
  import { Loader2 } from "lucide-react"
9
  import { cn } from "@/lib/utils"
@@ -27,6 +27,7 @@ export const Preview = forwardRef<PreviewRef, PreviewProps>(function Preview(
27
  const [isPartialGenerating, setIsPartialGenerating] = useState(false);
28
  const [error, setError] = useState<string | null>(null);
29
  const [showAuthError, setShowAuthError] = useState(false);
 
30
  const { selectedModelId } = useModel();
31
  const renderCount = useRef(0);
32
  const headUpdated = useRef(false);
@@ -103,6 +104,11 @@ export const Preview = forwardRef<PreviewRef, PreviewProps>(function Preview(
103
  document.body.removeChild(a);
104
  };
105
 
 
 
 
 
 
106
  const generateCode = async (prompt: string, colors: string[] = [], previousPrompt?: string) => {
107
  setLoading(true);
108
  renderCount.current = 0;
@@ -265,6 +271,14 @@ export const Preview = forwardRef<PreviewRef, PreviewProps>(function Preview(
265
  )}
266
  <div className="bg-white text-black h-full overflow-hidden relative isolation-auto">
267
  <div className="absolute top-3 right-3 flex gap-2 z-[100]">
 
 
 
 
 
 
 
 
268
  <button
269
  onClick={downloadHtml}
270
  className="bg-novita-gray/90 text-white p-2 rounded-md shadow-md hover:bg-novita-gray/70 transition-colors flex items-center justify-center"
@@ -283,6 +297,7 @@ export const Preview = forwardRef<PreviewRef, PreviewProps>(function Preview(
283
  </button>
284
  </div>
285
  <iframe
 
286
  className={cn("relative z-10 w-full h-full select-none", {
287
  "pointer-events-none": loading,
288
  })}
 
3
  import { useState, forwardRef, useImperativeHandle, useEffect, useRef } from "react"
4
  import { DEFAULT_HTML } from "@/lib/constants"
5
  import { PreviewRef, Version } from "@/lib/types"
6
+ import { MinimizeIcon, MaximizeIcon, DownloadIcon, RefreshIcon } from "./ui/icons"
7
  import { useModel } from "@/lib/contexts/model-context"
8
  import { Loader2 } from "lucide-react"
9
  import { cn } from "@/lib/utils"
 
27
  const [isPartialGenerating, setIsPartialGenerating] = useState(false);
28
  const [error, setError] = useState<string | null>(null);
29
  const [showAuthError, setShowAuthError] = useState(false);
30
+ const [refreshKey, setRefreshKey] = useState(0);
31
  const { selectedModelId } = useModel();
32
  const renderCount = useRef(0);
33
  const headUpdated = useRef(false);
 
104
  document.body.removeChild(a);
105
  };
106
 
107
+ const refreshPreview = () => {
108
+ if (!html) return;
109
+ setRefreshKey(prev => prev + 1);
110
+ };
111
+
112
  const generateCode = async (prompt: string, colors: string[] = [], previousPrompt?: string) => {
113
  setLoading(true);
114
  renderCount.current = 0;
 
271
  )}
272
  <div className="bg-white text-black h-full overflow-hidden relative isolation-auto">
273
  <div className="absolute top-3 right-3 flex gap-2 z-[100]">
274
+ <button
275
+ onClick={refreshPreview}
276
+ className="bg-novita-gray/90 text-white p-2 rounded-md shadow-md hover:bg-novita-gray/70 transition-colors flex items-center justify-center"
277
+ aria-label="Refresh Preview"
278
+ title="Refresh Preview"
279
+ >
280
+ <RefreshIcon />
281
+ </button>
282
  <button
283
  onClick={downloadHtml}
284
  className="bg-novita-gray/90 text-white p-2 rounded-md shadow-md hover:bg-novita-gray/70 transition-colors flex items-center justify-center"
 
297
  </button>
298
  </div>
299
  <iframe
300
+ key={refreshKey}
301
  className={cn("relative z-10 w-full h-full select-none", {
302
  "pointer-events-none": loading,
303
  })}
src/components/ui/{fullscreen-icons.tsx → icons.tsx} RENAMED
@@ -28,4 +28,15 @@ export function DownloadIcon() {
28
  <line x1="12" y1="15" x2="12" y2="3"></line>
29
  </svg>
30
  )
 
 
 
 
 
 
 
 
 
 
 
31
  }
 
28
  <line x1="12" y1="15" x2="12" y2="3"></line>
29
  </svg>
30
  )
31
+ }
32
+
33
+ export function RefreshIcon() {
34
+ return (
35
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
36
+ <path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path>
37
+ <path d="M21 3v5h-5"></path>
38
+ <path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path>
39
+ <path d="M3 21v-5h5"></path>
40
+ </svg>
41
+ )
42
  }