From 8f4569a99503323ede87c4d44f94e98c051e4dd1 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Mon, 3 Feb 2020 15:14:12 +0100 Subject: [PATCH] fix: Show isToofar warning on monthly and weekly (#426) * fix: Show isToofar warning on monthly and weekly * Fix memoization * Is too far should come before * Remove createHistoryItem on api load * Better warning messages * Always you smoke --- .prettierrc.js | 6 +---- .../Home/AdditionalInfo/AdditionalInfo.tsx | 18 +++++++------- App/Screens/Home/Home.tsx | 24 +++++++++++++------ .../CigaretteBlock/CigaretteBlock.tsx | 14 ++--------- App/stores/api.tsx | 18 ++++++-------- 5 files changed, 36 insertions(+), 44 deletions(-) diff --git a/.prettierrc.js b/.prettierrc.js index 4ee2f2e0..6aeb6e2c 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,5 +1 @@ -module.exports = { - semi: true, - singleQuote: true, - tabWidth: 2 -}; +module.exports = require('@amaurymartiny/eslintrc/prettierrc'); diff --git a/App/Screens/Home/AdditionalInfo/AdditionalInfo.tsx b/App/Screens/Home/AdditionalInfo/AdditionalInfo.tsx index 2af12a6a..59458746 100644 --- a/App/Screens/Home/AdditionalInfo/AdditionalInfo.tsx +++ b/App/Screens/Home/AdditionalInfo/AdditionalInfo.tsx @@ -80,6 +80,15 @@ export function AdditionalInfo( const isTooFar = isStationTooFar(currentLocation, api); + // Render a "station too far" warning + if (isTooFar) { + return ( + + {i18n.t('home_station_too_far_message')} + + ); + } + // Render a "beta" tag if (frequency !== 'daily' && !exactCount) { return ( @@ -103,14 +112,5 @@ export function AdditionalInfo( ); } - // Render a "station too far" warning - if (frequency === 'daily' && isTooFar) { - return ( - - {i18n.t('home_station_too_far_message')} - - ); - } - return null; } diff --git a/App/Screens/Home/Home.tsx b/App/Screens/Home/Home.tsx index 9194d828..45e5ce82 100644 --- a/App/Screens/Home/Home.tsx +++ b/App/Screens/Home/Home.tsx @@ -85,7 +85,10 @@ const memoHistoricalCigarettes = pMemoize( }); }, { - cacheKey: args => JSON.stringify(args) + cacheKey: (frequency: Frequency, { latitude, longitude }: LatLng) => { + // We cache this function with the following cache key + return `${frequency}${latitude}${longitude}`; + } } ); @@ -128,7 +131,7 @@ export function Home(props: HomeProps): React.ReactElement { ? TE.right(results) : TE.left( new Error( - `Data for ${frequency} measurements has ${results.length} items` + `Data for ${frequency} measurements on [${currentLocation.latitude},${currentLocation.longitude}] has no items` ) ) ), @@ -138,8 +141,16 @@ export function Home(props: HomeProps): React.ReactElement { value })); }), - TE.map(data => sumInDays(data, frequency)), - TE.map(pm25ToCigarettes), + TE.map(data => ({ + // Convert the PM2.5 sum to a cigarettes sum + count: pm25ToCigarettes(sumInDays(data, frequency)), + exact: + // We consider that the calculated sums are "exact", if there's at + // least 60 data points (for monthly sum) or 14 data points (for + // weekly sums), These 2 numbers are highly arbirtrary, I'm sure + // there's a more scientific way to find them. + frequency === 'monthly' ? data.length >= 60 : data.length >= 14 + })), TE.fold( error => { console.log(` - ${error.message}`); @@ -154,10 +165,9 @@ export function Home(props: HomeProps): React.ReactElement { return T.of(void undefined); }, - totalCigarettes => { + data => { setCigarettes({ - count: totalCigarettes, - exact: true, + ...data, frequency }); diff --git a/App/components/CigaretteBlock/CigaretteBlock.tsx b/App/components/CigaretteBlock/CigaretteBlock.tsx index bf8ff5c6..8c4ac882 100644 --- a/App/components/CigaretteBlock/CigaretteBlock.tsx +++ b/App/components/CigaretteBlock/CigaretteBlock.tsx @@ -48,14 +48,7 @@ function getSwearWord(cigaretteCount: number): string { } export function CigaretteBlock(props: CigaretteBlockProps): React.ReactElement { - const { - cigarettes, - frequency, - isGps, - style, - displayFrequency, - ...rest - } = props; + const { cigarettes, frequency, style, displayFrequency, ...rest } = props; // Decide on a swear word. The effect says that the swear word only changes // when the cigarettes count changes. @@ -70,10 +63,7 @@ export function CigaretteBlock(props: CigaretteBlockProps): React.ReactElement { const text = i18n.t('home_smoked_cigarette_title', { swearWord, - presentPast: - isGps && frequency === 'daily' - ? i18n.t('home_common_you_smoke') - : i18n.t('home_common_you_smoked'), + presentPast: i18n.t('home_common_you_smoke'), singularPlural: cigarettesRounded === 1 ? i18n.t('home_common_cigarette').toLowerCase() diff --git a/App/stores/api.tsx b/App/stores/api.tsx index 244271e1..52d42b1e 100644 --- a/App/stores/api.tsx +++ b/App/stores/api.tsx @@ -27,12 +27,11 @@ import * as TE from 'fp-ts/lib/TaskEither'; import promiseAny from 'p-any'; import React, { createContext, useContext, useEffect, useState } from 'react'; -import { logFpError, promiseToTE, sideEffect } from '../util/fp'; +import { logFpError, promiseToTE } from '../util/fp'; import { noop } from '../util/noop'; import { pm25ToCigarettes } from '../util/secretSauce'; import { ErrorContext } from './error'; import { CurrentLocationContext } from './location'; -import { createHistoryItem } from './util'; // FIXME Import from @shootismoke/convert type OpenAQFormat = Normalized[0]; @@ -68,7 +67,9 @@ function filterPm25(normalized: Normalized): Api { } }; } else { - throw new Error('PM2.5 has not been measured by this station right now'); + throw new Error( + `PM2.5 has not been measured by station ${normalized[0].location} right now` + ); } } @@ -78,7 +79,7 @@ function filterPm25(normalized: Normalized): Api { * * @param gps - The GPS coordinates to fetch data for */ -function race(gps: LatLng): TE.TaskEither { +function raceApi(gps: LatLng): TE.TaskEither { // Helper function to fetch & normalize data for 1 provider async function fetchForProvider( provider: ProviderPromise, @@ -122,7 +123,7 @@ interface ApiContextProviderProps { export function ApiContextProvider({ children }: ApiContextProviderProps): React.ReactElement { - const { currentLocation, isGps, setCurrentLocation } = useContext( + const { currentLocation, setCurrentLocation } = useContext( CurrentLocationContext ); const { setError } = useContext(ErrorContext); @@ -139,12 +140,7 @@ export function ApiContextProvider({ } pipe( - race(currentLocation), - TE.chain( - sideEffect(api => - isGps ? createHistoryItem(api) : TE.right(void undefined) - ) - ), + raceApi(currentLocation), TE.fold( error => { setError(error);