birdwingo / react-native-instagram-stories

🚀 Instagram stories is a versatile React Native component designed to display a horizontal scrollable list of user stories, similar to the stories feature found in the Instagram app.
https://birdwingo.com
MIT License
131 stars 35 forks source link

imageOverlayView=> Overlay Buttons and Links Not Clickable in Image/Video Story #104

Closed Adil7767 closed 3 months ago

Adil7767 commented 3 months ago

When I add an overlay with buttons or links on top of images and video stories, the buttons and links in the overlay are not clickable. Instead of triggering the button or link actions, clicking on them changes the story. This prevents the expected behavior of the buttons and links within the overlay.

Steps to Reproduce

Add an overlay with buttons or links on an image or video story. Click on any button or link in the overlay. Expected Behavior Clicking on the buttons or links in the overlay should trigger their respective actions.

Actual Behavior

Clicking on the buttons or links in the overlay changes the story instead of triggering the button or link actions.

Possible Solutions

Ensure the overlay is set up correctly to handle click events without affecting the underlying story change logic. Adjust the z-index of the overlay elements to ensure they are clickable. Prevent event propagation from overlay elements to the underlying story container.

      <InstagramStories
      ....
      imageOverlayView={
          <OverlayView data={data[activeStoryIndex]}/>
        }
        .....
        />

and my overlay component


import {Dimensions, StyleSheet, View} from 'react-native';
import React from 'react';
import Text from '../../../general_components/Text/Text';
const {width, height} = Dimensions.get('window');
import {Button} from 'react-native-paper';

const OverlayView = props => {
  const {data} = props;

  const widgetsRender = item => {
    if (item?.type === 'Button') {
      return (
        <Button
          mode={'contained'}
          style={{borderRadius: 14}}
          labelStyle={{fontSize: 18}}
          buttonColor={item?.background || 'white'}
          textColor={'black'}
          onPress={()=>console.log('object')}> //not showing console on click 
          {item?.title || 'Hello'}

        </Button>
      );
    } else {
      return (
        <>
        <Text
          variant={'default20'}
          style={[
            styles.text,
            {
              fontSize: item.fontSize,
              color: item.textColor,
              textAlign: item.fontAlignment,
              fontFamily: item.fontStyle,
            },
          ]}>
          {item.text}
        </Text>
        <Button
          mode={'contained'}
          style={{borderRadius: 14}}
          labelStyle={{fontSize: 18}}
          buttonColor={item?.background || 'red'}
          textColor={'black'}>
          {item?.title || 'kkkkk'}
        </Button>
        </>
      );
    }
  };
  return (
    <View style={{width: width, height: height, position: 'relative'}}>
      {data?.widgets?.map((value, index) => {
        const {item} = value;
        return (
          <View
            key={index}
            style={[
              styles.textContainer,
              {
                left: item?.position?.xPos + 60,
                top: item?.position?.yPos + 460,
                backgroundColor: item.backgroundColor,
                zIndex: 100,
              },
            ]}>
            {widgetsRender(item)}
          </View>
        );
      })}
    </View>
  );
};

export default OverlayView;

const styles = StyleSheet.create({
  textContainer: {
    position: 'absolute',
    padding: 10,
    borderRadius: 10,
    maxWidth: '90%',
    minWidth: '20%',
  },
  text: {
    padding: 0,
    minWidth: '20%',
    maxWidth: '100%',
    borderRadius: 10,
  },
});

{
  /*
     <View style={{width: width, height: height, position: 'relative'}}>
            {data[activeStoryIndex]?.widgets?.map((value, index) => {
              const {item} = value;
              return (
                <View
                  key={index}
                  style={[
                    styles.textContainer,
                    {
                      left: item?.position?.xPos + 60,
                      top: item?.position?.yPos + 460,
                      backgroundColor: item.backgroundColor,
                      zIndex: 100,
                    },
                  ]}>
                  <Text
                    variant={'default20'}
                    style={[
                      styles.text,
                      {
                        fontSize: item.fontSize,
                        color: item.textColor,
                        textAlign: item.fontAlignment,
                        fontFamily: item.fontStyle,
                      },
                    ]}>
                    {item.text}
                  </Text>
                </View>
              );
            })}
          </View>
    */
}
Adil7767 commented 3 months ago

its working now so i am closing the issue

import {
  Dimensions,
  ImageBackground,
  Linking,
  StyleSheet,
  View,
} from 'react-native';
import React from 'react';
import Text from '../../../general_components/Text/Text';
const {width, height} = Dimensions.get('window');
import {Button, Icon} from 'react-native-paper';
import {LinearGradient} from 'expo-linear-gradient';
import { convertStringToArray } from '../../../utilities/functions';

const OverlayView = props => {
  const {data} = props;
  const onButtonOrLinkClick = url => {
    Linking.openURL(url);
  };
  const widgetsRender = item => {
    if (item?.type === 'BUTTON') {
      return (
        <Button
          mode={'contained'}
          style={{borderRadius: 14}}
          labelStyle={{fontSize: 18}}
          buttonColor={item?.backgroundColor || '#fff'}
          textColor={item?.textColor || '#000'}
          onPress={() => onButtonOrLinkClick(item?.url || 'hello.com')}>
          {item?.title || 'Hello'}
        </Button>
      );
    } else if (item?.type === 'LINK') {
      return (
        <Button
          mode={'contained'}
          style={{borderRadius: 14}}
          labelStyle={{fontSize: 18}}
          buttonColor={'#fff'}
          textColor={item?.textColor || 'blue'}
          icon={({size, color}) => (
            <View style={{transform: [{rotate: '120deg'}]}}>
              <Icon
                source={'link'}
                size={28}
                color={item?.backgroundColor || 'blue'}
              />
            </View>
          )}
          onPress={() => onButtonOrLinkClick(item?.url || 'hello.com')}>
          {item?.data?.title.trim() === ''
            ? item?.data?.url
            : item?.data?.title || 'hi hello bye'}
        </Button>
      );
    } else {
      return (
        <View style={[styles.input, {backgroundColor: item?.backgroundColor}]}>
          <Text
            variant={'default20'}
            style={[
              styles.text,
              {
                fontSize: item?.fontSize,
                color: item?.textColor,
                textAlign: item?.fontAlignment,
                fontFamily: item?.fontStyle,
              },
            ]}>
            {item?.text}
          </Text>
        </View>
      );
    }
  };

    return (
    <View style={{flex: 1, position: 'relative'}}>
      <View style={styles.root}>
          <LinearGradient
            colors={
              data?.backgroundType === 'GRADIENT'
                ? convertStringToArray(data?.background)
                : []
            }
            style={[
              styles.container,
              {width: width, height: 56, position: 'relative'},
            ]}>
            {data?.widgets?.map((value, index) => {
              const {item} = value;
              return (
                <View
                  key={index}
                  style={[
                    styles.textContainer,
                    {
                      left: item?.position?.xPos + 50 || 50,
                      top: item?.position?.yPos + 460 || 460,
                      zIndex: 100,
                    },
                  ]}>
                  {widgetsRender(item)}
                </View>
              );
            })}
          </LinearGradient>
      </View>
    </View>
  );
};

export default OverlayView;

const styles = StyleSheet.create({
  textContainer: {
    position: 'absolute',
    padding: 10,
    borderRadius: 10,
    maxWidth: '90%',
    minWidth: '20%',
  },
  text: {
    padding: 0,
    minWidth: '20%',
    maxWidth: '100%',
    borderRadius: 10,
  },
  input: {
    padding: 6,
    borderRadius: 10,
  },
  root: {
    width: '100%',
    flex: 1,
    position: 'relative',
  },
  container: {
    position: 'relative',
    width: '100%',
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  backgroundImage: {
    position: 'relative',
    width: '100%',
    flex: 1,
    // borderRadius: 20,
    overflow: 'hidden',
    justifyContent: 'center',
    alignItems: 'center',
  },
});