feat: close #1762 add hover text for chat input actions

This commit is contained in:
Yidadaa
2023-06-13 02:27:39 +08:00
parent 0d4611052e
commit 88df4a2223
4 changed files with 135 additions and 41 deletions

View File

@@ -279,6 +279,52 @@ function ClearContextDivider() {
);
}
function ChatAction(props: {
text: string;
icon: JSX.Element;
onClick: () => void;
}) {
const iconRef = useRef<HTMLDivElement>(null);
const textRef = useRef<HTMLDivElement>(null);
const [hovering, setHovering] = useState(false);
const [width, setWidth] = useState(20);
const updateWidth = () => {
if (!iconRef.current || !textRef.current) return;
const getWidth = (dom: HTMLDivElement) => dom.getBoundingClientRect().width;
const textWidth = getWidth(textRef.current);
const iconWidth = getWidth(iconRef.current);
setWidth(hovering ? textWidth + iconWidth : iconWidth);
};
useEffect(() => {
updateWidth();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hovering]);
return (
<div
className={`${chatStyle["chat-input-action"]} clickable`}
onMouseEnter={() => setHovering(true)}
onMouseLeave={() => setHovering(false)}
style={{
width,
}}
onClick={() => {
props.onClick();
setTimeout(updateWidth, 1);
}}
>
<div ref={iconRef} className={chatStyle["icon"]}>
{props.icon}
</div>
<div className={chatStyle["text"]} ref={textRef}>
{props.text}
</div>
</div>
);
}
function useScrollToBottom() {
// for auto-scroll
const scrollRef = useRef<HTMLDivElement>(null);
@@ -330,61 +376,60 @@ export function ChatActions(props: {
return (
<div className={chatStyle["chat-input-actions"]}>
{couldStop && (
<div
className={`${chatStyle["chat-input-action"]} clickable`}
<ChatAction
onClick={stopAll}
>
<StopIcon />
</div>
text={Locale.Chat.InputActions.Stop}
icon={<StopIcon />}
/>
)}
{!props.hitBottom && (
<div
className={`${chatStyle["chat-input-action"]} clickable`}
<ChatAction
onClick={props.scrollToBottom}
>
<BottomIcon />
</div>
text={Locale.Chat.InputActions.ToBottom}
icon={<BottomIcon />}
/>
)}
{props.hitBottom && (
<div
className={`${chatStyle["chat-input-action"]} clickable`}
<ChatAction
onClick={props.showPromptModal}
>
<SettingsIcon />
</div>
text={Locale.Chat.InputActions.Settings}
icon={<SettingsIcon />}
/>
)}
<div
className={`${chatStyle["chat-input-action"]} clickable`}
<ChatAction
onClick={nextTheme}
>
{theme === Theme.Auto ? (
<AutoIcon />
) : theme === Theme.Light ? (
<LightIcon />
) : theme === Theme.Dark ? (
<DarkIcon />
) : null}
</div>
text={Locale.Chat.InputActions.Theme[theme]}
icon={
<>
{theme === Theme.Auto ? (
<AutoIcon />
) : theme === Theme.Light ? (
<LightIcon />
) : theme === Theme.Dark ? (
<DarkIcon />
) : null}
</>
}
/>
<div
className={`${chatStyle["chat-input-action"]} clickable`}
<ChatAction
onClick={props.showPromptHints}
>
<PromptIcon />
</div>
text={Locale.Chat.InputActions.Prompt}
icon={<PromptIcon />}
/>
<div
className={`${chatStyle["chat-input-action"]} clickable`}
<ChatAction
onClick={() => {
navigate(Path.Masks);
}}
>
<MaskIcon />
</div>
text={Locale.Chat.InputActions.Masks}
icon={<MaskIcon />}
/>
<div
className={`${chatStyle["chat-input-action"]} clickable`}
<ChatAction
text={Locale.Chat.InputActions.Clear}
icon={<BreakIcon />}
onClick={() => {
chatStore.updateCurrentSession((session) => {
if (session.clearContextIndex === session.messages.length) {
@@ -395,9 +440,7 @@ export function ChatActions(props: {
}
});
}}
>
<BreakIcon />
</div>
/>
</div>
);
}