From ba15de8d3091842f48c5bac071c258b98fc6ccf2 Mon Sep 17 00:00:00 2001 From: Luke Berndt Date: Sat, 14 Jan 2023 22:43:10 -0500 Subject: [PATCH] added stars and new calls --- backend/controllers/calls.js | 34 +- backend/index.js | 2 +- frontend/src/Call/CallItem.js | 111 ++--- frontend/src/Call/CallPlayer.js | 559 +++++++++------------- frontend/src/features/calls/callsSlice.js | 51 +- 5 files changed, 345 insertions(+), 412 deletions(-) diff --git a/backend/controllers/calls.js b/backend/controllers/calls.js index 64c282e..ef3170a 100644 --- a/backend/controllers/calls.js +++ b/backend/controllers/calls.js @@ -241,7 +241,39 @@ function package_call(item) { return call; } - +exports.remove_star = function(req, res, next) { + var objectId = req.params.id; + try { + var o_id = ObjectID.createFromHexString(objectId); + } catch (err) { + console.warn("[" + req.params.shortName + "] Error - /:shortName/call/:id generating ObjectID " + err); + res.status(500); + res.send(JSON.stringify({ + success: false, + message: err, + "_id": objectId + })); + return; + } + Call.findOneAndUpdate({ _id: objectId }, { $inc: { star: -1 } }, {new: true },function(err, item) { + if (err) { + res.status(500); + res.send(JSON.stringify({ + success: false, + message: err, + "_id": objectId + })); + } else { + var call = package_call(item); + req.call = call; + res.send(JSON.stringify({ + success: true, + call: call + })); + next(); + } + }) +} exports.add_star = function(req, res, next) { diff --git a/backend/index.js b/backend/index.js index 3783940..a748c0f 100644 --- a/backend/index.js +++ b/backend/index.js @@ -178,7 +178,7 @@ app.get('/:shortName/calls/older', calls.get_older_calls); app.get('/:shortName/calls/:time/older', calls.get_iphone_calls); app.get('/:shortName/calls', calls.get_calls); app.post('/:shortName/star/:id', calls.add_star); - +app.post('/:shortName/removeStar/:id', calls.remove_star); /*------ UPLOADS ---------- upload.single('call'), uploads.upload,*/ app.post('/:shortName/upload', upload.single('call'), uploads.upload, async function (req, res) { diff --git a/frontend/src/Call/CallItem.js b/frontend/src/Call/CallItem.js index d41949d..572ac3a 100644 --- a/frontend/src/Call/CallItem.js +++ b/frontend/src/Call/CallItem.js @@ -1,88 +1,44 @@ -import React, { Component } from "react"; +import React, { useState } from "react"; import { Table, Icon, Label } from "semantic-ui-react"; import { connect } from "react-redux" -import { bindActionCreators } from 'redux' -import * as callActionCreators from "./call-actions" +import { addStar, removeStar} from "../features/calls/callsSlice"; +import { useDispatch } from 'react-redux' -function mapStateToProps(state, props) { - return { - shortName: props.shortName +const CallItem = (props) => { - } -} - -function mapDispatchToProps(dispatch) { - return { - callActions: bindActionCreators(callActionCreators, dispatch) - } -} - - -class CallItem extends Component { -constructor(props) { - super(props); - this.hideStar = this.hideStar.bind(this); - this.showStar = this.showStar.bind(this); - this.addStar = this.addStar.bind(this); - this.state = { - starVisible: false, - starClicked: false - } -} -sourceString(call) { - var srcString = ""; - if (call.srcList) { - for (var src in call.srcList) { - /* srcNum = call.srcList[src].src; - if (sources.hasOwnProperty(srcNum)) { - srcString = srcString + sources[srcNum].codeName + ", "; - }*/ - } - } - - return srcString; -} - -componentDidUpdate(){ - if (this.props.activeCall) { - console.log("Active call mounted") - } -} -addStar(e) { - e.preventDefault(); - e.stopPropagation(); - e.nativeEvent.stopImmediatePropagation(); - if (!this.state.starClicked) { - - this.props.callActions.addStar(this.props.call._id); - this.setState({starClicked: true}); - } -} - -hideStar() { - this.setState({ starVisible: false }) -} - -showStar() { - this.setState({ starVisible: true }) -} - -render() { - const call = this.props.call; + const [starVisible, setStarVisible] = useState(false); + const [starClicked, setStarClicked] = useState(false); + const dispatch = useDispatch(); + const call = props.call; const time = new Date(call.time); + const activeCall = props.activeCall; + + const handleStarClicked = (e) => { + e.preventDefault(); + e.stopPropagation(); + e.nativeEvent.stopImmediatePropagation(); + if (!starClicked) { + setStarClicked(true); + dispatch(addStar(props.call._id)); + } else { + setStarClicked(false); + dispatch(removeStar(props.call._id)); + } + } + var rowSelected={}; let starButton; var starClickable = {}; - if (!this.state.starClicked) { + if (!starClicked) { starClickable = {link: true }; } - if (!call.star && this.state.starVisible) { + if (!call.star && starVisible) { starButton = } @@ -98,7 +54,7 @@ render() { ) } - if (this.props.activeCall) { + if (activeCall) { rowSelected={positive: true, color: "blue", key: "blue", @@ -106,26 +62,21 @@ render() { } } var talkgroup; - if ((typeof this.props.talkgroups == 'undefined') || (typeof this.props.talkgroups[call.talkgroupNum] == 'undefined')) { + if ((typeof props.talkgroups == 'undefined') || (typeof props.talkgroups[call.talkgroupNum] == 'undefined')) { talkgroup = call.talkgroupNum; } else { - talkgroup = this.props.talkgroups[call.talkgroupNum].description; + talkgroup = props.talkgroups[call.talkgroupNum].description; } return ( - this.props.onClick({call: call}, e)} {...rowSelected}> + props.onClick({call: call}, e)} {...rowSelected}> {call.len} {talkgroup} {time.toLocaleTimeString()} - {starButton} + setStarVisible(true)} onMouseLeave={() => setStarVisible(false)} onClick={handleStarClicked}>{starButton} ); } -} - -export default connect( - mapStateToProps, - mapDispatchToProps -)(CallItem) +export default CallItem; diff --git a/frontend/src/Call/CallPlayer.js b/frontend/src/Call/CallPlayer.js index 1fd8c1d..21675b5 100644 --- a/frontend/src/Call/CallPlayer.js +++ b/frontend/src/Call/CallPlayer.js @@ -1,5 +1,5 @@ -import React, { useEffect, useState, useRef } from "react"; -import { Link, useLocation, useParams, useNavigate} from 'react-router-dom'; +import React, { useEffect, useState, useRef } from "react"; +import { Link, useLocation, useParams, useNavigate } from 'react-router-dom'; import MediaPlayer from "./MediaPlayer"; import FilterModal from "./FilterModal"; @@ -10,7 +10,7 @@ import CallInfo from "./CallInfo"; import ListCalls from "./ListCalls"; import { useSelector, useDispatch } from 'react-redux' import { setLive, setShortName, setFilter } from "../features/callPlayer/callPlayerSlice"; -import { getCalls, getOlderCalls, getNewerCalls} from "../features/calls/callsSlice"; +import { getCalls, getOlderCalls, getNewerCalls, addCall } from "../features/calls/callsSlice"; import { useGetGroupsQuery, useGetTalkgroupsQuery } from '../features/api/apiSlice' import { useInView } from 'react-intersection-observer'; import { @@ -24,78 +24,76 @@ import { Button } from "semantic-ui-react"; import "./CallPlayer.css"; -//import setupSocket from '../socket/SetupSocket.js' import queryString from '../query-string'; import io from 'socket.io-client'; import { setDateFilter } from "./call-actions"; -const socket = io(process.env.REACT_APP_BACKEND_SERVER ); +const socket = io(process.env.REACT_APP_BACKEND_SERVER); // ---------------------------------------------------- -function CallPlayer (props) { +function CallPlayer(props) { - const { shortName } = useParams(); - const { ref: loadOlderRef, inView: loadOlderInView, entry: loadOlderEntry } = useInView({ - /* Optional options */ - threshold: 0.5 - }); - const { ref: loadNewerRef, inView: loadNewerInView, entry: loadNewerEntry } = useInView({ - /* Optional options */ - threshold: 0.5 - }); - const { data:groupsData, isSuccess:isGroupsSuccess } = useGetGroupsQuery(shortName); - //const { data:callsData, isSuccess:isCallsSuccess } = useGetCallsQuery({shortName}); - const {loading: callsLoading, data: callsData} = useSelector((state) => state.calls); - - //console.log(callsData); - const { data:talkgroupsData, isSuccess:isTalkgroupsSuccess } = useGetTalkgroupsQuery(shortName); - //const allCalls = callsData?callsData.ids.map( id => callsData.entities[id] ):[] + const { shortName } = useParams(); + const { ref: loadOlderRef, inView: loadOlderInView, entry: loadOlderEntry } = useInView({ + /* Optional options */ + threshold: 0.5 + }); + const { ref: loadNewerRef, inView: loadNewerInView, entry: loadNewerEntry } = useInView({ + /* Optional options */ + threshold: 0.5 + }); + const { data: groupsData, isSuccess: isGroupsSuccess } = useGetGroupsQuery(shortName); + //const { data:callsData, isSuccess:isCallsSuccess } = useGetCallsQuery({shortName}); + const { loading: callsLoading, data: callsData } = useSelector((state) => state.calls); - const [autoPlay, setAutoPlay] = useState(true); - const [addCallScroll, setAddCallScroll] = useState(false); - const [currentCall, setCurrentCall] = useState(false); - const [prevScrollHeight, setPrevScrollHeight] = useState(0); - const [playTime, setPlayTime] = useState(0); - const [selectLoadCall, setSelectLoadCall] = useState(false); - const [callSelect, setCallSelect] = useState(false); - const [urlOptions, setUrlOptions] = useState(false); - const [isPlaying, setIsPlaying] = useState(false); - const [sidebarOpened, setSidebarOpened] = useState(false); - const [filterVisible, setFilterVisible] = useState(false); - const [groupVisible, setGroupVisible] = useState(false); - const [calendarVisible, setCalendarVisible] = useState(false); - const [isConnected, setIsConnected] = useState(socket.connected); - const [loadCallId, setLoadCallId] = useState(false); + //console.log(callsData); + const { data: talkgroupsData, isSuccess: isTalkgroupsSuccess } = useGetTalkgroupsQuery(shortName); + //const allCalls = callsData?callsData.ids.map( id => callsData.entities[id] ):[] - const navigate = useNavigate(); - const dispatch = useDispatch(); - const positionRef = useRef(); + const [autoPlay, setAutoPlay] = useState(true); + const [addCallScroll, setAddCallScroll] = useState(false); + const [currentCall, setCurrentCall] = useState(false); + const [prevScrollHeight, setPrevScrollHeight] = useState(0); + const [playTime, setPlayTime] = useState(0); + const [selectLoadCall, setSelectLoadCall] = useState(false); + const [urlOptions, setUrlOptions] = useState(false); + const [isPlaying, setIsPlaying] = useState(false); + const [sidebarOpened, setSidebarOpened] = useState(false); + const [filterVisible, setFilterVisible] = useState(false); + const [groupVisible, setGroupVisible] = useState(false); + const [calendarVisible, setCalendarVisible] = useState(false); + const [isConnected, setIsConnected] = useState(socket.connected); + const [loadCallId, setLoadCallId] = useState(false); - const filterType = useSelector((state) => state.callPlayer.filterType); - const filterGroupId = useSelector((state) => state.callPlayer.filterGroupId); - const filterTalkgroups = useSelector((state) => state.callPlayer.filterTalkgroups); - const filterStarred = useSelector((state) => state.callPlayer.filterStarred); - const filterDate = useSelector((state) => state.callPlayer.filterDate); - const live = useSelector((state) => state.callPlayer.live); - const uri = queryString.parse(useLocation().search); - const pathname = useLocation().pathname; + const navigate = useNavigate(); + const dispatch = useDispatch(); + const positionRef = useRef(); - let currentCallId = false; - let currentCallMedia = false; + const filterType = useSelector((state) => state.callPlayer.filterType); + const filterGroupId = useSelector((state) => state.callPlayer.filterGroupId); + const filterTalkgroups = useSelector((state) => state.callPlayer.filterTalkgroups); + const filterStarred = useSelector((state) => state.callPlayer.filterStarred); + const filterDate = useSelector((state) => state.callPlayer.filterDate); + const live = useSelector((state) => state.callPlayer.live); + const uri = queryString.parse(useLocation().search); + const pathname = useLocation().pathname; - if (currentCall) { - currentCallId = currentCall._id; - currentCallMedia = currentCall.url; - } + let currentCallId = false; + let currentCallMedia = false; + + if (currentCall) { + currentCallId = currentCall._id; + currentCallMedia = currentCall.url; + } const handlePlayPause = (playing) => setIsPlaying(playing); - - const handlePusherClick = () => { + + const handlePusherClick = () => { if (sidebarOpened) setSidebarOpened(false); } @@ -105,35 +103,30 @@ function CallPlayer (props) { const handleCalendarToggle = () => setCalendarVisible(!calendarVisible); const playCall = (data) => { - setCurrentCall(data.call); - setIsPlaying(true); - } - + setCurrentCall(data.call); + setIsPlaying(true); + } + const callEnded = () => { if (callsData) { - const currentIndex = callsData.ids.findIndex(callId => callId === currentCallId); - if (autoPlay && (currentIndex > 0)) { - const nextCallId = callsData.ids[currentIndex - 1]; - const nextCall = callsData.entities[nextCallId]; + const currentIndex = callsData.ids.findIndex(callId => callId === currentCallId); + if (autoPlay && (currentIndex > 0)) { + const nextCallId = callsData.ids[currentIndex - 1]; + const nextCall = callsData.entities[nextCallId]; - setCurrentCall(nextCall); - setIsPlaying(true); + setCurrentCall(nextCall); + setIsPlaying(true); + } else { + setIsPlaying(false); + } } else { - setIsPlaying(false); + console.log("Somehow called, callEnded() but callsData was false"); } - } else { - console.log("Somehow called, callEnded() but callsData was false"); } - } - /*const changeUrl = url => callActions.changeUrl(url) + const getFilterDescription = () => { -*/ - - -const getFilterDescription = () => { - var filter = { type: 'all', code: "", filterStarred: false }; switch (filterType) { @@ -152,16 +145,17 @@ const getFilterDescription = () => { } filter.filterStarred = filterStarred return filter; -} + } - const addCall = (data) =>{ + const handleSocketMessage = (data) => { const message = JSON.parse(data) switch (message.type) { case 'calls': const ref = positionRef; setPrevScrollHeight(positionRef.clientHeight); setAddCallScroll(true); + dispatch(addCall(message)) /*const refs = this.refs.current; callActions.addCall(message); const newCall = callsById[callsAllIds[0]]; @@ -181,32 +175,6 @@ const getFilterDescription = () => { } } - useEffect(() => { - socket.on('connect', () => { - setIsConnected(true); - }); - - socket.on('disconnect', () => { - setIsConnected(false); - }); - - socket.on('reconnect', (attempts) => { - console.log("Socket Reconnected after attempts: " + attempts); // true - - if (live) { - this.startSocket(); - } - }) - - socket.on("new message", addCall); - - return () => { - socket.off('connect'); - socket.off('disconnect'); - socket.off('pong'); - }; - }, []); - const startSocket = () => { const filter = getFilterDescription(); socket.emit("start", { @@ -227,7 +195,7 @@ const getFilterDescription = () => { setCurrentCall(false); dispatch(getCalls({})); - + this.startSocket(); } } @@ -235,7 +203,7 @@ const getFilterDescription = () => { -const updateUri = () => { + const updateUri = () => { var search = "?" switch (filterType) { @@ -269,7 +237,7 @@ const updateUri = () => { } search = search + `starred=true`; } - navigate(pathname + search, {replace:true}); + navigate(pathname + search, { replace: true }); } @@ -313,8 +281,7 @@ const updateUri = () => { if (uri.hasOwnProperty('starred')) { const starred = uri['starred']; filter.filterStarred = starred === 'true' ? true : false; - - this.setState({ urlOptions: true }); + if (!urlOptions) setUrlOptions(true); } // is there a time based filter? @@ -322,7 +289,7 @@ const updateUri = () => { const date = new Date(parseInt(uri['time'])); filter.filterDate = date.getTime(); filter.live = false; - this.setState({ urlOptions: true }); + if (!urlOptions) setUrlOptions(true); } // is this just for one call? @@ -332,13 +299,7 @@ const updateUri = () => { setLoadCallId(_id); setSelectLoadCall(true); setAutoPlay(false); - this.setState({ - callId: _id, - urlOptions: true, - autoPlay: false, - callScroll: true, - callSelect: true - }); + if (!urlOptions) setUrlOptions(true); //callActions.fetchCallInfo(_id); //callActions.setCallTime(date); } @@ -349,7 +310,7 @@ const updateUri = () => { // is there a Filter set? if ((uri.hasOwnProperty('filter-code')) && (uri.hasOwnProperty('filter-type'))) { - this.setState({ urlOptions: true }); + if (!urlOptions) setUrlOptions(true); // The Filter is a group if (uri['filter-type'] === "group") { @@ -399,247 +360,187 @@ const updateUri = () => { setCurrentCall(call); } } - },[callsData]) + }, [callsData]) useEffect(() => { - // When a time/date is provided in the URL, it will be added to the filter - // When fetchCalls is called it will selected calls that are older - //callActions.fetchCalls(); - //talkgroupActions.fetchTalkgroups(shortName); - //groupActions.fetchGroups(shortName); - //systemActions.fetchSystems(); - - - setStateFromUri(); - //console.log("Setting short name to: " + shortName) - //dispatch(setShortName(shortName)); - return () => { - //this.endSocket(); + stopSocket(); + }; + }, []); + + useEffect(() => { + socket.on('connect', () => { + setIsConnected(true); + }); + + socket.on('disconnect', () => { + setIsConnected(false); + }); + + socket.on('reconnect', (attempts) => { + console.log("Socket Reconnected after attempts: " + attempts); // true + + if (live) { + this.startSocket(); + } + }) + + socket.on("new message", handleSocketMessage); + + return () => { + socket.off('connect'); + socket.off('disconnect'); + socket.off('pong'); }; }, []); useEffect(() => { - updateUri(); dispatch(getCalls({})); if (live) { startSocket(); } - //dispatch(getOlderCalls()); - }, [shortName,filterGroupId,filterTalkgroups,filterType,filterDate,filterStarred]) + }, [shortName, filterGroupId, filterTalkgroups, filterType, filterDate, filterStarred]) + // Update the Browser URI when any relevant values change + useEffect(() => { + updateUri(); + }, [filterGroupId, filterTalkgroups, filterType, filterDate, filterStarred, loadCallId]) - const compareArray = (a1, a2) => { - var i = a1.length; - while (i--) { - if (a1[i] !== a2[i]) - return false; - } - return true - } - useEffect( () => { + useEffect(() => { if (!urlOptions && groupsData && (groupsData.length > 0)) { setGroupVisible(true); } - },[groupsData] ) - - /* - componentWillUpdate(nextProps, nextState) { + }, [groupsData]) - const callsChanged = nextProps.callsAllIds[0] !== callsAllIds[0]; - if (callsChanged) { - const { contextRef } = this.state; - this.scrollPos = contextRef.scrollTop; - this.prevHeight = contextRef.clientHeight; - this.autoScroll = true; + var archiveLabel = ""; + if (filterDate) { + const filterDateObj = new Date(filterDate); + archiveLabel = filterDateObj.toLocaleDateString() + " " + filterDateObj.toLocaleTimeString() + } + + var callInfoHeader = "Call Info"; + var callLink = "" + var callDownload = "" + if (currentCall) { + if ((talkgroupsData) && talkgroupsData[currentCall.talkgroupNum]) { + callInfoHeader = talkgroupsData[currentCall.talkgroupNum].description; } - - - if (callId && !callUrl) { - const call = callsById[callId]; - if (call) { - this.setState({ callUrl: call.url }); - } - } - }*/ -/* - componentDidUpdate(prevProps, prevState) { - const { contextRef } = this.state - //console.log( contextRef.clientHeight - this.prevHeight ); - if (this.autoScroll) { - this.autoScroll = false; - window.scrollBy(0, contextRef.clientHeight - this.prevHeight); - } - - // scroll to a call once the calls have loaded - if (callScroll && (callsAllIds.length > prevProps.callsAllIds.length)) { - const call = callsById[callId]; - if (call) { - this.setState({ callScroll: false }); - if (this.currentCallRef.current) { - this.currentCallRef.current.scrollIntoView({ - behavior: "auto", - block: "center", - }); - } - this.scrollPos = contextRef.scrollTop; - this.prevHeight = contextRef.clientHeight; - } - } - - if (callSelect) { - const call = callsById[callId]; - if (call) { - const audio = this.audioRef.current; - var callUrl = call.url; - this.setState({ - callUrl: callUrl, - isPlaying: true, - callSelect: false - }, () => { audio.playSource(callUrl); }); //scrollToComponent(this.currentCallRef.current); - } - } - }*/ - - //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 - - //const { contextRef } = this.state - - var archiveLabel = ""; - if (filterDate) { - const filterDate = new Date(filterDate); - archiveLabel = filterDate.toLocaleDateString() + " " + filterDate.toLocaleTimeString() - } - - var callInfoHeader = "Call Info"; - - - - - var callsAllIds = []; - var callsById = false; - var callLink = "" - var callDownload = "" - if (currentCall) { - if ((talkgroupsData) && talkgroupsData[currentCall.talkgroupNum]) { - callInfoHeader = talkgroupsData[currentCall.talkgroupNum].description; - } - const callDate = new Date(currentCall.time); - callLink = "/system/" + shortName + "?call-id=" + currentCall._id + "&time=" + (callDate.getTime() + 1); - callDownload = currentCall.url; - } - var archive = process.env.REACT_APP_ARCHIVE_DAYS - - var filterLabel = "All" + const callDate = new Date(currentCall.time); + var search = "" switch (filterType) { - case 1: - filterLabel = "Group" - break; + case 1: + search = `filter-type=group&filter-code=${filterGroupId}&`; + break; case 2: - filterLabel = "Talkgroups" + search = `filter-type=talkgroup&filter-code=${filterTalkgroups}&`; break; default: case 0: - filterLabel = "All" + break; + } - /* if (calls) { - var callRows = calls.map((call) => - - )) - }*/ - - - return ( -
- - - - - - - - Home - Systems - About - - - - - - - - Filter - - - - {/*system && system.name*/} - - - - - - { - archiveLabel - ? archiveLabel - : "Archive" - } - - - - - Live - - - - - - - - - - -
- -
- - - - - - - - - - - - - setAutoPlay(!autoPlay)}>Autoplay - - - - Download - Link - - - -
- - - - - - ); + callLink = "/system/" + shortName + "?" + search + "call-id=" + currentCall._id + "&time=" + (callDate.getTime() + 1); + callDownload = currentCall.url; } + const archive = process.env.REACT_APP_ARCHIVE_DAYS + + var filterLabel = "All" + switch (filterType) { + case 1: + filterLabel = "Group" + break; + + case 2: + filterLabel = "Talkgroups" + break; + default: + case 0: + filterLabel = "All" + } + + return ( +
+ + + + + + + + Home + Systems + About + + + + + + + + Filter + + + + {/*system && system.name*/} + + + + + + { + archiveLabel + ? archiveLabel + : "Archive" + } + + + + + Live + + + + + + + +
+ +
+ + + + + + + + + + + + + setAutoPlay(!autoPlay)}>Autoplay + + + + Download + Link + + + +
+ ); +} + export default CallPlayer; diff --git a/frontend/src/features/calls/callsSlice.js b/frontend/src/features/calls/callsSlice.js index 2d446ca..9ed497c 100644 --- a/frontend/src/features/calls/callsSlice.js +++ b/frontend/src/features/calls/callsSlice.js @@ -125,6 +125,44 @@ const initialState = { return url; } +export const addStar = createAsyncThunk( + 'calls/addStar', + async(callId,{getState, requestIdleCallback}) => { + const {shortName} = getState().callPlayer; + const url = process.env.REACT_APP_BACKEND_SERVER + "/" + shortName.toLowerCase() + "/star/" + callId + const res = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, + body: "{}" + + }).then( + (data) => data.json() + ) + return res; + } +) + +export const removeStar = createAsyncThunk( + 'calls/removeStar', + async(callId,{getState, requestIdleCallback}) => { + const {shortName} = getState().callPlayer; + const url = process.env.REACT_APP_BACKEND_SERVER + "/" + shortName.toLowerCase() + "/removeStar/" + callId + const res = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, + body: "{}" + + }).then( + (data) => data.json() + ) + return res; + } +) + export const getCalls = createAsyncThunk( 'calls/getCalls', async({},{getState, requestId}) => { @@ -162,7 +200,12 @@ export const getCalls = createAsyncThunk( export const callsSlice = createSlice({ name: 'calls', initialState, - reducers: {}, + reducers: { + + addCall: (call) => { + state.data = callsAdapter.addOne(state.data, call) + }, + }, extraReducers: { [getCalls.pending]: (state) => { state.loading = true; @@ -218,6 +261,12 @@ export const callsSlice = createSlice({ state.oldestCallTime = new Date(lastTime) } }, + [addStar.fulfilled]: (state, {payload}) => { + state.data.entities[payload.call._id] = payload.call; + }, + [removeStar.fulfilled]: (state, {payload}) => { + state.data.entities[payload.call._id] = payload.call; + } } })