@ethora/chat-component 26.5.8 → 26.5.10
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/dist/assets/icons.d.ts +12 -0
- package/dist/components/VideoCalls/VideoCallOverlay.d.ts +2 -0
- package/dist/components/VideoCalls/VideoCallSession.d.ts +25 -0
- package/dist/firebase-messaging-sw.js +79 -4
- package/dist/helpers/callLogMessage.d.ts +11 -0
- package/dist/helpers/callPush.d.ts +22 -0
- package/dist/helpers/storeConsole.d.ts +1 -0
- package/dist/helpers/useDraggable.d.ts +18 -0
- package/dist/main.js +47563 -23462
- package/dist/main.js.map +1 -1
- package/dist/networking/api-requests/rooms.api.d.ts +3 -0
- package/dist/networking/callTokenStanza.d.ts +13 -0
- package/dist/roomStore/callSlice.d.ts +37 -0
- package/dist/roomStore/index.d.ts +4 -0
- package/dist/types/models/config.model.d.ts +41 -0
- package/dist/types/models/message.model.d.ts +7 -0
- package/dist/version.d.ts +1 -1
- package/package.json +4 -1
- package/public/firebase-messaging-sw.js +79 -4
package/dist/assets/icons.d.ts
CHANGED
|
@@ -23,6 +23,18 @@ export declare const SearchIcon: ({ color, ...props }: {
|
|
|
23
23
|
[x: string]: any;
|
|
24
24
|
color?: string;
|
|
25
25
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export declare const VideoCallIcon: ({ color, ...props }: {
|
|
27
|
+
[x: string]: any;
|
|
28
|
+
color?: string;
|
|
29
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export declare const AudioCallIcon: ({ color, ...props }: {
|
|
31
|
+
[x: string]: any;
|
|
32
|
+
color?: string;
|
|
33
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export declare const HangUpIcon: ({ color, ...props }: {
|
|
35
|
+
[x: string]: any;
|
|
36
|
+
color?: string;
|
|
37
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
26
38
|
export declare const ReferalsIcon: ({ color, ...props }: {
|
|
27
39
|
[x: string]: any;
|
|
28
40
|
color?: string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { VideoCallIcons } from '../../types/models/config.model';
|
|
3
|
+
interface VideoCallSessionProps {
|
|
4
|
+
token: string;
|
|
5
|
+
livekitUrl: string;
|
|
6
|
+
kind?: 'audio' | 'video';
|
|
7
|
+
primaryColor?: string;
|
|
8
|
+
/** Host icon overrides for the control bar. */
|
|
9
|
+
icons?: VideoCallIcons;
|
|
10
|
+
/** Start with the camera on (video calls). Default true. */
|
|
11
|
+
startWithCameraOn?: boolean;
|
|
12
|
+
/** Start with the microphone on. Default true. */
|
|
13
|
+
startWithMicOn?: boolean;
|
|
14
|
+
/** Show the screen-share control. Default true. */
|
|
15
|
+
showScreenShare?: boolean;
|
|
16
|
+
/** Render the compact floating-panel layout instead of the full screen. */
|
|
17
|
+
minimized?: boolean;
|
|
18
|
+
/** Toggle between full and minimized layouts (keeps the session mounted). */
|
|
19
|
+
onToggleMinimize?: () => void;
|
|
20
|
+
onConnected?: () => void;
|
|
21
|
+
onError?: (message: string) => void;
|
|
22
|
+
onHangup: () => void;
|
|
23
|
+
}
|
|
24
|
+
export declare const VideoCallSession: React.FC<VideoCallSessionProps>;
|
|
25
|
+
export {};
|
|
@@ -184,6 +184,54 @@ function pickImage(raw = {}, data = {}, notification = {}) {
|
|
|
184
184
|
return data.image || notification.image || raw.image || undefined;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
// ── CALL DETECTION ────────────────────────────────────────────
|
|
188
|
+
// Mirror of helpers/callPush.ts isCallPush(). A backgrounded call push must
|
|
189
|
+
// (a) read as a call (persistent, call-styled title) and (b) carry its FULL
|
|
190
|
+
// data payload through to the click handler — otherwise the app's isCallPush()
|
|
191
|
+
// sees only {url,messageId,...} and can't raise the ring screen.
|
|
192
|
+
function pickField(data, keys) {
|
|
193
|
+
for (let i = 0; i < keys.length; i += 1) {
|
|
194
|
+
const v = data && data[keys[i]];
|
|
195
|
+
if (v !== undefined && v !== null && String(v).trim() !== '') {
|
|
196
|
+
return String(v).trim();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return '';
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function isCallPushData(data) {
|
|
203
|
+
if (!data) return false;
|
|
204
|
+
const marker = pickField(data, [
|
|
205
|
+
'type',
|
|
206
|
+
'pushType',
|
|
207
|
+
'category',
|
|
208
|
+
'messageType',
|
|
209
|
+
'event',
|
|
210
|
+
]).toLowerCase();
|
|
211
|
+
if (
|
|
212
|
+
marker === 'call' ||
|
|
213
|
+
marker === 'incoming-call' ||
|
|
214
|
+
marker === 'call-token' ||
|
|
215
|
+
marker === 'call-invite'
|
|
216
|
+
) {
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
const callId = pickField(data, ['callId', 'callid', 'callID']);
|
|
220
|
+
const kind = pickField(data, ['kind']).toLowerCase();
|
|
221
|
+
const hasCallField =
|
|
222
|
+
!!pickField(data, ['callToken', 'livekitToken']) ||
|
|
223
|
+
!!pickField(data, ['callKind']) ||
|
|
224
|
+
kind === 'audio' ||
|
|
225
|
+
kind === 'video';
|
|
226
|
+
return !!callId && hasCallField;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function callPushKind(data) {
|
|
230
|
+
return pickField(data, ['callKind', 'kind']).toLowerCase() === 'audio'
|
|
231
|
+
? 'audio'
|
|
232
|
+
: 'video';
|
|
233
|
+
}
|
|
234
|
+
|
|
187
235
|
function extractMessageId(raw = {}, data = {}) {
|
|
188
236
|
return (
|
|
189
237
|
raw.messageId ||
|
|
@@ -356,14 +404,40 @@ async function handlePush(raw = {}, source = 'push') {
|
|
|
356
404
|
dedupKey,
|
|
357
405
|
});
|
|
358
406
|
|
|
407
|
+
const isCall = isCallPushData(data);
|
|
408
|
+
const callerName = isCall
|
|
409
|
+
? pickField(data, [
|
|
410
|
+
'callerName',
|
|
411
|
+
'callerDisplayName',
|
|
412
|
+
'senderName',
|
|
413
|
+
'title',
|
|
414
|
+
])
|
|
415
|
+
: '';
|
|
416
|
+
const callId = isCall
|
|
417
|
+
? pickField(data, ['callId', 'callid', 'callID'])
|
|
418
|
+
: '';
|
|
419
|
+
|
|
420
|
+
// Call pushes: a call-styled title, a tag keyed on the callId so repeat
|
|
421
|
+
// call-token pushes replace (not stack), and requireInteraction so the
|
|
422
|
+
// ring notification persists until the user answers/dismisses.
|
|
423
|
+
const notifTitle = isCall
|
|
424
|
+
? `Incoming ${callPushKind(data)} call${callerName ? ` · ${callerName}` : ''}`
|
|
425
|
+
: title;
|
|
426
|
+
const notifBody = isCall ? 'Tap to answer' : body;
|
|
427
|
+
|
|
359
428
|
const options = {
|
|
360
|
-
body,
|
|
429
|
+
body: notifBody,
|
|
361
430
|
icon,
|
|
362
431
|
badge,
|
|
363
432
|
image,
|
|
364
|
-
tag: dedupKey,
|
|
365
|
-
renotify:
|
|
433
|
+
tag: isCall ? `call:${callId || dedupKey}` : dedupKey,
|
|
434
|
+
renotify: isCall,
|
|
435
|
+
requireInteraction: isCall,
|
|
436
|
+
// Spread the ORIGINAL payload first so the click handler's isCallPush()
|
|
437
|
+
// sees the full call fields (callId/callToken/kind/room); our routing
|
|
438
|
+
// fields win on top.
|
|
366
439
|
data: {
|
|
440
|
+
...data,
|
|
367
441
|
url,
|
|
368
442
|
messageId,
|
|
369
443
|
dedupKey,
|
|
@@ -375,9 +449,10 @@ async function handlePush(raw = {}, source = 'push') {
|
|
|
375
449
|
log('SHOW NOTIFICATION', {
|
|
376
450
|
reason: 'NO_VISIBLE_CLIENT',
|
|
377
451
|
tag: options.tag,
|
|
452
|
+
isCall,
|
|
378
453
|
});
|
|
379
454
|
|
|
380
|
-
return self.registration.showNotification(
|
|
455
|
+
return self.registration.showNotification(notifTitle, options);
|
|
381
456
|
}
|
|
382
457
|
|
|
383
458
|
log('SKIP NOTIFICATION', {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IMessage } from '../types/types';
|
|
2
|
+
export interface CallLogMeta {
|
|
3
|
+
callId: string;
|
|
4
|
+
direction: 'outgoing' | 'incoming';
|
|
5
|
+
durationMs: number;
|
|
6
|
+
missed: boolean;
|
|
7
|
+
kind: 'audio' | 'video';
|
|
8
|
+
}
|
|
9
|
+
export declare const isCallLogMessage: (message: unknown) => boolean;
|
|
10
|
+
export declare const callStateHasLogData: (attrs: Record<string, any>) => boolean;
|
|
11
|
+
export declare const transformCallLogMessage: (message: IMessage, selfXmppUsername: string) => IMessage;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ParsedCallPush {
|
|
2
|
+
callId: string | null;
|
|
3
|
+
/** LiveKit token, if the push carried one (lets us ring + accept offline). */
|
|
4
|
+
token: string | null;
|
|
5
|
+
kind: 'audio' | 'video';
|
|
6
|
+
/** Bare room name (JID localpart) the call belongs to. */
|
|
7
|
+
roomBareName: string | null;
|
|
8
|
+
/** Raw room reference from the payload (full JID or bare name). */
|
|
9
|
+
roomRef: string | null;
|
|
10
|
+
/** Display name for the ring screen (caller). */
|
|
11
|
+
callerName: string | null;
|
|
12
|
+
/** Caller's xmpp localpart, when provided. */
|
|
13
|
+
callerXmppUsername: string | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* True when a push `data` payload represents an incoming call. Matches on an
|
|
17
|
+
* explicit call marker (`type`/`pushType`/`category`/`event` === "call"-ish)
|
|
18
|
+
* or on a callId paired with a call-specific field, so a normal message push
|
|
19
|
+
* is never misread as a call.
|
|
20
|
+
*/
|
|
21
|
+
export declare const isCallPush: (data: Record<string, any> | null | undefined) => boolean;
|
|
22
|
+
export declare const parseCallPush: (data: Record<string, any> | null | undefined) => ParsedCallPush;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface DraggablePosition {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Minimal pointer-based drag hook (no deps). Returns the current offset and a
|
|
7
|
+
* pointer-down handler to attach to a drag handle. The consumer decides how to
|
|
8
|
+
* apply `pos` (e.g. as `left/top`, or as a delta from a default corner).
|
|
9
|
+
*
|
|
10
|
+
* `onChange` fires while dragging so callers can clamp to bounds. Works with
|
|
11
|
+
* mouse and touch via Pointer Events. `null` position means "not yet dragged"
|
|
12
|
+
* (use your default layout until the user moves it).
|
|
13
|
+
*/
|
|
14
|
+
export declare const useDraggable: (clamp?: (pos: DraggablePosition) => DraggablePosition) => {
|
|
15
|
+
pos: DraggablePosition;
|
|
16
|
+
onPointerDown: (e: React.PointerEvent) => void;
|
|
17
|
+
setPos: import('react').Dispatch<import('react').SetStateAction<DraggablePosition>>;
|
|
18
|
+
};
|