-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathspeaking_test2_archived.html
More file actions
230 lines (198 loc) · 11.2 KB
/
speaking_test2_archived.html
File metadata and controls
230 lines (198 loc) · 11.2 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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Speaking Test Simulation</title>
<link rel="stylesheet" href="css/style.css">
<link href="https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:wght@400;500;700&display=swap" rel="stylesheet">
<link rel="icon" href="img/favicon.png" type="image/x-icon">
</head>
<body>
<header id="header-placeholder"></header>
<div class="content-pusher">
<div class="container">
<div class="test-simulation-wrapper">
<!-- Màn hình bắt đầu -->
<div id="start-screen" class="test-screen active">
<h1>Mô phỏng bài thi Speaking</h1>
<p>Bài thi sẽ chạy tự động qua 4 phần. Bạn sẽ không thể tạm dừng.</p>
<p>Hãy chuẩn bị sẵn micro hoặc điện thoại để ghi âm lại phần trả lời của bạn.</p>
<button class="action-btn" id="start-test-btn">Bắt đầu bài thi</button>
</div>
<!-- Màn hình làm bài -->
<div id="test-screen" class="test-screen">
<h2 id="part-indicator"></h2>
<p id="task-indicator"></p>
<div id="question-area">
<!-- Nội dung câu hỏi/hình ảnh sẽ được chèn vào đây -->
</div>
<div id="timer-area">
<div id="timer-label"></div>
<div id="timer-display"></div>
<div class="progress-bar-container">
<div id="progress-bar"></div>
</div>
<!-- THÊM NÚT MỚI VÀO ĐÂY -->
<button class="action-btn" id="next-btn" style="margin-top: 15px; display: none;">Next Question
➡️</button>
</div>
</div>
<!-- Màn hình kết thúc (ĐÃ NÂNG CẤP) -->
<div id="end-screen" class="test-screen">
<h1>Bài thi đã kết thúc!</h1>
<p>Chúc mừng bạn đã hoàn thành bài thi mô phỏng.</p>
<!-- Tái sử dụng giao diện của explanation-box -->
<div class="explanation-box" style="margin-top: 20px; text-align: left;">
<h3>💡 Bước tiếp theo: Tự đánh giá bài làm</h3>
<p>Bây giờ là lúc sử dụng file ghi âm bạn vừa tạo để cải thiện kỹ năng. Hãy làm theo các bước sau:</p>
<ul>
<li><strong>Bước 1:</strong> Nghe lại file ghi âm của bạn.</li>
<li><strong>Bước 2:</strong> So sánh câu trả lời của bạn với các "Câu trả lời mẫu" trong các trang luyện tập riêng lẻ.</li>
<li><strong>Bước 3 (Nâng cao):</strong> Tải file ghi âm (MP3) lên các công cụ AI như Google Gemini, ChatGPT-4o, hoặc các dịch vụ sửa bài nói chuyên dụng để nhận feedback chi tiết về ngữ pháp, phát âm và sự trôi chảy.</li>
</ul>
</div>
<a href="speaking_test.html" class="action-btn" style="margin-top: 20px;">Làm lại bài thi khác</a>
<a href="index.html" class="action-btn-secondary" style="margin-top: 10px;">Quay về trang chủ</a>
</div>
</div>
</div>
<footer id="footer-placeholder"></footer>
</div>
<script src="js/main.js"></script>
<script src="js/data-speaking.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
// Lấy các element
const startScreen = document.getElementById('start-screen');
const testScreen = document.getElementById('test-screen');
const endScreen = document.getElementById('end-screen');
const startBtn = document.getElementById('start-test-btn');
const partIndicator = document.getElementById('part-indicator');
const taskIndicator = document.getElementById('task-indicator');
const questionArea = document.getElementById('question-area');
const timerLabel = document.getElementById('timer-label');
const timerDisplay = document.getElementById('timer-display');
const progressBar = document.getElementById('progress-bar');
const nextBtn = document.getElementById('next-btn'); // Nút mới
// Hàm xáo trộn mảng
const shuffle = (array) => array.sort(() => Math.random() - 0.5);
let timerInterval; // Biến để lưu interval
let forceNext = () => { }; // Hàm để bỏ qua timer
// --- HÀM CHẠY ĐỒNG HỒ ĐƯỢC NÂNG CẤP ---
function runTimer(totalSeconds, showNextButton = false) {
return new Promise(resolve => {
let secondsLeft = totalSeconds;
// Logic của nút Next
forceNext = () => {
clearInterval(timerInterval);
nextBtn.style.display = 'none'; // Ẩn nút đi
resolve();
};
if (showNextButton) {
nextBtn.style.display = 'inline-block'; // Hiện nút Next
} else {
nextBtn.style.display = 'none';
}
// ... (phần code progress bar và hiển thị thời gian giữ nguyên) ...
progressBar.style.transition = 'none';
progressBar.style.width = '100%';
setTimeout(() => {
progressBar.style.transition = `width ${totalSeconds}s linear`;
progressBar.style.width = '0%';
}, 100);
const updateDisplay = () => {
const minutes = Math.floor(secondsLeft / 60);
const seconds = secondsLeft % 60;
timerDisplay.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
};
updateDisplay();
timerInterval = setInterval(() => {
secondsLeft--;
updateDisplay();
if (secondsLeft <= 0) {
forceNext(); // Gọi hàm forceNext khi hết giờ
}
}, 1000);
});
}
// Hàm hiển thị nội dung
function displayContent(part, task, contentHTML) {
partIndicator.textContent = `Part ${part}`;
taskIndicator.textContent = task;
questionArea.innerHTML = contentHTML;
}
// --- Luồng thi chính ---
async function startTest() {
startScreen.classList.remove('active');
testScreen.classList.add('active');
await runPart1();
await runPart2();
await runPart3();
await runPart4();
testScreen.classList.remove('active');
endScreen.classList.add('active');
}
async function runPart1() {
const questions = shuffle([...speakingData.part1]).slice(0, 3);
for (let i = 0; i < questions.length; i++) {
displayContent('1', `Question ${i + 1} of 3`, `<p class="test-question-text">${questions[i].prompt.question}</p>`);
timerLabel.textContent = "Answer the question";
await runTimer(questions[i].prompt.duration, true); // Thêm 'true' để hiện nút Next
}
}
async function runPart2() {
// LỌC BỎ CÁC CHỦ ĐỀ CHẤT LƯỢNG THẤP
const highQualityTopics = speakingData.part2.filter(topic => topic.quality !== 'low');
const topic = shuffle(highQualityTopics)[0];
const imageHTML = `<div class="test-image-container"><img src="${topic.imageSrc}" alt="Image for Part 2"></div>`;
// Sửa ở đây: dùng 'topic.tasks' thay vì 'questions'
for (let i = 0; i < topic.tasks.length; i++) {
const task = topic.tasks[i];
displayContent('2', `Task ${i + 1} of 3`,
`${imageHTML}
<p class="test-question-text">${task.question}</p>`
);
timerLabel.textContent = "Answer the question";
// Sửa ở đây: dùng 'task.duration'
await runTimer(task.duration, true);
}
}
async function runPart3() {
// LỌC BỎ CÁC CHỦ ĐỀ CHẤT LƯỢNG THẤP
const highQualityTopics = speakingData.part3.filter(topic => topic.quality !== 'low');
const topic = shuffle(highQualityTopics)[0];
const imagesHTML = `<div class="test-image-container">
<img src="${topic.image1Src}" alt="Picture 1">
<img src="${topic.image2Src}" alt="Picture 2">
</div>`;
// Sửa ở đây: dùng 'topic.tasks' thay vì 'questions'
for (let i = 0; i < topic.tasks.length; i++) {
const task = topic.tasks[i];
displayContent('3', `Task ${i + 1} of 3`,
`${imagesHTML}
<p class="test-question-text">${task.question}</p>`
);
timerLabel.textContent = "Answer the question";
// Sửa ở đây: dùng 'task.duration'
await runTimer(task.duration, true);
}
}
async function runPart4() {
const topic = shuffle([...speakingData.part4])[0];
let questionsHTML = '<ul>';
topic.tasks.forEach(task => { questionsHTML += `<li>${task.question}</li>`; });
questionsHTML += '</ul>';
displayContent('4', 'Prepare your answer', `<div class="test-part4-questions">${questionsHTML}</div>`);
timerLabel.textContent = "Preparation Time";
await runTimer(60); // Không có nút Next cho thời gian chuẩn bị
displayContent('4', 'Answer all three questions', `<div class="test-part4-questions">${questionsHTML}</div>`);
timerLabel.textContent = "Speaking Time";
await runTimer(120, true); // Có nút Next cho thời gian trả lời
}
startBtn.addEventListener('click', startTest);
nextBtn.addEventListener('click', () => forceNext()); // Nút Next sẽ gọi hàm forceNext
});
</script>
</body>
</html>