Skip to content

Commit 5ab637e

Browse files
committed
Fix group tasks
1 parent ec85690 commit 5ab637e

27 files changed

Lines changed: 657 additions & 639 deletions

apps/codebattle/assets/js/socket.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export const channelTopics = {
7474
tournamentPlayerFinishedTopic: "tournament:player:finished",
7575
tournamentActivated: "tournament:activated",
7676
tournamentCanceled: "tournament:canceled",
77+
groupTournamentRunUpdated: "group_tournament:run_updated",
7778
deployHandoffStarted: "deploy:handoff_started",
7879
deployHandoffDone: "deploy:handoff_done",
7980
deployHandoffFailed: "deploy:handoff_failed",

apps/codebattle/assets/js/widgets/middlewares/GroupTournament.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { camelizeKeys } from "humps";
22

3-
import { channelMethods } from "../../socket";
3+
import { channelMethods, channelTopics } from "../../socket";
44
import { actions } from "../slices";
55

66
import Channel from "./Channel";
@@ -12,7 +12,7 @@ export const setTournamentChannel = (tournamentId) => {
1212
return channel.setupChannel(newChannelName);
1313
};
1414

15-
export const connectToTournament = () => (dispatch) => {
15+
export const connectToTournament = (currentUserId) => (dispatch) => {
1616
if (!channel) {
1717
console.error("Channel not initialized");
1818
return;
@@ -65,6 +65,29 @@ export const connectToTournament = () => (dispatch) => {
6565

6666
channel.join().receive("ok", onJoinSuccess).receive("error", onJoinFailure);
6767

68+
const handleRunUpdated = (response) => {
69+
const latestSolutionEntry = response.solution || null;
70+
const currentUserSolution =
71+
latestSolutionEntry && latestSolutionEntry.userId === currentUserId
72+
? latestSolutionEntry
73+
: null;
74+
75+
dispatch(
76+
actions.applyRunUpdate({
77+
groupTournament: response.groupTournament,
78+
run: response.run,
79+
latestSolutionEntry,
80+
solution: currentUserSolution,
81+
}),
82+
);
83+
84+
if (response.run?.id) {
85+
dispatch(actions.addLog(`Run #${response.run.id} ${response.run.status}`));
86+
}
87+
};
88+
89+
channel.addListener(channelTopics.groupTournamentRunUpdated, handleRunUpdated);
90+
6891
return channel;
6992
};
7093

apps/codebattle/assets/js/widgets/slices/groupTournament.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,39 @@ const groupTournament = createSlice({
6464
setData: (state, { payload }) => {
6565
state.data = payload;
6666
},
67+
applyRunUpdate: (state, { payload }) => {
68+
const { groupTournament, run, solution, latestSolutionEntry } = payload;
69+
70+
state.data = state.data || {};
71+
72+
if (groupTournament) {
73+
state.data.groupTournament = {
74+
...(state.data.groupTournament || {}),
75+
...groupTournament,
76+
};
77+
}
78+
79+
if (run) {
80+
const currentRuns = state.data.runs || [];
81+
state.data.runs = [run, ...currentRuns.filter((item) => item.id !== run.id)];
82+
}
83+
84+
if (latestSolutionEntry) {
85+
state.data.latestSolutions = {
86+
...(state.data.latestSolutions || {}),
87+
[latestSolutionEntry.userId]: latestSolutionEntry,
88+
};
89+
}
90+
91+
if (solution) {
92+
const currentHistory = state.data.solutionHistory || [];
93+
state.data.solutionHistory = [
94+
solution,
95+
...currentHistory.filter((item) => item.id !== solution.id),
96+
];
97+
state.data.latestSolution = solution;
98+
}
99+
},
67100
resetGroupTournament: () => initialState,
68101
},
69102
});

apps/codebattle/assets/js/widgets/utils/useGroupTournamentChannel.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import { useEffect } from "react";
22

33
import { useDispatch } from "react-redux";
4+
import { useSelector } from "react-redux";
45

56
import * as TournamentActions from "../middlewares/GroupTournament";
7+
import * as selectors from "../selectors";
68

79
const useGroupTournamentChannel = (tournamentId) => {
810
const dispatch = useDispatch();
11+
const currentUserId = useSelector(selectors.currentUserIdSelector);
912

1013
useEffect(() => {
1114
if (!tournamentId) {
@@ -20,11 +23,11 @@ const useGroupTournamentChannel = (tournamentId) => {
2023
}
2124
};
2225

23-
TournamentActions.connectToTournament()(dispatch);
26+
TournamentActions.connectToTournament(currentUserId)(dispatch);
2427

2528
return clearTournamentChannel;
2629
// eslint-disable-next-line react-hooks/exhaustive-deps
27-
}, [dispatch, tournamentId]);
30+
}, [currentUserId, dispatch, tournamentId]);
2831
};
2932

3033
export default useGroupTournamentChannel;

apps/codebattle/lib/codebattle/group_task.ex

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ defmodule Codebattle.GroupTask do
55

66
import Ecto.Changeset
77

8-
alias Codebattle.GroupTaskRun
98
alias Codebattle.GroupTaskSolution
10-
alias Codebattle.GroupTaskToken
119

1210
@type t :: %__MODULE__{}
1311

@@ -16,9 +14,7 @@ defmodule Codebattle.GroupTask do
1614
field(:runner_url, :string)
1715
field(:time_to_solve_sec, :integer)
1816

19-
has_many(:runs, GroupTaskRun)
2017
has_many(:solutions, GroupTaskSolution)
21-
has_many(:tokens, GroupTaskToken)
2218

2319
timestamps()
2420
end

0 commit comments

Comments
 (0)