From 9c5625ac85106299abeaea8e1edb2353384e6373 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:59:06 +0900 Subject: [PATCH 1/6] [Update] Config Page: Translation Tab: DeeplAuthKey. to be editable when input box is empty. --- .../_components/deepl_auth_key/DeeplAuthKey.jsx | 7 +++++++ .../setting_box/translation/Translation.jsx | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.jsx b/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.jsx index 0a1dea91..00e56333 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.jsx @@ -4,6 +4,7 @@ import clsx from "clsx"; import ExternalLink from "@images/external_link.svg?react"; import { _Entry } from "../_atoms/_entry/_Entry"; import { useState, useRef } from "react"; +import { useEffect } from "react"; export const DeeplAuthKey = (props) => { const { t } = useTranslation(); @@ -22,6 +23,12 @@ export const DeeplAuthKey = (props) => { props.saveFunction(); }; + useEffect(() => { + if (props.variable === "" || props.variable === null) { + seIsEditable(true); + } + }, [props.variable]); + return (
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 e0f02565..7ff8a104 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 @@ -98,9 +98,9 @@ const CTranslation2ComputeDevice_Box = () => { }; const DeeplAuthKey_Box = () => { - const [input_value, seInputValue] = useState(""); const { t } = useTranslation(); const { currentDeepLAuthKey, setDeepLAuthKey, deleteDeepLAuthKey } = useDeepLAuthKey(); + const [input_value, seInputValue] = useState(currentDeepLAuthKey.data); const onChangeFunction = (value) => { seInputValue(value); From c65bb4578c2edeba5c05bf9a61ad3afea3c2fca6 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Sat, 7 Dec 2024 05:28:13 +0900 Subject: [PATCH 2/6] [Update] Config Page: Translation Tab: DeeplAuthKey. Add disable and loading ui when it's pending status. --- .../_components/_atoms/_entry/_Entry.jsx | 6 +++++- .../_components/_atoms/_entry/_Entry.module.scss | 5 +++++ .../_components/deepl_auth_key/DeeplAuthKey.jsx | 16 ++++++++++++++-- .../deepl_auth_key/DeeplAuthKey.module.scss | 12 ++++++++++-- .../threshold_entry/ThresholdEntry.module.scss | 1 + .../setting_box/translation/Translation.jsx | 1 + 6 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.jsx b/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.jsx index dc6f4309..e8bba371 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.jsx @@ -1,3 +1,4 @@ +import clsx from "clsx"; import React, { useRef, forwardRef, useImperativeHandle } from "react"; import styles from "./_Entry.module.scss"; @@ -9,6 +10,9 @@ const _Entry = forwardRef((props, ref) => { inputRef.current.focus(); } })); + const input_class_names = clsx(styles.entry_input_area, { + [styles.is_disabled]: props.is_disabled + }); return (
@@ -18,7 +22,7 @@ const _Entry = forwardRef((props, ref) => { > props.onChange(e)} /> diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.module.scss index dc2ac749..c9744de6 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/_components/_atoms/_entry/_Entry.module.scss @@ -16,4 +16,9 @@ height: 100%; font-size: 1.4rem; resize: none; + color: var(--dark_basic_text_color); + &.is_disabled { + color: var(--dark_500_color); + pointer-events: none; + } } \ No newline at end of file diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.jsx b/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.jsx index 00e56333..42401b7a 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.jsx +++ b/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.jsx @@ -1,6 +1,7 @@ import styles from "./DeeplAuthKey.module.scss"; import { useTranslation } from "react-i18next"; import clsx from "clsx"; +import CircularProgress from "@mui/material/CircularProgress"; import ExternalLink from "@images/external_link.svg?react"; import { _Entry } from "../_atoms/_entry/_Entry"; import { useState, useRef } from "react"; @@ -29,11 +30,22 @@ export const DeeplAuthKey = (props) => { } }, [props.variable]); + const is_disabled = props.state === "pending"; + + const save_button_class_names = clsx(styles.save_button, { + [styles.is_disabled]: is_disabled + }); + return (
- <_Entry ref={entryRef} width="30rem" onChange={onchangeEntryAuthKey} ui_variable={props.variable}/> - + <_Entry ref={entryRef} width="30rem" onChange={onchangeEntryAuthKey} ui_variable={props.variable} is_disabled={is_disabled}/> + {is_editable ? null : diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.module.scss index 6e5a3411..575ec8bc 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/_components/deepl_auth_key/DeeplAuthKey.module.scss @@ -44,17 +44,25 @@ .save_button { padding: 0.8rem 1.2rem; background-color: var(--primary_600_color); - color: var(--dark_basic_text_color); - font-size: 1.4rem; border-radius: 0.4rem; text-align: center; flex-shrink: 0; + min-width: 5.4rem; &:hover { background-color: var(--primary_500_color); } &:active { background-color: var(--primary_700_color); } + &.is_disabled { + pointer-events: none; + background-color: var(--primary_800_color); + } +} + +.save_button_label { + color: var(--dark_basic_text_color); + font-size: 1.4rem; } .open_webpage_button_wrapper { diff --git a/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/threshold_entry/ThresholdEntry.module.scss b/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/threshold_entry/ThresholdEntry.module.scss index d2378d03..929f8975 100644 --- a/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/threshold_entry/ThresholdEntry.module.scss +++ b/src-ui/app/config_page/setting_section/setting_box/_components/threshold_component/threshold_entry/ThresholdEntry.module.scss @@ -1,4 +1,5 @@ .container { + } .entry_wrapper { 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 7ff8a104..724e73b3 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 @@ -124,6 +124,7 @@ const DeeplAuthKey_Box = () => { {translator: t("main_page.translator")} )} variable={input_value} + state={currentDeepLAuthKey.state} onChangeFunction={onChangeFunction} saveFunction={saveFunction} /> From e7b8dac36da56983757dc4c829e97a659f5a65cd Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Sun, 8 Dec 2024 17:02:19 +0900 Subject: [PATCH 3/6] [Update] Config Page: Add notification ui. show error messages. --- src-ui/app/App.jsx | 2 + .../setting_box/translation/Translation.jsx | 2 +- .../SnackbarController.jsx | 41 ++++++++++++++++++ .../SnackbarController.module.scss | 16 +++++++ src-ui/logics/common/index.js | 1 + src-ui/logics/common/useNotificationStatus.js | 42 +++++++++++++++++++ src-ui/logics/useReceiveRoutes.js | 8 ++++ src-ui/store.js | 6 +++ 8 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src-ui/app/snackbar_controller/SnackbarController.jsx create mode 100644 src-ui/app/snackbar_controller/SnackbarController.module.scss create mode 100644 src-ui/logics/common/useNotificationStatus.js diff --git a/src-ui/app/App.jsx b/src-ui/app/App.jsx index 896cbb34..e9d12d08 100644 --- a/src-ui/app/App.jsx +++ b/src-ui/app/App.jsx @@ -8,6 +8,7 @@ import { ConfigPage } from "./config_page/ConfigPage"; import { SplashComponent } from "./splash_component/SplashComponent"; import { UpdatingComponent } from "./updating_component/UpdatingComponent"; import { ModalController } from "./modal_controller/ModalController"; +import { SnackbarController } from "./snackbar_controller/SnackbarController"; import styles from "./App.module.scss"; import { useIsBackendReady, useIsSoftwareUpdating } from "@logics_common"; @@ -45,6 +46,7 @@ const Contents = () => { +
: 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 724e73b3..95ebdb54 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 @@ -170,4 +170,4 @@ const findKeyByDeviceValue = (devices, target_value) => { } } return null; -}; +}; \ No newline at end of file diff --git a/src-ui/app/snackbar_controller/SnackbarController.jsx b/src-ui/app/snackbar_controller/SnackbarController.jsx new file mode 100644 index 00000000..c6433293 --- /dev/null +++ b/src-ui/app/snackbar_controller/SnackbarController.jsx @@ -0,0 +1,41 @@ +import { useState } from "react"; +import Button from "@mui/material/Button"; +import Snackbar from "@mui/material/Snackbar"; +import Slide from "@mui/material/Slide"; + +import styles from "./SnackbarController.module.scss"; +import { useNotificationStatus } from "@logics_common"; +import { clsx } from "clsx"; + +export const SnackbarController = () => { + const { currentNotificationStatus, closeNotification } = useNotificationStatus(); + + const handleClose = (event, reason) => { + closeNotification(event, reason); + }; + + const snackbar_classname = clsx(styles.snackbar_content, { + [styles.is_success]: currentNotificationStatus.data.status === "success", + [styles.is_error]: currentNotificationStatus.data.status === "error", + }); + + return ( +
+ +
+

{currentNotificationStatus.data.message}

+
+
+
+ ); +}; + +const SlideTransition = (props) => { + return ; +}; diff --git a/src-ui/app/snackbar_controller/SnackbarController.module.scss b/src-ui/app/snackbar_controller/SnackbarController.module.scss new file mode 100644 index 00000000..2db44fa9 --- /dev/null +++ b/src-ui/app/snackbar_controller/SnackbarController.module.scss @@ -0,0 +1,16 @@ +.snackbar_content { + width: 100%; + height: 100%; + padding: 2rem; + color: #fff; + &.is_success { + background-color: #368777; + } + &.is_error { + background-color: #bb4448; + } +} + +.snackbar_message { + font-size: 1.4rem; +} \ No newline at end of file diff --git a/src-ui/logics/common/index.js b/src-ui/logics/common/index.js index 8f1cd737..e63b28db 100644 --- a/src-ui/logics/common/index.js +++ b/src-ui/logics/common/index.js @@ -5,6 +5,7 @@ export { useWindow } from "./useWindow"; export { useIsOpenedConfigPage } from "./useIsOpenedConfigPage"; export { useIsSoftwareUpdateAvailable } from "./useIsSoftwareUpdateAvailable"; export { useIsSoftwareUpdating } from "./useIsSoftwareUpdating"; +export { useNotificationStatus } from "./useNotificationStatus"; export { useOpenFolder } from "./useOpenFolder"; export { useMessage } from "./useMessage"; export { useUpdateSoftware } from "./useUpdateSoftware"; diff --git a/src-ui/logics/common/useNotificationStatus.js b/src-ui/logics/common/useNotificationStatus.js new file mode 100644 index 00000000..f36c0c45 --- /dev/null +++ b/src-ui/logics/common/useNotificationStatus.js @@ -0,0 +1,42 @@ +import { useStore_NotificationStatus } from "@store"; + +export const useNotificationStatus = () => { + const { currentNotificationStatus, updateNotificationStatus } = useStore_NotificationStatus(); + + const generateRandomKey = () => Math.random(); + + const showNotification_Error = (message) => { + updateNotificationStatus({ + status: "error", + is_open: true, + key: generateRandomKey(), + message: message, + }); + }; + + const showNotification_Success = (message) => { + updateNotificationStatus({ + status: "success", + is_open: true, + key: generateRandomKey(), + message: message, + }); + }; + + const closeNotification = (event, reason) => { + if (reason === "clickaway") return; + updateNotificationStatus((prev) => ({ + ...prev.data, + is_open: false, + })); + }; + + return { + currentNotificationStatus, + updateNotificationStatus, + + showNotification_Error, + showNotification_Success, + closeNotification, + }; +}; \ No newline at end of file diff --git a/src-ui/logics/useReceiveRoutes.js b/src-ui/logics/useReceiveRoutes.js index 748b5061..0c09da4f 100644 --- a/src-ui/logics/useReceiveRoutes.js +++ b/src-ui/logics/useReceiveRoutes.js @@ -2,6 +2,9 @@ import { translator_status } from "@ui_configs"; import { arrayToObject } from "@utils"; import { + useNotificationStatus, + + useComputeMode, useInitProgress, useIsBackendReady, @@ -167,6 +170,10 @@ export const useReceiveRoutes = () => { const { updateOscIpAddress } = useOscIpAddress(); const { updateOscPort } = useOscPort(); + + + const { showNotification_Success, showNotification_Error } = useNotificationStatus(); + const routes = { // Common "/run/feed_watchdog": () => {}, @@ -494,6 +501,7 @@ export const useReceiveRoutes = () => { const error_route = error_routes[parsed_data.endpoint]; (error_route) ? error_route(parsed_data.result.data) : console.error(`Invalid endpoint: ${parsed_data.endpoint}\nresult: ${JSON.stringify(parsed_data.result)}`); console.error(`status 400: ${JSON.stringify(parsed_data.result)}`); + showNotification_Error(parsed_data.result.message); break; case 348: diff --git a/src-ui/store.js b/src-ui/store.js index cf63e236..878911cc 100644 --- a/src-ui/store.js +++ b/src-ui/store.js @@ -115,6 +115,12 @@ export const { atomInstance: Atom_IsSoftwareUpdateAvailable, useHook: useStore_I export const { atomInstance: Atom_InitProgress, useHook: useStore_InitProgress } = createAtomWithHook(0, "InitProgress"); export const { atomInstance: Atom_IsBreakPoint, useHook: useStore_IsBreakPoint } = createAtomWithHook(false, "IsBreakPoint"); export const { atomInstance: Atom_IsSoftwareUpdating, useHook: useStore_IsSoftwareUpdating } = createAtomWithHook(false, "IsSoftwareUpdating"); +export const { atomInstance: Atom_NotificationStatus, useHook: useStore_NotificationStatus } = createAtomWithHook({ + status: "", + is_open: false, + key: 0, + message: "", +}, "NotificationStatus"); // Main Page // Functions From a2bcbed780c922465a2cbf313005131f07942f0d Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Sun, 8 Dec 2024 17:38:56 +0900 Subject: [PATCH 4/6] [Chore] Change the name of functions. Remove and organize some imports. --- src-ui/app/App.jsx | 12 ++++++------ .../app/snackbar_controller/SnackbarController.jsx | 4 +--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src-ui/app/App.jsx b/src-ui/app/App.jsx index e9d12d08..fd2d8701 100644 --- a/src-ui/app/App.jsx +++ b/src-ui/app/App.jsx @@ -19,9 +19,9 @@ export const App = () => { return (
- + - + @@ -72,7 +72,7 @@ import { useMainFunction, } from "@logics_main"; -const StartPythonFacadeComponent = () => { +const StartPythonController = () => { const { asyncStartPython } = useStartPython(); const hasRunRef = useRef(false); const { asyncFetchFonts } = useAsyncFetchFonts(); @@ -80,7 +80,7 @@ const StartPythonFacadeComponent = () => { useEffect(() => { if (!hasRunRef.current) { asyncStartPython().then(() => { - startFeedingToWatchDog(); + startFeedingToWatchDogController(); asyncFetchFonts(); }).catch((err) => { console.error(err); @@ -104,7 +104,7 @@ const UiLanguageController = () => { import { useStore_MainFunctionsStateMemory } from "@store"; -const ConfigPageCloseTrigger = () => { +const ConfigPageCloseTriggerController = () => { const { currentIsOpenedConfigPage } = useIsOpenedConfigPage(); const { currentMainFunctionsStateMemory, updateMainFunctionsStateMemory} = useStore_MainFunctionsStateMemory(); const { @@ -198,7 +198,7 @@ const TransparencyController = () => { }; import { useStdoutToPython } from "@logics/useStdoutToPython"; -const startFeedingToWatchDog = () => { +const startFeedingToWatchDogController = () => { const { asyncStdoutToPython } = useStdoutToPython(); setInterval(() => { asyncStdoutToPython("/run/feed_watchdog"); diff --git a/src-ui/app/snackbar_controller/SnackbarController.jsx b/src-ui/app/snackbar_controller/SnackbarController.jsx index c6433293..dcc8f54a 100644 --- a/src-ui/app/snackbar_controller/SnackbarController.jsx +++ b/src-ui/app/snackbar_controller/SnackbarController.jsx @@ -1,11 +1,9 @@ -import { useState } from "react"; -import Button from "@mui/material/Button"; +import { clsx } from "clsx"; import Snackbar from "@mui/material/Snackbar"; import Slide from "@mui/material/Slide"; import styles from "./SnackbarController.module.scss"; import { useNotificationStatus } from "@logics_common"; -import { clsx } from "clsx"; export const SnackbarController = () => { const { currentNotificationStatus, closeNotification } = useNotificationStatus(); From b4eacc717580efa05e878dca3fb8f901d42c3fde Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Mon, 9 Dec 2024 09:25:05 +0900 Subject: [PATCH 5/6] [bugfix_2] Main Page: Message Log Input Box Ratio: Fix init apply ratio. (when I did it at the first time, 5ddc77a9ccf2be4a73cf4493eaf461f27d0f9b70, it looks not fixed yet.) --- .../message_container/MessageContainer.jsx | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src-ui/app/main_page/main_section/message_container/MessageContainer.jsx b/src-ui/app/main_page/main_section/message_container/MessageContainer.jsx index cad18079..dbc5c100 100644 --- a/src-ui/app/main_page/main_section/message_container/MessageContainer.jsx +++ b/src-ui/app/main_page/main_section/message_container/MessageContainer.jsx @@ -14,7 +14,7 @@ export const MessageContainer = () => { const { currentUiScaling } = useUiScaling(); const [is_hovered, setIsHovered] = useState(false); const [message_box_height_in_rem, setMessageBoxHeightInRem] = useState(10); - const FONT_SIZE_STANDARD = 10 * currentUiScaling.data / 100; // 10px = 1rem + const FONT_SIZE_STANDARD = 10 * currentUiScaling.data / 100; // 10px = 1rem const { currentIsAppliedInitMessageBoxHeight, updateIsAppliedInitMessageBoxHeight } = useStore_IsAppliedInitMessageBoxHeight(); const container_ref = useRef(null); @@ -23,9 +23,10 @@ export const MessageContainer = () => { const asyncSetMessageBoxHeightInRem = async (data) => { const minimized = await appWindow.isMinimized(); - if (minimized === true) return; // don't save while the window is minimized. + if (minimized) return; // don't save while the window is minimized. setMessageBoxHeightInRem(data); }; + const calculateMessageBoxRatioAndHeight = () => { if (!currentIsAppliedInitMessageBoxHeight.data) { asyncSetMessageInputBoxRatio(currentMessageInputBoxRatio.data); @@ -33,7 +34,7 @@ export const MessageContainer = () => { return; } - if (log_box_ref.current && message_box_wrapper_ref.current) { + if (log_box_ref.current && message_box_wrapper_ref.current && container_ref.current) { const container_height = container_ref.current.offsetHeight; const container_padding_bottom = parseFloat(window.getComputedStyle(container_ref.current).paddingBottom); const total_height = container_height - container_padding_bottom; @@ -43,6 +44,8 @@ export const MessageContainer = () => { asyncSetMessageInputBoxRatio(message_box_ratio); asyncSetMessageBoxHeightInRem(convertRatioToRem(message_box_ratio)); + } else { + console.warn("References not ready for calculation"); } }; @@ -53,24 +56,26 @@ export const MessageContainer = () => { }); useEffect(() => { - // Note: I thought the part "1.4" is message box bottom padding + (message box separator height/2) - // but it should be fixed at 1.4. Idk why, tho. asyncSetMessageBoxHeightInRem((position / FONT_SIZE_STANDARD) - 1.4); }, [position]); - useEffect(() => { asyncSetMessageBoxHeightInRem(convertRatioToRem(currentMessageInputBoxRatio.data)); }, [currentMessageInputBoxRatio.data]); const convertRatioToRem = (ratio) => { + if (!container_ref.current) return 0; const container_height = container_ref.current.offsetHeight; const container_padding_bottom = parseFloat(window.getComputedStyle(container_ref.current).paddingBottom); const total_height = container_height - container_padding_bottom; - if (total_height === 0) return 0; - return ((ratio / 100) * total_height / FONT_SIZE_STANDARD); + return total_height === 0 ? 0 : ((ratio / 100) * total_height / FONT_SIZE_STANDARD); }; + useEffect(() => { + calculateMessageBoxRatioAndHeight(); + updateIsAppliedInitMessageBoxHeight(true); // Ensure this happens after initial calculation + }, []); + useEffect(() => { let resizeTimeout; @@ -86,10 +91,6 @@ export const MessageContainer = () => { }; }, []); - useEffect(() => { - updateIsAppliedInitMessageBoxHeight(true); - }, []); - return (
{ onMouseLeave={() => setIsHovered(false)} > - +
{ ); }; -const Separator = ({ onDragStart, ...props }) => { - return ( -
- -
- ); -}; +const Separator = ({ onDragStart, ...props }) => ( +
+ +
+); From d7243190cb883c2ededbabe5c342c14f84435b62 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Mon, 9 Dec 2024 10:44:34 +0900 Subject: [PATCH 6/6] [Refactor] App.jsx: Distribute controllers to each files. --- src-ui/app/App.jsx | 167 ++---------------- .../ConfigPageCloseTriggerController.jsx | 55 ++++++ .../_app_controllers/FontFamilyController.jsx | 11 ++ .../StartPythonController.jsx | 48 +++++ .../TransparencyController.jsx | 11 ++ .../_app_controllers/UiLanguageController.jsx | 14 ++ .../app/_app_controllers/UiSizeController.jsx | 13 ++ src-ui/app/_app_controllers/index.js | 6 + 8 files changed, 173 insertions(+), 152 deletions(-) create mode 100644 src-ui/app/_app_controllers/ConfigPageCloseTriggerController.jsx create mode 100644 src-ui/app/_app_controllers/FontFamilyController.jsx create mode 100644 src-ui/app/_app_controllers/StartPythonController.jsx create mode 100644 src-ui/app/_app_controllers/TransparencyController.jsx create mode 100644 src-ui/app/_app_controllers/UiLanguageController.jsx create mode 100644 src-ui/app/_app_controllers/UiSizeController.jsx create mode 100644 src-ui/app/_app_controllers/index.js diff --git a/src-ui/app/App.jsx b/src-ui/app/App.jsx index fd2d8701..4374f7a9 100644 --- a/src-ui/app/App.jsx +++ b/src-ui/app/App.jsx @@ -1,7 +1,20 @@ -import { useEffect, useRef } from "react"; import { useTranslation } from "react-i18next"; -import { useStartPython } from "@logics/useStartPython"; +import { + useWindow, +} from "@logics_common"; + +// import React from "react"; + +import { + StartPythonController, + UiLanguageController, + ConfigPageCloseTriggerController, + UiSizeController, + FontFamilyController, + TransparencyController, +} from "./_app_controllers/index.js"; + import { WindowTitleBar } from "./window_title_bar/WindowTitleBar"; import { MainPage } from "./main_page/MainPage"; import { ConfigPage } from "./config_page/ConfigPage"; @@ -53,154 +66,4 @@ const Contents = () => { } ); -}; - -import { - useWindow, - useVolume, - useIsOpenedConfigPage, -} from "@logics_common"; - -import { - useUiLanguage, - useUiScaling, - useSelectedFontFamily, - useTransparency, -} from "@logics_configs"; - -import { - useMainFunction, -} from "@logics_main"; - -const StartPythonController = () => { - const { asyncStartPython } = useStartPython(); - const hasRunRef = useRef(false); - const { asyncFetchFonts } = useAsyncFetchFonts(); - - useEffect(() => { - if (!hasRunRef.current) { - asyncStartPython().then(() => { - startFeedingToWatchDogController(); - asyncFetchFonts(); - }).catch((err) => { - console.error(err); - }); - } - return () => hasRunRef.current = true; - }, []); - - return null; -}; - -const UiLanguageController = () => { - const { currentUiLanguage } = useUiLanguage(); - const { i18n } = useTranslation(); - - useEffect(() => { - i18n.changeLanguage(currentUiLanguage.data); - }, [currentUiLanguage.data]); - return null; -}; - -import { useStore_MainFunctionsStateMemory } from "@store"; - -const ConfigPageCloseTriggerController = () => { - const { currentIsOpenedConfigPage } = useIsOpenedConfigPage(); - const { currentMainFunctionsStateMemory, updateMainFunctionsStateMemory} = useStore_MainFunctionsStateMemory(); - const { - currentTranscriptionSendStatus, - setTranscriptionSend, - currentTranscriptionReceiveStatus, - setTranscriptionReceive, - } = useMainFunction(); - const { - currentMicThresholdCheckStatus, - volumeCheckStop_Mic, - currentSpeakerThresholdCheckStatus, - volumeCheckStop_Speaker, - } = useVolume(); - - - const memorizeLatestMainFunctionsState = () => { - updateMainFunctionsStateMemory({ - transcription_send: currentTranscriptionSendStatus.data, - transcription_receive: currentTranscriptionReceiveStatus.data, - }); - }; - - const restoreMainFunctionState = () => { - if (currentMainFunctionsStateMemory.data.transcription_send === true) setTranscriptionSend(true); - if (currentMainFunctionsStateMemory.data.transcription_receive === true) setTranscriptionReceive(true); - }; - - useEffect(() => { - if (currentIsOpenedConfigPage.data === true) { // When config page is opened. - memorizeLatestMainFunctionsState(); - if (currentTranscriptionSendStatus.data === true) setTranscriptionSend(false); - if (currentTranscriptionReceiveStatus.data === true) setTranscriptionReceive(false); - } else if (currentIsOpenedConfigPage.data === false) { // When config page is closed. - if (currentMicThresholdCheckStatus.data === true) volumeCheckStop_Mic(); - if (currentSpeakerThresholdCheckStatus.data === true) volumeCheckStop_Speaker(); - restoreMainFunctionState(); - } - }, [currentIsOpenedConfigPage.data]); - return null; -}; - -import React from "react"; -const UiSizeController = () => { - const { currentUiScaling } = useUiScaling(); - const font_size = 62.5 * currentUiScaling.data / 100; - - useEffect(() => { - document.documentElement.style.setProperty("font-size", `${font_size}%`); - }, [currentUiScaling.data]); - - return null; -}; - - -const FontFamilyController = () => { - const { currentSelectedFontFamily } = useSelectedFontFamily(); - useEffect(() => { - document.documentElement.style.setProperty("--font_family", currentSelectedFontFamily.data); - }, [currentSelectedFontFamily.data]); - - return null; -}; - -import { useStore_SelectableFontFamilyList } from "@store"; -import { arrayToObject } from "@utils"; - -import { invoke } from "@tauri-apps/api/tauri"; -const useAsyncFetchFonts = () => { - const { updateSelectableFontFamilyList } = useStore_SelectableFontFamilyList(); - const asyncFetchFonts = async () => { - try { - let fonts = await invoke("get_font_list"); - fonts = fonts.sort((a, b) => a.localeCompare(b, undefined, { sensitivity: "base" })); - updateSelectableFontFamilyList(arrayToObject(fonts)); - } catch (error) { - console.error("Error fetching fonts:", error); - } - }; - return { asyncFetchFonts }; -}; - - -const TransparencyController = () => { - const { currentTransparency } = useTransparency(); - useEffect(() => { - document.documentElement.style.setProperty("opacity", `${currentTransparency.data / 100}`); - }, [currentTransparency.data]); - - return null; -}; - -import { useStdoutToPython } from "@logics/useStdoutToPython"; -const startFeedingToWatchDogController = () => { - const { asyncStdoutToPython } = useStdoutToPython(); - setInterval(() => { - asyncStdoutToPython("/run/feed_watchdog"); - }, 20000); // 20000ミリ秒 = 20秒 }; \ No newline at end of file diff --git a/src-ui/app/_app_controllers/ConfigPageCloseTriggerController.jsx b/src-ui/app/_app_controllers/ConfigPageCloseTriggerController.jsx new file mode 100644 index 00000000..7705aecc --- /dev/null +++ b/src-ui/app/_app_controllers/ConfigPageCloseTriggerController.jsx @@ -0,0 +1,55 @@ +import { useEffect } from "react"; + +import { + useVolume, + useIsOpenedConfigPage, +} from "@logics_common"; + +import { + useMainFunction, +} from "@logics_main"; + +import { useStore_MainFunctionsStateMemory } from "@store"; + +export const ConfigPageCloseTriggerController = () => { + const { currentIsOpenedConfigPage } = useIsOpenedConfigPage(); + const { currentMainFunctionsStateMemory, updateMainFunctionsStateMemory} = useStore_MainFunctionsStateMemory(); + const { + currentTranscriptionSendStatus, + setTranscriptionSend, + currentTranscriptionReceiveStatus, + setTranscriptionReceive, + } = useMainFunction(); + const { + currentMicThresholdCheckStatus, + volumeCheckStop_Mic, + currentSpeakerThresholdCheckStatus, + volumeCheckStop_Speaker, + } = useVolume(); + + + const memorizeLatestMainFunctionsState = () => { + updateMainFunctionsStateMemory({ + transcription_send: currentTranscriptionSendStatus.data, + transcription_receive: currentTranscriptionReceiveStatus.data, + }); + }; + + const restoreMainFunctionState = () => { + if (currentMainFunctionsStateMemory.data.transcription_send === true) setTranscriptionSend(true); + if (currentMainFunctionsStateMemory.data.transcription_receive === true) setTranscriptionReceive(true); + }; + + useEffect(() => { + if (currentIsOpenedConfigPage.data === true) { // When config page is opened. + memorizeLatestMainFunctionsState(); + if (currentTranscriptionSendStatus.data === true) setTranscriptionSend(false); + if (currentTranscriptionReceiveStatus.data === true) setTranscriptionReceive(false); + } else if (currentIsOpenedConfigPage.data === false) { // When config page is closed. + if (currentMicThresholdCheckStatus.data === true) volumeCheckStop_Mic(); + if (currentSpeakerThresholdCheckStatus.data === true) volumeCheckStop_Speaker(); + restoreMainFunctionState(); + } + }, [currentIsOpenedConfigPage.data]); + return null; +}; \ No newline at end of file diff --git a/src-ui/app/_app_controllers/FontFamilyController.jsx b/src-ui/app/_app_controllers/FontFamilyController.jsx new file mode 100644 index 00000000..f7110d1d --- /dev/null +++ b/src-ui/app/_app_controllers/FontFamilyController.jsx @@ -0,0 +1,11 @@ +import { useEffect } from "react"; +import { useSelectedFontFamily } from "@logics_configs"; + +export const FontFamilyController = () => { + const { currentSelectedFontFamily } = useSelectedFontFamily(); + useEffect(() => { + document.documentElement.style.setProperty("--font_family", currentSelectedFontFamily.data); + }, [currentSelectedFontFamily.data]); + + return null; +}; diff --git a/src-ui/app/_app_controllers/StartPythonController.jsx b/src-ui/app/_app_controllers/StartPythonController.jsx new file mode 100644 index 00000000..62bf0b28 --- /dev/null +++ b/src-ui/app/_app_controllers/StartPythonController.jsx @@ -0,0 +1,48 @@ +import { invoke } from "@tauri-apps/api/tauri"; +import { useEffect, useRef } from "react"; +import { useStartPython } from "@logics/useStartPython"; +import { useStdoutToPython } from "@logics/useStdoutToPython"; + +import { useStore_SelectableFontFamilyList } from "@store"; +import { arrayToObject } from "@utils"; + +export const StartPythonController = () => { + const { asyncStartPython } = useStartPython(); + const hasRunRef = useRef(false); + const { asyncFetchFonts } = useAsyncFetchFonts(); + + useEffect(() => { + if (!hasRunRef.current) { + asyncStartPython().then(() => { + startFeedingToWatchDogController(); + asyncFetchFonts(); + }).catch((err) => { + console.error(err); + }); + } + return () => hasRunRef.current = true; + }, []); + + return null; +}; + +const useAsyncFetchFonts = () => { + const { updateSelectableFontFamilyList } = useStore_SelectableFontFamilyList(); + const asyncFetchFonts = async () => { + try { + let fonts = await invoke("get_font_list"); + fonts = fonts.sort((a, b) => a.localeCompare(b, undefined, { sensitivity: "base" })); + updateSelectableFontFamilyList(arrayToObject(fonts)); + } catch (error) { + console.error("Error fetching fonts:", error); + } + }; + return { asyncFetchFonts }; +}; + +const startFeedingToWatchDogController = () => { + const { asyncStdoutToPython } = useStdoutToPython(); + setInterval(() => { + asyncStdoutToPython("/run/feed_watchdog"); + }, 20000); // 20000ミリ秒 = 20秒 +}; \ No newline at end of file diff --git a/src-ui/app/_app_controllers/TransparencyController.jsx b/src-ui/app/_app_controllers/TransparencyController.jsx new file mode 100644 index 00000000..46982413 --- /dev/null +++ b/src-ui/app/_app_controllers/TransparencyController.jsx @@ -0,0 +1,11 @@ +import { useEffect } from "react"; +import { useTransparency } from "@logics_configs"; + +export const TransparencyController = () => { + const { currentTransparency } = useTransparency(); + useEffect(() => { + document.documentElement.style.setProperty("opacity", `${currentTransparency.data / 100}`); + }, [currentTransparency.data]); + + return null; +}; \ No newline at end of file diff --git a/src-ui/app/_app_controllers/UiLanguageController.jsx b/src-ui/app/_app_controllers/UiLanguageController.jsx new file mode 100644 index 00000000..5b45c503 --- /dev/null +++ b/src-ui/app/_app_controllers/UiLanguageController.jsx @@ -0,0 +1,14 @@ +import { useEffect } from "react"; + +import { useTranslation } from "react-i18next"; +import { useUiLanguage } from "@logics_configs"; + +export const UiLanguageController = () => { + const { currentUiLanguage } = useUiLanguage(); + const { i18n } = useTranslation(); + + useEffect(() => { + i18n.changeLanguage(currentUiLanguage.data); + }, [currentUiLanguage.data]); + return null; +}; \ No newline at end of file diff --git a/src-ui/app/_app_controllers/UiSizeController.jsx b/src-ui/app/_app_controllers/UiSizeController.jsx new file mode 100644 index 00000000..8b970c0f --- /dev/null +++ b/src-ui/app/_app_controllers/UiSizeController.jsx @@ -0,0 +1,13 @@ +import { useEffect } from "react"; +import { useUiScaling } from "@logics_configs"; + +export const UiSizeController = () => { + const { currentUiScaling } = useUiScaling(); + const font_size = 62.5 * currentUiScaling.data / 100; + + useEffect(() => { + document.documentElement.style.setProperty("font-size", `${font_size}%`); + }, [currentUiScaling.data]); + + return null; +}; \ No newline at end of file diff --git a/src-ui/app/_app_controllers/index.js b/src-ui/app/_app_controllers/index.js new file mode 100644 index 00000000..f91d40ac --- /dev/null +++ b/src-ui/app/_app_controllers/index.js @@ -0,0 +1,6 @@ +export { StartPythonController } from "./StartPythonController"; +export { UiLanguageController } from "./UiLanguageController"; +export { ConfigPageCloseTriggerController } from "./ConfigPageCloseTriggerController"; +export { UiSizeController } from "./UiSizeController"; +export { FontFamilyController } from "./FontFamilyController"; +export { TransparencyController } from "./TransparencyController"; \ No newline at end of file