@@ -45,6 +45,7 @@ import { PieceDisplayStyle } from '../../../lib/collections/RundownLayouts'
45
45
import RundownViewEventBus , {
46
46
RundownViewEvents ,
47
47
RevealInShelfEvent ,
48
+ ToggleShelfDropzoneEvent ,
48
49
} from '../../../lib/api/triggers/RundownViewEventBus'
49
50
import { setShelfContextMenuContext , ContextType } from './ShelfContextMenu'
50
51
import { translateMessage } from '@sofie-automation/corelib/dist/TranslatableMessage'
@@ -180,6 +181,7 @@ const bucketTarget = {
180
181
181
182
interface IState {
182
183
dropActive : boolean
184
+ dropFrameActive : string | null
183
185
bucketName : string
184
186
adLibPieces : BucketAdLibItem [ ]
185
187
singleClickMode : boolean
@@ -246,6 +248,7 @@ export interface IBucketPanelProps {
246
248
onSelectAdlib : ( piece : any ) => void // TODO - fix this
247
249
onAdLibContext : ( args : { contextBucket : Bucket ; contextBucketAdLib : BucketAdLibItem } , callback : ( ) => void ) => void
248
250
onPieceNameRename : ( ) => void
251
+ extFrameDropZones : { _id : string ; url : string } [ ]
249
252
}
250
253
251
254
export interface IBucketPanelTrackedProps extends IDashboardPanelTrackedProps {
@@ -408,6 +411,7 @@ const BucketPanelContent = withTranslation()(
408
411
409
412
this . state = {
410
413
dropActive : false ,
414
+ dropFrameActive : null ,
411
415
bucketName : props . bucket . name ,
412
416
adLibPieces : props . adLibPieces . slice ( ) ,
413
417
singleClickMode : false ,
@@ -419,6 +423,7 @@ const BucketPanelContent = withTranslation()(
419
423
window . addEventListener ( MOSEvents . dragleave , this . onDragLeave )
420
424
421
425
RundownViewEventBus . on ( RundownViewEvents . REVEAL_IN_SHELF , this . onRevealInShelf )
426
+ RundownViewEventBus . on ( RundownViewEvents . TOGGLE_SHELF_DROPZONE , this . onToggleDropFrame )
422
427
}
423
428
424
429
componentDidUpdate ( prevProps : IBucketPanelProps & IBucketPanelTrackedProps ) {
@@ -434,6 +439,7 @@ const BucketPanelContent = withTranslation()(
434
439
componentWillUnmount ( ) : void {
435
440
window . removeEventListener ( MOSEvents . dragenter , this . onDragEnter )
436
441
window . removeEventListener ( MOSEvents . dragleave , this . onDragLeave )
442
+ RundownViewEventBus . removeListener ( RundownViewEvents . TOGGLE_SHELF_DROPZONE , this . onToggleDropFrame )
437
443
}
438
444
439
445
onRevealInShelf = ( e : RevealInShelfEvent ) => {
@@ -789,6 +795,13 @@ const BucketPanelContent = withTranslation()(
789
795
)
790
796
}
791
797
798
+ private onToggleDropFrame = ( e : ToggleShelfDropzoneEvent ) => {
799
+ this . setState ( {
800
+ // dropActive: e.display,
801
+ dropFrameActive : e . display ? e . id : null ,
802
+ } )
803
+ }
804
+
792
805
render ( ) : JSX . Element | null {
793
806
const { connectDragSource, connectDragPreview, connectDropTarget } = this . props
794
807
@@ -828,7 +841,8 @@ const BucketPanelContent = withTranslation()(
828
841
< div
829
842
className = { ClassNames ( 'dashboard-panel' , 'dashboard-panel__panel--bucket' , {
830
843
'dashboard-panel__panel--bucket-active' : this . state . dropActive ,
831
- 'dashboard-panel__panel--sort-dragging' : this . props . isDragging ,
844
+ 'dashboard-panel__panel--sort-dragging' :
845
+ ( this . props . isDragging || this . state . dropFrameActive ) && ! this . state . dropActive ,
832
846
} ) }
833
847
data-bucket-id = { this . props . bucket . _id }
834
848
ref = { this . setRef }
@@ -906,6 +920,18 @@ const BucketPanelContent = withTranslation()(
906
920
</ BucketPieceButton >
907
921
</ ContextMenuTrigger >
908
922
) ) }
923
+ { this . props . extFrameDropZones . map ( ( dropZone ) => (
924
+ < DropzoneHolder
925
+ key = { dropZone . _id }
926
+ bucketId = { this . props . bucket . _id }
927
+ id = { dropZone . _id }
928
+ url = { dropZone . url }
929
+ hidden = { this . state . dropFrameActive !== dropZone . _id }
930
+ showStyleBaseId = { this . props . showStyleBaseId }
931
+ onDragEnter = { this . onDragEnter }
932
+ onDragLeave = { this . onDragLeave }
933
+ />
934
+ ) ) }
909
935
</ div >
910
936
</ div >
911
937
)
@@ -917,3 +943,88 @@ const BucketPanelContent = withTranslation()(
917
943
)
918
944
)
919
945
)
946
+
947
+ interface DropzoneHolderProps {
948
+ id : string
949
+ bucketId : BucketId
950
+ url : string
951
+ hidden : boolean
952
+ showStyleBaseId : ShowStyleBaseId
953
+
954
+ onDragEnter ?: ( ) => void
955
+ onDragLeave ?: ( ) => void
956
+ }
957
+ const DropzoneHolder = ( props : DropzoneHolderProps ) => {
958
+ const [ dropzoneElementRef , setDropzoneElementRef ] = React . useState < HTMLIFrameElement | null > ( null )
959
+
960
+ const onMessage = React . useCallback (
961
+ ( event : MessageEvent ) => {
962
+ // filter out messages from this panel
963
+ if ( event . source !== dropzoneElementRef ?. contentWindow ) return
964
+
965
+ switch ( event . data ?. event ) {
966
+ case 'drop' :
967
+ RundownViewEventBus . emit ( RundownViewEvents . ITEM_DROPPED , {
968
+ id : props . id ,
969
+ bucketId : props . bucketId ,
970
+ ev : event ,
971
+ } )
972
+ if ( props . onDragLeave ) props . onDragLeave ( )
973
+ break
974
+ case 'data' :
975
+ if ( event . data . data . trim ( ) . endsWith ( '</mos>' ) ) {
976
+ RundownViewEventBus . emit ( RundownViewEvents . ITEM_DROPPED , {
977
+ id : props . id ,
978
+ bucketId : props . bucketId ,
979
+ message : event . data . data ,
980
+ ev : event ,
981
+ } )
982
+ }
983
+ break
984
+ case 'error' :
985
+ RundownViewEventBus . emit ( RundownViewEvents . ITEM_DROPPED , {
986
+ id : props . id ,
987
+ bucketId : props . bucketId ,
988
+ error : event . data . message ,
989
+ ev : event ,
990
+ } )
991
+ break
992
+ case 'dragEnter' :
993
+ if ( props . onDragEnter ) props . onDragEnter ( )
994
+ break
995
+ case 'dragLeave' :
996
+ if ( props . onDragLeave ) props . onDragLeave ( )
997
+ break
998
+ }
999
+ } ,
1000
+ [ dropzoneElementRef , props . onDragEnter , props . onDragLeave ]
1001
+ )
1002
+
1003
+ React . useEffect ( ( ) => {
1004
+ if ( ! dropzoneElementRef ) return
1005
+
1006
+ const registerHandlers = ( ) => {
1007
+ window . addEventListener ( 'message' , onMessage )
1008
+ }
1009
+ const unregisterHandlers = ( ) => {
1010
+ window . removeEventListener ( 'message' , onMessage )
1011
+ }
1012
+
1013
+ registerHandlers ( )
1014
+
1015
+ return ( ) => {
1016
+ unregisterHandlers ( )
1017
+ }
1018
+ } , [ dropzoneElementRef , onMessage ] )
1019
+
1020
+ return (
1021
+ < div className = "dropzone-panel" style = { { visibility : props . hidden ? 'hidden' : 'visible' } } >
1022
+ < iframe
1023
+ ref = { setDropzoneElementRef }
1024
+ className = "external-frame-panel__iframe"
1025
+ src = { props . url }
1026
+ sandbox = "allow-forms allow-popups allow-scripts allow-same-origin"
1027
+ > </ iframe >
1028
+ </ div >
1029
+ )
1030
+ }
0 commit comments