import { ActionIcon, Group, type OptionsFilter, Select, Stack, Text, } from '@mantine/core'; import { useDisclosure } from '@mantine/hooks'; import { HelpModal, WeatherModal } from 'components'; import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks'; import { useEffect, useState } from 'react'; import { FiEdit, FiTrash } from 'react-icons/fi'; import { actionIconClasses, selectClasses } from 'styles'; export default function Search({ current, outlook, extendedForecast, weatherModalOpened, closeWeatherModal, openWeatherModal, }: any) { const { data: providers, isFetched: providersIsFetched } = useQueryAPI({ endpoint: 'api/providers', }); const [providerData, setProviderData] = useState([]); const { data: apps, isFetching: isAppsFetching } = useQueryAPI({ endpoint: 'api/apps', }); const [applicationData, setApplicationData] = useState([]); const { data: history, isFetched: historyIsFetched } = useQueryAPI({ endpoint: 'api/searchHistory', }); const [searchHistory, setSearchHistory] = useState([]); const [filteredHistory, setFilteredHistory] = useState([]); const { mutateAsync: createHistoryItem } = useMutationAPI(); const { mutateAsync: deleteHistoryItem } = useMutationAPI(); const [providerModalOpened, { open: openProviderModal, close: closeProviderModal }] = useDisclosure(false); const [dropdownOpened, { open: openDropdown, close: closeDropdown }] = useDisclosure(); const [listIndex, setListIndex] = useState(0); const { theme, providerLabel, setProviderLabel, providerURL, setProviderURL, providerPrefix, setProviderPrefix, searchValue, setSearchValue, } = useCommonHooks(); const [placeholderValue, setPlaceholderValue] = useState(''); const [value, setValue] = useState(0); const urlPattern = new RegExp( '^(https?:\\/\\/)?' + // protocol '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string '(\\#[-a-z\\d_]*)?$', 'i', ); // fragment locator const handleSearchHistoryItem = (item: any) => { const url = providers.find((provider: any) => provider.prefix === item.option.prefix)?.url || 'https://www.google.com/search?q='; open(`${url}${item.option.searchTerm}`, '_self'); }; const handleKeyPress = (item: any) => { let option = ''; let subtext = ''; if (item.target.value.startsWith('/')) { option = item.target.value.substr(1, item.target.value.indexOf(' ') - 1) || item.target.value.substr(1); subtext = item.target.value.substr(2 + option.length); } else if (item.target.value.startsWith('!')) { if (item.target.value.startsWith('!w')) { subtext = item.target.value.substr(2); } } else { subtext = item.target.value; } if (item.key === 'Enter') { if (providerLabel === 'Show help') { openProviderModal(); } else if (item.target.value.startsWith('/')) { createHistoryItem({ method: 'POST', endpoint: 'api/searchHistory', body: { prefix: providerPrefix, provider: providerLabel, searchTerm: subtext }, }).then(() => { open(`${providerURL}${subtext}`, '_self'); }); } else if (providerLabel === 'Show weather') { openWeatherModal(); } else if (providerLabel.startsWith('Launch')) { open( `https://${applicationData?.find((app: any) => app.baseUrl.substr(1).toLowerCase() === item.target.value.substr(1)).url}`, '_self', ); } else if (urlPattern.test(item.target.value)) { if (/^(https?:\/\/).*/i.test(item.target.value)) window.location = item.target.value; else open(`https://${item.target.value}`, '_self'); } else { createHistoryItem({ method: 'POST', endpoint: 'api/searchHistory', body: { prefix: providerPrefix, provider: providerLabel, searchTerm: subtext }, }).then(() => { open(`${providerURL}${subtext}`, '_self'); }); } } }; const handleKeyUp = (item: any) => { if (item.code === 'Escape') { if (dropdownOpened) { closeDropdown(); } setListIndex(0); setSearchValue(''); setProviderLabel('Google Search'); setProviderPrefix('/g'); setPlaceholderValue(''); } if (item.code === 'ArrowDown' && !dropdownOpened) { setListIndex(0); openDropdown(); setPlaceholderValue( `${searchHistory[listIndex].prefix} ${searchHistory[listIndex].searchTerm}`, ); } if (!providerLabel.startsWith('Invalid')) { handleKeyPress(item); } if (dropdownOpened) { if (searchValue === '') { if (item.code === 'ArrowUp') { if (listIndex === 0) { setListIndex(9); } else { setListIndex(listIndex - 1); } } else if (item.code === 'ArrowDown') { if (listIndex === 9) { setListIndex(0); } else { setListIndex(listIndex + 1); } } else if (item.code === 'ArrowRight' || item.code === 'Tab') { setSearchValue( `${searchHistory[listIndex].prefix} ${searchHistory[listIndex].searchTerm}`, ); setValue(searchHistory[listIndex].id); } } else if (searchValue !== '') { if (item.code === 'ArrowUp') { if (listIndex === 0) { setListIndex(filteredHistory.length - 1); } else if (listIndex >= filteredHistory.length) { setListIndex(filteredHistory.length - 1); } else { setListIndex(listIndex - 1); } } else if (item.code === 'ArrowDown') { if (listIndex >= filteredHistory.length - 1) { setListIndex(0); } else if (value === 0) { setListIndex(0); setValue(-1); } else { setListIndex(listIndex + 1); } } else if (item.code === 'ArrowRight' || item.code === 'Tab') { setSearchValue( `${filteredHistory[listIndex].prefix} ${filteredHistory[listIndex].searchTerm}`, ); setValue(filteredHistory[listIndex].id); } } } }; const onInput = (item: any) => { openDropdown(); setSearchValue(item.currentTarget.value); if ( item.target.value === '/?' || item.target.value === '!help' || item.target.value === '/help' || item.target.value === '!h' || item.target.value === '/h' ) { setProviderLabel('Show help'); } else if (item.target.value.startsWith('/g')) { setProviderLabel('Google Search'); setProviderURL('https://www.google.com/search?q='); setProviderPrefix('/g'); } else if (item.target.value.startsWith('/')) { const provider = providerData?.find( (p: any) => p.prefix === item.target.value.split(' ')[0], ); setProviderLabel(provider?.name || 'Invalid Search'); setProviderURL(provider?.url); setProviderPrefix(provider?.prefix); } else if (item.target.value.startsWith('!')) { if (item.target.value === '!w' || item.target.value === '!weather') { setProviderLabel('Show weather'); } else if ( applicationData?.find( (app: any) => app.baseUrl.substr(1).toLowerCase() === item.target.value.substr(1), ) ) { setProviderLabel(`Launch ${item.target.value.substr(1)}`); } else { setProviderLabel('Invalid function'); } } else { setProviderLabel('Google Search'); setProviderURL('https://www.google.com/search?q='); setProviderPrefix('/g'); } }; const optionsFilter: OptionsFilter = ({ options, search }) => { const splittedSearch = search.toLowerCase().trim().split(' '); return options .filter((option: any) => { const words = option.value.toLowerCase().trim().split(' '); return splittedSearch.every((searchWord) => words.some((word: any) => word.includes(searchWord)), ); }) .slice(0, 10); }; function RenderOption(item: any) { const [showFillButton, setShowFillButton] = useState(false); const m = new Date(item.option.dateTimeStamp); const dateString = `${m.getUTCFullYear()}/${`0${m.getUTCMonth() + 1}`.slice(-2)}/${`0${m.getUTCDate()}`.slice(-2)} ${`0${m.getUTCHours()}`.slice(-2)}:${`0${m.getUTCMinutes()}`.slice(-2)}:${`0${m.getUTCSeconds()}`.slice(-2)}`; return ( { handleSearchHistoryItem(item); }} onMouseEnter={() => { setShowFillButton(true); }} onMouseLeave={() => { setShowFillButton(false); }} > {item.option.provider} {showFillButton && ( { e.stopPropagation(); setSearchValue(item.option.searchTerm); }} > )} {item.option.searchTerm} {dateString} {showFillButton && ( { e.stopPropagation(); deleteHistoryItem({ method: 'DELETE', endpoint: 'api/searchHistory', body: { id: item.option.id }, }); }} > )} ); } useEffect(() => { if (providers && providersIsFetched) { setProviderData(providers); } }, [providers, providersIsFetched]); useEffect(() => { if (apps && !isAppsFetching) { setApplicationData(apps); } }, [apps, isAppsFetching]); useEffect(() => { if (history && historyIsFetched) { setSearchHistory(history); if (filteredHistory.length === 0) { setFilteredHistory(history.slice(0, 10)); } } }, [history, historyIsFetched]); useEffect(() => { if (dropdownOpened) { setPlaceholderValue( `${searchHistory[listIndex].prefix} ${searchHistory[listIndex].searchTerm}`, ); } }, [listIndex, dropdownOpened]); useEffect(() => { const splittedSearch = searchValue.toLowerCase().trim().split(' '); const filtered = searchHistory .filter((item: any) => { const option = `${item.prefix} ${item.searchTerm}`; const words = option.toLowerCase().trim().split(' '); return splittedSearch.every((searchWord) => words.some((word: any) => word.includes(searchWord)), ); }) .slice(0, 10); setFilteredHistory(filtered); }, [searchValue]); return (