Chat changes

This commit is contained in:
2025-04-27 10:53:03 -06:00
parent 871000c333
commit ae10c14cc8
3 changed files with 32 additions and 25 deletions

View File

@ -36,6 +36,7 @@ export default function Chat() {
} else { } else {
setMessages((prev) => [...prev, data]); setMessages((prev) => [...prev, data]);
// Auto-scroll to bottom on new message
const chatBox = document.getElementById("chat-messages"); const chatBox = document.getElementById("chat-messages");
if (chatBox) { if (chatBox) {
setTimeout(() => { setTimeout(() => {
@ -73,19 +74,21 @@ export default function Chat() {
}; };
return ( return (
<div class="w-full max-w-4xl mx-auto bg-dark rounded-lg shadow-lg overflow-hidden border border-gray-800"> <div class="w-full max-w-4xl mx-auto bg-[#1E2127] rounded-lg shadow-lg overflow-hidden border border-gray-800 flex flex-col h-[calc(100vh-180px)] md:h-[600px]">
{/* Header */}
<div class="p-4 bg-secondary text-white"> <div class="p-4 bg-secondary text-white">
<h2 class="text-xl font-bold">Live Chat</h2> <h2 class="text-2xl font-bold">Live Chat</h2>
<p class="text-sm opacity-80"> <p class="text-sm">
{isConnected {isConnected
? `${userCount} online • Messages are not saved` ? `${userCount} online • Messages are not saved`
: "Connecting..."} : "Connecting..."}
</p> </p>
</div> </div>
{/* Chat messages area */}
<div <div
id="chat-messages" id="chat-messages"
class="p-4 h-96 overflow-y-auto bg-dark text-gray-300" class="flex-grow overflow-y-auto bg-[#1E2127] text-gray-300 p-4"
> >
{messages.length === 0 {messages.length === 0
? ( ? (
@ -97,7 +100,7 @@ export default function Chat() {
messages.map((msg, i) => ( messages.map((msg, i) => (
<div <div
key={i} key={i}
class={`mb-3 max-w-md ${ class={`mb-3 max-w-[85%] ${
msg.sender === username ? "ml-auto" : "" msg.sender === username ? "ml-auto" : ""
}`} }`}
> >
@ -112,44 +115,44 @@ export default function Chat() {
<span class="font-bold text-sm"> <span class="font-bold text-sm">
{msg.sender === username ? "You" : msg.sender} {msg.sender === username ? "You" : msg.sender}
</span> </span>
<span class="text-xs opacity-70"> <span class="text-xs opacity-70 ml-2">
{new Date(msg.timestamp).toLocaleTimeString([], { {new Date(msg.timestamp).toLocaleTimeString([], {
hour: "2-digit", hour: "2-digit",
minute: "2-digit", minute: "2-digit",
})} })}
</span> </span>
</div> </div>
<p>{msg.text}</p> <p class="break-words">{msg.text}</p>
</div> </div>
</div> </div>
)) ))
)} )}
</div> </div>
<form onSubmit={sendMessage} class="p-4 border-t border-gray-800"> {/* Input area */}
<div class="flex"> <div class="p-3 border-t border-gray-800 pb-6 md:pb-3">
<form onSubmit={sendMessage} class="relative">
<input <input
type="text" type="text"
value={newMessage} value={newMessage}
onChange={(e) => setNewMessage(e.currentTarget.value)} onChange={(e) => setNewMessage(e.currentTarget.value)}
placeholder="Type your message..." placeholder="Type your message..."
class="flex-1 px-4 py-3 bg-gray-800 text-white rounded-l-lg border-0 focus:outline-none focus:ring-2 focus:ring-secondary placeholder-gray-500" class="w-full pl-4 pr-20 py-3 bg-gray-800 text-white rounded-lg border-0 focus:outline-none focus:ring-1 focus:ring-secondary placeholder-gray-500"
disabled={!isConnected} disabled={!isConnected}
maxLength={2000}
/> />
<button <button
type="submit" type="submit"
class="bg-secondary text-white px-8 py-3 rounded-r-lg hover:bg-opacity-90 focus:outline-none focus:ring-2 focus:ring-secondary font-medium" class="absolute right-0 top-0 h-full bg-secondary text-white px-5 rounded-r-lg font-medium"
disabled={!isConnected || !newMessage.trim()} disabled={!isConnected || !newMessage.trim()}
> >
Send Send
</button> </button>
</div> </form>
<p class="mt-2 text-xs text-gray-500"> <p class="mt-2 text-xs text-gray-500">
You are chatting as{" "} You are chatting as{" "}
<span class="font-medium text-gray-400">{username}</span> <span class="font-medium text-gray-400">{username}</span>
</p> </p>
</form> </div>
</div> </div>
); );
} }

View File

@ -1,4 +1,3 @@
// islands/NavigationBar.tsx
import { useComputed, useSignal } from "@preact/signals"; import { useComputed, useSignal } from "@preact/signals";
import { useEffect } from "preact/hooks"; import { useEffect } from "preact/hooks";
import { import {
@ -54,8 +53,8 @@ export default function NavigationBar({ currentPath }: NavigationBarProps) {
isScrolling.value ? "opacity-30" : "opacity-100" isScrolling.value ? "opacity-30" : "opacity-100"
} ${isVisible.value ? "translate-y-0" : "translate-y-20"}`} } ${isVisible.value ? "translate-y-0" : "translate-y-20"}`}
> >
<ul class="menu menu-horizontal bg-base-200 rounded-box p-2 shadow-lg gap-2"> <ul class="menu menu-horizontal bg-base-200 rounded-box p-2 shadow-lg flex flex-nowrap whitespace-nowrap overflow-x-auto">
<li> <li class="mx-1">
<a href="/" class={currentPath === "/" ? "menu-active" : ""}> <a href="/" class={currentPath === "/" ? "menu-active" : ""}>
<div class="tooltip" data-tip="Home"> <div class="tooltip" data-tip="Home">
<LuHouse class="text-xl" /> <LuHouse class="text-xl" />
@ -63,7 +62,7 @@ export default function NavigationBar({ currentPath }: NavigationBarProps) {
</a> </a>
</li> </li>
<li> <li class="mx-1">
<a <a
href="/posts" href="/posts"
class={isPostsPath(currentPath) ? "menu-active" : ""} class={isPostsPath(currentPath) ? "menu-active" : ""}
@ -74,7 +73,7 @@ export default function NavigationBar({ currentPath }: NavigationBarProps) {
</a> </a>
</li> </li>
<li> <li class="mx-1">
<a <a
href="/projects" href="/projects"
class={currentPath.startsWith("/projects") ? "menu-active" : ""} class={currentPath.startsWith("/projects") ? "menu-active" : ""}
@ -85,7 +84,7 @@ export default function NavigationBar({ currentPath }: NavigationBarProps) {
</a> </a>
</li> </li>
<li> <li class="mx-1">
<a <a
href="/chat" href="/chat"
class={currentPath.startsWith("/chat") ? "menu-active" : ""} class={currentPath.startsWith("/chat") ? "menu-active" : ""}

View File

@ -2,14 +2,19 @@ import Chat from "../islands/Chat.tsx";
export default function ChatPage() { export default function ChatPage() {
return ( return (
<div class="min-h-screen p-4 sm:p-8"> <div class="min-h-screen p-4 pb-24">
<h1 class="text-3xl sm:text-4xl font-bold text-secondary mb-6 sm:mb-8 text-center"> <div class="flex items-center justify-center mb-6">
Chat Room <div className="badge badge-dash badge-primary">Demo</div> <h1 class="text-3xl font-bold text-secondary">Chat Room</h1>
</h1> <span class="ml-3 border border-pink-500 text-pink-500 rounded-full px-3 py-1 text-sm">
Demo
</span>
</div>
<div class="max-w-4xl mx-auto"> <div class="max-w-4xl mx-auto">
<Chat /> <Chat />
</div> </div>
<div class="mt-8 text-center text-sm text-gray-500">
<div class="mt-4 text-center text-xs text-gray-500 mb-20">
<p> <p>
This is an ephemeral chat room. Messages are only visible to users This is an ephemeral chat room. Messages are only visible to users
currently online and aren't stored after you leave. currently online and aren't stored after you leave.