mirror of
https://github.com/lostpaul/obsidian-folder-notes.git
synced 2026-07-22 07:40:24 +00:00
Folder overview settings view
This commit is contained in:
parent
5c4c20d170
commit
b65d624e3b
8 changed files with 497 additions and 570 deletions
|
|
@ -36,6 +36,14 @@ export class Commands {
|
|||
}
|
||||
});
|
||||
|
||||
this.plugin.addCommand({
|
||||
id: 'open-folder-overview-view',
|
||||
name: 'Change folder overview settings',
|
||||
callback: () => {
|
||||
this.plugin.activateOverviewView();
|
||||
}
|
||||
});
|
||||
|
||||
this.plugin.addCommand({
|
||||
id: 'create-folder-note',
|
||||
name: 'Create folder note with a new folder for the active note in the current folder',
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ export class FolderOverview {
|
|||
files = sourceFolder.children;
|
||||
}
|
||||
|
||||
|
||||
|
||||
files = await this.filterFiles(files, plugin, sourceFolderPath, this.yaml.depth, this.pathBlacklist);
|
||||
|
||||
if (!this.yaml.includeTypes.includes('folder')) {
|
||||
|
|
@ -361,8 +361,6 @@ export class FolderOverview {
|
|||
return allFiles;
|
||||
}
|
||||
|
||||
|
||||
|
||||
fileMenu(file: TFile, e: MouseEvent) {
|
||||
const plugin = this.plugin;
|
||||
const fileMenu = new Menu();
|
||||
|
|
@ -466,6 +464,65 @@ export function getCodeBlockEndLine(text: string, startLine: number, count = 1)
|
|||
return line;
|
||||
}
|
||||
|
||||
export async function getOverviews(plugin: FolderNotesPlugin, file: TFile) {
|
||||
// is an object with unkown keys
|
||||
const overviews: { [key: string]: string }[] = [];
|
||||
const content = await plugin.app.vault.read(file);
|
||||
if (!content) return overviews;
|
||||
|
||||
const yamlBlocks = content.match(/```folder-overview\n([\s\S]*?)```/g);
|
||||
if (!yamlBlocks) return overviews;
|
||||
for (const block of yamlBlocks) {
|
||||
const yaml = parseYaml(block.replace('```folder-overview\n', '').replace('```', ''));
|
||||
if (!yaml) continue;
|
||||
overviews.push(yaml);
|
||||
}
|
||||
|
||||
return overviews;
|
||||
}
|
||||
|
||||
export async function updateYamlById(plugin: FolderNotesPlugin, overviewId: string, file: TFile, newYaml: yamlSettings) {
|
||||
plugin.app.vault.process(file, (text) => {
|
||||
const yamlBlocks = text.match(/```folder-overview\n([\s\S]*?)```/g);
|
||||
if (!yamlBlocks) return text;
|
||||
for (const block of yamlBlocks) {
|
||||
const yaml = parseYaml(block.replace('```folder-overview\n', '').replace('```', ''));
|
||||
if (!yaml) continue;
|
||||
if (yaml.id === overviewId) {
|
||||
const stringYaml = stringifyYaml(newYaml);
|
||||
const newBlock = `\`\`\`folder-overview\n${stringYaml}\`\`\``;
|
||||
text = text.replace(block, newBlock);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export function parseOverviewTitle(overview: yamlSettings, plugin: FolderNotesPlugin, folder: TFolder | null) {
|
||||
const sourceFolderPath = overview.folderPath;
|
||||
let sourceFolder: TFolder | undefined | null;
|
||||
let title = overview.title;
|
||||
|
||||
if (sourceFolderPath !== '/') {
|
||||
if (sourceFolderPath === '') {
|
||||
sourceFolder = folder;
|
||||
} else {
|
||||
sourceFolder = plugin.app.vault.getAbstractFileByPath(sourceFolderPath) as TFolder;
|
||||
}
|
||||
}
|
||||
|
||||
if (sourceFolder && sourceFolderPath !== '/') {
|
||||
title = title.replace('{{folderName}}', sourceFolder.name);
|
||||
} else if (sourceFolderPath == '/') {
|
||||
title = title.replace('{{folderName}}', 'Vault');
|
||||
} else {
|
||||
title = title.replace('{{folderName}}', '');
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
|
||||
class CustomMarkdownRenderChild extends MarkdownRenderChild {
|
||||
folderOverview: FolderOverview;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { App, Modal, Setting, MarkdownPostProcessorContext, stringifyYaml, TFile, TFolder } from 'obsidian';
|
||||
import { App, Modal, Setting, MarkdownPostProcessorContext, stringifyYaml, TFile, TFolder, SettingTab } from 'obsidian';
|
||||
import { yamlSettings, includeTypes, FolderOverview } from 'src/folderOverview/FolderOverview';
|
||||
import FolderNotesPlugin from '../main';
|
||||
import { ListComponent } from 'src/functions/ListComponent';
|
||||
import { updateYaml } from 'src/folderOverview/FolderOverview';
|
||||
import { FolderSuggest } from 'src/suggesters/FolderSuggester';
|
||||
import { getFolderPathFromString } from 'src/functions/utils';
|
||||
import { createOverviewSettings } from "src/folderOverview/settings";
|
||||
|
||||
export class FolderOverviewSettings extends Modal {
|
||||
plugin: FolderNotesPlugin;
|
||||
|
|
@ -54,313 +55,25 @@ export class FolderOverviewSettings extends Modal {
|
|||
updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
}
|
||||
onOpen() {
|
||||
this.display();
|
||||
}
|
||||
display() {
|
||||
const { contentEl } = this;
|
||||
this.display(contentEl, this.yaml, this.plugin, false, this.display, this.el, this.ctx);
|
||||
}
|
||||
display(contentEl: HTMLElement, yaml: yamlSettings, plugin: FolderNotesPlugin, defaultSettings: boolean, display: CallableFunction, el?: HTMLElement, ctx?: MarkdownPostProcessorContext, file?: TFile | null, settingsTab?: SettingTab, modal?: FolderOverviewSettings) {
|
||||
modal = this ?? modal;
|
||||
contentEl.empty();
|
||||
// close when user presses enter
|
||||
contentEl.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
this.close();
|
||||
modal.close();
|
||||
}
|
||||
});
|
||||
if (!this.defaultSettings) {
|
||||
if (!modal.defaultSettings) {
|
||||
contentEl.createEl('h2', { text: 'Folder overview settings' });
|
||||
} else {
|
||||
contentEl.createEl('h2', { text: 'Default folder overview settings' });
|
||||
}
|
||||
new Setting(contentEl)
|
||||
.setName('Show the title')
|
||||
.setDesc('Choose if the title should be shown')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(this.yaml.showTitle)
|
||||
.onChange(async (value) => {
|
||||
this.yaml.showTitle = value;
|
||||
this.display();
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);;
|
||||
})
|
||||
);
|
||||
if (this.yaml.showTitle) {
|
||||
new Setting(contentEl)
|
||||
.setName('Title')
|
||||
.setDesc('Choose the title of the folder overview')
|
||||
.addText((text) =>
|
||||
text
|
||||
.setValue(this.yaml?.title || '{{folderName}} overview')
|
||||
.onChange(async (value) => {
|
||||
this.yaml.title = value;
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);;
|
||||
})
|
||||
);
|
||||
}
|
||||
new Setting(contentEl)
|
||||
.setName('Folder path for the overview')
|
||||
.setDesc('Choose the folder path for the overview')
|
||||
.addSearch((search) => {
|
||||
new FolderSuggest(search.inputEl, this.plugin, false)
|
||||
search
|
||||
.setPlaceholder('Folder path')
|
||||
.setValue(this.yaml?.folderPath || '')
|
||||
.onChange(async (value) => {
|
||||
if (!(this.app.vault.getAbstractFileByPath(value) instanceof TFolder) && value !== '') return;
|
||||
this.yaml.folderPath = value;
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);;
|
||||
});
|
||||
});
|
||||
new Setting(contentEl)
|
||||
.setName('Overview style')
|
||||
.setDesc('Choose the style of the overview (grid style soon)')
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOption('list', 'List')
|
||||
.addOption('explorer', 'Explorer')
|
||||
.setValue(this.yaml?.style || 'list')
|
||||
.onChange(async (value: 'list') => {
|
||||
this.yaml.style = value;
|
||||
this.display();
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
})
|
||||
);
|
||||
if (this.yaml.style === 'explorer') {
|
||||
new Setting(contentEl)
|
||||
.setName('Store collapsed condition')
|
||||
.setDesc('Choose if the collapsed condition should be stored stored until you restart Obsidian')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(this.yaml.storeFolderCondition)
|
||||
.onChange(async (value) => {
|
||||
this.yaml.storeFolderCondition = value;
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);;
|
||||
})
|
||||
);
|
||||
}
|
||||
const setting = new Setting(contentEl);
|
||||
setting.setName('Include types');
|
||||
const list = new ListComponent(setting.settingEl, this.yaml.includeTypes || [], ['markdown', 'folder']);
|
||||
list.on('update', (values) => {
|
||||
this.yaml.includeTypes = values;
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
this.display();
|
||||
});
|
||||
|
||||
if ((this.yaml?.includeTypes?.length || 0) < 8 && !this.yaml.includeTypes?.includes('all')) {
|
||||
setting.addDropdown((dropdown) => {
|
||||
if (!this.yaml.includeTypes) this.yaml.includeTypes = this.plugin.settings.defaultOverview.includeTypes || [];
|
||||
this.yaml.includeTypes = this.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 (!this.yaml.includeTypes?.includes(option.value as includeTypes)) {
|
||||
dropdown.addOption(option.value, option.label);
|
||||
}
|
||||
});
|
||||
dropdown.addOption('+', '+');
|
||||
dropdown.setValue('+');
|
||||
dropdown.onChange(async (value) => {
|
||||
if (value === 'all') {
|
||||
this.yaml.includeTypes = this.yaml.includeTypes?.filter((type: string) => type === 'folder');
|
||||
list.setValues(this.yaml.includeTypes);
|
||||
}
|
||||
await list.addValue(value.toLowerCase());
|
||||
this.display();
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let disableFileTag;
|
||||
this.yaml.includeTypes?.forEach((type: string) => {
|
||||
type === 'folder' || type === 'markdown' ? (disableFileTag = true) : null;
|
||||
});
|
||||
|
||||
if (disableFileTag) {
|
||||
new Setting(contentEl)
|
||||
.setName('Disable file tag')
|
||||
.setDesc('Choose if the file tag should be shown after the file name')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(this.yaml.disableFileTag)
|
||||
.onChange(async (value) => {
|
||||
this.yaml.disableFileTag = value;
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
new Setting(contentEl)
|
||||
.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(this.yaml.showFolderNotes)
|
||||
.onChange(async (value) => {
|
||||
this.yaml.showFolderNotes = value;
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(contentEl)
|
||||
.setName('File depth')
|
||||
.setDesc('File & folder = +1 depth')
|
||||
.addSlider((slider) =>
|
||||
slider
|
||||
.setValue(this.yaml?.depth || 2)
|
||||
.setLimits(1, 10, 1)
|
||||
.setDynamicTooltip()
|
||||
.onChange(async (value) => {
|
||||
this.yaml.depth = value;
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(contentEl)
|
||||
.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(this.yaml?.sortBy || 'name')
|
||||
.onChange(async (value: 'name' | 'created' | 'modified') => {
|
||||
this.yaml.sortBy = value;
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
})
|
||||
)
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
.addOption('desc', 'Descending')
|
||||
.addOption('asc', 'Ascending')
|
||||
if (this.yaml.sortByAsc) {
|
||||
dropdown.setValue('asc');
|
||||
} else {
|
||||
dropdown.setValue('desc');
|
||||
}
|
||||
dropdown.onChange(async (value) => {
|
||||
if (value === 'desc') {
|
||||
this.yaml.sortByAsc = false;
|
||||
} else {
|
||||
this.yaml.sortByAsc = true;
|
||||
}
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
});
|
||||
});
|
||||
|
||||
if (this.yaml.style === 'list') {
|
||||
new Setting(contentEl)
|
||||
.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(this.yaml.showEmptyFolders)
|
||||
.onChange(async (value) => {
|
||||
this.yaml.showEmptyFolders = value;
|
||||
this.yaml.onlyIncludeSubfolders = false;
|
||||
this.display();
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
});
|
||||
});
|
||||
|
||||
if (this.yaml.showEmptyFolders) {
|
||||
new Setting(contentEl)
|
||||
.setName('Only show first empty subfolders of current folder')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(this.yaml.onlyIncludeSubfolders)
|
||||
.onChange(async (value) => {
|
||||
this.yaml.onlyIncludeSubfolders = value;
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.yaml.style === 'explorer') {
|
||||
new Setting(contentEl)
|
||||
.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(this.yaml.disableCollapseIcon)
|
||||
.onChange(async (value) => {
|
||||
this.yaml.disableCollapseIcon = value;
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(contentEl)
|
||||
.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(this.yaml.alwaysCollapse)
|
||||
.onChange(async (value) => {
|
||||
this.yaml.alwaysCollapse = value;
|
||||
if (this.defaultSettings) {
|
||||
return this.plugin.saveSettings();
|
||||
}
|
||||
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
createOverviewSettings(contentEl, yaml, plugin, defaultSettings, display, el, ctx, undefined, undefined, modal);
|
||||
}
|
||||
|
||||
onClose() {
|
||||
|
|
|
|||
273
src/folderOverview/settings.ts
Normal file
273
src/folderOverview/settings.ts
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
import { MarkdownPostProcessorContext, Setting, TFile, TFolder } from 'obsidian';
|
||||
import { updateYaml, updateYamlById, yamlSettings, includeTypes } from './FolderOverview';
|
||||
import { FolderSuggest } from 'src/suggesters/FolderSuggester';
|
||||
import { ListComponent } from 'src/functions/ListComponent';
|
||||
import FolderNotesPlugin from 'src/main';
|
||||
import { Callback } from 'front-matter-plugin-api-provider';
|
||||
import { SettingsTab } from 'src/settings/SettingsTab';
|
||||
import { FolderOverviewSettings } from './ModalSettings';
|
||||
|
||||
export async function createOverviewSettings(contentEl: HTMLElement, yaml: yamlSettings, plugin: FolderNotesPlugin, defaultSettings: boolean, display: CallableFunction, el?: HTMLElement, ctx?: MarkdownPostProcessorContext, file?: TFile | null, settingsTab?: SettingsTab, modal?: FolderOverviewSettings) {
|
||||
|
||||
new Setting(contentEl)
|
||||
.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);;
|
||||
display(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
})
|
||||
);
|
||||
if (yaml.showTitle) {
|
||||
new Setting(contentEl)
|
||||
.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);;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
new Setting(contentEl)
|
||||
.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 (!(plugin.app.vault.getAbstractFileByPath(value) instanceof TFolder) && value !== '') return;
|
||||
yaml.folderPath = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);;
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(contentEl)
|
||||
.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);
|
||||
display(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
})
|
||||
);
|
||||
|
||||
if (yaml.style === 'explorer') {
|
||||
new Setting(contentEl)
|
||||
.setName('Store collapsed condition')
|
||||
.setDesc('Choose if the collapsed condition should be stored 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);;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const setting = new Setting(contentEl);
|
||||
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);
|
||||
display(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
});
|
||||
|
||||
if ((yaml?.includeTypes?.length || 0) < 8 && !yaml.includeTypes?.includes('all')) {
|
||||
setting.addDropdown((dropdown) => {
|
||||
if (!yaml.includeTypes) yaml.includeTypes = plugin.settings.defaultOverview.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);
|
||||
display(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let disableFileTag;
|
||||
yaml.includeTypes?.forEach((type: string) => {
|
||||
type === 'folder' || type === 'markdown' ? (disableFileTag = true) : null;
|
||||
});
|
||||
|
||||
if (disableFileTag) {
|
||||
new Setting(contentEl)
|
||||
.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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
new Setting(contentEl)
|
||||
.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);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(contentEl)
|
||||
.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);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(contentEl)
|
||||
.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) => {
|
||||
if (value === 'desc') {
|
||||
yaml.sortByAsc = false;
|
||||
} else {
|
||||
yaml.sortByAsc = true;
|
||||
}
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
|
||||
if (yaml.style === 'list') {
|
||||
new Setting(contentEl)
|
||||
.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);
|
||||
display(contentEl, yaml, plugin, defaultSettings, display, el, ctx, file, settingsTab, modal);
|
||||
});
|
||||
});
|
||||
|
||||
if (yaml.showEmptyFolders) {
|
||||
new Setting(contentEl)
|
||||
.setName('Only show first empty subfolders of current folder')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(yaml.onlyIncludeSubfolders)
|
||||
.onChange(async (value) => {
|
||||
yaml.onlyIncludeSubfolders = value;
|
||||
updateSettings(contentEl, yaml, plugin, defaultSettings, el, ctx, file);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (yaml.style === 'explorer') {
|
||||
new Setting(contentEl)
|
||||
.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);
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(contentEl)
|
||||
.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);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function updateSettings(contentEl: HTMLElement, yaml: yamlSettings, plugin: FolderNotesPlugin, defaultSettings: boolean, el?: HTMLElement, ctx?: MarkdownPostProcessorContext, file?: TFile | null) {
|
||||
if (defaultSettings) {
|
||||
plugin.updateOverviewView();
|
||||
return plugin.saveSettings();
|
||||
}
|
||||
|
||||
if (el && ctx) {
|
||||
await updateYaml(plugin, ctx, el, yaml);
|
||||
}
|
||||
|
||||
if (file) {
|
||||
await updateYamlById(plugin, yaml.id, file, yaml);
|
||||
}
|
||||
}
|
||||
96
src/folderOverview/view.ts
Normal file
96
src/folderOverview/view.ts
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import { ItemView, Setting, TFile, WorkspaceLeaf, MarkdownPostProcessorContext } from 'obsidian';
|
||||
import FolderNotesPlugin from '../main';
|
||||
import { FolderOverview, getOverviews, yamlSettings, parseOverviewTitle } from './FolderOverview';
|
||||
import { FileSuggest } from 'src/suggesters/FileSuggester';
|
||||
import { createOverviewSettings } from './settings';
|
||||
|
||||
export const FOLDER_OVERVIEW_VIEW = 'folder-overview-view';
|
||||
|
||||
export class FolderOverviewView extends ItemView {
|
||||
plugin: FolderNotesPlugin;
|
||||
activeFile: TFile | null;
|
||||
overviewId: string | null;
|
||||
yaml: yamlSettings;
|
||||
defaultSettings: boolean;
|
||||
contentEl: HTMLElement = this.containerEl.children[1] as HTMLElement;
|
||||
constructor(leaf: WorkspaceLeaf, plugin: FolderNotesPlugin) {
|
||||
super(leaf);
|
||||
this.plugin = plugin;
|
||||
|
||||
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);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getViewType() {
|
||||
return FOLDER_OVERVIEW_VIEW;
|
||||
}
|
||||
|
||||
getDisplayText() {
|
||||
return 'Folder Overview settings';
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
return 'settings';
|
||||
}
|
||||
|
||||
async onOpen() {
|
||||
this.display(this.contentEl, this.yaml, this.plugin, this.defaultSettings, this.display, undefined, undefined, this.activeFile);
|
||||
}
|
||||
|
||||
async display(contentEl: HTMLElement, yaml: yamlSettings, plugin: FolderNotesPlugin, defaultSettings: boolean, display: CallableFunction, el?: HTMLElement, ctx?: MarkdownPostProcessorContext, file?: TFile | null) {
|
||||
contentEl.empty();
|
||||
contentEl.createEl('h4', { text: 'Folder Overview settings' });
|
||||
|
||||
const activeFile = plugin.app.workspace.getActiveFile();
|
||||
|
||||
if (!activeFile) {
|
||||
// coulnd't get active file
|
||||
contentEl.createEl('p', { text: 'No active file found' });
|
||||
return;
|
||||
}
|
||||
|
||||
const overviews = await getOverviews(plugin, activeFile);
|
||||
|
||||
const overviewSetting = new Setting(contentEl);
|
||||
overviewSetting.setName('Select overview');
|
||||
overviewSetting.setClass('fn-select-overview-setting');
|
||||
overviewSetting.addDropdown((cb) => {
|
||||
const options = overviews.reduce((acc, overview) => {
|
||||
acc[overview.id] = parseOverviewTitle(overview as any as yamlSettings, plugin, activeFile.parent);
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
cb.addOptions(options);
|
||||
cb.addOption('default', 'Default');
|
||||
cb.setValue(yaml?.id ?? 'default');
|
||||
|
||||
if (cb.getValue() === 'default' || defaultSettings) {
|
||||
yaml = plugin.settings.defaultOverview;
|
||||
defaultSettings = true;
|
||||
cb.setValue('default');
|
||||
} else {
|
||||
yaml = overviews.find((overview) => overview.id === yaml.id) as any as yamlSettings;
|
||||
defaultSettings = false;
|
||||
}
|
||||
|
||||
cb.onChange(async (value) => {
|
||||
if (value === 'default') {
|
||||
yaml = plugin.settings.defaultOverview;
|
||||
defaultSettings = true;
|
||||
} else {
|
||||
yaml = overviews.find((overview) => overview.id === value) as any as yamlSettings;
|
||||
defaultSettings = false;
|
||||
}
|
||||
display(contentEl, yaml, plugin, defaultSettings, display, undefined, undefined, activeFile);
|
||||
});
|
||||
});
|
||||
|
||||
createOverviewSettings(contentEl, yaml, plugin, defaultSettings, display, undefined, undefined, activeFile);
|
||||
|
||||
// execute display function when the default settings are changed
|
||||
|
||||
}
|
||||
}
|
||||
48
src/main.ts
48
src/main.ts
|
|
@ -1,4 +1,4 @@
|
|||
import { Plugin, TFile, TFolder, TAbstractFile, MarkdownPostProcessorContext, parseYaml, Notice, Keymap, MenuItem, requireApiVersion } from 'obsidian';
|
||||
import { Plugin, TFile, TFolder, TAbstractFile, MarkdownPostProcessorContext, parseYaml, Notice, Keymap, WorkspaceLeaf, requireApiVersion } from 'obsidian';
|
||||
import { DEFAULT_SETTINGS, FolderNotesSettings, SettingsTab } from './settings/SettingsTab';
|
||||
import { Commands } from './Commands';
|
||||
import { FileExplorerWorkspaceLeaf } from './globals';
|
||||
|
|
@ -17,6 +17,7 @@ import { addCSSClassToTitleEL, getEl, loadFileClasses } from './functions/styleF
|
|||
import { getExcludedFolder } from './ExcludeFolders/functions/folderFunctions';
|
||||
import { ClipBoardManager, FileExplorerView, InternalPlugin } from 'obsidian-typings'
|
||||
import { getFocusedItem } from './functions/utils';
|
||||
import { FOLDER_OVERVIEW_VIEW, FolderOverviewView } from './folderOverview/view';
|
||||
export default class FolderNotesPlugin extends Plugin {
|
||||
observer: MutationObserver;
|
||||
settings: FolderNotesSettings;
|
||||
|
|
@ -74,7 +75,7 @@ export default class FolderNotesPlugin extends Plugin {
|
|||
if (!folderNote) return;
|
||||
openFolderNote(this, folderNote);
|
||||
}
|
||||
|
||||
|
||||
const hoveredElement = this.hoveredElement;
|
||||
if (this.hoverLinkTriggered) return;
|
||||
if (!hoveredElement) return;
|
||||
|
|
@ -133,18 +134,14 @@ export default class FolderNotesPlugin extends Plugin {
|
|||
});
|
||||
|
||||
if (this.app.workspace.layoutReady) {
|
||||
// loadFileClasses(undefined, this);
|
||||
// // this.registerEvent(this.app.workspace.on('layout-change', () => {
|
||||
// // loadFileClasses(undefined, this);
|
||||
// // this.tabManager?.updateTabs();
|
||||
// // }));
|
||||
this.registerView(FOLDER_OVERVIEW_VIEW, (leaf: WorkspaceLeaf) => {
|
||||
return new FolderOverviewView(leaf, this);
|
||||
});
|
||||
} else {
|
||||
this.app.workspace.onLayoutReady(async () => {
|
||||
// loadFileClasses(undefined, this)
|
||||
// // this.registerEvent(this.app.workspace.on('layout-change', () => {
|
||||
// // loadFileClasses(undefined, this);
|
||||
// // this.tabManager?.updateTabs();
|
||||
// // }));
|
||||
this.registerView(FOLDER_OVERVIEW_VIEW, (leaf: WorkspaceLeaf) => {
|
||||
return new FolderOverviewView(leaf, this);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -164,7 +161,7 @@ export default class FolderNotesPlugin extends Plugin {
|
|||
// @ts-ignore
|
||||
const editMode = view.editMode ?? view.sourceMode ?? this.app.workspace.activeEditor?.editMode;
|
||||
if (!editMode) { return; }
|
||||
|
||||
|
||||
const plugin = this;
|
||||
|
||||
// @ts-ignore
|
||||
|
|
@ -233,6 +230,31 @@ export default class FolderNotesPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
async activateOverviewView() {
|
||||
const { workspace } = this.app;
|
||||
|
||||
let leaf: WorkspaceLeaf | null = null;
|
||||
const leaves = workspace.getLeavesOfType(FOLDER_OVERVIEW_VIEW);
|
||||
|
||||
if (leaves.length > 0) {
|
||||
leaf = leaves[0];
|
||||
} else {
|
||||
leaf = workspace.getRightLeaf(false);
|
||||
await leaf?.setViewState({ type: FOLDER_OVERVIEW_VIEW, active: true });
|
||||
}
|
||||
|
||||
if (!leaf) return;
|
||||
workspace.revealLeaf(leaf);
|
||||
}
|
||||
|
||||
async updateOverviewView() {
|
||||
const { workspace } = this.app;
|
||||
const leaf = workspace.getLeavesOfType(FOLDER_OVERVIEW_VIEW)[0];
|
||||
if (!leaf) return;
|
||||
const view = leaf.view as FolderOverviewView;
|
||||
view.display(view.contentEl, view.yaml, this, view.defaultSettings, view.display, undefined, undefined, view.activeFile);
|
||||
}
|
||||
|
||||
isEmptyFolderNoteFolder(folder: TFolder): boolean {
|
||||
let attachmentFolderPath = this.app.vault.getConfig('attachmentFolderPath') as string;
|
||||
const cleanAttachmentFolderPath = attachmentFolderPath?.replace('./', '') || '';
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { SettingsTab } from "./SettingsTab";
|
|||
import { ListComponent } from 'src/functions/ListComponent';
|
||||
import { includeTypes } from 'src/folderOverview/FolderOverview';
|
||||
import { FolderSuggest } from "src/suggesters/FolderSuggester";
|
||||
import { createOverviewSettings } from "src/folderOverview/settings";
|
||||
|
||||
export async function renderFolderOverview(settingsTab: SettingsTab) {
|
||||
const { plugin } = settingsTab;
|
||||
|
|
@ -10,251 +11,5 @@ export async function renderFolderOverview(settingsTab: SettingsTab) {
|
|||
const containerEl = settingsTab.settingsPage;
|
||||
containerEl.createEl('p', { text: 'Change the default settings for folder overviews', cls: 'setting-item-description' });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Show the title')
|
||||
.setDesc('Choose if the title should be shown')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(overviewSettings.showTitle)
|
||||
.onChange(async (value) => {
|
||||
overviewSettings.showTitle = value;
|
||||
settingsTab.display();
|
||||
plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
||||
if (overviewSettings.showTitle) {
|
||||
new Setting(containerEl)
|
||||
.setName('Title')
|
||||
.setDesc('Choose the title of the folder overview')
|
||||
.addText((text) =>
|
||||
text
|
||||
.setValue(overviewSettings?.title || '{{folderName}} overview')
|
||||
.onChange(async (value) => {
|
||||
overviewSettings.title = value;
|
||||
plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
}
|
||||
new Setting(containerEl)
|
||||
.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(overviewSettings?.folderPath || '')
|
||||
.onChange(async (value) => {
|
||||
if (!(this.app.vault.getAbstractFileByPath(value) instanceof TFolder) && value !== '') return;
|
||||
overviewSettings.folderPath = value;
|
||||
plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
new Setting(containerEl)
|
||||
.setName('Overview style')
|
||||
.setDesc('Choose the style of the overview (grid style soon)')
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOption('list', 'List')
|
||||
.addOption('explorer', 'Explorer')
|
||||
.setValue(overviewSettings?.style || 'list')
|
||||
.onChange(async (value: 'list') => {
|
||||
overviewSettings.style = value;
|
||||
settingsTab.display();
|
||||
plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
if (overviewSettings.style === 'explorer') {
|
||||
new Setting(containerEl)
|
||||
.setName('Store collapsed condition')
|
||||
.setDesc('Choose if the collapsed condition should be stored stored until you restart Obsidian')
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(overviewSettings.storeFolderCondition)
|
||||
.onChange(async (value) => {
|
||||
overviewSettings.storeFolderCondition = value;
|
||||
plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
}
|
||||
const setting = new Setting(containerEl)
|
||||
.setName('Include types');
|
||||
|
||||
const list = new ListComponent(setting.settingEl, overviewSettings?.includeTypes || [], ['markdown', 'folder']);
|
||||
list.on('update', (values) => {
|
||||
overviewSettings.includeTypes = values;
|
||||
settingsTab.display();
|
||||
plugin.saveSettings();
|
||||
});
|
||||
|
||||
if ((overviewSettings?.includeTypes?.length || 0) < 8 && !overviewSettings.includeTypes?.includes('all')) {
|
||||
setting.addDropdown((dropdown) => {
|
||||
overviewSettings.includeTypes = overviewSettings.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 (!overviewSettings.includeTypes?.includes(option.value as includeTypes)) {
|
||||
dropdown.addOption(option.value, option.label);
|
||||
}
|
||||
});
|
||||
dropdown.addOption('+', '+');
|
||||
dropdown.setValue('+');
|
||||
dropdown.onChange(async (value) => {
|
||||
if (value === 'all') {
|
||||
overviewSettings.includeTypes = overviewSettings.includeTypes?.filter((type: string) => type === 'folder');
|
||||
list.setValues(overviewSettings.includeTypes);
|
||||
}
|
||||
await list.addValue(value.toLowerCase());
|
||||
settingsTab.display();
|
||||
plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let disableFileTag;
|
||||
overviewSettings.includeTypes?.forEach((type: string) => {
|
||||
type === 'folder' || type === 'markdown' ? (disableFileTag = true) : null;
|
||||
});
|
||||
if (disableFileTag) {
|
||||
new Setting(containerEl)
|
||||
.setName('Disable file tag')
|
||||
.setDesc('Choose if the file tag should be shown after the file name')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(overviewSettings.disableFileTag)
|
||||
.onChange(async (value) => {
|
||||
overviewSettings.disableFileTag = value;
|
||||
plugin.saveSettings();
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
new Setting(containerEl)
|
||||
.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(overviewSettings.showFolderNotes)
|
||||
.onChange(async (value) => {
|
||||
overviewSettings.showFolderNotes = value;
|
||||
plugin.saveSettings();
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
if (overviewSettings.style !== 'explorer') {
|
||||
new Setting(containerEl)
|
||||
.setName('File depth')
|
||||
.setDesc('File & folder = +1 depth')
|
||||
.addSlider((slider) =>
|
||||
slider
|
||||
.setValue(overviewSettings?.depth || 2)
|
||||
.setLimits(1, 10, 1)
|
||||
.onChange(async (value) => {
|
||||
overviewSettings.depth = value;
|
||||
plugin.saveSettings();
|
||||
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
new Setting(containerEl)
|
||||
.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(overviewSettings?.sortBy || 'name')
|
||||
.onChange(async (value: 'name' | 'created' | 'modified') => {
|
||||
overviewSettings.sortBy = value;
|
||||
plugin.saveSettings();
|
||||
|
||||
})
|
||||
)
|
||||
.addDropdown((dropdown) => {
|
||||
dropdown
|
||||
.addOption('desc', 'Descending')
|
||||
.addOption('asc', 'Ascending')
|
||||
if (overviewSettings.sortByAsc) {
|
||||
dropdown.setValue('asc');
|
||||
} else {
|
||||
dropdown.setValue('desc');
|
||||
}
|
||||
dropdown.onChange(async (value) => {
|
||||
if (value === 'desc') {
|
||||
overviewSettings.sortByAsc = false;
|
||||
} else {
|
||||
overviewSettings.sortByAsc = true;
|
||||
}
|
||||
plugin.saveSettings();
|
||||
|
||||
});
|
||||
});
|
||||
if (overviewSettings.style === 'list') {
|
||||
new Setting(containerEl)
|
||||
.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(overviewSettings.showEmptyFolders)
|
||||
.onChange(async (value) => {
|
||||
overviewSettings.showEmptyFolders = value;
|
||||
overviewSettings.onlyIncludeSubfolders = false;
|
||||
settingsTab.display();
|
||||
plugin.saveSettings();
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
if (overviewSettings.showEmptyFolders) {
|
||||
new Setting(containerEl)
|
||||
.setName('Only show first empty subfolders of current folder')
|
||||
.addToggle((toggle) => {
|
||||
toggle
|
||||
.setValue(overviewSettings.onlyIncludeSubfolders)
|
||||
.onChange(async (value) => {
|
||||
overviewSettings.onlyIncludeSubfolders = value;
|
||||
plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (overviewSettings.style === 'explorer') {
|
||||
new Setting(containerEl)
|
||||
.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(overviewSettings.disableCollapseIcon)
|
||||
.onChange(async (value) => {
|
||||
overviewSettings.disableCollapseIcon = value;
|
||||
plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.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(overviewSettings.alwaysCollapse)
|
||||
.onChange(async (value) => {
|
||||
overviewSettings.alwaysCollapse = value;
|
||||
plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
}
|
||||
createOverviewSettings(containerEl, overviewSettings, plugin, true, settingsTab.display, undefined, undefined, undefined, settingsTab);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { App, Notice, PluginSettingTab, TFile, TFolder } from 'obsidian';
|
||||
import { App, Notice, PluginSettingTab, TFile, TFolder, MarkdownPostProcessorContext } from 'obsidian';
|
||||
import FolderNotesPlugin from '../main';
|
||||
import { ExcludePattern } from 'src/ExcludeFolders/ExcludePattern';
|
||||
import { ExcludedFolder } from 'src/ExcludeFolders/ExcludeFolder';
|
||||
|
|
@ -111,6 +111,7 @@ export const DEFAULT_SETTINGS: FolderNotesSettings = {
|
|||
storeFolderCondition: true,
|
||||
showFolderNotes: false,
|
||||
disableCollapseIcon: true,
|
||||
alwaysCollapse: false,
|
||||
},
|
||||
useSubmenus: true,
|
||||
syncMove: true,
|
||||
|
|
@ -225,32 +226,34 @@ export class SettingsTab extends PluginSettingTab {
|
|||
|
||||
}
|
||||
|
||||
display(): void {
|
||||
this.plugin.settingsOpened = true;
|
||||
const { containerEl } = this;
|
||||
display(contentEl?: HTMLElement, yaml?: yamlSettings, plugin?: FolderNotesPlugin, defaultSettings?: boolean, display?: CallableFunction, el?: HTMLElement, ctx?: MarkdownPostProcessorContext, file?: TFile | null, settingsTab?: this) {
|
||||
plugin = this?.plugin ?? plugin;
|
||||
plugin.settingsOpened = true;
|
||||
settingsTab = this ?? settingsTab;
|
||||
const { containerEl } = settingsTab;
|
||||
|
||||
containerEl.empty();
|
||||
|
||||
const tabBar = containerEl.createEl('nav', { cls: 'fn-settings-tab-bar' });
|
||||
for (const [tabId, tabInfo] of Object.entries(this.TABS)) {
|
||||
for (const [tabId, tabInfo] of Object.entries(settingsTab.TABS)) {
|
||||
const tabEl = tabBar.createEl('div', { cls: 'fn-settings-tab' });
|
||||
const tabName = tabEl.createEl('div', { cls: 'fn-settings-tab-name', text: tabInfo.name });
|
||||
if (this.plugin.settings.settingsTab.toLocaleLowerCase() === tabId.toLocaleLowerCase()) {
|
||||
if (plugin.settings.settingsTab.toLocaleLowerCase() === tabId.toLocaleLowerCase()) {
|
||||
tabEl.addClass('fn-settings-tab-active');
|
||||
}
|
||||
tabEl.addEventListener('click', () => {
|
||||
// @ts-ignore
|
||||
for (const tabEl of tabBar.children) {
|
||||
tabEl.removeClass('fn-settings-tab-active');
|
||||
this.plugin.settings.settingsTab = tabId.toLocaleLowerCase();
|
||||
this.plugin.saveSettings();
|
||||
plugin.settings.settingsTab = tabId.toLocaleLowerCase();
|
||||
plugin.saveSettings();
|
||||
}
|
||||
tabEl.addClass('fn-settings-tab-active');
|
||||
this.renderSettingsPage(tabId);
|
||||
settingsTab.renderSettingsPage(tabId);
|
||||
});
|
||||
}
|
||||
this.settingsPage = containerEl.createDiv({ cls: 'fn-settings-page' });
|
||||
this.renderSettingsPage(this.plugin.settings.settingsTab);
|
||||
settingsTab.settingsPage = containerEl.createDiv({ cls: 'fn-settings-page' });
|
||||
settingsTab.renderSettingsPage(plugin.settings.settingsTab);
|
||||
}
|
||||
|
||||
updateFolderNotes(newTemplate: string) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue