Fix file explorer folder overview depth issue

and also added a tooltip above the depth slider
This commit is contained in:
Lost Paul 2024-12-31 23:06:49 +01:00
parent b3e0c0c1b3
commit 5106b6f471
4 changed files with 46 additions and 44 deletions

View file

@ -61,6 +61,7 @@ export class FileExplorerOverview {
if (!folderElement && !tFolder) return;
// wait until the file explorer is loaded
const sourceFolderPath = tFolder?.path || '';
folderElement = document.querySelectorAll('.nav-files-container')[0] as HTMLElement;
if (!folderElement) return;
@ -108,7 +109,7 @@ export class FileExplorerOverview {
folderOverview.on('vault-change', handleVaultChange);
if (tFolder instanceof TFolder) {
await this.addFiles(tFolder.children, overviewList, folderOverview);
await this.addFiles(tFolder.children, overviewList, folderOverview, sourceFolderPath);
}
newFolderElement.querySelectorAll('div.tree-item-icon').forEach((el) => {
@ -117,7 +118,7 @@ export class FileExplorerOverview {
const path = el.parentElement?.getAttribute('data-path');
if (!path) return;
const folder = plugin.app.vault.getAbstractFileByPath(path);
this.handleCollapseClick(el, plugin, yaml, this.pathBlacklist, source, folderOverview, folder);
this.handleCollapseClick(el, plugin, yaml, this.pathBlacklist, sourceFolderPath, folderOverview, folder);
}
}
});
@ -131,15 +132,16 @@ export class FileExplorerOverview {
};
}
async addFiles(files: TAbstractFile[], childrenElement: HTMLElement, folderOverview: FolderOverview) {
async addFiles(files: TAbstractFile[], childrenElement: HTMLElement, folderOverview: FolderOverview, sourceFolderPath: string) {
const plugin = folderOverview.plugin;
const sortedFiles = folderOverview.sortFiles(files);
const allFiles = await folderOverview.filterFiles(files, plugin, sourceFolderPath, folderOverview.yaml.depth, folderOverview.pathBlacklist);
const sortedFiles = folderOverview.sortFiles(allFiles);
const folders = sortedFiles.filter(child => child instanceof TFolder);
const otherFiles = sortedFiles.filter(child => child instanceof TFile);
for (const child of folders) {
await this.createFolderEL(plugin, child, folderOverview, childrenElement);
await this.createFolderEL(plugin, child, folderOverview, childrenElement, sourceFolderPath);
}
for (const child of otherFiles) {
@ -148,7 +150,7 @@ export class FileExplorerOverview {
}
async handleCollapseClick(el: HTMLElement, plugin: FolderNotesPlugin, yaml: yamlSettings, pathBlacklist: string[], sourcePath: string, folderOverview: FolderOverview, folder?: TFolder | undefined | null | TAbstractFile) {
async handleCollapseClick(el: HTMLElement, plugin: FolderNotesPlugin, yaml: yamlSettings, pathBlacklist: string[], sourceFolderPath: string, folderOverview: FolderOverview, folder?: TFolder | undefined | null | TAbstractFile) {
el.classList.toggle('is-collapsed');
if (el.classList.contains('is-collapsed')) {
if (!(folder instanceof TFolder)) return;
@ -161,13 +163,12 @@ export class FileExplorerOverview {
if (!folderElement) return;
const childrenElement = folderElement.createDiv({ cls: 'tree-item-children nav-folder-children' });
let files = folderOverview.sortFiles(folder.children);
files = folderOverview.filterFiles(files, plugin, folder.path, yaml.depth || 1, pathBlacklist);
await this.addFiles(files, childrenElement, folderOverview);
files = await folderOverview.filterFiles(files, plugin, folder.path, yaml.depth || 1, pathBlacklist);
await this.addFiles(files, childrenElement, folderOverview, sourceFolderPath);
}
}
async createFolderEL(plugin: FolderNotesPlugin, child: TFolder, folderOverview: FolderOverview, childrenElement: HTMLElement) {
console.log('createFolderEL');
async createFolderEL(plugin: FolderNotesPlugin, child: TFolder, folderOverview: FolderOverview, childrenElement: HTMLElement, sourceFolderPath: string) {
const pathBlacklist = folderOverview.pathBlacklist;
const source = folderOverview.source;
const folderNote = getFolderNote(plugin, child.path);
@ -181,7 +182,6 @@ export class FileExplorerOverview {
const svg = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon right-triangle"><path d="M3 8L12 17L21 8"></path></svg>';
if (yaml.includeTypes.includes('folder')) {
console.log('folder');
folderElement = childrenElement.createDiv({
cls: 'tree-item nav-folder',
});
@ -202,7 +202,7 @@ export class FileExplorerOverview {
folderTitleText.onclick = () => {
const collapseIcon = folderTitle?.querySelectorAll('.tree-item-icon')[0] as HTMLElement;
if (collapseIcon) {
this.handleCollapseClick(collapseIcon, plugin, yaml, pathBlacklist, source, folderOverview, child);
this.handleCollapseClick(collapseIcon, plugin, yaml, pathBlacklist, sourceFolderPath, folderOverview, child);
}
}
}
@ -250,14 +250,15 @@ export class FileExplorerOverview {
folderTitle?.classList.remove('is-collapsed');
const childrenElement = folderElement?.createDiv({ cls: 'tree-item-children nav-folder-children' });
if (childrenElement) {
await this.addFiles(child.children, childrenElement, folderOverview);
await this.addFiles(child.children, childrenElement, folderOverview, sourceFolderPath);
}
} else {
await this.addFiles(child.children, childrenElement, folderOverview);
await this.addFiles(child.children, childrenElement, folderOverview, sourceFolderPath);
}
} else {
folderTitle?.classList.add('is-collapsed');
}
if (folderNote) { folderTitle?.classList.add('has-folder-note') }
if (folderNote && child.children.length === 1 && yaml.disableCollapseIcon) { folderTitle?.classList.add('fn-has-no-files') }
@ -272,13 +273,12 @@ export class FileExplorerOverview {
if (collapseIcon) {
collapseIcon.innerHTML = svg;
collapseIcon.onclick = () => {
this.handleCollapseClick(collapseIcon, plugin, yaml, pathBlacklist, source, folderOverview, child);
this.handleCollapseClick(collapseIcon, plugin, yaml, pathBlacklist, sourceFolderPath, folderOverview, child);
}
}
}
async createFileEL(plugin: FolderNotesPlugin, child: TFile, folderOverview: FolderOverview, childrenElement: HTMLElement) {
console.log('createFileEL');
const yaml = folderOverview.yaml;
const pathBlacklist = folderOverview.pathBlacklist;
@ -300,7 +300,6 @@ export class FileExplorerOverview {
if (!allTypes.includes(extension) && !includeTypes.includes('other')) return;
}
console.log('file');
const fileElement = childrenElement.createDiv({
cls: 'tree-item nav-file',
});

View file

@ -77,7 +77,7 @@ export class FolderOverview {
disableCollapseIcon: yaml?.disableCollapseIcon ?? plugin.settings.defaultOverview.disableCollapseIcon,
alwaysCollapse: yaml?.alwaysCollapse ?? plugin.settings.defaultOverview.alwaysCollapse,
};
const customChild = new CustomMarkdownRenderChild(el, this);
ctx.addChild(customChild);
@ -180,10 +180,8 @@ export class FolderOverview {
} else if (sourceFolder) {
files = sourceFolder.children;
}
console.log('sourceFolderPath', sourceFolderPath);
files = this.getAllFiles(files, sourceFolderPath, this.yaml.depth);
console.log('files', files);
files = await this.filterFiles(files, plugin, sourceFolderPath, this.yaml.depth, this.pathBlacklist);
if (!this.yaml.includeTypes.includes('folder')) {
@ -234,7 +232,6 @@ export class FolderOverview {
const overviewListEl = el.childNodes[0].childNodes[1];
if (overviewListEl && overviewListEl.childNodes.length === 0) {
console.log('overviewListEl childNodes', overviewListEl.childNodes);
if (this.yaml.style === 'explorer') {
const overview = el.childNodes[0];
if (!overview.childNodes[2]) {
@ -267,32 +264,31 @@ export class FolderOverview {
async filterFiles(files: TAbstractFile[], plugin: FolderNotesPlugin, sourceFolderPath: string, depth: number, pathBlacklist: string[]) {
const filteredFiles = await Promise.all(files.map(async (file) => {
const folderPath = getFolderPathFromString(file.path);
if (
(pathBlacklist.includes(file.path) && !this.yaml.showFolderNotes) ||
!folderPath.startsWith(sourceFolderPath) && sourceFolderPath !== '/' ||
file.path === this.sourceFilePath ||
(await getExcludedFolder(plugin, file.path, true))?.excludeFromFolderOverview
) {
const isBlacklisted = pathBlacklist.includes(file.path);
const isSubfolder = folderPath.startsWith(sourceFolderPath) && sourceFolderPath !== '/';
const isSourceFile = file.path === this.sourceFilePath;
const isExcludedFromOverview = (await getExcludedFolder(plugin, file.path, true))?.excludeFromFolderOverview;
if ((isBlacklisted && !this.yaml.showFolderNotes) || !isSubfolder || isSourceFile || isExcludedFromOverview) {
return null;
}
const fileDepth = file.path.split('/').length - sourceFolderPath.split('/').length;
return fileDepth <= depth ? file : null;
}));
return filteredFiles.filter(file => file !== null);
}
sortFiles(files: TAbstractFile[]): TAbstractFile[] {
const yaml = this.yaml;
if (!yaml?.sortBy) {
yaml.sortBy = this.plugin.settings.defaultOverview.sortBy ?? 'name';
yaml.sortByAsc = this.plugin.settings.defaultOverview.sortByAsc ?? false;
}
files.sort((a, b) => {
if (a instanceof TFolder && !(b instanceof TFolder)) {
return -1;
@ -300,13 +296,13 @@ export class FolderOverview {
if (!(a instanceof TFolder) && b instanceof TFolder) {
return 1;
}
if (a instanceof TFolder && b instanceof TFolder) {
return yaml.sortByAsc
? a.name.localeCompare(b.name)
: b.name.localeCompare(a.name);
}
if (a instanceof TFile && b instanceof TFile) {
if (yaml.sortBy === 'created') {
return yaml.sortByAsc ? a.stat.ctime - b.stat.ctime : b.stat.ctime - a.stat.ctime;
@ -321,9 +317,9 @@ export class FolderOverview {
return 0;
});
return files;
}
}
removeEmptyFolders(ul: HTMLUListElement | HTMLLIElement, depth: number, yaml: yamlSettings) {
const childrensToRemove: ChildNode[] = [];
@ -349,10 +345,10 @@ export class FolderOverview {
const getDepth = (filePath: string) => {
return filePath.split('/').length - sourceFolderPath.split('/').length;
};
files.forEach((file) => {
const fileDepth = getDepth(file.path);
if (file instanceof TFolder) {
if (fileDepth < depth) {
allFiles.push(...this.getAllFiles(file.children, sourceFolderPath, depth));
@ -361,11 +357,11 @@ export class FolderOverview {
allFiles.push(file);
}
});
return allFiles;
}
fileMenu(file: TFile, e: MouseEvent) {
const plugin = this.plugin;

View file

@ -31,6 +31,7 @@ export function renderListOverview(plugin: FolderNotesPlugin, ctx: MarkdownPostP
goThroughFolders(plugin, folderItem, file, folderOverview.yaml.depth, sourceFolderPath, ctx, folderOverview.yaml, folderOverview.pathBlacklist, folderOverview.yaml.includeTypes, folderOverview.yaml.disableFileTag, folderOverview);
}
});
files.forEach((file) => {
if (file instanceof TFile) {
addFileList(plugin, ul, folderOverview.pathBlacklist, file, folderOverview.yaml.includeTypes, folderOverview.yaml.disableFileTag, folderOverview);
@ -66,11 +67,12 @@ async function goThroughFolders(plugin: FolderNotesPlugin, list: HTMLLIElement |
depth--;
}
let allFiles = await folderOverview.filterFiles(folder.children, plugin, sourceFolderPath, depth, pathBlacklist);
const allFiles = await folderOverview.filterFiles(folder.children, plugin, sourceFolderPath, depth, pathBlacklist);
const files = folderOverview.sortFiles(allFiles.filter((file) => !(file instanceof TFolder)));
const folders = folderOverview.sortFiles(allFiles.filter((file) => file instanceof TFolder));
const ul = list.createEl('ul', { cls: 'folder-overview-list' });
folders.forEach((file) => {
if (file instanceof TFolder) {
const folderItem = addFolderList(plugin, ul, pathBlacklist, file, folderOverview);
@ -78,6 +80,7 @@ async function goThroughFolders(plugin: FolderNotesPlugin, list: HTMLLIElement |
goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag, folderOverview);
}
});
files.forEach((file) => {
if (file instanceof TFile) {
addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag, folderOverview);
@ -99,14 +102,17 @@ function addFileList(plugin: FolderNotesPlugin, list: HTMLUListElement | HTMLLIE
const allTypes = ['md', 'canvas', 'pdf', ...imageTypes, ...videoTypes, ...audioTypes];
if (!allTypes.includes(file.extension) && !includeTypes.includes('other')) return;
}
if (!folderOverview.yaml.showFolderNotes) {
if (pathBlacklist.includes(file.path)) return;
}
const listItem = list.createEl('li', { cls: 'folder-overview-list file-link' });
listItem.oncontextmenu = (e) => {
e.stopImmediatePropagation();
folderOverview.fileMenu(file, e);
}
const nameItem = listItem.createEl('div', { cls: 'folder-overview-list-item' });
const link = nameItem.createEl('a', { cls: 'internal-link', href: file.path });
link.innerText = file.basename;

View file

@ -245,6 +245,7 @@ export class FolderOverviewSettings extends Modal {
slider
.setValue(this.yaml?.depth || 2)
.setLimits(1, 10, 1)
.setDynamicTooltip()
.onChange(async (value) => {
this.yaml.depth = value;
if (this.defaultSettings) {