From 28ecf67cbdd258ef06dfa11e40dbee9f8b50a324 Mon Sep 17 00:00:00 2001 From: Luke Berndt Date: Wed, 11 Jan 2023 22:36:34 -0500 Subject: [PATCH] infiinite scroll is here! --- .env.test | 1 + frontend/package.json | 1 + frontend/src/Call/CallPlayer.js | 56 +++++++++++++++-------- frontend/src/features/calls/callsSlice.js | 8 ++-- frontend/yarn.lock | 5 ++ 5 files changed, 48 insertions(+), 23 deletions(-) diff --git a/.env.test b/.env.test index dd4df7c..1c0acdb 100644 --- a/.env.test +++ b/.env.test @@ -2,6 +2,7 @@ MEDIA=/Users/luke/Testing/media DATA=/Users/luke/Testing/data MAILJET_KEY="4d2a0f6deb20a7890afee2daf595c22d" MAILJET_SECRET="fb74f682d68bf6b05ab626c0ac93a6da" +GOOGLE_ANALYTICS="UA-45563211-1" STAGE=test TAG=1.7 DOMAIN_NAME="openmhz.test" diff --git a/frontend/package.json b/frontend/package.json index b407c80..8acbda3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,6 +19,7 @@ "react-datepicker": "4.8.0", "react-dom": "^18.2.0", "react-ga": "^3.3.1", + "react-intersection-observer": "^9.4.1", "react-redux": "^8.0.5", "react-router-dom": "6.6.1", "react-scripts": "5.0.1", diff --git a/frontend/src/Call/CallPlayer.js b/frontend/src/Call/CallPlayer.js index 3fad19a..15c3f0e 100644 --- a/frontend/src/Call/CallPlayer.js +++ b/frontend/src/Call/CallPlayer.js @@ -9,10 +9,10 @@ import CalendarModal from "./CalendarModalContainer"; import CallInfo from "./CallInfo"; import ListCalls from "./ListCalls"; import { useSelector, useDispatch } from 'react-redux' -import { setLive, setShortName } from "../features/callPlayer/callPlayerSlice"; -import { getCalls, getOlderCalls} from "../features/calls/callsSlice"; +import { setLive, setShortName, setFilter } from "../features/callPlayer/callPlayerSlice"; +import { getCalls, getOlderCalls, getNewerCalls} from "../features/calls/callsSlice"; import { useGetGroupsQuery, useGetTalkgroupsQuery } from '../features/api/apiSlice' -import { selectAllCalls, useGetCallsQuery, callsAdapter } from "../features/calls/callsSlice"; +import { useInView } from 'react-intersection-observer'; import { Container, Label, @@ -21,7 +21,6 @@ import { Menu, Icon, Sidebar, - Visibility, Button } from "semantic-ui-react"; import "./CallPlayer.css"; @@ -37,14 +36,21 @@ import queryString from '../query-string'; 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, data: callsData} = useSelector((state) => state.calls); + 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 [requestMessage, setRequestMessage] = useState(""); const [callUrl, setCallUrl] = useState(""); const [autoPlay, setAutoPlay] = useState(true); const [callId, setCallId] = useState(false); @@ -67,7 +73,6 @@ function CallPlayer (props) { 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 switchAutoPlay = () => setAutoPlay(!autoPlay); @@ -107,10 +112,11 @@ function CallPlayer (props) { callActions.fetchNewerCalls(newestCallTime.getTime()); } */ + const loadOlderCalls = (getOlderCalls) => { console.log("Loading Older Calls"); - dispatch(getOlderCalls()); + dispatch(getOlderCalls({})); } @@ -232,7 +238,6 @@ const getFilter = () => { const handleGroupClose = (didUpdate) => { setGroupVisible(!groupVisible); - //callActions.fetchCalls(); } const handleFilterClose = (didUpdate) => { @@ -241,7 +246,6 @@ const getFilter = () => { if (didUpdate) { setCallUrl(""); setCallId(false); - //callActions.fetchCalls(); } } /* @@ -299,7 +303,7 @@ const getFilter = () => { } }*/ - const setStateFromUri = () => { + const setStateFromUri = async () => { var filter = { filterDate: false, filterType: 0, // this is "all" @@ -367,9 +371,23 @@ const getFilter = () => { } } - //callActions.setFilter(filter); + await dispatch(setFilter(filter)); } + useEffect(() => { + if (loadNewerInView && callsData && (callsData.ids.length > 0)) { + dispatch(getNewerCalls({})); + } + }, [loadNewerInView]); + + + useEffect(() => { + if (loadOlderInView && callsData && (callsData.ids.length > 0)) { + dispatch(getOlderCalls({})); + } + }, [loadOlderInView]); + + 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 @@ -382,6 +400,7 @@ const getFilter = () => { if (filter.live) { this.startSocket(shortName, filterType, filterCode, filter.filterStarred); }*/ + setStateFromUri(); console.log("Setting short name to: " + shortName) dispatch(setShortName(shortName)); @@ -391,7 +410,8 @@ const getFilter = () => { }, []); useEffect(() => { - dispatch(getCalls({shortName})); + dispatch(getCalls({})); + //dispatch(getOlderCalls()); }, [shortName,filterGroupId,filterTalkgroups,filterType,filterStarred]) @@ -598,13 +618,11 @@ const getFilter = () => { onClick={handlePusherClick} style={{ minHeight: '100vh' }} > - +
- -
- -
- +
+ + diff --git a/frontend/src/features/calls/callsSlice.js b/frontend/src/features/calls/callsSlice.js index c178d93..2d446ca 100644 --- a/frontend/src/features/calls/callsSlice.js +++ b/frontend/src/features/calls/callsSlice.js @@ -58,7 +58,7 @@ const now = new Date(); export const callsAdapter = createEntityAdapter({ selectId: (call) => call._id, - sortComparer: (a, b) => a.time.localeCompare(b.time), + sortComparer: (a, b) => b.time.localeCompare(a.time), }) const initialState = { @@ -129,7 +129,7 @@ export const getCalls = createAsyncThunk( 'calls/getCalls', async({},{getState, requestId}) => { const state = getState() - const {loading,oldestCallTime, newestCallTime} = getState().call; + const {loading,oldestCallTime, newestCallTime} = getState().calls; const url = buildCallUrl(getState); const res = await fetch(url).then( (data) => data.json() @@ -140,7 +140,7 @@ export const getCalls = createAsyncThunk( export const getOlderCalls = createAsyncThunk( 'calls/getOlderCalls', async({},{getState, requestId} ) => { - const {loading,oldestCallTime, newestCallTime} = getState().call; + const {loading,oldestCallTime, newestCallTime} = getState().calls; const url = buildCallUrl(getState,"older",oldestCallTime.getTime()); const res = await fetch(url).then( (data) => data.json() @@ -151,7 +151,7 @@ export const getCalls = createAsyncThunk( export const getNewerCalls = createAsyncThunk( 'calls/getNewerCalls', async({},{getState, requestId} ) => { - const {loading,oldestCallTime, newestCallTime} = getState().call; + const {loading,oldestCallTime, newestCallTime} = getState().calls; const url = buildCallUrl(getState,"newer",newestCallTime.getTime()); const res = await fetch(url).then( (data) => data.json() diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 4d8363c..a308473 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -8431,6 +8431,11 @@ react-ga@^3.3.1: resolved "https://registry.yarnpkg.com/react-ga/-/react-ga-3.3.1.tgz#d8e1f4e05ec55ed6ff944dcb14b99011dfaf9504" integrity sha512-4Vc0W5EvXAXUN/wWyxvsAKDLLgtJ3oLmhYYssx+YzphJpejtOst6cbIHCIyF50Fdxuf5DDKqRYny24yJ2y7GFQ== +react-intersection-observer@^9.4.1: + version "9.4.1" + resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-9.4.1.tgz#4ccb21e16acd0b9cf5b28d275af7055bef878f6b" + integrity sha512-IXpIsPe6BleFOEHKzKh5UjwRUaz/JYS0lT/HPsupWEQou2hDqjhLMStc5zyE3eQVT4Fk3FufM8Fw33qW1uyeiw== + react-is@^16.13.1, react-is@^16.6.3, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"