Commit 58b938ad authored by Ruizi Yu's avatar Ruizi Yu
Browse files

finished fronted work

parent 15fe7465
......@@ -70,6 +70,10 @@ body {
margin-left: 10px;
margin-right: 10px;
}
.room.clicked
{
background-color:#ffffff40;
}
.room:hover
{
......@@ -208,4 +212,68 @@ body {
padding: 8px;
border-radius: 5px;
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";
//房间组件
interface RoomEntryProps {
roomId: number;
roomName: string;
lastMessage: MessageProps | null;
onDelete: (index: number) => void;
selectedRoomId:number;
setSelectedRoomId: React.Dispatch<React.SetStateAction<number>>;
}
function RoomEntry (props:RoomEntryProps) {
const [isContextMenuVisible, setContextMenuVisible] = useState(false);
const [contextMenuStyle, setContextMenuStyle] = useState({});
// const [deleteId,setDeleteId] = useState<number | null>(null);
//右键点击
function handleContextMenu(e: { preventDefault: () => void; button: number; clientY: any; clientX: any; }) {
e.preventDefault(); // 阻止默认的右键菜单
......@@ -24,36 +29,46 @@ function RoomEntry (props:RoomEntryProps) {
// 显示右键菜单
setContextMenuStyle(style);
setContextMenuVisible(true);
// setDeleteId(props.roomId);
}
else if (e.button === 1)
{
}
}
//左键点击
function handleRoomClick () {
props.setSelectedRoomId(props.roomId);
}
//删除房间
function handleDeleteRoom() {
setContextMenuVisible(false);
props.onDelete(props.roomId);
if (props.selectedRoomId === props.roomId) {
props.setSelectedRoomId(-1);
}
}
return(
<>
<div className="room" onContextMenu={handleContextMenu}>
{/* 判断该房间是否为选中的房间 */}
<div className={`room ${props.selectedRoomId === props.roomId ? "clicked" : ""}`} onContextMenu={handleContextMenu} onClick={handleRoomClick}>
<div>
<p>房间</p>
<p>时间</p>
<p>{props.roomName}</p>
<p>{props.lastMessage?.time??'刚刚'}</p>
</div>
<p>{props.lastMessage?.sender??'昵称'}</p>
<p>{props.lastMessage?.sender??'[新建了一个房间]'}</p>
</div>
{isContextMenuVisible && (
<div className="context-menu" style={contextMenuStyle}>
<div onClick={handleDeleteRoom}>删除房间</div>
<div onClick={()=>handleDeleteRoom()}>删除房间</div>
</div>
)}
</>
);
}
//消息组件
interface MessageProps {
messageId: number;
roomId: number;
......@@ -84,46 +99,85 @@ function MessageItem (props:MessageProps) {
</div>
</div>
</>
);
);
}
export default function ChatRoom () {
type Entry = number;
//get请求获取聊天房间列表
//选择的房间的状态定义
const [selectedRoomId, setSelectedRoomId] = useState(-1);
// 房间组件定义
type Entry = {
roomname:string;
};
const [roomEntries, setRoomEntries] = useState<Entry[]>([]);
var room_text = "";
//消息组件定义
type Messages = {
content: string;
time: number;
roomId:number;
};
const [messages, setMessages] = useState<Messages[]>([]);
var text = "";
//添加房间弹窗定义
const[isAddingRoom,setIsAddingRoom]=useState(false);
//添加房间
function addRoom(event: { preventDefault: () => void; }) {
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) {
setRoomEntries(prevEntries => prevEntries.filter((_, i) => i !== index)); // 通过过滤删除指定索引的房间
}
//消息框内容改变监测函数
function messageChange(event: { target: { value: string; }; preventDefault: () => void; }) {
text = event.target.value;
event.preventDefault();
}
//提交函数
function handleSubmit(event: { preventDefault: () => void; }) {
const currentTime = Date.now();
const newMessage = {
content:text,
time:currentTime
time:currentTime,
roomId:selectedRoomId
}
event.preventDefault();
setMessages(prevMessages => [...prevMessages, newMessage]);
console.log(messages);
const inputElement = document.querySelector('.input_blank') as HTMLInputElement;
......@@ -134,6 +188,14 @@ export default function ChatRoom () {
}
// useEffect(() => {
// const interval = setInterval(() => {
// setMessages(prevMessages => [...prevMessages, newMessage]);
// },1000);
// return () => {clearInterval(interval);}
// },[selectedRoomId])
//渲染内容
return(
<>
<div className="container">
......@@ -143,36 +205,45 @@ export default function ChatRoom () {
<h3>昵称</h3>
<button className="add_room" onClick={addRoom}>新建房间</button>
</div>
{/* 渲染房间 */}
<div className = "roomlist">
{roomEntries.map((_,index) => (
{roomEntries.map((entry,index) => (
<RoomEntry
key={index}
roomId={0}
onDelete={handleDeleteRoom}
roomName={""}
lastMessage={null}
roomId={index}
onDelete={handleDeleteRoom}
roomName={entry.roomname}
lastMessage={null}
setSelectedRoomId={setSelectedRoomId}
selectedRoomId={selectedRoomId}
/>
))}
</div>
</div>
{/* 聊天房间页面 */}
<div className = "messagelist">
<div className="listTitle">
<h3>房间一</h3>
</div>
<div className='chatroom'>
{messages.map((message,index) => (
<MessageItem
messageId={index}
roomId={0}
sender={"昵称"}
content={message.content}
time={message.time}
/>
))}
{messages.map((message, index) => {
if (message.roomId === selectedRoomId) {
return (
<MessageItem
key={index}
messageId={index}
roomId={message.roomId}
sender={"昵称"}
content={message.content}
time={message.time}
/>
);
} else {
return null;
}
})}
</div>
<div className="input">
......@@ -180,6 +251,17 @@ export default function ChatRoom () {
<button className="submit" onClick={handleSubmit}>发送</button>
</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>
</>
);
......
......@@ -25,10 +25,10 @@ export default function Setname() {
<input type="text" value={nickname} onChange={handleNicknameChange} required />
<label htmlFor="">昵称</label>
</div>
<div className='inputbox'>
{/* <div className='inputbox'>
<input type="password" required />
<label htmlFor="">密码</label>
</div>
</div> */}
<Link to = "/index">
<button className='setname-button'>登录</button>
</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