Skip to content

Commit af01b60

Browse files
author
vtm9
committed
Add user ban button in chat
1 parent 7a2070f commit af01b60

9 files changed

Lines changed: 74 additions & 60 deletions

File tree

services/app/assets/js/widgets/components/Message.jsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
import React from 'react';
2+
import { useSelector } from 'react-redux';
23
import moment from 'moment';
4+
import { currentUserIsAdminSelector } from '../selectors';
5+
import { pushCommand } from '../middlewares/Chat';
36

47
const Message = ({
58
text = '', name = '', type, time,
69
}) => {
10+
const currentUserIsAdmin = useSelector(state => currentUserIsAdminSelector(state));
11+
const handleBanClick = bannedName => {
12+
pushCommand({ type: 'ban', name: bannedName });
13+
};
14+
715
if (!text) {
816
return null;
917
}
@@ -12,9 +20,7 @@ const Message = ({
1220
return (
1321
<div className="d-flex align-items-baseline flex-wrap">
1422
<small className="text-muted text-small">{text}</small>
15-
<small className="text-muted text-small ml-auto">
16-
{time ? moment.unix(time).format('HH:mm:ss') : ''}
17-
</small>
23+
<small className="text-muted text-small ml-auto">{time ? moment.unix(time).format('HH:mm:ss') : ''}</small>
1824
</div>
1925
);
2026
}
@@ -44,9 +50,18 @@ const Message = ({
4450
{/* eslint-disable-next-line react/no-array-index-key */}
4551
<span className="font-weight-bold">{`${name}: `}</span>
4652
<span className="ml-1">{parts.map((part, i) => renderMessagePart(part, i))}</span>
47-
<small className="text-muted text-small ml-auto">
48-
{time ? moment.unix(time).format('HH:mm:ss') : ''}
49-
</small>
53+
<small className="text-muted text-small ml-auto">{time ? moment.unix(time).format('HH:mm:ss') : ''}</small>
54+
{currentUserIsAdmin ? (
55+
<button
56+
type="button"
57+
className="btn btn-sm btn-outline-danger"
58+
onClick={() => {
59+
handleBanClick(name);
60+
}}
61+
>
62+
Ban
63+
</button>
64+
) : null}
5065
</div>
5166
);
5267
};

services/app/assets/js/widgets/middlewares/Chat.js

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ const fetchState = () => dispatch => {
2525

2626
channel.join().receive('ok', camelizeKeysAndDispatch(actions.updateChatData));
2727

28-
channel.on(
29-
'chat:user_joined',
30-
camelizeKeysAndDispatch(actions.userJoinedChat),
31-
);
28+
channel.on('chat:user_joined', camelizeKeysAndDispatch(actions.userJoinedChat));
3229
channel.on('chat:user_left', camelizeKeysAndDispatch(actions.userLeftChat));
3330
channel.on('chat:new_msg', camelizeKeysAndDispatch(actions.newMessageChat));
3431
channel.on('chat:ban', camelizeKeysAndDispatch(actions.banUserChat));
@@ -43,13 +40,9 @@ export const connectToChat = () => dispatch => {
4340
export const addMessage = message => {
4441
const payload = { text: message };
4542

46-
channel
47-
.push('chat:new_msg', payload)
48-
.receive('error', error => console.error(error));
43+
channel.push('chat:new_msg', payload).receive('error', error => console.error(error));
4944
};
5045

5146
export const pushCommand = command => {
52-
channel
53-
.push('chat:command', command)
54-
.receive('error', error => console.error(error));
47+
channel.push('chat:command', { command }).receive('error', error => console.error(error));
5548
};

services/app/assets/js/widgets/selectors/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { replayerMachineStates } from '../machines/game';
1010

1111
export const currentUserIdSelector = state => state.user.currentUserId;
1212

13+
export const currentUserIsAdminSelector = state => state.user.isAdmin;
14+
1315
export const isShowGuideSelector = state => state.gameUI.isShowGuide;
1416

1517
export const gamePlayersSelector = state => state.game.players;

services/app/lib/codebattle/tournament/base.ex

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,28 +49,22 @@ defmodule Codebattle.Tournament.Base do
4949
leave(tournament, %{user_id: user.id})
5050
end
5151

52-
def leave(%{state: "upcoming"} = tournament, %{user_id: user_id}) do
52+
def leave(tournament, %{user_id: user_id}) do
5353
new_ids =
5454
tournament
5555
|> get_intended_player_ids
5656
|> Enum.filter(fn id -> id != user_id end)
5757

58-
new_data =
59-
tournament
60-
|> Map.get(:data)
61-
|> Map.merge(%{intended_player_ids: new_ids})
62-
|> Map.from_struct()
63-
64-
update!(tournament, %{data: new_data})
65-
end
66-
67-
def leave(%{state: "waiting_participants"} = tournament, %{user_id: user_id}) do
6858
new_players =
69-
tournament.data.players
59+
tournament
60+
|> get_players
7061
|> Enum.filter(fn player -> player.id != user_id end)
7162

7263
new_data =
73-
tournament |> Map.get(:data) |> Map.merge(%{players: new_players}) |> Map.from_struct()
64+
tournament
65+
|> Map.get(:data)
66+
|> Map.merge(%{players: new_players, intended_player_ids: new_ids})
67+
|> Map.from_struct()
7468

7569
update!(tournament, %{data: new_data})
7670
end

services/app/lib/codebattle/user.ex

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,35 @@ defmodule Codebattle.User do
2424
end
2525
end
2626

27-
@derive {Jason.Encoder,
28-
only: [
29-
:id,
30-
:name,
31-
:rating,
32-
:is_bot,
33-
:guest,
34-
:github_id,
35-
:github_name,
36-
:lang,
37-
:editor_mode,
38-
:editor_theme,
39-
:achievements,
40-
:rank,
41-
:games_played,
42-
:performance,
43-
:inserted_at,
44-
:sound_settings,
45-
:discord_name,
46-
:discord_id,
47-
:discord_avatar
48-
]}
27+
defimpl Jason.Encoder, for: Codebattle.User do
28+
def encode(user, opts) do
29+
Jason.Encode.map(
30+
Map.take(user, [
31+
:id,
32+
:name,
33+
:rating,
34+
:is_bot,
35+
:guest,
36+
:github_id,
37+
:github_name,
38+
:lang,
39+
:editor_mode,
40+
:editor_theme,
41+
:achievements,
42+
:rank,
43+
:games_played,
44+
:performance,
45+
:inserted_at,
46+
:sound_settings,
47+
:discord_name,
48+
:discord_id,
49+
:discord_avatar
50+
])
51+
|> Map.put(:is_admin, Codebattle.User.is_admin?(user)),
52+
opts
53+
)
54+
end
55+
end
4956

5057
schema "users" do
5158
field(:name, :string)

services/app/lib/codebattle_web/channels/chat_channel.ex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ defmodule CodebattleWeb.ChatChannel do
4040
{:noreply, socket}
4141
end
4242

43-
def handle_in("chat:command", payload, socket) do
43+
def handle_in("chat:command", %{"command" => payload}, socket) do
4444
chat_type = get_chat_type(socket)
4545

4646
Chat.Server.command(chat_type, socket.assigns.current_user, %{
@@ -69,6 +69,10 @@ defmodule CodebattleWeb.ChatChannel do
6969
{:noreply, socket}
7070
end
7171

72+
def handle_in(_, _payload, socket) do
73+
{:noreply, socket}
74+
end
75+
7276
defp get_user_name(%{is_bot: true, name: name}), do: "#{name}(bot)"
7377
defp get_user_name(%{name: name}), do: name
7478

services/app/lib/codebattle_web/live/tournament/show_view.ex

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ defmodule CodebattleWeb.Live.Tournament.ShowView do
146146
end
147147

148148
def handle_event("kick", %{"user_id" => user_id}, socket) do
149-
if can_moderate?(socket.assigns.tournament, socket.assigns.current_user.id) do
149+
if Tournament.Helpers.can_moderate?(socket.assigns.tournament, socket.assigns.current_user) do
150150
Tournament.Server.update_tournament(socket.assigns.tournament.id, :leave, %{
151151
user_id: String.to_integer(user_id)
152152
})
@@ -156,7 +156,7 @@ defmodule CodebattleWeb.Live.Tournament.ShowView do
156156
end
157157

158158
def handle_event("back", _params, socket) do
159-
if can_moderate?(socket.assigns.tournament, socket.assigns.current_user.id) do
159+
if Tournament.Helpers.can_moderate?(socket.assigns.tournament, socket.assigns.current_user) do
160160
Tournament.Server.update_tournament(socket.assigns.tournament.id, :back, %{
161161
user: socket.assigns.current_user
162162
})
@@ -285,10 +285,6 @@ defmodule CodebattleWeb.Live.Tournament.ShowView do
285285
topic == topic_name(tournament)
286286
end
287287

288-
defp can_moderate?(tournament, user_id) do
289-
tournament.creator_id == user_id
290-
end
291-
292288
defp get_chat_messages(id) do
293289
try do
294290
Chat.Server.get_messages({:tournament, id})

services/app/test/codebattle/tournament/base_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ defmodule Codebattle.Tournament.BaseTest do
2121
assert get_player_ids(updated) == [user.id]
2222

2323
updated = @module.leave(updated, %{user: user})
24-
assert get_intended_player_ids(updated) == [user.id]
24+
assert get_intended_player_ids(updated) == []
2525
assert get_player_ids(updated) == []
2626

2727
updated = @module.back(updated, %{user: user})

services/app/test/codebattle_web/channels/chat_channel_test.exs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,10 @@ defmodule CodebattleWeb.ChatChannelTest do
123123
%{name: "alice", text: "invalid_content", time: _}
124124
] = Server.get_messages(:lobby)
125125

126-
push(socket2, "chat:command", %{"type" => "ban", "name" => "alice", "duration" => "3h"})
126+
push(socket2, "chat:command", %{
127+
"command" => %{"type" => "ban", "name" => "alice", "duration" => "3h"}
128+
})
129+
127130
:timer.sleep(50)
128131

129132
assert [

0 commit comments

Comments
 (0)