Wrapper for InAppStory
npm install @inappstory/react-native-sdkor
yarn add @inappstory/react-native-sdkYou need to install pods with static frameworks, use USE_FRAMEWORKS = 'static' or have this in your Podfile:
use_frameworks! :linkage => :staticMake sure you update your Android SDK versions in build.gradle
minSdkVersion = 23
compileSdkVersion = 34
targetSdkVersion = 34
Import InAppStory SDK in MainApplication
import com.inappstorysdk.InAppStory;Add following code to onCreate() function
InAppStory.initSDK(getApplicationContext())To use the library, create StoryService.ts, configure storyManagerConfig with your API key and adjust appearanceManager styles
import {
AppearanceManager,
StoriesListCardTitlePosition,
StoriesListCardViewVariant,
StoryManager,
StoryReaderCloseButtonPosition,
StoryReaderSwipeStyle,
StoriesListCardTitleTextAlign,
type StoryManagerConfig,
} from '@inappstory/react-native-sdk';
import { Linking } from 'react-native';
const storyManagerConfig: StoryManagerConfig = {
apiKey: 'test-key',
userId: '1',
tags: [],
placeholders: {
username: 'Guest',
},
lang: 'en',
defaultMuted: true,
};
const createStoryManager = () => {
const storyManager = new StoryManager(storyManagerConfig);
storyManager.getGoodsCallback((skus: string[]) => {
//TODO: Fetch goods information
return skus.map((sku) => ({
sku: sku, //item sku
title: 'title of ' + sku, //item title for cell
subtitle: 'subtitle of ' + sku, //item subtitle for cell
imageURL: 'URL', //image url for cell
price: Number(Math.random() * 1000).toFixed(2), //price value for cell
oldPrice: Number(Math.random() * 1000).toFixed(2),
}));
});
storyManager.on('clickOnStory', (payload: any) =>
console.log('clickOnStory', { payload })
);
storyManager.on('showStory', (payload: any) =>
console.log('showStory', { payload })
);
storyManager.on('closeStory', (payload: any) =>
console.log('closeStory', { payload })
);
storyManager.on('showSlide', (payload: any) =>
console.log('showSlide', { payload })
);
storyManager.on('clickOnButton', (payload: any) =>
console.log('clickOnButton', { payload })
);
storyManager.on('likeStory', (payload: any) =>
console.log('likeStory', { payload })
);
storyManager.on('dislikeStory', (payload: any) =>
console.log('dislikeStory', { payload })
);
storyManager.on('favoriteStory', (payload: any) =>
console.log('favoriteStory', { payload })
);
storyManager.on('shareStory', (payload: any) =>
console.log('shareStory', { payload })
);
storyManager.on('shareStoryWithPath', (payload: any) =>
console.log('shareStoryWithPath', { payload })
);
// btn handler
storyManager.storyLinkClickHandler = (payload: any) => {
console.log({ payload });
if (payload.data.url != null) {
Linking.openURL(payload.data.url);
}
};
return storyManager;
};
const createAppearanceManager = () => {
return new AppearanceManager()
.setCommonOptions({
hasLike: true,
hasLikeButton: true,
hasDislikeButton: false,
hasFavorite: true,
hasShare: true,
})
.setStoriesListOptions({
card: {
title: {
font: 'bold normal 14px/16px "InternalPrimaryFont"',
padding: '0px 0 0 0',
fontSize: 12,
fontWeight: 600,
fontFamily: Platform.OS == 'ios' ? 'Bradley Hand' : 'Comic Sans',
lineHeight: 13,
lineClamp: 3,
textAlign: StoriesListCardTitleTextAlign.LEFT,
position: StoriesListCardTitlePosition.CARD_INSIDE_BOTTOM,
},
gap: 3,
height: 150,
variant: StoriesListCardViewVariant.RECTANGLE,
border: {
radius: 1,
color: 'black',
width: 2,
gap: 1,
},
boxShadow: null,
opacity: 1,
mask: {
color: 'rgba(34, 34, 34, 0.3)',
},
opened: {
border: {
radius: 0,
color: 'red',
width: 0,
gap: 0,
},
boxShadow: null,
opacity: 1,
mask: {
color: 'rgba(34, 34, 34, 0.1)',
},
},
},
favoriteCard: {
title: {
content: 'Saved',
},
},
layout: {
height: 0,
backgroundColor: 'transparent',
},
sidePadding: 5,
topPadding: 5,
bottomPadding: 2,
navigation: {
showControls: false,
controlsSize: 48,
controlsBackgroundColor: 'white',
controlsColor: 'black',
},
})
.setStoryReaderOptions({
closeButtonPosition: StoryReaderCloseButtonPosition.RIGHT,
scrollStyle: StoryReaderSwipeStyle.FLAT,
slideBorderRadius: 5,
})
.setStoryFavoriteReaderOptions({
title: {
content: 'Favorite',
font: '1.6rem/1.4 InternalPrimaryFont',
color: 'white',
},
});
};
export const storyManager = createStoryManager();
export const appearanceManager = createAppearanceManager();To display feed, use StoriesList component. storiesListViewModel allows to reload the story feed using storiesListViewModel.current.reload().
import { StoriesList } from '@inappstory/react-native-sdk';
import {
type StoriesListViewModel,
} from '@inappstory/react-native-sdk';
...
const storiesListViewModel = React.useRef<StoriesListViewModel>();
const viewModelExporter = React.useCallback(
(viewModel: StoriesListViewModel) =>
(storiesListViewModel.current = viewModel),
[]
);
...
<StoriesList
storyManager={storyManager}
appearanceManager={appearanceManager}
feed={feedId}
onLoadStart={onLoadStart}
onLoadEnd={onLoadEnd}
viewModelExporter={viewModelExporter}
/>;If you use favorites, use onFavoriteCell event that fires when user clicks on favorites cell
storyManager.on('onFavoriteCell', () => {
//Navigate to favorites screen
});To display favorite stories, pass favoritesOnly to
<StoriesList favoritesOnly={true} />To display items vertically, use vertical=true
<StoriesList vertical={true} />To render custom cells, add renderCell function to StoriesList
<StoriesList
...props
renderCell={(story, {isFirstItem, isLastItem}) => {
return <Text>{story.storyID}</Text>;
}}
/>InAppStorySDK.showGame(gameID);InAppStorySDK.setTags(['tag1']);InAppStorySDK.setPlaceholders({ username: 'John Doe' });InAppStorySDK.setImagesPlaceholders({
image1: 'https://example.com/image.jpg',
});InAppStorySDK.setOverScrollToClose(value);
InAppStorySDK.setSwipeToClose(value);
InAppStorySDK.setTimerGradientEnable(value);
InAppStorySDK.setCloseButtonPosition(value);
InAppStorySDK.setScrollStyle(value);
InAppStorySDK.setPresentationStyle(value);
InAppStorySDK.setReaderBackgroundColor(value);
InAppStorySDK.setReaderCornerRadius(value);InAppStorySDK.setHasLike(value);
InAppStorySDK.setHasShare(value);
InAppStorySDK.setHasFavorites(value);//To change sound settings
InAppStorySDK.changeSound(value);
//Get sound status
const soundEnabled = await InAppStorySDK.getSound();To use goods widget, add a function that returns products to getGoodsObject
storyManager.getGoodsObject((skus) => {
//TODO: return array of Goods
return skus.map((sku) => ({
sku: sku, //item sku
title: 'title of ' + sku, //item title for cell
subtitle: 'subtitle of ' + sku, //item subtitle for cell
imageURL: '', //image url for cell
price: Number(Math.random() * 1000).toFixed(2), //price value for cell
oldPrice: Number(Math.random() * 1000).toFixed(2),
}));
});After goods item is selected,
storyManager.on('goodItemSelected', (payload: any) => {
// User selected payload.sku SKU
});The app version is used by the platform to enable targeting of stories by app versions.
By default, IAS-SDK uses appVersion and appBundle from the native part of the application.
But you can override appVersion and appBundle via StoryManagerConfig.
This might be useful for CodePush users.
const storyManagerConfig: StoryManagerConfig = {
apiKey,
appVersion: {
version: '3.0.0',
build: 777,
},
};
const storyManager = new StoryManager(storyManagerConfig);To subscribe to events, use storyManager.on or storyManager.once
storyManager.on(eventName, (payload) => {
console.log(eventName, payload);
});| Event Name | |||
|---|---|---|---|
| storiesLoaded | |||
| ugcStoriesLoaded | |||
| clickOnStory | {id: String, feed: String, index: Number} | ||
| showStory | {id: String, feed: String, action: String} | ||
| closeStory | {id: String, feed: String, index: Number, action: String} | ||
| clickOnButton | |||
| showSlide | {id: String, index: Number} | ||
| likeStory | {id: String, feed: String, value: Boolean} | ||
| dislikeStory | {id: String, feed: String, value: Boolean} | ||
| favoriteStory | {id: String, feed: String, value: Boolean} | ||
| clickOnShareStory | |||
| storyWidgetEvent | {id: String, feed: String, name: String, data: String } |
| Event | Payload | ||
|---|---|---|---|
| storyListUpdate | {stories: [StoryData]} | ||
| storyUpdate | StoryData | ||
| favoritesUpdate | {} | ||
| favoriteCellDidSelect | {} | ||
| editorCellDidSelect | {} | ||
| favoritesUpdate | {} |
| Event | |||
|---|---|---|---|
| storyReaderWillShow | {type: String} | ||
| storyReaderDidClose | {type: String} | ||
| storiesDidUpdated | {isContent: String, storyType: String} | ||
| scrollUpdate | {index: String} |
| Event | |||
|---|---|---|---|
| sessionFailure | {message: String} | ||
| storyFailure | {message: String} | ||
| currentStoryFailure | {message: String} | ||
| networkFailure | {message: String} | ||
| requestFailure | {message: String, statusCode: String} |
| Event | Payload | ||
|---|---|---|---|
| startGame | {id: String, gameID: String} | ||
| finishGame | {id: String, gameID: String, result: String} | ||
| closeGame | {id: String, gameID: String} | ||
| eventGame | {id: String, gameID: String, name: String, payload: Object} | ||
| gameFailure | {id: String, gameID: String, message: String} | ||
| gameReaderWillShow | {} | ||
| gameReaderDidClose | {} | ||
| gameComplete | {data: Object, result: String, url: String} |
| Event | Payload | ||
|---|---|---|---|
| goodItemSelected | {sku: String} |
| Event | |||
|---|---|---|---|
| customShare | |||
| onActionWith |
-
Add images to your project assets
-
Configure required InAppStorySDK icons before showing stories:
InAppStorySDK.setLikeImage(image, activeImage);
InAppStorySDK.setDislikeImage(image, activeImage);
InAppStorySDK.setFavoriteImage(image, activeImage);
InAppStorySDK.setShareImage(image, activeImage);
InAppStorySDK.setSoundImage(image, activeImage);
InAppStorySDK.setCloseReaderImage(image);
InAppStorySDK.setRefreshImage(image);
InAppStorySDK.setRefreshGoodsImage(image);
InAppStorySDK.setCloseGoodsImage(image);image and activeImage parameters are the names of the images in your assets folder.
InAppStorySDK.setLikeImage('like', 'likeSelected');Breaking changes:
- Font settings are defined using separate variables (fontSize, fontWeight, fontFamily) instead of a string
- If you used svgMask in appearance manager, try to use custom cells to achieve same results.
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
Made with create-react-native-library