@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 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
- borderRadius: 16,
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
- if (calls.phase !== "active" || !conversationId) return;
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: wakeChrome, accessible: false, children: [
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
  {