From 2e62f52c46b27d71ec52257fb9faf22607d09f6c Mon Sep 17 00:00:00 2001 From: Alina Lobova Date: Tue, 15 Apr 2025 01:40:50 +0300 Subject: [PATCH] Sort opponent list: online users appear before offline users --- .../widgets/pages/lobby/CreateGameDialog.jsx | 78 ++++++++++++------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/services/app/apps/codebattle/assets/js/widgets/pages/lobby/CreateGameDialog.jsx b/services/app/apps/codebattle/assets/js/widgets/pages/lobby/CreateGameDialog.jsx index 69fec409f..d7f567b2a 100644 --- a/services/app/apps/codebattle/assets/js/widgets/pages/lobby/CreateGameDialog.jsx +++ b/services/app/apps/codebattle/assets/js/widgets/pages/lobby/CreateGameDialog.jsx @@ -35,29 +35,41 @@ const unchosenTask = { id: null }; const OpponentSelect = memo(({ setOpponent, opponent }) => { const dispatch = useDispatch(); const currentUserId = useSelector(selectors.currentUserIdSelector); - - const loadOptions = useCallback((inputValue, callback) => { - const queryParamsString = qs.stringify({ - q: { - name_ilike: inputValue, - }, - }); - - axios - .get(`/api/v1/users?${queryParamsString}`) - .then(({ data }) => { - const { users } = camelizeKeys(data); - - const options = users - .filter(({ id }) => currentUserId !== id) - .map(user => ({ label: , value: user })); - - callback(options); - }) - .catch(error => { - dispatch(actions.setError(error)); + const { presenceList } = useSelector(selectors.lobbyDataSelector); + + const loadOptions = useCallback( + (inputValue, callback) => { + const queryParamsString = qs.stringify({ + q: { + name_ilike: inputValue, + }, }); - }, [currentUserId, dispatch]); + + axios + .get(`/api/v1/users?${queryParamsString}`) + .then(({ data }) => { + const { users } = camelizeKeys(data); + + const options = users + .filter(({ id }) => currentUserId !== id) + .map(user => ({ + ...user, + isOnline: presenceList.some(p => p.id === user.id), + })) + .sort((a, b) => Number(b.isOnline) - Number(a.isOnline)) + .map(user => ({ + label: , + value: user, + })); + + callback(options); + }) + .catch(error => { + dispatch(actions.setError(error)); + }); + }, + [currentUserId, dispatch, presenceList], + ); return ( { function CreateGameDialog({ hideModal }) { const dispatch = useDispatch(); - const { gameOptions: givenGameOptions, opponentInfo } = useSelector(selectors.modalSelector); + const { gameOptions: givenGameOptions, opponentInfo } = useSelector( + selectors.modalSelector, + ); const [opponent, setOpponent] = useState(opponentInfo); const [chosenTask, setChosenTask] = useState(unchosenTask); const [chosenTags, setChosenTags] = useState([]); @@ -148,13 +162,19 @@ function CreateGameDialog({ hideModal }) { const isInvite = gameType === 'invite'; const isTaskChosen = chosenTask.id !== null; - const handleTimeoutChange = useCallback(e => setGameTimeout(e.target.value * 60), [setGameTimeout]); + const handleTimeoutChange = useCallback( + e => setGameTimeout(e.target.value * 60), + [setGameTimeout], + ); - const switchGameLevel = useCallback(level => { - setGameLevel(level); - setChosenTask(unchosenTask); - setChosenTags([]); - }, [setGameLevel, setChosenTask, setChosenTags]); + const switchGameLevel = useCallback( + level => { + setGameLevel(level); + setChosenTask(unchosenTask); + setChosenTags([]); + }, + [setGameLevel, setChosenTask, setChosenTags], + ); const createGame = () => { if (isInvite && opponent) {