forked from akai/readest
This commit is contained in:
@@ -142,6 +142,7 @@ const TranslatorPopup: React.FC<TranslatorPopupProps> = ({
|
||||
<div className='mb-2 flex items-center justify-between'>
|
||||
<h1 className='text-sm font-normal'>{_('Original Text')}</h1>
|
||||
<Select
|
||||
className='bg-gray-600 text-white/75'
|
||||
value={sourceLang}
|
||||
onChange={handleSourceLangChange}
|
||||
options={[
|
||||
@@ -168,6 +169,7 @@ const TranslatorPopup: React.FC<TranslatorPopupProps> = ({
|
||||
<div className='mb-2 flex items-center justify-between'>
|
||||
<h2 className='text-sm font-normal'>{_('Translated Text')}</h2>
|
||||
<Select
|
||||
className='bg-gray-600 text-white/75'
|
||||
value={targetLang}
|
||||
onChange={handleTargetLangChange}
|
||||
options={Object.entries(TRANSLATOR_LANGS)
|
||||
@@ -201,6 +203,7 @@ const TranslatorPopup: React.FC<TranslatorPopupProps> = ({
|
||||
)}
|
||||
<div className='ml-auto'>
|
||||
<Select
|
||||
className='bg-gray-600 text-white/75'
|
||||
value={provider}
|
||||
onChange={handleProviderChange}
|
||||
options={providers.map(({ name: value, label }) => ({ value, label }))}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { saveViewSettings } from '../../utils/viewSettingsHelper';
|
||||
import { getTranslators } from '@/services/translators';
|
||||
import { TRANSLATED_LANGS } from '@/services/constants';
|
||||
import DropDown from './DropDown';
|
||||
import Select from '@/components/Select';
|
||||
|
||||
const LangPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
const _ = useTranslation();
|
||||
@@ -22,7 +22,7 @@ const LangPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
const getCurrentUILangOption = () => {
|
||||
const uiLanguage = viewSettings.uiLanguage;
|
||||
return {
|
||||
option: uiLanguage,
|
||||
value: uiLanguage,
|
||||
label:
|
||||
uiLanguage === ''
|
||||
? _('Auto')
|
||||
@@ -32,13 +32,14 @@ const LangPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
|
||||
const getLangOptions = () => {
|
||||
const langs = TRANSLATED_LANGS as Record<string, string>;
|
||||
const options = Object.entries(langs).map(([option, label]) => ({ option, label }));
|
||||
const options = Object.entries(langs).map(([value, label]) => ({ value, label }));
|
||||
options.sort((a, b) => a.label.localeCompare(b.label));
|
||||
options.unshift({ option: '', label: _('System Language') });
|
||||
options.unshift({ value: '', label: _('System Language') });
|
||||
return options;
|
||||
};
|
||||
|
||||
const handleSelectUILang = (option: string) => {
|
||||
const handleSelectUILang = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const option = event.target.value;
|
||||
saveViewSettings(envConfig, bookKey, 'uiLanguage', option, false, false);
|
||||
i18n.changeLanguage(option ? option : navigator.language);
|
||||
};
|
||||
@@ -46,18 +47,19 @@ const LangPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
const getTranslationProviderOptions = () => {
|
||||
const translators = getTranslators();
|
||||
const availableProviders = translators.map((t) => {
|
||||
return { option: t.name, label: t.label };
|
||||
return { value: t.name, label: t.label };
|
||||
});
|
||||
return availableProviders;
|
||||
};
|
||||
|
||||
const getCurrentTranslationProviderOption = () => {
|
||||
const option = translationProvider;
|
||||
const value = translationProvider;
|
||||
const availableProviders = getTranslationProviderOptions();
|
||||
return availableProviders.find((p) => p.option === option) || availableProviders[0]!;
|
||||
return availableProviders.find((p) => p.value === value) || availableProviders[0]!;
|
||||
};
|
||||
|
||||
const handleSelectTranslationProvider = (option: string) => {
|
||||
const handleSelectTranslationProvider = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const option = event.target.value;
|
||||
setTranslationProvider(option);
|
||||
saveViewSettings(envConfig, bookKey, 'translationProvider', option, false, false);
|
||||
viewSettings.translationProvider = option;
|
||||
@@ -65,12 +67,13 @@ const LangPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
};
|
||||
|
||||
const getCurrentTargetLangOption = () => {
|
||||
const option = translateTargetLang;
|
||||
const value = translateTargetLang;
|
||||
const availableOptions = getLangOptions();
|
||||
return availableOptions.find((o) => o.option === option) || availableOptions[0]!;
|
||||
return availableOptions.find((o) => o.value === value) || availableOptions[0]!;
|
||||
};
|
||||
|
||||
const handleSelectTargetLang = (option: string) => {
|
||||
const handleSelectTargetLang = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
const option = event.target.value;
|
||||
setTranslateTargetLang(option);
|
||||
saveViewSettings(envConfig, bookKey, 'translateTargetLang', option, false, false);
|
||||
viewSettings.translateTargetLang = option;
|
||||
@@ -93,12 +96,10 @@ const LangPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
<div className='divide-base-200 divide-y'>
|
||||
<div className='config-item'>
|
||||
<span className=''>{_('Interface Language')}</span>
|
||||
<DropDown
|
||||
<Select
|
||||
value={getCurrentUILangOption().value}
|
||||
onChange={handleSelectUILang}
|
||||
options={getLangOptions()}
|
||||
selected={getCurrentUILangOption()}
|
||||
onSelect={handleSelectUILang}
|
||||
className='dropdown-bottom'
|
||||
listClassName='!max-h-60'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -121,24 +122,21 @@ const LangPanel: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
|
||||
<div className='config-item'>
|
||||
<span className=''>{_('Translation Service')}</span>
|
||||
<DropDown
|
||||
selected={getCurrentTranslationProviderOption()}
|
||||
<Select
|
||||
value={getCurrentTranslationProviderOption().value}
|
||||
onChange={handleSelectTranslationProvider}
|
||||
options={getTranslationProviderOptions()}
|
||||
onSelect={handleSelectTranslationProvider}
|
||||
disabled={!translationEnabled}
|
||||
className='dropdown-top'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='config-item'>
|
||||
<span className=''>{_('Translate To')}</span>
|
||||
<DropDown
|
||||
<Select
|
||||
value={getCurrentTargetLangOption().value}
|
||||
onChange={handleSelectTargetLang}
|
||||
options={getLangOptions()}
|
||||
selected={getCurrentTargetLangOption()}
|
||||
onSelect={handleSelectTargetLang}
|
||||
disabled={!translationEnabled}
|
||||
className='dropdown-top'
|
||||
listClassName='!max-h-60'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,19 +10,27 @@ type SelectProps = {
|
||||
value: string;
|
||||
onChange: (e: React.ChangeEvent<HTMLSelectElement>) => void;
|
||||
options: Option[];
|
||||
disabled?: boolean;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export default function Select({ value, onChange, options, className }: SelectProps) {
|
||||
export default function Select({
|
||||
value,
|
||||
onChange,
|
||||
options,
|
||||
className,
|
||||
disabled = false,
|
||||
}: SelectProps) {
|
||||
return (
|
||||
<select
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
className={clsx(
|
||||
'select h-8 min-h-8 rounded-md border-none text-end text-sm',
|
||||
'bg-gray-600 text-white/75 focus:outline-none focus:ring-0',
|
||||
'focus:outline-none focus:ring-0',
|
||||
className,
|
||||
)}
|
||||
disabled={disabled}
|
||||
style={{
|
||||
textAlignLast: 'end',
|
||||
}}
|
||||
|
||||
@@ -624,7 +624,7 @@ export const TRANSLATED_LANGS = {
|
||||
pl: 'Polski',
|
||||
tr: 'Türkçe',
|
||||
hi: 'हिन्दी',
|
||||
id: 'Bahasa Indonesia',
|
||||
id: 'Indonesia',
|
||||
vi: 'Tiếng Việt',
|
||||
'zh-CN': '简体中文',
|
||||
'zh-TW': '正體中文',
|
||||
|
||||
Reference in New Issue
Block a user