Skip to content

Commit

Permalink
small improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmicoptima committed Jul 25, 2023
1 parent 3f4e4f6 commit 06cbff8
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 51 deletions.
29 changes: 14 additions & 15 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
MakePromptFromPassagesModal,
} from './views';
import {
PROVIDERS,
Provider,
LoomSettings,
SearchResultState,
Expand Down Expand Up @@ -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" }],
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down Expand Up @@ -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);
})
)
);
Expand All @@ -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);
})
)
);
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "obsidian-loom",
"version": "1.16.1",
"version": "1.16.2",
"description": "Loom in Obsidian",
"main": "main.js",
"scripts": {
Expand Down
18 changes: 18 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
}
Expand Down
86 changes: 52 additions & 34 deletions views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand All @@ -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");
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 06cbff8

Please sign in to comment.