Skip to content

Commit 2127f8c

Browse files
committed
[WIP]
1 parent d442ec4 commit 2127f8c

File tree

11 files changed

+267
-143
lines changed

11 files changed

+267
-143
lines changed

src/components/NumericInput/NumericInput.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { getNumberSeparators } from '../../utils/locale-utils';
88
export interface NumericInputProps {
99
value?: number;
1010
onChange?: (value: number) => unknown;
11-
label?: string;
11+
label?: ReactNode;
1212
name?: string;
1313
id?: string;
1414
variant?: TextFieldVariants;

src/features/GearPiece.tsx

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ import {
33
Accordion,
44
AccordionDetails,
55
AccordionSummary,
6+
alpha,
67
Box,
8+
FormControlLabel,
79
Paper,
810
Stack,
11+
styled,
12+
Switch,
913
Typography,
1014
} from '@mui/material';
1115
import Grid from '@mui/material/Unstable_Grid2';
@@ -39,6 +43,21 @@ export interface GearPieceProps {
3943
['data-testid']?: string;
4044
}
4145

46+
const TitanSwitch = styled(Switch)(({ theme }) => ({
47+
'& .MuiSwitch-switchBase.Mui-checked': {
48+
color: theme.palette.titan.main,
49+
'&:hover': {
50+
backgroundColor: alpha(
51+
theme.palette.titan.main,
52+
theme.palette.action.hoverOpacity
53+
),
54+
},
55+
},
56+
'& .MuiSwitch-switchBase.Mui-checked + .MuiSwitch-track': {
57+
backgroundColor: theme.palette.titan.main,
58+
},
59+
}));
60+
4261
export const GearPiece = ({
4362
gearSnap,
4463
gearState,
@@ -70,7 +89,7 @@ export const GearPiece = ({
7089
}
7190
starsSelector={<GearStars gearSnap={gearSnap} gearState={gearState} />}
7291
randomStats={
73-
<>
92+
<Stack spacing={gearSnap.isAugmented ? 2 : 1}>
7493
{gearSnap.randomStats.map((randomStatSnap, i) => {
7594
return randomStatSnap && gearState.randomStats[i] ? (
7695
<StatEditor
@@ -79,6 +98,7 @@ export const GearPiece = ({
7998
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
8099
statState={gearState.randomStats[i]!}
81100
possibleStatTypes={possibleRandomStatTypes}
101+
isAugmented={gearSnap.isAugmented}
82102
/>
83103
) : (
84104
<EmptyStatEditor
@@ -90,9 +110,9 @@ export const GearPiece = ({
90110
/>
91111
);
92112
})}
93-
</>
113+
</Stack>
94114
}
95-
additionalActions={
115+
actions={
96116
<>
97117
{showGearOCRButton && (
98118
<GearOCRModal
@@ -112,6 +132,25 @@ export const GearPiece = ({
112132
)}
113133
</>
114134
}
135+
toggles={
136+
<>
137+
<FormControlLabel
138+
control={
139+
<TitanSwitch
140+
checked={gearSnap.isAugmented}
141+
onChange={(event) => {
142+
gearState.isAugmented = event.target.checked;
143+
}}
144+
/>
145+
}
146+
label={
147+
<Typography color="titan.light" variant="inherit">
148+
Titan/Augment
149+
</Typography>
150+
}
151+
/>
152+
</>
153+
}
115154
summary={
116155
<>
117156
{showStatSummary && (
@@ -167,15 +206,17 @@ function Layout({
167206
typeSelector,
168207
starsSelector,
169208
randomStats,
170-
additionalActions,
209+
actions,
210+
toggles,
171211
summary,
172212
'data-testid': dataTestId,
173213
}: {
174214
typeIcon: ReactNode;
175215
typeSelector: ReactNode;
176216
starsSelector: ReactNode;
177217
randomStats: ReactNode;
178-
additionalActions: ReactNode;
218+
actions: ReactNode;
219+
toggles: ReactNode;
179220
summary: ReactNode;
180221
['data-testid']?: string;
181222
}) {
@@ -191,7 +232,10 @@ function Layout({
191232
</Grid>
192233
</Grid>
193234
<Stack direction="row-reverse" spacing={1} mb={1}>
194-
{additionalActions}
235+
{actions}
236+
</Stack>
237+
<Stack direction="row" spacing={1} mb={1}>
238+
{toggles}
195239
</Stack>
196240
<Box mb={3}>{randomStats}</Box>
197241
<Box>{summary}</Box>

src/features/StatEditor.tsx

Lines changed: 102 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Box, Stack, Typography } from '@mui/material';
12
import Grid from '@mui/material/Unstable_Grid2';
23
import type { ReactNode } from 'react';
34

@@ -12,19 +13,17 @@ export interface StatEditorProps {
1213
statSnap: RandomStat;
1314
statState: RandomStat;
1415
possibleStatTypes: StatType[];
16+
isAugmented: boolean;
1517
}
1618

1719
export const StatEditor = ({
1820
statSnap,
1921
statState,
2022
possibleStatTypes = [],
23+
isAugmented,
2124
}: StatEditorProps) => {
2225
const statType = statSnap.type;
2326

24-
const handleStatValueChange = (value: number) => {
25-
statState.value = value;
26-
};
27-
2827
return (
2928
<Layout
3029
typeIcon={<StatTypeIcon statType={statType} />}
@@ -38,17 +37,40 @@ export const StatEditor = ({
3837
/>
3938
}
4039
valueInput={
41-
statType.isPercentageBased ? (
42-
<PercentageNumericInput
43-
value={statSnap.value}
44-
onChange={handleStatValueChange}
45-
aria-label="stat-value-input"
40+
<Input
41+
isPercentageBased={statType.isPercentageBased}
42+
value={statSnap.value}
43+
onChange={(value) => {
44+
statState.value = value;
45+
}}
46+
label={isAugmented ? 'Base value' : undefined}
47+
aria-label="stat-value-input"
48+
/>
49+
}
50+
augmentIncreaseValueInput={
51+
isAugmented && (
52+
<Input
53+
isPercentageBased={statType.isPercentageBased}
54+
value={statSnap.augmentIncreaseValue}
55+
onChange={(value) => {
56+
statState.augmentIncreaseValue = value;
57+
}}
58+
label={<Typography color="titan.main">Augment increase</Typography>}
59+
aria-label="stat-augment-increase-value-input"
60+
disabled
4661
/>
47-
) : (
48-
<NumericInput
49-
value={statSnap.value}
50-
onChange={handleStatValueChange}
51-
aria-label="stat-value-input"
62+
)
63+
}
64+
totalValueInput={
65+
isAugmented && (
66+
<Input
67+
isPercentageBased={statType.isPercentageBased}
68+
value={statSnap.totalValue}
69+
onChange={(value) => {
70+
statState.totalValue = value;
71+
}}
72+
label={<Typography color="titan.main">Total value</Typography>}
73+
aria-label="stat-total-value-input"
5274
/>
5375
)
5476
}
@@ -90,26 +112,82 @@ export const DisabledStatEditor = () => {
90112
);
91113
};
92114

115+
function Input({
116+
isPercentageBased,
117+
value,
118+
onChange,
119+
disabled,
120+
label,
121+
['aria-label']: ariaLabel,
122+
}: {
123+
isPercentageBased: boolean;
124+
value: number;
125+
onChange: (value: number) => void;
126+
disabled?: boolean;
127+
label?: ReactNode;
128+
'aria-label'?: string;
129+
}) {
130+
return isPercentageBased ? (
131+
<PercentageNumericInput
132+
value={value}
133+
onChange={onChange}
134+
disabled={disabled}
135+
label={label}
136+
aria-label={ariaLabel}
137+
/>
138+
) : (
139+
<NumericInput
140+
value={value}
141+
onChange={onChange}
142+
disabled={disabled}
143+
label={label}
144+
aria-label={ariaLabel}
145+
/>
146+
);
147+
}
148+
93149
function Layout({
94150
typeIcon,
95151
typeSelector,
96152
valueInput,
153+
augmentIncreaseValueInput,
154+
totalValueInput,
97155
}: {
98156
typeIcon: ReactNode;
99157
typeSelector: ReactNode;
100158
valueInput: ReactNode;
159+
augmentIncreaseValueInput?: ReactNode;
160+
totalValueInput?: ReactNode;
101161
}) {
162+
const isTwoLines = !!augmentIncreaseValueInput && !!totalValueInput;
163+
102164
return (
103-
<Grid container spacing={2}>
104-
<Grid maxWidth={40} display="flex" alignItems="center">
105-
{typeIcon}
106-
</Grid>
107-
<Grid xs display="flex" alignItems="end">
108-
{typeSelector}
109-
</Grid>
110-
<Grid xs={3} display="flex" alignItems="end">
111-
{valueInput}
165+
<Box>
166+
<Grid container spacing={2} justifyContent="space-between">
167+
<Grid xs={isTwoLines ? 6 : true}>
168+
<Stack direction="row" spacing={1} alignItems="center">
169+
<Box maxWidth={40} display="flex" alignItems="center">
170+
{typeIcon}
171+
</Box>
172+
{typeSelector}
173+
</Stack>
174+
</Grid>
175+
<Grid xs={3} display="flex" alignItems="end" justifySelf="flex-end">
176+
{valueInput}
177+
</Grid>
112178
</Grid>
113-
</Grid>
179+
{isTwoLines && (
180+
<Grid
181+
container
182+
spacing={2}
183+
display="flex"
184+
justifyContent="flex-end"
185+
alignItems="end"
186+
>
187+
<Grid xs={3}>{augmentIncreaseValueInput}</Grid>
188+
<Grid xs={3}>{totalValueInput}</Grid>
189+
</Grid>
190+
)}
191+
</Box>
114192
);
115193
}

src/features/TitanGearMaxStats.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ export function TitanGearMaxStats({
2828
return (
2929
<Typography key={i} gutterBottom>
3030
<strong>{displayName}: </strong>
31-
{randomStat.getValueToString()} +{' '}
32-
{randomStat.getAugmentIncreaseValueToString()} ={' '}
33-
<strong>{randomStat.getTotalValueWithAugmentToString()}</strong>
31+
{randomStat.valueString} +{' '}
32+
{randomStat.augmentIncreaseValueString} ={' '}
33+
<strong>{randomStat.totalValueString}</strong>
3434
</Typography>
3535
);
3636
})}
@@ -49,11 +49,9 @@ export function TitanGearMaxStats({
4949
return (
5050
<Typography key={i} gutterBottom>
5151
<strong>{displayName}: </strong>
52-
{augmentStat.getValueToString()} +{' '}
53-
{augmentStat.getAugmentIncreaseValueToString()} ={' '}
54-
<strong>
55-
{augmentStat.getTotalValueWithAugmentToString()}
56-
</strong>
52+
{augmentStat.valueString} +{' '}
53+
{augmentStat.augmentIncreaseValueString} ={' '}
54+
<strong>{augmentStat.totalValueString}</strong>
5755
</Typography>
5856
);
5957
})}

src/features/gear-comparer/GearRollSimulatorStat.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function GearRollSimulatorStat({
2828
</Grid>
2929
<Grid xs={4}>
3030
<Stack direction="row" spacing={2}>
31-
<Typography>{statSnap.getValueToString()}</Typography>
31+
<Typography>{statSnap.valueString}</Typography>
3232
<Typography fontStyle="italic">
3333
({pluralize('roll', rolls, true)})
3434
</Typography>

src/features/stats/StatMaxAugmentIncrease.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export function StatMaxAugmentIncrease() {
4848
possibleStatTypes={possibleStatTypes}
4949
statSnap={statSnap as RandomStat}
5050
statState={statState}
51+
isAugmented={false}
5152
/>
5253
) : (
5354
<EmptyStatEditor

src/models/basis-values.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/models/dto.ts

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,3 @@
11
export interface Dto {
22
version: number;
33
}
4-
5-
export interface DtoMigration {
6-
/** Version to migrate from to the next version */
7-
version: number;
8-
migrate(dto: Dto): Dto;
9-
}
10-
11-
/** Versioned migrations, in order */
12-
export type DtoMigrations = DtoMigration[];
13-
14-
export function migrateDtoToLatestVersion<T extends Dto>(
15-
dto: Dto,
16-
migrations: DtoMigrations
17-
): T {
18-
const version = dto.version ?? 1; // Default to version 1, for DTOs that don't have a version yet
19-
const latestVersion = migrations[migrations.length - 1].version + 1;
20-
21-
if (version === latestVersion) {
22-
return dto as unknown as T;
23-
}
24-
25-
const migration = migrations.find(
26-
(migration) => migration.version === version
27-
);
28-
29-
if (!migration) {
30-
throw new Error(
31-
`Could not find migration for version ${version} to ${latestVersion}`
32-
);
33-
}
34-
35-
return migrateDtoToLatestVersion(migration.migrate(dto), migrations);
36-
}

0 commit comments

Comments
 (0)