@@ -29,6 +29,7 @@ import {
29
29
resetLoadout ,
30
30
resetLoadoutArmorMods ,
31
31
updateLoadoutArmor ,
32
+ updateLoadoutArmorMods ,
32
33
updateLoadoutCharacter ,
33
34
updateRequiredStatMods ,
34
35
updateSubclass ,
@@ -39,14 +40,14 @@ import { updateManifest } from '../../lib/bungie_api/manifest';
39
40
import LoadoutCustomization from '../../components/LoadoutCustomization' ;
40
41
import background from '/assets/background.png' ;
41
42
import ExoticSelector from '../../features/armor-optimization/components/ExoticSelector' ;
42
- import { DAMAGE_TYPE } from '../../lib/bungie_api/constants' ;
43
+ import { ARMOR_ARRAY , DAMAGE_TYPE } from '../../lib/bungie_api/constants' ;
43
44
import { decodeLoadout } from '../../features/loadouts/util/loadout-encoder' ;
44
45
import {
45
46
resetDashboard ,
46
47
updateSelectedCharacter ,
47
48
updateSelectedExoticItemHash ,
48
49
} from '../../store/DashboardReducer' ;
49
- import { CircularProgress , Box , Grid , Typography } from '@mui/material' ;
50
+ import { CircularProgress , Box , Grid , Typography , Container } from '@mui/material' ;
50
51
import { ManifestArmorStatMod , ManifestExoticArmor } from '../../types/manifest-types' ;
51
52
import { SharedLoadoutDto } from '../../features/loadouts/types' ;
52
53
import { updateProfileCharacters } from '../../store/ProfileReducer' ;
@@ -55,20 +56,23 @@ import useArtificeMods from '../../hooks/use-artifice-mods';
55
56
import useStatMods from '../../hooks/use-stat-mods' ;
56
57
import StatModifications from '../../features/subclass/components/StatModifications' ;
57
58
import Footer from '../../components/Footer' ;
59
+ import { equipSharedMods } from '@/features/loadouts/util/loadout-utils' ;
60
+ import FadeIn from '@/components/FadeIn' ;
58
61
59
62
const DashboardContent = styled ( Grid ) ( ( { theme } ) => ( {
60
63
backgroundImage : `url(${ background } )` ,
61
64
backgroundSize : 'cover' ,
62
65
backgroundPosition : 'center' ,
63
66
} ) ) ;
64
67
65
- const LoadingScreen = styled ( Grid ) ( ( { theme } ) => ( {
68
+ const LoadingScreen = styled ( Box ) ( ( { theme } ) => ( {
66
69
height : '100vh' ,
67
70
width : '100vw' ,
68
71
display : 'flex' ,
69
72
flexDirection : 'column' ,
70
73
justifyContent : 'center' ,
71
74
alignItems : 'center' ,
75
+ textAlign : 'center' ,
72
76
backgroundImage : `url(${ background } )` ,
73
77
backgroundSize : 'cover' ,
74
78
backgroundPosition : 'center' ,
@@ -89,7 +93,7 @@ export const Dashboard: React.FC = () => {
89
93
const fragments = useSelector (
90
94
( state : RootState ) => state . loadoutConfig . loadout . subclassConfig . fragments
91
95
) ;
92
- const [ generatingPermutations , setGeneratingPermutations ] = useState ( false ) ;
96
+
93
97
const [ subclasses , setSubclasses ] = useState <
94
98
{ [ key : number ] : SubclassConfig | undefined } | undefined
95
99
> ( undefined ) ;
@@ -101,6 +105,7 @@ export const Dashboard: React.FC = () => {
101
105
const [ showLoadoutCustomization , setShowLoadoutCustomization ] = useState ( false ) ;
102
106
const [ showAbilitiesModification , setShowAbilitiesModification ] = useState ( false ) ;
103
107
const [ sharedLoadoutDto , setSharedLoadoutDto ] = useState < SharedLoadoutDto | undefined > ( undefined ) ;
108
+ const [ loadingMessage , setLoadingMessage ] = useState < String > ( 'Loading...' ) ;
104
109
105
110
const statMods = useStatMods ( ) ;
106
111
const artificeMods = useArtificeMods ( ) ;
@@ -212,9 +217,11 @@ export const Dashboard: React.FC = () => {
212
217
} ;
213
218
214
219
const updateData = async ( ) => {
220
+ setLoadingMessage ( 'Loading Destiny Data...' ) ;
215
221
await updateManifest ( ) ;
216
222
const destinyMembership = await getDestinyMembershipId ( ) ;
217
223
dispatch ( updateMembership ( destinyMembership ) ) ;
224
+ setLoadingMessage ( 'Loading Character Data...' ) ;
218
225
const profileCharacters = await getProfileData ( ) ;
219
226
dispatch ( updateProfileCharacters ( profileCharacters ) ) ;
220
227
@@ -226,9 +233,12 @@ export const Dashboard: React.FC = () => {
226
233
const sharedLoadoutLink = localStorage . getItem ( 'lastShared' ) ;
227
234
228
235
if ( sharedLoadoutLink !== '' && sharedLoadoutLink !== null ) {
236
+ setLoadingMessage ( 'Finding Best Loadout From Share Link...' ) ;
229
237
const sharedLoadoutDto = decodeLoadout ( sharedLoadoutLink ! ) ;
230
238
setSharedLoadoutDto ( sharedLoadoutDto ) ;
231
239
240
+ await equipSharedMods ( sharedLoadoutDto , dispatch ) . catch ( console . error ) ;
241
+
232
242
targetCharacterIndex = profileCharacters . findIndex (
233
243
( character : Character ) => character . class === sharedLoadoutDto . characterClass
234
244
) ;
@@ -254,6 +264,8 @@ export const Dashboard: React.FC = () => {
254
264
} )
255
265
) ;
256
266
}
267
+
268
+ setSharedLoadoutDto ( undefined ) ;
257
269
} else {
258
270
const keys = Object . keys ( profileCharacters [ targetCharacterIndex ] . subclasses ) ;
259
271
@@ -345,21 +357,24 @@ export const Dashboard: React.FC = () => {
345
357
filtered = filterPermutations ( permutations , selectedValues , fragmentStatModifications ) ;
346
358
}
347
359
348
- setGeneratingPermutations ( false ) ;
349
-
350
360
return filtered ;
351
361
} , [ permutations , selectedValues , sharedLoadoutDto , fragmentStatModifications ] ) ;
352
362
353
363
useEffect ( ( ) => {
354
364
if ( filteredPermutations && sharedLoadoutDto ) {
355
- openLoadoutCustomization ( filteredPermutations [ 0 ] ) ;
365
+ openLoadoutCustomization ( filteredPermutations [ 0 ] , false ) . catch ( console . error ) ;
356
366
localStorage . removeItem ( 'lastShared' ) ;
357
367
}
358
368
} , [ filteredPermutations , sharedLoadoutDto ] ) ;
359
369
360
- function openLoadoutCustomization ( filteredPermutation : FilteredPermutation ) {
361
- dispatch ( resetLoadoutArmorMods ( ) ) ;
370
+ async function openLoadoutCustomization (
371
+ filteredPermutation : FilteredPermutation ,
372
+ clearMods : boolean = true
373
+ ) {
374
+ if ( clearMods ) dispatch ( resetLoadoutArmorMods ( ) ) ;
375
+
362
376
dispatch ( updateLoadoutArmor ( filteredPermutation . permutation ) ) ;
377
+
363
378
const allStatMods = statMods . concat ( artificeMods ) ;
364
379
let requiredMods : { mod : ManifestArmorStatMod ; equipped : boolean } [ ] = [ ] ;
365
380
@@ -392,6 +407,7 @@ export const Dashboard: React.FC = () => {
392
407
}
393
408
394
409
dispatch ( updateRequiredStatMods ( requiredMods ) ) ;
410
+
395
411
setShowLoadoutCustomization ( true ) ;
396
412
}
397
413
@@ -452,95 +468,102 @@ export const Dashboard: React.FC = () => {
452
468
return (
453
469
< >
454
470
{ showAbilitiesModification && customizingSubclass ? (
455
- < SubclassCustomizationWrapper
456
- onBackClick = { ( ) => setShowAbilitiesModification ( false ) }
457
- subclass = { customizingSubclass }
458
- screenshot = { customizingSubclass . subclass . screenshot }
459
- />
460
- ) : showLoadoutCustomization ? (
461
- < LoadoutCustomization
462
- onBackClick = { ( ) => {
463
- setShowLoadoutCustomization ( false ) ;
464
- setSharedLoadoutDto ( undefined ) ;
465
- } }
466
- screenshot = { selectedSubclass ?. subclass . screenshot || '' }
467
- subclass = { selectedSubclass ! }
468
- />
469
- ) : sharedLoadoutDto === undefined && selectedSubclass ? (
470
- < >
471
- < HeaderComponent
472
- emblemUrl = { characters [ selectedCharacterIndex ] ?. emblem ?. secondarySpecial || '' }
473
- overlayUrl = { characters [ selectedCharacterIndex ] ?. emblem ?. secondaryOverlay || '' }
474
- displayName = { membership . bungieGlobalDisplayName }
475
- characters = { characters }
476
- selectedCharacter = { characters [ selectedCharacterIndex ] ! }
477
- onCharacterClick = { handleCharacterClick }
471
+ < FadeIn duration = { 160 } >
472
+ < SubclassCustomizationWrapper
473
+ onBackClick = { ( ) => setShowAbilitiesModification ( false ) }
474
+ subclass = { customizingSubclass }
475
+ screenshot = { customizingSubclass . subclass . screenshot }
478
476
/>
479
-
480
- < Grid
481
- container
482
- sx = { {
483
- width : '100vw' ,
484
- height : '100vh' ,
485
- overflowY : 'auto' ,
486
- paddingTop : '120px' ,
477
+ </ FadeIn >
478
+ ) : showLoadoutCustomization && sharedLoadoutDto === undefined ? (
479
+ < FadeIn duration = { 160 } >
480
+ < LoadoutCustomization
481
+ onBackClick = { ( ) => {
482
+ setShowLoadoutCustomization ( false ) ;
487
483
} }
488
- >
489
- < DashboardContent item container md = { 12 } justifyContent = "space-evenly" >
490
- < Grid item container direction = "column" md = { 4 } spacing = { 3 } sx = { { marginTop : '2%' } } >
491
- < Grid item md = { 1 } >
492
- < SingleDiamondButton
493
- subclasses = { subclasses }
494
- selectedSubclass = { selectedSubclass }
495
- onSubclassSelect = { handleSubclassSelect }
496
- onSubclassRightClick = { handleSubclassRightClick }
497
- />
498
- </ Grid >
499
- < Grid item md = { 1 } >
500
- < NumberBoxes />
484
+ screenshot = { selectedSubclass ?. subclass . screenshot || '' }
485
+ subclass = { selectedSubclass ! }
486
+ />
487
+ </ FadeIn >
488
+ ) : sharedLoadoutDto === undefined && selectedSubclass ? (
489
+ < >
490
+ < FadeIn duration = { 200 } >
491
+ < HeaderComponent
492
+ emblemUrl = { characters [ selectedCharacterIndex ] ?. emblem ?. secondarySpecial || '' }
493
+ overlayUrl = { characters [ selectedCharacterIndex ] ?. emblem ?. secondaryOverlay || '' }
494
+ displayName = { membership . bungieGlobalDisplayName }
495
+ characters = { characters }
496
+ selectedCharacter = { characters [ selectedCharacterIndex ] ! }
497
+ onCharacterClick = { handleCharacterClick }
498
+ />
499
+ </ FadeIn >
500
+
501
+ < FadeIn duration = { 300 } >
502
+ < Grid
503
+ container
504
+ sx = { {
505
+ width : '100vw' ,
506
+ height : '100vh' ,
507
+ overflowY : 'auto' ,
508
+ paddingTop : '120px' ,
509
+ } }
510
+ >
511
+ < DashboardContent item container md = { 12 } justifyContent = "space-evenly" >
512
+ < Grid item container direction = "column" md = { 4 } spacing = { 3 } sx = { { marginTop : '2%' } } >
513
+ < Grid item md = { 1 } >
514
+ < SingleDiamondButton
515
+ subclasses = { subclasses }
516
+ selectedSubclass = { selectedSubclass }
517
+ onSubclassSelect = { handleSubclassSelect }
518
+ onSubclassRightClick = { handleSubclassRightClick }
519
+ />
520
+ </ Grid >
521
+ < Grid item md = { 1 } >
522
+ < NumberBoxes />
523
+ </ Grid >
501
524
</ Grid >
502
- </ Grid >
503
- < Grid
504
- item
505
- container
506
- md = { 4 }
507
- spacing = { 3 }
508
- direction = "column"
509
- justifyContent = { 'start' }
510
- alignItems = { 'center' }
511
- sx = { { marginTop : '1%' } }
512
- >
513
- < Grid item height = "32vh" >
514
- < ExoticSelector
515
- selectedCharacter = { characters [ selectedCharacterIndex ] ! }
516
- selectedExoticItemHash = { selectedExotic . itemHash }
517
- />
525
+ < Grid
526
+ item
527
+ container
528
+ md = { 4 }
529
+ spacing = { 3 }
530
+ direction = "column"
531
+ justifyContent = { 'start' }
532
+ alignItems = { 'center' }
533
+ sx = { { marginTop : '1%' } }
534
+ >
535
+ < Grid item height = "32vh" >
536
+ < ExoticSelector
537
+ selectedCharacter = { characters [ selectedCharacterIndex ] ! }
538
+ selectedExoticItemHash = { selectedExotic . itemHash }
539
+ />
540
+ </ Grid >
541
+ < Grid item alignSelf = "flex-start" >
542
+ < StatModifications />
543
+ </ Grid >
518
544
</ Grid >
519
- < Grid item alignSelf = "flex-start" >
520
- < StatModifications />
545
+ < Grid item md = { 4 } sx = { { marginTop : '1%' } } >
546
+ { filteredPermutations ? (
547
+ < PermutationsList
548
+ permutations = { filteredPermutations }
549
+ onPermutationClick = { openLoadoutCustomization }
550
+ />
551
+ ) : (
552
+ false
553
+ ) }
521
554
</ Grid >
522
- </ Grid >
523
- < Grid item md = { 4 } sx = { { marginTop : '1%' } } >
524
- { filteredPermutations ? (
525
- < PermutationsList
526
- permutations = { filteredPermutations }
527
- onPermutationClick = { openLoadoutCustomization }
528
- />
529
- ) : (
530
- false
531
- ) }
532
- </ Grid >
533
- < Footer
534
- emblemUrl = { characters [ selectedCharacterIndex ] ?. emblem ?. secondarySpecial || '' }
535
- />
536
- </ DashboardContent >
537
- </ Grid >
555
+ < Footer
556
+ emblemUrl = { characters [ selectedCharacterIndex ] ?. emblem ?. secondarySpecial || '' }
557
+ />
558
+ </ DashboardContent >
559
+ </ Grid >
560
+ </ FadeIn >
538
561
</ >
539
562
) : (
540
- < LoadingScreen container >
563
+ < LoadingScreen >
541
564
< CircularProgress size = { 60 } thickness = { 4 } />
542
565
< Typography variant = "h5" sx = { { mt : 2 , color : 'white' } } >
543
- Loading Dashboard...
566
+ { loadingMessage }
544
567
</ Typography >
545
568
</ LoadingScreen >
546
569
) }
0 commit comments