@@ -47,6 +47,7 @@ import { PieceDisplayStyle } from '../../../lib/collections/RundownLayouts'
4747import RundownViewEventBus , {
4848 RundownViewEvents ,
4949 RevealInShelfEvent ,
50+ ToggleShelfDropzoneEvent ,
5051} from '../../../lib/api/triggers/RundownViewEventBus'
5152import { setShelfContextMenuContext , ContextType } from './ShelfContextMenu'
5253import { translateMessage } from '@sofie-automation/corelib/dist/TranslatableMessage'
@@ -178,6 +179,7 @@ const bucketTarget = {
178179
179180interface IState {
180181 dropActive : boolean
182+ dropFrameActive : string | null
181183 bucketName : string
182184 adLibPieces : BucketAdLibItem [ ]
183185 singleClickMode : boolean
@@ -244,6 +246,7 @@ export interface IBucketPanelProps {
244246 onSelectAdlib
245247 onAdLibContext : ( args : { contextBucket : Bucket ; contextBucketAdLib : BucketAdLibItem } , callback : ( ) => void ) => void
246248 onPieceNameRename : ( ) => void
249+ extFrameDropZones : { _id : string ; url : string } [ ]
247250}
248251
249252export interface IBucketPanelTrackedProps extends IDashboardPanelTrackedProps {
@@ -378,6 +381,7 @@ export const BucketPanel = translateWithTracker<Translated<IBucketPanelProps>, I
378381
379382 this . state = {
380383 dropActive : false ,
384+ dropFrameActive : null ,
381385 bucketName : props . bucket . name ,
382386 adLibPieces : props . adLibPieces . slice ( ) ,
383387 singleClickMode : false ,
@@ -419,6 +423,7 @@ export const BucketPanel = translateWithTracker<Translated<IBucketPanelProps>, I
419423 window . addEventListener ( MOSEvents . dragleave , this . onDragLeave )
420424
421425 RundownViewEventBus . on ( RundownViewEvents . REVEAL_IN_SHELF , this . onRevealInShelf )
426+ RundownViewEventBus . on ( RundownViewEvents . TOGGLE_SHELF_DROPZONE , this . onToggleDropFrame )
422427 }
423428
424429 componentDidUpdate ( prevProps : IBucketPanelProps & IBucketPanelTrackedProps ) {
@@ -436,6 +441,7 @@ export const BucketPanel = translateWithTracker<Translated<IBucketPanelProps>, I
436441
437442 window . removeEventListener ( MOSEvents . dragenter , this . onDragEnter )
438443 window . removeEventListener ( MOSEvents . dragleave , this . onDragLeave )
444+ RundownViewEventBus . removeListener ( RundownViewEvents . TOGGLE_SHELF_DROPZONE , this . onToggleDropFrame )
439445 }
440446
441447 onRevealInShelf = ( e : RevealInShelfEvent ) => {
@@ -791,6 +797,13 @@ export const BucketPanel = translateWithTracker<Translated<IBucketPanelProps>, I
791797 )
792798 }
793799
800+ private onToggleDropFrame = ( e : ToggleShelfDropzoneEvent ) => {
801+ this . setState ( {
802+ // dropActive: e.display,
803+ dropFrameActive : e . display ? e . id : null ,
804+ } )
805+ }
806+
794807 render ( ) : JSX . Element | null {
795808 const { connectDragSource, connectDragPreview, connectDropTarget } = this . props
796809
@@ -830,7 +843,8 @@ export const BucketPanel = translateWithTracker<Translated<IBucketPanelProps>, I
830843 < div
831844 className = { ClassNames ( 'dashboard-panel' , 'dashboard-panel__panel--bucket' , {
832845 'dashboard-panel__panel--bucket-active' : this . state . dropActive ,
833- 'dashboard-panel__panel--sort-dragging' : this . props . isDragging ,
846+ 'dashboard-panel__panel--sort-dragging' :
847+ ( this . props . isDragging || this . state . dropFrameActive ) && ! this . state . dropActive ,
834848 } ) }
835849 data-bucket-id = { this . props . bucket . _id }
836850 ref = { this . setRef }
@@ -908,6 +922,18 @@ export const BucketPanel = translateWithTracker<Translated<IBucketPanelProps>, I
908922 </ BucketPieceButton >
909923 </ ContextMenuTrigger >
910924 ) ) }
925+ { this . props . extFrameDropZones . map ( ( dropZone ) => (
926+ < DropzoneHolder
927+ key = { dropZone . _id }
928+ bucketId = { this . props . bucket . _id }
929+ id = { dropZone . _id }
930+ url = { dropZone . url }
931+ hidden = { this . state . dropFrameActive !== dropZone . _id }
932+ showStyleBaseId = { this . props . showStyleBaseId }
933+ onDragEnter = { this . onDragEnter }
934+ onDragLeave = { this . onDragLeave }
935+ />
936+ ) ) }
911937 </ div >
912938 </ div >
913939 )
@@ -919,3 +945,88 @@ export const BucketPanel = translateWithTracker<Translated<IBucketPanelProps>, I
919945 )
920946 )
921947)
948+
949+ interface DropzoneHolderProps {
950+ id : string
951+ bucketId : BucketId
952+ url : string
953+ hidden : boolean
954+ showStyleBaseId : ShowStyleBaseId
955+
956+ onDragEnter ?: ( ) => void
957+ onDragLeave ?: ( ) => void
958+ }
959+ const DropzoneHolder = ( props : DropzoneHolderProps ) => {
960+ const [ dropzoneElementRef , setDropzoneElementRef ] = React . useState < HTMLIFrameElement | null > ( null )
961+
962+ const onMessage = React . useCallback (
963+ ( event : MessageEvent ) => {
964+ // filter out messages from this panel
965+ if ( event . source !== dropzoneElementRef ?. contentWindow ) return
966+
967+ switch ( event . data ?. event ) {
968+ case 'drop' :
969+ RundownViewEventBus . emit ( RundownViewEvents . ITEM_DROPPED , {
970+ id : props . id ,
971+ bucketId : props . bucketId ,
972+ ev : event ,
973+ } )
974+ if ( props . onDragLeave ) props . onDragLeave ( )
975+ break
976+ case 'data' :
977+ if ( event . data . data . trim ( ) . endsWith ( '</mos>' ) ) {
978+ RundownViewEventBus . emit ( RundownViewEvents . ITEM_DROPPED , {
979+ id : props . id ,
980+ bucketId : props . bucketId ,
981+ message : event . data . data ,
982+ ev : event ,
983+ } )
984+ }
985+ break
986+ case 'error' :
987+ RundownViewEventBus . emit ( RundownViewEvents . ITEM_DROPPED , {
988+ id : props . id ,
989+ bucketId : props . bucketId ,
990+ error : event . data . message ,
991+ ev : event ,
992+ } )
993+ break
994+ case 'dragEnter' :
995+ if ( props . onDragEnter ) props . onDragEnter ( )
996+ break
997+ case 'dragLeave' :
998+ if ( props . onDragLeave ) props . onDragLeave ( )
999+ break
1000+ }
1001+ } ,
1002+ [ dropzoneElementRef , props . onDragEnter , props . onDragLeave ]
1003+ )
1004+
1005+ React . useEffect ( ( ) => {
1006+ if ( ! dropzoneElementRef ) return
1007+
1008+ const registerHandlers = ( ) => {
1009+ window . addEventListener ( 'message' , onMessage )
1010+ }
1011+ const unregisterHandlers = ( ) => {
1012+ window . removeEventListener ( 'message' , onMessage )
1013+ }
1014+
1015+ registerHandlers ( )
1016+
1017+ return ( ) => {
1018+ unregisterHandlers ( )
1019+ }
1020+ } , [ dropzoneElementRef , onMessage ] )
1021+
1022+ return (
1023+ < div className = "dropzone-panel" style = { { visibility : props . hidden ? 'hidden' : 'visible' } } >
1024+ < iframe
1025+ ref = { setDropzoneElementRef }
1026+ className = "external-frame-panel__iframe"
1027+ src = { props . url }
1028+ sandbox = "allow-forms allow-popups allow-scripts allow-same-origin"
1029+ > </ iframe >
1030+ </ div >
1031+ )
1032+ }
0 commit comments