@flamingo-stack/openframe-frontend-core 0.0.176 → 0.0.177-snapshot.20260514141929
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-VY6SYM2L.js → chunk-AAX27BCR.js} +311 -467
- package/dist/chunk-AAX27BCR.js.map +1 -0
- package/dist/{chunk-WX7PT5C7.cjs → chunk-ALW3D72O.cjs} +61 -2
- package/dist/chunk-ALW3D72O.cjs.map +1 -0
- package/dist/{chunk-KB2N44BY.js → chunk-FMWHOUFE.js} +61 -2
- package/dist/chunk-FMWHOUFE.js.map +1 -0
- package/dist/{chunk-SVF4YOGM.cjs → chunk-L4T24AN4.cjs} +482 -638
- package/dist/chunk-L4T24AN4.cjs.map +1 -0
- package/dist/components/chat/chat-message-list.d.ts.map +1 -1
- package/dist/components/features/index.cjs +3 -5
- package/dist/components/features/index.cjs.map +1 -1
- package/dist/components/features/index.js +2 -4
- package/dist/components/features/video-player.d.ts +17 -20
- package/dist/components/features/video-player.d.ts.map +1 -1
- package/dist/components/features/youtube-embed.d.ts +18 -4
- package/dist/components/features/youtube-embed.d.ts.map +1 -1
- package/dist/components/index.cjs +3 -5
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +2 -4
- package/dist/components/navigation/index.cjs +3 -3
- package/dist/components/navigation/index.js +2 -2
- package/dist/components/ui/index.cjs +3 -3
- package/dist/components/ui/index.js +2 -2
- package/dist/hooks/index.cjs +4 -2
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +3 -1
- package/dist/hooks/use-near-viewport.d.ts +42 -0
- package/dist/hooks/use-near-viewport.d.ts.map +1 -0
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -4
- package/package.json +1 -1
- package/src/components/chat/chat-message-list.tsx +48 -27
- package/src/components/features/video-player.tsx +39 -176
- package/src/components/features/youtube-embed.tsx +107 -224
- package/src/hooks/index.ts +3 -0
- package/src/hooks/use-near-viewport.ts +118 -0
- package/dist/chunk-KB2N44BY.js.map +0 -1
- package/dist/chunk-SVF4YOGM.cjs.map +0 -1
- package/dist/chunk-VY6SYM2L.js.map +0 -1
- package/dist/chunk-WX7PT5C7.cjs.map +0 -1
- package/src/components/features/__tests__/video-player.test.tsx +0 -142
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
useMdUp,
|
|
17
17
|
useOnboardingState,
|
|
18
18
|
useToast
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-FMWHOUFE.js";
|
|
20
20
|
import {
|
|
21
21
|
Button,
|
|
22
22
|
Checkbox,
|
|
@@ -413,7 +413,7 @@ function useDynamicTheme() {
|
|
|
413
413
|
}
|
|
414
414
|
|
|
415
415
|
// src/components/features/array-entry-manager.tsx
|
|
416
|
-
import { useState as useState58, useEffect as
|
|
416
|
+
import { useState as useState58, useEffect as useEffect42 } from "react";
|
|
417
417
|
|
|
418
418
|
// src/components/ui/allowed-domains-input.tsx
|
|
419
419
|
init_cn();
|
|
@@ -5315,7 +5315,7 @@ MemoizedChatMessageEnhanced.displayName = "MemoizedChatMessageEnhanced";
|
|
|
5315
5315
|
|
|
5316
5316
|
// src/components/chat/chat-message-list.tsx
|
|
5317
5317
|
init_cn();
|
|
5318
|
-
import { useRef as useRef6, useState as useState14, useEffect as useEffect6, useLayoutEffect as useLayoutEffect2, useImperativeHandle as useImperativeHandle3, forwardRef as forwardRef22 } from "react";
|
|
5318
|
+
import { useRef as useRef6, useState as useState14, useEffect as useEffect6, useLayoutEffect as useLayoutEffect2, useCallback as useCallback3, useImperativeHandle as useImperativeHandle3, forwardRef as forwardRef22 } from "react";
|
|
5319
5319
|
import { useStickToBottom } from "use-stick-to-bottom";
|
|
5320
5320
|
|
|
5321
5321
|
// src/components/chat/chat-message-loader.tsx
|
|
@@ -5432,10 +5432,13 @@ var ChatMessageList = forwardRef22(
|
|
|
5432
5432
|
return;
|
|
5433
5433
|
}
|
|
5434
5434
|
if (newCount > prevCount) {
|
|
5435
|
-
const
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5435
|
+
const isPrepend = prependRef.current.firstMessageId !== void 0 && messages[0]?.id !== prependRef.current.firstMessageId;
|
|
5436
|
+
if (!isPrepend) {
|
|
5437
|
+
const newSlice = messages.slice(prevCount);
|
|
5438
|
+
const hasNewUser = newSlice.some((m) => m.role === "user");
|
|
5439
|
+
if (hasNewUser) {
|
|
5440
|
+
void scrollToBottom({ animation: "instant", ignoreEscapes: true });
|
|
5441
|
+
}
|
|
5439
5442
|
}
|
|
5440
5443
|
}
|
|
5441
5444
|
}, [autoScroll, messages, dialogId, scrollToBottom, scrollEl]);
|
|
@@ -5499,6 +5502,13 @@ var ChatMessageList = forwardRef22(
|
|
|
5499
5502
|
}, [hasNextPage, scrollEl, sentinelEl, messages.length]);
|
|
5500
5503
|
useImperativeHandle3(ref, () => scrollRef.current, [scrollRef]);
|
|
5501
5504
|
const showLoader = useDelayedFlag(isLoading, { delay: 200, minDuration: 400 });
|
|
5505
|
+
const setScrollRef = useCallback3((el) => {
|
|
5506
|
+
scrollRef(el);
|
|
5507
|
+
setScrollEl(el);
|
|
5508
|
+
}, [scrollRef]);
|
|
5509
|
+
const setContentRef = useCallback3((el) => {
|
|
5510
|
+
contentRef(el);
|
|
5511
|
+
}, [contentRef]);
|
|
5502
5512
|
if (showLoader) {
|
|
5503
5513
|
return /* @__PURE__ */ jsx33(
|
|
5504
5514
|
ChatMessageListLoader,
|
|
@@ -5509,13 +5519,6 @@ var ChatMessageList = forwardRef22(
|
|
|
5509
5519
|
}
|
|
5510
5520
|
);
|
|
5511
5521
|
}
|
|
5512
|
-
const setScrollRef = (el) => {
|
|
5513
|
-
scrollRef(el);
|
|
5514
|
-
setScrollEl(el);
|
|
5515
|
-
};
|
|
5516
|
-
const setContentRef = (el) => {
|
|
5517
|
-
contentRef(el);
|
|
5518
|
-
};
|
|
5519
5522
|
return /* @__PURE__ */ jsxs28("div", { className: "relative flex-1 min-h-0 flex flex-col", children: [
|
|
5520
5523
|
/* @__PURE__ */ jsx33(
|
|
5521
5524
|
"div",
|
|
@@ -6220,7 +6223,7 @@ var NETWORK_CONFIG = {
|
|
|
6220
6223
|
};
|
|
6221
6224
|
|
|
6222
6225
|
// src/components/chat/hooks/use-chunk-catchup.ts
|
|
6223
|
-
import { useCallback as
|
|
6226
|
+
import { useCallback as useCallback6, useRef as useRef9 } from "react";
|
|
6224
6227
|
function makeSeqKey(messageType, chunkType, sequenceId) {
|
|
6225
6228
|
return `${messageType}:${chunkType}:${sequenceId}`;
|
|
6226
6229
|
}
|
|
@@ -6257,7 +6260,7 @@ function useChunkCatchup({
|
|
|
6257
6260
|
fetchChunksRef.current = fetchChunks;
|
|
6258
6261
|
const onChunkReceivedRef = useRef9(onChunkReceived);
|
|
6259
6262
|
onChunkReceivedRef.current = onChunkReceived;
|
|
6260
|
-
const processChunk =
|
|
6263
|
+
const processChunk = useCallback6((chunk, messageType, forceProcess = false) => {
|
|
6261
6264
|
if (bufferUntilInitialCatchupComplete.current && !forceProcess) {
|
|
6262
6265
|
chunkBuffer.current.push({ chunk, messageType });
|
|
6263
6266
|
return true;
|
|
@@ -6270,7 +6273,7 @@ function useChunkCatchup({
|
|
|
6270
6273
|
onChunkReceivedRef.current(chunk, messageType);
|
|
6271
6274
|
return true;
|
|
6272
6275
|
}, []);
|
|
6273
|
-
const flushBufferedRealtimeChunks =
|
|
6276
|
+
const flushBufferedRealtimeChunks = useCallback6(() => {
|
|
6274
6277
|
if (chunkBuffer.current.length === 0) return;
|
|
6275
6278
|
const buffered = [...chunkBuffer.current];
|
|
6276
6279
|
chunkBuffer.current = [];
|
|
@@ -6283,7 +6286,7 @@ function useChunkCatchup({
|
|
|
6283
6286
|
processChunk(chunk, messageType, true);
|
|
6284
6287
|
});
|
|
6285
6288
|
}, [processChunk]);
|
|
6286
|
-
const catchUpChunks =
|
|
6289
|
+
const catchUpChunks = useCallback6(async (fromSequenceId) => {
|
|
6287
6290
|
const dialogId2 = dialogIdRef.current;
|
|
6288
6291
|
const chatTypes2 = chatTypesRef.current;
|
|
6289
6292
|
const fetchChunks2 = fetchChunksRef.current;
|
|
@@ -6396,7 +6399,7 @@ function useChunkCatchup({
|
|
|
6396
6399
|
}
|
|
6397
6400
|
}
|
|
6398
6401
|
}, [flushBufferedRealtimeChunks]);
|
|
6399
|
-
const resetChunkTracking =
|
|
6402
|
+
const resetChunkTracking = useCallback6(() => {
|
|
6400
6403
|
processedSequenceKeys.current.clear();
|
|
6401
6404
|
lastSequenceId.current = null;
|
|
6402
6405
|
fetchingInProgress.current = false;
|
|
@@ -6405,13 +6408,13 @@ function useChunkCatchup({
|
|
|
6405
6408
|
bufferUntilInitialCatchupComplete.current = false;
|
|
6406
6409
|
hasCompletedInitialCatchup.current = false;
|
|
6407
6410
|
}, []);
|
|
6408
|
-
const startInitialBuffering =
|
|
6411
|
+
const startInitialBuffering = useCallback6(() => {
|
|
6409
6412
|
chunkBuffer.current = [];
|
|
6410
6413
|
bufferUntilInitialCatchupComplete.current = true;
|
|
6411
6414
|
hasCompletedInitialCatchup.current = false;
|
|
6412
6415
|
}, []);
|
|
6413
|
-
const isBufferingActive =
|
|
6414
|
-
const resetAndCatchUp =
|
|
6416
|
+
const isBufferingActive = useCallback6(() => bufferUntilInitialCatchupComplete.current, []);
|
|
6417
|
+
const resetAndCatchUp = useCallback6(async () => {
|
|
6415
6418
|
if (!dialogIdRef.current) return;
|
|
6416
6419
|
const fromSeq = lastSequenceId.current;
|
|
6417
6420
|
hasCompletedInitialCatchup.current = false;
|
|
@@ -6432,7 +6435,7 @@ function useChunkCatchup({
|
|
|
6432
6435
|
}
|
|
6433
6436
|
|
|
6434
6437
|
// src/components/chat/hooks/use-nats-dialog-subscription.ts
|
|
6435
|
-
import { useCallback as
|
|
6438
|
+
import { useCallback as useCallback7, useEffect as useEffect8, useRef as useRef10, useState as useState16 } from "react";
|
|
6436
6439
|
var shared = null;
|
|
6437
6440
|
function useNatsDialogSubscription({
|
|
6438
6441
|
enabled,
|
|
@@ -6481,7 +6484,7 @@ function useNatsDialogSubscription({
|
|
|
6481
6484
|
useEffect8(() => {
|
|
6482
6485
|
reconnectionBackoffRef.current = reconnectionBackoff;
|
|
6483
6486
|
}, [reconnectionBackoff]);
|
|
6484
|
-
const acquireClient =
|
|
6487
|
+
const acquireClient = useCallback7((url) => {
|
|
6485
6488
|
if (shared?.wsUrl !== url) {
|
|
6486
6489
|
if (shared) {
|
|
6487
6490
|
shared.closeTimer && clearTimeout(shared.closeTimer);
|
|
@@ -6508,7 +6511,7 @@ function useNatsDialogSubscription({
|
|
|
6508
6511
|
shared.closeTimer = null;
|
|
6509
6512
|
return shared;
|
|
6510
6513
|
}, [clientConfig]);
|
|
6511
|
-
const releaseClient =
|
|
6514
|
+
const releaseClient = useCallback7((url) => {
|
|
6512
6515
|
if (!shared || shared.wsUrl !== url) return;
|
|
6513
6516
|
shared.refCount = Math.max(0, shared.refCount - 1);
|
|
6514
6517
|
if (shared.refCount > 0) return;
|
|
@@ -6805,7 +6808,7 @@ function buildNatsWsUrl(apiBaseUrl, options) {
|
|
|
6805
6808
|
}
|
|
6806
6809
|
|
|
6807
6810
|
// src/components/chat/hooks/use-realtime-chunk-processor.ts
|
|
6808
|
-
import { useCallback as
|
|
6811
|
+
import { useCallback as useCallback8, useRef as useRef11, useEffect as useEffect9 } from "react";
|
|
6809
6812
|
|
|
6810
6813
|
// src/components/chat/utils/chunk-parser.ts
|
|
6811
6814
|
function normalizeToolCalls(raw) {
|
|
@@ -7429,7 +7432,7 @@ function useRealtimeChunkProcessor(options) {
|
|
|
7429
7432
|
}, [initialState, callbacks]);
|
|
7430
7433
|
const isInStreamRef = useRef11(false);
|
|
7431
7434
|
const pendingEscalatedRef = useRef11(/* @__PURE__ */ new Map());
|
|
7432
|
-
const processChunk =
|
|
7435
|
+
const processChunk = useCallback8(
|
|
7433
7436
|
(chunk) => {
|
|
7434
7437
|
if (!enableThinking && chunk && typeof chunk === "object" && chunk.type === MESSAGE_TYPE.THINKING) {
|
|
7435
7438
|
return;
|
|
@@ -7628,21 +7631,21 @@ function useRealtimeChunkProcessor(options) {
|
|
|
7628
7631
|
},
|
|
7629
7632
|
[callbacks, displayApprovalTypes, approvalStatuses, initialState, enableThinking]
|
|
7630
7633
|
);
|
|
7631
|
-
const getSegments =
|
|
7634
|
+
const getSegments = useCallback8(() => {
|
|
7632
7635
|
return accumulatorRef.current.getSegments();
|
|
7633
7636
|
}, []);
|
|
7634
|
-
const reset =
|
|
7637
|
+
const reset = useCallback8(() => {
|
|
7635
7638
|
accumulatorRef.current.reset();
|
|
7636
7639
|
pendingEscalatedRef.current.clear();
|
|
7637
7640
|
hasInitializedWithData.current = false;
|
|
7638
7641
|
}, []);
|
|
7639
|
-
const updateApprovalStatus =
|
|
7642
|
+
const updateApprovalStatus = useCallback8(
|
|
7640
7643
|
(requestId, status) => {
|
|
7641
7644
|
return accumulatorRef.current.updateApprovalStatus(requestId, status);
|
|
7642
7645
|
},
|
|
7643
7646
|
[]
|
|
7644
7647
|
);
|
|
7645
|
-
const getPendingApprovals =
|
|
7648
|
+
const getPendingApprovals = useCallback8(() => {
|
|
7646
7649
|
return new Map(pendingEscalatedRef.current);
|
|
7647
7650
|
}, []);
|
|
7648
7651
|
return {
|
|
@@ -8774,7 +8777,7 @@ function SlidingSidebar({ config }) {
|
|
|
8774
8777
|
}
|
|
8775
8778
|
|
|
8776
8779
|
// src/components/navigation/sticky-section-nav.tsx
|
|
8777
|
-
import { useEffect as useEffect14, useState as useState20, useCallback as
|
|
8780
|
+
import { useEffect as useEffect14, useState as useState20, useCallback as useCallback9, useRef as useRef14 } from "react";
|
|
8778
8781
|
import { jsx as jsx46, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
8779
8782
|
function StickySectionNav({
|
|
8780
8783
|
sections,
|
|
@@ -8838,7 +8841,7 @@ function useSectionNavigation(sections, options) {
|
|
|
8838
8841
|
const [activeSection, setActiveSection] = useState20(sections[0]?.id || "");
|
|
8839
8842
|
const isScrollingFromClick = useRef14(false);
|
|
8840
8843
|
const { offset: offset2 = 100 } = options || {};
|
|
8841
|
-
const handleSectionClick =
|
|
8844
|
+
const handleSectionClick = useCallback9((sectionId) => {
|
|
8842
8845
|
const targetElement = document.getElementById(sectionId);
|
|
8843
8846
|
if (!targetElement) return;
|
|
8844
8847
|
isScrollingFromClick.current = true;
|
|
@@ -8889,7 +8892,7 @@ function useSectionNavigation(sections, options) {
|
|
|
8889
8892
|
}
|
|
8890
8893
|
|
|
8891
8894
|
// src/components/navigation/navigation-sidebar.tsx
|
|
8892
|
-
import { useCallback as
|
|
8895
|
+
import { useCallback as useCallback10, useLayoutEffect as useLayoutEffect4, useMemo as useMemo7, useState as useState21 } from "react";
|
|
8893
8896
|
|
|
8894
8897
|
// src/components/navigation/navigation-sidebar-header.tsx
|
|
8895
8898
|
import { jsx as jsx47, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
@@ -9042,11 +9045,11 @@ function NavigationSidebar({ config, disabled = false }) {
|
|
|
9042
9045
|
const [transitionsEnabled, setTransitionsEnabled] = useState21(false);
|
|
9043
9046
|
const isMinimized = !isLgUp || minimized;
|
|
9044
9047
|
const showLabel = isLgUp && !minimized;
|
|
9045
|
-
const handleToggle =
|
|
9048
|
+
const handleToggle = useCallback10(() => {
|
|
9046
9049
|
setMinimized((prev) => !prev);
|
|
9047
9050
|
config.onToggleMinimized?.();
|
|
9048
9051
|
}, [setMinimized, config]);
|
|
9049
|
-
const handleItemClick =
|
|
9052
|
+
const handleItemClick = useCallback10((item, event) => {
|
|
9050
9053
|
event?.stopPropagation();
|
|
9051
9054
|
if (item.onClick) {
|
|
9052
9055
|
item.onClick();
|
|
@@ -9569,7 +9572,7 @@ function NotificationsHeaderButton({
|
|
|
9569
9572
|
}
|
|
9570
9573
|
|
|
9571
9574
|
// src/components/navigation/app-layout.tsx
|
|
9572
|
-
import { Suspense, useCallback as
|
|
9575
|
+
import { Suspense, useCallback as useCallback13, useState as useState24 } from "react";
|
|
9573
9576
|
|
|
9574
9577
|
// src/components/features/notifications/notification-drawer.tsx
|
|
9575
9578
|
import * as DialogPrimitive2 from "@radix-ui/react-dialog";
|
|
@@ -9949,7 +9952,7 @@ function NotificationsHistoryButton({ onClick }) {
|
|
|
9949
9952
|
}
|
|
9950
9953
|
|
|
9951
9954
|
// src/components/navigation/mobile-burger-menu.tsx
|
|
9952
|
-
import React29, { useCallback as
|
|
9955
|
+
import React29, { useCallback as useCallback12, useEffect as useEffect17 } from "react";
|
|
9953
9956
|
import { Fragment as Fragment8, jsx as jsx60, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
9954
9957
|
var HEADER_HEIGHT = 48;
|
|
9955
9958
|
var MobileBurgerMenu = React29.memo(function MobileBurgerMenu2({
|
|
@@ -9983,7 +9986,7 @@ var MobileBurgerMenu = React29.memo(function MobileBurgerMenu2({
|
|
|
9983
9986
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
9984
9987
|
}
|
|
9985
9988
|
}, [isOpen, onClose]);
|
|
9986
|
-
const handleItemClick =
|
|
9989
|
+
const handleItemClick = useCallback12((item) => {
|
|
9987
9990
|
if (item.onClick) {
|
|
9988
9991
|
item.onClick();
|
|
9989
9992
|
} else if (item.path) {
|
|
@@ -10159,10 +10162,10 @@ function AppLayout({
|
|
|
10159
10162
|
disabled = false
|
|
10160
10163
|
}) {
|
|
10161
10164
|
const [mobileMenuOpen, setMobileMenuOpen] = useState24(false);
|
|
10162
|
-
const handleToggleMobileMenu =
|
|
10165
|
+
const handleToggleMobileMenu = useCallback13(() => {
|
|
10163
10166
|
setMobileMenuOpen((prev) => !prev);
|
|
10164
10167
|
}, []);
|
|
10165
|
-
const handleCloseMobileMenu =
|
|
10168
|
+
const handleCloseMobileMenu = useCallback13(() => {
|
|
10166
10169
|
setMobileMenuOpen(false);
|
|
10167
10170
|
}, []);
|
|
10168
10171
|
return /* @__PURE__ */ jsxs51("div", { className: cn("flex h-screen bg-ods-bg", className), children: [
|
|
@@ -11878,7 +11881,7 @@ function EmptyState2({
|
|
|
11878
11881
|
}
|
|
11879
11882
|
|
|
11880
11883
|
// src/components/faq-accordion.tsx
|
|
11881
|
-
import { useRef as useRef15, useState as useState26, useEffect as useEffect19, useCallback as
|
|
11884
|
+
import { useRef as useRef15, useState as useState26, useEffect as useEffect19, useCallback as useCallback14 } from "react";
|
|
11882
11885
|
|
|
11883
11886
|
// src/components/ui/chevron-button.tsx
|
|
11884
11887
|
init_cn();
|
|
@@ -11920,7 +11923,7 @@ import { jsx as jsx85, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
|
11920
11923
|
var useMeasuredHeight = (isOpen) => {
|
|
11921
11924
|
const ref = useRef15(null);
|
|
11922
11925
|
const [maxHeight, setMaxHeight] = useState26("0px");
|
|
11923
|
-
const measure =
|
|
11926
|
+
const measure = useCallback14(() => {
|
|
11924
11927
|
if (ref.current) {
|
|
11925
11928
|
const height = ref.current.scrollHeight;
|
|
11926
11929
|
setMaxHeight(`${height}px`);
|
|
@@ -12506,13 +12509,13 @@ init_unified_pagination();
|
|
|
12506
12509
|
|
|
12507
12510
|
// src/components/footer-waitlist-button.tsx
|
|
12508
12511
|
import { usePathname as usePathname2, useRouter as useRouter4 } from "next/navigation";
|
|
12509
|
-
import { useCallback as
|
|
12512
|
+
import { useCallback as useCallback15 } from "react";
|
|
12510
12513
|
init_button2();
|
|
12511
12514
|
import { jsx as jsx91 } from "react/jsx-runtime";
|
|
12512
12515
|
function FooterWaitlistButton({ className }) {
|
|
12513
12516
|
const router = useRouter4();
|
|
12514
12517
|
const pathname = usePathname2();
|
|
12515
|
-
const handleClick =
|
|
12518
|
+
const handleClick = useCallback15(() => {
|
|
12516
12519
|
if (pathname?.startsWith("/waitlist")) {
|
|
12517
12520
|
const anchor = document.getElementById("waitlist-form");
|
|
12518
12521
|
if (anchor) {
|
|
@@ -12816,7 +12819,7 @@ function ResponsiveIconsBlock({ loading = false }) {
|
|
|
12816
12819
|
|
|
12817
12820
|
// src/components/image-cropper.tsx
|
|
12818
12821
|
init_button2();
|
|
12819
|
-
import { useCallback as
|
|
12822
|
+
import { useCallback as useCallback16, useState as useState29 } from "react";
|
|
12820
12823
|
import Cropper from "react-easy-crop";
|
|
12821
12824
|
|
|
12822
12825
|
// src/components/ui/slider.tsx
|
|
@@ -12878,11 +12881,11 @@ var ImageCropper = ({
|
|
|
12878
12881
|
const [zoom, setZoom] = useState29(1);
|
|
12879
12882
|
const [rotation, setRotation] = useState29(0);
|
|
12880
12883
|
const [croppedAreaPixels, setCroppedAreaPixels] = useState29(null);
|
|
12881
|
-
const onCropComplete =
|
|
12884
|
+
const onCropComplete = useCallback16((_, area) => {
|
|
12882
12885
|
setCroppedAreaPixels(area);
|
|
12883
12886
|
}, []);
|
|
12884
12887
|
const checkerBg = "bg-[length:16px_16px] bg-[linear-gradient(45deg,transparent_25%,#2a2a2a_25%,#2a2a2a_75%,transparent_75%,transparent),linear-gradient(45deg,#2a2a2a_25%,transparent_25%,transparent_75%,#2a2a2a_75%,#2a2a2a)]";
|
|
12885
|
-
const exportCrop =
|
|
12888
|
+
const exportCrop = useCallback16(async () => {
|
|
12886
12889
|
if (!croppedAreaPixels) return void 0;
|
|
12887
12890
|
const img = await loadImage(src);
|
|
12888
12891
|
const canvas = document.createElement("canvas");
|
|
@@ -13045,7 +13048,7 @@ var ImageCropper = ({
|
|
|
13045
13048
|
|
|
13046
13049
|
// src/components/media-carousel.tsx
|
|
13047
13050
|
init_cn();
|
|
13048
|
-
import { useState as useState30, useRef as useRef19, useEffect as useEffect22, memo as memo3, useCallback as
|
|
13051
|
+
import { useState as useState30, useRef as useRef19, useEffect as useEffect22, memo as memo3, useCallback as useCallback17 } from "react";
|
|
13049
13052
|
import { Fragment as Fragment13, jsx as jsx96, jsxs as jsxs77 } from "react/jsx-runtime";
|
|
13050
13053
|
var ChevronLeftIcon = () => /* @__PURE__ */ jsx96("svg", { width: "24", height: "24", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx96("polyline", { points: "15,18 9,12 15,6" }) });
|
|
13051
13054
|
var ChevronRightIcon = () => /* @__PURE__ */ jsx96("svg", { width: "24", height: "24", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx96("polyline", { points: "9,18 15,12 9,6" }) });
|
|
@@ -13121,7 +13124,7 @@ var MediaCarousel = memo3(function MediaCarousel2({
|
|
|
13121
13124
|
if (!currentItem) {
|
|
13122
13125
|
return null;
|
|
13123
13126
|
}
|
|
13124
|
-
const handleVideoClick =
|
|
13127
|
+
const handleVideoClick = useCallback17((index) => {
|
|
13125
13128
|
const item = media[index];
|
|
13126
13129
|
if (item.type !== "video") return;
|
|
13127
13130
|
const videoElements = document.querySelectorAll(`video[data-video-index="${index}"]`);
|
|
@@ -13163,7 +13166,7 @@ var MediaCarousel = memo3(function MediaCarousel2({
|
|
|
13163
13166
|
}
|
|
13164
13167
|
}
|
|
13165
13168
|
}, [media]);
|
|
13166
|
-
const nextSlide =
|
|
13169
|
+
const nextSlide = useCallback17(() => {
|
|
13167
13170
|
const currentVideo = document.querySelector(`[data-video-index="${currentIndex}"]`);
|
|
13168
13171
|
if (currentVideo && !currentVideo.paused) {
|
|
13169
13172
|
currentVideo.pause();
|
|
@@ -13171,7 +13174,7 @@ var MediaCarousel = memo3(function MediaCarousel2({
|
|
|
13171
13174
|
setPlayingVideos(/* @__PURE__ */ new Set());
|
|
13172
13175
|
setCurrentIndex((prev) => (prev + 1) % media.length);
|
|
13173
13176
|
}, [currentIndex, media.length]);
|
|
13174
|
-
const prevSlide =
|
|
13177
|
+
const prevSlide = useCallback17(() => {
|
|
13175
13178
|
const currentVideo = document.querySelector(`[data-video-index="${currentIndex}"]`);
|
|
13176
13179
|
if (currentVideo && !currentVideo.paused) {
|
|
13177
13180
|
currentVideo.pause();
|
|
@@ -13179,7 +13182,7 @@ var MediaCarousel = memo3(function MediaCarousel2({
|
|
|
13179
13182
|
setPlayingVideos(/* @__PURE__ */ new Set());
|
|
13180
13183
|
setCurrentIndex((prev) => (prev - 1 + media.length) % media.length);
|
|
13181
13184
|
}, [currentIndex, media.length]);
|
|
13182
|
-
const selectSlide =
|
|
13185
|
+
const selectSlide = useCallback17((index) => {
|
|
13183
13186
|
if (index === currentIndex) return;
|
|
13184
13187
|
const currentVideo = document.querySelector(`[data-video-index="${currentIndex}"]`);
|
|
13185
13188
|
if (currentVideo && !currentVideo.paused) {
|
|
@@ -13188,7 +13191,7 @@ var MediaCarousel = memo3(function MediaCarousel2({
|
|
|
13188
13191
|
setPlayingVideos(/* @__PURE__ */ new Set());
|
|
13189
13192
|
setCurrentIndex(index);
|
|
13190
13193
|
}, [currentIndex]);
|
|
13191
|
-
const handleKeyDown =
|
|
13194
|
+
const handleKeyDown = useCallback17((e) => {
|
|
13192
13195
|
if (media.length <= 1) return;
|
|
13193
13196
|
if (e.key === "ArrowLeft") {
|
|
13194
13197
|
e.preventDefault();
|
|
@@ -15860,7 +15863,7 @@ function DateTimePicker({
|
|
|
15860
15863
|
|
|
15861
15864
|
// src/components/shared/onboarding/onboarding-walkthrough.tsx
|
|
15862
15865
|
init_button2();
|
|
15863
|
-
import React41, { useRef as useRef20, useCallback as
|
|
15866
|
+
import React41, { useRef as useRef20, useCallback as useCallback18 } from "react";
|
|
15864
15867
|
|
|
15865
15868
|
// src/components/shared/onboarding/onboarding-step-card.tsx
|
|
15866
15869
|
import React40 from "react";
|
|
@@ -16155,7 +16158,7 @@ function OnboardingWalkthrough({
|
|
|
16155
16158
|
lastCompletionStatusRef.current = statusKey;
|
|
16156
16159
|
}
|
|
16157
16160
|
}, [completionStatus, isLoadingCompletion, state.completedSteps, markMultipleComplete]);
|
|
16158
|
-
const handleStepAction =
|
|
16161
|
+
const handleStepAction = useCallback18(async (step) => {
|
|
16159
16162
|
if (actionInProgressRef.current.has(step.id)) {
|
|
16160
16163
|
console.log(`\u23F3 Action already in progress for "${step.id}", skipping`);
|
|
16161
16164
|
return;
|
|
@@ -16394,7 +16397,7 @@ function ProductReleaseCardSkeleton({ className, size = "default" }) {
|
|
|
16394
16397
|
}
|
|
16395
16398
|
|
|
16396
16399
|
// src/components/shared/product-release/release-detail-page.tsx
|
|
16397
|
-
import { useState as useState37, useEffect as
|
|
16400
|
+
import { useState as useState37, useEffect as useEffect26 } from "react";
|
|
16398
16401
|
import Link4 from "next/link";
|
|
16399
16402
|
|
|
16400
16403
|
// src/components/layout/article-detail-layout.tsx
|
|
@@ -16613,58 +16616,20 @@ function ImageGalleryModal({
|
|
|
16613
16616
|
import { AlertTriangle, ExternalLink, BookMarked } from "lucide-react";
|
|
16614
16617
|
|
|
16615
16618
|
// src/components/features/youtube-embed.tsx
|
|
16616
|
-
import {
|
|
16617
|
-
import ReactPlayer from "react-player/youtube";
|
|
16619
|
+
import { useRef as useRef21, useState as useState34 } from "react";
|
|
16618
16620
|
import { jsx as jsx138, jsxs as jsxs111 } from "react/jsx-runtime";
|
|
16619
|
-
var Play = ({ size = 16, className }) => /* @__PURE__ */ jsx138("svg", { width: size, height: size, fill: "currentColor", viewBox: "0 0 24 24", className, children: /* @__PURE__ */ jsx138("polygon", { points: "5,3 19,12 5,21" }) });
|
|
16620
|
-
var Loader = ({ size = 16, className }) => /* @__PURE__ */ jsxs111("svg", { width: size, height: size, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", className, children: [
|
|
16621
|
-
/* @__PURE__ */ jsx138("line", { x1: "12", y1: "2", x2: "12", y2: "6" }),
|
|
16622
|
-
/* @__PURE__ */ jsx138("line", { x1: "12", y1: "18", x2: "12", y2: "22" }),
|
|
16623
|
-
/* @__PURE__ */ jsx138("line", { x1: "4.93", y1: "4.93", x2: "7.76", y2: "7.76" }),
|
|
16624
|
-
/* @__PURE__ */ jsx138("line", { x1: "16.24", y1: "16.24", x2: "19.07", y2: "19.07" }),
|
|
16625
|
-
/* @__PURE__ */ jsx138("line", { x1: "2", y1: "12", x2: "6", y2: "12" }),
|
|
16626
|
-
/* @__PURE__ */ jsx138("line", { x1: "18", y1: "12", x2: "22", y2: "12" }),
|
|
16627
|
-
/* @__PURE__ */ jsx138("line", { x1: "4.93", y1: "19.07", x2: "7.76", y2: "16.24" }),
|
|
16628
|
-
/* @__PURE__ */ jsx138("line", { x1: "16.24", y1: "7.76", x2: "19.07", y2: "4.93" })
|
|
16629
|
-
] });
|
|
16630
16621
|
var YouTubeEmbed = ({
|
|
16631
16622
|
videoId,
|
|
16632
16623
|
title = "YouTube Video",
|
|
16633
16624
|
className = "",
|
|
16634
16625
|
showTitle = true,
|
|
16635
16626
|
showMeta = true,
|
|
16636
|
-
minimalControls = false
|
|
16627
|
+
minimalControls = false,
|
|
16628
|
+
aboveTheFold = false
|
|
16637
16629
|
}) => {
|
|
16638
|
-
const [
|
|
16639
|
-
const
|
|
16640
|
-
const
|
|
16641
|
-
const [useIframe, setUseIframe] = useState34(false);
|
|
16642
|
-
const [mounted, setMounted] = useState34(false);
|
|
16643
|
-
useEffect25(() => {
|
|
16644
|
-
setMounted(true);
|
|
16645
|
-
setUseIframe(true);
|
|
16646
|
-
setIsLoading(false);
|
|
16647
|
-
}, []);
|
|
16648
|
-
const handleReady = () => {
|
|
16649
|
-
setIsLoading(false);
|
|
16650
|
-
};
|
|
16651
|
-
const handleError = () => {
|
|
16652
|
-
setIsLoading(false);
|
|
16653
|
-
setHasError(true);
|
|
16654
|
-
setUseIframe(true);
|
|
16655
|
-
};
|
|
16656
|
-
const handlePlay = () => {
|
|
16657
|
-
setIsPlaying(true);
|
|
16658
|
-
};
|
|
16659
|
-
const handlePause = () => {
|
|
16660
|
-
setIsPlaying(false);
|
|
16661
|
-
};
|
|
16662
|
-
const videoUrl = `https://www.youtube.com/watch?v=${videoId}`;
|
|
16663
|
-
const embedParams = new URLSearchParams({
|
|
16664
|
-
rel: "0",
|
|
16665
|
-
modestbranding: "1",
|
|
16666
|
-
playsinline: "1"
|
|
16667
|
-
});
|
|
16630
|
+
const [activated, setActivated] = useState34(false);
|
|
16631
|
+
const iframeSlotRef = useRef21(null);
|
|
16632
|
+
const embedParams = new URLSearchParams({ autoplay: "1", rel: "0", modestbranding: "1", playsinline: "1" });
|
|
16668
16633
|
if (minimalControls) {
|
|
16669
16634
|
embedParams.set("controls", "0");
|
|
16670
16635
|
embedParams.set("showinfo", "0");
|
|
@@ -16672,96 +16637,60 @@ var YouTubeEmbed = ({
|
|
|
16672
16637
|
embedParams.set("iv_load_policy", "3");
|
|
16673
16638
|
embedParams.set("cc_load_policy", "0");
|
|
16674
16639
|
embedParams.set("disablekb", "1");
|
|
16675
|
-
embedParams.set("rel", "0");
|
|
16676
|
-
}
|
|
16677
|
-
const embedUrl = `https://www.youtube.com/embed/${videoId}?${embedParams.toString()}`;
|
|
16678
|
-
if (!mounted) {
|
|
16679
|
-
return /* @__PURE__ */ jsx138("div", { className: `youtube-embed-container my-6 ${className}`, children: /* @__PURE__ */ jsx138("div", { className: "video-wrapper relative w-full", style: { paddingBottom: "56.25%" }, children: /* @__PURE__ */ jsx138("div", { className: "loading-overlay absolute inset-0 bg-ods-card border border-ods-border rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsxs111("div", { className: "loading-content flex flex-col items-center gap-3", children: [
|
|
16680
|
-
/* @__PURE__ */ jsx138(Loader, { className: "animate-spin text-ods-accent", size: 32 }),
|
|
16681
|
-
/* @__PURE__ */ jsx138("span", { className: "font-sans text-sm text-ods-text-secondary", children: "Loading video..." })
|
|
16682
|
-
] }) }) }) });
|
|
16683
|
-
}
|
|
16684
|
-
if (hasError) {
|
|
16685
|
-
return /* @__PURE__ */ jsx138("div", { className: `youtube-embed-error ${className}`, children: /* @__PURE__ */ jsxs111("div", { className: "error-state bg-ods-card border border-ods-error rounded-lg p-6 text-center my-6", children: [
|
|
16686
|
-
/* @__PURE__ */ jsx138("div", { className: "error-icon flex justify-center mb-4", children: /* @__PURE__ */ jsx138("svg", { width: "48", height: "48", fill: "currentColor", viewBox: "0 0 24 24", className: "text-ods-error", children: /* @__PURE__ */ jsx138("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" }) }) }),
|
|
16687
|
-
/* @__PURE__ */ jsx138("div", { className: "error-title font-sans font-semibold text-lg text-ods-error mb-2", children: "Video Unavailable" }),
|
|
16688
|
-
/* @__PURE__ */ jsx138("div", { className: "error-description font-sans text-sm text-ods-text-secondary mb-4", children: "Unable to load YouTube video. The video may be private or deleted." }),
|
|
16689
|
-
/* @__PURE__ */ jsx138(
|
|
16690
|
-
"a",
|
|
16691
|
-
{
|
|
16692
|
-
href: videoUrl,
|
|
16693
|
-
target: "_blank",
|
|
16694
|
-
rel: "noopener noreferrer",
|
|
16695
|
-
className: "error-retry-button bg-ods-error hover:bg-ods-error-hover text-ods-text-on-error border-none rounded px-4 py-2 font-sans font-medium text-sm cursor-pointer transition-colors duration-200",
|
|
16696
|
-
children: "Watch on YouTube"
|
|
16697
|
-
}
|
|
16698
|
-
)
|
|
16699
|
-
] }) });
|
|
16700
16640
|
}
|
|
16641
|
+
const embedUrl = `https://www.youtube-nocookie.com/embed/${videoId}?${embedParams.toString()}`;
|
|
16642
|
+
const watchUrl = `https://www.youtube.com/watch?v=${videoId}`;
|
|
16643
|
+
const posterJpg = `https://i.ytimg.com/vi/${videoId}/mqdefault.jpg`;
|
|
16644
|
+
const posterWebp = `https://i.ytimg.com/vi_webp/${videoId}/mqdefault.webp`;
|
|
16645
|
+
const handleActivate = () => {
|
|
16646
|
+
const slot = iframeSlotRef.current;
|
|
16647
|
+
if (!slot || activated) return;
|
|
16648
|
+
const iframe = document.createElement("iframe");
|
|
16649
|
+
iframe.setAttribute("allow", "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share");
|
|
16650
|
+
iframe.setAttribute("allowfullscreen", "");
|
|
16651
|
+
iframe.setAttribute("title", title);
|
|
16652
|
+
iframe.className = "absolute inset-0 w-full h-full border-0";
|
|
16653
|
+
iframe.src = embedUrl;
|
|
16654
|
+
slot.appendChild(iframe);
|
|
16655
|
+
setActivated(true);
|
|
16656
|
+
};
|
|
16701
16657
|
return /* @__PURE__ */ jsxs111("div", { className: `youtube-embed-container my-6 ${className}`, children: [
|
|
16702
16658
|
title && showTitle && /* @__PURE__ */ jsx138("div", { className: "video-title font-sans text-lg font-medium text-ods-text-primary mb-3", children: title }),
|
|
16703
|
-
/* @__PURE__ */
|
|
16704
|
-
|
|
16705
|
-
|
|
16706
|
-
/* @__PURE__ */ jsx138("span", { className: "font-sans text-sm text-ods-text-secondary", children: "Loading video..." })
|
|
16707
|
-
] }) }),
|
|
16708
|
-
/* @__PURE__ */ jsx138("div", { className: "video-player absolute inset-0 rounded-lg overflow-hidden border border-ods-border bg-ods-bg-inverse", children: useIframe ? (
|
|
16709
|
-
// Iframe fallback for mobile and error cases
|
|
16710
|
-
/* @__PURE__ */ jsx138(
|
|
16711
|
-
"iframe",
|
|
16712
|
-
{
|
|
16713
|
-
src: embedUrl,
|
|
16714
|
-
title,
|
|
16715
|
-
className: "w-full h-full border-0",
|
|
16716
|
-
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",
|
|
16717
|
-
allowFullScreen: true,
|
|
16718
|
-
style: { border: "none" }
|
|
16719
|
-
}
|
|
16720
|
-
)
|
|
16721
|
-
) : /* @__PURE__ */ jsx138(
|
|
16722
|
-
ReactPlayer,
|
|
16723
|
-
{
|
|
16724
|
-
url: videoUrl,
|
|
16725
|
-
width: "100%",
|
|
16726
|
-
height: "100%",
|
|
16727
|
-
onReady: handleReady,
|
|
16728
|
-
onError: handleError,
|
|
16729
|
-
onPlay: handlePlay,
|
|
16730
|
-
onPause: handlePause,
|
|
16731
|
-
config: {
|
|
16732
|
-
youtube: {
|
|
16733
|
-
playerVars: {
|
|
16734
|
-
autoplay: 0,
|
|
16735
|
-
controls: 1,
|
|
16736
|
-
rel: 0,
|
|
16737
|
-
showinfo: 0,
|
|
16738
|
-
modestbranding: 1,
|
|
16739
|
-
iv_load_policy: 3,
|
|
16740
|
-
cc_load_policy: 0,
|
|
16741
|
-
playsinline: 1
|
|
16742
|
-
}
|
|
16743
|
-
}
|
|
16744
|
-
},
|
|
16745
|
-
light: false,
|
|
16746
|
-
playing: false
|
|
16747
|
-
}
|
|
16748
|
-
) }),
|
|
16749
|
-
!useIframe && !isPlaying && !isLoading && /* @__PURE__ */ jsx138("div", { className: "play-overlay absolute inset-0 flex items-center justify-center bg-ods-bg-inverse bg-opacity-20 rounded-lg transition-opacity duration-300 hover:bg-opacity-30", children: /* @__PURE__ */ jsx138(
|
|
16659
|
+
/* @__PURE__ */ jsx138("div", { className: "video-wrapper relative w-full", style: { paddingBottom: "56.25%" }, children: /* @__PURE__ */ jsxs111("div", { className: "absolute inset-0 rounded-lg overflow-hidden border border-ods-border bg-ods-card", children: [
|
|
16660
|
+
/* @__PURE__ */ jsx138("div", { ref: iframeSlotRef, className: "absolute inset-0", "aria-hidden": !activated }),
|
|
16661
|
+
!activated && /* @__PURE__ */ jsxs111(
|
|
16750
16662
|
"button",
|
|
16751
16663
|
{
|
|
16752
|
-
|
|
16753
|
-
|
|
16754
|
-
|
|
16755
|
-
|
|
16664
|
+
type: "button",
|
|
16665
|
+
"aria-label": `Play: ${title}`,
|
|
16666
|
+
onClick: handleActivate,
|
|
16667
|
+
className: "group absolute inset-0 p-0 m-0 border-0 cursor-pointer bg-transparent",
|
|
16668
|
+
children: [
|
|
16669
|
+
/* @__PURE__ */ jsxs111("picture", { children: [
|
|
16670
|
+
/* @__PURE__ */ jsx138("source", { type: "image/webp", srcSet: posterWebp }),
|
|
16671
|
+
/* @__PURE__ */ jsx138(
|
|
16672
|
+
"img",
|
|
16673
|
+
{
|
|
16674
|
+
src: posterJpg,
|
|
16675
|
+
alt: title,
|
|
16676
|
+
loading: "lazy",
|
|
16677
|
+
fetchPriority: aboveTheFold ? "high" : "low",
|
|
16678
|
+
decoding: aboveTheFold ? "sync" : "async",
|
|
16679
|
+
className: "absolute inset-0 w-full h-full object-cover"
|
|
16680
|
+
}
|
|
16681
|
+
)
|
|
16682
|
+
] }),
|
|
16683
|
+
/* @__PURE__ */ jsx138("div", { className: "absolute inset-0 flex items-center justify-center bg-ods-bg-inverse bg-opacity-20 transition-opacity duration-200 group-hover:bg-opacity-30", children: /* @__PURE__ */ jsx138("span", { className: "flex items-center justify-center w-16 h-16 rounded-full bg-ods-accent text-ods-text-on-accent shadow-lg transition-transform duration-200 group-hover:scale-110", children: /* @__PURE__ */ jsx138("svg", { width: 24, height: 24, fill: "currentColor", viewBox: "0 0 24 24", className: "ml-1", children: /* @__PURE__ */ jsx138("polygon", { points: "5,3 19,12 5,21" }) }) }) })
|
|
16684
|
+
]
|
|
16756
16685
|
}
|
|
16757
|
-
)
|
|
16758
|
-
] }),
|
|
16686
|
+
)
|
|
16687
|
+
] }) }),
|
|
16759
16688
|
showMeta && /* @__PURE__ */ jsxs111("div", { className: "video-meta flex items-center justify-between mt-3 text-sm text-ods-text-secondary", children: [
|
|
16760
16689
|
/* @__PURE__ */ jsx138("div", { className: "video-platform font-sans", children: "YouTube" }),
|
|
16761
16690
|
/* @__PURE__ */ jsx138(
|
|
16762
16691
|
"a",
|
|
16763
16692
|
{
|
|
16764
|
-
href:
|
|
16693
|
+
href: watchUrl,
|
|
16765
16694
|
target: "_blank",
|
|
16766
16695
|
rel: "noopener noreferrer",
|
|
16767
16696
|
className: "video-link font-sans text-ods-accent hover:text-ods-accent-hover transition-colors duration-200",
|
|
@@ -16771,111 +16700,37 @@ var YouTubeEmbed = ({
|
|
|
16771
16700
|
] })
|
|
16772
16701
|
] });
|
|
16773
16702
|
};
|
|
16703
|
+
var YT_HOSTS = /* @__PURE__ */ new Set([
|
|
16704
|
+
"youtube.com",
|
|
16705
|
+
"www.youtube.com",
|
|
16706
|
+
"m.youtube.com",
|
|
16707
|
+
"youtu.be",
|
|
16708
|
+
"youtube-nocookie.com",
|
|
16709
|
+
"www.youtube-nocookie.com"
|
|
16710
|
+
]);
|
|
16711
|
+
var YT_PATH_RE = /^\/(?:embed|v|shorts)\/([^/]+)\/?$/;
|
|
16774
16712
|
var extractYouTubeId = (url) => {
|
|
16775
|
-
|
|
16776
|
-
|
|
16777
|
-
|
|
16778
|
-
|
|
16779
|
-
|
|
16780
|
-
for (const pattern of patterns) {
|
|
16781
|
-
const match = url.match(pattern);
|
|
16782
|
-
if (match) {
|
|
16783
|
-
return match[1];
|
|
16784
|
-
}
|
|
16713
|
+
let u;
|
|
16714
|
+
try {
|
|
16715
|
+
u = new URL(url);
|
|
16716
|
+
} catch {
|
|
16717
|
+
return null;
|
|
16785
16718
|
}
|
|
16786
|
-
return null;
|
|
16787
|
-
|
|
16788
|
-
|
|
16789
|
-
const videoId = extractYouTubeId(href);
|
|
16790
|
-
if (videoId) {
|
|
16791
|
-
return /* @__PURE__ */ jsx138(YouTubeEmbed, { videoId, title: typeof children === "string" ? children : void 0 });
|
|
16719
|
+
if (!YT_HOSTS.has(u.hostname.toLowerCase())) return null;
|
|
16720
|
+
if (u.hostname.toLowerCase().endsWith("youtu.be")) {
|
|
16721
|
+
return u.pathname.split("/").filter(Boolean)[0] ?? null;
|
|
16792
16722
|
}
|
|
16793
|
-
|
|
16794
|
-
|
|
16795
|
-
|
|
16796
|
-
|
|
16797
|
-
target: "_blank",
|
|
16798
|
-
rel: "noopener noreferrer",
|
|
16799
|
-
className: "text-ods-accent hover:text-ods-accent-hover transition-colors duration-200",
|
|
16800
|
-
children
|
|
16801
|
-
}
|
|
16802
|
-
);
|
|
16723
|
+
const v = u.searchParams.get("v");
|
|
16724
|
+
if (v) return v;
|
|
16725
|
+
const m = u.pathname.match(YT_PATH_RE);
|
|
16726
|
+
return m ? m[1] : null;
|
|
16803
16727
|
};
|
|
16804
16728
|
|
|
16805
16729
|
// src/components/features/video-player.tsx
|
|
16806
|
-
import { useState as useState35, useEffect as
|
|
16807
|
-
import
|
|
16730
|
+
import { useState as useState35, useEffect as useEffect25, useRef as useRef22, useMemo as useMemo11, useCallback as useCallback19 } from "react";
|
|
16731
|
+
import ReactPlayer from "react-player";
|
|
16808
16732
|
init_button2();
|
|
16809
16733
|
import { jsx as jsx139, jsxs as jsxs112 } from "react/jsx-runtime";
|
|
16810
|
-
function useVideoFirstFramePoster(url, enabled) {
|
|
16811
|
-
const [poster, setPoster] = useState35(null);
|
|
16812
|
-
useEffect26(() => {
|
|
16813
|
-
if (!enabled || !url) {
|
|
16814
|
-
setPoster(null);
|
|
16815
|
-
return;
|
|
16816
|
-
}
|
|
16817
|
-
const isDirectFile = /\.(mp4|webm|mov|m4v)(\?|#|$)/i.test(url);
|
|
16818
|
-
if (!isDirectFile) {
|
|
16819
|
-
setPoster(null);
|
|
16820
|
-
return;
|
|
16821
|
-
}
|
|
16822
|
-
let cancelled = false;
|
|
16823
|
-
const video = document.createElement("video");
|
|
16824
|
-
video.crossOrigin = "anonymous";
|
|
16825
|
-
video.preload = "metadata";
|
|
16826
|
-
video.muted = true;
|
|
16827
|
-
video.playsInline = true;
|
|
16828
|
-
video.setAttribute("data-poster-extractor", "true");
|
|
16829
|
-
const cleanup = () => {
|
|
16830
|
-
video.removeAttribute("src");
|
|
16831
|
-
try {
|
|
16832
|
-
video.load();
|
|
16833
|
-
} catch {
|
|
16834
|
-
}
|
|
16835
|
-
};
|
|
16836
|
-
const onLoadedMetadata = () => {
|
|
16837
|
-
if (cancelled) return;
|
|
16838
|
-
const dur = video.duration || 10;
|
|
16839
|
-
const target = Math.max(2, Math.min(dur * 0.1, 30));
|
|
16840
|
-
video.currentTime = target;
|
|
16841
|
-
};
|
|
16842
|
-
const onSeeked = () => {
|
|
16843
|
-
if (cancelled) return;
|
|
16844
|
-
try {
|
|
16845
|
-
const canvas = document.createElement("canvas");
|
|
16846
|
-
canvas.width = video.videoWidth;
|
|
16847
|
-
canvas.height = video.videoHeight;
|
|
16848
|
-
const ctx = canvas.getContext("2d");
|
|
16849
|
-
if (!ctx || !canvas.width || !canvas.height) {
|
|
16850
|
-
cleanup();
|
|
16851
|
-
return;
|
|
16852
|
-
}
|
|
16853
|
-
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
16854
|
-
const dataUrl = canvas.toDataURL("image/jpeg", 0.82);
|
|
16855
|
-
if (!cancelled) setPoster(dataUrl);
|
|
16856
|
-
} catch (err) {
|
|
16857
|
-
console.warn("[VideoPlayer] first-frame extraction failed", err);
|
|
16858
|
-
} finally {
|
|
16859
|
-
cleanup();
|
|
16860
|
-
}
|
|
16861
|
-
};
|
|
16862
|
-
const onError = () => {
|
|
16863
|
-
cleanup();
|
|
16864
|
-
};
|
|
16865
|
-
video.addEventListener("loadedmetadata", onLoadedMetadata);
|
|
16866
|
-
video.addEventListener("seeked", onSeeked);
|
|
16867
|
-
video.addEventListener("error", onError);
|
|
16868
|
-
video.src = url;
|
|
16869
|
-
return () => {
|
|
16870
|
-
cancelled = true;
|
|
16871
|
-
video.removeEventListener("loadedmetadata", onLoadedMetadata);
|
|
16872
|
-
video.removeEventListener("seeked", onSeeked);
|
|
16873
|
-
video.removeEventListener("error", onError);
|
|
16874
|
-
cleanup();
|
|
16875
|
-
};
|
|
16876
|
-
}, [url, enabled]);
|
|
16877
|
-
return poster;
|
|
16878
|
-
}
|
|
16879
16734
|
var webkitCaptionCSSInjected = false;
|
|
16880
16735
|
function ensureWebkitCaptionCSS() {
|
|
16881
16736
|
if (webkitCaptionCSSInjected || typeof document === "undefined") return;
|
|
@@ -16918,7 +16773,7 @@ function parseSrtTimestamp(ts) {
|
|
|
16918
16773
|
function useSubtitleOverlay(srtContent) {
|
|
16919
16774
|
const cues = useMemo11(() => srtContent ? parseSrt(srtContent) : [], [srtContent]);
|
|
16920
16775
|
const [activeText, setActiveText] = useState35(null);
|
|
16921
|
-
const updateTime =
|
|
16776
|
+
const updateTime = useCallback19((playedSeconds) => {
|
|
16922
16777
|
const timeMs = playedSeconds * 1e3;
|
|
16923
16778
|
const active = cues.find((c) => timeMs >= c.from && timeMs <= c.to);
|
|
16924
16779
|
setActiveText(active?.text ?? null);
|
|
@@ -16926,7 +16781,6 @@ function useSubtitleOverlay(srtContent) {
|
|
|
16926
16781
|
return { activeText, updateTime, hasCues: cues.length > 0 };
|
|
16927
16782
|
}
|
|
16928
16783
|
var SPEED_OPTIONS = [0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
16929
|
-
var LAZY_MOUNT_PLAY_FAILURE_GRACE_MS = 2e3;
|
|
16930
16784
|
function formatTime(secs) {
|
|
16931
16785
|
if (!secs || !isFinite(secs)) return "0:00";
|
|
16932
16786
|
const h = Math.floor(secs / 3600);
|
|
@@ -16948,14 +16802,14 @@ var VideoPlayer = ({
|
|
|
16948
16802
|
srtContent,
|
|
16949
16803
|
captionsUrl,
|
|
16950
16804
|
subtitleLabel,
|
|
16951
|
-
|
|
16805
|
+
preloadStrategy = "metadata"
|
|
16952
16806
|
}) => {
|
|
16953
16807
|
const [hasError, setHasError] = useState35(false);
|
|
16954
16808
|
const [isPlaying, setIsPlaying] = useState35(autoPlay);
|
|
16955
16809
|
const [mounted, setMounted] = useState35(false);
|
|
16956
16810
|
const [hasStarted, setHasStarted] = useState35(autoPlay);
|
|
16957
|
-
const playerRef =
|
|
16958
|
-
const containerRef =
|
|
16811
|
+
const playerRef = useRef22(null);
|
|
16812
|
+
const containerRef = useRef22(null);
|
|
16959
16813
|
const [played, setPlayed] = useState35(0);
|
|
16960
16814
|
const [loaded, setLoaded] = useState35(0);
|
|
16961
16815
|
const [duration, setDuration] = useState35(0);
|
|
@@ -16964,14 +16818,13 @@ var VideoPlayer = ({
|
|
|
16964
16818
|
const [isMuted, setIsMuted] = useState35(muted);
|
|
16965
16819
|
const [isBuffering, setIsBuffering] = useState35(false);
|
|
16966
16820
|
const [showControls, setShowControls] = useState35(true);
|
|
16967
|
-
const hideTimeoutRef =
|
|
16968
|
-
const clickTimerRef =
|
|
16969
|
-
const iosFullscreenTimerRef =
|
|
16970
|
-
const lazyMountFailureTimerRef = useRef21(void 0);
|
|
16821
|
+
const hideTimeoutRef = useRef22(void 0);
|
|
16822
|
+
const clickTimerRef = useRef22(void 0);
|
|
16823
|
+
const iosFullscreenTimerRef = useRef22(void 0);
|
|
16971
16824
|
const [captionsEnabled, setCaptionsEnabled] = useState35(true);
|
|
16972
16825
|
const [isFullscreen, setIsFullscreen] = useState35(false);
|
|
16973
16826
|
const { activeText, updateTime, hasCues } = useSubtitleOverlay(srtContent);
|
|
16974
|
-
|
|
16827
|
+
useEffect25(() => {
|
|
16975
16828
|
const onChange = () => {
|
|
16976
16829
|
const fsEl = document.fullscreenElement || document.webkitFullscreenElement;
|
|
16977
16830
|
setIsFullscreen(!!fsEl);
|
|
@@ -16983,14 +16836,14 @@ var VideoPlayer = ({
|
|
|
16983
16836
|
document.removeEventListener("webkitfullscreenchange", onChange);
|
|
16984
16837
|
};
|
|
16985
16838
|
}, []);
|
|
16986
|
-
const activateCaptionTracks =
|
|
16839
|
+
const activateCaptionTracks = useCallback19((video) => {
|
|
16987
16840
|
for (let i = 0; i < video.textTracks.length; i++) {
|
|
16988
16841
|
if (video.textTracks[i].kind === "captions" || video.textTracks[i].kind === "subtitles") {
|
|
16989
16842
|
video.textTracks[i].mode = "showing";
|
|
16990
16843
|
}
|
|
16991
16844
|
}
|
|
16992
16845
|
}, []);
|
|
16993
|
-
const enterNativeVideoFullscreen =
|
|
16846
|
+
const enterNativeVideoFullscreen = useCallback19(() => {
|
|
16994
16847
|
const video = playerRef.current?.getInternalPlayer();
|
|
16995
16848
|
if (!video || !video.webkitEnterFullscreen) return;
|
|
16996
16849
|
ensureWebkitCaptionCSS();
|
|
@@ -17029,7 +16882,7 @@ var VideoPlayer = ({
|
|
|
17029
16882
|
doFullscreen();
|
|
17030
16883
|
}, 500);
|
|
17031
16884
|
}, [captionsUrl, subtitleLabel, activateCaptionTracks]);
|
|
17032
|
-
const toggleFullscreen =
|
|
16885
|
+
const toggleFullscreen = useCallback19(() => {
|
|
17033
16886
|
const container = containerRef.current;
|
|
17034
16887
|
if (!container) return;
|
|
17035
16888
|
if (isFullscreen) {
|
|
@@ -17048,7 +16901,7 @@ var VideoPlayer = ({
|
|
|
17048
16901
|
enterNativeVideoFullscreen();
|
|
17049
16902
|
}
|
|
17050
16903
|
}, [isFullscreen, enterNativeVideoFullscreen]);
|
|
17051
|
-
const toggleMute =
|
|
16904
|
+
const toggleMute = useCallback19(() => {
|
|
17052
16905
|
if (isMuted) {
|
|
17053
16906
|
setIsMuted(false);
|
|
17054
16907
|
setVolume(prevVolume || 0.5);
|
|
@@ -17058,23 +16911,23 @@ var VideoPlayer = ({
|
|
|
17058
16911
|
setVolume(0);
|
|
17059
16912
|
}
|
|
17060
16913
|
}, [isMuted, volume, prevVolume]);
|
|
17061
|
-
const handleVolumeChange =
|
|
16914
|
+
const handleVolumeChange = useCallback19((e) => {
|
|
17062
16915
|
const val = parseFloat(e.target.value);
|
|
17063
16916
|
setVolume(val);
|
|
17064
16917
|
setIsMuted(val === 0);
|
|
17065
16918
|
if (val > 0) setPrevVolume(val);
|
|
17066
16919
|
}, []);
|
|
17067
|
-
const startHideTimer =
|
|
16920
|
+
const startHideTimer = useCallback19(() => {
|
|
17068
16921
|
clearTimeout(hideTimeoutRef.current);
|
|
17069
16922
|
if (isPlaying) {
|
|
17070
16923
|
hideTimeoutRef.current = setTimeout(() => setShowControls(false), 3e3);
|
|
17071
16924
|
}
|
|
17072
16925
|
}, [isPlaying]);
|
|
17073
|
-
const handleMouseMove =
|
|
16926
|
+
const handleMouseMove = useCallback19(() => {
|
|
17074
16927
|
setShowControls(true);
|
|
17075
16928
|
startHideTimer();
|
|
17076
16929
|
}, [startHideTimer]);
|
|
17077
|
-
const handleTouchToggle =
|
|
16930
|
+
const handleTouchToggle = useCallback19(() => {
|
|
17078
16931
|
if (!hasStarted) return;
|
|
17079
16932
|
setShowControls((prev) => {
|
|
17080
16933
|
const next = !prev;
|
|
@@ -17085,7 +16938,7 @@ var VideoPlayer = ({
|
|
|
17085
16938
|
return next;
|
|
17086
16939
|
});
|
|
17087
16940
|
}, [hasStarted, isPlaying]);
|
|
17088
|
-
|
|
16941
|
+
useEffect25(() => {
|
|
17089
16942
|
if (!hasStarted) return;
|
|
17090
16943
|
const el = containerRef.current;
|
|
17091
16944
|
if (!el) return;
|
|
@@ -17143,23 +16996,23 @@ var VideoPlayer = ({
|
|
|
17143
16996
|
}, [hasStarted, duration, toggleMute, toggleFullscreen]);
|
|
17144
16997
|
const [seekPreview, setSeekPreview] = useState35(null);
|
|
17145
16998
|
const [playbackRate, setPlaybackRate] = useState35(1);
|
|
17146
|
-
const cycleSpeed =
|
|
16999
|
+
const cycleSpeed = useCallback19(() => {
|
|
17147
17000
|
setPlaybackRate((prev) => {
|
|
17148
17001
|
const idx = SPEED_OPTIONS.indexOf(prev);
|
|
17149
17002
|
return SPEED_OPTIONS[(idx + 1) % SPEED_OPTIONS.length];
|
|
17150
17003
|
});
|
|
17151
17004
|
}, []);
|
|
17152
|
-
const progressBarRef =
|
|
17153
|
-
const isDraggingRef =
|
|
17154
|
-
const dragListenersRef =
|
|
17155
|
-
const seekToClientX =
|
|
17005
|
+
const progressBarRef = useRef22(null);
|
|
17006
|
+
const isDraggingRef = useRef22(false);
|
|
17007
|
+
const dragListenersRef = useRef22(null);
|
|
17008
|
+
const seekToClientX = useCallback19((clientX) => {
|
|
17156
17009
|
const rect = progressBarRef.current?.getBoundingClientRect();
|
|
17157
17010
|
if (!rect) return;
|
|
17158
17011
|
const fraction = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
|
|
17159
17012
|
setPlayed(fraction);
|
|
17160
17013
|
playerRef.current?.seekTo(fraction, "fraction");
|
|
17161
17014
|
}, []);
|
|
17162
|
-
const handleProgressMouseDown =
|
|
17015
|
+
const handleProgressMouseDown = useCallback19((e) => {
|
|
17163
17016
|
e.stopPropagation();
|
|
17164
17017
|
e.preventDefault();
|
|
17165
17018
|
isDraggingRef.current = true;
|
|
@@ -17182,17 +17035,17 @@ var VideoPlayer = ({
|
|
|
17182
17035
|
document.addEventListener("mousemove", onMouseMove);
|
|
17183
17036
|
document.addEventListener("mouseup", onMouseUp);
|
|
17184
17037
|
}, [seekToClientX]);
|
|
17185
|
-
const handleProgressTouchStart =
|
|
17038
|
+
const handleProgressTouchStart = useCallback19((e) => {
|
|
17186
17039
|
e.stopPropagation();
|
|
17187
17040
|
const touch = e.touches[0];
|
|
17188
17041
|
if (touch) seekToClientX(touch.clientX);
|
|
17189
17042
|
}, [seekToClientX]);
|
|
17190
|
-
const handleProgressTouchMove =
|
|
17043
|
+
const handleProgressTouchMove = useCallback19((e) => {
|
|
17191
17044
|
e.stopPropagation();
|
|
17192
17045
|
const touch = e.touches[0];
|
|
17193
17046
|
if (touch) seekToClientX(touch.clientX);
|
|
17194
17047
|
}, [seekToClientX]);
|
|
17195
|
-
const handleProgressKeyDown =
|
|
17048
|
+
const handleProgressKeyDown = useCallback19((e) => {
|
|
17196
17049
|
if (e.key === "ArrowRight") {
|
|
17197
17050
|
e.preventDefault();
|
|
17198
17051
|
e.stopPropagation();
|
|
@@ -17214,15 +17067,15 @@ var VideoPlayer = ({
|
|
|
17214
17067
|
playerRef.current?.seekTo(duration, "seconds");
|
|
17215
17068
|
}
|
|
17216
17069
|
}, [duration]);
|
|
17217
|
-
const handleProgressHover =
|
|
17070
|
+
const handleProgressHover = useCallback19((e) => {
|
|
17218
17071
|
if (isDraggingRef.current) return;
|
|
17219
17072
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
17220
17073
|
const fraction = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
|
17221
17074
|
const x = Math.max(30, Math.min(rect.width - 30, e.clientX - rect.left));
|
|
17222
17075
|
setSeekPreview({ fraction, x });
|
|
17223
17076
|
}, []);
|
|
17224
|
-
const isTouchRef =
|
|
17225
|
-
const handleContainerClick =
|
|
17077
|
+
const isTouchRef = useRef22(false);
|
|
17078
|
+
const handleContainerClick = useCallback19((e) => {
|
|
17226
17079
|
if (isTouchRef.current) {
|
|
17227
17080
|
isTouchRef.current = false;
|
|
17228
17081
|
return;
|
|
@@ -17240,22 +17093,20 @@ var VideoPlayer = ({
|
|
|
17240
17093
|
}, 250);
|
|
17241
17094
|
}
|
|
17242
17095
|
}, [hasStarted, toggleFullscreen]);
|
|
17243
|
-
const handleContainerTouchEnd =
|
|
17096
|
+
const handleContainerTouchEnd = useCallback19((e) => {
|
|
17244
17097
|
if (e.target.closest(".video-controls-bar")) return;
|
|
17245
17098
|
isTouchRef.current = true;
|
|
17246
17099
|
if (!hasStarted) return;
|
|
17247
17100
|
handleTouchToggle();
|
|
17248
17101
|
}, [hasStarted, handleTouchToggle]);
|
|
17249
|
-
const
|
|
17250
|
-
const effectivePoster = poster || extractedPoster || void 0;
|
|
17102
|
+
const effectivePoster = poster || void 0;
|
|
17251
17103
|
const posterBgColor = useImageEdgeColor(effectivePoster);
|
|
17252
|
-
|
|
17104
|
+
useEffect25(() => {
|
|
17253
17105
|
setMounted(true);
|
|
17254
17106
|
return () => {
|
|
17255
17107
|
clearTimeout(clickTimerRef.current);
|
|
17256
17108
|
clearTimeout(hideTimeoutRef.current);
|
|
17257
17109
|
clearTimeout(iosFullscreenTimerRef.current);
|
|
17258
|
-
clearTimeout(lazyMountFailureTimerRef.current);
|
|
17259
17110
|
isDraggingRef.current = false;
|
|
17260
17111
|
if (dragListenersRef.current) {
|
|
17261
17112
|
document.removeEventListener("mousemove", dragListenersRef.current.move);
|
|
@@ -17264,7 +17115,7 @@ var VideoPlayer = ({
|
|
|
17264
17115
|
}
|
|
17265
17116
|
};
|
|
17266
17117
|
}, []);
|
|
17267
|
-
|
|
17118
|
+
useEffect25(() => {
|
|
17268
17119
|
if (!hasStarted) return;
|
|
17269
17120
|
const video = playerRef.current?.getInternalPlayer();
|
|
17270
17121
|
if (!video) return;
|
|
@@ -17272,37 +17123,31 @@ var VideoPlayer = ({
|
|
|
17272
17123
|
video.addEventListener("webkitbeginfullscreen", onBeginFS);
|
|
17273
17124
|
return () => video.removeEventListener("webkitbeginfullscreen", onBeginFS);
|
|
17274
17125
|
}, [hasStarted, activateCaptionTracks]);
|
|
17275
|
-
const handleError =
|
|
17276
|
-
const handlePlay =
|
|
17126
|
+
const handleError = useCallback19(() => setHasError(true), []);
|
|
17127
|
+
const handlePlay = useCallback19(() => {
|
|
17277
17128
|
setIsPlaying(true);
|
|
17278
17129
|
setHasStarted(true);
|
|
17279
17130
|
}, []);
|
|
17280
|
-
const handlePause =
|
|
17281
|
-
const handleEnded =
|
|
17282
|
-
const handlePlayClick =
|
|
17283
|
-
|
|
17284
|
-
|
|
17285
|
-
|
|
17286
|
-
|
|
17287
|
-
|
|
17288
|
-
|
|
17289
|
-
if (native.paused && native.error) setHasError(true);
|
|
17290
|
-
}, LAZY_MOUNT_PLAY_FAILURE_GRACE_MS);
|
|
17291
|
-
});
|
|
17292
|
-
} else if (process.env.NODE_ENV !== "production") {
|
|
17293
|
-
console.warn("[VideoPlayer] lazyMount sync play(): no native HTMLVideoElement yet");
|
|
17294
|
-
}
|
|
17131
|
+
const handlePause = useCallback19(() => setIsPlaying(false), []);
|
|
17132
|
+
const handleEnded = useCallback19(() => setIsPlaying(false), []);
|
|
17133
|
+
const handlePlayClick = useCallback19(() => {
|
|
17134
|
+
const native = playerRef.current?.getInternalPlayer();
|
|
17135
|
+
if (native instanceof HTMLVideoElement) {
|
|
17136
|
+
native.play().catch(() => {
|
|
17137
|
+
});
|
|
17138
|
+
} else if (process.env.NODE_ENV !== "production") {
|
|
17139
|
+
console.warn("[VideoPlayer] sync play(): no native HTMLVideoElement yet");
|
|
17295
17140
|
}
|
|
17296
17141
|
setHasStarted(true);
|
|
17297
17142
|
setIsPlaying(true);
|
|
17298
|
-
}, [
|
|
17299
|
-
const handleProgress =
|
|
17143
|
+
}, []);
|
|
17144
|
+
const handleProgress = useCallback19(({ played: p, loaded: l, playedSeconds }) => {
|
|
17300
17145
|
setPlayed(p);
|
|
17301
17146
|
setLoaded(l);
|
|
17302
17147
|
updateTime(playedSeconds);
|
|
17303
17148
|
}, [updateTime]);
|
|
17304
|
-
const handleBuffer =
|
|
17305
|
-
const handleBufferEnd =
|
|
17149
|
+
const handleBuffer = useCallback19(() => setIsBuffering(true), []);
|
|
17150
|
+
const handleBufferEnd = useCallback19(() => setIsBuffering(false), []);
|
|
17306
17151
|
if (!mounted) {
|
|
17307
17152
|
return /* @__PURE__ */ jsx139("div", { className: `video-player-container ${className}`, children: /* @__PURE__ */ jsx139(
|
|
17308
17153
|
"div",
|
|
@@ -17349,7 +17194,7 @@ var VideoPlayer = ({
|
|
|
17349
17194
|
/* @__PURE__ */ jsx139("div", { className: `absolute inset-0 ${effectivePoster ? "bg-black/40" : "bg-black/20"} group-hover:bg-black/50 transition-all flex items-center justify-center rounded-md`, children: /* @__PURE__ */ jsx139("div", { className: "w-16 h-16 rounded-full bg-ods-accent hover:bg-ods-accent/90 transition-all flex items-center justify-center shadow-lg", children: /* @__PURE__ */ jsx139(PlayIcon, { size: 24, className: "ml-1 text-ods-text-on-accent" }) }) })
|
|
17350
17195
|
] }),
|
|
17351
17196
|
/* @__PURE__ */ jsx139("div", { className: isFullscreen ? "video-player absolute inset-0" : useNativeAspectRatio ? "video-player rounded-md overflow-hidden border border-ods-border bg-ods-background" : "video-player absolute inset-0 rounded-md overflow-hidden border border-ods-border bg-ods-background", children: /* @__PURE__ */ jsx139(
|
|
17352
|
-
|
|
17197
|
+
ReactPlayer,
|
|
17353
17198
|
{
|
|
17354
17199
|
ref: playerRef,
|
|
17355
17200
|
url,
|
|
@@ -17370,7 +17215,7 @@ var VideoPlayer = ({
|
|
|
17370
17215
|
onBufferEnd: handleBufferEnd,
|
|
17371
17216
|
onProgress: handleProgress,
|
|
17372
17217
|
progressInterval: 200,
|
|
17373
|
-
config: { file: { attributes: { controlsList: "nodownload", playsInline: true, preload:
|
|
17218
|
+
config: { file: { attributes: { controlsList: "nodownload", playsInline: true, preload: hasStarted ? "auto" : preloadStrategy } } },
|
|
17374
17219
|
light: false,
|
|
17375
17220
|
playsinline: true
|
|
17376
17221
|
}
|
|
@@ -17585,7 +17430,7 @@ import React46 from "react";
|
|
|
17585
17430
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
17586
17431
|
import { Check as Check2 } from "lucide-react";
|
|
17587
17432
|
import Link3 from "next/link";
|
|
17588
|
-
import React45, { useCallback as
|
|
17433
|
+
import React45, { useCallback as useCallback20, useState as useState36 } from "react";
|
|
17589
17434
|
init_cn();
|
|
17590
17435
|
init_button2();
|
|
17591
17436
|
import { Fragment as Fragment19, jsx as jsx140, jsxs as jsxs113 } from "react/jsx-runtime";
|
|
@@ -17593,7 +17438,7 @@ var ROW_CLASSES = "flex flex-1 min-w-0 items-center gap-2 px-3 py-3 cursor-point
|
|
|
17593
17438
|
var WRAPPER_CLASSES = "relative flex items-stretch border-b border-ods-border last:border-b-0";
|
|
17594
17439
|
var SECONDARY_ACTION_CLASSES = "flex w-10 shrink-0 items-center justify-center self-stretch border-l border-ods-border transition-colors hover:bg-ods-bg-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ods-focus";
|
|
17595
17440
|
var SecondaryAction = ({ action }) => {
|
|
17596
|
-
const handleClick =
|
|
17441
|
+
const handleClick = useCallback20(
|
|
17597
17442
|
(e) => {
|
|
17598
17443
|
e.stopPropagation();
|
|
17599
17444
|
if (action.disabled) {
|
|
@@ -17638,7 +17483,7 @@ var SecondaryAction = ({ action }) => {
|
|
|
17638
17483
|
);
|
|
17639
17484
|
};
|
|
17640
17485
|
var MenuItem = ({ item, onItemClick }) => {
|
|
17641
|
-
const activate =
|
|
17486
|
+
const activate = useCallback20(() => {
|
|
17642
17487
|
if (item.disabled) return;
|
|
17643
17488
|
if (item.type === "checkbox") {
|
|
17644
17489
|
item.onClick?.();
|
|
@@ -17649,7 +17494,7 @@ var MenuItem = ({ item, onItemClick }) => {
|
|
|
17649
17494
|
item.onClick?.();
|
|
17650
17495
|
onItemClick?.(item);
|
|
17651
17496
|
}, [item, onItemClick]);
|
|
17652
|
-
const handleClick =
|
|
17497
|
+
const handleClick = useCallback20(
|
|
17653
17498
|
(e) => {
|
|
17654
17499
|
e.stopPropagation();
|
|
17655
17500
|
e.preventDefault();
|
|
@@ -17657,7 +17502,7 @@ var MenuItem = ({ item, onItemClick }) => {
|
|
|
17657
17502
|
},
|
|
17658
17503
|
[activate]
|
|
17659
17504
|
);
|
|
17660
|
-
const handleKeyDown =
|
|
17505
|
+
const handleKeyDown = useCallback20(
|
|
17661
17506
|
(e) => {
|
|
17662
17507
|
if (e.key !== "Enter" && e.key !== " ") return;
|
|
17663
17508
|
e.preventDefault();
|
|
@@ -17666,7 +17511,7 @@ var MenuItem = ({ item, onItemClick }) => {
|
|
|
17666
17511
|
},
|
|
17667
17512
|
[activate]
|
|
17668
17513
|
);
|
|
17669
|
-
const handleLinkClick =
|
|
17514
|
+
const handleLinkClick = useCallback20(
|
|
17670
17515
|
(e) => {
|
|
17671
17516
|
if (item.disabled) {
|
|
17672
17517
|
e.preventDefault();
|
|
@@ -17827,7 +17672,7 @@ var ActionsMenuDropdown = ({
|
|
|
17827
17672
|
sideOffset = 6
|
|
17828
17673
|
}) => {
|
|
17829
17674
|
const [open, setOpen] = useState36(false);
|
|
17830
|
-
const handleItemClick =
|
|
17675
|
+
const handleItemClick = useCallback20(
|
|
17831
17676
|
(item) => {
|
|
17832
17677
|
onItemClick?.(item);
|
|
17833
17678
|
if (item.type !== "checkbox" && item.type !== "submenu") {
|
|
@@ -18355,7 +18200,7 @@ function ReleaseDetailPage({
|
|
|
18355
18200
|
const [deliveryData, setDeliveryData] = useState37(null);
|
|
18356
18201
|
const [roadmapLoading, setRoadmapLoading] = useState37(false);
|
|
18357
18202
|
const [deliveryLoading, setDeliveryLoading] = useState37(false);
|
|
18358
|
-
|
|
18203
|
+
useEffect26(() => {
|
|
18359
18204
|
async function fetchLinkedTasks() {
|
|
18360
18205
|
if (!release) return;
|
|
18361
18206
|
try {
|
|
@@ -18910,7 +18755,7 @@ function CompactPageLoader({
|
|
|
18910
18755
|
}
|
|
18911
18756
|
|
|
18912
18757
|
// src/components/ui/progress-bar.tsx
|
|
18913
|
-
import { useEffect as
|
|
18758
|
+
import { useEffect as useEffect28, useRef as useRef23, useState as useState39 } from "react";
|
|
18914
18759
|
import { jsx as jsx152 } from "react/jsx-runtime";
|
|
18915
18760
|
var ProgressBar = ({
|
|
18916
18761
|
progress,
|
|
@@ -18926,9 +18771,9 @@ var ProgressBar = ({
|
|
|
18926
18771
|
const isMdUp = useMdUp() ?? true;
|
|
18927
18772
|
const effectiveSegmentWidth = isMdUp ? segmentWidth : mobileSegmentWidth;
|
|
18928
18773
|
const effectiveHeight = isMdUp ? height : mobileHeight;
|
|
18929
|
-
const containerRef =
|
|
18774
|
+
const containerRef = useRef23(null);
|
|
18930
18775
|
const [segmentCount, setSegmentCount] = useState39(0);
|
|
18931
|
-
|
|
18776
|
+
useEffect28(() => {
|
|
18932
18777
|
if (!containerRef.current) return;
|
|
18933
18778
|
const resizeObserver = new ResizeObserver(() => {
|
|
18934
18779
|
if (containerRef.current) {
|
|
@@ -19752,11 +19597,11 @@ DialogDescription.displayName = DialogPrimitive3.Description.displayName;
|
|
|
19752
19597
|
// src/components/ui/modal.tsx
|
|
19753
19598
|
init_cn();
|
|
19754
19599
|
import * as React56 from "react";
|
|
19755
|
-
import { useEffect as
|
|
19600
|
+
import { useEffect as useEffect29 } from "react";
|
|
19756
19601
|
import { jsx as jsx158, jsxs as jsxs129 } from "react/jsx-runtime";
|
|
19757
19602
|
var Modal = React56.forwardRef(
|
|
19758
19603
|
({ isOpen, onClose, children, className }, ref) => {
|
|
19759
|
-
|
|
19604
|
+
useEffect29(() => {
|
|
19760
19605
|
const handleKeyDown = (event) => {
|
|
19761
19606
|
if (event.key === "Escape") {
|
|
19762
19607
|
onClose();
|
|
@@ -19838,13 +19683,13 @@ ModalFooter.displayName = "ModalFooter";
|
|
|
19838
19683
|
|
|
19839
19684
|
// src/components/ui/modal-v2.tsx
|
|
19840
19685
|
import * as React57 from "react";
|
|
19841
|
-
import { useEffect as
|
|
19686
|
+
import { useEffect as useEffect30 } from "react";
|
|
19842
19687
|
init_cn();
|
|
19843
19688
|
import { jsx as jsx159, jsxs as jsxs130 } from "react/jsx-runtime";
|
|
19844
19689
|
var ModalContext = React57.createContext({});
|
|
19845
19690
|
var Modal2 = React57.forwardRef(
|
|
19846
19691
|
({ isOpen, onClose, children, className }, ref) => {
|
|
19847
|
-
|
|
19692
|
+
useEffect30(() => {
|
|
19848
19693
|
const handleKeyDown = (event) => {
|
|
19849
19694
|
if (event.key === "Escape") {
|
|
19850
19695
|
onClose();
|
|
@@ -20518,7 +20363,7 @@ function TabContent({
|
|
|
20518
20363
|
|
|
20519
20364
|
// src/components/ui/tab-navigation.tsx
|
|
20520
20365
|
init_cn();
|
|
20521
|
-
import { useState as useState42, useEffect as
|
|
20366
|
+
import { useState as useState42, useEffect as useEffect31, useMemo as useMemo12, useRef as useRef25, useCallback as useCallback22 } from "react";
|
|
20522
20367
|
import { useSearchParams as useSearchParams3, useRouter as useRouter5, usePathname as usePathname3 } from "next/navigation";
|
|
20523
20368
|
import { Fragment as Fragment22, jsx as jsx168, jsxs as jsxs137 } from "react/jsx-runtime";
|
|
20524
20369
|
function TabNavigation({
|
|
@@ -20551,7 +20396,7 @@ function TabNavigation({
|
|
|
20551
20396
|
};
|
|
20552
20397
|
const [internalActiveTab, setInternalActiveTab] = useState42(getInitialTab);
|
|
20553
20398
|
const activeTab = isUrlSyncEnabled ? internalActiveTab : controlledActiveTab || "";
|
|
20554
|
-
|
|
20399
|
+
useEffect31(() => {
|
|
20555
20400
|
if (!isUrlSyncEnabled) return;
|
|
20556
20401
|
const fromUrl = searchParams?.get(paramName) || "";
|
|
20557
20402
|
const nextTab = validTabIds.has(fromUrl) ? fromUrl : defaultTab || tabs[0]?.id || "";
|
|
@@ -20571,16 +20416,16 @@ function TabNavigation({
|
|
|
20571
20416
|
controlledOnTabChange?.(tabId);
|
|
20572
20417
|
}
|
|
20573
20418
|
};
|
|
20574
|
-
const scrollRef =
|
|
20419
|
+
const scrollRef = useRef25(null);
|
|
20575
20420
|
const [canScrollLeft, setCanScrollLeft] = useState42(false);
|
|
20576
20421
|
const [canScrollRight, setCanScrollRight] = useState42(false);
|
|
20577
|
-
const updateScrollShadows =
|
|
20422
|
+
const updateScrollShadows = useCallback22(() => {
|
|
20578
20423
|
const el = scrollRef.current;
|
|
20579
20424
|
if (!el) return;
|
|
20580
20425
|
setCanScrollLeft(el.scrollLeft > 0);
|
|
20581
20426
|
setCanScrollRight(el.scrollLeft + el.clientWidth < el.scrollWidth - 1);
|
|
20582
20427
|
}, []);
|
|
20583
|
-
|
|
20428
|
+
useEffect31(() => {
|
|
20584
20429
|
const el = scrollRef.current;
|
|
20585
20430
|
if (!el) return;
|
|
20586
20431
|
updateScrollShadows();
|
|
@@ -20769,11 +20614,11 @@ function StatusIndicator({ status, label, href }) {
|
|
|
20769
20614
|
|
|
20770
20615
|
// src/components/layout/list-page-layout.tsx
|
|
20771
20616
|
init_cn();
|
|
20772
|
-
import { useEffect as
|
|
20617
|
+
import { useEffect as useEffect33, useState as useState44 } from "react";
|
|
20773
20618
|
|
|
20774
20619
|
// src/components/ui/filter-modal.tsx
|
|
20775
20620
|
init_cn();
|
|
20776
|
-
import { useEffect as
|
|
20621
|
+
import { useEffect as useEffect32, useState as useState43 } from "react";
|
|
20777
20622
|
init_button2();
|
|
20778
20623
|
|
|
20779
20624
|
// src/components/ui/filter-checkbox-item.tsx
|
|
@@ -20973,7 +20818,7 @@ function FilterModal({
|
|
|
20973
20818
|
return { ...currentFilters };
|
|
20974
20819
|
});
|
|
20975
20820
|
const [pendingTags, setPendingTags] = useState43(selectedTags ?? []);
|
|
20976
|
-
|
|
20821
|
+
useEffect32(() => {
|
|
20977
20822
|
if (isOpen) {
|
|
20978
20823
|
setSelectedFilters({ ...currentFilters });
|
|
20979
20824
|
setPendingTags(selectedTags ?? []);
|
|
@@ -21119,10 +20964,10 @@ function ListPageLayout({
|
|
|
21119
20964
|
const [mobileFilterOpen, setMobileFilterOpen] = useState44(false);
|
|
21120
20965
|
const [localSearchValue, setLocalSearchValue] = useState44(searchValue);
|
|
21121
20966
|
const debouncedSearchValue = useDebounce(localSearchValue, 500);
|
|
21122
|
-
|
|
20967
|
+
useEffect33(() => {
|
|
21123
20968
|
setLocalSearchValue(searchValue);
|
|
21124
20969
|
}, [searchValue]);
|
|
21125
|
-
|
|
20970
|
+
useEffect33(() => {
|
|
21126
20971
|
if (debouncedSearchValue !== searchValue) {
|
|
21127
20972
|
onSearch(debouncedSearchValue);
|
|
21128
20973
|
}
|
|
@@ -23299,7 +23144,7 @@ var ListLoader = (props) => /* @__PURE__ */ jsx206(ContentLoader, { ...props, va
|
|
|
23299
23144
|
|
|
23300
23145
|
// src/components/ui/table/table.tsx
|
|
23301
23146
|
init_cn();
|
|
23302
|
-
import { useEffect as
|
|
23147
|
+
import { useEffect as useEffect34, useRef as useRef28 } from "react";
|
|
23303
23148
|
init_pagination();
|
|
23304
23149
|
init_button2();
|
|
23305
23150
|
|
|
@@ -24050,10 +23895,10 @@ function Table({
|
|
|
24050
23895
|
};
|
|
24051
23896
|
const allSelected = selectedRows.length > 0 && selectedRows.length === data.length;
|
|
24052
23897
|
const someSelected = selectedRows.length > 0 && selectedRows.length < data.length;
|
|
24053
|
-
const sentinelRef =
|
|
24054
|
-
const onLoadMoreRef =
|
|
23898
|
+
const sentinelRef = useRef28(null);
|
|
23899
|
+
const onLoadMoreRef = useRef28(infiniteScroll?.onLoadMore);
|
|
24055
23900
|
onLoadMoreRef.current = infiniteScroll?.onLoadMore;
|
|
24056
|
-
|
|
23901
|
+
useEffect34(() => {
|
|
24057
23902
|
if (!infiniteScroll?.hasNextPage || infiniteScroll.isFetchingNextPage) return;
|
|
24058
23903
|
const sentinel = sentinelRef.current;
|
|
24059
23904
|
if (!sentinel) return;
|
|
@@ -24265,7 +24110,7 @@ import { useMemo as useMemo16 } from "react";
|
|
|
24265
24110
|
|
|
24266
24111
|
// src/components/ui/query-report-table/query-report-table-header.tsx
|
|
24267
24112
|
init_cn();
|
|
24268
|
-
import { useRef as
|
|
24113
|
+
import { useRef as useRef29, useState as useState47, useCallback as useCallback23 } from "react";
|
|
24269
24114
|
import { jsx as jsx217, jsxs as jsxs176 } from "react/jsx-runtime";
|
|
24270
24115
|
function QueryReportTableHeader({
|
|
24271
24116
|
columns,
|
|
@@ -24294,9 +24139,9 @@ function QueryReportTableHeader({
|
|
|
24294
24139
|
);
|
|
24295
24140
|
}
|
|
24296
24141
|
function TruncatedHeaderCell({ value, width }) {
|
|
24297
|
-
const textRef =
|
|
24142
|
+
const textRef = useRef29(null);
|
|
24298
24143
|
const [isTruncated, setIsTruncated] = useState47(false);
|
|
24299
|
-
const checkTruncation =
|
|
24144
|
+
const checkTruncation = useCallback23(() => {
|
|
24300
24145
|
const el = textRef.current;
|
|
24301
24146
|
if (el) {
|
|
24302
24147
|
setIsTruncated(el.scrollWidth > el.clientWidth);
|
|
@@ -24324,7 +24169,7 @@ function TruncatedHeaderCell({ value, width }) {
|
|
|
24324
24169
|
|
|
24325
24170
|
// src/components/ui/query-report-table/query-report-table-row.tsx
|
|
24326
24171
|
init_cn();
|
|
24327
|
-
import { useRef as
|
|
24172
|
+
import { useRef as useRef30, useState as useState48, useCallback as useCallback24 } from "react";
|
|
24328
24173
|
import { jsx as jsx218, jsxs as jsxs177 } from "react/jsx-runtime";
|
|
24329
24174
|
function QueryReportTableRow({
|
|
24330
24175
|
row,
|
|
@@ -24370,9 +24215,9 @@ function QueryReportTableRow({
|
|
|
24370
24215
|
);
|
|
24371
24216
|
}
|
|
24372
24217
|
function TruncatedCell({ value, className }) {
|
|
24373
|
-
const textRef =
|
|
24218
|
+
const textRef = useRef30(null);
|
|
24374
24219
|
const [isTruncated, setIsTruncated] = useState48(false);
|
|
24375
|
-
const checkTruncation =
|
|
24220
|
+
const checkTruncation = useCallback24(() => {
|
|
24376
24221
|
const el = textRef.current;
|
|
24377
24222
|
if (el) {
|
|
24378
24223
|
setIsTruncated(el.scrollWidth > el.clientWidth);
|
|
@@ -24635,7 +24480,7 @@ init_cn();
|
|
|
24635
24480
|
|
|
24636
24481
|
// src/components/ui/data-table/data-table-column-filter.tsx
|
|
24637
24482
|
init_cn();
|
|
24638
|
-
import { useCallback as
|
|
24483
|
+
import { useCallback as useCallback25, useMemo as useMemo17 } from "react";
|
|
24639
24484
|
|
|
24640
24485
|
// src/components/ui/data-table/utils.ts
|
|
24641
24486
|
function getHideClasses2(hideAt) {
|
|
@@ -24695,14 +24540,14 @@ function DataTableColumnFilter({
|
|
|
24695
24540
|
() => ({ [column.id]: currentValue ?? EMPTY_ARRAY }),
|
|
24696
24541
|
[column.id, currentValue]
|
|
24697
24542
|
);
|
|
24698
|
-
const handleApply =
|
|
24543
|
+
const handleApply = useCallback25(
|
|
24699
24544
|
(applied) => {
|
|
24700
24545
|
const next = applied[column.id] ?? [];
|
|
24701
24546
|
column.setFilterValue(next.length > 0 ? next : void 0);
|
|
24702
24547
|
},
|
|
24703
24548
|
[column]
|
|
24704
24549
|
);
|
|
24705
|
-
const handleReset =
|
|
24550
|
+
const handleReset = useCallback25(() => {
|
|
24706
24551
|
column.setFilterValue(void 0);
|
|
24707
24552
|
}, [column]);
|
|
24708
24553
|
return /* @__PURE__ */ jsx222(
|
|
@@ -24889,7 +24734,7 @@ function DataTableEmpty({
|
|
|
24889
24734
|
// src/components/ui/data-table/data-table-row.tsx
|
|
24890
24735
|
init_cn();
|
|
24891
24736
|
import Link10 from "next/link";
|
|
24892
|
-
import { memo as memo4, useCallback as
|
|
24737
|
+
import { memo as memo4, useCallback as useCallback26 } from "react";
|
|
24893
24738
|
import { flexRender as flexRender2 } from "@tanstack/react-table";
|
|
24894
24739
|
|
|
24895
24740
|
// src/components/ui/data-table/data-table-skeleton.tsx
|
|
@@ -24970,7 +24815,7 @@ function DataTableRowImpl({
|
|
|
24970
24815
|
className
|
|
24971
24816
|
}) {
|
|
24972
24817
|
const isLinkMode = Boolean(href) && !onClick;
|
|
24973
|
-
const handleClick =
|
|
24818
|
+
const handleClick = useCallback26(
|
|
24974
24819
|
(e) => {
|
|
24975
24820
|
const target = e.target;
|
|
24976
24821
|
if (target.closest("[data-no-row-click]")) return;
|
|
@@ -25107,7 +24952,7 @@ function DataTableBody({
|
|
|
25107
24952
|
}
|
|
25108
24953
|
|
|
25109
24954
|
// src/components/ui/data-table/data-table-infinite-footer.tsx
|
|
25110
|
-
import { useEffect as
|
|
24955
|
+
import { useEffect as useEffect35, useRef as useRef31 } from "react";
|
|
25111
24956
|
import { Fragment as Fragment34, jsx as jsx228, jsxs as jsxs186 } from "react/jsx-runtime";
|
|
25112
24957
|
function DataTableInfiniteFooter({
|
|
25113
24958
|
hasNextPage,
|
|
@@ -25116,10 +24961,10 @@ function DataTableInfiniteFooter({
|
|
|
25116
24961
|
skeletonRows = 3,
|
|
25117
24962
|
rootMargin = "200px"
|
|
25118
24963
|
}) {
|
|
25119
|
-
const sentinelRef =
|
|
25120
|
-
const onLoadMoreRef =
|
|
24964
|
+
const sentinelRef = useRef31(null);
|
|
24965
|
+
const onLoadMoreRef = useRef31(onLoadMore);
|
|
25121
24966
|
onLoadMoreRef.current = onLoadMore;
|
|
25122
|
-
|
|
24967
|
+
useEffect35(() => {
|
|
25123
24968
|
if (!hasNextPage || isFetchingNextPage) return;
|
|
25124
24969
|
const sentinel = sentinelRef.current;
|
|
25125
24970
|
if (!sentinel) return;
|
|
@@ -25244,7 +25089,7 @@ var DataTable = Object.assign(DataTableRoot, {
|
|
|
25244
25089
|
});
|
|
25245
25090
|
|
|
25246
25091
|
// src/components/ui/phone-input.tsx
|
|
25247
|
-
import { useCallback as
|
|
25092
|
+
import { useCallback as useCallback27, useEffect as useEffect36, useMemo as useMemo18, useRef as useRef32, useState as useState49 } from "react";
|
|
25248
25093
|
import { jsx as jsx230, jsxs as jsxs188 } from "react/jsx-runtime";
|
|
25249
25094
|
function PhoneInput({
|
|
25250
25095
|
value,
|
|
@@ -25262,9 +25107,9 @@ function PhoneInput({
|
|
|
25262
25107
|
[countryCode, priority, others]
|
|
25263
25108
|
);
|
|
25264
25109
|
const [isInvalid, setIsInvalid] = useState49(false);
|
|
25265
|
-
const debounceRef =
|
|
25266
|
-
const digitCount =
|
|
25267
|
-
const runValidation =
|
|
25110
|
+
const debounceRef = useRef32(null);
|
|
25111
|
+
const digitCount = useCallback27((val) => val.replace(/[^0-9]/g, "").length, []);
|
|
25112
|
+
const runValidation = useCallback27((phone) => {
|
|
25268
25113
|
if (!phone || digitCount(phone) === 0) {
|
|
25269
25114
|
setIsInvalid(false);
|
|
25270
25115
|
onValidationChange?.(false);
|
|
@@ -25274,11 +25119,11 @@ function PhoneInput({
|
|
|
25274
25119
|
setIsInvalid(invalid);
|
|
25275
25120
|
onValidationChange?.(invalid);
|
|
25276
25121
|
}, [countryCode, digitCount, onValidationChange]);
|
|
25277
|
-
const debouncedValidation =
|
|
25122
|
+
const debouncedValidation = useCallback27((phone) => {
|
|
25278
25123
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
25279
25124
|
debounceRef.current = setTimeout(() => runValidation(phone), 300);
|
|
25280
25125
|
}, [runValidation]);
|
|
25281
|
-
|
|
25126
|
+
useEffect36(() => {
|
|
25282
25127
|
return () => {
|
|
25283
25128
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
25284
25129
|
};
|
|
@@ -25840,8 +25685,8 @@ function FilterList({
|
|
|
25840
25685
|
|
|
25841
25686
|
// src/components/ui/tag-search-input.tsx
|
|
25842
25687
|
import {
|
|
25843
|
-
useEffect as
|
|
25844
|
-
useRef as
|
|
25688
|
+
useEffect as useEffect38,
|
|
25689
|
+
useRef as useRef34,
|
|
25845
25690
|
useState as useState51
|
|
25846
25691
|
} from "react";
|
|
25847
25692
|
init_cn();
|
|
@@ -25876,11 +25721,11 @@ function TagSearchInput({
|
|
|
25876
25721
|
limitTags,
|
|
25877
25722
|
placeholder: currentPlaceholder
|
|
25878
25723
|
});
|
|
25879
|
-
const wrapperRef =
|
|
25880
|
-
const hiddenTagsRef =
|
|
25881
|
-
const hiddenTagsPopupRef =
|
|
25724
|
+
const wrapperRef = useRef34(null);
|
|
25725
|
+
const hiddenTagsRef = useRef34(null);
|
|
25726
|
+
const hiddenTagsPopupRef = useRef34(null);
|
|
25882
25727
|
const [showHiddenTags, setShowHiddenTags] = useState51(false);
|
|
25883
|
-
|
|
25728
|
+
useEffect38(() => {
|
|
25884
25729
|
if (!showHiddenTags) return;
|
|
25885
25730
|
const handleClick = (e) => {
|
|
25886
25731
|
const target = e.target;
|
|
@@ -26036,7 +25881,7 @@ function TagSearchInput({
|
|
|
26036
25881
|
|
|
26037
25882
|
// src/components/ui/markdown-editor.tsx
|
|
26038
25883
|
init_cn();
|
|
26039
|
-
import { useRef as
|
|
25884
|
+
import { useRef as useRef35, useCallback as useCallback28, useState as useState52, useEffect as useEffect39 } from "react";
|
|
26040
25885
|
import dynamic from "next/dynamic";
|
|
26041
25886
|
import { Loader2 as Loader23, Upload as Upload2 } from "lucide-react";
|
|
26042
25887
|
import { jsx as jsx234, jsxs as jsxs192 } from "react/jsx-runtime";
|
|
@@ -26067,7 +25912,7 @@ body .w-md-editor .w-md-editor-bar::after { content: '' !important; display: blo
|
|
|
26067
25912
|
body .w-md-editor .w-md-editor-bar:hover::after { border-color: var(--color-text-secondary) !important; }
|
|
26068
25913
|
`;
|
|
26069
25914
|
function MarkdownEditorStyles() {
|
|
26070
|
-
|
|
25915
|
+
useEffect39(() => {
|
|
26071
25916
|
if (document.getElementById(MARKDOWN_EDITOR_STYLE_ID)) return;
|
|
26072
25917
|
const style = document.createElement("style");
|
|
26073
25918
|
style.id = MARKDOWN_EDITOR_STYLE_ID;
|
|
@@ -26091,11 +25936,11 @@ function MarkdownEditor({
|
|
|
26091
25936
|
onFileUploaded,
|
|
26092
25937
|
renderPreview
|
|
26093
25938
|
}) {
|
|
26094
|
-
const fileInputRef =
|
|
25939
|
+
const fileInputRef = useRef35(null);
|
|
26095
25940
|
const [isUploading, setIsUploading] = useState52(false);
|
|
26096
25941
|
const [uploadProgress, setUploadProgress] = useState52("");
|
|
26097
25942
|
const [defaultExtraCommands, setDefaultExtraCommands] = useState52([]);
|
|
26098
|
-
|
|
25943
|
+
useEffect39(() => {
|
|
26099
25944
|
import("@uiw/react-md-editor").then((mod) => {
|
|
26100
25945
|
if (mod.commands?.getExtraCommands) {
|
|
26101
25946
|
setDefaultExtraCommands(mod.commands.getExtraCommands());
|
|
@@ -26105,7 +25950,7 @@ function MarkdownEditor({
|
|
|
26105
25950
|
const handleChange = (val) => {
|
|
26106
25951
|
onChange(val || "");
|
|
26107
25952
|
};
|
|
26108
|
-
const insertTextAtCursor =
|
|
25953
|
+
const insertTextAtCursor = useCallback28(
|
|
26109
25954
|
(text) => {
|
|
26110
25955
|
const textarea = document.querySelector(
|
|
26111
25956
|
".w-md-editor-text-textarea"
|
|
@@ -26121,7 +25966,7 @@ function MarkdownEditor({
|
|
|
26121
25966
|
},
|
|
26122
25967
|
[value, onChange]
|
|
26123
25968
|
);
|
|
26124
|
-
const handleFileUpload =
|
|
25969
|
+
const handleFileUpload = useCallback28(
|
|
26125
25970
|
async (file) => {
|
|
26126
25971
|
if (!onUploadFile) return;
|
|
26127
25972
|
setIsUploading(true);
|
|
@@ -26142,7 +25987,7 @@ function MarkdownEditor({
|
|
|
26142
25987
|
},
|
|
26143
25988
|
[onUploadFile, insertTextAtCursor, onFileUploaded]
|
|
26144
25989
|
);
|
|
26145
|
-
const handleFileInputChange =
|
|
25990
|
+
const handleFileInputChange = useCallback28(
|
|
26146
25991
|
(e) => {
|
|
26147
25992
|
const file = e.target.files?.[0];
|
|
26148
25993
|
if (file) {
|
|
@@ -26152,7 +25997,7 @@ function MarkdownEditor({
|
|
|
26152
25997
|
},
|
|
26153
25998
|
[handleFileUpload]
|
|
26154
25999
|
);
|
|
26155
|
-
const handlePaste =
|
|
26000
|
+
const handlePaste = useCallback28(
|
|
26156
26001
|
(e) => {
|
|
26157
26002
|
if (!onUploadFile) return;
|
|
26158
26003
|
const items = e.clipboardData?.items;
|
|
@@ -26184,14 +26029,14 @@ function MarkdownEditor({
|
|
|
26184
26029
|
}
|
|
26185
26030
|
} : null;
|
|
26186
26031
|
const extraCommands = uploadCommand ? [...defaultExtraCommands, uploadCommand] : defaultExtraCommands;
|
|
26187
|
-
const wrapperRef =
|
|
26188
|
-
const isDraggingRef =
|
|
26189
|
-
const mouseYRef =
|
|
26190
|
-
const rafRef =
|
|
26191
|
-
const scrollParentRef =
|
|
26032
|
+
const wrapperRef = useRef35(null);
|
|
26033
|
+
const isDraggingRef = useRef35(false);
|
|
26034
|
+
const mouseYRef = useRef35(0);
|
|
26035
|
+
const rafRef = useRef35(0);
|
|
26036
|
+
const scrollParentRef = useRef35(window);
|
|
26192
26037
|
const EDGE_ZONE = 60;
|
|
26193
26038
|
const MAX_SCROLL_SPEED = 15;
|
|
26194
|
-
const findScrollParent =
|
|
26039
|
+
const findScrollParent = useCallback28((el) => {
|
|
26195
26040
|
let node = el?.parentElement;
|
|
26196
26041
|
while (node && node !== document.documentElement) {
|
|
26197
26042
|
const { overflowY } = window.getComputedStyle(node);
|
|
@@ -26202,7 +26047,7 @@ function MarkdownEditor({
|
|
|
26202
26047
|
}
|
|
26203
26048
|
return window;
|
|
26204
26049
|
}, []);
|
|
26205
|
-
const scrollLoop =
|
|
26050
|
+
const scrollLoop = useCallback28(() => {
|
|
26206
26051
|
if (!isDraggingRef.current) return;
|
|
26207
26052
|
const parent = scrollParentRef.current;
|
|
26208
26053
|
const isWindow = parent === window;
|
|
@@ -26218,7 +26063,7 @@ function MarkdownEditor({
|
|
|
26218
26063
|
}
|
|
26219
26064
|
rafRef.current = requestAnimationFrame(scrollLoop);
|
|
26220
26065
|
}, []);
|
|
26221
|
-
|
|
26066
|
+
useEffect39(() => {
|
|
26222
26067
|
const wrapper = wrapperRef.current;
|
|
26223
26068
|
if (!wrapper) return;
|
|
26224
26069
|
const onMouseMove = (e) => {
|
|
@@ -27500,12 +27345,12 @@ function ArrayEntryManager({
|
|
|
27500
27345
|
}) {
|
|
27501
27346
|
const [draftItems, setDraftItems] = useState58(items);
|
|
27502
27347
|
const [isDirty, setIsDirty] = useState58(false);
|
|
27503
|
-
|
|
27348
|
+
useEffect42(() => {
|
|
27504
27349
|
if (!isDirty && !isSaving) {
|
|
27505
27350
|
setDraftItems(items);
|
|
27506
27351
|
}
|
|
27507
27352
|
}, [items, isDirty, isSaving]);
|
|
27508
|
-
|
|
27353
|
+
useEffect42(() => {
|
|
27509
27354
|
if (onDirtyChange) {
|
|
27510
27355
|
onDirtyChange(isDirty);
|
|
27511
27356
|
}
|
|
@@ -27720,7 +27565,7 @@ function AuthProvidersList({
|
|
|
27720
27565
|
|
|
27721
27566
|
// src/components/features/changelog-manager.tsx
|
|
27722
27567
|
import { Trash2 as Trash23, Plus as Plus3, ChevronDown as ChevronDown7, ChevronUp as ChevronUp3, Eye, EyeOff } from "lucide-react";
|
|
27723
|
-
import { useState as useState60, useEffect as
|
|
27568
|
+
import { useState as useState60, useEffect as useEffect43 } from "react";
|
|
27724
27569
|
import { jsx as jsx247, jsxs as jsxs204 } from "react/jsx-runtime";
|
|
27725
27570
|
function ChangelogManager({
|
|
27726
27571
|
title,
|
|
@@ -27731,7 +27576,7 @@ function ChangelogManager({
|
|
|
27731
27576
|
showVisibilityToggle = false
|
|
27732
27577
|
}) {
|
|
27733
27578
|
const [expandedIndices, setExpandedIndices] = useState60(/* @__PURE__ */ new Set());
|
|
27734
|
-
|
|
27579
|
+
useEffect43(() => {
|
|
27735
27580
|
if (expandAll && entries.length > 0) {
|
|
27736
27581
|
setExpandedIndices(new Set(entries.map((_, i) => i)));
|
|
27737
27582
|
}
|
|
@@ -28043,7 +27888,7 @@ var ErrorBoundary = class extends Component {
|
|
|
28043
27888
|
|
|
28044
27889
|
// src/components/features/figma-prototype-viewer.tsx
|
|
28045
27890
|
init_cn();
|
|
28046
|
-
import { useState as useState61, useRef as
|
|
27891
|
+
import { useState as useState61, useRef as useRef38, useEffect as useEffect44, useCallback as useCallback30, useMemo as useMemo22 } from "react";
|
|
28047
27892
|
|
|
28048
27893
|
// src/components/features/section-selector.tsx
|
|
28049
27894
|
init_cn();
|
|
@@ -28412,10 +28257,10 @@ var FigmaPrototypeViewer = ({
|
|
|
28412
28257
|
}) => {
|
|
28413
28258
|
const clientId = process.env.NEXT_PUBLIC_FIGMA_CLIENT_ID || "UTQPwZHR9OZp68TTGPFFi5";
|
|
28414
28259
|
const showDebugPanel = process.env.NEXT_PUBLIC_FIGMA_DEBUG === "true";
|
|
28415
|
-
const iframeRef =
|
|
28416
|
-
const containerRef =
|
|
28417
|
-
const navTimerRef =
|
|
28418
|
-
const touchTimerRef =
|
|
28260
|
+
const iframeRef = useRef38(null);
|
|
28261
|
+
const containerRef = useRef38(null);
|
|
28262
|
+
const navTimerRef = useRef38(null);
|
|
28263
|
+
const touchTimerRef = useRef38(null);
|
|
28419
28264
|
const [screenWidth, setScreenWidth] = useState61(
|
|
28420
28265
|
typeof window !== "undefined" ? window.innerWidth : DESKTOP_BREAKPOINT
|
|
28421
28266
|
);
|
|
@@ -28481,7 +28326,7 @@ var FigmaPrototypeViewer = ({
|
|
|
28481
28326
|
embedUrl,
|
|
28482
28327
|
iframeKey
|
|
28483
28328
|
]);
|
|
28484
|
-
|
|
28329
|
+
useEffect44(() => {
|
|
28485
28330
|
const handleResize = () => {
|
|
28486
28331
|
const newWidth = window.innerWidth;
|
|
28487
28332
|
setScreenWidth(newWidth);
|
|
@@ -28495,7 +28340,7 @@ var FigmaPrototypeViewer = ({
|
|
|
28495
28340
|
return () => window.removeEventListener("resize", handleResize);
|
|
28496
28341
|
}, []);
|
|
28497
28342
|
const [lastViewMode, setLastViewMode] = useState61(viewMode);
|
|
28498
|
-
|
|
28343
|
+
useEffect44(() => {
|
|
28499
28344
|
if (lastViewMode !== viewMode && iframeState === "READY") {
|
|
28500
28345
|
console.log("[ViewMode Change]", lastViewMode, "\u2192", viewMode);
|
|
28501
28346
|
setIframeState("RELOADING");
|
|
@@ -28503,7 +28348,7 @@ var FigmaPrototypeViewer = ({
|
|
|
28503
28348
|
}
|
|
28504
28349
|
setLastViewMode(viewMode);
|
|
28505
28350
|
}, [viewMode, lastViewMode, iframeState]);
|
|
28506
|
-
|
|
28351
|
+
useEffect44(() => {
|
|
28507
28352
|
const handleVisibilityChange = () => {
|
|
28508
28353
|
if (document.visibilityState === "visible" && iframeState === "READY") {
|
|
28509
28354
|
console.log("[Sleep Recovery] Reloading iframe after sleep");
|
|
@@ -28514,7 +28359,7 @@ var FigmaPrototypeViewer = ({
|
|
|
28514
28359
|
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
28515
28360
|
return () => document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
28516
28361
|
}, [iframeState]);
|
|
28517
|
-
|
|
28362
|
+
useEffect44(() => {
|
|
28518
28363
|
const handleMessage = (event) => {
|
|
28519
28364
|
if (event.origin !== "https://www.figma.com") return;
|
|
28520
28365
|
const validEvents = ["INITIAL_LOAD", "NEW_STATE", "PRESENTED_NODE_CHANGED"];
|
|
@@ -28551,7 +28396,7 @@ var FigmaPrototypeViewer = ({
|
|
|
28551
28396
|
window.addEventListener("message", handleMessage);
|
|
28552
28397
|
return () => window.removeEventListener("message", handleMessage);
|
|
28553
28398
|
}, [config.sections, activeSection, isNavigating, externalActiveSection, config.onSectionChange, viewMode]);
|
|
28554
|
-
const navigateToSection =
|
|
28399
|
+
const navigateToSection = useCallback30((sectionId) => {
|
|
28555
28400
|
const section = config.sections.find((s) => s.id === sectionId);
|
|
28556
28401
|
if (!section || !iframeRef.current?.contentWindow || !isInitialized) {
|
|
28557
28402
|
return;
|
|
@@ -28575,7 +28420,7 @@ var FigmaPrototypeViewer = ({
|
|
|
28575
28420
|
if (navTimerRef.current) clearTimeout(navTimerRef.current);
|
|
28576
28421
|
navTimerRef.current = setTimeout(() => setIsNavigating(false), 500);
|
|
28577
28422
|
}, [config, isInitialized, viewMode, externalActiveSection]);
|
|
28578
|
-
const handleSectionClick =
|
|
28423
|
+
const handleSectionClick = useCallback30((sectionId) => {
|
|
28579
28424
|
const sectionsDisabled = iframeState !== "READY" || isNavigating;
|
|
28580
28425
|
if (sectionId === activeSection || sectionsDisabled) {
|
|
28581
28426
|
return;
|
|
@@ -28586,7 +28431,7 @@ var FigmaPrototypeViewer = ({
|
|
|
28586
28431
|
navigateToSection(sectionId);
|
|
28587
28432
|
}
|
|
28588
28433
|
}, [activeSection, iframeState, isNavigating, externalOnSectionClick, navigateToSection]);
|
|
28589
|
-
const handleTouchStart =
|
|
28434
|
+
const handleTouchStart = useCallback30((e) => {
|
|
28590
28435
|
const overlayElement = e.currentTarget;
|
|
28591
28436
|
console.log("[Touch] Touch detected, allowing iframe interaction");
|
|
28592
28437
|
overlayElement.style.pointerEvents = "none";
|
|
@@ -28598,12 +28443,12 @@ var FigmaPrototypeViewer = ({
|
|
|
28598
28443
|
}
|
|
28599
28444
|
}, 500);
|
|
28600
28445
|
}, []);
|
|
28601
|
-
|
|
28446
|
+
useEffect44(() => {
|
|
28602
28447
|
if (externalActiveSection && externalActiveSection !== activeSection && isInitialized) {
|
|
28603
28448
|
navigateToSection(externalActiveSection);
|
|
28604
28449
|
}
|
|
28605
28450
|
}, [externalActiveSection, activeSection, isInitialized, navigateToSection]);
|
|
28606
|
-
|
|
28451
|
+
useEffect44(() => {
|
|
28607
28452
|
return () => {
|
|
28608
28453
|
if (navTimerRef.current) clearTimeout(navTimerRef.current);
|
|
28609
28454
|
if (touchTimerRef.current) clearTimeout(touchTimerRef.current);
|
|
@@ -28706,7 +28551,7 @@ var FigmaPrototypeViewer = ({
|
|
|
28706
28551
|
|
|
28707
28552
|
// src/components/features/filters-dropdown.tsx
|
|
28708
28553
|
init_cn();
|
|
28709
|
-
import { useEffect as
|
|
28554
|
+
import { useEffect as useEffect45, useRef as useRef39, useState as useState62 } from "react";
|
|
28710
28555
|
import { jsx as jsx253, jsxs as jsxs209 } from "react/jsx-runtime";
|
|
28711
28556
|
var FilterCheckbox = ({ checked, disabled = false, className }) => {
|
|
28712
28557
|
return /* @__PURE__ */ jsx253(
|
|
@@ -28743,10 +28588,10 @@ var FiltersDropdown = ({
|
|
|
28743
28588
|
const [isVisible, setIsVisible] = useState62(false);
|
|
28744
28589
|
const [isMobile, setIsMobile] = useState62(false);
|
|
28745
28590
|
const [actualPlacement, setActualPlacement] = useState62(placement);
|
|
28746
|
-
const dropdownRef =
|
|
28747
|
-
const triggerRef =
|
|
28748
|
-
const containerRef =
|
|
28749
|
-
|
|
28591
|
+
const dropdownRef = useRef39(null);
|
|
28592
|
+
const triggerRef = useRef39(null);
|
|
28593
|
+
const containerRef = useRef39(null);
|
|
28594
|
+
useEffect45(() => {
|
|
28750
28595
|
if (isOpen) {
|
|
28751
28596
|
setShouldRender(true);
|
|
28752
28597
|
let id2 = 0;
|
|
@@ -28762,7 +28607,7 @@ var FiltersDropdown = ({
|
|
|
28762
28607
|
const t = setTimeout(() => setShouldRender(false), ANIMATION_MS);
|
|
28763
28608
|
return () => clearTimeout(t);
|
|
28764
28609
|
}, [isOpen]);
|
|
28765
|
-
|
|
28610
|
+
useEffect45(() => {
|
|
28766
28611
|
if (!responsive) {
|
|
28767
28612
|
setIsMobile(false);
|
|
28768
28613
|
return;
|
|
@@ -28774,7 +28619,7 @@ var FiltersDropdown = ({
|
|
|
28774
28619
|
window.addEventListener("resize", checkMobile);
|
|
28775
28620
|
return () => window.removeEventListener("resize", checkMobile);
|
|
28776
28621
|
}, [responsive]);
|
|
28777
|
-
|
|
28622
|
+
useEffect45(() => {
|
|
28778
28623
|
if (!isOpen || isMobile || !triggerRef.current) return;
|
|
28779
28624
|
const calculateOptimalPlacement = () => {
|
|
28780
28625
|
const trigger = triggerRef.current;
|
|
@@ -28811,12 +28656,12 @@ var FiltersDropdown = ({
|
|
|
28811
28656
|
return initial;
|
|
28812
28657
|
});
|
|
28813
28658
|
const currentFiltersStr = currentFilters ? JSON.stringify(currentFilters) : "";
|
|
28814
|
-
|
|
28659
|
+
useEffect45(() => {
|
|
28815
28660
|
if (currentFilters) {
|
|
28816
28661
|
setSelectedFilters({ ...currentFilters });
|
|
28817
28662
|
}
|
|
28818
28663
|
}, [currentFiltersStr]);
|
|
28819
|
-
|
|
28664
|
+
useEffect45(() => {
|
|
28820
28665
|
const handleClickOutside = (event) => {
|
|
28821
28666
|
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
28822
28667
|
setIsOpen(false);
|
|
@@ -28833,7 +28678,7 @@ var FiltersDropdown = ({
|
|
|
28833
28678
|
};
|
|
28834
28679
|
}
|
|
28835
28680
|
}, [isOpen, placement]);
|
|
28836
|
-
|
|
28681
|
+
useEffect45(() => {
|
|
28837
28682
|
const handleEscape = (e) => {
|
|
28838
28683
|
if (e.key === "Escape" && isOpen) {
|
|
28839
28684
|
setIsOpen(false);
|
|
@@ -29099,13 +28944,13 @@ function KnowledgeBaseLinksManager({
|
|
|
29099
28944
|
}
|
|
29100
28945
|
|
|
29101
28946
|
// src/components/features/loading-provider.tsx
|
|
29102
|
-
import { createContext as createContext7, useContext as useContext7, useState as useState63, useEffect as
|
|
28947
|
+
import { createContext as createContext7, useContext as useContext7, useState as useState63, useEffect as useEffect46 } from "react";
|
|
29103
28948
|
import { jsx as jsx256, jsxs as jsxs210 } from "react/jsx-runtime";
|
|
29104
28949
|
var LoadingContext = createContext7(void 0);
|
|
29105
28950
|
function LoadingProvider({ children }) {
|
|
29106
28951
|
const [isLoading, setIsLoading] = useState63(false);
|
|
29107
28952
|
const [progress, setProgress] = useState63(0);
|
|
29108
|
-
|
|
28953
|
+
useEffect46(() => {
|
|
29109
28954
|
let interval;
|
|
29110
28955
|
if (isLoading) {
|
|
29111
28956
|
setProgress(10);
|
|
@@ -29150,7 +28995,7 @@ function useLoading() {
|
|
|
29150
28995
|
}
|
|
29151
28996
|
|
|
29152
28997
|
// src/components/features/media-gallery-manager.tsx
|
|
29153
|
-
import { useState as useState64, useRef as
|
|
28998
|
+
import { useState as useState64, useRef as useRef40, useCallback as useCallback31 } from "react";
|
|
29154
28999
|
import {
|
|
29155
29000
|
Upload as Upload3,
|
|
29156
29001
|
Image as ImageIcon2,
|
|
@@ -29171,10 +29016,10 @@ function MediaGalleryManager({
|
|
|
29171
29016
|
modalTitle = "Media Gallery",
|
|
29172
29017
|
className = ""
|
|
29173
29018
|
}) {
|
|
29174
|
-
const fileInputRef =
|
|
29019
|
+
const fileInputRef = useRef40(null);
|
|
29175
29020
|
const [deletingIndex, setDeletingIndex] = useState64(null);
|
|
29176
29021
|
const [draggedIndex, setDraggedIndex] = useState64(null);
|
|
29177
|
-
const handleFileSelect =
|
|
29022
|
+
const handleFileSelect = useCallback31(async (event) => {
|
|
29178
29023
|
const file = event.target.files?.[0];
|
|
29179
29024
|
if (!file) return;
|
|
29180
29025
|
let mediaType;
|
|
@@ -29200,18 +29045,18 @@ function MediaGalleryManager({
|
|
|
29200
29045
|
console.error("Upload failed:", error);
|
|
29201
29046
|
}
|
|
29202
29047
|
}, [media, onChange, onUpload]);
|
|
29203
|
-
const handleDeleteMedia =
|
|
29048
|
+
const handleDeleteMedia = useCallback31((index) => {
|
|
29204
29049
|
setDeletingIndex(index);
|
|
29205
29050
|
onChange(media.filter((_, i) => i !== index));
|
|
29206
29051
|
setDeletingIndex(null);
|
|
29207
29052
|
}, [media, onChange]);
|
|
29208
|
-
const handleDragStart =
|
|
29053
|
+
const handleDragStart = useCallback31((index) => {
|
|
29209
29054
|
setDraggedIndex(index);
|
|
29210
29055
|
}, []);
|
|
29211
|
-
const handleDragOver =
|
|
29056
|
+
const handleDragOver = useCallback31((e) => {
|
|
29212
29057
|
e.preventDefault();
|
|
29213
29058
|
}, []);
|
|
29214
|
-
const handleDrop =
|
|
29059
|
+
const handleDrop = useCallback31((e, targetIndex) => {
|
|
29215
29060
|
e.preventDefault();
|
|
29216
29061
|
if (draggedIndex === null || draggedIndex === targetIndex) {
|
|
29217
29062
|
setDraggedIndex(null);
|
|
@@ -29223,7 +29068,7 @@ function MediaGalleryManager({
|
|
|
29223
29068
|
onChange(newMedia.map((item, i) => ({ ...item, display_order: i })));
|
|
29224
29069
|
setDraggedIndex(null);
|
|
29225
29070
|
}, [media, draggedIndex, onChange]);
|
|
29226
|
-
const renderMediaItem =
|
|
29071
|
+
const renderMediaItem = useCallback31((mediaItem, index) => {
|
|
29227
29072
|
const isDeleting = deletingIndex === index;
|
|
29228
29073
|
return /* @__PURE__ */ jsxs211(
|
|
29229
29074
|
Card,
|
|
@@ -29383,7 +29228,7 @@ function OSTypeBadgeGroup({
|
|
|
29383
29228
|
}
|
|
29384
29229
|
|
|
29385
29230
|
// src/components/features/parallax-image-showcase.tsx
|
|
29386
|
-
import { useEffect as
|
|
29231
|
+
import { useEffect as useEffect47, useState as useState65, useRef as useRef41 } from "react";
|
|
29387
29232
|
import Image12 from "next/image";
|
|
29388
29233
|
import { motion as motion2, useScroll, useTransform, useMotionValue, useSpring } from "framer-motion";
|
|
29389
29234
|
import { jsx as jsx260, jsxs as jsxs213 } from "react/jsx-runtime";
|
|
@@ -29403,8 +29248,8 @@ var ParallaxImageShowcase = ({
|
|
|
29403
29248
|
const mouseXSpring = useSpring(mouseX, springConfig);
|
|
29404
29249
|
const mouseYSpring = useSpring(mouseY, springConfig);
|
|
29405
29250
|
const [componentRect, setComponentRect] = useState65(null);
|
|
29406
|
-
const componentRef =
|
|
29407
|
-
|
|
29251
|
+
const componentRef = useRef41(null);
|
|
29252
|
+
useEffect47(() => {
|
|
29408
29253
|
const updateRect = () => {
|
|
29409
29254
|
if (componentRef.current) {
|
|
29410
29255
|
setComponentRect(componentRef.current.getBoundingClientRect());
|
|
@@ -29418,7 +29263,7 @@ var ParallaxImageShowcase = ({
|
|
|
29418
29263
|
window.removeEventListener("scroll", updateRect);
|
|
29419
29264
|
};
|
|
29420
29265
|
}, []);
|
|
29421
|
-
|
|
29266
|
+
useEffect47(() => {
|
|
29422
29267
|
const handleGlobalMouseMove = (e) => {
|
|
29423
29268
|
if (!componentRect) return;
|
|
29424
29269
|
const centerX = componentRect.left + componentRect.width / 2;
|
|
@@ -30062,7 +29907,7 @@ function PushButtonSelector({
|
|
|
30062
29907
|
}
|
|
30063
29908
|
|
|
30064
29909
|
// src/components/features/release-media-manager.tsx
|
|
30065
|
-
import { useState as useState66, useRef as
|
|
29910
|
+
import { useState as useState66, useRef as useRef42 } from "react";
|
|
30066
29911
|
import { Trash2 as Trash25, Plus as Plus5, Image as ImageIcon3, Video as Video4, Upload as Upload4, Loader2 as Loader28, GripVertical as GripVertical2 } from "lucide-react";
|
|
30067
29912
|
import Image13 from "next/image";
|
|
30068
29913
|
import { jsx as jsx265, jsxs as jsxs218 } from "react/jsx-runtime";
|
|
@@ -30072,7 +29917,7 @@ function ReleaseMediaManager({
|
|
|
30072
29917
|
onUpload,
|
|
30073
29918
|
className = ""
|
|
30074
29919
|
}) {
|
|
30075
|
-
const fileInputRef =
|
|
29920
|
+
const fileInputRef = useRef42(null);
|
|
30076
29921
|
const [uploadingIndex, setUploadingIndex] = useState66(null);
|
|
30077
29922
|
const handleFileSelect = async (event) => {
|
|
30078
29923
|
const file = event.target.files?.[0];
|
|
@@ -30986,7 +30831,7 @@ function TagsSelector({
|
|
|
30986
30831
|
|
|
30987
30832
|
// src/components/features/video-source-selector.tsx
|
|
30988
30833
|
init_button2();
|
|
30989
|
-
import { useState as useState69, useCallback as
|
|
30834
|
+
import { useState as useState69, useCallback as useCallback32 } from "react";
|
|
30990
30835
|
import { Upload as Upload6, Sparkles as Sparkles3, X as X13, Video as Video5 } from "lucide-react";
|
|
30991
30836
|
import { jsx as jsx272, jsxs as jsxs224 } from "react/jsx-runtime";
|
|
30992
30837
|
function VideoSourceSelector({
|
|
@@ -31015,7 +30860,7 @@ function VideoSourceSelector({
|
|
|
31015
30860
|
const [uploadProgress, setUploadProgress] = useState69(0);
|
|
31016
30861
|
const [uploadMessage, setUploadMessage] = useState69("");
|
|
31017
30862
|
const [uploadError, setUploadError] = useState69(null);
|
|
31018
|
-
const handleUploadClick =
|
|
30863
|
+
const handleUploadClick = useCallback32(() => {
|
|
31019
30864
|
const input = document.createElement("input");
|
|
31020
30865
|
input.type = "file";
|
|
31021
30866
|
input.accept = "video/*";
|
|
@@ -31046,7 +30891,7 @@ function VideoSourceSelector({
|
|
|
31046
30891
|
};
|
|
31047
30892
|
input.click();
|
|
31048
30893
|
}, [onUploadVideo, onUploadedVideoUrlChange]);
|
|
31049
|
-
const handleDeleteVideo =
|
|
30894
|
+
const handleDeleteVideo = useCallback32(() => {
|
|
31050
30895
|
onUploadedVideoUrlChange("");
|
|
31051
30896
|
}, [onUploadedVideoUrlChange]);
|
|
31052
30897
|
return /* @__PURE__ */ jsxs224("div", { className: `space-y-4 p-6 bg-ods-card border border-ods-border rounded-lg ${className}`, children: [
|
|
@@ -32508,7 +32353,7 @@ function ViewToggle({
|
|
|
32508
32353
|
|
|
32509
32354
|
// src/components/features/policy-configuration-panel.tsx
|
|
32510
32355
|
init_cn();
|
|
32511
|
-
import { useRef as
|
|
32356
|
+
import { useRef as useRef43, useEffect as useEffect48, useState as useState71 } from "react";
|
|
32512
32357
|
import { ChevronDown as ChevronDown8 } from "lucide-react";
|
|
32513
32358
|
init_button2();
|
|
32514
32359
|
|
|
@@ -32690,8 +32535,8 @@ var PolicyRow = ({ policy, categoryId, editMode, onPermissionChange }) => {
|
|
|
32690
32535
|
};
|
|
32691
32536
|
var useAnimatedHeight = (isExpanded) => {
|
|
32692
32537
|
const [height, setHeight] = useState71(0);
|
|
32693
|
-
const contentRef =
|
|
32694
|
-
|
|
32538
|
+
const contentRef = useRef43(null);
|
|
32539
|
+
useEffect48(() => {
|
|
32695
32540
|
if (contentRef.current) {
|
|
32696
32541
|
const contentHeight = contentRef.current.scrollHeight;
|
|
32697
32542
|
setHeight(isExpanded ? contentHeight : 0);
|
|
@@ -32847,7 +32692,7 @@ PolicyConfigurationPanel.displayName = "PolicyConfigurationPanel";
|
|
|
32847
32692
|
init_button2();
|
|
32848
32693
|
init_cn();
|
|
32849
32694
|
import { getCountries as getCountries2 } from "libphonenumber-js";
|
|
32850
|
-
import { useEffect as
|
|
32695
|
+
import { useEffect as useEffect49, useState as useState72 } from "react";
|
|
32851
32696
|
import { Fragment as Fragment41, jsx as jsx292, jsxs as jsxs240 } from "react/jsx-runtime";
|
|
32852
32697
|
function WaitlistForm({
|
|
32853
32698
|
id = "waitlist-form",
|
|
@@ -32876,12 +32721,12 @@ function WaitlistForm({
|
|
|
32876
32721
|
const [isPhoneInvalid, setIsPhoneInvalid] = useState72(false);
|
|
32877
32722
|
const [showConsentError, setShowConsentError] = useState72(false);
|
|
32878
32723
|
const isMailDomainGeneric = hasGenericEmailDomain(email);
|
|
32879
|
-
|
|
32724
|
+
useEffect49(() => {
|
|
32880
32725
|
if (defaultEmail) {
|
|
32881
32726
|
setEmail(defaultEmail);
|
|
32882
32727
|
}
|
|
32883
32728
|
}, [defaultEmail]);
|
|
32884
|
-
|
|
32729
|
+
useEffect49(() => {
|
|
32885
32730
|
setIsClient(true);
|
|
32886
32731
|
if (!geoApiUrl) return;
|
|
32887
32732
|
const supportedCountries = new Set(getCountries2());
|
|
@@ -33454,7 +33299,7 @@ function EmptyState3() {
|
|
|
33454
33299
|
}
|
|
33455
33300
|
|
|
33456
33301
|
// src/components/features/board/use-board-collapse.ts
|
|
33457
|
-
import { useCallback as
|
|
33302
|
+
import { useCallback as useCallback34, useState as useState73 } from "react";
|
|
33458
33303
|
function useBoardCollapse(storageKey) {
|
|
33459
33304
|
const [persisted, setPersisted] = useLocalStorage(
|
|
33460
33305
|
storageKey ?? "__board_collapse_unused__",
|
|
@@ -33463,13 +33308,13 @@ function useBoardCollapse(storageKey) {
|
|
|
33463
33308
|
const [memory, setMemory] = useState73({});
|
|
33464
33309
|
const collapsed = storageKey ? persisted : memory;
|
|
33465
33310
|
const setMap = storageKey ? setPersisted : setMemory;
|
|
33466
|
-
const toggle =
|
|
33311
|
+
const toggle = useCallback34(
|
|
33467
33312
|
(columnId) => {
|
|
33468
33313
|
setMap((prev) => ({ ...prev, [columnId]: !prev[columnId] }));
|
|
33469
33314
|
},
|
|
33470
33315
|
[setMap]
|
|
33471
33316
|
);
|
|
33472
|
-
const setCollapsed =
|
|
33317
|
+
const setCollapsed = useCallback34(
|
|
33473
33318
|
(columnId, value) => {
|
|
33474
33319
|
setMap((prev) => ({ ...prev, [columnId]: value }));
|
|
33475
33320
|
},
|
|
@@ -33947,7 +33792,6 @@ export {
|
|
|
33947
33792
|
ViewToggle,
|
|
33948
33793
|
YouTubeEmbed,
|
|
33949
33794
|
extractYouTubeId,
|
|
33950
|
-
YouTubeLinkParser,
|
|
33951
33795
|
PolicyConfigurationPanel,
|
|
33952
33796
|
PhoneInput,
|
|
33953
33797
|
WaitlistForm,
|
|
@@ -34342,4 +34186,4 @@ export {
|
|
|
34342
34186
|
TMCG_SOCIAL_PLATFORMS,
|
|
34343
34187
|
assets
|
|
34344
34188
|
};
|
|
34345
|
-
//# sourceMappingURL=chunk-
|
|
34189
|
+
//# sourceMappingURL=chunk-AAX27BCR.js.map
|