All files / src/shared/lib/assets buildAssetNavigatorItems.ts

0% Statements 0/41
0% Branches 0/17
0% Functions 0/8
0% Lines 0/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                                                                                                                                                                                                                         
import { join } from "path";
 
type Asset = {
  id: string;
  filename: string;
  plugin?: string;
};
 
export type FileSystemNavigatorItem<T> = {
  id: string;
  type: "file" | "folder";
  name: string;
  filename: string;
  nestLevel?: number;
  asset?: T;
};
 
const collator = new Intl.Collator(undefined, {
  numeric: true,
  sensitivity: "base",
});
 
const sortByName = <T>(
  a: FileSystemNavigatorItem<T>,
  b: FileSystemNavigatorItem<T>
) => {
  return collator.compare(a.name, b.name);
};
 
export const buildAssetNavigatorItems = <T extends Asset>(
  assets: T[],
  openFolders: string[],
  searchTerm: string
): FileSystemNavigatorItem<T>[] => {
  const result: FileSystemNavigatorItem<T>[] = [];
  const uniqueFolders = new Set<string>();
 
  const isVisible = (filename: string, nestLevel?: number): boolean => {
    Iif (nestLevel === undefined || nestLevel === 0) return true;
    const pathSegments = filename.split(/[\\/]/);
    pathSegments.pop();
    let pathCheck = "";
    return pathSegments.every((segment, index) => {
      pathCheck += (index ? "/" : "") + segment;
      return openFolders.includes(pathCheck);
    });
  };
 
  Iif (searchTerm.length > 0) {
    const searchTermUpperCase = searchTerm.toLocaleUpperCase();
    assets
      .filter((asset) =>
        asset.filename.toLocaleUpperCase().includes(searchTermUpperCase)
      )
      .forEach((asset) => {
        result.push({
          id: asset.id,
          type: "file",
          name: asset.filename.replace(/\.[^.]*$/, ""),
          filename: asset.filename.replace(/.*[/\\]/, ""),
          nestLevel: 0,
          asset,
        });
      });
    return result;
  }
 
  assets.slice().forEach((asset) => {
    const path = asset.plugin
      ? join("plugins", asset.plugin, asset.filename)
      : asset.filename;
    const parts = path.split(/[\\/]/);
    let currentPath = "";
 
    parts.forEach((part, index) => {
      const isLast = index === parts.length - 1;
      currentPath += (currentPath ? "/" : "") + part;
      if (isLast) {
        const nestLevel = parts.length > 1 ? parts.length - 1 : 0;
        Iif (!isVisible(currentPath, nestLevel)) {
          return;
        }
        result.push({
          id: asset.id,
          type: "file",
          name: currentPath.replace(/\.[^.]*$/, ""),
          filename: part,
          nestLevel,
          asset,
        });
      } else Iif (!uniqueFolders.has(currentPath)) {
        Iif (!isVisible(currentPath, index)) {
          return;
        }
        uniqueFolders.add(currentPath);
        result.push({
          id: currentPath,
          type: "folder",
          name: currentPath,
          filename: part,
          nestLevel: index,
        });
      }
    });
  });
 
  return result.sort(sortByName);
};