Skip to content

Commit e31030f

Browse files
committed
added sorting of the list of opponents: online users are displayed before offline users.
1 parent 9e5cb67 commit e31030f

1 file changed

Lines changed: 79 additions & 32 deletions

File tree

services/app/apps/codebattle/assets/js/widgets/pages/lobby/CreateGameDialog.jsx

Lines changed: 79 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -35,29 +35,68 @@ const unchosenTask = { id: null };
3535
const OpponentSelect = memo(({ setOpponent, opponent }) => {
3636
const dispatch = useDispatch();
3737
const currentUserId = useSelector(selectors.currentUserIdSelector);
38+
const { presenceList } = useSelector(selectors.lobbyDataSelector);
39+
console.log('presenceList:', presenceList);
40+
const loadOptions = useCallback(
41+
(inputValue, callback) => {
42+
const queryParamsString = qs.stringify({
43+
q: {
44+
name_ilike: inputValue,
45+
},
46+
});
3847

39-
const loadOptions = useCallback((inputValue, callback) => {
40-
const queryParamsString = qs.stringify({
41-
q: {
42-
name_ilike: inputValue,
43-
},
44-
});
48+
axios
49+
.get(`/api/v1/users?${queryParamsString}`)
50+
.then(({ data }) => {
51+
const { users: apiUsers } = camelizeKeys(data);
52+
const filteredApiUsers = apiUsers.filter(
53+
({ id }) => id !== currentUserId
54+
);
55+
const onlineUsersFromPresence = presenceList
56+
.map((p) => p.user)
57+
.filter((user) => user.id !== currentUserId);
58+
const combinedUsersMap = new Map();
4559

46-
axios
47-
.get(`/api/v1/users?${queryParamsString}`)
48-
.then(({ data }) => {
49-
const { users } = camelizeKeys(data);
60+
filteredApiUsers.forEach((user) => {
61+
const isOnline = presenceList.some(
62+
(presence) => String(presence.id) === String(user.id)
63+
);
64+
combinedUsersMap.set(user.id, { ...user, online: isOnline });
65+
});
5066

51-
const options = users
52-
.filter(({ id }) => currentUserId !== id)
53-
.map(user => ({ label: <UserLabel user={user} />, value: user }));
67+
onlineUsersFromPresence.forEach((onlineUser) => {
68+
if (!combinedUsersMap.has(onlineUser.id)) {
69+
combinedUsersMap.set(onlineUser.id, {
70+
...onlineUser,
71+
online: true,
72+
});
73+
}
74+
});
5475

55-
callback(options);
56-
})
57-
.catch(error => {
58-
dispatch(actions.setError(error));
59-
});
60-
}, [currentUserId, dispatch]);
76+
const combinedUsers = Array.from(combinedUsersMap.values());
77+
78+
const sortedUsers = combinedUsers.sort((a, b) => {
79+
const aOnline = a.online;
80+
const bOnline = b.online;
81+
if (aOnline === bOnline) {
82+
return 0;
83+
}
84+
return aOnline ? -1 : 1;
85+
});
86+
87+
const options = sortedUsers.map((user) => ({
88+
label: <UserLabel user={user} />,
89+
value: user,
90+
}));
91+
92+
callback(options);
93+
})
94+
.catch((error) => {
95+
dispatch(actions.setError(error));
96+
});
97+
},
98+
[currentUserId, dispatch, presenceList]
99+
);
61100

62101
return (
63102
<AsyncSelect
@@ -76,22 +115,22 @@ const OpponentSelect = memo(({ setOpponent, opponent }) => {
76115
});
77116

78117
const LevelButtonGroup = memo(({ value, onChange }) => {
79-
const getLevelClassName = level => {
118+
const getLevelClassName = (level) => {
80119
const isLevelActive = level === value;
81120
return cn('btn border-0 mb-2 rounded-lg', {
82121
'bg-orange': isLevelActive,
83122
'btn-outline-orange': !isLevelActive,
84123
});
85124
};
86125

87-
const changeGameLevel = level => {
126+
const changeGameLevel = (level) => {
88127
if (level === value) return;
89128
onChange(level);
90129
};
91130

92131
return (
93132
<div className="d-flex justify-content-around px-sm-3 px-md-5">
94-
{gameLevels.map(level => (
133+
{gameLevels.map((level) => (
95134
<button
96135
key={level}
97136
type="button"
@@ -109,7 +148,7 @@ const LevelButtonGroup = memo(({ value, onChange }) => {
109148
});
110149

111150
const GameTypeButtonGroup = memo(({ value, onChange }) => {
112-
const getGameTypeClassName = gameType => {
151+
const getGameTypeClassName = (gameType) => {
113152
const isGameTypeActive = gameType === value;
114153
return cn('btn mr-1 mb-1 mb-sm-0 rounded-lg text-nowrap', {
115154
'bg-orange text-white': isGameTypeActive,
@@ -119,7 +158,7 @@ const GameTypeButtonGroup = memo(({ value, onChange }) => {
119158

120159
return (
121160
<div className="d-flex flex-wrap flex-sm-nowrap justify-content-around px-sm-3 px-md-5 mt-3">
122-
{gameTypeCodes.map(gameTypeCode => (
161+
{gameTypeCodes.map((gameTypeCode) => (
123162
<button
124163
key={gameTypeCode}
125164
type="button"
@@ -135,7 +174,9 @@ const GameTypeButtonGroup = memo(({ value, onChange }) => {
135174

136175
function CreateGameDialog({ hideModal }) {
137176
const dispatch = useDispatch();
138-
const { gameOptions: givenGameOptions, opponentInfo } = useSelector(selectors.modalSelector);
177+
const { gameOptions: givenGameOptions, opponentInfo } = useSelector(
178+
selectors.modalSelector
179+
);
139180
const [opponent, setOpponent] = useState(opponentInfo);
140181
const [chosenTask, setChosenTask] = useState(unchosenTask);
141182
const [chosenTags, setChosenTags] = useState([]);
@@ -148,13 +189,19 @@ function CreateGameDialog({ hideModal }) {
148189
const isInvite = gameType === 'invite';
149190
const isTaskChosen = chosenTask.id !== null;
150191

151-
const handleTimeoutChange = useCallback(e => setGameTimeout(e.target.value * 60), [setGameTimeout]);
192+
const handleTimeoutChange = useCallback(
193+
(e) => setGameTimeout(e.target.value * 60),
194+
[setGameTimeout]
195+
);
152196

153-
const switchGameLevel = useCallback(level => {
154-
setGameLevel(level);
155-
setChosenTask(unchosenTask);
156-
setChosenTags([]);
157-
}, [setGameLevel, setChosenTask, setChosenTags]);
197+
const switchGameLevel = useCallback(
198+
(level) => {
199+
setGameLevel(level);
200+
setChosenTask(unchosenTask);
201+
setChosenTags([]);
202+
},
203+
[setGameLevel, setChosenTask, setChosenTags]
204+
);
158205

159206
const createGame = () => {
160207
if (isInvite && opponent) {
@@ -166,7 +213,7 @@ function CreateGameDialog({ hideModal }) {
166213
recipient_name: opponent.name,
167214
task_id: chosenTask.id,
168215
task_tags: isTaskChosen ? [] : chosenTags,
169-
}),
216+
})
170217
);
171218
} else if (!isInvite) {
172219
lobbyMiddlewares.createGame({

0 commit comments

Comments
 (0)