Merge branch 'ui' into for_webui
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
--primary_400_color: #48a495;
|
--primary_400_color: #48a495;
|
||||||
--primary_450_color: #429c8c;
|
--primary_450_color: #429c8c;
|
||||||
--primary_500_color: #3b9483;
|
--primary_500_color: #3b9483;
|
||||||
|
--primary_550_color: #398E7D;
|
||||||
--primary_600_color: #368777;
|
--primary_600_color: #368777;
|
||||||
--primary_650_color: #347f6f;
|
--primary_650_color: #347f6f;
|
||||||
--primary_700_color: #317767;
|
--primary_700_color: #317767;
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ const UiScalingContainer = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const MessageLogUiScalingContainer = () => {
|
export const MessageLogUiScalingContainer = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { currentMessageLogUiScaling, setMessageLogUiScaling } = useMessageLogUiScaling();
|
const { currentMessageLogUiScaling, setMessageLogUiScaling } = useMessageLogUiScaling();
|
||||||
const [ui_message_log_ui_scaling, setUiMessageLogUiScaling] = useState(currentMessageLogUiScaling.data);
|
const [ui_message_log_ui_scaling, setUiMessageLogUiScaling] = useState(currentMessageLogUiScaling.data);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export { Device } from "./device/Device";
|
export { Device } from "./device/Device";
|
||||||
export { Appearance } from "./appearance/Appearance";
|
export { Appearance, MessageLogUiScalingContainer } from "./appearance/Appearance";
|
||||||
export { Translation } from "./translation/Translation";
|
export { Translation } from "./translation/Translation";
|
||||||
export { Transcription } from "./transcription/Transcription";
|
export { Transcription } from "./transcription/Transcription";
|
||||||
export { Others, VrcMicMuteSyncContainer } from "./others/Others";
|
export { Others, VrcMicMuteSyncContainer } from "./others/Others";
|
||||||
|
|||||||
@@ -3,15 +3,19 @@ import { useRef, useEffect, useState } from "react";
|
|||||||
import styles from "./MessageContainer.module.scss";
|
import styles from "./MessageContainer.module.scss";
|
||||||
import { appWindow } from "@tauri-apps/api/window";
|
import { appWindow } from "@tauri-apps/api/window";
|
||||||
import { LogBox } from "./log_box/LogBox";
|
import { LogBox } from "./log_box/LogBox";
|
||||||
|
import { MessageLogSettingsContainer } from "./message_log_settings_container/MessageLogSettingsContainer";
|
||||||
import { MessageInputBox } from "./message_input_box/MessageInputBox";
|
import { MessageInputBox } from "./message_input_box/MessageInputBox";
|
||||||
import { useMessageInputBoxRatio } from "@logics_main";
|
import { useMessageInputBoxRatio } from "@logics_main";
|
||||||
import { useUiScaling } from "@logics_configs";
|
import { useUiScaling } from "@logics_configs";
|
||||||
|
import { useStore_IsAppliedInitMessageBoxHeight } from "@store";
|
||||||
|
|
||||||
export const MessageContainer = () => {
|
export const MessageContainer = () => {
|
||||||
const { currentMessageInputBoxRatio, asyncSetMessageInputBoxRatio } = useMessageInputBoxRatio();
|
const { currentMessageInputBoxRatio, asyncSetMessageInputBoxRatio } = useMessageInputBoxRatio();
|
||||||
const { currentUiScaling } = useUiScaling();
|
const { currentUiScaling } = useUiScaling();
|
||||||
|
const [is_hovered, setIsHovered] = useState(false);
|
||||||
const [message_box_height_in_rem, setMessageBoxHeightInRem] = useState(10);
|
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);
|
const container_ref = useRef(null);
|
||||||
const log_box_ref = useRef(null);
|
const log_box_ref = useRef(null);
|
||||||
@@ -22,8 +26,13 @@ export const MessageContainer = () => {
|
|||||||
if (minimized === true) return; // don't save while the window is minimized.
|
if (minimized === true) return; // don't save while the window is minimized.
|
||||||
setMessageBoxHeightInRem(data);
|
setMessageBoxHeightInRem(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const calculateMessageBoxRatioAndHeight = () => {
|
const calculateMessageBoxRatioAndHeight = () => {
|
||||||
|
if (!currentIsAppliedInitMessageBoxHeight.data) {
|
||||||
|
asyncSetMessageInputBoxRatio(currentMessageInputBoxRatio.data);
|
||||||
|
asyncSetMessageBoxHeightInRem(convertRatioToRem(currentMessageInputBoxRatio.data));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (log_box_ref.current && message_box_wrapper_ref.current) {
|
if (log_box_ref.current && message_box_wrapper_ref.current) {
|
||||||
const container_height = container_ref.current.offsetHeight;
|
const container_height = container_ref.current.offsetHeight;
|
||||||
const container_padding_bottom = parseFloat(window.getComputedStyle(container_ref.current).paddingBottom);
|
const container_padding_bottom = parseFloat(window.getComputedStyle(container_ref.current).paddingBottom);
|
||||||
@@ -33,9 +42,7 @@ export const MessageContainer = () => {
|
|||||||
const message_box_ratio = (message_box_height / total_height) * 100;
|
const message_box_ratio = (message_box_height / total_height) * 100;
|
||||||
|
|
||||||
asyncSetMessageInputBoxRatio(message_box_ratio);
|
asyncSetMessageInputBoxRatio(message_box_ratio);
|
||||||
|
asyncSetMessageBoxHeightInRem(convertRatioToRem(message_box_ratio));
|
||||||
const height_in_rem = convertRatioToRem(message_box_ratio);
|
|
||||||
asyncSetMessageBoxHeightInRem(height_in_rem);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,28 +71,34 @@ export const MessageContainer = () => {
|
|||||||
return ((ratio / 100) * total_height / FONT_SIZE_STANDARD);
|
return ((ratio / 100) * total_height / FONT_SIZE_STANDARD);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Tauriのwindow resizeイベントをリッスン
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let resizeTimeout;
|
let resizeTimeout;
|
||||||
|
|
||||||
// イベントのリスナーを設定
|
|
||||||
const unlisten = appWindow.onResized(() => {
|
const unlisten = appWindow.onResized(() => {
|
||||||
clearTimeout(resizeTimeout);
|
clearTimeout(resizeTimeout);
|
||||||
resizeTimeout = setTimeout(() => {
|
resizeTimeout = setTimeout(() => {
|
||||||
calculateMessageBoxRatioAndHeight(); // リサイズが終了した後に実行
|
calculateMessageBoxRatioAndHeight();
|
||||||
}, 200); // ドラッグが終了したと見なすまでの遅延(200ms程度)
|
}, 200);
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unlisten.then((dispose) => dispose()); // イベントリスナーを解除
|
unlisten.then((dispose) => dispose());
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
updateIsAppliedInitMessageBoxHeight(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container} ref={container_ref}>
|
<div className={styles.container} ref={container_ref}>
|
||||||
<div ref={log_box_ref} className={styles.log_box_resize_wrapper}>
|
<div className={styles.log_box_resize_wrapper}
|
||||||
|
ref={log_box_ref}
|
||||||
|
onMouseOver={() => setIsHovered(true)}
|
||||||
|
onMouseLeave={() => setIsHovered(false)}
|
||||||
|
>
|
||||||
<LogBox />
|
<LogBox />
|
||||||
|
<MessageLogSettingsContainer to_visible_toggle_bar={is_hovered}/>
|
||||||
</div>
|
</div>
|
||||||
<Separator {...separatorProps} onDragStart={calculateMessageBoxRatioAndHeight} />
|
<Separator {...separatorProps} onDragStart={calculateMessageBoxRatioAndHeight} />
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
.log_box_resize_wrapper {
|
.log_box_resize_wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.separator {
|
.separator {
|
||||||
|
|||||||
@@ -1,9 +1,43 @@
|
|||||||
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import styles from "./MessageContainer.module.scss";
|
import styles from "./MessageContainer.module.scss";
|
||||||
|
import { MessageSubMenuContainer } from "./message_sub_menu_container/MessageSubMenuContainer";
|
||||||
|
import { useMessage } from "@logics_common";
|
||||||
|
import { useIsVisibleResendButton } from "@logics_main";
|
||||||
export const MessageContainer = ({ messages, status, category, created_at }) => {
|
export const MessageContainer = ({ messages, status, category, created_at }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const {
|
||||||
|
sendMessage,
|
||||||
|
updateMessageInputValue,
|
||||||
|
} = useMessage();
|
||||||
|
const { currentIsVisibleResendButton } = useIsVisibleResendButton();
|
||||||
|
const [is_hovered, setIsHovered] = useState(false);
|
||||||
|
const [is_locked, setIsLocked] = useState(false);
|
||||||
|
|
||||||
|
const resendFunction = () => {
|
||||||
|
sendMessage(messages.original);
|
||||||
|
};
|
||||||
|
const editFunction = () => {
|
||||||
|
updateMessageInputValue(messages.original);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleMouseEnter = () => {
|
||||||
|
if (!is_locked) {
|
||||||
|
setIsHovered(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseLeave = () => {
|
||||||
|
setIsHovered(false);
|
||||||
|
setIsLocked(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const lockHoverState = () => {
|
||||||
|
setIsHovered(false);
|
||||||
|
setIsLocked(true);
|
||||||
|
};
|
||||||
|
|
||||||
const is_translated_exist = messages.translated.length >= 1;
|
const is_translated_exist = messages.translated.length >= 1;
|
||||||
const is_pending = status === "pending";
|
const is_pending = status === "pending";
|
||||||
@@ -12,11 +46,17 @@ export const MessageContainer = ({ messages, status, category, created_at }) =>
|
|||||||
|
|
||||||
const message_type_class_name = clsx({
|
const message_type_class_name = clsx({
|
||||||
[styles.sent_message]: is_sent_message,
|
[styles.sent_message]: is_sent_message,
|
||||||
|
[styles.is_shown_resend_button]: currentIsVisibleResendButton.data,
|
||||||
[styles.received_message]: !is_sent_message,
|
[styles.received_message]: !is_sent_message,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={clsx(styles.container, message_type_class_name)}>
|
<div
|
||||||
|
className={clsx(styles.container, message_type_class_name)}
|
||||||
|
onMouseEnter={handleMouseEnter}
|
||||||
|
onMouseLeave={handleMouseLeave}
|
||||||
|
>
|
||||||
|
<div className={clsx(styles.message_wrapper, message_type_class_name)}>
|
||||||
<div className={clsx(styles.info_box, message_type_class_name)}>
|
<div className={clsx(styles.info_box, message_type_class_name)}>
|
||||||
<p className={styles.time}>{created_at}</p>
|
<p className={styles.time}>{created_at}</p>
|
||||||
<p className={clsx(styles.category, message_type_class_name)}>{category_text}</p>
|
<p className={clsx(styles.category, message_type_class_name)}>{category_text}</p>
|
||||||
@@ -29,6 +69,14 @@ export const MessageContainer = ({ messages, status, category, created_at }) =>
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{currentIsVisibleResendButton.data && is_sent_message && is_hovered ? (
|
||||||
|
<MessageSubMenuContainer
|
||||||
|
setIsHovered={lockHoverState}
|
||||||
|
resendFunction={resendFunction}
|
||||||
|
editFunction={editFunction}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,26 @@
|
|||||||
@import "@scss_mixins";
|
@import "@scss_mixins";
|
||||||
|
|
||||||
|
// ******************* *******************
|
||||||
|
// ******************* Express in "em" not "rem" *******************
|
||||||
|
// ******************* *******************
|
||||||
.container {
|
.container {
|
||||||
margin-bottom: 1em;
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
user-select: text;
|
||||||
|
gap: 0.6rem;
|
||||||
|
&.sent_message.is_shown_resend_button:hover {
|
||||||
|
background-color: var(--dark_950_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.message_wrapper {
|
||||||
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
align-items: end;
|
||||||
user-select: text;
|
user-select: text;
|
||||||
|
padding: 0.6em 0;
|
||||||
&.sent_message {
|
&.sent_message {
|
||||||
align-items: end;
|
align-items: end;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import React, { useState, useRef } from "react";
|
||||||
|
import Tooltip, { tooltipClasses } from '@mui/material/Tooltip';
|
||||||
|
import styles from "./MessageSubMenuContainer.module.scss";
|
||||||
|
import SendMessageSvg from "@images/send_message.svg?react";
|
||||||
|
import RefreshSvg from "@images/refresh_2.svg?react";
|
||||||
|
|
||||||
|
export const MessageSubMenuContainer = (props) => {
|
||||||
|
const [is_holding, setIsHolding] = useState(false);
|
||||||
|
const progressRef = useRef(null);
|
||||||
|
const holdTimeout = useRef(null);
|
||||||
|
|
||||||
|
const startHold = () => {
|
||||||
|
setIsHolding(true);
|
||||||
|
if (progressRef.current) {
|
||||||
|
progressRef.current.style.transition = "width 500ms linear";
|
||||||
|
progressRef.current.style.width = "100%";
|
||||||
|
}
|
||||||
|
holdTimeout.current = setTimeout(() => {
|
||||||
|
props.resendFunction();
|
||||||
|
props.setIsHovered(false);
|
||||||
|
}, 500);
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancelHold = () => {
|
||||||
|
setIsHolding(false);
|
||||||
|
if (progressRef.current) {
|
||||||
|
progressRef.current.style.transition = "none";
|
||||||
|
progressRef.current.style.width = "0%";
|
||||||
|
}
|
||||||
|
clearTimeout(holdTimeout.current);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onClickFunction = () => {
|
||||||
|
props.editFunction();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const offset = {
|
||||||
|
popper: {
|
||||||
|
sx: {
|
||||||
|
[`&.${tooltipClasses.popper}[data-popper-placement*="top"] .${tooltipClasses.tooltip}`]: { marginBottom: "0.2em" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
|
<Tooltip
|
||||||
|
title={<Title_p />}
|
||||||
|
placement="top"
|
||||||
|
slotProps={offset}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className={styles.resend_button}
|
||||||
|
onMouseDown={startHold}
|
||||||
|
onMouseUp={cancelHold}
|
||||||
|
onMouseLeave={cancelHold}
|
||||||
|
onClick={onClickFunction}
|
||||||
|
>
|
||||||
|
<SendMessageSvg className={styles.send_message_svg} />
|
||||||
|
<RefreshSvg className={styles.refresh_svg} />
|
||||||
|
<div ref={progressRef} className={styles.hold_progress_bar}></div>
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Title_p = () => {
|
||||||
|
return <p className={styles.tooltip_title}>Press and hold to send</p>;
|
||||||
|
};
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -1,42 +1,83 @@
|
|||||||
import { useState } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import styles from "./MessageInputBox.module.scss";
|
import styles from "./MessageInputBox.module.scss";
|
||||||
import SendMessageSvg from "@images/send_message.svg?react";
|
import SendMessageSvg from "@images/send_message.svg?react";
|
||||||
import { useMessage } from "@logics_common";
|
import { useMessage } from "@logics_common";
|
||||||
|
import { useSendMessageButtonType, useEnableAutoClearMessageInputBox } from "@logics_configs";
|
||||||
import { store } from "@store";
|
import { store } from "@store";
|
||||||
import { scrollToBottom } from "@utils";
|
import { scrollToBottom } from "@utils";
|
||||||
import {
|
|
||||||
useSendMessageButtonType,
|
|
||||||
useEnableAutoClearMessageInputBox,
|
|
||||||
} from "@logics_configs";
|
|
||||||
|
|
||||||
export const MessageInputBox = () => {
|
export const MessageInputBox = () => {
|
||||||
const [inputValue, setInputValue] = useState("");
|
const [message_history, setMessageHistory] = useState([]);
|
||||||
const { sendMessage } = useMessage();
|
const [history_index, setHistoryIndex] = useState(-1);
|
||||||
|
const {
|
||||||
|
sendMessage,
|
||||||
|
currentMessageLogs,
|
||||||
|
currentMessageInputValue,
|
||||||
|
updateMessageInputValue,
|
||||||
|
} = useMessage();
|
||||||
|
|
||||||
const { currentEnableAutoClearMessageInputBox } = useEnableAutoClearMessageInputBox();
|
const { currentEnableAutoClearMessageInputBox } = useEnableAutoClearMessageInputBox();
|
||||||
const { currentSendMessageButtonType } = useSendMessageButtonType();
|
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) => {
|
const onSubmitFunction = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
sendMessage(inputValue);
|
|
||||||
|
|
||||||
if (currentEnableAutoClearMessageInputBox.data) setInputValue("");
|
if (!currentMessageInputValue.data.trim()) return updateMessageInputValue("");
|
||||||
|
|
||||||
|
sendMessage(currentMessageInputValue.data);
|
||||||
|
|
||||||
|
if (currentEnableAutoClearMessageInputBox.data) updateMessageInputValue("");
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
scrollToBottom(store.log_box_ref);
|
scrollToBottom(store.log_box_ref);
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
|
setHistoryIndex(-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onChangeFunction = (e) => {
|
const onChangeFunction = (e) => {
|
||||||
setInputValue(e.currentTarget.value);
|
updateMessageInputValue(e.currentTarget.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onKeyDownFunction = (e) => {
|
const onKeyDownFunction = (e) => {
|
||||||
if (currentSendMessageButtonType.data === "show_and_disable_enter_key") return;
|
if (currentSendMessageButtonType.data === "show_and_disable_enter_key") return;
|
||||||
if (e.keyCode == 13 && e.shiftKey == false) {
|
|
||||||
|
if (e.keyCode === 13 && !e.shiftKey) {
|
||||||
onSubmitFunction(e);
|
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);
|
||||||
|
updateMessageInputValue(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 (
|
return (
|
||||||
@@ -46,17 +87,18 @@ export const MessageInputBox = () => {
|
|||||||
className={styles.message_box_input_area}
|
className={styles.message_box_input_area}
|
||||||
onChange={onChangeFunction}
|
onChange={onChangeFunction}
|
||||||
placeholder="Input Textfield"
|
placeholder="Input Textfield"
|
||||||
value={inputValue}
|
value={currentMessageInputValue.data}
|
||||||
onKeyDown={onKeyDownFunction}
|
onKeyDown={onKeyDownFunction}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{ currentSendMessageButtonType.data !== "hide" && <SendMessageButton onSubmitFunction={onSubmitFunction}/> }
|
{currentSendMessageButtonType.data !== "hide" && (
|
||||||
|
<SendMessageButton onSubmitFunction={onSubmitFunction} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SendMessageButton = ({ onSubmitFunction }) => {
|
||||||
const SendMessageButton = ({onSubmitFunction}) => {
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className={styles.message_send_button}
|
className={styles.message_send_button}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import styles from "./MessageLogSettingsContainer.module.scss";
|
||||||
|
import clsx from "clsx";
|
||||||
|
|
||||||
|
import { useIsVisibleResendButton } from "@logics_main";
|
||||||
|
import { MessageLogUiScalingContainer } from "@setting_box";
|
||||||
|
import { Checkbox } from "@common_components";
|
||||||
|
|
||||||
|
export const MessageLogSettingsContainer = (props) => {
|
||||||
|
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 (
|
||||||
|
<div className={container_class_name}
|
||||||
|
onMouseOver={() => setIsHovered(true)}
|
||||||
|
onMouseLeave={() => {setIsHovered(false); setIsOpened(false);}}
|
||||||
|
onClick={() => setIsOpened(true)}
|
||||||
|
>
|
||||||
|
<MessageLogUiScalingContainer />
|
||||||
|
<div className={styles.others_wrapper}>
|
||||||
|
<div className={styles.resend_checkbox_toggle} onClick={toggleVisibleResendButton}>
|
||||||
|
<p className={styles.resend_checkbox_label}>Show Resend Button</p>
|
||||||
|
<Checkbox
|
||||||
|
id="visible_resend_button"
|
||||||
|
variable={currentIsVisibleResendButton}
|
||||||
|
size="2rem"
|
||||||
|
padding="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -67,8 +67,10 @@ const SoftwareUpdateAvailableButton = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
if (currentIsSoftwareUpdateAvailable.data === false) return null;
|
if (currentIsSoftwareUpdateAvailable.data === false) return null;
|
||||||
|
|
||||||
|
const { updateOpenedQuickSetting } = useStore_OpenedQuickSetting();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button className={styles.software_update_button}>
|
<button className={styles.software_update_button} onClick={()=>updateOpenedQuickSetting("update_software")}>
|
||||||
<RefreshSvg className={styles.refresh_svg}/>
|
<RefreshSvg className={styles.refresh_svg}/>
|
||||||
<p className={styles.software_update_label}>{t("main_page.update_available")}</p>
|
<p className={styles.software_update_label}>{t("main_page.update_available")}</p>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import styles from "./ModalController.module.scss";
|
import styles from "./ModalController.module.scss";
|
||||||
import { useStore_OpenedQuickSetting } from "@store";
|
import { useStore_OpenedQuickSetting } from "@store";
|
||||||
import { Vr, VrcMicMuteSyncContainer } from "@setting_box";
|
import { Vr, VrcMicMuteSyncContainer } from "@setting_box";
|
||||||
|
import { UpdateModal } from "./update_modal/UpdateModal";
|
||||||
export const ModalController = () => {
|
export const ModalController = () => {
|
||||||
const { currentOpenedQuickSetting, updateOpenedQuickSetting } = useStore_OpenedQuickSetting();
|
const { currentOpenedQuickSetting, updateOpenedQuickSetting } = useStore_OpenedQuickSetting();
|
||||||
if (currentOpenedQuickSetting.data === "") return null;
|
if (currentOpenedQuickSetting.data === "") return null;
|
||||||
@@ -22,6 +23,8 @@ const QuickSettingsController = () => {
|
|||||||
return <Vr />;
|
return <Vr />;
|
||||||
case "vrc_mic_mute_sync":
|
case "vrc_mic_mute_sync":
|
||||||
return <VrcMicMuteSyncContainer />;
|
return <VrcMicMuteSyncContainer />;
|
||||||
|
case "update_software":
|
||||||
|
return <UpdateModal />;
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
20
src-ui/app/modal_controller/update_modal/UpdateModal.jsx
Normal file
20
src-ui/app/modal_controller/update_modal/UpdateModal.jsx
Normal file
@@ -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 (
|
||||||
|
<div className={styles.container}>
|
||||||
|
<p className={styles.label}>{t("main_page.confirmation_message.update_software")}</p>
|
||||||
|
<div className={styles.button_wrapper}>
|
||||||
|
<button className={styles.deny_button} onClick={() => updateOpenedQuickSetting("")} >{t("main_page.confirmation_message.deny_update_software")}</button>
|
||||||
|
<button className={styles.accept_button} onClick={() => updateSoftware()}>{t("main_page.confirmation_message.accept_update_software")}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src-ui/assets/refresh_2.svg
Normal file
1
src-ui/assets/refresh_2.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 12l-4.463 4.969-4.537-4.969h3c0-4.97 4.03-9 9-9 2.395 0 4.565.942 6.179 2.468l-2.004 2.231c-1.081-1.05-2.553-1.699-4.175-1.699-3.309 0-6 2.691-6 6h3zm10.463-4.969l-4.463 4.969h3c0 3.309-2.691 6-6 6-1.623 0-3.094-.65-4.175-1.699l-2.004 2.231c1.613 1.526 3.784 2.468 6.179 2.468 4.97 0 9-4.03 9-9h3l-4.537-4.969z"/></svg>
|
||||||
|
After Width: | Height: | Size: 391 B |
49
src-ui/common_components/checkbox/Checkbox.jsx
Normal file
49
src-ui/common_components/checkbox/Checkbox.jsx
Normal file
@@ -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 (
|
||||||
|
<div className={styles.checkbox_container}>
|
||||||
|
<label
|
||||||
|
className={styles.checkbox_wrapper}
|
||||||
|
htmlFor={checkboxId}
|
||||||
|
style={{
|
||||||
|
"--checkbox-size": size,
|
||||||
|
"--checkbox-color": color,
|
||||||
|
"--checkbox-border-width": borderWidth,
|
||||||
|
"--checkbox-padding": padding,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{state === "pending" ? (
|
||||||
|
<span className={styles.loader}></span>
|
||||||
|
) : (
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id={checkboxId}
|
||||||
|
checked={variable.data}
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
onChange={() => {
|
||||||
|
if (toggleFunction) {
|
||||||
|
toggleFunction();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<span className={styles.cbx}>
|
||||||
|
<svg viewBox="0 0 12 12">
|
||||||
|
<polyline points="1 6.29411765 4.5 10 11 1"></polyline>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
60
src-ui/common_components/checkbox/Checkbox.module.scss
Normal file
60
src-ui/common_components/checkbox/Checkbox.module.scss
Normal file
@@ -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);
|
||||||
|
}
|
||||||
1
src-ui/common_components/index.js
Normal file
1
src-ui/common_components/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { Checkbox } from "./checkbox/Checkbox";
|
||||||
@@ -5,4 +5,5 @@ export { useIsOpenedConfigPage } from "./useIsOpenedConfigPage";
|
|||||||
export { useIsSoftwareUpdateAvailable } from "./useIsSoftwareUpdateAvailable";
|
export { useIsSoftwareUpdateAvailable } from "./useIsSoftwareUpdateAvailable";
|
||||||
export { useOpenFolder } from "./useOpenFolder";
|
export { useOpenFolder } from "./useOpenFolder";
|
||||||
export { useMessage } from "./useMessage";
|
export { useMessage } from "./useMessage";
|
||||||
|
export { useUpdateSoftware } from "./useUpdateSoftware";
|
||||||
export { useVolume } from "./useVolume";
|
export { useVolume } from "./useVolume";
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
useStore_MessageLogs,
|
useStore_MessageLogs,
|
||||||
|
useStore_MessageInputValue,
|
||||||
} from "@store";
|
} from "@store";
|
||||||
|
|
||||||
import { useStdoutToPython } from "@logics/useStdoutToPython";
|
import { useStdoutToPython } from "@logics/useStdoutToPython";
|
||||||
|
|
||||||
export const useMessage = () => {
|
export const useMessage = () => {
|
||||||
const { currentMessageLogs, addMessageLogs, updateMessageLogs } = useStore_MessageLogs();
|
const { currentMessageLogs, addMessageLogs, updateMessageLogs } = useStore_MessageLogs();
|
||||||
|
const { currentMessageInputValue, updateMessageInputValue } = useStore_MessageInputValue();
|
||||||
const { asyncStdoutToPython } = useStdoutToPython();
|
const { asyncStdoutToPython } = useStdoutToPython();
|
||||||
|
|
||||||
const sendMessage = (message) => {
|
const sendMessage = (message) => {
|
||||||
@@ -46,6 +48,9 @@ export const useMessage = () => {
|
|||||||
updateSentMessageLogById,
|
updateSentMessageLogById,
|
||||||
addSentMessageLog,
|
addSentMessageLog,
|
||||||
addReceivedMessageLog,
|
addReceivedMessageLog,
|
||||||
|
|
||||||
|
currentMessageInputValue,
|
||||||
|
updateMessageInputValue,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
12
src-ui/logics/common/useUpdateSoftware.js
Normal file
12
src-ui/logics/common/useUpdateSoftware.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { useStdoutToPython } from "@logics/useStdoutToPython";
|
||||||
|
|
||||||
|
export const useUpdateSoftware = () => {
|
||||||
|
const { asyncStdoutToPython } = useStdoutToPython();
|
||||||
|
const updateSoftware = () => {
|
||||||
|
asyncStdoutToPython("/run/update_software");
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
updateSoftware,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
export { useIsVisibleResendButton } from "./useIsVisibleResendButton";
|
||||||
export { useIsMainPageCompactMode } from "./useIsMainPageCompactMode";
|
export { useIsMainPageCompactMode } from "./useIsMainPageCompactMode";
|
||||||
export { useLanguageSettings } from "./useLanguageSettings";
|
export { useLanguageSettings } from "./useLanguageSettings";
|
||||||
export { useMainFunction } from "./useMainFunction";
|
export { useMainFunction } from "./useMainFunction";
|
||||||
|
|||||||
15
src-ui/logics/main/useIsVisibleResendButton.js
Normal file
15
src-ui/logics/main/useIsVisibleResendButton.js
Normal file
@@ -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,
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -17,6 +17,7 @@ export const store = {
|
|||||||
backend_subprocess: null,
|
backend_subprocess: null,
|
||||||
config_page: null,
|
config_page: null,
|
||||||
log_box_ref: null,
|
log_box_ref: null,
|
||||||
|
is_applied_init_message_box_height: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const generatePropertyNames = (base_name) => ({
|
const generatePropertyNames = (base_name) => ({
|
||||||
@@ -120,6 +121,9 @@ 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_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_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");
|
export const { atomInstance: Atom_SelectableLanguageList, useHook: useStore_SelectableLanguageList } = createAtomWithHook([], "SelectableLanguageList");
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export default defineConfig(async () => ({
|
|||||||
"@logics_configs": path.resolve(__dirname, "src-ui/logics/configs"),
|
"@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"),
|
"@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"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user