import React, { useEffect, useState } from "react"; import { Paper, Table, TableHead, TableRow, TableBody, TableContainer, TableCell, Typography, Tooltip, Box, Button, ButtonGroup, } from "@mui/material"; import makeStyles from "@mui/styles/makeStyles"; import createStyles from "@mui/styles/createStyles"; import { Theme } from "@mui/material/styles"; import ThumbUpAlt from "@mui/icons-material/ThumbUpAlt"; import ThumbDownAlt from "@mui/icons-material/ThumbDownAlt"; import DirectionsRunIcon from "@mui/icons-material/DirectionsRun"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import WarningIcon from "@mui/icons-material/Warning"; import { ImportData, saveObject } from "../../SaveObject"; import { Settings } from "../../Settings/Settings"; import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions"; import { numeralWrapper } from "../numeralFormat"; import { ConfirmationModal } from "./ConfirmationModal"; const useStyles = makeStyles((theme: Theme) => createStyles({ root: { padding: theme.spacing(2), maxWidth: "1000px", "& .MuiTable-root": { "& .MuiTableCell-root": { borderBottom: `1px solid ${Settings.theme.welllight}`, }, "& .MuiTableHead-root .MuiTableRow-root": { backgroundColor: Settings.theme.backgroundsecondary, "& .MuiTableCell-root": { color: Settings.theme.primary, fontWeight: "bold", }, }, "& .MuiTableBody-root": { "& .MuiTableRow-root:nth-of-type(odd)": { backgroundColor: Settings.theme.well, "& .MuiTableCell-root": { color: Settings.theme.primarylight, }, }, "& .MuiTableRow-root:nth-of-type(even)": { backgroundColor: Settings.theme.backgroundsecondary, "& .MuiTableCell-root": { color: Settings.theme.primarylight, }, }, }, }, }, }), ); function ComparisonIcon({ isBetter }: { isBetter: boolean }): JSX.Element { if (isBetter) { return ( Imported value is larger! } > ); } else { return ( Imported value is smaller! } > ); } } export interface ImportSaveProps { importString: string; automatic: boolean; onReturning: () => void; } let initialAutosave = 0; export function ImportSaveRoot({ importString, automatic, onReturning }: ImportSaveProps): JSX.Element { const classes = useStyles(); const [importData, setImportData] = useState(); const [currentData, setCurrentData] = useState(); const [importModalOpen, setImportModalOpen] = useState(false); function handleGoBack(): void { Settings.AutosaveInterval = initialAutosave; onReturning(); } async function handleImport(): Promise { await saveObject.importGame(importString, true); } useEffect(() => { // We want to disable autosave while we're in this mode initialAutosave = Settings.AutosaveInterval; Settings.AutosaveInterval = 0; }, []); useEffect(() => { async function fetchData(): Promise { const dataBeingImported = await saveObject.getImportDataFromString(importString); const dataCurrentlyInGame = await saveObject.getImportDataFromString(saveObject.getSaveString(true)); setImportData(dataBeingImported); setCurrentData(dataCurrentlyInGame); return Promise.resolve(); } if (importString) fetchData(); }, [importString]); if (!importData || !currentData) return <>; return ( Import Save Comparison {automatic && ( We've found a NEWER save that you may want to use instead. )} Your current game's data is on the left and the data that will be imported is on the right.
Please double check everything is fine before proceeding!
Current Game Being Imported Game Identifier {currentData.playerData?.identifier ?? "n/a"} {importData.playerData?.identifier ?? "n/a"} {importData.playerData?.identifier !== currentData.playerData?.identifier && ( )} Playtime {convertTimeMsToTimeElapsedString(currentData.playerData?.totalPlaytime ?? 0)} {convertTimeMsToTimeElapsedString(importData.playerData?.totalPlaytime ?? 0)} {importData.playerData?.totalPlaytime !== currentData.playerData?.totalPlaytime && ( (currentData.playerData?.totalPlaytime ?? 0) } /> )} Saved On {new Date(currentData.playerData?.lastSave ?? 0).toLocaleString()} {new Date(importData.playerData?.lastSave ?? 0).toLocaleString()} {importData.playerData?.lastSave !== currentData.playerData?.lastSave && ( (currentData.playerData?.lastSave ?? 0)} /> )} Money {numeralWrapper.formatMoney(currentData.playerData?.money ?? 0)} {numeralWrapper.formatMoney(importData.playerData?.money ?? 0)} {importData.playerData?.money !== currentData.playerData?.money && ( (currentData.playerData?.money ?? 0)} /> )} Hacking {numeralWrapper.formatSkill(currentData.playerData?.hacking ?? 0)} {numeralWrapper.formatSkill(importData.playerData?.hacking ?? 0)} {importData.playerData?.hacking !== currentData.playerData?.hacking && ( (currentData.playerData?.hacking ?? 0)} /> )} Augmentations {currentData.playerData?.augmentations} {importData.playerData?.augmentations} {importData.playerData?.augmentations !== currentData.playerData?.augmentations && ( (currentData.playerData?.augmentations ?? 0) } /> )} Factions {currentData.playerData?.factions} {importData.playerData?.factions} {importData.playerData?.factions !== currentData.playerData?.factions && ( (currentData.playerData?.factions ?? 0)} /> )} Achievements {currentData.playerData?.achievements} {importData.playerData?.achievements} {importData.playerData?.achievements !== currentData.playerData?.achievements && ( (currentData.playerData?.achievements ?? 0)} /> )} Source Files {currentData.playerData?.sourceFiles} {importData.playerData?.sourceFiles} {importData.playerData?.sourceFiles !== currentData.playerData?.sourceFiles && ( (currentData.playerData?.sourceFiles ?? 0)} /> )} BitNode {currentData.playerData?.bitNode}-{currentData.playerData?.bitNodeLevel} {importData.playerData?.bitNode}-{importData.playerData?.bitNodeLevel}
setImportModalOpen(false)} onConfirm={handleImport} confirmationText={ <> Importing new save game data will completely wipe the current game data!
} />
); }