Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: improve lock/unlock behavior #319

Merged
merged 1 commit into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions public/common/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ import { createExpandableSpan } from "../components/expandable/expandable";

window.activeLegendElement = null;

export function vec2Distance(location, pos) {
return Math.sqrt(
Math.pow(location.x - pos.x, 2) + Math.pow(location.y - pos.y, 2)
);
}

export function getVCSRepositoryPathAndPlatform(url) {
if (!url) {
return null;
Expand Down
73 changes: 49 additions & 24 deletions public/components/locker/locker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ export class Locker {
this.dom = document.getElementById("network-locker");
this.networkView = document.getElementById("network--view");
this.nsn = nsn;
this.unlock();
this.locked = false;
this.unlockAuthorized = true;
this.renderUnlock();

document.addEventListener("keydown", (event) => {
const hotkeys = JSON.parse(localStorage.getItem("hotkeys"));
Expand All @@ -15,33 +17,62 @@ export class Locker {
}
}
});
this.dom.addEventListener("click", () => {
this.auto();
});
this.dom.addEventListener("click", () => this.auto());
this.nsn.network.on("highlight_done", this.highlightDone.bind(this));
}

this.nsn.network.on("highlight_done", () => {
this.unlock();
});
highlightDone() {
if (!this.unlockAuthorized) {
return;
}

console.log("[LOCKER] highlight done emitted");
this.unlockAuthorized = false;
setTimeout(() => {
this.unlockAuthorized = true;
}, 1);

this.unlock();
}

auto() {
const wasLocked = this.locked === true;
// Refuse locking if there is no multi selections
if (this.nsn.lastHighlightedIds === null) {
return;
}

this[this.locked ? "unlock" : "lock"]();
}

if (wasLocked) {
if (window.networkNav.currentNodeParams === null) {
this.nsn.resetHighlight();
}
else {
this.nsn.neighbourHighlight(window.networkNav.currentNodeParams);
}
lock() {
if (!this.locked) {
console.log("[LOCKER] lock triggered");
this.renderLock();
this.locked = true;
}
}

lock(force = false) {
if (window.networkNav.currentNodeParams !== null && !force) {
unlock() {
if (!this.locked) {
return;
}

console.log("[LOCKER] unlock triggered");
this.renderUnlock();
this.locked = false;

// No node selected, so we reset highlight
const selectedNode = window.networkNav.currentNodeParams;
if (selectedNode === null) {
this.nsn.resetHighlight();
}
else if (this.nsn.lastHighlightedIds !== null) {
this.nsn.lastHighlightedIds = null;
this.nsn.neighbourHighlight(selectedNode);
}
}

renderLock() {
this.dom.classList.add("enabled");
this.dom.querySelector("p").textContent = "LOCKED";
this.networkView.classList.add("locked");
Expand All @@ -50,12 +81,9 @@ export class Locker {
iconElement.classList.remove("icon-lock-open");
iconElement.classList.add("icon-lock");
iconElement.classList.add("enabled");

this.nsn.lock();
this.locked = true;
}

unlock() {
renderUnlock() {
this.dom.classList.remove("enabled");
this.dom.querySelector("p").textContent = "UNLOCKED";
this.networkView.classList.remove("locked");
Expand All @@ -64,8 +92,5 @@ export class Locker {
iconElement.classList.remove("icon-lock");
iconElement.classList.remove("enabled");
iconElement.classList.add("icon-lock-open");

this.nsn.unlock();
this.locked = false;
}
}
24 changes: 20 additions & 4 deletions public/components/searchbar/searchbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import semver from "semver";
import sizeSatisfies from "@nodesecure/size-satisfies";

// Import Internal Dependencies
import { createDOMElement } from "../../common/utils.js";
import { createDOMElement, vec2Distance } from "../../common/utils.js";

// CONSTANTS
const kFiltersName = new Set(["package", "version", "flag", "license", "author", "ext", "builtin", "size"]);
Expand Down Expand Up @@ -408,12 +408,28 @@ export class SearchBar {
window.navigation.setNavByName("network--view");
this.delayOpenSearchBar = false;

if (window.locker.locked) {
this.network.resetHighlight();
}
this.network.highlightMultipleNodes(nodeIds);
window.locker.lock();

const currentSelectedNode = window.networkNav.currentNodeParams;
const moveTo = !currentSelectedNode || !nodeIds.includes(currentSelectedNode.nodes[0]);
if (moveTo) {
const origin = this.network.network.getViewPosition();
const closestNode = nodeIds
.map((id) => {
return { id, pos: this.network.network.getPosition(id) };
})
.reduce(
(a, b) => (vec2Distance(origin, a.pos) < vec2Distance(origin, b.pos) ? a : b)
);

const scale = nodeIds.length > 3 ? 0.25 : 0.35;
this.network.network.focus(closestNode.id, {
animation: true,
scale
});
}

this.close();

setTimeout(() => {
Expand Down
26 changes: 16 additions & 10 deletions public/components/views/home/maintainers/maintainers.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,27 @@ export class PopupMaintainer {
globeElement.addEventListener("click", () => {
const nodeIds = [...this.nsn.findNodeIds(new Set(packagesList))];

this.nsn.resetHighlight();
this.nsn.highlightMultipleNodes(nodeIds);
if (!window.locker.locked) {
window.locker.lock(true);
}

window.locker.lock();
window.popup.close();
window.navigation.setNavByName("network--view");

const moveTo = window.networkNav.currentNodeParams === null ||
!nodeIds.includes(window.networkNav.currentNodeParams.nodes[0]);
const currentSelectedNode = window.networkNav.currentNodeParams;
const moveTo = currentSelectedNode === null || !nodeIds.includes(currentSelectedNode.nodes[0]);
if (moveTo) {
this.nsn.network.moveTo({
position: this.nsn.network.getPosition(nodeIds[0]),
animation: true
const origin = this.nsn.network.getViewPosition();
const closestNode = nodeIds
.map((id) => {
return { id, pos: this.nsn.network.getPosition(id) };
})
.reduce(
(a, b) => (utils.vec2Distance(origin, a.pos) < utils.vec2Distance(origin, b.pos) ? a : b)
);

const scale = nodeIds.length > 3 ? 0.25 : 0.35;
this.nsn.network.focus(closestNode.id, {
animation: true,
scale
});
}
});
Expand Down
91 changes: 36 additions & 55 deletions workspaces/vis-network/src/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ export default class NodeSecureNetwork {
this.highlightEnabled = false;
this.isLoaded = false;

this.locked = false;
this.lastHighlightedIds = null;
const { nodes, edges } = secureDataSet.build();

Expand Down Expand Up @@ -107,24 +106,6 @@ export default class NodeSecureNetwork {
this.network.stabilize(500);
}

lock() {
if (this.locked) {
return;
}

this.locked = true;
this.network.emit("lock", this.locked);
}

unlock() {
if (!this.locked) {
return;
}

this.locked = false;
this.network.emit("lock", this.locked);
}

/**
* @param {!Set<string>} packages
* @returns {IterableIterator<number>}
Expand Down Expand Up @@ -214,8 +195,8 @@ export default class NodeSecureNetwork {
}

highlightMultipleNodes(nodeIds) {
if (this.locked) {
return;
if (this.lastHighlightedIds !== null) {
this.resetHighlight();
}
this.network.startSimulation();

Expand Down Expand Up @@ -266,6 +247,29 @@ export default class NodeSecureNetwork {
this.network.stopSimulation();
}

resetHighlight() {
const allNodes = this.nodes.get();
const allEdges = this.edges.get();

// reset all edge labels - even if user clicks on empty space
for (let id = 0; id < allEdges.length; id++) {
Object.assign(allEdges[id], CONSTANTS.LABELS.NONE);
}

this.highlightEnabled = false;
for (const node of allNodes) {
const { id, hasWarnings } = this.linker.get(Number(node.id));

Object.assign(node, utils.getNodeColor(id, hasWarnings, this.theme));
}

this.lastHighlightedIds = null;
this.network.startSimulation();
this.nodes.update(allNodes);
this.edges.update(allEdges);
this.network.stopSimulation();
}

/**
* Search for neighbours nodes of a given node
*
Expand All @@ -287,6 +291,10 @@ export default class NodeSecureNetwork {
}

lockedNeighbourHighlight(params) {
if (this.lastHighlightedIds === null) {
return false;
}

if (!params || params.nodes.length === 0) {
return true;
}
Expand All @@ -296,7 +304,6 @@ export default class NodeSecureNetwork {
return false;
}

this.network.startSimulation();
const allNodes = this.nodes.get({ returnType: "Object" });
for (const node of Object.values(allNodes)) {
if (!this.lastHighlightedIds.has(node.id)) {
Expand Down Expand Up @@ -328,47 +335,25 @@ export default class NodeSecureNetwork {
}


this.network.startSimulation();
this.nodes.update(Object.values(allNodes));
this.network.focus(selectedNode, {
animation: true,
scale: 0.35,
offset: { x: 250, y: 0 }
offset: { x: 150, y: 0 }
});
this.network.stopSimulation();

return true;
}

resetHighlight() {
this.network.startSimulation();

const allNodes = this.nodes.get();
const allEdges = this.edges.get();

// reset all edge labels - even if user clicks on empty space
for (let id = 0; id < allEdges.length; id++) {
Object.assign(allEdges[id], CONSTANTS.LABELS.NONE);
}

this.highlightEnabled = false;
for (const node of allNodes) {
const { id, hasWarnings } = this.linker.get(Number(node.id));

Object.assign(node, utils.getNodeColor(id, hasWarnings, this.theme));
}

this.locked = false;
this.lastHighlightedIds = null;

this.nodes.update(allNodes);
this.edges.update(allEdges);
this.network.stopSimulation();
}

neighbourHighlight(params) {
if (this.lastHighlightedIds !== null && this.locked && this.lockedNeighbourHighlight(params)) {
if (this.lockedNeighbourHighlight(params)) {
console.log("[NETWORK] locked, stop neighbour highlight");

return;
}
console.log("[NETWORK] neighbour highlight start");

const allNodes = this.nodes.get({ returnType: "Object" });
const allEdges = this.edges.get();
Expand Down Expand Up @@ -425,11 +410,10 @@ export default class NodeSecureNetwork {
}
}

// offset set to 250 to compensate for the package info slide in on the left of screen
this.network.focus(selectedNode, {
animation: true,
scale: 0.35,
offset: { x: 250, y: 0 }
offset: { x: 150, y: 0 }
});
}
else if (this.highlightEnabled) {
Expand All @@ -441,10 +425,7 @@ export default class NodeSecureNetwork {
}
}

// transform the object into an array
this.lastHighlightedIds = null;
this.locked = false;

this.nodes.update(Object.values(allNodes));
this.edges.update(allEdges);
this.network.stopSimulation();
Expand Down
Loading