
This library provides status/stories features like Instagram/WhatsApp or other social media, It is simple to use and fully customizable. It works on both android and iOS platforms.
Installation | StoryView | Usage | Props | Example | License
$ npm install react-native-story-view
# --- or ---
$ yarn add react-native-story-view
$ npm install react-native-video react-native-reanimated react-native-gesture-handler react-native-video-cache-control @shopify/flash-list lodash
# --- or ---
$ yarn add react-native-video react-native-reanimated react-native-gesture-handler react-native-video-cache-control @shopify/flash-list lodash
Note: If you already have these libraries installed and at the latest version, you are done here!
cd ios && pod install
Note: Make sure to add Reanimated's babel plugin to your
babel.config.js
module.exports = {
...
plugins: [
...
'react-native-reanimated/plugin',
],
};
In your project's
android/app/build.gradle
dependencies {
implementation 'com.danikula:videocache:2.7.1'
// Your rest of the code
}
In your project's
android/build.gradle
buildscript {
// Your rest of the code
}
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
jcenter()
}
}
Android:
If you're facing issue related to 'android-scalablevideoview' or 'videocache' module not found. Add this code in android's build.gradle
jcenter() {
content {
includeModule("com.yqritc", "android-scalablevideoview")
includeModule("com.danikula", "videocache")
}
}
![]() |
|
StoryView is divided into several components, MultiStory is the root component. ProfileHeader and Footer are individual components for header and footer. StoryContainer internally used for rendering Story. We'll look usage and customization of all these.
Checkout Multi Story Example here
Checkout Stories Data Format here
Checkout Single Story Example here
Define the users' stories array in the below format. There will be multiple users and multiple stories inside.
const userStories = [
{
id: 1, //unique id (required)
username: 'Alan', //user name on header
title: 'Albums', //title below username
profile: 'https://sosugary.com/wp-content/uploads/2022/01/TheWeeknd_001.jpg', //user profile picture
stories: [
{
id: 0, //unique id (required)
url: 'https://i1.sndcdn.com/artworks-IrhmhgPltsdrwMu8-thZohQ-t500x500.jpg', // story url
type: 'image', //image or video type of story
duration: 5, //default duration
storyId: 1,
isSeen: false,
showOverlay: true, // to show overlay component
link: 'https:google.com', // to handle navigation in overlay component
},
{
id: 1,
url: 'https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
type: 'video',
duration: 15,
storyId: 1,
isSeen: false,
},
],
},
{
id:2,
username: 'Weekend',
...
}
]
![]() |
|
This is the root component of StoryView package. It displays horizontal list of users with pre-defined ui from StoryAvatar component and uses animated flatlist under the hood to display stories. StoryContainer is used under the hood for story so all customization can be done from storyContainerProps.
const multiStoryRef = useRef<MultiStoryRef>(null);
<MultiStory
stories={stories}
ref={multiStoryRef}
avatarProps={{
userNameStyle: { fontSize: 16 },
}}
// all StoryContainer props applies here
storyContainerProps={{
renderHeaderComponent: ({ userStories, progressIndex, userStoryIndex }) => (
<Header {...{ userStories, progressIndex, multiStoryRef }} />
),
renderFooterComponent: ({ userStories, progressIndex, userStoryIndex }) => (
<Footer {...{ userStories }} />
),
barStyle: {
barActiveColor: Colors.red,
},
}}
/>;
Checkout Multi Story Example here
![]() |
This is an individual component, To display user details on header like instagram/whatsapp. In renderHeaderComponent of StoryContainer, Custom component can be assigned.
For MultiStory, renderHeaderComponent receives progressIndex, userStories, story and userStoryIndex for getting current user data.
const multiStoryRef = useRef(null);
<MultiStory
ref={multiStoryRef}
storyContainerProps={{
renderHeaderComponent: ({
userStories,
story,
progressIndex,
userStoryIndex,
}) => (
<ProfileHeader
userImage={{ uri: userStories?.profile ?? '' }}
userName={userStories?.username}
userMessage={userStories?.title}
onClosePress={() => {
multiStoryRef?.current?.close?.();
}}
/>
),
}}
/>;
![]() |
|
This is an individual component, To display footer like instagram. Any TextInput props can be directly passed to Footer. In renderFooterComponent of StoryContainer, Custom component can be assigned.
<MultiStory
storyContainerProps={{
renderFooterComponent: ({
userStories,
story,
progressIndex,
userStoryIndex,
}) => (
<Footer
onIconPress={() => {
console.log('Share icon clicked');
}}
onSendTextPress={() => {
console.log('Message sent');
}}
shouldShowSendImage={true}
shouldShowTextInputSend={true}
placeholder="Enter Message"
/>
),
}}
/>
This is the core component of StoryView, which provides all functionality of story view and customization. It is used to render all stories in MultiStory. This component is just for reference how storyContainerProps in MultiStory being passed in this component internally.
const [isStoryViewVisible, setIsStoryViewShow] = useState(false);
<StoryContainer
visible={isStoryViewVisible}
extended={true}
// extended enables play & pause feature on single story view default is "true"
maxVideoDuration={10}
stories={userStories[0].stories}
renderFooterComponent={({ story, progressIndex }) => (
<Footer
onSendTextPress={() => {
Alert.alert(`Current Story id ${story?.[progressIndex].id} `);
Keyboard.dismiss();
}}
onIconPress={() => {
Alert.alert('Current Story progress index' + progressIndex);
}}
/>
)}
renderHeaderComponent={({ story, progressIndex }) => (
<ProfileHeader
userImage={{ uri: userStories[0]?.profile ?? '' }}
userName={userStories[0]?.username}
userMessage={userStories[0]?.title}
onImageClick={() => {}}
onClosePress={() => setIsStoryViewShow(false)}
/>
)}
//Callback when all stories completes
onComplete={() => setIsStoryViewShow(false)}
/>;
MultiStory is wrapper on this component with extra horizontal user list UI of StoryAvatar. If MultiStory's horizontal list customisation is not sufficient for any use-case, use this base component and add your own customised horizontal user list UI.
|
const [isStoryViewVisible, setIsStoryViewShow] = useState(false);
const [pressedIndex, setPressedIndex] = useState<number>(0);
const openStories = (index: number) => {
setIsStoryViewShow(true);
setPressedIndex(index);
};
<View style={styles.container}>
<FlatList
horizontal
data={userStories}
keyExtractor={item => item?.id?.toString()}
renderItem={({ item, index }) => (
<Pressable onPress={() => openStories(index)}>
<CustomStoryAvatar {...{ item, index }} />
</Pressable>
)}
/>
{isStoryViewVisible && (
// add other StoryContainer Props
<MultiStoryContainer
visible={isStoryViewVisible}
onComplete={() => setIsStoryViewShow(false)}
stories={userStories}
renderHeaderComponent={...}
renderFooterComponent={...}
userStoryIndex={pressedIndex}
/>
)}
</View>
![]() |
ProgressBar customisation can be controlled through StoryContainer itself. enableProgress to make visible the progressbar.progressIndex to start story from any index. barStyle to customize look feel of progressbar.onChangePosition trigger when progressbar index will change returns current index.
<MultiStory
storyContainerProps={{
enableProgress: true,
//Callback when progressbar index changes
onChangePosition: position => {},
barStyle: {
barHeight: 2,
barInActiveColor: 'green',
barActiveColor: 'grey',
},
maxVideoDuration: 25,
progressIndex: 0,
}}
/>
![]() |
Pass any custom view in story view. It will be rendered on top of story view as it has an absolute position. In renderCustomView of StoryContainer, Any custom component can be assigned.
<MultiStory
storyContainerProps={{
renderCustomView: () => (
<View
style={{
position: 'absolute',
top: 40,
right: 50,
}}>
<Image
source={Images.star}
style={{
height: 25,
width: 25,
tintColor: 'green',
}}
/>
</View>
),
}}
/>
$ claude mcp add react-native-story-view \
-- python -m otcore.mcp_server <graph>