mirror of
https://github.com/langgenius/dify.git
synced 2026-03-09 09:26:42 +08:00
feat: use blacklist approach for file editability in Monaco Editor
Switch from whitelist to blacklist pattern for determining editable files. Files are now editable unless they are known binary types (audio, archives, executables, Office documents, fonts, etc.), enabling support for any runtime-generated text files without needing to add extensions one by one.
This commit is contained in:
@ -2,9 +2,9 @@ import type { AppAssetTreeView } from '@/types/app-asset'
|
||||
import { useMemo } from 'react'
|
||||
import {
|
||||
getFileExtension,
|
||||
isCodeOrTextFile,
|
||||
isImageFile,
|
||||
isMarkdownFile,
|
||||
isTextLikeFile,
|
||||
isVideoFile,
|
||||
} from '../utils/file-utils'
|
||||
|
||||
@ -17,24 +17,21 @@ export type FileTypeInfo = {
|
||||
isMediaFile: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to determine file type information based on file node.
|
||||
* Returns flags for markdown, code/text, image, video files.
|
||||
*/
|
||||
export function useFileTypeInfo(fileNode: AppAssetTreeView | undefined): FileTypeInfo {
|
||||
return useMemo(() => {
|
||||
const ext = getFileExtension(fileNode?.name, fileNode?.extension)
|
||||
const markdown = isMarkdownFile(ext)
|
||||
const codeOrText = isCodeOrTextFile(ext)
|
||||
const image = isImageFile(ext)
|
||||
const video = isVideoFile(ext)
|
||||
const editable = isTextLikeFile(ext)
|
||||
const codeOrText = editable && !markdown
|
||||
|
||||
return {
|
||||
isMarkdown: markdown,
|
||||
isCodeOrText: codeOrText,
|
||||
isImage: image,
|
||||
isVideo: video,
|
||||
isEditable: markdown || codeOrText,
|
||||
isEditable: editable,
|
||||
isMediaFile: image || video,
|
||||
}
|
||||
}, [fileNode?.name, fileNode?.extension])
|
||||
|
||||
@ -12,7 +12,7 @@ import {
|
||||
useCreateAppAssetFolder,
|
||||
useRenameAppAssetNode,
|
||||
} from '@/service/use-app-asset'
|
||||
import { getFileExtension, isCodeOrTextFile, isMarkdownFile } from '../utils/file-utils'
|
||||
import { getFileExtension, isTextLikeFile } from '../utils/file-utils'
|
||||
import { createDraftTreeNode, insertDraftTreeNode } from '../utils/tree-utils'
|
||||
|
||||
type UseInlineCreateNodeOptions = {
|
||||
@ -86,7 +86,7 @@ export function useInlineCreateNode({
|
||||
parentId: pendingCreateParentId,
|
||||
})
|
||||
const extension = getFileExtension(trimmedName, createdFile.extension)
|
||||
if (isMarkdownFile(extension) || isCodeOrTextFile(extension))
|
||||
if (isTextLikeFile(extension))
|
||||
storeApi.getState().openTab(createdFile.id, { pinned: true })
|
||||
Toast.notify({
|
||||
type: 'success',
|
||||
|
||||
@ -2,10 +2,80 @@ import { FileAppearanceTypeEnum } from '@/app/components/base/file-uploader/type
|
||||
|
||||
const MARKDOWN_EXTENSIONS = ['md', 'markdown', 'mdx']
|
||||
const CODE_EXTENSIONS = ['json', 'yaml', 'yml', 'toml', 'js', 'jsx', 'ts', 'tsx', 'py', 'schema']
|
||||
const TEXT_EXTENSIONS = ['txt', 'log', 'ini', 'env']
|
||||
const IGNORE_EXTENSIONS = ['gitignore', 'dockerignore', 'prettierignore', 'eslintignore', 'npmignore', 'hgignore']
|
||||
const IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp', 'ico']
|
||||
const VIDEO_EXTENSIONS = ['mp4', 'mov', 'webm', 'mpeg', 'mpg', 'm4v', 'avi']
|
||||
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 BINARY_EXTENSIONS = [
|
||||
'mp3',
|
||||
'wav',
|
||||
'ogg',
|
||||
'flac',
|
||||
'm4a',
|
||||
'aac',
|
||||
'wma',
|
||||
'aiff',
|
||||
'opus',
|
||||
'zip',
|
||||
'tar',
|
||||
'gz',
|
||||
'rar',
|
||||
'7z',
|
||||
'bz2',
|
||||
'xz',
|
||||
'tgz',
|
||||
'tbz2',
|
||||
'lz',
|
||||
'lzma',
|
||||
'cab',
|
||||
'iso',
|
||||
'dmg',
|
||||
'exe',
|
||||
'dll',
|
||||
'so',
|
||||
'dylib',
|
||||
'bin',
|
||||
'o',
|
||||
'obj',
|
||||
'class',
|
||||
'pyc',
|
||||
'pyo',
|
||||
'pyd',
|
||||
'wasm',
|
||||
'app',
|
||||
'msi',
|
||||
'deb',
|
||||
'rpm',
|
||||
'pdf',
|
||||
'doc',
|
||||
'docx',
|
||||
'xls',
|
||||
'xlsx',
|
||||
'ppt',
|
||||
'pptx',
|
||||
'odt',
|
||||
'ods',
|
||||
'odp',
|
||||
'rtf',
|
||||
'epub',
|
||||
'mobi',
|
||||
'ttf',
|
||||
'otf',
|
||||
'woff',
|
||||
'woff2',
|
||||
'eot',
|
||||
'db',
|
||||
'sqlite',
|
||||
'sqlite3',
|
||||
'mdb',
|
||||
'accdb',
|
||||
'jar',
|
||||
'war',
|
||||
'ear',
|
||||
'apk',
|
||||
'ipa',
|
||||
'aab',
|
||||
'lock',
|
||||
]
|
||||
|
||||
export function getFileExtension(name?: string, extension?: string): string {
|
||||
if (extension)
|
||||
@ -31,8 +101,12 @@ export function isMarkdownFile(extension: string): boolean {
|
||||
return MARKDOWN_EXTENSIONS.includes(extension)
|
||||
}
|
||||
|
||||
export function isCodeOrTextFile(extension: string): boolean {
|
||||
return CODE_EXTENSIONS.includes(extension) || TEXT_EXTENSIONS.includes(extension) || IGNORE_EXTENSIONS.includes(extension)
|
||||
export function isBinaryFile(extension: string): boolean {
|
||||
return BINARY_EXTENSIONS.includes(extension)
|
||||
}
|
||||
|
||||
export function isTextLikeFile(extension: string): boolean {
|
||||
return !isBinaryFile(extension) && !isImageFile(extension) && !isVideoFile(extension)
|
||||
}
|
||||
|
||||
export function isImageFile(extension: string): boolean {
|
||||
|
||||
Reference in New Issue
Block a user