├── .editorconfig ├── .gitattributes ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── build.yml │ ├── npm.yml │ └── pages.yml ├── .gitignore ├── .watchmanconfig ├── .yarn ├── plugins │ └── @yarnpkg │ │ ├── plugin-interactive-tools.cjs │ │ ├── plugin-version.cjs │ │ └── plugin-workspace-tools.cjs ├── releases │ └── yarn-3.6.1.cjs └── versions │ ├── 47500c27.yml │ └── bb9e8b5c.yml ├── .yarnrc.yml ├── LICENSE ├── README.md ├── android ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── snap │ │ └── camerakit │ │ └── reactnative │ │ ├── CameraImageProcessorModule.kt │ │ ├── CameraKitContextModule.kt │ │ ├── CameraKitEventEmitter.kt │ │ ├── CameraKitReactNativePackage.kt │ │ ├── CameraPreview.kt │ │ ├── CameraPreviewManager.kt │ │ └── TouchViewContainer.kt │ └── res │ └── layout │ ├── camera_kit_touch.xml │ └── camera_kit_view.xml ├── babel.config.js ├── camera-kit-react-native.podspec ├── docs ├── .nojekyll ├── assets │ ├── highlight.css │ ├── icons.js │ ├── icons.svg │ ├── main.js │ ├── navigation.js │ ├── search.js │ └── style.css ├── classes │ ├── Logger.html │ └── NativeEventEmitter.html ├── functions │ ├── CameraKitContext.html │ ├── CameraPreviewView.html │ ├── getNativeModule.html │ ├── getNativeViewManager.html │ ├── isCameraKitError.html │ ├── isNativeError.html │ ├── isSupportedImageFormat.html │ ├── isValidLaunchParam.html │ ├── useCameraKit.html │ ├── useCameraPermissions.html │ └── useIsMounted.html ├── index.html ├── interfaces │ ├── CameraKitContextProps.html │ ├── CameraKitError.html │ ├── CameraKitState.html │ ├── CameraOptions.html │ ├── EmitterSubscription.html │ ├── Lens.html │ ├── LensLaunchData.html │ ├── Media.html │ ├── NativeError.html │ ├── Snapcode.html │ └── VideoRecording.html ├── modules.html ├── types │ ├── ImageFormats.html │ ├── LogEntry.html │ ├── LogLevel.html │ ├── NativeCameraViewProps.html │ ├── NativeModule.html │ └── Rect.html └── variables │ ├── CameraKitReactNative.html │ ├── CameraKitStateContext.html │ ├── NativeView.html │ └── cameraKitLogEvents.html ├── example ├── .bundle │ └── config ├── .watchmanconfig ├── Gemfile ├── README.md ├── android │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── snap │ │ │ │ └── camerakit │ │ │ │ └── reactnative │ │ │ │ └── example │ │ │ │ └── ReactNativeFlipper.java │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── snap │ │ │ │ │ └── camerakit │ │ │ │ │ └── reactnative │ │ │ │ │ └── example │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ └── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── release │ │ │ └── java │ │ │ └── com │ │ │ └── camerakitreactnativeexample │ │ │ └── ReactNativeFlipper.java │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios │ ├── .xcode.env │ ├── CameraKitReactNativeExample-Bridging-Header.h │ ├── CameraKitReactNativeExample.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── CameraKitReactNativeExample.xcscheme │ ├── CameraKitReactNativeExample.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ ├── CameraKitReactNativeExample │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ └── main.m │ ├── CameraKitReactNativeExampleTests │ │ ├── CameraKitReactNativeExampleTests.m │ │ └── Info.plist │ ├── File.swift │ ├── Podfile │ └── Podfile.lock ├── jest.config.js ├── metro.config.js ├── package.json ├── react-native.config.js └── src │ ├── App.tsx │ ├── Button.tsx │ ├── CameraPreview.tsx │ ├── CameraStateContext.tsx │ ├── Lenses.tsx │ ├── capture-preview │ ├── Hint.tsx │ ├── ImagePreview.tsx │ └── VideoPreview.tsx │ └── globalStyles.tsx ├── ios ├── CameraKitContextModule.mm ├── CameraKitContextModule.swift ├── CameraKitEventEmitter.m ├── CameraKitEventEmitter.swift ├── CameraKitReactNative-Bridging-Header.h ├── CameraPreviewManager.m ├── CameraPreviewManager.swift └── CameraPreviewView.swift ├── package.json ├── scripts └── pod-install.cjs ├── src ├── CameraKitContext.tsx ├── CameraKitContextModule.ts ├── CameraPreviewView.tsx ├── Errors.ts ├── NativeView.ts ├── TypeGuards.ts ├── __tests__ │ └── index.test.tsx ├── index.tsx ├── logger │ ├── Logger.ts │ └── cameraKitLogEvents.tsx ├── useCameraPermissions.tsx ├── useIsMounted.ts └── verifyNativeModule.tsx ├── tsconfig.build.json ├── tsconfig.json ├── turbo.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | root = true 3 | 4 | [*] 5 | # Unix-style newlines with a newline ending every file 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | quote_type = single 10 | 11 | # 4 spaces for indentation 12 | indent_size = 4 13 | indent_style = space 14 | 15 | # 120 characters max per line 16 | max_line_length = 120 17 | 18 | # some files use 2 spaces for indentation 19 | [*.{json,yml,yaml}] 20 | indent_size = 2 21 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | # specific for windows script files 3 | *.bat text eol=crlf -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Background (Why?) 2 | 3 | N/A 4 | 5 | ## Change/Solution (What?) 6 | 7 | N/A 8 | 9 | ## Screenshots for any visual changes 10 | 11 | N/A 12 | 13 | ## Test Plans 14 | 15 | N/A 16 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | jobs: 13 | build: 14 | name: Build 15 | runs-on: ubuntu-latest 16 | timeout-minutes: 10 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@v4 20 | 21 | - name: Use Node.js 20.x 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: 20.x 25 | cache: 'npm' 26 | 27 | - name: Install dependencies 28 | uses: borales/actions-yarn@v5 29 | with: 30 | cmd: install --immutable 31 | 32 | - name: Prepare 33 | uses: borales/actions-yarn@v5 34 | with: 35 | cmd: prepare 36 | 37 | - name: Pack 38 | uses: borales/actions-yarn@v5 39 | with: 40 | cmd: pack 41 | -------------------------------------------------------------------------------- /.github/workflows/npm.yml: -------------------------------------------------------------------------------- 1 | name: Publish to npm 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v[0-9]+.[0-9]+.[0-9]+*' 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | timeout-minutes: 10 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v4 15 | 16 | - name: Use Node.js 20.x 17 | uses: actions/setup-node@v4 18 | with: 19 | node-version: 20.x 20 | cache: 'npm' 21 | 22 | - name: Install dependencies 23 | uses: borales/actions-yarn@v5 24 | with: 25 | cmd: install --immutable 26 | 27 | - name: Prepare 28 | uses: borales/actions-yarn@v5 29 | with: 30 | cmd: prepare 31 | 32 | - name: Pack 33 | uses: borales/actions-yarn@v5 34 | with: 35 | cmd: npm publish --access public 36 | env: 37 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 38 | -------------------------------------------------------------------------------- /.github/workflows/pages.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy docs to Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["main"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | jobs: 25 | # Single deploy job since we're just deploying 26 | deploy: 27 | environment: 28 | name: github-pages 29 | url: ${{ steps.deployment.outputs.page_url }} 30 | runs-on: ubuntu-latest 31 | steps: 32 | - name: Checkout code 33 | uses: actions/checkout@v4 34 | 35 | - name: Use Node.js 20.x 36 | uses: actions/setup-node@v4 37 | with: 38 | node-version: 20.x 39 | cache: 'npm' 40 | 41 | - name: Install dependencies 42 | uses: borales/actions-yarn@v5 43 | with: 44 | cmd: install --immutable 45 | 46 | - name: Build docs 47 | uses: borales/actions-yarn@v5 48 | with: 49 | cmd: docs 50 | 51 | - name: Setup Pages 52 | uses: actions/configure-pages@v4 53 | 54 | - name: Upload artifact 55 | uses: actions/upload-pages-artifact@v3 56 | with: 57 | # Upload entire repository 58 | path: './docs' 59 | 60 | - name: Deploy to GitHub Pages 61 | id: deployment 62 | uses: actions/deploy-pages@v4 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IJ 33 | # 34 | .classpath 35 | .cxx 36 | .gradle 37 | .idea 38 | .project 39 | .settings 40 | local.properties 41 | android.iml 42 | 43 | # Cocoapods 44 | # 45 | example/ios/Pods 46 | 47 | # Ruby 48 | example/vendor/ 49 | 50 | # node.js 51 | # 52 | node_modules/ 53 | npm-debug.log 54 | yarn-debug.log 55 | yarn-error.log 56 | 57 | # BUCK 58 | buck-out/ 59 | \.buckd/ 60 | android/app/libs 61 | android/keystores/debug.keystore 62 | 63 | # Yarn 64 | .yarn/* 65 | !.yarn/patches 66 | !.yarn/plugins 67 | !.yarn/releases 68 | !.yarn/sdks 69 | !.yarn/versions 70 | 71 | # Expo 72 | .expo/ 73 | 74 | # Turborepo 75 | .turbo/ 76 | 77 | # generated by bob 78 | lib/ 79 | 80 | #machamp 81 | 82 | output/ 83 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.yarn/versions/47500c27.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/.yarn/versions/47500c27.yml -------------------------------------------------------------------------------- /.yarn/versions/bb9e8b5c.yml: -------------------------------------------------------------------------------- 1 | undecided: 2 | - camera-kit-react-native-example 3 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nmHoistingLimits: workspaces 2 | 3 | nodeLinker: node-modules 4 | 5 | plugins: 6 | - path: scripts/pod-install.cjs 7 | - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs 8 | spec: "@yarnpkg/plugin-interactive-tools" 9 | - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs 10 | spec: "@yarnpkg/plugin-workspace-tools" 11 | - path: .yarn/plugins/@yarnpkg/plugin-version.cjs 12 | spec: "@yarnpkg/plugin-version" 13 | 14 | yarnPath: .yarn/releases/yarn-3.6.1.cjs 15 | 16 | npmPublishRegistry: https://registry.npmjs.org/ 17 | npmRegistryServer: https://registry.npmjs.org/ 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Snap Inc. All Rights Reserved. 2 | 3 | Please see below the terms for use of Snap Camera Kit, as well as the licenses and notices for React Native and the React Native Wrapper for Snap Camera Kit. 4 | 5 | — 6 | 7 | Terms for Snap Camera Kit: 8 | 9 | Access to or use of Camera Kit and its associated documentation, software code, and other materials (collectively, “Camera Kit”), made available by Snap Inc. and its affiliates ("Snap"), is subject to the Snap Camera Kit Terms, which you have already accepted and can be found at: 10 | 11 | https://www.snap.com/terms/snap-camera-kit 12 | 13 | If you no longer want to be a party to these terms, or if you do not agree to all of these terms, do not use or otherwise access Camera Kit and notify Snap immediately. 14 | 15 | — 16 | 17 | License for Snap Camera Kit Wrapper for React Native: 18 | 19 | The Snap Camera Kit wrapper for React Native is made available under the MIT License as reproduced below. 20 | 21 | MIT License 22 | 23 | Copyright (c) 2024 Snap Inc. 24 | 25 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 26 | 27 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | — 32 | 33 | License for React Native: 34 | 35 | MIT License 36 | 37 | Copyright (c) Meta Platforms. Inc. and affiliates. 38 | 39 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 40 | 41 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 42 | 43 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Camera Kit wrapper for React Native 2 | 3 | > [!IMPORTANT] 4 | > This repository contains example projects to help you get started with Camera Kit integrations. The software is provided "as is" without any warranties or guarantees, and it is not officially supported for production use. 5 | > 6 | > Advanced functionalities like Remote API support, Inclusive Camera features, etc. are not supported in this wrapper implementation. If your project needs missing features, feel free to implement them yourself and submit a PR to this repo or use native development environment. 7 | 8 | The project provides a wrapper to Snap's [Camera Kit](https://ar.snap.com/camera-kit) solution that simplifies and speeds up the integration process for developers building React Native apps. While development on native platforms is still a recommended way, this wrapper provides a convenient way to implement basic functionalities of Camera Kit in React Native application. 9 | 10 | ## Installation 11 | 12 | You can install the Camera Kit React Native package using npm: 13 | 14 | ```sh 15 | npm install @snap/camera-kit-react-native 16 | ``` 17 | 18 | ## Usage 19 | 20 | Start with importing the following modules: 21 | 22 | ```js 23 | import { CameraKitContext } from '@snap/camera-kit-react-native'; 24 | import { useCameraKit } from '@snap/camera-kit-react-native'; 25 | ``` 26 | 27 | `CameraKitContext` component will contain global configuration for CameraKit session whereas `useCameraKit` hook will provide API for managing native CameraKit session, load lenses, apply lens, etc. 28 | 29 | For Android, make sure you have following permissions defined in `AndroidManifest.xml` file: 30 | 31 | ```xml 32 | 33 | 34 | 35 | 36 | ``` 37 | 38 | ### Please refer to the [example](./example) directory for detailed usage examples on how to integrate and use this wrapper in your React Native project. 39 | 40 | ***Usage example:*** 41 | ```js 42 | import { PreviewView, useCamera } from "@snap/camera-kit-react-native" 43 | import { useEffect } from "react" 44 | import { View, FlatList, Pressable, Image } from "react-native" 45 | import { Lenses } from "./lenses" 46 | 47 | export function App() { 48 | const { setPosition } = useCamera(); 49 | 50 | useEffect(async () => { 51 | setPosition("front"); 52 | }) 53 | 54 | return ( 55 | 56 | 57 | 58 | 59 | ) 60 | } 61 | ``` 62 | 63 | ***Lens carousel example:*** 64 | ```js 65 | import { PreviewView, useCameraKitManager } from "@snap/camera-kit-react-native" 66 | import { useEffect } from "react" 67 | import { View, FlatList, Pressable, Image } from "react-native" 68 | import { useCameraManager } from "./partner-camera" 69 | 70 | function Lenses({ groupId }: { groupId: string }) { 71 | const { loadLenses, applyLens } = useCameraKitManager(); 72 | const [lenses, setLenses] = useState([]); 73 | 74 | useEffect(async () => { 75 | const getLenses = async () => { 76 | const lenses = await loadLenses(groupId); 77 | setLenses(lenses); 78 | } 79 | 80 | getLenses().catch(console.error) 81 | 82 | return undefined; 83 | }, [loadLenses]) 84 | 85 | return ( 86 | 87 | ( 91 | { 93 | applyLens(item.item.id); 94 | }}> 95 | 98 | 99 | )} 100 | keyExtractor={item => item.id} 101 | /> 102 | 103 | ) 104 | } 105 | ``` 106 | 107 | ## Contributing 108 | Thank you for your interest in improving our project! :pray: 109 | 110 | Here's how you can contribute: 111 | 112 | 1. Fork and clone this repository. 113 | 2. Install dependencies by running `yarn install --immutable && yarn prepare`. 114 | 3. Make your changes. 115 | 4. Test your changes with the example app using `yarn example start`. Ensure everything works as expected. 116 | 5. Update the documentation if necessary by running `yarn docs`. 117 | 6. Submit a pull request with a clear description of your changes. 118 | 119 | ## License 120 | Please refer to the [LICENSE](/LICENSE) file for license information. 121 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | // Buildscript is evaluated before everything else so we can't use getExtOrDefault 3 | def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["CameraKitReactNative_kotlinVersion"] 4 | 5 | ext { 6 | cameraKitVersion = "1.39.0" 7 | exoPlayerVersion = "2.16.1" 8 | } 9 | 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | classpath "com.android.tools.build:gradle:8.0.1" 17 | // noinspection DifferentKotlinGradleVersion 18 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 19 | } 20 | } 21 | 22 | def isNewArchitectureEnabled() { 23 | return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true" 24 | } 25 | 26 | apply plugin: "com.android.library" 27 | apply plugin: "kotlin-android" 28 | 29 | if (isNewArchitectureEnabled()) { 30 | apply plugin: "com.facebook.react" 31 | } 32 | 33 | def getExtOrDefault(name) { 34 | return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["CameraKitReactNative_" + name] 35 | } 36 | 37 | def getExtOrIntegerDefault(name) { 38 | return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["CameraKitReactNative_" + name]).toInteger() 39 | } 40 | 41 | android { 42 | 43 | namespace "com.snap.camerakit.reactnative" 44 | 45 | compileSdkVersion getExtOrIntegerDefault("compileSdkVersion") 46 | 47 | defaultConfig { 48 | minSdkVersion getExtOrIntegerDefault("minSdkVersion") 49 | targetSdkVersion getExtOrIntegerDefault("targetSdkVersion") 50 | 51 | } 52 | 53 | buildTypes { 54 | release { 55 | minifyEnabled false 56 | } 57 | } 58 | 59 | lintOptions { 60 | disable "GradleCompatible" 61 | } 62 | 63 | compileOptions { 64 | sourceCompatibility JavaVersion.VERSION_1_8 65 | targetCompatibility JavaVersion.VERSION_1_8 66 | } 67 | } 68 | 69 | repositories { 70 | google() 71 | mavenCentral() 72 | } 73 | 74 | def kotlin_version = getExtOrDefault("kotlinVersion") 75 | 76 | dependencies { 77 | // For < 0.71, this will be from the local maven repo 78 | // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin 79 | //noinspection GradleDynamicVersion 80 | implementation "com.facebook.react:react-native:+" 81 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 82 | 83 | implementation "com.google.android.exoplayer:exoplayer-core:$exoPlayerVersion" 84 | 85 | // Provides the core implementation of Camera Kit 86 | implementation "com.snap.camerakit:camerakit:$cameraKitVersion" 87 | // Provides an easy way to handle permission prompts 88 | implementation "com.snap.camerakit:support-permissions:$cameraKitVersion" 89 | // Implementation of Camera pipeline for Camera Kit using CameraX library 90 | implementation "com.snap.camerakit:support-camerax:$cameraKitVersion" 91 | // Provides an easy way to satisfy Snap's attribution requirement for Camera Kit applications 92 | implementation "com.snap.camerakit:support-snap-attribution:$cameraKitVersion" 93 | } 94 | 95 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | CameraKitReactNative_kotlinVersion=1.7.0 2 | CameraKitReactNative_minSdkVersion=21 3 | CameraKitReactNative_targetSdkVersion=34 4 | CameraKitReactNative_compileSdkVersion=34 5 | CameraKitReactNative_ndkversion=21.4.7075529 6 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /android/src/main/java/com/snap/camerakit/reactnative/CameraImageProcessorModule.kt: -------------------------------------------------------------------------------- 1 | package com.snap.camerakit.reactnative 2 | 3 | import androidx.lifecycle.ProcessLifecycleOwner 4 | import com.facebook.react.bridge.ReactApplicationContext 5 | import com.facebook.react.bridge.ReactContextBaseJavaModule 6 | import com.facebook.react.module.annotations.ReactModule 7 | import com.snap.camerakit.ImageProcessor 8 | import com.snap.camerakit.support.camera.AllowsCameraPreview 9 | import com.snap.camerakit.support.camera.AspectRatio 10 | import com.snap.camerakit.support.camera.Crop 11 | import com.snap.camerakit.support.camerax.CameraXImageProcessorSource 12 | import java.util.concurrent.Executors 13 | 14 | @ReactModule(name = CameraImageProcessorModule.NAME) 15 | class CameraImageProcessorModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { 16 | 17 | var facingFront = true 18 | var aspectRatio = AspectRatio.RATIO_16_9 19 | var mirrorFramesHorizontally = false 20 | var mirrorFramesVertically = false 21 | var crop: ImageProcessor.Input.Option.Crop? = null 22 | val imageProcessorSource = CameraXImageProcessorSource( 23 | context = reactApplicationContext.applicationContext, 24 | lifecycleOwner = ProcessLifecycleOwner.get(), 25 | executorService = Executors.newSingleThreadExecutor(), 26 | videoOutputDirectory = reactApplicationContext.applicationContext.cacheDir 27 | ) 28 | 29 | fun stopPreview() { 30 | imageProcessorSource.stopPreview() 31 | } 32 | 33 | fun startPreview() { 34 | val inputOptions = mutableSetOf() 35 | 36 | if (mirrorFramesVertically) { 37 | inputOptions.add(ImageProcessor.Input.Option.MirrorFramesVertically) 38 | } 39 | 40 | // On Android, in case if camera is facing front, frames are mirrored by default 41 | // in that case in order to support consistency between platforms I need to 42 | // invert the vertical frames mirroring if camera is facing front. 43 | if (facingFront && !mirrorFramesHorizontally) { 44 | inputOptions.add(ImageProcessor.Input.Option.MirrorFramesHorizontally) 45 | } 46 | // With the back camera behaviour is the same for both platforms. 47 | else if(!facingFront && mirrorFramesHorizontally){ 48 | inputOptions.add(ImageProcessor.Input.Option.MirrorFramesHorizontally) 49 | } 50 | 51 | crop?.let { 52 | inputOptions.add(it) 53 | } 54 | 55 | val configuration = AllowsCameraPreview.Configuration.Default(facingFront, aspectRatio, Crop.None) 56 | imageProcessorSource.startPreview( 57 | configuration, inputOptions 58 | ) {} 59 | } 60 | 61 | override fun getName() = NAME 62 | 63 | companion object { 64 | internal const val NAME = "CameraImageProcessor" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /android/src/main/java/com/snap/camerakit/reactnative/CameraKitEventEmitter.kt: -------------------------------------------------------------------------------- 1 | package com.snap.camerakit.reactnative 2 | 3 | import com.facebook.react.bridge.Arguments 4 | import com.facebook.react.bridge.ReactApplicationContext 5 | import com.facebook.react.bridge.ReactContextBaseJavaModule 6 | import com.facebook.react.bridge.ReactMethod 7 | import com.facebook.react.bridge.WritableMap 8 | import com.facebook.react.module.annotations.ReactModule 9 | import com.facebook.react.modules.core.DeviceEventManagerModule 10 | 11 | @ReactModule(name = CameraKitEventEmitter.NAME) 12 | class CameraKitEventEmitter(reactContext: ReactApplicationContext) : 13 | ReactContextBaseJavaModule(reactContext) { 14 | 15 | @ReactMethod 16 | fun addListener(eventName: String?) { 17 | // Keep: Required for RN built in Event Emitter Calls. 18 | } 19 | @ReactMethod 20 | fun removeListeners(count: Int?) { 21 | // Keep: Required for RN built in Event Emitter Calls. 22 | } 23 | 24 | fun sendError(item: Throwable){ 25 | val params = Arguments.createMap().apply { 26 | putString("message", item.message) 27 | putString("cause", item.cause?.message) 28 | putString("stackTrace", item.stackTrace.joinToString("\n")) 29 | } 30 | sendEvent(EventType.Error, params) 31 | } 32 | 33 | fun sendWarning(message: String){ 34 | sendEvent(EventType.Warning, Arguments.createMap().apply { 35 | putString("message", message) 36 | }) 37 | } 38 | 39 | private fun sendEvent( eventName: EventType, params: WritableMap?) { 40 | reactApplicationContext 41 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) 42 | .emit(eventName.toString(), params) 43 | } 44 | 45 | 46 | enum class EventType(private val value: String) { 47 | Error("error"), 48 | Warning("warn"), 49 | Log("log"), 50 | Info("info"), 51 | Debug("debug"); 52 | 53 | override fun toString(): String { 54 | return value 55 | } 56 | } 57 | 58 | override fun getName() = NAME 59 | companion object { 60 | internal const val NAME = "CameraKitEventEmitter" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /android/src/main/java/com/snap/camerakit/reactnative/CameraKitReactNativePackage.kt: -------------------------------------------------------------------------------- 1 | package com.snap.camerakit.reactnative 2 | 3 | import com.facebook.react.ReactPackage 4 | import com.facebook.react.bridge.NativeModule 5 | import com.facebook.react.bridge.ReactApplicationContext 6 | import com.facebook.react.uimanager.ViewManager 7 | 8 | class CameraKitReactNativePackage : ReactPackage { 9 | override fun createNativeModules(reactContext: ReactApplicationContext): List { 10 | return listOf( 11 | CameraImageProcessorModule(reactContext), 12 | CameraKitEventEmitter(reactContext), 13 | CameraKitContextModule(reactContext), 14 | ) 15 | } 16 | 17 | override fun createViewManagers(reactContext: ReactApplicationContext): List> { 18 | return listOf(CameraPreviewManager()) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /android/src/main/java/com/snap/camerakit/reactnative/CameraPreview.kt: -------------------------------------------------------------------------------- 1 | package com.snap.camerakit.reactnative 2 | 3 | import android.annotation.SuppressLint 4 | import android.graphics.Rect 5 | import android.view.TextureView 6 | import android.widget.FrameLayout 7 | import com.facebook.react.uimanager.ThemedReactContext 8 | import com.snap.camerakit.connectOutput 9 | import java.io.Closeable 10 | 11 | @SuppressLint("ViewConstructor") 12 | class CameraPreview(reactApplicationContext: ThemedReactContext) : 13 | FrameLayout(reactApplicationContext.applicationContext) { 14 | 15 | val imageProcessorModule: CameraImageProcessorModule = 16 | reactApplicationContext.getNativeModule(CameraImageProcessorModule::class.java)!! 17 | var safeRenderArea: Rect? = null 18 | 19 | private val cameraKitModule: CameraKitContextModule = 20 | reactApplicationContext.getNativeModule(CameraKitContextModule::class.java)!! 21 | private val textureView: TextureView 22 | private val closeOnDetach = mutableListOf() 23 | 24 | init { 25 | inflate(context, R.layout.camera_kit_view, this) 26 | this.textureView = findViewById(R.id.ck_texture_view) 27 | } 28 | 29 | fun restartPreview() { 30 | if (isAttachedToWindow) { 31 | imageProcessorModule.stopPreview() 32 | if(safeRenderArea != null){ 33 | cameraKitModule.setSafeRenderArea?.accept(safeRenderArea) 34 | } 35 | imageProcessorModule.startPreview() 36 | } 37 | } 38 | 39 | override fun onDetachedFromWindow() { 40 | removeView(cameraKitModule.touchViewContainer) 41 | imageProcessorModule.stopPreview() 42 | 43 | closeOnDetach.forEach { closeable -> 44 | closeable.close() 45 | } 46 | 47 | closeOnDetach.clear() 48 | 49 | super.onDetachedFromWindow() 50 | } 51 | 52 | 53 | override fun onAttachedToWindow() { 54 | addView(cameraKitModule.touchViewContainer) 55 | if (cameraKitModule.currentSession != null) { 56 | cameraKitModule.currentSession!!.processor.connectOutput(this.textureView).closeOnDetach() 57 | imageProcessorModule.startPreview() 58 | } 59 | 60 | super.onAttachedToWindow() 61 | } 62 | 63 | private fun Closeable.closeOnDetach() { 64 | if (isAttachedToWindow) { 65 | closeOnDetach.add(this) 66 | } else { 67 | close() 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /android/src/main/java/com/snap/camerakit/reactnative/CameraPreviewManager.kt: -------------------------------------------------------------------------------- 1 | package com.snap.camerakit.reactnative 2 | 3 | import android.graphics.Rect 4 | import com.facebook.react.bridge.ReadableMap 5 | import com.facebook.react.uimanager.SimpleViewManager 6 | import com.facebook.react.uimanager.ThemedReactContext 7 | import com.facebook.react.uimanager.annotations.ReactProp 8 | import com.snap.camerakit.ImageProcessor 9 | import com.snap.camerakit.support.camera.AspectRatio 10 | 11 | class CameraPreviewManager : SimpleViewManager() { 12 | override fun getName() = "CameraPreview" 13 | 14 | override fun createViewInstance(context: ThemedReactContext): CameraPreview { 15 | return CameraPreview(context) 16 | } 17 | 18 | override fun onAfterUpdateTransaction(view: CameraPreview) { 19 | super.onAfterUpdateTransaction(view) 20 | view.restartPreview() 21 | } 22 | 23 | @ReactProp(name = "cameraPosition") 24 | fun setPosition(view: CameraPreview, type: String) { 25 | view.imageProcessorModule.facingFront = type == "front" 26 | } 27 | 28 | @ReactProp(name = "ratio") 29 | fun setAspectRatio(view: CameraPreview, type: String) { 30 | view.imageProcessorModule.aspectRatio = 31 | if (AspectRatio.RATIO_16_9.name == type) AspectRatio.RATIO_16_9 else AspectRatio.RATIO_4_3 32 | } 33 | 34 | @ReactProp(name = "mirrorFramesHorizontally") 35 | fun setMirrorFramesHorizontally(view: CameraPreview, value: Boolean) { 36 | view.imageProcessorModule.mirrorFramesHorizontally = value 37 | } 38 | 39 | @ReactProp(name = "mirrorFramesVertically") 40 | fun setMirrorFramesVertically(view: CameraPreview, value: Boolean) { 41 | view.imageProcessorModule.mirrorFramesVertically = value 42 | } 43 | 44 | @ReactProp(name = "crop") 45 | fun setCrop(view: CameraPreview, value: ReadableMap?) { 46 | if (value == null) { 47 | view.imageProcessorModule.crop = value 48 | } else { 49 | view.imageProcessorModule.crop = ImageProcessor.Input.Option.Crop.Center( 50 | value.getInt("aspectRatioNumerator"), value.getInt("aspectRatioDenominator") 51 | ) 52 | } 53 | } 54 | 55 | @ReactProp(name = "safeRenderArea") 56 | fun setSafeRenderArea(view: CameraPreview, value: ReadableMap?) { 57 | view.safeRenderArea = if (value == null) { 58 | Rect(0, 0, view.width, view.height) 59 | } else { 60 | Rect( 61 | value.getInt("left"), value.getInt("top"), value.getInt("right"), value.getInt("bottom") 62 | ) 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /android/src/main/java/com/snap/camerakit/reactnative/TouchViewContainer.kt: -------------------------------------------------------------------------------- 1 | package com.snap.camerakit.reactnative 2 | 3 | import android.content.Context 4 | import android.view.ViewStub 5 | import android.widget.FrameLayout 6 | 7 | class TouchViewContainer(context: Context) : FrameLayout(context) { 8 | 9 | val touchViewStub: ViewStub 10 | init { 11 | inflate(context, R.layout.camera_kit_touch, this) 12 | this.touchViewStub = findViewById(R.id.ck_touch_view) 13 | } 14 | 15 | override fun requestLayout() { 16 | super.requestLayout() 17 | 18 | // Workaround to resize dynamically added children https://github.com/facebook/react-native/issues/4990. 19 | post(measureAndLayout) 20 | } 21 | 22 | private val measureAndLayout = Runnable { 23 | measure( 24 | MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), 25 | MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) 26 | ) 27 | layout(left, top, right, bottom) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /android/src/main/res/layout/camera_kit_touch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /android/src/main/res/layout/camera_kit_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /camera-kit-react-native.podspec: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 4 | folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' 5 | 6 | Pod::Spec.new do |s| 7 | s.name = "camera-kit-react-native" 8 | s.version = package["version"] 9 | s.summary = package["description"] 10 | s.homepage = package["homepage"] 11 | s.license = package["license"] 12 | s.authors = package["author"] 13 | 14 | s.platforms = { :ios => "12.0" } 15 | s.source = { :git => "https://github.com/snapchat/camera-kit-react-native.git", :tag => "#{s.version}" } 16 | 17 | s.source_files = "ios/**/*.{h,m,mm,swift}" 18 | 19 | s.dependency "SCCameraKit" 20 | s.dependency "SCCameraKitReferenceUI" 21 | 22 | # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0. 23 | # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79. 24 | if respond_to?(:install_modules_dependencies, true) 25 | install_modules_dependencies(s) 26 | else 27 | s.dependency "React-Core" 28 | 29 | # Don't install the dependencies when we run `pod install` in the old architecture. 30 | if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then 31 | s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" 32 | s.pod_target_xcconfig = { 33 | "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", 34 | "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", 35 | "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" 36 | } 37 | s.dependency "React-Codegen" 38 | s.dependency "RCT-Folly" 39 | s.dependency "RCTRequired" 40 | s.dependency "RCTTypeSafety" 41 | s.dependency "ReactCommon/turbomodule/core" 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/assets/highlight.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --light-hl-0: #795E26; 3 | --dark-hl-0: #DCDCAA; 4 | --light-hl-1: #000000; 5 | --dark-hl-1: #D4D4D4; 6 | --light-hl-2: #A31515; 7 | --dark-hl-2: #CE9178; 8 | --light-hl-3: #AF00DB; 9 | --dark-hl-3: #C586C0; 10 | --light-hl-4: #001080; 11 | --dark-hl-4: #9CDCFE; 12 | --light-hl-5: #0000FF; 13 | --dark-hl-5: #569CD6; 14 | --light-hl-6: #0070C1; 15 | --dark-hl-6: #4FC1FF; 16 | --light-hl-7: #800000; 17 | --dark-hl-7: #808080; 18 | --light-hl-8: #267F99; 19 | --dark-hl-8: #4EC9B0; 20 | --light-hl-9: #E50000; 21 | --dark-hl-9: #9CDCFE; 22 | --light-hl-10: #000000FF; 23 | --dark-hl-10: #D4D4D4; 24 | --light-hl-11: #098658; 25 | --dark-hl-11: #B5CEA8; 26 | --light-hl-12: #008000; 27 | --dark-hl-12: #6A9955; 28 | --light-code-background: #FFFFFF; 29 | --dark-code-background: #1E1E1E; 30 | } 31 | 32 | @media (prefers-color-scheme: light) { :root { 33 | --hl-0: var(--light-hl-0); 34 | --hl-1: var(--light-hl-1); 35 | --hl-2: var(--light-hl-2); 36 | --hl-3: var(--light-hl-3); 37 | --hl-4: var(--light-hl-4); 38 | --hl-5: var(--light-hl-5); 39 | --hl-6: var(--light-hl-6); 40 | --hl-7: var(--light-hl-7); 41 | --hl-8: var(--light-hl-8); 42 | --hl-9: var(--light-hl-9); 43 | --hl-10: var(--light-hl-10); 44 | --hl-11: var(--light-hl-11); 45 | --hl-12: var(--light-hl-12); 46 | --code-background: var(--light-code-background); 47 | } } 48 | 49 | @media (prefers-color-scheme: dark) { :root { 50 | --hl-0: var(--dark-hl-0); 51 | --hl-1: var(--dark-hl-1); 52 | --hl-2: var(--dark-hl-2); 53 | --hl-3: var(--dark-hl-3); 54 | --hl-4: var(--dark-hl-4); 55 | --hl-5: var(--dark-hl-5); 56 | --hl-6: var(--dark-hl-6); 57 | --hl-7: var(--dark-hl-7); 58 | --hl-8: var(--dark-hl-8); 59 | --hl-9: var(--dark-hl-9); 60 | --hl-10: var(--dark-hl-10); 61 | --hl-11: var(--dark-hl-11); 62 | --hl-12: var(--dark-hl-12); 63 | --code-background: var(--dark-code-background); 64 | } } 65 | 66 | :root[data-theme='light'] { 67 | --hl-0: var(--light-hl-0); 68 | --hl-1: var(--light-hl-1); 69 | --hl-2: var(--light-hl-2); 70 | --hl-3: var(--light-hl-3); 71 | --hl-4: var(--light-hl-4); 72 | --hl-5: var(--light-hl-5); 73 | --hl-6: var(--light-hl-6); 74 | --hl-7: var(--light-hl-7); 75 | --hl-8: var(--light-hl-8); 76 | --hl-9: var(--light-hl-9); 77 | --hl-10: var(--light-hl-10); 78 | --hl-11: var(--light-hl-11); 79 | --hl-12: var(--light-hl-12); 80 | --code-background: var(--light-code-background); 81 | } 82 | 83 | :root[data-theme='dark'] { 84 | --hl-0: var(--dark-hl-0); 85 | --hl-1: var(--dark-hl-1); 86 | --hl-2: var(--dark-hl-2); 87 | --hl-3: var(--dark-hl-3); 88 | --hl-4: var(--dark-hl-4); 89 | --hl-5: var(--dark-hl-5); 90 | --hl-6: var(--dark-hl-6); 91 | --hl-7: var(--dark-hl-7); 92 | --hl-8: var(--dark-hl-8); 93 | --hl-9: var(--dark-hl-9); 94 | --hl-10: var(--dark-hl-10); 95 | --hl-11: var(--dark-hl-11); 96 | --hl-12: var(--dark-hl-12); 97 | --code-background: var(--dark-code-background); 98 | } 99 | 100 | .hl-0 { color: var(--hl-0); } 101 | .hl-1 { color: var(--hl-1); } 102 | .hl-2 { color: var(--hl-2); } 103 | .hl-3 { color: var(--hl-3); } 104 | .hl-4 { color: var(--hl-4); } 105 | .hl-5 { color: var(--hl-5); } 106 | .hl-6 { color: var(--hl-6); } 107 | .hl-7 { color: var(--hl-7); } 108 | .hl-8 { color: var(--hl-8); } 109 | .hl-9 { color: var(--hl-9); } 110 | .hl-10 { color: var(--hl-10); } 111 | .hl-11 { color: var(--hl-11); } 112 | .hl-12 { color: var(--hl-12); } 113 | pre, code { background: var(--code-background); } 114 | -------------------------------------------------------------------------------- /docs/assets/navigation.js: -------------------------------------------------------------------------------- 1 | window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAE43WUW/TMBAH8O/i546ywgb0dRRpooWqlfqCeLjZt9QisSP7km1CfHeUpG2c5OLm1ff3z3HinvvrryB8JbEUa5sk6MRM5EBHsRQyBe/Rz5vxd0fKUjETf7RRYnm7+Pxvdpn5A0iXuCrR0CrTRJwyzAzEWRMWS0Fe3Wh/g6+EzkAqgrUeIEMH3zU9WFMNbZ3NfbucNoTuGST6OZvsLrq4u+folXPWxc06MgnbExDGsTpyHfuZk7YmttlTIkadXv6+ePLS6TrPgkxuwE76YGsceeSqEHvSqr6GwsjjVyAYJdpIDNug0rxRV2JTTyd39EwE9RizN5BLq/ijcC7GgINWaHcorVPaJCzTjcSwxwwS/GZdBhR8HXrL0c/DWs94/+XT7d0i/Eg2WRlyb33jPD5h/hpLTJn59fi1+c3Lb07/QeNLrx00GBuaJm+sKlLkwabGOpN+GTuU1JersWtPdukbOwRJzbO0TglOw1Ma9pcg17U/sGzdjk5NM+qGwQjcrFy9eE5rqxFCnpeszlV1h3iOGqambHew0+fCyLqPDq6QLnf/ccBtHZYaX7p77XtBKAImSPwRbLleZApWLboBA52bnhGDXITVfuzObMl+JsqxvTa0RpttD9oXeW4doQqaGS9yySh9gFSr5tbZgoOMZ/upCFl4vLwiDgvrU5gtukx73/2vwHBBLs4++o0tDKEa4S71AfP7P1vbUs5fCgAA" -------------------------------------------------------------------------------- /docs/assets/search.js: -------------------------------------------------------------------------------- 1 | window.searchData = "data:application/octet-stream;base64,H4sIAAAAAAAAE82cS3PbRhKA/wt4pWUB8wCkWyqb7LpW3risrC8slQshRzRKJIAFQCaOyv99awavbrAbBCgl5RMtsl/TX8+gMRj42Suy30vvdvXsPSXpxrvVcuml8d54t96P8d4U8b+T6scsrcwflbf0DsXOu/UeD+m6SrK0fDsUufpS7Xfe0lvv4rI0pXfred+WhOlDaTpVwiz8edykUkJ3Vj9/rr7mZoq9Bfqm0wM+ll4eFyatBsFeocj7QPzroB9dUt6bskyy9KOJN18vjefqxMzM8NpxMVHGeb77emfS8uIAoYUXx/aaKPvImi/e+BeHCEbJJLIw++xoXpRJZOL7SmUfWptLdXkuwTiZZFbxk7lP47z8kk1aGciYB0a+r4TC4NqUhpenFI2VSeouizc26f8sskN+ceBDK99XWlF0bV7F5XnFox2p1k/JxmQvqobWwveV0C6yNpk3LyvSepR/W7Ddyn/d/esFF4Gh/TPX1rLKLp9n08Zy1fh43QH97TXFDq37M/irBllnsB9poPpxOq2PZp0VmyTdduNN0soUj/HalG+xxGiXypfGuL3FKOJBiBOJTfB4rh8e6A2yeHID8aEwx8T8/ikxv7N3EEBmNJMQEWq4wLBcqzIZR7IZtbFwv9N5GGtj3Meo4UZivulknZ0Z+KIVmW98a692787kpBea7yCvSZ8ZAJCa76JM43ydbcwZH1BsvpPHeJ2k2w+FeTSFSddnYBPS810eTbrJin/EVTzuDMlNchNc34S+CjpPH826b77tWlC+tV9Nnpr1pP4ld1OcChYJTJ+seVYmVmWayQUQp9OA42Sc7pOiyIqfi3hvyn9lRfJnllbxbvd1YhAj6i8Ial0vm/PycaL0ggDK+NF8NOnGFD8UhixIIoATpXkBUBtIH0yxT9wuyejdNxB71Q2lod0F+cvUDSaoQ46QmxedyH0VV4dZmRiL+Iow/MIhnGmcC/O/gylH7/xnDaC39+px/5Wl0sY9Y/tq4gC6jAAAQdQ3Vdl2a4puGI3Pt/XXozNH+f31w7YfVXFYV9moqQWWYy5VdUTczoY5ml056qQT6e1X5eZNUr7Ji+QYV2a6t/LwW7kuksF1jXI6lLzId3AtezKlqe7ODxZKTcwn8rLLtuPJdL9Ptozbirts64IbtBbt1+Ptxamtn9Kq+Hpqy3099UFEUnY3jT/Z6zQxgYci003/J66So+Htgt8nt1aUTXDRnWoSNxPZhuxfh8YWjSCNH0bGtVKmLOPtNF+97MXuUidyX8Xrpx/STZHR93onnkm11wji3S/3cwOoVS52fihN8S59zCa5BcJzHJ42/ieT6aQrnDSXppYOYfJs9QwCZfdq4vXTr0VM395RfpHGS1yv40M52WsrPNMhWqzuD3meFZXZvNvHW/NzVuxjqg2jBWct3UCvHCzf8KcZz5Lfle+zQ1qZDd1/dT+/UuuP7S3QN+db/V4WRc4+S54xNCqUK2hhZlAvaXrnRDapzR0NEYySLJKtqerV6322OeyokAcSU6uvU7N7l+/jNIbtM2EdiM3a6byLD+n6y9jmTy8xfVXdOZ0PcRHv2d2ygd3FQIffYAIh9+5FMGhl0L7wMS6S+Lddd3U6vyE8WFtqtXrFs8ofiiwfLjKkzKgXEPS6XUxtp3k0KVjC+uBPhSazfm82CYnY/TBjX9uupP8tduOmFkCMBlnHQ8d63+ygUj7a314nYmTtfNBdYIyrjTH5XZI+nXcFJCe7AtXSXXo/mnjdrABEvVBiMzdb+zNYuOSpzgEKTucT58mv2ZMZ2WykTC+A2pn2BMXPnmTYDu6Cp0UB9S4Lg0y53RUb79KcxIxJQB8dG7e8mHhSbBD2eMU6meHJP6Jkodz0W+NP8S7Z3PVXErLTHApR5h+WXpJuzB/e7bN3NIVNgnfrBVfiyh5XeEzMbmOPN7YP5NbZfm+T8dD89snYzScrUYu8vfaWq+ulvL4K/ZuHh+Wq1XA/uC+cmO8tVz4l5iOxwFuugqUfXYVSI7EAiQlvuRJLoa60j6QEkpLeciUpnxKJKc6nQmLaW64UZU0jsZCzFiKxyFuuNGUtQmI3nLUbnF2b7JBM7wCDzxn0MQh7imAVkRYxCl+wFjENX7KCmIdv835D0PUxEF+zBjES36beJ4vUx1T8iHONsfgsFx+DCWz6fbLwA0wmcDMkICUHc8QC8AUpidkEloBPToEAwwksAp8s7wDTCSwEnyzdAPMJLAWfrMoAAwocILLaAgwosBz8G1ISIwocIhJ6gBkJCyIgGQnMSLjZQzISmJFwCxnJSAyWMjd/SEYCMxJuApGMBGYk3JJGMhKYkXBziGQkMCPBLmwCIxKWQ0DCFBiRcIhImAIjktecc4kJSYtBkNQlJiQtBkFSl5iQdFcbkrocXHAsBkFSl5iQtBgEfXHChKTFIEjqEhOSloMgqUuMSFoOgqQuMSJpOQgSpsSIlAUhSJgKM1IWhCQZKcxIWRCSZKQwI2VByIBYuRVGpFxTQCJSg7bAcpAkIoURKctBkogURqQsB0kiUhiRitgBYULKYpAkS4UJaYtBkiw1JqQdIZKlxoS0xaBIlhoT0paDIllqjEizjYLGhLTFoMiJqQe9G9sqaAxIWwqKLA+NAWmLQZHloTEhbTEounXEhEKLQZHlEWJCocWgSOohJhQ6QiT1EBMKHSGSeogJhZaDJqmHGFFoOWifKOMQEwotB02yDAcNdsiaxIRC12OTLENMKLQYNMkyxIQii0GTLCNMKLIYNN3iY0KRxaBJlhEmFFkMmmQZYUKRZO6QIswncnxI5hEGFFkKIck8qgG5O8ujcU866jvM1arb8X72Pje3nd2t87MXeLfP35aeqj/C+uOm/vD95lM0n7L51M1nIycaNXldf+pGTju5b/0drP3LRh3nSVXvr/Qxad0HFfmsYr77unOHaHtN2StKRq/e3HxKqnW7OdCrX/fq1xPV83q7CgSvQPBnrZj6QSMYARi7Cs+p77KtaXZxexPqpjcRinMmCrtnlzZbe2AYIJXhzTkjZb2RBNQjkIWzMTh1gocGI4nUqJWsPasCShvUtuDKqNbuj1oCdQBSjFdTc9736J4F9BZ8H0wuvhTcw09QASB1mtVy+9ZACbhSAasEziv1ugLoSk7X7iTv3E4ywCNAjUSMYn12OAdnh0GCAN+AM7A1TXnum2dfoNJBAJqbLJ2+xbNvH3EBI6DSNRuEPTNuT1KA4MFMDbjibI6yAy1QVQFXVQNHYJQBx8c9VHhsn0qD0YE1TY8q2w1MCBdURdheE7gcJyW/oglQz5JbSZJy3z7lBbGDCazZDJc13VO/oLgUN48SuxNrd12LeusZqIPZX48+YnGVZXuoAGBA0xPEormlKCmPdse4fkCZ19vKvYkQgIy4qynQxVUAajXkcjG8mPqwN+CCtkq11417uAt8gkrXHPf2dCPIO/AquSuHfbvRet7W73KCLPXKPjtOewgQOARxSjax2dbU5/WAInAmuYVj15xIBWoApGTTmm139VlDoAggSm4mtoq4JwGRRtwisK8f3QItEGjI1X53UgkUOyComrmjuPzU7xc8uvcLvqD3C8CVGKzQgisJJwCrFygFvJJdOuq1y14eTro5BRavkMscswBJkD/Fga513bmruD2tB0yAVUhxCICJJMPtMMiB4hbQ/uKIBg5KJuSC78/Xl835egANZE5w9Mm+C668XMr7N6wAcRBywE3kwr0bBLyBy5zgVoz6vf/h+gjXN1axOb8PHIJLgeCWRfumSeHeNIndmyZAHSwCgkNamopYWOHNEavZnYkA6wCYzyE3UvA6GiACaiDgVixXuFV95hCULoCp2DS5F0x7JZBav2lZfK70BkfcQZ5A/UluztlXc8vuv2gAuQIL7YjqsX5lvtcDifK5mj+UpuuyUJaB7jnVHL5vBKoKZFtwiA+lods0EIDmVlp7Ojdxp3MBYzCDFOe1fh1w2FwEYG0NuPJwWS76t6BByoC6Txbmw9LLk9zsktR4t6uHb9/+D+KGccVrSAAA"; -------------------------------------------------------------------------------- /docs/functions/getNativeModule.html: -------------------------------------------------------------------------------- 1 | getNativeModule | @snap/camera-kit-react-native
  • Type Parameters

    • T

    Parameters

    • moduleName: string

    Returns T

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/functions/isNativeError.html: -------------------------------------------------------------------------------- 1 | isNativeError | @snap/camera-kit-react-native
  • Checks if the error is a native error.

    2 |

    Parameters

    • error: any

      the error to check

      3 |

    Returns error is NativeError

    true if the error is a native error, false otherwise

    4 |

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/functions/isValidLaunchParam.html: -------------------------------------------------------------------------------- 1 | isValidLaunchParam | @snap/camera-kit-react-native
  • Parameters

    • value: unknown

    Returns boolean

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/types/ImageFormats.html: -------------------------------------------------------------------------------- 1 | ImageFormats | @snap/camera-kit-react-native
ImageFormats: "JPEG" | "PNG"

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/types/LogLevel.html: -------------------------------------------------------------------------------- 1 | LogLevel | @snap/camera-kit-react-native
LogLevel: LogEntry["level"]

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/types/NativeCameraViewProps.html: -------------------------------------------------------------------------------- 1 | NativeCameraViewProps | @snap/camera-kit-react-native
NativeCameraViewProps: ViewProps & Partial<CameraOptions>

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/types/Rect.html: -------------------------------------------------------------------------------- 1 | Rect | @snap/camera-kit-react-native
Rect: Record<"top" | "left" | "bottom" | "right", number>

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/variables/CameraKitReactNative.html: -------------------------------------------------------------------------------- 1 | CameraKitReactNative | @snap/camera-kit-react-native

Variable CameraKitReactNativeConst

CameraKitReactNative: CameraKitContextModule = ...

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/variables/CameraKitStateContext.html: -------------------------------------------------------------------------------- 1 | CameraKitStateContext | @snap/camera-kit-react-native

Variable CameraKitStateContextConst

CameraKitStateContext: Context<CameraKitState> = ...

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/variables/NativeView.html: -------------------------------------------------------------------------------- 1 | NativeView | @snap/camera-kit-react-native
NativeView: HostComponent<NativeCameraViewProps> = ...

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/variables/cameraKitLogEvents.html: -------------------------------------------------------------------------------- 1 | cameraKitLogEvents | @snap/camera-kit-react-native

Variable cameraKitLogEventsConst

cameraKitLogEvents: NativeEventEmitter = ...

Generated using TypeDoc

-------------------------------------------------------------------------------- /example/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | gem 'cocoapods', '~> 1.13' 7 | gem 'activesupport', '>= 6.1.7.3', '< 7.1.0' 8 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli). 2 | 3 | # Getting Started 4 | 5 | Ensure that you have access to _Camera Kit API token_ and _Lens Group ID_ to put in your application or run the provided _example_ application. Refer to [this guide](https://docs.snap.com/camera-kit/getting-started/setting-up-accounts) for Camera Kit account setup. 6 | 7 | Also, make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding. 8 | 9 | ## Step 1: Enter Camera Kit API token and group ID 10 | 11 | 1. Open `App.tsx` in and enter value for `apiToken` with the one you get from Camera Kit Developer portal. 12 | 2. Open `Lenses.tsx` and enter value for `groupId` from which you want to fetch lenses. [Optional] Enter value for `launchDataLensId` for the Lens which has launch data associated with it or remove all the relevant code that uses this param. 13 | 3. [_Optional_] This example is using version 1.39.0 of Camera Kit Mobile SDK for Android and latest version on iOS. If you want to use the [latest version](https://docs.snap.com/camera-kit/integrate-sdk/mobile/changelog-mobile#latest-version) of Camera Kit Mobile SDK on Android then modify `cameraKitVersion` variable in [build.gradle](../android/build.gradle) file. Please refer to [Lens Studio Compatibility](https://docs.snap.com/camera-kit/ar-content/lens-studio-compatibility) guide for selecting the appropriate version that work with your Lenses. 14 | 15 | ## Step 2: Start the Metro Server 16 | 17 | You will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native. 18 | 19 | To start Metro, run the following command from the _root_ of your React Native project: 20 | 21 | ```bash 22 | yarn start 23 | ``` 24 | 25 | ## Step 3: Start your Application 26 | 27 | Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app: 28 | 29 | ### For Android 30 | 31 | ```bash 32 | yarn android 33 | ``` 34 | 35 | ### For iOS 36 | 37 | ```bash 38 | yarn ios 39 | ``` 40 | 41 | If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly. 42 | 43 | This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively. 44 | 45 | ## Step 4: Modifying your App 46 | 47 | Now that you have successfully run the app, let's modify it. 48 | 49 | 1. Open `App.tsx` in your text editor of choice and edit some lines. 50 | 2. For **Android**: Press the R key twice or select **"Reload"** from the **Developer Menu** (Ctrl + M (on Window and Linux) or Cmd ⌘ + M (on macOS)) to see your changes! 51 | 52 | For **iOS**: Hit Cmd ⌘ + R in your iOS Simulator to reload the app and see your changes! 53 | 54 | ## Congratulations! :tada: 55 | 56 | You've successfully run and modified your React Native App. :partying_face: 57 | 58 | ### Now what? 59 | 60 | - If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps). 61 | - If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started). 62 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "com.facebook.react" 3 | 4 | /** 5 | * This is the configuration block to customize your React Native Android app. 6 | * By default you don't need to apply any configuration, just uncomment the lines you need. 7 | */ 8 | react { 9 | /* Folders */ 10 | // The root of your project, i.e. where "package.json" lives. Default is '..' 11 | // root = file("../") 12 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native 13 | // reactNativeDir = file("../node_modules/react-native") 14 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen 15 | // codegenDir = file("../node_modules/@react-native/codegen") 16 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js 17 | // cliFile = file("../node_modules/react-native/cli.js") 18 | 19 | /* Variants */ 20 | // The list of variants to that are debuggable. For those we're going to 21 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 22 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 23 | // debuggableVariants = ["liteDebug", "prodDebug"] 24 | 25 | /* Bundling */ 26 | // A list containing the node command and its flags. Default is just 'node'. 27 | // nodeExecutableAndArgs = ["node"] 28 | // 29 | // The command to run when bundling. By default is 'bundle' 30 | // bundleCommand = "ram-bundle" 31 | // 32 | // The path to the CLI configuration file. Default is empty. 33 | // bundleConfig = file(../rn-cli.config.js) 34 | // 35 | // The name of the generated asset file containing your JS bundle 36 | // bundleAssetName = "MyApplication.android.bundle" 37 | // 38 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 39 | // entryFile = file("../js/MyApplication.android.js") 40 | // 41 | // A list of extra flags to pass to the 'bundle' commands. 42 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 43 | // extraPackagerArgs = [] 44 | 45 | /* Hermes Commands */ 46 | // The hermes compiler command to run. By default it is 'hermesc' 47 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 48 | // 49 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 50 | // hermesFlags = ["-O", "-output-source-map"] 51 | } 52 | 53 | /** 54 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 55 | */ 56 | def enableProguardInReleaseBuilds = false 57 | 58 | /** 59 | * The preferred build flavor of JavaScriptCore (JSC) 60 | * 61 | * For example, to use the international variant, you can use: 62 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 63 | * 64 | * The international variant includes ICU i18n library and necessary data 65 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 66 | * give correct results when using with locales other than en-US. Note that 67 | * this variant is about 6MiB larger per architecture than default. 68 | */ 69 | def jscFlavor = 'org.webkit:android-jsc:+' 70 | 71 | android { 72 | ndkVersion rootProject.ext.ndkVersion 73 | 74 | compileSdkVersion rootProject.ext.compileSdkVersion 75 | 76 | namespace "com.snap.camerakit.reactnative.example" 77 | defaultConfig { 78 | applicationId "com.snap.camerakit.reactnative.example" 79 | minSdkVersion rootProject.ext.minSdkVersion 80 | targetSdkVersion rootProject.ext.targetSdkVersion 81 | versionCode 1 82 | versionName "1.0" 83 | } 84 | signingConfigs { 85 | debug { 86 | storeFile file('debug.keystore') 87 | storePassword 'android' 88 | keyAlias 'androiddebugkey' 89 | keyPassword 'android' 90 | } 91 | } 92 | buildTypes { 93 | debug { 94 | signingConfig signingConfigs.debug 95 | } 96 | release { 97 | // Caution! In production, you need to generate your own keystore file. 98 | // see https://reactnative.dev/docs/signed-apk-android. 99 | signingConfig signingConfigs.debug 100 | minifyEnabled enableProguardInReleaseBuilds 101 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 102 | } 103 | } 104 | } 105 | 106 | repositories { 107 | google() 108 | mavenCentral() 109 | } 110 | 111 | dependencies { 112 | // The version of react-native is set by the React Native Gradle Plugin 113 | implementation("com.facebook.react:react-android") 114 | 115 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") 116 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { 117 | exclude group:'com.squareup.okhttp3', module:'okhttp' 118 | } 119 | 120 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") 121 | if (hermesEnabled.toBoolean()) { 122 | implementation("com.facebook.react:hermes-android") 123 | } else { 124 | implementation jscFlavor 125 | } 126 | } 127 | 128 | configurations.all { 129 | // This block will apply to all configurations 130 | resolutionStrategy.eachDependency { DependencyResolveDetails details -> 131 | // Check if the module name contains 'kotlin-stdlib' 132 | if (details.requested.name.equals("kotlin-stdlib")) { 133 | // Use 1.7.22 version across all deps 134 | details.useVersion("1.7.22") 135 | } 136 | } 137 | } 138 | 139 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 140 | -------------------------------------------------------------------------------- /example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/app/debug.keystore -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example/android/app/src/debug/java/com/snap/camerakit/reactnative/example/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.snap.camerakit.reactnative.example; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 21 | import com.facebook.react.ReactInstanceEventListener; 22 | import com.facebook.react.ReactInstanceManager; 23 | import com.facebook.react.bridge.ReactContext; 24 | import com.facebook.react.modules.network.NetworkingModule; 25 | import okhttp3.OkHttpClient; 26 | 27 | /** 28 | * Class responsible of loading Flipper inside your React Native application. This is the debug 29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup. 30 | */ 31 | public class ReactNativeFlipper { 32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 33 | if (FlipperUtils.shouldEnableFlipper(context)) { 34 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 35 | 36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 37 | client.addPlugin(new DatabasesFlipperPlugin(context)); 38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 39 | client.addPlugin(CrashReporterPlugin.getInstance()); 40 | 41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 42 | NetworkingModule.setCustomClientBuilder( 43 | new NetworkingModule.CustomClientBuilder() { 44 | @Override 45 | public void apply(OkHttpClient.Builder builder) { 46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 47 | } 48 | }); 49 | client.addPlugin(networkFlipperPlugin); 50 | client.start(); 51 | 52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 53 | // Hence we run if after all native modules have been initialized 54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 55 | if (reactContext == null) { 56 | reactInstanceManager.addReactInstanceEventListener( 57 | new ReactInstanceEventListener() { 58 | @Override 59 | public void onReactContextInitialized(ReactContext reactContext) { 60 | reactInstanceManager.removeReactInstanceEventListener(this); 61 | reactContext.runOnNativeModulesQueueThread( 62 | new Runnable() { 63 | @Override 64 | public void run() { 65 | client.addPlugin(new FrescoFlipperPlugin()); 66 | } 67 | }); 68 | } 69 | }); 70 | } else { 71 | client.addPlugin(new FrescoFlipperPlugin()); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 18 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/snap/camerakit/reactnative/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.snap.camerakit.reactnative.example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate; 7 | 8 | public class MainActivity extends 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 15 | protected String getMainComponentName() { 16 | return "CameraKitReactNativeExample"; 17 | } 18 | 19 | /** 20 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link 21 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React 22 | * (aka React 18) with two boolean flags. 23 | */ 24 | @Override 25 | protected ReactActivityDelegate createReactActivityDelegate() { 26 | return new DefaultReactActivityDelegate( 27 | this, 28 | getMainComponentName(), 29 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 30 | DefaultNewArchitectureEntryPoint.getFabricEnabled()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/snap/camerakit/reactnative/example/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.snap.camerakit.reactnative.example; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.PackageList; 6 | import com.facebook.react.ReactApplication; 7 | import com.facebook.react.ReactNativeHost; 8 | import com.facebook.react.ReactPackage; 9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 10 | import com.facebook.react.defaults.DefaultReactNativeHost; 11 | import com.facebook.soloader.SoLoader; 12 | import java.util.List; 13 | 14 | public class MainApplication extends Application implements ReactApplication { 15 | 16 | private final ReactNativeHost mReactNativeHost = 17 | new DefaultReactNativeHost(this) { 18 | @Override 19 | public boolean getUseDeveloperSupport() { 20 | return BuildConfig.DEBUG; 21 | } 22 | 23 | @Override 24 | protected List getPackages() { 25 | @SuppressWarnings("UnnecessaryLocalVariable") 26 | List packages = new PackageList(this).getPackages(); 27 | // Packages that cannot be autolinked yet can be added manually here, for example: 28 | // packages.add(new MyReactNativePackage()); 29 | return packages; 30 | } 31 | 32 | @Override 33 | protected String getJSMainModuleName() { 34 | return "index"; 35 | } 36 | 37 | @Override 38 | protected boolean isNewArchEnabled() { 39 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; 40 | } 41 | 42 | @Override 43 | protected Boolean isHermesEnabled() { 44 | return BuildConfig.IS_HERMES_ENABLED; 45 | } 46 | }; 47 | 48 | @Override 49 | public ReactNativeHost getReactNativeHost() { 50 | return mReactNativeHost; 51 | } 52 | 53 | @Override 54 | public void onCreate() { 55 | super.onCreate(); 56 | SoLoader.init(this, /* native exopackage */ false); 57 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 58 | // If you opted-in for the New Architecture, we load the native entry point for this app. 59 | DefaultNewArchitectureEntryPoint.load(); 60 | } 61 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | CameraKitReactNativeExample 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/android/app/src/release/java/com/camerakitreactnativeexample/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.snap.camerakit.reactnative.example; 8 | 9 | import android.content.Context; 10 | import com.facebook.react.ReactInstanceManager; 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. This is the release 14 | * flavor of it so it's empty as we don't want to load Flipper. 15 | */ 16 | public class ReactNativeFlipper { 17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 18 | // Do nothing as we don't want to initialize Flipper on Release. 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "34.0.0" 6 | minSdkVersion = 21 7 | compileSdkVersion = 34 8 | targetSdkVersion = 34 9 | 10 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. 11 | ndkVersion = "23.1.7779620" 12 | } 13 | repositories { 14 | google() 15 | mavenCentral() 16 | } 17 | dependencies { 18 | classpath("com.android.tools.build:gradle") 19 | classpath("com.facebook.react:react-native-gradle-plugin") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /example/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 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.182.0 29 | 30 | # Use this property to specify which architecture you want to build. 31 | # You can also override it from the CLI using 32 | # ./gradlew -PreactNativeArchitectures=x86_64 33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 34 | 35 | # Use this property to enable support to the new architecture. 36 | # This will allow you to use TurboModules and the Fabric render in 37 | # your application. You should enable this flag either if you want 38 | # to write custom TurboModules/Fabric components OR use libraries that 39 | # are providing them. 40 | newArchEnabled=false 41 | 42 | # Use this property to enable or disable the Hermes JS engine. 43 | # If set to false, you will be using JSC instead. 44 | hermesEnabled=true 45 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snapchat/camera-kit-react-native/51e46c0bb43c21bed123744669569fe10d6098ce/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'CameraKitReactNativeExample' 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 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CameraKitReactNativeExample", 3 | "displayName": "CameraKitReactNativeExample" 4 | } 5 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = { 5 | presets: ['module:metro-react-native-babel-preset'], 6 | plugins: [ 7 | [ 8 | 'module-resolver', 9 | { 10 | extensions: ['.tsx', '.ts', '.js', '.json'], 11 | alias: { 12 | [pak.name]: path.join(__dirname, '..', pak.source), 13 | }, 14 | }, 15 | ], 16 | ], 17 | }; 18 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './src/App'; 3 | import { name as appName } from './app.json'; 4 | 5 | AppRegistry.registerComponent(appName, () => App); 6 | -------------------------------------------------------------------------------- /example/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 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample.xcodeproj/xcshareddata/xcschemes/CameraKitReactNativeExample.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 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample/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 = @"CameraKitReactNativeExample"; 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 | #if DEBUG 20 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 21 | #else 22 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 23 | #endif 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample/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 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSCameraUsageDescription 6 | This app uses the camera to show the preview on a screen. 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleDisplayName 10 | CameraKitReactNativeExample 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | $(MARKETING_VERSION) 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | $(CURRENT_PROJECT_VERSION) 27 | LSRequiresIPhoneOS 28 | 29 | NSAppTransportSecurity 30 | 31 | NSExceptionDomains 32 | 33 | localhost 34 | 35 | NSExceptionAllowsInsecureHTTPLoads 36 | 37 | 38 | 39 | 40 | NSCameraUsageDescription 41 | This app uses the camera to show the preview on a screen. 42 | NSLocationWhenInUseUsageDescription 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UISupportedInterfaceOrientations 51 | 52 | UIInterfaceOrientationPortrait 53 | UIInterfaceOrientationLandscapeLeft 54 | UIInterfaceOrientationLandscapeRight 55 | 56 | UIViewControllerBasedStatusBarAppearance 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample/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 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExample/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 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExampleTests/CameraKitReactNativeExampleTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface CameraKitReactNativeExampleTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation CameraKitReactNativeExampleTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction( 38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 39 | if (level >= RCTLogLevelError) { 40 | redboxError = message; 41 | } 42 | }); 43 | #endif 44 | 45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | 49 | foundElement = [self findSubviewInView:vc.view 50 | matching:^BOOL(UIView *view) { 51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 52 | return YES; 53 | } 54 | return NO; 55 | }]; 56 | } 57 | 58 | #ifdef DEBUG 59 | RCTSetLogFunction(RCTDefaultLogFunction); 60 | #endif 61 | 62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /example/ios/CameraKitReactNativeExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /example/ios/File.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // CameraKitReactNativeExample 4 | // 5 | 6 | import Foundation 7 | -------------------------------------------------------------------------------- /example/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 'CameraKitReactNativeExample' do 29 | config = use_native_modules! 30 | 31 | # Flags change depending on the env values. 32 | flags = get_default_flags() 33 | 34 | use_react_native!( 35 | :path => config[:reactNativePath], 36 | # Hermes is now enabled by default. Disable by setting this flag to false. 37 | :hermes_enabled => flags[:hermes_enabled], 38 | :fabric_enabled => flags[:fabric_enabled], 39 | # Enables Flipper. 40 | # 41 | # Note that if you have use_frameworks! enabled, Flipper will not work and 42 | # you should disable the next line. 43 | # :flipper_configuration => flipper_config, 44 | # An absolute path to your application root. 45 | :app_path => "#{Pod::Config.instance.installation_root}/.." 46 | ) 47 | 48 | target 'CameraKitReactNativeExampleTests' do 49 | inherit! :complete 50 | # Pods for testing 51 | end 52 | 53 | post_install do |installer| 54 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 55 | react_native_post_install( 56 | installer, 57 | config[:reactNativePath], 58 | :mac_catalyst_enabled => false 59 | ) 60 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /example/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); 2 | const path = require('path'); 3 | const escape = require('escape-string-regexp'); 4 | const exclusionList = require('metro-config/src/defaults/exclusionList'); 5 | const pak = require('../package.json'); 6 | 7 | const root = path.resolve(__dirname, '..'); 8 | const modules = Object.keys({ ...pak.peerDependencies }); 9 | 10 | /** 11 | * Metro configuration 12 | * https://facebook.github.io/metro/docs/configuration 13 | * 14 | * @type {import('metro-config').MetroConfig} 15 | */ 16 | const config = { 17 | watchFolders: [root], 18 | 19 | // We need to make sure that only one version is loaded for peerDependencies 20 | // So we block them at the root, and alias them to the versions in example's node_modules 21 | resolver: { 22 | blacklistRE: exclusionList(modules.map((m) => new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`))), 23 | 24 | extraNodeModules: modules.reduce((acc, name) => { 25 | acc[name] = path.join(__dirname, 'node_modules', name); 26 | return acc; 27 | }, {}), 28 | }, 29 | 30 | transformer: { 31 | getTransformOptions: async () => ({ 32 | transform: { 33 | experimentalImportSupport: false, 34 | inlineRequires: true, 35 | }, 36 | }), 37 | }, 38 | }; 39 | 40 | module.exports = mergeConfig(getDefaultConfig(__dirname), config); 41 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "camera-kit-react-native-example", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "build:android": "cd android && ./gradlew assembleDebug --no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a", 10 | "build:ios": "cd ios && xcodebuild -workspace CameraKitReactNativeExample.xcworkspace -scheme CameraKitReactNativeExample -configuration Debug -sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO" 11 | }, 12 | "dependencies": { 13 | "@types/react-native-video": "^5.0.18", 14 | "react": "18.2.0", 15 | "react-native": "0.72.9", 16 | "react-native-video": "^5.2.1" 17 | }, 18 | "devDependencies": { 19 | "@babel/core": "^7.20.0", 20 | "@babel/preset-env": "^7.20.0", 21 | "@babel/runtime": "^7.20.0", 22 | "@react-native/metro-config": "^0.72.11", 23 | "babel-plugin-module-resolver": "^5.0.0", 24 | "metro-react-native-babel-preset": "0.76.8", 25 | "pod-install": "^0.1.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /example/react-native.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = { 5 | dependencies: { 6 | [pak.name]: { 7 | root: path.join(__dirname, '..'), 8 | }, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Button } from './Button'; 3 | import { StyleSheet, View, SafeAreaView } from 'react-native'; 4 | import { CameraKitContext } from '@snap/camera-kit-react-native'; 5 | import { Preview } from './CameraPreview'; 6 | import { CameraContext } from './CameraStateContext'; 7 | 8 | const apiToken = 9 | 'REPLACE-THIS-WITH-YOUR-API-TOKEN'; 10 | 11 | export default function App() { 12 | const [stopRendering, setStopRendering] = useState(false); 13 | 14 | if (stopRendering) { 15 | return ( 16 | 17 | 18 |