Created an initialization function for when the page loads, and/or we need to populate data after recovering from the API server being down. Removed console log error messages for when API server is down. Fixed Summary coloring for scenes with no entrances.

This commit is contained in:
Ada Werefox 2024-04-07 20:13:07 -05:00
parent 171c491497
commit f15f125630
7 changed files with 504 additions and 155 deletions

View File

@ -5,6 +5,10 @@
"entrances": 1312, "entrances": 1312,
"hints": 0, "hints": 0,
"codes": { "codes": {
"empty": 0 "???": {
"Distance": 0,
"Global": false,
"InRange": false
}
} }
} }

View File

@ -11,20 +11,18 @@ var total_checks = 0;
var total_entrances = 0; var total_entrances = 0;
// Global state internal // Global state internal
var server_address = ""; var server_address = "localhost:51111";
var cross_codes = {}; var cross_codes = {};
var can_access_api_server = true;
window.onload = () => { window.onload = async () => {
get_updated_server_address(); await get_updated_server_address();
fetch(`${document.URL}static/tracker/data/holy_cross_codes.json`) fetch(`${document.URL}static/tracker/data/holy_cross_codes.json`)
.then((response) => response.json()) .then((response) => response.json())
.then( .then(
(data) => { (data) => {
cross_codes = JSON.parse(JSON.stringify(data)); cross_codes = JSON.parse(JSON.stringify(data));
refresh_overview().then((overview) => { initialize_elements();
perform_updates(true, true, true, true);
update_overview(overview, true);
});
refresh_elements(); refresh_elements();
}, },
(error) => { (error) => {
@ -33,40 +31,350 @@ window.onload = () => {
); );
}; };
async function refresh_elements() { // A function to call when the page loads to ensure that we have the correct data when we connect to the server.
const overview = await refresh_overview().catch(() => async function initialize_elements() {
console.log("Could not access the API server.") // Grab all updates from the backend.
); let overview = await refresh_overview();
if (!overview.overview) {
return;
}
const checks = await refresh_checks();
const entrances = await refresh_entrances();
const hints = await refresh_hints();
overview = overview.overview;
if (overview) { // Initialize overview data.
document.getElementById("status-block").classList.add("hidden"); current_checks = checks.collected;
current_entrances = entrances.found;
total_checks = checks.total;
total_entrances = entrances.total;
update_overview(overview, true);
const changed_seed = overview.seed != current_seed; // Initialize breakdown list
const changed_scene = overview.scene != current_scene; let breakdown_list = document
const changed_checks = overview.items != current_checks; .getElementById("breakdown-list")
const changed_entrances = overview.entrances != current_entrances; .cloneNode(true);
const changed_hints = overview.hints != current_hints; let breakdown_list_item = breakdown_list.firstElementChild.cloneNode(true);
const any_change = breakdown_list.innerHTML = "";
changed_seed || breakdown_list.appendChild(breakdown_list_item.cloneNode(true));
changed_scene || breakdown_list_item.classList.remove("hidden");
changed_checks ||
changed_entrances ||
changed_hints;
if (any_change) { // Initialize summary list
await perform_updates( let summary_list = document.getElementById("summary-list").cloneNode(true);
changed_seed, let summary_list_item =
changed_checks, summary_list.firstElementChild.firstElementChild.cloneNode(true);
changed_entrances, summary_list.firstElementChild.innerHTML = "";
changed_hints summary_list.firstElementChild.appendChild(summary_list_item.cloneNode(true));
); summary_list_item.classList.remove("hidden");
update_overview(overview, changed_scene);
// Initialize codes list
let codes_list = document.getElementById("codes-list").cloneNode(true);
let codes_list_item = codes_list.firstElementChild.cloneNode(true);
codes_list.innerHTML = "";
codes_list.appendChild(codes_list_item.cloneNode(true));
codes_list_item.classList.remove("hidden");
// Initialize hints list
let hints_list = document.getElementById("hints-list").cloneNode(true);
let hints_list_item = hints_list.firstElementChild.cloneNode(true);
hints_list.innerHTML = "";
hints_list.appendChild(hints_list_item.cloneNode(true));
hints_list_item.classList.remove("hidden");
// Populate the breakdown list
Object.keys(checks.scenes).forEach((scene) => {
// One-time update the title for each scene.
if (current_scene == scene) {
breakdown_list_item.dataset.current = "true";
breakdown_list_item.classList.remove("hidden", "order-last");
breakdown_list_item.classList.add("order-first");
} else {
breakdown_list_item.dataset.current = "false";
breakdown_list_item.classList.add("hidden", "order-last");
breakdown_list_item.classList.remove("order-first");
} }
await update_codes(overview.codes); breakdown_list_item.dataset.breakdownScene = scene;
breakdown_list_item.querySelector(".breakdown-block-title").textContent =
scene;
// Populate checks data
breakdown_list_item.querySelector(
".breakdown-block-checks-title"
).textContent = `Checks: ${checks.scenes[scene].collected}/${checks.scenes[scene].total}/(${checks.scenes[scene].remaining} left)`;
breakdown_list_item.querySelector(
".breakdown-block-checks-title"
).dataset.checksCollected = checks.scenes[scene].collected;
breakdown_list_item.querySelector(
".breakdown-block-checks-title"
).dataset.checksRemaining = checks.scenes[scene].remaining;
breakdown_list_item.querySelector(
".breakdown-block-checks-title"
).dataset.checksTotal = checks.scenes[scene].total;
// Populate entrances data
breakdown_list_item.querySelector(
".breakdown-block-entrances-title"
).textContent = `Entrances: ${entrances.scenes[scene].found}/${entrances.scenes[scene].total}/(${entrances.scenes[scene].remaining} left)`;
breakdown_list_item.querySelector(
".breakdown-block-entrances-title"
).dataset.entrancesFound = entrances.scenes[scene].found;
breakdown_list_item.querySelector(
".breakdown-block-entrances-title"
).dataset.entrancesRemaining = entrances.scenes[scene].remaining;
breakdown_list_item.querySelector(
".breakdown-block-entrances-title"
).dataset.entrancesTotal = entrances.scenes[scene].total;
// Initialize checks list
let new_breakdown_block_checks_list = breakdown_list_item
.querySelector(".breakdown-block-checks-list")
.cloneNode(true);
let new_breakdown_block_checks_list_item =
new_breakdown_block_checks_list.firstElementChild.cloneNode(true);
new_breakdown_block_checks_list.innerHTML = "";
new_breakdown_block_checks_list.appendChild(
new_breakdown_block_checks_list_item.cloneNode(true)
);
new_breakdown_block_checks_list_item.classList.remove("hidden");
// Initialize entrances list
let new_breakdown_block_entrances_list = breakdown_list_item
.querySelector(".breakdown-block-entrances-list")
.cloneNode(true);
let new_breakdown_block_entrances_list_item =
new_breakdown_block_entrances_list.firstElementChild.cloneNode(true);
new_breakdown_block_entrances_list.innerHTML = "";
new_breakdown_block_entrances_list.appendChild(
new_breakdown_block_entrances_list_item.cloneNode(true)
);
new_breakdown_block_entrances_list_item.classList.remove("hidden");
// Initialize mapped list
let new_breakdown_block_mapped_list = breakdown_list_item
.querySelector(".breakdown-block-mapped-list")
.cloneNode(true);
let new_breakdown_block_mapped_list_item =
new_breakdown_block_mapped_list.firstElementChild.cloneNode(true);
new_breakdown_block_mapped_list.innerHTML = "";
new_breakdown_block_mapped_list.appendChild(
new_breakdown_block_mapped_list_item.cloneNode(true)
);
new_breakdown_block_mapped_list_item.classList.remove("hidden");
// Create checks list
Object.keys(checks.scenes[scene].checks).forEach((check) => {
new_breakdown_block_checks_list_item.textContent = `${check}`;
if (!checks.scenes[scene].checks[check].name) {
new_breakdown_block_checks_list.appendChild(
new_breakdown_block_checks_list_item.cloneNode(true)
);
}
});
// Create entrances list and mapped list
Object.keys(entrances.scenes[scene].doors).forEach((entrance) => {
if (!entrances.scenes[scene].doors[entrance].door) {
new_breakdown_block_entrances_list_item.textContent = `${entrance}`;
new_breakdown_block_entrances_list.appendChild(
new_breakdown_block_entrances_list_item.cloneNode(true)
);
} else {
new_breakdown_block_mapped_list_item.dataset.scene =
entrances.scenes[scene].doors[entrance].scene;
new_breakdown_block_mapped_list_item.textContent = `✔️ ${entrance} -> ${entrances.scenes[scene].doors[entrance].door}`;
new_breakdown_block_mapped_list.appendChild(
new_breakdown_block_mapped_list_item.cloneNode(true)
);
}
});
// Replace lists in breakdown
breakdown_list_item
.querySelector(".breakdown-block-checks-list")
.replaceWith(new_breakdown_block_checks_list.cloneNode(true));
breakdown_list_item
.querySelector(".breakdown-block-entrances-list")
.replaceWith(new_breakdown_block_entrances_list.cloneNode(true));
breakdown_list_item
.querySelector(".breakdown-block-mapped-list")
.replaceWith(new_breakdown_block_mapped_list.cloneNode(true));
// Add breakdown to list
breakdown_list.appendChild(breakdown_list_item.cloneNode(true));
});
// Populate the summary list
for (const scene of Object.keys(checks.scenes)) {
// One-time update data for scene
summary_list_item.dataset.scene = scene;
summary_list_item.querySelector(".summary-title").textContent = scene;
// Update checks and entrances
summary_list_item.dataset.checksCollected = checks.scenes[scene].collected;
summary_list_item.dataset.checksRemaining = checks.scenes[scene].remaining;
summary_list_item.dataset.checksTotal = checks.scenes[scene].total;
summary_list_item.querySelector(
".summary-checks"
).textContent = `Checks: ${checks.scenes[scene].collected}/${checks.scenes[scene].total} (${checks.scenes[scene].total})`;
summary_list_item.dataset.entrancesFound = entrances.scenes[scene].found;
summary_list_item.dataset.entrancesRemaining =
entrances.scenes[scene].remaining;
summary_list_item.dataset.entrancesTotal = entrances.scenes[scene].total;
summary_list_item.querySelector(
".summary-entrances"
).textContent = `Entrances: ${entrances.scenes[scene].found}/${entrances.scenes[scene].total} (${entrances.scenes[scene].total})`;
// Hide summaries for scenes with no entrances
if (entrances.scenes[scene].total <= 0) {
summary_list_item.classList.add("hidden");
} else {
summary_list_item.classList.remove("hidden");
}
// Apply color coding and add summary to list
summary_list_item.firstElementChild.replaceWith(
await apply_summary_colors({
element: summary_list_item.firstElementChild.cloneNode(true),
checks_collected: checks.scenes[scene].collected,
checks_total: checks.scenes[scene].total,
entrances_found: entrances.scenes[scene].found,
entrances_total: entrances.scenes[scene].total,
})
);
summary_list.firstElementChild.appendChild(
summary_list_item.cloneNode(true)
);
}
// Populate the codes list
Object.keys(overview.codes)
.sort((i, j) => {
return overview.codes[i].Distance - overview.codes[j].Distance;
})
.forEach((codename, index) => {
// One-time update data for code
codes_list_item.dataset.codename = codename;
codes_list_item.dataset.order = index;
codes_list_item.querySelector(".codes-list-item-title").textContent =
codename;
// Update code
if (overview.codes[codename].Global) {
codes_list_item.querySelector(".codes-list-item-code").textContent =
cross_codes["Global"][codename]
.replace(/U/g, "⬆️")
.replace(/R/g, "➡️")
.replace(/D/g, "⬇️")
.replace(/L/g, "⬅️");
} else {
codes_list_item.querySelector(".codes-list-item-code").textContent =
cross_codes[overview.scene][codename]
.replace(/U/g, "⬆️")
.replace(/R/g, "➡️")
.replace(/D/g, "⬇️")
.replace(/L/g, "⬅️");
}
// Add code to list
codes_list.appendChild(codes_list_item.cloneNode(true));
});
Object.keys(cross_codes.Default).forEach((codename) => {
// One-time update data for default code
codes_list_item.dataset.codename = codename;
codes_list_item.dataset.order = "last";
codes_list_item.querySelector(".codes-list-item-title").textContent =
codename;
// Update code
codes_list_item.querySelector(".codes-list-item-code").textContent =
cross_codes.Default[codename]
.replace(/U/g, "⬆️")
.replace(/R/g, "➡️")
.replace(/D/g, "⬇️")
.replace(/L/g, "⬅️");
// Add code to list
codes_list.appendChild(codes_list_item.cloneNode(true));
});
// Populate the hints list
Object.keys(hints).forEach((hint) => {
// Update hint
hints_list_item.firstElementChild.textContent = hints[hint];
// Add hint to list
hints_list.appendChild(hints_list_item.cloneNode(true));
});
// Replace breakdown list
document
.getElementById("breakdown-list")
.replaceWith(breakdown_list.cloneNode(true));
// Replace summary list
document
.getElementById("summary-list")
.replaceWith(summary_list.cloneNode(true));
// Replace codes list
document.getElementById("codes-list").replaceWith(codes_list.cloneNode(true));
// Replace hints list
document.getElementById("hints-list").replaceWith(hints_list.cloneNode(true));
// update_if_changes(overview);
// update_checks(checks);
// update_entrances(entrances);
// update_hints(hints);
return;
}
async function refresh_elements() {
const response = await refresh_overview();
if (response.overview) {
if (!can_access_api_server) {
console.log("I found the server!");
can_access_api_server = true;
await initialize_elements();
}
update_if_changes(response.overview);
} else {
if (can_access_api_server) {
console.log("Could not access the API server.");
}
can_access_api_server = false;
} }
setTimeout(refresh_elements, 500); setTimeout(refresh_elements, 500);
} }
async function update_if_changes(overview) {
document.getElementById("status-block").classList.add("hidden");
const changed_seed = overview.seed != current_seed;
const changed_scene = overview.scene != current_scene;
const changed_checks = overview.items != current_checks;
const changed_entrances = overview.entrances != current_entrances;
const changed_hints = overview.hints != current_hints;
const any_change =
changed_seed ||
changed_scene ||
changed_checks ||
changed_entrances ||
changed_hints;
if (any_change) {
await perform_updates(
changed_seed,
changed_checks,
changed_entrances,
changed_hints
);
update_overview(overview, changed_scene);
}
await update_codes(overview.codes);
}
async function perform_updates( async function perform_updates(
changed_seed, changed_seed,
changed_checks, changed_checks,
@ -104,9 +412,9 @@ async function get_updated_server_address() {
(data) => { (data) => {
const parsed_data = JSON.parse(JSON.stringify(data)); const parsed_data = JSON.parse(JSON.stringify(data));
server_address = parsed_data["listen_address"]; server_address = parsed_data["listen_address"];
if (parsed_data["backend_filepath_updated"]) { // if (parsed_data["backend_filepath_updated"]) {
get_updated_filepath(); // get_updated_filepath();
} // }
}, },
(error) => { (error) => {
console.log(error); console.log(error);
@ -115,9 +423,18 @@ async function get_updated_server_address() {
} }
async function refresh_overview() { async function refresh_overview() {
const response = await fetch(`${server_address}overview`); try {
const data = await response.json(); const response = await fetch(`${server_address}overview`);
return data; if (response.ok) {
const data = await response.json();
if (!("error" in data)) {
return { overview: data, error: null };
}
}
return { overview: null, error: null };
} catch (e) {
return { overview: null, error: e };
}
} }
async function refresh_hints() { async function refresh_hints() {
@ -249,7 +566,6 @@ async function update_codes(codes) {
.getElementById("codes-list") .getElementById("codes-list")
.querySelector(`[data-codename="${code}"]`).classList .querySelector(`[data-codename="${code}"]`).classList
).filter((classname) => classname.startsWith("order-")); ).filter((classname) => classname.startsWith("order-"));
// console.log(classes);
if (classes.length > 0) { if (classes.length > 0) {
document document
.getElementById("codes-list") .getElementById("codes-list")
@ -344,7 +660,15 @@ async function apply_summary_colors(summary) {
"text-highlight-both-text" "text-highlight-both-text"
); );
} }
} else {
summary.element.classList.add(
"from-highlight-undiscovered-light",
"to-highlight-undiscovered-dark",
"text-highlight-undiscovered-text"
);
} }
return summary.element;
} }
async function update_summary(updates) { async function update_summary(updates) {
@ -353,7 +677,7 @@ async function update_summary(updates) {
.getElementById("summary-list") .getElementById("summary-list")
.querySelector(`[data-scene="${updates.scene}"]`) .querySelector(`[data-scene="${updates.scene}"]`)
.querySelector(".summary-checks"); .querySelector(".summary-checks");
summary_checks.textContent = `Checks: ${updates.checks.collected}/${summary_checks.dataset.checksTotal} (${updates.checks.remaining} left)`; summary_checks.textContent = `Checks: ${updates.checks.collected}/${summary_checks.dataset.checksTotal} (${updates.checks.remaining})`;
summary_checks.dataset.checksUndiscovered = updates.checks.collected; summary_checks.dataset.checksUndiscovered = updates.checks.collected;
apply_summary_colors({ apply_summary_colors({
element: document element: document
@ -414,45 +738,52 @@ async function update_checks(checks) {
document.getElementById("breakdown-list").children document.getElementById("breakdown-list").children
); );
breakdown_list.forEach((scene) => { breakdown_list.forEach((scene) => {
// Create variables for element pointers. if (scene.querySelector(".breakdown-block-title").textContent) {
let scene_title = scene.querySelector(".breakdown-block-title").textContent; // Create variables for element pointers.
if (scene_title) { let scene_title = scene.querySelector(
const scene_checks = parseInt( ".breakdown-block-title"
scene.querySelector(".breakdown-block-checks-title").dataset.checks ).textContent;
); if (scene_title) {
if (scene_checks != checks.scenes[scene_title].collected) { const scene_checks = parseInt(
scene.querySelector(".breakdown-block-checks-title").dataset.checks = scene.querySelector(".breakdown-block-checks-title").dataset.checks
scene_checks; );
update_summary({ if (scene_checks != checks.scenes[scene_title].collected) {
scene: scene_title, scene.querySelector(".breakdown-block-checks-title").dataset.checks =
checks: { scene_checks;
collected: checks.scenes[scene_title].collected, update_summary({
remaining: checks.scenes[scene_title].remaining, scene: scene_title,
}, checks: {
}); collected: checks.scenes[scene_title].collected,
scene.querySelector( remaining: checks.scenes[scene_title].remaining,
".breakdown-block-checks-title" },
).textContent = `Checks: ${checks.scenes[scene_title].collected}/${checks.scenes[scene_title].total} (${checks.scenes[scene_title].remaining})`; });
scene.querySelector(
".breakdown-block-checks-title"
).textContent = `Checks: ${checks.scenes[scene_title].collected}/${checks.scenes[scene_title].total} (${checks.scenes[scene_title].remaining})`;
new_breakdown_block_checks_list.innerHTML = ""; new_breakdown_block_checks_list.innerHTML = "";
breakdown_block_checks_list_item.classList.remove("hidden"); new_breakdown_block_checks_list.appendChild(
Object.keys(checks.scenes[scene_title].checks).forEach((check) => { breakdown_block_checks_list_item.cloneNode(true)
if (checks.scenes[scene_title].checks[check].name == "") { );
breakdown_block_checks_list_item.textContent = `${check}`; breakdown_block_checks_list_item.classList.remove("hidden");
new_breakdown_block_checks_list.appendChild( Object.keys(checks.scenes[scene_title].checks).forEach((check) => {
breakdown_block_checks_list_item.cloneNode(true) if (checks.scenes[scene_title].checks[check].name == "") {
); breakdown_block_checks_list_item.textContent = `${check}`;
} new_breakdown_block_checks_list.appendChild(
}); breakdown_block_checks_list_item.cloneNode(true)
document );
.getElementById("breakdown-list") }
.querySelector(`[data-breakdown-scene="${scene_title}"]`) });
.querySelector(".breakdown-block-checks-list").innerHTML = ""; document
document .getElementById("breakdown-list")
.getElementById("breakdown-list") .querySelector(`[data-breakdown-scene="${scene_title}"]`)
.querySelector(`[data-breakdown-scene="${scene_title}"]`) .querySelector(".breakdown-block-checks-list").innerHTML = "";
.querySelector(".breakdown-block-checks-list") document
.replaceWith(new_breakdown_block_checks_list.cloneNode(true)); .getElementById("breakdown-list")
.querySelector(`[data-breakdown-scene="${scene_title}"]`)
.querySelector(".breakdown-block-checks-list")
.replaceWith(new_breakdown_block_checks_list.cloneNode(true));
}
} }
} }
}); });
@ -483,66 +814,76 @@ async function update_entrances(entrances) {
document.getElementById("breakdown-list").children document.getElementById("breakdown-list").children
); );
breakdown_list.forEach((scene) => { breakdown_list.forEach((scene) => {
// Create variables for element pointers. if (scene.querySelector(".breakdown-block-title").textContent) {
let scene_title = scene.querySelector(".breakdown-block-title").textContent; // Create variables for element pointers.
if (scene_title) { let scene_title = scene.querySelector(
const scene_entrances = parseInt( ".breakdown-block-title"
scene.querySelector(".breakdown-block-entrances-title").dataset ).textContent;
.entrances if (scene_title) {
); const scene_entrances = parseInt(
if (scene_entrances != entrances.scenes[scene_title].found) { scene.querySelector(".breakdown-block-entrances-title").dataset
scene.querySelector(".breakdown-block-checks-title").dataset.entrances = .entrances
scene_entrances; );
update_summary({ if (scene_entrances != entrances.scenes[scene_title].found) {
scene: scene_title, scene.querySelector(
entrances: { ".breakdown-block-checks-title"
found: entrances.scenes[scene_title].found, ).dataset.entrances = scene_entrances;
remaining: entrances.scenes[scene_title].remaining, update_summary({
}, scene: scene_title,
}); entrances: {
scene.querySelector( found: entrances.scenes[scene_title].found,
".breakdown-block-entrances-title" remaining: entrances.scenes[scene_title].remaining,
).textContent = `Entrances: ${entrances.scenes[scene_title].found}/${entrances.scenes[scene_title].total} (${entrances.scenes[scene_title].remaining})`; },
});
scene.querySelector(
".breakdown-block-entrances-title"
).textContent = `Entrances: ${entrances.scenes[scene_title].found}/${entrances.scenes[scene_title].total} (${entrances.scenes[scene_title].remaining})`;
new_breakdown_block_entrances_list.innerHTML = ""; new_breakdown_block_entrances_list.innerHTML = "";
breakdown_block_entrances_list_item.classList.remove("hidden"); new_breakdown_block_entrances_list.appendChild(
new_breakdown_block_mapped_list.innerHTML = ""; breakdown_block_entrances_list_item.cloneNode(true)
breakdown_block_mapped_list_item.classList.remove("hidden"); );
breakdown_block_entrances_list_item.classList.remove("hidden");
new_breakdown_block_mapped_list.innerHTML = "";
breakdown_block_mapped_list_item.classList.remove("hidden");
Object.keys(entrances.scenes[scene_title].doors).forEach((entrance) => { Object.keys(entrances.scenes[scene_title].doors).forEach(
if (entrances.scenes[scene_title].doors[entrance].door == "") { (entrance) => {
breakdown_block_entrances_list_item.textContent = `${entrance}`; if (entrances.scenes[scene_title].doors[entrance].door == "") {
new_breakdown_block_entrances_list.appendChild( breakdown_block_entrances_list_item.textContent = `${entrance}`;
breakdown_block_entrances_list_item.cloneNode(true) new_breakdown_block_entrances_list.appendChild(
); breakdown_block_entrances_list_item.cloneNode(true)
} else { );
breakdown_block_mapped_list_item.textContent = `✔️ ${entrance} -> ${entrances.scenes[scene_title].doors[entrance].door}`; } else {
breakdown_block_mapped_list_item.id = `${entrance}-mapped`; breakdown_block_mapped_list_item.textContent = `✔️ ${entrance} -> ${entrances.scenes[scene_title].doors[entrance].door}`;
breakdown_block_mapped_list_item.dataset.scene = breakdown_block_mapped_list_item.id = `${entrance}-mapped`;
entrances.scenes[scene_title].doors[entrance].scene; breakdown_block_mapped_list_item.dataset.scene =
new_breakdown_block_mapped_list.appendChild( entrances.scenes[scene_title].doors[entrance].scene;
breakdown_block_mapped_list_item.cloneNode(true) new_breakdown_block_mapped_list.appendChild(
); breakdown_block_mapped_list_item.cloneNode(true)
} );
}); }
document }
.getElementById("breakdown-list") );
.querySelector(`[data-breakdown-scene="${scene_title}"]`) document
.querySelector(".breakdown-block-entrances-list").innerHTML = ""; .getElementById("breakdown-list")
document .querySelector(`[data-breakdown-scene="${scene_title}"]`)
.getElementById("breakdown-list") .querySelector(".breakdown-block-entrances-list").innerHTML = "";
.querySelector(`[data-breakdown-scene="${scene_title}"]`) document
.querySelector(".breakdown-block-entrances-list") .getElementById("breakdown-list")
.replaceWith(new_breakdown_block_entrances_list.cloneNode(true)); .querySelector(`[data-breakdown-scene="${scene_title}"]`)
document .querySelector(".breakdown-block-entrances-list")
.getElementById("breakdown-list") .replaceWith(new_breakdown_block_entrances_list.cloneNode(true));
.querySelector(`[data-breakdown-scene="${scene_title}"]`) document
.querySelector(".breakdown-block-mapped-list").innerHTML = ""; .getElementById("breakdown-list")
document .querySelector(`[data-breakdown-scene="${scene_title}"]`)
.getElementById("breakdown-list") .querySelector(".breakdown-block-mapped-list").innerHTML = "";
.querySelector(`[data-breakdown-scene="${scene_title}"]`) document
.querySelector(".breakdown-block-mapped-list") .getElementById("breakdown-list")
.replaceWith(new_breakdown_block_mapped_list.cloneNode(true)); .querySelector(`[data-breakdown-scene="${scene_title}"]`)
.querySelector(".breakdown-block-mapped-list")
.replaceWith(new_breakdown_block_mapped_list.cloneNode(true));
}
} }
} }
}); });
@ -552,6 +893,8 @@ async function update_hints(hints) {
let hints_list = document.getElementById("hints-list").cloneNode(true); let hints_list = document.getElementById("hints-list").cloneNode(true);
let hints_list_item = hints_list.firstElementChild.cloneNode(true); let hints_list_item = hints_list.firstElementChild.cloneNode(true);
hints_list.innerHTML = ""; hints_list.innerHTML = "";
hints_list.appendChild(hints_list_item.cloneNode(true));
hints_list_item.classList.remove("hidden");
Object.keys(hints).forEach((hint_index) => { Object.keys(hints).forEach((hint_index) => {
let hint = hints[hint_index].split( let hint = hints[hint_index].split(
/(\[[\w\s]+?\]|\"[\w \d\>\<#.\-\']+\"|\<[\w\d#]+\>)/gm /(\[[\w\s]+?\]|\"[\w \d\>\<#.\-\']+\"|\<[\w\d#]+\>)/gm
@ -599,9 +942,7 @@ async function update_hints(hints) {
async function update_scene(scene) { async function update_scene(scene) {
Array.from(document.getElementById("breakdown-list").children).forEach( Array.from(document.getElementById("breakdown-list").children).forEach(
(breakdown) => { (breakdown) => {
const breakdown_title = breakdown.querySelector( const breakdown_title = breakdown.dataset.breakdownScene;
".breakdown-block-title"
).textContent;
if (breakdown_title == scene) { if (breakdown_title == scene) {
document document
.getElementById("breakdown-list") .getElementById("breakdown-list")
@ -632,7 +973,7 @@ async function update_scene(scene) {
.classList.add("hidden"); .classList.add("hidden");
document document
.getElementById("breakdown-list") .getElementById("breakdown-list")
.querySelector(`[data-breakdown-scene="${scene}"]`) .querySelector(`[data-breakdown-scene="${breakdown_title}"]`)
.classList.add("order-last"); .classList.add("order-last");
document document
.getElementById("breakdown-list") .getElementById("breakdown-list")
@ -648,12 +989,12 @@ async function update_scene(scene) {
if (summary_scene == scene) { if (summary_scene == scene) {
document document
.getElementById("summary-list") .getElementById("summary-list")
.firstElementChild.querySelector(`[data-scene="${scene}"]`) .querySelector(`[data-scene="${scene}"]`)
.classList.add("hidden"); .classList.add("hidden");
} else if (!(summary_scene == "")) { } else if (!(summary_scene == "")) {
document document
.getElementById("summary-list") .getElementById("summary-list")
.firstElementChild.querySelector(`[data-scene="${summary_scene}"]`) .querySelector(`[data-scene="${summary_scene}"]`)
.classList.remove("hidden"); .classList.remove("hidden");
} }
}); });

View File

@ -79,5 +79,8 @@
"Holy Cross Door": "DRULUR", "Holy Cross Door": "DRULUR",
"Holy Cross (Blue Lines)": "URULURULURDRULDLURULURULU", "Holy Cross (Blue Lines)": "URULURULURDRULDLURULURULU",
"Tree Holy Cross Chest": "LDRLUD" "Tree Holy Cross Chest": "LDRLUD"
},
"???": {
"???": "UDLR"
} }
} }

View File

@ -12,7 +12,7 @@
</div> </div>
<hr class="border-2 border-bluelight-translucent-dark rounded-xl" /> <hr class="border-2 border-bluelight-translucent-dark rounded-xl" />
</div> </div>
<div class="flex flex-col pb-4 space-y-2 overflow-scroll max-h-64 scrollbar scrollbar-thumb-bluelight-dark scrollbar-track-bluelight breakdown-block-checks-list"> <div class="grid grid-flow-row pb-4 space-y-2 overflow-scroll max-h-64 scrollbar scrollbar-thumb-bluelight-dark scrollbar-track-bluelight breakdown-block-checks-list">
<ul class="py-0.5 min-w-max bg-bluelight-translucent rounded-md px-1 text-sm hidden"> <ul class="py-0.5 min-w-max bg-bluelight-translucent rounded-md px-1 text-sm hidden">
</ul> </ul>
{% for check_name, check in scene_data.checks.checks.items %} {% for check_name, check in scene_data.checks.checks.items %}
@ -25,14 +25,14 @@
</div> </div>
</div> </div>
<div class="flex flex-col overflow-hidden basis-1/2"> <div class="flex flex-col overflow-hidden basis-1/2">
<div class="flex flex-col my-2 space-y-2"> <div class="grid grid-flow-row my-2 space-y-2">
<div class="text-md breakdown-block-entrances-title" <div class="text-md breakdown-block-entrances-title"
data-entrances="{{ scene_data.entrances.found }}"> data-entrances="{{ scene_data.entrances.found }}">
Entrances: {{ scene_data.entrances.found }}/{{ scene_data.entrances.total }} ({{ scene_data.entrances.remaining }} left) Entrances: {{ scene_data.entrances.found }}/{{ scene_data.entrances.total }} ({{ scene_data.entrances.remaining }} left)
</div> </div>
<hr class="border-2 border-bluelight-translucent-dark rounded-xl" /> <hr class="border-2 border-bluelight-translucent-dark rounded-xl" />
</div> </div>
<div class="flex flex-col pb-4 space-y-2 overflow-scroll max-h-64 scrollbar scrollbar-thumb-bluelight-dark scrollbar-track-bluelight breakdown-block-entrances-list"> <div class="grid grid-flow-row pb-4 space-y-2 overflow-scroll max-h-64 scrollbar scrollbar-thumb-bluelight-dark scrollbar-track-bluelight breakdown-block-entrances-list">
<ul class="py-0.5 min-w-max bg-bluelight-translucent rounded-md px-1 text-sm hidden"> <ul class="py-0.5 min-w-max bg-bluelight-translucent rounded-md px-1 text-sm hidden">
</ul> </ul>
{% for entrance_origin, entrance_destination in scene_data.entrances.doors.items %} {% for entrance_origin, entrance_destination in scene_data.entrances.doors.items %}
@ -54,7 +54,6 @@
{% if entrance_destination.door %} {% if entrance_destination.door %}
<button type="button" <button type="button"
class="py-0.5 text-start bg-gradient-to-br from-bluelight-translucent-dark to-trans-pride-cyan-translucent rounded-md px-1 text-sm shadow-sm shadow-[#242424]" class="py-0.5 text-start bg-gradient-to-br from-bluelight-translucent-dark to-trans-pride-cyan-translucent rounded-md px-1 text-sm shadow-sm shadow-[#242424]"
id="{{ entrance_origin }}-mapped"
onclick="open_breakdown(this)" onclick="open_breakdown(this)"
data-scene="{{ entrance_destination.scene }}"> data-scene="{{ entrance_destination.scene }}">
✔️ {{ entrance_origin }} -> {{ entrance_destination.door }} ✔️ {{ entrance_origin }} -> {{ entrance_destination.door }}

View File

@ -1,3 +1,3 @@
<div class="h-full min-w-full p-2 rounded-md bg-[rgb(36,36,36)] bg-opacity-35"> <div class="h-full min-w-full p-2 rounded-md bg-[rgb(36,36,36)] bg-opacity-35 {{ extra_classes }}">
<div class="inline align-top text-md {% comment "" %}inline-block{% endcomment %}">{{ value }}</div> <div class="inline align-top text-md {% comment "" %}inline-block{% endcomment %}">{{ value }}</div>
</div> </div>

View File

@ -15,7 +15,7 @@
</span> </span>
<div class="min-w-0 my-auto text-xl align-middle overflow-clip sm:text-3xl">Tunic Transition Tracker</div> <div class="min-w-0 my-auto text-xl align-middle overflow-clip sm:text-3xl">Tunic Transition Tracker</div>
</div> </div>
<div class="flex-row pb-2 space-y-1 text-lg sm:text-2xl max-w-fit font-trunic"> <div class="flex pb-2 text-lg sm:text-2xl max-w-fit font-trunic">
( (
<div class="pt-1.5 text-sm sm:text-lg">&nbsp;tuniik' t'raan'ziishuun' t'raakx&nbsp;</div> <div class="pt-1.5 text-sm sm:text-lg">&nbsp;tuniik' t'raan'ziishuun' t'raakx&nbsp;</div>
) )
@ -79,7 +79,7 @@
<hr class="border-2 border-bluelight-translucent-dark rounded-xl" /> <hr class="border-2 border-bluelight-translucent-dark rounded-xl" />
<div class="flex-col py-2 space-y-1 *:text-wrap *:break-words" <div class="flex-col py-2 space-y-1 *:text-wrap *:break-words"
id="hints-list"> id="hints-list">
{% include "tracker/hints/index.html" with value="" %} {% include "tracker/hints/index.html" with value="" extra_classes="hidden" %}
{% for name, value in hints.items %} {% for name, value in hints.items %}
{% include "tracker/hints/index.html" %} {% include "tracker/hints/index.html" %}
{% endfor %} {% endfor %}

View File

@ -48,17 +48,19 @@ def index(request):
f"{listen_address}hints", timeout=5, verify=True f"{listen_address}hints", timeout=5, verify=True
).text ).text
tracker_overview_data = loads(request_overview_data) tracker_overview_data = loads(request_overview_data)
if "error" in tracker_overview_data.keys():
raise ValueError
tracker_items_data = loads(request_items_data) tracker_items_data = loads(request_items_data)
tracker_doors_data = loads(request_doors_data) tracker_doors_data = loads(request_doors_data)
tracker_hints_data = loads(request_hints_data) tracker_hints_data = loads(request_hints_data)
except: except:
with open("less_fun_overview.json", "r") as t: with open("empty_overview.json", "r") as t:
tracker_overview_data = loads(t.read()) tracker_overview_data = loads(t.read())
with open("less_fun_items.json", "r") as t: with open("empty_items.json", "r") as t:
tracker_items_data = loads(t.read()) tracker_items_data = loads(t.read())
with open("less_fun_doors.json", "r") as t: with open("empty_doors.json", "r") as t:
tracker_doors_data = loads(t.read()) tracker_doors_data = loads(t.read())
with open("less_fun_hints.json", "r") as t: with open("empty_hints.json", "r") as t:
tracker_hints_data = loads(t.read()) tracker_hints_data = loads(t.read())
with open("tracker/static/tracker/data/holy_cross_codes.json", "r") as t: with open("tracker/static/tracker/data/holy_cross_codes.json", "r") as t:
try: try: