mirror of
				https://github.com/notion-enhancer/notion-enhancer.git
				synced 2025-11-04 08:08:08 +11:00 
			
		
		
		
	chore(menu): detect db update by comparing against prev value
- syncs reload btn visibility b/w tabs - doesn't trigger when switching profiles if identical
This commit is contained in:
		
							parent
							
								
									ba98ed6412
								
							
						
					
					
						commit
						a6e9504b6f
					
				@ -52,18 +52,17 @@ const insertMenu = async (db) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let _contentWindow;
 | 
					    let _contentWindow;
 | 
				
			||||||
    const sendThemePing = () => {
 | 
					    const sendThemePing = () => {
 | 
				
			||||||
        if (!_contentWindow) return;
 | 
					 | 
				
			||||||
        const darkMode = document.body.classList.contains("dark"),
 | 
					        const darkMode = document.body.classList.contains("dark"),
 | 
				
			||||||
          notionTheme = darkMode ? "dark" : "light";
 | 
					          notionTheme = darkMode ? "dark" : "light";
 | 
				
			||||||
        if (renderPing.theme === notionTheme) return;
 | 
					        if (renderPing.theme === notionTheme) return;
 | 
				
			||||||
        renderPing.theme = notionTheme;
 | 
					        renderPing.theme = notionTheme;
 | 
				
			||||||
        _contentWindow.postMessage(renderPing, "*");
 | 
					        _contentWindow?.postMessage?.(renderPing, "*");
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      sendRenderPing = (contentWindow) => {
 | 
					      sendRenderPing = (contentWindow) => {
 | 
				
			||||||
        _contentWindow ??= contentWindow;
 | 
					        _contentWindow ??= contentWindow;
 | 
				
			||||||
        if (!$modal.hasAttribute("open")) return;
 | 
					        if (!$modal.hasAttribute("open")) return;
 | 
				
			||||||
        delete renderPing.theme;
 | 
					        delete renderPing.theme;
 | 
				
			||||||
        _contentWindow.focus();
 | 
					        _contentWindow?.focus?.();
 | 
				
			||||||
        sendThemePing();
 | 
					        sendThemePing();
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -4,9 +4,10 @@
 | 
				
			|||||||
 * (https://notion-enhancer.github.io/) under the MIT license
 | 
					 * (https://notion-enhancer.github.io/) under the MIT license
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { useState } from "../state.mjs";
 | 
					import { setState, useState } from "../state.mjs";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Checkbox({ _get, _set, ...props }) {
 | 
					function Checkbox({ _get, _set, _requireReload = true, ...props }) {
 | 
				
			||||||
 | 
					  let _initialValue;
 | 
				
			||||||
  const { html, extendProps } = globalThis.__enhancerApi,
 | 
					  const { html, extendProps } = globalThis.__enhancerApi,
 | 
				
			||||||
    $input = html`<input
 | 
					    $input = html`<input
 | 
				
			||||||
      type="checkbox"
 | 
					      type="checkbox"
 | 
				
			||||||
@ -21,6 +22,10 @@ function Checkbox({ _get, _set, ...props }) {
 | 
				
			|||||||
  useState(["rerender"], async () => {
 | 
					  useState(["rerender"], async () => {
 | 
				
			||||||
    const checked = (await _get?.()) ?? $input.checked;
 | 
					    const checked = (await _get?.()) ?? $input.checked;
 | 
				
			||||||
    $input.checked = checked;
 | 
					    $input.checked = checked;
 | 
				
			||||||
 | 
					    if (_requireReload) {
 | 
				
			||||||
 | 
					      _initialValue ??= checked;
 | 
				
			||||||
 | 
					      if (checked !== _initialValue) setState({ databaseUpdated: true });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return html`<label
 | 
					  return html`<label
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@
 | 
				
			|||||||
 * (https://notion-enhancer.github.io/) under the MIT license
 | 
					 * (https://notion-enhancer.github.io/) under the MIT license
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { useState } from "../state.mjs";
 | 
					import { setState, useState } from "../state.mjs";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const updateHotkey = (event) => {
 | 
					const updateHotkey = (event) => {
 | 
				
			||||||
    const keys = [];
 | 
					    const keys = [];
 | 
				
			||||||
@ -72,6 +72,7 @@ function Input({
 | 
				
			|||||||
  class: className,
 | 
					  class: className,
 | 
				
			||||||
  _get,
 | 
					  _get,
 | 
				
			||||||
  _set,
 | 
					  _set,
 | 
				
			||||||
 | 
					  _requireReload = true,
 | 
				
			||||||
  ...props
 | 
					  ...props
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
  let $filename, $clear;
 | 
					  let $filename, $clear;
 | 
				
			||||||
@ -117,6 +118,7 @@ function Input({
 | 
				
			|||||||
      ><i class="i-${icon} w-[16px] h-[16px]"></i>
 | 
					      ><i class="i-${icon} w-[16px] h-[16px]"></i>
 | 
				
			||||||
    </span>`;
 | 
					    </span>`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let _initialValue;
 | 
				
			||||||
  extendProps($input, {
 | 
					  extendProps($input, {
 | 
				
			||||||
    onchange: (event) => {
 | 
					    onchange: (event) => {
 | 
				
			||||||
      if (_set && type === "file") {
 | 
					      if (_set && type === "file") {
 | 
				
			||||||
@ -128,8 +130,20 @@ function Input({
 | 
				
			|||||||
      if (type === "file") {
 | 
					      if (type === "file") {
 | 
				
			||||||
        $filename.innerText = value?.filename || "Upload a file";
 | 
					        $filename.innerText = value?.filename || "Upload a file";
 | 
				
			||||||
        $clear.style.display = value?.filename ? "" : "none";
 | 
					        $clear.style.display = value?.filename ? "" : "none";
 | 
				
			||||||
      } else if ($input.value !== value) $input.value = value;
 | 
					        if (_requireReload) {
 | 
				
			||||||
      if (type === "color") updateContrast($input, $icon);
 | 
					          _initialValue ??= value?.content || "";
 | 
				
			||||||
 | 
					          if ((value?.content || "") !== _initialValue) {
 | 
				
			||||||
 | 
					            setState({ databaseUpdated: true });
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        if ($input.value !== value) $input.value = value;
 | 
				
			||||||
 | 
					        if (_requireReload) {
 | 
				
			||||||
 | 
					          _initialValue ??= value;
 | 
				
			||||||
 | 
					          if (value !== _initialValue) setState({ databaseUpdated: true });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (type === "color") updateContrast($input, $icon);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    onkeydown: type === "hotkey" ? updateHotkey : undefined,
 | 
					    onkeydown: type === "hotkey" ? updateHotkey : undefined,
 | 
				
			||||||
    oninput: type === "color" ? () => _set?.($input.value) : undefined,
 | 
					    oninput: type === "color" ? () => _set?.($input.value) : undefined,
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@
 | 
				
			|||||||
 * (https://notion-enhancer.github.io/) under the MIT license
 | 
					 * (https://notion-enhancer.github.io/) under the MIT license
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { useState } from "../state.mjs";
 | 
					import { setState, useState } from "../state.mjs";
 | 
				
			||||||
import { Popup } from "./Popup.mjs";
 | 
					import { Popup } from "./Popup.mjs";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Option({ value, _get, _set }) {
 | 
					function Option({ value, _get, _set }) {
 | 
				
			||||||
@ -33,7 +33,8 @@ function Option({ value, _get, _set }) {
 | 
				
			|||||||
  return $option;
 | 
					  return $option;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Select({ values, _get, _set, ...props }) {
 | 
					function Select({ values, _get, _set, _requireReload = true, ...props }) {
 | 
				
			||||||
 | 
					  let _initialValue;
 | 
				
			||||||
  const { html } = globalThis.__enhancerApi,
 | 
					  const { html } = globalThis.__enhancerApi,
 | 
				
			||||||
    // dir="rtl" overflows to the left during transition
 | 
					    // dir="rtl" overflows to the left during transition
 | 
				
			||||||
    $select = html`<div
 | 
					    $select = html`<div
 | 
				
			||||||
@ -45,8 +46,13 @@ function Select({ values, _get, _set, ...props }) {
 | 
				
			|||||||
      transition duration-[20ms] hover:bg-[color:var(--theme--bg-hover)]"
 | 
					      transition duration-[20ms] hover:bg-[color:var(--theme--bg-hover)]"
 | 
				
			||||||
      ...${props}
 | 
					      ...${props}
 | 
				
			||||||
    ></div>`;
 | 
					    ></div>`;
 | 
				
			||||||
  useState(["rerender"], () => {
 | 
					  useState(["rerender"], async () => {
 | 
				
			||||||
    _get?.().then((value) => ($select.innerText = value));
 | 
					    const value = (await _get?.()) ?? $select.innerText;
 | 
				
			||||||
 | 
					    $select.innerText = value;
 | 
				
			||||||
 | 
					    if (_requireReload) {
 | 
				
			||||||
 | 
					      _initialValue ??= value;
 | 
				
			||||||
 | 
					      if (value !== _initialValue) setState({ databaseUpdated: true });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return html`<div class="notion-enhancer--menu-select relative">
 | 
					  return html`<div class="notion-enhancer--menu-select relative">
 | 
				
			||||||
 | 
				
			|||||||
@ -4,9 +4,10 @@
 | 
				
			|||||||
 * (https://notion-enhancer.github.io/) under the MIT license
 | 
					 * (https://notion-enhancer.github.io/) under the MIT license
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { useState } from "../state.mjs";
 | 
					import { setState, useState } from "../state.mjs";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Toggle({ _get, _set, ...props }) {
 | 
					function Toggle({ _get, _set, _requireReload = true, ...props }) {
 | 
				
			||||||
 | 
					  let _initialValue;
 | 
				
			||||||
  const { html, extendProps } = globalThis.__enhancerApi,
 | 
					  const { html, extendProps } = globalThis.__enhancerApi,
 | 
				
			||||||
    $input = html`<input
 | 
					    $input = html`<input
 | 
				
			||||||
      type="checkbox"
 | 
					      type="checkbox"
 | 
				
			||||||
@ -19,6 +20,10 @@ function Toggle({ _get, _set, ...props }) {
 | 
				
			|||||||
  useState(["rerender"], async () => {
 | 
					  useState(["rerender"], async () => {
 | 
				
			||||||
    const checked = (await _get?.()) ?? $input.checked;
 | 
					    const checked = (await _get?.()) ?? $input.checked;
 | 
				
			||||||
    $input.checked = checked;
 | 
					    $input.checked = checked;
 | 
				
			||||||
 | 
					    if (_requireReload) {
 | 
				
			||||||
 | 
					      _initialValue ??= checked;
 | 
				
			||||||
 | 
					      if (checked !== _initialValue) setState({ databaseUpdated: true });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return html`<div class="notion-enhancer--menu-toggle shrink-0">
 | 
					  return html`<div class="notion-enhancer--menu-toggle shrink-0">
 | 
				
			||||||
 | 
				
			|||||||
@ -58,7 +58,7 @@ function List({ id, mods, description }) {
 | 
				
			|||||||
              }
 | 
					              }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          setState({ rerender: true, databaseUpdated: true });
 | 
					          setState({ rerender: true });
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
      return html`<${Mod} ...${{ ...mod, _get, _set }} />`;
 | 
					      return html`<${Mod} ...${{ ...mod, _get, _set }} />`;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
				
			|||||||
@ -79,7 +79,7 @@ function Options({ mod }) {
 | 
				
			|||||||
    const _get = async () => (await modDatabase(mod.id)).get(opt.key),
 | 
					    const _get = async () => (await modDatabase(mod.id)).get(opt.key),
 | 
				
			||||||
      _set = async (value) => {
 | 
					      _set = async (value) => {
 | 
				
			||||||
        await (await modDatabase(mod.id)).set(opt.key, value);
 | 
					        await (await modDatabase(mod.id)).set(opt.key, value);
 | 
				
			||||||
        setState({ rerender: true, databaseUpdated: true });
 | 
					        setState({ rerender: true });
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
    return html`<${Option} ...${{ _get, _set, ...opt }} />`;
 | 
					    return html`<${Option} ...${{ _get, _set, ...opt }} />`;
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,7 @@ function Profile({ id }) {
 | 
				
			|||||||
    setActive = async () => {
 | 
					    setActive = async () => {
 | 
				
			||||||
      if (await isActive()) return;
 | 
					      if (await isActive()) return;
 | 
				
			||||||
      await db.set("activeProfile", id);
 | 
					      await db.set("activeProfile", id);
 | 
				
			||||||
      setState({ rerender: true, databaseUpdated: true });
 | 
					      setState({ rerender: true });
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const $successName = html`<span
 | 
					  const $successName = html`<span
 | 
				
			||||||
@ -64,7 +64,7 @@ function Profile({ id }) {
 | 
				
			|||||||
          res = JSON.parse(res);
 | 
					          res = JSON.parse(res);
 | 
				
			||||||
          delete res["profileName"];
 | 
					          delete res["profileName"];
 | 
				
			||||||
          await profile.import(res);
 | 
					          await profile.import(res);
 | 
				
			||||||
          setState({ rerender: true, databaseUpdated: true });
 | 
					          setState({ rerender: true });
 | 
				
			||||||
          $uploadSuccess.show();
 | 
					          $uploadSuccess.show();
 | 
				
			||||||
          setTimeout(() => $uploadSuccess.hide(), 2000);
 | 
					          setTimeout(() => $uploadSuccess.hide(), 2000);
 | 
				
			||||||
        } catch (err) {
 | 
					        } catch (err) {
 | 
				
			||||||
@ -113,10 +113,8 @@ function Profile({ id }) {
 | 
				
			|||||||
      const index = profileIds.indexOf(id);
 | 
					      const index = profileIds.indexOf(id);
 | 
				
			||||||
      if (index > -1) profileIds.splice(index, 1);
 | 
					      if (index > -1) profileIds.splice(index, 1);
 | 
				
			||||||
      await db.set("profileIds", profileIds);
 | 
					      await db.set("profileIds", profileIds);
 | 
				
			||||||
      if (await isActive()) {
 | 
					      if (await isActive()) await db.remove("activeProfile");
 | 
				
			||||||
        await db.remove("activeProfile");
 | 
					      setState({ rerender: true });
 | 
				
			||||||
        setState({ rerender: true, databaseUpdated: true });
 | 
					 | 
				
			||||||
      } else setState({ rerender: true });
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    $delete = html`<button
 | 
					    $delete = html`<button
 | 
				
			||||||
      class="h-[14px] transition duration-[20ms]
 | 
					      class="h-[14px] transition duration-[20ms]
 | 
				
			||||||
@ -155,10 +153,13 @@ function Profile({ id }) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return html`<li class="flex items-center my-[14px] gap-[8px]" id=${id}>
 | 
					  return html`<li class="flex items-center my-[14px] gap-[8px]" id=${id}>
 | 
				
			||||||
    <${Checkbox}
 | 
					    <${Checkbox}
 | 
				
			||||||
      ...${{ _get: isActive, _set: setActive }}
 | 
					      ...${{ _get: isActive, _set: setActive, _requireReload: false }}
 | 
				
			||||||
      onchange=${(event) => (event.target.checked = true)}
 | 
					      onchange=${(event) => (event.target.checked = true)}
 | 
				
			||||||
    />
 | 
					    />
 | 
				
			||||||
    <${Input} icon="file-cog" ...${{ _get: getName, _set: setName }} />
 | 
					    <${Input}
 | 
				
			||||||
 | 
					      icon="file-cog"
 | 
				
			||||||
 | 
					      ...${{ _get: getName, _set: setName, _requireReload: false }}
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
    <${Button}
 | 
					    <${Button}
 | 
				
			||||||
      icon="import"
 | 
					      icon="import"
 | 
				
			||||||
      variant="sm"
 | 
					      variant="sm"
 | 
				
			||||||
 | 
				
			|||||||
@ -9,8 +9,8 @@ import { Option } from "./Options.mjs";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const privacyPolicy = "https://notion-enhancer.github.io/about/privacy-policy/";
 | 
					const privacyPolicy = "https://notion-enhancer.github.io/about/privacy-policy/";
 | 
				
			||||||
function Telemetry() {
 | 
					function Telemetry() {
 | 
				
			||||||
  const { html, platform, version, getMods } = globalThis.__enhancerApi,
 | 
					  const { html, platform, version } = globalThis.__enhancerApi,
 | 
				
			||||||
    { getProfile, isEnabled, initDatabase } = globalThis.__enhancerApi,
 | 
					    { getMods, isEnabled, initDatabase } = globalThis.__enhancerApi,
 | 
				
			||||||
    timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
 | 
					    timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const $enabledMods = html`<code></code>`;
 | 
					  const $enabledMods = html`<code></code>`;
 | 
				
			||||||
@ -29,7 +29,7 @@ function Telemetry() {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    _set = async (value) => {
 | 
					    _set = async (value) => {
 | 
				
			||||||
      await initDatabase().set("telemetryEnabled", value);
 | 
					      await initDatabase().set("telemetryEnabled", value);
 | 
				
			||||||
      setState({ rerender: true, databaseUpdated: true });
 | 
					      setState({ rerender: true });
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // todo: actually collect telemetry
 | 
					  // todo: actually collect telemetry
 | 
				
			||||||
@ -44,7 +44,7 @@ function Telemetry() {
 | 
				
			|||||||
      (<code>"${version}"</code>), and enabled mods (${$enabledMods}). You can
 | 
					      (<code>"${version}"</code>), and enabled mods (${$enabledMods}). You can
 | 
				
			||||||
      opt in or out of telemetry at any time. This setting syncs across
 | 
					      opt in or out of telemetry at any time. This setting syncs across
 | 
				
			||||||
      configuration profiles. For more information, read the notion-enhancer's
 | 
					      configuration profiles. For more information, read the notion-enhancer's
 | 
				
			||||||
      <a href=${privacyPolicy}>privacy policy</a>.`}
 | 
					      <a href=${privacyPolicy} class="ml-[3px]">privacy policy</a>.`}
 | 
				
			||||||
    ...${{ _get, _set }}
 | 
					    ...${{ _get, _set }}
 | 
				
			||||||
  />`;
 | 
					  />`;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -107,7 +107,7 @@ const render = async () => {
 | 
				
			|||||||
    const _get = () => isEnabled(mods[i].id),
 | 
					    const _get = () => isEnabled(mods[i].id),
 | 
				
			||||||
      _set = async (enabled) => {
 | 
					      _set = async (enabled) => {
 | 
				
			||||||
        await setEnabled(mods[i].id, enabled);
 | 
					        await setEnabled(mods[i].id, enabled);
 | 
				
			||||||
        setState({ rerender: true, databaseUpdated: true });
 | 
					        setState({ rerender: true });
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
    mods[i].view = html`<${View} id=${mods[i].id}>
 | 
					    mods[i].view = html`<${View} id=${mods[i].id}>
 | 
				
			||||||
      <!-- passing an empty options array hides the settings button -->
 | 
					      <!-- passing an empty options array hides the settings button -->
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user