mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-15 03:01:58 +08:00
84 lines
2.3 KiB
TypeScript
84 lines
2.3 KiB
TypeScript
import type { TFunction } from 'i18next';
|
|
import { IMAGE_FILE_EXTENSIONS } from '../constants/constants';
|
|
import type { FileTreeNode } from '../types/types';
|
|
|
|
export function filterFileTree(items: FileTreeNode[], query: string): FileTreeNode[] {
|
|
return items.reduce<FileTreeNode[]>((filteredItems, item) => {
|
|
const matchesName = item.name.toLowerCase().includes(query);
|
|
const filteredChildren =
|
|
item.type === 'directory' && item.children ? filterFileTree(item.children, query) : [];
|
|
|
|
if (matchesName || filteredChildren.length > 0) {
|
|
filteredItems.push({
|
|
...item,
|
|
children: filteredChildren,
|
|
});
|
|
}
|
|
|
|
return filteredItems;
|
|
}, []);
|
|
}
|
|
|
|
// During search we auto-expand every directory present in the filtered subtree.
|
|
export function collectExpandedDirectoryPaths(items: FileTreeNode[]): string[] {
|
|
const paths: string[] = [];
|
|
|
|
const visit = (nodes: FileTreeNode[]) => {
|
|
nodes.forEach((node) => {
|
|
if (node.type === 'directory' && node.children && node.children.length > 0) {
|
|
paths.push(node.path);
|
|
visit(node.children);
|
|
}
|
|
});
|
|
};
|
|
|
|
visit(items);
|
|
return paths;
|
|
}
|
|
|
|
export function formatFileSize(bytes?: number): string {
|
|
if (!bytes || bytes === 0) {
|
|
return '0 B';
|
|
}
|
|
|
|
const base = 1024;
|
|
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
const index = Math.floor(Math.log(bytes) / Math.log(base));
|
|
|
|
return `${(bytes / Math.pow(base, index)).toFixed(1).replace(/\.0$/, '')} ${sizes[index]}`;
|
|
}
|
|
|
|
export function formatRelativeTime(date: string | undefined, t: TFunction): string {
|
|
if (!date) {
|
|
return '-';
|
|
}
|
|
|
|
const now = new Date();
|
|
const past = new Date(date);
|
|
const diffInSeconds = Math.floor((now.getTime() - past.getTime()) / 1000);
|
|
|
|
if (diffInSeconds < 60) {
|
|
return t('fileTree.justNow');
|
|
}
|
|
|
|
if (diffInSeconds < 3600) {
|
|
return t('fileTree.minAgo', { count: Math.floor(diffInSeconds / 60) });
|
|
}
|
|
|
|
if (diffInSeconds < 86400) {
|
|
return t('fileTree.hoursAgo', { count: Math.floor(diffInSeconds / 3600) });
|
|
}
|
|
|
|
if (diffInSeconds < 2592000) {
|
|
return t('fileTree.daysAgo', { count: Math.floor(diffInSeconds / 86400) });
|
|
}
|
|
|
|
return past.toLocaleDateString();
|
|
}
|
|
|
|
export function isImageFile(filename: string): boolean {
|
|
const extension = filename.split('.').pop()?.toLowerCase();
|
|
return Boolean(extension && IMAGE_FILE_EXTENSIONS.has(extension));
|
|
}
|
|
|