From 44888b7e0543342a75a760fa37295ac8f8686730 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Tue, 26 Nov 2024 20:17:38 +0900 Subject: [PATCH 1/6] [Update] Main Page: Add feature that message history navigation with Shift + ArrowUp/Down. --- .../message_input_box/MessageInputBox.jsx | 61 +++++++++++++++---- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx b/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx index 007c3a67..f59d0341 100644 --- a/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx +++ b/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx @@ -1,24 +1,32 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import styles from "./MessageInputBox.module.scss"; import SendMessageSvg from "@images/send_message.svg?react"; import { useMessage } from "@logics_common"; +import { useSendMessageButtonType, useEnableAutoClearMessageInputBox } from "@logics_configs"; import { store } from "@store"; import { scrollToBottom } from "@utils"; -import { - useSendMessageButtonType, - useEnableAutoClearMessageInputBox, -} from "@logics_configs"; export const MessageInputBox = () => { - const [inputValue, setInputValue] = useState(""); - const { sendMessage } = useMessage(); + const [input_value, setInputValue] = useState(""); + const [message_history, setMessageHistory] = useState([]); + const [history_index, setHistoryIndex] = useState(-1); + const { sendMessage, currentMessageLogs } = useMessage(); const { currentEnableAutoClearMessageInputBox } = useEnableAutoClearMessageInputBox(); const { currentSendMessageButtonType } = useSendMessageButtonType(); + useEffect(() => { + if (currentMessageLogs.data) { + const sentMessages = currentMessageLogs.data + .filter(log => log.category === "sent") + .map(log => log.messages.original); + setMessageHistory(sentMessages); + } + }, [currentMessageLogs.data]); + const onSubmitFunction = (e) => { e.preventDefault(); - sendMessage(inputValue); + sendMessage(input_value); if (currentEnableAutoClearMessageInputBox.data) setInputValue(""); @@ -26,6 +34,7 @@ export const MessageInputBox = () => { scrollToBottom(store.log_box_ref); }, 10); + setHistoryIndex(-1); }; const onChangeFunction = (e) => { @@ -34,9 +43,34 @@ export const MessageInputBox = () => { const onKeyDownFunction = (e) => { if (currentSendMessageButtonType.data === "show_and_disable_enter_key") return; - if (e.keyCode == 13 && e.shiftKey == false) { + + if (e.keyCode === 13 && !e.shiftKey) { onSubmitFunction(e); } + + if (e.key === "ArrowUp" && e.shiftKey) { + e.preventDefault(); + + if (history_index + 1 < message_history.length) { + const new_index = history_index + 1; + setHistoryIndex(new_index); + setInputValue(message_history[message_history.length - 1 - new_index]); + } + } + + if (e.key === "ArrowDown" && e.shiftKey) { + e.preventDefault(); + + if (history_index > -1) { + const new_index = history_index - 1; + setHistoryIndex(new_index); + setInputValue( + new_index >= 0 + ? message_history[message_history.length - 1 - new_index] + : "" + ); + } + } }; return ( @@ -46,17 +80,18 @@ export const MessageInputBox = () => { className={styles.message_box_input_area} onChange={onChangeFunction} placeholder="Input Textfield" - value={inputValue} + value={input_value} onKeyDown={onKeyDownFunction} /> - { currentSendMessageButtonType.data !== "hide" && } + {currentSendMessageButtonType.data !== "hide" && ( + + )} ); }; - -const SendMessageButton = ({onSubmitFunction}) => { +const SendMessageButton = ({ onSubmitFunction }) => { return ( + + + ); +}; + +const Title_p = () => { + return

Press and hold to send

; +}; diff --git a/src-ui/app/main_page/main_section/message_container/log_box/message_container/message_sub_menu_container/MessageSubMenuContainer.module.scss b/src-ui/app/main_page/main_section/message_container/log_box/message_container/message_sub_menu_container/MessageSubMenuContainer.module.scss new file mode 100644 index 00000000..30b436b1 --- /dev/null +++ b/src-ui/app/main_page/main_section/message_container/log_box/message_container/message_sub_menu_container/MessageSubMenuContainer.module.scss @@ -0,0 +1,45 @@ +// ******************* ******************* +// ******************* Express in "em" not "rem" ******************* +// ******************* ******************* +.container { +} +.resend_button { + background-color: var(--dark_825_color); + position: relative; + height: 100%; + width: 3.8em; +} + +.send_message_svg { + position: absolute; + top: 58%; + left: 50%; + transform: translate(-50%, -50%); + width: 2.2em; + color: var(--dark_400_color); +} +.refresh_svg { + position: absolute; + top: 36%; + left: 42%; + transform: translate(-50%, -50%); + width: 1.8em; + color: var(--sent_400_color); + filter: drop-shadow(0.2em 0.2em 0 var(--dark_825_color)); +} + +.tooltip_title { + font-size: 1.2rem; + color: var(--dark_basic_text_color); +} + +.hold_progress_bar { + position: absolute; + top: 10%; + left: 50%; + transform: translate(-50%, -50%); + width: 0%; + height: 0.4em; + background-color: var(--sent_400_color); + transition: none; +} \ No newline at end of file diff --git a/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx b/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx index 6875b0a3..80c5cc83 100644 --- a/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx +++ b/src-ui/app/main_page/main_section/message_container/message_input_box/MessageInputBox.jsx @@ -7,10 +7,14 @@ import { store } from "@store"; import { scrollToBottom } from "@utils"; export const MessageInputBox = () => { - const [input_value, setInputValue] = useState(""); const [message_history, setMessageHistory] = useState([]); const [history_index, setHistoryIndex] = useState(-1); - const { sendMessage, currentMessageLogs } = useMessage(); + const { + sendMessage, + currentMessageLogs, + currentMessageInputValue, + updateMessageInputValue, + } = useMessage(); const { currentEnableAutoClearMessageInputBox } = useEnableAutoClearMessageInputBox(); const { currentSendMessageButtonType } = useSendMessageButtonType(); @@ -27,11 +31,11 @@ export const MessageInputBox = () => { const onSubmitFunction = (e) => { e.preventDefault(); - if (!input_value.trim()) return setInputValue(""); + if (!currentMessageInputValue.data.trim()) return updateMessageInputValue(""); - sendMessage(input_value); + sendMessage(currentMessageInputValue.data); - if (currentEnableAutoClearMessageInputBox.data) setInputValue(""); + if (currentEnableAutoClearMessageInputBox.data) updateMessageInputValue(""); setTimeout(() => { scrollToBottom(store.log_box_ref); @@ -41,7 +45,7 @@ export const MessageInputBox = () => { }; const onChangeFunction = (e) => { - setInputValue(e.currentTarget.value); + updateMessageInputValue(e.currentTarget.value); }; const onKeyDownFunction = (e) => { @@ -57,7 +61,7 @@ export const MessageInputBox = () => { if (history_index + 1 < message_history.length) { const new_index = history_index + 1; setHistoryIndex(new_index); - setInputValue(message_history[message_history.length - 1 - new_index]); + updateMessageInputValue(message_history[message_history.length - 1 - new_index]); } } @@ -83,7 +87,7 @@ export const MessageInputBox = () => { className={styles.message_box_input_area} onChange={onChangeFunction} placeholder="Input Textfield" - value={input_value} + value={currentMessageInputValue.data} onKeyDown={onKeyDownFunction} /> diff --git a/src-ui/assets/refresh_2.svg b/src-ui/assets/refresh_2.svg new file mode 100644 index 00000000..e6fb5367 --- /dev/null +++ b/src-ui/assets/refresh_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src-ui/logics/common/useMessage.js b/src-ui/logics/common/useMessage.js index 944c40b7..a951da58 100644 --- a/src-ui/logics/common/useMessage.js +++ b/src-ui/logics/common/useMessage.js @@ -1,11 +1,13 @@ import { useStore_MessageLogs, + useStore_MessageInputValue, } from "@store"; import { useStdoutToPython } from "@logics/useStdoutToPython"; export const useMessage = () => { const { currentMessageLogs, addMessageLogs, updateMessageLogs } = useStore_MessageLogs(); + const { currentMessageInputValue, updateMessageInputValue } = useStore_MessageInputValue(); const { asyncStdoutToPython } = useStdoutToPython(); const sendMessage = (message) => { @@ -46,6 +48,9 @@ export const useMessage = () => { updateSentMessageLogById, addSentMessageLog, addReceivedMessageLog, + + currentMessageInputValue, + updateMessageInputValue, }; }; diff --git a/src-ui/store.js b/src-ui/store.js index 4a426d0c..d082b3fb 100644 --- a/src-ui/store.js +++ b/src-ui/store.js @@ -120,6 +120,7 @@ export const { atomInstance: Atom_TranscriptionReceiveStatus, useHook: useStore_ export const { atomInstance: Atom_ForegroundStatus, useHook: useStore_ForegroundStatus } = createAtomWithHook(false, "ForegroundStatus", {is_state_ok: true}); export const { atomInstance: Atom_MessageLogs, useHook: useStore_MessageLogs } = createAtomWithHook(generateTestData(20), "MessageLogs"); +export const { atomInstance: Atom_MessageInputValue, useHook: useStore_MessageInputValue } = createAtomWithHook("", "MessageInputValue"); export const { atomInstance: Atom_SelectableLanguageList, useHook: useStore_SelectableLanguageList } = createAtomWithHook([], "SelectableLanguageList"); From 7df1eb04d0e50f46ef3c3d24f04267149d6fcf02 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Sat, 30 Nov 2024 04:33:38 +0900 Subject: [PATCH 4/6] [Update] Main Page: Message Logs: Add message log settings. and add tot visible resend or not toggle. --- .../setting_box/appearance/Appearance.jsx | 2 +- .../setting_section/setting_box/index.js | 2 +- .../message_container/MessageContainer.jsx | 10 +++- .../MessageContainer.module.scss | 1 + .../message_container/MessageContainer.jsx | 6 +- .../MessageContainer.module.scss | 2 +- .../MessageLogSettingsContainer.jsx | 45 ++++++++++++++ .../MessageLogSettingsContainer.module.scss | 49 +++++++++++++++ .../common_components/checkbox/Checkbox.jsx | 49 +++++++++++++++ .../checkbox/Checkbox.module.scss | 60 +++++++++++++++++++ src-ui/common_components/index.js | 1 + src-ui/logics/main/index.js | 1 + .../logics/main/useIsVisibleResendButton.js | 15 +++++ src-ui/store.js | 1 + vite.config.js | 1 + 15 files changed, 238 insertions(+), 7 deletions(-) create mode 100644 src-ui/app/main_page/main_section/message_container/message_log_settings_container/MessageLogSettingsContainer.jsx create mode 100644 src-ui/app/main_page/main_section/message_container/message_log_settings_container/MessageLogSettingsContainer.module.scss create mode 100644 src-ui/common_components/checkbox/Checkbox.jsx create mode 100644 src-ui/common_components/checkbox/Checkbox.module.scss create mode 100644 src-ui/common_components/index.js create mode 100644 src-ui/logics/main/useIsVisibleResendButton.js 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 0425981b..2755cce9 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 @@ -91,7 +91,7 @@ const UiScalingContainer = () => { }; -const MessageLogUiScalingContainer = () => { +export const MessageLogUiScalingContainer = () => { const { t } = useTranslation(); const { currentMessageLogUiScaling, setMessageLogUiScaling } = useMessageLogUiScaling(); const [ui_message_log_ui_scaling, setUiMessageLogUiScaling] = useState(currentMessageLogUiScaling.data); diff --git a/src-ui/app/config_page/setting_section/setting_box/index.js b/src-ui/app/config_page/setting_section/setting_box/index.js index 5c19a095..10521c96 100644 --- a/src-ui/app/config_page/setting_section/setting_box/index.js +++ b/src-ui/app/config_page/setting_section/setting_box/index.js @@ -1,5 +1,5 @@ export { Device } from "./device/Device"; -export { Appearance } from "./appearance/Appearance"; +export { Appearance, MessageLogUiScalingContainer } from "./appearance/Appearance"; export { Translation } from "./translation/Translation"; export { Transcription } from "./transcription/Transcription"; export { Others, VrcMicMuteSyncContainer } from "./others/Others"; 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 492afc8a..8ff1f14f 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 @@ -3,13 +3,14 @@ import { useRef, useEffect, useState } from "react"; import styles from "./MessageContainer.module.scss"; import { appWindow } from "@tauri-apps/api/window"; import { LogBox } from "./log_box/LogBox"; +import { MessageLogSettingsContainer } from "./message_log_settings_container/MessageLogSettingsContainer"; import { MessageInputBox } from "./message_input_box/MessageInputBox"; import { useMessageInputBoxRatio } from "@logics_main"; import { useUiScaling } from "@logics_configs"; - export const MessageContainer = () => { const { currentMessageInputBoxRatio, asyncSetMessageInputBoxRatio } = useMessageInputBoxRatio(); 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 @@ -84,8 +85,13 @@ export const MessageContainer = () => { return (
-
+
setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + > +
{ const { t } = useTranslation(); const { sendMessage, updateMessageInputValue, } = useMessage(); - + const { currentIsVisibleResendButton } = useIsVisibleResendButton(); const [is_hovered, setIsHovered] = useState(false); const [is_locked, setIsLocked] = useState(false); @@ -45,6 +46,7 @@ export const MessageContainer = ({ messages, status, category, created_at }) => const message_type_class_name = clsx({ [styles.sent_message]: is_sent_message, + [styles.is_shown_resend_button]: currentIsVisibleResendButton.data, [styles.received_message]: !is_sent_message, }); @@ -67,7 +69,7 @@ export const MessageContainer = ({ messages, status, category, created_at }) => }
- {is_sent_message && is_hovered ? ( + {currentIsVisibleResendButton.data && is_sent_message && is_hovered ? ( { + const [is_opened, setIsOpened] = useState(false); + const [is_hovered, setIsHovered] = useState(false); + + const { currentIsVisibleResendButton, toggleIsVisibleResendButton } = useIsVisibleResendButton(); + + const container_class_name = clsx(styles.container, { + [styles.to_visible_toggle_bar]: props.to_visible_toggle_bar, + [styles.is_hovered]: is_hovered, + [styles.is_opened]: is_opened + }); + + const toggleVisibleResendButton = () => { + toggleIsVisibleResendButton(); + }; + + return ( +
setIsHovered(true)} + onMouseLeave={() => {setIsHovered(false); setIsOpened(false);}} + onClick={() => setIsOpened(true)} + > + +
+
+

Show Resend Button

+ +
+
+
+ ); +}; \ No newline at end of file diff --git a/src-ui/app/main_page/main_section/message_container/message_log_settings_container/MessageLogSettingsContainer.module.scss b/src-ui/app/main_page/main_section/message_container/message_log_settings_container/MessageLogSettingsContainer.module.scss new file mode 100644 index 00000000..3d1077a0 --- /dev/null +++ b/src-ui/app/main_page/main_section/message_container/message_log_settings_container/MessageLogSettingsContainer.module.scss @@ -0,0 +1,49 @@ +$container_height: 18rem; +.container { + position: absolute; + top: -#{$container_height}; + left: 0; + height: $container_height; + width: 100%; + background-color: (#555555cc); + backdrop-filter: blur(0.6rem); + transition: top 0.3s ease; + padding: 0.6rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + &.to_visible_toggle_bar { + top: calc(-#{$container_height} + 1rem); + } + &.is_hovered { + top: calc(-#{$container_height} + 2rem); + } + &.is_opened { + top: 0; + } + &:not(.is_opened) { + cursor: pointer; + } +} + +.others_wrapper { + width: 100%; + display: flex; +} + +.resend_checkbox_toggle { + display: flex; + justify-content: center; + align-items: center; + padding: 0.6rem 1.2rem; + gap: 1rem; + cursor: pointer; + &:hover { + background-color: var(--dark_850_color); + } +} + +.resend_checkbox_label { + font-size: 1.4rem; +} diff --git a/src-ui/common_components/checkbox/Checkbox.jsx b/src-ui/common_components/checkbox/Checkbox.jsx new file mode 100644 index 00000000..ac291f65 --- /dev/null +++ b/src-ui/common_components/checkbox/Checkbox.jsx @@ -0,0 +1,49 @@ +import styles from "./Checkbox.module.scss"; + +export const Checkbox = ({ + checkboxId, + variable, + toggleFunction, + state = "idle", + size = "2.8rem", + color = "var(--primary_600_color)", + borderWidth = "0.2rem", + padding = "2rem", +}) => { + + return ( +
+ +
+ ); +}; diff --git a/src-ui/common_components/checkbox/Checkbox.module.scss b/src-ui/common_components/checkbox/Checkbox.module.scss new file mode 100644 index 00000000..4b536841 --- /dev/null +++ b/src-ui/common_components/checkbox/Checkbox.module.scss @@ -0,0 +1,60 @@ +@import "@scss_mixins"; + +.checkbox_container { + height: 100%; + display: flex; + justify-content: end; + align-items: center; +} + +.checkbox_wrapper { + display: inline-block; + cursor: pointer; + padding: var(--checkbox-padding, 2rem); + position: relative; + + &:hover { + & .cbx { + border: var(--checkbox-color, var(--primary_600_color)) solid var(--checkbox-border-width, 0.2rem); + } + } +} + +.checkbox_wrapper .cbx { + display: block; + width: var(--checkbox-size, 2.8rem); + height: var(--checkbox-size, 2.8rem); + border-radius: 0.4rem; + border: var(--dark_700_color) solid var(--checkbox-border-width, 0.2rem); + transition: all 0.15s ease; + padding: calc(var(--checkbox-size, 2.8rem) / 7); +} + +.checkbox_wrapper .cbx svg { + fill: none; + stroke-linecap: round; + stroke-linejoin: round; + stroke: var(--dark_basic_text_color); + stroke-width: calc(var(--checkbox-border-width, 0.2rem) / 2); + stroke-dasharray: 1.7rem; + stroke-dashoffset: 1.7rem; +} + +.checkbox_wrapper input[type="checkbox"] { + display: none; + visibility: hidden; +} + +.checkbox_wrapper input[type="checkbox"]:checked + .cbx { + background-color: var(--checkbox-color, var(--primary_600_color)); + border: none; +} + +.checkbox_wrapper input[type="checkbox"]:checked + .cbx svg { + stroke-dashoffset: 0; + transition: all 0.15s ease; +} + +.loader { + @include loader(2rem, 0.2rem, right, -2rem); +} diff --git a/src-ui/common_components/index.js b/src-ui/common_components/index.js new file mode 100644 index 00000000..244dff53 --- /dev/null +++ b/src-ui/common_components/index.js @@ -0,0 +1 @@ +export { Checkbox } from "./checkbox/Checkbox"; \ No newline at end of file diff --git a/src-ui/logics/main/index.js b/src-ui/logics/main/index.js index a86b3484..9d142003 100644 --- a/src-ui/logics/main/index.js +++ b/src-ui/logics/main/index.js @@ -1,3 +1,4 @@ +export { useIsVisibleResendButton } from "./useIsVisibleResendButton"; export { useIsMainPageCompactMode } from "./useIsMainPageCompactMode"; export { useLanguageSettings } from "./useLanguageSettings"; export { useMainFunction } from "./useMainFunction"; diff --git a/src-ui/logics/main/useIsVisibleResendButton.js b/src-ui/logics/main/useIsVisibleResendButton.js new file mode 100644 index 00000000..c479af0b --- /dev/null +++ b/src-ui/logics/main/useIsVisibleResendButton.js @@ -0,0 +1,15 @@ +import { useStore_IsVisibleResendButton } from "@store"; + +export const useIsVisibleResendButton = () => { + const { currentIsVisibleResendButton, updateIsVisibleResendButton } = useStore_IsVisibleResendButton(); + + const toggleIsVisibleResendButton = () => { + updateIsVisibleResendButton(!currentIsVisibleResendButton.data); + }; + + return { + currentIsVisibleResendButton, + toggleIsVisibleResendButton, + updateIsVisibleResendButton, + }; +}; \ No newline at end of file diff --git a/src-ui/store.js b/src-ui/store.js index d082b3fb..0470dd61 100644 --- a/src-ui/store.js +++ b/src-ui/store.js @@ -121,6 +121,7 @@ export const { atomInstance: Atom_ForegroundStatus, useHook: useStore_Foreground export const { atomInstance: Atom_MessageLogs, useHook: useStore_MessageLogs } = createAtomWithHook(generateTestData(20), "MessageLogs"); export const { atomInstance: Atom_MessageInputValue, useHook: useStore_MessageInputValue } = createAtomWithHook("", "MessageInputValue"); +export const { atomInstance: Atom_IsVisibleResendButton, useHook: useStore_IsVisibleResendButton } = createAtomWithHook(false, "IsVisibleResendButton"); export const { atomInstance: Atom_SelectableLanguageList, useHook: useStore_SelectableLanguageList } = createAtomWithHook([], "SelectableLanguageList"); diff --git a/vite.config.js b/vite.config.js index a2b46140..04151cd9 100644 --- a/vite.config.js +++ b/vite.config.js @@ -46,6 +46,7 @@ export default defineConfig(async () => ({ "@logics_configs": path.resolve(__dirname, "src-ui/logics/configs"), "@setting_box": path.resolve(__dirname, "src-ui/app/config_page/setting_section/setting_box/index.js"), + "@common_components": path.resolve(__dirname, "src-ui/common_components/index.js"), }, }, From 5ddc77a9ccf2be4a73cf4493eaf461f27d0f9b70 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Sat, 30 Nov 2024 19:28:36 +0900 Subject: [PATCH 5/6] [bugfix] Main Page: Message Log Input Box Ratio: Fix init apply ratio. imperfectly, tho. --- .../message_container/MessageContainer.jsx | 43 +++++++++++-------- src-ui/store.js | 2 + 2 files changed, 27 insertions(+), 18 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 8ff1f14f..cad18079 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 @@ -7,12 +7,15 @@ import { MessageLogSettingsContainer } from "./message_log_settings_container/Me import { MessageInputBox } from "./message_input_box/MessageInputBox"; import { useMessageInputBoxRatio } from "@logics_main"; import { useUiScaling } from "@logics_configs"; +import { useStore_IsAppliedInitMessageBoxHeight } from "@store"; + export const MessageContainer = () => { const { currentMessageInputBoxRatio, asyncSetMessageInputBoxRatio } = useMessageInputBoxRatio(); 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 { currentIsAppliedInitMessageBoxHeight, updateIsAppliedInitMessageBoxHeight } = useStore_IsAppliedInitMessageBoxHeight(); const container_ref = useRef(null); const log_box_ref = useRef(null); @@ -23,8 +26,13 @@ export const MessageContainer = () => { if (minimized === true) return; // don't save while the window is minimized. setMessageBoxHeightInRem(data); }; - const calculateMessageBoxRatioAndHeight = () => { + if (!currentIsAppliedInitMessageBoxHeight.data) { + asyncSetMessageInputBoxRatio(currentMessageInputBoxRatio.data); + asyncSetMessageBoxHeightInRem(convertRatioToRem(currentMessageInputBoxRatio.data)); + return; + } + if (log_box_ref.current && message_box_wrapper_ref.current) { const container_height = container_ref.current.offsetHeight; const container_padding_bottom = parseFloat(window.getComputedStyle(container_ref.current).paddingBottom); @@ -34,9 +42,7 @@ export const MessageContainer = () => { const message_box_ratio = (message_box_height / total_height) * 100; asyncSetMessageInputBoxRatio(message_box_ratio); - - const height_in_rem = convertRatioToRem(message_box_ratio); - asyncSetMessageBoxHeightInRem(height_in_rem); + asyncSetMessageBoxHeightInRem(convertRatioToRem(message_box_ratio)); } }; @@ -65,23 +71,24 @@ export const MessageContainer = () => { return ((ratio / 100) * total_height / FONT_SIZE_STANDARD); }; + useEffect(() => { + let resizeTimeout; - // Tauriのwindow resizeイベントをリッスン - useEffect(() => { - let resizeTimeout; + const unlisten = appWindow.onResized(() => { + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(() => { + calculateMessageBoxRatioAndHeight(); + }, 200); + }); - // イベントのリスナーを設定 - const unlisten = appWindow.onResized(() => { - clearTimeout(resizeTimeout); - resizeTimeout = setTimeout(() => { - calculateMessageBoxRatioAndHeight(); // リサイズが終了した後に実行 - }, 200); // ドラッグが終了したと見なすまでの遅延(200ms程度) - }); + return () => { + unlisten.then((dispose) => dispose()); + }; + }, []); - return () => { - unlisten.then((dispose) => dispose()); // イベントリスナーを解除 - }; - }, []); + useEffect(() => { + updateIsAppliedInitMessageBoxHeight(true); + }, []); return (
diff --git a/src-ui/store.js b/src-ui/store.js index 0470dd61..7ddf8418 100644 --- a/src-ui/store.js +++ b/src-ui/store.js @@ -17,6 +17,7 @@ export const store = { backend_subprocess: null, config_page: null, log_box_ref: null, + is_applied_init_message_box_height: false, }; const generatePropertyNames = (base_name) => ({ @@ -122,6 +123,7 @@ export const { atomInstance: Atom_ForegroundStatus, useHook: useStore_Foreground export const { atomInstance: Atom_MessageLogs, useHook: useStore_MessageLogs } = createAtomWithHook(generateTestData(20), "MessageLogs"); export const { atomInstance: Atom_MessageInputValue, useHook: useStore_MessageInputValue } = createAtomWithHook("", "MessageInputValue"); export const { atomInstance: Atom_IsVisibleResendButton, useHook: useStore_IsVisibleResendButton } = createAtomWithHook(false, "IsVisibleResendButton"); +export const { atomInstance: Atom_IsAppliedInitMessageBoxHeight, useHook: useStore_IsAppliedInitMessageBoxHeight } = createAtomWithHook(false, "IsAppliedInitMessageBoxHeight"); export const { atomInstance: Atom_SelectableLanguageList, useHook: useStore_SelectableLanguageList } = createAtomWithHook([], "SelectableLanguageList"); From b88efcdf083c1ceb64b0e42c7f1b775ac2a49c8b Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Sat, 30 Nov 2024 20:41:53 +0900 Subject: [PATCH 6/6] [Update] Add update software UI(modal). --- src-ui/app/_index_css/variables.css | 1 + .../RightSideComponents.jsx | 4 +- .../app/modal_controller/ModalController.jsx | 3 + .../update_modal/UpdateModal.jsx | 20 +++++++ .../update_modal/UpdateModal.module.scss | 55 +++++++++++++++++++ src-ui/logics/common/index.js | 1 + src-ui/logics/common/useUpdateSoftware.js | 12 ++++ 7 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src-ui/app/modal_controller/update_modal/UpdateModal.jsx create mode 100644 src-ui/app/modal_controller/update_modal/UpdateModal.module.scss create mode 100644 src-ui/logics/common/useUpdateSoftware.js diff --git a/src-ui/app/_index_css/variables.css b/src-ui/app/_index_css/variables.css index 7d9f52f9..652f1cd7 100644 --- a/src-ui/app/_index_css/variables.css +++ b/src-ui/app/_index_css/variables.css @@ -8,6 +8,7 @@ --primary_400_color: #48a495; --primary_450_color: #429c8c; --primary_500_color: #3b9483; + --primary_550_color: #398E7D; --primary_600_color: #368777; --primary_650_color: #347f6f; --primary_700_color: #317767; diff --git a/src-ui/app/main_page/main_section/top_bar/right_side_components/RightSideComponents.jsx b/src-ui/app/main_page/main_section/top_bar/right_side_components/RightSideComponents.jsx index e78d3ef6..1024888e 100644 --- a/src-ui/app/main_page/main_section/top_bar/right_side_components/RightSideComponents.jsx +++ b/src-ui/app/main_page/main_section/top_bar/right_side_components/RightSideComponents.jsx @@ -67,8 +67,10 @@ const SoftwareUpdateAvailableButton = () => { const { t } = useTranslation(); if (currentIsSoftwareUpdateAvailable.data === false) return null; + const { updateOpenedQuickSetting } = useStore_OpenedQuickSetting(); + return ( - diff --git a/src-ui/app/modal_controller/ModalController.jsx b/src-ui/app/modal_controller/ModalController.jsx index 762f9fb6..24009a74 100644 --- a/src-ui/app/modal_controller/ModalController.jsx +++ b/src-ui/app/modal_controller/ModalController.jsx @@ -1,6 +1,7 @@ import styles from "./ModalController.module.scss"; import { useStore_OpenedQuickSetting } from "@store"; import { Vr, VrcMicMuteSyncContainer } from "@setting_box"; +import { UpdateModal } from "./update_modal/UpdateModal"; export const ModalController = () => { const { currentOpenedQuickSetting, updateOpenedQuickSetting } = useStore_OpenedQuickSetting(); if (currentOpenedQuickSetting.data === "") return null; @@ -22,6 +23,8 @@ const QuickSettingsController = () => { return ; case "vrc_mic_mute_sync": return ; + case "update_software": + return ; default: return null; } diff --git a/src-ui/app/modal_controller/update_modal/UpdateModal.jsx b/src-ui/app/modal_controller/update_modal/UpdateModal.jsx new file mode 100644 index 00000000..e158a65f --- /dev/null +++ b/src-ui/app/modal_controller/update_modal/UpdateModal.jsx @@ -0,0 +1,20 @@ +import styles from "./UpdateModal.module.scss"; +import { useTranslation } from "react-i18next"; +import { useStore_OpenedQuickSetting } from "@store"; +import { useUpdateSoftware } from "@logics_common"; + +export const UpdateModal = () => { + const { t } = useTranslation(); + const { updateOpenedQuickSetting } = useStore_OpenedQuickSetting(); + const { updateSoftware } = useUpdateSoftware(); + + return ( +
+

{t("main_page.confirmation_message.update_software")}

+
+ + +
+
+ ); +}; \ No newline at end of file diff --git a/src-ui/app/modal_controller/update_modal/UpdateModal.module.scss b/src-ui/app/modal_controller/update_modal/UpdateModal.module.scss new file mode 100644 index 00000000..99d69293 --- /dev/null +++ b/src-ui/app/modal_controller/update_modal/UpdateModal.module.scss @@ -0,0 +1,55 @@ +.container { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 2.4rem; +} + +.label { + font-size: 2rem; + max-width: 48rem; + text-align: center; + color: var(--dark_basic_text_color); +} +.button_wrapper { + display: flex; + width: 100%; + max-width: 48rem; + justify-content: space-between; +} +.deny_button, .accept_button { + font-size: 1.6rem; + padding: 1rem; + min-width: 10rem; + flex: 1; + max-width: 20rem; + text-align: center; + border-radius: 0.4rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + color: var(--dark_basic_text_color); +} + +.accept_button { + background-color: var(--primary_550_color); + &:hover { + background-color: var(--primary_450_color); + } + &:active { + background-color: var(--primary_600_color); + } +} + +.deny_button { + background-color: var(--dark_750_color); + &:hover { + background-color: var(--dark_700_color); + } + &:active { + background-color: var(--dark_800_color); + } +} diff --git a/src-ui/logics/common/index.js b/src-ui/logics/common/index.js index de903104..692b65df 100644 --- a/src-ui/logics/common/index.js +++ b/src-ui/logics/common/index.js @@ -5,4 +5,5 @@ export { useIsOpenedConfigPage } from "./useIsOpenedConfigPage"; export { useIsSoftwareUpdateAvailable } from "./useIsSoftwareUpdateAvailable"; export { useOpenFolder } from "./useOpenFolder"; export { useMessage } from "./useMessage"; +export { useUpdateSoftware } from "./useUpdateSoftware"; export { useVolume } from "./useVolume"; \ No newline at end of file diff --git a/src-ui/logics/common/useUpdateSoftware.js b/src-ui/logics/common/useUpdateSoftware.js new file mode 100644 index 00000000..c033b878 --- /dev/null +++ b/src-ui/logics/common/useUpdateSoftware.js @@ -0,0 +1,12 @@ +import { useStdoutToPython } from "@logics/useStdoutToPython"; + +export const useUpdateSoftware = () => { + const { asyncStdoutToPython } = useStdoutToPython(); + const updateSoftware = () => { + asyncStdoutToPython("/run/update_software"); + }; + + return { + updateSoftware, + }; +}; \ No newline at end of file