11'use client' ;
22
33import sortBy from 'lodash/sortBy' ;
4+ import partition from 'lodash/partition' ;
45import { useEffect , useMemo , useState } from 'react' ;
56
7+ import { styled } from '@/styles' ;
8+
69import { SendEmail } from './components/send-email' ;
710import type { DownloadDropdownProps } from './download-button.types' ;
811import { Dropdown } from '../dropdown' ;
9- import type { DropdownOptionProps } from '../dropdown/dropdown.types' ;
12+ import type { DropdownOption } from '../dropdown/dropdown.types' ;
1013
1114import { StyledHideElementOn } from '@/components/elements/hide-on/hide-on' ;
1215import { useIsMobile } from '@/lib/hooks/use-is-mobile' ;
1316import { parseUserAgent } from '@/lib/utils/parse-user-agent' ;
17+ import type { DownloadDictionary } from '@/content/data/download-dictionary' ;
1418
1519const LATEST_RELEASE_URL = 'https://github.com/httptoolkit/httptoolkit-desktop/releases/latest' ;
1620
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+
1733export const DownloadDropdown = ( {
1834 $small,
1935 $variant,
@@ -22,25 +38,27 @@ export const DownloadDropdown = ({
2238 fixedOS,
2339 downloadItems,
2440} : DownloadDropdownProps ) => {
25- const [ operativeSystem , setOperativeSystem ] = useState ( ' ') ;
41+ const [ operatingSystem , setOperatingSystem ] = useState < string > ( fixedOS ?? 'windows ') ;
2642 const isMobile = useIsMobile ( ) ;
27- const defaultOperativeSystem =
28- downloadItems . find ( os => os . os === operativeSystem && os . defaultText ) || downloadItems [ 0 ] ;
2943
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 ]
3857 ) ;
3958
4059 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 ) ) ;
4462 } , [ ] ) ;
4563
4664 // Makes the hide/show with styles to avoid CLS issues
@@ -50,15 +68,20 @@ export const DownloadDropdown = ({
5068 < StyledHideElementOn $hideBelow = "md" >
5169 < Dropdown
5270 $small = { $small }
53- href = { defaultOperativeSystem . href }
71+ href = { defaultDownload . href }
5472 $variant = { $variant }
5573 $withBorder = { $withBorder }
5674 aria-label = "Download Items"
5775 items = { items }
5876 >
59- Download for { defaultOperativeSystem . defaultText }
77+ < div >
78+ Download for { defaultDownload . defaultText }
79+ { defaultDownload . subtext && < DownloadSubText >
80+ { defaultDownload . subtext }
81+ </ DownloadSubText > }
82+ </ div >
6083 </ Dropdown >
6184 </ StyledHideElementOn >
6285 </ >
6386 ) ;
64- } ;
87+ } ;
0 commit comments