From 2588ef37f74cafd117315786e1b7e940370906ad Mon Sep 17 00:00:00 2001 From: Steve Kuznetsov Date: Sat, 16 Mar 2024 08:52:33 -0600 Subject: [PATCH] AvalancheForecastZoneMap: update watch/bulletin behavior The warnings endpoint can return three different types of products (warnings, watches and special bulletins). We only want the map to flash when there's an active warning. A small fix to add 1 day to the warning fetch hook for the time machine, since the NAC API assumes a date and appends a time to it. Signed-off-by: Steve Kuznetsov --- CONTRIBUTING.md | 2 ++ components/AvalancheForecastZoneMap.tsx | 15 ++++++++++++--- components/screens/menu/DeveloperMenu.tsx | 12 +++++++++++- hooks/useAvalancheWarning.ts | 4 ++-- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a43f7445..0be1911f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,6 +25,8 @@ eas secret:push --env-file=.env ## Logging +The log level for our logger is set with `$LOG_LEVEL`, the default is `'info'` but it needs to be `'debug'` for the below network bits. + Runtime logging can be enabled in development mode by running `npx expo start` with the following environment variables set: `$LOG_NETWORK`: diff --git a/components/AvalancheForecastZoneMap.tsx b/components/AvalancheForecastZoneMap.tsx index e567a3b3..59ba3169 100644 --- a/components/AvalancheForecastZoneMap.tsx +++ b/components/AvalancheForecastZoneMap.tsx @@ -198,9 +198,18 @@ export const AvalancheForecastZoneMap: React.FunctionComponent = ({cen if (!warning) { return; } - const mapViewZoneData = zonesById[warning.zone_id]; - if (mapViewZoneData && warning.data.expires_time) { - mapViewZoneData.hasWarning = true; + // the warnings endpoint can return warnings, watches and special bulletins; we only want to make the map flash + // when there's an active warning for the zone + if ( + 'product_type' in warning.data && + warning.data.product_type === ProductType.Warning && + 'expires_time' in warning.data && + isAfter(toDate(new Date(warning.data.expires_time), {timeZone: 'UTC'}), requestedTimeToUTCDate(requestedTime)) + ) { + const mapViewZoneData = zonesById[warning.zone_id]; + if (mapViewZoneData) { + mapViewZoneData.hasWarning = true; + } } }); const zones = Object.keys(zonesById).map(k => zonesById[k]); diff --git a/components/screens/menu/DeveloperMenu.tsx b/components/screens/menu/DeveloperMenu.tsx index 2a2657ee..283bae4e 100644 --- a/components/screens/menu/DeveloperMenu.tsx +++ b/components/screens/menu/DeveloperMenu.tsx @@ -264,7 +264,17 @@ export const DeveloperMenu: React.FC = ({staging, setStaging action: () => { navigation.navigate('avalancheCenter', { center_id: 'NWAC', - requestedTime: toISOStringUTC(new Date('2023-02-20T5:21:00-0800')), + requestedTime: toISOStringUTC(new Date('2024-02-27T15:21:00-0800')), + }); + }, + }, + { + label: 'View map layer with active watch', + data: null, + action: () => { + navigation.navigate('avalancheCenter', { + center_id: 'CBAC', + requestedTime: toISOStringUTC(new Date('2023-03-21T5:21:00-0800')), }); }, }, diff --git a/hooks/useAvalancheWarning.ts b/hooks/useAvalancheWarning.ts index 8ebeefe1..b675d0bd 100644 --- a/hooks/useAvalancheWarning.ts +++ b/hooks/useAvalancheWarning.ts @@ -7,7 +7,7 @@ import * as Sentry from '@sentry/react-native'; import {QueryClient, useQuery, UseQueryResult} from '@tanstack/react-query'; import {Logger} from 'browser-bunyan'; import {ClientContext, ClientProps} from 'clientContext'; -import {formatDistanceToNowStrict} from 'date-fns'; +import {add, formatDistanceToNowStrict} from 'date-fns'; import {safeFetch} from 'hooks/fetch'; import {LoggerContext, LoggerProps} from 'loggerContext'; import {AvalancheCenterID, warningResultSchema, WarningResultWithZone} from 'types/nationalAvalancheCenter'; @@ -89,7 +89,7 @@ const fetchAvalancheWarning = async ( zone_id: String(zone_id), }; if (requested_time !== 'latest') { - params['published_time'] = apiDateString(requested_time); // the API accepts a _date_ and appends 19:00 to it for a time... + params['published_time'] = apiDateString(add(requested_time, {days: 1})); // the API accepts a _date_ and appends 19:00 to it for a time... } const what = 'avalanche warning'; const thisLogger = logger.child({url: url, params: params, what: what});