Fix Problem Switcher Not Update#929
Fix Problem Switcher Not Update#929def-WA2025 wants to merge 1 commit intoXMOJ-Script-dev:masterfrom
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideEnsure the contest problem list used by the problem switcher is refreshed from the contest page on each load instead of relying on possibly stale localStorage data, so EX problems and other updates are shown correctly. Sequence diagram for refreshed contest problem list on page loadsequenceDiagram
actor User
participant Browser
participant XMOJScript
participant LocalStorage
participant XMOJServer
User->>Browser: Open contest problem page
Browser->>XMOJScript: Execute main
XMOJScript->>LocalStorage: getItem(UserScript-Contest-cid-ProblemList)
LocalStorage-->>XMOJScript: ContestProblemList (ignored)
XMOJScript->>XMOJScript: Set ContestProblemList to null
XMOJScript->>XMOJServer: GET contest.php?cid=cid
XMOJServer-->>XMOJScript: HTML contest page
XMOJScript->>XMOJScript: Parse HTML and extract problem rows
XMOJScript->>XMOJScript: Build problemList array
XMOJScript->>LocalStorage: setItem(UserScript-Contest-cid-ProblemList, JSON.stringify(problemList))
XMOJScript->>XMOJScript: ContestProblemList = JSON.stringify(problemList)
XMOJScript->>Browser: Render problemSwitcher using updated ContestProblemList
Flow diagram for updated ContestProblemList refresh logicflowchart TD
A[Page load in contest problem view] --> B[Execute main]
B --> C[Read ContestProblemList from LocalStorage]
C --> D[Set ContestProblemList to null]
D --> E[Fetch contest.php with cid]
E --> F{Status 200 and no private or not started message}
F -- Yes --> G[Parse HTML with DOMParser]
G --> H[Select #problemset tbody rows]
H --> I[Iterate rows and build problemList array]
I --> J[Save problemList to LocalStorage as JSON]
J --> K[Set ContestProblemList to JSON string]
K --> L[Create and display problemSwitcher with fresh data]
F -- No --> M[Skip update, do not build problemList]
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- You’re now discarding any cached
ContestProblemListand always re-fetching; consider either preserving the original cache check with an explicit cache invalidation strategy or adding a clear reason in code comments for bypassing localStorage. - The line
let ContestProblemList = localStorage.getItem(...);immediately followed byContestProblemList = null;is redundant and confusing—either remove thegetItemcall or restore logic that uses its value. - The new fetch path assumes a successful response; consider adding basic error handling (e.g., non-200 status or network failure) to avoid the switcher silently breaking when the contest page cannot be retrieved.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- You’re now discarding any cached `ContestProblemList` and always re-fetching; consider either preserving the original cache check with an explicit cache invalidation strategy or adding a clear reason in code comments for bypassing localStorage.
- The line `let ContestProblemList = localStorage.getItem(...);` immediately followed by `ContestProblemList = null;` is redundant and confusing—either remove the `getItem` call or restore logic that uses its value.
- The new fetch path assumes a successful response; consider adding basic error handling (e.g., non-200 status or network failure) to avoid the switcher silently breaking when the contest page cannot be retrieved.
## Individual Comments
### Comment 1
<location path="XMOJ.user.js" line_range="2272-2274" />
<code_context>
- }
- localStorage.setItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList", JSON.stringify(problemList));
- ContestProblemList = JSON.stringify(problemList);
+ ContestProblemList = null;
+ const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid"));
+ const res = await contestReq.text();
</code_context>
<issue_to_address>
**suggestion:** Avoid resetting `ContestProblemList` to `null` if you intend to keep using the cached value from `localStorage`.
This assignment discards the value read from `localStorage`, and the cache is never used afterward. If you always want fresh data, remove the initial `localStorage.getItem(...)` call. If you want to preserve caching, drop this assignment so the stored value can still be used.
```suggestion
const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid"));
const res = await contestReq.text();
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| ContestProblemList = null; | ||
| const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid")); | ||
| const res = await contestReq.text(); |
There was a problem hiding this comment.
suggestion: Avoid resetting ContestProblemList to null if you intend to keep using the cached value from localStorage.
This assignment discards the value read from localStorage, and the cache is never used afterward. If you always want fresh data, remove the initial localStorage.getItem(...) call. If you want to preserve caching, drop this assignment so the stored value can still be used.
| ContestProblemList = null; | |
| const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid")); | |
| const res = await contestReq.text(); | |
| const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid")); | |
| const res = await contestReq.text(); |
There was a problem hiding this comment.
1 issue found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="XMOJ.user.js">
<violation number="1" location="XMOJ.user.js:2272">
P1: Do not clear `ContestProblemList` before refresh; it removes the cache fallback and can crash when refresh fails.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| ContestProblemList = null; | ||
| const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid")); | ||
| const res = await contestReq.text(); | ||
| if (contestReq.status === 200 && res.indexOf("比赛尚未开始或私有,不能查看题目。") === -1) { | ||
| const parser = new DOMParser(); | ||
| const dom = parser.parseFromString(res, "text/html"); | ||
| const rows = (dom.querySelector("#problemset > tbody")).rows; | ||
| let problemList = []; | ||
| for (let i = 0; i < rows.length; i++) { | ||
| problemList.push({ | ||
| "title": rows[i].children[2].innerText, | ||
| "url": rows[i].children[2].children[0].href | ||
| }); | ||
| } | ||
| localStorage.setItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList", JSON.stringify(problemList)); | ||
| ContestProblemList = JSON.stringify(problemList); | ||
| } |
There was a problem hiding this comment.
P1: Do not clear ContestProblemList before refresh; it removes the cache fallback and can crash when refresh fails.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At XMOJ.user.js, line 2272:
<comment>Do not clear `ContestProblemList` before refresh; it removes the cache fallback and can crash when refresh fails.</comment>
<file context>
@@ -2269,23 +2269,22 @@ async function main() {
- }
- localStorage.setItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList", JSON.stringify(problemList));
- ContestProblemList = JSON.stringify(problemList);
+ ContestProblemList = null;
+ const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid"));
+ const res = await contestReq.text();
</file context>
| ContestProblemList = null; | |
| const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid")); | |
| const res = await contestReq.text(); | |
| if (contestReq.status === 200 && res.indexOf("比赛尚未开始或私有,不能查看题目。") === -1) { | |
| const parser = new DOMParser(); | |
| const dom = parser.parseFromString(res, "text/html"); | |
| const rows = (dom.querySelector("#problemset > tbody")).rows; | |
| let problemList = []; | |
| for (let i = 0; i < rows.length; i++) { | |
| problemList.push({ | |
| "title": rows[i].children[2].innerText, | |
| "url": rows[i].children[2].children[0].href | |
| }); | |
| } | |
| localStorage.setItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList", JSON.stringify(problemList)); | |
| ContestProblemList = JSON.stringify(problemList); | |
| } | |
| const cachedContestProblemList = ContestProblemList; | |
| const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid")); | |
| const res = await contestReq.text(); | |
| if (contestReq.status === 200 && res.indexOf("比赛尚未开始或私有,不能查看题目。") === -1) { | |
| const parser = new DOMParser(); | |
| const dom = parser.parseFromString(res, "text/html"); | |
| const rows = (dom.querySelector("#problemset > tbody")).rows; | |
| let problemList = []; | |
| for (let i = 0; i < rows.length; i++) { | |
| problemList.push({ | |
| "title": rows[i].children[2].innerText, | |
| "url": rows[i].children[2].children[0].href | |
| }); | |
| } | |
| localStorage.setItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList", JSON.stringify(problemList)); | |
| ContestProblemList = JSON.stringify(problemList); | |
| } else { | |
| ContestProblemList = cachedContestProblemList; | |
| } |
|
ty for PR though base to extern-contrib pls |
|
Hmm so how can I submit to extern-contrib ( |
|
Because this is my first contribution to the project |
|
Oh sorry, if you have wrote access, you should make changes in this repo, not your fork, and base your PR to dev |
|
I will close this PR for now, please resubmit it |
|
Also it’s terribly late, so tomorrow pls |
|
tks |
|
直接清Cache 不好吧,加一个刷新按钮? |
|
正常提交更改方式是在这个仓库里新建一个分支,把自己的更改提交到那个分支,在PR到dev 注意新分支应基于最新dev |
OK |
What does this PR aim to accomplish?
Fix *EX problems not display.
How does this PR accomplish the above?
Update variable
contestProblemListwhen the page reload.By submitting this pull request, I confirm the following:
git rebase)Summary by Sourcery
Bug Fixes:
Summary by cubic
Refreshes the contest problem list on each page load so the Problem Switcher always shows the latest problems, including EX problems. Replaces stale cached data with the newest list.
UserScript-Contest-<cid>-ProblemListinlocalStorage.ContestProblemListon load to prevent stale entries and ensure EX problems appear.Written for commit 5b1123b. Summary will update on new commits.