feat(chat): expand empty input actions
This commit is contained in:
@@ -23,11 +23,13 @@
|
||||
import { useRef, useState } from "react";
|
||||
|
||||
import { useChatDispatch } from "@/stores/chat/chat-context";
|
||||
import { useUserState } from "@/stores/user/user-context";
|
||||
import { Logger } from "@/utils";
|
||||
|
||||
import { ChatInputActionPanel } from "./chat-input-action-panel";
|
||||
import { ChatInputTextField } from "./chat-input-text-field";
|
||||
import { ChatSendButton } from "./chat-send-button";
|
||||
import styles from "./chat-input-bar.module.css";
|
||||
import { Logger } from "@/utils";
|
||||
|
||||
const log = new Logger("AppChatComponentsChatInputBar");
|
||||
|
||||
@@ -37,11 +39,22 @@ export interface ChatInputBarProps {
|
||||
|
||||
export function ChatInputBar({ disabled = false }: ChatInputBarProps) {
|
||||
const dispatch = useChatDispatch();
|
||||
const { currentUser } = useUserState();
|
||||
const [input, setInput] = useState("");
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
const [isActionPanelOpen, setIsActionPanelOpen] = useState(false);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
const hasContent = input.trim().length > 0;
|
||||
const isActive = isFocused || isActionPanelOpen;
|
||||
const voiceMinutesRemaining = currentUser?.voiceMinutesRemaining ?? 0;
|
||||
|
||||
const handleInputChange = (value: string) => {
|
||||
setInput(value);
|
||||
if (value.trim().length > 0) {
|
||||
setIsActionPanelOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSend = () => {
|
||||
if (!hasContent) return;
|
||||
@@ -57,23 +70,55 @@ export function ChatInputBar({ disabled = false }: ChatInputBarProps) {
|
||||
textareaRef.current?.focus();
|
||||
};
|
||||
|
||||
const handleActionButtonClick = () => {
|
||||
if (hasContent) {
|
||||
handleSend();
|
||||
return;
|
||||
}
|
||||
|
||||
textareaRef.current?.blur();
|
||||
setIsFocused(false);
|
||||
setIsActionPanelOpen((open) => !open);
|
||||
};
|
||||
|
||||
const handleVoiceMessageClick = () => {
|
||||
log.debug("[chat-input-bar] voice message action clicked", {
|
||||
voiceMinutesRemaining,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`${styles.bar} ${isFocused ? styles.barFocused : ""}`}>
|
||||
<div className={`${styles.row} ${isFocused ? styles.rowFocused : ""}`}>
|
||||
<div
|
||||
className={`${styles.bar} ${isActive ? styles.barFocused : ""} ${
|
||||
isActionPanelOpen ? styles.barExpanded : ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={`${styles.row} ${isActive ? styles.rowFocused : ""} ${
|
||||
isActionPanelOpen ? styles.rowExpanded : ""
|
||||
}`}
|
||||
>
|
||||
<ChatInputTextField
|
||||
ref={textareaRef}
|
||||
value={input}
|
||||
onChange={setInput}
|
||||
onChange={handleInputChange}
|
||||
onSubmit={handleSend}
|
||||
onFocusChange={setIsFocused}
|
||||
disabled={disabled}
|
||||
/>
|
||||
<ChatSendButton
|
||||
disabled={!hasContent || disabled}
|
||||
disabled={disabled}
|
||||
hasContent={hasContent}
|
||||
onClick={handleSend}
|
||||
isExpanded={isActionPanelOpen}
|
||||
onClick={handleActionButtonClick}
|
||||
/>
|
||||
</div>
|
||||
{isActionPanelOpen ? (
|
||||
<ChatInputActionPanel
|
||||
voiceMinutesRemaining={voiceMinutesRemaining}
|
||||
onVoiceMessageClick={handleVoiceMessageClick}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user