Message input multiline

This commit is contained in:
2025-10-17 12:37:55 +02:00
parent f417e92d81
commit ef0a7bcfce
2 changed files with 69 additions and 16 deletions
+5 -1
View File
@@ -2,16 +2,20 @@
import AppSidebar from "@/components/Sidebar"; import AppSidebar from "@/components/Sidebar";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { useIsMobile } from "@/hooks/is-mobile";
import useApp from "@/hooks/use-app"; import useApp from "@/hooks/use-app";
export default function Chat() { export default function Chat() {
const app = useApp(); const app = useApp();
const isMobile = useIsMobile();
return ( return (
<AppSidebar app={app}> <AppSidebar app={app}>
<Card className="bg-background w-full"> <Card className="bg-background w-full">
<CardHeader> <CardHeader>
<CardTitle>Direct Messages</CardTitle> <CardTitle onClick={() => isMobile && app.setSidebarOpen(true)}>
Direct Messages
</CardTitle>
</CardHeader> </CardHeader>
<CardContent></CardContent> <CardContent></CardContent>
</Card> </Card>
+55 -6
View File
@@ -10,8 +10,8 @@ import {
DropdownMenuContent, DropdownMenuContent,
DropdownMenuTrigger, DropdownMenuTrigger,
} from "./ui/dropdown-menu"; } from "./ui/dropdown-menu";
import { ChevronLeftIcon, SmilePlusIcon } from "lucide-react"; import { ChevronLeftIcon, SendIcon, SmilePlusIcon } from "lucide-react";
import { useEffect, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { format, isToday, isYesterday } from "date-fns"; import { format, isToday, isYesterday } from "date-fns";
import ReactMarkdown from "react-markdown"; import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm"; import remarkGfm from "remark-gfm";
@@ -20,6 +20,7 @@ import axios from "axios";
import ProfilePicture from "./ProfilePicture"; import ProfilePicture from "./ProfilePicture";
import App from "@/types/app"; import App from "@/types/app";
import { useIsMobile } from "@/hooks/use-mobile"; import { useIsMobile } from "@/hooks/use-mobile";
import { Textarea } from "./ui/textarea";
function MessageContainer({ message, app }: { message: Message; app: App }) { function MessageContainer({ message, app }: { message: Message; app: App }) {
useEffect(() => { useEffect(() => {
@@ -144,6 +145,7 @@ export default function MessageBox({
}) { }) {
const [text, setText] = useState(""); const [text, setText] = useState("");
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const inputRef = useRef<any>(null);
return ( return (
<div className="h-svh w-full max-h-svh flex flex-col pb-5 pl-5 gap-5"> <div className="h-svh w-full max-h-svh flex flex-col pb-5 pl-5 gap-5">
@@ -164,21 +166,64 @@ export default function MessageBox({
))} ))}
</div> </div>
<footer className="flex gap-3 pr-5 w-full h-max"> <footer className="flex gap-3 pr-5 w-full h-max">
<Input {text.includes("\n") ? (
className="" <Textarea
ref={inputRef}
className="resize-none"
placeholder="Type a message..." placeholder="Type a message..."
value={text} value={text}
onChange={(e) => {
if (!e.target.value.includes("\n") && text.includes("\n")) {
setTimeout(() => {
if (inputRef.current) {
inputRef.current.selectionStart = text.length + 1;
inputRef.current.selectionEnd = text.length + 1;
inputRef.current.focus();
}
}, 10);
}
setText(e.target.value);
}}
onKeyDown={(e) => {
if (e.key === "Enter") {
if (!e.shiftKey) {
e.preventDefault();
sendMessage(text);
setText("");
}
}
}}
/>
) : (
<Input
placeholder="Type a message..."
ref={inputRef}
value={text}
onChange={(e) => setText(e.target.value)} onChange={(e) => setText(e.target.value)}
onKeyDown={(e) => { onKeyDown={(e) => {
if (e.key === "Enter") { if (e.key === "Enter") {
sendMessage(text); if (e.shiftKey) {
setText((p) => p + "\n");
setTimeout(() => {
if (inputRef.current) {
inputRef.current.selectionStart = text.length + 1;
inputRef.current.selectionEnd = text.length + 1;
inputRef.current.focus();
}
}, 10);
} else {
sendMessage(text.trim());
setText(""); setText("");
} }
}
}} }}
/> />
)}
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<Button variant="secondary"> <Button variant="secondary" className="hidden md:block">
<SmilePlusIcon /> <SmilePlusIcon />
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
@@ -190,6 +235,10 @@ export default function MessageBox({
/> />
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
<Button variant="secondary">
<SendIcon />
</Button>
</footer> </footer>
</div> </div>
); );