mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-04 12:49:03 +00:00
feat(onboarding): require agreement to privacy policy + ts & cs, add landing tiles
This commit is contained in:
parent
567e678a6f
commit
f1332fffbd
@ -7,7 +7,7 @@
|
||||
"use strict";
|
||||
|
||||
const platform = "browser",
|
||||
enhancerVersion = chrome.runtime.getManifest().version,
|
||||
version = chrome.runtime.getManifest().version,
|
||||
enhancerUrl = (target) => chrome.runtime.getURL(target);
|
||||
|
||||
const readFile = async (file) => {
|
||||
@ -75,8 +75,8 @@ const initDatabase = (namespace, fallbacks = {}) => {
|
||||
globalThis.__enhancerApi ??= {};
|
||||
Object.assign(globalThis.__enhancerApi, {
|
||||
platform,
|
||||
version,
|
||||
enhancerUrl,
|
||||
enhancerVersion,
|
||||
readFile,
|
||||
readJson,
|
||||
reloadApp,
|
||||
|
@ -7,12 +7,11 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs"),
|
||||
os = require("os"),
|
||||
path = require("path"),
|
||||
notionRequire = (target) => require(`../../../${target}`);
|
||||
|
||||
const platform = process.platform,
|
||||
enhancerVersion = require("notion-enhancer/package.json").version,
|
||||
version = require("notion-enhancer/package.json").version,
|
||||
enhancerUrl = (target) =>
|
||||
`notion://www.notion.so/__notion-enhancer/${target.replace(/^\//, "")}`;
|
||||
|
||||
@ -72,6 +71,7 @@ const initDatabase = (namespace, fallbacks = {}) => {
|
||||
init.run();
|
||||
|
||||
// schema:
|
||||
// - ("agreedToTerms") -> boolean
|
||||
// - ("profileIds") -> $profileId[]
|
||||
// - ("activeProfile") -> $profileId
|
||||
// - $profileId: ("profileName") -> string
|
||||
@ -148,8 +148,8 @@ globalThis.__enhancerApi ??= {};
|
||||
Object.assign(globalThis.__enhancerApi, {
|
||||
notionRequire,
|
||||
platform,
|
||||
version,
|
||||
enhancerUrl,
|
||||
enhancerVersion,
|
||||
readFile,
|
||||
readJson,
|
||||
reloadApp,
|
||||
|
@ -547,7 +547,7 @@ const h = (type, props, ...children) => {
|
||||
for (const prop in props ?? {}) {
|
||||
if (typeof props[prop] === "undefined") continue;
|
||||
if (htmlAttributes.includes(prop) || prop.startsWith("data-")) {
|
||||
if (typeof props[prop] === "boolean") {
|
||||
if (typeof props[prop] === "boolean" && !prop.startsWith("data-")) {
|
||||
if (!props[prop]) continue;
|
||||
elem.setAttribute(prop, "");
|
||||
} else elem.setAttribute(prop, props[prop]);
|
||||
|
@ -46,11 +46,15 @@ const getMods = async (category) => {
|
||||
};
|
||||
|
||||
const isEnabled = async (id) => {
|
||||
const mod = (await getMods()).find((mod) => mod.id === id);
|
||||
const { version, initDatabase } = globalThis.__enhancerApi,
|
||||
mod = (await getMods()).find((mod) => mod.id === id);
|
||||
if (mod._src === "core") return true;
|
||||
// prettier-ignore
|
||||
return mod._src === "core" || await globalThis.__enhancerApi
|
||||
.initDatabase([await getProfile(), "enabledMods"])
|
||||
.get(id);
|
||||
const agreedToTerms = await initDatabase().get("agreedToTerms"),
|
||||
enabledInProfile = await initDatabase([
|
||||
await getProfile(), "enabledMods",
|
||||
]).get(id);
|
||||
return agreedToTerms === version && enabledInProfile;
|
||||
},
|
||||
setEnabled = async (id, enabled) => {
|
||||
return await globalThis.__enhancerApi
|
||||
|
@ -10,6 +10,7 @@ export default async (api, db) => {
|
||||
const {
|
||||
html,
|
||||
platform,
|
||||
version,
|
||||
getMods,
|
||||
isEnabled,
|
||||
enhancerUrl,
|
||||
@ -17,6 +18,7 @@ export default async (api, db) => {
|
||||
sendMessage,
|
||||
addMutationListener,
|
||||
addKeyListener,
|
||||
initDatabase,
|
||||
} = api,
|
||||
openMenuHotkey = await db.get("openMenuHotkey"),
|
||||
menuButtonIconStyle = await db.get("menuButtonIconStyle"),
|
||||
@ -153,4 +155,8 @@ export default async (api, db) => {
|
||||
});
|
||||
|
||||
sendMessage("notion-enhancer", "load-complete");
|
||||
|
||||
if ((await initDatabase().get("agreedToTerms")) === version) {
|
||||
// telemetry
|
||||
}
|
||||
};
|
||||
|
@ -26,15 +26,16 @@ function Button({ icon, variant, tagName, ...props }, ...children) {
|
||||
bg-purple-500 hover:(from-white/20 to-transparent
|
||||
bg-[linear-gradient(225deg,var(--tw-gradient-stops))])`
|
||||
: `border-(& [color:var(--theme--fg-border)])
|
||||
hover:bg-[color:var(--theme--bg-hover)]`
|
||||
not-disabled:hover:bg-[color:var(--theme--bg-hover)]
|
||||
disabled:text-[color:var(--theme--fg-secondary)]`
|
||||
}`,
|
||||
});
|
||||
if (props["href"]) tagName ??= "a";
|
||||
return html`<${tagName ?? "button"} tabindex="0" ...${props}>
|
||||
tagName ??= props["href"] ? "a" : "button";
|
||||
return html`<${tagName} ...${props}>
|
||||
${icon
|
||||
? html`<i
|
||||
class="i-${icon}
|
||||
text-[${variant === "sm" && children.length ? "14" : "18"}px]"
|
||||
text-[${variant === "sm" && children.length ? "13" : "17"}px]"
|
||||
></i>`
|
||||
: ""}
|
||||
<span class="text-[${variant === "sm" ? "13" : "14"}px] empty:hidden">
|
||||
|
@ -18,8 +18,9 @@ function Checkbox({ _get, _set, ...props }) {
|
||||
...${props}
|
||||
/>`;
|
||||
extendProps($input, { onchange: () => _set?.($input.checked) });
|
||||
useState(["rerender"], () => {
|
||||
_get?.().then((checked) => ($input.checked = checked));
|
||||
useState(["rerender"], async () => {
|
||||
const checked = (await _get?.()) ?? $input.checked;
|
||||
$input.checked = checked;
|
||||
});
|
||||
|
||||
return html`<label
|
||||
|
@ -9,8 +9,8 @@ import { extendProps } from "../state.mjs";
|
||||
function Heading(props, ...children) {
|
||||
const { html } = globalThis.__enhancerApi;
|
||||
extendProps(props, {
|
||||
class: `notion-enhancer--menu-heading flex items-center gap-[4px]
|
||||
text-[16px] font-semibold mb-[16px] mt-[48px] first:mt-0 pb-[12px]
|
||||
class: `notion-enhancer--menu-heading text-[16px]
|
||||
font-semibold mb-[16px] mt-[48px] first:mt-0 pb-[12px]
|
||||
border-b-(& [color:var(--theme--fg-border)])`,
|
||||
});
|
||||
return html`<h4 ...${props}>${children}</h4>`;
|
||||
|
@ -124,14 +124,12 @@ function Input({
|
||||
} else _set?.($input.value);
|
||||
},
|
||||
onrerender: async () => {
|
||||
_get?.().then((value) => {
|
||||
value ??= "";
|
||||
if (type === "file") {
|
||||
$filename.innerText = value?.filename || "Upload a file";
|
||||
$clear.style.display = value?.filename ? "" : "none";
|
||||
} else if ($input.value !== value) $input.value = value;
|
||||
if (type === "color") updateContrast($input, $icon);
|
||||
});
|
||||
const value = (await _get?.()) ?? $input.value ?? "";
|
||||
if (type === "file") {
|
||||
$filename.innerText = value?.filename || "Upload a file";
|
||||
$clear.style.display = value?.filename ? "" : "none";
|
||||
} else if ($input.value !== value) $input.value = value;
|
||||
if (type === "color") updateContrast($input, $icon);
|
||||
},
|
||||
onkeydown: type === "hotkey" ? updateHotkey : undefined,
|
||||
oninput: type === "color" ? () => _set?.($input.value) : undefined,
|
||||
|
@ -25,12 +25,10 @@ function Option({ value, _get, _set }) {
|
||||
${value}
|
||||
</div>
|
||||
</div>`;
|
||||
useState(["rerender"], () => {
|
||||
_get?.().then((actualValue) => {
|
||||
if (actualValue === value) {
|
||||
$option.append($selected);
|
||||
} else $selected.remove();
|
||||
});
|
||||
useState(["rerender"], async () => {
|
||||
if ((await _get?.()) === value) {
|
||||
$option.append($selected);
|
||||
} else $selected.remove();
|
||||
});
|
||||
return $option;
|
||||
}
|
||||
|
29
src/core/menu/components/Tile.mjs
Normal file
29
src/core/menu/components/Tile.mjs
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* notion-enhancer
|
||||
* (c) 2023 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
import { extendProps } from "../state.mjs";
|
||||
|
||||
function Tile({ icon, title, tagName, ...props }, ...children) {
|
||||
const { html } = globalThis.__enhancerApi;
|
||||
extendProps(props, {
|
||||
class: `px-[16px] py-[12px]
|
||||
flex items-center gap-[12px] rounded-[4px]
|
||||
border-(& [color:var(--theme--fg-border)])
|
||||
hover:bg-[color:var(--theme--bg-hover)]`,
|
||||
});
|
||||
tagName ??= props["href"] ? "a" : "button";
|
||||
return html`<${tagName} ...${props}>
|
||||
<i class="i-${icon} text-[28px]"></i>
|
||||
<div>
|
||||
<h3 class="text-[14px] font-semibold">${title}</h3>
|
||||
<div class="text-(left [12px] [color:var(--theme--fg-secondary)])">
|
||||
${children}
|
||||
</div>
|
||||
</div>
|
||||
<//>`;
|
||||
}
|
||||
|
||||
export { Tile };
|
@ -16,8 +16,9 @@ function Toggle({ _get, _set, ...props }) {
|
||||
...${props}
|
||||
/>`;
|
||||
extendProps($input, { onchange: () => _set?.($input.checked) });
|
||||
useState(["rerender"], () => {
|
||||
_get?.().then((checked) => ($input.checked = checked));
|
||||
useState(["rerender"], async () => {
|
||||
const checked = (await _get?.()) ?? $input.checked;
|
||||
$input.checked = checked;
|
||||
});
|
||||
|
||||
return html`<div class="notion-enhancer--menu-toggle shrink-0">
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
import { Button } from "../components/Button.mjs";
|
||||
import { Description } from "../components/Description.mjs";
|
||||
import { useState } from "../state.mjs";
|
||||
|
||||
const rectToStyle = (rect) =>
|
||||
["width", "height", "top", "bottom", "left", "right"]
|
||||
@ -63,10 +64,8 @@ function Circle(rect) {
|
||||
}
|
||||
|
||||
function Banner() {
|
||||
const { html, enhancerVersion } = globalThis.__enhancerApi;
|
||||
// todo: show popup if update available
|
||||
return html`<section class="notion-enhancer--menu-banner">
|
||||
<div
|
||||
const { html, version, initDatabase } = globalThis.__enhancerApi,
|
||||
$welcome = html`<div
|
||||
class="relative flex overflow-hidden h-[192px] rounded-t-[4px]
|
||||
border-(& purple-400) bg-purple-500 from-white/20 to-transparent
|
||||
text-white bg-[linear-gradient(225deg,var(--tw-gradient-stops))]"
|
||||
@ -83,8 +82,10 @@ function Banner() {
|
||||
class="z-10 pl-[32px] md:pl-[48px] lg:pl-[64px]
|
||||
font-bold leading-tight tracking-tight my-auto"
|
||||
>
|
||||
<span class="text-[26px]">Welcome to</span><br />
|
||||
<span class="text-[28px]">the notion-enhancer</span>
|
||||
<a href="https://notion-enhancer.github.io/">
|
||||
<span class="text-[26px]">Welcome to</span><br />
|
||||
<span class="text-[28px]">the notion-enhancer</span>
|
||||
</a>
|
||||
</h1>
|
||||
|
||||
<div
|
||||
@ -92,15 +93,18 @@ function Banner() {
|
||||
pr-[32px] md:pr-[48px] lg:pr-[64px] pb-[24px]"
|
||||
>
|
||||
<i class="i-notion-enhancer text-[42px] mx-auto mb-[8px]"></i>
|
||||
<span
|
||||
class="text-[12px] py-[2px] px-[6px]
|
||||
<a
|
||||
href="https://github.com/notion-enhancer/notion-enhancer/releases/tag/v${version}"
|
||||
>
|
||||
<span
|
||||
class="text-[12px] py-[2px] px-[6px]
|
||||
font-medium leading-tight tracking-wide"
|
||||
>v${enhancerVersion}
|
||||
</span>
|
||||
>v${version}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
</div>`,
|
||||
$sponsorship = html`<div
|
||||
class="py-[18px] px-[16px] rounded-b-[4px]
|
||||
border-(& [color:var(--theme--fg-border)]) bg-[color:var(--theme--bg-secondary)]"
|
||||
>
|
||||
@ -135,7 +139,20 @@ function Banner() {
|
||||
join the server <a href="https://discord.gg/sFWPXtA">here</a> and follow
|
||||
the instructions in the <b>#welcome</b> channel.
|
||||
<//>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
initDatabase()
|
||||
.get("agreedToTerms")
|
||||
.then((agreedToTerms) => {
|
||||
// only show sponsorship if already agree to terms
|
||||
// and opening menu after having reloaded since agreeing
|
||||
$welcome.style.borderRadius = agreedToTerms === version ? "" : "4px";
|
||||
$sponsorship.style.display = agreedToTerms === version ? "" : "none";
|
||||
});
|
||||
|
||||
// todo: show popup if update available
|
||||
return html`<section class="notion-enhancer--menu-banner">
|
||||
${$welcome}${$sponsorship}
|
||||
</section>`;
|
||||
}
|
||||
|
||||
|
@ -1,40 +0,0 @@
|
||||
/**
|
||||
* notion-enhancer
|
||||
* (c) 2023 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
import { Heading } from "../components/Heading.mjs";
|
||||
import { Description } from "../components/Description.mjs";
|
||||
import { Checkbox } from "../components/Checkbox.mjs";
|
||||
import { Option } from "./Options.mjs";
|
||||
|
||||
const privacyPolicy = "https://notion-enhancer.github.io/about/privacy-policy/",
|
||||
tsAndCs = "https://notion-enhancer.github.io/about/terms-and-conditions/";
|
||||
|
||||
function GetStarted() {
|
||||
const { html } = globalThis.__enhancerApi;
|
||||
|
||||
return html`
|
||||
<${Heading}>Get Started <i class="i-arrow-right"></i><//>
|
||||
|
||||
<div class="flex items-center my-[14px] gap-[8px]">
|
||||
<${Checkbox}
|
||||
...${{ _get: () => Promise.resolve(true), _set: () => {} }}
|
||||
onchange=${(event) => (event.target.checked = true)}
|
||||
/>
|
||||
<p class="typography text-[14px]">
|
||||
I have read and agreed to the
|
||||
<a class="mx-[4px]" href=${privacyPolicy}>Privacy Policy</a>
|
||||
and <a href=${tsAndCs}>Terms & Conditions</a>.
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
export { GetStarted };
|
||||
|
||||
// - deidentified / anonymous
|
||||
// - once a week
|
||||
// - privacy policy
|
||||
// - learn how the notion-enhancer is used and what parts need focusing on
|
96
src/core/menu/islands/Onboarding.mjs
Normal file
96
src/core/menu/islands/Onboarding.mjs
Normal file
@ -0,0 +1,96 @@
|
||||
/**
|
||||
* notion-enhancer
|
||||
* (c) 2023 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||
* (https://notion-enhancer.github.io/) under the MIT license
|
||||
*/
|
||||
|
||||
import { Heading } from "../components/Heading.mjs";
|
||||
import { Description } from "../components/Description.mjs";
|
||||
import { Checkbox } from "../components/Checkbox.mjs";
|
||||
import { Button } from "../components/Button.mjs";
|
||||
import { Tile } from "../components/Tile.mjs";
|
||||
import { setState, useState } from "../state.mjs";
|
||||
|
||||
const privacyPolicy = "https://notion-enhancer.github.io/about/privacy-policy/",
|
||||
tsAndCs = "https://notion-enhancer.github.io/about/terms-and-conditions/";
|
||||
|
||||
function Onboarding() {
|
||||
const { html, version, initDatabase } = globalThis.__enhancerApi,
|
||||
$submitAgreement = html`<${Button}
|
||||
icon="arrow-right"
|
||||
class="ml-auto"
|
||||
disabled
|
||||
>Continue
|
||||
<//>`,
|
||||
$agreeToTerms = html`<div class="mt-[32px]">
|
||||
<${Description}>
|
||||
Thanks for installing the notion-enhancer! It's been absolutely
|
||||
incredible to see how the notion-enhancer has grown from small
|
||||
beginnings to something used today by over 11,000 people around the
|
||||
world, now including you. Before you begin, please read the privacy
|
||||
policy to learn how the notion-enhancer uses your data and the terms &
|
||||
conditions to understand what the notion-enhancer does and does not
|
||||
offer. Ticking the box below and pressing <mark>Continue</mark> will
|
||||
unlock the notion-enhancer's full functionality, accessible through the
|
||||
sidebar.
|
||||
<//>
|
||||
<div class="flex items-center my-[14px] gap-[8px]">
|
||||
<${Checkbox}
|
||||
_set=${(checked) => ($submitAgreement.disabled = !checked)}
|
||||
/>
|
||||
<p class="typography text-[14px] mr-[16px]">
|
||||
I have read and agree to the
|
||||
<a class="mx-[4px]" href=${privacyPolicy}>Privacy Policy</a>
|
||||
and <a href=${tsAndCs}>Terms & Conditions</a>.
|
||||
</p>
|
||||
${$submitAgreement}
|
||||
</div>
|
||||
</div>`;
|
||||
$submitAgreement.onclick = async () => {
|
||||
if ($submitAgreement.disabled) return;
|
||||
await initDatabase().set("agreedToTerms", version);
|
||||
setState({ rerender: true });
|
||||
};
|
||||
|
||||
const $regularGreeting = html`<div
|
||||
class="mt-[32px] grid-(& rows-2 cols-2) gap-[16px]"
|
||||
>
|
||||
<${Tile}
|
||||
href="https://notion-enhancer.github.io/getting-started/basic-usage/"
|
||||
icon="graduation-cap"
|
||||
title="Stuck?"
|
||||
>
|
||||
Check out the basic usage guide.
|
||||
<//>
|
||||
<${Tile}
|
||||
href="https://notion-enhancer.github.io/getting-started/basic-usage/"
|
||||
icon="package-plus"
|
||||
title="Something missing?"
|
||||
>
|
||||
Build your first extension.
|
||||
<//>
|
||||
<${Tile}
|
||||
href="https://github.com/notion-enhancer/notion-enhancer/issues/new?template=BUG_REPORT.md"
|
||||
icon="bug"
|
||||
title="Something not working?"
|
||||
>
|
||||
Report a bug.
|
||||
<//>
|
||||
<${Tile}
|
||||
href="https://discord.gg/sFWPXtA"
|
||||
icon="help-circle"
|
||||
title="Got questions?"
|
||||
>
|
||||
Join the community.
|
||||
<//>
|
||||
</div>`;
|
||||
useState(["rerender"], async () => {
|
||||
const agreedToTerms = await initDatabase().get("agreedToTerms");
|
||||
$agreeToTerms.style.display = agreedToTerms === version ? "none" : "";
|
||||
$regularGreeting.style.display = agreedToTerms === version ? "" : "none";
|
||||
});
|
||||
|
||||
return html`${$agreeToTerms}${$regularGreeting}`;
|
||||
}
|
||||
|
||||
export { Onboarding };
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
import { extendProps, setState, useState } from "../state.mjs";
|
||||
import { Description } from "../components/Description.mjs";
|
||||
|
||||
function SidebarHeading({}, ...children) {
|
||||
const { html } = globalThis.__enhancerApi;
|
||||
@ -19,10 +20,10 @@ function SidebarHeading({}, ...children) {
|
||||
|
||||
function SidebarButton({ id, icon, ...props }, ...children) {
|
||||
const { html } = globalThis.__enhancerApi,
|
||||
$btn = html`<${props.href ? "a" : "button"}
|
||||
class="flex select-none cursor-pointer w-full
|
||||
items-center py-[5px] px-[15px] text-[14px] last:mb-[12px]
|
||||
transition hover:bg-[color:var(--theme--bg-hover)]"
|
||||
$btn = html`<${props["href"] ? "a" : "button"}
|
||||
class="flex items-center select-none text-[14px]
|
||||
py-[5px] px-[15px] last:mb-[12px] w-full transition
|
||||
hover:bg-[color:var(--theme--bg-hover)] disabled:hidden"
|
||||
...${props}
|
||||
>
|
||||
${icon
|
||||
@ -35,7 +36,7 @@ function SidebarButton({ id, icon, ...props }, ...children) {
|
||||
<span class="leading-[20px]">${children}</span>
|
||||
<//>`;
|
||||
|
||||
if (!props.href) {
|
||||
if (!props["href"]) {
|
||||
extendProps($btn, {
|
||||
onclick: () => setState({ transition: "fade", view: id }),
|
||||
});
|
||||
@ -49,18 +50,39 @@ function SidebarButton({ id, icon, ...props }, ...children) {
|
||||
}
|
||||
|
||||
function Sidebar({ items, categories }) {
|
||||
const { html, isEnabled } = globalThis.__enhancerApi,
|
||||
const { html, version } = globalThis.__enhancerApi,
|
||||
{ initDatabase, isEnabled } = globalThis.__enhancerApi,
|
||||
$agreeToUnlock = html`<span
|
||||
class="pt-[2px] pb-[5px] px-[15px]
|
||||
inline-block text-[color:var(--theme--fg-red)]"
|
||||
>To unlock the notion-enhancer's full functionality, agree to the privacy
|
||||
policy and terms & conditions on the welcome page.
|
||||
</span>`,
|
||||
$sidebar = html`<aside
|
||||
class="notion-enhancer--menu-sidebar h-full row-span-1
|
||||
overflow-y-auto bg-[color:var(--theme--bg-secondary)]"
|
||||
class="notion-enhancer--menu-sidebar flex flex-col row-span-1
|
||||
h-full overflow-y-auto bg-[color:var(--theme--bg-secondary)]"
|
||||
>
|
||||
${items.map((item) => {
|
||||
if (typeof item === "object") {
|
||||
if (Array.isArray(item)) {
|
||||
const [title, desc] = Array.isArray(item) ? item : [item];
|
||||
return html`
|
||||
<${SidebarHeading}>${title}<//>
|
||||
<${Description}>${desc}<//>
|
||||
`;
|
||||
} else if (typeof item === "object") {
|
||||
const { title, ...props } = item;
|
||||
return html`<${SidebarButton} ...${props}>${title}<//>`;
|
||||
} else return html`<${SidebarHeading}>${item}<//>`;
|
||||
})}
|
||||
})}${$agreeToUnlock}
|
||||
</aside>`;
|
||||
useState(["rerender"], async () => {
|
||||
const agreedToTerms = await initDatabase().get("agreedToTerms");
|
||||
$agreeToUnlock.style.display = agreedToTerms === version ? "none" : "";
|
||||
[...$sidebar.children].forEach(($btn) => {
|
||||
if (!$btn.disableUntilAgreedToTerms) return;
|
||||
$btn.disabled = agreedToTerms !== version;
|
||||
});
|
||||
});
|
||||
|
||||
for (const { title, mods } of categories) {
|
||||
const $title = html`<${SidebarHeading}>${title}<//>`,
|
||||
@ -73,10 +95,8 @@ function Sidebar({ items, categories }) {
|
||||
useState(["rerender"], async () => {
|
||||
let sectionVisible = false;
|
||||
for (const [id, $btn] of $mods) {
|
||||
if (await isEnabled(id)) {
|
||||
$btn.style.display = "";
|
||||
sectionVisible = true;
|
||||
} else $btn.style.display = "none";
|
||||
$btn.disabled = !(await isEnabled(id));
|
||||
sectionVisible ||= !$btn.disabled;
|
||||
}
|
||||
$title.style.display = sectionVisible ? "" : "none";
|
||||
});
|
||||
|
@ -9,7 +9,7 @@ import { Option } from "./Options.mjs";
|
||||
|
||||
const privacyPolicy = "https://notion-enhancer.github.io/about/privacy-policy/";
|
||||
function Telemetry() {
|
||||
const { html, platform, getMods } = globalThis.__enhancerApi,
|
||||
const { html, platform, version, getMods } = globalThis.__enhancerApi,
|
||||
{ getProfile, isEnabled, initDatabase } = globalThis.__enhancerApi,
|
||||
timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
|
||||
@ -36,13 +36,14 @@ function Telemetry() {
|
||||
return html`<${Option}
|
||||
type="toggle"
|
||||
label="Telemetry"
|
||||
description=${html`If telemetry is enabled, basic usage data will be
|
||||
collected at a regular interval from your device in order to better
|
||||
understand how and where the notion-enhancer is used. This data is
|
||||
anonymous and includes only your platform (<code>"${platform}"</code>),
|
||||
timezone (<code>"${timezone}"</code>) and enabled mods (${$enabledMods}).
|
||||
You can opt in or out of telemetry at any time. For more information,
|
||||
please read the <a href=${privacyPolicy}>privacy policy</a>.`}
|
||||
description=${html`If telemetry is enabled, usage data will be collected
|
||||
once a week from your device in order to better understand how and where
|
||||
the notion-enhancer is used. This data is anonymous and includes only your
|
||||
platform (<code>"${platform}"</code>), timezone
|
||||
(<code>"${timezone}"</code>), notion-enhancer version
|
||||
(<code>"${version}"</code>), and enabled mods (${$enabledMods}). You can
|
||||
opt in or out of telemetry at any time. For more information, read the
|
||||
notion-enhancer's <a href=${privacyPolicy}>privacy policy</a>.`}
|
||||
...${{ _get, _set }}
|
||||
/>`;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import { setState, useState } from "./state.mjs";
|
||||
import { Sidebar } from "./islands/Sidebar.mjs";
|
||||
import { Footer } from "./islands/Footer.mjs";
|
||||
import { Banner } from "./islands/Banner.mjs";
|
||||
import { Onboarding } from "./islands/Onboarding.mjs";
|
||||
import { Telemetry } from "./islands/Telemetry.mjs";
|
||||
import { View } from "./islands/View.mjs";
|
||||
import { List } from "./islands/List.mjs";
|
||||
@ -73,13 +74,19 @@ const categories = [
|
||||
id: "core",
|
||||
title: "Core",
|
||||
icon: "sliders-horizontal",
|
||||
disableUntilAgreedToTerms: true,
|
||||
},
|
||||
...categories.map((c) => ({ id: c.id, title: c.title, icon: c.icon })),
|
||||
...categories.map((c) => ({
|
||||
id: c.id,
|
||||
title: c.title,
|
||||
icon: c.icon,
|
||||
disableUntilAgreedToTerms: true,
|
||||
})),
|
||||
];
|
||||
|
||||
const render = async () => {
|
||||
const { html, platform } = globalThis.__enhancerApi,
|
||||
{ getMods, isEnabled, setEnabled } = globalThis.__enhancerApi,
|
||||
const { html, getMods } = globalThis.__enhancerApi,
|
||||
{ isEnabled, setEnabled } = globalThis.__enhancerApi,
|
||||
[icon, renderStarted] = useState(["icon", "renderStarted"]);
|
||||
if (!html || !getMods || !icon || renderStarted) return;
|
||||
if (icon === "Monochrome") sidebar[1].icon += "?mask";
|
||||
@ -117,7 +124,10 @@ const render = async () => {
|
||||
<!-- wrappers necessary for transitions and breakpoints -->
|
||||
<div class="grow overflow-auto">
|
||||
<div class="relative h-full w-full">
|
||||
<${View} id="welcome"><${Banner} /><//>
|
||||
<${View} id="welcome">
|
||||
<${Banner} />
|
||||
<${Onboarding} />
|
||||
<//>
|
||||
<${View} id="core">
|
||||
<${Options} mod=${mods.find(({ _src }) => _src === "core")} />
|
||||
<${Telemetry} />
|
||||
|
Loading…
Reference in New Issue
Block a user