diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/download_models/DownloadModels.jsx b/src-ui/app/config_page/setting_section/setting_box/_components/download_models/DownloadModels.jsx new file mode 100644 index 00000000..747903a1 --- /dev/null +++ b/src-ui/app/config_page/setting_section/setting_box/_components/download_models/DownloadModels.jsx @@ -0,0 +1,79 @@ +import { useState, useEffect } from "react"; +import clsx from "clsx"; +import CircularProgress from '@mui/material/CircularProgress'; +import styles from "./DownloadModels.module.scss"; +import { + RadioButton, + // DownloadModels, +} from "../index"; +export const DownloadModels = (props) => { + const options = props.options.map(item => ({ + ...item, + disabled: !item.is_downloaded + })); + + return ( + <> + + + //
+ // {props.models.map((option) => ( + // + // ))} + //
+ ); +}; + +const ModelSelector = ({option, ...props}) => { + const [circular_color, setCircularColor] = useState(""); + const [circular_color_2, setCircularColor2] = useState(""); + useEffect(() => { + const circular_color = getComputedStyle(document.documentElement).getPropertyValue("--dark_600_color"); + setCircularColor(circular_color.trim()); + const circular_color_2 = getComputedStyle(document.documentElement).getPropertyValue("--primary_300_color"); + setCircularColor2(circular_color_2.trim()); + }, []); + + + const renderContent = () => { + const circular_progress = Math.floor(option.progress / 10) * 10; + + switch (true) { + case option.progress !== null: + return ( + <> + +

{`${Math.round(option.progress)}%`}

+ + ); + case option.is_pending: + return ; + case !option.is_downloaded: + return ( + + ); + default: + return null; + } + }; + + return
{renderContent()}
; +}; diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/download_models/DownloadModels.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/download_models/DownloadModels.module.scss new file mode 100644 index 00000000..aa17a737 --- /dev/null +++ b/src-ui/app/config_page/setting_section/setting_box/_components/download_models/DownloadModels.module.scss @@ -0,0 +1,32 @@ +@import "@scss_mixins"; + +.download_container { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + max-width: 8rem; +} + +.download_button { + pointer-events: auto; + background-color: var(--dark_800_color); + padding: 0.8rem; + flex-shrink: 0; + &:hover { + background-color: var(--dark_750_color); + } + &:active { + background-color: var(--dark_800_color); + } +} +.download_button_label { + font-size: 1.2rem; + color: var(--dark_basic_text_color); +} + +.progress_label { + position: absolute; + font-size: 1rem; + color: var(--dark_basic_text_color); +} \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/index.js b/src-ui/app/config_page/setting_section/setting_box/_components/index.js index 41c044b4..ffd9fa96 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/index.js +++ b/src-ui/app/config_page/setting_section/setting_box/_components/index.js @@ -8,4 +8,5 @@ export { RadioButton } from "./radio_button/RadioButton"; export { Slider } from "./slider/Slider"; export { SwitchBox } from "./switch_box/SwitchBox"; export { ThresholdComponent } from "./threshold_component/ThresholdComponent"; -export { WordFilter, WordFilterListToggleComponent } from "./word_filter/WordFilter"; \ No newline at end of file +export { WordFilter, WordFilterListToggleComponent } from "./word_filter/WordFilter"; +export { DownloadModels } from "./download_models/DownloadModels"; \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/label_component/LabelComponent.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/label_component/LabelComponent.module.scss index 8a423561..7aa82d3c 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/label_component/LabelComponent.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/_components/label_component/LabelComponent.module.scss @@ -2,7 +2,7 @@ display: flex; flex-direction: column; gap: 0.4rem; - flex-shrink: 0; + // flex-shrink: 0; } .label { diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/radio_button/RadioButton.jsx b/src-ui/app/config_page/setting_section/setting_box/_components/radio_button/RadioButton.jsx index 1c83847c..f3efdae4 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/radio_button/RadioButton.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/_components/radio_button/RadioButton.jsx @@ -1,33 +1,42 @@ import styles from "./RadioButton.module.scss"; +import clsx from "clsx"; export const RadioButton = (props) => { + const containerClass = clsx(styles.container, { + [styles.column]: props.column === true, + }); + return ( -
- {props.options.map((option) => ( -
); +}; + +export const DownloadModelsContainer = (props) => { + return ( +
+ + +
+ ); }; \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/_templates/Templates.module.scss b/src-ui/app/config_page/setting_section/setting_box/_templates/Templates.module.scss index 4e381a1d..3f06df1b 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_templates/Templates.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/_templates/Templates.module.scss @@ -4,7 +4,7 @@ justify-content: space-between; align-items: center; padding: 2rem; - gap: 2rem; + gap: 6rem; &.flex_column { flex-direction: column; } diff --git a/src-ui/app/config_page/setting_section/setting_box/appearance/Appearance.jsx b/src-ui/app/config_page/setting_section/setting_box/appearance/Appearance.jsx index abc8b0c7..0425981b 100644 --- a/src-ui/app/config_page/setting_section/setting_box/appearance/Appearance.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/appearance/Appearance.jsx @@ -13,10 +13,6 @@ import { useTransparency, } from "@logics_configs"; -import { - LabelComponent -} from "../_components/"; - import { SliderContainer, DropdownMenuContainer, @@ -42,34 +38,14 @@ const UiLanguageContainer = () => { const is_not_en_lang = currentUiLanguage.data !== "en" && currentUiLanguage.data !== undefined; return ( -
-
- {is_not_en_lang - ? - <> - - - : - - } -
-
- {currentUiLanguage.state === "pending" && } - {Object.entries(ui_configs.selectable_ui_languages).map(([key, value]) => ( - - ))} -
-
+ ); }; @@ -166,11 +142,12 @@ const SendMessageButtonTypeContainer = () => { selectFunction={setSendMessageButtonType} name="send_message_button_type" options={[ - { radio_button_id: "hide", label: t("config_page.send_message_button_type.hide") }, - { radio_button_id: "show", label: t("config_page.send_message_button_type.show") }, - { radio_button_id: "show_and_disable_enter_key", label: t("config_page.send_message_button_type.show_and_disable_enter_key") }, + { id: "hide", label: t("config_page.send_message_button_type.hide") }, + { id: "show", label: t("config_page.send_message_button_type.show") }, + { id: "show_and_disable_enter_key", label: t("config_page.send_message_button_type.show_and_disable_enter_key") }, ]} checked_variable={currentSendMessageButtonType} + column={true} /> ); }; diff --git a/src-ui/app/config_page/setting_section/setting_box/appearance/Appearance.module.scss b/src-ui/app/config_page/setting_section/setting_box/appearance/Appearance.module.scss index 0075aab5..9e9d2c53 100644 --- a/src-ui/app/config_page/setting_section/setting_box/appearance/Appearance.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/appearance/Appearance.module.scss @@ -1,66 +1 @@ -@import "@scss_mixins"; - -.ui_language_container { - display: flex; - width: 100%; - justify-content: space-between; - align-items: center; - padding: 2rem; - border-radius: 0.6rem; -} - -.ui_language_selector_container { - display: flex; - gap: 1rem; - position: relative; -} -.ui_language_label_wrapper { - display: flex; - align-items: center; -} -.ui_language_secondly_label { - font-size: 1.2rem; -} - -.radio_button_wrapper { - display: flex; - align-items: center; - cursor: pointer; - gap: 0.6rem; - padding: 0.6rem 1rem; - border-radius: 0.4rem; - position: relative; - &:hover { - background-color: var(--dark_850_color); - } - &:active { - background-color: var(--dark_925_color); - } - &.is_selected { - pointer-events: none; - } -} - -.radio_button_input { - appearance: none; - margin: 0; - width: 2rem; - height: 2rem; - border: 0.3rem solid var(--dark_600_color); - border-radius: 50%; - transition: border-color .1s ease, border-width .1s ease; - cursor: inherit; - &:checked { - border-color: var(--primary_400_color); - border-width: 0.6rem; - } -} - -.radio_button_label { - font-size: 1.4rem; - font-weight: 400; -} - -.loader { - @include loader(2rem, 0.2rem, right, -3rem); -} \ No newline at end of file +@import "@scss_mixins"; \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/translation/Translation.jsx b/src-ui/app/config_page/setting_section/setting_box/translation/Translation.jsx index 5cae2c20..f9ec52be 100644 --- a/src-ui/app/config_page/setting_section/setting_box/translation/Translation.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/translation/Translation.jsx @@ -4,13 +4,61 @@ import styles from "./Translation.module.scss"; import { useDeepLAuthKey, + useCTranslate2WeightTypeStatus, + useSelectedCTranslate2WeightType, } from "@logics_configs"; import { + DownloadModelsContainer, DeeplAuthKeyContainer, } from "../_templates/Templates"; export const Translation = () => { + return ( + <> + + + + ); +}; + +const CTranslate2WeightType_Box = () => { + const { t } = useTranslation(); + const { + currentCTranslate2WeightTypeStatus, + pendingCTranslate2WeightType, + downloadCTranslate2Weight, + } = useCTranslate2WeightTypeStatus(); + const { currentSelectedCTranslate2WeightType, setSelectedCTranslate2WeightType } = useSelectedCTranslate2WeightType(); + + const selectFunction = (id) => { + setSelectedCTranslate2WeightType(id); + }; + + const downloadStartFunction = (id) => { + pendingCTranslate2WeightType(id); + downloadCTranslate2Weight(id); + }; + + return ( + <> + + + ); +}; + +const DeeplAuthKey_Box = () => { const [input_value, seInputValue] = useState(""); const { t } = useTranslation(); const { currentDeepLAuthKey, setDeepLAuthKey, deleteDeepLAuthKey } = useDeepLAuthKey(); diff --git a/src-ui/logics/configs/index.js b/src-ui/logics/configs/index.js index 504fcce6..6f646d5e 100644 --- a/src-ui/logics/configs/index.js +++ b/src-ui/logics/configs/index.js @@ -31,7 +31,9 @@ export { useSpeakerRecordTimeout } from "./transcription/useSpeakerRecordTimeout export { useSpeakerPhraseTimeout } from "./transcription/useSpeakerPhraseTimeout"; export { useSpeakerMaxWords } from "./transcription/useSpeakerMaxWords"; +export { useCTranslate2WeightTypeStatus } from "./translation/useCTranslate2WeightTypeStatus"; export { useDeepLAuthKey } from "./translation/useDeepLAuthKey"; +export { useSelectedCTranslate2WeightType } from "./translation/useSelectedCTranslate2WeightType"; export { useIsEnabledOverlaySmallLog } from "./vr/useIsEnabledOverlaySmallLog"; export { useOverlaySettings } from "./vr/useOverlaySettings"; diff --git a/src-ui/logics/configs/translation/useCTranslate2WeightTypeStatus.js b/src-ui/logics/configs/translation/useCTranslate2WeightTypeStatus.js new file mode 100644 index 00000000..4f840765 --- /dev/null +++ b/src-ui/logics/configs/translation/useCTranslate2WeightTypeStatus.js @@ -0,0 +1,60 @@ +import { useStore_CTranslate2WeightTypeStatus } from "@store"; +import { useStdoutToPython } from "@logics/useStdoutToPython"; + +export const useCTranslate2WeightTypeStatus = () => { + const { asyncStdoutToPython } = useStdoutToPython(); + const { currentCTranslate2WeightTypeStatus, updateCTranslate2WeightTypeStatus, pendingCTranslate2WeightTypeStatus } = useStore_CTranslate2WeightTypeStatus(); + + const updateDownloadedCTranslate2WeightTypeStatus = (downloaded_weight_type_status) => { + updateCTranslate2WeightTypeStatus((old_status) => + old_status.data.map((item) => ({ + ...item, + is_downloaded: downloaded_weight_type_status[item.id] ?? item.is_downloaded, + })) + ); + }; + const updateDownloadProgressCTranslate2WeightTypeStatus = (payload) => { + if (payload === true) return console.error("fix me."); + + updateCTranslate2WeightTypeStatus((old_status) => + old_status.data.map((item) => + payload.weight_type === item.id + ? { ...item, progress: payload.progress * 100 } + : item + ) + ); + }; + const pendingCTranslate2WeightType = (id) => { + updateCTranslate2WeightTypeStatus((old_status) => + old_status.data.map((item) => + id === item.id + ? { ...item, is_pending: true } + : item + ) + ); + }; + const downloadedCTranslate2WeightType = (id) => { + updateCTranslate2WeightTypeStatus((old_status) => + old_status.data.map((item) => + id === item.id + ? { ...item, is_downloaded: true, is_pending: false, progress: null } + : item + ) + ); + }; + + const downloadCTranslate2Weight = (weight_type) => { + asyncStdoutToPython("/run/download_ctranslate2_weight", weight_type); + }; + + return { + currentCTranslate2WeightTypeStatus, + updateCTranslate2WeightTypeStatus, + + updateDownloadedCTranslate2WeightTypeStatus, + updateDownloadProgressCTranslate2WeightTypeStatus, + pendingCTranslate2WeightType, + downloadedCTranslate2WeightType, + downloadCTranslate2Weight, + }; +}; \ No newline at end of file diff --git a/src-ui/logics/configs/translation/useSelectedCTranslate2WeightType.js b/src-ui/logics/configs/translation/useSelectedCTranslate2WeightType.js new file mode 100644 index 00000000..8641a2ac --- /dev/null +++ b/src-ui/logics/configs/translation/useSelectedCTranslate2WeightType.js @@ -0,0 +1,24 @@ +import { useStore_SelectedCTranslate2WeightType } from "@store"; +import { useStdoutToPython } from "@logics/useStdoutToPython"; + +export const useSelectedCTranslate2WeightType = () => { + const { asyncStdoutToPython } = useStdoutToPython(); + const { currentSelectedCTranslate2WeightType, updateSelectedCTranslate2WeightType, pendingSelectedCTranslate2WeightType } = useStore_SelectedCTranslate2WeightType(); + + const getSelectedCTranslate2WeightType = () => { + pendingSelectedCTranslate2WeightType(); + asyncStdoutToPython("/get/data/ctranslate2_weight_type"); + }; + + const setSelectedCTranslate2WeightType = (selected_ctranslate2_weight_type) => { + pendingSelectedCTranslate2WeightType(); + asyncStdoutToPython("/set/data/ctranslate2_weight_type", selected_ctranslate2_weight_type); + }; + + return { + currentSelectedCTranslate2WeightType, + getSelectedCTranslate2WeightType, + updateSelectedCTranslate2WeightType, + setSelectedCTranslate2WeightType, + }; +}; \ No newline at end of file diff --git a/src-ui/logics/useReceiveRoutes.js b/src-ui/logics/useReceiveRoutes.js index d8c523d2..95a41b44 100644 --- a/src-ui/logics/useReceiveRoutes.js +++ b/src-ui/logics/useReceiveRoutes.js @@ -46,6 +46,8 @@ import { useSpeakerPhraseTimeout, useSpeakerMaxWords, useDeepLAuthKey, + useCTranslate2WeightTypeStatus, + useSelectedCTranslate2WeightType, useOverlaySettings, useIsEnabledOverlaySmallLog, useOverlaySmallLogSettings, @@ -118,6 +120,12 @@ export const useReceiveRoutes = () => { const { updateSpeakerMaxWords } = useSpeakerMaxWords(); const { updateDeepLAuthKey } = useDeepLAuthKey(); + const { updateSelectedCTranslate2WeightType } = useSelectedCTranslate2WeightType(); + const { + updateDownloadedCTranslate2WeightTypeStatus, + updateDownloadProgressCTranslate2WeightTypeStatus, + downloadedCTranslate2WeightType, + } = useCTranslate2WeightTypeStatus(); const { updateOverlaySettings } = useOverlaySettings(); const { updateOverlaySmallLogSettings } = useOverlaySmallLogSettings(); @@ -278,6 +286,14 @@ export const useReceiveRoutes = () => { "/set/data/deepl_auth_key": updateDeepLAuthKey, "/delete/data/deepl_auth_key": () => updateDeepLAuthKey(""), + "/get/data/ctranslate2_weight_type": updateSelectedCTranslate2WeightType, + "/set/data/ctranslate2_weight_type": updateSelectedCTranslate2WeightType, + + "/get/data/selectable_ctranslate2_weight_type_dict": updateDownloadedCTranslate2WeightTypeStatus, + + "/run/download_ctranslate2_weight": updateDownloadProgressCTranslate2WeightTypeStatus, + "/run/downloaded_ctranslate2_weight": downloadedCTranslate2WeightType, + // Transcription "/get/data/mic_record_timeout": updateMicRecordTimeout, "/set/data/mic_record_timeout": updateMicRecordTimeout, diff --git a/src-ui/store.js b/src-ui/store.js index 919227da..13b6ead4 100644 --- a/src-ui/store.js +++ b/src-ui/store.js @@ -9,6 +9,7 @@ import { } from "@test_data"; import { translator_status, + ctranslate2_weight_type_status, } from "@ui_configs"; export const store = { @@ -185,6 +186,8 @@ export const { atomInstance: Atom_MicWordFilterList, useHook: useStore_MicWordFi // Translation export const { atomInstance: Atom_DeepLAuthKey, useHook: useStore_DeepLAuthKey } = createAtomWithHook(null, "DeepLAuthKey"); +export const { atomInstance: Atom_SelectedCTranslate2WeightType, useHook: useStore_SelectedCTranslate2WeightType } = createAtomWithHook("", "SelectedCTranslate2WeightType"); +export const { atomInstance: Atom_CTranslate2WeightTypeStatus, useHook: useStore_CTranslate2WeightTypeStatus } = createAtomWithHook(ctranslate2_weight_type_status, "CTranslate2WeightTypeStatus"); // Transcription export const { atomInstance: Atom_MicRecordTimeout, useHook: useStore_MicRecordTimeout } = createAtomWithHook(0, "MicRecordTimeout"); diff --git a/src-ui/ui_configs.js b/src-ui/ui_configs.js index 12b0bcb4..1888964b 100644 --- a/src-ui/ui_configs.js +++ b/src-ui/ui_configs.js @@ -12,10 +12,15 @@ export const ui_configs = { mic_threshold_max: 2000, speaker_threshold_min: 0, speaker_threshold_max: 4000, - selectable_ui_languages: { - en: "English", - ja: "日本語", - ko: "한국어", - "zh-Hant": "繁體中文", - } -}; \ No newline at end of file + selectable_ui_languages: [ + {id: "en", label: "English"}, + {id: "ja", label: "日本語"}, + {id: "ko", label: "한국어"}, + {id: "zh-Hant", label: "繁體中文"}, + ] +}; + +export const ctranslate2_weight_type_status = [ + { id: "small", label: "small", is_downloaded: false, progress: null }, + { id: "large", label: "large", is_downloaded: false, progress: null }, +]; \ No newline at end of file