mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 18:08:07 +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 { useMemo } from 'react'
|
||||||
import {
|
import {
|
||||||
getFileExtension,
|
getFileExtension,
|
||||||
isCodeOrTextFile,
|
|
||||||
isImageFile,
|
isImageFile,
|
||||||
isMarkdownFile,
|
isMarkdownFile,
|
||||||
|
isTextLikeFile,
|
||||||
isVideoFile,
|
isVideoFile,
|
||||||
} from '../utils/file-utils'
|
} from '../utils/file-utils'
|
||||||
|
|
||||||
@ -17,24 +17,21 @@ export type FileTypeInfo = {
|
|||||||
isMediaFile: boolean
|
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 {
|
export function useFileTypeInfo(fileNode: AppAssetTreeView | undefined): FileTypeInfo {
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
const ext = getFileExtension(fileNode?.name, fileNode?.extension)
|
const ext = getFileExtension(fileNode?.name, fileNode?.extension)
|
||||||
const markdown = isMarkdownFile(ext)
|
const markdown = isMarkdownFile(ext)
|
||||||
const codeOrText = isCodeOrTextFile(ext)
|
|
||||||
const image = isImageFile(ext)
|
const image = isImageFile(ext)
|
||||||
const video = isVideoFile(ext)
|
const video = isVideoFile(ext)
|
||||||
|
const editable = isTextLikeFile(ext)
|
||||||
|
const codeOrText = editable && !markdown
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isMarkdown: markdown,
|
isMarkdown: markdown,
|
||||||
isCodeOrText: codeOrText,
|
isCodeOrText: codeOrText,
|
||||||
isImage: image,
|
isImage: image,
|
||||||
isVideo: video,
|
isVideo: video,
|
||||||
isEditable: markdown || codeOrText,
|
isEditable: editable,
|
||||||
isMediaFile: image || video,
|
isMediaFile: image || video,
|
||||||
}
|
}
|
||||||
}, [fileNode?.name, fileNode?.extension])
|
}, [fileNode?.name, fileNode?.extension])
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import {
|
|||||||
useCreateAppAssetFolder,
|
useCreateAppAssetFolder,
|
||||||
useRenameAppAssetNode,
|
useRenameAppAssetNode,
|
||||||
} from '@/service/use-app-asset'
|
} 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'
|
import { createDraftTreeNode, insertDraftTreeNode } from '../utils/tree-utils'
|
||||||
|
|
||||||
type UseInlineCreateNodeOptions = {
|
type UseInlineCreateNodeOptions = {
|
||||||
@ -86,7 +86,7 @@ export function useInlineCreateNode({
|
|||||||
parentId: pendingCreateParentId,
|
parentId: pendingCreateParentId,
|
||||||
})
|
})
|
||||||
const extension = getFileExtension(trimmedName, createdFile.extension)
|
const extension = getFileExtension(trimmedName, createdFile.extension)
|
||||||
if (isMarkdownFile(extension) || isCodeOrTextFile(extension))
|
if (isTextLikeFile(extension))
|
||||||
storeApi.getState().openTab(createdFile.id, { pinned: true })
|
storeApi.getState().openTab(createdFile.id, { pinned: true })
|
||||||
Toast.notify({
|
Toast.notify({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
|
|||||||
@ -2,10 +2,80 @@ import { FileAppearanceTypeEnum } from '@/app/components/base/file-uploader/type
|
|||||||
|
|
||||||
const MARKDOWN_EXTENSIONS = ['md', 'markdown', 'mdx']
|
const MARKDOWN_EXTENSIONS = ['md', 'markdown', 'mdx']
|
||||||
const CODE_EXTENSIONS = ['json', 'yaml', 'yml', 'toml', 'js', 'jsx', 'ts', 'tsx', 'py', 'schema']
|
const CODE_EXTENSIONS = ['json', 'yaml', 'yml', 'toml', 'js', 'jsx', 'ts', 'tsx', 'py', 'schema']
|
||||||
const TEXT_EXTENSIONS = ['txt', 'log', 'ini', 'env']
|
const IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp', 'ico', 'tiff', 'psd', 'heic', 'heif', 'avif']
|
||||||
const IGNORE_EXTENSIONS = ['gitignore', 'dockerignore', 'prettierignore', 'eslintignore', 'npmignore', 'hgignore']
|
const VIDEO_EXTENSIONS = ['mp4', 'mov', 'webm', 'mpeg', 'mpg', 'm4v', 'avi', 'mkv', 'flv', 'wmv', '3gp']
|
||||||
const IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp', 'ico']
|
|
||||||
const VIDEO_EXTENSIONS = ['mp4', 'mov', 'webm', 'mpeg', 'mpg', 'm4v', 'avi']
|
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 {
|
export function getFileExtension(name?: string, extension?: string): string {
|
||||||
if (extension)
|
if (extension)
|
||||||
@ -31,8 +101,12 @@ export function isMarkdownFile(extension: string): boolean {
|
|||||||
return MARKDOWN_EXTENSIONS.includes(extension)
|
return MARKDOWN_EXTENSIONS.includes(extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isCodeOrTextFile(extension: string): boolean {
|
export function isBinaryFile(extension: string): boolean {
|
||||||
return CODE_EXTENSIONS.includes(extension) || TEXT_EXTENSIONS.includes(extension) || IGNORE_EXTENSIONS.includes(extension)
|
return BINARY_EXTENSIONS.includes(extension)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isTextLikeFile(extension: string): boolean {
|
||||||
|
return !isBinaryFile(extension) && !isImageFile(extension) && !isVideoFile(extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isImageFile(extension: string): boolean {
|
export function isImageFile(extension: string): boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user