funuicss 3.7.8 → 3.7.10

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/ui/video/Video.js CHANGED
@@ -44,6 +44,42 @@ var __importStar = (this && this.__importStar) || (function () {
44
44
  return result;
45
45
  };
46
46
  })();
47
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
48
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
49
+ return new (P || (P = Promise))(function (resolve, reject) {
50
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
51
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
52
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
53
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
54
+ });
55
+ };
56
+ var __generator = (this && this.__generator) || function (thisArg, body) {
57
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
58
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
59
+ function verb(n) { return function (v) { return step([n, v]); }; }
60
+ function step(op) {
61
+ if (f) throw new TypeError("Generator is already executing.");
62
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
63
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
64
+ if (y = 0, t) op = [op[0] & 2, t.value];
65
+ switch (op[0]) {
66
+ case 0: case 1: t = op; break;
67
+ case 4: _.label++; return { value: op[1], done: false };
68
+ case 5: _.label++; y = op[1]; op = [0]; continue;
69
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
70
+ default:
71
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
72
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
73
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
74
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
75
+ if (t[2]) _.ops.pop();
76
+ _.trys.pop(); continue;
77
+ }
78
+ op = body.call(thisArg, _);
79
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
80
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
81
+ }
82
+ };
47
83
  var __rest = (this && this.__rest) || function (s, e) {
48
84
  var t = {};
49
85
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -62,51 +98,263 @@ Object.defineProperty(exports, "__esModule", { value: true });
62
98
  exports.default = Video;
63
99
  var react_1 = __importStar(require("react"));
64
100
  var pi_1 = require("react-icons/pi");
101
+ var tfi_1 = require("react-icons/tfi");
65
102
  var Text_1 = __importDefault(require("../text/Text"));
66
103
  var RowFlex_1 = __importDefault(require("../specials/RowFlex"));
67
104
  var ToolTip_1 = __importDefault(require("../tooltip/ToolTip"));
68
105
  var Circle_1 = __importDefault(require("../specials/Circle"));
69
106
  var Tip_1 = __importDefault(require("../tooltip/Tip"));
70
- var tfi_1 = require("react-icons/tfi");
71
107
  var videoFunctions_1 = require("./videoFunctions");
72
108
  var videoShortcuts_1 = require("./videoShortcuts");
109
+ var getDynamicIcon_1 = require("../../utils/getDynamicIcon");
110
+ // Configuration hook
111
+ var useComponentConfiguration = function (componentName, variant) {
112
+ if (variant === void 0) { variant = ''; }
113
+ // In a real implementation, this would come from a theme context or configuration file
114
+ var getComponentConfig = function () {
115
+ var baseConfig = {
116
+ Video: {
117
+ default: {
118
+ showControls: true,
119
+ showPlayPause: true,
120
+ showProgress: true,
121
+ showVolume: true,
122
+ showTime: true,
123
+ showFullscreen: true,
124
+ showDownload: true,
125
+ showSeekButtons: true,
126
+ spacebarPlay: true,
127
+ autoPlay: false,
128
+ loop: false,
129
+ muted: false,
130
+ seekAmount: 10,
131
+ hideControlsDelay: 3000,
132
+ funcss: '',
133
+ containerCss: '',
134
+ videoCss: '',
135
+ controlsCss: '',
136
+ progressCss: '',
137
+ progressBarCss: '',
138
+ timeCss: '',
139
+ playCss: '',
140
+ pauseCss: '',
141
+ volumeCss: '',
142
+ fullscreenCss: '',
143
+ downloadCss: '',
144
+ rewindCss: '',
145
+ forwardCss: '',
146
+ buttonCss: '',
147
+ },
148
+ minimal: {
149
+ showControls: true,
150
+ showPlayPause: true,
151
+ showProgress: true,
152
+ showVolume: false,
153
+ showTime: false,
154
+ showFullscreen: false,
155
+ showDownload: false,
156
+ showSeekButtons: false,
157
+ controlsCss: 'minimal-controls',
158
+ buttonCss: 'minimal-btn',
159
+ },
160
+ embedded: {
161
+ showControls: false,
162
+ autoPlay: true,
163
+ muted: true,
164
+ loop: true,
165
+ containerCss: 'embedded-video',
166
+ },
167
+ fullFeatured: {
168
+ showControls: true,
169
+ showPlayPause: true,
170
+ showProgress: true,
171
+ showVolume: true,
172
+ showTime: true,
173
+ showFullscreen: true,
174
+ showDownload: true,
175
+ showSeekButtons: true,
176
+ controlsCss: 'full-featured-controls',
177
+ buttonCss: 'featured-btn',
178
+ },
179
+ theater: {
180
+ showControls: true,
181
+ containerCss: 'theater-mode',
182
+ videoCss: 'theater-video',
183
+ controlsCss: 'theater-controls',
184
+ fullscreenCss: 'theater-fullscreen',
185
+ }
186
+ }
187
+ };
188
+ return baseConfig[componentName] || {};
189
+ };
190
+ var mergeWithLocal = function (localProps) {
191
+ var config = getComponentConfig();
192
+ var variantConfig = variant && config[variant] ? config[variant] : {};
193
+ var defaultConfig = config.default || {};
194
+ // Merge: default config < variant config < local props (local props have highest priority)
195
+ var mergedProps = __assign(__assign(__assign({}, defaultConfig), variantConfig), localProps);
196
+ return {
197
+ props: mergedProps,
198
+ variantConfig: variantConfig,
199
+ defaultConfig: defaultConfig,
200
+ };
201
+ };
202
+ return {
203
+ mergeWithLocal: mergeWithLocal,
204
+ getComponentConfig: getComponentConfig,
205
+ };
206
+ };
73
207
  function Video(_a) {
74
- var src = _a.src, poster = _a.poster, onDuration = _a.onDuration, isPause = _a.isPause, className = _a.className, autoPlay = _a.autoPlay, _b = _a.spacebarPlay, spacebarPlay = _b === void 0 ? true : _b, rest = __rest(_a, ["src", "poster", "onDuration", "isPause", "className", "autoPlay", "spacebarPlay"]);
208
+ var _this = this;
209
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
210
+ var src = _a.src, poster = _a.poster, onDuration = _a.onDuration, onEnded = _a.onEnded, isPause = _a.isPause, spacebarPlay = _a.spacebarPlay, _7 = _a.className, className = _7 === void 0 ? '' : _7, autoPlay = _a.autoPlay, showControls = _a.showControls, showPlayPause = _a.showPlayPause, showProgress = _a.showProgress, showVolume = _a.showVolume, showTime = _a.showTime, showFullscreen = _a.showFullscreen, showDownload = _a.showDownload, showSeekButtons = _a.showSeekButtons, playIcon = _a.playIcon, pauseIcon = _a.pauseIcon, fullscreenIcon = _a.fullscreenIcon, downloadIcon = _a.downloadIcon, volumeIcon = _a.volumeIcon, muteIcon = _a.muteIcon, rewindIcon = _a.rewindIcon, forwardIcon = _a.forwardIcon, hideControlsDelay = _a.hideControlsDelay, loop = _a.loop, muted = _a.muted, seekAmount = _a.seekAmount, _8 = _a.funcss, funcss = _8 === void 0 ? '' : _8, _9 = _a.containerCss, containerCss = _9 === void 0 ? '' : _9, _10 = _a.videoCss, videoCss = _10 === void 0 ? '' : _10, _11 = _a.controlsCss, controlsCss = _11 === void 0 ? '' : _11, _12 = _a.progressCss, progressCss = _12 === void 0 ? '' : _12, _13 = _a.progressBarCss, progressBarCss = _13 === void 0 ? '' : _13, _14 = _a.timeCss, timeCss = _14 === void 0 ? '' : _14, _15 = _a.playCss, playCss = _15 === void 0 ? '' : _15, _16 = _a.pauseCss, pauseCss = _16 === void 0 ? '' : _16, _17 = _a.volumeCss, volumeCss = _17 === void 0 ? '' : _17, _18 = _a.fullscreenCss, fullscreenCss = _18 === void 0 ? '' : _18, _19 = _a.downloadCss, downloadCss = _19 === void 0 ? '' : _19, _20 = _a.rewindCss, rewindCss = _20 === void 0 ? '' : _20, _21 = _a.forwardCss, forwardCss = _21 === void 0 ? '' : _21, _22 = _a.buttonCss, buttonCss = _22 === void 0 ? '' : _22, _23 = _a.variant, variant = _23 === void 0 ? '' : _23, rest = __rest(_a, ["src", "poster", "onDuration", "onEnded", "isPause", "spacebarPlay", "className", "autoPlay", "showControls", "showPlayPause", "showProgress", "showVolume", "showTime", "showFullscreen", "showDownload", "showSeekButtons", "playIcon", "pauseIcon", "fullscreenIcon", "downloadIcon", "volumeIcon", "muteIcon", "rewindIcon", "forwardIcon", "hideControlsDelay", "loop", "muted", "seekAmount", "funcss", "containerCss", "videoCss", "controlsCss", "progressCss", "progressBarCss", "timeCss", "playCss", "pauseCss", "volumeCss", "fullscreenCss", "downloadCss", "rewindCss", "forwardCss", "buttonCss", "variant"]);
211
+ var mergeWithLocal = useComponentConfiguration('Video', variant).mergeWithLocal;
212
+ // Create local props object - these will override config props
213
+ var localProps = __assign({ src: src, poster: poster, onDuration: onDuration, onEnded: onEnded, isPause: isPause, spacebarPlay: spacebarPlay, className: className, autoPlay: autoPlay, showControls: showControls, showPlayPause: showPlayPause, showProgress: showProgress, showVolume: showVolume, showTime: showTime, showFullscreen: showFullscreen, showDownload: showDownload, showSeekButtons: showSeekButtons, playIcon: playIcon, pauseIcon: pauseIcon, fullscreenIcon: fullscreenIcon, downloadIcon: downloadIcon, volumeIcon: volumeIcon, muteIcon: muteIcon, rewindIcon: rewindIcon, forwardIcon: forwardIcon, hideControlsDelay: hideControlsDelay, loop: loop, muted: muted, seekAmount: seekAmount, funcss: funcss, containerCss: containerCss, videoCss: videoCss, controlsCss: controlsCss, progressCss: progressCss, progressBarCss: progressBarCss, timeCss: timeCss, playCss: playCss, pauseCss: pauseCss, volumeCss: volumeCss, fullscreenCss: fullscreenCss, downloadCss: downloadCss, rewindCss: rewindCss, forwardCss: forwardCss, buttonCss: buttonCss }, rest);
214
+ // Merge with config - LOCAL PROPS OVERRIDE CONFIG
215
+ var mergedProps = mergeWithLocal(localProps).props;
216
+ // Extract final values - local props take precedence
217
+ var final = {
218
+ src: mergedProps.src,
219
+ poster: mergedProps.poster,
220
+ onDuration: mergedProps.onDuration,
221
+ onEnded: mergedProps.onEnded,
222
+ isPause: mergedProps.isPause,
223
+ spacebarPlay: (_b = mergedProps.spacebarPlay) !== null && _b !== void 0 ? _b : true,
224
+ className: (_c = mergedProps.className) !== null && _c !== void 0 ? _c : '',
225
+ autoPlay: (_d = mergedProps.autoPlay) !== null && _d !== void 0 ? _d : false,
226
+ showControls: (_e = mergedProps.showControls) !== null && _e !== void 0 ? _e : true,
227
+ showPlayPause: (_f = mergedProps.showPlayPause) !== null && _f !== void 0 ? _f : true,
228
+ showProgress: (_g = mergedProps.showProgress) !== null && _g !== void 0 ? _g : true,
229
+ showVolume: (_h = mergedProps.showVolume) !== null && _h !== void 0 ? _h : true,
230
+ showTime: (_j = mergedProps.showTime) !== null && _j !== void 0 ? _j : true,
231
+ showFullscreen: (_k = mergedProps.showFullscreen) !== null && _k !== void 0 ? _k : true,
232
+ showDownload: (_l = mergedProps.showDownload) !== null && _l !== void 0 ? _l : true,
233
+ showSeekButtons: (_m = mergedProps.showSeekButtons) !== null && _m !== void 0 ? _m : true,
234
+ playIcon: mergedProps.playIcon,
235
+ pauseIcon: mergedProps.pauseIcon,
236
+ fullscreenIcon: mergedProps.fullscreenIcon,
237
+ downloadIcon: mergedProps.downloadIcon,
238
+ volumeIcon: mergedProps.volumeIcon,
239
+ muteIcon: mergedProps.muteIcon,
240
+ rewindIcon: mergedProps.rewindIcon,
241
+ forwardIcon: mergedProps.forwardIcon,
242
+ hideControlsDelay: (_o = mergedProps.hideControlsDelay) !== null && _o !== void 0 ? _o : 3000,
243
+ loop: (_p = mergedProps.loop) !== null && _p !== void 0 ? _p : false,
244
+ muted: (_q = mergedProps.muted) !== null && _q !== void 0 ? _q : false,
245
+ seekAmount: (_r = mergedProps.seekAmount) !== null && _r !== void 0 ? _r : 10,
246
+ funcss: (_s = mergedProps.funcss) !== null && _s !== void 0 ? _s : '',
247
+ containerCss: (_t = mergedProps.containerCss) !== null && _t !== void 0 ? _t : '',
248
+ videoCss: (_u = mergedProps.videoCss) !== null && _u !== void 0 ? _u : '',
249
+ controlsCss: (_v = mergedProps.controlsCss) !== null && _v !== void 0 ? _v : '',
250
+ progressCss: (_w = mergedProps.progressCss) !== null && _w !== void 0 ? _w : '',
251
+ progressBarCss: (_x = mergedProps.progressBarCss) !== null && _x !== void 0 ? _x : '',
252
+ timeCss: (_y = mergedProps.timeCss) !== null && _y !== void 0 ? _y : '',
253
+ playCss: (_z = mergedProps.playCss) !== null && _z !== void 0 ? _z : '',
254
+ pauseCss: (_0 = mergedProps.pauseCss) !== null && _0 !== void 0 ? _0 : '',
255
+ volumeCss: (_1 = mergedProps.volumeCss) !== null && _1 !== void 0 ? _1 : '',
256
+ fullscreenCss: (_2 = mergedProps.fullscreenCss) !== null && _2 !== void 0 ? _2 : '',
257
+ downloadCss: (_3 = mergedProps.downloadCss) !== null && _3 !== void 0 ? _3 : '',
258
+ rewindCss: (_4 = mergedProps.rewindCss) !== null && _4 !== void 0 ? _4 : '',
259
+ forwardCss: (_5 = mergedProps.forwardCss) !== null && _5 !== void 0 ? _5 : '',
260
+ buttonCss: (_6 = mergedProps.buttonCss) !== null && _6 !== void 0 ? _6 : '',
261
+ };
75
262
  var videoRef = (0, react_1.useRef)(null);
76
263
  var containerRef = (0, react_1.useRef)(null);
77
264
  var animationFrameRef = (0, react_1.useRef)(null);
78
- var _c = (0, react_1.useState)(false), isPlaying = _c[0], setIsPlaying = _c[1];
79
- var _d = (0, react_1.useState)(0), currentTime = _d[0], setCurrentTime = _d[1];
80
- var _e = (0, react_1.useState)(0), duration = _e[0], setDuration = _e[1];
81
- var _f = (0, react_1.useState)(1), volume = _f[0], setVolume = _f[1];
82
- var _g = (0, react_1.useState)(false), isFullScreen = _g[0], setIsFullScreen = _g[1];
83
- var _h = (0, react_1.useState)(false), showVolume = _h[0], setShowVolume = _h[1];
84
- var _j = (0, react_1.useState)(true), isMouseMoving = _j[0], setIsMouseMoving = _j[1];
85
- var _k = (0, react_1.useState)(false), hasStarted = _k[0], setHasStarted = _k[1];
86
- var handleVideoEnd = function () {
87
- setIsPlaying(false);
88
- setCurrentTime(duration); // optional
89
- };
265
+ var _24 = (0, react_1.useState)(false), isPlaying = _24[0], setIsPlaying = _24[1];
266
+ var _25 = (0, react_1.useState)(0), currentTime = _25[0], setCurrentTime = _25[1];
267
+ var _26 = (0, react_1.useState)(0), duration = _26[0], setDuration = _26[1];
268
+ var _27 = (0, react_1.useState)(final.muted ? 0 : 1), volume = _27[0], setVolume = _27[1];
269
+ var _28 = (0, react_1.useState)(final.muted), isMuted = _28[0], setIsMuted = _28[1];
270
+ var _29 = (0, react_1.useState)(false), isFullScreen = _29[0], setIsFullScreen = _29[1];
271
+ var _30 = (0, react_1.useState)(false), showControlsState = _30[0], setShowControlsState = _30[1];
272
+ var _31 = (0, react_1.useState)(false), hasStarted = _31[0], setHasStarted = _31[1];
273
+ var _32 = (0, react_1.useState)(false), isHoveringProgress = _32[0], setIsHoveringProgress = _32[1];
274
+ var _33 = (0, react_1.useState)(false), isHoveringVolume = _33[0], setIsHoveringVolume = _33[1];
275
+ // Dynamic icon states
276
+ var _34 = (0, react_1.useState)(null), dynamicPlayIcon = _34[0], setDynamicPlayIcon = _34[1];
277
+ var _35 = (0, react_1.useState)(null), dynamicPauseIcon = _35[0], setDynamicPauseIcon = _35[1];
278
+ var _36 = (0, react_1.useState)(null), dynamicFullscreenIcon = _36[0], setDynamicFullscreenIcon = _36[1];
279
+ var _37 = (0, react_1.useState)(null), dynamicDownloadIcon = _37[0], setDynamicDownloadIcon = _37[1];
280
+ var _38 = (0, react_1.useState)(null), dynamicVolumeIcon = _38[0], setDynamicVolumeIcon = _38[1];
281
+ var _39 = (0, react_1.useState)(null), dynamicMuteIcon = _39[0], setDynamicMuteIcon = _39[1];
282
+ var _40 = (0, react_1.useState)(null), dynamicRewindIcon = _40[0], setDynamicRewindIcon = _40[1];
283
+ var _41 = (0, react_1.useState)(null), dynamicForwardIcon = _41[0], setDynamicForwardIcon = _41[1];
284
+ // Helper function to load dynamic icons
285
+ var loadDynamicIcon = function (iconProp, setter, defaultIcon) { return __awaiter(_this, void 0, void 0, function () {
286
+ var iconNode;
287
+ return __generator(this, function (_a) {
288
+ switch (_a.label) {
289
+ case 0:
290
+ if (!iconProp) {
291
+ setter(defaultIcon);
292
+ return [2 /*return*/];
293
+ }
294
+ if (!(typeof iconProp === 'string')) return [3 /*break*/, 2];
295
+ return [4 /*yield*/, (0, getDynamicIcon_1.getDynamicIcon)(iconProp)];
296
+ case 1:
297
+ iconNode = _a.sent();
298
+ setter(iconNode || defaultIcon);
299
+ return [3 /*break*/, 3];
300
+ case 2:
301
+ // It's already a ReactNode - use it directly
302
+ setter(iconProp);
303
+ _a.label = 3;
304
+ case 3: return [2 /*return*/];
305
+ }
306
+ });
307
+ }); };
308
+ // Load all dynamic icons on component mount and when icon props change
90
309
  (0, react_1.useEffect)(function () {
91
- var video = videoRef.current;
92
- if (!video)
93
- return;
94
- video.addEventListener('ended', handleVideoEnd);
95
- return function () {
96
- video.removeEventListener('ended', handleVideoEnd);
97
- };
98
- }, [duration]);
310
+ var loadIcons = function () { return __awaiter(_this, void 0, void 0, function () {
311
+ return __generator(this, function (_a) {
312
+ switch (_a.label) {
313
+ case 0: return [4 /*yield*/, Promise.all([
314
+ loadDynamicIcon(final.playIcon, setDynamicPlayIcon, react_1.default.createElement(pi_1.PiPlay, { size: 16 })),
315
+ loadDynamicIcon(final.pauseIcon, setDynamicPauseIcon, react_1.default.createElement(pi_1.PiPause, { size: 16 })),
316
+ loadDynamicIcon(final.fullscreenIcon, setDynamicFullscreenIcon, react_1.default.createElement(pi_1.PiCornersOut, { size: 16 })),
317
+ loadDynamicIcon(final.downloadIcon, setDynamicDownloadIcon, react_1.default.createElement(tfi_1.TfiDownload, { size: 14 })),
318
+ loadDynamicIcon(final.volumeIcon, setDynamicVolumeIcon, react_1.default.createElement(pi_1.PiSpeakerHigh, { size: 16 })),
319
+ loadDynamicIcon(final.muteIcon, setDynamicMuteIcon, react_1.default.createElement(pi_1.PiSpeakerSlash, { size: 16 })),
320
+ loadDynamicIcon(final.rewindIcon, setDynamicRewindIcon, react_1.default.createElement(tfi_1.TfiControlBackward, { size: 14 })),
321
+ loadDynamicIcon(final.forwardIcon, setDynamicForwardIcon, react_1.default.createElement(tfi_1.TfiControlForward, { size: 14 })),
322
+ ])];
323
+ case 1:
324
+ _a.sent();
325
+ return [2 /*return*/];
326
+ }
327
+ });
328
+ }); };
329
+ loadIcons();
330
+ }, [
331
+ final.playIcon, final.pauseIcon, final.fullscreenIcon, final.downloadIcon,
332
+ final.volumeIcon, final.muteIcon, final.rewindIcon, final.forwardIcon
333
+ ]);
334
+ // Helper function to render icon with proper size
335
+ var renderIcon = function (icon, defaultSize) {
336
+ if (defaultSize === void 0) { defaultSize = 16; }
337
+ if (!icon)
338
+ return null;
339
+ // If it's a React element, clone it with the size prop
340
+ if (react_1.default.isValidElement(icon)) {
341
+ return react_1.default.cloneElement(icon, {
342
+ size: icon.props.size || defaultSize
343
+ });
344
+ }
345
+ return icon;
346
+ };
347
+ // Play/Pause functionality
99
348
  var playVideo = function () {
100
349
  var video = videoRef.current;
101
350
  if (video) {
102
- // ✅ if video ended, reset it to start
103
351
  if (video.currentTime === video.duration) {
104
352
  video.currentTime = 0;
105
353
  }
106
354
  video.play().then(function () {
107
355
  setIsPlaying(true);
108
356
  setHasStarted(true);
109
- }).catch(function () { });
357
+ }).catch(console.error);
110
358
  }
111
359
  };
112
360
  var pauseVideo = function () {
@@ -116,24 +364,43 @@ function Video(_a) {
116
364
  setIsPlaying(false);
117
365
  }
118
366
  };
119
- (0, react_1.useEffect)(function () {
120
- var handleKey = function (e) { return (0, videoShortcuts_1.handleKeyDown)(e, isPlaying, playVideo, pauseVideo, spacebarPlay); };
121
- document.addEventListener('keydown', handleKey);
122
- return function () { return document.removeEventListener('keydown', handleKey); };
123
- }, [isPlaying]);
124
367
  var handlePlayPauseToggle = function () {
125
368
  isPlaying ? pauseVideo() : playVideo();
126
369
  };
127
- var handleRewind = function () {
128
- var video = videoRef.current;
129
- if (video)
130
- video.currentTime = Math.max(video.currentTime - 10, 0);
370
+ // Click handlers for different video areas
371
+ var handleVideoClick = function (e) {
372
+ var container = containerRef.current;
373
+ if (!container)
374
+ return;
375
+ var rect = container.getBoundingClientRect();
376
+ var clickX = e.clientX - rect.left;
377
+ var width = rect.width;
378
+ // Divide video into three areas
379
+ var leftArea = width * 0.3;
380
+ var rightArea = width * 0.7;
381
+ if (clickX < leftArea) {
382
+ // Left area - rewind
383
+ handleSeek(-final.seekAmount);
384
+ }
385
+ else if (clickX > rightArea) {
386
+ // Right area - forward
387
+ handleSeek(final.seekAmount);
388
+ }
389
+ else {
390
+ // Middle area - play/pause
391
+ handlePlayPauseToggle();
392
+ }
131
393
  };
132
- var handleForward = function () {
394
+ // Seek functionality
395
+ var handleSeek = function (seconds) {
133
396
  var video = videoRef.current;
134
- if (video)
135
- video.currentTime = Math.min(video.currentTime + 10, duration);
397
+ if (video) {
398
+ video.currentTime = Math.max(0, Math.min(video.currentTime + seconds, duration));
399
+ }
136
400
  };
401
+ var handleRewind = function () { return handleSeek(-final.seekAmount); };
402
+ var handleForward = function () { return handleSeek(final.seekAmount); };
403
+ // Fullscreen functionality
137
404
  var handleToggleFullScreen = function () {
138
405
  var _a, _b;
139
406
  var element = containerRef.current;
@@ -146,6 +413,40 @@ function Video(_a) {
146
413
  (_b = document.exitFullscreen) === null || _b === void 0 ? void 0 : _b.call(document);
147
414
  }
148
415
  };
416
+ // Volume functionality
417
+ var handleVolumeChange = function (e) {
418
+ var newVolume = parseFloat(e.target.value);
419
+ setVolume(newVolume);
420
+ setIsMuted(newVolume === 0);
421
+ if (videoRef.current) {
422
+ videoRef.current.volume = newVolume;
423
+ videoRef.current.muted = newVolume === 0;
424
+ }
425
+ };
426
+ var handleToggleMute = function () {
427
+ var newMuted = !isMuted;
428
+ setIsMuted(newMuted);
429
+ if (videoRef.current) {
430
+ videoRef.current.muted = newMuted;
431
+ if (newMuted) {
432
+ setVolume(0);
433
+ }
434
+ else {
435
+ setVolume(1);
436
+ if (videoRef.current)
437
+ videoRef.current.volume = 1;
438
+ }
439
+ }
440
+ };
441
+ // Progress functionality
442
+ var handleProgressChange = function (e) {
443
+ var newTime = parseFloat(e.target.value);
444
+ if (videoRef.current) {
445
+ videoRef.current.currentTime = newTime;
446
+ }
447
+ setCurrentTime(newTime);
448
+ };
449
+ // Time update animation
149
450
  var updateCurrentTime = (0, react_1.useCallback)(function () {
150
451
  var video = videoRef.current;
151
452
  if (video) {
@@ -153,63 +454,50 @@ function Video(_a) {
153
454
  animationFrameRef.current = requestAnimationFrame(updateCurrentTime);
154
455
  }
155
456
  }, []);
457
+ // Event handlers
156
458
  var handleLoadedMetadata = function () {
459
+ var _a;
157
460
  var video = videoRef.current;
158
461
  if (video) {
159
462
  setDuration(video.duration || 0);
160
- onDuration === null || onDuration === void 0 ? void 0 : onDuration(video.duration);
161
- if (autoPlay) {
463
+ (_a = final.onDuration) === null || _a === void 0 ? void 0 : _a.call(final, video.duration);
464
+ if (final.autoPlay) {
465
+ video.muted = true;
162
466
  video.play().then(function () {
163
- setIsPlaying(true); // ✅ update UI state
467
+ setIsPlaying(true);
164
468
  setHasStarted(true);
165
- }).catch(function () { });
469
+ }).catch(console.error);
166
470
  }
167
471
  }
168
472
  };
169
- (0, react_1.useEffect)(function () {
170
- if (autoPlay && videoRef.current) {
171
- videoRef.current.muted = true; // ✅ important for autoplay to work
172
- videoRef.current.play().then(function () {
173
- setIsPlaying(true);
174
- setHasStarted(true);
175
- }).catch(function (err) {
176
- console.warn('Autoplay failed', err);
177
- });
178
- }
179
- }, [autoPlay]);
180
- var handleProgressBarChange = function (e) {
181
- var newTime = parseFloat(e.target.value);
182
- if (videoRef.current) {
183
- videoRef.current.currentTime = newTime;
184
- }
185
- setCurrentTime(newTime);
186
- };
187
- var handleVolumeChange = function (e) {
188
- if (videoRef.current) {
189
- videoRef.current.muted = false;
473
+ var handleVideoEnd = function () {
474
+ var _a;
475
+ setIsPlaying(false);
476
+ (_a = final.onEnded) === null || _a === void 0 ? void 0 : _a.call(final); // Call the onEnded callback
477
+ if (final.loop && videoRef.current) {
478
+ videoRef.current.currentTime = 0;
479
+ playVideo();
190
480
  }
191
- var newVolume = parseFloat(e.target.value);
192
- setVolume(newVolume);
193
- if (videoRef.current)
194
- videoRef.current.volume = newVolume;
195
481
  };
482
+ // Effects
196
483
  (0, react_1.useEffect)(function () {
197
- if (autoPlay && videoRef.current) {
198
- var playPromise = videoRef.current.play();
199
- if (playPromise !== undefined) {
200
- playPromise.catch(function () { });
201
- }
202
- }
203
- }, [autoPlay]);
484
+ var handleKey = function (e) {
485
+ return (0, videoShortcuts_1.handleKeyDown)(e, isPlaying, playVideo, pauseVideo, final.spacebarPlay);
486
+ };
487
+ document.addEventListener('keydown', handleKey);
488
+ return function () { return document.removeEventListener('keydown', handleKey); };
489
+ }, [isPlaying, final.spacebarPlay]);
204
490
  (0, react_1.useEffect)(function () {
205
- if (videoRef.current) {
206
- videoRef.current.volume = volume;
207
- }
208
- }, [volume]);
491
+ var video = videoRef.current;
492
+ if (!video)
493
+ return;
494
+ video.addEventListener('ended', handleVideoEnd);
495
+ return function () { return video.removeEventListener('ended', handleVideoEnd); };
496
+ }, [final.loop, final.onEnded]);
209
497
  (0, react_1.useEffect)(function () {
210
- if (isPause)
498
+ if (final.isPause)
211
499
  pauseVideo();
212
- }, [isPause]);
500
+ }, [final.isPause]);
213
501
  (0, react_1.useEffect)(function () {
214
502
  var handleFullscreenChange = function () {
215
503
  setIsFullScreen(!!document.fullscreenElement);
@@ -217,24 +505,32 @@ function Video(_a) {
217
505
  document.addEventListener('fullscreenchange', handleFullscreenChange);
218
506
  return function () { return document.removeEventListener('fullscreenchange', handleFullscreenChange); };
219
507
  }, []);
508
+ // Controls visibility with hover
220
509
  (0, react_1.useEffect)(function () {
221
510
  var timer;
222
- var handleMouseMove = function (e) {
223
- var _a;
224
- if ((_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.target)) {
225
- setIsMouseMoving(true);
226
- clearTimeout(timer);
227
- timer = setTimeout(function () { return setIsMouseMoving(false); }, 2000);
228
- }
511
+ var show = function () {
512
+ setShowControlsState(true);
513
+ clearTimeout(timer);
514
+ timer = setTimeout(function () { return setShowControlsState(false); }, final.hideControlsDelay);
229
515
  };
230
- document.addEventListener('mousemove', handleMouseMove);
231
- document.addEventListener('touchstart', handleMouseMove);
516
+ var hide = function () {
517
+ setShowControlsState(false);
518
+ };
519
+ var container = containerRef.current;
520
+ if (container && final.showControls) {
521
+ container.addEventListener('mouseenter', show);
522
+ container.addEventListener('mouseleave', hide);
523
+ container.addEventListener('mousemove', show);
524
+ }
232
525
  return function () {
233
- document.removeEventListener('mousemove', handleMouseMove);
234
- document.removeEventListener('touchstart', handleMouseMove);
526
+ if (container) {
527
+ container.removeEventListener('mouseenter', show);
528
+ container.removeEventListener('mouseleave', hide);
529
+ container.removeEventListener('mousemove', show);
530
+ }
235
531
  clearTimeout(timer);
236
532
  };
237
- }, []);
533
+ }, [final.showControls, final.hideControlsDelay]);
238
534
  (0, react_1.useEffect)(function () {
239
535
  if (isPlaying) {
240
536
  animationFrameRef.current = requestAnimationFrame(updateCurrentTime);
@@ -247,59 +543,50 @@ function Video(_a) {
247
543
  cancelAnimationFrame(animationFrameRef.current);
248
544
  };
249
545
  }, [isPlaying, updateCurrentTime]);
250
- (0, react_1.useEffect)(function () {
251
- return function () {
252
- pauseVideo();
253
- };
254
- }, []);
255
- (0, react_1.useEffect)(function () {
256
- var video = videoRef.current;
257
- if (!video)
258
- return;
259
- var onEnd = function () {
260
- setIsPlaying(false);
261
- };
262
- video.addEventListener('ended', onEnd);
263
- return function () { return video.removeEventListener('ended', onEnd); };
264
- }, []);
265
- return (react_1.default.createElement("div", { ref: containerRef, className: "video_container fit ".concat(className || ''), id: "fun_video_container" },
266
- poster && !hasStarted && !isPlaying && (react_1.default.createElement("div", { style: { backgroundImage: "url(".concat(poster, ")") }, className: "video_poster" })),
267
- react_1.default.createElement("video", __assign({ ref: videoRef, preload: "auto", src: src, className: "video_player fit min-w-200", onClick: handlePlayPauseToggle, onLoadedMetadata: handleLoadedMetadata, playsInline: true, controls: false }, rest)),
268
- react_1.default.createElement("div", { className: "video_controls ".concat(isMouseMoving ? 'show_controls' : 'hide_controls') },
269
- react_1.default.createElement("div", { className: " animated fade-in pr-5 pl-5" },
270
- react_1.default.createElement(RowFlex_1.default, { gap: 0.3, funcss: 'mb-2', alignItems: "center" },
271
- react_1.default.createElement("div", { className: "col width-100-p" },
272
- react_1.default.createElement("input", { type: "range", min: 0, max: duration, value: currentTime, onChange: handleProgressBarChange, className: "width-100-p videoSlider styled-slider m-0", "aria-label": "Progress bar", style: { '--progress': "".concat((currentTime / duration) * 100) } })))),
273
- react_1.default.createElement("div", { className: "_center-play-icon animated fade-in", onClick: handlePlayPauseToggle },
274
- react_1.default.createElement("div", { className: '_play-button' }, isPlaying ? react_1.default.createElement(tfi_1.TfiControlPause, { size: 50 }) : react_1.default.createElement(tfi_1.TfiControlPlay, { size: 50 }))),
275
- react_1.default.createElement(RowFlex_1.default, { funcss: 'animated slide-up pr-5 pl-5', gap: 1, justify: "space-between" },
276
- react_1.default.createElement(RowFlex_1.default, { gap: 0.5 },
277
- react_1.default.createElement("div", { className: "hide-small" },
278
- react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5, onClick: handlePlayPauseToggle }, isPlaying ? react_1.default.createElement(tfi_1.TfiControlPause, { size: 20 }) : react_1.default.createElement(tfi_1.TfiControlPlay, { size: 20 }))),
279
- react_1.default.createElement(ToolTip_1.default, null,
280
- react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5, onClick: handleRewind },
281
- react_1.default.createElement(tfi_1.TfiControlBackward, null)),
282
- react_1.default.createElement(Tip_1.default, { tip: "right", animation: "ScaleUp", duration: 0.5, content: "10 sec Back" })),
283
- react_1.default.createElement(ToolTip_1.default, null,
284
- react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5, onClick: handleForward },
285
- react_1.default.createElement(tfi_1.TfiControlForward, null)),
286
- react_1.default.createElement(Tip_1.default, { tip: "right", animation: "ScaleUp", duration: 0.5, content: "10 sec Forward" })),
287
- react_1.default.createElement("div", { onMouseEnter: function () { return setShowVolume(true); }, onMouseLeave: function () { return setShowVolume(false); } },
288
- react_1.default.createElement(RowFlex_1.default, null,
289
- react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5 },
290
- react_1.default.createElement(tfi_1.TfiVolume, null)),
291
- showVolume && (react_1.default.createElement("input", { type: "range", min: 0, max: 1, step: 0.01, value: volume, onChange: handleVolumeChange, className: "width-100 max-w-50 animated slide-right", style: { height: '3px', marginLeft: 8 }, "aria-label": "Volume" })))),
292
- react_1.default.createElement("div", { className: 'video_time' },
293
- react_1.default.createElement(Text_1.default, { text: (0, videoFunctions_1.formatTime)(currentTime), funcss: 'm-0', size: "sm" }),
294
- "/",
295
- react_1.default.createElement(Text_1.default, { text: "".concat((0, videoFunctions_1.formatTime)(duration - currentTime)), funcss: 'm-0', size: "sm" }))),
546
+ // Beautiful Progress Bar Component
547
+ var ProgressBar = function () { return (react_1.default.createElement("div", { className: "progress-container mb-4" },
548
+ react_1.default.createElement("div", { className: "progress-wrapper" },
549
+ react_1.default.createElement("input", { type: "range", min: 0, max: duration, value: currentTime, onChange: handleProgressChange, className: "video-progress ".concat(final.progressCss), style: {
550
+ '--progress-percent': "".concat((currentTime / duration) * 100, "%"),
551
+ }, onMouseEnter: function () { return setIsHoveringProgress(true); }, onMouseLeave: function () { return setIsHoveringProgress(false); } })))); };
552
+ // Beautiful Volume Control Component
553
+ var VolumeControl = function () { return (react_1.default.createElement("div", { className: "volume-control-wrapper" },
554
+ react_1.default.createElement(ToolTip_1.default, null,
555
+ react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5, onClick: handleToggleMute, className: "volume-toggle ".concat(final.buttonCss, " ").concat(final.volumeCss) }, isMuted || volume === 0
556
+ ? renderIcon(dynamicMuteIcon, 16)
557
+ : renderIcon(dynamicVolumeIcon, 16)),
558
+ react_1.default.createElement(Tip_1.default, { tip: "top", content: isMuted ? "Unmute" : "Mute" })),
559
+ react_1.default.createElement("div", { className: "volume-slider-wrapper", onMouseEnter: function () { return setIsHoveringVolume(true); }, onMouseLeave: function () { return setIsHoveringVolume(false); } },
560
+ react_1.default.createElement("input", { type: "range", min: 0, max: 1, step: 0.01, value: volume, onChange: handleVolumeChange, className: "volume-slider", style: {
561
+ '--volume-percent': "".concat(volume * 100, "%"),
562
+ } })))); };
563
+ return (react_1.default.createElement("div", { ref: containerRef, className: "video_container fit ".concat(final.funcss, " ").concat(final.containerCss, " ").concat(final.className), onClick: handleVideoClick },
564
+ final.poster && !hasStarted && !isPlaying && (react_1.default.createElement("div", { style: { backgroundImage: "url(".concat(final.poster, ")") }, className: "video_poster" })),
565
+ react_1.default.createElement("video", { ref: videoRef, preload: "auto", src: final.src, className: "video_player fit min-w-200 ".concat(final.videoCss), onLoadedMetadata: handleLoadedMetadata, playsInline: true, controls: false, loop: final.loop, muted: final.muted }),
566
+ final.showControls && (react_1.default.createElement("div", { className: "video_controls ".concat(final.controlsCss, " ").concat(showControlsState ? 'show_controls' : 'hide_controls') },
567
+ final.showProgress && react_1.default.createElement(ProgressBar, null),
568
+ react_1.default.createElement(RowFlex_1.default, { gap: 1, justify: "space-between", alignItems: "center", className: "controls-row" },
569
+ react_1.default.createElement(RowFlex_1.default, { gap: 0.5, alignItems: "center" },
570
+ final.showPlayPause && (react_1.default.createElement(ToolTip_1.default, null,
571
+ react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5, onClick: handlePlayPauseToggle, className: "".concat(final.buttonCss, " ").concat(isPlaying ? final.pauseCss : final.playCss) }, isPlaying
572
+ ? renderIcon(dynamicPauseIcon, 16)
573
+ : renderIcon(dynamicPlayIcon, 16)),
574
+ react_1.default.createElement(Tip_1.default, { tip: "top", content: isPlaying ? "Pause" : "Play" }))),
575
+ final.showSeekButtons && (react_1.default.createElement(react_1.default.Fragment, null,
576
+ react_1.default.createElement(ToolTip_1.default, null,
577
+ react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5, onClick: handleRewind, className: "".concat(final.buttonCss, " ").concat(final.rewindCss) }, renderIcon(dynamicRewindIcon, 14)),
578
+ react_1.default.createElement(Tip_1.default, { tip: "top", content: "".concat(final.seekAmount, "s Back") })),
579
+ react_1.default.createElement(ToolTip_1.default, null,
580
+ react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5, onClick: handleForward, className: "".concat(final.buttonCss, " ").concat(final.forwardCss) }, renderIcon(dynamicForwardIcon, 14)),
581
+ react_1.default.createElement(Tip_1.default, { tip: "top", content: "".concat(final.seekAmount, "s Forward") })))),
582
+ final.showVolume && react_1.default.createElement(VolumeControl, null),
583
+ final.showTime && (react_1.default.createElement("div", { className: "video_time ".concat(final.timeCss) },
584
+ react_1.default.createElement(Text_1.default, { text: "".concat((0, videoFunctions_1.formatTime)(currentTime), " / ").concat((0, videoFunctions_1.formatTime)(duration)), funcss: 'm-0', size: "sm" })))),
296
585
  react_1.default.createElement(RowFlex_1.default, { gap: 0.3 },
297
- react_1.default.createElement(ToolTip_1.default, null,
298
- react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5, onClick: handleToggleFullScreen },
299
- react_1.default.createElement(pi_1.PiCornersOut, null)),
300
- react_1.default.createElement(Tip_1.default, { tip: "left", animation: "ScaleUp", duration: 0.5, content: "Expand" })),
301
- react_1.default.createElement(ToolTip_1.default, null,
302
- react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5, onClick: function () { return window.open(src || '', '_blank'); } },
303
- react_1.default.createElement(tfi_1.TfiDownload, null)),
304
- react_1.default.createElement(Tip_1.default, { tip: "left", animation: "ScaleUp", duration: 0.5, content: "Download" })))))));
586
+ final.showFullscreen && (react_1.default.createElement(ToolTip_1.default, null,
587
+ react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5, onClick: handleToggleFullScreen, className: "".concat(final.buttonCss, " ").concat(final.fullscreenCss) }, renderIcon(dynamicFullscreenIcon, 16)),
588
+ react_1.default.createElement(Tip_1.default, { tip: "top", content: "Fullscreen" }))),
589
+ final.showDownload && (react_1.default.createElement(ToolTip_1.default, null,
590
+ react_1.default.createElement(Circle_1.default, { bordered: true, size: 2.5, onClick: function () { return window.open(final.src, '_blank'); }, className: "".concat(final.buttonCss, " ").concat(final.downloadCss) }, renderIcon(dynamicDownloadIcon, 14)),
591
+ react_1.default.createElement(Tip_1.default, { tip: "top", content: "Download" })))))))));
305
592
  }