-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Share module #5904
Add Share module #5904
Changes from 1 commit
a76c6c0
424a665
5da16c7
8c3bece
1f5f0c0
fb5f6ea
f21d709
8917788
767f914
de58c94
68804ca
fb88c94
9917041
72c6d50
2678aee
32847bb
0371750
dfe1f63
772523e
43209dc
74e6966
dc7fdaa
7f39ae3
08c29bd
375ee94
851c4ea
4d6add8
e398fd9
71a67fb
4351eec
92a793b
68ca817
d3e13ed
ae290f0
918aaf6
f4d7d3a
29b5e3b
db99ac4
d0f6fb8
bc14456
a404f49
9c896e5
de1ab8f
5127f30
0834fc7
994cda0
2b52ff5
dc1c57c
94023f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/** | ||
* The examples provided by Facebook are for non-commercial testing and | ||
* evaluation purposes only. | ||
* | ||
* Facebook reserves all rights not expressly granted. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. property |
||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | ||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | ||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
* | ||
* @flow | ||
*/ | ||
'use strict'; | ||
|
||
var React = require('react-native'); | ||
var { | ||
StyleSheet, | ||
View, | ||
Text, | ||
TextInput, | ||
TouchableHighlight, | ||
Share, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. property There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to add it to the |
||
} = React; | ||
|
||
exports.framework = 'React'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. semi: Missing semicolon. |
||
exports.title = 'Share'; | ||
exports.description = 'Share data with other Apps.'; | ||
exports.examples = [{ | ||
title: 'Share Text Content', | ||
render() { | ||
return <ShareMessageExample />; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. keyword-spacing: Expected space(s) after "if". |
||
}]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. semi: Missing semicolon. |
||
|
||
class ShareMessageExample extends React.Component { | ||
|
||
constructor(props) { | ||
super(props); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. semi: Missing semicolon. |
||
|
||
this.shareMessage = this.shareMessage.bind(this); | ||
this.shareTextContent = this.shareTextContent.bind(this); | ||
|
||
this.state = { | ||
result: '' | ||
}; | ||
} | ||
|
||
render() { | ||
return ( | ||
<View> | ||
<TouchableHighlight style={styles.wrapper} | ||
onPress={this.shareMessage}> | ||
<View style={styles.button}> | ||
<Text>Click to share message</Text> | ||
</View> | ||
</TouchableHighlight> | ||
<TouchableHighlight style={styles.wrapper} | ||
onPress={this.shareTextContent}> | ||
<View style={styles.button}> | ||
<Text>Click to share message, URL and subject</Text> | ||
</View> | ||
</TouchableHighlight> | ||
<Text>{this.state.result}</Text> | ||
</View> | ||
); | ||
} | ||
|
||
shareMessage() { | ||
Share.shareTextContent({ | ||
message: 'React Native | A framework for building native apps using React' | ||
}) | ||
.then((result) => { | ||
if(!result) { | ||
this.setState({result:'Canceled'}) | ||
} else { | ||
this.setState({result:result}) | ||
} | ||
}) | ||
.catch((err) => console.error(err)) | ||
} | ||
shareTextContent() { | ||
Share.shareTextContent({ | ||
message: 'A framework for building native apps using React', | ||
url: 'http://facebook.github.io/react-native/', | ||
subject: 'React Native' | ||
}, { | ||
dialogTitle: 'Share React Native website', | ||
excludedActivityTypes: [ | ||
'com.apple.UIKit.activity.PostToTwitter' | ||
] | ||
}) | ||
.then((result) => this.setState({result:result})) | ||
.catch(()=> this.setState({result:'Canceled'})) | ||
} | ||
|
||
} | ||
|
||
|
||
var styles = StyleSheet.create({ | ||
wrapper: { | ||
borderRadius: 5, | ||
marginBottom: 5, | ||
}, | ||
button: { | ||
backgroundColor: '#eeeeee', | ||
padding: 10, | ||
}, | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/** | ||
* Copyright (c) 2016-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no-trailing-spaces: Trailing spaces not allowed. |
||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no-trailing-spaces: Trailing spaces not allowed. |
||
* of patent rights can be found in the PATENTS file in the same directory. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no-trailing-spaces: Trailing spaces not allowed. |
||
* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no-trailing-spaces: Trailing spaces not allowed. |
||
* @providesModule Share | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no-trailing-spaces: Trailing spaces not allowed. |
||
* @flow | ||
*/ | ||
'use strict'; | ||
|
||
const Platform = require('Platform'); | ||
const { | ||
ActionSheetManager, | ||
ShareModule | ||
} = require('NativeModules'); | ||
const invariant = require('invariant'); | ||
const processColor = require('processColor'); | ||
|
||
class Share { | ||
|
||
/** | ||
* Open a dialog to share text contents. | ||
* | ||
* ### Contents | ||
* | ||
* - `message` - a message to share | ||
* - `url` - an URL to share. In Android, this will overwrite message | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be better just to ignore this prop on Android instead of overwriting message. It becomes more explicit then, and the user can decide what to do. For example, I would usually prefer to combine the message and url into a single text on Android. |
||
* - `subject` - subject of the message | ||
* | ||
* At least one of URL and message is required. | ||
* | ||
* ### Options | ||
* | ||
* #### iOS | ||
* | ||
* - `excludedActivityTypes` | ||
* - `tintColor` | ||
* | ||
* #### Android | ||
* | ||
* - `dialogTitle` | ||
*/ | ||
static shareTextContent(contents: Object, options?: Object): Promise<boolean> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: call the argument |
||
invariant( | ||
typeof contents === 'object' && contents !== null, | ||
'Contents must a valid object' | ||
); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no-trailing-spaces: Trailing spaces not allowed. |
||
invariant( | ||
contents.url || contents.message, | ||
'At least one of URL and message is required' | ||
); | ||
for(let content in contents) { | ||
invariant( | ||
typeof content === 'string', | ||
'Invalid Content: should be a string. Was: ' + content | ||
); | ||
} | ||
options = options || {}; | ||
return Platform.OS === 'android' | ||
? ShareModule.shareTextContent(contents, options.dialogTitle) | ||
: new Promise((resolve, reject) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add if statements for each Platform type. |
||
ActionSheetManager.showShareActionSheetWithOptions( | ||
{...contents, tintColor: processColor(options.tintColor)}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. property |
||
console.error, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should reject the promise instead of logging. |
||
(success, activityType) => { | ||
if(success) { | ||
resolve(activityType) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the value of One solution is to resolve with an object with platform-specific properties. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is |
||
} else { | ||
reject() | ||
} | ||
} | ||
); | ||
}); | ||
} | ||
|
||
} | ||
|
||
module.exports = Share; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/** | ||
* Copyright (c) 2016-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
|
||
package com.facebook.react.modules.share; | ||
|
||
import android.app.Activity; | ||
import android.content.Intent; | ||
import android.net.Uri; | ||
|
||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException; | ||
import com.facebook.react.bridge.Promise; | ||
import com.facebook.react.bridge.ReactApplicationContext; | ||
import com.facebook.react.bridge.ReactContextBaseJavaModule; | ||
import com.facebook.react.bridge.ReactMethod; | ||
import com.facebook.react.bridge.ReadableMap; | ||
|
||
/** | ||
* Intent module. Launch other activities or open URLs. | ||
*/ | ||
public class ShareModule extends ReactContextBaseJavaModule { | ||
|
||
private Promise mPromise; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make this |
||
|
||
public ShareModule(ReactApplicationContext reactContext) { | ||
super(reactContext); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "ShareModule"; | ||
} | ||
|
||
/** | ||
* Open a chooser dialog to send text contents to other apps. | ||
* | ||
* Refer http://developer.android.com/intl/ko/training/sharing/send.html | ||
* | ||
* @param contents the data to send | ||
* @param title the title of the chooser dialog | ||
*/ | ||
@ReactMethod | ||
public void shareTextContent(ReadableMap contents, String title, final Promise promise) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is the promise final? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should be a test for this, checking that: the intent is built correctly, the currentActivity starts the correct intent. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
Activity currentActivity = getCurrentActivity(); | ||
|
||
if (currentActivity == null) { | ||
promise.reject("Activity doesn't exist"); | ||
return; | ||
} | ||
|
||
if (contents == null) { | ||
throw new JSApplicationIllegalArgumentException("Invalid contents"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's |
||
} | ||
|
||
mPromise = promise; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this needed? |
||
|
||
try { | ||
Intent intent = new Intent(Intent.ACTION_SEND); | ||
intent.setTypeAndNormalize("text/plain"); | ||
|
||
if(contents.hasKey("subject")) { | ||
intent.putExtra(Intent.EXTRA_SUBJECT, contents.getString("subject")); | ||
} | ||
|
||
if(contents.hasKey("message")) { | ||
intent.putExtra(Intent.EXTRA_TEXT, contents.getString("message")); | ||
} | ||
|
||
if(contents.hasKey("url")) { | ||
intent.putExtra(Intent.EXTRA_TEXT, contents.getString("url")); // this will overwrite message | ||
} | ||
|
||
currentActivity.startActivity(Intent.createChooser(intent, title)); | ||
//TODO: use createChooser (Intent target, CharSequence title, IntentSender sender) after API level 22 | ||
mPromise.resolve(true); | ||
mPromise = null; | ||
} catch (Exception e) { | ||
mPromise.reject("Failed to open share dialog"); | ||
mPromise = null; | ||
} | ||
|
||
} | ||
|
||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
property
_showResult
Property not found in ShareMessageExample