mirror of
https://github.com/lostpaul/obsidian-folder-overview.git
synced 2026-07-22 05:35:07 +00:00
Fix code style issues
This commit is contained in:
parent
94f2d633dd
commit
c840ca4e26
18 changed files with 7992 additions and 8006 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import esbuild from 'esbuild';
|
||||
import process from 'process';
|
||||
import builtins from 'builtin-modules'
|
||||
import builtins from 'builtin-modules';
|
||||
|
||||
const banner =
|
||||
`/*
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"id": "folder-overview",
|
||||
"name": "Folder overview",
|
||||
"version": "0.3.36",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "Provides a dynamic overview of your vault or folders in the format of a code block.",
|
||||
"author": "Lost Paul",
|
||||
"authorUrl": "https://github.com/LostPaul",
|
||||
"fundingUrl": "https://ko-fi.com/paul305844",
|
||||
"helpUrl": "https://lostpaul.github.io/obsidian-folder-notes/Features/Folder%20overview/",
|
||||
"isDesktopOnly": false
|
||||
"id": "folder-overview",
|
||||
"name": "Folder overview",
|
||||
"version": "0.3.36",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "Provides a dynamic overview of your vault or folders in the format of a code block.",
|
||||
"author": "Lost Paul",
|
||||
"authorUrl": "https://github.com/LostPaul",
|
||||
"fundingUrl": "https://ko-fi.com/paul305844",
|
||||
"helpUrl": "https://lostpaul.github.io/obsidian-folder-notes/Features/Folder%20overview/",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
|
|
|
|||
120
src/Commands.ts
120
src/Commands.ts
|
|
@ -3,65 +3,65 @@ import FolderOverviewPlugin from './main';
|
|||
import { Menu, Editor, MarkdownView, stringifyYaml } from 'obsidian';
|
||||
|
||||
export function registerOverviewCommands(plugin: FolderOverviewPlugin | FolderNotesPlugin) {
|
||||
plugin.addCommand({
|
||||
id: 'open-folder-overview-settings',
|
||||
name: 'Open folder overview settings',
|
||||
callback: () => {
|
||||
plugin.activateOverviewView();
|
||||
}
|
||||
});
|
||||
plugin.addCommand({
|
||||
id: 'open-folder-overview-settings',
|
||||
name: 'Open folder overview settings',
|
||||
callback: () => {
|
||||
plugin.activateOverviewView();
|
||||
},
|
||||
});
|
||||
|
||||
plugin.addCommand({
|
||||
id: 'insert-folder-overview',
|
||||
name: 'Insert folder overview',
|
||||
editorCheckCallback: (checking: boolean, editor: Editor) => {
|
||||
const line = editor.getCursor().line;
|
||||
const lineText = editor.getLine(line);
|
||||
if (lineText.trim() === '' || lineText.trim() === '>') {
|
||||
if (!checking) {
|
||||
let json = Object.assign({}, plugin instanceof FolderOverviewPlugin ? plugin.settings : plugin.settings.defaultOverview);
|
||||
json.id = crypto.randomUUID();
|
||||
const yaml = stringifyYaml(json)
|
||||
if (lineText.trim() === '') {
|
||||
editor.replaceSelection(`\`\`\`folder-overview\n${yaml}\`\`\`\n`);
|
||||
} else if (lineText.trim() === '>') {
|
||||
// add > to the beginning of each line
|
||||
const lines = yaml.split('\n');
|
||||
const newLines = lines.map((line) => {
|
||||
return `> ${line}`;
|
||||
});
|
||||
editor.replaceSelection(`\`\`\`folder-overview\n${newLines.join('\n')}\`\`\`\n`);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
})
|
||||
plugin.addCommand({
|
||||
id: 'insert-folder-overview',
|
||||
name: 'Insert folder overview',
|
||||
editorCheckCallback: (checking: boolean, editor: Editor) => {
|
||||
const line = editor.getCursor().line;
|
||||
const lineText = editor.getLine(line);
|
||||
if (lineText.trim() === '' || lineText.trim() === '>') {
|
||||
if (!checking) {
|
||||
const json = Object.assign({}, plugin instanceof FolderOverviewPlugin ? plugin.settings : plugin.settings.defaultOverview);
|
||||
json.id = crypto.randomUUID();
|
||||
const yaml = stringifyYaml(json);
|
||||
if (lineText.trim() === '') {
|
||||
editor.replaceSelection(`\`\`\`folder-overview\n${yaml}\`\`\`\n`);
|
||||
} else if (lineText.trim() === '>') {
|
||||
// add > to the beginning of each line
|
||||
const lines = yaml.split('\n');
|
||||
const newLines = lines.map((line) => {
|
||||
return `> ${line}`;
|
||||
});
|
||||
editor.replaceSelection(`\`\`\`folder-overview\n${newLines.join('\n')}\`\`\`\n`);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
plugin.registerEvent(plugin.app.workspace.on('editor-menu', (menu: Menu, editor: Editor, view: MarkdownView) => {
|
||||
const line = editor.getCursor().line;
|
||||
const lineText = editor.getLine(line);
|
||||
if (lineText.trim() === '' || lineText.trim() === '>') {
|
||||
menu.addItem((item) => {
|
||||
item.setTitle('Create folder overview')
|
||||
.setIcon('edit')
|
||||
.onClick(() => {
|
||||
let json = Object.assign({}, plugin instanceof FolderOverviewPlugin ? plugin.settings : plugin.settings.defaultOverview);
|
||||
json.id = crypto.randomUUID();
|
||||
const yaml = stringifyYaml(json)
|
||||
if (lineText.trim() === '') {
|
||||
editor.replaceSelection(`\`\`\`folder-overview\n${yaml}\`\`\`\n`);
|
||||
} else if (lineText.trim() === '>') {
|
||||
// add > to the beginning of each line
|
||||
const lines = yaml.split('\n');
|
||||
const newLines = lines.map((line) => {
|
||||
return `> ${line}`;
|
||||
});
|
||||
editor.replaceSelection(`\`\`\`folder-overview\n${newLines.join('\n')}\`\`\`\n`);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}));
|
||||
}
|
||||
plugin.registerEvent(plugin.app.workspace.on('editor-menu', (menu: Menu, editor: Editor, view: MarkdownView) => {
|
||||
const line = editor.getCursor().line;
|
||||
const lineText = editor.getLine(line);
|
||||
if (lineText.trim() === '' || lineText.trim() === '>') {
|
||||
menu.addItem((item) => {
|
||||
item.setTitle('Create folder overview')
|
||||
.setIcon('edit')
|
||||
.onClick(() => {
|
||||
const json = Object.assign({}, plugin instanceof FolderOverviewPlugin ? plugin.settings : plugin.settings.defaultOverview);
|
||||
json.id = crypto.randomUUID();
|
||||
const yaml = stringifyYaml(json);
|
||||
if (lineText.trim() === '') {
|
||||
editor.replaceSelection(`\`\`\`folder-overview\n${yaml}\`\`\`\n`);
|
||||
} else if (lineText.trim() === '>') {
|
||||
// add > to the beginning of each line
|
||||
const lines = yaml.split('\n');
|
||||
const newLines = lines.map((line) => {
|
||||
return `> ${line}`;
|
||||
});
|
||||
editor.replaceSelection(`\`\`\`folder-overview\n${newLines.join('\n')}\`\`\`\n`);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,403 +1,397 @@
|
|||
import { MarkdownPostProcessorContext, parseYaml, TAbstractFile, TFolder, TFile, stringifyYaml, Notice, Menu, setIcon, addIcon } from 'obsidian';
|
||||
import { MarkdownPostProcessorContext, TAbstractFile, TFolder, TFile, setIcon } from 'obsidian';
|
||||
import { getFolderNote } from '../../functions/folderNoteFunctions';
|
||||
import { FolderOverviewSettings } from './modals/Settings';
|
||||
import { getExcludedFolder } from '../../ExcludeFolders/functions/folderFunctions';
|
||||
import { getFolderPathFromString } from '../../functions/utils';
|
||||
import { getEl } from '../../functions/styleFunctions';
|
||||
import { FolderOverview, overviewSettings } from './FolderOverview';
|
||||
import FolderNameModal from '../../modals/FolderName';
|
||||
import NewFolderNameModal from '../../modals/NewFolderName';
|
||||
import FolderOverviewPlugin from './main';
|
||||
import FolderNotesPlugin from '../../main';
|
||||
import { DragManager } from 'obsidian-typings';
|
||||
|
||||
export class FileExplorerOverview {
|
||||
plugin: FolderOverviewPlugin | FolderNotesPlugin;
|
||||
folderOverview: FolderOverview;
|
||||
pathBlacklist: string[];
|
||||
source: string;
|
||||
yaml: overviewSettings;
|
||||
root: HTMLElement;
|
||||
plugin: FolderOverviewPlugin | FolderNotesPlugin;
|
||||
folderOverview: FolderOverview;
|
||||
pathBlacklist: string[];
|
||||
source: string;
|
||||
yaml: overviewSettings;
|
||||
root: HTMLElement;
|
||||
|
||||
eventListeners: (() => void)[] = [];
|
||||
constructor(plugin: FolderOverviewPlugin | FolderNotesPlugin, ctx: MarkdownPostProcessorContext, root: HTMLElement, yaml: overviewSettings, pathBlacklist: string[], folderOverview: FolderOverview) {
|
||||
this.plugin = plugin;
|
||||
this.folderOverview = folderOverview;
|
||||
this.pathBlacklist = pathBlacklist;
|
||||
this.source = ctx.sourcePath;
|
||||
this.yaml = yaml;
|
||||
this.root = root;
|
||||
}
|
||||
eventListeners: (() => void)[] = [];
|
||||
constructor(plugin: FolderOverviewPlugin | FolderNotesPlugin, ctx: MarkdownPostProcessorContext, root: HTMLElement, yaml: overviewSettings, pathBlacklist: string[], folderOverview: FolderOverview) {
|
||||
this.plugin = plugin;
|
||||
this.folderOverview = folderOverview;
|
||||
this.pathBlacklist = pathBlacklist;
|
||||
this.source = ctx.sourcePath;
|
||||
this.yaml = yaml;
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
disconnectListeners() {
|
||||
this.eventListeners.forEach((unregister) => {
|
||||
unregister();
|
||||
});
|
||||
this.eventListeners = [];
|
||||
}
|
||||
disconnectListeners() {
|
||||
this.eventListeners.forEach((unregister) => {
|
||||
unregister();
|
||||
});
|
||||
this.eventListeners = [];
|
||||
}
|
||||
|
||||
async renderFileExplorer() {
|
||||
this.disconnectListeners();
|
||||
const plugin = this.plugin;
|
||||
const ctx = this.folderOverview.ctx;
|
||||
const root = this.folderOverview.root;
|
||||
const yaml = this.folderOverview.yaml;
|
||||
const folderOverview = this.folderOverview;
|
||||
let folder: HTMLElement | null = null;
|
||||
if (plugin instanceof FolderNotesPlugin) {
|
||||
folder = getEl(yaml.folderPath, plugin);
|
||||
}
|
||||
let folderElement = folder?.parentElement;
|
||||
const source = ctx.sourcePath;
|
||||
const overviewList = folderOverview.listEl;
|
||||
overviewList?.empty();
|
||||
if (!overviewList) return;
|
||||
async renderFileExplorer() {
|
||||
this.disconnectListeners();
|
||||
const plugin = this.plugin;
|
||||
const ctx = this.folderOverview.ctx;
|
||||
const root = this.folderOverview.root;
|
||||
const yaml = this.folderOverview.yaml;
|
||||
const folderOverview = this.folderOverview;
|
||||
let folder: HTMLElement | null = null;
|
||||
if (plugin instanceof FolderNotesPlugin) {
|
||||
folder = getEl(yaml.folderPath, plugin);
|
||||
}
|
||||
let folderElement = folder?.parentElement;
|
||||
const overviewList = folderOverview.listEl;
|
||||
overviewList?.empty();
|
||||
if (!overviewList) return;
|
||||
|
||||
let tFolder = plugin.app.vault.getAbstractFileByPath(yaml.folderPath);
|
||||
if (!tFolder && yaml.folderPath.trim() == '') {
|
||||
if (ctx.sourcePath.includes('/')) {
|
||||
tFolder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(ctx.sourcePath));
|
||||
} else {
|
||||
yaml.folderPath = '/';
|
||||
tFolder = plugin.app.vault.getAbstractFileByPath('/');
|
||||
}
|
||||
}
|
||||
let tFolder = plugin.app.vault.getAbstractFileByPath(yaml.folderPath);
|
||||
if (!tFolder && yaml.folderPath.trim() === '') {
|
||||
if (ctx.sourcePath.includes('/')) {
|
||||
tFolder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(ctx.sourcePath));
|
||||
} else {
|
||||
yaml.folderPath = '/';
|
||||
tFolder = plugin.app.vault.getAbstractFileByPath('/');
|
||||
}
|
||||
}
|
||||
|
||||
if (!folderElement && !tFolder) return;
|
||||
// wait until the file explorer is loaded
|
||||
if (!folderElement && !tFolder) return;
|
||||
// wait until the file explorer is loaded
|
||||
|
||||
const sourceFolderPath = tFolder?.path || '';
|
||||
const sourceFolderPath = tFolder?.path || '';
|
||||
|
||||
folderElement = document.querySelectorAll('.nav-files-container')[0] as HTMLElement;
|
||||
if (!folderElement) {
|
||||
folderElement = root.createDiv({
|
||||
cls: 'nav-files-container',
|
||||
});
|
||||
}
|
||||
folderElement = document.querySelectorAll('.nav-files-container')[0] as HTMLElement;
|
||||
if (!folderElement) {
|
||||
folderElement = root.createDiv({
|
||||
cls: 'nav-files-container',
|
||||
});
|
||||
}
|
||||
|
||||
const newFolderElement = folderElement.cloneNode(true) as HTMLElement;
|
||||
const newFolderElement = folderElement.cloneNode(true) as HTMLElement;
|
||||
|
||||
newFolderElement.querySelectorAll('div.nav-folder-title').forEach((el) => {
|
||||
const folder = plugin.app.vault.getAbstractFileByPath(el.getAttribute('data-path') || '');
|
||||
if (!(folder instanceof TFolder)) return;
|
||||
newFolderElement.querySelectorAll('div.nav-folder-title').forEach((el) => {
|
||||
const folder = plugin.app.vault.getAbstractFileByPath(el.getAttribute('data-path') || '');
|
||||
if (!(folder instanceof TFolder)) return;
|
||||
|
||||
if (yaml.alwaysCollapse) {
|
||||
folder.collapsed = true;
|
||||
el.classList.add('is-collapsed');
|
||||
} else {
|
||||
if (yaml.storeFolderCondition) {
|
||||
if (folder.collapsed) {
|
||||
el.classList.add('is-collapsed');
|
||||
} else {
|
||||
el.classList.remove('is-collapsed');
|
||||
}
|
||||
} else {
|
||||
if (el.parentElement?.classList.contains('is-collapsed')) {
|
||||
folder.collapsed = true;
|
||||
} else {
|
||||
folder.collapsed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (yaml.alwaysCollapse) {
|
||||
folder.collapsed = true;
|
||||
el.classList.add('is-collapsed');
|
||||
} else {
|
||||
if (yaml.storeFolderCondition) {
|
||||
if (folder.collapsed) {
|
||||
el.classList.add('is-collapsed');
|
||||
} else {
|
||||
el.classList.remove('is-collapsed');
|
||||
}
|
||||
} else {
|
||||
if (el.parentElement?.classList.contains('is-collapsed')) {
|
||||
folder.collapsed = true;
|
||||
} else {
|
||||
folder.collapsed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (el.classList.contains('has-folder-note')) {
|
||||
if (plugin instanceof FolderNotesPlugin) {
|
||||
const folderNote = getFolderNote(plugin, folder.path);
|
||||
if (folderNote) { folderOverview.pathBlacklist.push(folderNote.path); }
|
||||
}
|
||||
}
|
||||
});
|
||||
if (el.classList.contains('has-folder-note')) {
|
||||
if (plugin instanceof FolderNotesPlugin) {
|
||||
const folderNote = getFolderNote(plugin, folder.path);
|
||||
if (folderNote) { folderOverview.pathBlacklist.push(folderNote.path); }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const debouncedRenderFileExplorer = this.debounce(() => this.renderFileExplorer(), 300);
|
||||
const debouncedRenderFileExplorer = this.debounce(() => this.renderFileExplorer(), 300);
|
||||
|
||||
const handleVaultChange = () => {
|
||||
debouncedRenderFileExplorer();
|
||||
}
|
||||
const handleVaultChange = () => {
|
||||
debouncedRenderFileExplorer();
|
||||
};
|
||||
|
||||
this.eventListeners.push(() => {
|
||||
folderOverview.off('vault-change', handleVaultChange);
|
||||
});
|
||||
this.eventListeners.push(() => {
|
||||
folderOverview.off('vault-change', handleVaultChange);
|
||||
});
|
||||
|
||||
folderOverview.on('vault-change', handleVaultChange);
|
||||
folderOverview.on('vault-change', handleVaultChange);
|
||||
|
||||
if (tFolder instanceof TFolder) {
|
||||
await this.addFiles(tFolder.children, overviewList, folderOverview, sourceFolderPath);
|
||||
}
|
||||
if (tFolder instanceof TFolder) {
|
||||
await this.addFiles(tFolder.children, overviewList, folderOverview, sourceFolderPath);
|
||||
}
|
||||
|
||||
newFolderElement.querySelectorAll('div.tree-item-icon').forEach((el) => {
|
||||
if (el instanceof HTMLElement) {
|
||||
el.onclick = () => {
|
||||
const path = el.parentElement?.getAttribute('data-path');
|
||||
if (!path) return;
|
||||
const folder = plugin.app.vault.getAbstractFileByPath(path);
|
||||
this.handleCollapseClick(el, plugin, yaml, this.pathBlacklist, sourceFolderPath, folderOverview, folder);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
newFolderElement.querySelectorAll('div.tree-item-icon').forEach((el) => {
|
||||
if (el instanceof HTMLElement) {
|
||||
el.onclick = () => {
|
||||
const path = el.parentElement?.getAttribute('data-path');
|
||||
if (!path) return;
|
||||
const folder = plugin.app.vault.getAbstractFileByPath(path);
|
||||
this.handleCollapseClick(el, plugin, yaml, this.pathBlacklist, sourceFolderPath, folderOverview, folder);
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
debounce(func: Function, wait: number) {
|
||||
let timeout: number | undefined;
|
||||
return (...args: any[]) => {
|
||||
clearTimeout(timeout);
|
||||
timeout = window.setTimeout(() => func.apply(this, args), wait);
|
||||
};
|
||||
}
|
||||
debounce(func: Function, wait: number) {
|
||||
let timeout: number | undefined;
|
||||
return (...args: any[]) => {
|
||||
clearTimeout(timeout);
|
||||
timeout = window.setTimeout(() => func.apply(this, args), wait);
|
||||
};
|
||||
}
|
||||
|
||||
async addFiles(files: TAbstractFile[], childrenElement: HTMLElement, folderOverview: FolderOverview, sourceFolderPath: string) {
|
||||
const plugin = folderOverview.plugin;
|
||||
const allFiles = await folderOverview.filterFiles(files, plugin, sourceFolderPath, folderOverview.yaml.depth, folderOverview.pathBlacklist);
|
||||
const sortedFiles = folderOverview.sortFiles((allFiles ?? []).filter((file): file is TAbstractFile => file !== null));
|
||||
async addFiles(files: TAbstractFile[], childrenElement: HTMLElement, folderOverview: FolderOverview, sourceFolderPath: string) {
|
||||
const plugin = folderOverview.plugin;
|
||||
const allFiles = await folderOverview.filterFiles(files, plugin, sourceFolderPath, folderOverview.yaml.depth, folderOverview.pathBlacklist);
|
||||
const sortedFiles = folderOverview.sortFiles((allFiles ?? []).filter((file): file is TAbstractFile => file !== null));
|
||||
|
||||
const folders = sortedFiles.filter(child => child instanceof TFolder);
|
||||
const otherFiles = sortedFiles.filter(child => child instanceof TFile);
|
||||
const folders = sortedFiles.filter((child) => child instanceof TFolder);
|
||||
const otherFiles = sortedFiles.filter((child) => child instanceof TFile);
|
||||
|
||||
for (const child of folders) {
|
||||
if (!(child instanceof TFolder)) continue;
|
||||
await this.createFolderEL(plugin, child, folderOverview, childrenElement, sourceFolderPath);
|
||||
}
|
||||
for (const child of folders) {
|
||||
if (!(child instanceof TFolder)) continue;
|
||||
await this.createFolderEL(plugin, child, folderOverview, childrenElement, sourceFolderPath);
|
||||
}
|
||||
|
||||
for (const child of otherFiles) {
|
||||
if (!(child instanceof TFile)) continue;
|
||||
await this.createFileEL(plugin, child, folderOverview, childrenElement);
|
||||
}
|
||||
for (const child of otherFiles) {
|
||||
if (!(child instanceof TFile)) continue;
|
||||
await this.createFileEL(plugin, child, folderOverview, childrenElement);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async handleCollapseClick(el: HTMLElement, plugin: FolderOverviewPlugin | FolderNotesPlugin, yaml: overviewSettings, 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;
|
||||
folder.collapsed = true;
|
||||
el.parentElement?.parentElement?.childNodes[1]?.remove();
|
||||
} else {
|
||||
if (!(folder instanceof TFolder)) return;
|
||||
folder.collapsed = false;
|
||||
const folderElement = el.parentElement?.parentElement;
|
||||
if (!folderElement) return;
|
||||
const childrenElement = folderElement.createDiv({ cls: 'tree-item-children nav-folder-children' });
|
||||
let files = folderOverview.sortFiles(folder.children);
|
||||
const filteredFiles = (await folderOverview.filterFiles(files, plugin, folder.path, yaml.depth || 1, pathBlacklist) ?? []).filter((file): file is TAbstractFile => file !== null);
|
||||
await this.addFiles(filteredFiles, childrenElement, folderOverview, sourceFolderPath);
|
||||
}
|
||||
}
|
||||
async handleCollapseClick(el: HTMLElement, plugin: FolderOverviewPlugin | FolderNotesPlugin, yaml: overviewSettings, 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;
|
||||
folder.collapsed = true;
|
||||
el.parentElement?.parentElement?.childNodes[1]?.remove();
|
||||
} else {
|
||||
if (!(folder instanceof TFolder)) return;
|
||||
folder.collapsed = false;
|
||||
const folderElement = el.parentElement?.parentElement;
|
||||
if (!folderElement) return;
|
||||
const childrenElement = folderElement.createDiv({ cls: 'tree-item-children nav-folder-children' });
|
||||
const files = folderOverview.sortFiles(folder.children);
|
||||
const filteredFiles = (await folderOverview.filterFiles(files, plugin, folder.path, yaml.depth || 1, pathBlacklist) ?? []).filter((file): file is TAbstractFile => file !== null);
|
||||
await this.addFiles(filteredFiles, childrenElement, folderOverview, sourceFolderPath);
|
||||
}
|
||||
}
|
||||
|
||||
async createFolderEL(plugin: FolderOverviewPlugin | FolderNotesPlugin, child: TFolder, folderOverview: FolderOverview, childrenElement: HTMLElement, sourceFolderPath: string) {
|
||||
const pathBlacklist = folderOverview.pathBlacklist;
|
||||
const source = folderOverview.source;
|
||||
let folderNote: TFile | null | undefined = undefined;
|
||||
if (plugin instanceof FolderNotesPlugin) {
|
||||
folderNote = getFolderNote(plugin, child.path);
|
||||
}
|
||||
const yaml = folderOverview.yaml;
|
||||
let folderTitle: HTMLElement | null = null;
|
||||
let folderElement: HTMLElement | null = null;
|
||||
async createFolderEL(plugin: FolderOverviewPlugin | FolderNotesPlugin, child: TFolder, folderOverview: FolderOverview, childrenElement: HTMLElement, sourceFolderPath: string) {
|
||||
const pathBlacklist = folderOverview.pathBlacklist;
|
||||
let folderNote: TFile | null | undefined = undefined;
|
||||
if (plugin instanceof FolderNotesPlugin) {
|
||||
folderNote = getFolderNote(plugin, child.path);
|
||||
}
|
||||
const yaml = folderOverview.yaml;
|
||||
let folderTitle: HTMLElement | null = null;
|
||||
let folderElement: HTMLElement | null = null;
|
||||
|
||||
if (folderNote) { pathBlacklist.push(folderNote.path); }
|
||||
let excludedFolder = undefined;
|
||||
if (plugin instanceof FolderNotesPlugin) {
|
||||
excludedFolder = await getExcludedFolder(plugin, child.path, true);
|
||||
}
|
||||
if (excludedFolder?.excludeFromFolderOverview) { return; }
|
||||
if (folderNote) { pathBlacklist.push(folderNote.path); }
|
||||
let excludedFolder = undefined;
|
||||
if (plugin instanceof FolderNotesPlugin) {
|
||||
excludedFolder = await getExcludedFolder(plugin, child.path, true);
|
||||
}
|
||||
if (excludedFolder?.excludeFromFolderOverview) { return; }
|
||||
|
||||
if (yaml.includeTypes.includes('folder')) {
|
||||
folderOverview.el.parentElement?.classList.add('fv-remove-edit-button');
|
||||
folderElement = childrenElement.createDiv({
|
||||
cls: 'tree-item nav-folder',
|
||||
});
|
||||
if (yaml.includeTypes.includes('folder')) {
|
||||
folderOverview.el.parentElement?.classList.add('fv-remove-edit-button');
|
||||
folderElement = childrenElement.createDiv({
|
||||
cls: 'tree-item nav-folder',
|
||||
});
|
||||
|
||||
folderTitle = folderElement.createDiv({
|
||||
cls: 'tree-item-self is-clickable nav-folder-title',
|
||||
attr: {
|
||||
'data-path': child.path
|
||||
},
|
||||
})
|
||||
folderTitle = folderElement.createDiv({
|
||||
cls: 'tree-item-self is-clickable nav-folder-title',
|
||||
attr: {
|
||||
'data-path': child.path,
|
||||
},
|
||||
});
|
||||
|
||||
const folderTitleText = folderTitle?.createDiv({
|
||||
cls: 'tree-item-inner nav-folder-title-content',
|
||||
text: child.name,
|
||||
});
|
||||
const folderTitleText = folderTitle?.createDiv({
|
||||
cls: 'tree-item-inner nav-folder-title-content',
|
||||
text: child.name,
|
||||
});
|
||||
|
||||
if (folderTitleText && !folderNote) {
|
||||
folderTitleText.onclick = () => {
|
||||
const collapseIcon = folderTitle?.querySelectorAll('.tree-item-icon')[0] as HTMLElement;
|
||||
if (collapseIcon) {
|
||||
this.handleCollapseClick(collapseIcon, plugin, yaml, pathBlacklist, sourceFolderPath, folderOverview, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (folderTitleText && !folderNote) {
|
||||
folderTitleText.onclick = () => {
|
||||
const collapseIcon = folderTitle?.querySelectorAll('.tree-item-icon')[0] as HTMLElement;
|
||||
if (collapseIcon) {
|
||||
this.handleCollapseClick(collapseIcon, plugin, yaml, pathBlacklist, sourceFolderPath, folderOverview, child);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (yaml.allowDragAndDrop) {
|
||||
folderTitle.draggable = true;
|
||||
folderTitle.addEventListener('dragstart', e => {
|
||||
const dragManager = plugin.app.dragManager;
|
||||
const dragData = dragManager.dragFolder(e, child);
|
||||
dragManager.onDragStart(e, dragData);
|
||||
folderTitle?.classList.add('is-being-dragged');
|
||||
});
|
||||
if (yaml.allowDragAndDrop) {
|
||||
folderTitle.draggable = true;
|
||||
folderTitle.addEventListener('dragstart', (e) => {
|
||||
const dragManager = plugin.app.dragManager;
|
||||
const dragData = dragManager.dragFolder(e, child);
|
||||
dragManager.onDragStart(e, dragData);
|
||||
folderTitle?.classList.add('is-being-dragged');
|
||||
});
|
||||
|
||||
folderTitle.addEventListener('dragend', e => {
|
||||
folderTitle?.classList.remove('is-being-dragged');
|
||||
});
|
||||
folderTitle.addEventListener('dragend', (e) => {
|
||||
folderTitle?.classList.remove('is-being-dragged');
|
||||
});
|
||||
|
||||
folderTitle.addEventListener('dragover', e => {
|
||||
e.preventDefault();
|
||||
const { draggable } = plugin.app.dragManager;
|
||||
if (draggable) {
|
||||
folderElement?.classList.add('is-being-dragged-over');
|
||||
plugin.app.dragManager.setAction(window.i18next.t('interface.drag-and-drop.move-into-folder', { folder: child.name }));
|
||||
}
|
||||
folderTitle.addEventListener('dragover', (e) => {
|
||||
e.preventDefault();
|
||||
const { draggable } = plugin.app.dragManager;
|
||||
if (draggable) {
|
||||
folderElement?.classList.add('is-being-dragged-over');
|
||||
plugin.app.dragManager.setAction(window.i18next.t('interface.drag-and-drop.move-into-folder', { folder: child.name }));
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
folderTitle.addEventListener('dragleave', e => {
|
||||
folderElement?.classList.remove('is-being-dragged-over');
|
||||
});
|
||||
folderTitle.addEventListener('dragleave', (e) => {
|
||||
folderElement?.classList.remove('is-being-dragged-over');
|
||||
});
|
||||
|
||||
folderTitle.addEventListener('drop', e => {
|
||||
const { draggable } = plugin.app.dragManager;
|
||||
if (draggable && draggable.file) {
|
||||
plugin.app.fileManager.renameFile(draggable.file, child.path + '/' + draggable.file.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
folderTitle.addEventListener('drop', (e) => {
|
||||
const { draggable } = plugin.app.dragManager;
|
||||
if (draggable && draggable.file) {
|
||||
plugin.app.fileManager.renameFile(draggable.file, child.path + '/' + draggable.file.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
folderTitle.oncontextmenu = (e) => {
|
||||
folderOverview.folderMenu(child, e);
|
||||
}
|
||||
}
|
||||
folderTitle.oncontextmenu = (e) => {
|
||||
folderOverview.folderMenu(child, e);
|
||||
};
|
||||
}
|
||||
|
||||
if (!child.collapsed || !yaml.includeTypes.includes('folder')) {
|
||||
if (yaml.alwaysCollapse) {
|
||||
child.collapsed = true;
|
||||
}
|
||||
if (yaml.includeTypes.includes('folder')) {
|
||||
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, sourceFolderPath);
|
||||
}
|
||||
} else {
|
||||
await this.addFiles(child.children, childrenElement, folderOverview, sourceFolderPath);
|
||||
}
|
||||
} else {
|
||||
folderTitle?.classList.add('is-collapsed');
|
||||
}
|
||||
if (!child.collapsed || !yaml.includeTypes.includes('folder')) {
|
||||
if (yaml.alwaysCollapse) {
|
||||
child.collapsed = true;
|
||||
}
|
||||
if (yaml.includeTypes.includes('folder')) {
|
||||
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, sourceFolderPath);
|
||||
}
|
||||
} else {
|
||||
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') }
|
||||
if (folderNote) { folderTitle?.classList.add('has-folder-note'); }
|
||||
if (folderNote && child.children.length === 1 && yaml.disableCollapseIcon) { folderTitle?.classList.add('fn-has-no-files'); }
|
||||
|
||||
const collapseIcon = folderTitle?.createDiv({
|
||||
cls: 'tree-item-icon collapse-icon nav-folder-collapse-indicator fn-folder-overview-collapse-icon',
|
||||
});
|
||||
const collapseIcon = folderTitle?.createDiv({
|
||||
cls: 'tree-item-icon collapse-icon nav-folder-collapse-indicator fn-folder-overview-collapse-icon',
|
||||
});
|
||||
|
||||
if (child.collapsed) {
|
||||
collapseIcon?.classList.add('is-collapsed');
|
||||
}
|
||||
if (child.collapsed) {
|
||||
collapseIcon?.classList.add('is-collapsed');
|
||||
}
|
||||
|
||||
if (collapseIcon) {
|
||||
setIcon(collapseIcon, 'chevron-down');
|
||||
collapseIcon.querySelector('path')?.setAttribute('d', 'M3 8L12 17L21 8');
|
||||
collapseIcon.onclick = () => {
|
||||
this.handleCollapseClick(collapseIcon, plugin, yaml, pathBlacklist, sourceFolderPath, folderOverview, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (collapseIcon) {
|
||||
setIcon(collapseIcon, 'chevron-down');
|
||||
collapseIcon.querySelector('path')?.setAttribute('d', 'M3 8L12 17L21 8');
|
||||
collapseIcon.onclick = () => {
|
||||
this.handleCollapseClick(collapseIcon, plugin, yaml, pathBlacklist, sourceFolderPath, folderOverview, child);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async createFileEL(plugin: FolderOverviewPlugin | FolderNotesPlugin, child: TFile, folderOverview: FolderOverview, childrenElement: HTMLElement) {
|
||||
const yaml = folderOverview.yaml;
|
||||
const pathBlacklist = folderOverview.pathBlacklist;
|
||||
async createFileEL(plugin: FolderOverviewPlugin | FolderNotesPlugin, child: TFile, folderOverview: FolderOverview, childrenElement: HTMLElement) {
|
||||
const yaml = folderOverview.yaml;
|
||||
const pathBlacklist = folderOverview.pathBlacklist;
|
||||
|
||||
if (pathBlacklist.includes(child.path) && !yaml.showFolderNotes) { return; }
|
||||
if (pathBlacklist.includes(child.path) && !yaml.showFolderNotes) { return; }
|
||||
|
||||
const extension = child.extension.toLowerCase() == 'md' ? 'markdown' : child.extension.toLowerCase();
|
||||
const includeTypes = yaml.includeTypes;
|
||||
const extension = child.extension.toLowerCase() === 'md' ? 'markdown' : child.extension.toLowerCase();
|
||||
const includeTypes = yaml.includeTypes;
|
||||
|
||||
if (includeTypes.length > 0 && !includeTypes.includes('all')) {
|
||||
if ((extension === 'md' || extension === 'markdown') && !includeTypes.includes('markdown')) return;
|
||||
if (extension === 'canvas' && !includeTypes.includes('canvas')) return;
|
||||
if (extension === 'pdf' && !includeTypes.includes('pdf')) return;
|
||||
const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp'];
|
||||
if (imageTypes.includes(extension) && !includeTypes.includes('image')) return;
|
||||
const videoTypes = ['mp4', 'webm', 'ogv', 'mov', 'mkv'];
|
||||
if (videoTypes.includes(extension) && !includeTypes.includes('video')) return;
|
||||
const audioTypes = ['mp3', 'wav', 'm4a', '3gp', 'flac', 'ogg', 'oga', 'opus'];
|
||||
if (audioTypes.includes(extension) && includeTypes.includes('audio')) return;
|
||||
const allTypes = ['markdown', 'md', 'canvas', 'pdf', ...imageTypes, ...videoTypes, ...audioTypes];
|
||||
if (!allTypes.includes(extension) && !includeTypes.includes('other')) return;
|
||||
}
|
||||
if (includeTypes.length > 0 && !includeTypes.includes('all')) {
|
||||
if ((extension === 'md' || extension === 'markdown') && !includeTypes.includes('markdown')) return;
|
||||
if (extension === 'canvas' && !includeTypes.includes('canvas')) return;
|
||||
if (extension === 'pdf' && !includeTypes.includes('pdf')) return;
|
||||
const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp'];
|
||||
if (imageTypes.includes(extension) && !includeTypes.includes('image')) return;
|
||||
const videoTypes = ['mp4', 'webm', 'ogv', 'mov', 'mkv'];
|
||||
if (videoTypes.includes(extension) && !includeTypes.includes('video')) return;
|
||||
const audioTypes = ['mp3', 'wav', 'm4a', '3gp', 'flac', 'ogg', 'oga', 'opus'];
|
||||
if (audioTypes.includes(extension) && includeTypes.includes('audio')) return;
|
||||
const allTypes = ['markdown', 'md', 'canvas', 'pdf', ...imageTypes, ...videoTypes, ...audioTypes];
|
||||
if (!allTypes.includes(extension) && !includeTypes.includes('other')) return;
|
||||
}
|
||||
|
||||
folderOverview.el.parentElement?.classList.add('fv-remove-edit-button');
|
||||
folderOverview.el.parentElement?.classList.add('fv-remove-edit-button');
|
||||
|
||||
const fileElement = childrenElement.createDiv({
|
||||
cls: 'tree-item nav-file',
|
||||
});
|
||||
const fileElement = childrenElement.createDiv({
|
||||
cls: 'tree-item nav-file',
|
||||
});
|
||||
|
||||
const fileTitle = fileElement.createDiv({
|
||||
cls: 'tree-item-self is-clickable nav-file-title pointer-cursor',
|
||||
attr: {
|
||||
'data-path': child.path,
|
||||
},
|
||||
});
|
||||
const fileTitle = fileElement.createDiv({
|
||||
cls: 'tree-item-self is-clickable nav-file-title pointer-cursor',
|
||||
attr: {
|
||||
'data-path': child.path,
|
||||
},
|
||||
});
|
||||
|
||||
if (yaml.allowDragAndDrop) {
|
||||
fileTitle.draggable = true;
|
||||
fileTitle.addEventListener('dragstart', e => {
|
||||
const dragManager = plugin.app.dragManager;
|
||||
const dragData = dragManager.dragFile(e, child);
|
||||
dragManager.onDragStart(e, dragData);
|
||||
fileTitle.classList.add('is-being-dragged');
|
||||
});
|
||||
if (yaml.allowDragAndDrop) {
|
||||
fileTitle.draggable = true;
|
||||
fileTitle.addEventListener('dragstart', (e) => {
|
||||
const dragManager = plugin.app.dragManager;
|
||||
const dragData = dragManager.dragFile(e, child);
|
||||
dragManager.onDragStart(e, dragData);
|
||||
fileTitle.classList.add('is-being-dragged');
|
||||
});
|
||||
|
||||
fileTitle.addEventListener('dragend', () => {
|
||||
fileTitle.classList.remove('is-being-dragged');
|
||||
});
|
||||
fileTitle.addEventListener('dragend', () => {
|
||||
fileTitle.classList.remove('is-being-dragged');
|
||||
});
|
||||
|
||||
fileTitle.addEventListener('dragover', e => {
|
||||
e.preventDefault();
|
||||
const { draggable } = plugin.app.dragManager;
|
||||
if (draggable) {
|
||||
plugin.app.dragManager.setAction(window.i18next.t('interface.drag-and-drop.move-into-folder', { folder: child.parent?.name || plugin.app.vault.getName() }));
|
||||
fileElement.parentElement?.parentElement?.classList.add('is-being-dragged-over');
|
||||
fileTitle.addEventListener('dragover', (e) => {
|
||||
e.preventDefault();
|
||||
const { draggable } = plugin.app.dragManager;
|
||||
if (draggable) {
|
||||
plugin.app.dragManager.setAction(window.i18next.t('interface.drag-and-drop.move-into-folder', { folder: child.parent?.name || plugin.app.vault.getName() }));
|
||||
fileElement.parentElement?.parentElement?.classList.add('is-being-dragged-over');
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
fileTitle.addEventListener('dragleave', () => {
|
||||
fileElement.parentElement?.parentElement?.classList.remove('is-being-dragged-over');
|
||||
});
|
||||
fileTitle.addEventListener('dragleave', () => {
|
||||
fileElement.parentElement?.parentElement?.classList.remove('is-being-dragged-over');
|
||||
});
|
||||
|
||||
fileTitle.addEventListener('drop', e => {
|
||||
e.preventDefault();
|
||||
const { draggable } = plugin.app.dragManager;
|
||||
if (draggable?.file) {
|
||||
const targetFolder = child.parent?.path || '';
|
||||
if (targetFolder) {
|
||||
plugin.app.fileManager.renameFile(draggable.file, `${targetFolder}/${draggable.file.name}`);
|
||||
}
|
||||
fileElement.parentElement?.parentElement?.classList.remove('is-being-dragged-over');
|
||||
}
|
||||
});
|
||||
}
|
||||
fileTitle.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
const { draggable } = plugin.app.dragManager;
|
||||
if (draggable?.file) {
|
||||
const targetFolder = child.parent?.path || '';
|
||||
if (targetFolder) {
|
||||
plugin.app.fileManager.renameFile(draggable.file, `${targetFolder}/${draggable.file.name}`);
|
||||
}
|
||||
fileElement.parentElement?.parentElement?.classList.remove('is-being-dragged-over');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fileTitle.onclick = () => {
|
||||
plugin.app.workspace.openLinkText(child.path, child.path, true);
|
||||
};
|
||||
fileTitle.onclick = () => {
|
||||
plugin.app.workspace.openLinkText(child.path, child.path, true);
|
||||
};
|
||||
|
||||
fileTitle.oncontextmenu = (e) => {
|
||||
folderOverview.fileMenu(child, e);
|
||||
};
|
||||
fileTitle.oncontextmenu = (e) => {
|
||||
folderOverview.fileMenu(child, e);
|
||||
};
|
||||
|
||||
fileTitle.createDiv({
|
||||
cls: 'tree-item-inner nav-file-title-content',
|
||||
text: child.basename,
|
||||
});
|
||||
fileTitle.createDiv({
|
||||
cls: 'tree-item-inner nav-file-title-content',
|
||||
text: child.basename,
|
||||
});
|
||||
|
||||
if (child.extension !== 'md' && !yaml.disableFileTag) {
|
||||
fileTitle.createDiv({
|
||||
cls: 'nav-file-tag',
|
||||
text: child.extension
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (child.extension !== 'md' && !yaml.disableFileTag) {
|
||||
fileTitle.createDiv({
|
||||
cls: 'nav-file-tag',
|
||||
text: child.extension,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import NewFolderNameModal from '../../modals/NewFolderName';
|
|||
import { CustomEventEmitter } from './utils/EventEmitter';
|
||||
import FolderOverviewPlugin from './main';
|
||||
import FolderNotesPlugin from '../../main';
|
||||
import { title } from 'process';
|
||||
|
||||
export type includeTypes = 'folder' | 'markdown' | 'canvas' | 'other' | 'pdf' | 'image' | 'audio' | 'video' | 'all';
|
||||
|
||||
|
|
@ -83,7 +82,7 @@ export class FolderOverview {
|
|||
disableCollapseIcon: yaml?.disableCollapseIcon ?? defaultSettings.disableCollapseIcon,
|
||||
alwaysCollapse: yaml?.alwaysCollapse ?? defaultSettings.alwaysCollapse,
|
||||
autoSync: yaml?.autoSync ?? defaultSettings.autoSync,
|
||||
allowDragAndDrop: yaml?.allowDragAndDrop ?? defaultSettings.allowDragAndDrop
|
||||
allowDragAndDrop: yaml?.allowDragAndDrop ?? defaultSettings.allowDragAndDrop,
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -167,7 +166,7 @@ export class FolderOverview {
|
|||
if (this.yaml.showTitle) {
|
||||
if (sourceFolder && sourceFolderPath !== '/') {
|
||||
titleEl.innerText = this.yaml.title.replace('{{folderName}}', sourceFolder.name);
|
||||
} else if (sourceFolderPath == '/') {
|
||||
} else if (sourceFolderPath === '/') {
|
||||
titleEl.innerText = this.yaml.title.replace('{{folderName}}', 'Vault');
|
||||
} else {
|
||||
titleEl.innerText = this.yaml.title.replace('{{folderName}}', '');
|
||||
|
|
@ -175,7 +174,7 @@ export class FolderOverview {
|
|||
}
|
||||
|
||||
if (!sourceFolder && (sourceFolderPath !== '/' && sourceFolderPath !== '')) { return new Notice('Folder overview: Couldn\'t find the folder'); }
|
||||
if (!sourceFolder && sourceFolderPath == '') {
|
||||
if (!sourceFolder && sourceFolderPath === '') {
|
||||
sourceFolderPath = '/';
|
||||
}
|
||||
if (!(sourceFolder instanceof TFolder) && sourceFolderPath !== '/') { return; }
|
||||
|
|
@ -486,7 +485,7 @@ export function parseOverviewTitle(overview: overviewSettings, plugin: FolderOve
|
|||
const title = overview.title;
|
||||
if (folder?.path === '/' && sourceFolderPath === '' || sourceFolderPath === '/') {
|
||||
return title.replace('{{folderName}}', 'Vault');
|
||||
} else if (folder && sourceFolderPath == '') {
|
||||
} else if (folder && sourceFolderPath === '') {
|
||||
return title.replace('{{folderName}}', folder.name);
|
||||
} else if (sourceFolderPath !== '') {
|
||||
const newSourceFolder = plugin.app.vault.getAbstractFileByPath(sourceFolderPath);
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
export {}
|
||||
export {};
|
||||
|
|
|
|||
280
src/ListStyle.ts
280
src/ListStyle.ts
|
|
@ -1,4 +1,4 @@
|
|||
import { MarkdownPostProcessorContext, TFolder, TFile, Plugin } from 'obsidian';
|
||||
import { MarkdownPostProcessorContext, TFolder, TFile } from 'obsidian';
|
||||
import { extractFolderName, getFolderNote } from '../../functions/folderNoteFunctions';
|
||||
import { FolderOverview, overviewSettings } from './FolderOverview';
|
||||
import { getFolderPathFromString } from '../../functions/utils';
|
||||
|
|
@ -6,169 +6,169 @@ import FolderOverviewPlugin from './main';
|
|||
import FolderNotesPlugin from '../../main';
|
||||
|
||||
export function renderListOverview(plugin: FolderOverviewPlugin | FolderNotesPlugin, ctx: MarkdownPostProcessorContext, root: HTMLElement, yaml: overviewSettings, pathBlacklist: string[], folderOverview: FolderOverview) {
|
||||
const overviewList = folderOverview.listEl;
|
||||
overviewList?.empty();
|
||||
let tFolder = plugin.app.vault.getAbstractFileByPath(yaml.folderPath);
|
||||
if (!tFolder && yaml.folderPath.trim() == '') {
|
||||
if (ctx.sourcePath.includes('/')) {
|
||||
tFolder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(ctx.sourcePath));
|
||||
} else {
|
||||
yaml.folderPath = '/';
|
||||
tFolder = plugin.app.vault.getAbstractFileByPath('/');
|
||||
}
|
||||
}
|
||||
if (!(tFolder instanceof TFolder)) { return; }
|
||||
const overviewList = folderOverview.listEl;
|
||||
overviewList?.empty();
|
||||
let tFolder = plugin.app.vault.getAbstractFileByPath(yaml.folderPath);
|
||||
if (!tFolder && yaml.folderPath.trim() === '') {
|
||||
if (ctx.sourcePath.includes('/')) {
|
||||
tFolder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(ctx.sourcePath));
|
||||
} else {
|
||||
yaml.folderPath = '/';
|
||||
tFolder = plugin.app.vault.getAbstractFileByPath('/');
|
||||
}
|
||||
}
|
||||
if (!(tFolder instanceof TFolder)) { return; }
|
||||
|
||||
let files = tFolder.children;
|
||||
if (!files) { return; }
|
||||
const ul = folderOverview.listEl;
|
||||
const sourceFolderPath = tFolder.path;
|
||||
let files = tFolder.children;
|
||||
if (!files) { return; }
|
||||
const ul = folderOverview.listEl;
|
||||
const sourceFolderPath = tFolder.path;
|
||||
|
||||
const folders = folderOverview.sortFiles(files.filter(f => f instanceof TFolder));
|
||||
files = folderOverview.sortFiles(files.filter(f => f instanceof TFile));
|
||||
folders.forEach((file) => {
|
||||
if (file instanceof TFolder) {
|
||||
if (yaml.includeTypes.includes('folder')) {
|
||||
const folderItem = addFolderList(plugin, ul, folderOverview.pathBlacklist, file, folderOverview);
|
||||
if (!folderItem) { return; }
|
||||
goThroughFolders(plugin, folderItem, file, folderOverview.yaml.depth, sourceFolderPath, ctx, folderOverview.yaml, folderOverview.pathBlacklist, folderOverview.yaml.includeTypes, folderOverview.yaml.disableFileTag, folderOverview);
|
||||
} else {
|
||||
goThroughFolders(plugin, ul, file, folderOverview.yaml.depth, sourceFolderPath, ctx, folderOverview.yaml, folderOverview.pathBlacklist, folderOverview.yaml.includeTypes, folderOverview.yaml.disableFileTag, folderOverview);
|
||||
}
|
||||
}
|
||||
});
|
||||
const folders = folderOverview.sortFiles(files.filter((f) => f instanceof TFolder));
|
||||
files = folderOverview.sortFiles(files.filter((f) => f instanceof TFile));
|
||||
folders.forEach((file) => {
|
||||
if (file instanceof TFolder) {
|
||||
if (yaml.includeTypes.includes('folder')) {
|
||||
const folderItem = addFolderList(plugin, ul, folderOverview.pathBlacklist, file, folderOverview);
|
||||
if (!folderItem) { return; }
|
||||
goThroughFolders(plugin, folderItem, file, folderOverview.yaml.depth, sourceFolderPath, ctx, folderOverview.yaml, folderOverview.pathBlacklist, folderOverview.yaml.includeTypes, folderOverview.yaml.disableFileTag, folderOverview);
|
||||
} else {
|
||||
goThroughFolders(plugin, ul, 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);
|
||||
}
|
||||
});
|
||||
files.forEach((file) => {
|
||||
if (file instanceof TFile) {
|
||||
addFileList(plugin, ul, folderOverview.pathBlacklist, file, folderOverview.yaml.includeTypes, folderOverview.yaml.disableFileTag, folderOverview);
|
||||
}
|
||||
});
|
||||
|
||||
// Event system for rendering list style
|
||||
const debouncedRenderListOverview = debounce(() => renderListOverview(plugin, ctx, root, yaml, pathBlacklist, folderOverview), 300);
|
||||
const handleVaultChange = () => {
|
||||
debouncedRenderListOverview();
|
||||
}
|
||||
// Event system for rendering list style
|
||||
const debouncedRenderListOverview = debounce(() => renderListOverview(plugin, ctx, root, yaml, pathBlacklist, folderOverview), 300);
|
||||
const handleVaultChange = () => {
|
||||
debouncedRenderListOverview();
|
||||
};
|
||||
|
||||
folderOverview.on('vault-change', handleVaultChange);
|
||||
folderOverview.on('vault-change', handleVaultChange);
|
||||
}
|
||||
|
||||
function debounce(func: Function, wait: number) {
|
||||
let timeout: number | undefined;
|
||||
return (...args: any[]) => {
|
||||
clearTimeout(timeout);
|
||||
timeout = window.setTimeout(() => func.apply(this, args), wait);
|
||||
};
|
||||
let timeout: number | undefined;
|
||||
return (...args: any[]) => {
|
||||
clearTimeout(timeout);
|
||||
timeout = window.setTimeout(() => func.apply(this, args), wait);
|
||||
};
|
||||
}
|
||||
|
||||
export function addFolderList(plugin: FolderOverviewPlugin | FolderNotesPlugin | FolderNotesPlugin, list: HTMLUListElement | HTMLLIElement, pathBlacklist: string[], folder: TFolder, folderOverview: FolderOverview) {
|
||||
folderOverview.el.parentElement?.classList.add('fv-remove-edit-button');
|
||||
const isFirstLevelSub = folder.path.split('/').length === folderOverview.yaml.folderPath.split('/').length + 1;
|
||||
if (!folderOverview.yaml.showEmptyFolders && folder.children.length === 0 && !folderOverview.yaml.onlyIncludeSubfolders) {
|
||||
return;
|
||||
} else if (folderOverview.yaml.onlyIncludeSubfolders && !isFirstLevelSub && folder.children.length === 0) {
|
||||
return;
|
||||
}
|
||||
folderOverview.el.parentElement?.classList.add('fv-remove-edit-button');
|
||||
const isFirstLevelSub = folder.path.split('/').length === folderOverview.yaml.folderPath.split('/').length + 1;
|
||||
if (!folderOverview.yaml.showEmptyFolders && folder.children.length === 0 && !folderOverview.yaml.onlyIncludeSubfolders) {
|
||||
return;
|
||||
} else if (folderOverview.yaml.onlyIncludeSubfolders && !isFirstLevelSub && folder.children.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const folderItem = list.createEl('li', { cls: 'folder-overview-list folder-list' });
|
||||
if (plugin instanceof FolderNotesPlugin) {
|
||||
const folderNote = getFolderNote(plugin, folder.path);
|
||||
if (folderNote instanceof TFile) {
|
||||
const folderNoteLink = folderItem.createEl('a', { cls: 'folder-overview-list-item folder-name-item internal-link', href: folderNote.path });
|
||||
folderNoteLink.innerText = folder.name;
|
||||
pathBlacklist.push(folderNote.path);
|
||||
folderNoteLink.oncontextmenu = (e) => {
|
||||
e.stopImmediatePropagation();
|
||||
folderOverview.fileMenu(folderNote, e);
|
||||
}
|
||||
} else {
|
||||
const folderName = folderItem.createEl('span', { cls: 'folder-overview-list-item folder-name-item' });
|
||||
folderName.innerText = folder.name;
|
||||
folderName.oncontextmenu = (e) => {
|
||||
folderOverview.folderMenu(folder, e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const folderName = folderItem.createEl('span', { cls: 'folder-overview-list-item folder-name-item' });
|
||||
folderName.innerText = folder.name;
|
||||
folderName.oncontextmenu = (e) => {
|
||||
folderOverview.folderMenu(folder, e);
|
||||
}
|
||||
}
|
||||
const folderItem = list.createEl('li', { cls: 'folder-overview-list folder-list' });
|
||||
if (plugin instanceof FolderNotesPlugin) {
|
||||
const folderNote = getFolderNote(plugin, folder.path);
|
||||
if (folderNote instanceof TFile) {
|
||||
const folderNoteLink = folderItem.createEl('a', { cls: 'folder-overview-list-item folder-name-item internal-link', href: folderNote.path });
|
||||
folderNoteLink.innerText = folder.name;
|
||||
pathBlacklist.push(folderNote.path);
|
||||
folderNoteLink.oncontextmenu = (e) => {
|
||||
e.stopImmediatePropagation();
|
||||
folderOverview.fileMenu(folderNote, e);
|
||||
};
|
||||
} else {
|
||||
const folderName = folderItem.createEl('span', { cls: 'folder-overview-list-item folder-name-item' });
|
||||
folderName.innerText = folder.name;
|
||||
folderName.oncontextmenu = (e) => {
|
||||
folderOverview.folderMenu(folder, e);
|
||||
};
|
||||
}
|
||||
} else {
|
||||
const folderName = folderItem.createEl('span', { cls: 'folder-overview-list-item folder-name-item' });
|
||||
folderName.innerText = folder.name;
|
||||
folderName.oncontextmenu = (e) => {
|
||||
folderOverview.folderMenu(folder, e);
|
||||
};
|
||||
}
|
||||
|
||||
return folderItem;
|
||||
return folderItem;
|
||||
}
|
||||
|
||||
async function goThroughFolders(plugin: FolderOverviewPlugin | FolderNotesPlugin, list: HTMLLIElement | HTMLUListElement, folder: TFolder,
|
||||
depth: number, sourceFolderPath: string, ctx: MarkdownPostProcessorContext, yaml: overviewSettings,
|
||||
pathBlacklist: string[], includeTypes: string[], disableFileTag: boolean, folderOverview: FolderOverview) {
|
||||
if (sourceFolderPath === '') {
|
||||
depth--;
|
||||
}
|
||||
depth: number, sourceFolderPath: string, ctx: MarkdownPostProcessorContext, yaml: overviewSettings,
|
||||
pathBlacklist: string[], includeTypes: string[], disableFileTag: boolean, folderOverview: FolderOverview) {
|
||||
if (sourceFolderPath === '') {
|
||||
depth--;
|
||||
}
|
||||
|
||||
const allFiles = await folderOverview.filterFiles(folder.children, plugin, sourceFolderPath, depth, pathBlacklist);
|
||||
const files = folderOverview.sortFiles(allFiles.filter((file): file is TFile => !(file instanceof TFolder) && file !== null));
|
||||
const allFiles = await folderOverview.filterFiles(folder.children, plugin, sourceFolderPath, depth, pathBlacklist);
|
||||
const files = folderOverview.sortFiles(allFiles.filter((file): file is TFile => !(file instanceof TFolder) && file !== null));
|
||||
|
||||
const folders = folderOverview.sortFiles(allFiles.filter((file): file is TFile => (file instanceof TFolder) && file !== null));
|
||||
const ul = list.createEl('ul', { cls: 'folder-overview-list' });
|
||||
const folders = folderOverview.sortFiles(allFiles.filter((file): file is TFile => (file instanceof TFolder) && file !== null));
|
||||
const ul = list.createEl('ul', { cls: 'folder-overview-list' });
|
||||
|
||||
folders.forEach((file) => {
|
||||
if (file instanceof TFolder) {
|
||||
if (yaml.includeTypes.includes('folder')) {
|
||||
const folderItem = addFolderList(plugin, ul, pathBlacklist, file, folderOverview);
|
||||
if (!folderItem) { return; }
|
||||
goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag, folderOverview);
|
||||
} else {
|
||||
goThroughFolders(plugin, list, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag, folderOverview);
|
||||
}
|
||||
}
|
||||
});
|
||||
folders.forEach((file) => {
|
||||
if (file instanceof TFolder) {
|
||||
if (yaml.includeTypes.includes('folder')) {
|
||||
const folderItem = addFolderList(plugin, ul, pathBlacklist, file, folderOverview);
|
||||
if (!folderItem) { return; }
|
||||
goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag, folderOverview);
|
||||
} else {
|
||||
goThroughFolders(plugin, list, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag, folderOverview);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
files.forEach((file) => {
|
||||
if (file instanceof TFile) {
|
||||
if (yaml.includeTypes.includes('folder')) {
|
||||
addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag, folderOverview);
|
||||
} else {
|
||||
addFileList(plugin, list, pathBlacklist, file, includeTypes, disableFileTag, folderOverview);
|
||||
}
|
||||
}
|
||||
});
|
||||
files.forEach((file) => {
|
||||
if (file instanceof TFile) {
|
||||
if (yaml.includeTypes.includes('folder')) {
|
||||
addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag, folderOverview);
|
||||
} else {
|
||||
addFileList(plugin, list, pathBlacklist, file, includeTypes, disableFileTag, folderOverview);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addFileList(plugin: FolderOverviewPlugin | FolderNotesPlugin, list: HTMLUListElement | HTMLLIElement, pathBlacklist: string[], file: TFile, includeTypes: string[], disableFileTag: boolean, folderOverview: FolderOverview) {
|
||||
if (includeTypes.length > 0 && !includeTypes.includes('all')) {
|
||||
if (file.extension === 'md' && !includeTypes.includes('markdown')) return;
|
||||
if (file.extension === 'canvas' && !includeTypes.includes('canvas')) return;
|
||||
if (file.extension === 'pdf' && !includeTypes.includes('pdf')) return;
|
||||
const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp'];
|
||||
if (imageTypes.includes(file.extension) && !includeTypes.includes('image')) return;
|
||||
const videoTypes = ['mp4', 'webm', 'ogv', 'mov', 'mkv'];
|
||||
if (videoTypes.includes(file.extension) && !includeTypes.includes('video')) return;
|
||||
const audioTypes = ['mp3', 'wav', 'm4a', '3gp', 'flac', 'ogg', 'oga', 'opus'];
|
||||
if (audioTypes.includes(file.extension) && includeTypes.includes('audio')) return;
|
||||
const allTypes = ['md', 'canvas', 'pdf', ...imageTypes, ...videoTypes, ...audioTypes];
|
||||
if (!allTypes.includes(file.extension) && !includeTypes.includes('other')) return;
|
||||
}
|
||||
if (includeTypes.length > 0 && !includeTypes.includes('all')) {
|
||||
if (file.extension === 'md' && !includeTypes.includes('markdown')) return;
|
||||
if (file.extension === 'canvas' && !includeTypes.includes('canvas')) return;
|
||||
if (file.extension === 'pdf' && !includeTypes.includes('pdf')) return;
|
||||
const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp'];
|
||||
if (imageTypes.includes(file.extension) && !includeTypes.includes('image')) return;
|
||||
const videoTypes = ['mp4', 'webm', 'ogv', 'mov', 'mkv'];
|
||||
if (videoTypes.includes(file.extension) && !includeTypes.includes('video')) return;
|
||||
const audioTypes = ['mp3', 'wav', 'm4a', '3gp', 'flac', 'ogg', 'oga', 'opus'];
|
||||
if (audioTypes.includes(file.extension) && includeTypes.includes('audio')) return;
|
||||
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;
|
||||
if (plugin instanceof FolderNotesPlugin && extractFolderName(plugin.settings.folderNoteName, file.basename) === file.parent?.name) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!folderOverview.yaml.showFolderNotes) {
|
||||
if (pathBlacklist.includes(file.path)) return;
|
||||
if (plugin instanceof FolderNotesPlugin && extractFolderName(plugin.settings.folderNoteName, file.basename) === file.parent?.name) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
folderOverview.el.parentElement?.classList.add('fv-remove-edit-button');
|
||||
const listItem = list.createEl('li', { cls: 'folder-overview-list file-link' });
|
||||
listItem.oncontextmenu = (e) => {
|
||||
e.stopImmediatePropagation();
|
||||
folderOverview.fileMenu(file, e);
|
||||
}
|
||||
folderOverview.el.parentElement?.classList.add('fv-remove-edit-button');
|
||||
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;
|
||||
if (file.extension !== 'md' && !disableFileTag) {
|
||||
nameItem.createDiv({ cls: 'nav-file-tag' }).innerText = file.extension;
|
||||
}
|
||||
}
|
||||
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;
|
||||
if (file.extension !== 'md' && !disableFileTag) {
|
||||
nameItem.createDiv({ cls: 'nav-file-tag' }).innerText = file.extension;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import { DEFAULT_SETTINGS, SettingsTab } from './settings';
|
|||
import { registerOverviewCommands } from './Commands';
|
||||
import { FolderOverviewSettings } from './modals/Settings';
|
||||
import FolderNotesPlugin from '../../main';
|
||||
import { FolderNotesSettings } from '../../settings/SettingsTab';
|
||||
|
||||
export default class FolderOverviewPlugin extends Plugin {
|
||||
settings: overviewSettings;
|
||||
|
|
@ -100,7 +99,7 @@ export async function updateOverviewView(plugin: FolderOverviewPlugin | FolderNo
|
|||
const view = leaf.view as any as FolderOverviewView;
|
||||
if (!view) return;
|
||||
if (!view.yaml) return;
|
||||
const yaml = view.yaml.id === '' ? view.yaml : newYaml;
|
||||
const yaml = view.yaml.id === '' ? view.yaml : newYaml;
|
||||
view.display(view.contentEl, yaml ?? view.yaml, plugin, view.defaultSettings, view.display, undefined, undefined, view.activeFile, plugin.settingsTab, view.modal, 'all');
|
||||
}
|
||||
|
||||
|
|
@ -110,4 +109,4 @@ export async function updateViewDropdown(plugin: FolderOverviewPlugin | FolderNo
|
|||
if (!leaf) return;
|
||||
const view = leaf.view as any as FolderOverviewView;
|
||||
view.display(view.contentEl, view.yaml, plugin, view.defaultSettings, view.display, undefined, undefined, view.activeFile, plugin.settingsTab, view.modal, 'dropdown');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
import { App, Modal, Setting, MarkdownPostProcessorContext, stringifyYaml, TFile, TFolder, SettingTab, Plugin } from 'obsidian';
|
||||
import { overviewSettings, includeTypes, FolderOverview } from '../FolderOverview';
|
||||
import { ListComponent } from '../utils/ListComponent';
|
||||
import { updateYaml } from '../FolderOverview';
|
||||
import { FolderSuggest } from '../suggesters/FolderSuggester';
|
||||
import { App, Modal, MarkdownPostProcessorContext, TFile, SettingTab } from 'obsidian';
|
||||
import { overviewSettings, includeTypes, updateYaml } from '../FolderOverview';
|
||||
import { getFolderPathFromString } from '../utils/functions';
|
||||
import { createOverviewSettings } from '../settings';
|
||||
import FolderOverviewPlugin from '../main';
|
||||
|
|
@ -41,7 +38,7 @@ export class FolderOverviewSettings extends Modal {
|
|||
alwaysCollapse: yaml?.alwaysCollapse ?? defaultSettings.alwaysCollapse,
|
||||
autoSync: yaml?.autoSync ?? defaultSettings.autoSync,
|
||||
allowDragAndDrop: yaml?.allowDragAndDrop ?? defaultSettings.allowDragAndDrop,
|
||||
}
|
||||
};
|
||||
}
|
||||
if (ctx) {
|
||||
this.ctx = ctx;
|
||||
|
|
@ -58,16 +55,16 @@ export class FolderOverviewSettings extends Modal {
|
|||
this.display(contentEl, this.yaml, this.plugin, this.defaultSettings, this.display, this.el, this.ctx);
|
||||
}
|
||||
|
||||
display(contentEl: HTMLElement,
|
||||
yaml: overviewSettings,
|
||||
display(contentEl: HTMLElement,
|
||||
yaml: overviewSettings,
|
||||
plugin: FolderOverviewPlugin | FolderNotesPlugin,
|
||||
defaultSettings: overviewSettings,
|
||||
display: CallableFunction,
|
||||
el?: HTMLElement,
|
||||
ctx?: MarkdownPostProcessorContext,
|
||||
file?: TFile | null,
|
||||
settingsTab?: SettingTab,
|
||||
modal?: FolderOverviewSettings,
|
||||
defaultSettings: overviewSettings,
|
||||
display: CallableFunction,
|
||||
el?: HTMLElement,
|
||||
ctx?: MarkdownPostProcessorContext,
|
||||
file?: TFile | null,
|
||||
settingsTab?: SettingTab,
|
||||
modal?: FolderOverviewSettings,
|
||||
changedSection?: string) {
|
||||
modal = this ?? modal;
|
||||
contentEl.empty();
|
||||
|
|
|
|||
735
src/settings.ts
735
src/settings.ts
|
|
@ -1,8 +1,7 @@
|
|||
import { MarkdownPostProcessorContext, normalizePath, Plugin, Plugin$1, PluginSettingTab, Setting, TFile, TFolder } from 'obsidian';
|
||||
import { MarkdownPostProcessorContext, normalizePath, PluginSettingTab, Setting, TFile, TFolder } from 'obsidian';
|
||||
import { updateYaml, updateYamlById, overviewSettings, includeTypes } from './FolderOverview';
|
||||
import { FolderSuggest } from './suggesters/FolderSuggester';
|
||||
import { ListComponent } from './utils/ListComponent';
|
||||
import { Callback } from 'front-matter-plugin-api-provider';
|
||||
import { FolderOverviewSettings } from './modals/Settings';
|
||||
import FolderOverviewPlugin from './main';
|
||||
import FolderNotesPlugin from '../../main';
|
||||
|
|
@ -11,416 +10,416 @@ import FolderNotesPlugin from '../../main';
|
|||
|
||||
|
||||
export const DEFAULT_SETTINGS: overviewSettings = {
|
||||
id: '',
|
||||
folderPath: '',
|
||||
title: '{{folderName}} overview',
|
||||
showTitle: false,
|
||||
depth: 3,
|
||||
includeTypes: ['folder', 'markdown'],
|
||||
style: 'list',
|
||||
disableFileTag: false,
|
||||
sortBy: 'name',
|
||||
sortByAsc: true,
|
||||
showEmptyFolders: false,
|
||||
onlyIncludeSubfolders: false,
|
||||
storeFolderCondition: true,
|
||||
showFolderNotes: false,
|
||||
disableCollapseIcon: true,
|
||||
alwaysCollapse: false,
|
||||
autoSync: true,
|
||||
allowDragAndDrop: true,
|
||||
}
|
||||
id: '',
|
||||
folderPath: '',
|
||||
title: '{{folderName}} overview',
|
||||
showTitle: false,
|
||||
depth: 3,
|
||||
includeTypes: ['folder', 'markdown'],
|
||||
style: 'list',
|
||||
disableFileTag: false,
|
||||
sortBy: 'name',
|
||||
sortByAsc: true,
|
||||
showEmptyFolders: false,
|
||||
onlyIncludeSubfolders: false,
|
||||
storeFolderCondition: true,
|
||||
showFolderNotes: false,
|
||||
disableCollapseIcon: true,
|
||||
alwaysCollapse: false,
|
||||
autoSync: true,
|
||||
allowDragAndDrop: true,
|
||||
};
|
||||
|
||||
export class SettingsTab extends PluginSettingTab {
|
||||
plugin: FolderOverviewPlugin;
|
||||
plugin: FolderOverviewPlugin;
|
||||
|
||||
constructor(plugin: FolderOverviewPlugin) {
|
||||
super(plugin.app, plugin);
|
||||
}
|
||||
constructor(plugin: FolderOverviewPlugin) {
|
||||
super(plugin.app, plugin);
|
||||
}
|
||||
|
||||
display() {
|
||||
const { containerEl } = this;
|
||||
containerEl.empty();
|
||||
containerEl.createEl('p', { text: 'Edit the default settings of folder overviews', cls: 'setting-item-description' });
|
||||
display() {
|
||||
const { containerEl } = this;
|
||||
containerEl.empty();
|
||||
containerEl.createEl('p', { text: 'Edit the default settings of folder overviews', cls: 'setting-item-description' });
|
||||
|
||||
this.display = this.display.bind(this);
|
||||
this.display = this.display.bind(this);
|
||||
|
||||
createOverviewSettings(containerEl, this.plugin.settings, this.plugin, this.plugin.settings, this.display, undefined, undefined, undefined, this);
|
||||
}
|
||||
createOverviewSettings(containerEl, this.plugin.settings, this.plugin, this.plugin.settings, this.display, undefined, undefined, undefined, this);
|
||||
}
|
||||
}
|
||||
|
||||
const createOrReplaceSetting = (
|
||||
container: HTMLElement,
|
||||
section: string,
|
||||
changedSection: string | null,
|
||||
renderSetting: (el: HTMLElement) => void
|
||||
container: HTMLElement,
|
||||
section: string,
|
||||
changedSection: string | null,
|
||||
renderSetting: (el: HTMLElement) => void
|
||||
) => {
|
||||
let sectionContainer = container.querySelector(`.setting-${section}`);
|
||||
if (sectionContainer) {
|
||||
if (changedSection === section || changedSection === 'all') {
|
||||
sectionContainer.empty();
|
||||
renderSetting(sectionContainer as HTMLElement);
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
let sectionContainer = container.querySelector(`.setting-${section}`);
|
||||
if (sectionContainer) {
|
||||
if (changedSection === section || changedSection === 'all') {
|
||||
sectionContainer.empty();
|
||||
renderSetting(sectionContainer as HTMLElement);
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sectionContainer = container.createDiv({ cls: `setting-${section} overview-setting-item-fv` });
|
||||
renderSetting(sectionContainer as HTMLElement);
|
||||
sectionContainer = container.createDiv({ cls: `setting-${section} overview-setting-item-fv` });
|
||||
renderSetting(sectionContainer as HTMLElement);
|
||||
};
|
||||
|
||||
|
||||
export async function createOverviewSettings(contentEl: HTMLElement, yaml: overviewSettings, plugin: FolderOverviewPlugin | FolderNotesPlugin, defaultSettings: overviewSettings, display: CallableFunction, el?: HTMLElement, ctx?: MarkdownPostProcessorContext, file?: TFile | null, settingsTab?: PluginSettingTab, modal?: FolderOverviewSettings, changedSection?: string | null) {
|
||||
changedSection = changedSection ?? null;
|
||||
changedSection = changedSection ?? null;
|
||||
|
||||
createOrReplaceSetting(contentEl, 'auto-sync', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Auto sync')
|
||||
.setDesc('Choose if the overview should automatically update when you delete, create or rename a file/folder')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(yaml.autoSync)
|
||||
.onChange(async (value) => {
|
||||
yaml.autoSync = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
})
|
||||
);
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'auto-sync', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Auto sync')
|
||||
.setDesc('Choose if the overview should automatically update when you delete, create or rename a file/folder')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(yaml.autoSync)
|
||||
.onChange(async (value) => {
|
||||
yaml.autoSync = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'allow-drag-and-drop', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Allow drag and drop')
|
||||
.setDesc('Choose if you want to allow drag and drop in the overview')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(yaml.allowDragAndDrop)
|
||||
.onChange(async (value) => {
|
||||
yaml.allowDragAndDrop = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
})
|
||||
);
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'allow-drag-and-drop', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Allow drag and drop')
|
||||
.setDesc('Choose if you want to allow drag and drop in the overview')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(yaml.allowDragAndDrop)
|
||||
.onChange(async (value) => {
|
||||
yaml.allowDragAndDrop = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'showTitle', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Show the title')
|
||||
.setDesc('Choose if the title should be shown')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(yaml.showTitle)
|
||||
.onChange(async (value) => {
|
||||
yaml.showTitle = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
})
|
||||
);
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'showTitle', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Show the title')
|
||||
.setDesc('Choose if the title should be shown')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(yaml.showTitle)
|
||||
.onChange(async (value) => {
|
||||
yaml.showTitle = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'title-container-fn', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Title')
|
||||
.setDesc('Choose the title of the folder overview')
|
||||
.addText((text) =>
|
||||
text
|
||||
.setValue(yaml?.title || '{{folderName}} overview')
|
||||
.onChange(async (value) => {
|
||||
yaml.title = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
})
|
||||
);
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'title-container-fn', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Title')
|
||||
.setDesc('Choose the title of the folder overview')
|
||||
.addText((text) =>
|
||||
text
|
||||
.setValue(yaml?.title || '{{folderName}} overview')
|
||||
.onChange(async (value) => {
|
||||
yaml.title = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'folder-path', changedSection, (settingEl) => {
|
||||
const folderPathSetting = new Setting(settingEl)
|
||||
.setName('Folder path for the overview')
|
||||
.setDesc('Choose the folder path for the overview')
|
||||
.addSearch((search) => {
|
||||
new FolderSuggest(search.inputEl, plugin, false);
|
||||
search
|
||||
.setPlaceholder('Folder path')
|
||||
.setValue(yaml?.folderPath || '')
|
||||
.onChange(async (value) => {
|
||||
if (value.trim() !== '') {
|
||||
value = normalizePath(value);
|
||||
}
|
||||
if (!(plugin.app.vault.getAbstractFileByPath(value) instanceof TFolder) && value !== '') return;
|
||||
yaml.folderPath = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
folderPathSetting.settingEl.classList.add('fn-overview-folder-path');
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'folder-path', changedSection, (settingEl) => {
|
||||
const folderPathSetting = new Setting(settingEl)
|
||||
.setName('Folder path for the overview')
|
||||
.setDesc('Choose the folder path for the overview')
|
||||
.addSearch((search) => {
|
||||
new FolderSuggest(search.inputEl, plugin, false);
|
||||
search
|
||||
.setPlaceholder('Folder path')
|
||||
.setValue(yaml?.folderPath || '')
|
||||
.onChange(async (value) => {
|
||||
if (value.trim() !== '') {
|
||||
value = normalizePath(value);
|
||||
}
|
||||
if (!(plugin.app.vault.getAbstractFileByPath(value) instanceof TFolder) && value !== '') return;
|
||||
yaml.folderPath = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
folderPathSetting.settingEl.classList.add('fn-overview-folder-path');
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'overview-style', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Overview style')
|
||||
.setDesc('Choose the style of the overview (grid style soon)')
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOption('list', 'List')
|
||||
.addOption('explorer', 'Explorer')
|
||||
.setValue(yaml?.style || 'list')
|
||||
.onChange(async (value: 'list') => {
|
||||
yaml.style = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
})
|
||||
);
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'overview-style', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Overview style')
|
||||
.setDesc('Choose the style of the overview (grid style soon)')
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOption('list', 'List')
|
||||
.addOption('explorer', 'Explorer')
|
||||
.setValue(yaml?.style || 'list')
|
||||
.onChange(async (value: 'list') => {
|
||||
yaml.style = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'include-types', changedSection, (settingEl) => {
|
||||
const setting = new Setting(settingEl);
|
||||
setting.setName('Include types');
|
||||
const list = new ListComponent(setting.settingEl, yaml.includeTypes || [], ['markdown', 'folder']);
|
||||
list.on('update', (values) => {
|
||||
yaml.includeTypes = values;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal, 'include-types');
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'include-types', changedSection, (settingEl) => {
|
||||
const setting = new Setting(settingEl);
|
||||
setting.setName('Include types');
|
||||
const list = new ListComponent(setting.settingEl, yaml.includeTypes || [], ['markdown', 'folder']);
|
||||
list.on('update', (values) => {
|
||||
yaml.includeTypes = values;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal, 'include-types');
|
||||
});
|
||||
|
||||
if ((yaml?.includeTypes?.length || 0) < 8 && !yaml.includeTypes?.includes('all')) {
|
||||
setting.addDropdown((dropdown) => {
|
||||
if (!yaml.includeTypes) yaml.includeTypes = (plugin instanceof FolderNotesPlugin) ? plugin.settings.defaultOverview.includeTypes : plugin.settings.includeTypes || [];
|
||||
yaml.includeTypes = yaml.includeTypes.map((type: string) => type.toLowerCase()) as includeTypes[];
|
||||
const options = [
|
||||
{ value: 'markdown', label: 'Markdown' },
|
||||
{ value: 'folder', label: 'Folder' },
|
||||
{ value: 'canvas', label: 'Canvas' },
|
||||
{ value: 'pdf', label: 'PDF' },
|
||||
{ value: 'image', label: 'Image' },
|
||||
{ value: 'audio', label: 'Audio' },
|
||||
{ value: 'video', label: 'Video' },
|
||||
{ value: 'other', label: 'All other file types' },
|
||||
{ value: 'all', label: 'All file types' },
|
||||
];
|
||||
if ((yaml?.includeTypes?.length || 0) < 8 && !yaml.includeTypes?.includes('all')) {
|
||||
setting.addDropdown((dropdown) => {
|
||||
if (!yaml.includeTypes) yaml.includeTypes = (plugin instanceof FolderNotesPlugin) ? plugin.settings.defaultOverview.includeTypes : plugin.settings.includeTypes || [];
|
||||
yaml.includeTypes = yaml.includeTypes.map((type: string) => type.toLowerCase()) as includeTypes[];
|
||||
const options = [
|
||||
{ value: 'markdown', label: 'Markdown' },
|
||||
{ value: 'folder', label: 'Folder' },
|
||||
{ value: 'canvas', label: 'Canvas' },
|
||||
{ value: 'pdf', label: 'PDF' },
|
||||
{ value: 'image', label: 'Image' },
|
||||
{ value: 'audio', label: 'Audio' },
|
||||
{ value: 'video', label: 'Video' },
|
||||
{ value: 'other', label: 'All other file types' },
|
||||
{ value: 'all', label: 'All file types' },
|
||||
];
|
||||
|
||||
options.forEach((option) => {
|
||||
if (!yaml.includeTypes?.includes(option.value as includeTypes)) {
|
||||
dropdown.addOption(option.value, option.label);
|
||||
}
|
||||
});
|
||||
dropdown.addOption('+', '+');
|
||||
dropdown.setValue('+');
|
||||
dropdown.onChange(async (value) => {
|
||||
if (value === 'all') {
|
||||
yaml.includeTypes = yaml.includeTypes?.filter((type: string) => type === 'folder');
|
||||
list.setValues(yaml.includeTypes);
|
||||
}
|
||||
await list.addValue(value.toLowerCase());
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal, 'include-types');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
options.forEach((option) => {
|
||||
if (!yaml.includeTypes?.includes(option.value as includeTypes)) {
|
||||
dropdown.addOption(option.value, option.label);
|
||||
}
|
||||
});
|
||||
dropdown.addOption('+', '+');
|
||||
dropdown.setValue('+');
|
||||
dropdown.onChange(async (value) => {
|
||||
if (value === 'all') {
|
||||
yaml.includeTypes = yaml.includeTypes?.filter((type: string) => type === 'folder');
|
||||
list.setValues(yaml.includeTypes);
|
||||
}
|
||||
await list.addValue(value.toLowerCase());
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal, 'include-types');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'file-tag', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Disable file tag')
|
||||
.setDesc('Choose if the file tag should be shown after the file name')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(yaml.disableFileTag)
|
||||
.onChange(async (value) => {
|
||||
yaml.disableFileTag = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'file-tag', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Disable file tag')
|
||||
.setDesc('Choose if the file tag should be shown after the file name')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(yaml.disableFileTag)
|
||||
.onChange(async (value) => {
|
||||
yaml.disableFileTag = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'show-folder-notes', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Show folder notes')
|
||||
.setDesc('Choose if folder notes (the note itself and not the folder name) should be shown in the overview')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(yaml.showFolderNotes)
|
||||
.onChange(async (value) => {
|
||||
yaml.showFolderNotes = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
})
|
||||
);
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'show-folder-notes', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Show folder notes')
|
||||
.setDesc('Choose if folder notes (the note itself and not the folder name) should be shown in the overview')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(yaml.showFolderNotes)
|
||||
.onChange(async (value) => {
|
||||
yaml.showFolderNotes = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'file-depth', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('File depth')
|
||||
.setDesc('File & folder = +1 depth')
|
||||
.addSlider((slider) =>
|
||||
slider
|
||||
.setValue(yaml?.depth || 2)
|
||||
.setLimits(1, 10, 1)
|
||||
.setDynamicTooltip()
|
||||
.onChange(async (value) => {
|
||||
yaml.depth = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
})
|
||||
);
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'file-depth', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('File depth')
|
||||
.setDesc('File & folder = +1 depth')
|
||||
.addSlider((slider) =>
|
||||
slider
|
||||
.setValue(yaml?.depth || 2)
|
||||
.setLimits(1, 10, 1)
|
||||
.setDynamicTooltip()
|
||||
.onChange(async (value) => {
|
||||
yaml.depth = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'sort-files', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Sort files by')
|
||||
.setDesc('Choose how the files should be sorted')
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOption('name', 'Name')
|
||||
.addOption('created', 'Created')
|
||||
.addOption('modified', 'Modified')
|
||||
.setValue(yaml?.sortBy || 'name')
|
||||
.onChange(async (value: 'name' | 'created' | 'modified') => {
|
||||
yaml.sortBy = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
})
|
||||
)
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
.addOption('desc', 'Descending')
|
||||
.addOption('asc', 'Ascending');
|
||||
if (yaml.sortByAsc) {
|
||||
dropdown.setValue('asc');
|
||||
} else {
|
||||
dropdown.setValue('desc');
|
||||
}
|
||||
dropdown.onChange(async (value) => {
|
||||
yaml.sortByAsc = value === 'asc';
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'sort-files', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Sort files by')
|
||||
.setDesc('Choose how the files should be sorted')
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOption('name', 'Name')
|
||||
.addOption('created', 'Created')
|
||||
.addOption('modified', 'Modified')
|
||||
.setValue(yaml?.sortBy || 'name')
|
||||
.onChange(async (value: 'name' | 'created' | 'modified') => {
|
||||
yaml.sortBy = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
})
|
||||
)
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
.addOption('desc', 'Descending')
|
||||
.addOption('asc', 'Ascending');
|
||||
if (yaml.sortByAsc) {
|
||||
dropdown.setValue('asc');
|
||||
} else {
|
||||
dropdown.setValue('desc');
|
||||
}
|
||||
dropdown.onChange(async (value) => {
|
||||
yaml.sortByAsc = value === 'asc';
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'show-empty-folders', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Show folder names of folders that appear empty in the folder overview')
|
||||
.setDesc('Show the names of folders that appear to have no files/folders in the folder overview. That\'s mostly the case when you set the file depth to 1.')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(yaml.showEmptyFolders)
|
||||
.onChange(async (value) => {
|
||||
yaml.showEmptyFolders = value;
|
||||
yaml.onlyIncludeSubfolders = false;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
});
|
||||
});
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'show-empty-folders', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Show folder names of folders that appear empty in the folder overview')
|
||||
.setDesc('Show the names of folders that appear to have no files/folders in the folder overview. That\'s mostly the case when you set the file depth to 1.')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(yaml.showEmptyFolders)
|
||||
.onChange(async (value) => {
|
||||
yaml.showEmptyFolders = value;
|
||||
yaml.onlyIncludeSubfolders = false;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
refresh(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'show-empty-folders-only-first-level', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Only show empty folders which are on the first level of the folder overview')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(yaml.onlyIncludeSubfolders)
|
||||
.onChange(async (value) => {
|
||||
yaml.onlyIncludeSubfolders = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'show-empty-folders-only-first-level', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Only show empty folders which are on the first level of the folder overview')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(yaml.onlyIncludeSubfolders)
|
||||
.onChange(async (value) => {
|
||||
yaml.onlyIncludeSubfolders = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'disable-collapse-icon', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Disable collapse icon for folder notes')
|
||||
.setDesc('Remove the collapse icon next to the folder name for folder notes when they only contain the folder note itself')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(yaml.disableCollapseIcon)
|
||||
.onChange(async (value) => {
|
||||
yaml.disableCollapseIcon = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'disable-collapse-icon', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Disable collapse icon for folder notes')
|
||||
.setDesc('Remove the collapse icon next to the folder name for folder notes when they only contain the folder note itself')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(yaml.disableCollapseIcon)
|
||||
.onChange(async (value) => {
|
||||
yaml.disableCollapseIcon = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'store-collapse-condition', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Store collapsed condition')
|
||||
.setDesc('Choose if the collapsed condition should be stored until you restart Obsidian')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(yaml.storeFolderCondition)
|
||||
.onChange(async (value) => {
|
||||
yaml.storeFolderCondition = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
})
|
||||
);
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'store-collapse-condition', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Store collapsed condition')
|
||||
.setDesc('Choose if the collapsed condition should be stored until you restart Obsidian')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(yaml.storeFolderCondition)
|
||||
.onChange(async (value) => {
|
||||
yaml.storeFolderCondition = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
createOrReplaceSetting(contentEl, 'collapse-all-by-default', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Collapse all in the tree by default')
|
||||
.setDesc('Collapse every folder in the file explorer in the overview by default')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(yaml.alwaysCollapse)
|
||||
.onChange(async (value) => {
|
||||
yaml.alwaysCollapse = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
});
|
||||
createOrReplaceSetting(contentEl, 'collapse-all-by-default', changedSection, (settingEl) => {
|
||||
new Setting(settingEl)
|
||||
.setName('Collapse all in the tree by default')
|
||||
.setDesc('Collapse every folder in the file explorer in the overview by default')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(yaml.alwaysCollapse)
|
||||
.onChange(async (value) => {
|
||||
yaml.alwaysCollapse = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
}
|
||||
|
||||
async function updateSettings(contentEl: HTMLElement, yaml: overviewSettings, plugin: FolderOverviewPlugin | FolderNotesPlugin, defaultSettings: overviewSettings, el?: HTMLElement, ctx?: MarkdownPostProcessorContext, file?: TFile | null) {
|
||||
let showDisableFileTag = false;
|
||||
yaml.includeTypes?.forEach((type: string) => {
|
||||
if (type !== 'markdown' && type !== 'folder') {
|
||||
showDisableFileTag = true;
|
||||
}
|
||||
});
|
||||
if (yaml.includeTypes.length === 0) {
|
||||
showDisableFileTag = false;
|
||||
}
|
||||
|
||||
toggleSections(contentEl, {
|
||||
'setting-title-container-fn': yaml.showTitle,
|
||||
'setting-store-collapse-condition': yaml.style === 'explorer',
|
||||
'setting-file-tag': showDisableFileTag,
|
||||
'setting-show-empty-folders': yaml.style === 'list',
|
||||
'setting-show-empty-folders-only-first-level': yaml.showEmptyFolders && yaml.style === 'list',
|
||||
'setting-disable-collapse-icon': yaml.style === 'explorer',
|
||||
'setting-collapse-all-by-default': yaml.style === 'explorer',
|
||||
'setting-allow-drag-and-drop': yaml.style === 'explorer'
|
||||
});
|
||||
if (!yaml.id) {
|
||||
plugin.saveSettings();
|
||||
if (file === undefined) {
|
||||
plugin.updateOverviewView(plugin);
|
||||
}
|
||||
return
|
||||
}
|
||||
let showDisableFileTag = false;
|
||||
yaml.includeTypes?.forEach((type: string) => {
|
||||
if (type !== 'markdown' && type !== 'folder') {
|
||||
showDisableFileTag = true;
|
||||
}
|
||||
});
|
||||
if (yaml.includeTypes.length === 0) {
|
||||
showDisableFileTag = false;
|
||||
}
|
||||
|
||||
if (el && ctx) {
|
||||
await updateYaml(plugin, ctx, el, yaml);
|
||||
}
|
||||
toggleSections(contentEl, {
|
||||
'setting-title-container-fn': yaml.showTitle,
|
||||
'setting-store-collapse-condition': yaml.style === 'explorer',
|
||||
'setting-file-tag': showDisableFileTag,
|
||||
'setting-show-empty-folders': yaml.style === 'list',
|
||||
'setting-show-empty-folders-only-first-level': yaml.showEmptyFolders && yaml.style === 'list',
|
||||
'setting-disable-collapse-icon': yaml.style === 'explorer',
|
||||
'setting-collapse-all-by-default': yaml.style === 'explorer',
|
||||
'setting-allow-drag-and-drop': yaml.style === 'explorer',
|
||||
});
|
||||
if (!yaml.id) {
|
||||
plugin.saveSettings();
|
||||
if (file === undefined) {
|
||||
plugin.updateOverviewView(plugin);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (file) {
|
||||
await updateYamlById(plugin, yaml.id, file, yaml);
|
||||
}
|
||||
if (el && ctx) {
|
||||
await updateYaml(plugin, ctx, el, yaml);
|
||||
}
|
||||
|
||||
if (file) {
|
||||
await updateYamlById(plugin, yaml.id, file, yaml);
|
||||
}
|
||||
}
|
||||
|
||||
function refresh(contentEl: HTMLElement, yaml: overviewSettings, plugin: FolderOverviewPlugin | FolderNotesPlugin, defaultSettings: overviewSettings, display: CallableFunction, el?: HTMLElement, ctx?: MarkdownPostProcessorContext, file?: TFile | null, settingsTab?: PluginSettingTab, modal?: FolderOverviewSettings, changedSection?: string) {
|
||||
if (file) {
|
||||
contentEl = contentEl.parentElement as HTMLElement;
|
||||
}
|
||||
display(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal, changedSection);
|
||||
if (file) {
|
||||
contentEl = contentEl.parentElement as HTMLElement;
|
||||
}
|
||||
display(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal, changedSection);
|
||||
|
||||
}
|
||||
|
||||
function toggleSections(contentEl: HTMLElement, sections: Record<string, boolean>) {
|
||||
Object.entries(sections).forEach(([sectionClass, shouldShow]) => {
|
||||
const sections = contentEl.querySelectorAll(`.${sectionClass}`);
|
||||
sections.forEach((section) => {
|
||||
if (shouldShow && section) {
|
||||
section.classList.remove('hide');
|
||||
} else {
|
||||
section?.classList.add('hide');
|
||||
}
|
||||
});
|
||||
});
|
||||
Object.entries(sections).forEach(([sectionClass, shouldShow]) => {
|
||||
const sections = contentEl.querySelectorAll(`.${sectionClass}`);
|
||||
sections.forEach((section) => {
|
||||
if (shouldShow && section) {
|
||||
section.classList.remove('hide');
|
||||
} else {
|
||||
section?.classList.add('hide');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes and https://github.com/SilentVoid13/Templater
|
||||
|
||||
import { AbstractInputSuggest, TAbstractFile, TFile } from 'obsidian';
|
||||
import FolderNotesPlugin from '../main';
|
||||
import FolderOverviewPlugin from '../main';
|
||||
import FolderNotesPlugin from '../../../main';
|
||||
export enum FileSuggestMode {
|
||||
TemplateFiles,
|
||||
ScriptFiles,
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
export class CustomEventEmitter {
|
||||
private events: { [key: string]: Array<(data?: any) => void> } = {};
|
||||
private events: { [key: string]: Array<(data?: any) => void> } = {};
|
||||
|
||||
on(event: string, listener: (data?: any) => void) {
|
||||
if (!this.events[event]) {
|
||||
this.events[event] = [];
|
||||
}
|
||||
this.events[event].push(listener);
|
||||
}
|
||||
on(event: string, listener: (data?: any) => void) {
|
||||
if (!this.events[event]) {
|
||||
this.events[event] = [];
|
||||
}
|
||||
this.events[event].push(listener);
|
||||
}
|
||||
|
||||
off(event: string, listener: (data?: any) => void) {
|
||||
if (!this.events[event]) return;
|
||||
off(event: string, listener: (data?: any) => void) {
|
||||
if (!this.events[event]) return;
|
||||
|
||||
this.events[event] = this.events[event].filter((l) => l !== listener);
|
||||
}
|
||||
this.events[event] = this.events[event].filter((l) => l !== listener);
|
||||
}
|
||||
|
||||
emit(event: string, data?: any) {
|
||||
if (!this.events[event]) return;
|
||||
emit(event: string, data?: any) {
|
||||
if (!this.events[event]) return;
|
||||
|
||||
this.events[event].forEach((listener) => listener(data));
|
||||
}
|
||||
}
|
||||
this.events[event].forEach((listener) => listener(data));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ export class ListComponent {
|
|||
}
|
||||
span.setAttribute('extension', value);
|
||||
const removeSpan = span.createEl('span', { cls: 'ofn-list-item-remove setting-hotkey-icon' });
|
||||
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 lucide-x"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>';
|
||||
const svgElement = removeSpan.createEl('span', { cls: 'ofn-list-item-remove-icon' });
|
||||
setIcon(svgElement, 'x');
|
||||
removeSpan.onClickEvent((e) => {
|
||||
|
|
@ -74,10 +73,9 @@ export class ListComponent {
|
|||
|
||||
addResetButton() {
|
||||
const resetButton = this.controlEl.createEl('span', { cls: 'clickable-icon setting-restore-hotkey-button' });
|
||||
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 lucide-rotate-ccw"><path d="M3 2v6h6"></path><path d="M3 13a9 9 0 1 0 3-7.7L3 8"></path></svg>';
|
||||
setIcon(resetButton, 'rotate-ccw');
|
||||
resetButton.onClickEvent((e) => {
|
||||
this.setValues(this.defaultValues);
|
||||
this.setValues(this.defaultValues);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
|
@ -88,4 +86,4 @@ export class ListComponent {
|
|||
this.emit('remove', value);
|
||||
this.emit('update', this.values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
export function getFolderPathFromString(path: string): string {
|
||||
const subString = path.lastIndexOf('/') >= 0 ? path.lastIndexOf('/') : 0;
|
||||
const folderPath = path.substring(0, subString);
|
||||
if (folderPath === '') {
|
||||
return '/';
|
||||
} else {
|
||||
return folderPath;
|
||||
}
|
||||
}
|
||||
const subString = path.lastIndexOf('/') >= 0 ? path.lastIndexOf('/') : 0;
|
||||
const folderPath = path.substring(0, subString);
|
||||
if (folderPath === '') {
|
||||
return '/';
|
||||
} else {
|
||||
return folderPath;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
225
src/view.ts
225
src/view.ts
|
|
@ -1,6 +1,5 @@
|
|||
import { ItemView, Setting, TFile, WorkspaceLeaf, MarkdownPostProcessorContext, Notice, Plugin, SettingTab } from 'obsidian';
|
||||
import { FolderOverview, getOverviews, overviewSettings, parseOverviewTitle } from './FolderOverview';
|
||||
import { FileSuggest } from './suggesters/FileSuggester';
|
||||
import { ItemView, Setting, TFile, WorkspaceLeaf, MarkdownPostProcessorContext, SettingTab } from 'obsidian';
|
||||
import { getOverviews, overviewSettings, parseOverviewTitle } from './FolderOverview';
|
||||
import { createOverviewSettings } from './settings';
|
||||
import FolderOverviewPlugin from './main';
|
||||
export const FOLDER_OVERVIEW_VIEW = 'folder-overview-view';
|
||||
|
|
@ -8,135 +7,135 @@ import FolderNotesPlugin from '../../main';
|
|||
import { FolderOverviewSettings } from './modals/Settings';
|
||||
|
||||
export class FolderOverviewView extends ItemView {
|
||||
plugin: FolderOverviewPlugin | FolderNotesPlugin;
|
||||
activeFile: TFile | null;
|
||||
overviewId: string | null;
|
||||
yaml: overviewSettings;
|
||||
defaultSettings: overviewSettings;
|
||||
contentEl: HTMLElement = this.containerEl.children[1] as HTMLElement;
|
||||
changedSection: string | null | undefined;
|
||||
modal: FolderOverviewSettings;
|
||||
plugin: FolderOverviewPlugin | FolderNotesPlugin;
|
||||
activeFile: TFile | null;
|
||||
overviewId: string | null;
|
||||
yaml: overviewSettings;
|
||||
defaultSettings: overviewSettings;
|
||||
contentEl: HTMLElement = this.containerEl.children[1] as HTMLElement;
|
||||
changedSection: string | null | undefined;
|
||||
modal: FolderOverviewSettings;
|
||||
|
||||
constructor(leaf: WorkspaceLeaf, plugin: FolderOverviewPlugin | FolderNotesPlugin) {
|
||||
super(leaf);
|
||||
this.plugin = plugin;
|
||||
constructor(leaf: WorkspaceLeaf, plugin: FolderOverviewPlugin | FolderNotesPlugin) {
|
||||
super(leaf);
|
||||
this.plugin = plugin;
|
||||
|
||||
this.display = this.display.bind(this);
|
||||
if (plugin instanceof FolderOverviewPlugin) {
|
||||
this.defaultSettings = this.plugin.settings as any as overviewSettings;
|
||||
} else if (plugin instanceof FolderNotesPlugin) {
|
||||
this.defaultSettings = plugin.settings.defaultOverview;
|
||||
}
|
||||
this.display = this.display.bind(this);
|
||||
if (plugin instanceof FolderOverviewPlugin) {
|
||||
this.defaultSettings = this.plugin.settings as any as overviewSettings;
|
||||
} else if (plugin instanceof FolderNotesPlugin) {
|
||||
this.defaultSettings = plugin.settings.defaultOverview;
|
||||
}
|
||||
|
||||
this.registerEvent(
|
||||
this.plugin.app.workspace.on('file-open', (file) => {
|
||||
this.activeFile = file;
|
||||
this.display(this.contentEl, this.yaml, this.plugin, this.defaultSettings, this.display, undefined, undefined, file, undefined, undefined, 'all');
|
||||
})
|
||||
);
|
||||
}
|
||||
this.registerEvent(
|
||||
this.plugin.app.workspace.on('file-open', (file) => {
|
||||
this.activeFile = file;
|
||||
this.display(this.contentEl, this.yaml, this.plugin, this.defaultSettings, this.display, undefined, undefined, file, undefined, undefined, 'all');
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getViewType() {
|
||||
return FOLDER_OVERVIEW_VIEW;
|
||||
}
|
||||
getViewType() {
|
||||
return FOLDER_OVERVIEW_VIEW;
|
||||
}
|
||||
|
||||
getDisplayText() {
|
||||
return 'Folder Overview settings';
|
||||
}
|
||||
getDisplayText() {
|
||||
return 'Folder Overview settings';
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
return 'settings';
|
||||
}
|
||||
getIcon() {
|
||||
return 'settings';
|
||||
}
|
||||
|
||||
async onOpen() {
|
||||
this.display(this.contentEl, this.yaml, this.plugin, this.defaultSettings, this.display, undefined, undefined, this.activeFile);
|
||||
}
|
||||
async onOpen() {
|
||||
this.display(this.contentEl, this.yaml, this.plugin, this.defaultSettings, this.display, undefined, undefined, this.activeFile);
|
||||
}
|
||||
|
||||
async display(
|
||||
contentEl: HTMLElement,
|
||||
yaml: overviewSettings,
|
||||
plugin: FolderOverviewPlugin | FolderNotesPlugin,
|
||||
defaultSettings: overviewSettings,
|
||||
display: CallableFunction,
|
||||
el?: HTMLElement,
|
||||
ctx?: MarkdownPostProcessorContext,
|
||||
file?: TFile | null,
|
||||
settingsTab?: SettingTab,
|
||||
modal?: FolderOverviewSettings,
|
||||
changedSection?: string | null | undefined
|
||||
) {
|
||||
this.contentEl = contentEl;
|
||||
this.yaml = yaml;
|
||||
this.defaultSettings = defaultSettings;
|
||||
this.changedSection = changedSection;
|
||||
if (file) { this.activeFile = file; }
|
||||
let header = contentEl.querySelector('.fn-folder-overview-header');
|
||||
if (!header) {
|
||||
header = contentEl.createEl('h4', {
|
||||
cls: 'fn-folder-overview-header',
|
||||
text: 'Folder Overview settings'
|
||||
});
|
||||
}
|
||||
async display(
|
||||
contentEl: HTMLElement,
|
||||
yaml: overviewSettings,
|
||||
plugin: FolderOverviewPlugin | FolderNotesPlugin,
|
||||
defaultSettings: overviewSettings,
|
||||
display: CallableFunction,
|
||||
el?: HTMLElement,
|
||||
ctx?: MarkdownPostProcessorContext,
|
||||
file?: TFile | null,
|
||||
settingsTab?: SettingTab,
|
||||
modal?: FolderOverviewSettings,
|
||||
changedSection?: string | null | undefined
|
||||
) {
|
||||
this.contentEl = contentEl;
|
||||
this.yaml = yaml;
|
||||
this.defaultSettings = defaultSettings;
|
||||
this.changedSection = changedSection;
|
||||
if (file) { this.activeFile = file; }
|
||||
let header = contentEl.querySelector('.fn-folder-overview-header');
|
||||
if (!header) {
|
||||
header = contentEl.createEl('h4', {
|
||||
cls: 'fn-folder-overview-header',
|
||||
text: 'Folder Overview settings',
|
||||
});
|
||||
}
|
||||
|
||||
const activeFile = plugin.app.workspace.getActiveFile();
|
||||
const activeFile = plugin.app.workspace.getActiveFile();
|
||||
|
||||
const overviews = await getOverviews(plugin, activeFile);
|
||||
const overviews = await getOverviews(plugin, activeFile);
|
||||
|
||||
let settingsContainer = contentEl.querySelector('.fn-settings-container') as HTMLElement;
|
||||
if (!settingsContainer) {
|
||||
settingsContainer = contentEl.createDiv({ cls: 'fn-settings-container' });
|
||||
}
|
||||
let settingsContainer = contentEl.querySelector('.fn-settings-container') as HTMLElement;
|
||||
if (!settingsContainer) {
|
||||
settingsContainer = contentEl.createDiv({ cls: 'fn-settings-container' });
|
||||
}
|
||||
|
||||
let dropdown = settingsContainer.querySelector('.fn-select-overview-setting');
|
||||
if (!dropdown || changedSection === 'all' || changedSection === 'dropdown') {
|
||||
if (dropdown) { settingsContainer.empty(); }
|
||||
dropdown = settingsContainer.createDiv({ cls: 'fn-select-overview-setting' });
|
||||
let dropdown = settingsContainer.querySelector('.fn-select-overview-setting');
|
||||
if (!dropdown || changedSection === 'all' || changedSection === 'dropdown') {
|
||||
if (dropdown) { settingsContainer.empty(); }
|
||||
dropdown = settingsContainer.createDiv({ cls: 'fn-select-overview-setting' });
|
||||
|
||||
const overviewSetting = new Setting(dropdown as HTMLElement);
|
||||
overviewSetting
|
||||
.setName('Select overview')
|
||||
.setClass('fn-select-overview-setting')
|
||||
.addDropdown((cb) => {
|
||||
if (activeFile) {
|
||||
const titleCounts: Record<string, number> = {};
|
||||
const overviewSetting = new Setting(dropdown as HTMLElement);
|
||||
overviewSetting
|
||||
.setName('Select overview')
|
||||
.setClass('fn-select-overview-setting')
|
||||
.addDropdown((cb) => {
|
||||
if (activeFile) {
|
||||
const titleCounts: Record<string, number> = {};
|
||||
|
||||
const options = overviews.reduce((acc, overview) => {
|
||||
let title = parseOverviewTitle(
|
||||
const options = overviews.reduce((acc, overview) => {
|
||||
const title = parseOverviewTitle(
|
||||
overview as any as overviewSettings,
|
||||
plugin,
|
||||
activeFile.parent
|
||||
);
|
||||
);
|
||||
|
||||
const count = (titleCounts[title] || 0) + 1;
|
||||
titleCounts[title] = count;
|
||||
const count = (titleCounts[title] || 0) + 1;
|
||||
titleCounts[title] = count;
|
||||
|
||||
acc[overview.id] = count > 1 ? `${title} (${count})` : title;
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
cb.addOptions(options);
|
||||
}
|
||||
acc[overview.id] = count > 1 ? `${title} (${count})` : title;
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
cb.addOptions(options);
|
||||
}
|
||||
|
||||
cb.addOption('default', 'Default');
|
||||
cb.setValue(yaml?.id ?? 'default');
|
||||
if (cb.getValue() === 'default' || !yaml?.id.trim() || cb.getValue().trim() === '') {
|
||||
yaml = defaultSettings;
|
||||
cb.setValue('default');
|
||||
} else {
|
||||
yaml = overviews.find((overview) => overview.id === yaml.id) as any as overviewSettings;
|
||||
}
|
||||
cb.addOption('default', 'Default');
|
||||
cb.setValue(yaml?.id ?? 'default');
|
||||
if (cb.getValue() === 'default' || !yaml?.id.trim() || cb.getValue().trim() === '') {
|
||||
yaml = defaultSettings;
|
||||
cb.setValue('default');
|
||||
} else {
|
||||
yaml = overviews.find((overview) => overview.id === yaml.id) as any as overviewSettings;
|
||||
}
|
||||
|
||||
cb.onChange(async (value) => {
|
||||
if (value === 'default') {
|
||||
yaml = defaultSettings;
|
||||
} else {
|
||||
yaml = overviews.find((overview) => overview.id === value) as any as overviewSettings;
|
||||
}
|
||||
await display(contentEl, yaml, plugin, defaultSettings, display, undefined, undefined, activeFile, undefined, undefined, 'all');
|
||||
});
|
||||
});
|
||||
}
|
||||
cb.onChange(async (value) => {
|
||||
if (value === 'default') {
|
||||
yaml = defaultSettings;
|
||||
} else {
|
||||
yaml = overviews.find((overview) => overview.id === value) as any as overviewSettings;
|
||||
}
|
||||
await display(contentEl, yaml, plugin, defaultSettings, display, undefined, undefined, activeFile, undefined, undefined, 'all');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
this.yaml = yaml;
|
||||
await createOverviewSettings(settingsContainer, yaml, plugin, defaultSettings, display, undefined, undefined, activeFile, undefined, undefined, changedSection);
|
||||
}
|
||||
}
|
||||
this.yaml = yaml;
|
||||
await createOverviewSettings(settingsContainer, yaml, plugin, defaultSettings, display, undefined, undefined, activeFile, undefined, undefined, changedSection);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"module": "ESNext",
|
||||
"target": "ES6",
|
||||
"allowJs": true,
|
||||
"noImplicitAny": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"isolatedModules": true,
|
||||
"strictNullChecks": true,
|
||||
"lib": [
|
||||
"DOM",
|
||||
"ES5",
|
||||
"ES6",
|
||||
"ES7",
|
||||
"ES2021"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
],
|
||||
"types": [
|
||||
"obsidian-typings"
|
||||
]
|
||||
}
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"module": "ESNext",
|
||||
"target": "ES6",
|
||||
"allowJs": true,
|
||||
"noImplicitAny": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"isolatedModules": true,
|
||||
"strictNullChecks": true,
|
||||
"lib": [
|
||||
"DOM",
|
||||
"ES5",
|
||||
"ES6",
|
||||
"ES7",
|
||||
"ES2021"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
],
|
||||
"types": [
|
||||
"obsidian-typings"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue