mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-06 21:49:03 +00:00
menu routing/structure + nav
This commit is contained in:
parent
a2b93cb513
commit
f7c597ebb3
@ -42,7 +42,7 @@ export const reloadTabs = () => chrome.runtime.sendMessage({ action: 'reloadTabs
|
||||
/** a notification displayed when the menu is opened for the first time */
|
||||
export const welcomeNotification = {
|
||||
id: '84e2d49b-c3dc-44b4-a154-cf589676bfa0',
|
||||
color: 'blue',
|
||||
// color: 'blue',
|
||||
icon: 'message-circle',
|
||||
message: 'Welcome! Come chat with us on Discord.',
|
||||
link: 'https://discord.gg/sFWPXtA',
|
||||
|
@ -9,8 +9,6 @@
|
||||
const _id = 'a6621988-551d-495a-97d8-3c568bca2e9e';
|
||||
import { env, storage, web, fmt, fs, registry, regexers } from '../../api/_.mjs';
|
||||
|
||||
document.querySelector('img[data-notion]').addEventListener('click', env.focusNotion);
|
||||
|
||||
import * as router from './router.js';
|
||||
|
||||
const components = {};
|
||||
|
@ -24,7 +24,8 @@ const mapColorVariables = (color) => ({
|
||||
|
||||
setup({
|
||||
preflight: {
|
||||
body: apply`px-4 py-3 bg-notion-bg font-sans`,
|
||||
html: apply`w-full h-full`,
|
||||
body: apply`w-full h-full bg-notion-bg font-sans text-foreground`,
|
||||
},
|
||||
theme: {
|
||||
fontFamily: {
|
||||
@ -91,7 +92,7 @@ document.addEventListener('visibilitychange', loadTheme);
|
||||
loadTheme();
|
||||
|
||||
const notifications = {
|
||||
$container: web.html`<div class="${tw`absolute bottom-3 right-4 w-80`}"></div>`,
|
||||
$container: web.html`<div class="${tw`absolute bottom-0 right-0 px-4 py-3 max-w-full w-96`}"></div>`,
|
||||
cache: await db.get(['notifications'], []),
|
||||
provider: [
|
||||
env.welcomeNotification,
|
||||
@ -99,7 +100,9 @@ const notifications = {
|
||||
],
|
||||
add({ icon, message, id = undefined, color = undefined, link = undefined }) {
|
||||
const style = tw`p-2 ${
|
||||
color ? `bg-${color}-tag text-${color}-tag-text` : 'bg-notion-popup text-foreground'
|
||||
color
|
||||
? `bg-${color}-tag text-${color}-tag-text border border-${color}-text hover:bg-${color}-text`
|
||||
: 'bg-notion-popup text-foreground hover:bg-interactive-hover border border-notion-divider'
|
||||
} flex items-center rounded-full mt-3 shadow-md cursor-pointer`,
|
||||
$notification = web.render(
|
||||
link
|
||||
@ -143,3 +146,57 @@ if (errors.length) {
|
||||
color: 'red',
|
||||
});
|
||||
}
|
||||
|
||||
// mod config
|
||||
|
||||
const $container = web.html`<div class="${tw`flex w-full h-full`}"></div>`,
|
||||
$nav = web.html`<nav class="${tw`px-4 py-3 flex items-center border-b border-notion-divider space-x-4`}"></nav>`,
|
||||
$main = web.html`<main class="${tw`transition px-4 py-3`}">abc</main>`,
|
||||
$footer = web.html`<footer></footer>`,
|
||||
$sidebar = web.html`<article class="${tw`h-full w-96 bg-notion-secondary border-l border-notion-divider`}"></article>`;
|
||||
|
||||
const $notion = web.html`<h1 class="${tw`flex items-center font-semibold text-xl cursor-pointer select-none mr-4`}">
|
||||
${(await fs.getText('icon/colour.svg')).replace(
|
||||
/width="\d+" height="\d+"/,
|
||||
`class="${tw`h-6 w-6 mr-3`}"`
|
||||
)}
|
||||
<a href="https://notion-enhancer.github.io/" target="_blank">notion-enhancer</a>
|
||||
</h1>`;
|
||||
$notion.children[0].addEventListener('click', env.focusNotion);
|
||||
|
||||
const navItemStyle = tw`px-3 py-2 rounded-md text-sm font-medium bg-interactive hover:bg-interactive-hover`,
|
||||
selectedNavItemStyle = tw`px-3 py-2 rounded-md text-sm font-medium ring-1 ring-notion-divider bg-notion-secondary`;
|
||||
|
||||
const $extensionsNavItem = web.html`<a href="?view=extensions" class="${navItemStyle}">extensions</a>`,
|
||||
$themesNavItem = web.html`<a href="?view=themes" class="${navItemStyle}">themes</a>`,
|
||||
$supportNavItem = web.html`<a href="https://discord.gg/sFWPXtA" class="${navItemStyle}">support</a>`;
|
||||
|
||||
web.render(
|
||||
document.body,
|
||||
web.render(
|
||||
$container,
|
||||
web.render(
|
||||
web.html`<div class="${tw`h-full flex-auto`}"></div>`,
|
||||
web.render($nav, $notion, $extensionsNavItem, $themesNavItem, $supportNavItem),
|
||||
$main,
|
||||
$footer
|
||||
),
|
||||
$sidebar
|
||||
)
|
||||
);
|
||||
|
||||
import * as router from './router.mjs';
|
||||
|
||||
router.addView('extensions', () => {
|
||||
$themesNavItem.className = navItemStyle;
|
||||
$extensionsNavItem.className = selectedNavItemStyle;
|
||||
web.empty($main);
|
||||
web.render($main, 123);
|
||||
});
|
||||
router.addView('themes', () => {
|
||||
$extensionsNavItem.className = navItemStyle;
|
||||
$themesNavItem.className = selectedNavItemStyle;
|
||||
web.empty($main);
|
||||
web.render($main, 456);
|
||||
});
|
||||
router.listen('extensions', $main);
|
||||
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* notion-enhancer core: menu
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { web } from '../../api/_.mjs';
|
||||
|
||||
export const getSearch = () =>
|
||||
new Map(
|
||||
location.search
|
||||
.slice(1)
|
||||
.split('&')
|
||||
.map((query) => query.split('='))
|
||||
);
|
||||
|
||||
let defaultView = '';
|
||||
const views = new Map(),
|
||||
filters = new Map();
|
||||
|
||||
export function setDefaultView(name) {
|
||||
defaultView = name;
|
||||
}
|
||||
export function addView(name, loader, filter = () => {}) {
|
||||
views.set(name, loader);
|
||||
filters.set(name, filter);
|
||||
}
|
||||
export function removeView(name) {
|
||||
views.delete(name);
|
||||
filters.delete(name);
|
||||
}
|
||||
|
||||
function router(event) {
|
||||
event.preventDefault();
|
||||
const anchor = event.path.find((anchor) => anchor.nodeName === 'A');
|
||||
if (location.search !== anchor.getAttribute('href')) {
|
||||
window.history.pushState(
|
||||
{ search: anchor.getAttribute('href'), hash: '' },
|
||||
'',
|
||||
anchor.href
|
||||
);
|
||||
load();
|
||||
}
|
||||
}
|
||||
function navigator(event) {
|
||||
event.preventDefault();
|
||||
const anchor = event.path.find((anchor) => anchor.nodeName === 'A'),
|
||||
hash = anchor.getAttribute('href').slice(1);
|
||||
document.getElementById(hash).scrollIntoView(true);
|
||||
document.documentElement.scrollTop = 0;
|
||||
history.replaceState({ search: location.search, hash }, null, `#${hash}`);
|
||||
}
|
||||
|
||||
export async function load(force = false) {
|
||||
const $container = document.querySelector('main'),
|
||||
search = getSearch(),
|
||||
fallbackView = () => {
|
||||
window.history.replaceState(
|
||||
{ search: `?view=${defaultView}`, hash: '' },
|
||||
null,
|
||||
`?view=${defaultView}`
|
||||
);
|
||||
return load();
|
||||
};
|
||||
if (force || !search.get('view') || document.body.dataset.view !== search.get('view')) {
|
||||
if (views.get(search.get('view'))) {
|
||||
const $body = await (views.get(search.get('view')) || (() => void 0))();
|
||||
if ($body) {
|
||||
$container.style.opacity = 0;
|
||||
await new Promise((res, rej) =>
|
||||
setTimeout(() => {
|
||||
document.body.dataset.view = search.get('view');
|
||||
$container.innerHTML = '';
|
||||
$container.append($body);
|
||||
requestAnimationFrame(() => {
|
||||
$container.style.opacity = '';
|
||||
setTimeout(res, 200);
|
||||
});
|
||||
}, 200)
|
||||
);
|
||||
} else return fallbackView();
|
||||
} else return fallbackView();
|
||||
}
|
||||
if (filters.get(search.get('view'))) filters.get(search.get('view'))(search);
|
||||
}
|
||||
window.addEventListener('popstate', (event) => {
|
||||
if (event.state) load();
|
||||
document.getElementById(location.hash.slice(1))?.scrollIntoView(true);
|
||||
document.documentElement.scrollTop = 0;
|
||||
});
|
||||
web.addDocumentObserver((mutation) => {
|
||||
mutation.target.querySelectorAll('a[href^="?"]').forEach((a) => {
|
||||
a.removeEventListener('click', router);
|
||||
a.addEventListener('click', router);
|
||||
});
|
||||
mutation.target.querySelectorAll('a[href^="#"]').forEach((a) => {
|
||||
a.removeEventListener('click', navigator);
|
||||
a.addEventListener('click', navigator);
|
||||
});
|
||||
});
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* notion-enhancer core: menu
|
||||
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { web } from '../../api/_.mjs';
|
||||
|
||||
export const queryParams = () => new URLSearchParams(window.location.search);
|
||||
|
||||
let _defaultView = '',
|
||||
$viewRoot;
|
||||
const _views = new Map();
|
||||
|
||||
export function addView(name, loadFunc) {
|
||||
_views.set(name, loadFunc);
|
||||
}
|
||||
export function removeView(name) {
|
||||
_views.delete(name);
|
||||
}
|
||||
|
||||
function router(event) {
|
||||
event.preventDefault();
|
||||
const anchor = event.path.find((anchor) => anchor.nodeName === 'A');
|
||||
if (location.search !== anchor.getAttribute('href')) {
|
||||
window.history.pushState(null, null, anchor.href);
|
||||
listen();
|
||||
}
|
||||
}
|
||||
function navigator(event) {
|
||||
event.preventDefault();
|
||||
const anchor = event.path.find((anchor) => anchor.nodeName === 'A'),
|
||||
hash = anchor.getAttribute('href').slice(1);
|
||||
document.getElementById(hash).scrollIntoView(true);
|
||||
document.documentElement.scrollTop = 0;
|
||||
history.replaceState({ search: location.search, hash }, null, `#${hash}`);
|
||||
}
|
||||
|
||||
export async function listen(defaultView = null, $elem = null) {
|
||||
if (defaultView) _defaultView = defaultView;
|
||||
if ($elem) $viewRoot = $elem;
|
||||
if (!$viewRoot) throw new Error('no view root set.');
|
||||
if (!_defaultView) throw new Error('no view root set.');
|
||||
|
||||
const query = queryParams(),
|
||||
fallbackView = () => {
|
||||
window.history.replaceState(null, null, `?view=${_defaultView}`);
|
||||
return listen();
|
||||
};
|
||||
if (!query.get('view') || document.body.dataset.view !== query.get('view')) {
|
||||
if (_views.get(query.get('view'))) {
|
||||
$viewRoot.style.opacity = 0;
|
||||
const loadFunc = _views.get(query.get('view'))();
|
||||
setTimeout(async () => {
|
||||
await loadFunc;
|
||||
requestAnimationFrame(() => {
|
||||
$viewRoot.style.opacity = '';
|
||||
});
|
||||
}, 200);
|
||||
} else return fallbackView();
|
||||
} else return fallbackView();
|
||||
}
|
||||
|
||||
window.addEventListener('popstate', (event) => {
|
||||
if (event.state) listen();
|
||||
document.getElementById(location.hash.slice(1))?.scrollIntoView(true);
|
||||
document.documentElement.scrollTop = 0;
|
||||
});
|
||||
web.addDocumentObserver((mutation) => {
|
||||
mutation.target.querySelectorAll('a[href^="?"]').forEach((a) => {
|
||||
a.removeEventListener('click', router);
|
||||
a.addEventListener('click', router);
|
||||
});
|
||||
mutation.target.querySelectorAll('a[href^="#"]').forEach((a) => {
|
||||
a.removeEventListener('click', navigator);
|
||||
a.addEventListener('click', navigator);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user