├── .eslintrc ├── .gitattributes ├── .gitignore ├── .npmignore ├── .prettierrc ├── .vscode └── launch.json ├── README.md ├── android ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── jobeso │ │ ├── Base64.java │ │ ├── RNStoryShareFileProvider.java │ │ ├── RNStoryShareModule.java │ │ └── RNStorySharePackage.java │ └── res │ └── xml │ └── filepaths.xml ├── example ├── .buckconfig ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .watchmanconfig ├── __tests__ │ └── App-test.js ├── android │ ├── app │ │ ├── BUCK │ │ ├── build.gradle │ │ ├── build_defs.bzl │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ │ └── xml │ │ │ └── file_paths.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── keystores │ │ ├── BUCK │ │ └── debug.keystore.properties │ └── settings.gradle ├── app.json ├── app │ ├── Button.js │ ├── Root.js │ └── ShareSection.js ├── babel.config.js ├── index.js ├── ios │ ├── Podfile │ ├── Podfile.lock │ ├── empty.swift │ ├── example-Bridging-Header.h │ ├── example-tvOS │ │ └── Info.plist │ ├── example-tvOSTests │ │ └── Info.plist │ ├── example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── example-tvOS.xcscheme │ │ │ └── example.xcscheme │ ├── example.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ ├── example │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── main.m │ └── exampleTests │ │ ├── Info.plist │ │ └── exampleTests.m ├── metro.config.js ├── package.json └── yarn.lock ├── index.js ├── ios ├── RNStoryShare-Bridging-Header.h ├── RNStoryShare.m ├── RNStoryShare.podspec ├── RNStoryShare.swift └── RNStoryShare.xcodeproj │ └── project.pbxproj ├── package.json └── yarn.lock /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb", "prettier", "prettier/react"], 3 | "parser": "babel-eslint", 4 | "plugins": ["react", "jsx-a11y", "import", "prettier"], 5 | "rules": { 6 | "import/no-extraneous-dependencies": 0, 7 | "func-names": 0, 8 | "import/extensions": 0, 9 | "import/no-named-as-default": 0, 10 | "import/no-named-as-default-member": 0, 11 | "import/no-unresolved": 1, 12 | "jsx-a11y/no-static-element-interactions": 0, 13 | "no-extra-boolean-cast": 0, 14 | "no-plusplus": 0, 15 | "no-sequences": 0, 16 | "no-script-url": 0, 17 | "no-unused-vars": 1, 18 | "react/no-did-update-set-state": 0, 19 | "spaced-comment": 0, 20 | "import/prefer-default-export": 0, 21 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], 22 | "no-underscore-dangle": 0, 23 | "lines-between-class-members": 0, 24 | "react/sort-comp": 0, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # OSX 3 | # 4 | .DS_Store 5 | 6 | # node.js 7 | # 8 | node_modules/ 9 | npm-debug.log 10 | yarn-error.log 11 | 12 | 13 | # Xcode 14 | # 15 | build/ 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | xcuserdata 25 | *.xccheckout 26 | *.moved-aside 27 | DerivedData 28 | *.hmap 29 | *.ipa 30 | *.xcuserstate 31 | project.xcworkspace 32 | Pods 33 | 34 | 35 | # Android/IntelliJ 36 | # 37 | build/ 38 | .idea 39 | .gradle 40 | local.properties 41 | *.iml 42 | 43 | # BUCK 44 | buck-out/ 45 | \.buckd/ 46 | *.keystore 47 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | example 2 | build 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "insertPragma": false, 4 | "jsxBracketSameLine": false, 5 | "parser": "babylon", 6 | "printWidth": 80, 7 | "proseWrap": "always", 8 | "requirePragma": false, 9 | "semi": false, 10 | "singleQuote": true, 11 | "tabWidth": 2, 12 | "trailingComma": "es5", 13 | "useTabs": false 14 | } 15 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-story-share 2 | 3 | Share your images to instagram and snapchat stories. 4 | 5 | | OS | Type | Supported | 6 | |---|---|:---:| 7 | | iOS | BASE64 | YES | 8 | | | FILE | YES | 9 | | Android | BASE64 | YES | 10 | | | FILE | YES | 11 | 12 | ## Getting started 13 | 14 | `$ yarn add react-native-story-share` 15 | 16 | or 17 | 18 | `$ npm install react-native-story-share --save` 19 | 20 | ## Installation 21 | 1. Either choose `Mostly automatic installation` or `Manual installation` 22 | 2. Follow the `Integration` guide 23 | 24 | ### Mostly automatic installation 25 | 26 | `$ react-native link react-native-story-share` 27 | 28 | ### Manual installation 29 | 30 | #### iOS 31 | 32 | 1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]` 33 | 2. Go to `node_modules` ➜ `react-native-story-share` and add `RNStoryShare.xcodeproj` 34 | 3. In XCode, in the project navigator, select your project. Add `libRNStoryShare.a` to your project's `Build Phases` ➜ `Link Binary With Libraries` 35 | 4. Run your project (`Cmd+R`) 36 | 37 | #### Android 38 | 39 | 1. Open up `android/app/src/main/java/[...]/MainActivity.java` 40 | 41 | - Add `import com.jobeso.RNStorySharePackage;` to the imports at the top of the file 42 | - Add `new RNStorySharePackage()` to the list returned by the `getPackages()` method 43 | 44 | 2. Append the following lines to `android/settings.gradle`: 45 | ``` 46 | include ':react-native-story-share' 47 | project(':react-native-story-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-story-share/android') 48 | ``` 49 | 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`: 50 | ``` 51 | compile project(':react-native-story-share') 52 | ``` 53 | 54 | ## Integration 55 | 56 | ### Android 57 | 58 | + add snap client id 59 | ```diff 60 | 61 | ... 62 | 63 | + 64 | 65 | ... 66 | 67 | ``` 68 | 69 | + add snap sdk 70 | ``` 71 | maven { url "https://storage.googleapis.com/snap-kit-build/maven" } 72 | ``` 73 | 74 | ### iOS 75 | 76 | #### Swift 77 | 78 | 1. Under `Build Settings` section `Build Options` set `Always Embed Swift Started Libraries` to `true` 79 | 2. Make sure you have the following under `library search paths` 80 | 81 | ``` 82 | $(inherited) 83 | $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) 84 | ``` 85 | 86 | #### Info.plist 87 | 88 | + add `instagram-stories` and `snapchat` to the `LSApplicationQueriesSchemes` key in your app's Info.plist. 89 | 90 | ```diff 91 | ... 92 | LSApplicationQueriesSchemes 93 | 94 | ... 95 | + instagram-stories 96 | + snapchat 97 | 98 | ... 99 | ``` 100 | 101 | #### snapchat 102 | + add `SCSDKClientId` to your `Info.plist` 103 | + add `pod 'SnapSDK', :subspecs => ['SCSDKCreativeKit']` to your Podfile with `use_frameworks!` 104 | + *optional* add [build script](https://docs.snapchat.com/docs/submitting) to reduce bundle size 105 | 106 | ## Usage 107 | 108 | ### Share To Instagram 109 | ```javascript 110 | import RNStoryShare from "react-native-story-share"; 111 | 112 | RNStoryShare.isInstagramAvailable() 113 | .then(isAvailable => { 114 | 115 | if(isAvailable){ 116 | RNStoryShare.shareToInstagram({ 117 | type: RNStoryShare.BASE64, // or RNStoryShare.FILE 118 | attributionLink: 'https://myproject.com', 119 | backgroundAsset: 'data:image/png;base64,iVBO...', 120 | stickerAsset: 'data:image/png;base64,iVBO...', 121 | backgroundBottomColor: '#f44162', 122 | backgroundTopColor: '#f4a142' 123 | }); 124 | } 125 | }) 126 | .catch(e => console.log(e)); 127 | ``` 128 | 129 | ### Share To Snapchat 130 | ```javascript 131 | import RNStoryShare from "react-native-story-share"; 132 | 133 | RNStoryShare.isSnapchatAvailable() 134 | .then(isAvailable => { 135 | 136 | if(isAvailable){ 137 | RNStoryShare.shareToSnapchat({ 138 | type: RNStoryShare.BASE64, // or RNStoryShare.FILE 139 | attributionLink: 'https://myproject.com', 140 | backgroundAsset: 'data:image/png;base64,iVBO...', 141 | stickerAsset: 'data:image/png;base64,iVBO...', 142 | captionText: 'text exemple', 143 | media: "photo" // or "video" 144 | stickerOptions: { 145 | height: 900, 146 | width: 900 147 | } 148 | }); 149 | } 150 | }) 151 | .catch(e => console.log(e)); 152 | 153 | ``` 154 | 155 | ## API 156 | 157 | ### Constants 158 | 159 | | Name | Value | 160 | |---|---| 161 | | BASE64 | "base64" | 162 | | FILE | "file" | 163 | 164 | ### Methods 165 | 166 | #### `isInstagramAvailable(): Promise` 167 | Return a boolean indicating if Instagram is available on the phone. 168 | 169 | #### `isSnapchatAvailable(): Promise` 170 | Return a boolean indicating if Snapchat is available on the phone. 171 | 172 | #### `shareToInstagram(config: ShareConfigObject): Promise` 173 | ``` 174 | type ShareConfigObject = { 175 | type: "base64" || "file", 176 | attributionLink: string, 177 | backgroundAsset: string, 178 | stickerAsset: string, 179 | stickerOptions: { 180 | height: integer, 181 | width: integer 182 | } 183 | } 184 | ``` 185 | Shares a file or base64 image as background, sticker or both to Instagram. The background colors are only applyed when no background asset is set. 186 | 187 | #### `shareToSnapchat(config: ShareConfigObject): Promise` 188 | ``` 189 | type ShareConfigObject = { 190 | type: "base64" || "file", 191 | attributionLink: string, 192 | backgroundAsset: string, 193 | stickerAsset: string, 194 | backgroundBottomColor: string, 195 | backgroundTopColor: string 196 | } 197 | ``` 198 | Shares a file or base64 image as background, sticker or both to Snapchat. `stickerOptions` are only supported by Android. 199 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | buildscript { 3 | repositories { 4 | mavenCentral() 5 | google() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.2.2' 10 | } 11 | } 12 | 13 | apply plugin: 'com.android.library' 14 | 15 | def _ext = rootProject.ext; 16 | def _compileSdkVersion = _ext.has('compileSdkVersion') ? _ext.compileSdkVersion : 31; 17 | def _buildToolsVersion = _ext.has('buildToolsVersion') ? _ext.buildToolsVersion : '31.0.0'; 18 | def _minSdkVersion = _ext.has('minSdkVersion') ? _ext.minSdkVersion : 26; 19 | def _targetSdkVersion = _ext.has('targetSdkVersion') ? _ext.targetSdkVersion : 31; 20 | 21 | android { 22 | compileSdkVersion _compileSdkVersion 23 | buildToolsVersion _buildToolsVersion 24 | 25 | defaultConfig { 26 | minSdkVersion _minSdkVersion 27 | targetSdkVersion _targetSdkVersion 28 | versionCode 1 29 | versionName "1.0" 30 | } 31 | lintOptions { 32 | abortOnError false 33 | } 34 | } 35 | 36 | repositories { 37 | mavenCentral() 38 | maven { 39 | url "https://storage.googleapis.com/snap-kit-build/maven" 40 | } 41 | } 42 | 43 | dependencies { 44 | implementation('com.facebook.react:react-native:+') 45 | implementation([ 46 | 'com.snap.creativekit:creativekit:2.1.0' 47 | ]) 48 | } 49 | 50 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /android/src/main/java/com/jobeso/Base64.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.jobeso; 18 | 19 | import android.util.Base64OutputStream; 20 | 21 | import java.io.UnsupportedEncodingException; 22 | 23 | /** 24 | * Utilities for encoding and decoding the Base64 representation of 25 | * binary data. See RFCs 2045 and 3548. 28 | */ 29 | public class Base64 { 30 | /** 31 | * Default values for encoder/decoder flags. 32 | */ 33 | public static final int DEFAULT = 0; 34 | 35 | /** 36 | * Encoder flag bit to omit the padding '=' characters at the end 37 | * of the output (if any). 38 | */ 39 | public static final int NO_PADDING = 1; 40 | 41 | /** 42 | * Encoder flag bit to omit all line terminators (i.e., the output 43 | * will be on one long line). 44 | */ 45 | public static final int NO_WRAP = 2; 46 | 47 | /** 48 | * Encoder flag bit to indicate lines should be terminated with a 49 | * CRLF pair instead of just an LF. Has no effect if {@code 50 | * NO_WRAP} is specified as well. 51 | */ 52 | public static final int CRLF = 4; 53 | 54 | /** 55 | * Encoder/decoder flag bit to indicate using the "URL and 56 | * filename safe" variant of Base64 (see RFC 3548 section 4) where 57 | * {@code -} and {@code _} are used in place of {@code +} and 58 | * {@code /}. 59 | */ 60 | public static final int URL_SAFE = 8; 61 | 62 | /** 63 | * Flag to pass to {@link Base64OutputStream} to indicate that it 64 | * should not close the output stream it is wrapping when it 65 | * itself is closed. 66 | */ 67 | public static final int NO_CLOSE = 16; 68 | 69 | // -------------------------------------------------------- 70 | // shared code 71 | // -------------------------------------------------------- 72 | 73 | /* package */ static abstract class Coder { 74 | public byte[] output; 75 | public int op; 76 | 77 | /** 78 | * Encode/decode another block of input data. this.output is 79 | * provided by the caller, and must be big enough to hold all 80 | * the coded data. On exit, this.opwill be set to the length 81 | * of the coded data. 82 | * 83 | * @param finish true if this is the final call to process for 84 | * this object. Will finalize the coder state and 85 | * include any final bytes in the output. 86 | * 87 | * @return true if the input so far is good; false if some 88 | * error has been detected in the input stream.. 89 | */ 90 | public abstract boolean process(byte[] input, int offset, int len, boolean finish); 91 | 92 | /** 93 | * @return the maximum number of bytes a call to process() 94 | * could produce for the given number of input bytes. This may 95 | * be an overestimate. 96 | */ 97 | public abstract int maxOutputSize(int len); 98 | } 99 | 100 | // -------------------------------------------------------- 101 | // decoding 102 | // -------------------------------------------------------- 103 | 104 | /** 105 | * Decode the Base64-encoded data in input and return the data in 106 | * a new byte array. 107 | * 108 | *

The padding '=' characters at the end are considered optional, but 109 | * if any are present, there must be the correct number of them. 110 | * 111 | * @param str the input String to decode, which is converted to 112 | * bytes using the default charset 113 | * @param flags controls certain features of the decoded output. 114 | * Pass {@code DEFAULT} to decode standard Base64. 115 | * 116 | * @throws IllegalArgumentException if the input contains 117 | * incorrect padding 118 | */ 119 | public static byte[] decode(String str, int flags) { 120 | return decode(str.getBytes(), flags); 121 | } 122 | 123 | /** 124 | * Decode the Base64-encoded data in input and return the data in 125 | * a new byte array. 126 | * 127 | *

The padding '=' characters at the end are considered optional, but 128 | * if any are present, there must be the correct number of them. 129 | * 130 | * @param input the input array to decode 131 | * @param flags controls certain features of the decoded output. 132 | * Pass {@code DEFAULT} to decode standard Base64. 133 | * 134 | * @throws IllegalArgumentException if the input contains 135 | * incorrect padding 136 | */ 137 | public static byte[] decode(byte[] input, int flags) { 138 | return decode(input, 0, input.length, flags); 139 | } 140 | 141 | /** 142 | * Decode the Base64-encoded data in input and return the data in 143 | * a new byte array. 144 | * 145 | *

The padding '=' characters at the end are considered optional, but 146 | * if any are present, there must be the correct number of them. 147 | * 148 | * @param input the data to decode 149 | * @param offset the position within the input array at which to start 150 | * @param len the number of bytes of input to decode 151 | * @param flags controls certain features of the decoded output. 152 | * Pass {@code DEFAULT} to decode standard Base64. 153 | * 154 | * @throws IllegalArgumentException if the input contains 155 | * incorrect padding 156 | */ 157 | public static byte[] decode(byte[] input, int offset, int len, int flags) { 158 | // Allocate space for the most data the input could represent. 159 | // (It could contain less if it contains whitespace, etc.) 160 | Decoder decoder = new Decoder(flags, new byte[len*3/4]); 161 | 162 | if (!decoder.process(input, offset, len, true)) { 163 | throw new IllegalArgumentException("bad base-64"); 164 | } 165 | 166 | // Maybe we got lucky and allocated exactly enough output space. 167 | if (decoder.op == decoder.output.length) { 168 | return decoder.output; 169 | } 170 | 171 | // Need to shorten the array, so allocate a new one of the 172 | // right size and copy. 173 | byte[] temp = new byte[decoder.op]; 174 | System.arraycopy(decoder.output, 0, temp, 0, decoder.op); 175 | return temp; 176 | } 177 | 178 | /* package */ static class Decoder extends Coder { 179 | /** 180 | * Lookup table for turning bytes into their position in the 181 | * Base64 alphabet. 182 | */ 183 | private static final int DECODE[] = { 184 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 185 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 186 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 187 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, 188 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 189 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, 190 | -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 191 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, 192 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 193 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 194 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 195 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 196 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 197 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 198 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 199 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 200 | }; 201 | 202 | /** 203 | * Decode lookup table for the "web safe" variant (RFC 3548 204 | * sec. 4) where - and _ replace + and /. 205 | */ 206 | private static final int DECODE_WEBSAFE[] = { 207 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 208 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 209 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, 210 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, 211 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 212 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, 213 | -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 214 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, 215 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 216 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 217 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 218 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 219 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 220 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 221 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 222 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 223 | }; 224 | 225 | /** Non-data values in the DECODE arrays. */ 226 | private static final int SKIP = -1; 227 | private static final int EQUALS = -2; 228 | 229 | /** 230 | * States 0-3 are reading through the next input tuple. 231 | * State 4 is having read one '=' and expecting exactly 232 | * one more. 233 | * State 5 is expecting no more data or padding characters 234 | * in the input. 235 | * State 6 is the error state; an error has been detected 236 | * in the input and no future input can "fix" it. 237 | */ 238 | private int state; // state number (0 to 6) 239 | private int value; 240 | 241 | final private int[] alphabet; 242 | 243 | public Decoder(int flags, byte[] output) { 244 | this.output = output; 245 | 246 | alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE; 247 | state = 0; 248 | value = 0; 249 | } 250 | 251 | /** 252 | * @return an overestimate for the number of bytes {@code 253 | * len} bytes could decode to. 254 | */ 255 | public int maxOutputSize(int len) { 256 | return len * 3/4 + 10; 257 | } 258 | 259 | /** 260 | * Decode another block of input data. 261 | * 262 | * @return true if the state machine is still healthy. false if 263 | * bad base-64 data has been detected in the input stream. 264 | */ 265 | public boolean process(byte[] input, int offset, int len, boolean finish) { 266 | if (this.state == 6) return false; 267 | 268 | int p = offset; 269 | len += offset; 270 | 271 | // Using local variables makes the decoder about 12% 272 | // faster than if we manipulate the member variables in 273 | // the loop. (Even alphabet makes a measurable 274 | // difference, which is somewhat surprising to me since 275 | // the member variable is final.) 276 | int state = this.state; 277 | int value = this.value; 278 | int op = 0; 279 | final byte[] output = this.output; 280 | final int[] alphabet = this.alphabet; 281 | 282 | while (p < len) { 283 | // Try the fast path: we're starting a new tuple and the 284 | // next four bytes of the input stream are all data 285 | // bytes. This corresponds to going through states 286 | // 0-1-2-3-0. We expect to use this method for most of 287 | // the data. 288 | // 289 | // If any of the next four bytes of input are non-data 290 | // (whitespace, etc.), value will end up negative. (All 291 | // the non-data values in decode are small negative 292 | // numbers, so shifting any of them up and or'ing them 293 | // together will result in a value with its top bit set.) 294 | // 295 | // You can remove this whole block and the output should 296 | // be the same, just slower. 297 | if (state == 0) { 298 | while (p+4 <= len && 299 | (value = ((alphabet[input[p] & 0xff] << 18) | 300 | (alphabet[input[p+1] & 0xff] << 12) | 301 | (alphabet[input[p+2] & 0xff] << 6) | 302 | (alphabet[input[p+3] & 0xff]))) >= 0) { 303 | output[op+2] = (byte) value; 304 | output[op+1] = (byte) (value >> 8); 305 | output[op] = (byte) (value >> 16); 306 | op += 3; 307 | p += 4; 308 | } 309 | if (p >= len) break; 310 | } 311 | 312 | // The fast path isn't available -- either we've read a 313 | // partial tuple, or the next four input bytes aren't all 314 | // data, or whatever. Fall back to the slower state 315 | // machine implementation. 316 | 317 | int d = alphabet[input[p++] & 0xff]; 318 | 319 | switch (state) { 320 | case 0: 321 | if (d >= 0) { 322 | value = d; 323 | ++state; 324 | } else if (d != SKIP) { 325 | this.state = 6; 326 | return false; 327 | } 328 | break; 329 | 330 | case 1: 331 | if (d >= 0) { 332 | value = (value << 6) | d; 333 | ++state; 334 | } else if (d != SKIP) { 335 | this.state = 6; 336 | return false; 337 | } 338 | break; 339 | 340 | case 2: 341 | if (d >= 0) { 342 | value = (value << 6) | d; 343 | ++state; 344 | } else if (d == EQUALS) { 345 | // Emit the last (partial) output tuple; 346 | // expect exactly one more padding character. 347 | output[op++] = (byte) (value >> 4); 348 | state = 4; 349 | } else if (d != SKIP) { 350 | this.state = 6; 351 | return false; 352 | } 353 | break; 354 | 355 | case 3: 356 | if (d >= 0) { 357 | // Emit the output triple and return to state 0. 358 | value = (value << 6) | d; 359 | output[op+2] = (byte) value; 360 | output[op+1] = (byte) (value >> 8); 361 | output[op] = (byte) (value >> 16); 362 | op += 3; 363 | state = 0; 364 | } else if (d == EQUALS) { 365 | // Emit the last (partial) output tuple; 366 | // expect no further data or padding characters. 367 | output[op+1] = (byte) (value >> 2); 368 | output[op] = (byte) (value >> 10); 369 | op += 2; 370 | state = 5; 371 | } else if (d != SKIP) { 372 | this.state = 6; 373 | return false; 374 | } 375 | break; 376 | 377 | case 4: 378 | if (d == EQUALS) { 379 | ++state; 380 | } else if (d != SKIP) { 381 | this.state = 6; 382 | return false; 383 | } 384 | break; 385 | 386 | case 5: 387 | if (d != SKIP) { 388 | this.state = 6; 389 | return false; 390 | } 391 | break; 392 | } 393 | } 394 | 395 | if (!finish) { 396 | // We're out of input, but a future call could provide 397 | // more. 398 | this.state = state; 399 | this.value = value; 400 | this.op = op; 401 | return true; 402 | } 403 | 404 | // Done reading input. Now figure out where we are left in 405 | // the state machine and finish up. 406 | 407 | switch (state) { 408 | case 0: 409 | // Output length is a multiple of three. Fine. 410 | break; 411 | case 1: 412 | // Read one extra input byte, which isn't enough to 413 | // make another output byte. Illegal. 414 | this.state = 6; 415 | return false; 416 | case 2: 417 | // Read two extra input bytes, enough to emit 1 more 418 | // output byte. Fine. 419 | output[op++] = (byte) (value >> 4); 420 | break; 421 | case 3: 422 | // Read three extra input bytes, enough to emit 2 more 423 | // output bytes. Fine. 424 | output[op++] = (byte) (value >> 10); 425 | output[op++] = (byte) (value >> 2); 426 | break; 427 | case 4: 428 | // Read one padding '=' when we expected 2. Illegal. 429 | this.state = 6; 430 | return false; 431 | case 5: 432 | // Read all the padding '='s we expected and no more. 433 | // Fine. 434 | break; 435 | } 436 | 437 | this.state = state; 438 | this.op = op; 439 | return true; 440 | } 441 | } 442 | 443 | // -------------------------------------------------------- 444 | // encoding 445 | // -------------------------------------------------------- 446 | 447 | /** 448 | * Base64-encode the given data and return a newly allocated 449 | * String with the result. 450 | * 451 | * @param input the data to encode 452 | * @param flags controls certain features of the encoded output. 453 | * Passing {@code DEFAULT} results in output that 454 | * adheres to RFC 2045. 455 | */ 456 | public static String encodeToString(byte[] input, int flags) { 457 | try { 458 | return new String(encode(input, flags), "US-ASCII"); 459 | } catch (UnsupportedEncodingException e) { 460 | // US-ASCII is guaranteed to be available. 461 | throw new AssertionError(e); 462 | } 463 | } 464 | 465 | /** 466 | * Base64-encode the given data and return a newly allocated 467 | * String with the result. 468 | * 469 | * @param input the data to encode 470 | * @param offset the position within the input array at which to 471 | * start 472 | * @param len the number of bytes of input to encode 473 | * @param flags controls certain features of the encoded output. 474 | * Passing {@code DEFAULT} results in output that 475 | * adheres to RFC 2045. 476 | */ 477 | public static String encodeToString(byte[] input, int offset, int len, int flags) { 478 | try { 479 | return new String(encode(input, offset, len, flags), "US-ASCII"); 480 | } catch (UnsupportedEncodingException e) { 481 | // US-ASCII is guaranteed to be available. 482 | throw new AssertionError(e); 483 | } 484 | } 485 | 486 | /** 487 | * Base64-encode the given data and return a newly allocated 488 | * byte[] with the result. 489 | * 490 | * @param input the data to encode 491 | * @param flags controls certain features of the encoded output. 492 | * Passing {@code DEFAULT} results in output that 493 | * adheres to RFC 2045. 494 | */ 495 | public static byte[] encode(byte[] input, int flags) { 496 | return encode(input, 0, input.length, flags); 497 | } 498 | 499 | /** 500 | * Base64-encode the given data and return a newly allocated 501 | * byte[] with the result. 502 | * 503 | * @param input the data to encode 504 | * @param offset the position within the input array at which to 505 | * start 506 | * @param len the number of bytes of input to encode 507 | * @param flags controls certain features of the encoded output. 508 | * Passing {@code DEFAULT} results in output that 509 | * adheres to RFC 2045. 510 | */ 511 | public static byte[] encode(byte[] input, int offset, int len, int flags) { 512 | Encoder encoder = new Encoder(flags, null); 513 | 514 | // Compute the exact length of the array we will produce. 515 | int output_len = len / 3 * 4; 516 | 517 | // Account for the tail of the data and the padding bytes, if any. 518 | if (encoder.do_padding) { 519 | if (len % 3 > 0) { 520 | output_len += 4; 521 | } 522 | } else { 523 | switch (len % 3) { 524 | case 0: break; 525 | case 1: output_len += 2; break; 526 | case 2: output_len += 3; break; 527 | } 528 | } 529 | 530 | // Account for the newlines, if any. 531 | if (encoder.do_newline && len > 0) { 532 | output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) * 533 | (encoder.do_cr ? 2 : 1); 534 | } 535 | 536 | encoder.output = new byte[output_len]; 537 | encoder.process(input, offset, len, true); 538 | 539 | assert encoder.op == output_len; 540 | 541 | return encoder.output; 542 | } 543 | 544 | /* package */ static class Encoder extends Coder { 545 | /** 546 | * Emit a new line every this many output tuples. Corresponds to 547 | * a 76-character line length (the maximum allowable according to 548 | * RFC 2045). 549 | */ 550 | public static final int LINE_GROUPS = 19; 551 | 552 | /** 553 | * Lookup table for turning Base64 alphabet positions (6 bits) 554 | * into output bytes. 555 | */ 556 | private static final byte ENCODE[] = { 557 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 558 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 559 | 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 560 | 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', 561 | }; 562 | 563 | /** 564 | * Lookup table for turning Base64 alphabet positions (6 bits) 565 | * into output bytes. 566 | */ 567 | private static final byte ENCODE_WEBSAFE[] = { 568 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 569 | 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 570 | 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 571 | 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_', 572 | }; 573 | 574 | final private byte[] tail; 575 | /* package */ int tailLen; 576 | private int count; 577 | 578 | final public boolean do_padding; 579 | final public boolean do_newline; 580 | final public boolean do_cr; 581 | final private byte[] alphabet; 582 | 583 | public Encoder(int flags, byte[] output) { 584 | this.output = output; 585 | 586 | do_padding = (flags & NO_PADDING) == 0; 587 | do_newline = (flags & NO_WRAP) == 0; 588 | do_cr = (flags & CRLF) != 0; 589 | alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE; 590 | 591 | tail = new byte[2]; 592 | tailLen = 0; 593 | 594 | count = do_newline ? LINE_GROUPS : -1; 595 | } 596 | 597 | /** 598 | * @return an overestimate for the number of bytes {@code 599 | * len} bytes could encode to. 600 | */ 601 | public int maxOutputSize(int len) { 602 | return len * 8/5 + 10; 603 | } 604 | 605 | public boolean process(byte[] input, int offset, int len, boolean finish) { 606 | // Using local variables makes the encoder about 9% faster. 607 | final byte[] alphabet = this.alphabet; 608 | final byte[] output = this.output; 609 | int op = 0; 610 | int count = this.count; 611 | 612 | int p = offset; 613 | len += offset; 614 | int v = -1; 615 | 616 | // First we need to concatenate the tail of the previous call 617 | // with any input bytes available now and see if we can empty 618 | // the tail. 619 | 620 | switch (tailLen) { 621 | case 0: 622 | // There was no tail. 623 | break; 624 | 625 | case 1: 626 | if (p+2 <= len) { 627 | // A 1-byte tail with at least 2 bytes of 628 | // input available now. 629 | v = ((tail[0] & 0xff) << 16) | 630 | ((input[p++] & 0xff) << 8) | 631 | (input[p++] & 0xff); 632 | tailLen = 0; 633 | }; 634 | break; 635 | 636 | case 2: 637 | if (p+1 <= len) { 638 | // A 2-byte tail with at least 1 byte of input. 639 | v = ((tail[0] & 0xff) << 16) | 640 | ((tail[1] & 0xff) << 8) | 641 | (input[p++] & 0xff); 642 | tailLen = 0; 643 | } 644 | break; 645 | } 646 | 647 | if (v != -1) { 648 | output[op++] = alphabet[(v >> 18) & 0x3f]; 649 | output[op++] = alphabet[(v >> 12) & 0x3f]; 650 | output[op++] = alphabet[(v >> 6) & 0x3f]; 651 | output[op++] = alphabet[v & 0x3f]; 652 | if (--count == 0) { 653 | if (do_cr) output[op++] = '\r'; 654 | output[op++] = '\n'; 655 | count = LINE_GROUPS; 656 | } 657 | } 658 | 659 | // At this point either there is no tail, or there are fewer 660 | // than 3 bytes of input available. 661 | 662 | // The main loop, turning 3 input bytes into 4 output bytes on 663 | // each iteration. 664 | while (p+3 <= len) { 665 | v = ((input[p] & 0xff) << 16) | 666 | ((input[p+1] & 0xff) << 8) | 667 | (input[p+2] & 0xff); 668 | output[op] = alphabet[(v >> 18) & 0x3f]; 669 | output[op+1] = alphabet[(v >> 12) & 0x3f]; 670 | output[op+2] = alphabet[(v >> 6) & 0x3f]; 671 | output[op+3] = alphabet[v & 0x3f]; 672 | p += 3; 673 | op += 4; 674 | if (--count == 0) { 675 | if (do_cr) output[op++] = '\r'; 676 | output[op++] = '\n'; 677 | count = LINE_GROUPS; 678 | } 679 | } 680 | 681 | if (finish) { 682 | // Finish up the tail of the input. Note that we need to 683 | // consume any bytes in tail before any bytes 684 | // remaining in input; there should be at most two bytes 685 | // total. 686 | 687 | if (p-tailLen == len-1) { 688 | int t = 0; 689 | v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4; 690 | tailLen -= t; 691 | output[op++] = alphabet[(v >> 6) & 0x3f]; 692 | output[op++] = alphabet[v & 0x3f]; 693 | if (do_padding) { 694 | output[op++] = '='; 695 | output[op++] = '='; 696 | } 697 | if (do_newline) { 698 | if (do_cr) output[op++] = '\r'; 699 | output[op++] = '\n'; 700 | } 701 | } else if (p-tailLen == len-2) { 702 | int t = 0; 703 | v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) | 704 | (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2); 705 | tailLen -= t; 706 | output[op++] = alphabet[(v >> 12) & 0x3f]; 707 | output[op++] = alphabet[(v >> 6) & 0x3f]; 708 | output[op++] = alphabet[v & 0x3f]; 709 | if (do_padding) { 710 | output[op++] = '='; 711 | } 712 | if (do_newline) { 713 | if (do_cr) output[op++] = '\r'; 714 | output[op++] = '\n'; 715 | } 716 | } else if (do_newline && op > 0 && count != LINE_GROUPS) { 717 | if (do_cr) output[op++] = '\r'; 718 | output[op++] = '\n'; 719 | } 720 | 721 | assert tailLen == 0; 722 | assert p == len; 723 | } else { 724 | // Save the leftovers in tail to be consumed on the next 725 | // call to encodeInternal. 726 | 727 | if (p == len-1) { 728 | tail[tailLen++] = input[p]; 729 | } else if (p == len-2) { 730 | tail[tailLen++] = input[p]; 731 | tail[tailLen++] = input[p+1]; 732 | } 733 | } 734 | 735 | this.op = op; 736 | this.count = count; 737 | 738 | return true; 739 | } 740 | } 741 | 742 | private Base64() { } // don't instantiate 743 | } 744 | -------------------------------------------------------------------------------- /android/src/main/java/com/jobeso/RNStoryShareFileProvider.java: -------------------------------------------------------------------------------- 1 | package com.jobeso; 2 | 3 | import androidx.core.content.FileProvider; 4 | 5 | public class RNStoryShareFileProvider extends FileProvider { 6 | } 7 | -------------------------------------------------------------------------------- /android/src/main/java/com/jobeso/RNStoryShareModule.java: -------------------------------------------------------------------------------- 1 | 2 | package com.jobeso; 3 | 4 | import android.app.Activity; 5 | import android.content.Intent; 6 | import android.content.pm.PackageManager; 7 | import android.net.Uri; 8 | import androidx.annotation.Nullable; 9 | import androidx.core.content.FileProvider; 10 | 11 | import com.facebook.react.bridge.JSApplicationIllegalArgumentException; 12 | import com.facebook.react.bridge.Promise; 13 | import com.facebook.react.bridge.ReactApplicationContext; 14 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 15 | import com.facebook.react.bridge.ReactMethod; 16 | import com.facebook.react.bridge.ReadableMap; 17 | import com.snap.creativekit.SnapCreative; 18 | import com.snap.creativekit.api.SnapCreativeKitApi; 19 | import com.snap.creativekit.exceptions.SnapMediaSizeException; 20 | import com.snap.creativekit.media.SnapMediaFactory; 21 | import com.snap.creativekit.media.SnapPhotoFile; 22 | import com.snap.creativekit.media.SnapSticker; 23 | import com.snap.creativekit.media.SnapVideoFile; 24 | import com.snap.creativekit.models.SnapContent; 25 | import com.snap.creativekit.models.SnapLiveCameraContent; 26 | import com.snap.creativekit.models.SnapPhotoContent; 27 | import com.snap.creativekit.models.SnapVideoContent; 28 | 29 | 30 | import java.io.BufferedOutputStream; 31 | import java.io.File; 32 | import java.io.FileInputStream; 33 | import java.io.FileNotFoundException; 34 | import java.io.FileOutputStream; 35 | import java.io.IOException; 36 | import java.io.InputStream; 37 | import java.io.OutputStream; 38 | import java.util.HashMap; 39 | import java.util.Map; 40 | import java.util.Random; 41 | 42 | import android.graphics.Bitmap; 43 | import android.graphics.BitmapFactory; 44 | import java.io.ByteArrayOutputStream; 45 | import java.net.URL; 46 | 47 | public class RNStoryShareModule extends ReactContextBaseJavaModule { 48 | private static final String FILE= "file"; 49 | private static final String BASE64 = "base64"; 50 | private static final String INTERNAL_DIR_NAME = "rnstoryshare"; 51 | 52 | private static final String SUCCESS = "success"; 53 | private static final String UNKNOWN_ERROR = "An unknown error occured in RNStoryShare"; 54 | private static final String ERROR_TYPE_NOT_SUPPORTED = "Type not supported by RNStoryShare"; 55 | private static final String ERROR_NO_PERMISSIONS = "Permissions Missing"; 56 | private static final String TYPE_ERROR = "Type Error"; 57 | private static final String MEDIA_TYPE_IMAGE = "image/*"; 58 | private static final String MEDIA_TYPE_VIDEO = "video/*"; 59 | private static final String PHOTO = "photo"; 60 | private static final String VIDEO = "video"; 61 | 62 | private static final String instagramScheme = "com.instagram.android"; 63 | private static final String snapchatScheme = "com.snapchat.android"; 64 | 65 | private final ReactApplicationContext reactContext; 66 | 67 | public RNStoryShareModule(ReactApplicationContext reactContext) { 68 | super(reactContext); 69 | this.reactContext = reactContext; 70 | } 71 | 72 | @Override 73 | public String getName() { 74 | return "RNStoryShare"; 75 | } 76 | 77 | @Override 78 | public Map getConstants() { 79 | final Map constants = new HashMap<>(); 80 | constants.put("BASE64", BASE64); 81 | constants.put("FILE", FILE); 82 | constants.put("SUCCESS", SUCCESS); 83 | constants.put("UNKNOWN_ERROR", UNKNOWN_ERROR); 84 | constants.put("TYPE_ERROR", TYPE_ERROR); 85 | return constants; 86 | } 87 | 88 | private String generateFileName(){ 89 | Random r = new Random(); 90 | int hash = r.nextInt(999999); 91 | 92 | return "image-" + hash + ".png"; 93 | } 94 | 95 | private String getFilePath() { 96 | String externalDir = this.getReactApplicationContext().getExternalCacheDir() + "/"; 97 | String namespaceDir = externalDir + INTERNAL_DIR_NAME + "/"; 98 | String fileName = generateFileName(); 99 | 100 | File folder = new File(namespaceDir); 101 | 102 | if (!folder.exists()) { 103 | Boolean isCreated = folder.mkdir(); 104 | 105 | if(!isCreated){ 106 | return externalDir + fileName; 107 | } 108 | } 109 | 110 | return namespaceDir + fileName; 111 | } 112 | 113 | private static File createFile(final String path){ 114 | final File file = new File(path); 115 | 116 | if (!file.exists()) { 117 | try { 118 | file.createNewFile(); 119 | } catch (IOException e) { 120 | e.printStackTrace(); 121 | return null; 122 | } 123 | } 124 | 125 | return file; 126 | } 127 | 128 | private static File getSavedImageFileForBase64(final String path, final String data) { 129 | final byte[] imgBytesData = android.util.Base64.decode(data, android.util.Base64.DEFAULT); 130 | final File file = createFile(path); 131 | final FileOutputStream fileOutputStream; 132 | 133 | try { 134 | fileOutputStream = new FileOutputStream(file); 135 | } catch (FileNotFoundException e) { 136 | e.printStackTrace(); 137 | return null; 138 | } 139 | 140 | final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); 141 | try { 142 | bufferedOutputStream.write(imgBytesData); 143 | } catch (IOException e) { 144 | e.printStackTrace(); 145 | return null; 146 | } finally { 147 | try { 148 | bufferedOutputStream.close(); 149 | } catch (IOException e) { 150 | e.printStackTrace(); 151 | } 152 | } 153 | return file; 154 | } 155 | 156 | private File getFileFromBase64String(String base64ImageData){ 157 | String backgroundAssetPath = getFilePath(); 158 | String data = base64ImageData.substring(base64ImageData.indexOf(",") + 1); 159 | 160 | return getSavedImageFileForBase64(backgroundAssetPath, data); 161 | } 162 | 163 | private static void copyFile(File src, File dst) throws IOException { 164 | InputStream in = new FileInputStream(src); 165 | try { 166 | OutputStream out = new FileOutputStream(dst); 167 | try { 168 | // Transfer bytes from in to out 169 | byte[] buf = new byte[1024]; 170 | int len; 171 | while ((len = in.read(buf)) > 0) { 172 | out.write(buf, 0, len); 173 | } 174 | } finally { 175 | out.close(); 176 | } 177 | } finally { 178 | in.close(); 179 | } 180 | } 181 | 182 | public String getBase64(String imagePath) { 183 | try { 184 | boolean isPNG = imagePath.contains(".png") ? true : false; 185 | 186 | InputStream in = new URL(imagePath).openConnection().getInputStream(); 187 | 188 | Bitmap bm = BitmapFactory.decodeStream(in); 189 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 190 | 191 | Bitmap.CompressFormat compressFormat = isPNG ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG; 192 | bm.compress(compressFormat, 100, baos); 193 | 194 | String base64prefix = String.format("data:image/%s;charset=utf-8;base64, ", isPNG ? "png" : "jpeg"); 195 | return base64prefix + Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT); 196 | } catch (Exception e) { 197 | e.printStackTrace(); 198 | return null; 199 | } 200 | } 201 | 202 | private void _shareToInstagram( 203 | @Nullable File backgroundFile, 204 | @Nullable File stickerFile, 205 | @Nullable String attributionLink, 206 | @Nullable String backgroundBottomColor, 207 | @Nullable String backgroundTopColor, 208 | String media, 209 | Promise promise 210 | ){ 211 | try { 212 | Intent intent = new Intent("com.instagram.share.ADD_TO_STORY"); 213 | String providerName = this.getReactApplicationContext().getPackageName() + ".fileprovider"; 214 | Activity activity = getCurrentActivity(); 215 | 216 | if (backgroundFile != null){ 217 | Uri backgroundImageUri = FileProvider.getUriForFile(activity, providerName, backgroundFile); 218 | 219 | //intent.setDataAndType(backgroundImageUri, MEDIA_TYPE_IMAGE); 220 | intent.setDataAndType(backgroundImageUri, media.equals(VIDEO) ? MEDIA_TYPE_VIDEO : MEDIA_TYPE_IMAGE); 221 | } else { 222 | intent.setType(MEDIA_TYPE_IMAGE); 223 | } 224 | 225 | if(stickerFile != null){ 226 | Uri stickerAssetUri = FileProvider.getUriForFile(activity, providerName, stickerFile); 227 | 228 | intent.putExtra("interactive_asset_uri", stickerAssetUri ); 229 | activity.grantUriPermission( 230 | "com.instagram.android", stickerAssetUri , Intent.FLAG_GRANT_READ_URI_PERMISSION); 231 | } 232 | 233 | intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 234 | 235 | if(backgroundBottomColor != null){ 236 | intent.putExtra("bottom_background_color", backgroundBottomColor); 237 | } 238 | 239 | if(backgroundTopColor != null){ 240 | intent.putExtra("top_background_color", backgroundTopColor); 241 | } 242 | 243 | if(attributionLink != null){ 244 | intent.putExtra("content_url", attributionLink); 245 | } 246 | 247 | if (activity.getPackageManager().resolveActivity(intent, 0) != null) { 248 | activity.startActivityForResult(intent, 0); 249 | promise.resolve(SUCCESS); 250 | }else{ 251 | throw new Exception("Couldn't open intent"); 252 | } 253 | }catch (Exception e){ 254 | promise.reject(UNKNOWN_ERROR, e); 255 | } 256 | } 257 | 258 | @ReactMethod 259 | public void shareToInstagram(ReadableMap config, Promise promise){ 260 | try{ 261 | String backgroundAsset = config.hasKey("backgroundAsset") ? config.getString("backgroundAsset") : null; 262 | String backgroundBottomColor = config.hasKey("backgroundBottomColor") ? config.getString("backgroundBottomColor") : null; 263 | String backgroundTopColor = config.hasKey("backgroundTopColor") ? config.getString("backgroundTopColor") : null; 264 | String stickerAsset = config.hasKey("stickerAsset") ? config.getString("stickerAsset") : null; 265 | String attributionLink = config.hasKey("attributionLink") ? config.getString("attributionLink") : null; 266 | String type = config.hasKey("type") ? config.getString("type") : FILE; 267 | String media = config.hasKey("media") ? config.getString("media") : PHOTO; 268 | 269 | if(backgroundAsset == null && stickerAsset == null){ 270 | Error e = new Error("backgroundAsset and stickerAsset are not allowed to both be null."); 271 | promise.reject("Error in RNStory Share: No asset paths provided", e); 272 | } 273 | 274 | if (!media.equals(PHOTO) && !media.equals(VIDEO)) { 275 | throw new Error(ERROR_TYPE_NOT_SUPPORTED); 276 | } 277 | 278 | File backgroundFile = null; 279 | File stickerFile = null; 280 | 281 | switch(type){ 282 | case BASE64: { 283 | if(backgroundAsset != null){ 284 | backgroundFile = getFileFromBase64String(backgroundAsset); 285 | 286 | if(backgroundFile == null){ 287 | throw new Error("Could not create file from Base64 in RNStoryShare"); 288 | } 289 | } 290 | 291 | if(stickerAsset != null){ 292 | stickerFile = getFileFromBase64String(stickerAsset); 293 | 294 | if(stickerFile == null){ 295 | throw new Error("Could not create file from Base64 in RNStoryShare"); 296 | } 297 | } 298 | break; 299 | } 300 | 301 | case FILE: { 302 | if (backgroundAsset != null) { 303 | backgroundFile = getFileFromBase64String(getBase64(backgroundAsset)); 304 | 305 | if (backgroundFile == null) { 306 | throw new Error("Could not create file from Base64 in RNStoryShare"); 307 | } 308 | } 309 | 310 | if (stickerAsset != null) { 311 | stickerFile = getFileFromBase64String(getBase64(stickerAsset)); 312 | 313 | if (stickerFile == null) { 314 | throw new Error("Could not create file from Base64 in RNStoryShare"); 315 | } 316 | } 317 | 318 | break; 319 | } 320 | 321 | default: { 322 | throw new Error(ERROR_TYPE_NOT_SUPPORTED); 323 | } 324 | } 325 | 326 | _shareToInstagram(backgroundFile, stickerFile, attributionLink, backgroundBottomColor, backgroundTopColor, media, promise); 327 | } catch (NullPointerException e){ 328 | promise.reject(e.getMessage(), e); 329 | } catch (Exception e){ 330 | promise.reject(UNKNOWN_ERROR, e); 331 | } catch(Error e) { 332 | promise.reject(e.getMessage(), e); 333 | } 334 | } 335 | 336 | private void _shareToSnapchat( 337 | @Nullable File backgroundFile, 338 | @Nullable File stickerFile, 339 | @Nullable ReadableMap stickerOptions, 340 | @Nullable String attributionLink, 341 | @Nullable String captionText, 342 | String media, 343 | Promise promise 344 | ) { 345 | try { 346 | Activity activity = getCurrentActivity(); 347 | SnapMediaFactory snapMediaFactory = SnapCreative.getMediaFactory(activity); 348 | SnapContent snapContent; 349 | SnapCreativeKitApi snapCreativeKitApi = SnapCreative.getApi(activity); 350 | 351 | if (backgroundFile != null) { 352 | if (media.equals(PHOTO)) { 353 | SnapPhotoFile photoFile = snapMediaFactory.getSnapPhotoFromFile(backgroundFile); 354 | snapContent = new SnapPhotoContent(photoFile); 355 | } else { 356 | SnapVideoFile videoFile = snapMediaFactory.getSnapVideoFromFile(backgroundFile); 357 | snapContent = new SnapVideoContent(videoFile); 358 | } 359 | 360 | } else { 361 | snapContent = new SnapLiveCameraContent(); 362 | } 363 | 364 | if(stickerFile != null){ 365 | SnapSticker snapSticker = snapMediaFactory.getSnapStickerFromFile(stickerFile); 366 | 367 | if(stickerOptions != null){ 368 | Integer width = stickerOptions.hasKey("width") ? stickerOptions.getInt("width") : null; 369 | Integer height = stickerOptions.hasKey("height") ? stickerOptions.getInt("height") : null; 370 | 371 | if(width != null){ 372 | snapSticker.setWidth(width); 373 | } 374 | 375 | if(height != null){ 376 | snapSticker.setHeight(height); 377 | } 378 | } 379 | 380 | snapContent.setSnapSticker(snapSticker); 381 | } 382 | 383 | if(attributionLink != null){ 384 | snapContent.setAttachmentUrl(attributionLink); 385 | } 386 | 387 | if (captionText != null){ 388 | snapContent.setCaptionText(captionText); 389 | } 390 | 391 | snapCreativeKitApi.send(snapContent); 392 | promise.resolve(SUCCESS); 393 | } catch (SnapMediaSizeException e) { 394 | promise.reject("RNStoryShare: Snapchat Exception", e.getMessage()); 395 | } catch (Exception e){ 396 | promise.reject(UNKNOWN_ERROR, e); 397 | } 398 | } 399 | 400 | @ReactMethod 401 | public void shareToSnapchat(ReadableMap config, Promise promise) { 402 | try { 403 | String backgroundAsset = config.hasKey("backgroundAsset") ? config.getString("backgroundAsset") : null; 404 | String stickerAsset = config.hasKey("stickerAsset") ? config.getString("stickerAsset") : null; 405 | ReadableMap stickerOptions = config.hasKey("stickerOptions") ? config.getMap("stickerOptions") : null; 406 | String attributionLink = config.hasKey("attributionLink") ? config.getString("attributionLink") : null; 407 | String captionText = config.hasKey("captionText") ? config.getString("captionText") : null; 408 | String type = config.hasKey("type") ? config.getString("type") : FILE; 409 | String media = config.hasKey("media") ? config.getString("media") : PHOTO; 410 | 411 | File backgroundFile = null; 412 | File stickerFile = null; 413 | 414 | if (!type.equals(BASE64) && !type.equals(FILE)){ 415 | throw new Error(ERROR_TYPE_NOT_SUPPORTED); 416 | } 417 | 418 | if (!media.equals(PHOTO) && !media.equals(VIDEO)) { 419 | throw new Error(ERROR_TYPE_NOT_SUPPORTED); 420 | } 421 | 422 | if (backgroundAsset == null && stickerAsset == null){ 423 | throw new Error("backgroundAsset and stickerAsset are not allowed to both be null."); 424 | } 425 | 426 | if (backgroundAsset != null){ 427 | if (type.equals(BASE64)){ 428 | backgroundFile = getFileFromBase64String(backgroundAsset); 429 | } else { 430 | backgroundFile = new File(backgroundAsset); 431 | } 432 | 433 | if(backgroundFile == null){ 434 | throw new Error("Could not create file from Base64 in RNStoryShare"); 435 | } 436 | } 437 | 438 | if (stickerAsset != null){ 439 | stickerFile = getFileFromBase64String(stickerAsset); 440 | 441 | if(stickerFile == null){ 442 | throw new Error("Could not create file from Base64 in RNStoryShare"); 443 | } 444 | } 445 | 446 | _shareToSnapchat(backgroundFile, stickerFile, stickerOptions, attributionLink, captionText, media, promise); 447 | } catch (Error e){ 448 | promise.reject(e.getMessage(), e); 449 | } catch (Exception e){ 450 | promise.reject(UNKNOWN_ERROR, e); 451 | } 452 | } 453 | 454 | 455 | private void canOpenUrl(String packageScheme, Promise promise){ 456 | try{ 457 | Activity activity = getCurrentActivity(); 458 | activity.getPackageManager().getPackageInfo(packageScheme, PackageManager.GET_ACTIVITIES); 459 | promise.resolve(true); 460 | } catch (PackageManager.NameNotFoundException e) { 461 | promise.resolve(false); 462 | } catch (Exception e) { 463 | promise.reject(new JSApplicationIllegalArgumentException( 464 | "Could not check if URL '" + packageScheme + "' can be opened: " + e.getMessage())); 465 | } 466 | } 467 | 468 | @ReactMethod 469 | public void isInstagramAvailable(Promise promise){ 470 | canOpenUrl(instagramScheme, promise); 471 | } 472 | 473 | @ReactMethod 474 | public void isSnapchatAvailable(Promise promise){ 475 | canOpenUrl(snapchatScheme, promise); 476 | } 477 | } 478 | -------------------------------------------------------------------------------- /android/src/main/java/com/jobeso/RNStorySharePackage.java: -------------------------------------------------------------------------------- 1 | 2 | package com.jobeso; 3 | 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | import com.facebook.react.ReactPackage; 9 | import com.facebook.react.bridge.NativeModule; 10 | import com.facebook.react.bridge.ReactApplicationContext; 11 | import com.facebook.react.uimanager.ViewManager; 12 | import com.facebook.react.bridge.JavaScriptModule; 13 | public class RNStorySharePackage implements ReactPackage { 14 | @Override 15 | public List createNativeModules(ReactApplicationContext reactContext) { 16 | return Arrays.asList(new RNStoryShareModule(reactContext)); 17 | } 18 | 19 | // Deprecated from RN 0.47 20 | public List> createJSModules() { 21 | return Collections.emptyList(); 22 | } 23 | 24 | @Override 25 | public List createViewManagers(ReactApplicationContext reactContext) { 26 | return Collections.emptyList(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /android/src/main/res/xml/filepaths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /example/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /example/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | 16 | ; Ignore polyfills 17 | .*/Libraries/polyfills/.* 18 | 19 | ; Ignore metro 20 | .*/node_modules/metro/.* 21 | 22 | [include] 23 | 24 | [libs] 25 | node_modules/react-native/Libraries/react-native/react-native-interface.js 26 | node_modules/react-native/flow/ 27 | 28 | [options] 29 | emoji=true 30 | 31 | esproposal.optional_chaining=enable 32 | esproposal.nullish_coalescing=enable 33 | 34 | module.system=haste 35 | module.system.haste.use_name_reducers=true 36 | # get basename 37 | module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' 38 | # strip .js or .js.flow suffix 39 | module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' 40 | # strip .ios suffix 41 | module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' 42 | module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' 43 | module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' 44 | module.system.haste.paths.blacklist=.*/__tests__/.* 45 | module.system.haste.paths.blacklist=.*/__mocks__/.* 46 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* 47 | module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.* 48 | 49 | munge_underscores=true 50 | 51 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 52 | 53 | module.file_ext=.js 54 | module.file_ext=.jsx 55 | module.file_ext=.json 56 | module.file_ext=.native.js 57 | 58 | suppress_type=$FlowIssue 59 | suppress_type=$FlowFixMe 60 | suppress_type=$FlowFixMeProps 61 | suppress_type=$FlowFixMeState 62 | 63 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 64 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 65 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 66 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 67 | 68 | [version] 69 | ^0.92.0 70 | -------------------------------------------------------------------------------- /example/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | -------------------------------------------------------------------------------- /example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /example/__tests__/App-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: test renderer must be required after react-native. 10 | import renderer from 'react-test-renderer'; 11 | 12 | it('renders correctly', () => { 13 | renderer.create(); 14 | }); 15 | -------------------------------------------------------------------------------- /example/android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.example", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.example", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // whether to bundle JS and assets in debug mode 22 | * bundleInDebug: false, 23 | * 24 | * // whether to bundle JS and assets in release mode 25 | * bundleInRelease: true, 26 | * 27 | * // whether to bundle JS and assets in another build variant (if configured). 28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 29 | * // The configuration property can be in the following formats 30 | * // 'bundleIn${productFlavor}${buildType}' 31 | * // 'bundleIn${buildType}' 32 | * // bundleInFreeDebug: true, 33 | * // bundleInPaidRelease: true, 34 | * // bundleInBeta: true, 35 | * 36 | * // whether to disable dev mode in custom build variants (by default only disabled in release) 37 | * // for example: to disable dev mode in the staging build type (if configured) 38 | * devDisabledInStaging: true, 39 | * // The configuration property can be in the following formats 40 | * // 'devDisabledIn${productFlavor}${buildType}' 41 | * // 'devDisabledIn${buildType}' 42 | * 43 | * // the root of your project, i.e. where "package.json" lives 44 | * root: "../../", 45 | * 46 | * // where to put the JS bundle asset in debug mode 47 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 48 | * 49 | * // where to put the JS bundle asset in release mode 50 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 51 | * 52 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 53 | * // require('./image.png')), in debug mode 54 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 55 | * 56 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 57 | * // require('./image.png')), in release mode 58 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 59 | * 60 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 61 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 62 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 63 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 64 | * // for example, you might want to remove it from here. 65 | * inputExcludes: ["android/**", "ios/**"], 66 | * 67 | * // override which node gets called and with what additional arguments 68 | * nodeExecutableAndArgs: ["node"], 69 | * 70 | * // supply additional arguments to the packager 71 | * extraPackagerArgs: [] 72 | * ] 73 | */ 74 | 75 | project.ext.react = [ 76 | entryFile: "index.js" 77 | ] 78 | 79 | apply from: "../../node_modules/react-native/react.gradle" 80 | 81 | /** 82 | * Set this to true to create two separate APKs instead of one: 83 | * - An APK that only works on ARM devices 84 | * - An APK that only works on x86 devices 85 | * The advantage is the size of the APK is reduced by about 4MB. 86 | * Upload all the APKs to the Play Store and people will download 87 | * the correct one based on the CPU architecture of their device. 88 | */ 89 | def enableSeparateBuildPerCPUArchitecture = false 90 | 91 | /** 92 | * Run Proguard to shrink the Java bytecode in release builds. 93 | */ 94 | def enableProguardInReleaseBuilds = false 95 | 96 | android { 97 | compileSdkVersion rootProject.ext.compileSdkVersion 98 | 99 | compileOptions { 100 | sourceCompatibility JavaVersion.VERSION_1_8 101 | targetCompatibility JavaVersion.VERSION_1_8 102 | } 103 | 104 | defaultConfig { 105 | applicationId "com.example" 106 | minSdkVersion rootProject.ext.minSdkVersion 107 | targetSdkVersion rootProject.ext.targetSdkVersion 108 | versionCode 1 109 | versionName "1.0" 110 | } 111 | splits { 112 | abi { 113 | reset() 114 | enable enableSeparateBuildPerCPUArchitecture 115 | universalApk false // If true, also generate a universal APK 116 | include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" 117 | } 118 | } 119 | buildTypes { 120 | release { 121 | minifyEnabled enableProguardInReleaseBuilds 122 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 123 | } 124 | } 125 | // applicationVariants are e.g. debug, release 126 | applicationVariants.all { variant -> 127 | variant.outputs.each { output -> 128 | // For each separate APK per architecture, set a unique version code as described here: 129 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 130 | def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a": 3, "x86_64": 4] 131 | def abi = output.getFilter(OutputFile.ABI) 132 | if (abi != null) { // null for the universal-debug, universal-release variants 133 | output.versionCodeOverride = 134 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 135 | } 136 | } 137 | } 138 | } 139 | 140 | dependencies { 141 | implementation project(':react-native-view-shot') 142 | implementation project(':react-native-story-share') 143 | implementation fileTree(dir: "libs", include: ["*.jar"]) 144 | implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}" 145 | implementation "com.facebook.react:react-native:+" // From node_modules 146 | } 147 | 148 | // Run this once to be able to run the application with BUCK 149 | // puts all compile dependencies into folder libs for BUCK to use 150 | task copyDownloadableDepsToLibs(type: Copy) { 151 | from configurations.compile 152 | into 'libs' 153 | } 154 | -------------------------------------------------------------------------------- /example/android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /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 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "example"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.react.ReactApplication; 6 | import fr.greweb.reactnativeviewshot.RNViewShotPackage; 7 | import com.jobeso.RNStorySharePackage; 8 | import com.facebook.react.ReactNativeHost; 9 | import com.facebook.react.ReactPackage; 10 | import com.facebook.react.shell.MainReactPackage; 11 | import com.facebook.soloader.SoLoader; 12 | 13 | import java.util.Arrays; 14 | import java.util.List; 15 | 16 | public class MainApplication extends Application implements ReactApplication { 17 | 18 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 19 | @Override 20 | public boolean getUseDeveloperSupport() { 21 | return BuildConfig.DEBUG; 22 | } 23 | 24 | @Override 25 | protected List getPackages() { 26 | return Arrays.asList( 27 | new MainReactPackage(), 28 | new RNViewShotPackage(), 29 | new RNStorySharePackage() 30 | ); 31 | } 32 | 33 | @Override 34 | protected String getJSMainModuleName() { 35 | return "index"; 36 | } 37 | }; 38 | 39 | @Override 40 | public ReactNativeHost getReactNativeHost() { 41 | return mReactNativeHost; 42 | } 43 | 44 | @Override 45 | public void onCreate() { 46 | super.onCreate(); 47 | SoLoader.init(this, /* native exopackage */ false); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jobeso/react-native-story-share/54feb918d8f0c0fd17da49d54f416878bb15bb85/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/Jobeso/react-native-story-share/54feb918d8f0c0fd17da49d54f416878bb15bb85/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/Jobeso/react-native-story-share/54feb918d8f0c0fd17da49d54f416878bb15bb85/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/Jobeso/react-native-story-share/54feb918d8f0c0fd17da49d54f416878bb15bb85/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/Jobeso/react-native-story-share/54feb918d8f0c0fd17da49d54f416878bb15bb85/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/Jobeso/react-native-story-share/54feb918d8f0c0fd17da49d54f416878bb15bb85/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/Jobeso/react-native-story-share/54feb918d8f0c0fd17da49d54f416878bb15bb85/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/Jobeso/react-native-story-share/54feb918d8f0c0fd17da49d54f416878bb15bb85/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/Jobeso/react-native-story-share/54feb918d8f0c0fd17da49d54f416878bb15bb85/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/Jobeso/react-native-story-share/54feb918d8f0c0fd17da49d54f416878bb15bb85/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | example 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /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 = "28.0.3" 6 | minSdkVersion = 19 7 | compileSdkVersion = 28 8 | targetSdkVersion = 28 9 | supportLibVersion = "28.0.0" 10 | } 11 | repositories { 12 | google() 13 | jcenter() 14 | } 15 | dependencies { 16 | classpath 'com.android.tools.build:gradle:3.3.1' 17 | 18 | // NOTE: Do not place your application dependencies here; they belong 19 | // in the individual module build.gradle files 20 | } 21 | } 22 | 23 | allprojects { 24 | repositories { 25 | mavenLocal() 26 | google() 27 | jcenter() 28 | maven { 29 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 30 | url "$rootDir/../node_modules/react-native/android" 31 | } 32 | maven { url "https://storage.googleapis.com/snap-kit-build/maven" } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /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: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 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 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jobeso/react-native-story-share/54feb918d8f0c0fd17da49d54f416878bb15bb85/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 6 | -------------------------------------------------------------------------------- /example/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /example/android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = "debug", 3 | properties = "debug.keystore.properties", 4 | store = "debug.keystore", 5 | visibility = [ 6 | "PUBLIC", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /example/android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'example' 2 | include ':react-native-view-shot' 3 | project(':react-native-view-shot').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-view-shot/android') 4 | include ':react-native-story-share' 5 | project(':react-native-story-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-story-share/android') 6 | 7 | include ':app' 8 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "displayName": "example" 4 | } -------------------------------------------------------------------------------- /example/app/Button.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Text, TouchableOpacity } from 'react-native' 3 | import P from 'prop-types' 4 | 5 | export const Button = ({ children, onPress }) => ( 6 | 7 | {children} 8 | 9 | ) 10 | 11 | Button.propTypes = { 12 | children: P.string.isRequired, 13 | onPress: P.func, 14 | } 15 | 16 | Button.defaultProps = { 17 | onPress: () => {}, 18 | } 19 | -------------------------------------------------------------------------------- /example/app/Root.js: -------------------------------------------------------------------------------- 1 | import { curry } from 'ramda' 2 | import React from 'react' 3 | import { Platform, ScrollView, Text } from 'react-native' 4 | import Permissions from 'react-native-permissions' 5 | import RNStoryShare from 'react-native-story-share' 6 | import ViewShot, { captureRef } from 'react-native-view-shot' 7 | import { Button } from './Button' 8 | import { ShareSection } from './ShareSection' 9 | 10 | const base64Background = 11 | 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAQAAAAHUWYVAAABKUlEQVR42u3RMQEAAAjDMOZf9DDBwZFKaNKOHhUgQAQEiIAAERAgAgJEQAQEiIAAERAgAgJEQAQEiIAAERAgAgJEQAQEiIAAERAgAgJEQAQEiIAAERAgAgJEQAQEiIAAERAgAgJEQAQEiIAAERAgAgJEQAQEiIAAERAgAgJEQAQEiIAAERAgAgJEQAQEiIAAERAgAgJEQICYAERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAEBIiBABAQIECACAkRAgAgIEAEBIiACAkRAgAgIEAEBIiACAkRAgOiyBdIBj0hI3a/GAAAAAElFTkSuQmCC' 12 | const base64Sticker = 13 | 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAABn0lEQVR42u3TAQ0AAAjDMO5fNCAABaTNLCxdtQGXGAQMAgYBg4BBwCBgEDAIGAQMAhgEDAIGAYOAQcAgYBAwCBgEDGIQMAgYBAwCBgGDgEHAIGAQMAhgEDAIGAQMAgYBg4BBwCBgEDAIYBAwCBgEDAIGAYOAQcAgYBDAIGAQMAgYBAwCBgGDgEHAIGAQwCBgEDAIGAQMAgYBg4BBwCCAQcAgYBAwCBgEDAIGAYOAQcAggEHAIGAQMAgYBAwCBgGDgEHAIAYBg4BBwCBgEDAIGAQMAgYBgwAGAYOAQcAgYBAwCBgEDAIGAYMYBAwCBgGDgEHAIGAQMAgYBAwCGAQMAgYBg4BBwCBgEDAIGAQMAhgEDAIGAYOAQcAgYBAwCBgEMAgYBAwCBgGDgEHAIGAQMAgYBDAIGAQMAgYBg4BBwCBgEDAIYBAwCBgEDAIGAYOAQcAgYBAwCGAQMAgYBAwCBgGDgEHAIGAQMIhBwCBgEDAIGAQMAgYBg4BBwCCAQcAgYBAwCBgEDAIGAYOAQcAgBgGDgEHAIGAQMAgYBAwCHw2n4Y9IKdr/IQAAAABJRU5ErkJggg==' 14 | 15 | // curry is not necessary RNStoryShares functions 16 | // it returns a new function when only part of the arguments are provided 17 | // see https://ramdajs.com/docs/#curry 18 | const shareInstagram = curry((onError, type, backgroundAsset, stickerAsset) => { 19 | RNStoryShare.shareToInstagram({ 20 | backgroundAsset, 21 | stickerAsset, 22 | backgroundBottomColor: '#f44162', 23 | backgroundTopColor: '#f4a142', 24 | attributionLink: '', 25 | type, 26 | }).catch(onError) 27 | }) 28 | 29 | // curry is not necessary RNStoryShares functions 30 | // it returns a new function when only part of the arguments are provided 31 | // see https://ramdajs.com/docs/#curry 32 | const shareSnapchat = curry((onError, type, backgroundAsset, stickerAsset) => { 33 | RNStoryShare.shareToSnapchat({ 34 | backgroundAsset, 35 | stickerAsset, 36 | attributionLink: 'https://google.com/', 37 | type, 38 | }).catch(onError) 39 | }) 40 | 41 | class Root extends React.PureComponent { 42 | state = { 43 | error: undefined, 44 | isInstagramAvailable: false, 45 | isSnapchatAvailable: false, 46 | } 47 | 48 | async componentDidMount() { 49 | if (Platform.OS === 'android') { 50 | Permissions.request('storage').then(response => { 51 | if (response === 'denied') { 52 | this.setState({ error: 'No permissions' }) 53 | } 54 | }) 55 | } 56 | 57 | try { 58 | const isInstagramAvailable = await RNStoryShare.isInstagramAvailable() 59 | const isSnapchatAvailable = await RNStoryShare.isSnapchatAvailable() 60 | 61 | this.setState({ isInstagramAvailable, isSnapchatAvailable }) 62 | } catch (error) { 63 | this.setState({ error }) 64 | } 65 | } 66 | 67 | _ref = undefined 68 | 69 | _setError = e => { 70 | this.setState({ error: e }) 71 | } 72 | 73 | _captureScreen = () => 74 | new Promise(resolve => { 75 | captureRef(this._ref, { 76 | format: 'png', 77 | quality: 0.8, 78 | }) 79 | .then(uri => { 80 | resolve(uri) 81 | }) 82 | .catch(this._setError) 83 | }) 84 | 85 | _shareInstaBase64 = shareInstagram(this._setError, RNStoryShare.BASE64) 86 | _shareInstaBackground = () => { 87 | this._shareInstaBase64(base64Background, undefined) 88 | } 89 | _shareInstaSticker = () => { 90 | this._shareInstaBase64(undefined, base64Sticker) 91 | } 92 | _shareInstaBoth = () => { 93 | this._shareInstaBase64(base64Background, base64Sticker) 94 | } 95 | 96 | _shareInstaFile = shareInstagram(this._setError, RNStoryShare.FILE) 97 | _shareInstaFileBackground = async () => { 98 | const uri = await this._captureScreen() 99 | 100 | this._shareInstaFile(uri, undefined) 101 | } 102 | _shareInstaFileSticker = async () => { 103 | const uri = await this._captureScreen() 104 | 105 | this._shareInstaFile(undefined, uri) 106 | } 107 | _shareInstaFileBoth = async () => { 108 | const uri = await this._captureScreen() 109 | 110 | this._shareInstaFile(uri, uri) 111 | } 112 | 113 | _shareSnapBase64 = shareSnapchat(this._setError, RNStoryShare.BASE64) 114 | _shareSnapBackground = () => { 115 | this._shareSnapBase64(base64Background, undefined) 116 | } 117 | _shareSnapSticker = () => { 118 | this._shareSnapBase64(undefined, base64Sticker) 119 | } 120 | _shareSnapBoth = () => { 121 | this._shareSnapBase64(base64Background, base64Sticker) 122 | } 123 | 124 | _shareSnapFile = shareSnapchat(this._setError, RNStoryShare.FILE) 125 | _shareSnapFileBackground = async () => { 126 | const uri = await this._captureScreen() 127 | 128 | this._shareSnapFile(uri, undefined) 129 | } 130 | _shareSnapFileSticker = async () => { 131 | const uri = await this._captureScreen() 132 | 133 | this._shareSnapFile(undefined, uri) 134 | } 135 | _shareSnapFileBoth = async () => { 136 | const uri = await this._captureScreen() 137 | 138 | this._shareSnapFile(uri, uri) 139 | } 140 | 141 | _setRef = ref => { 142 | this._ref = ref 143 | } 144 | 145 | render() { 146 | const { error, isInstagramAvailable, isSnapchatAvailable } = this.state 147 | 148 | return ( 149 | 157 | 158 | 165 | RNStoryShare Example 166 | 167 | 168 | 172 | 173 | 174 | 175 | 176 | 177 | 181 | 182 | 183 | 184 | 185 | 186 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | {error ? `error: ${error.message}` : null} 204 | 205 | 206 | ) 207 | } 208 | } 209 | 210 | export { Root } 211 | -------------------------------------------------------------------------------- /example/app/ShareSection.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Text, View } from 'react-native' 3 | import P from 'prop-types' 4 | 5 | export const ShareSection = ({ children, isAvailable, title }) => ( 6 | <> 7 | {title} 8 | 9 | {isAvailable ? 'available' : 'not available'} 10 | 11 | 19 | {children} 20 | 21 | 22 | ) 23 | 24 | ShareSection.propTypes = { 25 | children: P.oneOfType([P.element, P.array]), 26 | isAvailable: P.bool, 27 | title: P.string.isRequired, 28 | } 29 | 30 | ShareSection.defaultProps = { 31 | isAvailable: false, 32 | } 33 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import { AppRegistry } from 'react-native' 6 | import { Root } from './app/Root' 7 | import { name as appName } from './app.json' 8 | 9 | AppRegistry.registerComponent(appName, () => Root) 10 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'example' do 5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for example 9 | pod 'SnapSDK', :subspecs => ['SCSDKCreativeKit'] 10 | 11 | end 12 | 13 | post_install do |installer| 14 | installer.pods_project.targets.each do |target| 15 | if target.name == "React" 16 | target.remove_from_project 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SnapSDK/SCSDKCreativeKit (1.3.1) 3 | 4 | DEPENDENCIES: 5 | - SnapSDK/SCSDKCreativeKit 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - SnapSDK 10 | 11 | SPEC CHECKSUMS: 12 | SnapSDK: be510aaabbfa7ab0142b53770f2e79c6c6b363e6 13 | 14 | PODFILE CHECKSUM: 8bd2eddce1a393d7d107f8928793e97893a7fd18 15 | 16 | COCOAPODS: 1.5.3 17 | -------------------------------------------------------------------------------- /example/ios/empty.swift: -------------------------------------------------------------------------------- 1 | // 2 | // empty.swift 3 | // example 4 | // 5 | // Created by Johannes Sorg on 05.05.19. 6 | // Copyright © 2019 Facebook. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /example/ios/example-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 | 5 | -------------------------------------------------------------------------------- /example/ios/example-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | 44 | NSExceptionDomains 45 | 46 | localhost 47 | 48 | NSExceptionAllowsInsecureHTTPLoads 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /example/ios/example-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 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/example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 11 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; 12 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; 13 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; 14 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 15 | 11D1A2F320CAFA9E000508D9 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; }; 16 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; 17 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; 18 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 19 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 20 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 21 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 22 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 23 | 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 24 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 25 | A28A7FED64964DAF85E4297E /* libRNStoryShare.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD32FA0ED5A84EB2822BE5C3 /* libRNStoryShare.a */; }; 26 | ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */; }; 27 | ED297163215061F000B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED297162215061F000B7C4FE /* JavaScriptCore.framework */; }; 28 | F3A52ED1227EE8B5009EE95D /* empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3A52ED0227EE8B5009EE95D /* empty.swift */; }; 29 | F3C7F31E2286E180005B3881 /* libRNViewShot.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3C7F31D2286E16A005B3881 /* libRNViewShot.a */; }; 30 | F3F6EE9122872CAF00EB4FD9 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3F6EE8E22872C9B00EB4FD9 /* libReactNativePermissions.a */; }; 31 | FB31D6945635E06C6EFC9194 /* Pods_example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFECA5B9F615BCF6E26ACB8B /* Pods_example.framework */; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXContainerItemProxy section */ 35 | 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { 36 | isa = PBXContainerItemProxy; 37 | containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 38 | proxyType = 2; 39 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 40 | remoteInfo = RCTActionSheet; 41 | }; 42 | 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { 43 | isa = PBXContainerItemProxy; 44 | containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 45 | proxyType = 2; 46 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 47 | remoteInfo = RCTGeolocation; 48 | }; 49 | 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { 50 | isa = PBXContainerItemProxy; 51 | containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 52 | proxyType = 2; 53 | remoteGlobalIDString = 58B5115D1A9E6B3D00147676; 54 | remoteInfo = RCTImage; 55 | }; 56 | 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = { 57 | isa = PBXContainerItemProxy; 58 | containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 59 | proxyType = 2; 60 | remoteGlobalIDString = 58B511DB1A9E6C8500147676; 61 | remoteInfo = RCTNetwork; 62 | }; 63 | 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = { 64 | isa = PBXContainerItemProxy; 65 | containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 66 | proxyType = 2; 67 | remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; 68 | remoteInfo = RCTVibration; 69 | }; 70 | 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { 71 | isa = PBXContainerItemProxy; 72 | containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 73 | proxyType = 2; 74 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 75 | remoteInfo = RCTSettings; 76 | }; 77 | 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = { 78 | isa = PBXContainerItemProxy; 79 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 80 | proxyType = 2; 81 | remoteGlobalIDString = 3C86DF461ADF2C930047B81A; 82 | remoteInfo = RCTWebSocket; 83 | }; 84 | 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { 85 | isa = PBXContainerItemProxy; 86 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 87 | proxyType = 2; 88 | remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; 89 | remoteInfo = React; 90 | }; 91 | 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */ = { 92 | isa = PBXContainerItemProxy; 93 | containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; 94 | proxyType = 2; 95 | remoteGlobalIDString = ADD01A681E09402E00F6D226; 96 | remoteInfo = "RCTBlob-tvOS"; 97 | }; 98 | 2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */ = { 99 | isa = PBXContainerItemProxy; 100 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 101 | proxyType = 2; 102 | remoteGlobalIDString = 3DBE0D001F3B181A0099AA32; 103 | remoteInfo = fishhook; 104 | }; 105 | 2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */ = { 106 | isa = PBXContainerItemProxy; 107 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 108 | proxyType = 2; 109 | remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32; 110 | remoteInfo = "fishhook-tvOS"; 111 | }; 112 | 2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */ = { 113 | isa = PBXContainerItemProxy; 114 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 115 | proxyType = 2; 116 | remoteGlobalIDString = EBF21BDC1FC498900052F4D5; 117 | remoteInfo = jsinspector; 118 | }; 119 | 2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */ = { 120 | isa = PBXContainerItemProxy; 121 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 122 | proxyType = 2; 123 | remoteGlobalIDString = EBF21BFA1FC4989A0052F4D5; 124 | remoteInfo = "jsinspector-tvOS"; 125 | }; 126 | 2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */ = { 127 | isa = PBXContainerItemProxy; 128 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 129 | proxyType = 2; 130 | remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7; 131 | remoteInfo = "third-party"; 132 | }; 133 | 2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */ = { 134 | isa = PBXContainerItemProxy; 135 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 136 | proxyType = 2; 137 | remoteGlobalIDString = 3D383D3C1EBD27B6005632C8; 138 | remoteInfo = "third-party-tvOS"; 139 | }; 140 | 2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */ = { 141 | isa = PBXContainerItemProxy; 142 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 143 | proxyType = 2; 144 | remoteGlobalIDString = 139D7E881E25C6D100323FB7; 145 | remoteInfo = "double-conversion"; 146 | }; 147 | 2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */ = { 148 | isa = PBXContainerItemProxy; 149 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 150 | proxyType = 2; 151 | remoteGlobalIDString = 3D383D621EBD27B9005632C8; 152 | remoteInfo = "double-conversion-tvOS"; 153 | }; 154 | 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = { 155 | isa = PBXContainerItemProxy; 156 | containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 157 | proxyType = 2; 158 | remoteGlobalIDString = 2D2A283A1D9B042B00D4039D; 159 | remoteInfo = "RCTImage-tvOS"; 160 | }; 161 | 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */ = { 162 | isa = PBXContainerItemProxy; 163 | containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 164 | proxyType = 2; 165 | remoteGlobalIDString = 2D2A28471D9B043800D4039D; 166 | remoteInfo = "RCTLinking-tvOS"; 167 | }; 168 | 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */ = { 169 | isa = PBXContainerItemProxy; 170 | containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 171 | proxyType = 2; 172 | remoteGlobalIDString = 2D2A28541D9B044C00D4039D; 173 | remoteInfo = "RCTNetwork-tvOS"; 174 | }; 175 | 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */ = { 176 | isa = PBXContainerItemProxy; 177 | containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 178 | proxyType = 2; 179 | remoteGlobalIDString = 2D2A28611D9B046600D4039D; 180 | remoteInfo = "RCTSettings-tvOS"; 181 | }; 182 | 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */ = { 183 | isa = PBXContainerItemProxy; 184 | containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 185 | proxyType = 2; 186 | remoteGlobalIDString = 2D2A287B1D9B048500D4039D; 187 | remoteInfo = "RCTText-tvOS"; 188 | }; 189 | 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */ = { 190 | isa = PBXContainerItemProxy; 191 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 192 | proxyType = 2; 193 | remoteGlobalIDString = 2D2A28881D9B049200D4039D; 194 | remoteInfo = "RCTWebSocket-tvOS"; 195 | }; 196 | 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */ = { 197 | isa = PBXContainerItemProxy; 198 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 199 | proxyType = 2; 200 | remoteGlobalIDString = 2D2A28131D9B038B00D4039D; 201 | remoteInfo = "React-tvOS"; 202 | }; 203 | 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */ = { 204 | isa = PBXContainerItemProxy; 205 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 206 | proxyType = 2; 207 | remoteGlobalIDString = 3D3C059A1DE3340900C268FA; 208 | remoteInfo = yoga; 209 | }; 210 | 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */ = { 211 | isa = PBXContainerItemProxy; 212 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 213 | proxyType = 2; 214 | remoteGlobalIDString = 3D3C06751DE3340C00C268FA; 215 | remoteInfo = "yoga-tvOS"; 216 | }; 217 | 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */ = { 218 | isa = PBXContainerItemProxy; 219 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 220 | proxyType = 2; 221 | remoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4; 222 | remoteInfo = cxxreact; 223 | }; 224 | 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */ = { 225 | isa = PBXContainerItemProxy; 226 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 227 | proxyType = 2; 228 | remoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4; 229 | remoteInfo = "cxxreact-tvOS"; 230 | }; 231 | 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = { 232 | isa = PBXContainerItemProxy; 233 | containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; 234 | proxyType = 2; 235 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 236 | remoteInfo = RCTAnimation; 237 | }; 238 | 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = { 239 | isa = PBXContainerItemProxy; 240 | containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; 241 | proxyType = 2; 242 | remoteGlobalIDString = 2D2A28201D9B03D100D4039D; 243 | remoteInfo = "RCTAnimation-tvOS"; 244 | }; 245 | 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { 246 | isa = PBXContainerItemProxy; 247 | containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 248 | proxyType = 2; 249 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 250 | remoteInfo = RCTLinking; 251 | }; 252 | 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { 253 | isa = PBXContainerItemProxy; 254 | containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 255 | proxyType = 2; 256 | remoteGlobalIDString = 58B5119B1A9E6C1200147676; 257 | remoteInfo = RCTText; 258 | }; 259 | ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */ = { 260 | isa = PBXContainerItemProxy; 261 | containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; 262 | proxyType = 2; 263 | remoteGlobalIDString = 358F4ED71D1E81A9004DF814; 264 | remoteInfo = RCTBlob; 265 | }; 266 | F30F69B7225FCAFD005926AA /* PBXContainerItemProxy */ = { 267 | isa = PBXContainerItemProxy; 268 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 269 | proxyType = 2; 270 | remoteGlobalIDString = EDEBC6D6214B3E7000DD5AC8; 271 | remoteInfo = jsi; 272 | }; 273 | F30F69B9225FCAFD005926AA /* PBXContainerItemProxy */ = { 274 | isa = PBXContainerItemProxy; 275 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 276 | proxyType = 2; 277 | remoteGlobalIDString = EDEBC73B214B45A300DD5AC8; 278 | remoteInfo = jsiexecutor; 279 | }; 280 | F30F69BB225FCAFD005926AA /* PBXContainerItemProxy */ = { 281 | isa = PBXContainerItemProxy; 282 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 283 | proxyType = 2; 284 | remoteGlobalIDString = ED296FB6214C9A0900B7C4FE; 285 | remoteInfo = "jsi-tvOS"; 286 | }; 287 | F30F69BD225FCAFD005926AA /* PBXContainerItemProxy */ = { 288 | isa = PBXContainerItemProxy; 289 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 290 | proxyType = 2; 291 | remoteGlobalIDString = ED296FEE214C9CF800B7C4FE; 292 | remoteInfo = "jsiexecutor-tvOS"; 293 | }; 294 | F331880F227F2D0A00D25DFA /* PBXContainerItemProxy */ = { 295 | isa = PBXContainerItemProxy; 296 | containerPortal = C19B916E68BB4F9A9BF649F8 /* RNStoryShare.xcodeproj */; 297 | proxyType = 2; 298 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 299 | remoteInfo = RNStoryShare; 300 | }; 301 | F3C7F31C2286E16A005B3881 /* PBXContainerItemProxy */ = { 302 | isa = PBXContainerItemProxy; 303 | containerPortal = F3C7F2F22286E16A005B3881 /* RNViewShot.xcodeproj */; 304 | proxyType = 2; 305 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 306 | remoteInfo = RNViewShot; 307 | }; 308 | F3F6EE8D22872C9B00EB4FD9 /* PBXContainerItemProxy */ = { 309 | isa = PBXContainerItemProxy; 310 | containerPortal = F3F6EE6422872C9B00EB4FD9 /* ReactNativePermissions.xcodeproj */; 311 | proxyType = 2; 312 | remoteGlobalIDString = 9D23B34F1C767B80008B4819; 313 | remoteInfo = ReactNativePermissions; 314 | }; 315 | /* End PBXContainerItemProxy section */ 316 | 317 | /* Begin PBXFileReference section */ 318 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; 319 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; 320 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; 321 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; 322 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; 323 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; 324 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 325 | 00E356F21AD99517003FC87E /* exampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = exampleTests.m; sourceTree = ""; }; 326 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; 327 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; 328 | 13B07F961A680F5B00A75B9A /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 329 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = example/AppDelegate.h; sourceTree = ""; }; 330 | 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = example/AppDelegate.m; sourceTree = ""; }; 331 | 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 332 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = example/Images.xcassets; sourceTree = ""; }; 333 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = example/Info.plist; sourceTree = ""; }; 334 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = example/main.m; sourceTree = ""; }; 335 | 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; 336 | 2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; 337 | 4E5363563F27C912CABEBE44 /* Pods-example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-example/Pods-example.debug.xcconfig"; sourceTree = ""; }; 338 | 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; }; 339 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 340 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; 341 | ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTBlob.xcodeproj; path = "../node_modules/react-native/Libraries/Blob/RCTBlob.xcodeproj"; sourceTree = ""; }; 342 | BFECA5B9F615BCF6E26ACB8B /* Pods_example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 343 | C19B916E68BB4F9A9BF649F8 /* RNStoryShare.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNStoryShare.xcodeproj; path = "../node_modules/react-native-story-share/ios/RNStoryShare.xcodeproj"; sourceTree = ""; }; 344 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 345 | ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; 346 | EF15424E952D254812F46535 /* Pods-example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.release.xcconfig"; path = "Pods/Target Support Files/Pods-example/Pods-example.release.xcconfig"; sourceTree = ""; }; 347 | F3A52ECF227EE8B5009EE95D /* example-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "example-Bridging-Header.h"; sourceTree = ""; }; 348 | F3A52ED0227EE8B5009EE95D /* empty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = empty.swift; sourceTree = ""; }; 349 | F3C7F2F22286E16A005B3881 /* RNViewShot.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNViewShot.xcodeproj; path = "../node_modules/react-native-view-shot/ios/RNViewShot.xcodeproj"; sourceTree = ""; }; 350 | F3F6EE6422872C9B00EB4FD9 /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ReactNativePermissions.xcodeproj; path = "../node_modules/react-native-permissions/ios/ReactNativePermissions.xcodeproj"; sourceTree = ""; }; 351 | FD32FA0ED5A84EB2822BE5C3 /* libRNStoryShare.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNStoryShare.a; sourceTree = ""; }; 352 | /* End PBXFileReference section */ 353 | 354 | /* Begin PBXFrameworksBuildPhase section */ 355 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 356 | isa = PBXFrameworksBuildPhase; 357 | buildActionMask = 2147483647; 358 | files = ( 359 | ED297163215061F000B7C4FE /* JavaScriptCore.framework in Frameworks */, 360 | ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */, 361 | 11D1A2F320CAFA9E000508D9 /* libRCTAnimation.a in Frameworks */, 362 | 146834051AC3E58100842450 /* libReact.a in Frameworks */, 363 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 364 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, 365 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, 366 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, 367 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, 368 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, 369 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, 370 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, 371 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 372 | FB31D6945635E06C6EFC9194 /* Pods_example.framework in Frameworks */, 373 | A28A7FED64964DAF85E4297E /* libRNStoryShare.a in Frameworks */, 374 | F3C7F31E2286E180005B3881 /* libRNViewShot.a in Frameworks */, 375 | F3F6EE9122872CAF00EB4FD9 /* libReactNativePermissions.a in Frameworks */, 376 | ); 377 | runOnlyForDeploymentPostprocessing = 0; 378 | }; 379 | /* End PBXFrameworksBuildPhase section */ 380 | 381 | /* Begin PBXGroup section */ 382 | 00C302A81ABCB8CE00DB3ED1 /* Products */ = { 383 | isa = PBXGroup; 384 | children = ( 385 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, 386 | ); 387 | name = Products; 388 | sourceTree = ""; 389 | }; 390 | 00C302B61ABCB90400DB3ED1 /* Products */ = { 391 | isa = PBXGroup; 392 | children = ( 393 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, 394 | ); 395 | name = Products; 396 | sourceTree = ""; 397 | }; 398 | 00C302BC1ABCB91800DB3ED1 /* Products */ = { 399 | isa = PBXGroup; 400 | children = ( 401 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, 402 | 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */, 403 | ); 404 | name = Products; 405 | sourceTree = ""; 406 | }; 407 | 00C302D41ABCB9D200DB3ED1 /* Products */ = { 408 | isa = PBXGroup; 409 | children = ( 410 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, 411 | 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */, 412 | ); 413 | name = Products; 414 | sourceTree = ""; 415 | }; 416 | 00C302E01ABCB9EE00DB3ED1 /* Products */ = { 417 | isa = PBXGroup; 418 | children = ( 419 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, 420 | ); 421 | name = Products; 422 | sourceTree = ""; 423 | }; 424 | 00E356EF1AD99517003FC87E /* exampleTests */ = { 425 | isa = PBXGroup; 426 | children = ( 427 | 00E356F21AD99517003FC87E /* exampleTests.m */, 428 | 00E356F01AD99517003FC87E /* Supporting Files */, 429 | ); 430 | path = exampleTests; 431 | sourceTree = ""; 432 | }; 433 | 00E356F01AD99517003FC87E /* Supporting Files */ = { 434 | isa = PBXGroup; 435 | children = ( 436 | 00E356F11AD99517003FC87E /* Info.plist */, 437 | ); 438 | name = "Supporting Files"; 439 | sourceTree = ""; 440 | }; 441 | 039EF71D30C5B6CC7B20F540 /* Pods */ = { 442 | isa = PBXGroup; 443 | children = ( 444 | 4E5363563F27C912CABEBE44 /* Pods-example.debug.xcconfig */, 445 | EF15424E952D254812F46535 /* Pods-example.release.xcconfig */, 446 | ); 447 | name = Pods; 448 | sourceTree = ""; 449 | }; 450 | 139105B71AF99BAD00B5F7CC /* Products */ = { 451 | isa = PBXGroup; 452 | children = ( 453 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, 454 | 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */, 455 | ); 456 | name = Products; 457 | sourceTree = ""; 458 | }; 459 | 139FDEE71B06529A00C62182 /* Products */ = { 460 | isa = PBXGroup; 461 | children = ( 462 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, 463 | 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */, 464 | 2D16E6841FA4F8DC00B85C8A /* libfishhook.a */, 465 | 2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */, 466 | ); 467 | name = Products; 468 | sourceTree = ""; 469 | }; 470 | 13B07FAE1A68108700A75B9A /* example */ = { 471 | isa = PBXGroup; 472 | children = ( 473 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */, 474 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 475 | 13B07FB01A68108700A75B9A /* AppDelegate.m */, 476 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 477 | 13B07FB61A68108700A75B9A /* Info.plist */, 478 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 479 | 13B07FB71A68108700A75B9A /* main.m */, 480 | F3A52ED0227EE8B5009EE95D /* empty.swift */, 481 | F3A52ECF227EE8B5009EE95D /* example-Bridging-Header.h */, 482 | ); 483 | name = example; 484 | sourceTree = ""; 485 | }; 486 | 146834001AC3E56700842450 /* Products */ = { 487 | isa = PBXGroup; 488 | children = ( 489 | 146834041AC3E56700842450 /* libReact.a */, 490 | 3DAD3EA31DF850E9000B6D8A /* libReact.a */, 491 | 3DAD3EA51DF850E9000B6D8A /* libyoga.a */, 492 | 3DAD3EA71DF850E9000B6D8A /* libyoga.a */, 493 | 3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */, 494 | 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */, 495 | 2DF0FFDF2056DD460020B375 /* libjsinspector.a */, 496 | 2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */, 497 | 2DF0FFE32056DD460020B375 /* libthird-party.a */, 498 | 2DF0FFE52056DD460020B375 /* libthird-party.a */, 499 | 2DF0FFE72056DD460020B375 /* libdouble-conversion.a */, 500 | 2DF0FFE92056DD460020B375 /* libdouble-conversion.a */, 501 | F30F69B8225FCAFD005926AA /* libjsi.a */, 502 | F30F69BA225FCAFD005926AA /* libjsiexecutor.a */, 503 | F30F69BC225FCAFD005926AA /* libjsi-tvOS.a */, 504 | F30F69BE225FCAFD005926AA /* libjsiexecutor-tvOS.a */, 505 | ); 506 | name = Products; 507 | sourceTree = ""; 508 | }; 509 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { 510 | isa = PBXGroup; 511 | children = ( 512 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */, 513 | ED2971642150620600B7C4FE /* JavaScriptCore.framework */, 514 | 2D16E6891FA4F8E400B85C8A /* libReact.a */, 515 | BFECA5B9F615BCF6E26ACB8B /* Pods_example.framework */, 516 | ); 517 | name = Frameworks; 518 | sourceTree = ""; 519 | }; 520 | 5E91572E1DD0AC6500FF2AA8 /* Products */ = { 521 | isa = PBXGroup; 522 | children = ( 523 | 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */, 524 | 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */, 525 | ); 526 | name = Products; 527 | sourceTree = ""; 528 | }; 529 | 78C398B11ACF4ADC00677621 /* Products */ = { 530 | isa = PBXGroup; 531 | children = ( 532 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, 533 | 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */, 534 | ); 535 | name = Products; 536 | sourceTree = ""; 537 | }; 538 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 539 | isa = PBXGroup; 540 | children = ( 541 | F3F6EE6422872C9B00EB4FD9 /* ReactNativePermissions.xcodeproj */, 542 | F3C7F2F22286E16A005B3881 /* RNViewShot.xcodeproj */, 543 | 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */, 544 | 146833FF1AC3E56700842450 /* React.xcodeproj */, 545 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 546 | ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */, 547 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 548 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, 549 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 550 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, 551 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, 552 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, 553 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 554 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 555 | C19B916E68BB4F9A9BF649F8 /* RNStoryShare.xcodeproj */, 556 | ); 557 | name = Libraries; 558 | sourceTree = ""; 559 | }; 560 | 832341B11AAA6A8300B99B32 /* Products */ = { 561 | isa = PBXGroup; 562 | children = ( 563 | 832341B51AAA6A8300B99B32 /* libRCTText.a */, 564 | 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */, 565 | ); 566 | name = Products; 567 | sourceTree = ""; 568 | }; 569 | 83CBB9F61A601CBA00E9B192 = { 570 | isa = PBXGroup; 571 | children = ( 572 | 13B07FAE1A68108700A75B9A /* example */, 573 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 574 | 00E356EF1AD99517003FC87E /* exampleTests */, 575 | 83CBBA001A601CBA00E9B192 /* Products */, 576 | 2D16E6871FA4F8E400B85C8A /* Frameworks */, 577 | F30F69CB225FCEFA005926AA /* Recovered References */, 578 | 039EF71D30C5B6CC7B20F540 /* Pods */, 579 | ); 580 | indentWidth = 2; 581 | sourceTree = ""; 582 | tabWidth = 2; 583 | usesTabs = 0; 584 | }; 585 | 83CBBA001A601CBA00E9B192 /* Products */ = { 586 | isa = PBXGroup; 587 | children = ( 588 | 13B07F961A680F5B00A75B9A /* example.app */, 589 | ); 590 | name = Products; 591 | sourceTree = ""; 592 | }; 593 | ADBDB9201DFEBF0600ED6528 /* Products */ = { 594 | isa = PBXGroup; 595 | children = ( 596 | ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */, 597 | 2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */, 598 | ); 599 | name = Products; 600 | sourceTree = ""; 601 | }; 602 | F30F69CB225FCEFA005926AA /* Recovered References */ = { 603 | isa = PBXGroup; 604 | children = ( 605 | FD32FA0ED5A84EB2822BE5C3 /* libRNStoryShare.a */, 606 | ); 607 | name = "Recovered References"; 608 | sourceTree = ""; 609 | }; 610 | F331880C227F2D0A00D25DFA /* Products */ = { 611 | isa = PBXGroup; 612 | children = ( 613 | F3318810227F2D0A00D25DFA /* libRNStoryShare.a */, 614 | ); 615 | name = Products; 616 | sourceTree = ""; 617 | }; 618 | F3C7F2F32286E16A005B3881 /* Products */ = { 619 | isa = PBXGroup; 620 | children = ( 621 | F3C7F31D2286E16A005B3881 /* libRNViewShot.a */, 622 | ); 623 | name = Products; 624 | sourceTree = ""; 625 | }; 626 | F3F6EE6522872C9B00EB4FD9 /* Products */ = { 627 | isa = PBXGroup; 628 | children = ( 629 | F3F6EE8E22872C9B00EB4FD9 /* libReactNativePermissions.a */, 630 | ); 631 | name = Products; 632 | sourceTree = ""; 633 | }; 634 | /* End PBXGroup section */ 635 | 636 | /* Begin PBXNativeTarget section */ 637 | 13B07F861A680F5B00A75B9A /* example */ = { 638 | isa = PBXNativeTarget; 639 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */; 640 | buildPhases = ( 641 | 847281F9B99D2ECACA838396 /* [CP] Check Pods Manifest.lock */, 642 | 13B07F871A680F5B00A75B9A /* Sources */, 643 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 644 | 13B07F8E1A680F5B00A75B9A /* Resources */, 645 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 646 | E4103B4AB33B31270BBC5339 /* [CP] Embed Pods Frameworks */, 647 | ); 648 | buildRules = ( 649 | ); 650 | dependencies = ( 651 | ); 652 | name = example; 653 | productName = "Hello World"; 654 | productReference = 13B07F961A680F5B00A75B9A /* example.app */; 655 | productType = "com.apple.product-type.application"; 656 | }; 657 | /* End PBXNativeTarget section */ 658 | 659 | /* Begin PBXProject section */ 660 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 661 | isa = PBXProject; 662 | attributes = { 663 | LastUpgradeCheck = 940; 664 | ORGANIZATIONNAME = Facebook; 665 | TargetAttributes = { 666 | 13B07F861A680F5B00A75B9A = { 667 | LastSwiftMigration = 1020; 668 | }; 669 | }; 670 | }; 671 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "example" */; 672 | compatibilityVersion = "Xcode 3.2"; 673 | developmentRegion = English; 674 | hasScannedForEncodings = 0; 675 | knownRegions = ( 676 | English, 677 | en, 678 | Base, 679 | ); 680 | mainGroup = 83CBB9F61A601CBA00E9B192; 681 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 682 | projectDirPath = ""; 683 | projectReferences = ( 684 | { 685 | ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; 686 | ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 687 | }, 688 | { 689 | ProductGroup = 5E91572E1DD0AC6500FF2AA8 /* Products */; 690 | ProjectRef = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; 691 | }, 692 | { 693 | ProductGroup = ADBDB9201DFEBF0600ED6528 /* Products */; 694 | ProjectRef = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; 695 | }, 696 | { 697 | ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; 698 | ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 699 | }, 700 | { 701 | ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; 702 | ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 703 | }, 704 | { 705 | ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; 706 | ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 707 | }, 708 | { 709 | ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; 710 | ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 711 | }, 712 | { 713 | ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; 714 | ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 715 | }, 716 | { 717 | ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; 718 | ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 719 | }, 720 | { 721 | ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; 722 | ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 723 | }, 724 | { 725 | ProductGroup = 139FDEE71B06529A00C62182 /* Products */; 726 | ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 727 | }, 728 | { 729 | ProductGroup = 146834001AC3E56700842450 /* Products */; 730 | ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; 731 | }, 732 | { 733 | ProductGroup = F3F6EE6522872C9B00EB4FD9 /* Products */; 734 | ProjectRef = F3F6EE6422872C9B00EB4FD9 /* ReactNativePermissions.xcodeproj */; 735 | }, 736 | { 737 | ProductGroup = F331880C227F2D0A00D25DFA /* Products */; 738 | ProjectRef = C19B916E68BB4F9A9BF649F8 /* RNStoryShare.xcodeproj */; 739 | }, 740 | { 741 | ProductGroup = F3C7F2F32286E16A005B3881 /* Products */; 742 | ProjectRef = F3C7F2F22286E16A005B3881 /* RNViewShot.xcodeproj */; 743 | }, 744 | ); 745 | projectRoot = ""; 746 | targets = ( 747 | 13B07F861A680F5B00A75B9A /* example */, 748 | ); 749 | }; 750 | /* End PBXProject section */ 751 | 752 | /* Begin PBXReferenceProxy section */ 753 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { 754 | isa = PBXReferenceProxy; 755 | fileType = archive.ar; 756 | path = libRCTActionSheet.a; 757 | remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; 758 | sourceTree = BUILT_PRODUCTS_DIR; 759 | }; 760 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { 761 | isa = PBXReferenceProxy; 762 | fileType = archive.ar; 763 | path = libRCTGeolocation.a; 764 | remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; 765 | sourceTree = BUILT_PRODUCTS_DIR; 766 | }; 767 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { 768 | isa = PBXReferenceProxy; 769 | fileType = archive.ar; 770 | path = libRCTImage.a; 771 | remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; 772 | sourceTree = BUILT_PRODUCTS_DIR; 773 | }; 774 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { 775 | isa = PBXReferenceProxy; 776 | fileType = archive.ar; 777 | path = libRCTNetwork.a; 778 | remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; 779 | sourceTree = BUILT_PRODUCTS_DIR; 780 | }; 781 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { 782 | isa = PBXReferenceProxy; 783 | fileType = archive.ar; 784 | path = libRCTVibration.a; 785 | remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; 786 | sourceTree = BUILT_PRODUCTS_DIR; 787 | }; 788 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { 789 | isa = PBXReferenceProxy; 790 | fileType = archive.ar; 791 | path = libRCTSettings.a; 792 | remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; 793 | sourceTree = BUILT_PRODUCTS_DIR; 794 | }; 795 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = { 796 | isa = PBXReferenceProxy; 797 | fileType = archive.ar; 798 | path = libRCTWebSocket.a; 799 | remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */; 800 | sourceTree = BUILT_PRODUCTS_DIR; 801 | }; 802 | 146834041AC3E56700842450 /* libReact.a */ = { 803 | isa = PBXReferenceProxy; 804 | fileType = archive.ar; 805 | path = libReact.a; 806 | remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; 807 | sourceTree = BUILT_PRODUCTS_DIR; 808 | }; 809 | 2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */ = { 810 | isa = PBXReferenceProxy; 811 | fileType = archive.ar; 812 | path = "libRCTBlob-tvOS.a"; 813 | remoteRef = 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */; 814 | sourceTree = BUILT_PRODUCTS_DIR; 815 | }; 816 | 2D16E6841FA4F8DC00B85C8A /* libfishhook.a */ = { 817 | isa = PBXReferenceProxy; 818 | fileType = archive.ar; 819 | path = libfishhook.a; 820 | remoteRef = 2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */; 821 | sourceTree = BUILT_PRODUCTS_DIR; 822 | }; 823 | 2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */ = { 824 | isa = PBXReferenceProxy; 825 | fileType = archive.ar; 826 | path = "libfishhook-tvOS.a"; 827 | remoteRef = 2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */; 828 | sourceTree = BUILT_PRODUCTS_DIR; 829 | }; 830 | 2DF0FFDF2056DD460020B375 /* libjsinspector.a */ = { 831 | isa = PBXReferenceProxy; 832 | fileType = archive.ar; 833 | path = libjsinspector.a; 834 | remoteRef = 2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */; 835 | sourceTree = BUILT_PRODUCTS_DIR; 836 | }; 837 | 2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */ = { 838 | isa = PBXReferenceProxy; 839 | fileType = archive.ar; 840 | path = "libjsinspector-tvOS.a"; 841 | remoteRef = 2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */; 842 | sourceTree = BUILT_PRODUCTS_DIR; 843 | }; 844 | 2DF0FFE32056DD460020B375 /* libthird-party.a */ = { 845 | isa = PBXReferenceProxy; 846 | fileType = archive.ar; 847 | path = "libthird-party.a"; 848 | remoteRef = 2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */; 849 | sourceTree = BUILT_PRODUCTS_DIR; 850 | }; 851 | 2DF0FFE52056DD460020B375 /* libthird-party.a */ = { 852 | isa = PBXReferenceProxy; 853 | fileType = archive.ar; 854 | path = "libthird-party.a"; 855 | remoteRef = 2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */; 856 | sourceTree = BUILT_PRODUCTS_DIR; 857 | }; 858 | 2DF0FFE72056DD460020B375 /* libdouble-conversion.a */ = { 859 | isa = PBXReferenceProxy; 860 | fileType = archive.ar; 861 | path = "libdouble-conversion.a"; 862 | remoteRef = 2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */; 863 | sourceTree = BUILT_PRODUCTS_DIR; 864 | }; 865 | 2DF0FFE92056DD460020B375 /* libdouble-conversion.a */ = { 866 | isa = PBXReferenceProxy; 867 | fileType = archive.ar; 868 | path = "libdouble-conversion.a"; 869 | remoteRef = 2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */; 870 | sourceTree = BUILT_PRODUCTS_DIR; 871 | }; 872 | 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = { 873 | isa = PBXReferenceProxy; 874 | fileType = archive.ar; 875 | path = "libRCTImage-tvOS.a"; 876 | remoteRef = 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */; 877 | sourceTree = BUILT_PRODUCTS_DIR; 878 | }; 879 | 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */ = { 880 | isa = PBXReferenceProxy; 881 | fileType = archive.ar; 882 | path = "libRCTLinking-tvOS.a"; 883 | remoteRef = 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */; 884 | sourceTree = BUILT_PRODUCTS_DIR; 885 | }; 886 | 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */ = { 887 | isa = PBXReferenceProxy; 888 | fileType = archive.ar; 889 | path = "libRCTNetwork-tvOS.a"; 890 | remoteRef = 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */; 891 | sourceTree = BUILT_PRODUCTS_DIR; 892 | }; 893 | 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */ = { 894 | isa = PBXReferenceProxy; 895 | fileType = archive.ar; 896 | path = "libRCTSettings-tvOS.a"; 897 | remoteRef = 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */; 898 | sourceTree = BUILT_PRODUCTS_DIR; 899 | }; 900 | 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */ = { 901 | isa = PBXReferenceProxy; 902 | fileType = archive.ar; 903 | path = "libRCTText-tvOS.a"; 904 | remoteRef = 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */; 905 | sourceTree = BUILT_PRODUCTS_DIR; 906 | }; 907 | 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */ = { 908 | isa = PBXReferenceProxy; 909 | fileType = archive.ar; 910 | path = "libRCTWebSocket-tvOS.a"; 911 | remoteRef = 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */; 912 | sourceTree = BUILT_PRODUCTS_DIR; 913 | }; 914 | 3DAD3EA31DF850E9000B6D8A /* libReact.a */ = { 915 | isa = PBXReferenceProxy; 916 | fileType = archive.ar; 917 | path = libReact.a; 918 | remoteRef = 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */; 919 | sourceTree = BUILT_PRODUCTS_DIR; 920 | }; 921 | 3DAD3EA51DF850E9000B6D8A /* libyoga.a */ = { 922 | isa = PBXReferenceProxy; 923 | fileType = archive.ar; 924 | path = libyoga.a; 925 | remoteRef = 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */; 926 | sourceTree = BUILT_PRODUCTS_DIR; 927 | }; 928 | 3DAD3EA71DF850E9000B6D8A /* libyoga.a */ = { 929 | isa = PBXReferenceProxy; 930 | fileType = archive.ar; 931 | path = libyoga.a; 932 | remoteRef = 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */; 933 | sourceTree = BUILT_PRODUCTS_DIR; 934 | }; 935 | 3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */ = { 936 | isa = PBXReferenceProxy; 937 | fileType = archive.ar; 938 | path = libcxxreact.a; 939 | remoteRef = 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */; 940 | sourceTree = BUILT_PRODUCTS_DIR; 941 | }; 942 | 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */ = { 943 | isa = PBXReferenceProxy; 944 | fileType = archive.ar; 945 | path = libcxxreact.a; 946 | remoteRef = 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */; 947 | sourceTree = BUILT_PRODUCTS_DIR; 948 | }; 949 | 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = { 950 | isa = PBXReferenceProxy; 951 | fileType = archive.ar; 952 | path = libRCTAnimation.a; 953 | remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */; 954 | sourceTree = BUILT_PRODUCTS_DIR; 955 | }; 956 | 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */ = { 957 | isa = PBXReferenceProxy; 958 | fileType = archive.ar; 959 | path = libRCTAnimation.a; 960 | remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */; 961 | sourceTree = BUILT_PRODUCTS_DIR; 962 | }; 963 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { 964 | isa = PBXReferenceProxy; 965 | fileType = archive.ar; 966 | path = libRCTLinking.a; 967 | remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; 968 | sourceTree = BUILT_PRODUCTS_DIR; 969 | }; 970 | 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { 971 | isa = PBXReferenceProxy; 972 | fileType = archive.ar; 973 | path = libRCTText.a; 974 | remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; 975 | sourceTree = BUILT_PRODUCTS_DIR; 976 | }; 977 | ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */ = { 978 | isa = PBXReferenceProxy; 979 | fileType = archive.ar; 980 | path = libRCTBlob.a; 981 | remoteRef = ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */; 982 | sourceTree = BUILT_PRODUCTS_DIR; 983 | }; 984 | F30F69B8225FCAFD005926AA /* libjsi.a */ = { 985 | isa = PBXReferenceProxy; 986 | fileType = archive.ar; 987 | path = libjsi.a; 988 | remoteRef = F30F69B7225FCAFD005926AA /* PBXContainerItemProxy */; 989 | sourceTree = BUILT_PRODUCTS_DIR; 990 | }; 991 | F30F69BA225FCAFD005926AA /* libjsiexecutor.a */ = { 992 | isa = PBXReferenceProxy; 993 | fileType = archive.ar; 994 | path = libjsiexecutor.a; 995 | remoteRef = F30F69B9225FCAFD005926AA /* PBXContainerItemProxy */; 996 | sourceTree = BUILT_PRODUCTS_DIR; 997 | }; 998 | F30F69BC225FCAFD005926AA /* libjsi-tvOS.a */ = { 999 | isa = PBXReferenceProxy; 1000 | fileType = archive.ar; 1001 | path = "libjsi-tvOS.a"; 1002 | remoteRef = F30F69BB225FCAFD005926AA /* PBXContainerItemProxy */; 1003 | sourceTree = BUILT_PRODUCTS_DIR; 1004 | }; 1005 | F30F69BE225FCAFD005926AA /* libjsiexecutor-tvOS.a */ = { 1006 | isa = PBXReferenceProxy; 1007 | fileType = archive.ar; 1008 | path = "libjsiexecutor-tvOS.a"; 1009 | remoteRef = F30F69BD225FCAFD005926AA /* PBXContainerItemProxy */; 1010 | sourceTree = BUILT_PRODUCTS_DIR; 1011 | }; 1012 | F3318810227F2D0A00D25DFA /* libRNStoryShare.a */ = { 1013 | isa = PBXReferenceProxy; 1014 | fileType = archive.ar; 1015 | path = libRNStoryShare.a; 1016 | remoteRef = F331880F227F2D0A00D25DFA /* PBXContainerItemProxy */; 1017 | sourceTree = BUILT_PRODUCTS_DIR; 1018 | }; 1019 | F3C7F31D2286E16A005B3881 /* libRNViewShot.a */ = { 1020 | isa = PBXReferenceProxy; 1021 | fileType = archive.ar; 1022 | path = libRNViewShot.a; 1023 | remoteRef = F3C7F31C2286E16A005B3881 /* PBXContainerItemProxy */; 1024 | sourceTree = BUILT_PRODUCTS_DIR; 1025 | }; 1026 | F3F6EE8E22872C9B00EB4FD9 /* libReactNativePermissions.a */ = { 1027 | isa = PBXReferenceProxy; 1028 | fileType = archive.ar; 1029 | path = libReactNativePermissions.a; 1030 | remoteRef = F3F6EE8D22872C9B00EB4FD9 /* PBXContainerItemProxy */; 1031 | sourceTree = BUILT_PRODUCTS_DIR; 1032 | }; 1033 | /* End PBXReferenceProxy section */ 1034 | 1035 | /* Begin PBXResourcesBuildPhase section */ 1036 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 1037 | isa = PBXResourcesBuildPhase; 1038 | buildActionMask = 2147483647; 1039 | files = ( 1040 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 1041 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 1042 | ); 1043 | runOnlyForDeploymentPostprocessing = 0; 1044 | }; 1045 | /* End PBXResourcesBuildPhase section */ 1046 | 1047 | /* Begin PBXShellScriptBuildPhase section */ 1048 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 1049 | isa = PBXShellScriptBuildPhase; 1050 | buildActionMask = 2147483647; 1051 | files = ( 1052 | ); 1053 | inputPaths = ( 1054 | ); 1055 | name = "Bundle React Native code and images"; 1056 | outputPaths = ( 1057 | ); 1058 | runOnlyForDeploymentPostprocessing = 0; 1059 | shellPath = /bin/sh; 1060 | shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; 1061 | }; 1062 | 847281F9B99D2ECACA838396 /* [CP] Check Pods Manifest.lock */ = { 1063 | isa = PBXShellScriptBuildPhase; 1064 | buildActionMask = 2147483647; 1065 | files = ( 1066 | ); 1067 | inputFileListPaths = ( 1068 | ); 1069 | inputPaths = ( 1070 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 1071 | "${PODS_ROOT}/Manifest.lock", 1072 | ); 1073 | name = "[CP] Check Pods Manifest.lock"; 1074 | outputFileListPaths = ( 1075 | ); 1076 | outputPaths = ( 1077 | "$(DERIVED_FILE_DIR)/Pods-example-checkManifestLockResult.txt", 1078 | ); 1079 | runOnlyForDeploymentPostprocessing = 0; 1080 | shellPath = /bin/sh; 1081 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 1082 | showEnvVarsInLog = 0; 1083 | }; 1084 | E4103B4AB33B31270BBC5339 /* [CP] Embed Pods Frameworks */ = { 1085 | isa = PBXShellScriptBuildPhase; 1086 | buildActionMask = 2147483647; 1087 | files = ( 1088 | ); 1089 | inputFileListPaths = ( 1090 | ); 1091 | inputPaths = ( 1092 | "${SRCROOT}/Pods/Target Support Files/Pods-example/Pods-example-frameworks.sh", 1093 | "${PODS_ROOT}/SnapSDK/SCSDKCreativeKit.framework", 1094 | "${PODS_ROOT}/SnapSDK/SCSDKCoreKit.framework", 1095 | ); 1096 | name = "[CP] Embed Pods Frameworks"; 1097 | outputFileListPaths = ( 1098 | ); 1099 | outputPaths = ( 1100 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SCSDKCreativeKit.framework", 1101 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SCSDKCoreKit.framework", 1102 | ); 1103 | runOnlyForDeploymentPostprocessing = 0; 1104 | shellPath = /bin/sh; 1105 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-example/Pods-example-frameworks.sh\"\n"; 1106 | showEnvVarsInLog = 0; 1107 | }; 1108 | /* End PBXShellScriptBuildPhase section */ 1109 | 1110 | /* Begin PBXSourcesBuildPhase section */ 1111 | 13B07F871A680F5B00A75B9A /* Sources */ = { 1112 | isa = PBXSourcesBuildPhase; 1113 | buildActionMask = 2147483647; 1114 | files = ( 1115 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, 1116 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 1117 | F3A52ED1227EE8B5009EE95D /* empty.swift in Sources */, 1118 | ); 1119 | runOnlyForDeploymentPostprocessing = 0; 1120 | }; 1121 | /* End PBXSourcesBuildPhase section */ 1122 | 1123 | /* Begin PBXVariantGroup section */ 1124 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { 1125 | isa = PBXVariantGroup; 1126 | children = ( 1127 | 13B07FB21A68108700A75B9A /* Base */, 1128 | ); 1129 | name = LaunchScreen.xib; 1130 | path = example; 1131 | sourceTree = ""; 1132 | }; 1133 | /* End PBXVariantGroup section */ 1134 | 1135 | /* Begin XCBuildConfiguration section */ 1136 | 13B07F941A680F5B00A75B9A /* Debug */ = { 1137 | isa = XCBuildConfiguration; 1138 | baseConfigurationReference = 4E5363563F27C912CABEBE44 /* Pods-example.debug.xcconfig */; 1139 | buildSettings = { 1140 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1141 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1142 | CLANG_ENABLE_MODULES = YES; 1143 | CURRENT_PROJECT_VERSION = 1; 1144 | DEAD_CODE_STRIPPING = NO; 1145 | DEVELOPMENT_TEAM = ""; 1146 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 1147 | HEADER_SEARCH_PATHS = ( 1148 | "$(inherited)", 1149 | "$(SRCROOT)/../node_modules/react-native-story-share/ios", 1150 | "$(SRCROOT)/../node_modules/react-native-story-view-shot/ios", 1151 | ); 1152 | INFOPLIST_FILE = example/Info.plist; 1153 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1154 | LIBRARY_SEARCH_PATHS = ( 1155 | "$(inherited)", 1156 | "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", 1157 | "\"$(SRCROOT)/example\"", 1158 | ); 1159 | OTHER_LDFLAGS = ( 1160 | "$(inherited)", 1161 | "-ObjC", 1162 | "-lc++", 1163 | ); 1164 | PRODUCT_BUNDLE_IDENTIFIER = com.jobeso.rnstoryshareexample; 1165 | PRODUCT_NAME = example; 1166 | SWIFT_OBJC_BRIDGING_HEADER = "example-Bridging-Header.h"; 1167 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1168 | SWIFT_VERSION = 5.0; 1169 | VERSIONING_SYSTEM = "apple-generic"; 1170 | }; 1171 | name = Debug; 1172 | }; 1173 | 13B07F951A680F5B00A75B9A /* Release */ = { 1174 | isa = XCBuildConfiguration; 1175 | baseConfigurationReference = EF15424E952D254812F46535 /* Pods-example.release.xcconfig */; 1176 | buildSettings = { 1177 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1178 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1179 | CLANG_ENABLE_MODULES = YES; 1180 | CURRENT_PROJECT_VERSION = 1; 1181 | DEVELOPMENT_TEAM = ""; 1182 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 1183 | HEADER_SEARCH_PATHS = ( 1184 | "$(inherited)", 1185 | "$(SRCROOT)/../node_modules/react-native-story-share/ios", 1186 | "$(SRCROOT)/../node_modules/react-native-story-view-shot/ios", 1187 | ); 1188 | INFOPLIST_FILE = example/Info.plist; 1189 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1190 | LIBRARY_SEARCH_PATHS = ( 1191 | "$(inherited)", 1192 | "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", 1193 | "\"$(SRCROOT)/example\"", 1194 | ); 1195 | OTHER_LDFLAGS = ( 1196 | "$(inherited)", 1197 | "-ObjC", 1198 | "-lc++", 1199 | ); 1200 | PRODUCT_BUNDLE_IDENTIFIER = com.jobeso.rnstoryshareexample; 1201 | PRODUCT_NAME = example; 1202 | SWIFT_OBJC_BRIDGING_HEADER = "example-Bridging-Header.h"; 1203 | SWIFT_VERSION = 5.0; 1204 | VERSIONING_SYSTEM = "apple-generic"; 1205 | }; 1206 | name = Release; 1207 | }; 1208 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 1209 | isa = XCBuildConfiguration; 1210 | buildSettings = { 1211 | ALWAYS_SEARCH_USER_PATHS = NO; 1212 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1213 | CLANG_CXX_LIBRARY = "libc++"; 1214 | CLANG_ENABLE_MODULES = YES; 1215 | CLANG_ENABLE_OBJC_ARC = YES; 1216 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1217 | CLANG_WARN_BOOL_CONVERSION = YES; 1218 | CLANG_WARN_COMMA = YES; 1219 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1220 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 1221 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1222 | CLANG_WARN_EMPTY_BODY = YES; 1223 | CLANG_WARN_ENUM_CONVERSION = YES; 1224 | CLANG_WARN_INFINITE_RECURSION = YES; 1225 | CLANG_WARN_INT_CONVERSION = YES; 1226 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1227 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 1228 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1229 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1230 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1231 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1232 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1233 | CLANG_WARN_UNREACHABLE_CODE = YES; 1234 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1235 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 1236 | COPY_PHASE_STRIP = NO; 1237 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1238 | ENABLE_TESTABILITY = YES; 1239 | GCC_C_LANGUAGE_STANDARD = gnu99; 1240 | GCC_DYNAMIC_NO_PIC = NO; 1241 | GCC_NO_COMMON_BLOCKS = YES; 1242 | GCC_OPTIMIZATION_LEVEL = 0; 1243 | GCC_PREPROCESSOR_DEFINITIONS = ( 1244 | "DEBUG=1", 1245 | "$(inherited)", 1246 | ); 1247 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 1248 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1249 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1250 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1251 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1252 | GCC_WARN_UNUSED_FUNCTION = YES; 1253 | GCC_WARN_UNUSED_VARIABLE = YES; 1254 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 1255 | MTL_ENABLE_DEBUG_INFO = YES; 1256 | ONLY_ACTIVE_ARCH = YES; 1257 | SDKROOT = iphoneos; 1258 | }; 1259 | name = Debug; 1260 | }; 1261 | 83CBBA211A601CBA00E9B192 /* Release */ = { 1262 | isa = XCBuildConfiguration; 1263 | buildSettings = { 1264 | ALWAYS_SEARCH_USER_PATHS = NO; 1265 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 1266 | CLANG_CXX_LIBRARY = "libc++"; 1267 | CLANG_ENABLE_MODULES = YES; 1268 | CLANG_ENABLE_OBJC_ARC = YES; 1269 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1270 | CLANG_WARN_BOOL_CONVERSION = YES; 1271 | CLANG_WARN_COMMA = YES; 1272 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1273 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 1274 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1275 | CLANG_WARN_EMPTY_BODY = YES; 1276 | CLANG_WARN_ENUM_CONVERSION = YES; 1277 | CLANG_WARN_INFINITE_RECURSION = YES; 1278 | CLANG_WARN_INT_CONVERSION = YES; 1279 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1280 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 1281 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1282 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1283 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1284 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1285 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1286 | CLANG_WARN_UNREACHABLE_CODE = YES; 1287 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1288 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 1289 | COPY_PHASE_STRIP = YES; 1290 | ENABLE_NS_ASSERTIONS = NO; 1291 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1292 | GCC_C_LANGUAGE_STANDARD = gnu99; 1293 | GCC_NO_COMMON_BLOCKS = YES; 1294 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1295 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1296 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1297 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1298 | GCC_WARN_UNUSED_FUNCTION = YES; 1299 | GCC_WARN_UNUSED_VARIABLE = YES; 1300 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 1301 | MTL_ENABLE_DEBUG_INFO = NO; 1302 | SDKROOT = iphoneos; 1303 | VALIDATE_PRODUCT = YES; 1304 | }; 1305 | name = Release; 1306 | }; 1307 | /* End XCBuildConfiguration section */ 1308 | 1309 | /* Begin XCConfigurationList section */ 1310 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */ = { 1311 | isa = XCConfigurationList; 1312 | buildConfigurations = ( 1313 | 13B07F941A680F5B00A75B9A /* Debug */, 1314 | 13B07F951A680F5B00A75B9A /* Release */, 1315 | ); 1316 | defaultConfigurationIsVisible = 0; 1317 | defaultConfigurationName = Release; 1318 | }; 1319 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "example" */ = { 1320 | isa = XCConfigurationList; 1321 | buildConfigurations = ( 1322 | 83CBBA201A601CBA00E9B192 /* Debug */, 1323 | 83CBBA211A601CBA00E9B192 /* Release */, 1324 | ); 1325 | defaultConfigurationIsVisible = 0; 1326 | defaultConfigurationName = Release; 1327 | }; 1328 | /* End XCConfigurationList section */ 1329 | }; 1330 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 1331 | } 1332 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/xcshareddata/xcschemes/example-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (nonatomic, strong) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "AppDelegate.h" 9 | 10 | #import 11 | #import 12 | #import 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 19 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 20 | moduleName:@"example" 21 | initialProperties:nil]; 22 | 23 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 24 | 25 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 26 | UIViewController *rootViewController = [UIViewController new]; 27 | rootViewController.view = rootView; 28 | self.window.rootViewController = rootViewController; 29 | [self.window makeKeyAndVisible]; 30 | return YES; 31 | } 32 | 33 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 34 | { 35 | #if DEBUG 36 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 37 | #else 38 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 39 | #endif 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /example/ios/example/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | RNStoryShareExample 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSApplicationQueriesSchemes 26 | 27 | instagram-stories 28 | snapchat 29 | 30 | LSRequiresIPhoneOS 31 | 32 | NSAppTransportSecurity 33 | 34 | NSAllowsArbitraryLoads 35 | 36 | NSExceptionDomains 37 | 38 | localhost 39 | 40 | NSExceptionAllowsInsecureHTTPLoads 41 | 42 | 43 | 44 | 45 | NSLocationWhenInUseUsageDescription 46 | 47 | UILaunchStoryboardName 48 | LaunchScreen 49 | UIRequiredDeviceCapabilities 50 | 51 | armv7 52 | 53 | UISupportedInterfaceOrientations 54 | 55 | UIInterfaceOrientationPortrait 56 | UIInterfaceOrientationLandscapeLeft 57 | UIInterfaceOrientationLandscapeRight 58 | 59 | UIViewControllerBasedStatusBarAppearance 60 | 61 | SCSDKClientId 62 | 01f13186-6b89-4261-a238-a1c3caa625f3 63 | 64 | 65 | -------------------------------------------------------------------------------- /example/ios/example/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /example/ios/exampleTests/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/exampleTests/exampleTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | #import 12 | #import 13 | 14 | #define TIMEOUT_SECONDS 600 15 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 16 | 17 | @interface exampleTests : XCTestCase 18 | 19 | @end 20 | 21 | @implementation exampleTests 22 | 23 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 24 | { 25 | if (test(view)) { 26 | return YES; 27 | } 28 | for (UIView *subview in [view subviews]) { 29 | if ([self findSubviewInView:subview matching:test]) { 30 | return YES; 31 | } 32 | } 33 | return NO; 34 | } 35 | 36 | - (void)testRendersWelcomeScreen 37 | { 38 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 39 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 40 | BOOL foundElement = NO; 41 | 42 | __block NSString *redboxError = nil; 43 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 44 | if (level >= RCTLogLevelError) { 45 | redboxError = message; 46 | } 47 | }); 48 | 49 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 50 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 51 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 52 | 53 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 54 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 55 | return YES; 56 | } 57 | return NO; 58 | }]; 59 | } 60 | 61 | RCTSetLogFunction(RCTDefaultLogFunction); 62 | 63 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 64 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 65 | } 66 | 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: false, 14 | }, 15 | }), 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "postinstall": "rm -rf node_modules/react-native-story-share/example", 7 | "run:android": "react-native run-android", 8 | "run:packager": "node node_modules/react-native/local-cli/cli.js start", 9 | "start": "node node_modules/react-native/local-cli/cli.js start", 10 | "test": "jest" 11 | }, 12 | "dependencies": { 13 | "ramda": "^0.26.1", 14 | "react": "16.8.3", 15 | "react-native": "0.59.4", 16 | "react-native-permissions": "^1.1.1", 17 | "react-native-story-share": "file:..", 18 | "react-native-view-shot": "^2.6.0" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.4.3", 22 | "@babel/runtime": "^7.4.3", 23 | "babel-jest": "^24.7.1", 24 | "jest": "^24.7.1", 25 | "metro-react-native-babel-preset": "^0.53.1", 26 | "react-test-renderer": "16.8.3" 27 | }, 28 | "jest": { 29 | "preset": "react-native" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { NativeModules } from 'react-native' 2 | 3 | const { RNStoryShare } = NativeModules 4 | 5 | export default RNStoryShare 6 | -------------------------------------------------------------------------------- /ios/RNStoryShare-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 | 5 | #import 6 | #import "RCTConvert.h" 7 | -------------------------------------------------------------------------------- /ios/RNStoryShare.m: -------------------------------------------------------------------------------- 1 | 2 | #import "React/RCTBridgeModule.h" 3 | 4 | @interface RCT_EXTERN_MODULE(RNStoryShare, NSObject) 5 | 6 | - (dispatch_queue_t)methodQueue 7 | { 8 | return dispatch_get_main_queue(); 9 | } 10 | 11 | + (BOOL)requiresMainQueueSetup 12 | { 13 | return YES; 14 | } 15 | 16 | RCT_EXTERN_METHOD(shareToInstagram:(NSDictionary *)config 17 | resolver: (RCTPromiseResolveBlock)resolve 18 | rejecter: (RCTPromiseRejectBlock)reject) 19 | 20 | RCT_EXTERN_METHOD(shareToSnapchat:(NSDictionary *)config 21 | resolver: (RCTPromiseResolveBlock)resolve 22 | rejecter: (RCTPromiseRejectBlock)reject) 23 | 24 | RCT_EXTERN_METHOD(isInstagramAvailable: (RCTPromiseResolveBlock)resolve 25 | rejecter: (RCTPromiseRejectBlock)reject) 26 | 27 | RCT_EXTERN_METHOD(isSnapchatAvailable: (RCTPromiseResolveBlock)resolve 28 | rejecter: (RCTPromiseRejectBlock)reject) 29 | 30 | @end 31 | 32 | -------------------------------------------------------------------------------- /ios/RNStoryShare.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | s.name = "RNStoryShare" 4 | s.version = "1.0.0" 5 | s.summary = "RNStoryShare" 6 | s.description = "Share your images to instagram stories." 7 | s.homepage = "https://github.com/Jobeso/react-native-story-share" 8 | s.license = "MIT" 9 | s.author = { "author" => "author@domain.cn" } 10 | s.platform = :ios, "7.0" 11 | s.source = { :git => "https://github.com/author/RNStoryShare.git", :tag => "master" } 12 | s.source_files = "*.{h,m,swift}" 13 | s.requires_arc = true 14 | 15 | 16 | s.dependency "React" 17 | s.dependency "SnapSDK/SCSDKCreativeKit" 18 | 19 | end 20 | -------------------------------------------------------------------------------- /ios/RNStoryShare.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RNStoryShare.swift 3 | // RNStoryShare 4 | // 5 | // Created by Johannes Sorg on 21.11.18. 6 | // Copyright © 2018 Facebook. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import SCSDKCreativeKit 12 | 13 | @objc(RNStoryShare) 14 | class RNStoryShare: NSObject{ 15 | let domain: String = "RNStoryShare" 16 | let FILE: String = "file" 17 | let BASE64: String = "base64" 18 | 19 | let UNKNOWN_ERROR: String = "An unknown error occured in RNStoryShare" 20 | 21 | let instagramScheme = URL(string: "instagram-stories://share") 22 | let snapchatScheme = URL(string: "snapchat://") 23 | 24 | @objc 25 | func constantsToExport() -> [String: Any]! { 26 | return [ 27 | "FILE": FILE, 28 | "BASE64": BASE64 29 | ] 30 | } 31 | 32 | @objc 33 | func isInstagramAvailable(_ resolve: RCTPromiseResolveBlock, 34 | rejecter reject: RCTPromiseRejectBlock) -> Void { 35 | resolve(UIApplication.shared.canOpenURL(instagramScheme!)) 36 | } 37 | 38 | @objc 39 | func isSnapchatAvailable(_ resolve: RCTPromiseResolveBlock, 40 | rejecter reject: RCTPromiseRejectBlock) -> Void { 41 | resolve(UIApplication.shared.canOpenURL(snapchatScheme!)) 42 | } 43 | 44 | func _shareToInstagram(_ backgroundData: NSData? = nil, 45 | stickerData: NSData? = nil, 46 | attributionLink: String, 47 | backgroundBottomColor: String, 48 | backgroundTopColor: String, 49 | resolve: RCTPromiseResolveBlock, 50 | reject: RCTPromiseRejectBlock){ 51 | do{ 52 | if(UIApplication.shared.canOpenURL(instagramScheme!)){ 53 | 54 | var pasteboardItems: Dictionary = [:] 55 | 56 | if(backgroundData != nil){ 57 | pasteboardItems["com.instagram.sharedSticker.backgroundImage"] = backgroundData! 58 | } 59 | 60 | if(stickerData != nil){ 61 | pasteboardItems["com.instagram.sharedSticker.stickerImage"] = stickerData! 62 | pasteboardItems["com.instagram.sharedSticker.backgroundTopColor"] = backgroundTopColor 63 | pasteboardItems["com.instagram.sharedSticker.backgroundBottomColor"] = backgroundBottomColor 64 | } 65 | 66 | pasteboardItems["com.instagram.sharedSticker.contentURL"] = attributionLink 67 | 68 | UIPasteboard.general.items = [pasteboardItems] 69 | UIApplication.shared.openURL(instagramScheme!) 70 | resolve("ok") 71 | 72 | } else { 73 | throw NSError(domain: domain, code: 400, userInfo: nil) 74 | } 75 | }catch { 76 | reject(domain, error.localizedDescription, error) 77 | } 78 | } 79 | 80 | 81 | @objc 82 | func shareToInstagram(_ config: NSDictionary, 83 | resolver resolve: RCTPromiseResolveBlock, 84 | rejecter reject: RCTPromiseRejectBlock) -> Void { 85 | 86 | do { 87 | if (config["backgroundAsset"] == nil && config["stickerAsset"] == nil){ 88 | let error = NSError(domain: domain, code: 400, userInfo: ["Error": "Background Asset and Sticker Asset are nil"]) 89 | return reject("No Assets", "Background Asset and Sticker Asset are nil", error) 90 | } 91 | 92 | if (config["media"] as? String == "photo") { 93 | let backgroundAsset = RCTConvert.nsurl(config["backgroundAsset"]) 94 | let backgroundBottomColor = RCTConvert.nsString(config["backgroundBottomColor"]) ?? "" 95 | let backgroundTopColor = RCTConvert.nsString(config["backgroundTopColor"]) ?? "" 96 | let stickerAsset = RCTConvert.nsurl(config["stickerAsset"]) 97 | let attributionLink: String = RCTConvert.nsString(config["attributionLink"]) ?? "" 98 | 99 | var backgroundData: NSData? = nil 100 | var stickerData: NSData? = nil 101 | 102 | if(backgroundAsset != nil){ 103 | let decodedData = try Data(contentsOf: backgroundAsset!, 104 | options: NSData.ReadingOptions(rawValue: 0)) 105 | 106 | backgroundData = UIImage(data: decodedData)!.pngData()! as NSData 107 | } 108 | 109 | if(stickerAsset != nil){ 110 | let decodedStickerData = try Data(contentsOf: stickerAsset!, 111 | options: NSData.ReadingOptions(rawValue: 0)) 112 | 113 | stickerData = UIImage(data: decodedStickerData)!.pngData()! as NSData 114 | } 115 | 116 | _shareToInstagram(backgroundData, 117 | stickerData: stickerData, 118 | attributionLink: attributionLink, 119 | backgroundBottomColor: backgroundBottomColor, 120 | backgroundTopColor: backgroundTopColor, 121 | resolve: resolve, 122 | reject: reject) 123 | } else if (config["media"] as? String == "video") { 124 | if let assetPath = config["backgroundAsset"] as? String, let url = URL(string: "instagram://library?AssetPath=" + assetPath) { 125 | if UIApplication.shared.canOpenURL(url) { 126 | if #available(iOS 10.0, *) { 127 | UIApplication.shared.open(url, options: [:], completionHandler:nil) 128 | } else { 129 | // Fallback on earlier versions 130 | } 131 | } 132 | } 133 | } 134 | 135 | } catch { 136 | reject(domain, error.localizedDescription, error) 137 | } 138 | } 139 | 140 | 141 | 142 | func _shareToSnapchat(_ snap: SCSDKSnapContent, 143 | stickerAsset: URL? = nil, 144 | attributionLink: String, 145 | type: String, 146 | resolve: @escaping RCTPromiseResolveBlock, 147 | reject: RCTPromiseRejectBlock) 148 | { 149 | do { 150 | if(attributionLink != ""){ 151 | snap.attachmentUrl = attributionLink 152 | } 153 | 154 | if(stickerAsset != nil){ 155 | let sticker: SCSDKSnapSticker 156 | 157 | if(type == BASE64){ 158 | let data = try Data(contentsOf: stickerAsset!, 159 | options: NSData.ReadingOptions(rawValue: 0)) 160 | let stickerImage = UIImage(data: data) 161 | 162 | sticker = SCSDKSnapSticker(stickerImage: stickerImage!) 163 | } else { 164 | sticker = SCSDKSnapSticker(stickerUrl: stickerAsset!, isAnimated: false) 165 | } 166 | 167 | snap.sticker = sticker 168 | } 169 | 170 | let snapAPI = SCSDKSnapAPI(content: snap) 171 | snapAPI.startSnapping {(error: Error?) in 172 | resolve("ok") 173 | } 174 | } catch { 175 | reject(domain, error.localizedDescription, error) 176 | } 177 | } 178 | 179 | @objc 180 | func shareToSnapchat(_ config: NSDictionary, 181 | resolver resolve: @escaping RCTPromiseResolveBlock, 182 | rejecter reject: RCTPromiseRejectBlock) -> Void { 183 | do { 184 | if (config["backgroundAsset"] == nil && config["stickerAsset"] == nil){ 185 | let error = NSError(domain: domain, code: 400, userInfo: ["Error": "Background Asset and Sticker Asset are nil"]) 186 | return reject("No Assets", "Background Asset and Sticker Asset are nil", error) 187 | } 188 | 189 | let backgroundAsset = RCTConvert.nsurl(config["backgroundAsset"]) 190 | let stickerAsset = RCTConvert.nsurl(config["stickerAsset"]) 191 | let attributionLink: String = RCTConvert.nsString(config["attributionLink"]) ?? "" 192 | let type: String = RCTConvert.nsString(config["type"] ?? FILE) 193 | let captionText: String = RCTConvert.nsString(config["captionText"]) ?? "" 194 | 195 | let snap: SCSDKSnapContent 196 | 197 | if (config["media"] as? String == "photo") { 198 | if (backgroundAsset != nil) { 199 | let photo: SCSDKSnapPhoto 200 | if(type == BASE64){ 201 | let data = try Data(contentsOf: backgroundAsset!, options: NSData.ReadingOptions(rawValue: 0)) 202 | let snapImage = UIImage(data: data) 203 | photo = SCSDKSnapPhoto(image: snapImage!) 204 | } else { 205 | photo = SCSDKSnapPhoto(imageUrl: backgroundAsset!) 206 | } 207 | snap = SCSDKPhotoSnapContent(snapPhoto: photo) 208 | } else { 209 | snap = SCSDKNoSnapContent() 210 | } 211 | snap = SCSDKPhotoSnapContent(snapPhoto: photo) 212 | snap.caption = captionText 213 | }else{ 214 | snap = SCSDKNoSnapContent() 215 | snap.caption = captionText 216 | _shareToSnapchat(snap,stickerAsset: stickerAsset, attributionLink: attributionLink, type: type, resolve: resolve, reject: reject) 217 | } else if (config["media"] as? String == "video") { 218 | if (backgroundAsset != nil) { 219 | let video: SCSDKSnapVideo 220 | if (type == BASE64){ 221 | fatalError("Not yet implemented") 222 | } else { 223 | video = SCSDKSnapVideo(videoUrl: backgroundAsset!) 224 | } 225 | snap = SCSDKVideoSnapContent(snapVideo: video) 226 | } else { 227 | snap = SCSDKNoSnapContent() 228 | } 229 | _shareToSnapchat(snap,stickerAsset: stickerAsset, attributionLink: attributionLink, type: type, resolve: resolve, reject: reject) 230 | } 231 | 232 | } catch { 233 | reject(domain, error.localizedDescription, error) 234 | } 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /ios/RNStoryShare.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B3E7B58A1CC2AC0600A0062D /* RNStoryShare.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNStoryShare.m */; }; 11 | F310292E21A5EF6900F4F039 /* RNStoryShare.swift in Sources */ = {isa = PBXBuildFile; fileRef = F310292D21A5EF6900F4F039 /* RNStoryShare.swift */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXCopyFilesBuildPhase section */ 15 | 58B511D91A9E6C8500147676 /* CopyFiles */ = { 16 | isa = PBXCopyFilesBuildPhase; 17 | buildActionMask = 2147483647; 18 | dstPath = "include/$(PRODUCT_NAME)"; 19 | dstSubfolderSpec = 16; 20 | files = ( 21 | ); 22 | runOnlyForDeploymentPostprocessing = 0; 23 | }; 24 | /* End PBXCopyFilesBuildPhase section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 134814201AA4EA6300B7C361 /* libRNStoryShare.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNStoryShare.a; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | B3E7B5881CC2AC0600A0062D /* RNStoryShare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNStoryShare.h; sourceTree = ""; }; 29 | B3E7B5891CC2AC0600A0062D /* RNStoryShare.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNStoryShare.m; sourceTree = ""; }; 30 | F310292C21A5EF6800F4F039 /* RNStoryShare-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNStoryShare-Bridging-Header.h"; sourceTree = ""; }; 31 | F310292D21A5EF6900F4F039 /* RNStoryShare.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNStoryShare.swift; sourceTree = ""; }; 32 | /* End PBXFileReference section */ 33 | 34 | /* Begin PBXFrameworksBuildPhase section */ 35 | 58B511D81A9E6C8500147676 /* Frameworks */ = { 36 | isa = PBXFrameworksBuildPhase; 37 | buildActionMask = 2147483647; 38 | files = ( 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXFrameworksBuildPhase section */ 43 | 44 | /* Begin PBXGroup section */ 45 | 134814211AA4EA7D00B7C361 /* Products */ = { 46 | isa = PBXGroup; 47 | children = ( 48 | 134814201AA4EA6300B7C361 /* libRNStoryShare.a */, 49 | ); 50 | name = Products; 51 | sourceTree = ""; 52 | }; 53 | 58B511D21A9E6C8500147676 = { 54 | isa = PBXGroup; 55 | children = ( 56 | F310292D21A5EF6900F4F039 /* RNStoryShare.swift */, 57 | B3E7B5881CC2AC0600A0062D /* RNStoryShare.h */, 58 | B3E7B5891CC2AC0600A0062D /* RNStoryShare.m */, 59 | 134814211AA4EA7D00B7C361 /* Products */, 60 | F310292C21A5EF6800F4F039 /* RNStoryShare-Bridging-Header.h */, 61 | ); 62 | sourceTree = ""; 63 | }; 64 | /* End PBXGroup section */ 65 | 66 | /* Begin PBXNativeTarget section */ 67 | 58B511DA1A9E6C8500147676 /* RNStoryShare */ = { 68 | isa = PBXNativeTarget; 69 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNStoryShare" */; 70 | buildPhases = ( 71 | 58B511D71A9E6C8500147676 /* Sources */, 72 | 58B511D81A9E6C8500147676 /* Frameworks */, 73 | 58B511D91A9E6C8500147676 /* CopyFiles */, 74 | ); 75 | buildRules = ( 76 | ); 77 | dependencies = ( 78 | ); 79 | name = RNStoryShare; 80 | productName = RCTDataManager; 81 | productReference = 134814201AA4EA6300B7C361 /* libRNStoryShare.a */; 82 | productType = "com.apple.product-type.library.static"; 83 | }; 84 | /* End PBXNativeTarget section */ 85 | 86 | /* Begin PBXProject section */ 87 | 58B511D31A9E6C8500147676 /* Project object */ = { 88 | isa = PBXProject; 89 | attributes = { 90 | LastUpgradeCheck = 0830; 91 | ORGANIZATIONNAME = Facebook; 92 | TargetAttributes = { 93 | 58B511DA1A9E6C8500147676 = { 94 | CreatedOnToolsVersion = 6.1.1; 95 | LastSwiftMigration = 1010; 96 | }; 97 | }; 98 | }; 99 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNStoryShare" */; 100 | compatibilityVersion = "Xcode 3.2"; 101 | developmentRegion = English; 102 | hasScannedForEncodings = 0; 103 | knownRegions = ( 104 | English, 105 | en, 106 | ); 107 | mainGroup = 58B511D21A9E6C8500147676; 108 | productRefGroup = 58B511D21A9E6C8500147676; 109 | projectDirPath = ""; 110 | projectRoot = ""; 111 | targets = ( 112 | 58B511DA1A9E6C8500147676 /* RNStoryShare */, 113 | ); 114 | }; 115 | /* End PBXProject section */ 116 | 117 | /* Begin PBXSourcesBuildPhase section */ 118 | 58B511D71A9E6C8500147676 /* Sources */ = { 119 | isa = PBXSourcesBuildPhase; 120 | buildActionMask = 2147483647; 121 | files = ( 122 | B3E7B58A1CC2AC0600A0062D /* RNStoryShare.m in Sources */, 123 | F310292E21A5EF6900F4F039 /* RNStoryShare.swift in Sources */, 124 | ); 125 | runOnlyForDeploymentPostprocessing = 0; 126 | }; 127 | /* End PBXSourcesBuildPhase section */ 128 | 129 | /* Begin XCBuildConfiguration section */ 130 | 58B511ED1A9E6C8500147676 /* Debug */ = { 131 | isa = XCBuildConfiguration; 132 | buildSettings = { 133 | ALWAYS_SEARCH_USER_PATHS = NO; 134 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 135 | CLANG_CXX_LIBRARY = "libc++"; 136 | CLANG_ENABLE_MODULES = YES; 137 | CLANG_ENABLE_OBJC_ARC = YES; 138 | CLANG_WARN_BOOL_CONVERSION = YES; 139 | CLANG_WARN_CONSTANT_CONVERSION = YES; 140 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 141 | CLANG_WARN_EMPTY_BODY = YES; 142 | CLANG_WARN_ENUM_CONVERSION = YES; 143 | CLANG_WARN_INFINITE_RECURSION = YES; 144 | CLANG_WARN_INT_CONVERSION = YES; 145 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 146 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 147 | CLANG_WARN_UNREACHABLE_CODE = YES; 148 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 149 | COPY_PHASE_STRIP = NO; 150 | ENABLE_STRICT_OBJC_MSGSEND = YES; 151 | ENABLE_TESTABILITY = YES; 152 | GCC_C_LANGUAGE_STANDARD = gnu99; 153 | GCC_DYNAMIC_NO_PIC = NO; 154 | GCC_NO_COMMON_BLOCKS = YES; 155 | GCC_OPTIMIZATION_LEVEL = 0; 156 | GCC_PREPROCESSOR_DEFINITIONS = ( 157 | "DEBUG=1", 158 | "$(inherited)", 159 | ); 160 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 161 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 162 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 163 | GCC_WARN_UNDECLARED_SELECTOR = YES; 164 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 165 | GCC_WARN_UNUSED_FUNCTION = YES; 166 | GCC_WARN_UNUSED_VARIABLE = YES; 167 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 168 | MTL_ENABLE_DEBUG_INFO = YES; 169 | ONLY_ACTIVE_ARCH = YES; 170 | SDKROOT = iphoneos; 171 | }; 172 | name = Debug; 173 | }; 174 | 58B511EE1A9E6C8500147676 /* Release */ = { 175 | isa = XCBuildConfiguration; 176 | buildSettings = { 177 | ALWAYS_SEARCH_USER_PATHS = NO; 178 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 179 | CLANG_CXX_LIBRARY = "libc++"; 180 | CLANG_ENABLE_MODULES = YES; 181 | CLANG_ENABLE_OBJC_ARC = YES; 182 | CLANG_WARN_BOOL_CONVERSION = YES; 183 | CLANG_WARN_CONSTANT_CONVERSION = YES; 184 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 185 | CLANG_WARN_EMPTY_BODY = YES; 186 | CLANG_WARN_ENUM_CONVERSION = YES; 187 | CLANG_WARN_INFINITE_RECURSION = YES; 188 | CLANG_WARN_INT_CONVERSION = YES; 189 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 190 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 191 | CLANG_WARN_UNREACHABLE_CODE = YES; 192 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 193 | COPY_PHASE_STRIP = YES; 194 | ENABLE_NS_ASSERTIONS = NO; 195 | ENABLE_STRICT_OBJC_MSGSEND = YES; 196 | GCC_C_LANGUAGE_STANDARD = gnu99; 197 | GCC_NO_COMMON_BLOCKS = YES; 198 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 199 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 200 | GCC_WARN_UNDECLARED_SELECTOR = YES; 201 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 202 | GCC_WARN_UNUSED_FUNCTION = YES; 203 | GCC_WARN_UNUSED_VARIABLE = YES; 204 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 205 | MTL_ENABLE_DEBUG_INFO = NO; 206 | SDKROOT = iphoneos; 207 | VALIDATE_PRODUCT = YES; 208 | }; 209 | name = Release; 210 | }; 211 | 58B511F01A9E6C8500147676 /* Debug */ = { 212 | isa = XCBuildConfiguration; 213 | buildSettings = { 214 | CLANG_ENABLE_MODULES = YES; 215 | FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../../../ios/Pods/**"; 216 | HEADER_SEARCH_PATHS = ( 217 | "$(inherited)", 218 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 219 | "$(SRCROOT)/../../../React/**", 220 | "$(SRCROOT)/../../react-native/React/**", 221 | "${SRCROOT}/../../../ios/Pods/Headers/**", 222 | ); 223 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 224 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 225 | OTHER_LDFLAGS = "-ObjC"; 226 | PRODUCT_NAME = RNStoryShare; 227 | SKIP_INSTALL = YES; 228 | SWIFT_OBJC_BRIDGING_HEADER = "RNStoryShare-Bridging-Header.h"; 229 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 230 | SWIFT_VERSION = 4.2; 231 | }; 232 | name = Debug; 233 | }; 234 | 58B511F11A9E6C8500147676 /* Release */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | CLANG_ENABLE_MODULES = YES; 238 | FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../../../ios/Pods/**"; 239 | HEADER_SEARCH_PATHS = ( 240 | "$(inherited)", 241 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 242 | "$(SRCROOT)/../../../React/**", 243 | "$(SRCROOT)/../../react-native/React/**", 244 | "${SRCROOT}/../../../ios/Pods/Headers/**", 245 | ); 246 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 247 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 248 | OTHER_LDFLAGS = "-ObjC"; 249 | PRODUCT_NAME = RNStoryShare; 250 | SKIP_INSTALL = YES; 251 | SWIFT_OBJC_BRIDGING_HEADER = "RNStoryShare-Bridging-Header.h"; 252 | SWIFT_VERSION = 4.2; 253 | }; 254 | name = Release; 255 | }; 256 | /* End XCBuildConfiguration section */ 257 | 258 | /* Begin XCConfigurationList section */ 259 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNStoryShare" */ = { 260 | isa = XCConfigurationList; 261 | buildConfigurations = ( 262 | 58B511ED1A9E6C8500147676 /* Debug */, 263 | 58B511EE1A9E6C8500147676 /* Release */, 264 | ); 265 | defaultConfigurationIsVisible = 0; 266 | defaultConfigurationName = Release; 267 | }; 268 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNStoryShare" */ = { 269 | isa = XCConfigurationList; 270 | buildConfigurations = ( 271 | 58B511F01A9E6C8500147676 /* Debug */, 272 | 58B511F11A9E6C8500147676 /* Release */, 273 | ); 274 | defaultConfigurationIsVisible = 0; 275 | defaultConfigurationName = Release; 276 | }; 277 | /* End XCConfigurationList section */ 278 | }; 279 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 280 | } 281 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-story-share", 3 | "version": "0.7.0", 4 | "description": "share your images to instagram and snapchat stories", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "react-native", 11 | "instagram", 12 | "snapchat", 13 | "story", 14 | "share" 15 | ], 16 | "author": "Johannes Sorg ", 17 | "license": "MIT", 18 | "peerDependencies": { 19 | "react-native": "^0.41.2" 20 | }, 21 | "devDependencies": { 22 | "babel-eslint": "^10.0.1", 23 | "babel-preset-react-native": "^4.0.1", 24 | "eslint": "^5.9.0", 25 | "eslint-config-airbnb": "^17.1.0", 26 | "eslint-config-prettier": "^3.3.0", 27 | "eslint-plugin-import": "^2.14.0", 28 | "eslint-plugin-jsx-a11y": "^6.1.2", 29 | "eslint-plugin-prettier": "^3.0.0", 30 | "eslint-plugin-react": "^7.11.1", 31 | "prettier": "^1.15.2" 32 | } 33 | } 34 | --------------------------------------------------------------------------------