@bendyline/squisq-react 2.7.1 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +1 -1
- package/THIRD_PARTY_LICENSES.txt +2 -2
- package/dist/{chunk-KXYE4AGL.js → chunk-LAL43UUN.js} +485 -170
- package/dist/index.d.ts +51 -6
- package/dist/index.js +3 -1
- package/dist/player/index.d.ts +14 -3
- package/dist/player/index.js +1 -1
- package/dist/squisq-player.full.global.js +434 -432
- package/dist/squisq-player.global.js +63 -61
- package/dist/standalone-source.js +1 -1
- package/package.json +3 -3
|
@@ -1242,10 +1242,282 @@ function DocControlsSlideshow({
|
|
|
1242
1242
|
);
|
|
1243
1243
|
}
|
|
1244
1244
|
|
|
1245
|
+
// src/DashboardView.tsx
|
|
1246
|
+
import { Fragment as Fragment2, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef4 } from "react";
|
|
1247
|
+
import { materializeDashboard, resolveThemeForDoc, VIEWPORT_PRESETS } from "@bendyline/squisq/doc";
|
|
1248
|
+
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1249
|
+
async function waitForDashboardAssets(root) {
|
|
1250
|
+
if (typeof document !== "undefined" && document.fonts?.ready) {
|
|
1251
|
+
try {
|
|
1252
|
+
await document.fonts.ready;
|
|
1253
|
+
} catch {
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
const images = Array.from(root.querySelectorAll("img"));
|
|
1257
|
+
await Promise.allSettled(
|
|
1258
|
+
images.map((img) => {
|
|
1259
|
+
if (img.complete) return Promise.resolve();
|
|
1260
|
+
if (typeof img.decode === "function") return img.decode().catch(() => void 0);
|
|
1261
|
+
return new Promise((resolve) => {
|
|
1262
|
+
img.addEventListener("load", () => resolve(), { once: true });
|
|
1263
|
+
img.addEventListener("error", () => resolve(), { once: true });
|
|
1264
|
+
});
|
|
1265
|
+
})
|
|
1266
|
+
);
|
|
1267
|
+
await new Promise((resolve) => {
|
|
1268
|
+
if (typeof requestAnimationFrame === "function") {
|
|
1269
|
+
requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
|
|
1270
|
+
} else {
|
|
1271
|
+
setTimeout(resolve, 0);
|
|
1272
|
+
}
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
function syntheticBlock(id, layers) {
|
|
1276
|
+
return { id, startTime: 0, duration: 0, audioSegment: 0, layers };
|
|
1277
|
+
}
|
|
1278
|
+
function DashboardView({
|
|
1279
|
+
doc,
|
|
1280
|
+
theme,
|
|
1281
|
+
viewport,
|
|
1282
|
+
layout,
|
|
1283
|
+
showTitle,
|
|
1284
|
+
style,
|
|
1285
|
+
documentTitle,
|
|
1286
|
+
basePath = ".",
|
|
1287
|
+
animationsEnabled = true,
|
|
1288
|
+
muted = true,
|
|
1289
|
+
renderMode = false,
|
|
1290
|
+
onRenderAPIReady,
|
|
1291
|
+
className
|
|
1292
|
+
}) {
|
|
1293
|
+
const rootRef = useRef4(null);
|
|
1294
|
+
const activeTheme = useMemo3(() => theme ?? resolveThemeForDoc(doc), [theme, doc]);
|
|
1295
|
+
const activeViewport = viewport ?? VIEWPORT_PRESETS.landscape;
|
|
1296
|
+
const materialization = useMemo3(
|
|
1297
|
+
() => materializeDashboard(doc, {
|
|
1298
|
+
theme: activeTheme,
|
|
1299
|
+
viewport: activeViewport,
|
|
1300
|
+
layout,
|
|
1301
|
+
showTitle,
|
|
1302
|
+
style,
|
|
1303
|
+
documentTitle
|
|
1304
|
+
}),
|
|
1305
|
+
[doc, activeTheme, activeViewport, layout, showTitle, style, documentTitle]
|
|
1306
|
+
);
|
|
1307
|
+
const backdropBottom = useMemo3(
|
|
1308
|
+
() => syntheticBlock("dashboard-backdrop-bottom", materialization.backdrop.bottomLayers),
|
|
1309
|
+
[materialization]
|
|
1310
|
+
);
|
|
1311
|
+
const backdropTop = useMemo3(
|
|
1312
|
+
() => materialization.backdrop.topLayers.length > 0 ? syntheticBlock("dashboard-backdrop-top", materialization.backdrop.topLayers) : null,
|
|
1313
|
+
[materialization]
|
|
1314
|
+
);
|
|
1315
|
+
const titleBlock = useMemo3(
|
|
1316
|
+
() => materialization.title ? syntheticBlock("dashboard-title-band", materialization.title.layers) : null,
|
|
1317
|
+
[materialization]
|
|
1318
|
+
);
|
|
1319
|
+
useEffect4(() => {
|
|
1320
|
+
if (!renderMode || !onRenderAPIReady) return;
|
|
1321
|
+
const api = {
|
|
1322
|
+
seekTo: async () => {
|
|
1323
|
+
const root = rootRef.current;
|
|
1324
|
+
if (root) await waitForDashboardAssets(root);
|
|
1325
|
+
},
|
|
1326
|
+
getRenderedTime: () => 0,
|
|
1327
|
+
getDuration: () => 0,
|
|
1328
|
+
getBlocks: () => materialization.cells.map((cell) => ({
|
|
1329
|
+
id: String(cell.block.id),
|
|
1330
|
+
template: cell.block.template ?? "content",
|
|
1331
|
+
startTime: 0,
|
|
1332
|
+
duration: 0
|
|
1333
|
+
})),
|
|
1334
|
+
getAudioSegments: () => [],
|
|
1335
|
+
getCaptions: () => [],
|
|
1336
|
+
getChapters: () => [],
|
|
1337
|
+
showCover: async () => {
|
|
1338
|
+
},
|
|
1339
|
+
hideCover: async () => {
|
|
1340
|
+
},
|
|
1341
|
+
hasCoverBlock: () => false
|
|
1342
|
+
};
|
|
1343
|
+
onRenderAPIReady(api);
|
|
1344
|
+
return () => onRenderAPIReady(null);
|
|
1345
|
+
}, [renderMode, onRenderAPIReady, materialization]);
|
|
1346
|
+
const canvasDimensions = { width: activeViewport.width, height: activeViewport.height };
|
|
1347
|
+
const coverStyle = { position: "absolute", inset: 0 };
|
|
1348
|
+
const canvasStyle = {
|
|
1349
|
+
position: "relative",
|
|
1350
|
+
width: "var(--squisq-dashboard-fit-width, 100%)",
|
|
1351
|
+
aspectRatio: `${activeViewport.width} / ${activeViewport.height}`,
|
|
1352
|
+
overflow: "hidden",
|
|
1353
|
+
// The style variant owns the canvas fill: card styles tint it away
|
|
1354
|
+
// from the card surface so cards read as raised.
|
|
1355
|
+
background: materialization.backdrop.fill,
|
|
1356
|
+
margin: "0 auto",
|
|
1357
|
+
"--squisq-dashboard-aspect": (activeViewport.width / activeViewport.height).toFixed(6)
|
|
1358
|
+
};
|
|
1359
|
+
return /* @__PURE__ */ jsxs4(
|
|
1360
|
+
"div",
|
|
1361
|
+
{
|
|
1362
|
+
ref: rootRef,
|
|
1363
|
+
className: className ? `squisq-dashboard ${className}` : "squisq-dashboard",
|
|
1364
|
+
"data-dashboard-layout": materialization.layout.name,
|
|
1365
|
+
"data-dashboard-style": materialization.style,
|
|
1366
|
+
style: canvasStyle,
|
|
1367
|
+
children: [
|
|
1368
|
+
/* @__PURE__ */ jsx7("div", { style: coverStyle, "aria-hidden": "true", children: /* @__PURE__ */ jsx7(
|
|
1369
|
+
BlockRenderer,
|
|
1370
|
+
{
|
|
1371
|
+
block: backdropBottom,
|
|
1372
|
+
blockTime: 0,
|
|
1373
|
+
basePath,
|
|
1374
|
+
viewport: canvasDimensions,
|
|
1375
|
+
isPlaying: false,
|
|
1376
|
+
muted: true,
|
|
1377
|
+
animationsEnabled,
|
|
1378
|
+
theme: activeTheme
|
|
1379
|
+
}
|
|
1380
|
+
) }),
|
|
1381
|
+
materialization.cells.map((cell) => /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1382
|
+
cell.frame && /* @__PURE__ */ jsx7(
|
|
1383
|
+
"div",
|
|
1384
|
+
{
|
|
1385
|
+
className: "squisq-dashboard__frame",
|
|
1386
|
+
"data-cell-index": cell.index,
|
|
1387
|
+
"aria-hidden": "true",
|
|
1388
|
+
style: {
|
|
1389
|
+
position: "absolute",
|
|
1390
|
+
left: cell.frame.rectPct.left,
|
|
1391
|
+
top: cell.frame.rectPct.top,
|
|
1392
|
+
width: cell.frame.rectPct.width,
|
|
1393
|
+
height: cell.frame.rectPct.height,
|
|
1394
|
+
pointerEvents: "none"
|
|
1395
|
+
},
|
|
1396
|
+
children: /* @__PURE__ */ jsx7(
|
|
1397
|
+
BlockRenderer,
|
|
1398
|
+
{
|
|
1399
|
+
block: syntheticBlock(`dashboard-frame-${cell.index}`, cell.frame.layers),
|
|
1400
|
+
blockTime: 0,
|
|
1401
|
+
basePath,
|
|
1402
|
+
viewport: {
|
|
1403
|
+
width: cell.frame.viewport.width,
|
|
1404
|
+
height: cell.frame.viewport.height
|
|
1405
|
+
},
|
|
1406
|
+
isPlaying: false,
|
|
1407
|
+
muted: true,
|
|
1408
|
+
animationsEnabled,
|
|
1409
|
+
theme: activeTheme
|
|
1410
|
+
}
|
|
1411
|
+
)
|
|
1412
|
+
}
|
|
1413
|
+
),
|
|
1414
|
+
/* @__PURE__ */ jsxs4(
|
|
1415
|
+
"div",
|
|
1416
|
+
{
|
|
1417
|
+
className: "squisq-dashboard__cell",
|
|
1418
|
+
"data-cell-index": cell.index,
|
|
1419
|
+
style: {
|
|
1420
|
+
position: "absolute",
|
|
1421
|
+
left: cell.rectPct.left,
|
|
1422
|
+
top: cell.rectPct.top,
|
|
1423
|
+
width: cell.rectPct.width,
|
|
1424
|
+
height: cell.rectPct.height,
|
|
1425
|
+
// Percentage radii scale with the rendered canvas, so a card
|
|
1426
|
+
// cell's full-bleed art stays clipped to its corners at any
|
|
1427
|
+
// export resolution.
|
|
1428
|
+
...cell.frame?.contentRadiusPct ? { borderRadius: cell.frame.contentRadiusPct, overflow: "hidden" } : {}
|
|
1429
|
+
},
|
|
1430
|
+
children: [
|
|
1431
|
+
/* @__PURE__ */ jsx7(
|
|
1432
|
+
BlockRenderer,
|
|
1433
|
+
{
|
|
1434
|
+
block: { ...cell.block, layers: cell.layers },
|
|
1435
|
+
blockTime: 0,
|
|
1436
|
+
basePath,
|
|
1437
|
+
viewport: { width: cell.viewport.width, height: cell.viewport.height },
|
|
1438
|
+
isPlaying: false,
|
|
1439
|
+
muted,
|
|
1440
|
+
animationsEnabled,
|
|
1441
|
+
theme: activeTheme
|
|
1442
|
+
}
|
|
1443
|
+
),
|
|
1444
|
+
cell.frame && cell.frame.overlayLayers.length > 0 && // Borders and accents ride above the block: a template that
|
|
1445
|
+
// paints its own opaque surface would bury them. Same box, so
|
|
1446
|
+
// the cell's clip rounds them to the card's corners.
|
|
1447
|
+
/* @__PURE__ */ jsx7("div", { style: { position: "absolute", inset: 0, pointerEvents: "none" }, children: /* @__PURE__ */ jsx7(
|
|
1448
|
+
BlockRenderer,
|
|
1449
|
+
{
|
|
1450
|
+
block: syntheticBlock(
|
|
1451
|
+
`dashboard-frame-overlay-${cell.index}`,
|
|
1452
|
+
cell.frame.overlayLayers
|
|
1453
|
+
),
|
|
1454
|
+
blockTime: 0,
|
|
1455
|
+
basePath,
|
|
1456
|
+
viewport: {
|
|
1457
|
+
width: cell.frame.overlayViewport.width,
|
|
1458
|
+
height: cell.frame.overlayViewport.height
|
|
1459
|
+
},
|
|
1460
|
+
isPlaying: false,
|
|
1461
|
+
muted: true,
|
|
1462
|
+
animationsEnabled,
|
|
1463
|
+
theme: activeTheme
|
|
1464
|
+
}
|
|
1465
|
+
) })
|
|
1466
|
+
]
|
|
1467
|
+
}
|
|
1468
|
+
)
|
|
1469
|
+
] }, `${cell.index}-${cell.block.id}`)),
|
|
1470
|
+
materialization.title && titleBlock && /* @__PURE__ */ jsx7(
|
|
1471
|
+
"div",
|
|
1472
|
+
{
|
|
1473
|
+
className: "squisq-dashboard__title",
|
|
1474
|
+
style: {
|
|
1475
|
+
position: "absolute",
|
|
1476
|
+
left: materialization.title.rectPct.left,
|
|
1477
|
+
top: materialization.title.rectPct.top,
|
|
1478
|
+
width: materialization.title.rectPct.width,
|
|
1479
|
+
height: materialization.title.rectPct.height
|
|
1480
|
+
},
|
|
1481
|
+
children: /* @__PURE__ */ jsx7(
|
|
1482
|
+
BlockRenderer,
|
|
1483
|
+
{
|
|
1484
|
+
block: titleBlock,
|
|
1485
|
+
blockTime: 0,
|
|
1486
|
+
basePath,
|
|
1487
|
+
viewport: {
|
|
1488
|
+
width: materialization.title.viewport.width,
|
|
1489
|
+
height: materialization.title.viewport.height
|
|
1490
|
+
},
|
|
1491
|
+
isPlaying: false,
|
|
1492
|
+
muted: true,
|
|
1493
|
+
animationsEnabled,
|
|
1494
|
+
theme: activeTheme
|
|
1495
|
+
}
|
|
1496
|
+
)
|
|
1497
|
+
}
|
|
1498
|
+
),
|
|
1499
|
+
backdropTop && /* @__PURE__ */ jsx7("div", { style: { ...coverStyle, pointerEvents: "none" }, "aria-hidden": "true", children: /* @__PURE__ */ jsx7(
|
|
1500
|
+
BlockRenderer,
|
|
1501
|
+
{
|
|
1502
|
+
block: backdropTop,
|
|
1503
|
+
blockTime: 0,
|
|
1504
|
+
basePath,
|
|
1505
|
+
viewport: canvasDimensions,
|
|
1506
|
+
isPlaying: false,
|
|
1507
|
+
muted: true,
|
|
1508
|
+
animationsEnabled,
|
|
1509
|
+
theme: activeTheme
|
|
1510
|
+
}
|
|
1511
|
+
) })
|
|
1512
|
+
]
|
|
1513
|
+
}
|
|
1514
|
+
);
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1245
1517
|
// src/docPlayer/playerAppearance.ts
|
|
1246
1518
|
import {
|
|
1247
1519
|
resolveCoverSlideSettings,
|
|
1248
|
-
resolveThemeForDoc
|
|
1520
|
+
resolveThemeForDoc as resolveThemeForDoc2
|
|
1249
1521
|
} from "@bendyline/squisq/doc";
|
|
1250
1522
|
function readFrontmatterSetting(frontmatter, canonical, legacy) {
|
|
1251
1523
|
if (!frontmatter) return void 0;
|
|
@@ -1303,7 +1575,7 @@ function resolveDocPlayerAppearance(doc, overrides = {}) {
|
|
|
1303
1575
|
...overrides.coverSlidePlayback !== void 0 ? { playback: overrides.coverSlidePlayback } : {}
|
|
1304
1576
|
});
|
|
1305
1577
|
return {
|
|
1306
|
-
theme: overrides.theme ??
|
|
1578
|
+
theme: overrides.theme ?? resolveThemeForDoc2(doc),
|
|
1307
1579
|
videoPresentation: overrides.videoPresentation ?? resolveVideoPresentation(
|
|
1308
1580
|
readFrontmatterSetting(frontmatter, "squisq-video-presentation", "video-presentation")
|
|
1309
1581
|
) ?? "background",
|
|
@@ -1321,14 +1593,14 @@ function resolveDocPlayerAppearance(doc, overrides = {}) {
|
|
|
1321
1593
|
|
|
1322
1594
|
// src/DocPlayer.tsx
|
|
1323
1595
|
import {
|
|
1324
|
-
Fragment as
|
|
1596
|
+
Fragment as Fragment3,
|
|
1325
1597
|
useId as useId2,
|
|
1326
|
-
useRef as
|
|
1598
|
+
useRef as useRef6,
|
|
1327
1599
|
useState as useState5,
|
|
1328
|
-
useEffect as
|
|
1600
|
+
useEffect as useEffect6,
|
|
1329
1601
|
useLayoutEffect as useLayoutEffect2,
|
|
1330
1602
|
useCallback as useCallback4,
|
|
1331
|
-
useMemo as
|
|
1603
|
+
useMemo as useMemo4
|
|
1332
1604
|
} from "react";
|
|
1333
1605
|
import { flushSync } from "react-dom";
|
|
1334
1606
|
import {
|
|
@@ -1340,7 +1612,7 @@ import {
|
|
|
1340
1612
|
import { applySurface, pipStyleVars } from "@bendyline/squisq/schemas";
|
|
1341
1613
|
|
|
1342
1614
|
// src/hooks/useSlideSwipe.ts
|
|
1343
|
-
import { useCallback as useCallback3, useEffect as
|
|
1615
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef5, useState as useState4 } from "react";
|
|
1344
1616
|
var DISTANCE_RATIO = 0.3;
|
|
1345
1617
|
var FLICK_VELOCITY = 0.5;
|
|
1346
1618
|
var MIN_FLICK_DISTANCE = 12;
|
|
@@ -1366,13 +1638,13 @@ function useSlideSwipe(opts) {
|
|
|
1366
1638
|
const settleMs = opts.settleMs ?? DEFAULT_SETTLE_MS;
|
|
1367
1639
|
const [offsetPx, setOffsetPx] = useState4(0);
|
|
1368
1640
|
const [phase, setPhase] = useState4("idle");
|
|
1369
|
-
const optsRef =
|
|
1641
|
+
const optsRef = useRef5(opts);
|
|
1370
1642
|
optsRef.current = opts;
|
|
1371
|
-
const dragRef =
|
|
1372
|
-
const phaseRef =
|
|
1643
|
+
const dragRef = useRef5(null);
|
|
1644
|
+
const phaseRef = useRef5("idle");
|
|
1373
1645
|
phaseRef.current = phase;
|
|
1374
|
-
const settleTimer =
|
|
1375
|
-
const settleRaf =
|
|
1646
|
+
const settleTimer = useRef5(null);
|
|
1647
|
+
const settleRaf = useRef5(null);
|
|
1376
1648
|
const clearPending = useCallback3(() => {
|
|
1377
1649
|
if (settleTimer.current != null) {
|
|
1378
1650
|
clearTimeout(settleTimer.current);
|
|
@@ -1403,7 +1675,7 @@ function useSlideSwipe(opts) {
|
|
|
1403
1675
|
setPhase("dragging");
|
|
1404
1676
|
setOffsetPx(0);
|
|
1405
1677
|
}, []);
|
|
1406
|
-
|
|
1678
|
+
useEffect5(() => {
|
|
1407
1679
|
function currentWidth() {
|
|
1408
1680
|
return optsRef.current.containerRef.current?.getBoundingClientRect().width ?? 0;
|
|
1409
1681
|
}
|
|
@@ -1473,7 +1745,7 @@ function useSlideSwipe(opts) {
|
|
|
1473
1745
|
window.removeEventListener("pointercancel", onCancel);
|
|
1474
1746
|
};
|
|
1475
1747
|
}, [settleMs]);
|
|
1476
|
-
|
|
1748
|
+
useEffect5(() => {
|
|
1477
1749
|
if (!opts.enabled) {
|
|
1478
1750
|
dragRef.current = null;
|
|
1479
1751
|
clearPending();
|
|
@@ -1481,7 +1753,7 @@ function useSlideSwipe(opts) {
|
|
|
1481
1753
|
setOffsetPx(0);
|
|
1482
1754
|
}
|
|
1483
1755
|
}, [opts.enabled, clearPending]);
|
|
1484
|
-
|
|
1756
|
+
useEffect5(() => clearPending, [clearPending]);
|
|
1485
1757
|
return { offsetPx, phase, onPointerDown };
|
|
1486
1758
|
}
|
|
1487
1759
|
|
|
@@ -1490,7 +1762,7 @@ import {
|
|
|
1490
1762
|
expandCoverBlock,
|
|
1491
1763
|
createTemplateContext,
|
|
1492
1764
|
markdownToDoc,
|
|
1493
|
-
VIEWPORT_PRESETS
|
|
1765
|
+
VIEWPORT_PRESETS as VIEWPORT_PRESETS2
|
|
1494
1766
|
} from "@bendyline/squisq/doc";
|
|
1495
1767
|
import { parseMarkdown } from "@bendyline/squisq/markdown";
|
|
1496
1768
|
|
|
@@ -1780,7 +2052,7 @@ function seekVideoToFrame(video, targetTime, timeoutMs = DEFAULT_VIDEO_FRAME_TIM
|
|
|
1780
2052
|
}
|
|
1781
2053
|
|
|
1782
2054
|
// src/DocPlayer.tsx
|
|
1783
|
-
import { jsx as
|
|
2055
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1784
2056
|
function isDevEnvironment() {
|
|
1785
2057
|
try {
|
|
1786
2058
|
return typeof process !== "undefined" && process.env.NODE_ENV !== "production";
|
|
@@ -1812,15 +2084,15 @@ function waitForVisualUpdate() {
|
|
|
1812
2084
|
}
|
|
1813
2085
|
function DocPlayer(props) {
|
|
1814
2086
|
const { doc, markdown } = props;
|
|
1815
|
-
const markdownDoc =
|
|
2087
|
+
const markdownDoc = useMemo4(
|
|
1816
2088
|
() => !doc && markdown !== void 0 ? markdownToDoc(parseMarkdown(markdown)) : void 0,
|
|
1817
2089
|
[doc, markdown]
|
|
1818
2090
|
);
|
|
1819
2091
|
const resolvedDoc = doc ?? markdownDoc;
|
|
1820
2092
|
if (!resolvedDoc) {
|
|
1821
|
-
return /* @__PURE__ */
|
|
2093
|
+
return /* @__PURE__ */ jsx8("div", { className: "doc-player doc-player--empty" });
|
|
1822
2094
|
}
|
|
1823
|
-
return /* @__PURE__ */
|
|
2095
|
+
return /* @__PURE__ */ jsx8(DocPlayerContent, { ...props, doc: resolvedDoc });
|
|
1824
2096
|
}
|
|
1825
2097
|
function DocPlayerContent({
|
|
1826
2098
|
doc,
|
|
@@ -1846,6 +2118,10 @@ function DocPlayerContent({
|
|
|
1846
2118
|
onBlockMarkers,
|
|
1847
2119
|
forceViewport,
|
|
1848
2120
|
displayMode = "video",
|
|
2121
|
+
dashboardLayout,
|
|
2122
|
+
dashboardShowTitle,
|
|
2123
|
+
dashboardStyle,
|
|
2124
|
+
dashboardDocumentTitle,
|
|
1849
2125
|
showCoverSlide,
|
|
1850
2126
|
coverSlideTemplate,
|
|
1851
2127
|
coverSlideDuration,
|
|
@@ -1866,20 +2142,21 @@ function DocPlayerContent({
|
|
|
1866
2142
|
}) {
|
|
1867
2143
|
const isSlideshowMode = displayMode === "slideshow";
|
|
1868
2144
|
const isLinearMode = displayMode === "linear";
|
|
1869
|
-
const
|
|
1870
|
-
const
|
|
2145
|
+
const isDashboardMode = displayMode === "dashboard";
|
|
2146
|
+
const audioRef = useRef6(null);
|
|
2147
|
+
const containerRef = useRef6(null);
|
|
1871
2148
|
const playerId = `squisq-player-${useId2().replace(/:/g, "")}`;
|
|
1872
2149
|
const [tapFeedback, setTapFeedback] = useState5(null);
|
|
1873
|
-
const tapFeedbackTimer =
|
|
2150
|
+
const tapFeedbackTimer = useRef6();
|
|
1874
2151
|
const { viewport } = useViewportOrientation();
|
|
1875
|
-
const activeViewport = forceViewport || (renderMode ?
|
|
2152
|
+
const activeViewport = forceViewport || (renderMode ? VIEWPORT_PRESETS2.landscape : viewport);
|
|
1876
2153
|
const activeOrientation = activeViewport.height > activeViewport.width ? "portrait" : "landscape";
|
|
1877
|
-
const isDebugMode =
|
|
2154
|
+
const isDebugMode = useMemo4(() => {
|
|
1878
2155
|
if (typeof window === "undefined") return false;
|
|
1879
2156
|
const params = new URLSearchParams(window.location.search);
|
|
1880
2157
|
return params.get("debug") === "true";
|
|
1881
2158
|
}, []);
|
|
1882
|
-
const syntheticDuration =
|
|
2159
|
+
const syntheticDuration = useMemo4(
|
|
1883
2160
|
() => audioMode === "synthetic" ? getDocPlaybackDuration(doc) : 0,
|
|
1884
2161
|
[audioMode, doc]
|
|
1885
2162
|
);
|
|
@@ -1892,7 +2169,7 @@ function DocPlayerContent({
|
|
|
1892
2169
|
syntheticDuration
|
|
1893
2170
|
);
|
|
1894
2171
|
const audio = externalAudioController || internalAudio;
|
|
1895
|
-
|
|
2172
|
+
useEffect6(() => {
|
|
1896
2173
|
if (warnedMissingStyles || !isDevEnvironment()) return;
|
|
1897
2174
|
const el = containerRef.current;
|
|
1898
2175
|
if (!el || typeof getComputedStyle !== "function") return;
|
|
@@ -1923,9 +2200,9 @@ function DocPlayerContent({
|
|
|
1923
2200
|
const [renderClock, setRenderClock] = useState5(null);
|
|
1924
2201
|
const renderTimeOverride = renderClock?.doc === doc ? renderClock.time : null;
|
|
1925
2202
|
const currentTime = renderMode ? renderTimeOverride ?? audioCurrentTime : audioCurrentTime;
|
|
1926
|
-
const rawSchedule =
|
|
2203
|
+
const rawSchedule = useMemo4(() => resolveMediaSchedule(doc), [doc]);
|
|
1927
2204
|
const clipDurations = useMediaClipDurations(rawSchedule, basePath);
|
|
1928
|
-
const mediaSchedule =
|
|
2205
|
+
const mediaSchedule = useMemo4(
|
|
1929
2206
|
() => resolveMediaSchedule(doc, { intrinsicDuration: (clip) => clipDurations.get(clip.src) }),
|
|
1930
2207
|
[doc, clipDurations]
|
|
1931
2208
|
);
|
|
@@ -1950,13 +2227,13 @@ function DocPlayerContent({
|
|
|
1950
2227
|
if (!isPlaying) startActiveTimelineMedia();
|
|
1951
2228
|
return toggle();
|
|
1952
2229
|
}, [isPlaying, startActiveTimelineMedia, toggle]);
|
|
1953
|
-
const currentTimeRef =
|
|
2230
|
+
const currentTimeRef = useRef6(currentTime);
|
|
1954
2231
|
currentTimeRef.current = currentTime;
|
|
1955
|
-
const committedRenderTimeRef =
|
|
1956
|
-
const renderCommitWaitersRef =
|
|
1957
|
-
const totalDurationRef =
|
|
2232
|
+
const committedRenderTimeRef = useRef6(currentTime);
|
|
2233
|
+
const renderCommitWaitersRef = useRef6([]);
|
|
2234
|
+
const totalDurationRef = useRef6(totalDuration);
|
|
1958
2235
|
totalDurationRef.current = totalDuration;
|
|
1959
|
-
const expandedBlocksLenRef =
|
|
2236
|
+
const expandedBlocksLenRef = useRef6(0);
|
|
1960
2237
|
useLayoutEffect2(() => {
|
|
1961
2238
|
committedRenderTimeRef.current = currentTime;
|
|
1962
2239
|
const pending = renderCommitWaitersRef.current;
|
|
@@ -1966,7 +2243,7 @@ function DocPlayerContent({
|
|
|
1966
2243
|
return false;
|
|
1967
2244
|
});
|
|
1968
2245
|
}, [currentTime]);
|
|
1969
|
-
|
|
2246
|
+
useEffect6(
|
|
1970
2247
|
() => () => {
|
|
1971
2248
|
const error = new Error("DocPlayer unmounted before the requested frame committed.");
|
|
1972
2249
|
renderCommitWaitersRef.current.splice(0).forEach((waiter) => waiter.reject(error));
|
|
@@ -2006,7 +2283,7 @@ function DocPlayerContent({
|
|
|
2006
2283
|
);
|
|
2007
2284
|
const autoSurface = useAutoSurface(surface === "auto");
|
|
2008
2285
|
const resolvedSurface = surface === "auto" ? autoSurface : surface;
|
|
2009
|
-
const appearance =
|
|
2286
|
+
const appearance = useMemo4(
|
|
2010
2287
|
() => resolveDocPlayerAppearance(doc, {
|
|
2011
2288
|
theme,
|
|
2012
2289
|
videoPresentation,
|
|
@@ -2031,13 +2308,13 @@ function DocPlayerContent({
|
|
|
2031
2308
|
coverSlidePlayback
|
|
2032
2309
|
]
|
|
2033
2310
|
);
|
|
2034
|
-
const effectiveTheme =
|
|
2311
|
+
const effectiveTheme = useMemo4(() => {
|
|
2035
2312
|
const base = appearance.theme;
|
|
2036
2313
|
return resolvedSurface ? applySurface(base, resolvedSurface) : base;
|
|
2037
2314
|
}, [appearance.theme, resolvedSurface]);
|
|
2038
|
-
const resolvedPipStyle =
|
|
2315
|
+
const resolvedPipStyle = useMemo4(() => pipStyleVars(effectiveTheme), [effectiveTheme]);
|
|
2039
2316
|
const pipVars = resolvedPipStyle;
|
|
2040
|
-
const pipFrameStyle =
|
|
2317
|
+
const pipFrameStyle = useMemo4(
|
|
2041
2318
|
() => ({
|
|
2042
2319
|
border: resolvedPipStyle["--squisq-pip-border"],
|
|
2043
2320
|
borderRadius: resolvedPipStyle["--squisq-pip-radius"],
|
|
@@ -2067,7 +2344,7 @@ function DocPlayerContent({
|
|
|
2067
2344
|
// remove authored slides from the default loss-averse projection.
|
|
2068
2345
|
useAudioSegmentTiming: audioMode !== "synthetic"
|
|
2069
2346
|
});
|
|
2070
|
-
const coverBlock =
|
|
2347
|
+
const coverBlock = useMemo4(() => {
|
|
2071
2348
|
const startBlockConfig = doc.startBlock;
|
|
2072
2349
|
if (!appearance.showCoverSlide) return null;
|
|
2073
2350
|
if (!startBlockConfig) return null;
|
|
@@ -2092,11 +2369,11 @@ function DocPlayerContent({
|
|
|
2092
2369
|
const hasManagedCover = !!coverBlock;
|
|
2093
2370
|
const [slideshowCoverVisible, setSlideshowCoverVisible] = useState5(false);
|
|
2094
2371
|
const [isSlideshowPickerOpen, setIsSlideshowPickerOpen] = useState5(false);
|
|
2095
|
-
const slideshowCoverInitKeyRef =
|
|
2096
|
-
|
|
2372
|
+
const slideshowCoverInitKeyRef = useRef6("");
|
|
2373
|
+
useEffect6(() => {
|
|
2097
2374
|
slideshowCoverInitKeyRef.current = "";
|
|
2098
2375
|
}, [doc]);
|
|
2099
|
-
|
|
2376
|
+
useEffect6(() => {
|
|
2100
2377
|
const initKey = `${isSlideshowMode}:${hasManagedCover}:${renderMode}`;
|
|
2101
2378
|
if (slideshowCoverInitKeyRef.current === initKey) return;
|
|
2102
2379
|
slideshowCoverInitKeyRef.current = initKey;
|
|
@@ -2109,10 +2386,10 @@ function DocPlayerContent({
|
|
|
2109
2386
|
}, [isSlideshowMode, hasManagedCover, renderMode, pause]);
|
|
2110
2387
|
const [coverForced, setCoverForced] = useState5(false);
|
|
2111
2388
|
const [coverGraceActive, setCoverGraceActive] = useState5(false);
|
|
2112
|
-
const coverGraceTimer =
|
|
2113
|
-
const coverWasShowing =
|
|
2114
|
-
const hasPlayedOnce =
|
|
2115
|
-
|
|
2389
|
+
const coverGraceTimer = useRef6();
|
|
2390
|
+
const coverWasShowing = useRef6(false);
|
|
2391
|
+
const hasPlayedOnce = useRef6(false);
|
|
2392
|
+
useEffect6(() => {
|
|
2116
2393
|
hasPlayedOnce.current = false;
|
|
2117
2394
|
coverWasShowing.current = false;
|
|
2118
2395
|
clearTimeout(coverGraceTimer.current);
|
|
@@ -2121,7 +2398,7 @@ function DocPlayerContent({
|
|
|
2121
2398
|
}, [doc]);
|
|
2122
2399
|
const atRest = !!(coverBlock && !isSlideshowMode && !isPlaying && currentTime === 0 && !hasPlayedOnce.current && !renderMode && !autoPlay);
|
|
2123
2400
|
if (atRest) coverWasShowing.current = true;
|
|
2124
|
-
|
|
2401
|
+
useEffect6(() => {
|
|
2125
2402
|
if (isPlaying && coverWasShowing.current && coverBlock && !renderMode && !isSlideshowMode) {
|
|
2126
2403
|
coverWasShowing.current = false;
|
|
2127
2404
|
hasPlayedOnce.current = true;
|
|
@@ -2132,8 +2409,8 @@ function DocPlayerContent({
|
|
|
2132
2409
|
);
|
|
2133
2410
|
}
|
|
2134
2411
|
}, [isPlaying, coverBlock, renderMode, isSlideshowMode, appearance.coverSlideDuration]);
|
|
2135
|
-
|
|
2136
|
-
|
|
2412
|
+
useEffect6(() => () => clearTimeout(coverGraceTimer.current), []);
|
|
2413
|
+
useEffect6(() => () => clearTimeout(tapFeedbackTimer.current), []);
|
|
2137
2414
|
const showVideoCoverBlock = !isSlideshowMode && !isLinearMode && !!coverBlock && (coverForced || coverGraceActive || !isPlaying && currentTime === 0 && !hasPlayedOnce.current && !renderMode && !autoPlay);
|
|
2138
2415
|
const effectiveSlideshowCoverVisible = coverVisible ?? slideshowCoverVisible;
|
|
2139
2416
|
const showSlideshowCover = !!(isSlideshowMode && !isLinearMode && !renderMode && coverBlock && effectiveSlideshowCoverVisible);
|
|
@@ -2141,29 +2418,29 @@ function DocPlayerContent({
|
|
|
2141
2418
|
const slideshowHasCover = !!(isSlideshowMode && !renderMode && coverBlock);
|
|
2142
2419
|
const slideshowSlideIndex = slideshowHasCover ? effectiveSlideshowCoverVisible ? 0 : currentBlockIndex + 1 : currentBlockIndex;
|
|
2143
2420
|
const slideshowTotalSlides = slideshowHasCover ? expandedBlocks.length + 1 : expandedBlocks.length;
|
|
2144
|
-
const hasAutoPlayed =
|
|
2145
|
-
|
|
2421
|
+
const hasAutoPlayed = useRef6(false);
|
|
2422
|
+
useEffect6(() => {
|
|
2146
2423
|
hasAutoPlayed.current = false;
|
|
2147
2424
|
}, [doc]);
|
|
2148
|
-
|
|
2425
|
+
useEffect6(() => {
|
|
2149
2426
|
if (isAudioReady && autoPlay && !hasAutoPlayed.current) {
|
|
2150
2427
|
hasAutoPlayed.current = true;
|
|
2151
2428
|
playWithTimelineMedia();
|
|
2152
2429
|
}
|
|
2153
2430
|
}, [isAudioReady, autoPlay, playWithTimelineMedia]);
|
|
2154
|
-
|
|
2431
|
+
useEffect6(() => {
|
|
2155
2432
|
onTimeUpdate?.(currentTime);
|
|
2156
2433
|
}, [currentTime, onTimeUpdate]);
|
|
2157
|
-
|
|
2434
|
+
useEffect6(() => {
|
|
2158
2435
|
if (isEnded) {
|
|
2159
2436
|
onEnded?.();
|
|
2160
|
-
if (loop && !isSlideshowMode && !isLinearMode) {
|
|
2437
|
+
if (loop && !isSlideshowMode && !isLinearMode && !isDashboardMode) {
|
|
2161
2438
|
void restart();
|
|
2162
2439
|
}
|
|
2163
2440
|
}
|
|
2164
|
-
}, [isEnded, isLinearMode, isSlideshowMode, loop, onEnded, restart]);
|
|
2165
|
-
const liveRenderAPIRef =
|
|
2166
|
-
const stableRenderAPIRef =
|
|
2441
|
+
}, [isEnded, isDashboardMode, isLinearMode, isSlideshowMode, loop, onEnded, restart]);
|
|
2442
|
+
const liveRenderAPIRef = useRef6(null);
|
|
2443
|
+
const stableRenderAPIRef = useRef6(null);
|
|
2167
2444
|
if (!stableRenderAPIRef.current) {
|
|
2168
2445
|
const current = () => {
|
|
2169
2446
|
const api = liveRenderAPIRef.current;
|
|
@@ -2184,8 +2461,8 @@ function DocPlayerContent({
|
|
|
2184
2461
|
};
|
|
2185
2462
|
}
|
|
2186
2463
|
const stableRenderAPI = stableRenderAPIRef.current;
|
|
2187
|
-
|
|
2188
|
-
if (!renderMode && !isDebugMode) {
|
|
2464
|
+
useEffect6(() => {
|
|
2465
|
+
if (isDashboardMode || !renderMode && !isDebugMode) {
|
|
2189
2466
|
liveRenderAPIRef.current = null;
|
|
2190
2467
|
return;
|
|
2191
2468
|
}
|
|
@@ -2311,19 +2588,21 @@ function DocPlayerContent({
|
|
|
2311
2588
|
coverBlock,
|
|
2312
2589
|
doc,
|
|
2313
2590
|
externalAudioController,
|
|
2314
|
-
waitForRenderCommit
|
|
2591
|
+
waitForRenderCommit,
|
|
2592
|
+
isDashboardMode
|
|
2315
2593
|
]);
|
|
2316
|
-
|
|
2594
|
+
useEffect6(() => {
|
|
2595
|
+
if (isDashboardMode) return;
|
|
2317
2596
|
if (!renderMode && !isDebugMode || !containerRef.current) {
|
|
2318
2597
|
onRenderAPIReady?.(null);
|
|
2319
2598
|
return;
|
|
2320
2599
|
}
|
|
2321
2600
|
onRenderAPIReady?.(stableRenderAPI);
|
|
2322
2601
|
return () => onRenderAPIReady?.(null);
|
|
2323
|
-
}, [renderMode, isDebugMode, onRenderAPIReady, stableRenderAPI]);
|
|
2602
|
+
}, [renderMode, isDebugMode, isDashboardMode, onRenderAPIReady, stableRenderAPI]);
|
|
2324
2603
|
const defaultMode = captionsEnabledProp === false ? "off" : captionStyle || "standard";
|
|
2325
2604
|
const [captionMode, setCaptionMode] = useState5(defaultMode);
|
|
2326
|
-
|
|
2605
|
+
useEffect6(() => {
|
|
2327
2606
|
setCaptionMode(defaultMode);
|
|
2328
2607
|
}, [defaultMode]);
|
|
2329
2608
|
const captionsEnabled = captionMode !== "off";
|
|
@@ -2343,8 +2622,8 @@ function DocPlayerContent({
|
|
|
2343
2622
|
});
|
|
2344
2623
|
}, [onCaptionsToggle]);
|
|
2345
2624
|
const hasCaptions = doc.captions && doc.captions.phrases.length > 0;
|
|
2346
|
-
const segmentTitleMap =
|
|
2347
|
-
const playbackState =
|
|
2625
|
+
const segmentTitleMap = useMemo4(() => buildSegmentTitleMap(doc), [doc]);
|
|
2626
|
+
const playbackState = useMemo4(
|
|
2348
2627
|
() => ({
|
|
2349
2628
|
isPlaying,
|
|
2350
2629
|
currentTime,
|
|
@@ -2387,7 +2666,7 @@ function DocPlayerContent({
|
|
|
2387
2666
|
expandedBlocks.length
|
|
2388
2667
|
]
|
|
2389
2668
|
);
|
|
2390
|
-
const playbackActions =
|
|
2669
|
+
const playbackActions = useMemo4(
|
|
2391
2670
|
() => ({
|
|
2392
2671
|
toggle: toggleWithTimelineMedia,
|
|
2393
2672
|
restart,
|
|
@@ -2405,7 +2684,7 @@ function DocPlayerContent({
|
|
|
2405
2684
|
onFullscreenToggle
|
|
2406
2685
|
]
|
|
2407
2686
|
);
|
|
2408
|
-
const slideNavActions =
|
|
2687
|
+
const slideNavActions = useMemo4(
|
|
2409
2688
|
() => ({
|
|
2410
2689
|
nextSlide: () => {
|
|
2411
2690
|
if (slideshowHasCover && slideshowCoverVisible) {
|
|
@@ -2494,10 +2773,10 @@ function DocPlayerContent({
|
|
|
2494
2773
|
onNext: handleSwipeNext,
|
|
2495
2774
|
onPrev: handleSwipePrev
|
|
2496
2775
|
});
|
|
2497
|
-
|
|
2776
|
+
useEffect6(() => {
|
|
2498
2777
|
onPlaybackStateChange?.(playbackState);
|
|
2499
2778
|
}, [playbackState, onPlaybackStateChange]);
|
|
2500
|
-
|
|
2779
|
+
useEffect6(() => {
|
|
2501
2780
|
onControlsReady?.({ play: playWithTimelineMedia, pause, ...playbackActions });
|
|
2502
2781
|
}, [playWithTimelineMedia, pause, playbackActions, onControlsReady]);
|
|
2503
2782
|
const getBlockTitle = useCallback4((block) => {
|
|
@@ -2524,7 +2803,7 @@ function DocPlayerContent({
|
|
|
2524
2803
|
}
|
|
2525
2804
|
return block.id.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
2526
2805
|
}, []);
|
|
2527
|
-
const slideshowPickerItems =
|
|
2806
|
+
const slideshowPickerItems = useMemo4(() => {
|
|
2528
2807
|
const blockItems = expandedBlocks.map((block, index) => ({
|
|
2529
2808
|
id: block.id,
|
|
2530
2809
|
label: String(index + 1),
|
|
@@ -2540,7 +2819,7 @@ function DocPlayerContent({
|
|
|
2540
2819
|
...blockItems
|
|
2541
2820
|
];
|
|
2542
2821
|
}, [coverBlock, expandedBlocks, getBlockTitle, slideshowHasCover]);
|
|
2543
|
-
const blockMarkers =
|
|
2822
|
+
const blockMarkers = useMemo4(() => {
|
|
2544
2823
|
if (!totalDuration || !expandedBlocks.length) return [];
|
|
2545
2824
|
let prevSegment = -1;
|
|
2546
2825
|
return expandedBlocks.map((block, index) => {
|
|
@@ -2555,7 +2834,7 @@ function DocPlayerContent({
|
|
|
2555
2834
|
};
|
|
2556
2835
|
});
|
|
2557
2836
|
}, [expandedBlocks, totalDuration, getBlockTitle]);
|
|
2558
|
-
|
|
2837
|
+
useEffect6(() => {
|
|
2559
2838
|
if (blockMarkers.length > 0) {
|
|
2560
2839
|
onBlockMarkers?.(blockMarkers);
|
|
2561
2840
|
}
|
|
@@ -2577,7 +2856,7 @@ function DocPlayerContent({
|
|
|
2577
2856
|
) && !isSlideshowToolbarTarget) {
|
|
2578
2857
|
return;
|
|
2579
2858
|
}
|
|
2580
|
-
if (isLinearMode) return;
|
|
2859
|
+
if (isLinearMode || isDashboardMode) return;
|
|
2581
2860
|
if (e.key === "f" || e.key === "F") {
|
|
2582
2861
|
if (!onFullscreenToggle) return;
|
|
2583
2862
|
e.preventDefault();
|
|
@@ -2629,6 +2908,7 @@ function DocPlayerContent({
|
|
|
2629
2908
|
[
|
|
2630
2909
|
isSlideshowMode,
|
|
2631
2910
|
isLinearMode,
|
|
2911
|
+
isDashboardMode,
|
|
2632
2912
|
toggleWithTimelineMedia,
|
|
2633
2913
|
seekTo,
|
|
2634
2914
|
slideNavActions,
|
|
@@ -2639,16 +2919,16 @@ function DocPlayerContent({
|
|
|
2639
2919
|
(e) => handleKeyboardShortcut(e, false),
|
|
2640
2920
|
[handleKeyboardShortcut]
|
|
2641
2921
|
);
|
|
2642
|
-
|
|
2643
|
-
if (!globalKeyboardShortcuts || renderMode || isLinearMode) return;
|
|
2922
|
+
useEffect6(() => {
|
|
2923
|
+
if (!globalKeyboardShortcuts || renderMode || isLinearMode || isDashboardMode) return;
|
|
2644
2924
|
const handleDocumentKeyDown = (event) => {
|
|
2645
2925
|
handleKeyboardShortcut(event, true);
|
|
2646
2926
|
};
|
|
2647
2927
|
document.addEventListener("keydown", handleDocumentKeyDown);
|
|
2648
2928
|
return () => document.removeEventListener("keydown", handleDocumentKeyDown);
|
|
2649
|
-
}, [globalKeyboardShortcuts, handleKeyboardShortcut, isLinearMode, renderMode]);
|
|
2929
|
+
}, [globalKeyboardShortcuts, handleKeyboardShortcut, isDashboardMode, isLinearMode, renderMode]);
|
|
2650
2930
|
if (isLinearMode) {
|
|
2651
|
-
return /* @__PURE__ */
|
|
2931
|
+
return /* @__PURE__ */ jsx8(
|
|
2652
2932
|
"div",
|
|
2653
2933
|
{
|
|
2654
2934
|
ref: containerRef,
|
|
@@ -2660,7 +2940,7 @@ function DocPlayerContent({
|
|
|
2660
2940
|
height: "100%",
|
|
2661
2941
|
overflow: "hidden"
|
|
2662
2942
|
},
|
|
2663
|
-
children: /* @__PURE__ */
|
|
2943
|
+
children: /* @__PURE__ */ jsx8(
|
|
2664
2944
|
LinearDocView,
|
|
2665
2945
|
{
|
|
2666
2946
|
doc,
|
|
@@ -2677,7 +2957,41 @@ function DocPlayerContent({
|
|
|
2677
2957
|
}
|
|
2678
2958
|
);
|
|
2679
2959
|
}
|
|
2680
|
-
|
|
2960
|
+
if (isDashboardMode) {
|
|
2961
|
+
return /* @__PURE__ */ jsx8(
|
|
2962
|
+
"div",
|
|
2963
|
+
{
|
|
2964
|
+
ref: containerRef,
|
|
2965
|
+
"data-player-id": playerId,
|
|
2966
|
+
className: "doc-player doc-player--dashboard",
|
|
2967
|
+
style: {
|
|
2968
|
+
position: "relative",
|
|
2969
|
+
width: "100%",
|
|
2970
|
+
aspectRatio: `${activeViewport.width} / ${activeViewport.height}`,
|
|
2971
|
+
margin: "0 auto",
|
|
2972
|
+
overflow: "hidden"
|
|
2973
|
+
},
|
|
2974
|
+
children: /* @__PURE__ */ jsx8(
|
|
2975
|
+
DashboardView,
|
|
2976
|
+
{
|
|
2977
|
+
doc,
|
|
2978
|
+
theme,
|
|
2979
|
+
viewport: activeViewport,
|
|
2980
|
+
layout: dashboardLayout,
|
|
2981
|
+
showTitle: dashboardShowTitle,
|
|
2982
|
+
style: dashboardStyle,
|
|
2983
|
+
documentTitle: dashboardDocumentTitle,
|
|
2984
|
+
basePath,
|
|
2985
|
+
animationsEnabled,
|
|
2986
|
+
muted: renderMode || muted,
|
|
2987
|
+
renderMode: renderMode || isDebugMode,
|
|
2988
|
+
onRenderAPIReady
|
|
2989
|
+
}
|
|
2990
|
+
)
|
|
2991
|
+
}
|
|
2992
|
+
);
|
|
2993
|
+
}
|
|
2994
|
+
return /* @__PURE__ */ jsxs5(
|
|
2681
2995
|
"div",
|
|
2682
2996
|
{
|
|
2683
2997
|
ref: containerRef,
|
|
@@ -2705,8 +3019,8 @@ function DocPlayerContent({
|
|
|
2705
3019
|
touchAction: swipeEnabled ? "pan-y" : void 0
|
|
2706
3020
|
},
|
|
2707
3021
|
children: [
|
|
2708
|
-
/* @__PURE__ */
|
|
2709
|
-
/* @__PURE__ */
|
|
3022
|
+
/* @__PURE__ */ jsx8("audio", { ref: audioRef, preload: "auto", muted }),
|
|
3023
|
+
/* @__PURE__ */ jsx8(
|
|
2710
3024
|
MediaClipLayer,
|
|
2711
3025
|
{
|
|
2712
3026
|
schedule: mediaSchedule,
|
|
@@ -2723,8 +3037,8 @@ function DocPlayerContent({
|
|
|
2723
3037
|
pipFrameStyle
|
|
2724
3038
|
}
|
|
2725
3039
|
),
|
|
2726
|
-
/* @__PURE__ */
|
|
2727
|
-
showCoverBlock && coverBlock && /* @__PURE__ */
|
|
3040
|
+
/* @__PURE__ */ jsxs5("div", { className: "doc-player__viewport", children: [
|
|
3041
|
+
showCoverBlock && coverBlock && /* @__PURE__ */ jsx8("div", { className: "doc-player__block doc-player__block--cover", children: /* @__PURE__ */ jsx8(
|
|
2728
3042
|
BlockRenderer,
|
|
2729
3043
|
{
|
|
2730
3044
|
block: coverBlock,
|
|
@@ -2741,7 +3055,7 @@ function DocPlayerContent({
|
|
|
2741
3055
|
// reconciles one block's layers onto another's (templates reuse layer
|
|
2742
3056
|
// ids like `title`/`background`), which would otherwise reuse stale
|
|
2743
3057
|
// DOM / skip entrance animations mid-transition.
|
|
2744
|
-
/* @__PURE__ */
|
|
3058
|
+
/* @__PURE__ */ jsx8("div", { className: "doc-player__block doc-player__block--previous", children: /* @__PURE__ */ jsx8(
|
|
2745
3059
|
BlockRenderer,
|
|
2746
3060
|
{
|
|
2747
3061
|
block: previousBlock,
|
|
@@ -2755,7 +3069,7 @@ function DocPlayerContent({
|
|
|
2755
3069
|
theme: effectiveTheme
|
|
2756
3070
|
}
|
|
2757
3071
|
) }, previousBlock.id),
|
|
2758
|
-
currentBlock && /* @__PURE__ */
|
|
3072
|
+
currentBlock && /* @__PURE__ */ jsx8(
|
|
2759
3073
|
"div",
|
|
2760
3074
|
{
|
|
2761
3075
|
className: `doc-player__block doc-player__block--active${swipe.phase !== "idle" ? ` doc-player__block--${swipe.phase}` : ""}`,
|
|
@@ -2764,7 +3078,7 @@ function DocPlayerContent({
|
|
|
2764
3078
|
...swipe.phase !== "idle" ? { transform: `translateX(${swipe.offsetPx}px)` } : {},
|
|
2765
3079
|
...showCoverBlock ? { opacity: 0, pointerEvents: "none" } : {}
|
|
2766
3080
|
} : void 0,
|
|
2767
|
-
children: /* @__PURE__ */
|
|
3081
|
+
children: /* @__PURE__ */ jsx8(
|
|
2768
3082
|
BlockRenderer,
|
|
2769
3083
|
{
|
|
2770
3084
|
block: currentBlock,
|
|
@@ -2781,7 +3095,7 @@ function DocPlayerContent({
|
|
|
2781
3095
|
},
|
|
2782
3096
|
currentBlock.id
|
|
2783
3097
|
),
|
|
2784
|
-
hasCaptions && (renderMode ? captionsEnabled : true) && /* @__PURE__ */
|
|
3098
|
+
hasCaptions && (renderMode ? captionsEnabled : true) && /* @__PURE__ */ jsx8(
|
|
2785
3099
|
CaptionOverlay,
|
|
2786
3100
|
{
|
|
2787
3101
|
captions: doc.captions,
|
|
@@ -2793,7 +3107,7 @@ function DocPlayerContent({
|
|
|
2793
3107
|
viewport: activeViewport
|
|
2794
3108
|
}
|
|
2795
3109
|
),
|
|
2796
|
-
isDebugMode && /* @__PURE__ */
|
|
3110
|
+
isDebugMode && /* @__PURE__ */ jsxs5(
|
|
2797
3111
|
"div",
|
|
2798
3112
|
{
|
|
2799
3113
|
className: "doc-player__debug",
|
|
@@ -2814,27 +3128,27 @@ function DocPlayerContent({
|
|
|
2814
3128
|
textAlign: "left"
|
|
2815
3129
|
},
|
|
2816
3130
|
children: [
|
|
2817
|
-
/* @__PURE__ */
|
|
2818
|
-
/* @__PURE__ */
|
|
2819
|
-
/* @__PURE__ */
|
|
3131
|
+
/* @__PURE__ */ jsx8("div", { style: { color: "#ffcc00", fontWeight: "bold", marginBottom: "4px" }, children: "DEBUG MODE" }),
|
|
3132
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
3133
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: "template:" }),
|
|
2820
3134
|
" ",
|
|
2821
|
-
/* @__PURE__ */
|
|
3135
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#ff6b6b" }, children: currentBlock?.template ?? "raw" })
|
|
2822
3136
|
] }),
|
|
2823
|
-
/* @__PURE__ */
|
|
2824
|
-
/* @__PURE__ */
|
|
3137
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
3138
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: "block:" }),
|
|
2825
3139
|
" ",
|
|
2826
3140
|
currentBlockIndex + 1,
|
|
2827
3141
|
"/",
|
|
2828
3142
|
expandedBlocks.length,
|
|
2829
3143
|
" ",
|
|
2830
|
-
/* @__PURE__ */
|
|
3144
|
+
/* @__PURE__ */ jsxs5("span", { style: { color: "#666" }, children: [
|
|
2831
3145
|
"(",
|
|
2832
3146
|
currentBlock?.id || "none",
|
|
2833
3147
|
")"
|
|
2834
3148
|
] })
|
|
2835
3149
|
] }),
|
|
2836
|
-
/* @__PURE__ */
|
|
2837
|
-
/* @__PURE__ */
|
|
3150
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
3151
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: "time:" }),
|
|
2838
3152
|
" ",
|
|
2839
3153
|
currentTime.toFixed(2),
|
|
2840
3154
|
"s /",
|
|
@@ -2842,7 +3156,7 @@ function DocPlayerContent({
|
|
|
2842
3156
|
totalDuration.toFixed(1),
|
|
2843
3157
|
"s",
|
|
2844
3158
|
" ",
|
|
2845
|
-
/* @__PURE__ */
|
|
3159
|
+
/* @__PURE__ */ jsxs5("span", { style: { color: "#666" }, children: [
|
|
2846
3160
|
"(progress: ",
|
|
2847
3161
|
(docProgress * 100).toFixed(1),
|
|
2848
3162
|
"%, scriptDur: ",
|
|
@@ -2850,8 +3164,8 @@ function DocPlayerContent({
|
|
|
2850
3164
|
")"
|
|
2851
3165
|
] })
|
|
2852
3166
|
] }),
|
|
2853
|
-
/* @__PURE__ */
|
|
2854
|
-
/* @__PURE__ */
|
|
3167
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
3168
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: "blockTime:" }),
|
|
2855
3169
|
" ",
|
|
2856
3170
|
blockTime.toFixed(2),
|
|
2857
3171
|
"s /",
|
|
@@ -2859,58 +3173,58 @@ function DocPlayerContent({
|
|
|
2859
3173
|
(currentBlock?.duration || 0).toFixed(1),
|
|
2860
3174
|
"s"
|
|
2861
3175
|
] }),
|
|
2862
|
-
/* @__PURE__ */
|
|
2863
|
-
/* @__PURE__ */
|
|
3176
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
3177
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: "segment:" }),
|
|
2864
3178
|
" ",
|
|
2865
3179
|
currentSegment,
|
|
2866
3180
|
"/",
|
|
2867
3181
|
doc.audio.segments.length - 1,
|
|
2868
3182
|
" ",
|
|
2869
|
-
/* @__PURE__ */
|
|
3183
|
+
/* @__PURE__ */ jsxs5("span", { style: { color: "#666" }, children: [
|
|
2870
3184
|
"(",
|
|
2871
3185
|
doc.audio.segments[currentSegment]?.name || "none",
|
|
2872
3186
|
")"
|
|
2873
3187
|
] })
|
|
2874
3188
|
] }),
|
|
2875
|
-
/* @__PURE__ */
|
|
2876
|
-
/* @__PURE__ */
|
|
3189
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
3190
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: "viewport:" }),
|
|
2877
3191
|
" ",
|
|
2878
3192
|
activeViewport.name || `${activeViewport.width}x${activeViewport.height}`,
|
|
2879
3193
|
" ",
|
|
2880
|
-
/* @__PURE__ */
|
|
3194
|
+
/* @__PURE__ */ jsxs5("span", { style: { color: "#666" }, children: [
|
|
2881
3195
|
"(",
|
|
2882
3196
|
activeOrientation,
|
|
2883
3197
|
")"
|
|
2884
3198
|
] })
|
|
2885
3199
|
] }),
|
|
2886
|
-
/* @__PURE__ */
|
|
2887
|
-
/* @__PURE__ */
|
|
3200
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
3201
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: "playing:" }),
|
|
2888
3202
|
" ",
|
|
2889
|
-
/* @__PURE__ */
|
|
2890
|
-
showCoverBlock && /* @__PURE__ */
|
|
3203
|
+
/* @__PURE__ */ jsx8("span", { style: { color: isPlaying ? "#4ade80" : "#f87171" }, children: isPlaying ? "yes" : "no" }),
|
|
3204
|
+
showCoverBlock && /* @__PURE__ */ jsx8("span", { style: { color: "#60a5fa" }, children: " (cover)" })
|
|
2891
3205
|
] }),
|
|
2892
3206
|
hasCaptions && (() => {
|
|
2893
3207
|
const debugPhrase = getCaptionAtTime2(doc.captions, currentTime);
|
|
2894
3208
|
const debugEnabled = captionsEnabled && (isPlaying || currentTime > 0);
|
|
2895
|
-
return /* @__PURE__ */
|
|
2896
|
-
/* @__PURE__ */
|
|
2897
|
-
/* @__PURE__ */
|
|
3209
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3210
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
3211
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: "captions:" }),
|
|
2898
3212
|
" ",
|
|
2899
3213
|
doc.captions?.phrases.length || 0,
|
|
2900
3214
|
" phrases",
|
|
2901
3215
|
" ",
|
|
2902
|
-
/* @__PURE__ */
|
|
3216
|
+
/* @__PURE__ */ jsxs5("span", { style: { color: captionsEnabled ? "#4ade80" : "#666" }, children: [
|
|
2903
3217
|
"(",
|
|
2904
3218
|
captionsEnabled ? "on" : "off",
|
|
2905
3219
|
")"
|
|
2906
3220
|
] })
|
|
2907
3221
|
] }),
|
|
2908
|
-
/* @__PURE__ */
|
|
2909
|
-
/* @__PURE__ */
|
|
3222
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
3223
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: "cc.enabled:" }),
|
|
2910
3224
|
" ",
|
|
2911
|
-
/* @__PURE__ */
|
|
3225
|
+
/* @__PURE__ */ jsx8("span", { style: { color: debugEnabled ? "#4ade80" : "#f87171" }, children: String(debugEnabled) }),
|
|
2912
3226
|
" ",
|
|
2913
|
-
/* @__PURE__ */
|
|
3227
|
+
/* @__PURE__ */ jsxs5("span", { style: { color: "#666" }, children: [
|
|
2914
3228
|
"(playing=",
|
|
2915
3229
|
String(isPlaying),
|
|
2916
3230
|
" t>0=",
|
|
@@ -2918,15 +3232,15 @@ function DocPlayerContent({
|
|
|
2918
3232
|
")"
|
|
2919
3233
|
] })
|
|
2920
3234
|
] }),
|
|
2921
|
-
/* @__PURE__ */
|
|
2922
|
-
/* @__PURE__ */
|
|
3235
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
3236
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: "cc.phrase:" }),
|
|
2923
3237
|
" ",
|
|
2924
|
-
/* @__PURE__ */
|
|
3238
|
+
/* @__PURE__ */ jsx8("span", { style: { color: debugPhrase ? "#4ade80" : "#f87171" }, children: debugPhrase ? `"${debugPhrase.text.slice(0, 30)}..."` : "null" })
|
|
2925
3239
|
] }),
|
|
2926
|
-
debugPhrase && /* @__PURE__ */
|
|
2927
|
-
/* @__PURE__ */
|
|
3240
|
+
debugPhrase && /* @__PURE__ */ jsxs5("div", { children: [
|
|
3241
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888" }, children: "cc.range:" }),
|
|
2928
3242
|
" ",
|
|
2929
|
-
/* @__PURE__ */
|
|
3243
|
+
/* @__PURE__ */ jsxs5("span", { style: { color: "#60a5fa" }, children: [
|
|
2930
3244
|
debugPhrase.startTime.toFixed(2),
|
|
2931
3245
|
"-",
|
|
2932
3246
|
debugPhrase.endTime.toFixed(2)
|
|
@@ -2938,7 +3252,7 @@ function DocPlayerContent({
|
|
|
2938
3252
|
}
|
|
2939
3253
|
)
|
|
2940
3254
|
] }),
|
|
2941
|
-
!isAvailable && unavailableMessage && /* @__PURE__ */
|
|
3255
|
+
!isAvailable && unavailableMessage && /* @__PURE__ */ jsxs5(
|
|
2942
3256
|
"div",
|
|
2943
3257
|
{
|
|
2944
3258
|
className: "doc-player__unavailable",
|
|
@@ -2959,12 +3273,12 @@ function DocPlayerContent({
|
|
|
2959
3273
|
zIndex: 50
|
|
2960
3274
|
},
|
|
2961
3275
|
children: [
|
|
2962
|
-
/* @__PURE__ */
|
|
2963
|
-
/* @__PURE__ */
|
|
3276
|
+
/* @__PURE__ */ jsx8("span", { style: { fontSize: "32px" }, children: "\u{1F50A}" }),
|
|
3277
|
+
/* @__PURE__ */ jsx8("span", { children: unavailableMessage })
|
|
2964
3278
|
]
|
|
2965
3279
|
}
|
|
2966
3280
|
),
|
|
2967
|
-
!renderMode && !isSlideshowMode && showControls && /* @__PURE__ */
|
|
3281
|
+
!renderMode && !isSlideshowMode && showControls && /* @__PURE__ */ jsx8(
|
|
2968
3282
|
DocControlsOverlay,
|
|
2969
3283
|
{
|
|
2970
3284
|
state: playbackState,
|
|
@@ -2974,7 +3288,7 @@ function DocPlayerContent({
|
|
|
2974
3288
|
getBlockTitle
|
|
2975
3289
|
}
|
|
2976
3290
|
),
|
|
2977
|
-
!renderMode && !isSlideshowMode && !showControls && showScrubber && /* @__PURE__ */
|
|
3291
|
+
!renderMode && !isSlideshowMode && !showControls && showScrubber && /* @__PURE__ */ jsx8(
|
|
2978
3292
|
"div",
|
|
2979
3293
|
{
|
|
2980
3294
|
className: "doc-player__scrubber",
|
|
@@ -2989,7 +3303,7 @@ function DocPlayerContent({
|
|
|
2989
3303
|
alignItems: "center",
|
|
2990
3304
|
zIndex: 100
|
|
2991
3305
|
},
|
|
2992
|
-
children: /* @__PURE__ */
|
|
3306
|
+
children: /* @__PURE__ */ jsx8(
|
|
2993
3307
|
DocProgressBar,
|
|
2994
3308
|
{
|
|
2995
3309
|
state: playbackState,
|
|
@@ -3001,7 +3315,7 @@ function DocPlayerContent({
|
|
|
3001
3315
|
)
|
|
3002
3316
|
}
|
|
3003
3317
|
),
|
|
3004
|
-
!renderMode && isSlideshowMode && showControls && /* @__PURE__ */
|
|
3318
|
+
!renderMode && isSlideshowMode && showControls && /* @__PURE__ */ jsx8(
|
|
3005
3319
|
DocControlsSlideshow,
|
|
3006
3320
|
{
|
|
3007
3321
|
state: playbackState,
|
|
@@ -3011,14 +3325,14 @@ function DocPlayerContent({
|
|
|
3011
3325
|
onPickerOpenChange: setIsSlideshowPickerOpen
|
|
3012
3326
|
}
|
|
3013
3327
|
),
|
|
3014
|
-
!isSlideshowMode && tapFeedback && /* @__PURE__ */
|
|
3328
|
+
!isSlideshowMode && tapFeedback && /* @__PURE__ */ jsx8("div", { className: "doc-player__tap-feedback", children: /* @__PURE__ */ jsx8("svg", { viewBox: "0 0 24 24", fill: "white", width: "48", height: "48", children: tapFeedback === "pause" ? /* @__PURE__ */ jsx8("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }) : /* @__PURE__ */ jsx8("path", { d: "M8 5v14l11-7z" }) }) }, tapFeedback)
|
|
3015
3329
|
]
|
|
3016
3330
|
}
|
|
3017
3331
|
);
|
|
3018
3332
|
}
|
|
3019
3333
|
|
|
3020
3334
|
// src/DocControlsBottom.tsx
|
|
3021
|
-
import { jsx as
|
|
3335
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3022
3336
|
function DocControlsBottom({
|
|
3023
3337
|
state,
|
|
3024
3338
|
actions,
|
|
@@ -3026,32 +3340,32 @@ function DocControlsBottom({
|
|
|
3026
3340
|
expandedBlocks,
|
|
3027
3341
|
getBlockTitle
|
|
3028
3342
|
}) {
|
|
3029
|
-
return /* @__PURE__ */
|
|
3030
|
-
/* @__PURE__ */
|
|
3343
|
+
return /* @__PURE__ */ jsxs6("div", { className: "doc-controls-bottom", children: [
|
|
3344
|
+
/* @__PURE__ */ jsx9(
|
|
3031
3345
|
"button",
|
|
3032
3346
|
{
|
|
3033
3347
|
className: "bottom-ctrl-btn",
|
|
3034
3348
|
onClick: actions.restart,
|
|
3035
3349
|
title: "Restart",
|
|
3036
3350
|
"aria-label": "Restart from beginning",
|
|
3037
|
-
children: /* @__PURE__ */
|
|
3351
|
+
children: /* @__PURE__ */ jsx9("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx9("path", { d: "M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z" }) })
|
|
3038
3352
|
}
|
|
3039
3353
|
),
|
|
3040
|
-
/* @__PURE__ */
|
|
3354
|
+
/* @__PURE__ */ jsx9(
|
|
3041
3355
|
"button",
|
|
3042
3356
|
{
|
|
3043
3357
|
className: "bottom-ctrl-btn bottom-play-btn",
|
|
3044
3358
|
onClick: actions.toggle,
|
|
3045
3359
|
"aria-label": state.isPlaying ? "Pause" : "Play",
|
|
3046
|
-
children: state.isPlaying ? /* @__PURE__ */
|
|
3360
|
+
children: state.isPlaying ? /* @__PURE__ */ jsx9("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx9("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }) }) : /* @__PURE__ */ jsx9("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx9("path", { d: "M8 5v14l11-7z" }) })
|
|
3047
3361
|
}
|
|
3048
3362
|
),
|
|
3049
|
-
/* @__PURE__ */
|
|
3363
|
+
/* @__PURE__ */ jsxs6("span", { className: "bottom-time", children: [
|
|
3050
3364
|
formatTime(state.currentTime),
|
|
3051
3365
|
" / ",
|
|
3052
3366
|
formatTime(state.totalDuration)
|
|
3053
3367
|
] }),
|
|
3054
|
-
/* @__PURE__ */
|
|
3368
|
+
/* @__PURE__ */ jsx9(
|
|
3055
3369
|
DocProgressBar,
|
|
3056
3370
|
{
|
|
3057
3371
|
state,
|
|
@@ -3061,92 +3375,92 @@ function DocControlsBottom({
|
|
|
3061
3375
|
getBlockTitle
|
|
3062
3376
|
}
|
|
3063
3377
|
),
|
|
3064
|
-
/* @__PURE__ */
|
|
3378
|
+
/* @__PURE__ */ jsxs6("span", { className: "bottom-segment", children: [
|
|
3065
3379
|
state.currentBlockIndex + 1,
|
|
3066
3380
|
"/",
|
|
3067
3381
|
state.totalBlocks
|
|
3068
3382
|
] }),
|
|
3069
|
-
state.hasCaptions && /* @__PURE__ */
|
|
3383
|
+
state.hasCaptions && /* @__PURE__ */ jsx9(
|
|
3070
3384
|
"button",
|
|
3071
3385
|
{
|
|
3072
3386
|
className: `bottom-ctrl-btn ${state.captionMode !== "off" ? "bottom-ctrl-btn--active" : ""}`,
|
|
3073
3387
|
onClick: () => actions.cycleCaptionMode(),
|
|
3074
3388
|
title: state.captionMode === "off" ? "Captions: Off" : state.captionMode === "standard" ? "Captions: Standard" : "Captions: Social",
|
|
3075
3389
|
"aria-label": "Cycle caption style",
|
|
3076
|
-
children: /* @__PURE__ */
|
|
3390
|
+
children: /* @__PURE__ */ jsx9("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx9("path", { d: "M19 4H5a2 2 0 00-2 2v12a2 2 0 002 2h14a2 2 0 002-2V6a2 2 0 00-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-4a1 1 0 011-1h3a1 1 0 011 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1a1 1 0 01-1 1h-3a1 1 0 01-1-1v-4a1 1 0 011-1h3a1 1 0 011 1v1z" }) })
|
|
3077
3391
|
}
|
|
3078
3392
|
),
|
|
3079
|
-
actions.toggleFullscreen && /* @__PURE__ */
|
|
3393
|
+
actions.toggleFullscreen && /* @__PURE__ */ jsx9(
|
|
3080
3394
|
"button",
|
|
3081
3395
|
{
|
|
3082
3396
|
className: `bottom-ctrl-btn ${state.isFullscreen ? "bottom-ctrl-btn--active" : ""}`,
|
|
3083
3397
|
onClick: actions.toggleFullscreen,
|
|
3084
3398
|
title: state.isFullscreen ? "Exit fullscreen (F)" : "Fullscreen (F)",
|
|
3085
3399
|
"aria-label": state.isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
|
|
3086
|
-
children: state.isFullscreen ? /* @__PURE__ */
|
|
3400
|
+
children: state.isFullscreen ? /* @__PURE__ */ jsx9("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx9("path", { d: "M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z" }) }) : /* @__PURE__ */ jsx9("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "18", height: "18", children: /* @__PURE__ */ jsx9("path", { d: "M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" }) })
|
|
3087
3401
|
}
|
|
3088
3402
|
)
|
|
3089
3403
|
] });
|
|
3090
3404
|
}
|
|
3091
3405
|
|
|
3092
3406
|
// src/DocControlsSidebar.tsx
|
|
3093
|
-
import { jsx as
|
|
3407
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3094
3408
|
function DocControlsSidebar({ state, actions }) {
|
|
3095
|
-
return /* @__PURE__ */
|
|
3096
|
-
/* @__PURE__ */
|
|
3409
|
+
return /* @__PURE__ */ jsxs7("div", { className: "doc-controls-sidebar", children: [
|
|
3410
|
+
/* @__PURE__ */ jsx10(
|
|
3097
3411
|
"button",
|
|
3098
3412
|
{
|
|
3099
3413
|
className: "sidebar-ctrl-btn",
|
|
3100
3414
|
onClick: actions.restart,
|
|
3101
3415
|
title: "Restart",
|
|
3102
3416
|
"aria-label": "Restart from beginning",
|
|
3103
|
-
children: /* @__PURE__ */
|
|
3417
|
+
children: /* @__PURE__ */ jsx10("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx10("path", { d: "M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z" }) })
|
|
3104
3418
|
}
|
|
3105
3419
|
),
|
|
3106
|
-
/* @__PURE__ */
|
|
3420
|
+
/* @__PURE__ */ jsx10(
|
|
3107
3421
|
"button",
|
|
3108
3422
|
{
|
|
3109
3423
|
className: "sidebar-ctrl-btn sidebar-play-btn",
|
|
3110
3424
|
onClick: actions.toggle,
|
|
3111
3425
|
"aria-label": state.isPlaying ? "Pause" : "Play",
|
|
3112
|
-
children: state.isPlaying ? /* @__PURE__ */
|
|
3426
|
+
children: state.isPlaying ? /* @__PURE__ */ jsx10("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "22", height: "22", children: /* @__PURE__ */ jsx10("path", { d: "M6 19h4V5H6v14zm8-14v14h4V5h-4z" }) }) : /* @__PURE__ */ jsx10("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "22", height: "22", children: /* @__PURE__ */ jsx10("path", { d: "M8 5v14l11-7z" }) })
|
|
3113
3427
|
}
|
|
3114
3428
|
),
|
|
3115
|
-
/* @__PURE__ */
|
|
3116
|
-
/* @__PURE__ */
|
|
3117
|
-
/* @__PURE__ */
|
|
3429
|
+
/* @__PURE__ */ jsxs7("div", { className: "sidebar-time", children: [
|
|
3430
|
+
/* @__PURE__ */ jsx10("div", { children: formatTime(state.currentTime) }),
|
|
3431
|
+
/* @__PURE__ */ jsx10("div", { className: "sidebar-time-total", children: formatTime(state.totalDuration) })
|
|
3118
3432
|
] }),
|
|
3119
|
-
/* @__PURE__ */
|
|
3433
|
+
/* @__PURE__ */ jsxs7("div", { className: "sidebar-segment", children: [
|
|
3120
3434
|
state.currentBlockIndex + 1,
|
|
3121
3435
|
"/",
|
|
3122
3436
|
state.totalBlocks
|
|
3123
3437
|
] }),
|
|
3124
|
-
state.hasCaptions && /* @__PURE__ */
|
|
3438
|
+
state.hasCaptions && /* @__PURE__ */ jsx10(
|
|
3125
3439
|
"button",
|
|
3126
3440
|
{
|
|
3127
3441
|
className: `sidebar-ctrl-btn ${state.captionMode !== "off" ? "sidebar-ctrl-btn--active" : ""}`,
|
|
3128
3442
|
onClick: () => actions.cycleCaptionMode(),
|
|
3129
3443
|
title: state.captionMode === "off" ? "Captions: Off" : state.captionMode === "standard" ? "Captions: Standard" : "Captions: Social",
|
|
3130
3444
|
"aria-label": "Cycle caption style",
|
|
3131
|
-
children: /* @__PURE__ */
|
|
3445
|
+
children: /* @__PURE__ */ jsx10("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx10("path", { d: "M19 4H5a2 2 0 00-2 2v12a2 2 0 002 2h14a2 2 0 002-2V6a2 2 0 00-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-4a1 1 0 011-1h3a1 1 0 011 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1a1 1 0 01-1 1h-3a1 1 0 01-1-1v-4a1 1 0 011-1h3a1 1 0 011 1v1z" }) })
|
|
3132
3446
|
}
|
|
3133
3447
|
),
|
|
3134
|
-
actions.toggleFullscreen && /* @__PURE__ */
|
|
3448
|
+
actions.toggleFullscreen && /* @__PURE__ */ jsx10(
|
|
3135
3449
|
"button",
|
|
3136
3450
|
{
|
|
3137
3451
|
className: `sidebar-ctrl-btn ${state.isFullscreen ? "sidebar-ctrl-btn--active" : ""}`,
|
|
3138
3452
|
onClick: actions.toggleFullscreen,
|
|
3139
3453
|
title: state.isFullscreen ? "Exit fullscreen (F)" : "Fullscreen (F)",
|
|
3140
3454
|
"aria-label": state.isFullscreen ? "Exit fullscreen" : "Enter fullscreen",
|
|
3141
|
-
children: state.isFullscreen ? /* @__PURE__ */
|
|
3455
|
+
children: state.isFullscreen ? /* @__PURE__ */ jsx10("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx10("path", { d: "M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z" }) }) : /* @__PURE__ */ jsx10("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "20", height: "20", children: /* @__PURE__ */ jsx10("path", { d: "M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" }) })
|
|
3142
3456
|
}
|
|
3143
3457
|
)
|
|
3144
3458
|
] });
|
|
3145
3459
|
}
|
|
3146
3460
|
|
|
3147
3461
|
// src/DocPlayerWithSidebar.tsx
|
|
3148
|
-
import { useRef as
|
|
3149
|
-
import { jsx as
|
|
3462
|
+
import { useRef as useRef7, useState as useState6, useCallback as useCallback5, useEffect as useEffect7 } from "react";
|
|
3463
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3150
3464
|
var DEFAULT_STATE = {
|
|
3151
3465
|
isPlaying: false,
|
|
3152
3466
|
currentTime: 0,
|
|
@@ -3178,9 +3492,9 @@ function DocPlayerWithSidebar({
|
|
|
3178
3492
|
onPlayingChange,
|
|
3179
3493
|
theme
|
|
3180
3494
|
}) {
|
|
3181
|
-
const stateRef =
|
|
3182
|
-
const actionsRef =
|
|
3183
|
-
const wasPlayingRef =
|
|
3495
|
+
const stateRef = useRef7(DEFAULT_STATE);
|
|
3496
|
+
const actionsRef = useRef7(null);
|
|
3497
|
+
const wasPlayingRef = useRef7(false);
|
|
3184
3498
|
const [, setTick] = useState6(0);
|
|
3185
3499
|
const handleStateChange = useCallback5(
|
|
3186
3500
|
(state) => {
|
|
@@ -3201,15 +3515,15 @@ function DocPlayerWithSidebar({
|
|
|
3201
3515
|
},
|
|
3202
3516
|
[]
|
|
3203
3517
|
);
|
|
3204
|
-
|
|
3518
|
+
useEffect7(() => {
|
|
3205
3519
|
const interval = setInterval(() => {
|
|
3206
3520
|
if (!stateRef.current.isPlaying) return;
|
|
3207
3521
|
setTick((t) => t + 1);
|
|
3208
3522
|
}, 250);
|
|
3209
3523
|
return () => clearInterval(interval);
|
|
3210
3524
|
}, []);
|
|
3211
|
-
return /* @__PURE__ */
|
|
3212
|
-
/* @__PURE__ */
|
|
3525
|
+
return /* @__PURE__ */ jsxs8("div", { className: "doc-player-sidebar-layout", children: [
|
|
3526
|
+
/* @__PURE__ */ jsx11("div", { className: "doc-player-sidebar-layout__video", children: /* @__PURE__ */ jsx11(
|
|
3213
3527
|
DocPlayer,
|
|
3214
3528
|
{
|
|
3215
3529
|
doc,
|
|
@@ -3232,7 +3546,7 @@ function DocPlayerWithSidebar({
|
|
|
3232
3546
|
forceViewport
|
|
3233
3547
|
}
|
|
3234
3548
|
) }),
|
|
3235
|
-
actionsRef.current && /* @__PURE__ */
|
|
3549
|
+
actionsRef.current && /* @__PURE__ */ jsx11(DocControlsSidebar, { state: stateRef.current, actions: actionsRef.current })
|
|
3236
3550
|
] });
|
|
3237
3551
|
}
|
|
3238
3552
|
|
|
@@ -3245,6 +3559,7 @@ export {
|
|
|
3245
3559
|
DocProgressBar,
|
|
3246
3560
|
DocControlsOverlay,
|
|
3247
3561
|
DocControlsSlideshow,
|
|
3562
|
+
DashboardView,
|
|
3248
3563
|
resolveDocPlayerAppearance,
|
|
3249
3564
|
DocPlayer,
|
|
3250
3565
|
DocControlsBottom,
|