diff --git a/package.json b/package.json index f4e18608..a3e8f417 100644 --- a/package.json +++ b/package.json @@ -72,9 +72,9 @@ "@types/jest": "^23.3.10", "@types/node": "10.11.7", "@types/pako": "^1.0.0", - "@types/react": "^16.4.16", + "@types/react": "^16.9.19", "@types/react-bootstrap": "^0.32.15", - "@types/react-dom": "^16.0.9", + "@types/react-dom": "^16.9.5", "@types/react-flags-select": "^1.1.2", "@types/react-google-recaptcha": "^0.10.0", "@types/react-paginate": "^6.2.0", @@ -106,7 +106,6 @@ "jest-css-modules": "^1.1.0", "lint-staged": "^8.1.0", "mini-css-extract-plugin": "^0.4.4", - "pnotify": "4.0.0-alpha.2", "postcss": "^7.0.5", "postcss-browser-reporter": "^0.5.0", "postcss-import": "^12.0.0", @@ -135,17 +134,19 @@ "dependencies": { "@types/commonmark": "^0.27.3", "@types/react-router-dom": "^5.1.3", + "@types/react-toast-notifications": "^2.4.0", "bootstrap": "^4.2.1", "classnames": "^2.2.6", "codecharacter-renderer": "^2.3.1", "commonmark": "^0.28.1", "copy-webpack-plugin": "^5.0.0", + "nvm": "0.0.4", "pako": "^1.0.10", - "react": "^16.5.2", + "react": "^16.12.0", "react-ace": "^6.2.0", "react-bootstrap": "^0.32.4", "react-country-flag": "^1.0.1", - "react-dom": "^16.5.2", + "react-dom": "^16.12.0", "react-flags-select": "^1.1.10", "react-ga": "^2.7.0", "react-google-recaptcha": "^1.0.5", @@ -160,6 +161,7 @@ "react-router-redux": "^4.0.8", "react-spinners": "^0.5.1", "react-split-pane": "^0.1.84", + "react-toast-notifications": "^2.4.0", "redux": "^4.0.1", "redux-actions": "^2.6.1", "redux-persist": "^5.10.0", diff --git a/src/app/components/SocketHandler.tsx b/src/app/components/SocketHandler.tsx index 8b85fe87..a6dda938 100644 --- a/src/app/components/SocketHandler.tsx +++ b/src/app/components/SocketHandler.tsx @@ -1,112 +1,109 @@ import { SOCKET_BASE_URL } from 'app/../config/config'; +import 'app/styles/ReactToastNotifications.css'; import * as SocketHandlerInterfaces from 'app/types/SocketHandler'; import * as React from 'react'; +import { useToasts } from 'react-toast-notifications'; import * as io from 'socket.io-client'; -export class SocketHandler extends React.Component { - private socket: SocketIOClient.Socket; - constructor(props: SocketHandlerInterfaces.Props) { - super(props); - this.socket = io.connect(SOCKET_BASE_URL, { - reconnection: true, - reconnectionDelay: 1000, - transports: ['websocket'], - }); - } - - public componentDidMount() { +// tslint:disable-next-line: variable-name +export const SocketHandler: React.FunctionComponent = ( + props: SocketHandlerInterfaces.Props, +) => { + const { addToast } = useToasts(); + const socket: SocketIOClient.Socket = io.connect(SOCKET_BASE_URL, { + reconnection: true, + reconnectionDelay: 1000, + transports: ['websocket'], + }); + + React.useEffect(() => { const { sendCompileError, sendCompileSuccess, sendExecuteError, sendExecuteSuccess, - sendInfo, - sendSuccess, - sendError, sendDebugRunSuccess, sendDebugRunError, - } = this.props; + } = props; - this.socket.on('Info', (message: string) => { - sendInfo(message); + socket.on('Info', (message: string) => { + addToast(message, { appearance: 'info', autoDismiss: true }); }); - this.socket.on('Success', (message: string) => { - sendSuccess(message); + socket.on('Success', (message: string) => { + addToast(message, { appearance: 'success', autoDismiss: true }); }); - this.socket.on('Error', (message: string) => { - sendError(message); + socket.on('Error', (message: string) => { + addToast(message, { appearance: 'error', autoDismiss: true }); }); - this.socket.on('connect', () => { - sendSuccess('Connected to Server!'); + socket.on('connect', () => { + addToast('Connected to Server!', { appearance: 'success', autoDismiss: true }); }); - this.socket.on('Compile Info', (message: string) => { - sendInfo(message); + socket.on('Compile Info', (message: string) => { + addToast(message, { appearance: 'info', autoDismiss: true }); }); - this.socket.on('Compile Success', () => { - sendSuccess('Compiled Successfully!'); + socket.on('Compile Success', () => { + addToast('Compiled Successfully!', { appearance: 'success', autoDismiss: true }); sendCompileSuccess(); }); - this.socket.on('Compile Error', (message: string) => { - sendError(`Compile Error: ${message}`); - sendCompileError(''); + socket.on('Compile Error', (message: string) => { + addToast(`Compile Error: ${message}`, { appearance: 'error', autoDismiss: true }), + sendCompileError(''); }); - this.socket.on('Compile Error Log', (log: string) => { - sendError('Compile Error'); + socket.on('Compile Error Log', (log: string) => { + addToast('Compile Error', { appearance: 'error', autoDismiss: true }); sendCompileError(log); }); - this.socket.on('Match Info', (message: string) => { - sendInfo(message); + socket.on('Match Info', (message: string) => { + addToast(message, { appearance: 'info', autoDismiss: true }); }); - this.socket.on('Match Error', (message: string) => { - sendError(message); + socket.on('Match Error', (message: string) => { + addToast(message, { appearance: 'error', autoDismiss: true }); sendExecuteError(message); }); - this.socket.on('Match Result Success', (result: string) => { - sendSuccess(result); + socket.on('Match Result Success', (result: string) => { + addToast(result, { appearance: 'success', autoDismiss: true }); }); - this.socket.on('Match Result Error', (result: string) => { - sendError(result); + socket.on('Match Result Error', (result: string) => { + addToast(result, { appearance: 'error', autoDismiss: true }); }); - this.socket.on('Match Success', (matchLogs: string) => { - sendSuccess('Match Executed Successfully!'); + socket.on('Match Success', (matchLogs: string) => { + addToast('Match Executed Successfully!', { appearance: 'success', autoDismiss: true }); sendExecuteSuccess(matchLogs); }); - this.socket.on('Debug Run Info', (message: string) => { - sendInfo(message); + socket.on('Debug Run Info', (message: string) => { + addToast(message, { appearance: 'info', autoDismiss: true }); }); - this.socket.on('Debug Run Success', (stackTrace: string) => { + socket.on('Debug Run Success', (stackTrace: string) => { sendDebugRunSuccess(stackTrace); }); - this.socket.on('Debug Run Error', (message: string) => { - sendError(`Debug Run Error: ${message}`); - sendDebugRunError(); + socket.on('Debug Run Error', (message: string) => { + addToast(`Debug Run Error: ${message}`, { appearance: 'error', autoDismiss: true }), + sendDebugRunError(); }); - this.socket.on('disconnect', () => { - sendError('Disconnected'); + socket.on('disconnect', () => { + addToast('Disconnected', { appearance: 'error', autoDismiss: true }); }); - } - public componentWillUnmount() { - this.socket.disconnect(); - } + return () => { + socket.disconnect(); + }; + }, []); - public render() { - return null; - } -} + return null; +}; diff --git a/src/app/components/UserProfileModal/EditProfile.tsx b/src/app/components/UserProfileModal/EditProfile.tsx index e9426cbb..890cff86 100755 --- a/src/app/components/UserProfileModal/EditProfile.tsx +++ b/src/app/components/UserProfileModal/EditProfile.tsx @@ -1,5 +1,5 @@ import * as authStyles from 'app/styles/Authentication.module.css'; -import 'app/styles/Flags.css'; +import 'app/styles/ReactFlagsSelect.css'; import * as profileStyles from 'app/styles/UserProfileModal.module.css'; import { Avatar } from 'app/types/Authentication/Register'; import { InputName } from 'app/types/UserProfileModal'; diff --git a/src/app/containers/SocketHandler.ts b/src/app/containers/SocketHandler.ts index 7d74a058..8c20325b 100644 --- a/src/app/containers/SocketHandler.ts +++ b/src/app/containers/SocketHandler.ts @@ -1,4 +1,4 @@ -import { NotificationActions, SubmissionActions } from 'app/actions'; +import { SubmissionActions } from 'app/actions'; import { SocketHandler } from 'app/components/SocketHandler'; import { RootState } from 'app/reducers'; import * as SocketHandlerInterfaces from 'app/types/SocketHandler'; @@ -16,11 +16,8 @@ const mapDispatchToProps = (dispatch: Dispatch) => { sendDebugRunError: () => dispatch(SubmissionActions.handleDebugRunError()), sendDebugRunSuccess: (stackTrace: string) => dispatch(SubmissionActions.handleDebugRunSuccess(stackTrace)), - sendError: (message: string) => dispatch(NotificationActions.error(message)), sendExecuteError: (error: string) => dispatch(SubmissionActions.handleExecuteError(error)), sendExecuteSuccess: (logs: string) => dispatch(SubmissionActions.handleExecuteSuccess(logs)), - sendInfo: (message: string) => dispatch(NotificationActions.info(message)), - sendSuccess: (message: string) => dispatch(NotificationActions.success(message)), }; }; diff --git a/src/app/index.tsx b/src/app/index.tsx index 0a83d041..74d3fe38 100644 --- a/src/app/index.tsx +++ b/src/app/index.tsx @@ -11,19 +11,22 @@ import { hot } from 'react-hot-loader'; // @ts-ignore import { Sugar } from 'react-preloaders'; import { BrowserRouter, Route, Switch } from 'react-router-dom'; +import { ToastProvider } from 'react-toast-notifications'; initializeRendererAssets(); /* tslint:disable-next-line:variable-name */ export const App = hot(module)(() => ( - - - - - - - - + + + + + + + + + + )); diff --git a/src/app/reducers/Notification.ts b/src/app/reducers/Notification.ts index a5e73155..d684f8ed 100644 --- a/src/app/reducers/Notification.ts +++ b/src/app/reducers/Notification.ts @@ -1,31 +1,6 @@ import { NotificationActions } from 'app/actions'; import * as NotificationInterfaces from 'app/types/Notification'; -// @ts-ignore -import PNotify from 'pnotify/dist/es/PNotify'; -import 'pnotify/dist/es/PNotifyButtons'; -import 'pnotify/dist/PNotifyBrightTheme.css'; - -const stackBottomRight = { - ...PNotify.defaultStack, - dir1: 'up', - dir2: 'left', -}; - -const pnotifyOptions = (title: string) => { - return { - title, - addclass: 'stack-bottomright', - buttons: { - closer: true, - sticker: true, - }, - delay: 5000, - stack: stackBottomRight, - text: false, - }; -}; - const notificationInitialState: NotificationInterfaces.NotificationStoreState = { loading: false, notifications: [], @@ -37,17 +12,14 @@ export const notificationReducer = ( ) => { switch (action.type) { case NotificationActions.Type.INFO: { - PNotify.info(pnotifyOptions(action.payload.message)); return state; } case NotificationActions.Type.SUCCESS: { - PNotify.success(pnotifyOptions(action.payload.message)); return state; } case NotificationActions.Type.ERROR: { - PNotify.error(pnotifyOptions(action.payload.message)); return state; } diff --git a/src/app/styles/Flags.css b/src/app/styles/ReactFlagsSelect.css similarity index 91% rename from src/app/styles/Flags.css rename to src/app/styles/ReactFlagsSelect.css index 112ed933..ed2c1229 100755 --- a/src/app/styles/Flags.css +++ b/src/app/styles/ReactFlagsSelect.css @@ -1,3 +1,4 @@ +/* Overriding react-flag-select package styles */ .flag-select { align-items: center !important; width: 100% !important; diff --git a/src/app/styles/ReactToastNotifications.css b/src/app/styles/ReactToastNotifications.css new file mode 100644 index 00000000..6a2742ae --- /dev/null +++ b/src/app/styles/ReactToastNotifications.css @@ -0,0 +1,4 @@ +/* Overriding the react-toast-notifications package-styles */ +.react-toast-notifications__container { + overflow: hidden !important; +} diff --git a/src/app/types/SocketHandler.ts b/src/app/types/SocketHandler.ts index 5774cbac..ece2b835 100644 --- a/src/app/types/SocketHandler.ts +++ b/src/app/types/SocketHandler.ts @@ -5,9 +5,6 @@ export interface DispatchProps { sendCompileSuccess: () => void; sendDebugRunError: () => void; sendDebugRunSuccess: (stackTrace: string) => void; - sendError: (message: string) => void; - sendInfo: (message: string) => void; - sendSuccess: (message: string) => void; } export type Props = DispatchProps; diff --git a/src/assets/index.html b/src/assets/index.html index 05ac7f73..f6204cf2 100644 --- a/src/assets/index.html +++ b/src/assets/index.html @@ -1,7 +1,7 @@ - + - + Code Character