@@ -473,9 +475,9 @@
000
href="https://status.dangoweb.com/">server maintenance, or contact support below.
diff --git a/package-lock.json b/package-lock.json
index ef1abb72..a2d78a7f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,7 +22,7 @@
"devDependencies": {
"eslint": "^8.51.0",
"prettier": "^3.2.5",
- "vite": "^6.3.6",
+ "vite": "^6.4.1",
"vite-plugin-webfont-dl": "^3.10.4"
}
},
@@ -517,7 +517,6 @@
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
"integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
"optional": true,
- "peer": true,
"dependencies": {
"@jridgewell/set-array": "^1.0.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
@@ -532,7 +531,6 @@
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
"optional": true,
- "peer": true,
"engines": {
"node": ">=6.0.0"
}
@@ -542,7 +540,6 @@
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
"optional": true,
- "peer": true,
"engines": {
"node": ">=6.0.0"
}
@@ -552,7 +549,6 @@
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
"optional": true,
- "peer": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
@@ -562,15 +558,13 @@
"version": "1.4.14",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
- "optional": true,
- "peer": true
+ "optional": true
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.17",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
"integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
"optional": true,
- "peer": true,
"dependencies": {
"@jridgewell/resolve-uri": "3.1.0",
"@jridgewell/sourcemap-codec": "1.4.14"
@@ -870,6 +864,7 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
"integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
"devOptional": true,
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -1075,8 +1070,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "optional": true,
- "peer": true
+ "optional": true
},
"node_modules/cacheable": {
"version": "1.10.0",
@@ -1301,7 +1295,6 @@
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
"optional": true,
- "peer": true,
"bin": {
"detect-libc": "bin/detect-libc.js"
},
@@ -1441,6 +1434,7 @@
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz",
"integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==",
"dev": true,
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -2082,10 +2076,11 @@
"dev": true
},
"node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
@@ -2160,32 +2155,164 @@
"node": ">= 0.8.0"
}
},
- "node_modules/lightningcss": {
+ "node_modules/lightningcss-darwin-arm64": {
"version": "1.21.7",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.21.7.tgz",
- "integrity": "sha512-xITZyh5sLFwRPYUSw15T00Rm7gcQ1qOPuQwNOcvHsTm6nLWTQ723w7zl42wrC5t+xtdg6FPmnXHml1nZxxvp1w==",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.21.7.tgz",
+ "integrity": "sha512-tt7hIsFio9jZofTVHtCACz6rB6c9RyABMXfA9A/VcKOjS3sq+koX/QkRJWY06utwOImbJIXBC5hbg9t3RkPUAQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
"optional": true,
- "peer": true,
- "dependencies": {
- "detect-libc": "^1.0.3"
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.21.7.tgz",
+ "integrity": "sha512-F4gS4bf7eWekfPT+TxJNm/pF+QRgZiTrTkQH6cw4/UWfdeZISfuhD5El2dm16giFnY0K5ylIwO+ZusgYNkGSXA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
},
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.21.7.tgz",
+ "integrity": "sha512-RMfNzJWXCSfPnL55fcLWEAadcY6QUFT0S8NceNKYzp1KiCZtkJIy6RQ5SaVxPzRqd3iMsahUf5sfnG8N1UQSNQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
"engines": {
"node": ">= 12.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.21.7.tgz",
+ "integrity": "sha512-biSRUDZNx7vubWP1jArw/qqfZKPGpkV/qzunasZzxmqijbZ43sW9faDQYxWNcxPWljJJdF/qs6qcurYFovWtrQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
},
- "optionalDependencies": {
- "lightningcss-darwin-arm64": "1.21.7",
- "lightningcss-darwin-x64": "1.21.7",
- "lightningcss-freebsd-x64": "1.21.7",
- "lightningcss-linux-arm-gnueabihf": "1.21.7",
- "lightningcss-linux-arm64-gnu": "1.21.7",
- "lightningcss-linux-arm64-musl": "1.21.7",
- "lightningcss-linux-x64-gnu": "1.21.7",
- "lightningcss-linux-x64-musl": "1.21.7",
- "lightningcss-win32-x64-msvc": "1.21.7"
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.21.7.tgz",
+ "integrity": "sha512-PENY8QekqL9TG3AY/A7rkUBb5ymefGxea7Oe7+x7Hbw4Bz4Hpj5cec5OoMypMqFbURPmpi0fTWx4vSWUPzpDcA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.21.7.tgz",
+ "integrity": "sha512-pfOipKvA/0X1OjRaZt3870vnV9UGBSjayIqHh0fGx/+aRz3O0MVFHE/60P2UWXpM3YGJEw/hMWtNkrFwqOge8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.21.7.tgz",
+ "integrity": "sha512-dgcsis4TAA7s0ia4f31QHX+G4PWPwxk+wJaEQLaV0NdJs09O5hHoA8DpLEr8nrvc/tsRTyVNBP1rDtgzySjpXg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.21.7.tgz",
+ "integrity": "sha512-A+9dXpxld3p4Cd6fxev2eqEvaauYtrgNpXV3t7ioCJy30Oj9nYiNGwiGusM+4MJVcEpUPGUGiuAqY4sWilRDwA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
"node_modules/lightningcss-win32-x64-msvc": {
@@ -2199,7 +2326,6 @@
"os": [
"win32"
],
- "peer": true,
"engines": {
"node": ">= 12.0.0"
},
@@ -2470,6 +2596,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -2737,7 +2864,6 @@
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"optional": true,
- "peer": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@@ -2789,7 +2915,6 @@
"resolved": "https://registry.npmjs.org/terser/-/terser-5.16.4.tgz",
"integrity": "sha512-5yEGuZ3DZradbogeYQ1NaGz7rXVBDWujWlx1PT8efXO6Txn+eWbfKqB2bTDVmFXmePFkoLU6XI8UektMIEA0ug==",
"optional": true,
- "peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.2",
"acorn": "^8.5.0",
@@ -2807,8 +2932,7 @@
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "optional": true,
- "peer": true
+ "optional": true
},
"node_modules/text-table": {
"version": "0.2.0",
@@ -2884,10 +3008,11 @@
}
},
"node_modules/vite": {
- "version": "6.3.6",
- "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.6.tgz",
- "integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==",
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
+ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.4.4",
diff --git a/package.json b/package.json
index 0f37e907..2d9f2349 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"devDependencies": {
"eslint": "^8.51.0",
"prettier": "^3.2.5",
- "vite": "^6.3.6",
+ "vite": "^6.4.1",
"vite-plugin-webfont-dl": "^3.10.4"
},
"dependencies": {
diff --git a/src/admin.js b/src/admin.js
index 935372c9..4a719181 100644
--- a/src/admin.js
+++ b/src/admin.js
@@ -131,6 +131,8 @@ try {
} catch (error) {
if (storage.get("developer")) {
alert(`Error @ admin.js: ${error.message}`);
- };
+ } else {
+ ui.reportBugModal(null, String(error.stack));
+ }
throw error;
};
\ No newline at end of file
diff --git a/src/checker/admin.js b/src/checker/admin.js
index 4232f5fa..b99193b3 100644
--- a/src/checker/admin.js
+++ b/src/checker/admin.js
@@ -6361,6 +6361,8 @@ try {
} catch (error) {
if (storage.get("developer")) {
alert(`Error @ admin.js: ${error.message}`);
+ } else {
+ ui.reportBugModal(null, String(error.stack));
}
throw error;
}
\ No newline at end of file
diff --git a/src/checker/checker.js b/src/checker/checker.js
index 79500256..4c49c9d0 100644
--- a/src/checker/checker.js
+++ b/src/checker/checker.js
@@ -524,13 +524,16 @@ try {
option.setAttribute('due', segment.due || '');
segments.append(option);
});
- segments.value = segmentsArray.find(s => {
- if (!s.due) return false;
- return (new Date(`${s.due}T00:00:00`).toLocaleDateString('en-US', { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' }) === new Date().toLocaleDateString('en-US', { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric', }) && new Date().getTime() <= periodRange[1]);
- })?.id || segmentsArray.find(s => {
- if (!s.due) return false;
- return (new Date(`${s.due}T00:00:00`).getTime() > periodRange[1] && new Date(`${s.due}T00:00:00`).getTime() <= periodRange[0] + 86400000);
- })?.id || segmentsArray.find(s => !s.due)?.id || segmentsArray[0]?.id;
+ const today = new Date();
+ const todayString = today.toLocaleDateString('en-US', { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' });
+ const sortedSegments = segmentsArray.filter(s => s.due).sort((a, b) => new Date(`${a.due}T00:00:00`) - new Date(`${b.due}T00:00:00`));
+ segments.value = sortedSegments.find(s => {
+ const dueDate = new Date(`${s.due}T00:00:00`);
+ return dueDate.toLocaleDateString('en-US', { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' }) === todayString && today.getTime() <= periodRange[1];
+ })?.id || sortedSegments.find(s => {
+ const dueDate = new Date(`${s.due}T00:00:00`);
+ return dueDate.getTime() > periodRange[1];
+ })?.id || sortedSegments[0]?.id || segmentsArray[0]?.id;
segments.removeEventListener("change", updateSegment);
segments.addEventListener("change", updateSegment);
// Update history feed
@@ -598,7 +601,10 @@ try {
document.querySelector('[data-segment-due]').innerHTML = `
Due ${new Date(`${selectedSegment.due}T00:00:00`).toLocaleDateString('en-US', { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' })}`;
if (document.querySelector('[data-segment-due]')._interval) clearInterval(document.querySelector('[data-segment-due]')._interval);
document.querySelector('[data-segment-due]')._interval = setInterval(() => {
- const dueTime = new Date(`${selectedSegment.due}T00:00:00`).getTime();
+ const periodRange = getExtendedPeriodRange(null, Number(storage.get("code").slice(0, 1)));
+ const timeObj = new Date(periodRange[0]);
+ const dateObj = new Date(`${selectedSegment.due}T00:00:00`);
+ const dueTime = new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate(), timeObj.getHours(), timeObj.getMinutes(), timeObj.getSeconds()).getTime();
const currentTime = new Date().getTime();
var timeDiff = dueTime - currentTime;
var prefix = 'in ';
@@ -1521,6 +1527,8 @@ try {
} catch (error) {
if (storage.get("developer")) {
alert(`Error @ clicker.js: ${error.message}`);
- };
+ } else {
+ ui.reportBugModal(null, String(error.stack));
+ }
throw error;
};
\ No newline at end of file
diff --git a/src/checker/ta.js b/src/checker/ta.js
index 4b6ae1e2..107b9bec 100644
--- a/src/checker/ta.js
+++ b/src/checker/ta.js
@@ -1298,6 +1298,8 @@ try {
} catch (error) {
if (storage.get("developer")) {
alert(`Error @ ta.js: ${error.message}`);
+ } else {
+ ui.reportBugModal(null, String(error.stack));
}
throw error;
}
\ No newline at end of file
diff --git a/src/keybinds/keybinds.js b/src/keybinds/keybinds.js
index 44e58445..c08212aa 100644
--- a/src/keybinds/keybinds.js
+++ b/src/keybinds/keybinds.js
@@ -35,6 +35,7 @@ try {
e.preventDefault();
document.querySelector('[data-next-question]').click();
}
+ if (e.key == "b") ui.reportBugModal();
} else if (e.altKey) {
if (/[1-9]/.test(e.key)) {
e.preventDefault();
@@ -129,6 +130,8 @@ try {
} catch (error) {
if (storage.get("developer")) {
alert(`Error @ keybinds.js: ${error.message}`);
- };
+ } else {
+ ui.reportBugModal(null, String(error.stack));
+ }
throw error;
};
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index 7c1b45dd..685bb499 100644
--- a/src/main.js
+++ b/src/main.js
@@ -128,6 +128,8 @@ try {
} catch (error) {
if (storage.get("developer")) {
alert(`Error @ main.js: ${error.message}`);
- };
+ } else {
+ ui.reportBugModal(null, String(error.stack));
+ }
throw error;
};
\ No newline at end of file
diff --git a/src/modules/mathlive.js b/src/modules/mathlive.js
index 95436ea0..a2120549 100644
--- a/src/modules/mathlive.js
+++ b/src/modules/mathlive.js
@@ -1,12 +1,4 @@
-import storage from "/src/modules/storage.js";
import "/node_modules/mathlive/dist/mathlive-fonts.css";
import { MathfieldElement } from "mathlive";
-try {
- MathfieldElement.soundsDirectory = null;
-} catch (error) {
- if (storage.get("developer")) {
- alert(`Error @ mathlive.js: ${error.message}`);
- };
- throw error;
-};
\ No newline at end of file
+MathfieldElement.soundsDirectory = null;
\ No newline at end of file
diff --git a/src/modules/ui.css b/src/modules/ui.css
index 756081d8..2fdb8fba 100644
--- a/src/modules/ui.css
+++ b/src/modules/ui.css
@@ -131,7 +131,8 @@ div[data-modal-actions] > button {
dialog > button[data-modal-view]:not(.icon),
dialog > button[data-logout],
dialog > button[data-sync],
-dialog > button[data-welcome] {
+dialog > button[data-welcome],
+dialog > button[data-report-bug] {
text-align: unset;
}
diff --git a/src/modules/ui.js b/src/modules/ui.js
index e0dec28b..ac505e42 100644
--- a/src/modules/ui.js
+++ b/src/modules/ui.js
@@ -49,7 +49,7 @@ export function modal(options) {
label.innerHTML = options.input.label;
dialog.appendChild(label);
}
- const input = document.createElement((options.input.type === "select") ? "select" : "input");
+ const input = document.createElement((options.input.type === "select") ? "select" : ((options.input.type === "textarea") ? "textarea" : "input"));
if (options.input.type !== "select") input.type = options.input.type || "text";
if ((options.input.type === "select") && options.input.multiple) input.multiple = options.input.multiple;
if ((options.input.type === "select") && options.input.options) {
@@ -61,8 +61,10 @@ export function modal(options) {
input.appendChild(optionElement);
});
}
+ if (options.input.type === "textarea") input.rows = options.input.rows || 3;
input.placeholder = options.input.placeholder || "";
if (options.input.defaultValue) input.value = options.input.defaultValue || "";
+ if (options.input.disabled) input.disabled = true;
input.className = `dialog-input${options.input.selectAll ? " selectAll" : ""}`;
input.min = options.input.min || "";
input.max = options.input.max || "";
@@ -78,8 +80,8 @@ export function modal(options) {
label.innerHTML = input.label;
dialog.appendChild(label);
}
- const inputElement = document.createElement((input.type === "select") ? "select" : "input");
- if (input.type !== "select") inputElement.type = input.type || "text";
+ const inputElement = document.createElement((input.type === "select") ? "select" : ((input.type === "textarea") ? "textarea" : "input"));
+ if (input.type === "input") inputElement.type = input.type || "text";
if ((input.type === "select") && input.multiple) inputElement.multiple = input.multiple;
if ((input.type === "select") && input.options) {
input.options.forEach(option => {
@@ -90,8 +92,10 @@ export function modal(options) {
inputElement.appendChild(optionElement);
});
}
+ if (input.type === "textarea") inputElement.rows = input.rows || 3;
inputElement.placeholder = input.placeholder || "";
if (input.defaultValue) inputElement.value = input.defaultValue || "";
+ if (input.disabled) inputElement.disabled = true;
inputElement.className = `dialog-input${input.selectAll ? " selectAll" : ""}`;
inputElement.min = input.min || "";
inputElement.max = input.max || "";
@@ -117,8 +121,7 @@ export function modal(options) {
var buttonGroupContainerElement = document.createElement("div");
buttonGroupContainerElement.className = "button-grid";
buttonGroup.buttons.forEach(button => {
- if (button.icon) button.text = `
${button.text}`;
- var btnElement = new Element("button", button.text, {
+ var btnElement = new Element("button", `${button.icon ? `
` : ''}${button.text}`, {
click: () => {
if (button.onclick) {
var hasEmptyRequiredInput = false;
@@ -154,8 +157,7 @@ export function modal(options) {
var buttonsContainerElement = document.createElement("div");
buttonsContainerElement.className = "button-grid";
options.buttons.forEach(button => {
- if (button.icon) button.text = + `
`;
- var btnElement = new Element("button", button.text, {
+ var btnElement = new Element("button", `${button.icon ? `
` : ''}${button.text}`, {
click: () => {
if (button.onclick) {
var hasEmptyRequiredInput = false;
@@ -1027,4 +1029,71 @@ export async function setNotifications(array) {
document.querySelector('[data-modal-view="history"]')?.classList.remove('unread');
document.querySelector('[data-modal-view="history"]')?.setAttribute('tooltip', 'History');
}
-}
\ No newline at end of file
+}
+
+document.querySelectorAll('[data-report-bug]').forEach(a => a.addEventListener('click', reportBugModal));
+
+export function reportBugModal(event = null, report = null) {
+ if (report) toast('A bug was detected, please report it.', 10000, 'error', 'bi bi-bug-fill');
+ view();
+ modal({
+ title: 'Report Bug',
+ body: '
Report a bug with the Virtual Checker or internal APIs.
',
+ inputs: [
+ {
+ type: 'select',
+ label: 'Issue with',
+ options: [
+ { value: 'Virtual Checker', text: 'Virtual Checker' },
+ { value: 'Homework Checker (API)', text: 'API' },
+ ],
+ required: true,
+ disabled: report,
+ },
+ {
+ type: 'textarea',
+ label: 'Description',
+ placeholder: 'Describe the issue you encountered...',
+ required: true,
+ selectAll: !report,
+ disabled: report,
+ defaultValue: report || '',
+ }
+ ],
+ buttons: [
+ {
+ text: 'Cancel',
+ icon: 'bi-x-lg',
+ class: 'cancel-button',
+ close: true,
+ },
+ {
+ text: 'Submit',
+ icon: 'bi-bug-fill',
+ class: 'submit-button',
+ onclick: (inputValues) => {
+ try {
+ const fields = {
+ "entry.470737118": storage.get("code"),
+ "entry.888169052": inputValues[0],
+ "entry.689497704": `${report ? '000' : storage.get("code")}:${inputValues[1]}`,
+ };
+ const params = new URLSearchParams(fields).toString();
+ const url = "https://docs.google.com/forms/d/e/1FAIpQLSdOO9-Y7IG-djY1MVFpr1qR5-vXw6asU--e61w9atFaRVOpNw/formResponse?";
+ fetch(url + params, {
+ method: "POST",
+ mode: "no-cors",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ });
+ toast('Bug report submitted successfully. Thank you!', 5000, 'success', 'bi bi-check-circle-fill');
+ } catch (e) {
+ toast('Failed to submit bug report. Please try again later.', 5000, 'error', 'bi bi-x-circle-fill');
+ }
+ },
+ close: true,
+ },
+ ],
+ });
+}
diff --git a/src/symbols/symbols.js b/src/symbols/symbols.js
index 9d7c008a..43bf9a54 100644
--- a/src/symbols/symbols.js
+++ b/src/symbols/symbols.js
@@ -160,11 +160,15 @@ function insert(symbol, customInput) {
if (customInput) {
customInput.setRangeText(symbol, customInput.selectionStart, customInput.selectionEnd, "end");
customInput.focus();
- } else {
+ } else if (answerInput) {
answerInput.setRangeText(symbol, answerInput.selectionStart, answerInput.selectionEnd, "end");
answerInput.focus();
- };
- autocomplete.update();
+ } else if (document.activeElement && (document.activeElement.tagName.toLowerCase() === 'input' && document.activeElement.getAttribute("type") && (document.activeElement.getAttribute("type") === "text") || document.activeElement.tagName.toLowerCase() === 'textarea')) {
+ const activeInput = document.activeElement;
+ activeInput.setRangeText(symbol, activeInput.selectionStart, activeInput.selectionEnd, "end");
+ activeInput.focus();
+ }
+ autocomplete?.update();
}
// Insert symbol from index
diff --git a/src/ta.js b/src/ta.js
index 567e94d7..9aa8ccc9 100644
--- a/src/ta.js
+++ b/src/ta.js
@@ -127,6 +127,8 @@ try {
} catch (error) {
if (storage.get("developer")) {
alert(`Error @ ta.js: ${error.message}`);
- };
+ } else {
+ ui.reportBugModal(null, String(error.stack));
+ }
throw error;
};
\ No newline at end of file
diff --git a/src/themes/butterfly/butterfly.js b/src/themes/butterfly/butterfly.js
index d7123b3b..55a44f2a 100644
--- a/src/themes/butterfly/butterfly.js
+++ b/src/themes/butterfly/butterfly.js
@@ -1,3 +1,4 @@
+import * as ui from "/src/modules/ui.js";
import storage from "/src/modules/storage.js";
import "./butterfly.css";
import star0 from "./stars/star0.png";
@@ -43,6 +44,8 @@ try {
} catch (error) {
if (storage.get("developer")) {
alert(`Error @ butterfly.js: ${error.message}`);
- };
+ } else {
+ ui.reportBugModal(null, String(error.stack));
+ }
throw error;
};
\ No newline at end of file
diff --git a/src/themes/themes.js b/src/themes/themes.js
index f12bcc86..c1a11559 100644
--- a/src/themes/themes.js
+++ b/src/themes/themes.js
@@ -5,6 +5,7 @@ import themes from "./themes.json";
import "./butterfly/butterfly.js";
import "./festive/festive.js";
+import * as ui from "/src/modules/ui.js";
import storage from "/src/modules/storage.js";
import * as auth from "/src/modules/auth.js";
import Element from "/src/modules/element.js";
@@ -122,8 +123,8 @@ function updateThemeCode() {
function sortKeys(obj) {
return Object.keys(obj).sort().reduce((acc, key) => {
- acc[key] = obj[key];
- return acc;
+ acc[key] = obj[key];
+ return acc;
}, {});
}
@@ -333,6 +334,8 @@ try {
} catch (error) {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
- };
+ } else {
+ ui.reportBugModal(null, String(error.stack));
+ }
throw error;
};
\ No newline at end of file
diff --git a/ta/index.html b/ta/index.html
index a8d9531f..249719a5 100644
--- a/ta/index.html
+++ b/ta/index.html
@@ -265,6 +265,7 @@
+
@@ -361,11 +362,9 @@
000