mirror of
https://github.com/lordmathis/lemma.git
synced 2025-12-23 01:54:28 +00:00
92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
import { API_BASE_URL } from '@/types/api';
|
|
import { IMAGE_EXTENSIONS, type FileNode } from '@/types/models';
|
|
|
|
/**
|
|
* Represents a flattened file for searching and autocompletion
|
|
*/
|
|
export interface FlatFile {
|
|
name: string; // "meeting-notes.md"
|
|
path: string; // "work/2024/meeting-notes.md"
|
|
displayPath: string; // "work/2024/meeting-notes"
|
|
nameWithoutExt: string; // "meeting-notes"
|
|
parentFolder: string; // "work/2024"
|
|
isImage: boolean;
|
|
}
|
|
|
|
/**
|
|
* Checks if the given file path has an image extension.
|
|
* @param filePath - The file path to check.
|
|
* @returns True if the file path has an image extension, false otherwise.
|
|
*/
|
|
export const isImageFile = (filePath: string): boolean => {
|
|
return IMAGE_EXTENSIONS.some((ext) => filePath.toLowerCase().endsWith(ext));
|
|
};
|
|
|
|
export const getFileUrl = (workspaceName: string, filePath: string) => {
|
|
return `${API_BASE_URL}/workspaces/${encodeURIComponent(
|
|
workspaceName
|
|
)}/files/content?file_path=${encodeURIComponent(filePath)}`;
|
|
};
|
|
|
|
/**
|
|
* Recursively flattens FileNode tree into searchable array
|
|
* Precomputes display strings and metadata for performance
|
|
*
|
|
* @param nodes - Array of FileNode from the file tree
|
|
* @param showHiddenFiles - Whether to include hidden files (files/folders starting with .)
|
|
* @returns Array of FlatFile objects ready for searching
|
|
*/
|
|
export function flattenFileTree(nodes: FileNode[], showHiddenFiles = false): FlatFile[] {
|
|
const result: FlatFile[] = [];
|
|
|
|
function traverse(node: FileNode) {
|
|
// Skip hidden files and folders if showHiddenFiles is false
|
|
// Hidden files/folders are those that start with a dot (.)
|
|
if (!showHiddenFiles && node.name.startsWith('.')) {
|
|
return;
|
|
}
|
|
|
|
// Only process files, not folders (folders have children)
|
|
if (!node.children) {
|
|
const name = node.name;
|
|
const path = node.path;
|
|
const isImage = isImageFile(path);
|
|
|
|
// Remove extension for display (except for images)
|
|
let nameWithoutExt = name;
|
|
let displayPath = path;
|
|
|
|
if (name.endsWith('.md')) {
|
|
nameWithoutExt = name.slice(0, -3);
|
|
displayPath = path.slice(0, -3);
|
|
}
|
|
|
|
// Get parent folder path
|
|
const lastSlashIndex = path.lastIndexOf('/');
|
|
const parentFolder = lastSlashIndex > 0 ? path.slice(0, lastSlashIndex) : '';
|
|
|
|
result.push({
|
|
name,
|
|
path,
|
|
displayPath,
|
|
nameWithoutExt,
|
|
parentFolder,
|
|
isImage,
|
|
});
|
|
}
|
|
|
|
// Recursively process children
|
|
if (node.children) {
|
|
for (const child of node.children) {
|
|
traverse(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const node of nodes) {
|
|
traverse(node);
|
|
}
|
|
|
|
return result;
|
|
}
|