Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: remove setNativeProps usage #3605

Merged
merged 2 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading