Skip to content

Commit 2bd658b

Browse files
committed
Update framework recognition
1 parent 731f4d5 commit 2bd658b

File tree

3 files changed

+155
-62
lines changed

3 files changed

+155
-62
lines changed

web/src/gui/deployments/files/FileExplorer.tsx

Lines changed: 24 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,17 @@ import * as Collapsible from '@radix-ui/react-collapsible';
22
import byteSize from 'byte-size';
33
import clsx from 'clsx';
44
import { FC, useState } from 'react';
5-
import {
6-
LuChevronRight,
7-
LuFile,
8-
LuFileCode,
9-
LuFileCog,
10-
LuFileImage,
11-
LuFileJson,
12-
LuFileText,
13-
LuFileType,
14-
LuFolderClosed,
15-
LuFolderOpen,
16-
} from 'react-icons/lu';
5+
import { LuChevronRight, LuFolderClosed, LuFolderOpen } from 'react-icons/lu';
176

187
import { useDeploymentFiles } from '@/api';
198
import { components } from '@/api/schema.gen';
9+
import {
10+
getFrameworkColor,
11+
getFrameworkIcon,
12+
useFramework,
13+
} from '@/util/files/detection';
14+
import { mimeTypeToColor } from '@/util/files/mime';
15+
import { CustomFileIcon } from '@/util/files/mime';
2016

2117
type DeploymentFile = components['schemas']['DeploymentFileEntry'];
2218

@@ -86,8 +82,12 @@ export const FileExplorer: FC<{ siteId: string; deploymentId: string }> = ({
8682

8783
return (
8884
<div className="card space-y-3">
89-
<div className="space-y-2">
85+
<div className="flex justify-between">
9086
<div className="font-bold">File Explorer</div>
87+
<FrameworkDetection
88+
siteId={siteId}
89+
deploymentId={deploymentId}
90+
/>
9191
</div>
9292
<div className="bg-secondary rounded-md border">
9393
<TreeEntry node={tree} name="/" isRoot hideRoot />
@@ -226,54 +226,16 @@ export const FileEntry: FC<{ file: DeploymentFile; name: string }> = ({
226226
);
227227
};
228228

229-
export const CustomFileIcon: FC<{ mime_type: string }> = ({ mime_type }) => {
230-
if (mime_type === 'text/html') {
231-
return <LuFileText />;
232-
}
233-
234-
if (mime_type === 'text/xml') {
235-
return <LuFileText />;
236-
}
237-
238-
if (
239-
[
240-
'image/png',
241-
'image/jpeg',
242-
'image/gif',
243-
'image/svg+xml',
244-
'image/webp',
245-
].includes(mime_type)
246-
) {
247-
return <LuFileImage />;
248-
}
249-
250-
if (
251-
[
252-
'application/font-woff',
253-
'application/font-woff2',
254-
'application/font-sfnt',
255-
].includes(mime_type)
256-
) {
257-
return <LuFileType />;
258-
}
259-
260-
if (mime_type === 'text/css') {
261-
return <LuFileCog />;
262-
}
229+
export const FrameworkDetection: FC<{
230+
siteId: string;
231+
deploymentId: string;
232+
}> = ({ siteId, deploymentId }) => {
233+
const framework = useFramework(siteId, deploymentId);
263234

264-
if (mime_type === 'text/javascript') {
265-
return <LuFileCode />;
266-
}
267-
268-
if (mime_type === 'application/json') {
269-
return <LuFileJson />;
270-
}
271-
272-
return <LuFile />;
273-
};
274-
275-
export const mimeTypeToColor = (mime_type: string) => {
276-
if (mime_type === 'text/html') {
277-
return 'text-yellow-500';
278-
}
235+
return (
236+
<div className="text-muted flex items-center gap-2">
237+
{getFrameworkIcon(framework)}
238+
<span className={getFrameworkColor(framework)}>{framework}</span>
239+
</div>
240+
);
279241
};

web/src/util/files/detection.tsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { useMemo } from 'react';
2+
import { SiAstro, SiMdbook, SiNextdotjs } from 'react-icons/si';
3+
4+
import { useDeploymentFiles } from '@/api';
5+
import { components } from '@/api/schema.gen';
6+
7+
type DeploymentFileEntry = components['schemas']['DeploymentFileEntry'];
8+
9+
type Frameworks = 'nextjs' | 'svelte' | 'sveltekit' | 'astro' | 'mdbook';
10+
11+
const patternMatch: Record<string, Frameworks> = {
12+
'/_next/*': 'nextjs',
13+
'/book.js': 'mdbook',
14+
'/_astro/*': 'astro',
15+
};
16+
17+
export const detectFramework = (
18+
files: DeploymentFileEntry[]
19+
): Frameworks | undefined => {
20+
for (const file of files) {
21+
const path = '/' + file.deployment_file_file_path;
22+
23+
for (const pattern in patternMatch) {
24+
if (new RegExp(pattern).test(path)) {
25+
return patternMatch[pattern];
26+
}
27+
}
28+
}
29+
30+
return 'mdbook';
31+
};
32+
33+
export const useFramework = (siteId: string, deploymentId: string) => {
34+
const { data: files } = useDeploymentFiles(siteId, deploymentId);
35+
36+
return useMemo(() => {
37+
if (!files) return 'mdbook';
38+
39+
return detectFramework(files);
40+
}, [files]);
41+
};
42+
43+
export const getFrameworkIcon = (framework?: Frameworks) => {
44+
switch (framework) {
45+
case 'nextjs':
46+
return <SiNextdotjs />;
47+
case 'astro':
48+
return <SiAstro />;
49+
case 'mdbook':
50+
return <SiMdbook />;
51+
}
52+
53+
return <></>;
54+
};
55+
56+
export const getFrameworkColor = (framework?: Frameworks) => {
57+
switch (framework) {
58+
case 'nextjs':
59+
return 'text-blue-500';
60+
case 'svelte':
61+
return 'text-purple-500';
62+
case 'sveltekit':
63+
return 'text-purple-500';
64+
case 'astro':
65+
return 'text-[#ff5c02]';
66+
case 'mdbook':
67+
return 'text-gray-500';
68+
}
69+
};

web/src/util/files/mime.tsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { FC } from 'react';
2+
import {
3+
LuFile,
4+
LuFileCode,
5+
LuFileCog,
6+
LuFileImage,
7+
LuFileJson,
8+
LuFileText,
9+
LuFileType,
10+
} from 'react-icons/lu';
11+
12+
export const CustomFileIcon: FC<{ mime_type: string }> = ({ mime_type }) => {
13+
if (mime_type === 'text/html') {
14+
return <LuFileText />;
15+
}
16+
17+
if (mime_type === 'text/xml') {
18+
return <LuFileText />;
19+
}
20+
21+
if (
22+
[
23+
'image/png',
24+
'image/jpeg',
25+
'image/gif',
26+
'image/svg+xml',
27+
'image/webp',
28+
].includes(mime_type)
29+
) {
30+
return <LuFileImage />;
31+
}
32+
33+
if (
34+
[
35+
'application/font-woff',
36+
'application/font-woff2',
37+
'application/font-sfnt',
38+
].includes(mime_type)
39+
) {
40+
return <LuFileType />;
41+
}
42+
43+
if (mime_type === 'text/css') {
44+
return <LuFileCog />;
45+
}
46+
47+
if (mime_type === 'text/javascript') {
48+
return <LuFileCode />;
49+
}
50+
51+
if (mime_type === 'application/json') {
52+
return <LuFileJson />;
53+
}
54+
55+
return <LuFile />;
56+
};
57+
58+
export const mimeTypeToColor = (mime_type: string) => {
59+
if (mime_type === 'text/html') {
60+
return 'text-yellow-500';
61+
}
62+
};

0 commit comments

Comments
 (0)