mirror of
https://github.com/inaturalist/iNaturalistReactNative.git
synced 2025-12-23 22:18:36 -05:00
QualityGradeStatus component, replaced QualityBadge, import svg
This commit is contained in:
@@ -1,17 +1,31 @@
|
||||
/**
|
||||
* Metro configuration for React Native
|
||||
* https://github.com/facebook/react-native
|
||||
* with added config for react-native-svg-transformer
|
||||
* https://www.npmjs.com/package/react-native-svg-transformer?activeTab
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
transformer: {
|
||||
getTransformOptions: async () => ( {
|
||||
transform: {
|
||||
experimentalImportSupport: false,
|
||||
inlineRequires: true
|
||||
}
|
||||
} )
|
||||
}
|
||||
};
|
||||
const { getDefaultConfig } = require( "metro-config" );
|
||||
|
||||
module.exports = ( async () => {
|
||||
const {
|
||||
resolver: { sourceExts, assetExts }
|
||||
} = await getDefaultConfig();
|
||||
return {
|
||||
transformer: {
|
||||
getTransformOptions: async () => ( {
|
||||
transform: {
|
||||
experimentalImportSupport: false,
|
||||
inlineRequires: true
|
||||
}
|
||||
} ),
|
||||
babelTransformerPath: require.resolve( "react-native-svg-transformer" )
|
||||
},
|
||||
resolver: {
|
||||
assetExts: assetExts.filter( ext => ext !== "svg" ),
|
||||
sourceExts: [...sourceExts, "svg"]
|
||||
}
|
||||
};
|
||||
} )();
|
||||
|
||||
1861
package-lock.json
generated
1861
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -54,6 +54,7 @@
|
||||
"linkifyjs": "^4.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"markdown-it": "^13.0.1",
|
||||
"metro-config": "^0.74.1",
|
||||
"nativewind": "^2.0.11",
|
||||
"radio-buttons-react-native": "^1.0.4",
|
||||
"react": "18.1.0",
|
||||
@@ -90,6 +91,7 @@
|
||||
"react-native-screens": "^3.18.2",
|
||||
"react-native-sensitive-info": "^6.0.0-alpha.9",
|
||||
"react-native-svg": "^12.3.0",
|
||||
"react-native-svg-transformer": "^1.0.0",
|
||||
"react-native-uuid": "^2.0.1",
|
||||
"react-native-vector-icons": "^9.1.0",
|
||||
"react-native-vision-camera": "^2.15.2",
|
||||
@@ -157,7 +159,10 @@
|
||||
],
|
||||
"automock": false,
|
||||
"resetMocks": false,
|
||||
"verbose": true
|
||||
"verbose": true,
|
||||
"moduleNameMapper": {
|
||||
"\\.svg": "<rootDir>/tests/mocks/svgMock.js"
|
||||
}
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// @flow
|
||||
|
||||
import { useNavigation, useRoute } from "@react-navigation/native";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { createComment } from "api/comments";
|
||||
@@ -7,7 +6,7 @@ import {
|
||||
faveObservation, fetchRemoteObservation, markObservationUpdatesViewed, unfaveObservation
|
||||
} from "api/observations";
|
||||
import PhotoScroll from "components/SharedComponents/PhotoScroll";
|
||||
import QualityBadge from "components/SharedComponents/QualityBadge";
|
||||
import QualityGradeStatus from "components/SharedComponents/QualityGradeStatus";
|
||||
import ScrollWithFooter from "components/SharedComponents/ScrollWithFooter";
|
||||
import Tabs from "components/SharedComponents/Tabs";
|
||||
import UserIcon from "components/SharedComponents/UserIcon";
|
||||
@@ -362,8 +361,9 @@ const ObsDetails = ( ): Node => {
|
||||
/>
|
||||
<Text className="ml-1">{observation.comments.length}</Text>
|
||||
</View>
|
||||
<QualityBadge
|
||||
<QualityGradeStatus
|
||||
qualityGrade={checkCamelAndSnakeCase( observation, "qualityGrade" )}
|
||||
color={colors.darkGray}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @flow
|
||||
|
||||
import checkCamelAndSnakeCase from "components/ObsDetails/helpers/checkCamelAndSnakeCase";
|
||||
import QualityGradeStatus from "components/SharedComponents/QualityGradeStatus";
|
||||
import { Text, View } from "components/styledComponents";
|
||||
import { t } from "i18next";
|
||||
import type { Node } from "react";
|
||||
import React from "react";
|
||||
import Icon from "react-native-vector-icons/MaterialIcons";
|
||||
@@ -29,12 +29,6 @@ const ObsCardStats = ( { item, type, view }: Props ): Node => {
|
||||
return colors.black;
|
||||
};
|
||||
|
||||
const qualityGradeText = {
|
||||
needs_id: t( "NI" ),
|
||||
research: t( "RG" ),
|
||||
casual: t( "C" )
|
||||
};
|
||||
|
||||
const renderIdRow = ( ) => (
|
||||
<View className="flex-row items-center mr-3">
|
||||
<Icon name="shield" color={setIconColor( )} size={14} />
|
||||
@@ -56,9 +50,7 @@ const ObsCardStats = ( { item, type, view }: Props ): Node => {
|
||||
);
|
||||
|
||||
const renderQualityGrade = ( ) => (
|
||||
<Text style={{ color: setIconColor( ) }}>
|
||||
{qualityGrade ? qualityGradeText[qualityGrade] : "?"}
|
||||
</Text>
|
||||
<QualityGradeStatus qualityGrade={qualityGrade} color={setIconColor( )} />
|
||||
);
|
||||
|
||||
const renderColumn = ( ) => (
|
||||
|
||||
33
src/components/SharedComponents/QualityGradeStatus.js
Normal file
33
src/components/SharedComponents/QualityGradeStatus.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// @flow
|
||||
import { View } from "components/styledComponents";
|
||||
import CasualGrade from "images/svg/casualGrade.svg";
|
||||
import NeedsIdGrade from "images/svg/needsIdGrade.svg";
|
||||
import ResearchGrade from "images/svg/researchGrade.svg";
|
||||
import * as React from "react";
|
||||
|
||||
type Props = {
|
||||
qualityGrade: ?string,
|
||||
color: boolean
|
||||
}
|
||||
|
||||
const qualityGradeSVG = ( qualityGrade, color ) => {
|
||||
if ( qualityGrade === "research" ) {
|
||||
// $FlowIgnore
|
||||
return <ResearchGrade color={color} />;
|
||||
}
|
||||
if ( qualityGrade === "needs_id" ) {
|
||||
// $FlowIgnore
|
||||
return <NeedsIdGrade color={color} />;
|
||||
}
|
||||
// $FlowIgnore
|
||||
return <CasualGrade color={color} />;
|
||||
};
|
||||
|
||||
const QualityGradeStatus = ( { qualityGrade, color }: Props ): React.Node => (
|
||||
<View>
|
||||
{ qualityGradeSVG( qualityGrade, color )}
|
||||
</View>
|
||||
|
||||
);
|
||||
|
||||
export default QualityGradeStatus;
|
||||
@@ -10,6 +10,7 @@ import AddObsButton from "./SharedComponents/Buttons/AddObsButton";
|
||||
import Button from "./SharedComponents/Buttons/Button";
|
||||
import EvidenceButton from "./SharedComponents/Buttons/EvidenceButton";
|
||||
import SecondaryCTAButton from "./SharedComponents/Buttons/SecondaryCTAButton";
|
||||
import QualityGradeStatus from "./SharedComponents/QualityGradeStatus";
|
||||
import ViewWithFooter from "./SharedComponents/ViewWithFooter";
|
||||
|
||||
/* eslint-disable i18next/no-literal-string */
|
||||
@@ -96,6 +97,33 @@ const UiLibrary = ( ) => (
|
||||
<Text>Disabled SecondaryCTAButton</Text>
|
||||
</SecondaryCTAButton>
|
||||
|
||||
<Text className="text-lg">Quality Grade Status</Text>
|
||||
<View className="flex flex-row justify-between">
|
||||
<View>
|
||||
<Text className="text-center">Research</Text>
|
||||
<QualityGradeStatus qualityGrade="research" color="black" />
|
||||
</View>
|
||||
<View>
|
||||
<Text className="text-center">Needs Id</Text>
|
||||
<QualityGradeStatus qualityGrade="needs_id" color="black" />
|
||||
</View>
|
||||
<View>
|
||||
<Text className="text-center">Casual</Text>
|
||||
<QualityGradeStatus qualityGrade="casual" color="black" />
|
||||
</View>
|
||||
</View>
|
||||
<View className="flex flex-row justify-between">
|
||||
<View>
|
||||
<QualityGradeStatus qualityGrade="research" color="green" />
|
||||
</View>
|
||||
<View>
|
||||
<QualityGradeStatus qualityGrade="needs_id" color="green" />
|
||||
</View>
|
||||
<View>
|
||||
<QualityGradeStatus qualityGrade="casual" color="green" />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<Text className="text-lg">More Stuff!</Text>
|
||||
<Text className="h-[100px]">
|
||||
Useless spacer at the end because height in NativeWind is confusing.
|
||||
|
||||
5
src/images/svg/casualGrade.svg
Normal file
5
src/images/svg/casualGrade.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="51" height="21" viewBox="0 0 51 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 2C1 1.44771 1.44772 1 2 1H39C39 1 39 1 39 1C39 1 50 1 50 10.5C50 20 39 20 39 20C39 20 39 20 39 20H2C1.44772 20 1 19.5523 1 19V2Z" stroke="currentColor"/>
|
||||
<circle cx="22" cy="9" r="4" stroke="currentColor"/>
|
||||
<path d="M29 20C29 16.134 25.866 13 22 13C18.134 13 15 16.134 15 20" stroke="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 455 B |
9
src/images/svg/needsIdGrade.svg
Normal file
9
src/images/svg/needsIdGrade.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg width="51" height="21" viewBox="0 0 51 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 2C1 1.44771 1.44772 1 2 1H40.3325C40.6025 1 40.8609 1.10912 41.0492 1.30257L49.3213 9.80257C49.6991 10.1908 49.6991 10.8092 49.3213 11.1974L41.0492 19.6974C40.8609 19.8909 40.6025 20 40.3325 20H2C1.44771 20 1 19.5523 1 19V2Z" stroke="currentColor"/>
|
||||
<line x1="34" y1="7.5" x2="34" y2="13.5" stroke="currentColor" stroke-linecap="round"/>
|
||||
<line x1="31" y1="10.5" x2="37" y2="10.5" stroke="currentColor" stroke-linecap="round"/>
|
||||
<circle cx="12" cy="9" r="4" stroke="currentColor" stroke-linecap="round" stroke-dasharray="0.01 2"/>
|
||||
<circle cx="22" cy="9" r="4" stroke="currentColor"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9949 13.5C11.7187 13.5002 11.4947 13.2765 11.4945 13.0004C11.4943 12.7242 11.718 12.5002 11.9941 12.5L12.005 12.5C12.2811 12.5002 12.5048 12.7242 12.5046 13.0003C12.5045 13.2765 12.2805 13.5002 12.0043 13.5L11.9949 13.5ZM15.1064 13.7053C15.2461 13.4672 15.5525 13.3874 15.7907 13.5272L15.7992 13.5322C16.0372 13.6722 16.1166 13.9787 15.9765 14.2167C15.8364 14.4547 15.5299 14.534 15.292 14.394L15.2846 14.3896C15.0464 14.2499 14.9666 13.9435 15.1064 13.7053ZM8.29419 14.0393C8.45651 14.2627 8.407 14.5754 8.1836 14.7377L8.17538 14.7437C7.95224 14.9064 7.63948 14.8573 7.47681 14.6342C7.31414 14.411 7.36317 14.0983 7.58632 13.9356L7.59579 13.9287C7.81919 13.7664 8.13187 13.8159 8.29419 14.0393ZM16.6466 14.7408C16.8437 14.5474 17.1603 14.5504 17.3537 14.7475L17.3571 14.7511C17.5504 14.9483 17.5472 15.2649 17.3499 15.4581C17.1527 15.6514 16.8362 15.6482 16.6429 15.451L16.6399 15.4479C16.4465 15.2508 16.4495 14.9342 16.6466 14.7408ZM6.63419 15.4768C6.85734 15.6395 6.90637 15.9522 6.7437 16.1754L6.73772 16.1836C6.5754 16.407 6.26272 16.4565 6.03932 16.2942C5.81592 16.1319 5.7664 15.8192 5.92872 15.5958L5.93562 15.5863C6.09829 15.3632 6.41105 15.3141 6.63419 15.4768ZM5.49736 17.3555C5.75993 17.441 5.90348 17.7231 5.81799 17.9857L5.81485 17.9954C5.72977 18.2581 5.44783 18.4021 5.18512 18.317C4.92242 18.2319 4.77842 17.95 4.8635 17.6873L4.86712 17.6761C4.95262 17.4135 5.23478 17.27 5.49736 17.3555ZM5.00039 19.4945C5.27653 19.4947 5.50021 19.7187 5.5 19.9949L5.5 20C5.5 20.2761 5.27614 20.5 5 20.5C4.72386 20.5 4.5 20.2761 4.5 20L4.5 19.9941C4.50021 19.718 4.72424 19.4943 5.00039 19.4945Z" fill="#454545"/>
|
||||
<path d="M29 20C29 16.134 25.866 13 22 13C18.134 13 15 16.134 15 20" stroke="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
8
src/images/svg/researchGrade.svg
Normal file
8
src/images/svg/researchGrade.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg width="51" height="21" viewBox="0 0 51 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 2C1 1.44771 1.44772 1 2 1H48.6314C49.5158 1 49.9649 2.06365 49.3481 2.69743L42.4335 9.80257C42.0557 10.1908 42.0557 10.8092 42.4335 11.1974L49.3481 18.3026C49.9649 18.9363 49.5158 20 48.6314 20H2C1.44771 20 1 19.5523 1 19V2Z" stroke="currentColor"/>
|
||||
<path d="M32.939 12.2199L31.3279 10.5958C31.0827 10.3486 30.6831 10.3486 30.4379 10.5958C30.1955 10.8402 30.1955 11.2343 30.4379 11.4787L32.2291 13.2843C32.6202 13.6786 33.2578 13.6786 33.649 13.2843L38.5621 8.33146C38.8045 8.08709 38.8045 7.69296 38.5621 7.4486C38.3169 7.20143 37.9173 7.20143 37.6721 7.4486L32.939 12.2199Z" fill="#454545"/>
|
||||
<circle cx="12" cy="9" r="4" stroke="currentColor"/>
|
||||
<circle cx="22" cy="9" r="4" stroke="currentColor"/>
|
||||
<path d="M5 20C5 16.134 8.13401 13 12 13C13.9587 13 15.7295 13.8045 17 15.101" stroke="currentColor"/>
|
||||
<path d="M29 20C29 16.134 25.866 13 22 13C18.134 13 15 16.134 15 20" stroke="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
9
src/types/declarations.d.ts
vendored
Normal file
9
src/types/declarations.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// Using typescript with react-native-svg-transformer
|
||||
// from https://www.npmjs.com/package/react-native-svg-transformer?activeTab
|
||||
|
||||
declare module "*.svg" {
|
||||
import React from 'react';
|
||||
import { SvgProps } from "react-native-svg";
|
||||
const content: React.FC<SvgProps>;
|
||||
export default content;
|
||||
}
|
||||
2
tests/mocks/svgMock.js
Normal file
2
tests/mocks/svgMock.js
Normal file
@@ -0,0 +1,2 @@
|
||||
module.exports = "SvgMock";
|
||||
module.exports.ReactComponent = "SvgMock";
|
||||
@@ -1,6 +1,5 @@
|
||||
import { fireEvent, render } from "@testing-library/react-native";
|
||||
import ObsCard from "components/Observations/ObsCard";
|
||||
import { t } from "i18next";
|
||||
import React from "react";
|
||||
|
||||
import factory from "../../../factory";
|
||||
@@ -9,12 +8,11 @@ const testObservation = factory( "LocalObservation", {
|
||||
taxon: { preferred_common_name: "Foo", name: "bar" }
|
||||
} );
|
||||
|
||||
const qualityGradeText = t( "RG" );
|
||||
|
||||
test( "renders text passed into observation card", ( ) => {
|
||||
const { getByTestId, getByText } = render(
|
||||
<ObsCard
|
||||
item={testObservation}
|
||||
handlePress={( ) => jest.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -27,7 +25,7 @@ test( "renders text passed into observation card", ( ) => {
|
||||
expect( getByText( testObservation.placeGuess ) ).toBeTruthy( );
|
||||
expect( getByText( testObservation.comments.length.toString( ) ) ).toBeTruthy( );
|
||||
expect( getByText( testObservation.identifications.length.toString( ) ) ).toBeTruthy( );
|
||||
expect( getByText( qualityGradeText ) ).toBeTruthy( );
|
||||
// add grade tests
|
||||
} );
|
||||
|
||||
test( "navigates to ObsDetails on button press", ( ) => {
|
||||
@@ -49,7 +47,12 @@ test( "navigates to ObsDetails on button press", ( ) => {
|
||||
} );
|
||||
|
||||
test( "should not have accessibility errors", ( ) => {
|
||||
const obsCard = <ObsCard item={testObservation} />;
|
||||
const obsCard = (
|
||||
<ObsCard
|
||||
item={testObservation}
|
||||
handlePress={( ) => jest.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
expect( obsCard ).toBeAccessible( );
|
||||
} );
|
||||
|
||||
Reference in New Issue
Block a user