@tscircuit/fake-snippets 0.0.109 → 0.0.111
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/.github/workflows/bun-formatcheck.yml +2 -2
- package/.github/workflows/bun-pver-release.yml +3 -3
- package/.github/workflows/bun-test.yml +1 -1
- package/.github/workflows/bun-typecheck.yml +2 -2
- package/.github/workflows/update-snapshots.yml +1 -1
- package/README.md +4 -0
- package/api/generated-index.js +37 -3
- package/biome.json +2 -1
- package/bun-tests/fake-snippets-api/fixtures/get-test-server.ts +32 -3
- package/bun-tests/fake-snippets-api/fixtures/preload.ts +18 -0
- package/bun-tests/fake-snippets-api/routes/orgs/add_member.test.ts +26 -0
- package/bun-tests/fake-snippets-api/routes/orgs/create.test.ts +37 -0
- package/bun-tests/fake-snippets-api/routes/orgs/get.test.ts +52 -0
- package/bun-tests/fake-snippets-api/routes/orgs/list.test.ts +17 -0
- package/bun-tests/fake-snippets-api/routes/orgs/list_members.test.ts +23 -0
- package/bun-tests/fake-snippets-api/routes/orgs/remove_member.test.ts +81 -0
- package/bun-tests/fake-snippets-api/routes/orgs/update.test.ts +151 -0
- package/bun-tests/fake-snippets-api/routes/package_builds/get.test.ts +1 -1
- package/bun-tests/fake-snippets-api/routes/package_files/create.test.ts +15 -13
- package/bun-tests/fake-snippets-api/routes/package_files/create_or_update.test.ts +26 -24
- package/bun-tests/fake-snippets-api/routes/package_files/delete.test.ts +9 -9
- package/bun-tests/fake-snippets-api/routes/package_files/download.test.ts +4 -4
- package/bun-tests/fake-snippets-api/routes/package_files/get.test.ts +38 -28
- package/bun-tests/fake-snippets-api/routes/package_files/list.test.ts +23 -15
- package/bun-tests/fake-snippets-api/routes/package_releases/create.test.ts +33 -0
- package/bun-tests/fake-snippets-api/routes/package_releases/get.test.ts +4 -4
- package/bun-tests/fake-snippets-api/routes/package_releases/get_image_generation_fields.test.ts +38 -0
- package/bun-tests/fake-snippets-api/routes/packages/create.test.ts +19 -0
- package/bun-tests/fake-snippets-api/routes/packages/fork.test.ts +3 -4
- package/bun-tests/fake-snippets-api/routes/packages/get.test.ts +30 -0
- package/bun-tests/fake-snippets-api/routes/packages/images.test.ts +4 -2
- package/bun-tests/fake-snippets-api/routes/packages/list-1.test.ts +34 -0
- package/bun.lock +361 -453
- package/bunfig.toml +2 -1
- package/dist/bundle.js +1313 -639
- package/dist/index.d.ts +313 -6
- package/dist/index.js +328 -24
- package/dist/schema.d.ts +290 -1
- package/dist/schema.js +54 -1
- package/fake-snippets-api/lib/db/autoload-dev-packages.ts +31 -20
- package/fake-snippets-api/lib/db/db-client.ts +219 -4
- package/fake-snippets-api/lib/db/schema.ts +63 -1
- package/fake-snippets-api/lib/db/seed.ts +100 -0
- package/fake-snippets-api/lib/middleware/with-session-auth.ts +60 -8
- package/fake-snippets-api/lib/package_file/get-package-file-id-from-file-descriptor.ts +2 -2
- package/fake-snippets-api/lib/public-mapping/public-map-org.ts +33 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package-build.ts +10 -0
- package/fake-snippets-api/lib/public-mapping/public-map-package-release.ts +17 -0
- package/fake-snippets-api/routes/api/orgs/add_member.ts +52 -0
- package/fake-snippets-api/routes/api/orgs/create.ts +48 -0
- package/fake-snippets-api/routes/api/orgs/get.ts +39 -0
- package/fake-snippets-api/routes/api/orgs/list.ts +31 -0
- package/fake-snippets-api/routes/api/orgs/list_members.ts +60 -0
- package/fake-snippets-api/routes/api/orgs/remove_member.ts +46 -0
- package/fake-snippets-api/routes/api/orgs/update.ts +118 -0
- package/fake-snippets-api/routes/api/package_files/get.ts +3 -6
- package/fake-snippets-api/routes/api/package_files/list.ts +7 -4
- package/fake-snippets-api/routes/api/packages/create.ts +57 -10
- package/fake-snippets-api/routes/api/packages/get.ts +23 -0
- package/fake-snippets-api/routes/api/packages/images/[owner_github_username]/[unscoped_name]/[view_format].ts +13 -11
- package/fake-snippets-api/routes/api/packages/list.ts +29 -2
- package/fake-snippets-api/routes/api/packages/update_ai_description.ts +37 -0
- package/package.json +25 -19
- package/renovate.json +1 -1
- package/scripts/generate-sitemap.ts +1 -1
- package/src/App.tsx +27 -8
- package/src/ContextProviders.tsx +25 -2
- package/src/components/CircuitJsonImportDialog.tsx +1 -1
- package/src/components/CmdKMenu.tsx +281 -247
- package/src/components/DownloadButtonAndMenu.tsx +17 -5
- package/src/components/FileSidebar.tsx +11 -17
- package/src/components/Footer.tsx +8 -9
- package/src/components/Header.tsx +19 -32
- package/src/components/Header2.tsx +16 -32
- package/src/components/HeaderDropdown.tsx +13 -8
- package/src/components/HeaderLogin.tsx +43 -15
- package/src/components/NotFound.tsx +5 -5
- package/src/components/PackageBreadcrumb.tsx +6 -12
- package/src/components/PackageSearchResults.tsx +1 -1
- package/src/components/PrefetchPageLink.tsx +7 -1
- package/src/components/ProfileRouter.tsx +32 -0
- package/src/components/SearchComponent.tsx +12 -8
- package/src/components/SentryNotFoundReporter.tsx +44 -0
- package/src/components/UserCard.tsx +80 -0
- package/src/components/ViewPackagePage/components/build-status.tsx +1 -1
- package/src/components/ViewPackagePage/components/important-files-view.tsx +105 -34
- package/src/components/ViewPackagePage/components/main-content-header.tsx +10 -6
- package/src/components/ViewPackagePage/components/main-content-view-selector.tsx +1 -1
- package/src/components/ViewPackagePage/components/mobile-sidebar.tsx +54 -19
- package/src/components/ViewPackagePage/components/package-header.tsx +25 -33
- package/src/components/ViewPackagePage/components/preview-image-squares.tsx +11 -18
- package/src/components/ViewPackagePage/components/repo-page-content.tsx +12 -5
- package/src/components/ViewPackagePage/components/sidebar-about-section.tsx +16 -10
- package/src/components/ViewPackagePage/components/sidebar-releases-section.tsx +11 -11
- package/src/components/ViewPackagePage/components/tab-views/pcb-view.tsx +1 -2
- package/src/components/ViewPackagePage/components/tab-views/schematic-view.tsx +2 -1
- package/src/components/dialogs/GitHubRepositorySelector.tsx +56 -49
- package/src/components/dialogs/edit-package-details-dialog.tsx +5 -6
- package/src/components/dialogs/import-component-dialog.tsx +16 -9
- package/src/components/dialogs/import-package-dialog.tsx +3 -2
- package/src/components/dialogs/new-package-save-prompt-dialog.tsx +190 -0
- package/src/components/organization/OrganizationCard.tsx +206 -0
- package/src/components/organization/OrganizationCardSkeleton.tsx +55 -0
- package/src/components/organization/OrganizationHeader.tsx +154 -0
- package/src/components/organization/OrganizationMembers.tsx +146 -0
- package/src/components/package-port/CodeAndPreview.tsx +15 -12
- package/src/components/package-port/CodeEditor.tsx +4 -30
- package/src/components/package-port/CodeEditorHeader.tsx +123 -61
- package/src/components/package-port/EditorNav.tsx +32 -49
- package/src/components/preview/ConnectedPackagesList.tsx +8 -8
- package/src/components/preview/ConnectedRepoOverview.tsx +102 -2
- package/src/components/preview/PackageReleasesDashboard.tsx +23 -11
- package/src/components/ui/tree-view.tsx +6 -3
- package/src/hooks/use-add-org-member-mutation.ts +51 -0
- package/src/hooks/use-create-org-mutation.ts +38 -0
- package/src/hooks/use-create-package-mutation.ts +3 -0
- package/src/hooks/use-current-package-release.ts +4 -3
- package/src/hooks/use-download-zip.ts +2 -2
- package/src/hooks/use-global-store.ts +6 -4
- package/src/hooks/use-hydration.ts +30 -0
- package/src/hooks/use-jlcpcb-component-import.tsx +164 -0
- package/src/hooks/use-list-org-members.ts +27 -0
- package/src/hooks/use-list-user-orgs.ts +25 -0
- package/src/hooks/use-org-by-github-handle.ts +26 -0
- package/src/hooks/use-org.ts +24 -0
- package/src/hooks/use-organization.ts +42 -0
- package/src/hooks/use-package-as-snippet.ts +4 -2
- package/src/hooks/use-package-builds.ts +6 -2
- package/src/hooks/use-package-files.ts +5 -3
- package/src/hooks/use-package-release-by-id-or-version.ts +29 -20
- package/src/hooks/use-package-release-images.ts +105 -0
- package/src/hooks/use-package-release.ts +2 -2
- package/src/hooks/use-package-stars.ts +80 -4
- package/src/hooks/use-preview-images.ts +6 -3
- package/src/hooks/use-remove-org-member-mutation.ts +32 -0
- package/src/hooks/use-update-ai-description-mutation.ts +42 -0
- package/src/hooks/use-update-org-mutation.ts +41 -0
- package/src/hooks/use-warn-user-on-page-change.ts +71 -4
- package/src/hooks/useFileManagement.ts +51 -22
- package/src/hooks/useOptimizedPackageFilesLoader.ts +11 -24
- package/src/hooks/usePackageFilesLoader.ts +2 -2
- package/src/hooks/useUpdatePackageFilesMutation.ts +13 -1
- package/src/lib/download-fns/download-gltf-from-circuit-json.ts +1 -1
- package/src/lib/download-fns/download-kicad-files.ts +22 -11
- package/src/lib/download-fns/download-step.ts +12 -0
- package/src/lib/normalize-svg-for-tile.ts +50 -0
- package/src/lib/posthog.ts +11 -9
- package/src/lib/react-query-api-failure-tracking.ts +148 -0
- package/src/lib/sentry.ts +14 -0
- package/src/lib/templates/blank-circuit-board-template.ts +0 -4
- package/src/lib/ts-lib-cache.ts +122 -7
- package/src/lib/utils/checkIfManualEditsImported.ts +4 -4
- package/src/lib/utils/findTargetFile.ts +45 -10
- package/src/lib/utils/isComponentExported.ts +2 -1
- package/src/main.tsx +2 -1
- package/src/pages/create-organization.tsx +169 -0
- package/src/pages/dashboard.tsx +38 -6
- package/src/pages/datasheet.tsx +1 -1
- package/src/pages/datasheets.tsx +3 -3
- package/src/pages/editor.tsx +4 -6
- package/src/pages/landing.tsx +6 -6
- package/src/pages/latest.tsx +3 -0
- package/src/pages/organization-profile.tsx +199 -0
- package/src/pages/organization-settings.tsx +569 -0
- package/src/pages/package-editor.tsx +21 -21
- package/src/pages/preview-release.tsx +75 -145
- package/src/pages/quickstart.tsx +159 -123
- package/src/pages/release-detail.tsx +119 -31
- package/src/pages/search.tsx +197 -57
- package/src/pages/settings-redirect.tsx +44 -0
- package/src/pages/trending.tsx +29 -20
- package/src/pages/user-profile.tsx +58 -7
- package/src/pages/user-settings.tsx +161 -0
- package/src/pages/view-package.tsx +30 -16
- package/vite.config.ts +9 -0
- package/fake-snippets-api/routes/api/autocomplete/create_autocomplete.ts +0 -133
- package/src/components/JLCPCBImportDialog.tsx +0 -280
- package/src/components/PackageBuildsPage/LogContent.tsx +0 -72
- package/src/components/PackageBuildsPage/PackageBuildDetailsPage.tsx +0 -113
- package/src/components/PackageBuildsPage/build-preview-content.tsx +0 -56
- package/src/components/PackageBuildsPage/collapsible-section.tsx +0 -63
- package/src/components/PackageBuildsPage/package-build-details-panel.tsx +0 -166
- package/src/components/PackageBuildsPage/package-build-header.tsx +0 -79
- package/src/components/PageSearchComponent.tsx +0 -148
- package/src/pages/package-builds.tsx +0 -33
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { GitFork, Star, Tag, Settings, LinkIcon } from "lucide-react"
|
|
2
2
|
import { Badge } from "@/components/ui/badge"
|
|
3
3
|
import { Skeleton } from "@/components/ui/skeleton"
|
|
4
|
+
import { usePackageReleaseImages } from "@/hooks/use-package-release-images"
|
|
4
5
|
import { usePreviewImages } from "@/hooks/use-preview-images"
|
|
5
6
|
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
6
7
|
import { Button } from "@/components/ui/button"
|
|
7
8
|
import { useEditPackageDetailsDialog } from "@/components/dialogs/edit-package-details-dialog"
|
|
8
9
|
import React, { useState, useEffect, useMemo, useCallback } from "react"
|
|
10
|
+
import {
|
|
11
|
+
normalizeSvgForSquareTile,
|
|
12
|
+
svgToDataUrl,
|
|
13
|
+
} from "@/lib/normalize-svg-for-tile"
|
|
9
14
|
import { useCurrentPackageInfo } from "@/hooks/use-current-package-info"
|
|
10
|
-
import {
|
|
15
|
+
import { usePackageFileById, usePackageFiles } from "@/hooks/use-package-files"
|
|
11
16
|
import { getLicenseFromLicenseContent } from "@/lib/getLicenseFromLicenseContent"
|
|
12
17
|
|
|
13
18
|
interface MobileSidebarProps {
|
|
@@ -20,19 +25,25 @@ const MobileSidebar = ({
|
|
|
20
25
|
onViewChange,
|
|
21
26
|
}: MobileSidebarProps) => {
|
|
22
27
|
const { packageInfo, refetch: refetchPackageInfo } = useCurrentPackageInfo()
|
|
23
|
-
const { data:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
const { data: releaseFiles } = usePackageFiles(
|
|
29
|
+
packageInfo?.latest_package_release_id,
|
|
30
|
+
)
|
|
31
|
+
const licenseFileId = useMemo(() => {
|
|
32
|
+
return (
|
|
33
|
+
releaseFiles?.find((f) => f.file_path === "LICENSE")?.package_file_id ||
|
|
34
|
+
null
|
|
35
|
+
)
|
|
36
|
+
}, [releaseFiles])
|
|
37
|
+
const { data: licenseFileMeta } = usePackageFileById(licenseFileId)
|
|
27
38
|
const currentLicense = useMemo(() => {
|
|
28
39
|
if (packageInfo?.latest_license) {
|
|
29
40
|
return packageInfo?.latest_license
|
|
30
41
|
}
|
|
31
42
|
if (licenseFileMeta?.content_text) {
|
|
32
|
-
return getLicenseFromLicenseContent(licenseFileMeta
|
|
43
|
+
return getLicenseFromLicenseContent(licenseFileMeta.content_text)
|
|
33
44
|
}
|
|
34
45
|
return undefined
|
|
35
|
-
}, [licenseFileMeta
|
|
46
|
+
}, [licenseFileMeta, packageInfo?.latest_license])
|
|
36
47
|
const topics = useMemo(
|
|
37
48
|
() => (packageInfo?.is_package ? ["Package"] : ["Board"]),
|
|
38
49
|
[packageInfo?.is_package],
|
|
@@ -69,11 +80,21 @@ const MobileSidebar = ({
|
|
|
69
80
|
[refetchPackageInfo],
|
|
70
81
|
)
|
|
71
82
|
|
|
72
|
-
const { availableViews } =
|
|
83
|
+
const { availableViews: imageViews } = usePackageReleaseImages({
|
|
84
|
+
packageReleaseId: packageInfo?.latest_package_release_id,
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
const { availableViews: pngViews } = usePreviewImages({
|
|
73
88
|
packageName: packageInfo?.name,
|
|
74
89
|
fsMapHash: packageInfo?.latest_package_release_fs_sha ?? "",
|
|
75
90
|
})
|
|
76
91
|
|
|
92
|
+
const viewsToRender =
|
|
93
|
+
imageViews.length === 0 ||
|
|
94
|
+
imageViews.every((v) => !v.isLoading && !v.imageUrl)
|
|
95
|
+
? (pngViews as any)
|
|
96
|
+
: imageViews
|
|
97
|
+
|
|
77
98
|
const handleViewClick = useCallback(
|
|
78
99
|
(viewId: string) => {
|
|
79
100
|
onViewChange?.(viewId as "3d" | "pcb" | "schematic")
|
|
@@ -185,11 +206,14 @@ const MobileSidebar = ({
|
|
|
185
206
|
</div>
|
|
186
207
|
|
|
187
208
|
<div className="grid grid-cols-3 gap-2">
|
|
188
|
-
{
|
|
209
|
+
{viewsToRender.map((view: any) => (
|
|
189
210
|
<PreviewButton
|
|
190
211
|
key={view.id}
|
|
191
212
|
view={view.label}
|
|
192
213
|
onClick={() => handleViewClick(view.id)}
|
|
214
|
+
backgroundClass={view.backgroundClass}
|
|
215
|
+
svg={view.svg}
|
|
216
|
+
isLoading={view.isLoading}
|
|
193
217
|
imageUrl={view.imageUrl}
|
|
194
218
|
status={view.status}
|
|
195
219
|
onLoad={view.onLoad}
|
|
@@ -225,6 +249,9 @@ export default React.memo(MobileSidebar)
|
|
|
225
249
|
function PreviewButton({
|
|
226
250
|
view,
|
|
227
251
|
onClick,
|
|
252
|
+
backgroundClass,
|
|
253
|
+
svg,
|
|
254
|
+
isLoading,
|
|
228
255
|
imageUrl,
|
|
229
256
|
status,
|
|
230
257
|
onLoad,
|
|
@@ -232,30 +259,38 @@ function PreviewButton({
|
|
|
232
259
|
}: {
|
|
233
260
|
view: string
|
|
234
261
|
onClick: () => void
|
|
262
|
+
backgroundClass?: string
|
|
263
|
+
svg?: string | null
|
|
264
|
+
isLoading?: boolean
|
|
235
265
|
imageUrl?: string
|
|
236
|
-
status
|
|
237
|
-
onLoad
|
|
238
|
-
onError
|
|
266
|
+
status?: "loading" | "loaded" | "error"
|
|
267
|
+
onLoad?: () => void
|
|
268
|
+
onError?: () => void
|
|
239
269
|
}) {
|
|
240
|
-
if (
|
|
270
|
+
if (!svg && !isLoading && !imageUrl) {
|
|
241
271
|
return null
|
|
242
272
|
}
|
|
243
273
|
|
|
244
274
|
return (
|
|
245
275
|
<button
|
|
246
276
|
onClick={onClick}
|
|
247
|
-
className=
|
|
277
|
+
className={`aspect-square ${backgroundClass ?? "bg-gray-100"} rounded-lg border border-gray-200 dark:border-[#30363d] flex items-center justify-center transition-colors mt-4 overflow-hidden`}
|
|
248
278
|
>
|
|
249
|
-
{status === "loading" && (
|
|
279
|
+
{(isLoading || status === "loading") && (
|
|
250
280
|
<Skeleton className="w-full h-full rounded-lg" />
|
|
251
281
|
)}
|
|
252
|
-
{
|
|
282
|
+
{!isLoading && !status && svg && (
|
|
283
|
+
<img
|
|
284
|
+
src={svgToDataUrl(normalizeSvgForSquareTile(svg))}
|
|
285
|
+
alt={view}
|
|
286
|
+
className="w-full h-full object-contain"
|
|
287
|
+
/>
|
|
288
|
+
)}
|
|
289
|
+
{imageUrl && !isLoading && (
|
|
253
290
|
<img
|
|
254
291
|
src={imageUrl}
|
|
255
292
|
alt={view}
|
|
256
|
-
className=
|
|
257
|
-
status === "loaded" ? "block" : "hidden"
|
|
258
|
-
}`}
|
|
293
|
+
className="w-full h-full object-cover rounded-lg"
|
|
259
294
|
onLoad={onLoad}
|
|
260
295
|
onError={onError}
|
|
261
296
|
/>
|
|
@@ -12,7 +12,7 @@ import { Lock, Globe } from "lucide-react"
|
|
|
12
12
|
import { GitFork, Package, Star } from "lucide-react"
|
|
13
13
|
|
|
14
14
|
import { useForkPackageMutation } from "@/hooks/use-fork-package-mutation"
|
|
15
|
-
import {
|
|
15
|
+
import { usePackageStarringByName } from "@/hooks/use-package-stars"
|
|
16
16
|
import { useOrderDialog } from "@tscircuit/runframe"
|
|
17
17
|
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
18
18
|
import { Package as PackageType } from "fake-snippets-api/lib/db/schema"
|
|
@@ -29,7 +29,7 @@ export default function PackageHeader({
|
|
|
29
29
|
isPrivate = false,
|
|
30
30
|
isCurrentUserAuthor = false,
|
|
31
31
|
}: PackageHeaderProps) {
|
|
32
|
-
const
|
|
32
|
+
const accountName = packageInfo?.owner_github_username
|
|
33
33
|
const packageName = packageInfo?.unscoped_name
|
|
34
34
|
const sessionToken = useGlobalStore((s) => s.session?.token)
|
|
35
35
|
const isOwner =
|
|
@@ -43,8 +43,8 @@ export default function PackageHeader({
|
|
|
43
43
|
packageReleaseId: packageInfo?.latest_package_release_id ?? "",
|
|
44
44
|
})
|
|
45
45
|
|
|
46
|
-
const {
|
|
47
|
-
packageInfo?.name ??
|
|
46
|
+
const { isStarred, starCount, toggleStar } = usePackageStarringByName(
|
|
47
|
+
packageInfo?.name ?? null,
|
|
48
48
|
)
|
|
49
49
|
|
|
50
50
|
const { mutateAsync: forkPackage, isLoading: isForkLoading } =
|
|
@@ -52,12 +52,7 @@ export default function PackageHeader({
|
|
|
52
52
|
|
|
53
53
|
const handleStarClick = async () => {
|
|
54
54
|
if (!packageInfo?.name || !isLoggedIn) return
|
|
55
|
-
|
|
56
|
-
if (packageInfo?.is_starred) {
|
|
57
|
-
await removeStar.mutateAsync()
|
|
58
|
-
} else {
|
|
59
|
-
await addStar.mutateAsync()
|
|
60
|
-
}
|
|
55
|
+
await toggleStar()
|
|
61
56
|
}
|
|
62
57
|
|
|
63
58
|
const handleForkClick = async () => {
|
|
@@ -65,8 +60,6 @@ export default function PackageHeader({
|
|
|
65
60
|
await forkPackage(packageInfo.package_id)
|
|
66
61
|
}
|
|
67
62
|
|
|
68
|
-
const isStarLoading = addStar.isLoading || removeStar.isLoading
|
|
69
|
-
|
|
70
63
|
useEffect(() => {
|
|
71
64
|
window.TSCIRCUIT_REGISTRY_API_BASE_URL =
|
|
72
65
|
import.meta.env.VITE_TSCIRCUIT_REGISTRY_API_URL ??
|
|
@@ -81,18 +74,18 @@ export default function PackageHeader({
|
|
|
81
74
|
<div className="max-w-[1200px] mx-auto px-4">
|
|
82
75
|
<div className="flex items-center justify-between flex-wrap gap-y-2">
|
|
83
76
|
<div className="flex items-center min-w-0 flex-wrap">
|
|
84
|
-
{
|
|
77
|
+
{accountName && packageName ? (
|
|
85
78
|
<>
|
|
86
79
|
<h1 className="text-lg md:text-xl font-bold mr-2 break-words">
|
|
87
80
|
<Link
|
|
88
|
-
href={`/${
|
|
81
|
+
href={`/${accountName}`}
|
|
89
82
|
className="text-blue-600 hover:underline"
|
|
90
83
|
>
|
|
91
|
-
{
|
|
84
|
+
{accountName}
|
|
92
85
|
</Link>
|
|
93
86
|
<span className="px-1 text-gray-500">/</span>
|
|
94
87
|
<Link
|
|
95
|
-
href={`/${
|
|
88
|
+
href={`/${accountName}/${packageName}`}
|
|
96
89
|
className="text-blue-600 hover:underline"
|
|
97
90
|
>
|
|
98
91
|
{packageName}
|
|
@@ -126,7 +119,12 @@ export default function PackageHeader({
|
|
|
126
119
|
</div>
|
|
127
120
|
|
|
128
121
|
<div className="hidden md:flex items-center space-x-2">
|
|
129
|
-
<Button
|
|
122
|
+
<Button
|
|
123
|
+
variant="outline"
|
|
124
|
+
size="sm"
|
|
125
|
+
onClick={open}
|
|
126
|
+
disabled={!packageInfo?.latest_package_release_id}
|
|
127
|
+
>
|
|
130
128
|
<Package className="w-4 h-4 mr-2" />
|
|
131
129
|
Order
|
|
132
130
|
</Button>
|
|
@@ -144,21 +142,17 @@ export default function PackageHeader({
|
|
|
144
142
|
: ""
|
|
145
143
|
}
|
|
146
144
|
onClick={handleStarClick}
|
|
147
|
-
disabled={
|
|
148
|
-
isStarLoading || !packageInfo?.name || !isLoggedIn
|
|
149
|
-
}
|
|
145
|
+
disabled={!packageInfo?.name || !isLoggedIn}
|
|
150
146
|
>
|
|
151
147
|
<Star
|
|
152
148
|
className={`w-4 h-4 mr-2 ${
|
|
153
|
-
|
|
154
|
-
? "fill-yellow-500 text-yellow-500"
|
|
155
|
-
: ""
|
|
149
|
+
isStarred ? "fill-yellow-500 text-yellow-500" : ""
|
|
156
150
|
}`}
|
|
157
151
|
/>
|
|
158
|
-
{
|
|
159
|
-
{(
|
|
152
|
+
{isStarred ? "Starred" : "Star"}
|
|
153
|
+
{(starCount ?? 0) > 0 && (
|
|
160
154
|
<span className="ml-1.5 bg-gray-100 text-gray-700 rounded-full px-1.5 py-0.5 text-xs font-medium">
|
|
161
|
-
{
|
|
155
|
+
{starCount}
|
|
162
156
|
</span>
|
|
163
157
|
)}
|
|
164
158
|
</Button>
|
|
@@ -220,19 +214,17 @@ export default function PackageHeader({
|
|
|
220
214
|
: ""
|
|
221
215
|
}
|
|
222
216
|
onClick={handleStarClick}
|
|
223
|
-
disabled={
|
|
217
|
+
disabled={!packageInfo?.name || !isLoggedIn}
|
|
224
218
|
>
|
|
225
219
|
<Star
|
|
226
220
|
className={`w-4 h-4 mr-2 ${
|
|
227
|
-
|
|
228
|
-
? "fill-yellow-500 text-yellow-500"
|
|
229
|
-
: ""
|
|
221
|
+
isStarred ? "fill-yellow-500 text-yellow-500" : ""
|
|
230
222
|
}`}
|
|
231
223
|
/>
|
|
232
|
-
{
|
|
233
|
-
{(
|
|
224
|
+
{isStarred ? "Starred" : "Star"}
|
|
225
|
+
{(starCount ?? 0) > 0 && (
|
|
234
226
|
<span className="ml-1.5 bg-gray-100 text-gray-700 rounded-full px-1.5 py-0.5 text-xs font-medium">
|
|
235
|
-
{
|
|
227
|
+
{starCount}
|
|
236
228
|
</span>
|
|
237
229
|
)}
|
|
238
230
|
</Button>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { Skeleton } from "@/components/ui/skeleton"
|
|
2
1
|
import { usePreviewImages } from "@/hooks/use-preview-images"
|
|
3
2
|
import type { Package } from "fake-snippets-api/lib/db/schema"
|
|
4
3
|
|
|
5
4
|
interface ViewPlaceholdersProps {
|
|
6
|
-
packageInfo?: Pick<
|
|
5
|
+
packageInfo?: Pick<
|
|
6
|
+
Package,
|
|
7
|
+
"name" | "latest_package_release_fs_sha" | "latest_package_release_id"
|
|
8
|
+
>
|
|
7
9
|
onViewChange?: (view: "3d" | "pcb" | "schematic") => void
|
|
8
10
|
}
|
|
9
11
|
|
|
@@ -15,7 +17,6 @@ export default function PreviewImageSquares({
|
|
|
15
17
|
packageName: packageInfo?.name,
|
|
16
18
|
fsMapHash: packageInfo?.latest_package_release_fs_sha ?? "",
|
|
17
19
|
})
|
|
18
|
-
|
|
19
20
|
const handleViewClick = (viewId: string) => {
|
|
20
21
|
onViewChange?.(viewId as "3d" | "pcb" | "schematic")
|
|
21
22
|
}
|
|
@@ -25,24 +26,16 @@ export default function PreviewImageSquares({
|
|
|
25
26
|
{availableViews.map((view) => (
|
|
26
27
|
<button
|
|
27
28
|
key={view.id}
|
|
28
|
-
className={`aspect-square bg-
|
|
29
|
+
className={`aspect-square ${view.status == "loading" ? "bg-slate-900/10 animate-pulse" : (view.backgroundClass ?? "bg-gray-100")} rounded-lg border border-gray-200 dark:border-[#30363d] flex items-center justify-center transition-colors overflow-hidden mb-6`}
|
|
29
30
|
onClick={() => handleViewClick(view.id)}
|
|
30
31
|
>
|
|
31
32
|
{view.imageUrl && (
|
|
32
|
-
|
|
33
|
-
{view.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
alt={view.label}
|
|
39
|
-
className={`w-full h-full object-cover rounded-lg ${
|
|
40
|
-
view.status === "loaded" ? "block" : "hidden"
|
|
41
|
-
}`}
|
|
42
|
-
onLoad={view.onLoad}
|
|
43
|
-
onError={view.onError}
|
|
44
|
-
/>
|
|
45
|
-
</>
|
|
33
|
+
<img
|
|
34
|
+
src={view.imageUrl}
|
|
35
|
+
className="w-full h-full object-cover rounded-lg"
|
|
36
|
+
onLoad={view.onLoad}
|
|
37
|
+
onError={view.onError}
|
|
38
|
+
/>
|
|
46
39
|
)}
|
|
47
40
|
</button>
|
|
48
41
|
))}
|
|
@@ -18,12 +18,12 @@ import Header from "@/components/Header"
|
|
|
18
18
|
import Footer from "@/components/Footer"
|
|
19
19
|
import PackageHeader from "./package-header"
|
|
20
20
|
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
21
|
-
import { useLocation } from "wouter"
|
|
22
21
|
import type {
|
|
23
22
|
Package,
|
|
24
23
|
PackageFile as ApiPackageFile,
|
|
25
24
|
} from "fake-snippets-api/lib/db/schema"
|
|
26
25
|
import { useRequestAiReviewMutation } from "@/hooks/use-request-ai-review-mutation"
|
|
26
|
+
import { useUpdateAiDescriptionMutation } from "@/hooks/use-update-ai-description-mutation"
|
|
27
27
|
import { useAiReview } from "@/hooks/use-ai-review"
|
|
28
28
|
import { useQueryClient } from "react-query"
|
|
29
29
|
import SidebarReleasesSection from "./sidebar-releases-section"
|
|
@@ -81,6 +81,9 @@ export default function RepoPageContent({
|
|
|
81
81
|
},
|
|
82
82
|
})
|
|
83
83
|
|
|
84
|
+
const { mutate: updateAiDescription, isLoading: isUpdatingAiDescription } =
|
|
85
|
+
useUpdateAiDescriptionMutation()
|
|
86
|
+
|
|
84
87
|
const aiReviewRequested =
|
|
85
88
|
Boolean(packageRelease?.ai_review_requested) ||
|
|
86
89
|
Boolean(pendingAiReviewId) ||
|
|
@@ -212,15 +215,12 @@ export default function RepoPageContent({
|
|
|
212
215
|
|
|
213
216
|
{/* Dynamic Content based on active view */}
|
|
214
217
|
{renderContent()}
|
|
215
|
-
|
|
216
218
|
{/* Important Files View - Always shown */}
|
|
217
219
|
<ImportantFilesView
|
|
218
220
|
importantFiles={importantFiles}
|
|
219
221
|
isFetched={arePackageFilesFetched}
|
|
222
|
+
pkg={packageInfo}
|
|
220
223
|
onEditClicked={onEditClicked}
|
|
221
|
-
packageAuthorOwner={packageInfo?.owner_github_username}
|
|
222
|
-
aiDescription={packageInfo?.ai_description ?? ""}
|
|
223
|
-
aiUsageInstructions={packageInfo?.ai_usage_instructions ?? ""}
|
|
224
224
|
aiReviewText={packageRelease?.ai_review_text ?? null}
|
|
225
225
|
aiReviewRequested={aiReviewRequested}
|
|
226
226
|
onRequestAiReview={() => {
|
|
@@ -230,6 +230,13 @@ export default function RepoPageContent({
|
|
|
230
230
|
})
|
|
231
231
|
}
|
|
232
232
|
}}
|
|
233
|
+
onRequestAiDescriptionUpdate={() => {
|
|
234
|
+
if (packageInfo) {
|
|
235
|
+
updateAiDescription({
|
|
236
|
+
package_id: packageInfo.package_id,
|
|
237
|
+
})
|
|
238
|
+
}
|
|
239
|
+
}}
|
|
233
240
|
onLicenseFileRequested={licenseFileRequested}
|
|
234
241
|
/>
|
|
235
242
|
</div>
|
|
@@ -2,12 +2,12 @@ import { Badge } from "@/components/ui/badge"
|
|
|
2
2
|
import { GitFork, Star, Settings, LinkIcon, Github, Plus } from "lucide-react"
|
|
3
3
|
import { Skeleton } from "@/components/ui/skeleton"
|
|
4
4
|
import { useCurrentPackageInfo } from "@/hooks/use-current-package-info"
|
|
5
|
-
import {
|
|
5
|
+
import { useCurrentPackageRelease } from "@/hooks/use-current-package-release"
|
|
6
6
|
import { useGlobalStore } from "@/hooks/use-global-store"
|
|
7
7
|
import { Button } from "@/components/ui/button"
|
|
8
8
|
import { useEditPackageDetailsDialog } from "@/components/dialogs/edit-package-details-dialog"
|
|
9
9
|
import { useState, useEffect, useMemo } from "react"
|
|
10
|
-
import {
|
|
10
|
+
import { usePackageFileById, usePackageFiles } from "@/hooks/use-package-files"
|
|
11
11
|
import { getLicenseFromLicenseContent } from "@/lib/getLicenseFromLicenseContent"
|
|
12
12
|
import { PackageInfo } from "@/lib/types"
|
|
13
13
|
|
|
@@ -21,23 +21,29 @@ export default function SidebarAboutSection({
|
|
|
21
21
|
onLicenseClick,
|
|
22
22
|
}: SidebarAboutSectionProps = {}) {
|
|
23
23
|
const { packageInfo, refetch: refetchPackageInfo } = useCurrentPackageInfo()
|
|
24
|
-
const {
|
|
24
|
+
const { packageRelease } = useCurrentPackageRelease({
|
|
25
|
+
include_ai_review: true,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const { data: releaseFiles } = usePackageFiles(
|
|
25
29
|
packageInfo?.latest_package_release_id,
|
|
26
30
|
)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
const licenseFileId = useMemo(() => {
|
|
32
|
+
return (
|
|
33
|
+
releaseFiles?.find((f) => f.file_path === "LICENSE")?.package_file_id ||
|
|
34
|
+
null
|
|
35
|
+
)
|
|
36
|
+
}, [releaseFiles])
|
|
37
|
+
const { data: licenseFileMeta } = usePackageFileById(licenseFileId)
|
|
32
38
|
const currentLicense = useMemo(() => {
|
|
33
39
|
if (packageInfo?.latest_license) {
|
|
34
40
|
return packageInfo?.latest_license
|
|
35
41
|
}
|
|
36
42
|
if (licenseFileMeta?.content_text) {
|
|
37
|
-
return getLicenseFromLicenseContent(licenseFileMeta
|
|
43
|
+
return getLicenseFromLicenseContent(licenseFileMeta.content_text)
|
|
38
44
|
}
|
|
39
45
|
return null
|
|
40
|
-
}, [licenseFileMeta])
|
|
46
|
+
}, [licenseFileMeta, packageInfo?.latest_license])
|
|
41
47
|
const topics = packageInfo?.is_package ? ["Package"] : ["Board"]
|
|
42
48
|
const isLoading = !packageInfo || !packageRelease
|
|
43
49
|
const isLoggedIn = useGlobalStore((s) => Boolean(s.session))
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Tag, Clock } from "lucide-react"
|
|
2
2
|
import { Skeleton } from "@/components/ui/skeleton"
|
|
3
3
|
import { useCurrentPackageInfo } from "@/hooks/use-current-package-info"
|
|
4
|
-
import {
|
|
4
|
+
import { useCurrentPackageRelease } from "@/hooks/use-current-package-release"
|
|
5
5
|
import { timeAgo } from "@/lib/utils/timeAgo"
|
|
6
6
|
import { BuildStatus, BuildStep } from "./build-status"
|
|
7
7
|
import type { PackageRelease } from "fake-snippets-api/lib/db/schema"
|
|
8
8
|
import { getBuildStatus, StatusIcon } from "@/components/preview"
|
|
9
|
-
import {
|
|
9
|
+
import { Link } from "wouter"
|
|
10
10
|
import { usePackageBuild } from "@/hooks/use-package-builds"
|
|
11
11
|
|
|
12
12
|
function getTranspilationStatus(
|
|
@@ -39,9 +39,9 @@ function getCircuitJsonStatus(pr?: PackageRelease | null): BuildStep["status"] {
|
|
|
39
39
|
|
|
40
40
|
export default function SidebarReleasesSection() {
|
|
41
41
|
const { packageInfo } = useCurrentPackageInfo()
|
|
42
|
-
const {
|
|
43
|
-
|
|
44
|
-
)
|
|
42
|
+
const { packageRelease } = useCurrentPackageRelease({
|
|
43
|
+
include_ai_review: true,
|
|
44
|
+
})
|
|
45
45
|
const { data: latestBuild } = usePackageBuild(
|
|
46
46
|
packageRelease?.latest_package_build_id ?? null,
|
|
47
47
|
)
|
|
@@ -80,21 +80,21 @@ export default function SidebarReleasesSection() {
|
|
|
80
80
|
return (
|
|
81
81
|
<div className="mb-6">
|
|
82
82
|
<h2 className="text-lg font-semibold mb-2">
|
|
83
|
-
<
|
|
83
|
+
<Link
|
|
84
84
|
href={`/${packageInfo?.owner_github_username}/${packageInfo?.unscoped_name}/releases`}
|
|
85
85
|
className="hover:underline"
|
|
86
86
|
>
|
|
87
87
|
Releases
|
|
88
|
-
</
|
|
88
|
+
</Link>
|
|
89
89
|
</h2>
|
|
90
90
|
<div className="flex flex-col space-y-2">
|
|
91
|
-
<
|
|
91
|
+
<Link
|
|
92
92
|
href={`/${packageInfo?.owner_github_username}/${packageInfo?.unscoped_name}/releases`}
|
|
93
93
|
className="flex items-center hover:underline"
|
|
94
94
|
>
|
|
95
95
|
<Tag className="h-4 w-4 mr-2 text-gray-500 dark:text-[#8b949e]" />
|
|
96
96
|
<span className="text-sm font-medium">v{packageRelease.version}</span>
|
|
97
|
-
</
|
|
97
|
+
</Link>
|
|
98
98
|
<div className="flex items-center">
|
|
99
99
|
<Clock className="h-4 w-4 mr-2 text-gray-500 dark:text-[#8b949e]" />
|
|
100
100
|
<span className="text-sm text-gray-500 dark:text-[#8b949e]">
|
|
@@ -109,13 +109,13 @@ export default function SidebarReleasesSection() {
|
|
|
109
109
|
/>
|
|
110
110
|
))}
|
|
111
111
|
{latestBuild && (
|
|
112
|
-
<
|
|
112
|
+
<Link
|
|
113
113
|
href={`/${packageInfo?.name}/releases`}
|
|
114
114
|
className="flex items-center gap-2 text-sm text-gray-500 dark:text-[#8b949e]"
|
|
115
115
|
>
|
|
116
116
|
<StatusIcon status={status} />
|
|
117
117
|
<span>Package Preview {label}</span>
|
|
118
|
-
</
|
|
118
|
+
</Link>
|
|
119
119
|
)}
|
|
120
120
|
</div>
|
|
121
121
|
{/* <a href="#" className="text-blue-600 dark:text-[#58a6ff] hover:underline text-sm">
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { usePackageFile, usePackageFileByPath } from "@/hooks/use-package-files"
|
|
2
1
|
import { PcbViewerWithContainerHeight } from "@/components/PcbViewerWithContainerHeight"
|
|
3
|
-
import { useEffect, useState } from "react"
|
|
4
2
|
import { useCurrentPackageCircuitJson } from "../../hooks/use-current-package-circuit-json"
|
|
5
3
|
|
|
6
4
|
export default function PCBView() {
|
|
@@ -27,6 +25,7 @@ export default function PCBView() {
|
|
|
27
25
|
return (
|
|
28
26
|
<div className="border border-gray-200 dark:border-[#30363d] rounded-md p-4 mb-4 bg-white dark:bg-[#0d1117]">
|
|
29
27
|
<PcbViewerWithContainerHeight
|
|
28
|
+
disablePcbGroups
|
|
30
29
|
clickToInteractEnabled
|
|
31
30
|
circuitJson={circuitJson}
|
|
32
31
|
containerClassName="w-full h-[620px]"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCurrentPackageCircuitJson } from "../../hooks/use-current-package-circuit-json"
|
|
2
|
-
import { SchematicViewer } from "@tscircuit/
|
|
2
|
+
import { SchematicViewer } from "@tscircuit/schematic-viewer"
|
|
3
3
|
|
|
4
4
|
export default function SchematicView() {
|
|
5
5
|
const { circuitJson, isLoading, error } = useCurrentPackageCircuitJson()
|
|
@@ -26,6 +26,7 @@ export default function SchematicView() {
|
|
|
26
26
|
return (
|
|
27
27
|
<div className="h-[620px]">
|
|
28
28
|
<SchematicViewer
|
|
29
|
+
disableGroups
|
|
29
30
|
clickToInteractEnabled
|
|
30
31
|
circuitJson={circuitJson}
|
|
31
32
|
containerStyle={{
|