├── .buckconfig ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .watchmanconfig ├── App.iMessage.js ├── App.js ├── DevMenu.js ├── README.md ├── __tests__ └── App.js ├── android ├── app │ ├── BUCK │ ├── build.gradle │ ├── build_defs.bzl │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── awesomeproject │ │ │ ├── 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 ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── keystores │ ├── BUCK │ └── debug.keystore.properties └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── index.message.js ├── ios ├── AwesomeProject-tvOS │ └── Info.plist ├── AwesomeProject-tvOSTests │ └── Info.plist ├── AwesomeProject.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ ├── AwesomeProject-tvOS.xcscheme │ │ ├── AwesomeProject.xcscheme │ │ └── AwesomeProjectMessageExtension.xcscheme ├── AwesomeProject │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── App-Icon-1024pt.png │ │ │ ├── Contents.json │ │ │ ├── iPad-Settings-29pt@2x.png │ │ │ └── iPhone-Settings-29pt@3x.png │ │ └── Contents.json │ ├── Info.plist │ └── main.m ├── AwesomeProjectMessageExtension │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── iMessage App Icon.stickersiconset │ │ │ ├── App-Icon-1024pt.png │ │ │ ├── Contents.json │ │ │ ├── Message-27x20pt@2x.png │ │ │ ├── Message-27x20pt@3x.png │ │ │ ├── Message-32x24pt@2x.png │ │ │ ├── Message-32x24pt@3x.png │ │ │ ├── Message-App-Store-1024x768pt.png │ │ │ ├── Message-iPad-67x50pt@2x.png │ │ │ ├── Message-iPad-Pro-74x55pt@2x.png │ │ │ ├── Message-iPhone-60x45pt@2x.png │ │ │ ├── Message-iPhone-60x45pt@3x.png │ │ │ ├── iPad-Settings-29pt@2x.png │ │ │ ├── iPhone-Settings-29pt@2x.png │ │ │ └── iPhone-Settings-29pt@3x.png │ │ └── zebra.imageset │ │ │ ├── Contents.json │ │ │ └── zebra.jpg │ ├── Base.lproj │ │ └── MainInterface.storyboard │ ├── Bridging-Header.h │ ├── Info.plist │ ├── LoadingView.xib │ ├── Mappers.swift │ ├── MessagesEventEmitter.m │ ├── MessagesEventEmitter.swift │ ├── MessagesManager.m │ ├── MessagesManager.swift │ ├── MessagesViewController.swift │ └── ModuleInitializer.swift └── AwesomeProjectTests │ ├── AwesomeProjectTests.m │ └── Info.plist ├── package-lock.json └── package.json /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /.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 | node_modules/react-native/flow-github/ 28 | 29 | [options] 30 | emoji=true 31 | 32 | esproposal.optional_chaining=enable 33 | esproposal.nullish_coalescing=enable 34 | 35 | module.system=haste 36 | module.system.haste.use_name_reducers=true 37 | # get basename 38 | module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' 39 | # strip .js or .js.flow suffix 40 | module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' 41 | # strip .ios suffix 42 | module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' 43 | module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' 44 | module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' 45 | module.system.haste.paths.blacklist=.*/__tests__/.* 46 | module.system.haste.paths.blacklist=.*/__mocks__/.* 47 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* 48 | module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.* 49 | 50 | munge_underscores=true 51 | 52 | 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' 53 | 54 | module.file_ext=.js 55 | module.file_ext=.jsx 56 | module.file_ext=.json 57 | module.file_ext=.native.js 58 | 59 | suppress_type=$FlowIssue 60 | suppress_type=$FlowFixMe 61 | suppress_type=$FlowFixMeProps 62 | suppress_type=$FlowFixMeState 63 | 64 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 65 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 66 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 67 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 68 | 69 | [version] 70 | ^0.86.0 71 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /App.iMessage.js: -------------------------------------------------------------------------------- 1 | // 2 | // App.iMessage.js 3 | // 4 | 5 | import React, { Component } from 'react'; 6 | import { 7 | Text, 8 | View, 9 | NativeModules, 10 | NativeEventEmitter, 11 | Button, 12 | } from 'react-native'; 13 | import DevMenu from './DevMenu'; 14 | 15 | const { MessagesManager, MessagesEventEmitter } = NativeModules; 16 | const MessagesEvents = new NativeEventEmitter(MessagesEventEmitter); 17 | 18 | export default class App extends Component { 19 | state = { 20 | presentationStyle: '', 21 | conversation: null, 22 | message: null, 23 | } 24 | 25 | componentDidMount() { 26 | MessagesManager 27 | .getPresentationStyle(presentationStyle => this.setState({ presentationStyle })) 28 | 29 | MessagesEvents 30 | .addListener('onPresentationStyleChanged', ({ presentationStyle }) => this.setState({ presentationStyle })); 31 | 32 | MessagesManager 33 | .getActiveConversation((conversation, message) => this.setState({ conversation, message })); 34 | 35 | MessagesEvents 36 | .addListener('didReceiveMessage', ({ message }) => this.setState({ message })); 37 | 38 | MessagesEvents 39 | .addListener('didSelectMessage', ({ message }) => this.setState({ message })); 40 | 41 | this.performFakeAsyncTaskAndHideLoadingView() 42 | } 43 | 44 | performFakeAsyncTaskAndHideLoadingView = () => { 45 | setTimeout(() => MessagesManager.hideLoadingView(), 1500); 46 | } 47 | 48 | onTogglePresentationStyle = () => { 49 | MessagesManager 50 | .updatePresentationStyle(this.state.presentationStyle === 'expanded' ? 'compact' : 'expanded') 51 | .then(presentationStyle => this.setState({ presentationStyle })) 52 | } 53 | 54 | onComposeMessage = () => { 55 | MessagesManager.composeMessage({ 56 | layout: { 57 | imageName: 'zebra.jpg', 58 | imageTitle: 'Image Title', 59 | imageSubtitle: 'Image Subtitle', 60 | }, 61 | summaryText: 'Sent a message from AwesomeMessageExtension', 62 | url: `?timestamp=${Date.now()}&sender=${this.state.conversation.localParticipiantIdentifier}` 63 | }) 64 | .then(() => MessagesManager.updatePresentationStyle('compact')) 65 | .catch(error => console.log('An error occurred while composing the message: ', error)) 66 | } 67 | 68 | onOpenURL = () => { 69 | MessagesManager.openURL('url://test') 70 | .then(() => console.log('Successfully opened url!')) 71 | .catch(error => console.log('An error occurred while opening the URL: ', error)) 72 | } 73 | 74 | onShowLoadingView = () => { 75 | MessagesManager.showLoadingView(); 76 | this.performFakeAsyncTaskAndHideLoadingView(); 77 | } 78 | 79 | render() { 80 | const { message } = this.state; 81 | 82 | return ( 83 | 84 | {__DEV__ && } 85 | 86 |