@poolse/react-native 2.13.0 → 2.13.1
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 +14 -0
- package/dist/index.cjs +35 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +35 -19
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ 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.13.1] — 2026-08-23
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Controls no longer vanish mid-tap on a video call: pressing one now
|
|
12
|
+
restarts the idle countdown, which a screen-wide handler never saw
|
|
13
|
+
because a child `Pressable` wins the touch outright.
|
|
14
|
+
- The iOS audio policy is released when a call ends while its session is
|
|
15
|
+
still starting, instead of being left installed.
|
|
16
|
+
- The floating self-preview follows the stage across a rotation rather
|
|
17
|
+
than keeping a pixel position from the old bounds.
|
|
18
|
+
- The auto-hang-up on an emptied call fires once rather than on every
|
|
19
|
+
render in the window before the phase flips.
|
|
20
|
+
|
|
7
21
|
## [2.13.0] — 2026-08-23
|
|
8
22
|
|
|
9
23
|
A near-total rebuild of the calling surface.
|
package/dist/index.cjs
CHANGED
|
@@ -5476,6 +5476,11 @@ function LocalVideoPip({
|
|
|
5476
5476
|
const cornerRef = react.useRef(corner);
|
|
5477
5477
|
cornerRef.current = corner;
|
|
5478
5478
|
const dragged = react.useRef(false);
|
|
5479
|
+
react.useEffect(() => {
|
|
5480
|
+
if (dragged.current) return;
|
|
5481
|
+
const at = corners[corner];
|
|
5482
|
+
if (at) pan.setValue(at);
|
|
5483
|
+
}, [corners, corner, pan]);
|
|
5479
5484
|
const responder = react.useMemo(
|
|
5480
5485
|
() => reactNative.PanResponder.create({
|
|
5481
5486
|
// Claim the gesture only once it is clearly a drag. A lower
|
|
@@ -5700,6 +5705,7 @@ function useCallAudio({
|
|
|
5700
5705
|
if (!active || !session) return;
|
|
5701
5706
|
const wantsSpeaker = preferSpeaker.current;
|
|
5702
5707
|
let disposePolicy;
|
|
5708
|
+
let released = false;
|
|
5703
5709
|
void (async () => {
|
|
5704
5710
|
try {
|
|
5705
5711
|
await session.configureAudio({
|
|
@@ -5713,14 +5719,22 @@ function useCallAudio({
|
|
|
5713
5719
|
});
|
|
5714
5720
|
} catch {
|
|
5715
5721
|
}
|
|
5722
|
+
if (released) return;
|
|
5716
5723
|
disposePolicy = livekitReactNative?.setupIOSAudioManagement?.(wantsSpeaker);
|
|
5717
5724
|
try {
|
|
5718
5725
|
await session.startAudioSession();
|
|
5719
5726
|
} catch {
|
|
5720
5727
|
}
|
|
5728
|
+
if (released) {
|
|
5729
|
+
void session.stopAudioSession().catch(() => {
|
|
5730
|
+
});
|
|
5731
|
+
disposePolicy?.();
|
|
5732
|
+
return;
|
|
5733
|
+
}
|
|
5721
5734
|
refreshRoutes();
|
|
5722
5735
|
})();
|
|
5723
5736
|
return () => {
|
|
5737
|
+
released = true;
|
|
5724
5738
|
void session.stopAudioSession().catch(() => {
|
|
5725
5739
|
});
|
|
5726
5740
|
disposePolicy?.();
|
|
@@ -5877,31 +5891,33 @@ function CallScreen({
|
|
|
5877
5891
|
});
|
|
5878
5892
|
const [routesOpen, setRoutesOpen] = react.useState(false);
|
|
5879
5893
|
const [chromeVisible, setChromeVisible] = react.useState(true);
|
|
5880
|
-
const
|
|
5894
|
+
const [lastWake, setLastWake] = react.useState(0);
|
|
5881
5895
|
const chromeHides = connected && isVideoCall;
|
|
5882
5896
|
react.useEffect(() => {
|
|
5883
|
-
if (!chromeHides) {
|
|
5884
|
-
setChromeVisible(true);
|
|
5885
|
-
return;
|
|
5886
|
-
}
|
|
5887
|
-
hideAt.current = Date.now() + CHROME_IDLE_MS;
|
|
5888
|
-
const timer = setInterval(() => {
|
|
5889
|
-
if (Date.now() >= hideAt.current) setChromeVisible(false);
|
|
5890
|
-
}, 500);
|
|
5891
|
-
return () => clearInterval(timer);
|
|
5892
|
-
}, [chromeHides, chromeVisible]);
|
|
5893
|
-
const wakeChrome = react.useCallback(() => {
|
|
5894
|
-
hideAt.current = Date.now() + CHROME_IDLE_MS;
|
|
5895
5897
|
setChromeVisible(true);
|
|
5896
|
-
|
|
5898
|
+
if (!chromeHides) return;
|
|
5899
|
+
const timer = setTimeout(() => setChromeVisible(false), CHROME_IDLE_MS);
|
|
5900
|
+
return () => clearTimeout(timer);
|
|
5901
|
+
}, [chromeHides, lastWake]);
|
|
5902
|
+
const wakeChrome = react.useCallback(() => setLastWake(Date.now()), []);
|
|
5903
|
+
const withWake = react.useCallback(
|
|
5904
|
+
(fn) => () => {
|
|
5905
|
+
wakeChrome();
|
|
5906
|
+
fn();
|
|
5907
|
+
},
|
|
5908
|
+
[wakeChrome]
|
|
5909
|
+
);
|
|
5897
5910
|
const hangUp = react.useCallback(() => {
|
|
5898
5911
|
sfu.leave();
|
|
5899
5912
|
mesh.leave();
|
|
5900
5913
|
void calls.hangUp();
|
|
5901
5914
|
}, [sfu, mesh, calls]);
|
|
5902
5915
|
const alone = usingSfu ? sfu.alone : mesh.alone;
|
|
5916
|
+
const endedOnEmpty = react.useRef(false);
|
|
5917
|
+
if (calls.phase !== "active") endedOnEmpty.current = false;
|
|
5903
5918
|
react.useEffect(() => {
|
|
5904
|
-
if (!alone || calls.phase !== "active") return;
|
|
5919
|
+
if (!alone || calls.phase !== "active" || endedOnEmpty.current) return;
|
|
5920
|
+
endedOnEmpty.current = true;
|
|
5905
5921
|
hangUp();
|
|
5906
5922
|
}, [alone, calls.phase, hangUp]);
|
|
5907
5923
|
const micOn = usingSfu ? sfu.micEnabled : !mesh.muted;
|
|
@@ -6012,7 +6028,7 @@ function CallScreen({
|
|
|
6012
6028
|
icon: micOn ? "mic" : "mic-off",
|
|
6013
6029
|
label: micOn ? "Mute" : "Unmute",
|
|
6014
6030
|
active: !micOn,
|
|
6015
|
-
onPress: toggleMic,
|
|
6031
|
+
onPress: withWake(toggleMic),
|
|
6016
6032
|
accessibilityLabel: micOn ? "Mute microphone" : "Unmute microphone"
|
|
6017
6033
|
}
|
|
6018
6034
|
),
|
|
@@ -6022,7 +6038,7 @@ function CallScreen({
|
|
|
6022
6038
|
icon: speakerIcon(audio),
|
|
6023
6039
|
label: speakerLabel(audio),
|
|
6024
6040
|
active: audio.speakerOn,
|
|
6025
|
-
onPress: onSpeakerPress,
|
|
6041
|
+
onPress: withWake(onSpeakerPress),
|
|
6026
6042
|
accessibilityLabel: "Audio output"
|
|
6027
6043
|
}
|
|
6028
6044
|
),
|
|
@@ -6032,7 +6048,7 @@ function CallScreen({
|
|
|
6032
6048
|
icon: videoOn ? "video" : "video-off",
|
|
6033
6049
|
label: "Camera",
|
|
6034
6050
|
active: !videoOn,
|
|
6035
|
-
onPress: () => void sfu.toggleCamera(),
|
|
6051
|
+
onPress: withWake(() => void sfu.toggleCamera()),
|
|
6036
6052
|
accessibilityLabel: videoOn ? "Turn camera off" : "Turn camera on"
|
|
6037
6053
|
}
|
|
6038
6054
|
),
|
|
@@ -6041,7 +6057,7 @@ function CallScreen({
|
|
|
6041
6057
|
{
|
|
6042
6058
|
icon: "camera-flip",
|
|
6043
6059
|
label: "Flip",
|
|
6044
|
-
onPress: () => void sfu.switchCamera(),
|
|
6060
|
+
onPress: withWake(() => void sfu.switchCamera()),
|
|
6045
6061
|
accessibilityLabel: "Switch camera"
|
|
6046
6062
|
}
|
|
6047
6063
|
)
|