Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Ruizi Yu
ChatRoom
Commits
58b938ad
You need to sign in or sign up before continuing.
Commit
58b938ad
authored
Sep 07, 2023
by
Ruizi Yu
Browse files
finished fronted work
parent
15fe7465
Changes
4
Hide whitespace changes
Inline
Side-by-side
chat-room/src/pages/ChatRoom/ChatRoom.css
View file @
58b938ad
...
@@ -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
chat-room/src/pages/ChatRoom/ChatRoom.tsx
View file @
58b938ad
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
>
</>
</>
);
);
...
...
chat-room/src/pages/SetName/SetName.tsx
View file @
58b938ad
...
@@ -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
>
...
...
chat-room/src/util.ts
0 → 100644
View file @
58b938ad
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
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment