🚀 An Instagram Stories like component.
- Use Case
- Compatibility
- Installation
- Example Usage
- Component API
- Customization
- TODOs
- Issues
- Contributing
- License
You need a component for rendering Instagram like stories.
Since this library does internal use of hooks you need React >= 16.8.0
.
You can install this library via NPM or YARN.
npm i @blackbox-vision/react-native-live-stories
yarn add @blackbox-vision/react-native-live-stories
We rely on the following packages:
- react-native-video-cache
- react-native-fast-image
- react-native-video
- react-native-elements
- react-native-snap-carousel
- react-native-vector-icons
- react-native-linear-gradient
You can install all of them by running the next command:
npm i react-native-elements react-native-video react-native-snap-carousel react-native-vector-icons react-native-linear-gradient react-native-fast-image react-native-video-cache
If in your android builds you've proguard enabled, you will need to add the following config in proguard-rules.pro
:
-keep public class com.dylanvann.fastimage.* {*;}
-keep public class com.dylanvann.fastimage.** {*;}
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
For built-in caching we use react-native-video-cache library, which needs a little adjustment in the android manifest in order to work.
You need to add the property android:usesCleartextTraffic="true"
in your application in AndroidManifest.xml
.
After reading and performing the previous steps, you should be able to import the library and use it like in this example:
// insta-stories.js
import { Text } from 'react-native';
import React, { useState } from 'react';
import { StoryPreview } from '@blackbox-vision/react-native-live-stories';
const stories = [
{
id: 1,
viewed: false,
preview:
'https://instagram.faep7-1.fna.fbcdn.net/v/t51.2885-19/s320x320/62500940_1363897577094116_5145198214462308352_n.jpg?_nc_ht=instagram.faep7-1.fna.fbcdn.net&_nc_ohc=BkIQomknhK0AX_1xEiM&oh=2269fb6e76910915456b7bb6ff24a282&oe=5FBFFDA9',
video: 'https://www.w3schools.com/html/mov_bbb.mp4',
},
{
id: 2,
viewed: false,
preview:
'https://instagram.faep7-1.fna.fbcdn.net/v/t51.2885-19/s320x320/62500940_1363897577094116_5145198214462308352_n.jpg?_nc_ht=instagram.faep7-1.fna.fbcdn.net&_nc_ohc=BkIQomknhK0AX_1xEiM&oh=2269fb6e76910915456b7bb6ff24a282&oe=5FBFFDA9',
video: 'https://vjs.zencdn.net/v/oceans.mp4',
},
{
id: 3,
viewed: false,
preview:
'https://instagram.faep7-1.fna.fbcdn.net/v/t51.2885-19/s320x320/62500940_1363897577094116_5145198214462308352_n.jpg?_nc_ht=instagram.faep7-1.fna.fbcdn.net&_nc_ohc=BkIQomknhK0AX_1xEiM&oh=2269fb6e76910915456b7bb6ff24a282&oe=5FBFFDA9',
video: 'https://vjs.zencdn.net/v/oceans.mp4',
},
];
const InstaStories = (props) => {
const onStoryDetailItemNext = (story, idx) => {
console.info('Moving to next story', story, ' at index ', idx);
};
const onStoryDetailBackPress = (story, idx) => {
console.info('Going back from story', story, ' at index ', idx);
};
const onStoryPreviewItemPress = (story, idx) => {
console.info('Clicking story preview for story', story, ' at index ', idx);
};
const getStoryPreviewItemProps = (story, idx) => ({
shouldAnimate: !story.viewed,
});
return (
<StoryPreview
stories={stories}
onStoryDetailItemNext={onStoryDetailItemNext}
onStoryDetailBackPress={onStoryDetailBackPress}
onStoryPreviewItemPress={onStoryPreviewItemPress}
getStoryPreviewItemProps={getStoryPreviewItemProps}
/>
);
};
The StoryPreview
component has the following props:
Properties | Types | Default Value | Description |
---|---|---|---|
style | ViewStyle |
none | Styles for FlatList mini stories container |
stories | array | [] | An array of stories to be rendered |
StoryDetailItemHeader | component | none | Component for Header in Story Detail Item |
StoryDetailItemFooter | component | none | Component for Footer in Story Detail Item |
onStoryDetailItemNext | function | none | Callback fired when drag to next item |
onStoryDetailBackPress | function | none | Callback fired when on back button press |
onStoryPreviewItemPress | function | none | Callback fired when performed click on preview |
getStoryPreviewItemProps | function | none | Callback to get story preview item props dynamically |
We provide some sort of customization by passing some components that can override the defaults from the library.
For now, we only give the ability to customize the followings components:
- Story Header
- Story Footer
You can pass to the StoryPreview
the component prop StoryDetailItemHeader
that will replace the Header
shipped by default.
Example Header:
import React from 'react';
import { Text } from 'react-native';
export const StoryHeader = ({
mute,
muted,
story,
goBack,
duration,
progress,
}) => <Text>I am the header</Text>;
StoryHeader.displayName = 'StoryHeader';
You can pass to the StoryPreview
the component prop StoryDetailItemFooter
that will replace the Footer
shipped by default.
Example Footer:
import React from 'react';
import { Text } from 'react-native';
export const StoryFooter = ({
mute,
muted,
story,
goBack,
duration,
progress,
}) => <Text>I am the footer</Text>;
StoryFooter.displayName = 'StoryFooter';
With this library we're intended to have you covered when trying to implement stories into a React Native app.
As part of our efforts we've a very stable code by now, but we need to improve much things in order to reach a stable release.
Here is a list of things we need to do:
- Re-define story attributes to support passing more information.
- Improve grow animation to behave like Insta one.
- Add support for loading effect in Previews like Insta.
- Add support for rendering multiple same user stories.
- Add support for rendering initial preview with a CTA.
- Ship with a default Header and Footer in the story that looks like Instagram ones.
Please, open an issue following one of the issues templates. We will do our best to fix them.
If you want to contribute to this project see contributing for more information.
Distributed under the MIT license. See LICENSE for more information.