digitransit-ui/app/component/routepage/TripStopsContainer.js
2024-05-11 14:17:23 +03:00

153 lines
3.8 KiB
JavaScript

import PropTypes from 'prop-types';
import React, { useState, useRef } from 'react';
import { createFragmentContainer, graphql } from 'react-relay';
import cx from 'classnames';
import pure from 'recompose/pure';
import { matchShape } from 'found';
import debounce from 'lodash/debounce';
import RouteControlPanel from './RouteControlPanel';
import { getStartTime } from '../../util/timeUtils';
import TripStopListContainer from './TripStopListContainer';
import withBreakpoint from '../../util/withBreakpoint';
import ScrollableWrapper from '../ScrollableWrapper';
import { routeShape } from '../../util/shapes';
function TripStopsContainer({ breakpoint, match, trip, route }) {
const [keepTracking, setTracking] = useState(true);
const humanScrolling = useRef(true);
const setHumanScrolling = boolVal => {
humanScrolling.current = boolVal;
};
if (!trip) {
return null;
}
const tripStartTime = getStartTime(
trip.stoptimesForDate[0].scheduledDeparture,
);
const handleScroll = () => {
if (humanScrolling.current && keepTracking) {
setTracking(false);
}
};
return (
<ScrollableWrapper
className={cx('route-page-content', {
'bp-large': breakpoint === 'large',
})}
id="trip-route-page-content"
onScroll={debounce(handleScroll, 100, { leading: true })}
>
{route && route.patterns && (
<RouteControlPanel
match={match}
route={route}
breakpoint={breakpoint}
tripStartTime={tripStartTime}
/>
)}
<TripStopListContainer
key="list"
trip={trip}
tripStart={tripStartTime}
keepTracking={keepTracking}
setHumanScrolling={setHumanScrolling}
/>
</ScrollableWrapper>
);
}
TripStopsContainer.propTypes = {
trip: PropTypes.shape({
stoptimesForDate: PropTypes.arrayOf(
PropTypes.shape({
scheduledDeparture: PropTypes.number.isRequired,
}).isRequired,
).isRequired,
}),
match: matchShape.isRequired,
breakpoint: PropTypes.string.isRequired,
route: routeShape,
};
TripStopsContainer.defaultProps = {
trip: undefined,
route: undefined,
};
const pureComponent = pure(withBreakpoint(TripStopsContainer));
const containerComponent = createFragmentContainer(pureComponent, {
trip: graphql`
fragment TripStopsContainer_trip on Trip {
stoptimesForDate {
scheduledDeparture
}
...TripStopListContainer_trip
}
`,
pattern: graphql`
fragment TripStopsContainer_pattern on Pattern {
id
}
`,
route: graphql`
fragment TripStopsContainer_route on Route
@argumentDefinitions(date: { type: "String" }) {
gtfsId
color
shortName
longName
mode
type
...RouteAgencyInfo_route
...RoutePatternSelect_route @arguments(date: $date)
agency {
phone
name
}
patterns {
alerts(types: [ROUTE, STOPS_ON_PATTERN]) {
id
alertSeverityLevel
effectiveEndDate
effectiveStartDate
}
headsign
code
stops {
id
gtfsId
code
alerts {
id
alertDescriptionText
alertHash
alertHeaderText
alertSeverityLevel
alertUrl
effectiveEndDate
effectiveStartDate
}
}
trips: tripsForDate(serviceDate: $date) {
stoptimes: stoptimesForDate(serviceDate: $date) {
realtimeState
scheduledArrival
scheduledDeparture
serviceDay
}
}
activeDates: trips {
serviceId
day: activeDates
}
}
}
`,
});
export { containerComponent as default, TripStopsContainer as Component };