enzostvs HF Staff commited on
Commit
dbf8f03
·
1 Parent(s): 08f3d9b

Support json file

Browse files
app/api/me/projects/[namespace]/[repoId]/route.ts CHANGED
@@ -108,7 +108,7 @@ export async function GET(
108
  const allowedFilesExtensions = ["jpg", "jpeg", "png", "gif", "svg", "webp", "avif", "heic", "heif", "ico", "bmp", "tiff", "tif", "mp4", "webm", "ogg", "avi", "mov", "mp3", "wav", "ogg", "aac", "m4a"];
109
 
110
  for await (const fileInfo of listFiles({repo, accessToken: user.token as string})) {
111
- if (fileInfo.path.endsWith(".html") || fileInfo.path.endsWith(".css") || fileInfo.path.endsWith(".js")) {
112
  const blob = await downloadFile({ repo, accessToken: user.token as string, path: fileInfo.path, raw: true });
113
  const html = await blob?.text();
114
  if (!html) {
 
108
  const allowedFilesExtensions = ["jpg", "jpeg", "png", "gif", "svg", "webp", "avif", "heic", "heif", "ico", "bmp", "tiff", "tif", "mp4", "webm", "ogg", "avi", "mov", "mp3", "wav", "ogg", "aac", "m4a"];
109
 
110
  for await (const fileInfo of listFiles({repo, accessToken: user.token as string})) {
111
+ if (fileInfo.path.endsWith(".html") || fileInfo.path.endsWith(".css") || fileInfo.path.endsWith(".js") || fileInfo.path.endsWith(".json")) {
112
  const blob = await downloadFile({ repo, accessToken: user.token as string, path: fileInfo.path, raw: true });
113
  const html = await blob?.text();
114
  if (!html) {
app/layout.tsx CHANGED
@@ -114,7 +114,7 @@ export default async function RootLayout({
114
  data-domain="deepsite.hf.co"
115
  src="https://plausible.io/js/script.js"
116
  />
117
- <DomainRedirect />
118
  <IframeDetector />
119
  <Toaster richColors position="bottom-center" />
120
  <TanstackContext>
 
114
  data-domain="deepsite.hf.co"
115
  src="https://plausible.io/js/script.js"
116
  />
117
+ {/* <DomainRedirect /> */}
118
  <IframeDetector />
119
  <Toaster richColors position="bottom-center" />
120
  <TanstackContext>
components/editor/ask-ai/context.tsx CHANGED
@@ -23,6 +23,8 @@ export const Context = () => {
23
  return <Braces className={size} />;
24
  } else if (filePath.endsWith(".js")) {
25
  return <FileCode className={size} />;
 
 
26
  } else {
27
  return <FileText className={size} />;
28
  }
@@ -52,6 +54,8 @@ export const Context = () => {
52
  selectedFile && selectedFile.endsWith(".html"),
53
  "!bg-amber-500/10 !border-amber-500/30 !text-amber-400":
54
  selectedFile && selectedFile.endsWith(".js"),
 
 
55
  })}
56
  disabled={
57
  globalAiLoading || globalEditorLoading || pages.length === 0
 
23
  return <Braces className={size} />;
24
  } else if (filePath.endsWith(".js")) {
25
  return <FileCode className={size} />;
26
+ } else if (filePath.endsWith(".json")) {
27
+ return <Braces className={size} />;
28
  } else {
29
  return <FileText className={size} />;
30
  }
 
54
  selectedFile && selectedFile.endsWith(".html"),
55
  "!bg-amber-500/10 !border-amber-500/30 !text-amber-400":
56
  selectedFile && selectedFile.endsWith(".js"),
57
+ "!bg-yellow-500/10 !border-yellow-500/30 !text-yellow-400":
58
+ selectedFile && selectedFile.endsWith(".json"),
59
  })}
60
  disabled={
61
  globalAiLoading || globalEditorLoading || pages.length === 0
components/editor/file-browser/index.tsx CHANGED
@@ -7,6 +7,7 @@ import {
7
  Folder,
8
  ChevronRight,
9
  ChevronDown,
 
10
  } from "lucide-react";
11
  import classNames from "classnames";
12
 
@@ -197,27 +198,7 @@ export function FileBrowser() {
197
  </svg>
198
  );
199
  case "json":
200
- return (
201
- <svg className="size-4 shrink-0" viewBox="0 0 32 32" fill="none">
202
- <rect width="32" height="32" rx="2" fill="#F7DF1E" />
203
- <path
204
- d="M16 2L4 8v16l12 6 12-6V8L16 2zm8.8 20.4l-8.8 4.4-8.8-4.4V9.6l8.8-4.4 8.8 4.4v12.8z"
205
- fill="#000"
206
- opacity="0.15"
207
- />
208
- <text
209
- x="50%"
210
- y="50%"
211
- dominantBaseline="middle"
212
- textAnchor="middle"
213
- fill="#000"
214
- fontSize="14"
215
- fontWeight="600"
216
- >
217
- {}
218
- </text>
219
- </svg>
220
- );
221
  default:
222
  return <FileCode2 className="size-4 shrink-0 text-neutral-400" />;
223
  }
@@ -249,7 +230,7 @@ export function FileBrowser() {
249
  case "json":
250
  return {
251
  name: "JSON",
252
- color: "bg-yellow-500/20 border-yellow-500/30 text-yellow-400",
253
  };
254
  default:
255
  return {
@@ -458,6 +439,13 @@ export function FileBrowser() {
458
  JS: {pages.filter((p) => p.path.endsWith(".js")).length}
459
  </span>
460
  </div>
 
 
 
 
 
 
 
461
  </div>
462
  </div>
463
  </SheetContent>
 
7
  Folder,
8
  ChevronRight,
9
  ChevronDown,
10
+ FileJson,
11
  } from "lucide-react";
12
  import classNames from "classnames";
13
 
 
198
  </svg>
199
  );
200
  case "json":
201
+ return <FileJson className="size-4 shrink-0 text-amber-400" />;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  default:
203
  return <FileCode2 className="size-4 shrink-0 text-neutral-400" />;
204
  }
 
230
  case "json":
231
  return {
232
  name: "JSON",
233
+ color: "bg-amber-500/20 border-amber-500/30 text-amber-400",
234
  };
235
  default:
236
  return {
 
439
  JS: {pages.filter((p) => p.path.endsWith(".js")).length}
440
  </span>
441
  </div>
442
+ <div className="flex items-center gap-2 text-neutral-500">
443
+ <div className="size-2 rounded-full bg-yellow-600" />
444
+ <span>
445
+ JSON:{" "}
446
+ {pages.filter((p) => p.path.endsWith(".json")).length}
447
+ </span>
448
+ </div>
449
  </div>
450
  </div>
451
  </SheetContent>
components/editor/index.tsx CHANGED
@@ -68,6 +68,7 @@ export const AppEditor = ({
68
  const path = currentPageData.path;
69
  if (path.endsWith(".css")) return "css";
70
  if (path.endsWith(".js")) return "javascript";
 
71
  return "html";
72
  }, [currentPageData.path]);
73
 
@@ -76,6 +77,7 @@ export const AppEditor = ({
76
  if (editorLanguage === "css") return "CSS copied to clipboard!";
77
  if (editorLanguage === "javascript")
78
  return "JavaScript copied to clipboard!";
 
79
  return "HTML copied to clipboard!";
80
  }, [editorLanguage]);
81
 
 
68
  const path = currentPageData.path;
69
  if (path.endsWith(".css")) return "css";
70
  if (path.endsWith(".js")) return "javascript";
71
+ if (path.endsWith(".json")) return "json";
72
  return "html";
73
  }, [currentPageData.path]);
74
 
 
77
  if (editorLanguage === "css") return "CSS copied to clipboard!";
78
  if (editorLanguage === "javascript")
79
  return "JavaScript copied to clipboard!";
80
+ if (editorLanguage === "json") return "JSON copied to clipboard!";
81
  return "HTML copied to clipboard!";
82
  }, [editorLanguage]);
83
 
components/editor/preview/index.tsx CHANGED
@@ -78,6 +78,9 @@ export const Preview = ({ isNew }: { isNew: boolean }) => {
78
  const jsFiles = pages.filter(
79
  (p) => p.path.endsWith(".js") && p.path !== previewPageData?.path
80
  );
 
 
 
81
 
82
  let modifiedHtml = html;
83
 
@@ -147,6 +150,42 @@ export const Preview = ({ isNew }: { isNew: boolean }) => {
147
  });
148
  }
149
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  return modifiedHtml;
151
  },
152
  [pages, previewPageData?.path]
 
78
  const jsFiles = pages.filter(
79
  (p) => p.path.endsWith(".js") && p.path !== previewPageData?.path
80
  );
81
+ const jsonFiles = pages.filter(
82
+ (p) => p.path.endsWith(".json") && p.path !== previewPageData?.path
83
+ );
84
 
85
  let modifiedHtml = html;
86
 
 
150
  });
151
  }
152
 
153
+ // Inject all JSON files as script tags with type="application/json"
154
+ if (jsonFiles.length > 0) {
155
+ const allJsonContent = jsonFiles
156
+ .map(
157
+ (file) =>
158
+ `<script type="application/json" data-injected-from="${
159
+ file.path
160
+ }" id="${file.path.replace(/[^a-zA-Z0-9]/g, "-")}">\n${
161
+ file.html
162
+ }\n</script>`
163
+ )
164
+ .join("\n");
165
+
166
+ if (modifiedHtml.includes("</body>")) {
167
+ modifiedHtml = modifiedHtml.replace(
168
+ "</body>",
169
+ `${allJsonContent}\n</body>`
170
+ );
171
+ } else if (modifiedHtml.includes("<body>")) {
172
+ modifiedHtml = modifiedHtml + allJsonContent;
173
+ } else {
174
+ modifiedHtml = modifiedHtml + "\n" + allJsonContent;
175
+ }
176
+
177
+ jsonFiles.forEach((file) => {
178
+ const escapedPath = file.path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
179
+ modifiedHtml = modifiedHtml.replace(
180
+ new RegExp(
181
+ `<script\\s+[^>]*src=["'][\\.\/]*${escapedPath}["'][^>]*><\\/script>`,
182
+ "gi"
183
+ ),
184
+ ""
185
+ );
186
+ });
187
+ }
188
+
189
  return modifiedHtml;
190
  },
191
  [pages, previewPageData?.path]
lib/prompts.ts CHANGED
@@ -20,7 +20,7 @@ You create website in a way a designer would, using ONLY HTML, CSS and Javascrip
20
  Try to create the best UI possible. Important: Make the website responsive by using TailwindCSS. Use it as much as you can, if you can't use it, use custom css (make sure to import tailwind with <script src="https://cdn.tailwindcss.com"></script> in the head).
21
  Also try to elaborate as much as you can, to create something unique, with a great design.
22
  If you want to use ICONS import Feather Icons (Make sure to add <script src="https://unpkg.com/feather-icons"></script> and <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> in the head., and <script>feather.replace();</script> in the body. Ex : <i data-feather="user"></i>).
23
- For interactive animations you can use: Vanta.js (Make sure to add <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script> and <script>VANTA.GLOBE({...</script> in the body.).
24
  Don't hesitate to use real public API for the datas, you can find good ones here https://github.com/public-apis/public-apis depending on what the user asks for.
25
  You can create multiple pages website at once (following the format rules below) or a Single Page Application. But make sure to create multiple pages if the user asks for different pages.
26
  IMPORTANT: To avoid duplicate code across pages, you MUST create separate style.css and script.js files for shared CSS and JavaScript code. Each HTML file should link to these files using <link rel="stylesheet" href="style.css"> and <script src="script.js"></script>.
 
20
  Try to create the best UI possible. Important: Make the website responsive by using TailwindCSS. Use it as much as you can, if you can't use it, use custom css (make sure to import tailwind with <script src="https://cdn.tailwindcss.com"></script> in the head).
21
  Also try to elaborate as much as you can, to create something unique, with a great design.
22
  If you want to use ICONS import Feather Icons (Make sure to add <script src="https://unpkg.com/feather-icons"></script> and <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> in the head., and <script>feather.replace();</script> in the body. Ex : <i data-feather="user"></i>).
23
+ For interactive animations you can use: Vanta.js (Make sure to add <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script> and <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> and <script>VANTA.GLOBE({...</script> in the body.).
24
  Don't hesitate to use real public API for the datas, you can find good ones here https://github.com/public-apis/public-apis depending on what the user asks for.
25
  You can create multiple pages website at once (following the format rules below) or a Single Page Application. But make sure to create multiple pages if the user asks for different pages.
26
  IMPORTANT: To avoid duplicate code across pages, you MUST create separate style.css and script.js files for shared CSS and JavaScript code. Each HTML file should link to these files using <link rel="stylesheet" href="style.css"> and <script src="script.js"></script>.