|
|
|
@ -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>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|