mirror of
https://github.com/inaturalist/iNaturalistReactNative.git
synced 2025-12-23 22:18:36 -05:00
Create a hook to fetch a particular user's observations; add basic styling to obs cards
This commit is contained in:
45
components/Observations/ObsCard.js
Normal file
45
components/Observations/ObsCard.js
Normal file
@@ -0,0 +1,45 @@
|
||||
// @flow strict-local
|
||||
|
||||
import React from "react";
|
||||
import { Pressable, Text, View, Image } from "react-native";
|
||||
import type { Node } from "react";
|
||||
|
||||
import { viewStyles, textStyles } from "../../styles/observations/obsCard";
|
||||
|
||||
type Props = {
|
||||
item: {
|
||||
uuid: string,
|
||||
userPhoto: string,
|
||||
commonName: string,
|
||||
location: string,
|
||||
timeObservedAt: string,
|
||||
identifications: number,
|
||||
comments: number,
|
||||
qualityGrade: string
|
||||
}
|
||||
}
|
||||
|
||||
const ObsCard = ( { item }: Props ): Node => {
|
||||
const handlePress = ( ) => console.log( "obs card was pressed" );
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
onPress={handlePress}
|
||||
style={viewStyles.row}
|
||||
>
|
||||
<Image source={{ uri: item.userPhoto }} style={viewStyles.imageBackground} />
|
||||
<View style={viewStyles.obsDetailsColumn}>
|
||||
<Text style={textStyles.text}>{item.commonName}</Text>
|
||||
<Text style={textStyles.text}>{item.location}</Text>
|
||||
<Text style={textStyles.text}>{item.timeObservedAt}</Text>
|
||||
</View>
|
||||
<View>
|
||||
<Text style={textStyles.text}>{item.identifications}</Text>
|
||||
<Text style={textStyles.text}>{item.comments}</Text>
|
||||
<Text style={textStyles.text}>{item.qualityGrade}</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
);
|
||||
};
|
||||
|
||||
export default ObsCard;
|
||||
27
components/Observations/ObservationsList.js
Normal file
27
components/Observations/ObservationsList.js
Normal file
@@ -0,0 +1,27 @@
|
||||
// @flow strict-local
|
||||
|
||||
import React from "react";
|
||||
import { FlatList } from "react-native";
|
||||
import type { Node } from "react";
|
||||
|
||||
import ObsCard from "./ObsCard";
|
||||
import viewStyles from "../../styles/observations/observationsList";
|
||||
import useFetchObservations from "../hooks/fetchObservations";
|
||||
|
||||
const ObservationsList = ( ): Node => {
|
||||
const observations = useFetchObservations( );
|
||||
|
||||
const extractKey = item => item.uuid;
|
||||
const renderItem = ( { item } ) => <ObsCard item={item} />;
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
contentContainerStyle={viewStyles.background}
|
||||
data={observations}
|
||||
keyExtractor={extractKey}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ObservationsList;
|
||||
40
components/hooks/fetchObservations.js
Normal file
40
components/hooks/fetchObservations.js
Normal file
@@ -0,0 +1,40 @@
|
||||
// @flow strict-local
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import inatjs from "inaturalistjs";
|
||||
|
||||
const useFetchObservations = ( ): any => {
|
||||
const [observations, setObservations] = useState( [] );
|
||||
|
||||
useEffect( ( ) => {
|
||||
const fetchObservations = async ( ) => {
|
||||
try {
|
||||
const testUser = "albulltest";
|
||||
const params = { user_login: testUser };
|
||||
const response = await inatjs.observations.search( params );
|
||||
const userObservations = response.results;
|
||||
|
||||
const onlyNecessaryObsDetails = userObservations.map( ( obs => {
|
||||
return {
|
||||
uuid: obs.uuid,
|
||||
userPhoto: obs.taxon.default_photo.square_url,
|
||||
commonName: obs.taxon.preferred_common_name || obs.taxon.name,
|
||||
location: obs.place_guess || obs.location,
|
||||
timeObservedAt: obs.time_observed_at,
|
||||
identifications: obs.identifications_count,
|
||||
comments: obs.comments.length,
|
||||
qualityGrade: obs.quality_grade
|
||||
};
|
||||
} ) );
|
||||
setObservations( onlyNecessaryObsDetails );
|
||||
} catch ( e ) {
|
||||
console.log( e, JSON.stringify( e ), "couldn't fetch observations" );
|
||||
}
|
||||
};
|
||||
fetchObservations( );
|
||||
}, [] );
|
||||
|
||||
return observations;
|
||||
};
|
||||
|
||||
export default useFetchObservations;
|
||||
4
index.js
4
index.js
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import {AppRegistry} from "react-native";
|
||||
import App from "./App";
|
||||
import ObsList from "./components/Observations/ObservationsList";
|
||||
import {name as appName} from "./app.json";
|
||||
|
||||
AppRegistry.registerComponent( appName, () => App );
|
||||
AppRegistry.registerComponent( appName, () => ObsList );
|
||||
|
||||
@@ -114,7 +114,6 @@
|
||||
AA97B3DCA18D747D9E7F0358 /* Pods-iNaturalistReactNative-iNaturalistReactNativeTests.debug.xcconfig */,
|
||||
ACD831F90866E862C17F1AD1 /* Pods-iNaturalistReactNative-iNaturalistReactNativeTests.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -263,7 +262,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||
shellScript = "export NODE_BINARY=/Users/amanda/.nvm/versions/node/v12.13.0/bin/node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||
};
|
||||
010B3221A1D8DF0722FE9DE2 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@@ -485,6 +484,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = N5J7L4P93Z;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = iNaturalistReactNative/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -511,6 +511,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = N5J7L4P93Z;
|
||||
INFOPLIST_FILE = iNaturalistReactNative/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
||||
94
package-lock.json
generated
94
package-lock.json
generated
@@ -8,6 +8,7 @@
|
||||
"name": "inaturalistreactnative",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"inaturalistjs": "github:inaturalist/inaturalistjs",
|
||||
"react": "17.0.2",
|
||||
"react-native": "0.65.1"
|
||||
},
|
||||
@@ -25,6 +26,7 @@
|
||||
"eslint-plugin-react": "^7.25.1",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-react-native": "^3.11.0",
|
||||
"flow-bin": "^0.149.0",
|
||||
"jest": "^26.6.3",
|
||||
"metro-react-native-babel-preset": "^0.66.0",
|
||||
"react-native-codegen": "^0.0.7",
|
||||
@@ -4376,8 +4378,7 @@
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"node_modules/atob": {
|
||||
"version": "2.1.2",
|
||||
@@ -5128,7 +5129,6 @@
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
@@ -5305,6 +5305,28 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch": {
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.5.tgz",
|
||||
"integrity": "sha512-xqYAhQb4NhCJSRym03dwxpP1bYXpK3y7UN83Bo2WFi3x1Zmzn0SL/6xGoPr+gpt4WmNrgCCX3HPysvOwFOW36w==",
|
||||
"dependencies": {
|
||||
"node-fetch": "2.6.1",
|
||||
"whatwg-fetch": "2.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch/node_modules/node-fetch": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch/node_modules/whatwg-fetch": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
|
||||
"integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng=="
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
@@ -5450,7 +5472,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
@@ -6843,6 +6864,18 @@
|
||||
"integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/flow-bin": {
|
||||
"version": "0.149.0",
|
||||
"resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.149.0.tgz",
|
||||
"integrity": "sha512-32hM6iKSInPCUuooS23SJ4c5Up0Tt9ozrXEE6urEpTDJU0z/vQblnCBRt3QZaEEDzSKOu2QZAU6K7fbShOOHaQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"flow": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/flow-parser": {
|
||||
"version": "0.121.0",
|
||||
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz",
|
||||
@@ -6864,7 +6897,6 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
|
||||
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
@@ -7399,6 +7431,15 @@
|
||||
"node": ">=0.8.19"
|
||||
}
|
||||
},
|
||||
"node_modules/inaturalistjs": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "git+ssh://git@github.com/inaturalist/inaturalistjs.git#b60365d9b49c68f77e684b0d79c49933a88117cb",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cross-fetch": "^2.2.3",
|
||||
"form-data": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
@@ -17139,8 +17180,7 @@
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"atob": {
|
||||
"version": "2.1.2",
|
||||
@@ -17716,7 +17756,6 @@
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
@@ -17870,6 +17909,27 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"cross-fetch": {
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.5.tgz",
|
||||
"integrity": "sha512-xqYAhQb4NhCJSRym03dwxpP1bYXpK3y7UN83Bo2WFi3x1Zmzn0SL/6xGoPr+gpt4WmNrgCCX3HPysvOwFOW36w==",
|
||||
"requires": {
|
||||
"node-fetch": "2.6.1",
|
||||
"whatwg-fetch": "2.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-fetch": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
||||
},
|
||||
"whatwg-fetch": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
|
||||
"integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
@@ -17984,8 +18044,7 @@
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"denodeify": {
|
||||
"version": "1.2.1",
|
||||
@@ -19032,6 +19091,12 @@
|
||||
"integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
|
||||
"dev": true
|
||||
},
|
||||
"flow-bin": {
|
||||
"version": "0.149.0",
|
||||
"resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.149.0.tgz",
|
||||
"integrity": "sha512-32hM6iKSInPCUuooS23SJ4c5Up0Tt9ozrXEE6urEpTDJU0z/vQblnCBRt3QZaEEDzSKOu2QZAU6K7fbShOOHaQ==",
|
||||
"dev": true
|
||||
},
|
||||
"flow-parser": {
|
||||
"version": "0.121.0",
|
||||
"resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz",
|
||||
@@ -19047,7 +19112,6 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
|
||||
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
@@ -19435,6 +19499,14 @@
|
||||
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
|
||||
"dev": true
|
||||
},
|
||||
"inaturalistjs": {
|
||||
"version": "git+ssh://git@github.com/inaturalist/inaturalistjs.git#b60365d9b49c68f77e684b0d79c49933a88117cb",
|
||||
"from": "inaturalistjs@github:inaturalist/inaturalistjs",
|
||||
"requires": {
|
||||
"cross-fetch": "^2.2.3",
|
||||
"form-data": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"lint": "eslint ."
|
||||
},
|
||||
"dependencies": {
|
||||
"inaturalistjs": "github:inaturalist/inaturalistjs",
|
||||
"react": "17.0.2",
|
||||
"react-native": "0.65.1"
|
||||
},
|
||||
@@ -27,6 +28,7 @@
|
||||
"eslint-plugin-react": "^7.25.1",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-react-native": "^3.11.0",
|
||||
"flow-bin": "^0.149.0",
|
||||
"jest": "^26.6.3",
|
||||
"metro-react-native-babel-preset": "^0.66.0",
|
||||
"react-native-codegen": "^0.0.7",
|
||||
|
||||
6
styles/global.js
Normal file
6
styles/global.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// @flow strict-local
|
||||
|
||||
export const colors = {
|
||||
white: "#ffffff",
|
||||
black: "#000000"
|
||||
};
|
||||
33
styles/observations/obsCard.js
Normal file
33
styles/observations/obsCard.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// @flow strict-local
|
||||
|
||||
import { StyleSheet } from "react-native";
|
||||
|
||||
import type { ViewStyleProp, TextStyleProp } from "react-native/Libraries/StyleSheet/StyleSheet";
|
||||
import { colors } from "../global";
|
||||
|
||||
const viewStyles: { [string]: ViewStyleProp } = StyleSheet.create( {
|
||||
imageBackground: {
|
||||
width: 75,
|
||||
height: 75,
|
||||
borderRadius: 10,
|
||||
backgroundColor: colors.black,
|
||||
marginHorizontal: 20
|
||||
},
|
||||
obsDetailsColumn: {
|
||||
width: 200
|
||||
},
|
||||
row: {
|
||||
flexDirection: "row",
|
||||
flexWrap: "nowrap",
|
||||
marginVertical: 10
|
||||
}
|
||||
} );
|
||||
|
||||
const textStyles: { [string]: TextStyleProp } = StyleSheet.create( {
|
||||
text: { }
|
||||
} );
|
||||
|
||||
export {
|
||||
viewStyles,
|
||||
textStyles
|
||||
};
|
||||
15
styles/observations/observationsList.js
Normal file
15
styles/observations/observationsList.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// @flow strict-local
|
||||
|
||||
import { StyleSheet } from "react-native";
|
||||
import { colors } from "../global";
|
||||
|
||||
import type { ViewStyleProp } from "react-native/Libraries/StyleSheet/StyleSheet";
|
||||
|
||||
const viewStyles: { [string]: ViewStyleProp } = StyleSheet.create( {
|
||||
background: {
|
||||
backgroundColor: colors.white,
|
||||
flex: 1
|
||||
}
|
||||
} );
|
||||
|
||||
export default viewStyles;
|
||||
Reference in New Issue
Block a user