Merge branch 'ui_refactor' into develop

This commit is contained in:
Sakamoto Shiina
2025-11-13 10:33:16 +09:00
20 changed files with 519 additions and 700 deletions

View File

@@ -0,0 +1,76 @@
import styles from "./_DropdownMenu.module.scss";
import clsx from "clsx";
import ArrowLeftSvg from "@images/arrow_left.svg?react";
import { useStore_IsOpenedDropdownMenu } from "@store";
export const _DropdownMenu = (props) => {
const { updateIsOpenedDropdownMenu, currentIsOpenedDropdownMenu } = useStore_IsOpenedDropdownMenu();
const toggleDropdownMenu = () => {
if (currentIsOpenedDropdownMenu.data === props.dropdown_id) {
updateIsOpenedDropdownMenu("");
} else {
if (props.openListFunction !== undefined) props.openListFunction();
updateIsOpenedDropdownMenu(props.dropdown_id);
}
};
const selectValue = (key) => {
updateIsOpenedDropdownMenu("");
props.selectFunction({
dropdown_id: props.dropdown_id,
selected_id: key,
});
};
const dropdown_content_wrapper_class_name = clsx(styles["dropdown_content_wrapper"], {
[styles.is_opened]: (currentIsOpenedDropdownMenu.data === props.dropdown_id) ? true : false,
[styles.is_disabled]: props.is_disabled,
});
const dropdown_toggle_button_class_name = clsx(styles["dropdown_toggle_button"], {
[styles.is_pending]: (props.state === "pending") ? true : false,
[styles.is_disabled]: props.is_disabled,
});
const arrow_class_names = clsx(styles["arrow_left_svg"], {
[styles.is_opened]: (currentIsOpenedDropdownMenu.data === props.dropdown_id) ? true : false
});
const getSelectedText = () => {
if (props.state !== "ok") return;
if (props.list[props.selected_id] === undefined) return props.selected_id; // [Fix me]
return props.list[props.selected_id];
};
const list = (props.list === undefined) ? {} : props.list;
return (
<div className={styles.container}>
<div className={dropdown_toggle_button_class_name} onClick={toggleDropdownMenu} style={props.style}>
{(props.state === "pending")
? <p className={styles.dropdown_selected_text}>Loading...</p>
: <p className={styles.dropdown_selected_text}>{getSelectedText()}</p>
}
{(props.state === "pending")
? <span className={styles.loader}></span>
: <ArrowLeftSvg className={arrow_class_names} />
}
</div>
<div className={dropdown_content_wrapper_class_name}>
<div className={styles.dropdown_content}>
{(props.state === "ok")
? Object.entries(list).map(([key, value]) => {
return (
<div key={key} className={styles.value_button} onClick={() => selectValue(key)}>
<p className={styles.value_text}>{value}</p>
</div>
);
})
: null
}
</div>
</div>
</div>
);
};

View File

@@ -0,0 +1,97 @@
@import "@scss_mixins";
.container {
position: relative;
}
.dropdown_toggle_button {
position: relative;
background-color: var(--dark_950_color);
min-width: 20rem;
padding: 0.8rem 1.4rem;
cursor: pointer;
border-radius: 0.4rem;
&:hover {
background-color: var(--dark_925_color);
}
&:active {
background-color: var(--dark_975_color);
}
&.is_pending {
pointer-events: none;
}
&.is_disabled {
pointer-events: none;
.dropdown_selected_text, .arrow_left_svg {
color: var(--dark_550_color);
}
}
}
.dropdown_selected_text {
font-size: 1.4rem;
padding-right: 2.8rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dropdown_content_wrapper {
display: none;
position: absolute;
top: 100%; // Position it below the toggle button
right: 0;
min-width: 20rem;
z-index: 1;
&.is_opened {
display: block;
}
&.is_disabled {
pointer-events: none;
.value_text {
color: var(--dark_550_color);
}
}
}
.dropdown_content {
background-color: var(--dark_900_color);
border: 0.1rem solid var(--dark_600_color);
display: flex;
flex-direction: column;
gap: 0.1rem;
white-space: nowrap;
max-height: 20rem;
overflow-y: scroll;
}
.value_button {
background-color: var(--dark_875_color);
padding: 1.2rem;
cursor: pointer;
&:hover {
background-color: var(--dark_800_color);
}
&:active {
background-color: var(--dark_900_color);
}
}
.value_text {
font-size: 1.4rem;
}
.loader {
@include loader(2rem, 0.2rem, right, 0);
}
.arrow_left_svg {
position: absolute;
top: 50%;
right: 0;
transform: translate(-50%, -50%) rotate(-90deg);
width: 1.4rem;
&.is_opened {
transform: translate(-50%, -50%) rotate(90deg);
}
}

View File

@@ -0,0 +1,44 @@
import clsx from "clsx";
import { useState } from "react";
import styles from "./_SwitchBox.module.scss";
export const _SwitchBox = (props) => {
const [is_hovered, setIsHovered] = useState(false);
const [is_mouse_down, setIsMouseDown] = useState(false);
const is_pending = (props.variable.state === "pending");
const getClassNames = (base_class) => clsx(base_class, {
[styles.is_active]: (props.variable.data === true),
[styles.is_pending]: is_pending,
[styles.is_hovered]: is_hovered,
[styles.is_mouse_down]: is_mouse_down,
});
const onMouseEnter = () => setIsHovered(true);
const onMouseLeave = () => setIsHovered(false);
const onMouseDown = () => setIsMouseDown(true);
const onMouseUp = () => setIsMouseDown(false);
const toggleFunction = () => {
props.toggleFunction();
};
return (
<div className={styles.switchbox_container}>
<div className={getClassNames(styles.switchbox_wrapper)}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onMouseDown={onMouseDown}
onMouseUp={onMouseUp}
onClick={toggleFunction}
>
<div className={getClassNames(styles.toggle_control)}>
<span className={getClassNames(styles.control)}></span>
{is_pending && <span className={styles.loader}></span>}
</div>
</div>
</div>
);
};

View File

@@ -0,0 +1,33 @@
@import "@scss_mixins";
.switchbox_container {
display: flex;
justify-content: end;
align-items: center;
height: 2rem;
}
.switchbox_wrapper {
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
padding: 2rem;
height: 100%;
flex-shrink: 0;
&.is_pending {
pointer-events: none;
}
}
.toggle_control {
position: relative;
@include toggle_control_styles;
display: flex;
justify-content: center;
align-items: center;
}
.loader {
@include loader(2rem, 0.2rem, right, -4rem);
}

View File

@@ -1,76 +1,28 @@
import styles from "./DropdownMenu.module.scss";
import clsx from "clsx";
import ArrowLeftSvg from "@images/arrow_left.svg?react";
import { useStore_IsOpenedDropdownMenu } from "@store";
import { _DropdownMenu } from "../_atoms/_dropdown_menu/_DropdownMenu";
export const DropdownMenu = (props) => {
const { updateIsOpenedDropdownMenu, currentIsOpenedDropdownMenu } = useStore_IsOpenedDropdownMenu();
const toggleDropdownMenu = () => {
if (currentIsOpenedDropdownMenu.data === props.dropdown_id) {
updateIsOpenedDropdownMenu("");
} else {
if (props.openListFunction !== undefined) props.openListFunction();
updateIsOpenedDropdownMenu(props.dropdown_id);
}
return (
<div className={styles.each_dropdown_menu_wrapper}>
{props.secondary_label && <p className={styles.secondary_label}>{props.secondary_label}</p>}
<_DropdownMenu {...props} />
</div>
);
};
const selectValue = (key) => {
updateIsOpenedDropdownMenu("");
props.selectFunction({
dropdown_id: props.dropdown_id,
selected_id: key,
});
};
const dropdown_content_wrapper_class_name = clsx(styles["dropdown_content_wrapper"], {
[styles.is_opened]: (currentIsOpenedDropdownMenu.data === props.dropdown_id) ? true : false,
[styles.is_disabled]: props.is_disabled,
});
const dropdown_toggle_button_class_name = clsx(styles["dropdown_toggle_button"], {
[styles.is_pending]: (props.state === "pending") ? true : false,
[styles.is_disabled]: props.is_disabled,
});
const arrow_class_names = clsx(styles["arrow_left_svg"], {
[styles.is_opened]: (currentIsOpenedDropdownMenu.data === props.dropdown_id) ? true : false
});
const getSelectedText = () => {
if (props.state !== "ok") return;
if (props.list[props.selected_id] === undefined) return props.selected_id; // [Fix me]
return props.list[props.selected_id];
};
const list = (props.list === undefined) ? {} : props.list;
export const MultiDropdownMenu = (props) => {
return (
<div className={styles.container}>
<div className={dropdown_toggle_button_class_name} onClick={toggleDropdownMenu} style={props.style}>
{(props.state === "pending")
? <p className={styles.dropdown_selected_text}>Loading...</p>
: <p className={styles.dropdown_selected_text}>{getSelectedText()}</p>
{props.dropdown_settings.map((dropdown_props, index) => {
if (dropdown_props.insert_component) {
const InsertComponent = dropdown_props.insert_component;
return <InsertComponent key={index} {...dropdown_props.insert_component_props} />;
}
{(props.state === "pending")
? <span className={styles.loader}></span>
: <ArrowLeftSvg className={arrow_class_names} />
}
</div>
<div className={dropdown_content_wrapper_class_name}>
<div className={styles.dropdown_content}>
{(props.state === "ok")
? Object.entries(list).map(([key, value]) => {
return (
<div key={key} className={styles.value_button} onClick={() => selectValue(key)}>
<p className={styles.value_text}>{value}</p>
</div>
<DropdownMenu key={dropdown_props.dropdown_id} {...dropdown_props} />
);
})
: null
}
</div>
</div>
)}
</div>
);
};

View File

@@ -1,97 +1,26 @@
@import "@scss_mixins";
.container {
position: relative;
display: flex;
flex-direction: row;
gap: 2.8rem;
}
.dropdown_toggle_button {
position: relative;
background-color: var(--dark_950_color);
min-width: 20rem;
padding: 0.8rem 1.4rem;
cursor: pointer;
border-radius: 0.4rem;
&:hover {
background-color: var(--dark_925_color);
}
&:active {
background-color: var(--dark_975_color);
}
&.is_pending {
pointer-events: none;
}
&.is_disabled {
pointer-events: none;
.dropdown_selected_text, .arrow_left_svg {
color: var(--dark_550_color);
}
}
}
.dropdown_selected_text {
font-size: 1.4rem;
padding-right: 2.8rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dropdown_content_wrapper {
display: none;
position: absolute;
top: 100%; // Position it below the toggle button
right: 0;
min-width: 20rem;
z-index: 1;
&.is_opened {
display: block;
}
&.is_disabled {
pointer-events: none;
.value_text {
color: var(--dark_550_color);
}
}
}
.dropdown_content {
background-color: var(--dark_900_color);
border: 0.1rem solid var(--dark_600_color);
.each_dropdown_menu_wrapper {
display: flex;
flex-direction: column;
gap: 0.1rem;
gap: 0.6rem;
white-space: nowrap;
max-height: 20rem;
overflow-y: scroll;
}
.value_button {
background-color: var(--dark_875_color);
padding: 1.2rem;
cursor: pointer;
&:hover {
background-color: var(--dark_800_color);
}
&:active {
background-color: var(--dark_900_color);
max-width: 24rem;
&.is_disabled {
pointer-events: none;
}
}
.value_text {
.secondary_label {
padding-left: 0.2rem;
padding-right: 0.4rem;
font-size: 1.4rem;
}
.loader {
@include loader(2rem, 0.2rem, right, 0);
}
.arrow_left_svg {
position: absolute;
top: 50%;
right: 0;
transform: translate(-50%, -50%) rotate(-90deg);
width: 1.4rem;
&.is_opened {
transform: translate(-50%, -50%) rotate(90deg);
}
color: var(--dark_500_color);
white-space: nowrap;
}

View File

@@ -1,7 +1,7 @@
export { ActionButton } from "./action_button/ActionButton";
export { ComputeDevice } from "./compute_device/ComputeDevice";
export { DeeplAuthKey, OpenWebpage_DeeplAuthKey } from "./deepl_auth_key/DeeplAuthKey";
export { DropdownMenu } from "./dropdown_menu/DropdownMenu";
export { DropdownMenu, MultiDropdownMenu } from "./dropdown_menu/DropdownMenu";
export { Entry } from "./entry/Entry";
export { EntryWithSaveButton } from "./entry_with_save_button/EntryWithSaveButton";
export { HotkeysEntry } from "./hotkeys_entry/HotkeysEntry";

View File

@@ -1,44 +1,13 @@
import clsx from "clsx";
import { useState } from "react";
import styles from "./SwitchBox.module.scss";
import { _SwitchBox } from "../_atoms/_switch_box/_SwitchBox";
export const SwitchBox = (props) => {
const [is_hovered, setIsHovered] = useState(false);
const [is_mouse_down, setIsMouseDown] = useState(false);
const is_pending = (props.variable.state === "pending");
const getClassNames = (base_class) => clsx(base_class, {
[styles.is_active]: (props.variable.data === true),
[styles.is_pending]: is_pending,
[styles.is_hovered]: is_hovered,
[styles.is_mouse_down]: is_mouse_down,
});
const onMouseEnter = () => setIsHovered(true);
const onMouseLeave = () => setIsHovered(false);
const onMouseDown = () => setIsMouseDown(true);
const onMouseUp = () => setIsMouseDown(false);
const toggleFunction = () => {
props.toggleFunction();
};
return (
<div className={styles.switchbox_container}>
<div className={getClassNames(styles.switchbox_wrapper)}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onMouseDown={onMouseDown}
onMouseUp={onMouseUp}
onClick={toggleFunction}
>
<div className={getClassNames(styles.toggle_control)}>
<span className={getClassNames(styles.control)}></span>
{is_pending && <span className={styles.loader}></span>}
</div>
</div>
<div className={styles.container}>
{props.secondary_label && <p className={styles.secondary_label}>{props.secondary_label}</p>}
<_SwitchBox {...props} />
</div>
);
};

View File

@@ -1,33 +1,17 @@
@import "@scss_mixins";
.switchbox_container {
display: flex;
justify-content: end;
align-items: center;
height: 2rem;
}
.switchbox_wrapper {
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: pointer;
padding: 2rem;
height: 100%;
flex-shrink: 0;
&.is_pending {
pointer-events: none;
}
gap: 1rem;
}
.toggle_control {
position: relative;
@include toggle_control_styles;
display: flex;
justify-content: center;
align-items: center;
}
.loader {
@include loader(2rem, 0.2rem, right, -4rem);
.secondary_label {
padding-left: 0.2rem;
padding-right: 0.4rem;
font-size: 1.4rem;
color: var(--dark_500_color);
white-space: nowrap;
}

View File

@@ -50,7 +50,7 @@ export const WordFilter = () => {
return (
<div className={styles.container}>
{ currentIsOpenedMicWordFilterList.data &&
{ currentIsOpenedMicWordFilterList.data && currentMicWordFilterList.data.length > 0 &&
<div className={styles.list_section_wrapper}>
{
currentMicWordFilterList.data.map((item, index) => {

View File

@@ -4,11 +4,13 @@
align-items: center;
flex-direction: column;
gap: 2rem;
width: 100%;
}
.list_section_wrapper {
display: flex;
justify-content: center;
flex-wrap: wrap;
width: 100%;
gap: 0.6rem;

View File

@@ -5,6 +5,7 @@ import { useStore_IsOpenedDropdownMenu, useStore_IsBreakPoint } from "@store";
import {
LabelComponent,
DropdownMenu,
MultiDropdownMenu,
Slider,
SwitchBox,
Entry,
@@ -22,13 +23,6 @@ import {
} from "../_components";
import { Checkbox } from "@common_components";
const LabeledContainer = ({ children, label, desc, custom_class_name }) => (
<div className={clsx(styles.container, custom_class_name)}>
<LabelComponent label={label} desc={desc} />
{children}
</div>
);
export const useOnMouseLeaveDropdownMenu = () => {
const { updateIsOpenedDropdownMenu } = useStore_IsOpenedDropdownMenu();
@@ -41,27 +35,87 @@ export const useOnMouseLeaveDropdownMenu = () => {
export const DropdownMenuContainer = (props) => {
const { onMouseLeaveFunction } = useOnMouseLeaveDropdownMenu();
return (
<div className={styles.container} onMouseLeave={onMouseLeaveFunction}>
<TemplatesContainerWrapper onMouseLeaveFunction={onMouseLeaveFunction} {...props}>
<LabelComponent label={props.label} desc={props.desc} />
<DropdownMenu {...props} />
</TemplatesContainerWrapper>
);
};
export const MultiDropdownMenuContainer = (props) => {
const { onMouseLeaveFunction } = useOnMouseLeaveDropdownMenu();
return (
<TemplatesContainerWrapper onMouseLeaveFunction={onMouseLeaveFunction} {...props}>
<LabelComponent label={props.label} desc={props.desc} />
<MultiDropdownMenu dropdown_settings={props.dropdown_settings} />
</TemplatesContainerWrapper>
);
};
const TemplatesContainerWrapper = ({
children,
add_break_point = true,
flex_column = false,
remove_border_bottom = false,
onMouseLeaveFunction = null,
}) => {
const { currentIsBreakPoint } = useStore_IsBreakPoint();
const container_class = clsx(styles.container, {
[styles.is_break_point]: add_break_point && currentIsBreakPoint.data,
[styles.flex_column]: flex_column,
[styles.remove_border_bottom]: remove_border_bottom,
});
return (
<div className={container_class} onMouseLeave={onMouseLeaveFunction}>
{children}
</div>
);
};
const CommonContainer = ({ Component, ...props }) => {
const CommonContainer = ({
label_type = "label_component",
add_break_point = true,
flex_column = false,
remove_border_bottom = false,
Component,
...props
}) => {
const { currentIsBreakPoint } = useStore_IsBreakPoint();
const container_class = clsx(styles.container, {
[styles.is_break_point]: props.add_break_point ?? currentIsBreakPoint.data,
});
return (
<LabeledContainer label={props.label} desc={props.desc} custom_class_name={container_class}>
<Component {...props} is_break_point={currentIsBreakPoint.data} />
</LabeledContainer>
);
const container_wrapper_props = {
add_break_point: add_break_point,
flex_column: flex_column,
remove_border_bottom: remove_border_bottom,
};
if (label_type === "label_component") {
return (
<TemplatesContainerWrapper {...container_wrapper_props}>
<LabelComponent label={props.label} desc={props.desc} />
<Component {...props} is_break_point={currentIsBreakPoint.data} />
</TemplatesContainerWrapper>
);
} else if (label_type === "no_label") {
return (
<TemplatesContainerWrapper {...container_wrapper_props}>
<Component {...props} is_break_point={currentIsBreakPoint.data} />
</TemplatesContainerWrapper>
);
} else if (label_type === "label_only") {
return (
<TemplatesContainerWrapper {...container_wrapper_props}>
<LabelComponent label={props.label} desc={props.desc} />
</TemplatesContainerWrapper>
);
}
};
export const SliderContainer = (props) => (
<CommonContainer Component={Slider} {...props} />
);
@@ -90,19 +144,14 @@ export const RadioButtonContainer = (props) => (
);
export const DeeplAuthKeyContainer = (props) => {
const { currentIsBreakPoint } = useStore_IsBreakPoint();
const container_class = clsx(styles.container, {
[styles.is_break_point]: currentIsBreakPoint.data,
});
return (
<div className={container_class}>
<TemplatesContainerWrapper>
<div className={styles.deepl_auth_key_label_section}>
<LabelComponent label={props.label} desc={props.desc} />
<OpenWebpage_DeeplAuthKey />
</div>
<DeeplAuthKey {...props} />
</div>
</TemplatesContainerWrapper>
);
};
@@ -114,19 +163,22 @@ export const ComputeDeviceContainer = (props) => (
<CommonContainer Component={ComputeDevice} {...props} />
);
export const WordFilterContainer = (props) => (
<div className={styles.word_filter_container}>
<div className={styles.word_filter_switch_section}>
<div className={styles.word_filter_label_wrapper}>
<LabelComponent label={props.label} desc={props.desc} />
</div>
<WordFilterListToggleComponent />
</div>
<div className={styles.word_filter_section}>
<WordFilter {...props} />
</div>
</div>
export const WordFilterContainer = (props) => {
return (
<>
<CommonContainer
Component={WordFilterListToggleComponent}
remove_border_bottom={true}
{...props}
/>
<CommonContainer
Component={WordFilter}
label_type="no_label"
{...props}
/>
</>
);
};
export const DownloadModelsContainer = (props) => (
<CommonContainer Component={DownloadModels} {...props} />
@@ -134,13 +186,17 @@ export const DownloadModelsContainer = (props) => (
export const MessageFormatContainer = (props) => {
return (
<div className={clsx(styles.container, styles.flex_column)}>
<div className={styles.label_only_section}>
<LabelComponent label={props.label} desc={props.desc} />
</div>
<div className={styles.message_format_section}>
<MessageFormat {...props}/>
</div>
</div>
<>
<CommonContainer
remove_border_bottom={true}
label_type="label_only"
{...props}
/>
<CommonContainer
Component={MessageFormat}
label_type="no_label"
{...props}
/>
</>
);
};

View File

@@ -8,7 +8,9 @@
&.flex_column {
flex-direction: column;
}
&:not(.remove_border_bottom) {
border-bottom: solid 0.1rem var(--dark_800_color);
}
&.is_break_point {
flex-direction: column;
@@ -17,10 +19,6 @@
}
}
.label_only_section {
width: 100%;
}
.deepl_auth_key_label_section {
max-width: 34rem;
display: flex;
@@ -29,29 +27,3 @@
align-items: center;
gap: 1.4rem;
}
.message_format_section {
width: 100%;
}
.word_filter_container {
display: flex;
width: 100%;
flex-direction: column;
justify-content: space-between;
align-items: center;
gap: 2rem;
padding: 2rem;
}
.word_filter_switch_section {
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
}
.word_filter_label_wrapper {
max-width: 34rem;
}

View File

@@ -9,11 +9,13 @@ import {
import {
useOnMouseLeaveDropdownMenu,
MultiDropdownMenuContainer,
} from "../_templates/Templates";
import {
LabelComponent,
DropdownMenu,
MultiDropdownMenu,
ThresholdComponent,
SwitchBox,
} from "../_components";
@@ -70,53 +72,41 @@ const Mic_Container = () => {
}
};
const { currentIsBreakPoint } = useStore_IsBreakPoint();
const device_container_class = clsx(styles.device_container, {
[styles.is_break_point]: currentIsBreakPoint.data,
});
return (
<div className={styles.mic_container}>
<div className={device_container_class} onMouseLeave={onMouseLeaveFunction}>
<LabelComponent label={t("config_page.device.mic_host_device.label")} />
<div className={styles.device_contents}>
<div className={styles.device_auto_select_wrapper}>
<p className={styles.device_secondary_label}>{t("config_page.device.label_auto_select")}</p>
<SwitchBox
variable={currentEnableAutoMicSelect}
toggleFunction={toggleEnableAutoMicSelect}
<MultiDropdownMenuContainer
label={t("config_page.device.mic_host_device.label")}
remove_border_bottom={true}
dropdown_settings={[
{
insert_component: SwitchBox,
insert_component_props: {
secondary_label: t("config_page.device.label_auto_select"),
variable: currentEnableAutoMicSelect,
toggleFunction: toggleEnableAutoMicSelect,
}
},
{
dropdown_id: "mic_host",
secondary_label: t("config_page.device.label_host"),
selected_id: currentSelectedMicHost.data,
list: currentMicHostList.data,
selectFunction: selectFunction_host,
state: currentSelectedMicHost.state,
style: { maxWidth: "20rem", minWidth: "10rem" },
is_disabled: is_disabled_selector,
},
{
dropdown_id: "mic_device",
secondary_label: t("config_page.device.label_device"),
selected_id: currentSelectedMicDevice.data,
list: currentMicDeviceList.data,
selectFunction: selectFunction_device,
state: currentSelectedMicDevice.state,
is_disabled: is_disabled_selector,
}
]}
/>
</div>
<div className={styles.device_dropdown_wrapper}>
<div className={styles.device_dropdown}>
<p className={styles.device_secondary_label}>{t("config_page.device.label_host")}</p>
<DropdownMenu
dropdown_id="mic_host"
selected_id={currentSelectedMicHost.data}
list={currentMicHostList.data}
selectFunction={selectFunction_host}
state={currentSelectedMicHost.state}
style={{ maxWidth: "20rem", minWidth: "10rem" }}
is_disabled={is_disabled_selector}
/>
</div>
<div className={styles.device_dropdown}>
<p className={styles.device_secondary_label}>{t("config_page.device.label_device")}</p>
<DropdownMenu
dropdown_id="mic_device"
selected_id={currentSelectedMicDevice.data}
list={currentMicDeviceList.data}
selectFunction={selectFunction_device}
state={currentSelectedMicDevice.state}
is_disabled={is_disabled_selector}
/>
</div>
</div>
</div>
</div>
<div className={styles.threshold_container}>
<div className={styles.threshold_switch_section}>
<LabelComponent {...getLabels()} />
@@ -181,19 +171,14 @@ const Speaker_Container = () => {
<div className={device_container_class} onMouseLeave={onMouseLeaveFunction}>
<LabelComponent label={t("config_page.device.speaker_device.label")} />
<div className={styles.device_contents}>
<div className={styles.device_auto_select_wrapper}>
<p className={styles.device_secondary_label}>{t("config_page.device.label_auto_select")}</p>
<SwitchBox
secondary_label={t("config_page.device.label_auto_select")}
variable={currentEnableAutoSpeakerSelect}
toggleFunction={toggleEnableAutoSpeakerSelect}
/>
</div>
<div className={styles.device_dropdown}>
<p className={styles.device_secondary_label}>{t("config_page.device.label_device")}</p>
<DropdownMenu
dropdown_id="speaker_device"
secondary_label={t("config_page.device.label_device")}
label={t("config_page.device.speaker_device.label")}
selected_id={currentSelectedSpeakerDevice.data}
list={currentSpeakerDeviceList.data}
@@ -203,7 +188,6 @@ const Speaker_Container = () => {
/>
</div>
</div>
</div>
<div className={styles.threshold_container}>
<div className={styles.threshold_switch_section}>
<LabelComponent {...getLabels()}/>

View File

@@ -78,28 +78,3 @@
justify-content: center;
align-items: center;
}
.device_dropdown_wrapper {
display: flex;
flex-direction: row;
gap: 2.8rem;
}
.device_dropdown {
display: flex;
flex-direction: column;
gap: 0.6rem;
white-space: nowrap;
max-width: 24rem;
&.is_disabled {
pointer-events: none;
}
}
.device_secondary_label {
padding-left: 0.2rem;
padding-right: 0.4rem;
font-size: 1.4rem;
color: var(--dark_500_color);
white-space: nowrap;
}

View File

@@ -1,5 +1,5 @@
import { SwitchBox } from "../../_components";
import { _DownloadButton } from "../../_components/_atoms/_download_button/_DownloadButton";
import { _SwitchBox } from "../../_components/_atoms/_switch_box/_SwitchBox";
import styles from "./PluginsControlComponent.module.scss";
import { useI18n } from "@useI18n";
@@ -90,7 +90,7 @@ const DownloadedPluginControl = ({
return (
<div className={styles.container}>
<p>{t("config_page.plugins.no_latest_info")}</p>
<SwitchBox variable={option} toggleFunction={togglePlugin} />
<_SwitchBox variable={option} toggleFunction={togglePlugin} />
</div>
);
} else if (plugin_status.is_latest_version_already) {
@@ -98,7 +98,7 @@ const DownloadedPluginControl = ({
<div className={styles.container}>
<p>{latest_version_label}</p>
<p>{t("config_page.plugins.using_latest_version")}</p>
<SwitchBox variable={option} toggleFunction={togglePlugin} />
<_SwitchBox variable={option} toggleFunction={togglePlugin} />
</div>
);
} else if (plugin_status.is_latest_version_available) {
@@ -107,14 +107,14 @@ const DownloadedPluginControl = ({
<p>{latest_version_label}</p>
<p>{t("config_page.plugins.available_latest_version")}</p>
<_DownloadButton option={option} downloadStartFunction={downloadStartFunction} />
<SwitchBox variable={option} toggleFunction={togglePlugin} />
<_SwitchBox variable={option} toggleFunction={togglePlugin} />
</div>
);
} else {
return (
<div className={styles.container}>
<p>{t("config_page.plugins.available_latest_version")}</p>
<SwitchBox variable={option} toggleFunction={togglePlugin} />
<_SwitchBox variable={option} toggleFunction={togglePlugin} />
</div>
);
}

View File

@@ -11,6 +11,7 @@ import {
import {
WordFilterContainer,
DownloadModelsContainer,
MultiDropdownMenuContainer,
RadioButtonContainer,
DropdownMenuContainer,
SliderContainer,
@@ -20,6 +21,7 @@ import {
import {
DropdownMenu,
MultiDropdownMenu,
LabelComponent,
SectionLabelComponent,
} from "../_components";
@@ -281,8 +283,6 @@ const TranscriptionComputeDevice_Box = () => {
currentSelectedTranscriptionComputeType,
setSelectedTranscriptionComputeType,
} = useTranscription();
const { onMouseLeaveFunction } = useOnMouseLeaveDropdownMenu();
const { currentIsBreakPoint } = useStore_IsBreakPoint();
const list_for_ui = transformDeviceArray(currentSelectableTranscriptionComputeDeviceList.data);
@@ -364,50 +364,34 @@ const TranscriptionComputeDevice_Box = () => {
setSelectedTranscriptionComputeType(selected_data.selected_id);
};
const device_container_class = clsx(styles.device_container, {
[styles.is_break_point]: currentIsBreakPoint.data,
});
const is_disabled_selector = currentSelectedTranscriptionComputeDevice.state === "pending" || currentSelectedTranscriptionComputeType.state === "pending";
return (
<div className={styles.mic_container}>
<div className={device_container_class} onMouseLeave={onMouseLeaveFunction}>
<LabelComponent
<MultiDropdownMenuContainer
label={t("config_page.transcription.transcription_compute_device.label")}
desc={t("config_page.common.compute_device.desc")}
dropdown_settings={[
{
secondary_label: t("config_page.common.compute_device.label_device"),
dropdown_id: "transcription_compute_device",
selected_id: target_index,
list: list_for_ui,
selectFunction: selectFunction_ComputeDevice,
state: currentSelectedTranscriptionComputeDevice.state,
style: { maxWidth: "20rem", minWidth: "10rem" },
is_disabled: is_disabled_selector,
},
{
secondary_label: t("config_page.common.compute_device.label_type"),
dropdown_id: "transcription_compute_type",
selected_id: currentSelectedTranscriptionComputeType.data,
list: new_compute_types_labels,
selectFunction: selectFunction_ComputeType,
state: currentSelectedTranscriptionComputeType.state,
is_disabled: is_disabled_selector,
}
]}
/>
<div className={styles.device_contents}>
<div className={styles.device_dropdown_wrapper}>
<div className={styles.device_dropdown}>
<p className={styles.device_secondary_label}>{t("config_page.common.compute_device.label_device")}</p>
<DropdownMenu
dropdown_id="transcription_compute_device"
selected_id={target_index}
list={list_for_ui}
selectFunction={selectFunction_ComputeDevice}
state={currentSelectedTranscriptionComputeDevice.state}
style={{ maxWidth: "20rem", minWidth: "10rem" }}
is_disabled={is_disabled_selector}
/>
</div>
<div className={styles.device_dropdown}>
<p className={styles.device_secondary_label}>{t("config_page.common.compute_device.label_type")}</p>
<DropdownMenu
dropdown_id="transcription_compute_type"
selected_id={currentSelectedTranscriptionComputeType.data}
list={new_compute_types_labels}
selectFunction={selectFunction_ComputeType}
state={currentSelectedTranscriptionComputeType.state}
is_disabled={is_disabled_selector}
/>
</div>
</div>
</div>
</div>
</div>
);
};

View File

@@ -3,119 +3,3 @@
flex-direction: column;
gap: 6.4rem;
}
// [Fix me] Need refactor.
.mic_container {
display: flex;
flex-direction: column;
border-bottom: solid 0.1rem var(--dark_800_color);
padding-bottom: 1rem;
}
.speaker_container {
padding-top: 0rem;
}
.device_container {
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
padding: 2rem;
margin-bottom: 0rem;
&.is_break_point {
flex-direction: column;
gap: 2rem;
align-items: start;
& .device_contents {
display: flex;
width: 100%;
justify-content: space-between;
padding-left: 0rem;
}
}
}
.threshold_container {
padding: 2rem;
}
.threshold_container {
display: flex;
width: 100%;
flex-direction: column;
justify-content: space-between;
align-items: center;
gap: 2rem;
}
.threshold_switch_section {
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
}
.threshold_section {
width: 100%;
}
.device_label {
font-size: 1.8rem;
}
.device_contents {
display: flex;
width: 100%;
justify-content: end;
padding-left: 2rem;
gap: 2rem;
}
.device_auto_select_wrapper {
display: flex;
flex-direction: column;
gap: 1.2rem;
justify-content: center;
align-items: center;
}
.device_dropdown_wrapper {
display: flex;
flex-direction: row;
gap: 2.8rem;
}
.device_dropdown {
display: flex;
flex-direction: column;
gap: 0.6rem;
white-space: nowrap;
max-width: 24rem;
&.is_disabled {
pointer-events: none;
}
}
.device_secondary_label {
padding-left: 0.2rem;
padding-right: 0.4rem;
font-size: 1.4rem;
color: var(--dark_500_color);
white-space: nowrap;
}

View File

@@ -11,12 +11,14 @@ import {
import {
DownloadModelsContainer,
DeeplAuthKeyContainer,
MultiDropdownMenuContainer,
useOnMouseLeaveDropdownMenu,
} from "../_templates/Templates";
import {
DropdownMenu,
MultiDropdownMenu,
LabelComponent,
} from "../_components";
@@ -89,8 +91,6 @@ const TranslationComputeDevice_Box = () => {
currentSelectedTranslationComputeType,
setSelectedTranslationComputeType,
} = useTranslation();
const { onMouseLeaveFunction } = useOnMouseLeaveDropdownMenu();
const { currentIsBreakPoint } = useStore_IsBreakPoint();
const list_for_ui = transformDeviceArray(currentSelectableTranslationComputeDeviceList.data);
@@ -172,50 +172,34 @@ const TranslationComputeDevice_Box = () => {
setSelectedTranslationComputeType(selected_data.selected_id);
};
const device_container_class = clsx(styles.device_container, {
[styles.is_break_point]: currentIsBreakPoint.data,
});
const is_disabled_selector = currentSelectedTranslationComputeDevice.state === "pending" || currentSelectedTranslationComputeType.state === "pending";
return (
<div className={styles.mic_container}>
<div className={device_container_class} onMouseLeave={onMouseLeaveFunction}>
<LabelComponent
<MultiDropdownMenuContainer
label={t("config_page.translation.translation_compute_device.label")}
desc={t("config_page.common.compute_device.desc")}
dropdown_settings={[
{
dropdown_id: "translation_compute_device",
secondary_label: t("config_page.common.compute_device.label_device"),
selected_id: target_index,
list: list_for_ui,
selectFunction: selectFunction_ComputeDevice,
state: currentSelectedTranslationComputeDevice.state,
style: { maxWidth: "20rem", minWidth: "10rem" },
is_disabled: is_disabled_selector,
},
{
dropdown_id: "translation_compute_type",
secondary_label: t("config_page.common.compute_device.label_type"),
selected_id: currentSelectedTranslationComputeType.data,
list: new_compute_types_labels,
selectFunction: selectFunction_ComputeType,
state: currentSelectedTranslationComputeType.state,
is_disabled: is_disabled_selector,
}
]}
/>
<div className={styles.device_contents}>
<div className={styles.device_dropdown_wrapper}>
<div className={styles.device_dropdown}>
<p className={styles.device_secondary_label}>{t("config_page.common.compute_device.label_device")}</p>
<DropdownMenu
dropdown_id="translation_compute_device"
selected_id={target_index}
list={list_for_ui}
selectFunction={selectFunction_ComputeDevice}
state={currentSelectedTranslationComputeDevice.state}
style={{ maxWidth: "20rem", minWidth: "10rem" }}
is_disabled={is_disabled_selector}
/>
</div>
<div className={styles.device_dropdown}>
<p className={styles.device_secondary_label}>{t("config_page.common.compute_device.label_type")}</p>
<DropdownMenu
dropdown_id="translation_compute_type"
selected_id={currentSelectedTranslationComputeType.data}
list={new_compute_types_labels}
selectFunction={selectFunction_ComputeType}
state={currentSelectedTranslationComputeType.state}
is_disabled={is_disabled_selector}
/>
</div>
</div>
</div>
</div>
</div>
);
};

View File

@@ -1,106 +0,0 @@
// [Fix me] Need refactor.
.mic_container {
display: flex;
flex-direction: column;
border-bottom: solid 0.1rem var(--dark_800_color);
padding-bottom: 1rem;
}
.speaker_container {
padding-top: 0rem;
}
.device_container {
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
padding: 2rem;
margin-bottom: 0rem;
&.is_break_point {
flex-direction: column;
gap: 2rem;
align-items: start;
& .device_contents {
display: flex;
width: 100%;
justify-content: space-between;
padding-left: 0rem;
}
}
}
.threshold_container {
padding: 2rem;
}
.threshold_container {
display: flex;
width: 100%;
flex-direction: column;
justify-content: space-between;
align-items: center;
gap: 2rem;
}
.threshold_switch_section {
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
}
.threshold_section {
width: 100%;
}
.device_label {
font-size: 1.8rem;
}
.device_contents {
display: flex;
width: 100%;
justify-content: end;
padding-left: 2rem;
gap: 2rem;
}
.device_auto_select_wrapper {
display: flex;
flex-direction: column;
gap: 1.2rem;
justify-content: center;
align-items: center;
}
.device_dropdown_wrapper {
display: flex;
flex-direction: row;
gap: 2.8rem;
}
.device_dropdown {
display: flex;
flex-direction: column;
gap: 0.6rem;
white-space: nowrap;
max-width: 24rem;
&.is_disabled {
pointer-events: none;
}
}
.device_secondary_label {
padding-left: 0.2rem;
padding-right: 0.4rem;
font-size: 1.4rem;
color: var(--dark_500_color);
white-space: nowrap;
}