Skip to content

Commit 75c0f0d

Browse files
committed
Fix: Limit multiple ratings within a single day.
1 parent bcdd026 commit 75c0f0d

File tree

4 files changed

+139
-81
lines changed

4 files changed

+139
-81
lines changed

src/popup/daily-review.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ function calculateRetrievabilityAverage() {
148148
function updateStats() {
149149
console.log('更新统计信息');
150150
// 设置默认值
151-
const completedCount = 0;
152-
const totalProblems = 0;
151+
let completedCount = 0;
152+
let totalProblems = 0;
153153
// 添加空值检查
154154
if (!daily_store || !daily_store.dailyReviewProblems) {
155155
console.log('daily_store 或 dailyReviewProblems 为空:', {

src/popup/script/leetcode.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { loadConfigs } from "../service/configService";
2-
import { submissionListener,addRecordButton } from "./submission";
2+
import { addRecordButton } from "./submission";
33

44
console.log(`Hello Leetcode-Mastery-Scheduler!`);
55

66
await loadConfigs();
7-
// document.addEventListener('click', submissionListener);
7+
88

99

1010
document.addEventListener('DOMContentLoaded', addRecordButton);

src/popup/script/leetcodecn.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { loadConfigs } from "../service/configService";
2-
import { submissionListener,addRecordButton } from "./submission";
2+
import { addRecordButton } from "./submission";
33

44
console.log(`Hello Leetcode-Mastery-Scheduler!`);
55

66
await loadConfigs();
7-
// document.addEventListener('click', submissionListener);
7+
88

99

1010
document.addEventListener('DOMContentLoaded', addRecordButton);

src/popup/script/submission.js

Lines changed: 133 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2,72 +2,9 @@ import { getDifficultyBasedSteps, getSubmissionResult, isSubmissionSuccess, isSu
22
import { getAllProblems, createOrUpdateProblem, getCurrentProblemInfoFromLeetCodeByHref,getCurrentProblemInfoFromLeetCodeByUrl, syncProblems } from "../service/problemService";
33
import { Problem } from "../entity/problem";
44
import { updateProblemWithFSRS } from "../util/fsrs";
5-
/*
6-
monitorSubmissionResult will repeateadly check for the submission result.
7-
*/
8-
const monitorSubmissionResult = () => {
95

10-
let submissionResult;
11-
let maxRetry = 10;
12-
const retryInterval = 1000;
136

14-
const functionId = setInterval(async () => {
157

16-
if (maxRetry <= 0) {
17-
clearInterval(functionId);
18-
return;
19-
}
20-
21-
submissionResult = getSubmissionResult();
22-
23-
if (submissionResult === undefined || submissionResult.length === 0) {
24-
maxRetry--;
25-
return;
26-
}
27-
28-
clearInterval(functionId);
29-
let isSuccess = isSubmissionSuccess(submissionResult);
30-
31-
if (!isSuccess) return;
32-
33-
const { problemIndex, problemName, problemLevel, problemUrl } = await getCurrentProblemInfoFromLeetCodeByHref();
34-
await syncProblems(); // prior to fetch local problem data, sync local problem data with cloud
35-
const problems = await getAllProblems();
36-
let problem = problems[problemIndex];
37-
38-
if (problem && problem.isDeleted !== true) {
39-
const reviewNeeded = needReview(problem);
40-
if (reviewNeeded) {
41-
await createOrUpdateProblem(updateProblemUponSuccessSubmission(problem));
42-
}
43-
} else {
44-
problem = new Problem(problemIndex, problemName, problemLevel, problemUrl, Date.now(), getDifficultyBasedSteps(problemLevel)[0], Date.now());
45-
await createOrUpdateProblem(problem);
46-
}
47-
await syncProblems(); // after problem updated, sync to cloud
48-
49-
console.log("Submission successfully tracked!");
50-
51-
}, retryInterval)
52-
};
53-
54-
export const submissionListener = (event) => {
55-
56-
const element = event.target;
57-
58-
const filterConditions = [
59-
isSubmitButton(element),
60-
element.parentElement && isSubmitButton(element.parentElement),
61-
element.parentElement && element.parentElement.parentElement && isSubmitButton(element.parentElement.parentElement),
62-
]
63-
64-
const isSubmission = filterConditions.reduce((prev, curr) => prev || curr);
65-
66-
if (isSubmission) {
67-
monitorSubmissionResult();
68-
}
69-
70-
};
718

729

7310

@@ -258,26 +195,45 @@ export async function handleFeedbackSubmission(problem = null) {
258195
return null;
259196
}
260197

261-
// 如果没有传入 problem,说明是新提交,需要获取题目信息
198+
// 如果没有传入 problem,说明是页面提交,需要获取题目信息
262199
if (!problem) {
263200
await syncProblems(); // 同步云端数据
264201
const { problemIndex, problemName, problemLevel, problemUrl } = await getCurrentProblemInfoFromLeetCodeByHref();
265202
const problems = await getAllProblems();
266203
problem = problems[problemIndex];
267204

268-
if (problem && problem.isDeleted !== true) {
269-
problem = updateProblemWithFSRS(problem, feedback);
270-
await createOrUpdateProblem(updateProblemUponSuccessSubmission(problem));
271-
} else {
205+
if (!problem || problem.isDeleted == true) {
272206
problem = new Problem(problemIndex, problemName, problemLevel, problemUrl, Date.now(), getDifficultyBasedSteps(problemLevel)[0], Date.now());
273-
problem = updateProblemWithFSRS(problem, feedback);
274-
await createOrUpdateProblem(problem);
275207
}
276-
} else {
277-
// 如果传入了 problem,说明是复习
278-
problem = updateProblemWithFSRS(problem, feedback);
279-
await createOrUpdateProblem(problem);
280208
}
209+
210+
// 检查上次复习时间是否是今天,如果是则不允许再次复习
211+
if (problem.fsrsState && problem.fsrsState.lastReview) {
212+
const lastReviewDate = new Date(problem.fsrsState.lastReview);
213+
const today = new Date();
214+
215+
// 比较年、月、日是否相同(考虑时区影响)
216+
if (lastReviewDate.getFullYear() === today.getFullYear() &&
217+
lastReviewDate.getMonth() === today.getMonth() &&
218+
lastReviewDate.getDate() === today.getDate()) {
219+
220+
// 显示双语警告提示
221+
showToast("今天已经复习过这道题了,请明天再来!\nYou've already reviewed this problem today. Please come back tomorrow!", "warning");
222+
return null;
223+
}
224+
}
225+
226+
problem = updateProblemWithFSRS(problem, feedback);
227+
await createOrUpdateProblem(problem);
228+
229+
// 计算下次复习时间与今天的天数差
230+
const nextReviewDate = new Date(problem.fsrsState.nextReview);
231+
const today = new Date();
232+
const diffTime = nextReviewDate.getTime() - today.getTime();
233+
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
234+
235+
// 显示复习成功提示,包含下次复习时间
236+
showToast(`复习成功!下次复习时间:${nextReviewDate.toLocaleDateString()}${diffDays}天后)\nReview successful! Next review: ${nextReviewDate.toLocaleDateString()} (in ${diffDays} days)`, "success");
281237

282238
await syncProblems(); // 同步到云端
283239
console.log("提交成功!");
@@ -288,7 +244,109 @@ export async function handleFeedbackSubmission(problem = null) {
288244
}
289245
}
290246

291-
247+
// 添加一个更醒目的提示框函数,支持不同类型的提示
248+
function showToast(message, type = "info", duration = 5000) {
249+
// 检查是否已存在toast样式
250+
if (!document.getElementById('lms-toast-style')) {
251+
const style = document.createElement('style');
252+
style.id = 'lms-toast-style';
253+
style.textContent = `
254+
.lms-toast {
255+
position: fixed;
256+
top: 20px;
257+
left: 50%;
258+
transform: translateX(-50%);
259+
padding: 12px 24px;
260+
border-radius: 4px;
261+
z-index: 10000;
262+
font-size: 14px;
263+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
264+
animation: lms-toast-in 0.3s ease;
265+
max-width: 80%;
266+
text-align: center;
267+
white-space: pre-line;
268+
font-weight: 500;
269+
}
270+
271+
.lms-toast-info {
272+
background-color: #1890ff;
273+
color: white;
274+
border-left: 4px solid #096dd9;
275+
}
276+
277+
.lms-toast-success {
278+
background-color: #52c41a;
279+
color: white;
280+
border-left: 4px solid #389e0d;
281+
}
282+
283+
.lms-toast-warning {
284+
background-color: #ffd666;
285+
color: #874d00;
286+
border-left: 4px solid #faad14;
287+
font-weight: bold;
288+
}
289+
290+
.lms-toast-error {
291+
background-color: #ff4d4f;
292+
color: white;
293+
border-left: 4px solid #cf1322;
294+
font-weight: bold;
295+
}
296+
297+
@keyframes lms-toast-in {
298+
from {
299+
opacity: 0;
300+
transform: translate(-50%, -20px);
301+
}
302+
to {
303+
opacity: 1;
304+
transform: translate(-50%, 0);
305+
}
306+
}
307+
308+
.lms-toast-icon {
309+
margin-right: 8px;
310+
font-weight: bold;
311+
}
312+
`;
313+
document.head.appendChild(style);
314+
}
315+
316+
// 移除可能存在的旧提示
317+
const existingToast = document.querySelector('.lms-toast');
318+
if (existingToast) {
319+
existingToast.remove();
320+
}
321+
322+
const toast = document.createElement('div');
323+
toast.className = `lms-toast lms-toast-${type}`;
324+
325+
// 添加图标
326+
let icon = '';
327+
switch(type) {
328+
case 'info': icon = 'ℹ️'; break;
329+
case 'success': icon = '✅'; break;
330+
case 'warning': icon = '⚠️'; break;
331+
case 'error': icon = '❌'; break;
332+
}
333+
334+
toast.innerHTML = `<span class="lms-toast-icon">${icon}</span>${message}`;
335+
document.body.appendChild(toast);
336+
337+
// 添加点击关闭功能
338+
toast.addEventListener('click', () => {
339+
toast.style.opacity = '0';
340+
toast.style.transition = 'opacity 0.3s ease';
341+
setTimeout(() => toast.remove(), 300);
342+
});
343+
344+
setTimeout(() => {
345+
toast.style.opacity = '0';
346+
toast.style.transition = 'opacity 0.3s ease';
347+
setTimeout(() => toast.remove(), 300);
348+
}, duration);
349+
}
292350

293351
// 6. 显示评分对话框
294352
const showDifficultyFeedbackDialog = () => {

0 commit comments

Comments
 (0)