1
0
mirror of https://github.com/barthuijgen/factorio-sites.git synced 2025-01-07 13:40:12 +02:00

Integrate FBSR renderer, improve homepage responsiveness

This commit is contained in:
Bart 2021-03-18 21:01:30 +01:00
parent bf7f860ed1
commit c8abe91459
10 changed files with 140 additions and 44 deletions

View File

@ -42,8 +42,6 @@ const parseFactorioCode = (string: string): ReactNode => {
if (!iconMatches.length) return <span>{string}</span>;
// console.log(string, iconMatches);
const result = [] as ReactNode[];
let lastHandledIndex = 0;
@ -73,7 +71,6 @@ const parseFactorioCode = (string: string): ReactNode => {
match.groups.type = type;
match.groups.icon = icon;
}
console.log(match);
}
result.push(
<FactorioIcon

View File

@ -50,7 +50,6 @@ export const FullscreenImage: React.FC<FullscreenImageProps> = ({ alt, src }) =>
scale: 0.9,
translation: { x: window.innerWidth * 0.05, y: 30 },
});
console.log(src);
return (
<>

View File

@ -25,9 +25,10 @@ const editorCss = css`
interface ImageEditorProps {
string: string;
onError?: () => void;
}
export const ImageEditor: React.FC<ImageEditorProps> = ({ string }) => {
export const ImageEditor: React.FC<ImageEditorProps> = ({ string, onError }) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
// const [image, setImage] = useState<string | undefined>();
const FbeRef = useRef<FBE>();
@ -89,13 +90,14 @@ export const ImageEditor: React.FC<ImageEditorProps> = ({ string }) => {
// setImage(URL.createObjectURL(picture));
} catch (reason) {
setRenderError(true);
if (onError) onError();
if (Array.isArray(reason.errors)) {
return console.error("Blueprint string not supported by FBE", reason.errors);
}
console.error("Failed to render blueprint", reason);
}
})();
}, [string, editorLoaded]);
}, [string, editorLoaded, onError]);
return (
<div css={editorCss}>

View File

@ -5,7 +5,6 @@ import { chakraResponsive, parseBlueprintStringClient } from "@factorio-sites/we
import { Panel } from "../../components/Panel";
import { Markdown } from "../../components/Markdown";
import { CopyButton } from "../../components/CopyButton";
import { ImageEditor } from "../../components/ImageEditor";
import styled from "@emotion/styled";
import { FavoriteButton } from "./FavoriteButton";
import { useUrl } from "../../hooks/url.hook";
@ -13,9 +12,7 @@ import { BlueprintData } from "./BlueprintData";
import { BlueprintInfo } from "./BlueprintInfo";
import { BlueprintTags } from "./BlueprintTags";
import { BlueprintEntities } from "./BlueprintEntities";
import { useCookies } from "react-cookie";
import { FullscreenImage } from "../FullscreenImage";
import { isMobileBrowser } from "../../utils/navigator.utils";
import { BlueprintImage, RENDERERS } from "./BlueprintImage";
const StyledBlueptintPage = styled(Grid)`
grid-gap: 16px;
@ -58,8 +55,7 @@ export const BlueprintSubPage: React.FC<BlueprintProps> = ({
const url = useUrl();
const [string, setString] = useState<string | null>(null);
const [data, setData] = useState<BlueprintStringData | null>(null);
const [cookies] = useCookies();
const isFbeRenderer = cookies.renderer !== "fbsr" && !isMobileBrowser();
const [renderer, setRenderer] = useState<RENDERERS | null>(null);
useEffect(() => {
fetch(`/api/string/${blueprint.blueprint_hash}`)
@ -84,7 +80,7 @@ export const BlueprintSubPage: React.FC<BlueprintProps> = ({
title={
<>
<span>Image</span>
{isFbeRenderer && (
{renderer === "fbe" && (
<img
src="/fbe.svg"
alt="Factorio blueprint editor"
@ -110,15 +106,14 @@ export const BlueprintSubPage: React.FC<BlueprintProps> = ({
</>
}
>
{string &&
(isFbeRenderer ? (
<ImageEditor string={string}></ImageEditor>
) : (
<FullscreenImage
src={`https://fbsr.factorio.workers.dev/${blueprint.blueprint_hash}?size=1000`}
alt={blueprint.label}
/>
))}
{string && (
<BlueprintImage
string={string}
label={blueprint.label}
blueprint_hash={blueprint.blueprint_hash}
onSetRenderer={setRenderer}
/>
)}
</Panel>
<Panel

View File

@ -17,7 +17,6 @@ import { Panel } from "../../components/Panel";
import { Markdown } from "../../components/Markdown";
import { BookChildTree } from "../../components/BookChildTree";
import { CopyButton } from "../../components/CopyButton";
import { ImageEditor } from "../../components/ImageEditor";
import { useUrl } from "../../hooks/url.hook";
import { FavoriteButton } from "./FavoriteButton";
import { BlueprintData } from "./BlueprintData";
@ -25,9 +24,7 @@ import { BlueprintInfo } from "./BlueprintInfo";
import { BlueprintTags } from "./BlueprintTags";
import { BlueprintEntities } from "./BlueprintEntities";
import { FactorioCode } from "../FactorioCode";
import { useCookies } from "react-cookie";
import { FullscreenImage } from "../FullscreenImage";
import { isMobileBrowser } from "../../utils/navigator.utils";
import { BlueprintImage, RENDERERS } from "./BlueprintImage";
const StyledBlueptintPage = styled(Grid)`
grid-gap: 16px;
@ -79,8 +76,7 @@ export const BlueprintBookSubPage: React.FC<BlueprintBookSubPageProps> = ({
null
);
const [selectedData, setSelectedData] = useState<BlueprintStringData | null>(null);
const [cookies] = useCookies();
const isFbeRenderer = cookies.renderer !== "fbsr" && !isMobileBrowser();
const [renderer, setRenderer] = useState<RENDERERS | null>(null);
const selectedHash = selected.data.blueprint_hash;
const showEntities = selected.type === "blueprint" && selectedData?.blueprint;
@ -163,7 +159,7 @@ export const BlueprintBookSubPage: React.FC<BlueprintBookSubPageProps> = ({
title={
<>
<span>Image</span>
{isFbeRenderer && (
{renderer === "fbe" && (
<img
src="/fbe.svg"
alt="Factorio blueprint editor"
@ -189,17 +185,14 @@ export const BlueprintBookSubPage: React.FC<BlueprintBookSubPageProps> = ({
</>
}
>
{selectedBlueprintString &&
(isFbeRenderer ? (
<ImageEditor string={selectedBlueprintString}></ImageEditor>
) : (
<FullscreenImage
src={`https://fbsr.factorio.workers.dev/${selected.data.blueprint_hash}?size=1000`}
alt={selected.data.label}
/>
))}
{/* {selectedBlueprintString && <ImageEditor string={selectedBlueprintString}></ImageEditor>} */}
{selectedBlueprintString && (
<BlueprintImage
string={selectedBlueprintString}
label={selected.data.label}
blueprint_hash={selected.data.blueprint_hash}
onSetRenderer={setRenderer}
/>
)}
</Panel>
<Panel

View File

@ -0,0 +1,46 @@
import { useEffect, useState } from "react";
import { useCookies } from "react-cookie";
import { useWindowWidth } from "../../hooks/window.hooks";
import { FullscreenImage } from "../FullscreenImage";
import { ImageEditor } from "../ImageEditor";
export type RENDERERS = "fbe" | "fbsr";
interface BlueprintImageProps {
string: string;
blueprint_hash: string;
label: string;
onSetRenderer?: (renderer: RENDERERS) => void;
}
export const BlueprintImage: React.FC<BlueprintImageProps> = ({
string,
blueprint_hash,
label,
onSetRenderer,
}) => {
const width = useWindowWidth();
const [cookies] = useCookies();
const determineRenderer = () => {
const isFbeRenderer = cookies.renderer !== "fbsr" && width > 760;
return isFbeRenderer ? "fbe" : "fbsr";
};
const [renderer, setRenderer] = useState<RENDERERS>(determineRenderer);
useEffect(() => {
setRenderer(determineRenderer());
if (onSetRenderer) onSetRenderer(determineRenderer());
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [blueprint_hash]);
return renderer === "fbe" ? (
<ImageEditor string={string} onError={() => setRenderer("fbsr")}></ImageEditor>
) : (
<FullscreenImage
src={`https://fbsr.factorio.workers.dev/${blueprint_hash}?size=1000`}
alt={label}
/>
);
};

View File

@ -0,0 +1,42 @@
import { useState, useEffect } from "react";
type TimeoutType = ReturnType<typeof setTimeout> | null;
const RESIZE_DEBOUNCE_MS = 100;
function getWidth() {
return typeof window !== "undefined"
? window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
: 0;
}
export function useWindowWidth() {
const [width, setWidth] = useState(getWidth());
let isMounted = false;
useEffect(() => {
let timeoutId: TimeoutType = null;
const reesizeListener = () => {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
timeoutId = setTimeout(() => {
if (isMounted) {
setWidth(getWidth());
}
}, RESIZE_DEBOUNCE_MS);
};
window.addEventListener("resize", reesizeListener);
return () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
isMounted = false;
window.removeEventListener("resize", reesizeListener);
};
});
return width;
}

View File

@ -21,19 +21,33 @@ import {
Stack,
Radio,
Checkbox,
useBreakpoint,
} from "@chakra-ui/react";
import { css } from "@emotion/react";
import { MdSearch } from "react-icons/md";
import { TAGS } from "@factorio-sites/common-utils";
import { mq } from "@factorio-sites/web-utils";
const pageCss = css({
display: "flex",
flexDirection: "column",
[mq[0]]: {
flexDirection: "row",
},
});
const sidebarCss = css({
borderRight: "1px solid #b7b7b7",
paddingRight: "1rem",
marginRight: "1rem",
width: "233px",
borderBottom: "1px solid #b7b7b7",
paddingBottom: "1rem",
marginBottom: "1rem",
[mq[0]]: {
borderRight: "1px solid #b7b7b7",
marginRight: "1rem",
paddingRight: "1rem",
borderBottom: "none",
paddingBottom: "0",
marginBottom: "0",
width: "233px",
},
});
const SidebarRow = css({
marginTop: "1rem",
@ -67,6 +81,8 @@ export const Index: NextPage<IndexProps> = ({
const [searchQuery, setSearchQuery] = useState("");
const routerQueryToHref = useRouterQueryToHref();
const data = useFbeData();
const bp = useBreakpoint();
console.log({ bp });
useEffect(() => {
setSearchQuery((router.query.q as string) || "");

View File

@ -98,6 +98,8 @@ export const UserEdit: NextPage = () => {
setCookie("renderer", value, {
path: "/",
expires: addYears(new Date(), 1),
sameSite: "strict",
secure: process.env.NODE_ENV === "production",
})
}
value={cookies.renderer || "fbe"}

View File

@ -112,3 +112,7 @@ export function chakraResponsive({
}): Array<string | null> {
return [mobile, mobile, desktop, desktop];
}
const breakpoints = ["30em", "48em", "62em", "80em"];
export const mq = breakpoints.map((bp) => `@media (min-width: ${bp})`);