Skip to content

Commit

Permalink
Finished save select.
Browse files Browse the repository at this point in the history
"Complement saves" can be added by modifying the `getComplementarySaves` method in G3RRSAV
  • Loading branch information
evanwporter committed Dec 16, 2024
1 parent 04c06dc commit b689d3d
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 13 deletions.
23 changes: 18 additions & 5 deletions src/app/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { GameOfOrigin, isGameBoy, isGen3, isGen4, isGen5 } from 'pokemon-resourc
import { useCallback, useContext, useEffect, useState } from 'react'
import { MdFileOpen } from 'react-icons/md'
import SaveNotFoundError from 'src/saves/SaveNotFoundError'
import { SelectPlugin } from 'src/saves/SelectPlugin'
import { SAVClass } from 'src/types/SAVTypes/util'
import { Errorable } from 'src/types/types'
import { BackendContext } from '../backend/backendProvider'
import FilterPanel from '../components/filter/FilterPanel'
Expand Down Expand Up @@ -48,11 +50,11 @@ const Home = () => {
const [errorMessages, setErrorMessages] = useState<string[]>()
const [filesToDelete, setFilesToDelete] = useState<string[]>([])
const [saveFound, setSaveFound] = useState<boolean>(false);
// const [saveFound, setSaveFound] = useState<{
// filePath: PathData;
// fileBytes: Uint8Array;
// createdDate: Date;
// } | null>();
const [specifySave, setSpecifySave] = useState<{
supportedSaveTypes: SAVClass[];
plugins: string[];
onSelect?: (plugin: string) => void;
} | null>(null);

const onViewDrop = (e: React.DragEvent<HTMLDivElement>, type: string) => {
const processDroppedData = async (file?: File, droppedMon?: PKMInterface) => {
Expand Down Expand Up @@ -384,9 +386,20 @@ const Home = () => {
setOpenSaveDialog(false)
}}
setSaveFound={setSaveFound}
setSpecifySave={setSpecifySave}
/>
</ModalDialog>
</Modal>
{specifySave && (
<SelectPlugin
plugins={specifySave.plugins}
onPluginClick={(selectedPlugin) => {
console.log(`Selected plugin: ${selectedPlugin}`);
specifySave.onSelect?.(selectedPlugin);
setSpecifySave(null);
}}
/>
)}
{saveFound && (
<SaveNotFoundError
onClose={() => setSaveFound(false)}
Expand Down
38 changes: 33 additions & 5 deletions src/saves/SavesModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,33 @@ import * as E from 'fp-ts/lib/Either'
import { useCallback, useContext, useState } from 'react'
import 'react-data-grid/lib/styles.css'
import { PathData } from 'src/types/SAVTypes/path'
import { SAVClass } from 'src/types/SAVTypes/util'
import { getMonFileIdentifier } from 'src/util/Lookup'
import { BackendContext } from '../backend/backendProvider'
import { CardsIcon, GridIcon } from '../components/Icons'
import { AppInfoContext } from '../state/appInfo'
import { LookupContext } from '../state/lookup'
import { OpenSavesContext } from '../state/openSaves'
import { getSaveRef } from '../types/SAVTypes/SAV'
import { buildSaveFile } from '../types/SAVTypes/load'
import { buildSaveFile, getSaveType } from '../types/SAVTypes/load'
import RecentSaves from './RecentSaves'
import SaveFolders from './SaveFolders'
import { waitForPluginSelection } from './SelectPlugin'
import SuggestedSaves from './SuggestedSaves'
import { SaveViewMode } from './util'

interface SavesModalProps {
onClose: () => void,
setSaveFound: React.Dispatch<React.SetStateAction<boolean>>
setSaveFound: React.Dispatch<React.SetStateAction<boolean>>,
setSpecifySave: React.Dispatch<React.SetStateAction<{
supportedSaveTypes: SAVClass[];
plugins: string[];
onSelect?: (plugin: string) => void;
} | null>>
}

const SavesModal = (props: SavesModalProps) => {
const { onClose, setSaveFound } = props
const { onClose, setSaveFound, setSpecifySave } = props
const backend = useContext(BackendContext)
const [, dispatchOpenSaves] = useContext(OpenSavesContext)
const [lookupState] = useContext(LookupContext)
Expand All @@ -54,11 +61,31 @@ const SavesModal = (props: SavesModalProps) => {
backend.loadSaveFile(filePath).then(
E.match(
(err) => console.error(err),
({ path, fileBytes, createdDate }) => {
async ({ path, fileBytes, createdDate }) => {
if (!filePath) {
filePath = path
}
if (filePath && fileBytes && lookupState.loaded) {
let saveType = getSaveType(fileBytes, getEnabledSaveTypes())

console.log(saveType)

const complementaryPlugins = saveType?.getComplementaryPlugins?.() ?? [];

if (complementaryPlugins.length > 0) {
setSpecifySave({
supportedSaveTypes: getEnabledSaveTypes(),
plugins: complementaryPlugins,
});

// Wait for user selection
saveType = await waitForPluginSelection(setSpecifySave);
if (!saveType) {
console.error("No save type selected.");
return;
}
}

const saveFile = buildSaveFile(
filePath,
fileBytes,
Expand All @@ -68,7 +95,8 @@ const SavesModal = (props: SavesModalProps) => {
gen345LookupMap: lookupState.gen345,
fileCreatedDate: createdDate,
},
getEnabledSaveTypes(),
undefined, // supported saves
saveType,
(updatedMon) => {
const identifier = getMonFileIdentifier(updatedMon)

Expand Down
79 changes: 79 additions & 0 deletions src/saves/SelectPlugin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
Button,
DialogContent,
DialogTitle,
ModalClose,
ModalDialog,
Stack,
Typography
} from '@mui/joy';
import { SAVClass } from 'src/types/SAVTypes/util';

export function waitForPluginSelection(
setSpecifySave: React.Dispatch<React.SetStateAction<{
supportedSaveTypes: SAVClass[];
plugins: string[];
onSelect?: (plugin: string) => void;
} | null>>
): Promise<SAVClass | undefined> {
return new Promise((resolve) => {
setSpecifySave((prevState) => {
if (!prevState) {
throw new Error("SpecifySave state is unexpectedly null.");
}

return {
...prevState,
onSelect: (selectedPlugin: string) => {
resolve(
prevState.supportedSaveTypes.find(
(item) => item.saveTypeID === selectedPlugin
)
);
setSpecifySave(null); // Close the modal after selection
},
};
});
});
}


interface SelectPluginProps {
plugins: string[];
onPluginClick: (plugin: string) => void;
}

export const SelectPlugin = ({
plugins,
onPluginClick,
}: SelectPluginProps) => {
return (
<ModalDialog
sx={{
minWidth: 400,
maxWidth: '80%',
borderRadius: 'lg',
padding: 2,
zIndex: 2000 // High zIndex to overlay it over everything
}}
>
<ModalClose />
<DialogTitle>Complementary Plugins</DialogTitle>
<DialogContent>
<Typography>Select a plugin to proceed:</Typography>
<Stack spacing={2} mt={2}>
{plugins.map((plugin, index) => (
<Button
key={index}
onClick={() => onPluginClick(plugin)}
variant="soft"
color="primary"
>
{plugin}
</Button>
))}
</Stack>
</DialogContent>
</ModalDialog>
);
};
8 changes: 6 additions & 2 deletions src/types/SAVTypes/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,15 @@ export const buildSaveFile = (
gen345LookupMap?: Record<string, string>
fileCreatedDate?: Date
},
supportedSaveTypes: SAVClass[],
supportedSaveTypes?: SAVClass[],
saveType?: SAVClass | undefined,
updateMonCallback?: (mon: OHPKM) => void
): SAV | undefined => {
const { homeMonMap, gen12LookupMap, gen345LookupMap } = lookupMaps
const saveType = getSaveType(fileBytes, supportedSaveTypes)

if (!saveType && supportedSaveTypes) {
saveType = getSaveType(fileBytes, supportedSaveTypes)
}

if (!saveType) return undefined

Expand Down
4 changes: 4 additions & 0 deletions src/types/SAVTypes/radicalred/G3RRSAV.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,10 @@ export class G3RRSAV implements PluginSAV<PK3RR> {
getPluginIdentifier() {
return 'radical_red'
}

static getComplementaryPlugins() {
return [] // ['G3RRSAV', 'G3UBSAV']
}
}

const findFirstSectionOffset = (bytes: Uint8Array): number => {
Expand Down
7 changes: 6 additions & 1 deletion src/types/SAVTypes/unbound/G3UBSAV.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,16 @@ export class G3UBSAV implements PluginSAV<PK3UB> {
updatedBoxSlots: BoxCoordinates[] = []
gameColor!: () => string
isPlugin: true = true
getPluginIdentifier!: (() => string | undefined) & (() => string)
getCurrentBox!: () => Box<PK3UB>
supportsMon!: (dexNumber: number, formeNumber: number) => boolean
prepareBoxesAndGetModified!: () => OHPKM[]
calculateChecksum?: (() => number) | undefined
getGameName!: () => string
getExtraData?: (() => object) | undefined

getPluginIdentifier() {
return 'unbound'
}

static saveTypeID = 'G3UBSAV'
}
2 changes: 2 additions & 0 deletions src/types/SAVTypes/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export interface SAVClass {
saveTypeName: string
saveTypeID: string
saveTypeAbbreviation: string
getComplementaryPlugins?: () => string[]
getPluginIdentifier?: () => string
}

export type PKMTypeOf<Type> = Type extends SAV<infer X> ? X : never
Expand Down

0 comments on commit b689d3d

Please sign in to comment.