mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-10 15:39:01 +00:00
fix(word-counter): handle singular vs. plural stats appropriately
This commit is contained in:
parent
44c480062b
commit
951b199b54
@ -4,65 +4,38 @@
|
|||||||
* (https://notion-enhancer.github.io/) under the MIT license
|
* (https://notion-enhancer.github.io/) under the MIT license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const humanTime = (mins) => {
|
import { Stat } from "./islands/Stat.mjs";
|
||||||
let readable = "";
|
import { PanelDescription } from "../outliner/islands/PanelDescription.mjs";
|
||||||
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`<div
|
|
||||||
role="button"
|
|
||||||
class="select-none cursor-pointer rounded-[3px]
|
|
||||||
transition hover:bg-[color:var(--theme--bg-hover)]
|
|
||||||
text-[14px] my-[6px] mx-[12px] py-[2px] px-[10px]"
|
|
||||||
...${props}
|
|
||||||
>
|
|
||||||
${children}
|
|
||||||
</div>`;
|
|
||||||
$stat.addEventListener("click", () => {
|
|
||||||
navigator.clipboard.writeText($stat.innerText);
|
|
||||||
});
|
|
||||||
return $stat;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async (api, db) => {
|
export default async (api, db) => {
|
||||||
const { html, debounce, addMutationListener, addPanelView } = api,
|
const { html, debounce, addMutationListener, addPanelView } = api,
|
||||||
readingSpeed = await db.get("readingSpeed"),
|
readingSpeed = await db.get("readingSpeed"),
|
||||||
speakingSpeed = await db.get("speakingSpeed"),
|
speakingSpeed = await db.get("speakingSpeed"),
|
||||||
$wordCount = html`<b>0</b>`,
|
page = ".notion-page-content",
|
||||||
$characterCount = html`<b>0</b>`,
|
humanReadableTime = (mins) => {
|
||||||
$sentenceCount = html`<b>0</b>`,
|
let readable = "";
|
||||||
$blockCount = html`<b>0</b>`,
|
if (isNaN(mins)) mins = 0;
|
||||||
$readingTime = html`<b>${humanTime(0)}</b>`,
|
const secs = Math.round((mins % 1) * 60);
|
||||||
$speakingTime = html`<b>${humanTime(0)}</b>`,
|
mins = Math.floor(mins);
|
||||||
page = ".notion-page-content";
|
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({
|
addPanelView({
|
||||||
title: "Word Counter",
|
title: "Word Counter",
|
||||||
$icon: "type",
|
$icon: "type",
|
||||||
$view: html`<section>
|
$view: html`<section>
|
||||||
<p
|
<${PanelDescription}>Click on a stat to copy it.<//>
|
||||||
class="py-[12px] px-[18px]
|
${$wordCount}${$characterCount}${$sentenceCount}${$blockCount}
|
||||||
text-([color:var(--theme--fg-secondary)] [13px])"
|
${$readingTime}${$speakingTime}
|
||||||
>
|
|
||||||
Click on a stat to copy it.
|
|
||||||
</p>
|
|
||||||
<${Stat}>${$wordCount} words<//>
|
|
||||||
<${Stat}>${$characterCount} characters<//>
|
|
||||||
<${Stat}>${$sentenceCount} sentences<//>
|
|
||||||
<${Stat}>${$blockCount} blocks<//>
|
|
||||||
<${Stat}>${$readingTime} reading time<//>
|
|
||||||
<${Stat}>${$speakingTime} speaking time<//>
|
|
||||||
</section>`,
|
</section>`,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -71,13 +44,15 @@ export default async (api, db) => {
|
|||||||
if (!document.contains($page)) $page = document.querySelector(page);
|
if (!document.contains($page)) $page = document.querySelector(page);
|
||||||
if (!$page) return;
|
if (!$page) return;
|
||||||
const text = $page.innerText,
|
const text = $page.innerText,
|
||||||
words = text.split(/[^\w]+/).length;
|
words = text.split(/[^\w]+/).length,
|
||||||
$wordCount.innerText = words;
|
sentences = text.split(".").filter((s) => s.trim()).length,
|
||||||
$characterCount.innerText = text.length;
|
blocks = $page.querySelectorAll("[data-block-id]").length;
|
||||||
$sentenceCount.innerText = text.split(".").filter((s) => s.trim()).length;
|
$wordCount.setCount(words);
|
||||||
$blockCount.innerText = $page.querySelectorAll("[data-block-id]").length;
|
$characterCount.setCount(text.length);
|
||||||
$readingTime.innerText = humanTime(words / readingSpeed);
|
$sentenceCount.setCount(sentences);
|
||||||
$speakingTime.innerText = humanTime(words / speakingSpeed);
|
$blockCount.setCount(blocks);
|
||||||
|
$readingTime.setCount(humanReadableTime(words / readingSpeed));
|
||||||
|
$speakingTime.setCount(humanReadableTime(words / speakingSpeed));
|
||||||
});
|
});
|
||||||
addMutationListener(page, updateStats);
|
addMutationListener(page, updateStats);
|
||||||
updateStats();
|
updateStats();
|
||||||
|
31
src/extensions/word-counter/islands/Stat.mjs
Normal file
31
src/extensions/word-counter/islands/Stat.mjs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* notion-enhancer: word-counter
|
||||||
|
* (c) 2024 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||||
|
* (https://notion-enhancer.github.io/) under the MIT license
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Stat({ unit, countable, ...props }, ...children) {
|
||||||
|
const { html } = globalThis.__enhancerApi,
|
||||||
|
$count = html`<b></b>`,
|
||||||
|
$unit = html`<span></span>`,
|
||||||
|
$stat = html`<p
|
||||||
|
role="button"
|
||||||
|
class="select-none cursor-pointer rounded-[3px]
|
||||||
|
transition hover:bg-[color:var(--theme--bg-hover)]
|
||||||
|
text-[14px] my-[6px] mx-[12px] py-[2px] px-[10px]"
|
||||||
|
...${props}
|
||||||
|
>
|
||||||
|
${$count} ${$unit}
|
||||||
|
</p>`;
|
||||||
|
$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 };
|
Loading…
Reference in New Issue
Block a user