Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,18 @@ <h1 id="frq-score">4</h1>
</div>
<!-- Controls -->
<div id="controls-container" class="pill">
<button class="icon" data-modal-view="store" tooltip="Theme Store">
<i class="bi bi-shop-window"></i>
</button>
<button class="icon" data-modal-view="settings" tooltip="Settings">
<i class="bi bi-gear"></i>
</button>
<button class="pill" data-modal-view="settings/code" tooltip="Change Seat Code">
<span class="code">000</span>
</button>
<button class="icon" data-modal-view="settings/makeup" tooltip="Make Up Clicks">
<i class="bi bi-calendar-check"></i>
</button>
<button class="icon" data-modal-view="history" tooltip="Click History">
<i class="bi bi-clock-history"></i>
</button>
Expand Down
36 changes: 32 additions & 4 deletions src/clicker/clicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,14 @@ try {
ui.view("settings/code");
return;
}
await auth.sync(true, updateCode);
await auth.sync(true, updateCode)
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ clicker.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
}

init();
Expand Down Expand Up @@ -441,7 +448,14 @@ try {
text: `Use ${input}`,
class: 'submit-button',
onclick: async () => {
if (storage.get("code") !== input) await auth.clearBulkLoad();
if (storage.get("code") !== input) await auth.clearBulkLoad()
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ clicker.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
storage.set("code", input);
init();
// Close all modals
Expand All @@ -458,7 +472,14 @@ try {
} else {
// Close all modals
ui.view("");
if (storage.get("code") !== input) await auth.clearBulkLoad();
if (storage.get("code") !== input) await auth.clearBulkLoad()
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ clicker.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
storage.set("code", input);
init();
// Update URL parameters with seat code
Expand Down Expand Up @@ -570,7 +591,14 @@ try {
]);
}
// Render Theme Store
themes.renderStore();
themes.renderStore()
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ clicker.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
}

// Show multiple choice card
Expand Down
6 changes: 5 additions & 1 deletion src/design.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

body {
min-height: 100%;
padding: 50px 7.5% 25px 7.5%;
padding: 50px 7.5% 125px 7.5%;
color: var(--text-color);
background-color: var(--background-color);
font:
Expand All @@ -66,6 +66,10 @@ body.enable-transitions {
--easing: cubic-bezier(0.32, 0, 0.67, 0);
}

body:has(#header) > *:not([id]):not(dialog) {
position: fixed;
}

h1 {
font-size: 1.75rem;
}
Expand Down
32 changes: 32 additions & 0 deletions src/layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,34 @@ div.spacer {
align-self: center;
position: fixed;
bottom: 25px;
padding-left: 5px;
transition: 0.5s;
}

#controls-container:hover {
border-radius: 0 100vh 100vh 0;
transition: 0.5s;
}

#controls-container::before {
content: attr(checks);
position: absolute;
bottom: 0;
right: 75%;
height: 100%;
width: fit-content;
background-color: var(--surface-color);
color: var(--accent-text-color);
padding: 7.5px 12.5px 7.5px 17.5px;
border-radius: 50vh 0 0 50vh;
z-index: -1;
transition: 0.5s;
}

#controls-container:hover::before {
right: 100%;
background-color: var(--accent-color);
transition: 0.5s;
}

#symbols-grid {
Expand Down Expand Up @@ -281,6 +309,10 @@ div.spacer {
margin-top: 10px;
}

dialog:has(.history-feed) > button {
margin-top: 5px;
}

#history-feed {
overflow-y: auto;
height: 400px;
Expand Down
4 changes: 4 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ try {
storage.set("developer", true);
updateVersionString(true);
}

window.onerror = function (error, url, line) {
ui.reportBugModal(null, `${String(error)} at ${url} line ${line}`);
}
} catch (error) {
if (storage.get("developer")) {
alert(`Error @ main.js: ${error.message}`);
Expand Down
18 changes: 16 additions & 2 deletions src/modules/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,14 @@ export async function sync(hideWelcome = true, returnFunction = null) {
Object.entries(r.settings).forEach(([key, value]) => {
if (key !== "password" && key !== "code" && key !== "usr" && key !== "pwd" && key !== "history" && key !== "questionsAnswered" && key !== "developer" && key !== "cache" && key !== "lastBulkLoad" && key !== "adminCache" && key !== "lastAdminBulkLoad") storage.set(key, value);
});
await themes.syncTheme();
await themes.syncTheme()
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ auth.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
if (document.getElementById('clicker')) document.getElementById('clicker').classList = r.settings['layout'] || '';
}
window.location.reload();
Expand Down Expand Up @@ -591,7 +598,14 @@ export async function bulkLoad(fields = [], usr = null, pwd = null, isAdmin = fa
}
if (fields.includes('courses') ? (!(await storage.idbGet((isAdmin || isTA) ? "adminCache" : "cache") || {})?.['courses']?.length && !fetchedBulkLoad?.courses?.length) : false) {
console.log('🔴 Bulk load out of sync, reloading');
await clearBulkLoad();
await clearBulkLoad()
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ auth.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
location.reload();
return false;
}
Expand Down
13 changes: 0 additions & 13 deletions src/modules/ui.css
Original file line number Diff line number Diff line change
Expand Up @@ -623,19 +623,6 @@ body:has(.topbar) {
margin-left: -20px;
}

#controls-container .pill::before {
content: attr(checks);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
min-width: 100%;
background: var(--accent-color);
color: var(--accent-text-color);
padding: 7.5px 17.5px 2.5px 17.5px;
border-radius: 50vh 50vh 0 0;
}

[data-manual-reset-cache] {
margin-top: 10px;
}
110 changes: 97 additions & 13 deletions src/themes/themes.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,27 @@ export async function renderStore() {
await storage.idbReady;
var initialTheme = storage.get("theme") || "default";
var checks = (await storage.idbGet("cache"))?.checksCount || 0;
document.querySelector('#controls-container .pill')?.setAttribute('checks', checks);
document.getElementById("controls-container")?.setAttribute('checks', checks);
var ownedThemes = (await storage.idbGet("cache"))?.ownedThemes || [];
if (document.body.getAttribute('data-theme') && !ownedThemes.includes(document.body.getAttribute('data-theme')) && themes.find(theme => theme[0] === document.body.getAttribute('data-theme'))?.[3]) {
resetTheme();
ui.toast("Applied theme is not owned.", 2000, "error", "bi bi-exclamation-triangle-fill");
await auth.syncPush("theme");
renderStore();
await auth.syncPush("theme")
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
renderStore()
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
return;
}
var featuredTheme = themes.filter(t => t[3] && (t[0] !== document.body.getAttribute('data-theme')))[Math.floor(Math.random() * themes.filter(t => t[3] && (t[0] !== document.body.getAttribute('data-theme'))).length)];
Expand Down Expand Up @@ -244,7 +258,14 @@ export async function renderStore() {
Array.from(store.querySelectorAll('.theme-item button')).forEach(btn => {
btn.textContent = btn.parentElement.classList.contains('selected') ? "Applied" : (ownedThemes.includes(btn.parentElement.getAttribute('data-theme')) ? "Owned" : "Preview");
});
await auth.syncPush("theme");
await auth.syncPush("theme")
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
ui.toast(`Applied ${featuredTheme[1] || featuredTheme[0]} theme.`, 2000, "success", "bi bi-check2-circle");
} else {
if (featuredTheme[4] && featuredTheme[4].length && !featuredTheme[4].some(t => ownedThemes.includes(t))) {
Expand All @@ -270,7 +291,14 @@ export async function renderStore() {
icon: 'bi-bag-check-fill',
class: 'submit-button',
onclick: async () => {
await auth.buyTheme(featuredTheme[0], featuredTheme[3]);
await auth.buyTheme(featuredTheme[0], featuredTheme[3])
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
ownedThemes.push(featuredTheme[0]);
const cache = await storage.idbGet("cache") || {};
cache.ownedThemes = ownedThemes;
Expand All @@ -283,7 +311,14 @@ export async function renderStore() {
checksText.innerHTML = `<i class="bi bi-check2-circle"></i> You've got ${cache.checksCount} Check${(cache.checksCount == 1) ? '' : 's'} available to spend!`;
storage.set("theme", featuredTheme[0]);
document.body.setAttribute('data-theme', featuredTheme[0]);
await auth.syncPush("theme");
await auth.syncPush("theme")
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
ui.toast(`Purchased and applied ${featuredTheme[1] || featuredTheme[0]} theme.`, 2000, "success", "bi bi-bag-check-fill");
},
close: true,
Expand Down Expand Up @@ -346,7 +381,14 @@ export async function renderStore() {
Array.from(store.querySelectorAll('.theme-item button')).forEach(btn => {
btn.textContent = btn.parentElement.classList.contains('selected') ? "Applied" : (ownedThemes.includes(btn.parentElement.getAttribute('data-theme')) ? "Owned" : "Preview");
});
await auth.syncPush("theme");
await auth.syncPush("theme")
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
ui.toast(`Applied ${name} theme.`, 2000, "success", "bi bi-check2-circle");
} else {
if (theme[4] && theme[4].length && !theme[4].some(t => ownedThemes.includes(t))) {
Expand All @@ -372,7 +414,14 @@ export async function renderStore() {
icon: 'bi-bag-check-fill',
class: 'submit-button',
onclick: async () => {
await auth.buyTheme(theme[0], theme[3]);
await auth.buyTheme(theme[0], theme[3])
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
ownedThemes.push(theme[0]);
const cache = await storage.idbGet("cache") || {};
cache.ownedThemes = ownedThemes;
Expand All @@ -385,7 +434,14 @@ export async function renderStore() {
checksText.innerHTML = `<i class="bi bi-check2-circle"></i> You've got ${cache.checksCount} Check${(cache.checksCount == 1) ? '' : 's'} available to spend!`;
storage.set("theme", theme[0]);
document.body.setAttribute('data-theme', theme[0]);
await auth.syncPush("theme");
await auth.syncPush("theme")
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
ui.toast(`Purchased and applied ${name} theme.`, 2000, "success", "bi bi-bag-check-fill");
},
close: true,
Expand Down Expand Up @@ -461,8 +517,22 @@ try {
storage.set("theme", value);
// Update developer theme input
if (document.getElementById("theme-debug")) document.getElementById("theme-debug").value = value;
await auth.syncPush("theme");
await auth.syncPush("custom-theme");
await auth.syncPush("theme")
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
await auth.syncPush("custom-theme")
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
});

document.getElementById("theme-reset")?.addEventListener("click", resetTheme);
Expand All @@ -477,8 +547,22 @@ try {
storage.set("custom-theme", customTheme);
storage.set("theme", "custom");
applyCustomTheme();
await auth.syncPush("custom-theme");
await auth.syncPush("theme");
await auth.syncPush("custom-theme")
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
await auth.syncPush("theme")
.catch(error => {
if (storage.get("developer")) {
alert(`Error @ themes.js: ${error.message}`);
} else {
ui.reportBugModal(null, String(error.stack));
}
});
});

document.getElementById("editor-reset")?.addEventListener("click", () => {
Expand Down