Verified Commit dbfb6cb5 authored by Sébastiaan Versteeg's avatar Sébastiaan Versteeg
Browse files

Fix i18next-react and iPhone X notch support

parent 4fe269da
......@@ -76,6 +76,7 @@ android {
}
dependencies {
implementation project(':react-native-device-info')
implementation project(':react-native-screens')
implementation project(':react-native-gesture-handler')
implementation project(':react-native-sentry')
......
......@@ -3,6 +3,7 @@ package com.thaliapp;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.learnium.RNDeviceInfo.RNDeviceInfo;
import com.swmansion.rnscreens.RNScreensPackage;
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
import cl.json.ShareApplication;
......@@ -37,6 +38,7 @@ public class MainApplication extends Application implements ShareApplication, Re
protected List<ReactPackage> getPackages() {
return Arrays.asList(
new MainReactPackage(),
new RNDeviceInfo(),
new RNScreensPackage(),
new RNGestureHandlerPackage(),
new RNSharePackage(),
......
rootProject.name = 'ThaliApp'
include ':react-native-device-info'
project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
include ':react-native-screens'
project(':react-native-screens').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-screens/android')
include ':react-native-gesture-handler'
......
......@@ -4,7 +4,7 @@ import {
} from 'react-native';
import { applyMiddleware, createStore } from 'redux';
import { Provider } from 'react-redux';
import { I18nextProvider, translate } from 'react-i18next';
import { I18nextProvider, withTranslation } from 'react-i18next';
import createSagaMiddleware from 'redux-saga';
import firebase from 'react-native-firebase';
import locale from 'react-native-locale-detector';
......@@ -124,4 +124,4 @@ Main.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate('app/App')(Main);
export default withTranslation('app/App')(Main);
import React from 'react';
import { Image, Text, View } from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import PropTypes from 'prop-types';
import styles from './style/ErrorScreen';
......@@ -29,4 +29,4 @@ ErrorScreen.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate('components/errorScreen/ErrorScreen')(ErrorScreen);
export default withTranslation('components/errorScreen/ErrorScreen')(ErrorScreen);
......@@ -9,6 +9,7 @@ import {
TextInput,
TouchableOpacity,
View,
SafeAreaView,
} from 'react-native';
import PropTypes from 'prop-types';
......@@ -154,17 +155,19 @@ class SearchHeader extends Component {
animated
barStyle={isSearching ? 'dark-content' : 'light-content'}
/>
<View style={styles.appBar}>
{isAnimating && (
<Animated.View
style={[
styles.animationView, { transform: [{ scale: scaleValue }] }]}
/>
)}
{this.getLeftIcon()}
{this.getCenter()}
{this.getRightIcon()}
</View>
<SafeAreaView style={styles.safeArea}>
<View style={styles.appBar}>
{isAnimating && (
<Animated.View
style={[
styles.animationView, { transform: [{ scale: scaleValue }] }]}
/>
)}
{this.getLeftIcon()}
{this.getCenter()}
{this.getRightIcon()}
</View>
</SafeAreaView>
</View>
);
}
......
import { Dimensions } from 'react-native';
import Colors from '../../../style/Colors';
import StyleSheet from '../../../style/StyleSheet';
import Colors from '../../../style/Colors';
import { STATUSBAR_HEIGHT, APPBAR_HEIGHT }
from '../../standardHeader/style/StandardHeader';
import { APPBAR_HEIGHT, STATUSBAR_HEIGHT } from '../../standardHeader/style/StandardHeader';
const windowWidth = Dimensions.get('window').width;
const styles = StyleSheet.create({
safeArea: {
backgroundColor: Colors.magenta,
android: {
elevation: 4,
},
ios: {
borderStyle: 'solid',
borderBottomColor: Colors.darkMagenta,
borderBottomWidth: 1,
},
},
appBar: {
backgroundColor: Colors.magenta,
height: APPBAR_HEIGHT + STATUSBAR_HEIGHT,
paddingTop: STATUSBAR_HEIGHT,
justifyContent: 'flex-start',
alignItems: 'center',
flexWrap: 'wrap',
flexDirection: 'row',
elevation: 4,
android: {
height: APPBAR_HEIGHT + STATUSBAR_HEIGHT,
paddingTop: STATUSBAR_HEIGHT,
},
ios: {
height: APPBAR_HEIGHT,
},
},
title: {
color: Colors.white,
......
......@@ -4,7 +4,7 @@ import {
Alert, Image, ImageBackground, Text, TouchableHighlight, View,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import Icon from 'react-native-vector-icons/MaterialIcons';
import styles from './style/Sidebar';
import Colors from '../../style/Colors';
......@@ -125,4 +125,4 @@ Sidebar.propTypes = {
openMemberList: PropTypes.func.isRequired,
};
export default translate('components/sidebar/Sidebar')(Sidebar);
export default withTranslation('components/sidebar/Sidebar')(Sidebar);
import React from 'react';
import {
StatusBar, Text, TouchableOpacity, View,
StatusBar, Text, TouchableOpacity, View, SafeAreaView
} from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/MaterialIcons';
......@@ -43,24 +43,26 @@ const StandardHeader = props => (
barStyle="light-content"
/>
</View>
<View style={styles.appBar}>
<TouchableOpacity
style={styles.iconButton}
onPress={() => (props.menu ? props.navigation.toggleDrawer() : props.navigation.goBack())}
>
<Icon
name={props.menu ? 'menu' : 'arrow-back'}
style={styles.icon}
size={24}
/>
</TouchableOpacity>
<Text style={styles.title}>
{sceneToTitle(props.navigation.state.routeName, props.t)}
</Text>
<View style={styles.rightView}>
{props.rightView}
<SafeAreaView style={styles.safeArea}>
<View style={styles.appBar}>
<TouchableOpacity
style={styles.iconButton}
onPress={() => (props.menu ? props.navigation.toggleDrawer() : props.navigation.goBack())}
>
<Icon
name={props.menu ? 'menu' : 'arrow-back'}
style={styles.icon}
size={24}
/>
</TouchableOpacity>
<Text style={styles.title}>
{sceneToTitle(props.navigation.state.routeName, props.t)}
</Text>
<View style={styles.rightView}>
{props.rightView}
</View>
</View>
</View>
</SafeAreaView>
</View>
);
......@@ -76,7 +78,7 @@ StandardHeader.defaultProps = {
menu: false,
};
const StandardHeaderContainer = withNavigation(translate('components/standardHeader/StandardHeader')(StandardHeader));
const StandardHeaderContainer = withNavigation(withTranslation('components/standardHeader/StandardHeader')(StandardHeader));
export default StandardHeaderContainer;
export function withStandardHeader(Component, menu) {
......
import { Platform, StatusBar } from 'react-native';
import DeviceInfo from 'react-native-device-info';
import StyleSheet from '../../../style/StyleSheet';
import Colors from '../../../style/Colors';
export const STATUSBAR_HEIGHT = Platform.OS === 'ios' ? 20 : StatusBar.currentHeight;
// eslint-disable-next-line no-nested-ternary
export const STATUSBAR_HEIGHT = Platform.OS === 'ios'
? DeviceInfo.hasNotch() ? 44 : 20 : StatusBar.currentHeight;
export const APPBAR_HEIGHT = Platform.OS === 'ios' ? 44 : 56;
export const TOTAL_BAR_HEIGHT = APPBAR_HEIGHT + STATUSBAR_HEIGHT;
......@@ -19,13 +23,8 @@ const styles = StyleSheet.create({
elevation: 4,
},
},
appBar: {
safeArea: {
backgroundColor: Colors.magenta,
height: APPBAR_HEIGHT,
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center',
flexWrap: 'wrap',
android: {
height: APPBAR_HEIGHT,
elevation: 4,
......@@ -36,6 +35,14 @@ const styles = StyleSheet.create({
borderBottomWidth: 1,
},
},
appBar: {
backgroundColor: Colors.magenta,
height: APPBAR_HEIGHT,
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center',
flexWrap: 'wrap',
},
title: {
color: Colors.white,
android: {
......
import React from 'react';
import PropTypes from 'prop-types';
import { Text, TouchableHighlight, View } from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import Moment from 'moment';
import styles from './style/CalendarItem';
......@@ -57,4 +57,4 @@ CalendarItem.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate('screen/events/CalendarItem')(CalendarItem);
export default withTranslation('screen/events/CalendarItem')(CalendarItem);
......@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import {
RefreshControl, ScrollView, SectionList, Text, View,
} from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import Moment from 'moment';
import locale from 'react-native-locale-detector';
import CalendarItem from './CalendarItemConnector';
......@@ -205,4 +205,4 @@ CalendarScreen.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate('screens/events/CalendarScreen')(withStandardHeader(CalendarScreen, true));
export default withTranslation('screens/events/CalendarScreen')(withStandardHeader(CalendarScreen, true));
......@@ -2,7 +2,7 @@ import React, { Component } from 'react';
import {
View, Text, Switch, RefreshControl, ScrollView, FlatList, TouchableHighlight,
} from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/MaterialIcons';
import Snackbar from 'react-native-snackbar';
......@@ -340,4 +340,4 @@ EventAdminScreen.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate('screens/events/EventAdminScreen')(EventAdminScreen);
export default withTranslation('screens/events/EventAdminScreen')(EventAdminScreen);
......@@ -11,7 +11,7 @@ import {
TouchableOpacity,
View,
} from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import Moment from 'moment';
import HTML from 'react-native-render-html';
import Share from 'react-native-share';
......@@ -556,4 +556,4 @@ EventScreen.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate('screens/events/EventScreen')(EventScreen);
export default withTranslation('screens/events/EventScreen')(EventScreen);
......@@ -9,7 +9,7 @@ import {
TextInput,
View,
} from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import PropTypes from 'prop-types';
import HTML from 'react-native-render-html';
......@@ -218,4 +218,4 @@ RegistrationScreen.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate('screens/events/RegistrationScreen')(withStandardHeader(RegistrationScreen));
export default withTranslation('screens/events/RegistrationScreen')(withStandardHeader(RegistrationScreen));
......@@ -9,7 +9,7 @@ import {
TextInput,
View,
} from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { url } from '../../../utils/url';
import DismissKeyboardView from '../../components/dismissKeyboardView/DismissKeyboardView';
import Button from '../../components/button/Button';
......@@ -119,4 +119,4 @@ LoginScreen.propTypes = {
status: PropTypes.string.isRequired,
};
export default translate(['screens/user/LoginScreen'])(LoginScreen);
export default withTranslation(['screens/user/LoginScreen'])(LoginScreen);
import React, { Component } from 'react';
import { FlatList, View } from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import PropTypes from 'prop-types';
import MemberView from '../../components/memberView/MemberViewConnector';
......@@ -115,4 +115,4 @@ MemberListScreen.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate('screens/memberList/MemberListScreen')(MemberListScreen);
export default withTranslation('screens/memberList/MemberListScreen')(MemberListScreen);
......@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import {
RefreshControl, ScrollView, Text, TouchableHighlight, View,
} from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import Icon from 'react-native-vector-icons/MaterialIcons';
import Moment from 'moment';
import LoadingScreen from '../../components/loadingScreen/LoadingScreen';
......@@ -277,4 +277,4 @@ PizzaScreen.defaultProps = {
order: null,
};
export default translate('screens/pizza/PizzaScreen')(withStandardHeader(PizzaScreen));
export default withTranslation('screens/pizza/PizzaScreen')(withStandardHeader(PizzaScreen));
import PropTypes from 'prop-types';
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { Text, View } from 'react-native';
import Moment from 'moment';
import CardSection from '../../components/cardSection/CardSection';
......@@ -73,4 +73,4 @@ AchievementSection.propTypes = {
type: PropTypes.string.isRequired,
};
export default translate('screens/profile/AchievementSection')(AchievementSection);
export default withTranslation('screens/profile/AchievementSection')(AchievementSection);
import PropTypes from 'prop-types';
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { Text } from 'react-native';
import CardSection from '../../components/cardSection/CardSection';
import styles from './style/Profile';
......@@ -31,4 +31,4 @@ DescriptionSection.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate('screens/profile/DescriptionSection')(DescriptionSection);
export default withTranslation('screens/profile/DescriptionSection')(DescriptionSection);
import PropTypes from 'prop-types';
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { Text, View } from 'react-native';
import Moment from 'moment';
import CardSection from '../../components/cardSection/CardSection';
......@@ -70,4 +70,4 @@ PersonalInfoSection.propTypes = {
openUrl: PropTypes.func.isRequired,
};
export default translate('screens/profile/PersonalInfoSection')(PersonalInfoSection);
export default withTranslation('screens/profile/PersonalInfoSection')(PersonalInfoSection);
......@@ -9,7 +9,7 @@ import {
TouchableOpacity,
View,
} from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import LinearGradient from 'react-native-linear-gradient';
import Icon from 'react-native-vector-icons/MaterialIcons';
import ErrorScreen from '../../components/errorScreen/ErrorScreen';
......@@ -230,4 +230,4 @@ ProfileScreen.propTypes = {
goBack: PropTypes.func.isRequired,
};
export default translate('screens/profile/ProfileScreen')(ProfileScreen);
export default withTranslation('screens/profile/ProfileScreen')(ProfileScreen);
import React, { Component } from 'react';
import { Switch, Text, View } from 'react-native';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import styles from './style/NotificationsSection';
import Colors from '../../style/Colors';
......@@ -106,4 +106,4 @@ NotificationsSection.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate('screens/settings/NotificationsSection')(NotificationsSection);
export default withTranslation('screens/settings/NotificationsSection')(NotificationsSection);
......@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import {
Text, TouchableHighlight, TouchableOpacity, View,
} from 'react-native';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import Moment from 'moment';
import styles from './style/EventDetailCard';
......@@ -96,4 +96,4 @@ EventDetailCard.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate(['screens/welcome/EventDetailCard'])(EventDetailCard);
export default withTranslation('screens/welcome/EventDetailCard')(EventDetailCard);
......@@ -9,7 +9,7 @@ import {
View,
} from 'react-native';
import { connect } from 'react-redux';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import Moment from 'moment';
import EventDetailCard from './EventDetailCardConnector';
import LoadingScreen from '../../components/loadingScreen/LoadingScreen';
......@@ -69,7 +69,7 @@ const mapDispatchToFooterProps = {
openCalendar: calendarActions.open,
};
const FooterComponent = connect(() => ({}), mapDispatchToFooterProps)(translate('screens/welcome/WelcomeScreen')(Footer));
const FooterComponent = connect(() => ({}), mapDispatchToFooterProps)(withTranslation('screens/welcome/WelcomeScreen')(Footer));
class WelcomeScreen extends Component {
handleRefresh = () => {
......@@ -160,4 +160,4 @@ WelcomeScreen.propTypes = {
t: PropTypes.func.isRequired,
};
export default translate('screens/welcome/WelcomeScreen')(withStandardHeader(WelcomeScreen, true));
export default withTranslation('screens/welcome/WelcomeScreen')(withStandardHeader(WelcomeScreen, true));
import i18n from 'i18next';
import { reactI18nextModule } from 'react-i18next';
import { initReactI18next } from 'react-i18next';
import i18nextReactNative from 'i18next-react-native-language-detector';
import locales from '../assets/locales/index';
i18n
.use(reactI18nextModule)
.use(initReactI18next)
.use(i18nextReactNative)
.init({
nsSeparator: false,
......
import locale from 'react-native-locale-detector';
let server = 'https://thalia.nu';
let server = 'https://staging.thalia.nu';
/* istanbul ignore next line */
if (__DEV__) { // eslint-disable-line no-undef
server = 'http://localhost:8000';
// server = 'http://localhost:8000';
}
export const url = server;
......
......@@ -5,7 +5,6 @@
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
......@@ -39,6 +38,7 @@
2DCD954D1E0B4F2C00145EB5 /* ThaliAppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ThaliAppTests.m */; };
2DF0FFEE2056DD460020B375 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; };
2F6E0641344C43BD8556F071 /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = DCCD2767C1244F58838A52AC /* Ionicons.ttf */; };
3238F61D229F16FE00BEB7F8 /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3238F61A229F16F400BEB7F8 /* libRNDeviceInfo.a */; };
327DC4A2229EB48000DE29E9 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 327DC4A1229EB48000DE29E9 /* GoogleService-Info.plist */; };
327DC54B229EB8E100DE29E9 /* libBVLinearGradient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 327DC537229EB6C300DE29E9 /* libBVLinearGradient.a */; };
327DC54C229EB8E100DE29E9 /* libRNScreens.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 327DC527229EB68D00DE29E9 /* libRNScreens.a */; };
......@@ -204,6 +204,20 @@
remoteGlobalIDString = 3D383D621EBD27B9005632C8;
remoteInfo = "double-conversion-tvOS";
};
3238F619229F16F400BEB7F8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 3238F614229F16F300BEB7F8 /* RNDeviceInfo.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = DA5891D81BA9A9FC002B4DB2;
remoteInfo = RNDeviceInfo;
};
3238F61B229F16F400BEB7F8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 3238F614229F16F300BEB7F8 /* RNDeviceInfo.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = E72EC1401F7ABB5A0001BC90;
remoteInfo = "RNDeviceInfo-tvOS";
};
327DC48C229EB42900DE29E9 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
......@@ -476,6 +490,7 @@
2D02E4901E0B4A5D006451C7 /* ThaliApp-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ThaliApp-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; };
2F20D59838BD63F955316D16 /* Pods-ThaliAppTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ThaliAppTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ThaliAppTests/Pods-ThaliAppTests.release.xcconfig"; sourceTree = "<group>"; };
3238F614229F16F300BEB7F8 /* RNDeviceInfo.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNDeviceInfo.xcodeproj; path = "../node_modules/react-native-device-info/ios/RNDeviceInfo.xcodeproj"; sourceTree = "<group>"; };
327DC4A1229EB48000DE29E9 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
327DC4A3229EB53A00DE29E9 /* ThaliApp.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = ThaliApp.entitlements; path = ThaliApp/ThaliApp.entitlements; sourceTree = "<group>"; };
327DC4B2229EB5A700DE29E9 /* RNSentry.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNSentry.xcodeproj; path = "../node_modules/react-native-sentry/ios/RNSentry.xcodeproj"; sourceTree = "<group>"; };
......@@ -526,6 +541,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
3238F61D229F16FE00BEB7F8 /* libRNDeviceInfo.a in Frameworks */,
327DC59C229EBC1500DE29E9 /* libRNGestureHandler.a in Frameworks */,
327DC54B229EB8E100DE29E9 /* libBVLinearGradient.a in Frameworks */,
327DC54C229EB8E100DE29E9 /* libRNScreens.a in Frameworks */,
......@@ -734,6 +750,15 @@
name = Frameworks;