You need to sign in or sign up before continuing.
Commit 58b938ad authored by Ruizi Yu's avatar Ruizi Yu
Browse files

finished fronted work

parent 15fe7465
...@@ -70,6 +70,10 @@ body { ...@@ -70,6 +70,10 @@ body {
margin-left: 10px; margin-left: 10px;
margin-right: 10px; margin-right: 10px;
} }
.room.clicked
{
background-color:#ffffff40;
}
.room:hover .room:hover
{ {
...@@ -208,4 +212,68 @@ body { ...@@ -208,4 +212,68 @@ body {
padding: 8px; padding: 8px;
border-radius: 5px; border-radius: 5px;
cursor:pointer; cursor:pointer;
}
.add-windows{
position: absolute;
top:25%;
left:30%;
width: 40%;
height: 50%;
background: transparent;
border: 2px solid rgba(255, 255, 255, 0.5);
backdrop-filter: blur(8px);
border-radius: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.add-windows-button{
width: 50%;
height: 10%;
border-radius: 40px;
background: #fff;
border: none;
outline: none;
cursor: pointer;
font-size: 16px;
font-weight: 600;
}
.add-windows-inputbox {
position: relative;
margin: 30px 0;
width: 310px;
border-bottom: 2px solid #fff;
}
.add-windows-inputbox label {
position: absolute;
top: 50%;
left: 5px;
transform: translateY(-50%);
color: #fff;
font-size: 1em;
pointer-events: none;
transition: 0.5s;
}
input:focus ~ label,
input:valid ~ label {
top: -5px;
}
.add-windows-inputbox input {
width: 100%;
height: 50px;
background-color: transparent;
border: none;
outline: none;
font-size: 1em;
padding: 0 35px 0 5px;
color: #fff;
} }
\ No newline at end of file
import React , { useState } from "react"; import React , { useEffect, useState } from "react";
import "./ChatRoom.css"; import "./ChatRoom.css";
//房间组件
interface RoomEntryProps { interface RoomEntryProps {
roomId: number; roomId: number;
roomName: string; roomName: string;
lastMessage: MessageProps | null; lastMessage: MessageProps | null;
onDelete: (index: number) => void; onDelete: (index: number) => void;
selectedRoomId:number;
setSelectedRoomId: React.Dispatch<React.SetStateAction<number>>;
} }
function RoomEntry (props:RoomEntryProps) { function RoomEntry (props:RoomEntryProps) {
const [isContextMenuVisible, setContextMenuVisible] = useState(false); const [isContextMenuVisible, setContextMenuVisible] = useState(false);
const [contextMenuStyle, setContextMenuStyle] = useState({}); const [contextMenuStyle, setContextMenuStyle] = useState({});
// const [deleteId,setDeleteId] = useState<number | null>(null);
//右键点击
function handleContextMenu(e: { preventDefault: () => void; button: number; clientY: any; clientX: any; }) { function handleContextMenu(e: { preventDefault: () => void; button: number; clientY: any; clientX: any; }) {
e.preventDefault(); // 阻止默认的右键菜单 e.preventDefault(); // 阻止默认的右键菜单
...@@ -24,36 +29,46 @@ function RoomEntry (props:RoomEntryProps) { ...@@ -24,36 +29,46 @@ function RoomEntry (props:RoomEntryProps) {
// 显示右键菜单 // 显示右键菜单
setContextMenuStyle(style); setContextMenuStyle(style);
setContextMenuVisible(true); setContextMenuVisible(true);
// setDeleteId(props.roomId);
} }
else if (e.button === 1)
{ }
} //左键点击
function handleRoomClick () {
props.setSelectedRoomId(props.roomId);
} }
//删除房间
function handleDeleteRoom() { function handleDeleteRoom() {
setContextMenuVisible(false); setContextMenuVisible(false);
props.onDelete(props.roomId); props.onDelete(props.roomId);
if (props.selectedRoomId === props.roomId) {
props.setSelectedRoomId(-1);
}
} }
return( return(
<> <>
<div className="room" onContextMenu={handleContextMenu}> {/* 判断该房间是否为选中的房间 */}
<div className={`room ${props.selectedRoomId === props.roomId ? "clicked" : ""}`} onContextMenu={handleContextMenu} onClick={handleRoomClick}>
<div> <div>
<p>房间</p> <p>{props.roomName}</p>
<p>时间</p> <p>{props.lastMessage?.time??'刚刚'}</p>
</div> </div>
<p>{props.lastMessage?.sender??'昵称'}</p> <p>{props.lastMessage?.sender??'[新建了一个房间]'}</p>
</div> </div>
{isContextMenuVisible && ( {isContextMenuVisible && (
<div className="context-menu" style={contextMenuStyle}> <div className="context-menu" style={contextMenuStyle}>
<div onClick={handleDeleteRoom}>删除房间</div> <div onClick={()=>handleDeleteRoom()}>删除房间</div>
</div> </div>
)} )}
</> </>
); );
} }
//消息组件
interface MessageProps { interface MessageProps {
messageId: number; messageId: number;
roomId: number; roomId: number;
...@@ -84,46 +99,85 @@ function MessageItem (props:MessageProps) { ...@@ -84,46 +99,85 @@ function MessageItem (props:MessageProps) {
</div> </div>
</div> </div>
</> </>
); );
} }
export default function ChatRoom () { export default function ChatRoom () {
type Entry = number; //get请求获取聊天房间列表
//选择的房间的状态定义
const [selectedRoomId, setSelectedRoomId] = useState(-1);
// 房间组件定义
type Entry = {
roomname:string;
};
const [roomEntries, setRoomEntries] = useState<Entry[]>([]); const [roomEntries, setRoomEntries] = useState<Entry[]>([]);
var room_text = "";
//消息组件定义
type Messages = { type Messages = {
content: string; content: string;
time: number; time: number;
roomId:number;
}; };
const [messages, setMessages] = useState<Messages[]>([]); const [messages, setMessages] = useState<Messages[]>([]);
var text = ""; var text = "";
//添加房间弹窗定义
const[isAddingRoom,setIsAddingRoom]=useState(false);
//添加房间
function addRoom(event: { preventDefault: () => void; }) { function addRoom(event: { preventDefault: () => void; }) {
event.preventDefault(); event.preventDefault();
setRoomEntries(prevEntries => [...prevEntries, prevEntries.length]); setIsAddingRoom(true);
// setRoomEntries(prevEntries => [...prevEntries, prevEntries.length]);
} }
function handleRoomNameChange(event: {
preventDefault(): unknown; target: { value: string; }
}) {
room_text = event.target.value;
event.preventDefault();
}
function addWindowsSubmit() {
const newEntry = {
roomname:room_text
}
setRoomEntries(prevEntries => [...prevEntries, newEntry]);
setIsAddingRoom(false);
}
//删除房间
function handleDeleteRoom(index: number) { function handleDeleteRoom(index: number) {
setRoomEntries(prevEntries => prevEntries.filter((_, i) => i !== index)); // 通过过滤删除指定索引的房间 setRoomEntries(prevEntries => prevEntries.filter((_, i) => i !== index)); // 通过过滤删除指定索引的房间
} }
//消息框内容改变监测函数
function messageChange(event: { target: { value: string; }; preventDefault: () => void; }) { function messageChange(event: { target: { value: string; }; preventDefault: () => void; }) {
text = event.target.value; text = event.target.value;
event.preventDefault(); event.preventDefault();
} }
//提交函数
function handleSubmit(event: { preventDefault: () => void; }) { function handleSubmit(event: { preventDefault: () => void; }) {
const currentTime = Date.now(); const currentTime = Date.now();
const newMessage = { const newMessage = {
content:text, content:text,
time:currentTime time:currentTime,
roomId:selectedRoomId
} }
event.preventDefault(); event.preventDefault();
setMessages(prevMessages => [...prevMessages, newMessage]); setMessages(prevMessages => [...prevMessages, newMessage]);
console.log(messages); console.log(messages);
const inputElement = document.querySelector('.input_blank') as HTMLInputElement; const inputElement = document.querySelector('.input_blank') as HTMLInputElement;
...@@ -134,6 +188,14 @@ export default function ChatRoom () { ...@@ -134,6 +188,14 @@ export default function ChatRoom () {
} }
// useEffect(() => {
// const interval = setInterval(() => {
// setMessages(prevMessages => [...prevMessages, newMessage]);
// },1000);
// return () => {clearInterval(interval);}
// },[selectedRoomId])
//渲染内容
return( return(
<> <>
<div className="container"> <div className="container">
...@@ -143,36 +205,45 @@ export default function ChatRoom () { ...@@ -143,36 +205,45 @@ export default function ChatRoom () {
<h3>昵称</h3> <h3>昵称</h3>
<button className="add_room" onClick={addRoom}>新建房间</button> <button className="add_room" onClick={addRoom}>新建房间</button>
</div> </div>
{/* 渲染房间 */}
<div className = "roomlist"> <div className = "roomlist">
{roomEntries.map((_,index) => ( {roomEntries.map((entry,index) => (
<RoomEntry <RoomEntry
key={index} key={index}
roomId={0} roomId={index}
onDelete={handleDeleteRoom} onDelete={handleDeleteRoom}
roomName={""} roomName={entry.roomname}
lastMessage={null} lastMessage={null}
setSelectedRoomId={setSelectedRoomId}
selectedRoomId={selectedRoomId}
/> />
))} ))}
</div> </div>
</div> </div>
{/* 聊天房间页面 */}
<div className = "messagelist"> <div className = "messagelist">
<div className="listTitle"> <div className="listTitle">
<h3>房间一</h3> <h3>房间一</h3>
</div> </div>
<div className='chatroom'> <div className='chatroom'>
{messages.map((message,index) => ( {messages.map((message, index) => {
<MessageItem if (message.roomId === selectedRoomId) {
messageId={index} return (
roomId={0} <MessageItem
sender={"昵称"} key={index}
content={message.content} messageId={index}
time={message.time} roomId={message.roomId}
/> sender={"昵称"}
))} content={message.content}
time={message.time}
/>
);
} else {
return null;
}
})}
</div> </div>
<div className="input"> <div className="input">
...@@ -180,6 +251,17 @@ export default function ChatRoom () { ...@@ -180,6 +251,17 @@ export default function ChatRoom () {
<button className="submit" onClick={handleSubmit}>发送</button> <button className="submit" onClick={handleSubmit}>发送</button>
</div> </div>
</div> </div>
{isAddingRoom && (
<div className="add-windows">
<h2>添加房间</h2>
<div className="add-windows-inputbox">
<input type="text" onChange={handleRoomNameChange} required />
<label htmlFor="">房间名称</label>
</div>
<button className='add-windows-button' onClick={addWindowsSubmit}>确认添加</button>
</div>
)}
</div> </div>
</> </>
); );
......
...@@ -25,10 +25,10 @@ export default function Setname() { ...@@ -25,10 +25,10 @@ export default function Setname() {
<input type="text" value={nickname} onChange={handleNicknameChange} required /> <input type="text" value={nickname} onChange={handleNicknameChange} required />
<label htmlFor="">昵称</label> <label htmlFor="">昵称</label>
</div> </div>
<div className='inputbox'> {/* <div className='inputbox'>
<input type="password" required /> <input type="password" required />
<label htmlFor="">密码</label> <label htmlFor="">密码</label>
</div> </div> */}
<Link to = "/index"> <Link to = "/index">
<button className='setname-button'>登录</button> <button className='setname-button'>登录</button>
</Link> </Link>
......
import type {Response} from "./vite-env";
const prefix = "http://47.99.68.65";
export async function getFetcher(key:string){
const resp = (await fetch(prefix + key, { mode: "cors"}).then((res) => res.json()
)) as Response<any>;
if (resp.code !== 0) {
throw new Error(resp.message + " " + resp.code);
}
return resp.data;
}
export async function postFetcher(
key:string,
body:{ arg: Record<string, unknown> | Array<unknown> }
) {
const resp = (await fetch(prefix + key, {
method:"POST",
headers:{"Content-Type":"application/json" },
body:JSON.stringify(body.arg),
mode:"cors",
} ).then((res) => res.json())) as Response<any>;
if (resp.code !== 0) {
throw new Error(resp.message + " " + resp.code);
}
return resp.data;
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment