npm package: @saleassist/reels
Description: React Native SDK to display shoppable video tiles from SaleAssist.
Author: saleassist
Latest version: 0.2.5

# @saleassist/reels

[![npm version](https://img.shields.io/npm/v/@saleassist/reels.svg?style=flat)](https://www.npmjs.com/package/@saleassist/reels)
[![SaleAssist](https://img.shields.io/badge/SaleAssist-Platform-black.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABsSURBVDhP7dDBCYAwDAXQdBRHcRRHcRRHcZRO4iiO4iiO0lEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVEcxVH8Bz4sA5X5eAAAAABJRU5ErkJggg==&style=flat)](https://www.saleassist.ai/)

React Native SDK to display **shoppable video tiles** from [SaleAssist](https://saleassist.ai).  
A high-performance React Native component for short-form video content with built-in engagement and conversion capabilities.

---

## ✨ Features

- 🎥 **Multiple view types**: Tile, Grid, Coverflow, Story
- 🛍️ **Built-in product integration** with CTAs
- 🔄 **Auto-play & looping** videos
- 📱 **Cross-platform** (iOS & Android)
- 🎨 **Customizable** themes & layouts
- ⚡ **Optimized** for smooth scrolling
- 🔧 Works with both **Expo** and **React Native CLI**

---

## 📦 Installation

### React Native CLI

```sh
npm install @saleassist/reels react-native-video

npm i @gumlet/insights-react-native react-native-crypto react-native-device-info @react-native-async-storage/async-storage react-native-uuid react-native-url-polyfill --legacy-peer-deps

npx pod-install  # iOS only
```

### Expo

```sh
npm install @saleassist/reels
npx expo install expo-video
```

---

## ⚠️ Troubleshooting: React Native < 0.81

If you're using **React Native version 0.81 or below** and encounter errors after installing `react-native-video` or `@gumlet/insights-react-native`, add this initialization code at the **top of your app's entry file** (e.g., `index.js` or `App.js`):

```jsx
import Video from 'react-native-video';

const initVideo = () => {
  try {
    global.ReactNativeVideo = Video;
    try {
      const gumletModule = require('@gumlet/insights-react-native');
      const GumletVideo = gumletModule.default 
        ? gumletModule.default(Video) 
        : gumletModule(Video);
      global.GumletVideo = GumletVideo;
    } catch (gumletError) {
      global.GumletVideo = Video;
    }
  } catch (error) {
    console.log('RN 0.73 setup error:', error);
  }
};

initVideo();
```

---

## 🚀 Usage

### Basic Example

```jsx
import { SaleAssistReels } from "@saleassist/reels";

const App = () => {
  return (
    <SaleAssistReels
      playlistId="your-playlist-id"
      videoViewtype="tileView"
      autoPlay={true}
    />
  );
};
```

### Advanced Example with Navigation

Handle CTA and product clicks by implementing callback functions:

```jsx
import { SaleAssistReels } from "@saleassist/reels";
import { useNavigation } from '@react-navigation/native';

const YourComponent = () => {
  const navigation = useNavigation();
  
  // Extract product ID from URL pattern: "ProductDetails/abc123"
  const extractProductIdFromUrl = (url) => {
    try {
      let match = url.match(/ProductDetails\/([^\/\?#]+)/);
      return match ? match[1] : null;
    } catch (error) {
      console.error("Error extracting product ID:", error);
      return null;
    }
  };

  // Handle CTA button clicks (e.g., "Buy Now", "Shop Now")
  const handleCTAPress = (data) => {
    const { url, ctaText } = data;
    
    // Navigate to product details
    if (url && url.includes("ProductDetails/")) {
      const productId = extractProductIdFromUrl(url);
      const product = products.find((p) => p.id === productId);
      navigation.navigate("ProductDetails", { product });
    } 
    // Navigate to category page
    else if (url && url.includes("/category/")) {
      const categoryId = url.split("/category/")[1];
      navigation.navigate("Category", { category: categoryId });
    } 
    // Navigate to external URL in WebView
    else if (url) {
      navigation.navigate("WebView", { url });
    }
  };

  // Handle product tap in video
  const handleProductPress = (data) => {
    const { url, ctaText } = data;
    
    // Handle string URL with product ID
    if (url && typeof url === "string" && url.includes("ProductDetails/")) {
      const productId = extractProductIdFromUrl(url);
      const product = products.find((p) => p.id === productId);
      navigation.navigate("ProductDetails", { product });
    } 
    // Handle direct product object
    else if (url && typeof url === "object" && url.id) {
      navigation.navigate("ProductDetails", { product: url });
    } 
    // Fallback to WebView
    else if (url) {
      navigation.navigate("WebView", { url });
    }
  };

  return (
    <SaleAssistReels
      playlistId="your-playlist-id"
      videoViewtype="tileView"
      autoPlay={true}
      borderRadius={10}
      seperatorWidth={8}
      tileSize={{ width: 160, height: 250 }}
      onCTAPress={handleCTAPress}
      onProductPress={handleProductPress}
      storyCaption={true}
    />
  );
};
```

---

## ⚙️ Props

| Prop             | Type     | Default                       | Description                                                |
|------------------|----------|-------------------------------|------------------------------------------------------------|
| **playlistId** ⚠️ | `string` | —                             | **Required.** Your SaleAssist playlist ID                  |
| `videoViewtype`  | `string` | `'tileView'`                  | View mode: `'tileView'` \| `'gridView'` \| `'coverflowView'` \| `'storyView'` |
| `autoPlay`       | `boolean`| `false`                       | Auto-play videos when visible                              |
| `borderRadius`   | `number` | `12`                          | Border radius for video tiles (in pixels)                  |
| `seperatorWidth` | `number` | `16`                          | Space between items (in pixels)                            |
| `tileSize`       | `object` | `{ width: 180, height: 280 }` | Dimensions of video tiles                                  |
| `onCTAPress`     | `function` | —                           | Callback fired when CTA button is pressed                  |
| `onProductPress` | `function` | —                           | Callback fired when a product is pressed                   |
| `storyCaption`   | `boolean`| `true`                        | Show/hide story captions                                   |

---

## 📊 Analytics Disclaimer

**Analytics support is currently available only for React Native CLI applications.**  
Expo applications do not support analytics at this time.

---

## 📸 Preview

### View Types

| Tile View | Grid View | Story View | Coverflow View |
|-----------|-----------|------------|----------------|
| <img width="120" height="254" alt="Tile View" src="https://client-static.saleassist.ai/10b07b83-c8e3-4b74-8c06-3eb5923794af/tileView" /> | <img width="120" height="254" alt="Grid View" src="https://client-static.saleassist.ai/10b07b83-c8e3-4b74-8c06-3eb5923794af/gridView" /> | <img width="120" height="254" alt="Story View" src="https://client-static.saleassist.ai/10b07b83-c8e3-4b74-8c06-3eb5923794af/Storyview" /> | <img width="120" height="254" alt="Coverflow View" src="https://client-static.saleassist.ai/10b07b83-c8e3-4b74-8c06-3eb5923794af/coverflow" /> |

---

## 📄 License

MIT © [SaleAssist](https://saleassist.ai)

---

## 🔗 Resources

- [SaleAssist Platform](https://www.saleassist.ai/)
- [npm Package](https://www.npmjs.com/package/@saleassist/reels)
- [React Native Documentation](https://reactnative.dev)

---

_Made with ❤️ using [create-react-native-library](https://github.com/callstack/react-native-builder-bob)_