Skip to content

Commit

Permalink
fix: Reset search times at intervals (#1876)
Browse files Browse the repository at this point in the history
  • Loading branch information
cbrevik authored Dec 10, 2021
1 parent 7765c82 commit 2dfe791
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 37 deletions.
29 changes: 27 additions & 2 deletions src/screens/Assistant/Assistant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,17 @@ import NewsBanner from './NewsBanner';
import Results from './Results';
import {SearchStateType} from './types';
import {ThemeColor} from '@atb/theme/colors';
import useInterval from '@atb/utils/use-interval';
import {differenceInMinutes, parseISO} from 'date-fns';

const themeColor: ThemeColor = 'background_accent';

type AssistantRouteName = 'AssistantRoot';
const AssistantRouteNameStatic: AssistantRouteName = 'AssistantRoot';

// Used to re-trigger refresh of search time if set to 'now' after 60 minutes.
const REFRESH_NOW_SEARCH_TIME_LIMIT_IN_MINUTES = 60;

export type AssistantScreenNavigationProp = CompositeNavigationProp<
StackNavigationProp<AssistantParams>,
StackNavigationProp<RootStackParamList>
Expand Down Expand Up @@ -137,6 +142,28 @@ const Assistant: React.FC<Props> = ({
date: new Date().toISOString(),
});

const screenHasFocus = useIsFocused();

useInterval(
() => {
if (searchTime.option === 'now') {
const now = new Date();
const diff = differenceInMinutes(now, parseISO(searchTime.date));

// Update "now" date if it has been more than 60 minutes
// since last time now has been updated
if (diff >= REFRESH_NOW_SEARCH_TIME_LIMIT_IN_MINUTES) {
navigation.setParams({
searchTime: {option: 'now', date: now.toISOString()},
});
}
}
},
1000,
[searchTime.option, searchTime.date],
!screenHasFocus || searchTime.option !== 'now',
);

function swap() {
log('swap', {
newFrom: translateLocation(to),
Expand Down Expand Up @@ -388,8 +415,6 @@ const Assistant: React.FC<Props> = ({
string | undefined
>();

const screenHasFocus = useIsFocused();

useEffect(() => {
if (!screenHasFocus) return;
switch (searchState) {
Expand Down
2 changes: 1 addition & 1 deletion src/screens/Nearby/DepartureTimeSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import {DateInputItem, Section, TimeInputItem} from '@atb/components/sections';
import {NavigationProp} from '@react-navigation/native';
import {NearbyStackParams} from '.';
import {dateWithReplacedTime, formatLocaleTime} from '@atb/utils/date';
import {SearchTime} from '@atb/screens/Nearby/Nearby';
import {Confirm} from '@atb/assets/svg/icons/actions';
import useKeyboardHeight from '@atb/utils/use-keyboard-height';
import {SearchTime} from './types';

type Props = {
close: () => void;
Expand Down
26 changes: 10 additions & 16 deletions src/screens/Nearby/Nearby.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,10 @@ import {NearbyStackParams} from '.';
import Loading from '../Loading';
import DepartureTimeSheet from './DepartureTimeSheet';
import {useDepartureData} from './state';
import {SearchTime} from './types';

const themeColor: ThemeColor = 'background_accent';

const DateOptions = ['now', 'departure'] as const;
type DateOptionType = typeof DateOptions[number];
export type SearchTime = {
option: DateOptionType;
date: string;
};

type NearbyRouteName = 'NearbyRoot';
const NearbyRouteNameStatic: NearbyRouteName = 'NearbyRoot';

Expand Down Expand Up @@ -109,22 +103,21 @@ const NearbyOverview: React.FC<Props> = ({
const [loadAnnouncement, setLoadAnnouncement] = useState<string>('');
const styles = useNearbyStyles();

const [searchTime, setSearchTime] = useState<SearchTime>({
option: 'now',
date: new Date().toISOString(),
});

const currentSearchLocation = useMemo<LocationWithMetadata | undefined>(
() => currentLocation && {...currentLocation, resultType: 'geolocation'},
[currentLocation],
);
const fromLocation = searchedFromLocation ?? currentSearchLocation;
const updatingLocation = !fromLocation && hasLocationPermission;

const {state, refresh, loadMore, setShowFavorites} = useDepartureData(
fromLocation,
searchTime?.option !== 'now' ? searchTime.date : undefined,
);
const {
state,
refresh,
loadMore,
setShowFavorites,
setSearchTime,
} = useDepartureData(fromLocation);

const {
data,
tick,
Expand All @@ -133,6 +126,7 @@ const NearbyOverview: React.FC<Props> = ({
error,
showOnlyFavorites,
queryInput,
searchTime,
} = state;

const {
Expand Down
78 changes: 60 additions & 18 deletions src/screens/Nearby/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {DeparturesRealtimeData} from '@atb/sdk';
import {differenceInMinutes} from 'date-fns';
import useInterval from '@atb/utils/use-interval';
import {updateStopsWithRealtime} from '../../departure-list/utils';
import {SearchTime} from './types';

const DEFAULT_NUMBER_OF_DEPARTURES_PER_LINE_TO_SHOW = 7;

Expand All @@ -41,33 +42,35 @@ export type DepartureDataState = {
queryInput: DepartureGroupsQuery;
cursorInfo: DepartureGroupMetadata['metadata'] | undefined;
lastRefreshTime: Date;
searchTime: SearchTime;
};

const initialQueryInput: DepartureGroupsQuery = {
limitPerLine: DEFAULT_NUMBER_OF_DEPARTURES_PER_LINE_TO_SHOW,
startTime: new Date().toISOString(),
};
const initialState: DepartureDataState = {
const initialState: Omit<
DepartureDataState,
'searchTime' | 'queryInput' | 'lastRefreshTime'
> = {
data: null,
showOnlyFavorites: false,
error: undefined,
locationId: undefined,
isLoading: false,
isFetchingMore: false,
cursorInfo: undefined,
queryInput: initialQueryInput,
lastRefreshTime: new Date(),

// Store date as update tick to know when to rerender
// and re-sort objects.
tick: undefined,
};

type DepartureDataActions =
| {
type: 'SET_SEARCH_TIME';
searchTime: SearchTime;
location?: Location;
favoriteDepartures?: UserFavoriteDepartures;
}
| {
type: 'LOAD_INITIAL_DEPARTURES';
location?: Location;
startTime?: string;
favoriteDepartures?: UserFavoriteDepartures;
}
| {
Expand Down Expand Up @@ -116,10 +119,15 @@ const reducer: ReducerWithSideEffects<
if (!action.location) return NoUpdate();

// Update input data with new date as this
// is a fresh fetch. We should fetch tha latest information.
// is a fresh fetch. We should fetch the latest information.

const {option, date} = state.searchTime;

const startTime = option === 'now' ? new Date().toISOString() : date;

const queryInput: DepartureGroupsQuery = {
limitPerLine: DEFAULT_NUMBER_OF_DEPARTURES_PER_LINE_TO_SHOW,
startTime: action.startTime ?? new Date().toISOString(),
startTime,
};

return UpdateWithSideEffect<DepartureDataState, DepartureDataActions>(
Expand All @@ -128,6 +136,8 @@ const reducer: ReducerWithSideEffects<
isLoading: true,
error: undefined,
isFetchingMore: true,
searchTime: {option, date: startTime},
lastRefreshTime: new Date(),
queryInput,
},
async (state, dispatch) => {
Expand Down Expand Up @@ -254,7 +264,22 @@ const reducer: ReducerWithSideEffects<
type: 'LOAD_INITIAL_DEPARTURES',
location: action.location,
favoriteDepartures: action.favoriteDepartures,
startTime: state.queryInput?.startTime,
});
},
);
}

case 'SET_SEARCH_TIME': {
return UpdateWithSideEffect<DepartureDataState, DepartureDataActions>(
{
...state,
searchTime: action.searchTime,
},
async (_, dispatch) => {
dispatch({
type: 'LOAD_INITIAL_DEPARTURES',
location: action.location,
favoriteDepartures: action.favoriteDepartures,
});
},
);
Expand All @@ -271,7 +296,6 @@ const reducer: ReducerWithSideEffects<
: (state.data ?? []).concat(action.result.data),
cursorInfo: action.result.metadata,
tick: new Date(),
lastRefreshTime: new Date(),
});
}

Expand Down Expand Up @@ -313,23 +337,40 @@ const reducer: ReducerWithSideEffects<
*/
export function useDepartureData(
location?: Location,
startTime?: string,
updateFrequencyInSeconds: number = 30,
tickRateInSeconds: number = 10,
) {
const [state, dispatch] = useReducerWithSideEffects(reducer, initialState);
const [state, dispatch] = useReducerWithSideEffects(reducer, {
...initialState,
searchTime: {option: 'now', date: new Date().toISOString()},
queryInput: {
limitPerLine: DEFAULT_NUMBER_OF_DEPARTURES_PER_LINE_TO_SHOW,
startTime: new Date().toISOString(),
},
lastRefreshTime: new Date(),
});
const isFocused = useIsFocused();
const {favoriteDepartures} = useFavorites();

const setSearchTime = useCallback(
(searchTime: SearchTime) =>
dispatch({
type: 'SET_SEARCH_TIME',
searchTime,
location,
favoriteDepartures,
}),
[location?.id, favoriteDepartures],
);

const refresh = useCallback(
() =>
dispatch({
type: 'LOAD_INITIAL_DEPARTURES',
location,
startTime,
favoriteDepartures,
}),
[location?.id, favoriteDepartures, startTime],
[location?.id, favoriteDepartures],
);

const loadMore = useCallback(
Expand All @@ -349,7 +390,7 @@ export function useDepartureData(
[location?.id, favoriteDepartures],
);

useEffect(refresh, [location?.id, startTime]);
useEffect(refresh, [location?.id]);
useEffect(() => {
if (!state.tick) {
return;
Expand Down Expand Up @@ -377,6 +418,7 @@ export function useDepartureData(
state,
refresh,
loadMore,
setSearchTime,
setShowFavorites,
};
}
6 changes: 6 additions & 0 deletions src/screens/Nearby/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const DateOptions = ['now', 'departure'] as const;
export type DateOptionType = typeof DateOptions[number];
export type SearchTime = {
option: DateOptionType;
date: string;
};

0 comments on commit 2dfe791

Please sign in to comment.