mirror of
https://github.com/cosmicoptima/loom.git
synced 2026-07-22 07:40:25 +00:00
small improvements
This commit is contained in:
parent
3f4e4f67a7
commit
06cbff8c21
5 changed files with 86 additions and 51 deletions
29
main.ts
29
main.ts
|
|
@ -6,7 +6,6 @@ import {
|
|||
MakePromptFromPassagesModal,
|
||||
} from './views';
|
||||
import {
|
||||
PROVIDERS,
|
||||
Provider,
|
||||
LoomSettings,
|
||||
SearchResultState,
|
||||
|
|
@ -492,7 +491,7 @@ export default class LoomPlugin extends Plugin {
|
|||
checking,
|
||||
(state) => canDelete(state, state.current, checking),
|
||||
(state) => {
|
||||
this.app.workspace.trigger("loom:delete", state.current);
|
||||
this.app.workspace.trigger("loom:delete", [state.current]);
|
||||
}
|
||||
),
|
||||
hotkeys: [{ modifiers: ["Alt"], key: "Backspace" }],
|
||||
|
|
@ -828,25 +827,26 @@ export default class LoomPlugin extends Plugin {
|
|||
|
||||
// switch to the merged node and delete the child node
|
||||
this.app.workspace.trigger("loom:switch-to", parentId);
|
||||
this.app.workspace.trigger("loom:delete", id);
|
||||
this.app.workspace.trigger("loom:delete", [id]);
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
this.registerEvent(
|
||||
// @ts-expect-error
|
||||
this.app.workspace.on("loom:delete", (id: string) =>
|
||||
this.app.workspace.on("loom:delete", (ids: string[]) =>
|
||||
this.wftsar((file) => {
|
||||
const state = this.state[file.path];
|
||||
if (!canDelete(state, id, false)) return;
|
||||
const parentId = state.nodes[id].parentId;
|
||||
|
||||
// remove the node from the hoist stack
|
||||
this.state[file.path].hoisted = state.hoisted.filter((id_) => id_ !== id);
|
||||
ids = ids.filter((id) => canDelete(state, id, false));
|
||||
if (ids.length === 0) return;
|
||||
|
||||
// add the node and its descendants to a list of nodes to delete
|
||||
// remove the nodes from the hoist stack
|
||||
this.state[file.path].hoisted = state.hoisted.filter((id) => !ids.includes(id));
|
||||
|
||||
let deleted = [id];
|
||||
// add the nodes and their descendants to a list of nodes to delete
|
||||
|
||||
let deleted = [...ids];
|
||||
|
||||
const addChildren = (id: string) => {
|
||||
const children = Object.entries(state.nodes)
|
||||
|
|
@ -855,10 +855,11 @@ export default class LoomPlugin extends Plugin {
|
|||
deleted = deleted.concat(children);
|
||||
children.forEach(addChildren);
|
||||
}
|
||||
addChildren(id);
|
||||
ids.forEach(addChildren);
|
||||
|
||||
// if the current node will be deleted, switch to its next sibling or its closest ancestor
|
||||
if (deleted.includes(state.current)) {
|
||||
const parentId = state.nodes[state.current].parentId;
|
||||
const siblings = Object.entries(state.nodes)
|
||||
.filter(([, node]) => node.parentId === parentId)
|
||||
.map(([id]) => id);
|
||||
|
|
@ -908,8 +909,7 @@ export default class LoomPlugin extends Plugin {
|
|||
const children = Object.entries(this.state[file.path].nodes)
|
||||
.filter(([, node]) => node.parentId === id)
|
||||
.map(([id]) => id);
|
||||
for (const id of children)
|
||||
this.app.workspace.trigger("loom:delete", id);
|
||||
this.app.workspace.trigger("loom:delete", children);
|
||||
})
|
||||
)
|
||||
);
|
||||
|
|
@ -922,8 +922,7 @@ export default class LoomPlugin extends Plugin {
|
|||
const siblings = Object.entries(this.state[file.path].nodes)
|
||||
.filter(([id_, node]) => node.parentId === parentId && id_ !== id)
|
||||
.map(([id]) => id);
|
||||
for (const id of siblings)
|
||||
this.app.workspace.trigger("loom:delete", id);
|
||||
this.app.workspace.trigger("loom:delete", siblings);
|
||||
})
|
||||
)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "loom",
|
||||
"name": "Loom",
|
||||
"version": "1.16.1",
|
||||
"version": "1.16.2",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "Loom in Obsidian",
|
||||
"author": "celeste",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "obsidian-loom",
|
||||
"version": "1.16.1",
|
||||
"version": "1.16.2",
|
||||
"description": "Loom in Obsidian",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
|
|||
18
styles.css
18
styles.css
|
|
@ -249,8 +249,11 @@ body {
|
|||
margin: 0.2em 0;
|
||||
padding: 0.8em;
|
||||
white-space: pre-wrap;
|
||||
|
||||
position: relative;
|
||||
}
|
||||
.loom__sibling:hover {
|
||||
background-color: var(--nav-item-background-active);
|
||||
color: var(--nav-item-color-active);
|
||||
}
|
||||
.loom__sibling.is-active {
|
||||
|
|
@ -263,6 +266,21 @@ body {
|
|||
margin-right: 0.3em;
|
||||
}
|
||||
|
||||
.loom__sibling-buttons {
|
||||
display: none;
|
||||
|
||||
background-color: rgba(16, 16, 16, 0.6);
|
||||
border-radius: 0.3em;
|
||||
padding: 0.2em;
|
||||
|
||||
position: absolute;
|
||||
right: 0.5em;
|
||||
top: 0.5em;
|
||||
}
|
||||
.loom__sibling:hover .loom__sibling-buttons {
|
||||
display: inline-flex !important;
|
||||
}
|
||||
|
||||
.loom__sibling-separator {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
|||
86
views.ts
86
views.ts
|
|
@ -11,16 +11,15 @@ import {
|
|||
} from "@codemirror/view";
|
||||
const dialog = require("electron").remote.dialog;
|
||||
|
||||
interface MenuContext {
|
||||
interface NodeContext {
|
||||
app: App;
|
||||
event: MouseEvent;
|
||||
state: NoteState;
|
||||
id: string;
|
||||
node: Node;
|
||||
deletable: boolean;
|
||||
}
|
||||
|
||||
const showNodeMenu = ({ app, event, state, id, node, deletable }: MenuContext) => {
|
||||
const showNodeMenu = (event: MouseEvent, { app, state, id, node, deletable }: NodeContext) => {
|
||||
const menu = new Menu();
|
||||
|
||||
const menuItem = (name: string, icon: string, callback: () => void) =>
|
||||
|
|
@ -34,6 +33,8 @@ const showNodeMenu = ({ app, event, state, id, node, deletable }: MenuContext) =
|
|||
menuItem(name, icon, () => app.workspace.trigger(event));
|
||||
const selfArgMenuItem = (name: string, icon: string, event: string) =>
|
||||
menuItem(name, icon, () => app.workspace.trigger(event, id));
|
||||
const selfListArgMenuItem = (name: string, icon: string, event: string) =>
|
||||
menuItem(name, icon, () => app.workspace.trigger(event, [id]));
|
||||
|
||||
if (state.hoisted[state.hoisted.length - 1] === id)
|
||||
zeroArgMenuItem("Unhoist", "arrow-down", "loom:unhoist");
|
||||
|
|
@ -60,12 +61,46 @@ const showNodeMenu = ({ app, event, state, id, node, deletable }: MenuContext) =
|
|||
|
||||
if (deletable) {
|
||||
menu.addSeparator();
|
||||
selfArgMenuItem("Delete", "trash", "loom:delete");
|
||||
selfListArgMenuItem("Delete", "trash", "loom:delete");
|
||||
}
|
||||
|
||||
menu.showAtMouseEvent(event);
|
||||
}
|
||||
|
||||
const renderNodeButtons = (
|
||||
container: HTMLElement,
|
||||
{ app, state, id, node, deletable }: NodeContext
|
||||
) => {
|
||||
const button = (label: string, icon: string, callback: (event: MouseEvent) => void) => {
|
||||
const button_ = container.createDiv({
|
||||
cls: "loom__node-button",
|
||||
attr: { "aria-label": label },
|
||||
});
|
||||
setIcon(button_, icon);
|
||||
button_.addEventListener("click", event => { event.stopPropagation(); callback(event); });
|
||||
};
|
||||
|
||||
button("Show menu", "menu", (event) => showNodeMenu(event, { app, state, id, node, deletable }));
|
||||
|
||||
if (state.hoisted[state.hoisted.length - 1] === id)
|
||||
button("Unhoist", "arrow-down", () => app.workspace.trigger("loom:unhoist"));
|
||||
else button("Hoist", "arrow-up", () => app.workspace.trigger("loom:hoist", id));
|
||||
|
||||
if (node.bookmarked)
|
||||
button(
|
||||
"Remove bookmark",
|
||||
"bookmark-minus",
|
||||
() => app.workspace.trigger("loom:toggle-bookmark", id)
|
||||
);
|
||||
else
|
||||
button("Bookmark", "bookmark", () =>
|
||||
app.workspace.trigger("loom:toggle-bookmark", id)
|
||||
);
|
||||
|
||||
if (deletable)
|
||||
button("Delete", "trash", () => app.workspace.trigger("loom:delete", [id]));
|
||||
};
|
||||
|
||||
export class LoomView extends ItemView {
|
||||
getNoteState: () => NoteState | null;
|
||||
getSettings: () => LoomSettings;
|
||||
|
|
@ -403,10 +438,12 @@ export class LoomView extends ItemView {
|
|||
const rootNodes = Object.entries(state.nodes)
|
||||
.filter(([, node]) => node.parentId === null)
|
||||
const deletable = rootNodes.length !== 1 || rootNodes[0][0] !== id;
|
||||
|
||||
const nodeContext: NodeContext = { app: this.app, state, id, node, deletable };
|
||||
|
||||
nodeContainer.addEventListener("contextmenu", (event) => {
|
||||
event.preventDefault();
|
||||
showNodeMenu({ app: this.app, event, state, id, node, deletable });
|
||||
showNodeMenu(event, nodeContext);
|
||||
});
|
||||
|
||||
// add buttons on hover
|
||||
|
|
@ -415,34 +452,7 @@ export class LoomView extends ItemView {
|
|||
cls: "loom__node-buttons"
|
||||
});
|
||||
|
||||
const button = (label: string, icon: string, callback: (event: MouseEvent) => void) => {
|
||||
const button_ = nodeButtonsContainer.createDiv({
|
||||
cls: "loom__node-button",
|
||||
attr: { "aria-label": label },
|
||||
});
|
||||
setIcon(button_, icon);
|
||||
button_.addEventListener("click", callback);
|
||||
};
|
||||
|
||||
button("Show menu", "menu", (event) => showNodeMenu({ app: this.app, event, state, id, node, deletable }));
|
||||
|
||||
if (state.hoisted[state.hoisted.length - 1] === id)
|
||||
button("Unhoist", "arrow-down", () => this.app.workspace.trigger("loom:unhoist"));
|
||||
else button("Hoist", "arrow-up", () => this.app.workspace.trigger("loom:hoist", id));
|
||||
|
||||
if (node.bookmarked)
|
||||
button(
|
||||
"Remove bookmark",
|
||||
"bookmark-minus",
|
||||
() => this.app.workspace.trigger("loom:toggle-bookmark", id)
|
||||
);
|
||||
else
|
||||
button("Bookmark", "bookmark", () =>
|
||||
this.app.workspace.trigger("loom:toggle-bookmark", id)
|
||||
);
|
||||
|
||||
if (deletable)
|
||||
button("Delete", "trash", () => this.app.workspace.trigger("loom:delete", id));
|
||||
renderNodeButtons(nodeButtonsContainer, nodeContext);
|
||||
|
||||
// indicate if loom is currently generating children for this node
|
||||
|
||||
|
|
@ -554,9 +564,17 @@ export class LoomSiblingsView extends ItemView {
|
|||
const rootNodes = Object.entries(state.nodes)
|
||||
.filter(([, node]) => node.parentId === null)
|
||||
const deletable = rootNodes.length !== 1 || rootNodes[0][0] !== id;
|
||||
|
||||
const nodeContext: NodeContext = { app: this.app, state, id, node, deletable };
|
||||
|
||||
const nodeButtonsContainer = nodeContainer.createDiv({
|
||||
cls: "loom__sibling-buttons"
|
||||
});
|
||||
renderNodeButtons(nodeButtonsContainer, nodeContext);
|
||||
|
||||
nodeContainer.addEventListener("contextmenu", (event) => {
|
||||
event.preventDefault();
|
||||
showNodeMenu({ app: this.app, event, state, id, node, deletable });
|
||||
showNodeMenu(event, nodeContext);
|
||||
});
|
||||
|
||||
if (parseInt(i) !== siblings.length - 1)
|
||||
|
|
|
|||
Loading…
Reference in a new issue