@pickleball/expo-sdk 0.2.0 → 1.0.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 +41 -0
- package/README.md +155 -101
- package/dist/advanced-DcbHBCGb.d.ts +300 -0
- package/dist/advanced-DeQwg7MK.d.cts +300 -0
- package/dist/advanced.cjs +14 -2
- package/dist/advanced.d.cts +2 -2
- package/dist/advanced.d.ts +2 -2
- package/dist/advanced.js +17 -5
- package/dist/camera-controls-By8tHigY.d.cts +97 -0
- package/dist/camera-controls-rCBUGGPC.d.ts +97 -0
- package/dist/chunk-62YV3PCD.cjs +139 -0
- package/dist/chunk-6F3HN6US.js +50 -0
- package/dist/chunk-6YE5BL3A.cjs +50 -0
- package/dist/chunk-7Z7TN5N3.js +318 -0
- package/dist/{chunk-TRLASNPQ.cjs → chunk-GXQYMPHE.cjs} +1 -1
- package/dist/{chunk-TBPR2QND.cjs → chunk-IUIRVKJI.cjs} +736 -399
- package/dist/chunk-TBUEXRFQ.cjs +318 -0
- package/dist/{chunk-FODE2W2H.js → chunk-XGP2MN5R.js} +688 -351
- package/dist/{chunk-6JOMESNT.js → chunk-XL4CISVQ.js} +1 -1
- package/dist/chunk-ZSKSXOCZ.js +139 -0
- package/dist/convex-command-subscription-Cabh9tND.d.ts +41 -0
- package/dist/convex-command-subscription-DUgpu75l.d.cts +41 -0
- package/dist/device-agent/index.cjs +973 -44
- package/dist/device-agent/index.d.cts +339 -3
- package/dist/device-agent/index.d.ts +339 -3
- package/dist/device-agent/index.js +940 -11
- package/dist/{engine-CCSSqPbZ.d.cts → engine-BSvSdCSE.d.cts} +227 -2
- package/dist/{engine-CCSSqPbZ.d.ts → engine-BSvSdCSE.d.ts} +227 -2
- package/dist/index.cjs +419 -937
- package/dist/index.d.cts +315 -32
- package/dist/index.d.ts +315 -32
- package/dist/index.js +423 -941
- package/dist/plugin.cjs +11 -13
- package/dist/plugin.d.cts +15 -1
- package/dist/plugin.d.ts +15 -1
- package/dist/plugin.js +7 -9
- package/dist/realtime/index.cjs +31 -0
- package/dist/realtime/index.d.cts +15 -0
- package/dist/realtime/index.d.ts +15 -0
- package/dist/realtime/index.js +31 -0
- package/dist/ui/index.cjs +1297 -0
- package/dist/ui/index.d.cts +493 -0
- package/dist/ui/index.d.ts +493 -0
- package/dist/ui/index.js +1297 -0
- package/dist/version.cjs +2 -2
- package/dist/version.js +1 -1
- package/package.json +31 -15
- package/src/advanced.ts +11 -9
- package/src/auto-resume.tsx +259 -0
- package/src/camera-controls.ts +99 -0
- package/src/camera-grant-provider.ts +392 -0
- package/src/camera-settings.ts +133 -0
- package/src/contracts.ts +73 -0
- package/src/device-agent/agent.ts +262 -9
- package/src/device-agent/beat-policy.ts +46 -0
- package/src/device-agent/component.tsx +11 -0
- package/src/device-agent/convex-beat-transport.ts +140 -0
- package/src/device-agent/convex-command-subscription.ts +101 -0
- package/src/device-agent/convex-control-channel.ts +7 -1
- package/src/device-agent/http-transport.ts +22 -1
- package/src/device-agent/index.ts +22 -0
- package/src/device-agent/mqtt-channel.ts +379 -0
- package/src/device-agent/mqtt-codec.ts +347 -0
- package/src/device-agent/tournament.ts +352 -0
- package/src/engine.ts +580 -15
- package/src/http-session-provider.ts +21 -189
- package/src/index.ts +84 -5
- package/src/local-video-quality.ts +43 -0
- package/src/native-runtime.ts +234 -78
- package/src/plugin.ts +19 -6
- package/src/provider.tsx +94 -18
- package/src/realtime/index.ts +56 -0
- package/src/resume-policy.ts +85 -0
- package/src/resume.ts +132 -0
- package/src/rtmp-room-adapter.ts +164 -12
- package/src/session-grant.ts +256 -0
- package/src/ui/camera-screen.tsx +484 -0
- package/src/ui/controls-sheet.tsx +445 -0
- package/src/ui/copy.ts +326 -0
- package/src/ui/helpers.ts +105 -0
- package/src/ui/hooks.ts +59 -0
- package/src/ui/index.ts +42 -0
- package/src/ui/preview-view.tsx +39 -0
- package/src/ui/primitives.tsx +304 -0
- package/src/uplink-check.ts +173 -0
- package/dist/advanced-BXDrDl1h.d.ts +0 -316
- package/dist/advanced-BdAa2Erv.d.cts +0 -316
- package/src/livekit-room-adapter.ts +0 -390
- package/src/livestream-screen.tsx +0 -1002
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
+
var _chunkGXQYMPHEcjs = require('./chunk-GXQYMPHE.cjs');
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
|
|
@@ -14,6 +15,7 @@
|
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
|
|
18
|
+
var _chunk62YV3PCDcjs = require('./chunk-62YV3PCD.cjs');
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
|
|
@@ -24,864 +26,60 @@
|
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
|
|
27
|
-
var _chunkTBPR2QNDcjs = require('./chunk-TBPR2QND.cjs');
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
var _chunkTRLASNPQcjs = require('./chunk-TRLASNPQ.cjs');
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
var _chunk7OX2DSKIcjs = require('./chunk-7OX2DSKI.cjs');
|
|
34
33
|
|
|
35
|
-
// src/livestream-screen.tsx
|
|
36
|
-
var _react = require('react'); var _react2 = _interopRequireDefault(_react);
|
|
37
34
|
|
|
38
35
|
|
|
39
36
|
|
|
40
37
|
|
|
41
38
|
|
|
42
39
|
|
|
43
|
-
var _reactnative = require('react-native');
|
|
44
|
-
var _reactnativesafeareacontext = require('react-native-safe-area-context');
|
|
45
40
|
|
|
46
|
-
// ../shared/src/court-detection.ts
|
|
47
|
-
var COURT_DETECTION_MAX_IMAGE_BYTES = 3 * 1024 * 1024;
|
|
48
|
-
var KITCHEN_FAR_Y = 15 / 44;
|
|
49
|
-
var KITCHEN_NEAR_Y = 29 / 44;
|
|
50
41
|
|
|
51
|
-
// ../shared/src/index.ts
|
|
52
|
-
var MAX_LIVE_DURATION_MS = 6 * 60 * 60 * 1e3;
|
|
53
|
-
var EMPTY_ROOM_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
54
|
-
var STALE_SCHEDULED_MS = 48 * 60 * 60 * 1e3;
|
|
55
|
-
var NO_PUBLISHER_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
56
|
-
function sessionShortCode(sessionId) {
|
|
57
|
-
const AMBIGUOUS = /[01ilo]/g;
|
|
58
|
-
const cleaned = sessionId.toLowerCase().replace(AMBIGUOUS, "");
|
|
59
|
-
return cleaned.slice(-6).toUpperCase().padStart(6, "X");
|
|
60
|
-
}
|
|
61
42
|
|
|
62
|
-
|
|
63
|
-
var
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
landscapeHint: "C\u1EA7m m\xE1y ngang trong su\u1ED1t bu\u1ED5i quay.",
|
|
103
|
-
rotatePortrait: "Xoay m\xE1y d\u1ECDc theo khung 9:16 \u0111\u1EC3 b\u1EAFt \u0111\u1EA7u ph\xE1t.",
|
|
104
|
-
rotateLandscape: "Xoay m\xE1y ngang theo khung 16:9 \u0111\u1EC3 b\u1EAFt \u0111\u1EA7u ph\xE1t.",
|
|
105
|
-
lensLabel: "\u1ED0ng k\xEDnh",
|
|
106
|
-
cameraLabel: "Camera",
|
|
107
|
-
cameraFront: "Tr\u01B0\u1EDBc",
|
|
108
|
-
cameraBack: "Sau",
|
|
109
|
-
visibilityLabel: "Ch\u1EBF \u0111\u1ED9",
|
|
110
|
-
visPublic: "C\xF4ng khai",
|
|
111
|
-
visPrivate: "Ri\xEAng t\u01B0",
|
|
112
|
-
backToPreview: "Quay l\u1EA1i m\xE0n h\xECnh ch\u1EDD"
|
|
113
|
-
},
|
|
114
|
-
en: {
|
|
115
|
-
states: {
|
|
116
|
-
idle: "Ready",
|
|
117
|
-
preparing: "Preparing\u2026",
|
|
118
|
-
preview: "Preview",
|
|
119
|
-
connecting: "Connecting\u2026",
|
|
120
|
-
standby: "READY",
|
|
121
|
-
live: "LIVE",
|
|
122
|
-
reconnecting: "Reconnecting\u2026",
|
|
123
|
-
ending: "Ending\u2026",
|
|
124
|
-
ended: "Livestream ended",
|
|
125
|
-
error: "Something went wrong"
|
|
126
|
-
},
|
|
127
|
-
consent: "Recording consent",
|
|
128
|
-
consentDetail: "I consent to recording and saving this livestream as video.",
|
|
129
|
-
start: "Connect",
|
|
130
|
-
startStandby: "Standby Mode",
|
|
131
|
-
startLive: "Go Live Now",
|
|
132
|
-
confirmStart: "Confirm start",
|
|
133
|
-
afterThree: "Connect in 3 seconds",
|
|
134
|
-
live: "LIVE",
|
|
135
|
-
endLabel: "End livestream",
|
|
136
|
-
endQuestion: "End this livestream?",
|
|
137
|
-
end: "End",
|
|
138
|
-
cancel: "Cancel",
|
|
139
|
-
ended: "Livestream ended",
|
|
140
|
-
retry: "Try again",
|
|
141
|
-
errorDetail: "Technical details",
|
|
142
|
-
offline: "Network offline",
|
|
143
|
-
flip: "Flip camera",
|
|
144
|
-
playLabel: "Start broadcasting",
|
|
145
|
-
pauseLabel: "Pause broadcasting",
|
|
146
|
-
mic: "Microphone",
|
|
147
|
-
orientationLabel: "Frame",
|
|
148
|
-
portrait: "9:16 Tall",
|
|
149
|
-
landscape: "16:9 Wide",
|
|
150
|
-
portraitHint: "Hold the phone upright while filming.",
|
|
151
|
-
landscapeHint: "Hold the phone sideways while filming.",
|
|
152
|
-
rotatePortrait: "Rotate the phone upright to match the 9:16 frame before going live.",
|
|
153
|
-
rotateLandscape: "Rotate the phone sideways to match the 16:9 frame before going live.",
|
|
154
|
-
lensLabel: "Lens",
|
|
155
|
-
cameraLabel: "Camera",
|
|
156
|
-
cameraFront: "Front",
|
|
157
|
-
cameraBack: "Back",
|
|
158
|
-
visibilityLabel: "Mode",
|
|
159
|
-
visPublic: "Public",
|
|
160
|
-
visPrivate: "Private",
|
|
161
|
-
backToPreview: "Back to standby"
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
var errorTitle = {
|
|
165
|
-
vi: {
|
|
166
|
-
PERMISSION_DENIED: "C\u1EA7n quy\u1EC1n Camera v\xE0 Micr\xF4",
|
|
167
|
-
NETWORK_UNAVAILABLE: "Kh\xF4ng c\xF3 k\u1EBFt n\u1ED1i m\u1EA1ng",
|
|
168
|
-
TOKEN_EXPIRED: "Phi\xEAn x\xE1c th\u1EF1c \u0111\xE3 h\u1EBFt h\u1EA1n",
|
|
169
|
-
SDK_UPGRADE_REQUIRED: "C\u1EA7n c\u1EADp nh\u1EADt \u1EE9ng d\u1EE5ng",
|
|
170
|
-
UNSUPPORTED_RUNTIME: "M\xF4i tr\u01B0\u1EDDng ch\u1EA1y kh\xF4ng \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3",
|
|
171
|
-
SESSION_CONFLICT: "\u0110ang c\xF3 phi\xEAn ph\xE1t kh\xE1c",
|
|
172
|
-
RECORDING_FAILED: "Kh\xF4ng th\u1EC3 ghi h\xECnh",
|
|
173
|
-
CONSENT_REQUIRED: "C\u1EA7n \u0111\u1ED3ng \xFD ghi h\xECnh",
|
|
174
|
-
SDK_DISABLED: "T\xEDnh n\u0103ng ph\xE1t tr\u1EF1c ti\u1EBFp \u0111ang t\u1EAFt",
|
|
175
|
-
CONFIGURATION_ERROR: "C\u1EA5u h\xECnh SDK ch\u01B0a \u0111\xFAng",
|
|
176
|
-
INVALID_RESPONSE: "Ph\u1EA3n h\u1ED3i m\xE1y ch\u1EE7 kh\xF4ng h\u1EE3p l\u1EC7",
|
|
177
|
-
TIMEOUT: "Y\xEAu c\u1EA7u qu\xE1 th\u1EDDi gian",
|
|
178
|
-
UNKNOWN: "\u0110\xE3 x\u1EA3y ra l\u1ED7i"
|
|
179
|
-
},
|
|
180
|
-
en: {
|
|
181
|
-
PERMISSION_DENIED: "Camera and Microphone access required",
|
|
182
|
-
NETWORK_UNAVAILABLE: "No network connection",
|
|
183
|
-
TOKEN_EXPIRED: "Authentication expired",
|
|
184
|
-
SDK_UPGRADE_REQUIRED: "App update required",
|
|
185
|
-
UNSUPPORTED_RUNTIME: "Unsupported runtime",
|
|
186
|
-
SESSION_CONFLICT: "Another livestream is active",
|
|
187
|
-
RECORDING_FAILED: "Recording failed",
|
|
188
|
-
CONSENT_REQUIRED: "Recording consent required",
|
|
189
|
-
SDK_DISABLED: "Livestreaming is disabled",
|
|
190
|
-
CONFIGURATION_ERROR: "SDK configuration error",
|
|
191
|
-
INVALID_RESPONSE: "Invalid server response",
|
|
192
|
-
TIMEOUT: "Request timed out",
|
|
193
|
-
UNKNOWN: "Something went wrong"
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
var remediation = {
|
|
197
|
-
vi: {
|
|
198
|
-
PERMISSION_DENIED: "M\u1EDF C\xE0i \u0111\u1EB7t v\xE0 cho ph\xE9p Camera c\xF9ng Micr\xF4, sau \u0111\xF3 th\u1EED l\u1EA1i.",
|
|
199
|
-
NETWORK_UNAVAILABLE: "Ki\u1EC3m tra Wi-Fi ho\u1EB7c d\u1EEF li\u1EC7u di \u0111\u1ED9ng r\u1ED3i th\u1EED l\u1EA1i.",
|
|
200
|
-
TOKEN_EXPIRED: "Phi\xEAn x\xE1c th\u1EF1c \u0111\xE3 h\u1EBFt h\u1EA1n. H\xE3y k\u1EBFt n\u1ED1i m\u1EA1ng v\xE0 th\u1EED l\u1EA1i.",
|
|
201
|
-
SDK_UPGRADE_REQUIRED: "C\u1EADp nh\u1EADt \u1EE9ng d\u1EE5ng l\xEAn b\u1EA3n m\u1EDBi nh\u1EA5t v\xE0 c\xE0i l\u1EA1i Development Build.",
|
|
202
|
-
UNSUPPORTED_RUNTIME: "C\xE0i Development Build tr\xEAn iOS ho\u1EB7c Android; Expo Go v\xE0 web kh\xF4ng \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3.",
|
|
203
|
-
SESSION_CONFLICT: "K\u1EBFt th\xFAc phi\xEAn ph\xE1t \u0111ang ho\u1EA1t \u0111\u1ED9ng tr\u01B0\u1EDBc khi b\u1EAFt \u0111\u1EA7u phi\xEAn m\u1EDBi.",
|
|
204
|
-
RECORDING_FAILED: "Kh\xF4ng th\u1EC3 t\u1EA1o b\u1EA3n ghi m\xE1y ch\u1EE7. H\xE3y th\u1EED l\u1EA1i ho\u1EB7c li\xEAn h\u1EC7 h\u1ED7 tr\u1EE3.",
|
|
205
|
-
CONSENT_REQUIRED: "\u0110\u1ED3ng \xFD ghi h\xECnh tr\u01B0\u1EDBc khi b\u1EAFt \u0111\u1EA7u ph\xE1t tr\u1EF1c ti\u1EBFp.",
|
|
206
|
-
SDK_DISABLED: "T\xEDnh n\u0103ng \u0111ang b\u1ECB t\u1EAFt cho \u1EE9ng d\u1EE5ng n\xE0y. H\xE3y li\xEAn h\u1EC7 qu\u1EA3n tr\u1ECB vi\xEAn.",
|
|
207
|
-
CONFIGURATION_ERROR: "Ki\u1EC3m tra c\u1EA5u h\xECnh Provider v\xE0 config plugin, sau \u0111\xF3 rebuild \u1EE9ng d\u1EE5ng.",
|
|
208
|
-
INVALID_RESPONSE: "M\xE1y ch\u1EE7 tr\u1EA3 v\u1EC1 d\u1EEF li\u1EC7u kh\xF4ng h\u1EE3p l\u1EC7. H\xE3y th\u1EED l\u1EA1i ho\u1EB7c li\xEAn h\u1EC7 h\u1ED7 tr\u1EE3.",
|
|
209
|
-
TIMEOUT: "Y\xEAu c\u1EA7u qu\xE1 th\u1EDDi gian. Ki\u1EC3m tra k\u1EBFt n\u1ED1i r\u1ED3i th\u1EED l\u1EA1i.",
|
|
210
|
-
UNKNOWN: "Th\u1EED l\u1EA1i. N\u1EBFu l\u1ED7i ti\u1EBFp di\u1EC5n, h\xE3y li\xEAn h\u1EC7 h\u1ED7 tr\u1EE3."
|
|
211
|
-
},
|
|
212
|
-
en: {
|
|
213
|
-
PERMISSION_DENIED: "Open Settings and allow Camera and Microphone, then try again.",
|
|
214
|
-
NETWORK_UNAVAILABLE: "Check Wi-Fi or mobile data, then try again.",
|
|
215
|
-
TOKEN_EXPIRED: "Your authentication has expired. Connect to the network and try again.",
|
|
216
|
-
SDK_UPGRADE_REQUIRED: "Update the app to the latest version and install a new Development Build.",
|
|
217
|
-
UNSUPPORTED_RUNTIME: "Install an iOS or Android Development Build; Expo Go and web are unsupported.",
|
|
218
|
-
SESSION_CONFLICT: "End the active livestream before starting another one.",
|
|
219
|
-
RECORDING_FAILED: "The server recording could not be created. Try again or contact support.",
|
|
220
|
-
CONSENT_REQUIRED: "Accept recording consent before going live.",
|
|
221
|
-
SDK_DISABLED: "Livestreaming is disabled for this app. Contact an administrator.",
|
|
222
|
-
CONFIGURATION_ERROR: "Check the Provider and config plugin setup, then rebuild the app.",
|
|
223
|
-
INVALID_RESPONSE: "The server returned invalid data. Try again or contact support.",
|
|
224
|
-
TIMEOUT: "The request timed out. Check your connection and try again.",
|
|
225
|
-
UNKNOWN: "Try again. If the problem continues, contact support."
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
function LivestreamScreen(props) {
|
|
229
|
-
const state = _chunkTBPR2QNDcjs.useLivestream.call(void 0, );
|
|
230
|
-
const strings = copy[state.locale];
|
|
231
|
-
const insets = _reactnativesafeareacontext.useSafeAreaInsets.call(void 0, );
|
|
232
|
-
const { width: windowWidth, height: windowHeight } = _reactnative.useWindowDimensions.call(void 0, );
|
|
233
|
-
const landscapeUi = windowWidth > windowHeight;
|
|
234
|
-
const panelWidth = Math.min(360, Math.round(windowWidth * 0.42));
|
|
235
|
-
const selectedOrientation = _nullishCoalesce(state.captureOrientation, () => ( "portrait"));
|
|
236
|
-
const orientationMismatch = props.physicalOrientation != null && props.physicalOrientation !== selectedOrientation;
|
|
237
|
-
const rotateWarning = selectedOrientation === "landscape" ? strings.rotateLandscape : strings.rotatePortrait;
|
|
238
|
-
const consentStorageKey = `@pickleball/consent:${props.input.consentVersion}`;
|
|
239
|
-
const storedConsent = (() => {
|
|
240
|
-
try {
|
|
241
|
-
return _optionalChain([globalThis, 'access', _ => _.localStorage, 'optionalAccess', _2 => _2.getItem, 'call', _3 => _3(consentStorageKey)]) === "yes";
|
|
242
|
-
} catch (e) {
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
})();
|
|
246
|
-
const [consented, setConsented] = _react.useState.call(void 0, storedConsent);
|
|
247
|
-
const [confirmingEnd, setConfirmingEnd] = _react.useState.call(void 0, false);
|
|
248
|
-
const [visibility, setVisibility] = _react.useState.call(void 0,
|
|
249
|
-
_nullishCoalesce(props.input.visibility, () => ( "public"))
|
|
250
|
-
);
|
|
251
|
-
const inLive = state.state === "standby" || state.state === "live" || state.state === "reconnecting";
|
|
252
|
-
const isPublishing = state.state === "live";
|
|
253
|
-
const [liveControlsVisible, setLiveControlsVisible] = _react.useState.call(void 0, true);
|
|
254
|
-
const [controlsTick, setControlsTick] = _react.useState.call(void 0, 0);
|
|
255
|
-
const showLiveControls = () => {
|
|
256
|
-
setLiveControlsVisible(true);
|
|
257
|
-
setControlsTick((tick) => tick + 1);
|
|
258
|
-
};
|
|
259
|
-
_react.useEffect.call(void 0, () => {
|
|
260
|
-
if (inLive) setLiveControlsVisible(true);
|
|
261
|
-
}, [inLive]);
|
|
262
|
-
_react.useEffect.call(void 0, () => {
|
|
263
|
-
if (!inLive || !liveControlsVisible || confirmingEnd) return;
|
|
264
|
-
const timer = setTimeout(() => setLiveControlsVisible(false), 1e4);
|
|
265
|
-
return () => clearTimeout(timer);
|
|
266
|
-
}, [inLive, liveControlsVisible, confirmingEnd, controlsTick]);
|
|
267
|
-
_react.useEffect.call(void 0, () => {
|
|
268
|
-
if (state.state === "idle") void state.prepare().catch(() => void 0);
|
|
269
|
-
}, [state.prepare, state.state]);
|
|
270
|
-
const connect = (autoPublish = false) => {
|
|
271
|
-
try {
|
|
272
|
-
_optionalChain([globalThis, 'access', _4 => _4.localStorage, 'optionalAccess', _5 => _5.setItem, 'call', _6 => _6(consentStorageKey, "yes")]);
|
|
273
|
-
} catch (e2) {
|
|
274
|
-
}
|
|
275
|
-
void state.start({ ...props.input, visibility }, { autoPublish }).catch(() => void 0);
|
|
276
|
-
};
|
|
277
|
-
const autoConnectedRef = _react2.default.useRef(false);
|
|
278
|
-
_react.useEffect.call(void 0, () => {
|
|
279
|
-
if (props.autoConnect !== true || autoConnectedRef.current) return;
|
|
280
|
-
if (state.state !== "preview" || !storedConsent) return;
|
|
281
|
-
autoConnectedRef.current = true;
|
|
282
|
-
connect();
|
|
283
|
-
}, [props.autoConnect, state.state, storedConsent]);
|
|
284
|
-
const theme = state.theme;
|
|
285
|
-
const bodyFont = fontOf(theme);
|
|
286
|
-
const boldFont = fontOf(theme, true);
|
|
287
|
-
const displayFont = theme.displayFontFamily ? { fontFamily: theme.displayFontFamily } : boldFont;
|
|
288
|
-
const button = (color) => ({
|
|
289
|
-
minHeight: 40,
|
|
290
|
-
minWidth: 44,
|
|
291
|
-
paddingHorizontal: 16,
|
|
292
|
-
alignItems: "center",
|
|
293
|
-
justifyContent: "center",
|
|
294
|
-
backgroundColor: color,
|
|
295
|
-
borderRadius: 999
|
|
296
|
-
});
|
|
297
|
-
const secondaryButton = {
|
|
298
|
-
...button(theme.elevated),
|
|
299
|
-
borderWidth: 1,
|
|
300
|
-
borderColor: theme.hairline
|
|
301
|
-
};
|
|
302
|
-
const cta = (enabled) => ({
|
|
303
|
-
minHeight: 48,
|
|
304
|
-
alignItems: "center",
|
|
305
|
-
justifyContent: "center",
|
|
306
|
-
borderRadius: 999,
|
|
307
|
-
backgroundColor: enabled ? theme.accent : theme.elevated,
|
|
308
|
-
...enabled ? {
|
|
309
|
-
shadowColor: theme.accent,
|
|
310
|
-
shadowOpacity: 0.45,
|
|
311
|
-
shadowRadius: 14,
|
|
312
|
-
shadowOffset: { width: 0, height: 0 },
|
|
313
|
-
elevation: 8
|
|
314
|
-
} : { borderWidth: 1, borderColor: theme.hairline }
|
|
315
|
-
});
|
|
316
|
-
const fab = (bg) => ({
|
|
317
|
-
width: 48,
|
|
318
|
-
height: 48,
|
|
319
|
-
borderRadius: 24,
|
|
320
|
-
alignItems: "center",
|
|
321
|
-
justifyContent: "center",
|
|
322
|
-
backgroundColor: bg,
|
|
323
|
-
borderWidth: 1,
|
|
324
|
-
borderColor: theme.hairline
|
|
325
|
-
});
|
|
326
|
-
const statusLabel = statusText(state.state, strings);
|
|
327
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
328
|
-
_reactnative.View,
|
|
329
|
-
{
|
|
330
|
-
style: {
|
|
331
|
-
flex: 1,
|
|
332
|
-
flexDirection: landscapeUi ? "row" : "column",
|
|
333
|
-
backgroundColor: theme.background,
|
|
334
|
-
paddingTop: insets.top,
|
|
335
|
-
paddingBottom: insets.bottom,
|
|
336
|
-
paddingLeft: insets.left,
|
|
337
|
-
paddingRight: insets.right,
|
|
338
|
-
...props.style
|
|
339
|
-
},
|
|
340
|
-
children: [
|
|
341
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.View, { style: { flex: 1 }, children: props.renderPreview ? props.renderPreview(state) : inLive ? (
|
|
342
|
-
// Live: camera full màn hình; chạm để hiện nút điều khiển.
|
|
343
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Pressable, { style: { flex: 1 }, onPress: showLiveControls, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DefaultPreview, { state }) })
|
|
344
|
-
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
345
|
-
AspectBox,
|
|
346
|
-
{
|
|
347
|
-
ratio: selectedOrientation === "landscape" ? 16 / 9 : 9 / 16,
|
|
348
|
-
background: theme.background,
|
|
349
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DefaultPreview, { state })
|
|
350
|
-
}
|
|
351
|
-
) }),
|
|
352
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
353
|
-
_reactnative.View,
|
|
354
|
-
{
|
|
355
|
-
style: {
|
|
356
|
-
position: "absolute",
|
|
357
|
-
top: insets.top + 12,
|
|
358
|
-
left: 12,
|
|
359
|
-
right: 12,
|
|
360
|
-
gap: 8
|
|
361
|
-
},
|
|
362
|
-
children: props.renderHeader ? props.renderHeader(state) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
363
|
-
_reactnative.View,
|
|
364
|
-
{
|
|
365
|
-
style: {
|
|
366
|
-
alignSelf: "flex-start",
|
|
367
|
-
flexDirection: "row",
|
|
368
|
-
alignItems: "center",
|
|
369
|
-
gap: 8,
|
|
370
|
-
paddingVertical: 6,
|
|
371
|
-
paddingHorizontal: 12,
|
|
372
|
-
borderRadius: 999,
|
|
373
|
-
borderWidth: 1,
|
|
374
|
-
borderColor: theme.hairline,
|
|
375
|
-
backgroundColor: theme.overlay,
|
|
376
|
-
...state.state === "live" ? { shadowColor: theme.accent, shadowOpacity: 0.4, shadowRadius: 10, shadowOffset: { width: 0, height: 0 }, elevation: 6 } : {}
|
|
377
|
-
},
|
|
378
|
-
children: [
|
|
379
|
-
state.state === "live" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.View, { style: { width: 8, height: 8, borderRadius: 4, backgroundColor: theme.accent } }) : null,
|
|
380
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
381
|
-
_reactnative.Text,
|
|
382
|
-
{
|
|
383
|
-
selectable: true,
|
|
384
|
-
style: [
|
|
385
|
-
{
|
|
386
|
-
color: state.state === "live" ? theme.accent : theme.foreground,
|
|
387
|
-
fontSize: 12,
|
|
388
|
-
fontWeight: "700",
|
|
389
|
-
letterSpacing: 0.6
|
|
390
|
-
},
|
|
391
|
-
displayFont
|
|
392
|
-
],
|
|
393
|
-
children: statusLabel
|
|
394
|
-
}
|
|
395
|
-
),
|
|
396
|
-
state.state === "live" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { selectable: true, style: [{ color: theme.textSecondary, fontSize: 12, fontVariant: ["tabular-nums"] }, bodyFont], children: formatElapsed(state.elapsedMs) }) : null,
|
|
397
|
-
state.sessionId ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
398
|
-
_reactnative.Text,
|
|
399
|
-
{
|
|
400
|
-
selectable: true,
|
|
401
|
-
style: [{ color: theme.textSecondary, fontSize: 12, letterSpacing: 1 }, bodyFont],
|
|
402
|
-
children: sessionShortCode(state.sessionId)
|
|
403
|
-
}
|
|
404
|
-
) : null,
|
|
405
|
-
inLive && state.deviceMetrics ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
406
|
-
_reactnative.Text,
|
|
407
|
-
{
|
|
408
|
-
selectable: true,
|
|
409
|
-
numberOfLines: 1,
|
|
410
|
-
style: [{ color: theme.textSecondary, fontSize: 12 }, bodyFont],
|
|
411
|
-
children: [
|
|
412
|
-
state.deviceMetrics.batteryPct !== void 0 ? `\u{1F50B}${state.deviceMetrics.batteryPct}%${state.deviceMetrics.charging ? "\u26A1" : ""}` : null,
|
|
413
|
-
state.deviceMetrics.netType ? `\u{1F4F6}${state.deviceMetrics.netType}` : null,
|
|
414
|
-
_nullishCoalesce(state.deviceMetrics.connQuality, () => ( null))
|
|
415
|
-
].filter(Boolean).join(" ")
|
|
416
|
-
}
|
|
417
|
-
) : null,
|
|
418
|
-
!state.isOnline ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { selectable: true, style: [{ color: theme.danger, fontSize: 12 }, bodyFont], children: strings.offline }) : null
|
|
419
|
-
]
|
|
420
|
-
}
|
|
421
|
-
)
|
|
422
|
-
}
|
|
423
|
-
),
|
|
424
|
-
!inLive || state.error ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.View, { style: landscapeUi ? { width: panelWidth } : null, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
425
|
-
_reactnative.ScrollView,
|
|
426
|
-
{
|
|
427
|
-
style: landscapeUi ? { flex: 1 } : void 0,
|
|
428
|
-
scrollEnabled: landscapeUi,
|
|
429
|
-
contentContainerStyle: landscapeUi ? { flexGrow: 1, justifyContent: "center" } : void 0,
|
|
430
|
-
children: state.error ? props.renderError ? props.renderError(state) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _reactnative.View, { style: { padding: 14, gap: 10, backgroundColor: theme.overlay }, children: [
|
|
431
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { selectable: true, accessibilityRole: "alert", style: [{ color: theme.foreground, fontSize: 15, fontWeight: "700" }, displayFont], children: errorTitle[state.locale][state.error.code] }),
|
|
432
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { selectable: true, style: [{ color: theme.textSecondary, fontSize: 13 }, bodyFont], children: remediation[state.locale][state.error.code] }),
|
|
433
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _reactnative.Text, { selectable: true, style: [{ color: theme.muted, fontSize: 11 }, bodyFont], children: [
|
|
434
|
-
strings.errorDetail,
|
|
435
|
-
": ",
|
|
436
|
-
state.error.message
|
|
437
|
-
] }),
|
|
438
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Pressable, { accessibilityRole: "button", onPress: () => void state.retry(), style: cta(true), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { style: [{ color: theme.ink, fontSize: 14, fontWeight: "800" }, boldFont], children: strings.retry }) })
|
|
439
|
-
] }) : props.renderControls ? props.renderControls(state) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _reactnative.View, { style: { padding: 14, gap: 10, backgroundColor: theme.overlay }, children: [
|
|
440
|
-
state.state === "preview" ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
441
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ControlRow, { label: strings.orientationLabel, theme, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
442
|
-
Segmented,
|
|
443
|
-
{
|
|
444
|
-
theme,
|
|
445
|
-
value: selectedOrientation,
|
|
446
|
-
onSelect: (value) => void state.setCaptureOrientation(value),
|
|
447
|
-
options: [
|
|
448
|
-
{ value: "portrait", label: strings.portrait },
|
|
449
|
-
{ value: "landscape", label: strings.landscape }
|
|
450
|
-
]
|
|
451
|
-
}
|
|
452
|
-
) }),
|
|
453
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ControlRow, { label: strings.visibilityLabel, theme, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
454
|
-
Segmented,
|
|
455
|
-
{
|
|
456
|
-
theme,
|
|
457
|
-
value: visibility,
|
|
458
|
-
onSelect: (value) => setVisibility(value),
|
|
459
|
-
options: [
|
|
460
|
-
{ value: "public", label: strings.visPublic },
|
|
461
|
-
{ value: "private", label: strings.visPrivate }
|
|
462
|
-
]
|
|
463
|
-
}
|
|
464
|
-
) }),
|
|
465
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ControlRow, { label: strings.cameraLabel, theme, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
466
|
-
Segmented,
|
|
467
|
-
{
|
|
468
|
-
theme,
|
|
469
|
-
value: state.isCameraFront ? "front" : "back",
|
|
470
|
-
onSelect: (value) => {
|
|
471
|
-
if (value === "front" !== state.isCameraFront) {
|
|
472
|
-
void state.switchCamera();
|
|
473
|
-
}
|
|
474
|
-
},
|
|
475
|
-
options: [
|
|
476
|
-
{ value: "back", label: strings.cameraBack },
|
|
477
|
-
{ value: "front", label: strings.cameraFront }
|
|
478
|
-
]
|
|
479
|
-
}
|
|
480
|
-
) }),
|
|
481
|
-
(() => {
|
|
482
|
-
const backLenses = state.cameras.filter(
|
|
483
|
-
(camera) => camera.facing === "environment" && !/dual|triple/i.test(camera.label)
|
|
484
|
-
);
|
|
485
|
-
if (backLenses.length < 2 || state.isCameraFront) return null;
|
|
486
|
-
const lensName = (label) => /ultra\s*wide/i.test(label) ? "0.5x" : /telephoto/i.test(label) ? "Tele" : "1x";
|
|
487
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ControlRow, { label: strings.lensLabel, theme, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
488
|
-
Segmented,
|
|
489
|
-
{
|
|
490
|
-
theme,
|
|
491
|
-
value: state.selectedCameraId,
|
|
492
|
-
onSelect: (deviceId) => void state.selectCamera(deviceId),
|
|
493
|
-
options: backLenses.map((camera) => ({
|
|
494
|
-
value: camera.deviceId,
|
|
495
|
-
label: lensName(camera.label),
|
|
496
|
-
accessibilityLabel: camera.label
|
|
497
|
-
}))
|
|
498
|
-
}
|
|
499
|
-
) });
|
|
500
|
-
})(),
|
|
501
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { selectable: true, style: [{ color: theme.muted, fontSize: 11 }, bodyFont], children: selectedOrientation === "landscape" ? strings.landscapeHint : strings.portraitHint }),
|
|
502
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
503
|
-
_reactnative.Pressable,
|
|
504
|
-
{
|
|
505
|
-
accessibilityRole: "checkbox",
|
|
506
|
-
accessibilityLabel: strings.consent,
|
|
507
|
-
accessibilityState: { checked: consented },
|
|
508
|
-
onPress: () => setConsented((value) => !value),
|
|
509
|
-
style: { minHeight: 40, flexDirection: "row", alignItems: "center", gap: 10 },
|
|
510
|
-
children: [
|
|
511
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
512
|
-
_reactnative.View,
|
|
513
|
-
{
|
|
514
|
-
style: {
|
|
515
|
-
width: 22,
|
|
516
|
-
height: 22,
|
|
517
|
-
borderRadius: theme.radiusSm,
|
|
518
|
-
borderWidth: 1.5,
|
|
519
|
-
borderColor: consented ? theme.accent : theme.hairline,
|
|
520
|
-
backgroundColor: consented ? theme.accent : theme.surface,
|
|
521
|
-
alignItems: "center",
|
|
522
|
-
justifyContent: "center"
|
|
523
|
-
},
|
|
524
|
-
children: consented ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { style: { color: theme.ink, fontSize: 13, fontWeight: "800" }, children: "\u2713" }) : null
|
|
525
|
-
}
|
|
526
|
-
),
|
|
527
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { selectable: true, style: [{ color: theme.textSecondary, fontSize: 13, flex: 1 }, bodyFont], children: strings.consentDetail })
|
|
528
|
-
]
|
|
529
|
-
}
|
|
530
|
-
),
|
|
531
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _reactnative.View, { style: { flexDirection: "row", gap: 8 }, children: [
|
|
532
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
533
|
-
_reactnative.Pressable,
|
|
534
|
-
{
|
|
535
|
-
accessibilityRole: "button",
|
|
536
|
-
accessibilityLabel: strings.startStandby,
|
|
537
|
-
accessibilityState: { disabled: !consented },
|
|
538
|
-
disabled: !consented,
|
|
539
|
-
onPress: () => connect(false),
|
|
540
|
-
style: [
|
|
541
|
-
secondaryButton,
|
|
542
|
-
{
|
|
543
|
-
flex: 1,
|
|
544
|
-
minHeight: 48,
|
|
545
|
-
backgroundColor: consented ? theme.elevated : theme.surface
|
|
546
|
-
}
|
|
547
|
-
],
|
|
548
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
549
|
-
_reactnative.Text,
|
|
550
|
-
{
|
|
551
|
-
style: [
|
|
552
|
-
{
|
|
553
|
-
color: consented ? theme.foreground : theme.muted,
|
|
554
|
-
fontSize: 14,
|
|
555
|
-
fontWeight: "800"
|
|
556
|
-
},
|
|
557
|
-
boldFont
|
|
558
|
-
],
|
|
559
|
-
children: `\u{1F7E1} ${strings.startStandby}`
|
|
560
|
-
}
|
|
561
|
-
)
|
|
562
|
-
}
|
|
563
|
-
),
|
|
564
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
565
|
-
_reactnative.Pressable,
|
|
566
|
-
{
|
|
567
|
-
accessibilityRole: "button",
|
|
568
|
-
accessibilityLabel: strings.startLive,
|
|
569
|
-
accessibilityState: { disabled: !consented },
|
|
570
|
-
disabled: !consented,
|
|
571
|
-
onPress: () => connect(true),
|
|
572
|
-
style: [cta(consented), { flex: 1 }],
|
|
573
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
574
|
-
_reactnative.Text,
|
|
575
|
-
{
|
|
576
|
-
style: [
|
|
577
|
-
{
|
|
578
|
-
color: consented ? theme.ink : theme.muted,
|
|
579
|
-
fontSize: 14,
|
|
580
|
-
fontWeight: "800"
|
|
581
|
-
},
|
|
582
|
-
boldFont
|
|
583
|
-
],
|
|
584
|
-
children: `\u{1F7E2} ${strings.startLive}`
|
|
585
|
-
}
|
|
586
|
-
)
|
|
587
|
-
}
|
|
588
|
-
)
|
|
589
|
-
] })
|
|
590
|
-
] }) : null,
|
|
591
|
-
state.state === "ended" ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _reactnative.View, { style: { gap: 10 }, children: [
|
|
592
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { selectable: true, style: [{ color: theme.foreground, textAlign: "center", fontSize: 15, fontWeight: "700" }, displayFont], children: strings.ended }),
|
|
593
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
594
|
-
_reactnative.Pressable,
|
|
595
|
-
{
|
|
596
|
-
accessibilityRole: "button",
|
|
597
|
-
onPress: () => {
|
|
598
|
-
setConfirmingEnd(false);
|
|
599
|
-
_optionalChain([props, 'access', _7 => _7.onEnded, 'optionalCall', _8 => _8()]);
|
|
600
|
-
void state.prepare();
|
|
601
|
-
},
|
|
602
|
-
style: cta(true),
|
|
603
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { style: [{ color: theme.ink, fontSize: 14, fontWeight: "800" }, boldFont], children: strings.backToPreview })
|
|
604
|
-
}
|
|
605
|
-
)
|
|
606
|
-
] }) : null
|
|
607
|
-
] })
|
|
608
|
-
}
|
|
609
|
-
) }) : null,
|
|
610
|
-
inLive && liveControlsVisible && !confirmingEnd ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
611
|
-
_reactnative.View,
|
|
612
|
-
{
|
|
613
|
-
style: {
|
|
614
|
-
position: "absolute",
|
|
615
|
-
right: 16,
|
|
616
|
-
bottom: insets.bottom + 24,
|
|
617
|
-
gap: 12,
|
|
618
|
-
alignItems: "center"
|
|
619
|
-
},
|
|
620
|
-
children: [
|
|
621
|
-
state.state === "standby" && orientationMismatch ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
622
|
-
_reactnative.Text,
|
|
623
|
-
{
|
|
624
|
-
style: [
|
|
625
|
-
{
|
|
626
|
-
maxWidth: 200,
|
|
627
|
-
textAlign: "center",
|
|
628
|
-
color: theme.danger,
|
|
629
|
-
fontSize: 11,
|
|
630
|
-
fontWeight: "700"
|
|
631
|
-
},
|
|
632
|
-
boldFont
|
|
633
|
-
],
|
|
634
|
-
children: rotateWarning
|
|
635
|
-
}
|
|
636
|
-
) : null,
|
|
637
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
638
|
-
_reactnative.Pressable,
|
|
639
|
-
{
|
|
640
|
-
accessibilityRole: "button",
|
|
641
|
-
accessibilityLabel: isPublishing ? strings.pauseLabel : strings.playLabel,
|
|
642
|
-
accessibilityState: {
|
|
643
|
-
disabled: state.state === "standby" && orientationMismatch
|
|
644
|
-
},
|
|
645
|
-
disabled: state.state === "standby" && orientationMismatch,
|
|
646
|
-
onPress: () => {
|
|
647
|
-
showLiveControls();
|
|
648
|
-
if (isPublishing) void state.stopPublishing();
|
|
649
|
-
else void state.startPublishing();
|
|
650
|
-
},
|
|
651
|
-
style: [
|
|
652
|
-
fab(
|
|
653
|
-
state.state === "standby" && orientationMismatch ? theme.elevated : theme.accent
|
|
654
|
-
),
|
|
655
|
-
{ borderColor: theme.accent }
|
|
656
|
-
],
|
|
657
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { style: { fontSize: 18, color: theme.ink, fontWeight: "800" }, children: isPublishing ? "\u23F8" : "\u25B6" })
|
|
658
|
-
}
|
|
659
|
-
),
|
|
660
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
661
|
-
_reactnative.Pressable,
|
|
662
|
-
{
|
|
663
|
-
accessibilityRole: "button",
|
|
664
|
-
accessibilityLabel: strings.flip,
|
|
665
|
-
onPress: () => {
|
|
666
|
-
showLiveControls();
|
|
667
|
-
void state.switchCamera();
|
|
668
|
-
},
|
|
669
|
-
style: fab(theme.overlay),
|
|
670
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { style: { fontSize: 20 }, children: "\u{1F504}" })
|
|
671
|
-
}
|
|
672
|
-
),
|
|
673
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
674
|
-
_reactnative.Pressable,
|
|
675
|
-
{
|
|
676
|
-
accessibilityRole: "switch",
|
|
677
|
-
accessibilityLabel: strings.mic,
|
|
678
|
-
accessibilityState: { checked: state.isMicrophoneEnabled },
|
|
679
|
-
onPress: () => {
|
|
680
|
-
showLiveControls();
|
|
681
|
-
void state.setMicrophoneEnabled(!state.isMicrophoneEnabled);
|
|
682
|
-
},
|
|
683
|
-
style: [
|
|
684
|
-
fab(theme.overlay),
|
|
685
|
-
state.isMicrophoneEnabled ? null : { borderColor: theme.danger }
|
|
686
|
-
],
|
|
687
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { style: { fontSize: 20 }, children: state.isMicrophoneEnabled ? "\u{1F399}\uFE0F" : "\u{1F507}" })
|
|
688
|
-
}
|
|
689
|
-
),
|
|
690
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
691
|
-
_reactnative.Pressable,
|
|
692
|
-
{
|
|
693
|
-
accessibilityRole: "button",
|
|
694
|
-
accessibilityLabel: strings.endLabel,
|
|
695
|
-
onPress: () => setConfirmingEnd(true),
|
|
696
|
-
style: [fab(theme.danger), { borderColor: theme.danger }],
|
|
697
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { style: { fontSize: 18, color: theme.ink, fontWeight: "800" }, children: "\u25A0" })
|
|
698
|
-
}
|
|
699
|
-
)
|
|
700
|
-
]
|
|
701
|
-
}
|
|
702
|
-
) : null,
|
|
703
|
-
confirmingEnd ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
704
|
-
_reactnative.View,
|
|
705
|
-
{
|
|
706
|
-
style: {
|
|
707
|
-
position: "absolute",
|
|
708
|
-
inset: 0,
|
|
709
|
-
alignItems: "center",
|
|
710
|
-
justifyContent: "center",
|
|
711
|
-
backgroundColor: theme.overlay
|
|
712
|
-
},
|
|
713
|
-
children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
714
|
-
_reactnative.View,
|
|
715
|
-
{
|
|
716
|
-
style: {
|
|
717
|
-
width: 280,
|
|
718
|
-
gap: 10,
|
|
719
|
-
padding: 16,
|
|
720
|
-
borderRadius: theme.radius,
|
|
721
|
-
borderWidth: 1,
|
|
722
|
-
borderColor: theme.hairline,
|
|
723
|
-
backgroundColor: theme.surface
|
|
724
|
-
},
|
|
725
|
-
children: [
|
|
726
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { selectable: true, style: [{ color: theme.foreground, fontSize: 15, fontWeight: "700" }, displayFont], children: strings.endQuestion }),
|
|
727
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
728
|
-
_reactnative.Pressable,
|
|
729
|
-
{
|
|
730
|
-
accessibilityRole: "button",
|
|
731
|
-
onPress: () => {
|
|
732
|
-
setConfirmingEnd(false);
|
|
733
|
-
void state.stop("user");
|
|
734
|
-
},
|
|
735
|
-
style: button(theme.danger),
|
|
736
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { style: [{ color: theme.ink, fontSize: 14, fontWeight: "800" }, boldFont], children: strings.end })
|
|
737
|
-
}
|
|
738
|
-
),
|
|
739
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Pressable, { accessibilityRole: "button", onPress: () => setConfirmingEnd(false), style: secondaryButton, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.Text, { style: [{ color: theme.textSecondary, fontSize: 13, fontWeight: "600" }, bodyFont], children: strings.cancel }) })
|
|
740
|
-
]
|
|
741
|
-
}
|
|
742
|
-
)
|
|
743
|
-
}
|
|
744
|
-
) : null
|
|
745
|
-
]
|
|
746
|
-
}
|
|
747
|
-
);
|
|
748
|
-
}
|
|
749
|
-
var fontOf = (theme, bold = false) => bold ? { fontFamily: _nullishCoalesce(theme.fontFamilyBold, () => ( theme.fontFamily)) } : { fontFamily: theme.fontFamily };
|
|
750
|
-
function Segmented({
|
|
751
|
-
options,
|
|
752
|
-
value,
|
|
753
|
-
onSelect,
|
|
754
|
-
theme
|
|
755
|
-
}) {
|
|
756
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
757
|
-
_reactnative.View,
|
|
758
|
-
{
|
|
759
|
-
style: {
|
|
760
|
-
flex: 1,
|
|
761
|
-
flexDirection: "row",
|
|
762
|
-
padding: 3,
|
|
763
|
-
gap: 3,
|
|
764
|
-
borderRadius: 999,
|
|
765
|
-
borderWidth: 1,
|
|
766
|
-
borderColor: theme.hairline,
|
|
767
|
-
backgroundColor: theme.surface
|
|
768
|
-
},
|
|
769
|
-
children: options.map((option) => {
|
|
770
|
-
const selected = option.value === value;
|
|
771
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
772
|
-
_reactnative.Pressable,
|
|
773
|
-
{
|
|
774
|
-
accessibilityRole: "button",
|
|
775
|
-
accessibilityLabel: _nullishCoalesce(option.accessibilityLabel, () => ( option.label)),
|
|
776
|
-
accessibilityState: { selected },
|
|
777
|
-
onPress: () => onSelect(option.value),
|
|
778
|
-
style: {
|
|
779
|
-
flex: 1,
|
|
780
|
-
minHeight: 32,
|
|
781
|
-
alignItems: "center",
|
|
782
|
-
justifyContent: "center",
|
|
783
|
-
borderRadius: 999,
|
|
784
|
-
backgroundColor: selected ? theme.accent : "transparent"
|
|
785
|
-
},
|
|
786
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
787
|
-
_reactnative.Text,
|
|
788
|
-
{
|
|
789
|
-
numberOfLines: 1,
|
|
790
|
-
style: [
|
|
791
|
-
{
|
|
792
|
-
fontSize: 12,
|
|
793
|
-
fontWeight: "700",
|
|
794
|
-
color: selected ? theme.ink : theme.textSecondary
|
|
795
|
-
},
|
|
796
|
-
fontOf(theme, true)
|
|
797
|
-
],
|
|
798
|
-
children: option.label
|
|
799
|
-
}
|
|
800
|
-
)
|
|
801
|
-
},
|
|
802
|
-
option.value
|
|
803
|
-
);
|
|
804
|
-
})
|
|
805
|
-
}
|
|
806
|
-
);
|
|
807
|
-
}
|
|
808
|
-
function ControlRow({
|
|
809
|
-
label,
|
|
810
|
-
theme,
|
|
811
|
-
children
|
|
812
|
-
}) {
|
|
813
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _reactnative.View, { style: { flexDirection: "row", alignItems: "center", gap: 10 }, children: [
|
|
814
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
815
|
-
_reactnative.Text,
|
|
816
|
-
{
|
|
817
|
-
numberOfLines: 1,
|
|
818
|
-
style: [
|
|
819
|
-
{
|
|
820
|
-
width: 78,
|
|
821
|
-
fontSize: 10,
|
|
822
|
-
letterSpacing: 1,
|
|
823
|
-
textTransform: "uppercase",
|
|
824
|
-
fontWeight: "700",
|
|
825
|
-
color: theme.muted
|
|
826
|
-
},
|
|
827
|
-
fontOf(theme, true)
|
|
828
|
-
],
|
|
829
|
-
children: label
|
|
830
|
-
}
|
|
831
|
-
),
|
|
832
|
-
children
|
|
833
|
-
] });
|
|
834
|
-
}
|
|
835
|
-
function AspectBox({
|
|
836
|
-
ratio,
|
|
837
|
-
background,
|
|
838
|
-
children
|
|
839
|
-
}) {
|
|
840
|
-
const [size, setSize] = _react.useState.call(void 0, null);
|
|
841
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
842
|
-
_reactnative.View,
|
|
843
|
-
{
|
|
844
|
-
style: { flex: 1, alignItems: "center", justifyContent: "center", backgroundColor: background },
|
|
845
|
-
onLayout: (event) => {
|
|
846
|
-
const { width, height } = event.nativeEvent.layout;
|
|
847
|
-
setSize({ w: width, h: height });
|
|
848
|
-
},
|
|
849
|
-
children: size ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
850
|
-
_reactnative.View,
|
|
851
|
-
{
|
|
852
|
-
style: {
|
|
853
|
-
width: Math.min(size.w, size.h * ratio),
|
|
854
|
-
height: Math.min(size.h, size.w / ratio),
|
|
855
|
-
overflow: "hidden"
|
|
856
|
-
},
|
|
857
|
-
children
|
|
858
|
-
}
|
|
859
|
-
) : null
|
|
860
|
-
}
|
|
861
|
-
);
|
|
862
|
-
}
|
|
863
|
-
function DefaultPreview({ state }) {
|
|
864
|
-
const preview = state.previewTrack;
|
|
865
|
-
if (!preview) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactnative.View, { style: { flex: 1, backgroundColor: state.theme.background } });
|
|
866
|
-
if (preview.kind === "rtmp") {
|
|
867
|
-
const rtmp = _chunk7OX2DSKIcjs.__require.call(void 0, "@pickleball/rtmp-native");
|
|
868
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, rtmp.PickleballRtmpPreviewView, { style: { flex: 1 } });
|
|
869
|
-
}
|
|
870
|
-
const liveKit = _chunk7OX2DSKIcjs.__require.call(void 0, "@livekit/react-native");
|
|
871
|
-
const liveKitPreview = preview;
|
|
872
|
-
const remountKey = `${_nullishCoalesce(state.selectedCameraId, () => ( "auto"))}:${state.isCameraFront ? "front" : "back"}`;
|
|
873
|
-
return liveKitPreview.trackRef ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, liveKit.VideoTrack, { trackRef: liveKitPreview.trackRef, mirror: state.isCameraFront, objectFit: "cover", style: { flex: 1 } }, remountKey) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, liveKit.VideoView, { videoTrack: liveKitPreview.videoTrack, mirror: state.isCameraFront, objectFit: "cover", style: { flex: 1 } }, remountKey);
|
|
874
|
-
}
|
|
875
|
-
function formatElapsed(milliseconds) {
|
|
876
|
-
const total = Math.floor(milliseconds / 1e3);
|
|
877
|
-
const hours = Math.floor(total / 3600);
|
|
878
|
-
const minutes = Math.floor(total % 3600 / 60);
|
|
879
|
-
const seconds = total % 60;
|
|
880
|
-
return [hours, minutes, seconds].map((value) => String(value).padStart(2, "0")).join(":");
|
|
881
|
-
}
|
|
882
|
-
function statusText(state, strings) {
|
|
883
|
-
return strings.states[state];
|
|
884
|
-
}
|
|
43
|
+
|
|
44
|
+
var _chunkTBUEXRFQcjs = require('./chunk-TBUEXRFQ.cjs');
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
var _chunkIUIRVKJIcjs = require('./chunk-IUIRVKJI.cjs');
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
var _chunk7OX2DSKIcjs = require('./chunk-7OX2DSKI.cjs');
|
|
885
83
|
|
|
886
84
|
// src/http-session-provider.ts
|
|
887
85
|
var defaultPaths = {
|
|
@@ -893,134 +91,379 @@ var defaultPaths = {
|
|
|
893
91
|
unpublish: (sessionId) => `/sessions/${encodeURIComponent(sessionId)}/unpublish`
|
|
894
92
|
};
|
|
895
93
|
function createHttpSessionProvider(options) {
|
|
896
|
-
const baseUrl = normalizeBaseUrl(options.baseUrl);
|
|
897
|
-
const
|
|
898
|
-
if (typeof fetchImplementation !== "function") {
|
|
899
|
-
throw new (0, _chunkTBPR2QNDcjs.ExpoSdkConfigurationError)("A Fetch API implementation is required");
|
|
900
|
-
}
|
|
94
|
+
const baseUrl = _chunk62YV3PCDcjs.normalizeBaseUrl.call(void 0, options.baseUrl);
|
|
95
|
+
const postJson = _chunk62YV3PCDcjs.createJsonPoster.call(void 0, { fetch: options.fetch, timeoutMs: options.timeoutMs });
|
|
901
96
|
const paths = { ...defaultPaths, ...options.paths };
|
|
902
97
|
async function post(path, body) {
|
|
903
|
-
const
|
|
904
|
-
|
|
905
|
-
() => controller.abort(),
|
|
906
|
-
_nullishCoalesce(options.timeoutMs, () => ( 1e4))
|
|
907
|
-
);
|
|
908
|
-
try {
|
|
909
|
-
const extraHeaders = typeof options.headers === "function" ? await options.headers() : _nullishCoalesce(options.headers, () => ( {}));
|
|
910
|
-
const response = await fetchImplementation(joinUrl(baseUrl, path), {
|
|
911
|
-
method: "POST",
|
|
912
|
-
headers: { "Content-Type": "application/json", ...extraHeaders },
|
|
913
|
-
body: JSON.stringify(body),
|
|
914
|
-
signal: controller.signal,
|
|
915
|
-
redirect: "error"
|
|
916
|
-
});
|
|
917
|
-
const envelope = await response.json().catch(() => {
|
|
918
|
-
throw new (0, _chunkTBPR2QNDcjs.InvalidResponseError)();
|
|
919
|
-
});
|
|
920
|
-
if (!response.ok) throw parseProxyError(envelope, response.status);
|
|
921
|
-
if (!isRecord(envelope) || !("data" in envelope)) {
|
|
922
|
-
throw new (0, _chunkTBPR2QNDcjs.InvalidResponseError)();
|
|
923
|
-
}
|
|
924
|
-
return envelope.data;
|
|
925
|
-
} catch (error) {
|
|
926
|
-
if (controller.signal.aborted) throw new (0, _chunkTBPR2QNDcjs.ExpoSdkTimeoutError)();
|
|
927
|
-
if (error instanceof _chunkTBPR2QNDcjs.PickleballExpoError) throw error;
|
|
928
|
-
if (error instanceof TypeError) {
|
|
929
|
-
throw new (0, _chunkTBPR2QNDcjs.NetworkUnavailableError)(void 0, { cause: error });
|
|
930
|
-
}
|
|
931
|
-
throw error;
|
|
932
|
-
} finally {
|
|
933
|
-
clearTimeout(timeout);
|
|
934
|
-
}
|
|
98
|
+
const extraHeaders = typeof options.headers === "function" ? await options.headers() : _nullishCoalesce(options.headers, () => ( {}));
|
|
99
|
+
return postJson(_chunk62YV3PCDcjs.joinUrl.call(void 0, baseUrl, path), body, extraHeaders);
|
|
935
100
|
}
|
|
936
101
|
return {
|
|
937
102
|
async bootstrap(input) {
|
|
938
103
|
const data = await post(paths.bootstrap, input);
|
|
939
|
-
if (!isBootstrap(data)) throw new (0,
|
|
104
|
+
if (!_chunk62YV3PCDcjs.isBootstrap.call(void 0, data)) throw new (0, _chunkIUIRVKJIcjs.InvalidResponseError)();
|
|
940
105
|
return data;
|
|
941
106
|
},
|
|
942
107
|
async start(input) {
|
|
943
108
|
const data = await post(paths.sessions, input);
|
|
944
|
-
if (!isSessionGrant(data)) throw new (0,
|
|
109
|
+
if (!_chunk62YV3PCDcjs.isSessionGrant.call(void 0, data)) throw new (0, _chunkIUIRVKJIcjs.InvalidResponseError)();
|
|
945
110
|
return data;
|
|
946
111
|
},
|
|
947
112
|
async refresh(sessionId) {
|
|
948
113
|
const data = await post(paths.refresh(sessionId), {});
|
|
949
|
-
if (!isSessionRefresh(data)) throw new (0,
|
|
114
|
+
if (!_chunk62YV3PCDcjs.isSessionRefresh.call(void 0, data)) throw new (0, _chunkIUIRVKJIcjs.InvalidResponseError)();
|
|
950
115
|
return data;
|
|
951
116
|
},
|
|
952
117
|
async end(input) {
|
|
953
118
|
const data = await post(paths.end(input.sessionId), input);
|
|
954
|
-
if (data !== null && data !== void 0) throw new (0,
|
|
119
|
+
if (data !== null && data !== void 0) throw new (0, _chunkIUIRVKJIcjs.InvalidResponseError)();
|
|
955
120
|
},
|
|
956
121
|
async publish(sessionId) {
|
|
957
122
|
const data = await post(paths.publish(sessionId), { sessionId });
|
|
958
|
-
if (!isSessionStatus(data)) throw new (0,
|
|
123
|
+
if (!_chunk62YV3PCDcjs.isSessionStatus.call(void 0, data)) throw new (0, _chunkIUIRVKJIcjs.InvalidResponseError)();
|
|
959
124
|
},
|
|
960
125
|
async unpublish(sessionId) {
|
|
961
126
|
const data = await post(paths.unpublish(sessionId), { sessionId });
|
|
962
|
-
if (!isSessionStatus(data)) throw new (0,
|
|
127
|
+
if (!_chunk62YV3PCDcjs.isSessionStatus.call(void 0, data)) throw new (0, _chunkIUIRVKJIcjs.InvalidResponseError)();
|
|
963
128
|
}
|
|
964
129
|
};
|
|
965
130
|
}
|
|
966
|
-
|
|
967
|
-
|
|
131
|
+
|
|
132
|
+
// src/camera-grant-provider.ts
|
|
133
|
+
var CAMERA_GRANT_STORAGE_KEY = "@pickleball/expo-sdk/camera-grant";
|
|
134
|
+
var DEFAULT_LOCAL_CONFIG = {
|
|
135
|
+
enabled: true,
|
|
136
|
+
protocolVersion: 1,
|
|
137
|
+
minSdkVersion: "0.0.0",
|
|
138
|
+
recommendedSdkVersion: _chunkGXQYMPHEcjs.PICKLEBALL_EXPO_SDK_VERSION,
|
|
139
|
+
videoQuality: 720,
|
|
140
|
+
reconnectTimeoutMs: 3e4,
|
|
141
|
+
backgroundGraceMs: 9e4,
|
|
142
|
+
telemetryIntervalMs: 6e4,
|
|
143
|
+
maxSessionDurationMs: 6 * 60 * 6e4
|
|
144
|
+
};
|
|
145
|
+
function parseHandle(raw) {
|
|
146
|
+
if (!raw) return null;
|
|
968
147
|
try {
|
|
969
|
-
const
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
const localDevelopment = url.protocol === "http:" && loopbackHosts.has(url.hostname);
|
|
973
|
-
const devPrivateLan = typeof __DEV__ !== "undefined" && __DEV__ === true && url.protocol === "http:" && PRIVATE_LAN_HOST.test(url.hostname);
|
|
974
|
-
if (!secure && !localDevelopment && !devPrivateLan || url.username || url.password) {
|
|
975
|
-
throw new Error();
|
|
148
|
+
const value = JSON.parse(raw);
|
|
149
|
+
if (!_chunk62YV3PCDcjs.isRecord.call(void 0, value) || typeof value.sessionId !== "string" || typeof value.base !== "string" || typeof value.token !== "string" || typeof value.tokenExpiresAt !== "number") {
|
|
150
|
+
return null;
|
|
976
151
|
}
|
|
977
|
-
return
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
152
|
+
return {
|
|
153
|
+
sessionId: value.sessionId,
|
|
154
|
+
base: value.base,
|
|
155
|
+
token: value.token,
|
|
156
|
+
tokenExpiresAt: value.tokenExpiresAt,
|
|
157
|
+
...value.quality === 720 || value.quality === 1080 ? { quality: value.quality } : {},
|
|
158
|
+
savedAt: typeof value.savedAt === "number" ? value.savedAt : 0
|
|
159
|
+
};
|
|
160
|
+
} catch (e) {
|
|
161
|
+
return null;
|
|
982
162
|
}
|
|
983
163
|
}
|
|
984
|
-
function
|
|
985
|
-
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
envelope.error.code,
|
|
990
|
-
typeof envelope.error.message === "string" ? envelope.error.message : void 0
|
|
991
|
-
) : new (0, _chunkTBPR2QNDcjs.InvalidResponseError)();
|
|
992
|
-
return Object.assign(error, { httpStatus });
|
|
993
|
-
}
|
|
994
|
-
function isRecord(value) {
|
|
995
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
164
|
+
function withStatus(error) {
|
|
165
|
+
if (_chunk62YV3PCDcjs.httpStatusOf.call(void 0, error) === 401) {
|
|
166
|
+
return Object.assign(new (0, _chunkIUIRVKJIcjs.TokenExpiredError)(), { httpStatus: 401 });
|
|
167
|
+
}
|
|
168
|
+
return error;
|
|
996
169
|
}
|
|
997
|
-
function
|
|
998
|
-
|
|
170
|
+
function createCameraGrantProvider(options) {
|
|
171
|
+
const storage = _nullishCoalesce(options.storage, () => ( _chunkIUIRVKJIcjs.createDefaultStorage.call(void 0, )));
|
|
172
|
+
const storageKey = _nullishCoalesce(options.storageKey, () => ( CAMERA_GRANT_STORAGE_KEY));
|
|
173
|
+
const post = _chunk62YV3PCDcjs.createJsonPoster.call(void 0, { fetch: options.fetch, timeoutMs: options.timeoutMs });
|
|
174
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
175
|
+
let handle = null;
|
|
176
|
+
let handleLoaded = null;
|
|
177
|
+
let activeGrant = null;
|
|
178
|
+
let pendingResume = null;
|
|
179
|
+
const emit = () => {
|
|
180
|
+
for (const listener of listeners) listener();
|
|
181
|
+
};
|
|
182
|
+
async function loadHandle() {
|
|
183
|
+
if (!handleLoaded) {
|
|
184
|
+
handleLoaded = storage.getItem(storageKey).then((raw) => {
|
|
185
|
+
if (handle === null) handle = parseHandle(raw);
|
|
186
|
+
}).catch(() => void 0);
|
|
187
|
+
}
|
|
188
|
+
await handleLoaded;
|
|
189
|
+
}
|
|
190
|
+
async function saveHandle(next) {
|
|
191
|
+
handle = next;
|
|
192
|
+
try {
|
|
193
|
+
if (next) await storage.setItem(storageKey, JSON.stringify(next));
|
|
194
|
+
else await storage.removeItem(storageKey);
|
|
195
|
+
} catch (e2) {
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function setActive(grant) {
|
|
199
|
+
activeGrant = grant;
|
|
200
|
+
emit();
|
|
201
|
+
}
|
|
202
|
+
async function adopt(grant, quality) {
|
|
203
|
+
const base = _chunk62YV3PCDcjs.sessionApiBaseFromTelemetryEndpoint.call(void 0, grant.telemetry.endpoint);
|
|
204
|
+
await saveHandle({
|
|
205
|
+
sessionId: grant.sessionId,
|
|
206
|
+
base,
|
|
207
|
+
token: grant.telemetry.token,
|
|
208
|
+
tokenExpiresAt: grant.telemetry.expiresAt,
|
|
209
|
+
...quality !== void 0 ? { quality } : _optionalChain([handle, 'optionalAccess', _ => _.quality]) !== void 0 ? { quality: handle.quality } : {},
|
|
210
|
+
savedAt: Date.now()
|
|
211
|
+
});
|
|
212
|
+
setActive(grant);
|
|
213
|
+
}
|
|
214
|
+
function requireHandle(sessionId) {
|
|
215
|
+
if (!handle || handle.sessionId !== sessionId) {
|
|
216
|
+
throw Object.assign(
|
|
217
|
+
new (0, _chunkIUIRVKJIcjs.SessionConflictError)("No camera grant is held for this session"),
|
|
218
|
+
{ httpStatus: 404 }
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
return handle;
|
|
222
|
+
}
|
|
223
|
+
function bearer(current) {
|
|
224
|
+
return { Authorization: `Bearer ${current.token}` };
|
|
225
|
+
}
|
|
226
|
+
async function call(current, action, body) {
|
|
227
|
+
try {
|
|
228
|
+
return await post(`${current.base}/${action}`, body, bearer(current));
|
|
229
|
+
} catch (error) {
|
|
230
|
+
throw withStatus(error);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const provider = {
|
|
234
|
+
async bootstrap() {
|
|
235
|
+
await loadHandle();
|
|
236
|
+
return {
|
|
237
|
+
config: { ...DEFAULT_LOCAL_CONFIG, ...options.localConfig },
|
|
238
|
+
serverTime: Date.now(),
|
|
239
|
+
rolloutEnabled: true
|
|
240
|
+
};
|
|
241
|
+
},
|
|
242
|
+
async start(input) {
|
|
243
|
+
await loadHandle();
|
|
244
|
+
const resumeGrant = pendingResume;
|
|
245
|
+
if (resumeGrant && _chunkTBUEXRFQcjs.resumeGrantMatches.call(void 0, input.externalSessionId, resumeGrant.sessionId)) {
|
|
246
|
+
pendingResume = null;
|
|
247
|
+
return resumeGrant;
|
|
248
|
+
}
|
|
249
|
+
const raw = await options.requestGrant(input);
|
|
250
|
+
if (!_chunk62YV3PCDcjs.isCameraGrant.call(void 0, raw)) {
|
|
251
|
+
throw new (0, _chunkIUIRVKJIcjs.InvalidResponseError)("The partner backend returned an invalid camera grant");
|
|
252
|
+
}
|
|
253
|
+
await adopt(raw, input.quality);
|
|
254
|
+
if (input.standby !== true && raw.status !== "live") {
|
|
255
|
+
const current = requireHandle(raw.sessionId);
|
|
256
|
+
try {
|
|
257
|
+
const data = await call(current, "publish", {
|
|
258
|
+
sessionId: raw.sessionId,
|
|
259
|
+
...input.quality !== void 0 ? { quality: input.quality } : {}
|
|
260
|
+
});
|
|
261
|
+
if (!_chunk62YV3PCDcjs.isSessionStatus.call(void 0, data)) throw new (0, _chunkIUIRVKJIcjs.InvalidResponseError)();
|
|
262
|
+
} catch (error) {
|
|
263
|
+
await call(current, "end", { sessionId: raw.sessionId, reason: "error" }).catch(
|
|
264
|
+
() => void 0
|
|
265
|
+
);
|
|
266
|
+
await saveHandle(null);
|
|
267
|
+
setActive(null);
|
|
268
|
+
throw error;
|
|
269
|
+
}
|
|
270
|
+
setActive({ ...raw, status: "live" });
|
|
271
|
+
}
|
|
272
|
+
_optionalChain([options, 'access', _2 => _2.onGrant, 'optionalCall', _3 => _3(_nullishCoalesce(activeGrant, () => ( raw)), "start")]);
|
|
273
|
+
return raw;
|
|
274
|
+
},
|
|
275
|
+
async refresh(sessionId) {
|
|
276
|
+
await loadHandle();
|
|
277
|
+
const current = requireHandle(sessionId);
|
|
278
|
+
const data = await call(current, "refresh", {});
|
|
279
|
+
if (!_chunk62YV3PCDcjs.isCameraGrant.call(void 0, data)) throw new (0, _chunkIUIRVKJIcjs.InvalidResponseError)();
|
|
280
|
+
await adopt(data, current.quality);
|
|
281
|
+
_optionalChain([options, 'access', _4 => _4.onGrant, 'optionalCall', _5 => _5(data, "refresh")]);
|
|
282
|
+
return {
|
|
283
|
+
participantToken: data.participantToken,
|
|
284
|
+
tokenExpiresAt: data.tokenExpiresAt,
|
|
285
|
+
telemetry: data.telemetry,
|
|
286
|
+
config: data.config
|
|
287
|
+
};
|
|
288
|
+
},
|
|
289
|
+
async end(input) {
|
|
290
|
+
await loadHandle();
|
|
291
|
+
if (!handle || handle.sessionId !== input.sessionId) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const current = handle;
|
|
295
|
+
if (current.tokenExpiresAt <= Date.now()) {
|
|
296
|
+
await saveHandle(null);
|
|
297
|
+
setActive(null);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
try {
|
|
301
|
+
await call(current, "end", { sessionId: input.sessionId, reason: input.reason });
|
|
302
|
+
} catch (error) {
|
|
303
|
+
const status = _chunk62YV3PCDcjs.httpStatusOf.call(void 0, error);
|
|
304
|
+
if (status !== 404 && status !== 409 && status !== 410) throw error;
|
|
305
|
+
}
|
|
306
|
+
await saveHandle(null);
|
|
307
|
+
setActive(null);
|
|
308
|
+
},
|
|
309
|
+
async publish(sessionId) {
|
|
310
|
+
await loadHandle();
|
|
311
|
+
const current = requireHandle(sessionId);
|
|
312
|
+
const data = await call(current, "publish", {
|
|
313
|
+
sessionId,
|
|
314
|
+
...current.quality !== void 0 ? { quality: current.quality } : {}
|
|
315
|
+
});
|
|
316
|
+
if (!_chunk62YV3PCDcjs.isSessionStatus.call(void 0, data)) throw new (0, _chunkIUIRVKJIcjs.InvalidResponseError)();
|
|
317
|
+
if (activeGrant) setActive({ ...activeGrant, status: "live" });
|
|
318
|
+
},
|
|
319
|
+
async unpublish(sessionId) {
|
|
320
|
+
await loadHandle();
|
|
321
|
+
const current = requireHandle(sessionId);
|
|
322
|
+
const data = await call(current, "unpublish", { sessionId });
|
|
323
|
+
if (!_chunk62YV3PCDcjs.isSessionStatus.call(void 0, data)) throw new (0, _chunkIUIRVKJIcjs.InvalidResponseError)();
|
|
324
|
+
if (activeGrant) setActive({ ...activeGrant, status: "scheduled" });
|
|
325
|
+
},
|
|
326
|
+
adoptResumeGrant(grant) {
|
|
327
|
+
pendingResume = grant;
|
|
328
|
+
},
|
|
329
|
+
async resume(sessionId) {
|
|
330
|
+
await loadHandle();
|
|
331
|
+
if (!handle || handle.sessionId !== sessionId) return { kind: "gone" };
|
|
332
|
+
const current = handle;
|
|
333
|
+
if (current.tokenExpiresAt <= Date.now()) {
|
|
334
|
+
await saveHandle(null);
|
|
335
|
+
return { kind: "gone" };
|
|
336
|
+
}
|
|
337
|
+
let data;
|
|
338
|
+
try {
|
|
339
|
+
data = await post(`${current.base}/refresh`, {}, bearer(current));
|
|
340
|
+
} catch (error) {
|
|
341
|
+
const status = _chunk62YV3PCDcjs.httpStatusOf.call(void 0, error);
|
|
342
|
+
if (status === void 0) return { kind: "retry" };
|
|
343
|
+
const verdict = _chunkTBUEXRFQcjs.classifyResumeStatus.call(void 0, status);
|
|
344
|
+
return { kind: verdict === "ok" ? "retry" : verdict };
|
|
345
|
+
}
|
|
346
|
+
if (!_chunk62YV3PCDcjs.isCameraGrant.call(void 0, data)) return { kind: "retry" };
|
|
347
|
+
await adopt(data, current.quality);
|
|
348
|
+
_optionalChain([options, 'access', _6 => _6.onGrant, 'optionalCall', _7 => _7(data, "resume")]);
|
|
349
|
+
return { kind: "grant", grant: data, live: data.status === "live" };
|
|
350
|
+
},
|
|
351
|
+
getActiveGrant: () => activeGrant,
|
|
352
|
+
subscribe(listener) {
|
|
353
|
+
listeners.add(listener);
|
|
354
|
+
return () => {
|
|
355
|
+
listeners.delete(listener);
|
|
356
|
+
};
|
|
357
|
+
},
|
|
358
|
+
async hasResumableSession() {
|
|
359
|
+
await loadHandle();
|
|
360
|
+
return handle !== null;
|
|
361
|
+
},
|
|
362
|
+
async clearStoredSession() {
|
|
363
|
+
pendingResume = null;
|
|
364
|
+
await saveHandle(null);
|
|
365
|
+
setActive(null);
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
return provider;
|
|
999
369
|
}
|
|
1000
|
-
function
|
|
1001
|
-
|
|
370
|
+
function useCameraGrant(provider) {
|
|
371
|
+
const React = _chunk7OX2DSKIcjs.__require.call(void 0, "react");
|
|
372
|
+
return React.useSyncExternalStore(
|
|
373
|
+
provider.subscribe,
|
|
374
|
+
provider.getActiveGrant,
|
|
375
|
+
provider.getActiveGrant
|
|
376
|
+
);
|
|
1002
377
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
378
|
+
|
|
379
|
+
// src/resume.ts
|
|
380
|
+
function withResume(provider, resume) {
|
|
381
|
+
let pending = null;
|
|
382
|
+
return {
|
|
383
|
+
bootstrap: provider.bootstrap.bind(provider),
|
|
384
|
+
refresh: provider.refresh.bind(provider),
|
|
385
|
+
end: provider.end.bind(provider),
|
|
386
|
+
publish: _optionalChain([provider, 'access', _8 => _8.publish, 'optionalAccess', _9 => _9.bind, 'call', _10 => _10(provider)]),
|
|
387
|
+
unpublish: _optionalChain([provider, 'access', _11 => _11.unpublish, 'optionalAccess', _12 => _12.bind, 'call', _13 => _13(provider)]),
|
|
388
|
+
async start(input) {
|
|
389
|
+
const grant = pending;
|
|
390
|
+
if (grant && _chunkTBUEXRFQcjs.resumeGrantMatches.call(void 0, input.externalSessionId, grant.sessionId)) {
|
|
391
|
+
pending = null;
|
|
392
|
+
return grant;
|
|
393
|
+
}
|
|
394
|
+
return provider.start(input);
|
|
395
|
+
},
|
|
396
|
+
adoptResumeGrant(grant) {
|
|
397
|
+
pending = grant;
|
|
398
|
+
},
|
|
399
|
+
resume
|
|
400
|
+
};
|
|
1005
401
|
}
|
|
1006
|
-
function
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
402
|
+
function grantFromRefreshPayload(data) {
|
|
403
|
+
if (!_chunk62YV3PCDcjs.isRecord.call(void 0, data) || typeof data.sessionId !== "string" || typeof data.serverUrl !== "string" || typeof data.participantToken !== "string" || !_chunk62YV3PCDcjs.isFiniteNumber.call(void 0, data.tokenExpiresAt) || !_chunk62YV3PCDcjs.isTelemetryCredentials.call(void 0, data.telemetry) || !_chunkIUIRVKJIcjs.isSdkRemoteConfig.call(void 0, data.config)) {
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
return {
|
|
407
|
+
sessionId: data.sessionId,
|
|
408
|
+
serverUrl: data.serverUrl,
|
|
409
|
+
participantToken: data.participantToken,
|
|
410
|
+
playbackUrl: typeof data.playbackUrl === "string" ? data.playbackUrl : null,
|
|
411
|
+
tokenExpiresAt: data.tokenExpiresAt,
|
|
412
|
+
telemetry: data.telemetry,
|
|
413
|
+
config: data.config
|
|
414
|
+
};
|
|
1011
415
|
}
|
|
1012
|
-
function
|
|
1013
|
-
|
|
416
|
+
function createHttpResumeFetcher(options) {
|
|
417
|
+
const fetchImplementation = _nullishCoalesce(options.fetch, () => ( globalThis.fetch));
|
|
418
|
+
const timeoutMs = _nullishCoalesce(options.timeoutMs, () => ( 1e4));
|
|
419
|
+
return async (sessionId) => {
|
|
420
|
+
const controller = new AbortController();
|
|
421
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
422
|
+
try {
|
|
423
|
+
const headers = typeof options.headers === "function" ? await options.headers() : _nullishCoalesce(options.headers, () => ( {}));
|
|
424
|
+
const response = await fetchImplementation(options.url(sessionId), {
|
|
425
|
+
method: "POST",
|
|
426
|
+
headers: { "Content-Type": "application/json", ...headers },
|
|
427
|
+
body: JSON.stringify({}),
|
|
428
|
+
signal: controller.signal
|
|
429
|
+
});
|
|
430
|
+
const verdict = _chunkTBUEXRFQcjs.classifyResumeStatus.call(void 0, response.status);
|
|
431
|
+
if (verdict !== "ok") return { kind: verdict };
|
|
432
|
+
const envelope = await response.json().catch(() => null);
|
|
433
|
+
const grant = grantFromRefreshPayload(_optionalChain([envelope, 'optionalAccess', _14 => _14.data]));
|
|
434
|
+
if (!grant) return { kind: "retry" };
|
|
435
|
+
const status = (_optionalChain([envelope, 'optionalAccess', _15 => _15.data])).status;
|
|
436
|
+
return { kind: "grant", grant, live: status === "live" };
|
|
437
|
+
} catch (e3) {
|
|
438
|
+
return { kind: "retry" };
|
|
439
|
+
} finally {
|
|
440
|
+
clearTimeout(timer);
|
|
441
|
+
}
|
|
442
|
+
};
|
|
1014
443
|
}
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
444
|
+
|
|
445
|
+
// src/local-video-quality.ts
|
|
446
|
+
function withLocalVideoQuality(provider, resolution) {
|
|
447
|
+
return {
|
|
448
|
+
...provider,
|
|
449
|
+
async bootstrap(input) {
|
|
450
|
+
const result = await provider.bootstrap(input);
|
|
451
|
+
return { ...result, config: { ...result.config, videoQuality: resolution() } };
|
|
452
|
+
},
|
|
453
|
+
async start(input) {
|
|
454
|
+
const quality = resolution();
|
|
455
|
+
const result = await provider.start({ ...input, quality });
|
|
456
|
+
return { ...result, config: { ...result.config, videoQuality: quality } };
|
|
457
|
+
},
|
|
458
|
+
async refresh(sessionId) {
|
|
459
|
+
const result = await provider.refresh(sessionId);
|
|
460
|
+
return { ...result, config: { ...result.config, videoQuality: resolution() } };
|
|
461
|
+
},
|
|
462
|
+
end: (input) => provider.end(input),
|
|
463
|
+
// publish/unpublish là optional trong contract — forward nguyên trạng.
|
|
464
|
+
publish: provider.publish ? (sessionId) => provider.publish(sessionId) : void 0,
|
|
465
|
+
unpublish: provider.unpublish ? (sessionId) => provider.unpublish(sessionId) : void 0
|
|
466
|
+
};
|
|
1024
467
|
}
|
|
1025
468
|
|
|
1026
469
|
|
|
@@ -1051,4 +494,43 @@ function isSessionRefresh(value) {
|
|
|
1051
494
|
|
|
1052
495
|
|
|
1053
496
|
|
|
1054
|
-
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
exports.AUDIO_BITRATE_BPS = _chunkIUIRVKJIcjs.AUDIO_BITRATE_BPS; exports.CAMERA_GRANT_STORAGE_KEY = CAMERA_GRANT_STORAGE_KEY; exports.CAMERA_SETTINGS_STORAGE_KEY = _chunkTBUEXRFQcjs.CAMERA_SETTINGS_STORAGE_KEY; exports.ConsentRequiredError = _chunkIUIRVKJIcjs.ConsentRequiredError; exports.DEFAULT_CAMERA_SETTINGS = _chunkTBUEXRFQcjs.DEFAULT_CAMERA_SETTINGS; exports.DEFAULT_LOCAL_CONFIG = DEFAULT_LOCAL_CONFIG; exports.DEFAULT_UPLOAD_URL = _chunkIUIRVKJIcjs.DEFAULT_UPLOAD_URL; exports.ExpoSdkConfigurationError = _chunkIUIRVKJIcjs.ExpoSdkConfigurationError; exports.ExpoSdkTimeoutError = _chunkIUIRVKJIcjs.ExpoSdkTimeoutError; exports.InvalidResponseError = _chunkIUIRVKJIcjs.InvalidResponseError; exports.NetworkUnavailableError = _chunkIUIRVKJIcjs.NetworkUnavailableError; exports.PICKLEBALL_EXPO_SDK_VERSION = _chunkGXQYMPHEcjs.PICKLEBALL_EXPO_SDK_VERSION; exports.PermissionDeniedError = _chunkIUIRVKJIcjs.PermissionDeniedError; exports.PickleballAutoPrepare = _chunkTBUEXRFQcjs.PickleballAutoPrepare; exports.PickleballAutoResume = _chunkTBUEXRFQcjs.PickleballAutoResume; exports.PickleballExpoError = _chunkIUIRVKJIcjs.PickleballExpoError; exports.PickleballLiveProvider = _chunkIUIRVKJIcjs.PickleballLiveProvider; exports.RESUME_RETRY_DELAYS_MS = _chunkTBUEXRFQcjs.RESUME_RETRY_DELAYS_MS; exports.RecordingFailureError = _chunkIUIRVKJIcjs.RecordingFailureError; exports.SDK_TELEMETRY_EVENT_NAMES = _chunkIUIRVKJIcjs.SDK_TELEMETRY_EVENT_NAMES; exports.SdkDisabledError = _chunkIUIRVKJIcjs.SdkDisabledError; exports.SessionConflictError = _chunkIUIRVKJIcjs.SessionConflictError; exports.TokenExpiredError = _chunkIUIRVKJIcjs.TokenExpiredError; exports.UnknownSdkError = _chunkIUIRVKJIcjs.UnknownSdkError; exports.UnsupportedRuntimeError = _chunkIUIRVKJIcjs.UnsupportedRuntimeError; exports.UnsupportedSdkError = _chunkIUIRVKJIcjs.UnsupportedSdkError; exports.VIDEO_BITRATE_BPS = _chunkIUIRVKJIcjs.VIDEO_BITRATE_BPS; exports.applyAntiFlicker = _chunkTBUEXRFQcjs.applyAntiFlicker; exports.cameraSettingsKey = _chunkTBUEXRFQcjs.cameraSettingsKey; exports.classifyResumeStatus = _chunkTBUEXRFQcjs.classifyResumeStatus; exports.compareSemver = _chunkIUIRVKJIcjs.compareSemver; exports.createCameraGrantProvider = createCameraGrantProvider; exports.createCameraSettingsStore = _chunkTBUEXRFQcjs.createCameraSettingsStore; exports.createDefaultStorage = _chunkIUIRVKJIcjs.createDefaultStorage; exports.createHttpResumeFetcher = createHttpResumeFetcher; exports.createHttpSessionProvider = createHttpSessionProvider; exports.createRtmpRoomFactory = _chunkIUIRVKJIcjs.createRtmpRoomFactory; exports.createRtmpRuntime = _chunkIUIRVKJIcjs.createRtmpRuntime; exports.defaultLivestreamTheme = _chunkIUIRVKJIcjs.defaultLivestreamTheme; exports.errorFromCode = _chunkIUIRVKJIcjs.errorFromCode; exports.getCameraCapabilities = _chunkTBUEXRFQcjs.getCameraCapabilities; exports.grantFromRefreshPayload = grantFromRefreshPayload; exports.isSdkRemoteConfig = _chunkIUIRVKJIcjs.isSdkRemoteConfig; exports.isSdkVersionSupported = _chunkIUIRVKJIcjs.isSdkVersionSupported; exports.isSessionGoneError = _chunkIUIRVKJIcjs.isSessionGoneError; exports.normalizeError = _chunkIUIRVKJIcjs.normalizeError; exports.parseCameraSettings = _chunkTBUEXRFQcjs.parseCameraSettings; exports.requestNativePermissions = _chunkTBUEXRFQcjs.requestNativePermissions; exports.requiredMbpsFor = _chunkIUIRVKJIcjs.requiredMbpsFor; exports.resumeBlocksArm = _chunkTBUEXRFQcjs.resumeBlocksArm; exports.resumeExternalSessionId = _chunkTBUEXRFQcjs.resumeExternalSessionId; exports.resumeGrantMatches = _chunkTBUEXRFQcjs.resumeGrantMatches; exports.resumeRetryDelayMs = _chunkTBUEXRFQcjs.resumeRetryDelayMs; exports.rtmpRoomFactoryFor = _chunkTBUEXRFQcjs.rtmpRoomFactoryFor; exports.runUplinkCheck = _chunkIUIRVKJIcjs.runUplinkCheck; exports.setExposureBias = _chunkTBUEXRFQcjs.setExposureBias; exports.setExposureLocked = _chunkTBUEXRFQcjs.setExposureLocked; exports.setFocusLocked = _chunkTBUEXRFQcjs.setFocusLocked; exports.setTorch = _chunkTBUEXRFQcjs.setTorch; exports.setZoom = _chunkTBUEXRFQcjs.setZoom; exports.useCameraGrant = useCameraGrant; exports.useCameraSettings = _chunkTBUEXRFQcjs.useCameraSettings; exports.useLivestream = _chunkIUIRVKJIcjs.useLivestream; exports.useStandbySession = _chunkTBUEXRFQcjs.useStandbySession; exports.verdictFor = _chunkIUIRVKJIcjs.verdictFor; exports.withLocalVideoQuality = withLocalVideoQuality; exports.withResume = withResume;
|