Skip to content

Commit

Permalink
feat(example-app): sort project tree nodes by name
Browse files Browse the repository at this point in the history
  • Loading branch information
alirezamirian committed Nov 26, 2023
1 parent 8593119 commit 0a341d8
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 7 deletions.
38 changes: 32 additions & 6 deletions packages/example-app/src/ProjectView/ProjectView.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { currentProjectState, Project } from "../Project/project.state";
import { dirContentState, FsItem } from "../fs/fs.state";
import { filterPath } from "../Project/project-utils";
import { getParentPaths } from "../file-utils";
import * as path from "path";
import { vcsRootsState } from "../VersionControl/file-status.state";
import { notNull } from "@intellij-platform/core/utils/array-utils";

Expand Down Expand Up @@ -73,6 +72,32 @@ export const currentProjectTreeState = selector({
},
});

type FilesTreeSort = "name"; // more to be added

// TODO: add more sort options and add "Tree Appearance" option in Project tool window settings menu.
export const projectTreeSortState = atom<FilesTreeSort>({
key: "project.tree.sort",
default: "name",
});

/**
* NOTE: using in-place native sort for performance.
* See more https://www.measurethat.net/Benchmarks/Show/6698/0/ramda-sort-vs-js-native-sort
*/
function sortProjectTreeNodes(items: FileTreeNode[]): void {
// TODO: add sortBy: FileTreeSort parameter
// TODO: add directoriesOnTop: boolean parameter
items.sort((item1, item2) => {
if (item1.name < item2.name) {
return -1;
}
if (item1.name > item2.name) {
return 1;
}
return 0;
});
}

// NOTE: this function could be sync, and those `await`s before `get` are unnecessary. They are there simply because
// I didn't realize `get` returns the value, not Promise. But interestingly, when this function is made sync,
// performance drastically drops for some reason. That needs to be investigated.
Expand All @@ -84,10 +109,8 @@ async function createProjectTree(
const mapItem =
(parent: FileTreeDirNode | null) =>
async (item: FsItem): Promise<FileTreeNode | null> => {
const name = path.basename(item.path);
const node = {
...item,
name,
parent,
};
const dirNode: FileTreeDirNode = { ...node, children: [] };
Expand All @@ -100,21 +123,24 @@ async function createProjectTree(
)
)
).filter(notNull);
sortProjectTreeNodes(dirNode.children);
return dirNode;
}
return null;
}
return node;
};

const children = (
await Promise.all((rootItems || []).map(mapItem(null)))
).filter(notNull);
sortProjectTreeNodes(children);
return {
type: "project",
path: project.path,
name: project.name,
parent: null,
children: (await Promise.all((rootItems || []).map(mapItem(null)))).filter(
notNull
),
children,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function FileItem({
matches: null | TextRange[];
}) {
const { isSelected } = useContext(ItemStateContext) || {};
const title = path.basename(file.relativePath);
const title = file.name;
const dir = path.dirname(file.relativePath);

const [dirMatches, filenameMatches] = splitWhen<TextRange, TextRange>(
Expand Down
5 changes: 5 additions & 0 deletions packages/example-app/src/fs/fs.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import {
} from "recoil";
import { fs } from "./fs";
import { Stats } from "@isomorphic-git/lightning-fs";
import { basename } from "path";

export interface FsItem {
type: "dir" | "file";
name: string;
path: string;
lastModification: number;
size: number;
}

Expand Down Expand Up @@ -40,7 +43,9 @@ export const dirContentState = selectorFamily({
);
return stats.map((stat) => ({
type: stat.type,
name: basename(stat.filePath),
path: stat.filePath,
lastModification: stat.mtimeMs,
size: stat.size,
}));
},
Expand Down

0 comments on commit 0a341d8

Please sign in to comment.