├── .nvmrc ├── .yarnrc.yml ├── jest.config.js ├── tsconfig.json ├── babel.config.js ├── app.json ├── android ├── app │ ├── debug.keystore │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── values │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ └── drawable │ │ │ │ │ └── rn_edit_text_material.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── quickstartreactnative │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ └── MainApplication.kt │ │ │ └── AndroidManifest.xml │ │ └── debug │ │ │ └── AndroidManifest.xml │ ├── proguard-rules.pro │ └── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── settings.gradle ├── build.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── .htfiles_manual ├── ios ├── QuickstartReactNative │ ├── Images.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── PrivacyInfo.xcprivacy │ ├── Info.plist │ └── LaunchScreen.storyboard ├── QuickstartReactNative.xcworkspace │ └── contents.xcworkspacedata ├── .xcode.env ├── Podfile ├── QuickstartReactNative.xcodeproj │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── QuickstartReactNative.xcscheme │ └── project.pbxproj └── Podfile.lock ├── .prettierrc.js ├── index.js ├── index.native.js ├── src ├── index.web.js └── App.tsx ├── .htfiles ├── metro.config.js ├── Gemfile ├── scripts └── update_file.sh ├── .eslintrc.js ├── CONTRIBUTING.md ├── LICENSE ├── .gitignore ├── package.json ├── .githooks └── pre-push ├── README.md └── justfile /.nvmrc: -------------------------------------------------------------------------------- 1 | v18 2 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@react-native/typescript-config/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "QuickstartReactNative", 3 | "displayName": "Quickstart React Native" 4 | } 5 | -------------------------------------------------------------------------------- /android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/app/debug.keystore -------------------------------------------------------------------------------- /.htfiles_manual: -------------------------------------------------------------------------------- 1 | android/app/build.gradle 2 | android/build.gradle 3 | android/gradle.properties 4 | ios/Podfile 5 | package.json 6 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | QuickstartReactNative 3 | 4 | -------------------------------------------------------------------------------- /ios/QuickstartReactNative/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hypertrack/quickstart-react-native/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import {AppRegistry} from 'react-native'; 2 | import App from './src/App'; 3 | import {name as appName} from './app.json'; 4 | 5 | AppRegistry.registerComponent(appName, () => App); 6 | -------------------------------------------------------------------------------- /index.native.js: -------------------------------------------------------------------------------- 1 | import {AppRegistry} from 'react-native'; 2 | import App from './src/App'; 3 | import {name as appName} from './app.json'; 4 | 5 | AppRegistry.registerComponent(appName, () => App); 6 | -------------------------------------------------------------------------------- /src/index.web.js: -------------------------------------------------------------------------------- 1 | import {AppRegistry} from 'react-native'; 2 | import App from './App'; 3 | 4 | AppRegistry.registerComponent('App', () => App); 5 | 6 | AppRegistry.runApplication('App', { 7 | rootTag: document.getElementById('root'), 8 | }); 9 | -------------------------------------------------------------------------------- /.htfiles: -------------------------------------------------------------------------------- 1 | android/app/src/main/AndroidManifest.xml 2 | ios/QuickstartReactNative/Info.plist 3 | src/App.tsx 4 | .eslintrc.js 5 | .prettierrc.js 6 | .yarnrc.yml 7 | app.json 8 | README.md 9 | .nvmrc 10 | android/app/google-services.json 11 | index.native.js 12 | src/index.web.js 13 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /ios/QuickstartReactNative.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); 2 | 3 | /** 4 | * Metro configuration 5 | * https://reactnative.dev/docs/metro 6 | * 7 | * @type {import('@react-native/metro-config').MetroConfig} 8 | */ 9 | const config = {}; 10 | 11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config); 12 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } 2 | plugins { id("com.facebook.react.settings") } 3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } 4 | rootProject.name = 'QuickstartReactNative' 5 | include ':app' 6 | includeBuild('../node_modules/@react-native/gradle-plugin') 7 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | # Exclude problematic versions of cocoapods and activesupport that causes build failures. 7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' 8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' 9 | gem 'xcodeproj', '< 1.26.0' 10 | gem 'concurrent-ruby', '< 1.3.4' 11 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /scripts/update_file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Check if params are provided 5 | if [ $# -ne 3 ]; then 6 | echo "Usage: $0 " 7 | exit 1 8 | fi 9 | 10 | echo "Updating $2 to $3 in $1" 11 | 12 | file="$1" 13 | source_text="$2" 14 | new_text="$3" 15 | 16 | if [ ! -f "$file" ]; then 17 | echo "Error: $file not found." 18 | exit 1 19 | fi 20 | 21 | cat $file | sed "s/$source_text/$new_text/" >tmp 22 | cat tmp >$file 23 | rm -f tmp 24 | 25 | echo "Updated $source_text in $file to $new_text" 26 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | parser: '@typescript-eslint/parser', 5 | plugins: ['@typescript-eslint'], 6 | overrides: [ 7 | { 8 | files: ['*.ts', '*.tsx'], 9 | rules: { 10 | '@typescript-eslint/no-shadow': ['error'], 11 | 'no-shadow': 'off', 12 | 'no-undef': 'off', 13 | '@typescript-eslint/no-unused-vars': 'off', 14 | 'react-hooks/exhaustive-deps': 'off', 15 | 'prettier/prettier': 'off', 16 | }, 17 | }, 18 | ], 19 | }; 20 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "35.0.0" 4 | minSdkVersion = 24 5 | compileSdkVersion = 35 6 | targetSdkVersion = 34 7 | ndkVersion = "27.1.12297006" 8 | kotlinVersion = "1.6.21" 9 | } 10 | repositories { 11 | google() 12 | jcenter() 13 | mavenCentral() 14 | } 15 | dependencies { 16 | classpath("com.android.tools.build:gradle") 17 | classpath("com.facebook.react:react-native-gradle-plugin") 18 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}") 19 | classpath("com.google.gms:google-services:4.3.13") 20 | } 21 | } 22 | 23 | apply plugin: "com.facebook.react.rootproject" 24 | 25 | allprojects { 26 | repositories { 27 | maven { 28 | name 'hypertrack' 29 | url 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/' 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | ## FAQ 4 | 5 | ### How to update HyperTrack SDK wrapper version? 6 | 7 | Update the [package.json](./package.json) according to [Install guide](https://hypertrack.com/docs/install-sdk-react-native#add-hypertrack-sdk-to-your-project) 8 | 9 | ### How to run with local build of the SDK? 10 | 11 | Run `just al`. This command will look for local SDK repo in `../sdk-react-native`. It will override the `node_modules` content of `../sdk-react-native/sdk` to avoid conflicts with the `devDependencies` of the SDK. 12 | 13 | ### How to change build config? 14 | 15 | React Native version: `package.json` - `react-native` 16 | 17 | #### Android 18 | 19 | - `android/build.gradle` - `ext.buildscript` 20 | - compileSdkVersion 21 | - targetSdkVersion 22 | - minSdkVersion 23 | 24 | ### How to get logs 25 | 26 | You can see native logs with according native IDE. 27 | 28 | React Native logs are printed in Metro UI. Run `npx react-native start` to open it. 29 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/quickstartreactnative/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.quickstartreactnative 2 | 3 | import com.facebook.react.ReactActivity 4 | import com.facebook.react.ReactActivityDelegate 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate 7 | 8 | class MainActivity : ReactActivity() { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | override fun getMainComponentName(): String = "QuickstartReactNative" 15 | 16 | /** 17 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] 18 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] 19 | */ 20 | override fun createReactActivityDelegate(): ReactActivityDelegate = 21 | DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) 22 | } 23 | -------------------------------------------------------------------------------- /ios/QuickstartReactNative/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import React 3 | import React_RCTAppDelegate 4 | import ReactAppDependencyProvider 5 | 6 | @main 7 | class AppDelegate: RCTAppDelegate { 8 | override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { 9 | self.moduleName = "QuickstartReactNative" 10 | self.dependencyProvider = RCTAppDependencyProvider() 11 | 12 | // You can add your custom initial props in the dictionary below. 13 | // They will be passed down to the ViewController used by React Native. 14 | self.initialProps = [:] 15 | 16 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 17 | } 18 | 19 | override func sourceURL(for bridge: RCTBridge) -> URL? { 20 | self.bundleURL() 21 | } 22 | 23 | override func bundleURL() -> URL? { 24 | #if DEBUG 25 | RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index") 26 | #else 27 | Bundle.main.url(forResource: "main", withExtension: "jsbundle") 28 | #endif 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 HyperTrack 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ios/QuickstartReactNative/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ios/QuickstartReactNative/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPIType 9 | NSPrivacyAccessedAPICategoryFileTimestamp 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | C617.1 13 | 14 | 15 | 16 | NSPrivacyAccessedAPIType 17 | NSPrivacyAccessedAPICategoryUserDefaults 18 | NSPrivacyAccessedAPITypeReasons 19 | 20 | CA92.1 21 | 22 | 23 | 24 | NSPrivacyAccessedAPIType 25 | NSPrivacyAccessedAPICategorySystemBootTime 26 | NSPrivacyAccessedAPITypeReasons 27 | 28 | 35F9.1 29 | 30 | 31 | 32 | NSPrivacyCollectedDataTypes 33 | 34 | NSPrivacyTracking 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | google-services.json 3 | /.vscode 4 | update_storage/ 5 | rn_files.txt 6 | 7 | # OSX 8 | # 9 | .DS_Store 10 | 11 | # Xcode 12 | # 13 | build/ 14 | *.pbxuser 15 | !default.pbxuser 16 | *.mode1v3 17 | !default.mode1v3 18 | *.mode2v3 19 | !default.mode2v3 20 | *.perspectivev3 21 | !default.perspectivev3 22 | xcuserdata 23 | *.xccheckout 24 | *.moved-aside 25 | DerivedData 26 | *.hmap 27 | *.ipa 28 | *.xcuserstate 29 | ios/.xcode.env.local 30 | 31 | # Android/IntelliJ 32 | # 33 | build/ 34 | .idea 35 | .gradle 36 | local.properties 37 | *.iml 38 | *.hprof 39 | .cxx/ 40 | 41 | # node.js 42 | # 43 | node_modules/ 44 | npm-debug.log 45 | yarn-error.log 46 | .yarn/* 47 | 48 | # BUCK 49 | buck-out/ 50 | \.buckd/ 51 | *.keystore 52 | !debug.keystore 53 | 54 | # fastlane 55 | # 56 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 57 | # screenshots whenever they are needed. 58 | # For more information about the recommended setup visit: 59 | # https://docs.fastlane.tools/best-practices/source-control/ 60 | 61 | **/fastlane/report.xml 62 | **/fastlane/Preview.html 63 | **/fastlane/screenshots 64 | **/fastlane/test_output 65 | 66 | # Bundle artifact 67 | *.jsbundle 68 | 69 | # Ruby / CocoaPods 70 | /ios/Pods/ 71 | /vendor/bundle/ 72 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hypertrack-quickstart-reactnative", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "lint": "eslint .", 9 | "start": "react-native start", 10 | "test": "jest" 11 | }, 12 | "dependencies": { 13 | "hypertrack-sdk-react-native": "14.0.3", 14 | "hypertrack-sdk-react-native-plugin-android-activity-service-google": "14.0.3", 15 | "hypertrack-sdk-react-native-plugin-android-location-services-google": "14.0.3", 16 | "hypertrack-sdk-react-native-plugin-android-push-service-firebase": "14.0.3", 17 | "react": "18.3.1", 18 | "react-native": "0.77.1", 19 | "react-native-permissions": "^4.1.5" 20 | }, 21 | "devDependencies": { 22 | "@babel/core": "^7.25.2", 23 | "@babel/preset-env": "^7.25.3", 24 | "@babel/runtime": "^7.25.0", 25 | "@react-native-community/cli": "15.0.1", 26 | "@react-native-community/cli-platform-android": "15.0.1", 27 | "@react-native-community/cli-platform-ios": "15.0.1", 28 | "@react-native/babel-preset": "0.77.1", 29 | "@react-native/eslint-config": "0.77.1", 30 | "@react-native/metro-config": "0.77.1", 31 | "@react-native/typescript-config": "0.77.1", 32 | "@types/jest": "^29.5.13", 33 | "@types/react": "^18.2.6", 34 | "@types/react-test-renderer": "^18.0.0", 35 | "eslint": "^8.19.0", 36 | "jest": "^29.6.3", 37 | "prettier": "2.8.8", 38 | "react-test-renderer": "18.3.1", 39 | "typescript": "5.0.4" 40 | }, 41 | "engines": { 42 | "node": ">=18" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/quickstartreactnative/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.quickstartreactnative 2 | 3 | import android.app.Application 4 | import com.facebook.react.PackageList 5 | import com.facebook.react.ReactApplication 6 | import com.facebook.react.ReactHost 7 | import com.facebook.react.ReactNativeHost 8 | import com.facebook.react.ReactPackage 9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load 10 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost 11 | import com.facebook.react.defaults.DefaultReactNativeHost 12 | import com.facebook.react.soloader.OpenSourceMergedSoMapping 13 | import com.facebook.soloader.SoLoader 14 | import com.quickstartreactnative.BuildConfig 15 | 16 | class MainApplication : Application(), ReactApplication { 17 | 18 | override val reactNativeHost: ReactNativeHost = 19 | object : DefaultReactNativeHost(this) { 20 | override fun getPackages(): List = 21 | PackageList(this).packages.apply { 22 | // Packages that cannot be autolinked yet can be added manually here, for example: 23 | // add(MyReactNativePackage()) 24 | } 25 | 26 | override fun getJSMainModuleName(): String = "index" 27 | 28 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 29 | 30 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 31 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 32 | } 33 | 34 | override val reactHost: ReactHost 35 | get() = getDefaultReactHost(applicationContext, reactNativeHost) 36 | 37 | override fun onCreate() { 38 | super.onCreate() 39 | SoLoader.init(this, OpenSourceMergedSoMapping) 40 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 41 | // If you opted-in for the New Architecture, we load the native entry point for this app. 42 | load() 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m -XX:MaxHeapSize=8g 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Use this property to specify which architecture you want to build. 28 | # You can also override it from the CLI using 29 | # ./gradlew -PreactNativeArchitectures=x86_64 30 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 31 | 32 | # Use this property to enable support to the new architecture. 33 | # This will allow you to use TurboModules and the Fabric render in 34 | # your application. You should enable this flag either if you want 35 | # to write custom TurboModules/Fabric components OR use libraries that 36 | # are providing them. 37 | newArchEnabled=true 38 | 39 | # Use this property to enable or disable the Hermes JS engine. 40 | # If set to false, you will be using JSC instead. 41 | hermesEnabled=true 42 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 22 | 23 | 24 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /.githooks/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | check_error="Git hook check error" 4 | 5 | # Check if there are any local dependencies in the package.json file 6 | local_deps=$(grep -E "file:.*\..*" package.json) 7 | 8 | # If local dependencies are found, exit with an error message 9 | if [ "$local_deps" ]; then 10 | echo "$check_error: Local dependencies found in package.json: \n\n $local_deps \n\n Push blocked to prevent committing local dependencies." 11 | exit 1 12 | fi 13 | 14 | # Check if there are any Github dependencies in the package.json file 15 | github_deps=$(grep -E "https://github.com" package.json) 16 | 17 | # If github dependencies are found, exit with an error message 18 | if [ "$github_deps" ]; then 19 | echo "$check_error: Github dependencies found in package.json: \n\n $github_deps \n\n Push blocked to prevent committing Github dependencies." 20 | exit 1 21 | fi 22 | 23 | if grep -q "'.\{86\}'" "src/App.tsx"; then 24 | echo "$check_error: PUBLISHABLE_KEY is set" 25 | exit 1 26 | fi 27 | 28 | if ! grep -q "value=\"Paste_your_publishable_key_here" "android/app/src/main/AndroidManifest.xml"; then 29 | echo "$check_error: PUBLISHABLE_KEY is probably set ('Paste_your_publishable_key_here' not found in AndroidManifest)" 30 | exit 1 31 | fi 32 | 33 | if ! grep -q "Paste_your_publishable_key_here" "ios/QuickstartReactNative/Info.plist"; then 34 | echo "$check_error: PUBLISHABLE_KEY is probably set ('Paste_your_publishable_key_here' not found in Info.plist)" 35 | exit 1 36 | fi 37 | 38 | xcode_project_config_path="ios/QuickstartReactNative.xcodeproj/project.pbxproj" 39 | 40 | # Check if the xcodeproj command line tool is installed 41 | if ! type "xcodeproj" >/dev/null; then 42 | echo "$check_error: The xcodeproj command line tool is not installed. Unable to check if the development team is set up." 43 | else 44 | # Check if the project file exists 45 | if [ ! -f $xcode_project_config_path ]; then 46 | echo "$check_error: The project file '$xcode_project_config_path' does not exist." 47 | exit 1 48 | fi 49 | 50 | # Check if the development team is set up 51 | if cat $xcode_project_config_path | grep -q -E 'DEVELOPMENT_TEAM\s*=\s*[A-Z0-9]{10}'; then 52 | echo "$check_error: iOS Development team is set up." 53 | exit 1 54 | fi 55 | fi 56 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # react-native-permissions replaces 'Resolve react_native_pods.rb with node to allow for hoisting' 2 | # section to this: 3 | # Resolve react_native_pods.rb with node to allow for hoisting 4 | def node_require(script) 5 | # Resolve script with node to allow for hoisting 6 | require Pod::Executable.execute_command('node', ['-p', 7 | "require.resolve( 8 | '#{script}', 9 | {paths: [process.argv[1]]}, 10 | )", __dir__]).strip 11 | end 12 | 13 | # Use it to require both react-native's and this package's scripts: 14 | node_require('react-native/scripts/react_native_pods.rb') 15 | node_require('react-native-permissions/scripts/setup.rb') 16 | 17 | platform :ios, min_ios_version_supported 18 | prepare_react_native_project! 19 | 20 | setup_permissions([ 21 | # 'AppTrackingTransparency', 22 | # 'Bluetooth', 23 | # 'Calendars', 24 | # 'CalendarsWriteOnly', 25 | # 'Camera', 26 | # 'Contacts', 27 | # 'FaceID', 28 | # 'LocationAccuracy', 29 | 'LocationAlways', 30 | 'LocationWhenInUse', 31 | # 'MediaLibrary', 32 | # 'Microphone', 33 | 'Motion', 34 | # 'Notifications', 35 | # 'PhotoLibrary', 36 | # 'PhotoLibraryAddOnly', 37 | # 'Reminders', 38 | # 'Siri', 39 | # 'SpeechRecognition', 40 | # 'StoreKit', 41 | ]) 42 | 43 | ENV['RCT_NEW_ARCH_ENABLED'] = '1' 44 | 45 | linkage = ENV['USE_FRAMEWORKS'] 46 | if linkage != nil 47 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 48 | use_frameworks! :linkage => linkage.to_sym 49 | end 50 | 51 | target 'QuickstartReactNative' do 52 | config = use_native_modules! 53 | 54 | # Flags change depending on the env values. 55 | flags = get_default_flags() 56 | 57 | use_react_native!( 58 | :path => config[:reactNativePath], 59 | # Hermes is now enabled by default. Disable by setting this flag to false. 60 | :hermes_enabled => flags[:hermes_enabled], 61 | :fabric_enabled => flags[:fabric_enabled], 62 | # An absolute path to your application root. 63 | :app_path => "#{Pod::Config.instance.installation_root}/.." 64 | ) 65 | 66 | post_install do |installer| 67 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 68 | react_native_post_install( 69 | installer, 70 | config[:reactNativePath], 71 | :mac_catalyst_enabled => false 72 | ) 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Native Quickstart for HyperTrack SDK 2 | 3 | [![GitHub](https://img.shields.io/github/license/hypertrack/quickstart-react-native?color=orange)](./LICENSE) 4 | [![Github](https://img.shields.io/badge/hypertrack_sdk_react_native-11.0.0-brightgreen.svg)](https://github.com/hypertrack/sdk-react-native) 5 | 6 | [HyperTrack](https://www.hypertrack.com/) lets you add live location tracking to your mobile app. Live location is made available along with ongoing activity, tracking controls and tracking outage with reasons. 7 | 8 | This repo contains an example React Native app that has everything you need to get started. 9 | 10 | For information about how to get started with React Native SDK, please check this [Guide](https://www.hypertrack.com/docs/install-sdk-react-native). 11 | 12 | ## How to get started? 13 | 14 | ### Create HyperTrack Account 15 | 16 | [Sign up](https://dashboard.hypertrack.com/signup) for HyperTrack and get your publishable key from the [Setup page](https://dashboard.hypertrack.com/setup). 17 | 18 | ### Setup the environment 19 | 20 | You need to [set up the development environment for React Native](https://reactnative.dev/docs/environment-setup) 21 | 22 | ### Setup the project 23 | 24 | - run `yarn` 25 | - run `npx pod install` 26 | 27 | ### Set your publishable key 28 | 29 | Follow the [instructions on setting up publishable key](https://hypertrack.com/docs/install-sdk-react-native#set-the-publishable-key) in our docs 30 | 31 | ### Setup silent push notifications 32 | 33 | Follow the [instructions on setting up silent push notifications](https://hypertrack.com/docs/install-sdk-react-native/#set-up-silent-push-notifications) in our docs. 34 | 35 | HyperTrack SDK needs Firebase Cloud Messaging and APNS to manage on-device tracking as well as enable using HyperTrack cloud APIs from your server to control the tracking. 36 | 37 | ### Run the app 38 | 39 | - Android: run `npx react-native run-android` 40 | - iOS: run `npx react-native run-ios` 41 | 42 | ### Grant permissions 43 | 44 | [Grant required permissions to the app](https://hypertrack.com/docs/install-sdk-react-native#grant-the-permissions-to-the-app) 45 | 46 | ### Start tracking 47 | 48 | Press `Start tracking` button. 49 | 50 | To see the device on a map, open the [HyperTrack dashboard](https://dashboard.hypertrack.com/). 51 | 52 | The app will create a driver with driver handle `test_driver_quickstart_react_native_` 53 | 54 | ## Support 55 | 56 | Join our [Slack community](https://join.slack.com/t/hypertracksupport/shared_invite/enQtNDA0MDYxMzY1MDMxLTdmNDQ1ZDA1MTQxOTU2NTgwZTNiMzUyZDk0OThlMmJkNmE0ZGI2NGY2ZGRhYjY0Yzc0NTJlZWY2ZmE5ZTA2NjI) for instant responses. You can also email us at help@hypertrack.com 57 | -------------------------------------------------------------------------------- /ios/QuickstartReactNative/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HyperTrackPublishableKey 6 | Paste_your_publishable_key_here 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleDisplayName 10 | QuickstartReactNative 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | $(MARKETING_VERSION) 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | $(CURRENT_PROJECT_VERSION) 27 | LSRequiresIPhoneOS 28 | 29 | NSAppTransportSecurity 30 | 31 | 32 | NSAllowsArbitraryLoads 33 | 34 | NSAllowsLocalNetworking 35 | 36 | NSExceptionDomains 37 | 38 | localhost 39 | 40 | NSExceptionAllowsInsecureHTTPLoads 41 | 42 | 43 | 44 | 45 | NSLocationAlwaysAndWhenInUseUsageDescription 46 | To let your friends and family track you live, you need to allow HyperTrack Live to access this device's location 47 | NSLocationAlwaysUsageDescription 48 | To let your friends and family track you live, you need to allow HyperTrack Live to access this device's location 49 | NSLocationWhenInUseUsageDescription 50 | To let your friends and family track you live, you need to allow HyperTrack Live to access this device's location 51 | NSMotionUsageDescription 52 | To track your movement accurately, HyperTrack Live needs to access motion sensors 53 | UIBackgroundModes 54 | 55 | location 56 | remote-notification 57 | 58 | UILaunchStoryboardName 59 | LaunchScreen 60 | UIRequiredDeviceCapabilities 61 | 62 | armv7 63 | 64 | UISupportedInterfaceOrientations 65 | 66 | UIInterfaceOrientationPortrait 67 | UIInterfaceOrientationLandscapeLeft 68 | UIInterfaceOrientationLandscapeRight 69 | 70 | UIViewControllerBasedStatusBarAppearance 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /ios/QuickstartReactNative.xcodeproj/xcshareddata/xcschemes/QuickstartReactNative.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /ios/QuickstartReactNative/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "org.jetbrains.kotlin.android" 3 | apply plugin: "com.facebook.react" 4 | apply plugin: "com.google.gms.google-services" 5 | 6 | /** 7 | * This is the configuration block to customize your React Native Android app. 8 | * By default you don't need to apply any configuration, just uncomment the lines you need. 9 | */ 10 | react { 11 | /* Folders */ 12 | // The root of your project, i.e. where "package.json" lives. Default is '../..' 13 | // root = file("../../") 14 | // The folder where the react-native NPM package is. Default is ../../node_modules/react-native 15 | // reactNativeDir = file("../../node_modules/react-native") 16 | // The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen 17 | // codegenDir = file("../../node_modules/@react-native/codegen") 18 | // The cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js 19 | // cliFile = file("../../node_modules/react-native/cli.js") 20 | 21 | /* Variants */ 22 | // The list of variants to that are debuggable. For those we're going to 23 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 24 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 25 | // debuggableVariants = ["liteDebug", "prodDebug"] 26 | 27 | /* Bundling */ 28 | // A list containing the node command and its flags. Default is just 'node'. 29 | // nodeExecutableAndArgs = ["node"] 30 | // 31 | // The command to run when bundling. By default is 'bundle' 32 | // bundleCommand = "ram-bundle" 33 | // 34 | // The path to the CLI configuration file. Default is empty. 35 | // bundleConfig = file(../rn-cli.config.js) 36 | // 37 | // The name of the generated asset file containing your JS bundle 38 | // bundleAssetName = "MyApplication.android.bundle" 39 | // 40 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 41 | // entryFile = file("../js/MyApplication.android.js") 42 | // 43 | // A list of extra flags to pass to the 'bundle' commands. 44 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 45 | // extraPackagerArgs = [] 46 | 47 | /* Hermes Commands */ 48 | // The hermes compiler command to run. By default it is 'hermesc' 49 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 50 | // 51 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 52 | // hermesFlags = ["-O", "-output-source-map"] 53 | 54 | /* Autolinking */ 55 | autolinkLibrariesWithApp() 56 | } 57 | 58 | /** 59 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 60 | */ 61 | def enableProguardInReleaseBuilds = false 62 | 63 | /** 64 | * The preferred build flavor of JavaScriptCore (JSC) 65 | * 66 | * For example, to use the international variant, you can use: 67 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 68 | * 69 | * The international variant includes ICU i18n library and necessary data 70 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 71 | * give correct results when using with locales other than en-US. Note that 72 | * this variant is about 6MiB larger per architecture than default. 73 | */ 74 | def jscFlavor = 'org.webkit:android-jsc:+' 75 | 76 | android { 77 | ndkVersion rootProject.ext.ndkVersion 78 | buildToolsVersion rootProject.ext.buildToolsVersion 79 | compileSdk rootProject.ext.compileSdkVersion 80 | 81 | // we don't use variable because React Native parses this value on build 82 | namespace "com.quickstartreactnative" 83 | 84 | defaultConfig { 85 | applicationId "com.hypertrack.quickstart.reactnative.android" 86 | minSdkVersion rootProject.ext.minSdkVersion 87 | targetSdkVersion rootProject.ext.targetSdkVersion 88 | versionCode 1 89 | versionName "1.0" 90 | } 91 | signingConfigs { 92 | debug { 93 | storeFile file('debug.keystore') 94 | storePassword 'android' 95 | keyAlias 'androiddebugkey' 96 | keyPassword 'android' 97 | } 98 | } 99 | buildTypes { 100 | debug { 101 | signingConfig signingConfigs.debug 102 | } 103 | release { 104 | // Caution! In production, you need to generate your own keystore file. 105 | // see https://reactnative.dev/docs/signed-apk-android. 106 | signingConfig signingConfigs.debug 107 | minifyEnabled enableProguardInReleaseBuilds 108 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 109 | } 110 | } 111 | packagingOptions { 112 | pickFirst 'lib/x86/libc++_shared.so' 113 | pickFirst 'lib/x86_64/libc++_shared.so' 114 | pickFirst 'lib/armeabi-v7a/libc++_shared.so' 115 | pickFirst 'lib/arm64-v8a/libc++_shared.so' 116 | } 117 | } 118 | 119 | dependencies { 120 | // The version of react-native is set by the React Native Gradle Plugin 121 | implementation("com.facebook.react:react-android") 122 | 123 | if (hermesEnabled.toBoolean()) { 124 | implementation("com.facebook.react:hermes-android") 125 | } else { 126 | implementation jscFlavor 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # SPDX-License-Identifier: Apache-2.0 19 | # 20 | 21 | ############################################################################## 22 | # 23 | # Gradle start up script for POSIX generated by Gradle. 24 | # 25 | # Important for running: 26 | # 27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 28 | # noncompliant, but you have some other compliant shell such as ksh or 29 | # bash, then to run this script, type that shell name before the whole 30 | # command line, like: 31 | # 32 | # ksh Gradle 33 | # 34 | # Busybox and similar reduced shells will NOT work, because this script 35 | # requires all of these POSIX shell features: 36 | # * functions; 37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 39 | # * compound commands having a testable exit status, especially «case»; 40 | # * various built-in commands including «command», «set», and «ulimit». 41 | # 42 | # Important for patching: 43 | # 44 | # (2) This script targets any POSIX shell, so it avoids extensions provided 45 | # by Bash, Ksh, etc; in particular arrays are avoided. 46 | # 47 | # The "traditional" practice of packing multiple parameters into a 48 | # space-separated string is a well documented source of bugs and security 49 | # problems, so this is (mostly) avoided, by progressively accumulating 50 | # options in "$@", and eventually passing that to Java. 51 | # 52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 54 | # see the in-line comments for details. 55 | # 56 | # There are tweaks for specific operating systems such as AIX, CygWin, 57 | # Darwin, MinGW, and NonStop. 58 | # 59 | # (3) This script is generated from the Groovy template 60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 61 | # within the Gradle project. 62 | # 63 | # You can find Gradle at https://github.com/gradle/gradle/. 64 | # 65 | ############################################################################## 66 | 67 | # Attempt to set APP_HOME 68 | 69 | # Resolve links: $0 may be a link 70 | app_path=$0 71 | 72 | # Need this for daisy-chained symlinks. 73 | while 74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 75 | [ -h "$app_path" ] 76 | do 77 | ls=$( ls -ld "$app_path" ) 78 | link=${ls#*' -> '} 79 | case $link in #( 80 | /*) app_path=$link ;; #( 81 | *) app_path=$APP_HOME$link ;; 82 | esac 83 | done 84 | 85 | # This is normally unused 86 | # shellcheck disable=SC2034 87 | APP_BASE_NAME=${0##*/} 88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s 90 | ' "$PWD" ) || exit 91 | 92 | # Use the maximum available, or set MAX_FD != -1 to use that value. 93 | MAX_FD=maximum 94 | 95 | warn () { 96 | echo "$*" 97 | } >&2 98 | 99 | die () { 100 | echo 101 | echo "$*" 102 | echo 103 | exit 1 104 | } >&2 105 | 106 | # OS specific support (must be 'true' or 'false'). 107 | cygwin=false 108 | msys=false 109 | darwin=false 110 | nonstop=false 111 | case "$( uname )" in #( 112 | CYGWIN* ) cygwin=true ;; #( 113 | Darwin* ) darwin=true ;; #( 114 | MSYS* | MINGW* ) msys=true ;; #( 115 | NONSTOP* ) nonstop=true ;; 116 | esac 117 | 118 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 119 | 120 | 121 | # Determine the Java command to use to start the JVM. 122 | if [ -n "$JAVA_HOME" ] ; then 123 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 124 | # IBM's JDK on AIX uses strange locations for the executables 125 | JAVACMD=$JAVA_HOME/jre/sh/java 126 | else 127 | JAVACMD=$JAVA_HOME/bin/java 128 | fi 129 | if [ ! -x "$JAVACMD" ] ; then 130 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 131 | 132 | Please set the JAVA_HOME variable in your environment to match the 133 | location of your Java installation." 134 | fi 135 | else 136 | JAVACMD=java 137 | if ! command -v java >/dev/null 2>&1 138 | then 139 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 140 | 141 | Please set the JAVA_HOME variable in your environment to match the 142 | location of your Java installation." 143 | fi 144 | fi 145 | 146 | # Increase the maximum file descriptors if we can. 147 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 148 | case $MAX_FD in #( 149 | max*) 150 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 151 | # shellcheck disable=SC2039,SC3045 152 | MAX_FD=$( ulimit -H -n ) || 153 | warn "Could not query maximum file descriptor limit" 154 | esac 155 | case $MAX_FD in #( 156 | '' | soft) :;; #( 157 | *) 158 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 159 | # shellcheck disable=SC2039,SC3045 160 | ulimit -n "$MAX_FD" || 161 | warn "Could not set maximum file descriptor limit to $MAX_FD" 162 | esac 163 | fi 164 | 165 | # Collect all arguments for the java command, stacking in reverse order: 166 | # * args from the command line 167 | # * the main class name 168 | # * -classpath 169 | # * -D...appname settings 170 | # * --module-path (only if needed) 171 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 172 | 173 | # For Cygwin or MSYS, switch paths to Windows format before running java 174 | if "$cygwin" || "$msys" ; then 175 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 176 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 177 | 178 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 179 | 180 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 181 | for arg do 182 | if 183 | case $arg in #( 184 | -*) false ;; # don't mess with options #( 185 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 186 | [ -e "$t" ] ;; #( 187 | *) false ;; 188 | esac 189 | then 190 | arg=$( cygpath --path --ignore --mixed "$arg" ) 191 | fi 192 | # Roll the args list around exactly as many times as the number of 193 | # args, so each arg winds up back in the position where it started, but 194 | # possibly modified. 195 | # 196 | # NB: a `for` loop captures its iteration list before it begins, so 197 | # changing the positional parameters here affects neither the number of 198 | # iterations, nor the values presented in `arg`. 199 | shift # remove old arg 200 | set -- "$@" "$arg" # push replacement arg 201 | done 202 | fi 203 | 204 | 205 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 206 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 207 | 208 | # Collect all arguments for the java command: 209 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 210 | # and any embedded shellness will be escaped. 211 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 212 | # treated as '${Hostname}' itself on the command line. 213 | 214 | set -- \ 215 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 216 | -classpath "$CLASSPATH" \ 217 | org.gradle.wrapper.GradleWrapperMain \ 218 | "$@" 219 | 220 | # Stop when "xargs" is not available. 221 | if ! command -v xargs >/dev/null 2>&1 222 | then 223 | die "xargs is not available" 224 | fi 225 | 226 | # Use "xargs" to parse quoted args. 227 | # 228 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 229 | # 230 | # In Bash we could simply go: 231 | # 232 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 233 | # set -- "${ARGS[@]}" "$@" 234 | # 235 | # but POSIX shell has neither arrays nor command substitution, so instead we 236 | # post-process each arg (as a line of input to sed) to backslash-escape any 237 | # character that might be a shell metacharacter, then use eval to reverse 238 | # that process (while maintaining the separation between arguments), and wrap 239 | # the whole thing up as a single "set" statement. 240 | # 241 | # This will of course break if any of these variables contains a newline or 242 | # an unmatched quote. 243 | # 244 | 245 | eval "set -- $( 246 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 247 | xargs -n1 | 248 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 249 | tr '\n' ' ' 250 | )" '"$@"' 251 | 252 | exec "$JAVACMD" "$@" 253 | -------------------------------------------------------------------------------- /justfile: -------------------------------------------------------------------------------- 1 | alias a := add-plugin 2 | alias al := add-plugin-local 3 | alias ap := add-plugin 4 | alias c := clean 5 | alias cm := compile 6 | alias cn := clear-nm 7 | alias epn := extract-plugin-nm 8 | alias ogp := open-github-prs 9 | alias oi := open-ios 10 | alias pi := pod-install 11 | alias ra := run-android 12 | alias s := setup 13 | alias sm := start-metro 14 | alias urn := update-react-native 15 | alias us := update-sdk 16 | alias v := version 17 | alias va := version-android 18 | 19 | REPOSITORY_NAME := "quickstart-react-native" 20 | SDK_NAME := "HyperTrack SDK React Native" 21 | 22 | # Source: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string 23 | # \ are escaped 24 | SEMVER_REGEX := "(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?" 25 | 26 | ACTIVITY_SERVICE_GOOGLE_PLUGIN_LOCAL_PATH := "../sdk-react-native/plugin_android_activity_service_google" 27 | LOCATION_SERVICES_GOOGLE_PLUGIN_LOCAL_PATH := "../sdk-react-native/plugin_android_location_services_google" 28 | LOCATION_SERVICES_GOOGLE_19_0_1_PLUGIN_LOCAL_PATH := "../sdk-react-native/plugin_android_location_services_google_19_0_1" 29 | PUSH_SERVICE_FIREBASE_PLUGIN_LOCAL_PATH := "../sdk-react-native/plugin_android_push_service_firebase" 30 | SDK_PLUGIN_LOCAL_PATH := "../sdk-react-native/sdk" 31 | 32 | add-plugin version: hooks 33 | #!/usr/bin/env sh 34 | set -euo pipefail 35 | 36 | if grep -q '"hypertrack-sdk-react-native"' package.json; then 37 | yarn remove hypertrack-sdk-react-native 38 | fi 39 | if grep -q '"hypertrack-sdk-react-native-plugin-android-activity-service-google"' package.json; then 40 | yarn remove hypertrack-sdk-react-native-plugin-android-activity-service-google 41 | fi 42 | if grep -q '"hypertrack-sdk-react-native-plugin-android-location-services-google"' package.json; then 43 | yarn remove hypertrack-sdk-react-native-plugin-android-location-services-google 44 | fi 45 | if grep -q '"hypertrack-sdk-react-native-plugin-android-push-service-firebase"' package.json; then 46 | yarn remove hypertrack-sdk-react-native-plugin-android-push-service-firebase 47 | fi 48 | 49 | MAJOR_VERSION=$(echo {{version}} | grep -o '^[0-9]\+') 50 | if [ $MAJOR_VERSION -ge 12 ]; then 51 | yarn add hypertrack-sdk-react-native-plugin-android-activity-service-google@{{version}} 52 | yarn add hypertrack-sdk-react-native-plugin-android-location-services-google@{{version}} 53 | yarn add hypertrack-sdk-react-native-plugin-android-push-service-firebase@{{version}} 54 | fi 55 | yarn add hypertrack-sdk-react-native@{{version}} 56 | 57 | just pod-install 58 | 59 | add-plugin-local: hooks 60 | #!/usr/bin/env sh 61 | set -euo pipefail 62 | 63 | yarn add hypertrack-sdk-react-native 64 | just extract-plugin-nm 65 | if grep -q '"hypertrack-sdk-react-native"' package.json; then 66 | yarn remove hypertrack-sdk-react-native 67 | fi 68 | if grep -q '"hypertrack-sdk-react-native-plugin-android-activity-service-google"' package.json; then 69 | yarn remove hypertrack-sdk-react-native-plugin-android-activity-service-google 70 | fi 71 | if grep -q '"hypertrack-sdk-react-native-plugin-android-location-services-google"' package.json; then 72 | yarn remove hypertrack-sdk-react-native-plugin-android-location-services-google 73 | fi 74 | if grep -q '"hypertrack-sdk-react-native-plugin-android-push-service-firebase"' package.json; then 75 | yarn remove hypertrack-sdk-react-native-plugin-android-push-service-firebase 76 | fi 77 | 78 | yarn add hypertrack-sdk-react-native@file:{{SDK_PLUGIN_LOCAL_PATH}} 79 | yarn add hypertrack-sdk-react-native-plugin-android-activity-service-google@file:{{ACTIVITY_SERVICE_GOOGLE_PLUGIN_LOCAL_PATH}} 80 | yarn add hypertrack-sdk-react-native-plugin-android-location-services-google@file:{{LOCATION_SERVICES_GOOGLE_PLUGIN_LOCAL_PATH}} 81 | yarn add hypertrack-sdk-react-native-plugin-android-push-service-firebase@file:{{PUSH_SERVICE_FIREBASE_PLUGIN_LOCAL_PATH}} 82 | 83 | just pod-install 84 | 85 | clean: 86 | #!/usr/bin/env sh 87 | set -euo pipefail 88 | 89 | cd android 90 | ./gradlew clean 91 | cd .. 92 | just clear-nm 93 | 94 | clear-nm: hooks 95 | rm -rf node_modules 96 | rm yarn.lock 97 | 98 | compile: hooks 99 | npx tsc 100 | 101 | extract-plugin-nm: 102 | rm -rf {{SDK_PLUGIN_LOCAL_PATH}}/node_modules 103 | mkdir {{SDK_PLUGIN_LOCAL_PATH}}/node_modules 104 | cp -r node_modules/hypertrack-sdk-react-native/node_modules {{SDK_PLUGIN_LOCAL_PATH}}/node_modules 105 | 106 | hooks: 107 | chmod +x .githooks/pre-push 108 | git config core.hooksPath .githooks 109 | 110 | open-github-prs: 111 | open "https://github.com/hypertrack/{{REPOSITORY_NAME}}/pulls" 112 | 113 | open-ios: 114 | open ios/QuickstartReactNative.xcworkspace 115 | 116 | pod-install: 117 | #!/usr/bin/env sh 118 | cd ios 119 | rm -f Podfile.lock 120 | pwd 121 | NO_FLIPPER=1 pod install --repo-update 122 | cd .. 123 | 124 | restore-manual: 125 | #!/usr/bin/env sh 126 | set -euo pipefail 127 | 128 | while IFS= read -r line; do 129 | cp -f "update_storage/$line" "$line" 2>/dev/null && rm -f "update_storage/$line" || echo "Failed to restore $line" 130 | done < .htfiles_manual 131 | 132 | run-android: hooks compile 133 | npx react-native run-android 134 | 135 | setup: hooks 136 | yarn 137 | just pi 138 | 139 | start-metro: hooks compile 140 | npx react-native start 141 | 142 | update-sdk version: hooks 143 | git checkout -b update-sdk-{{version}} 144 | just add-plugin {{version}} 145 | git commit -am "Update {{SDK_NAME}} to {{version}}" 146 | just open-github-prs 147 | 148 | update-react-native version: 149 | #!/usr/bin/env sh 150 | set -euo pipefail 151 | 152 | just _store-files-for-update 153 | just _clear-files-before-update 154 | just _create-rn-app "{{version}}" 155 | just _restore-files-for-update 156 | 157 | rm -rf __tests__ 158 | rm -f App.tsx 159 | rm index.js 160 | 161 | ./scripts/update_file.sh ios/QuickstartReactNative.xcodeproj/project.pbxproj "org.reactjs.native.example.\$(PRODUCT_NAME:.*)" "com.hypertrack.quickstart.reactnative.ios" 162 | 163 | cp -f index.native.js index.js 164 | 165 | echo "Now commit changes and manually merge these files with 'just restore-manual':\n" 166 | cat .htfiles_manual 167 | echo "\nIf you are getting BuildConfig not found error in Android, add 'import com.quickstartreactnative.BuildConfig' in MainApplication.kt'" 168 | 169 | version: 170 | @cat package.json | grep hypertrack-sdk-react-native | head -n 1 | grep -o -E '{{SEMVER_REGEX}}' 171 | 172 | version-android: 173 | #!/usr/bin/env sh 174 | set -euo pipefail 175 | cd android 176 | ./gradlew app:dependencies | grep "com.hypertrack:sdk-android" | head -n 1 | grep -o -E '{{SEMVER_REGEX}}' 177 | cd .. 178 | 179 | _get_rn_files: 180 | #!/usr/bin/env sh 181 | set -euo pipefail 182 | 183 | TARGET_DIR="$PWD" 184 | 185 | # not related to RN 186 | EXCEPTIONS=( 187 | "update_storage" 188 | ".git" 189 | ".githooks" 190 | ".gitignore" 191 | ".idea" 192 | "CONTRIBUTING.md" 193 | "justfile" 194 | "LICENSE" 195 | "text.txt" 196 | "rn_files.txt" 197 | ".rnignore" 198 | ".htfiles" 199 | ".htfiles_manual" 200 | "scripts" 201 | ) 202 | 203 | # Construct the exclusion filter safely 204 | EXCLUDE_ARGS=() 205 | for item in "${EXCEPTIONS[@]}"; do 206 | EXCLUDE_ARGS+=(! -name "$item") 207 | done 208 | 209 | find "$TARGET_DIR" -mindepth 1 -maxdepth 1 "${EXCLUDE_ARGS[@]}" -print > rn_files.txt 210 | 211 | _store-files-for-update: 212 | #!/usr/bin/env sh 213 | set -euo pipefail 214 | 215 | rm -rf update_storage 216 | mkdir -p update_storage 217 | 218 | while IFS= read -r line; do 219 | foldername=$(dirname "update_storage/$line") 220 | mkdir -p "$foldername" 221 | cp -f "$line" "update_storage/$line" 222 | done < .htfiles 223 | 224 | while IFS= read -r line; do 225 | foldername=$(dirname "update_storage/$line") 226 | mkdir -p "$foldername" 227 | cp -f "$line" "update_storage/$line" 2>/dev/null || true 228 | done < .htfiles_manual 229 | 230 | _clear-files-before-update: _get_rn_files 231 | #!/usr/bin/env sh 232 | set -euo pipefail 233 | 234 | # remove all files listed in rn_files.txt 235 | while IFS= read -r line; do 236 | rm -rf "$line" 237 | done < rn_files.txt 238 | 239 | rm -f rn_files.txt 240 | rm -f App.tsx 241 | rm -f index.js 242 | 243 | _create-rn-app version="0.77.0": 244 | #!/usr/bin/env sh 245 | set -euo pipefail 246 | 247 | # check if react-native-cli and @react-native-community/cli are installed and delete if they are 248 | if [ -x "$(npm list -g react-native-cli)" ]; then 249 | echo "To avoid conflicts, uninstall react-native-cli globally with \n 'npm uninstall -g react-native-cli'" 250 | exit 1 251 | fi 252 | if [ -x "$(npm list -g @react-native-community/cli)" ]; then 253 | echo "To avoid conflicts, uninstall @react-native-community/cli globally with \n 'npm uninstall -g @react-native-community/cli'" 254 | exit 1 255 | fi 256 | 257 | if [[ "{{version}}" > "0.71.0" ]]; then 258 | npx @react-native-community/cli@latest init QuickstartReactNative --version {{version}} --pm yarn 259 | else 260 | npx @react-native-community/cli@latest init QuickstartReactNative --version {{version}} --pm yarn --template react-native-template-typescript 261 | fi 262 | 263 | cp -r QuickstartReactNative/* . 264 | rm -rf QuickstartReactNative 265 | 266 | _restore-files-for-update: 267 | #!/usr/bin/env sh 268 | set -euo pipefail 269 | 270 | while IFS= read -r line; do 271 | foldername=$(dirname "$line") 272 | mkdir -p "$foldername" 273 | cp -f "update_storage/$line" "$line" 2>/dev/null && rm -f "update_storage/$line" || echo "Failed to restore $line" 274 | done < .htfiles 275 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, {useEffect, useRef, useState} from 'react'; 2 | import { 3 | View, 4 | StyleSheet, 5 | Text, 6 | Pressable, 7 | Alert, 8 | ScrollView, 9 | SafeAreaView, 10 | StatusBar, 11 | EmitterSubscription, 12 | } from 'react-native'; 13 | import {Platform} from 'react-native'; 14 | import {check, PERMISSIONS, request, RESULTS} from 'react-native-permissions'; 15 | 16 | import HyperTrack, { 17 | HyperTrackError, 18 | Location, 19 | LocationError, 20 | LocationWithDeviation, 21 | Order, 22 | OrderStatus, 23 | Result, 24 | } from 'hypertrack-sdk-react-native'; 25 | 26 | const Button = ({title, onPress}: {title: string; onPress: () => void}) => ( 27 | [ 29 | { 30 | backgroundColor: pressed ? 'rgba(60, 105, 246, 0.5)' : '#3C69F6', 31 | }, 32 | styles.button, 33 | ]} 34 | onPress={onPress}> 35 | {title} 36 | 37 | ); 38 | 39 | const App = () => { 40 | const [errorsState, setErrorsState] = useState(''); 41 | const [deviceIdState, setDeviceIdState] = useState(''); 42 | const [isAvailableState, setIsAvailableState] = useState(false); 43 | const [isTrackingState, setIsTrackingState] = useState(false); 44 | const [locationState, setLocationState] = useState(''); 45 | const [ordersState, setOrdersState] = useState('N/A'); 46 | 47 | const errorsListener = useRef(null); 48 | const isAvailableListener = useRef( 49 | null, 50 | ); 51 | const isTrackingListener = useRef( 52 | null, 53 | ); 54 | const locationListener = useRef(null); 55 | const ordersListener = useRef(null); 56 | 57 | useEffect(() => { 58 | const initSDK = async () => { 59 | try { 60 | const deviceId = await HyperTrack.getDeviceId(); 61 | console.log('getDeviceId', deviceId); 62 | setDeviceIdState(deviceId); 63 | 64 | const name = 'Quickstart ReactNative'; 65 | HyperTrack.setName(name); 66 | console.log('setName', name); 67 | 68 | const metadata = { 69 | /** 70 | * Metadata is an custom data that is linked to the device. 71 | */ 72 | source: name, 73 | employee_id: Math.round(Math.random() * 10000), 74 | }; 75 | HyperTrack.setMetadata(metadata); 76 | console.log('setMetadata', metadata); 77 | 78 | let platformName = ''; 79 | if (Platform.OS === 'android') { 80 | platformName = 'android'; 81 | } else if (Platform.OS === 'ios') { 82 | platformName = 'ios'; 83 | } 84 | /** 85 | * Worker handle is used to link the device and the worker. 86 | * You can use any unique user identifier here. 87 | * The recommended way is to set it on app login in set it to null on logout 88 | * (to remove the link between the device and the worker) 89 | **/ 90 | HyperTrack.setWorkerHandle( 91 | `test_worker_quickstart_react_native_${platformName}`, 92 | ); 93 | console.log('workerHandle is set'); 94 | 95 | const workerHandle = await HyperTrack.getWorkerHandle(); 96 | console.log('getWorkerHandle', workerHandle); 97 | 98 | errorsListener.current = HyperTrack.subscribeToErrors( 99 | (errors: HyperTrackError[]) => { 100 | let result = getErrorsText(errors); 101 | console.log('Listener errors: ', result); 102 | setErrorsState(result); 103 | }, 104 | ); 105 | 106 | isAvailableListener.current = HyperTrack.subscribeToIsAvailable( 107 | (isAvailable: boolean) => { 108 | console.log('Listener isAvailable: ', isAvailable); 109 | setIsAvailableState(isAvailable); 110 | }, 111 | ); 112 | 113 | isTrackingListener.current = HyperTrack.subscribeToIsTracking( 114 | (isTracking: boolean) => { 115 | console.log('Listener isTracking: ', isTracking); 116 | setIsTrackingState(isTracking); 117 | }, 118 | ); 119 | 120 | locationListener.current = HyperTrack.subscribeToLocation( 121 | (locationResult: Result) => { 122 | console.log('Listener location: ', locationResult); 123 | setLocationState(getLocationResponseText(locationResult)); 124 | }, 125 | ); 126 | 127 | ordersListener.current = HyperTrack.subscribeToOrders( 128 | async (orders: Map) => { 129 | console.log('Listener orders: ', orders); 130 | const text = await getOrdersResponseText(orders); 131 | setOrdersState(text); 132 | }, 133 | ); 134 | } catch (error) { 135 | console.log(error, JSON.stringify(error)); 136 | } 137 | }; 138 | initSDK(); 139 | 140 | return () => { 141 | errorsListener.current?.remove(); 142 | isTrackingListener.current?.remove(); 143 | isAvailableListener.current?.remove(); 144 | locationListener.current?.remove(); 145 | ordersListener.current?.remove(); 146 | }; 147 | }, []); 148 | 149 | const addGeotag = async () => { 150 | try { 151 | /** 152 | * geotagPayload is an arbitrary object. 153 | * You can put there any JSON-serializable data. 154 | * It will be displayed in the HyperTrack dashboard and 155 | * available in the webhook events. 156 | */ 157 | const geotagPayload = { 158 | payload: 'Quickstart ReactNative', 159 | value: Math.random(), 160 | }; 161 | 162 | const orderHandle = 'test_order'; 163 | const orderStatus: OrderStatus = { 164 | type: 'orderStatusCustom', 165 | value: 'test_status', 166 | }; 167 | const result = await HyperTrack.addGeotag( 168 | orderHandle, 169 | orderStatus, 170 | geotagPayload, 171 | ); 172 | console.log('Add geotag: ', result); 173 | Alert.alert('Add geotag', getLocationResponseText(result)); 174 | } catch (error) { 175 | console.log('error', error); 176 | } 177 | }; 178 | 179 | const addGeotagWithExpectedLocation = async () => { 180 | try { 181 | /** 182 | * geotagPayload is an arbitrary object. 183 | * You can put there any JSON-serializable data. 184 | * It will be displayed in the HyperTrack dashboard and 185 | * available in the webhook events. 186 | */ 187 | const geotagPayload = { 188 | payload: 'Quickstart ReactNative', 189 | value: Math.random(), 190 | }; 191 | 192 | const orderHandle = 'test_order'; 193 | const orderStatus: OrderStatus = { 194 | type: 'orderStatusCustom', 195 | value: 'test_status', 196 | }; 197 | const result = await HyperTrack.addGeotag( 198 | orderHandle, 199 | orderStatus, 200 | geotagPayload, 201 | { 202 | latitude: 37.775, 203 | longitude: -122.418, 204 | }, 205 | ); 206 | console.log('Add geotag with expected location:', result); 207 | Alert.alert( 208 | 'Add geotag with expected location', 209 | getLocationWithDeviationResponseText(result), 210 | ); 211 | } catch (error) { 212 | console.log('error', error); 213 | } 214 | }; 215 | 216 | const getAllowMockLocation = async () => { 217 | const allowMockLocation = await HyperTrack.getAllowMockLocation(); 218 | console.log('AllowMockLocation:', allowMockLocation); 219 | Alert.alert('AllowMockLocation', `${allowMockLocation}`); 220 | }; 221 | 222 | const getErrors = async () => { 223 | const errors = await HyperTrack.getErrors(); 224 | let result = getErrorsText(errors); 225 | console.log('Errors:', result); 226 | Alert.alert('errors', result); 227 | }; 228 | 229 | const getIsAvailable = async () => { 230 | const available = await HyperTrack.getIsAvailable(); 231 | console.log('isAvailable', available); 232 | Alert.alert('isAvailable', `${available}`); 233 | }; 234 | 235 | const getIsTracking = async () => { 236 | const isTracking = await HyperTrack.getIsTracking(); 237 | console.log('isTracking', isTracking); 238 | Alert.alert('isTracking', `${isTracking}`); 239 | }; 240 | 241 | const getLocation = async () => { 242 | try { 243 | const result = await HyperTrack.getLocation(); 244 | Alert.alert('Location:', getLocationResponseText(result)); 245 | } catch (error) { 246 | console.log('error', error); 247 | } 248 | }; 249 | 250 | const getMetadata = async () => { 251 | const metadata = await HyperTrack.getMetadata(); 252 | console.log('Metadata:', metadata); 253 | Alert.alert('Metadata', JSON.stringify(metadata)); 254 | }; 255 | 256 | const getName = async () => { 257 | const name = await HyperTrack.getName(); 258 | console.log('Name:', name); 259 | Alert.alert('Name', name); 260 | }; 261 | 262 | const getOrders = async () => { 263 | const orders = await HyperTrack.getOrders(); 264 | console.log('Orders:', orders); 265 | const text = await getOrdersResponseText(orders); 266 | Alert.alert('Orders', text); 267 | }; 268 | 269 | const locate = async () => { 270 | HyperTrack.locate((locationResult: Result) => { 271 | try { 272 | let result = getLocateResponseText(locationResult); 273 | console.log('Locate:', result); 274 | Alert.alert('Result', result); 275 | } catch (error) { 276 | console.log('error', error); 277 | } 278 | }); 279 | console.log('Locate started'); 280 | }; 281 | 282 | const requestMotionActivityPermission = async () => { 283 | await request(PERMISSIONS.IOS.MOTION); 284 | }; 285 | 286 | const setAllowMockLocation = async (allowMockLocation: boolean) => { 287 | HyperTrack.setAllowMockLocation(allowMockLocation); 288 | console.log('setAllowMockLocation', allowMockLocation); 289 | }; 290 | 291 | const setIsAvailable = async (isAvailable: boolean) => { 292 | HyperTrack.setIsAvailable(isAvailable); 293 | console.log('setIsAvailable', isAvailable); 294 | }; 295 | 296 | const setIsTracking = async (isTracking: boolean) => { 297 | HyperTrack.setIsTracking(isTracking); 298 | console.log('setIsTracking', isTracking); 299 | }; 300 | 301 | return ( 302 | 303 | 304 | 305 | Device ID: 306 | 307 | {deviceIdState} 308 | 309 | 310 | Orders: 311 | {ordersState} 312 | 313 | {'Location'} 314 | {locationState} 315 | 316 | {'Errors'} 317 | {errorsState} 318 | 319 | 320 |