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:
parent
bf7f860ed1
commit
c8abe91459
@ -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
|
||||
|
@ -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 (
|
||||
<>
|
||||
|
@ -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}>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
46
apps/blueprints/src/components/blueprint/BlueprintImage.tsx
Normal file
46
apps/blueprints/src/components/blueprint/BlueprintImage.tsx
Normal 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}
|
||||
/>
|
||||
);
|
||||
};
|
42
apps/blueprints/src/hooks/window.hooks.ts
Normal file
42
apps/blueprints/src/hooks/window.hooks.ts
Normal 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;
|
||||
}
|
@ -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) || "");
|
||||
|
@ -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"}
|
||||
|
@ -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})`);
|
||||
|
Loading…
Reference in New Issue
Block a user