Skip to content

Commit

Permalink
Inspector Width (#68)
Browse files Browse the repository at this point in the history
* add max width/height to svg viewer, add key to traitTable

* adjust rawSvg/formattedSvg naming
  • Loading branch information
mshrieve authored Jul 19, 2022
1 parent 803b76c commit db3d6b1
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 58 deletions.
2 changes: 1 addition & 1 deletion lib/forge-std
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { useEffect, useRef } from "react";
import { downloadSVG, downloadPNG, scaleCanvas } from "../util/index";

type RawSVGViewerProps = {
type SVGViewerProps = {
debug?: boolean;
className?: string;
rawSVG: string;
svg: string;
isLoading?: boolean;
tokenId: number;
};

const WIDTH = 1200;
const HEIGHT = 1200;

export function RawSVGViewer(props: RawSVGViewerProps) {
export function SVGViewer(props: SVGViewerProps) {
const canvasRef = useRef(null);

useEffect(() => {
Expand All @@ -21,7 +21,7 @@ export function RawSVGViewer(props: RawSVGViewerProps) {

return (
<div
className={`rounded-3xl shadow-elevation-medium relative h-full max-h-[54rem] w-auto bg-white/5 ${props.className}`}
className={`rounded-3xl shadow-elevation-medium relative h-full max-h-[600px] max-w-[600px] w-auto bg-white/5 ${props.className}`}
>
<canvas
ref={canvasRef}
Expand All @@ -34,7 +34,7 @@ export function RawSVGViewer(props: RawSVGViewerProps) {
className={`rounded-3xl h-full w-auto overflow-hidden transition-opacity duration-300 ${
props.isLoading ? "opacity-0" : "opacity-100"
} ${props.debug ? "debug-svg" : ""}`}
dangerouslySetInnerHTML={{ __html: props.rawSVG }}
dangerouslySetInnerHTML={{ __html: props.svg }}
/>
<div
className={`rounded-3xl z-90 absolute content-none top-0 left-0 right-0 bottom-0 ${
Expand All @@ -45,14 +45,14 @@ export function RawSVGViewer(props: RawSVGViewerProps) {
<div className="absolute right-0 bottom-0 p-4 flex gap-x-2">
<button
className="text-sm exclusion bg-white/10 border border-white/10 rounded-lg px-2 py-0.5 text-label"
onClick={() => downloadSVG(props.rawSVG, 'bibo' + props.tokenId)}
onClick={() => downloadSVG(props.svg, "bibo" + props.tokenId)}
>
↓ SVG
</button>

<button
className="text-sm exclusion bg-white/10 border border-white/10 rounded-lg px-2 py-0.5 text-label"
onClick={() => downloadPNG(canvasRef, props.rawSVG, 'bibo' + props.tokenId, WIDTH, HEIGHT)}
onClick={() => downloadPNG(canvasRef, props.svg, "bibo" + props.tokenId, WIDTH, HEIGHT)}
>
↓ PNG
</button>
Expand All @@ -62,7 +62,7 @@ export function RawSVGViewer(props: RawSVGViewerProps) {
);
}

RawSVGViewer.defaultProps = {
SVGViewer.defaultProps = {
debug: false,
className: "",
};
5 changes: 4 additions & 1 deletion packages/inspector/components/TraitsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export const TraitsTable = ({
<span className="w-full px-8 py-2 text-label font-bold bg-[#21262d]">{name}</span>

{attributes.map(({ trait_type, value }, i) => (
<span className={`w-full flex ${isOdd(i) ? "bg-[#21262d]" : "bg-[#161b22]"}`}>
<span
key={trait_type}
className={`w-full flex ${isOdd(i) ? "bg-[#21262d]" : "bg-[#161b22]"}`}
>
<span className="w-full px-8 py-1 text-label text-sm">{trait_type}</span>
<span className="w-full px-8 py-1 text-primary text-sm">{value}</span>
</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,36 @@
import { useState, useEffect } from "react";
// import babelParser from 'prettier/parser-babel'
import htmlParser from 'prettier/parser-html'
import prettier from 'prettier/standalone'
import htmlParser from "prettier/parser-html";
import prettier from "prettier/standalone";

const options = {
parser: 'html',
parser: "html",
plugins: [htmlParser],
tabWidth: 2,
semi: false,
singleQuote: false,
bracketSameLine: true,
}
};

function formatSVG(code: string) {
return prettier.format(code, options)
return prettier.format(code, options);
}


export const useSvg = (svg: string) => {
const [formatted, setFormatted] = useState("");
export const useFormattedSvg = (svg: string) => {
const [formattedSvg, setFormattedSvg] = useState("");
const [error, setError] = useState("");

useEffect(() => {
try {
if (svg === null) {
setFormatted("");
setFormattedSvg("");
} else {
setFormatted(formatSVG(svg));
setFormattedSvg(formatSVG(svg));
}
} catch (e) {
setError(e.message);
}
}, [svg]);

return { formatted, error };
return { formattedSvg, error };
};
10 changes: 5 additions & 5 deletions packages/inspector/hooks/useNFT.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState, useEffect } from "react";
import { decodeBase64 } from "../util";
import { trait, NFTState } from "../types";
import { NFTState } from "../types";

const defaultState = {
metadata: {
Expand All @@ -9,7 +9,7 @@ const defaultState = {
attributes: [],
},
tokenId: null,
rawSVG: null,
svg: null,
};

export const useNFT = (tokenURI: string) => {
Expand All @@ -18,14 +18,14 @@ export const useNFT = (tokenURI: string) => {
useEffect(() => {
if (tokenURI == null) return;
// decode and parse metadata
console.log(decodeBase64(tokenURI))
console.log(decodeBase64(tokenURI));
const metadata = JSON.parse(decodeBase64(tokenURI));

const tokenId = metadata.tokenId;

// decode svg
const rawSVG = decodeBase64(metadata.image);
setState({ metadata, tokenId, rawSVG });
const svg = decodeBase64(metadata.image);
setState({ metadata, tokenId, svg });
}, [tokenURI]);

return { ...state };
Expand Down
68 changes: 37 additions & 31 deletions packages/inspector/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
import { useState } from "react";
import SyntaxHighlighter from "react-syntax-highlighter";
import { xml } from '@codemirror/lang-xml'
import { EditorView } from '@codemirror/view'
import { basicSetup } from 'codemirror'
import CodeMirror from '@uiw/react-codemirror'
import { syntaxHighlighting, bracketMatching, foldGutter, codeFolding } from '@codemirror/language'
import { highlightDark, themeDark } from '../components/CodeMirrorTheme'
import { xml } from "@codemirror/lang-xml";
import { EditorView } from "@codemirror/view";
import { basicSetup } from "codemirror";
import CodeMirror from "@uiw/react-codemirror";
import { syntaxHighlighting, bracketMatching, foldGutter, codeFolding } from "@codemirror/language";
import { highlightDark, themeDark } from "../components/CodeMirrorTheme";

import { NFTStatus, IndexView } from "../types";
import { useLocalRender } from "../hooks/useLocalRender";
import { useNFT } from "../hooks/useNFT";
import { useSvg } from "../hooks/useSVG";
import { useFormattedSvg } from "../hooks/useFormattedSVG";
import { Container } from "../components/Container";
import { Pane } from "../components/Pane";
import { HorizontalRule } from "../components/HorizontalRule";
import { Toolbar } from "../components/Toolbar";
import { VerticalRule } from "../components/VerticalRule";
import { Button } from "../components/Button";
import { RawSVGViewer } from "../components/RawSVGViewer";
import { SVGViewer } from "../components/SVGViewer";
import { ToggleButton } from "../components/ToggleButton";
import { TraitsTable } from "../components/TraitsTable";

export default function Index() {
const { tokenURI, status, handleFetchNFT } = useLocalRender();
const { metadata, tokenId, rawSVG } = useNFT(tokenURI);
const { metadata, tokenId, svg } = useNFT(tokenURI);
const [debug, setDebug] = useState(false);
const { formatted, error } = useSvg(rawSVG);
const { formattedSvg, error } = useFormattedSvg(svg);

const loc = formatted.split(/\r\n|\r|\n/).length;
const kb = ((new TextEncoder().encode(rawSVG)).length * 0.001).toFixed(3)
const loc = formattedSvg.split(/\r\n|\r|\n/).length;
const kb = (new TextEncoder().encode(svg).length * 0.001).toFixed(3);

return (
<Container>
<Pane>
<div className="flex h-full overflow-y-scroll">
<CodeMirror
<CodeMirror
className="w-full h-full border-none overflow-y-scroll scrollbar-none"
value={formatted}
value={formattedSvg}
// height={ '100%' }
basicSetup={{
foldGutter: false,
Expand All @@ -48,7 +48,7 @@ export default function Index() {
EditorView.lineWrapping,
syntaxHighlighting(highlightDark),
codeFolding({
placeholderText:"􀠪",
placeholderText: "􀠪",
}),
foldGutter({
markerDOM(open) {
Expand All @@ -60,24 +60,20 @@ export default function Index() {
el.className = "user-select-none text-[#ff7b72]";
el.innerHTML = "􀯽";
}
return el
}}),
return el;
},
}),
]}
/>
</div>
{
error.length === 0 ? (
null
) :
{error.length === 0 ? null : (
<>
<div className="border-t border-t-red-500/50 flex flex-col w-full px-4 py-2 bg-red-500/10 text-label">
<div className="w-full text-sm font-bold text-red-500">
Error parsing SVG
<div className="border-t border-t-red-500/50 flex flex-col w-full px-4 py-2 bg-red-500/10 text-label">
<div className="w-full text-sm font-bold text-red-500">Error parsing SVG</div>
<div className="w-full text-sm">{error}</div>
</div>
<div className="w-full text-sm">{error}</div>
</div>
</>
}
)}
<HorizontalRule />
<Toolbar className="justify-between">
<div className="text-label flex gap-x-1 items-center">
Expand All @@ -86,9 +82,14 @@ export default function Index() {
</div>

<div className="flex gap-x-2 items-center">
<div className="text-label text-sm"><div className="inline mr-1">{loc}</div><div className="inline opacity-50">LOC</div></div>
<div className="text-label text-sm"><div className="inline mr-1">{kb}</div><div className="inline opacity-50">kb</div></div>

<div className="text-label text-sm">
<div className="inline mr-1">{loc}</div>
<div className="inline opacity-50">LOC</div>
</div>
<div className="text-label text-sm">
<div className="inline mr-1">{kb}</div>
<div className="inline opacity-50">kb</div>
</div>
</div>
</Toolbar>
</Pane>
Expand All @@ -97,7 +98,12 @@ export default function Index() {

<Pane className="items-center h-full">
<div className="flex w-full h-full items-center justify-center p-8">
<RawSVGViewer tokenId={tokenId} rawSVG={rawSVG} debug={debug} isLoading={status == NFTStatus.FETCHING}/>
<SVGViewer
tokenId={tokenId}
svg={svg}
debug={debug}
isLoading={status == NFTStatus.FETCHING}
/>
</div>

<TraitsTable
Expand Down
2 changes: 1 addition & 1 deletion packages/inspector/types/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export type NFTState = {
attributes: trait[];
};
tokenId: number;
rawSVG: string;
svg: string;
};

export type GenericComponentProps = {
Expand Down

0 comments on commit db3d6b1

Please sign in to comment.