@@ -7,19 +7,24 @@ import type { FC } from 'react';
77import Select from '@/components/Common/Select' ;
88import { ReleaseContext } from '@/providers/releaseProvider' ;
99import type { InstallationMethod } from '@/types/release' ;
10- import {
11- getNextItem ,
12- INSTALLATION_METHODS ,
13- parseCompatibility ,
14- } from '@/util/downloadUtils' ;
10+ import { nextItem , INSTALL_METHODS , parseCompat } from '@/util/downloadUtils' ;
1511
1612const PlatformDropdown : FC = ( ) => {
1713 const release = useContext ( ReleaseContext ) ;
1814 const t = useTranslations ( ) ;
1915
16+ // Prevents the Platform from being set during OS loading state
17+ // This also prevents the Platform from being set (by Dropdwon or Automatic methods)
18+ // when we haven't yet loaded the OS and defined the initial Platform
19+ const setPlaform = ( platform : InstallationMethod | '' ) => {
20+ if ( release . os !== 'LOADING' && release . platform !== '' ) {
21+ release . setPlatform ( platform ) ;
22+ }
23+ } ;
24+
2025 // We parse the compatibility of the dropdown items
2126 const parsedPlatforms = useMemo (
22- ( ) => parseCompatibility ( INSTALLATION_METHODS , release ) ,
27+ ( ) => parseCompat ( INSTALL_METHODS , release ) ,
2328 // We only want to react on the change of the OS and Version
2429 // eslint-disable-next-line react-hooks/exhaustive-deps
2530 [ release . os , release . version ]
@@ -43,39 +48,37 @@ const PlatformDropdown: FC = () => {
4348 [ parsedPlatforms ]
4449 ) ;
4550
46- // Since in some cases we don't want to have a Platform Dropdown
47- // This allows us to render the first non-disabled platform
48- // Or the recommended platform when the Dropdown component is bound
4951 useEffect ( ( ) => {
50- if ( ! release . platform ) {
51- const initial = parsedPlatforms . find ( ( { disabled } ) => ! disabled ) ;
52-
53- const recommended = parsedPlatforms . find (
54- ( { recommended, disabled } ) => recommended && ! disabled
52+ // We should only define the initial Platform if the current platform is empty
53+ // (aka has not yet been set) and the OS has finished loading (in the sense that)
54+ // `detectOS` has finished running and decided what platform we are running on.
55+ if ( release . os !== 'LOADING' && release . platform === '' ) {
56+ release . setPlatform (
57+ // Sets either the utmost recommended platform or the first non-disabled one
58+ // Note that the first item of groupped platforms is always the recommended one
59+ nextItem ( '' , grouppedPlatforms [ 0 ] . items ) ||
60+ nextItem ( '' , parsedPlatforms )
5561 ) ;
56-
57- release . setPlatform ( recommended ?. value || initial ?. value || '' ) ;
5862 }
59- // We are interested only on the initial render of this component
6063 // eslint-disable-next-line react-hooks/exhaustive-deps
61- } , [ ] ) ;
64+ } , [ parsedPlatforms , release . platform , release . os ] ) ;
6265
6366 // We set the Platform to the next available platform when the current
6467 // one is not valid anymore due to OS or Version changes
6568 useEffect (
66- ( ) => release . setPlatform ( getNextItem ( release . platform , parsedPlatforms ) ) ,
69+ ( ) => setPlaform ( nextItem ( release . platform , parsedPlatforms ) ) ,
6770 // We only want to react on the change of the OS and Version
6871 // eslint-disable-next-line react-hooks/exhaustive-deps
6972 [ release . os , release . version ]
7073 ) ;
7174
7275 return (
73- < Select
76+ < Select < InstallationMethod | '' >
7477 values = { grouppedPlatforms }
7578 defaultValue = { release . platform }
7679 loading = { release . os === 'LOADING' || release . platform === '' }
7780 ariaLabel = { t ( 'layouts.download.dropdown.platform' ) }
78- onChange = { platform => release . setPlatform ( platform as InstallationMethod ) }
81+ onChange = { platform => setPlaform ( platform ) }
7982 className = "min-w-28"
8083 inline = { true }
8184 />
0 commit comments