Skip to content

Commit f85e0a4

Browse files
committed
add stream widget
1 parent 4c5a04a commit f85e0a4

File tree

7 files changed

+335
-26
lines changed

7 files changed

+335
-26
lines changed

services/app/apps/codebattle/assets/css/style.scss

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,3 +2494,81 @@ a:hover {
24942494
color: white;
24952495
padding-right: 25px;
24962496
}
2497+
2498+
.cb-stream-tasks-stats {
2499+
background-color: #FAFF0F;
2500+
padding: 20px 16px;
2501+
border-radius: 25px;
2502+
}
2503+
2504+
.cb-stream-output-title {
2505+
background-color: #FAFF0F;
2506+
width: 151px;
2507+
height: 69px;
2508+
2509+
min-width: 151px;
2510+
padding: 10px 16px;
2511+
border-radius: 25px;
2512+
}
2513+
2514+
.cb-stream-editor-panel {
2515+
border: 4px solid #3C4168;
2516+
}
2517+
2518+
.cb-stream-editor-left {
2519+
border-top-left-radius: 25px;
2520+
border-right: 0px;
2521+
border-bottom: 0px;
2522+
}
2523+
2524+
.cb-stream-editor-right {
2525+
border-top-right-radius: 25px;
2526+
border-left: 0px;
2527+
border-bottom: 0px;
2528+
}
2529+
2530+
.cb-stream-name {
2531+
width: 118px;
2532+
color: #FAFF0F;
2533+
}
2534+
2535+
.cb-stream-output {
2536+
min-width: 450px;
2537+
border: 4px solid #3C4168;
2538+
border-radius: 25px;
2539+
}
2540+
2541+
.cb-stream-task-description {
2542+
color: #B6A4FF;
2543+
}
2544+
2545+
.cb-stream-widget {
2546+
background-color: #000000;
2547+
}
2548+
2549+
.cb-stream-output-data {
2550+
color: #B6A4FF;
2551+
overflow: hidden;
2552+
}
2553+
2554+
.cb-stream-full-video {
2555+
border: 4px solid #3C4168;
2556+
border-radius: 25px;
2557+
}
2558+
2559+
.cb-stream-full-editor {
2560+
border: 4px solid #3C4168;
2561+
border-radius: 25px;
2562+
}
2563+
2564+
.editor-left {
2565+
border-top-left-radius: 25px;
2566+
border-right: 0px;
2567+
border-bottom: 0px;
2568+
}
2569+
2570+
.editor-right {
2571+
border-top-right-radius: 25px;
2572+
border-left: 0px;
2573+
border-bottom: 0px;
2574+
}

services/app/apps/codebattle/assets/js/widgets/App.jsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,12 @@ export const StreamPage = () => (
237237
<Provider store={store}>
238238
<PersistGate loading={null} persistor={persistor}>
239239
<Suspense>
240-
<Stream />
240+
<Stream
241+
mainMachine={mainMachine}
242+
waitingRoomMachine={waitingRoomMachine}
243+
taskMachine={taskMachine}
244+
editorMachine={editorMachine}
245+
/>
241246
</Suspense>
242247
</PersistGate>
243248
</Provider>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from 'react';
2+
3+
import { useSelector } from 'react-redux';
4+
5+
import { leftEditorSelector, rightEditorSelector } from '@/selectors';
6+
7+
import ExtendedEditor from '../../components/Editor';
8+
import editorThemes from '../../config/editorThemes';
9+
10+
function StreamEditorPanel({ orientation, roomMachineState }) {
11+
const editorSelector = orientation === 'left' ? leftEditorSelector : rightEditorSelector;
12+
13+
const editor = useSelector(editorSelector(roomMachineState));
14+
const editorParams = {
15+
editable: false,
16+
syntax: editor?.currentLangSlug,
17+
theme: editorThemes.dark,
18+
mute: true,
19+
loading: false,
20+
value: editor?.text,
21+
lineNumbers: false,
22+
wordWrap: 'on',
23+
};
24+
25+
return (
26+
<div className={`col-8 cb-stream-editor-panel p-4 cb-stream-editor-${orientation}`}>
27+
<div className="d-flex flex-column flex-grow-1 position-relative cb-editor-height h-100">
28+
<ExtendedEditor {...editorParams} />
29+
</div>
30+
</div>
31+
);
32+
}
33+
34+
export default StreamEditorPanel;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import React from 'react';
2+
3+
import { useSelector } from 'react-redux';
4+
5+
import ExtendedEditor from '@/components/Editor';
6+
import {
7+
leftEditorSelector, rightEditorSelector,
8+
} from '@/selectors';
9+
10+
import editorThemes from '../../config/editorThemes';
11+
import TaskDescriptionMarkdown from '../game/TaskDescriptionMarkdown';
12+
13+
function StreamFullPanel({ game, roomMachineState }) {
14+
const leftEditor = useSelector(leftEditorSelector(roomMachineState));
15+
const rightEditor = useSelector(rightEditorSelector(roomMachineState));
16+
// const leftOutput = useSelector(leftExecutionOutputSelector(roomMachineState));
17+
// const rightOutput = useSelector(rightExecutionOutputSelector(roomMachineState));
18+
19+
const editorLeftParams = {
20+
editable: false,
21+
syntax: leftEditor?.currentLangSlug,
22+
theme: editorThemes.dark,
23+
mute: true,
24+
loading: false,
25+
value: leftEditor?.text,
26+
lineNumbers: false,
27+
wordWrap: 'on',
28+
};
29+
const editorRightParams = {
30+
editable: false,
31+
syntax: rightEditor?.currentLangSlug,
32+
theme: editorThemes.dark,
33+
mute: true,
34+
loading: false,
35+
value: rightEditor?.text,
36+
lineNumbers: false,
37+
wordWrap: 'on',
38+
};
39+
40+
return (
41+
<div className="d-flex col-12 flex-column w-100 h-100 cb-stream-full-info">
42+
<div className="d-flex w-100 justify-content-between pb-3 px-2">
43+
<div className="cb-stream-tasks-stats">
44+
<span>3/8 Задача</span>
45+
</div>
46+
<div className="cb-stream-task-description h-100 w-100 px-2">
47+
<TaskDescriptionMarkdown description={game?.task?.descriptionRu} />
48+
</div>
49+
<div className="d-flex flex-column pb-4">
50+
<div className="d-flex cb-stream-output mt-2 mb-1">
51+
<div className="d-flex align-items-center cb-stream-output-title">Входные данные</div>
52+
<div />
53+
</div>
54+
<div className="d-flex cb-stream-output mt-2 mb-1">
55+
<div className="d-flex align-items-center cb-stream-output-title">Ожидаемые данные</div>
56+
<div />
57+
</div>
58+
</div>
59+
</div>
60+
<div className="d-flex w-100 h-100 cb-stream-full-editors">
61+
<div className="col-4 cb-stream-full-editor editor-right">
62+
<div className="d-flex flex-column flex-grow-1 position-relative cb-editor-height h-100">
63+
<ExtendedEditor {...editorLeftParams} />
64+
</div>
65+
</div>
66+
<div className="col-4 cb-stream-full-video px-2">stream</div>
67+
<div className="col-4 cb-stream-full-editor editor-right">
68+
<div className="d-flex flex-column flex-grow-1 position-relative cb-editor-height h-100">
69+
<ExtendedEditor {...editorRightParams} />
70+
</div>
71+
</div>
72+
</div>
73+
</div>
74+
);
75+
}
76+
77+
export default StreamFullPanel;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react';
2+
3+
import upperCase from 'lodash/upperCase';
4+
import { useSelector } from 'react-redux';
5+
6+
import {
7+
firstPlayerSelector, leftExecutionOutputSelector, rightExecutionOutputSelector, secondPlayerSelector,
8+
} from '@/selectors';
9+
10+
import TaskDescriptionMarkdown from '../game/TaskDescriptionMarkdown';
11+
12+
function StreamTaskInfoPanel({ game, orientation, roomMachineState }) {
13+
const outputSelector = orientation === 'left' ? leftExecutionOutputSelector : rightExecutionOutputSelector;
14+
const playerSelector = orientation === 'left' ? firstPlayerSelector : secondPlayerSelector;
15+
16+
const output = useSelector(outputSelector(roomMachineState));
17+
const player = useSelector(playerSelector);
18+
19+
const assert = output?.asserts ? output.asserts[0] : {};
20+
21+
const args = assert?.arguments;
22+
const expected = assert?.expected;
23+
const result = assert?.result || assert?.value;
24+
25+
return (
26+
<div className="d-flex flex-column justify-content-between col-4">
27+
<div className="d-flex pt-4 justify-content-between">
28+
<div className="cb-stream-tasks-stats">
29+
<span>3/8 ЗАДАЧ</span>
30+
</div>
31+
{/* <div> */}
32+
{/* <span>3 / 8 Задача</span> */}
33+
{/* </div> */}
34+
<div className="d-flex align-items-center cb-stream-name">
35+
<span>{upperCase(player?.name || 'Башкевич Илья')}</span>
36+
</div>
37+
</div>
38+
<div className="cb-stream-task-description h-100 py-5">
39+
<TaskDescriptionMarkdown description={game?.task?.descriptionRu} />
40+
</div>
41+
<div className="d-flex flex-column pb-4">
42+
<div className="d-flex cb-stream-output mt-2 mb-1">
43+
<div className="d-flex align-items-center cb-stream-output-title">Входные данные</div>
44+
<div className="cb-stream-output-data align-content-around">{args}</div>
45+
</div>
46+
<div className="d-flex cb-stream-output mb-1">
47+
<div className="d-flex align-items-center cb-stream-output-title">Ожидаемый результат</div>
48+
<div className="cb-stream-output-data align-content-around">{expected}</div>
49+
</div>
50+
<div className="d-flex cb-stream-output mt-1 mb-2">
51+
<div className="d-flex align-items-center cb-stream-output-title">Полученный результат</div>
52+
<div className="cb-stream-output-data align-content-around">{result}</div>
53+
</div>
54+
</div>
55+
</div>
56+
);
57+
}
58+
59+
export default StreamTaskInfoPanel;

services/app/apps/codebattle/assets/js/widgets/pages/stream/StreamWidget.jsx

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,90 @@ import React, { useEffect } from 'react';
33
import { useDispatch, useSelector } from 'react-redux';
44

55
import { connectToGame, setGameChannel } from '@/middlewares/Room';
6+
import useGameRoomMachine from '@/utils/useGameRoomMachine';
7+
import useMachineStateSelector from '@/utils/useMachineStateSelector';
8+
import useSearchParams from '@/utils/useSearchParams';
69

10+
import * as machineSelectors from '../../machines/selectors';
711
import { connectToStream } from '../../middlewares/Stream';
812

9-
function StreamWidget({ gameService, waitingRoomService }) {
13+
import StreamEditorPanel from './StreamEditorPanel';
14+
import StreamFullPanel from './StreamFullPanel';
15+
import StreamTaskInfoPanel from './StreamTaskInfoPanel';
16+
17+
const orientations = {
18+
NONE: 'none',
19+
LEFT: 'left',
20+
RIGHT: 'right',
21+
};
22+
23+
function StreamWidget({
24+
mainMachine,
25+
waitingRoomMachine,
26+
taskMachine,
27+
}) {
1028
const dispatch = useDispatch();
11-
const gameId = useSelector(state => state.game.id);
29+
const game = useSelector(state => state.game);
30+
const searchParams = useSearchParams();
31+
const orientation = searchParams.has('orientation') ? searchParams.get('orientation') : orientations.NONE;
32+
33+
const { mainService, waitingRoomService } = useGameRoomMachine({
34+
mainMachine,
35+
taskMachine,
36+
waitingRoomMachine,
37+
});
38+
39+
const roomMachineState = useMachineStateSelector(
40+
mainService,
41+
machineSelectors.roomStateSelector,
42+
);
1243

13-
console.log(gameId);
1444
useEffect(() => {
1545
dispatch(connectToStream());
1646
}, []);
1747

1848
useEffect(() => {
19-
const channel = setGameChannel(gameId);
20-
21-
if (gameId) {
22-
const options = { cancelRedirect: true };
23-
connectToGame(gameService, waitingRoomService, options)(dispatch);
49+
if (!game.id) {
50+
return () => { };
2451
}
2552

53+
const channel = setGameChannel(game.id);
54+
55+
const options = { cancelRedirect: true };
56+
connectToGame(mainService, waitingRoomService, options)(dispatch);
57+
2658
const clearChannel = () => {
2759
if (channel) {
2860
channel.leave();
2961
}
3062
};
3163

3264
return clearChannel;
33-
}, [gameId, gameService, waitingRoomService, dispatch]);
65+
}, [game.id, mainService, waitingRoomService, dispatch]);
66+
67+
if (!game.id) {
68+
return <div className="vh-100 cb-stream-widget" />;
69+
}
3470

35-
return <div>Stream Widget</div>;
71+
return (
72+
<div className="vh-100 p-2 cb-stream-widget">
73+
{orientations.NONE === orientation && (
74+
<StreamFullPanel game={game} roomMachineState={roomMachineState} />
75+
)}
76+
{orientations.LEFT === orientation && (
77+
<div className="d-flex w-100 h-100">
78+
<StreamTaskInfoPanel game={game} orientation={orientation} roomMachineState={roomMachineState} />
79+
<StreamEditorPanel orientation={orientation} roomMachineState={roomMachineState} />
80+
</div>
81+
)}
82+
{orientations.RIGHT === orientation && (
83+
<div className="d-flex w-100 h-100">
84+
<StreamEditorPanel orientation={orientation} roomMachineState={roomMachineState} />
85+
<StreamTaskInfoPanel game={game} orientation={orientation} roomMachineState={roomMachineState} />
86+
</div>
87+
)}
88+
</div>
89+
);
3690
}
3791

3892
export default StreamWidget;

0 commit comments

Comments
 (0)