├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .flowconfig ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── asana-attachment.yml │ ├── asana-comment.yml │ ├── pr-checks.yml │ └── pr-rebase.yml ├── .gitignore ├── .husky └── pre-commit ├── .prettierrc.json ├── .yarnrc ├── AirshipDemo ├── .eslintrc.json ├── .gitignore ├── README.md ├── android │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── airshipdemo │ │ │ │ ├── MainActivity.kt │ │ │ │ └── MainApplication.kt │ │ │ └── res │ │ │ ├── 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 │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── babel.config.js ├── index.ts ├── ios │ ├── .xcode.env │ ├── AirshipDemo.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── AirshipDemo.xcscheme │ ├── AirshipDemo.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── AirshipDemo │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ └── main.m │ ├── Podfile │ └── Podfile.lock ├── metro.config.js ├── package.json ├── patches │ └── @react-native-community+blur+3.6.0.patch ├── react-native.config.js ├── src │ ├── CustomFloatingComponent.tsx │ ├── Demo.tsx │ ├── TextInputModal.tsx │ ├── ThemedDropdown.tsx │ ├── ThemedModal.tsx │ ├── ThemedToast.tsx │ └── theming │ │ ├── ThemeProvider.tsx │ │ ├── ThemedButton.tsx │ │ ├── ThemedText.tsx │ │ ├── ThemedTextInput.tsx │ │ └── themes.ts ├── tsconfig.json └── yarn.lock ├── CHANGELOG.md ├── README.md ├── docs ├── custom-components.md ├── dropdown.md ├── dropdown.png ├── isometric.png ├── isometric.svg ├── modal.md ├── modal.png ├── toast.md └── toast.png ├── package.json ├── src ├── components │ ├── Airship.tsx │ ├── AirshipDropdown.tsx │ ├── AirshipModal.tsx │ ├── AirshipToast.tsx │ └── Barometer.tsx ├── index.flow.js ├── index.ts ├── types.ts └── util │ └── sides.ts ├── tsconfig.json ├── update-demo.sh └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /lib/ 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "standard-kit/prettier", 4 | "standard-kit/prettier/jsx", 5 | "standard-kit/prettier/flow", 6 | "standard-kit/prettier/typescript", 7 | "standard-kit/prettier/react" 8 | ], 9 | "parserOptions": { 10 | "project": "tsconfig.json" 11 | }, 12 | "plugins": [ 13 | "simple-import-sort" 14 | ], 15 | "rules": { 16 | "simple-import-sort/imports": "error" 17 | }, 18 | "settings": { 19 | "react": { 20 | "version": "16.9" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | .*/AirshipDemo/.* 3 | 4 | [include] 5 | 6 | [libs] 7 | 8 | [lints] 9 | 10 | [options] 11 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### CHANGELOG 2 | 3 | Does this branch warrant an entry to the CHANGELOG? 4 | 5 | - [ ] Yes 6 | - [ ] No 7 | 8 | ### Dependencies 9 | 10 | none 11 | 12 | ### Description 13 | 14 | none 15 | -------------------------------------------------------------------------------- /.github/workflows/asana-attachment.yml: -------------------------------------------------------------------------------- 1 | # removed -------------------------------------------------------------------------------- /.github/workflows/asana-comment.yml: -------------------------------------------------------------------------------- 1 | # removed -------------------------------------------------------------------------------- /.github/workflows/pr-checks.yml: -------------------------------------------------------------------------------- 1 | name: PR Checks 2 | on: [pull_request] 3 | jobs: 4 | block-wip-pr: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2.0.0 8 | - name: Block WIP PR 9 | uses: samholmes/block-wip-pr-action@v1.2.0 10 | -------------------------------------------------------------------------------- /.github/workflows/pr-rebase.yml: -------------------------------------------------------------------------------- 1 | name: PR Rebase 2 | on: 3 | issue_comment: 4 | types: [created] 5 | jobs: 6 | rebase: 7 | name: Rebase 8 | if: >- 9 | github.event.issue.pull_request != '' && 10 | ( 11 | contains(github.event.comment.body, '/autosquash') || 12 | contains(github.event.comment.body, '/fixup') || 13 | contains(github.event.comment.body, '/rebase') 14 | ) 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout the latest code 18 | uses: actions/checkout@v3 19 | with: 20 | token: ${{ secrets.GITHUB_TOKEN }} 21 | fetch-depth: 0 # otherwise, you will fail to push refs to dest repo 22 | - name: Automatic Rebase 23 | uses: EdgeApp/rebase@changelog-resolver 24 | with: 25 | autosquash: ${{ true }} 26 | changelogResolver: ${{ true }} 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build output: 2 | lib/ 3 | 4 | # Package managers: 5 | node_modules/ 6 | npm-debug.log 7 | package-lock.json 8 | yarn-error.log 9 | 10 | # Editors: 11 | .DS_Store 12 | .idea/ 13 | .vscode/ 14 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run precommit 5 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "semi": false, 4 | "singleQuote": true, 5 | "trailingComma": "none" 6 | } 7 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | --ignore-scripts true 2 | -------------------------------------------------------------------------------- /AirshipDemo/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "project": "AirshipDemo/tsconfig.json" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /AirshipDemo/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | ios/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | .cxx/ 34 | *.keystore 35 | !debug.keystore 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | 43 | # fastlane 44 | # 45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 46 | # screenshots whenever they are needed. 47 | # For more information about the recommended setup visit: 48 | # https://docs.fastlane.tools/best-practices/source-control/ 49 | 50 | **/fastlane/report.xml 51 | **/fastlane/Preview.html 52 | **/fastlane/screenshots 53 | **/fastlane/test_output 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # Ruby / CocoaPods 59 | /ios/Pods/ 60 | /vendor/bundle/ 61 | 62 | # Temporary files created by Metro to check the health of the file watcher 63 | .metro-health-check* 64 | 65 | # testing 66 | /coverage 67 | -------------------------------------------------------------------------------- /AirshipDemo/README.md: -------------------------------------------------------------------------------- 1 | # react-native-airship Demo App 2 | 3 | This app shows off the react-native-airship built-in components. 4 | 5 | To launch the demo, first run `yarn install` in this folder to set up the dependencies, and then run either `yarn android` or `yarn ios`. 6 | 7 | If you want to edit the Airship library while using this demo, run the `update-demo.sh` script located in the outer folder to copy your changes into `node_modules`. 8 | 9 | ## Theming 10 | 11 | Most applications have unique color schemes. If you want to customize the Airship components to match your color scheme, it is simplest to make some lightweight wrappers around the built-in components. These wrappers pass in the right default colors, so you can use the wrapped components througout your app without worrying about appearances. 12 | 13 | See [ThemedModal](./src/ThemedModal.tsx) for an example of what theming a component might look like. 14 | 15 | This demo includes both light & dark themes based on the Solarized color scheme, and it uses the [react-native-patina](https://www.npmjs.com/package/react-native-patina) library to switch between them. This is just a demo, so feel free to use whatever theming approach you like. 16 | -------------------------------------------------------------------------------- /AirshipDemo/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "org.jetbrains.kotlin.android" 3 | apply plugin: "com.facebook.react" 4 | 5 | /** 6 | * This is the configuration block to customize your React Native Android app. 7 | * By default you don't need to apply any configuration, just uncomment the lines you need. 8 | */ 9 | react { 10 | /* Folders */ 11 | // The root of your project, i.e. where "package.json" lives. Default is '..' 12 | // root = file("../") 13 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native 14 | // reactNativeDir = file("../node_modules/react-native") 15 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen 16 | // codegenDir = file("../node_modules/@react-native/codegen") 17 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js 18 | // cliFile = file("../node_modules/react-native/cli.js") 19 | 20 | /* Variants */ 21 | // The list of variants to that are debuggable. For those we're going to 22 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 23 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 24 | // debuggableVariants = ["liteDebug", "prodDebug"] 25 | 26 | /* Bundling */ 27 | // A list containing the node command and its flags. Default is just 'node'. 28 | // nodeExecutableAndArgs = ["node"] 29 | // 30 | // The command to run when bundling. By default is 'bundle' 31 | // bundleCommand = "ram-bundle" 32 | // 33 | // The path to the CLI configuration file. Default is empty. 34 | // bundleConfig = file(../rn-cli.config.js) 35 | // 36 | // The name of the generated asset file containing your JS bundle 37 | // bundleAssetName = "MyApplication.android.bundle" 38 | // 39 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 40 | // entryFile = file("../js/MyApplication.android.js") 41 | // 42 | // A list of extra flags to pass to the 'bundle' commands. 43 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 44 | // extraPackagerArgs = [] 45 | 46 | /* Hermes Commands */ 47 | // The hermes compiler command to run. By default it is 'hermesc' 48 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 49 | // 50 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 51 | // hermesFlags = ["-O", "-output-source-map"] 52 | } 53 | 54 | /** 55 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 56 | */ 57 | def enableProguardInReleaseBuilds = false 58 | 59 | /** 60 | * The preferred build flavor of JavaScriptCore (JSC) 61 | * 62 | * For example, to use the international variant, you can use: 63 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 64 | * 65 | * The international variant includes ICU i18n library and necessary data 66 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 67 | * give correct results when using with locales other than en-US. Note that 68 | * this variant is about 6MiB larger per architecture than default. 69 | */ 70 | def jscFlavor = 'org.webkit:android-jsc:+' 71 | 72 | android { 73 | ndkVersion rootProject.ext.ndkVersion 74 | buildToolsVersion rootProject.ext.buildToolsVersion 75 | compileSdk rootProject.ext.compileSdkVersion 76 | 77 | namespace "com.airshipdemo" 78 | defaultConfig { 79 | applicationId "com.airshipdemo" 80 | minSdkVersion rootProject.ext.minSdkVersion 81 | targetSdkVersion rootProject.ext.targetSdkVersion 82 | versionCode 1 83 | versionName "1.0" 84 | } 85 | signingConfigs { 86 | debug { 87 | storeFile file('debug.keystore') 88 | storePassword 'android' 89 | keyAlias 'androiddebugkey' 90 | keyPassword 'android' 91 | } 92 | } 93 | buildTypes { 94 | debug { 95 | signingConfig signingConfigs.debug 96 | } 97 | release { 98 | // Caution! In production, you need to generate your own keystore file. 99 | // see https://reactnative.dev/docs/signed-apk-android. 100 | signingConfig signingConfigs.debug 101 | minifyEnabled enableProguardInReleaseBuilds 102 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 103 | } 104 | } 105 | } 106 | 107 | dependencies { 108 | // The version of react-native is set by the React Native Gradle Plugin 109 | implementation("com.facebook.react:react-android") 110 | implementation("com.facebook.react:flipper-integration") 111 | 112 | if (hermesEnabled.toBoolean()) { 113 | implementation("com.facebook.react:hermes-android") 114 | } else { 115 | implementation jscFlavor 116 | } 117 | } 118 | 119 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 120 | -------------------------------------------------------------------------------- /AirshipDemo/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/app/debug.keystore -------------------------------------------------------------------------------- /AirshipDemo/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 | -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/java/com/airshipdemo/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.airshipdemo 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 = "AirshipDemo" 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 | -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/java/com/airshipdemo/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.airshipdemo 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.flipper.ReactNativeFlipper 13 | import com.facebook.soloader.SoLoader 14 | 15 | class MainApplication : Application(), ReactApplication { 16 | 17 | override val reactNativeHost: ReactNativeHost = 18 | object : DefaultReactNativeHost(this) { 19 | override fun getPackages(): List { 20 | // Packages that cannot be autolinked yet can be added manually here, for example: 21 | // packages.add(new MyReactNativePackage()); 22 | return PackageList(this).packages 23 | } 24 | 25 | override fun getJSMainModuleName(): String = "index" 26 | 27 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 28 | 29 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 30 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 31 | } 32 | 33 | override val reactHost: ReactHost 34 | get() = getDefaultReactHost(this.applicationContext, reactNativeHost) 35 | 36 | override fun onCreate() { 37 | super.onCreate() 38 | SoLoader.init(this, false) 39 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 40 | // If you opted-in for the New Architecture, we load the native entry point for this app. 41 | load() 42 | } 43 | ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AirshipDemo 3 | 4 | -------------------------------------------------------------------------------- /AirshipDemo/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AirshipDemo/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "34.0.0" 4 | minSdkVersion = 21 5 | compileSdkVersion = 34 6 | targetSdkVersion = 34 7 | ndkVersion = "25.1.8937393" 8 | kotlinVersion = "1.8.0" 9 | } 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle") 16 | classpath("com.facebook.react:react-native-gradle-plugin") 17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") 18 | } 19 | } 20 | 21 | apply plugin: "com.facebook.react.rootproject" 22 | -------------------------------------------------------------------------------- /AirshipDemo/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 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=false 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 | -------------------------------------------------------------------------------- /AirshipDemo/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/AirshipDemo/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /AirshipDemo/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /AirshipDemo/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 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit 88 | 89 | # Use the maximum available, or set MAX_FD != -1 to use that value. 90 | MAX_FD=maximum 91 | 92 | warn () { 93 | echo "$*" 94 | } >&2 95 | 96 | die () { 97 | echo 98 | echo "$*" 99 | echo 100 | exit 1 101 | } >&2 102 | 103 | # OS specific support (must be 'true' or 'false'). 104 | cygwin=false 105 | msys=false 106 | darwin=false 107 | nonstop=false 108 | case "$( uname )" in #( 109 | CYGWIN* ) cygwin=true ;; #( 110 | Darwin* ) darwin=true ;; #( 111 | MSYS* | MINGW* ) msys=true ;; #( 112 | NONSTOP* ) nonstop=true ;; 113 | esac 114 | 115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 116 | 117 | 118 | # Determine the Java command to use to start the JVM. 119 | if [ -n "$JAVA_HOME" ] ; then 120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 121 | # IBM's JDK on AIX uses strange locations for the executables 122 | JAVACMD=$JAVA_HOME/jre/sh/java 123 | else 124 | JAVACMD=$JAVA_HOME/bin/java 125 | fi 126 | if [ ! -x "$JAVACMD" ] ; then 127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 128 | 129 | Please set the JAVA_HOME variable in your environment to match the 130 | location of your Java installation." 131 | fi 132 | else 133 | JAVACMD=java 134 | if ! command -v java >/dev/null 2>&1 135 | then 136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | fi 142 | 143 | # Increase the maximum file descriptors if we can. 144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 145 | case $MAX_FD in #( 146 | max*) 147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 148 | # shellcheck disable=SC3045 149 | MAX_FD=$( ulimit -H -n ) || 150 | warn "Could not query maximum file descriptor limit" 151 | esac 152 | case $MAX_FD in #( 153 | '' | soft) :;; #( 154 | *) 155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 156 | # shellcheck disable=SC3045 157 | ulimit -n "$MAX_FD" || 158 | warn "Could not set maximum file descriptor limit to $MAX_FD" 159 | esac 160 | fi 161 | 162 | # Collect all arguments for the java command, stacking in reverse order: 163 | # * args from the command line 164 | # * the main class name 165 | # * -classpath 166 | # * -D...appname settings 167 | # * --module-path (only if needed) 168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 169 | 170 | # For Cygwin or MSYS, switch paths to Windows format before running java 171 | if "$cygwin" || "$msys" ; then 172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 174 | 175 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 176 | 177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 178 | for arg do 179 | if 180 | case $arg in #( 181 | -*) false ;; # don't mess with options #( 182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 183 | [ -e "$t" ] ;; #( 184 | *) false ;; 185 | esac 186 | then 187 | arg=$( cygpath --path --ignore --mixed "$arg" ) 188 | fi 189 | # Roll the args list around exactly as many times as the number of 190 | # args, so each arg winds up back in the position where it started, but 191 | # possibly modified. 192 | # 193 | # NB: a `for` loop captures its iteration list before it begins, so 194 | # changing the positional parameters here affects neither the number of 195 | # iterations, nor the values presented in `arg`. 196 | shift # remove old arg 197 | set -- "$@" "$arg" # push replacement arg 198 | done 199 | fi 200 | 201 | 202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 204 | 205 | # Collect all arguments for the java command; 206 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 207 | # shell script including quotes and variable substitutions, so put them in 208 | # double quotes to make sure that they get re-expanded; and 209 | # * put everything else in single quotes, so that it's not re-expanded. 210 | 211 | set -- \ 212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 213 | -classpath "$CLASSPATH" \ 214 | org.gradle.wrapper.GradleWrapperMain \ 215 | "$@" 216 | 217 | # Stop when "xargs" is not available. 218 | if ! command -v xargs >/dev/null 2>&1 219 | then 220 | die "xargs is not available" 221 | fi 222 | 223 | # Use "xargs" to parse quoted args. 224 | # 225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 226 | # 227 | # In Bash we could simply go: 228 | # 229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 230 | # set -- "${ARGS[@]}" "$@" 231 | # 232 | # but POSIX shell has neither arrays nor command substitution, so instead we 233 | # post-process each arg (as a line of input to sed) to backslash-escape any 234 | # character that might be a shell metacharacter, then use eval to reverse 235 | # that process (while maintaining the separation between arguments), and wrap 236 | # the whole thing up as a single "set" statement. 237 | # 238 | # This will of course break if any of these variables contains a newline or 239 | # an unmatched quote. 240 | # 241 | 242 | eval "set -- $( 243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 244 | xargs -n1 | 245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 246 | tr '\n' ' ' 247 | )" '"$@"' 248 | 249 | exec "$JAVACMD" "$@" 250 | -------------------------------------------------------------------------------- /AirshipDemo/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 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /AirshipDemo/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'AirshipDemo' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/@react-native/gradle-plugin') 5 | -------------------------------------------------------------------------------- /AirshipDemo/babel.config.js: -------------------------------------------------------------------------------- 1 | /* global module */ 2 | 3 | module.exports = { 4 | presets: ['module:@react-native/babel-preset'] 5 | } 6 | -------------------------------------------------------------------------------- /AirshipDemo/index.ts: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native' 2 | 3 | import { Demo } from './src/Demo' 4 | 5 | AppRegistry.registerComponent('AirshipDemo', () => Demo) 6 | -------------------------------------------------------------------------------- /AirshipDemo/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 | -------------------------------------------------------------------------------- /AirshipDemo/ios/AirshipDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 11 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 12 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 13 | 797F98F9351E154851F83E0E /* libPods-AirshipDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BEE524C9133254F775B77B96 /* libPods-AirshipDemo.a */; }; 14 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXFileReference section */ 18 | 13B07F961A680F5B00A75B9A /* AirshipDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AirshipDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 19 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = AirshipDemo/AppDelegate.h; sourceTree = ""; }; 20 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.mm; path = AirshipDemo/AppDelegate.mm; sourceTree = ""; }; 21 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = AirshipDemo/Images.xcassets; sourceTree = ""; }; 22 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = AirshipDemo/Info.plist; sourceTree = ""; }; 23 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = AirshipDemo/main.m; sourceTree = ""; }; 24 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = AirshipDemo/LaunchScreen.storyboard; sourceTree = ""; }; 25 | A401D522B94AEDB975826F50 /* Pods-AirshipDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AirshipDemo.release.xcconfig"; path = "Target Support Files/Pods-AirshipDemo/Pods-AirshipDemo.release.xcconfig"; sourceTree = ""; }; 26 | BEE524C9133254F775B77B96 /* libPods-AirshipDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AirshipDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | E9D3E32E0BAA71D2C53D04FF /* Pods-AirshipDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AirshipDemo.debug.xcconfig"; path = "Target Support Files/Pods-AirshipDemo/Pods-AirshipDemo.debug.xcconfig"; sourceTree = ""; }; 28 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | 797F98F9351E154851F83E0E /* libPods-AirshipDemo.a in Frameworks */, 37 | ); 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXFrameworksBuildPhase section */ 41 | 42 | /* Begin PBXGroup section */ 43 | 13B07FAE1A68108700A75B9A /* AirshipDemo */ = { 44 | isa = PBXGroup; 45 | children = ( 46 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 47 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */, 48 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 49 | 13B07FB61A68108700A75B9A /* Info.plist */, 50 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, 51 | 13B07FB71A68108700A75B9A /* main.m */, 52 | ); 53 | name = AirshipDemo; 54 | sourceTree = ""; 55 | }; 56 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */, 60 | BEE524C9133254F775B77B96 /* libPods-AirshipDemo.a */, 61 | ); 62 | name = Frameworks; 63 | sourceTree = ""; 64 | }; 65 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | ); 69 | name = Libraries; 70 | sourceTree = ""; 71 | }; 72 | 83CBB9F61A601CBA00E9B192 = { 73 | isa = PBXGroup; 74 | children = ( 75 | 13B07FAE1A68108700A75B9A /* AirshipDemo */, 76 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 77 | 83CBBA001A601CBA00E9B192 /* Products */, 78 | 2D16E6871FA4F8E400B85C8A /* Frameworks */, 79 | AB4C4B0A0480EDBACD13ACD5 /* Pods */, 80 | ); 81 | indentWidth = 2; 82 | sourceTree = ""; 83 | tabWidth = 2; 84 | usesTabs = 0; 85 | }; 86 | 83CBBA001A601CBA00E9B192 /* Products */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 13B07F961A680F5B00A75B9A /* AirshipDemo.app */, 90 | ); 91 | name = Products; 92 | sourceTree = ""; 93 | }; 94 | AB4C4B0A0480EDBACD13ACD5 /* Pods */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | E9D3E32E0BAA71D2C53D04FF /* Pods-AirshipDemo.debug.xcconfig */, 98 | A401D522B94AEDB975826F50 /* Pods-AirshipDemo.release.xcconfig */, 99 | ); 100 | path = Pods; 101 | sourceTree = ""; 102 | }; 103 | /* End PBXGroup section */ 104 | 105 | /* Begin PBXNativeTarget section */ 106 | 13B07F861A680F5B00A75B9A /* AirshipDemo */ = { 107 | isa = PBXNativeTarget; 108 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "AirshipDemo" */; 109 | buildPhases = ( 110 | 691C29C2F11E0531BC523123 /* [CP] Check Pods Manifest.lock */, 111 | FD10A7F022414F080027D42C /* Start Packager */, 112 | 13B07F871A680F5B00A75B9A /* Sources */, 113 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 114 | 13B07F8E1A680F5B00A75B9A /* Resources */, 115 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 116 | 97F9260948765A3BBE1D67F7 /* [CP] Embed Pods Frameworks */, 117 | 9409072AFF91E5F94985E931 /* [CP] Copy Pods Resources */, 118 | ); 119 | buildRules = ( 120 | ); 121 | dependencies = ( 122 | ); 123 | name = AirshipDemo; 124 | productName = AirshipDemo; 125 | productReference = 13B07F961A680F5B00A75B9A /* AirshipDemo.app */; 126 | productType = "com.apple.product-type.application"; 127 | }; 128 | /* End PBXNativeTarget section */ 129 | 130 | /* Begin PBXProject section */ 131 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 132 | isa = PBXProject; 133 | attributes = { 134 | LastUpgradeCheck = 1210; 135 | TargetAttributes = { 136 | 13B07F861A680F5B00A75B9A = { 137 | LastSwiftMigration = 1120; 138 | }; 139 | }; 140 | }; 141 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "AirshipDemo" */; 142 | compatibilityVersion = "Xcode 12.0"; 143 | developmentRegion = en; 144 | hasScannedForEncodings = 0; 145 | knownRegions = ( 146 | en, 147 | Base, 148 | ); 149 | mainGroup = 83CBB9F61A601CBA00E9B192; 150 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 151 | projectDirPath = ""; 152 | projectRoot = ""; 153 | targets = ( 154 | 13B07F861A680F5B00A75B9A /* AirshipDemo */, 155 | ); 156 | }; 157 | /* End PBXProject section */ 158 | 159 | /* Begin PBXResourcesBuildPhase section */ 160 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 161 | isa = PBXResourcesBuildPhase; 162 | buildActionMask = 2147483647; 163 | files = ( 164 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, 165 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Bundle React Native code and images"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n"; 185 | }; 186 | 691C29C2F11E0531BC523123 /* [CP] Check Pods Manifest.lock */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputFileListPaths = ( 192 | ); 193 | inputPaths = ( 194 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 195 | "${PODS_ROOT}/Manifest.lock", 196 | ); 197 | name = "[CP] Check Pods Manifest.lock"; 198 | outputFileListPaths = ( 199 | ); 200 | outputPaths = ( 201 | "$(DERIVED_FILE_DIR)/Pods-AirshipDemo-checkManifestLockResult.txt", 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | shellPath = /bin/sh; 205 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 206 | showEnvVarsInLog = 0; 207 | }; 208 | 9409072AFF91E5F94985E931 /* [CP] Copy Pods Resources */ = { 209 | isa = PBXShellScriptBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | ); 213 | inputFileListPaths = ( 214 | "${PODS_ROOT}/Target Support Files/Pods-AirshipDemo/Pods-AirshipDemo-resources-${CONFIGURATION}-input-files.xcfilelist", 215 | ); 216 | name = "[CP] Copy Pods Resources"; 217 | outputFileListPaths = ( 218 | "${PODS_ROOT}/Target Support Files/Pods-AirshipDemo/Pods-AirshipDemo-resources-${CONFIGURATION}-output-files.xcfilelist", 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | shellPath = /bin/sh; 222 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AirshipDemo/Pods-AirshipDemo-resources.sh\"\n"; 223 | showEnvVarsInLog = 0; 224 | }; 225 | 97F9260948765A3BBE1D67F7 /* [CP] Embed Pods Frameworks */ = { 226 | isa = PBXShellScriptBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | ); 230 | inputFileListPaths = ( 231 | "${PODS_ROOT}/Target Support Files/Pods-AirshipDemo/Pods-AirshipDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist", 232 | ); 233 | name = "[CP] Embed Pods Frameworks"; 234 | outputFileListPaths = ( 235 | "${PODS_ROOT}/Target Support Files/Pods-AirshipDemo/Pods-AirshipDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist", 236 | ); 237 | runOnlyForDeploymentPostprocessing = 0; 238 | shellPath = /bin/sh; 239 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AirshipDemo/Pods-AirshipDemo-frameworks.sh\"\n"; 240 | showEnvVarsInLog = 0; 241 | }; 242 | FD10A7F022414F080027D42C /* Start Packager */ = { 243 | isa = PBXShellScriptBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | ); 247 | inputFileListPaths = ( 248 | ); 249 | inputPaths = ( 250 | ); 251 | name = "Start Packager"; 252 | outputFileListPaths = ( 253 | ); 254 | outputPaths = ( 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | shellPath = /bin/sh; 258 | shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; 259 | showEnvVarsInLog = 0; 260 | }; 261 | /* End PBXShellScriptBuildPhase section */ 262 | 263 | /* Begin PBXSourcesBuildPhase section */ 264 | 13B07F871A680F5B00A75B9A /* Sources */ = { 265 | isa = PBXSourcesBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, 269 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | }; 273 | /* End PBXSourcesBuildPhase section */ 274 | 275 | /* Begin XCBuildConfiguration section */ 276 | 13B07F941A680F5B00A75B9A /* Debug */ = { 277 | isa = XCBuildConfiguration; 278 | baseConfigurationReference = E9D3E32E0BAA71D2C53D04FF /* Pods-AirshipDemo.debug.xcconfig */; 279 | buildSettings = { 280 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 281 | CLANG_ENABLE_MODULES = YES; 282 | CURRENT_PROJECT_VERSION = 1; 283 | ENABLE_BITCODE = NO; 284 | INFOPLIST_FILE = AirshipDemo/Info.plist; 285 | LD_RUNPATH_SEARCH_PATHS = ( 286 | "$(inherited)", 287 | "@executable_path/Frameworks", 288 | ); 289 | MARKETING_VERSION = 1.0; 290 | OTHER_LDFLAGS = ( 291 | "$(inherited)", 292 | "-ObjC", 293 | "-lc++", 294 | ); 295 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 296 | PRODUCT_NAME = AirshipDemo; 297 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 298 | SWIFT_VERSION = 5.0; 299 | VERSIONING_SYSTEM = "apple-generic"; 300 | }; 301 | name = Debug; 302 | }; 303 | 13B07F951A680F5B00A75B9A /* Release */ = { 304 | isa = XCBuildConfiguration; 305 | baseConfigurationReference = A401D522B94AEDB975826F50 /* Pods-AirshipDemo.release.xcconfig */; 306 | buildSettings = { 307 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 308 | CLANG_ENABLE_MODULES = YES; 309 | CURRENT_PROJECT_VERSION = 1; 310 | INFOPLIST_FILE = AirshipDemo/Info.plist; 311 | LD_RUNPATH_SEARCH_PATHS = ( 312 | "$(inherited)", 313 | "@executable_path/Frameworks", 314 | ); 315 | MARKETING_VERSION = 1.0; 316 | OTHER_LDFLAGS = ( 317 | "$(inherited)", 318 | "-ObjC", 319 | "-lc++", 320 | ); 321 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 322 | PRODUCT_NAME = AirshipDemo; 323 | SWIFT_VERSION = 5.0; 324 | VERSIONING_SYSTEM = "apple-generic"; 325 | }; 326 | name = Release; 327 | }; 328 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 329 | isa = XCBuildConfiguration; 330 | buildSettings = { 331 | ALWAYS_SEARCH_USER_PATHS = NO; 332 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 333 | CLANG_CXX_LANGUAGE_STANDARD = "c++20"; 334 | CLANG_CXX_LIBRARY = "libc++"; 335 | CLANG_ENABLE_MODULES = YES; 336 | CLANG_ENABLE_OBJC_ARC = YES; 337 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 338 | CLANG_WARN_BOOL_CONVERSION = YES; 339 | CLANG_WARN_COMMA = YES; 340 | CLANG_WARN_CONSTANT_CONVERSION = YES; 341 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 342 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 343 | CLANG_WARN_EMPTY_BODY = YES; 344 | CLANG_WARN_ENUM_CONVERSION = YES; 345 | CLANG_WARN_INFINITE_RECURSION = YES; 346 | CLANG_WARN_INT_CONVERSION = YES; 347 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 348 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 349 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 350 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 351 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 352 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 353 | CLANG_WARN_STRICT_PROTOTYPES = YES; 354 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 355 | CLANG_WARN_UNREACHABLE_CODE = YES; 356 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 357 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 358 | COPY_PHASE_STRIP = NO; 359 | ENABLE_STRICT_OBJC_MSGSEND = YES; 360 | ENABLE_TESTABILITY = YES; 361 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; 362 | GCC_C_LANGUAGE_STANDARD = gnu99; 363 | GCC_DYNAMIC_NO_PIC = NO; 364 | GCC_NO_COMMON_BLOCKS = YES; 365 | GCC_OPTIMIZATION_LEVEL = 0; 366 | GCC_PREPROCESSOR_DEFINITIONS = ( 367 | "DEBUG=1", 368 | "$(inherited)", 369 | ); 370 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 371 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 372 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 373 | GCC_WARN_UNDECLARED_SELECTOR = YES; 374 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 375 | GCC_WARN_UNUSED_FUNCTION = YES; 376 | GCC_WARN_UNUSED_VARIABLE = YES; 377 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 378 | LD_RUNPATH_SEARCH_PATHS = ( 379 | /usr/lib/swift, 380 | "$(inherited)", 381 | ); 382 | LIBRARY_SEARCH_PATHS = ( 383 | "\"$(SDKROOT)/usr/lib/swift\"", 384 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 385 | "\"$(inherited)\"", 386 | ); 387 | MTL_ENABLE_DEBUG_INFO = YES; 388 | ONLY_ACTIVE_ARCH = YES; 389 | OTHER_CFLAGS = "$(inherited)"; 390 | OTHER_CPLUSPLUSFLAGS = ( 391 | "$(OTHER_CFLAGS)", 392 | "-DFOLLY_NO_CONFIG", 393 | "-DFOLLY_MOBILE=1", 394 | "-DFOLLY_USE_LIBCPP=1", 395 | "-DFOLLY_CFG_NO_COROUTINES=1", 396 | ); 397 | OTHER_LDFLAGS = ( 398 | "$(inherited)", 399 | "-Wl", 400 | "-ld_classic", 401 | ); 402 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; 403 | SDKROOT = iphoneos; 404 | USE_HERMES = true; 405 | }; 406 | name = Debug; 407 | }; 408 | 83CBBA211A601CBA00E9B192 /* Release */ = { 409 | isa = XCBuildConfiguration; 410 | buildSettings = { 411 | ALWAYS_SEARCH_USER_PATHS = NO; 412 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 413 | CLANG_CXX_LANGUAGE_STANDARD = "c++20"; 414 | CLANG_CXX_LIBRARY = "libc++"; 415 | CLANG_ENABLE_MODULES = YES; 416 | CLANG_ENABLE_OBJC_ARC = YES; 417 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 418 | CLANG_WARN_BOOL_CONVERSION = YES; 419 | CLANG_WARN_COMMA = YES; 420 | CLANG_WARN_CONSTANT_CONVERSION = YES; 421 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 422 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 423 | CLANG_WARN_EMPTY_BODY = YES; 424 | CLANG_WARN_ENUM_CONVERSION = YES; 425 | CLANG_WARN_INFINITE_RECURSION = YES; 426 | CLANG_WARN_INT_CONVERSION = YES; 427 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 428 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 429 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 430 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 431 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 432 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 433 | CLANG_WARN_STRICT_PROTOTYPES = YES; 434 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 435 | CLANG_WARN_UNREACHABLE_CODE = YES; 436 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 437 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 438 | COPY_PHASE_STRIP = YES; 439 | ENABLE_NS_ASSERTIONS = NO; 440 | ENABLE_STRICT_OBJC_MSGSEND = YES; 441 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; 442 | GCC_C_LANGUAGE_STANDARD = gnu99; 443 | GCC_NO_COMMON_BLOCKS = YES; 444 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 445 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 446 | GCC_WARN_UNDECLARED_SELECTOR = YES; 447 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 448 | GCC_WARN_UNUSED_FUNCTION = YES; 449 | GCC_WARN_UNUSED_VARIABLE = YES; 450 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 451 | LD_RUNPATH_SEARCH_PATHS = ( 452 | /usr/lib/swift, 453 | "$(inherited)", 454 | ); 455 | LIBRARY_SEARCH_PATHS = ( 456 | "\"$(SDKROOT)/usr/lib/swift\"", 457 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 458 | "\"$(inherited)\"", 459 | ); 460 | MTL_ENABLE_DEBUG_INFO = NO; 461 | OTHER_CFLAGS = "$(inherited)"; 462 | OTHER_CPLUSPLUSFLAGS = ( 463 | "$(OTHER_CFLAGS)", 464 | "-DFOLLY_NO_CONFIG", 465 | "-DFOLLY_MOBILE=1", 466 | "-DFOLLY_USE_LIBCPP=1", 467 | "-DFOLLY_CFG_NO_COROUTINES=1", 468 | ); 469 | OTHER_LDFLAGS = ( 470 | "$(inherited)", 471 | "-Wl", 472 | "-ld_classic", 473 | ); 474 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; 475 | SDKROOT = iphoneos; 476 | USE_HERMES = true; 477 | VALIDATE_PRODUCT = YES; 478 | }; 479 | name = Release; 480 | }; 481 | /* End XCBuildConfiguration section */ 482 | 483 | /* Begin XCConfigurationList section */ 484 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "AirshipDemo" */ = { 485 | isa = XCConfigurationList; 486 | buildConfigurations = ( 487 | 13B07F941A680F5B00A75B9A /* Debug */, 488 | 13B07F951A680F5B00A75B9A /* Release */, 489 | ); 490 | defaultConfigurationIsVisible = 0; 491 | defaultConfigurationName = Release; 492 | }; 493 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "AirshipDemo" */ = { 494 | isa = XCConfigurationList; 495 | buildConfigurations = ( 496 | 83CBBA201A601CBA00E9B192 /* Debug */, 497 | 83CBBA211A601CBA00E9B192 /* Release */, 498 | ); 499 | defaultConfigurationIsVisible = 0; 500 | defaultConfigurationName = Release; 501 | }; 502 | /* End XCConfigurationList section */ 503 | }; 504 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 505 | } 506 | -------------------------------------------------------------------------------- /AirshipDemo/ios/AirshipDemo.xcodeproj/xcshareddata/xcschemes/AirshipDemo.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 | -------------------------------------------------------------------------------- /AirshipDemo/ios/AirshipDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /AirshipDemo/ios/AirshipDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /AirshipDemo/ios/AirshipDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /AirshipDemo/ios/AirshipDemo/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.moduleName = @"AirshipDemo"; 10 | // You can add your custom initial props in the dictionary below. 11 | // They will be passed down to the ViewController used by React Native. 12 | self.initialProps = @{}; 13 | 14 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | } 16 | 17 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 18 | { 19 | return [self getBundleURL]; 20 | } 21 | 22 | - (NSURL *)getBundleURL 23 | { 24 | #if DEBUG 25 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 26 | #else 27 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 28 | #endif 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /AirshipDemo/ios/AirshipDemo/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 | -------------------------------------------------------------------------------- /AirshipDemo/ios/AirshipDemo/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /AirshipDemo/ios/AirshipDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | AirshipDemo 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSAllowsLocalNetworking 32 | 33 | 34 | NSLocationWhenInUseUsageDescription 35 | 36 | UILaunchStoryboardName 37 | LaunchScreen 38 | UIRequiredDeviceCapabilities 39 | 40 | armv7 41 | 42 | UISupportedInterfaceOrientations 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | UIViewControllerBasedStatusBarAppearance 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /AirshipDemo/ios/AirshipDemo/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 | -------------------------------------------------------------------------------- /AirshipDemo/ios/AirshipDemo/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /AirshipDemo/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | require Pod::Executable.execute_command('node', ['-p', 3 | 'require.resolve( 4 | "react-native/scripts/react_native_pods.rb", 5 | {paths: [process.argv[1]]}, 6 | )', __dir__]).strip 7 | 8 | platform :ios, min_ios_version_supported 9 | prepare_react_native_project! 10 | 11 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. 12 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded 13 | # 14 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` 15 | # ```js 16 | # module.exports = { 17 | # dependencies: { 18 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), 19 | # ``` 20 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled 21 | 22 | linkage = ENV['USE_FRAMEWORKS'] 23 | if linkage != nil 24 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 25 | use_frameworks! :linkage => linkage.to_sym 26 | end 27 | 28 | target 'AirshipDemo' do 29 | config = use_native_modules! 30 | 31 | use_react_native!( 32 | :path => config[:reactNativePath], 33 | # Enables Flipper. 34 | # 35 | # Note that if you have use_frameworks! enabled, Flipper will not work and 36 | # you should disable the next line. 37 | :flipper_configuration => flipper_config, 38 | # An absolute path to your application root. 39 | :app_path => "#{Pod::Config.instance.installation_root}/.." 40 | ) 41 | 42 | post_install do |installer| 43 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 44 | react_native_post_install( 45 | installer, 46 | config[:reactNativePath], 47 | :mac_catalyst_enabled => false 48 | ) 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /AirshipDemo/metro.config.js: -------------------------------------------------------------------------------- 1 | /* global __dirname module require */ 2 | 3 | const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config') 4 | 5 | /** 6 | * Metro configuration 7 | * https://facebook.github.io/metro/docs/configuration 8 | * 9 | * @type {import('metro-config').MetroConfig} 10 | */ 11 | const config = {} 12 | 13 | module.exports = mergeConfig(getDefaultConfig(__dirname), config) 14 | -------------------------------------------------------------------------------- /AirshipDemo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "airship-demo", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "prepare": "patch-package", 9 | "prepare-ios": "(cd ios; pod install --repo-update)", 10 | "start": "react-native start" 11 | }, 12 | "dependencies": { 13 | "@react-native-community/blur": "^3.6.0", 14 | "react": "18.2.0", 15 | "react-native": "0.73.0", 16 | "react-native-airship": "*", 17 | "react-native-patina": "^0.1.3" 18 | }, 19 | "devDependencies": { 20 | "@babel/core": "^7.20.0", 21 | "@babel/preset-env": "^7.20.0", 22 | "@babel/runtime": "^7.20.0", 23 | "@react-native/babel-preset": "^0.73.18", 24 | "@react-native/metro-config": "^0.73.2", 25 | "@react-native/typescript-config": "^0.73.1", 26 | "@types/react": "^18.2.6", 27 | "@types/react-test-renderer": "^18.0.0", 28 | "eslint": "^8.19.0", 29 | "patch-package": "^8.0.0", 30 | "prettier": "2.8.8", 31 | "typescript": "^4.9.5" 32 | }, 33 | "engines": { 34 | "node": ">=18" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /AirshipDemo/patches/@react-native-community+blur+3.6.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/node_modules/@react-native-community/blur/android/build.gradle b/node_modules/@react-native-community/blur/android/build.gradle 2 | index 8177235..fcdeb1c 100644 3 | --- a/node_modules/@react-native-community/blur/android/build.gradle 4 | +++ b/node_modules/@react-native-community/blur/android/build.gradle 5 | @@ -9,7 +9,6 @@ buildscript { 6 | if (project == rootProject) { 7 | repositories { 8 | google() 9 | - jcenter() 10 | } 11 | 12 | dependencies { 13 | @@ -37,11 +36,12 @@ android { 14 | 15 | repositories { 16 | google() 17 | - jcenter() 18 | + maven { url 'https://jitpack.io' } 19 | } 20 | 21 | dependencies { 22 | //noinspection GradleDynamicVersion 23 | implementation 'com.facebook.react:react-native:+' 24 | - implementation 'com.eightbitlab:blurview:1.6.3' 25 | + implementation 'com.github.Dimezis:BlurView:version-1.6.6' 26 | + implementation 'com.github.android:renderscript-intrinsics-replacement-toolkit:b6363490c3' 27 | } 28 | diff --git a/node_modules/@react-native-community/blur/android/src/main/java/com/cmcewen/blurview/BlurViewManager.java b/node_modules/@react-native-community/blur/android/src/main/java/com/cmcewen/blurview/BlurViewManager.java 29 | index b583b02..fa319d1 100644 30 | --- a/node_modules/@react-native-community/blur/android/src/main/java/com/cmcewen/blurview/BlurViewManager.java 31 | +++ b/node_modules/@react-native-community/blur/android/src/main/java/com/cmcewen/blurview/BlurViewManager.java 32 | @@ -1,5 +1,6 @@ 33 | package com.cmcewen.blurview; 34 | 35 | +import android.app.Activity; 36 | import android.graphics.drawable.Drawable; 37 | import android.view.View; 38 | import android.view.ViewGroup; 39 | @@ -14,7 +15,6 @@ import java.util.Objects; 40 | import javax.annotation.Nonnull; 41 | 42 | import eightbitlab.com.blurview.BlurView; 43 | -import eightbitlab.com.blurview.RenderScriptBlur; 44 | 45 | 46 | @SuppressWarnings("unused") 47 | @@ -32,14 +32,17 @@ class BlurViewManager extends ViewGroupManager { 48 | @Override 49 | public @Nonnull BlurView createViewInstance(@Nonnull ThemedReactContext ctx) { 50 | BlurView blurView = new BlurView(ctx); 51 | - View decorView = Objects.requireNonNull(ctx.getCurrentActivity()).getWindow().getDecorView(); 52 | - ViewGroup rootView = decorView.findViewById(android.R.id.content); 53 | - Drawable windowBackground = decorView.getBackground(); 54 | - blurView.setupWith(rootView) 55 | - .setFrameClearDrawable(windowBackground) 56 | - .setBlurAlgorithm(new RenderScriptBlur(ctx)) 57 | - .setBlurRadius(defaultRadius) 58 | - .setHasFixedTransformationMatrix(false); 59 | + Activity currentActivity = ctx.getCurrentActivity(); 60 | + if (currentActivity != null) { 61 | + View decorView = currentActivity.getWindow().getDecorView(); 62 | + ViewGroup rootView = decorView.findViewById(android.R.id.content); 63 | + Drawable windowBackground = decorView.getBackground(); 64 | + blurView.setupWith(rootView) 65 | + .setFrameClearDrawable(windowBackground) 66 | + .setBlurAlgorithm(new SimdBlur()) 67 | + .setBlurRadius(defaultRadius) 68 | + .setHasFixedTransformationMatrix(false); 69 | + } 70 | return blurView; 71 | } 72 | 73 | diff --git a/node_modules/@react-native-community/blur/android/src/main/java/com/cmcewen/blurview/SimdBlur.java b/node_modules/@react-native-community/blur/android/src/main/java/com/cmcewen/blurview/SimdBlur.java 74 | new file mode 100644 75 | index 0000000..1d15b8d 76 | --- /dev/null 77 | +++ b/node_modules/@react-native-community/blur/android/src/main/java/com/cmcewen/blurview/SimdBlur.java 78 | @@ -0,0 +1,32 @@ 79 | +package com.cmcewen.blurview; 80 | + 81 | +import android.graphics.Bitmap; 82 | +import androidx.annotation.NonNull; 83 | +import com.google.android.renderscript.Toolkit; 84 | +import eightbitlab.com.blurview.BlurAlgorithm; 85 | + 86 | +public final class SimdBlur implements BlurAlgorithm { 87 | + /** 88 | + * @param bitmap bitmap to blur 89 | + * @param blurRadius blur radius (1..25) 90 | + * @return blurred bitmap 91 | + */ 92 | + @Override 93 | + public final Bitmap blur(Bitmap bitmap, float blurRadius) { 94 | + return Toolkit.INSTANCE.blur(bitmap, (int) blurRadius); 95 | + } 96 | + 97 | + @Override 98 | + public boolean canModifyBitmap() { 99 | + return true; 100 | + } 101 | + 102 | + @Override 103 | + public final void destroy() {} 104 | + 105 | + @NonNull 106 | + @Override 107 | + public Bitmap.Config getSupportedBitmapConfig() { 108 | + return Bitmap.Config.ARGB_8888; 109 | + } 110 | +} 111 | diff --git a/node_modules/@react-native-community/blur/src/BlurView.android.js b/node_modules/@react-native-community/blur/src/BlurView.android.js 112 | index a192476..3a9c5b3 100644 113 | --- a/node_modules/@react-native-community/blur/src/BlurView.android.js 114 | +++ b/node_modules/@react-native-community/blur/src/BlurView.android.js 115 | @@ -5,6 +5,7 @@ import { 116 | requireNativeComponent, 117 | DeviceEventEmitter, 118 | ViewPropTypes, 119 | + Platform, 120 | StyleSheet, 121 | } from 'react-native'; 122 | 123 | @@ -65,6 +66,14 @@ class BlurView extends Component { 124 | render() { 125 | const { style } = this.props; 126 | 127 | + if (Platform.Version <= 27) { 128 | + return ( 129 | + 130 | + {this.props.children} 131 | + 132 | + ) 133 | + } 134 | + 135 | return ( 136 | 7 | } 8 | 9 | /** 10 | * An example of how easy it is to build floating UI elements using Airship. 11 | */ 12 | export function CustomFloatingComponent(props: Props): JSX.Element { 13 | const { bridge } = props 14 | React.useEffect(() => bridge.on('clear', bridge.resolve), [bridge]) 15 | React.useEffect(() => bridge.on('result', bridge.remove), [bridge]) 16 | 17 | return ( 18 | bridge.resolve()}> 19 | Tap to dismiss 20 | 21 | ) 22 | } 23 | 24 | const styles = StyleSheet.create({ 25 | text: { 26 | backgroundColor: 'rgba(255, 255, 255, 0.75)', 27 | borderRadius: 10, 28 | color: 'black', 29 | fontSize: 12, 30 | margin: 10, 31 | padding: 10, 32 | textAlign: 'center' 33 | } 34 | }) 35 | -------------------------------------------------------------------------------- /AirshipDemo/src/Demo.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { 3 | Appearance, 4 | Platform, 5 | SafeAreaView, 6 | ScrollView, 7 | StatusBar, 8 | StyleSheet, 9 | Switch, 10 | View 11 | } from 'react-native' 12 | import { makeAirship } from 'react-native-airship' 13 | import { cacheStyles } from 'react-native-patina' 14 | 15 | import { CustomFloatingComponent } from './CustomFloatingComponent' 16 | import { TextInputModal } from './TextInputModal' 17 | import { ThemedDropdown } from './ThemedDropdown' 18 | import { ThemedToast } from './ThemedToast' 19 | import { ThemedButton } from './theming/ThemedButton' 20 | import { ThemedText } from './theming/ThemedText' 21 | import { changeTheme, Theme, ThemeProvider } from './theming/ThemeProvider' 22 | import { darkTheme, lightTheme } from './theming/themes' 23 | 24 | const Airship = makeAirship() 25 | 26 | /** 27 | * The demo app. This has a main scroll view with a handful of buttons 28 | * for launching different Airship components. 29 | */ 30 | export const Demo = (props: {}): JSX.Element => { 31 | // Switch states: 32 | const [dark, setDark] = React.useState(Appearance.getColorScheme() === 'dark') 33 | const [translucent, setTranslucent] = React.useState(true) 34 | 35 | // Theming: 36 | const theme = dark ? darkTheme : lightTheme 37 | React.useEffect(() => changeTheme(theme), [theme]) 38 | const styles = getStyles(theme) 39 | const marginTop = 40 | translucent && StatusBar.currentHeight != null ? StatusBar.currentHeight : 0 41 | 42 | return ( 43 | 44 | 45 | 50 | 51 | 55 | Airship Demo 56 | 57 | Press some buttons to launch the demo components 58 | 59 | Modal 60 | 61 | Centered modal 62 | 63 | Dropdown 64 | Toast 65 | Custom component 66 | Clear all 67 | 68 | Dark mode 69 | 74 | 75 | {Platform.OS === 'android' ? ( 76 | 77 | Translucent status bar 78 | 83 | 84 | ) : null} 85 | 86 | 87 | 88 | 89 | ) 90 | } 91 | 92 | const getStyles = cacheStyles((theme: Theme) => ({ 93 | screen: { 94 | ...StyleSheet.absoluteFillObject, 95 | backgroundColor: theme.background 96 | }, 97 | scrollView: { 98 | flex: 1 99 | }, 100 | scrollContents: { 101 | padding: theme.rem(1) 102 | }, 103 | row: { 104 | alignItems: 'center', 105 | flexDirection: 'row', 106 | justifyContent: 'space-between' 107 | } 108 | })) 109 | 110 | // Callbacks for demo components: 111 | 112 | function handleModal(): void { 113 | Airship.show(bridge => { 114 | return 115 | }).catch(ignoreError) 116 | } 117 | 118 | function handleCenterModal(): void { 119 | Airship.show(bridge => { 120 | return 121 | }).catch(ignoreError) 122 | } 123 | 124 | function handleDropdown(): void { 125 | Airship.show(bridge => { 126 | return ( 127 | Alert: This is a dropdown 128 | ) 129 | }).catch(ignoreError) 130 | } 131 | 132 | function handleToast(): void { 133 | Airship.show(bridge => { 134 | return 135 | }).catch(ignoreError) 136 | } 137 | 138 | function handleCustom(): void { 139 | Airship.show(bridge => { 140 | return 141 | }).catch(ignoreError) 142 | } 143 | 144 | function handleClear(): void { 145 | Airship.clear() 146 | } 147 | 148 | const ignoreError = (): void => undefined 149 | -------------------------------------------------------------------------------- /AirshipDemo/src/TextInputModal.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { AirshipBridge } from 'react-native-airship' 3 | 4 | import { ThemedModal } from './ThemedModal' 5 | import { ThemedButton } from './theming/ThemedButton' 6 | import { ThemedText } from './theming/ThemedText' 7 | import { ThemedTextInput } from './theming/ThemedTextInput' 8 | 9 | interface Props { 10 | bridge: AirshipBridge 11 | center?: boolean 12 | } 13 | 14 | /** 15 | * This is an example of how to use the AirshipModal component 16 | * as a building-block of a larger modal component. 17 | * This one allows the user to enter some text, 18 | * which it returns as a promise. 19 | */ 20 | export function TextInputModal(props: Props): JSX.Element { 21 | const { bridge, center = false } = props 22 | const [text, setText] = React.useState('text input') 23 | 24 | return ( 25 | bridge.resolve(undefined)} 29 | > 30 | A Modal 31 | 32 | The Airship modal slides in from the bottom of the screen. It can have 33 | any contents you like. 34 | 35 | 36 | bridge.resolve(text)}> 37 | Sounds good 38 | 39 | 40 | ) 41 | } 42 | -------------------------------------------------------------------------------- /AirshipDemo/src/ThemedDropdown.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { Text } from 'react-native' 3 | import { AirshipDropdown, AirshipDropdownProps } from 'react-native-airship' 4 | import { cacheStyles } from 'react-native-patina' 5 | 6 | import { Theme, useTheme } from './theming/ThemeProvider' 7 | 8 | export function ThemedDropdown(props: AirshipDropdownProps): JSX.Element { 9 | const { children } = props 10 | const theme = useTheme() 11 | const styles = getStyles(theme) 12 | 13 | return ( 14 | 20 | {children} 21 | 22 | ) 23 | } 24 | 25 | const getStyles = cacheStyles((theme: Theme) => ({ 26 | dropdownText: { 27 | alignSelf: 'center', 28 | color: theme.dropdownText, 29 | flexShrink: 1, 30 | fontSize: theme.rem(1), 31 | margin: theme.rem(1) 32 | } 33 | })) 34 | -------------------------------------------------------------------------------- /AirshipDemo/src/ThemedModal.tsx: -------------------------------------------------------------------------------- 1 | import { BlurView } from '@react-native-community/blur' 2 | import * as React from 'react' 3 | import { StyleSheet } from 'react-native' 4 | import { AirshipModal, AirshipModalProps } from 'react-native-airship' 5 | 6 | import { useTheme } from './theming/ThemeProvider' 7 | 8 | export function ThemedModal(props: AirshipModalProps): JSX.Element { 9 | const { center = false } = props 10 | const theme = useTheme() 11 | 12 | return ( 13 | } 19 | {...props} 20 | /> 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /AirshipDemo/src/ThemedToast.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { AirshipToast, AirshipToastProps } from 'react-native-airship' 3 | 4 | import { useTheme } from './theming/ThemeProvider' 5 | 6 | export function ThemedToast(props: AirshipToastProps): JSX.Element { 7 | const theme = useTheme() 8 | 9 | return ( 10 | 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /AirshipDemo/src/theming/ThemeProvider.tsx: -------------------------------------------------------------------------------- 1 | import { Appearance } from 'react-native' 2 | import { makeThemeContext, setCacheSize } from 'react-native-patina' 3 | 4 | import { darkTheme, lightTheme } from './themes' 5 | 6 | // Make room for two themes: 7 | setCacheSize(2) 8 | 9 | export interface Theme { 10 | rem: (size: number) => number 11 | background: string 12 | text: string 13 | header: string 14 | 15 | button: string 16 | buttonText: string 17 | 18 | dropdown: string 19 | dropdownText: string 20 | 21 | textInput: string 22 | textInputBorder: string 23 | textInputText: string 24 | 25 | toast: string 26 | toastText: string 27 | } 28 | 29 | export interface ThemeProps { 30 | theme: Theme 31 | } 32 | 33 | export const { changeTheme, ThemeProvider, useTheme, withTheme } = 34 | makeThemeContext( 35 | Appearance.getColorScheme() === 'dark' ? darkTheme : lightTheme 36 | ) 37 | -------------------------------------------------------------------------------- /AirshipDemo/src/theming/ThemedButton.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { Text, TouchableOpacity } from 'react-native' 3 | import { cacheStyles } from 'react-native-patina' 4 | 5 | import { Theme, useTheme } from './ThemeProvider' 6 | 7 | interface Props { 8 | children: string | React.ReactNode 9 | onPress: () => void 10 | } 11 | 12 | export function ThemedButton(props: Props): JSX.Element { 13 | const theme = useTheme() 14 | const styles = getStyles(theme) 15 | const { children, onPress } = props 16 | 17 | return ( 18 | 19 | {typeof children === 'string' ? ( 20 | {children} 21 | ) : ( 22 | children 23 | )} 24 | 25 | ) 26 | } 27 | 28 | const getStyles = cacheStyles((theme: Theme) => ({ 29 | button: { 30 | alignItems: 'center', 31 | backgroundColor: theme.button, 32 | borderRadius: theme.rem(1), 33 | justifyContent: 'center', 34 | margin: theme.rem(1), 35 | padding: theme.rem(1), 36 | flexDirection: 'row' 37 | }, 38 | buttonText: { 39 | color: theme.buttonText, 40 | fontSize: theme.rem(1) 41 | } 42 | })) 43 | -------------------------------------------------------------------------------- /AirshipDemo/src/theming/ThemedText.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { Text } from 'react-native' 3 | import { cacheStyles } from 'react-native-patina' 4 | 5 | import { Theme, useTheme } from './ThemeProvider' 6 | 7 | interface Props { 8 | children: React.ReactNode 9 | header?: boolean 10 | } 11 | 12 | export function ThemedText(props: Props): JSX.Element { 13 | const { children, header = false } = props 14 | const theme = useTheme() 15 | const styles = getStyles(theme) 16 | 17 | return {children} 18 | } 19 | 20 | const getStyles = cacheStyles((theme: Theme) => ({ 21 | header: { 22 | alignSelf: 'center', 23 | color: theme.header, 24 | fontSize: theme.rem(1.2), 25 | margin: theme.rem(1), 26 | marginBottom: 0 27 | }, 28 | text: { 29 | color: theme.text, 30 | fontSize: theme.rem(1), 31 | margin: theme.rem(1) 32 | } 33 | })) 34 | -------------------------------------------------------------------------------- /AirshipDemo/src/theming/ThemedTextInput.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import { Keyboard, TextInput, TouchableOpacity, View } from 'react-native' 3 | import { cacheStyles } from 'react-native-patina' 4 | 5 | import { ThemedText } from './ThemedText' 6 | import { Theme, useTheme } from './ThemeProvider' 7 | 8 | interface Props { 9 | value: string 10 | onChangeText: (text: string) => void 11 | } 12 | 13 | export function ThemedTextInput(props: Props): JSX.Element { 14 | const { value, onChangeText } = props 15 | const theme = useTheme() 16 | const styles = getStyles(theme) 17 | 18 | return ( 19 | 20 | 25 | Keyboard.dismiss()}> 26 | Hide keyboard 27 | 28 | 29 | ) 30 | } 31 | 32 | const getStyles = cacheStyles((theme: Theme) => ({ 33 | input: { 34 | backgroundColor: theme.textInput, 35 | borderColor: theme.textInputBorder, 36 | borderRadius: theme.rem(0.5), 37 | borderWidth: theme.rem(0.1), 38 | color: theme.textInputText, 39 | flex: 1, 40 | fontSize: theme.rem(1), 41 | marginBottom: theme.rem(1), 42 | marginLeft: theme.rem(1), 43 | marginTop: theme.rem(1), 44 | padding: theme.rem(0.5) 45 | }, 46 | row: { 47 | alignItems: 'center', 48 | flexDirection: 'row', 49 | justifyContent: 'space-between' 50 | } 51 | })) 52 | -------------------------------------------------------------------------------- /AirshipDemo/src/theming/themes.ts: -------------------------------------------------------------------------------- 1 | import { Theme } from './ThemeProvider' 2 | 3 | const solarized = { 4 | base03: '#002b36', 5 | base02: '#073642', 6 | base01: '#586e75', 7 | base00: '#657b83', 8 | base0: '#839496', 9 | base1: '#93a1a1', 10 | base2: '#eee8d5', 11 | base3: '#fdf6e3', 12 | yellow: '#b58900', 13 | orange: '#cb4b16', 14 | red: '#dc322f', 15 | magenta: '#d33682', 16 | violet: '#6c71c4', 17 | blue: '#268bd2', 18 | cyan: '#2aa198', 19 | green: '#859900' 20 | } 21 | 22 | export const darkTheme: Theme = { 23 | rem(size: number): number { 24 | return Math.round(size * 16) 25 | }, 26 | 27 | background: solarized.base03, 28 | text: solarized.base0, 29 | header: solarized.base1, 30 | 31 | button: solarized.base0, 32 | buttonText: solarized.base03, 33 | 34 | dropdown: solarized.base00, 35 | dropdownText: solarized.base03, 36 | 37 | textInput: solarized.base02, 38 | textInputBorder: solarized.base0, 39 | textInputText: solarized.base0, 40 | 41 | toast: solarized.base3, 42 | toastText: solarized.base00 43 | } 44 | 45 | export const lightTheme: Theme = { 46 | rem(size: number): number { 47 | return Math.round(size * 16) 48 | }, 49 | 50 | background: solarized.base3, 51 | text: solarized.base00, 52 | header: solarized.base01, 53 | 54 | button: solarized.base2, 55 | buttonText: solarized.base00, 56 | 57 | dropdown: 'white', 58 | dropdownText: solarized.base03, 59 | 60 | textInput: solarized.base2, 61 | textInputBorder: solarized.base00, 62 | textInputText: solarized.base00, 63 | 64 | toast: solarized.base03, 65 | toastText: solarized.base1 66 | } 67 | -------------------------------------------------------------------------------- /AirshipDemo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "noEmit": true, 4 | 5 | "esModuleInterop": true, 6 | "isolatedModules": true, 7 | "jsx": "react-native", 8 | "lib": ["es2017"], 9 | "moduleResolution": "node", 10 | "target": "esnext", 11 | "skipLibCheck": true, 12 | 13 | "strict": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # react-native-airship 2 | 3 | ## 0.2.12 (2023-07-07) 4 | 5 | - fixed: Make the barometer component non-accessible. 6 | 7 | ## 0.2.11 (2022-12-19) 8 | 9 | - fixed: Extra call to `handleLayout` within `Barometer` to fix edge-case for incorrect screen layout calculations. 10 | 11 | ## 0.2.10 (2022-09-16) 12 | 13 | - changed: Default to Default to `AirshipBridge` instead of `AirshipBridge`. This change may cause new TypeScript errors to appear, but it is not a breaking change - the cases were always broken, but TypeScript simply wasn't reporting the errors. 14 | 15 | ## 0.2.9 (2022-04-25) 16 | 17 | - added: Add `borderColor` and `borderWidth` props to the `AirshipModal` component. 18 | 19 | ## 0.2.8 (2022-04-01) 20 | 21 | - fixed: Replace deprecated `removeListener` calls. 22 | 23 | ## 0.2.7 (2021-07-29) 24 | 25 | - added: New optional `overflow` prop for `AirshipModal`. 26 | 27 | ## 0.2.6 (2021-07-15) 28 | 29 | - added: Add optional shadow properties to the `AirshipModal`: 30 | - `shadowOffset` 31 | - `shadowOpacity` 32 | - `shadowRadius` 33 | 34 | ## 0.2.5 (2021-04-15) 35 | 36 | - fixed: Make the `Airship` Flow type work like the Typescript version. 37 | 38 | ## 0.2.4 (2021-03-25) 39 | 40 | - fixed: Do not crash when calling `Airship.clear` recursively. 41 | 42 | ## 0.2.3 (2021-01-23) 43 | 44 | - fixed: Measure the screen by mounting a test component and seeing where it lands, avoiding the need for various properties to control the layout. If the status bar is translucent, or if they keyboard is `adjustPan` mode on Android, we can automatically determine that now and do the right thing. 45 | - removed: `avoidAndroidKeyboard` prop on the top-level `Airship`. 46 | - removed: `statusBarTranslucent` prop on the top-level `Airship`. 47 | 48 | ## 0.2.2 (2020-09-03) 49 | 50 | - added: Add an `Airship.clear` method, which calls any callbacks registered with `bridge.on('clear')`. 51 | - added: Add a `bridge.on('result')` method to replace `bridge.onResult`. 52 | - fixed: Add some missing Flow type definitions. 53 | - fixed: Make the Typescript definitions work better with strict mode. 54 | - deprecated: `bridge.onResult` 55 | 56 | ## 0.2.1 (2020-08-11) 57 | 58 | - Fix various Flow & documentation issues from the previous release. 59 | 60 | ## 0.2.0(2020-08-07) 61 | 62 | With this version, the demo components become an official part of the library. The old `react-native-airship/demos` entry point has gone away, so you can import `AirshipDropdown`, `AirshipModal`, and `AirshipToast` directly from `react-native-airship` now. 63 | 64 | Since the demo components are meant to be directly usable, they now accept many more properties for controlling their appearance & behavior. 65 | 66 | The `activity` property on the `AirshipToast` has also gone away. See the [documentation](./docs/toast.md) for another way to achieve this same result. 67 | 68 | The `styleOverride` property on the `AirshipModal` has also gone away. Use the new appearance properties to make changes now. 69 | 70 | ## 0.1.4 (2020-07-31) 71 | 72 | - Update the readme file with a cool image. 73 | 74 | ## 0.1.3 (2020-07-28) 75 | 76 | - Fix the Flow types for compatibility with older versions. 77 | 78 | ## 0.1.2 (2019-11-27) 79 | 80 | - Port the demos to `react-native-safe-area-context`. 81 | - Add a temporary `styleOverride` prop to the modal while we figure out which customizations we want to support. 82 | 83 | ## 0.1.1 (2019-11-22) 84 | 85 | - Fix a packaging glitch that made the demos unusable. 86 | 87 | ## 0.1.0 (2019-11-21) 88 | 89 | - Initial release, extracted from edge-react-gui. 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-airship 2 | 3 | The airship floats above your React Native application, providing a place for modals, alerts, menus, toasts, and anything else to appear on top of your normal UI. 4 | 5 | Glass sheet hovering above phone 6 | 7 | Unlike React Native's built-in `Modal` component, the airship doesn't block the user from interacting with the application below. The airship has also a simple, promised-based API that lets it easily host multiple children at once. To place an item on the airship, call the `Airship.show` method: 8 | 9 | ```javascript 10 | const answer = await Airship.show(bridge => ( 11 | 12 | )) 13 | ``` 14 | 15 | The `Airship.show` method returns a promise, so you can simply `await` the user's feedback. This is much simpler than the typical approach of setting up a router and writing custom state handling. 16 | 17 | Besides the generic `Airship` container, this library comes with a handful of ready-to-use UI components: 18 | 19 | - [AirshipDropdown](./docs/dropdown.md) - A drop-down alert. 20 | - [AirshipModal](./docs/modal.md) - A slide-up modal which dims the rest of the screen. 21 | - [AirshipToast](./docs/toast.md) - Emulates the Android Toast component in a cross-platform way. 22 | 23 | If these don't do what you want, you can easily [write your own components](./docs/custom-components.md) to work with Airship. 24 | 25 | ## Setup 26 | 27 | Install `react-native-airship` using either NPM or yarn: 28 | 29 | ```sh 30 | yarn add react-native-airship 31 | # or: 32 | npm i -s react-native-airship 33 | ``` 34 | 35 | Next, create an Airship instance and place it outside your main scene or router: 36 | 37 | ```javascript 38 | // your-app.js: 39 | 40 | import { makeAirship } from 'react-native-airship' 41 | 42 | export const Airship = makeAirship() 43 | 44 | export const App = () => ( 45 | 46 | 47 | 48 | ) 49 | ``` 50 | 51 | Now, anybody in your application can use this `Airship` instance to show things on top of the app: 52 | 53 | ```javascript 54 | import { Airship } from './your-app.js' 55 | 56 | Airship.show(bridge => ) 57 | ``` 58 | 59 | There is also an `Airship.clear` method that can quickly remove everything mounted on the Airship (useful when logging out, for instance). 60 | 61 | ## Demo 62 | 63 | This repository includes a [demo application](./AirshipDemo/) you can use to try out the Airship. You will need to run `yarn install` or `npm install` separately in that folder to set up the demo, and then run either `react-native run-android` or `react-native run-ios` to start the demo. 64 | -------------------------------------------------------------------------------- /docs/custom-components.md: -------------------------------------------------------------------------------- 1 | # Custom Airship Components 2 | 3 | Although the Airship library comes with a handful of built-in components, it is actually super-easy to write your own: 4 | 5 | ```javascript 6 | function CustomFloatingComponent(props) { 7 | const { bridge } = props 8 | React.useEffect(() => bridge.on('clear', bridge.resolve), []) 9 | React.useEffect(() => bridge.on('result', bridge.remove), []) 10 | 11 | return ( 12 | bridge.resolve()}> 13 | Tap to dismiss 14 | 15 | ) 16 | } 17 | 18 | Airship.show(bridge => ) 19 | ``` 20 | 21 | This component is completely functional, although it lacks pretty styling. See [AirshipDemo/src/CustomFloatingComponent.tsx](../AirshipDemo/src/CustomFloatingComponent.tsx) for a styled version. 22 | 23 | Calling `Airship.show` is similar to calling `new Promise` - you receive some methods that you can use to control the resulting promise. The methods are placed on a `bridge` object, which makes them convenient to pass around as props. 24 | 25 | In this example, tapping the text calls `bridge.resolve` to resolve the promise. Once the promise resolves, the component un-mounts itself in response to the `bridge.on('result')` callback. 26 | 27 | ## Bridge Methods 28 | 29 | The `bridge` object has the following methods: 30 | 31 | - `bridge.resolve` - Resolves the promise returned from `Airship.show`. 32 | - `bridge.reject` - Rejects the promise returned from `Airship.show`. 33 | - `bridge.remove` - Removes the component from the Airship. 34 | - `bridge.on('result', callback)` - Invokes the callback when the component lifetime promise settles (either resolved or rejected). 35 | - `bridge.on('clear', callback)` - Invokes the callback whenever `Airship.clear` is called. 36 | 37 | A typical use-case is to use `bridge.on('result')` to start some sort of fade-out animation. That way, calling either `bridge.resolve` or `bridge.reject` will not only settle the promise, but will also begin hiding the component. Once the animation completes, call `bridge.remove` to finally un-mount the component. 38 | 39 | It is also a good idea to set up a `bridge.on('clear')` callback, so your component can remove itself when somebody calls `Airship.clear`. 40 | 41 | The bridge also has a deprecated `onResult` method, which is equivalent to calling `on('result')`. Do not use `onResult` method; it will go away in the next breaking release. 42 | 43 | ## Layout 44 | 45 | The `Airship` component mounts its children inside a wrapper component. This wrapper component fills the entire screen, and uses padding to avoid the status bar, keyboard, notches, and other obstacles. 46 | 47 | The wrapper component also has `flexDirection: 'row'` and `justifyContent: 'center'` set. This will center your floating UI horizontally. You can align your content vertically by setting `alignSelf` to either `flex-start` (top), `center`, or `flex-end` (bottom). 48 | 49 | The wrapper component's padding means that your floating UI will automatically avoid all the obstacles (such as notches) around the edges of the screen. On the other hand, this creates a problem if you actually _want_ your floating UI to touch one or more screen edges (such as for a drawer that slides in). 50 | 51 | There are two simple approaches to touching the screen edges: 52 | 53 | - Negative margin 54 | - Absolute positioning 55 | 56 | ### Negative Margin 57 | 58 | If you want your component to visually touch the screen edges while still keeping its contents in the safe area, just give those edges a negative margin: 59 | 60 | ```javascript 61 | return {...contents} 62 | ``` 63 | 64 | By balancing the negative margin with an equal and opposite padding, the component will stretch outwards towards the edge of the screen while keeping its contents in the safe area. The exact amount of negative margin doesn't matter, as long as it is large enough to reach all the way to the edge (going over is fine). A conservative value like 64 is about 50% larger than the gap on an iPhone X, so it should be safe for most devices. 65 | 66 | ### Absolute Positioning 67 | 68 | You can also use absolute positioning if you simply want to cover the entire screen: 69 | 70 | ```javascript 71 | return ( 72 | 73 | {...contents} 74 | 75 | ) 76 | ``` 77 | 78 | This will touch all four edges of the screen, completely ignoring the safe area. This approach is great for capturing touches or applying darkening outside your main UI. On the other hand, it loses the safe area information, which makes it less useful if you have contents that need to remain readable. 79 | -------------------------------------------------------------------------------- /docs/dropdown.md: -------------------------------------------------------------------------------- 1 | # AirshipDropdown 2 | 3 | The dropdown component slides in from the top of the screen. It can have any contents you like, but it is most useful for alerts. 4 | 5 | Screen shot 6 | 7 | The dropdown accepts a `bridge` property, which allows it to animate away & remove itself once the `Airship.show` promise resolves. 8 | 9 | The dropdown auto-hides itself after a short timeout, or whenever the user taps on it. You can pass an `onPress` callback to change the tap behavior, and you can use the `autoHideMs` prop to change the timeout (or disable it). 10 | 11 | ## Reference 12 | 13 | Here are the properties the component accepts. Only the `bridge` property is mandatory. 14 | 15 | ```typescript 16 | export interface AirshipDropdownProps { 17 | bridge: AirshipBridge 18 | children?: React.ReactNode 19 | 20 | // Called when the user taps anywhere in the dropdown. 21 | // Defaults to hiding the dropdown. 22 | onPress?: () => void 23 | 24 | // Determines how long the dropdown remains visible, 25 | // or 0 to disable auto-hide. Defaults to 5000ms. 26 | autoHideMs?: number 27 | 28 | // The component color. Defaults to white. 29 | backgroundColor?: string 30 | 31 | // The radius to use on the bottom corners. Defaults to 4. 32 | borderRadius?: number 33 | 34 | // The flex direction for the contents. 35 | flexDirection?: ViewStyle['flexDirection'] 36 | 37 | // How to justify the contents along the flex direction. 38 | justifyContent?: ViewStyle['justifyContent'] 39 | 40 | // The minimum gap between the component and the screen edges. 41 | // Takes 0-4 numbers (top, right, bottom, left), 42 | // using the same logic as the web `margin` property. Defaults to 0. 43 | margin?: number | number[] 44 | 45 | // The maximum height the component will be. 46 | // Defaults to 25% of the longest screen dimension. 47 | maxHeight?: number 48 | 49 | // The maximum width the component will be. 50 | // Defaults to 512. 51 | maxWidth?: number 52 | 53 | // Internal padding to place inside the component. 54 | // Takes 0-4 numbers (top, right, bottom, left), 55 | // using the same logic as the web `padding` property. Defaults to 0. 56 | padding?: number | number[] 57 | 58 | // How long the entry animation should be. Defaults to 300ms. 59 | slideInMs?: number 60 | 61 | // How long the exit animation should be. Defaults to 500ms. 62 | slideOutMs?: number 63 | } 64 | ``` 65 | -------------------------------------------------------------------------------- /docs/dropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/docs/dropdown.png -------------------------------------------------------------------------------- /docs/isometric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EdgeApp/react-native-airship/ba98c206dca49b5fe8b7e19462eba3b73536bdbf/docs/isometric.png -------------------------------------------------------------------------------- /docs/isometric.svg: -------------------------------------------------------------------------------- 1 | 2 | 21 | 23 | 43 | 46 | 47 | 49 | 50 | 52 | image/svg+xml 53 | 55 | 56 | 57 | 58 | 59 | 103 | 108 | 111 | 117 | 125 | 134 | 135 | 139 | 143 | 147 | 151 | 155 | 159 | 163 | 167 | 168 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /docs/modal.md: -------------------------------------------------------------------------------- 1 | # AirshipModal 2 | 3 | The modal component slides up from the bottom of the screen, while the rest of the app dims. Tapping outside the modal dismisses it. The modal can have any contents you like. 4 | 5 | Screen shot 6 | 7 | The modal accepts a `bridge` property, which allows it to animate away & remove itself once the `Airship.show` promise resolves. 8 | 9 | The modal also requires an `onCancel` callback. The modal calls this whenever the user taps outside the modal or presses the phone's back button. The best approach is to call `bridge.resolve` or `bridge.reject` to dismiss the modal when this happens. If you don't want the user to easily escape the modal, just pass a do-nothing function to `onCancel`. 10 | 11 | The best way to use `AirshipModal` is to treat it as a building block for a larger modal component, which includes your various messages, buttons, or controls: 12 | 13 | ```javascript 14 | export function YesNoModal(props) { 15 | const { bridge, question } = props 16 | 17 | return ( 18 | bridge.resolve(false)}> 19 | {question} 20 |