Skip to content

Commit a762493

Browse files
committed
feat(): create event page
1 parent f70e773 commit a762493

File tree

6 files changed

+289
-5
lines changed

6 files changed

+289
-5
lines changed

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@
2929
"electron-squirrel-startup": "^1.0.0",
3030
"electron-webpack": "^2.8.2",
3131
"electronmon": "^1.1.2",
32+
"material-ui-numeric-input": "^3.1.1",
3233
"react": "^16.13.1",
3334
"react-dom": "^16.13.1",
3435
"react-icons": "^4.3.1",
36+
"react-input-number": "^5.0.19",
37+
"react-numeric-input": "^2.2.3",
3538
"react-ranger": "^2.1.0",
3639
"react-router-dom": "^6.0.2",
3740
"react-scripts": "3.4.1",
@@ -84,7 +87,8 @@
8487
"devDependencies": {
8588
"cross-env": "^7.0.3",
8689
"electron": "^19.0.7",
87-
"electron-builder": "^22.10.5"
90+
"electron-builder": "^22.10.5",
91+
"react-error-overlay": "6.0.9"
8892
},
8993
"build": {
9094
"appId": "easystream.client",

src/Components/App/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Product } from '../Product/Product'
1212
import { Report } from '../Report/Report'
1313
import { MicsLevel } from '../MicsLevel/MicsLevel';
1414
import { WordDetection } from '../WordDetection/WordDetection';
15+
import { GeneralEvent } from '../Events/GeneralEvent';
1516
import { AllMics, resultFormat } from '../../Socket/interfaces';
1617
const ipcRenderer = window.require('electron').ipcRenderer
1718

@@ -71,6 +72,7 @@ export default function App() {
7172
<Route path='/products' element={<Product/>} />
7273
<Route path='/audio/mics-level' element={<MicsLevel/>} />
7374
<Route path='/audio/word-detection' element={<WordDetection/>} />
75+
<Route path='/events/general' element={<GeneralEvent/>} />
7476
</Routes>
7577
</div>
7678
</Router>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
body {
2+
margin: 0
3+
}
4+
5+
.events-container {
6+
text-align: center;
7+
}
8+
9+
.card-event {
10+
background-color: black;
11+
border-color: grey;
12+
}
13+
14+
.add_button_pos {
15+
top: calc(100% - 20%);
16+
left: calc(100% - 20%);
17+
position: absolute;
18+
}
19+
20+
.add_button {
21+
font-size: 25px !important;
22+
}
23+
24+
.rightAlignItem {
25+
justify-content: flex-end;
26+
}
27+
28+
.MuiCardActions-root{
29+
padding: 0 !important;
30+
}
31+
32+
.form-item {
33+
padding: 10px;
34+
}
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
import React from 'react';
2+
import './GeneralEvent.css';
3+
import Card from '@mui/material/Card';
4+
import CardActions from '@mui/material/CardActions';
5+
import CardContent from '@mui/material/CardContent';
6+
import Button from '@mui/material/Button';
7+
import Typography from '@mui/material/Typography';
8+
import { AiOutlineBug, AiOutlinePlayCircle, AiOutlineSound, AiOutlineStop, AiOutlineVideoCamera } from 'react-icons/ai';
9+
import { MdPanoramaHorizontal } from 'react-icons/md';
10+
import { IconButton, InputLabel, MenuItem, Select, SelectChangeEvent } from '@mui/material';
11+
import { BsTrash } from 'react-icons/bs';
12+
import TextField from '@mui/material/TextField';
13+
import Dialog from '@mui/material/Dialog';
14+
import DialogActions from '@mui/material/DialogActions';
15+
import DialogContent from '@mui/material/DialogContent';
16+
import DialogContentText from '@mui/material/DialogContentText';
17+
import DialogTitle from '@mui/material/DialogTitle';
18+
import NumericInput from 'material-ui-numeric-input';
19+
20+
export enum EventType {
21+
ChangeCamera,
22+
ChangeScene,
23+
StartLive,
24+
StopLive,
25+
ActivateSoundboard
26+
}
27+
28+
export const GeneralEvent = () => {
29+
30+
const keysEventType = Object.keys(EventType).filter(k => typeof EventType[k as any] === "number");
31+
const valuesEventType = keysEventType.map(k => EventType[k as any]);
32+
33+
const [open, setOpen] = React.useState(false);
34+
const [newEventName, setNewEventName] = React.useState("");
35+
const [newEventSelected, setNewEventSelected] = React.useState(0);
36+
const [newEventParam, setNewEventParam] = React.useState(0)
37+
38+
const handleOnChangeSelect = (event: SelectChangeEvent<unknown>) => {
39+
const value = event.target.value as EventType;
40+
setNewEventSelected(value);
41+
};
42+
43+
const handleClickOpen = () => {
44+
setOpen(true);
45+
};
46+
47+
const [ exampleEvents, setExampleEvents ] = React.useState([
48+
{
49+
id: 1,
50+
name: "Change to camera 2",
51+
event: EventType.ChangeCamera,
52+
param_value: 2
53+
},
54+
{
55+
id: 4,
56+
name: "Cut the live with 30delay",
57+
event: EventType.StopLive,
58+
param_value: 30
59+
},
60+
{
61+
id: 5,
62+
name: "LoL Sound",
63+
event: EventType.ActivateSoundboard,
64+
param_value: 8
65+
}
66+
])
67+
68+
const handleSave = () => {
69+
console.log("newEventName", newEventName);
70+
console.log("newEventSelected", newEventSelected);
71+
console.log("newEventParam", newEventParam);
72+
if (newEventName !== "") {
73+
let newElem: any = {
74+
id: Math.max(...exampleEvents.map(o => o.id)) + 1,
75+
name: newEventName,
76+
event: newEventSelected as EventType,
77+
}
78+
if (newEventParam) {
79+
newElem.param_value = newEventParam;
80+
}
81+
82+
const newList = exampleEvents.concat([newElem]);
83+
84+
setExampleEvents(newList);
85+
alert("Event saved");
86+
} else {
87+
// Put alert
88+
alert("Missing parameters");
89+
}
90+
setNewEventName("");
91+
setNewEventSelected(0);
92+
setNewEventParam(0);
93+
setOpen(false);
94+
};
95+
96+
const handleCancel = () => {
97+
setOpen(false);
98+
}
99+
100+
101+
function deleteEvent(id: number) {
102+
const newList = exampleEvents.filter((item) => item.id !== id);
103+
104+
setExampleEvents(newList);
105+
}
106+
107+
function getEvent(eventEnum: any) {
108+
if (eventEnum === EventType.ActivateSoundboard)
109+
return "Activate Soundboard";
110+
if (eventEnum === EventType.ChangeCamera)
111+
return "Change the camera"
112+
if (eventEnum === EventType.ChangeScene)
113+
return "Change the scene"
114+
if (eventEnum === EventType.StartLive)
115+
return "Start the live"
116+
if (eventEnum === EventType.StopLive)
117+
return "Stop the live"
118+
return ""
119+
}
120+
121+
function getIcon(eventEnum: EventType) {
122+
if (eventEnum === EventType.ActivateSoundboard)
123+
return <AiOutlineSound />
124+
if (eventEnum === EventType.ChangeCamera)
125+
return <AiOutlineVideoCamera />
126+
if (eventEnum === EventType.ChangeScene)
127+
return <MdPanoramaHorizontal />
128+
if (eventEnum === EventType.StartLive)
129+
return <AiOutlinePlayCircle />
130+
if (eventEnum === EventType.StopLive)
131+
return <AiOutlineStop />
132+
return <AiOutlineBug />
133+
}
134+
135+
return (
136+
<>
137+
<div className="container events-container">
138+
139+
<h2>List of Events</h2>
140+
141+
{
142+
exampleEvents.length === 0 ? (
143+
<>
144+
<h4>No events found.</h4>
145+
</>
146+
) : (exampleEvents.map((item, index) => {
147+
return (
148+
<Card key={index} className="card-event" sx={{ minWidth: 150, minHeight: 100, margin: 2 }}>
149+
<CardContent>
150+
<Typography variant="h5" component="div">
151+
{ getIcon(item.event) } "{ item.name }"
152+
</Typography>
153+
<Typography sx={{ mb: 1.5 }} color="text.secondary">
154+
{ getEvent(item.event) }
155+
</Typography>
156+
<Typography variant="body2">
157+
{ item.param_value ? "Parameter:" + item.param_value : "" }
158+
</Typography>
159+
</CardContent>
160+
<CardActions disableSpacing className="rightAlignItem">
161+
<IconButton onClick={() => deleteEvent(item.id)} aria-label="delete">
162+
<BsTrash />
163+
</IconButton>
164+
</CardActions>
165+
</Card>
166+
)
167+
}))
168+
}
169+
170+
</div>
171+
172+
<Dialog open={open} onClose={handleCancel}>
173+
<DialogTitle>Add Event</DialogTitle>
174+
<DialogContent>
175+
<DialogContentText>
176+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
177+
Aenean hendrerit, nisl ut mollis placerat, lorem risus feugiat purus, quis tincidunt nisi ipsum eu risus.
178+
Nulla at mollis tortor. Morbi accumsan mauris ac euismod tempor.
179+
Curabitur non consequat dolor. Nunc ut blandit tortor.
180+
Pellentesque viverra volutpat est, vel hendrerit neque elementum nec.
181+
</DialogContentText>
182+
183+
<div className="form-item">
184+
<TextField
185+
autoFocus
186+
id="name"
187+
label="Name of the event"
188+
type="text"
189+
value={newEventName}
190+
variant="standard"
191+
onChange={(newValue) => setNewEventName(newValue.target.value)}
192+
/>
193+
</div>
194+
195+
<div className="form-item">
196+
<InputLabel id="select-event-label">Event</InputLabel>
197+
<Select
198+
labelId="select-event-label"
199+
id="select-event"
200+
value={newEventSelected}
201+
onChange={handleOnChangeSelect}
202+
autoWidth
203+
label="Event"
204+
>
205+
{
206+
keysEventType.map((k) => {
207+
return (<MenuItem key={EventType[k as any]} value={EventType[k as any]}>{getEvent(EventType[k as any])}</MenuItem>)
208+
})
209+
}
210+
</Select>
211+
</div>
212+
213+
<div className="form-item">
214+
<NumericInput
215+
name='Parameter event'
216+
precision={0}
217+
decimalChar=','
218+
thousandChar='.'
219+
label='Parameter event'
220+
onChange={(event) => setNewEventParam(event.target.value as number)}
221+
variant='outlined'
222+
/>
223+
</div>
224+
225+
</DialogContent>
226+
<DialogActions>
227+
<Button onClick={handleCancel}>Cancel</Button>
228+
<Button onClick={handleSave}>Save</Button>
229+
</DialogActions>
230+
</Dialog>
231+
232+
<div className="add_button_pos">
233+
<Button variant="contained" className="add_button" onClick={handleClickOpen}
234+
>
235+
Add Event
236+
</Button>
237+
</div>
238+
</>
239+
);
240+
}

src/Components/Home/Home.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ export const Home = () => {
1010
return (
1111
<>
1212
<h1> Home</h1>
13-
<Link to="/reports">reports</Link>
14-
<Link to="/products">products</Link>
15-
<Link to="/audio/mics-level">Mics Level</Link>
16-
<Link to="/audio/word-detection">Word Detection</Link>
13+
<Link className="m-2" to="/reports">Reports</Link>
14+
<Link className="m-2" to="/products">Products</Link>
15+
<Link className="m-2" to="/audio/mics-level">Mics Level</Link>
16+
<Link className="m-2" to="/audio/word-detection">Word Detection</Link>
17+
<Link className="m-2" to="/events/general">Generate Event</Link>
1718
</>
1819
);
1920
}

src/index.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ body {
1919
code {
2020
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
2121
}
22+
.m-2{
23+
margin: 6px;
24+
}

0 commit comments

Comments
 (0)