react-native-tpstreams 0.2.0 → 0.2.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.
@@ -84,7 +84,7 @@ def kotlin_version = getExtOrDefault("kotlinVersion")
84
84
  dependencies {
85
85
  implementation "com.facebook.react:react-android"
86
86
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
87
- implementation "com.tpstreams:tpstreams-player:0.0.1"
87
+ implementation "com.tpstreams:tpstreams-player:0.0.2"
88
88
  }
89
89
 
90
90
  react {
@@ -2,14 +2,20 @@ package com.tpstreams
2
2
 
3
3
  import android.util.Log
4
4
  import android.widget.FrameLayout
5
+ import com.facebook.react.bridge.Arguments
6
+ import com.facebook.react.bridge.ReactContext
5
7
  import com.facebook.react.uimanager.ThemedReactContext
8
+ import com.facebook.react.uimanager.events.RCTEventEmitter
6
9
  import com.tpstreams.player.TPStreamsPlayer
7
10
  import com.tpstreams.player.TPStreamsPlayerView
11
+ import androidx.media3.common.Player
12
+ import androidx.media3.common.PlaybackParameters
13
+ import androidx.media3.common.PlaybackException
8
14
 
9
15
  class TPStreamsRNPlayerView(context: ThemedReactContext) : FrameLayout(context) {
10
-
11
16
  private val playerView: TPStreamsPlayerView = TPStreamsPlayerView(context)
12
17
  private var player: TPStreamsPlayer? = null
18
+ private val reactContext: ReactContext = context
13
19
 
14
20
  private var videoId: String? = null
15
21
  private var accessToken: String? = null
@@ -18,6 +24,31 @@ class TPStreamsRNPlayerView(context: ThemedReactContext) : FrameLayout(context)
18
24
  addView(playerView, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT))
19
25
  }
20
26
 
27
+ // Emit React Native events
28
+ private fun emitEvent(eventName: String, data: Map<String, Any>) {
29
+ val event = Arguments.createMap()
30
+ data.forEach { (key, value) ->
31
+ when (value) {
32
+ is Int -> event.putInt(key, value)
33
+ is Double -> event.putDouble(key, value)
34
+ is Boolean -> event.putBoolean(key, value)
35
+ is String -> event.putString(key, value)
36
+ else -> Log.w("TPStreamsRN", "Unsupported type for event data: ${value::class.java}")
37
+ }
38
+ }
39
+ reactContext.getJSModule(RCTEventEmitter::class.java)
40
+ .receiveEvent(id, eventName, event)
41
+ }
42
+
43
+ private fun sendErrorEvent(message: String, code: Int = 0, details: String? = null) {
44
+ val event = Arguments.createMap()
45
+ event.putString("message", message)
46
+ event.putInt("code", code)
47
+ details?.let { event.putString("details", it) }
48
+ reactContext.getJSModule(RCTEventEmitter::class.java)
49
+ .receiveEvent(id, "onError", event)
50
+ }
51
+
21
52
  fun setVideoId(videoId: String?) {
22
53
  this.videoId = videoId
23
54
  tryCreatePlayer()
@@ -34,13 +65,91 @@ class TPStreamsRNPlayerView(context: ThemedReactContext) : FrameLayout(context)
34
65
 
35
66
  try {
36
67
  player = TPStreamsPlayer.create(context, videoId!!, accessToken!!)
68
+
69
+ // Add player event listeners
70
+ player?.addListener(createPlayerListener())
71
+
37
72
  playerView.player = player
38
73
  playerView.showController()
74
+
75
+ // Send initial events
76
+ emitEvent("onPlayerStateChanged", mapOf("playbackState" to 0))
77
+ emitEvent("onIsPlayingChanged", mapOf("isPlaying" to false))
78
+ emitEvent("onPlaybackSpeedChanged", mapOf("speed" to 1.0))
79
+ emitEvent("onIsLoadingChanged", mapOf("isLoading" to false))
39
80
  } catch (e: Exception) {
40
81
  Log.e("TPStreamsRN", "Error creating player", e)
82
+ sendErrorEvent("Error creating player", 1001, e.message)
41
83
  }
42
84
  }
43
85
 
86
+ private fun createPlayerListener(): Player.Listener {
87
+ return object : Player.Listener {
88
+ override fun onPlaybackStateChanged(playbackState: Int) {
89
+ emitEvent("onPlayerStateChanged", mapOf("playbackState" to playbackState))
90
+ }
91
+
92
+ override fun onIsPlayingChanged(isPlaying: Boolean) {
93
+ emitEvent("onIsPlayingChanged", mapOf("isPlaying" to isPlaying))
94
+ }
95
+
96
+ override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters) {
97
+ emitEvent("onPlaybackSpeedChanged", mapOf("speed" to playbackParameters.speed.toDouble()))
98
+ }
99
+
100
+ override fun onIsLoadingChanged(isLoading: Boolean) {
101
+ emitEvent("onIsLoadingChanged", mapOf("isLoading" to isLoading))
102
+ }
103
+
104
+ override fun onPlayerError(error: PlaybackException) {
105
+ Log.e("TPStreamsRN", "Player error", error)
106
+ sendErrorEvent("Playback error", error.errorCode, error.message)
107
+ }
108
+ }
109
+ }
110
+
111
+ // Player control methods
112
+ fun play() {
113
+ player?.play()
114
+ }
115
+
116
+ fun pause() {
117
+ player?.pause()
118
+ }
119
+
120
+ fun seekTo(positionMs: Long) {
121
+ player?.seekTo(positionMs)
122
+ }
123
+
124
+ fun setPlaybackSpeed(speed: Float) {
125
+ player?.setPlaybackSpeed(speed)
126
+ }
127
+
128
+ // Player information methods with event emission
129
+ fun getCurrentPosition(): Long {
130
+ val position = player?.currentPosition ?: 0L
131
+ emitEvent("onCurrentPosition", mapOf("position" to position.toDouble()))
132
+ return position
133
+ }
134
+
135
+ fun getDuration(): Long {
136
+ val duration = player?.duration ?: 0L
137
+ emitEvent("onDuration", mapOf("duration" to duration.toDouble()))
138
+ return duration
139
+ }
140
+
141
+ fun isPlaying(): Boolean {
142
+ val playing = player?.isPlaying ?: false
143
+ emitEvent("onIsPlaying", mapOf("isPlaying" to playing))
144
+ return playing
145
+ }
146
+
147
+ fun getPlaybackSpeed(): Float {
148
+ val speed = player?.playbackParameters?.speed ?: 1.0f
149
+ emitEvent("onPlaybackSpeed", mapOf("speed" to speed.toDouble()))
150
+ return speed
151
+ }
152
+
44
153
  override fun onDetachedFromWindow() {
45
154
  super.onDetachedFromWindow()
46
155
  try {
@@ -1,6 +1,5 @@
1
1
  package com.tpstreams
2
2
 
3
- import com.facebook.react.bridge.ReadableMap
4
3
  import com.facebook.react.module.annotations.ReactModule
5
4
  import com.facebook.react.uimanager.SimpleViewManager
6
5
  import com.facebook.react.uimanager.ThemedReactContext
@@ -8,39 +7,91 @@ import com.facebook.react.uimanager.ViewManagerDelegate
8
7
  import com.facebook.react.uimanager.annotations.ReactProp
9
8
  import com.facebook.react.viewmanagers.TPStreamsRNPlayerViewManagerInterface
10
9
  import com.facebook.react.viewmanagers.TPStreamsRNPlayerViewManagerDelegate
10
+ import com.facebook.react.common.MapBuilder
11
11
 
12
12
  @ReactModule(name = TPStreamsRNPlayerViewManager.NAME)
13
13
  class TPStreamsRNPlayerViewManager : SimpleViewManager<TPStreamsRNPlayerView>(),
14
14
  TPStreamsRNPlayerViewManagerInterface<TPStreamsRNPlayerView> {
15
- private val mDelegate: ViewManagerDelegate<TPStreamsRNPlayerView>
16
-
17
- init {
18
- mDelegate = TPStreamsRNPlayerViewManagerDelegate(this)
15
+
16
+ companion object {
17
+ const val NAME = "TPStreamsRNPlayerView"
18
+
19
+ // Event names
20
+ private const val EVENT_CURRENT_POSITION = "onCurrentPosition"
21
+ private const val EVENT_DURATION = "onDuration"
22
+ private const val EVENT_IS_PLAYING = "onIsPlaying"
23
+ private const val EVENT_PLAYBACK_SPEED = "onPlaybackSpeed"
24
+ private const val EVENT_PLAYER_STATE_CHANGED = "onPlayerStateChanged"
25
+ private const val EVENT_IS_PLAYING_CHANGED = "onIsPlayingChanged"
26
+ private const val EVENT_PLAYBACK_SPEED_CHANGED = "onPlaybackSpeedChanged"
27
+ private const val EVENT_IS_LOADING_CHANGED = "onIsLoadingChanged"
28
+ private const val EVENT_ERROR = "onError"
19
29
  }
30
+
31
+ private val mDelegate: ViewManagerDelegate<TPStreamsRNPlayerView> =
32
+ TPStreamsRNPlayerViewManagerDelegate(this)
20
33
 
21
- override fun getDelegate(): ViewManagerDelegate<TPStreamsRNPlayerView>? {
22
- return mDelegate
23
- }
34
+ override fun getDelegate(): ViewManagerDelegate<TPStreamsRNPlayerView>? = mDelegate
24
35
 
25
- override fun getName(): String {
26
- return NAME
27
- }
36
+ override fun getName(): String = NAME
28
37
 
29
- public override fun createViewInstance(context: ThemedReactContext): TPStreamsRNPlayerView {
30
- return TPStreamsRNPlayerView(context)
38
+ override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any> {
39
+ return MapBuilder.builder<String, Any>()
40
+ .put(EVENT_CURRENT_POSITION, MapBuilder.of("registrationName", EVENT_CURRENT_POSITION))
41
+ .put(EVENT_DURATION, MapBuilder.of("registrationName", EVENT_DURATION))
42
+ .put(EVENT_IS_PLAYING, MapBuilder.of("registrationName", EVENT_IS_PLAYING))
43
+ .put(EVENT_PLAYBACK_SPEED, MapBuilder.of("registrationName", EVENT_PLAYBACK_SPEED))
44
+ .put(EVENT_PLAYER_STATE_CHANGED, MapBuilder.of("registrationName", EVENT_PLAYER_STATE_CHANGED))
45
+ .put(EVENT_IS_PLAYING_CHANGED, MapBuilder.of("registrationName", EVENT_IS_PLAYING_CHANGED))
46
+ .put(EVENT_PLAYBACK_SPEED_CHANGED, MapBuilder.of("registrationName", EVENT_PLAYBACK_SPEED_CHANGED))
47
+ .put(EVENT_IS_LOADING_CHANGED, MapBuilder.of("registrationName", EVENT_IS_LOADING_CHANGED))
48
+ .put(EVENT_ERROR, MapBuilder.of("registrationName", EVENT_ERROR))
49
+ .build()
31
50
  }
32
51
 
52
+ public override fun createViewInstance(context: ThemedReactContext): TPStreamsRNPlayerView =
53
+ TPStreamsRNPlayerView(context)
54
+
33
55
  @ReactProp(name = "videoId")
34
56
  override fun setVideoId(view: TPStreamsRNPlayerView, videoId: String?) {
35
- view.setVideoId(videoId)
57
+ view.setVideoId(videoId)
36
58
  }
37
59
 
38
60
  @ReactProp(name = "accessToken")
39
61
  override fun setAccessToken(view: TPStreamsRNPlayerView, accessToken: String?) {
40
- view.setAccessToken(accessToken)
62
+ view.setAccessToken(accessToken)
41
63
  }
42
64
 
43
- companion object {
44
- const val NAME = "TPStreamsRNPlayerView"
65
+ // Command implementations
66
+ override fun play(view: TPStreamsRNPlayerView) {
67
+ view.play()
68
+ }
69
+
70
+ override fun pause(view: TPStreamsRNPlayerView) {
71
+ view.pause()
72
+ }
73
+
74
+ override fun seekTo(view: TPStreamsRNPlayerView, positionMs: Double) {
75
+ view.seekTo(positionMs.toLong())
76
+ }
77
+
78
+ override fun setPlaybackSpeed(view: TPStreamsRNPlayerView, speed: Float) {
79
+ view.setPlaybackSpeed(speed)
80
+ }
81
+
82
+ override fun getCurrentPosition(view: TPStreamsRNPlayerView) {
83
+ view.getCurrentPosition()
84
+ }
85
+
86
+ override fun getDuration(view: TPStreamsRNPlayerView) {
87
+ view.getDuration()
88
+ }
89
+
90
+ override fun isPlaying(view: TPStreamsRNPlayerView) {
91
+ view.isPlaying()
92
+ }
93
+
94
+ override fun getPlaybackSpeed(view: TPStreamsRNPlayerView) {
95
+ view.getPlaybackSpeed()
45
96
  }
46
97
  }
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+
3
+ import { forwardRef, useImperativeHandle, useRef, useCallback } from 'react';
4
+ import TPStreamsPlayerView, { Commands } from './TPStreamsPlayerViewNativeComponent';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ // Create a unique ID for each instance to track promises
7
+ let nextInstanceId = 0;
8
+
9
+ // Type for tracking promises waiting to be resolved
10
+
11
+ // Return type for player API methods
12
+
13
+ // Prop types for the player component
14
+
15
+ /**
16
+ * TPStreamsPlayer - React component wrapper for TPStreamsPlayerView
17
+ * Provides a simple imperative API for controlling the player
18
+ */
19
+ const TPStreamsPlayer = /*#__PURE__*/forwardRef((props, ref) => {
20
+ const {
21
+ videoId,
22
+ accessToken,
23
+ style,
24
+ onPlayerStateChanged,
25
+ onIsPlayingChanged,
26
+ onPlaybackSpeedChanged,
27
+ onIsLoadingChanged,
28
+ onError,
29
+ ...restProps
30
+ } = props;
31
+ const nativeRef = useRef(null);
32
+ const instanceId = useRef(nextInstanceId++);
33
+ const promiseMap = useRef({});
34
+
35
+ // Event handlers that resolve promises
36
+ const onCurrentPosition = useCallback(event => {
37
+ const key = `position-${instanceId.current}`;
38
+ const handler = promiseMap.current[key];
39
+ if (handler) {
40
+ handler.resolve(event.nativeEvent.position);
41
+ delete promiseMap.current[key];
42
+ }
43
+ }, []);
44
+ const onDuration = useCallback(event => {
45
+ const key = `duration-${instanceId.current}`;
46
+ const handler = promiseMap.current[key];
47
+ if (handler) {
48
+ handler.resolve(event.nativeEvent.duration);
49
+ delete promiseMap.current[key];
50
+ }
51
+ }, []);
52
+ const onIsPlaying = useCallback(event => {
53
+ const key = `isPlaying-${instanceId.current}`;
54
+ const handler = promiseMap.current[key];
55
+ if (handler) {
56
+ handler.resolve(event.nativeEvent.isPlaying);
57
+ delete promiseMap.current[key];
58
+ }
59
+ }, []);
60
+ const onPlaybackSpeed = useCallback(event => {
61
+ const key = `playbackSpeed-${instanceId.current}`;
62
+ const handler = promiseMap.current[key];
63
+ if (handler) {
64
+ handler.resolve(event.nativeEvent.speed);
65
+ delete promiseMap.current[key];
66
+ }
67
+ }, []);
68
+
69
+ // Player event handlers
70
+ const handlePlayerStateChanged = useCallback(event => {
71
+ onPlayerStateChanged?.(event.nativeEvent.playbackState);
72
+ }, [onPlayerStateChanged]);
73
+ const handleIsPlayingChanged = useCallback(event => {
74
+ onIsPlayingChanged?.(event.nativeEvent.isPlaying);
75
+ }, [onIsPlayingChanged]);
76
+ const handlePlaybackSpeedChanged = useCallback(event => {
77
+ onPlaybackSpeedChanged?.(event.nativeEvent.speed);
78
+ }, [onPlaybackSpeedChanged]);
79
+ const handleIsLoadingChanged = useCallback(event => {
80
+ onIsLoadingChanged?.(event.nativeEvent.isLoading);
81
+ }, [onIsLoadingChanged]);
82
+ const handleError = useCallback(event => {
83
+ const {
84
+ message,
85
+ code,
86
+ details
87
+ } = event.nativeEvent;
88
+
89
+ // Reject any pending promises with this error
90
+ Object.entries(promiseMap.current).forEach(([key, handler]) => {
91
+ handler.reject(new Error(`${message}: ${details || 'Unknown error'}`));
92
+ delete promiseMap.current[key];
93
+ });
94
+
95
+ // Forward the error to the client if they provided an onError handler
96
+ onError?.({
97
+ message,
98
+ code,
99
+ details
100
+ });
101
+ }, [onError]);
102
+
103
+ // Helper to create promise-based API methods
104
+ const createPromiseMethod = useCallback((command, eventKey) => {
105
+ return () => new Promise((resolve, reject) => {
106
+ if (nativeRef.current) {
107
+ const key = `${eventKey}-${instanceId.current}`;
108
+ promiseMap.current[key] = {
109
+ resolve,
110
+ reject
111
+ };
112
+ command(nativeRef.current);
113
+
114
+ // Set a timeout to reject the promise if it's not resolved in time
115
+ setTimeout(() => {
116
+ if (promiseMap.current[key]) {
117
+ reject(new Error(`Timeout getting ${eventKey}`));
118
+ delete promiseMap.current[key];
119
+ }
120
+ }, 5000);
121
+ } else {
122
+ reject(new Error('Player is not initialized'));
123
+ }
124
+ });
125
+ }, []);
126
+ useImperativeHandle(ref, () => ({
127
+ play: () => nativeRef.current && Commands.play(nativeRef.current),
128
+ pause: () => nativeRef.current && Commands.pause(nativeRef.current),
129
+ seekTo: positionMs => nativeRef.current && Commands.seekTo(nativeRef.current, positionMs),
130
+ setPlaybackSpeed: speed => nativeRef.current && Commands.setPlaybackSpeed(nativeRef.current, speed),
131
+ getCurrentPosition: createPromiseMethod(Commands.getCurrentPosition, 'position'),
132
+ getDuration: createPromiseMethod(Commands.getDuration, 'duration'),
133
+ isPlaying: createPromiseMethod(Commands.isPlaying, 'isPlaying'),
134
+ getPlaybackSpeed: createPromiseMethod(Commands.getPlaybackSpeed, 'speed')
135
+ }), [createPromiseMethod]);
136
+
137
+ // Create native props object with the correct types
138
+ const nativeProps = {
139
+ ...restProps,
140
+ videoId,
141
+ accessToken,
142
+ style,
143
+ onCurrentPosition,
144
+ onDuration,
145
+ onIsPlaying,
146
+ onPlaybackSpeed,
147
+ onPlayerStateChanged: handlePlayerStateChanged,
148
+ onIsPlayingChanged: handleIsPlayingChanged,
149
+ onPlaybackSpeedChanged: handlePlaybackSpeedChanged,
150
+ onIsLoadingChanged: handleIsLoadingChanged,
151
+ onError: handleError
152
+ };
153
+ return /*#__PURE__*/_jsx(TPStreamsPlayerView, {
154
+ ...nativeProps,
155
+ ref: nativeRef
156
+ });
157
+ });
158
+ export default TPStreamsPlayer;
159
+ //# sourceMappingURL=TPStreamsPlayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["forwardRef","useImperativeHandle","useRef","useCallback","TPStreamsPlayerView","Commands","jsx","_jsx","nextInstanceId","TPStreamsPlayer","props","ref","videoId","accessToken","style","onPlayerStateChanged","onIsPlayingChanged","onPlaybackSpeedChanged","onIsLoadingChanged","onError","restProps","nativeRef","instanceId","promiseMap","onCurrentPosition","event","key","current","handler","resolve","nativeEvent","position","onDuration","duration","onIsPlaying","isPlaying","onPlaybackSpeed","speed","handlePlayerStateChanged","playbackState","handleIsPlayingChanged","handlePlaybackSpeedChanged","handleIsLoadingChanged","isLoading","handleError","message","code","details","Object","entries","forEach","reject","Error","createPromiseMethod","command","eventKey","Promise","setTimeout","play","pause","seekTo","positionMs","setPlaybackSpeed","getCurrentPosition","getDuration","getPlaybackSpeed","nativeProps"],"sourceRoot":"../../src","sources":["TPStreamsPlayer.tsx"],"mappings":"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","ignoreList":[]}
@@ -1,9 +1,70 @@
1
1
  import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
2
2
  import type { ViewProps } from 'react-native';
3
+ import type {
4
+ Double,
5
+ Float,
6
+ Int32,
7
+ } from 'react-native/Libraries/Types/CodegenTypes';
8
+ import type { HostComponent } from 'react-native';
9
+ import type { DirectEventHandler } from 'react-native/Libraries/Types/CodegenTypes';
10
+ import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';
3
11
 
4
- interface NativeProps extends ViewProps {
12
+ export interface ErrorEvent {
13
+ message: string;
14
+ code: Int32;
15
+ details?: string;
16
+ }
17
+
18
+ export interface NativeProps extends ViewProps {
5
19
  videoId?: string;
6
20
  accessToken?: string;
21
+
22
+ // Event props for receiving data from native methods
23
+ onCurrentPosition?: DirectEventHandler<{ position: Double }>;
24
+ onDuration?: DirectEventHandler<{ duration: Double }>;
25
+ onIsPlaying?: DirectEventHandler<{ isPlaying: boolean }>;
26
+ onPlaybackSpeed?: DirectEventHandler<{ speed: Float }>;
27
+
28
+ // Player event props
29
+ onPlayerStateChanged?: DirectEventHandler<{ playbackState: Int32 }>;
30
+ onIsPlayingChanged?: DirectEventHandler<{ isPlaying: boolean }>;
31
+ onPlaybackSpeedChanged?: DirectEventHandler<{ speed: Double }>;
32
+ onIsLoadingChanged?: DirectEventHandler<{ isLoading: boolean }>;
33
+ onError?: DirectEventHandler<ErrorEvent>;
7
34
  }
8
35
 
36
+ interface TPStreamsPlayerViewCommands {
37
+ play: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
38
+ pause: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
39
+ seekTo: (
40
+ viewRef: React.ElementRef<HostComponent<NativeProps>>,
41
+ positionMs: Double
42
+ ) => void;
43
+ setPlaybackSpeed: (
44
+ viewRef: React.ElementRef<HostComponent<NativeProps>>,
45
+ speed: Float
46
+ ) => void;
47
+ getCurrentPosition: (
48
+ viewRef: React.ElementRef<HostComponent<NativeProps>>
49
+ ) => void;
50
+ getDuration: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
51
+ isPlaying: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
52
+ getPlaybackSpeed: (
53
+ viewRef: React.ElementRef<HostComponent<NativeProps>>
54
+ ) => void;
55
+ }
56
+
57
+ export const Commands = codegenNativeCommands<TPStreamsPlayerViewCommands>({
58
+ supportedCommands: [
59
+ 'play',
60
+ 'pause',
61
+ 'seekTo',
62
+ 'setPlaybackSpeed',
63
+ 'getCurrentPosition',
64
+ 'getDuration',
65
+ 'isPlaying',
66
+ 'getPlaybackSpeed',
67
+ ],
68
+ });
69
+
9
70
  export default codegenNativeComponent<NativeProps>('TPStreamsRNPlayerView');
@@ -3,6 +3,7 @@
3
3
  import { NativeModules } from 'react-native';
4
4
  export { default as TPStreamsPlayerView } from './TPStreamsPlayerViewNativeComponent';
5
5
  export * from './TPStreamsPlayerViewNativeComponent';
6
+ export { default as TPStreamsPlayer } from "./TPStreamsPlayer.js";
6
7
  const TPStreamsModule = NativeModules.TPStreams;
7
8
  export const TPStreams = {
8
9
  initialize: organizationId => {
@@ -1 +1 @@
1
- {"version":3,"names":["NativeModules","default","TPStreamsPlayerView","TPStreamsModule","TPStreams","initialize","organizationId"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,cAAc;AAC5C,SAASC,OAAO,IAAIC,mBAAmB,QAAQ,sCAAsC;AACrF,cAAc,sCAAsC;AAEpD,MAAMC,eAAe,GAAGH,aAAa,CAACI,SAAS;AAE/C,OAAO,MAAMA,SAAS,GAAG;EACvBC,UAAU,EAAGC,cAAsB,IAAW;IAC5CH,eAAe,CAACE,UAAU,CAACC,cAAc,CAAC;EAC5C;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["NativeModules","default","TPStreamsPlayerView","TPStreamsPlayer","TPStreamsModule","TPStreams","initialize","organizationId"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,cAAc;AAC5C,SAASC,OAAO,IAAIC,mBAAmB,QAAQ,sCAAsC;AACrF,cAAc,sCAAsC;AAEpD,SAASD,OAAO,IAAIE,eAAe,QAAQ,sBAAmB;AAG9D,MAAMC,eAAe,GAAGJ,aAAa,CAACK,SAAS;AAE/C,OAAO,MAAMA,SAAS,GAAG;EACvBC,UAAU,EAAGC,cAAsB,IAAW;IAC5CH,eAAe,CAACE,UAAU,CAACC,cAAc,CAAC;EAC5C;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,32 @@
1
+ /// <reference types="react" />
2
+ import type { ViewProps } from 'react-native';
3
+ export interface TPStreamsPlayerRef {
4
+ play: () => void;
5
+ pause: () => void;
6
+ seekTo: (positionMs: number) => void;
7
+ setPlaybackSpeed: (speed: number) => void;
8
+ getCurrentPosition: () => Promise<number>;
9
+ getDuration: () => Promise<number>;
10
+ isPlaying: () => Promise<boolean>;
11
+ getPlaybackSpeed: () => Promise<number>;
12
+ }
13
+ export interface TPStreamsPlayerProps extends ViewProps {
14
+ videoId?: string;
15
+ accessToken?: string;
16
+ onPlayerStateChanged?: (state: number) => void;
17
+ onIsPlayingChanged?: (isPlaying: boolean) => void;
18
+ onPlaybackSpeedChanged?: (speed: number) => void;
19
+ onIsLoadingChanged?: (isLoading: boolean) => void;
20
+ onError?: (error: {
21
+ message: string;
22
+ code: number;
23
+ details?: string;
24
+ }) => void;
25
+ }
26
+ /**
27
+ * TPStreamsPlayer - React component wrapper for TPStreamsPlayerView
28
+ * Provides a simple imperative API for controlling the player
29
+ */
30
+ declare const TPStreamsPlayer: import("react").ForwardRefExoticComponent<TPStreamsPlayerProps & import("react").RefAttributes<TPStreamsPlayerRef>>;
31
+ export default TPStreamsPlayer;
32
+ //# sourceMappingURL=TPStreamsPlayer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TPStreamsPlayer.d.ts","sourceRoot":"","sources":["../../../src/TPStreamsPlayer.tsx"],"names":[],"mappings":";AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAc9C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,kBAAkB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,WAAW,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,gBAAgB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACzC;AAGD,MAAM,WAAW,oBAAqB,SAAQ,SAAS;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,KAAK,IAAI,CAAC;CACZ;AAED;;;GAGG;AACH,QAAA,MAAM,eAAe,qHA0KpB,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,9 +1,54 @@
1
+ /// <reference types="react" />
1
2
  /// <reference types="react-native/types/modules/Codegen" />
2
3
  import type { ViewProps } from 'react-native';
3
- interface NativeProps extends ViewProps {
4
+ import type { Double, Float, Int32 } from 'react-native/Libraries/Types/CodegenTypes';
5
+ import type { HostComponent } from 'react-native';
6
+ import type { DirectEventHandler } from 'react-native/Libraries/Types/CodegenTypes';
7
+ export interface ErrorEvent {
8
+ message: string;
9
+ code: Int32;
10
+ details?: string;
11
+ }
12
+ export interface NativeProps extends ViewProps {
4
13
  videoId?: string;
5
14
  accessToken?: string;
15
+ onCurrentPosition?: DirectEventHandler<{
16
+ position: Double;
17
+ }>;
18
+ onDuration?: DirectEventHandler<{
19
+ duration: Double;
20
+ }>;
21
+ onIsPlaying?: DirectEventHandler<{
22
+ isPlaying: boolean;
23
+ }>;
24
+ onPlaybackSpeed?: DirectEventHandler<{
25
+ speed: Float;
26
+ }>;
27
+ onPlayerStateChanged?: DirectEventHandler<{
28
+ playbackState: Int32;
29
+ }>;
30
+ onIsPlayingChanged?: DirectEventHandler<{
31
+ isPlaying: boolean;
32
+ }>;
33
+ onPlaybackSpeedChanged?: DirectEventHandler<{
34
+ speed: Double;
35
+ }>;
36
+ onIsLoadingChanged?: DirectEventHandler<{
37
+ isLoading: boolean;
38
+ }>;
39
+ onError?: DirectEventHandler<ErrorEvent>;
40
+ }
41
+ interface TPStreamsPlayerViewCommands {
42
+ play: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
43
+ pause: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
44
+ seekTo: (viewRef: React.ElementRef<HostComponent<NativeProps>>, positionMs: Double) => void;
45
+ setPlaybackSpeed: (viewRef: React.ElementRef<HostComponent<NativeProps>>, speed: Float) => void;
46
+ getCurrentPosition: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
47
+ getDuration: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
48
+ isPlaying: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
49
+ getPlaybackSpeed: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
6
50
  }
51
+ export declare const Commands: TPStreamsPlayerViewCommands;
7
52
  declare const _default: import("react-native/Libraries/Utilities/codegenNativeComponent").NativeComponentType<NativeProps>;
8
53
  export default _default;
9
54
  //# sourceMappingURL=TPStreamsPlayerViewNativeComponent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TPStreamsPlayerViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/TPStreamsPlayerViewNativeComponent.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,UAAU,WAAY,SAAQ,SAAS;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;;AAED,wBAA4E"}
1
+ {"version":3,"file":"TPStreamsPlayerViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/TPStreamsPlayerViewNativeComponent.ts"],"names":[],"mappings":";;AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EACV,MAAM,EACN,KAAK,EACL,KAAK,EACN,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAGpF,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,KAAK,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,UAAU,CAAC,EAAE,kBAAkB,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtD,WAAW,CAAC,EAAE,kBAAkB,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACzD,eAAe,CAAC,EAAE,kBAAkB,CAAC;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IAGvD,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;QAAE,aAAa,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IACpE,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAChE,sBAAsB,CAAC,EAAE,kBAAkB,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAChE,OAAO,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;CAC1C;AAED,UAAU,2BAA2B;IACnC,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,CAAC;IACtE,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,CAAC;IACvE,MAAM,EAAE,CACN,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,EACrD,UAAU,EAAE,MAAM,KACf,IAAI,CAAC;IACV,gBAAgB,EAAE,CAChB,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,EACrD,KAAK,EAAE,KAAK,KACT,IAAI,CAAC;IACV,kBAAkB,EAAE,CAClB,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAClD,IAAI,CAAC;IACV,WAAW,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,CAAC;IAC7E,SAAS,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAAK,IAAI,CAAC;IAC3E,gBAAgB,EAAE,CAChB,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,KAClD,IAAI,CAAC;CACX;AAED,eAAO,MAAM,QAAQ,6BAWnB,CAAC;;AAEH,wBAA4E"}
@@ -1,5 +1,7 @@
1
1
  export { default as TPStreamsPlayerView } from './TPStreamsPlayerViewNativeComponent';
2
2
  export * from './TPStreamsPlayerViewNativeComponent';
3
+ export { default as TPStreamsPlayer } from './TPStreamsPlayer';
4
+ export type { TPStreamsPlayerRef } from './TPStreamsPlayer';
3
5
  export declare const TPStreams: {
4
6
  initialize: (organizationId: string) => void;
5
7
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AACtF,cAAc,sCAAsC,CAAC;AAIrD,eAAO,MAAM,SAAS;iCACS,MAAM,KAAG,IAAI;CAG3C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AACtF,cAAc,sCAAsC,CAAC;AAErD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/D,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAI5D,eAAO,MAAM,SAAS;iCACS,MAAM,KAAG,IAAI;CAG3C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-tpstreams",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Video component for TPStreams",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -0,0 +1,225 @@
1
+ import { forwardRef, useImperativeHandle, useRef, useCallback } from 'react';
2
+ import TPStreamsPlayerView, {
3
+ Commands,
4
+ } from './TPStreamsPlayerViewNativeComponent';
5
+ import type {
6
+ NativeProps,
7
+ ErrorEvent,
8
+ } from './TPStreamsPlayerViewNativeComponent';
9
+ import type { ViewProps } from 'react-native';
10
+
11
+ // Create a unique ID for each instance to track promises
12
+ let nextInstanceId = 0;
13
+
14
+ // Type for tracking promises waiting to be resolved
15
+ type PromiseMap = {
16
+ [key: string]: {
17
+ resolve: (value: any) => void;
18
+ reject: (reason?: any) => void;
19
+ };
20
+ };
21
+
22
+ // Return type for player API methods
23
+ export interface TPStreamsPlayerRef {
24
+ play: () => void;
25
+ pause: () => void;
26
+ seekTo: (positionMs: number) => void;
27
+ setPlaybackSpeed: (speed: number) => void;
28
+ getCurrentPosition: () => Promise<number>;
29
+ getDuration: () => Promise<number>;
30
+ isPlaying: () => Promise<boolean>;
31
+ getPlaybackSpeed: () => Promise<number>;
32
+ }
33
+
34
+ // Prop types for the player component
35
+ export interface TPStreamsPlayerProps extends ViewProps {
36
+ videoId?: string;
37
+ accessToken?: string;
38
+ onPlayerStateChanged?: (state: number) => void;
39
+ onIsPlayingChanged?: (isPlaying: boolean) => void;
40
+ onPlaybackSpeedChanged?: (speed: number) => void;
41
+ onIsLoadingChanged?: (isLoading: boolean) => void;
42
+ onError?: (error: {
43
+ message: string;
44
+ code: number;
45
+ details?: string;
46
+ }) => void;
47
+ }
48
+
49
+ /**
50
+ * TPStreamsPlayer - React component wrapper for TPStreamsPlayerView
51
+ * Provides a simple imperative API for controlling the player
52
+ */
53
+ const TPStreamsPlayer = forwardRef<TPStreamsPlayerRef, TPStreamsPlayerProps>(
54
+ (props, ref) => {
55
+ const {
56
+ videoId,
57
+ accessToken,
58
+ style,
59
+ onPlayerStateChanged,
60
+ onIsPlayingChanged,
61
+ onPlaybackSpeedChanged,
62
+ onIsLoadingChanged,
63
+ onError,
64
+ ...restProps
65
+ } = props;
66
+
67
+ const nativeRef = useRef(null);
68
+ const instanceId = useRef<number>(nextInstanceId++);
69
+ const promiseMap = useRef<PromiseMap>({});
70
+
71
+ // Event handlers that resolve promises
72
+ const onCurrentPosition = useCallback((event: any) => {
73
+ const key = `position-${instanceId.current}`;
74
+ const handler = promiseMap.current[key];
75
+ if (handler) {
76
+ handler.resolve(event.nativeEvent.position);
77
+ delete promiseMap.current[key];
78
+ }
79
+ }, []);
80
+
81
+ const onDuration = useCallback((event: any) => {
82
+ const key = `duration-${instanceId.current}`;
83
+ const handler = promiseMap.current[key];
84
+ if (handler) {
85
+ handler.resolve(event.nativeEvent.duration);
86
+ delete promiseMap.current[key];
87
+ }
88
+ }, []);
89
+
90
+ const onIsPlaying = useCallback((event: any) => {
91
+ const key = `isPlaying-${instanceId.current}`;
92
+ const handler = promiseMap.current[key];
93
+ if (handler) {
94
+ handler.resolve(event.nativeEvent.isPlaying);
95
+ delete promiseMap.current[key];
96
+ }
97
+ }, []);
98
+
99
+ const onPlaybackSpeed = useCallback((event: any) => {
100
+ const key = `playbackSpeed-${instanceId.current}`;
101
+ const handler = promiseMap.current[key];
102
+ if (handler) {
103
+ handler.resolve(event.nativeEvent.speed);
104
+ delete promiseMap.current[key];
105
+ }
106
+ }, []);
107
+
108
+ // Player event handlers
109
+ const handlePlayerStateChanged = useCallback(
110
+ (event: any) => {
111
+ onPlayerStateChanged?.(event.nativeEvent.playbackState);
112
+ },
113
+ [onPlayerStateChanged]
114
+ );
115
+
116
+ const handleIsPlayingChanged = useCallback(
117
+ (event: any) => {
118
+ onIsPlayingChanged?.(event.nativeEvent.isPlaying);
119
+ },
120
+ [onIsPlayingChanged]
121
+ );
122
+
123
+ const handlePlaybackSpeedChanged = useCallback(
124
+ (event: any) => {
125
+ onPlaybackSpeedChanged?.(event.nativeEvent.speed);
126
+ },
127
+ [onPlaybackSpeedChanged]
128
+ );
129
+
130
+ const handleIsLoadingChanged = useCallback(
131
+ (event: any) => {
132
+ onIsLoadingChanged?.(event.nativeEvent.isLoading);
133
+ },
134
+ [onIsLoadingChanged]
135
+ );
136
+
137
+ const handleError = useCallback(
138
+ (event: { nativeEvent: ErrorEvent }) => {
139
+ const { message, code, details } = event.nativeEvent;
140
+
141
+ // Reject any pending promises with this error
142
+ Object.entries(promiseMap.current).forEach(([key, handler]) => {
143
+ handler.reject(
144
+ new Error(`${message}: ${details || 'Unknown error'}`)
145
+ );
146
+ delete promiseMap.current[key];
147
+ });
148
+
149
+ // Forward the error to the client if they provided an onError handler
150
+ onError?.({ message, code, details });
151
+ },
152
+ [onError]
153
+ );
154
+
155
+ // Helper to create promise-based API methods
156
+ const createPromiseMethod = useCallback(
157
+ (command: (ref: any) => void, eventKey: string) => {
158
+ return () =>
159
+ new Promise<any>((resolve, reject) => {
160
+ if (nativeRef.current) {
161
+ const key = `${eventKey}-${instanceId.current}`;
162
+ promiseMap.current[key] = { resolve, reject };
163
+ command(nativeRef.current);
164
+
165
+ // Set a timeout to reject the promise if it's not resolved in time
166
+ setTimeout(() => {
167
+ if (promiseMap.current[key]) {
168
+ reject(new Error(`Timeout getting ${eventKey}`));
169
+ delete promiseMap.current[key];
170
+ }
171
+ }, 5000);
172
+ } else {
173
+ reject(new Error('Player is not initialized'));
174
+ }
175
+ });
176
+ },
177
+ []
178
+ );
179
+
180
+ useImperativeHandle(
181
+ ref,
182
+ () => ({
183
+ play: () => nativeRef.current && Commands.play(nativeRef.current),
184
+ pause: () => nativeRef.current && Commands.pause(nativeRef.current),
185
+ seekTo: (positionMs: number) =>
186
+ nativeRef.current && Commands.seekTo(nativeRef.current, positionMs),
187
+ setPlaybackSpeed: (speed: number) =>
188
+ nativeRef.current &&
189
+ Commands.setPlaybackSpeed(nativeRef.current, speed),
190
+ getCurrentPosition: createPromiseMethod(
191
+ Commands.getCurrentPosition,
192
+ 'position'
193
+ ),
194
+ getDuration: createPromiseMethod(Commands.getDuration, 'duration'),
195
+ isPlaying: createPromiseMethod(Commands.isPlaying, 'isPlaying'),
196
+ getPlaybackSpeed: createPromiseMethod(
197
+ Commands.getPlaybackSpeed,
198
+ 'speed'
199
+ ),
200
+ }),
201
+ [createPromiseMethod]
202
+ );
203
+
204
+ // Create native props object with the correct types
205
+ const nativeProps: NativeProps = {
206
+ ...restProps,
207
+ videoId,
208
+ accessToken,
209
+ style,
210
+ onCurrentPosition,
211
+ onDuration,
212
+ onIsPlaying,
213
+ onPlaybackSpeed,
214
+ onPlayerStateChanged: handlePlayerStateChanged,
215
+ onIsPlayingChanged: handleIsPlayingChanged,
216
+ onPlaybackSpeedChanged: handlePlaybackSpeedChanged,
217
+ onIsLoadingChanged: handleIsLoadingChanged,
218
+ onError: handleError,
219
+ };
220
+
221
+ return <TPStreamsPlayerView {...nativeProps} ref={nativeRef} />;
222
+ }
223
+ );
224
+
225
+ export default TPStreamsPlayer;
@@ -1,9 +1,70 @@
1
1
  import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
2
2
  import type { ViewProps } from 'react-native';
3
+ import type {
4
+ Double,
5
+ Float,
6
+ Int32,
7
+ } from 'react-native/Libraries/Types/CodegenTypes';
8
+ import type { HostComponent } from 'react-native';
9
+ import type { DirectEventHandler } from 'react-native/Libraries/Types/CodegenTypes';
10
+ import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';
3
11
 
4
- interface NativeProps extends ViewProps {
12
+ export interface ErrorEvent {
13
+ message: string;
14
+ code: Int32;
15
+ details?: string;
16
+ }
17
+
18
+ export interface NativeProps extends ViewProps {
5
19
  videoId?: string;
6
20
  accessToken?: string;
21
+
22
+ // Event props for receiving data from native methods
23
+ onCurrentPosition?: DirectEventHandler<{ position: Double }>;
24
+ onDuration?: DirectEventHandler<{ duration: Double }>;
25
+ onIsPlaying?: DirectEventHandler<{ isPlaying: boolean }>;
26
+ onPlaybackSpeed?: DirectEventHandler<{ speed: Float }>;
27
+
28
+ // Player event props
29
+ onPlayerStateChanged?: DirectEventHandler<{ playbackState: Int32 }>;
30
+ onIsPlayingChanged?: DirectEventHandler<{ isPlaying: boolean }>;
31
+ onPlaybackSpeedChanged?: DirectEventHandler<{ speed: Double }>;
32
+ onIsLoadingChanged?: DirectEventHandler<{ isLoading: boolean }>;
33
+ onError?: DirectEventHandler<ErrorEvent>;
7
34
  }
8
35
 
36
+ interface TPStreamsPlayerViewCommands {
37
+ play: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
38
+ pause: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
39
+ seekTo: (
40
+ viewRef: React.ElementRef<HostComponent<NativeProps>>,
41
+ positionMs: Double
42
+ ) => void;
43
+ setPlaybackSpeed: (
44
+ viewRef: React.ElementRef<HostComponent<NativeProps>>,
45
+ speed: Float
46
+ ) => void;
47
+ getCurrentPosition: (
48
+ viewRef: React.ElementRef<HostComponent<NativeProps>>
49
+ ) => void;
50
+ getDuration: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
51
+ isPlaying: (viewRef: React.ElementRef<HostComponent<NativeProps>>) => void;
52
+ getPlaybackSpeed: (
53
+ viewRef: React.ElementRef<HostComponent<NativeProps>>
54
+ ) => void;
55
+ }
56
+
57
+ export const Commands = codegenNativeCommands<TPStreamsPlayerViewCommands>({
58
+ supportedCommands: [
59
+ 'play',
60
+ 'pause',
61
+ 'seekTo',
62
+ 'setPlaybackSpeed',
63
+ 'getCurrentPosition',
64
+ 'getDuration',
65
+ 'isPlaying',
66
+ 'getPlaybackSpeed',
67
+ ],
68
+ });
69
+
9
70
  export default codegenNativeComponent<NativeProps>('TPStreamsRNPlayerView');
package/src/index.tsx CHANGED
@@ -2,6 +2,9 @@ import { NativeModules } from 'react-native';
2
2
  export { default as TPStreamsPlayerView } from './TPStreamsPlayerViewNativeComponent';
3
3
  export * from './TPStreamsPlayerViewNativeComponent';
4
4
 
5
+ export { default as TPStreamsPlayer } from './TPStreamsPlayer';
6
+ export type { TPStreamsPlayerRef } from './TPStreamsPlayer';
7
+
5
8
  const TPStreamsModule = NativeModules.TPStreams;
6
9
 
7
10
  export const TPStreams = {