Calude güncellemesi FileManager optimizasyon

This commit is contained in:
Sedat ÖZTÜRK 2026-08-09 12:08:57 +03:00
parent a01ce1533a
commit b9550acda2
3 changed files with 681 additions and 761 deletions

View file

@ -25,6 +25,8 @@ export interface FileManagerClipboard {
operation: 'copy' | 'cut'
items: FileItem[]
sourceFolder?: string
/** Tenant the items were copied/cut from. Paste is rejected across tenants. */
sourceTenantId?: string
}
export interface FileManagerState {

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,12 @@
import { forwardRef, useState, useEffect, type ChangeEvent, type MouseEvent } from 'react'
import {
forwardRef,
memo,
useState,
useEffect,
type ChangeEvent,
type MouseEvent,
type ReactNode,
} from 'react'
import classNames from 'classnames'
import {
FaFolder,
@ -120,6 +128,28 @@ const getFileTypeLabel = (item: FileItemType, translate: (key: string) => string
return extension?.toUpperCase() || translate('::FileManager.File')
}
// Defined at module level: nesting it inside FileItem would remount the <img>
// (and restart the download) on every parent render.
const ImagePreview = ({ src, alt, fallback }: { src: string; alt: string; fallback: ReactNode }) => {
const [imageError, setImageError] = useState(false)
return (
<div className="w-full h-full bg-gray-100 dark:bg-gray-700 rounded flex items-center justify-center overflow-hidden">
{!imageError ? (
<img
src={src}
alt={alt}
loading="lazy"
className="max-w-full max-h-full object-cover"
onError={() => setImageError(true)}
/>
) : (
<div className="flex items-center justify-center w-full h-full">{fallback}</div>
)}
</div>
)
}
const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
const {
item,
@ -332,28 +362,6 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
</div>
)
// Resim preview komponenti
const ImagePreview = ({ src, alt }: { src: string; alt: string }) => {
const [imageError, setImageError] = useState(false)
return (
<div className="w-full h-full bg-gray-100 dark:bg-gray-700 rounded flex items-center justify-center overflow-hidden">
{!imageError ? (
<img
src={src}
alt={alt}
className="max-w-full max-h-full object-cover"
onError={() => setImageError(true)}
/>
) : (
<div className="flex items-center justify-center w-full h-full">
{getFileIcon(item, false)}
</div>
)}
</div>
)
}
if (viewMode === 'list') {
return (
<>
@ -389,7 +397,11 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
{/* File Icon or Preview */}
<div className="w-8 h-8">
{item.type === 'file' && item.mimeType?.startsWith('image/') ? (
<ImagePreview src={FILE_URL(item.path, item.tenantId)} alt={item.name} />
<ImagePreview
src={FILE_URL(item.path, item.tenantId)}
alt={item.name}
fallback={getFileIcon(item, false)}
/>
) : (
<div className="w-full h-full flex items-center justify-center">
{getFileIcon(item, false)}
@ -484,7 +496,11 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
<div className="flex justify-center mb-3">
{item.type === 'file' && item.mimeType?.startsWith('image/') ? (
<div className="w-16 h-16">
<ImagePreview src={FILE_URL(item.path, item.tenantId)} alt={item.name} />
<ImagePreview
src={FILE_URL(item.path, item.tenantId)}
alt={item.name}
fallback={getFileIcon(item, false)}
/>
</div>
) : (
<div className="flex justify-center">{getFileIcon(item, true)}</div>
@ -535,4 +551,4 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((props, ref) => {
FileItem.displayName = 'FileItem'
export default FileItem
export default memo(FileItem)