fixed up the other windows

This commit is contained in:
Luke Berndt
2023-01-16 21:16:13 -05:00
parent 14906865a1
commit 6f50a7b9c8
11 changed files with 141 additions and 295 deletions

View File

@@ -3,10 +3,7 @@ import { Link } from 'react-router-dom'
import { Container, Header, Divider, Icon, Menu, Button } from "semantic-ui-react"; import { Container, Header, Divider, Icon, Menu, Button } from "semantic-ui-react";
class AboutComponent extends Component { const AboutComponent = () => {
render() {
return ( return (
<div> <div>
<Menu fixed="top"> <Menu fixed="top">
@@ -42,6 +39,6 @@ class AboutComponent extends Component {
</div> </div>
); );
} }
}
export default AboutComponent; export default AboutComponent;

View File

@@ -1,28 +0,0 @@
import { connect } from "react-redux"
import * as callActionCreators from "./call-actions"
import { bindActionCreators } from 'redux'
import CalendarModal from "./CalendarModal"
function mapStateToProps(state, props) {
return {
groups: state.group.items[props.shortName],
talkgroups: state.talkgroup.items[props.shortName],
talkgroupsIsWaiting: state.talkgroup.isWaiting,
groupsIsWaiting: state.group.isWaiting,
shortName: props.shortName,
activeTab: state.call.filterType,
selectedTalkgroups: state.call.filterTalkgroups
}
}
function mapDispatchToProps(dispatch) {
return {
callActions: bindActionCreators(callActionCreators, dispatch)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(CalendarModal)

View File

@@ -5,7 +5,7 @@ import MediaPlayer from "./MediaPlayer";
import FilterModal from "./FilterModal"; import FilterModal from "./FilterModal";
import GroupModal from "./GroupModal"; import GroupModal from "./GroupModal";
import SupportModal from "./SupportModal"; import SupportModal from "./SupportModal";
import CalendarModal from "./CalendarModalContainer"; import CalendarModal from "./CalendarModal";
import CallInfo from "./CallInfo"; import CallInfo from "./CallInfo";
import ListCalls from "./ListCalls"; import ListCalls from "./ListCalls";
import { useSelector, useDispatch } from 'react-redux' import { useSelector, useDispatch } from 'react-redux'
@@ -50,9 +50,7 @@ function CallPlayer(props) {
const [autoPlay, setAutoPlay] = useState(true); const [autoPlay, setAutoPlay] = useState(true);
const [addCallScroll, setAddCallScroll] = useState(false);
const [currentCall, setCurrentCall] = useState(false); const [currentCall, setCurrentCall] = useState(false);
const [prevScrollHeight, setPrevScrollHeight] = useState(0);
const [urlOptions, setUrlOptions] = useState(false); const [urlOptions, setUrlOptions] = useState(false);
const [isPlaying, setIsPlaying] = useState(false); const [isPlaying, setIsPlaying] = useState(false);
const [sidebarOpened, setSidebarOpened] = useState(false); const [sidebarOpened, setSidebarOpened] = useState(false);
@@ -155,13 +153,10 @@ function CallPlayer(props) {
case 'calls': case 'calls':
const ref = positionRef.current; const ref = positionRef.current;
pageYOffset.current = positionRef.current.clientHeight; pageYOffset.current = positionRef.current.clientHeight;
setPrevScrollHeight(positionRef.current.clientHeight);
console.log("Prior to setAddCallScroll, addCallScroll was: " + addCallScroll);
setAddCallScroll(true);
if (shouldPlayAddCallRef.current) { if (shouldPlayAddCallRef.current) {
setCurrentCall(message); setCurrentCall(message);
} }
console.log("Prior to addCall, addCallScroll was: " + addCallScroll);
dispatch(addCall(message)); dispatch(addCall(message));
console.log("Got: " + message._id); console.log("Got: " + message._id);
@@ -349,7 +344,7 @@ function CallPlayer(props) {
useLayoutEffect( () => { useLayoutEffect( () => {
const scrollAmount = parseInt(positionRef.current.clientHeight) - parseInt(pageYOffset.current); const scrollAmount = parseInt(positionRef.current.clientHeight) - parseInt(pageYOffset.current);
if (scrollAmount > 0) { if (scrollAmount > 0) {
console.log("useLayoutEffect for callsData - state prevScrollHeight: " + prevScrollHeight + " ref: " + pageYOffset.current + " current: " + positionRef.current.clientHeight + " Scroll Amount: " + scrollAmount) console.log("useLayoutEffect for callsData - ref: " + pageYOffset.current + " current: " + positionRef.current.clientHeight + " Scroll Amount: " + scrollAmount)
window.scrollBy(0, scrollAmount); window.scrollBy(0, scrollAmount);
} }
}, [callsData]) }, [callsData])

View File

@@ -1,69 +0,0 @@
import { connect } from "react-redux"
import * as callActionCreators from "./call-actions"
import * as talkgroupActionCreators from "../Talkgroups/talkgroup-actions"
import * as groupActionCreators from "../Group/group-actions"
import * as systemActionCreators from "../System/system-actions"
import { bindActionCreators } from 'redux'
import CallPlayer from "./CallPlayer"
import {
useLocation,
useNavigate,
useParams
} from "react-router-dom";
// glorious solution here: https://stackoverflow.com/questions/71097375/how-can-i-use-withrouter-in-react-router-v6-for-passing-props
function withRouter(Component) {
function ComponentWithRouterProp(props) {
let location = useLocation();
let navigate = useNavigate();
let params = useParams();
return (
<Component
{...props}
router={{ location, navigate, params }}
/>
);
}
return ComponentWithRouterProp;
}
function mapStateToProps(state, props) {
const shortName = props.router.params.shortName;
return {
callsById: state.call.byId,
callsAllIds: state.call.allIds,
oldestCallTime: state.call.oldestCallTime,
newestCallTime: state.call.newestCallTime,
live: state.call.live,
filterDate: state.call.filterDate,
filterType: state.call.filterType,
filterTalkgroups: state.call.filterTalkgroups,
filterGroupId: state.call.filterGroupId,
filterStarred: state.call.filterStarred,
system: state.system.items.find((item) => item.shortName === shortName),
groups: state.group.items[shortName],
talkgroups: state.talkgroup.items[shortName],
callsIsWaiting: state.call.isWaiting,
systemIsWaiting: state.system.isWaiting,
talkgroupsIsWaiting: state.talkgroup.isWaiting,
groupsIsWaiting: state.group.isWaiting,
location: props.router.location,
shortName: shortName
}
}
function mapDispatchToProps(dispatch) {
return {
groupActions: bindActionCreators(groupActionCreators, dispatch),
systemActions: bindActionCreators(systemActionCreators, dispatch),
callActions: bindActionCreators(callActionCreators, dispatch),
talkgroupActions: bindActionCreators(talkgroupActionCreators, dispatch)
}
}
export default withRouter(connect(
mapStateToProps,
mapDispatchToProps
)(CallPlayer))

View File

@@ -1,34 +0,0 @@
import { connect } from "react-redux"
import * as talkgroupActionCreators from "../Talkgroups/talkgroup-actions"
import * as groupActionCreators from "../Group/group-actions"
import * as callActionCreators from "./call-actions"
import { bindActionCreators } from 'redux'
import FilterModal from "./FilterModal"
function mapStateToProps(state, props) {
return {
groups: state.group.items[props.shortName],
talkgroups: state.talkgroup.items[props.shortName],
talkgroupsIsWaiting: state.talkgroup.isWaiting,
groupsIsWaiting: state.group.isWaiting,
shortName: props.shortName,
activeTab: state.call.filterType,
selectedTalkgroups: state.call.filterTalkgroups,
selectedGroup: state.call.filterGroupId,
filterStarred: state.call.filterStarred
}
}
function mapDispatchToProps(dispatch) {
return {
groupActions: bindActionCreators(groupActionCreators, dispatch),
talkgroupActions: bindActionCreators(talkgroupActionCreators, dispatch),
callActions: bindActionCreators(callActionCreators, dispatch)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(FilterModal)

View File

@@ -1,27 +0,0 @@
import { connect } from "react-redux"
import * as groupActionCreators from "../Group/group-actions"
import * as callActionCreators from "./call-actions"
import { bindActionCreators } from 'redux'
import GroupModal from "./GroupModal"
function mapStateToProps(state, props) {
return {
groups: state.group.items[props.shortName],
groupsIsWaiting: state.group.isWaiting,
shortName: props.shortName,
selectedGroup: state.call.filterGroupId
}
}
function mapDispatchToProps(dispatch) {
return {
groupActions: bindActionCreators(groupActionCreators, dispatch),
callActions: bindActionCreators(callActionCreators, dispatch)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(GroupModal)

View File

@@ -1,4 +1,4 @@
import React, { Component } from "react"; import React, { Component, useState, useEffect, useRef } from "react";
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import SystemCard from "../System/SystemCard"; import SystemCard from "../System/SystemCard";
import "./Main.css"; import "./Main.css";
@@ -17,6 +17,9 @@ import {
} from 'semantic-ui-react' } from 'semantic-ui-react'
import { useSelector, useDispatch } from 'react-redux'
import { selectAllSystems, selectActiveSystems, useGetSystemsQuery } from "../features/api/apiSlice";
/* Responsive component was removed from Semantic UI. This is discussed here: https://github.com/Semantic-Org/Semantic-UI-React/pull/4008 */ /* Responsive component was removed from Semantic UI. This is discussed here: https://github.com/Semantic-Org/Semantic-UI-React/pull/4008 */
const AppMedia = createMedia({ const AppMedia = createMedia({
@@ -80,15 +83,14 @@ General flow:
- componentDidMount(): it will call fetchSystem() this will perform an HTTP request if Systems does not exist, and then add System to Props - componentDidMount(): it will call fetchSystem() this will perform an HTTP request if Systems does not exist, and then add System to Props
*/ */
class DesktopContainer extends Component { const DesktopContainer = (props) => {
state = {} const [fixed, setFixed] = useState(false);
const hideFixedMenu = () => setFixed(false)
const showFixedMenu = () => setFixed(true)
hideFixedMenu = () => this.setState({ fixed: false })
showFixedMenu = () => this.setState({ fixed: true })
render() { const { children } = props
const { children } = this.props
const { fixed } = this.state
return ( return (
<Media greaterThanOrEqual="tablet"> <Media greaterThanOrEqual="tablet">
@@ -128,26 +130,24 @@ class DesktopContainer extends Component {
</Media> </Media>
) )
} }
}
/* /*
DesktopContainer.propTypes = { DesktopContainer.propTypes = {
children: PropTypes.node, children: PropTypes.node,
} }
*/ */
class MobileContainer extends Component { const MobileContainer = (props) => {
state = {}
handlePusherClick = () => { const [sidebarOpened, setSidebarOpened] = useState(false);
const { sidebarOpened } = this.state
if (sidebarOpened) this.setState({ sidebarOpened: false }) const handlePusherClick = () => {
setSidebarOpened(!sidebarOpened)
} }
handleToggle = () => this.setState({ sidebarOpened: !this.state.sidebarOpened }) const handleToggle = () => setSidebarOpened(!sidebarOpened)
render() {
const { children } = this.props const { children } = props
const { sidebarOpened } = this.state
return ( return (
<Media lessThan="tablet"> <Media lessThan="tablet">
@@ -162,7 +162,7 @@ class MobileContainer extends Component {
<Sidebar.Pusher <Sidebar.Pusher
dimmed={sidebarOpened} dimmed={sidebarOpened}
onClick={this.handlePusherClick} onClick={handlePusherClick}
style={{ minHeight: '100vh' }} style={{ minHeight: '100vh' }}
> >
<div className='relative'> <div className='relative'>
@@ -181,7 +181,7 @@ class MobileContainer extends Component {
<Container> <Container>
<Menu inverted secondary size='large'> <Menu inverted secondary size='large'>
<Menu.Item onClick={this.handleToggle}> <Menu.Item onClick={handleToggle}>
<Icon name='sidebar' /> <Icon name='sidebar' />
</Menu.Item> </Menu.Item>
<Menu.Item header>{process.env.REACT_APP_SITE_NAME}</Menu.Item> <Menu.Item header>{process.env.REACT_APP_SITE_NAME}</Menu.Item>
@@ -196,7 +196,6 @@ class MobileContainer extends Component {
</Media> </Media>
) )
} }
}
/* /*
MobileContainer.propTypes = { MobileContainer.propTypes = {
children: PropTypes.node, children: PropTypes.node,
@@ -210,41 +209,62 @@ const ResponsiveContainer = ({ children }) => (
) )
// ---------------------------------------------------- // ----------------------------------------------------
class Main extends Component { const Main = (props) => {
constructor(props) {
super(props); const [visible, setVisible] = useState(true);
this.advanceSystem = this.advanceSystem.bind(this); const [duration, setDuration] = useState(500);
this.state = { duration: 500, visible: true, currentSystem: 0} const [currentSystem, setCurrentSystem] = useState(0);
const dispatch = useDispatch();
const {data:systems, isSuccess} = useGetSystemsQuery(); //= selectAllSystems();
function useInterval(callback, delay) {
const savedCallback = useRef();
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
} }
const handleVisibility = () => setVisible(!visible);
const advanceSystem = () => {
handleChange = (e, { name, value }) => this.setState({ [name]: value }) if (isSuccess) {
let nextSystem = currentSystem + 1;
handleVisibility = () => this.setState({ visible: !this.state.visible }) if (nextSystem > systems.systems.length) {
nextSystem = 0;
advanceSystem() {
var currentSystem = this.state.currentSystem + 1;
if (currentSystem > this.props.system.items.length) {
currentSystem = 0;
} }
this.setState({ visible: !this.state.visible, currentSystem }); setCurrentSystem(nextSystem);
setVisible(!visible);
}
//this.setState({ visible: !this.state.visible, currentSystem });
} }
componentDidMount() { useInterval( ()=>{ advanceSystem()}, 3000)
this.props.fetchSystems();
this.interval = setInterval(() => this.advanceSystem(), 3000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
//https://stackoverflow.com/questions/36559661/how-can-i-dispatch-from-child-components-in-react-redux //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 //https://stackoverflow.com/questions/42597602/react-onclick-pass-event-with-parameter
render() {
const system = this.props.system.items[this.state.currentSystem]; let system = false;
if (isSuccess) {
system = systems.systems[currentSystem];
}
return ( return (
<> <>
<style>{mediaStyles}</style> <style>{mediaStyles}</style>
@@ -254,9 +274,9 @@ render() {
<Grid columns='equal' stackable textAlign='center' style={{ height: '350px', marginRight: '0px' }}> <Grid columns='equal' stackable textAlign='center' style={{ height: '350px', marginRight: '0px' }}>
<Grid.Row textAlign='center'> <Grid.Row textAlign='center'>
<Grid.Column style={{ paddingBottom: '4em', paddingTop: '2em', maxWidth: 450 }}> <Grid.Column style={{ paddingBottom: '4em', paddingTop: '2em', maxWidth: 450 }}>
{ system && (<Transition visible={this.state.visible} animation='pulse' duration={500}> { system && (<Transition visible={visible} animation='pulse' duration={500}>
<SystemCard keepShort={true} system={system} key={system.shortName} onClick={(e) => this.props.changeUrl("/system/" + system.shortName)}/> <SystemCard keepShort={true} system={system} key={system.shortName} onClick={(e) => props.changeUrl("/system/" + system.shortName)}/>
</Transition>)} </Transition>)}
</Grid.Column> </Grid.Column>
@@ -351,6 +371,5 @@ render() {
</>); </>);
} }
}
export default Main; export default Main;

View File

@@ -1,16 +0,0 @@
import { connect } from "react-redux"
import * as systemActions from "../System/system-actions"
import Main from "./Main"
function mapStateToProps(state) {
return {
system: state.system
}
}
export default connect(
mapStateToProps,
systemActions
)(Main)

View File

@@ -10,22 +10,15 @@ import {
Divider Divider
} from "semantic-ui-react"; } from "semantic-ui-react";
import { selectAllSystems, selectActiveSystems, useGetSystemsQuery } from "../features/api/apiSlice";
// ---------------------------------------------------- // ----------------------------------------------------
class ListSystems extends Component {
state = { const ListSystems = (props) => {
requestMessage: "",
}
componentDidMount() {
this.props.fetchSystems();
}
//https://stackoverflow.com/questions/36559661/how-can-i-dispatch-from-child-components-in-react-redux const {data:systems, isSuccess} = useGetSystemsQuery();
//https://stackoverflow.com/questions/42597602/react-onclick-pass-event-with-parameter
render() {
const systems = this.props.system.items;
return ( return (
<div> <div>
<Menu fixed="top"> <Menu fixed="top">
@@ -35,7 +28,8 @@ class ListSystems extends Component {
<Container > <Container >
<Divider horizontal style={{paddingTop:"5em", paddingBottom:"2em"}}><Header as="h1">Radio Systems<Icon name='rss' /></Header></Divider> <Divider horizontal style={{paddingTop:"5em", paddingBottom:"2em"}}><Header as="h1">Radio Systems<Icon name='rss' /></Header></Divider>
<Card.Group itemsPerRow={4} stackable={true}> <Card.Group itemsPerRow={4} stackable={true}>
{systems.map((system) =>
{isSuccess&&systems.systems.map((system) =>
system.active&&<SystemCard system={system} key={system.shortName} onClick={(e) => this.props.changeUrl("/system/" + system.shortName)}/> system.active&&<SystemCard system={system} key={system.shortName} onClick={(e) => this.props.changeUrl("/system/" + system.shortName)}/>
// <SystemCard system={system} key={system.shortName} onClick={(e) => this.props.changeUrl("/system/" + system.shortName)}/> // <SystemCard system={system} key={system.shortName} onClick={(e) => this.props.changeUrl("/system/" + system.shortName)}/>
)} )}
@@ -44,6 +38,6 @@ class ListSystems extends Component {
</div> </div>
); );
} }
}
export default ListSystems; export default ListSystems;

View File

@@ -1,6 +1,6 @@
// Import the RTK Query methods from the React-specific entry point // Import the RTK Query methods from the React-specific entry point
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { createSelector} from '@reduxjs/toolkit'
// Define our single API slice object // Define our single API slice object
@@ -29,5 +29,20 @@ export const apiSlice = createApi({
}) })
}) })
export const selectSystemsResult = apiSlice.endpoints.getSystems.select();
const emptySystems = []
export const selectAllSystems = createSelector(
selectSystemsResult,
systemsResult => systemsResult?.data ?? emptySystems
)
export const selectActiveSystems = createSelector(
selectAllSystems,
(state, userId) => userId,
(systems, userId) => systems.find(system => system.active === true)
)
// Export the auto-generated hook for the `getPosts` query endpoint // Export the auto-generated hook for the `getPosts` query endpoint
export const { useGetGroupsQuery, useGetSystemsQuery, useGetTalkgroupsQuery, useGetCallsQuery } = apiSlice export const { useGetGroupsQuery, useGetSystemsQuery, useGetTalkgroupsQuery } = apiSlice

View File

@@ -11,10 +11,10 @@ import 'semantic-ui-css/semantic.min.css'
//import withTracker from './withTracker'; //import withTracker from './withTracker';
// Main // Main
import MainContainer from "./Main/MainContainer" import Main from "./Main/Main"
// System // System
import ListSystemsContainer from "./System/ListSystemsContainer" import ListSystems from "./System/ListSystems"
// Call // Call
import CallPlayer from "./Call/CallPlayer" import CallPlayer from "./Call/CallPlayer"
@@ -30,8 +30,8 @@ root.render(
<Provider store={store}> <Provider store={store}>
<BrowserRouter> <BrowserRouter>
<Routes> <Routes>
<Route exact path="/" element={<MainContainer/>} /> <Route exact path="/" element={<Main/>} />
<Route exact path="/systems" element={<ListSystemsContainer/>} /> <Route exact path="/systems" element={<ListSystems/>} />
<Route exact path="/system/:shortName" element={<CallPlayer/>} /> <Route exact path="/system/:shortName" element={<CallPlayer/>} />
<Route exact path="/about" element={<AboutComponent/>} /> <Route exact path="/about" element={<AboutComponent/>} />