box-content-preview 3.105.0 → 3.107.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.
package/dist/lib/index.js CHANGED
@@ -424,7 +424,7 @@ class PreviewError extends Error {
424
424
  /* harmony export */ zb: () => (/* binding */ CLASS_DOC_FIRST_IMAGE),
425
425
  /* harmony export */ ze: () => (/* binding */ STATUS_PENDING)
426
426
  /* harmony export */ });
427
- /* unused harmony exports CLASS_ACTIVE, CLASS_BOX_PREVIEW, CLASS_BOX_PREVIEW_CONTAINER, CLASS_BOX_PREVIEW_HEADER_CONTAINER, CLASS_BOX_PREVIEW_ICON, CLASS_BOX_PREVIEW_LOGO_CUSTOM, CLASS_BOX_PREVIEW_LOGO_DEFAULT, CLASS_PREFETCHED_IMAGE, SELECTOR_BOX_PREVIEW_HEADER, SELECTOR_BOX_PREVIEW_NOTIFICATION */
427
+ /* unused harmony exports CLASS_ACTIVE, CLASS_BOX_PREVIEW, CLASS_BOX_PREVIEW_CONTAINER, CLASS_BOX_PREVIEW_HEADER_CONTAINER, CLASS_BOX_PREVIEW_ICON, CLASS_BOX_PREVIEW_LOGO_CUSTOM, CLASS_BOX_PREVIEW_LOGO_DEFAULT, CLASS_BOX_PREVIEW_VERSION_BANNER, CLASS_BOX_PREVIEW_VERSION_BANNER_COMPARED, CLASS_PREFETCHED_IMAGE, SELECTOR_BOX_PREVIEW_VERSION_BANNER, SELECTOR_BOX_PREVIEW_HEADER, SELECTOR_BOX_PREVIEW_NOTIFICATION */
428
428
  const CLASS_ACTIVE = 'bp-is-active';
429
429
  const CLASS_ANNOTATIONS_CREATE_DRAWING = 'bp-annotations-create--drawing';
430
430
  const CLASS_ANNOTATIONS_CREATE_HIGHLIGHT = 'bp-annotations-create--highlight';
@@ -453,6 +453,8 @@ const CLASS_BOX_PREVIEW_LOGO_CUSTOM = 'bp-custom-logo';
453
453
  const CLASS_BOX_PREVIEW_LOGO_DEFAULT = 'bp-default-logo';
454
454
  const CLASS_BOX_PREVIEW_MENU = 'bp-menu';
455
455
  const CLASS_BOX_PREVIEW_MOBILE = 'bp-is-mobile';
456
+ const CLASS_BOX_PREVIEW_VERSION_BANNER = 'bp-version-banner';
457
+ const CLASS_BOX_PREVIEW_VERSION_BANNER_COMPARED = 'bp-version-banner--compared';
456
458
  const CLASS_BOX_PREVIEW_OVERLAY = 'bp-overlay';
457
459
  const CLASS_BOX_PREVIEW_OVERLAY_WRAPPER = 'bp-overlay-wrapper';
458
460
  const CLASS_BOX_PREVIEW_PRELOAD = 'bp-preload';
@@ -492,6 +494,7 @@ const DISCOVERABILITY_ATTRIBUTE = 'data-resin-discoverability';
492
494
  const SELECTOR_BOX_PREVIEW_CONTAINER = `.${CLASS_BOX_PREVIEW_CONTAINER}`;
493
495
  const SELECTOR_BOX_PREVIEW = `.${CLASS_BOX_PREVIEW}`;
494
496
  const SELECTOR_BOX_PREVIEW_CONTENT = `.${CLASS_BOX_PREVIEW_CONTENT}`;
497
+ const SELECTOR_BOX_PREVIEW_VERSION_BANNER = (/* unused pure expression or super */ null && (`.${CLASS_BOX_PREVIEW_VERSION_BANNER}`));
495
498
  const SELECTOR_NAVIGATION_LEFT = '.bp-navigate-left';
496
499
  const SELECTOR_NAVIGATION_RIGHT = '.bp-navigate-right';
497
500
  const SELECTOR_BOX_PREVIEW_BTN_ANNOTATE_POINT = '.bp-btn-annotate-point';
@@ -1029,7 +1032,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1029
1032
  const CLIENT_NAME = "box-content-preview"; // eslint-disable-line no-undef
1030
1033
  const CLIENT_NAME_KEY = 'box_client_name';
1031
1034
  const CLIENT_VERSION_KEY = 'box_client_version';
1032
- const CLIENT_VERSION = "3.105.0"; // eslint-disable-line no-undef
1035
+ const CLIENT_VERSION = "3.107.0"; // eslint-disable-line no-undef
1033
1036
  const HEADER_CLIENT_NAME = 'X-Box-Client-Name';
1034
1037
  const HEADER_CLIENT_VERSION = 'X-Box-Client-Version';
1035
1038
  const PROMISE_MAP = {};
@@ -3698,21 +3701,29 @@ function eventTargetElement(target) {
3698
3701
  * Optimistic comment-badge selection that clears on pointerdown outside the
3699
3702
  * selected avatar or its cluster. Host `hostSelectedId` can restore a different
3700
3703
  * id; acking the dismissed id must not bring the ring back.
3704
+ * A new `selectionSeq` is the user picking that same comment again, so the ring returns.
3701
3705
  */
3702
- function useDismissableMarkerSelection(hostSelectedId = null) {
3706
+ function useDismissableMarkerSelection(hostSelectedId = null, selectionSeq = null) {
3703
3707
  const containerRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
3704
3708
  const dismissedIdRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
3709
+ const appliedSeqRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
3705
3710
  const [optimisticSelectedId, setOptimisticSelectedId] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
3706
3711
  const [isSelectionDismissed, setIsSelectionDismissed] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
3707
3712
  const selectedId = optimisticSelectedId ?? (isSelectionDismissed ? null : hostSelectedId);
3708
3713
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
3709
3714
  setOptimisticSelectedId(null);
3715
+ if (selectionSeq != null && selectionSeq !== appliedSeqRef.current) {
3716
+ appliedSeqRef.current = selectionSeq;
3717
+ dismissedIdRef.current = null;
3718
+ setIsSelectionDismissed(false);
3719
+ return;
3720
+ }
3710
3721
  if (dismissedIdRef.current && hostSelectedId === dismissedIdRef.current) {
3711
3722
  return;
3712
3723
  }
3713
3724
  dismissedIdRef.current = null;
3714
3725
  setIsSelectionDismissed(false);
3715
- }, [hostSelectedId]);
3726
+ }, [hostSelectedId, selectionSeq]);
3716
3727
  const selectMarker = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(id => {
3717
3728
  dismissedIdRef.current = null;
3718
3729
  setIsSelectionDismissed(false);
@@ -4807,6 +4818,8 @@ function morphPeaks(from, to, elapsedMs) {
4807
4818
  }
4808
4819
  // EXTERNAL MODULE: ./src/lib/viewers/media/waveform/viewport.ts
4809
4820
  var waveform_viewport = __webpack_require__(772);
4821
+ // EXTERNAL MODULE: ./src/lib/viewers/media/waveform/range.ts
4822
+ var waveform_range = __webpack_require__(4253);
4810
4823
  // EXTERNAL MODULE: ./src/lib/viewers/media/waveform/useTapeWaveform.ts
4811
4824
  var useTapeWaveform = __webpack_require__(7308);
4812
4825
  // EXTERNAL MODULE: ./node_modules/classnames/index.js
@@ -4873,6 +4886,7 @@ function WaveformCommentMarkers({
4873
4886
  isTape = false,
4874
4887
  onCommentMarkerClick,
4875
4888
  selectedId: hostSelectedId = null,
4889
+ selectionSeq = null,
4876
4890
  viewport = null
4877
4891
  }) {
4878
4892
  const trackRef = (0,external_react_.useRef)(null); // width source for clustering overlapping badges
@@ -4880,7 +4894,7 @@ function WaveformCommentMarkers({
4880
4894
  containerRef,
4881
4895
  selectMarker,
4882
4896
  selectedId
4883
- } = (0,useDismissableMarkerSelection/* default */.A)(hostSelectedId);
4897
+ } = (0,useDismissableMarkerSelection/* default */.A)(hostSelectedId, selectionSeq);
4884
4898
  const [trackWidth, setTrackWidth] = (0,external_react_.useState)(0);
4885
4899
  const canShowTrack = durationSec > 0 && commentMarkers.length > 0;
4886
4900
  const zoomLevel = viewport?.zoomLevel ?? constants/* WAVEFORM_ZOOM_MIN */.LW;
@@ -5392,8 +5406,6 @@ function IconComment24(props) {
5392
5406
  }));
5393
5407
  }
5394
5408
  /* harmony default export */ const icons_IconComment24 = (IconComment24);
5395
- // EXTERNAL MODULE: ./src/lib/viewers/media/waveform/range.ts
5396
- var waveform_range = __webpack_require__(4253);
5397
5409
  ;// ./src/lib/viewers/media/waveform/usePlayheadCamera.ts
5398
5410
 
5399
5411
 
@@ -5727,6 +5739,15 @@ var IconExit24 = __webpack_require__(8950);
5727
5739
  function stopRangeEvent(event) {
5728
5740
  event.stopPropagation();
5729
5741
  }
5742
+ function focusMediaContainer(event) {
5743
+ const {
5744
+ currentTarget
5745
+ } = event;
5746
+ if (!(currentTarget instanceof Element)) {
5747
+ return;
5748
+ }
5749
+ currentTarget.closest('.bp-media-container')?.focus();
5750
+ }
5730
5751
  function offsetLeftCss(base, offsetPx) {
5731
5752
  if (!offsetPx) {
5732
5753
  return base;
@@ -5810,7 +5831,7 @@ const WaveformRangeSelection = /*#__PURE__*/(0,external_react_.forwardRef)(funct
5810
5831
  const isRangeOpen = displayed.startMs !== displayed.endMs && activeHandle == null;
5811
5832
  const showCommentButton = !readOnly && Boolean(onDragCreate) && isRangeOpen;
5812
5833
  const showClearControl = onRangeClear != null && isRangeOpen;
5813
- const showClearOnly = readOnly && showClearControl;
5834
+ const showClearOnly = showClearControl && !showCommentButton;
5814
5835
  const syncPositions = (0,external_react_.useCallback)((next, nextViewport, nextDurationSec) => {
5815
5836
  displayedRef.current = next;
5816
5837
  const collapsed = next.startMs === next.endMs;
@@ -6040,6 +6061,7 @@ const WaveformRangeSelection = /*#__PURE__*/(0,external_react_.forwardRef)(funct
6040
6061
  "data-testid": "bp-waveform-range-clear",
6041
6062
  onClick: event => {
6042
6063
  stopRangeEvent(event);
6064
+ focusMediaContainer(event);
6043
6065
  onRangeClear();
6044
6066
  },
6045
6067
  onPointerDown: stopRangeEvent,
@@ -6077,6 +6099,7 @@ const WaveformRangeSelection = /*#__PURE__*/(0,external_react_.forwardRef)(funct
6077
6099
  "data-testid": "bp-waveform-range-clear",
6078
6100
  onClick: event => {
6079
6101
  stopRangeEvent(event);
6102
+ focusMediaContainer(event);
6080
6103
  onRangeClear();
6081
6104
  },
6082
6105
  onPointerDown: stopRangeEvent,
@@ -6162,6 +6185,14 @@ function devicePixelWidth(widthCssPx) {
6162
6185
  const pixelRatio = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;
6163
6186
  return widthCssPx * pixelRatio;
6164
6187
  }
6188
+
6189
+ /** Dragged time while media is still at the pre-drag position. */
6190
+ function pinnedPlayheadSec(pin, mediaTimeSec) {
6191
+ if (pin && Math.abs(mediaTimeSec - pin.fromSec) <= 0.001 && Math.abs(mediaTimeSec - pin.sec) > 0.001) {
6192
+ return pin.sec;
6193
+ }
6194
+ return null;
6195
+ }
6165
6196
  function WaveformView_prefersReducedMotion() {
6166
6197
  return typeof window !== 'undefined' && typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
6167
6198
  }
@@ -6320,9 +6351,9 @@ function WaveformView({
6320
6351
  const containerRef = (0,external_react_.useRef)(null); // WaveSurfer canvas host
6321
6352
  const playheadAnimationRef = (0,external_react_.useRef)(0); // animation frame id while the playhead follows playback
6322
6353
  const playheadRef = (0,external_react_.useRef)(null); // playhead element the camera positions
6354
+ const rangeLayerRef = (0,external_react_.useRef)(null);
6323
6355
  const trackRef = (0,external_react_.useRef)(null); // hover / tap target around the canvas
6324
6356
  const wavesurferRef = (0,external_react_.useRef)(null); // WaveSurfer instance
6325
- const rangeLayerRef = (0,external_react_.useRef)(null);
6326
6357
 
6327
6358
  // Latest props for WaveSurfer + media listeners that must not re-subscribe each render.
6328
6359
  const cameraModeRef = (0,external_react_.useRef)(cameraMode); // latest tape/desktop; WaveSurfer create() deps stay empty
@@ -6333,10 +6364,10 @@ function WaveformView({
6333
6364
  const isPlayingRef = (0,external_react_.useRef)(isPlaying); // latest isPlaying; tape tap toggles from this
6334
6365
  const mediaElRef = (0,external_react_.useRef)(mediaEl); // latest <audio>/<video>; camera + playhead tick read this
6335
6366
  const onPlayPauseRef = (0,external_react_.useRef)(onPlayPause); // latest play/pause; tape tap must not re-bind
6336
- const onSeekRef = (0,external_react_.useRef)(onSeek); // latest onSeek; click/scroll handlers must not re-bind
6337
6367
  const onRangeChangeRef = (0,external_react_.useRef)(onRangeChange); // latest range commit; drag-create must not re-bind
6338
6368
  const onRangeClearRef = (0,external_react_.useRef)(onRangeClear); // latest click-outside clear; WaveSurfer click must not re-bind
6339
6369
  const onRangeDragChangeRef = (0,external_react_.useRef)(onRangeDragChange); // latest drag flag; unmount must not re-bind
6370
+ const onSeekRef = (0,external_react_.useRef)(onSeek); // latest onSeek; click/scroll handlers must not re-bind
6340
6371
  const onViewportChangeRef = (0,external_react_.useRef)(onViewportChange); // latest viewport callback; camera commits here
6341
6372
  const peaksRef = (0,external_react_.useRef)(peaks); // latest peaks; WaveSurfer create() + morph read this
6342
6373
 
@@ -6347,9 +6378,12 @@ function WaveformView({
6347
6378
  const bufferProgressRef = (0,external_react_.useRef)(0); // latest buffer fill; zoomed tile tint reads this
6348
6379
  const hideScrubTimeChipTimerRef = (0,external_react_.useRef)(0); // hides the tape scrub time chip after scroll settles
6349
6380
  const hoverProgressRef = (0,external_react_.useRef)(null); // latest hover fill; zoomed tile tint reads this
6381
+ const isPlayheadDraggingRef = (0,external_react_.useRef)(false); // playhead drag owns position until pointerup
6350
6382
  const lastObservedWidthRef = (0,external_react_.useRef)(0); // last ResizeObserver width; skip no-op resizes
6351
6383
  const liveHeightRef = (0,external_react_.useRef)(height); // canvas height last applied to WaveSurfer
6352
6384
  const pinchStartRef = (0,external_react_.useRef)(null); // two-finger distance and zoom at pinch start
6385
+ const playheadDragRef = (0,external_react_.useRef)(null); // active playhead drag; pointerup seeks
6386
+ const playheadPinRef = (0,external_react_.useRef)(null); // dragged time until media/props catch up
6353
6387
  const pointerZoomClearTimerRef = (0,external_react_.useRef)(0); // clears pointerZoomRef after WAVEFORM_ZOOM_DISMISS_MS
6354
6388
  const pointerZoomRef = (0,external_react_.useRef)(false); // pinch/wheel in progress; skip play/pause and tape recenter
6355
6389
  const queuedTapeSeekTimeSecRef = (0,external_react_.useRef)(null); // seek time waiting for the next animation frame
@@ -6362,16 +6396,18 @@ function WaveformView({
6362
6396
  const zoomOriginRef = (0,external_react_.useRef)(null); // pointer+time so zoom keeps that point fixed
6363
6397
 
6364
6398
  cameraModeRef.current = cameraMode;
6365
- currentTimeRef.current = currentTime;
6399
+ if (!isPlayheadDraggingRef.current && playheadPinRef.current == null) {
6400
+ currentTimeRef.current = currentTime;
6401
+ }
6366
6402
  durationSecRef.current = durationSec;
6367
6403
  interactiveRef.current = interactive;
6368
6404
  isPlayingRef.current = isPlaying;
6369
6405
  mediaElRef.current = mediaEl;
6370
6406
  onPlayPauseRef.current = onPlayPause;
6371
- onSeekRef.current = onSeek;
6372
6407
  onRangeChangeRef.current = onRangeChange;
6373
6408
  onRangeClearRef.current = onRangeClear;
6374
6409
  onRangeDragChangeRef.current = onRangeDragChange;
6410
+ onSeekRef.current = onSeek;
6375
6411
  onViewportChangeRef.current = onViewportChange;
6376
6412
  peaksRef.current = peaks;
6377
6413
  const [internalZoom, setInternalZoom] = (0,external_react_.useState)(constants/* WAVEFORM_ZOOM_MIN */.LW);
@@ -6383,15 +6419,16 @@ function WaveformView({
6383
6419
  const [previewRange, setPreviewRange] = (0,external_react_.useState)(null);
6384
6420
  const [createRange, setCreateRange] = (0,external_react_.useState)(null);
6385
6421
  const [isRangeDragging, setIsRangeDragging] = (0,external_react_.useState)(false);
6386
- const isRangeDraggingRef = (0,external_react_.useRef)(false);
6387
- const rangeRef = (0,external_react_.useRef)(range); // latest committed draft; drag-create must not start on top of an open span
6422
+ const [isPlayheadDragging, setIsPlayheadDragging] = (0,external_react_.useState)(false);
6388
6423
  const createDragRef = (0,external_react_.useRef)(null);
6389
- const tapeRangeHoldRef = (0,external_react_.useRef)(false); // a tape long-press is waiting to draw; touch must not scroll
6424
+ const isRangeDraggingRef = (0,external_react_.useRef)(false);
6425
+ const lastSetTimeSecRef = (0,external_react_.useRef)(null);
6390
6426
  const rangeDragPointerXRef = (0,external_react_.useRef)(null); // clientX while a handle or create-drag is down
6427
+ const rangeRef = (0,external_react_.useRef)(range); // latest committed draft; drag-create must not start on top of an open span
6391
6428
  const removeCreateDragListenersRef = (0,external_react_.useRef)(null);
6392
6429
  const removeTapeContextMenuRef = (0,external_react_.useRef)(null);
6393
6430
  const skipNextSeekRef = (0,external_react_.useRef)(false); // ignore the click fired when a handle is released
6394
- const lastSetTimeSecRef = (0,external_react_.useRef)(null);
6431
+ const tapeRangeHoldRef = (0,external_react_.useRef)(false); // a tape long-press is waiting to draw; touch must not scroll
6395
6432
  const [isRangeHovered, setIsRangeHovered] = (0,external_react_.useState)(false);
6396
6433
  const isControlled = typeof zoomLevelProp === 'number';
6397
6434
  const maxZoom = (0,waveform_viewport/* getWaveformZoomMax */.by)({
@@ -6826,7 +6863,17 @@ function WaveformView({
6826
6863
  applyZoomWindow();
6827
6864
  }, [applyZoomWindow]);
6828
6865
  (0,external_react_.useLayoutEffect)(() => {
6829
- updatePlayheadPosition(mediaEl ? mediaEl.currentTime : currentTime);
6866
+ if (isPlayheadDraggingRef.current) {
6867
+ return;
6868
+ }
6869
+ const mediaTimeSec = mediaEl ? mediaEl.currentTime : currentTime;
6870
+ const draggedTimeSec = pinnedPlayheadSec(playheadPinRef.current, mediaTimeSec);
6871
+ if (draggedTimeSec != null) {
6872
+ updatePlayheadPosition(draggedTimeSec);
6873
+ return;
6874
+ }
6875
+ playheadPinRef.current = null;
6876
+ updatePlayheadPosition(mediaTimeSec);
6830
6877
  }, [currentTime, durationSec, mediaEl, updatePlayheadPosition, viewport]);
6831
6878
  (0,external_react_.useEffect)(() => {
6832
6879
  const media = mediaEl;
@@ -6834,10 +6881,15 @@ function WaveformView({
6834
6881
  return undefined;
6835
6882
  }
6836
6883
  const tick = () => {
6837
- if (!media.paused) {
6838
- updatePlayheadPosition(media.currentTime);
6839
- if (!isRangeDraggingRef.current) {
6840
- applyPlayheadCamera(media.currentTime, false);
6884
+ if (!media.paused && !isPlayheadDraggingRef.current) {
6885
+ const mediaTimeSec = media.currentTime;
6886
+ const draggedTimeSec = pinnedPlayheadSec(playheadPinRef.current, mediaTimeSec);
6887
+ if (draggedTimeSec == null) {
6888
+ playheadPinRef.current = null;
6889
+ }
6890
+ updatePlayheadPosition(draggedTimeSec ?? mediaTimeSec);
6891
+ if (draggedTimeSec == null && !isRangeDraggingRef.current) {
6892
+ applyPlayheadCamera(mediaTimeSec, false);
6841
6893
  }
6842
6894
  }
6843
6895
  playheadAnimationRef.current = window.requestAnimationFrame(tick);
@@ -6845,7 +6897,7 @@ function WaveformView({
6845
6897
  const startLoop = () => {
6846
6898
  window.cancelAnimationFrame(playheadAnimationRef.current);
6847
6899
  releaseUserPanHold();
6848
- if (!isRangeDraggingRef.current) {
6900
+ if (!isRangeDraggingRef.current && !isPlayheadDraggingRef.current) {
6849
6901
  applyPlayheadCamera(media.currentTime, true);
6850
6902
  }
6851
6903
  playheadAnimationRef.current = window.requestAnimationFrame(tick);
@@ -6858,9 +6910,15 @@ function WaveformView({
6858
6910
  clearFollowPin();
6859
6911
  }
6860
6912
  syncViewport();
6861
- updatePlayheadPosition(media.currentTime);
6913
+ if (!isPlayheadDraggingRef.current) {
6914
+ updatePlayheadPosition(media.currentTime);
6915
+ }
6862
6916
  };
6863
6917
  const handleSeeked = () => {
6918
+ if (isPlayheadDraggingRef.current) {
6919
+ return;
6920
+ }
6921
+ playheadPinRef.current = null;
6864
6922
  onPlayheadSeek(media.currentTime);
6865
6923
  if (!isUserPanning() && !isRangeDraggingRef.current) {
6866
6924
  seekTo(media.currentTime);
@@ -6924,15 +6982,19 @@ function WaveformView({
6924
6982
  });
6925
6983
  if (isScrollableWindow) {
6926
6984
  tintZoomedWaveform(wavesurfer, fills);
6927
- return;
6985
+ } else {
6986
+ wavesurfer.setOptions({
6987
+ progressColor: toCanvasFill(fills.progressColor, devicePixelWidth(canvasWidthPx)),
6988
+ waveColor: toCanvasFill(fills.waveColor, devicePixelWidth(canvasWidthPx))
6989
+ });
6928
6990
  }
6929
- wavesurfer.setOptions({
6930
- progressColor: toCanvasFill(fills.progressColor, devicePixelWidth(canvasWidthPx)),
6931
- waveColor: toCanvasFill(fills.waveColor, devicePixelWidth(canvasWidthPx))
6932
- });
6933
- lastSetTimeSecRef.current = currentTimeRef.current;
6934
- wavesurfer.setTime(currentTimeRef.current);
6935
- }, [activeRangeProgress, bufferProgress, canvasWidthPx, hoverProgress, isRangeDragging, isScrollableWindow, isTape, isZoomed]);
6991
+ if (!isScrollableWindow || isPlayheadDragging) {
6992
+ // WaveSurfer clips progressColor left of this time.
6993
+ const playedUntilSec = isPlayheadDragging && hoverProgress != null ? hoverProgress * durationSecRef.current : currentTimeRef.current;
6994
+ lastSetTimeSecRef.current = playedUntilSec;
6995
+ wavesurfer.setTime(playedUntilSec);
6996
+ }
6997
+ }, [activeRangeProgress, bufferProgress, canvasWidthPx, hoverProgress, isPlayheadDragging, isRangeDragging, isScrollableWindow, isTape, isZoomed]);
6936
6998
  (0,external_react_.useEffect)(() => {
6937
6999
  const track = trackRef.current;
6938
7000
  if (!track) {
@@ -7045,6 +7107,9 @@ function WaveformView({
7045
7107
  setHoverProgress(Math.min(1, Math.max(0, pointerX / rect.width)));
7046
7108
  }, [durationSec, interactive, isTape]);
7047
7109
  const onHoverLeave = (0,external_react_.useCallback)(() => {
7110
+ if (isPlayheadDraggingRef.current) {
7111
+ return;
7112
+ }
7048
7113
  setHoverProgress(null);
7049
7114
  setIsRangeHovered(false);
7050
7115
  }, []);
@@ -7091,10 +7156,10 @@ function WaveformView({
7091
7156
  hasPreviousFrame = true;
7092
7157
  previousFrameMs = frameMs;
7093
7158
  const pointer = getPointerInTrack();
7094
- const viewport = viewportRef.current;
7159
+ const currentViewport = viewportRef.current;
7095
7160
  const scrollDeltaPx = pointer ? (0,waveform_viewport/* getRangeEdgeScrollDeltaPx */.CD)({
7096
7161
  elapsedSec,
7097
- pixelsPerSecond: viewport.pixelsPerSecond,
7162
+ pixelsPerSecond: currentViewport.pixelsPerSecond,
7098
7163
  pointerX: pointer.x,
7099
7164
  widthPx: pointer.width
7100
7165
  }) : null;
@@ -7102,8 +7167,8 @@ function WaveformView({
7102
7167
  pendingScrollPx = 0;
7103
7168
  } else {
7104
7169
  pendingScrollPx += scrollDeltaPx;
7105
- const nextScroll = Math.min((0,waveform_viewport/* maxScrollLeft */.d0)(viewport), Math.max(0, viewport.scrollLeftPx + pendingScrollPx));
7106
- const scrolledPx = nextScroll - viewport.scrollLeftPx;
7170
+ const nextScroll = Math.min((0,waveform_viewport/* maxScrollLeft */.d0)(currentViewport), Math.max(0, currentViewport.scrollLeftPx + pendingScrollPx));
7171
+ const scrolledPx = nextScroll - currentViewport.scrollLeftPx;
7107
7172
  pendingScrollPx = scrolledPx === 0 ? 0 : pendingScrollPx - scrolledPx;
7108
7173
  if (scrolledPx !== 0) {
7109
7174
  applyScrollLeft(nextScroll, true);
@@ -7129,6 +7194,9 @@ function WaveformView({
7129
7194
  createDragRef.current = null;
7130
7195
  onRangeDragChangeRef.current?.(false);
7131
7196
  }
7197
+ isPlayheadDraggingRef.current = false;
7198
+ playheadDragRef.current = null;
7199
+ playheadPinRef.current = null;
7132
7200
  };
7133
7201
  }, []);
7134
7202
  (0,external_react_.useLayoutEffect)(() => {
@@ -7228,7 +7296,7 @@ function WaveformView({
7228
7296
  const {
7229
7297
  target
7230
7298
  } = event;
7231
- if (target instanceof Element && target.closest('.bp-WaveformRange-handle, .bp-WaveformRange-comment')) {
7299
+ if (target instanceof Element && target.closest('.bp-WaveformRange-handle, .bp-WaveformRange-comment, .bp-WaveformView-playhead--draggable')) {
7232
7300
  return;
7233
7301
  }
7234
7302
  const drag = rangeCreateDragFromEvent(event, {
@@ -7327,6 +7395,112 @@ function WaveformView({
7327
7395
  const isOverlayReadOnly = rangeReadOnly && createRange == null;
7328
7396
  const showPlayheadComment = interactive && !isPlaying && !isRangeDragging && (0,waveform_range/* isRangeCollapsed */.BT)(overlayRange) && Boolean(onPlayheadComment);
7329
7397
  const showRangeOverlay = Boolean(overlayRange) && (isRangeDragging || !isPlaying || !(0,waveform_range/* isRangeCollapsed */.BT)(overlayRange));
7398
+ const canDragPlayhead = interactive && !isTape;
7399
+
7400
+ /** Media time under a pointer X on the waveform track. */
7401
+ const mediaTimeFromClientX = clientX => {
7402
+ const track = trackRef.current;
7403
+ if (!track || !(durationSecRef.current > 0) || !Number.isFinite(clientX)) {
7404
+ return null;
7405
+ }
7406
+ const rect = track.getBoundingClientRect();
7407
+ if (!(rect.width > 0)) {
7408
+ return null;
7409
+ }
7410
+ const pointerX = clientX - rect.left;
7411
+ const currentViewport = viewportRef.current;
7412
+ const unclampedTimeSec = currentViewport.pixelsPerSecond > 0 ? (0,waveform_viewport/* timeFromPositionPx */.lZ)(pointerX, currentViewport) : pointerX / rect.width * durationSecRef.current;
7413
+ return Number.isFinite(unclampedTimeSec) ? Math.min(durationSecRef.current, Math.max(0, unclampedTimeSec)) : null;
7414
+ };
7415
+
7416
+ /** CSS playhead + hover fills at timeSec; media seek waits for pointerup. */
7417
+ const showDraggedPlayhead = timeSec => {
7418
+ const playhead = playheadRef.current;
7419
+ if (!playhead) {
7420
+ return;
7421
+ }
7422
+ const drag = playheadDragRef.current;
7423
+ playheadPinRef.current = {
7424
+ fromSec: drag?.fromSec ?? timeSec,
7425
+ sec: timeSec
7426
+ };
7427
+ playhead.style.left = (0,waveform_viewport/* timeLeftPercent */.Mu)(timeSec, durationSecRef.current, viewportRef.current);
7428
+ setHoverProgress(timeSec / durationSecRef.current);
7429
+ };
7430
+ const onPlayheadPointerDown = event => {
7431
+ if (event.target instanceof Element && event.target.closest('.bp-WaveformView-playheadComment')) {
7432
+ return;
7433
+ }
7434
+ if (!canDragPlayhead || event.button > 0 || event.ctrlKey || event.metaKey || isRangeDraggingRef.current) {
7435
+ return;
7436
+ }
7437
+ event.preventDefault();
7438
+ event.stopPropagation();
7439
+ try {
7440
+ event.currentTarget.setPointerCapture?.(event.pointerId);
7441
+ } catch {
7442
+ return; // Don't start a drag we cannot track after the pointer leaves.
7443
+ }
7444
+ const fromSec = mediaElRef.current ? mediaElRef.current.currentTime : currentTimeRef.current;
7445
+ playheadDragRef.current = {
7446
+ fromSec,
7447
+ pointerId: event.pointerId
7448
+ };
7449
+ playheadPinRef.current = {
7450
+ fromSec,
7451
+ sec: fromSec
7452
+ };
7453
+ isPlayheadDraggingRef.current = true;
7454
+ setIsPlayheadDragging(true);
7455
+ setHoverProgress(durationSecRef.current > 0 ? fromSec / durationSecRef.current : null);
7456
+ clearFollowPin();
7457
+ cancelJump();
7458
+ };
7459
+ const onPlayheadPointerMove = event => {
7460
+ const drag = playheadDragRef.current;
7461
+ if (!drag || event.pointerId !== drag.pointerId) {
7462
+ return;
7463
+ }
7464
+ const timeSec = mediaTimeFromClientX(event.clientX);
7465
+ if (timeSec == null) {
7466
+ return;
7467
+ }
7468
+ event.preventDefault();
7469
+ event.stopPropagation();
7470
+ showDraggedPlayhead(timeSec);
7471
+ };
7472
+ const onPlayheadPointerUp = event => {
7473
+ const drag = playheadDragRef.current;
7474
+ if (!drag || event.pointerId !== drag.pointerId) {
7475
+ return;
7476
+ }
7477
+ event.preventDefault();
7478
+ event.stopPropagation();
7479
+ const timeSec = mediaTimeFromClientX(event.clientX) ?? playheadPinRef.current?.sec;
7480
+ if (timeSec != null) {
7481
+ playheadPinRef.current = {
7482
+ fromSec: drag.fromSec,
7483
+ sec: timeSec
7484
+ };
7485
+ currentTimeRef.current = timeSec;
7486
+ }
7487
+ playheadDragRef.current = null;
7488
+ isPlayheadDraggingRef.current = false;
7489
+ setIsPlayheadDragging(false);
7490
+ if (event.type !== 'lostpointercapture') {
7491
+ try {
7492
+ event.currentTarget.releasePointerCapture?.(event.pointerId);
7493
+ } catch {
7494
+ // Capture was never set or already lost.
7495
+ }
7496
+ }
7497
+ if (timeSec == null) {
7498
+ return;
7499
+ }
7500
+ onPlayheadSeek(timeSec);
7501
+ updatePlayheadPosition(timeSec);
7502
+ onSeekRef.current?.(timeSec);
7503
+ };
7330
7504
  const scrubTimeChip = isTape && scrubPreviewTimeSec != null ? /*#__PURE__*/external_react_["default"].createElement("div", {
7331
7505
  className: "bp-WaveformView-hover bp-WaveformView-hover--tape",
7332
7506
  "data-testid": "bp-waveform-hover"
@@ -7338,6 +7512,7 @@ function WaveformView({
7338
7512
  ref: bindOverlayPortalHost,
7339
7513
  className: classnames_default()('bp-WaveformView', {
7340
7514
  'bp-WaveformView--inert': !interactive,
7515
+ 'bp-WaveformView--playheadDragging': isPlayheadDragging,
7341
7516
  'bp-WaveformView--tape': isTape,
7342
7517
  'bp-WaveformView--zoomed': isZoomed
7343
7518
  }),
@@ -7366,8 +7541,16 @@ function WaveformView({
7366
7541
  className: "bp-WaveformView-canvas"
7367
7542
  }), /*#__PURE__*/external_react_["default"].createElement("div", {
7368
7543
  ref: playheadRef,
7369
- className: "bp-WaveformView-playhead",
7370
- "data-testid": "bp-waveform-playhead"
7544
+ className: classnames_default()('bp-WaveformView-playhead', {
7545
+ 'bp-WaveformView-playhead--draggable': canDragPlayhead
7546
+ }),
7547
+ "data-target-id": canDragPlayhead ? 'Waveform-dragPlayhead' : undefined,
7548
+ "data-testid": "bp-waveform-playhead",
7549
+ onLostPointerCapture: onPlayheadPointerUp,
7550
+ onPointerCancel: onPlayheadPointerUp,
7551
+ onPointerDown: onPlayheadPointerDown,
7552
+ onPointerMove: onPlayheadPointerMove,
7553
+ onPointerUp: onPlayheadPointerUp
7371
7554
  }, showPlayheadComment && /*#__PURE__*/external_react_["default"].createElement("button", {
7372
7555
  className: "bp-WaveformRange-comment bp-WaveformView-playheadComment",
7373
7556
  "data-target-id": "Waveform-commentAtTime",
@@ -7398,7 +7581,7 @@ function WaveformView({
7398
7581
  },
7399
7582
  onPreviewChange: setPreviewRange,
7400
7583
  onRangeChange: interactive && !isOverlayReadOnly ? onRangeChange : undefined,
7401
- onRangeClear: onRangeClear,
7584
+ onRangeClear: isTape && !isRangeDragging ? onRangeClear : undefined,
7402
7585
  range: overlayRange,
7403
7586
  readOnly: isOverlayReadOnly,
7404
7587
  viewport: viewport
@@ -7650,7 +7833,11 @@ function WaveformZoomControl({
7650
7833
 
7651
7834
 
7652
7835
 
7836
+
7653
7837
  const PLACEHOLDER_PEAKS = placeholderPeaks();
7838
+
7839
+ /** Clicks here keep an open range. Everywhere else in the player dismisses it. */
7840
+ const RANGE_DISMISS_IGNORE = '.bp-WaveformView, .bp-WaveformCommentMarkers, .bp-WaveformRange-comment, .bp-WaveformZoomControl, .bp-MP3ControlsV2-bar';
7654
7841
  function MP3ControlsV2({
7655
7842
  autoplay,
7656
7843
  bufferedRange,
@@ -7699,6 +7886,7 @@ function MP3ControlsV2({
7699
7886
  const [playRequested, setPlayRequested] = (0,external_react_.useState)(hasStartedPlayback);
7700
7887
  const [viewport, setViewport] = (0,external_react_.useState)(null);
7701
7888
  const isTape = (0,useTapeWaveform/* default */.Ay)();
7889
+ const controlsRef = (0,external_react_.useRef)(null); // player root; pointerdown outside the range chrome dismisses it
7702
7890
  const hasAppliedTapeDefaultZoomRef = (0,external_react_.useRef)(false); // ~10s window applied; reset to 1× when leaving tape
7703
7891
  const lastKeyboardZoomStepRef = (0,external_react_.useRef)(0); // last +/− step applied; skip re-step when maxZoom retriggers the effect
7704
7892
  const userChangedTapeZoomRef = (0,external_react_.useRef)(false); // pinch/wheel zoom; skip re-applying the 10s default
@@ -7770,7 +7958,9 @@ function MP3ControlsV2({
7770
7958
  const waveformRange = commentRangeDraft ?? commentRangeReadOnly;
7771
7959
  const isRangeReadOnly = commentRangeDraft == null && commentRangeReadOnly != null;
7772
7960
  const waveformMarkers = (0,external_react_.useMemo)(() => commentMarkers || [], [commentMarkers]);
7773
- const selectedMarkerId = (0,external_react_.useMemo)(() => waveformMarkers.find(marker => marker.isSelected)?.id ?? null, [waveformMarkers]);
7961
+ const selectedMarker = (0,external_react_.useMemo)(() => waveformMarkers.find(marker => marker.isSelected) ?? null, [waveformMarkers]);
7962
+ const selectedMarkerId = selectedMarker?.id ?? null;
7963
+ const selectionSeq = selectedMarker?.selectionSeq ?? null;
7774
7964
  const handleCommentMarkerClick = (0,external_react_.useCallback)(marker => {
7775
7965
  setPlayRequested(true);
7776
7966
  onPlayPause(false);
@@ -7782,6 +7972,24 @@ function MP3ControlsV2({
7782
7972
  }, [onCommentMarkerClick, onPlayPause, onTimeChange]);
7783
7973
  const hasStarted = playRequested || hasStartedPlayback;
7784
7974
  const isWaveformInteractive = hasStarted && hasMediaMetadata;
7975
+ const canDismissOpenRange = isWaveformInteractive && !(0,waveform_range/* isRangeCollapsed */.BT)(waveformRange);
7976
+ (0,external_react_.useEffect)(() => {
7977
+ const root = controlsRef.current;
7978
+ if (!canDismissOpenRange || !onCommentRangeClear || !root) {
7979
+ return undefined;
7980
+ }
7981
+ const onPointerDown = event => {
7982
+ const {
7983
+ target
7984
+ } = event;
7985
+ if (!(target instanceof Element) || target.closest(RANGE_DISMISS_IGNORE)) {
7986
+ return;
7987
+ }
7988
+ onCommentRangeClear();
7989
+ };
7990
+ root.addEventListener('pointerdown', onPointerDown);
7991
+ return () => root.removeEventListener('pointerdown', onPointerDown);
7992
+ }, [canDismissOpenRange, onCommentRangeClear]);
7785
7993
  const isWaitingToPlay = hasStarted && !hasMediaMetadata;
7786
7994
  const showPlayOverlay = !hasStarted && !isPlaying;
7787
7995
  const hasZoomHandlers = hasRealPeaks && !showPlayOverlay;
@@ -7790,7 +7998,8 @@ function MP3ControlsV2({
7790
7998
  const showShuttle = !isTape && !!shuttleDirection && shuttleRate > 0;
7791
7999
  const waveformZoomLevel = isTape || hasZoomHandlers ? zoomLevel : constants/* WAVEFORM_ZOOM_MIN */.LW;
7792
8000
  return /*#__PURE__*/external_react_["default"].createElement("div", {
7793
- className: "bp-MP3ControlsV2",
8001
+ ref: controlsRef,
8002
+ className: canDismissOpenRange ? 'bp-MP3ControlsV2 bp-MP3ControlsV2--rangeDismiss' : 'bp-MP3ControlsV2',
7794
8003
  "data-testid": "media-controls-wrapper-v2"
7795
8004
  }, /*#__PURE__*/external_react_["default"].createElement("div", {
7796
8005
  className: "bp-MP3ControlsV2-stage"
@@ -7823,6 +8032,7 @@ function MP3ControlsV2({
7823
8032
  isTape: isTape,
7824
8033
  onCommentMarkerClick: handleCommentMarkerClick,
7825
8034
  selectedId: selectedMarkerId,
8035
+ selectionSeq: selectionSeq,
7826
8036
  viewport: viewport
7827
8037
  })), showShuttle && shuttleDirection && /*#__PURE__*/external_react_["default"].createElement(WaveformShuttleIndicator, {
7828
8038
  direction: shuttleDirection,
@@ -25154,7 +25364,7 @@ class Browser {
25154
25364
  ;// ./src/lib/Logger.js
25155
25365
  /* eslint-disable no-undef */
25156
25366
  const CLIENT_NAME = "box-content-preview";
25157
- const CLIENT_VERSION = "3.105.0";
25367
+ const CLIENT_VERSION = "3.107.0";
25158
25368
  /* eslint-enable no-undef */
25159
25369
 
25160
25370
  class Logger {
@@ -38066,9 +38276,13 @@ class MP3Viewer extends media_MediaBaseViewer {
38066
38276
 
38067
38277
  // Host echoes often omit isSelected. Keep hostSelectedMarkerId so ↑/↓ can
38068
38278
  // still walk other comments at the same time. Clear only when that id is gone.
38279
+ // selectionSeq is a new pick of that same comment: seek and draw the range again.
38069
38280
  if (selected) {
38070
- if (selected.id !== this.hostSelectedMarkerId) {
38281
+ const incomingSeq = Number.isFinite(selected.selectionSeq) ? selected.selectionSeq : null;
38282
+ const isRepeatSelect = incomingSeq != null && incomingSeq !== this.hostSelectedMarkerSeq;
38283
+ if (selected.id !== this.hostSelectedMarkerId || isRepeatSelect) {
38071
38284
  this.hostSelectedMarkerId = selected.id;
38285
+ this.hostSelectedMarkerSeq = incomingSeq;
38072
38286
  this.commentRangeReadOnly = commentMarkerRange(selected);
38073
38287
  if (Number.isFinite(selected.time)) {
38074
38288
  this.pendingHostSelectedSeek = selected;
@@ -38077,6 +38291,7 @@ class MP3Viewer extends media_MediaBaseViewer {
38077
38291
  }
38078
38292
  } else if (this.hostSelectedMarkerId && !markers.some(marker => marker.id === this.hostSelectedMarkerId)) {
38079
38293
  this.hostSelectedMarkerId = null;
38294
+ this.hostSelectedMarkerSeq = null;
38080
38295
  this.pendingHostSelectedSeek = null;
38081
38296
  this.commentRangeReadOnly = null;
38082
38297
  }
@@ -38135,7 +38350,7 @@ class MP3Viewer extends media_MediaBaseViewer {
38135
38350
  });
38136
38351
  MP3Viewer_defineProperty(this, "handleCommentRangeDragCreate", () => {
38137
38352
  const draft = this.commentRangeDraft;
38138
- if (!draft || (0,range/* isRangeCollapsed */.BT)(draft)) {
38353
+ if (!this.getCanCreateComment() || !draft || (0,range/* isRangeCollapsed */.BT)(draft)) {
38139
38354
  return;
38140
38355
  }
38141
38356
  this.isCommentRangeTimestampActive = true;
@@ -38152,7 +38367,7 @@ class MP3Viewer extends media_MediaBaseViewer {
38152
38367
  */
38153
38368
  MP3Viewer_defineProperty(this, "handlePlayheadComment", () => {
38154
38369
  const timeSec = this.mediaEl?.currentTime;
38155
- if (this.shuttleDirection || !Number.isFinite(timeSec) || timeSec < 0) {
38370
+ if (!this.getCanCreateComment() || this.shuttleDirection || !Number.isFinite(timeSec) || timeSec < 0) {
38156
38371
  return;
38157
38372
  }
38158
38373
  if (this.commentRangeDraft && !(0,range/* isRangeCollapsed */.BT)(this.commentRangeDraft)) {
@@ -38244,6 +38459,7 @@ class MP3Viewer extends media_MediaBaseViewer {
38244
38459
  this.commentRangeDraft = null;
38245
38460
  this.commentRangeReadOnly = null;
38246
38461
  this.hostSelectedMarkerId = null;
38462
+ this.hostSelectedMarkerSeq = null;
38247
38463
  this.isCommentRangeDragging = false;
38248
38464
  this.isCommentRangeTimestampActive = false;
38249
38465
  this.shuttleDirection = null;
@@ -39184,6 +39400,17 @@ class MP3Viewer extends media_MediaBaseViewer {
39184
39400
  }
39185
39401
  super.mediaendHandler();
39186
39402
  }
39403
+
39404
+ /**
39405
+ * Only an explicit `can_comment` shows Comment.
39406
+ * A missing file, permissions object, or flag hides it.
39407
+ *
39408
+ * @return {boolean}
39409
+ */
39410
+ getCanCreateComment() {
39411
+ const canComment = this.options?.file?.permissions?.can_comment;
39412
+ return canComment ?? false;
39413
+ }
39187
39414
  /**
39188
39415
  * @inheritdoc
39189
39416
  */
@@ -39232,8 +39459,8 @@ class MP3Viewer extends media_MediaBaseViewer {
39232
39459
  onCommentRangeChange: this.handleCommentRangeChange,
39233
39460
  onCommentRangeClear: this.handleCommentRangeClear,
39234
39461
  onCommentRangeDragChange: this.handleCommentRangeDragChange,
39235
- onCommentRangeDragCreate: this.handleCommentRangeDragCreate,
39236
- onPlayheadComment: this.handlePlayheadComment,
39462
+ onCommentRangeDragCreate: this.getCanCreateComment() ? this.handleCommentRangeDragCreate : undefined,
39463
+ onPlayheadComment: this.getCanCreateComment() ? this.handlePlayheadComment : undefined,
39237
39464
  onPlayNextChange: this.setPlayNext,
39238
39465
  peaks: this.waveformPeaks,
39239
39466
  playNext: this.isPlayNextEnabled(),
@@ -41090,12 +41317,13 @@ function TimeControlsV2({
41090
41317
  const [hoverTime, setHoverTime] = external_react_["default"].useState(0);
41091
41318
  const [trackWidth, setTrackWidth] = external_react_["default"].useState(0);
41092
41319
  const scrubberRef = external_react_["default"].useRef(null);
41093
- const hostSelectedId = external_react_["default"].useMemo(() => commentMarkers.find(marker => marker.isSelected)?.id ?? null, [commentMarkers]);
41320
+ const selectedMarker = external_react_["default"].useMemo(() => commentMarkers.find(marker => marker.isSelected) ?? null, [commentMarkers]);
41321
+ const hostSelectedId = selectedMarker?.id ?? null;
41094
41322
  const {
41095
41323
  containerRef,
41096
41324
  selectMarker,
41097
41325
  selectedId
41098
- } = (0,useDismissableMarkerSelection/* default */.A)(hostSelectedId);
41326
+ } = (0,useDismissableMarkerSelection/* default */.A)(hostSelectedId, selectedMarker?.selectionSeq ?? null);
41099
41327
  const currentValue = isFinite_default()(currentTime) ? currentTime : 0;
41100
41328
  const durationValue = isFinite_default()(durationTime) ? durationTime : 0;
41101
41329
  const currentPercentage = (0,utils/* percent */.K)(currentValue, durationValue);
@@ -45444,14 +45672,14 @@ function GalleryGrid({
45444
45672
  function syncHighRes() {
45445
45673
  const store = highResStoreRef.current;
45446
45674
  const {
45447
- pageRatio
45675
+ pageRatio: thumbnailPageRatio
45448
45676
  } = thumbnail;
45449
- if (!store || !pageRatio) return;
45677
+ if (!store || !thumbnailPageRatio) return;
45450
45678
  const width = getNeededThumbWidth();
45451
45679
  if (width === GALLERY_THUMB_MAX_WIDTH) {
45452
- store.setRetained([], width, pageRatio);
45680
+ store.setRetained([], width, thumbnailPageRatio);
45453
45681
  } else if (!isProcessingRef.current) {
45454
- store.setRetained(getPagesNearViewport(0.5), width, pageRatio);
45682
+ store.setRetained(getPagesNearViewport(0.5), width, thumbnailPageRatio);
45455
45683
  }
45456
45684
  }
45457
45685
  function getUnloadedNearViewport() {
@@ -55717,6 +55945,8 @@ class Preview extends (events_default()) {
55717
55945
  * @return {void}
55718
55946
  */
55719
55947
  destroy() {
55948
+ clearTimeout(this.retryTimeout);
55949
+
55720
55950
  // Log all load metrics
55721
55951
  this.emitLoadMetrics();
55722
55952