From 11c16fadbd7954524bb811acecc2c406212a8cea Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Fri, 14 Nov 2025 09:40:25 +0900 Subject: [PATCH] [Update] UI: Add Plamo, OpenAI and Gemini authentication key components and integrate them into the Translation section. --- .../config_page_setter/ui_config_setter.js | 85 +++++++ .../config_page_setter/useSettingsLogics.js | 4 +- src-ui/logics/utils.js | 7 + .../setting_box/translation/Translation.jsx | 229 ++++++++++++++++++ 4 files changed, 324 insertions(+), 1 deletion(-) diff --git a/src-ui/logics/configs/config_page_setter/ui_config_setter.js b/src-ui/logics/configs/config_page_setter/ui_config_setter.js index 4cc07310..a59b8e2b 100644 --- a/src-ui/logics/configs/config_page_setter/ui_config_setter.js +++ b/src-ui/logics/configs/config_page_setter/ui_config_setter.js @@ -221,6 +221,7 @@ export const SETTINGS_ARRAY = [ logics_template_id: "get_set", base_endpoint_name: "selected_translation_compute_device", }, + // DeepL { Category: "Translation", Base_Name: "DeepLAuthKey", @@ -229,6 +230,90 @@ export const SETTINGS_ARRAY = [ logics_template_id: "get_set_delete", base_endpoint_name: "deepl_auth_key", }, + // Plamo + { + Category: "Translation", + Base_Name: "PlamoAuthKey", + default_value: "", + ui_template_id: "input", + logics_template_id: "get_set_delete", + base_endpoint_name: "plamo_auth_key", + }, + { + Category: "Translation", + Base_Name: "SelectablePlamoModelList", + default_value: [], + ui_template_id: "list", + logics_template_id: "get_set", + add_endpoint_run_array: ["from_backend"], + base_endpoint_name: "selectable_plamo_model_list", + response_transform: "arrayToObject", + }, + { + Category: "Translation", + Base_Name: "SelectedPlamoModel", + default_value: "", + ui_template_id: "select", + logics_template_id: "get_set", + add_endpoint_run_array: ["from_backend"], + base_endpoint_name: "selected_plamo_model", + }, + // Gemini + { + Category: "Translation", + Base_Name: "GeminiAuthKey", + default_value: "", + ui_template_id: "input", + logics_template_id: "get_set_delete", + base_endpoint_name: "gemini_auth_key", + }, + { + Category: "Translation", + Base_Name: "SelectableGeminiModelList", + default_value: [], + ui_template_id: "list", + logics_template_id: "get_set", + add_endpoint_run_array: ["from_backend"], + base_endpoint_name: "selectable_gemini_model_list", + response_transform: "arrayToObject", + }, + { + Category: "Translation", + Base_Name: "SelectedGeminiModel", + default_value: "", + ui_template_id: "select", + logics_template_id: "get_set", + add_endpoint_run_array: ["from_backend"], + base_endpoint_name: "selected_gemini_model", + }, + // OpenAI + { + Category: "Translation", + Base_Name: "OpenAIAuthKey", + default_value: "", + ui_template_id: "input", + logics_template_id: "get_set_delete", + base_endpoint_name: "openai_auth_key", + }, + { + Category: "Translation", + Base_Name: "SelectableOpenAIModelList", + default_value: [], + ui_template_id: "list", + logics_template_id: "get_set", + add_endpoint_run_array: ["from_backend"], + base_endpoint_name: "selectable_openai_model_list", + response_transform: "arrayToObject", + }, + { + Category: "Translation", + Base_Name: "SelectedOpenAIModel", + default_value: "", + ui_template_id: "select", + logics_template_id: "get_set", + add_endpoint_run_array: ["from_backend"], + base_endpoint_name: "selected_openai_model", + }, // Transcription // Mic diff --git a/src-ui/logics/configs/config_page_setter/useSettingsLogics.js b/src-ui/logics/configs/config_page_setter/useSettingsLogics.js index 63e714b9..58702b06 100644 --- a/src-ui/logics/configs/config_page_setter/useSettingsLogics.js +++ b/src-ui/logics/configs/config_page_setter/useSettingsLogics.js @@ -1,7 +1,7 @@ import * as stores from "@store"; import { useStdoutToPython } from "@useStdoutToPython"; import { useNotificationStatus } from "@logics_common"; -import { arrayToObject } from "@utils"; +import { arrayToObject, arrayToIdLabel } from "@utils"; const transformResponse = (transformName, payload) => { if (!transformName) return payload; @@ -9,6 +9,8 @@ const transformResponse = (transformName, payload) => { switch (transformName) { case "arrayToObject": return arrayToObject(payload); + case "arrayToIdLabel": + return arrayToIdLabel(payload); default: return payload; } diff --git a/src-ui/logics/utils.js b/src-ui/logics/utils.js index 2f5f8bdc..bf7d3f19 100644 --- a/src-ui/logics/utils.js +++ b/src-ui/logics/utils.js @@ -5,6 +5,13 @@ export const arrayToObject = (array) => { }, {}); }; +export const arrayToIdLabel = (array) => { + return array.map((element) => ({ + id: element, + label: element, + })); +}; + export const chunkArray = (array, size) => { const chunked = []; for (let i = 0; i < array.length; i += size) { diff --git a/src-ui/views/app/config_page/setting_section/setting_box/translation/Translation.jsx b/src-ui/views/app/config_page/setting_section/setting_box/translation/Translation.jsx index 8a8e95cf..28b0f9f2 100644 --- a/src-ui/views/app/config_page/setting_section/setting_box/translation/Translation.jsx +++ b/src-ui/views/app/config_page/setting_section/setting_box/translation/Translation.jsx @@ -12,6 +12,8 @@ import { DownloadModelsContainer, AuthKeyContainer, MultiDropdownMenuContainer, + RadioButtonContainer, + DropdownMenuContainer, useOnMouseLeaveDropdownMenu, } from "../_templates/Templates"; @@ -29,7 +31,17 @@ export const Translation = () => { <> + + + + + + + + + + ); }; @@ -245,6 +257,223 @@ const DeeplAuthKey_Box = () => { ); }; +const PlamoAuthKey_Box = () => { + const { t } = useI18n(); + const { currentPlamoAuthKey, setPlamoAuthKey, deletePlamoAuthKey } = useTranslation(); + const [input_value, seInputValue] = useState(currentPlamoAuthKey.data); + + const onChangeFunction = (value) => { + seInputValue(value); + }; + + const saveFunction = () => { + if (input_value === "" || input_value === null) { + return deletePlamoAuthKey(); + }; + setPlamoAuthKey(input_value); + }; + + useEffect(() => { + if (currentPlamoAuthKey.state === "pending") return; + seInputValue(currentPlamoAuthKey.data); + }, [currentPlamoAuthKey]); + + return ( + <> + + + ); +}; +const PlamoModelContainer = () => { + const { t } = useI18n(); + const { + currentSelectablePlamoModelList, + + currentSelectedPlamoModel, + setSelectedPlamoModel, + } = useTranslation(); + + if (currentSelectablePlamoModelList.data.length === 0) return null; + + const selectFunction = (selected_data) => { + setSelectedPlamoModel(selected_data.selected_id); + }; + + return ( + + ); +}; + + + +const GeminiAuthKey_Box = () => { + const { t } = useI18n(); + const { currentGeminiAuthKey, setGeminiAuthKey, deleteGeminiAuthKey } = useTranslation(); + const [input_value, seInputValue] = useState(currentGeminiAuthKey.data); + + const onChangeFunction = (value) => { + seInputValue(value); + }; + + const saveFunction = () => { + if (input_value === "" || input_value === null) { + return deleteGeminiAuthKey(); + }; + setGeminiAuthKey(input_value); + }; + + useEffect(() => { + if (currentGeminiAuthKey.state === "pending") return; + seInputValue(currentGeminiAuthKey.data); + }, [currentGeminiAuthKey]); + + return ( + <> + + + ); +}; +const GeminiModelContainer = () => { + const { t } = useI18n(); + const { + currentSelectableGeminiModelList, + + currentSelectedGeminiModel, + setSelectedGeminiModel, + } = useTranslation(); + + if (currentSelectableGeminiModelList.data.length === 0) return null; + + const selectFunction = (selected_data) => { + setSelectedGeminiModel(selected_data.selected_id); + }; + + return ( + + ); +}; + + +const OpenAIAuthKey_Box = () => { + const { t } = useI18n(); + const { currentOpenAIAuthKey, setOpenAIAuthKey, deleteOpenAIAuthKey } = useTranslation(); + const [input_value, seInputValue] = useState(currentOpenAIAuthKey.data); + + const onChangeFunction = (value) => { + seInputValue(value); + }; + + const saveFunction = () => { + if (input_value === "" || input_value === null) { + return deleteOpenAIAuthKey(); + }; + setOpenAIAuthKey(input_value); + }; + + useEffect(() => { + if (currentOpenAIAuthKey.state === "pending") return; + seInputValue(currentOpenAIAuthKey.data); + }, [currentOpenAIAuthKey]); + + return ( + <> + + + ); +}; +const OpenAIModelContainer = () => { + const { t } = useI18n(); + const { + currentSelectableOpenAIModelList, + + currentSelectedOpenAIModel, + setSelectedOpenAIModel, + } = useTranslation(); + + if (currentSelectableOpenAIModelList.data.length === 0) return null; + + const selectFunction = (selected_data) => { + setSelectedOpenAIModel(selected_data.selected_id); + }; + + return ( + + ); +}; + + // Duplicate const transformDeviceArray = (devices) => { const name_counts = Object.values(devices).reduce((counts, device) => {