fix: remove setNativeProps usage (#3605)
				
					
				
			* fix: remove `setNativeProps` usage * code review
This commit is contained in:
		@@ -70,7 +70,6 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
 | 
			
		||||
    private static final String PROP_PREVENTS_DISPLAY_SLEEP_DURING_VIDEO_PLAYBACK = "preventsDisplaySleepDuringVideoPlayback";
 | 
			
		||||
    private static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval";
 | 
			
		||||
    private static final String PROP_REPORT_BANDWIDTH = "reportBandwidth";
 | 
			
		||||
    private static final String PROP_SEEK = "seek";
 | 
			
		||||
    private static final String PROP_RATE = "rate";
 | 
			
		||||
    private static final String PROP_MIN_LOAD_RETRY_COUNT = "minLoadRetryCount";
 | 
			
		||||
    private static final String PROP_MAXIMUM_BIT_RATE = "maxBitRate";
 | 
			
		||||
@@ -321,11 +320,6 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
 | 
			
		||||
        videoView.setReportBandwidth(reportBandwidth);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ReactProp(name = PROP_SEEK)
 | 
			
		||||
    public void setSeek(final ReactExoplayerView videoView, final float seek) {
 | 
			
		||||
        videoView.seekTo(Math.round(seek * 1000f));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ReactProp(name = PROP_RATE)
 | 
			
		||||
    public void setRate(final ReactExoplayerView videoView, final float rate) {
 | 
			
		||||
        videoView.setRateModifier(rate);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
package com.brentvatne.react;
 | 
			
		||||
 | 
			
		||||
import android.view.View;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
 | 
			
		||||
import com.brentvatne.exoplayer.ReactExoplayerView;
 | 
			
		||||
import com.facebook.react.bridge.ReactApplicationContext;
 | 
			
		||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
 | 
			
		||||
import com.facebook.react.bridge.ReactMethod;
 | 
			
		||||
import com.facebook.react.uimanager.UIManagerModule;
 | 
			
		||||
 | 
			
		||||
public class VideoManagerModule extends ReactContextBaseJavaModule {
 | 
			
		||||
    private static final String REACT_CLASS = "VideoManager";
 | 
			
		||||
 | 
			
		||||
    public VideoManagerModule(ReactApplicationContext reactContext) {
 | 
			
		||||
        super(reactContext);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getName() {
 | 
			
		||||
        return REACT_CLASS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ReactMethod
 | 
			
		||||
    public void setPlayerPauseState(Boolean paused, int reactTag) {
 | 
			
		||||
        UIManagerModule uiManager = getReactApplicationContext().getNativeModule(UIManagerModule.class);
 | 
			
		||||
        uiManager.prependUIBlock(manager -> {
 | 
			
		||||
            View view = manager.resolveView(reactTag);
 | 
			
		||||
 | 
			
		||||
            if (view instanceof ReactExoplayerView) {
 | 
			
		||||
                ReactExoplayerView videoView = (ReactExoplayerView) view;
 | 
			
		||||
                videoView.setPausedModifier(paused);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,59 @@
 | 
			
		||||
package com.brentvatne.react
 | 
			
		||||
 | 
			
		||||
import com.brentvatne.common.toolbox.ReactBridgeUtils
 | 
			
		||||
import com.brentvatne.exoplayer.ReactExoplayerView
 | 
			
		||||
import com.facebook.react.bridge.ReactApplicationContext
 | 
			
		||||
import com.facebook.react.bridge.ReactContextBaseJavaModule
 | 
			
		||||
import com.facebook.react.bridge.ReactMethod
 | 
			
		||||
import com.facebook.react.bridge.ReadableMap
 | 
			
		||||
import com.facebook.react.bridge.UiThreadUtil
 | 
			
		||||
import com.facebook.react.uimanager.UIManagerModule
 | 
			
		||||
import kotlin.math.roundToInt
 | 
			
		||||
 | 
			
		||||
class VideoManagerModule(reactContext: ReactApplicationContext?) : ReactContextBaseJavaModule(reactContext) {
 | 
			
		||||
    override fun getName(): String {
 | 
			
		||||
        return REACT_CLASS
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun performOnPlayerView(reactTag: Int, callback: (ReactExoplayerView?) -> Unit) {
 | 
			
		||||
        UiThreadUtil.runOnUiThread {
 | 
			
		||||
            val view = if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
 | 
			
		||||
                reactApplicationContext.fabricUIManager?.resolveView(
 | 
			
		||||
                    reactTag
 | 
			
		||||
                )
 | 
			
		||||
            } else {
 | 
			
		||||
                val uiManager = reactApplicationContext.getNativeModule(UIManagerModule::class.java)
 | 
			
		||||
                uiManager?.resolveView(reactTag)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (view is ReactExoplayerView) {
 | 
			
		||||
                callback(view)
 | 
			
		||||
            } else {
 | 
			
		||||
                callback(null)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ReactMethod
 | 
			
		||||
    fun setPlayerPauseState(paused: Boolean?, reactTag: Int) {
 | 
			
		||||
        performOnPlayerView(reactTag) {
 | 
			
		||||
            it?.setPausedModifier(paused!!)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ReactMethod
 | 
			
		||||
    fun seek(info: ReadableMap, reactTag: Int) {
 | 
			
		||||
        if (!info.hasKey("time")) {
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val time = ReactBridgeUtils.safeGetInt(info, "time")
 | 
			
		||||
        performOnPlayerView(reactTag) {
 | 
			
		||||
            it?.seekTo((time * 1000f).roundToInt().toLong())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        private const val REACT_CLASS = "VideoManager"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -28,7 +28,6 @@ RCT_EXPORT_VIEW_PROPERTY(pictureInPicture, BOOL);
 | 
			
		||||
RCT_EXPORT_VIEW_PROPERTY(ignoreSilentSwitch, NSString);
 | 
			
		||||
RCT_EXPORT_VIEW_PROPERTY(mixWithOthers, NSString);
 | 
			
		||||
RCT_EXPORT_VIEW_PROPERTY(rate, float);
 | 
			
		||||
RCT_EXPORT_VIEW_PROPERTY(seek, NSDictionary);
 | 
			
		||||
RCT_EXPORT_VIEW_PROPERTY(fullscreen, BOOL);
 | 
			
		||||
RCT_EXPORT_VIEW_PROPERTY(fullscreenAutorotate, BOOL);
 | 
			
		||||
RCT_EXPORT_VIEW_PROPERTY(fullscreenOrientation, NSString);
 | 
			
		||||
@@ -74,6 +73,8 @@ RCT_EXTERN_METHOD(save
 | 
			
		||||
                  : (RCTPromiseResolveBlock)resolve rejecter
 | 
			
		||||
                  : (RCTPromiseRejectBlock)reject)
 | 
			
		||||
 | 
			
		||||
RCT_EXTERN_METHOD(seek : (NSDictionary*)info reactTag : (nonnull NSNumber*)reactTag)
 | 
			
		||||
 | 
			
		||||
RCT_EXTERN_METHOD(setLicenseResult : (NSString*)license licenseUrl : (NSString*)licenseUrl reactTag : (nonnull NSNumber*)reactTag)
 | 
			
		||||
 | 
			
		||||
RCT_EXTERN_METHOD(setLicenseResultError : (NSString*)error licenseUrl : (NSString*)licenseUrl reactTag : (nonnull NSNumber*)reactTag)
 | 
			
		||||
 
 | 
			
		||||
@@ -11,77 +11,70 @@ class RCTVideoManager: RCTViewManager {
 | 
			
		||||
        return bridge.uiManager.methodQueue
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    func performOnVideoView(withReactTag reactTag: NSNumber, callback: @escaping (RCTVideo?) -> Void) {
 | 
			
		||||
        DispatchQueue.main.async { [weak self] in
 | 
			
		||||
            guard let self else {
 | 
			
		||||
                callback(nil)
 | 
			
		||||
                return
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            guard let view = self.bridge.uiManager.view(forReactTag: reactTag) as? RCTVideo else {
 | 
			
		||||
                RCTLogError("Invalid view returned from registry, expecting RCTVideo, got: \(String(describing: view))")
 | 
			
		||||
                callback(nil)
 | 
			
		||||
                return
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            callback(view)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @objc(save:reactTag:resolver:rejecter:)
 | 
			
		||||
    func save(options: NSDictionary, reactTag: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
 | 
			
		||||
        bridge.uiManager.prependUIBlock { _, viewRegistry in
 | 
			
		||||
            let view = viewRegistry?[reactTag]
 | 
			
		||||
            if !(view is RCTVideo) {
 | 
			
		||||
                RCTLogError("Invalid view returned from registry, expecting RCTVideo, got: %@", String(describing: view))
 | 
			
		||||
            } else if let view = view as? RCTVideo {
 | 
			
		||||
                view.save(options: options, resolve: resolve, reject: reject)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        performOnVideoView(withReactTag: reactTag, callback: { videoView in
 | 
			
		||||
            videoView?.save(options: options, resolve: resolve, reject: reject)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @objc(seek:reactTag:)
 | 
			
		||||
    func seek(info: NSDictionary, reactTag: NSNumber) {
 | 
			
		||||
        performOnVideoView(withReactTag: reactTag, callback: { videoView in
 | 
			
		||||
            videoView?.setSeek(info)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @objc(setLicenseResult:licenseUrl:reactTag:)
 | 
			
		||||
    func setLicenseResult(license: NSString, licenseUrl: NSString, reactTag: NSNumber) {
 | 
			
		||||
        bridge.uiManager.prependUIBlock { _, viewRegistry in
 | 
			
		||||
            let view = viewRegistry?[reactTag]
 | 
			
		||||
            if !(view is RCTVideo) {
 | 
			
		||||
                RCTLogError("Invalid view returned from registry, expecting RCTVideo, got: %@", String(describing: view))
 | 
			
		||||
            } else if let view = view as? RCTVideo {
 | 
			
		||||
                view.setLicenseResult(license as String, licenseUrl as String)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        performOnVideoView(withReactTag: reactTag, callback: { videoView in
 | 
			
		||||
            videoView?.setLicenseResult(license as String, licenseUrl as String)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @objc(setLicenseResultError:licenseUrl:reactTag:)
 | 
			
		||||
    func setLicenseResultError(error: NSString, licenseUrl: NSString, reactTag: NSNumber) {
 | 
			
		||||
        bridge.uiManager.prependUIBlock { _, viewRegistry in
 | 
			
		||||
            let view = viewRegistry?[reactTag]
 | 
			
		||||
            if !(view is RCTVideo) {
 | 
			
		||||
                RCTLogError("Invalid view returned from registry, expecting RCTVideo, got: %@", String(describing: view))
 | 
			
		||||
            } else if let view = view as? RCTVideo {
 | 
			
		||||
                view.setLicenseResultError(error as String, licenseUrl as String)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        performOnVideoView(withReactTag: reactTag, callback: { videoView in
 | 
			
		||||
            videoView?.setLicenseResultError(error as String, licenseUrl as String)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @objc(dismissFullscreenPlayer:)
 | 
			
		||||
    func dismissFullscreenPlayer(_ reactTag: NSNumber) {
 | 
			
		||||
        bridge.uiManager.prependUIBlock { _, viewRegistry in
 | 
			
		||||
            let view = viewRegistry?[reactTag]
 | 
			
		||||
            if !(view is RCTVideo) {
 | 
			
		||||
                RCTLogError("Invalid view returned from registry, expecting RCTVideo, got: %@", String(describing: view))
 | 
			
		||||
            } else if let view = view as? RCTVideo {
 | 
			
		||||
                view.dismissFullscreenPlayer()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        performOnVideoView(withReactTag: reactTag, callback: { videoView in
 | 
			
		||||
            videoView?.dismissFullscreenPlayer()
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @objc(presentFullscreenPlayer:)
 | 
			
		||||
    func presentFullscreenPlayer(_ reactTag: NSNumber) {
 | 
			
		||||
        bridge.uiManager.prependUIBlock { _, viewRegistry in
 | 
			
		||||
            let view = viewRegistry?[reactTag]
 | 
			
		||||
            if !(view is RCTVideo) {
 | 
			
		||||
                RCTLogError("Invalid view returned from registry, expecting RCTVideo, got: %@", String(describing: view))
 | 
			
		||||
            } else if let view = view as? RCTVideo {
 | 
			
		||||
                view.presentFullscreenPlayer()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        performOnVideoView(withReactTag: reactTag, callback: { videoView in
 | 
			
		||||
            videoView?.presentFullscreenPlayer()
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @objc(setPlayerPauseState:reactTag:)
 | 
			
		||||
    func setPlayerPauseState(paused: NSNumber, reactTag: NSNumber) {
 | 
			
		||||
        bridge.uiManager.prependUIBlock { _, viewRegistry in
 | 
			
		||||
            let view = viewRegistry?[reactTag]
 | 
			
		||||
            if !(view is RCTVideo) {
 | 
			
		||||
                RCTLogError("Invalid view returned from registry, expecting RCTVideo, got: %@", String(describing: view))
 | 
			
		||||
            } else if let view = view as? RCTVideo {
 | 
			
		||||
                let paused = paused.boolValue
 | 
			
		||||
                view.setPaused(paused)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        performOnVideoView(withReactTag: reactTag, callback: { videoView in
 | 
			
		||||
            videoView?.setPaused(paused.boolValue)
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override class func requiresMainQueueSetup() -> Bool {
 | 
			
		||||
 
 | 
			
		||||
@@ -227,19 +227,22 @@ const Video = forwardRef<VideoRef, ReactVideoProps>(
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const callSeekFunction = () => {
 | 
			
		||||
        VideoManager.seek(
 | 
			
		||||
          {
 | 
			
		||||
            time,
 | 
			
		||||
            tolerance: tolerance || 0,
 | 
			
		||||
          },
 | 
			
		||||
          getReactTag(nativeRef),
 | 
			
		||||
        );
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      Platform.select({
 | 
			
		||||
        ios: () => {
 | 
			
		||||
          nativeRef.current?.setNativeProps({
 | 
			
		||||
            seek: {
 | 
			
		||||
              time,
 | 
			
		||||
              tolerance: tolerance || 0,
 | 
			
		||||
            },
 | 
			
		||||
          });
 | 
			
		||||
        },
 | 
			
		||||
        ios: callSeekFunction,
 | 
			
		||||
        android: callSeekFunction,
 | 
			
		||||
        default: () => {
 | 
			
		||||
          nativeRef.current?.setNativeProps({
 | 
			
		||||
            seek: time,
 | 
			
		||||
          });
 | 
			
		||||
          // TODO: Implement VideoManager.seek for windows
 | 
			
		||||
          nativeRef.current?.setNativeProps({seek: time});
 | 
			
		||||
        },
 | 
			
		||||
      })();
 | 
			
		||||
    }, []);
 | 
			
		||||
 
 | 
			
		||||
@@ -537,6 +537,7 @@ export type VideoSaveData = {
 | 
			
		||||
 | 
			
		||||
export interface VideoManagerType {
 | 
			
		||||
  save: (option: object, reactTag: number) => Promise<VideoSaveData>;
 | 
			
		||||
  seek: (option: Seek, reactTag: number) => Promise<void>;
 | 
			
		||||
  setPlayerPauseState: (paused: boolean, reactTag: number) => Promise<void>;
 | 
			
		||||
  setLicenseResult: (
 | 
			
		||||
    result: string,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user