Skip to content

Commit

Permalink
fix: remove setNativeProps usage (#3605)
Browse files Browse the repository at this point in the history
* fix: remove `setNativeProps` usage

* code review
  • Loading branch information
KrzysztofMoch authored Mar 28, 2024
1 parent 38746ff commit 0312afc
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -321,11 +320,6 @@ public void setReportBandwidth(final ReactExoplayerView videoView, final boolean
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);
Expand Down
38 changes: 0 additions & 38 deletions android/src/main/java/com/brentvatne/react/VideoManagerModule.java

This file was deleted.

59 changes: 59 additions & 0 deletions android/src/main/java/com/brentvatne/react/VideoManagerModule.kt
Original file line number Diff line number Diff line change
@@ -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"
}
}
3 changes: 2 additions & 1 deletion ios/Video/RCTVideoManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ @interface RCT_EXTERN_MODULE (RCTVideoManager, RCTViewManager)
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);
Expand Down Expand Up @@ -74,6 +73,8 @@ @interface RCT_EXTERN_MODULE (RCTVideoManager, RCTViewManager)
: (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)
Expand Down
91 changes: 42 additions & 49 deletions ios/Video/RCTVideoManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,77 +11,70 @@ class RCTVideoManager: RCTViewManager {
return bridge.uiManager.methodQueue
}

@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)
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) {
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 {
Expand Down
25 changes: 14 additions & 11 deletions src/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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});
},
})();
}, []);
Expand Down
1 change: 1 addition & 0 deletions src/specs/VideoNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 0312afc

Please sign in to comment.