import React, { Suspense, lazy } from "react"; import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget"; import { WidgetType } from "constants/WidgetConstants"; import { EventType } from "constants/ActionConstants"; import { VALIDATION_TYPES } from "constants/WidgetValidation"; import { WidgetPropertyValidationType, BASE_WIDGET_VALIDATION, } from "utils/WidgetValidation"; import Skeleton from "components/utils/Skeleton"; import * as Sentry from "@sentry/react"; import { retryPromise } from "utils/AppsmithUtils"; import ReactPlayer from "react-player"; import withMeta, { WithMeta } from "./MetaHOC"; const VideoComponent = lazy(() => retryPromise(() => import("components/designSystems/appsmith/VideoComponent"), ), ); export enum PlayState { NOT_STARTED = "NOT_STARTED", PAUSED = "PAUSED", ENDED = "ENDED", PLAYING = "PLAYING", } class VideoWidget extends BaseWidget { static getPropertyPaneConfig() { return [ { sectionName: "General", children: [ { propertyName: "url", label: "URL", controlType: "INPUT_TEXT", placeholderText: "Enter url", inputType: "TEXT", isBindProperty: true, isTriggerProperty: false, }, { propertyName: "autoPlay", label: "Auto Play", helpText: "Video will be automatically played", controlType: "SWITCH", isJSConvertible: true, isBindProperty: true, isTriggerProperty: false, }, { helpText: "Controls the visibility of the widget", propertyName: "isVisible", label: "Visible", controlType: "SWITCH", isJSConvertible: true, isBindProperty: true, isTriggerProperty: false, }, ], }, { sectionName: "Actions", children: [ { helpText: "Triggers an action when the video is played", propertyName: "onPlay", label: "onPlay", controlType: "ACTION_SELECTOR", isJSConvertible: true, isBindProperty: true, isTriggerProperty: true, }, { helpText: "Triggers an action when the video is paused", propertyName: "onPause", label: "onPause", controlType: "ACTION_SELECTOR", isJSConvertible: true, isBindProperty: true, isTriggerProperty: true, }, { helpText: "Triggers an action when the video ends", propertyName: "onEnd", label: "onEnd", controlType: "ACTION_SELECTOR", isJSConvertible: true, isBindProperty: true, isTriggerProperty: true, }, ], }, ]; } private _player = React.createRef(); static getPropertyValidationMap(): WidgetPropertyValidationType { return { ...BASE_WIDGET_VALIDATION, url: VALIDATION_TYPES.TEXT, }; } static getMetaPropertiesMap(): Record { return { playState: PlayState.NOT_STARTED, }; } static getDefaultPropertiesMap(): Record { return {}; } shouldComponentUpdate(nextProps: VideoWidgetProps) { return nextProps.url !== this.props.url; } getPageView() { const { url, autoPlay, onEnd, onPause, onPlay } = this.props; return ( }> { this.props.updateWidgetMetaProperty( "playState", PlayState.PLAYING, { dynamicString: onPlay, event: { type: EventType.ON_VIDEO_PLAY, }, }, ); }} onPause={() => { //TODO: We do not want the pause event for onSeek or onEnd. this.props.updateWidgetMetaProperty("playState", PlayState.PAUSED, { dynamicString: onPause, event: { type: EventType.ON_VIDEO_PAUSE, }, }); }} onEnded={() => { this.props.updateWidgetMetaProperty("playState", PlayState.ENDED, { dynamicString: onEnd, event: { type: EventType.ON_VIDEO_END, }, }); }} /> ); } getWidgetType(): WidgetType { return "VIDEO_WIDGET"; } } export interface VideoWidgetProps extends WidgetProps, WithMeta { url: string; autoPlay: boolean; onPause?: string; onPlay?: string; onEnd?: string; } export default VideoWidget; export const ProfiledVideoWidget = Sentry.withProfiler(withMeta(VideoWidget));