voxnix 1.0.6 → 1.0.7

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 CHANGED
@@ -1,10 +1,14 @@
1
1
  # Voxnix
2
2
 
3
- A React Component SDK for seamless Voice PABX Integration.
3
+ Universal Voice Widget SDK. Works in React, Vue, Angular, plain HTML — any stack.
4
4
 
5
- ## Overview
5
+ ## What it does
6
6
 
7
- Voxnix is a ready-to-use SDK designed to quickly integrate voice and PABX calling features into your React applications. It provides a self-contained dialer UI and automatically handles voice engine connectivity, including remote media stream attachment.
7
+ - Floating phone button (fixed position, configurable placement)
8
+ - Auto-connects to your SIP/PABX server on init
9
+ - Shows dialer numpad immediately after registration
10
+ - Full call UI: incoming call, outgoing dialing, in-call controls (mute, hold, DTMF)
11
+ - Fires callbacks for all call events so your app can react
8
12
 
9
13
  ## Installation
10
14
 
@@ -14,107 +18,170 @@ npm install voxnix
14
18
  yarn add voxnix
15
19
  ```
16
20
 
17
- ## Usage
21
+ ## Quick start (any framework)
22
+
23
+ ```js
24
+ import { OmnixWidget } from 'voxnix';
25
+
26
+ const widget = OmnixWidget.init({
27
+ platform: 'sipjs',
28
+ auth: {
29
+ username: '1001',
30
+ pwd_pbx: 'secret',
31
+ pabx_host: 'sip.example.com',
32
+ port: 8089,
33
+ },
34
+ placement: 'bottom-left', // 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'
35
+
36
+ onRegisterStatus: (status) => {
37
+ console.log('SIP status:', status); // 'REGISTERED' | 'FAILED'
38
+ },
39
+ onIncomingCall: (data) => console.log('Incoming:', data),
40
+ onCallAnswered: (data) => console.log('Answered:', data),
41
+ onCallEnded: (data) => console.log('Ended:', data),
42
+ onCallUnanswered: () => console.log('Missed call'),
43
+ });
44
+
45
+ // Imperative controls (optional — widget has its own UI)
46
+ widget.answer();
47
+ widget.hangup();
48
+ widget.reject();
49
+ widget.mute(true); // mute
50
+ widget.mute(false); // unmute
51
+ widget.hold(true); // hold
52
+ widget.hold(false); // resume
53
+ widget.dial('1002'); // programmatic dial
54
+ widget.destroy(); // unmount widget
55
+ ```
18
56
 
19
- You can use the `Voxnix` component directly in your React application. Pass the required PABX configuration credentials through the `config` prop and use the event callbacks to listen for call states. You can also use a React `ref` to imperatively control the call (e.g., answer, hold, mute, hangup) from your parent component.
57
+ ### Custom container or offset
20
58
 
21
- ```jsx
22
- import React, { useRef } from "react";
23
- import { Voxnix } from "voxnix";
59
+ ```js
60
+ OmnixWidget.init({
61
+ container: '#my-widget-slot', // CSS selector or DOM element
62
+ // or use offset to position precisely (bypasses placement classes)
63
+ offset: { bottom: 80, left: 10 },
64
+ // ... rest of config
65
+ });
66
+ ```
24
67
 
25
- const App = () => {
26
- const voxnixRef = useRef(null);
68
+ ## React integration
27
69
 
28
- const pabxConfig = {
29
- auth: {
30
- username: "YOUR_USERNAME",
31
- password: "YOUR_PASSWORD",
32
- host: "YOUR_PABX_HOST", // e.g., sip.example.com
33
- },
34
- };
35
-
36
- const handleIncomingCall = (callData) => {
37
- console.log("Incoming call notification:", callData);
38
- // You can answer programmatically
39
- // voxnixRef.current.answer();
40
- };
41
-
42
- const handleCallAnswered = () => {
43
- console.log("Call has been answered");
44
- };
45
-
46
- const handleCallEnded = () => {
47
- console.log("Call has ended");
48
- };
49
-
50
- const handleRegisterStatus = (status) => {
51
- console.log("PABX Registration Status:", status); // "REGISTERED" | "FAILED"
52
- };
53
-
54
- // Example Call Controls
55
- const toggleMute = (isMuted) => voxnixRef.current?.mute(isMuted);
56
- const toggleHold = (isOnHold, setIsOnHold) =>
57
- voxnixRef.current?.hold(isOnHold, setIsOnHold);
58
- const endCall = () => voxnixRef.current?.hangup();
59
-
60
- return (
61
- <div style={{ padding: "20px" }}>
62
- <h1>Voice Integration App</h1>
63
-
64
- {/* Voxnix Voice Engine & UI Component */}
65
- <Voxnix
66
- ref={voxnixRef}
67
- config={pabxConfig}
68
- onIncomingCall={handleIncomingCall}
69
- onCallAnswered={handleCallAnswered}
70
- onCallEnded={handleCallEnded}
71
- onRegisterStatus={handleRegisterStatus}
72
- />
73
- </div>
74
- );
75
- };
76
-
77
- export default App;
70
+ ```jsx
71
+ import { useEffect, useRef } from 'react';
72
+ import { OmnixWidget } from 'voxnix';
73
+
74
+ function App() {
75
+ const widgetRef = useRef(null);
76
+
77
+ useEffect(() => {
78
+ widgetRef.current = OmnixWidget.init({
79
+ platform: 'sipjs',
80
+ auth: { username: '1001', pwd_pbx: 'secret', pabx_host: 'sip.example.com' },
81
+ placement: 'bottom-right',
82
+ onIncomingCall: (data) => { /* navigate, show notification, etc. */ },
83
+ onCallAnswered: (data) => { /* routing logic */ },
84
+ onCallEnded: () => { /* cleanup */ },
85
+ onRegisterStatus: (s) => { /* update UI */ },
86
+ });
87
+
88
+ return () => widgetRef.current?.destroy();
89
+ }, []);
90
+
91
+ return <div id="app">...</div>;
92
+ }
78
93
  ```
79
94
 
80
- ## Component Props
95
+ ## Vue integration
81
96
 
82
- | Prop | Type | Description |
83
- | ------------------ | ---------- | ------------------------------------------------------------------------------------ |
84
- | `config` | `Object` | Configuration object containing `auth` credentials (`username`, `password`, `host`). |
85
- | `onIncomingCall` | `Function` | Callback triggered when there is an incoming call. |
86
- | `onCallAnswered` | `Function` | Callback triggered when the call is answered. |
87
- | `onCallEnded` | `Function` | Callback triggered when the call ends. |
88
- | `onCallUnanswered` | `Function` | Callback triggered when an incoming call is not answered. |
89
- | `onRegisterStatus` | `Function` | Callback triggered when the PABX registration status changes. |
97
+ ```js
98
+ // composable or mounted()
99
+ import { OmnixWidget } from 'voxnix';
90
100
 
91
- ## Ref API (Call Controls)
101
+ onMounted(() => {
102
+ const widget = OmnixWidget.init({ ... });
103
+ onUnmounted(() => widget.destroy());
104
+ });
105
+ ```
92
106
 
93
- You can access these methods by passing a `ref` to the `Voxnix` component:
107
+ ## Via CDN (plain HTML, no bundler)
94
108
 
95
- | Method | Parameters | Description |
96
- | ----------------------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
97
- | `answer()` | - | Answers an incoming call. |
98
- | `reject()` | - | Rejects an incoming call. |
99
- | `hangup()` | - | Ends the current active call. |
100
- | `mute(isMuted)` | `isMuted: boolean` | Mutes or unmutes the local microphone. |
101
- | `hold(isOnHold, setIsOnHold)` | `isOnHold: boolean, setIsOnHold: function` | Puts the call on hold or resumes it. Passes `setIsOnHold` to allow the SDK to asynchronously update the parent UI state when the re-INVITE succeeds. |
109
+ ```html
110
+ <!-- Include React CDN first -->
111
+ <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
112
+ <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
102
113
 
103
- ## Media Handling
114
+ <!-- Or use the self-contained IIFE build (includes React) -->
115
+ <script src="./dist/voxnix.iife.js"></script>
116
+ <script>
117
+ OmnixWidget.init({
118
+ platform: 'sipjs',
119
+ auth: {
120
+ username: '1001',
121
+ pwd_pbx: 'secret',
122
+ pabx_host: 'sip.example.com',
123
+ },
124
+ placement: 'bottom-right',
125
+ onRegisterStatus: (s) => console.log('SIP:', s),
126
+ onIncomingCall: (d) => console.log('Incoming:', d),
127
+ });
128
+ </script>
129
+ ```
104
130
 
105
- Voxnix handles remote media setup automatically. When a call state becomes `Established`, Voxnix will attach the incoming audio stream to an invisible `<audio id="voxnix-remote-audio" />` element. When the call is terminated, the media is safely cleaned up.
131
+ ## Config reference
132
+
133
+ | Option | Type | Default | Description |
134
+ |---------------------|------------------------------------------------|-----------------|--------------------------------------------------|
135
+ | `platform` | `string` | `'sipjs'` | Voice platform. Currently: `'sipjs'` |
136
+ | `auth` | `object` | — | SIP credentials (see below) |
137
+ | `placement` | `'bottom-left'│'bottom-right'│'top-left'│'top-right'` | `'bottom-left'` | Fixed position of the floating widget |
138
+ | `offset` | `{ bottom?, top?, left?, right? }` | `undefined` | CSS pixel coords — overrides `placement` |
139
+ | `container` | `string │ HTMLElement` | `undefined` | Mount target. Auto-creates `div` if omitted |
140
+ | `onIncomingCall` | `(data) => void` | — | Fired on incoming SIP INVITE |
141
+ | `onCallAnswered` | `(data) => void` | — | Fired when call is established |
142
+ | `onCallEnded` | `(data) => void` | — | Fired on BYE / hangup |
143
+ | `onCallUnanswered` | `() => void` | — | Fired when incoming call is not answered |
144
+ | `onRegisterStatus` | `(status: string) => void` | — | `'REGISTERED'` or `'FAILED'` |
145
+
146
+ ### `auth` object
147
+
148
+ | Field | Description |
149
+ |---------------|---------------------------------|
150
+ | `username` | SIP username / extension |
151
+ | `pwd_pbx` | SIP password |
152
+ | `pabx_host` | SIP domain / WSS host |
153
+ | `port` | WSS port (default `8089`) |
154
+
155
+ ## Instance API
156
+
157
+ `OmnixWidget.init()` returns an instance with these methods:
158
+
159
+ | Method | Description |
160
+ |-----------------|------------------------------------|
161
+ | `answer()` | Answer incoming call |
162
+ | `hangup()` | End active call |
163
+ | `reject()` | Reject incoming call |
164
+ | `mute(bool)` | Mute / unmute microphone |
165
+ | `hold(bool)` | Hold / resume call |
166
+ | `dial(number)` | Programmatically dial a number |
167
+ | `destroy()` | Unmount widget and clean up |
168
+
169
+ ## Build
106
170
 
107
- ## Development
171
+ ```bash
172
+ # ESM + UMD (peer React, for npm consumers)
173
+ yarn build:lib
108
174
 
109
- To run the project locally for development:
175
+ # Self-contained IIFE (bundles React, for CDN/script tag)
176
+ yarn build:iife
110
177
 
111
- ```bash
112
- yarn install
113
- yarn dev
178
+ # Both
179
+ yarn build
114
180
  ```
115
181
 
116
- To build for production:
182
+ ## Development
117
183
 
118
184
  ```bash
119
- yarn build
185
+ yarn install
186
+ yarn dev
120
187
  ```