1
0
Fork 0

add import/export

This commit is contained in:
iTNTPiston 2022-06-19 13:09:39 -07:00
parent 7d7e11bdb1
commit 3a92f0fc1d
22 changed files with 1185 additions and 983 deletions

View file

@ -1,16 +1,16 @@
{
"files": {
"main.css": "/static/css/main.7948f1f9.css",
"main.js": "/static/js/main.22757a4a.js",
"main.js": "/static/js/main.6564ce4b.js",
"static/js/787.ada1a5f8.chunk.js": "/static/js/787.ada1a5f8.chunk.js",
"static/media/Calamity-Regular.otf": "/static/media/Calamity-Regular.cbeefc650e6ac39335b6.otf",
"index.html": "/index.html",
"main.7948f1f9.css.map": "/static/css/main.7948f1f9.css.map",
"main.22757a4a.js.map": "/static/js/main.22757a4a.js.map",
"main.6564ce4b.js.map": "/static/js/main.6564ce4b.js.map",
"787.ada1a5f8.chunk.js.map": "/static/js/787.ada1a5f8.chunk.js.map"
},
"entrypoints": [
"static/css/main.7948f1f9.css",
"static/js/main.22757a4a.js"
"static/js/main.6564ce4b.js"
]
}

View file

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="for Breath of the Wild"/><meta property="og:site_name" content="itntpiston.app"/><meta property="og:title" content="Hundo Duplication Simulator"><meta property="og:type" content="website"><meta property="og:url" content="https://dupl.itntpiston.app/#/"><meta property="og:description" content="for Breath of the Wild"><link rel="manifest" href="/manifest.json"/><title>Hundo Duplication Simulator</title><script defer="defer" src="/static/js/main.22757a4a.js"></script><link href="/static/css/main.7948f1f9.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="for Breath of the Wild"/><meta property="og:site_name" content="itntpiston.app"/><meta property="og:title" content="Hundo Duplication Simulator"><meta property="og:type" content="website"><meta property="og:url" content="https://dupl.itntpiston.app/#/"><meta property="og:description" content="for Breath of the Wild"><link rel="manifest" href="/manifest.json"/><title>Hundo Duplication Simulator</title><script defer="defer" src="/static/js/main.6564ce4b.js"></script><link href="/static/css/main.7948f1f9.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
docs/static/js/main.6564ce4b.js.map vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,17 +1,15 @@
import { Command, CommandBreakSlots, CommandInitialize, CommandNothing, CommandReload, CommandSave, CommandSortKey } from 'core/Command';
import { Inventory } from 'core/Inventory';
import React, { useEffect, useMemo, useState } from 'react';
import { Command, CommandBreakSlots, CommandInitialize, CommandNothing, CommandReload, CommandSave, CommandSortKey } from "core/Command";
import { Inventory } from "core/Inventory";
import React, { useEffect, useMemo, useRef, useState } from "react";
import './App.css';
import { CommandItem } from './components/CommandItem';
import { ItemStack as ISC } from './components/ItemStack';
import "./App.css";
import { CommandItem } from "./components/CommandItem";
import { ItemStack, ItemType } from 'core/ItemStack';
import { DisplayPane } from 'surfaces/DisplayPane';
import { Item } from 'core/Item';
import { deserialzeCommands, serializeCommands } from 'core/serialize';
const Buffer = require("buffer/").Buffer;
import { DisplayPane } from "surfaces/DisplayPane";
import { Item } from "core/Item";
import { deserialzeCommands, serializeCommands } from "core/serialize";
import { saveAs } from "data/FileSaver";
import { parseCommand } from "core/Parser";
const getDefaultCommands = (): Command[]=>{
const encoded = localStorage.getItem("HDS.CurrentCommands");
@ -43,7 +41,7 @@ const getDefaultCommands = (): Command[]=>{
new CommandSave(),
new CommandReload()
];
}
};
export const App: React.FC = () => {
const [commands, setCommands] = useState<Command[]>(getDefaultCommands());
@ -70,7 +68,7 @@ export const App: React.FC = () => {
}else if(e.code==="ArrowUp"){
setDisplayIndex(Math.max(0, displayIndex-1));
}
}
};
}, [commands, displayIndex]);
useEffect(()=>{
@ -78,12 +76,25 @@ export const App: React.FC = () => {
localStorage.setItem("HDS.CurrentCommands", encoded);
}, [commands]);
const uploadRef = useRef<HTMLInputElement>(null);
return (
<div className='Calamity'
>
<input ref={uploadRef} id="Upload" type="File" hidden onChange={(e)=>{
const files = e.target.files;
if(files?.length && files[0]){
const file = files[0];
file.text().then(text=>{
const lines = text.split("\n");
const parsedCommands: Command[] = lines.map(l=>parseCommand(l)).filter(c=>c) as Command[];
setDisplayIndex(0);
setContextIndex(-1);
setContextMenuShowing(false);
setCommands(parsedCommands);
});
}
}}/>
<div id="CommandList" style={{
width: "300px",
height: "calc( 100vh - 5px )",
@ -98,11 +109,11 @@ export const App: React.FC = () => {
paddingInlineStart: 0
}}>
{
commands.map((c,i)=>(
commands.map((c,i)=>
<CommandItem
onClick={()=>setDisplayIndex(i)}
onContextMenu={(x,y)=>{
setContextIndex(i)
setContextIndex(i);
setContextMenuX(x);
setContextMenuY(y);
setContextMenuShowing(true);
@ -114,14 +125,23 @@ export const App: React.FC = () => {
>
{c.getDisplayString()}
</CommandItem>
))
)
}
<CommandItem onClick={()=>{
const arrCopy = [...commands];
arrCopy.push(new CommandNothing());
setCommands(arrCopy);
}}>(new)</CommandItem>
<CommandItem onClick={()=>{
if(uploadRef.current){
uploadRef.current.click();
}
}}>(import)</CommandItem>
<CommandItem onClick={()=>{
const lines = commands.map(c=>c.getDisplayString());
const text = lines.join("\n");
saveAs(text, "dupe.txt");
}}>(export)</CommandItem>
</ul>
</div>
{displayIndex >= 0 && displayIndex < commands.length &&
@ -134,9 +154,8 @@ export const App: React.FC = () => {
const arrCopy = [...commands];
arrCopy[displayIndex] = c;
setCommands(arrCopy);
}}/>
}}
/>
}
{
@ -190,4 +209,4 @@ export const App: React.FC = () => {
}
</div>
);
}
};

View file

@ -15,12 +15,11 @@ export const CommandItem: React.FC<CommandItemProps> = ({isSelected, isContextSe
onClick={onClick}
onContextMenu={(e)=>{
if(onContextMenu){
console.log(e);
onContextMenu(e.clientX,e.clientY);
e.preventDefault();
}
}}
>{children}&nbsp;</li>
}
>{children}&nbsp;</li>;
};

View file

@ -10,9 +10,9 @@ export const ItemList: React.FC<ItemListProps> = ({items, numBroken}) => {
{
items.map(({name, count}, i)=>{
const broken = i+numBroken >= items.length;
return <ItemStack key={i} name={name} count={count} isBroken={broken}/>
return <ItemStack key={i} name={name} count={count} isBroken={broken}/>;
})
}
</>;
}
};

View file

@ -5,5 +5,5 @@ type ItemStackProps = {
};
export const ItemStack: React.FC<ItemStackProps> = ({name, count, isBroken})=>{
return <span>[{name} x{count}]{isBroken && " (broken)"}&nbsp;<br/></span>
}
return <span>[{name} x{count}]{isBroken && " (broken)"}&nbsp;<br/></span>;
};

View file

@ -1,8 +1,8 @@
import { Inventory } from "./Inventory";
import { Item, ItemIds } from "./Item";
import { ItemStack, ItemType } from "./ItemStack";
import { ItemStack } from "./ItemStack";
const Buffer = require("buffer/").Buffer;
const Buffer = require("buffer/").Buffer; /* eslint-disable-line @typescript-eslint/no-var-requires*/
export interface Command {
execute(inv: Inventory): void,
@ -13,11 +13,8 @@ export interface Command {
export class CommandNothing implements Command {
static Op = 0x0;
constructor(){
}
fromBuffer(buf: Buffer): number {
fromBuffer(_buf: Buffer): number {
return 0;
}
toBuffer(): Buffer {
@ -26,8 +23,8 @@ export class CommandNothing implements Command {
return buf;
}
execute(inv: Inventory): void {
execute(_inv: Inventory): void {
// nothing
}
getDisplayString(): string {
return "";
@ -37,7 +34,7 @@ export class CommandNothing implements Command {
export class CommandInitialize implements Command {
static Op = 0x1;
private stacks: ItemStack[]
private stacks: ItemStack[];
constructor(stacks: ItemStack[]){
this.stacks = stacks;
}
@ -68,7 +65,6 @@ export class CommandInitialize implements Command {
buf.writeInt16LE(this.stacks.length, write);
write+=2;
this.stacks.forEach(({item,count})=>{
console.log(count);
buf.writeInt16LE(count&0xffff, write);
write+=2;
buf.writeInt8(ItemIds[item], write);
@ -85,7 +81,7 @@ export class CommandInitialize implements Command {
this.stacks.forEach(({item, count})=>{
parts.push(""+count);
parts.push(item);
})
});
return parts.join(" ");
}
@ -117,7 +113,7 @@ export class CommandBreakSlots implements Command {
export class CommandSave implements Command {
static Op = 0x3;
public fromBuffer(buf: Buffer): number {
public fromBuffer(_buf: Buffer): number {
return 0;
}
public toBuffer(): Buffer {
@ -135,7 +131,7 @@ export class CommandSave implements Command {
export class CommandReload implements Command {
static Op = 0x4;
public fromBuffer(buf: Buffer): number {
public fromBuffer(_buf: Buffer): number {
return 0;
}
public toBuffer(): Buffer {
@ -153,7 +149,7 @@ export class CommandReload implements Command {
export class CommandSortKey implements Command {
static Op = 0x5;
public fromBuffer(buf: Buffer): number {
public fromBuffer(_buf: Buffer): number {
return 0;
}
public toBuffer(): Buffer {
@ -171,7 +167,7 @@ export class CommandSortKey implements Command {
export class CommandSortMaterial implements Command {
static Op = 0x6;
public fromBuffer(buf: Buffer): number {
public fromBuffer(_buf: Buffer): number {
return 0;
}
public toBuffer(): Buffer {
@ -197,7 +193,7 @@ const VerbToId = {
"Get": 6,
"Add": 7,
"Pickup": 8
}
};
export class CommandRemoveMaterial implements Command {
static Op = 0x7;
@ -256,7 +252,7 @@ export class CommandRemoveUnstackableMaterial implements Command {
private item: Item;
private slot: number;
constructor(verb: string,item: Item, slot: number){
this.verb = VerbToId[verb as keyof typeof VerbToId] || 0;;
this.verb = VerbToId[verb as keyof typeof VerbToId] || 0;
this.item = item;
this.slot = slot;
}

View file

@ -4,11 +4,11 @@ import { ItemStack, ItemType } from "./ItemStack";
export class Inventory {
private slots: ItemStack[] = [];
private savedSlots: ItemStack[] = [];
private numBroken: number = 0;
private isInitialSort: boolean = false;
private isAltered: boolean = true;
private isSaveAltered: boolean = true;
private inaccurate: boolean = false;
private numBroken = 0;
private isInitialSort = false;
private isAltered = true;
private isSaveAltered = true;
private inaccurate = false;
public clone(): Inventory {
const other = new Inventory();
other.slots = [...this.slots.map(stack=>({...stack}))];
@ -36,6 +36,11 @@ export class Inventory {
public init(stacks: ItemStack[]) {
this.savedSlots = [...stacks.map((stack)=>({...stack}))];
this.slots = [...stacks.map((stack)=>({...stack}))];
this.numBroken = 0;
this.isInitialSort = false;
this.isAltered = true;
this.isSaveAltered = true;
this.inaccurate = false;
}
public addBrokenSlots(num: number) {
@ -56,7 +61,7 @@ export class Inventory {
[ItemType.Material]: [],
[ItemType.Meal]: [],
[ItemType.Key]: []
}
};
for(let i=Math.max(0, this.slots.length-this.numBroken);i<this.slots.length;i++){
const stack = this.slots[i];
if(!shouldIgnoreOnReload(stack.item)){

View file

@ -5,7 +5,6 @@ export enum Item {
Glider = "Glider",
SpiritOrb = "SpiritOrb",
Lotus = "Lotus",
SilentPrincess = "SilentPrincess",
Honey = "Honey",
@ -50,7 +49,7 @@ export const ItemIds = {
[Item.Wood]: 0x1f,
[Item.SpeedFood]: 0x40,
}
};
export const itemToType = (item: Item): ItemType => {
if (item === Item.Slate || item === Item.Glider || item === Item.SpiritOrb){
@ -60,15 +59,15 @@ export const itemToType = (item: Item): ItemType => {
return ItemType.Meal;
}
return ItemType.Material;
}
};
export const shouldIgnoreOnReload = (item: Item): boolean => {
return item === Item.Slate || item === Item.Glider;
}
};
export const isStackable = (item: Item): boolean => {
return item !==Item.Slate && item !== Item.Glider && item !== Item.SpeedFood;
}
};
const KeyItemSortOrderMap = (()=>{
const map: {[k in Item]?: number} = {};
@ -82,7 +81,7 @@ const KeyItemSortOrderMap = (()=>{
export const getKeyItemSortOrder = (item: Item): number => {
return KeyItemSortOrderMap[item] || -1;
}
};
const MaterialSortOrderMap = (()=>{
const map: {[k in Item]?: number} = {};
@ -109,4 +108,4 @@ const MaterialSortOrderMap = (()=>{
export const getMaterialSortOrder = (item: Item): number => {
return MaterialSortOrderMap[item] || -1;
}
};

View file

@ -78,4 +78,4 @@ export const parseCommand = (cmdString: string): Command | undefined => {
}
return undefined;
}
};

View file

@ -1,7 +1,7 @@
import { Command, CommandAddMaterial, CommandBreakSlots, CommandInitialize, CommandNothing, CommandReload, CommandRemoveMaterial, CommandRemoveUnstackableMaterial, CommandSave, CommandSortKey, CommandSortMaterial } from "./Command";
import { Item } from "./Item";
const Buffer = require("buffer/").Buffer;
const Buffer = require("buffer/").Buffer; /* eslint-disable-line @typescript-eslint/no-var-requires*/
export const serializeCommands = (commands: Command[]): string => {
const sizeBuf: Buffer = Buffer.alloc(4);
@ -9,9 +9,9 @@ export const serializeCommands = (commands: Command[]): string => {
const commandBuffers = commands.map(c=>c.toBuffer());
const allBufs = Buffer.concat([sizeBuf, ...commandBuffers]);
console.log(allBufs);
return allBufs.toString("base64");
}
};
export const deserialzeCommands = (base64str: string): Command[] => {
const buf: Buffer = Buffer.from(base64str, "base64");
@ -62,4 +62,4 @@ export const deserialzeCommands = (base64str: string): Command[] => {
}
}
return commands;
}
};

View file

@ -0,0 +1,168 @@
/* eslint no-empty:0 */
/*
* FileSaver.js
* A saveAs() FileSaver implementation.
*
* By Eli Grey, http://eligrey.com
*
* License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
* source : http://purl.eligrey.com/github/FileSaver.js
*/
// The one and only way of getting global scope in all environments
// https://stackoverflow.com/q/3277182/1008999
var _global = typeof window === "object" && window.window === window
? window : typeof window.self === "object" && window.self.self === window.self
? window.self : typeof window.global === "object" && window.global.global === window.global
? window.global
: this;
function bom (blob, opts) {
if (typeof opts === "undefined") {opts = { autoBom: false };}
else if (typeof opts !== "object") {
console.error("Deprecated: Expected third argument to be a object");
opts = { autoBom: !opts };
}
// prepend BOM for UTF-8 XML and text/* types (including HTML)
// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type });
}
return blob;
}
function download (url, name, opts) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "blob";
xhr.onload = function () {
saveAs(xhr.response, name, opts);
};
xhr.onerror = function () {
console.error("could not download file");
};
xhr.send();
}
function corsEnabled (url) {
var xhr = new XMLHttpRequest();
// use sync to avoid popup blocker
xhr.open("HEAD", url, false);
try {
xhr.send();
} catch (e) {}
return xhr.status >= 200 && xhr.status <= 299;
}
// `a.click()` doesn't work for all browsers (#465)
function click (node) {
try {
node.dispatchEvent(new MouseEvent("click"));
} catch (e) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 80,
20, false, false, false, false, 0, null);
node.dispatchEvent(evt);
}
}
// Detect WebView inside a native macOS app by ruling out all browsers
// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
var isMacOSWebView = _global.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent);
var saveAs = _global.saveAs || (
// probably in some web worker
typeof window !== "object" || window !== _global
? function saveAs () { /* noop */ }
// Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView
: "download" in HTMLAnchorElement.prototype && !isMacOSWebView
? function saveAs (blob, name, opts) {
var URL = _global.URL || _global.webkitURL;
var a = document.createElement("a");
name = name || blob.name || "download";
a.download = name;
a.rel = "noopener"; // tabnabbing
// TODO: detect chrome extensions & packaged apps
// a.target = '_blank'
if (typeof blob === "string") {
// Support regular links
a.href = blob;
if (a.origin !== window.location.origin) {
corsEnabled(a.href)
? download(blob, name, opts)
: click(a, a.target = "_blank");
} else {
click(a);
}
} else {
// Support blobs
a.href = URL.createObjectURL(blob);
setTimeout(function () { URL.revokeObjectURL(a.href); }, 4E4); // 40s
setTimeout(function () { click(a); }, 0);
}
}
// Use msSaveOrOpenBlob as a second approach
: "msSaveOrOpenBlob" in navigator
? function saveAs (blob, name, opts) {
name = name || blob.name || "download";
if (typeof blob === "string") {
if (corsEnabled(blob)) {
download(blob, name, opts);
} else {
var a = document.createElement("a");
a.href = blob;
a.target = "_blank";
setTimeout(function () { click(a); });
}
} else {
navigator.msSaveOrOpenBlob(bom(blob, opts), name);
}
}
// Fallback to using FileReader and a popup
: function saveAs (blob, name, opts, popup) {
// Open a popup immediately do go around popup blocker
// Mostly only available on user interaction and the fileReader is async so...
popup = popup || window.open("", "_blank");
if (popup) {
popup.document.title =
popup.document.body.innerText = "downloading...";
}
if (typeof blob === "string") {return download(blob, name, opts);}
var force = blob.type === "application/octet-stream";
var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari;
var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
if ((isChromeIOS || force && isSafari || isMacOSWebView) && typeof FileReader !== "undefined") {
// Safari doesn't allow downloading of blob URLs
var reader = new FileReader();
reader.onloadend = function () {
var url = reader.result;
url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, "data:attachment/file;");
if (popup) {popup.location.href = url;}
else {window.location = url;}
popup = null; // reverse-tabnabbing #460
};
reader.readAsDataURL(blob);
} else {
var URL = _global.URL || _global.webkitURL;
var url = URL.createObjectURL(blob);
if (popup) {popup.location = url;}
else {window.location.href = url;}
popup = null; // reverse-tabnabbing #460
setTimeout(function () { URL.revokeObjectURL(url); }, 4E4); // 40s
}
}
);
export default saveAs;

View file

@ -0,0 +1,9 @@
The MIT License
Copyright © 2016 Eli Grey.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,8 @@
import FileSaverFunction from "./FileSaver";
export const saveAs = (content: string, filename: string): void =>{
const blob = new Blob([content], {
type: "text/plain;charset=utf-8"
});
FileSaverFunction(blob, filename);
};

View file

@ -1,11 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import {App} from './App';
import reportWebVitals from './reportWebVitals';
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import {App} from "./App";
import reportWebVitals from "./reportWebVitals";
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>

View file

@ -1,8 +1,8 @@
import { ReportHandler } from 'web-vitals';
import { ReportHandler } from "web-vitals";
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);

View file

@ -2,4 +2,4 @@
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';
import "@testing-library/jest-dom";

View file

@ -1,11 +1,11 @@
import clsx from "clsx"
import { ItemList, ItemListProps } from "components/ItemList"
import { Command } from "core/Command"
import { itemToType } from "core/Item"
import { ItemStack, ItemType } from "core/ItemStack"
import { parseCommand } from "core/Parser"
import clsx from "clsx";
import { ItemList, ItemListProps } from "components/ItemList";
import { Command } from "core/Command";
import { itemToType } from "core/Item";
import { ItemStack, ItemType } from "core/ItemStack";
import { parseCommand } from "core/Parser";
import React, { useEffect, useState } from "react"
import React, { useEffect, useState } from "react";
type DisplayPaneProps = {
command: string,
@ -31,12 +31,12 @@ const stacksToItemListProps = (stacks: ItemStack[], numBroken: number): [ItemLis
items: stacksToNameAndCount(keyItems),
numBroken
},
]
}
];
};
const stacksToNameAndCount = (stacks: ItemStack[]): ItemListProps["items"] => {
return stacks.map(({item, count})=>({name: item, count}));
}
};
export const DisplayPane: React.FC<DisplayPaneProps> = ({command,editCommand,displayIndex, stacks, numBroken})=>{
const [commandString, setCommandString] = useState<string>("");
@ -126,6 +126,5 @@ When you reload without altering inventory, things become weird. It won't be han
<ItemList {...keyItemListProps}/>
</div>
</div>
}
</div>;
};