mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-09 15:09:02 +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 */
|
/** a notification displayed when the menu is opened for the first time */
|
||||||
export const welcomeNotification = {
|
export const welcomeNotification = {
|
||||||
id: '84e2d49b-c3dc-44b4-a154-cf589676bfa0',
|
id: '84e2d49b-c3dc-44b4-a154-cf589676bfa0',
|
||||||
color: 'blue',
|
// color: 'blue',
|
||||||
icon: 'message-circle',
|
icon: 'message-circle',
|
||||||
message: 'Welcome! Come chat with us on Discord.',
|
message: 'Welcome! Come chat with us on Discord.',
|
||||||
link: 'https://discord.gg/sFWPXtA',
|
link: 'https://discord.gg/sFWPXtA',
|
||||||
|
@ -9,8 +9,6 @@
|
|||||||
const _id = 'a6621988-551d-495a-97d8-3c568bca2e9e';
|
const _id = 'a6621988-551d-495a-97d8-3c568bca2e9e';
|
||||||
import { env, storage, web, fmt, fs, registry, regexers } from '../../api/_.mjs';
|
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';
|
import * as router from './router.js';
|
||||||
|
|
||||||
const components = {};
|
const components = {};
|
||||||
|
@ -24,7 +24,8 @@ const mapColorVariables = (color) => ({
|
|||||||
|
|
||||||
setup({
|
setup({
|
||||||
preflight: {
|
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: {
|
theme: {
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
@ -91,7 +92,7 @@ document.addEventListener('visibilitychange', loadTheme);
|
|||||||
loadTheme();
|
loadTheme();
|
||||||
|
|
||||||
const notifications = {
|
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'], []),
|
cache: await db.get(['notifications'], []),
|
||||||
provider: [
|
provider: [
|
||||||
env.welcomeNotification,
|
env.welcomeNotification,
|
||||||
@ -99,7 +100,9 @@ const notifications = {
|
|||||||
],
|
],
|
||||||
add({ icon, message, id = undefined, color = undefined, link = undefined }) {
|
add({ icon, message, id = undefined, color = undefined, link = undefined }) {
|
||||||
const style = tw`p-2 ${
|
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`,
|
} flex items-center rounded-full mt-3 shadow-md cursor-pointer`,
|
||||||
$notification = web.render(
|
$notification = web.render(
|
||||||
link
|
link
|
||||||
@ -143,3 +146,57 @@ if (errors.length) {
|
|||||||
color: 'red',
|
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