@tscircuit/fake-snippets 0.0.108 → 0.0.109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bun.lock +62 -19
- package/dist/bundle.js +3 -2
- package/dist/index.d.ts +5 -0
- package/dist/index.js +2 -1
- package/dist/schema.d.ts +8 -0
- package/dist/schema.js +2 -1
- package/fake-snippets-api/lib/db/schema.ts +1 -0
- package/package.json +7 -8
- package/src/App.tsx +0 -2
- package/src/components/DownloadButtonAndMenu.tsx +133 -35
- package/src/components/FileSidebar.tsx +31 -34
- package/src/components/Footer.tsx +0 -1
- package/src/components/HeaderLogin.tsx +1 -1
- package/src/components/HiddenFilesDropdown.tsx +0 -2
- package/src/components/PackageBuildsPage/PackageBuildDetailsPage.tsx +0 -2
- package/src/components/PackageBuildsPage/build-preview-content.tsx +34 -5
- package/src/components/PackageCard.tsx +0 -1
- package/src/components/ViewPackagePage/components/ShikiCodeViewer.tsx +20 -11
- package/src/components/ViewPackagePage/components/important-files-view.tsx +75 -59
- package/src/components/ViewPackagePage/components/main-content-header.tsx +4 -4
- package/src/components/ViewPackagePage/components/main-content-view-selector.tsx +0 -1
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +0 -1
- package/src/components/ViewPackagePage/components/package-header.tsx +14 -17
- package/src/components/ViewPackagePage/components/preview-image-squares.tsx +0 -1
- package/src/components/ViewPackagePage/components/repo-page-content.tsx +21 -20
- package/src/components/ViewPackagePage/components/sidebar.tsx +0 -2
- package/src/components/ViewPackagePage/components/tab-views/files-view.tsx +18 -17
- package/src/components/ViewPackagePage/components/theme-toggle.tsx +0 -2
- package/src/components/ViewPackagePage/hooks/use-toast.tsx +0 -1
- package/src/components/package-port/CodeAndPreview.tsx +23 -40
- package/src/components/package-port/CodeEditor.tsx +24 -1
- package/src/components/package-port/CodeEditorHeader.tsx +5 -2
- package/src/components/preview/PackageReleasesDashboard.tsx +30 -25
- package/src/hooks/use-current-package-id.ts +5 -30
- package/src/hooks/use-current-package-info.ts +29 -5
- package/src/hooks/use-global-store.ts +1 -1
- package/src/hooks/useFileManagement.ts +153 -34
- package/src/hooks/useOptimizedPackageFilesLoader.ts +149 -0
- package/src/hooks/useUpdatePackageFilesMutation.ts +2 -0
- package/src/lib/download-fns/download-circuit-png.ts +11 -3
- package/src/lib/download-fns/download-gltf-from-circuit-json.ts +44 -0
- package/src/lib/utils/isComponentExported.ts +9 -0
- package/src/pages/authorize.tsx +0 -2
- package/src/pages/landing.tsx +0 -1
- package/src/pages/preview-release.tsx +14 -4
- package/src/pages/view-package.tsx +14 -13
- package/src/components/Footer2.tsx +0 -100
- package/src/components/ShippingInformationForm.tsx +0 -423
- package/src/components/StaticViewSnippetHeader.tsx +0 -70
- package/src/components/ViewPackagePage/components/file-explorer.tsx +0 -67
- package/src/components/ViewPackagePage/components/readme-view.tsx +0 -58
- package/src/components/ViewPackagePage/components/repo-header-button.tsx +0 -36
- package/src/components/ViewPackagePage/components/repo-header.tsx +0 -4
- package/src/components/ViewPackagePage/components/sidebar-contributors-section.tsx +0 -31
- package/src/components/ViewSnippetHeader.tsx +0 -181
- package/src/components/ui/input-otp.tsx +0 -69
- package/src/pages/settings.tsx +0 -25
package/dist/index.d.ts
CHANGED
|
@@ -667,6 +667,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
667
667
|
latest_package_release_fs_sha: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
668
668
|
default_view: z.ZodOptional<z.ZodDefault<z.ZodEnum<["files", "3d", "pcb", "schematic"]>>>;
|
|
669
669
|
allow_pr_previews: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
670
|
+
is_starred: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
670
671
|
}, "strip", z.ZodTypeAny, {
|
|
671
672
|
name: string;
|
|
672
673
|
unscoped_name: string;
|
|
@@ -695,6 +696,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
695
696
|
website: string | null;
|
|
696
697
|
ai_usage_instructions: string | null;
|
|
697
698
|
latest_package_release_fs_sha: string | null;
|
|
699
|
+
is_starred?: boolean | undefined;
|
|
698
700
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
699
701
|
latest_license?: string | null | undefined;
|
|
700
702
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
@@ -715,6 +717,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
715
717
|
latest_package_release_id: string | null;
|
|
716
718
|
latest_version: string | null;
|
|
717
719
|
ai_usage_instructions: string | null;
|
|
720
|
+
is_starred?: boolean | undefined;
|
|
718
721
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
719
722
|
star_count?: number | undefined;
|
|
720
723
|
is_private?: boolean | null | undefined;
|
|
@@ -1036,6 +1039,7 @@ declare const createDatabase: ({ seed }?: {
|
|
|
1036
1039
|
website: string | null;
|
|
1037
1040
|
ai_usage_instructions: string | null;
|
|
1038
1041
|
latest_package_release_fs_sha: string | null;
|
|
1042
|
+
is_starred?: boolean | undefined;
|
|
1039
1043
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
1040
1044
|
latest_license?: string | null | undefined;
|
|
1041
1045
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
@@ -1441,6 +1445,7 @@ declare const createDatabase: ({ seed }?: {
|
|
|
1441
1445
|
website: string | null;
|
|
1442
1446
|
ai_usage_instructions: string | null;
|
|
1443
1447
|
latest_package_release_fs_sha: string | null;
|
|
1448
|
+
is_starred?: boolean | undefined;
|
|
1444
1449
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
1445
1450
|
latest_license?: string | null | undefined;
|
|
1446
1451
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
package/dist/index.js
CHANGED
|
@@ -260,7 +260,8 @@ var packageSchema = z.object({
|
|
|
260
260
|
ai_usage_instructions: z.string().nullable(),
|
|
261
261
|
latest_package_release_fs_sha: z.string().nullable().default(null),
|
|
262
262
|
default_view: z.enum(["files", "3d", "pcb", "schematic"]).default("files").optional(),
|
|
263
|
-
allow_pr_previews: z.boolean().default(false).optional()
|
|
263
|
+
allow_pr_previews: z.boolean().default(false).optional(),
|
|
264
|
+
is_starred: z.boolean().default(false).optional()
|
|
264
265
|
});
|
|
265
266
|
var jlcpcbOrderStateSchema = z.object({
|
|
266
267
|
jlcpcb_order_state_id: z.string(),
|
package/dist/schema.d.ts
CHANGED
|
@@ -840,6 +840,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
840
840
|
latest_package_release_fs_sha: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
841
841
|
default_view: z.ZodOptional<z.ZodDefault<z.ZodEnum<["files", "3d", "pcb", "schematic"]>>>;
|
|
842
842
|
allow_pr_previews: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
843
|
+
is_starred: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
843
844
|
}, "strip", z.ZodTypeAny, {
|
|
844
845
|
name: string;
|
|
845
846
|
unscoped_name: string;
|
|
@@ -868,6 +869,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
868
869
|
website: string | null;
|
|
869
870
|
ai_usage_instructions: string | null;
|
|
870
871
|
latest_package_release_fs_sha: string | null;
|
|
872
|
+
is_starred?: boolean | undefined;
|
|
871
873
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
872
874
|
latest_license?: string | null | undefined;
|
|
873
875
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
@@ -888,6 +890,7 @@ declare const packageSchema: z.ZodObject<{
|
|
|
888
890
|
latest_package_release_id: string | null;
|
|
889
891
|
latest_version: string | null;
|
|
890
892
|
ai_usage_instructions: string | null;
|
|
893
|
+
is_starred?: boolean | undefined;
|
|
891
894
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
892
895
|
star_count?: number | undefined;
|
|
893
896
|
is_private?: boolean | null | undefined;
|
|
@@ -1430,6 +1433,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1430
1433
|
latest_package_release_fs_sha: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
1431
1434
|
default_view: z.ZodOptional<z.ZodDefault<z.ZodEnum<["files", "3d", "pcb", "schematic"]>>>;
|
|
1432
1435
|
allow_pr_previews: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
1436
|
+
is_starred: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
1433
1437
|
}, "strip", z.ZodTypeAny, {
|
|
1434
1438
|
name: string;
|
|
1435
1439
|
unscoped_name: string;
|
|
@@ -1458,6 +1462,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1458
1462
|
website: string | null;
|
|
1459
1463
|
ai_usage_instructions: string | null;
|
|
1460
1464
|
latest_package_release_fs_sha: string | null;
|
|
1465
|
+
is_starred?: boolean | undefined;
|
|
1461
1466
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
1462
1467
|
latest_license?: string | null | undefined;
|
|
1463
1468
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
@@ -1478,6 +1483,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
1478
1483
|
latest_package_release_id: string | null;
|
|
1479
1484
|
latest_version: string | null;
|
|
1480
1485
|
ai_usage_instructions: string | null;
|
|
1486
|
+
is_starred?: boolean | undefined;
|
|
1481
1487
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
1482
1488
|
star_count?: number | undefined;
|
|
1483
1489
|
is_private?: boolean | null | undefined;
|
|
@@ -2138,6 +2144,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
2138
2144
|
website: string | null;
|
|
2139
2145
|
ai_usage_instructions: string | null;
|
|
2140
2146
|
latest_package_release_fs_sha: string | null;
|
|
2147
|
+
is_starred?: boolean | undefined;
|
|
2141
2148
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
2142
2149
|
latest_license?: string | null | undefined;
|
|
2143
2150
|
default_view?: "files" | "3d" | "pcb" | "schematic" | undefined;
|
|
@@ -2428,6 +2435,7 @@ declare const databaseSchema: z.ZodObject<{
|
|
|
2428
2435
|
latest_package_release_id: string | null;
|
|
2429
2436
|
latest_version: string | null;
|
|
2430
2437
|
ai_usage_instructions: string | null;
|
|
2438
|
+
is_starred?: boolean | undefined;
|
|
2431
2439
|
snippet_type?: "board" | "package" | "model" | "footprint" | undefined;
|
|
2432
2440
|
star_count?: number | undefined;
|
|
2433
2441
|
is_private?: boolean | null | undefined;
|
package/dist/schema.js
CHANGED
|
@@ -255,7 +255,8 @@ var packageSchema = z.object({
|
|
|
255
255
|
ai_usage_instructions: z.string().nullable(),
|
|
256
256
|
latest_package_release_fs_sha: z.string().nullable().default(null),
|
|
257
257
|
default_view: z.enum(["files", "3d", "pcb", "schematic"]).default("files").optional(),
|
|
258
|
-
allow_pr_previews: z.boolean().default(false).optional()
|
|
258
|
+
allow_pr_previews: z.boolean().default(false).optional(),
|
|
259
|
+
is_starred: z.boolean().default(false).optional()
|
|
259
260
|
});
|
|
260
261
|
var jlcpcbOrderStateSchema = z.object({
|
|
261
262
|
jlcpcb_order_state_id: z.string(),
|
|
@@ -311,6 +311,7 @@ export const packageSchema = z.object({
|
|
|
311
311
|
.default("files")
|
|
312
312
|
.optional(),
|
|
313
313
|
allow_pr_previews: z.boolean().default(false).optional(),
|
|
314
|
+
is_starred: z.boolean().default(false).optional(),
|
|
314
315
|
})
|
|
315
316
|
export type Package = z.infer<typeof packageSchema>
|
|
316
317
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/fake-snippets",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.109",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
"@radix-ui/react-toggle": "^1.1.0",
|
|
76
76
|
"@radix-ui/react-toggle-group": "^1.1.0",
|
|
77
77
|
"@radix-ui/react-tooltip": "^1.1.2",
|
|
78
|
+
"@resvg/resvg-wasm": "^2.6.2",
|
|
78
79
|
"@tailwindcss/typography": "^0.5.16",
|
|
79
80
|
"@tscircuit/3d-viewer": "^0.0.303",
|
|
80
81
|
"@tscircuit/assembly-viewer": "^0.0.1",
|
|
@@ -84,8 +85,9 @@
|
|
|
84
85
|
"@tscircuit/mm": "^0.0.8",
|
|
85
86
|
"@tscircuit/pcb-viewer": "^1.11.194",
|
|
86
87
|
"@tscircuit/prompt-benchmarks": "^0.0.28",
|
|
87
|
-
"@tscircuit/runframe": "0.0.
|
|
88
|
+
"@tscircuit/runframe": "^0.0.781",
|
|
88
89
|
"@tscircuit/schematic-viewer": "^2.0.21",
|
|
90
|
+
"@tscircuit/simple-3d-svg": "^0.0.41",
|
|
89
91
|
"@types/babel__standalone": "^7.1.7",
|
|
90
92
|
"@types/bun": "^1.1.10",
|
|
91
93
|
"@types/country-list": "^2.1.4",
|
|
@@ -93,7 +95,6 @@
|
|
|
93
95
|
"@types/md5": "^2.3.5",
|
|
94
96
|
"@types/ms": "^0.7.34",
|
|
95
97
|
"@types/node": "^22.13.0",
|
|
96
|
-
"@types/prismjs": "^1.26.4",
|
|
97
98
|
"@types/react": "^18.3.9",
|
|
98
99
|
"@types/react-dom": "^18.3.0",
|
|
99
100
|
"@types/react-helmet": "^6.1.11",
|
|
@@ -104,11 +105,12 @@
|
|
|
104
105
|
"@vercel/analytics": "^1.4.1",
|
|
105
106
|
"@vitejs/plugin-react": "^4.3.1",
|
|
106
107
|
"autoprefixer": "^10.4.20",
|
|
107
|
-
"change-case": "^5.4.4",
|
|
108
108
|
"circuit-json-to-bom-csv": "^0.0.7",
|
|
109
109
|
"circuit-json-to-gerber": "^0.0.29",
|
|
110
|
+
"circuit-json-to-gltf": "^0.0.4",
|
|
110
111
|
"circuit-json-to-pnp-csv": "^0.0.7",
|
|
111
112
|
"circuit-json-to-readable-netlist": "^0.0.13",
|
|
113
|
+
"circuit-json-to-simple-3d": "^0.0.6",
|
|
112
114
|
"circuit-json-to-spice": "^0.0.6",
|
|
113
115
|
"circuit-json-to-tscircuit": "^0.0.4",
|
|
114
116
|
"circuit-to-svg": "^0.0.167",
|
|
@@ -117,8 +119,6 @@
|
|
|
117
119
|
"cmdk": "^1.0.4",
|
|
118
120
|
"codemirror": "^6.0.1",
|
|
119
121
|
"codemirror-copilot": "^0.0.7",
|
|
120
|
-
"country-list": "^2.3.0",
|
|
121
|
-
"date-fns": "^4.1.0",
|
|
122
122
|
"dotenv": "^16.5.0",
|
|
123
123
|
"dsn-converter": "^0.0.60",
|
|
124
124
|
"easyeda": "^0.0.203",
|
|
@@ -131,7 +131,6 @@
|
|
|
131
131
|
"he": "^1.2.0",
|
|
132
132
|
"idb-keyval": "^6.2.2",
|
|
133
133
|
"immer": "^10.1.1",
|
|
134
|
-
"input-otp": "^1.2.4",
|
|
135
134
|
"javascript-time-ago": "^2.5.11",
|
|
136
135
|
"jose": "^5.9.3",
|
|
137
136
|
"jscad-electronics": "^0.0.25",
|
|
@@ -147,7 +146,6 @@
|
|
|
147
146
|
"openai": "^5.6.0",
|
|
148
147
|
"postcss": "^8.4.47",
|
|
149
148
|
"posthog-js": "^1.203.2",
|
|
150
|
-
"prismjs": "^1.29.0",
|
|
151
149
|
"prompts": "^2.4.2",
|
|
152
150
|
"react": "^18.3.1",
|
|
153
151
|
"react-cookie-consent": "^9.0.0",
|
|
@@ -172,6 +170,7 @@
|
|
|
172
170
|
"sitemap": "^8.0.0",
|
|
173
171
|
"sonner": "^1.5.0",
|
|
174
172
|
"states-us": "^1.1.1",
|
|
173
|
+
"svgo": "^4.0.0",
|
|
175
174
|
"tailwind-merge": "^2.5.2",
|
|
176
175
|
"tailwindcss": "^3.4.13",
|
|
177
176
|
"tailwindcss-animate": "^1.0.7",
|
package/src/App.tsx
CHANGED
|
@@ -64,7 +64,6 @@ const MyOrdersPage = lazyImport(() => import("@/pages/my-orders"))
|
|
|
64
64
|
const LatestPage = lazyImport(() => import("@/pages/latest"))
|
|
65
65
|
const QuickstartPage = lazyImport(() => import("@/pages/quickstart"))
|
|
66
66
|
const SearchPage = lazyImport(() => import("@/pages/search"))
|
|
67
|
-
const SettingsPage = lazyImport(() => import("@/pages/settings"))
|
|
68
67
|
const UserProfilePage = lazyImport(() => import("@/pages/user-profile"))
|
|
69
68
|
const DevLoginPage = lazyImport(() => import("@/pages/dev-login"))
|
|
70
69
|
const ViewPackagePage = lazyImport(() => import("@/pages/view-package"))
|
|
@@ -252,7 +251,6 @@ function App() {
|
|
|
252
251
|
<Route path="/quickstart" component={QuickstartPage} />
|
|
253
252
|
<Route path="/dashboard" component={DashboardPage} />
|
|
254
253
|
<Route path="/latest" component={LatestPage} />
|
|
255
|
-
<Route path="/settings" component={SettingsPage} />
|
|
256
254
|
<Route path="/search" component={SearchPage} />
|
|
257
255
|
<Route path="/trending" component={TrendingPage} />
|
|
258
256
|
<Route path="/datasheets" component={DatasheetsPage} />
|
|
@@ -18,18 +18,22 @@ import { usePcbDownloadDialog } from "@/components/dialogs/pcb-download-dialog"
|
|
|
18
18
|
import { downloadKicadFiles } from "@/lib/download-fns/download-kicad-files"
|
|
19
19
|
import { AnyCircuitElement } from "circuit-json"
|
|
20
20
|
import { ChevronDown, Download, Hammer } from "lucide-react"
|
|
21
|
-
import {
|
|
21
|
+
import { downloadGltfFromCircuitJson } from "@/lib/download-fns/download-gltf-from-circuit-json"
|
|
22
22
|
import { downloadPngImage } from "@/lib/download-fns/download-png-utils"
|
|
23
23
|
import { ImageFormat } from "@/lib/download-fns/download-circuit-png"
|
|
24
24
|
import { CubeIcon } from "@radix-ui/react-icons"
|
|
25
|
+
import { useState } from "react"
|
|
26
|
+
import { useAxios } from "@/hooks/use-axios"
|
|
27
|
+
import { useCurrentPackageId } from "@/hooks/use-current-package-id"
|
|
25
28
|
|
|
26
29
|
interface DownloadButtonAndMenuProps {
|
|
27
30
|
className?: string
|
|
28
31
|
unscopedName?: string
|
|
29
32
|
author?: string
|
|
30
|
-
|
|
33
|
+
hasCircuitJson?: boolean
|
|
31
34
|
desiredImageType?: string
|
|
32
35
|
offerMultipleImageFormats?: boolean
|
|
36
|
+
circuitJson?: AnyCircuitElement[] | null
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
export function DownloadButtonAndMenu({
|
|
@@ -37,14 +41,52 @@ export function DownloadButtonAndMenu({
|
|
|
37
41
|
unscopedName,
|
|
38
42
|
author,
|
|
39
43
|
desiredImageType = "pcb",
|
|
40
|
-
|
|
44
|
+
hasCircuitJson,
|
|
41
45
|
offerMultipleImageFormats = false,
|
|
46
|
+
circuitJson,
|
|
42
47
|
}: DownloadButtonAndMenuProps) {
|
|
43
48
|
const notImplemented = useNotImplementedToast()
|
|
44
49
|
const { Dialog: PcbDownloadDialog, openDialog: openPcbDownloadDialog } =
|
|
45
50
|
usePcbDownloadDialog()
|
|
51
|
+
const axios = useAxios()
|
|
52
|
+
const { packageId } = useCurrentPackageId()
|
|
53
|
+
const [fetchedCircuitJson, setFetchedCircuitJson] = useState<
|
|
54
|
+
AnyCircuitElement[] | null
|
|
55
|
+
>(null)
|
|
56
|
+
const [isFetchingCircuitJson, setIsFetchingCircuitJson] = useState(false)
|
|
57
|
+
|
|
58
|
+
const canDownload = Boolean(
|
|
59
|
+
hasCircuitJson || (circuitJson && circuitJson.length),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
const getCircuitJson = async (): Promise<AnyCircuitElement[]> => {
|
|
63
|
+
if (circuitJson && circuitJson.length) return circuitJson
|
|
64
|
+
if (fetchedCircuitJson && fetchedCircuitJson.length)
|
|
65
|
+
return fetchedCircuitJson
|
|
66
|
+
setIsFetchingCircuitJson(true)
|
|
67
|
+
try {
|
|
68
|
+
const { data } = await axios.post("/package_files/get", {
|
|
69
|
+
package_id: packageId,
|
|
70
|
+
file_path: "dist/circuit.json",
|
|
71
|
+
})
|
|
72
|
+
const content = data?.package_file?.content_text
|
|
73
|
+
if (!content) throw new Error("Circuit JSON not found")
|
|
74
|
+
const parsed = JSON.parse(content)
|
|
75
|
+
setFetchedCircuitJson(parsed)
|
|
76
|
+
return parsed
|
|
77
|
+
} catch (error: any) {
|
|
78
|
+
toast({
|
|
79
|
+
title: "Failed to fetch Circuit JSON",
|
|
80
|
+
description: error?.message || error?.toString?.() || "Unknown error",
|
|
81
|
+
variant: "destructive",
|
|
82
|
+
})
|
|
83
|
+
throw error
|
|
84
|
+
} finally {
|
|
85
|
+
setIsFetchingCircuitJson(false)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
46
88
|
|
|
47
|
-
if (!
|
|
89
|
+
if (!canDownload) {
|
|
48
90
|
return (
|
|
49
91
|
<div className={className}>
|
|
50
92
|
<Button
|
|
@@ -76,11 +118,9 @@ export function DownloadButtonAndMenu({
|
|
|
76
118
|
<DropdownMenuContent className="!z-[101]">
|
|
77
119
|
<DropdownMenuItem
|
|
78
120
|
className="text-xs"
|
|
79
|
-
onSelect={() => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
unscopedName || "circuit" + ".json",
|
|
83
|
-
)
|
|
121
|
+
onSelect={async () => {
|
|
122
|
+
const cj = await getCircuitJson()
|
|
123
|
+
downloadCircuitJson(cj, unscopedName || "circuit" + ".json")
|
|
84
124
|
}}
|
|
85
125
|
>
|
|
86
126
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -93,7 +133,12 @@ export function DownloadButtonAndMenu({
|
|
|
93
133
|
className="text-xs"
|
|
94
134
|
onClick={async () => {
|
|
95
135
|
try {
|
|
96
|
-
await
|
|
136
|
+
const cj = await getCircuitJson()
|
|
137
|
+
await downloadGltfFromCircuitJson(
|
|
138
|
+
cj,
|
|
139
|
+
unscopedName || "circuit",
|
|
140
|
+
{ format: "glb", boardTextureResolution: 2048 },
|
|
141
|
+
)
|
|
97
142
|
} catch (error: any) {
|
|
98
143
|
toast({
|
|
99
144
|
title: "Error Downloading 3D Model",
|
|
@@ -112,8 +157,34 @@ export function DownloadButtonAndMenu({
|
|
|
112
157
|
<DropdownMenuItem
|
|
113
158
|
className="text-xs"
|
|
114
159
|
onClick={async () => {
|
|
160
|
+
try {
|
|
161
|
+
const cj = await getCircuitJson()
|
|
162
|
+
await downloadGltfFromCircuitJson(
|
|
163
|
+
cj,
|
|
164
|
+
unscopedName || "circuit",
|
|
165
|
+
{ format: "gltf", boardTextureResolution: 2048 },
|
|
166
|
+
)
|
|
167
|
+
} catch (error: any) {
|
|
168
|
+
toast({
|
|
169
|
+
title: "Error Downloading 3D Model (GLTF)",
|
|
170
|
+
description: error.toString(),
|
|
171
|
+
variant: "destructive",
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
}}
|
|
175
|
+
>
|
|
176
|
+
<CubeIcon className="mr-1 h-3 w-3" />
|
|
177
|
+
<span className="flex-grow mr-6">3D Model</span>
|
|
178
|
+
<span className="text-[0.6rem] bg-green-500 opacity-80 text-white font-mono rounded-md px-1 text-center py-0.5 mr-1">
|
|
179
|
+
gltf
|
|
180
|
+
</span>
|
|
181
|
+
</DropdownMenuItem>
|
|
182
|
+
<DropdownMenuItem
|
|
183
|
+
className="text-xs"
|
|
184
|
+
onClick={async () => {
|
|
185
|
+
const cj = await getCircuitJson()
|
|
115
186
|
await downloadFabricationFiles({
|
|
116
|
-
circuitJson,
|
|
187
|
+
circuitJson: cj,
|
|
117
188
|
snippetUnscopedName: unscopedName || "snippet",
|
|
118
189
|
}).catch((error) => {
|
|
119
190
|
console.error(error)
|
|
@@ -144,8 +215,9 @@ export function DownloadButtonAndMenu({
|
|
|
144
215
|
</DropdownMenuItem>
|
|
145
216
|
<DropdownMenuItem
|
|
146
217
|
className="text-xs"
|
|
147
|
-
onSelect={() => {
|
|
148
|
-
|
|
218
|
+
onSelect={async () => {
|
|
219
|
+
const cj = await getCircuitJson()
|
|
220
|
+
downloadKicadFiles(cj, unscopedName || "kicad_project")
|
|
149
221
|
}}
|
|
150
222
|
>
|
|
151
223
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -157,8 +229,9 @@ export function DownloadButtonAndMenu({
|
|
|
157
229
|
|
|
158
230
|
<DropdownMenuItem
|
|
159
231
|
className="text-xs"
|
|
160
|
-
onSelect={() => {
|
|
161
|
-
|
|
232
|
+
onSelect={async () => {
|
|
233
|
+
const cj = await getCircuitJson()
|
|
234
|
+
downloadSchematicSvg(cj, unscopedName || "circuit")
|
|
162
235
|
}}
|
|
163
236
|
>
|
|
164
237
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -169,8 +242,9 @@ export function DownloadButtonAndMenu({
|
|
|
169
242
|
</DropdownMenuItem>
|
|
170
243
|
<DropdownMenuItem
|
|
171
244
|
className="text-xs"
|
|
172
|
-
onSelect={() => {
|
|
173
|
-
|
|
245
|
+
onSelect={async () => {
|
|
246
|
+
const cj = await getCircuitJson()
|
|
247
|
+
downloadAssemblySvg(cj, unscopedName || "circuit")
|
|
174
248
|
}}
|
|
175
249
|
>
|
|
176
250
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -181,7 +255,9 @@ export function DownloadButtonAndMenu({
|
|
|
181
255
|
</DropdownMenuItem>
|
|
182
256
|
<DropdownMenuItem
|
|
183
257
|
className="text-xs"
|
|
184
|
-
onSelect={() => {
|
|
258
|
+
onSelect={async () => {
|
|
259
|
+
const cj = await getCircuitJson()
|
|
260
|
+
setFetchedCircuitJson(cj)
|
|
185
261
|
openPcbDownloadDialog()
|
|
186
262
|
}}
|
|
187
263
|
>
|
|
@@ -193,8 +269,9 @@ export function DownloadButtonAndMenu({
|
|
|
193
269
|
</DropdownMenuItem>
|
|
194
270
|
<DropdownMenuItem
|
|
195
271
|
className="text-xs"
|
|
196
|
-
onSelect={() => {
|
|
197
|
-
|
|
272
|
+
onSelect={async () => {
|
|
273
|
+
const cj = await getCircuitJson()
|
|
274
|
+
downloadDsnFile(cj, unscopedName || "circuit")
|
|
198
275
|
}}
|
|
199
276
|
>
|
|
200
277
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -205,8 +282,9 @@ export function DownloadButtonAndMenu({
|
|
|
205
282
|
</DropdownMenuItem>
|
|
206
283
|
<DropdownMenuItem
|
|
207
284
|
className="text-xs"
|
|
208
|
-
onClick={() => {
|
|
209
|
-
|
|
285
|
+
onClick={async () => {
|
|
286
|
+
const cj = await getCircuitJson()
|
|
287
|
+
downloadReadableNetlist(cj, unscopedName || "circuit")
|
|
210
288
|
}}
|
|
211
289
|
>
|
|
212
290
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -217,8 +295,9 @@ export function DownloadButtonAndMenu({
|
|
|
217
295
|
</DropdownMenuItem>
|
|
218
296
|
<DropdownMenuItem
|
|
219
297
|
className="text-xs"
|
|
220
|
-
onSelect={() => {
|
|
221
|
-
|
|
298
|
+
onSelect={async () => {
|
|
299
|
+
const cj = await getCircuitJson()
|
|
300
|
+
downloadSpiceFile(cj, unscopedName || "circuit")
|
|
222
301
|
}}
|
|
223
302
|
>
|
|
224
303
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -229,8 +308,9 @@ export function DownloadButtonAndMenu({
|
|
|
229
308
|
</DropdownMenuItem>
|
|
230
309
|
<DropdownMenuItem
|
|
231
310
|
className="text-xs"
|
|
232
|
-
onSelect={() => {
|
|
233
|
-
|
|
311
|
+
onSelect={async () => {
|
|
312
|
+
const cj = await getCircuitJson()
|
|
313
|
+
downloadSimpleRouteJson(cj, unscopedName || "circuit")
|
|
234
314
|
}}
|
|
235
315
|
>
|
|
236
316
|
<Download className="mr-1 h-3 w-3" />
|
|
@@ -243,7 +323,7 @@ export function DownloadButtonAndMenu({
|
|
|
243
323
|
{!offerMultipleImageFormats && (
|
|
244
324
|
<DropdownMenuItem
|
|
245
325
|
className="text-xs"
|
|
246
|
-
onClick={() => {
|
|
326
|
+
onClick={async () => {
|
|
247
327
|
const desiredImageFormat = [
|
|
248
328
|
"pcb",
|
|
249
329
|
"schematic",
|
|
@@ -252,8 +332,9 @@ export function DownloadButtonAndMenu({
|
|
|
252
332
|
].includes(desiredImageType)
|
|
253
333
|
? desiredImageType
|
|
254
334
|
: "pcb"
|
|
335
|
+
const cj = await getCircuitJson()
|
|
255
336
|
downloadPngImage({
|
|
256
|
-
circuitJson,
|
|
337
|
+
circuitJson: cj,
|
|
257
338
|
unscopedName,
|
|
258
339
|
author,
|
|
259
340
|
format: desiredImageFormat as ImageFormat,
|
|
@@ -271,9 +352,9 @@ export function DownloadButtonAndMenu({
|
|
|
271
352
|
<>
|
|
272
353
|
<DropdownMenuItem
|
|
273
354
|
className="text-xs"
|
|
274
|
-
onClick={() =>
|
|
355
|
+
onClick={async () =>
|
|
275
356
|
downloadPngImage({
|
|
276
|
-
circuitJson,
|
|
357
|
+
circuitJson: await getCircuitJson(),
|
|
277
358
|
unscopedName,
|
|
278
359
|
author,
|
|
279
360
|
format: "schematic",
|
|
@@ -288,9 +369,9 @@ export function DownloadButtonAndMenu({
|
|
|
288
369
|
</DropdownMenuItem>
|
|
289
370
|
<DropdownMenuItem
|
|
290
371
|
className="text-xs"
|
|
291
|
-
onClick={() =>
|
|
372
|
+
onClick={async () =>
|
|
292
373
|
downloadPngImage({
|
|
293
|
-
circuitJson,
|
|
374
|
+
circuitJson: await getCircuitJson(),
|
|
294
375
|
unscopedName,
|
|
295
376
|
author,
|
|
296
377
|
format: "pcb",
|
|
@@ -305,9 +386,9 @@ export function DownloadButtonAndMenu({
|
|
|
305
386
|
</DropdownMenuItem>
|
|
306
387
|
<DropdownMenuItem
|
|
307
388
|
className="text-xs"
|
|
308
|
-
onClick={() =>
|
|
389
|
+
onClick={async () =>
|
|
309
390
|
downloadPngImage({
|
|
310
|
-
circuitJson,
|
|
391
|
+
circuitJson: await getCircuitJson(),
|
|
311
392
|
unscopedName,
|
|
312
393
|
author,
|
|
313
394
|
format: "assembly",
|
|
@@ -320,12 +401,29 @@ export function DownloadButtonAndMenu({
|
|
|
320
401
|
png
|
|
321
402
|
</span>
|
|
322
403
|
</DropdownMenuItem>
|
|
404
|
+
<DropdownMenuItem
|
|
405
|
+
className="text-xs"
|
|
406
|
+
onClick={async () =>
|
|
407
|
+
downloadPngImage({
|
|
408
|
+
circuitJson: await getCircuitJson(),
|
|
409
|
+
unscopedName,
|
|
410
|
+
author,
|
|
411
|
+
format: "3d",
|
|
412
|
+
})
|
|
413
|
+
}
|
|
414
|
+
>
|
|
415
|
+
<Download className="mr-1 h-3 w-3" />
|
|
416
|
+
<span className="flex-grow mr-6">3D PNG</span>
|
|
417
|
+
<span className="text-[0.6rem] opacity-80 bg-teal-600 text-white font-mono rounded-md px-1 text-center py-0.5 mr-1">
|
|
418
|
+
png
|
|
419
|
+
</span>
|
|
420
|
+
</DropdownMenuItem>
|
|
323
421
|
</>
|
|
324
422
|
)}
|
|
325
423
|
</DropdownMenuContent>
|
|
326
424
|
</DropdownMenu>
|
|
327
425
|
<PcbDownloadDialog
|
|
328
|
-
circuitJson={circuitJson}
|
|
426
|
+
circuitJson={fetchedCircuitJson || circuitJson || []}
|
|
329
427
|
fileName={unscopedName || "circuit"}
|
|
330
428
|
/>
|
|
331
429
|
</div>
|
|
@@ -1,25 +1,9 @@
|
|
|
1
1
|
import React, { useState } from "react"
|
|
2
2
|
import { cn } from "@/lib/utils"
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
Folder,
|
|
6
|
-
MoreVertical,
|
|
7
|
-
PanelRightOpen,
|
|
8
|
-
Plus,
|
|
9
|
-
Trash2,
|
|
10
|
-
Pencil,
|
|
11
|
-
} from "lucide-react"
|
|
12
|
-
import { TreeView, TreeDataItem } from "@/components/ui/tree-view"
|
|
13
|
-
import { isHiddenFile } from "./ViewPackagePage/utils/is-hidden-file"
|
|
3
|
+
import { PanelRightOpen, Plus, Loader2 } from "lucide-react"
|
|
4
|
+
import { TreeView } from "@/components/ui/tree-view"
|
|
14
5
|
import { Input } from "@/components/ui/input"
|
|
15
6
|
import { transformFilesToTreeData } from "@/lib/utils/transformFilesToTreeData"
|
|
16
|
-
import {
|
|
17
|
-
DropdownMenu,
|
|
18
|
-
DropdownMenuContent,
|
|
19
|
-
DropdownMenuGroup,
|
|
20
|
-
DropdownMenuItem,
|
|
21
|
-
DropdownMenuTrigger,
|
|
22
|
-
} from "./ui/dropdown-menu"
|
|
23
7
|
import type {
|
|
24
8
|
ICreateFileProps,
|
|
25
9
|
ICreateFileResult,
|
|
@@ -28,8 +12,6 @@ import type {
|
|
|
28
12
|
IRenameFileProps,
|
|
29
13
|
IRenameFileResult,
|
|
30
14
|
} from "@/hooks/useFileManagement"
|
|
31
|
-
import { useToast } from "@/hooks/use-toast"
|
|
32
|
-
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
33
15
|
import type { Package } from "fake-snippets-api/lib/db/schema"
|
|
34
16
|
type FileName = string
|
|
35
17
|
|
|
@@ -45,6 +27,8 @@ interface FileSidebarProps {
|
|
|
45
27
|
isCreatingFile: boolean
|
|
46
28
|
setIsCreatingFile: React.Dispatch<React.SetStateAction<boolean>>
|
|
47
29
|
pkg?: Package
|
|
30
|
+
isLoadingFiles?: boolean
|
|
31
|
+
loadingProgress?: string | null
|
|
48
32
|
}
|
|
49
33
|
|
|
50
34
|
const FileSidebar: React.FC<FileSidebarProps> = ({
|
|
@@ -58,6 +42,8 @@ const FileSidebar: React.FC<FileSidebarProps> = ({
|
|
|
58
42
|
handleRenameFile,
|
|
59
43
|
isCreatingFile,
|
|
60
44
|
setIsCreatingFile,
|
|
45
|
+
isLoadingFiles = true,
|
|
46
|
+
loadingProgress = null,
|
|
61
47
|
}) => {
|
|
62
48
|
const [sidebarOpen, setSidebarOpen] = fileSidebarState
|
|
63
49
|
const [newFileName, setNewFileName] = useState("")
|
|
@@ -69,7 +55,6 @@ const FileSidebar: React.FC<FileSidebarProps> = ({
|
|
|
69
55
|
const [selectedItemId, setSelectedItemId] = React.useState<string>(
|
|
70
56
|
currentFile || "",
|
|
71
57
|
)
|
|
72
|
-
const { toast } = useToast()
|
|
73
58
|
const canModifyFiles = true
|
|
74
59
|
|
|
75
60
|
const onFolderSelect = (folderPath: string) => {
|
|
@@ -184,19 +169,31 @@ const FileSidebar: React.FC<FileSidebarProps> = ({
|
|
|
184
169
|
className,
|
|
185
170
|
)}
|
|
186
171
|
>
|
|
187
|
-
<
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
172
|
+
<div className="flex items-center justify-between px-2 pt-2">
|
|
173
|
+
<button
|
|
174
|
+
onClick={toggleSidebar}
|
|
175
|
+
className={`text-gray-400 scale-90 transition-opacity duration-200 ${!sidebarOpen ? "opacity-0 pointer-events-none" : "opacity-100"}`}
|
|
176
|
+
>
|
|
177
|
+
<PanelRightOpen />
|
|
178
|
+
</button>
|
|
179
|
+
<div className="flex items-center gap-2">
|
|
180
|
+
{isLoadingFiles && (
|
|
181
|
+
<div className="flex items-center gap-1">
|
|
182
|
+
<Loader2 className="w-3 h-3 animate-spin text-gray-400" />
|
|
183
|
+
{loadingProgress && (
|
|
184
|
+
<span className="text-xs text-gray-400">{loadingProgress}</span>
|
|
185
|
+
)}
|
|
186
|
+
</div>
|
|
187
|
+
)}
|
|
188
|
+
<button
|
|
189
|
+
onClick={() => setIsCreatingFile(true)}
|
|
190
|
+
className="text-gray-400 hover:text-gray-600"
|
|
191
|
+
aria-label="Create new file"
|
|
192
|
+
>
|
|
193
|
+
<Plus className="w-5 h-5" />
|
|
194
|
+
</button>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
200
197
|
{isCreatingFile && (
|
|
201
198
|
<div className="p-2">
|
|
202
199
|
<Input
|