@blaze-cms/react-page-builder 0.146.0-alpha.13 → 0.146.0-alpha.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/lib/components/MenuItem/MenuEntitiesItem.js +1 -0
  3. package/lib/components/MenuItem/MenuEntitiesItem.js.map +1 -1
  4. package/lib/components/Video/Video.js +2 -1
  5. package/lib/components/Video/Video.js.map +1 -1
  6. package/lib/components/Video/VideoContext.js +12 -0
  7. package/lib/components/Video/VideoContext.js.map +1 -0
  8. package/lib/components/Video/VideoRender.js +36 -3
  9. package/lib/components/Video/VideoRender.js.map +1 -1
  10. package/lib/components/Video/constants.js +14 -0
  11. package/lib/components/Video/constants.js.map +1 -0
  12. package/lib/components/Video/helpers/emit-gtm-event.js +31 -0
  13. package/lib/components/Video/helpers/emit-gtm-event.js.map +1 -0
  14. package/lib/components/Video/providers/JWPlayer/JWPlayerController.js +28 -8
  15. package/lib/components/Video/providers/JWPlayer/JWPlayerController.js.map +1 -1
  16. package/lib/components/Video/providers/JWPlayer/JWPlayerProvider.js +16 -4
  17. package/lib/components/Video/providers/JWPlayer/JWPlayerProvider.js.map +1 -1
  18. package/lib/components/Video/providers/YouTube/YoutubeEmbeded.js +55 -0
  19. package/lib/components/Video/providers/YouTube/YoutubeEmbeded.js.map +1 -1
  20. package/lib-es/components/MenuItem/MenuEntitiesItem.js +1 -0
  21. package/lib-es/components/MenuItem/MenuEntitiesItem.js.map +1 -1
  22. package/lib-es/components/Video/Video.js +2 -1
  23. package/lib-es/components/Video/Video.js.map +1 -1
  24. package/lib-es/components/Video/VideoContext.js +6 -0
  25. package/lib-es/components/Video/VideoContext.js.map +1 -0
  26. package/lib-es/components/Video/VideoRender.js +28 -3
  27. package/lib-es/components/Video/VideoRender.js.map +1 -1
  28. package/lib-es/components/Video/constants.js +7 -0
  29. package/lib-es/components/Video/constants.js.map +1 -0
  30. package/lib-es/components/Video/helpers/emit-gtm-event.js +25 -0
  31. package/lib-es/components/Video/helpers/emit-gtm-event.js.map +1 -0
  32. package/lib-es/components/Video/providers/JWPlayer/JWPlayerController.js +28 -4
  33. package/lib-es/components/Video/providers/JWPlayer/JWPlayerController.js.map +1 -1
  34. package/lib-es/components/Video/providers/JWPlayer/JWPlayerProvider.js +10 -4
  35. package/lib-es/components/Video/providers/JWPlayer/JWPlayerProvider.js.map +1 -1
  36. package/lib-es/components/Video/providers/YouTube/YoutubeEmbeded.js +58 -2
  37. package/lib-es/components/Video/providers/YouTube/YoutubeEmbeded.js.map +1 -1
  38. package/package.json +2 -2
  39. package/src/components/MenuItem/MenuEntitiesItem.js +2 -0
  40. package/src/components/Video/Video.js +1 -1
  41. package/src/components/Video/VideoContext.js +7 -0
  42. package/src/components/Video/VideoRender.js +28 -3
  43. package/src/components/Video/constants.js +6 -0
  44. package/src/components/Video/helpers/emit-gtm-event.js +25 -0
  45. package/src/components/Video/providers/JWPlayer/JWPlayerController.js +21 -4
  46. package/src/components/Video/providers/JWPlayer/JWPlayerProvider.js +7 -5
  47. package/src/components/Video/providers/YouTube/YoutubeEmbeded.js +63 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blaze-cms/react-page-builder",
3
- "version": "0.146.0-alpha.13",
3
+ "version": "0.146.0-alpha.15",
4
4
  "description": "Blaze react page builder",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib-es/index.js",
@@ -90,5 +90,5 @@
90
90
  "lib/*",
91
91
  "lib-es/*"
92
92
  ],
93
- "gitHead": "169de01b9b9e3f4ea64ac0b4b14a846ebdb02021"
93
+ "gitHead": "127d2d79d4908d1456fe83639fe606236114d60a"
94
94
  }
@@ -134,6 +134,8 @@ const MenuEntitiesItem = ({ entities, parent, ...props }) => {
134
134
  filterOperator
135
135
  });
136
136
 
137
+ variables.limit = props.limit || undefined;
138
+
137
139
  const hasNoItemsToDisplayOrFilter = !updatedItemsToDisplay.length && !updatedFilterBy;
138
140
 
139
141
  const { data = {} } = useQuery(action, {
@@ -43,7 +43,7 @@ const Video = ({
43
43
  });
44
44
 
45
45
  return (
46
- <Wrapper className="video" modifiers={modifiers}>
46
+ <Wrapper className="video" modifiers={modifiers} key={url}>
47
47
  {playInModal ? (
48
48
  <VideoModal
49
49
  url={url}
@@ -0,0 +1,7 @@
1
+ import { createContext } from 'react';
2
+
3
+ const VideoContext = createContext({});
4
+ const VideoContextProvider = VideoContext.Provider;
5
+ const VideoContextConsumer = VideoContext.Consumer;
6
+
7
+ export { VideoContext, VideoContextProvider, VideoContextConsumer };
@@ -1,15 +1,40 @@
1
- import React from 'react';
1
+ import React, { useRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import getProvider from './providers';
4
4
  import { withTitle } from '../../HOC';
5
+ import { VideoContextProvider } from './VideoContext';
6
+ import emitGtmEvent from './helpers/emit-gtm-event';
5
7
 
6
8
  const VideoRender = ({ provider, ...props }) => {
9
+ const ref = useRef(0);
7
10
  const Provider = getProvider(provider);
8
- return <Provider {...props} />;
11
+ const { gtmEventName: propEventName } = props;
12
+ const gtmEventName = propEventName || process.env.BLAZE_VIDEO_EVENT_NAME;
13
+ const emitEvent = gtmEventName
14
+ ? ({ action, videoId }) =>
15
+ emitGtmEvent({
16
+ gtmEventName,
17
+ provider,
18
+ action,
19
+ videoId,
20
+ playCounter: ref
21
+ })
22
+ : null;
23
+
24
+ return (
25
+ <VideoContextProvider value={{ emitEvent }}>
26
+ <Provider {...props} />
27
+ </VideoContextProvider>
28
+ );
9
29
  };
10
30
 
11
31
  VideoRender.propTypes = {
12
- provider: PropTypes.string.isRequired
32
+ provider: PropTypes.string.isRequired,
33
+ gtmEventName: PropTypes.string
34
+ };
35
+
36
+ VideoRender.defaultProps = {
37
+ gtmEventName: ''
13
38
  };
14
39
 
15
40
  export default withTitle(VideoRender);
@@ -0,0 +1,6 @@
1
+ export const EVENT_ACTIONS = {
2
+ START: 'start',
3
+ PLAYING: 'playing',
4
+ PAUSED: 'paused',
5
+ ENDED: 'ended'
6
+ };
@@ -0,0 +1,25 @@
1
+ import { EVENT_ACTIONS } from '../constants';
2
+
3
+ const emitGtmEvent = ({ gtmEventName, provider, action, videoId, playCounter }) => {
4
+ if (!window.dataLayer || !action) return;
5
+
6
+ const actionToUse =
7
+ action === EVENT_ACTIONS.PLAYING && playCounter.current < 1 ? EVENT_ACTIONS.START : action;
8
+
9
+ if (action === EVENT_ACTIONS.PLAYING) {
10
+ // eslint-disable-next-line no-param-reassign
11
+ playCounter.current += 1;
12
+ }
13
+
14
+ const playCount = playCounter.current;
15
+
16
+ window.dataLayer.push({
17
+ event: gtmEventName,
18
+ video_action: actionToUse,
19
+ video_provider: provider,
20
+ video_id: videoId,
21
+ video_play_count: playCount
22
+ });
23
+ };
24
+
25
+ export default emitGtmEvent;
@@ -2,10 +2,13 @@
2
2
  Custom controller to extend and scale the 'react-jw-player' library for future updates.
3
3
  */
4
4
 
5
+ import { EVENT_ACTIONS } from '../../constants';
6
+
5
7
  class JWPlayerController {
6
- constructor() {
8
+ constructor({ emitEvent }) {
7
9
  this.player = null;
8
10
  this.error = null;
11
+ this.emitEvent = emitEvent;
9
12
  }
10
13
 
11
14
  setPlayer = player => {
@@ -24,11 +27,25 @@ class JWPlayerController {
24
27
  this.error = message;
25
28
  };
26
29
 
27
- onComplete = event => {};
30
+ doEmitEvent = action => {
31
+ const { emitEvent } = this;
32
+ if (emitEvent) {
33
+ const { mediaid: videoId } = this.player.getPlaylistItem();
34
+ emitEvent({ action, videoId });
35
+ }
36
+ };
37
+
38
+ onComplete = event => {
39
+ this.doEmitEvent(EVENT_ACTIONS.ENDED);
40
+ };
28
41
 
29
- onPause = event => {};
42
+ onPause = event => {
43
+ this.doEmitEvent(EVENT_ACTIONS.PAUSED);
44
+ };
30
45
 
31
- onPlay = event => {};
46
+ onPlay = event => {
47
+ this.doEmitEvent(EVENT_ACTIONS.PLAYING);
48
+ };
32
49
 
33
50
  get events() {
34
51
  return {
@@ -1,10 +1,9 @@
1
- import React from 'react';
1
+ import React, { useContext, useRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import ReactJWPlayer from 'react-jw-player';
4
4
  import { JW_PLAYER_TYPE_FILE, VIDEO_WRAPPER_CLASS_NAME } from '../../../../constants';
5
5
  import JWPlayerController from './JWPlayerController';
6
-
7
- const PlayerController = new JWPlayerController();
6
+ import { VideoContext } from '../../VideoContext';
8
7
 
9
8
  const JWPlayerProvider = ({
10
9
  url,
@@ -17,15 +16,18 @@ const JWPlayerProvider = ({
17
16
  imageData,
18
17
  loop: repeat
19
18
  }) => {
19
+ const { emitEvent } = useContext(VideoContext);
20
+ const PlayerController = useRef(new JWPlayerController({ emitEvent }));
21
+
20
22
  const handleOnReady = () => {
21
23
  const jwPlayer = window.jwplayer(name);
22
24
  if (jwPlayer) {
23
- PlayerController.setPlayer(jwPlayer);
25
+ PlayerController.current.setPlayer(jwPlayer);
24
26
  }
25
27
  };
26
28
 
27
29
  const getJWPlayerProps = () => {
28
- const { events } = PlayerController;
30
+ const { events } = PlayerController.current;
29
31
 
30
32
  const props = {
31
33
  customProps: { repeat, controls, events },
@@ -1,8 +1,12 @@
1
- import React, { useState, useEffect } from 'react';
1
+ import React, { useState, useEffect, useContext, useRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useInView } from '@blaze-react/utils/lib/customHooks';
4
4
  import { IN_VIEW_CONFIG } from '../../../../constants';
5
5
  import { getPosterUrl, YT_HQ_FORMAT, YT_IMAGE_URL } from './helpers';
6
+ import { VideoContext } from '../../VideoContext';
7
+ import { EVENT_ACTIONS } from '../../constants';
8
+
9
+ const SCRIPT_ID = 'youtube-iframe-api';
6
10
 
7
11
  const YoutubeEmbeded = ({
8
12
  autoplay,
@@ -23,6 +27,9 @@ const YoutubeEmbeded = ({
23
27
  placeholderOnly,
24
28
  imageData
25
29
  }) => {
30
+ const ref = useRef(null);
31
+ const playerRef = useRef(null);
32
+ const { emitEvent } = useContext(VideoContext);
26
33
  const [isIntersecting, outerRef] = useInView(IN_VIEW_CONFIG);
27
34
  const [preconnected, setPreconnected] = useState(false);
28
35
  const [renderIframe, setRenderIframe] = useState(!!autoplay);
@@ -43,10 +50,62 @@ const YoutubeEmbeded = ({
43
50
  webp
44
51
  });
45
52
  const mutedValue = muted ? '&mute=1' : '';
46
- const iframeSrc = !playlist
53
+ let iframeSrc = !playlist
47
54
  ? `${ytUrl}/embed/${encodedId}?autoplay=1${mutedValue}${paramsImp}`
48
55
  : `${ytUrl}/embed/videoseries?autoplay=1${mutedValue}&list=${encodedId}${paramsImp}`;
56
+ if (emitEvent) iframeSrc += `&enablejsapi=1&origin=${window.location.origin}`;
57
+
49
58
  const parsedWrapperClassname = `yt-facade ${renderIframe ? 'yt-activated' : ''}`;
59
+ const iframeId = `yt-iframe-${videoId}`;
60
+
61
+ useEffect(
62
+ () => {
63
+ if (!emitEvent || !renderIframe) return;
64
+
65
+ if (!document.getElementById(SCRIPT_ID)) {
66
+ // if script not already loaded
67
+ const tag = document.createElement('script');
68
+ tag.id = SCRIPT_ID;
69
+ tag.src = 'https://www.youtube.com/iframe_api';
70
+ const firstScriptTag = document.getElementsByTagName('script')[0];
71
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
72
+ }
73
+
74
+ const onStateChange = event => {
75
+ let action = '';
76
+ if (event.data === window.YT.PlayerState.ENDED) {
77
+ action = EVENT_ACTIONS.ENDED;
78
+ } else if (event.data === window.YT.PlayerState.PAUSED) {
79
+ action = EVENT_ACTIONS.PAUSED;
80
+ } else if (event.data === window.YT.PlayerState.PLAYING) {
81
+ action = EVENT_ACTIONS.PLAYING;
82
+ }
83
+
84
+ emitEvent({ action, videoId });
85
+ };
86
+
87
+ if (window.YT) {
88
+ // if script already loaded then attach player
89
+ window.YT.ready(() => {
90
+ playerRef.current = new window.YT.Player(iframeId, {
91
+ events: {
92
+ onStateChange
93
+ }
94
+ });
95
+ });
96
+ } else {
97
+ // called on script load
98
+ window.onYouTubeIframeAPIReady = () => {
99
+ playerRef.current = new window.YT.Player(ref.current, {
100
+ events: {
101
+ onStateChange
102
+ }
103
+ });
104
+ };
105
+ }
106
+ },
107
+ [emitEvent, iframeId, renderIframe, videoId]
108
+ );
50
109
 
51
110
  useEffect(
52
111
  () => {
@@ -114,6 +173,8 @@ const YoutubeEmbeded = ({
114
173
  </div>
115
174
  {renderIframe && (
116
175
  <iframe
176
+ ref={ref}
177
+ id={iframeId}
117
178
  className={iframeClass}
118
179
  title={videoTitle}
119
180
  allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"