├── .editorconfig
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── code-health.md
│ └── feature_request.md
├── actions
│ └── submit-test
│ │ └── action.yml
├── auto_assign.yml
├── pull_request_template.md
└── workflows
│ ├── ci.yml
│ ├── test-e2e.yml
│ ├── test-submit.yml
│ └── todo-to-issue.yml
├── .gitignore
├── .idea
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── externalDependencies.xml
└── ktfmt.xml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── app
├── build.gradle
├── proguard-rules.pro
├── schemas
│ └── org.groundplatform.android.persistence.local.room.LocalDatabase
│ │ ├── 120.json
│ │ ├── 121.json
│ │ └── 122.json
└── src
│ ├── debug
│ ├── AndroidManifest.xml
│ ├── ic_launcher-playstore.png
│ ├── java
│ │ └── org
│ │ │ └── groundplatform
│ │ │ └── android
│ │ │ └── HiltTestActivity.kt
│ ├── local
│ │ └── google-services.json
│ ├── res
│ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_round.png
│ │ └── values
│ │ │ └── ic_launcher_background.xml
│ └── resources
│ │ └── jacoco-agent.properties
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ └── licenses
│ │ │ └── cc0_license.txt
│ ├── ic_launcher-playstore.png
│ ├── ic_launcher-web.png
│ ├── java
│ │ └── org
│ │ │ └── groundplatform
│ │ │ └── android
│ │ │ ├── AbstractActivity.kt
│ │ │ ├── Config.kt
│ │ │ ├── ExcludeFromJacocoGeneratedReport.kt
│ │ │ ├── FirebaseCrashLogger.kt
│ │ │ ├── GroundApplication.kt
│ │ │ ├── GroundApplicationModule.kt
│ │ │ ├── LocalDatabaseModule.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── MainUiState.kt
│ │ │ ├── MainViewModel.kt
│ │ │ ├── PermissionDeniedDialog.kt
│ │ │ ├── SettingsActivity.kt
│ │ │ ├── coroutines
│ │ │ ├── CoroutineDispatchersModule.kt
│ │ │ └── CoroutineScopesModule.kt
│ │ │ ├── model
│ │ │ ├── AuditInfo.kt
│ │ │ ├── Role.kt
│ │ │ ├── Survey.kt
│ │ │ ├── SurveyListItem.kt
│ │ │ ├── TermsOfService.kt
│ │ │ ├── User.kt
│ │ │ ├── geometry
│ │ │ │ ├── Coordinates.kt
│ │ │ │ ├── Geometry.kt
│ │ │ │ └── InvalidGeometryException.kt
│ │ │ ├── imagery
│ │ │ │ ├── OfflineArea.kt
│ │ │ │ └── TileSource.kt
│ │ │ ├── job
│ │ │ │ ├── Job.kt
│ │ │ │ └── Style.kt
│ │ │ ├── locationofinterest
│ │ │ │ └── LocationOfInterest.kt
│ │ │ ├── mutation
│ │ │ │ ├── LocationOfInterestMutation.kt
│ │ │ │ ├── Mutation.kt
│ │ │ │ └── SubmissionMutation.kt
│ │ │ ├── submission
│ │ │ │ ├── CaptureLocationTaskData.kt
│ │ │ │ ├── DateTimeTaskData.kt
│ │ │ │ ├── DraftSubmission.kt
│ │ │ │ ├── GeometryTaskData.kt
│ │ │ │ ├── MultipleChoiceTaskData.kt
│ │ │ │ ├── NumberTaskData.kt
│ │ │ │ ├── PhotoTaskData.kt
│ │ │ │ ├── SkippedTaskData.kt
│ │ │ │ ├── Submission.kt
│ │ │ │ ├── SubmissionData.kt
│ │ │ │ ├── TaskData.kt
│ │ │ │ ├── TextTaskData.kt
│ │ │ │ ├── UploadQueueEntry.kt
│ │ │ │ └── ValueDelta.kt
│ │ │ └── task
│ │ │ │ ├── Condition.kt
│ │ │ │ ├── MultipleChoice.kt
│ │ │ │ ├── Option.kt
│ │ │ │ └── Task.kt
│ │ │ ├── persistence
│ │ │ ├── local
│ │ │ │ ├── LocalDataConsistencyException.kt
│ │ │ │ ├── LocalDataStoreModule.kt
│ │ │ │ ├── LocalValueStore.kt
│ │ │ │ ├── SharedPreferencesModule.kt
│ │ │ │ ├── room
│ │ │ │ │ ├── IntEnum.kt
│ │ │ │ │ ├── LocalDataStoreException.kt
│ │ │ │ │ ├── LocalDatabase.kt
│ │ │ │ │ ├── converter
│ │ │ │ │ │ ├── ConverterExt.kt
│ │ │ │ │ │ ├── GeometryWrapperTypeConverter.kt
│ │ │ │ │ │ ├── JsonArrayTypeConverter.kt
│ │ │ │ │ │ ├── JsonObjectTypeConverter.kt
│ │ │ │ │ │ ├── LoiPropertiesMapConverter.kt
│ │ │ │ │ │ ├── StyleTypeConverter.kt
│ │ │ │ │ │ ├── SubmissionDataConverter.kt
│ │ │ │ │ │ ├── SubmissionDeltasConverter.kt
│ │ │ │ │ │ └── ValueJsonConverter.kt
│ │ │ │ │ ├── dao
│ │ │ │ │ │ ├── BaseDao.kt
│ │ │ │ │ │ ├── ConditionDao.kt
│ │ │ │ │ │ ├── DraftSubmissionDao.kt
│ │ │ │ │ │ ├── ExpressionDao.kt
│ │ │ │ │ │ ├── JobDao.kt
│ │ │ │ │ │ ├── LocationOfInterestDao.kt
│ │ │ │ │ │ ├── LocationOfInterestMutationDao.kt
│ │ │ │ │ │ ├── MultipleChoiceDao.kt
│ │ │ │ │ │ ├── OfflineAreaDao.kt
│ │ │ │ │ │ ├── OptionDao.kt
│ │ │ │ │ │ ├── SubmissionDao.kt
│ │ │ │ │ │ ├── SubmissionMutationDao.kt
│ │ │ │ │ │ ├── SurveyDao.kt
│ │ │ │ │ │ ├── TaskDao.kt
│ │ │ │ │ │ └── UserDao.kt
│ │ │ │ │ ├── entity
│ │ │ │ │ │ ├── AuditInfoEntity.kt
│ │ │ │ │ │ ├── ConditionEntity.kt
│ │ │ │ │ │ ├── DraftSubmissionEntity.kt
│ │ │ │ │ │ ├── ExpressionEntity.kt
│ │ │ │ │ │ ├── GeometryWrapper.kt
│ │ │ │ │ │ ├── JobEntity.kt
│ │ │ │ │ │ ├── LocationOfInterestEntity.kt
│ │ │ │ │ │ ├── LocationOfInterestMutationEntity.kt
│ │ │ │ │ │ ├── MultipleChoiceEntity.kt
│ │ │ │ │ │ ├── OfflineAreaEntity.kt
│ │ │ │ │ │ ├── OptionEntity.kt
│ │ │ │ │ │ ├── StyleEntity.kt
│ │ │ │ │ │ ├── SubmissionEntity.kt
│ │ │ │ │ │ ├── SubmissionMutationEntity.kt
│ │ │ │ │ │ ├── SurveyEntity.kt
│ │ │ │ │ │ ├── TaskEntity.kt
│ │ │ │ │ │ └── UserEntity.kt
│ │ │ │ │ ├── fields
│ │ │ │ │ │ ├── EntityDeletionState.kt
│ │ │ │ │ │ ├── ExpressionEntityType.kt
│ │ │ │ │ │ ├── MatchEntityType.kt
│ │ │ │ │ │ ├── MultipleChoiceEntityType.kt
│ │ │ │ │ │ ├── MutationEntitySyncStatus.kt
│ │ │ │ │ │ ├── MutationEntityType.kt
│ │ │ │ │ │ ├── OfflineAreaEntityState.kt
│ │ │ │ │ │ ├── TaskEntityType.kt
│ │ │ │ │ │ ├── TileSetEntityState.kt
│ │ │ │ │ │ └── UserDetails.kt
│ │ │ │ │ ├── relations
│ │ │ │ │ │ ├── ConditionEntityAndRelations.kt
│ │ │ │ │ │ ├── JobEntityAndRelations.kt
│ │ │ │ │ │ ├── SurveyEntityAndRelations.kt
│ │ │ │ │ │ └── TaskEntityAndRelations.kt
│ │ │ │ │ └── stores
│ │ │ │ │ │ ├── RoomLocationOfInterestStore.kt
│ │ │ │ │ │ ├── RoomOfflineAreaStore.kt
│ │ │ │ │ │ ├── RoomSubmissionStore.kt
│ │ │ │ │ │ ├── RoomSurveyStore.kt
│ │ │ │ │ │ └── RoomUserStore.kt
│ │ │ │ └── stores
│ │ │ │ │ ├── LocalLocationOfInterestStore.kt
│ │ │ │ │ ├── LocalMutationStore.kt
│ │ │ │ │ ├── LocalOfflineAreaStore.kt
│ │ │ │ │ ├── LocalSubmissionStore.kt
│ │ │ │ │ ├── LocalSurveyStore.kt
│ │ │ │ │ └── LocalUserStore.kt
│ │ │ ├── remote
│ │ │ │ ├── DataStoreException.kt
│ │ │ │ ├── RemoteDataStore.kt
│ │ │ │ ├── RemotePersistenceModule.kt
│ │ │ │ ├── RemoteStorageManager.kt
│ │ │ │ └── firebase
│ │ │ │ │ ├── FirebaseFirestoreProvider.kt
│ │ │ │ │ ├── FirebaseMessagingService.kt
│ │ │ │ │ ├── FirebaseStorageManager.kt
│ │ │ │ │ ├── FirestoreDataStore.kt
│ │ │ │ │ ├── FirestoreUuidGenerator.kt
│ │ │ │ │ ├── base
│ │ │ │ │ ├── FluentCollectionReference.kt
│ │ │ │ │ ├── FluentDocumentReference.kt
│ │ │ │ │ └── FluentFirestore.kt
│ │ │ │ │ ├── protobuf
│ │ │ │ │ ├── FirestoreToProtobufExt.kt
│ │ │ │ │ ├── MessageLiteReflectionExt.kt
│ │ │ │ │ ├── ModelToProtoExt.kt
│ │ │ │ │ └── ProtobufToFirestoreExt.kt
│ │ │ │ │ └── schema
│ │ │ │ │ ├── AuditInfoConverter.kt
│ │ │ │ │ ├── CaptureLocationResultConverter.kt
│ │ │ │ │ ├── ConditionConverter.kt
│ │ │ │ │ ├── GeometryConverter.kt
│ │ │ │ │ ├── GroundFirestore.kt
│ │ │ │ │ ├── JobCollectionReference.kt
│ │ │ │ │ ├── JobConverter.kt
│ │ │ │ │ ├── LoiCollectionReference.kt
│ │ │ │ │ ├── LoiConverter.kt
│ │ │ │ │ ├── LoiDocumentReference.kt
│ │ │ │ │ ├── MultipleChoiceConverter.kt
│ │ │ │ │ ├── OptionConverter.kt
│ │ │ │ │ ├── SubmissionCollectionReference.kt
│ │ │ │ │ ├── SubmissionDocumentReference.kt
│ │ │ │ │ ├── SurveyConverter.kt
│ │ │ │ │ ├── SurveyDocumentReference.kt
│ │ │ │ │ ├── SurveysCollectionReference.kt
│ │ │ │ │ ├── TaskConverter.kt
│ │ │ │ │ ├── TermsOfServiceCollectionReference.kt
│ │ │ │ │ ├── TermsOfServiceConverter.kt
│ │ │ │ │ ├── TermsOfServiceDocument.kt
│ │ │ │ │ └── TermsOfServiceDocumentReference.kt
│ │ │ ├── sync
│ │ │ │ ├── LocalMutationSyncWorker.kt
│ │ │ │ ├── MediaUploadWorkManager.kt
│ │ │ │ ├── MediaUploadWorker.kt
│ │ │ │ ├── MutationSyncWorkManager.kt
│ │ │ │ ├── SurveySyncService.kt
│ │ │ │ ├── SurveySyncWorker.kt
│ │ │ │ ├── WorkManagerModule.kt
│ │ │ │ └── WorkRequestBuilder.kt
│ │ │ └── uuid
│ │ │ │ └── OfflineUuidGenerator.kt
│ │ │ ├── repository
│ │ │ ├── LocationOfInterestRepository.kt
│ │ │ ├── MapStateRepository.kt
│ │ │ ├── MutationRepository.kt
│ │ │ ├── OfflineAreaRepository.kt
│ │ │ ├── SubmissionRepository.kt
│ │ │ ├── SurveyRepository.kt
│ │ │ ├── TermsOfServiceRepository.kt
│ │ │ ├── UserMediaRepository.kt
│ │ │ └── UserRepository.kt
│ │ │ ├── system
│ │ │ ├── ActivityResult.kt
│ │ │ ├── ActivityStreams.kt
│ │ │ ├── FusedLocationProviderClient.kt
│ │ │ ├── GeocodingManager.kt
│ │ │ ├── GoogleApiManager.kt
│ │ │ ├── LocationManager.kt
│ │ │ ├── NetworkManager.kt
│ │ │ ├── PermissionsManager.kt
│ │ │ ├── RequestPermissionsResult.kt
│ │ │ ├── SettingsClient.kt
│ │ │ ├── SettingsManager.kt
│ │ │ ├── SystemModule.kt
│ │ │ ├── auth
│ │ │ │ ├── AnonymousAuthenticationManager.kt
│ │ │ │ ├── AuthenticationManager.kt
│ │ │ │ ├── AuthenticationModule.kt
│ │ │ │ ├── BaseAuthenticationManager.kt
│ │ │ │ ├── GoogleAuthenticationManager.kt
│ │ │ │ └── SignInState.kt
│ │ │ └── channel
│ │ │ │ └── LocationSharedFlowCallback.kt
│ │ │ ├── ui
│ │ │ ├── IconFactory.kt
│ │ │ ├── common
│ │ │ │ ├── AbstractDialogFragment.kt
│ │ │ │ ├── AbstractFragment.kt
│ │ │ │ ├── AbstractMapContainerFragment.kt
│ │ │ │ ├── AbstractViewModel.kt
│ │ │ │ ├── BackPressListener.kt
│ │ │ │ ├── BaseMapViewModel.kt
│ │ │ │ ├── BindingAdapters.kt
│ │ │ │ ├── EphemeralPopups.kt
│ │ │ │ ├── LocationOfInterestHelper.kt
│ │ │ │ ├── MapConfig.kt
│ │ │ │ ├── ProgressDialogs.kt
│ │ │ │ ├── SharedViewModel.kt
│ │ │ │ ├── ViewModelFactory.kt
│ │ │ │ ├── ViewModelKey.kt
│ │ │ │ └── ViewModelModule.kt
│ │ │ ├── compose
│ │ │ │ ├── ConfirmationDialog.kt
│ │ │ │ ├── HtmlText.kt
│ │ │ │ ├── HyperlinkText.kt
│ │ │ │ └── Toolbar.kt
│ │ │ ├── datacollection
│ │ │ │ ├── DataCollectionFragment.kt
│ │ │ │ ├── DataCollectionViewModel.kt
│ │ │ │ ├── DataCollectionViewPagerAdapter.kt
│ │ │ │ ├── DataCollectionViewPagerAdapterFactory.kt
│ │ │ │ ├── DataSubmissionConfirmationScreen.kt
│ │ │ │ ├── TaskDataHandler.kt
│ │ │ │ ├── TaskPosition.kt
│ │ │ │ ├── TaskSequenceHandler.kt
│ │ │ │ ├── UiState.kt
│ │ │ │ ├── components
│ │ │ │ │ ├── ButtonAction.kt
│ │ │ │ │ ├── InstructionsDialog.kt
│ │ │ │ │ ├── LoiNameDialog.kt
│ │ │ │ │ ├── TaskButton.kt
│ │ │ │ │ ├── TaskView.kt
│ │ │ │ │ ├── TaskViewFactory.kt
│ │ │ │ │ └── TextTaskInput.kt
│ │ │ │ └── tasks
│ │ │ │ │ ├── AbstractTaskFragment.kt
│ │ │ │ │ ├── AbstractTaskMapFragment.kt
│ │ │ │ │ ├── AbstractTaskViewModel.kt
│ │ │ │ │ ├── date
│ │ │ │ │ ├── DateTaskFragment.kt
│ │ │ │ │ └── DateTaskViewModel.kt
│ │ │ │ │ ├── instruction
│ │ │ │ │ ├── InstructionTaskFragment.kt
│ │ │ │ │ └── InstructionTaskViewModel.kt
│ │ │ │ │ ├── location
│ │ │ │ │ ├── CaptureLocationTaskFragment.kt
│ │ │ │ │ ├── CaptureLocationTaskMapFragment.kt
│ │ │ │ │ └── CaptureLocationTaskViewModel.kt
│ │ │ │ │ ├── multiplechoice
│ │ │ │ │ ├── MultipleChoiceItem.kt
│ │ │ │ │ ├── MultipleChoiceItemView.kt
│ │ │ │ │ ├── MultipleChoiceTaskFragment.kt
│ │ │ │ │ └── MultipleChoiceTaskViewModel.kt
│ │ │ │ │ ├── number
│ │ │ │ │ ├── NumberTaskFragment.kt
│ │ │ │ │ └── NumberTaskViewModel.kt
│ │ │ │ │ ├── photo
│ │ │ │ │ ├── PhotoTaskFragment.kt
│ │ │ │ │ └── PhotoTaskViewModel.kt
│ │ │ │ │ ├── point
│ │ │ │ │ ├── DropPinTaskFragment.kt
│ │ │ │ │ ├── DropPinTaskMapFragment.kt
│ │ │ │ │ └── DropPinTaskViewModel.kt
│ │ │ │ │ ├── polygon
│ │ │ │ │ ├── DrawAreaTaskFragment.kt
│ │ │ │ │ ├── DrawAreaTaskMapFragment.kt
│ │ │ │ │ └── DrawAreaTaskViewModel.kt
│ │ │ │ │ ├── text
│ │ │ │ │ ├── TextTaskFragment.kt
│ │ │ │ │ └── TextTaskViewModel.kt
│ │ │ │ │ └── time
│ │ │ │ │ ├── TimeTaskFragment.kt
│ │ │ │ │ └── TimeTaskViewModel.kt
│ │ │ ├── home
│ │ │ │ ├── AboutFragment.kt
│ │ │ │ ├── DataSharingTermsDialog.kt
│ │ │ │ ├── HomeScreenFragment.kt
│ │ │ │ ├── HomeScreenViewModel.kt
│ │ │ │ ├── UserDetailsDialog.kt
│ │ │ │ └── mapcontainer
│ │ │ │ │ ├── AdaptiveSpacingItemDecorator.kt
│ │ │ │ │ ├── HomeScreenMapContainerFragment.kt
│ │ │ │ │ ├── HomeScreenMapContainerViewModel.kt
│ │ │ │ │ ├── MapTypeAdapter.kt
│ │ │ │ │ ├── MapTypeDialogFragment.kt
│ │ │ │ │ ├── MapTypeViewModel.kt
│ │ │ │ │ └── jobs
│ │ │ │ │ ├── ActionButton.kt
│ │ │ │ │ ├── DataCollectionEntryPointData.kt
│ │ │ │ │ ├── JobMapComposables.kt
│ │ │ │ │ ├── JobSelectionModal.kt
│ │ │ │ │ ├── JobSelectionRow.kt
│ │ │ │ │ └── LoiJobSheet.kt
│ │ │ ├── map
│ │ │ │ ├── Bounds.kt
│ │ │ │ ├── CameraPosition.kt
│ │ │ │ ├── CameraUpdateRequest.kt
│ │ │ │ ├── Feature.kt
│ │ │ │ ├── FeatureType.kt
│ │ │ │ ├── MapFragment.kt
│ │ │ │ ├── MapProviderModule.kt
│ │ │ │ ├── MapType.kt
│ │ │ │ └── gms
│ │ │ │ │ ├── ClippingTileProvider.kt
│ │ │ │ │ ├── ConverterExt.kt
│ │ │ │ │ ├── GmsExt.kt
│ │ │ │ │ ├── GoogleMapsFragment.kt
│ │ │ │ │ ├── TemplateUrlTileProvider.kt
│ │ │ │ │ ├── features
│ │ │ │ │ ├── FeatureClusterItem.kt
│ │ │ │ │ ├── FeatureClusterManager.kt
│ │ │ │ │ ├── FeatureClusterRenderer.kt
│ │ │ │ │ ├── FeatureManager.kt
│ │ │ │ │ ├── LineStringRenderer.kt
│ │ │ │ │ ├── MapsItemManager.kt
│ │ │ │ │ ├── MapsItemRenderer.kt
│ │ │ │ │ ├── PointRenderer.kt
│ │ │ │ │ ├── PolygonRenderer.kt
│ │ │ │ │ └── TooltipMarkerRenderer.kt
│ │ │ │ │ └── mog
│ │ │ │ │ ├── ImageEditor.kt
│ │ │ │ │ ├── LatLngBoundsExt.kt
│ │ │ │ │ ├── MathExt.kt
│ │ │ │ │ ├── MogClient.kt
│ │ │ │ │ ├── MogCollection.kt
│ │ │ │ │ ├── MogImageMetadata.kt
│ │ │ │ │ ├── MogMetadata.kt
│ │ │ │ │ ├── MogMetadataReader.kt
│ │ │ │ │ ├── MogProviderModule.kt
│ │ │ │ │ ├── MogSource.kt
│ │ │ │ │ ├── MogTile.kt
│ │ │ │ │ ├── MogTileDownloader.kt
│ │ │ │ │ ├── MogTileMetadata.kt
│ │ │ │ │ ├── MogTileProvider.kt
│ │ │ │ │ ├── MogTileReader.kt
│ │ │ │ │ ├── MogTilesRequest.kt
│ │ │ │ │ ├── PixelBounds.kt
│ │ │ │ │ ├── PixelCoordinates.kt
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── SeekableInputStream.kt
│ │ │ │ │ ├── TiffTag.kt
│ │ │ │ │ ├── TiffTagDataType.kt
│ │ │ │ │ ├── TileCoordinates.kt
│ │ │ │ │ └── UrlInputStream.kt
│ │ │ ├── offlineareas
│ │ │ │ ├── OfflineAreaDetails.kt
│ │ │ │ ├── OfflineAreaListItem.kt
│ │ │ │ ├── OfflineAreasFragment.kt
│ │ │ │ ├── OfflineAreasViewModel.kt
│ │ │ │ ├── selector
│ │ │ │ │ ├── DownloadProgressDialog.kt
│ │ │ │ │ ├── OfflineAreaSelectorFragment.kt
│ │ │ │ │ ├── OfflineAreaSelectorViewModel.kt
│ │ │ │ │ └── UiState.kt
│ │ │ │ └── viewer
│ │ │ │ │ ├── OfflineAreaViewerFragment.kt
│ │ │ │ │ └── OfflineAreaViewerViewModel.kt
│ │ │ ├── settings
│ │ │ │ ├── Keys.kt
│ │ │ │ └── SettingsFragment.kt
│ │ │ ├── signin
│ │ │ │ ├── SignInFragment.kt
│ │ │ │ └── SignInViewModel.kt
│ │ │ ├── startup
│ │ │ │ ├── StartupFragment.kt
│ │ │ │ └── StartupViewModel.kt
│ │ │ ├── surveyselector
│ │ │ │ ├── SurveyListAdapter.kt
│ │ │ │ ├── SurveySelectorFragment.kt
│ │ │ │ ├── SurveySelectorViewModel.kt
│ │ │ │ └── UiState.kt
│ │ │ ├── syncstatus
│ │ │ │ ├── SyncListItem.kt
│ │ │ │ ├── SyncStatusDetail.kt
│ │ │ │ ├── SyncStatusFragment.kt
│ │ │ │ └── SyncStatusViewModel.kt
│ │ │ ├── theme
│ │ │ │ ├── Color.kt
│ │ │ │ └── Theme.kt
│ │ │ ├── tos
│ │ │ │ ├── TermsOfServiceFragment.kt
│ │ │ │ └── TermsOfServiceViewModel.kt
│ │ │ └── util
│ │ │ │ ├── BitmapUtil.kt
│ │ │ │ ├── ContextExt.kt
│ │ │ │ ├── FileUtil.kt
│ │ │ │ ├── LocaleAwareMeasureFormatter.kt
│ │ │ │ ├── PolygonUtil.kt
│ │ │ │ ├── RotateUsingExif.kt
│ │ │ │ ├── VibrationHelper.kt
│ │ │ │ └── ViewUtil.kt
│ │ │ ├── usecases
│ │ │ ├── datasharingterms
│ │ │ │ └── GetDataSharingTermsUseCase.kt
│ │ │ ├── submission
│ │ │ │ └── SubmitDataUseCase.kt
│ │ │ └── survey
│ │ │ │ ├── ActivateSurveyUseCase.kt
│ │ │ │ ├── ListAvailableSurveysUseCase.kt
│ │ │ │ ├── MakeSurveyAvailableOfflineUseCase.kt
│ │ │ │ ├── ReactivateLastSurveyUseCase.kt
│ │ │ │ ├── RemoveOfflineSurveyUseCase.kt
│ │ │ │ └── SyncSurveyUseCase.kt
│ │ │ └── util
│ │ │ ├── AsyncSingletonProvider.kt
│ │ │ ├── ComposeExt.kt
│ │ │ ├── CoordinatesExt.kt
│ │ │ ├── Debug.kt
│ │ │ ├── Enums.kt
│ │ │ ├── FileExt.kt
│ │ │ ├── FirebaseFirestoreExt.kt
│ │ │ ├── InsetExt.kt
│ │ │ ├── ListExt.kt
│ │ │ ├── MapExt.kt
│ │ │ ├── RangeExt.kt
│ │ │ ├── StrictModeExtensions.kt
│ │ │ └── ViewExt.kt
│ └── res
│ │ ├── color
│ │ ├── nav_drawer_item.xml
│ │ └── task_transparent_btn_selector.xml
│ │ ├── drawable-anydpi
│ │ ├── ic_arrow_back.xml
│ │ ├── ic_gps_lock.xml
│ │ ├── ic_history.xml
│ │ └── ic_more_vert.xml
│ │ ├── drawable-hdpi
│ │ ├── ground_logo.png
│ │ └── splash_background.png
│ │ ├── drawable
│ │ ├── baseline_check_24.xml
│ │ ├── baseline_close_24.xml
│ │ ├── baseline_hourglass_empty_24.xml
│ │ ├── baseline_menu_24.xml
│ │ ├── baseline_warning_24.xml
│ │ ├── cloud_off.xml
│ │ ├── cluster_marker.xml
│ │ ├── data_submitted.xml
│ │ ├── feed.xml
│ │ ├── green_gradient.xml
│ │ ├── ic_add.xml
│ │ ├── ic_circle_marker.xml
│ │ ├── ic_content_paste.xml
│ │ ├── ic_gps_lock_not_fixed.xml
│ │ ├── ic_maps_ar.xml
│ │ ├── ic_marker_fill.xml
│ │ ├── ic_marker_outline.xml
│ │ ├── ic_marker_overlay.xml
│ │ ├── ic_offline_pin.xml
│ │ ├── ic_photo_grey_600_24dp.xml
│ │ ├── ic_plus_sign.xml
│ │ ├── ic_question_answer.xml
│ │ ├── ic_redo_black.xml
│ │ ├── ic_ring_marker.xml
│ │ ├── ic_settings.xml
│ │ ├── ic_sync.xml
│ │ ├── ic_undo_black.xml
│ │ ├── info_outline.xml
│ │ ├── map_layers.xml
│ │ ├── map_type_roadmap.png
│ │ ├── map_type_satellite.png
│ │ ├── map_type_terrain.png
│ │ ├── offline_area_viewport_outline.xml
│ │ ├── offline_map_imagery.xml
│ │ ├── outline_done_all_24.xml
│ │ ├── outline_draw.xml
│ │ ├── outline_error_outline_24.xml
│ │ ├── outline_photo_camera.xml
│ │ ├── outline_pin_drop.xml
│ │ ├── swipe_24.xml
│ │ ├── task_light_green_btn_selector.xml
│ │ └── touch_app_24.xml
│ │ ├── font
│ │ ├── display_500.xml
│ │ ├── display_700.xml
│ │ ├── google_sans.ttf
│ │ ├── manrope_bold.ttf
│ │ ├── manrope_medium.ttf
│ │ ├── text_500.xml
│ │ ├── text_700.xml
│ │ ├── urbanist_bold.ttf
│ │ └── urbanist_medium.ttf
│ │ ├── layout
│ │ ├── basemap_layout.xml
│ │ ├── data_collection_frag.xml
│ │ ├── date_task_frag.xml
│ │ ├── fragment_draw_area_task.xml
│ │ ├── home_screen_frag.xml
│ │ ├── main_act.xml
│ │ ├── map_task_frag.xml
│ │ ├── map_type_dialog_fragment.xml
│ │ ├── map_type_dialog_item.xml
│ │ ├── menu_button.xml
│ │ ├── nav_drawer_header.xml
│ │ ├── offline_area_selector_frag.xml
│ │ ├── offline_area_viewer_frag.xml
│ │ ├── offline_areas_frag.xml
│ │ ├── photo_task.xml
│ │ ├── photo_task_frag.xml
│ │ ├── progress_dialog.xml
│ │ ├── settings_activity.xml
│ │ ├── sign_in_frag.xml
│ │ ├── startup_frag.xml
│ │ ├── survey_card_item.xml
│ │ ├── survey_selector_frag.xml
│ │ ├── sync_status_frag.xml
│ │ ├── task_frag_action_buttons.xml
│ │ ├── task_frag_with_combined_header.xml
│ │ ├── task_frag_with_header.xml
│ │ └── time_task_frag.xml
│ │ ├── menu
│ │ ├── nav_drawer_menu.xml
│ │ └── survey_options_menu.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_foreground.png
│ │ └── ic_launcher_round.png
│ │ ├── navigation
│ │ └── nav_graph.xml
│ │ ├── values-es
│ │ └── strings.xml
│ │ ├── values-fr
│ │ └── strings.xml
│ │ ├── values-night
│ │ └── colors.xml
│ │ ├── values-pt
│ │ └── strings.xml
│ │ ├── values
│ │ ├── arrays.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── strings-untranslated.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ │ └── xml
│ │ ├── file_paths.xml
│ │ └── preferences.xml
│ ├── staging
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── org
│ │ │ └── groundplatform
│ │ │ └── android
│ │ │ └── HiltTestActivity.kt
│ └── resources
│ │ └── jacoco-agent.properties
│ └── test
│ ├── java
│ └── org
│ │ └── groundplatform
│ │ └── android
│ │ ├── BaseHiltTest.kt
│ │ ├── FakeData.kt
│ │ ├── HiltExt.kt
│ │ ├── MainActivityTest.kt
│ │ ├── MainViewModelTest.kt
│ │ ├── PermissionDeniedDialogTest.kt
│ │ ├── RecyclerViewHelper.kt
│ │ ├── ResultAssertions.kt
│ │ ├── TestAuthenticationModule.kt
│ │ ├── TestCoroutineDispatchersModule.kt
│ │ ├── TestCoroutineScopesModule.kt
│ │ ├── TestLocalDatabaseModule.kt
│ │ ├── TestRemoteStorageModule.kt
│ │ ├── TestWorkManagerModule.kt
│ │ ├── TimberTestRule.kt
│ │ ├── UiTestHelper.kt
│ │ ├── model
│ │ ├── SurveyTest.kt
│ │ ├── geometry
│ │ │ └── GeometryTest.kt
│ │ └── task
│ │ │ └── ConditionTest.kt
│ │ ├── persistence
│ │ ├── local
│ │ │ ├── LocalLocationOfInterestStoreTest.kt
│ │ │ ├── LocalOfflineAreaStore.kt
│ │ │ ├── LocalSubmissionStoreTest.kt
│ │ │ ├── LocalSurveyStoreTest.kt
│ │ │ ├── LocalUserStoreTest.kt
│ │ │ └── room
│ │ │ │ └── converter
│ │ │ │ └── ValueJsonConverterTest.kt
│ │ ├── remote
│ │ │ ├── FakeRemoteDataStore.kt
│ │ │ ├── FakeRemoteStorageManager.kt
│ │ │ └── firebase
│ │ │ │ ├── FirebaseMessagingSurveyTest.kt
│ │ │ │ ├── FirestoreTestUtil.kt
│ │ │ │ ├── protobuf
│ │ │ │ ├── FirestoreToProtobufExtTest.kt
│ │ │ │ ├── LoiMutationConverterTest.kt
│ │ │ │ ├── ModelToProtoExtKtTest.kt
│ │ │ │ └── ProtobufToFirestoreExtTest.kt
│ │ │ │ └── schema
│ │ │ │ ├── AuditInfoConverterTest.kt
│ │ │ │ ├── ConditionConverterTest.kt
│ │ │ │ ├── GeometryConverterTest.kt
│ │ │ │ ├── JobConverterTest.kt
│ │ │ │ ├── LoiConverterTest.kt
│ │ │ │ ├── MultipleChoiceConverterTest.kt
│ │ │ │ ├── SubmissionMutationConverterTest.kt
│ │ │ │ ├── SurveyConverterTest.kt
│ │ │ │ ├── TaskConverterTest.kt
│ │ │ │ └── TermsOfServiceConverterTest.kt
│ │ ├── sync
│ │ │ ├── FakeWorkManager.kt
│ │ │ ├── LocalMutationSyncWorkerTest.kt
│ │ │ ├── MediaUploadWorkerTest.kt
│ │ │ ├── SurveySyncServiceTest.kt
│ │ │ └── SurveySyncWorkerTest.kt
│ │ └── uuid
│ │ │ └── FakeUuidGenerator.kt
│ │ ├── repository
│ │ ├── LocationOfInterestRepositoryTest.kt
│ │ ├── MapStateRepositoryTest.kt
│ │ ├── SurveyRepositoryTest.kt
│ │ ├── TermsOfServiceRepositoryTest.kt
│ │ ├── UserMediaRepositoryTest.kt
│ │ └── UserRepositoryTest.kt
│ │ ├── system
│ │ ├── GeocodingManagerTest.kt
│ │ ├── LocationManagerTest.kt
│ │ ├── PermissionsManagerTest.kt
│ │ ├── SettingsManagerTest.kt
│ │ └── auth
│ │ │ └── FakeAuthenticationManager.kt
│ │ ├── ui
│ │ ├── IconFactoryTest.kt
│ │ ├── common
│ │ │ └── LocationOfInterestHelperTest.kt
│ │ ├── datacollection
│ │ │ ├── DataCollectionFragmentTest.kt
│ │ │ ├── TaskDataHandlerTest.kt
│ │ │ ├── TaskFragmentRunner.kt
│ │ │ ├── TaskSequenceHandlerTest.kt
│ │ │ └── tasks
│ │ │ │ ├── BaseTaskFragmentTest.kt
│ │ │ │ ├── date
│ │ │ │ └── DateTaskFragmentTest.kt
│ │ │ │ ├── instruction
│ │ │ │ └── InstructionTaskFragmentTest.kt
│ │ │ │ ├── location
│ │ │ │ └── CaptureLocationTaskFragmentTest.kt
│ │ │ │ ├── multiplechoice
│ │ │ │ └── MultipleChoiceTaskFragmentTest.kt
│ │ │ │ ├── number
│ │ │ │ └── NumberTaskFragmentTest.kt
│ │ │ │ ├── photo
│ │ │ │ └── PhotoTaskFragmentTest.kt
│ │ │ │ ├── point
│ │ │ │ └── DropPinTaskFragmentTest.kt
│ │ │ │ ├── polygon
│ │ │ │ ├── DrawAreaTaskFragmentTest.kt
│ │ │ │ └── DrawAreaTaskViewModelTest.kt
│ │ │ │ ├── text
│ │ │ │ └── TextTaskFragmentTest.kt
│ │ │ │ └── time
│ │ │ │ └── TimeTaskFragmentTest.kt
│ │ ├── home
│ │ │ ├── AboutFragmentTest.kt
│ │ │ ├── DataSharingTermsDialogTest.kt
│ │ │ ├── HomeScreenFragmentTest.kt
│ │ │ └── mapcontainer
│ │ │ │ ├── HomeScreenMapContainerFragmentTest.kt
│ │ │ │ ├── HomeScreenMapContainerViewModelTest.kt
│ │ │ │ ├── MapTypeDialogFragmentTest.kt
│ │ │ │ └── jobs
│ │ │ │ └── LoiJobSheetTest.kt
│ │ ├── map
│ │ │ ├── CameraPositionTest.kt
│ │ │ └── gms
│ │ │ │ ├── FeatureClusterManagerTest.kt
│ │ │ │ └── mog
│ │ │ │ ├── MogCollectionTest.kt
│ │ │ │ ├── MogImageMetadataTest.kt
│ │ │ │ ├── MogSourceTest.kt
│ │ │ │ ├── MogTileMetadataTest.kt
│ │ │ │ ├── MogTileRequestTest.kt
│ │ │ │ ├── MogTileTest.kt
│ │ │ │ ├── PixelCoordinatesTest.kt
│ │ │ │ ├── SeekableBufferedInputStreamTest.kt
│ │ │ │ ├── SeekableInputStreamTest.kt
│ │ │ │ ├── TiffTagDataTypeTest.kt
│ │ │ │ ├── TiffTagTest.kt
│ │ │ │ └── TileCoordinatesTest.kt
│ │ ├── offlineareas
│ │ │ ├── OfflineAreasFragmentTest.kt
│ │ │ ├── selector
│ │ │ │ ├── DownloadProgressDialogTest.kt
│ │ │ │ └── OfflineAreaSelectorFragmentTest.kt
│ │ │ └── viewer
│ │ │ │ ├── OfflineAreaViewerFragmentTest.kt
│ │ │ │ └── OfflineAreaViewerViewModelTest.kt
│ │ ├── settings
│ │ │ └── SettingsFragmentTest.kt
│ │ ├── signin
│ │ │ └── SignInFragmentTest.kt
│ │ ├── surveyselector
│ │ │ └── SurveySelectorFragmentTest.kt
│ │ ├── syncstatus
│ │ │ └── SyncStatusFragmentTest.kt
│ │ ├── tos
│ │ │ └── TermsOfServiceFragmentTest.kt
│ │ └── util
│ │ │ └── LocaleAwareMeasureFormatterTest.kt
│ │ ├── usecases
│ │ ├── datasharingterms
│ │ │ └── GetDataSharingTermsUseCaseTest.kt
│ │ ├── submission
│ │ │ └── SubmitDataUseCaseTest.kt
│ │ └── survey
│ │ │ ├── ActivateSurveyUseCaseTest.kt
│ │ │ ├── ListAvailableSurveysUseCaseTest.kt
│ │ │ ├── MakeSurveyAvailableOfflineUseCaseTest.kt
│ │ │ ├── ReactivateLastSurveyUseCaseTest.kt
│ │ │ ├── RemoveOfflineSurveyUseCaseTest.kt
│ │ │ └── SyncSurveyUseCaseTest.kt
│ │ └── util
│ │ ├── CoordinatesExtTest.kt
│ │ ├── PolygonUtilTest.kt
│ │ ├── RangeExtTest.kt
│ │ └── view
│ │ └── ViewMatchers.kt
│ ├── proto
│ └── test.proto
│ └── resources
│ └── robolectric.properties
├── build.gradle
├── cloud-builder
└── sign
│ └── keystore
├── codecov.yml
├── config
├── checkstyle
│ ├── checkstyle.gradle
│ └── xml.header
├── detekt
│ ├── baseline.xml
│ ├── detekt.yml
│ └── license.template
├── jacoco
│ └── jacoco.gradle
└── lint
│ ├── lint.gradle
│ └── lint.xml
├── docs
├── android-architecture-diagram.png
└── architecture-docs.md
├── e2eTest
├── build.gradle
└── src
│ └── main
│ └── java
│ └── org
│ └── groundplatform
│ └── android
│ └── e2etest
│ ├── AutomatorRunner.kt
│ ├── SurveyRunnerTest.kt
│ └── TestConfig.kt
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.defaults.properties
├── settings.gradle
└── third_party
└── checkstyle
├── LICENSE
├── METADATA
└── google_checks.xml
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | charset = utf-8
3 | end_of_line = lf
4 | insert_final_newline = false
5 | indent_style = space
6 | indent_size = 4
7 |
8 | [{*.jhm,*.rng,*.wsdl,*.fxml,*.xslt,*.jrxml,*.ant,*.xul,*.xsl,*.xsd,*.tld,*.jnlp,*.xml}]
9 | indent_size = 2
10 |
11 | [*.json]
12 | indent_size = 2
13 |
14 | [*.java]
15 | indent_size = 2
16 |
17 | [{*.yaml,*.yml}]
18 | indent_size = 2
19 |
20 | [*.kt]
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a bug report to help us improve
4 | title: ''
5 | labels: 'type: bug'
6 | assignees: ''
7 | type: 'Bug'
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **App version**
14 | Android:
15 |
16 | **To Reproduce**
17 | Steps to reproduce the behavior:
18 | 1. Go to '...'
19 | 2. Click on '....'
20 | 3. Scroll down to '....'
21 | 4. See error
22 |
23 | **Expected behavior**
24 | A clear and concise description of what you expected to happen.
25 |
26 | **Actual behavior**
27 | A clear and concise description of what you actually saw happen.
28 |
29 | **Screenshots**
30 | If applicable, add screenshots to help explain your problem.
31 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/code-health.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Code health
3 | about: Code improvements, cleanup, and TODOs
4 | title: "[Code health] Description"
5 | labels: 'type: code health'
6 | assignees: ''
7 | type: 'Task'
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Request a new feature
4 | title: "[AppFeatureNameHere] Description"
5 | labels: 'priority: p2, type: feature request'
6 | assignees: ''
7 | type: 'Feature'
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Fixes #
5 |
6 |
7 |
8 |
14 |
15 |
16 |
17 |
18 |
19 | @... PTAL?
20 |
--------------------------------------------------------------------------------
/.github/workflows/test-submit.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2024 The Ground Authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | name: Submission Test
15 |
16 | on:
17 | issue_comment:
18 | types: [created]
19 |
20 | jobs:
21 | submitTest:
22 | if: github.event.issue.pull_request && contains(github.event.comment.body, '/submitTest')
23 | name: Submit to survey
24 | runs-on: ubuntu-latest
25 | timeout-minutes: 15
26 | steps:
27 | - name: Checkout code
28 | uses: actions/checkout@v4
29 | - name: Run submit-test
30 | uses: ./.github/actions/submit-test
31 | with:
32 | android-repository: ${{ github.repository }}
33 | google-maps-key: ${{ secrets.GOOGLE_MAPS_KEY }}
34 | use-repo-data: true
35 | upload-artifacts: false
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .*
2 | **/google-services.json
3 | secrets.properties
4 | !app/src/debug/local/google-services.json
5 | !.gitignore
6 | !gradle/
7 |
8 | # Taken from Android.gitignore https://github.com/github/gitignore/blob/master/Android.gitignore
9 | #
10 | # Built application files
11 | *.apk
12 | *.ap_
13 |
14 | # Files for the Dalvik VM
15 | *.dex
16 |
17 | # Java class files
18 | *.class
19 |
20 | # Generated files
21 | bin/
22 | gen/
23 | out/
24 |
25 | # Gradle files
26 | .gradle/
27 | build/
28 |
29 | # Local configuration file (sdk path, etc)
30 | local.properties
31 |
32 | # Proguard folder generated by Eclipse
33 | proguard/
34 |
35 | # Log Files
36 | *.log
37 |
38 | # Android Studio captures folder
39 | captures/
40 |
41 | # IntelliJ
42 | *.iml
43 |
44 | # Code styling configuration
45 | # https://github.com/google/styleguide/blob/gh-pages/intellij-java-google-style.xml
46 | !/.idea/codeStyles/
47 | !/.editorconfig
48 | !/.idea/externalDependencies.xml
49 | !/.idea/ktfmt.xml
50 |
51 | # Ctags
52 | **/tags
53 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/externalDependencies.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/ktfmt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/debug/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/app/src/debug/java/org/groundplatform/android/HiltTestActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android
17 |
18 | import dagger.hilt.android.AndroidEntryPoint
19 |
20 | @AndroidEntryPoint class HiltTestActivity : AbstractActivity()
21 |
--------------------------------------------------------------------------------
/app/src/debug/local/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "334087903719",
4 | "project_id": "local",
5 | "storage_bucket": "local.appspot.com"
6 | },
7 | "client": [
8 | {
9 | "client_info": {
10 | "mobilesdk_app_id": "1:334087903719:android:277f0bf3c1887739f40542",
11 | "android_client_info": {
12 | "package_name": "org.groundplatform.android"
13 | }
14 | },
15 | "oauth_client": [
16 | {
17 | "client_id": "local.apps.googleusercontent.com",
18 | "client_type": 3
19 | }
20 | ],
21 | "api_key": [
22 | {
23 | "current_key": "AIzaSyBKXBjsrQzgpbhgP9RwuOG6xWww83eKi_Q"
24 | }
25 | ],
26 | "services": {
27 | "appinvite_service": {
28 | "other_platform_oauth_client": []
29 | }
30 | }
31 | }
32 | ],
33 | "configuration_version": "1"
34 | }
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/debug/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 | #FFFFFF
21 |
--------------------------------------------------------------------------------
/app/src/debug/resources/jacoco-agent.properties:
--------------------------------------------------------------------------------
1 | output=none
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google/ground-android/60d4cc3ae9ba06d656d1e8161fa5f93a7c7e8b81/app/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/ExcludeFromJacocoGeneratedReport.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android
17 |
18 | // https://stackoverflow.com/questions/47824761/how-would-i-add-an-annotation-to-exclude-a-method-from-a-jacoco-code-coverage-re
19 | @Retention(AnnotationRetention.RUNTIME)
20 | @Target(AnnotationTarget.FUNCTION)
21 | annotation class ExcludeFromJacocoGeneratedReport
22 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/MainUiState.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.groundplatform.android
18 |
19 | sealed class MainUiState {
20 |
21 | data object OnPermissionDenied : MainUiState()
22 |
23 | data object OnUserSignedOut : MainUiState()
24 |
25 | data object OnUserSigningIn : MainUiState()
26 |
27 | data object TosNotAccepted : MainUiState()
28 |
29 | data object NoActiveSurvey : MainUiState()
30 |
31 | data object ShowHomeScreen : MainUiState()
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/SettingsActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android
17 |
18 | import android.os.Bundle
19 | import dagger.hilt.android.AndroidEntryPoint
20 | import org.groundplatform.android.databinding.SettingsActivityBinding
21 |
22 | @AndroidEntryPoint
23 | class SettingsActivity : AbstractActivity() {
24 | override fun onCreate(savedInstanceState: Bundle?) {
25 | super.onCreate(savedInstanceState)
26 |
27 | val binding = SettingsActivityBinding.inflate(layoutInflater)
28 | setContentView(binding.root)
29 |
30 | with(binding.settingsToolbar) {
31 | setSupportActionBar(this)
32 | setNavigationOnClickListener { finish() }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/Role.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model
17 |
18 | enum class Role {
19 | DATA_COLLECTOR,
20 | OWNER,
21 | SURVEY_ORGANIZER,
22 | VIEWER,
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/SurveyListItem.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.groundplatform.android.model
18 |
19 | data class SurveyListItem(
20 | val id: String,
21 | val title: String,
22 | val description: String,
23 | val availableOffline: Boolean,
24 | )
25 |
26 | fun Survey.toListItem(availableOffline: Boolean): SurveyListItem =
27 | SurveyListItem(id, title, description, availableOffline)
28 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/TermsOfService.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model
17 |
18 | /** If present in remote db, terms of service must be accepted by user after sign in. */
19 | data class TermsOfService(val id: String, val text: String?)
20 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/User.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model
17 |
18 | /** Represents a single application user. */
19 | data class User(
20 | val id: String,
21 | val email: String,
22 | val displayName: String,
23 | val photoUrl: String? = null,
24 | val isAnonymous: Boolean = false,
25 | )
26 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/geometry/Coordinates.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.geometry
17 |
18 | import kotlinx.serialization.Serializable
19 |
20 | /** A pair of latitude and longitude coordinates in decimal degrees. */
21 | @Serializable
22 | data class Coordinates(val lat: Double, val lng: Double) : Comparable {
23 | override fun compareTo(other: Coordinates): Int =
24 | compareValuesBy(this, other, { it.lat }, { it.lng })
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/geometry/InvalidGeometryException.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.geometry
17 |
18 | /**
19 | * Represents types of geometry errors.
20 | *
21 | * Typically thrown when a construction does not satisfy definitional constraints for a given
22 | * geometry.
23 | */
24 | class InvalidGeometryException(override val message: String) : Throwable(message)
25 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/imagery/OfflineArea.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.imagery
17 |
18 | import org.groundplatform.android.ui.map.Bounds
19 | import org.groundplatform.android.ui.map.gms.mog.TileCoordinates
20 |
21 | /** An area is a contiguous set of tiles that task a geodesic rectangle. */
22 | data class OfflineArea(
23 | val id: String,
24 | val state: State,
25 | val bounds: Bounds,
26 | val name: String,
27 | /** The range of zoom levels downloaded. */
28 | val zoomRange: IntRange,
29 | ) {
30 | val tiles
31 | get() = zoomRange.flatMap { TileCoordinates.withinBounds(bounds, it) }
32 |
33 | enum class State {
34 | PENDING,
35 | IN_PROGRESS,
36 | DOWNLOADED,
37 | FAILED,
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/imagery/TileSource.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.imagery
17 |
18 | import org.groundplatform.android.ui.map.Bounds
19 |
20 | /** Represents a single source of tiled map imagery. */
21 | sealed class TileSource
22 |
23 | data class LocalTileSource(val localFilePath: String, val clipBounds: List) : TileSource()
24 |
25 | data class RemoteMogTileSource(val remotePath: String) : TileSource()
26 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/job/Style.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.job
17 |
18 | data class Style(val color: String)
19 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/submission/CaptureLocationTaskData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.submission
17 |
18 | import org.groundplatform.android.model.geometry.Point
19 | import org.groundplatform.android.proto.Task
20 |
21 | /** User-provided response to a "capture location" data collection [Task]. */
22 | data class CaptureLocationTaskData(
23 | val location: Point,
24 | val altitude: Double?, // in metres
25 | val accuracy: Double?, // in metres
26 | ) : TaskData {
27 |
28 | override fun isEmpty(): Boolean = false
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/submission/DateTimeTaskData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.submission
17 |
18 | import kotlinx.serialization.Serializable
19 |
20 | /** A user-provided response to a date and time question task. */
21 | @Serializable
22 | data class DateTimeTaskData(val timeInMillis: Long) : TaskData {
23 |
24 | override fun isEmpty(): Boolean = timeInMillis == 0L
25 |
26 | companion object {
27 | fun fromMillis(timeInMillis: Long): TaskData = DateTimeTaskData(timeInMillis)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/submission/DraftSubmission.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.submission
17 |
18 | /** Represents a single instance of data being collected by the user. */
19 | data class DraftSubmission(
20 | val id: String,
21 | val jobId: String,
22 | val loiId: String?,
23 | val loiName: String?,
24 | val surveyId: String,
25 | val deltas: List,
26 | val currentTaskId: String?,
27 | )
28 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/submission/NumberTaskData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.submission
17 |
18 | import kotlinx.serialization.Serializable
19 |
20 | /** A user provided response to a number question task. */
21 | @Serializable
22 | data class NumberTaskData(val number: String) : TaskData {
23 | val value: Double
24 | get() = number.toDouble()
25 |
26 | override fun isEmpty(): Boolean = number.isEmpty()
27 |
28 | companion object {
29 | fun fromNumber(number: String): TaskData? =
30 | if (number.isEmpty() || number.toDoubleOrNull() == null) null else NumberTaskData(number)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/submission/PhotoTaskData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.submission
17 |
18 | import kotlinx.serialization.Serializable
19 | import org.groundplatform.android.model.job.Job
20 | import org.groundplatform.android.model.locationofinterest.LocationOfInterest
21 |
22 | /** Represents a single photo associated with a given [LocationOfInterest] and [Job]. */
23 | @Serializable
24 | class PhotoTaskData(val remoteFilename: String) : TaskData {
25 |
26 | override fun isEmpty(): Boolean = remoteFilename.isEmpty()
27 |
28 | override fun toString(): String = remoteFilename
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/submission/SkippedTaskData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2024 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.submission
17 |
18 | import kotlinx.serialization.Serializable
19 |
20 | /** User skipped the response for the given task. */
21 | @Serializable
22 | class SkippedTaskData : TaskData {
23 |
24 | override fun isEmpty(): Boolean = true
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/submission/TaskData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.submission
17 |
18 | /** User-provided value for a single data collection [Task]. */
19 | interface TaskData {
20 | fun isEmpty(): Boolean
21 | }
22 |
23 | fun TaskData?.isNullOrEmpty(): Boolean = this?.isEmpty() ?: true
24 |
25 | fun TaskData?.isNotNullOrEmpty(): Boolean = !this.isNullOrEmpty()
26 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/submission/TextTaskData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.submission
17 |
18 | import kotlinx.serialization.Serializable
19 |
20 | /** A user-provided value to a text question task. */
21 | @Serializable
22 | data class TextTaskData(val text: String) : TaskData {
23 | override fun isEmpty(): Boolean = text.trim { it <= ' ' }.isEmpty()
24 |
25 | companion object {
26 | fun fromString(text: String): TaskData? = if (text.isEmpty()) null else TextTaskData(text)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/submission/ValueDelta.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.submission
17 |
18 | import org.groundplatform.android.model.task.Task
19 |
20 | /**
21 | * Represents a change to an individual value in a submission.
22 | *
23 | * @property taskId the id of the task task being updated.
24 | * @property taskType the type of task being updated.
25 | * @property newTaskData the new value of the value, or empty if removed.
26 | */
27 | data class ValueDelta(val taskId: String, val taskType: Task.Type, val newTaskData: TaskData?)
28 |
--------------------------------------------------------------------------------
/app/src/main/java/org/groundplatform/android/model/task/MultipleChoice.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.groundplatform.android.model.task
17 |
18 | import kotlinx.collections.immutable.PersistentList
19 | import kotlinx.collections.immutable.persistentListOf
20 | import kotlinx.serialization.Serializable
21 |
22 | /** A question task with pre-defined options for the user to choose from. */
23 | @Serializable
24 | data class MultipleChoice
25 | @JvmOverloads
26 | constructor(
27 | val options: PersistentList