diff --git a/package-lock.json b/package-lock.json
index 920242dcc..53ec1ed30 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,6 +16,7 @@
"react-native": "0.65.1",
"react-native-gesture-handler": "^1.10.3",
"react-native-maps": "^0.29.3",
+ "react-native-modal": "^13.0.0",
"react-native-reanimated": "^2.2.2",
"react-native-safe-area-context": "^3.3.2",
"react-native-screens": "^3.8.0",
@@ -12643,6 +12644,14 @@
"react-native": "*"
}
},
+ "node_modules/react-native-animatable": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/react-native-animatable/-/react-native-animatable-1.3.3.tgz",
+ "integrity": "sha512-2ckIxZQAsvWn25Ho+DK3d1mXIgj7tITkrS4pYDvx96WyOttSvzzFeQnM2od0+FUMzILbdHDsDEqZvnz1DYNQ1w==",
+ "dependencies": {
+ "prop-types": "^15.7.2"
+ }
+ },
"node_modules/react-native-clean-project": {
"version": "3.6.7",
"resolved": "https://registry.npmjs.org/react-native-clean-project/-/react-native-clean-project-3.6.7.tgz",
@@ -12691,6 +12700,19 @@
"react-native-web": "^0.13"
}
},
+ "node_modules/react-native-modal": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/react-native-modal/-/react-native-modal-13.0.0.tgz",
+ "integrity": "sha512-k6r9T31mc7HIDFj1V53ceAAN1dwc8052c4JLtDVEmEQ19Bbq9yiLXoDsQuNb+hB8A+2tVOXmo5Gq4IQfb11upw==",
+ "dependencies": {
+ "prop-types": "^15.6.2",
+ "react-native-animatable": "1.3.3"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-native": ">=0.65.0"
+ }
+ },
"node_modules/react-native-reanimated": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.2.3.tgz",
@@ -25287,6 +25309,14 @@
"react-test-renderer": "^17.0.1"
}
},
+ "react-native-animatable": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/react-native-animatable/-/react-native-animatable-1.3.3.tgz",
+ "integrity": "sha512-2ckIxZQAsvWn25Ho+DK3d1mXIgj7tITkrS4pYDvx96WyOttSvzzFeQnM2od0+FUMzILbdHDsDEqZvnz1DYNQ1w==",
+ "requires": {
+ "prop-types": "^15.7.2"
+ }
+ },
"react-native-clean-project": {
"version": "3.6.7",
"resolved": "https://registry.npmjs.org/react-native-clean-project/-/react-native-clean-project-3.6.7.tgz",
@@ -25324,6 +25354,15 @@
"@types/geojson": "^7946.0.7"
}
},
+ "react-native-modal": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/react-native-modal/-/react-native-modal-13.0.0.tgz",
+ "integrity": "sha512-k6r9T31mc7HIDFj1V53ceAAN1dwc8052c4JLtDVEmEQ19Bbq9yiLXoDsQuNb+hB8A+2tVOXmo5Gq4IQfb11upw==",
+ "requires": {
+ "prop-types": "^15.6.2",
+ "react-native-animatable": "1.3.3"
+ }
+ },
"react-native-reanimated": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.2.3.tgz",
diff --git a/package.json b/package.json
index 41ecf58f0..878fc6f82 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"react-native": "0.65.1",
"react-native-gesture-handler": "^1.10.3",
"react-native-maps": "^0.29.3",
+ "react-native-modal": "^13.0.0",
"react-native-reanimated": "^2.2.2",
"react-native-safe-area-context": "^3.3.2",
"react-native-screens": "^3.8.0",
diff --git a/src/components/Camera/CameraOptionsModal.js b/src/components/Camera/CameraOptionsModal.js
new file mode 100644
index 000000000..e54a1f18b
--- /dev/null
+++ b/src/components/Camera/CameraOptionsModal.js
@@ -0,0 +1,17 @@
+// @flow
+
+import * as React from "react";
+import { Text, View } from "react-native";
+
+import { textStyles } from "../../styles/sharedComponents/modal";
+
+const CameraOptionsModal = ( ): React.Node => (
+
+ take photo with camera
+ upload photo from gallery
+ record a sound
+ submit without evidence
+
+);
+
+export default CameraOptionsModal;
diff --git a/src/components/Observations/ObsListRightHeader.js b/src/components/Observations/ObsListRightHeader.js
new file mode 100644
index 000000000..8baada576
--- /dev/null
+++ b/src/components/Observations/ObsListRightHeader.js
@@ -0,0 +1,14 @@
+// @flow
+
+import * as React from "react";
+import { Text, Pressable } from "react-native";
+
+import { viewStyles } from "../../styles/observations/obsListRightHeader";
+
+const ObsListRightHeader = ( ): React.Node => (
+ console.log( "navigate to messages" )} style={viewStyles.messages}>
+ messages
+
+);
+
+export default ObsListRightHeader;
diff --git a/src/components/SharedComponents/Footer.js b/src/components/SharedComponents/Footer.js
index a0cb95ae2..480d4f3db 100644
--- a/src/components/SharedComponents/Footer.js
+++ b/src/components/SharedComponents/Footer.js
@@ -5,30 +5,45 @@ import { Pressable, Text, View } from "react-native";
import { useNavigation } from "@react-navigation/native";
import { viewStyles } from "../../styles/sharedComponents/footer";
+import CameraOptionsModal from "../Camera/CameraOptionsModal";
+import Modal from "./Modal";
const Footer = ( ): React.Node => {
+ const [showModal, setModal] = React.useState( false );
+
+ const openModal = React.useCallback( ( ) => setModal( true ), [] );
+ const closeModal = React.useCallback( ( ) => setModal( false ), [] );
+
const navigation = useNavigation( );
const toggleSideMenu = ( ) => navigation.openDrawer( );
const navToObsList = ( ) => navigation.navigate( "my observations" );
+ const navToCameraOptions = ( ) => openModal( );
return (
-
-
- menu
-
-
- explore
-
-
- camera
-
-
- obs list
-
-
- notifications
-
-
+ <>
+ }
+ />
+
+
+ menu
+
+
+ explore
+
+
+ camera
+
+
+ obs list
+
+
+ notifications
+
+
+ >
);
};
diff --git a/src/components/SharedComponents/Modal.js b/src/components/SharedComponents/Modal.js
new file mode 100644
index 000000000..490f23fd3
--- /dev/null
+++ b/src/components/SharedComponents/Modal.js
@@ -0,0 +1,29 @@
+// @flow
+import * as React from "react";
+import RNModal from "react-native-modal";
+
+// repurposed from Seek: https://github.com/inaturalist/SeekReactNative/blob/main/components/UIComponents/Modals/Modal.js
+
+type Props = {
+ showModal: boolean,
+ closeModal: Function,
+ modal: any
+}
+
+// accessibility might not work on Android because of backdrop
+// https://github.com/react-native-modal/react-native-modal/issues/525
+
+const Modal = ( { showModal, closeModal, modal }: Props ): React.Node => (
+
+ {modal}
+
+);
+
+export default Modal;
diff --git a/src/navigation/drawerNavigation.js b/src/navigation/drawerNavigation.js
index 481469ef1..dd7a0b19b 100644
--- a/src/navigation/drawerNavigation.js
+++ b/src/navigation/drawerNavigation.js
@@ -5,6 +5,7 @@ import { createDrawerNavigator } from "@react-navigation/drawer";
import ObsList from "../components/Observations/ObsList";
import PlaceholderComponent from "../components/PlaceholderComponent";
+import ObsListRightHeader from "../components/Observations/ObsListRightHeader";
// this removes the default hamburger menu from header
const screenOptions = { headerLeft: ( ) => <>> };
@@ -13,7 +14,13 @@ const Drawer = createDrawerNavigator();
const DrawerNavigator = ( ): React.Node => (
-
+ ( {
+ headerRight: ( ) =>
+ } )}
+ />
diff --git a/src/styles/observations/obsListRightHeader.js b/src/styles/observations/obsListRightHeader.js
new file mode 100644
index 000000000..478ae633a
--- /dev/null
+++ b/src/styles/observations/obsListRightHeader.js
@@ -0,0 +1,15 @@
+// @flow strict-local
+
+import { StyleSheet } from "react-native";
+
+import type { ViewStyleProp } from "react-native/Libraries/StyleSheet/StyleSheet";
+
+const viewStyles: { [string]: ViewStyleProp } = StyleSheet.create( {
+ messages: {
+ marginRight: 20
+ }
+} );
+
+export {
+ viewStyles
+};
diff --git a/src/styles/sharedComponents/modal.js b/src/styles/sharedComponents/modal.js
new file mode 100644
index 000000000..83af92734
--- /dev/null
+++ b/src/styles/sharedComponents/modal.js
@@ -0,0 +1,17 @@
+// @flow strict-local
+
+import { StyleSheet } from "react-native";
+
+import type { TextStyleProp } from "react-native/Libraries/StyleSheet/StyleSheet";
+import { colors } from "../global";
+
+const textStyles: { [string]: TextStyleProp } = StyleSheet.create( {
+ whiteText: {
+ color: colors.white,
+ marginVertical: 10
+ }
+} );
+
+export {
+ textStyles
+};