Commit a7940a38 authored by Ruizi Yu's avatar Ruizi Yu
Browse files

finshed

parent 57fa177a
import { useState } from 'react'
// import { useState } from 'react'
import { Route, Routes } from 'react-router-dom'
import SetName from './pages/SetName/SetName'
import ChatRoom from './pages/ChatRoom/ChatRoom'
......
......@@ -6,11 +6,48 @@ body {
overflow-x: hidden;
}
.slide-in {
position:absolute;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
transform: translateY(-100%);
opacity: 0;
animation: slide-in 2s forwards;
}
.slide-in h1 {
text-align: center;
color: #fff;
}
@keyframes slide-in {
0% {
top: 100%;
opacity: 0;
}
70% {
top: 50%;
opacity: 1;
}
100% {
top: 30%;
opacity: 0;
}
}
.container
{
display: flex;
height:100vh;
opacity: 0;
visibility: hidden;
transition: opacity 0.5s ease-in-out;
}
.container.visible {
opacity: 1;
visibility: visible;
}
.roomList
{
......@@ -49,14 +86,15 @@ body {
text-align: left;
border-radius: 5px;
color: aliceblue;
margin: 5px;
margin: 8px;
padding-bottom: 5px;
white-space: nowrap;
overflow: hidden;
/* text-overflow: ellipsis; */
border-bottom: 2px solid rgba(255, 255, 255, 0.5);
border-right: 2px solid rgba(255, 255, 255, 0.5);
/* border-right: 2px solid rgba(255, 255, 255, 0.5); */
height:100px;
transition: background-color 0.3s ease;
}
/* .room_message
{
......@@ -94,12 +132,75 @@ body {
.room.clicked
{
background-color:#ffffff40;
}
-webkit-animation: shadow-pop-tl 0.3s cubic-bezier(0.470, 0.000, 0.745, 0.715) both;
animation: shadow-pop-tl 0.3s cubic-bezier(0.470, 0.000, 0.745, 0.715) both;
}
@-webkit-keyframes shadow-pop-tl {
0% {
-webkit-box-shadow: 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf;
box-shadow: 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf;
-webkit-transform: translateX(0) translateY(0);
transform: translateX(0) translateY(0);
}
100% {
-webkit-box-shadow: -1px -1px #3e3e3ecf, -2px -2px #3e3e3ecf, -3px -3px #3e3e3ecf, -4px -4px #3e3e3ecf, -5px -5px #3e3e3ecf, -6px -6px #3e3e3ecf, -7px -7px #3e3e3ecf, -8px -8px #3e3e3ecf;
box-shadow: -1px -1px #3e3e3ecf, -2px -2px #3e3e3ecf, -3px -3px #3e3e3ecf, -4px -4px #3e3e3ecf, -5px -5px #3e3e3ecf, -6px -6px #3e3e3ecf, -7px -7px #3e3e3ecf, -8px -8px #3e3e3ecf;
-webkit-transform: translateX(5px) translateY(5px);
transform: translateX(5px) translateY(5px);
}
}
@keyframes shadow-pop-tl {
0% {
-webkit-box-shadow: 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf;
box-shadow: 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf;
-webkit-transform: translateX(0) translateY(0);
transform: translateX(0) translateY(0);
}
100% {
-webkit-box-shadow: -1px -1px #3e3e3ecf, -2px -2px #3e3e3ecf, -3px -3px #3e3e3ecf, -4px -4px #3e3e3ecf, -5px -5px #3e3e3ecf, -6px -6px #3e3e3ecf, -7px -7px #3e3e3ecf, -8px -8px #3e3e3ecf;
box-shadow: -1px -1px #3e3e3ecf, -2px -2px #3e3e3ecf, -3px -3px #3e3e3ecf, -4px -4px #3e3e3ecf, -5px -5px #3e3e3ecf, -6px -6px #3e3e3ecf, -7px -7px #3e3e3ecf, -8px -8px #3e3e3ecf;
-webkit-transform: translateX(5px) translateY(5px);
transform: translateX(5px) translateY(5px);
}
}
.room:hover
{
background-color:#ffffff40;
}
-webkit-animation: shadow-pop-tl 0.3s cubic-bezier(0.470, 0.000, 0.745, 0.715) both;
animation: shadow-pop-tl 0.3s cubic-bezier(0.470, 0.000, 0.745, 0.715) both;
}
@-webkit-keyframes shadow-pop-tl {
0% {
-webkit-box-shadow: 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf;
box-shadow: 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf;
-webkit-transform: translateX(0) translateY(0);
transform: translateX(0) translateY(0);
}
100% {
-webkit-box-shadow: -1px -1px #3e3e3ecf, -2px -2px #3e3e3ecf, -3px -3px #3e3e3ecf, -4px -4px #3e3e3ecf, -5px -5px #3e3e3ecf, -6px -6px #3e3e3ecf, -7px -7px #3e3e3ecf, -8px -8px #3e3e3ecf;
box-shadow: -1px -1px #3e3e3ecf, -2px -2px #3e3e3ecf, -3px -3px #3e3e3ecf, -4px -4px #3e3e3ecf, -5px -5px #3e3e3ecf, -6px -6px #3e3e3ecf, -7px -7px #3e3e3ecf, -8px -8px #3e3e3ecf;
-webkit-transform: translateX(5px) translateY(5px);
transform: translateX(5px) translateY(5px);
}
}
@keyframes shadow-pop-tl {
0% {
-webkit-box-shadow: 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf;
box-shadow: 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf, 0 0 #3e3e3ecf;
-webkit-transform: translateX(0) translateY(0);
transform: translateX(0) translateY(0);
}
100% {
-webkit-box-shadow: -1px -1px #3e3e3ecf, -2px -2px #3e3e3ecf, -3px -3px #3e3e3ecf, -4px -4px #3e3e3ecf, -5px -5px #3e3e3ecf, -6px -6px #3e3e3ecf, -7px -7px #3e3e3ecf, -8px -8px #3e3e3ecf;
box-shadow: -1px -1px #3e3e3ecf, -2px -2px #3e3e3ecf, -3px -3px #3e3e3ecf, -4px -4px #3e3e3ecf, -5px -5px #3e3e3ecf, -6px -6px #3e3e3ecf, -7px -7px #3e3e3ecf, -8px -8px #3e3e3ecf;
-webkit-transform: translateX(5px) translateY(5px);
transform: translateX(5px) translateY(5px);
}
}
.listTitle
{
......@@ -109,16 +210,43 @@ body {
color: aliceblue;
padding-left: 10px;
height:60px;
display:flex;
justify-content: space-between;
white-space: nowrap;
}
.listTitle div {
display: flex;
align-items: center;
}
.listTitle.room_list
.back {
border-radius: 10px;
border-color:#ffffffc1;
background: transparent;
background-color:#ffffffa2;
background-color:#ffffff40;
/* margin-top: 10px;
margin-bottom: 6px; */
margin-right: 7px;
padding:5px;
/* padding-bottom: 0;
padding-top: 0; */
line-height: 1;
color: aliceblue;
overflow: hidden;
text-overflow: ellipsis;
transition: background-color 0.3s ease;
}
.back:hover {
background-color:#ffffffa2;
}
/* .listTitle.room_list
{
display:flex;
justify-content: space-between;
white-space: nowrap;
/* overflow: hidden;
text-overflow: ellipsis; */
}
} */
.listTitle.room_list h3 {
width: 70%;
overflow: hidden;
......@@ -141,6 +269,7 @@ body {
color: aliceblue;
overflow: hidden;
text-overflow: ellipsis;
transition: background-color 0.3s ease;
}
.add_room:hover
......@@ -174,11 +303,14 @@ body {
border-radius: 1vh;
width:90%;
height: 30px;
transition: background-color 0.3s ease;
background-color:#ffffff40;
}
.input_blank:hover
{
background-color:#ffffff40;
background-color: #ffffffb0;
}
.submit
......@@ -193,6 +325,7 @@ body {
line-height: 1;
color: aliceblue;
height: 30px;
transition: background-color 0.3s ease;
}
.submit:hover
......@@ -264,14 +397,24 @@ body {
left: 0;
background: #f1f1f1;
border: 1px solid #ccc;
padding: 8px;
padding: 2px;
border-radius: 5px;
cursor:pointer;
text-align: center;
}
.context-menu div {
padding: 5px;
border-radius: 5px;
transition: background-color 0.3s ease;
}
.context-menu div:hover {
background-color:#cecece;
}
.add-windows{
position: absolute;
top:25%;
top:35%;
left:30%;
width: 40%;
height: 50%;
......@@ -279,13 +422,39 @@ body {
border: 2px solid rgba(255, 255, 255, 0.5);
backdrop-filter: blur(8px);
border-radius: 10px;
min-width: 300px;
min-height: 250px;
padding:2%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
-webkit-animation: slide-top 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: slide-top 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
@-webkit-keyframes slide-top {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
100% {
-webkit-transform: translateY(-100px);
transform: translateY(-100px);
}
}
@keyframes slide-top {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
100% {
-webkit-transform: translateY(-100px);
transform: translateY(-100px);
}
}
.add-windows-button{
width: 50%;
......@@ -297,6 +466,31 @@ body {
cursor: pointer;
font-size: 16px;
font-weight: 600;
transition: background-color 0.3s ease;
}
.add-windows-button:hover
{
background-color:#cecece;
}
.add-windows-button.cancel{
width: 50%;
height: 10%;
border-radius: 40px;
background: #fff;
border: none;
outline: none;
cursor: pointer;
font-size: 16px;
font-weight: 600;
margin-top: 10px;
transition: background-color 0.3s ease;
}
.add-windows-button.cancel:hover
{
background-color:#cecece;
}
.add-windows-inputbox {
......@@ -322,6 +516,10 @@ input:valid ~ label {
top: -5px;
}
.add-windows-inputbox {
width: 70%;
}
.add-windows-inputbox input {
width: 100%;
height: 50px;
......
import React , { useEffect, useState } from "react";
import { useEffect, useState } from "react";
import useSWR from "swr";
import useSWRMutation from "swr/mutation";
import { Link } from 'react-router-dom';
import "./ChatRoom.css";
import { RoomEntry } from "./RoomEntry";
......@@ -9,22 +10,28 @@ import {MessageItem} from "./MessageItem";
import { getFetcher } from "../../util";
import { postFetcher } from "../../util";
import { RoomAddArgs } from "../../vite-env";
import { RoomAddRes } from "../../vite-env";
// import { RoomAddArgs } from "../../vite-env";
// import { RoomAddRes } from "../../vite-env";
import { RoomListRes } from "../../vite-env";
import { RoomDeleteArgs } from "../../vite-env";
import { MessageAddArgs } from "../../vite-env";
import { RoomMessageListArgs } from "../../vite-env";
// import { RoomDeleteArgs } from "../../vite-env";
// import { MessageAddArgs } from "../../vite-env";
// import { RoomMessageListArgs } from "../../vite-env";
import { RoomMessageListRes } from "../../vite-env";
import { RoomMessageGetUpdateArgs } from "../../vite-env";
import { RoomMessageGetUpdateRes } from "../../vite-env";
// import { RoomMessageGetUpdateArgs } from "../../vite-env";
// import { RoomMessageGetUpdateRes } from "../../vite-env";
export default function ChatRoom () {
//定义部分
var ID;
if(localStorage.getItem('latestRoomId')) {
ID = Number(localStorage.getItem('latestRoomId'));
}else {
ID = null;
}
const [roomId, setRoomId] = useState<number | null>(null);//定义“全局变量”roomId,选中房间时更改
const [roomId, setRoomId] = useState<number | null>(ID);//定义“全局变量”roomId,选中房间时更改
const [isAddingRoom,setIsAddingRoom]=useState(false);//添加房间弹窗定义
const nickname = localStorage.getItem('nickname')??'';//昵称
var text = "";
......@@ -41,6 +48,7 @@ export default function ChatRoom () {
roomName: string;
}
>("/api/room/add", postFetcher);
// if(isMutating)return <Loading />;
//获取房间列表
......@@ -53,7 +61,6 @@ export default function ChatRoom () {
});
// if(roomIsLoading)return<Loading />;
// if(roomError)return<Errorwindow />;
// const roomList = roomData?.rooms;
//删除房间
......@@ -114,20 +121,16 @@ export default function ChatRoom () {
}
async function addWindowsSubmit() {
const newId = await addTrigger({ user:nickname, roomName:room_text });
// const newId =
await addTrigger({ user:nickname, roomName:room_text });
// if(newId) setRoomId(Number(newId));
// console.log(roomId);
setIsAddingRoom(false);
}
// useEffect(() => {
// console.log(roomId); // 可以在控制台打印最新的 roomId
// // 进行其他操作或触发重新渲染
// }, [roomId]);
// function updateRoomId(newId:number) {
// setRoomId(newId);
// console.log(roomId);
// }
function addWindowCancel() {
setIsAddingRoom(false);
}
//删除房间
......@@ -156,9 +159,21 @@ export default function ChatRoom () {
//渲染内容
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
setTimeout(() => {
setIsVisible(true);
}, 2000);
}, []);
return(
<>
<div className="container">
<div className="slide-in">
<h1>Hello! {nickname}</h1>
</div>
<div className={`container ${isVisible ? 'visible' : ''}`}>
{/* 消息列表 */}
<div className = "roomList">
<div className="listTitle room_list">
......@@ -169,6 +184,7 @@ export default function ChatRoom () {
<div className = "roomlist">
{roomData?.rooms.map((entry,_) => (
<RoomEntry
key = {entry.roomId}
roomId={entry.roomId}
roomName={entry.roomName}
lastMessage={entry.lastMessage}
......@@ -195,12 +211,18 @@ export default function ChatRoom () {
}
</h3>
<div>
<Link to = "/">
<button className="back">返回</button>
</Link>
</div>
</div>
<div className='chatroom'>
{messageListData?.messages.map((message, _) => {
return (
<MessageItem
key = {message.roomId}
messageId={message.messageId}
roomId={message.roomId}
sender={message.sender}
......@@ -234,6 +256,7 @@ export default function ChatRoom () {
<label htmlFor="">房间名称</label>
</div>
<button className='add-windows-button' onClick={addWindowsSubmit}>确认添加</button>
<button className='add-windows-button cancel'onClick={addWindowCancel} >取消</button>
</div>
)}
</div>
......@@ -242,14 +265,14 @@ export default function ChatRoom () {
}
function Loading() {
return(
window.prompt("Loading...")
);
}
// function Loading() {
// return(
// window.prompt("Loading...")
// );
// }
function Errorwindow() {
return(
window.prompt("Error!")
);
}
// function Errorwindow() {
// return(
// window.prompt("Error!")
// );
// }
import React , { useEffect, useState } from "react";
import { useState } from "react";
import "./ChatRoom.css";
import {RoomEntryProps} from "../../vite-env";
......@@ -34,6 +34,7 @@ export function RoomEntry (props:RoomEntryProps) {
//左键点击
function handleRoomClick () {
props.setSelectedRoomId(props.roomId);
localStorage.setItem('latestRoomId', String(props.roomId));
}
//删除房间
......@@ -44,6 +45,10 @@ export function RoomEntry (props:RoomEntryProps) {
props.setSelectedRoomId(null);
}
}
function handleCancel() {
setContextMenuVisible(false);
}
return(
<>
......@@ -62,7 +67,8 @@ export function RoomEntry (props:RoomEntryProps) {
</div>
{isContextMenuVisible && (
<div className="context-menu" style={contextMenuStyle}>
<div onClick={()=>handleDeleteRoom()}>删除房间</div>
<div onClick={handleDeleteRoom}>删除房间</div>
<div onClick={handleCancel}>取消</div>
</div>
)}
</>
......
......@@ -9,7 +9,7 @@ body {
section {
display: flex;
justify-content: center;
align-items: center;
/* align-items: center; */
min-height: 100vh;
width: 100%;
......@@ -19,7 +19,8 @@ section {
}
.form-box {
position: relative;
position:absolute;
top:30%;
width: 400px;
height: 450px;
background: transparent;
......@@ -31,7 +32,30 @@ section {
display: flex;
justify-content: center;
align-items: center;
-webkit-animation: slide-top 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: slide-top 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
@-webkit-keyframes slide-top {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
100% {
-webkit-transform: translateY(-100px);
transform: translateY(-100px);
}
}
@keyframes slide-top {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
100% {
-webkit-transform: translateY(-100px);
transform: translateY(-100px);
}
}
.form-value h2 {
font-size: 30px;
......@@ -83,4 +107,8 @@ input:valid ~ label {
cursor: pointer;
font-size: 16px;
font-weight: 600;
transition: background-color 0.3s ease;
}
.setname-button:hover {
background-color:#cecece;
}
import React, { useState } from 'react';
// import React, { useState } from 'react';
import "./SetName.css";
import { Link } from 'react-router-dom';
......@@ -30,10 +30,6 @@ export default function Setname() {
<input type="text" onChange={handleNicknameChange} required />
<label htmlFor="">昵称</label>
</div>
{/* <div className='inputbox'>
<input type="password" required />
<label htmlFor="">密码</label>
</div> */}
<Link to = "/index">
<button onClick={handleSubmit} className='setname-button'>登录</button>
</Link>
......
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