diff --git a/.github/workflows/UpdateVersion.yml b/.github/workflows/UpdateVersion.yml
index 74a49224..6112841f 100644
--- a/.github/workflows/UpdateVersion.yml
+++ b/.github/workflows/UpdateVersion.yml
@@ -14,7 +14,7 @@ jobs:
pull-requests: write
contents: write
runs-on: ubuntu-latest
- if: github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'github-actions[bot]'
+ if: github.event.pull_request.head.repo.full_name == github.repository && !endsWith(github.actor, '[bot]')
steps:
- name: Generate a token
id: generate_token
@@ -26,4 +26,4 @@ jobs:
- name: Update version
env:
PR_BODY: ${{ github.event.pull_request.body }}
- run: node ./Update/UpdateVersion.js ${{ steps.generate_token.outputs.token }} ${{ github.event.number }} "${{ github.event.pull_request.title }}" "$PR_BODY"
+ run: node ./Update/UpdateVersion.js ${{ steps.generate_token.outputs.token }} ${{ github.event.number }} "${{ github.event.pull_request.title }}" "$PR_BODY" "${{ github.event.action }}"
diff --git a/Update.json b/Update.json
index 467e4c56..38e5a669 100644
--- a/Update.json
+++ b/Update.json
@@ -3385,6 +3385,43 @@
}
],
"Notes": "No release notes were provided for this release."
+ },
+ "3.2.1": {
+ "UpdateDate": 1771740586846,
+ "Prerelease": true,
+ "UpdateContents": [
+ {
+ "PR": 916,
+ "Description": "Fix contest ranking table styling for dark mode"
+ }
+ ],
+ "Notes": "Fix contest ranking table colors in dark mode (contestrank-oi.php and contestrank-correct.php)"
+ },
+ "3.2.2": {
+ "UpdateDate": 1771848993140,
+ "Prerelease": true,
+ "UpdateContents": [
+ {
+ "PR": 919,
+ "Description": "Gate WebSocket toast notifications by per-feature popup settings"
+ }
+ ],
+ "Notes": "Fix WebSocket notification toasts ignoring per-feature popup settings (BBSPopup/MessagePopup)."
+ },
+ "3.3.0": {
+ "UpdateDate": 1772197258188,
+ "Prerelease": false,
+ "UpdateContents": [
+ {
+ "PR": 916,
+ "Description": "Fix contest ranking table styling for dark mode"
+ },
+ {
+ "PR": 919,
+ "Description": "Gate WebSocket toast notifications by per-feature popup settings"
+ }
+ ],
+ "Notes": "Bug 修复
\n- 修复了暗色模式下比赛排名表(contestrank-oi.php 和 contestrank-correct.php)颜色显示异常的问题(#916)
\n- 修复了 WebSocket 弹窗通知未遵循各功能独立弹窗开关(BBSPopup/MessagePopup)的问题(#919)"
}
}
}
\ No newline at end of file
diff --git a/Update/UpdateVersion.js b/Update/UpdateVersion.js
index cd744cd8..891d2c46 100644
--- a/Update/UpdateVersion.js
+++ b/Update/UpdateVersion.js
@@ -8,9 +8,14 @@ execSync("gh pr checkout " + PRNumber);
console.info("PR #" + PRNumber + " has been checked out.");
// Check if the last commit was made by github-actions[bot]
+// Only skip for synchronize events (push-triggered) to prevent infinite loops.
+// For edited events (PR title/body changes), allow metadata updates even when
+// the branch tip is a bot commit.
+const eventAction = String(process.argv[6] || "");
const lastCommitAuthor = execSync("git log -1 --pretty=format:'%an'").toString().trim();
console.log("Last commit author: " + lastCommitAuthor);
-if (lastCommitAuthor === "github-actions[bot]") {
+console.log("Event action : " + eventAction);
+if (lastCommitAuthor === "github-actions[bot]" && eventAction !== "edited") {
console.log("Last commit was made by github-actions[bot]. Skipping to prevent infinite loop.");
process.exit(0);
}
diff --git a/XMOJ.user.js b/XMOJ.user.js
index 74e4ef53..4c9d072c 100644
--- a/XMOJ.user.js
+++ b/XMOJ.user.js
@@ -1,6 +1,6 @@
// ==UserScript==
// @name XMOJ
-// @version 3.2.0
+// @version 3.3.0
// @description XMOJ增强脚本
// @author @XMOJ-Script-dev, @langningchen and the community
// @namespace https://github/langningchen
@@ -650,11 +650,13 @@ function HandleNotificationMessage(event) {
console.log("WebSocket: Server confirmed connection at timestamp", notification.timestamp);
}
} else if (notification.type === 'bbs_mention') {
- // Backend now provides all data needed for immediate display
- CreateAndShowBBSMentionToast(notification.data);
+ if (UtilityEnabled("BBSPopup")) {
+ CreateAndShowBBSMentionToast(notification.data);
+ }
} else if (notification.type === 'mail_mention') {
- // Backend now provides all data needed for immediate display
- CreateAndShowMailMentionToast(notification.data);
+ if (UtilityEnabled("MessagePopup")) {
+ CreateAndShowMailMentionToast(notification.data);
+ }
} else if (notification.type === 'pong') {
if (UtilityEnabled("DebugMode")) {
console.log("WebSocket: Received pong");
@@ -2994,11 +2996,21 @@ async function main() {
document.querySelector("#rank").innerText = "比赛暂时还没有排名";
} else {
document.querySelector("body > div > div.mt-3 > center > h3").innerText = document.querySelector("body > div > div.mt-3 > center > h3").innerText.substring(document.querySelector("body > div > div.mt-3 > center > h3").innerText.indexOf(" -- ") + 4) + "(OI排名)";
- document.querySelector("#rank > thead > tr > :nth-child(1)").innerText = "排名";
- document.querySelector("#rank > thead > tr > :nth-child(2)").innerText = "用户";
- document.querySelector("#rank > thead > tr > :nth-child(3)").innerText = "昵称";
- document.querySelector("#rank > thead > tr > :nth-child(4)").innerText = "AC数";
- document.querySelector("#rank > thead > tr > :nth-child(5)").innerText = "得分";
+ let HeaderCells = document.querySelectorAll("#rank > thead > tr > *");
+ HeaderCells[0].innerText = "排名";
+ HeaderCells[1].innerText = "用户";
+ HeaderCells[2].innerText = "昵称";
+ HeaderCells[3].innerText = "AC数";
+ HeaderCells[4].innerText = "得分";
+ for (let j = 0; j < HeaderCells.length; j++) {
+ HeaderCells[j].removeAttribute("bgcolor");
+ HeaderCells[j].style.setProperty("background-color", "black", "important");
+ HeaderCells[j].style.setProperty("color", "white", "important");
+ let Links = HeaderCells[j].querySelectorAll("a");
+ for (let k = 0; k < Links.length; k++) {
+ Links[k].style.setProperty("color", "white", "important");
+ }
+ }
let RefreshOIRank = async () => {
await fetch(location.href)
.then((Response) => {
@@ -3009,6 +3021,7 @@ async function main() {
TidyTable(ParsedDocument.getElementById("rank"));
let Temp = ParsedDocument.getElementById("rank").rows;
for (var i = 1; i < Temp.length; i++) {
+ Temp[i].style.backgroundColor = "";
let MetalCell = Temp[i].cells[0];
let Metal = document.createElement("span");
Metal.innerText = MetalCell.innerText;
@@ -3018,6 +3031,10 @@ async function main() {
GetUsernameHTML(Temp[i].cells[1], Temp[i].cells[1].innerText);
Temp[i].cells[2].innerHTML = Temp[i].cells[2].innerText;
Temp[i].cells[3].innerHTML = Temp[i].cells[3].innerText;
+ for (let j = 0; j < 5 && j < Temp[i].cells.length; j++) {
+ Temp[i].cells[j].style.backgroundColor = "";
+ Temp[i].cells[j].style.color = "";
+ }
for (let j = 5; j < Temp[i].cells.length; j++) {
let InnerText = Temp[i].cells[j].innerText;
let BackgroundColor = Temp[i].cells[j].style.backgroundColor;
@@ -3038,7 +3055,7 @@ async function main() {
} else if (FirstBlood) {
BackgroundColor = "rgb(127, 127, 255)";
} else if (Solved) {
- BackgroundColor = "rgb(0, 255, 0, " + Math.max(1 / 10 * (10 - ErrorCount), 0.2) + ")";
+ BackgroundColor = "rgba(0, 255, 0, " + Math.max(1 / 10 * (10 - ErrorCount), 0.2) + ")";
if (ErrorCount != 0) {
InnerText += " (" + (ErrorCount == 5 ? "4+" : ErrorCount) + ")";
}
@@ -3080,11 +3097,21 @@ async function main() {
document.querySelector("body > div > div.mt-3 > center > h3").innerText = document.querySelector("body > div > div.mt-3 > center > h3").innerText.substring(document.querySelector("body > div > div.mt-3 > center > h3").innerText.indexOf(" -- ") + 4) + "(订正排名)";
document.querySelector("body > div > div.mt-3 > center > a").remove();
}
- document.querySelector("#rank > thead > tr > :nth-child(1)").innerText = "排名";
- document.querySelector("#rank > thead > tr > :nth-child(2)").innerText = "用户";
- document.querySelector("#rank > thead > tr > :nth-child(3)").innerText = "昵称";
- document.querySelector("#rank > thead > tr > :nth-child(4)").innerText = "AC数";
- document.querySelector("#rank > thead > tr > :nth-child(5)").innerText = "得分";
+ let HeaderCells = document.querySelectorAll("#rank > thead > tr > *");
+ HeaderCells[0].innerText = "排名";
+ HeaderCells[1].innerText = "用户";
+ HeaderCells[2].innerText = "昵称";
+ HeaderCells[3].innerText = "AC数";
+ HeaderCells[4].innerText = "得分";
+ for (let j = 0; j < HeaderCells.length; j++) {
+ HeaderCells[j].removeAttribute("bgcolor");
+ HeaderCells[j].style.setProperty("background-color", "black", "important");
+ HeaderCells[j].style.setProperty("color", "white", "important");
+ let Links = HeaderCells[j].querySelectorAll("a");
+ for (let k = 0; k < Links.length; k++) {
+ Links[k].style.setProperty("color", "white", "important");
+ }
+ }
let RefreshCorrectRank = async () => {
await fetch(location.href)
.then((Response) => {
@@ -3095,6 +3122,7 @@ async function main() {
TidyTable(ParsedDocument.getElementById("rank"));
let Temp = ParsedDocument.getElementById("rank").rows;
for (var i = 1; i < Temp.length; i++) {
+ Temp[i].style.backgroundColor = "";
let MetalCell = Temp[i].cells[0];
let Metal = document.createElement("span");
Metal.innerText = MetalCell.innerText;
@@ -3104,6 +3132,10 @@ async function main() {
GetUsernameHTML(Temp[i].cells[1], Temp[i].cells[1].innerText);
Temp[i].cells[2].innerHTML = Temp[i].cells[2].innerText;
Temp[i].cells[3].innerHTML = Temp[i].cells[3].innerText;
+ for (let j = 0; j < 5 && j < Temp[i].cells.length; j++) {
+ Temp[i].cells[j].style.backgroundColor = "";
+ Temp[i].cells[j].style.color = "";
+ }
for (let j = 5; j < Temp[i].cells.length; j++) {
let InnerText = Temp[i].cells[j].innerText;
let BackgroundColor = Temp[i].cells[j].style.backgroundColor;
@@ -3136,6 +3168,7 @@ async function main() {
}
Temp[i].cells[j].innerHTML = InnerText;
Temp[i].cells[j].style.backgroundColor = BackgroundColor;
+ Temp[i].cells[j].style.color = (UtilityEnabled("DarkMode") ? "white" : "black");
}
}
document.querySelector("#rank > tbody").innerHTML = ParsedDocument.querySelector("#rank > tbody").innerHTML;
diff --git a/package.json b/package.json
index 9dd923ed..33385212 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "xmoj-script",
- "version": "3.2.0",
+ "version": "3.3.0",
"description": "an improvement script for xmoj.tech",
"main": "AddonScript.js",
"scripts": {