@tiledev/sdk-apptile-live-selling 0.2.5 → 0.3.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.
Files changed (51) hide show
  1. package/README.md +105 -12
  2. package/dist/engine.native.d.ts.map +1 -1
  3. package/dist/engine.native.js +16 -6
  4. package/dist/engine.native.js.map +1 -1
  5. package/dist/index.d.ts +8 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +10 -3
  8. package/dist/index.js.map +1 -1
  9. package/dist/react/LiveVideoTarget.d.ts +28 -2
  10. package/dist/react/LiveVideoTarget.d.ts.map +1 -1
  11. package/dist/react/LiveVideoTarget.js +37 -4
  12. package/dist/react/LiveVideoTarget.js.map +1 -1
  13. package/dist/react/index.web.d.ts.map +1 -1
  14. package/dist/react/index.web.js +5 -0
  15. package/dist/react/index.web.js.map +1 -1
  16. package/dist/react/useLiveSession.d.ts.map +1 -1
  17. package/dist/react/useLiveSession.js +148 -20
  18. package/dist/react/useLiveSession.js.map +1 -1
  19. package/dist/session.d.ts +8 -0
  20. package/dist/session.d.ts.map +1 -1
  21. package/dist/session.js +37 -4
  22. package/dist/session.js.map +1 -1
  23. package/dist/sessionTypes.d.ts +57 -28
  24. package/dist/sessionTypes.d.ts.map +1 -1
  25. package/dist/sessionTypes.js.map +1 -1
  26. package/dist/streams.d.ts +6 -0
  27. package/dist/streams.d.ts.map +1 -1
  28. package/dist/streams.js +7 -6
  29. package/dist/streams.js.map +1 -1
  30. package/dist/types.d.ts +13 -0
  31. package/dist/types.d.ts.map +1 -1
  32. package/dist/types.js.map +1 -1
  33. package/package.json +8 -19
  34. package/android/build.gradle +0 -33
  35. package/android/src/main/AndroidManifest.xml +0 -7
  36. package/android/src/main/java/expo/modules/livepip/LivePipModule.kt +0 -310
  37. package/app.plugin.js +0 -3
  38. package/dist/pip.d.ts +0 -14
  39. package/dist/pip.d.ts.map +0 -1
  40. package/dist/pip.js +0 -15
  41. package/dist/pip.js.map +0 -1
  42. package/dist/pip.native.d.ts +0 -11
  43. package/dist/pip.native.d.ts.map +0 -1
  44. package/dist/pip.native.js +0 -47
  45. package/dist/pip.native.js.map +0 -1
  46. package/expo-module.config.json +0 -9
  47. package/ios/LivePip.podspec +0 -20
  48. package/ios/LivePipController.swift +0 -327
  49. package/ios/LivePipModule.swift +0 -35
  50. package/plugin/build/index.d.ts +0 -29
  51. package/plugin/build/index.js +0 -101
@@ -1,310 +0,0 @@
1
- package expo.modules.livepip
2
-
3
- import android.app.PictureInPictureParams
4
- import android.content.Intent
5
- import android.content.pm.PackageManager
6
- import android.os.Build
7
- import android.os.Bundle
8
- import android.os.Handler
9
- import android.os.Looper
10
- import android.util.Rational
11
- import androidx.activity.ComponentActivity
12
- import androidx.annotation.RequiresApi
13
- import androidx.core.app.PictureInPictureModeChangedInfo
14
- import androidx.core.os.bundleOf
15
- import androidx.core.util.Consumer
16
- import androidx.lifecycle.Lifecycle
17
- import com.facebook.react.bridge.ReactContext
18
- import expo.modules.kotlin.modules.Module
19
- import expo.modules.kotlin.modules.ModuleDefinition
20
-
21
- /**
22
- * System picture-in-picture for the live stream, Android side.
23
- *
24
- * The API is the one iOS already speaks — `configure` / `setStream` / `setArmed` / `start` / `stop`
25
- * and four events — so `modules/live-pip/index.ts` and every caller stay platform-agnostic. What
26
- * happens underneath is not the same shape at all, and it is worth saying why.
27
- *
28
- * On iOS a PIP window is a piece of *content*: AVKit wants a sample-buffer layer, the engine's own
29
- * texture view is not one, and so `LivePipController` intercepts Zego's frames and re-enqueues them.
30
- * On Android a PIP window is the *activity itself*, scaled down. There is nothing to intercept — the
31
- * `ZegoTextureView` already on screen keeps drawing, because an activity in PIP is paused but still
32
- * visible and never reaches `onStop`. So this file is only ever asking the OS to shrink the window,
33
- * and the "show video, hide everything else" half of the job is React's: see `LivePipBubble`, which
34
- * fills the window with the stream while `pipMode` is `system`.
35
- *
36
- * That is also why `configure` and `setStream` are no-ops here rather than missing. They exist on
37
- * iOS to build and steer a frame pipeline this platform does not have, and the shared JS calls them
38
- * unconditionally.
39
- */
40
- class LivePipModule : Module() {
41
- /** Whether backgrounding the app should hand over to a PIP window. Mirrors iOS's meaning exactly. */
42
- private var armed = false
43
-
44
- /**
45
- * Our view of `Activity.isInPictureInPictureMode`, so a listener firing twice for one transition
46
- * cannot emit `onPipStart` twice.
47
- */
48
- private var inPip = false
49
-
50
- /**
51
- * The activity the listener below is attached to, so it can be detached from the same one. An
52
- * activity is recreated on a process restart or a config change we do not handle, and leaving the
53
- * listener on a dead one means emitting events for a window nobody can see.
54
- */
55
- private var listeningTo: ComponentActivity? = null
56
-
57
- private val pipListener = Consumer<PictureInPictureModeChangedInfo> { info ->
58
- handleModeChange(info.isInPictureInPictureMode)
59
- }
60
-
61
- private val activity: ComponentActivity?
62
- get() = appContext.currentActivity as? ComponentActivity
63
-
64
- override fun definition() = ModuleDefinition {
65
- Name("LivePip")
66
-
67
- Events("onPipStart", "onPipStop", "onPipRestore", "onPipError")
68
-
69
- /** No-op: nothing to configure without a frame pipeline. See the note at the top of the file. */
70
- AsyncFunction("configure") {}
71
-
72
- /** No-op: the window renders whatever the activity renders, so it needs no stream id. */
73
- AsyncFunction("setStream") { _: String? -> }
74
-
75
- AsyncFunction("setArmed") { next: Boolean -> setArmed(next) }
76
-
77
- AsyncFunction("start") { start() }
78
-
79
- AsyncFunction("stop") { stop() }
80
-
81
- /**
82
- * The pre-Android-12 half of auto-enter.
83
- *
84
- * From API 31 the OS does this itself off `setAutoEnterEnabled`, which is the only version that
85
- * gets a genuinely seamless handoff — the transition happens with no app code in the loop, the
86
- * same property iOS's `canStartPictureInPictureAutomaticallyFromInline` has. Below that, the last
87
- * callback before the app leaves is this one, so it is where the request has to go. Not
88
- * `onPause`: that also fires when the screen turns off, and a PIP window opened because someone
89
- * pocketed their phone is not what "keep watching" means.
90
- */
91
- OnUserLeavesActivity {
92
- if (armed && Build.VERSION.SDK_INT < Build.VERSION_CODES.S) start()
93
- }
94
-
95
- /**
96
- * Fires when React Native pauses the host — which, entering PIP, happens either just before or
97
- * just after the mode change, depending on the OS version and on whether auto-enter or an
98
- * explicit call opened the window. Whichever order it lands in, the pause must not be the last
99
- * word while a window is up, so the un-pause is re-applied from both sides.
100
- */
101
- OnActivityEntersBackground {
102
- if (inPip) keepRenderingWhileInPip()
103
- }
104
-
105
- OnDestroy { detach() }
106
- }
107
-
108
- // MARK: - Entry points
109
- //
110
- // Each one re-tests the version rather than trusting the guard in the last one. The whole file
111
- // below API 26 is unreachable — `enterPictureInPictureMode(params)` does not exist there — and a
112
- // helper that establishes the version is invisible to lint's `NewApi` check, so the test has to
113
- // sit where the call is or the release build fails on it.
114
-
115
- private fun setArmed(next: Boolean) {
116
- armed = next
117
- if (!available()) {
118
- // Only worth saying when something was actually asked for. A device without the feature is a
119
- // live stream without picture-in-picture, which is still a working live stream — the in-app
120
- // bubble carries on regardless.
121
- if (next) fail("Picture-in-picture is not available on this device")
122
- return
123
- }
124
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
125
- applyArmed(next)
126
- }
127
-
128
- private fun start() {
129
- if (!available() || Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
130
- enterPip()
131
- }
132
-
133
- private fun stop() {
134
- val activity = this.activity ?: return
135
- activity.runOnUiThread {
136
- if (!activity.isInPictureInPictureMode) return@runOnUiThread
137
- leavePip(activity)
138
- }
139
- }
140
-
141
- // MARK: - The window
142
-
143
- @RequiresApi(Build.VERSION_CODES.O)
144
- private fun applyArmed(next: Boolean) {
145
- val activity = this.activity ?: return
146
- activity.runOnUiThread {
147
- attach(activity)
148
- // Below API 31 there are no params to keep current — `enterPictureInPictureMode` carries them
149
- // at the moment it is called, from `OnUserLeavesActivity` above.
150
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
151
- runCatching { activity.setPictureInPictureParams(params(autoEnter = next)) }
152
- .onFailure { fail(it.message ?: "Could not arm picture-in-picture") }
153
- }
154
- // Deliberately *not* leaving an open window when disarmed. Disarming happens when the session
155
- // ends — the host hangs up, or the viewer closes the window — and the two cases that reach
156
- // here mid-window both end with the OS taking the window down anyway. The one that does not is
157
- // a stream ending while the user watches in PIP, and yanking the whole app to the foreground
158
- // for that is worse than leaving a window they can dismiss themselves: Android has no
159
- // counterpart to `stopPictureInPicture()`, so foregrounding is the only "close" available.
160
- }
161
- }
162
-
163
- @RequiresApi(Build.VERSION_CODES.O)
164
- private fun enterPip() {
165
- val activity = this.activity ?: return
166
- activity.runOnUiThread {
167
- if (activity.isInPictureInPictureMode) return@runOnUiThread
168
- attach(activity)
169
- // Not merely a failed transition: the OS also throws here when the user has revoked the app's
170
- // picture-in-picture access in settings, which is a state nothing else reports.
171
- runCatching { activity.enterPictureInPictureMode(params(autoEnter = armed)) }
172
- .onFailure { fail(it.message ?: "Could not start picture-in-picture") }
173
- }
174
- }
175
-
176
- /**
177
- * Comes back out of the window and into the app.
178
- *
179
- * Android has no counterpart to `stopPictureInPicture()` — the only way out is to bring the task
180
- * forward, which is exactly what the window's own expand button does. So this takes the expand
181
- * path, and the listener below reports it as a restore rather than as a dismissal. iOS's `stop()`
182
- * means the other thing (dismiss, and stop playing); nothing in the app calls either, and the JS
183
- * wrapper documents the split.
184
- */
185
- private fun leavePip(activity: ComponentActivity) {
186
- val intent = Intent(activity, activity.javaClass)
187
- .addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT or Intent.FLAG_ACTIVITY_SINGLE_TOP)
188
- runCatching { activity.startActivity(intent) }
189
- }
190
-
191
- /**
192
- * Portrait 9:16 — the shape the hosts publish in, and the same one the in-app bubble uses. Without
193
- * it the window inherits the activity's aspect ratio, which is the phone's, and the stream sits in
194
- * a tall window with black down both sides.
195
- */
196
- @RequiresApi(Build.VERSION_CODES.O)
197
- private fun params(autoEnter: Boolean): PictureInPictureParams {
198
- val builder = PictureInPictureParams.Builder().setAspectRatio(Rational(9, 16))
199
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
200
- builder.setAutoEnterEnabled(autoEnter)
201
- // Seamless resize is for content that can be re-laid-out mid-transition; a video surface
202
- // cross-fades instead, which is what turning it off asks for — and the cross-fade is also what
203
- // covers React swapping the app's UI for the full-bleed stream on the way in.
204
- builder.setSeamlessResizeEnabled(false)
205
- }
206
- return builder.build()
207
- }
208
-
209
- /**
210
- * API 26, not the manifest's own 24: picture-in-picture existed at 24 for Android TV only, and the
211
- * params overload does not exist before O. The feature check covers the rest — a handset can ship
212
- * without it, and low-memory devices routinely do.
213
- */
214
- private fun available(): Boolean {
215
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return false
216
- val activity = this.activity ?: return false
217
- return activity.packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
218
- }
219
-
220
- // MARK: - Transitions
221
-
222
- private fun attach(activity: ComponentActivity) {
223
- if (listeningTo === activity) return
224
- detach()
225
- activity.addOnPictureInPictureModeChangedListener(pipListener)
226
- listeningTo = activity
227
- inPip = activity.isInPictureInPictureMode
228
- }
229
-
230
- private fun detach() {
231
- listeningTo?.removeOnPictureInPictureModeChangedListener(pipListener)
232
- listeningTo = null
233
- }
234
-
235
- private fun handleModeChange(isInPip: Boolean) {
236
- if (isInPip == inPip) return
237
- inPip = isInPip
238
-
239
- if (isInPip) {
240
- keepRenderingWhileInPip()
241
- emit("onPipStart", Bundle())
242
- return
243
- }
244
-
245
- /*
246
- * Expanded, or closed? Both leave PIP and neither carries a flag saying which.
247
- *
248
- * The lifecycle answers it. Tapping the window's close button stops the activity *before* this
249
- * callback runs, so the state has already fallen below STARTED; tapping expand brings it
250
- * forward, so it is at least STARTED. This is the check Google's own PIP sample uses, and this
251
- * callback is the last moment the two paths are still distinguishable.
252
- */
253
- val restored = listeningTo?.lifecycle?.currentState?.isAtLeast(Lifecycle.State.STARTED) ?: false
254
- // Hand the lifecycle back. Restoring brings a real `onResume` along behind this, so only the
255
- // close needs saying: there the activity stops without ever pausing again — it already paused on
256
- // the way *into* the window — so nothing else would undo the un-pause below, and the app would
257
- // go on rendering a screen no one is looking at.
258
- if (!restored) resumeReactHostRendering(resumed = false)
259
- // Same order as iOS: the restore first, then the stop it caused. The JS ignores a stop that
260
- // carries `restored`, so the pair reads as one event on either platform.
261
- if (restored) emit("onPipRestore", Bundle())
262
- emit("onPipStop", bundleOf("restored" to restored))
263
- }
264
-
265
- /**
266
- * Keeps React Native drawing while the app is in a picture-in-picture window.
267
- *
268
- * Without this the window is a still photograph. An activity in PIP is *paused* — visible, but
269
- * paused — and React Native reads that pause as "nobody is looking": `FabricUIManager.onHostPause`
270
- * stops `DispatchUIFrameCallback`, so mount items queue up and are never applied. React goes on
271
- * computing perfectly correct layouts that never reach a native view.
272
- *
273
- * Measured, not inferred, and worth repeating if this ever regresses: an opaque full-window view
274
- * rendered from JS reported the right layout through `onLayout` — the PIP window's own size, to the
275
- * decimal — and did not draw a single pixel of itself. Layout was fine; mounting was frozen. (Do
276
- * not reach for `dumpsys gfxinfo` to check this. Its frame counter sits still for a paused activity
277
- * whether or not the window is updating, so it reads the same before and after this fix. Take a
278
- * screenshot instead.)
279
- *
280
- * So the pause is contradicted for exactly as long as a window is up. That is not a trick — the
281
- * app genuinely is on screen, and every native app in PIP keeps rendering. The cost is that JS
282
- * sees `AppState: 'active'` while in PIP, which is also the truthful answer.
283
- *
284
- * Posted rather than called inline: this runs from inside React Native's own lifecycle dispatch,
285
- * which is iterating its listener list at the time, and re-entering it there is how you get a
286
- * concurrent modification out of a list nobody expected to change mid-loop.
287
- */
288
- private fun keepRenderingWhileInPip() = resumeReactHostRendering(resumed = true)
289
-
290
- private fun resumeReactHostRendering(resumed: Boolean) {
291
- val context = appContext.reactContext as? ReactContext ?: return
292
- val activity = this.activity
293
- Handler(Looper.getMainLooper()).post {
294
- runCatching {
295
- if (resumed) context.onHostResume(activity) else context.onHostPause()
296
- }.onFailure { fail(it.message ?: "Could not keep rendering in picture-in-picture") }
297
- }
298
- }
299
-
300
- private fun fail(message: String) = emit("onPipError", bundleOf("message" to message))
301
-
302
- /**
303
- * Best-effort by design. Closing the window finishes the activity and the React host goes with it,
304
- * so the last event of a session is routinely sent into a runtime that is already tearing down.
305
- * That throws, and it is not a failure worth reporting to anyone.
306
- */
307
- private fun emit(name: String, body: Bundle) {
308
- runCatching { sendEvent(name, body) }
309
- }
310
- }
package/app.plugin.js DELETED
@@ -1,3 +0,0 @@
1
- // Expo resolves a package's config plugin through this file. Points at the compiled plugin so a
2
- // consumer never needs TypeScript at prebuild time.
3
- module.exports = require('./plugin/build');
package/dist/pip.d.ts DELETED
@@ -1,14 +0,0 @@
1
- /**
2
- * System picture-in-picture — DEFAULT / non-native build (no-op).
3
- *
4
- * The window is an OS surface fed by a native module, so there is nothing web, the editor preview or
5
- * any Node runtime could do with it. Metro resolves `pip.native.ts` on iOS/Android and this file
6
- * everywhere else, which is also why a pure `tsc --noEmit` never needs `expo` installed.
7
- *
8
- * Keep every signature here in lock-step with `pip.native.ts`.
9
- */
10
- import type { LivePipController } from './sessionTypes';
11
- /** False off-device, so the session never arms a handover that cannot happen. */
12
- export declare const isLivePipSupported = false;
13
- export declare const livePip: LivePipController;
14
- //# sourceMappingURL=pip.d.ts.map
package/dist/pip.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"pip.d.ts","sourceRoot":"","sources":["../src/pip.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIxD,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAExC,eAAO,MAAM,OAAO,EAAE,iBAOrB,CAAC"}
package/dist/pip.js DELETED
@@ -1,15 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.livePip = exports.isLivePipSupported = void 0;
4
- const noop = async () => undefined;
5
- /** False off-device, so the session never arms a handover that cannot happen. */
6
- exports.isLivePipSupported = false;
7
- exports.livePip = {
8
- configure: noop,
9
- setStream: noop,
10
- setArmed: noop,
11
- start: noop,
12
- stop: noop,
13
- addListener: () => undefined,
14
- };
15
- //# sourceMappingURL=pip.js.map
package/dist/pip.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"pip.js","sourceRoot":"","sources":["../src/pip.ts"],"names":[],"mappings":";;;AAWA,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE,CAAC,SAAS,CAAC;AAElD,iFAAiF;AACpE,QAAA,kBAAkB,GAAG,KAAK,CAAC;AAE3B,QAAA,OAAO,GAAsB;IACxC,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,WAAW,EAAE,GAAG,EAAE,CAAC,SAAS;CAC7B,CAAC"}
@@ -1,11 +0,0 @@
1
- import type { LivePipController } from './sessionTypes';
2
- /**
3
- * Whether picture-in-picture can be used at all on this build.
4
- *
5
- * This says the module is *in the binary*, not that the device will grant a window — an Android
6
- * handset can ship without the picture-in-picture feature, and the user can revoke the permission in
7
- * settings. Those surface as `onPipError`, because they cannot be known until a window is asked for.
8
- */
9
- export declare const isLivePipSupported: boolean;
10
- export declare const livePip: LivePipController;
11
- //# sourceMappingURL=pip.native.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pip.native.d.ts","sourceRoot":"","sources":["../src/pip.native.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,gBAAgB,CAAC;AAgBvE;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,SAAiB,CAAC;AAEjD,eAAO,MAAM,OAAO,EAAE,iBAoBrB,CAAC"}
@@ -1,47 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.livePip = exports.isLivePipSupported = void 0;
4
- /**
5
- * System picture-in-picture — the native build.
6
- *
7
- * The window is an OS surface, not a React view, so the module below feeds it frames (iOS) or marks
8
- * the activity as PIP-capable (Android) and reports the transitions back. `plugin/` writes the
9
- * manifest and Info.plist entries this needs; without the config plugin the module loads and the OS
10
- * simply never grants a window.
11
- */
12
- const expo_1 = require("expo");
13
- /**
14
- * `requireOptionalNativeModule` rather than the throwing variant: a bundle running against a binary
15
- * built before this package was added should get a missing module, not a crash on import.
16
- */
17
- const native = (0, expo_1.requireOptionalNativeModule)('LivePip');
18
- /**
19
- * Whether picture-in-picture can be used at all on this build.
20
- *
21
- * This says the module is *in the binary*, not that the device will grant a window — an Android
22
- * handset can ship without the picture-in-picture feature, and the user can revoke the permission in
23
- * settings. Those surface as `onPipError`, because they cannot be known until a window is asked for.
24
- */
25
- exports.isLivePipSupported = native != null;
26
- exports.livePip = {
27
- configure: async () => {
28
- await (native === null || native === void 0 ? void 0 : native.configure());
29
- },
30
- setStream: async (streamId) => {
31
- await (native === null || native === void 0 ? void 0 : native.setStream(streamId));
32
- },
33
- setArmed: async (armed) => {
34
- await (native === null || native === void 0 ? void 0 : native.setArmed(armed));
35
- },
36
- start: async () => {
37
- await (native === null || native === void 0 ? void 0 : native.start());
38
- },
39
- stop: async () => {
40
- await (native === null || native === void 0 ? void 0 : native.stop());
41
- },
42
- addListener: (event, listener) => {
43
- const subscription = native === null || native === void 0 ? void 0 : native.addListener(event, listener);
44
- return subscription ? () => subscription.remove() : undefined;
45
- },
46
- };
47
- //# sourceMappingURL=pip.native.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pip.native.js","sourceRoot":"","sources":["../src/pip.native.ts"],"names":[],"mappings":";;;AAAA;;;;;;;GAOG;AACH,+BAAsE;AAYtE;;;GAGG;AACH,MAAM,MAAM,GAAG,IAAA,kCAA2B,EAAsB,SAAS,CAAC,CAAC;AAE3E;;;;;;GAMG;AACU,QAAA,kBAAkB,GAAG,MAAM,IAAI,IAAI,CAAC;AAEpC,QAAA,OAAO,GAAsB;IACxC,SAAS,EAAE,KAAK,IAAI,EAAE;QACpB,MAAM,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,SAAS,EAAE,CAAA,CAAC;IAC5B,CAAC;IACD,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QAC5B,MAAM,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,SAAS,CAAC,QAAQ,CAAC,CAAA,CAAC;IACpC,CAAC;IACD,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QACxB,MAAM,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,CAAC,KAAK,CAAC,CAAA,CAAC;IAChC,CAAC;IACD,KAAK,EAAE,KAAK,IAAI,EAAE;QAChB,MAAM,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,EAAE,CAAA,CAAC;IACxB,CAAC;IACD,IAAI,EAAE,KAAK,IAAI,EAAE;QACf,MAAM,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,EAAE,CAAA,CAAC;IACvB,CAAC;IACD,WAAW,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QAC/B,MAAM,YAAY,GAAG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC1D,OAAO,YAAY,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,CAAC;CACF,CAAC"}
@@ -1,9 +0,0 @@
1
- {
2
- "platforms": ["apple", "android"],
3
- "apple": {
4
- "modules": ["LivePipModule"]
5
- },
6
- "android": {
7
- "modules": ["expo.modules.livepip.LivePipModule"]
8
- }
9
- }
@@ -1,20 +0,0 @@
1
- Pod::Spec.new do |s|
2
- s.name = 'LivePip'
3
- s.version = '1.0.0'
4
- s.summary = 'System picture-in-picture for the Zego live stream'
5
- s.description = 'Feeds Zego custom-render frames into an AVPictureInPictureController.'
6
- s.author = 'Apptile'
7
- s.homepage = 'https://apptile.io'
8
- s.license = 'MIT'
9
- # AVPictureInPictureController only accepts a sample-buffer content source from iOS 15.
10
- s.platforms = { :ios => '15.1' }
11
- s.source = { git: '' }
12
- s.static_framework = true
13
-
14
- s.dependency 'ExpoModulesCore'
15
- # Same pod the React Native wrapper pulls in, so this resolves to the one installed engine
16
- # rather than a second copy.
17
- s.dependency 'ZegoExpressEngine'
18
-
19
- s.source_files = "**/*.{h,m,mm,swift,hpp,cpp}"
20
- end