@poolse/react-native 2.15.1 → 2.16.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 +36 -0
- package/dist/index.cjs +34 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -2
- package/dist/index.d.ts +26 -2
- package/dist/index.js +34 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,42 @@ All notable changes to `@poolse/react-native` are documented here.
|
|
|
4
4
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
|
|
5
5
|
versions follow [semver](https://semver.org).
|
|
6
6
|
|
|
7
|
+
## [2.16.0] — 2026-08-24
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Ring tones.** `CallScreen` takes an optional `inCallManager` module
|
|
12
|
+
and plays ringback while an outbound call rings, and a ringtone for an
|
|
13
|
+
inbound one — but only when it is actually showing the incoming UI,
|
|
14
|
+
since CallKit already rings and a second tone underneath is noise.
|
|
15
|
+
A silent outbound call is indistinguishable from one that failed to
|
|
16
|
+
place at all.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **Media opens while the call rings, not after it is answered.** The
|
|
21
|
+
caller used to stare at a blank screen for the whole ring and then
|
|
22
|
+
watch their own preview pop in a second late — and the microphone was
|
|
23
|
+
not open either, so the first word of every call was clipped. The room
|
|
24
|
+
is now joined on `ringing-out`, so it is warm the moment the far side
|
|
25
|
+
picks up. Safe for the alone-detection: a caller in an empty room has
|
|
26
|
+
never seen a peer, which is the guard that already exists.
|
|
27
|
+
- **Tapping the call screen toggles the controls.** It only ever showed
|
|
28
|
+
them before, and a timer took them away — so there was no way to
|
|
29
|
+
deliberately clear the chrome and look at the video. The idle timer
|
|
30
|
+
remains, on top rather than as the only way they disappear.
|
|
31
|
+
|
|
32
|
+
## [2.15.2] — 2026-08-23
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **The floating self-preview had a visible seam around its edge.** The
|
|
37
|
+
bubble clips to its own rounding, but the tile inside rounded itself
|
|
38
|
+
as well and carried a 2px border — transparent or not, that inset the
|
|
39
|
+
video from the edge it should meet, and the two radii disagreeing left
|
|
40
|
+
a hairline along the curve. The inner tile is borderless now, and the
|
|
41
|
+
bubble is rounder.
|
|
42
|
+
|
|
7
43
|
## [2.15.1] — 2026-08-23
|
|
8
44
|
|
|
9
45
|
### Changed
|
package/dist/index.cjs
CHANGED
|
@@ -5544,6 +5544,7 @@ function LocalVideoPip({
|
|
|
5544
5544
|
label,
|
|
5545
5545
|
avatarSize: 48,
|
|
5546
5546
|
hideName: true,
|
|
5547
|
+
bleed: true,
|
|
5547
5548
|
style: styles28.fill
|
|
5548
5549
|
}
|
|
5549
5550
|
) })
|
|
@@ -5559,7 +5560,10 @@ var styles28 = reactNative.StyleSheet.create({
|
|
|
5559
5560
|
left: 0,
|
|
5560
5561
|
width: PIP_WIDTH,
|
|
5561
5562
|
height: PIP_HEIGHT,
|
|
5562
|
-
|
|
5563
|
+
// Generous enough to read as a bubble rather than a cropped
|
|
5564
|
+
// rectangle. The video is clipped to it, so this is the only
|
|
5565
|
+
// rounding in play.
|
|
5566
|
+
borderRadius: 22,
|
|
5563
5567
|
overflow: "hidden",
|
|
5564
5568
|
// Lifted off the video so it reads as floating rather than inset.
|
|
5565
5569
|
shadowColor: "#000",
|
|
@@ -5842,6 +5846,7 @@ function CallScreen({
|
|
|
5842
5846
|
onStatusChange,
|
|
5843
5847
|
onTransportChange,
|
|
5844
5848
|
onVideoChange,
|
|
5849
|
+
inCallManager,
|
|
5845
5850
|
nativeIncomingUi
|
|
5846
5851
|
}) {
|
|
5847
5852
|
const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
|
|
@@ -5852,7 +5857,7 @@ function CallScreen({
|
|
|
5852
5857
|
() => meshAvailable && webrtc ? { webrtc: createNativeWebRtcAdapter(webrtc) } : {},
|
|
5853
5858
|
[meshAvailable, webrtc]
|
|
5854
5859
|
);
|
|
5855
|
-
const conversationId = calls.phase === "active" ? calls.activeConversationId : null;
|
|
5860
|
+
const conversationId = calls.phase === "active" ? calls.activeConversationId : calls.phase === "ringing-out" ? calls.outgoing?.conversationId ?? null : null;
|
|
5856
5861
|
const isVideoCall = calls.media === "video";
|
|
5857
5862
|
const sfu = react$1.useCallRoom(livekit ? conversationId : null, {
|
|
5858
5863
|
livekit,
|
|
@@ -5863,7 +5868,8 @@ function CallScreen({
|
|
|
5863
5868
|
const status = usingSfu ? toVoiceStatus(sfu.status) : mesh.status;
|
|
5864
5869
|
const connected = calls.phase === "active" && status === "connected";
|
|
5865
5870
|
react.useEffect(() => {
|
|
5866
|
-
|
|
5871
|
+
const wants = calls.phase === "active" || calls.phase === "ringing-out";
|
|
5872
|
+
if (!wants || !conversationId) return;
|
|
5867
5873
|
let cancelled = false;
|
|
5868
5874
|
void (async () => {
|
|
5869
5875
|
const joined = livekit ? await sfu.join() : false;
|
|
@@ -5891,6 +5897,23 @@ function CallScreen({
|
|
|
5891
5897
|
livekitReactNative
|
|
5892
5898
|
});
|
|
5893
5899
|
const [routesOpen, setRoutesOpen] = react.useState(false);
|
|
5900
|
+
const showingIncoming = calls.phase === "ringing-in" && !nativeIncomingUi;
|
|
5901
|
+
react.useEffect(() => {
|
|
5902
|
+
const ringing = calls.phase === "ringing-out";
|
|
5903
|
+
if (!ringing && !showingIncoming) return;
|
|
5904
|
+
try {
|
|
5905
|
+
if (ringing) inCallManager?.startRingback?.("_DEFAULT_");
|
|
5906
|
+
else inCallManager?.startRingtone?.("_DEFAULT_");
|
|
5907
|
+
} catch {
|
|
5908
|
+
}
|
|
5909
|
+
return () => {
|
|
5910
|
+
try {
|
|
5911
|
+
inCallManager?.stopRingback?.();
|
|
5912
|
+
inCallManager?.stopRingtone?.();
|
|
5913
|
+
} catch {
|
|
5914
|
+
}
|
|
5915
|
+
};
|
|
5916
|
+
}, [calls.phase, showingIncoming, inCallManager]);
|
|
5894
5917
|
const [chromeVisible, setChromeVisible] = react.useState(true);
|
|
5895
5918
|
const [lastWake, setLastWake] = react.useState(0);
|
|
5896
5919
|
const chromeHides = connected && isVideoCall;
|
|
@@ -5901,6 +5924,13 @@ function CallScreen({
|
|
|
5901
5924
|
return () => clearTimeout(timer);
|
|
5902
5925
|
}, [chromeHides, lastWake]);
|
|
5903
5926
|
const wakeChrome = react.useCallback(() => setLastWake(Date.now()), []);
|
|
5927
|
+
const toggleChrome = react.useCallback(() => {
|
|
5928
|
+
setChromeVisible((visible2) => {
|
|
5929
|
+
if (visible2) return false;
|
|
5930
|
+
setLastWake(Date.now());
|
|
5931
|
+
return true;
|
|
5932
|
+
});
|
|
5933
|
+
}, []);
|
|
5904
5934
|
const withWake = react.useCallback(
|
|
5905
5935
|
(fn) => () => {
|
|
5906
5936
|
wakeChrome();
|
|
@@ -5959,7 +5989,7 @@ function CallScreen({
|
|
|
5959
5989
|
onRequestClose: hangUp,
|
|
5960
5990
|
children: [
|
|
5961
5991
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.StatusBar, { barStyle: "light-content" }),
|
|
5962
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style: styles30.screen, onPress:
|
|
5992
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.Pressable, { style: styles30.screen, onPress: toggleChrome, accessible: false, children: [
|
|
5963
5993
|
showStage ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5964
5994
|
CallVideoGrid,
|
|
5965
5995
|
{
|