diff --git a/frontend/src/Call/CallPlayer.js b/frontend/src/Call/CallPlayer.js
index ee39862..ee2865f 100644
--- a/frontend/src/Call/CallPlayer.js
+++ b/frontend/src/Call/CallPlayer.js
@@ -2,10 +2,9 @@ import React, { useEffect, useLayoutEffect, useState, useRef } from "react";
import { Link, useLocation, useParams, useNavigate } from 'react-router-dom';
import MediaPlayer from "./MediaPlayer";
-import FilterModal from "./FilterModal";
-import GroupModal from "./GroupModal";
+
import SupportModal from "./SupportModal";
-import CalendarModal from "./CalendarModal";
+
import CallInfo from "./CallInfo";
import ListCalls from "./ListCalls";
import { useSelector, useDispatch } from 'react-redux'
@@ -44,21 +43,22 @@ function CallPlayer(props) {
threshold: 0.5
});
const { data: groupsData, isSuccess: isGroupsSuccess } = useGetGroupsQuery(shortName);
- const { loading: callsLoading, data: callsData } = useSelector((state) => state.calls);
const { data: talkgroupsData, isSuccess: isTalkgroupsSuccess } = useGetTalkgroupsQuery(shortName);
-
+ const callsData = props.callsData;
const [autoPlay, setAutoPlay] = useState(true);
const [currentCall, setCurrentCall] = 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 navigate = useNavigate();
const dispatch = useDispatch();
const positionRef = useRef(); // lets us get the Y Scroll offset for the Call List
@@ -66,14 +66,6 @@ function CallPlayer(props) {
const shouldPlayAddCallRef = useRef(); // we need to do this to make the current value of isPlaying available in the socket message callback
shouldPlayAddCallRef.current = (!isPlaying && autoPlay)?true: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;
let currentCallId = false;
@@ -86,16 +78,10 @@ function CallPlayer(props) {
setIsPlaying(playing);
}
- const handlePusherClick = () => {
- if (sidebarOpened) setSidebarOpened(false);
- }
const handleAutoPlay = (currentAutoPlay) => {
setAutoPlay(!currentAutoPlay);
}
- const handleSidebarToggle = () => setSidebarOpened(!sidebarOpened);
- const handleFilterToggle = () => setFilterVisible(!filterVisible);
- const handleCalendarToggle = () => setCalendarVisible(!calendarVisible);
const playCall = (data) => {
setCurrentCall(data.call);
@@ -120,189 +106,8 @@ function CallPlayer(props) {
}
}
- const getFilterDescription = () => {
-
- var filter = { type: 'all', code: "", filterStarred: false };
-
- switch (filterType) {
- case 1:
- filter.type = "group";
- filter.code = filterGroupId
- break;
- case 2:
- filter.type = "talkgroup";
- filter.code = filterTalkgroups
- break;
- default:
- case 0:
- filter.type = "all";
- filter.code = ""
- }
- filter.filterStarred = filterStarred
- return filter;
- }
- const handleSocketMessage = (data) => {
- const message = JSON.parse(data)
- switch (message.type) {
- case 'calls':
-
- pageYOffset.current = positionRef.current.clientHeight;
-
- if (shouldPlayAddCallRef.current) {
- setCurrentCall(message);
- }
- dispatch(addCall(message));
-
- console.log("Got: " + message._id);
- break
- default:
- break
- }
- }
-
- const startSocket = () => {
- const filter = getFilterDescription();
-
- socket.emit("start", {
- filterCode: filter.code,
- filterType: filter.type,
- filterName: "OpenMHz",
- filterStarred: filter.starred,
- shortName: shortName
- });
- }
- const stopSocket = () => {
- socket.emit("stop");
- }
-
- const updateUri = () => {
- var search = "?"
- switch (filterType) {
-
- case 1:
- search = search + `filter-type=group&filter-code=${filterGroupId}`;
- break;
- case 2:
- search = search + `filter-type=talkgroup&filter-code=${filterTalkgroups}`;
- break;
- default:
- case 0:
- break;
-
- }
- if (loadCallId) {
- if (search.length !== 1) {
- search = search + '&';
- }
- search = search + `call-id=${loadCallId}`
- }
- if (filterDate) {
- if (search.length !== 1) {
- search = search + '&';
- }
- search = search + `time=${filterDate}`;
- }
-
- if (filterStarred) {
- if (search.length !== 1) {
- search = search + '&';
- }
- search = search + `starred=true`;
- }
- navigate(pathname + search, { replace: true });
-
- }
-
- const handleLiveToggle = (currentlyLive) => {
- if (!live) {
- dispatch(setDateFilter(false));
- dispatch(setLive(true));
- setCurrentCall(false);
- dispatch(getCalls({}));
-
- startSocket();
- }
- }
-
- const handleCalendarClose = (didUpdate) => {
- setCalendarVisible(!calendarVisible);
-
- if (didUpdate) {
- dispatch(setLive(false));
- setCurrentCall(false);
- stopSocket();
- }
- }
-
- const handleGroupClose = (didUpdate) => {
- setGroupVisible(!groupVisible);
- }
-
- const handleFilterClose = (didUpdate) => {
- setFilterVisible(!filterVisible);
-
- if (didUpdate) {
- setCurrentCall(false);
- }
- }
-
-
- const setStateFromUri = async () => {
- var filter = {
- filterDate: false,
- filterType: 0, // this is "all"
- filterTalkgroups: [],
- filterGroupId: false,
- filterStarred: false,
- live: true,
- shortName: shortName
- };
-
- // is there a star filter?
- if (uri.hasOwnProperty('starred')) {
- const starred = uri['starred'];
- filter.filterStarred = starred === 'true' ? true : false;
- if (!urlOptions) setUrlOptions(true);
- }
-
- // is there a time based filter?
- if (uri.hasOwnProperty('time')) {
- const date = new Date(parseInt(uri['time']));
- filter.filterDate = date.getTime();
- filter.live = false;
- if (!urlOptions) setUrlOptions(true);
- }
-
- // is this just for one call?
- if (uri.hasOwnProperty('call-id')) {
- const _id = uri['call-id'];
- setLoadCallId(_id);
- setAutoPlay(false);
- if (!urlOptions) setUrlOptions(true);
- }
-
- // is there a Filter set?
- if ((uri.hasOwnProperty('filter-code')) && (uri.hasOwnProperty('filter-type'))) {
- if (!urlOptions) setUrlOptions(true);
-
- // The Filter is a group
- if (uri['filter-type'] === "group") {
- filter.filterType = 1;
- filter.filterGroupId = uri["filter-code"];
- }
-
- // The Filter is talkgroups
- if (uri['filter-type'] === 'talkgroup') {
- const tg = uri["filter-code"].split(',').map(Number);
- filter.filterType = 2;
- filter.filterTalkgroups = tg;
- }
- }
-
- dispatch(setFilter(filter));
- }
useEffect(() => {
if (loadNewerInView && callsData && (callsData.ids.length > 0)) {
@@ -316,7 +121,7 @@ function CallPlayer(props) {
dispatch(getOlderCalls({}));
}
}, [loadOlderInView]);
-
+/*
useEffect(() => {
if ( loadCallId && callsData) {
const call = callsData.entities[loadCallId];
@@ -324,7 +129,7 @@ function CallPlayer(props) {
setCurrentCall(call);
}
}
- }, [callsData])
+ }, [callsData])*/
useLayoutEffect( () => {
const scrollAmount = parseInt(positionRef.current.clientHeight) - parseInt(pageYOffset.current);
@@ -339,66 +144,7 @@ function CallPlayer(props) {
}, [callsData]);
*/
- useEffect(() => {
- setStateFromUri();
- return () => {
- 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(() => {
- dispatch(getCalls({}));
- if (live) {
- startSocket();
- }
- }, [shortName, filterGroupId, filterTalkgroups, filterType, filterDate, filterStarred])
-
-
- // Update the Browser URI when any relevant values change
- useEffect(() => {
- updateUri();
- }, [filterGroupId, filterTalkgroups, filterType, filterDate, filterStarred, loadCallId])
-
-
- useEffect(() => {
- if (!urlOptions && groupsData && (groupsData.length > 0)) {
- setGroupVisible(true);
- }
- }, [groupsData])
-
-
-
- var archiveLabel = "";
- if (filterDate) {
- const filterDateObj = new Date(filterDate);
- archiveLabel = filterDateObj.toLocaleDateString() + " " + filterDateObj.toLocaleTimeString()
- }
var callInfoHeader = "Call Info";
var callLink = ""
@@ -426,70 +172,13 @@ function CallPlayer(props) {
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
-
-
-
@@ -499,7 +188,7 @@ function CallPlayer(props) {
-
+
diff --git a/frontend/src/Call/Calls.js b/frontend/src/Call/Calls.js
new file mode 100644
index 0000000..8996748
--- /dev/null
+++ b/frontend/src/Call/Calls.js
@@ -0,0 +1,408 @@
+import React, { useEffect, useLayoutEffect, useState, useRef } from "react";
+import { Link, useLocation, useParams, useNavigate } from 'react-router-dom';
+
+import FilterModal from "./FilterModal";
+import GroupModal from "./GroupModal";
+
+import CalendarModal from "./CalendarModal";
+import CallPlayer from "./CallPlayer";
+
+import { useSelector, useDispatch } from 'react-redux'
+import { setLive, setFilter,setDateFilter } from "../features/callPlayer/callPlayerSlice";
+import { getCalls, getOlderCalls, getNewerCalls, addCall } from "../features/calls/callsSlice";
+import { useGetGroupsQuery, useGetTalkgroupsQuery } from '../features/api/apiSlice'
+import { useInView } from 'react-intersection-observer';
+import {
+ Container,
+ Label,
+ Rail,
+ Sticky,
+ Menu,
+ Icon,
+ Sidebar
+} from "semantic-ui-react";
+import "./CallPlayer.css";
+import queryString from '../query-string';
+import io from 'socket.io-client';
+
+
+
+
+const socket = io(process.env.REACT_APP_BACKEND_SERVER);
+
+
+// ----------------------------------------------------
+function Calls(props) {
+
+ const { shortName } = useParams();
+
+ const { data: groupsData, isSuccess: isGroupsSuccess } = useGetGroupsQuery(shortName);
+ const { loading: callsLoading, data: callsData } = useSelector((state) => state.calls);
+ const { data: talkgroupsData, isSuccess: isTalkgroupsSuccess } = useGetTalkgroupsQuery(shortName);
+
+
+ const [autoPlay, setAutoPlay] = useState(true);
+ const [currentCall, setCurrentCall] = 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 navigate = useNavigate();
+ const dispatch = useDispatch();
+ const positionRef = useRef(); // lets us get the Y Scroll offset for the Call List
+ const pageYOffset = useRef(); // Store the current Scroll Offset in a way that guarantees the latest value is available when Call Data is updated
+ const shouldPlayAddCallRef = useRef(); // we need to do this to make the current value of isPlaying available in the socket message callback
+ shouldPlayAddCallRef.current = (!isPlaying && autoPlay)?true: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;
+
+ let currentCallId = false;
+
+
+ if (currentCall) {
+ currentCallId = currentCall._id;
+ }
+
+
+ const handlePusherClick = () => {
+ if (sidebarOpened) setSidebarOpened(false);
+ }
+
+ const handleSidebarToggle = () => setSidebarOpened(!sidebarOpened);
+ const handleFilterToggle = () => setFilterVisible(!filterVisible);
+ const handleCalendarToggle = () => setCalendarVisible(!calendarVisible);
+
+
+
+
+ const getFilterDescription = () => {
+
+ var filter = { type: 'all', code: "", filterStarred: false };
+
+ switch (filterType) {
+ case 1:
+ filter.type = "group";
+ filter.code = filterGroupId
+ break;
+ case 2:
+ filter.type = "talkgroup";
+ filter.code = filterTalkgroups
+ break;
+ default:
+ case 0:
+ filter.type = "all";
+ filter.code = ""
+ }
+ filter.filterStarred = filterStarred
+ return filter;
+ }
+
+
+ const handleSocketMessage = (data) => {
+ const message = JSON.parse(data)
+ switch (message.type) {
+ case 'calls':
+
+ pageYOffset.current = positionRef.current.clientHeight;
+
+ if (shouldPlayAddCallRef.current) {
+ setCurrentCall(message);
+ }
+ dispatch(addCall(message));
+
+ console.log("Got: " + message._id);
+ break
+ default:
+ break
+ }
+ }
+
+ const startSocket = () => {
+ const filter = getFilterDescription();
+
+ socket.emit("start", {
+ filterCode: filter.code,
+ filterType: filter.type,
+ filterName: "OpenMHz",
+ filterStarred: filter.starred,
+ shortName: shortName
+ });
+ }
+ const stopSocket = () => {
+ socket.emit("stop");
+ }
+
+ const updateUri = () => {
+ var search = "?"
+ switch (filterType) {
+
+ case 1:
+ search = search + `filter-type=group&filter-code=${filterGroupId}`;
+ break;
+ case 2:
+ search = search + `filter-type=talkgroup&filter-code=${filterTalkgroups}`;
+ break;
+ default:
+ case 0:
+ break;
+
+ }
+ if (loadCallId) {
+ if (search.length !== 1) {
+ search = search + '&';
+ }
+ search = search + `call-id=${loadCallId}`
+ }
+ if (filterDate) {
+ if (search.length !== 1) {
+ search = search + '&';
+ }
+ search = search + `time=${filterDate}`;
+ }
+
+ if (filterStarred) {
+ if (search.length !== 1) {
+ search = search + '&';
+ }
+ search = search + `starred=true`;
+ }
+ navigate(pathname + search, { replace: true });
+
+ }
+
+ const handleLiveToggle = (currentlyLive) => {
+ if (!live) {
+ dispatch(setDateFilter(false));
+ dispatch(setLive(true));
+ setCurrentCall(false);
+ dispatch(getCalls({}));
+
+ startSocket();
+ }
+ }
+
+ const handleCalendarClose = (didUpdate) => {
+ setCalendarVisible(!calendarVisible);
+
+ if (didUpdate) {
+ dispatch(setLive(false));
+ setCurrentCall(false);
+ stopSocket();
+ }
+ }
+
+ const handleGroupClose = (didUpdate) => {
+ setGroupVisible(!groupVisible);
+ }
+
+ const handleFilterClose = (didUpdate) => {
+ setFilterVisible(!filterVisible);
+
+ if (didUpdate) {
+ setCurrentCall(false);
+ }
+ }
+
+
+ const setStateFromUri = async () => {
+ var filter = {
+ filterDate: false,
+ filterType: 0, // this is "all"
+ filterTalkgroups: [],
+ filterGroupId: false,
+ filterStarred: false,
+ live: true,
+ shortName: shortName
+ };
+
+ // is there a star filter?
+ if (uri.hasOwnProperty('starred')) {
+ const starred = uri['starred'];
+ filter.filterStarred = starred === 'true' ? true : false;
+ if (!urlOptions) setUrlOptions(true);
+ }
+
+ // is there a time based filter?
+ if (uri.hasOwnProperty('time')) {
+ const date = new Date(parseInt(uri['time']));
+ filter.filterDate = date.getTime();
+ filter.live = false;
+ if (!urlOptions) setUrlOptions(true);
+ }
+
+ // is this just for one call?
+ if (uri.hasOwnProperty('call-id')) {
+ const _id = uri['call-id'];
+ setLoadCallId(_id);
+ setAutoPlay(false);
+ if (!urlOptions) setUrlOptions(true);
+ }
+
+ // is there a Filter set?
+ if ((uri.hasOwnProperty('filter-code')) && (uri.hasOwnProperty('filter-type'))) {
+ if (!urlOptions) setUrlOptions(true);
+
+ // The Filter is a group
+ if (uri['filter-type'] === "group") {
+ filter.filterType = 1;
+ filter.filterGroupId = uri["filter-code"];
+ }
+
+ // The Filter is talkgroups
+ if (uri['filter-type'] === 'talkgroup') {
+ const tg = uri["filter-code"].split(',').map(Number);
+ filter.filterType = 2;
+ filter.filterTalkgroups = tg;
+ }
+ }
+
+ dispatch(setFilter(filter));
+ }
+
+
+
+
+
+ useEffect(() => {
+ setStateFromUri();
+ return () => {
+ 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(() => {
+ dispatch(getCalls({}));
+ if (live) {
+ startSocket();
+ }
+ }, [shortName, filterGroupId, filterTalkgroups, filterType, filterDate, filterStarred])
+
+
+ // Update the Browser URI when any relevant values change
+ useEffect(() => {
+ updateUri();
+ }, [filterGroupId, filterTalkgroups, filterType, filterDate, filterStarred, loadCallId])
+
+
+ useEffect(() => {
+ if (!urlOptions && groupsData && (groupsData.length > 0)) {
+ setGroupVisible(true);
+ }
+ }, [groupsData])
+
+
+
+ var archiveLabel = "";
+ if (filterDate) {
+ const filterDateObj = new Date(filterDate);
+ archiveLabel = filterDateObj.toLocaleDateString() + " " + filterDateObj.toLocaleTimeString()
+ }
+
+
+
+ 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
+
+
+
+
+
+
+ );
+}
+
+
+export default Calls;
diff --git a/frontend/src/Call/ListCalls.js b/frontend/src/Call/ListCalls.js
index ed11a25..f2e0379 100644
--- a/frontend/src/Call/ListCalls.js
+++ b/frontend/src/Call/ListCalls.js
@@ -34,7 +34,7 @@ const ListCalls = (props) => {
- {callsData != false &&
+ {callsData &&
{
diff --git a/frontend/src/index.js b/frontend/src/index.js
index 34b44a9..a2cd078 100644
--- a/frontend/src/index.js
+++ b/frontend/src/index.js
@@ -17,7 +17,7 @@ import Main from "./Main/Main"
import ListSystems from "./System/ListSystems"
// Call
-import CallPlayer from "./Call/CallPlayer"
+import Calls from "./Call/Calls"
import AboutComponent from "./About/AboutComponent"
@@ -32,7 +32,7 @@ root.render(
} />
} />
- } />
+ } />
} />