Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,6 @@ android/generated

# React Native Nitro Modules
nitrogen/

# nodejs version
.tool-versions
48 changes: 35 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@

## Dependency

- @react-native-async-storage/async-storage: ^2.1.1
- react-native-document-picker: ^9.3.1
- react-native-svg: ^15.11.2
This package relies on several peer dependencies that must already exist in your host app:

- `@react-native-async-storage/async-storage`: ^2.1.1
- `react-native-document-picker`: ^9.3.1
- `react-native-svg`: ^15.11.2

Because they are peer dependencies, they **must** be installed in the consumer app in addition to the widget.

## Installation

Expand All @@ -18,9 +21,22 @@
yarn add @qiscus-community/react-native-multichannel-widget

# Dependencies required for qiscus multichannel
yarn add @react-native-async-storage/async-storage react-native-document-picker
yarn add @react-native-async-storage/async-storage react-native-document-picker react-native-svg
```

### Native setup

All three peer dependencies contain native code. React Native autolinking will register them on iOS and Android, but you still have to complete the platform build steps:

1. iOS
- Run `cd ios && pod install && cd ..` to install the pods produced by the packages above.
- Ensure your Podfile uses `use_frameworks! :linkage => :static` or the default CocoaPods linking mode so `RNSVG`, `RNDocumentPicker`, and `RNAsyncStorage` are compiled into the app.
2. Android
- No manual linking is needed (RN >= 0.63), but you must re-run Gradle after dependencies change: `cd android && ./gradlew clean && cd ..` or rebuild from Android Studio.
- Confirm that your app already requests the runtime permissions required by `react-native-document-picker` (e.g. READ/WRITE external storage if you support Android versions that still need them). The library will prompt users, but the permissions must exist in `AndroidManifest.xml`.

After these steps, rebuild the native app (Xcode/Android Studio or `yarn ios` / `yarn android`) so the widget can access the peer dependencies.

## How To Use

### Initialization
Expand Down Expand Up @@ -158,7 +174,7 @@ Channel Id is an identity for each widget channel. If you have a specific widget
1. **Get your APPID**

- Go to [Qiscus Multichannel Chat page](https://multichannel.qiscus.com/) to register your email
- Log in to Qiscus Multichannel Chat with yout email and password
- Log in to Qiscus Multichannel Chat with your email and password
- Go to ‘Setting’ menu on the left bar
- Look for ‘App Information’
- You can find APPID in the App Info
Expand All @@ -169,25 +185,31 @@ Channel Id is an identity for each widget channel. If you have a specific widget
- Look for ‘Qiscus Widget’
- Slide the toggle to activate the Qiscus widget

3. **Run npm install**
3. **Install the example dependencies**

After cloning the example, you need to run this code to install all C*ocoapods* dependencies needed by the Example
From the repository root run:

```
yarn
yarn install
```

4. **Set YOUR_APP_ID in the Example**
4. **Configure the example**

- Open example/src/App.tsx
- Replace the `APP_ID` at line 12 with your appId
- Open `example/src/App.tsx`
- Replace the `APP_ID` constant with your App ID and optionally update `CHANNEL_ID`

```javascript
<MultichannelWidgetProvider appId={APP_ID}>
<App />
</MultichannelWidgetProvider>
```

5. **Start Chat**
5. **Run the example app**

From the `example` directory start the Metro bundler with `yarn start`. In another terminal run one of the following:

- `yarn android` to build and install the Expo project on an Android device/emulator.
- `yarn ios` to build and install on the iOS simulator (requires Xcode and CocoaPods).
- `yarn web` to try the widget in a browser.

The Example is ready to use. You can start to chat with your agent from the Qiscus Multichannel Chat dashboard.
Once the app launches you can start chatting with the agents that monitor your Qiscus Multichannel Chat dashboard.
83 changes: 83 additions & 0 deletions docs/GETTING_STARTED.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Getting Started

This guide walks through the exact steps to run the bundled Expo example and experiment with `@qiscus-community/react-native-multichannel-widget` without needing prior knowledge of the project.

## 1. Prerequisites

| Tool | Recommended version | Notes |
| --- | --- | --- |
| Node.js | 18 LTS or newer (Expo 52 requires ≥18) | Install via [Node installers](https://nodejs.org/) or `nvm`. |
| Yarn | 3.6 (repo uses Yarn Berry) | Enable via `corepack enable` once Node is installed. |
| Java Development Kit | 17 | Needed for the Android build. Install via Temurin or Android Studio. |
| Android Studio & SDK tools | Latest stable | Required for `yarn android`. Make sure an emulator and SDK 34+ are installed. |
| Xcode & CocoaPods | Xcode 15, CocoaPods 1.14+ | Only needed for building the iOS example. |
| Watchman (macOS) | Optional but recommended | Improves Metro bundler performance. |

## 2. Clone and Install

```bash
git clone https://github.com/apiep/react-native-multichannel-widget.git
cd react-native-multichannel-widget
corepack enable # ensures Yarn 3 is available
yarn install # installs root + example dependencies
```

> Tip: If you edit the library code inside `src`, run `yarn prepare` to rebuild the distributable files consumed by the example app.

> ⚠️ The repo is pinned to **Yarn 3 (Berry)** through `packageManager`. Stick to `yarn` commands—running `npm install` or `npx` in the root will rewrite lockfiles and frequently break the example workspace.

## 3. Yarn Workflow Cheat Sheet

| Command | Run inside | Why it matters |
| --- | --- | --- |
| `yarn install` | Repo root | Installs every workspace (library + example) with the pinned Yarn version. Re-run after pulling new changes or installing extra dev tools. |
| `yarn prepare` | Repo root | Builds the library via `react-native-builder-bob` so the example consumes your latest edits. Required any time you change files in `src/`, `android/`, or `ios/`. |
| `yarn test` / `yarn lint` / `yarn typecheck` | Repo root | Quickly validate your changes before publishing or pushing. |
| `cd example && yarn install` | `example/` (only if prompted) | The workspace shares dependencies from the root install, but if Expo asks for missing packages, install them here with `yarn`, never `npm`. |
| `cd example && yarn start` / `yarn android` / `yarn ios` | `example/` | Boots the Expo bundler or runs native builds. These commands expect the root install + any recent `yarn prepare` run. |

Having a mental map of where to run each `yarn` command saves time and avoids accidentally mixing package managers.

## 4. Retrieve Your Qiscus Credentials

1. Sign in to [Qiscus Multichannel Chat](https://multichannel.qiscus.com/).
2. Open **Settings → App Information** and copy the `APP_ID`.
3. (Optional) Navigate to **Integration → Qiscus Widget** to activate the widget and grab a specific `CHANNEL_ID` if you plan to target a non-default widget channel.

## 5. Configure the Example App

1. Open `example/src/App.tsx`.
2. Replace the `APP_ID` constant (and `CHANNEL_ID` if desired) with the values taken from the dashboard.
3. Save the file—no additional configuration files are required.

The example already sets up `MultichannelWidgetProvider`, login, and chat components; you only need to inject valid credentials.

## 6. Run the Example with Expo

```bash
cd example
yarn start # starts the Metro bundler (keep it running)
```

In a separate terminal choose one of:

- `yarn android` – builds and runs on an Android emulator/device via `expo run:android`
- `yarn ios` – builds and runs on the iOS simulator via `expo run:ios`
- `yarn web` – opens the widget inside a browser (useful for quick UI checks)

Expo will prompt you to select the target if multiple devices are detected. When the app launches, enter any `userId`/`displayName` pair and tap the login button to start the conversation with your agents on the Qiscus dashboard.

## 7. Common Tasks

- **Clear Metro cache** – Run `yarn start --reset-cache` inside `example` if the bundler serves stale code.
- **Update native dependencies** – After changing native code (inside `android`/`ios` folders of the library), re-run `yarn install` followed by `yarn example ios|android` to regenerate native builds.
- **Testing the library** – From the repo root run `yarn test` (Jest), `yarn lint`, or `yarn typecheck` before publishing.

## 8. Troubleshooting

- `Command yarn android fails with SDK errors` – Make sure Android Studio has downloaded the latest Platform Tools and that `ANDROID_HOME` is set.
- `CocoaPods cannot find dependencies` – Run `sudo gem install cocoapods` once, then `npx pod-install` under `example/ios`.
- `initiateChat throws appId error` – Double-check your `APP_ID` and ensure the widget integration toggle is enabled in Qiscus.
- `Example does not reflect local package changes` – Run `yarn prepare` from the root to rebuild the library before reloading the app.

You should now have a fully working playground to explore the widget, tweak configuration APIs, and verify the user experience before integrating it into your own app.
2 changes: 2 additions & 0 deletions example/.bundle/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BUNDLE_PATH: "vendor/bundle"
BUNDLE_FORCE_RUBY_PLATFORM: 1
13 changes: 13 additions & 0 deletions example/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
root: true,
extends: '@react-native',
rules: {
'react-native/no-unused-styles': 'warn',
},
overrides: [
{
files: ['src/**/*.{ts,tsx}'],
extends: ['@react-native'],
},
],
};
61 changes: 61 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# React Native
node_modules/
.expo/
.expo-shared/
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/
yarn-error.log

# Android
android/app/build/
android/.gradle/
android/build/
.cxx/
.idea/
local.properties
*.iml
*.keystore
!debug.keystore

# iOS
ios/Pods/
ios/build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate

# Bundler / Fastlane / Ruby
/vendor/bundle/
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output

# Misc
.DS_Store
.metro-health-check*
/coverage

# Firebase
firebase.json
android/app/google-services.json
ios/GoogleService-Info.plist

7 changes: 7 additions & 0 deletions example/.prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
arrowParens: 'avoid',
bracketSameLine: true,
bracketSpacing: false,
singleQuote: true,
trailingComma: 'all',
};
1 change: 1 addition & 0 deletions example/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodejs 22.17.0
3 changes: 3 additions & 0 deletions example/.watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"ignore_dirs": ["node_modules", ".git", "android", "ios", "build", "dist"]
}
118 changes: 118 additions & 0 deletions example/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
*/

import React from 'react';
import type {PropsWithChildren} from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
} from 'react-native';

import {
Colors,
DebugInstructions,
Header,
LearnMoreLinks,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';

type SectionProps = PropsWithChildren<{
title: string;
}>;

function Section({children, title}: SectionProps): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';
return (
<View style={styles.sectionContainer}>
<Text
style={[
styles.sectionTitle,
{
color: isDarkMode ? Colors.white : Colors.black,
},
]}>
{title}
</Text>
<Text
style={[
styles.sectionDescription,
{
color: isDarkMode ? Colors.light : Colors.dark,
},
]}>
{children}
</Text>
</View>
);
}

function App(): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';

const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};

return (
<SafeAreaView style={backgroundStyle}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
<View
style={{
backgroundColor: isDarkMode ? Colors.black : Colors.white,
}}>
<Section title="Step One">
Edit <Text style={styles.highlight}>App.tsx</Text> to change this
screen and then come back to see your edits.
</Section>
<Section title="See Your Changes">
<ReloadInstructions />
</Section>
<Section title="Debug">
<DebugInstructions />
</Section>
<Section title="Learn More">
Read the docs to discover what to do next:
</Section>
<LearnMoreLinks />
</View>
</ScrollView>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '700',
},
});

export default App;
Loading