mirror of
				https://github.com/notion-enhancer/notion-enhancer.git
				synced 2025-10-31 06:08:09 +11: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
 | ||||
|  */ | ||||
| 
 | ||||
| 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`<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; | ||||
| } | ||||
| 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`<b>0</b>`, | ||||
|     $characterCount = html`<b>0</b>`, | ||||
|     $sentenceCount = html`<b>0</b>`, | ||||
|     $blockCount = html`<b>0</b>`, | ||||
|     $readingTime = html`<b>${humanTime(0)}</b>`, | ||||
|     $speakingTime = html`<b>${humanTime(0)}</b>`, | ||||
|     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`<section>
 | ||||
|       <p | ||||
|         class="py-[12px] px-[18px] | ||||
|         text-([color:var(--theme--fg-secondary)] [13px])" | ||||
|       > | ||||
|         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<//>
 | ||||
|       <${PanelDescription}>Click on a stat to copy it.<//>
 | ||||
|       ${$wordCount}${$characterCount}${$sentenceCount}${$blockCount} | ||||
|       ${$readingTime}${$speakingTime} | ||||
|     </section>`, | ||||
|   }); | ||||
| 
 | ||||
| @ -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(); | ||||
|  | ||||
							
								
								
									
										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