@desynova-digital/player 4.0.99 → 4.0.101

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.
package/actions/player.js CHANGED
@@ -302,14 +302,12 @@ function toggleFullscreen(player) {
302
302
 
303
303
  function toggleRightBar(player, showRightMenu) {
304
304
  var _right$offsetWidth;
305
- var root = document.querySelector('.player-container');
306
305
  var right = document.querySelector('.right-video-section');
307
306
  var sidebarWidth = (_right$offsetWidth = right === null || right === void 0 ? void 0 : right.offsetWidth) !== null && _right$offsetWidth !== void 0 ? _right$offsetWidth : 0; // actual width of sidebar
308
307
  // Already fullscreen → toggle UI only (NO EXIT)
309
308
  if (_fullscreen["default"].isFullscreen && right) {
310
309
  right.style.transition = 'transform 0.4s ease, opacity 0.3s ease';
311
310
  if (showRightMenu) {
312
- root.classList.add('rightbar-visible');
313
311
  // ✅ Coming from right to left (enter animation)
314
312
  right.style.display = 'block';
315
313
  right.style.right = "-".concat(sidebarWidth, "px"); // start off-screen
@@ -320,14 +318,9 @@ function toggleRightBar(player, showRightMenu) {
320
318
  right.style.opacity = '1';
321
319
  });
322
320
  } else {
323
- root.classList.remove('rightbar-visible');
324
321
  // ✅ Going left to right (exit animation)
325
322
  right.style.right = "-".concat(sidebarWidth, "px"); // start off-screen
326
323
  right.style.opacity = '0';
327
- // Hide after animation completes
328
- setTimeout(function () {
329
- right.style.display = 'none';
330
- }, 400);
331
324
  }
332
325
  return {
333
326
  type: OPERATE,
@@ -204,6 +204,8 @@ var Player = exports["default"] = /*#__PURE__*/function (_Component) {
204
204
  _classCallCheck(this, Player);
205
205
  _this = _callSuper(this, Player, [props]);
206
206
  _defineProperty(_this, "handleFullscreenFix", function () {
207
+ // Also trigger our fullscreen handler so ESC exits resize everything reliably.
208
+ _this.handleFullScreenChange();
207
209
  // Wait for fullscreen to finish layout
208
210
  requestAnimationFrame(function () {
209
211
  requestAnimationFrame(function () {
@@ -212,8 +214,13 @@ var Player = exports["default"] = /*#__PURE__*/function (_Component) {
212
214
 
213
215
  // Now trigger resize for React / your components
214
216
  window.dispatchEvent(new Event('resize'));
217
+ _this.handleResize();
215
218
  });
216
219
  });
220
+ // Final fallback in case layout changes land after the next frame
221
+ setTimeout(function () {
222
+ return _this.handleResize();
223
+ }, 120);
217
224
  });
218
225
  _defineProperty(_this, "closeSidemenu", function () {
219
226
  var _this$manager$getStat = _this.manager.getState(),
@@ -252,6 +259,8 @@ var Player = exports["default"] = /*#__PURE__*/function (_Component) {
252
259
  right.style.removeProperty('transform');
253
260
  right.style.removeProperty('opacity');
254
261
  right.style.removeProperty('right');
262
+ right.style.removeProperty('top');
263
+ right.style.removeProperty('height');
255
264
  }
256
265
 
257
266
  // Reset UI state in parent
@@ -273,6 +282,7 @@ var Player = exports["default"] = /*#__PURE__*/function (_Component) {
273
282
  _this.handleBlur = _this.handleBlur.bind(_this);
274
283
  _this.actions.handlePlayerType(props.playerType);
275
284
  _this.actions.handleControlType(props.controlType);
285
+ _this.scheduleResize = _this.scheduleResize.bind(_this);
276
286
  if (_this.props.fullScreenRef) {
277
287
  _this.props.fullScreenRef.current.player = _this;
278
288
  }
@@ -372,6 +382,7 @@ var Player = exports["default"] = /*#__PURE__*/function (_Component) {
372
382
  key: "componentDidMount",
373
383
  value: function componentDidMount() {
374
384
  this.handleResize();
385
+ this.scheduleResize();
375
386
  window.addEventListener('resize', this.handleResize);
376
387
  document.addEventListener('fullscreenchange', this.handleFullscreenFix);
377
388
  _fullscreen["default"].addEventListener(this.handleFullScreenChange);
@@ -389,6 +400,7 @@ var Player = exports["default"] = /*#__PURE__*/function (_Component) {
389
400
  activeSDBorder = _this$props2.activeSDBorder,
390
401
  activeVersion = _this$props2.activeVersion;
391
402
  this.handleResize();
403
+ this.scheduleResize();
392
404
  if (activeSDBorder !== prevProps.activeSDBorder) {
393
405
  this.actions.handleSDBorderChange(activeSDBorder || false);
394
406
  }
@@ -945,10 +957,19 @@ var Player = exports["default"] = /*#__PURE__*/function (_Component) {
945
957
  if (player.isFullscreen) return;
946
958
  this.actions.activate(false);
947
959
  }
960
+ }, {
961
+ key: "scheduleResize",
962
+ value: function scheduleResize() {
963
+ var _this5 = this;
964
+ // Some child elements finish layout on the next frame; ensure resize runs after paint.
965
+ requestAnimationFrame(function () {
966
+ _this5.handleResize();
967
+ });
968
+ }
948
969
  }, {
949
970
  key: "render",
950
971
  value: function render() {
951
- var _this5 = this,
972
+ var _this6 = this,
952
973
  _props$player;
953
974
  var _this$manager$getStat4 = this.manager.getState(),
954
975
  player = _this$manager$getStat4.player;
@@ -968,16 +989,18 @@ var Player = exports["default"] = /*#__PURE__*/function (_Component) {
968
989
  isRightMenuVisible = _this$props7.isRightMenuVisible;
969
990
  return /*#__PURE__*/_react["default"].createElement(PlayerBlock, {
970
991
  ref: function ref(c) {
971
- _this5.manager.rootElement = c;
992
+ _this6.manager.rootElement = c;
972
993
  },
973
994
  role: "region",
974
995
  onFocus: this.handleFocus,
975
996
  onBlur: this.handleBlur,
976
997
  tabIndex: "-1"
977
- }, /*#__PURE__*/_react["default"].createElement(PlayerContainer, _extends({
978
- className: "player-container ".concat(isFullscreen ? 'fullscreen-left-only' : ''),
998
+ }, /*#__PURE__*/_react["default"].createElement(PlayerContainer
999
+ // className={`player-container ${isFullscreen ? 'fullscreen-left-only' : ''}`}
1000
+ , _extends({
1001
+ className: "player-container",
979
1002
  ref: function ref(playerContainer) {
980
- _this5._playerContainer = playerContainer;
1003
+ _this6._playerContainer = playerContainer;
981
1004
  }
982
1005
  }, props, {
983
1006
  hasRightSection: !!rightSection,
@@ -986,16 +1009,16 @@ var Player = exports["default"] = /*#__PURE__*/function (_Component) {
986
1009
  }), /*#__PURE__*/_react["default"].createElement("div", {
987
1010
  className: "left-video-section",
988
1011
  ref: function ref(leftSectionRef) {
989
- _this5._leftSectionRef = leftSectionRef;
1012
+ _this6._leftSectionRef = leftSectionRef;
990
1013
  }
991
1014
  }, childrensLeft), /*#__PURE__*/_react["default"].createElement("div", {
992
1015
  className: "audio-meter-block ".concat(playerType),
993
1016
  ref: function ref(audioMeterBlock) {
994
- _this5._audioMeterBlock = audioMeterBlock;
1017
+ _this6._audioMeterBlock = audioMeterBlock;
995
1018
  }
996
1019
  }, /*#__PURE__*/_react["default"].createElement(AudioMeterBlock, {
997
1020
  onClick: function onClick() {
998
- _this5.meterBlockClick();
1021
+ _this6.meterBlockClick();
999
1022
  },
1000
1023
  role: "presentation",
1001
1024
  active: true
@@ -1005,18 +1028,18 @@ var Player = exports["default"] = /*#__PURE__*/function (_Component) {
1005
1028
  }))), rightSection ? /*#__PURE__*/_react["default"].createElement("div", {
1006
1029
  className: "right-video-section",
1007
1030
  ref: function ref(rightSectionRef) {
1008
- _this5._rightSectionRef = rightSectionRef;
1031
+ _this6._rightSectionRef = rightSectionRef;
1009
1032
  }
1010
1033
  }, rightSection) : null), props.controlType === 'advanced' ? /*#__PURE__*/_react["default"].createElement(ControlContainer, {
1011
1034
  ref: function ref(advancedControl) {
1012
- _this5._advancedControl = advancedControl;
1035
+ _this6._advancedControl = advancedControl;
1013
1036
  }
1014
1037
  }, /*#__PURE__*/_react["default"].createElement(_ProgressControl["default"], _extends({}, props, {
1015
1038
  key: "progress-control",
1016
1039
  order: 1
1017
1040
  }))) : /*#__PURE__*/_react["default"].createElement(_Playlist["default"], _extends({
1018
1041
  ref: function ref(c) {
1019
- _this5._playlist = c;
1042
+ _this6._playlist = c;
1020
1043
  },
1021
1044
  key: "playlist",
1022
1045
  order: 5
@@ -836,10 +836,14 @@ var Shortcut = exports["default"] = /*#__PURE__*/function (_Component) {
836
836
  playbackRate = 4;
837
837
  } else if (playbackRate >= 1.5) {
838
838
  playbackRate = 2;
839
- } else if (playbackRate >= 1) {
839
+ } else if (playbackRate >= 1.25) {
840
840
  playbackRate = 1.5;
841
- } else if (playbackRate >= 0.5) {
841
+ } else if (playbackRate >= 1.) {
842
+ playbackRate = 1.25;
843
+ } else if (playbackRate >= 0.75) {
842
844
  playbackRate = 1.0;
845
+ } else if (playbackRate >= 0.5) {
846
+ playbackRate = 0.75;
843
847
  }
844
848
  /*
845
849
  * else if (playbackRate >= 1.25) {
@@ -107,10 +107,12 @@ var defaultProps = {
107
107
  var SubTitleSection = _styledComponents["default"].div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: absolute;\n font-family: SFUIText-Regular;\n font-size: 16px;\n bottom: 20px;\n width: 100%;\n display: flex;\n justify-content: center;\n text-align: center;\n color: #ffffff;\n height: 90%;\n align-items: center;\n\n .subtitleContainer {\n border-radius: 4px;\n width: fit-content;\n background: #000000;\n opacity: 0.9;\n padding: ", ";\n line-height: 20px;\n position: absolute;\n\n i,\n em {\n font-style: italic; /* Override the font style for <em> tags inside elements with the class .someClass */\n }\n\n strong {\n font-weight: bold;\n }\n }\n .longSubtitleStyles {\n overflow-y: auto;\n height: fit-content;\n max-height: 70px;\n max-width: 75%;\n width: fit-content;\n }\n"])), function (props) {
108
108
  return props.currentSubtitleObj && props.currentSubtitleObj.line1 ? '8px 10px' : '0px';
109
109
  });
110
- var VideoBlock = _styledComponents["default"].div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n position: relative;\n &.video-react-player-block {\n position: relative;\n transition: all 0.1s ease-in-out;\n -moz-transition: all 0.1s ease-in-out;\n -webkit-transition: all 0.1s ease-in-out;\n -ms-transition: all 0.1s ease-in-out;\n -o-transition: all 0.1s ease-in-out;\n ", "\n video {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n right: 0;\n bottom: 0;\n }\n .audio-tracks {\n position: relative;\n display: flex;\n background: rgba(0, 0, 0, 0.5);\n color: #fff;\n z-index: 10;\n position: absolute;\n width: 100%;\n bottom: 0;\n p {\n cursor: pointer;\n padding: 10px;\n }\n }\n .loader-container {\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n z-index: 10;\n background: rgba(0, 0, 0, 0.5);\n }\n }\n &.ratio-border {\n // border: 1px solid rgba(255, 255, 255, 0.5);\n &:after {\n content: ", ";\n position: absolute;\n color: #fff;\n font-family: SFUIText-Regular;\n font-size: 12px;\n transform: rotate(-90deg);\n top: 20%;\n left: -50px;\n }\n }\n"])), function (props) {
110
+ var VideoBlock = _styledComponents["default"].div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n position: relative;\n &.video-react-player-block {\n position: relative;\n transition: all 0.1s ease-in-out;\n -moz-transition: all 0.1s ease-in-out;\n -webkit-transition: all 0.1s ease-in-out;\n -ms-transition: all 0.1s ease-in-out;\n -o-transition: all 0.1s ease-in-out;\n ", "\n video {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n right: 0;\n bottom: 0;\n }\n .audio-tracks {\n position: relative;\n display: flex;\n background: rgba(0, 0, 0, 0.5);\n color: #fff;\n z-index: 10;\n position: absolute;\n width: 100%;\n bottom: 0;\n p {\n cursor: pointer;\n padding: 10px;\n }\n }\n .loader-container {\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n position: absolute;\n z-index: 10;\n background: rgba(0, 0, 0, 0.5);\n }\n }\n &.ratio-border {\n // border: 1px solid rgba(255, 255, 255, 0.5);\n &:after {\n content: ", ";\n position: absolute;\n color: #fff;\n font-family: SFUIText-Regular;\n font-size: 12px;\n transform: rotate(-90deg);\n top: 20%;\n left: ", ";\n }\n }\n"])), function (props) {
111
111
  return props.svgLayerActive && "\n pointer-events: none;\n video {\n pointer-events: none;\n }\n ";
112
112
  }, function (props) {
113
113
  return props.HDBorder ? '"16:9 Safe Area"' : '';
114
+ }, function (props) {
115
+ return props.isFullScreen && props.isRightMenuVisible ? '-30px' : '-50px';
114
116
  });
115
117
  var Video = exports["default"] = /*#__PURE__*/function (_Component) {
116
118
  function Video(props) {
@@ -51,7 +51,7 @@ var ProgressControlBlock = _styledComponents["default"].div(_templateObject || (
51
51
  var markers = _ref.markers;
52
52
  return markers.length > 3 ? '40px' : '23px';
53
53
  });
54
- var SeekControlBar = _styledComponents["default"].div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n width: 100%;\n height: 100%;\n position: relative;\n cursor: ", ";\n overflow: hidden;\n z-index: ", ";\n .timeline-content {\n overflow-x: ", ";\n white-space: nowrap;\n }\n .hide-scrollbar {\n /* Hide scrollbar for Webkit-based browsers (Chrome, Safari, Edge) */\n scrollbar-width: none; /* Hides scrollbar in Firefox */\n -ms-overflow-style: none; /* Hides scrollbar in IE 10+ */\n }\n\n .hide-scrollbar::-webkit-scrollbar {\n width: 0; /* Removes the scrollbar for Webkit browsers */\n }\n\n .scrollBarVisibility\n max-height: 65px;\n overflow-y: visible;\n scrollbar-width: none; /* Hides scrollbar in Firefox */\n -ms-overflow-style: none; /* Hides scrollbar in Internet Explorer 10+ */\n\n /* Hides scrollbar for Webkit-based browsers (Chrome, Safari, Edge) */\n &::-webkit-scrollbar {\n width: 0;\n }\n"])), function (props) {
54
+ var SeekControlBar = _styledComponents["default"].div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n width: 100%;\n height: 100%;\n position: relative;\n cursor: ", ";\n overflow: hidden;\n z-index: ", ";\n .timeline-content {\n overflow-x: ", ";\n white-space: nowrap;\n }\n .hide-scrollbar {\n /* Hide scrollbar for Webkit-based browsers (Chrome, Safari, Edge) */\n scrollbar-width: none; /* Hides scrollbar in Firefox */\n -ms-overflow-style: none; /* Hides scrollbar in IE 10+ */\n }\n\n .hide-scrollbar::-webkit-scrollbar {\n width: 0; /* Removes the scrollbar for Webkit browsers */\n }\n\n .scrollBarVisibility {\n max-height: 65px;\n overflow-y: visible;\n scrollbar-width: none; /* Hides scrollbar in Firefox */\n -ms-overflow-style: none; /* Hides scrollbar in Internet Explorer 10+ */\n\n /* Hides scrollbar for Webkit-based browsers (Chrome, Safari, Edge) */\n &::-webkit-scrollbar {\n width: 0;\n }\n }\n"])), function (props) {
55
55
  return props.isFullscreen ? 'default' : 'pointer';
56
56
  }, function (props) {
57
57
  return props.controlType === 'advanced' && !props.isFullscreen ? '2' : '1';
@@ -73,6 +73,7 @@ var ScrollStyledDiv = _styledComponents["default"].div(_templateObject4 || (_tem
73
73
  var CoverDiv = _styledComponents["default"].div(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n background-color: black;\n z-index: 2;\n position: absolute;\n height: 60px;\n width: 89px;\n left: 0px;\n top: 20px;\n"])));
74
74
  var ProgressControl = exports["default"] = /*#__PURE__*/function (_Component) {
75
75
  function ProgressControl(props, context) {
76
+ var _props$player$zoom, _props$player;
76
77
  var _this;
77
78
  _classCallCheck(this, ProgressControl);
78
79
  _this = _callSuper(this, ProgressControl, [props, context]);
@@ -85,16 +86,24 @@ var ProgressControl = exports["default"] = /*#__PURE__*/function (_Component) {
85
86
  mouseTime: {
86
87
  time: null,
87
88
  position: 0,
88
- stateZoom: null
89
+ stateZoom: (_props$player$zoom = props === null || props === void 0 || (_props$player = props.player) === null || _props$player === void 0 ? void 0 : _props$player.zoom) !== null && _props$player$zoom !== void 0 ? _props$player$zoom : null
89
90
  }
90
91
  };
91
92
  _this.parentScrollDivRef = /*#__PURE__*/(0, _react.createRef)();
92
93
  _this.handleMouseMoveThrottle = _this.handleMouseMove.bind(_this);
93
94
  _this.handleSeekbarZoom = _this.handleSeekbarZoom.bind(_this);
95
+ _this.ensureInitialSizing = _this.ensureInitialSizing.bind(_this);
96
+ _this.forceLayoutAdjust = _this.forceLayoutAdjust.bind(_this);
94
97
  return _this;
95
98
  }
96
99
  _inherits(ProgressControl, _Component);
97
100
  return _createClass(ProgressControl, [{
101
+ key: "componentDidMount",
102
+ value: function componentDidMount() {
103
+ this.ensureInitialSizing();
104
+ this.forceLayoutAdjust();
105
+ }
106
+ }, {
98
107
  key: "componentDidUpdate",
99
108
  value: function componentDidUpdate() {
100
109
  var _this$props = this.props,
@@ -102,19 +111,36 @@ var ProgressControl = exports["default"] = /*#__PURE__*/function (_Component) {
102
111
  zoom = _this$props$player.zoom,
103
112
  readyState = _this$props$player.readyState,
104
113
  isFullscreen = _this$props$player.isFullscreen,
114
+ duration = _this$props$player.duration,
105
115
  controlType = _this$props.controlType;
116
+ var prevDuration = this.prevDuration;
117
+ this.prevDuration = duration;
106
118
  var stateZoom = this.state.stateZoom;
107
119
  if (zoom !== stateZoom && readyState === 4 && controlType === 'advanced' && !isFullscreen) {
108
120
  this.handleSeekbarZoom();
109
121
  }
122
+
123
+ // If duration became available after mount, ensure layout is sized.
124
+ if (readyState >= 1 && this.state.stateZoom === null) {
125
+ this.ensureInitialSizing();
126
+ }
127
+ if (duration && duration !== prevDuration) {
128
+ this.forceLayoutAdjust();
129
+ }
110
130
  }
111
131
  }, {
112
132
  key: "handleSeekbarZoom",
113
133
  value: function handleSeekbarZoom() {
114
- var zoom = this.props.player.zoom;
134
+ var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
135
+ var _this$props$player2 = this.props.player,
136
+ zoom = _this$props$player2.zoom,
137
+ readyState = _this$props$player2.readyState;
138
+ if (!force && readyState !== 4) {
139
+ return;
140
+ }
115
141
  var progressBlock = (0, _reactDom.findDOMNode)(this.progressControlBlock);
116
142
  var seekBarBlock = (0, _reactDom.findDOMNode)(this.seekControlBar);
117
- var currentZoom = parseFloat(zoom.toFixed(1));
143
+ var currentZoom = parseFloat((zoom || 0).toFixed(1));
118
144
 
119
145
  // To be Rectified
120
146
  if (this.seekBar.timeline) {
@@ -126,6 +152,55 @@ var ProgressControl = exports["default"] = /*#__PURE__*/function (_Component) {
126
152
  });
127
153
  }
128
154
  }
155
+ }, {
156
+ key: "ensureInitialSizing",
157
+ value: function ensureInitialSizing() {
158
+ var _this2 = this;
159
+ var _this$props$player3 = this.props.player,
160
+ zoom = _this$props$player3.zoom,
161
+ duration = _this$props$player3.duration;
162
+ if (!duration) return;
163
+ // First attempt on next paint
164
+ requestAnimationFrame(function () {
165
+ return _this2.handleSeekbarZoom(true);
166
+ });
167
+ // Fallback after layout settles
168
+ setTimeout(function () {
169
+ return _this2.handleSeekbarZoom(true);
170
+ }, 60);
171
+ }
172
+ }, {
173
+ key: "forceLayoutAdjust",
174
+ value: function forceLayoutAdjust() {
175
+ var _this$seekBar,
176
+ _this$pointersBar,
177
+ _this$seekBar2,
178
+ _this3 = this;
179
+ var attempt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
180
+ var _this$props$player4 = this.props.player,
181
+ zoom = _this$props$player4.zoom,
182
+ duration = _this$props$player4.duration;
183
+ if (!duration) return;
184
+ var currentZoom = parseFloat((zoom || 0).toFixed(1));
185
+ if ((_this$seekBar = this.seekBar) !== null && _this$seekBar !== void 0 && _this$seekBar.timeline) {
186
+ this.seekBar.timeline.generateTimeline(currentZoom);
187
+ }
188
+ if ((_this$pointersBar = this.pointersBar) !== null && _this$pointersBar !== void 0 && _this$pointersBar.generateZoomWithOfPointersBar) {
189
+ this.pointersBar.generateZoomWithOfPointersBar(currentZoom);
190
+ }
191
+ if (typeof ((_this$seekBar2 = this.seekBar) === null || _this$seekBar2 === void 0 ? void 0 : _this$seekBar2.scrollToSeekbarMiddle) === 'function') {
192
+ this.seekBar.scrollToSeekbarMiddle();
193
+ }
194
+ // Retry a few times while layout stabilizes to avoid needing a user click.
195
+ if (attempt < 4) {
196
+ requestAnimationFrame(function () {
197
+ return _this3.forceLayoutAdjust(attempt + 1);
198
+ });
199
+ setTimeout(function () {
200
+ return _this3.forceLayoutAdjust(attempt + 1);
201
+ }, 80);
202
+ }
203
+ }
129
204
  }, {
130
205
  key: "handleMouseMove",
131
206
  value: function handleMouseMove(event) {
@@ -146,7 +221,7 @@ var ProgressControl = exports["default"] = /*#__PURE__*/function (_Component) {
146
221
  }, {
147
222
  key: "render",
148
223
  value: function render() {
149
- var _this2 = this;
224
+ var _this4 = this;
150
225
  var _this$props2 = this.props,
151
226
  controlType = _this$props2.controlType,
152
227
  playerType = _this$props2.playerType,
@@ -168,7 +243,7 @@ var ProgressControl = exports["default"] = /*#__PURE__*/function (_Component) {
168
243
  isFullscreen: isFullscreen,
169
244
  markers: markers,
170
245
  ref: function ref(c) {
171
- _this2.progressControlBlock = c;
246
+ _this4.progressControlBlock = c;
172
247
  }
173
248
  }, playerType == 'default' && /*#__PURE__*/_react["default"].createElement(_MarkerBar["default"], _extends({}, this.props, {
174
249
  zoom: zoom
@@ -186,7 +261,7 @@ var ProgressControl = exports["default"] = /*#__PURE__*/function (_Component) {
186
261
  className: "empty-block"
187
262
  })))) : null, /*#__PURE__*/_react["default"].createElement(SeekControlBar, {
188
263
  ref: function ref(c) {
189
- _this2.seekControlBar = c;
264
+ _this4.seekControlBar = c;
190
265
  },
191
266
  id: "seekbar-control-block",
192
267
  zoom: stateZoom && parseFloat(stateZoom.toFixed(1)),
@@ -197,7 +272,7 @@ var ProgressControl = exports["default"] = /*#__PURE__*/function (_Component) {
197
272
  }, /*#__PURE__*/_react["default"].createElement(_SeekBar["default"], _extends({
198
273
  mouseTime: mouseTime,
199
274
  ref: function ref(c) {
200
- _this2.seekBar = c;
275
+ _this4.seekBar = c;
201
276
  },
202
277
  zoom: stateZoom && parseFloat(stateZoom.toFixed(1))
203
278
  }, this.props)), /*#__PURE__*/_react["default"].createElement("div", {
@@ -206,7 +281,7 @@ var ProgressControl = exports["default"] = /*#__PURE__*/function (_Component) {
206
281
  onScroll: this.handleChildScroll,
207
282
  theme: theme,
208
283
  ref: function ref(c) {
209
- _this2.pointersBar = c;
284
+ _this4.pointersBar = c;
210
285
  },
211
286
  zoom: stateZoom && parseFloat(stateZoom.toFixed(1))
212
287
  }, this.props))))), controlType === 'advanced' && !isFullscreen ? /*#__PURE__*/_react["default"].createElement(MarkerTagsBlock, null, /*#__PURE__*/_react["default"].createElement("div", {
@@ -125,19 +125,36 @@ var SeekBar = exports["default"] = /*#__PURE__*/function (_Component) {
125
125
  };
126
126
  _this.hoverBoxRef = /*#__PURE__*/_react["default"].createRef();
127
127
  _this.hoverImageRef = /*#__PURE__*/_react["default"].createRef();
128
+ _this.ensureInitialScroll = _this.ensureInitialScroll.bind(_this);
129
+ _this.observeSeekbar = _this.observeSeekbar.bind(_this);
130
+ _this.disconnectObserver = _this.disconnectObserver.bind(_this);
131
+ _this.lastObservedWidth = 0;
128
132
  return _this;
129
133
  }
130
134
  _inherits(SeekBar, _Component);
131
135
  return _createClass(SeekBar, [{
132
136
  key: "componentDidMount",
133
- value: function componentDidMount() {}
137
+ value: function componentDidMount() {
138
+ this.ensureInitialScroll();
139
+ this.observeSeekbar();
140
+ }
134
141
  }, {
135
142
  key: "componentDidUpdate",
136
143
  value: function componentDidUpdate(prevProps) {
137
- var _prevProps$player, _this$props$player;
138
- if (((_prevProps$player = prevProps.player) === null || _prevProps$player === void 0 ? void 0 : _prevProps$player.currentTime) !== ((_this$props$player = this.props.player) === null || _this$props$player === void 0 ? void 0 : _this$props$player.currentTime)) {
144
+ var _prevProps$player, _this$props$player, _prevProps$player2, _this$props$player2;
145
+ var durationChanged = ((_prevProps$player = prevProps.player) === null || _prevProps$player === void 0 ? void 0 : _prevProps$player.duration) !== ((_this$props$player = this.props.player) === null || _this$props$player === void 0 ? void 0 : _this$props$player.duration);
146
+ var zoomChanged = prevProps.zoom !== this.props.zoom;
147
+ if (((_prevProps$player2 = prevProps.player) === null || _prevProps$player2 === void 0 ? void 0 : _prevProps$player2.currentTime) !== ((_this$props$player2 = this.props.player) === null || _this$props$player2 === void 0 ? void 0 : _this$props$player2.currentTime) || durationChanged || zoomChanged) {
139
148
  this.scrollToSeekbarMiddle();
140
149
  }
150
+ if (durationChanged || zoomChanged) {
151
+ this.ensureInitialScroll();
152
+ }
153
+ }
154
+ }, {
155
+ key: "componentWillUnmount",
156
+ value: function componentWillUnmount() {
157
+ this.disconnectObserver();
141
158
  }
142
159
 
143
160
  /**
@@ -146,14 +163,52 @@ var SeekBar = exports["default"] = /*#__PURE__*/function (_Component) {
146
163
  * @return {Number} Percentage played
147
164
  * @method getPercent
148
165
  */
166
+ }, {
167
+ key: "ensureInitialScroll",
168
+ value: function ensureInitialScroll() {
169
+ var _this2 = this;
170
+ // Align viewport after layout; helps first render where timeline width is 0 until paint.
171
+ requestAnimationFrame(function () {
172
+ return _this2.scrollToSeekbarMiddle();
173
+ });
174
+ setTimeout(function () {
175
+ return _this2.scrollToSeekbarMiddle();
176
+ }, 60);
177
+ }
178
+ }, {
179
+ key: "observeSeekbar",
180
+ value: function observeSeekbar() {
181
+ var _this3 = this;
182
+ var seekbar = document.getElementById('seekbar-control-block');
183
+ if (!seekbar || typeof ResizeObserver === 'undefined') return;
184
+ this.disconnectObserver();
185
+ this.seekbarObserver = new ResizeObserver(function (entries) {
186
+ var _entry$contentRect;
187
+ var entry = entries[0];
188
+ var width = (entry === null || entry === void 0 || (_entry$contentRect = entry.contentRect) === null || _entry$contentRect === void 0 ? void 0 : _entry$contentRect.width) || 0;
189
+ if (width > 0 && width !== _this3.lastObservedWidth) {
190
+ _this3.lastObservedWidth = width;
191
+ _this3.scrollToSeekbarMiddle();
192
+ }
193
+ });
194
+ this.seekbarObserver.observe(seekbar);
195
+ }
196
+ }, {
197
+ key: "disconnectObserver",
198
+ value: function disconnectObserver() {
199
+ if (this.seekbarObserver) {
200
+ this.seekbarObserver.disconnect();
201
+ this.seekbarObserver = null;
202
+ }
203
+ }
149
204
  }, {
150
205
  key: "getPercent",
151
206
  value: function getPercent() {
152
207
  var _this$props = this.props,
153
- _this$props$player2 = _this$props.player,
154
- currentTime = _this$props$player2.currentTime,
155
- seekingTime = _this$props$player2.seekingTime,
156
- duration = _this$props$player2.duration,
208
+ _this$props$player3 = _this$props.player,
209
+ currentTime = _this$props$player3.currentTime,
210
+ seekingTime = _this$props$player3.seekingTime,
211
+ duration = _this$props$player3.duration,
157
212
  zoom = _this$props.zoom;
158
213
  var time = seekingTime || currentTime;
159
214
  var percent = time / duration;
@@ -198,13 +253,18 @@ var SeekBar = exports["default"] = /*#__PURE__*/function (_Component) {
198
253
  }, {
199
254
  key: "scrollToSeekbarMiddle",
200
255
  value: function scrollToSeekbarMiddle() {
201
- var viewportWidth = document.getElementById('seekbar-control-block').clientWidth;
256
+ var seekbarEl = document.getElementById('seekbar-control-block');
257
+ var timelineEl = document.getElementsByClassName('timeline-content')[0];
258
+ if (!seekbarEl || !timelineEl) return;
259
+ var viewportWidth = seekbarEl.clientWidth || seekbarEl.getBoundingClientRect().width;
260
+ if (!viewportWidth) return;
202
261
  var percentScroll = (this.getPercent() * 100).toFixed(2) / 100;
203
262
  var scrollWidth = viewportWidth * percentScroll;
204
- if (scrollWidth < document.getElementsByClassName('timeline-content')[0].scrollLeft || scrollWidth > document.getElementsByClassName('timeline-content')[0].scrollLeft + viewportWidth) {
263
+ if (timelineEl.scrollLeft === undefined) return;
264
+ if (scrollWidth < timelineEl.scrollLeft || scrollWidth > timelineEl.scrollLeft + viewportWidth) {
205
265
  viewportWidth = viewportWidth / 2;
206
266
  scrollWidth = scrollWidth - viewportWidth;
207
- document.getElementsByClassName('timeline-content')[0].scrollTo({
267
+ timelineEl.scrollTo({
208
268
  left: scrollWidth,
209
269
  behavior: 'instant'
210
270
  });
@@ -265,7 +325,7 @@ var SeekBar = exports["default"] = /*#__PURE__*/function (_Component) {
265
325
  }, {
266
326
  key: "render",
267
327
  value: function render() {
268
- var _this2 = this;
328
+ var _this4 = this;
269
329
  var _this$props3 = this.props,
270
330
  _this$props3$player = _this$props3.player,
271
331
  currentTime = _this$props3$player.currentTime,
@@ -286,8 +346,8 @@ var SeekBar = exports["default"] = /*#__PURE__*/function (_Component) {
286
346
  style: this.returnStyle(playerType),
287
347
  onMouseDown: this.handleMouseDown,
288
348
  onMouseMove: function onMouseMove(e) {
289
- _this2.handleMouseMove(e); // existing seeking
290
- _this2.handleHoverScrub(e); // NEW preview scrub
349
+ _this4.handleMouseMove(e); // existing seeking
350
+ _this4.handleHoverScrub(e); // NEW preview scrub
291
351
  },
292
352
  onMouseUp: this.handleMouseUp,
293
353
  onMouseEnter: this.showHoverPreview,
@@ -303,7 +363,7 @@ var SeekBar = exports["default"] = /*#__PURE__*/function (_Component) {
303
363
  isFullscreen: isFullscreen
304
364
  }, /*#__PURE__*/_react["default"].createElement(_Slider["default"], _extends({}, this.props, {
305
365
  ref: function ref(input) {
306
- _this2.slider = input;
366
+ _this4.slider = input;
307
367
  },
308
368
  label: "video progress bar",
309
369
  valuenow: (this.getPercent() * 100).toFixed(2),
@@ -322,10 +382,10 @@ var SeekBar = exports["default"] = /*#__PURE__*/function (_Component) {
322
382
  assetType: assetType
323
383
  }, this.props)))), controlType === 'advanced' && !isFullscreen ? /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(AdvancedControlBlock, null, /*#__PURE__*/_react["default"].createElement(_Timeline["default"], _extends({}, this.props, {
324
384
  scrollSeekBar: function scrollSeekBar() {
325
- return _this2.scrollToSeekbarMiddle();
385
+ return _this4.scrollToSeekbarMiddle();
326
386
  },
327
387
  ref: function ref(c) {
328
- _this2.timeline = c;
388
+ _this4.timeline = c;
329
389
  },
330
390
  zoomFactor: zoom
331
391
  })))) : null));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@desynova-digital/player",
3
- "version": "4.0.99",
3
+ "version": "4.0.101",
4
4
  "description": "Video Player Package for Contido Application",
5
5
  "main": "index.js",
6
6
  "scripts": {