Use local cache to optimize display

This commit is contained in:
2024-02-02 00:50:50 +01:00
parent edbc01122d
commit 311a29cf4b
5 changed files with 179 additions and 85 deletions

View File

@ -1,4 +1,3 @@
import {useEffect, useState} from "react"
import {
Box,
styled,
@ -11,6 +10,8 @@ import {
Typography
} from "@mui/material"
import {CSSTransition, TransitionGroup} from 'react-transition-group'
import {useQueries, useQuery, useQueryClient} from "@tanstack/react-query";
import {useEffect, useState} from "react";
const StyledTableRow = styled(TableRow)(({ theme, tableType }) => ({
'tbody &:nth-of-type(odd)': {
@ -49,27 +50,37 @@ function TrainsTableHeader({tableType}) {
}
function TrainsTableBody({stop, date, time, tableType}) {
const [trains, setTrains] = useState([])
const queryClient = useQueryClient()
useEffect(() => {
if (stop.id !== undefined) {
let validTrains = trains.filter(train => {
if (tableType === "departures")
return `${train.departure_date}T${train.departure_time_24h}` >= `${date}T${time}`
else
return `${train.arrival_date}T${train.arrival_time_24h}` >= `${date}T${time}`
})
if (trains.length > 0 && validTrains.length === trains.length)
return
console.log(`${trains.length - validTrains.length} trains deleted`)
fetch(`http://localhost:8000/api/station/next_${tableType}/?stop_id=${stop.id}&date=${date}&time=${time}&offset=${validTrains.length}&limit=${20 - validTrains.length}`)
let filterTime = (train) => {
if (train.departure_time === "04:56:00")
return false
if (tableType === "departures")
return `${train.departure_date}T${train.departure_time_24h}` >= `${date}T${time}`
else
return `${train.arrival_date}T${train.arrival_time_24h}` >= `${date}T${time}`
}
function updateTrains() {
return fetch(`http://localhost:8000/api/station/next_${tableType}/?stop_id=${stop.id}&date=${date}&time=${time}&offset=${0}&limit=${20}`)
.then(response => response.json())
.then(data => data.results)
.then(data => {
setTrains(trains => [...validTrains, ...data])
})
}
}, [stop, tableType, date, time])
.then(data => [...data])
}
const trainsQuery = useQuery({
queryKey: ['trains', stop.id, tableType],
queryFn: updateTrains,
enabled: !!stop.id,
})
const trains = trainsQuery.data ?? []
useEffect(() => {
let validTrains = trains?.filter(filterTime) ?? []
console.log(validTrains.length)
if (trains?.length > 0 && validTrains.length <= trains?.length)
queryClient.invalidateQueries({queryKey: ['trains', stop.id, tableType]})
}, [stop.id, tableType, date, time])
let table_rows = trains.map((train) => <CSSTransition key={train.id} timeout={500} classNames="shrink">
<TrainRow train={train} tableType={tableType} />
@ -85,64 +96,51 @@ function TrainsTableBody({stop, date, time, tableType}) {
}
function TrainRow({train, tableType}) {
const [trip, setTrip] = useState({})
const [route, setRoute] = useState({})
const [stopTimes, setStopTimes] = useState([])
const [trainType, setTrainType] = useState("")
const tripQuery = useQuery({
queryKey: ['trip', train.trip],
queryFn: () => fetch(`http://localhost:8000/api/gtfs/trip/${train.trip}/`)
.then(response => response.json()),
enabled: !!train.trip,
})
const trip = tripQuery.data ?? {}
useEffect(() => {
if (train.trip !== undefined) {
fetch(`http://localhost:8000/api/gtfs/trip/${train.trip}/`)
const routeQuery = useQuery({
queryKey: ['route', trip.route],
queryFn: () => fetch(`http://localhost:8000/api/gtfs/route/${trip.route}/`)
.then(response => response.json()),
enabled: !!trip.route,
})
const route = routeQuery.data ?? {}
const trainType = getTrainType(train, route)
const stopTimesQuery = useQuery({
queryKey: ['stop_times', trip.id],
queryFn: () => fetch(`http://localhost:8000/api/gtfs/stop_time/?trip=${trip.id}&order=stop_sequence&limit=1000`)
.then(response => response.json())
.then(t => {
t.stop_times = []
setTrip(t)
})
}
}, [train.trip])
.then(data => data.results),
enabled: !!trip.id,
})
const stopTimes = stopTimesQuery.data ?? []
const stopIds = stopTimes.map(stop_time => stop_time.stop)
useEffect(() => {
if (trip.route !== undefined) {
fetch(`http://localhost:8000/api/gtfs/route/${trip.route}/`)
.then(response => response.json())
.then(data => {
setRoute(data)
})
}
}, [trip.route])
const stopQueries = useQueries({
queries: stopIds.map(stopId => ({
queryKey: ['stop', stopId],
queryFn: () => fetch(`http://localhost:8000/api/gtfs/stop/${stopId}/`)
.then(response => response.json()),
enabled: !!stopId,
})),
})
const stops = stopTimes.map(((stopTime, i) => ({...stopTime, stop: stopQueries[i]?.data ?? {"name": "…"}}))) ?? []
useEffect(() => {
if (route !== undefined) {
setTrainType(getTrainType(train, route))
}
}, [train, route]);
let headline = stops[tableType === "departures" ? stops.length - 1 : 0]?.stop ?? {name: "Chargement…"}
useEffect(() => {
if (trip.route !== undefined) {
fetch(`http://localhost:8000/api/gtfs/stop_time/?trip=${trip.id}&order=stop_sequence&limit=1000`)
.then(response => response.json())
.then(data => data.results)
.then(stop_times => {
Promise.all(stop_times.map(stop_time =>
fetch(`http://localhost:8000/api/gtfs/stop/${stop_time.stop}/`).then(response => response.json())
)).then(stops => {
setStopTimes(stop_times.map((stop_time, index) => {
stop_time.stop = stops[index]
return stop_time
}))
})
})
}
}, [trip.route])
let headline = stopTimes[tableType === "departures" ? stopTimes.length - 1 : 0]?.stop ?? {name: "Chargement…"}
let stops_filter
let stopsFilter
if (tableType === "departures")
stops_filter = (stop_time) => stop_time.stop_sequence > train.stop_sequence && stop_time.drop_off_type === 0
stopsFilter = (stop_time) => stop_time.stop_sequence > train.stop_sequence && stop_time.drop_off_type === 0
else
stops_filter = (stop_time) => stop_time.stop_sequence < train.stop_sequence && stop_time.pickup_type === 0
let stops_names = stopTimes.filter(stops_filter).map(stop_time => stop_time?.stop.name ?? "").join(", ")
stopsFilter = (stop_time) => stop_time.stop_sequence < train.stop_sequence && stop_time.pickup_type === 0
let stopsNames = stops.filter(stopsFilter).map(stopTime => stopTime?.stop.name ?? "").join(", ") ?? ""
return <>
<StyledTableRow tableType={tableType}>
@ -176,8 +174,8 @@ function TrainRow({train, tableType}) {
</Box>
</TableCell>
<TableCell>
<Typography fontSize={24} fontWeight="bold">{headline.name}</Typography>
<span className="stops">{stops_names}</span>
<Typography fontSize={24} fontWeight="bold" data-stop-id={headline.id}>{headline.name}</Typography>
<span className="stops">{stopsNames}</span>
</TableCell>
</StyledTableRow>
</>