Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions apps/web/src/app/components/ChatPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ function ChatPanel({
}: ChatPanelProps) {
const messagesEndRef = useRef<HTMLDivElement>(null);
const scrollContainerRef = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLTextAreaElement>(null);
const shouldAutoScrollRef = useRef(true);
const sendAnimationTimeoutRef = useRef<number | null>(null);
const prevMessageIdsRef = useRef<Set<string>>(new Set());
Expand Down Expand Up @@ -211,6 +212,16 @@ function ChatPanel({
setActiveMentionIndex(0);
}, [chatInput]);

useEffect(() => {
const input = inputRef.current;
if (!input) return;

input.style.height = "auto";
input.style.height = `${input.scrollHeight}px`;
input.style.overflowY =
input.scrollHeight > input.clientHeight ? "auto" : "hidden";
}, [chatInput]);

useEffect(() => {
const previousCount = previousMessageCountRef.current;
const addedMessages = messages.length - previousCount;
Expand Down Expand Up @@ -312,7 +323,7 @@ function ChatPanel({
);
return;
}
if (e.key === "Tab" || e.key === "Enter") {
if (e.key === "Tab" || (e.key === "Enter" && !e.shiftKey)) {
e.preventDefault();
applyMentionSuggestion(activeMentionIndex);
return;
Expand All @@ -334,12 +345,17 @@ function ChatPanel({
);
return;
}
if (isPickingCommand && (e.key === "Tab" || e.key === "Enter")) {
if (
isPickingCommand &&
(e.key === "Tab" || (e.key === "Enter" && !e.shiftKey))
) {
const command = commandSuggestions[activeCommandIndex];
const isExactMatch =
command &&
chatInput.trim().toLowerCase() === `/${command.label}`;
if (e.key === "Enter" && isExactMatch) {
e.preventDefault();
handleSubmit(e);
return;
}
e.preventDefault();
Expand Down Expand Up @@ -514,7 +530,7 @@ function ChatPanel({
{directMessageLabel}
</p>
) : null}
<p className="text-xs break-words leading-relaxed">
<p className="text-xs break-words whitespace-pre-wrap leading-relaxed">
{renderMessageContent(msg.content)}
</p>
</div>
Expand Down Expand Up @@ -604,9 +620,10 @@ function ChatPanel({
})}
</div>
)}
<div className="flex gap-1.5">
<input
type="text"
<div className="flex items-end gap-1.5">
<textarea
ref={inputRef}
rows={1}
value={chatInput}
onChange={(e) => onInputChange(e.target.value)}
onKeyDown={handleKeyDown}
Expand All @@ -619,7 +636,7 @@ function ChatPanel({
}
maxLength={1000}
disabled={isChatDisabled}
className="flex-1 px-2.5 py-1.5 bg-black/30 border border-[#FEFCD9]/10 rounded-md text-xs text-[#FEFCD9] placeholder:text-[#FEFCD9]/30 focus:outline-none focus:border-[#FEFCD9]/20 disabled:opacity-50"
className="max-h-24 min-h-8 flex-1 resize-none px-2.5 py-1.5 bg-black/30 border border-[#FEFCD9]/10 rounded-md text-xs text-[#FEFCD9] placeholder:text-[#FEFCD9]/30 focus:outline-none focus:border-[#FEFCD9]/20 disabled:opacity-50"
Comment thread
greptile-apps[bot] marked this conversation as resolved.
/>
<button
type="submit"
Expand Down
38 changes: 29 additions & 9 deletions apps/web/src/app/components/mobile/MobileChatPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function MobileChatPanel({
mentionableParticipants = [],
}: MobileChatPanelProps) {
const messagesEndRef = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
const inputRef = useRef<HTMLTextAreaElement>(null);
const [activeCommandIndex, setActiveCommandIndex] = useState(0);
const [activeMentionIndex, setActiveMentionIndex] = useState(0);
const [localValue, setLocalValue] = useState(chatInput);
Expand Down Expand Up @@ -127,6 +127,16 @@ function MobileChatPanel({
}
}, [chatInput, localValue]);

useEffect(() => {
const input = inputRef.current;
if (!input) return;

input.style.height = "auto";
input.style.height = `${input.scrollHeight}px`;
input.style.overflowY =
input.scrollHeight > input.clientHeight ? "auto" : "hidden";
}, [localValue]);

useEffect(() => {
setActiveCommandIndex(0);
setActiveMentionIndex(0);
Expand Down Expand Up @@ -156,7 +166,7 @@ function MobileChatPanel({
onInputChange(nextValue);
};

const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (showMentionSuggestions) {
if (e.key === "ArrowDown") {
e.preventDefault();
Expand All @@ -170,7 +180,7 @@ function MobileChatPanel({
);
return;
}
if (e.key === "Tab" || e.key === "Enter") {
if (e.key === "Tab" || (e.key === "Enter" && !e.shiftKey)) {
e.preventDefault();
applyMentionSuggestion(activeMentionIndex);
return;
Expand All @@ -192,12 +202,17 @@ function MobileChatPanel({
);
return;
}
if (isPickingCommand && (e.key === "Tab" || e.key === "Enter")) {
if (
isPickingCommand &&
(e.key === "Tab" || (e.key === "Enter" && !e.shiftKey))
) {
const command = commandSuggestions[activeCommandIndex];
const isExactMatch =
command &&
localValue.trim().toLowerCase() === `/${command.label}`;
if (e.key === "Enter" && isExactMatch) {
e.preventDefault();
handleSubmit(e);
return;
}
e.preventDefault();
Expand All @@ -208,6 +223,11 @@ function MobileChatPanel({
return;
}
}

if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSubmit(e);
}
};

const resolveDisplayName = (userId: string) => {
Expand Down Expand Up @@ -348,7 +368,7 @@ function MobileChatPanel({
: "bg-[#2a2a2a]/90 text-[#FEFCD9] rounded-bl-md selection:bg-[#F95F4A]/40 selection:text-white"
} ${message.isDirect ? "ring-1 ring-amber-300/30" : ""}`}
>
<p className="text-sm break-words">
<p className="text-sm break-words whitespace-pre-wrap">
{directMessageLabel ? (
<span className="mb-1 block text-[9px] uppercase tracking-[0.14em] text-amber-300/80">
{directMessageLabel}
Expand All @@ -369,7 +389,7 @@ function MobileChatPanel({

<form
onSubmit={handleSubmit}
className="relative flex items-center gap-2 px-4 py-3 border-t border-[#FEFCD9]/10 bg-[#0b0b0b]/95"
className="relative flex items-end gap-2 px-4 py-3 border-t border-[#FEFCD9]/10 bg-[#0b0b0b]/95"
>
{showMentionSuggestions && (
<div className="absolute bottom-full mb-2 left-0 right-0 max-h-40 overflow-y-auto mobile-sheet-card shadow-xl overflow-hidden">
Expand Down Expand Up @@ -426,9 +446,9 @@ function MobileChatPanel({
})}
</div>
)}
<input
<textarea
ref={inputRef}
type="text"
rows={1}
value={localValue}
onChange={(e) => {
setLocalValue(e.target.value);
Expand All @@ -443,7 +463,7 @@ function MobileChatPanel({
: "Type a message or /..."
}
disabled={isChatDisabled}
className="flex-1 mobile-glass mobile-pill px-4 py-2.5 text-sm text-[#FEFCD9] placeholder:text-[#FEFCD9]/30 focus:outline-none focus:border-[#F95F4A]/50 disabled:opacity-50"
className="max-h-28 min-h-10 flex-1 resize-none mobile-glass mobile-pill px-4 py-2.5 text-sm text-[#FEFCD9] placeholder:text-[#FEFCD9]/30 focus:outline-none focus:border-[#F95F4A]/50 disabled:opacity-50"
Comment thread
greptile-apps[bot] marked this conversation as resolved.
/>
<button
type="submit"
Expand Down