mirror of
https://github.com/cosmicoptima/loom.git
synced 2026-07-22 07:40:25 +00:00
add bookmarking
This commit is contained in:
parent
89eb733f7e
commit
08d4d4943d
2 changed files with 84 additions and 6 deletions
71
main.ts
71
main.ts
|
|
@ -46,6 +46,7 @@ interface Node {
|
|||
unread: boolean;
|
||||
lastVisited?: number;
|
||||
collapsed: boolean;
|
||||
bookmarked: boolean;
|
||||
}
|
||||
|
||||
interface NoteState {
|
||||
|
|
@ -311,6 +312,7 @@ export default class LoomPlugin extends Plugin {
|
|||
parentId: null,
|
||||
unread: false,
|
||||
collapsed: false,
|
||||
bookmarked: false,
|
||||
};
|
||||
|
||||
return;
|
||||
|
|
@ -372,6 +374,7 @@ export default class LoomPlugin extends Plugin {
|
|||
parentId: i === 0 ? null : ancestors[i - 1],
|
||||
unread: false,
|
||||
collapsed: false,
|
||||
bookmarked: false,
|
||||
};
|
||||
|
||||
let parentId = id;
|
||||
|
|
@ -382,6 +385,7 @@ export default class LoomPlugin extends Plugin {
|
|||
parentId,
|
||||
unread: false,
|
||||
collapsed: false,
|
||||
bookmarked: false,
|
||||
};
|
||||
parentId = childId;
|
||||
}
|
||||
|
|
@ -480,6 +484,16 @@ export default class LoomPlugin extends Plugin {
|
|||
)
|
||||
);
|
||||
|
||||
this.registerEvent(
|
||||
// @ts-ignore
|
||||
this.app.workspace.on("loom:toggle-bookmark", (id: string) =>
|
||||
this.wftsar(
|
||||
(file) =>
|
||||
(this.state[file.path].nodes[id].bookmarked = !this.state[file.path].nodes[id].bookmarked)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
this.registerEvent(
|
||||
// @ts-ignore
|
||||
this.app.workspace.on("loom:create-child", (id: string) =>
|
||||
|
|
@ -490,6 +504,7 @@ export default class LoomPlugin extends Plugin {
|
|||
parentId: id,
|
||||
unread: false,
|
||||
collapsed: false,
|
||||
bookmarked: false,
|
||||
};
|
||||
|
||||
this.app.workspace.trigger("loom:switch-to", newId);
|
||||
|
|
@ -507,6 +522,7 @@ export default class LoomPlugin extends Plugin {
|
|||
parentId: this.state[file.path].nodes[id].parentId,
|
||||
unread: false,
|
||||
collapsed: false,
|
||||
bookmarked: false,
|
||||
};
|
||||
|
||||
this.app.workspace.trigger("loom:switch-to", newId);
|
||||
|
|
@ -524,6 +540,7 @@ export default class LoomPlugin extends Plugin {
|
|||
parentId: this.state[file.path].nodes[id].parentId,
|
||||
unread: false,
|
||||
collapsed: false,
|
||||
bookmarked: false,
|
||||
};
|
||||
|
||||
this.app.workspace.trigger("loom:switch-to", newId);
|
||||
|
|
@ -584,6 +601,7 @@ export default class LoomPlugin extends Plugin {
|
|||
parentId: inRangeNode,
|
||||
unread: false,
|
||||
collapsed: false,
|
||||
bookmarked: false,
|
||||
};
|
||||
|
||||
// then, create a new node with no text
|
||||
|
|
@ -593,6 +611,7 @@ export default class LoomPlugin extends Plugin {
|
|||
parentId: inRangeNode,
|
||||
unread: false,
|
||||
collapsed: false,
|
||||
bookmarked: false,
|
||||
};
|
||||
|
||||
// move the children to under the after node
|
||||
|
|
@ -747,6 +766,7 @@ export default class LoomPlugin extends Plugin {
|
|||
parentId: null,
|
||||
unread: false,
|
||||
collapsed: false,
|
||||
bookmarked: false,
|
||||
};
|
||||
this.state[file.path].current = id;
|
||||
|
||||
|
|
@ -823,6 +843,7 @@ export default class LoomPlugin extends Plugin {
|
|||
parentId: state.current,
|
||||
unread: true,
|
||||
collapsed: false,
|
||||
bookmarked: false,
|
||||
};
|
||||
ids.push(id);
|
||||
}
|
||||
|
|
@ -1054,7 +1075,7 @@ class LoomView extends ItemView {
|
|||
const rootNodes = nodes.filter(([, node]) => node.parentId === null);
|
||||
if (rootNodes.length === 1) onlyRootNode = rootNodes[0][0];
|
||||
|
||||
const renderNode = (node: Node, id: string, container: HTMLElement) => {
|
||||
const renderNode = (node: Node, id: string, container: HTMLElement, children: boolean) => {
|
||||
// div for the node and its children
|
||||
const nodeDiv = container.createDiv({});
|
||||
|
||||
|
|
@ -1069,7 +1090,7 @@ class LoomView extends ItemView {
|
|||
// an expand/collapse button if the node has children
|
||||
const hasChildren =
|
||||
nodes.filter(([, node]) => node.parentId === id).length > 0;
|
||||
if (hasChildren) {
|
||||
if (children && hasChildren) {
|
||||
const collapseDiv = itemDiv.createDiv({
|
||||
cls: `collapse-icon loom-collapse${
|
||||
node.collapsed ? " is-collapsed" : ""
|
||||
|
|
@ -1081,6 +1102,12 @@ class LoomView extends ItemView {
|
|||
);
|
||||
}
|
||||
|
||||
// a bookmark icon if the node is bookmarked
|
||||
if (node.bookmarked) {
|
||||
const bookmarkDiv = itemDiv.createDiv({ cls: "loom-node-bookmark" });
|
||||
setIcon(bookmarkDiv, "bookmark");
|
||||
}
|
||||
|
||||
// an unread indicator if the node is unread
|
||||
if (node.unread) itemDiv.createDiv({ cls: "loom-node-unread-indicator" });
|
||||
|
||||
|
|
@ -1126,6 +1153,16 @@ class LoomView extends ItemView {
|
|||
item.onClick(() => this.app.workspace.trigger("loom:hoist", id));
|
||||
}
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
if (state.nodes[id].bookmarked) {
|
||||
item.setTitle("Remove bookmark");
|
||||
item.setIcon("bookmark-minus");
|
||||
} else {
|
||||
item.setTitle("Bookmark");
|
||||
item.setIcon("bookmark");
|
||||
}
|
||||
item.onClick(() => this.app.workspace.trigger("loom:toggle-bookmark", id));
|
||||
});
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
|
|
@ -1182,14 +1219,22 @@ class LoomView extends ItemView {
|
|||
this.app.workspace.trigger("loom:hoist", id)
|
||||
);
|
||||
|
||||
if (state.nodes[id].bookmarked)
|
||||
itemButton("Remove bookmark", "bookmark-minus", () =>
|
||||
this.app.workspace.trigger("loom:toggle-bookmark", id)
|
||||
);
|
||||
else
|
||||
itemButton("Bookmark", "bookmark", () =>
|
||||
this.app.workspace.trigger("loom:toggle-bookmark", id)
|
||||
);
|
||||
|
||||
if (id !== onlyRootNode)
|
||||
itemButton("Delete", "trash", () =>
|
||||
this.app.workspace.trigger("loom:delete", id)
|
||||
);
|
||||
|
||||
// render children if the node is not collapsed
|
||||
if (!node.collapsed) {
|
||||
// if the node is too narrow, render a hoist button instead
|
||||
if (children && !node.collapsed) {
|
||||
const hasChildren =
|
||||
nodes.filter(([, node]) => node.parentId === id).length > 0;
|
||||
if (nodeDiv.offsetWidth < 150 && hasChildren) {
|
||||
|
|
@ -1215,16 +1260,30 @@ class LoomView extends ItemView {
|
|||
container: HTMLElement
|
||||
) => {
|
||||
const children = nodes.filter(([, node]) => node.parentId === parentId);
|
||||
for (const [id, node] of children) renderNode(node, id, container);
|
||||
for (const [id, node] of children) renderNode(node, id, container, true);
|
||||
};
|
||||
|
||||
// bookmark list
|
||||
const bookmarksDiv = container.createDiv({ cls: "loom-section" });
|
||||
const bookmarks = nodes.filter(([, node]) => node.bookmarked);
|
||||
const bookmarkHeader = bookmarksDiv.createDiv({ cls: "tree-item-self loom-node loom-section-header" });
|
||||
bookmarkHeader.createEl("b", { text: "Bookmarks", cls: "tree-item-inner" });
|
||||
bookmarkHeader.createEl("span", { text: `${bookmarks.length}`, cls: "tree-item-flair-outer loom-section-count" });
|
||||
for (const [id, node] of bookmarks) renderNode(node, id, bookmarksDiv, false);
|
||||
|
||||
// main tree header
|
||||
const treeHeader = container.createDiv({ cls: "tree-item-self loom-node loom-section-header" });
|
||||
const treeHeaderText = state.hoisted.length > 0 ? "Hoisted node" : "All nodes";
|
||||
treeHeader.createEl("b", { text: treeHeaderText, cls: "tree-item-inner" });
|
||||
|
||||
// if there is a hoisted node, it is the root node
|
||||
// otherwise, all children of `null` are the root nodes
|
||||
if (state.hoisted.length > 0)
|
||||
renderNode(
|
||||
state.nodes[state.hoisted[state.hoisted.length - 1]],
|
||||
state.hoisted[state.hoisted.length - 1],
|
||||
container
|
||||
container,
|
||||
true
|
||||
);
|
||||
else renderChildren(null, container);
|
||||
|
||||
|
|
|
|||
19
styles.css
19
styles.css
|
|
@ -78,6 +78,13 @@
|
|||
padding: 0.35em 0 0.35em 0.6em;
|
||||
}
|
||||
|
||||
.loom-node-bookmark {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 0.3em;
|
||||
margin-right: -0.3em;
|
||||
}
|
||||
|
||||
.loom-node-unread {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
|
@ -108,3 +115,15 @@
|
|||
.loom-spacer {
|
||||
padding-right: 0.6em;
|
||||
}
|
||||
|
||||
.loom-section {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.loom-section-header {
|
||||
padding: 0.35em;
|
||||
}
|
||||
|
||||
.loom-section-count {
|
||||
color: var(--text-faint);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue