feat: add keepScreenAwake prop (#4700)

This commit is contained in:
Krzysztof Moch
2025-09-21 13:12:33 +02:00
committed by GitHub
parent 4052514cf2
commit 100aefc8d4
15 changed files with 100 additions and 0 deletions
+1
View File
@@ -52,6 +52,7 @@ export default App;
| `pictureInPicture` | `boolean` | No | `false` | Whether to enable and show the picture-in-picture (PiP) button in the native controls (if supported by the platform and controls are visible). |
| `autoEnterPictureInPicture` | `boolean` | No | `false` | Whether the video should automatically enter PiP mode when it starts playing and the app is backgrounded (behavior might vary by platform). |
| `resizeMode` | `'contain' \| 'cover' \| 'stretch' \| 'none'` | No | `'none'` | How the video should be resized to fit the view. |
| `keepScreenAwake` | `boolean` | No | `true` | Whether to keep the device screen awake while the video view is mounted. |
## Events
@@ -72,6 +72,12 @@ class HybridVideoViewViewManager(nitroId: Int): HybridVideoViewViewManagerSpec()
videoView.get()?.resizeMode = value
}
override var keepScreenAwake: Boolean
get() = videoView.get()?.keepScreenAwake == true
set(value) {
videoView.get()?.keepScreenAwake = value
}
// View callbacks
override var onPictureInPictureChange: ((Boolean) -> Unit)? = null
set(value) {
@@ -98,6 +98,12 @@ class VideoView @JvmOverloads constructor(
}
}
var keepScreenAwake: Boolean
get() = playerView.keepScreenOn
set(value) {
playerView.keepScreenOn = value
}
var events = object : VideoViewEvents {
override var onPictureInPictureChange: ((Boolean) -> Unit)? = {}
override var onFullscreenChange: ((Boolean) -> Unit)? = {}
@@ -119,6 +119,25 @@ class HybridVideoViewViewManager: HybridVideoViewViewManagerSpec {
}
}
var keepScreenAwake: Bool {
get {
guard let view else {
print(DEALOCATED_WARNING)
return false
}
return view.keepScreenAwake
}
set {
guard let view else {
print(DEALOCATED_WARNING)
return
}
view.keepScreenAwake = newValue
}
}
func enterFullscreen() throws {
guard let view else {
throw VideoViewError.viewIsDeallocated.error()
@@ -28,6 +28,19 @@ import AVKit
}
}
private var _keepScreenAwake: Bool = false
var keepScreenAwake: Bool {
get {
guard let player = player as? HybridVideoPlayer else { return false }
return player.player.preventsDisplaySleepDuringVideoPlayback
}
set {
guard let player = player as? HybridVideoPlayer else { return }
player.player.preventsDisplaySleepDuringVideoPlayback = newValue
_keepScreenAwake = newValue
}
}
var playerViewController: AVPlayerViewController? {
didSet {
guard let observer, let playerViewController else { return }
@@ -168,8 +181,18 @@ import AVKit
if newSuperview == nil {
PluginsRegistry.shared.notifyVideoViewDestroyed(view: self)
// We want to disable this when view is about to unmount
if keepScreenAwake {
keepScreenAwake = false
}
} else {
PluginsRegistry.shared.notifyVideoViewCreated(view: self)
// We want to restore keepScreenAwake after component remount
if _keepScreenAwake {
keepScreenAwake = true
}
}
}
@@ -90,6 +90,15 @@ namespace margelo::nitro::video {
static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JResizeMode> /* resizeMode */)>("setResizeMode");
method(_javaPart, JResizeMode::fromCpp(resizeMode));
}
bool JHybridVideoViewViewManagerSpec::getKeepScreenAwake() {
static const auto method = javaClassStatic()->getMethod<jboolean()>("getKeepScreenAwake");
auto __result = method(_javaPart);
return static_cast<bool>(__result);
}
void JHybridVideoViewViewManagerSpec::setKeepScreenAwake(bool keepScreenAwake) {
static const auto method = javaClassStatic()->getMethod<void(jboolean /* keepScreenAwake */)>("setKeepScreenAwake");
method(_javaPart, keepScreenAwake);
}
std::optional<std::function<void(bool /* isInPictureInPicture */)>> JHybridVideoViewViewManagerSpec::getOnPictureInPictureChange() {
static const auto method = javaClassStatic()->getMethod<jni::local_ref<JFunc_void_bool::javaobject>()>("getOnPictureInPictureChange_cxx");
auto __result = method(_javaPart);
@@ -59,6 +59,8 @@ namespace margelo::nitro::video {
void setAutoEnterPictureInPicture(bool autoEnterPictureInPicture) override;
ResizeMode getResizeMode() override;
void setResizeMode(ResizeMode resizeMode) override;
bool getKeepScreenAwake() override;
void setKeepScreenAwake(bool keepScreenAwake) override;
std::optional<std::function<void(bool /* isInPictureInPicture */)>> getOnPictureInPictureChange() override;
void setOnPictureInPictureChange(const std::optional<std::function<void(bool /* isInPictureInPicture */)>>& onPictureInPictureChange) override;
std::optional<std::function<void(bool /* fullscreen */)>> getOnFullscreenChange() override;
@@ -67,6 +67,12 @@ abstract class HybridVideoViewViewManagerSpec: HybridObject() {
@set:Keep
abstract var resizeMode: ResizeMode
@get:DoNotStrip
@get:Keep
@set:DoNotStrip
@set:Keep
abstract var keepScreenAwake: Boolean
abstract var onPictureInPictureChange: ((isInPictureInPicture: Boolean) -> Unit)?
private var onPictureInPictureChange_cxx: Func_void_bool?
@@ -92,6 +92,12 @@ namespace margelo::nitro::video {
inline void setResizeMode(ResizeMode resizeMode) noexcept override {
_swiftPart.setResizeMode(static_cast<int>(resizeMode));
}
inline bool getKeepScreenAwake() noexcept override {
return _swiftPart.getKeepScreenAwake();
}
inline void setKeepScreenAwake(bool keepScreenAwake) noexcept override {
_swiftPart.setKeepScreenAwake(std::forward<decltype(keepScreenAwake)>(keepScreenAwake));
}
inline std::optional<std::function<void(bool /* isInPictureInPicture */)>> getOnPictureInPictureChange() noexcept override {
auto __result = _swiftPart.getOnPictureInPictureChange();
return __result;
@@ -16,6 +16,7 @@ public protocol HybridVideoViewViewManagerSpec_protocol: HybridObject {
var pictureInPicture: Bool { get set }
var autoEnterPictureInPicture: Bool { get set }
var resizeMode: ResizeMode { get set }
var keepScreenAwake: Bool { get set }
var onPictureInPictureChange: ((_ isInPictureInPicture: Bool) -> Void)? { get set }
var onFullscreenChange: ((_ fullscreen: Bool) -> Void)? { get set }
var willEnterFullscreen: (() -> Void)? { get set }
@@ -180,6 +180,17 @@ open class HybridVideoViewViewManagerSpec_cxx {
}
}
public final var keepScreenAwake: Bool {
@inline(__always)
get {
return self.__implementation.keepScreenAwake
}
@inline(__always)
set {
self.__implementation.keepScreenAwake = newValue
}
}
public final var onPictureInPictureChange: bridge.std__optional_std__function_void_bool____isInPictureInPicture______ {
@inline(__always)
get {
@@ -24,6 +24,8 @@ namespace margelo::nitro::video {
prototype.registerHybridSetter("autoEnterPictureInPicture", &HybridVideoViewViewManagerSpec::setAutoEnterPictureInPicture);
prototype.registerHybridGetter("resizeMode", &HybridVideoViewViewManagerSpec::getResizeMode);
prototype.registerHybridSetter("resizeMode", &HybridVideoViewViewManagerSpec::setResizeMode);
prototype.registerHybridGetter("keepScreenAwake", &HybridVideoViewViewManagerSpec::getKeepScreenAwake);
prototype.registerHybridSetter("keepScreenAwake", &HybridVideoViewViewManagerSpec::setKeepScreenAwake);
prototype.registerHybridGetter("onPictureInPictureChange", &HybridVideoViewViewManagerSpec::getOnPictureInPictureChange);
prototype.registerHybridSetter("onPictureInPictureChange", &HybridVideoViewViewManagerSpec::setOnPictureInPictureChange);
prototype.registerHybridGetter("onFullscreenChange", &HybridVideoViewViewManagerSpec::getOnFullscreenChange);
@@ -61,6 +61,8 @@ namespace margelo::nitro::video {
virtual void setAutoEnterPictureInPicture(bool autoEnterPictureInPicture) = 0;
virtual ResizeMode getResizeMode() = 0;
virtual void setResizeMode(ResizeMode resizeMode) = 0;
virtual bool getKeepScreenAwake() = 0;
virtual void setKeepScreenAwake(bool keepScreenAwake) = 0;
virtual std::optional<std::function<void(bool /* isInPictureInPicture */)>> getOnPictureInPictureChange() = 0;
virtual void setOnPictureInPictureChange(const std::optional<std::function<void(bool /* isInPictureInPicture */)>>& onPictureInPictureChange) = 0;
virtual std::optional<std::function<void(bool /* fullscreen */)>> getOnFullscreenChange() = 0;
@@ -40,6 +40,10 @@ export interface VideoViewProps extends Partial<VideoViewEvents>, ViewProps {
* - 'none': Do not resize the video
*/
resizeMode?: ResizeMode;
/**
* Whether to keep the screen awake while the video view is mounted. Defaults to true.
*/
keepScreenAwake?: boolean;
}
export interface VideoViewRef {
@@ -99,6 +103,7 @@ const updateProps = (manager: VideoViewViewManager, props: VideoViewProps) => {
manager.willExitFullscreen = props.willExitFullscreen;
manager.willEnterPictureInPicture = props.willEnterPictureInPicture;
manager.willExitPictureInPicture = props.willExitPictureInPicture;
manager.keepScreenAwake = props.keepScreenAwake ?? true;
};
/**
@@ -17,6 +17,7 @@ export interface VideoViewViewManager
enterPictureInPicture(): void;
exitPictureInPicture(): void;
canEnterPictureInPicture(): boolean;
keepScreenAwake: boolean;
}
// @internal