Skip to content

Commit

Permalink
Inscriber recipe layout.
Browse files Browse the repository at this point in the history
Pull up page title.
  • Loading branch information
shartte committed Jul 9, 2023
1 parent 93db53b commit 151ecb0
Show file tree
Hide file tree
Showing 16 changed files with 144 additions and 35 deletions.
10 changes: 7 additions & 3 deletions src/GuideShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { Link, Outlet } from "react-router-dom";
import logo from "./assets/logo_00.png";
import GuideNavBar from "./GuideNavBar.tsx";
import { useGuide } from "./data/Guide.ts";
import { useCallback, useState } from "react";
import { ReactElement, useCallback, useState } from "react";
import { GuidePageTitleProvider } from "./components/GuidePageTitleProvider.tsx";

function GuideShell() {
const guide = useGuide();
Expand All @@ -12,6 +13,7 @@ function GuideShell() {
const toggleMenu = useCallback(() => {
setMenuExpanded((expanded) => !expanded);
}, []);
const [pageTitle, setPageTitle] = useState<ReactElement | null>(null);

return (
<main className={css.main + " " + (menuExpanded ? css.menuExpanded : "")}>
Expand All @@ -33,12 +35,14 @@ function GuideShell() {
<span aria-hidden="true"></span>
</a>
</div>
<div>{/* TODO Show title */}</div>
<div>{pageTitle}</div>
<aside onClick={() => setMenuExpanded(false)}>
<GuideNavBar />
</aside>
<article>
<Outlet />
<GuidePageTitleProvider value={setPageTitle}>
<Outlet />
</GuidePageTitleProvider>
</article>
<div className={css.versionPicker}>
Minecraft {guide.gameVersion} [<a href="#/">change</a>]
Expand Down
Binary file removed src/assets/inscriber_arrows_bg_light.png
Binary file not shown.
Binary file added src/assets/inscriber_bottom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/inscriber_right.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/inscriber_top.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/components/GuidePageTitleProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createContext, ReactElement, useContext } from "react";

type GuidePageTitleSetter = (title: ReactElement | null) => void;

const context = createContext<GuidePageTitleSetter>(() => {});

export function useGuidePageTitleSetter() {
return useContext(context);
}

export const GuidePageTitleProvider = context.Provider;
11 changes: 9 additions & 2 deletions src/components/GuidebookPageRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ExportedPage, useGuide } from "../data/Guide.ts";
import { compilePage } from "../page-compiler/compilePage.tsx";
import { useMemo } from "react";
import { useEffect, useMemo } from "react";
import { useGuidePageTitleSetter } from "./GuidePageTitleProvider.tsx";

export type GuidebookPageRouteProps = {
pageId: string;
Expand All @@ -9,7 +10,13 @@ export type GuidebookPageRouteProps = {

function GuidebookPageRoute({ pageId, page }: GuidebookPageRouteProps) {
const guide = useGuide();
return useMemo(() => compilePage(guide, pageId, page), [guide, pageId, page]);
const { title, content } = useMemo(
() => compilePage(guide, pageId, page),
[guide, pageId, page]
);
const setPageTitle = useGuidePageTitleSetter();
useEffect(() => setPageTitle(title), [setPageTitle, title]);
return content;
}

export default GuidebookPageRoute;
7 changes: 2 additions & 5 deletions src/components/recipes/ChargerRecipe.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import css from "./recipe.module.css";
import RecipeIngredient from "./RecipeIngredient";
import RecipeArrow from "./RecipeArrow";
import { ChargerRecipeInfo, useGuide } from "../../data/Guide.ts";
import { ChargerRecipeInfo } from "../../data/Guide.ts";
import MinecraftFrame from "../MinecraftFrame.tsx";
import ItemIcon from "../ItemIcon.tsx";

Expand All @@ -10,14 +10,11 @@ export interface ChargerRecipeProps {
}

function ChargerRecipe({ recipe }: ChargerRecipeProps) {
const guide = useGuide();
const resultItem = guide.getItemInfo(recipe.resultItem);

return (
<MinecraftFrame>
<div className={css.recipeBoxLayout}>
<div>
<ItemIcon nolink id="charger" /> Charger: {resultItem.displayName}
<ItemIcon nolink id="charger" /> Charger
</div>
<RecipeIngredient itemIds={recipe.ingredient} />
<RecipeArrow />
Expand Down
19 changes: 10 additions & 9 deletions src/components/recipes/InscriberRecipe.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
import css from "./recipe.module.css";
import RecipeIngredient from "./RecipeIngredient";
import RecipeArrow from "./RecipeArrow";
import { InscriberRecipeInfo, useGuide } from "../../data/Guide.ts";
import { InscriberRecipeInfo } from "../../data/Guide.ts";
import MinecraftFrame from "../MinecraftFrame.tsx";
import ItemIcon from "../ItemIcon.tsx";
import topArrow from "../../assets/inscriber_top.png";
import bottomArrow from "../../assets/inscriber_bottom.png";
import rightArrow from "../../assets/inscriber_right.png";

export interface InscriberRecipeProps {
recipe: InscriberRecipeInfo;
}

function InscriberRecipe({ recipe }: InscriberRecipeProps) {
const guide = useGuide();
const resultItem = guide.getItemInfo(recipe.resultItem);

return (
<MinecraftFrame>
<div className={css.recipeBoxLayout}>
<div>
<ItemIcon nolink id="inscriber" /> Inscriber: {resultItem.displayName}
<ItemIcon nolink id="inscriber" /> Inscriber
</div>
<div style={{ display: "flex", flexDirection: "column" }}>
<div className={css.inscriberGrid}>
<RecipeIngredient itemIds={recipe.top} />
<RecipeIngredient itemIds={recipe.middle} />
<RecipeIngredient itemIds={recipe.bottom} />
<RecipeIngredient itemIds={[recipe.resultItem]} />
<img src={topArrow} alt="" />
<img src={bottomArrow} alt="" />
<img src={rightArrow} alt="" />
</div>
<RecipeArrow />
<RecipeIngredient itemIds={[recipe.resultItem]} />
</div>
</MinecraftFrame>
);
Expand Down
9 changes: 7 additions & 2 deletions src/components/recipes/InscriberRecipes.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import InscriberRecipe from "./InscriberRecipe";
import css from "./recipe.module.css";
import { useGuide } from "../../data/Guide.ts";
import { RecipeType, useGuide } from "../../data/Guide.ts";
import { useMemo } from "react";

function InscriberRecipes() {
const guide = useGuide();
const recipes = useMemo(
() => guide.getRecipesByType(RecipeType.InscriberRecipeType),
[guide]
);
return (
<div className={css.recipeContainer}>
{Object.values(guide.inscriberRecipes).map((recipe) => (
{recipes.map((recipe) => (
<InscriberRecipe key={recipe.id} recipe={recipe} />
))}
</div>
Expand Down
10 changes: 7 additions & 3 deletions src/components/recipes/Recipe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@ export type RecipeProps =
}
| { id?: never; recipe: TaggedRecipe };

function UnsupportedRecipeType({ recipe }: { recipe: TaggedRecipe }) {
return <ErrorText>Unsupported Recipe Type ({recipe.type})</ErrorText>;
}

const RecipeTypeMap: Record<RecipeType, JSXElementConstructor<any>> = {
[RecipeType.CraftingRecipeType]: CraftingRecipe,
[RecipeType.SmeltingRecipeType]: SmeltingRecipe,
// [RecipeType.StonecuttingRecipeType]: StonecuttingRecipe,
[RecipeType.StonecuttingRecipeType]: UnsupportedRecipeType,
[RecipeType.SmithingRecipeType]: SmithingRecipe,
[RecipeType.TransformRecipeType]: TransformRecipe,
[RecipeType.InscriberRecipeType]: InscriberRecipe,
[RecipeType.ChargerRecipeType]: ChargerRecipe,
// [RecipeType.EntropyRecipeType]: EntropyRecipe,
// [RecipeType.MatterCannonAmmoType]: MatterCannonAmmo,
[RecipeType.EntropyRecipeType]: UnsupportedRecipeType,
[RecipeType.MatterCannonAmmoType]: UnsupportedRecipeType,
};

function Recipe(props: RecipeProps) {
Expand Down
10 changes: 3 additions & 7 deletions src/components/recipes/SmeltingRecipe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import css from "./recipe.module.css";
import RecipeIngredient from "./RecipeIngredient";
import smelt from "./smelt.png";
import RecipeArrow from "./RecipeArrow";
import { SmeltingRecipeInfo, useGuide } from "../../data/Guide.ts";
import { SmeltingRecipeInfo } from "../../data/Guide.ts";
import MinecraftFrame from "../MinecraftFrame.tsx";
import ItemIcon from "../ItemIcon.tsx";

Expand All @@ -11,19 +11,15 @@ export interface SmeltingRecipeProps {
}

function SmeltingRecipe({ recipe }: SmeltingRecipeProps) {
const guide = useGuide();
const resultItem = guide.getItemInfo(recipe.resultItem);

return (
<MinecraftFrame>
<div className={css.recipeBoxLayout}>
<div>
<ItemIcon nolink id="minecraft:furnace" /> Smelting:{" "}
{resultItem.displayName}
<ItemIcon nolink id="minecraft:furnace" /> Smelting
</div>
<div className={css.smeltingInputBox}>
<RecipeIngredient itemIds={recipe.ingredient} />
<div className={css.ingredientBox}>
<div>
<img className="item-icon" src={smelt} alt="fire" />
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions src/components/recipes/TransformRecipe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ function FluidTransformCircumstance({ fluids }: { fluids: string[] }) {
<img
className={css.fluidIcon}
src={guide.baseUrl + "/" + fluidInfo.icon}
alt=""
/>
{" Throw in " + fluidInfo.displayName}
</>
Expand Down
60 changes: 58 additions & 2 deletions src/components/recipes/recipe.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

/* This is the title row */
.recipeBoxLayout > :first-child {
grid-column-start: span 3;
grid-column: 1 / span 3;
color: #333333;
display: flex;
flex-direction: row;
Expand Down Expand Up @@ -121,4 +121,60 @@
.smeltingInputBox > :last-child {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
}

.inscriberGrid {
display: grid;
grid-template-columns: auto auto max-content auto;
grid-template-rows: auto auto auto;
grid-column: 1 / span 3;
align-items: center;
justify-items: center;
}

/* top */
.inscriberGrid > :nth-child(1) {
grid-row: 1;
grid-column: 1;
}

/* middle */
.inscriberGrid > :nth-child(2) {
grid-row: 2;
grid-column: 2;
}

/* bottom */
.inscriberGrid > :nth-child(3) {
grid-row: 3;
grid-column: 1;
}

/* result */
.inscriberGrid > :nth-child(4) {
grid-row: 2;
grid-column: 4;
}

/* top arrow */
.inscriberGrid > :nth-child(5) {
grid-row: 1;
grid-column: 2;
width: calc(17px * var(--gui-scale));
margin-top: calc(10px * var(--gui-scale));
}

/* bottom arrow */
.inscriberGrid > :nth-child(6) {
grid-row: 3;
grid-column: 2;
width: calc(17px * var(--gui-scale));
margin-bottom: calc(10px * var(--gui-scale));
}

/* right arrow */
.inscriberGrid > :nth-child(7) {
grid-row: 2;
grid-column: 3;
height: calc(16px * var(--gui-scale));
}
8 changes: 8 additions & 0 deletions src/data/Guide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,14 @@ export class Guide {
return this.index.recipes[recipeId];
}

getRecipesByType<T extends RecipeType, RT = TaggedRecipe & { type: T }>(
recipeType: T
): RT[] {
return Object.values(this.index.recipes).filter(
(recipe) => recipe.type === recipeType
) as RT[];
}

getRecipesForItem(item: string): TaggedRecipe[] {
return this.recipesForItems.get(item) ?? [];
}
Expand Down
23 changes: 21 additions & 2 deletions src/page-compiler/compilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export function compilePage(
guide: Guide,
pageId: string,
page: ExportedPage
): ReactNode {
): { title: ReactElement | null; content: ReactNode } {
const astRoot = page.astRoot;
assertNodeType(astRoot, "root");

Expand All @@ -151,5 +151,24 @@ export function compilePage(
compileContentNode: (node, parent) => compileContent(context, node, parent),
};

return context.compileChildren(astRoot);
let title: ReactElement | null = null;

// Clone root
const clonedRoot = {
...astRoot,
children: [...astRoot.children],
};
for (let i = 0; i < clonedRoot.children.length; i++) {
const child = clonedRoot.children[i];
if (child.type === "heading") {
if (child.depth === 1) {
title = compileHeading(context, child);
clonedRoot.children.splice(i, 1);
}
break;
}
}
const content = context.compileChildren(clonedRoot);

return { title, content };
}

0 comments on commit 151ecb0

Please sign in to comment.