react-native-social-share icon indicating copy to clipboard operation
react-native-social-share copied to clipboard

iOS Issue When Calling Tweet From Modal

Open angusmccloud opened this issue 7 years ago • 5 comments

I'm using SocialShare on both iOS and Android for the Twitter side of Social integration (using the FBSDK for that piece), and have found that on iOS the Twitter dialog box doesn't doesn't appear if my tweet function is called from a button in a Modal.

If I put a flat button on the screen it will work every time, but in a Modal it doesn't.

At this point I've disabled the modals that see if people want to post to social media, but that's really disappointing since it's a great way to prompt people when certain events happen.

Has anyone else run into this?

Cheers! -Connor

angusmccloud avatar Jun 29 '17 20:06 angusmccloud

@angusmccloud Hey Connor

I am quite sure this behavior happens because the share dialog is a modal of some sort itself. Maybe you could fix it by making the button first close down the modal and then trigger the social share.

Cheers Kim

doefler avatar Jun 29 '17 20:06 doefler

@doefler I should have shared some code! Yes, that was my first guess and so I have things structured like this:

  tweet(){
    this.setSocialMediaModal(false); // this true/false powers the Visible property on the Modal
    var text = this.getTwitterText(); // Pulls a random string to have as the default text (that fits within the 140 characters)
    if(this.props.PublishedFlag == "1"){ // Should we share a link to the content (is it a publicly accessible URL)
      var link = this.props.ProfileURL;
    }
    else{
      var link = null;
    }
    if(this.props.BeerImage == "noimage.jpg"){ // Is there an image to share
//      console.log("Beer has no image");
      var imageLink = null;
    }
    else{
//      console.log("Beer has an image");
      var imageLink = GLOBAL.beer_image_base_url + this.props.BeerImage;
    }
//    console.log("Text: " + text + ", link: " + link + ", Image: " + imageLink);
    shareOnTwitter({
        'text':text,
        'link':link,
        'imagelink':imageLink,
      },
      (results) => {
.....
//        console.log(results);
      }
    );
  }

angusmccloud avatar Jun 29 '17 20:06 angusmccloud

@angusmccloud

Can you share the rest of this file? Do you bind "this" to the event? onClick={this.onClickHandler.bind(this)} for example.

Does the console tell anything?

doefler avatar Jun 29 '17 20:06 doefler

@doefler

Can you share the rest of this file? I can share that relevant section (this screen is the most complex and longest within the app).

Do you bind "this" to the event? No, the setSocialMediaModal is not bound, I can try that tonight.

Does the console tell anything? No, but that's because I do all of this on a PC and this works 100% of the time on Android. I'll steal my wife's macbook and see if the log tells me anything. I DO know that iOS will crash if you try to open multiple modals/alerts, and Android doesn't. But this method of "close the one that's open before opening the next" has worked for me everywhere else in the app.

Code for that component (with unrelated pieces "..." out):

class RenderButtons extends Component {
  constructor() {
    super();
    this.state = {
      socialMediaModal: false,
      ...
    }
  }

  async componentWillMount(){
	... // Fetching some asyncStorage info, not relevant to Twitter
    this.CheckOut = this.CheckOut.bind(this);
  }

  CheckOut(){
    this.setState({checkedInFlag: false});
  }

  removeImage() {
    ...
  }

  startImagePicker() {
    ...
  }

  render(){
    var dataFetching = this.props.dataFetching;
    ... // Other unrelated variables

    if (dataFetching === false) {
      ...

      return(
        <View>
          <Modal
            animationType={"fade"}
            transparent={true}
            visible={this.state.socialMediaModal}
            onRequestClose={() => this.setSocialMediaModal(false)}
          >
            <TouchableWithoutFeedback onPress={ () => this.setSocialMediaModal(false)}>
              <View style={styles.ModalBackground}>
                <View style={{backgroundColor: '#fff4ed', width: deviceWidth*.9, borderRadius: 5}}>
                  <View style={{padding: 10}}>
                    <Button
                      onPress = { () => this.postToSocialMedia('Facebook') } // This function was designed to do both Twitter and FB, but I don't have Twitter hitting it anymore
                      title = "Share on Facebook"
                      color = {COLOR_DEFAULT_ORANGE}
                      accessibilityLabel = "Share on Facebook"
                    />
                  </View>
                  <View style={styles.BeerTeaserSeparator} />
                  <View style={{padding: 10}}>
                    <Button
                      onPress = { () => this.tweet() }
                      title = "Post to Twitter"
                      color = {COLOR_DEFAULT_ORANGE}
                      accessibilityLabel = "Post to Twitter"
                    />
                  </View>
                  <View style={styles.BeerTeaserSeparator} />
                  <View style={{padding: 10}}>
                    <Button
                      onPress = { () => this.setSocialMediaModal(false) }
                      title = "Done"
                      color = {COLOR_DEFAULT_ORANGE}
                      accessibilityLabel = "Done"
                    />
                  </View>
                </View>
              </View>
            </TouchableWithoutFeedback>
          </Modal>
          ...
		  // I used to have a Share button here that enabled the SocialMediaModal - I've replaced it with 2 separate buttons for Twitter and FB
		  // The SocialMediaModal was also enabled through a separate process (which never had problems)
          <TouchableWithoutFeedback onPress={ () => this.tweet()}>
            <View style={styles.BeerProfileFunctionRow}>
              <View style={styles.BeerProfileRowLeftSide}>
                <Image source={require('../images/icons/Twitter.png')} resizeMode="contain" style={styles.BeerProfileFunctionPic} />
              </View>
              <View style={styles.BeerProfileRowRightSide}>
                <Text allowFontScaling={GLOBAL.fontScaling} style={styles.BeerProfileRowText}>Post to Twitter</Text>
              </View>
            </View>
          </TouchableWithoutFeedback>
          <TouchableWithoutFeedback onPress = { () => this.postToSocialMedia('Facebook')}>
            <View style={styles.BeerProfileFunctionRow}>
              <View style={styles.BeerProfileRowLeftSide}>
                <Image source={require('../images/icons/FacebookIcon.png')} resizeMode="contain" style={styles.BeerProfileFunctionPic} />
              </View>
              <View style={styles.BeerProfileRowRightSide}>
                <Text allowFontScaling={GLOBAL.fontScaling} style={styles.BeerProfileRowText}>Share on Facebook</Text>
              </View>
            </View>
          </TouchableWithoutFeedback>
          <SimilarBeersButton SimilarBeersVisible={similarBeersVisible} SimilarBeersCount={SimilarBeersCount} setSimilarBeersVisible={this.props.setSimilarBeersVisible} />
        </View>
      );
    }
    else {
      return(
        <ActivityIndicator
          animating={true}
          style={{alignItems: 'center', justifyContent: 'center', height: 80}}
          size="large"
        />
      );
    }
  }

  tweet(){
//    this.setSocialMediaModal(false); // Commented out in my current code since I'm no longer using the Modal
    var text = this.getTwitterText();
    if(this.props.PublishedFlag == "1"){
      var link = this.props.ProfileURL;
    }
    else{
      var link = null;
    }
    if(this.props.BeerImage == "noimage.jpg"){
      var imageLink = null;
    }
    else{
      var imageLink = GLOBAL.beer_image_base_url + this.props.BeerImage;
    }
//    console.log("Text: " + text + ", link: " + link + ", Image: " + imageLink);
    shareOnTwitter({
        'text':text,
        'link':link,
        'imagelink':imageLink,
      },
      (results) => {
		...
//        console.log(results);
      }
    );
  }

  getTwitterText(){
    // Set the variables that will go into building the string later
	...
	
    var twitterText = '';

    var twitterTextArray = new Array();

    twitterTextArray = this.addToTwitterArray("Having " + aOrAn + " " + beerName + brewerTwitter + locationTwitter + ratedText + " via @BrewGene", twitterTextArray);
    twitterTextArray = this.addToTwitterArray("Drinking " + aOrAn + " " + beerName + brewerTwitter + locationTwitter + ratedText + " via @BrewGene", twitterTextArray);
	... // There are a bunch of these

    if(twitterTextArray.length === 0){
      // Get a really short one in there if all the others were too long
      twitterTextArray.push("Having " + aOrAn + " " + beerName + " via @BrewGene");
    }

    var twitterArrayLength = Math.floor(Math.random()*twitterTextArray.length);

    twitterText = twitterTextArray[twitterArrayLength];
    return(twitterText);
  }

  postToSocialMedia(platform) {
  ... // I was using this for Twitter as well as FB, but broke twitter into its own function when trying to debug
  }

  addToTwitterArray(string, twitterArray){
    var maxCharacters = 140
    if(this.props.PublishedFlag == "1"){ // 23 characters used for a Link
      maxCharacters = maxCharacters - 23;
    }
    if(this.props.BeerImage !== "noimage.jpg"){
      maxCharacters = maxCharacters - 24;
    }
    if(string.length <= maxCharacters){
      // Only add the string to the array if it's under the 140 characters, including link and image
      twitterArray.push(string);
    }
    return twitterArray;
  }

  setSocialMediaModal(visible) {
    this.setState({socialMediaModal: visible});
  }

	... // A few more unrelated functions
}

angusmccloud avatar Jun 29 '17 21:06 angusmccloud

@angusmccloud

I would try changing:


<View style={{padding: 10}}>
	<Button
		onPress = { () => this.tweet() }
		title = "Post to Twitter"
		color = {COLOR_DEFAULT_ORANGE}
		accessibilityLabel = "Post to Twitter"
	/>
</View>

into


<View style={{padding: 10}}>
	<Button
		onPress = { this.tweet.bind(this) }
		title = "Post to Twitter"
		color = {COLOR_DEFAULT_ORANGE}
		accessibilityLabel = "Post to Twitter"
	/>
</View>

Notice the onPress part.

Other than that, I don't have any idea, what might cause this.

doefler avatar Jun 29 '17 21:06 doefler