@100mslive/react-native-hms 1.12.2 → 2.0.0-alpha.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 (70) hide show
  1. package/android/build.gradle +70 -12
  2. package/android/src/main/java/com/reactnativehmssdk/HMSAudioshareActivity.kt +8 -8
  3. package/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayer.kt +38 -12
  4. package/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayerManagerImpl.kt +185 -0
  5. package/android/src/main/java/com/reactnativehmssdk/HMSHelper.kt +20 -10
  6. package/android/src/main/java/com/reactnativehmssdk/{HMSManager.kt → HMSManagerImpl.kt} +28 -111
  7. package/android/src/main/java/com/reactnativehmssdk/HMSRNSDK.kt +3 -3
  8. package/android/src/main/java/com/reactnativehmssdk/HMSReactNativeEvent.kt +29 -0
  9. package/android/src/main/java/com/reactnativehmssdk/HMSSDKViewManagerImpl.kt +119 -0
  10. package/android/src/main/java/com/reactnativehmssdk/HMSView.kt +33 -5
  11. package/android/src/main/java/com/reactnativehmssdk/HmsScreenshareActivity.kt +9 -9
  12. package/android/src/main/java/com/reactnativehmssdk/HmssdkPackage.kt +42 -3
  13. package/android/src/newarch/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt +128 -0
  14. package/android/src/newarch/java/com/reactnativehmssdk/HMSManager.kt +332 -0
  15. package/android/src/newarch/java/com/reactnativehmssdk/HMSSDKViewManager.kt +102 -0
  16. package/android/src/oldarch/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt +61 -0
  17. package/android/src/oldarch/java/com/reactnativehmssdk/HMSManager.kt +351 -0
  18. package/android/src/oldarch/java/com/reactnativehmssdk/HMSSDKViewManager.kt +87 -0
  19. package/ios/HMSHLSPlayerComponentView.mm +325 -0
  20. package/ios/HMSHLSPlayerManager.m +10 -0
  21. package/ios/HMSHLSPlayerManager.swift +91 -79
  22. package/ios/HMSManager.m +13 -0
  23. package/ios/HMSManager.mm +365 -0
  24. package/ios/HMSManager.swift +109 -103
  25. package/ios/HMSView.m +9 -0
  26. package/ios/HMSView.swift +44 -14
  27. package/ios/HMSViewComponentView.mm +229 -0
  28. package/lib/commonjs/classes/HmsView.js +45 -48
  29. package/lib/commonjs/classes/HmsView.js.map +1 -1
  30. package/lib/commonjs/components/HMSHLSPlayer/HMSHLSPlayer.js +46 -26
  31. package/lib/commonjs/components/HMSHLSPlayer/HMSHLSPlayer.js.map +1 -1
  32. package/lib/commonjs/components/HMSHLSPlayer/RCTHMSHLSPlayer.js +5 -4
  33. package/lib/commonjs/components/HMSHLSPlayer/RCTHMSHLSPlayer.js.map +1 -1
  34. package/lib/commonjs/modules/HMSManagerModule.js +3 -10
  35. package/lib/commonjs/modules/HMSManagerModule.js.map +1 -1
  36. package/lib/commonjs/specs/HMSHLSPlayerNativeComponent.js +75 -0
  37. package/lib/commonjs/specs/HMSHLSPlayerNativeComponent.js.map +1 -0
  38. package/lib/commonjs/specs/HMSViewNativeComponent.js +55 -0
  39. package/lib/commonjs/specs/HMSViewNativeComponent.js.map +1 -0
  40. package/lib/commonjs/specs/NativeHMSManager.js +38 -0
  41. package/lib/commonjs/specs/NativeHMSManager.js.map +1 -0
  42. package/lib/module/classes/HmsView.js +46 -49
  43. package/lib/module/classes/HmsView.js.map +1 -1
  44. package/lib/module/components/HMSHLSPlayer/HMSHLSPlayer.js +48 -28
  45. package/lib/module/components/HMSHLSPlayer/HMSHLSPlayer.js.map +1 -1
  46. package/lib/module/components/HMSHLSPlayer/RCTHMSHLSPlayer.js +3 -3
  47. package/lib/module/components/HMSHLSPlayer/RCTHMSHLSPlayer.js.map +1 -1
  48. package/lib/module/modules/HMSManagerModule.js +1 -9
  49. package/lib/module/modules/HMSManagerModule.js.map +1 -1
  50. package/lib/module/specs/HMSHLSPlayerNativeComponent.js +69 -0
  51. package/lib/module/specs/HMSHLSPlayerNativeComponent.js.map +1 -0
  52. package/lib/module/specs/HMSViewNativeComponent.js +49 -0
  53. package/lib/module/specs/HMSViewNativeComponent.js.map +1 -0
  54. package/lib/module/specs/NativeHMSManager.js +33 -0
  55. package/lib/module/specs/NativeHMSManager.js.map +1 -0
  56. package/lib/typescript/components/HMSHLSPlayer/RCTHMSHLSPlayer.d.ts +6 -9
  57. package/lib/typescript/specs/HMSHLSPlayerNativeComponent.d.ts +115 -0
  58. package/lib/typescript/specs/HMSViewNativeComponent.d.ts +97 -0
  59. package/lib/typescript/specs/NativeHMSManager.d.ts +147 -0
  60. package/package.json +16 -1
  61. package/react-native-hms.podspec +43 -0
  62. package/src/classes/HmsView.tsx +60 -78
  63. package/src/components/HMSHLSPlayer/HMSHLSPlayer.tsx +62 -128
  64. package/src/components/HMSHLSPlayer/RCTHMSHLSPlayer.ts +8 -13
  65. package/src/modules/HMSManagerModule.ts +1 -14
  66. package/src/specs/HMSHLSPlayerNativeComponent.ts +203 -0
  67. package/src/specs/HMSViewNativeComponent.ts +119 -0
  68. package/src/specs/NativeHMSManager.ts +307 -0
  69. package/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt +0 -144
  70. package/android/src/main/java/com/reactnativehmssdk/HMSSDKViewManager.kt +0 -111
@@ -0,0 +1,365 @@
1
+ //
2
+ // HMSManager.mm
3
+ //
4
+ // TurboModule wrapper for the existing Swift `HMSManager` class.
5
+ //
6
+ // Phase 1 / 1B of the New Architecture migration. This file adds
7
+ // protocol conformance to the `NativeHMSManagerSpec` (Codegen-generated
8
+ // from src/specs/NativeHMSManager.ts) WITHOUT modifying the Swift
9
+ // source. Each forwarder adapts the protocol's named-label selectors
10
+ // (e.g. `build:resolve:reject:`) to the existing Swift selectors with
11
+ // positional underscore labels (e.g. `build:::`).
12
+ //
13
+ // Why a category and not a separate class:
14
+ // - The Swift HMSManager is registered as the RN module via
15
+ // `RCT_EXTERN_MODULE` in HMSManager.m (under old arch) and remains
16
+ // the lifecycle owner under new arch via `HMSManager.shared`.
17
+ // - A category lets us add protocol conformance + `getTurboModule:`
18
+ // to the existing class without creating a separate Obj-C class
19
+ // that would conflict with the RN module-name registry or break
20
+ // the singleton pattern from Phase 0.
21
+ //
22
+ // Important caveats for the consumer-side first build:
23
+ // - The `RNHmsSpec/RNHmsSpec.h` header below is generated by
24
+ // Codegen at the consumer's `pod install` time. It does NOT
25
+ // exist in the SDK source tree.
26
+ // - The `react_native_hms-Swift.h` header is auto-generated by
27
+ // the Swift compiler in the consumer's build. The exact name
28
+ // depends on CocoaPods' module-name normalization; if your
29
+ // build can't resolve it, check the CocoaPods-derived module
30
+ // name (typically the package name with '-' → '_').
31
+ // - Method-name collisions with the Swift class are intentional
32
+ // — different Obj-C selectors (named labels vs positional) so
33
+ // Obj-C dispatcher considers them distinct methods.
34
+ //
35
+
36
+ // Value-based check (not #ifdef): RN's Podfile + use_react_native! defines
37
+ // RCT_NEW_ARCH_ENABLED unconditionally as 0 or 1 depending on the build mode.
38
+ // `#ifdef` fires for both values; `#if` only when truthy.
39
+ #if RCT_NEW_ARCH_ENABLED
40
+
41
+ #import "RNHmsSpec/RNHmsSpec.h"
42
+ #import <React/RCTBridgeModule.h>
43
+ #import <React/RCTEventEmitter.h>
44
+
45
+ // Auto-generated by `swiftc -emit-objc-header`. Imported with a quoted include
46
+ // (not `<react_native_hms/...>`) because Xcode emits this file into the pod's
47
+ // `DerivedSources/` directory, which CocoaPods adds to the pod target's header
48
+ // search paths — the angle-bracket form would also require a `react_native_hms/`
49
+ // prefix path that doesn't exist for the generated `-Swift.h`.
50
+ #import "react_native_hms-Swift.h"
51
+
52
+ @interface HMSManager (TurboModuleConformance) <NativeHMSManagerSpec>
53
+ @end
54
+
55
+ @implementation HMSManager (TurboModuleConformance)
56
+
57
+ #pragma mark - TurboModule registration
58
+
59
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
60
+ (const facebook::react::ObjCTurboModule::InitParams &)params {
61
+ return std::make_shared<facebook::react::NativeHMSManagerSpecJSI>(params);
62
+ }
63
+
64
+ #pragma mark - Promise method forwarders
65
+ //
66
+ // The Codegen-generated `NativeHMSManagerSpec` protocol declares each
67
+ // async method with named labels: `methodName:resolve:reject:`. The
68
+ // existing Swift HMSManager exposes them with positional underscore
69
+ // labels (selector: `methodName:::`). The macro below adapts the
70
+ // protocol's expected selector to the existing Swift selector by
71
+ // dispatching through `[self methodName:data :resolve :reject]`.
72
+ //
73
+ // `self` here refers to the same HMSManager instance — the category's
74
+ // method has a different selector from the Swift method (named labels
75
+ // vs positional), so this is NOT infinite recursion.
76
+ //
77
+
78
+ #define FORWARD_PROMISE(name) \
79
+ -(void)name : (NSDictionary *)data \
80
+ resolve : (RCTPromiseResolveBlock)resolve \
81
+ reject : (RCTPromiseRejectBlock)reject { \
82
+ [self name:data :resolve :reject]; \
83
+ }
84
+
85
+ // Lifecycle
86
+ FORWARD_PROMISE(build)
87
+ FORWARD_PROMISE(destroy)
88
+ FORWARD_PROMISE(previewForRole)
89
+ FORWARD_PROMISE(cancelPreview)
90
+ FORWARD_PROMISE(leave)
91
+ FORWARD_PROMISE(endRoom)
92
+
93
+ // Track operations
94
+ // `setLocalMute` / `setLocalVideoMute` are declared as `void` in the TS spec
95
+ // (fire-and-forget — the Swift impl is sync). The protocol expects a 1-arg
96
+ // selector but the existing Swift method has 3 positional args (data, resolve,
97
+ // reject). Forward 1-arg → 3-arg with nil resolve/reject so the Swift impl
98
+ // still runs and any rejection is silently dropped (matching `void` semantics).
99
+ - (void)setLocalMute:(NSDictionary *)data {
100
+ [self setLocalMute:data :nil :nil];
101
+ }
102
+ - (void)setLocalVideoMute:(NSDictionary *)data {
103
+ [self setLocalVideoMute:data :nil :nil];
104
+ }
105
+ FORWARD_PROMISE(isMute)
106
+ FORWARD_PROMISE(changeTrackState)
107
+ FORWARD_PROMISE(changeTrackStateForRoles)
108
+ FORWARD_PROMISE(setVolume)
109
+ FORWARD_PROMISE(remoteMuteAllAudio)
110
+ FORWARD_PROMISE(setPlaybackAllowed)
111
+ FORWARD_PROMISE(isPlaybackAllowed)
112
+ FORWARD_PROMISE(setPlaybackForAllAudio)
113
+ FORWARD_PROMISE(getRemoteVideoTrackFromTrackId)
114
+ FORWARD_PROMISE(getRemoteAudioTrackFromTrackId)
115
+ FORWARD_PROMISE(getVideoTrackLayer)
116
+ FORWARD_PROMISE(getVideoTrackLayerDefinition)
117
+ FORWARD_PROMISE(setVideoTrackLayer)
118
+ FORWARD_PROMISE(captureImageAtMaxSupportedResolution)
119
+
120
+ // Peer operations
121
+ FORWARD_PROMISE(getLocalPeer)
122
+ FORWARD_PROMISE(getRemotePeers)
123
+ FORWARD_PROMISE(getRoles)
124
+ FORWARD_PROMISE(getRoom)
125
+ FORWARD_PROMISE(changeName)
126
+ FORWARD_PROMISE(changeMetadata)
127
+ FORWARD_PROMISE(changeRole)
128
+ FORWARD_PROMISE(changeRoleOfPeer)
129
+ FORWARD_PROMISE(changeRoleOfPeersWithRoles)
130
+ FORWARD_PROMISE(acceptRoleChange)
131
+ FORWARD_PROMISE(removePeer)
132
+ FORWARD_PROMISE(raiseLocalPeerHand)
133
+ FORWARD_PROMISE(lowerLocalPeerHand)
134
+ FORWARD_PROMISE(lowerRemotePeerHand)
135
+
136
+ // Peer list iterator (the sync `getPeerListIterator` is below)
137
+ FORWARD_PROMISE(peerListIteratorHasNext)
138
+ FORWARD_PROMISE(peerListIteratorNext)
139
+
140
+ // Messaging
141
+ FORWARD_PROMISE(sendBroadcastMessage)
142
+ FORWARD_PROMISE(sendGroupMessage)
143
+ FORWARD_PROMISE(sendDirectMessage)
144
+
145
+ // RTMP / Recording / HLS streaming
146
+ FORWARD_PROMISE(startRTMPOrRecording)
147
+ FORWARD_PROMISE(stopRtmpAndRecording)
148
+ FORWARD_PROMISE(startHLSStreaming)
149
+ FORWARD_PROMISE(stopHLSStreaming)
150
+ FORWARD_PROMISE(sendHLSTimedMetadata)
151
+
152
+ // Screen share
153
+ FORWARD_PROMISE(startScreenshare)
154
+ FORWARD_PROMISE(stopScreenshare)
155
+ FORWARD_PROMISE(isScreenShared)
156
+
157
+ // Audio share — iOS API
158
+ FORWARD_PROMISE(playAudioShare)
159
+ FORWARD_PROMISE(pauseAudioShare)
160
+ FORWARD_PROMISE(resumeAudioShare)
161
+ FORWARD_PROMISE(stopAudioShare)
162
+ FORWARD_PROMISE(setAudioShareVolume)
163
+ FORWARD_PROMISE(audioShareCurrentTime)
164
+ FORWARD_PROMISE(audioShareDuration)
165
+ FORWARD_PROMISE(audioShareIsPlaying)
166
+
167
+ // Audio output
168
+ FORWARD_PROMISE(switchAudioOutput)
169
+ FORWARD_PROMISE(switchAudioOutputUsingIOSUI)
170
+
171
+ // PiP (iOS-implemented)
172
+ // Note: `setupPIP` is declared in the TS spec and the legacy paper bridge
173
+ // (`RCT_EXTERN_METHOD` in HMSManager.m) but the Swift class never implemented
174
+ // it. Under old arch this would have crashed at runtime if called; no JS
175
+ // caller currently does. Stubbed below — not via FORWARD_PROMISE.
176
+ FORWARD_PROMISE(stopPIP)
177
+ FORWARD_PROMISE(disposePIP)
178
+ FORWARD_PROMISE(isPIPActive)
179
+ FORWARD_PROMISE(changeIOSPIPVideoTrack)
180
+ FORWARD_PROMISE(setActiveSpeakerInIOSPIP)
181
+
182
+ // Session store / metadata
183
+ FORWARD_PROMISE(getSessionMetadataForKey)
184
+ FORWARD_PROMISE(setSessionMetadataForKey)
185
+ FORWARD_PROMISE(addKeyChangeListener)
186
+ FORWARD_PROMISE(removeKeyChangeListener)
187
+
188
+ // Polls / Quiz
189
+ FORWARD_PROMISE(quickStartPoll)
190
+ FORWARD_PROMISE(addResponseOnPollQuestion)
191
+ FORWARD_PROMISE(stopPoll)
192
+ FORWARD_PROMISE(fetchLeaderboard)
193
+
194
+ // Whiteboard
195
+ FORWARD_PROMISE(startWhiteboard)
196
+ FORWARD_PROMISE(stopWhiteboard)
197
+
198
+ // Transcripts
199
+ FORWARD_PROMISE(handleRealTimeTranscription)
200
+
201
+ // Noise cancellation
202
+ FORWARD_PROMISE(enableNoiseCancellationPlugin)
203
+ FORWARD_PROMISE(disableNoiseCancellationPlugin)
204
+ FORWARD_PROMISE(isNoiseCancellationPluginEnabled)
205
+ FORWARD_PROMISE(isNoiseCancellationPluginAvailable)
206
+
207
+ // Video plugin (iOS only)
208
+ FORWARD_PROMISE(enableVideoPlugin)
209
+ FORWARD_PROMISE(disableVideoPlugin)
210
+ FORWARD_PROMISE(changeVirtualBackground)
211
+ FORWARD_PROMISE(setVideoFilterParameter)
212
+
213
+ // Misc / system / config
214
+ FORWARD_PROMISE(enableEvent)
215
+ FORWARD_PROMISE(disableEvent)
216
+ FORWARD_PROMISE(restrictData)
217
+ FORWARD_PROMISE(getAuthTokenByRoomCode)
218
+ FORWARD_PROMISE(getRoomLayout)
219
+ FORWARD_PROMISE(setAlwaysScreenOn)
220
+
221
+ #undef FORWARD_PROMISE
222
+
223
+ #pragma mark - Multi-arg method forwarder
224
+
225
+ // `handlePipActions` is the only iOS method with two non-promise args
226
+ // (action: string, data: Object). The Swift selector is
227
+ // `handlePipActions::::` (4 colons, all positional).
228
+ - (void)handlePipActions:(NSString *)action
229
+ data:(NSDictionary *)data
230
+ resolve:(RCTPromiseResolveBlock)resolve
231
+ reject:(RCTPromiseRejectBlock)reject {
232
+ [self handlePipActions:action :data :resolve :reject];
233
+ }
234
+
235
+ #pragma mark - Unimplemented iOS methods
236
+
237
+ // Declared in TS spec but never implemented in Swift. Reject gracefully so
238
+ // JS callers get an error rather than a crash. See note at FORWARD_PROMISE
239
+ // block above.
240
+ - (void)setupPIP:(NSDictionary *)data
241
+ resolve:(RCTPromiseResolveBlock)resolve
242
+ reject:(RCTPromiseRejectBlock)reject {
243
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"setupPIP is not implemented on iOS", nil);
244
+ }
245
+
246
+ #pragma mark - Methods with matching selectors (no forwarder needed)
247
+ //
248
+ // The following methods have selectors that already match between the
249
+ // Codegen protocol and the existing Swift class — same arity, same
250
+ // labels — so the protocol's required method is satisfied by the
251
+ // existing Swift implementation directly. NO forwarder is needed:
252
+ //
253
+ // Sync methods (return value, no resolve/reject):
254
+ // - getPeerProperty: [Swift selector matches protocol]
255
+ // - getRoomProperty: [Swift selector matches protocol]
256
+ // - getPeerListIterator: [Swift selector matches protocol]
257
+ //
258
+ // Void methods (single dictionary param, no resolve/reject):
259
+ // - preview: (Swift exposes preview:)
260
+ // - join: (Swift exposes join:)
261
+ // - switchCamera: (Swift exposes switchCamera:)
262
+ // - enableNetworkQualityUpdates:
263
+ // - disableNetworkQualityUpdates:
264
+ //
265
+
266
+ #pragma mark - Android-only methods (stubs)
267
+ //
268
+ // These methods are declared in the cross-platform spec but are not
269
+ // implemented on iOS. Calls from JS without a `Platform.OS === 'android'`
270
+ // guard will reject with a 'HMS_PLATFORM_UNSUPPORTED' error.
271
+
272
+ - (void)checkNotifications:(RCTPromiseResolveBlock)resolve
273
+ reject:(RCTPromiseRejectBlock)reject {
274
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"checkNotifications is Android-only", nil);
275
+ }
276
+
277
+ - (void)getAudioDevicesList:(NSDictionary *)data
278
+ resolve:(RCTPromiseResolveBlock)resolve
279
+ reject:(RCTPromiseRejectBlock)reject {
280
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"getAudioDevicesList is Android-only", nil);
281
+ }
282
+
283
+ - (void)getAudioOutputRouteType:(NSDictionary *)data
284
+ resolve:(RCTPromiseResolveBlock)resolve
285
+ reject:(RCTPromiseRejectBlock)reject {
286
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"getAudioOutputRouteType is Android-only", nil);
287
+ }
288
+
289
+ - (void)setAudioMode:(NSDictionary *)data
290
+ resolve:(RCTPromiseResolveBlock)resolve
291
+ reject:(RCTPromiseRejectBlock)reject {
292
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"setAudioMode is Android-only", nil);
293
+ }
294
+
295
+ - (void)setAudioMixingMode:(NSDictionary *)data
296
+ resolve:(RCTPromiseResolveBlock)resolve
297
+ reject:(RCTPromiseRejectBlock)reject {
298
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"setAudioMixingMode is Android-only", nil);
299
+ }
300
+
301
+ - (void)getAudioMixingMode:(NSDictionary *)data
302
+ resolve:(RCTPromiseResolveBlock)resolve
303
+ reject:(RCTPromiseRejectBlock)reject {
304
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"getAudioMixingMode is Android-only", nil);
305
+ }
306
+
307
+ - (void)getVolume:(NSDictionary *)data
308
+ resolve:(RCTPromiseResolveBlock)resolve
309
+ reject:(RCTPromiseRejectBlock)reject {
310
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"getVolume is Android-only", nil);
311
+ }
312
+
313
+ - (void)setPermissionsAccepted:(NSDictionary *)data
314
+ resolve:(RCTPromiseResolveBlock)resolve
315
+ reject:(RCTPromiseRejectBlock)reject {
316
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"setPermissionsAccepted is Android-only", nil);
317
+ }
318
+
319
+ - (void)startAudioshare:(NSDictionary *)data
320
+ resolve:(RCTPromiseResolveBlock)resolve
321
+ reject:(RCTPromiseRejectBlock)reject {
322
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"startAudioshare is Android-only", nil);
323
+ }
324
+
325
+ - (void)stopAudioshare:(NSDictionary *)data
326
+ resolve:(RCTPromiseResolveBlock)resolve
327
+ reject:(RCTPromiseRejectBlock)reject {
328
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"stopAudioshare is Android-only", nil);
329
+ }
330
+
331
+ - (void)isAudioShared:(NSDictionary *)data
332
+ resolve:(RCTPromiseResolveBlock)resolve
333
+ reject:(RCTPromiseRejectBlock)reject {
334
+ reject(@"HMS_PLATFORM_UNSUPPORTED", @"isAudioShared is Android-only", nil);
335
+ }
336
+
337
+ #pragma mark - Android-only void methods (no-op stubs)
338
+
339
+ - (void)setAudioDeviceChangeListener:(NSDictionary *)data {
340
+ // No-op on iOS — Android-only
341
+ }
342
+
343
+ - (void)hideSystemBars {
344
+ // No-op on iOS — Android-only
345
+ }
346
+
347
+ - (void)showSystemBars {
348
+ // No-op on iOS — Android-only
349
+ }
350
+
351
+ #pragma mark - Android-only sync methods (stubs)
352
+
353
+ - (NSNumber *)setSoftInputMode:(double)inputMode {
354
+ // No-op on iOS — Android-only — returns 0
355
+ return @(0);
356
+ }
357
+
358
+ - (NSNumber *)getSoftInputMode {
359
+ // No-op on iOS — Android-only — returns 0
360
+ return @(0);
361
+ }
362
+
363
+ @end
364
+
365
+ #endif // RCT_NEW_ARCH_ENABLED