1
1
'use client' ;
2
2
3
3
import sortBy from 'lodash/sortBy' ;
4
+ import partition from 'lodash/partition' ;
4
5
import { useEffect , useMemo , useState } from 'react' ;
5
6
7
+ import { styled } from '@/styles' ;
8
+
6
9
import { SendEmail } from './components/send-email' ;
7
10
import type { DownloadDropdownProps } from './download-button.types' ;
8
11
import { Dropdown } from '../dropdown' ;
9
- import type { DropdownOptionProps } from '../dropdown/dropdown.types' ;
12
+ import type { DropdownOption } from '../dropdown/dropdown.types' ;
10
13
11
14
import { StyledHideElementOn } from '@/components/elements/hide-on/hide-on' ;
12
15
import { useIsMobile } from '@/lib/hooks/use-is-mobile' ;
13
16
import { parseUserAgent } from '@/lib/utils/parse-user-agent' ;
17
+ import type { DownloadDictionary } from '@/content/data/download-dictionary' ;
14
18
15
19
const LATEST_RELEASE_URL = 'https://github.com/httptoolkit/httptoolkit-desktop/releases/latest' ;
16
20
21
+ const DownloadSubText = styled . div `
22
+ font-size: ${ ( { theme } ) => theme . fontSizes . text . xs } ;
23
+ margin-top: 4px;
24
+ ` ;
25
+
26
+ const downloadItemToOption = ( item : DownloadDictionary ) => ( {
27
+ as : 'link' ,
28
+ href : item . href || LATEST_RELEASE_URL ,
29
+ text : item . text ,
30
+ subtext : item . subtext
31
+ } as const ) ;
32
+
17
33
export const DownloadDropdown = ( {
18
34
$small,
19
35
$variant,
@@ -22,25 +38,27 @@ export const DownloadDropdown = ({
22
38
fixedOS,
23
39
downloadItems,
24
40
} : DownloadDropdownProps ) => {
25
- const [ operativeSystem , setOperativeSystem ] = useState ( ' ') ;
41
+ const [ operatingSystem , setOperatingSystem ] = useState < string > ( fixedOS ?? 'windows ') ;
26
42
const isMobile = useIsMobile ( ) ;
27
- const defaultOperativeSystem =
28
- downloadItems . find ( os => os . os === operativeSystem && os . defaultText ) || downloadItems [ 0 ] ;
29
43
30
- const items : DropdownOptionProps [ ] = useMemo (
31
- ( ) =>
32
- sortBy ( downloadItems , [ item => ( item . os === defaultOperativeSystem . os ? 0 : 1 ) ] , 'os' , 'desc' ) . map ( item => ( {
33
- as : 'link' ,
34
- href : item . href || LATEST_RELEASE_URL ,
35
- content : item . text ,
36
- } ) ) ,
37
- [ operativeSystem ] ,
44
+ const defaultDownload =
45
+ downloadItems . find ( os => os . os === operatingSystem && os . defaultText ) || downloadItems [ 0 ] ;
46
+
47
+ const items : DropdownOption [ ] = useMemo (
48
+ ( ) => {
49
+ const [ currentOsDownloads , otherOsDownloads ] = partition ( downloadItems , ( { os } ) => os === operatingSystem ) ;
50
+
51
+ return [
52
+ ...sortBy ( currentOsDownloads . map ( downloadItemToOption ) , [ 'desc' ] ) ,
53
+ ...( currentOsDownloads . length ? [ { type : 'hr' } as const ] : [ ] ) ,
54
+ ...sortBy ( otherOsDownloads . map ( downloadItemToOption ) , [ 'os' , 'desc' ] ) ,
55
+ ] ;
56
+ } , [ downloadItems , operatingSystem ]
38
57
) ;
39
58
40
59
useEffect ( ( ) => {
41
- if ( ! isMobile && fixedOS ) return setOperativeSystem ( fixedOS ) ;
42
-
43
- setOperativeSystem ( parseUserAgent ( navigator . userAgent ) ) ;
60
+ if ( ! isMobile && fixedOS ) return setOperatingSystem ( fixedOS ) ;
61
+ setOperatingSystem ( parseUserAgent ( navigator . userAgent ) ) ;
44
62
} , [ ] ) ;
45
63
46
64
// Makes the hide/show with styles to avoid CLS issues
@@ -50,15 +68,20 @@ export const DownloadDropdown = ({
50
68
< StyledHideElementOn $hideBelow = "md" >
51
69
< Dropdown
52
70
$small = { $small }
53
- href = { defaultOperativeSystem . href }
71
+ href = { defaultDownload . href }
54
72
$variant = { $variant }
55
73
$withBorder = { $withBorder }
56
74
aria-label = "Download Items"
57
75
items = { items }
58
76
>
59
- Download for { defaultOperativeSystem . defaultText }
77
+ < div >
78
+ Download for { defaultDownload . defaultText }
79
+ { defaultDownload . subtext && < DownloadSubText >
80
+ { defaultDownload . subtext }
81
+ </ DownloadSubText > }
82
+ </ div >
60
83
</ Dropdown >
61
84
</ StyledHideElementOn >
62
85
</ >
63
86
) ;
64
- } ;
87
+ } ;
0 commit comments