mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 17:38:04 +08:00
Frontend: - Migrate deprecated imports: modal→dialog, toast→ui/toast, tooltip→tooltip-plus, portal-to-follow-elem→portal-to-follow-elem-plus, select→ui/select, confirm→alert-dialog - Replace next/* with @/next/* wrapper modules - Convert TypeScript enums to const objects (erasable-syntax-only) - Replace all `any` types with `unknown` or specific types in workflow types - Fix unused vars, react-hooks-extra, react-refresh/only-export-components - Extract InteractionMode to separate module, tool-block commands to commands.ts Backend: - Fix pyrefly errors: type narrowing, null guards, getattr patterns - Remove unused TYPE_CHECKING imports in LLM node - Add ignore_imports entries to .importlinter for dify_graph boundary violations Made-with: Cursor
99 lines
2.6 KiB
TypeScript
99 lines
2.6 KiB
TypeScript
'use client'
|
|
|
|
import * as React from 'react'
|
|
import Loading from '@/app/components/base/loading'
|
|
import dynamic from '@/next/dynamic'
|
|
import { useFetchTextContent } from '../hooks/use-fetch-text-content'
|
|
import { useFileTypeInfo } from '../hooks/use-file-type-info'
|
|
import { getFileLanguage } from '../utils/file-utils'
|
|
import MediaFilePreview from './media-file-preview'
|
|
import UnsupportedFileDownload from './unsupported-file-download'
|
|
|
|
const ReadOnlyCodePreview = dynamic(
|
|
() => import('./read-only-code-preview'),
|
|
{ ssr: false, loading: () => <Loading type="area" /> },
|
|
)
|
|
|
|
const ReadOnlyMarkdownPreview = dynamic(
|
|
() => import('./read-only-markdown-preview'),
|
|
{ ssr: false, loading: () => <Loading type="area" /> },
|
|
)
|
|
|
|
const SQLiteFilePreview = dynamic(
|
|
() => import('./sqlite-file-preview'),
|
|
{ ssr: false, loading: () => <Loading type="area" /> },
|
|
)
|
|
|
|
const PdfFilePreview = dynamic(
|
|
() => import('./pdf-file-preview'),
|
|
{ ssr: false, loading: () => <Loading type="area" /> },
|
|
)
|
|
|
|
type ReadOnlyFilePreviewProps = {
|
|
downloadUrl: string
|
|
fileName: string
|
|
extension?: string | null
|
|
fileSize?: number | null
|
|
}
|
|
|
|
const ReadOnlyFilePreview = ({
|
|
downloadUrl,
|
|
fileName,
|
|
extension,
|
|
fileSize,
|
|
}: ReadOnlyFilePreviewProps) => {
|
|
const fileNode = React.useMemo(
|
|
() => ({ name: fileName, extension }),
|
|
[fileName, extension],
|
|
)
|
|
const { isMarkdown, isCodeOrText, isImage, isVideo, isPdf, isSQLite, isPreviewable } = useFileTypeInfo(fileNode)
|
|
const isTextFile = isPreviewable && (isMarkdown || isCodeOrText)
|
|
const { data: textContent, isLoading: isTextLoading } = useFetchTextContent(
|
|
isTextFile ? downloadUrl : undefined,
|
|
)
|
|
|
|
if (!isPreviewable) {
|
|
return (
|
|
<UnsupportedFileDownload
|
|
name={fileName}
|
|
size={fileSize ?? undefined}
|
|
downloadUrl={downloadUrl}
|
|
/>
|
|
)
|
|
}
|
|
|
|
if (isTextFile && isTextLoading)
|
|
return <Loading type="area" />
|
|
|
|
if (isMarkdown)
|
|
return <ReadOnlyMarkdownPreview value={textContent ?? ''} />
|
|
|
|
if (isCodeOrText) {
|
|
return (
|
|
<ReadOnlyCodePreview
|
|
value={textContent ?? ''}
|
|
language={getFileLanguage(fileName)}
|
|
/>
|
|
)
|
|
}
|
|
|
|
if (isImage || isVideo)
|
|
return <MediaFilePreview type={isImage ? 'image' : 'video'} src={downloadUrl} />
|
|
|
|
if (isSQLite)
|
|
return <SQLiteFilePreview downloadUrl={downloadUrl} />
|
|
|
|
if (isPdf)
|
|
return <PdfFilePreview downloadUrl={downloadUrl} />
|
|
|
|
return (
|
|
<UnsupportedFileDownload
|
|
name={fileName}
|
|
size={fileSize ?? undefined}
|
|
downloadUrl={downloadUrl}
|
|
/>
|
|
)
|
|
}
|
|
|
|
export default React.memo(ReadOnlyFilePreview)
|