react-native-spalla-player 0.13.4 → 0.14.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.
@@ -1,36 +1,62 @@
1
1
  package com.spallaplayer
2
2
 
3
3
  import android.content.Context
4
+ import android.util.Log
4
5
  import android.widget.FrameLayout
5
6
  import com.spalla.sdk.android.core.player.view.SpallaPlayerView
6
7
  import android.view.ViewGroup;
8
+ import androidx.core.view.isNotEmpty
7
9
 
8
10
  class SpallaPlayerContainerView(context: Context) : ViewGroup(context) {
9
- val spallaPlayerView: SpallaPlayerView = SpallaPlayerView(context)
11
+ val spallaPlayerView: SpallaPlayerView = SpallaPlayerView(context)
12
+ private var isAttachedToWindow = false
10
13
 
11
- init {
12
- addView(spallaPlayerView) // Add SpallaPlayerView as a child of this container
13
- // You might need to set layout params for spallaPlayerView here
14
- }
14
+ init {
15
+ addView(spallaPlayerView)
16
+ requestLayout()
17
+ }
18
+
19
+ override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
20
+ val containerWidth = r - l
21
+ val containerHeight = b - t
22
+
23
+ Log.d("SpallaPlayerContainerView", "Layout: container=${containerWidth}x${containerHeight}")
24
+
25
+ for (i in 0 until childCount) {
26
+ val child = getChildAt(i)
27
+ child.layout(0, 0, containerWidth, containerHeight)
15
28
 
16
- override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
17
- for (i in 0 until childCount) {
18
- val child = getChildAt(i)
19
- child.layout(0, 0, width, height)
29
+ if (child is SpallaPlayerView) {
30
+ // Schedule multiple layout passes to catch the async initialization
31
+ repeat(3) { index ->
32
+ child.post {
33
+ child.requestLayout()
34
+ }
35
+ }
36
+ }
37
+ }
20
38
  }
21
- }
22
39
 
23
- override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
24
- val width = MeasureSpec.getSize(widthMeasureSpec)
25
- val height = MeasureSpec.getSize(heightMeasureSpec)
26
- for (i in 0 until childCount) {
27
- val child = getChildAt(i)
28
- child.measure(
29
- MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
30
- MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
31
- )
40
+ override fun onAttachedToWindow() {
41
+ super.onAttachedToWindow()
42
+ isAttachedToWindow = true
43
+ // Ensure proper initialization when attached to window
44
+ post {
45
+ requestLayout()
46
+ }
47
+ }
48
+
49
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
50
+ val width = MeasureSpec.getSize(widthMeasureSpec)
51
+ val height = MeasureSpec.getSize(heightMeasureSpec)
52
+ for (i in 0 until childCount) {
53
+ val child = getChildAt(i)
54
+ child.measure(
55
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
56
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
57
+ )
58
+ }
59
+ setMeasuredDimension(width, height)
32
60
  }
33
- setMeasuredDimension(width, height)
34
- }
35
61
 
36
62
  }
@@ -14,180 +14,186 @@ import com.spalla.sdk.android.core.player.view.SpallaPlayerView
14
14
 
15
15
 
16
16
  class SpallaPlayerModule(reactContext: ReactApplicationContext) :
17
- ReactContextBaseJavaModule(reactContext),
18
- LifecycleEventListener {
19
- private val _reactContext: ReactApplicationContext
20
-
21
- init {
22
- reactContext.addLifecycleEventListener(this)
23
- _reactContext = reactContext
24
- }
25
-
26
- override fun getName(): String {
27
- return "RNSpallaPlayer"
28
- }
29
-
30
- override fun onHostResume() {
31
- }
32
-
33
- override fun onHostPause() {
34
-
35
- }
36
-
37
- override fun onHostDestroy() {
38
- }
39
-
40
- @ReactMethod
41
- fun play(tag: Int) {
42
- if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
43
- val uiManager = UIManagerHelper.getUIManager(_reactContext, UIManagerType.FABRIC)
44
- if (uiManager is UIManager) {
45
- uiManager.resolveView(tag)?.let { view ->
46
- if (view is SpallaPlayerContainerView) {
47
- view.spallaPlayerView.play()
48
- } else {
49
- throw ClassCastException(
50
- "Cannot play: view with tag #$tag is not a SpallaPlayerView"
51
- )
52
- }
53
- }
54
- }
55
- } else {
56
- val uiManager: UIManagerModule? =
57
- _reactContext.getNativeModule(UIManagerModule::class.java)
58
- uiManager?.prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
59
- val playerView = nativeViewHierarchyManager.resolveView(tag)
60
- if (playerView is SpallaPlayerContainerView) {
61
- playerView.spallaPlayerView.play()
62
- } else {
63
- throw ClassCastException(
64
- String.format(
65
- "Cannot play: view with tag #%d is not a SpallaPlayerView",
66
- tag
67
- )
68
- )
69
- }
70
- }
17
+ ReactContextBaseJavaModule(reactContext),
18
+ LifecycleEventListener {
19
+ private val _reactContext: ReactApplicationContext
20
+
21
+ init {
22
+ reactContext.addLifecycleEventListener(this)
23
+ _reactContext = reactContext
71
24
  }
72
- }
73
-
74
- @ReactMethod
75
- fun pause(tag: Int) {
76
- if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
77
- val uiManager = UIManagerHelper.getUIManager(_reactContext, UIManagerType.FABRIC)
78
- if (uiManager is UIManager) {
79
- uiManager.resolveView(tag)?.let { view ->
80
- if (view is SpallaPlayerContainerView) {
81
- view.spallaPlayerView.pause()
82
- } else {
83
- throw ClassCastException(
84
- "Cannot pause: view with tag #$tag is not a SpallaPlayerView"
85
- )
86
- }
87
- }
88
- }
89
- } else {
90
- val uiManager: UIManagerModule? =
91
- _reactContext.getNativeModule(UIManagerModule::class.java)
92
- uiManager?.prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
93
- val playerView = nativeViewHierarchyManager.resolveView(tag)
94
- if (playerView is SpallaPlayerContainerView) {
95
- playerView.spallaPlayerView.pause()
96
- } else {
97
- throw ClassCastException(
98
- String.format(
99
- "Cannot play: view with tag #%d is not a SpallaPplayerView",
100
- tag
101
- )
102
- )
103
- }
104
- }
25
+
26
+ override fun getName(): String {
27
+ return "RNSpallaPlayer"
28
+ }
29
+
30
+ override fun onHostResume() {
105
31
  }
106
32
 
33
+ override fun onHostPause() {
107
34
 
108
- }
35
+ }
109
36
 
110
- @ReactMethod
111
- fun seekTo(tag: Int, time: Double) {
112
- _reactContext.getNativeModule(UIManagerModule::class.java)!!
113
- .prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
114
- val playerView = nativeViewHierarchyManager.resolveView(tag)
115
- if (playerView is SpallaPlayerContainerView) {
116
- playerView.spallaPlayerView.seekTo(time)
37
+ override fun onHostDestroy() {
38
+ }
39
+
40
+ @ReactMethod
41
+ fun play(tag: Int) {
42
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
43
+ val uiManager = UIManagerHelper.getUIManager(_reactContext, UIManagerType.FABRIC)
44
+ if (uiManager is UIManager) {
45
+ uiManager.resolveView(tag)?.let { view ->
46
+ if (view is SpallaPlayerContainerView) {
47
+ view.post {
48
+ view.spallaPlayerView.play()
49
+ }
50
+ } else {
51
+ throw ClassCastException(
52
+ "Cannot play: view with tag #$tag is not a SpallaPlayerView"
53
+ )
54
+ }
55
+ }
56
+ }
117
57
  } else {
118
- throw ClassCastException(
119
- String.format(
120
- "Cannot play: view with tag #%d is not a SpallaPplayerView",
121
- tag
122
- )
123
- )
58
+ val uiManager: UIManagerModule? =
59
+ _reactContext.getNativeModule(UIManagerModule::class.java)
60
+ uiManager?.prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
61
+ val playerView = nativeViewHierarchyManager.resolveView(tag)
62
+ if (playerView is SpallaPlayerContainerView) {
63
+ playerView.spallaPlayerView.play()
64
+ } else {
65
+ throw ClassCastException(
66
+ String.format(
67
+ "Cannot play: view with tag #%d is not a SpallaPlayerView",
68
+ tag
69
+ )
70
+ )
71
+ }
72
+ }
124
73
  }
125
- }
126
- }
127
-
128
- @ReactMethod
129
- fun selectSubtitle(tag: Int, subtitle: String?) {
130
- _reactContext.getNativeModule(UIManagerModule::class.java)!!
131
- .prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
132
- val playerView = nativeViewHierarchyManager.resolveView(tag)
133
- if (playerView is SpallaPlayerContainerView) {
134
- playerView.spallaPlayerView.selectSubtitle(subtitle)
74
+ }
75
+
76
+ @ReactMethod
77
+ fun pause(tag: Int) {
78
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
79
+ val uiManager = UIManagerHelper.getUIManager(_reactContext, UIManagerType.FABRIC)
80
+ if (uiManager is UIManager) {
81
+ uiManager.resolveView(tag)?.let { view ->
82
+ if (view is SpallaPlayerContainerView) {
83
+ view.post {
84
+ view.spallaPlayerView.pause()
85
+ }
86
+ } else {
87
+ throw ClassCastException(
88
+ "Cannot pause: view with tag #$tag is not a SpallaPlayerView"
89
+ )
90
+ }
91
+ }
92
+ }
135
93
  } else {
136
- throw ClassCastException(
137
- String.format(
138
- "Cannot play: view with tag #%d is not a SpallaPplayerView",
139
- tag
140
- )
141
- )
94
+ val uiManager: UIManagerModule? =
95
+ _reactContext.getNativeModule(UIManagerModule::class.java)
96
+ uiManager?.prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
97
+ val playerView = nativeViewHierarchyManager.resolveView(tag)
98
+ if (playerView is SpallaPlayerContainerView) {
99
+ playerView.spallaPlayerView.pause()
100
+ } else {
101
+ throw ClassCastException(
102
+ String.format(
103
+ "Cannot play: view with tag #%d is not a SpallaPplayerView",
104
+ tag
105
+ )
106
+ )
107
+ }
108
+ }
142
109
  }
143
- }
144
- }
145
-
146
- @ReactMethod
147
- fun selectPlaybackRate(tag: Int, rate: Double) {
148
- _reactContext.getNativeModule(UIManagerModule::class.java)!!
149
- .prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
150
- val playerView = nativeViewHierarchyManager.resolveView(tag)
151
- if (playerView is SpallaPlayerContainerView) {
152
- playerView.spallaPlayerView.selectPlaybackRate(rate)
110
+
111
+
112
+ }
113
+
114
+ @ReactMethod
115
+ fun seekTo(tag: Int, time: Double) {
116
+ _reactContext.getNativeModule(UIManagerModule::class.java)!!
117
+ .prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
118
+ val playerView = nativeViewHierarchyManager.resolveView(tag)
119
+ if (playerView is SpallaPlayerContainerView) {
120
+ playerView.spallaPlayerView.seekTo(time)
121
+ } else {
122
+ throw ClassCastException(
123
+ String.format(
124
+ "Cannot play: view with tag #%d is not a SpallaPplayerView",
125
+ tag
126
+ )
127
+ )
128
+ }
129
+ }
130
+ }
131
+
132
+ @ReactMethod
133
+ fun selectSubtitle(tag: Int, subtitle: String?) {
134
+ _reactContext.getNativeModule(UIManagerModule::class.java)!!
135
+ .prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
136
+ val playerView = nativeViewHierarchyManager.resolveView(tag)
137
+ if (playerView is SpallaPlayerContainerView) {
138
+ playerView.spallaPlayerView.selectSubtitle(subtitle)
139
+ } else {
140
+ throw ClassCastException(
141
+ String.format(
142
+ "Cannot play: view with tag #%d is not a SpallaPplayerView",
143
+ tag
144
+ )
145
+ )
146
+ }
147
+ }
148
+ }
149
+
150
+ @ReactMethod
151
+ fun selectPlaybackRate(tag: Int, rate: Double) {
152
+ _reactContext.getNativeModule(UIManagerModule::class.java)!!
153
+ .prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
154
+ val playerView = nativeViewHierarchyManager.resolveView(tag)
155
+ if (playerView is SpallaPlayerContainerView) {
156
+ playerView.spallaPlayerView.selectPlaybackRate(rate)
157
+ } else {
158
+ throw ClassCastException(
159
+ String.format(
160
+ "Cannot play: view with tag #%d is not a SpallaPplayerView",
161
+ tag
162
+ )
163
+ )
164
+ }
165
+ }
166
+ }
167
+
168
+ @ReactMethod
169
+ fun unmount(tag: Int) {
170
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
171
+ val uiManager = UIManagerHelper.getUIManager(_reactContext, UIManagerType.FABRIC)
172
+ if (uiManager is UIManager) {
173
+ uiManager.resolveView(tag)?.let { view ->
174
+ if (view is SpallaPlayerContainerView) {
175
+ view.post {
176
+ view.spallaPlayerView.pause()
177
+ }
178
+ }
179
+ }
180
+ }
153
181
  } else {
154
- throw ClassCastException(
155
- String.format(
156
- "Cannot play: view with tag #%d is not a SpallaPplayerView",
157
- tag
158
- )
159
- )
182
+ val uiManager: UIManagerModule? =
183
+ _reactContext.getNativeModule(UIManagerModule::class.java)
184
+ uiManager?.prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
185
+ val playerView = nativeViewHierarchyManager.resolveView(tag)
186
+ if (playerView is SpallaPlayerContainerView) {
187
+ playerView.spallaPlayerView.pause()
188
+ }
189
+ }
160
190
  }
161
- }
162
- }
163
-
164
- @ReactMethod
165
- fun unmount(tag: Int) {
166
- if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
167
- val uiManager = UIManagerHelper.getUIManager(_reactContext, UIManagerType.FABRIC)
168
- if (uiManager is UIManager) {
169
- uiManager.resolveView(tag)?.let { view ->
170
- if (view is SpallaPlayerContainerView) {
171
- view.spallaPlayerView.pause()
172
- }
173
- }
174
- }
175
- } else {
176
- val uiManager: UIManagerModule? =
177
- _reactContext.getNativeModule(UIManagerModule::class.java)
178
- uiManager?.prependUIBlock { nativeViewHierarchyManager: NativeViewHierarchyManager ->
179
- val playerView = nativeViewHierarchyManager.resolveView(tag)
180
- if (playerView is SpallaPlayerContainerView) {
181
- playerView.spallaPlayerView.pause()
182
- }
183
- }
184
191
  }
185
- }
186
192
 
187
- @ReactMethod
188
- fun initialize(token: String, applicationId: String?) {
189
- SpallaSDK.initialize(_reactContext, token)
190
- }
193
+ @ReactMethod
194
+ fun initialize(token: String, applicationId: String?) {
195
+ SpallaSDK.initialize(_reactContext, token)
196
+ }
191
197
 
192
198
 
193
199
  }
@@ -18,216 +18,232 @@ import java.util.Timer
18
18
  import java.util.TimerTask
19
19
 
20
20
  class RNSpallaPlayerManager() : ViewGroupManager<SpallaPlayerContainerView>(),
21
- SpallaPlayerListener, SpallaPlayerFullScreenListener {
22
- private var _playerView: SpallaPlayerView? = null
23
- private var _reactContext: ReactContext? = null
24
- private var _container: SpallaPlayerContainerView? = null
25
-
26
- private var contentId: String? = null
27
- private var startTime: Double? = null
28
- private var subtitle: String? = null
29
- private var loadTimer: Timer? = null
30
- private var playbackRate: Double = 1.0
31
- private var hideUI: Boolean? = null
32
-
33
- override fun getName() = "RNSpallaPlayer"
34
-
35
- override fun createViewInstance(context: ThemedReactContext): SpallaPlayerContainerView {
36
- _reactContext = context
37
- val container = SpallaPlayerContainerView(context)
38
- _playerView = container.spallaPlayerView
39
- _playerView?.registerPlayerListener(this)
40
- _playerView?.registerFullScreenListener(this)
41
- this._container = container
42
-
43
- return container
44
- }
45
-
46
- override fun getExportedCustomBubblingEventTypeConstants(): MutableMap<String, Any> {
47
- val eventMap = mutableMapOf<String, Any>()
48
-
49
- eventMap["onPlayerEvent"] = mapOf(
50
- "phasedRegistrationNames" to mapOf(
51
- "bubbled" to "onPlayerEvent"
52
- )
53
- )
54
-
55
- return eventMap
56
- }
57
-
58
- override fun onDropViewInstance(view: SpallaPlayerContainerView) {
59
- Log.v("RNSpallaPlayerManager", "onDropViewInstance")
60
-
61
- try {
62
- view.spallaPlayerView.onDestroy()
63
- } catch (e: Exception) {
64
- e.printStackTrace()
65
- }
66
- super.onDropViewInstance(view)
67
- }
68
-
69
- override fun addView(parent: SpallaPlayerContainerView, child: View, index: Int) {
70
- parent.addView(child, index)
71
- }
72
-
73
- override fun removeViewAt(parent: SpallaPlayerContainerView, index: Int) {
74
- parent.removeViewAt(index)
75
- }
76
-
77
- override fun getChildCount(parent: SpallaPlayerContainerView): Int {
78
- return parent.childCount
79
- }
80
-
81
- override fun getChildAt(parent: SpallaPlayerContainerView, index: Int): View {
82
- return parent.getChildAt(index)
83
- }
84
-
85
- @ReactProp(name = "contentId")
86
- fun setContentId(view: SpallaPlayerContainerView, contentId: String) {
87
- this.contentId = contentId
88
- checkAndLoadPlayer(view)
89
- }
90
-
91
- @ReactProp(name = "muted")
92
- fun setMuted(view: SpallaPlayerContainerView, muted: Boolean) {
93
- _playerView?.setMuted(muted)
94
- }
95
-
96
- @ReactProp(name = "startTime")
97
- fun setStartTime(view: SpallaPlayerContainerView, startTime: Double) {
98
- this.startTime = startTime
99
- //checkAndLoadPlayer(view)
100
- }
101
-
102
- @ReactProp(name = "subtitle")
103
- fun setSubtitle(view: SpallaPlayerContainerView, subtitle: String?) {
104
- this.subtitle = subtitle
105
- _playerView?.selectSubtitle(subtitle)
106
- }
107
-
108
- @ReactProp(name = "playbackRate")
109
- fun setPlaybackRate(view: SpallaPlayerContainerView, playbackRate: Double) {
110
- if (playbackRate > 0) {
111
- this.playbackRate = playbackRate
112
- _playerView?.selectPlaybackRate(playbackRate)
113
- }
114
- }
115
-
116
- @ReactProp(name = "hideUI")
117
- fun setPlaybackRate(view: SpallaPlayerContainerView, hideUI: Boolean) {
118
- this.hideUI = hideUI
119
- checkAndLoadPlayer(view)
120
- }
121
-
122
- private fun checkAndLoadPlayer(view: SpallaPlayerContainerView) {
123
- if (contentId != null && startTime != null && hideUI != null) {
124
- view.spallaPlayerView.load(contentId!!, true, startTime!!, subtitle, hideUI!!)
125
- }
126
- }
127
-
128
- private fun startLoadTimer(view: SpallaPlayerView) {
129
- // Cancel any existing timer
130
- loadTimer?.cancel()
131
-
132
- // Start a new timer to check if all required properties are set
133
- loadTimer = Timer()
134
- loadTimer?.schedule(object : TimerTask() {
135
- override fun run() {
21
+ SpallaPlayerListener, SpallaPlayerFullScreenListener {
22
+ private var _playerView: SpallaPlayerView? = null
23
+ private var _reactContext: ReactContext? = null
24
+ private var _container: SpallaPlayerContainerView? = null
25
+
26
+ private var contentId: String? = null
27
+ private var startTime: Double? = null
28
+ private var subtitle: String? = null
29
+ private var loadTimer: Timer? = null
30
+ private var playbackRate: Double = 1.0
31
+ private var hideUI: Boolean? = null
32
+
33
+ override fun getName() = "RNSpallaPlayer"
34
+
35
+ override fun createViewInstance(context: ThemedReactContext): SpallaPlayerContainerView {
36
+ _reactContext = context
37
+ val container = SpallaPlayerContainerView(context)
38
+ _playerView = container.spallaPlayerView
39
+ _playerView?.registerPlayerListener(this)
40
+ _playerView?.registerFullScreenListener(this)
41
+ this._container = container
42
+
43
+ return container
44
+ }
45
+
46
+ override fun getExportedCustomBubblingEventTypeConstants(): MutableMap<String, Any> {
47
+ val eventMap = mutableMapOf<String, Any>()
48
+
49
+ eventMap["onPlayerEvent"] = mapOf(
50
+ "phasedRegistrationNames" to mapOf(
51
+ "bubbled" to "onPlayerEvent"
52
+ )
53
+ )
54
+
55
+ return eventMap
56
+ }
57
+
58
+ override fun onDropViewInstance(view: SpallaPlayerContainerView) {
59
+ Log.v("RNSpallaPlayerManager", "onDropViewInstance")
60
+ view.post {
61
+ try {
62
+ loadTimer?.cancel()
63
+ view.spallaPlayerView.onDestroy()
64
+ } catch (e: Exception) {
65
+ e.printStackTrace()
66
+ }
67
+ }
68
+ super.onDropViewInstance(view)
69
+ }
70
+
71
+ override fun addView(parent: SpallaPlayerContainerView, child: View, index: Int) {
72
+ parent.addView(child, index)
73
+ }
74
+
75
+ override fun removeViewAt(parent: SpallaPlayerContainerView, index: Int) {
76
+ parent.removeViewAt(index)
77
+ }
78
+
79
+ override fun getChildCount(parent: SpallaPlayerContainerView): Int {
80
+ return parent.childCount
81
+ }
82
+
83
+ override fun getChildAt(parent: SpallaPlayerContainerView, index: Int): View {
84
+ return parent.getChildAt(index)
85
+ }
86
+
87
+ @ReactProp(name = "contentId")
88
+ fun setContentId(view: SpallaPlayerContainerView, contentId: String) {
89
+ this.contentId = contentId
90
+ //delay initialization for a bit
136
91
  loadTimer?.cancel()
137
- loadTimer = null
138
- // Call view.load with the required properties
139
- view.load(contentId!!, true, startTime!!, subtitle = subtitle, hideUI!!)
140
- }
141
- }, 300) // Delay of 200ms to allow all properties to be set
142
- }
143
-
144
- override fun onEvent(event: SpallaPlayerEvent) {
145
- val map: WritableMap = Arguments.createMap()
146
-
147
- Log.v("RNSpallaPlayerManager", "onEvent: $event")
148
- when (event) {
149
- is DurationUpdate -> {
150
- map.putString("event", "durationUpdate")
151
- map.putDouble("duration", event.duration)
152
- }
153
-
154
- Ended -> map.putString("event", "ended")
155
- is Error -> {
156
- map.putString("event", "error")
157
- map.putString("message", event.message)
158
- }
159
-
160
- Pause -> map.putString("event", "pause")
161
- Play -> map.putString("event", "play")
162
- Playing -> map.putString("event", "playing")
163
- is TimeUpdate -> {
164
- map.putString("event", "timeUpdate")
165
- map.putDouble("time", event.currentTime)
166
- }
167
-
168
- Waiting -> map.putString("event", "buffering")
169
- is SubtitlesAvailable -> {
170
- map.putString("event", "subtitlesAvailable")
171
-
172
- var subs = Arguments.createArray()
173
- event.subtitles.forEach {
174
- subs.pushString(it)
92
+ loadTimer = Timer()
93
+ loadTimer?.schedule(object : TimerTask() {
94
+ override fun run() {
95
+ checkAndLoadPlayer(view)
96
+ }
97
+ }, 100)
98
+ }
99
+
100
+ @ReactProp(name = "muted")
101
+ fun setMuted(view: SpallaPlayerContainerView, muted: Boolean) {
102
+ _playerView?.setMuted(muted)
103
+ }
104
+
105
+ @ReactProp(name = "startTime")
106
+ fun setStartTime(view: SpallaPlayerContainerView, startTime: Double) {
107
+ this.startTime = startTime
108
+ //checkAndLoadPlayer(view)
109
+ }
110
+
111
+ @ReactProp(name = "subtitle")
112
+ fun setSubtitle(view: SpallaPlayerContainerView, subtitle: String?) {
113
+ this.subtitle = subtitle
114
+ _playerView?.selectSubtitle(subtitle)
115
+ }
116
+
117
+ @ReactProp(name = "playbackRate")
118
+ fun setPlaybackRate(view: SpallaPlayerContainerView, playbackRate: Double) {
119
+ if (playbackRate > 0) {
120
+ this.playbackRate = playbackRate
121
+ _playerView?.selectPlaybackRate(playbackRate)
122
+ }
123
+ }
124
+
125
+ @ReactProp(name = "hideUI")
126
+ fun setHideUI(view: SpallaPlayerContainerView, hideUI: Boolean) {
127
+ this.hideUI = hideUI
128
+ }
129
+
130
+ private fun checkAndLoadPlayer(view: SpallaPlayerContainerView) {
131
+ if (contentId != null && startTime != null && hideUI != null) {
132
+ view.post {
133
+ view.spallaPlayerView.load(contentId!!, true, startTime!!, subtitle, hideUI!!)
134
+ }
175
135
  }
176
- map.putArray("subtitles", subs)
177
- }
178
-
179
- is SubtitleSelected -> {
180
- map.putString("event", "subtitleSelected")
181
- map.putString("subtitle", event.subtitle)
182
- }
183
-
184
- is MetadataLoaded -> {
185
- map.putString("event", "metadataLoaded")
186
- map.putBoolean("isLive", event.metadata.isLive)
187
- map.putDouble("duration", event.metadata.duration)
188
-
189
- // make sure current playback rate is applied if set initially
190
- _playerView?.selectPlaybackRate(playbackRate)
191
- }
192
-
193
- is PlaybackRateSelected -> {
194
- map.putString("event", "playbackRateSelected")
195
- map.putDouble("rate", event.rate)
196
- }
197
-
198
- }
199
- _container?.let { container ->
200
- _reactContext?.getJSModule(RCTEventEmitter::class.java)?.receiveEvent(
201
- container.id,
202
- "onPlayerEvent",
203
- map
204
- )
205
- }
206
- }
207
-
208
- override fun onEnterFullScreen() {
209
- Log.v("SpallaPlayerViewManager", "onEnterFullScreen")
210
- val map: WritableMap = Arguments.createMap()
211
- map.putString("event", "enterFullScreen")
212
- _container?.let { container ->
213
- _reactContext?.getJSModule(RCTEventEmitter::class.java)?.receiveEvent(
214
- container.id,
215
- "onPlayerEvent",
216
- map
217
- )
218
- }
219
- }
220
-
221
- override fun onExitFullScreen() {
222
- val map: WritableMap = Arguments.createMap()
223
- map.putString("event", "exitFullScreen")
224
- _container?.let { container ->
225
- _reactContext?.getJSModule(RCTEventEmitter::class.java)?.receiveEvent(
226
- container.id,
227
- "onPlayerEvent",
228
- map
229
- )
230
- }
231
- }
136
+ }
137
+
138
+ override fun onEvent(event: SpallaPlayerEvent) {
139
+ val map: WritableMap = Arguments.createMap()
140
+
141
+ Log.v("RNSpallaPlayerManager", "onEvent: $event")
142
+ when (event) {
143
+ is DurationUpdate -> {
144
+ map.putString("event", "durationUpdate")
145
+ map.putDouble("duration", event.duration)
146
+ requestLayout()
147
+ }
148
+
149
+ Ended -> map.putString("event", "ended")
150
+ is Error -> {
151
+ map.putString("event", "error")
152
+ map.putString("message", event.message)
153
+ }
154
+
155
+ Pause -> map.putString("event", "pause")
156
+ Play -> map.putString("event", "play")
157
+ Playing -> map.putString("event", "playing")
158
+ is TimeUpdate -> {
159
+ map.putString("event", "timeUpdate")
160
+ map.putDouble("time", event.currentTime)
161
+ }
162
+
163
+ Waiting -> map.putString("event", "buffering")
164
+ is SubtitlesAvailable -> {
165
+ map.putString("event", "subtitlesAvailable")
166
+
167
+ var subs = Arguments.createArray()
168
+ event.subtitles.forEach {
169
+ subs.pushString(it)
170
+ }
171
+ map.putArray("subtitles", subs)
172
+ }
173
+
174
+ is SubtitleSelected -> {
175
+ map.putString("event", "subtitleSelected")
176
+ map.putString("subtitle", event.subtitle)
177
+ }
178
+
179
+ is MetadataLoaded -> {
180
+ map.putString("event", "metadataLoaded")
181
+ map.putBoolean("isLive", event.metadata.isLive)
182
+ map.putDouble("duration", event.metadata.duration)
183
+
184
+ // make sure current playback rate is applied if set initially
185
+ _playerView?.selectPlaybackRate(playbackRate)
186
+ requestLayout()
187
+ }
188
+
189
+ is PlaybackRateSelected -> {
190
+ map.putString("event", "playbackRateSelected")
191
+ map.putDouble("rate", event.rate)
192
+ requestLayout()
193
+ }
194
+
195
+ }
196
+ _container?.let { container ->
197
+ _reactContext?.getJSModule(RCTEventEmitter::class.java)?.receiveEvent(
198
+ container.id,
199
+ "onPlayerEvent",
200
+ map
201
+ )
202
+ }
203
+ }
204
+
205
+ override fun onEnterFullScreen() {
206
+ Log.v("SpallaPlayerViewManager", "onEnterFullScreen")
207
+ val map: WritableMap = Arguments.createMap()
208
+ map.putString("event", "enterFullScreen")
209
+ _container?.let { container ->
210
+ _reactContext?.getJSModule(RCTEventEmitter::class.java)?.receiveEvent(
211
+ container.id,
212
+ "onPlayerEvent",
213
+ map
214
+ )
215
+ }
216
+ }
217
+
218
+ override fun onExitFullScreen() {
219
+ val map: WritableMap = Arguments.createMap()
220
+ map.putString("event", "exitFullScreen")
221
+ _container?.let { container ->
222
+ _reactContext?.getJSModule(RCTEventEmitter::class.java)?.receiveEvent(
223
+ container.id,
224
+ "onPlayerEvent",
225
+ map
226
+ )
227
+ }
228
+ }
229
+
230
+ fun requestLayout() {
231
+ _playerView?.post(measureAndLayout)
232
+ }
233
+
234
+ private val measureAndLayout = Runnable {
235
+ _playerView?.let {
236
+ it.measure(
237
+ View.MeasureSpec.makeMeasureSpec(it.width, View.MeasureSpec.EXACTLY),
238
+ View.MeasureSpec.makeMeasureSpec(it.height, View.MeasureSpec.EXACTLY)
239
+ )
240
+ it.layout(
241
+ it.left,
242
+ it.top,
243
+ it.right,
244
+ it.bottom
245
+ )
246
+ }
247
+ }
232
248
 
233
249
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-spalla-player",
3
- "version": "0.13.4",
3
+ "version": "0.14.0",
4
4
  "description": "Spalla SDK for RN",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/commonjs/index.js",