Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion app/components/NoEmission/NoEmission.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const NoEmission: React.FC = () => {
const navigator = navigate(navigation);

return (
<ScrollView style={styles.container}>
<ScrollView style={styles.container} contentInsetAdjustmentBehavior="automatic">
<StickersImage sticker="earth" />
<View style={styles.textView}>
<Text.H1 style={styles.header}>{t("NO_EMISSION_COMPONENT_TITLE")}</Text.H1>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

exports[`renders correctly NoEmission 1`] = `
<ScrollView
contentInsetAdjustmentBehavior="automatic"
ref={null}
style={
{
Expand Down
6 changes: 4 additions & 2 deletions app/constant/Layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ const SPACING = {
const PADDING_HORIZONTAL = SPACING.DOUBLE;

const isSmallDevice = width < 375;

const screen = {
width,
height,
};

export { screen, isSmallDevice, PADDING_HORIZONTAL, SPACING };
// Standard Android Bottom Tab Bar height (typically 56dp) plus a small 4dp buffer. We must use a hardcoded value here because the dynamic useBottomTabBarHeight hook causes a crash when used outside the Tab Navigator context (which is the case with our Native Tabs setup)
const ANDROID_TAB_BAR_HEIGHT = 60;

export { screen, isSmallDevice, PADDING_HORIZONTAL, SPACING, ANDROID_TAB_BAR_HEIGHT };
9 changes: 9 additions & 0 deletions app/hooks/useTabBarBottomPadding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useSafeAreaInsets } from "react-native-safe-area-context";

import { platform } from "utils";
import { Layout } from "constant";

export const useTabBarBottomPadding = (): number => {
const insets = useSafeAreaInsets();
return platform.isAndroid ? Layout.ANDROID_TAB_BAR_HEIGHT + insets.bottom : 0;
};
41 changes: 19 additions & 22 deletions app/navigation/Navigator/BottomTabNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React from "react";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { createNativeBottomTabNavigator, type NativeBottomTabNavigationOptions } from "@react-navigation/bottom-tabs/unstable";

import { TabBarIcon } from "components";
import { t } from "utils";
import { Colors } from "style";

Expand All @@ -12,35 +10,34 @@ import EmissionsNavigator from "./BottomTab/EmissionsNavigator";
import SettingsNavigator from "./BottomTab/SettingsNavigator";
import AddEmissionNavigator from "./BottomTab/AddEmissionNavigator";

const BottomTab = createBottomTabNavigator();
const BottomTab = createNativeBottomTabNavigator();

const BudgetOptions = {
const BudgetOptions: NativeBottomTabNavigationOptions = {
tabBarLabel: t("BUDGET_SCREEN_TAB_NAME"),
tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} name={"calculator"} />,
tabBarIcon: { type: "image", source: require("../../../assets/images/tabs/budget.png") },
};

const EmissionsOptions = {
const EmissionsOptions: NativeBottomTabNavigationOptions = {
tabBarLabel: t("EMISSIONS_SCREEN_TAB_NAME"),
tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} name={"stats-chart-sharp"} />,
tabBarIcon: { type: "image", source: require("../../../assets/images/tabs/emissions.png") },
};

const ActOptions = {
const ActOptions: NativeBottomTabNavigationOptions = {
tabBarLabel: t("ACT_SCREEN_TAB_NAME"),
tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} name={"hand-left-sharp"} />,
tabBarIcon: { type: "image", source: require("../../../assets/images/tabs/act.png") },
};

const SettingsOptions = {
const SettingsOptions: NativeBottomTabNavigationOptions = {
tabBarLabel: t("SETTINGS_SCREEN_TAB_NAME"),
tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} name={"options"} />,
tabBarIcon: { type: "image", source: require("../../../assets/images/tabs/settings.png") },
};

const AddEmissionOptions = {
const AddEmissionOptions: NativeBottomTabNavigationOptions = {
tabBarLabel: t("ADD_EMISSION_SCREEN_TAB_NAME"),
tabBarIcon: ({ focused }) => <TabBarIcon focused={focused} name={"add-circle"} />,
tabBarIcon: { type: "image", source: require("../../../assets/images/tabs/add.png") },
};

const BottomTabNavigator = (): React.ReactElement => {
const { bottom } = useSafeAreaInsets();
return (
<BottomTab.Navigator
id="BottomTab"
Expand All @@ -49,12 +46,7 @@ const BottomTabNavigator = (): React.ReactElement => {
headerShown: false,
tabBarActiveTintColor: Colors.primary,
tabBarInactiveTintColor: Colors.black50,
tabBarBadgeStyle: {
backgroundColor: Colors.white,
borderTopWidth: 2,
borderTopColor: Colors.primary10,
paddingBottom: bottom / 2 + 6,
},
tabBarLabelVisibilityMode: "labeled",
}}
>
<BottomTab.Screen
Expand All @@ -72,7 +64,11 @@ const BottomTabNavigator = (): React.ReactElement => {
options={AddEmissionOptions}
component={AddEmissionNavigator}
/>
<BottomTab.Screen name="Act" options={ActOptions} component={ActNavigator} />
<BottomTab.Screen
name="Act"
options={ActOptions}
component={ActNavigator}
/>
<BottomTab.Screen
name="SettingsNavigator"
options={SettingsOptions}
Expand All @@ -83,3 +79,4 @@ const BottomTabNavigator = (): React.ReactElement => {
};

export default BottomTabNavigator;

47 changes: 28 additions & 19 deletions app/screens/About/AboutScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,38 @@ import { ScrollView, View } from "react-native";
import { Text, StickersImage } from "components";
import { t } from "utils";
import { NavStatelessComponent } from "interfaces";
import { useTabBarBottomPadding } from "hooks/useTabBarBottomPadding";

import styles from "./AboutScreen.styles";
import navigationOptions from "./AboutScreen.navigationOptions";

const AboutScreen: NavStatelessComponent = () => (
<ScrollView style={styles.container}>
<StickersImage sticker="earth" />
<Text.Primary style={styles.header}>{t("ABOUT_SCREEN_INTRO")}</Text.Primary>
<Text.H2 style={styles.header}>{t("ABOUT_SCREEN_CARE_HEADER")}</Text.H2>
<Text.H3 style={styles.subHeader}>{t("ABOUT_SCREEN_PRIVACY")}</Text.H3>
<Text.Primary>{t("ABOUT_SCREEN_PRIVACY_BODY")}</Text.Primary>
<Text.H3 style={styles.subHeader}>{t("ABOUT_SCREEN_ETHIC")}</Text.H3>
<Text.Primary>{t("ABOUT_SCREEN_ETHIC_BODY")}</Text.Primary>
<Text.H3 style={styles.subHeader}>{t("ABOUT_SCREEN_OPEN_SOURCE")}</Text.H3>
<Text.Primary>{t("ABOUT_SCREEN_OPEN_SOURCE_BODY")}</Text.Primary>
<Text.H2 style={styles.header}>{t("ABOUT_SCREEN_LIBRARIES_AND_CONTRIBUTORS")}</Text.H2>
<View style={styles.githubView}>
<Text.Primary>{t("ABOUT_SCREEN_CAN_BE_FOUND")}</Text.Primary>
<Text.Link url="https://github.com/NMF-earth/nmf-app">{t("ABOUT_SCREEN_GITHUB")}</Text.Link>
</View>
<View style={styles.separator} />
</ScrollView>
);
const AboutScreen: NavStatelessComponent = () => {
const bottomPadding = useTabBarBottomPadding();

return (
<ScrollView
style={styles.container}
contentInsetAdjustmentBehavior="automatic"
contentContainerStyle={{ paddingBottom: bottomPadding }}
>
<StickersImage sticker="earth" />
<Text.Primary style={styles.header}>{t("ABOUT_SCREEN_INTRO")}</Text.Primary>
<Text.H2 style={styles.header}>{t("ABOUT_SCREEN_CARE_HEADER")}</Text.H2>
<Text.H3 style={styles.subHeader}>{t("ABOUT_SCREEN_PRIVACY")}</Text.H3>
<Text.Primary>{t("ABOUT_SCREEN_PRIVACY_BODY")}</Text.Primary>
<Text.H3 style={styles.subHeader}>{t("ABOUT_SCREEN_ETHIC")}</Text.H3>
<Text.Primary>{t("ABOUT_SCREEN_ETHIC_BODY")}</Text.Primary>
<Text.H3 style={styles.subHeader}>{t("ABOUT_SCREEN_OPEN_SOURCE")}</Text.H3>
<Text.Primary>{t("ABOUT_SCREEN_OPEN_SOURCE_BODY")}</Text.Primary>
<Text.H2 style={styles.header}>{t("ABOUT_SCREEN_LIBRARIES_AND_CONTRIBUTORS")}</Text.H2>
<View style={styles.githubView}>
<Text.Primary>{t("ABOUT_SCREEN_CAN_BE_FOUND")}</Text.Primary>
<Text.Link url="https://github.com/NMF-earth/nmf-app">{t("ABOUT_SCREEN_GITHUB")}</Text.Link>
</View>
<View style={styles.separator} />
</ScrollView>
);
};

AboutScreen.navigationOptions = navigationOptions();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

exports[`AboutScreen renders correctly 1`] = `
<ScrollView
contentContainerStyle={
{
"paddingBottom": 0,
}
}
contentInsetAdjustmentBehavior="automatic"
ref={null}
style={
{
Expand Down
1 change: 1 addition & 0 deletions app/screens/Act/ActScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const ActScreen: NavStatelessComponent = () => {
return (
<FlatList
style={styles.container}
contentInsetAdjustmentBehavior="automatic"
data={data}
renderItem={renderItem}
keyExtractor={(item) => item.title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ exports[`ActScreen renders correctly 1`] = `
"type": [Function],
}
}
contentInsetAdjustmentBehavior="automatic"
data={[]}
keyExtractor={[Function]}
ref={null}
Expand Down
8 changes: 7 additions & 1 deletion app/screens/ActDetail/ActDetailScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import HTML from "react-native-render-html";
import { HTMLImage } from "components";
import { ui } from "utils";
import { NavStatelessComponent } from "interfaces";
import { useTabBarBottomPadding } from "hooks/useTabBarBottomPadding";

import styles from "./ActDetailScreen.styles";
import navigationOptions from "./ActDetailScreen.navigationOptions";
Expand All @@ -21,9 +22,14 @@ const ActDetailScreen: NavStatelessComponent = () => {
// eslint-disable-next-line no-unsafe-optional-chaining
const { body } = route?.params;
const contentWidth = useWindowDimensions().width;
const paddingBottom = useTabBarBottomPadding();

return (
<ScrollView style={styles.container}>
<ScrollView
style={styles.container}
contentInsetAdjustmentBehavior="automatic"
contentContainerStyle={{ paddingBottom: paddingBottom }}
>
<HTML
source={{ html: body }}
contentWidth={contentWidth}
Expand Down
10 changes: 9 additions & 1 deletion app/screens/AddEmission/AddEmissionScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { pathOr } from "ramda";
import { navigate } from "navigation";
import { Text, TextInput, TextButton, OpenFoodFacts } from "components";
import { userPreferences } from "ducks";
import { useTabBarBottomPadding } from "hooks/useTabBarBottomPadding";
import {
EmissionType,
EmissionPayload,
Expand Down Expand Up @@ -291,8 +292,14 @@ const AddEmissionScreen = ({ locale = "", language = "" }: LocalizationContextPr
}
}, []);

const paddingBottom = useTabBarBottomPadding();

return (
<KeyboardAwareScrollView style={styles.container}>
<KeyboardAwareScrollView
style={styles.container}
contentInsetAdjustmentBehavior="automatic"
contentContainerStyle={{ paddingBottom: paddingBottom }}
>
{emissionType == EmissionType.productScanned && !!name && (
<View style={styles.textContainer}>
<Text.H2 style={styles.text}>{t("ADD_EMISSION_SCREEN_NAME")}</Text.H2>
Expand Down Expand Up @@ -356,6 +363,7 @@ const AddEmissionScreen = ({ locale = "", language = "" }: LocalizationContextPr
isVisible={isDatePickerVisible}
isDarkModeEnabled={isDarkModeEnabled}
mode="date"
date={creationDate.toDate()}
onConfirm={handleConfirm}
onCancel={hideDatePicker}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ exports[`AddEmissionScreen renders correctly 1`] = `
locale="en"
>
<KeyboardAwareScrollView
contentContainerStyle={
{
"paddingBottom": 0,
}
}
contentInsetAdjustmentBehavior="automatic"
style={
{
"alignContent": "flex-start",
Expand Down Expand Up @@ -56,6 +62,7 @@ exports[`AddEmissionScreen renders correctly 1`] = `
<DateTimePickerModal
cancelTextIOS="Cancel"
confirmTextIOS="Confirm"
date={2019-04-07T10:20:30.000Z}
isDarkModeEnabled={false}
isVisible={false}
locale="en_GB"
Expand Down
9 changes: 8 additions & 1 deletion app/screens/Budget/BudgetScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Button } from "components";
import { t } from "utils";
import { navigate } from "navigation";
import { NavStatelessComponent } from "interfaces";
import { useTabBarBottomPadding } from "hooks/useTabBarBottomPadding";

import styles from "./BudgetScreen.styles";
import { NumberOfDaysVegetarian, ProgressChart } from "./components";
Expand Down Expand Up @@ -49,8 +50,14 @@ const BudgetScreen: NavStatelessComponent = () => {
const customCurrentYearEmissions = useSelector(selectors.getCurrentYearCustomCarbonValue);
const totalCurrentYearEmissions = useSelector(selectors.getCurrentYearAllCarbonValue);

const paddingBottom = useTabBarBottomPadding();

return (
<ScrollView style={styles.container}>
<ScrollView
style={styles.container}
contentInsetAdjustmentBehavior="automatic"
contentContainerStyle={{ paddingBottom: paddingBottom }}
>
<ProgressChart
isMonth
totalEmissions={totalCurrentMonthEmissions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

exports[`BudgetScreen renders correctly 1`] = `
<ScrollView
contentContainerStyle={
{
"paddingBottom": 0,
}
}
contentInsetAdjustmentBehavior="automatic"
ref={null}
style={
{
Expand Down
9 changes: 8 additions & 1 deletion app/screens/CategorySelection/CategorySelectionScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { navigate } from "navigation";
import { EmissionType, NavStatelessComponent } from "interfaces";
import { Text, Tag } from "components";
import { t, ui } from "utils";
import { useTabBarBottomPadding } from "hooks/useTabBarBottomPadding";

import { categories } from "./categoryList";
import navigationOptions from "./CategorySelectionScreen.navigationOptions";
Expand All @@ -25,8 +26,14 @@ const CategorySelectionScreen: NavStatelessComponent = () => {
}
};

const paddingBottom = useTabBarBottomPadding();

return (
<ScrollView style={styles.container}>
<ScrollView
style={styles.container}
contentInsetAdjustmentBehavior="automatic"
contentContainerStyle={{ paddingBottom: paddingBottom }}
>
<Text.H2 style={styles.info}>{t("CATEGORY_SELECTION_SCREEN_SELECT_CATEGORY")}</Text.H2>
{categories.map((category, index) => (
<Tag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

exports[`CategorySelectionScreen renders correctly 1`] = `
<ScrollView
contentContainerStyle={
{
"paddingBottom": 0,
}
}
contentInsetAdjustmentBehavior="automatic"
ref={null}
style={
{
Expand Down
2 changes: 1 addition & 1 deletion app/screens/ComingSoon/ComingSoonScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import navigationOptions from "./ComingSoonScreen.navigationOptions";

const ComingSoonScreen: NavStatelessComponent = () => {
return (
<ScrollView style={styles.container}>
<ScrollView style={styles.container} contentInsetAdjustmentBehavior="automatic">
<StickersImage sticker="bike" />
<View style={styles.textView}>
<Text.Primary style={styles.paragraph}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

exports[`ComingSoonScreen renders correctly 1`] = `
<ScrollView
contentInsetAdjustmentBehavior="automatic"
ref={null}
style={
{
Expand Down
2 changes: 1 addition & 1 deletion app/screens/EmissionItem/EmissionItemScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ const EmissionItemScreen = ({ language = "" }: LocalizationContextProps) => {
}

return (
<ScrollView style={styles.container}>
<ScrollView style={styles.container} contentInsetAdjustmentBehavior="automatic">
{name.length ? (
<>
<Text.H3>{t("EMISSION_ITEM_SCREEN_NAME")}</Text.H3>
Expand Down
Loading