diff --git a/App/Screens/About/About.tsx b/App/Screens/About/About.tsx index 65f5b509..a6aae5f5 100644 --- a/App/Screens/About/About.tsx +++ b/App/Screens/About/About.tsx @@ -44,8 +44,8 @@ const scrollViewOptions = { }; export const aboutSections = { - about_how_results: 'about_how_results', - about_why_is_the_station_so_far_title: 'about_why_is_the_station_so_far_title' + aboutBetaInaccurate: 'aboutBetaInaccurate', + aboutWhyIsTheStationSoFarTitle: 'aboutWhyIsTheStationSoFarTitle' }; const handleOpenAmaury = () => @@ -115,6 +115,16 @@ export function About (props: AboutProps) { + + {i18n.t('about_beta_inaccurate_title')} + + {i18n.t('about_beta_inaccurate_message')} + + + {i18n.t('about_where_does_data_come_from_title')} @@ -130,8 +140,7 @@ export function About (props: AboutProps) { @@ -154,14 +163,6 @@ export function About (props: AboutProps) { - - HELLO - TODO - - {i18n.t('about_credits_title')} diff --git a/App/Screens/About/Box/Box.tsx b/App/Screens/About/Box/Box.tsx index 0cb7f0c3..1dc793b8 100644 --- a/App/Screens/About/Box/Box.tsx +++ b/App/Screens/About/Box/Box.tsx @@ -16,6 +16,7 @@ import React from 'react'; import { Image, Platform, StyleSheet, Text, View } from 'react-native'; +import { scale } from 'react-native-size-matters'; import cigarette from '../../../../assets/images/cigarette.png'; import { i18n } from '../../../localization'; @@ -83,7 +84,7 @@ const styles = StyleSheet.create({ color: theme.secondaryTextColor, fontSize: 12, fontWeight: '900', - letterSpacing: 0.5 + letterSpacing: scale(0.5) }, micro: { ...Platform.select({ diff --git a/App/Screens/Home/AdditionalInfo/AdditionalInfo.tsx b/App/Screens/Home/AdditionalInfo/AdditionalInfo.tsx new file mode 100644 index 00000000..140b3795 --- /dev/null +++ b/App/Screens/Home/AdditionalInfo/AdditionalInfo.tsx @@ -0,0 +1,102 @@ +// Sh**t! I Smoke +// Copyright (C) 2018-2019 Marcelo S. Coelho, Amaury Martiny + +// Sh**t! I Smoke is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Sh**t! I Smoke is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Sh**t! I Smoke. If not, see . + +import React, { useContext } from 'react'; +import { + StyleSheet, + Text, + TouchableOpacity, + View, + ViewProps +} from 'react-native'; +import { scale } from 'react-native-size-matters'; +import { NavigationInjectedProps } from 'react-navigation'; + +import { aboutSections } from '../../About'; +import { i18n } from '../../../localization'; +import { Frequency } from '../SelectFrequency'; +import { ApiContext, CurrentLocationContext } from '../../../stores'; +import { track } from '../../../util/amplitude'; +import { isStationTooFar } from '../../../util/station'; +import * as theme from '../../../util/theme'; + +interface AdditionalInfoProps extends NavigationInjectedProps, ViewProps { + frequency: Frequency; +} + +export function AdditionalInfo (props: AdditionalInfoProps) { + const { api } = useContext(ApiContext)!; + const { currentLocation } = useContext(CurrentLocationContext); + const { frequency, navigation, style, ...rest } = props; + + const isTooFar = isStationTooFar(currentLocation!, api!); + + function renderBeta () { + return ( + { + track('HOME_SCREEN_BETA_INACCURATE_CLICK'); + navigation.navigate('About', { + scrollInto: aboutSections.aboutBetaInaccurate + }); + }} + style={styles.linkToAbout} + > + + BETA + + {i18n.t('home_beta_not_accurate')} + + ); + } + + if (frequency === 'daily' && !isTooFar) { + return null; + } + + return ( + + {frequency !== 'daily' + ? renderBeta() + : isTooFar && ( + + {i18n.t('home_station_too_far_message')} + + )} + + ); +} + +const styles = StyleSheet.create({ + linkToAbout: { + alignItems: 'center', + flexDirection: 'row' + }, + tag: { + backgroundColor: '#C4C4C4', + borderRadius: scale(10), + marginRight: theme.spacing.mini, + paddingHorizontal: scale(6), + paddingVertical: scale(3) + }, + tagLabel: { + color: 'white', + fontSize: scale(10), + letterSpacing: scale(1), + marginLeft: scale(2), + textAlign: 'center' + } +}); diff --git a/App/Screens/Home/Wait/Wait.tsx b/App/Screens/Home/AdditionalInfo/index.ts similarity index 53% rename from App/Screens/Home/Wait/Wait.tsx rename to App/Screens/Home/AdditionalInfo/index.ts index a1590cb0..e45b5bf7 100644 --- a/App/Screens/Home/Wait/Wait.tsx +++ b/App/Screens/Home/AdditionalInfo/index.ts @@ -1,4 +1,3 @@ -// Sh**t! I Smoke // Copyright (C) 2018-2019 Marcelo S. Coelho, Amaury Martiny // Sh**t! I Smoke is free software: you can redistribute it and/or modify @@ -14,27 +13,4 @@ // You should have received a copy of the GNU General Public License // along with Sh**t! I Smoke. If not, see . -import React from 'react'; -import { Image, StyleProp, StyleSheet, View, ViewStyle } from 'react-native'; -import { scale } from 'react-native-size-matters'; - -import wait from '../../../../assets/images/wait.png'; -import { CIGARETTES_HEIGHT } from '../../../components/Cigarettes'; - -interface WaitProps { - style?: StyleProp; -} - -export function Wait ({ style }: WaitProps) { - return ( - - - - ); -} - -const styles = StyleSheet.create({ - container: { - height: scale(CIGARETTES_HEIGHT) - } -}); +export * from './AdditionalInfo'; diff --git a/App/Screens/Home/CigaretteBlock/CigaretteBlock.tsx b/App/Screens/Home/CigaretteBlock/CigaretteBlock.tsx new file mode 100644 index 00000000..fd5f57a7 --- /dev/null +++ b/App/Screens/Home/CigaretteBlock/CigaretteBlock.tsx @@ -0,0 +1,89 @@ +// Sh**t! I Smoke +// Copyright (C) 2018-2019 Marcelo S. Coelho, Amaury Martiny + +// Sh**t! I Smoke is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Sh**t! I Smoke is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Sh**t! I Smoke. If not, see . + +import React, { useContext } from 'react'; +import { StyleSheet, Text, View, ViewProps } from 'react-native'; + +import { Cigarettes } from '../../../components'; +import { i18n } from '../../../localization'; +import { Frequency } from '../SelectFrequency'; +import { CurrentLocationContext } from '../../../stores'; +import swearWords from './swearWords'; +import * as theme from '../../../util/theme'; + +interface CigaretteBlockProps extends ViewProps { + cigaretteCount: number; + frequency: Frequency; +} + +function getSwearWord (cigaretteCount: number) { + if (cigaretteCount <= 1) return i18n.t('home_common_oh'); + + // Return a random swear word + return swearWords[Math.floor(Math.random() * swearWords.length)]; +} + +export function CigaretteBlock (props: CigaretteBlockProps) { + const { isGps } = useContext(CurrentLocationContext)!; + const { cigaretteCount, frequency, style, ...rest } = props; + + const renderCigarettesText = () => { + // Round to 1 decimal + const cigarettes = Math.round(cigaretteCount * 10) / 10; + + const text = i18n.t('home_smoked_cigarette_title', { + swearWord: getSwearWord(cigaretteCount), + presentPast: + isGps && frequency === 'daily' + ? i18n.t('home_common_you_smoke') + : i18n.t('home_common_you_d_smoke'), + singularPlural: + cigarettes === 1 + ? i18n.t('home_common_cigarette').toLowerCase() + : i18n.t('home_common_cigarettes').toLowerCase(), + cigarettes + }); + + const [firstPartText, secondPartText] = text.split('<'); + + return ( + + {firstPartText} + + {secondPartText.split('>')[0]} + + {secondPartText.split('>')[1]} + + ); + }; + + return ( + + + {renderCigarettesText()} + + ); +} + +const styles = StyleSheet.create({ + cigarettesCount: { + color: theme.primaryColor + }, + shit: { + ...theme.shitText, + marginTop: theme.spacing.normal + } +}); diff --git a/App/Screens/Home/Wait/index.ts b/App/Screens/Home/CigaretteBlock/index.ts similarity index 95% rename from App/Screens/Home/Wait/index.ts rename to App/Screens/Home/CigaretteBlock/index.ts index 562c9927..62560abb 100644 --- a/App/Screens/Home/Wait/index.ts +++ b/App/Screens/Home/CigaretteBlock/index.ts @@ -14,4 +14,4 @@ // You should have received a copy of the GNU General Public License // along with Sh**t! I Smoke. If not, see . -export * from './Wait'; +export * from './CigaretteBlock'; diff --git a/App/Screens/Home/swearWords.ts b/App/Screens/Home/CigaretteBlock/swearWords.ts similarity index 95% rename from App/Screens/Home/swearWords.ts rename to App/Screens/Home/CigaretteBlock/swearWords.ts index 7a0d2959..27060dd5 100644 --- a/App/Screens/Home/swearWords.ts +++ b/App/Screens/Home/CigaretteBlock/swearWords.ts @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Sh**t! I Smoke. If not, see . -import { i18n } from '../../localization'; +import { i18n } from '../../../localization'; export default [ i18n.t('home_swear_word_shoot'), diff --git a/App/Screens/Home/Footer/Footer.tsx b/App/Screens/Home/Footer/Footer.tsx index 7c5704c0..c1f6ce19 100644 --- a/App/Screens/Home/Footer/Footer.tsx +++ b/App/Screens/Home/Footer/Footer.tsx @@ -15,7 +15,7 @@ // along with Sh**t! I Smoke. If not, see . import React, { useContext } from 'react'; -import { Share, StyleSheet, Text, View } from 'react-native'; +import { Share, StyleSheet, View, ViewProps } from 'react-native'; import { NavigationInjectedProps } from 'react-navigation'; import { aboutSections } from '../../About'; @@ -26,29 +26,31 @@ import { track } from '../../../util/amplitude'; import { isStationTooFar } from '../../../util/station'; import * as theme from '../../../util/theme'; -interface FooterProps extends NavigationInjectedProps {} +interface FooterProps extends NavigationInjectedProps, ViewProps {} export function Footer (props: FooterProps) { const { api } = useContext(ApiContext)!; const { currentLocation } = useContext(CurrentLocationContext); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { navigation, style, ...rest } = props; const isTooFar = isStationTooFar(currentLocation!, api!); function goToAbout () { track('HOME_SCREEN_ABOUT_CLICK'); - props.navigation.navigate('About'); + navigation.navigate('About'); } function goToAboutWhySoFar () { track('HOME_SCREEN_ABOUT_WHY_SO_FAR_CLICK'); - props.navigation.navigate('About', { - scrollInto: aboutSections.about_why_is_the_station_so_far_title + navigation.navigate('About', { + scrollInto: aboutSections.aboutWhyIsTheStationSoFarTitle }); } function goToDetails () { track('HOME_SCREEN_DETAILS_CLICK'); - props.navigation.navigate('Details'); + navigation.navigate('Details'); } function handleShare () { @@ -93,12 +95,7 @@ export function Footer (props: FooterProps) { }; return ( - - {isTooFar && ( - - {i18n.t('home_station_too_far_message')} - - )} + {renderBigButton()} {renderSmallButtons()} @@ -106,18 +103,9 @@ export function Footer (props: FooterProps) { } const styles = StyleSheet.create({ - container: { - ...theme.withPadding, - marginBottom: theme.spacing.normal, - marginTop: theme.spacing.mini - }, - isStationTooFar: { - ...theme.text, - marginBottom: theme.spacing.normal - }, smallButtons: { flexDirection: 'row', justifyContent: 'space-around', - marginTop: theme.spacing.small + marginTop: theme.spacing.mini } }); diff --git a/App/Screens/Home/Header/Header.tsx b/App/Screens/Home/Header/Header.tsx index f2353c70..4c9fe407 100644 --- a/App/Screens/Home/Header/Header.tsx +++ b/App/Screens/Home/Header/Header.tsx @@ -22,6 +22,7 @@ import { Text, View } from 'react-native'; +import { scale } from 'react-native-size-matters'; import alert from '../../../../assets/images/alert.png'; import { ChangeLocation, CurrentLocation } from '../../../components'; @@ -56,54 +57,51 @@ export function Header (props: HeaderProps) { return ( - - - - - {isTooFar && } - - {i18n.t('home_header_air_quality_station_distance', { - distanceToStation: distance, - distanceUnit - })}{' '} - {!isGps && i18n.t('home_header_from_search')} - - + + + + {isTooFar && } + + {i18n.t('home_header_air_quality_station_distance', { + distanceToStation: distance, + distanceUnit + })}{' '} + {!isGps && i18n.t('home_header_from_search')} + - - + + ); } const styles = StyleSheet.create({ - backButton: { - marginBottom: theme.spacing.normal - }, - container: { - paddingHorizontal: theme.spacing.normal, - paddingTop: theme.spacing.normal - }, - content: { + ...theme.withPadding, alignItems: 'center', - flexDirection: 'row' + flexDirection: 'row', + paddingTop: theme.spacing.normal }, currentLocation: { - marginRight: theme.spacing.mini, - flex: 1 + flex: 1, + marginRight: theme.spacing.mini }, distance: { alignItems: 'center', flexDirection: 'row', marginTop: theme.spacing.mini }, + distanceText: { + ...theme.text, + flex: 1 + }, warning: { - marginRight: theme.spacing.mini + marginRight: theme.spacing.mini, + marginTop: scale(-2) // FIXME We shouldn't need that, with `alignItems: 'center'` on .distance } }); diff --git a/App/Screens/Home/Home.tsx b/App/Screens/Home/Home.tsx index 51d8d38d..c38590a3 100644 --- a/App/Screens/Home/Home.tsx +++ b/App/Screens/Home/Home.tsx @@ -15,83 +15,45 @@ // along with Sh**t! I Smoke. If not, see . import React, { useContext, useState } from 'react'; -import { ScrollView, StyleSheet, Text, View } from 'react-native'; +import { ScrollView, StyleSheet, View } from 'react-native'; import { NavigationInjectedProps } from 'react-navigation'; -import { Cigarettes } from '../../components'; +import { AdditionalInfo } from './AdditionalInfo'; +import { CigaretteBlock } from './CigaretteBlock'; import { Footer } from './Footer'; import { Header } from './Header'; -import { i18n } from '../../localization'; import { Frequency, SelectFrequency } from './SelectFrequency'; import { SmokeVideo } from './SmokeVideo'; -import { ApiContext, CurrentLocationContext } from '../../stores'; -import swearWords from './swearWords'; +import { ApiContext } from '../../stores'; +import { Api } from '../../stores/fetchApi'; import { track, trackScreen } from '../../util/amplitude'; import * as theme from '../../util/theme'; interface HomeProps extends NavigationInjectedProps {} -function getSwearWord (cigaretteCount: number) { - if (cigaretteCount <= 1) return i18n.t('home_common_oh'); - - // Return a random swear word - return swearWords[Math.floor(Math.random() * swearWords.length)]; +/** + * Compute the number of cigarettes to show + */ +function getCigaretteCount (frequency: Frequency, api: Api) { + switch (frequency) { + case 'daily': { + return api.shootISmoke.cigarettes; + } + case 'weekly': + return api.shootISmoke.cigarettes * 7; + case 'monthly': { + return api.shootISmoke.cigarettes * 30; + } + } } export function Home (props: HomeProps) { - const { api } = useContext(ApiContext)!; - const { isGps } = useContext(CurrentLocationContext)!; + const { api } = useContext(ApiContext); const [frequency, setFrenquency] = useState('daily'); - trackScreen('HOME'); - - function getCigaretteCount () { - switch (frequency) { - case 'daily': { - return api!.shootISmoke.cigarettes; - } - case 'weekly': - return api!.shootISmoke.cigarettes * 7; - case 'monthly': { - return api!.shootISmoke.cigarettes * 30; - } - } - } - const cigaretteCount = getCigaretteCount(); - - function renderCigarettes () { - return ; - } - - const renderCigarettesText = () => { - // Round to 1 decimal - const cigarettes = Math.round(cigaretteCount * 10) / 10; - - const text = i18n.t('home_smoked_cigarette_title', { - swearWord: getSwearWord(cigaretteCount), - presentPast: - isGps && frequency === 'daily' - ? i18n.t('home_common_you_smoke') - : i18n.t('home_common_you_d_smoke'), - singularPlural: - cigarettes === 1 - ? i18n.t('home_common_cigarette').toLowerCase() - : i18n.t('home_common_cigarettes').toLowerCase(), - cigarettes - }); + const cigaretteCount = getCigaretteCount(frequency, api!); - const [firstPartText, secondPartText] = text.split('<'); - - return ( - - {firstPartText} - - {secondPartText.split('>')[0]} - - {secondPartText.split('>')[1]} - - ); - }; + trackScreen('HOME'); return ( @@ -102,68 +64,43 @@ export function Home (props: HomeProps) { props.navigation.navigate('Search'); }} /> - - - {renderCigarettes()} - {renderCigarettesText()} - { - if (freq === 'daily') { - track('HOME_SCREEN_DAILY_CLICK'); - } else if (freq === 'weekly') { - track('HOME_SCREEN_WEEKLY_CLICK'); - } else if (freq === 'monthly') { - track('HOME_SCREEN_MONTHLY_CLICK'); - } - - setFrenquency(freq); - }} - style={styles.selectFrequency} - /> - -