Fix file rename bugs and hide file extensions
All checks were successful
Automated Container Build / build-and-push (push) Successful in 34s
All checks were successful
Automated Container Build / build-and-push (push) Successful in 34s
This commit is contained in:
parent
5200654d0f
commit
99e0cd5f0c
2 changed files with 51 additions and 17 deletions
|
|
@ -46,6 +46,20 @@ interface UploadProgress {
|
|||
error?: string;
|
||||
}
|
||||
|
||||
function getFileDisplayName(name: string, isDir: boolean) {
|
||||
if (isDir) return name;
|
||||
const dotIndex = name.lastIndexOf('.');
|
||||
if (dotIndex > 0) return name.substring(0, dotIndex);
|
||||
return name;
|
||||
}
|
||||
|
||||
function getFileExtension(name: string, isDir: boolean) {
|
||||
if (isDir) return '';
|
||||
const dotIndex = name.lastIndexOf('.');
|
||||
if (dotIndex > 0) return name.substring(dotIndex);
|
||||
return '';
|
||||
}
|
||||
|
||||
export default function FileExplorer({ onLogout }: FileExplorerProps) {
|
||||
const [currentPath, setCurrentPath] = useState(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
|
|
@ -324,6 +338,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
|
|||
}
|
||||
|
||||
function handleFileClick(file: FileItem, e: React.MouseEvent) {
|
||||
if (renaming === file.path) return;
|
||||
if (e.shiftKey) {
|
||||
// Multi-select with shift
|
||||
setSelectedFiles(prev => {
|
||||
|
|
@ -406,9 +421,20 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
|
|||
}
|
||||
}
|
||||
|
||||
async function handleRename(path: string) {
|
||||
if (!newName.trim()) return;
|
||||
await api.rename(path, newName);
|
||||
async function handleRename(path: string, originalName: string, isDir: boolean) {
|
||||
if (!newName.trim()) {
|
||||
setRenaming(null);
|
||||
setNewName('');
|
||||
return;
|
||||
}
|
||||
const ext = getFileExtension(originalName, isDir);
|
||||
const finalName = newName.trim() + ext;
|
||||
if (finalName === originalName) {
|
||||
setRenaming(null);
|
||||
setNewName('');
|
||||
return;
|
||||
}
|
||||
await api.rename(path, finalName);
|
||||
setRenaming(null);
|
||||
setNewName('');
|
||||
loadFiles();
|
||||
|
|
@ -785,7 +811,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
|
|||
<div className="w-4 h-4 flex items-center justify-center flex-shrink-0 [&>svg]:w-4 [&>svg]:h-4">
|
||||
{getFileIcon(file)}
|
||||
</div>
|
||||
<span className="truncate flex-1">{file.name}</span>
|
||||
<span className="truncate flex-1" title={getFileDisplayName(file.name, file.is_dir)}>{getFileDisplayName(file.name, file.is_dir)}</span>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
|
|
@ -1141,10 +1167,11 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
|
|||
type="text"
|
||||
value={newName}
|
||||
onChange={(e) => setNewName(e.target.value)}
|
||||
onKeyDown={(e) => { if (e.key === 'Enter') handleRename(file.path); if (e.key === 'Escape') setRenaming(null); }}
|
||||
onBlur={() => handleRename(file.path)}
|
||||
onKeyDown={(e) => { if (e.key === 'Enter') handleRename(file.path, file.name, file.is_dir); if (e.key === 'Escape') setRenaming(null); }}
|
||||
onBlur={() => handleRename(file.path, file.name, file.is_dir)}
|
||||
autoFocus
|
||||
onFocus={(e) => e.target.select()}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="w-full text-xs text-center bg-transparent outline-none"
|
||||
style={{
|
||||
color: 'var(--color-text-primary)',
|
||||
|
|
@ -1155,9 +1182,9 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
|
|||
<span
|
||||
className="text-xs font-medium text-center w-full truncate"
|
||||
style={{ color: 'var(--color-text-primary)' }}
|
||||
title={file.name}
|
||||
title={getFileDisplayName(file.name, file.is_dir)}
|
||||
>
|
||||
{file.name}
|
||||
{getFileDisplayName(file.name, file.is_dir)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -1221,15 +1248,16 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
|
|||
type="text"
|
||||
value={newName}
|
||||
onChange={(e) => setNewName(e.target.value)}
|
||||
onKeyDown={(e) => { if (e.key === 'Enter') handleRename(file.path); if (e.key === 'Escape') setRenaming(null); }}
|
||||
onBlur={() => handleRename(file.path)}
|
||||
onKeyDown={(e) => { if (e.key === 'Enter') handleRename(file.path, file.name, file.is_dir); if (e.key === 'Escape') setRenaming(null); }}
|
||||
onBlur={() => handleRename(file.path, file.name, file.is_dir)}
|
||||
autoFocus
|
||||
onFocus={(e) => e.target.select()}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="flex-1 text-sm bg-transparent outline-none"
|
||||
style={{ color: 'var(--color-text-primary)', borderBottom: '1px solid var(--color-accent)' }}
|
||||
/>
|
||||
) : (
|
||||
<span className="text-sm truncate" style={{ color: 'var(--color-text-primary)' }}>{file.name}</span>
|
||||
<span className="text-sm truncate" style={{ color: 'var(--color-text-primary)' }} title={getFileDisplayName(file.name, file.is_dir)}>{getFileDisplayName(file.name, file.is_dir)}</span>
|
||||
)}
|
||||
{file.is_pinned && <Pin className="w-3 h-3 flex-shrink-0" style={{ color: 'var(--color-warning)' }} />}
|
||||
</div>
|
||||
|
|
@ -1376,7 +1404,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
|
|||
label="Rename"
|
||||
onClick={() => {
|
||||
setRenaming(contextMenu.file.path);
|
||||
setNewName(contextMenu.file.name);
|
||||
setNewName(getFileDisplayName(contextMenu.file.name, contextMenu.file.is_dir));
|
||||
setContextMenu(null);
|
||||
}}
|
||||
/>
|
||||
|
|
@ -1490,9 +1518,9 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
|
|||
<span
|
||||
className="text-xs font-medium truncate max-w-[200px]"
|
||||
style={{ color: 'var(--color-text-primary)' }}
|
||||
title={upload.name}
|
||||
title={getFileDisplayName(upload.name, false)}
|
||||
>
|
||||
{upload.name}
|
||||
{getFileDisplayName(upload.name, false)}
|
||||
</span>
|
||||
<span className="text-xs" style={{ color: 'var(--color-text-tertiary)' }}>
|
||||
{upload.status === 'complete' ? '✓' : upload.status === 'error' ? '✗' : `${Math.round(upload.progress)}%`}
|
||||
|
|
|
|||
Reference in a new issue