From 6c134aa197746eb8339182a2e4d62c6306e7cfed Mon Sep 17 00:00:00 2001 From: Hamcha Date: Tue, 25 Aug 2020 15:28:42 +0200 Subject: [PATCH] Add food and drink page tweaks --- src/index.ts | 63 +++++++------ src/scripts/index.ts | 9 ++ src/scripts/pages/food.ts | 190 ++++++++++++++++++++++++++++++++++++++ src/scripts/search.ts | 1 - style/main.scss | 1 + style/pages/food.scss | 134 +++++++++++++++++++++++++++ style/pages/global.scss | 4 + 7 files changed, 374 insertions(+), 28 deletions(-) create mode 100644 src/scripts/pages/food.ts create mode 100644 style/pages/food.scss diff --git a/src/index.ts b/src/index.ts index a278c4f..df5928b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,9 @@ import { searchBox } from "./scripts/search"; import unknown from "~/assets/images/tab-icons/unknown.svg"; import { bindFunctions } from "./scripts/index"; +// Enable single page mode for developing scripts +const devSinglePage = null; //["Other", "Guide_to_food_and_drinks"]; + async function load() { const sectionListContainer = document.getElementById("section-list"); const tabListContainer = document.getElementById("tab-list"); @@ -24,43 +27,49 @@ async function load() { const spinnerContainer = document.querySelector("#tabs > .speen"); const icons = document.createElement("div"); icons.className = "loading-icons"; - sections.forEach((section) => - section.tabs.forEach((tab) => { - const iconElement = document.createElement("img"); - iconElement.dataset.tab = tab.page; - iconElement.src = tab.icon || unknown; - iconElement.title = tab.page.replace(/_/gi, " "); - icons.appendChild(iconElement); - }) - ); - spinnerContainer.appendChild(icons); - const promises = sections.flatMap((section) => { - manager.createSection(section.name); + let promises = []; + if (devSinglePage != null) { + manager.createSection(devSinglePage[0]); + promises = [manager.openTab(devSinglePage[0], devSinglePage[1], {})]; + } else { + sections.forEach((section) => + section.tabs.forEach((tab) => { + const iconElement = document.createElement("img"); + iconElement.dataset.tab = tab.page; + iconElement.src = tab.icon || unknown; + iconElement.title = tab.page.replace(/_/gi, " "); + icons.appendChild(iconElement); + }) + ); + spinnerContainer.appendChild(icons); - return section.tabs.map(async (tab) => { - // Load page - await manager.openTab(section.name, tab.page, { - icon: tab.icon, - text: tab.text, + promises = sections.flatMap((section) => { + manager.createSection(section.name); + + return section.tabs.map(async (tab) => { + // Load page + await manager.openTab(section.name, tab.page, { + icon: tab.icon, + text: tab.text, + }); + // Remove icon from loading + icons.removeChild(icons.querySelector(`img[data-tab=${tab.page}]`)); }); - // Remove icon from loading - icons.removeChild(icons.querySelector(`img[data-tab=${tab.page}]`)); }); - }); - - manager.showSection("Medical"); - // DEV: If you only need one page just comment the block above and uncomment this: - // manager.createSection("Medical"); - // const promises = [manager.openTab("Medical", "Infections", {})]; - + } const welcome = document.getElementById("Welcome"); bindFunctions(welcome, "$Welcome"); Promise.all(promises).then(() => { // Remove app-wide loading manager.setLoading(false); - welcome.classList.add("active"); + if (devSinglePage) { + manager.setActive(devSinglePage[1]); + } else { + manager.showSection("Medical"); + welcome.classList.add("active"); + } }); } if ("serviceWorker" in navigator) { diff --git a/src/scripts/index.ts b/src/scripts/index.ts index da7d70f..a2e592c 100644 --- a/src/scripts/index.ts +++ b/src/scripts/index.ts @@ -1,5 +1,6 @@ import { chemistryScript, processChemistry } from "./pages/chemistry"; import { processVirology, virologyScript } from "./pages/virology"; +import { processFood, foodScript } from "./pages/food"; import { genericScript } from "./pages/generic"; import { processGlobal } from "./pages/global"; import { welcomeScript } from "./pages/welcome"; @@ -8,6 +9,7 @@ import { welcomeScript } from "./pages/welcome"; // Only change it when you made changes to the processHTML part! export const PAGE_VERSIONS = { Infections: "fcebeda2fddb46d924f4538cd9c0daeb55aa4c9b", + Guide_to_food_and_drinks: "131e010df66ed689d31df53c3ca17ad16635a827", $DEFAULT: "bb7abd544a19369d4b6b7e3dde3eb3cc34c023d4", }; @@ -23,6 +25,9 @@ export function processHTML(root: HTMLElement, docname: string): void { case "Infections": processVirology(root); break; + case "Guide_to_food_and_drinks": + processFood(root); + break; default: } } @@ -63,6 +68,10 @@ export function bindFunctions(root: HTMLElement, docname: string): void { case "$Welcome": welcomeScript(root); break; + case "Guide_to_food_and_drinks": + genericScript(root, docname); + foodScript(root); + break; default: genericScript(root, docname); break; diff --git a/src/scripts/pages/food.ts b/src/scripts/pages/food.ts new file mode 100644 index 0000000..b6cf4a9 --- /dev/null +++ b/src/scripts/pages/food.ts @@ -0,0 +1,190 @@ +import { parseTable, makeTable } from "../utils"; +import { registerSearchEntries } from "../search"; + +export function processFood(root: HTMLElement): void { + const drinkTables = ["#Basic_Drink_Ingredients", "#Mixed_Drinks"]; + drinkTables.forEach((selector) => { + const table = root.querySelector(`${selector} .wikitable`); + const drinks = parseTable(table).map((row) => { + const foodBlock = document.createElement("td"); + foodBlock.innerHTML = ` +
${row["Picture"].innerHTML}
+
${row["Cocktail"].innerHTML}
+

${row["Strength"].innerHTML}

+

${row["Drink Description"].innerHTML}

+

${row["Notes"].innerHTML}

+`; + const ingredients = row["Ingredients"].innerHTML + .split(/,|\+/gi) + .map((s) => `

${s.trim()}

`); + row["Ingredients"].innerHTML = ingredients.join(""); + return { Drink: foodBlock, Ingredients: row["Ingredients"] }; + }); + const betterTable = makeTable(["Drink", "Ingredients"], drinks); + betterTable.className = "drink-ext wikitable"; + table.replaceWith(betterTable); + }); + + const baseFoodTables = [ + { + selector: "#Butchering", + title: "Food name", + process: "How to acquire", + }, + { + selector: "#Knife_\\.26_Rolling_Pin", + title: "Food name", + process: "How to acquire", + }, + { + selector: "#Processor", + title: "Processes", + process: "Condiments", + }, + { + selector: "#All-In-One-Grinder", + title: "Blends", + process: "How to acquire", + }, + { + selector: "#Microwave_Oven", + title: "Cooked food", + process: "How to acquire", + }, + { + selector: "#Junk_Food", + title: "Dispenses", + process: "Description", + }, + { + selector: "#Junk_Drinks", + title: "Dispenses", + process: "Description", + }, + { + selector: "#Hot_Drinks", + title: "Dispenses", + process: "Description", + }, + { + selector: "#Other_food", + title: "Item", + process: "Description", + }, + ]; + baseFoodTables.forEach(({ selector, title, process }) => { + const table = root.querySelector(`${selector} .wikitable`); + const foods = parseTable(table).map((row) => { + const foodBlock = document.createElement("td"); + foodBlock.innerHTML = `
+
${row["Picture"].innerHTML}
+
${row[title].innerHTML}
+
+`; + const out = {}; + out[title] = foodBlock; + out[process] = row[process]; + return out; + }); + const betterTable = makeTable([title, process], foods); + betterTable.className = "food-base-ext wikitable"; + table.replaceWith(betterTable); + }); + + const customTable = root.querySelector( + `#Custom_Recipes .wikitable` + ); + const customFood = parseTable(customTable).map((row) => { + row[ + "Custom food" + ].innerHTML = `
${row["Custom food"].innerHTML}
`; + return row; + }); + const betterCustomTable = makeTable(Object.keys(customFood[0]), customFood); + betterCustomTable.className = "food-base-ext wikitable"; + customTable.replaceWith(betterCustomTable); + + const recipeBookTable = root.querySelector( + `#Recipe_Books .wikitable` + ); + const recipeBook = parseTable(recipeBookTable).map((row) => { + const bookBlock = document.createElement("td"); + bookBlock.innerHTML = `
${row["Picture"].innerHTML}
+
${row["Book"].innerHTML}
+

${row["Unlocks"].innerHTML}

+

${row["Notes"].innerHTML}

+`; + return { Book: bookBlock, "Where to get": row["Where to get"] }; + }); + const betterBookTable = makeTable(["Book", "Where to get"], recipeBook); + betterBookTable.className = "book-ext wikitable"; + recipeBookTable.replaceWith(betterBookTable); + + const foodRecipesTables = [ + "#Burgers", + "#Breads", + "#Sandwiches", + "#Pizzas", + "#Pastas", + "#Soups_\\.26_Stews", + "#Seafood", + "#Meat", + "#Misc\\._Food", + "#Frozen", + "#Pies", + "#Salads", + "#Cakes", + "#Side_Dishes", + "#Pastries", + "#Sweets", + "#Icecream_Vat", + "#Exotic", + ]; + foodRecipesTables.forEach((selector) => { + const table = root.querySelector(`${selector} .wikitable`); + const recipes = parseTable(table).map((row) => { + const foodBlock = document.createElement("td"); + foodBlock.innerHTML = ` +
${row["Picture"].innerHTML}
+
${row["Recipe"].innerHTML}
+${ + "Nutritional Value" in row + ? `

${row["Nutritional Value"].innerHTML}

` + : "" +} +${"Notes" in row ? `

${row["Notes"].innerHTML}

` : ""} +`; + const ingredients = row["Ingredients"].innerHTML + .split(/,|\+/gi) + .map((s) => `

${s.trim()}

`); + row["Ingredients"].innerHTML = ingredients.join(""); + return { Drink: foodBlock, Ingredients: row["Ingredients"] }; + }); + const betterTable = makeTable(["Drink", "Ingredients"], recipes); + betterTable.className = "recipe-ext wikitable"; + table.replaceWith(betterTable); + }); +} + +export function foodScript(root: HTMLElement): void { + // Init fuzzy search with elements + const foodEntries = Array.from( + root.querySelectorAll( + ".drink-ext tr:not(:first-child), .food-base-ext tr:not(:first-child), .food-ext tr:not(:first-child)" + ) + ); + registerSearchEntries( + foodEntries.map((element, id) => ({ + page: "Guide_to_food_and_drinks", + name: element.querySelector(".food-name").textContent.trim(), + element, + alignment: "center", + id, + })) + ); +} + +export default { + processFood, + foodScript, +}; diff --git a/src/scripts/search.ts b/src/scripts/search.ts index 75dedc5..da10c2c 100644 --- a/src/scripts/search.ts +++ b/src/scripts/search.ts @@ -138,7 +138,6 @@ export function searchBox(): HTMLElement { await nextAnimationFrame(); - console.log(results); resultList.innerHTML = ""; results.forEach((elem) => { const li = document.createElement("li"); diff --git a/style/main.scss b/style/main.scss index 45a581b..0e48756 100644 --- a/style/main.scss +++ b/style/main.scss @@ -4,5 +4,6 @@ $nanotrasen: #384e68; @import "search.scss"; @import "pages/global.scss"; @import "pages/chemistry.scss"; +@import "pages/food.scss"; @import "pages/virology.scss"; @import "pages/welcome.scss"; diff --git a/style/pages/food.scss b/style/pages/food.scss new file mode 100644 index 0000000..a48a26f --- /dev/null +++ b/style/pages/food.scss @@ -0,0 +1,134 @@ +div[data-tab="Guide_to_food_and_drinks"] { + .drink-ext, + .food-base-ext, + .book-ext, + .recipe-ext { + width: 100%; + th, + td:first-child { + background-color: #2f4257; + } + .food-pic { + float: left; + min-width: 64px; + min-height: 64px; + display: flex; + align-items: center; + justify-content: center; + } + .food-name { + font-size: 12pt; + text-align: left; + padding: 10pt; + padding-bottom: 0; + margin-bottom: 10pt; + } + p { + font-size: 8pt; + font-weight: 300; + line-height: 1.2em; + word-spacing: -0.1em; + margin: 5pt 0; + } + + .bgus_fz_selected { + background: $nanotrasen !important; + th, + td { + border-top: 2px solid lighten($nanotrasen, 20%); + border-bottom: 2px solid lighten($nanotrasen, 15%); + } + th { + background: lighten($nanotrasen, 5%) !important; + } + div.tooltiptext { + border-color: lighten($nanotrasen, 20%); + background: darken($nanotrasen, 10%); + } + } + } + + .drink-ext { + p { + font-size: 9pt; + } + .strength { + font-size: 9pt; + &:before { + content: "Strength: "; + font-weight: bold; + } + } + .description, + .notes { + margin: 10pt 0; + line-height: 1.5em; + } + td:nth-child(2) { + width: 30vw; + max-width: 300px; + text-align: center; + } + } + + .food-base-ext { + td:nth-child(1) { + width: 30vw; + max-width: 300px; + text-align: center; + } + .food-pic { + float: none; + min-width: 64px; + min-height: 64px; + display: inline-block; + } + .food-block { + display: flex; + align-items: center; + } + td:nth-child(2) { + padding: 5pt; + font-size: 10pt; + } + } + + .book-ext { + p { + font-size: 9pt; + } + .description, + .notes { + margin: 10pt 0; + line-height: 1.5em; + } + .unlocks { + &:before { + content: "Unlocks: "; + font-weight: bold; + } + } + td:nth-child(2) { + width: 30vw; + max-width: 300px; + text-align: center; + p { + font-size: 9pt; + } + } + } + + .recipe-ext { + p { + font-size: 9pt; + } + td:nth-child(2) { + width: 30vw; + max-width: 300px; + } + .notes { + margin: 10pt 0; + line-height: 1.5em; + } + } +} diff --git a/style/pages/global.scss b/style/pages/global.scss index a6e322f..eb7989b 100644 --- a/style/pages/global.scss +++ b/style/pages/global.scss @@ -39,6 +39,10 @@ $max-width: 960px; padding: 15pt 10pt; } + img { + vertical-align: middle; + } + p, h2, h3,