diff --git a/src/extensions/word-counter/client.mjs b/src/extensions/word-counter/client.mjs index 42e1f25..33d639f 100644 --- a/src/extensions/word-counter/client.mjs +++ b/src/extensions/word-counter/client.mjs @@ -4,65 +4,38 @@ * (https://notion-enhancer.github.io/) under the MIT license */ -const humanTime = (mins) => { - let readable = ""; - if (1 <= mins || !mins) { - readable += `${Math.floor(mins)} min`; - if (2 <= mins) readable += "s"; - } - const secs = Math.round((mins % 1) * 60); - if (1 <= secs) { - if (1 <= mins) readable += " "; - readable += `${secs} sec`; - if (2 <= secs) readable += "s"; - } - return readable; -}; - -function Stat(props, ...children) { - const { html } = globalThis.__enhancerApi, - $stat = html`
- ${children} -
`; - $stat.addEventListener("click", () => { - navigator.clipboard.writeText($stat.innerText); - }); - return $stat; -} +import { Stat } from "./islands/Stat.mjs"; +import { PanelDescription } from "../outliner/islands/PanelDescription.mjs"; export default async (api, db) => { const { html, debounce, addMutationListener, addPanelView } = api, readingSpeed = await db.get("readingSpeed"), speakingSpeed = await db.get("speakingSpeed"), - $wordCount = html`0`, - $characterCount = html`0`, - $sentenceCount = html`0`, - $blockCount = html`0`, - $readingTime = html`${humanTime(0)}`, - $speakingTime = html`${humanTime(0)}`, - page = ".notion-page-content"; + page = ".notion-page-content", + humanReadableTime = (mins) => { + let readable = ""; + if (isNaN(mins)) mins = 0; + const secs = Math.round((mins % 1) * 60); + mins = Math.floor(mins); + if (mins) readable = `${mins} min${mins === 1 ? "" : "s"}`; + if (secs && mins) readable += " "; + if (secs || !mins) readable += `${secs} sec${secs === 1 ? "" : "s"}`; + return readable; + }; + + const $wordCount = html`<${Stat} unit="word" countable />`, + $characterCount = html`<${Stat} unit="character" countable />`, + $sentenceCount = html`<${Stat} unit="sentence" countable />`, + $blockCount = html`<${Stat} unit="block" countable />`, + $readingTime = html`<${Stat} unit="reading time" />`, + $speakingTime = html`<${Stat} unit="speaking time" />`; addPanelView({ title: "Word Counter", $icon: "type", $view: html`
-

- Click on a stat to copy it. -

- <${Stat}>${$wordCount} words - <${Stat}>${$characterCount} characters - <${Stat}>${$sentenceCount} sentences - <${Stat}>${$blockCount} blocks - <${Stat}>${$readingTime} reading time - <${Stat}>${$speakingTime} speaking time + <${PanelDescription}>Click on a stat to copy it. + ${$wordCount}${$characterCount}${$sentenceCount}${$blockCount} + ${$readingTime}${$speakingTime}
`, }); @@ -71,13 +44,15 @@ export default async (api, db) => { if (!document.contains($page)) $page = document.querySelector(page); if (!$page) return; const text = $page.innerText, - words = text.split(/[^\w]+/).length; - $wordCount.innerText = words; - $characterCount.innerText = text.length; - $sentenceCount.innerText = text.split(".").filter((s) => s.trim()).length; - $blockCount.innerText = $page.querySelectorAll("[data-block-id]").length; - $readingTime.innerText = humanTime(words / readingSpeed); - $speakingTime.innerText = humanTime(words / speakingSpeed); + words = text.split(/[^\w]+/).length, + sentences = text.split(".").filter((s) => s.trim()).length, + blocks = $page.querySelectorAll("[data-block-id]").length; + $wordCount.setCount(words); + $characterCount.setCount(text.length); + $sentenceCount.setCount(sentences); + $blockCount.setCount(blocks); + $readingTime.setCount(humanReadableTime(words / readingSpeed)); + $speakingTime.setCount(humanReadableTime(words / speakingSpeed)); }); addMutationListener(page, updateStats); updateStats(); diff --git a/src/extensions/word-counter/islands/Stat.mjs b/src/extensions/word-counter/islands/Stat.mjs new file mode 100644 index 0000000..955166a --- /dev/null +++ b/src/extensions/word-counter/islands/Stat.mjs @@ -0,0 +1,31 @@ +/** + * notion-enhancer: word-counter + * (c) 2024 dragonwocky (https://dragonwocky.me/) + * (https://notion-enhancer.github.io/) under the MIT license + */ + +function Stat({ unit, countable, ...props }, ...children) { + const { html } = globalThis.__enhancerApi, + $count = html``, + $unit = html``, + $stat = html`

+ ${$count} ${$unit} +

`; + $stat.setCount = (count) => { + $count.innerText = count; + const pluralise = countable && typeof count === "number" && count !== 1; + $unit.innerText = pluralise ? `${unit}s` : unit; + }; + $stat.addEventListener("click", () => { + navigator.clipboard.writeText($stat.innerText); + }); + return $stat; +} + +export { Stat };