@alfalab/core-components-gallery 7.2.3 → 7.3.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 (285) hide show
  1. package/Component.js +51 -7
  2. package/Component.js.map +1 -1
  3. package/components/bottom-button/index.css +5 -5
  4. package/components/bottom-button/index.module.css.js +1 -1
  5. package/components/buttons/index.css +5 -5
  6. package/components/buttons/index.d.ts +3 -1
  7. package/components/buttons/index.js +49 -12
  8. package/components/buttons/index.js.map +1 -1
  9. package/components/buttons/index.module.css.js +1 -1
  10. package/components/header/Component.js +1 -0
  11. package/components/header/Component.js.map +1 -1
  12. package/components/header/index.css +3 -2
  13. package/components/header/index.module.css.js +1 -1
  14. package/components/header/index.module.css.js.map +1 -1
  15. package/components/header-info-block/Component.js +2 -1
  16. package/components/header-info-block/Component.js.map +1 -1
  17. package/components/header-info-block/index.css +4 -4
  18. package/components/header-info-block/index.module.css.js +1 -1
  19. package/components/header-mobile/index.css +6 -6
  20. package/components/header-mobile/index.module.css.js +1 -1
  21. package/components/image-preview/Component.js +2 -1
  22. package/components/image-preview/Component.js.map +1 -1
  23. package/components/image-preview/index.css +20 -20
  24. package/components/image-preview/index.module.css.js +1 -1
  25. package/components/image-preview/index.module.css.js.map +1 -1
  26. package/components/image-viewer/hooks.js +3 -2
  27. package/components/image-viewer/hooks.js.map +1 -1
  28. package/components/image-viewer/index.css +30 -31
  29. package/components/image-viewer/index.module.css.js +1 -1
  30. package/components/image-viewer/index.module.css.js.map +1 -1
  31. package/components/image-viewer/single.js +1 -0
  32. package/components/image-viewer/single.js.map +1 -1
  33. package/components/image-viewer/slide.js +3 -2
  34. package/components/image-viewer/slide.js.map +1 -1
  35. package/components/image-viewer/video/index.css +22 -10
  36. package/components/image-viewer/video/index.js +50 -15
  37. package/components/image-viewer/video/index.js.map +1 -1
  38. package/components/image-viewer/video/index.module.css.js +1 -1
  39. package/components/image-viewer/video/index.module.css.js.map +1 -1
  40. package/components/info-bar/Component.js +1 -0
  41. package/components/info-bar/Component.js.map +1 -1
  42. package/components/info-bar/index.css +3 -3
  43. package/components/info-bar/index.module.css.js +1 -1
  44. package/components/navigation-bar/Component.js +56 -26
  45. package/components/navigation-bar/Component.js.map +1 -1
  46. package/components/navigation-bar/index.css +21 -11
  47. package/components/navigation-bar/index.module.css.js +1 -1
  48. package/components/navigation-bar/index.module.css.js.map +1 -1
  49. package/components/subtitles/index.css +3 -3
  50. package/components/subtitles/index.module.css.js +1 -1
  51. package/constants.d.ts +1 -1
  52. package/constants.js +1 -1
  53. package/constants.js.map +1 -1
  54. package/cssm/Component.js +51 -7
  55. package/cssm/Component.js.map +1 -1
  56. package/cssm/components/buttons/index.d.ts +3 -1
  57. package/cssm/components/buttons/index.js +54 -17
  58. package/cssm/components/buttons/index.js.map +1 -1
  59. package/cssm/components/header/Component.js +1 -0
  60. package/cssm/components/header/Component.js.map +1 -1
  61. package/cssm/components/header/index.module.css +2 -1
  62. package/cssm/components/header-info-block/Component.js +2 -1
  63. package/cssm/components/header-info-block/Component.js.map +1 -1
  64. package/cssm/components/image-preview/Component.js +2 -1
  65. package/cssm/components/image-preview/Component.js.map +1 -1
  66. package/cssm/components/image-preview/index.module.css +3 -3
  67. package/cssm/components/image-viewer/hooks.js +3 -2
  68. package/cssm/components/image-viewer/hooks.js.map +1 -1
  69. package/cssm/components/image-viewer/index.module.css +2 -3
  70. package/cssm/components/image-viewer/single.js +1 -0
  71. package/cssm/components/image-viewer/single.js.map +1 -1
  72. package/cssm/components/image-viewer/slide.js +3 -2
  73. package/cssm/components/image-viewer/slide.js.map +1 -1
  74. package/cssm/components/image-viewer/video/index.js +50 -15
  75. package/cssm/components/image-viewer/video/index.js.map +1 -1
  76. package/cssm/components/image-viewer/video/index.module.css +15 -3
  77. package/cssm/components/info-bar/Component.js +1 -0
  78. package/cssm/components/info-bar/Component.js.map +1 -1
  79. package/cssm/components/navigation-bar/Component.js +56 -26
  80. package/cssm/components/navigation-bar/Component.js.map +1 -1
  81. package/cssm/components/navigation-bar/index.module.css +13 -3
  82. package/cssm/constants.d.ts +1 -1
  83. package/cssm/constants.js +1 -1
  84. package/cssm/constants.js.map +1 -1
  85. package/cssm/hooks/use-custom-subtitles.js +57 -11
  86. package/cssm/hooks/use-custom-subtitles.js.map +1 -1
  87. package/cssm/index.js +1 -0
  88. package/cssm/index.js.map +1 -1
  89. package/cssm/types.d.ts +4 -2
  90. package/cssm/utils/index.d.ts +1 -0
  91. package/cssm/utils/index.js +2 -0
  92. package/cssm/utils/index.js.map +1 -1
  93. package/cssm/utils/modern-download.d.ts +6 -0
  94. package/cssm/utils/modern-download.js +113 -0
  95. package/cssm/utils/modern-download.js.map +1 -0
  96. package/esm/Component.js +51 -7
  97. package/esm/Component.js.map +1 -1
  98. package/esm/components/bottom-button/index.css +5 -5
  99. package/esm/components/bottom-button/index.module.css.js +1 -1
  100. package/esm/components/buttons/index.css +5 -5
  101. package/esm/components/buttons/index.d.ts +3 -1
  102. package/esm/components/buttons/index.js +50 -13
  103. package/esm/components/buttons/index.js.map +1 -1
  104. package/esm/components/buttons/index.module.css.js +1 -1
  105. package/esm/components/header/Component.js +1 -0
  106. package/esm/components/header/Component.js.map +1 -1
  107. package/esm/components/header/index.css +3 -2
  108. package/esm/components/header/index.module.css.js +1 -1
  109. package/esm/components/header/index.module.css.js.map +1 -1
  110. package/esm/components/header-info-block/Component.js +2 -1
  111. package/esm/components/header-info-block/Component.js.map +1 -1
  112. package/esm/components/header-info-block/index.css +4 -4
  113. package/esm/components/header-info-block/index.module.css.js +1 -1
  114. package/esm/components/header-mobile/index.css +6 -6
  115. package/esm/components/header-mobile/index.module.css.js +1 -1
  116. package/esm/components/image-preview/Component.js +2 -1
  117. package/esm/components/image-preview/Component.js.map +1 -1
  118. package/esm/components/image-preview/index.css +20 -20
  119. package/esm/components/image-preview/index.module.css.js +1 -1
  120. package/esm/components/image-preview/index.module.css.js.map +1 -1
  121. package/esm/components/image-viewer/hooks.js +3 -2
  122. package/esm/components/image-viewer/hooks.js.map +1 -1
  123. package/esm/components/image-viewer/index.css +30 -31
  124. package/esm/components/image-viewer/index.module.css.js +1 -1
  125. package/esm/components/image-viewer/index.module.css.js.map +1 -1
  126. package/esm/components/image-viewer/single.js +1 -0
  127. package/esm/components/image-viewer/single.js.map +1 -1
  128. package/esm/components/image-viewer/slide.js +3 -2
  129. package/esm/components/image-viewer/slide.js.map +1 -1
  130. package/esm/components/image-viewer/video/index.css +22 -10
  131. package/esm/components/image-viewer/video/index.js +51 -16
  132. package/esm/components/image-viewer/video/index.js.map +1 -1
  133. package/esm/components/image-viewer/video/index.module.css.js +1 -1
  134. package/esm/components/image-viewer/video/index.module.css.js.map +1 -1
  135. package/esm/components/info-bar/Component.js +1 -0
  136. package/esm/components/info-bar/Component.js.map +1 -1
  137. package/esm/components/info-bar/index.css +3 -3
  138. package/esm/components/info-bar/index.module.css.js +1 -1
  139. package/esm/components/navigation-bar/Component.js +56 -25
  140. package/esm/components/navigation-bar/Component.js.map +1 -1
  141. package/esm/components/navigation-bar/index.css +21 -11
  142. package/esm/components/navigation-bar/index.module.css.js +1 -1
  143. package/esm/components/navigation-bar/index.module.css.js.map +1 -1
  144. package/esm/components/subtitles/index.css +3 -3
  145. package/esm/components/subtitles/index.module.css.js +1 -1
  146. package/esm/constants.d.ts +1 -1
  147. package/esm/constants.js +1 -1
  148. package/esm/constants.js.map +1 -1
  149. package/esm/hooks/use-custom-subtitles.js +57 -11
  150. package/esm/hooks/use-custom-subtitles.js.map +1 -1
  151. package/esm/index.css +9 -9
  152. package/esm/index.js +1 -0
  153. package/esm/index.js.map +1 -1
  154. package/esm/index.module.css.js +1 -1
  155. package/esm/types.d.ts +4 -2
  156. package/esm/utils/index.d.ts +1 -0
  157. package/esm/utils/index.js +1 -0
  158. package/esm/utils/index.js.map +1 -1
  159. package/esm/utils/modern-download.d.ts +6 -0
  160. package/esm/utils/modern-download.js +109 -0
  161. package/esm/utils/modern-download.js.map +1 -0
  162. package/hooks/use-custom-subtitles.js +57 -11
  163. package/hooks/use-custom-subtitles.js.map +1 -1
  164. package/index.css +9 -9
  165. package/index.js +1 -0
  166. package/index.js.map +1 -1
  167. package/index.module.css.js +1 -1
  168. package/modern/Component.js +50 -7
  169. package/modern/Component.js.map +1 -1
  170. package/modern/components/bottom-button/index.css +5 -5
  171. package/modern/components/bottom-button/index.module.css.js +1 -1
  172. package/modern/components/buttons/index.css +5 -5
  173. package/modern/components/buttons/index.d.ts +3 -1
  174. package/modern/components/buttons/index.js +51 -12
  175. package/modern/components/buttons/index.js.map +1 -1
  176. package/modern/components/buttons/index.module.css.js +1 -1
  177. package/modern/components/header/index.css +3 -2
  178. package/modern/components/header/index.module.css.js +1 -1
  179. package/modern/components/header/index.module.css.js.map +1 -1
  180. package/modern/components/header-info-block/Component.js +1 -1
  181. package/modern/components/header-info-block/Component.js.map +1 -1
  182. package/modern/components/header-info-block/index.css +4 -4
  183. package/modern/components/header-info-block/index.module.css.js +1 -1
  184. package/modern/components/header-mobile/index.css +6 -6
  185. package/modern/components/header-mobile/index.module.css.js +1 -1
  186. package/modern/components/image-preview/Component.js +1 -1
  187. package/modern/components/image-preview/Component.js.map +1 -1
  188. package/modern/components/image-preview/index.css +20 -20
  189. package/modern/components/image-preview/index.module.css.js +1 -1
  190. package/modern/components/image-preview/index.module.css.js.map +1 -1
  191. package/modern/components/image-viewer/hooks.js +3 -2
  192. package/modern/components/image-viewer/hooks.js.map +1 -1
  193. package/modern/components/image-viewer/index.css +30 -31
  194. package/modern/components/image-viewer/index.module.css.js +1 -1
  195. package/modern/components/image-viewer/index.module.css.js.map +1 -1
  196. package/modern/components/image-viewer/slide.js +2 -2
  197. package/modern/components/image-viewer/slide.js.map +1 -1
  198. package/modern/components/image-viewer/video/index.css +22 -10
  199. package/modern/components/image-viewer/video/index.js +47 -12
  200. package/modern/components/image-viewer/video/index.js.map +1 -1
  201. package/modern/components/image-viewer/video/index.module.css.js +1 -1
  202. package/modern/components/image-viewer/video/index.module.css.js.map +1 -1
  203. package/modern/components/info-bar/index.css +3 -3
  204. package/modern/components/info-bar/index.module.css.js +1 -1
  205. package/modern/components/navigation-bar/Component.js +55 -25
  206. package/modern/components/navigation-bar/Component.js.map +1 -1
  207. package/modern/components/navigation-bar/index.css +21 -11
  208. package/modern/components/navigation-bar/index.module.css.js +1 -1
  209. package/modern/components/navigation-bar/index.module.css.js.map +1 -1
  210. package/modern/components/subtitles/index.css +3 -3
  211. package/modern/components/subtitles/index.module.css.js +1 -1
  212. package/modern/constants.d.ts +1 -1
  213. package/modern/constants.js +1 -1
  214. package/modern/constants.js.map +1 -1
  215. package/modern/hooks/use-custom-subtitles.js +56 -9
  216. package/modern/hooks/use-custom-subtitles.js.map +1 -1
  217. package/modern/index.css +9 -9
  218. package/modern/index.module.css.js +1 -1
  219. package/modern/types.d.ts +4 -2
  220. package/modern/utils/index.d.ts +1 -0
  221. package/modern/utils/index.js +1 -0
  222. package/modern/utils/index.js.map +1 -1
  223. package/modern/utils/modern-download.d.ts +6 -0
  224. package/modern/utils/modern-download.js +76 -0
  225. package/modern/utils/modern-download.js.map +1 -0
  226. package/moderncssm/Component.js +50 -7
  227. package/moderncssm/Component.js.map +1 -1
  228. package/moderncssm/components/buttons/index.d.ts +3 -1
  229. package/moderncssm/components/buttons/index.js +51 -12
  230. package/moderncssm/components/buttons/index.js.map +1 -1
  231. package/moderncssm/components/header/index.module.css +1 -1
  232. package/moderncssm/components/header-info-block/Component.js +1 -1
  233. package/moderncssm/components/header-info-block/Component.js.map +1 -1
  234. package/moderncssm/components/image-preview/Component.js +1 -1
  235. package/moderncssm/components/image-preview/Component.js.map +1 -1
  236. package/moderncssm/components/image-preview/index.module.css +2 -2
  237. package/moderncssm/components/image-viewer/hooks.js +3 -2
  238. package/moderncssm/components/image-viewer/hooks.js.map +1 -1
  239. package/moderncssm/components/image-viewer/index.module.css +2 -2
  240. package/moderncssm/components/image-viewer/slide.js +2 -2
  241. package/moderncssm/components/image-viewer/slide.js.map +1 -1
  242. package/moderncssm/components/image-viewer/video/index.js +47 -12
  243. package/moderncssm/components/image-viewer/video/index.js.map +1 -1
  244. package/moderncssm/components/image-viewer/video/index.module.css +16 -3
  245. package/moderncssm/components/navigation-bar/Component.js +55 -25
  246. package/moderncssm/components/navigation-bar/Component.js.map +1 -1
  247. package/moderncssm/components/navigation-bar/index.module.css +14 -2
  248. package/moderncssm/constants.d.ts +1 -1
  249. package/moderncssm/constants.js +1 -1
  250. package/moderncssm/constants.js.map +1 -1
  251. package/moderncssm/hooks/use-custom-subtitles.js +56 -9
  252. package/moderncssm/hooks/use-custom-subtitles.js.map +1 -1
  253. package/moderncssm/types.d.ts +4 -2
  254. package/moderncssm/utils/index.d.ts +1 -0
  255. package/moderncssm/utils/index.js +1 -0
  256. package/moderncssm/utils/index.js.map +1 -1
  257. package/moderncssm/utils/modern-download.d.ts +6 -0
  258. package/moderncssm/utils/modern-download.js +76 -0
  259. package/moderncssm/utils/modern-download.js.map +1 -0
  260. package/package.json +2 -2
  261. package/src/Component.tsx +63 -6
  262. package/src/components/buttons/index.tsx +157 -62
  263. package/src/components/header/index.module.css +1 -1
  264. package/src/components/header-info-block/Component.tsx +2 -2
  265. package/src/components/image-preview/Component.tsx +1 -1
  266. package/src/components/image-preview/index.module.css +2 -2
  267. package/src/components/image-viewer/hooks.ts +3 -2
  268. package/src/components/image-viewer/index.module.css +2 -2
  269. package/src/components/image-viewer/slide.tsx +2 -1
  270. package/src/components/image-viewer/video/index.module.css +16 -3
  271. package/src/components/image-viewer/video/index.tsx +62 -13
  272. package/src/components/navigation-bar/Component.tsx +68 -27
  273. package/src/components/navigation-bar/index.module.css +12 -2
  274. package/src/constants.ts +1 -1
  275. package/src/hooks/use-custom-subtitles.ts +72 -12
  276. package/src/types.ts +4 -2
  277. package/src/utils/index.ts +1 -0
  278. package/src/utils/modern-download.ts +107 -0
  279. package/types.d.ts +4 -2
  280. package/utils/index.d.ts +1 -0
  281. package/utils/index.js +2 -0
  282. package/utils/index.js.map +1 -1
  283. package/utils/modern-download.d.ts +6 -0
  284. package/utils/modern-download.js +113 -0
  285. package/utils/modern-download.js.map +1 -0
@@ -1,4 +1,4 @@
1
- import React, { useRef, useState, useContext, useEffect, useCallback } from 'react';
1
+ import React, { useState, useRef, useContext, useEffect, useCallback } from 'react';
2
2
  import cn from 'classnames';
3
3
  import { Circle } from '@alfalab/core-components-icon-view/modern/circle';
4
4
  import PlayCompactMIcon from '@alfalab/icons-glyph/PlayCompactMIcon';
@@ -8,9 +8,12 @@ import { Subtitles } from '../../subtitles/index.js';
8
8
  import styles from './index.module.css.js';
9
9
 
10
10
  const Video = ({ url, index, className, isActive }) => {
11
+ const [videoLoaded, setVideoLoaded] = useState(false);
11
12
  const playerRef = useRef(null);
12
13
  const timer = useRef();
13
14
  const [hlsSupported, setHlsSupported] = useState(true);
15
+ const abortController = useRef(new AbortController());
16
+ const [videoError, setVideoError] = useState(false);
14
17
  const { setImageMeta, mutedVideo, view, playingVideo, setPlayingVideo, setHideNavigation, getCurrentImage, } = useContext(GalleryContext);
15
18
  const isMobile = view === 'mobile';
16
19
  const isDesktop = view === 'desktop';
@@ -40,6 +43,36 @@ const Video = ({ url, index, className, isActive }) => {
40
43
  return null;
41
44
  }
42
45
  }, [setImageMeta, index]);
46
+ useEffect(() => () => abortController.current.abort(), []);
47
+ useEffect(() => {
48
+ const video = playerRef.current;
49
+ if (!video) {
50
+ return;
51
+ }
52
+ const { signal } = abortController.current;
53
+ const handleCanPlay = () => {
54
+ setVideoLoaded(true);
55
+ setVideoError(false);
56
+ setImageMeta({
57
+ player: playerRef,
58
+ width: video.videoWidth || 1920,
59
+ height: video.videoHeight || 1080,
60
+ loaded: true,
61
+ }, index);
62
+ };
63
+ const handleError = () => {
64
+ setVideoError(true);
65
+ setVideoLoaded(false);
66
+ setImageMeta({ player: { current: null }, broken: true, loaded: true }, index);
67
+ };
68
+ const handleLoadStart = () => {
69
+ setVideoLoaded(false);
70
+ setVideoError(false);
71
+ };
72
+ video.addEventListener('canplay', handleCanPlay, { signal });
73
+ video.addEventListener('error', handleError, { signal });
74
+ video.addEventListener('loadstart', handleLoadStart, { signal });
75
+ }, [setImageMeta, index]);
43
76
  useEffect(() => {
44
77
  let hls = null;
45
78
  const initHls = async () => {
@@ -105,8 +138,11 @@ const Video = ({ url, index, className, isActive }) => {
105
138
  }
106
139
  }, [isActive, playingVideo]);
107
140
  useEffect(() => {
141
+ const { signal } = abortController.current;
108
142
  const handleSpacePress = (e) => {
109
143
  if ((e.key === ' ' || e.code === 'Space') && isActive) {
144
+ e.preventDefault();
145
+ e.stopPropagation();
110
146
  if (playingVideo) {
111
147
  setPlayingVideo(false);
112
148
  }
@@ -115,10 +151,7 @@ const Video = ({ url, index, className, isActive }) => {
115
151
  }
116
152
  }
117
153
  };
118
- document.addEventListener('keyup', handleSpacePress);
119
- return () => {
120
- document.removeEventListener('keyup', handleSpacePress);
121
- };
154
+ document.addEventListener('keydown', handleSpacePress, { signal });
122
155
  }, [isActive, playingVideo, setPlayingVideo]);
123
156
  const handleWrapperClick = (e) => {
124
157
  e.stopPropagation();
@@ -132,9 +165,10 @@ const Video = ({ url, index, className, isActive }) => {
132
165
  setHideNavigation(true);
133
166
  }, 3000);
134
167
  }
135
- return;
136
168
  }
137
- setPlayingVideo(!playingVideo);
169
+ else {
170
+ setPlayingVideo(!playingVideo);
171
+ }
138
172
  };
139
173
  const handleBottomButtonClick = useCallback((e) => {
140
174
  e.stopPropagation();
@@ -159,16 +193,17 @@ const Video = ({ url, index, className, isActive }) => {
159
193
  }
160
194
  setHideNavigation(false);
161
195
  };
162
- return (
163
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
164
- React.createElement("div", { onClick: handleWrapperClick, className: styles.videoWrapper },
196
+ return (React.createElement("div", { "aria-hidden": true, onClick: handleWrapperClick, "data-content-area": 'true', className: cn(styles.videoWrapper, {
197
+ [styles.loading]: !videoLoaded && !videoError,
198
+ [styles.mobileWrapper]: isMobile,
199
+ }) },
165
200
  React.createElement("video", { onPlay: onPlay, onPause: onPause, ref: playerRef, playsInline: true, muted: mutedVideo, loop: true, src: hlsSupported ? undefined : url, className: cn(styles.video, { [styles.mobile]: view === 'mobile' }, className) },
166
201
  React.createElement("track", { kind: 'captions' })),
167
- isDesktop && !playingVideo && (React.createElement("div", { className: styles.videoButton },
202
+ isDesktop && !playingVideo && videoLoaded && (React.createElement("div", { className: styles.videoButton },
168
203
  React.createElement(Circle, { size: 64, shapeClassName: styles.iconShape },
169
204
  React.createElement(PlayCompactMIcon, { className: styles.icon })))),
170
205
  isDesktop && React.createElement(Subtitles, null),
171
- isDesktop && image?.bottomButton && (React.createElement(BottomButton, { bottomButton: image.bottomButton, onClick: handleBottomButtonClick, className: styles.bottomButton }))));
206
+ isDesktop && image?.bottomButton && videoLoaded && (React.createElement(BottomButton, { bottomButton: image.bottomButton, onClick: handleBottomButtonClick, className: styles.bottomButton }))));
172
207
  };
173
208
 
174
209
  export { Video };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/components/image-viewer/video/index.tsx"],"sourcesContent":["import React, {\n type MouseEvent,\n type ReactEventHandler,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport cn from 'classnames';\nimport type Hls from 'hls.js';\n\nimport { Circle } from '@alfalab/core-components-icon-view/circle';\nimport PlayCompactMIcon from '@alfalab/icons-glyph/PlayCompactMIcon';\n\nimport { GalleryContext } from '../../../context';\nimport { BottomButton } from '../../bottom-button';\nimport { Subtitles } from '../../subtitles';\n\nimport styles from './index.module.css';\n\ntype Props = {\n url: string;\n index: number;\n isActive: boolean;\n className?: string;\n};\n\nexport const Video = ({ url, index, className, isActive }: Props) => {\n const playerRef = useRef<HTMLVideoElement>(null);\n const timer = useRef<ReturnType<typeof setTimeout>>();\n const [hlsSupported, setHlsSupported] = useState<boolean>(true);\n\n const {\n setImageMeta,\n mutedVideo,\n view,\n playingVideo,\n setPlayingVideo,\n setHideNavigation,\n getCurrentImage,\n } = useContext(GalleryContext);\n\n const isMobile = view === 'mobile';\n const isDesktop = view === 'desktop';\n\n const image = getCurrentImage();\n\n useEffect(() => {\n setImageMeta({ player: playerRef }, index);\n /* eslint-disable-next-line react-hooks/exhaustive-deps */\n }, [index]);\n\n const loadHlsLibrary = useCallback(\n async (attempt = 1, maxAttempts = 3): Promise<typeof Hls | null> => {\n try {\n const { default: HlsLib } = await import(\n /* webpackChunkName: \"hls-js-gallery\" */ 'hls.js'\n );\n\n return HlsLib;\n } catch {\n if (attempt < maxAttempts) {\n /* Экспоненциальная задержка ретрая: 300ms, 600ms, 1200ms */\n await new Promise<void>((resolve) => {\n setTimeout(\n () => {\n resolve();\n },\n 300 * 2 ** (attempt - 1),\n );\n });\n\n return loadHlsLibrary(attempt + 1, maxAttempts);\n }\n\n setHlsSupported(false);\n setImageMeta({ player: { current: null }, broken: true }, index);\n\n return null;\n }\n },\n [setImageMeta, index],\n );\n\n useEffect(() => {\n let hls: Hls | null = null;\n\n const initHls = async () => {\n try {\n const HlsLib = await loadHlsLibrary();\n\n if (!HlsLib || !playerRef.current) {\n return;\n }\n\n if (!HlsLib.isSupported()) {\n setHlsSupported(false);\n\n return;\n }\n\n hls = new HlsLib();\n\n hls.on(HlsLib.Events.ERROR, (_, data) => {\n if (data.fatal && hls) {\n switch (data.type) {\n case HlsLib.ErrorTypes.MEDIA_ERROR:\n hls.recoverMediaError();\n break;\n case HlsLib.ErrorTypes.NETWORK_ERROR:\n setImageMeta({ player: { current: null }, broken: true }, index);\n break;\n default:\n hls.destroy();\n break;\n }\n }\n });\n\n hls.loadSource(url);\n\n if (playerRef.current) {\n hls.attachMedia(playerRef.current);\n hls.subtitleDisplay = false;\n }\n } catch {\n setHlsSupported(false);\n setImageMeta({ player: { current: null }, broken: true }, index);\n }\n };\n\n initHls();\n\n return () => {\n if (hls) {\n hls.destroy();\n }\n if (timer.current) {\n clearTimeout(timer.current);\n }\n };\n /* eslint-disable-next-line react-hooks/exhaustive-deps */\n }, [url, index]);\n\n useEffect(() => {\n if (playerRef.current && isActive) {\n if (playingVideo) {\n playerRef.current.play();\n } else {\n playerRef.current.pause();\n }\n }\n if (playerRef.current && !isActive) {\n playerRef.current.pause();\n playerRef.current.currentTime = 0;\n }\n }, [isActive, playingVideo]);\n\n useEffect(() => {\n const handleSpacePress = (e: KeyboardEvent) => {\n if ((e.key === ' ' || e.code === 'Space') && isActive) {\n if (playingVideo) {\n setPlayingVideo(false);\n } else {\n setPlayingVideo(true);\n }\n }\n };\n\n document.addEventListener('keyup', handleSpacePress);\n\n return () => {\n document.removeEventListener('keyup', handleSpacePress);\n };\n }, [isActive, playingVideo, setPlayingVideo]);\n\n const handleWrapperClick = (e: MouseEvent) => {\n e.stopPropagation();\n\n if (isMobile) {\n setHideNavigation(false);\n\n if (playingVideo) {\n if (timer.current) {\n clearTimeout(timer.current);\n }\n timer.current = setTimeout(() => {\n setHideNavigation(true);\n }, 3000);\n }\n\n return;\n }\n\n setPlayingVideo(!playingVideo);\n };\n\n const handleBottomButtonClick = useCallback(\n (e: MouseEvent) => {\n e.stopPropagation();\n if (image?.bottomButton) {\n image.bottomButton.onClick(e);\n }\n },\n [image?.bottomButton],\n );\n\n const onPlay: ReactEventHandler<HTMLVideoElement> = () => {\n image?.onPlay?.();\n\n if (timer.current) {\n clearTimeout(timer.current);\n }\n\n timer.current = setTimeout(() => {\n setHideNavigation(true);\n }, 3000);\n };\n\n const onPause: ReactEventHandler<HTMLVideoElement> = () => {\n image?.onPause?.();\n\n if (timer.current) {\n clearTimeout(timer.current);\n timer.current = undefined;\n }\n\n setHideNavigation(false);\n };\n\n return (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions\n <div onClick={handleWrapperClick} className={styles.videoWrapper}>\n <video\n onPlay={onPlay}\n onPause={onPause}\n ref={playerRef}\n playsInline={true}\n muted={mutedVideo}\n loop={true}\n src={hlsSupported ? undefined : url}\n className={cn(styles.video, { [styles.mobile]: view === 'mobile' }, className)}\n >\n <track kind='captions' />\n </video>\n {isDesktop && !playingVideo && (\n <div className={styles.videoButton}>\n <Circle size={64} shapeClassName={styles.iconShape}>\n <PlayCompactMIcon className={styles.icon} />\n </Circle>\n </div>\n )}\n {isDesktop && <Subtitles />}\n {isDesktop && image?.bottomButton && (\n <BottomButton\n bottomButton={image.bottomButton}\n onClick={handleBottomButtonClick}\n className={styles.bottomButton}\n />\n )}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/image-viewer/video/index.tsx"],"sourcesContent":["import React, {\n type MouseEvent,\n type ReactEventHandler,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport cn from 'classnames';\nimport type Hls from 'hls.js';\n\nimport { Circle } from '@alfalab/core-components-icon-view/circle';\nimport PlayCompactMIcon from '@alfalab/icons-glyph/PlayCompactMIcon';\n\nimport { GalleryContext } from '../../../context';\nimport { BottomButton } from '../../bottom-button';\nimport { Subtitles } from '../../subtitles';\n\nimport styles from './index.module.css';\n\ntype Props = {\n url: string;\n index: number;\n isActive: boolean;\n className?: string;\n};\n\nexport const Video = ({ url, index, className, isActive }: Props) => {\n const [videoLoaded, setVideoLoaded] = useState(false);\n const playerRef = useRef<HTMLVideoElement>(null);\n const timer = useRef<ReturnType<typeof setTimeout>>();\n const [hlsSupported, setHlsSupported] = useState<boolean>(true);\n const abortController = useRef(new AbortController());\n const [videoError, setVideoError] = useState(false);\n\n const {\n setImageMeta,\n mutedVideo,\n view,\n playingVideo,\n setPlayingVideo,\n setHideNavigation,\n getCurrentImage,\n } = useContext(GalleryContext);\n\n const isMobile = view === 'mobile';\n const isDesktop = view === 'desktop';\n\n const image = getCurrentImage();\n\n useEffect(() => {\n setImageMeta({ player: playerRef }, index);\n /* eslint-disable-next-line react-hooks/exhaustive-deps */\n }, [index]);\n\n const loadHlsLibrary = useCallback(\n async (attempt = 1, maxAttempts = 3): Promise<typeof Hls | null> => {\n try {\n const { default: HlsLib } = await import(\n /* webpackChunkName: \"hls-js-gallery\" */ 'hls.js'\n );\n\n return HlsLib;\n } catch {\n if (attempt < maxAttempts) {\n /* Экспоненциальная задержка ретрая: 300ms, 600ms, 1200ms */\n await new Promise<void>((resolve) => {\n setTimeout(\n () => {\n resolve();\n },\n 300 * 2 ** (attempt - 1),\n );\n });\n\n return loadHlsLibrary(attempt + 1, maxAttempts);\n }\n\n setHlsSupported(false);\n setImageMeta({ player: { current: null }, broken: true }, index);\n\n return null;\n }\n },\n [setImageMeta, index],\n );\n\n useEffect(() => () => abortController.current.abort(), []);\n\n useEffect(() => {\n const video = playerRef.current;\n\n if (!video) {\n return;\n }\n\n const { signal } = abortController.current;\n\n const handleCanPlay = () => {\n setVideoLoaded(true);\n setVideoError(false);\n setImageMeta(\n {\n player: playerRef,\n width: video.videoWidth || 1920,\n height: video.videoHeight || 1080,\n loaded: true,\n },\n index,\n );\n };\n\n const handleError = () => {\n setVideoError(true);\n setVideoLoaded(false);\n setImageMeta({ player: { current: null }, broken: true, loaded: true }, index);\n };\n\n const handleLoadStart = () => {\n setVideoLoaded(false);\n setVideoError(false);\n };\n\n video.addEventListener('canplay', handleCanPlay, { signal });\n video.addEventListener('error', handleError, { signal });\n video.addEventListener('loadstart', handleLoadStart, { signal });\n }, [setImageMeta, index]);\n\n useEffect(() => {\n let hls: Hls | null = null;\n\n const initHls = async () => {\n try {\n const HlsLib = await loadHlsLibrary();\n\n if (!HlsLib || !playerRef.current) {\n return;\n }\n\n if (!HlsLib.isSupported()) {\n setHlsSupported(false);\n\n return;\n }\n\n hls = new HlsLib();\n\n hls.on(HlsLib.Events.ERROR, (_, data) => {\n if (data.fatal && hls) {\n switch (data.type) {\n case HlsLib.ErrorTypes.MEDIA_ERROR:\n hls.recoverMediaError();\n break;\n case HlsLib.ErrorTypes.NETWORK_ERROR:\n setImageMeta({ player: { current: null }, broken: true }, index);\n break;\n default:\n hls.destroy();\n break;\n }\n }\n });\n\n hls.loadSource(url);\n\n if (playerRef.current) {\n hls.attachMedia(playerRef.current);\n hls.subtitleDisplay = false;\n }\n } catch {\n setHlsSupported(false);\n setImageMeta({ player: { current: null }, broken: true }, index);\n }\n };\n\n initHls();\n\n return () => {\n if (hls) {\n hls.destroy();\n }\n if (timer.current) {\n clearTimeout(timer.current);\n }\n };\n /* eslint-disable-next-line react-hooks/exhaustive-deps */\n }, [url, index]);\n\n useEffect(() => {\n if (playerRef.current && isActive) {\n if (playingVideo) {\n playerRef.current.play();\n } else {\n playerRef.current.pause();\n }\n }\n if (playerRef.current && !isActive) {\n playerRef.current.pause();\n playerRef.current.currentTime = 0;\n }\n }, [isActive, playingVideo]);\n\n useEffect(() => {\n const { signal } = abortController.current;\n\n const handleSpacePress = (e: KeyboardEvent) => {\n if ((e.key === ' ' || e.code === 'Space') && isActive) {\n e.preventDefault();\n e.stopPropagation();\n if (playingVideo) {\n setPlayingVideo(false);\n } else {\n setPlayingVideo(true);\n }\n }\n };\n\n document.addEventListener('keydown', handleSpacePress, { signal });\n }, [isActive, playingVideo, setPlayingVideo]);\n\n const handleWrapperClick = (e: MouseEvent) => {\n e.stopPropagation();\n\n if (isMobile) {\n setHideNavigation(false);\n\n if (playingVideo) {\n if (timer.current) {\n clearTimeout(timer.current);\n }\n timer.current = setTimeout(() => {\n setHideNavigation(true);\n }, 3000);\n }\n } else {\n setPlayingVideo(!playingVideo);\n }\n };\n\n const handleBottomButtonClick = useCallback(\n (e: MouseEvent) => {\n e.stopPropagation();\n if (image?.bottomButton) {\n image.bottomButton.onClick(e);\n }\n },\n [image?.bottomButton],\n );\n\n const onPlay: ReactEventHandler<HTMLVideoElement> = () => {\n image?.onPlay?.();\n\n if (timer.current) {\n clearTimeout(timer.current);\n }\n\n timer.current = setTimeout(() => {\n setHideNavigation(true);\n }, 3000);\n };\n\n const onPause: ReactEventHandler<HTMLVideoElement> = () => {\n image?.onPause?.();\n\n if (timer.current) {\n clearTimeout(timer.current);\n timer.current = undefined;\n }\n\n setHideNavigation(false);\n };\n\n return (\n <div\n aria-hidden={true}\n onClick={handleWrapperClick}\n data-content-area='true'\n className={cn(styles.videoWrapper, {\n [styles.loading]: !videoLoaded && !videoError,\n [styles.mobileWrapper]: isMobile,\n })}\n >\n <video\n onPlay={onPlay}\n onPause={onPause}\n ref={playerRef}\n playsInline={true}\n muted={mutedVideo}\n loop={true}\n src={hlsSupported ? undefined : url}\n className={cn(styles.video, { [styles.mobile]: view === 'mobile' }, className)}\n >\n <track kind='captions' />\n </video>\n {isDesktop && !playingVideo && videoLoaded && (\n <div className={styles.videoButton}>\n <Circle size={64} shapeClassName={styles.iconShape}>\n <PlayCompactMIcon className={styles.icon} />\n </Circle>\n </div>\n )}\n {isDesktop && <Subtitles />}\n {isDesktop && image?.bottomButton && videoLoaded && (\n <BottomButton\n bottomButton={image.bottomButton}\n onClick={handleBottomButtonClick}\n className={styles.bottomButton}\n />\n )}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import './index.css';
2
2
 
3
- const styles = {"videoWrapper":"gallery__videoWrapper_gnw2e","video":"gallery__video_gnw2e","mobile":"gallery__mobile_gnw2e","videoButton":"gallery__videoButton_gnw2e","icon":"gallery__icon_gnw2e","iconShape":"gallery__iconShape_gnw2e","bottomButton":"gallery__bottomButton_gnw2e"};
3
+ const styles = {"videoWrapper":"gallery__videoWrapper_yf8l7","mobileWrapper":"gallery__mobileWrapper_yf8l7","loading":"gallery__loading_yf8l7","video":"gallery__video_yf8l7","mobile":"gallery__mobile_yf8l7","videoButton":"gallery__videoButton_yf8l7","icon":"gallery__icon_yf8l7","iconShape":"gallery__iconShape_yf8l7","bottomButton":"gallery__bottomButton_yf8l7"};
4
4
 
5
5
  export { styles as default };
6
6
  //# sourceMappingURL=index.module.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.css.js","sources":["../../../src/components/image-viewer/video/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n.videoWrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n min-width: 0;\n min-height: 0;\n position: relative;\n}\n\n.video {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n border-radius: var(--border-radius-24);\n}\n\n.mobile {\n border-radius: var(--border-radius-0);\n}\n\n.videoButton {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1;\n color: green;\n}\n\n.icon {\n color: var(--color-static-neutral-0);\n}\n\n.iconShape {\n fill: var(--color-static-neutral-translucent-700);\n}\n\n.bottomButton {\n position: absolute;\n bottom: 48px;\n left: 32px;\n right: 32px;\n}\n"],"names":[],"mappings":";;AAEgB,eAAe,CAAC,cAAc,CAAC,6BAA6B,CAAC,OAAO,CAAC,sBAAsB,CAAC,QAAQ,CAAC,uBAAuB,CAAC,aAAa,CAAC,4BAA4B,CAAC,MAAM,CAAC,qBAAqB,CAAC,WAAW,CAAC,0BAA0B,CAAC,cAAc,CAAC,6BAA6B,CAAC;;;;"}
1
+ {"version":3,"file":"index.module.css.js","sources":["../../../src/components/image-viewer/video/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n.videoWrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: auto;\n max-width: 100%;\n position: relative;\n min-width: 300px;\n min-height: 200px;\n}\n\n.mobileWrapper {\n width: 100%;\n}\n\n.videoWrapper.loading {\n width: 100%;\n aspect-ratio: 16/9;\n background-color: var(--color-static-neutral-translucent-100-inverted);\n border-radius: var(--border-radius-24);\n align-items: center;\n}\n\n.video {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n border-radius: var(--border-radius-24);\n}\n\n.mobile {\n border-radius: var(--border-radius-0);\n}\n\n.videoButton {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1;\n color: green;\n}\n\n.icon {\n color: var(--color-static-neutral-0);\n}\n\n.iconShape {\n fill: var(--color-static-neutral-translucent-700);\n}\n\n.bottomButton {\n position: absolute;\n bottom: 48px;\n left: 32px;\n right: 32px;\n}\n"],"names":[],"mappings":";;AAEgB,eAAe,CAAC,cAAc,CAAC,6BAA6B,CAAC,eAAe,CAAC,8BAA8B,CAAC,SAAS,CAAC,wBAAwB,CAAC,OAAO,CAAC,sBAAsB,CAAC,QAAQ,CAAC,uBAAuB,CAAC,aAAa,CAAC,4BAA4B,CAAC,MAAM,CAAC,qBAAqB,CAAC,WAAW,CAAC,0BAA0B,CAAC,cAAc,CAAC,6BAA6B,CAAC;;;;"}
@@ -5,10 +5,10 @@
5
5
  --gap-4: 4px;
6
6
  --gap-8: 8px;
7
7
  }
8
- .gallery__description_2ekgy {
8
+ .gallery__description_bonz4 {
9
9
  text-align: center;
10
10
  }
11
- .gallery__infoWrapper_2ekgy {
11
+ .gallery__infoWrapper_bonz4 {
12
12
  background-color: var(--color-static-neutral-0-inverted);
13
13
  display: flex;
14
14
  align-items: center;
@@ -17,7 +17,7 @@
17
17
  position: relative;
18
18
  height: 48px;
19
19
  }
20
- .gallery__infoWrapper_2ekgy.gallery__video_2ekgy {
20
+ .gallery__infoWrapper_bonz4.gallery__video_bonz4 {
21
21
  padding: 0 var(--gap-4) var(--gap-4);
22
22
  justify-content: space-between;
23
23
  }
@@ -1,6 +1,6 @@
1
1
  import './index.css';
2
2
 
3
- const styles = {"description":"gallery__description_2ekgy","infoWrapper":"gallery__infoWrapper_2ekgy","video":"gallery__video_2ekgy"};
3
+ const styles = {"description":"gallery__description_bonz4","infoWrapper":"gallery__infoWrapper_bonz4","video":"gallery__video_bonz4"};
4
4
 
5
5
  export { styles as default };
6
6
  //# sourceMappingURL=index.module.css.js.map
@@ -1,6 +1,6 @@
1
1
  import React, { useRef, useState, useContext, useCallback, useEffect } from 'react';
2
2
  import cn from 'classnames';
3
- import throttle from 'lodash/throttle';
3
+ import { isClient } from '@alfalab/core-components-shared/modern';
4
4
  import { GalleryContext } from '../../context.js';
5
5
  import { getImageKey } from '../../utils/utils.js';
6
6
  import { TestIds } from '../../utils/constants.js';
@@ -8,11 +8,13 @@ import { ImagePreview } from '../image-preview/Component.js';
8
8
  import styles from './index.module.css.js';
9
9
 
10
10
  const MIN_SCROLL_STEP = 24;
11
- const SCROLL_SPEED = 2; // Коэффициент скорости прокрутки (можно настроить)
12
- const SCROLL_THRESHOLD = 150; // Расстояние от границы, при котором начинается прокрутка
11
+ const DRAG_CLICK_THRESHOLD = 5;
13
12
  const NavigationBar = () => {
14
13
  const containerRef = useRef(null);
15
- const [isNavMouseDowned, setIsNavMouseDowned] = useState(false);
14
+ const dragStartXRef = useRef(0);
15
+ const dragStartScrollLeftRef = useRef(0);
16
+ const suppressClickRef = useRef(false);
17
+ const [isDragging, setIsDragging] = useState(false);
16
18
  const { images, currentSlideIndex, setCurrentSlideIndex, getSwiper, setPlayingVideo, view } = useContext(GalleryContext);
17
19
  const swiper = getSwiper();
18
20
  const handlePreviewSelect = (index) => {
@@ -31,32 +33,57 @@ const NavigationBar = () => {
31
33
  });
32
34
  }
33
35
  }, []);
34
- const handlePreviewMouseDown = () => {
35
- setIsNavMouseDowned(true);
36
+ const handlePreviewMouseDown = (e) => {
37
+ if (e.button !== 0 || !containerRef.current) {
38
+ return;
39
+ }
40
+ dragStartXRef.current = e.clientX;
41
+ dragStartScrollLeftRef.current = containerRef.current.scrollLeft;
42
+ suppressClickRef.current = false;
43
+ setIsDragging(true);
36
44
  };
37
- const handlePreviewMouseUp = () => {
38
- setIsNavMouseDowned(false);
39
- if (containerRef.current) {
40
- containerRef.current.style.scrollBehavior = 'auto'; // Отключаем плавность для резкой остановки
45
+ const handlePreviewMouseUp = useCallback(() => {
46
+ setIsDragging(false);
47
+ }, []);
48
+ const dragTo = useCallback((clientX) => {
49
+ const container = containerRef.current;
50
+ if (!container) {
51
+ return;
52
+ }
53
+ const deltaX = clientX - dragStartXRef.current;
54
+ if (Math.abs(deltaX) > DRAG_CLICK_THRESHOLD) {
55
+ suppressClickRef.current = true;
41
56
  }
57
+ container.scrollLeft = dragStartScrollLeftRef.current - deltaX;
58
+ }, []);
59
+ const handleMouseNavigationMove = (e) => {
60
+ if (!isDragging) {
61
+ return;
62
+ }
63
+ dragTo(e.clientX);
42
64
  };
43
- const handleMouseNavigationMove = throttle((e) => {
44
- if (!containerRef.current || !isNavMouseDowned)
65
+ const handleClickCapture = (e) => {
66
+ if (!suppressClickRef.current) {
45
67
  return;
46
- const container = containerRef.current;
47
- const { width: containerWidth, left: containerLeft } = container.getBoundingClientRect();
48
- const mouseX = e.clientX;
49
- // Если курсор близко к правой границе
50
- if (mouseX > containerWidth + containerLeft - SCROLL_THRESHOLD) {
51
- const scrollValue = (mouseX - (containerWidth + containerLeft - SCROLL_THRESHOLD)) * SCROLL_SPEED;
52
- container.scrollBy({ left: scrollValue, behavior: 'smooth' });
53
68
  }
54
- // Если курсор близко к левой границе
55
- else if (mouseX < containerLeft + SCROLL_THRESHOLD) {
56
- const scrollValue = (mouseX - (containerLeft + SCROLL_THRESHOLD)) * SCROLL_SPEED;
57
- container.scrollBy({ left: scrollValue, behavior: 'smooth' });
69
+ e.preventDefault();
70
+ e.stopPropagation();
71
+ suppressClickRef.current = false;
72
+ };
73
+ useEffect(() => {
74
+ if (!isClient() || !isDragging) {
75
+ return undefined;
58
76
  }
59
- }, 150);
77
+ const handleDocumentMouseMove = (event) => {
78
+ dragTo(event.clientX);
79
+ };
80
+ document.addEventListener('mousemove', handleDocumentMouseMove);
81
+ document.addEventListener('mouseup', handlePreviewMouseUp);
82
+ return () => {
83
+ document.removeEventListener('mousemove', handleDocumentMouseMove);
84
+ document.removeEventListener('mouseup', handlePreviewMouseUp);
85
+ };
86
+ }, [dragTo, handlePreviewMouseUp, isDragging]);
60
87
  const handlePreviewPosition = useCallback((preview, containerWidth) => {
61
88
  const { right, left, x } = preview.getBoundingClientRect();
62
89
  if (view === 'mobile') {
@@ -82,7 +109,10 @@ const NavigationBar = () => {
82
109
  }, [currentSlideIndex, handlePreviewPosition, scroll]);
83
110
  return (
84
111
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
85
- React.createElement("div", { className: cn(styles.component, { [styles.mobile]: view === 'mobile' }), ref: containerRef, "data-test-id": TestIds.NAVIGATION_BAR, onMouseDown: handlePreviewMouseDown, onMouseUp: handlePreviewMouseUp, onMouseMove: handleMouseNavigationMove }, images.map((image, index) => {
112
+ React.createElement("div", { className: cn(styles.component, {
113
+ [styles.mobile]: view === 'mobile',
114
+ [styles.dragging]: isDragging,
115
+ }), ref: containerRef, "data-test-id": TestIds.NAVIGATION_BAR, onMouseDown: handlePreviewMouseDown, onMouseUp: handlePreviewMouseUp, onMouseMove: handleMouseNavigationMove, onClickCapture: handleClickCapture }, images.map((image, index) => {
86
116
  const active = index === currentSlideIndex;
87
117
  return (React.createElement(ImagePreview, { key: getImageKey(image, index), image: image, active: active, index: index, onSelect: handlePreviewSelect, className: cn(styles.preview, { [styles.mobile]: view === 'mobile' }) }));
88
118
  })));
@@ -1 +1 @@
1
- {"version":3,"file":"Component.js","sources":["../../../src/components/navigation-bar/Component.tsx"],"sourcesContent":["import React, { type FC, useCallback, useContext, useEffect, useRef, useState } from 'react';\nimport cn from 'classnames';\nimport throttle from 'lodash/throttle';\n\nimport { GalleryContext } from '../../context';\nimport { getImageKey, TestIds } from '../../utils';\nimport { ImagePreview } from '../image-preview';\n\nimport styles from './index.module.css';\n\nconst MIN_SCROLL_STEP = 24;\nconst SCROLL_SPEED = 2; // Коэффициент скорости прокрутки (можно настроить)\nconst SCROLL_THRESHOLD = 150; // Расстояние от границы, при котором начинается прокрутка\n\nexport const NavigationBar: FC = () => {\n const containerRef = useRef<HTMLDivElement>(null);\n\n const [isNavMouseDowned, setIsNavMouseDowned] = useState<boolean>(false);\n\n const { images, currentSlideIndex, setCurrentSlideIndex, getSwiper, setPlayingVideo, view } =\n useContext(GalleryContext);\n\n const swiper = getSwiper();\n\n const handlePreviewSelect = (index: number) => {\n setCurrentSlideIndex?.(index);\n\n if (swiper) {\n setPlayingVideo(true);\n swiper.slideTo(index);\n }\n };\n\n const scroll = useCallback((scrollValue: number) => {\n if (containerRef.current) {\n containerRef.current.scroll({\n top: 0,\n left: containerRef.current.scrollLeft + scrollValue,\n behavior: 'smooth',\n });\n }\n }, []);\n\n const handlePreviewMouseDown = () => {\n setIsNavMouseDowned(true);\n };\n\n const handlePreviewMouseUp = () => {\n setIsNavMouseDowned(false);\n if (containerRef.current) {\n containerRef.current.style.scrollBehavior = 'auto'; // Отключаем плавность для резкой остановки\n }\n };\n\n const handleMouseNavigationMove = throttle((e: React.MouseEvent<HTMLDivElement>) => {\n if (!containerRef.current || !isNavMouseDowned) return;\n\n const container = containerRef.current;\n const { width: containerWidth, left: containerLeft } = container.getBoundingClientRect();\n const mouseX = e.clientX;\n\n // Если курсор близко к правой границе\n if (mouseX > containerWidth + containerLeft - SCROLL_THRESHOLD) {\n const scrollValue =\n (mouseX - (containerWidth + containerLeft - SCROLL_THRESHOLD)) * SCROLL_SPEED;\n\n container.scrollBy({ left: scrollValue, behavior: 'smooth' });\n }\n // Если курсор близко к левой границе\n else if (mouseX < containerLeft + SCROLL_THRESHOLD) {\n const scrollValue = (mouseX - (containerLeft + SCROLL_THRESHOLD)) * SCROLL_SPEED;\n\n container.scrollBy({ left: scrollValue, behavior: 'smooth' });\n }\n }, 150);\n\n const handlePreviewPosition = useCallback(\n (preview: Element, containerWidth: number) => {\n const { right, left, x } = preview.getBoundingClientRect();\n\n if (view === 'mobile') {\n scroll(x - containerWidth / 2 + MIN_SCROLL_STEP); // Передвигаем в центр активное превью\n }\n\n if (right > containerWidth) {\n const scrollValue = right - containerWidth + MIN_SCROLL_STEP;\n\n scroll(scrollValue);\n } else if (left < 0) {\n const scrollValue = left - MIN_SCROLL_STEP;\n\n scroll(scrollValue);\n }\n },\n [scroll, view],\n );\n\n useEffect(() => {\n if (containerRef.current) {\n const { width: containerWidth } = containerRef.current.getBoundingClientRect();\n\n const activePreview = containerRef.current.children[currentSlideIndex];\n\n if (activePreview) {\n handlePreviewPosition(activePreview, containerWidth);\n }\n }\n }, [currentSlideIndex, handlePreviewPosition, scroll]);\n\n return (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n className={cn(styles.component, { [styles.mobile]: view === 'mobile' })}\n ref={containerRef}\n data-test-id={TestIds.NAVIGATION_BAR}\n onMouseDown={handlePreviewMouseDown}\n onMouseUp={handlePreviewMouseUp}\n onMouseMove={handleMouseNavigationMove}\n >\n {images.map((image, index) => {\n const active = index === currentSlideIndex;\n\n return (\n <ImagePreview\n key={getImageKey(image, index)}\n image={image}\n active={active}\n index={index}\n onSelect={handlePreviewSelect}\n className={cn(styles.preview, { [styles.mobile]: view === 'mobile' })}\n />\n );\n })}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Component.js","sources":["../../../src/components/navigation-bar/Component.tsx"],"sourcesContent":["import React, { type FC, useCallback, useContext, useEffect, useRef, useState } from 'react';\nimport cn from 'classnames';\n\nimport { isClient } from '@alfalab/core-components-shared';\n\nimport { GalleryContext } from '../../context';\nimport { getImageKey, TestIds } from '../../utils';\nimport { ImagePreview } from '../image-preview';\n\nimport styles from './index.module.css';\n\nconst MIN_SCROLL_STEP = 24;\nconst DRAG_CLICK_THRESHOLD = 5;\n\nexport const NavigationBar: FC = () => {\n const containerRef = useRef<HTMLDivElement>(null);\n const dragStartXRef = useRef<number>(0);\n const dragStartScrollLeftRef = useRef<number>(0);\n const suppressClickRef = useRef<boolean>(false);\n\n const [isDragging, setIsDragging] = useState<boolean>(false);\n\n const { images, currentSlideIndex, setCurrentSlideIndex, getSwiper, setPlayingVideo, view } =\n useContext(GalleryContext);\n\n const swiper = getSwiper();\n\n const handlePreviewSelect = (index: number) => {\n setCurrentSlideIndex?.(index);\n\n if (swiper) {\n setPlayingVideo(true);\n swiper.slideTo(index);\n }\n };\n\n const scroll = useCallback((scrollValue: number) => {\n if (containerRef.current) {\n containerRef.current.scroll({\n top: 0,\n left: containerRef.current.scrollLeft + scrollValue,\n behavior: 'smooth',\n });\n }\n }, []);\n\n const handlePreviewMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {\n if (e.button !== 0 || !containerRef.current) {\n return;\n }\n\n dragStartXRef.current = e.clientX;\n dragStartScrollLeftRef.current = containerRef.current.scrollLeft;\n suppressClickRef.current = false;\n setIsDragging(true);\n };\n\n const handlePreviewMouseUp = useCallback(() => {\n setIsDragging(false);\n }, []);\n\n const dragTo = useCallback((clientX: number) => {\n const container = containerRef.current;\n\n if (!container) {\n return;\n }\n\n const deltaX = clientX - dragStartXRef.current;\n\n if (Math.abs(deltaX) > DRAG_CLICK_THRESHOLD) {\n suppressClickRef.current = true;\n }\n\n container.scrollLeft = dragStartScrollLeftRef.current - deltaX;\n }, []);\n\n const handleMouseNavigationMove = (e: React.MouseEvent<HTMLDivElement>) => {\n if (!isDragging) {\n return;\n }\n\n dragTo(e.clientX);\n };\n\n const handleClickCapture = (e: React.MouseEvent<HTMLDivElement>) => {\n if (!suppressClickRef.current) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n suppressClickRef.current = false;\n };\n\n useEffect(() => {\n if (!isClient() || !isDragging) {\n return undefined;\n }\n\n const handleDocumentMouseMove = (event: MouseEvent) => {\n dragTo(event.clientX);\n };\n\n document.addEventListener('mousemove', handleDocumentMouseMove);\n document.addEventListener('mouseup', handlePreviewMouseUp);\n\n return () => {\n document.removeEventListener('mousemove', handleDocumentMouseMove);\n document.removeEventListener('mouseup', handlePreviewMouseUp);\n };\n }, [dragTo, handlePreviewMouseUp, isDragging]);\n\n const handlePreviewPosition = useCallback(\n (preview: Element, containerWidth: number) => {\n const { right, left, x } = preview.getBoundingClientRect();\n\n if (view === 'mobile') {\n scroll(x - containerWidth / 2 + MIN_SCROLL_STEP); // Передвигаем в центр активное превью\n }\n\n if (right > containerWidth) {\n const scrollValue = right - containerWidth + MIN_SCROLL_STEP;\n\n scroll(scrollValue);\n } else if (left < 0) {\n const scrollValue = left - MIN_SCROLL_STEP;\n\n scroll(scrollValue);\n }\n },\n [scroll, view],\n );\n\n useEffect(() => {\n if (containerRef.current) {\n const { width: containerWidth } = containerRef.current.getBoundingClientRect();\n\n const activePreview = containerRef.current.children[currentSlideIndex];\n\n if (activePreview) {\n handlePreviewPosition(activePreview, containerWidth);\n }\n }\n }, [currentSlideIndex, handlePreviewPosition, scroll]);\n\n return (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n className={cn(styles.component, {\n [styles.mobile]: view === 'mobile',\n [styles.dragging]: isDragging,\n })}\n ref={containerRef}\n data-test-id={TestIds.NAVIGATION_BAR}\n onMouseDown={handlePreviewMouseDown}\n onMouseUp={handlePreviewMouseUp}\n onMouseMove={handleMouseNavigationMove}\n onClickCapture={handleClickCapture}\n >\n {images.map((image, index) => {\n const active = index === currentSlideIndex;\n\n return (\n <ImagePreview\n key={getImageKey(image, index)}\n image={image}\n active={active}\n index={index}\n onSelect={handlePreviewSelect}\n className={cn(styles.preview, { [styles.mobile]: view === 'mobile' })}\n />\n );\n })}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -6,9 +6,9 @@
6
6
  --gap-4: 4px;
7
7
  --gap-8: 8px;
8
8
  --gap-12: 12px;
9
- --gap-24: 24px;
9
+ --gap-32: 32px;
10
10
  }
11
- .gallery__component_jvjzj {
11
+ .gallery__component_11mwi {
12
12
  display: flex;
13
13
  flex-wrap: nowrap;
14
14
  align-content: center;
@@ -16,29 +16,39 @@
16
16
  flex-shrink: 0;
17
17
  overflow-x: auto;
18
18
  box-sizing: border-box;
19
- padding: var(--gap-12) var(--gap-24);
19
+ padding: var(--gap-12) var(--gap-32);
20
20
  scrollbar-width: none;
21
21
  background-color: var(--color-static-neutral-0-inverted);
22
+ cursor: grab;
23
+ -webkit-user-select: none;
24
+ -moz-user-select: none;
25
+ user-select: none;
22
26
  }
23
- .gallery__component_jvjzj.gallery__mobile_jvjzj {
24
- padding: var(--gap-8) var(--gap-24);
27
+ .gallery__component_11mwi.gallery__mobile_11mwi {
28
+ padding: var(--gap-8);
25
29
  }
26
- .gallery__component_jvjzj::-webkit-scrollbar {
30
+ .gallery__component_11mwi.gallery__dragging_11mwi {
31
+ cursor: grabbing;
32
+ }
33
+ .gallery__component_11mwi.gallery__dragging_11mwi * {
34
+ cursor: grabbing;
35
+ }
36
+ .gallery__component_11mwi::-webkit-scrollbar {
27
37
  display: none;
28
38
  }
29
- .gallery__previews_jvjzj {
39
+ .gallery__previews_11mwi {
30
40
  display: flex;
31
41
  }
32
- .gallery__preview_jvjzj {
42
+ .gallery__preview_11mwi {
33
43
  flex-shrink: 0;
34
44
  margin-right: var(--gap-4);
35
45
  }
36
- .gallery__preview_jvjzj.gallery__mobile_jvjzj {
46
+ .gallery__preview_11mwi.gallery__mobile_11mwi {
37
47
  margin-right: var(--gap-2);
38
48
  }
39
- .gallery__preview_jvjzj:first-child {
49
+ .gallery__preview_11mwi:first-child {
40
50
  margin-left: auto;
41
51
  }
42
- .gallery__preview_jvjzj:last-child {
52
+ .gallery__preview_11mwi:last-child {
43
53
  margin-right: auto;
44
54
  }
@@ -1,6 +1,6 @@
1
1
  import './index.css';
2
2
 
3
- const styles = {"component":"gallery__component_jvjzj","mobile":"gallery__mobile_jvjzj","preview":"gallery__preview_jvjzj"};
3
+ const styles = {"component":"gallery__component_11mwi","mobile":"gallery__mobile_11mwi","dragging":"gallery__dragging_11mwi","preview":"gallery__preview_11mwi"};
4
4
 
5
5
  export { styles as default };
6
6
  //# sourceMappingURL=index.module.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.css.js","sources":["../../src/components/navigation-bar/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n.component {\n display: flex;\n flex-wrap: nowrap;\n align-content: center;\n align-items: center;\n flex-shrink: 0;\n overflow-x: auto;\n box-sizing: border-box;\n padding: var(--gap-12) var(--gap-24);\n scrollbar-width: none;\n background-color: var(--color-static-neutral-0-inverted);\n\n &.mobile {\n padding: var(--gap-8) var(--gap-24);\n }\n\n &::-webkit-scrollbar {\n display: none;\n }\n}\n\n.previews {\n display: flex;\n}\n\n.preview {\n flex-shrink: 0;\n margin-right: var(--gap-4);\n\n &.mobile {\n margin-right: var(--gap-2);\n }\n\n &:first-child {\n margin-left: auto;\n }\n\n &:last-child {\n margin-right: auto;\n }\n}\n"],"names":[],"mappings":";;AAEgB,eAAe,CAAC,WAAW,CAAC,0BAA0B,CAAC,QAAQ,CAAC,uBAAuB,CAAsC,SAAS,CAAC,wBAAwB,CAAC;;;;"}
1
+ {"version":3,"file":"index.module.css.js","sources":["../../src/components/navigation-bar/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n.component {\n display: flex;\n flex-wrap: nowrap;\n align-content: center;\n align-items: center;\n flex-shrink: 0;\n overflow-x: auto;\n box-sizing: border-box;\n padding: var(--gap-12) var(--gap-32);\n scrollbar-width: none;\n background-color: var(--color-static-neutral-0-inverted);\n cursor: grab;\n user-select: none;\n\n &.mobile {\n padding: var(--gap-8);\n }\n\n &.dragging {\n cursor: grabbing;\n\n & * {\n cursor: grabbing;\n }\n }\n\n &::-webkit-scrollbar {\n display: none;\n }\n}\n\n.previews {\n display: flex;\n}\n\n.preview {\n flex-shrink: 0;\n margin-right: var(--gap-4);\n\n &.mobile {\n margin-right: var(--gap-2);\n }\n\n &:first-child {\n margin-left: auto;\n }\n\n &:last-child {\n margin-right: auto;\n }\n}\n"],"names":[],"mappings":";;AAEgB,eAAe,CAAC,WAAW,CAAC,0BAA0B,CAAC,QAAQ,CAAC,uBAAuB,CAAC,UAAU,CAAC,yBAAyB,CAAsC,SAAS,CAAC,wBAAwB,CAAC;;;;"}
@@ -3,7 +3,7 @@
3
3
  --gap-16: 16px;
4
4
  --gap-32: 32px;
5
5
  }
6
- .gallery__subtitles_j6roo {
6
+ .gallery__subtitles_ljsjn {
7
7
  position: absolute;
8
8
  align-self: flex-end;
9
9
  padding: var(--gap-0) var(--gap-32);
@@ -16,10 +16,10 @@
16
16
  opacity 500ms ease-in-out,
17
17
  margin-bottom 270ms ease-in-out;
18
18
  }
19
- .gallery__subtitles_j6roo.gallery__mobile_j6roo {
19
+ .gallery__subtitles_ljsjn.gallery__mobile_ljsjn {
20
20
  position: static;
21
21
  position: initial;
22
22
  }
23
- .gallery__hideSubtitles_j6roo {
23
+ .gallery__hideSubtitles_ljsjn {
24
24
  opacity: 0;
25
25
  }
@@ -1,6 +1,6 @@
1
1
  import './index.css';
2
2
 
3
- const styles = {"subtitles":"gallery__subtitles_j6roo","mobile":"gallery__mobile_j6roo","hideSubtitles":"gallery__hideSubtitles_j6roo"};
3
+ const styles = {"subtitles":"gallery__subtitles_ljsjn","mobile":"gallery__mobile_ljsjn","hideSubtitles":"gallery__hideSubtitles_ljsjn"};
4
4
 
5
5
  export { styles as default };
6
6
  //# sourceMappingURL=index.module.css.js.map
@@ -1,4 +1,4 @@
1
- export declare const SWIPE_THRESHOLD = -250;
1
+ export declare const SWIPE_THRESHOLD = 250;
2
2
  export declare const PREVIEW_WIDTH_MOBILE = 46;
3
3
  export declare const PREVIEW_HEIGHT_MOBILE = 46;
4
4
  export declare const PREVIEW_WIDTH_DESKTOP = 56;
@@ -1,4 +1,4 @@
1
- const SWIPE_THRESHOLD = -250;
1
+ const SWIPE_THRESHOLD = 250;
2
2
  const PREVIEW_WIDTH_MOBILE = 46;
3
3
  const PREVIEW_HEIGHT_MOBILE = 46;
4
4
  const PREVIEW_WIDTH_DESKTOP = 56;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sources":["../src/constants.ts"],"sourcesContent":["export const SWIPE_THRESHOLD = -250;\n\nexport const PREVIEW_WIDTH_MOBILE = 46;\nexport const PREVIEW_HEIGHT_MOBILE = 46;\n\nexport const PREVIEW_WIDTH_DESKTOP = 56;\nexport const PREVIEW_HEIGHT_DESKTOP = 56;\n\nexport const PREVIEW_VIDEO_MULTIPLIER = 12;\n"],"names":[],"mappings":"AAAa,MAAA,eAAe,GAAG;AAExB,MAAM,oBAAoB,GAAG;AAC7B,MAAM,qBAAqB,GAAG;AAE9B,MAAM,qBAAqB,GAAG;AAC9B,MAAM,sBAAsB,GAAG;AAE/B,MAAM,wBAAwB,GAAG;;;;"}
1
+ {"version":3,"file":"constants.js","sources":["../src/constants.ts"],"sourcesContent":["export const SWIPE_THRESHOLD = 250;\n\nexport const PREVIEW_WIDTH_MOBILE = 46;\nexport const PREVIEW_HEIGHT_MOBILE = 46;\n\nexport const PREVIEW_WIDTH_DESKTOP = 56;\nexport const PREVIEW_HEIGHT_DESKTOP = 56;\n\nexport const PREVIEW_VIDEO_MULTIPLIER = 12;\n"],"names":[],"mappings":"AAAO,MAAM,eAAe,GAAG;AAExB,MAAM,oBAAoB,GAAG;AAC7B,MAAM,qBAAqB,GAAG;AAE9B,MAAM,qBAAqB,GAAG;AAC9B,MAAM,sBAAsB,GAAG;AAE/B,MAAM,wBAAwB,GAAG;;;;"}