@poolse/react 2.9.0 → 2.10.0
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/index.cjs +111 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -3
- package/dist/index.d.ts +68 -3
- package/dist/index.js +111 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { PoolseConfig, Poolse, Me, Uuid, Conversation, ConversationCreateRequest, Membership, MemberRole, Message, MessageCreateRequest, RealtimeStatus, Attachment, AttachmentUploadInput, PoolseUserProfile, VoiceStatus, VoiceParticipant, VoiceRoomOptions, IncomingCall, OutgoingCall } from '@poolse/sdk';
|
|
2
|
+
import { PoolseConfig, Poolse, Me, Uuid, Conversation, ConversationCreateRequest, Membership, MemberRole, Message, MessageCreateRequest, RealtimeStatus, Attachment, AttachmentUploadInput, PoolseUserProfile, CallRoomStatus, CallParticipant, LiveKitModule, VoiceStatus, VoiceParticipant, VoiceRoomOptions, IncomingCall, OutgoingCall, CallMedia } from '@poolse/sdk';
|
|
3
3
|
export { ApiError, Attachment, AttachmentStatus, AttachmentUploadInput, AttachmentUploadRequest, AttachmentUploadResponse, AuthError, Conversation, ConversationCreateRequest, Me, MemberRole, Membership, Message, MessageCreateRequest, MessageType, NetworkError, PoolseConfig, PoolseError, PoolseUserProfile, RateLimitedError, RealtimeStatus, Uuid } from '@poolse/sdk';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
|
|
@@ -485,6 +485,63 @@ declare function sameDay(a: string, b: string): boolean;
|
|
|
485
485
|
*/
|
|
486
486
|
declare function formatDayLabel(iso: string, now?: Date): string;
|
|
487
487
|
|
|
488
|
+
interface UseCallRoomOptions {
|
|
489
|
+
/**
|
|
490
|
+
* `livekit-client`, imported by your app:
|
|
491
|
+
*
|
|
492
|
+
* import * as livekit from 'livekit-client';
|
|
493
|
+
*
|
|
494
|
+
* Passed in rather than imported by the SDK because Metro bundles from
|
|
495
|
+
* the static import graph and cannot follow the `require` that tsup
|
|
496
|
+
* emits — a dependency the SDK imports for itself never reaches a
|
|
497
|
+
* React Native bundle.
|
|
498
|
+
*/
|
|
499
|
+
livekit: LiveKitModule;
|
|
500
|
+
/** Publish the camera on join. An audio call starts with it off. */
|
|
501
|
+
video?: boolean;
|
|
502
|
+
/** Join muted. */
|
|
503
|
+
muted?: boolean;
|
|
504
|
+
}
|
|
505
|
+
interface UseCallRoom {
|
|
506
|
+
status: CallRoomStatus;
|
|
507
|
+
/** Everyone on the call, the local participant first. */
|
|
508
|
+
participants: CallParticipant[];
|
|
509
|
+
cameraEnabled: boolean;
|
|
510
|
+
micEnabled: boolean;
|
|
511
|
+
error: Error | null;
|
|
512
|
+
/**
|
|
513
|
+
* Whether this deployment has an SFU.
|
|
514
|
+
*
|
|
515
|
+
* `null` until a join has been attempted, then `false` if the API
|
|
516
|
+
* answered 503. A `false` here is not a failure — it means fall back
|
|
517
|
+
* to `useVoiceRoom`, which is how every call worked before the SFU.
|
|
518
|
+
*/
|
|
519
|
+
sfuAvailable: boolean | null;
|
|
520
|
+
/** Connect. Resolves `false` when there is no SFU. */
|
|
521
|
+
join: () => Promise<boolean>;
|
|
522
|
+
leave: () => void;
|
|
523
|
+
setCameraEnabled: (enabled: boolean) => Promise<void>;
|
|
524
|
+
toggleCamera: () => Promise<void>;
|
|
525
|
+
setMicrophoneEnabled: (enabled: boolean) => Promise<void>;
|
|
526
|
+
toggleMic: () => Promise<void>;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* A call's media, carried by the SFU.
|
|
530
|
+
*
|
|
531
|
+
* Media only. Ringing, accept/decline/hangup and the poolse roster stay
|
|
532
|
+
* with `useCalls` and `useVoiceRoom`; this is what people sound and look
|
|
533
|
+
* like. A call screen normally uses both.
|
|
534
|
+
*
|
|
535
|
+
* const media = useCallRoom(conversationId, { livekit, video: true });
|
|
536
|
+
* await media.join();
|
|
537
|
+
* await media.toggleCamera();
|
|
538
|
+
*
|
|
539
|
+
* Both the camera and the microphone can be turned on and off at any
|
|
540
|
+
* point during the call — that is the SFU's doing, since renegotiating a
|
|
541
|
+
* live connection is exactly what the peer-to-peer mesh cannot do.
|
|
542
|
+
*/
|
|
543
|
+
declare function useCallRoom(conversationId: string | null, opts: UseCallRoomOptions): UseCallRoom;
|
|
544
|
+
|
|
488
545
|
interface UseVoiceRoom {
|
|
489
546
|
status: VoiceStatus;
|
|
490
547
|
/** Everyone currently in the room, oldest join first. */
|
|
@@ -550,9 +607,17 @@ interface UseCalls {
|
|
|
550
607
|
* `active` — the same id for both caller and callee.
|
|
551
608
|
*/
|
|
552
609
|
activeConversationId: string | null;
|
|
610
|
+
/**
|
|
611
|
+
* What the current call opened as.
|
|
612
|
+
*
|
|
613
|
+
* `'audio'` when nothing is in flight. Either side can still turn
|
|
614
|
+
* their camera on mid-call — this is what was rung, which is what the
|
|
615
|
+
* incoming UI has to commit to before the user answers.
|
|
616
|
+
*/
|
|
617
|
+
media: CallMedia;
|
|
553
618
|
error: Error | null;
|
|
554
619
|
/** Ring every other member of a conversation. */
|
|
555
|
-
call: (conversationId: string) => Promise<void>;
|
|
620
|
+
call: (conversationId: string, media?: CallMedia) => Promise<void>;
|
|
556
621
|
/**
|
|
557
622
|
* Answer the inbound ring.
|
|
558
623
|
*
|
|
@@ -600,4 +665,4 @@ interface UseCalls {
|
|
|
600
665
|
*/
|
|
601
666
|
declare function useCalls(userId: string | null, opts?: UseCallsOptions): UseCalls;
|
|
602
667
|
|
|
603
|
-
export { type CallPhase, type GroupPosition, PoolseProvider, type PoolseProviderProps, type ReactionMap, type UploadItem, type UploadItemStatus, type UseCalls, type UseUserState, type UseVoiceRoom, computeGroupPosition, formatDayLabel, sameDay, sameGroup, useAttachmentUpload, useAttachmentUrl, useCalls, useConversation, useConversations, useMe, useMembers, useMessages, usePoolse, usePresence, useReactions, useRealtimeStatus, useThread, useTyping, useUser, useVoiceRoom };
|
|
668
|
+
export { type CallPhase, type GroupPosition, PoolseProvider, type PoolseProviderProps, type ReactionMap, type UploadItem, type UploadItemStatus, type UseCallRoom, type UseCallRoomOptions, type UseCalls, type UseUserState, type UseVoiceRoom, computeGroupPosition, formatDayLabel, sameDay, sameGroup, useAttachmentUpload, useAttachmentUrl, useCallRoom, useCalls, useConversation, useConversations, useMe, useMembers, useMessages, usePoolse, usePresence, useReactions, useRealtimeStatus, useThread, useTyping, useUser, useVoiceRoom };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { PoolseConfig, Poolse, Me, Uuid, Conversation, ConversationCreateRequest, Membership, MemberRole, Message, MessageCreateRequest, RealtimeStatus, Attachment, AttachmentUploadInput, PoolseUserProfile, VoiceStatus, VoiceParticipant, VoiceRoomOptions, IncomingCall, OutgoingCall } from '@poolse/sdk';
|
|
2
|
+
import { PoolseConfig, Poolse, Me, Uuid, Conversation, ConversationCreateRequest, Membership, MemberRole, Message, MessageCreateRequest, RealtimeStatus, Attachment, AttachmentUploadInput, PoolseUserProfile, CallRoomStatus, CallParticipant, LiveKitModule, VoiceStatus, VoiceParticipant, VoiceRoomOptions, IncomingCall, OutgoingCall, CallMedia } from '@poolse/sdk';
|
|
3
3
|
export { ApiError, Attachment, AttachmentStatus, AttachmentUploadInput, AttachmentUploadRequest, AttachmentUploadResponse, AuthError, Conversation, ConversationCreateRequest, Me, MemberRole, Membership, Message, MessageCreateRequest, MessageType, NetworkError, PoolseConfig, PoolseError, PoolseUserProfile, RateLimitedError, RealtimeStatus, Uuid } from '@poolse/sdk';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
|
|
@@ -485,6 +485,63 @@ declare function sameDay(a: string, b: string): boolean;
|
|
|
485
485
|
*/
|
|
486
486
|
declare function formatDayLabel(iso: string, now?: Date): string;
|
|
487
487
|
|
|
488
|
+
interface UseCallRoomOptions {
|
|
489
|
+
/**
|
|
490
|
+
* `livekit-client`, imported by your app:
|
|
491
|
+
*
|
|
492
|
+
* import * as livekit from 'livekit-client';
|
|
493
|
+
*
|
|
494
|
+
* Passed in rather than imported by the SDK because Metro bundles from
|
|
495
|
+
* the static import graph and cannot follow the `require` that tsup
|
|
496
|
+
* emits — a dependency the SDK imports for itself never reaches a
|
|
497
|
+
* React Native bundle.
|
|
498
|
+
*/
|
|
499
|
+
livekit: LiveKitModule;
|
|
500
|
+
/** Publish the camera on join. An audio call starts with it off. */
|
|
501
|
+
video?: boolean;
|
|
502
|
+
/** Join muted. */
|
|
503
|
+
muted?: boolean;
|
|
504
|
+
}
|
|
505
|
+
interface UseCallRoom {
|
|
506
|
+
status: CallRoomStatus;
|
|
507
|
+
/** Everyone on the call, the local participant first. */
|
|
508
|
+
participants: CallParticipant[];
|
|
509
|
+
cameraEnabled: boolean;
|
|
510
|
+
micEnabled: boolean;
|
|
511
|
+
error: Error | null;
|
|
512
|
+
/**
|
|
513
|
+
* Whether this deployment has an SFU.
|
|
514
|
+
*
|
|
515
|
+
* `null` until a join has been attempted, then `false` if the API
|
|
516
|
+
* answered 503. A `false` here is not a failure — it means fall back
|
|
517
|
+
* to `useVoiceRoom`, which is how every call worked before the SFU.
|
|
518
|
+
*/
|
|
519
|
+
sfuAvailable: boolean | null;
|
|
520
|
+
/** Connect. Resolves `false` when there is no SFU. */
|
|
521
|
+
join: () => Promise<boolean>;
|
|
522
|
+
leave: () => void;
|
|
523
|
+
setCameraEnabled: (enabled: boolean) => Promise<void>;
|
|
524
|
+
toggleCamera: () => Promise<void>;
|
|
525
|
+
setMicrophoneEnabled: (enabled: boolean) => Promise<void>;
|
|
526
|
+
toggleMic: () => Promise<void>;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* A call's media, carried by the SFU.
|
|
530
|
+
*
|
|
531
|
+
* Media only. Ringing, accept/decline/hangup and the poolse roster stay
|
|
532
|
+
* with `useCalls` and `useVoiceRoom`; this is what people sound and look
|
|
533
|
+
* like. A call screen normally uses both.
|
|
534
|
+
*
|
|
535
|
+
* const media = useCallRoom(conversationId, { livekit, video: true });
|
|
536
|
+
* await media.join();
|
|
537
|
+
* await media.toggleCamera();
|
|
538
|
+
*
|
|
539
|
+
* Both the camera and the microphone can be turned on and off at any
|
|
540
|
+
* point during the call — that is the SFU's doing, since renegotiating a
|
|
541
|
+
* live connection is exactly what the peer-to-peer mesh cannot do.
|
|
542
|
+
*/
|
|
543
|
+
declare function useCallRoom(conversationId: string | null, opts: UseCallRoomOptions): UseCallRoom;
|
|
544
|
+
|
|
488
545
|
interface UseVoiceRoom {
|
|
489
546
|
status: VoiceStatus;
|
|
490
547
|
/** Everyone currently in the room, oldest join first. */
|
|
@@ -550,9 +607,17 @@ interface UseCalls {
|
|
|
550
607
|
* `active` — the same id for both caller and callee.
|
|
551
608
|
*/
|
|
552
609
|
activeConversationId: string | null;
|
|
610
|
+
/**
|
|
611
|
+
* What the current call opened as.
|
|
612
|
+
*
|
|
613
|
+
* `'audio'` when nothing is in flight. Either side can still turn
|
|
614
|
+
* their camera on mid-call — this is what was rung, which is what the
|
|
615
|
+
* incoming UI has to commit to before the user answers.
|
|
616
|
+
*/
|
|
617
|
+
media: CallMedia;
|
|
553
618
|
error: Error | null;
|
|
554
619
|
/** Ring every other member of a conversation. */
|
|
555
|
-
call: (conversationId: string) => Promise<void>;
|
|
620
|
+
call: (conversationId: string, media?: CallMedia) => Promise<void>;
|
|
556
621
|
/**
|
|
557
622
|
* Answer the inbound ring.
|
|
558
623
|
*
|
|
@@ -600,4 +665,4 @@ interface UseCalls {
|
|
|
600
665
|
*/
|
|
601
666
|
declare function useCalls(userId: string | null, opts?: UseCallsOptions): UseCalls;
|
|
602
667
|
|
|
603
|
-
export { type CallPhase, type GroupPosition, PoolseProvider, type PoolseProviderProps, type ReactionMap, type UploadItem, type UploadItemStatus, type UseCalls, type UseUserState, type UseVoiceRoom, computeGroupPosition, formatDayLabel, sameDay, sameGroup, useAttachmentUpload, useAttachmentUrl, useCalls, useConversation, useConversations, useMe, useMembers, useMessages, usePoolse, usePresence, useReactions, useRealtimeStatus, useThread, useTyping, useUser, useVoiceRoom };
|
|
668
|
+
export { type CallPhase, type GroupPosition, PoolseProvider, type PoolseProviderProps, type ReactionMap, type UploadItem, type UploadItemStatus, type UseCallRoom, type UseCallRoomOptions, type UseCalls, type UseUserState, type UseVoiceRoom, computeGroupPosition, formatDayLabel, sameDay, sameGroup, useAttachmentUpload, useAttachmentUrl, useCallRoom, useCalls, useConversation, useConversations, useMe, useMembers, useMessages, usePoolse, usePresence, useReactions, useRealtimeStatus, useThread, useTyping, useUser, useVoiceRoom };
|
package/dist/index.js
CHANGED
|
@@ -1062,6 +1062,112 @@ function formatDayLabel(iso, now = /* @__PURE__ */ new Date()) {
|
|
|
1062
1062
|
}
|
|
1063
1063
|
return d.toLocaleDateString(void 0, { day: "numeric", month: "short", year: "numeric" });
|
|
1064
1064
|
}
|
|
1065
|
+
function useCallRoom(conversationId, opts) {
|
|
1066
|
+
const poolse = usePoolse();
|
|
1067
|
+
const [status, setStatus] = useState("idle");
|
|
1068
|
+
const [participants, setParticipants] = useState([]);
|
|
1069
|
+
const [cameraEnabled, setCamera] = useState(false);
|
|
1070
|
+
const [micEnabled, setMic] = useState(false);
|
|
1071
|
+
const [error, setError] = useState(null);
|
|
1072
|
+
const [sfuAvailable, setSfuAvailable] = useState(null);
|
|
1073
|
+
const optsRef = useRef(opts);
|
|
1074
|
+
const joined = useRef(false);
|
|
1075
|
+
const room = useMemo(() => {
|
|
1076
|
+
if (!conversationId) return null;
|
|
1077
|
+
return poolse.call(conversationId, {
|
|
1078
|
+
livekit: optsRef.current.livekit,
|
|
1079
|
+
...optsRef.current.video !== void 0 ? { video: optsRef.current.video } : {},
|
|
1080
|
+
...optsRef.current.muted !== void 0 ? { muted: optsRef.current.muted } : {}
|
|
1081
|
+
});
|
|
1082
|
+
}, [poolse, conversationId]);
|
|
1083
|
+
const sync = useCallback((target) => {
|
|
1084
|
+
if (!target) return;
|
|
1085
|
+
setCamera(target.isCameraEnabled());
|
|
1086
|
+
setMic(target.isMicrophoneEnabled());
|
|
1087
|
+
}, []);
|
|
1088
|
+
useEffect(() => {
|
|
1089
|
+
if (!room) {
|
|
1090
|
+
setStatus("idle");
|
|
1091
|
+
setParticipants([]);
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
setStatus(room.getStatus());
|
|
1095
|
+
setParticipants(room.getParticipants());
|
|
1096
|
+
const offStatus = room.onStatus(setStatus);
|
|
1097
|
+
const offRoster = room.onParticipants((next) => {
|
|
1098
|
+
setParticipants(next);
|
|
1099
|
+
sync(room);
|
|
1100
|
+
});
|
|
1101
|
+
const offError = room.onError(setError);
|
|
1102
|
+
return () => {
|
|
1103
|
+
offStatus();
|
|
1104
|
+
offRoster();
|
|
1105
|
+
offError();
|
|
1106
|
+
if (joined.current) {
|
|
1107
|
+
joined.current = false;
|
|
1108
|
+
room.leave();
|
|
1109
|
+
}
|
|
1110
|
+
};
|
|
1111
|
+
}, [room, sync]);
|
|
1112
|
+
const join = useCallback(async () => {
|
|
1113
|
+
if (!room) return false;
|
|
1114
|
+
setError(null);
|
|
1115
|
+
try {
|
|
1116
|
+
const connected = await room.join();
|
|
1117
|
+
joined.current = connected;
|
|
1118
|
+
setSfuAvailable(connected);
|
|
1119
|
+
sync(room);
|
|
1120
|
+
return connected;
|
|
1121
|
+
} catch (err) {
|
|
1122
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
1123
|
+
setSfuAvailable(true);
|
|
1124
|
+
return false;
|
|
1125
|
+
}
|
|
1126
|
+
}, [room, sync]);
|
|
1127
|
+
const leave = useCallback(() => {
|
|
1128
|
+
if (!joined.current) return;
|
|
1129
|
+
joined.current = false;
|
|
1130
|
+
room?.leave();
|
|
1131
|
+
}, [room]);
|
|
1132
|
+
const setCameraEnabled = useCallback(
|
|
1133
|
+
async (enabled) => {
|
|
1134
|
+
if (!room) return;
|
|
1135
|
+
await room.setCameraEnabled(enabled);
|
|
1136
|
+
sync(room);
|
|
1137
|
+
},
|
|
1138
|
+
[room, sync]
|
|
1139
|
+
);
|
|
1140
|
+
const setMicrophoneEnabled = useCallback(
|
|
1141
|
+
async (enabled) => {
|
|
1142
|
+
if (!room) return;
|
|
1143
|
+
await room.setMicrophoneEnabled(enabled);
|
|
1144
|
+
sync(room);
|
|
1145
|
+
},
|
|
1146
|
+
[room, sync]
|
|
1147
|
+
);
|
|
1148
|
+
const toggleCamera = useCallback(async () => {
|
|
1149
|
+
if (!room) return;
|
|
1150
|
+
await setCameraEnabled(!room.isCameraEnabled());
|
|
1151
|
+
}, [room, setCameraEnabled]);
|
|
1152
|
+
const toggleMic = useCallback(async () => {
|
|
1153
|
+
if (!room) return;
|
|
1154
|
+
await setMicrophoneEnabled(!room.isMicrophoneEnabled());
|
|
1155
|
+
}, [room, setMicrophoneEnabled]);
|
|
1156
|
+
return {
|
|
1157
|
+
status,
|
|
1158
|
+
participants,
|
|
1159
|
+
cameraEnabled,
|
|
1160
|
+
micEnabled,
|
|
1161
|
+
error,
|
|
1162
|
+
sfuAvailable,
|
|
1163
|
+
join,
|
|
1164
|
+
leave,
|
|
1165
|
+
setCameraEnabled,
|
|
1166
|
+
toggleCamera,
|
|
1167
|
+
setMicrophoneEnabled,
|
|
1168
|
+
toggleMic
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1065
1171
|
function useVoiceRoom(conversationId, opts = {}) {
|
|
1066
1172
|
const poolse = usePoolse();
|
|
1067
1173
|
const [status, setStatus] = useState("idle");
|
|
@@ -1176,11 +1282,11 @@ function useCalls(userId, opts = {}) {
|
|
|
1176
1282
|
};
|
|
1177
1283
|
}, [calls]);
|
|
1178
1284
|
const call = useCallback(
|
|
1179
|
-
async (conversationId) => {
|
|
1285
|
+
async (conversationId, media2 = "audio") => {
|
|
1180
1286
|
if (!calls) return;
|
|
1181
1287
|
setError(null);
|
|
1182
1288
|
try {
|
|
1183
|
-
const placed = await calls.invite(conversationId);
|
|
1289
|
+
const placed = await calls.invite(conversationId, media2);
|
|
1184
1290
|
setOutgoing(placed);
|
|
1185
1291
|
setPhase("ringing-out");
|
|
1186
1292
|
} catch (err) {
|
|
@@ -1271,11 +1377,13 @@ function useCalls(userId, opts = {}) {
|
|
|
1271
1377
|
setActiveConversationId(null);
|
|
1272
1378
|
setError(null);
|
|
1273
1379
|
}, []);
|
|
1380
|
+
const media = incoming?.media ?? outgoing?.media ?? "audio";
|
|
1274
1381
|
return {
|
|
1275
1382
|
phase,
|
|
1276
1383
|
incoming,
|
|
1277
1384
|
outgoing,
|
|
1278
1385
|
activeConversationId,
|
|
1386
|
+
media,
|
|
1279
1387
|
error,
|
|
1280
1388
|
call,
|
|
1281
1389
|
accept,
|
|
@@ -1286,6 +1394,6 @@ function useCalls(userId, opts = {}) {
|
|
|
1286
1394
|
};
|
|
1287
1395
|
}
|
|
1288
1396
|
|
|
1289
|
-
export { PoolseProvider, computeGroupPosition, formatDayLabel, sameDay, sameGroup, useAttachmentUpload, useAttachmentUrl, useCalls, useConversation, useConversations, useMe, useMembers, useMessages, usePoolse, usePresence, useReactions, useRealtimeStatus, useThread, useTyping, useUser, useVoiceRoom };
|
|
1397
|
+
export { PoolseProvider, computeGroupPosition, formatDayLabel, sameDay, sameGroup, useAttachmentUpload, useAttachmentUrl, useCallRoom, useCalls, useConversation, useConversations, useMe, useMembers, useMessages, usePoolse, usePresence, useReactions, useRealtimeStatus, useThread, useTyping, useUser, useVoiceRoom };
|
|
1290
1398
|
//# sourceMappingURL=index.js.map
|
|
1291
1399
|
//# sourceMappingURL=index.js.map
|