diff --git a/frontend/.eslintcache b/frontend/.eslintcache
index c5dfe12..d4c212a 100644
--- a/frontend/.eslintcache
+++ b/frontend/.eslintcache
@@ -1 +1 @@
-[{"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/ListCalls.js":"1","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-actions.js":"2","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/ListSystemsContainer.js":"3","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CallPlayer.js":"4","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-constants.js":"5","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/SupportModal.js":"6","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/FilterModal.js":"7","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/query-string.js":"8","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CalendarModal.js":"9","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/redux-router/configureStore.js":"10","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-actions.js":"11","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-reducer.js":"12","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/MediaPlayer.js":"13","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/GroupModal.js":"14","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-actions.js":"15","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/redux-router/reducers.js":"16","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/SystemCard.js":"17","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CalendarModalContainer.js":"18","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/ListSystems.js":"19","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-constants.js":"20","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CallItem.js":"21","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/system-actions.js":"22","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-reducer.js":"23","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Main/MainContainer.js":"24","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-reducer.js":"25","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-constants.js":"26"},{"size":2078,"mtime":1613098367816,"results":"27","hashOfConfig":"28"},{"size":9179,"mtime":1609597700043,"results":"29","hashOfConfig":"28"},{"size":277,"mtime":1545362103911,"results":"30","hashOfConfig":"28"},{"size":18569,"mtime":1613012570071,"results":"31","hashOfConfig":"28"},{"size":151,"mtime":1545362103908,"results":"32","hashOfConfig":"28"},{"size":1313,"mtime":1610678127937,"results":"33","hashOfConfig":"28"},{"size":4455,"mtime":1612233941171,"results":"34","hashOfConfig":"28"},{"size":362,"mtime":1610678313030,"results":"35","hashOfConfig":"28"},{"size":1778,"mtime":1609597248589,"results":"36","hashOfConfig":"28"},{"size":854,"mtime":1611803272298,"results":"37","hashOfConfig":"28"},{"size":2433,"mtime":1609597717050,"results":"38","hashOfConfig":"28"},{"size":1395,"mtime":1545362103908,"results":"39","hashOfConfig":"28"},{"size":4252,"mtime":1612317546527,"results":"40","hashOfConfig":"28"},{"size":2023,"mtime":1612233431556,"results":"41","hashOfConfig":"28"},{"size":1747,"mtime":1609597708479,"results":"42","hashOfConfig":"28"},{"size":595,"mtime":1609596047661,"results":"43","hashOfConfig":"28"},{"size":2045,"mtime":1609520570000,"results":"44","hashOfConfig":"28"},{"size":763,"mtime":1545362103896,"results":"45","hashOfConfig":"28"},{"size":1547,"mtime":1609520315634,"results":"46","hashOfConfig":"28"},{"size":537,"mtime":1545362103916,"results":"47","hashOfConfig":"28"},{"size":2909,"mtime":1613011408389,"results":"48","hashOfConfig":"28"},{"size":1575,"mtime":1610678224214,"results":"49","hashOfConfig":"28"},{"size":1045,"mtime":1610678295131,"results":"50","hashOfConfig":"28"},{"size":264,"mtime":1545362103910,"results":"51","hashOfConfig":"28"},{"size":7019,"mtime":1560857753468,"results":"52","hashOfConfig":"28"},{"size":1109,"mtime":1560828045933,"results":"53","hashOfConfig":"28"},{"filePath":"54","messages":"55","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},"1du4mf8",{"filePath":"56","messages":"57","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"58","usedDeprecatedRules":"59"},{"filePath":"60","messages":"61","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"62"},{"filePath":"63","messages":"64","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"65","messages":"66","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"67"},{"filePath":"68","messages":"69","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"70","messages":"71","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"72","messages":"73","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"74","usedDeprecatedRules":"75"},{"filePath":"76","messages":"77","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"78"},{"filePath":"79","messages":"80","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"81","messages":"82","errorCount":0,"warningCount":7,"fixableErrorCount":0,"fixableWarningCount":0,"source":"83","usedDeprecatedRules":"59"},{"filePath":"84","messages":"85","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"86","messages":"87","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"88","messages":"89","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"90","messages":"91","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"93","messages":"94","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"95"},{"filePath":"96","messages":"97","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"95"},{"filePath":"98","messages":"99","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"100","messages":"101","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"102","messages":"103","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"62"},{"filePath":"104","messages":"105","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"106"},{"filePath":"107","messages":"108","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"67"},{"filePath":"109","messages":"110","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"95"},{"filePath":"111","messages":"112","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"113","messages":"114","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"115","usedDeprecatedRules":"95"},{"filePath":"116","messages":"117","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/ListCalls.js",["118"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-actions.js",["119","120","121"],"import axios from \"axios\";\n\nimport * as types from \"./call-constants\";\nimport { push } from 'connected-react-router';\n\nconst FETCH_SUCCESS_STATISTIC = \"FETCH_SUCCESS_STATISTIC\"\n\nfunction beginFetchCallInfo() {\n return { type: types.FETCH_CALL_INFO };\n}\n\nfunction fetchCallInfoSuccess(data) {\n return { type: types.FETCH_SUCCESS_CALL_INFO,\n data };\n}\n\nfunction fetchCallInfoError(data) {\n return { type: types.FETCH_ERROR_CALL_INFO,\n data };\n}\n\nfunction prependCall() {\n return { type: types.PREPEND_CALL };\n}\n\nfunction beginAddStar() {\n return { type: types.ADD_STAR };\n}\n\nfunction addStarSuccess(data) {\n return { type: types.ADD_STAR_SUCCESS, data };\n}\n\nfunction addStarError(data) {\n return { type: types.ADD_STAR_ERROR, data };\n}\n\nfunction beginFetchCall() {\n return { type: types.FETCH_CALL };\n}\n\nfunction fetchCallSuccess(data) {\n return { type: types.FETCH_SUCCESS_CALL,\n data };\n}\n\n\n\nfunction fetchOlderCallSuccess(data) {\n return { type: types.FETCH_SUCCESS_OLDER_CALL,\n data };\n}\n\nfunction fetchNewerCallSuccess(data) {\n return { type: types.FETCH_SUCCESS_NEWER_CALL,\n data };\n}\n\nfunction fetchCallError(data) {\n return { type: types.FETCH_ERROR_CALL,\n data };\n}\n\n\nexport function changeUrl(url) {\n return dispatch => {\n dispatch(push(url));\n };\n}\n\n// Example of an Async Action Creator\n// http://redux.js.org/docs/advanced/AsyncActions.html\n\nfunction shouldFetchCalls(state, subreddit) {\n return true;\n if ((!state.call.items) || (state.call.items.length <1)) {\n return true\n } else if (state.call.isWaiting) {\n return false\n } else {\n return false\n }\n}\n\n\n\n\nfunction buildUrlParams(a) {\n return Object.keys(a).map(function(k) {\n return encodeURIComponent(k) + '=' + encodeURIComponent(a[k])\n }).join('&')\n}\n\nfunction buildCallUrl(state, date, direction) {\n var params = {};\n var url = \"\";\n\n\n if ((typeof direction === 'string') && (typeof date === 'number')) {\n url = url + '/' + direction;\n params[\"time\"] = date;\n } else {\n if (state.call.filterDate){\n url = url + '/older'\n params[\"time\"] = state.call.filterDate;\n }\n }\n if (state.call.filterStarred) {\n params[\"filter-starred\"] = true;\n }\n switch(state.call.filterType) {\n case 1:\n params[\"filter-type\"] = \"group\";\n params[\"filter-code\"] = state.call.filterGroupId;\n break;\n case 2:\n params[\"filter-type\"] = \"talkgroup\";\n params[\"filter-code\"] = state.call.filterTalkgroups;\n break;\n default:\n case 0:\n }\n/*\n\n if (this.filterCode != \"\") {\n params[\"filter-code\"] = this.filterCode;\n }\n\n if (this.filterType == this.FilterType.Group) {\n params[\"filter-type\"] = \"group\";\n params[\"filter-name\"] = this.filterName;\n }\n\n if (this.filterType == this.FilterType.Talkgroup) {\n params[\"filter-type\"] = \"talkgroup\";\n }\n\n if (this.filterType == this.FilterType.Unit) {\n params[\"filter-type\"] = \"unit\";\n }\n\n*/\n // url = startUp.backend_server + \"/\" + startUp.shortName.toLowerCase() + \"/calls\" + url + '?' + buildUrlParams(params);\n url = process.env.REACT_APP_BACKEND_SERVER + \"/\" + state.call.shortName + \"/calls\" + url + '?' + buildUrlParams(params);\n console.log(\"Trying to fetch data from this url: \" + url);\n return url;\n}\n\nexport function fetchNewerCalls( timestamp) {\n return (dispatch, getState) => {\n const state = getState();\n if (shouldFetchCalls(state)) {\n dispatch(beginFetchCall());\n const url = buildCallUrl(state, timestamp, \"newer\")\n return axios\n .get(url)\n .then(response => {\n if ((response.data) && (response.data.calls.length >0)) {\n var data = {shortName: state.call.shortName, calls: response.data.calls}\n dispatch(fetchNewerCallSuccess(data));\n } else {\n dispatch(fetchCallError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n}\n\n\nexport function fetchOlderCalls( timestamp) {\n return (dispatch, getState) => {\n const state = getState();\n if (shouldFetchCalls(state)) {\n dispatch(beginFetchCall());\n const url = buildCallUrl(state, timestamp, \"older\")\n return axios\n .get(url)\n .then(response => {\n if (response.data) {\n var data = {shortName: state.call.shortName, calls: response.data.calls}\n dispatch(fetchOlderCallSuccess(data));\n } else {\n dispatch(fetchCallError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n}\n\n\nexport function addStar( callId) {\n return (dispatch, getState) => {\n const state = getState();\n dispatch(beginAddStar());\n\n const url = process.env.REACT_APP_BACKEND_SERVER + \"/\" + state.call.shortName.toLowerCase() + \"/star/\" + callId\n return axios\n .post(url,{}, {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded'\n }\n }).then(response => {\n if (response.data.success) {\n dispatch(addStarSuccess(response.data.call));\n } else {\n dispatch(addStarError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n\n\n\nexport function fetchCallInfo( callId) {\n return (dispatch, getState) => {\n const state = getState();\n dispatch(beginFetchCallInfo());\n\n const url = process.env.REACT_APP_BACKEND_SERVER + \"/\" + state.call.shortName.toLowerCase() + \"/call/\" + callId\n return axios\n .get(url)\n .then(response => {\n if (response.data.success) {\n dispatch(fetchCallInfoSuccess(response.data.call));\n } else {\n dispatch(fetchCallInfoError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n\nexport function fetchCalls() {\n return (dispatch, getState) => {\n const state = getState();\n if (shouldFetchCalls(state)) {\n dispatch(beginFetchCall());\n const url=buildCallUrl(state);\n return axios\n .get(url)\n .then(response => {\n if (response.data) {\n // check to make sure you actually got some calls back.\n if (response.data.calls.length > 0) {\n var data = {shortName: state.call.shortName, calls: response.data.calls}\n dispatch(fetchCallSuccess(data));\n } else {\n dispatch(fetchCallError());\n }\n } else {\n dispatch(fetchCallError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n}\n\nexport function addCall(call) {\n return (dispatch, getState) => {\n dispatch({ type: types.UPSERT_CALL, data: call});\n };\n}\n\nexport function setStarred(starred) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_STARRED_FILTER, data: starred});\n };\n}\n\nexport function setLive(live) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_LIVE, data: live});\n };\n}\n\nexport function setCurrentCallId(callId) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_CURRENT_CALL_ID, data: callId});\n };\n}\n\n// should be as a unix timestamp\nexport function setDateFilter(date) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_DATE_FILTER, date: date});\n };\n}\n\nexport function setAllFilter() {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_ALL_FILTER});\n };\n}\n\nexport function setTalkgroupFilter(tgs) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_TALKGROUP_FILTER, talkgroups: tgs});\n };\n}\n\nexport function setGroupFilter(groupId) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_GROUP_FILTER, groupId: groupId});\n };\n}\n\nexport function setShortName(shortName) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_SHORT_NAME, data: shortName});\n };\n}\n\nexport function setFilter(filter) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_FILTER, data: filter});\n };\n}\n",["122","123"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/ListSystemsContainer.js",[],["124","125"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CallPlayer.js",["126","127"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-constants.js",[],["128","129"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/SupportModal.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/FilterModal.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/query-string.js",["130"],"export default {\n parse: function parse(queryString) {\n var query = {};\n var pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');\n for (var i = 0; i < pairs.length; i++) {\n var pair = pairs[i].split('=');\n query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');\n }\n return query;\n }\n}\n",["131","132"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CalendarModal.js",["133"],"import React, { Component } from \"react\";\nimport {\n Modal,\n Button,\n Icon,\n Header\n} from \"semantic-ui-react\";\nimport \"./CalendarModal.css\";\nimport DatePicker from 'react-datepicker';\nimport { subDays } from 'date-fns'\nimport 'react-datepicker/dist/react-datepicker.css';\n\nclass CalendarModal extends Component {\n constructor(props) {\n super(props)\n this.handleDateChange = this.handleDateChange.bind(this);\n this.handleDone = this.handleDone.bind(this);\n this.handleClose = this.handleClose.bind(this);\n\n this.state = {\n open: false,\n startDate: new Date()\n }\n}\n\nhandleDateChange = (date) => {\n this.setState({\n startDate: date\n });\n }\n\nhandleClose = () => this.props.onClose(false);\nhandleDone(event) {\n this.props.callActions.setDateFilter(this.state.startDate.getTime());\n this.props.onClose(true);\n}\n\n\n render() {\n \n return (\n\n \n Select a Date & Time\n \n \n \n \n \n \n \n \n \n\n )\n }\n}\n\nexport default CalendarModal;\n","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/redux-router/configureStore.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-actions.js",["134","135","136","137","138","139","140"],"import axios from 'axios';\n//import { browserHistory } from \"react-router\"\nimport * as types from \"./talkgroup-constants\";\nimport { push } from 'connected-react-router';\n\n// \"Log In\" action creators\nfunction beginImportTalkgroup() {\n return { type: types.IMPORT_TALKGROUP };\n}\n\nfunction importTalkgroupSuccess(data) {\n return {\n type: types.IMPORT_SUCCESS_TALKGROUP,\n data\n };\n}\n\nfunction importTalkgroupError(data) {\n return {\n type: types.IMPORT_ERROR_TALKGROUP,\n data\n };\n}\n\nfunction beginExportTalkgroup() {\n return { type: types.EXPORT_TALKGROUP };\n}\n\nfunction exportTalkgroupSuccess() {\n return { type: types.EXPORT_SUCCESS_TALKGROUP };\n}\n\nfunction exportTalkgroupError() {\n return { type: types.EXPORT_ERROR_TALKGROUP };\n}\n\n\nfunction beginFetchTalkgroup() {\n return { type: types.FETCH_TALKGROUP };\n}\n\nfunction fetchTalkgroupSuccess(data) {\n return { type: types.FETCH_SUCCESS_TALKGROUP,\n data };\n}\n\nfunction fetchTalkgroupError(data) {\n return { type: types.FETCH_ERROR_TALKGROUP,\n data };\n}\n\n\nfunction makeUserRequest(method, data, api) {\n // returns a Promise\n return axios({\n method: method,\n url: api,\n data: data\n });\n}\n\nexport function changeUrl(url) {\n return dispatch => {\n dispatch(push(url));\n };\n}\n\n\n// https://stackoverflow.com/questions/41878838/how-do-i-set-multipart-in-axios-with-react\n\n\n\nfunction shouldFetchTalkgroups(state, shortName) {\n if (!state.talkgroup.items.hasOwnProperty(shortName)) {\n return true\n } else if (state.talkgroup.isWaiting) {\n return false\n } else {\n return false\n }\n}\n\nexport function fetchTalkgroups(shortName) {\n return (dispatch, getState) => {\n if (shouldFetchTalkgroups(getState(), shortName)) {\n dispatch(beginFetchTalkgroup());\n\n return axios\n .get(process.env.REACT_APP_BACKEND_SERVER + \"/\" + shortName + \"/talkgroups\")\n .then(response => {\n if (response.data) {\n var data = {shortName: shortName, talkgroups: response.data.talkgroups}\n dispatch(fetchTalkgroupSuccess( data));\n } else {\n dispatch(fetchTalkgroupError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n}\n","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-reducer.js",["141","142"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/MediaPlayer.js",["143","144"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/GroupModal.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-actions.js",[],["145","146"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/redux-router/reducers.js",[],["147","148"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/SystemCard.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CalendarModalContainer.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/ListSystems.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-constants.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CallItem.js",["149"],"\nimport React, { Component } from \"react\";\nimport {\n Table,\n Icon,\n Label\n} from \"semantic-ui-react\";\nimport { connect } from \"react-redux\"\nimport { bindActionCreators } from 'redux'\nimport * as callActionCreators from \"./call-actions\"\n\n\nfunction mapStateToProps(state, props) {\n return {\n shortName: props.shortName\n\n\t}\n}\n\nfunction mapDispatchToProps(dispatch) {\n return {\n callActions: bindActionCreators(callActionCreators, dispatch)\n }\n}\n\n\nclass CallItem extends Component {\nconstructor(props) {\n super(props);\n this.hideStar = this.hideStar.bind(this);\n this.showStar = this.showStar.bind(this);\n this.addStar = this.addStar.bind(this);\n this.state = {\n starVisible: false,\n starClicked: false\n }\n}\nsourceString(call) {\n var srcString = \"\";\n if (call.srcList) {\n for (var src in call.srcList) {\n /* srcNum = call.srcList[src].src;\n if (sources.hasOwnProperty(srcNum)) {\n srcString = srcString + sources[srcNum].codeName + \", \";\n }*/\n }\n }\n\n return srcString;\n}\n\ncomponentDidUpdate(){\n if (this.props.activeCall) {\n console.log(\"Active call mounted\")\n }\n}\naddStar(e) {\n e.preventDefault();\n e.stopPropagation();\n e.nativeEvent.stopImmediatePropagation();\n if (!this.state.starClicked) {\n \n this.props.callActions.addStar(this.props.call._id);\n this.setState({starClicked: true});\n }\n}\n\nhideStar() {\n this.setState({ starVisible: false })\n}\n\nshowStar() {\n this.setState({ starVisible: true })\n}\n\nrender() {\n const call = this.props.call;\n const time = new Date(call.time);\n var rowSelected={};\n let starButton;\n var starClickable = {};\n if (!this.state.starClicked) {\n starClickable = {link: true };\n }\n if (!call.star && this.state.starVisible) {\n starButton = \n }\n\n if (call.star) {\n starButton = \n }\n if (call.star && call.star > 1) {\n starButton = (\n \n \n )\n }\n\n if (this.props.activeCall) {\n rowSelected={positive: true}\n }\n var talkgroup;\n if ((typeof this.props.talkgroups == 'undefined') || (typeof this.props.talkgroups[call.talkgroupNum] == 'undefined')) {\n talkgroup = call.talkgroupNum;\n } else {\n talkgroup = this.props.talkgroups[call.talkgroupNum].description;\n }\n return (\n
this.props.onClick({call: call}, e)} {...rowSelected}>\n {call.len} \n {talkgroup} \n {time.toLocaleTimeString()} \n {starButton}\n \n\n\n );\n}\n}\n\nexport default connect(\n\tmapStateToProps,\n\tmapDispatchToProps\n)(CallItem)\n\n","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/system-actions.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-reducer.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Main/MainContainer.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-reducer.js",["150","151"],"import {\n FETCH_CALL_INFO,\n FETCH_SUCCESS_CALL_INFO,\n FETCH_ERROR_CALL_INFO,\n FETCH_CALL,\n PREPEND_CALL,\n UPSERT_CALL,\n FETCH_SUCCESS_CALL,\n FETCH_SUCCESS_OLDER_CALL,\n FETCH_SUCCESS_NEWER_CALL,\n FETCH_ERROR_CALL,\n SET_SHORT_NAME,\n SET_ALL_FILTER,\n SET_GROUP_FILTER,\n SET_TALKGROUP_FILTER,\n SET_DATE_FILTER,\n SET_STARRED_FILTER,\n SET_FILTER,\n SET_CURRENT_CALL_ID,\n SET_LIVE,\n ADD_STAR_SUCCESS\n} from \"./call-constants\";\n\nfunction updateObject(oldObject, newValues) {\n // Encapsulate the idea of passing a new object as the first parameter\n // to Object.assign to ensure we correctly copy data instead of mutating\n return Object.assign({}, oldObject, newValues);\n}\n\nfunction updateCallInItems(calls, action) {\nreturn calls.map( (item) => {\n if (item._id !== action.data._id) {\n // This isn't the item we care about - keep it as-is\n return item;\n }\n\n // Otherwise, this is the one we want - return an updated value\n return {\n ...action.data\n };\n });\n}\n/*\nfunction updateObjectInArray(array, action) {\n return array.map((item, index) => {\n if (index !== action.index) {\n // This isn't the item we care about - keep it as-is\n return item\n }\n\n // Otherwise, this is the one we want - return an updated value\n return {\n ...item,\n ...action.item\n }\n })\n}\n\nfunction updateObjectInArray(array, shortName, updatedItem) {\n return array.map( item => {\n if(item.shortName !== shortName) {\n // This isn't the item we care about - keep it as-is\n return item;\n }\n\n // Otherwise, this is the one we want - return an updated value\n return {\n ...item,\n ...updatedItem\n };\n });\n}\n*/\nconst now = new Date();\nconst call = (\n state = {\n isWaiting: false,\n shortName: \"\",\n byId: {},\n allIds: [],\n oldestCallTime: now,\n newestCallTime: now,\n filterType: 0,\n filterTalkgroups: [],\n filterGroupId: false,\n filterDate: false,\n filterStarred: false,\n currentCallId: false,\n live: false\n },\n action\n) => {\n switch (action.type) {\n\n case SET_CURRENT_CALL_ID:\n return Object.assign({}, state, {currentCallId: action.data});\n \n case SET_FILTER:\n {\n var filter={};\n filter.live = !action.data.live ? state.live : action.data.live;\n filter.filterStarred = !action.data.filterStarred ? false : action.data.filterStarred;\n filter.filterType = !action.data.filterType ? 0 : action.data.filterType;\n filter.filterTalkgroups = !action.data.filterTalkgroups ? [] : action.data.filterTalkgroups;\n filter.filterGroupId = !action.data.filterGroupId ? false : action.data.filterGroupId;\n filter.filterDate = !action.data.filterDate ? 0 : action.data.filterDate;\n return Object.assign({}, state, {\n live: action.data.live,\n filterType: action.data.filterType,\n filterTalkgroups: action.data.filterTalkgroups,\n filterGroupId: action.data.filterGroupId,\n filterDate: action.data.filterDate,\n filterStarred: action.data.filterStarred\n });\n }\n\n case SET_LIVE:\n return Object.assign({}, state, {live: action.data});\n \n case SET_SHORT_NAME:\n return Object.assign({}, state, {shortName: action.data});\n\n case SET_DATE_FILTER:\n return Object.assign({}, state, {filterDate: action.date});\n\n case SET_STARRED_FILTER:\n return Object.assign({}, state, {filterStarred: action.data});\n\n case SET_ALL_FILTER:\n return Object.assign({}, state, {filterType: 0, filterTalkgroups:[], filterGroupId: false});\n\n case SET_GROUP_FILTER:\n return Object.assign({}, state, {filterType: 1, filterTalkgroups:[], filterGroupId: action.groupId});\n\n case SET_TALKGROUP_FILTER:\n return Object.assign({}, state, {filterType: 2, filterTalkgroups: action.talkgroups, filterGroupId: false});\n\n case FETCH_CALL_INFO:\n case FETCH_CALL:\n return Object.assign({}, state, { isWaiting: true});\n\n case FETCH_SUCCESS_CALL_INFO:\n return Object.assign({}, state, {\n byId: {...state.byId, [action.data._id]: action.data },\n isWaiting: false\n\n });\n\n case ADD_STAR_SUCCESS:\n return Object.assign({}, state,{\n byId: {...state.byId, [action.data._id]: action.data },\n isWaiting: false\n\n });\n // This will set the items to the rx data\n case FETCH_SUCCESS_CALL:\n {\n const byId = action.data.calls.reduce((acc, call) => ({ ...acc, [call._id]: call }), {});\n const allIds = action.data.calls.map(call => call._id);\n return Object.assign({}, state, {\n isWaiting: false,\n shortName: action.data.shortName,\n newestCallTime: new Date(action.data.calls[0].time),\n oldestCallTime: new Date(action.data.calls[action.data.calls.length-1].time),\n byId: { ...byId},\n allIds: [...allIds]\n });\n }\n\n case UPSERT_CALL:\n if (typeof state.byId[action.data._id] !== \"undefined\") {\n return Object.assign({}, state, {\n byId: {...state.byId, [action.data._id]: action.data },\n });\n } else {\n return Object.assign({}, state, {\n newestCallTime: new Date(action.data.time),\n byId: {[action.data._id]: action.data, ...state.byId},\n allIds: [action.data._id, ...state.allIds]\n }); \n }\n\n case PREPEND_CALL:\n return Object.assign({}, state, {\n isWaiting: false,\n newestCallTime: new Date(action.data.time),\n byId: {[action.data._id]: action.data, ...state.byId},\n allIds: [action.data._id, ...state.allIds]\n });\n\n// This will add the array of Calls in the data to the beginning of the existing array of Calls\n case FETCH_SUCCESS_NEWER_CALL:\n const byId = action.data.calls.reduce((acc, call) => ({ ...acc, [call._id]: call }), {});\n const allIds = action.data.calls.map(call => call._id).reverse();\n return Object.assign({}, state, {\n isWaiting: false,\n shortName: action.data.shortName,\n newestCallTime: new Date(action.data.calls[action.data.calls.length-1].time),\n byId: {...state.byId, ...byId},\n allIds: [...allIds, ...state.allIds]\n });\n\n// This will add the array of Calls in the data to the end of the existing array of Calls\n case FETCH_SUCCESS_OLDER_CALL:\n {\n const byId = action.data.calls.reduce((acc, call) => ({ ...acc, [call._id]: call }), {});\n const allIds = action.data.calls.map(call => call._id);\n return Object.assign({}, state, {\n isWaiting: false,\n shortName: action.data.shortName,\n oldestCallTime: new Date(action.data.calls[action.data.calls.length-1].time),\n byId: {...state.byId, ...byId},\n allIds: [ ...state.allIds, ...allIds]\n });\n }\n case FETCH_ERROR_CALL_INFO:\n case FETCH_ERROR_CALL:\n return Object.assign({}, state, {\n isWaiting: false\n });\n\n default:\n return state;\n }\n};\n\nexport default call;\n","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-constants.js",[],{"ruleId":"152","severity":1,"message":"153","line":23,"column":84,"nodeType":"154","messageId":"155","endLine":23,"endColumn":86},{"ruleId":"156","severity":1,"message":"157","line":6,"column":7,"nodeType":"158","messageId":"159","endLine":6,"endColumn":30},{"ruleId":"156","severity":1,"message":"160","line":22,"column":10,"nodeType":"158","messageId":"159","endLine":22,"endColumn":21},{"ruleId":"161","severity":1,"message":"162","line":76,"column":3,"nodeType":"163","messageId":"164","endLine":82,"endColumn":4},{"ruleId":"165","replacedBy":"166"},{"ruleId":"167","replacedBy":"168"},{"ruleId":"165","replacedBy":"169"},{"ruleId":"167","replacedBy":"170"},{"ruleId":"156","severity":1,"message":"171","line":277,"column":15,"nodeType":"158","messageId":"159","endLine":277,"endColumn":19},{"ruleId":"152","severity":1,"message":"153","line":438,"column":27,"nodeType":"154","messageId":"155","endLine":438,"endColumn":29},{"ruleId":"165","replacedBy":"172"},{"ruleId":"167","replacedBy":"173"},{"ruleId":"174","severity":1,"message":"175","line":1,"column":1,"nodeType":"176","endLine":11,"endColumn":2},{"ruleId":"165","replacedBy":"177"},{"ruleId":"167","replacedBy":"178"},{"ruleId":"156","severity":1,"message":"179","line":6,"column":3,"nodeType":"158","messageId":"159","endLine":6,"endColumn":9},{"ruleId":"156","severity":1,"message":"180","line":7,"column":10,"nodeType":"158","messageId":"159","endLine":7,"endColumn":30},{"ruleId":"156","severity":1,"message":"181","line":11,"column":10,"nodeType":"158","messageId":"159","endLine":11,"endColumn":32},{"ruleId":"156","severity":1,"message":"182","line":18,"column":10,"nodeType":"158","messageId":"159","endLine":18,"endColumn":30},{"ruleId":"156","severity":1,"message":"183","line":25,"column":10,"nodeType":"158","messageId":"159","endLine":25,"endColumn":30},{"ruleId":"156","severity":1,"message":"184","line":29,"column":10,"nodeType":"158","messageId":"159","endLine":29,"endColumn":32},{"ruleId":"156","severity":1,"message":"185","line":33,"column":10,"nodeType":"158","messageId":"159","endLine":33,"endColumn":30},{"ruleId":"156","severity":1,"message":"186","line":53,"column":10,"nodeType":"158","messageId":"159","endLine":53,"endColumn":25},{"ruleId":"156","severity":1,"message":"187","line":7,"column":10,"nodeType":"158","messageId":"159","endLine":7,"endColumn":22},{"ruleId":"156","severity":1,"message":"188","line":13,"column":10,"nodeType":"158","messageId":"159","endLine":13,"endColumn":27},{"ruleId":"189","severity":1,"message":"190","line":77,"column":3,"nodeType":"191","messageId":"155","endLine":78,"endColumn":4},{"ruleId":"156","severity":1,"message":"192","line":89,"column":5,"nodeType":"158","messageId":"159","endLine":89,"endColumn":16},{"ruleId":"165","replacedBy":"193"},{"ruleId":"167","replacedBy":"194"},{"ruleId":"165","replacedBy":"195"},{"ruleId":"167","replacedBy":"196"},{"ruleId":"156","severity":1,"message":"197","line":41,"column":18,"nodeType":"158","messageId":"159","endLine":41,"endColumn":21},{"ruleId":"156","severity":1,"message":"187","line":24,"column":10,"nodeType":"158","messageId":"159","endLine":24,"endColumn":22},{"ruleId":"156","severity":1,"message":"198","line":30,"column":10,"nodeType":"158","messageId":"159","endLine":30,"endColumn":27},"eqeqeq","Expected '!==' and instead saw '!='.","BinaryExpression","unexpected","no-unused-vars","'FETCH_SUCCESS_STATISTIC' is assigned a value but never used.","Identifier","unusedVar","'prependCall' is defined but never used.","no-unreachable","Unreachable code.","IfStatement","unreachableCode","no-native-reassign",["199"],"no-negated-in-lhs",["200"],["199"],["200"],"'refs' is assigned a value but never used.",["199"],["200"],"import/no-anonymous-default-export","Assign object to a variable before exporting as module default","ExportDefaultDeclaration",["199"],["200"],"'Header' is defined but never used.","'beginImportTalkgroup' is defined but never used.","'importTalkgroupSuccess' is defined but never used.","'importTalkgroupError' is defined but never used.","'beginExportTalkgroup' is defined but never used.","'exportTalkgroupSuccess' is defined but never used.","'exportTalkgroupError' is defined but never used.","'makeUserRequest' is defined but never used.","'updateObject' is defined but never used.","'updateItemInArray' is defined but never used.","no-dupe-class-members","Duplicate name 'componentDidUpdate'.","MethodDefinition","'playEnabled' is assigned a value but never used.",["199"],["200"],["199"],["200"],"'src' is assigned a value but never used.","'updateCallInItems' is defined but never used.","no-global-assign","no-unsafe-negation"]
\ No newline at end of file
+[{"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/ListCalls.js":"1","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-actions.js":"2","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/ListSystemsContainer.js":"3","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CallPlayer.js":"4","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-constants.js":"5","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/SupportModal.js":"6","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/FilterModal.js":"7","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/query-string.js":"8","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CalendarModal.js":"9","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/redux-router/configureStore.js":"10","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-actions.js":"11","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-reducer.js":"12","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/MediaPlayer.js":"13","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/GroupModal.js":"14","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-actions.js":"15","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/redux-router/reducers.js":"16","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/SystemCard.js":"17","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CalendarModalContainer.js":"18","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/ListSystems.js":"19","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-constants.js":"20","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CallItem.js":"21","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/system-actions.js":"22","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-reducer.js":"23","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Main/MainContainer.js":"24","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-reducer.js":"25","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-constants.js":"26"},{"size":1638,"mtime":1613098982285,"results":"27","hashOfConfig":"28"},{"size":9179,"mtime":1609597700043,"results":"29","hashOfConfig":"28"},{"size":277,"mtime":1545362103911,"results":"30","hashOfConfig":"28"},{"size":18826,"mtime":1613099368034,"results":"31","hashOfConfig":"28"},{"size":151,"mtime":1545362103908,"results":"32","hashOfConfig":"28"},{"size":1313,"mtime":1610678127937,"results":"33","hashOfConfig":"28"},{"size":4455,"mtime":1612233941171,"results":"34","hashOfConfig":"28"},{"size":362,"mtime":1610678313030,"results":"35","hashOfConfig":"28"},{"size":1778,"mtime":1609597248589,"results":"36","hashOfConfig":"28"},{"size":854,"mtime":1611803272298,"results":"37","hashOfConfig":"28"},{"size":2433,"mtime":1609597717050,"results":"38","hashOfConfig":"28"},{"size":1395,"mtime":1545362103908,"results":"39","hashOfConfig":"28"},{"size":4252,"mtime":1612317546527,"results":"40","hashOfConfig":"28"},{"size":2023,"mtime":1612233431556,"results":"41","hashOfConfig":"28"},{"size":1747,"mtime":1609597708479,"results":"42","hashOfConfig":"28"},{"size":595,"mtime":1609596047661,"results":"43","hashOfConfig":"28"},{"size":2045,"mtime":1609520570000,"results":"44","hashOfConfig":"28"},{"size":763,"mtime":1545362103896,"results":"45","hashOfConfig":"28"},{"size":1547,"mtime":1609520315634,"results":"46","hashOfConfig":"28"},{"size":537,"mtime":1545362103916,"results":"47","hashOfConfig":"28"},{"size":2909,"mtime":1613011408389,"results":"48","hashOfConfig":"28"},{"size":1575,"mtime":1610678224214,"results":"49","hashOfConfig":"28"},{"size":1045,"mtime":1610678295131,"results":"50","hashOfConfig":"28"},{"size":264,"mtime":1545362103910,"results":"51","hashOfConfig":"28"},{"size":7019,"mtime":1560857753468,"results":"52","hashOfConfig":"28"},{"size":1109,"mtime":1560828045933,"results":"53","hashOfConfig":"28"},{"filePath":"54","messages":"55","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},"1du4mf8",{"filePath":"56","messages":"57","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"58","usedDeprecatedRules":"59"},{"filePath":"60","messages":"61","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"62"},{"filePath":"63","messages":"64","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"65","messages":"66","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"67"},{"filePath":"68","messages":"69","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"70","messages":"71","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"72","messages":"73","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"74","usedDeprecatedRules":"75"},{"filePath":"76","messages":"77","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"78"},{"filePath":"79","messages":"80","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"81","messages":"82","errorCount":0,"warningCount":7,"fixableErrorCount":0,"fixableWarningCount":0,"source":"83","usedDeprecatedRules":"59"},{"filePath":"84","messages":"85","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"86","messages":"87","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"88","messages":"89","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"90","messages":"91","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"93","messages":"94","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"95"},{"filePath":"96","messages":"97","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"95"},{"filePath":"98","messages":"99","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"100","messages":"101","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"102","messages":"103","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"62"},{"filePath":"104","messages":"105","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"106"},{"filePath":"107","messages":"108","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"67"},{"filePath":"109","messages":"110","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"95"},{"filePath":"111","messages":"112","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"113","messages":"114","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"115","usedDeprecatedRules":"95"},{"filePath":"116","messages":"117","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/ListCalls.js",["118"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-actions.js",["119","120","121"],"import axios from \"axios\";\n\nimport * as types from \"./call-constants\";\nimport { push } from 'connected-react-router';\n\nconst FETCH_SUCCESS_STATISTIC = \"FETCH_SUCCESS_STATISTIC\"\n\nfunction beginFetchCallInfo() {\n return { type: types.FETCH_CALL_INFO };\n}\n\nfunction fetchCallInfoSuccess(data) {\n return { type: types.FETCH_SUCCESS_CALL_INFO,\n data };\n}\n\nfunction fetchCallInfoError(data) {\n return { type: types.FETCH_ERROR_CALL_INFO,\n data };\n}\n\nfunction prependCall() {\n return { type: types.PREPEND_CALL };\n}\n\nfunction beginAddStar() {\n return { type: types.ADD_STAR };\n}\n\nfunction addStarSuccess(data) {\n return { type: types.ADD_STAR_SUCCESS, data };\n}\n\nfunction addStarError(data) {\n return { type: types.ADD_STAR_ERROR, data };\n}\n\nfunction beginFetchCall() {\n return { type: types.FETCH_CALL };\n}\n\nfunction fetchCallSuccess(data) {\n return { type: types.FETCH_SUCCESS_CALL,\n data };\n}\n\n\n\nfunction fetchOlderCallSuccess(data) {\n return { type: types.FETCH_SUCCESS_OLDER_CALL,\n data };\n}\n\nfunction fetchNewerCallSuccess(data) {\n return { type: types.FETCH_SUCCESS_NEWER_CALL,\n data };\n}\n\nfunction fetchCallError(data) {\n return { type: types.FETCH_ERROR_CALL,\n data };\n}\n\n\nexport function changeUrl(url) {\n return dispatch => {\n dispatch(push(url));\n };\n}\n\n// Example of an Async Action Creator\n// http://redux.js.org/docs/advanced/AsyncActions.html\n\nfunction shouldFetchCalls(state, subreddit) {\n return true;\n if ((!state.call.items) || (state.call.items.length <1)) {\n return true\n } else if (state.call.isWaiting) {\n return false\n } else {\n return false\n }\n}\n\n\n\n\nfunction buildUrlParams(a) {\n return Object.keys(a).map(function(k) {\n return encodeURIComponent(k) + '=' + encodeURIComponent(a[k])\n }).join('&')\n}\n\nfunction buildCallUrl(state, date, direction) {\n var params = {};\n var url = \"\";\n\n\n if ((typeof direction === 'string') && (typeof date === 'number')) {\n url = url + '/' + direction;\n params[\"time\"] = date;\n } else {\n if (state.call.filterDate){\n url = url + '/older'\n params[\"time\"] = state.call.filterDate;\n }\n }\n if (state.call.filterStarred) {\n params[\"filter-starred\"] = true;\n }\n switch(state.call.filterType) {\n case 1:\n params[\"filter-type\"] = \"group\";\n params[\"filter-code\"] = state.call.filterGroupId;\n break;\n case 2:\n params[\"filter-type\"] = \"talkgroup\";\n params[\"filter-code\"] = state.call.filterTalkgroups;\n break;\n default:\n case 0:\n }\n/*\n\n if (this.filterCode != \"\") {\n params[\"filter-code\"] = this.filterCode;\n }\n\n if (this.filterType == this.FilterType.Group) {\n params[\"filter-type\"] = \"group\";\n params[\"filter-name\"] = this.filterName;\n }\n\n if (this.filterType == this.FilterType.Talkgroup) {\n params[\"filter-type\"] = \"talkgroup\";\n }\n\n if (this.filterType == this.FilterType.Unit) {\n params[\"filter-type\"] = \"unit\";\n }\n\n*/\n // url = startUp.backend_server + \"/\" + startUp.shortName.toLowerCase() + \"/calls\" + url + '?' + buildUrlParams(params);\n url = process.env.REACT_APP_BACKEND_SERVER + \"/\" + state.call.shortName + \"/calls\" + url + '?' + buildUrlParams(params);\n console.log(\"Trying to fetch data from this url: \" + url);\n return url;\n}\n\nexport function fetchNewerCalls( timestamp) {\n return (dispatch, getState) => {\n const state = getState();\n if (shouldFetchCalls(state)) {\n dispatch(beginFetchCall());\n const url = buildCallUrl(state, timestamp, \"newer\")\n return axios\n .get(url)\n .then(response => {\n if ((response.data) && (response.data.calls.length >0)) {\n var data = {shortName: state.call.shortName, calls: response.data.calls}\n dispatch(fetchNewerCallSuccess(data));\n } else {\n dispatch(fetchCallError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n}\n\n\nexport function fetchOlderCalls( timestamp) {\n return (dispatch, getState) => {\n const state = getState();\n if (shouldFetchCalls(state)) {\n dispatch(beginFetchCall());\n const url = buildCallUrl(state, timestamp, \"older\")\n return axios\n .get(url)\n .then(response => {\n if (response.data) {\n var data = {shortName: state.call.shortName, calls: response.data.calls}\n dispatch(fetchOlderCallSuccess(data));\n } else {\n dispatch(fetchCallError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n}\n\n\nexport function addStar( callId) {\n return (dispatch, getState) => {\n const state = getState();\n dispatch(beginAddStar());\n\n const url = process.env.REACT_APP_BACKEND_SERVER + \"/\" + state.call.shortName.toLowerCase() + \"/star/\" + callId\n return axios\n .post(url,{}, {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded'\n }\n }).then(response => {\n if (response.data.success) {\n dispatch(addStarSuccess(response.data.call));\n } else {\n dispatch(addStarError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n\n\n\nexport function fetchCallInfo( callId) {\n return (dispatch, getState) => {\n const state = getState();\n dispatch(beginFetchCallInfo());\n\n const url = process.env.REACT_APP_BACKEND_SERVER + \"/\" + state.call.shortName.toLowerCase() + \"/call/\" + callId\n return axios\n .get(url)\n .then(response => {\n if (response.data.success) {\n dispatch(fetchCallInfoSuccess(response.data.call));\n } else {\n dispatch(fetchCallInfoError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n\nexport function fetchCalls() {\n return (dispatch, getState) => {\n const state = getState();\n if (shouldFetchCalls(state)) {\n dispatch(beginFetchCall());\n const url=buildCallUrl(state);\n return axios\n .get(url)\n .then(response => {\n if (response.data) {\n // check to make sure you actually got some calls back.\n if (response.data.calls.length > 0) {\n var data = {shortName: state.call.shortName, calls: response.data.calls}\n dispatch(fetchCallSuccess(data));\n } else {\n dispatch(fetchCallError());\n }\n } else {\n dispatch(fetchCallError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n}\n\nexport function addCall(call) {\n return (dispatch, getState) => {\n dispatch({ type: types.UPSERT_CALL, data: call});\n };\n}\n\nexport function setStarred(starred) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_STARRED_FILTER, data: starred});\n };\n}\n\nexport function setLive(live) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_LIVE, data: live});\n };\n}\n\nexport function setCurrentCallId(callId) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_CURRENT_CALL_ID, data: callId});\n };\n}\n\n// should be as a unix timestamp\nexport function setDateFilter(date) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_DATE_FILTER, date: date});\n };\n}\n\nexport function setAllFilter() {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_ALL_FILTER});\n };\n}\n\nexport function setTalkgroupFilter(tgs) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_TALKGROUP_FILTER, talkgroups: tgs});\n };\n}\n\nexport function setGroupFilter(groupId) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_GROUP_FILTER, groupId: groupId});\n };\n}\n\nexport function setShortName(shortName) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_SHORT_NAME, data: shortName});\n };\n}\n\nexport function setFilter(filter) {\n return (dispatch, getState) => {\n dispatch({ type: types.SET_FILTER, data: filter});\n };\n}\n",["122","123"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/ListSystemsContainer.js",[],["124","125"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CallPlayer.js",["126","127"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-constants.js",[],["128","129"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/SupportModal.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/FilterModal.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/query-string.js",["130"],"export default {\n parse: function parse(queryString) {\n var query = {};\n var pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');\n for (var i = 0; i < pairs.length; i++) {\n var pair = pairs[i].split('=');\n query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');\n }\n return query;\n }\n}\n",["131","132"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CalendarModal.js",["133"],"import React, { Component } from \"react\";\nimport {\n Modal,\n Button,\n Icon,\n Header\n} from \"semantic-ui-react\";\nimport \"./CalendarModal.css\";\nimport DatePicker from 'react-datepicker';\nimport { subDays } from 'date-fns'\nimport 'react-datepicker/dist/react-datepicker.css';\n\nclass CalendarModal extends Component {\n constructor(props) {\n super(props)\n this.handleDateChange = this.handleDateChange.bind(this);\n this.handleDone = this.handleDone.bind(this);\n this.handleClose = this.handleClose.bind(this);\n\n this.state = {\n open: false,\n startDate: new Date()\n }\n}\n\nhandleDateChange = (date) => {\n this.setState({\n startDate: date\n });\n }\n\nhandleClose = () => this.props.onClose(false);\nhandleDone(event) {\n this.props.callActions.setDateFilter(this.state.startDate.getTime());\n this.props.onClose(true);\n}\n\n\n render() {\n \n return (\n\n \n Select a Date & Time\n \n \n \n \n \n \n \n \n \n\n )\n }\n}\n\nexport default CalendarModal;\n","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/redux-router/configureStore.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-actions.js",["134","135","136","137","138","139","140"],"import axios from 'axios';\n//import { browserHistory } from \"react-router\"\nimport * as types from \"./talkgroup-constants\";\nimport { push } from 'connected-react-router';\n\n// \"Log In\" action creators\nfunction beginImportTalkgroup() {\n return { type: types.IMPORT_TALKGROUP };\n}\n\nfunction importTalkgroupSuccess(data) {\n return {\n type: types.IMPORT_SUCCESS_TALKGROUP,\n data\n };\n}\n\nfunction importTalkgroupError(data) {\n return {\n type: types.IMPORT_ERROR_TALKGROUP,\n data\n };\n}\n\nfunction beginExportTalkgroup() {\n return { type: types.EXPORT_TALKGROUP };\n}\n\nfunction exportTalkgroupSuccess() {\n return { type: types.EXPORT_SUCCESS_TALKGROUP };\n}\n\nfunction exportTalkgroupError() {\n return { type: types.EXPORT_ERROR_TALKGROUP };\n}\n\n\nfunction beginFetchTalkgroup() {\n return { type: types.FETCH_TALKGROUP };\n}\n\nfunction fetchTalkgroupSuccess(data) {\n return { type: types.FETCH_SUCCESS_TALKGROUP,\n data };\n}\n\nfunction fetchTalkgroupError(data) {\n return { type: types.FETCH_ERROR_TALKGROUP,\n data };\n}\n\n\nfunction makeUserRequest(method, data, api) {\n // returns a Promise\n return axios({\n method: method,\n url: api,\n data: data\n });\n}\n\nexport function changeUrl(url) {\n return dispatch => {\n dispatch(push(url));\n };\n}\n\n\n// https://stackoverflow.com/questions/41878838/how-do-i-set-multipart-in-axios-with-react\n\n\n\nfunction shouldFetchTalkgroups(state, shortName) {\n if (!state.talkgroup.items.hasOwnProperty(shortName)) {\n return true\n } else if (state.talkgroup.isWaiting) {\n return false\n } else {\n return false\n }\n}\n\nexport function fetchTalkgroups(shortName) {\n return (dispatch, getState) => {\n if (shouldFetchTalkgroups(getState(), shortName)) {\n dispatch(beginFetchTalkgroup());\n\n return axios\n .get(process.env.REACT_APP_BACKEND_SERVER + \"/\" + shortName + \"/talkgroups\")\n .then(response => {\n if (response.data) {\n var data = {shortName: shortName, talkgroups: response.data.talkgroups}\n dispatch(fetchTalkgroupSuccess( data));\n } else {\n dispatch(fetchTalkgroupError());\n let registerMessage = response.data.message;\n return registerMessage;\n }\n })\n .catch(response => {\n if (response instanceof Error) {\n // Something happened in setting up the request that triggered an Error\n console.log(\"Error\", response.message);\n }\n });\n };\n};\n}\n","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-reducer.js",["141","142"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/MediaPlayer.js",["143","144"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/GroupModal.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Group/group-actions.js",[],["145","146"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/redux-router/reducers.js",[],["147","148"],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/SystemCard.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CalendarModalContainer.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/ListSystems.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-constants.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/CallItem.js",["149"],"\nimport React, { Component } from \"react\";\nimport {\n Table,\n Icon,\n Label\n} from \"semantic-ui-react\";\nimport { connect } from \"react-redux\"\nimport { bindActionCreators } from 'redux'\nimport * as callActionCreators from \"./call-actions\"\n\n\nfunction mapStateToProps(state, props) {\n return {\n shortName: props.shortName\n\n\t}\n}\n\nfunction mapDispatchToProps(dispatch) {\n return {\n callActions: bindActionCreators(callActionCreators, dispatch)\n }\n}\n\n\nclass CallItem extends Component {\nconstructor(props) {\n super(props);\n this.hideStar = this.hideStar.bind(this);\n this.showStar = this.showStar.bind(this);\n this.addStar = this.addStar.bind(this);\n this.state = {\n starVisible: false,\n starClicked: false\n }\n}\nsourceString(call) {\n var srcString = \"\";\n if (call.srcList) {\n for (var src in call.srcList) {\n /* srcNum = call.srcList[src].src;\n if (sources.hasOwnProperty(srcNum)) {\n srcString = srcString + sources[srcNum].codeName + \", \";\n }*/\n }\n }\n\n return srcString;\n}\n\ncomponentDidUpdate(){\n if (this.props.activeCall) {\n console.log(\"Active call mounted\")\n }\n}\naddStar(e) {\n e.preventDefault();\n e.stopPropagation();\n e.nativeEvent.stopImmediatePropagation();\n if (!this.state.starClicked) {\n \n this.props.callActions.addStar(this.props.call._id);\n this.setState({starClicked: true});\n }\n}\n\nhideStar() {\n this.setState({ starVisible: false })\n}\n\nshowStar() {\n this.setState({ starVisible: true })\n}\n\nrender() {\n const call = this.props.call;\n const time = new Date(call.time);\n var rowSelected={};\n let starButton;\n var starClickable = {};\n if (!this.state.starClicked) {\n starClickable = {link: true };\n }\n if (!call.star && this.state.starVisible) {\n starButton = \n }\n\n if (call.star) {\n starButton = \n }\n if (call.star && call.star > 1) {\n starButton = (\n \n \n )\n }\n\n if (this.props.activeCall) {\n rowSelected={positive: true}\n }\n var talkgroup;\n if ((typeof this.props.talkgroups == 'undefined') || (typeof this.props.talkgroups[call.talkgroupNum] == 'undefined')) {\n talkgroup = call.talkgroupNum;\n } else {\n talkgroup = this.props.talkgroups[call.talkgroupNum].description;\n }\n return (\n this.props.onClick({call: call}, e)} {...rowSelected}>\n {call.len} \n {talkgroup} \n {time.toLocaleTimeString()} \n {starButton}\n \n\n\n );\n}\n}\n\nexport default connect(\n\tmapStateToProps,\n\tmapDispatchToProps\n)(CallItem)\n\n","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/System/system-actions.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Talkgroups/talkgroup-reducer.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Main/MainContainer.js",[],"/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-reducer.js",["150","151"],"import {\n FETCH_CALL_INFO,\n FETCH_SUCCESS_CALL_INFO,\n FETCH_ERROR_CALL_INFO,\n FETCH_CALL,\n PREPEND_CALL,\n UPSERT_CALL,\n FETCH_SUCCESS_CALL,\n FETCH_SUCCESS_OLDER_CALL,\n FETCH_SUCCESS_NEWER_CALL,\n FETCH_ERROR_CALL,\n SET_SHORT_NAME,\n SET_ALL_FILTER,\n SET_GROUP_FILTER,\n SET_TALKGROUP_FILTER,\n SET_DATE_FILTER,\n SET_STARRED_FILTER,\n SET_FILTER,\n SET_CURRENT_CALL_ID,\n SET_LIVE,\n ADD_STAR_SUCCESS\n} from \"./call-constants\";\n\nfunction updateObject(oldObject, newValues) {\n // Encapsulate the idea of passing a new object as the first parameter\n // to Object.assign to ensure we correctly copy data instead of mutating\n return Object.assign({}, oldObject, newValues);\n}\n\nfunction updateCallInItems(calls, action) {\nreturn calls.map( (item) => {\n if (item._id !== action.data._id) {\n // This isn't the item we care about - keep it as-is\n return item;\n }\n\n // Otherwise, this is the one we want - return an updated value\n return {\n ...action.data\n };\n });\n}\n/*\nfunction updateObjectInArray(array, action) {\n return array.map((item, index) => {\n if (index !== action.index) {\n // This isn't the item we care about - keep it as-is\n return item\n }\n\n // Otherwise, this is the one we want - return an updated value\n return {\n ...item,\n ...action.item\n }\n })\n}\n\nfunction updateObjectInArray(array, shortName, updatedItem) {\n return array.map( item => {\n if(item.shortName !== shortName) {\n // This isn't the item we care about - keep it as-is\n return item;\n }\n\n // Otherwise, this is the one we want - return an updated value\n return {\n ...item,\n ...updatedItem\n };\n });\n}\n*/\nconst now = new Date();\nconst call = (\n state = {\n isWaiting: false,\n shortName: \"\",\n byId: {},\n allIds: [],\n oldestCallTime: now,\n newestCallTime: now,\n filterType: 0,\n filterTalkgroups: [],\n filterGroupId: false,\n filterDate: false,\n filterStarred: false,\n currentCallId: false,\n live: false\n },\n action\n) => {\n switch (action.type) {\n\n case SET_CURRENT_CALL_ID:\n return Object.assign({}, state, {currentCallId: action.data});\n \n case SET_FILTER:\n {\n var filter={};\n filter.live = !action.data.live ? state.live : action.data.live;\n filter.filterStarred = !action.data.filterStarred ? false : action.data.filterStarred;\n filter.filterType = !action.data.filterType ? 0 : action.data.filterType;\n filter.filterTalkgroups = !action.data.filterTalkgroups ? [] : action.data.filterTalkgroups;\n filter.filterGroupId = !action.data.filterGroupId ? false : action.data.filterGroupId;\n filter.filterDate = !action.data.filterDate ? 0 : action.data.filterDate;\n return Object.assign({}, state, {\n live: action.data.live,\n filterType: action.data.filterType,\n filterTalkgroups: action.data.filterTalkgroups,\n filterGroupId: action.data.filterGroupId,\n filterDate: action.data.filterDate,\n filterStarred: action.data.filterStarred\n });\n }\n\n case SET_LIVE:\n return Object.assign({}, state, {live: action.data});\n \n case SET_SHORT_NAME:\n return Object.assign({}, state, {shortName: action.data});\n\n case SET_DATE_FILTER:\n return Object.assign({}, state, {filterDate: action.date});\n\n case SET_STARRED_FILTER:\n return Object.assign({}, state, {filterStarred: action.data});\n\n case SET_ALL_FILTER:\n return Object.assign({}, state, {filterType: 0, filterTalkgroups:[], filterGroupId: false});\n\n case SET_GROUP_FILTER:\n return Object.assign({}, state, {filterType: 1, filterTalkgroups:[], filterGroupId: action.groupId});\n\n case SET_TALKGROUP_FILTER:\n return Object.assign({}, state, {filterType: 2, filterTalkgroups: action.talkgroups, filterGroupId: false});\n\n case FETCH_CALL_INFO:\n case FETCH_CALL:\n return Object.assign({}, state, { isWaiting: true});\n\n case FETCH_SUCCESS_CALL_INFO:\n return Object.assign({}, state, {\n byId: {...state.byId, [action.data._id]: action.data },\n isWaiting: false\n\n });\n\n case ADD_STAR_SUCCESS:\n return Object.assign({}, state,{\n byId: {...state.byId, [action.data._id]: action.data },\n isWaiting: false\n\n });\n // This will set the items to the rx data\n case FETCH_SUCCESS_CALL:\n {\n const byId = action.data.calls.reduce((acc, call) => ({ ...acc, [call._id]: call }), {});\n const allIds = action.data.calls.map(call => call._id);\n return Object.assign({}, state, {\n isWaiting: false,\n shortName: action.data.shortName,\n newestCallTime: new Date(action.data.calls[0].time),\n oldestCallTime: new Date(action.data.calls[action.data.calls.length-1].time),\n byId: { ...byId},\n allIds: [...allIds]\n });\n }\n\n case UPSERT_CALL:\n if (typeof state.byId[action.data._id] !== \"undefined\") {\n return Object.assign({}, state, {\n byId: {...state.byId, [action.data._id]: action.data },\n });\n } else {\n return Object.assign({}, state, {\n newestCallTime: new Date(action.data.time),\n byId: {[action.data._id]: action.data, ...state.byId},\n allIds: [action.data._id, ...state.allIds]\n }); \n }\n\n case PREPEND_CALL:\n return Object.assign({}, state, {\n isWaiting: false,\n newestCallTime: new Date(action.data.time),\n byId: {[action.data._id]: action.data, ...state.byId},\n allIds: [action.data._id, ...state.allIds]\n });\n\n// This will add the array of Calls in the data to the beginning of the existing array of Calls\n case FETCH_SUCCESS_NEWER_CALL:\n const byId = action.data.calls.reduce((acc, call) => ({ ...acc, [call._id]: call }), {});\n const allIds = action.data.calls.map(call => call._id).reverse();\n return Object.assign({}, state, {\n isWaiting: false,\n shortName: action.data.shortName,\n newestCallTime: new Date(action.data.calls[action.data.calls.length-1].time),\n byId: {...state.byId, ...byId},\n allIds: [...allIds, ...state.allIds]\n });\n\n// This will add the array of Calls in the data to the end of the existing array of Calls\n case FETCH_SUCCESS_OLDER_CALL:\n {\n const byId = action.data.calls.reduce((acc, call) => ({ ...acc, [call._id]: call }), {});\n const allIds = action.data.calls.map(call => call._id);\n return Object.assign({}, state, {\n isWaiting: false,\n shortName: action.data.shortName,\n oldestCallTime: new Date(action.data.calls[action.data.calls.length-1].time),\n byId: {...state.byId, ...byId},\n allIds: [ ...state.allIds, ...allIds]\n });\n }\n case FETCH_ERROR_CALL_INFO:\n case FETCH_ERROR_CALL:\n return Object.assign({}, state, {\n isWaiting: false\n });\n\n default:\n return state;\n }\n};\n\nexport default call;\n","/Users/luke/Projects/OpenMHz/trunk-server-public/frontend/src/Call/call-constants.js",[],{"ruleId":"152","severity":1,"message":"153","line":12,"column":3,"nodeType":"154","messageId":"155","endLine":16,"endColumn":4},{"ruleId":"156","severity":1,"message":"157","line":6,"column":7,"nodeType":"158","messageId":"159","endLine":6,"endColumn":30},{"ruleId":"156","severity":1,"message":"160","line":22,"column":10,"nodeType":"158","messageId":"159","endLine":22,"endColumn":21},{"ruleId":"161","severity":1,"message":"162","line":76,"column":3,"nodeType":"163","messageId":"164","endLine":82,"endColumn":4},{"ruleId":"165","replacedBy":"166"},{"ruleId":"167","replacedBy":"168"},{"ruleId":"165","replacedBy":"169"},{"ruleId":"167","replacedBy":"170"},{"ruleId":"156","severity":1,"message":"171","line":285,"column":15,"nodeType":"158","messageId":"159","endLine":285,"endColumn":19},{"ruleId":"172","severity":1,"message":"173","line":446,"column":27,"nodeType":"174","messageId":"175","endLine":446,"endColumn":29},{"ruleId":"165","replacedBy":"176"},{"ruleId":"167","replacedBy":"177"},{"ruleId":"178","severity":1,"message":"179","line":1,"column":1,"nodeType":"180","endLine":11,"endColumn":2},{"ruleId":"165","replacedBy":"181"},{"ruleId":"167","replacedBy":"182"},{"ruleId":"156","severity":1,"message":"183","line":6,"column":3,"nodeType":"158","messageId":"159","endLine":6,"endColumn":9},{"ruleId":"156","severity":1,"message":"184","line":7,"column":10,"nodeType":"158","messageId":"159","endLine":7,"endColumn":30},{"ruleId":"156","severity":1,"message":"185","line":11,"column":10,"nodeType":"158","messageId":"159","endLine":11,"endColumn":32},{"ruleId":"156","severity":1,"message":"186","line":18,"column":10,"nodeType":"158","messageId":"159","endLine":18,"endColumn":30},{"ruleId":"156","severity":1,"message":"187","line":25,"column":10,"nodeType":"158","messageId":"159","endLine":25,"endColumn":30},{"ruleId":"156","severity":1,"message":"188","line":29,"column":10,"nodeType":"158","messageId":"159","endLine":29,"endColumn":32},{"ruleId":"156","severity":1,"message":"189","line":33,"column":10,"nodeType":"158","messageId":"159","endLine":33,"endColumn":30},{"ruleId":"156","severity":1,"message":"190","line":53,"column":10,"nodeType":"158","messageId":"159","endLine":53,"endColumn":25},{"ruleId":"156","severity":1,"message":"191","line":7,"column":10,"nodeType":"158","messageId":"159","endLine":7,"endColumn":22},{"ruleId":"156","severity":1,"message":"192","line":13,"column":10,"nodeType":"158","messageId":"159","endLine":13,"endColumn":27},{"ruleId":"193","severity":1,"message":"194","line":77,"column":3,"nodeType":"154","messageId":"175","endLine":78,"endColumn":4},{"ruleId":"156","severity":1,"message":"195","line":89,"column":5,"nodeType":"158","messageId":"159","endLine":89,"endColumn":16},{"ruleId":"165","replacedBy":"196"},{"ruleId":"167","replacedBy":"197"},{"ruleId":"165","replacedBy":"198"},{"ruleId":"167","replacedBy":"199"},{"ruleId":"156","severity":1,"message":"200","line":41,"column":18,"nodeType":"158","messageId":"159","endLine":41,"endColumn":21},{"ruleId":"156","severity":1,"message":"191","line":24,"column":10,"nodeType":"158","messageId":"159","endLine":24,"endColumn":22},{"ruleId":"156","severity":1,"message":"201","line":30,"column":10,"nodeType":"158","messageId":"159","endLine":30,"endColumn":27},"no-useless-constructor","Useless constructor.","MethodDefinition","noUselessConstructor","no-unused-vars","'FETCH_SUCCESS_STATISTIC' is assigned a value but never used.","Identifier","unusedVar","'prependCall' is defined but never used.","no-unreachable","Unreachable code.","IfStatement","unreachableCode","no-native-reassign",["202"],"no-negated-in-lhs",["203"],["202"],["203"],"'refs' is assigned a value but never used.","eqeqeq","Expected '!==' and instead saw '!='.","BinaryExpression","unexpected",["202"],["203"],"import/no-anonymous-default-export","Assign object to a variable before exporting as module default","ExportDefaultDeclaration",["202"],["203"],"'Header' is defined but never used.","'beginImportTalkgroup' is defined but never used.","'importTalkgroupSuccess' is defined but never used.","'importTalkgroupError' is defined but never used.","'beginExportTalkgroup' is defined but never used.","'exportTalkgroupSuccess' is defined but never used.","'exportTalkgroupError' is defined but never used.","'makeUserRequest' is defined but never used.","'updateObject' is defined but never used.","'updateItemInArray' is defined but never used.","no-dupe-class-members","Duplicate name 'componentDidUpdate'.","'playEnabled' is assigned a value but never used.",["202"],["203"],["202"],["203"],"'src' is assigned a value but never used.","'updateCallInItems' is defined but never used.","no-global-assign","no-unsafe-negation"]
\ No newline at end of file
diff --git a/frontend/src/Call/CallPlayer.js b/frontend/src/Call/CallPlayer.js
index ff302b8..f7bc79a 100644
--- a/frontend/src/Call/CallPlayer.js
+++ b/frontend/src/Call/CallPlayer.js
@@ -53,6 +53,7 @@ class CallPlayer extends React.Component {
this.endSocket = this.endSocket.bind(this);
this.changeUrl = this.changeUrl.bind(this);
this.audioRef = React.createRef();
+ this.currentCallRef = React.createRef();
this.state = {
requestMessage: "",
callUrl: "",
@@ -252,6 +253,13 @@ class CallPlayer extends React.Component {
var callUrl = nextCall.url;
this.setState({callUrl: callUrl, callId: nextCallId, sourceIndex: 0, isPlaying: true}, () => { audio.playSource(callUrl)}); //scrollToComponent(this.currentCallRef.current);
+ if (this.currentCallRef.current) {
+ this.currentCallRef.current.scrollIntoView({
+ behavior: "smooth",
+
+ block: "center",
+ });
+ }
this.props.callActions.fetchCallInfo( nextCallId);
} else {
this.setState({isPlaying: false});
@@ -542,7 +550,7 @@ class CallPlayer extends React.Component {
style={{ minHeight: '100vh' }}
>
-
+
diff --git a/frontend/src/Call/ListCalls.js b/frontend/src/Call/ListCalls.js
index 5d931ec..582b4a6 100644
--- a/frontend/src/Call/ListCalls.js
+++ b/frontend/src/Call/ListCalls.js
@@ -11,23 +11,10 @@ import "./CallPlayer.css";
class ListCalls extends React.Component {
constructor(props) {
super(props);
- this.handleCurrentCallRef = this.handleCurrentCallRef.bind(this);
//this.currentCallRef = React.createRef();
}
- handleCurrentCallRef(ref) {
- this.currentCallRef = ref
- console.log("Setting it")
- }
- componentDidUpdate(prevProps, prevState) {
- if (this.currentCallRef && this.props.activeCallId && (this.props.activeCallId != prevProps.activeCallId)) {
- this.currentCallRef.scrollIntoView({
- behavior: "smooth",
- block: "center",
- });
- }
- }
//https://stackoverflow.com/questions/36559661/how-can-i-dispatch-from-child-components-in-react-redux
//https://stackoverflow.com/questions/42597602/react-onclick-pass-event-with-parameter
@@ -47,7 +34,7 @@ class ListCalls extends React.Component {
{this.props.callsAllIds.map((callId, index) => {
if (callId === this.props.activeCallId) {
- return ()
+ return ()
} else {
return
}