* Added basic navigation test for StandardCamera & SoundRecorder
* Abstracted camera nav buttons and used in SoundRecorder
* Show sounds in the MediaViewer
* Added sounds to ObsEdit, w/ MediaViewer support
* Ensure sounds get both uploaded and added to observations
* Local sound deletion
* Remote sound deletion
* Rudimentary and deeply unperformative sound visualization
Closes#869
* Changed the default React Query retry handler to be synchronous; being async
meant it returned a promise, which React Query interpreted as true-ish,
which meant it retried forever
* React Query retry handler should log info about its query key, which should
make those problems a bit easier to debug given a log
* Prevent useObservationUpdates from throwing errors when network requests
fail, which they always do while offline
* Added our own ErrorBoundary that shows a component trace
* Prevent several uses of useAuthenticatedRequest when not online
* Work around bug in vision-camera-plugin-inatvision where it can't get
dimensions of photos in Android
* Actually throw errors when vision-camera-plugin-inatvision's predictImage
throws unexpected errors
* Allow online suggestions while signed out using anonymous JWT
* Restored Suggestions navigation tests
* Restored SuggestionsWithSyncedObs.test.js tests
* Mocked vision-camera-plugin-inatvision instead of useOfflineSuggestions
* Removed unnecessarily complex object from navigation params
There were a lot of issues here, but the main ones (I think) were related to
rendering all the navigators and waiting for asynchronous stuff to happen
before proceeding with the test.
* Use different plugin branch
* Predict taxa for local image url in suggestions screen
WIP: This is working on iOS. On Android there is a crash. The pexample app in the plugin repository works on Android, so I assume the crash is happening because of some things here. Maybe the wrong url is passed in.
Anyway, I am only adding prediction for the local image and haven't wired up the results to state or UI.
* Use latest plugin commit
* Refactor cv model version to be imported from helper
* Refactor image prediction function call into helper module
* Mock for new vision plugin function
Fixes#907. Also adds an ObsEditOffline test for adding a new obs offline...
which doesn't actually catch this bug, but may catch others. This bug may
have been due to a race condition that doesn't happen in the test env for
some reason.
The problem seemed to be reverse geocoding the coordinates for each
observation before moving on to ObsEdit, i.e. when that threw an exception it
kind of silently cause Promise.all not to resolve... which is not supposed to
happen for a few reasons, foremost among them that we were catching the error
and returning null instead. So I'm still confused about why exactly this was
happening.
Regardless, geocoding is potentially slow and buggy, so IMO it's better to do
it on ObsEdit than in the provider, and only do it when we need it, i.e. when
the user is actually looking at the obs.
Some other minor changes
* Show loading indicator on GroupPhotos button while creating obs
* fetchPlaceName performs a null check on coords before making a network
request to test connectivity
* More precise error handling
* Removed some redundant await statements
* Mocked react-native-geocoder-reborn in tests
Closes#857
* Bugfix: navigation was broken when choosing a taxon on Suggestions
* Test for Suggestions navigation
The thorny part here was isolating the test Realm db. We should really have a
generalized strategy for this, but this works for this task.
Primarily adds designed layouts for permission gates (also referred to as permissions priming).
* moved permission gate business logic into a container
* use react-native-permissions exclusively
* Show PermissionGate as a modal
* Basic unit tests for PermissionGate
* Consistent content width on tablet, other minor style changes
* Allow PermissionGate to be used outside of nav hierarchy
* Use user location on Explore after getting permission
* Remove redundant 'always' location perm in ios
* Isolate current location button in the Map component, which uses location fetching functionality from react-native-maps instead of our own
* Updated cocoapods; matched INatIcon.ttf to sha1 hashes
* Update vision camera
* Breaking change: camera device hook
* Breaking change: replace reanimated function calls
* Update vision plugin
* New take photo options
* Use changed props
* Remove undocumented prop
* Update test mocks for vision camera libraries
* Replace vision camera device orientation strings
* Add explanations to a central file for patches needed with the vision camera
* Some more patches
* Update some dependencies with minor version change
* Update some dependencies
* Fix some dependencies because of incompatibilities
* Update package-lock.json
* Testing dependencies updated
* Fix RN permissions
An upgrade broke the import of it's mock in our tests.
* Bump some more minor dependencies
* Small package dump
* Upgrade to Realm v12
* Upgrade i18n dependencies
* Update AuthenticationService.js
* Revert "Upgrade to Realm v12"
This reverts commit ce463fe246.
* Ensure layout of the PhotoCarousel photos doesn't change in delete mode
* Stop conflating screen-size layout differences with tablet layout differences
* Bugfix: deleting one photo in the StandardCamera removed all photos
* Animated rotation of rotatable elements on StandardCamera
* Ensure loading status shows while first photo is being taken
* Tried to remove some open handles and shore up some unhappy tests
Fixes problem in which the StandardCamera did not render previews in the correct orientation in Android.
* useDeviceOrientation hook in StandardCamera
* Bugfix: useDeviceOrientation was not setting the initial device orientation
correctly
* Bugfix: deal with idiosyncracies in iOS vs Android orientation values when
making our own copies of photos
* Convenience scripts for running OS-specific e2e build and test
* StandardCamera for large layouts
* StandardCamera and main merge cleanup
* Refactoring flashButton render
* Adjust margins and button spacing for large layouts
* Change conditionals to include screen size breakpoints
* Remove redundant conditionals
* Added PhotoPreview large screens landscape, styling cleanup, ios portrait mode lock on phones
* Update unit test, update snapshots
* Rotate icons in landscape and fix photolist direction in phones
* Rotate icon function adjusted
* Several fixes for orientation chages; keep camera buttons in place
Orientation was not being set correctly, but given the different definitions
and different values for orientation used by differe libraries, that's pretty
understandable. Here's I've tried to standardize around some constants and
make sure it gets set correct and variables like `isLandscapeMode` actuall
have the value the claim to hold.
Also redid the "no photos" state for the camera to be closer to spec, though
the text rotation is quite a pain.
Camera buttons should now stay in place even when the flash button appears or
disappears depending on the camera in use.
* Use isLargeScreen consistently
* Don't track orientation change when it doesn't do anything
i.e. on a phone. This was causing a crash in Android when rotating into
portrait orientation.
* Orientation change updates for StandardCamera
* go back to supporting rotation on small devices for the icons
* fixed android crash when rotating from landscape to portrait on a small
device
* handled FACE-UP and FACE-DOWN orientations by just not changing layout in
those scenarios
* Fix discard changes sheet in camera
---------
Co-authored-by: Ken-ichi Ueda <kenichi.ueda@gmail.com>
Co-authored-by: Amanda Bullington <albullington@gmail.com>
* Add DateDisplay to ObsCard and make first pass at translation strings
* Add failing tests (due to lack of localization) for timeless dates
* WIP: trying to ensure i18next gets initialized before tests run
The remaining test failures might be legit. This probably breaks the actual
app, though.
* Got the rest of the tests working
* Updated tests to assume UTC
* Updated README to advise against using `npx jest` so test runs always have
the env vars we specify in our `npm test` script
* Moved i18next initialization to an explicitly-named file
* Use i18next init function in app
* Fixed up remaining tests
* Added test for non-English localization of date format
* Cleanup
* Made DateDisplay explicitly handle strings not Dates
* Restore skipped localization tests for MyObservations
* Remove duplicative tests from DateDisplay unit test
* Added note to the README about initializing i18next
* Updated change to DateDisplay in main
---------
Co-authored-by: Ken-ichi Ueda <kenichi.ueda@gmail.com>
* Incremental changes to navbar component
* Fix tests
* Fix ally tests
* Space parens
* Add box shadow for android
* Add accessibility role
* Add a11y
* lint
* Add basic tests
* Fix tests
* Fix tests
* Update colors
* Merge remote changes
* Lint
* Add more comprehensive test
* Incremental changes to navbar component
* Fix tests
* Fix ally tests
* Space parens
* Add box shadow for android
* Add accessibility role
* Add a11y
* lint
* Add basic tests
* Fix tests
* Fix tests
* Update colors
* Merge remote changes
* Lint
* Add more comprehensive test
* switch to react native paper
* Make explore button nav to explore
* Remove inline styles
* Fix border on android
* Use user icon component in nav bar
* Rename props
* Remove t from nav button
* Change accessibility props
* Use a11y role for tabs
* Update NavBar.js
* Mock route for messages
* Mock route in tests
* Remove not needed function
* Remove NavBar unit test
* Create integration test file
* Add container mock to user profile test
---------
Co-authored-by: Johannes Klein <johannes.t.klein@gmail.com>
* Standard Camera adjust for width when screen orientation changes. Closes#350.
* Remove SafeAreaView from StandardCamera
* Reduced pressable area for camera button
* Lock StandardCamera orientation to portrait mode on smaller devices, detect device rotation
* PhotoCarousel responsive to device rotation, mocks added to StandardCamera tests
* Image rotation when rotation to and from landscape mode
Removes intentional Realm file deletion to avoid unintentional Realm file deletion, though the latter remains something of a mystery.
* Configure Realm with the full path to the file
* Remove all Realm.open calls in AuthenticationService in favor of passing the
context/provider copy of realm (only one realm instance)
* Only delete the realm file on sign out if deleting realm contents fails for
some reason
* Replaced deleteRealm with semantically more accurate clearRealm
Closes#373
* #369 - use different library for location fetching
* Use @react-native-community/geolocation everywhere, including tests
Co-authored-by: Yaron Budowski <budowski@gmail.com>
* Set up logging for user signing in and out
* Set up button to email debug logs in About; closes#357
* Fix bug where signOut called too many times in App; code cleanup
* Add mocks to RNFS to get Auth tests passing
* Add simple test to make sure mailer is called on button press
* Added a file sharing fallback when Mail is not available in iOS
* Rename log extension
Co-authored-by: Ken-ichi Ueda <kenichi.ueda@gmail.com>
* Add script to clean start
* Add function to camera mock
* Basic StandardCamera test setup
* Display flash off icon in camera
* Add accessibility labels to strings
* Change to use testID for tests
* Rename package script
* Update vision-camera mock
* Fetch user from server, set locale in realm and change language with i18next
* Added some Spanish translations so I can see localization working
* config QueryClient with `cacheTime: Infinity` to deal with "Jest did not
exit" errors
Co-authored-by: Ken-ichi Ueda <kenichi.ueda@gmail.com>
* Allow editing of existing id; remove unused id buttons; closes#230 and closes#231
* Remove unused text component & update IdentificationSection to tailwind css
* Remove unused obsEdit styles; convert styles to tailwind
* Remove unused bottom modal component and obsedit stylesheet
* Add comments to useEffect for opening local observation; convert realm object to JSON
* ObsEdit loads obs from db only when required
* Use observation update API call for observations already on the server
* Change wasSynced to instance method; only upload unsynced evidence
* Move keyboard aware scroll mock to jest.setup
* Await uploading evidence instead of returning a different response
Co-authored-by: Ken-ichi Ueda <kenichi.ueda@gmail.com>
I enabled jest.useFakeTimers() for all tests in the jest test setup files. I have since learned that it is better to enable it on a test-by-test basis. I have now enabled it globally and fixed the resulting error in the ObsEdit test.
* #144 - when creating new observation, import first photo EXIF data for location + date
* #144 - usePhotoExif - read partial file data; added testing for usePhotoExif hook
* #144 - import photo exif - use our own react-native-exif-reader library + other fixes (not to automatically fetch location, save original uri)
* Do not save original photo URI in DB, only pass it along to obs edit screen for EXIF parsing
* Upgraded testing library version to support renderHook
Co-authored-by: Ken-ichi Ueda <kenichi.ueda@gmail.com>
* Started using the FlatList extraData prop to rerender the list.
* Added an integration test for photo selection state
* More fully-formed default mock for camera-roll; removed other test
Co-authored-by: Ken-ichi Ueda <kenichi.ueda@gmail.com>
* Separate AddCommentModal into its own component
* Use defaultValue instead of setting TextInput with value from state; styling fixes
* Fix for android build in build.gradle
* Styling fixes for text inputs
* Update bottom sheet mock to get tests passing
* Restore notes to same code as in main branch
This also upgrades us to React Native 0.70.4 and adds a number of files that get us ready for the New Architecture.
Co-authored-by: Ken-ichi Ueda <kenichi.ueda@gmail.com>
This attempts to remove the necessity of opening and closing Realm
connections, which can lead to stale connections and invalidated objects. I
did not try to remove direct access to realm from AuthenticatedService,
which exists outside of the component hierarchy and can't really access
context, but I think eventually we may want to bring all that functionality
within the component hierarchy so there really is only one Realm connection
in the app.
Probably still some bugs here. One major problem is that deleting the Realm
file does not seem to trigger a re-render of the RealmProvider. My workaround
was to delete all the data in RealmProvider connection to Realm before
deleting the file, but it seems kind of redundant.
Some other changes
* Updated react-native-image-resizer and worked around some regressions
* Needed to use Array.from on Realm collections in many places;
map( o => o ) doesn't seem to work for creating POJOs from realm objects any more
* React Native Paper provider needs to be inside the Realm provider for any
realm stuff to happen with rn paper modals
* Several workarounds for the fact that Realm objects don't behave like POJOs
* Added useApiToken hook (#158)
* Renamed the useUser hook to useRemoteUser, since that's what it was doing
* Add icons to obs card comments/ids
* Show red icons when user has unviewed comments/ids
* Mark obs viewed locally and with server via obs detail
* Mock i18next; get tests passing
These rules are largely based on the AirBnB ones, which are not quite standard
for the React Native world, where Prettier seems to be more common, but I
think they add a lot of useful checks, and unlike Prettier we can customize
them. This also just makes it easier for people on the iNat team to work on
the mobile app.
Some specific changes:
* Added eslint-plugin-react-hooks to eslint rules
* Added eslint-plugin-simple-import-sort to eslint rules
* Bugfix: could not import photo from gallery
* Added support for react-native/no-inline-styles eslint rule
* useUser should not bother fetching a user for a blank userId