@atlaskit/media-ui 16.5.0 → 17.2.0

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 (200) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/dist/cjs/BlockCard/components/Byline.js +4 -2
  3. package/dist/cjs/BlockCard/components/Content.js +6 -2
  4. package/dist/cjs/BlockCard/components/ContentHeader.js +6 -2
  5. package/dist/cjs/BlockCard/components/Icon.js +3 -3
  6. package/dist/cjs/BlockCard/components/Link.js +3 -1
  7. package/dist/cjs/BlockCard/components/Modal.js +13 -21
  8. package/dist/cjs/BlockCard/components/ModalHeader.js +7 -2
  9. package/dist/cjs/BlockCard/components/Name.js +6 -2
  10. package/dist/cjs/BlockCard/views/ErroredView.js +5 -1
  11. package/dist/cjs/BlockCard/views/ForbiddenView.js +5 -2
  12. package/dist/cjs/BlockCard/views/NotFoundView.js +5 -1
  13. package/dist/cjs/BlockCard/views/ResolvedView.js +5 -2
  14. package/dist/cjs/EmbedCard/components/Frame.js +1 -1
  15. package/dist/cjs/MediaInlineCard/ErroredView/index.js +93 -0
  16. package/dist/cjs/MediaInlineCard/Frame/index.js +98 -0
  17. package/dist/cjs/MediaInlineCard/Frame/styled.js +54 -0
  18. package/dist/cjs/MediaInlineCard/Icon.js +30 -0
  19. package/dist/cjs/MediaInlineCard/IconAndTitleLayout/index.js +131 -0
  20. package/dist/cjs/MediaInlineCard/IconAndTitleLayout/styled.js +72 -0
  21. package/dist/cjs/MediaInlineCard/LoadedView/index.js +66 -0
  22. package/dist/cjs/MediaInlineCard/LoadingView/index.js +85 -0
  23. package/dist/cjs/MediaInlineCard/LoadingView/styled.js +19 -0
  24. package/dist/cjs/MediaInlineCard/index.js +29 -0
  25. package/dist/cjs/MediaInlineCard/styled.js +25 -0
  26. package/dist/cjs/classNames.js +52 -0
  27. package/dist/cjs/codeViewer.js +8 -0
  28. package/dist/cjs/customMediaPlayer/analytics/events/screen/customMediaPlayer.js +35 -0
  29. package/dist/cjs/customMediaPlayer/analytics/events/track/playCount.js +35 -0
  30. package/dist/cjs/customMediaPlayer/analytics/events/track/played.js +35 -0
  31. package/dist/cjs/customMediaPlayer/analytics/events/ui/mediaButtonClicked.js +33 -0
  32. package/dist/cjs/customMediaPlayer/analytics/events/ui/playPauseBlanketClicked.js +32 -0
  33. package/dist/cjs/customMediaPlayer/analytics/events/ui/playbackSpeedChanged.js +32 -0
  34. package/dist/cjs/customMediaPlayer/analytics/events/ui/shortcutPressed.js +33 -0
  35. package/dist/cjs/customMediaPlayer/analytics/events/ui/timeRangeNavigated.js +33 -0
  36. package/dist/cjs/customMediaPlayer/analytics/index.js +89 -0
  37. package/dist/cjs/customMediaPlayer/analytics/utils/analytics.js +29 -0
  38. package/dist/cjs/customMediaPlayer/analytics/utils/playbackAttributes.js +40 -0
  39. package/dist/cjs/customMediaPlayer/fullscreen.js +4 -2
  40. package/dist/cjs/customMediaPlayer/icons.js +61 -0
  41. package/dist/cjs/customMediaPlayer/index.js +345 -83
  42. package/dist/cjs/customMediaPlayer/playbackSpeedControls.js +4 -2
  43. package/dist/cjs/customMediaPlayer/timeRange.js +6 -1
  44. package/dist/cjs/customMediaPlayer/types.js +5 -0
  45. package/dist/cjs/ellipsify.js +42 -40
  46. package/dist/cjs/index.js +22 -2
  47. package/dist/cjs/locales.js +17 -0
  48. package/dist/cjs/mediaImage/index.js +8 -4
  49. package/dist/cjs/mediaImage/styled.js +32 -4
  50. package/dist/cjs/messages.js +22 -7
  51. package/dist/cjs/shortcut.js +12 -5
  52. package/dist/cjs/version.json +1 -1
  53. package/dist/es2019/BlockCard/components/Byline.js +4 -2
  54. package/dist/es2019/BlockCard/components/Content.js +3 -1
  55. package/dist/es2019/BlockCard/components/ContentHeader.js +3 -1
  56. package/dist/es2019/BlockCard/components/Icon.js +3 -3
  57. package/dist/es2019/BlockCard/components/Link.js +3 -1
  58. package/dist/es2019/BlockCard/components/Modal.js +30 -19
  59. package/dist/es2019/BlockCard/components/ModalHeader.js +60 -55
  60. package/dist/es2019/BlockCard/components/Name.js +3 -1
  61. package/dist/es2019/BlockCard/views/ErroredView.js +2 -0
  62. package/dist/es2019/BlockCard/views/ForbiddenView.js +3 -1
  63. package/dist/es2019/BlockCard/views/NotFoundView.js +2 -0
  64. package/dist/es2019/BlockCard/views/ResolvedView.js +3 -1
  65. package/dist/es2019/EmbedCard/components/Frame.js +1 -1
  66. package/dist/es2019/MediaInlineCard/ErroredView/index.js +43 -0
  67. package/dist/es2019/MediaInlineCard/Frame/index.js +60 -0
  68. package/dist/es2019/MediaInlineCard/Frame/styled.js +60 -0
  69. package/dist/es2019/MediaInlineCard/Icon.js +23 -0
  70. package/dist/es2019/MediaInlineCard/IconAndTitleLayout/index.js +90 -0
  71. package/dist/es2019/MediaInlineCard/IconAndTitleLayout/styled.js +103 -0
  72. package/dist/es2019/MediaInlineCard/LoadedView/index.js +25 -0
  73. package/dist/es2019/MediaInlineCard/LoadingView/index.js +42 -0
  74. package/dist/es2019/MediaInlineCard/LoadingView/styled.js +6 -0
  75. package/dist/es2019/MediaInlineCard/index.js +3 -0
  76. package/dist/es2019/MediaInlineCard/styled.js +9 -0
  77. package/dist/es2019/classNames.js +8 -3
  78. package/dist/es2019/codeViewer.js +8 -0
  79. package/dist/es2019/customMediaPlayer/analytics/events/screen/customMediaPlayer.js +16 -0
  80. package/dist/es2019/customMediaPlayer/analytics/events/track/playCount.js +16 -0
  81. package/dist/es2019/customMediaPlayer/analytics/events/track/played.js +16 -0
  82. package/dist/es2019/customMediaPlayer/analytics/events/ui/mediaButtonClicked.js +18 -0
  83. package/dist/es2019/customMediaPlayer/analytics/events/ui/playPauseBlanketClicked.js +17 -0
  84. package/dist/es2019/customMediaPlayer/analytics/events/ui/playbackSpeedChanged.js +17 -0
  85. package/dist/es2019/customMediaPlayer/analytics/events/ui/shortcutPressed.js +18 -0
  86. package/dist/es2019/customMediaPlayer/analytics/events/ui/timeRangeNavigated.js +18 -0
  87. package/dist/es2019/customMediaPlayer/analytics/index.js +9 -0
  88. package/dist/es2019/customMediaPlayer/analytics/utils/analytics.js +14 -0
  89. package/dist/es2019/customMediaPlayer/analytics/utils/playbackAttributes.js +31 -0
  90. package/dist/es2019/customMediaPlayer/fullscreen.js +4 -2
  91. package/dist/es2019/customMediaPlayer/icons.js +49 -0
  92. package/dist/es2019/customMediaPlayer/index.js +357 -78
  93. package/dist/es2019/customMediaPlayer/playbackSpeedControls.js +4 -2
  94. package/dist/es2019/customMediaPlayer/timeRange.js +9 -1
  95. package/dist/es2019/customMediaPlayer/types.js +1 -0
  96. package/dist/es2019/ellipsify.js +22 -16
  97. package/dist/es2019/index.js +2 -1
  98. package/dist/es2019/locales.js +3 -0
  99. package/dist/es2019/mediaImage/index.js +8 -4
  100. package/dist/es2019/mediaImage/styled.js +29 -8
  101. package/dist/es2019/messages.js +22 -7
  102. package/dist/es2019/shortcut.js +12 -5
  103. package/dist/es2019/version.json +1 -1
  104. package/dist/esm/BlockCard/components/Byline.js +4 -2
  105. package/dist/esm/BlockCard/components/Content.js +3 -1
  106. package/dist/esm/BlockCard/components/ContentHeader.js +3 -1
  107. package/dist/esm/BlockCard/components/Icon.js +3 -3
  108. package/dist/esm/BlockCard/components/Link.js +3 -1
  109. package/dist/esm/BlockCard/components/Modal.js +31 -22
  110. package/dist/esm/BlockCard/components/ModalHeader.js +6 -2
  111. package/dist/esm/BlockCard/components/Name.js +3 -1
  112. package/dist/esm/BlockCard/views/ErroredView.js +2 -0
  113. package/dist/esm/BlockCard/views/ForbiddenView.js +3 -1
  114. package/dist/esm/BlockCard/views/NotFoundView.js +2 -0
  115. package/dist/esm/BlockCard/views/ResolvedView.js +3 -1
  116. package/dist/esm/EmbedCard/components/Frame.js +1 -1
  117. package/dist/esm/MediaInlineCard/ErroredView/index.js +70 -0
  118. package/dist/esm/MediaInlineCard/Frame/index.js +84 -0
  119. package/dist/esm/MediaInlineCard/Frame/styled.js +39 -0
  120. package/dist/esm/MediaInlineCard/Icon.js +15 -0
  121. package/dist/esm/MediaInlineCard/IconAndTitleLayout/index.js +113 -0
  122. package/dist/esm/MediaInlineCard/IconAndTitleLayout/styled.js +33 -0
  123. package/dist/esm/MediaInlineCard/LoadedView/index.js +50 -0
  124. package/dist/esm/MediaInlineCard/LoadingView/index.js +66 -0
  125. package/dist/esm/MediaInlineCard/LoadingView/styled.js +7 -0
  126. package/dist/esm/MediaInlineCard/index.js +3 -0
  127. package/dist/esm/MediaInlineCard/styled.js +11 -0
  128. package/dist/esm/classNames.js +8 -3
  129. package/dist/esm/codeViewer.js +8 -0
  130. package/dist/esm/customMediaPlayer/analytics/events/screen/customMediaPlayer.js +23 -0
  131. package/dist/esm/customMediaPlayer/analytics/events/track/playCount.js +23 -0
  132. package/dist/esm/customMediaPlayer/analytics/events/track/played.js +23 -0
  133. package/dist/esm/customMediaPlayer/analytics/events/ui/mediaButtonClicked.js +23 -0
  134. package/dist/esm/customMediaPlayer/analytics/events/ui/playPauseBlanketClicked.js +22 -0
  135. package/dist/esm/customMediaPlayer/analytics/events/ui/playbackSpeedChanged.js +22 -0
  136. package/dist/esm/customMediaPlayer/analytics/events/ui/shortcutPressed.js +23 -0
  137. package/dist/esm/customMediaPlayer/analytics/events/ui/timeRangeNavigated.js +23 -0
  138. package/dist/esm/customMediaPlayer/analytics/index.js +9 -0
  139. package/dist/esm/customMediaPlayer/analytics/utils/analytics.js +14 -0
  140. package/dist/esm/customMediaPlayer/analytics/utils/playbackAttributes.js +29 -0
  141. package/dist/esm/customMediaPlayer/fullscreen.js +4 -2
  142. package/dist/esm/customMediaPlayer/icons.js +49 -0
  143. package/dist/esm/customMediaPlayer/index.js +354 -78
  144. package/dist/esm/customMediaPlayer/playbackSpeedControls.js +4 -2
  145. package/dist/esm/customMediaPlayer/timeRange.js +6 -1
  146. package/dist/esm/customMediaPlayer/types.js +1 -0
  147. package/dist/esm/ellipsify.js +38 -36
  148. package/dist/esm/index.js +2 -1
  149. package/dist/esm/locales.js +3 -0
  150. package/dist/esm/mediaImage/index.js +8 -4
  151. package/dist/esm/mediaImage/styled.js +31 -4
  152. package/dist/esm/messages.js +22 -7
  153. package/dist/esm/shortcut.js +12 -5
  154. package/dist/esm/version.json +1 -1
  155. package/dist/types/BlockCard/components/Byline.d.ts +2 -1
  156. package/dist/types/BlockCard/components/Content.d.ts +1 -0
  157. package/dist/types/BlockCard/components/ContentHeader.d.ts +1 -0
  158. package/dist/types/BlockCard/components/Link.d.ts +2 -1
  159. package/dist/types/BlockCard/components/ModalHeader.d.ts +2 -2
  160. package/dist/types/BlockCard/components/Name.d.ts +1 -0
  161. package/dist/types/BlockCard/views/ErroredView.d.ts +1 -0
  162. package/dist/types/BlockCard/views/ForbiddenView.d.ts +1 -0
  163. package/dist/types/BlockCard/views/NotFoundView.d.ts +1 -0
  164. package/dist/types/BlockCard/views/ResolvedView.d.ts +1 -0
  165. package/dist/types/MediaInlineCard/ErroredView/index.d.ts +16 -0
  166. package/dist/types/MediaInlineCard/Frame/index.d.ts +17 -0
  167. package/dist/types/MediaInlineCard/Frame/styled.d.ts +5 -0
  168. package/dist/types/MediaInlineCard/Icon.d.ts +3 -0
  169. package/dist/types/MediaInlineCard/IconAndTitleLayout/index.d.ts +18 -0
  170. package/dist/types/MediaInlineCard/IconAndTitleLayout/styled.d.ts +12 -0
  171. package/dist/types/MediaInlineCard/LoadedView/index.d.ts +18 -0
  172. package/dist/types/MediaInlineCard/LoadingView/index.d.ts +17 -0
  173. package/dist/types/MediaInlineCard/LoadingView/styled.d.ts +2 -0
  174. package/dist/types/MediaInlineCard/index.d.ts +6 -0
  175. package/dist/types/MediaInlineCard/styled.d.ts +2 -0
  176. package/dist/types/classNames.d.ts +7 -2
  177. package/dist/types/customMediaPlayer/analytics/events/screen/customMediaPlayer.d.ts +5 -0
  178. package/dist/types/customMediaPlayer/analytics/events/track/playCount.d.ts +5 -0
  179. package/dist/types/customMediaPlayer/analytics/events/track/played.d.ts +5 -0
  180. package/dist/types/customMediaPlayer/analytics/events/ui/mediaButtonClicked.d.ts +5 -0
  181. package/dist/types/customMediaPlayer/analytics/events/ui/playPauseBlanketClicked.d.ts +5 -0
  182. package/dist/types/customMediaPlayer/analytics/events/ui/playbackSpeedChanged.d.ts +5 -0
  183. package/dist/types/customMediaPlayer/analytics/events/ui/shortcutPressed.d.ts +5 -0
  184. package/dist/types/customMediaPlayer/analytics/events/ui/timeRangeNavigated.d.ts +5 -0
  185. package/dist/types/customMediaPlayer/analytics/index.d.ts +11 -0
  186. package/dist/types/customMediaPlayer/analytics/utils/analytics.d.ts +19 -0
  187. package/dist/types/customMediaPlayer/analytics/utils/playbackAttributes.d.ts +24 -0
  188. package/dist/types/customMediaPlayer/icons.d.ts +3 -0
  189. package/dist/types/customMediaPlayer/index.d.ts +44 -30
  190. package/dist/types/customMediaPlayer/playbackSpeedControls.d.ts +1 -0
  191. package/dist/types/customMediaPlayer/timeRange.d.ts +1 -0
  192. package/dist/types/customMediaPlayer/types.d.ts +4 -0
  193. package/dist/types/index.d.ts +3 -1
  194. package/dist/types/locales.d.ts +4 -0
  195. package/dist/types/mediaImage/index.d.ts +2 -0
  196. package/dist/types/mediaImage/styled.d.ts +5 -2
  197. package/dist/types/messages.d.ts +1 -1
  198. package/dist/types/shortcut.d.ts +15 -4
  199. package/locales/package.json +7 -0
  200. package/package.json +17 -14
@@ -1,6 +1,8 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React from 'react';
3
3
  import { Component } from 'react';
4
+ import { version as packageVersion, name as packageName } from '../version.json';
5
+ import { withAnalyticsEvents } from '@atlaskit/analytics-next';
4
6
  import PlayIcon from '@atlaskit/icon/glyph/vid-play';
5
7
  import PauseIcon from '@atlaskit/icon/glyph/vid-pause';
6
8
  import FullScreenIconOn from '@atlaskit/icon/glyph/vid-full-screen-on';
@@ -8,6 +10,7 @@ import FullScreenIconOff from '@atlaskit/icon/glyph/vid-full-screen-off';
8
10
  import SoundIcon from '@atlaskit/icon/glyph/hipchat/outgoing-sound';
9
11
  import HDIcon from '@atlaskit/icon/glyph/vid-hd-circle';
10
12
  import DownloadIcon from '@atlaskit/icon/glyph/download';
13
+ import { withMediaAnalyticsContext } from '@atlaskit/media-common';
11
14
  import MediaButton from '../MediaButton';
12
15
  import Spinner from '@atlaskit/spinner';
13
16
  import { WidthObserver } from '@atlaskit/width-detector';
@@ -15,6 +18,7 @@ import MediaPlayer from 'react-video-renderer';
15
18
  import { B200, DN400, N0, DN60 } from '@atlaskit/theme/colors';
16
19
  import { TimeRange } from './timeRange';
17
20
  import { CurrentTime, VideoWrapper, CustomVideoWrapper, TimebarWrapper, VolumeWrapper, TimeWrapper, LeftControls, RightControls, ControlsWrapper, VolumeToggleWrapper, MutedIndicator, SpinnerWrapper, VolumeTimeRangeWrapper } from './styled';
21
+ import { fireAnalyticsEvent, relevantFeatureFlagNames, createCustomMediaPlayerScreenEvent, createMediaButtonClickedEvent, createMediaShortcutPressedEvent, createPlayPauseBlanketClickedEvent, createTimeRangeNavigatedEvent, createPlaybackSpeedChangedEvent, createFirstPlayedTrackEvent, createPlayedTrackEvent } from './analytics';
18
22
  import { formatDuration } from '../formatDuration';
19
23
  import { hideControlsClassName } from '../classNames';
20
24
  import { Shortcut, keyCodes } from '../shortcut';
@@ -25,14 +29,29 @@ import simultaneousPlayManager from './simultaneousPlayManager';
25
29
  import { TimeSaver } from './timeSaver';
26
30
  import PlaybackSpeedControls from './playbackSpeedControls';
27
31
  import { PlayPauseBlanket } from './playPauseBlanket';
32
+ import Tooltip from '@atlaskit/tooltip';
33
+ import { SkipTenBackwardIcon, SkipTenForwardIcon } from './icons';
28
34
  const SMALL_VIDEO_MAX_WIDTH = 400;
29
35
  const MINIMUM_DURATION_BEFORE_SAVING_TIME = 60;
30
- export class CustomMediaPlayer extends Component {
36
+ const VIEWED_TRACKING_SECS = 2;
37
+ export class CustomMediaPlayerBase extends Component {
31
38
  constructor(...args) {
32
39
  super(...args);
33
40
 
41
+ _defineProperty(this, "videoState", {
42
+ isLoading: true,
43
+ buffered: 0,
44
+ currentTime: 0,
45
+ volume: 1,
46
+ status: 'paused',
47
+ duration: 0,
48
+ isMuted: false
49
+ });
50
+
34
51
  _defineProperty(this, "wasPlayedOnce", false);
35
52
 
53
+ _defineProperty(this, "lastCurrentTime", 0);
54
+
36
55
  _defineProperty(this, "timeSaver", new TimeSaver(this.props.lastWatchTimeConfig));
37
56
 
38
57
  _defineProperty(this, "state", {
@@ -58,11 +77,13 @@ export class CustomMediaPlayer extends Component {
58
77
  }
59
78
  });
60
79
 
61
- _defineProperty(this, "onTimeChange", navigate => value => {
62
- navigate(value);
80
+ _defineProperty(this, "onTimeChanged", () => {
81
+ this.createAndFireUIEvent('timeRangeNavigate', 'time');
63
82
  });
64
83
 
65
- _defineProperty(this, "onVolumeChange", setVolume => value => setVolume(value));
84
+ _defineProperty(this, "onVolumeChanged", () => {
85
+ this.createAndFireUIEvent('volumeRangeNavigate', 'volume');
86
+ });
66
87
 
67
88
  _defineProperty(this, "onCurrentTimeChange", (currentTime, duration) => {
68
89
  if (duration - currentTime > MINIMUM_DURATION_BEFORE_SAVING_TIME) {
@@ -72,17 +93,6 @@ export class CustomMediaPlayer extends Component {
72
93
  }
73
94
  });
74
95
 
75
- _defineProperty(this, "shortcutHandler", toggleButtonAction => () => {
76
- const {
77
- showControls
78
- } = this.props;
79
- toggleButtonAction();
80
-
81
- if (showControls) {
82
- showControls();
83
- }
84
- });
85
-
86
96
  _defineProperty(this, "renderCurrentTime", ({
87
97
  currentTime,
88
98
  duration
@@ -108,7 +118,7 @@ export class CustomMediaPlayer extends Component {
108
118
  const secondaryColor = isHDActive ? N0 : DN60;
109
119
  return /*#__PURE__*/React.createElement(MediaButton, {
110
120
  testId: "custom-media-player-hd-button",
111
- onClick: onHDToggleClick,
121
+ onClick: !!onHDToggleClick ? this.getMediaButtonClickHandler(onHDToggleClick, 'HDButton') : undefined,
112
122
  iconBefore: /*#__PURE__*/React.createElement(HDIcon, {
113
123
  primaryColor: primaryColor,
114
124
  secondaryColor: secondaryColor,
@@ -126,6 +136,7 @@ export class CustomMediaPlayer extends Component {
126
136
  this.setState({
127
137
  playbackSpeed
128
138
  });
139
+ this.createAndFireUIEvent('playbackSpeedChange');
129
140
  });
130
141
 
131
142
  _defineProperty(this, "renderSpeedControls", () => {
@@ -138,38 +149,40 @@ export class CustomMediaPlayer extends Component {
138
149
  return /*#__PURE__*/React.createElement(PlaybackSpeedControls, {
139
150
  originalDimensions: originalDimensions,
140
151
  playbackSpeed: playbackSpeed,
141
- onPlaybackSpeedChange: this.onPlaybackSpeedChange
152
+ onPlaybackSpeedChange: this.onPlaybackSpeedChange,
153
+ onClick: () => this.createAndFireUIEvent('mediaButtonClick', 'playbackSpeedButton')
142
154
  });
143
155
  });
144
156
 
145
- _defineProperty(this, "renderVolume", ({
146
- isMuted,
147
- volume
148
- }, actions, showSlider) => {
149
- return /*#__PURE__*/React.createElement(VolumeWrapper, {
150
- showSlider: showSlider
151
- }, /*#__PURE__*/React.createElement(VolumeToggleWrapper, {
152
- isMuted: isMuted
153
- }, /*#__PURE__*/React.createElement(MutedIndicator, {
154
- isMuted: isMuted
155
- }), /*#__PURE__*/React.createElement(MediaButton, {
156
- testId: "custom-media-player-volume-toggle-button",
157
- onClick: actions.toggleMute,
158
- iconBefore: /*#__PURE__*/React.createElement(SoundIcon, {
159
- label: "volume"
160
- })
161
- })), showSlider && /*#__PURE__*/React.createElement(VolumeTimeRangeWrapper, null, /*#__PURE__*/React.createElement(TimeRange, {
162
- onChange: this.onVolumeChange(actions.setVolume),
163
- duration: 1,
164
- currentTime: volume,
165
- bufferedTime: volume,
166
- disableThumbTooltip: true,
167
- isAlwaysActive: true
168
- })));
157
+ _defineProperty(this, "renderVolume", (videoState, actions, showSlider) => /*#__PURE__*/React.createElement(VolumeWrapper, {
158
+ showSlider: showSlider
159
+ }, /*#__PURE__*/React.createElement(VolumeToggleWrapper, {
160
+ isMuted: videoState.isMuted
161
+ }, /*#__PURE__*/React.createElement(MutedIndicator, {
162
+ isMuted: videoState.isMuted
163
+ }), /*#__PURE__*/React.createElement(MediaButton, {
164
+ testId: "custom-media-player-volume-toggle-button",
165
+ onClick: this.getMediaButtonClickHandler(actions.toggleMute, 'muteButton'),
166
+ iconBefore: /*#__PURE__*/React.createElement(SoundIcon, {
167
+ label: "volume"
168
+ })
169
+ })), showSlider && /*#__PURE__*/React.createElement(VolumeTimeRangeWrapper, null, /*#__PURE__*/React.createElement(TimeRange, {
170
+ onChange: actions.setVolume,
171
+ duration: 1,
172
+ currentTime: videoState.volume,
173
+ bufferedTime: videoState.volume,
174
+ disableThumbTooltip: true,
175
+ isAlwaysActive: true,
176
+ onChanged: this.onVolumeChanged
177
+ }))));
178
+
179
+ _defineProperty(this, "toggleFullscreen", () => toggleFullscreen(this.videoWrapperRef));
180
+
181
+ _defineProperty(this, "onFullScreenButtonClick", () => {
182
+ this.toggleFullscreen();
183
+ this.createAndFireUIEvent('mediaButtonClick', 'fullScreenButton');
169
184
  });
170
185
 
171
- _defineProperty(this, "onFullScreenClick", () => toggleFullscreen(this.videoWrapperRef));
172
-
173
186
  _defineProperty(this, "onResize", width => this.setState({
174
187
  isLargePlayer: width > SMALL_VIDEO_MAX_WIDTH
175
188
  }));
@@ -198,7 +211,7 @@ export class CustomMediaPlayer extends Component {
198
211
  });
199
212
  return /*#__PURE__*/React.createElement(MediaButton, {
200
213
  testId: "custom-media-player-fullscreen-button",
201
- onClick: this.onFullScreenClick,
214
+ onClick: this.onFullScreenButtonClick,
202
215
  iconBefore: icon
203
216
  });
204
217
  });
@@ -214,13 +227,110 @@ export class CustomMediaPlayer extends Component {
214
227
 
215
228
  return /*#__PURE__*/React.createElement(MediaButton, {
216
229
  testId: "custom-media-player-download-button",
217
- onClick: onDownloadClick,
230
+ onClick: this.getMediaButtonClickHandler(onDownloadClick, 'downloadButton'),
218
231
  iconBefore: /*#__PURE__*/React.createElement(DownloadIcon, {
219
232
  label: "download"
220
233
  })
221
234
  });
222
235
  });
223
236
 
237
+ _defineProperty(this, "renderShortcuts", ({
238
+ togglePlayPauseAction,
239
+ toggleMute,
240
+ skipBackward,
241
+ skipForward
242
+ }) => {
243
+ const {
244
+ isShortcutEnabled
245
+ } = this.props;
246
+ const {
247
+ isFullScreenEnabled
248
+ } = this.state;
249
+ const shortcuts = (isShortcutEnabled || isFullScreenEnabled) && [/*#__PURE__*/React.createElement(Shortcut, {
250
+ key: "space-shortcut",
251
+ code: keyCodes.space,
252
+ handler: this.getKeyboardShortcutHandler(togglePlayPauseAction, 'space')
253
+ }), /*#__PURE__*/React.createElement(Shortcut, {
254
+ key: "m-shortcut",
255
+ code: keyCodes.m,
256
+ handler: this.getKeyboardShortcutHandler(toggleMute, 'mute')
257
+ })];
258
+
259
+ if (shortcuts && isFullScreenEnabled) {
260
+ // Fullscreen shortcuts only. We don't want to override left/right keys in media-viewer settings
261
+ shortcuts.push( /*#__PURE__*/React.createElement(Shortcut, {
262
+ key: "skip-backward-shortcut",
263
+ code: keyCodes.leftArrow,
264
+ handler: this.getKeyboardShortcutHandler(skipBackward, 'leftArrow')
265
+ }));
266
+ shortcuts.push( /*#__PURE__*/React.createElement(Shortcut, {
267
+ key: "skip-forward-shortcut",
268
+ code: keyCodes.rightArrow,
269
+ handler: this.getKeyboardShortcutHandler(skipForward, 'rightArrow')
270
+ }));
271
+ }
272
+
273
+ return shortcuts;
274
+ });
275
+
276
+ _defineProperty(this, "renderPlayPauseButton", isPlaying => {
277
+ const {
278
+ intl: {
279
+ formatMessage
280
+ }
281
+ } = this.props;
282
+ const toggleButtonIcon = isPlaying ? /*#__PURE__*/React.createElement(PauseIcon, {
283
+ label: formatMessage(messages.pause)
284
+ }) : /*#__PURE__*/React.createElement(PlayIcon, {
285
+ label: formatMessage(messages.play)
286
+ });
287
+ return /*#__PURE__*/React.createElement(Tooltip, {
288
+ content: formatMessage(isPlaying ? messages.pause : messages.play),
289
+ position: "top"
290
+ }, /*#__PURE__*/React.createElement(MediaButton, {
291
+ testId: "custom-media-player-play-toggle-button",
292
+ "data-test-is-playing": isPlaying,
293
+ iconBefore: toggleButtonIcon,
294
+ onClick: isPlaying ? this.pausePlayByButtonClick : this.startPlayByButtonClick
295
+ }));
296
+ });
297
+
298
+ _defineProperty(this, "renderSkipBackwardButton", skipBackward => {
299
+ const {
300
+ intl: {
301
+ formatMessage
302
+ }
303
+ } = this.props;
304
+ return /*#__PURE__*/React.createElement(Tooltip, {
305
+ content: formatMessage(messages.skipBackward),
306
+ position: "top"
307
+ }, /*#__PURE__*/React.createElement(MediaButton, {
308
+ testId: "custom-media-player-skip-backward-button",
309
+ iconBefore: /*#__PURE__*/React.createElement(SkipTenBackwardIcon, {
310
+ label: formatMessage(messages.skipBackward)
311
+ }),
312
+ onClick: this.getMediaButtonClickHandler(skipBackward, 'skipBackwardButton')
313
+ }));
314
+ });
315
+
316
+ _defineProperty(this, "renderSkipForwardButton", skipForward => {
317
+ const {
318
+ intl: {
319
+ formatMessage
320
+ }
321
+ } = this.props;
322
+ return /*#__PURE__*/React.createElement(Tooltip, {
323
+ content: formatMessage(messages.skipForward),
324
+ position: "top"
325
+ }, /*#__PURE__*/React.createElement(MediaButton, {
326
+ testId: "custom-media-player-skip-forward-button",
327
+ iconBefore: /*#__PURE__*/React.createElement(SkipTenForwardIcon, {
328
+ label: formatMessage(messages.skipForward)
329
+ }),
330
+ onClick: this.getMediaButtonClickHandler(skipForward, 'skipForwardButton')
331
+ }));
332
+ });
333
+
224
334
  _defineProperty(this, "renderSpinner", () => /*#__PURE__*/React.createElement(SpinnerWrapper, null, /*#__PURE__*/React.createElement(Spinner, {
225
335
  appearance: "invert",
226
336
  size: "large"
@@ -248,13 +358,112 @@ export class CustomMediaPlayer extends Component {
248
358
  onFirstPlay();
249
359
  }
250
360
  });
361
+
362
+ _defineProperty(this, "getMediaButtonClickHandler", (action, buttonType) => () => {
363
+ action();
364
+ this.createAndFireUIEvent('mediaButtonClick', buttonType);
365
+ });
366
+
367
+ _defineProperty(this, "getKeyboardShortcutHandler", (action, shortcutType) => () => {
368
+ const {
369
+ showControls
370
+ } = this.props;
371
+ action();
372
+
373
+ if (showControls) {
374
+ showControls();
375
+ }
376
+
377
+ this.createAndFireUIEvent('shortcutPress', shortcutType);
378
+ });
379
+
380
+ _defineProperty(this, "onViewed", videoState => {
381
+ const {
382
+ createAnalyticsEvent,
383
+ fileId,
384
+ isAutoPlay,
385
+ isHDAvailable,
386
+ isHDActive,
387
+ type
388
+ } = this.props;
389
+ const {
390
+ isFullScreenEnabled,
391
+ isLargePlayer,
392
+ playbackSpeed
393
+ } = this.state;
394
+ const {
395
+ status,
396
+ currentTime
397
+ } = videoState;
398
+
399
+ if (status === 'playing' && (currentTime < this.lastCurrentTime || currentTime >= this.lastCurrentTime + VIEWED_TRACKING_SECS)) {
400
+ fireAnalyticsEvent(createPlayedTrackEvent(type, { ...videoState,
401
+ isAutoPlay,
402
+ isHDAvailable,
403
+ isHDActive,
404
+ isFullScreenEnabled,
405
+ isLargePlayer,
406
+ playbackSpeed
407
+ }, fileId), createAnalyticsEvent);
408
+ this.lastCurrentTime = currentTime;
409
+ }
410
+ });
411
+
412
+ _defineProperty(this, "resetPendingPlayPauseToggleTimer", () => {
413
+ if (this.clickToTogglePlayTimoutId !== undefined) {
414
+ clearTimeout(this.clickToTogglePlayTimoutId);
415
+ }
416
+ });
417
+
418
+ _defineProperty(this, "doubleClickToFullscreen", () => {
419
+ this.resetPendingPlayPauseToggleTimer();
420
+ this.toggleFullscreen(); // TODO Add an event similar to "playPauseBlanketClick" but for fullscreen trigger
421
+ });
422
+
423
+ _defineProperty(this, "togglePlayByBlanketClick", action => {
424
+ this.resetPendingPlayPauseToggleTimer();
425
+ this.clickToTogglePlayTimoutId = setTimeout(() => {
426
+ action();
427
+ this.createAndFireUIEvent('playPauseBlanketClick');
428
+ }, 200);
429
+ });
430
+
431
+ _defineProperty(this, "startPlayByBlanketClick", () => {
432
+ this.togglePlayByBlanketClick(this.play);
433
+ });
434
+
435
+ _defineProperty(this, "pausePlayByBlanketClick", () => {
436
+ this.togglePlayByBlanketClick(this.pause);
437
+ });
438
+
439
+ _defineProperty(this, "startPlayByButtonClick", this.getMediaButtonClickHandler(this.play, 'playButton'));
440
+
441
+ _defineProperty(this, "pausePlayByButtonClick", this.getMediaButtonClickHandler(this.pause, 'pauseButton'));
251
442
  }
252
443
 
253
444
  componentDidMount() {
254
445
  const {
446
+ type,
447
+ fileId,
255
448
  isAutoPlay,
256
- onFirstPlay
449
+ isHDAvailable,
450
+ isHDActive,
451
+ onFirstPlay,
452
+ createAnalyticsEvent
257
453
  } = this.props;
454
+ const {
455
+ isFullScreenEnabled,
456
+ isLargePlayer,
457
+ playbackSpeed
458
+ } = this.state;
459
+ fireAnalyticsEvent(createCustomMediaPlayerScreenEvent(type, {
460
+ isAutoPlay,
461
+ isHDAvailable,
462
+ isHDActive,
463
+ isFullScreenEnabled,
464
+ isLargePlayer,
465
+ playbackSpeed
466
+ }, fileId), createAnalyticsEvent);
258
467
 
259
468
  if (this.videoWrapperRef) {
260
469
  this.videoWrapperRef.addEventListener('fullscreenchange', this.onFullScreenChange);
@@ -266,6 +475,14 @@ export class CustomMediaPlayer extends Component {
266
475
  simultaneousPlayManager.pauseOthers(this);
267
476
 
268
477
  if (onFirstPlay) {
478
+ fireAnalyticsEvent(createFirstPlayedTrackEvent(type, {
479
+ isAutoPlay,
480
+ isHDAvailable,
481
+ isHDActive,
482
+ isFullScreenEnabled,
483
+ isLargePlayer,
484
+ playbackSpeed
485
+ }, fileId), createAnalyticsEvent);
269
486
  this.wasPlayedOnce = true;
270
487
  onFirstPlay();
271
488
  }
@@ -288,21 +505,74 @@ export class CustomMediaPlayer extends Component {
288
505
  }
289
506
  }
290
507
 
508
+ createAndFireUIEvent(eventType, actionSubjectId) {
509
+ const {
510
+ type,
511
+ fileId,
512
+ isHDActive,
513
+ isHDAvailable,
514
+ isAutoPlay,
515
+ createAnalyticsEvent
516
+ } = this.props;
517
+ const {
518
+ isFullScreenEnabled,
519
+ isLargePlayer,
520
+ playbackSpeed
521
+ } = this.state;
522
+ const playbackState = { ...this.videoState,
523
+ isAutoPlay,
524
+ isHDAvailable,
525
+ isHDActive,
526
+ isFullScreenEnabled,
527
+ isLargePlayer,
528
+ playbackSpeed
529
+ };
530
+ let analyticsEvent;
531
+
532
+ switch (eventType) {
533
+ case 'mediaButtonClick':
534
+ analyticsEvent = createMediaButtonClickedEvent(type, playbackState, actionSubjectId, fileId);
535
+ break;
536
+
537
+ case 'shortcutPress':
538
+ analyticsEvent = createMediaShortcutPressedEvent(type, playbackState, actionSubjectId, fileId);
539
+ break;
540
+
541
+ case 'playPauseBlanketClick':
542
+ analyticsEvent = createPlayPauseBlanketClickedEvent(type, playbackState, fileId);
543
+ break;
544
+
545
+ case 'timeRangeNavigate':
546
+ case 'volumeRangeNavigate':
547
+ analyticsEvent = createTimeRangeNavigatedEvent(type, playbackState, actionSubjectId, fileId);
548
+ break;
549
+
550
+ case 'playbackSpeedChange':
551
+ analyticsEvent = createPlaybackSpeedChangedEvent(type, playbackState, fileId);
552
+ break;
553
+
554
+ default:
555
+ analyticsEvent = {
556
+ eventType: 'ui',
557
+ action: 'default',
558
+ actionSubject: 'customMediaPlayer',
559
+ attributes: {
560
+ type
561
+ }
562
+ };
563
+ }
564
+
565
+ fireAnalyticsEvent(analyticsEvent, createAnalyticsEvent);
566
+ }
567
+
291
568
  render() {
292
569
  const {
293
570
  type,
294
571
  src,
295
572
  isAutoPlay,
296
- isShortcutEnabled,
297
- intl: {
298
- formatMessage
299
- },
300
573
  onCanPlay,
301
574
  onError
302
575
  } = this.props;
303
- const {
304
- isFullScreenEnabled
305
- } = this.state;
306
576
  return /*#__PURE__*/React.createElement(CustomVideoWrapper, {
307
577
  innerRef: this.saveVideoWrapperRef,
308
578
  "data-testid": "custom-media-player"
@@ -315,7 +585,10 @@ export class CustomMediaPlayer extends Component {
315
585
  onTimeChange: this.onCurrentTimeChange,
316
586
  onError: onError
317
587
  }, (video, videoState, actions) => {
318
- this.setActions(actions);
588
+ this.onViewed(videoState);
589
+ this.setActions(actions); //Video State(either prop or variable) is ReadOnly
590
+
591
+ this.videoState = videoState;
319
592
  const {
320
593
  status,
321
594
  currentTime,
@@ -327,31 +600,29 @@ export class CustomMediaPlayer extends Component {
327
600
  isLargePlayer
328
601
  } = this.state;
329
602
  const isPlaying = status === 'playing';
330
- const toggleButtonIcon = isPlaying ? /*#__PURE__*/React.createElement(PauseIcon, {
331
- label: formatMessage(messages.play)
332
- }) : /*#__PURE__*/React.createElement(PlayIcon, {
333
- label: formatMessage(messages.pause)
334
- });
335
- const toggleButtonAction = isPlaying ? this.pause : this.play;
336
- const button = /*#__PURE__*/React.createElement(MediaButton, {
337
- testId: "custom-media-player-play-toggle-button",
338
- "data-test-is-playing": isPlaying,
339
- iconBefore: toggleButtonIcon,
340
- onClick: toggleButtonAction
603
+ const skipAmount = 10;
604
+
605
+ const skipBackward = () => {
606
+ const newTime = videoState.currentTime - skipAmount;
607
+ actions.navigate(Math.max(newTime, 0));
608
+ };
609
+
610
+ const skipForward = () => {
611
+ const newTime = videoState.currentTime + skipAmount;
612
+ actions.navigate(Math.min(newTime, videoState.duration));
613
+ };
614
+
615
+ const shortcuts = this.renderShortcuts({
616
+ togglePlayPauseAction: isPlaying ? this.pause : this.play,
617
+ toggleMute: actions.toggleMute,
618
+ skipBackward,
619
+ skipForward
341
620
  });
342
- const shortcuts = (isShortcutEnabled || isFullScreenEnabled) && [/*#__PURE__*/React.createElement(Shortcut, {
343
- key: "space-shortcut",
344
- keyCode: keyCodes.space,
345
- handler: this.shortcutHandler(toggleButtonAction)
346
- }), /*#__PURE__*/React.createElement(Shortcut, {
347
- key: "m-shortcut",
348
- keyCode: keyCodes.m,
349
- handler: this.shortcutHandler(actions.toggleMute)
350
- })];
351
621
  return /*#__PURE__*/React.createElement(VideoWrapper, null, /*#__PURE__*/React.createElement(WidthObserver, {
352
622
  setWidth: this.onResize
353
623
  }), shortcuts, isLoading && this.renderSpinner(), /*#__PURE__*/React.createElement(PlayPauseBlanket, {
354
- onClick: this.shortcutHandler(toggleButtonAction),
624
+ onDoubleClick: this.doubleClickToFullscreen,
625
+ onClick: isPlaying ? this.pausePlayByBlanketClick : this.startPlayByBlanketClick,
355
626
  "data-testid": "play-pause-blanket"
356
627
  }, video), /*#__PURE__*/React.createElement(ControlsWrapper, {
357
628
  className: hideControlsClassName
@@ -359,10 +630,18 @@ export class CustomMediaPlayer extends Component {
359
630
  currentTime: currentTime,
360
631
  bufferedTime: buffered,
361
632
  duration: duration,
362
- onChange: this.onTimeChange(actions.navigate)
363
- })), /*#__PURE__*/React.createElement(TimebarWrapper, null, /*#__PURE__*/React.createElement(LeftControls, null, button, this.renderVolume(videoState, actions, isLargePlayer)), /*#__PURE__*/React.createElement(RightControls, null, isLargePlayer && this.renderCurrentTime(videoState), this.renderHDButton(), this.renderSpeedControls(), this.renderFullScreenButton(), this.renderDownloadButton()))));
633
+ onChange: actions.navigate,
634
+ onChanged: this.onTimeChanged
635
+ })), /*#__PURE__*/React.createElement(TimebarWrapper, null, /*#__PURE__*/React.createElement(LeftControls, null, this.renderPlayPauseButton(isPlaying), this.renderSkipBackwardButton(skipBackward), this.renderSkipForwardButton(skipForward), this.renderVolume(videoState, actions, isLargePlayer)), /*#__PURE__*/React.createElement(RightControls, null, isLargePlayer && this.renderCurrentTime(videoState), this.renderHDButton(), this.renderSpeedControls(), this.renderFullScreenButton(), this.renderDownloadButton()))));
364
636
  }));
365
637
  }
366
638
 
367
639
  }
368
- export default injectIntl(CustomMediaPlayer);
640
+ export const CustomMediaPlayer = withMediaAnalyticsContext({
641
+ packageVersion,
642
+ packageName,
643
+ componentName: 'customMediaPlayer',
644
+ component: 'customMediaPlayer'
645
+ }, {
646
+ filterFeatureFlags: relevantFeatureFlagNames
647
+ })(withAnalyticsEvents()(injectIntl(CustomMediaPlayerBase)));
@@ -93,7 +93,8 @@ export class PlaybackSpeedControls extends Component {
93
93
  render() {
94
94
  const {
95
95
  playbackSpeed,
96
- intl
96
+ intl,
97
+ onClick
97
98
  } = this.props;
98
99
  const {
99
100
  popupHeight
@@ -142,7 +143,8 @@ export class PlaybackSpeedControls extends Component {
142
143
  }, /*#__PURE__*/React.createElement(MediaButton, {
143
144
  testId: "custom-media-player-playback-speed-toggle-button",
144
145
  buttonRef: ref,
145
- isSelected: isOpen
146
+ isSelected: isOpen,
147
+ onClick: onClick
146
148
  }, playbackSpeed, "x")),
147
149
  styles: this.popupCustomStyles,
148
150
  popperProps: popperProps
@@ -64,9 +64,17 @@ export class TimeRange extends Component {
64
64
  });
65
65
 
66
66
  _defineProperty(this, "onMouseUp", () => {
67
- // As soon as user finished dragging, we should clean up events.
67
+ const {
68
+ onChanged
69
+ } = this.props; // As soon as user finished dragging, we should clean up events.
70
+
68
71
  document.removeEventListener('mouseup', this.onMouseUp);
69
72
  document.removeEventListener('mousemove', this.onMouseMove);
73
+
74
+ if (onChanged) {
75
+ onChanged();
76
+ }
77
+
70
78
  this.setState({
71
79
  isDragging: false
72
80
  });
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useRef, useEffect } from 'react';
2
2
  import styled from 'styled-components';
3
3
  import * as exenv from 'exenv';
4
4
  const Wrapper = styled.div`
@@ -13,22 +13,28 @@ export const Ellipsify = ({
13
13
  endLength,
14
14
  inline,
15
15
  testId
16
- }) => /*#__PURE__*/React.createElement(Wrapper, {
17
- className: "ellipsed-text",
18
- innerRef: setEllipsis({
19
- lines,
20
- endLength
21
- }),
22
- "aria-label": text,
23
- inline: inline,
24
- "data-testid": testId
25
- }, text);
26
-
27
- const setEllipsis = props => element => {
28
- if (!element) {
29
- return;
30
- }
16
+ }) => {
17
+ const element = useRef(null);
18
+ useEffect(() => {
19
+ if (!element.current) {
20
+ return;
21
+ }
22
+
23
+ setEllipsis(element.current, {
24
+ lines,
25
+ endLength
26
+ });
27
+ }, [element, lines, endLength]);
28
+ return /*#__PURE__*/React.createElement(Wrapper, {
29
+ className: "ellipsed-text",
30
+ innerRef: element,
31
+ "aria-label": text,
32
+ inline: inline,
33
+ "data-testid": testId
34
+ }, text);
35
+ };
31
36
 
37
+ const setEllipsis = (element, props) => {
32
38
  const maximumLines = props.lines;
33
39
  const height = element.getBoundingClientRect().height;
34
40
  const text = element.textContent;