Skip to content

Commit

Permalink
Merge branch 'main' into feat/on-seen
Browse files Browse the repository at this point in the history
  • Loading branch information
caglardurmus authored Apr 21, 2023
2 parents c49951b + b1d4d39 commit af287b4
Show file tree
Hide file tree
Showing 8 changed files with 413 additions and 140 deletions.
70 changes: 52 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,39 @@ import InstaStory from 'react-native-insta-story';

## Props

| Name | Description | Type | Default Value |
| :--------------------- | :-------------------------------------------------- | :-------- | :-----------: |
| data | Array of IUserStory. You can check from interfaces. | object | |
| unPressedBorderColor | Unpressed border color of profile circle | color | red |
| pressedBorderColor | Pressed border color of profile circle | color | grey |
| onClose | Todo when close | function | null |
| onStart | Todo when start | function | null |
| onStorySeen | Called each time story is seen | function | null |
| duration | Per story duration seconds | number | 10 |
| swipeText | Text of swipe component | string | Swipe Up |
| customSwipeUpComponent | For use custom component for swipe area | component | |
| customCloseComponent | For use custom component for close button | component | |
| avatarSize | Size of avatar circle | number | 60 |
| showAvatarText | For show or hide avatar text. | bool | true |
| textStyle | For avatar text style | TextStyle | |
| Name | Description | Type | Default Value |
| :------------------------- | :-------------------------------------------------- | :------------ | :-----------: |
| data | Array of IUserStory. You can check from interfaces. | object | |
| unPressedBorderColor | Unpressed border color of profile circle | color | red |
| pressedBorderColor | Pressed border color of profile circle | color | grey |
| unPressedAvatarTextColor | Unpressed avatar text color | color | red |
| pressedAvatarTextColor | Pressed avatar text color | color | grey |
| onStorySeen | Called each time story is seen | function | null |
| onClose | Todo when close | function | null |
| onStart | Todo when start | function | null |
| duration | Per story duration seconds | number | 10 |
| swipeText | Text of swipe component | string | Swipe Up |
| renderSwipeUpComponent | Render a custom swipe up component | function | |
| renderCloseComponent | Render a custom close button | function | |
| renderTextComponent | Render custom avatar text component | function | |
| avatarSize | Size of avatar circle | number | 60 |
| showAvatarText | For show or hide avatar text. | bool | true |
| avatarTextStyle | For avatar text style | TextStyle | |
| avatarImageStyle | For avatar image style | ImageStyle | |
| avatarWrapperStyle | For individual avatar wrapper style | ViewStyle | |
| avatarFlatListProps | Horizontal avatar flat list props | FlatListProps | |
| loadedAnimationBarStyle | For loaded animation bar style | ViewStyle | |
| unloadedAnimationBarStyle | For unloaded animation bar style | ViewStyle | |
| animationBarContainerStyle | For animation bar container style | ViewStyle | |
| storyUserContainerStyle | For story item user container style | ViewStyle | |
| storyImageStyle | For story image style | ImageStyle | |
| storyAvatarImageStyle | For story avatar image style | ImageStyle | |
| storyContainerStyle | For story container style | ViewStyle | |

## Usage

### Basic

```javascript
import InstaStory from 'react-native-insta-story';

Expand Down Expand Up @@ -121,17 +136,36 @@ const handleSeenStories = async (item) => {
}
};

```

### Custom components

The render component functions are all passed `item` as a prop which is the current [IUserStoryItem](./src/interfaces/index.ts#L15) being displayed.

`renderSwipeUpComponent` and `renderCloseComponent` are both passed the `onPress` prop which is a function that closes the current story item modal and calls the `IUserStoryItem.onPress` function. `onPress` is passed so you could add other buttons. This is useful when adding a button which has it's own `onPress` prop, eg. a share button, next to the close button.

`renderTextComponent` is passed the `profileName` of the current story's user.

```javascript
const data = [...sameDataAsBasicExampleAbove];
<InstaStory
data={data}
duration={10}
onStart={(item) => console.log(item)}
onClose={handleSeenStories}
onStorySeen={updateSeenStories}
customSwipeUpComponent={
renderCloseComponent={({ item, onPress }) => (
<View style={{ flexDirection: 'row' }}>
<Button onPress={shareStory}>Share</Button>
<Button onPress={onPress}>X</Button>
</View>
)}
renderTextComponent={({ item, profileName }) => (
<View>
<Text>Swipe</Text>
<Text>{profileName}</Text>
<Text>{item.customProps?.yourCustomProp}</Text>
</View>
}
)}
style={{ marginTop: 30 }}
/>;
```
Expand Down
54 changes: 43 additions & 11 deletions src/Story.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Fragment, useRef, useState, useEffect } from 'react';
import { Dimensions, View, Platform } from 'react-native';
import { Dimensions, View, Platform, StyleSheet } from 'react-native';
import Modal from 'react-native-modalbox';

import StoryListItem from './StoryListItem';
Expand All @@ -9,21 +9,36 @@ import AndroidCubeEffect from './components/AndroidCubeEffect';
import CubeNavigationHorizontal from './components/CubeNavigationHorizontal';
import { IUserStory, NextOrPrevious, StoryProps } from './interfaces';

const { height, width } = Dimensions.get('window');

export const Story = ({
data,
unPressedBorderColor,
pressedBorderColor,
unPressedAvatarTextColor,
pressedAvatarTextColor,
style,
onStart,
onClose,
duration,
swipeText,
customSwipeUpComponent,
customCloseComponent,
avatarSize,
showAvatarText,
avatarTextStyle,
onStorySeen,
renderCloseComponent,
renderSwipeUpComponent,
renderTextComponent,
loadedAnimationBarStyle,
unloadedAnimationBarStyle,
animationBarContainerStyle,
storyUserContainerStyle,
storyImageStyle,
storyAvatarImageStyle,
storyContainerStyle,
avatarImageStyle,
avatarWrapperStyle,
avatarFlatListProps,
}: StoryProps) => {
const [dataState, setDataState] = useState<IUserStory[]>(data);
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
Expand Down Expand Up @@ -103,8 +118,9 @@ export const Story = ({
currentPage={currentPage}
onFinish={onStoryFinish}
swipeText={swipeText}
customSwipeUpComponent={customSwipeUpComponent}
customCloseComponent={customCloseComponent}
renderSwipeUpComponent={renderSwipeUpComponent}
renderCloseComponent={renderCloseComponent}
renderTextComponent={renderTextComponent}
onClosePress={() => {
setIsModalOpen(false);
if (onClose) {
Expand All @@ -113,6 +129,13 @@ export const Story = ({
}}
index={i}
onStorySeen={onStorySeen}
unloadedAnimationBarStyle={unloadedAnimationBarStyle}
animationBarContainerStyle={animationBarContainerStyle}
loadedAnimationBarStyle={loadedAnimationBarStyle}
storyUserContainerStyle={storyUserContainerStyle}
storyImageStyle={storyImageStyle}
storyAvatarImageStyle={storyAvatarImageStyle}
storyContainerStyle={storyContainerStyle}
/>
);
});
Expand Down Expand Up @@ -156,16 +179,17 @@ export const Story = ({
avatarSize={avatarSize}
unPressedBorderColor={unPressedBorderColor}
pressedBorderColor={pressedBorderColor}
unPressedAvatarTextColor={unPressedAvatarTextColor}
pressedAvatarTextColor={pressedAvatarTextColor}
showText={showAvatarText}
textStyle={avatarTextStyle}
avatarTextStyle={avatarTextStyle}
avatarWrapperStyle={avatarWrapperStyle}
avatarImageStyle={avatarImageStyle}
avatarFlatListProps={avatarFlatListProps}
/>
</View>
<Modal
style={{
flex: 1,
height: Dimensions.get('window').height,
width: Dimensions.get('window').width,
}}
style={styles.modal}
isOpen={isModalOpen}
onClosed={() => setIsModalOpen(false)}
position="center"
Expand All @@ -180,6 +204,14 @@ export const Story = ({
);
};

const styles = StyleSheet.create({
modal: {
flex: 1,
height,
width,
},
});

export default Story;

Story.defaultProps = {
Expand Down
35 changes: 24 additions & 11 deletions src/StoryCircleListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ const StoryCircleListItem = ({
item,
unPressedBorderColor,
pressedBorderColor,
unPressedAvatarTextColor,
pressedAvatarTextColor,
avatarSize = 60,
showText,
textStyle,
avatarTextStyle,
handleStoryItemPress,
avatarImageStyle,
avatarWrapperStyle,
}: StoryCircleListItemProps) => {
const [isPressed, setIsPressed] = useState(item?.seen);

Expand Down Expand Up @@ -51,6 +55,7 @@ const StoryCircleListItem = ({
height: avatarWrapperSize,
width: avatarWrapperSize,
},
avatarWrapperStyle,
!isPressed
? {
borderColor: unPressedBorderColor ?? 'red',
Expand All @@ -61,11 +66,14 @@ const StoryCircleListItem = ({
]}
>
<Image
style={{
height: avatarSize,
width: avatarSize,
borderRadius: 100,
}}
style={[
{
height: avatarSize,
width: avatarSize,
borderRadius: 100,
},
avatarImageStyle,
]}
source={{ uri: item.user_image }}
defaultSource={Platform.OS === 'ios' ? DEFAULT_AVATAR : null}
/>
Expand All @@ -74,11 +82,16 @@ const StoryCircleListItem = ({
<Text
numberOfLines={1}
ellipsizeMode="tail"
style={{
width: avatarWrapperSize,
...styles.text,
...textStyle,
}}
style={[
{
width: avatarWrapperSize,
...styles.text,
...avatarTextStyle,
},
isPressed
? { color: pressedAvatarTextColor || undefined }
: { color: unPressedAvatarTextColor || undefined },
]}
>
{item.user_name}
</Text>
Expand Down
70 changes: 44 additions & 26 deletions src/StoryCircleListView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { View, FlatList } from 'react-native';
import { View, FlatList, StyleSheet } from 'react-native';
import StoryCircleListItem from './StoryCircleListItem';
import { StoryCircleListViewProps } from 'src/interfaces';

Expand All @@ -8,36 +8,54 @@ const StoryCircleListView = ({
handleStoryItemPress,
unPressedBorderColor,
pressedBorderColor,
unPressedAvatarTextColor,
pressedAvatarTextColor,
avatarSize,
showText,
textStyle,
avatarTextStyle,
avatarImageStyle,
avatarWrapperStyle,
avatarFlatListProps,
}: StoryCircleListViewProps) => {
return (
<View>
<FlatList
keyExtractor={(_item, index) => index.toString()}
data={data}
horizontal
style={{ paddingLeft: 12 }}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
ListFooterComponent={<View style={{ flex: 1, width: 8 }} />}
renderItem={({ item, index }) => (
<StoryCircleListItem
avatarSize={avatarSize}
handleStoryItemPress={() =>
handleStoryItemPress && handleStoryItemPress(item, index)
}
unPressedBorderColor={unPressedBorderColor}
pressedBorderColor={pressedBorderColor}
item={item}
showText={showText}
textStyle={textStyle}
/>
)}
/>
</View>
<FlatList
keyExtractor={(_item, index) => index.toString()}
data={data}
horizontal
style={styles.paddingLeft}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
ListFooterComponent={<View style={styles.footer} />}
renderItem={({ item, index }) => (
<StoryCircleListItem
avatarSize={avatarSize}
handleStoryItemPress={() =>
handleStoryItemPress && handleStoryItemPress(item, index)
}
unPressedBorderColor={unPressedBorderColor}
pressedBorderColor={pressedBorderColor}
unPressedAvatarTextColor={unPressedAvatarTextColor}
pressedAvatarTextColor={pressedAvatarTextColor}
item={item}
showText={showText}
avatarTextStyle={avatarTextStyle}
avatarImageStyle={avatarImageStyle}
avatarWrapperStyle={avatarWrapperStyle}
/>
)}
{...avatarFlatListProps}
/>
);
};

const styles = StyleSheet.create({
paddingLeft: {
paddingLeft: 12,
},
footer: {
flex: 1,
width: 8,
},
});

export default StoryCircleListView;
Loading

0 comments on commit af287b4

Please sign in to comment.