| {headerIcon && <div className='flex items-center justify-center w-6 h-6'>{headerIcon}</div>} | {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 className='text-sm font-semibold text-gray-800'>{title}</div> | ||||
| </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> | </div> | ||||
| </div> | </div> |
| import { fetchAppVoices } from '@/service/apps' | import { fetchAppVoices } from '@/service/apps' | ||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| import { HelpCircle } from '@/app/components/base/icons/src/vender/line/general' | import { HelpCircle } from '@/app/components/base/icons/src/vender/line/general' | ||||
| import { languages } from '@/utils/language' | |||||
| const VoiceParamConfig: FC = () => { | const VoiceParamConfig: FC = () => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const pathname = usePathname() | const pathname = usePathname() | ||||
| const matched = pathname.match(/\/app\/([^/]+)/) | const matched = pathname.match(/\/app\/([^/]+)/) | ||||
| const appId = (matched?.length && matched[1]) ? matched[1] : '' | 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 { | const { | ||||
| textToSpeechConfig, | textToSpeechConfig, | ||||
| setTextToSpeechConfig, | setTextToSpeechConfig, | ||||
| } = useContext(ConfigContext) | } = 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 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 | const voiceItems = useSWR({ url: `/apps/${appId}/text-to-audio/voices?language=${languageItem ? languageItem.value : 'en-US'}` }, fetchAppVoices).data | ||||
| > | > | ||||
| <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"> | <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 | <Listbox.Option | ||||
| key={item.value} | key={item.value} | ||||
| className={({ active }) => | className={({ active }) => |
| 'use client' | 'use client' | ||||
| import React, { type FC } from 'react' | import React, { type FC } from 'react' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useContext } from 'use-context-selector' | |||||
| import Panel from '@/app/components/app/configuration/base/feature-panel' | import Panel from '@/app/components/app/configuration/base/feature-panel' | ||||
| import { Speaker } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' | 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 TextToSpeech: FC = () => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const { | |||||
| textToSpeechConfig, | |||||
| } = useContext(ConfigContext) | |||||
| return ( | return ( | ||||
| <Panel | <Panel | ||||
| title={ | title={ | ||||
| } | } | ||||
| headerIcon={<Speaker className='w-4 h-4 text-[#7839EE]' />} | headerIcon={<Speaker className='w-4 h-4 text-[#7839EE]' />} | ||||
| headerRight={ | 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 | noBodySpacing | ||||
| isShowTextToSpeech={true} | isShowTextToSpeech={true} |
| itIT: 'Italian', | itIT: 'Italian', | ||||
| thTH: 'Thai.', | thTH: 'Thai.', | ||||
| idID: 'Indonesian', | idID: 'Indonesian', | ||||
| jaJP: 'Japanese', | |||||
| koKR: 'Korean', | |||||
| ptBR: 'Portuguese', | |||||
| ruRU: 'Russian', | |||||
| }, | }, | ||||
| }, | }, | ||||
| unit: { | unit: { |
| itIT: 'italiano', | itIT: 'italiano', | ||||
| thTH: 'tailandês', | thTH: 'tailandês', | ||||
| idID: 'indonésio', | idID: 'indonésio', | ||||
| jaJP: 'japonês', | |||||
| koKR: 'coreano', | |||||
| ptBR: 'português', | |||||
| ruRU: 'russo', | |||||
| }, | }, | ||||
| }, | }, | ||||
| anthropicHosted: { | anthropicHosted: { |
| itIT: '意大利语', | itIT: '意大利语', | ||||
| thTH: '泰语', | thTH: '泰语', | ||||
| idID: '印尼语', | idID: '印尼语', | ||||
| jaJP: '日语', | |||||
| koKR: '韩语', | |||||
| ptBR: '葡萄牙语', | |||||
| ruRU: '俄语', | |||||
| }, | }, | ||||
| }, | }, | ||||
| unit: { | unit: { |
| name: string | 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 = [ | export const languages = [ | ||||
| { | { | ||||
| value: 'pt-BR', | value: 'pt-BR', | ||||
| name: 'Português(Brasil)', | 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) => { | export const getModelRuntimeSupported = (locale: string) => { |