Skip to content

Commit 1607f54

Browse files
authored
Add reading time estimation and remove character counter (#48)
1 parent 3086a88 commit 1607f54

2 files changed

Lines changed: 25 additions & 8 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ A clean, distraction-free text editor for focused writing.
1414
- **Focus on your writing** – The interface fades away as you type.
1515
- **Comfort for your eyes** – Light and dark themes for any time of day.
1616
- **Never lose your work** – Auto-save in your browser.
17-
- **Know your progress** – Built-in word and character count.
17+
- **Know your progress** – Built-in word count and reading time estimator.
1818
- **Take your words with you** – Export locally anytime.
1919
- **Go all in** – Full-screen mode.
2020
- **Respects your privacy** – No accounts, no tracking, no cookies.

index.html

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -388,25 +388,41 @@
388388
return content.trim().split(/\s+/).filter(Boolean).length;
389389
}
390390

391+
getReadingTime(wordCount) {
392+
// Average reading speed: 200 words per minute
393+
const wordsPerMinute = 200;
394+
const minutes = Math.ceil(wordCount / wordsPerMinute);
395+
396+
if (minutes === 0) {
397+
return '<1 min';
398+
} else if (minutes < 60) {
399+
return `~${minutes} min${minutes !== 1 ? 's' : ''}`;
400+
} else if (minutes < 1440) {
401+
const hours = Math.ceil(minutes / 60);
402+
return `~${hours} hour${hours !== 1 ? 's' : ''}`;
403+
} else {
404+
const days = Math.ceil(minutes / 1440);
405+
return `~${days} day${days !== 1 ? 's' : ''}`;
406+
}
407+
}
391408
updateCount() {
392409
const text = this.editor.value;
393-
let count, label;
410+
const wordCount = this.getWordsCount(text);
411+
let displayText;
394412

395413
if (this.countMode === 'words') {
396-
count = this.getWordsCount(text);
397-
label = `word${count !== 1 ? 's' : ''}`;
414+
displayText = `${wordCount} word${wordCount !== 1 ? 's' : ''}`;
398415
} else {
399-
count = text.length;
400-
label = `character${count !== 1 ? 's' : ''}`;
416+
displayText = this.getReadingTime(wordCount);
401417
}
402418

403-
this.countDisplay.textContent = `${count} ${label}`;
419+
this.countDisplay.textContent = displayText;
404420
}
405421

406422
toggleCountMode() {
407423
this.countDisplay.style.opacity = '0';
408424
setTimeout(() => {
409-
this.countMode = this.countMode === 'words' ? 'characters' : 'words';
425+
this.countMode = this.countMode === 'words' ? 'reading' : 'words';
410426
localStorage.setItem(SHIRO_COUNT_MODE, this.countMode);
411427
this.updateCount();
412428
this.countDisplay.style.opacity = '1';
@@ -422,6 +438,7 @@
422438

423439
show() {
424440
if (!this.visible) {
441+
this.updateCount();
425442
this.controls.forEach(c => c.classList.remove('hidden'));
426443
this.visible = true;
427444
}

0 commit comments

Comments
 (0)