-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
120 lines (98 loc) · 4.21 KB
/
script.js
File metadata and controls
120 lines (98 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// DOM Elements
const bookSelector = document.getElementById('book-selector');
const startBtn = document.getElementById('start-btn');
const finishBtn = document.getElementById('finish-btn');
const readingArea = document.getElementById('reading-area');
const readingContent = document.getElementById('reading-content');
const welcomeScreen = document.getElementById('welcome-screen');
const resultsOverlay = document.getElementById('results-overlay');
const wpmDisplay = document.getElementById('wpm-val');
const timeVal = document.getElementById('time-val');
const wordsVal = document.getElementById('words-val');
const restartBtn = document.getElementById('restart-btn');
let startTime = 0;
let timerInterval = null;
// Initialize
function init() {
// Populate selector
// Use global variable cosmereData
if (typeof cosmereData !== 'undefined') {
cosmereData.forEach(book => {
const option = document.createElement('option');
option.value = book.id;
option.textContent = book.title;
bookSelector.appendChild(option);
});
}
// Event Listeners
startBtn.addEventListener('click', startTest);
finishBtn.addEventListener('click', finishTest);
restartBtn.addEventListener('click', resetTest);
}
function startTest() {
const selectedId = bookSelector.value;
const book = cosmereData.find(b => b.id == selectedId);
if (!book) return;
// Load content
// Format text with paragraph tags for better reading
const paragraphs = book.fragment.split('\n\n').map(p => `<p style="margin-bottom: 1.5em;">${p}</p>`).join('');
readingContent.innerHTML = paragraphs;
// UI Transition
welcomeScreen.classList.add('hidden');
readingArea.style.display = 'flex';
readingArea.classList.add('fade-in');
// Controls
startBtn.style.display = 'none';
bookSelector.disabled = true;
// Add floating finish button to bottom right or keep sticky header?
// For now, let's inject a finish button at the bottom of the text as well for convenience
const bottomBtn = document.createElement('button');
bottomBtn.textContent = 'Terminar Lectura';
bottomBtn.style.cssText = "display: block; margin: 2rem auto; width: 100%; max-width: 300px;";
bottomBtn.onclick = finishTest;
readingContent.appendChild(bottomBtn);
// Start Timer
startTime = performance.now();
// Reset scroll
readingArea.scrollTop = 0;
}
function finishTest() {
const endTime = performance.now();
const timeInSeconds = (endTime - startTime) / 1000;
const timeInMinutes = timeInSeconds / 60;
// Word Count
// Use a robust split but exclude empty strings
const text = readingContent.innerText; // Get text without HTML tags
// Remove the button text from the count check logic if needed,
// but readingContent.innerText might include 'Terminar Lectura' if we are not careful.
// Let's count from the source data instead to be accurate.
const selectedId = bookSelector.value;
const book = cosmereData.find(b => b.id == selectedId);
const wordCount = book.fragment.trim().split(/\s+/).length;
// Validate sane reading time (e.g. if instant click)
if (timeInSeconds < 5) {
alert("¡Has ido demasiado rápido! Lee el texto de verdad.");
return;
}
const wpm = Math.round(wordCount / timeInMinutes);
// Save to local storage (Simple history)
const history = JSON.parse(localStorage.getItem('readingHistory') || '[]');
history.push({ date: new Date().toISOString(), wpm: wpm, book: book.title });
localStorage.setItem('readingHistory', JSON.stringify(history));
// Show Results
wpmDisplay.textContent = wpm;
timeVal.textContent = `${Math.round(timeInSeconds)}s`;
wordsVal.textContent = wordCount;
resultsOverlay.style.display = 'flex';
}
function resetTest() {
resultsOverlay.style.display = 'none';
readingArea.style.display = 'none';
welcomeScreen.classList.remove('hidden');
startBtn.style.display = 'block';
bookSelector.disabled = false;
// Clear dynamic content
readingContent.innerHTML = '';
}
// Run
init();