react-native-theoplayer 8.5.0 → 8.7.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 +25 -0
- package/android/build.gradle +3 -3
- package/android/src/main/java/com/theoplayer/ads/AdEventAdapter.kt +2 -2
- package/android/src/main/java/com/theoplayer/ads/AdsModule.kt +52 -0
- package/android/src/main/java/com/theoplayer/player/PlayerModule.kt +7 -0
- package/android/src/main/java/com/theoplayer/presentation/PresentationManager.kt +22 -8
- package/android/src/main/java/com/theoplayer/presentation/PresentationModeChangeContext.kt +4 -1
- package/android/src/main/java/com/theoplayer/util/PayloadBuilder.kt +1 -0
- package/android/src/main/java/com/theoplayer/util/ViewResolver.kt +6 -5
- package/app.plugin.js +3 -2
- package/ios/THEOplayerRCTBridge.m +8 -0
- package/ios/THEOplayerRCTPlayerAPI.swift +6 -0
- package/ios/THEOplayerRCTTypeUtils.swift +16 -0
- package/ios/ads/THEOplayerRCTAdsAPI+Omid.swift +55 -0
- package/ios/ads/THEOplayerRCTAdsEventHandler.swift +77 -36
- package/ios/backgroundAudio/THEOplayerRCTNowPlayingManager.swift +7 -2
- package/lib/commonjs/api/ads/Omid.js +17 -0
- package/lib/commonjs/api/ads/Omid.js.map +1 -0
- package/lib/commonjs/api/ads/barrel.js +11 -0
- package/lib/commonjs/api/ads/barrel.js.map +1 -1
- package/lib/commonjs/api/barrel.js +11 -0
- package/lib/commonjs/api/barrel.js.map +1 -1
- package/lib/commonjs/api/event/PlayerEvent.js +1 -0
- package/lib/commonjs/api/event/PlayerEvent.js.map +1 -1
- package/lib/commonjs/api/version/barrel.js +17 -0
- package/lib/commonjs/api/version/barrel.js.map +1 -0
- package/lib/commonjs/index.js +9 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/internal/adapter/ads/THEOplayerNativeAdsAdapter.js +5 -0
- package/lib/commonjs/internal/adapter/ads/THEOplayerNativeAdsAdapter.js.map +1 -1
- package/lib/commonjs/internal/adapter/ads/THEOplayerNativeOmid.js +25 -0
- package/lib/commonjs/internal/adapter/ads/THEOplayerNativeOmid.js.map +1 -0
- package/lib/commonjs/internal/adapter/ads/THEOplayerWebAdsAdapter.js +5 -0
- package/lib/commonjs/internal/adapter/ads/THEOplayerWebAdsAdapter.js.map +1 -1
- package/lib/commonjs/internal/version/Version.js +20 -0
- package/lib/commonjs/internal/version/Version.js.map +1 -0
- package/lib/commonjs/internal/version/Version.web.js +18 -0
- package/lib/commonjs/internal/version/Version.web.js.map +1 -0
- package/lib/commonjs/manifest.json +1 -0
- package/lib/module/api/ads/Omid.js +12 -0
- package/lib/module/api/ads/Omid.js.map +1 -0
- package/lib/module/api/ads/barrel.js +1 -0
- package/lib/module/api/ads/barrel.js.map +1 -1
- package/lib/module/api/barrel.js +1 -0
- package/lib/module/api/barrel.js.map +1 -1
- package/lib/module/api/event/PlayerEvent.js +1 -0
- package/lib/module/api/event/PlayerEvent.js.map +1 -1
- package/lib/module/api/version/barrel.js +2 -0
- package/lib/module/api/version/barrel.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/internal/adapter/ads/THEOplayerNativeAdsAdapter.js +5 -0
- package/lib/module/internal/adapter/ads/THEOplayerNativeAdsAdapter.js.map +1 -1
- package/lib/module/internal/adapter/ads/THEOplayerNativeOmid.js +18 -0
- package/lib/module/internal/adapter/ads/THEOplayerNativeOmid.js.map +1 -0
- package/lib/module/internal/adapter/ads/THEOplayerWebAdsAdapter.js +5 -0
- package/lib/module/internal/adapter/ads/THEOplayerWebAdsAdapter.js.map +1 -1
- package/lib/module/internal/version/Version.js +11 -0
- package/lib/module/internal/version/Version.js.map +1 -0
- package/lib/module/internal/version/Version.web.js +10 -0
- package/lib/module/internal/version/Version.web.js.map +1 -0
- package/lib/module/manifest.json +1 -0
- package/lib/typescript/api/ads/AdsAPI.d.ts +7 -0
- package/lib/typescript/api/ads/AdsAPI.d.ts.map +1 -1
- package/lib/typescript/api/ads/Omid.d.ts +49 -0
- package/lib/typescript/api/ads/Omid.d.ts.map +1 -0
- package/lib/typescript/api/ads/barrel.d.ts +1 -0
- package/lib/typescript/api/ads/barrel.d.ts.map +1 -1
- package/lib/typescript/api/barrel.d.ts +1 -0
- package/lib/typescript/api/barrel.d.ts.map +1 -1
- package/lib/typescript/api/event/AdEvent.d.ts +2 -2
- package/lib/typescript/api/event/PlayerEvent.d.ts +8 -1
- package/lib/typescript/api/event/PlayerEvent.d.ts.map +1 -1
- package/lib/typescript/api/player/THEOplayer.d.ts +2 -0
- package/lib/typescript/api/player/THEOplayer.d.ts.map +1 -1
- package/lib/typescript/api/version/barrel.d.ts +2 -0
- package/lib/typescript/api/version/barrel.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/internal/adapter/ads/THEOplayerNativeAdsAdapter.d.ts +3 -0
- package/lib/typescript/internal/adapter/ads/THEOplayerNativeAdsAdapter.d.ts.map +1 -1
- package/lib/typescript/internal/adapter/ads/THEOplayerNativeOmid.d.ts +9 -0
- package/lib/typescript/internal/adapter/ads/THEOplayerNativeOmid.d.ts.map +1 -0
- package/lib/typescript/internal/adapter/ads/THEOplayerWebAdsAdapter.d.ts +2 -0
- package/lib/typescript/internal/adapter/ads/THEOplayerWebAdsAdapter.d.ts.map +1 -1
- package/lib/typescript/internal/version/Version.d.ts +3 -0
- package/lib/typescript/internal/version/Version.d.ts.map +1 -0
- package/lib/typescript/internal/version/Version.web.d.ts +3 -0
- package/lib/typescript/internal/version/Version.web.d.ts.map +1 -0
- package/package.json +16 -15
- package/react-native-theoplayer.podspec +6 -6
- package/src/api/ads/AdsAPI.ts +8 -0
- package/src/api/ads/Omid.ts +58 -0
- package/src/api/ads/barrel.ts +1 -0
- package/src/api/barrel.ts +1 -0
- package/src/api/event/AdEvent.ts +2 -2
- package/src/api/event/PlayerEvent.ts +8 -0
- package/src/api/player/THEOplayer.ts +2 -0
- package/src/api/version/barrel.ts +1 -0
- package/src/index.tsx +1 -0
- package/src/internal/adapter/ads/THEOplayerNativeAdsAdapter.ts +8 -0
- package/src/internal/adapter/ads/THEOplayerNativeOmid.ts +21 -0
- package/src/internal/adapter/ads/THEOplayerWebAdsAdapter.ts +7 -0
- package/src/internal/version/Version.ts +12 -0
- package/src/internal/version/Version.web.ts +11 -0
- package/src/manifest.json +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.1.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [8.7.0] - 24-11-05
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Fixed an issue on iOS where the dynamic island (iphone 14 plus and higher) briefly disappeared when updating the nowPlayingInfo on for example backgrounding the app.
|
|
13
|
+
- Fixed an issue on Android when using Expo, where the Expo plugin would not add THEOplayer's Maven repo to the project's repositories list.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Added the `Omid` API for ads, which can be used to manage friendly video controls overlay obstructions.
|
|
18
|
+
|
|
19
|
+
## [8.6.0] - 24-10-25
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Added `AdEvent.AD_CLICKED` and `AdEvent.AD_TAPPED` ad events for iOS and Android. The events are dispatched when a user taps or clicks on an ad that has a `clickThrough` link.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Upgrade example app to support React Native v0.75.
|
|
28
|
+
|
|
8
29
|
## [8.5.0] - 24-10-21
|
|
9
30
|
|
|
10
31
|
### Added
|
|
@@ -40,6 +61,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
40
61
|
- Fixed an issue on Android where on some Android SDK versions controlling playback with the notification buttons would not work.
|
|
41
62
|
- Fixed an issue on Web and Android where a text track with attribute `DEFAULT` was not set as the player's `selectedTextTrack` property.
|
|
42
63
|
|
|
64
|
+
### Added
|
|
65
|
+
|
|
66
|
+
- Added `sdkVersions` to react-native-theoplayer, which contains the current RN SDK version and the version of the underlying native THEOplayer SDK.
|
|
67
|
+
|
|
43
68
|
## [8.3.0] - 24-09-30
|
|
44
69
|
|
|
45
70
|
### Added
|
package/android/build.gradle
CHANGED
|
@@ -108,9 +108,9 @@ repositories {
|
|
|
108
108
|
maven { url "https://maven.theoplayer.com/releases" }
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
// The minimum supported THEOplayer version is 8.
|
|
112
|
-
def theoplayer_sdk_version = safeExtGet('THEOplayer_sdk', '[8.
|
|
113
|
-
def theoplayer_mediasession_version = safeExtGet('THEOplayer_mediasession', '[8.
|
|
111
|
+
// The minimum supported THEOplayer version is 8.3.0
|
|
112
|
+
def theoplayer_sdk_version = safeExtGet('THEOplayer_sdk', '[8.3.0, 9.0.0)')
|
|
113
|
+
def theoplayer_mediasession_version = safeExtGet('THEOplayer_mediasession', '[8.0.0, 9.0.0)')
|
|
114
114
|
|
|
115
115
|
dependencies {
|
|
116
116
|
//noinspection GradleDynamicVersion
|
|
@@ -115,8 +115,8 @@ class AdEventAdapter(private val adsApi: AdsApiWrapper, eventEmitter: AdEventEmi
|
|
|
115
115
|
GoogleImaAdEventType.AD_BREAK_STARTED, AdsEventTypes.AD_BREAK_BEGIN -> "adbreakbegin"
|
|
116
116
|
GoogleImaAdEventType.AD_BREAK_ENDED, AdsEventTypes.AD_BREAK_END -> "adbreakend"
|
|
117
117
|
GoogleImaAdEventType.AD_BREAK_FETCH_ERROR -> "aderror"
|
|
118
|
-
GoogleImaAdEventType.CLICKED -> "adclicked"
|
|
119
|
-
GoogleImaAdEventType.TAPPED -> "adtapped"
|
|
118
|
+
GoogleImaAdEventType.CLICKED, AdsEventTypes.AD_CLICKED -> "adclicked"
|
|
119
|
+
GoogleImaAdEventType.TAPPED, AdsEventTypes.AD_TAPPED -> "adtapped"
|
|
120
120
|
GoogleImaAdEventType.ICON_TAPPED -> "adicontapped"
|
|
121
121
|
GoogleImaAdEventType.ICON_FALLBACK_IMAGE_CLOSED -> "adiconfallbackimageclosed"
|
|
122
122
|
AdsEventTypes.ADD_AD -> "addad"
|
|
@@ -3,14 +3,21 @@
|
|
|
3
3
|
package com.theoplayer.ads
|
|
4
4
|
|
|
5
5
|
import android.util.Log
|
|
6
|
+
import android.view.View
|
|
6
7
|
import com.facebook.react.bridge.*
|
|
7
8
|
import com.theoplayer.source.SourceAdapter
|
|
8
9
|
import com.theoplayer.util.ViewResolver
|
|
9
10
|
import com.theoplayer.ReactTHEOplayerView
|
|
11
|
+
import com.theoplayer.android.api.ads.OmidFriendlyObstruction
|
|
12
|
+
import com.theoplayer.android.api.ads.OmidFriendlyObstructionPurpose
|
|
10
13
|
import com.theoplayer.android.api.error.THEOplayerException
|
|
11
14
|
|
|
12
15
|
private const val TAG = "THEORCTAdsModule"
|
|
13
16
|
|
|
17
|
+
private const val PROP_OMID_VIEW = "view"
|
|
18
|
+
private const val PROP_OMID_PURPOSE = "purpose"
|
|
19
|
+
private const val PROP_OMID_REASON = "reason"
|
|
20
|
+
|
|
14
21
|
class AdsModule(context: ReactApplicationContext) : ReactContextBaseJavaModule(context) {
|
|
15
22
|
private val sourceHelper = SourceAdapter()
|
|
16
23
|
private val viewResolver: ViewResolver = ViewResolver(context)
|
|
@@ -133,4 +140,49 @@ class AdsModule(context: ReactApplicationContext) : ReactContextBaseJavaModule(c
|
|
|
133
140
|
}
|
|
134
141
|
}
|
|
135
142
|
}
|
|
143
|
+
|
|
144
|
+
@ReactMethod
|
|
145
|
+
fun addFriendlyObstruction(tag: Int, obstruction: ReadableMap) {
|
|
146
|
+
val obsTag =
|
|
147
|
+
if (obstruction.hasKey(PROP_OMID_VIEW)) obstruction.getInt(PROP_OMID_VIEW) else null
|
|
148
|
+
val purpose = if (obstruction.hasKey(PROP_OMID_PURPOSE)) {
|
|
149
|
+
when (obstruction.getString(PROP_OMID_PURPOSE)) {
|
|
150
|
+
"videoControls" -> OmidFriendlyObstructionPurpose.VIDEO_CONTROLS
|
|
151
|
+
"closeAd" -> OmidFriendlyObstructionPurpose.CLOSE_AD
|
|
152
|
+
"notVisible" -> OmidFriendlyObstructionPurpose.NOT_VISIBLE
|
|
153
|
+
else -> OmidFriendlyObstructionPurpose.OTHER
|
|
154
|
+
}
|
|
155
|
+
} else null
|
|
156
|
+
val reason =
|
|
157
|
+
if (obstruction.hasKey(PROP_OMID_REASON)) obstruction.getString(PROP_OMID_REASON) else null
|
|
158
|
+
|
|
159
|
+
if (obsTag !== null) {
|
|
160
|
+
viewResolver.resolveViewByTag(obsTag) { obsView: View? ->
|
|
161
|
+
addFriendlyObstruction(tag, obsView, purpose, reason)
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private fun addFriendlyObstruction(
|
|
167
|
+
tag: Int,
|
|
168
|
+
obsView: View?,
|
|
169
|
+
purpose: OmidFriendlyObstructionPurpose?,
|
|
170
|
+
reason: String?
|
|
171
|
+
) {
|
|
172
|
+
if (obsView == null || purpose == null) {
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
viewResolver.resolveViewByTag(tag) { view: ReactTHEOplayerView? ->
|
|
176
|
+
view?.player?.ads?.omid?.addFriendlyObstruction(
|
|
177
|
+
OmidFriendlyObstruction(obsView, purpose, reason)
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@ReactMethod
|
|
183
|
+
fun removeAllFriendlyObstructions(tag: Int) {
|
|
184
|
+
viewResolver.resolveViewByTag(tag) { view: ReactTHEOplayerView? ->
|
|
185
|
+
view?.player?.ads?.omid?.removeAllFriendlyObstructions()
|
|
186
|
+
}
|
|
187
|
+
}
|
|
136
188
|
}
|
|
@@ -10,6 +10,7 @@ import com.theoplayer.android.api.player.RenderingTarget
|
|
|
10
10
|
import com.theoplayer.android.api.player.track.mediatrack.MediaTrack
|
|
11
11
|
import com.theoplayer.android.api.player.track.mediatrack.quality.VideoQuality
|
|
12
12
|
import com.theoplayer.android.api.player.track.texttrack.TextTrackMode
|
|
13
|
+
import com.theoplayer.android.api.THEOplayerGlobal
|
|
13
14
|
import com.theoplayer.audio.BackgroundAudioConfigAdapter
|
|
14
15
|
import com.theoplayer.presentation.PipConfigAdapter
|
|
15
16
|
import com.theoplayer.track.TextTrackStyleAdapter
|
|
@@ -25,6 +26,12 @@ class PlayerModule(context: ReactApplicationContext) : ReactContextBaseJavaModul
|
|
|
25
26
|
return TAG
|
|
26
27
|
}
|
|
27
28
|
|
|
29
|
+
// The native version string of the Android THEOplayer SDK.
|
|
30
|
+
@ReactMethod
|
|
31
|
+
fun version(promise: Promise) {
|
|
32
|
+
promise.resolve(THEOplayerGlobal.getVersion())
|
|
33
|
+
}
|
|
34
|
+
|
|
28
35
|
@ReactMethod
|
|
29
36
|
fun setABRConfig(tag: Int, config: ReadableMap?) {
|
|
30
37
|
viewResolver.resolveViewByTag(tag) { view: ReactTHEOplayerView? ->
|
|
@@ -40,6 +40,8 @@ class PresentationManager(
|
|
|
40
40
|
|
|
41
41
|
var currentPresentationMode: PresentationMode = PresentationMode.INLINE
|
|
42
42
|
private set
|
|
43
|
+
var currentPresentationModeChangeContext: PresentationModeChangeContext? = null
|
|
44
|
+
private set
|
|
43
45
|
|
|
44
46
|
var pipConfig: PipConfig = PipConfig()
|
|
45
47
|
|
|
@@ -54,12 +56,14 @@ class PresentationManager(
|
|
|
54
56
|
}
|
|
55
57
|
onPictureInPictureModeChanged = object : BroadcastReceiver() {
|
|
56
58
|
override fun onReceive(context: Context?, intent: Intent?) {
|
|
57
|
-
|
|
59
|
+
val transitioningToPip = intent
|
|
60
|
+
?.getBooleanExtra("isTransitioningToPip", false) ?: false
|
|
58
61
|
val inPip = intent?.getBooleanExtra("isInPictureInPictureMode", false) ?: false
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
// Dispatch event on every PiP mode change
|
|
63
|
+
when {
|
|
64
|
+
transitioningToPip -> onEnterPip(true)
|
|
65
|
+
inPip -> onEnterPip()
|
|
66
|
+
else -> onExitPip()
|
|
63
67
|
}
|
|
64
68
|
}
|
|
65
69
|
}
|
|
@@ -104,9 +108,11 @@ class PresentationManager(
|
|
|
104
108
|
PresentationMode.INLINE -> {
|
|
105
109
|
setFullscreen(false)
|
|
106
110
|
}
|
|
111
|
+
|
|
107
112
|
PresentationMode.FULLSCREEN -> {
|
|
108
113
|
setFullscreen(true)
|
|
109
114
|
}
|
|
115
|
+
|
|
110
116
|
PresentationMode.PICTURE_IN_PICTURE -> {
|
|
111
117
|
setFullscreen(false)
|
|
112
118
|
enterPip()
|
|
@@ -144,8 +150,13 @@ class PresentationManager(
|
|
|
144
150
|
}
|
|
145
151
|
}
|
|
146
152
|
|
|
147
|
-
private fun onEnterPip() {
|
|
148
|
-
updatePresentationMode(
|
|
153
|
+
private fun onEnterPip(transitioningToPip: Boolean = false) {
|
|
154
|
+
updatePresentationMode(
|
|
155
|
+
PresentationMode.PICTURE_IN_PICTURE,
|
|
156
|
+
if (transitioningToPip)
|
|
157
|
+
PresentationModeChangeContext(PresentationModeChangePipContext.TRANSITIONING_TO_PIP)
|
|
158
|
+
else null
|
|
159
|
+
)
|
|
149
160
|
}
|
|
150
161
|
|
|
151
162
|
private fun onExitPip() {
|
|
@@ -241,11 +252,14 @@ class PresentationManager(
|
|
|
241
252
|
presentationMode: PresentationMode,
|
|
242
253
|
context: PresentationModeChangeContext? = null
|
|
243
254
|
) {
|
|
244
|
-
if (presentationMode == currentPresentationMode
|
|
255
|
+
if (presentationMode == currentPresentationMode &&
|
|
256
|
+
context == currentPresentationModeChangeContext
|
|
257
|
+
) {
|
|
245
258
|
return
|
|
246
259
|
}
|
|
247
260
|
val prevPresentationMode = currentPresentationMode
|
|
248
261
|
currentPresentationMode = presentationMode
|
|
262
|
+
currentPresentationModeChangeContext = context
|
|
249
263
|
eventEmitter.emitPresentationModeChange(presentationMode, prevPresentationMode, context)
|
|
250
264
|
|
|
251
265
|
// Resume playing when going to PiP and player was playing
|
|
@@ -9,7 +9,10 @@ enum class PresentationModeChangePipContext {
|
|
|
9
9
|
CLOSED,
|
|
10
10
|
|
|
11
11
|
// The PiP window transitioned back into the app.
|
|
12
|
-
RESTORED
|
|
12
|
+
RESTORED,
|
|
13
|
+
|
|
14
|
+
// The app transitioning to PiP frame
|
|
15
|
+
TRANSITIONING_TO_PIP
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
data class PresentationModeChangeContext(
|
|
@@ -109,6 +109,7 @@ class PayloadBuilder {
|
|
|
109
109
|
val contextPayload = Arguments.createMap()
|
|
110
110
|
context.pip?.let { pipCtx ->
|
|
111
111
|
contextPayload.putString(EVENT_PROP_PIP, when (pipCtx) {
|
|
112
|
+
PresentationModeChangePipContext.TRANSITIONING_TO_PIP -> "transitioning-to-pip"
|
|
112
113
|
PresentationModeChangePipContext.RESTORED -> "restored"
|
|
113
114
|
else -> "closed"
|
|
114
115
|
})
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
package com.theoplayer.util
|
|
2
2
|
|
|
3
3
|
import android.util.Log
|
|
4
|
+
import android.view.View
|
|
4
5
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
6
|
import com.facebook.react.uimanager.UIManagerModule
|
|
6
|
-
import com.theoplayer.ReactTHEOplayerView
|
|
7
7
|
|
|
8
8
|
private const val TAG = "ViewResolver"
|
|
9
9
|
private const val INVALID_TAG = -1
|
|
10
10
|
|
|
11
|
+
@Suppress("UNCHECKED_CAST")
|
|
11
12
|
class ViewResolver(private val reactContext: ReactApplicationContext) {
|
|
12
13
|
private var uiManager: UIManagerModule? = null
|
|
13
14
|
|
|
14
|
-
fun resolveViewByTag(tag: Int, onResolved: (view:
|
|
15
|
+
fun <T: View> resolveViewByTag(tag: Int, onResolved: (view: T?) -> Unit) {
|
|
15
16
|
if (tag == INVALID_TAG) {
|
|
16
17
|
// Don't bother trying to resolve an invalid tag.
|
|
17
18
|
onResolved(null)
|
|
@@ -21,10 +22,10 @@ class ViewResolver(private val reactContext: ReactApplicationContext) {
|
|
|
21
22
|
}
|
|
22
23
|
uiManager?.addUIBlock {
|
|
23
24
|
try {
|
|
24
|
-
onResolved(it.resolveView(tag) as
|
|
25
|
+
onResolved(it.resolveView(tag) as? T?)
|
|
25
26
|
} catch (e: Exception) {
|
|
26
|
-
// The
|
|
27
|
-
Log.e(TAG, "Failed to resolve
|
|
27
|
+
// The View instance could not be resolved: log but do not forward exception.
|
|
28
|
+
Log.e(TAG, "Failed to resolve View tag $tag: $e")
|
|
28
29
|
onResolved(null)
|
|
29
30
|
}
|
|
30
31
|
}
|
package/app.plugin.js
CHANGED
|
@@ -40,10 +40,11 @@ const withAndroidTHEOplayer = (config, props) => {
|
|
|
40
40
|
const { extensions } = props | {};
|
|
41
41
|
config = applyAndroidExtensions(config, extensions);
|
|
42
42
|
|
|
43
|
-
// Add
|
|
43
|
+
// Add THEOplayer and local Maven repos to the project's repositories
|
|
44
44
|
return withProjectBuildGradle(config, (config) => {
|
|
45
45
|
const localMaven = 'maven { url("$rootDir/../node_modules/react-native-theoplayer/android/local") }';
|
|
46
|
-
|
|
46
|
+
const THEOplayerMaven = 'maven { url("https://maven.theoplayer.com/releases") }';
|
|
47
|
+
config.modResults.contents = config.modResults.contents.replace(/allprojects\s*\{\s*repositories\s*\{/, `$&\n\t\t${localMaven}\n\t\t${THEOplayerMaven}`);
|
|
47
48
|
return config;
|
|
48
49
|
});
|
|
49
50
|
};
|
|
@@ -60,6 +60,9 @@ RCT_EXTERN_METHOD(destroy:(nonnull NSNumber *)node);
|
|
|
60
60
|
// ----------------------------------------------------------------------------
|
|
61
61
|
@interface RCT_EXTERN_REMAP_MODULE(THEORCTPlayerModule, THEOplayerRCTPlayerAPI, NSObject)
|
|
62
62
|
|
|
63
|
+
RCT_EXTERN_METHOD(version:(RCTPromiseResolveBlock)resolve
|
|
64
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
65
|
+
|
|
63
66
|
RCT_EXTERN_METHOD(setPaused:(nonnull NSNumber *)node
|
|
64
67
|
paused:(BOOL)paused)
|
|
65
68
|
|
|
@@ -157,6 +160,11 @@ RCT_EXTERN_METHOD(daiStreamTimeForContentTime:(nonnull NSNumber *)node
|
|
|
157
160
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
158
161
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
159
162
|
|
|
163
|
+
RCT_EXTERN_METHOD(addFriendlyObstruction:(nonnull NSNumber *)node
|
|
164
|
+
obstruction:(NSDictionary)obstruction)
|
|
165
|
+
|
|
166
|
+
RCT_EXTERN_METHOD(removeAllFriendlyObstructions:(nonnull NSNumber *)node)
|
|
167
|
+
|
|
160
168
|
@end
|
|
161
169
|
|
|
162
170
|
// ----------------------------------------------------------------------------
|
|
@@ -35,6 +35,12 @@ class THEOplayerRCTPlayerAPI: NSObject, RCTBridgeModule {
|
|
|
35
35
|
static func requiresMainQueueSetup() -> Bool {
|
|
36
36
|
return false
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
@objc(version:rejecter:)
|
|
40
|
+
func version(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
41
|
+
let versionString = THEOplayer.version
|
|
42
|
+
resolve(versionString)
|
|
43
|
+
}
|
|
38
44
|
|
|
39
45
|
@objc(setPaused:paused:)
|
|
40
46
|
func setPaused(_ node: NSNumber, paused: Bool) -> Void {
|
|
@@ -123,6 +123,22 @@ class THEOplayerRCTTypeUtils {
|
|
|
123
123
|
return .moviePlayback
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
+
|
|
127
|
+
class func omidFriendlyObstructionPurposeFromString(_ purposeString: String) -> OmidFriendlyObstructionPurpose {
|
|
128
|
+
switch purposeString {
|
|
129
|
+
case "videoControls":
|
|
130
|
+
return OmidFriendlyObstructionPurpose.mediaControls
|
|
131
|
+
case "closeAd":
|
|
132
|
+
return OmidFriendlyObstructionPurpose.closeAd
|
|
133
|
+
case "notVisible":
|
|
134
|
+
return OmidFriendlyObstructionPurpose.notVisible
|
|
135
|
+
case "other":
|
|
136
|
+
return OmidFriendlyObstructionPurpose.other
|
|
137
|
+
default:
|
|
138
|
+
return OmidFriendlyObstructionPurpose.other
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
}
|
|
126
142
|
|
|
127
143
|
#if os(iOS)
|
|
128
144
|
class func cacheStatusToString(_ status: CacheStatus) -> String {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// THEOplayerRCTAdsAPI+Omid.swift
|
|
2
|
+
|
|
3
|
+
import Foundation
|
|
4
|
+
import THEOplayerSDK
|
|
5
|
+
import UIKit
|
|
6
|
+
|
|
7
|
+
let PROP_OMID_VIEW: String = "view"
|
|
8
|
+
let PROP_OMID_PURPOSE: String = "purpose"
|
|
9
|
+
let PROP_OMID_REASON: String = "reason"
|
|
10
|
+
|
|
11
|
+
extension THEOplayerRCTAdsAPI {
|
|
12
|
+
|
|
13
|
+
#if canImport(THEOplayerGoogleIMAIntegration)
|
|
14
|
+
@objc(addFriendlyObstruction:obstruction:)
|
|
15
|
+
func addFriendlyObstruction(_ node: NSNumber, obstruction: NSDictionary) {
|
|
16
|
+
DispatchQueue.main.async {
|
|
17
|
+
if let obstructionNode = obstruction[PROP_OMID_VIEW] as? NSNumber,
|
|
18
|
+
let purposeString = obstruction[PROP_OMID_PURPOSE] as? String,
|
|
19
|
+
let theView = self.bridge.uiManager.view(forReactTag: node) as? THEOplayerRCTView,
|
|
20
|
+
let obstructionView = self.bridge.uiManager.view(forReactTag: obstructionNode),
|
|
21
|
+
let ads = theView.ads() {
|
|
22
|
+
let obstruction = OmidFriendlyObstruction(view: obstructionView,
|
|
23
|
+
purpose: THEOplayerRCTTypeUtils.omidFriendlyObstructionPurposeFromString(purposeString),
|
|
24
|
+
detailedReason: obstruction[PROP_OMID_REASON] as? String)
|
|
25
|
+
ads.omid.addFriendlyObstruction(friendlyObstruction: obstruction)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@objc(removeAllFriendlyObstructions:)
|
|
31
|
+
func removeAllFriendlyObstructions(_ node: NSNumber) {
|
|
32
|
+
DispatchQueue.main.async {
|
|
33
|
+
if let theView = self.bridge.uiManager.view(forReactTag: node) as? THEOplayerRCTView,
|
|
34
|
+
let ads = theView.ads() {
|
|
35
|
+
ads.omid.removeFriendlyObstructions()
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
#else
|
|
41
|
+
|
|
42
|
+
@objc(addFriendlyObstruction:obstruction:)
|
|
43
|
+
func addFriendlyObstruction(_ node: NSNumber, obstruction: NSDictionary) {
|
|
44
|
+
if DEBUG_ADS_API { print(ERROR_MESSAGE_ADS_UNSUPPORTED_FEATURE) }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@objc(removeAllFriendlyObstructions:)
|
|
48
|
+
func removeAllFriendlyObstructions(_ node: NSNumber) {
|
|
49
|
+
if DEBUG_ADS_API { print(ERROR_MESSAGE_ADS_UNSUPPORTED_FEATURE) }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
#endif
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|