@poolse/react-native 2.17.1 → 2.19.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/CHANGELOG.md +44 -0
- package/dist/index.cjs +62 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -26
- package/dist/index.d.ts +0 -26
- package/dist/index.js +62 -22
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -1310,32 +1310,6 @@ interface RingToneModule {
|
|
|
1310
1310
|
startRingtone?: (...args: never[]) => void;
|
|
1311
1311
|
stopRingtone?: (...args: never[]) => void;
|
|
1312
1312
|
}
|
|
1313
|
-
/**
|
|
1314
|
-
* WhatsApp-style call UI: a full-screen sheet that covers the app while
|
|
1315
|
-
* a call is ringing or connected, and renders nothing when idle.
|
|
1316
|
-
*
|
|
1317
|
-
* Mount it once, high in the tree, so a call can arrive on any screen:
|
|
1318
|
-
*
|
|
1319
|
-
* <PoolseProvider config={config}>
|
|
1320
|
-
* <CallScreen
|
|
1321
|
-
* userId={me.id}
|
|
1322
|
-
* livekit={livekit}
|
|
1323
|
-
* livekitReactNative={livekitRN}
|
|
1324
|
-
* />
|
|
1325
|
-
* <YourApp />
|
|
1326
|
-
* </PoolseProvider>
|
|
1327
|
-
*
|
|
1328
|
-
* ## Two media paths
|
|
1329
|
-
*
|
|
1330
|
-
* With `livekit` supplied, media rides the SFU: one upload per
|
|
1331
|
-
* participant regardless of call size, and the camera and microphone can
|
|
1332
|
-
* be switched on and off at any point. Without it — or against a
|
|
1333
|
-
* deployment that has no SFU configured — calls fall back to the
|
|
1334
|
-
* peer-to-peer mesh, which is audio only.
|
|
1335
|
-
*
|
|
1336
|
-
* The fallback is automatic and silent by design. A deployment without
|
|
1337
|
-
* an SFU is a supported configuration, not a broken one.
|
|
1338
|
-
*/
|
|
1339
1313
|
declare function CallScreen({ userId, labelFor, calls: callsProp, webrtc, livekit, livekitReactNative, onStatusChange, onTransportChange, onVideoChange, inCallManager, nativeIncomingUi, }: CallScreenProps): react_jsx_runtime.JSX.Element;
|
|
1340
1314
|
|
|
1341
1315
|
interface CallVideoGridProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -1310,32 +1310,6 @@ interface RingToneModule {
|
|
|
1310
1310
|
startRingtone?: (...args: never[]) => void;
|
|
1311
1311
|
stopRingtone?: (...args: never[]) => void;
|
|
1312
1312
|
}
|
|
1313
|
-
/**
|
|
1314
|
-
* WhatsApp-style call UI: a full-screen sheet that covers the app while
|
|
1315
|
-
* a call is ringing or connected, and renders nothing when idle.
|
|
1316
|
-
*
|
|
1317
|
-
* Mount it once, high in the tree, so a call can arrive on any screen:
|
|
1318
|
-
*
|
|
1319
|
-
* <PoolseProvider config={config}>
|
|
1320
|
-
* <CallScreen
|
|
1321
|
-
* userId={me.id}
|
|
1322
|
-
* livekit={livekit}
|
|
1323
|
-
* livekitReactNative={livekitRN}
|
|
1324
|
-
* />
|
|
1325
|
-
* <YourApp />
|
|
1326
|
-
* </PoolseProvider>
|
|
1327
|
-
*
|
|
1328
|
-
* ## Two media paths
|
|
1329
|
-
*
|
|
1330
|
-
* With `livekit` supplied, media rides the SFU: one upload per
|
|
1331
|
-
* participant regardless of call size, and the camera and microphone can
|
|
1332
|
-
* be switched on and off at any point. Without it — or against a
|
|
1333
|
-
* deployment that has no SFU configured — calls fall back to the
|
|
1334
|
-
* peer-to-peer mesh, which is audio only.
|
|
1335
|
-
*
|
|
1336
|
-
* The fallback is automatic and silent by design. A deployment without
|
|
1337
|
-
* an SFU is a supported configuration, not a broken one.
|
|
1338
|
-
*/
|
|
1339
1313
|
declare function CallScreen({ userId, labelFor, calls: callsProp, webrtc, livekit, livekitReactNative, onStatusChange, onTransportChange, onVideoChange, inCallManager, nativeIncomingUi, }: CallScreenProps): react_jsx_runtime.JSX.Element;
|
|
1340
1314
|
|
|
1341
1315
|
interface CallVideoGridProps {
|
package/dist/index.js
CHANGED
|
@@ -5809,6 +5809,10 @@ function format(total) {
|
|
|
5809
5809
|
return `${hours > 0 ? `${hours}:` : ""}${mm}:${String(seconds).padStart(2, "0")}`;
|
|
5810
5810
|
}
|
|
5811
5811
|
var CHROME_IDLE_MS = 4500;
|
|
5812
|
+
var ENDED_LINGER_MS = 2500;
|
|
5813
|
+
function isOver(phase) {
|
|
5814
|
+
return phase === "declined" || phase === "busy" || phase === "timed-out";
|
|
5815
|
+
}
|
|
5812
5816
|
function CallScreen({
|
|
5813
5817
|
userId,
|
|
5814
5818
|
labelFor,
|
|
@@ -5924,6 +5928,11 @@ function CallScreen({
|
|
|
5924
5928
|
endedOnEmpty.current = true;
|
|
5925
5929
|
hangUp();
|
|
5926
5930
|
}, [alone, calls.phase, hangUp]);
|
|
5931
|
+
useEffect(() => {
|
|
5932
|
+
if (!isOver(calls.phase)) return;
|
|
5933
|
+
const timer = setTimeout(calls.reset, ENDED_LINGER_MS);
|
|
5934
|
+
return () => clearTimeout(timer);
|
|
5935
|
+
}, [calls.phase, calls.reset]);
|
|
5927
5936
|
const micOn = usingSfu ? sfu.micEnabled : !mesh.muted;
|
|
5928
5937
|
const toggleMic = useCallback(() => {
|
|
5929
5938
|
if (usingSfu) void sfu.toggleMic();
|
|
@@ -5937,7 +5946,7 @@ function CallScreen({
|
|
|
5937
5946
|
const label = useMemo(() => labelFor ?? ((id) => `User ${id.slice(0, 6)}`), [labelFor]);
|
|
5938
5947
|
const ringingIn = calls.phase === "ringing-in";
|
|
5939
5948
|
const ringingOut = calls.phase === "ringing-out";
|
|
5940
|
-
const ended = calls.phase
|
|
5949
|
+
const ended = isOver(calls.phase);
|
|
5941
5950
|
const visible = calls.phase !== "idle" && !(nativeIncomingUi && ringingIn);
|
|
5942
5951
|
const duration = useCallDuration(connected);
|
|
5943
5952
|
const participants = usingSfu ? sfu.participants : [];
|
|
@@ -6179,6 +6188,26 @@ function isStalePush(sentAt, now, staleAfterMs) {
|
|
|
6179
6188
|
if (age < 0) return false;
|
|
6180
6189
|
return age > staleAfterMs;
|
|
6181
6190
|
}
|
|
6191
|
+
function readPush(payload) {
|
|
6192
|
+
const callId = payload.call_id;
|
|
6193
|
+
if (!callId) return { kind: "ignore" };
|
|
6194
|
+
if (payload.event === "ended") return { kind: "teardown", callId };
|
|
6195
|
+
const conversationId = payload.conversation_id;
|
|
6196
|
+
if (!conversationId) return { kind: "ignore" };
|
|
6197
|
+
return {
|
|
6198
|
+
kind: "ring",
|
|
6199
|
+
sentAt: payload.sent_at,
|
|
6200
|
+
call: {
|
|
6201
|
+
callId,
|
|
6202
|
+
conversationId,
|
|
6203
|
+
callerUserId: payload.caller_user_id ?? "",
|
|
6204
|
+
callerName: payload.caller_name ?? "Incoming call",
|
|
6205
|
+
// `has_video` is what older servers sent; `media` supersedes it.
|
|
6206
|
+
// Either saying video means the system UI offers video.
|
|
6207
|
+
media: payload.media === "video" || payload.has_video ? "video" : "audio"
|
|
6208
|
+
}
|
|
6209
|
+
};
|
|
6210
|
+
}
|
|
6182
6211
|
function useVoipCalls({
|
|
6183
6212
|
voipPush,
|
|
6184
6213
|
callKeep,
|
|
@@ -6191,6 +6220,9 @@ function useVoipCalls({
|
|
|
6191
6220
|
}) {
|
|
6192
6221
|
const poolse = usePoolse();
|
|
6193
6222
|
const shown = useRef(/* @__PURE__ */ new Map());
|
|
6223
|
+
const [voipToken, setVoipToken] = useState(null);
|
|
6224
|
+
const { me } = useMe();
|
|
6225
|
+
const registered = useRef(null);
|
|
6194
6226
|
const handlers = useRef({ onAnswer, onDecline, calls });
|
|
6195
6227
|
handlers.current = { onAnswer, onDecline, calls };
|
|
6196
6228
|
const staleRef = useRef(staleAfterMs);
|
|
@@ -6230,24 +6262,37 @@ function useVoipCalls({
|
|
|
6230
6262
|
void ready.current.then(done, done);
|
|
6231
6263
|
if (isStalePush(sentAt, Date.now(), staleRef.current)) dismiss.current(call.callId);
|
|
6232
6264
|
});
|
|
6265
|
+
useEffect(() => {
|
|
6266
|
+
const userId = me?.id;
|
|
6267
|
+
if (!voipToken || !userId) return;
|
|
6268
|
+
const pair = `${userId}:${voipToken}`;
|
|
6269
|
+
if (registered.current === pair) return;
|
|
6270
|
+
void poolse.devices.register({
|
|
6271
|
+
token: voipToken,
|
|
6272
|
+
platform: "ios",
|
|
6273
|
+
environment: apnsEnvironment ?? guessApnsEnvironment()
|
|
6274
|
+
}).then(() => {
|
|
6275
|
+
registered.current = pair;
|
|
6276
|
+
}).catch(() => {
|
|
6277
|
+
});
|
|
6278
|
+
}, [poolse, voipToken, me?.id, apnsEnvironment]);
|
|
6233
6279
|
useEffect(() => {
|
|
6234
6280
|
let cancelled = false;
|
|
6235
6281
|
const fromPush = (payload) => {
|
|
6236
|
-
const
|
|
6237
|
-
|
|
6238
|
-
if (
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
);
|
|
6282
|
+
const intent = readPush(payload);
|
|
6283
|
+
if (intent.kind === "ignore") return;
|
|
6284
|
+
if (intent.kind === "teardown") {
|
|
6285
|
+
dismiss.current(intent.callId);
|
|
6286
|
+
handlers.current.calls?.dropped(intent.callId);
|
|
6287
|
+
return;
|
|
6288
|
+
}
|
|
6289
|
+
present.current(intent.call, intent.sentAt);
|
|
6290
|
+
handlers.current.calls?.ring({
|
|
6291
|
+
callId: intent.call.callId,
|
|
6292
|
+
conversationId: intent.call.conversationId,
|
|
6293
|
+
callerUserId: intent.call.callerUserId,
|
|
6294
|
+
media: intent.call.media
|
|
6295
|
+
});
|
|
6251
6296
|
};
|
|
6252
6297
|
ready.current = callKeep.setup({
|
|
6253
6298
|
ios: { appName },
|
|
@@ -6262,12 +6307,7 @@ function useVoipCalls({
|
|
|
6262
6307
|
});
|
|
6263
6308
|
voipPush.addEventListener("register", ((token) => {
|
|
6264
6309
|
if (cancelled || !token) return;
|
|
6265
|
-
|
|
6266
|
-
token,
|
|
6267
|
-
platform: "ios",
|
|
6268
|
-
environment: apnsEnvironment ?? guessApnsEnvironment()
|
|
6269
|
-
}).catch(() => {
|
|
6270
|
-
});
|
|
6310
|
+
setVoipToken(token);
|
|
6271
6311
|
}));
|
|
6272
6312
|
voipPush.addEventListener("notification", ((payload) => {
|
|
6273
6313
|
fromPush(payload);
|