| @@ -43,14 +43,11 @@ const FeaturePanel: FC<IFeaturePanelProps> = ({ | |||
| {headerIcon && <div className='flex items-center justify-center w-6 h-6'>{headerIcon}</div>} | |||
| <div className='text-sm font-semibold text-gray-800'>{title}</div> | |||
| </div> | |||
| <div> | |||
| {isShowTextToSpeech | |||
| ? ( | |||
| <div className='flex items-center'> | |||
| <ParamsConfig/> | |||
| </div> | |||
| ) | |||
| : headerRight} | |||
| <div className='flex gap-2 items-center'> | |||
| {headerRight && <div>{headerRight}</div>} | |||
| {isShowTextToSpeech && <div className='flex items-center'> | |||
| <ParamsConfig/> | |||
| </div>} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -13,29 +13,19 @@ import ConfigContext from '@/context/debug-configuration' | |||
| import { fetchAppVoices } from '@/service/apps' | |||
| import Tooltip from '@/app/components/base/tooltip' | |||
| import { HelpCircle } from '@/app/components/base/icons/src/vender/line/general' | |||
| import { languages } from '@/utils/language' | |||
| const VoiceParamConfig: FC = () => { | |||
| const { t } = useTranslation() | |||
| const pathname = usePathname() | |||
| const matched = pathname.match(/\/app\/([^/]+)/) | |||
| const appId = (matched?.length && matched[1]) ? matched[1] : '' | |||
| const LanguageItems = [ | |||
| { value: 'zh-Hans', name: 'Chinese' }, | |||
| { value: 'en-US', name: 'English' }, | |||
| { value: 'de-DE', name: 'German' }, | |||
| { value: 'fr-FR', name: 'French' }, | |||
| { value: 'es-ES', name: 'Spanish' }, | |||
| { value: 'it-IT', name: 'Italian' }, | |||
| { value: 'th-TH', name: 'Thai' }, | |||
| { value: 'id-ID', name: 'Indonesian' }, | |||
| ] | |||
| const { | |||
| textToSpeechConfig, | |||
| setTextToSpeechConfig, | |||
| } = useContext(ConfigContext) | |||
| const languageItem = LanguageItems.find(item => item.value === textToSpeechConfig.language) | |||
| const languageItem = languages.find(item => item.value === textToSpeechConfig.language) | |||
| const localLanguagePlaceholder = languageItem?.name || t('common.placeholder.select') | |||
| const voiceItems = useSWR({ url: `/apps/${appId}/text-to-audio/voices?language=${languageItem ? languageItem.value : 'en-US'}` }, fetchAppVoices).data | |||
| @@ -87,7 +77,7 @@ const VoiceParamConfig: FC = () => { | |||
| > | |||
| <Listbox.Options className="absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg border-gray-200 border-[0.5px] focus:outline-none sm:text-sm"> | |||
| {LanguageItems.map((item: Item) => ( | |||
| {languages.map((item: Item) => ( | |||
| <Listbox.Option | |||
| key={item.value} | |||
| className={({ active }) => | |||
| @@ -1,12 +1,17 @@ | |||
| 'use client' | |||
| import React, { type FC } from 'react' | |||
| import { useTranslation } from 'react-i18next' | |||
| import { useContext } from 'use-context-selector' | |||
| import Panel from '@/app/components/app/configuration/base/feature-panel' | |||
| import { Speaker } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' | |||
| import ConfigContext from '@/context/debug-configuration' | |||
| import { languages } from '@/utils/language' | |||
| const TextToSpeech: FC = () => { | |||
| const { t } = useTranslation() | |||
| const { | |||
| textToSpeechConfig, | |||
| } = useContext(ConfigContext) | |||
| return ( | |||
| <Panel | |||
| title={ | |||
| @@ -16,7 +21,9 @@ const TextToSpeech: FC = () => { | |||
| } | |||
| headerIcon={<Speaker className='w-4 h-4 text-[#7839EE]' />} | |||
| headerRight={ | |||
| <div className='text-xs text-gray-500'>{t('appDebug.feature.textToSpeech.resDes')}</div> | |||
| <div className='text-xs text-gray-500'> | |||
| {languages.find(i => i.value === textToSpeechConfig.language)?.name} {textToSpeechConfig.voice} | |||
| </div> | |||
| } | |||
| noBodySpacing | |||
| isShowTextToSpeech={true} | |||
| @@ -49,6 +49,10 @@ const translation = { | |||
| itIT: 'Italian', | |||
| thTH: 'Thai.', | |||
| idID: 'Indonesian', | |||
| jaJP: 'Japanese', | |||
| koKR: 'Korean', | |||
| ptBR: 'Portuguese', | |||
| ruRU: 'Russian', | |||
| }, | |||
| }, | |||
| unit: { | |||
| @@ -63,6 +63,10 @@ const translation = { | |||
| itIT: 'italiano', | |||
| thTH: 'tailandês', | |||
| idID: 'indonésio', | |||
| jaJP: 'japonês', | |||
| koKR: 'coreano', | |||
| ptBR: 'português', | |||
| ruRU: 'russo', | |||
| }, | |||
| }, | |||
| anthropicHosted: { | |||
| @@ -49,6 +49,10 @@ const translation = { | |||
| itIT: '意大利语', | |||
| thTH: '泰语', | |||
| idID: '印尼语', | |||
| jaJP: '日语', | |||
| koKR: '韩语', | |||
| ptBR: '葡萄牙语', | |||
| ruRU: '俄语', | |||
| }, | |||
| }, | |||
| unit: { | |||
| @@ -3,8 +3,8 @@ export type Item = { | |||
| name: string | |||
| } | |||
| export const LanguagesSupported = ['en-US', 'zh-Hans', 'pt-BR', 'es-ES', 'fr-FR', 'de-DE', 'ja-JP', 'ko-KR', 'ru-RU', 'it-IT'] | |||
| export const LanguagesSupportedUnderscore = ['en_US', 'zh_Hans', 'pt_BR', 'es_ES', 'fr_FR', 'de_DE', 'ja_JP', 'ko_KR', 'ru_RU', 'it_IT'] | |||
| export const LanguagesSupported = ['en-US', 'zh-Hans', 'pt-BR', 'es-ES', 'fr-FR', 'de-DE', 'ja-JP', 'ko-KR', 'ru-RU', 'it-IT', 'th-TH', 'id-ID'] | |||
| export const LanguagesSupportedUnderscore = ['en_US', 'zh_Hans', 'pt_BR', 'es_ES', 'fr_FR', 'de_DE', 'ja_JP', 'ko_KR', 'ru_RU', 'it_IT', 'th_TH', 'id_ID'] | |||
| export const languages = [ | |||
| { | |||
| @@ -19,34 +19,42 @@ export const languages = [ | |||
| value: 'pt-BR', | |||
| name: 'Português(Brasil)', | |||
| }, | |||
| // { | |||
| // value: 'es-ES', | |||
| // name: 'Español(España)', | |||
| // }, | |||
| // { | |||
| // value: 'fr-FR', | |||
| // name: 'Français(France)', | |||
| // }, | |||
| // { | |||
| // value: 'de-DE', | |||
| // name: 'Deutsch(Deutschland)', | |||
| // }, | |||
| // { | |||
| // value: 'ja-JP', | |||
| // name: '日本語(日本)', | |||
| // }, | |||
| // { | |||
| // value: 'ko-KR', | |||
| // name: '한국어(대한민국)', | |||
| // }, | |||
| // { | |||
| // value: 'ru-RU', | |||
| // name: 'Русский(Россия)', | |||
| // }, | |||
| // { | |||
| // value: 'it-IT', | |||
| // name: 'Italiano(Italia)', | |||
| // }, | |||
| { | |||
| value: 'es-ES', | |||
| name: 'Español(España)', | |||
| }, | |||
| { | |||
| value: 'fr-FR', | |||
| name: 'Français(France)', | |||
| }, | |||
| { | |||
| value: 'de-DE', | |||
| name: 'Deutsch(Deutschland)', | |||
| }, | |||
| { | |||
| value: 'ja-JP', | |||
| name: '日本語(日本)', | |||
| }, | |||
| { | |||
| value: 'ko-KR', | |||
| name: '한국어(대한민국)', | |||
| }, | |||
| { | |||
| value: 'ru-RU', | |||
| name: 'Русский(Россия)', | |||
| }, | |||
| { | |||
| value: 'it-IT', | |||
| name: 'Italiano(Italia)', | |||
| }, | |||
| { | |||
| value: 'th-TH', | |||
| name: 'ไทย(ประเทศไทย)', | |||
| }, | |||
| { | |||
| value: 'id-ID', | |||
| name: 'Bahasa Indonesia', | |||
| }, | |||
| ] | |||
| export const getModelRuntimeSupported = (locale: string) => { | |||