Skip to content

Commit 08aacc1

Browse files
committed
show chat users
1 parent d412998 commit 08aacc1

File tree

6 files changed

+75
-51
lines changed

6 files changed

+75
-51
lines changed

src/main/client/src/component/Chat.jsx

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ import {
55
useContext,
66
useRef,
77
} from "react"
8-
import {
9-
useParams,
10-
} from "react-router-dom"
118
import {
129
useAuthStore,
1310
} from "../store.js"
@@ -19,17 +16,20 @@ import {
1916

2017
export const Chat = ({chatId}) => {
2118
let [messages, setMessages] = useState([])
22-
let divRef = useRef()
19+
let [users, setUsers] = useState([])
2320
let messageRef = useRef()
2421
let needsScroll = useRef(false)
2522
let stompClient = useContext(StompContext)
2623
let auth = useAuthStore(state => state.auth)
2724

2825
useEffect(() => {
29-
stompClient.subscribe("/topic/chat/" + chatId, (m) => {
26+
let sub1 = stompClient.subscribe("/topic/users/Lobby", (message) => {
27+
let r = JSON.parse(message.body)
28+
setUsers(r.users)
29+
})
30+
let sub2 = stompClient.subscribe("/topic/chat/" + chatId, (m) => {
3031
let message = JSON.parse(m.body)
31-
let msg = messageRef.current
32-
needsScroll.current = msg.scrollHeight <= msg.scrollTop + msg.offsetHeight
32+
needsScroll.current = isLastChildVisible(messageRef.current)
3333
setMessages(previous => {
3434
if (previous.length && previous[previous.length - 1].n === message.n) {
3535
return previous
@@ -48,13 +48,26 @@ export const Chat = ({chatId}) => {
4848
})
4949
setMessages(chat.messages || [])
5050
})
51+
return () => {
52+
sub1.unsubscribe()
53+
sub2.unsubscribe()
54+
}
5155
}, [stompClient, auth, chatId])
5256

5357
useEffect(() => {
5458
if (!needsScroll.current) {
5559
return
5660
}
57-
window.setTimeout(() => divRef.current?.scrollIntoView({behavior: "smooth"}), 0)
61+
window.setTimeout(() => {
62+
if (!messageRef.current) {
63+
return
64+
}
65+
let lastChild = messageRef.current.lastChild
66+
if (!lastChild) {
67+
return
68+
}
69+
lastChild.scrollIntoView({behavior: "smooth"})
70+
}, 0)
5871
}, [messages])
5972

6073
let onSendMessage = useCallback((event) => doTry(async () => {
@@ -71,14 +84,21 @@ export const Chat = ({chatId}) => {
7184
}), [stompClient, chatId])
7285

7386
return <>
74-
<div ref={messageRef}
75-
className="grow border border-gray-500 bg-gray-900 rounded-lg p-1 overflow-y-scroll">
76-
{messages.map(message => (
77-
<p key={message.n}>{message.user + ": " + message.message}</p>
78-
))}
79-
<div ref={divRef} />
87+
<div
88+
className="grow border border-gray-500 bg-gray-900 rounded-lg flex flex-col overflow-y-hidden">
89+
<div className="px-1 flex-none h-14 overflow-y-scroll">
90+
{users.map(user => (
91+
<p key={user}>{user}</p>
92+
))}
93+
</div>
94+
<div className="w-full flex-none h-[2px] bg-gray-500" />
95+
<div ref={messageRef} className="px-1 overflow-y-scroll">
96+
{messages.map(message => (
97+
<p key={message.n}>{message.user + ": " + message.message}</p>
98+
))}
99+
</div>
80100
</div>
81-
<form className="flex-0 mb-2" onSubmit={onSendMessage}>
101+
<form className="flex-none mb-2" onSubmit={onSendMessage}>
82102
<input
83103
className="w-full rounded-lg p-2 border border-gray-500 bg-stone-800 text-stone-100"
84104
type="text"
@@ -87,3 +107,14 @@ export const Chat = ({chatId}) => {
87107
</form>
88108
</>
89109
}
110+
111+
function isLastChildVisible(container) {
112+
let lastChild = container.lastChild
113+
if (!lastChild) {
114+
return false
115+
}
116+
let lastChildTop = lastChild.offsetTop
117+
let containerTop = container.scrollTop + container.offsetTop
118+
let containerBottom = containerTop + container.clientHeight
119+
return lastChildTop < containerBottom
120+
}

src/main/client/src/feature/game/Game.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ export const Game = () => {
210210
destination: "/app/game/move",
211211
body: JSON.stringify(move),
212212
})
213-
}, [context, currentPlayer, currentColor, auth, board, stompClient, counting, forbidden_x, forbidden_y, gameHasEnded, movesLength, addMove, isSelfPlay, myColor, muted])
213+
}, [context, currentPlayer, currentColor, auth, board, stompClient, counting, forbidden_x, forbidden_y, gameHasEnded, movesLength, addMove, isSelfPlay, myColor, muted, sound])
214214

215215
let onMuteClick = useCallback(() => {
216216
if (muted) {
Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
import {
2-
useContext,
32
useEffect,
4-
useState,
53
} from "react"
64
import {
75
tfetch,
8-
StompContext,
96
doTry,
107
} from "../../util.js"
118
import {
129
useAuthStore,
1310
} from "../../store.js"
11+
import {
12+
Chat,
13+
} from "../../component/Chat.jsx"
1414
import {
1515
SideBar,
1616
} from "../../component/SideBar.jsx"
1717

1818
export const LobbyPanel = () => {
1919
return (
2020
<SideBar page="lobby">
21-
<div className="pt-2">
21+
<div className="pr-3 pt-2 pl-2 h-full flex flex-col gap-y-1">
2222
<Panel />
2323
</div>
2424
</SideBar>
@@ -27,8 +27,6 @@ export const LobbyPanel = () => {
2727

2828
function Panel() {
2929
let auth = useAuthStore(state => state.auth)
30-
let stompClient = useContext(StompContext)
31-
let [users, setUsers] = useState([])
3230
useEffect(() => {
3331
doTry(() => {
3432
tfetch("/api/lobby/hello", {
@@ -38,28 +36,8 @@ function Panel() {
3836
})
3937
})
4038
return undefined
41-
}, [setUsers, auth])
42-
useEffect(() => {
43-
let sub1 = stompClient.subscribe("/topic/lobby/users", (message) => {
44-
let r = JSON.parse(message.body)
45-
setUsers(r.users)
46-
})
47-
return () => {
48-
sub1.unsubscribe()
49-
}
50-
}, [setUsers, stompClient])
51-
return (
52-
<div className="mt-2">
53-
<div className="pl-2 pb-2 border-b border-b-slate-700">
54-
{auth.name}
55-
</div>
56-
<div className="pl-2 mt-2">
57-
{users.map(user => (
58-
<div key={user}>
59-
{user}
60-
</div>
61-
))}
62-
</div>
63-
</div>
64-
)
39+
}, [auth])
40+
return <>
41+
<Chat chatId="Lobby"/>
42+
</>
6543
}

src/main/java/com/bernd/ChatController.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
import com.bernd.model.Chat;
44
import com.bernd.model.ChatMessage;
55
import com.bernd.model.ChatRequest;
6+
import com.bernd.model.UsersMessage;
67
import com.bernd.util.Auth;
7-
import java.security.Principal;
8-
import java.util.ArrayList;
9-
import java.util.concurrent.atomic.AtomicInteger;
108
import org.springframework.http.ResponseEntity;
119
import org.springframework.messaging.core.MessageSendingOperations;
1210
import org.springframework.messaging.handler.annotation.MessageMapping;
@@ -15,6 +13,11 @@
1513
import org.springframework.web.bind.annotation.PathVariable;
1614
import org.springframework.web.bind.annotation.ResponseBody;
1715

16+
import java.security.Principal;
17+
import java.util.ArrayList;
18+
import java.util.TreeSet;
19+
import java.util.concurrent.atomic.AtomicInteger;
20+
1821
@Controller
1922
public class ChatController {
2023

@@ -38,9 +41,12 @@ public Chat getChat(@PathVariable String id) {
3841
public ResponseEntity<?> sendChat(ChatRequest chatRequest, Principal principal) {
3942
String user = Auth.getPrincipal(principal);
4043
Chat chat = chats.map().computeIfAbsent(chatRequest.id(),
41-
id -> new Chat(id, new AtomicInteger(0), new ArrayList<>()));
44+
id -> new Chat(id, new AtomicInteger(0), new ArrayList<>(), new TreeSet<>()));
4245
ChatMessage message = new ChatMessage(chat.counter().getAndIncrement(), chatRequest.message(), user);
4346
chat.messages().add(message);
47+
if (chat.users().add(user)) {
48+
operations.convertAndSend("/topic/users/" + chat.id(), new UsersMessage(chat.users()));
49+
}
4450
operations.convertAndSend("/topic/chat/" + chat.id(), message);
4551
return ResponseEntity.ok().build();
4652
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.bernd.model;
22

33
import java.util.List;
4+
import java.util.Set;
45
import java.util.concurrent.atomic.AtomicInteger;
56

67
public record Chat(
78
String id,
89
AtomicInteger counter,
9-
List<ChatMessage> messages) {
10+
List<ChatMessage> messages,
11+
Set<String> users) {
1012
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.bernd.model;
2+
3+
import java.util.Set;
4+
5+
public record UsersMessage(
6+
Set<String> users) {
7+
}

0 commit comments

Comments
 (0)