diff --git a/src/Components/ActionsReactions/AddAppLaunch/AddAppLaunch.css b/src/Components/ActionsReactions/AddAppLaunch/AddAppLaunch.css
new file mode 100644
index 0000000..56e58eb
--- /dev/null
+++ b/src/Components/ActionsReactions/AddAppLaunch/AddAppLaunch.css
@@ -0,0 +1,25 @@
+.boxStylesAddNewWorld {
+ border: "solid";
+ border-color: "#FD7014";
+ border-width: "4";
+ padding-left: "20vw";
+ padding-right: "20vw";
+ padding-top: "2vh";
+ padding-bottom: "2vh";
+ background-color: "#222831";
+ border-radius: "15px";
+ align-items: "center";
+ cursor: "pointer";
+}
+
+.IconStylesAddNewWorld {
+ padding-left: "15px";
+ font-size: "30px";
+ width: "50px";
+}
+
+.TextStylesAddNewWorld {
+ display: "flex";
+ align-items: "center";
+ text-align: "center";
+}
diff --git a/src/Components/ActionsReactions/AddAppLaunch/AddAppLaunch.tsx b/src/Components/ActionsReactions/AddAppLaunch/AddAppLaunch.tsx
new file mode 100644
index 0000000..ad197e0
--- /dev/null
+++ b/src/Components/ActionsReactions/AddAppLaunch/AddAppLaunch.tsx
@@ -0,0 +1,107 @@
+import { Box } from "@mui/system";
+import React from "react";
+import {
+ IoIosAddCircleOutline,
+} from "react-icons/io";
+import CSS from "csstype";
+import { AppLaunchModal } from "./AppLaunchModal/AppLaunchModal"
+import { SelectChangeEvent } from "@mui/material/Select";
+
+const boxStyles: CSS.Properties = {
+ border: "solid",
+ borderColor: "#FD7014",
+ borderWidth: "50",
+ paddingLeft: "20vw",
+ paddingRight: "20vw",
+ paddingTop: "2vh",
+ paddingBottom: "2vh",
+ backgroundColor: "#222831",
+ borderRadius: "15px",
+ alignItems: "center",
+ cursor: "pointer",
+};
+
+const IconStyles: CSS.Properties = {
+ paddingLeft: "15px",
+ fontSize: "30px",
+ width: "50px",
+};
+
+const TextStyles: CSS.Properties = {
+ display: "flex",
+ alignItems: "center",
+ textAlign: "center",
+};
+
+interface event {
+ id: number;
+ keyword: string[];
+ source: String[];
+}
+
+export const AddAppLaunch = (props: any) => {
+ const [open, setOpen] = React.useState(false);
+ const [sources, setsources] = React.useState("");
+ const handleOpen = () => setOpen(true);
+ const handleClose = () => setOpen(false);
+
+ const save = () => {
+ if (props.newEvent.length !== 0 && props.newEvent.source && props.newEvent.source.name) {
+ props.addNewEvent(props.newEvent);
+ handleClose();
+ } else {
+ alert("Please insert at least one source.")
+ }
+ };
+
+ const closeWithoutSave = () => {
+ props.setnewEvent({ id: props.newEvent, keywords: [], sources: [] });
+ handleClose();
+ };
+
+ const handleChange = (e: any) => {
+ if (e.key === "Enter" && e.currentTarget.value !== "") {
+
+ let cpy = {...props.newEvent};
+
+ cpy.keywords[0] = (e.currentTarget.value);
+ e.currentTarget.value = "";
+ props.setnewEvent(cpy);
+ return
+ }
+ };
+
+ const addSource = (event: SelectChangeEvent) => {
+ let cpy = {...props.newEvent};
+
+ cpy.source = props.sources.find((elem: any) => elem.name === event.target.value)
+ props.setnewEvent(cpy);
+ };
+
+ return (
+ <>
+
+
+ Click to add new App Launch Event
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/src/Components/ActionsReactions/AddAppLaunch/AppLaunchModal/AppLaunchModal.css b/src/Components/ActionsReactions/AddAppLaunch/AppLaunchModal/AppLaunchModal.css
new file mode 100644
index 0000000..06b8bef
--- /dev/null
+++ b/src/Components/ActionsReactions/AddAppLaunch/AppLaunchModal/AppLaunchModal.css
@@ -0,0 +1,38 @@
+styleModal {
+ position: "absolute" as "absolute";
+ top: "50%";
+ left: "50%";
+ transform: "translate(-50%, -50%)";
+ width: 400;
+ background-color: "#222831";
+ border: "2px solid #FD7014";
+ box-shadow: 24;
+ padding: 4;
+ border-radius: "15px";
+}
+
+IconStylesModal {
+ padding-left: "85%";
+ font-size: "15px";
+ width: "50px";
+}
+
+TextStylesModal {
+ display: "flex";
+ align-items: "center";
+ text-align: "center";
+ word-wrap: "break-word";
+ width: "10px";
+ max-width: "10px";
+ white-space: "nowrap";
+ padding-left: "1vw";
+}
+
+SelectStylesModal {
+ color: red;
+}
+
+/* hover typography-item */
+.typography-item:hover {
+ color: #FD7014;
+}
diff --git a/src/Components/ActionsReactions/AddAppLaunch/AppLaunchModal/AppLaunchModal.tsx b/src/Components/ActionsReactions/AddAppLaunch/AppLaunchModal/AppLaunchModal.tsx
new file mode 100644
index 0000000..3e01116
--- /dev/null
+++ b/src/Components/ActionsReactions/AddAppLaunch/AppLaunchModal/AppLaunchModal.tsx
@@ -0,0 +1,237 @@
+import './AppLaunchModal.css'
+import React, { useState } from "react";
+import Box from "@mui/material/Box";
+import Button from "@mui/material/Button";
+import Typography from "@mui/material/Typography";
+import Modal from "@mui/material/Modal";
+import { BsTrash } from "react-icons/bs";
+import { Divider, FormControl, InputLabel, MenuItem, withStyles } from "@mui/material";
+import { AiOutlineMinus } from "react-icons/ai";
+import CSS from "csstype";
+import { SxProps } from '@mui/system';
+import { BorderColorRounded } from '@material-ui/icons';
+// import { makeStyles } from "@mui/styles";
+import { MuiThemeProvider, createTheme } from '@material-ui/core/styles';
+import Select from "@material-ui/core/Select";
+import { makeStyles } from "@material-ui/core/styles";
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+
+
+const themeUnFocus = createTheme({
+ overrides: {
+ MuiSelect: {
+ select: {
+ "&:focus": {
+ background: "$labelcolor"
+ }
+ }
+ }
+ }
+});
+
+const style = {
+ Box: {
+ position: "absolute" as "absolute",
+ top: "50%",
+ left: "50%",
+ transform: "translate(-50%, -50%)",
+ width: 500,
+ bgcolor: "#222831",
+ border: "1px solid #FD7014",
+ boxShadow: 24,
+ p: 4,
+ borderRadius: "15px",
+ },
+ Icon: {
+ paddingLeft: "85%",
+ fontSize: "15px",
+ width: "50px",
+ },
+ Text: {
+ display: "flex",
+ alignItems: "center",
+ textAlign: "center",
+ wordWrap: "break-word",
+ width: "10px",
+ maxWidth: "10px",
+ whiteSpace: "nowrap",
+ paddingLeft: "1vw",
+ },
+};
+
+const useStyles = makeStyles({
+ select: {
+ "&:before": {
+ borderColor: "#f56f28"
+ },
+ "&:after": {
+ borderColor: "#f56f28"
+ },
+ '&:not(.Mui-disabled):hover::before': {
+ borderColor: '#f56f28',
+ },
+ },
+ icon: {
+ fill: "#f56f28",
+ },
+ root: {
+ color: "#f56f28",
+ },
+ selectLabel: {
+ fontSize: "15px",
+ "&.MuiInputLabel-root": {
+ color: "white",
+ },
+ "&.Mui-focused": {
+ color: "#f56f28",
+ }
+ }
+})
+
+export const AppLaunchModal = (props: any) => {
+ const classes = useStyles()
+
+ return (
+ props.closeWithoutSave()}
+ aria-labelledby="modal-modal-title"
+ aria-describedby="modal-modal-description"
+ >
+
+ {
+ props.handleChange(event);
+ }}
+ />
+
+ {props.newEvent.keywords[0]}
+
+
+
+
+ {
+ props.sources.length === 0 ? (
+ <>
+ No action found.
+ You can create action in "Generate Action".
+ >
+ ) : (
+
+
+ sources
+
+
+
+ )
+ }
+ {
+ props.newEvent.source && props.newEvent.source.name ? (
+
+
+ {props.newEvent.source.name}
+
+
+ ) : (
+ <>
+ Source not selected.
+ >
+ )
+ }
+
+
+
+
+
+ );
+};
diff --git a/src/Components/ActionsReactions/AddNewKeyPressed/AddNewKeyPressed.tsx b/src/Components/ActionsReactions/AddNewKeyPressed/AddNewKeyPressed.tsx
index d3302bb..42253ed 100644
--- a/src/Components/ActionsReactions/AddNewKeyPressed/AddNewKeyPressed.tsx
+++ b/src/Components/ActionsReactions/AddNewKeyPressed/AddNewKeyPressed.tsx
@@ -74,7 +74,7 @@ export const AddNewKeyPressed = (props: any) => {
<>
- Click to add new Event
+ Click to add new Key Pressed Event
diff --git a/src/Components/ActionsReactions/AddNewWord/AddNewWord.tsx b/src/Components/ActionsReactions/AddNewWord/AddNewWord.tsx
index 7c98d22..ab7aaaa 100644
--- a/src/Components/ActionsReactions/AddNewWord/AddNewWord.tsx
+++ b/src/Components/ActionsReactions/AddNewWord/AddNewWord.tsx
@@ -100,7 +100,7 @@ export const AddNewWord = (props: any) => {
<>
- Click to add new Event
+ Click to add new Word Detection Event
diff --git a/src/Components/ActionsReactions/AppLaunch/AppLaunch.tsx b/src/Components/ActionsReactions/AppLaunch/AppLaunch.tsx
new file mode 100644
index 0000000..a75bd47
--- /dev/null
+++ b/src/Components/ActionsReactions/AppLaunch/AppLaunch.tsx
@@ -0,0 +1,242 @@
+import React, { Component, useEffect, useState } from "react";
+import { AddAppLaunch } from "../AddAppLaunch/AddAppLaunch";
+import { Link } from "react-router-dom";
+
+import { Button } from "@mui/material";
+
+import useAxiosPrivate from "../../../hooks/useAxiosPrivate";
+
+import BoxEvent from "../../BoxEvent/BoxEvent";
+import { LocalStorage } from '../../../LocalStorage/LocalStorage';
+import { getActReactCouplesFormat, actionReactionFormat, removeActReactAnswer } from '../../../Socket/interfaces';
+const ipcRenderer = window.require('electron').ipcRenderer
+const SAVE_WORD_DETECTION_URL = "/applicationSavedFeature/saveWordsDetection";
+
+export enum ActionType {
+ WORD_DETECT = "WORD_DETECT",
+ APP_LAUNCH = "APP_LAUNCH",
+ KEY_PRESSED = "KEY_PRESSED",
+}
+
+export interface action_reaction_identified {
+ actReactId: number,
+ isActive: boolean,
+ action: {
+ actionId: number,
+ type: string,
+ params?: Object
+ },
+ reaction: {
+ reactionId: number,
+ type: string,
+ params?: Object
+ }
+}
+
+export interface action_reaction {
+ action: {
+ type: string,
+ params?: Object
+ },
+ reaction: {
+ name: string,
+ type: string,
+ params?: Object
+ }
+}
+
+interface event {
+ id: number;
+ keywords: String[];
+ source: {
+ id?: number,
+ name?: String,
+ action?: ActionType,
+ param_value?: number
+ };
+}
+
+export const AppLaunch = (props: any) => {
+ const [ action_reactionArray, setaction_reactionArray ] = React.useState([])
+ const [newEvent, setnewEvent] = React.useState({
+ id: action_reactionArray.length,
+ keywords: [],
+ source: {},
+ });
+ const [sources] = React.useState(LocalStorage.getItemObject("actionsList") || [])
+ const [load, setload] = React.useState(true);
+ const [point, setpoint] = React.useState(".");
+ const axiosPrivate = useAxiosPrivate();
+
+ const style = {
+ Button: {
+ borderColor: "#f56f28",
+ color: "#FFFFFF",
+ marginTop: "20px",
+ "&:hover": {
+ borderColor: "#f56f28",
+ color: "#f56f28",
+ },
+ },
+ };
+
+ const save = () => {
+ const mics = ''
+ console.log(action_reactionArray)
+ // axiosPrivate.post(SAVE_WORD_DETECTION_URL, {
+ // mics,
+ // headers: { "Content-Type": "application/json" },
+ // // withCredentials: true,
+ // });
+ }
+
+ const updateActionReactionArray = () => {
+ getActionReactionFromServer()
+ .then(res => {
+ if (res.statusCode === 200) {
+ console.log("New Array", res);
+ setaction_reactionArray(res.data.actReacts)
+ }
+ });
+ }
+
+ 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.APP_LAUNCH as string,
+ params: {
+ app_name: event.keywords[0] // ! Careful
+ }
+ },
+ reaction: {
+ name: event.source.name,
+ type: event.source.action,
+ params: event.source.params
+ }
+ }
+
+ console.log("New action sent to server", newActionReaction)
+ 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)
+ updateActionReactionArray()
+ alert("Remove Action & Reaction successfully")
+ } else {
+ alert("Error server. Please check connection.")
+ }
+ })
+ }
+
+ function updateEventFromBoxEvent(eventArr: any) {
+ 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.data.actReacts)
+ resolve(false);
+ }
+ })
+ })
+ }
+
+ sleep().then((res) => setload(res));
+ }, []);
+
+ function addpoint() {
+ {setInterval(() => {
+ (point.length >= 3 ? setpoint(".") : setpoint(point + "."));
+ }, 1000)}
+ }
+
+ return (
+ <>
+ {load ? (
+ <>
+ Easystream is loading
+ {point}
+ {addpoint()}
+ >
+ ) : (
+ <>
+ {
+ action_reactionArray.map((item: any, index: number) => {
+ if (item.action.type === "APP_LAUNCH") {
+ return ;
+ }
+ })
+ }
+
+
+ Go Back
+
+ >
+ )
+ }
+ >
+ );
+};
diff --git a/src/Components/ActionsReactions/CreateActions/CreateActions.tsx b/src/Components/ActionsReactions/CreateActions/CreateActions.tsx
index 92465ef..dd72e2c 100644
--- a/src/Components/ActionsReactions/CreateActions/CreateActions.tsx
+++ b/src/Components/ActionsReactions/CreateActions/CreateActions.tsx
@@ -12,6 +12,7 @@ export const CreateActions = () => {
Select an action
Word Detection
Key Pressed
+ App Launch
Go Back
>
);
diff --git a/src/Components/App/App.tsx b/src/Components/App/App.tsx
index 13c52a0..4c09fd1 100644
--- a/src/Components/App/App.tsx
+++ b/src/Components/App/App.tsx
@@ -22,6 +22,7 @@ import { KeyPressed } from '../ActionsReactions/KeyPressed/KeyPressed';
import { CreateActions } from '../ActionsReactions/CreateActions/CreateActions';
import { CreateReactions } from '../ActionsReactions/CreateReactions/CreateReactions'
import { Feedback } from '../Other/Feedback/Feedback';
+import { AppLaunch } from '../ActionsReactions/AppLaunch/AppLaunch';
const ipcRenderer = window.require("electron").ipcRenderer;
@@ -43,6 +44,7 @@ export default function App() {
} />
} />
} />
+ } />
} />
{
return (
<>
-
+
your ip: { visibility ? ip : "*********" }
setvisibility(!visibility) } aria-label="visibility">
{ visibility ? : }