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 ──
|
||||
|
||||
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 item: BookmarkItem = {
|
||||
id,
|
||||
|
||||
+77
-10
@@ -316,12 +316,25 @@ export class WaypointView extends ItemView {
|
||||
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) => {
|
||||
item
|
||||
.setTitle('New group')
|
||||
.setIcon('folder-plus')
|
||||
.onClick(() => {
|
||||
this.plugin.addBookmark('', 'New Group', 'group', 'folder');
|
||||
this.plugin.addBookmark('', 'New Group', 'group', '');
|
||||
});
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
@@ -534,23 +547,30 @@ export class WaypointView extends ItemView {
|
||||
if (isGroup) {
|
||||
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 });
|
||||
});
|
||||
|
||||
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 });
|
||||
|
||||
// Click group row → open linked file (if any), otherwise toggle collapse
|
||||
rowEl.addEventListener('click', (event: MouseEvent) => {
|
||||
// Mod+click opens group's linked file
|
||||
if (item.filePath && Keymap.isModEvent(event)) {
|
||||
if (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;
|
||||
}
|
||||
}
|
||||
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) => {
|
||||
if (event.button === 1 && item.filePath) {
|
||||
event.preventDefault();
|
||||
@@ -570,8 +590,22 @@ export class WaypointView extends ItemView {
|
||||
|
||||
// ── File: icon + label ──
|
||||
} 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' });
|
||||
setIcon(iconEl, item.icon || 'file');
|
||||
if (item.icon) setIcon(iconEl, item.icon);
|
||||
|
||||
const labelEl = rowEl.createDiv({ cls: 'waypoint-bm-label', text: item.label });
|
||||
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) ──
|
||||
@@ -687,7 +729,7 @@ export class WaypointView extends ItemView {
|
||||
menu.addItem((i) =>
|
||||
i
|
||||
.setTitle('Add bookmark here')
|
||||
.setIcon('plus')
|
||||
.setIcon('file-plus')
|
||||
.onClick(() => {
|
||||
const file = this.app.workspace.getActiveFile();
|
||||
if (!file) {
|
||||
@@ -699,7 +741,32 @@ export class WaypointView extends ItemView {
|
||||
type: 'file',
|
||||
label: file.basename,
|
||||
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: [],
|
||||
collapsed: false,
|
||||
indent: item.indent + 1,
|
||||
@@ -719,7 +786,7 @@ export class WaypointView extends ItemView {
|
||||
type: 'group',
|
||||
label: 'New Group',
|
||||
filePath: '',
|
||||
icon: 'folder',
|
||||
icon: '',
|
||||
children: [],
|
||||
collapsed: false,
|
||||
indent: item.indent + 1,
|
||||
|
||||
Reference in New Issue
Block a user