mirror of
https://github.com/lostpaul/obsidian-folder-notes.git
synced 2026-07-22 07:40:24 +00:00
Fix issues with 1.7.2 Obsidian release and some code rewrite
This commit is contained in:
parent
423071e492
commit
1c794c18ea
10 changed files with 81 additions and 69 deletions
|
|
@ -8,7 +8,7 @@ import { addExcludedFolder, deleteExcludedFolder, getDetachedFolder, getExcluded
|
|||
import ExcludedFolderSettings from './ExcludeFolders/modals/ExcludeFolderSettings'
|
||||
import { ExcludePattern } from './ExcludeFolders/ExcludePattern';
|
||||
import PatternSettings from './ExcludeFolders/modals/PatternSettings';
|
||||
import { loadFolderClasses } from './functions/styleFunctions';
|
||||
import { applyCSSClassesToFolder } from './functions/styleFunctions';
|
||||
|
||||
export class Commands {
|
||||
plugin: FolderNotesPlugin;
|
||||
|
|
@ -373,7 +373,7 @@ export class Commands {
|
|||
this.plugin.settings.excludeFolders = this.plugin.settings.excludeFolders.filter(
|
||||
(folder) => (folder.path !== file.path) && folder.hideNote);
|
||||
this.plugin.saveSettings(false);
|
||||
loadFolderClasses(true, file, this.plugin);
|
||||
applyCSSClassesToFolder(file.path, this.plugin);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
|
@ -391,7 +391,7 @@ export class Commands {
|
|||
excludedFolder.excludeFromFolderOverview = false;
|
||||
excludedFolder.hideInSettings = true;
|
||||
addExcludedFolder(this.plugin, excludedFolder, false);
|
||||
loadFolderClasses(true, file, this.plugin);
|
||||
applyCSSClassesToFolder(file.path, this.plugin);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { Platform, Keymap } from 'obsidian';
|
|||
import { getFolderNote } from 'src/functions/folderNoteFunctions';
|
||||
import { handleFolderClick, handleViewHeaderClick } from './handleClick';
|
||||
import { getExcludedFolder } from 'src/ExcludeFolders/functions/folderFunctions';
|
||||
import { applyCSSClassesToFolder } from 'src/functions/styleFunctions';
|
||||
|
||||
export async function addObserver(plugin: FolderNotesPlugin) {
|
||||
plugin.observer = new MutationObserver((mutations: MutationRecord[]) => {
|
||||
|
|
@ -12,6 +13,8 @@ export async function addObserver(plugin: FolderNotesPlugin) {
|
|||
.forEach((element: HTMLElement) => {
|
||||
if (element.onclick) return;
|
||||
if (Platform.isMobile && plugin.settings.disableOpenFolderNoteOnClick) return;
|
||||
const folderPath = element.parentElement?.getAttribute('data-path') || '';
|
||||
const apply = applyCSSClassesToFolder(folderPath, plugin);
|
||||
// handle middle click
|
||||
element.addEventListener('auxclick', (event: MouseEvent) => {
|
||||
if (event.button == 1) {
|
||||
|
|
|
|||
|
|
@ -63,10 +63,9 @@ export class FileExplorerOverview {
|
|||
|
||||
|
||||
folderElement = document.querySelectorAll('.nav-files-container')[0] as HTMLElement;
|
||||
console.log('folderElement', folderElement);
|
||||
if (!folderElement) return;
|
||||
|
||||
const newFolderElement = folderElement.cloneNode(true) as HTMLElement;
|
||||
console.log('newFolderElement', newFolderElement);
|
||||
|
||||
newFolderElement.querySelectorAll('div.nav-folder-title').forEach((el) => {
|
||||
const folder = plugin.app.vault.getAbstractFileByPath(el.getAttribute('data-path') || '');
|
||||
|
|
|
|||
|
|
@ -26,55 +26,49 @@ export function loadFileClasses(forceReload = false, plugin: FolderNotesPlugin)
|
|||
removeCSSClassFromEL(file?.path, 'only-has-folder-note');
|
||||
} else {
|
||||
if (!excludedFolder?.hideNote) {
|
||||
addCSSClassToTitleEL(plugin, folderNote.path, 'is-folder-note');
|
||||
}
|
||||
addCSSClassToTitleEL(plugin, file.path, 'has-folder-note');
|
||||
if (plugin.isEmptyFolderNoteFolder(file)) {
|
||||
addCSSClassToTitleEL(plugin, file.path, 'only-has-folder-note');
|
||||
} else {
|
||||
removeCSSClassFromEL(file.path, 'only-has-folder-note');
|
||||
addCSSClassToTitleEL(folderNote.path, 'is-folder-note');
|
||||
}
|
||||
addCSSClassesToFolder(file, plugin);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// load classes of specific folder
|
||||
export async function loadFolderClasses(forceReload = false, folder: TFolder, plugin: FolderNotesPlugin) {
|
||||
if (plugin.activeFileExplorer === getFileExplorer() && !forceReload) { return; }
|
||||
plugin.activeFileExplorer = getFileExplorer();
|
||||
|
||||
export async function applyCSSClassesToFolder(folderPath: string, plugin: FolderNotesPlugin) {
|
||||
const folder = plugin.app.vault.getAbstractFileByPath(folderPath);
|
||||
if (!folder || !(folder instanceof TFolder)) { return; }
|
||||
|
||||
const folderNote = getFolderNote(plugin, folder.path);
|
||||
if (!folderNote) {
|
||||
removeCSSClassFromEL(folder?.path, 'has-folder-note');
|
||||
removeCSSClassFromEL(folder?.path, 'only-has-folder-note');
|
||||
plugin.isEmptyFolderNoteFolder(folder)
|
||||
return;
|
||||
}
|
||||
|
||||
const excludedFolder = await getExcludedFolder(plugin, folder.path, true);
|
||||
// cleanup after ourselves
|
||||
// Incase settings have changed
|
||||
|
||||
if (excludedFolder?.disableFolderNote) {
|
||||
removeCSSClassFromEL(folderNote.path, 'is-folder-note');
|
||||
removeCSSClassFromEL(folder.path, 'has-folder-note');
|
||||
removeCSSClassFromEL(folder?.path, 'only-has-folder-note');
|
||||
} else {
|
||||
if (!excludedFolder?.hideNote) {
|
||||
addCSSClassToTitleEL(plugin, folderNote.path, 'is-folder-note');
|
||||
addCSSClassToFolderNote(folderNote);
|
||||
}
|
||||
addCSSClassToTitleEL(plugin, folder.path, 'has-folder-note');
|
||||
addCSSClassesToFolder(folder, plugin);
|
||||
if (plugin.isEmptyFolderNoteFolder(folder)) {
|
||||
addCSSClassToTitleEL(plugin, folder.path, 'only-has-folder-note');
|
||||
addCSSClassToTitleEL(folder.path, 'only-has-folder-note');
|
||||
} else {
|
||||
removeCSSClassFromEL(folder.path, 'only-has-folder-note');
|
||||
}
|
||||
}
|
||||
|
||||
addCSSClassesToBothFolderAndNote(folderNote, folder, plugin);
|
||||
}
|
||||
|
||||
export function addCSSClassesToBothFolderAndNote(file: TFile, folder: TFolder) {
|
||||
export function addCSSClassesToBothFolderAndNote(file: TFile, folder: TFolder, plugin: FolderNotesPlugin) {
|
||||
addCSSClassToFolderNote(file);
|
||||
addCSSClassesToFolder(folder);
|
||||
addCSSClassesToFolder(folder, plugin);
|
||||
}
|
||||
|
||||
export function removeCSSClassesFromBothFolderAndNote(folder: TFolder, file: TFile) {
|
||||
|
|
@ -82,30 +76,30 @@ export function removeCSSClassesFromBothFolderAndNote(folder: TFolder, file: TFi
|
|||
removeCSSClassesFromFolder(folder);
|
||||
}
|
||||
|
||||
export function addCSSClassesToFolder(folder: TFolder) {
|
||||
addCSSClassToTitleEL(undefined, folder.path, 'has-folder-note');
|
||||
if (this.isEmptyFolderNoteFolder(folder)) {
|
||||
addCSSClassToTitleEL(undefined, folder.path, 'only-has-folder-note');
|
||||
export function addCSSClassesToFolder(folder: TFolder, plugin: FolderNotesPlugin) {
|
||||
addCSSClassToTitleEL(folder.path, 'has-folder-note');
|
||||
if (plugin.isEmptyFolderNoteFolder(folder)) {
|
||||
addCSSClassToTitleEL(folder.path, 'only-has-folder-note');
|
||||
} else {
|
||||
removeCSSClassFromEL(folder.path, 'only-has-folder-note');
|
||||
}
|
||||
}
|
||||
|
||||
export function addCSSClassToFolderNote(file: TFile) {
|
||||
addCSSClassToTitleEL(undefined, file.path, 'is-folder-note');
|
||||
addCSSClassToTitleEL(file.path, 'is-folder-note');
|
||||
}
|
||||
|
||||
export function removeCSSClassFromFolderNote(file: TFile) {
|
||||
this.removeCSSClassFromEL(file.path, 'is-folder-note');
|
||||
removeCSSClassFromEL(file.path, 'is-folder-note');
|
||||
}
|
||||
|
||||
export function removeCSSClassesFromFolder(folder: TFolder) {
|
||||
this.removeCSSClassFromEL(folder.path, 'has-folder-note');
|
||||
this.removeCSSClassFromEL(folder.path, 'only-has-folder-note');
|
||||
removeCSSClassFromEL(folder.path, 'has-folder-note');
|
||||
removeCSSClassFromEL(folder.path, 'only-has-folder-note');
|
||||
}
|
||||
|
||||
export async function addCSSClassToTitleEL(plugin: FolderNotesPlugin | undefined, path: string, cssClass: string, waitForCreate = false, count = 0) {
|
||||
const fileExplorerItem = getEl(path)
|
||||
export async function addCSSClassToTitleEL(path: string, cssClass: string, waitForCreate = false, count = 0) {
|
||||
const fileExplorerItem = getEl(path);
|
||||
if (!fileExplorerItem) {
|
||||
if (waitForCreate && count < 5) {
|
||||
// sleep for a second for the file-explorer event to catch up
|
||||
|
|
@ -113,21 +107,19 @@ export async function addCSSClassToTitleEL(plugin: FolderNotesPlugin | undefined
|
|||
// If we could guarrantee load order it wouldn't be an issue but we can't
|
||||
// realise this is racey and needs to be fixed.
|
||||
await new Promise((r) => setTimeout(r, 500));
|
||||
addCSSClassToTitleEL(plugin, path, cssClass, waitForCreate, count + 1);
|
||||
addCSSClassToTitleEL(path, cssClass, waitForCreate, count + 1);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
fileExplorerItem.addClass(cssClass);
|
||||
|
||||
const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`);
|
||||
viewHeaderItems.forEach((item) => {
|
||||
item.addClass(cssClass);
|
||||
});
|
||||
}
|
||||
|
||||
export async function removeCSSClassFromEL(path: string | undefined, cssClass: string) {
|
||||
export function removeCSSClassFromEL(path: string | undefined, cssClass: string) {
|
||||
if (!path) return;
|
||||
const fileExplorerItem = getEl(path);
|
||||
const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`);
|
||||
|
|
@ -145,5 +137,4 @@ export function getEl(path: string): HTMLElement | null {
|
|||
if (!fileExplorerItem) { return null; }
|
||||
if (fileExplorerItem.selfEl) return fileExplorerItem.selfEl;
|
||||
return fileExplorerItem.titleEl;
|
||||
}
|
||||
|
||||
}
|
||||
45
src/main.ts
45
src/main.ts
|
|
@ -13,7 +13,7 @@ import { FolderOverview } from './folderOverview/FolderOverview';
|
|||
import { TabManager } from './events/TabManager';
|
||||
import './functions/ListComponent';
|
||||
import { handleDelete } from './events/handleDelete';
|
||||
import { addCSSClassToTitleEL, getEl, loadFileClasses, removeCSSClassFromEL } from './functions/styleFunctions';
|
||||
import { addCSSClassToTitleEL, getEl, loadFileClasses } from './functions/styleFunctions';
|
||||
import { getExcludedFolder } from './ExcludeFolders/functions/folderFunctions';
|
||||
import { ClipBoardManager, FileExplorerView, InternalPlugin, InternalPlugins } from 'obsidian-typings'
|
||||
export default class FolderNotesPlugin extends Plugin {
|
||||
|
|
@ -87,11 +87,6 @@ export default class FolderNotesPlugin extends Plugin {
|
|||
this.hoverLinkTriggered = true;
|
||||
});
|
||||
|
||||
this.registerEvent(this.app.workspace.on('layout-change', () => {
|
||||
loadFileClasses(undefined, this);
|
||||
this.tabManager?.updateTabs();
|
||||
}));
|
||||
|
||||
this.registerEvent(this.app.vault.on('create', (file: TAbstractFile) => {
|
||||
handleCreate(file, this);
|
||||
}));
|
||||
|
|
@ -129,8 +124,18 @@ 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();
|
||||
}));
|
||||
} else {
|
||||
this.app.workspace.onLayoutReady(async () => loadFileClasses(undefined, this));
|
||||
this.app.workspace.onLayoutReady(async () => {
|
||||
loadFileClasses(undefined, this)
|
||||
this.registerEvent(this.app.workspace.on('layout-change', () => {
|
||||
loadFileClasses(undefined, this);
|
||||
this.tabManager?.updateTabs();
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -141,13 +146,20 @@ export default class FolderNotesPlugin extends Plugin {
|
|||
this.tabManager = new TabManager(this);
|
||||
this.tabManager.updateTabs();
|
||||
|
||||
const view = this.app.workspace.getLeavesOfType('markdown')[0]?.view;
|
||||
const leaf = this.app.workspace.getLeavesOfType('markdown').first();
|
||||
const view = leaf?.view;
|
||||
|
||||
if (!view) { return; }
|
||||
|
||||
// @ts-ignore
|
||||
const editMode = view.editMode ?? view.sourceMode ?? this.app.workspace.activeEditor?.editMode;
|
||||
const plugin = this;
|
||||
|
||||
// @ts-ignore
|
||||
const originalHandleDragOver = view.editMode.clipboardManager.constructor.prototype.handleDragOver;
|
||||
const originalHandleDragOver = editMode.clipboardManager.constructor.prototype.handleDragOver;
|
||||
|
||||
// @ts-ignore
|
||||
view.editMode.clipboardManager.constructor.prototype.handleDragOver = function (evt, ...args) {
|
||||
editMode.clipboardManager.constructor.prototype.handleDragOver = function (evt, ...args) {
|
||||
const { draggable } = plugin.app.dragManager;
|
||||
if (draggable && draggable.file instanceof TFolder && getFolderNote(plugin, draggable.file.path)) {
|
||||
plugin.app.dragManager.setAction(window.i18next.t("interface.drag-and-drop.insert-link-here"));
|
||||
|
|
@ -157,9 +169,9 @@ export default class FolderNotesPlugin extends Plugin {
|
|||
};
|
||||
|
||||
// @ts-ignore
|
||||
const originalHandleDrop = view.editMode.clipboardManager.constructor.prototype.handleDrop;
|
||||
const originalHandleDrop = editMode.clipboardManager.constructor.prototype.handleDrop;
|
||||
// @ts-ignore
|
||||
view.editMode.clipboardManager.constructor.prototype.handleDrop = function (evt, ...args) {
|
||||
editMode.clipboardManager.constructor.prototype.handleDrop = function (evt, ...args) {
|
||||
const { draggable } = plugin.app.dragManager;
|
||||
if (draggable && draggable.file instanceof TFolder && getFolderNote(plugin, draggable.file.path)) {
|
||||
const folderNote = getFolderNote(plugin, draggable.file.path);
|
||||
|
|
@ -171,9 +183,7 @@ export default class FolderNotesPlugin extends Plugin {
|
|||
return originalHandleDrop.call(this, evt, ...args);
|
||||
}
|
||||
|
||||
// const fileExplorerPluginInstance = this.app.internalPlugins.getEnabledPluginById(InternalPluginName.FileExplorer);
|
||||
|
||||
|
||||
// const fileExplorerPluginInstance = this.app.internalPlugins.getEnabledPluginById(InternalPluginName.FileExplorer);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -189,17 +199,18 @@ export default class FolderNotesPlugin extends Plugin {
|
|||
}, { capture: true });
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(el, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
|
||||
try {
|
||||
if (this.app.workspace.layoutReady) {
|
||||
const folderOverview = new FolderOverview(this, ctx, source, el);
|
||||
folderOverview.create(this, parseYaml(source), el, ctx);
|
||||
} else {
|
||||
this.app.workspace.onLayoutReady(() => {
|
||||
console.log('layout ready');
|
||||
const folderOverview = new FolderOverview(this, ctx, source, el);
|
||||
folderOverview.create(this, parseYaml(source), el, ctx);
|
||||
});
|
||||
|
|
@ -216,7 +227,7 @@ export default class FolderNotesPlugin extends Plugin {
|
|||
const attachmentsAreInRootFolder = attachmentFolderPath === './' || attachmentFolderPath === '';
|
||||
const threshold = this.settings.storageLocation === 'insideFolder' ? 1 : 0;
|
||||
if (folder.children.length == 0) {
|
||||
addCSSClassToTitleEL(this, folder.path, 'fn-empty-folder');
|
||||
addCSSClassToTitleEL(folder.path, 'fn-empty-folder');
|
||||
}
|
||||
|
||||
if (folder.children.length == threshold) {
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ export enum FileSuggestMode {
|
|||
export class FileSuggest extends TextInputSuggest<TFile> {
|
||||
constructor(
|
||||
public inputEl: HTMLInputElement,
|
||||
private plugin: FolderNotesPlugin
|
||||
plugin: FolderNotesPlugin
|
||||
) {
|
||||
super(inputEl);
|
||||
super(inputEl, plugin);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ export enum FileSuggestMode {
|
|||
export class FolderSuggest extends TextInputSuggest<TFolder> {
|
||||
constructor(
|
||||
public inputEl: HTMLInputElement,
|
||||
private plugin: FolderNotesPlugin,
|
||||
plugin: FolderNotesPlugin,
|
||||
private whitelistSuggester: boolean,
|
||||
public folder?: TFolder,
|
||||
) {
|
||||
super(inputEl);
|
||||
super(inputEl, plugin);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import { ISuggestOwner, Scope } from 'obsidian';
|
||||
import { createPopper, Instance as PopperInstance } from '@popperjs/core';
|
||||
import FolderNotesPlugin from 'src/main';
|
||||
|
||||
const wrapAround = (value: number, size: number): number => {
|
||||
return ((value % size) + size) % size;
|
||||
|
|
@ -14,6 +15,7 @@ class Suggest<T> {
|
|||
private suggestions: HTMLDivElement[];
|
||||
private selectedItem: number;
|
||||
private containerEl: HTMLElement;
|
||||
plugin: FolderNotesPlugin;
|
||||
|
||||
constructor(
|
||||
owner: ISuggestOwner<T>,
|
||||
|
|
@ -117,12 +119,14 @@ export abstract class TextInputSuggest<T> implements ISuggestOwner<T> {
|
|||
private scope: Scope;
|
||||
private suggestEl: HTMLElement;
|
||||
private suggest: Suggest<T>;
|
||||
plugin: FolderNotesPlugin;
|
||||
|
||||
constructor(inputEl: HTMLInputElement | HTMLTextAreaElement) {
|
||||
constructor(inputEl: HTMLInputElement | HTMLTextAreaElement, plugin: FolderNotesPlugin) {
|
||||
this.inputEl = inputEl;
|
||||
this.plugin = plugin;
|
||||
this.scope = new Scope();
|
||||
|
||||
this.suggestEl = createDiv('fn-suggestion-container');
|
||||
this.suggestEl = createDiv('suggestion-container');
|
||||
const suggestion = this.suggestEl.createDiv('suggestion');
|
||||
this.suggest = new Suggest(this, suggestion, this.scope);
|
||||
|
||||
|
|
@ -133,7 +137,7 @@ export abstract class TextInputSuggest<T> implements ISuggestOwner<T> {
|
|||
this.inputEl.addEventListener('blur', this.close.bind(this));
|
||||
this.suggestEl.on(
|
||||
'mousedown',
|
||||
'.fn-suggestion-container',
|
||||
'.suggestion-container',
|
||||
(event: MouseEvent) => {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
|
@ -160,7 +164,7 @@ export abstract class TextInputSuggest<T> implements ISuggestOwner<T> {
|
|||
|
||||
open(container: HTMLElement, inputEl: HTMLElement): void {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
app.keymap.pushScope(this.scope);
|
||||
this.plugin.app.keymap.pushScope(this.scope);
|
||||
|
||||
container.appendChild(this.suggestEl);
|
||||
this.popper = createPopper(inputEl, this.suggestEl, {
|
||||
|
|
@ -189,7 +193,7 @@ export abstract class TextInputSuggest<T> implements ISuggestOwner<T> {
|
|||
}
|
||||
|
||||
close(): void {
|
||||
app.keymap.popScope(this.scope);
|
||||
this.plugin.app.keymap.popScope(this.scope);
|
||||
|
||||
this.suggest.setSuggestions([]);
|
||||
if (this.popper) this.popper.destroy();
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ export enum FileSuggestMode {
|
|||
export class TemplateSuggest extends TextInputSuggest<TFile> {
|
||||
constructor(
|
||||
public inputEl: HTMLInputElement,
|
||||
private plugin: FolderNotesPlugin
|
||||
plugin: FolderNotesPlugin
|
||||
) {
|
||||
super(inputEl);
|
||||
super(inputEl, plugin);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
padding-top: 4px !important;
|
||||
}
|
||||
|
||||
.fn-whitespace-stop-collapsing .collapse-icon {
|
||||
padding-top: 4px !important;
|
||||
}
|
||||
|
||||
.mod-rtl .fn-whitespace-stop-collapsing .nav-folder-title-content {
|
||||
padding-left: 8px !important;
|
||||
}
|
||||
|
|
@ -266,4 +270,4 @@ body:not(.disable-folder-highlight) .tree-item-self.fn-is-active {
|
|||
border: 1px solid var(--background-modifier-border);
|
||||
box-shadow: var(--shadow-s);
|
||||
z-index: var(--layer-notice);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue