Files tab: multi-selection, drag-and-drop, keyboard shortcuts, custom confirm modal, SVG icons
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
export function formatFileSize(bytes) {
|
||||
if (bytes == null || bytes < 0) return '—'
|
||||
if (bytes === 0) return '0 B'
|
||||
const units = ['B', 'KB', 'MB', 'GB']
|
||||
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1)
|
||||
const val = bytes / Math.pow(1024, i)
|
||||
return (i === 0 ? val.toFixed(0) : val.toFixed(1)) + ' ' + units[i]
|
||||
}
|
||||
|
||||
const mimeLabels = {
|
||||
'image/jpeg': 'JPEG image',
|
||||
'image/png': 'PNG image',
|
||||
'image/gif': 'GIF image',
|
||||
'image/webp': 'WebP image',
|
||||
'image/svg+xml': 'SVG image',
|
||||
'image/bmp': 'BMP image',
|
||||
'image/tiff': 'TIFF image',
|
||||
'image/avif': 'AVIF image',
|
||||
'application/pdf': 'PDF document',
|
||||
'application/msword': 'Word document',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'Word document',
|
||||
'application/vnd.ms-excel': 'Excel spreadsheet',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'Excel spreadsheet',
|
||||
'application/vnd.ms-powerpoint': 'PowerPoint presentation',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'PowerPoint presentation',
|
||||
'application/zip': 'ZIP archive',
|
||||
'application/gzip': 'GZIP archive',
|
||||
'application/x-tar': 'TAR archive',
|
||||
'application/x-7z-compressed': '7z archive',
|
||||
'application/x-rar-compressed': 'RAR archive',
|
||||
'text/plain': 'Text file',
|
||||
'text/html': 'HTML file',
|
||||
'text/css': 'CSS file',
|
||||
'text/javascript': 'JavaScript file',
|
||||
'application/json': 'JSON file',
|
||||
'application/xml': 'XML file',
|
||||
'application/x-yaml': 'YAML file',
|
||||
'application/octet-stream': 'Binary file',
|
||||
'application/x-msdos-program': 'Executable',
|
||||
'inode/directory': 'Folder',
|
||||
}
|
||||
|
||||
export function formatMimeType(mime) {
|
||||
if (!mime) return 'Unknown'
|
||||
return mimeLabels[mime] || mime
|
||||
}
|
||||
|
||||
export function getFileKind(item) {
|
||||
if (item.type === 'folder') return 'folder'
|
||||
const mime = (item.mime || '').toLowerCase()
|
||||
if (mime.startsWith('image/')) return 'image'
|
||||
if (mime.startsWith('video/')) return 'video'
|
||||
if (mime.startsWith('audio/')) return 'audio'
|
||||
if (mime.startsWith('text/')) return 'text'
|
||||
if (mime.includes('pdf')) return 'pdf'
|
||||
if (mime.includes('word') || mime.includes('document')) return 'document'
|
||||
if (mime.includes('spreadsheet') || mime.includes('excel')) return 'spreadsheet'
|
||||
if (mime.includes('presentation') || mime.includes('powerpoint')) return 'presentation'
|
||||
if (mime.includes('zip') || mime.includes('tar') || mime.includes('gzip') || mime.includes('rar') || mime.includes('7z') || mime.includes('compress')) return 'archive'
|
||||
if (mime.includes('json') || mime.includes('xml') || mime.includes('yaml') || mime.includes('javascript') || mime.includes('css') || mime.includes('html')) return 'code'
|
||||
const name = (item.name || '').toLowerCase()
|
||||
const ext = name.split('.').pop()
|
||||
const codeExts = ['js','ts','jsx','tsx','vue','svelte','py','rs','go','c','cpp','h','hpp','java','kt','swift','rb','php','pl','sh','bash','zsh','fish','yml','yaml','json','xml','toml','ini','cfg','conf','md','markdown','css','scss','less','sass','sql','graphql','proto','gradle','cmake','makefile','dockerfile','env','gitignore']
|
||||
if (codeExts.includes(ext)) return 'code'
|
||||
return 'generic'
|
||||
}
|
||||
|
||||
const imageMimes = ['image/jpeg','image/png','image/gif','image/webp','image/bmp','image/tiff','image/avif','image/svg+xml']
|
||||
const textMimes = ['text/plain','text/html','text/css','text/javascript','application/json','application/xml','application/x-yaml','text/x-shellscript']
|
||||
const codeNames = ['txt','log','conf','ini','yaml','yml','json','xml','csv','sh','py','js','ts','css','html','md','markdown','cfg']
|
||||
|
||||
const imageExts = ['jpg','jpeg','png','gif','webp','bmp','tiff','tif','avif','svg']
|
||||
|
||||
export function canPreviewFile(item) {
|
||||
if (item.type === 'folder') return false
|
||||
const mime = (item.mime || '').toLowerCase()
|
||||
const name = (item.name || '').toLowerCase()
|
||||
const ext = name.split('.').pop()
|
||||
if (imageMimes.includes(mime) || imageExts.includes(ext)) return true
|
||||
if (mime.includes('pdf')) return true
|
||||
if (textMimes.includes(mime) || codeNames.includes(ext)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
export function isImageFile(item) {
|
||||
const mime = (item.mime || '').toLowerCase()
|
||||
const name = (item.name || '').toLowerCase()
|
||||
const ext = name.split('.').pop()
|
||||
return imageMimes.includes(mime) || imageExts.includes(ext)
|
||||
}
|
||||
|
||||
export function isTextFile(item) {
|
||||
const mime = (item.mime || '').toLowerCase()
|
||||
const name = (item.name || '').toLowerCase()
|
||||
const ext = name.split('.').pop()
|
||||
return textMimes.includes(mime) || (codeNames.includes(ext) && ext !== 'md' && ext !== 'markdown')
|
||||
}
|
||||
|
||||
export function isPdfFile(item) {
|
||||
return (item.mime || '').toLowerCase().includes('pdf')
|
||||
}
|
||||
|
||||
export function isMarkdownFile(item) {
|
||||
const name = (item.name || '').toLowerCase()
|
||||
return name.endsWith('.md') || name.endsWith('.markdown')
|
||||
}
|
||||
|
||||
export function needsBase64Preview(item) {
|
||||
return isImageFile(item) || isPdfFile(item)
|
||||
}
|
||||
|
||||
export function needsTextPreview(item) {
|
||||
return isTextFile(item) || isMarkdownFile(item)
|
||||
}
|
||||
Reference in New Issue
Block a user