Skip to content

Commit

Permalink
Merge pull request #41 from theosanderson/context-menu
Browse files Browse the repository at this point in the history
feat: Add right-click context menu for copying sequence selections
  • Loading branch information
theosanderson authored Dec 12, 2024
2 parents 54de7c1 + 96c1d42 commit 2156a19
Show file tree
Hide file tree
Showing 7 changed files with 11,942 additions and 8,072 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.aider*
.env
gensplore-component/.yarn/install-state.gz
1 change: 1 addition & 0 deletions gensplore-component/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
3 changes: 2 additions & 1 deletion gensplore-component/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,6 @@
"last 1 firefox version",
"last 1 safari version"
]
}
},
"packageManager": "[email protected]+sha512.4e502bea682e7d8004561f916f1da2dfbe6f718024f6aa50bf8cd86f38ea3a94a7f1bf854a9ca666dd8eafcfb8d44baaa91bf5c7876e79a7aeac952c332f0e88"
}
27 changes: 27 additions & 0 deletions gensplore-component/src/components/ContextMenu.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';

const ContextMenu = ({ x, y, onClose, onCopy, onCopyRC }) => {
if (x === null || y === null) return null;

return (
<div
className="fixed bg-white shadow-lg border border-gray-200 rounded-md py-1 z-50"
style={{ left: x, top: y }}
>
<button
className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
onClick={onCopy}
>
Copy Selection
</button>
<button
className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
onClick={onCopyRC}
>
Copy as Reverse Complement
</button>
</div>
);
};

export default ContextMenu;
94 changes: 69 additions & 25 deletions gensplore-component/src/components/GensploreView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import React, {
} from "react";

import "../App.css"
import Offcanvas from './Offcanvas'; // Import the new offcanvas component
import Offcanvas from './Offcanvas';
import ContextMenu from './ContextMenu';

import Tooltip from "./Tooltip";
import { getReverseComplement, filterFeatures } from "../utils";
Expand All @@ -33,6 +34,7 @@ function GensploreView({ genbankString, searchInput, setSearchInput, showLogo })
const [ref, { width }] = useMeasure();

const [hoveredInfo, setHoveredInfo] = useState(null);
const [contextMenu, setContextMenu] = useState({ x: null, y: null });
const [genbankData, setGenbankData] = useState(null);
const [sequenceHits, setSequenceHits] = useState([]);
const [curSeqHitIndex, setCurSeqHitIndex] = useState(0);
Expand Down Expand Up @@ -115,22 +117,8 @@ function GensploreView({ genbankString, searchInput, setSearchInput, showLogo })
const handleKeyDown = (e) => {
// ctrl-C
if ((e.ctrlKey || e.metaKey) && e.keyCode === 67) {
const selStart = Math.min(whereMouseWentDown, whereMouseWentUp);
const selEnd = Math.max(whereMouseWentDown, whereMouseWentUp);
//console.log(selStart,selEnd);
let selectedText = genbankData.parsedSequence.sequence.substring(
selStart,
selEnd
);
if (selectedText) {
if (e.shiftKey) {
selectedText = getReverseComplement(selectedText);
}
console.log(selectedText);
navigator.clipboard.writeText(selectedText);
toast.success(
`Copied ${e.shiftKey ? "reverse complement" : ""} to clipboard`
);
if (whereMouseWentDown !== null && whereMouseWentUp !== null) {
copySelectedSequence(e.shiftKey);
e.preventDefault();
}
}
Expand Down Expand Up @@ -346,6 +334,51 @@ if (hit1 === -1) {
}, [genbankData]);


// Handle context menu
const handleContextMenu = (e) => {
e.preventDefault();

setContextMenu({ x: e.clientX, y: e.clientY });

};

const handleCloseContextMenu = () => {
setContextMenu({ x: null, y: null });
};

const copySelectedSequence = (asReverseComplement = false) => {
if (!whereMouseWentDown || !whereMouseWentUp) return;

const selStart = Math.min(whereMouseWentDown, whereMouseWentUp);
const selEnd = Math.max(whereMouseWentDown, whereMouseWentUp);
let selectedText = genbankData.parsedSequence.sequence.substring(selStart, selEnd);

if (asReverseComplement) {
selectedText = getReverseComplement(selectedText);
}

navigator.clipboard.writeText(selectedText);
toast.success(`Copied ${asReverseComplement ? 'reverse complement ' : ''}to clipboard`);
};

const handleCopySelection = () => {
copySelectedSequence(false);
handleCloseContextMenu();
};

const handleCopyRC = () => {
copySelectedSequence(true);
handleCloseContextMenu();
};

useEffect(() => {
document.addEventListener('click', handleCloseContextMenu);
return () => {
document.removeEventListener('click', handleCloseContextMenu);
};
}, []);



//console.log("virtualItems", virtualItems);

Expand All @@ -361,7 +394,9 @@ if (hit1 === -1) {
);
}


return (<>
<div onContextMenu={handleContextMenu}>
<Dialog
open={configModalOpen}
onClose={() => setConfigModalOpen(false)}
Expand Down Expand Up @@ -536,10 +571,18 @@ if (hit1 === -1) {
</div>
</div>

{contextMenu.x !== null && (
<ContextMenu
x={contextMenu.x}
y={contextMenu.y}
onClose={handleCloseContextMenu}
onCopy={handleCopySelection}
onCopyRC={handleCopyRC}
/>
)}

{
featureOffcanvasOpen &&
<Offcanvas isOpen={featureOffcanvasOpen} onClose={() => setFeatureOffcanvasOpen(false)}>
{featureOffcanvasOpen && (
<Offcanvas isOpen={featureOffcanvasOpen} onClose={() => setFeatureOffcanvasOpen(false)}>
<table className="min-w-full divide-y divide-gray-200">
<thead>
<tr>
Expand Down Expand Up @@ -604,10 +647,11 @@ if (hit1 === -1) {
))}
</tbody>
</table>
</Offcanvas>
</Offcanvas>
)}
</div>
</>
);
}
</>
);
}

export default GensploreView;
export default GensploreView;
8 changes: 8 additions & 0 deletions gensplore-component/src/components/SingleRow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,10 @@ const SingleRow = ({
...(isSelected ? { backgroundColor: "#ffffee" } : {}),
}}
onMouseDown={(e) => {
// if right mouse button, don't do anything
if (e.button == 2) {
return;
}
// figure out which nucleotide was clicked
const x = e.clientX - e.currentTarget.getBoundingClientRect().left;
const nucleotide =
Expand All @@ -532,6 +536,10 @@ const SingleRow = ({
e.preventDefault();
}}
onMouseUp={(e) => {
// if right mouse button, don't do anything
if (e.button == 2) {
return;
}
// figure out which nucleotide was clicked
const x = e.clientX - e.currentTarget.getBoundingClientRect().left;
const nucleotide =
Expand Down
Loading

0 comments on commit 2156a19

Please sign in to comment.