react-native-levelplayads 0.1.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/LICENSE +20 -0
- package/NitroLevelPlayAds.podspec +28 -0
- package/README.md +52 -0
- package/android/CMakeLists.txt +20 -0
- package/android/build.gradle +130 -0
- package/android/consumer-rules.pro +3 -0
- package/android/fix-prefab.gradle +46 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/cpp/cpp-adapter.cpp +7 -0
- package/android/src/main/java/com/margelo/nitro/levelplayads/HybridLevelPlayAds.kt +287 -0
- package/android/src/main/java/com/margelo/nitro/levelplayads/LevelPlayAndroidUtils.kt +30 -0
- package/android/src/main/java/com/margelo/nitro/levelplayads/NitroLevelPlayAdsPackage.java +27 -0
- package/ios/HybridLevelPlayAds.swift +274 -0
- package/ios/LevelPlayAdsSupport.swift +74 -0
- package/lib/module/index.js +31 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/index.test.js +78 -0
- package/lib/module/index.test.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/specs/LevelPlayAds.nitro.js +4 -0
- package/lib/module/specs/LevelPlayAds.nitro.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/index.d.ts +16 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/index.test.d.ts +2 -0
- package/lib/typescript/src/index.test.d.ts.map +1 -0
- package/lib/typescript/src/specs/LevelPlayAds.nitro.d.ts +18 -0
- package/lib/typescript/src/specs/LevelPlayAds.nitro.d.ts.map +1 -0
- package/nitro.json +18 -0
- package/nitrogen/generated/android/NitroLevelPlayAds+autolinking.cmake +81 -0
- package/nitrogen/generated/android/NitroLevelPlayAds+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NitroLevelPlayAdsOnLoad.cpp +44 -0
- package/nitrogen/generated/android/NitroLevelPlayAdsOnLoad.hpp +25 -0
- package/nitrogen/generated/android/c++/JHybridLevelPlayAdsSpec.cpp +112 -0
- package/nitrogen/generated/android/c++/JHybridLevelPlayAdsSpec.hpp +69 -0
- package/nitrogen/generated/android/c++/JLevelPlayAdShowResult.hpp +54 -0
- package/nitrogen/generated/android/c++/JLevelPlayAdShowState.hpp +59 -0
- package/nitrogen/generated/android/c++/JLevelPlayAdType.hpp +59 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/levelplayads/HybridLevelPlayAdsSpec.kt +72 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/levelplayads/LevelPlayAdShowResult.kt +29 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/levelplayads/LevelPlayAdShowState.kt +21 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/levelplayads/LevelPlayAdType.kt +21 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/levelplayads/NitroLevelPlayAdsOnLoad.kt +35 -0
- package/nitrogen/generated/ios/NitroLevelPlayAds+autolinking.rb +60 -0
- package/nitrogen/generated/ios/NitroLevelPlayAds-Swift-Cxx-Bridge.cpp +56 -0
- package/nitrogen/generated/ios/NitroLevelPlayAds-Swift-Cxx-Bridge.hpp +168 -0
- package/nitrogen/generated/ios/NitroLevelPlayAds-Swift-Cxx-Umbrella.hpp +54 -0
- package/nitrogen/generated/ios/NitroLevelPlayAdsAutolinking.mm +33 -0
- package/nitrogen/generated/ios/NitroLevelPlayAdsAutolinking.swift +25 -0
- package/nitrogen/generated/ios/c++/HybridLevelPlayAdsSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridLevelPlayAdsSpecSwift.hpp +116 -0
- package/nitrogen/generated/ios/swift/Func_void.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_LevelPlayAdShowResult.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridLevelPlayAdsSpec.swift +54 -0
- package/nitrogen/generated/ios/swift/HybridLevelPlayAdsSpec_cxx.swift +201 -0
- package/nitrogen/generated/ios/swift/LevelPlayAdShowResult.swift +35 -0
- package/nitrogen/generated/ios/swift/LevelPlayAdShowState.swift +40 -0
- package/nitrogen/generated/ios/swift/LevelPlayAdType.swift +40 -0
- package/nitrogen/generated/shared/c++/HybridLevelPlayAdsSpec.cpp +26 -0
- package/nitrogen/generated/shared/c++/HybridLevelPlayAdsSpec.hpp +73 -0
- package/nitrogen/generated/shared/c++/LevelPlayAdShowResult.hpp +68 -0
- package/nitrogen/generated/shared/c++/LevelPlayAdShowState.hpp +76 -0
- package/nitrogen/generated/shared/c++/LevelPlayAdType.hpp +76 -0
- package/package.json +170 -0
- package/react-native.config.js +8 -0
- package/src/index.test.ts +119 -0
- package/src/index.ts +71 -0
- package/src/specs/LevelPlayAds.nitro.ts +26 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import NitroModules
|
|
3
|
+
// Verified by compiling a throwaway Swift file (`swiftc -typecheck`) against the
|
|
4
|
+
// real IronSourceSDK 9.5.0.0 XCFramework (https://trunk.cocoapods.org, pod
|
|
5
|
+
// "IronSourceSDK") — the framework module is named `IronSource`, and the unified
|
|
6
|
+
// LevelPlay iOS API lives under the `LPM*` prefix (LPMInterstitialAd, LPMRewardedAd,
|
|
7
|
+
// LPMInitRequestBuilder, LPMPrivacySettings, ...), distinct from the legacy
|
|
8
|
+
// `IronSourceAds` facade.
|
|
9
|
+
@preconcurrency import IronSource
|
|
10
|
+
|
|
11
|
+
final class HybridLevelPlayAds: HybridLevelPlayAdsSpec, @unchecked Sendable {
|
|
12
|
+
private let stateLock = NSLock()
|
|
13
|
+
private var isInitialized = false
|
|
14
|
+
private var isInitializing = false
|
|
15
|
+
private var initializedAppKey: String?
|
|
16
|
+
private var initializingAppKey: String?
|
|
17
|
+
private var initializationContinuations: [CheckedContinuation<Void, Error>] = []
|
|
18
|
+
|
|
19
|
+
// Keyed by adUnitId: load() and show() are separate calls in this module's
|
|
20
|
+
// spec, so the loaded ad object has to be held onto between the two calls.
|
|
21
|
+
private var loadedInterstitials: [String: InterstitialAdHolder] = [:]
|
|
22
|
+
private var loadedRewarded: [String: RewardedAdHolder] = [:]
|
|
23
|
+
|
|
24
|
+
// NSLock.lock()/unlock() are `noasync` in Swift 6 — this keeps locking out of
|
|
25
|
+
// `async` function bodies (a suspension point could otherwise occur while held).
|
|
26
|
+
private func withStateLock<T>(_ body: () -> T) -> T {
|
|
27
|
+
stateLock.lock()
|
|
28
|
+
defer { stateLock.unlock() }
|
|
29
|
+
return body()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
func initialize(appKey: String, testMode: Bool) throws -> Promise<Void> {
|
|
33
|
+
guard !appKey.isEmpty else {
|
|
34
|
+
throw levelPlayAdsError("LevelPlay app key is empty")
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return Promise.async {
|
|
38
|
+
try await withCheckedThrowingContinuation { continuation in
|
|
39
|
+
DispatchQueue.main.async {
|
|
40
|
+
self.stateLock.lock()
|
|
41
|
+
if self.isInitialized {
|
|
42
|
+
let existing = self.initializedAppKey
|
|
43
|
+
self.stateLock.unlock()
|
|
44
|
+
if let existing, existing != appKey {
|
|
45
|
+
continuation.resume(
|
|
46
|
+
throwing: levelPlayAdsError("LevelPlay SDK was already initialized with another app key")
|
|
47
|
+
)
|
|
48
|
+
} else {
|
|
49
|
+
continuation.resume()
|
|
50
|
+
}
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if self.isInitializing, self.initializingAppKey != appKey {
|
|
55
|
+
self.stateLock.unlock()
|
|
56
|
+
continuation.resume(
|
|
57
|
+
throwing: levelPlayAdsError("LevelPlay SDK is being initialized with another app key")
|
|
58
|
+
)
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
self.initializationContinuations.append(continuation)
|
|
63
|
+
if self.isInitializing {
|
|
64
|
+
self.stateLock.unlock()
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
self.isInitializing = true
|
|
68
|
+
self.initializingAppKey = appKey
|
|
69
|
+
self.stateLock.unlock()
|
|
70
|
+
|
|
71
|
+
if testMode {
|
|
72
|
+
LevelPlay.setAdaptersDebug(true)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let request = LPMInitRequestBuilder(appKey: appKey).build()
|
|
76
|
+
LevelPlay.initWithRequest(request) { _, error in
|
|
77
|
+
self.handleInitialization(error: error)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
fileprivate func handleInitialization(error: Error?) {
|
|
85
|
+
stateLock.lock()
|
|
86
|
+
let continuations = initializationContinuations
|
|
87
|
+
initializationContinuations.removeAll()
|
|
88
|
+
isInitializing = false
|
|
89
|
+
let appKey = initializingAppKey
|
|
90
|
+
initializingAppKey = nil
|
|
91
|
+
if error == nil {
|
|
92
|
+
isInitialized = true
|
|
93
|
+
initializedAppKey = appKey
|
|
94
|
+
}
|
|
95
|
+
stateLock.unlock()
|
|
96
|
+
|
|
97
|
+
continuations.forEach { continuation in
|
|
98
|
+
if let error {
|
|
99
|
+
continuation.resume(throwing: error)
|
|
100
|
+
} else {
|
|
101
|
+
continuation.resume()
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
func load(adType: LevelPlayAdType, adUnitId: String) throws -> Promise<Void> {
|
|
107
|
+
guard !adUnitId.isEmpty else {
|
|
108
|
+
throw levelPlayAdsError("LevelPlay ad unit ID is empty")
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return Promise.async {
|
|
112
|
+
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) in
|
|
113
|
+
switch adType {
|
|
114
|
+
case .interstitial:
|
|
115
|
+
DispatchQueue.main.async {
|
|
116
|
+
let holder = InterstitialAdHolder(adUnitId: adUnitId)
|
|
117
|
+
RetainBox.retain(holder)
|
|
118
|
+
holder.onLoaded = { [weak self] in
|
|
119
|
+
self?.withStateLock { self?.loadedInterstitials[adUnitId] = holder }
|
|
120
|
+
RetainBox.release(holder)
|
|
121
|
+
continuation.resume()
|
|
122
|
+
}
|
|
123
|
+
holder.onLoadFailed = { error in
|
|
124
|
+
RetainBox.release(holder)
|
|
125
|
+
continuation.resume(throwing: error)
|
|
126
|
+
}
|
|
127
|
+
holder.ad.loadAd()
|
|
128
|
+
}
|
|
129
|
+
case .rewarded:
|
|
130
|
+
DispatchQueue.main.async {
|
|
131
|
+
let holder = RewardedAdHolder(adUnitId: adUnitId)
|
|
132
|
+
RetainBox.retain(holder)
|
|
133
|
+
holder.onLoaded = { [weak self] in
|
|
134
|
+
self?.withStateLock { self?.loadedRewarded[adUnitId] = holder }
|
|
135
|
+
RetainBox.release(holder)
|
|
136
|
+
continuation.resume()
|
|
137
|
+
}
|
|
138
|
+
holder.onLoadFailed = { error in
|
|
139
|
+
RetainBox.release(holder)
|
|
140
|
+
continuation.resume(throwing: error)
|
|
141
|
+
}
|
|
142
|
+
holder.ad.loadAd()
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
func show(adType: LevelPlayAdType, adUnitId: String) throws -> Promise<LevelPlayAdShowResult> {
|
|
150
|
+
guard !adUnitId.isEmpty else {
|
|
151
|
+
throw levelPlayAdsError("LevelPlay ad unit ID is empty")
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return Promise.async {
|
|
155
|
+
let viewController = try await currentViewController()
|
|
156
|
+
|
|
157
|
+
switch adType {
|
|
158
|
+
case .interstitial:
|
|
159
|
+
let holder = self.withStateLock { self.loadedInterstitials.removeValue(forKey: adUnitId) }
|
|
160
|
+
guard let holder else {
|
|
161
|
+
throw levelPlayAdsError("LevelPlay interstitial ad is not ready")
|
|
162
|
+
}
|
|
163
|
+
// Reuse the same delegate that was registered in load() — swapping in a
|
|
164
|
+
// different delegate instance here is what used to drop didCloseAd.
|
|
165
|
+
RetainBox.retain(holder)
|
|
166
|
+
return try await withCheckedThrowingContinuation {
|
|
167
|
+
(continuation: CheckedContinuation<LevelPlayAdShowResult, Error>) in
|
|
168
|
+
holder.onDisplayFailed = { error in onShowDisplayFailed(holder, continuation, error) }
|
|
169
|
+
holder.onClosed = {
|
|
170
|
+
RetainBox.release(holder)
|
|
171
|
+
continuation.resume(returning: LevelPlayAdShowResult(state: .completed))
|
|
172
|
+
}
|
|
173
|
+
DispatchQueue.main.async {
|
|
174
|
+
holder.ad.showAd(viewController: viewController, placementName: nil)
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
case .rewarded:
|
|
178
|
+
let holder = self.withStateLock { self.loadedRewarded.removeValue(forKey: adUnitId) }
|
|
179
|
+
guard let holder else {
|
|
180
|
+
throw levelPlayAdsError("LevelPlay rewarded ad is not ready")
|
|
181
|
+
}
|
|
182
|
+
RetainBox.retain(holder)
|
|
183
|
+
// Rewarded ads don't carry a Unity-style "finish state" — LevelPlay fires a
|
|
184
|
+
// separate didReward event before didCloseAd, so completion is derived from
|
|
185
|
+
// whether that event happened at all before the ad closed.
|
|
186
|
+
var didReceiveReward = false
|
|
187
|
+
return try await withCheckedThrowingContinuation {
|
|
188
|
+
(continuation: CheckedContinuation<LevelPlayAdShowResult, Error>) in
|
|
189
|
+
holder.onReward = { didReceiveReward = true }
|
|
190
|
+
holder.onDisplayFailed = { error in onShowDisplayFailed(holder, continuation, error) }
|
|
191
|
+
holder.onClosed = {
|
|
192
|
+
RetainBox.release(holder)
|
|
193
|
+
let state: LevelPlayAdShowState = didReceiveReward ? .completed : .skipped
|
|
194
|
+
continuation.resume(returning: LevelPlayAdShowResult(state: state))
|
|
195
|
+
}
|
|
196
|
+
DispatchQueue.main.async {
|
|
197
|
+
holder.ad.showAd(viewController: viewController, placementName: nil)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
func setGDPRConsent(optIn: Bool) throws {
|
|
205
|
+
LPMPrivacySettings.setGDPRConsent(optIn)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
func setCCPAConsent(optIn: Bool) throws {
|
|
209
|
+
// CCPA flag semantics are "opted out of sale", the inverse of our `optIn`
|
|
210
|
+
// (personalized-ads-allowed) flag.
|
|
211
|
+
LPMPrivacySettings.setCCPA(!optIn)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
func setCOPPA(isCoppa: Bool) throws {
|
|
215
|
+
LPMPrivacySettings.setCOPPA(isCoppa)
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private func onShowDisplayFailed<T>(
|
|
220
|
+
_ holder: AnyObject,
|
|
221
|
+
_ continuation: CheckedContinuation<T, Error>,
|
|
222
|
+
_ error: Error
|
|
223
|
+
) {
|
|
224
|
+
RetainBox.release(holder)
|
|
225
|
+
continuation.resume(throwing: error)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// LevelPlay requires the same delegate instance to stay registered from
|
|
229
|
+
// loadAd() through showAd() — swapping in a different delegate right before
|
|
230
|
+
// showAd() (as the old per-phase Load/Show delegate pairs did) is what dropped
|
|
231
|
+
// didCloseAd on Android's equivalent path once the listener was swapped.
|
|
232
|
+
private class AdHolder: NSObject, @unchecked Sendable {
|
|
233
|
+
var onLoaded: (() -> Void)?
|
|
234
|
+
var onLoadFailed: ((Error) -> Void)?
|
|
235
|
+
var onDisplayed: (() -> Void)?
|
|
236
|
+
var onDisplayFailed: ((Error) -> Void)?
|
|
237
|
+
var onClosed: (() -> Void)?
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
private final class InterstitialAdHolder: AdHolder, LPMInterstitialAdDelegate {
|
|
241
|
+
let ad: LPMInterstitialAd
|
|
242
|
+
|
|
243
|
+
init(adUnitId: String) {
|
|
244
|
+
self.ad = LPMInterstitialAd(adUnitId: adUnitId)
|
|
245
|
+
super.init()
|
|
246
|
+
self.ad.setDelegate(self)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
func didLoadAd(withAdInfo adInfo: LPMAdInfo) { onLoaded?() }
|
|
250
|
+
func didFailToLoadAd(withAdUnitId adUnitId: String, error: Error) { onLoadFailed?(error) }
|
|
251
|
+
func didDisplayAd(withAdInfo adInfo: LPMAdInfo) { onDisplayed?() }
|
|
252
|
+
func didFailToDisplayAd(withAdInfo adInfo: LPMAdInfo, error: Error) { onDisplayFailed?(error) }
|
|
253
|
+
func didClickAd(withAdInfo adInfo: LPMAdInfo) {}
|
|
254
|
+
func didCloseAd(withAdInfo adInfo: LPMAdInfo) { onClosed?() }
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
private final class RewardedAdHolder: AdHolder, LPMRewardedAdDelegate {
|
|
258
|
+
let ad: LPMRewardedAd
|
|
259
|
+
var onReward: (() -> Void)?
|
|
260
|
+
|
|
261
|
+
init(adUnitId: String) {
|
|
262
|
+
self.ad = LPMRewardedAd(adUnitId: adUnitId)
|
|
263
|
+
super.init()
|
|
264
|
+
self.ad.setDelegate(self)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
func didLoadAd(withAdInfo adInfo: LPMAdInfo) { onLoaded?() }
|
|
268
|
+
func didFailToLoadAd(withAdUnitId adUnitId: String, error: Error) { onLoadFailed?(error) }
|
|
269
|
+
func didDisplayAd(withAdInfo adInfo: LPMAdInfo) { onDisplayed?() }
|
|
270
|
+
func didReward(withAdInfo adInfo: LPMAdInfo, reward: LPMReward) { onReward?() }
|
|
271
|
+
func didFailToDisplayAd(withAdInfo adInfo: LPMAdInfo, error: Error) { onDisplayFailed?(error) }
|
|
272
|
+
func didClickAd(withAdInfo adInfo: LPMAdInfo) {}
|
|
273
|
+
func didCloseAd(withAdInfo adInfo: LPMAdInfo) { onClosed?() }
|
|
274
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import UIKit
|
|
3
|
+
|
|
4
|
+
let levelPlayAdsErrorDomain = "NitroLevelPlayAds"
|
|
5
|
+
|
|
6
|
+
func levelPlayAdsError(_ message: String, code: Int = 1) -> NSError {
|
|
7
|
+
NSError(
|
|
8
|
+
domain: levelPlayAdsErrorDomain,
|
|
9
|
+
code: code,
|
|
10
|
+
userInfo: [NSLocalizedDescriptionKey: message]
|
|
11
|
+
)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
func runOnMain(_ body: @escaping () -> Void) {
|
|
15
|
+
if Thread.isMainThread {
|
|
16
|
+
body()
|
|
17
|
+
} else {
|
|
18
|
+
DispatchQueue.main.sync(execute: body)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
func currentViewController() async throws -> UIViewController {
|
|
23
|
+
try await withCheckedThrowingContinuation { continuation in
|
|
24
|
+
DispatchQueue.main.async {
|
|
25
|
+
let root = UIApplication.shared.connectedScenes
|
|
26
|
+
.compactMap { $0 as? UIWindowScene }
|
|
27
|
+
.flatMap(\.windows)
|
|
28
|
+
.first(where: \.isKeyWindow)?
|
|
29
|
+
.rootViewController
|
|
30
|
+
|
|
31
|
+
guard let root else {
|
|
32
|
+
continuation.resume(
|
|
33
|
+
throwing: levelPlayAdsError("Cannot show LevelPlay ad without a view controller")
|
|
34
|
+
)
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
continuation.resume(returning: topViewController(root))
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private func topViewController(_ viewController: UIViewController) -> UIViewController {
|
|
43
|
+
if let presented = viewController.presentedViewController {
|
|
44
|
+
return topViewController(presented)
|
|
45
|
+
}
|
|
46
|
+
if let navigation = viewController as? UINavigationController,
|
|
47
|
+
let visible = navigation.visibleViewController {
|
|
48
|
+
return topViewController(visible)
|
|
49
|
+
}
|
|
50
|
+
if let tab = viewController as? UITabBarController,
|
|
51
|
+
let selected = tab.selectedViewController {
|
|
52
|
+
return topViewController(selected)
|
|
53
|
+
}
|
|
54
|
+
return viewController
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/// LevelPlay load/show delegates are plain callback objects with no owner —
|
|
58
|
+
/// this keeps them alive for the duration of a single load/show call.
|
|
59
|
+
enum RetainBox {
|
|
60
|
+
private static let lock = NSLock()
|
|
61
|
+
private static var boxes: [ObjectIdentifier: AnyObject] = [:]
|
|
62
|
+
|
|
63
|
+
static func retain(_ object: AnyObject) {
|
|
64
|
+
lock.lock()
|
|
65
|
+
boxes[ObjectIdentifier(object)] = object
|
|
66
|
+
lock.unlock()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static func release(_ object: AnyObject) {
|
|
70
|
+
lock.lock()
|
|
71
|
+
boxes.removeValue(forKey: ObjectIdentifier(object))
|
|
72
|
+
lock.unlock()
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { NitroModules } from 'react-native-nitro-modules';
|
|
4
|
+
const nativeLevelPlayAds = NitroModules.createHybridObject('LevelPlayAds');
|
|
5
|
+
function requireAdUnitId(methodName, adUnitId) {
|
|
6
|
+
if (typeof adUnitId !== 'string' || adUnitId.length === 0) {
|
|
7
|
+
throw new Error(`LevelPlayAds.${methodName}(*) 'adUnitId' expected a non-empty string value.`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
const levelPlayAdsInstance = {
|
|
11
|
+
initialize(appKey, options) {
|
|
12
|
+
if (typeof appKey !== 'string' || appKey.length === 0) {
|
|
13
|
+
throw new Error("LevelPlayAds.initialize(*) 'appKey' expected a non-empty string value.");
|
|
14
|
+
}
|
|
15
|
+
return nativeLevelPlayAds.initialize(appKey, options?.testMode ?? false);
|
|
16
|
+
},
|
|
17
|
+
load(adType, adUnitId) {
|
|
18
|
+
requireAdUnitId('load', adUnitId);
|
|
19
|
+
return nativeLevelPlayAds.load(adType, adUnitId);
|
|
20
|
+
},
|
|
21
|
+
show(adType, adUnitId) {
|
|
22
|
+
requireAdUnitId('show', adUnitId);
|
|
23
|
+
return nativeLevelPlayAds.show(adType, adUnitId);
|
|
24
|
+
},
|
|
25
|
+
setGDPRConsent: optIn => nativeLevelPlayAds.setGDPRConsent(optIn),
|
|
26
|
+
setCCPAConsent: optIn => nativeLevelPlayAds.setCCPAConsent(optIn),
|
|
27
|
+
setCOPPA: isCoppa => nativeLevelPlayAds.setCOPPA(isCoppa)
|
|
28
|
+
};
|
|
29
|
+
export const LevelPlayAds = () => levelPlayAdsInstance;
|
|
30
|
+
export default LevelPlayAds;
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NitroModules","nativeLevelPlayAds","createHybridObject","requireAdUnitId","methodName","adUnitId","length","Error","levelPlayAdsInstance","initialize","appKey","options","testMode","load","adType","show","setGDPRConsent","optIn","setCCPAConsent","setCOPPA","isCoppa","LevelPlayAds"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,4BAA4B;AA2BzD,MAAMC,kBAAkB,GACtBD,YAAY,CAACE,kBAAkB,CAAqB,cAAc,CAAC;AAErE,SAASC,eAAeA,CAACC,UAAkB,EAAEC,QAAgB,EAAQ;EACnE,IAAI,OAAOA,QAAQ,KAAK,QAAQ,IAAIA,QAAQ,CAACC,MAAM,KAAK,CAAC,EAAE;IACzD,MAAM,IAAIC,KAAK,CACb,gBAAgBH,UAAU,mDAC5B,CAAC;EACH;AACF;AAEA,MAAMI,oBAAiD,GAAG;EACxDC,UAAUA,CAACC,MAAM,EAAEC,OAAO,EAAE;IAC1B,IAAI,OAAOD,MAAM,KAAK,QAAQ,IAAIA,MAAM,CAACJ,MAAM,KAAK,CAAC,EAAE;MACrD,MAAM,IAAIC,KAAK,CACb,wEACF,CAAC;IACH;IACA,OAAON,kBAAkB,CAACQ,UAAU,CAACC,MAAM,EAAEC,OAAO,EAAEC,QAAQ,IAAI,KAAK,CAAC;EAC1E,CAAC;EACDC,IAAIA,CAACC,MAAM,EAAET,QAAQ,EAAE;IACrBF,eAAe,CAAC,MAAM,EAAEE,QAAQ,CAAC;IACjC,OAAOJ,kBAAkB,CAACY,IAAI,CAACC,MAAM,EAAET,QAAQ,CAAC;EAClD,CAAC;EACDU,IAAIA,CAACD,MAAM,EAAET,QAAQ,EAAE;IACrBF,eAAe,CAAC,MAAM,EAAEE,QAAQ,CAAC;IACjC,OAAOJ,kBAAkB,CAACc,IAAI,CAACD,MAAM,EAAET,QAAQ,CAAC;EAClD,CAAC;EACDW,cAAc,EAAGC,KAAK,IAAKhB,kBAAkB,CAACe,cAAc,CAACC,KAAK,CAAC;EACnEC,cAAc,EAAGD,KAAK,IAAKhB,kBAAkB,CAACiB,cAAc,CAACD,KAAK,CAAC;EACnEE,QAAQ,EAAGC,OAAO,IAAKnB,kBAAkB,CAACkB,QAAQ,CAACC,OAAO;AAC5D,CAAC;AAED,OAAO,MAAMC,YAAY,GAAGA,CAAA,KAC1Bb,oBAAoB;AAEtB,eAAea,YAAY","ignoreList":[]}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// NitroModules.createHybridObject() is called twice: once by index.ts eagerly
|
|
4
|
+
// at import time, once again below to obtain a reference for assertions. Both
|
|
5
|
+
// calls must return the same object, hence the memoized instance.
|
|
6
|
+
jest.mock('react-native-nitro-modules', () => {
|
|
7
|
+
let instance;
|
|
8
|
+
return {
|
|
9
|
+
NitroModules: {
|
|
10
|
+
createHybridObject: () => {
|
|
11
|
+
instance ??= {
|
|
12
|
+
initialize: jest.fn(async () => undefined),
|
|
13
|
+
load: jest.fn(async () => undefined),
|
|
14
|
+
show: jest.fn(async () => ({
|
|
15
|
+
state: 'completed'
|
|
16
|
+
})),
|
|
17
|
+
setGDPRConsent: jest.fn(),
|
|
18
|
+
setCCPAConsent: jest.fn(),
|
|
19
|
+
setCOPPA: jest.fn()
|
|
20
|
+
};
|
|
21
|
+
return instance;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
import { NitroModules } from 'react-native-nitro-modules';
|
|
27
|
+
import { LevelPlayAds } from "./index.js";
|
|
28
|
+
const mockNativeLevelPlayAds = NitroModules.createHybridObject('LevelPlayAds');
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
jest.clearAllMocks();
|
|
31
|
+
});
|
|
32
|
+
describe('LevelPlayAds().initialize', () => {
|
|
33
|
+
it('throws for an empty app key', () => {
|
|
34
|
+
expect(() => LevelPlayAds().initialize('')).toThrow(/expected a non-empty string value/);
|
|
35
|
+
});
|
|
36
|
+
it('defaults testMode to false', () => {
|
|
37
|
+
LevelPlayAds().initialize('app-key-1');
|
|
38
|
+
expect(mockNativeLevelPlayAds.initialize).toHaveBeenCalledWith('app-key-1', false);
|
|
39
|
+
});
|
|
40
|
+
it('forwards testMode when provided', () => {
|
|
41
|
+
LevelPlayAds().initialize('app-key-1', {
|
|
42
|
+
testMode: true
|
|
43
|
+
});
|
|
44
|
+
expect(mockNativeLevelPlayAds.initialize).toHaveBeenCalledWith('app-key-1', true);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe('LevelPlayAds().load', () => {
|
|
48
|
+
it('throws for an empty ad unit id', () => {
|
|
49
|
+
expect(() => LevelPlayAds().load('interstitial', '')).toThrow(/expected a non-empty string value/);
|
|
50
|
+
});
|
|
51
|
+
it('delegates to the native module', async () => {
|
|
52
|
+
await LevelPlayAds().load('interstitial', 'ad-unit-1');
|
|
53
|
+
expect(mockNativeLevelPlayAds.load).toHaveBeenCalledWith('interstitial', 'ad-unit-1');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
describe('LevelPlayAds().show', () => {
|
|
57
|
+
it('throws for an empty ad unit id', () => {
|
|
58
|
+
expect(() => LevelPlayAds().show('rewarded', '')).toThrow(/expected a non-empty string value/);
|
|
59
|
+
});
|
|
60
|
+
it('resolves with the native show result', async () => {
|
|
61
|
+
const result = await LevelPlayAds().show('rewarded', 'ad-unit-1');
|
|
62
|
+
expect(mockNativeLevelPlayAds.show).toHaveBeenCalledWith('rewarded', 'ad-unit-1');
|
|
63
|
+
expect(result).toEqual({
|
|
64
|
+
state: 'completed'
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('LevelPlayAds() consent setters', () => {
|
|
69
|
+
it('forwards GDPR/CCPA/COPPA flags to the native module', () => {
|
|
70
|
+
LevelPlayAds().setGDPRConsent(true);
|
|
71
|
+
LevelPlayAds().setCCPAConsent(false);
|
|
72
|
+
LevelPlayAds().setCOPPA(true);
|
|
73
|
+
expect(mockNativeLevelPlayAds.setGDPRConsent).toHaveBeenCalledWith(true);
|
|
74
|
+
expect(mockNativeLevelPlayAds.setCCPAConsent).toHaveBeenCalledWith(false);
|
|
75
|
+
expect(mockNativeLevelPlayAds.setCOPPA).toHaveBeenCalledWith(true);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["jest","mock","instance","NitroModules","createHybridObject","initialize","fn","undefined","load","show","state","setGDPRConsent","setCCPAConsent","setCOPPA","LevelPlayAds","mockNativeLevelPlayAds","beforeEach","clearAllMocks","describe","it","expect","toThrow","toHaveBeenCalledWith","testMode","result","toEqual"],"sourceRoot":"../../src","sources":["index.test.ts"],"mappings":";;AAAA;AACA;AACA;AACAA,IAAI,CAACC,IAAI,CAAC,4BAA4B,EAAE,MAAM;EAC5C,IAAIC,QASS;EAEb,OAAO;IACLC,YAAY,EAAE;MACZC,kBAAkB,EAAEA,CAAA,KAAM;QACxBF,QAAQ,KAAK;UACXG,UAAU,EAAEL,IAAI,CAACM,EAAE,CAAC,YAAYC,SAAS,CAAC;UAC1CC,IAAI,EAAER,IAAI,CAACM,EAAE,CAAC,YAAYC,SAAS,CAAC;UACpCE,IAAI,EAAET,IAAI,CAACM,EAAE,CAAC,aAAa;YAAEI,KAAK,EAAE;UAAY,CAAC,CAAC,CAAC;UACnDC,cAAc,EAAEX,IAAI,CAACM,EAAE,CAAC,CAAC;UACzBM,cAAc,EAAEZ,IAAI,CAACM,EAAE,CAAC,CAAC;UACzBO,QAAQ,EAAEb,IAAI,CAACM,EAAE,CAAC;QACpB,CAAC;QACD,OAAOJ,QAAQ;MACjB;IACF;EACF,CAAC;AACH,CAAC,CAAC;AAEF,SAASC,YAAY,QAAQ,4BAA4B;AAEzD,SAASW,YAAY,QAAQ,YAAS;AAEtC,MAAMC,sBAAsB,GAAGZ,YAAY,CAACC,kBAAkB,CAC5D,cACF,CAOC;AAEDY,UAAU,CAAC,MAAM;EACfhB,IAAI,CAACiB,aAAa,CAAC,CAAC;AACtB,CAAC,CAAC;AAEFC,QAAQ,CAAC,2BAA2B,EAAE,MAAM;EAC1CC,EAAE,CAAC,6BAA6B,EAAE,MAAM;IACtCC,MAAM,CAAC,MAAMN,YAAY,CAAC,CAAC,CAACT,UAAU,CAAC,EAAE,CAAC,CAAC,CAACgB,OAAO,CACjD,mCACF,CAAC;EACH,CAAC,CAAC;EAEFF,EAAE,CAAC,4BAA4B,EAAE,MAAM;IACrCL,YAAY,CAAC,CAAC,CAACT,UAAU,CAAC,WAAW,CAAC;IACtCe,MAAM,CAACL,sBAAsB,CAACV,UAAU,CAAC,CAACiB,oBAAoB,CAC5D,WAAW,EACX,KACF,CAAC;EACH,CAAC,CAAC;EAEFH,EAAE,CAAC,iCAAiC,EAAE,MAAM;IAC1CL,YAAY,CAAC,CAAC,CAACT,UAAU,CAAC,WAAW,EAAE;MAAEkB,QAAQ,EAAE;IAAK,CAAC,CAAC;IAC1DH,MAAM,CAACL,sBAAsB,CAACV,UAAU,CAAC,CAACiB,oBAAoB,CAC5D,WAAW,EACX,IACF,CAAC;EACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEFJ,QAAQ,CAAC,qBAAqB,EAAE,MAAM;EACpCC,EAAE,CAAC,gCAAgC,EAAE,MAAM;IACzCC,MAAM,CAAC,MAAMN,YAAY,CAAC,CAAC,CAACN,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAACa,OAAO,CAC3D,mCACF,CAAC;EACH,CAAC,CAAC;EAEFF,EAAE,CAAC,gCAAgC,EAAE,YAAY;IAC/C,MAAML,YAAY,CAAC,CAAC,CAACN,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC;IACtDY,MAAM,CAACL,sBAAsB,CAACP,IAAI,CAAC,CAACc,oBAAoB,CACtD,cAAc,EACd,WACF,CAAC;EACH,CAAC,CAAC;AACJ,CAAC,CAAC;AAEFJ,QAAQ,CAAC,qBAAqB,EAAE,MAAM;EACpCC,EAAE,CAAC,gCAAgC,EAAE,MAAM;IACzCC,MAAM,CAAC,MAAMN,YAAY,CAAC,CAAC,CAACL,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAACY,OAAO,CACvD,mCACF,CAAC;EACH,CAAC,CAAC;EAEFF,EAAE,CAAC,sCAAsC,EAAE,YAAY;IACrD,MAAMK,MAAM,GAAG,MAAMV,YAAY,CAAC,CAAC,CAACL,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC;IACjEW,MAAM,CAACL,sBAAsB,CAACN,IAAI,CAAC,CAACa,oBAAoB,CACtD,UAAU,EACV,WACF,CAAC;IACDF,MAAM,CAACI,MAAM,CAAC,CAACC,OAAO,CAAC;MAAEf,KAAK,EAAE;IAAY,CAAC,CAAC;EAChD,CAAC,CAAC;AACJ,CAAC,CAAC;AAEFQ,QAAQ,CAAC,gCAAgC,EAAE,MAAM;EAC/CC,EAAE,CAAC,qDAAqD,EAAE,MAAM;IAC9DL,YAAY,CAAC,CAAC,CAACH,cAAc,CAAC,IAAI,CAAC;IACnCG,YAAY,CAAC,CAAC,CAACF,cAAc,CAAC,KAAK,CAAC;IACpCE,YAAY,CAAC,CAAC,CAACD,QAAQ,CAAC,IAAI,CAAC;IAE7BO,MAAM,CAACL,sBAAsB,CAACJ,cAAc,CAAC,CAACW,oBAAoB,CAAC,IAAI,CAAC;IACxEF,MAAM,CAACL,sBAAsB,CAACH,cAAc,CAAC,CAACU,oBAAoB,CAAC,KAAK,CAAC;IACzEF,MAAM,CAACL,sBAAsB,CAACF,QAAQ,CAAC,CAACS,oBAAoB,CAAC,IAAI,CAAC;EACpE,CAAC,CAAC;AACJ,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../../src","sources":["specs/LevelPlayAds.nitro.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { LevelPlayAdShowResult, LevelPlayAdType } from './specs/LevelPlayAds.nitro.js';
|
|
2
|
+
export interface LevelPlayAdsInitializeOptions {
|
|
3
|
+
testMode?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export interface LevelPlayAdsModuleInterface {
|
|
6
|
+
initialize(appKey: string, options?: LevelPlayAdsInitializeOptions): Promise<void>;
|
|
7
|
+
load(adType: LevelPlayAdType, adUnitId: string): Promise<void>;
|
|
8
|
+
show(adType: LevelPlayAdType, adUnitId: string): Promise<LevelPlayAdShowResult>;
|
|
9
|
+
setGDPRConsent(optIn: boolean): void;
|
|
10
|
+
setCCPAConsent(optIn: boolean): void;
|
|
11
|
+
setCOPPA(isCoppa: boolean): void;
|
|
12
|
+
}
|
|
13
|
+
export declare const LevelPlayAds: () => LevelPlayAdsModuleInterface;
|
|
14
|
+
export default LevelPlayAds;
|
|
15
|
+
export type { LevelPlayAdShowResult, LevelPlayAdShowState, LevelPlayAdType, LevelPlayAds as LevelPlayAdsSpec, } from './specs/LevelPlayAds.nitro.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,qBAAqB,EACrB,eAAe,EAEhB,MAAM,+BAA4B,CAAC;AAEpC,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,2BAA2B;IAC1C,UAAU,CACR,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,6BAA6B,GACtC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,IAAI,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,IAAI,CACF,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAClC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAClC;AAmCD,eAAO,MAAM,YAAY,QAAO,2BACV,CAAC;AAEvB,eAAe,YAAY,CAAC;AAE5B,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,YAAY,IAAI,gBAAgB,GACjC,MAAM,+BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
export type LevelPlayAdShowState = 'completed' | 'skipped';
|
|
3
|
+
export interface LevelPlayAdShowResult {
|
|
4
|
+
state: LevelPlayAdShowState;
|
|
5
|
+
}
|
|
6
|
+
export type LevelPlayAdType = 'interstitial' | 'rewarded';
|
|
7
|
+
export interface LevelPlayAds extends HybridObject<{
|
|
8
|
+
ios: 'swift';
|
|
9
|
+
android: 'kotlin';
|
|
10
|
+
}> {
|
|
11
|
+
initialize(appKey: string, testMode: boolean): Promise<void>;
|
|
12
|
+
load(adType: LevelPlayAdType, adUnitId: string): Promise<void>;
|
|
13
|
+
show(adType: LevelPlayAdType, adUnitId: string): Promise<LevelPlayAdShowResult>;
|
|
14
|
+
setGDPRConsent(optIn: boolean): void;
|
|
15
|
+
setCCPAConsent(optIn: boolean): void;
|
|
16
|
+
setCOPPA(isCoppa: boolean): void;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=LevelPlayAds.nitro.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LevelPlayAds.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/LevelPlayAds.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG,SAAS,CAAC;AAE3D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,oBAAoB,CAAC;CAC7B;AAED,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,UAAU,CAAC;AAE1D,MAAM,WAAW,YAAa,SAAQ,YAAY,CAAC;IACjD,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,QAAQ,CAAC;CACnB,CAAC;IACA,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7D,IAAI,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,IAAI,CACF,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAElC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAClC"}
|
package/nitro.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://nitro.margelo.com/nitro.schema.json",
|
|
3
|
+
"cxxNamespace": ["levelplayads"],
|
|
4
|
+
"ios": {
|
|
5
|
+
"iosModuleName": "NitroLevelPlayAds"
|
|
6
|
+
},
|
|
7
|
+
"android": {
|
|
8
|
+
"androidNamespace": ["levelplayads"],
|
|
9
|
+
"androidCxxLibName": "NitroLevelPlayAds"
|
|
10
|
+
},
|
|
11
|
+
"autolinking": {
|
|
12
|
+
"LevelPlayAds": {
|
|
13
|
+
"swift": "HybridLevelPlayAds",
|
|
14
|
+
"kotlin": "HybridLevelPlayAds"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"ignorePaths": ["**/node_modules"]
|
|
18
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#
|
|
2
|
+
# NitroLevelPlayAds+autolinking.cmake
|
|
3
|
+
# This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
# https://github.com/mrousavy/nitro
|
|
5
|
+
# Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
# This is a CMake file that adds all files generated by Nitrogen
|
|
9
|
+
# to the current CMake project.
|
|
10
|
+
#
|
|
11
|
+
# To use it, add this to your CMakeLists.txt:
|
|
12
|
+
# ```cmake
|
|
13
|
+
# include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/NitroLevelPlayAds+autolinking.cmake)
|
|
14
|
+
# ```
|
|
15
|
+
|
|
16
|
+
# Define a flag to check if we are building properly
|
|
17
|
+
add_definitions(-DBUILDING_NITROLEVELPLAYADS_WITH_GENERATED_CMAKE_PROJECT)
|
|
18
|
+
|
|
19
|
+
# Enable Raw Props parsing in react-native (for Nitro Views)
|
|
20
|
+
add_definitions(-DRN_SERIALIZABLE_STATE)
|
|
21
|
+
|
|
22
|
+
# Add all headers that were generated by Nitrogen
|
|
23
|
+
include_directories(
|
|
24
|
+
"../nitrogen/generated/shared/c++"
|
|
25
|
+
"../nitrogen/generated/android/c++"
|
|
26
|
+
"../nitrogen/generated/android/"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Add all .cpp sources that were generated by Nitrogen
|
|
30
|
+
target_sources(
|
|
31
|
+
# CMake project name (Android C++ library name)
|
|
32
|
+
NitroLevelPlayAds PRIVATE
|
|
33
|
+
# Autolinking Setup
|
|
34
|
+
../nitrogen/generated/android/NitroLevelPlayAdsOnLoad.cpp
|
|
35
|
+
# Shared Nitrogen C++ sources
|
|
36
|
+
../nitrogen/generated/shared/c++/HybridLevelPlayAdsSpec.cpp
|
|
37
|
+
# Android-specific Nitrogen C++ sources
|
|
38
|
+
../nitrogen/generated/android/c++/JHybridLevelPlayAdsSpec.cpp
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake
|
|
42
|
+
# Used in node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake
|
|
43
|
+
target_compile_definitions(
|
|
44
|
+
NitroLevelPlayAds PRIVATE
|
|
45
|
+
-DFOLLY_NO_CONFIG=1
|
|
46
|
+
-DFOLLY_HAVE_CLOCK_GETTIME=1
|
|
47
|
+
-DFOLLY_USE_LIBCPP=1
|
|
48
|
+
-DFOLLY_CFG_NO_COROUTINES=1
|
|
49
|
+
-DFOLLY_MOBILE=1
|
|
50
|
+
-DFOLLY_HAVE_RECVMMSG=1
|
|
51
|
+
-DFOLLY_HAVE_PTHREAD=1
|
|
52
|
+
# Once we target android-23 above, we can comment
|
|
53
|
+
# the following line. NDK uses GNU style stderror_r() after API 23.
|
|
54
|
+
-DFOLLY_HAVE_XSI_STRERROR_R=1
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Add all libraries required by the generated specs
|
|
58
|
+
find_package(fbjni REQUIRED) # <-- Used for communication between Java <-> C++
|
|
59
|
+
find_package(ReactAndroid REQUIRED) # <-- Used to set up React Native bindings (e.g. CallInvoker/TurboModule)
|
|
60
|
+
find_package(react-native-nitro-modules REQUIRED) # <-- Used to create all HybridObjects and use the Nitro core library
|
|
61
|
+
|
|
62
|
+
# Link all libraries together
|
|
63
|
+
target_link_libraries(
|
|
64
|
+
NitroLevelPlayAds
|
|
65
|
+
fbjni::fbjni # <-- Facebook C++ JNI helpers
|
|
66
|
+
ReactAndroid::jsi # <-- RN: JSI
|
|
67
|
+
react-native-nitro-modules::NitroModules # <-- NitroModules Core :)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Link react-native (different prefab between RN 0.75 and RN 0.76)
|
|
71
|
+
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
|
|
72
|
+
target_link_libraries(
|
|
73
|
+
NitroLevelPlayAds
|
|
74
|
+
ReactAndroid::reactnative # <-- RN: Native Modules umbrella prefab
|
|
75
|
+
)
|
|
76
|
+
else()
|
|
77
|
+
target_link_libraries(
|
|
78
|
+
NitroLevelPlayAds
|
|
79
|
+
ReactAndroid::react_nativemodule_core # <-- RN: TurboModules Core
|
|
80
|
+
)
|
|
81
|
+
endif()
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// NitroLevelPlayAds+autolinking.gradle
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
/// This is a Gradle file that adds all files generated by Nitrogen
|
|
9
|
+
/// to the current Gradle project.
|
|
10
|
+
///
|
|
11
|
+
/// To use it, add this to your build.gradle:
|
|
12
|
+
/// ```gradle
|
|
13
|
+
/// apply from: '../nitrogen/generated/android/NitroLevelPlayAds+autolinking.gradle'
|
|
14
|
+
/// ```
|
|
15
|
+
|
|
16
|
+
logger.warn("[NitroModules] 🔥 NitroLevelPlayAds is boosted by nitro!")
|
|
17
|
+
|
|
18
|
+
android {
|
|
19
|
+
sourceSets {
|
|
20
|
+
main {
|
|
21
|
+
java.srcDirs += [
|
|
22
|
+
// Nitrogen files
|
|
23
|
+
"${project.projectDir}/../nitrogen/generated/android/kotlin"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|