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: Add some translations #89

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add translations
  • Loading branch information
amaury1093 committed May 17, 2019
commit d2195372577ff01203b4f5bf9d74c8c4a75bcd0e
3 changes: 1 addition & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
# editorconfig-tools is unable to ignore longs strings or urls
max_line_length = null
max_line_length = 100
34 changes: 22 additions & 12 deletions App/Screens/About/Language/Language.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,46 +14,56 @@
// You should have received a copy of the GNU General Public License
// along with Sh**t! I Smoke. If not, see <http:https://www.gnu.org/licenses/>.

import localeCode from 'locale-code';
import { getName } from 'country-list';
import { getNativeName } from 'iso-639-1';
import { inject, observer } from 'mobx-react';
import React, { Component } from 'react';
import { Picker, StyleSheet, Text, View } from 'react-native';

import { i18n } from '../../../localization';
import * as theme from '../../../utils/theme';

function getLanguageName (code) {
const [languageCode, countryCode] = code.split('-');
const languageName = getNativeName(languageCode);
const countryName = countryCode ? ` (${getName(countryCode)})` : '';

return languageName + countryName;
}

@inject('stores')
@observer
export class Language extends Component {
handleValueChange = (itemValue) => {
handleValueChange = itemValue => {
i18n.locale = itemValue;

// Reload app for changes to take effect
this.props.stores.reloadApp();
}
};

render () {
console.log(getLanguageName('en-US'));
console.log(getLanguageName('en-GB'));
console.log(getLanguageName('fr'));
console.log(getLanguageName('fr-BE'));
console.log(getLanguageName('es'));
console.log(getLanguageName('pt-BR'));
// Using this hack to show custom picker style
// https://github.com/facebook/react-native/issues/7817#issuecomment-264851951
return (
<View style={styles.container}>
<Text style={theme.link}>{localeCode.getLanguageNativeName(i18n.locale)}</Text>
<Text style={theme.link}>{getLanguageName(i18n.locale)}</Text>
<Picker
itemStyle={theme.text}
onValueChange={this.handleValueChange}
selectedValue={i18n.locale}
style={styles.picker}
>
{Object.keys(i18n.translations).map((lang) =>
<Picker.Item
key={lang}
label={localeCode.getLanguageNativeName(lang)}
value={lang}
/>)
}
{Object.keys(i18n.translations).map(lang => (
<Picker.Item key={lang} label={getLanguageName(lang)} value={lang} />
))}
</Picker>
</View>

);
}
}
Expand Down
13 changes: 9 additions & 4 deletions App/Screens/Details/Header/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import React, { Component } from 'react';
import { formatRelative } from 'date-fns';
import * as datesFnsLocales from 'date-fns/locale';
import { Image, StyleSheet, Text, View } from 'react-native';
import { inject, observer } from 'mobx-react';

Expand All @@ -36,8 +37,7 @@ export class Header extends Component {
stores: { api }
} = this.props;

const lastUpdated =
api.time && api.time.v ? new Date(api.time.v * 1000) : null;
const lastUpdated = api.time && api.time.v ? new Date(api.time.v * 1000) : null;
const { dominentpol, iaqi } = api;

return (
Expand All @@ -52,10 +52,15 @@ export class Header extends Component {
{lastUpdated &&
this.renderInfo(
i18n.t('details_header_latest_update_label'),
formatRelative(lastUpdated, new Date())
formatRelative(lastUpdated, new Date(), {
locale: datesFnsLocales[i18n.locale.split('-')[0]]
})
)}
{dominentpol &&
this.renderInfo(i18n.t('details_header_primary_pollutant_label'), dominentpol.toUpperCase())}
this.renderInfo(
i18n.t('details_header_primary_pollutant_label'),
dominentpol.toUpperCase()
)}

<View style={styles.pollutants}>
{trackedPollutant.map(
Expand Down
41 changes: 23 additions & 18 deletions App/Screens/ErrorScreen/ErrorScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import { inject, observer } from 'mobx-react';
import React, { Component } from 'react';
import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { Image, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';

import error from '../../../assets/images/error.png';
import { i18n } from '../../localization';
Expand All @@ -31,24 +31,28 @@ export class ErrorScreen extends Component {
const { error: errorText } = this.props.stores;

return (
<View style={styles.container}>
<Image source={error} />
<View>
<Text style={styles.errorText}>
<Text style={styles.sorry}>{i18n.t('error_screen_common_sorry')}</Text>
{i18n.t('error_screen_error_cannot_load_cigarettes')}
<ScrollView>
<View style={styles.container}>
<Image source={error} />
<View>
<Text style={styles.errorText}>
<Text style={styles.sorry}>{i18n.t('error_screen_common_sorry')}</Text>
{i18n.t('error_screen_error_cannot_load_cigarettes')}
</Text>
</View>
<TouchableOpacity onPress={this.goToSearch}>
<View style={styles.chooseOther}>
<Text style={theme.bigButtonText}>
{i18n.t('error_screen_choose_other_location').toUpperCase()}
</Text>
</View>
</TouchableOpacity>
<Text style={theme.text}>{i18n.t('error_screen_error_description')}</Text>
<Text style={styles.errorMessage}>
{i18n.t('error_screen_error_message', { errorText })}
</Text>
</View>
<TouchableOpacity onPress={this.goToSearch}>
<View style={styles.chooseOther}>
<Text style={theme.bigButtonText}>{i18n.t('error_screen_choose_other_location').toUpperCase()}</Text>
</View>
</TouchableOpacity>
<Text style={theme.text}>
{i18n.t('error_screen_error_description')}
</Text>
<Text style={styles.errorMessage}>{i18n.t('error_screen_error_message', { errorText })}</Text>
</View>
</ScrollView>
);
}
}
Expand All @@ -62,7 +66,8 @@ const styles = StyleSheet.create({
...theme.fullScreen,
...theme.withPadding,
flexGrow: 1,
flexDirection: 'column'
flexDirection: 'column',
marginVertical: theme.spacing.normal
},
errorMessage: {
...theme.text,
Expand Down
43 changes: 21 additions & 22 deletions App/Screens/Home/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,7 @@

import React, { Component } from 'react';
import { inject, observer } from 'mobx-react';
import {
ScrollView,
Share,
StyleSheet,
Text,
TouchableOpacity,
View
} from 'react-native';
import { ScrollView, Share, StyleSheet, Text, TouchableOpacity, View } from 'react-native';

import { Cigarettes } from './Cigarettes';
import { Header } from './Header';
Expand Down Expand Up @@ -67,9 +60,7 @@ export class Home extends Component {
</View>
<View style={styles.cta}>
{isStationTooFar && (
<Text style={styles.isStationTooFar}>
{i18n.t('home_station_too_far_message')}
</Text>
<Text style={styles.isStationTooFar}>{i18n.t('home_station_too_far_message')}</Text>
)}
{this.renderBigButton()}
{this.renderFooter()}
Expand All @@ -87,7 +78,9 @@ export class Home extends Component {
return (
<TouchableOpacity onPress={this.goToAbout}>
<View style={theme.bigButton}>
<Text style={theme.bigButtonText}>{i18n.t('home_btn_why_is_station_so_far').toUpperCase()}</Text>
<Text style={theme.bigButtonText}>
{i18n.t('home_btn_why_is_station_so_far').toUpperCase()}
</Text>
</View>
</TouchableOpacity>
);
Expand All @@ -96,7 +89,9 @@ export class Home extends Component {
return (
<TouchableOpacity onPress={this.goToDetails}>
<View style={theme.bigButton}>
<Text style={theme.bigButtonText}>{i18n.t('home_btn_see_detailed_info').toUpperCase()}</Text>
<Text style={theme.bigButtonText}>
{i18n.t('home_btn_see_detailed_info').toUpperCase()}
</Text>
</View>
</TouchableOpacity>
);
Expand All @@ -110,18 +105,22 @@ export class Home extends Component {
<View style={styles.smallButtons}>
{isStationTooFar ? (
<SmallButton
icon='plus-circle'
icon="plus-circle"
text={i18n.t('home_btn_more_details').toUpperCase()}
onPress={this.goToDetails}
/>
) : (
<SmallButton
icon='question-circle'
icon="question-circle"
text={i18n.t('home_btn_faq_about').toUpperCase()}
onPress={this.goToAbout}
/>
)}
<SmallButton icon='share-alt' text={i18n.t('home_btn_share').toUpperCase()} onPress={this.handleShare} />
<SmallButton
icon="share-alt"
text={i18n.t('home_btn_share').toUpperCase()}
onPress={this.handleShare}
/>
</View>
);
};
Expand Down Expand Up @@ -152,19 +151,19 @@ export class Home extends Component {
const text = i18n.t('home_smoked_cigarette_title', {
swearWord: this.renderShit(),
presentPast: this.renderPresentPast(),
singularPlural: cigarettes === 1 ? i18n.t('home_common_cigarette').toLowerCase() : i18n.t('home_common_cigarettes').toLowerCase(),
singularPlural:
cigarettes === 1
? i18n.t('home_common_cigarette').toLowerCase()
: i18n.t('home_common_cigarettes').toLowerCase(),
cigarettes
});

const firstPartText = text.split('<')[0];
const secondPartText = text.split('<')[1];
const [firstPartText, secondPartText] = text.split('<');

return (
<Text adjustsFontSizeToFit style={styles.shit}>
{firstPartText}
<Text style={styles.cigarettesCount}>
{secondPartText.split('>')[0]}
</Text>
<Text style={styles.cigarettesCount}>{secondPartText.split('>')[0]}</Text>
{secondPartText.split('>')[1]}
</Text>
);
Expand Down
7 changes: 2 additions & 5 deletions App/localization/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,17 @@ const ptBR = require('./languages/pt-BR');
i18n.fallbacks = true;
i18n.translations = {
en,
'en-GB': en,
'en-US': en,
'en-UK': en,
es,
fr,
'fr-BE': fr,
'fr-CH': fr,
'fr-FR': fr,
'fr-CA': fr,
pt: ptBR,
'pt-BR': ptBR
};

i18n.locale = Localization.locale || 'en';

export {
i18n
};
export { i18n };
44 changes: 22 additions & 22 deletions App/localization/languages/fr.json
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
{
"error_screen_common_sorry": "Désolé !",
"error_screen_error_cannot_load_cigarettes": "Ne ne pouvons\npas charger\nvos cigarettes.",
"error_screen_common_sorry": "Désolé ! ",
"error_screen_error_cannot_load_cigarettes": "Nous ne pouvons pas charger vos cigarettes.",
"error_screen_choose_other_location": "Choisir un autre lieu",
"error_screen_error_description": "Il y a soit un problème avec nos bases de données, ou bien vous n'avez pas de station de surveillance de l'air près de vous. Réessayez plus tard !",
"error_screen_error_description": "Il y a soit un problème avec nos bases de données, ou bien vous n'avez pas de station de qualité de l'air près de vous. Réessayez plus tard !",
"error_screen_error_message": "Erreur: {{errorText}}",
"home_station_too_far_message": "Nous ne sommes pas parvenus à trouver une station plus proche de vous. Les résultats pourraient être inexacts à cette distance.",
"home_share_title": "Saviez-vous que vous fumez peut-être jusqu'à 20 cigarettes par jour, juste parce-que vous vivez dans une grande ville?",
"home_share_message": "Zut! J'ai 'fumé' {{cigarettes}} cigarettes aujourd'hui en respirant l'air urbain. Et toi? Regarde ici : https://shootismoke.github.io",
"home_header_air_quality_station_distance": "Station de surveillance de l'air: {{distanceToStation}}km",
"home_btn_why_is_station_so_far": "Pourquoi la station est-elle si éloignée?",
"home_btn_see_detailed_info": "Voir des informations plus détaillées",
"home_btn_more_details": "Plus de détails",
"home_btn_faq_about": "Faq/À propos",
"home_header_air_quality_station_distance": "Station de qualité de l'air: {{distanceToStation}}km",
"home_btn_why_is_station_so_far": "La station est éloignée !",
"home_btn_see_detailed_info": "Plus de détails",
"home_btn_more_details": "Détails",
"home_btn_faq_about": "A propos",
"home_btn_share": "Partager",
"home_common_you_ll_smoke": "Vous allez fumer",
"home_common_you_smoked": "Vous avez fumé",
"home_common_oh": "Oh",
"home_common_cigarette": "Cigarette",
"home_common_cigarettes": "Cigarettes",
"home_smoked_cigarette_title": "{{swearWord}}! {{presentPast}} <{{cigarettes}} {{singularPlural}}> aujourd'hui.",
"home_swear_word_dang": "Dang",
"home_swear_word_shoot": "Shoot",
"home_swear_word_darn": "Zut",
"home_swear_word_geez": "Geez",
"home_swear_word_omg": "OMG",
"home_swear_word_crap": "Crap",
"home_swear_word_dang": "Ma foi ",
"home_swear_word_shoot": "Eh bien ",
"home_swear_word_darn": "Bigre ",
"home_swear_word_geez": "Miséricorde ",
"home_swear_word_omg": "La barbe ",
"home_swear_word_crap": "Saperlipopette ",
"home_swear_word_arrgh": "Arrgh",
"loading_title_cough": "Tousse",
"loading_title_cough": "Kof",
"loading_title_loading": "Chargement",
"search_header_input_placeholder": "Chercher une ville ou une adresse",
"nav_btn_back": "Retour",
"details_air_quality_station_marker": "Station de mesure de la pollution de l'air",
"details_your_position_marker": "Votre position",
"details_air_quality_station_marker": "Station de qualité de l'air",
"details_your_position_marker": "Ma position",
"details_header_latest_update_label": "Dernière mise à jour :",
"details_header_primary_pollutant_label": "Polluant primaire :",
"details_header_primary_pollutant_label": "Polluant principal :",
"details_distance_label": "Station AQI: {{distanceToStation}}km",
"about_how_do_you_calculate_the_number_of_cigarettes_title": "Comment calculons nous le nombre de cigarettes ?",
"about_how_do_you_calculate_the_number_of_cigarettes_message_1": "Cette application a été inspirée des recherches sur la terre de Berkeley à propos du",
"about_how_do_you_calculate_the_number_of_cigarettes_message_1": "Cette application a été inspirée des recherches de Berkeley à propos du",
"about_how_do_you_calculate_the_number_of_cigarettes_link_1": "lien entre la pollution de l'air et les cigarettes fumées",
"about_how_do_you_calculate_the_number_of_cigarettes_message_2": ". La règle de base est simple: une cigarette par jour équivaut approximativement à un niveau de PM2,5 de 22",
"about_where_does_data_come_from_title": "D'où viennent les données ?",
Expand All @@ -46,14 +46,14 @@
"about_why_is_the_station_so_far_title": "Pourquoi la station est-elle si loin de moi ?",
"about_why_is_the_station_so_far_message": "Comme les stations qui mesurent et communiquent les résultats de la qualité de l'air toutes les heures coûtent cher, les données sont toujours limitées aux régions bien développées et aux grandes villes du monde. Si vous êtes loin d'un centre urbain plus important, les résultats ne seront probablement pas aussi précis. Les chances sont que votre air est meilleur dans ce cas au moins!",
"about_weird_results_title": "Les résultats sont incohérents!",
"about_weird_results_message_1": "Nous avons également rencontré quelques résultats surprenants: des grandes villes avec un meilleur air que des petits villages; augmentation soudaine et considérable du nombre de cigarettes; Les stations de la même ville affichent des chiffres très différents… Le fait est que la qualité de l’air dépend de plusieurs facteurs tels que la température, la pression, l’humidité et même la direction et l’intensité du vent. Si le résultat vous semble étrange, regardez sur",
"about_weird_results_message_1": "Nous avons également rencontré quelques résultats surprenants : des grandes villes avec un meilleur air que des petits villages; augmentation soudaine et considérable du nombre de cigarettes; Les stations de la même ville affichent des chiffres très différents… Le fait est que la qualité de l’air dépend de plusieurs facteurs tels que la température, la pression, l’humidité et même la direction et l’intensité du vent. Si le résultat vous semble étrange, regardez sur",
"about_weird_results_link_1": "WAQI",
"about_weird_results_message_2": "pour plus d'informations et un historique de votre station.",
"about_box_per_day": "par jour",
"about_box_footnote": "* Les particules atmosphériques (PM) dont le diamètre est inférieur à 2,5 micromètres augmentent les risques d’inhalation par les êtres vivants.",
"about_credits_title": "Crédits",
"about_credits_concept_and_development": "Concept & Développement par",
"about_credits_design_and_copywriting": "Design & Rédaction par",
"about_credits_concept_and_development": "Concept & Développement :",
"about_credits_design_and_copywriting": "Design & Rédaction :",
"about_credits_data_from": "Mesure de qualité de l'air de",
"about_credits_source_code": "Code source",
"about_credits_available_github": "disponible sur GitHub",
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
"@expo/vector-icons": "^9.0.0",
"async-retry": "^1.2.3",
"axios": "^0.18.0",
"country-list": "^2.1.0",
"date-fns": "^2.0.0-alpha.25",
"expo": "^32.0.0",
"haversine": "^1.1.0",
"i18n-js": "^3.2.1",
"locale-code": "^2.0.2",
"iso-639-1": "^2.0.5",
"mobx": "^4.6.0",
"mobx-react": "^5.3.6",
"mobx-state-tree": "^3.7.1",
Expand Down
Loading