Skip to content

Commit 2235634

Browse files
authored
Merge pull request #120 from dragoni7/optimize-permutation-and-filtering
Optimize permutation and filtering. Layout improvements. Code cleanup
2 parents 8434fdc + 10aca21 commit 2235634

23 files changed

+534
-458
lines changed

src/app/routes/Dashboard.tsx

Lines changed: 137 additions & 301 deletions
Large diffs are not rendered by default.

src/components/D2LTooltip.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { TooltipProps, Tooltip, tooltipClasses, styled } from '@mui/material';
2+
3+
interface D2LTooltipProps extends TooltipProps {
4+
maxWidth?: number;
5+
}
6+
7+
export const D2LTooltip = styled(({ className, ...props }: D2LTooltipProps) => (
8+
<Tooltip {...props} classes={{ popper: className }} />
9+
))(({ theme, maxWidth = 120 }) => ({
10+
[`& .${tooltipClasses.tooltip}`]: {
11+
maxWidth: maxWidth,
12+
backgroundColor: 'rgba(0, 0, 0, 0.9)',
13+
borderRadius: '0px',
14+
boxShadow: 10,
15+
fontFamily: 'Arial, sans-serif',
16+
color: '#ffffff',
17+
fontWeight: 'bold',
18+
fontSize: 14,
19+
[theme.breakpoints.down('lg')]: {
20+
fontSize: 12,
21+
},
22+
},
23+
[`& .${tooltipClasses.arrow}`]: {
24+
color: 'black',
25+
},
26+
}));

src/components/Footer.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ import { Box, Stack, Typography } from '@mui/material';
33
import LogoutButton from '@/features/auth/components/LogoutButton';
44
import RefreshCharacters from './RefreshCharacters';
55
import CoffeeButton from './CoffeeButton';
6+
import useSelectedCharacter from '@/hooks/use-selected-character';
67

7-
interface FooterProps {
8-
emblemUrl: string;
9-
}
10-
11-
const Footer: React.FC<FooterProps> = ({ emblemUrl }) => {
8+
const Footer: React.FC = () => {
9+
const selectedcharacter = useSelectedCharacter();
1210
return (
1311
<Box
1412
sx={{
@@ -17,7 +15,7 @@ const Footer: React.FC<FooterProps> = ({ emblemUrl }) => {
1715
left: 0,
1816
right: 0,
1917
height: '5.4%',
20-
backgroundImage: `url(${emblemUrl})`,
18+
backgroundImage: `url(${selectedcharacter?.emblem?.secondarySpecial})`,
2119
backgroundSize: 'cover',
2220
backgroundPosition: 'center',
2321
display: 'flex',

src/components/HeaderComponent.tsx

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,39 @@
1+
import useSelectedCharacter from '@/hooks/use-selected-character';
2+
import { RootState } from '@/store';
13
import React from 'react';
2-
import { Character } from '../types/d2l-types';
3-
import { useDispatch } from 'react-redux';
4+
import { useDispatch, useSelector } from 'react-redux';
45
import { updateSelectedCharacter } from '../store/DashboardReducer';
56
import {
6-
HeaderOverlayImage,
7-
HeaderDisplayName,
7+
Header,
88
HeaderBottomContainer,
99
HeaderButtonContainer,
1010
HeaderCharacterText,
11-
Header,
11+
HeaderDisplayName,
12+
HeaderOverlayImage,
1213
} from '../styled';
1314

1415
interface HeaderComponentProps {
15-
emblemUrl: string;
16-
overlayUrl: string;
17-
displayName: string;
18-
characters: Character[];
19-
selectedCharacter: Character | null;
2016
onCharacterClick: (index: number) => void;
2117
}
2218

23-
const HeaderComponent: React.FC<HeaderComponentProps> = ({
24-
emblemUrl,
25-
overlayUrl,
26-
displayName,
27-
characters,
28-
selectedCharacter,
29-
onCharacterClick,
30-
}) => {
19+
const HeaderComponent: React.FC<HeaderComponentProps> = ({ onCharacterClick }) => {
3120
const dispatch = useDispatch();
3221

22+
const selectedCharacter = useSelectedCharacter();
23+
24+
const characters = useSelector((root: RootState) => root.profile.characters);
25+
const displayName = useSelector(
26+
(root: RootState) => root.destinyMembership.membership.bungieGlobalDisplayName
27+
);
28+
3329
const handleCharacterClick = (index: number) => {
3430
onCharacterClick(index);
3531
dispatch(updateSelectedCharacter(index));
3632
};
3733

3834
return (
39-
<Header emblemUrl={emblemUrl}>
40-
<HeaderOverlayImage src={overlayUrl} alt="Overlay" />
35+
<Header emblemUrl={selectedCharacter?.emblem?.secondarySpecial!}>
36+
<HeaderOverlayImage src={selectedCharacter?.emblem?.secondaryOverlay!} alt="Overlay" />
4137
<HeaderDisplayName>{displayName}</HeaderDisplayName>
4238
<HeaderBottomContainer>
4339
<HeaderButtonContainer>

src/components/RefreshCharacters.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Box, CircularProgress, IconButton, Tooltip } from '@mui/material';
22
import { Refresh } from '@mui/icons-material';
33
import { useDispatch } from 'react-redux';
4-
import { refreshProfileCharacters } from '../util/profile-characters';
4+
import { refreshProfileCharacters } from '../features/profile/profile-data';
55
import { useState } from 'react';
66

77
export default function RefreshCharacters() {

src/components/SubclassSelector.tsx

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ const SingleDiamondButton: React.FC<SingleDiamondButtonProps> = ({
4949
config: { duration: morphDuration },
5050
}));
5151

52-
// Swap animation adjustments
5352
const [{ x }, swapApi] = useSpring(() => ({
5453
x: 0,
55-
config: { tension: 220, friction: 26 }, // Adjusted for smoother animation
54+
config: { tension: 220, friction: 26 },
5655
}));
5756

5857
const morph = useCallback(() => {
@@ -138,16 +137,7 @@ const SingleDiamondButton: React.FC<SingleDiamondButtonProps> = ({
138137
onSubclassSelect(subclass);
139138
};
140139

141-
const handleReset = () => {
142-
if (lastNonPrismaticSubclass) {
143-
setIsPrismaticActive(false);
144-
setCurrentSubclass(lastNonPrismaticSubclass);
145-
onSubclassSelect(lastNonPrismaticSubclass);
146-
swapApi.start({ x: 0 });
147-
}
148-
};
149-
150-
const handleRightClick = (event: React.MouseEvent, subclass: SubclassConfig) => {
140+
const handleOpenSubclass = (event: React.MouseEvent, subclass: SubclassConfig) => {
151141
event.preventDefault();
152142
onSubclassRightClick(subclass);
153143
};
@@ -170,7 +160,6 @@ const SingleDiamondButton: React.FC<SingleDiamondButtonProps> = ({
170160
<animated.div
171161
className={`single-diamond-wrapper ${isPrismaticActive ? 'prismatic-active' : ''}`}
172162
style={{
173-
// Adjusted swap animation for smoother transition
174163
transform: x.to((x) => `translateX(${x * 40}px)`),
175164
}}
176165
>
@@ -194,7 +183,7 @@ const SingleDiamondButton: React.FC<SingleDiamondButtonProps> = ({
194183
}}
195184
onContextMenu={(event) => {
196185
if (damageType in subclasses && selectedSubclass?.damageType === damageType)
197-
handleRightClick(event, subclasses[Number(damageType)]!);
186+
handleOpenSubclass(event, subclasses[Number(damageType)]!);
198187
}}
199188
>
200189
<img
@@ -211,10 +200,9 @@ const SingleDiamondButton: React.FC<SingleDiamondButtonProps> = ({
211200
<>
212201
<div
213202
className="prismatic-button diamond-shape"
214-
onClick={handleReset}
215-
onContextMenu={(event) => {
203+
onClick={(event) => {
216204
if (selectedSubclass?.damageType === DAMAGE_TYPE.KINETIC)
217-
handleRightClick(event, currentSubclass!);
205+
handleOpenSubclass(event, currentSubclass!);
218206
}}
219207
>
220208
<div className="prismatic-glow diamond-shape"></div>
@@ -233,10 +221,6 @@ const SingleDiamondButton: React.FC<SingleDiamondButtonProps> = ({
233221
transform: x.to((x) => `scale(${1 - x * 0.4})`),
234222
}}
235223
onClick={() => handleSelect(lastNonPrismaticSubclass!)}
236-
onContextMenu={(event) => {
237-
if (selectedSubclass?.damageType !== DAMAGE_TYPE.KINETIC)
238-
handleRightClick(event, lastNonPrismaticSubclass!);
239-
}}
240224
>
241225
<img
242226
src={lastNonPrismaticSubclass!.subclass.icon}
@@ -252,9 +236,9 @@ const SingleDiamondButton: React.FC<SingleDiamondButtonProps> = ({
252236
style={{
253237
transform: x.to((x) => `scale(${1 - x * 0.4})`),
254238
}}
255-
onContextMenu={(event) => {
239+
onClick={(event) => {
256240
if (selectedSubclass?.damageType !== DAMAGE_TYPE.KINETIC)
257-
handleRightClick(event, currentSubclass!);
241+
handleOpenSubclass(event, currentSubclass!);
258242
}}
259243
>
260244
{currentSubclass && (
@@ -269,10 +253,6 @@ const SingleDiamondButton: React.FC<SingleDiamondButtonProps> = ({
269253
<div
270254
className="prismatic-button"
271255
onClick={() => handleSelect(subclasses[DAMAGE_TYPE.KINETIC]!)}
272-
onContextMenu={(event) => {
273-
if (selectedSubclass?.damageType === DAMAGE_TYPE.KINETIC)
274-
handleRightClick(event, subclasses[DAMAGE_TYPE.KINETIC]!);
275-
}}
276256
>
277257
<div className="prismatic-glow"></div>
278258
<RotatingShape />

src/features/armor-mods/components/RequiredMod.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ManifestArmorStatMod } from '../../../types/manifest-types';
22
import { Tooltip, styled } from '@mui/material';
33
import { autoEquipStatMod } from '../mod-utils';
44
import { useDispatch } from 'react-redux';
5+
import { D2LTooltip } from '@/components/D2LTooltip';
56

67
interface RequiredModProps {
78
required: { mod: ManifestArmorStatMod; equipped: boolean };
@@ -23,7 +24,7 @@ export default function RequiredMod({ required }: RequiredModProps) {
2324
}
2425

2526
return (
26-
<Tooltip title={required.mod.name}>
27+
<D2LTooltip maxWidth={300} title={required.mod.name} arrow>
2728
<RequiredModImg
2829
src={required.mod.icon}
2930
onClick={handleOnClick}
@@ -32,6 +33,6 @@ export default function RequiredMod({ required }: RequiredModProps) {
3233
'&:hover': { scale: 1.07 },
3334
}}
3435
/>
35-
</Tooltip>
36+
</D2LTooltip>
3637
);
3738
}

src/features/armor-optimization/components/ExoticSelector.tsx

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import React, { useEffect, useState } from 'react';
2-
import { styled } from '@mui/material/styles';
3-
import { Autocomplete, TextField, Popper } from '@mui/material';
2+
import { Autocomplete, TextField } from '@mui/material';
43
import { db } from '../../../store/db';
54
import { ArmorSlot, Character, ExoticClassCombo } from '../../../types/d2l-types';
65
import {
76
updateSelectedExoticClassCombo,
87
updateSelectedExoticItemHash,
8+
updateSelectedValues,
99
} from '../../../store/DashboardReducer';
1010
import { useDispatch } from 'react-redux';
1111
import { ManifestExoticArmor } from '../../../types/manifest-types';
1212
import { ARMOR } from '../../../lib/bungie_api/constants';
1313
import {
14-
SelectExotic,
1514
StyledPopper,
1615
ExoticIcon,
1716
ComboOption,
@@ -20,29 +19,30 @@ import {
2019
ArrowButton,
2120
ArrowIcon,
2221
} from '../styled';
23-
24-
interface ExoticSelectorProps {
25-
selectedCharacter: Character | undefined;
26-
selectedExoticItemHash: number | null;
27-
}
22+
import { useSelector } from 'react-redux';
23+
import { RootState } from '@/store';
24+
import useSelectedCharacter from '@/hooks/use-selected-character';
2825

2926
interface IntrinsicMod {
3027
itemHash: number;
3128
name: string;
3229
icon: string;
3330
}
3431

35-
const ExoticSelector: React.FC<ExoticSelectorProps> = ({
36-
selectedCharacter,
37-
selectedExoticItemHash,
38-
}) => {
32+
const ExoticSelector: React.FC = () => {
3933
const dispatch = useDispatch();
4034
const [exotics, setExotics] = useState<ManifestExoticArmor[]>([]);
4135
const [comboInput, setComboInput] = useState('');
4236
const [selectedExotic, setSelectedExotic] = useState<ManifestExoticArmor | null>(null);
4337
const [selectedCombo, setSelectedCombo] = useState<ExoticClassCombo | null>(null);
4438
const [inputValue, setInputValue] = React.useState('');
4539
const [intrinsicMods, setIntrinsicMods] = useState<{ [key: number]: IntrinsicMod }>({});
40+
const selectedExoticItemHash = useSelector(
41+
(state: RootState) => state.dashboard.selectedExotic.itemHash
42+
);
43+
44+
const selectedCharacter = useSelectedCharacter();
45+
4646
const exoticClassCombos = selectedCharacter?.exoticClassCombos;
4747

4848
const fetchExoticData = async () => {
@@ -81,6 +81,8 @@ const ExoticSelector: React.FC<ExoticSelectorProps> = ({
8181
useEffect(() => {
8282
fetchExoticData();
8383
fetchIntrinsicModData();
84+
setSelectedExotic(null);
85+
setInputValue('');
8486
}, [selectedCharacter]);
8587

8688
useEffect(() => {
@@ -92,11 +94,6 @@ const ExoticSelector: React.FC<ExoticSelectorProps> = ({
9294
}
9395
}, [selectedExoticItemHash, exotics]);
9496

95-
useEffect(() => {
96-
setSelectedExotic(null);
97-
setInputValue('');
98-
}, [selectedCharacter]);
99-
10097
const handleExoticSelect = (newValue: ManifestExoticArmor | null) => {
10198
setSelectedExotic(newValue);
10299

@@ -117,6 +114,7 @@ const ExoticSelector: React.FC<ExoticSelectorProps> = ({
117114
setSelectedExotic(null);
118115
setSelectedCombo(null);
119116
dispatch(updateSelectedExoticItemHash({ itemHash: null, slot: null }));
117+
dispatch(updateSelectedValues({}));
120118
};
121119

122120
return (
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { RootState } from '@/store';
2+
import { updateAssumeMasterwork, updateAssumeExoticArtifice } from '@/store/DashboardReducer';
3+
import { FormGroup, FormControlLabel, Switch } from '@mui/material';
4+
import { useDispatch } from 'react-redux';
5+
import { useSelector } from 'react-redux';
6+
7+
export default function Filters() {
8+
const { assumeMasterwork, assumeExoticArtifice } = useSelector(
9+
(state: RootState) => state.dashboard
10+
);
11+
12+
const dispatch = useDispatch();
13+
return (
14+
<FormGroup
15+
sx={{
16+
padding: 2,
17+
backgroundColor: 'rgba(0, 0, 0, 0.2)',
18+
backdropFilter: 'blur(5px)',
19+
border: '1px solid rgba(255, 255, 255, 0.3)',
20+
}}
21+
>
22+
<FormControlLabel
23+
control={
24+
<Switch checked={assumeMasterwork} onChange={() => dispatch(updateAssumeMasterwork())} />
25+
}
26+
label="Assume Armor Masterworked"
27+
/>
28+
<FormControlLabel
29+
control={
30+
<Switch
31+
checked={assumeExoticArtifice}
32+
onChange={() => dispatch(updateAssumeExoticArtifice())}
33+
/>
34+
}
35+
label="Assume Exotics are Artifice"
36+
/>
37+
</FormGroup>
38+
);
39+
}

0 commit comments

Comments
 (0)