diff --git a/web/app/components/workflow/skill/file-content-panel.tsx b/web/app/components/workflow/skill/file-content-panel.tsx
index eceb6a97e3..7e207b183f 100644
--- a/web/app/components/workflow/skill/file-content-panel.tsx
+++ b/web/app/components/workflow/skill/file-content-panel.tsx
@@ -56,7 +56,7 @@ const FileContentPanel = () => {
const currentFileNode = fileTabId ? nodeMap?.get(fileTabId) : undefined
- const { isMarkdown, isCodeOrText, isImage, isVideo, isSQLite, isEditable } = useFileTypeInfo(currentFileNode)
+ const { isMarkdown, isCodeOrText, isImage, isVideo, isSQLite, isEditable, isPreviewable } = useFileTypeInfo(currentFileNode)
const { fileContent, downloadUrlData, isLoading, error } = useSkillFileData(appId, fileTabId, isEditable)
@@ -210,7 +210,7 @@ const FileContentPanel = () => {
const downloadUrl = downloadUrlData?.download_url || ''
const fileName = currentFileNode?.name || ''
const fileSize = currentFileNode?.size
- const isUnsupportedFile = !isMarkdown && !isCodeOrText && !isImage && !isVideo && !isSQLite
+ const isUnsupportedFile = !isPreviewable
return (
diff --git a/web/app/components/workflow/skill/hooks/use-file-type-info.ts b/web/app/components/workflow/skill/hooks/use-file-type-info.ts
index a867950c44..b582deb6c1 100644
--- a/web/app/components/workflow/skill/hooks/use-file-type-info.ts
+++ b/web/app/components/workflow/skill/hooks/use-file-type-info.ts
@@ -16,11 +16,25 @@ export type FileTypeInfo = {
isSQLite: boolean
isEditable: boolean
isMediaFile: boolean
+ isPreviewable: boolean
}
export function useFileTypeInfo(fileNode: { name: string, extension?: string | null } | undefined): FileTypeInfo {
return useMemo(() => {
- const ext = getFileExtension(fileNode?.name, fileNode?.extension ?? undefined)
+ if (!fileNode) {
+ return {
+ isMarkdown: false,
+ isCodeOrText: false,
+ isImage: false,
+ isVideo: false,
+ isSQLite: false,
+ isEditable: false,
+ isMediaFile: false,
+ isPreviewable: false,
+ }
+ }
+
+ const ext = getFileExtension(fileNode.name, fileNode.extension ?? undefined)
const markdown = isMarkdownFile(ext)
const image = isImageFile(ext)
const video = isVideoFile(ext)
@@ -36,6 +50,7 @@ export function useFileTypeInfo(fileNode: { name: string, extension?: string | n
isSQLite: sqlite,
isEditable: editable,
isMediaFile: image || video,
+ isPreviewable: editable || image || video || sqlite,
}
}, [fileNode?.name, fileNode?.extension])
}
diff --git a/web/app/components/workflow/skill/utils/file-utils.ts b/web/app/components/workflow/skill/utils/file-utils.ts
index ae8e6d4148..811e9c57ae 100644
--- a/web/app/components/workflow/skill/utils/file-utils.ts
+++ b/web/app/components/workflow/skill/utils/file-utils.ts
@@ -1,12 +1,12 @@
import { FileAppearanceTypeEnum } from '@/app/components/base/file-uploader/types'
-const MARKDOWN_EXTENSIONS = ['md', 'markdown', 'mdx']
-const CODE_EXTENSIONS = ['json', 'yaml', 'yml', 'toml', 'js', 'jsx', 'ts', 'tsx', 'py', 'schema']
-const IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp', 'ico', 'tiff', 'psd', 'heic', 'heif', 'avif']
-const VIDEO_EXTENSIONS = ['mp4', 'mov', 'webm', 'mpeg', 'mpg', 'm4v', 'avi', 'mkv', 'flv', 'wmv', '3gp']
-const SQLITE_EXTENSIONS = ['db', 'sqlite', 'sqlite3']
+const MARKDOWN_EXTENSIONS = new Set(['md', 'markdown', 'mdx'])
+const CODE_EXTENSIONS = new Set(['json', 'yaml', 'yml', 'toml', 'js', 'jsx', 'ts', 'tsx', 'py', 'schema'])
+const IMAGE_EXTENSIONS = new Set(['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp', 'ico', 'tiff', 'psd', 'heic', 'heif', 'avif'])
+const VIDEO_EXTENSIONS = new Set(['mp4', 'mov', 'webm', 'mpeg', 'mpg', 'm4v', 'avi', 'mkv', 'flv', 'wmv', '3gp'])
+const SQLITE_EXTENSIONS = new Set(['db', 'sqlite', 'sqlite3'])
-const BINARY_EXTENSIONS = [
+const BINARY_EXTENSIONS = new Set([
'mp3',
'wav',
'ogg',
@@ -76,7 +76,7 @@ const BINARY_EXTENSIONS = [
'ipa',
'aab',
'lock',
-]
+])
export function getFileExtension(name?: string, extension?: string): string {
if (extension)
@@ -105,8 +105,8 @@ const EXTENSION_TO_ICON_TYPE = new Map(
[PPT_EXTENSIONS, FileAppearanceTypeEnum.ppt],
[CODE_EXTENSIONS, FileAppearanceTypeEnum.code],
[SQLITE_EXTENSIONS, FileAppearanceTypeEnum.database],
- ] as [string[], FileAppearanceTypeEnum][]).flatMap(
- ([exts, type]) => exts.map(e => [e, type] as [string, FileAppearanceTypeEnum]),
+ ] as [Iterable, FileAppearanceTypeEnum][]).flatMap(
+ ([exts, type]) => [...exts].map(e => [e, type] as [string, FileAppearanceTypeEnum]),
),
)
@@ -116,11 +116,11 @@ export function getFileIconType(name: string, ext?: string | null): FileAppearan
}
export function isMarkdownFile(extension: string): boolean {
- return MARKDOWN_EXTENSIONS.includes(extension)
+ return MARKDOWN_EXTENSIONS.has(extension)
}
export function isBinaryFile(extension: string): boolean {
- return BINARY_EXTENSIONS.includes(extension)
+ return BINARY_EXTENSIONS.has(extension)
}
export function isTextLikeFile(extension: string): boolean {
@@ -128,15 +128,15 @@ export function isTextLikeFile(extension: string): boolean {
}
export function isImageFile(extension: string): boolean {
- return IMAGE_EXTENSIONS.includes(extension)
+ return IMAGE_EXTENSIONS.has(extension)
}
export function isVideoFile(extension: string): boolean {
- return VIDEO_EXTENSIONS.includes(extension)
+ return VIDEO_EXTENSIONS.has(extension)
}
export function isSQLiteFile(extension: string): boolean {
- return SQLITE_EXTENSIONS.includes(extension)
+ return SQLITE_EXTENSIONS.has(extension)
}
export function getFileLanguage(name: string): string {
diff --git a/web/app/components/workflow/skill/viewer/read-only-file-preview.tsx b/web/app/components/workflow/skill/viewer/read-only-file-preview.tsx
index deb5c9a060..8d59d002f1 100644
--- a/web/app/components/workflow/skill/viewer/read-only-file-preview.tsx
+++ b/web/app/components/workflow/skill/viewer/read-only-file-preview.tsx
@@ -41,12 +41,22 @@ const ReadOnlyFilePreview = ({
() => ({ name: fileName, extension }),
[fileName, extension],
)
- const { isMarkdown, isCodeOrText, isImage, isVideo, isSQLite } = useFileTypeInfo(fileNode)
- const isTextFile = isMarkdown || isCodeOrText
+ const { isMarkdown, isCodeOrText, isImage, isVideo, isSQLite, isPreviewable } = useFileTypeInfo(fileNode)
+ const isTextFile = isPreviewable && (isMarkdown || isCodeOrText)
const { data: textContent, isLoading: isTextLoading } = useFetchTextContent(
isTextFile ? downloadUrl : undefined,
)
+ if (!isPreviewable) {
+ return (
+
+ )
+ }
+
if (isTextFile && isTextLoading)
return