* Use unrestricted commonAncestorRankType for offline predictions from file
* The plugin provides an interface for this
* Fix type error
* Add missing type
* The iconic taxon is no longer part of the predictions result
If we use common ancestor rollup mode the ancestor taxa are no longer included in the result (which in turn are the top 10 species predictions). So, we have to get the iconic taxon name for each result in a different manner.
* Not needed as results are returned with highest score first
* Remove number wrapper
* Update comment
* There is no special offline not-confident criterion
This now returns common ancestor as top ID in case there is none over the threshold. So, same as online.
* No distinction between debug types
* Update ModelPrediction.js
* This is actually redundant
* Offline suggestions need to be sorted same as online
* Should not have removed the export
* Update comments
* Update vc plugin
* Update tests with breaking change: combined_score now 0-100
* Frame processor predictions are in range of 0-100 with new key
* Remove offline convert score to confidence
* Update calculateConfidence.js
* Common ancestor should use combine_score
* Offline suggestions have combined_scores now instead of scores
* Change filtering to range 0-100
* Only use combined_score for Match screen
* Update debug data
* Fic typo in tests
* Remove key from type
* remove assumed and undocumented meaning of page being zero from our use of
useInfiniteScroll in Explore; uses explicit type checks instead
* document byzantine pagination logic in useInfiniteExploreScroll
* fix broken infinite scroll when sorting by faves (was only showing first
page)
The underlying problem from 96c316a was setting initialPageParam to 1 in
useAuthenticatedInfiniteQuery, which seems rational, except
useInfiniteExploreScroll was using a false-ish value of page to detect when
it was requesting its first page. This does the same by being more explicit
about page's type without injecting undocumented meaning into the params we
hand to useInfiniteScroll.
* refactor: move Explore page param munging into unit tested helper
Closes MOB-400
* refactor: convert UserIcon to TypeScript
* feat: show simple MyObs to signed in user; add user icon & login to header
* feat: show warning and edit button for unuploaded obs w/o basics
* refactor: consolidate ObsEdit navigation logic
* feat: show edit button with circle dots
* refactor: upload UploadQueuedRotatingIcon to the more reusable CircleDots
component
* refactor: upload icons to use more composition and fewer specialized, one-off
components
* fix: bugs in determining if an obs has date and coords
* refactor: extract MyObservationsSimple business logic into container
* refactor: get total obs count from relevant hooks
* feat: show remote species for signed in users
* fix: hide photo count icon when missing basics icon is present
* feat: show banner alerting user when missing location or date
Closes MOB-318
Simplified version of MyObs for signed out users with more than 1 obs. Currently only in debug mode.
Also:
* refactor: extract TaxonGridItem into a reusable component
* chore: TypeScript cleanup
Closes MOB-317
FYI, this also essentially outlaws variables in translation keys because a key
that is only used with interpolated strings will never appear as "used".
Also starts using a convention of adding info to i18n keys that do not relate
to the text after double dashes, e.g. `Unknown--taxon = Unknown` for a string
that is specifically meant to describe a missing taxon but only needs to have
the word "Unknown".
* Changed several accessibilityHints to 3rd person
* Made several accessibilityLabels shorter and more verb-oriented
* Removed many unused i18n keys
* Refactored variables in i18n keys
* Removed some unused code from the old Settings
* Restyle community taxon section
* Use fave/unfave mutation in case of need_id metric
* Add votes field to Observation
* Change useIsConnected to TS
* Refactor fetching of remote observation into hook
Also includes the code to update local copy of a user's own observation
* Use const as key instead of string
* Remove unused prop
* Only send obs uuid to DQA
* Get obs in DQA container
* Rebuild object that is to check as it was send in nav params
* Refactor qualityGrade
* Refactor set to not loading state
* Update test to reflect fetching of obs
* Refactor too long lines
* Refetch remote observation after success in adding/removing vote
* Change qualitcMetrics to make use of observation.votes as well
Also refactored the object structure to use more efficient and performant filtering and finding in child components.
* Only use data slice for DQA buttons
* Refactor DQAButtons to only work with data slice relevant to that metric
* Special case for needs_id metric
* Also show loading indicator when fetching remote obs
* Add TODO
* Check only for vote of this user
* Optional chaining for user id
* Update test
* Enable fetching of remote if local is falsy
* Invalidate query on mutation
* Only set loading to false after refetch is finished
* Split up DQA test into unit tests and integration tests
* Use factory for mock user
* Add needs_id DQAVoteButtons unit test
* Revert hook to js
* Check for observation before using it
* Undo code style changes
* Remove unused value
* Refactor faves to be derived from votes
* Refactor needs_id interaction into standalone fcts
* Code style
* Only requests remote taxon if local is missing or hasn't been synced in a
week
* Returns a localized version of the remote taxon immediately without waiting
to get a newly-created record from realm
* Expands tests to use a unique realm, integrate more of our code, and check
to ensure the API gets called
* Show indicator while loading taxon on ARCamera
* Show iconic taxon found in model results if we can't load a remote taxon
* Show iconic taxon as backdrop for ObsImage whenever possible
* Use latest vision-plugin from feature branch
* Change model helper to TS
* Update prediction from image to the new return structure
* Rename variable
* Change ARCamera to new return structure
* Update all test that make use of predictions
* Update to use plugins main branch
* 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
Additionally,
* Adds tests for ID withdraw and restore
* Renames withdrawOrRestoreIdentification function for clarity
* Adds some accessibility labels for testing and accessibility
Closes#1129
* Extracted non-photo stuff from PhotoDisplay
* Separate component for FaveButton
* Prevent faves while signed out
* Separate component for nav header
* Stick nav header while scrolling until tabs
* Nav header has slight gradient for visibility over white content
* Renamed ObsDetails media components so they're not focused on photos
* Data and layout changes leading up to sound player on ObsDetail
* Add sound player to ObsDetails
* Swiping away while playing should pause playback
* Swiping back to sound and playing again should resume where you left off
* Allow viewing media while offline (images may be cached)
* Stop playback when navigating away from ObsDetails
* Fetch sounds in Explore so we can show sound icon
* Map all observation objects in explore with Realm-ish attributes
Syncing was broken when an unsynced obs was deleted
The main problem here was that MyObs state has a list of observations that
need upload, but since it was a plain array of Realm objects it crashed when
one of those objects was invalid, which happened after deletion. This fix
isn't great: it just makes it so the thing in state is a Realm.Results
object, which will update dynamically when its underlying data changes. We
could also JSONify what we have in state, but then you get into problems of
nested objects and deep JSONification.
Also
* Delete local obs if remote doesn't exist
* Bugfix: ObsDetail tried to mark non-existent remote obs as viewed
* Tried to handle react query retries better
* 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.
* Bugfix: TaxonDetails was crashing if it received a null taxon
* Send lat and lng instead of latitude and longitude to the score_image
endpoint
* Show offline suggestions when you are offline
* Show notice when viewing offline suggestions
* Moved code unique to useOnlineSuggestions into that file
* Ensure we use a medium size image to get suggestions when dealing with
remote URLs
* More logging around React Query retries
* Use default retry logic for useAuthenticatedQuery
* Made a module-resolver shortcut for tests
* Move offline notice above top suggestion; hide when offlines exist but onlines do too
* Access MediaViewer from TaxonDetails
* Added our own presets for ActivityIndicator
* TaxonDetail should show a local taxon if one is available
* Made it a little easier to import the custom logger
* Refactored MediaViewer to accept photo-like objects instead of URIs
* Added license / attribution button to MediaViewer
* Moved delete button into MainPhotoDisplay so each photo has its own button
and it can be laid out relative to its photo
* Add custom header to MediaViewer when accessed from TaxonDetial
* Allow DisplayTaxonName to accept custom text components as props
* Added darker bg to photo on TaxonDetail to make title more legible
* 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.
* Make minimum viable RemoteComment
* Minimum vialbe RemoteIdentification
* Minimum viable remote project, place, and messages
* Create minimum viable records for all remote factories
* Remove factories for local device data
* Minimum viable local taxon, comment, id
* Minimum viable for local observation photo (photo has no primary key)
* Minimum viable LocalUser
* Minimum viable record for LocalObservation
Obs deletion bug mostly has to do with Realm objects hanging around in memory
when they're no longer in the database. I spent a long time trying to write a
test that could see the custom header button menu we add via react-navigation
but never got it to work.
* Refactor ObsStatus, add filled property
* Remove viewed prop from observation
* Update properties for ObsDetail mark viewed
* Use separate fields for comments and ids for ObsStatus
* Add hook for fetching updates
* Unit tests for the updates hook
* Unit tests for different paths for updating the realm observation when using the hook
* Update MyObservations.test.js
* Add integration test if updates has been called in my observations
* Update Podfile.lock
* Update observation to not viewed if the keys have not been initialized
* Add test case if observation fields are not initialized
* Add test case
* Refetch stale data on coming back from the background
* Subscribe to observation updates also in ObsDetail screen
This also invalidates and refetches the data after a successful mutation of the id or comment being viewed.
* Refetch observation updates data on sync button press
* Throw error in updates query
* Return refetch function from hook
* Add mock to ObsDetails
* Remove unused var
* Update useObservationsUpdates.test.js
* Reset realm viewed state to true ...
for all observations on app mount and coming to the foreground.
* Reorder function calls
* Change hook to use boolean as enabled param
* Create ObsDetails.test.js
* Update date handle tests to make sure Remote data classes have parseable date
* Add test case for comment and identification
* Update ObsDetails.test.js
* Also check for user in ObsDetails
* Refactored into separate hook for App.js
* Unit and integration test for new hook
* Rename const
* Rename field
* Rename field
* Export query key from hook
* Refactor true check
* Additional methods for obs being viewed or not
* Changed test description
* Add per_page to observations updated
* Crosshairs, location accuracy warnings, text input for location picker
* Add LocationPicker tests
* UI improvements and code refactor into smaller components; get GMaps working
* Add shadows to icons/text boxes
* Use debouncing to avoid map jitter when typing in location
* Show place results & let user pick new location from web api
* Add tests for location picker with remote results
* Add gmaps api key to github actions
* Try adding manifest placeholders for env variable to work in github actions
* Add key to printf in github actions
* Try accessing GMAPS_API_KEY a different way
* Update android e2e env file step
This updates the "Create .env file" step to use printf to print the Google Maps key into a newly created .env file in the GitHub Action runner. Using the same key as in env.example.
* Fix newline
---------
Co-authored-by: Johannes Klein <johannes.t.klein@gmail.com>
* WIP: very rough start at pulling state up into a container for MyObservations
I made a parallel MyObservations component and container so ObservationViews
can still be used as a working reference, but the ultimate goal here is to
focus MyObservations on presentation, and pull state and other business logic
up into a container component. This should make MyObservations a bit more
testable and clean up a very large and confusing file.
I'm also trying to move away from a generalized representation of observations
on all screens, which is why I want to name it MyObservations and not
ObservationViews. MyObservations has a lot of unique functionality that we
won't need elsewhere, and we can modularize stuff when we need to use it in
multiple places.
* UI updates for header, toolbar, empty component
* Add pressable component and login sheet
* UI improvements; get infinite scroll working
* UI improvements & additions for empty screen & bottom sheet
* Show login sheet when a user presses sync but is not logged in
* Fix backdrop close for AddObsModal
* Move UI elements to MyObservations
* Fix unit tests for MyObservations
* Fix for login sheet
* Set header height to a different height on Android to account for safe area
* Fix failing tests & rerender of user icon in navbar
* Remove scientific name from DisplayTaxonName to match Figma UI
* Set height above toolbar dynamically for sticky toolbar
* Add prop to display or hide second name in DisplayTaxonName
* Use RN styling to style grid view for MyObs flatlist
* Fix failing project obs test
* Create separate ToolbarContainer to separate presentation from logic; fix upload count
* Merge main and show onboarding based on user's total obs count
* Fix display taxon name styling and remove header fade on iOS
* Add header text for 0 observations, logged out state
* Update infinite scroll to 50 obs at a time; make loading wheel show faster
* Add uploaded status to toolbar
* Apply bandaid fix to stop Android from crashing on start
* Start adding new icons to MyObs
* Add circular progress; show upload icons at correct times during upload
* Add disabled props for accessibility state
* Fix tests; update snapshots
* Code cleanup
* Code cleanup & add inaturalist icon
* Fix merge conflict and add icon
* Add inaturalist icon
* Fix navigation to obs list and toolbar status when upload completes
* Move showLoginSheet code to MyObsContainer
* Fix toolbar status text
* Sync toolbar with upload status progress
* Clear toolbar after nav
* Tests passing
* Update e2e test
* Target login button in e2e tests
* Fix failing e2e tests with new testID for login button
* Update button snapshot to include new testID
---------
Co-authored-by: Ken-ichi Ueda <kenichi.ueda@gmail.com>
* Regroup accessibility label strings at end of strings file
* Add accessibility test to AddID
* Add a11y labels to AddID
* Add a11y test to StandardCamera
* Add a11y props to StandardCamera
* Remove unit test with only todos
* Add a11y test to Messages
* Refactor PhotoScroll test into own file
* Add a11y test to ObsDetails
* Add a11y test to ObsList
* Add a11y matcher to PhotoGallery test
* Add a11y matcher to ProjectDetails test
* Add a11y matcher to ProjectObservations test
* Add a11y matcher to Projects test
* Add a11y props to ProjectList
* Add a11y props to ProjectTabs
* Add a11y matcher to Search
* Add a11y matcher to UserProfile test
* Add a11y test matcher to UserText test
* Update react-native-accessibility-engine
* Add a11y matcher to Tabs test
* Add a11y label to a selectable photo
* Refactor DataTab tests into separate file
* Refactor ActivityTab test out into own file
* Added a test how to check if a component uses a mocked container
* Add wrong a11y props to TextInput left icon
* Enable a11y test with actual BottomSheet because mock does not pass a11y props down
* Add a11y default props to Button
* Show no-internet state for photo/map elements in ObsDetail when offline
* Add two tests to check that correct elements are shown offline/online in ObsDetails
* Create useIsOnline hook to check for connectivity; only mark viewed locally if API call succeeds
* Rename hook to useIsConnected
* Update no wifi image and add a11y labels
* Add device location factory function for mocking latLng; fixes for ObsDetails test
* Test that data tab content is not visible before changing tab
Co-authored-by: Johannes Klein <johannes.t.klein@gmail.com>
* Refactor ObsEditProvider to make a reusable uploadObservation function; add blocking loading state in ObsEdit
* Allow individual uploads from ObsList; add loading wheel to toolbar
* Add upload button on grid view; closes#281
* Fix failing tests
* Use needsSync instance method & fix failing tests
* Switch test rendering back to renderComponent method
* Fix exif test
* Make sure camera/no evidence still create a new observed_on_string
* Fix failing test with observed_on_string in fake LocalObs; closes#259
* Parse date into local timezone
* 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>
* Rewrite remote observation & update fetching using useQuery in ObsList
* Fix ObsList test by adding query provider
* Add padding to infinite scroll view indicator
* Only set next uuid for obslist if not still loading results from last api call
* Improve how ObsList works when observations don't fill screen
* Remove explore, explore provider, dropdown menu, and related screens; fix tests
* Move setIdBelow function into onEndReached
* 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>
* 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>
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
* Sign out user when encountering a 401 error while fetching JWT
* Save currently signed in user in Realm
* Check for logged in user on app start, add loading wheel to obs list, sign user out when no user ID
Closes#99
Co-authored-by: Ken-ichi Ueda <kenichi.ueda@gmail.com>
* Break uploader into helper function; add bottom model for uploading from obs list
* Create mapping function for uploading observations to iNat
* Mark observations as uploaded when id is returned from server
* Format dates on obs list
* Save all obs locally before trying to upload
* Resize grouped photo gallery photos for upload
* Resize photos btw group photos screen and obs edit
* Get sound, photo, obs uploads saving to realm and uploading later
* ObsEdit progresses to next or prev screen after one obs is saved locally
* Format date in camera; use time observed to show new local obs in ObsList
* Remove time zone attribute, since this is handled by server
* Submit sound and photo uuids as the file name for sound/photo uploads
* Make obsSounds an array in case there are multiple sounds for upload
* Removing time synced from Photo model bc not sure it's necessary
* Save _synced_at and _created_at time for all remote obs
* Fix back button, obs edit
* Don't show obs edit for unuploaded obs
* Get rid of ObservationProvider, move useObservations hook
* Fix place name; add date/time and location to no evidence uploads
* Add species_guess to observation when taxon_id changes
* Format date from picker; use string for sending to server
* Styling cleanup with react-native-paper; make ObsEdit into section components
* Add vector icons to ios (for searchbar)
* Add empty text to CV suggestions
* Cleanup code for marking records synced & uploading to server
* Use placeholder icons on bottom tab bar
* Add icons to ObsList; fix grid view when photo === null
* Fix jest tests
* Simplify setting an identification in ObsEdit
* Move inline styles to separate files
* Display all relevant saved obs data on ObsDetails; function to check for camel or snake case attributes
* Move logic for creating new sound observation to model, not sound recorder
* Add android vector icons
* Move create obs and create with no evidence into Observation model
* Add mock for react-native-fs
* Show option to edit user obs in ObsDetail; fix captive/geoprivacy/date fields for uploaded obs
* Move obsPhoto creation and obs with obsPhoto creation into models
* Create obs with sound from Obs model
* Create multiple obs from gallery photos; move logic into model
* Pass observation to ObsDetails via navigation to avoid opening and closing realm twice
* Lint error fixes
* Fix jest tests
* Use icons on normal camera
* Use timestamps from gallery and camera for new observations
* Keep simplifying code
* Update version/build number; add key to info.plist for faster ios build
* Remove TranslatedHeadline component
* Move saveLocalObservation logic to model
* Move all FIELDS for api calls into models (except messages, which doesn't have a model yet)
* Only show upload UI if user is logged in
* Fix obs edit link so it works for both logged in and logged out users
* Bug fixes: get fields from models; addListener function in test
* Model code cleanup
* More code cleanup
* Remove unused imports
* first pass
* some clean-up
* linting clean-up
* added a Q
* more cleanup
* Merge branch main of https://github.com/inaturalist/iNaturalistReactNative into 34-messages-0
# Conflicts:
#src/providers/hooks/useObservations.js
* simplify away from context and providers
* remove unused model
* remove model ref
* other clean-up
* add basic unit test for messages
* add activity indicator
* add test for activity indicator
* remove false positive tests
* fix navigation
* remove api params
* clean up
* move navigation and update test
* improve testing
* Get observation upload and obs_photo upload working with staging v1
* Add location with accuracy to normal camera uploads
* Add location and date to sound recordings
* Add camera options button to end of evidence list
* Add photos to obsEditProvider from camera, sound, and photo library
* Code cleanup
* Use ObsEditProvider as global state for uploader; support multi photo/sound; get test passing
* Set config to API v2