notion-enhancer/repo/tabs/rendererIndex.cjs

140 lines
4.9 KiB
JavaScript

/**
* notion-enhancer: tabs
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
* (https://notion-enhancer.github.io/) under the MIT license
*/
'use strict';
module.exports = async function (api, db, __exports, __eval) {
const url = require('url'),
electron = require('electron'),
electronWindow = electron.remote.getCurrentWindow(),
{ components, web } = api;
window['__start'] = async () => {
// display:none; to prevent content flash while css loads
document.body.style.display = 'none';
const tabCache = new Map(),
Tab = await require('./tab.cjs')(api, db, tabCache);
document.body.dataset.tabLabels = await db.get(['label_type']);
document.body.dataset.tabStyle = await db.get(['layout_style']);
const $header = web.html`<header></header>`,
$tabs = web.html`<div id="tabs"></div>`,
$newTab = web.html`<div class="new-tab">${await components.feather('plus')}</div>`,
$root = document.querySelector('#root'),
$windowActions = web.html`<div id="window-actions"></div>`;
document.body.prepend(web.render($header, $tabs, $newTab, $windowActions));
$newTab.addEventListener('click', () => new Tab($tabs, $root));
electron.ipcRenderer.on('notion-enhancer:close-tab', (event, id) => {
const tab = tabCache.get(id);
if (tab) tab.close();
});
electron.ipcRenderer.on(
'notion-enhancer:open-tab',
(event, opts) => new Tab($tabs, $root, opts)
);
const rememberLastOpen = await db.get(['remember_last_open']),
openTabs = await db.get(['last_open_tabs_cache']);
if (rememberLastOpen && openTabs && Array.isArray(openTabs)) {
for (const tab of openTabs) {
new Tab($tabs, $root, { ...tab, cancelAnimation: true });
}
} else {
new Tab($tabs, $root, {
notionUrl: url.parse(window.location.href, true).query.path,
cancelAnimation: true,
});
}
window.addEventListener('beforeunload', () => {
const openTabs = [...$tabs.children]
.filter(($tab) => tabCache.get($tab.id))
.map(($tab) => {
const tab = tabCache.get($tab.id);
return {
notionUrl: tab.$notion.src,
icon: tab.icon,
title: tab.title,
};
});
db.set(['last_open_tabs_cache'], openTabs);
});
let $draggedTab;
const $dragIndicator = web.html`<span class="drag-indicator"></span>`,
getDragTarget = ($el) => {
while (!$el.matches('.tab, header, body')) $el = $el.parentElement;
if ($el.matches('header')) $el = $el.firstElementChild;
return $el.matches('#tabs, .tab') ? $el : undefined;
},
resetDraggedTabs = () => {
if ($draggedTab) {
$dragIndicator.remove();
$draggedTab.style.opacity = '';
$draggedTab = undefined;
}
};
$header.addEventListener('dragstart', (event) => {
$draggedTab = getDragTarget(event.target);
$draggedTab.style.opacity = 0.5;
const tab = tabCache.get($draggedTab.id);
event.dataTransfer.setData(
'text',
JSON.stringify({
window: electronWindow.webContents.id,
tab: $draggedTab.id,
icon: tab.$tabIcon.innerText || tab.$tabIcon.style.background,
title: tab.$tabTitle.innerText,
url: tab.$notion.src,
})
);
});
$header.addEventListener('dragover', (event) => {
const $target = getDragTarget(event.target);
if ($target) {
if ($target.matches('#tabs')) {
$target.after($dragIndicator);
} else if ($target.matches('#tabs > :first-child')) {
$tabs.before($dragIndicator);
} else $target.before($dragIndicator);
event.preventDefault();
}
});
document.addEventListener('drop', (event) => {
const eventData = JSON.parse(event.dataTransfer.getData('text')),
$target = getDragTarget(event.target) || $tabs,
sameWindow = eventData.window === electronWindow.webContents.id,
tabMovement =
!sameWindow ||
($target &&
$target !== $draggedTab &&
$target !== $draggedTab.nextElementSibling &&
($target.matches('#tabs') ? $target.lastElementChild !== $draggedTab : true));
if (!sameWindow) {
electron.ipcRenderer.send('notion-enhancer:close-tab', {
window: eventData.window,
id: eventData.tab,
});
const transferred = new Tab($tabs, $root, {
notionUrl: eventData.url,
cancelAnimation: true,
icon: eventData.icon,
title: eventData.title,
});
$draggedTab = transferred.$tab;
}
if (tabMovement) {
if ($target.matches('#tabs')) {
$target.append($draggedTab);
} else $target.before($draggedTab);
}
resetDraggedTabs();
});
$header.addEventListener('dragend', (event) => resetDraggedTabs());
};
};