From 775d8412d08c7689aedfe5a8bbadfad924f42628 Mon Sep 17 00:00:00 2001 From: dragonwocky Date: Thu, 30 Sep 2021 23:09:22 +1000 Subject: [PATCH] added profile switcher + split up menu js --- extension/CHANGELOG.md | 3 +- extension/api/registry.mjs | 14 +- extension/api/storage.mjs | 14 +- .../components.mjs | 237 +++++++ .../menu.js | 433 ------------- .../menu.mjs | 582 ++++++------------ .../notifications.mjs | 88 +++ .../router.mjs | 3 +- .../styles.mjs | 24 +- .../theme.css | 8 +- .../variables.css | 6 +- 11 files changed, 556 insertions(+), 856 deletions(-) create mode 100644 extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/components.mjs delete mode 100644 extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.js create mode 100644 extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/notifications.mjs diff --git a/extension/CHANGELOG.md b/extension/CHANGELOG.md index 0a676cf..14fb0c9 100644 --- a/extension/CHANGELOG.md +++ b/extension/CHANGELOG.md @@ -9,10 +9,11 @@ a complete rework of the enhancer including a port to the browser as a chrome ex - new: notifications sourced from an online endpoint for sending global user alerts. - new: simplify user installs by depending on the chrome web store and [notion-repackaged](https://github.com/notion-enhancer/notion-repackaged). - new: separate menu profiles for mod configurations. +- new: a hotkey option type that allows typing in/pressing a hotkey to enter it, instead of typing. - improved: split the core mod into separate mods for specific features. - improved: theming variables that are more specific, less laggy, and less complicated. - improved: merged bracketed-links into tweaks. -- improved: a redesigned menu with separate categories for mods and a sidebar for configuring options. +- improved: a redesigned menu with nicer ui, separate categories for mods and a sidebar for configuration. - removed: integrated scrollbar tweak (notion now includes by default). - removed: js insert. css insert moved to tweaks mod. - removed: majority of layout and font size variables - better to leave former to notion and use `ctrl +` for latter. diff --git a/extension/api/registry.mjs b/extension/api/registry.mjs index d79a694..a0dd206 100644 --- a/extension/api/registry.mjs +++ b/extension/api/registry.mjs @@ -28,11 +28,11 @@ export const core = [ /** all available configuration types */ export const optionTypes = ['toggle', 'select', 'text', 'number', 'color', 'file', 'hotkey']; +/** the name of the active configuration profile */ +export const profileName = await storage.get(['currentprofile'], 'default'); + /** the root database for the current profile */ -export const profile = storage.db([ - 'profiles', - await storage.get(['currentprofile'], 'default'), -]); +export const profileDB = storage.db(['profiles', profileName]); /** * internally used to validate mod.json files and provide helpful errors @@ -282,7 +282,7 @@ export const enabled = async (id) => { const mod = await get(id); if (!mod.environments.includes(env.name)) return false; if (core.includes(id)) return true; - return await profile.get(['_mods', id], false); + return await profileDB.get(['_mods', id], false); }; /** @@ -322,8 +322,8 @@ export const db = async (id) => { // profiles -> profile -> mod -> option fallback = (await optionDefault(id, path[1])) ?? fallback; } - return profile.get(path, fallback); + return profileDB.get(path, fallback); }, - profile.set + profileDB.set ); }; diff --git a/extension/api/storage.mjs b/extension/api/storage.mjs index 848646b..91674f2 100644 --- a/extension/api/storage.mjs +++ b/extension/api/storage.mjs @@ -22,17 +22,16 @@ const _queue = [], */ export const get = (path, fallback = undefined) => { if (!path.length) return fallback; - const namespace = path.shift(); return new Promise((res, rej) => chrome.storage.local.get(async (values) => { - let value = values[namespace]; - do { + let value = values; + while (path.length) { if (value === undefined) { value = fallback; break; } value = value[path.shift()]; - } while (path.length); + } res(value ?? fallback); }) ); @@ -53,10 +52,9 @@ export const set = (path, value) => { _queue.shift(); } const pathClone = [...path], - namespace = path.shift(); + namespace = path[0]; chrome.storage.local.get(async (values) => { - const update = values[namespace] ?? {}; - let pointer = update, + let pointer = values, old; while (path.length) { const key = path.shift(); @@ -68,7 +66,7 @@ export const set = (path, value) => { pointer[key] = pointer[key] ?? {}; pointer = pointer[key]; } - chrome.storage.local.set({ [namespace]: update }, () => { + chrome.storage.local.set({ [namespace]: values[namespace] }, () => { _onChangeListeners.forEach((listener) => listener({ type: 'set', path: pathClone, new: value, old }) ); diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/components.mjs b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/components.mjs new file mode 100644 index 0000000..f160ea5 --- /dev/null +++ b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/components.mjs @@ -0,0 +1,237 @@ +/* + * notion-enhancer core: menu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +import { fmt, registry, web } from '../../api/_.mjs'; + +import { notifications } from './notifications.mjs'; + +export const components = { + preview: (url) => web.html``, + title: (title) => web.html`

${web.escape(title)}

`, + version: (version) => web.html`v${web.escape(version)}`, + tags: (tags) => { + if (!tags.length) return ''; + return web.render( + web.html`

`, + tags.map((tag) => `#${web.escape(tag)}`).join(' ') + ); + }, + description: (description) => web.html`

+ ${fmt.md.renderInline(description)} +

`, + authors: (authors) => { + const author = (author) => web.html` + ${web.escape(author.name)}'s avatar ${web.escape(author.name)} + `; + return web.render(web.html`

`, ...authors.map(author)); + }, + toggle: (label, checked) => { + const $label = web.html``, + $input = web.html``, + $feature = web.html``; + $label.addEventListener('keyup', (event) => { + if (['Enter', ' '].includes(event.key)) $input.checked = !$input.checked; + }); + return web.render($label, $input, $feature); + }, +}; + +export const options = { + toggle: async (mod, opt) => { + const checked = await registry.profileDB.get([mod.id, opt.key], opt.value), + $toggle = components.toggle(opt.label, checked), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = $toggle.children[0], + $input = $toggle.children[1]; + if (opt.tooltip) { + $label.prepend($tooltip); + web.tooltip($tooltip, opt.tooltip); + } + $input.addEventListener('change', async (event) => { + await registry.profileDB.set([mod.id, opt.key], $input.checked); + notifications.onChange(); + }); + return $toggle; + }, + select: async (mod, opt) => { + const value = await registry.profileDB.get([mod.id, opt.key], opt.values[0]), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $options = opt.values.map( + (option) => web.raw`` + ), + $select = web.html``, + $icon = web.html`${web.icon('chevron-down', { class: 'input-icon' })}`; + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $select.addEventListener('change', async (event) => { + await registry.profileDB.set([mod.id, opt.key], $select.value); + notifications.onChange(); + }); + return web.render($label, $select, $icon); + }, + text: async (mod, opt) => { + const value = await registry.profileDB.get([mod.id, opt.key], opt.value), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${web.icon('type', { class: 'input-icon' })}`; + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $input.addEventListener('change', async (event) => { + await registry.profileDB.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + return web.render($label, $input, $icon); + }, + number: async (mod, opt) => { + const value = await registry.profileDB.get([mod.id, opt.key], opt.value), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${web.icon('hash', { class: 'input-icon' })}`; + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $input.addEventListener('change', async (event) => { + await registry.profileDB.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + return web.render($label, $input, $icon); + }, + color: async (mod, opt) => { + const value = await registry.profileDB.get([mod.id, opt.key], opt.value), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${web.icon('droplet', { class: 'input-icon' })}`, + paint = () => { + $input.style.background = $picker.toBackground(); + $input.style.color = $picker.isLight() ? '#000' : '#fff'; + $input.style.padding = ''; + }, + $picker = new web.jscolor($input, { + value, + format: 'rgba', + previewSize: 0, + borderRadius: 3, + borderColor: 'var(--theme--ui_divider)', + controlBorderColor: 'var(--theme--ui_divider)', + backgroundColor: 'var(--theme--bg)', + onInput: paint, + onChange: paint, + }); + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $input.addEventListener('change', async (event) => { + await registry.profileDB.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + paint(); + return web.render($label, $input, $icon); + }, + file: async (mod, opt) => { + const { filename } = (await registry.profileDB.get([mod.id, opt.key], {})) || {}, + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $pseudo = web.html`Upload file...`, + $input = web.html``, + $icon = web.html`${web.icon('file', { class: 'input-icon' })}`, + $filename = web.html`${web.escape(filename || 'none')}`, + $latest = web.render(web.html``, $filename); + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $input.addEventListener('change', (event) => { + const file = event.target.files[0], + reader = new FileReader(); + reader.onload = async (progress) => { + $filename.innerText = file.name; + await registry.profileDB.set([mod.id, opt.key], { + filename: file.name, + content: progress.currentTarget.result, + }); + notifications.onChange(); + }; + reader.readAsText(file); + }); + $latest.addEventListener('click', (event) => { + $filename.innerText = 'none'; + registry.profileDB.set([mod.id, opt.key], {}); + }); + return web.render( + web.html`
`, + web.render($label, $input, $pseudo, $icon), + $latest + ); + }, + hotkey: async (mod, opt) => { + const value = await registry.profileDB.get([mod.id, opt.key], opt.value), + $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, + $label = web.render( + web.html``, + web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) + ), + $input = web.html``, + $icon = web.html`${web.icon('command', { class: 'input-icon' })}`; + if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $input.addEventListener('keydown', async (event) => { + event.preventDefault(); + const pressed = [], + modifiers = { + metaKey: 'Meta', + ctrlKey: 'Control', + altKey: 'Alt', + shiftKey: 'Shift', + }; + for (const modifier in modifiers) { + if (event[modifier]) pressed.push(modifiers[modifier]); + } + const empty = ['Backspace', 'Delete'].includes(event.key) && !pressed.length; + if (!empty && !pressed.includes(event.key)) { + let key = event.key; + if (key === ' ') key = 'Space'; + if (key.length === 1) key = event.key.toUpperCase(); + pressed.push(key); + } + $input.value = pressed.join('+'); + await registry.profileDB.set([mod.id, opt.key], $input.value); + notifications.onChange(); + }); + return web.render($label, $input, $icon); + }, +}; diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.js b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.js deleted file mode 100644 index d717714..0000000 --- a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.js +++ /dev/null @@ -1,433 +0,0 @@ -/* - * notion-enhancer core: menu - * (c) 2021 dragonwocky (https://dragonwocky.me/) - * (https://notion-enhancer.github.io/) under the MIT license - */ - -'use strict'; - -const _id = 'a6621988-551d-495a-97d8-3c568bca2e9e'; -import { env, storage, web, fmt, fs, registry, regexers } from '../../api/_.mjs'; - -import * as router from './router.js'; - -const components = {}; -components.card = async (mod) => { - const $card = web.createElement(web.html` -
- ${ - mod.preview - ? web.html`` - : '' - } -
- -
    - ${mod.tags.map((tag) => web.html`
  • #${web.escapeHtml(tag)}
  • `).join('')} -
-

${fmt.md.renderInline(mod.description)}

- -

- - - settings & documentation - -

-
-
`); - $card.querySelector('.library--title input').addEventListener('change', async (event) => { - storage.set('_mods', mod.id, event.target.checked); - }); - return $card; -}; -components.options = { - async toggle(id, { key, label, tooltip }) { - const state = await storage.get(id, key), - opt = web.createElement(web.html` - `); - opt.addEventListener('change', (event) => storage.set(id, key, event.target.checked)); - if (tooltip) web.addTooltip(opt.querySelector('[data-tooltip]'), tooltip); - return opt; - }, - async select(id, { key, label, tooltip, values }) { - const state = await storage.get(id, key), - opt = web.createElement(web.html` - `); - opt.addEventListener('change', (event) => storage.set(id, key, event.target.value)); - if (tooltip) web.addTooltip(opt.querySelector('[data-tooltip]'), tooltip); - return opt; - }, - async text(id, { key, label, tooltip }) { - const state = await storage.get(id, key), - opt = web.createElement(web.html` - `); - opt.querySelector('textarea').addEventListener('input', (event) => { - event.target.style.removeProperty('--txt--scroll-height'); - event.target.style.setProperty( - '--txt--scroll-height', - event.target.scrollHeight + 1 + 'px' - ); - }); - opt.addEventListener('change', (event) => storage.set(id, key, event.target.value)); - if (tooltip) web.addTooltip(opt.querySelector('[data-tooltip]'), tooltip); - return opt; - }, - async number(id, { key, label, tooltip }) { - const state = await storage.get(id, key), - opt = web.createElement(web.html` - `); - opt.addEventListener('change', (event) => storage.set(id, key, event.target.value)); - if (tooltip) web.addTooltip(opt.querySelector('[data-tooltip]'), tooltip); - return opt; - }, - async color(id, { key, label, tooltip }) { - const state = await storage.get(id, key), - opt = web.createElement(web.html` - `); - const $fill = opt.querySelector('input'), - paintInput = () => { - $fill.style.background = picker.toBackground(); - $fill.style.color = picker.isLight() ? '#000' : '#fff'; - }, - picker = new fmt.JSColor($fill, { - value: state, - previewSize: 0, - borderRadius: 3, - borderColor: 'var(--theme--divider)', - controlBorderColor: 'var(--theme--divider)', - backgroundColor: 'var(--theme--page)', - onInput() { - paintInput(); - }, - onChange() { - paintInput(); - storage.set(id, key, this.toRGBAString()); - }, - }); - paintInput(); - opt.addEventListener('click', (event) => { - picker.show(); - }); - if (tooltip) web.addTooltip(opt.querySelector('[data-tooltip]'), tooltip); - return opt; - }, - async file(id, { key, label, tooltip, extensions }) { - const state = await storage.get(id, key), - opt = web.createElement(web.html` - `); - opt.addEventListener('change', (event) => { - const file = event.target.files[0], - reader = new FileReader(); - opt.querySelector('.library--file_path').innerText = file.name; - reader.onload = (progress) => { - storage.set(id, key, file.name); - storage.set(id, `_file.${key}`, progress.currentTarget.result); - }; - reader.readAsText(file); - }); - opt.querySelector('.library--file_remove').addEventListener( - 'click', - (event) => { - event.preventDefault(); - opt.querySelector('input').value = ''; - opt.querySelector('.library--file_path').innerText = 'choose file...'; - storage.set(id, key, undefined); - storage.set(id, `_file.${key}`, undefined); - }, - false - ); - opt.addEventListener('click', (event) => { - document.documentElement.scrollTop = 0; - }); - web.addTooltip( - opt.querySelector('[data-tooltip]'), - `${tooltip ? `${tooltip}\n\n` : ''}**warning:** ${ - 'browser extensions do not have true filesystem access, ' + - 'so file content is only saved on selection. re-select files to apply edits.' - }` - ); - return opt; - }, -}; - -const actionButtons = { - _reloadTriggered: false, - async reload($fragment = document) { - let $reload = $fragment.querySelector('[data-reload]'); - if (!$reload && this._reloadTriggered) { - $reload = web.createElement(web.html` - `); - $reload.addEventListener('click', env.reload); - $fragment.querySelector('.action--buttons').append($reload); - await new Promise((res, rej) => requestAnimationFrame(res)); - $reload.dataset.triggered = true; - } - }, - async clearFilters($fragment = document) { - let $clearFilters = $fragment.querySelector('[data-clear-filters]'); - const search = router.getSearch(); - if (search.get('tag') || search.has('enabled') || search.has('disabled')) { - if (!$clearFilters) { - $clearFilters = web.createElement(web.html` - - - clear filters - `); - $fragment.querySelector('.action--buttons').append($clearFilters); - await new Promise((res, rej) => requestAnimationFrame(res)); - $clearFilters.dataset.triggered = true; - } - } else if ($clearFilters) $clearFilters.remove(); - }, -}; -storage.addChangeListener(async (event) => { - actionButtons._reloadTriggered = true; - actionButtons.reload(); - router.load(); - - if (event.namespace === '_mods' && event.new === true) { - const enabledTheme = (await registry.get()).find((mod) => mod.id === event.key); - if ( - enabledTheme.tags.includes('theme') && - (await storage.get(_id, 'themes.autoresolve', true)) - ) { - for (const theme of await registry.get( - (mod) => - mod.tags.includes('theme') && - mod.id !== enabledTheme.id && - ((mod.tags.includes('dark') && enabledTheme.tags.includes('dark')) || - (mod.tags.includes('light') && enabledTheme.tags.includes('light'))) - )) { - if (document.body.dataset.view === 'library') { - const $toggle = document.getElementById(`enable--${theme.id}`); - if ($toggle.checked) $toggle.click(); - } else storage.set('_mods', theme.id, false); - } - } - } -}); - -router.addView( - 'library', - async () => { - const $fragment = web.createFragment(web.html` -

- - - themes - - - - extensions - - - - enabled - - - - disabled - -

`); - for (const mod of await registry.get( - (mod) => !mod.environments || mod.environments.includes(env.name) - )) { - $fragment.append(await components.card(mod)); - } - actionButtons.reload($fragment); - actionButtons.clearFilters($fragment); - return $fragment; - }, - async (search = router.getSearch()) => { - for (const [filter, active] of [ - ['tag=theme', search.get('tag') === 'theme'], - ['tag=extension', search.get('tag') === 'extension'], - ['enabled', search.has('enabled')], - ['disabled', search.has('disabled')], - ]) { - document - .querySelector(`.action--buttons > [href="?view=library&${filter}"]`) - .classList[active ? 'add' : 'remove']('action--active'); - } - const visible = new Set(); - for (const mod of await registry.get()) { - const isEnabled = await registry.isEnabled(mod.id), - filterConditions = - (search.has('tag') ? mod.tags.includes(search.get('tag')) : true) && - (search.has('enabled') && search.has('disabled') - ? true - : search.has('enabled') - ? isEnabled - : search.has('disabled') - ? !isEnabled - : true); - if (filterConditions) visible.add(mod.id); - } - for (const card of document.querySelectorAll('main > .library--card')) - card.style.display = 'none'; - for (const card of document.querySelectorAll('main > .library--card')) - if (visible.has(card.dataset.mod)) card.style.display = ''; - actionButtons.clearFilters(); - } -); - -router.addView( - 'mod', - async () => { - const mod = (await registry.get()).find((mod) => mod.id === router.getSearch().get('id')); - if (!mod) return false; - const $fragment = web.createFragment(web.html` -

- - - back to library - - - - view source code - -

`); - const $card = await components.card(mod); - $card.querySelector('.library--expand').remove(); - if (mod.options && mod.options.length) { - const options = web.createElement(web.html`
`); - mod.options - .filter((opt) => !opt.environments || opt.environments.includes(env.name)) - .forEach(async (opt) => - options.append(await components.options[opt.type](mod.id, opt)) - ); - $card.append(options); - } - $fragment.append( - $card, - web.createElement(web.html` -
- ${ - (await fs.isFile(`repo/${mod._dir}/README.md`)) - ? fmt.md.render(await fs.getText(`repo/${mod._dir}/README.md`)) - : '' - } -
`) - ); - fmt.Prism.highlightAllUnder($fragment); - actionButtons.reload($fragment); - return $fragment; - }, - () => { - if (document.querySelector('[data-mod]').dataset.mod !== router.getSearch().get('id')) - router.load(true); - } -); - -router.setDefaultView('library'); -router.load(); diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.mjs b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.mjs index ccf4a15..5852d73 100644 --- a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.mjs +++ b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/menu.mjs @@ -6,13 +6,12 @@ 'use strict'; -// initialisation and external interactions +import { env, fs, storage, registry, web } from '../../api/_.mjs'; +const db = await registry.db('a6621988-551d-495a-97d8-3c568bca2e9e'); -import * as api from '../../api/_.mjs'; -const { env, fmt, fs, registry, web } = api, - db = await registry.db('a6621988-551d-495a-97d8-3c568bca2e9e'); - -import { tw } from './styles.mjs'; +import './styles.mjs'; +import { notifications } from './notifications.mjs'; +import { components, options } from './components.mjs'; web.addHotkeyListener(await db.get(['hotkey']), env.focusNotion); @@ -34,406 +33,209 @@ window.addEventListener('beforeunload', (event) => { document.activeElement.blur(); }); -const notifications = { - $container: web.html`
`, - cache: await db.get(['notifications'], []), - provider: [ - env.welcomeNotification, - ...(await fs.getJSON('https://notion-enhancer.github.io/notifications.json')), - ], - add({ icon, message, id = undefined, color = undefined, link = undefined }) { - const $notification = link - ? web.html`` - : web.html``, - resolve = async () => { - if (id !== undefined) { - notifications.cache.push(id); - await db.set(['notifications'], notifications.cache); - } - $notification.remove(); - }; - $notification.addEventListener('click', resolve); - $notification.addEventListener('keyup', (event) => { - if (['Enter', ' '].includes(event.key)) resolve(); - }); - web.render( - notifications.$container, - web.render( - $notification, - web.html` - ${fmt.md.renderInline(message)} - `, - web.html`${web.icon(icon, { class: 'notification-icon' })}` - ) - ); - return $notification; - }, - _onChange: false, - onChange() { - if (this._onChange) return; - this._onChange = true; - const $notification = this.add({ - icon: 'refresh-cw', - message: 'Reload to apply changes.', - }); - $notification.addEventListener('click', env.reload); - }, -}; -web.render(document.body, notifications.$container); -for (const notification of notifications.provider) { - if ( - !notifications.cache.includes(notification.id) && - notification.version === env.version && - (!notification.environments || notification.environments.includes(env.name)) - ) { - notifications.add(notification); - } -} - -const errors = await registry.errors(); -if (errors.length) { - console.log('[notion-enhancer] registry errors:'); - console.table(errors); - notifications.add({ - icon: 'alert-circle', - message: 'Failed to load mods (check console).', - color: 'red', - }); -} - -// mod config - -const components = { - preview: (url) => web.html``, - title: (title) => web.html`

${web.escape(title)}

`, - version: (version) => web.html`v${web.escape(version)}`, - tags: (tags) => { - if (!tags.length) return ''; - return web.render( - web.html`

`, - tags.map((tag) => `#${web.escape(tag)}`).join(' ') - ); - }, - description: (description) => web.html`

- ${fmt.md.renderInline(description)} -

`, - authors: (authors) => { - const author = (author) => web.html` - ${web.escape(author.name)}'s avatar ${web.escape(author.name)} - `; - return web.render(web.html`

`, ...authors.map(author)); - }, - toggle: (label, checked) => { - const $label = web.html``, - $input = web.html``, - $feature = web.html``; - $label.addEventListener('keyup', (event) => { - if (['Enter', ' '].includes(event.key)) $input.checked = !$input.checked; - }); - return web.render($label, $input, $feature); - }, -}; - const $main = web.html`
`, $sidebar = web.html``, + $profile = web.html``, $options = web.html`
-

Select a mod to view and configure its options.

+

Select a mod to view and configure its options.

`; -const options = { - toggle: async (mod, opt) => { - const checked = await registry.profile.get([mod.id, opt.key], opt.value), - $toggle = components.toggle(opt.label, checked), - $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, - $label = $toggle.children[0], - $input = $toggle.children[1]; - if (opt.tooltip) { - $label.prepend($tooltip); - web.tooltip($tooltip, opt.tooltip); - } - $input.addEventListener('change', async (event) => { - await registry.profile.set([mod.id, opt.key], $input.checked); - notifications.onChange(); - }); - return $toggle; - }, - select: async (mod, opt) => { - const value = await registry.profile.get([mod.id, opt.key], opt.values[0]), - $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, - $label = web.render( - web.html``, - web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) +let _$profileConfig; +$profile.addEventListener('click', async (event) => { + for (const $selected of document.querySelectorAll('.mod-selected')) { + $selected.className = 'mod'; + } + if (!_$profileConfig) { + const profileNames = [ + ...new Set([ + ...Object.keys(await storage.get(['profiles'], { default: {} })), + registry.profileName, + ]), + ], + $options = profileNames.map( + (profile) => web.raw`` ), $select = web.html``, - $icon = web.html`${web.icon('chevron-down', { class: 'input-icon' })}`; - if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); + $edit = web.html``, + $save = web.html``, + $delete = web.html``, + $error = web.html`

`; $select.addEventListener('change', async (event) => { - await registry.profile.set([mod.id, opt.key], $select.value); - notifications.onChange(); + if ($select.value === '--') { + $edit.value = ''; + } else $edit.value = $select.value; }); - return web.render($label, $select, $icon); - }, - text: async (mod, opt) => { - const value = await registry.profile.get([mod.id, opt.key], opt.value), - $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, - $label = web.render( - web.html``, - web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) - ), - $input = web.html``, - $icon = web.html`${web.icon('type', { class: 'input-icon' })}`; - if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); - $input.addEventListener('change', async (event) => { - await registry.profile.set([mod.id, opt.key], $input.value); - notifications.onChange(); - }); - return web.render($label, $input, $icon); - }, - number: async (mod, opt) => { - const value = await registry.profile.get([mod.id, opt.key], opt.value), - $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, - $label = web.render( - web.html``, - web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) - ), - $input = web.html``, - $icon = web.html`${web.icon('hash', { class: 'input-icon' })}`; - if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); - $input.addEventListener('change', async (event) => { - await registry.profile.set([mod.id, opt.key], $input.value); - notifications.onChange(); - }); - return web.render($label, $input, $icon); - }, - color: async (mod, opt) => { - const value = await registry.profile.get([mod.id, opt.key], opt.value), - $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, - $label = web.render( - web.html``, - web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) - ), - $input = web.html``, - $icon = web.html`${web.icon('droplet', { class: 'input-icon' })}`, - paint = () => { - $input.style.background = $picker.toBackground(); - $input.style.color = $picker.isLight() ? '#000' : '#fff'; - $input.style.padding = ''; - }, - $picker = new web.jscolor($input, { - value, - format: 'rgba', - previewSize: 0, - borderRadius: 3, - borderColor: 'var(--theme--ui_divider)', - controlBorderColor: 'var(--theme--ui_divider)', - backgroundColor: 'var(--theme--bg)', - onInput: paint, - onChange: paint, - }); - if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); - $input.addEventListener('change', async (event) => { - await registry.profile.set([mod.id, opt.key], $input.value); - notifications.onChange(); - }); - paint(); - return web.render($label, $input, $icon); - }, - file: async (mod, opt) => { - const { filename } = (await registry.profile.get([mod.id, opt.key], {})) || {}, - $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, - $label = web.render( - web.html``, - web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) - ), - $pseudo = web.html`Upload file...`, - $input = web.html``, - $icon = web.html`${web.icon('file', { class: 'input-icon' })}`, - $filename = web.html`${web.escape(filename || 'none')}`, - $latest = web.render(web.html``, $filename); - if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); - $input.addEventListener('change', (event) => { - const file = event.target.files[0], - reader = new FileReader(); - reader.onload = async (progress) => { - $filename.innerText = file.name; - await registry.profile.set([mod.id, opt.key], { - filename: file.name, - content: progress.currentTarget.result, - }); - notifications.onChange(); - }; - reader.readAsText(file); - }); - $latest.addEventListener('click', (event) => { - $filename.innerText = 'none'; - registry.profile.set([mod.id, opt.key], {}); - }); - return web.render( - web.html`
`, - web.render($label, $input, $pseudo, $icon), - $latest - ); - }, - hotkey: async (mod, opt) => { - const value = await registry.profile.get([mod.id, opt.key], opt.value), - $tooltip = web.html`${web.icon('info', { class: 'input-tooltip' })}`, - $label = web.render( - web.html``, - web.render(web.html`

`, opt.tooltip ? $tooltip : '', opt.label) - ), - $input = web.html``, - $icon = web.html`${web.icon('command', { class: 'input-icon' })}`; - if (opt.tooltip) web.tooltip($tooltip, opt.tooltip); - $input.addEventListener('keydown', async (event) => { - event.preventDefault(); - const pressed = [], - modifiers = { - metaKey: 'Meta', - ctrlKey: 'Control', - altKey: 'Alt', - shiftKey: 'Shift', - }; - for (const modifier in modifiers) { - if (event[modifier]) pressed.push(modifiers[modifier]); + $save.addEventListener('click', async (event) => { + if (profileNames.includes($edit.value) && $select.value !== $edit.value) { + web.render( + web.empty($error), + `The profile "${web.escape($edit.value)}" already exists.` + ); + return false; } - const empty = ['Backspace', 'Delete'].includes(event.key) && !pressed.length; - if (!empty && !pressed.includes(event.key)) { - let key = event.key; - if (key === ' ') key = 'Space'; - if (key.length === 1) key = event.key.toUpperCase(); - pressed.push(key); + if (!$edit.value.match(/^[A-Za-z0-9_-]+$/)) { + web.render( + web.empty($error), + 'Profile names can only contain letters, numbers, dashes and underscores.' + ); + return false; } - $input.value = pressed.join('+'); - await registry.profile.set([mod.id, opt.key], $input.value); - notifications.onChange(); + await storage.set(['currentprofile'], $edit.value); + if ($select.value === '--') { + await storage.set(['profiles', $edit.value], {}); + } else if ($select.value !== $edit.value) { + await storage.set( + ['profiles', $edit.value], + await storage.get(['profiles', $select.value], {}) + ); + await storage.set(['profiles', $select.value], undefined); + } + location.reload(); }); - return web.render($label, $input, $icon); - }, -}; - -components.options = async (mod) => { - const $fragment = document.createDocumentFragment(); - for (const opt of mod.options) { - web.render($fragment, await options[opt.type](mod, opt)); - } - if (!mod.options.length) { - web.render($fragment, web.html`

No options.

`); - } - return $fragment; -}; - -components.mod = async (mod) => { - const $mod = web.html`
`, - $toggle = components.toggle('', await registry.enabled(mod.id)); - $toggle.addEventListener('change', (event) => { - registry.profile.set(['_mods', mod.id], event.target.checked); - notifications.onChange(); - }); - $mod.addEventListener('click', async (event) => { - if ($mod.className === 'mod-selected') return; - for (const $selected of document.querySelectorAll('.mod-selected')) { - $selected.className = 'mod'; - } - $mod.className = 'mod-selected'; - web.render( - web.empty($options), - web.render(components.title(mod.name), components.version(mod.version)), - components.tags(mod.tags), - await components.options(mod) - ); - }); - return web.render( - web.html`
`, - web.render( - $mod, - mod.preview - ? components.preview( - mod.preview.startsWith('http') - ? mod.preview - : fs.localPath(`repo/${mod._dir}/${mod.preview}`) - ) - : '', - web.render( - web.html`
`, - web.render(components.title(mod.name), components.version(mod.version)), - components.tags(mod.tags), - components.description(mod.description), - components.authors(mod.authors), - mod.environments.includes(env.name) && !registry.core.includes(mod.id) ? $toggle : '' - ) - ) - ); -}; - -components._$modListCache = {}; -components.modList = async (category) => { - if (!components._$modListCache[category]) { - const $search = web.html``, - $list = web.html`
`, - mods = await registry.list( - (mod) => mod.environments.includes(env.name) && mod.tags.includes(category) + $delete.addEventListener('click', async (event) => { + await storage.set(['profiles', $select.value], undefined); + await storage.set( + ['currentprofile'], + profileNames.find((profile) => profile !== $select.value) || 'default' ); - web.addHotkeyListener(['/'], () => $search.focus()); - $search.addEventListener('input', (event) => { - const query = $search.value.toLowerCase(); - for (const $mod of $list.children) { - const matches = !query || $mod.innerText.toLowerCase().includes(query); - $mod.classList[matches ? 'remove' : 'add']('hidden'); - } + location.reload(); }); - for (const mod of mods) { - mod.tags = mod.tags.filter((tag) => tag !== category); - web.render($list, await components.mod(mod)); - mod.tags.unshift(category); - } - components._$modListCache[category] = web.render( + + _$profileConfig = web.render( web.html`
`, + web.html`

+ Profiles are used to switch entire configurations. + Here they can be selected, renamed or deleted. + Profile names can only contain letters, numbers, + dashes and underscores.
+ Be careful - deleting a profile deletes all configuration + related to it. +

`, web.render( - web.html``, - $search, - web.html`${web.icon('search', { class: 'input-icon' })}` + web.html``, + $select, + web.html`${web.icon('chevron-down', { class: 'input-icon' })}` ), - $list + web.render( + web.html``, + $edit, + web.html`${web.icon('type', { class: 'input-icon' })}` + ), + web.render(web.html`

`, $save, $delete), + $error ); } - return components._$modListCache[category]; -}; + web.render(web.empty($options), _$profileConfig); +}); + +const _$modListCache = {}, + generators = { + options: async (mod) => { + const $fragment = document.createDocumentFragment(); + for (const opt of mod.options) { + web.render($fragment, await options[opt.type](mod, opt)); + } + if (!mod.options.length) { + web.render($fragment, web.html`

No options.

`); + } + return $fragment; + }, + mod: async (mod) => { + const $mod = web.html`
`, + $toggle = components.toggle('', await registry.enabled(mod.id)); + $toggle.addEventListener('change', (event) => { + registry.profileDB.set(['_mods', mod.id], event.target.checked); + notifications.onChange(); + }); + $mod.addEventListener('click', async (event) => { + if ($mod.className === 'mod-selected') return; + for (const $selected of document.querySelectorAll('.mod-selected')) { + $selected.className = 'mod'; + } + $mod.className = 'mod-selected'; + const fragment = [ + web.render(components.title(mod.name), components.version(mod.version)), + components.tags(mod.tags), + await generators.options(mod), + ]; + web.render(web.empty($options), ...fragment); + }); + return web.render( + web.html`
`, + web.render( + $mod, + mod.preview + ? components.preview( + mod.preview.startsWith('http') + ? mod.preview + : fs.localPath(`repo/${mod._dir}/${mod.preview}`) + ) + : '', + web.render( + web.html`
`, + web.render(components.title(mod.name), components.version(mod.version)), + components.tags(mod.tags), + components.description(mod.description), + components.authors(mod.authors), + mod.environments.includes(env.name) && !registry.core.includes(mod.id) + ? $toggle + : '' + ) + ) + ); + }, + modList: async (category) => { + if (!_$modListCache[category]) { + const $search = web.html``, + $list = web.html`
`, + mods = await registry.list( + (mod) => mod.environments.includes(env.name) && mod.tags.includes(category) + ); + web.addHotkeyListener(['/'], () => $search.focus()); + $search.addEventListener('input', (event) => { + const query = $search.value.toLowerCase(); + for (const $mod of $list.children) { + const matches = !query || $mod.innerText.toLowerCase().includes(query); + $mod.classList[matches ? 'remove' : 'add']('hidden'); + } + }); + for (const mod of mods) { + mod.tags = mod.tags.filter((tag) => tag !== category); + web.render($list, await generators.mod(mod)); + mod.tags.unshift(category); + } + _$modListCache[category] = web.render( + web.html`
`, + web.render( + web.html``, + $search, + web.html`${web.icon('search', { class: 'input-icon' })}` + ), + $list + ); + } + return _$modListCache[category]; + }, + }; const $notionNavItem = web.html`

${(await fs.getText('icon/colour.svg')).replace( @@ -465,7 +267,7 @@ web.render( ), $main ), - web.render($sidebar, $options) + web.render($sidebar, $profile, $options) ) ); @@ -481,19 +283,19 @@ import * as router from './router.mjs'; router.addView('core', async () => { web.empty($main); selectNavItem($coreNavItem); - return web.render($main, await components.modList('core')); + return web.render($main, await generators.modList('core')); }); router.addView('extensions', async () => { web.empty($main); selectNavItem($extensionsNavItem); - return web.render($main, await components.modList('extension')); + return web.render($main, await generators.modList('extension')); }); router.addView('themes', async () => { web.empty($main); selectNavItem($themesNavItem); - return web.render($main, await components.modList('theme')); + return web.render($main, await generators.modList('theme')); }); router.loadView('extensions', $main); diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/notifications.mjs b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/notifications.mjs new file mode 100644 index 0000000..94bb890 --- /dev/null +++ b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/notifications.mjs @@ -0,0 +1,88 @@ +/* + * notion-enhancer core: menu + * (c) 2021 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +'use strict'; + +import { env, fs, fmt, registry, web } from '../../api/_.mjs'; +const db = await registry.db('a6621988-551d-495a-97d8-3c568bca2e9e'); + +import { tw } from './styles.mjs'; + +export const notifications = { + $container: web.html`
`, + cache: await db.get(['notifications'], []), + provider: [ + env.welcomeNotification, + ...(await fs.getJSON('https://notion-enhancer.github.io/notifications.json')), + ], + add({ icon, message, id = undefined, color = undefined, link = undefined }) { + const $notification = link + ? web.html`` + : web.html``, + resolve = async () => { + if (id !== undefined) { + notifications.cache.push(id); + await db.set(['notifications'], notifications.cache); + } + $notification.remove(); + }; + $notification.addEventListener('click', resolve); + $notification.addEventListener('keyup', (event) => { + if (['Enter', ' '].includes(event.key)) resolve(); + }); + web.render( + notifications.$container, + web.render( + $notification, + web.html` + ${fmt.md.renderInline(message)} + `, + web.html`${web.icon(icon, { class: 'notification-icon' })}` + ) + ); + return $notification; + }, + _onChange: false, + onChange() { + if (this._onChange) return; + this._onChange = true; + const $notification = this.add({ + icon: 'refresh-cw', + message: 'Reload to apply changes.', + }); + $notification.addEventListener('click', env.reload); + }, +}; +web.render(document.body, notifications.$container); +for (const notification of notifications.provider) { + if ( + !notifications.cache.includes(notification.id) && + notification.version === env.version && + (!notification.environments || notification.environments.includes(env.name)) + ) { + notifications.add(notification); + } +} + +const errors = await registry.errors(); +if (errors.length) { + console.log('[notion-enhancer] registry errors:'); + console.table(errors); + notifications.add({ + icon: 'alert-circle', + message: 'Failed to load mods (check console).', + color: 'red', + }); +} diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/router.mjs b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/router.mjs index 110608b..d6e1d98 100644 --- a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/router.mjs +++ b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/router.mjs @@ -8,8 +8,7 @@ import { web } from '../../api/_.mjs'; -let _defaultView = '', - $viewRoot; +let _defaultView = ''; const _views = new Map(); export function addView(name, loadFunc) { diff --git a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/styles.mjs b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/styles.mjs index f46b10f..5c59819 100644 --- a/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/styles.mjs +++ b/extension/repo/menu@a6621988-551d-495a-97d8-3c568bca2e9e/styles.mjs @@ -40,14 +40,14 @@ const customClasses = { 'nav-notion': apply`flex items-center font-semibold text-xl cursor-pointer select-none mr-4 ml-4 sm:mb-4 md:w-full lg:(w-auto ml-0 mb-0)`, 'nav-notion-icon': apply`h-12 w-12 mr-5 sm:(h-6 w-6 mr-3)`, - 'nav-item': apply`ml-4 px-3 py-2 rounded-md text-sm font-medium hover:bg-interactive-hover focus:bg-interactive-active`, + 'nav-item': apply`ml-4 px-3 py-2 rounded-md text-sm font-medium hover:bg-interactive-hover focus:bg-interactive-focus`, 'nav-item-selected': apply`ml-4 px-3 py-2 rounded-md text-sm font-medium ring-1 ring-divider bg-notion-secondary`, 'main': apply`transition px-4 py-3 overflow-y-auto max-h-full-48 sm:max-h-full-32 lg:max-h-full-16`, 'mods-list': apply`flex flex-wrap`, 'mod-container': apply`w-full md:w-1/2 lg:w-1/3 xl:w-1/4 2xl:w-1/5 px-2.5 py-2.5 box-border`, 'mod': apply`relative h-full w-full flex flex-col overflow-hidden rounded-lg shadow-lg bg-notion-secondary border border-divider cursor-pointer`, - 'mod-selected': apply`mod ring ring-accent-blue-active`, + 'mod-selected': apply`mod ring ring-accent-blue-focus`, 'mod-body': apply`px-4 py-3 flex flex-col flex-auto children:cursor-pointer`, 'mod-preview': apply`object-cover w-full h-32`, 'mod-title': apply`mb-2 text-xl font-semibold tracking-tight flex items-center`, @@ -57,16 +57,24 @@ const customClasses = { 'mod-authors-container': apply`text-sm font-medium`, 'mod-author': apply`flex items-center mb-2`, 'mod-author-avatar': apply`inline object-cover w-5 h-5 rounded-full mr-2`, + 'sidebar': apply`h-full w-96 px-4 pt-3 pb-32 flex flex-col bg-notion-secondary border-l border-divider`, + 'profile-button': apply`block px-4 py-3 mb-2 rounded-md text-sm text-left font-semibold shadow-inner + bg-accent-red-hover border border-accent-red text-accent-red focus:(outline-none ring ring-inset ring-accent-red)`, + 'profile-save': apply`text-sm px-3 py-2 font-medium mt-2 bg-accent-blue text-accent-blue-text rounded-md + hover:bg-accent-blue-hover focus:(bg-accent-blue-focus outline-none)`, + 'profile-delete': apply`text-sm px-3 py-2 font-medium ml-3 mt-3 bg-red-tag text-red-tag-text rounded-md + border border-red-text hover:bg-red-text focus:(outline-none bg-red-text)`, + 'profile-error': apply`text-xs mt-2 text-red-text`, + 'button-icon': apply`w-4 h-4 -mt-1 inline-block mr-1`, + 'options-container': apply`px-4 py-3 shadow-inner rounded-lg bg-notion border border-divider space-y-3`, + 'options-placeholder': apply`text-sm text-foreground-secondary`, 'toggle-box': apply`w-9 h-5 p-0.5 flex items-center bg-toggle-off rounded-full duration-300 ease-in-out cursor-pointer`, 'toggle-label': apply`relative text-sm flex w-full mt-auto`, 'toggle-check': apply`appearance-none ml-auto checked:sibling:(bg-toggle-on after::translate-x-4)`, 'toggle-feature': apply`after::(${pseudoContent} w-4 h-4 bg-toggle-feature rounded-full duration-300) cursor-pointer`, - 'sidebar': apply`h-full w-96 px-4 pt-3 pb-32 flex flex-col bg-notion-secondary border-l border-divider`, - 'options-container': apply`px-4 py-3 shadow-inner rounded-lg bg-notion border border-divider space-y-3`, - 'options-empty': apply`text-sm text-foreground-secondary`, 'input-label': apply`block text-sm mt-2 relative`, 'input': apply`transition block w-full mt-2 pl-3 pr-14 py-2 text-sm rounded-md flex bg-input text-foreground - appearance-none placeholder-foreground-secondary ring-1 ring-divider focus:(outline-none ring ring-accent-blue-active)`, + appearance-none placeholder-foreground-secondary ring-1 ring-divider focus:(outline-none ring ring-accent-blue-focus)`, 'input-tooltip': apply`h-4 w-4 -mt-1 inline-block mr-2`, 'input-icon': apply`absolute w-11 h-9 right-0 bottom-0 py-2 px-3 bg-notion-secondary rounded-r-md text-icon`, 'input-placeholder': apply`text-foreground-secondary`, @@ -96,8 +104,8 @@ setup({ 'icon-secondary': 'var(--theme--icon_secondary)', 'foreground': 'var(--theme--text)', 'foreground-secondary': 'var(--theme--text_secondary)', - 'interactive-active': 'var(--theme--ui_interactive-active)', 'interactive-hover': 'var(--theme--ui_interactive-hover)', + 'interactive-focus': 'var(--theme--ui_interactive-focus)', 'tag': 'var(--theme--tag_default)', 'tag-text': 'var(--theme--tag_default-text)', 'toggle': { @@ -108,7 +116,7 @@ setup({ 'accent': { 'blue': 'var(--theme--accent_blue)', 'blue-hover': 'var(--theme--accent_blue-hover)', - 'blue-active': 'var(--theme--accent_blue-active)', + 'blue-focus': 'var(--theme--accent_blue-focus)', 'blue-text': 'var(--theme--accent_blue-text)', 'red': 'var(--theme--accent_red)', 'red-hover': 'var(--theme--accent_red-hover)', diff --git a/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/theme.css b/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/theme.css index 95123c7..207639a 100644 --- a/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/theme.css +++ b/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/theme.css @@ -349,7 +349,7 @@ body, .notion-default-overlay-container [style*='grid-template-columns: [boolean-start] 60px [boolean-end property-start] 120px [property-end opererator-start] 110px [operator-end value-start] auto [value-end menu-start] 32px [menu-end];'] .notion-focusable[style*='background: rgb(223, 223, 222);'] { - background: var(--theme--ui_interactive-active) !important; + background: var(--theme--ui_interactive-focus) !important; } .notion-focusable-within, @@ -641,8 +641,8 @@ body, } .notion-focusable-within:focus-within, .notion-focusable:focus-visible { - box-shadow: var(--theme--accent_blue-active, rgba(26, 170, 220, 0.7)) 0px 0px 0px 1px inset, - var(--theme--accent_blue-active, rgba(26, 170, 220, 0.4)) 0px 0px 0px 2px !important; + box-shadow: var(--theme--accent_blue-focus, rgba(26, 170, 220, 0.7)) 0px 0px 0px 1px inset, + var(--theme--accent_blue-focus, rgba(26, 170, 220, 0.4)) 0px 0px 0px 2px !important; } @keyframes pulsing-button-border { @@ -661,7 +661,7 @@ body, background: var(--theme--accent_blue-hover) !important; } [style*='background: rgb(0, 141, 190);'] { - background: var(--theme--accent_blue-active) !important; + background: var(--theme--accent_blue-focus) !important; } [style*='background-color: rgb(235, 87, 87); height: 28px; width: 28px;'] { diff --git a/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/variables.css b/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/variables.css index 241edee..9f43b96 100644 --- a/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/variables.css +++ b/extension/repo/theming@0f0bf8b6-eae6-4273-b307-8fc43f2ee082/variables.css @@ -28,7 +28,7 @@ --theme--accent_blue: rgb(46, 170, 220); --theme--accent_blue-selection: rgb(46, 170, 220, 0.25); --theme--accent_blue-hover: rgb(6, 156, 205); - --theme--accent_blue-active: rgb(0, 141, 190); + --theme--accent_blue-focus: rgb(0, 141, 190); --theme--accent_blue-text: #fff; --theme--accent_red: #eb5757; --theme--accent_red-hover: rgba(235, 87, 87, 0.1); @@ -47,7 +47,7 @@ --theme--ui_shadow: rgba(15, 15, 15, 0.15); --theme--ui_divider: rgb(237, 237, 236); --theme--ui_interactive-hover: rgba(55, 53, 47, 0.08); - --theme--ui_interactive-active: rgba(55, 53, 47, 0.16); + --theme--ui_interactive-focus: rgba(55, 53, 47, 0.16); --theme--ui_toggle-on: var(--theme--accent_blue); --theme--ui_toggle-off: rgba(135, 131, 120, 0.3); --theme--ui_toggle-feature: #fff; @@ -211,7 +211,7 @@ --theme--ui_shadow: rgba(15, 15, 15, 0.15); --theme--ui_divider: rgb(255, 255, 255, 0.07); --theme--ui_interactive-hover: rgb(71, 76, 80); - --theme--ui_interactive-active: rgb(63, 68, 71); + --theme--ui_interactive-focus: rgb(63, 68, 71); --theme--ui_toggle-on: var(--theme--accent_blue); --theme--ui_toggle-off: rgba(202, 204, 206, 0.3); --theme--ui_toggle-feature: #fff;