diff --git a/public/electron.js b/public/electron.js index 72ca0b9..8f7dfd6 100644 --- a/public/electron.js +++ b/public/electron.js @@ -1,117 +1,224 @@ // Modules to control application life and create native browser window -const { app, BrowserWindow, ipcMain } = require('electron') -const path = require('path') -const isDev = require('electron-is-dev') -const { TCPConnection } = require('../src/Socket/socket.js'); +const { app, BrowserWindow, ipcMain } = require("electron"); +const path = require("path"); +const isDev = require("electron-is-dev"); +const { TCPConnection } = require("../src/Socket/socket.js"); let loadingScreen; let mainWindow; -let tcpConn = new TCPConnection('localhost', 47920); -tcpConn.connect() -.then((res) => { - console.log('TCPConnection is connected'); - launchingApplication(); - console.log('res', res); - return res; -}).catch(err => { - if (isDev) { - console.log('DEV MODE'); - return null; - } else { - console.log('Error Electron', err); - console.log('CHANGE HOST IP'); - return null; - } +let tcpConn = new TCPConnection("localhost", 47920); +tcpConn + .connect() + .then((res) => { + console.log("TCPConnection is connected"); + launchingApplication(); + console.log("res", res); + return res; + }) + .catch((err) => { + if (isDev) { + console.log("DEV MODE"); + return null; + } else { + console.log("Error Electron", err); + console.log("CHANGE HOST IP"); + return null; + } + }); + +const createWindow = () => { + // Create the browser window. + mainWindow = new BrowserWindow({ + webPreferences: { + nodeIntegration: true, // turn this off if you don't mean to use node + contextIsolation: false, + enableRemoteModule: isDev, + }, + autoHideMenuBar: true, + minWidth: 800, + minHeight: 600, + /// show to false mean than the window will proceed with its lifecycle, but will not render until we will show it up + show: false, + }); + + // load the index.html of the app. (or localhost on port 3000 if you're in development) + mainWindow.loadURL("http://localhost:3000"); + + mainWindow.on("closed", () => { + mainWindow = null; + }); + + /// keep listening on the did-finish-load event, when the mainWindow content has loaded + mainWindow.webContents.on("did-finish-load", () => { + /// then close the loading screen window and show the main window + if (loadingScreen) { + loadingScreen.close(); + } + mainWindow.maximize(); + mainWindow.show(); + }); +}; + +ipcMain.on("getAllMics", (event, arg) => { + if (isDev) { + let res = { + statusCode: 200, + message: "OK", + length: 1, + mics: [ + { + name: "Mic Test Dev", + level: 30, + isActive: true, + }, + ], + }; + event.returnValue = res; + return res; + } else { + return tcpConn.getAllMics().then((res) => { + console.log("getAllMics : " + res); + event.returnValue = res; + }); + } }); +ipcMain.on("getActReactCouples", (event, arg) => { + if (isDev) { + let res = { + statusCode: 200, + message: "OK", + length: 1, + actReacts: [ + { + actReactId: 1, + isActive: true, + action: { + actionId: 1, + type: "WORD_DETECT", + params: { + words: ['bouloubouga'] + } + }, + reaction: { + name: "Changement de caméra sur la caméra 1", + reactionId: 1, + type: "CAMERA_SWITCH", + params: { + "video-source": "camera_1" + } + } + }, + ], + }; + event.returnValue = res; + return res; + } else { + return tcpConn.getActReactCouples().then((res) => { + console.log("getActReactCouples : " + res); + event.returnValue = res; + }); + } +}); -const createWindow = () => { - // Create the browser window. - mainWindow = new BrowserWindow({ - webPreferences: { - nodeIntegration: true, // turn this off if you don't mean to use node - contextIsolation: false, - enableRemoteModule: isDev - }, - autoHideMenuBar: true, - minWidth: 800, - minHeight: 600, - /// show to false mean than the window will proceed with its lifecycle, but will not render until we will show it up - show: false - }) - - // load the index.html of the app. (or localhost on port 3000 if you're in development) - mainWindow.loadURL('http://localhost:3000') - - mainWindow.on('closed', () => { - mainWindow = null; - }); - - /// keep listening on the did-finish-load event, when the mainWindow content has loaded - mainWindow.webContents.on('did-finish-load', () => { - /// then close the loading screen window and show the main window - if (loadingScreen) { - loadingScreen.close(); - } - mainWindow.maximize(); - mainWindow.show(); - }); - -} - -ipcMain.on('getAllMics', (event, arg) => { - if (isDev) { - return { length: 0, mics: [] }; - } else { - return tcpConn.getAllMics().then(res => { - console.log('getAllMics : ' + res); - event.returnValue = res; - }); - } +ipcMain.on("setMicLevel", (event, arg) => { + if (isDev) { + let res = { + message: "OK", + statusCode: 200, + }; + event.returnValue = res; + return res; + } else { + return tcpConn.setVolumeToMic(arg).then((res) => { + console.log("setVolumeToMic : " + res); + event.returnValue = res; + }); + } }); -ipcMain.on('setVolumeToMic', (event, arg) => { - if (isDev) { - return { message: 'Error', statusCode: 500 } - } else { - return tcpConn.setVolumeToMic(arg).then(res => { - console.log('setVolumeToMic : ' + res); - event.returnValue = res; - }); - } +ipcMain.on("setSubtitles", (event, arg) => { + if (isDev) { + let res = { + message: "OK", + statusCode: 200, + }; + event.returnValue = res; + return res; + } else { + return tcpConn.setSubtitles(arg).then((res) => { + console.log("setSubtitles : " + res); + event.returnValue = res; + }); + } }); -ipcMain.on('getMic', (event, arg) => { - return tcpConn.getMic(arg).then(res => { - console.log('getMic : ' + res); - event.returnValue = res; - }); +ipcMain.on("setActionReaction", (event, arg) => { + if (isDev) { + let res = { + message: "OK", + statusCode: 200, + data: { + actionId: 1, + reactionId: 1, + actReactId: 1, + } + }; + event.returnValue = res; + return res; + } else { + return tcpConn.setActionReaction(arg).then((res) => { + console.log("setActionReaction : " + res); + event.returnValue = res; + }); + } }); -ipcMain.on('getAllEvents', (event, arg) => { - return tcpConn.getAllEvents().then(res => { - console.log('getAllEvents : ' + res); - event.returnValue = res; - }); +ipcMain.on("setAutoAudioLeveler", (event, arg) => { + if (isDev) { + let res = { + message: "OK", + statusCode: 200, + }; + event.returnValue = res; + return res; + } else { + return tcpConn.setAutoAudioLeveler(arg).then((res) => { + console.log("setAutoAudioLeveler : " + res); + event.returnValue = res; + }); + } }); -ipcMain.on('getEvent', (event, arg) => { - return tcpConn.getEvent(arg).then(res => { - console.log('getEvent : ' + res); - event.returnValue = res; - }); +ipcMain.on("removeActReact", (event, arg) => { + if (isDev) { + let res = { + statusCode: 200, + message: "OK", + data: { + actReactId: 1 + } + }; + event.returnValue = res; + return res; + } else { + return tcpConn.removeActReact(arg).then((res) => { + console.log("removeActReact : " + res); + event.returnValue = res; + }); + } }); -ipcMain.on('disconnectSocket', (event, arg) => { - return tcpConn.getAllMics().then(res => { - console.log('disconnectSocket : ' + res); - event.returnValue = res; - }); +ipcMain.on("disconnectSocket", (event, arg) => { + return tcpConn.getAllMics().then((res) => { + console.log("disconnectSocket : " + res); + event.returnValue = res; + }); }); -ipcMain.on('close-me', (evt, arg) => { - app.quit() -}) +ipcMain.on("close-me", (evt, arg) => { + app.quit(); +}); const createLoadingScreen = () => { /// create a browser window @@ -124,53 +231,52 @@ const createLoadingScreen = () => { frame: false, /// and set the transparency, to remove any window background color transparent: true, - webPreferences: { - nodeIntegration: true, - enableRemoteModule: isDev, - contextIsolation: false - } + webPreferences: { + nodeIntegration: true, + enableRemoteModule: isDev, + contextIsolation: false, + }, }) ); loadingScreen.setResizable(false); - loadingScreen.loadURL(`file://${path.join(__dirname, './loading.html')}`); - loadingScreen.on('closed', () => (loadingScreen = null)); - loadingScreen.webContents.on('did-finish-load', () => { + loadingScreen.loadURL(`file://${path.join(__dirname, "./loading.html")}`); + loadingScreen.on("closed", () => (loadingScreen = null)); + loadingScreen.webContents.on("did-finish-load", () => { loadingScreen.show(); }); }; const launchingApplication = () => { - createWindow(); - - app.on('activate', () => { - // On macOS it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (BrowserWindow.getAllWindows().length === 0) - createWindow() - }) -} + createWindow(); + + app.on("activate", () => { + // On macOS it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (BrowserWindow.getAllWindows().length === 0) createWindow(); + }); +}; // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. -app.on('ready', () => { - if (isDev) { - launchingApplication(); - } else { - createLoadingScreen(); - } -}) +app.on("ready", () => { + if (isDev) { + launchingApplication(); + } else { + createLoadingScreen(); + } +}); // Quit when all windows are closed, except on macOS. There, it's common // for applications and their menu bar to stay active until the user quits // explicitly with Cmd + Q. -app.on('window-all-closed', () => { - if (process.platform !== 'darwin') app.quit() -}) +app.on("window-all-closed", () => { + if (process.platform !== "darwin") app.quit(); +}); -app.on('before-quit', () => { - tcpConn.disconnectSocket(); -}) +app.on("before-quit", () => { + tcpConn.disconnectSocket(); +}); // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and require them here. diff --git a/src/Components/Actions/GeneralActions.tsx b/src/Components/Actions/GeneralActions.tsx index 0fda247..b0742db 100644 --- a/src/Components/Actions/GeneralActions.tsx +++ b/src/Components/Actions/GeneralActions.tsx @@ -15,70 +15,77 @@ import DialogActions from '@mui/material/DialogActions'; import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import DialogTitle from '@mui/material/DialogTitle'; -import NumericInput from 'material-ui-numeric-input'; import { LocalStorage } from '../../LocalStorage/LocalStorage'; -export enum ActionType { - ChangeCamera, - ChangeScene, - StartLive, - StopLive, - ActivateSoundboard +export enum ReactionType { + CAMERA_SWITCH = "CAMERA_SWITCH", + SCENE_SWITCH = "SCENE_SWITCH", + START_LIVE = "START_LIVE", + STOP_LIVE = "STOP_LIVE", + TOGGLE_AUDIO_COMPRESSOR = "TOGGLE_AUDIO_COMPRESSOR" } export const GeneralActions = () => { - const keysActionType = Object.keys(ActionType).filter(k => typeof ActionType[k as any] === "number"); - const valuesActionType = keysActionType.map(k => ActionType[k as any]); - - const [open, setOpen] = React.useState(false); - const [newActionName, setNewActionName] = React.useState(""); - const [newActionSelected, setNewActionSelected] = React.useState(0); - const [newActionParam, setNewActionParam] = React.useState(0) - - const handleOnChangeSelect = (action: SelectChangeEvent) => { - const value = action.target.value as ActionType; - setNewActionSelected(value); - }; - - const handleClickOpen = () => { - setOpen(true); - }; - - const [ actionsList, setActionsList ] = React.useState(LocalStorage.getItemObject("actionsList") || []) - - const handleSave = () => { - console.log("newActionName", newActionName); - console.log("newActionSelected", newActionSelected); - console.log("newActionParam", newActionParam); - if (newActionName !== "") { - let newElem: any = { - id: actionsList.length > 0 ? Math.max(...actionsList.map((o: any) => o.id)) + 1 : 1, - name: newActionName, - action: newActionSelected as ActionType, + const keysReactionType = Object.keys(ReactionType); + + const [open, setOpen] = React.useState(false); + const [newActionName, setNewActionName] = React.useState(""); + const [newActionSelected, setNewActionSelected] = React.useState("CAMERA_SWITCH"); + const [newActionParam, setNewActionParam] = React.useState("") + + const handleOnChangeSelect = (action: SelectChangeEvent) => { + const value = action.target.value as ReactionType; + setNewActionSelected(value); + }; + + const handleClickOpen = () => { + setOpen(true); + }; + + const [ actionsList, setActionsList ] = React.useState(LocalStorage.getItemObject("actionsList") || []) + + const handleSave = () => { + console.log("newActionName", newActionName); + console.log("newActionSelected", newActionSelected); + console.log("newActionParam", newActionParam); + if (newActionName !== "") { + let newElem: any = { + id: actionsList.length > 0 ? Math.max(...actionsList.map((o: any) => o.id)) + 1 : 1, + name: newActionName, + action: newActionSelected as ReactionType, + } + if (newActionParam) { + if (newActionSelected === ReactionType.TOGGLE_AUDIO_COMPRESSOR) + newElem.params = { "audio-source": newActionParam }; + if (newActionSelected === ReactionType.CAMERA_SWITCH) + newElem.params = { "video-source": newActionParam }; + if (newActionSelected === ReactionType.SCENE_SWITCH) + newElem.params = { "scene-name": newActionParam }; + if (newActionSelected === ReactionType.START_LIVE) + newElem.params = { "seconds": newActionParam }; + if (newActionSelected === ReactionType.STOP_LIVE) + newElem.params = { "seconds": newActionParam }; + } + + const newList = actionsList.concat([newElem]); + + setActionsList(newList); + LocalStorage.setItemObject("actionsList", newList) + alert("Action saved"); + } else { + // Put alert + alert("Missing parameters"); } - if (newActionParam) { - newElem.param_value = newActionParam; - } - - const newList = actionsList.concat([newElem]); - - setActionsList(newList); - LocalStorage.setItemObject("actionsList", newList) - alert("Action saved"); - } else { - // Put alert - alert("Missing parameters"); + setNewActionName(""); + setNewActionSelected("CAMERA_SWITCH"); + setNewActionParam(""); + setOpen(false); + }; + + const handleCancel = () => { + setOpen(false); } - setNewActionName(""); - setNewActionSelected(0); - setNewActionParam(0); - setOpen(false); - }; - - const handleCancel = () => { - setOpen(false); - } function deleteAction(id: number) { @@ -89,29 +96,29 @@ export const GeneralActions = () => { } function getAction(actionEnum: any) { - if (actionEnum === ActionType.ActivateSoundboard) - return "Activate Soundboard"; - if (actionEnum === ActionType.ChangeCamera) + if (actionEnum === ReactionType.TOGGLE_AUDIO_COMPRESSOR) + return "Toggle the audio compressor"; + if (actionEnum === ReactionType.CAMERA_SWITCH) return "Change the camera" - if (actionEnum === ActionType.ChangeScene) + if (actionEnum === ReactionType.SCENE_SWITCH) return "Change the scene" - if (actionEnum === ActionType.StartLive) + if (actionEnum === ReactionType.START_LIVE) return "Start the live" - if (actionEnum === ActionType.StopLive) + if (actionEnum === ReactionType.STOP_LIVE) return "Stop the live" return "" } - function getIcon(actionEnum: ActionType) { - if (actionEnum === ActionType.ActivateSoundboard) + function getIcon(actionEnum: ReactionType) { + if (actionEnum === ReactionType.TOGGLE_AUDIO_COMPRESSOR) return - if (actionEnum === ActionType.ChangeCamera) + if (actionEnum === ReactionType.CAMERA_SWITCH) return - if (actionEnum === ActionType.ChangeScene) + if (actionEnum === ReactionType.SCENE_SWITCH) return - if (actionEnum === ActionType.StartLive) + if (actionEnum === ReactionType.START_LIVE) return - if (actionEnum === ActionType.StopLive) + if (actionEnum === ReactionType.STOP_LIVE) return return } @@ -120,7 +127,7 @@ export const GeneralActions = () => { <>
-

List of Actions

+

List of Reactions

{ actionsList.length === 0 ? ( @@ -138,7 +145,14 @@ export const GeneralActions = () => { { getAction(item.action) } - { item.param_value ? "Parameter:" + item.param_value : "" } + { + item.params ? + Object.keys(item.params).map(key => { + return `${key}: ${item.params[key]}`; + }).join("\n") + : + "" + } @@ -154,7 +168,7 @@ export const GeneralActions = () => {
- Add Action + Add Reaction Lorem ipsum dolor sit amet, consectetur adipiscing elit. @@ -187,22 +201,20 @@ export const GeneralActions = () => { label="Action" > { - keysActionType.map((k) => { - return ({getAction(ActionType[k as any])}) + keysReactionType.map((k) => { + return ({getAction(k)}) }) }
- setNewActionParam(action.target.value as number)} - variant='outlined' + setNewActionParam(action.target.value)} />
@@ -216,7 +228,7 @@ export const GeneralActions = () => {
diff --git a/src/Components/AddNewWord/AddNewWord.tsx b/src/Components/AddNewWord/AddNewWord.tsx index 5829ee1..540aeb6 100644 --- a/src/Components/AddNewWord/AddNewWord.tsx +++ b/src/Components/AddNewWord/AddNewWord.tsx @@ -119,7 +119,6 @@ export const AddNewWord = (props: any) => { newEvent={props.newEvent} setnewEvent={props.setnewEvent} addNewEvent={props.addNewEvent} - changeEvent={props.changeEvent} open={open} /> diff --git a/src/Components/App/App.tsx b/src/Components/App/App.tsx index c079dd5..095fc80 100644 --- a/src/Components/App/App.tsx +++ b/src/Components/App/App.tsx @@ -13,53 +13,10 @@ import { Report } from '../Report/Report' import { MicsLevel } from '../MicsLevel/MicsLevel'; import { WordDetection } from '../WordDetection/WordDetection'; import { GeneralActions } from '../Actions/GeneralActions'; -import { AllMics, resultFormat } from '../../Socket/interfaces'; import { Scenes } from '../Scenes/Scenes'; -const ipcRenderer = window.require('electron').ipcRenderer export default function App() { - const [response, setResponse] = useState(''); - - const getAllMics = (): Promise => { - return new Promise(async (resolve, reject) => { - const result: AllMics = await ipcRenderer.sendSync('getAllMics', 'ping'); - console.log('getAllMics invoke', result); - resolve(result); - }) - } - - const setVolumeToMic = (micId: string, value: number): Promise => { - return new Promise(async (resolve, reject) => { - const result: resultFormat = await ipcRenderer.sendSync('setVolumeToMic', {'micId': micId, 'value': value}); - console.log('setVolumeToMic invoke', result); - resolve(result) - }); - } - - useEffect(() => { - setTimeout(() => { - console.log('Call getAllMics'); - getAllMics() - .then(_ => { - setVolumeToMic('Audio Input Capture (PulseAudio)', 100) - .then((res) => { - if (res.statusCode === 200) { - getAllMics() - .then((allMics) => { - console.log('FINALLY -> ', allMics); - }) - } - }) - }) - }, 5000); - - return () => { - console.log('unmounting'); - setResponse(''); - }; - }, []); - return (
diff --git a/src/Components/BoxEvent/BoxEvent.tsx b/src/Components/BoxEvent/BoxEvent.tsx index 80a116e..45afccc 100644 --- a/src/Components/BoxEvent/BoxEvent.tsx +++ b/src/Components/BoxEvent/BoxEvent.tsx @@ -61,20 +61,28 @@ export default function BoxEvent(props: any) { return ( <> - - If you say : - {props.keyObj.keywords.map((item: any, index: number) => { - return [{item}] - })} - { deleteEvent(props.i) }} - /> -

- The actions : - [{props.keyObj.source.name}] - will be done. -
+ { + props.keyObj.action.type === "WORD_DETECT" ? + + + If you say : + { + props.keyObj.action.params.words.map((item: any, index: number) => { + return [{item}] + }) + } + { deleteEvent(props.i) }} + /> +

+ The reaction : + [{props.keyObj.reaction?.name ? props.keyObj.reaction?.name : "NAME ERROR" }] + will be done. +
+ + : <> + } ); } diff --git a/src/Components/MicsLevel/MicsLevel.tsx b/src/Components/MicsLevel/MicsLevel.tsx index 14c1cce..badd7fc 100644 --- a/src/Components/MicsLevel/MicsLevel.tsx +++ b/src/Components/MicsLevel/MicsLevel.tsx @@ -1,60 +1,75 @@ import React, { Component, useEffect, useState } from "react"; import ReactRanger from "react-ranger"; import CustomizedSlider from "../Slider/Slider"; +import { AllMics, Mic } from '../../Socket/interfaces'; +import { resultFormat } from '../../Socket/interfaces'; +const ipcRenderer = window.require('electron').ipcRenderer export const MicsLevel = () => { - const [exampleMicsArray, setExampleMicsArray] = React.useState([ - { - id: 1, - name: "Mic 1", - level: 0, - savedlevel: 0, - isActive: true, - }, - { - id: 2, - name: "Mic 2", - level: 50, - savedlevel: 50, - isActive: true, - }, - { - id: 3, - name: "Mic 3", - level: 100, - savedlevel: 100, - isActive: false, - }, - ]); - + const [exampleMicsArray, setExampleMicsArray] = React.useState([]); const [load, setload] = React.useState(true); const [point, setpoint] = React.useState("."); + let timeoutCommit: NodeJS.Timeout | undefined = undefined; + + const getAllMics = (): Promise => { + return new Promise(async (resolve, reject) => { + const result: AllMics = await ipcRenderer.sendSync('getAllMics', 'ping'); + resolve(result); + }) + } + + // setVolumeToMic('Audio Input Capture (PulseAudio)', 100) + const setVolumeToMic = (mics: Mic[]): Promise => { + return new Promise(async (resolve, reject) => { + const result: resultFormat = await ipcRenderer.sendSync('setMicLevel', mics); + console.log('setVolumeToMic invoke', result); + resolve(result) + }); + } const getData = (index: number, value: number) => { - exampleMicsArray[index].level = value; - console.log("Values", exampleMicsArray); + let copy = exampleMicsArray.slice(); + copy[index].level = value; + console.log("Values", copy); + setExampleMicsArray(copy); + + // Update to server + clearTimeout(timeoutCommit) + timeoutCommit = setTimeout(() => { + setVolumeToMic(exampleMicsArray) + }, 3000); }; + const setActive = (index: number, value: boolean) => { let copy = exampleMicsArray.slice(); copy[index].isActive = value; setExampleMicsArray(copy); + + // Update to server + clearTimeout(timeoutCommit) + timeoutCommit = setTimeout(() => { + setVolumeToMic(exampleMicsArray) + }, 3000); }; useEffect(() => { async function sleep(): Promise { - await delay(4000); - return !load; + return new Promise((resolve) => { + getAllMics() + .then(res => { + if (res.statusCode === 200) { + setExampleMicsArray(res.mics) + resolve(false); + } + }) + }) } sleep().then((res) => setload(res)); }, []); - function delay(ms: number) { - return new Promise((resolve) => setTimeout(resolve, ms)); - } - function addpoint() { {setInterval(() => { (point.length >= 3 ? setpoint(".") : setpoint(point + ".")); @@ -70,18 +85,22 @@ export const MicsLevel = () => { {addpoint()} ) : ( - exampleMicsArray.map((item, index) => { - return ( - getData(index, val)} - sendActive={(val: boolean) => setActive(index, val)} - /> - ); - }) + exampleMicsArray && exampleMicsArray.length > 0 ? ( + exampleMicsArray.map((item, index) => { + return ( + getData(index, val)} + sendActive={(val: boolean) => setActive(index, val)} + /> + ); + }) + ) : ( + <> + ) )} ); diff --git a/src/Components/Scenes/Scenes.tsx b/src/Components/Scenes/Scenes.tsx index ae2a43f..372f4ef 100644 --- a/src/Components/Scenes/Scenes.tsx +++ b/src/Components/Scenes/Scenes.tsx @@ -26,8 +26,8 @@ export const Scenes = (props: any) => { lineHeight: 1.6 }; - const test = () => { - console.log("hello"); + const toggle = () => { + console.log("toggle"); } return ( @@ -37,7 +37,7 @@ export const Scenes = (props: any) => { { - test(); + toggle(); }} /> diff --git a/src/Components/Sidebar/Sidebar.tsx b/src/Components/Sidebar/Sidebar.tsx index 00a56cc..ccc00e0 100644 --- a/src/Components/Sidebar/Sidebar.tsx +++ b/src/Components/Sidebar/Sidebar.tsx @@ -14,7 +14,6 @@ const PathView = (props: any) => { const parseLocation = (path: string) => { const res = SidebarData.find(item => item.subNav && item.subNav.find(item => item.path === path)?.fullTitle); // Get the item which has the full title of the current page - console.log(res); if (res?.subNav) { return res.subNav.find(item => item.path === path)?.fullTitle; // Get the full title of the current page } else { diff --git a/src/Components/Slider/Slider.tsx b/src/Components/Slider/Slider.tsx index 9b3c7f8..eb78c65 100644 --- a/src/Components/Slider/Slider.tsx +++ b/src/Components/Slider/Slider.tsx @@ -96,14 +96,11 @@ export default function CustomizedSlider(props: any) { { - props.sendData(val); - }} onChangeCommitted={(_, val: any) => { props.sendData(val); }} aria-label="Micro" - defaultValue={props.defaultValue} + defaultValue={props.value} marks={marks} valueLabelDisplay="on" /> diff --git a/src/Components/Subtitles/Subtitles.tsx b/src/Components/Subtitles/Subtitles.tsx index 6833494..a20f425 100644 --- a/src/Components/Subtitles/Subtitles.tsx +++ b/src/Components/Subtitles/Subtitles.tsx @@ -10,6 +10,8 @@ import Select, { SelectChangeEvent } from '@mui/material/Select'; import { languages } from "../Language/LanguageData"; import Grid from '@mui/material/Grid'; import { LocalStorage } from "../../LocalStorage/LocalStorage"; +import { resultFormat } from "../../Socket/interfaces"; +const ipcRenderer = window.require('electron').ipcRenderer export const Subtitles = () => { @@ -44,14 +46,30 @@ export const Subtitles = () => { const [subtitlesActivated, setSubtitlesActivated] = React.useState(LocalStorage.getItemObject("subtitlesActivated") || false); const [languageSelected, setLanguageSelected] = React.useState(LocalStorage.getItemObject("languageSelected") || "en"); + const updateChangesToServer = (): Promise => { + return new Promise(async (resolve, reject) => { + let params = { + enable: subtitlesActivated, + language: languageSelected + } + const result: resultFormat = await ipcRenderer.sendSync('setSubtitles', params); + console.log('updateChangesToServer invoke', result); + resolve(result) + }); + } + const handleToggleChange = (event: SelectChangeEvent) => { LocalStorage.setItemObject("subtitlesActivated", !subtitlesActivated) setSubtitlesActivated(!subtitlesActivated); + + updateChangesToServer(); }; const handleSelectChange = (event: any) => { LocalStorage.setItemObject("languageSelected", event.target.value) setLanguageSelected(event.target.value); + + updateChangesToServer(); }; return ( diff --git a/src/Components/WordDetection/WordDetection.tsx b/src/Components/WordDetection/WordDetection.tsx index 0afa590..0eb01ff 100644 --- a/src/Components/WordDetection/WordDetection.tsx +++ b/src/Components/WordDetection/WordDetection.tsx @@ -1,8 +1,42 @@ -import * as React from "react"; +import React, { Component, useEffect, useState } from "react"; import { AddNewWord } from "../AddNewWord/AddNewWord"; import BoxEvent from "../BoxEvent/BoxEvent"; import { LocalStorage } from '../../LocalStorage/LocalStorage'; -import { ActionType } from '../Actions/GeneralActions'; +import { getActReactCouplesFormat, actionReactionFormat, removeActReactAnswer } from '../../Socket/interfaces'; +const ipcRenderer = window.require('electron').ipcRenderer + +export enum ActionType { + WORD_DETECT = "WORD_DETECT", + APP_LAUNCH = "APP_LAUNCH", + KEY_PRESSED = "KEY_PRESSED", +} + +interface action_reaction_identified { + actReactId: number, + isActive: boolean, + action: { + actionId: number, + type: string, + params?: Object + }, + reaction: { + reactionId: number, + type: string, + params?: Object + } +} + +interface action_reaction { + action: { + type: string, + params?: Object + }, + reaction: { + name: string, + type: string, + params?: Object + } +} interface event { id: number; @@ -16,47 +50,150 @@ interface event { } export const WordDetection = (props: any) => { - const [ eventArray, seteventArray ] = React.useState(LocalStorage.getItemObject("eventArray") || []) + const [ action_reactionArray, setaction_reactionArray ] = React.useState([]) const [newEvent, setnewEvent] = React.useState({ - id: eventArray.length, + id: action_reactionArray.length, keywords: [], source: {}, }); const [sources] = React.useState(LocalStorage.getItemObject("actionsList") || []) + const [load, setload] = React.useState(true); + const [point, setpoint] = React.useState("."); - function addNewEvent(event: event) { - let copy = eventArray.slice(); - event.id = eventArray.length; - copy.push(event); - seteventArray(copy); - LocalStorage.setItemObject("eventArray", copy) - setnewEvent({ id: eventArray.length, keywords: [], source: {} }); + const updateActionReactionArray = () => { + getActionReactionFromServer() + .then(res => { + if (res.statusCode === 200) { + console.log("New Array", res); + setaction_reactionArray(res.actReacts) + } + }); } - const changeEvent = (id: number, event: event) => { - let copy = eventArray.slice(); - copy[id] = event; - seteventArray(copy); - LocalStorage.setItemObject("eventArray", copy) - }; + const getActionReactionFromServer = (): Promise => { + return new Promise(async (resolve, reject) => { + const result: getActReactCouplesFormat = await ipcRenderer.sendSync('getActReactCouples', 'ping'); + resolve(result); + }); + } + + const sendActionReactionToServer = (newActionReaction: action_reaction): Promise => { + return new Promise(async (resolve, reject) => { + const result: actionReactionFormat = await ipcRenderer.sendSync('setActionReaction', newActionReaction); + resolve(result); + }); + } + + function addNewEvent(event: any) { + let newActionReaction: action_reaction = { + action: { + type: ActionType.WORD_DETECT as string, + params: { + words: event.keywords + } + }, + reaction: { + name: event.source.name, + type: event.source.action, + params: event.source.params + } + } + + sendActionReactionToServer(newActionReaction) + .then(res => { + if (res.statusCode === 200) { + updateActionReactionArray() + alert("Action & Reaction submitted successfully !") + } else { + alert("Error server") + } + }); + } + + function findDeletedElement(originalArray: any[], newArray: any[]): any | undefined { + const newSet = new Set(newArray); + for (const element of originalArray) { + if (!newSet.has(element)) { + return element; + } + } + return undefined; + } + + const removeAndUpdateActReaction = (params: any, eventArr: any) => { + return new Promise(async (resolve, reject) => { + const result: removeActReactAnswer = await ipcRenderer.sendSync('removeActReact', params) + if (result.statusCode === 200) { + console.log("Remove ActReaction", result.data.actReactId) + setaction_reactionArray(eventArr); + LocalStorage.setItemObject("action_reactionArray", eventArr) + } else { + alert("Error server. Please check connection.") + } + }) + } function updateEventFromBoxEvent(eventArr: any) { - seteventArray(eventArr); - LocalStorage.setItemObject("eventArray", eventArr) + console.log("Before", action_reactionArray); + console.log("After", eventArr); + + const elem = findDeletedElement(action_reactionArray, eventArr) + if (elem !== undefined) { + console.log("LELEMENT", elem) + const actReactId = elem.actReactId; + removeAndUpdateActReaction({ actReactId }, eventArr) + } else { + console.error("Changement undefined."); + } + } + + useEffect(() => { + async function sleep(): Promise { + return new Promise((resolve) => { + getActionReactionFromServer() + .then(res => { + if (res.statusCode === 200) { + console.log("New Array", res); + setaction_reactionArray(res.actReacts) + resolve(false); + } + }) + }) + } + + sleep().then((res) => setload(res)); + }, []); + + function addpoint() { + {setInterval(() => { + (point.length >= 3 ? setpoint(".") : setpoint(point + ".")); + }, 1000)} } return ( <> - {eventArray.map((item: any, index: number) => { - return ; - })} + {load ? ( + <> +

Easystream is loading

+

{point}

+ {addpoint()} + + ) : ( + <> + { + action_reactionArray.map((item: any, index: number) => { + return ; + }) + } + + ) + } ); }; diff --git a/src/Socket/interfaces.ts b/src/Socket/interfaces.ts index c8d3a36..55148b6 100644 --- a/src/Socket/interfaces.ts +++ b/src/Socket/interfaces.ts @@ -1,17 +1,62 @@ export interface resultFormat { + statusCode: number, message: string, - statusCode: number }; +export interface actionReactionFormat { + message: string, + statusCode: number, + data: { + actionId: number, + reactionId: number, + actReactId: number, + } +} + +interface actionInterface { + actionId: number, + type: string, + params: any +} + +interface reactionInterface { + name: string, + reactionId: number, + type: string, + params?: any +} + +export interface removeActReactAnswer { + statusCode: number, + message: string, + data: { + actReactId: number + } +} + +export interface actReactInterface { + actReactId: number, + isActive: boolean, + action: actionInterface + reaction: reactionInterface +} + +export interface getActReactCouplesFormat { + statusCode: number, + message: string, + length: number, + actReacts: actReactInterface[] +} + export interface Mic { - micName: string, - micKind: string, - unversionedmicKind: string, - value: number, + name: string, + level: number, isActive: boolean, }; export interface AllMics { + statusCode: number, + message: string, length: number, mics: [Mic], }; diff --git a/src/Socket/socket.js b/src/Socket/socket.js index 2eb410d..4da83bd 100644 --- a/src/Socket/socket.js +++ b/src/Socket/socket.js @@ -54,7 +54,6 @@ class TCPConnection { getAllMics() { let obj = { command: 'getAllMics', - args: {} }; console.log('getAllMics -> ', JSON.stringify(obj)); return new Promise((resolve, reject) => { @@ -72,12 +71,31 @@ class TCPConnection { }); } + getActReactCouples() { + let obj = { + command: 'getActReactCouples', + }; + console.log('getActReactCouples -> ', JSON.stringify(obj)); + return new Promise((resolve, reject) => { + this.sendData(obj, (data, error) => { + if (data) { + console.log('getActReactCouples resolve', data); + resolve(data); + } else { + console.log('getActReactCouples error', error); + this.socket.end(); + ipcRenderer.send('close-me') + reject(error); + } + }); + }); + } + setVolumeToMic(args) { let obj = { - command: 'setVolumeToMic', - args: { - micId: args.micId, - value: args.value + command: 'setMicLevel', + params: { + mics: args } }; console.log('setVolumeToMic -> ', JSON.stringify(obj)); @@ -95,20 +113,19 @@ class TCPConnection { }); } - getMic(micId) { + setSubtitles(args) { let obj = { - command: 'getMic', - args: { - micId - } + command: 'setSubtitles', + params: args }; + console.log('setSubtitles -> ', JSON.stringify(obj)); return new Promise((resolve, reject) => { this.sendData(obj, (data, error) => { if (data) { - console.log('getMic resolve', data); + console.log('setSubtitles resolve', data); resolve(data); } else { - console.log('getMic error', error); + console.log('setSubtitles error', error); this.socket.end(); reject(error); } @@ -116,18 +133,19 @@ class TCPConnection { }); } - getAllEvents() { + setActionReaction(args) { let obj = { - command: 'getAllEvents', - args: {} + command: 'setActionReaction', + params: args }; + console.log('setActionReaction -> ', JSON.stringify(obj)); return new Promise((resolve, reject) => { this.sendData(obj, (data, error) => { if (data) { - console.log('getAllEvents resolve', data); + console.log('setActionReaction resolve', data); resolve(data); } else { - console.log('getAllEvents error', error); + console.log('setActionReaction error', error); this.socket.end(); reject(error); } @@ -135,21 +153,39 @@ class TCPConnection { }); } - getEvent(eventId) { + setAutoAudioLeveler(args) { let obj = { - command: 'getEvent', - args: { - eventId - } + command: 'setAutoAudioLeveler', + params: args + }; + console.log('setAutoAudioLeveler -> ', JSON.stringify(obj)); + return new Promise((resolve, reject) => { + this.sendData(obj, (data, error) => { + if (data) { + console.log('setAutoAudioLeveler resolve', data); + resolve(data); + } else { + console.log('setAutoAudioLeveler error', error); + this.socket.end(); + reject(error); + } + }); + }); + } + + removeActReact(args) { + let obj = { + command: 'removeActReact', + params: args }; + console.log('removeActReact -> ', JSON.stringify(obj)); return new Promise((resolve, reject) => { - console.log('getEvent emit'); this.sendData(obj, (data, error) => { if (data) { - console.log('getEvent resolve', data); + console.log('removeActReact resolve', data); resolve(data); } else { - console.log('getEvent error', error); + console.log('removeActReact error', error); this.socket.end(); reject(error); }