Files
Homarr/src/components/Settings/Common/SearchEngine/SearchEngineSelector.tsx

136 lines
4.0 KiB
TypeScript
Raw Normal View History

import { Alert, Paper, SegmentedControl, Space, Stack, TextInput, Title } from '@mantine/core';
import { IconInfoCircle } from '@tabler/icons-react';
2022-12-04 17:36:30 +01:00
import { useTranslation } from 'next-i18next';
import { ChangeEventHandler, useState } from 'react';
2022-12-06 21:22:37 +01:00
import { useConfigContext } from '../../../../config/provider';
import { useConfigStore } from '../../../../config/store';
2022-12-04 17:36:30 +01:00
import {
CommonSearchEngineCommonSettingsType,
SearchEngineCommonSettingsType,
2022-12-06 21:22:37 +01:00
} from '../../../../types/settings';
import { SearchNewTabSwitch } from './SearchNewTabSwitch';
2022-12-04 17:36:30 +01:00
interface Props {
searchEngine: SearchEngineCommonSettingsType;
}
export const SearchEngineSelector = ({ searchEngine }: Props) => {
const { t } = useTranslation(['settings/general/search-engine']);
const { updateSearchEngineConfig } = useUpdateSearchEngineConfig();
const [engine, setEngine] = useState(searchEngine.type);
const [searchUrl, setSearchUrl] = useState(
searchEngine.type === 'custom' ? searchEngine.properties.template : searchUrls.google
);
const onEngineChange = (value: EngineType) => {
setEngine(value);
updateSearchEngineConfig(value, searchUrl);
};
const onSearchUrlChange: ChangeEventHandler<HTMLInputElement> = (ev) => {
const url = ev.currentTarget.value;
setSearchUrl(url);
updateSearchEngineConfig(engine, url);
};
return (
<Stack spacing={0} mt="xs">
<Title order={5} mb="xs">
{t('title')}
</Title>
<SegmentedControl
fullWidth
mb="sm"
title={t('title') ?? undefined}
2022-12-04 17:36:30 +01:00
value={engine}
onChange={onEngineChange}
data={searchEngineOptions}
/>
<Paper p="md" py="sm" mb="md" withBorder>
<Title order={6} mb={0}>
2023-01-06 12:23:54 +09:00
{t('configurationName')}
</Title>
<SearchNewTabSwitch defaultValue={searchEngine.properties.openInNewTab} />
{engine === 'custom' && (
<>
<Space mb="md" />
<TextInput
label={t('customEngine.label')}
name={t('configurationName') ?? undefined}
description={t('tips.placeholderTip')}
placeholder={t('customEngine.placeholder') ?? undefined}
value={searchUrl}
onChange={onSearchUrlChange}
/>
</>
)}
</Paper>
2022-12-04 17:36:30 +01:00
<Alert icon={<IconInfoCircle />} color="blue">
{t('tips.generalTip')}
</Alert>
</Stack>
);
};
const searchEngineOptions: { label: string; value: EngineType }[] = [
{ label: 'Google', value: 'google' },
{ label: 'DuckDuckGo', value: 'duckDuckGo' },
{ label: 'Bing', value: 'bing' },
{ label: 'Custom', value: 'custom' },
];
export const searchUrls: { [key in CommonSearchEngineCommonSettingsType['type']]: string } = {
google: 'https://google.com/search?q=',
duckDuckGo: 'https://duckduckgo.com/?q=',
bing: 'https://bing.com/search?q=',
};
type EngineType = SearchEngineCommonSettingsType['type'];
const useUpdateSearchEngineConfig = () => {
const { name: configName } = useConfigContext();
const updateConfig = useConfigStore((x) => x.updateConfig);
if (!configName) {
2022-12-04 17:36:30 +01:00
return {
updateSearchEngineConfig: () => {},
};
}
2022-12-04 17:36:30 +01:00
const updateSearchEngineConfig = (engine: EngineType, searchUrl: string) => {
updateConfig(configName, (prev) => ({
...prev,
settings: {
...prev.settings,
common: {
...prev.settings.common,
searchEngine:
engine === 'custom'
? {
type: engine,
properties: {
...prev.settings.common.searchEngine.properties,
template: searchUrl,
},
}
: {
type: engine,
properties: {
openInNewTab: prev.settings.common.searchEngine.properties.openInNewTab,
enabled: prev.settings.common.searchEngine.properties.enabled,
},
},
},
},
}));
};
return {
updateSearchEngineConfig,
};
};