feat: parent notes (file bookmarks with children) + no default icon
- File bookmarks can now have children, rendered with a chevron - Group bookmarks can have an associated filePath; clicking opens the file, clicking chevron toggles collapse - 'Add as parent note' option in header context menu creates a group with the current file linked - 'Add child note' option in group context menu creates a sub-group with the current file linked (parent note pattern) - Default icon changed from 'file'/'folder' to '' (no icon) - Chevron click always toggles collapse regardless of type
This commit is contained in:
+1
-1
@@ -254,7 +254,7 @@ export default class WaypointPlugin extends Plugin {
|
|||||||
|
|
||||||
// ── Bookmarks ──
|
// ── Bookmarks ──
|
||||||
|
|
||||||
addBookmark(filePath: string, label: string, type: 'file' | 'group' | 'separator' | 'spacer' = 'file', icon = 'file'): BookmarkItem {
|
addBookmark(filePath: string, label: string, type: 'file' | 'group' | 'separator' | 'spacer' = 'file', icon = ''): BookmarkItem {
|
||||||
const id = `bm-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
const id = `bm-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
||||||
const item: BookmarkItem = {
|
const item: BookmarkItem = {
|
||||||
id,
|
id,
|
||||||
|
|||||||
+77
-10
@@ -316,12 +316,25 @@ export class WaypointView extends ItemView {
|
|||||||
this.plugin.addBookmark(file.path, file.basename, 'file');
|
this.plugin.addBookmark(file.path, file.basename, 'file');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
menu.addItem((item) => {
|
||||||
|
item
|
||||||
|
.setTitle('Add as parent note')
|
||||||
|
.setIcon('folder-plus')
|
||||||
|
.onClick(() => {
|
||||||
|
const file = this.app.workspace.getActiveFile();
|
||||||
|
if (!file) return;
|
||||||
|
const bm = this.plugin.addBookmark(file.path, file.basename, 'group', '');
|
||||||
|
bm.filePath = file.path;
|
||||||
|
this.plugin.saveWaypointData();
|
||||||
|
this.redraw();
|
||||||
|
});
|
||||||
|
});
|
||||||
menu.addItem((item) => {
|
menu.addItem((item) => {
|
||||||
item
|
item
|
||||||
.setTitle('New group')
|
.setTitle('New group')
|
||||||
.setIcon('folder-plus')
|
.setIcon('folder-plus')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this.plugin.addBookmark('', 'New Group', 'group', 'folder');
|
this.plugin.addBookmark('', 'New Group', 'group', '');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
menu.addItem((item) => {
|
menu.addItem((item) => {
|
||||||
@@ -534,23 +547,30 @@ export class WaypointView extends ItemView {
|
|||||||
if (isGroup) {
|
if (isGroup) {
|
||||||
const chevron = rowEl.createDiv({ cls: 'waypoint-bm-chevron' });
|
const chevron = rowEl.createDiv({ cls: 'waypoint-bm-chevron' });
|
||||||
setIcon(chevron, 'chevron-down');
|
setIcon(chevron, 'chevron-down');
|
||||||
|
chevron.addEventListener('click', (event: MouseEvent) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.plugin.updateBookmark(item.id, { collapsed: !item.collapsed });
|
||||||
|
});
|
||||||
|
|
||||||
const iconEl = rowEl.createDiv({ cls: 'waypoint-bm-icon' });
|
const iconEl = rowEl.createDiv({ cls: 'waypoint-bm-icon' });
|
||||||
setIcon(iconEl, item.icon || 'folder');
|
if (item.icon) setIcon(iconEl, item.icon);
|
||||||
|
|
||||||
const labelEl = rowEl.createDiv({ cls: 'waypoint-bm-label', text: item.label });
|
const labelEl = rowEl.createDiv({ cls: 'waypoint-bm-label', text: item.label });
|
||||||
|
|
||||||
|
// Click group row → open linked file (if any), otherwise toggle collapse
|
||||||
rowEl.addEventListener('click', (event: MouseEvent) => {
|
rowEl.addEventListener('click', (event: MouseEvent) => {
|
||||||
// Mod+click opens group's linked file
|
if (item.filePath) {
|
||||||
if (item.filePath && Keymap.isModEvent(event)) {
|
|
||||||
const tfile = this.app.vault.getFileByPath(item.filePath);
|
const tfile = this.app.vault.getFileByPath(item.filePath);
|
||||||
if (tfile) this.app.workspace.getLeaf(false).openFile(tfile);
|
if (tfile) {
|
||||||
|
const newLeaf = Keymap.isModEvent(event);
|
||||||
|
this.app.workspace.getLeaf(newLeaf as any).openFile(tfile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this.plugin.updateBookmark(item.id, { collapsed: !item.collapsed });
|
this.plugin.updateBookmark(item.id, { collapsed: !item.collapsed });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Middle click on group header → open group's linked file in new tab
|
// Middle click on group → open in new tab
|
||||||
rowEl.addEventListener('mousedown', (event: MouseEvent) => {
|
rowEl.addEventListener('mousedown', (event: MouseEvent) => {
|
||||||
if (event.button === 1 && item.filePath) {
|
if (event.button === 1 && item.filePath) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -570,8 +590,22 @@ export class WaypointView extends ItemView {
|
|||||||
|
|
||||||
// ── File: icon + label ──
|
// ── File: icon + label ──
|
||||||
} else {
|
} else {
|
||||||
|
// Chevron for file bookmarks that have children
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
const chevron = rowEl.createDiv({ cls: 'waypoint-bm-chevron' });
|
||||||
|
setIcon(chevron, 'chevron-down');
|
||||||
|
chevron.addEventListener('click', (event: MouseEvent) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.plugin.updateBookmark(item.id, { collapsed: !item.collapsed });
|
||||||
|
});
|
||||||
|
if (item.collapsed) {
|
||||||
|
rowEl.addClass('collapsed');
|
||||||
|
chevron.style.transform = 'rotate(-90deg)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const iconEl = rowEl.createDiv({ cls: 'waypoint-bm-icon' });
|
const iconEl = rowEl.createDiv({ cls: 'waypoint-bm-icon' });
|
||||||
setIcon(iconEl, item.icon || 'file');
|
if (item.icon) setIcon(iconEl, item.icon);
|
||||||
|
|
||||||
const labelEl = rowEl.createDiv({ cls: 'waypoint-bm-label', text: item.label });
|
const labelEl = rowEl.createDiv({ cls: 'waypoint-bm-label', text: item.label });
|
||||||
setTooltip(rowEl, item.filePath);
|
setTooltip(rowEl, item.filePath);
|
||||||
@@ -599,6 +633,14 @@ export class WaypointView extends ItemView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Children container for file bookmarks with children
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
const childrenContainer = container.createDiv({
|
||||||
|
cls: `waypoint-bookmark-children${item.collapsed ? ' collapsed' : ''}`,
|
||||||
|
});
|
||||||
|
this.renderBookmarkList(childrenContainer, item.children, depth + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Right-click context menu (both types) ──
|
// ── Right-click context menu (both types) ──
|
||||||
@@ -687,7 +729,7 @@ export class WaypointView extends ItemView {
|
|||||||
menu.addItem((i) =>
|
menu.addItem((i) =>
|
||||||
i
|
i
|
||||||
.setTitle('Add bookmark here')
|
.setTitle('Add bookmark here')
|
||||||
.setIcon('plus')
|
.setIcon('file-plus')
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
const file = this.app.workspace.getActiveFile();
|
const file = this.app.workspace.getActiveFile();
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@@ -699,7 +741,32 @@ export class WaypointView extends ItemView {
|
|||||||
type: 'file',
|
type: 'file',
|
||||||
label: file.basename,
|
label: file.basename,
|
||||||
filePath: file.path,
|
filePath: file.path,
|
||||||
icon: 'file',
|
icon: '',
|
||||||
|
children: [],
|
||||||
|
collapsed: false,
|
||||||
|
indent: item.indent + 1,
|
||||||
|
};
|
||||||
|
item.children.push(child);
|
||||||
|
this.plugin.saveWaypointData();
|
||||||
|
this.redraw();
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
menu.addItem((i) =>
|
||||||
|
i
|
||||||
|
.setTitle('Add child note')
|
||||||
|
.setIcon('file-plus')
|
||||||
|
.onClick(() => {
|
||||||
|
const file = this.app.workspace.getActiveFile();
|
||||||
|
if (!file) {
|
||||||
|
new Notice('No active file');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const child: BookmarkItem = {
|
||||||
|
id: `bm-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
||||||
|
type: 'group',
|
||||||
|
label: file.basename,
|
||||||
|
filePath: file.path,
|
||||||
|
icon: '',
|
||||||
children: [],
|
children: [],
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
indent: item.indent + 1,
|
indent: item.indent + 1,
|
||||||
@@ -719,7 +786,7 @@ export class WaypointView extends ItemView {
|
|||||||
type: 'group',
|
type: 'group',
|
||||||
label: 'New Group',
|
label: 'New Group',
|
||||||
filePath: '',
|
filePath: '',
|
||||||
icon: 'folder',
|
icon: '',
|
||||||
children: [],
|
children: [],
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
indent: item.indent + 1,
|
indent: item.indent + 1,
|
||||||
|
|||||||
Reference in New Issue
Block a user