Skip to content

Instantly share code, notes, and snippets.

@thesved
Created September 17, 2020 15:44
Show Gist options
  • Save thesved/fb3381d52de284659ed714ce9b14ddcb to your computer and use it in GitHub Desktop.
Save thesved/fb3381d52de284659ed714ce9b14ddcb to your computer and use it in GitHub Desktop.
Automatically open Roam's left menu based on mouse position
/*
* Viktor's Roam Mobile Menu Mouse Opener
* version: 0.1
* author: @ViktorTabori
*
* How to install it:
* - go to page [[roam/js]]
* - create a node with: { {[[roam/js]]}}
* - create a clode block under it, and change its type from clojure to javascript
* - allow the running of the javascript on the {{[[roam/js]]}} node
*/
if (window.ViktorMouseMenuOpener) window.ViktorMouseMenuOpener.stop();
window.ViktorMouseMenuOpener = /*window.ViktorMouseMenuOpener ||*/ (function(){
// max wait for second tap in ms
var added = false,
triggerWaitTime = 200, // wait millsiseconds to auto open or auto close
tolerance = 10, // pixels which is tolerated to trigger open/close
autoOpen = true, // auto opens left bar
autoClose = true, // auto closes left bar
openSelector = '.roam-topbar .bp3-icon-menu, .roam-topbar .bp3-icon-menu-open',
closeSelector = '.roam-sidebar-content .bp3-icon-menu, .roam-sidebar-content .bp3-icon-menu-closed',
status = {wait:false, x:0},
sidebar = document.getElementsByClassName('roam-sidebar-container')[0],
sidebarWidth = sidebar.getBoundingClientRect().width;
// start the plugin
setTimeout(start, 1000);
// return public attributes
return {
added: added,
start: start,
stop: stop,
};
// install and run the plugin
function start() {
if (added) return;
added = true;
document.addEventListener('mousemove', process, {passive: false, capture: true});
console.log('** mouse menu opener installed **');
}
// stop the plugin
function stop() {
if (!added) return;
added = false;
document.removeEventListener('mousemove', process, {passive: false, capture: true});
console.log('** mouse menu opener STOPPED **');
}
// process touch and click events
function process(e) {
status.x = e.x;
if (status.wait) return;
// auto open or close
var isOpen = sidebar.getBoundingClientRect().x >= 0;
var clickItem;
var shouldClick;
if (autoOpen && !isOpen) {
clickItem = document.querySelector(openSelector);
shouldClick = (pos)=>(pos<=tolerance);
}
else if (autoClose && isOpen) {
clickItem = document.querySelector(closeSelector);
shouldClick = (pos)=>(pos>sidebarWidth+tolerance);
}
if (!clickItem || !shouldClick(status.x)) return;
status.wait = true;
setTimeout(function(){
status.wait = false;
if (shouldClick(status.x)) {
for (var i=0; i<2; i++) { // sometimes the menu won't open for the first click
setTimeout(()=>{
'mouseover mousedown mouseup click'.split(' ').forEach(type=>{
clickItem.dispatchEvent(new MouseEvent(type, {view: window, bubbles: true, cancelable: true, buttons: 1}));
});
}, i==0?0:50);
}
}
}, triggerWaitTime);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment