Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement miles/kilometer selector #252

Merged
merged 11 commits into from
Oct 6, 2019
6 changes: 4 additions & 2 deletions App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { Screens } from './Screens';
import { Background as LoadingBackground } from './Screens/Loading/Background';
import {
ApiContextProvider,
DistanceUnitProvider,
ErrorContextProvider,
FrequencyContextProvider,
LocationContextProvider
Expand All @@ -46,7 +47,6 @@ export function App () {
const [ready, setReady] = useState(false);
useEffect(() => {
Promise.all([

Font.loadAsync({
'gotham-black': require('../assets/fonts/Gotham-Black.ttf'),
'gotham-book': require('../assets/fonts/Gotham-Book.ttf')
Expand Down Expand Up @@ -74,7 +74,9 @@ export function App () {
<LocationContextProvider>
<ApiContextProvider>
<FrequencyContextProvider>
<Screens />
<DistanceUnitProvider>
<Screens />
</DistanceUnitProvider>
</FrequencyContextProvider>
</ApiContextProvider>
</LocationContextProvider>
Expand Down
88 changes: 45 additions & 43 deletions App/Screens/About/About.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,7 @@

import Constants from 'expo-constants';
import React from 'react';
import {
Linking,
Platform,
ScrollView,
StyleSheet,
Text,
View
} from 'react-native';
import { Linking, Platform, ScrollView, StyleSheet, Switch, Text, View } from 'react-native';
import { ScrollIntoView, wrapScrollView } from 'react-native-scroll-into-view';
import { scale } from 'react-native-size-matters';
import { NavigationInjectedProps } from 'react-navigation';
Expand All @@ -33,6 +26,7 @@ import { BackButton } from '../../components';
import { i18n } from '../../localization';
import { trackScreen } from '../../util/amplitude';
import * as theme from '../../util/theme';
import { useDistanceUnit } from '../../stores/distanceUnit';
Copy link
Member

@amaury1093 amaury1093 Oct 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alphabetical by import location


const CustomScrollView = wrapScrollView(ScrollView);
const scrollViewOptions = {
Expand All @@ -57,9 +51,7 @@ const handleOpenAqi = () => {
};

const handleOpenArticle = () => {
Linking.openURL(
'http:https://berkeleyearth.org/air-pollution-and-cigarette-equivalence/'
);
Linking.openURL('http:https://berkeleyearth.org/air-pollution-and-cigarette-equivalence/');
};

const handleOpenGithub = () => {
Expand All @@ -77,35 +69,26 @@ interface AboutProps

export function About (props: AboutProps) {
const { navigation } = props;
const { distanceUnit, localizedDistanceUnit, setDistanceUnit } = useDistanceUnit();

trackScreen('ABOUT');

const toggleDistanceSwitch = (value: boolean) => setDistanceUnit(value ? 'km' : 'mile');

return (
<CustomScrollView
scrollIntoViewOptions={scrollViewOptions}
style={theme.withPadding}
>
<BackButton
onPress={() => navigation.goBack()}
style={styles.backButton}
/>
<CustomScrollView scrollIntoViewOptions={scrollViewOptions} style={theme.withPadding}>
<BackButton onPress={() => navigation.goBack()} style={styles.backButton} />

<View style={styles.section}>
<Text style={styles.h2}>
{i18n.t('about_how_do_you_calculate_the_number_of_cigarettes_title')}
</Text>
<Text style={theme.text}>
{i18n.t(
'about_how_do_you_calculate_the_number_of_cigarettes_message_1'
)}{' '}
{i18n.t('about_how_do_you_calculate_the_number_of_cigarettes_message_1')}{' '}
<Text onPress={handleOpenArticle} style={theme.link}>
{i18n.t(
'about_how_do_you_calculate_the_number_of_cigarettes_link_1'
)}
{i18n.t('about_how_do_you_calculate_the_number_of_cigarettes_link_1')}
</Text>
{i18n.t(
'about_how_do_you_calculate_the_number_of_cigarettes_message_2'
)}
{i18n.t('about_how_do_you_calculate_the_number_of_cigarettes_message_2')}
<Text style={styles.micro}>&micro;</Text>
g/m&sup3;
{' \u207D'}
Expand All @@ -126,15 +109,11 @@ export function About (props: AboutProps) {
style={styles.section}
>
<Text style={styles.h2}>{i18n.t('about_beta_inaccurate_title')}</Text>
<Text style={theme.text}>
{i18n.t('about_beta_inaccurate_message')}
</Text>
<Text style={theme.text}>{i18n.t('about_beta_inaccurate_message')}</Text>
</ScrollIntoView>

<View style={styles.section}>
<Text style={styles.h2}>
{i18n.t('about_where_does_data_come_from_title')}
</Text>
<Text style={styles.h2}>{i18n.t('about_where_does_data_come_from_title')}</Text>
<Text style={theme.text}>
{i18n.t('about_where_does_data_come_from_message_1')}{' '}
<Text onPress={handleOpenAqi} style={theme.link}>
Expand All @@ -145,17 +124,11 @@ export function About (props: AboutProps) {
</View>

<ScrollIntoView
onMount={
navigation.getParam('scrollInto') === 'aboutWhyIsTheStationSoFarTitle'
}
onMount={navigation.getParam('scrollInto') === 'aboutWhyIsTheStationSoFarTitle'}
style={styles.section}
>
<Text style={styles.h2}>
{i18n.t('about_why_is_the_station_so_far_title')}
</Text>
<Text style={theme.text}>
{i18n.t('about_why_is_the_station_so_far_message')}
</Text>
<Text style={styles.h2}>{i18n.t('about_why_is_the_station_so_far_title')}</Text>
<Text style={theme.text}>{i18n.t('about_why_is_the_station_so_far_message')}</Text>
</ScrollIntoView>

<View style={styles.section}>
Expand All @@ -169,6 +142,18 @@ export function About (props: AboutProps) {
</Text>
</View>

<View style={styles.distance}>
<Text style={styles.h2}>{i18n.t('about_distance_unit_title')}</Text>
<View style={styles.distanceSwitchWrapper}>
<Switch
onValueChange={toggleDistanceSwitch}
trackColor={{ true: theme.primaryColor, false: theme.iconBackgroundColor }}
value={distanceUnit === 'km'}
/>
<Text style={styles.distanceText}>{localizedDistanceUnit('long')}</Text>
</View>
</View>

<View style={styles.credits}>
<Text style={styles.h2}>{i18n.t('about_credits_title')}</Text>
<Text style={theme.text}>
Expand Down Expand Up @@ -217,6 +202,23 @@ const styles = StyleSheet.create({
marginBottom: theme.spacing.normal,
paddingTop: theme.spacing.big
},
distance: {
borderTopColor: theme.iconBackgroundColor,
borderTopWidth: 1,
marginBottom: theme.spacing.big,
paddingTop: theme.spacing.big
},
distanceSwitchWrapper: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center'
},
distanceText: {
...theme.text,
fontSize: scale(14),
paddingLeft: theme.spacing.small,
textTransform: 'capitalize'
},
h2: {
...theme.title,
fontSize: scale(20),
Expand Down
27 changes: 7 additions & 20 deletions App/Screens/Details/Details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ import { Header } from './Header';
import { i18n } from '../../localization';
import { ApiContext, CurrentLocationContext } from '../../stores';
import { trackScreen } from '../../util/amplitude';
import {
distanceToStation,
getCorrectLatLng,
DistanceUnit
} from '../../util/station';
import { useDistanceUnit } from '../../stores/distanceUnit';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alphabetical

import { distanceToStation, getCorrectLatLng } from '../../util/station';

interface DetailsProps extends NavigationInjectedProps {}

Expand All @@ -43,9 +40,8 @@ export function Details (props: DetailsProps) {

const [showMap, setShowMap] = useState(false);
const { api } = useContext(ApiContext);
const { currentLocation: _currentLocation } = useContext(
CurrentLocationContext
);
const { currentLocation: _currentLocation } = useContext(CurrentLocationContext);
const { distanceUnit } = useDistanceUnit();

trackScreen('DETAILS');

Expand All @@ -68,14 +64,7 @@ export function Details (props: DetailsProps) {
// object` error. It's related to the MapView below.
const currentLocation = { ..._currentLocation! };

const haversineDistanceUnit = i18n.t(
'haversine_distance_unit'
) as DistanceUnit;
const distance = distanceToStation(
currentLocation!,
api!,
haversineDistanceUnit
);
const distance = distanceToStation(currentLocation!, api!, distanceUnit);

const station = {
description: api!.shootISmoke.station || '',
Expand All @@ -94,11 +83,9 @@ export function Details (props: DetailsProps) {
<MapView
initialRegion={{
latitude: (currentLocation.latitude + station.latitude) / 2,
latitudeDelta:
Math.abs(currentLocation.latitude - station.latitude) * 2,
latitudeDelta: Math.abs(currentLocation.latitude - station.latitude) * 2,
longitude: (currentLocation.longitude + station.longitude) / 2,
longitudeDelta:
Math.abs(currentLocation.longitude - station.longitude) * 2
longitudeDelta: Math.abs(currentLocation.longitude - station.longitude) * 2
}}
onMapReady={handleMapReady}
style={styles.map}
Expand Down
4 changes: 3 additions & 1 deletion App/Screens/Details/Distance/Distance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import { StyleSheet, Text } from 'react-native';
import { Banner } from '../../../components';
import { i18n } from '../../../localization';
import * as theme from '../../../util/theme';
import { useDistanceUnit } from '../../../stores/distanceUnit';

interface DistanceProps {
distance: number;
}

export function Distance (props: DistanceProps) {
const distanceUnit = i18n.t('distance_unit');
const { localizedDistanceUnit } = useDistanceUnit();
const distanceUnit = localizedDistanceUnit('short');

return (
<Banner elevated shadowPosition="top" style={styles.banner}>
Expand Down
37 changes: 9 additions & 28 deletions App/Screens/Home/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,60 +15,41 @@
// along with Sh**t! I Smoke. If not, see <http:https://www.gnu.org/licenses/>.

import React, { useContext } from 'react';
import {
GestureResponderEvent,
Image,
StyleSheet,
Text,
View
} from 'react-native';
import { GestureResponderEvent, Image, StyleSheet, Text, View } from 'react-native';
import { scale } from 'react-native-size-matters';

import alert from '../../../../assets/images/alert.png';
import { ChangeLocation, CurrentLocation } from '../../../components';
import { i18n } from '../../../localization';
import { ApiContext, CurrentLocationContext } from '../../../stores';
import {
distanceToStation,
isStationTooFar,
DistanceUnit
} from '../../../util/station';
import { distanceToStation, isStationTooFar } from '../../../util/station';
import { useDistanceUnit } from '../../../stores/distanceUnit';
import * as theme from '../../../util/theme';

interface HeaderProps {
onChangeLocationClick: (event: GestureResponderEvent) => void;
onChangeLocationClick: (event: GestureResponderEvent) => void
}

export function Header (props: HeaderProps) {
const { api } = useContext(ApiContext)!;
const { currentLocation, isGps } = useContext(CurrentLocationContext);
const { distanceUnit, localizedDistanceUnit } = useDistanceUnit();
const { onChangeLocationClick } = props;

const distanceUnit = i18n.t('distance_unit');
const haversineDistanceUnit = i18n.t(
'haversine_distance_unit'
) as DistanceUnit;
const distance = distanceToStation(
currentLocation!,
api!,
haversineDistanceUnit
);
const shortDistanceUnit = localizedDistanceUnit('short');
const distance = distanceToStation(currentLocation!, api!, distanceUnit);
const isTooFar = isStationTooFar(currentLocation!, api!);

return (
<View style={styles.container}>
<View style={styles.currentLocation}>
<CurrentLocation
api={api!}
currentLocation={currentLocation!}
numberOfLines={2}
/>
<CurrentLocation api={api!} currentLocation={currentLocation!} numberOfLines={2} />
<View style={styles.distance}>
{isTooFar && <Image source={alert} style={styles.warning} />}
<Text style={styles.distanceText}>
{i18n.t('home_header_air_quality_station_distance', {
distanceToStation: distance,
distanceUnit
distanceUnit: shortDistanceUnit
})}{' '}
{!isGps && i18n.t('home_header_from_search')}
</Text>
Expand Down
9 changes: 6 additions & 3 deletions App/localization/languages/en-us.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@
"details_header_latest_update_ago": "ago",
"details_header_primary_pollutant_label": "Primary Pollutant:",
"details_distance_label": "AQI Station: {{distanceToStation}}{{distanceUnit}} away",
"distance_unit": "mi",
"haversine_distance_unit": "mile",
"distance_unit_short_km": "km",
"distance_unit_short_mi": "mi",
"distance_unit_long_km": "kilometer",
"distance_unit_long_mi": "mile",
"past_stations_loading": "Loading",
"past_stations_date_from_to": "{{startDate}} to {{endDate}}",
"past_stations_monitored_weekly": "Stations monitored from you during the week",
Expand All @@ -76,6 +78,7 @@
"about_weird_results_message_1": "We have also encountered a few surprising results: large cities with better air than small villages; sudden huge increases in the number of cigarettes; stations of the same town showing significantly different numbers... The fact is air quality depends on several factors such as temperature, pressure, humidity and even wind direction and intensity. If the result seems weird for you, check",
"about_weird_results_link_1": "WAQI",
"about_weird_results_message_2": "for more information and history on your station.",
"about_distance_unit_title": "Distance Unit",
"about_credits_title": "Credits",
"about_credits_concept_and_development": "Concept & Development by",
"about_credits_design_and_copywriting": "Design & Copywriting by",
Expand All @@ -84,4 +87,4 @@
"about_credits_available_github": "available on Github",
"about_language": "Language",
"current_location_unknown_station": "Unknown AQI station"
}
}
9 changes: 6 additions & 3 deletions App/localization/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@
"details_header_latest_update_ago": "ago",
"details_header_primary_pollutant_label": "Primary Pollutant:",
"details_distance_label": "AQI Station: {{distanceToStation}}{{distanceUnit}} away",
"distance_unit": "km",
"haversine_distance_unit": "km",
"distance_unit_short_km": "km",
"distance_unit_short_mi": "mi",
"distance_unit_long_km": "kilometer",
"distance_unit_long_mi": "mile",
"past_stations_loading": "Loading",
"past_stations_date_from_to": "{{startDate}} to {{endDate}}",
"past_stations_monitored_weekly": "Stations monitored from you during the week",
Expand All @@ -76,6 +78,7 @@
"about_weird_results_message_1": "We have also encountered a few surprising results: large cities with better air than small villages; sudden huge increases in the number of cigarettes; stations of the same town showing significantly different numbers... The fact is air quality depends on several factors such as temperature, pressure, humidity and even wind direction and intensity. If the result seems weird for you, check",
"about_weird_results_link_1": "WAQI",
"about_weird_results_message_2": "for more information and history on your station.",
"about_distance_unit_title": "Distance Unit",
"about_credits_title": "Credits",
"about_credits_concept_and_development": "Concept & Development by",
"about_credits_design_and_copywriting": "Design & Copywriting by",
Expand All @@ -84,4 +87,4 @@
"about_credits_available_github": "available on Github",
"about_language": "Language",
"current_location_unknown_station": "Unknown AQI station"
}
}
Loading