react-peer-chat 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -1
- package/build/index.d.ts +2 -2
- package/build/index.js +7 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,2 +1,140 @@
|
|
|
1
1
|
# react-peer-chat
|
|
2
|
-
An easy to use react component for impleting peer-to-peer chatting.
|
|
2
|
+
An easy to use react component for impleting peer-to-peer chatting using [peerjs](https://peerjs.com/) under the hood.
|
|
3
|
+
|
|
4
|
+
It is as easy as to import a React component!
|
|
5
|
+
## Features
|
|
6
|
+
- Peer-to-peer chat without need to have any knowledge about WebRTC
|
|
7
|
+
- Easy to use
|
|
8
|
+
- Supports text chat that persists on page reload
|
|
9
|
+
- Supports voice chat
|
|
10
|
+
- Fully Customizable. See [usage with FoC](#Full-Customization)
|
|
11
|
+
## Installation
|
|
12
|
+
To install react-peer-chat
|
|
13
|
+
```bash
|
|
14
|
+
# with npm:
|
|
15
|
+
npm install react-peer-chat --save
|
|
16
|
+
|
|
17
|
+
# with yarn:
|
|
18
|
+
yarn add react-peer-chat
|
|
19
|
+
|
|
20
|
+
# with pnpm:
|
|
21
|
+
pnpm add react-peer-chat
|
|
22
|
+
|
|
23
|
+
# with bun:
|
|
24
|
+
bun add react-peer-chat
|
|
25
|
+
```
|
|
26
|
+
## Usage
|
|
27
|
+
When you use the `<Chat>` component of `react-peer-chat`, initially the user will see 2 buttons(svg icons), one for text chat and other for voice chat.
|
|
28
|
+
#### Basic Usage
|
|
29
|
+
```jsx
|
|
30
|
+
import React, { useEffect } from 'react';
|
|
31
|
+
import Chat, { clearChat } from 'react-peer-chat';
|
|
32
|
+
import 'react-peer-chat/build/styles.css';
|
|
33
|
+
|
|
34
|
+
function App() {
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
return clearChat // clear the chat when app is unmounted
|
|
37
|
+
}, [])
|
|
38
|
+
|
|
39
|
+
return <Chat
|
|
40
|
+
name='John Doe'
|
|
41
|
+
peerId='some-unique-id'
|
|
42
|
+
remotePeerId='another-unique-id'
|
|
43
|
+
/>
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
#### Partial Customization
|
|
47
|
+
Use props provided by `<Chat>` component to customize it.
|
|
48
|
+
```jsx
|
|
49
|
+
import React from 'react';
|
|
50
|
+
import Chat from 'react-peer-chat';
|
|
51
|
+
import 'react-peer-chat/build/styles.css';
|
|
52
|
+
|
|
53
|
+
function App() {
|
|
54
|
+
return <Chat
|
|
55
|
+
name='John Doe'
|
|
56
|
+
peerId='some-unique-id'
|
|
57
|
+
remotePeerId='another-unique-id'
|
|
58
|
+
dialogOptions={{
|
|
59
|
+
position: 'left',
|
|
60
|
+
style: { padding: '4px' }
|
|
61
|
+
}}
|
|
62
|
+
props={{ title: 'React Peer Chat Component' }}
|
|
63
|
+
onError={() => {
|
|
64
|
+
console.error('Microphone not accessible!');
|
|
65
|
+
}}
|
|
66
|
+
/>
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
#### Full Customization
|
|
70
|
+
Use Function as Children(FoC) to fully customize the `<Chat>` component.
|
|
71
|
+
```jsx
|
|
72
|
+
import React from 'react'
|
|
73
|
+
import Chat from 'react-peer-chat'
|
|
74
|
+
// import 'react-peer-chat/build/styles.css' (No need to import CSS when using custom component)
|
|
75
|
+
|
|
76
|
+
function App() {
|
|
77
|
+
return <Chat
|
|
78
|
+
name='John Doe'
|
|
79
|
+
peerId='some-unique-id'
|
|
80
|
+
remotePeerId='another-unique-id'
|
|
81
|
+
onError={() => {
|
|
82
|
+
console.error('Microphone not accessible!');
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
{({ remotePeerName, messages, addMessage, audio, setAudio }) => (
|
|
86
|
+
<YourCustomComponent>
|
|
87
|
+
{...}
|
|
88
|
+
</YourCustomComponent>
|
|
89
|
+
)}
|
|
90
|
+
</Chat>
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
## Chat Component API Reference
|
|
94
|
+
Here is the full API for the `<Chat>` component, these properties can be set on an instance of Chat:
|
|
95
|
+
| Parameter | Type | Required | Default | Description |
|
|
96
|
+
| - | - | - | - | - |
|
|
97
|
+
| `name` | `String` | No | Anonymous User | Name of the peer which will be shown to the remote peer. |
|
|
98
|
+
| `peerId` | `String` | Yes | - | It is the unique id that is alloted to a peer. It uniquely identifies a peer from other peers. |
|
|
99
|
+
| `remotePeerId` | `String` | No | - | It is the unique id of the remote peer. If provided, the peer will try to connect to the remote peer. |
|
|
100
|
+
| `text` | `Boolean` | No | `true` | Text chat will be enabled if this property is set to true. |
|
|
101
|
+
| `voice` | `Boolean` | No | `true` | Voice chat will be enabled if this property is set to true. |
|
|
102
|
+
| `peerOptions` | [`PeerOptions`](#PeerOptions) | No | - | Options to customize peerjs Peer instance. |
|
|
103
|
+
| `dialogOptions` | [`DialogOptions`](#DialogOptions) | No | { position: 'center' } | Options to customize text dialog box styling. |
|
|
104
|
+
| `onError` | `Function` | No | `() => alert('Microphone not accessible!')` | Function to be executed when microphone is not accessible. |
|
|
105
|
+
| `props` | `React.DetailedHTMLProps` | No | - | Props to customize the `<Chat>` component. |
|
|
106
|
+
| `children` | [`Children`](#Children) | No | - | Props to customize the `<Chat>` component. |
|
|
107
|
+
### Types
|
|
108
|
+
#### PeerOptions
|
|
109
|
+
```typescript
|
|
110
|
+
import { PeerOptions } from 'peerjs'
|
|
111
|
+
```
|
|
112
|
+
#### DialogOptions
|
|
113
|
+
```typescript
|
|
114
|
+
import { CSSProperties } from 'react';
|
|
115
|
+
type DialogPosition = 'left' | 'center' | 'right';
|
|
116
|
+
type DialogOptions = {
|
|
117
|
+
position: DialogPosition;
|
|
118
|
+
style: CSSProperties;
|
|
119
|
+
};
|
|
120
|
+
```
|
|
121
|
+
#### Children
|
|
122
|
+
```typescript
|
|
123
|
+
import { ReactNode } from 'react';
|
|
124
|
+
type Message = {
|
|
125
|
+
id: string;
|
|
126
|
+
text: string;
|
|
127
|
+
};
|
|
128
|
+
type ChildrenOptions = {
|
|
129
|
+
remotePeerName?: string;
|
|
130
|
+
messages?: Message[];
|
|
131
|
+
addMessage?: (message: Message, sendToRemotePeer?: boolean) => void;
|
|
132
|
+
audio?: boolean;
|
|
133
|
+
setAudio?: (audio: boolean) => void;
|
|
134
|
+
};
|
|
135
|
+
type Children = (childrenOptions: ChildrenOptions) => ReactNode;
|
|
136
|
+
```
|
|
137
|
+
## Used By
|
|
138
|
+
- [StarWars](https://starwarsgame.vercel.app/)
|
|
139
|
+
## Author
|
|
140
|
+
[Sahil Aggarwal](https://www.github.com/SahilAggarwal2004)
|
package/build/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ type Message = {
|
|
|
5
5
|
text: string;
|
|
6
6
|
};
|
|
7
7
|
type ChildrenOptions = {
|
|
8
|
-
|
|
8
|
+
remotePeerName?: string;
|
|
9
9
|
messages?: Message[];
|
|
10
10
|
addMessage?: (message: Message, sendToRemotePeer?: boolean) => void;
|
|
11
11
|
audio?: boolean;
|
|
@@ -24,7 +24,7 @@ type Props = {
|
|
|
24
24
|
voice?: boolean;
|
|
25
25
|
peerOptions?: PeerOptions;
|
|
26
26
|
dialogOptions?: DialogOptions;
|
|
27
|
-
onError?:
|
|
27
|
+
onError?: Function;
|
|
28
28
|
children?: (childrenOptions: ChildrenOptions) => ReactNode;
|
|
29
29
|
props?: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
|
|
30
30
|
};
|
package/build/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { BiSolidMessageDetail, BiSolidMessageX, BsFillMicFill, BsFillMicMuteFill
|
|
|
4
4
|
export default function Chat({ name, peerId, remotePeerId, peerOptions, text = true, voice = true, dialogOptions, onError = () => alert("Microphone not accessible!"), children, props = {} }) {
|
|
5
5
|
const [peer, setPeer] = useState();
|
|
6
6
|
const [notification, setNotification] = useState(false);
|
|
7
|
-
const [
|
|
7
|
+
const [remotePeerName, setRemotePeer] = useStorage('rpc-remote-peer', '', { save: true });
|
|
8
8
|
const [messages, setMessages] = useStorage('rpc-messages', [], { save: true });
|
|
9
9
|
const connRef = useRef();
|
|
10
10
|
const [dialog, setDialog] = useState(false);
|
|
@@ -26,11 +26,11 @@ export default function Chat({ name, peerId, remotePeerId, peerOptions, text = t
|
|
|
26
26
|
function handleConnection(conn) {
|
|
27
27
|
connRef.current = conn;
|
|
28
28
|
conn.on('open', () => {
|
|
29
|
-
conn.on('data', ({ type, message,
|
|
29
|
+
conn.on('data', ({ type, message, remotePeerName, messages }) => {
|
|
30
30
|
if (type === 'message')
|
|
31
31
|
addMessage(message);
|
|
32
32
|
else if (type === 'init') {
|
|
33
|
-
setRemotePeer(
|
|
33
|
+
setRemotePeer(remotePeerName || 'Anonymous User');
|
|
34
34
|
setMessages(old => {
|
|
35
35
|
if (messages.length > old.length)
|
|
36
36
|
return messages;
|
|
@@ -38,7 +38,7 @@ export default function Chat({ name, peerId, remotePeerId, peerOptions, text = t
|
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
|
-
conn.send({ type: 'init',
|
|
41
|
+
conn.send({ type: 'init', remotePeerName: name, messages });
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
useEffect(() => {
|
|
@@ -115,9 +115,9 @@ export default function Chat({ name, peerId, remotePeerId, peerOptions, text = t
|
|
|
115
115
|
const container = containerRef.current;
|
|
116
116
|
if (container)
|
|
117
117
|
container.scrollTop = container.scrollHeight;
|
|
118
|
-
}, [dialog,
|
|
118
|
+
}, [dialog, remotePeerName, messages]);
|
|
119
119
|
return React.createElement("div", { className: 'rpc-main', ...props },
|
|
120
|
-
typeof children === 'function' ? children({
|
|
120
|
+
typeof children === 'function' ? children({ remotePeerName, messages, addMessage, audio, setAudio }) : React.createElement(React.Fragment, null,
|
|
121
121
|
text && React.createElement("div", null,
|
|
122
122
|
dialog ? React.createElement(BiSolidMessageX, { onClick: () => setDialog(false) }) : React.createElement("div", { className: 'rpc-notification' },
|
|
123
123
|
React.createElement(BiSolidMessageDetail, { onClick: () => {
|
|
@@ -131,7 +131,7 @@ export default function Chat({ name, peerId, remotePeerId, peerOptions, text = t
|
|
|
131
131
|
React.createElement("div", null,
|
|
132
132
|
React.createElement("div", { ref: containerRef, className: 'rpc-message-container' }, messages.map(({ id, text }, i) => React.createElement("div", { key: i },
|
|
133
133
|
React.createElement("strong", null,
|
|
134
|
-
id === peerId ? 'You' :
|
|
134
|
+
id === peerId ? 'You' : remotePeerName,
|
|
135
135
|
": "),
|
|
136
136
|
React.createElement("span", null, text)))),
|
|
137
137
|
React.createElement("hr", null),
|