Skip to content

Commit cfba364

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

File tree

1 file changed

+73
-26
lines changed

1 file changed

+73
-26
lines changed

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

+73-26
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
@@ -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) {

0 commit comments

Comments
 (0)