@papyrus-sdk/ui-react 0.2.20 → 0.2.22
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/LICENSE +21 -0
- package/base.css +2 -2
- package/dist/index.js +491 -68
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +491 -68
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
package/dist/index.mjs
CHANGED
|
@@ -3,6 +3,8 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
import { useViewerStore } from "@papyrus-sdk/core";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
var MOBILE_LANDSCAPE_MAX_HEIGHT_PX = 500;
|
|
7
|
+
var MOBILE_VIEWPORT_QUERY = `(max-width: 639px), (orientation: landscape) and (max-height: ${MOBILE_LANDSCAPE_MAX_HEIGHT_PX}px)`;
|
|
6
8
|
var Topbar = ({
|
|
7
9
|
engine,
|
|
8
10
|
showBrand = false,
|
|
@@ -57,7 +59,7 @@ var Topbar = ({
|
|
|
57
59
|
}, [hasMobileMenu]);
|
|
58
60
|
useEffect(() => {
|
|
59
61
|
if (!canUseDOM || typeof window.matchMedia !== "function") return;
|
|
60
|
-
const mediaQuery = window.matchMedia(
|
|
62
|
+
const mediaQuery = window.matchMedia(MOBILE_VIEWPORT_QUERY);
|
|
61
63
|
const updateViewport = () => setIsMobileViewport(mediaQuery.matches);
|
|
62
64
|
updateViewport();
|
|
63
65
|
if (typeof mediaQuery.addEventListener === "function") {
|
|
@@ -1102,10 +1104,15 @@ var SidebarRight = ({ engine, style }) => {
|
|
|
1102
1104
|
setDocumentState,
|
|
1103
1105
|
triggerScrollToPage,
|
|
1104
1106
|
annotations,
|
|
1105
|
-
accentColor
|
|
1107
|
+
accentColor,
|
|
1108
|
+
updateAnnotation,
|
|
1109
|
+
addAnnotationReply,
|
|
1110
|
+
setSelectedAnnotation
|
|
1106
1111
|
} = useViewerStore3();
|
|
1107
1112
|
const [query, setQuery] = useState3("");
|
|
1108
1113
|
const [isSearching, setIsSearching] = useState3(false);
|
|
1114
|
+
const [contentDrafts, setContentDrafts] = useState3({});
|
|
1115
|
+
const [replyDrafts, setReplyDrafts] = useState3({});
|
|
1109
1116
|
const searchService = new SearchService(engine);
|
|
1110
1117
|
const isDark = uiTheme === "dark";
|
|
1111
1118
|
const accentSoft = withAlpha2(accentColor, 0.12);
|
|
@@ -1121,6 +1128,41 @@ var SidebarRight = ({ engine, style }) => {
|
|
|
1121
1128
|
setSearch(query, results);
|
|
1122
1129
|
setIsSearching(false);
|
|
1123
1130
|
};
|
|
1131
|
+
const jumpToAnnotation = (annotation) => {
|
|
1132
|
+
const page = annotation.pageIndex + 1;
|
|
1133
|
+
engine.goToPage(page);
|
|
1134
|
+
setDocumentState({ currentPage: page });
|
|
1135
|
+
setSelectedAnnotation(annotation.id);
|
|
1136
|
+
triggerScrollToPage(annotation.pageIndex);
|
|
1137
|
+
};
|
|
1138
|
+
const getContentDraft = (annotation) => {
|
|
1139
|
+
if (Object.prototype.hasOwnProperty.call(contentDrafts, annotation.id)) {
|
|
1140
|
+
return contentDrafts[annotation.id];
|
|
1141
|
+
}
|
|
1142
|
+
return annotation.content ?? "";
|
|
1143
|
+
};
|
|
1144
|
+
const updateContentDraft = (annotationId, nextValue) => {
|
|
1145
|
+
setContentDrafts((prev) => ({ ...prev, [annotationId]: nextValue }));
|
|
1146
|
+
};
|
|
1147
|
+
const submitContent = (annotation) => {
|
|
1148
|
+
const nextContent = getContentDraft(annotation).trim();
|
|
1149
|
+
const currentContent = (annotation.content ?? "").trim();
|
|
1150
|
+
if (nextContent === currentContent) return;
|
|
1151
|
+
updateAnnotation(annotation.id, {
|
|
1152
|
+
content: nextContent,
|
|
1153
|
+
updatedAt: Date.now()
|
|
1154
|
+
});
|
|
1155
|
+
};
|
|
1156
|
+
const getReplyDraft = (annotationId) => replyDrafts[annotationId] ?? "";
|
|
1157
|
+
const updateReplyDraft = (annotationId, nextValue) => {
|
|
1158
|
+
setReplyDrafts((prev) => ({ ...prev, [annotationId]: nextValue }));
|
|
1159
|
+
};
|
|
1160
|
+
const submitReply = (annotationId) => {
|
|
1161
|
+
const nextReply = getReplyDraft(annotationId).trim();
|
|
1162
|
+
if (!nextReply) return;
|
|
1163
|
+
addAnnotationReply(annotationId, nextReply);
|
|
1164
|
+
setReplyDrafts((prev) => ({ ...prev, [annotationId]: "" }));
|
|
1165
|
+
};
|
|
1124
1166
|
if (!sidebarRightOpen) return null;
|
|
1125
1167
|
return /* @__PURE__ */ jsxs3(
|
|
1126
1168
|
"div",
|
|
@@ -1322,48 +1364,152 @@ var SidebarRight = ({ engine, style }) => {
|
|
|
1322
1364
|
}
|
|
1323
1365
|
) }),
|
|
1324
1366
|
/* @__PURE__ */ jsx3("p", { className: "text-[10px] font-bold text-gray-400 uppercase tracking-widest", children: "Sem anota\xE7\xF5es" })
|
|
1325
|
-
] }) : annotations.
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1367
|
+
] }) : annotations.slice().sort(
|
|
1368
|
+
(a, b) => (b.updatedAt ?? b.createdAt) - (a.updatedAt ?? a.createdAt)
|
|
1369
|
+
).map((ann) => {
|
|
1370
|
+
const isCommentThread = ann.type === "comment" || ann.type === "text";
|
|
1371
|
+
const replies = ann.replies ?? [];
|
|
1372
|
+
const contentDraft = getContentDraft(ann);
|
|
1373
|
+
const replyDraft = getReplyDraft(ann.id);
|
|
1374
|
+
const hasExistingContent = Boolean((ann.content ?? "").trim());
|
|
1375
|
+
return /* @__PURE__ */ jsxs3(
|
|
1376
|
+
"div",
|
|
1377
|
+
{
|
|
1378
|
+
className: "rounded-xl border p-4 transition-colors",
|
|
1379
|
+
style: {
|
|
1380
|
+
background: "var(--papyrus-surface-2-resolved, var(--papyrus-surface-2, #1f2937))",
|
|
1381
|
+
borderColor: "var(--papyrus-border-resolved, var(--papyrus-border, #374151))",
|
|
1382
|
+
color: "var(--papyrus-text-resolved, var(--papyrus-text, #e5e7eb))"
|
|
1383
|
+
},
|
|
1384
|
+
children: [
|
|
1385
|
+
/* @__PURE__ */ jsxs3("div", { className: "mb-3 flex items-center justify-between", children: [
|
|
1386
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center space-x-2", children: [
|
|
1387
|
+
/* @__PURE__ */ jsx3(
|
|
1388
|
+
"div",
|
|
1389
|
+
{
|
|
1390
|
+
className: "h-2.5 w-2.5 rounded-full",
|
|
1391
|
+
style: { backgroundColor: ann.color }
|
|
1392
|
+
}
|
|
1393
|
+
),
|
|
1394
|
+
/* @__PURE__ */ jsxs3(
|
|
1395
|
+
"span",
|
|
1396
|
+
{
|
|
1397
|
+
className: "text-[10px] font-black uppercase tracking-wide",
|
|
1398
|
+
style: { color: accentColor },
|
|
1399
|
+
children: [
|
|
1400
|
+
"P",
|
|
1401
|
+
ann.pageIndex + 1
|
|
1402
|
+
]
|
|
1403
|
+
}
|
|
1404
|
+
),
|
|
1405
|
+
/* @__PURE__ */ jsx3("span", { className: "text-[10px] font-semibold opacity-70 uppercase tracking-wide", children: ann.type })
|
|
1406
|
+
] }),
|
|
1332
1407
|
/* @__PURE__ */ jsx3(
|
|
1333
|
-
"
|
|
1408
|
+
"button",
|
|
1409
|
+
{
|
|
1410
|
+
type: "button",
|
|
1411
|
+
className: "rounded-md border px-2 py-1 text-[10px] font-semibold uppercase tracking-wide",
|
|
1412
|
+
onClick: () => jumpToAnnotation(ann),
|
|
1413
|
+
style: {
|
|
1414
|
+
borderColor: accentColor,
|
|
1415
|
+
color: accentColor
|
|
1416
|
+
},
|
|
1417
|
+
children: "Ir para pagina"
|
|
1418
|
+
}
|
|
1419
|
+
)
|
|
1420
|
+
] }),
|
|
1421
|
+
isCommentThread ? /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
|
|
1422
|
+
/* @__PURE__ */ jsx3(
|
|
1423
|
+
"textarea",
|
|
1334
1424
|
{
|
|
1335
|
-
className: "w-
|
|
1336
|
-
style: {
|
|
1425
|
+
className: "w-full resize-none rounded-md border p-2 text-xs focus:outline-none",
|
|
1426
|
+
style: {
|
|
1427
|
+
background: "var(--papyrus-surface-resolved, var(--papyrus-surface, #111827))",
|
|
1428
|
+
borderColor: "var(--papyrus-border-resolved, var(--papyrus-border, #374151))",
|
|
1429
|
+
color: "var(--papyrus-text-resolved, var(--papyrus-text, #e5e7eb))"
|
|
1430
|
+
},
|
|
1431
|
+
rows: 3,
|
|
1432
|
+
placeholder: "Escreva seu comentario...",
|
|
1433
|
+
value: contentDraft,
|
|
1434
|
+
onChange: (event) => updateContentDraft(ann.id, event.target.value),
|
|
1435
|
+
onKeyDown: (event) => {
|
|
1436
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
1437
|
+
event.preventDefault();
|
|
1438
|
+
submitContent(ann);
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1337
1441
|
}
|
|
1338
1442
|
),
|
|
1339
|
-
/* @__PURE__ */
|
|
1340
|
-
"
|
|
1443
|
+
/* @__PURE__ */ jsx3("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx3(
|
|
1444
|
+
"button",
|
|
1341
1445
|
{
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1446
|
+
type: "button",
|
|
1447
|
+
className: "rounded-md px-3 py-1.5 text-[11px] font-semibold text-white",
|
|
1448
|
+
style: { backgroundColor: accentColor },
|
|
1449
|
+
onClick: () => submitContent(ann),
|
|
1450
|
+
children: hasExistingContent ? "Atualizar comentario" : "Enviar comentario"
|
|
1451
|
+
}
|
|
1452
|
+
) })
|
|
1453
|
+
] }) : null,
|
|
1454
|
+
replies.length > 0 ? /* @__PURE__ */ jsx3("div", { className: "mt-3 space-y-2", children: replies.map((reply) => /* @__PURE__ */ jsxs3(
|
|
1455
|
+
"div",
|
|
1456
|
+
{
|
|
1457
|
+
className: "rounded-md border p-2",
|
|
1458
|
+
style: {
|
|
1459
|
+
background: "var(--papyrus-surface-resolved, var(--papyrus-surface, #111827))",
|
|
1460
|
+
borderColor: "var(--papyrus-border-resolved, var(--papyrus-border, #374151))"
|
|
1461
|
+
},
|
|
1462
|
+
children: [
|
|
1463
|
+
/* @__PURE__ */ jsx3("p", { className: "text-xs leading-relaxed", children: reply.content }),
|
|
1464
|
+
/* @__PURE__ */ jsx3("p", { className: "mt-1 text-[10px] opacity-70", children: new Date(reply.createdAt).toLocaleTimeString(
|
|
1465
|
+
[],
|
|
1466
|
+
{
|
|
1467
|
+
hour: "2-digit",
|
|
1468
|
+
minute: "2-digit"
|
|
1469
|
+
}
|
|
1470
|
+
) })
|
|
1471
|
+
]
|
|
1472
|
+
},
|
|
1473
|
+
reply.id
|
|
1474
|
+
)) }) : null,
|
|
1475
|
+
isCommentThread ? /* @__PURE__ */ jsxs3("div", { className: "mt-3 flex items-center gap-2", children: [
|
|
1476
|
+
/* @__PURE__ */ jsx3(
|
|
1477
|
+
"input",
|
|
1478
|
+
{
|
|
1479
|
+
type: "text",
|
|
1480
|
+
className: "flex-1 rounded-md border px-2 py-1.5 text-xs focus:outline-none",
|
|
1481
|
+
style: {
|
|
1482
|
+
background: "var(--papyrus-surface-resolved, var(--papyrus-surface, #111827))",
|
|
1483
|
+
borderColor: "var(--papyrus-border-resolved, var(--papyrus-border, #374151))",
|
|
1484
|
+
color: "var(--papyrus-text-resolved, var(--papyrus-text, #e5e7eb))"
|
|
1485
|
+
},
|
|
1486
|
+
value: replyDraft,
|
|
1487
|
+
placeholder: "Responder...",
|
|
1488
|
+
onChange: (event) => updateReplyDraft(ann.id, event.target.value),
|
|
1489
|
+
onKeyDown: (event) => {
|
|
1490
|
+
if (event.key === "Enter") {
|
|
1491
|
+
event.preventDefault();
|
|
1492
|
+
submitReply(ann.id);
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
),
|
|
1497
|
+
/* @__PURE__ */ jsx3(
|
|
1498
|
+
"button",
|
|
1499
|
+
{
|
|
1500
|
+
type: "button",
|
|
1501
|
+
className: "rounded-md px-3 py-1.5 text-[11px] font-semibold text-white",
|
|
1502
|
+
style: { backgroundColor: accentColor },
|
|
1503
|
+
onClick: () => submitReply(ann.id),
|
|
1504
|
+
children: "Responder"
|
|
1348
1505
|
}
|
|
1349
1506
|
)
|
|
1350
|
-
] })
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
/* @__PURE__ */ jsx3(
|
|
1357
|
-
"p",
|
|
1358
|
-
{
|
|
1359
|
-
className: `text-[11px] font-bold uppercase tracking-tight ${isDark ? "text-gray-200" : "text-gray-700"}`,
|
|
1360
|
-
children: ann.type
|
|
1361
|
-
}
|
|
1362
|
-
)
|
|
1363
|
-
]
|
|
1364
|
-
},
|
|
1365
|
-
ann.id
|
|
1366
|
-
))
|
|
1507
|
+
] }) : null
|
|
1508
|
+
]
|
|
1509
|
+
},
|
|
1510
|
+
ann.id
|
|
1511
|
+
);
|
|
1512
|
+
})
|
|
1367
1513
|
] }) })
|
|
1368
1514
|
]
|
|
1369
1515
|
}
|
|
@@ -1393,6 +1539,10 @@ var PageRenderer = ({
|
|
|
1393
1539
|
const canvasRef = useRef3(null);
|
|
1394
1540
|
const htmlLayerRef = useRef3(null);
|
|
1395
1541
|
const textLayerRef = useRef3(null);
|
|
1542
|
+
const skipNextAnnotationSelectRef = useRef3(false);
|
|
1543
|
+
const skipSelectResetTimerRef = useRef3(
|
|
1544
|
+
null
|
|
1545
|
+
);
|
|
1396
1546
|
const [loading, setLoading] = useState4(true);
|
|
1397
1547
|
const [pageSize, setPageSize] = useState4(null);
|
|
1398
1548
|
const [isDragging, setIsDragging] = useState4(false);
|
|
@@ -1410,6 +1560,8 @@ var PageRenderer = ({
|
|
|
1410
1560
|
setDocumentState,
|
|
1411
1561
|
annotations,
|
|
1412
1562
|
addAnnotation,
|
|
1563
|
+
addAnnotationReply,
|
|
1564
|
+
updateAnnotation,
|
|
1413
1565
|
activeTool,
|
|
1414
1566
|
removeAnnotation,
|
|
1415
1567
|
selectedAnnotationId,
|
|
@@ -1433,6 +1585,24 @@ var PageRenderer = ({
|
|
|
1433
1585
|
() => Boolean(searchQuery?.trim()) && searchResults.some((res) => res.pageIndex === pageIndex),
|
|
1434
1586
|
[searchQuery, searchResults, pageIndex]
|
|
1435
1587
|
);
|
|
1588
|
+
const suppressNextAnnotationSelect = () => {
|
|
1589
|
+
skipNextAnnotationSelectRef.current = true;
|
|
1590
|
+
if (skipSelectResetTimerRef.current) {
|
|
1591
|
+
clearTimeout(skipSelectResetTimerRef.current);
|
|
1592
|
+
}
|
|
1593
|
+
skipSelectResetTimerRef.current = setTimeout(() => {
|
|
1594
|
+
skipNextAnnotationSelectRef.current = false;
|
|
1595
|
+
skipSelectResetTimerRef.current = null;
|
|
1596
|
+
}, 0);
|
|
1597
|
+
};
|
|
1598
|
+
useEffect3(
|
|
1599
|
+
() => () => {
|
|
1600
|
+
if (skipSelectResetTimerRef.current) {
|
|
1601
|
+
clearTimeout(skipSelectResetTimerRef.current);
|
|
1602
|
+
}
|
|
1603
|
+
},
|
|
1604
|
+
[]
|
|
1605
|
+
);
|
|
1436
1606
|
useEffect3(() => {
|
|
1437
1607
|
let active = true;
|
|
1438
1608
|
const loadSize = async () => {
|
|
@@ -1602,13 +1772,27 @@ var PageRenderer = ({
|
|
|
1602
1772
|
activeSearchIndex,
|
|
1603
1773
|
textLayerVersion
|
|
1604
1774
|
]);
|
|
1605
|
-
const
|
|
1775
|
+
const getTouchPoint = (event) => {
|
|
1776
|
+
const touch = event.touches[0] ?? event.changedTouches[0];
|
|
1777
|
+
if (!touch) return null;
|
|
1778
|
+
return { x: touch.clientX, y: touch.clientY };
|
|
1779
|
+
};
|
|
1780
|
+
const handlePointerDown = (clientX, clientY, target) => {
|
|
1781
|
+
const clickedInsideAnnotation = Boolean(
|
|
1782
|
+
target?.closest("[data-papyrus-annotation-id]")
|
|
1783
|
+
);
|
|
1784
|
+
const clickedSelectionMenu = Boolean(
|
|
1785
|
+
target?.closest("[data-papyrus-selection-menu]")
|
|
1786
|
+
);
|
|
1787
|
+
if (!clickedInsideAnnotation && !clickedSelectionMenu) {
|
|
1788
|
+
setSelectedAnnotation(null);
|
|
1789
|
+
}
|
|
1606
1790
|
setSelectionMenu(null);
|
|
1607
1791
|
if (activeTool === "ink") {
|
|
1608
1792
|
const rect2 = containerRef.current?.getBoundingClientRect();
|
|
1609
1793
|
if (!rect2) return;
|
|
1610
|
-
const x2 = (
|
|
1611
|
-
const y2 = (
|
|
1794
|
+
const x2 = (clientX - rect2.left) / rect2.width;
|
|
1795
|
+
const y2 = (clientY - rect2.top) / rect2.height;
|
|
1612
1796
|
setIsInkDrawing(true);
|
|
1613
1797
|
setInkPoints([{ x: x2, y: y2 }]);
|
|
1614
1798
|
return;
|
|
@@ -1617,25 +1801,25 @@ var PageRenderer = ({
|
|
|
1617
1801
|
const rect = containerRef.current?.getBoundingClientRect();
|
|
1618
1802
|
if (!rect) return;
|
|
1619
1803
|
setIsDragging(true);
|
|
1620
|
-
const x =
|
|
1621
|
-
const y =
|
|
1804
|
+
const x = clientX - rect.left;
|
|
1805
|
+
const y = clientY - rect.top;
|
|
1622
1806
|
setStartPos({ x, y });
|
|
1623
1807
|
setCurrentRect({ x, y, w: 0, h: 0 });
|
|
1624
1808
|
};
|
|
1625
|
-
const
|
|
1809
|
+
const handlePointerMove = (clientX, clientY) => {
|
|
1626
1810
|
if (isInkDrawing) {
|
|
1627
1811
|
const rect2 = containerRef.current?.getBoundingClientRect();
|
|
1628
1812
|
if (!rect2) return;
|
|
1629
|
-
const x = (
|
|
1630
|
-
const y = (
|
|
1813
|
+
const x = (clientX - rect2.left) / rect2.width;
|
|
1814
|
+
const y = (clientY - rect2.top) / rect2.height;
|
|
1631
1815
|
setInkPoints((prev) => [...prev, { x, y }]);
|
|
1632
1816
|
return;
|
|
1633
1817
|
}
|
|
1634
1818
|
if (!isDragging) return;
|
|
1635
1819
|
const rect = containerRef.current?.getBoundingClientRect();
|
|
1636
1820
|
if (!rect) return;
|
|
1637
|
-
const currentX =
|
|
1638
|
-
const currentY =
|
|
1821
|
+
const currentX = clientX - rect.left;
|
|
1822
|
+
const currentY = clientY - rect.top;
|
|
1639
1823
|
setCurrentRect({
|
|
1640
1824
|
x: Math.min(startPos.x, currentX),
|
|
1641
1825
|
y: Math.min(startPos.y, currentY),
|
|
@@ -1643,7 +1827,7 @@ var PageRenderer = ({
|
|
|
1643
1827
|
h: Math.abs(currentY - startPos.y)
|
|
1644
1828
|
});
|
|
1645
1829
|
};
|
|
1646
|
-
const
|
|
1830
|
+
const handlePointerUp = () => {
|
|
1647
1831
|
if (isInkDrawing) {
|
|
1648
1832
|
setIsInkDrawing(false);
|
|
1649
1833
|
if (inkPoints.length > 1) {
|
|
@@ -1659,6 +1843,7 @@ var PageRenderer = ({
|
|
|
1659
1843
|
x: Math.max(0, Math.min(1, p.x)),
|
|
1660
1844
|
y: Math.max(0, Math.min(1, p.y))
|
|
1661
1845
|
}));
|
|
1846
|
+
suppressNextAnnotationSelect();
|
|
1662
1847
|
addAnnotation({
|
|
1663
1848
|
id: Math.random().toString(36).substr(2, 9),
|
|
1664
1849
|
pageIndex,
|
|
@@ -1739,6 +1924,7 @@ var PageRenderer = ({
|
|
|
1739
1924
|
height: Math.max(...ye) - Math.min(...ys)
|
|
1740
1925
|
};
|
|
1741
1926
|
if (textMarkupTools.has(activeTool)) {
|
|
1927
|
+
suppressNextAnnotationSelect();
|
|
1742
1928
|
addAnnotation({
|
|
1743
1929
|
id: Math.random().toString(36).substr(2, 9),
|
|
1744
1930
|
pageIndex,
|
|
@@ -1774,6 +1960,9 @@ var PageRenderer = ({
|
|
|
1774
1960
|
if (currentRect.w > 5 && currentRect.h > 5) {
|
|
1775
1961
|
const rect = containerRef.current?.getBoundingClientRect();
|
|
1776
1962
|
if (rect) {
|
|
1963
|
+
if (activeTool !== "text" && activeTool !== "comment") {
|
|
1964
|
+
suppressNextAnnotationSelect();
|
|
1965
|
+
}
|
|
1777
1966
|
addAnnotation({
|
|
1778
1967
|
id: Math.random().toString(36).substr(2, 9),
|
|
1779
1968
|
pageIndex,
|
|
@@ -1803,6 +1992,37 @@ var PageRenderer = ({
|
|
|
1803
1992
|
}
|
|
1804
1993
|
}
|
|
1805
1994
|
};
|
|
1995
|
+
const handleMouseDown = (e) => {
|
|
1996
|
+
handlePointerDown(e.clientX, e.clientY, e.target);
|
|
1997
|
+
};
|
|
1998
|
+
const handleMouseMove = (e) => {
|
|
1999
|
+
handlePointerMove(e.clientX, e.clientY);
|
|
2000
|
+
};
|
|
2001
|
+
const handleMouseUp = () => {
|
|
2002
|
+
handlePointerUp();
|
|
2003
|
+
};
|
|
2004
|
+
const handleTouchStart = (event) => {
|
|
2005
|
+
if (event.touches.length > 1) return;
|
|
2006
|
+
const point = getTouchPoint(event);
|
|
2007
|
+
if (!point) return;
|
|
2008
|
+
handlePointerDown(point.x, point.y, event.target);
|
|
2009
|
+
if ((activeTool === "ink" || !canSelectText) && event.cancelable) {
|
|
2010
|
+
event.preventDefault();
|
|
2011
|
+
}
|
|
2012
|
+
};
|
|
2013
|
+
const handleTouchMove = (event) => {
|
|
2014
|
+
if (event.touches.length > 1) return;
|
|
2015
|
+
const point = getTouchPoint(event);
|
|
2016
|
+
if (!point) return;
|
|
2017
|
+
handlePointerMove(point.x, point.y);
|
|
2018
|
+
if ((isInkDrawing || isDragging) && event.cancelable) {
|
|
2019
|
+
event.preventDefault();
|
|
2020
|
+
}
|
|
2021
|
+
};
|
|
2022
|
+
const handleTouchEnd = (event) => {
|
|
2023
|
+
if (event.touches.length > 0) return;
|
|
2024
|
+
handlePointerUp();
|
|
2025
|
+
};
|
|
1806
2026
|
const getPageFilter = () => {
|
|
1807
2027
|
switch (pageTheme) {
|
|
1808
2028
|
case "sepia":
|
|
@@ -1820,10 +2040,18 @@ var PageRenderer = ({
|
|
|
1820
2040
|
{
|
|
1821
2041
|
ref: containerRef,
|
|
1822
2042
|
className: `relative inline-block shadow-2xl bg-white mb-10 ${canSelectText ? "" : "no-select cursor-crosshair"}`,
|
|
1823
|
-
style: {
|
|
2043
|
+
style: {
|
|
2044
|
+
scrollMarginTop: "20px",
|
|
2045
|
+
minHeight: "100px",
|
|
2046
|
+
touchAction: activeTool === "ink" || activeTool === "text" || activeTool === "comment" ? "none" : "auto"
|
|
2047
|
+
},
|
|
1824
2048
|
onMouseDown: handleMouseDown,
|
|
1825
2049
|
onMouseMove: handleMouseMove,
|
|
1826
2050
|
onMouseUp: handleMouseUp,
|
|
2051
|
+
onTouchStart: handleTouchStart,
|
|
2052
|
+
onTouchMove: handleTouchMove,
|
|
2053
|
+
onTouchEnd: handleTouchEnd,
|
|
2054
|
+
onTouchCancel: handleTouchEnd,
|
|
1827
2055
|
children: [
|
|
1828
2056
|
loading && /* @__PURE__ */ jsx4("div", { className: "absolute inset-0 bg-gray-50 flex items-center justify-center z-10 animate-pulse", children: /* @__PURE__ */ jsx4("span", { className: "text-[10px] font-black text-gray-400 uppercase tracking-widest", children: "Sincronizando..." }) }),
|
|
1829
2057
|
/* @__PURE__ */ jsx4(
|
|
@@ -1897,6 +2125,7 @@ var PageRenderer = ({
|
|
|
1897
2125
|
selectionMenu && /* @__PURE__ */ jsx4(
|
|
1898
2126
|
"div",
|
|
1899
2127
|
{
|
|
2128
|
+
"data-papyrus-selection-menu": "true",
|
|
1900
2129
|
className: "absolute z-[60] flex items-center gap-1 rounded-full border px-2 py-1 shadow-xl bg-white/95 backdrop-blur-md text-gray-700",
|
|
1901
2130
|
style: { left: selectionMenu.anchor.x, top: selectionMenu.anchor.y },
|
|
1902
2131
|
children: [
|
|
@@ -1909,6 +2138,7 @@ var PageRenderer = ({
|
|
|
1909
2138
|
{
|
|
1910
2139
|
className: "text-[10px] font-bold px-2 py-1 rounded-full hover:bg-gray-100",
|
|
1911
2140
|
onClick: () => {
|
|
2141
|
+
suppressNextAnnotationSelect();
|
|
1912
2142
|
addAnnotation({
|
|
1913
2143
|
id: Math.random().toString(36).substr(2, 9),
|
|
1914
2144
|
pageIndex,
|
|
@@ -1935,7 +2165,15 @@ var PageRenderer = ({
|
|
|
1935
2165
|
isSelected: selectedAnnotationId === ann.id,
|
|
1936
2166
|
accentColor,
|
|
1937
2167
|
onDelete: () => removeAnnotation(ann.id),
|
|
1938
|
-
onSelect: () =>
|
|
2168
|
+
onSelect: () => {
|
|
2169
|
+
if (skipNextAnnotationSelectRef.current) {
|
|
2170
|
+
skipNextAnnotationSelectRef.current = false;
|
|
2171
|
+
return;
|
|
2172
|
+
}
|
|
2173
|
+
setSelectedAnnotation(ann.id);
|
|
2174
|
+
},
|
|
2175
|
+
onUpdate: (updates) => updateAnnotation(ann.id, updates),
|
|
2176
|
+
onAddReply: (content) => addAnnotationReply(ann.id, content)
|
|
1939
2177
|
},
|
|
1940
2178
|
ann.id
|
|
1941
2179
|
)) })
|
|
@@ -1943,12 +2181,43 @@ var PageRenderer = ({
|
|
|
1943
2181
|
}
|
|
1944
2182
|
);
|
|
1945
2183
|
};
|
|
1946
|
-
var AnnotationItem = ({
|
|
2184
|
+
var AnnotationItem = ({
|
|
2185
|
+
ann,
|
|
2186
|
+
isSelected,
|
|
2187
|
+
accentColor,
|
|
2188
|
+
onDelete,
|
|
2189
|
+
onSelect,
|
|
2190
|
+
onUpdate,
|
|
2191
|
+
onAddReply
|
|
2192
|
+
}) => {
|
|
1947
2193
|
const isText = ann.type === "text" || ann.type === "comment";
|
|
1948
2194
|
const isHighlight = ann.type === "highlight";
|
|
1949
2195
|
const isMarkup = ann.type === "highlight" || ann.type === "underline" || ann.type === "squiggly" || ann.type === "strikeout";
|
|
1950
2196
|
const rects = ann.rects && ann.rects.length > 0 ? ann.rects : [ann.rect];
|
|
1951
2197
|
const isInk = ann.type === "ink" && ann.path && ann.path.length > 1;
|
|
2198
|
+
const [draftContent, setDraftContent] = useState4(ann.content ?? "");
|
|
2199
|
+
const [draftReply, setDraftReply] = useState4("");
|
|
2200
|
+
useEffect3(() => {
|
|
2201
|
+
setDraftContent(ann.content ?? "");
|
|
2202
|
+
}, [ann.id, ann.content]);
|
|
2203
|
+
useEffect3(() => {
|
|
2204
|
+
setDraftReply("");
|
|
2205
|
+
}, [ann.id]);
|
|
2206
|
+
const handleSaveContent = () => {
|
|
2207
|
+
const nextContent = draftContent.trim();
|
|
2208
|
+
const currentContent = (ann.content ?? "").trim();
|
|
2209
|
+
if (nextContent === currentContent) return;
|
|
2210
|
+
onUpdate({
|
|
2211
|
+
content: nextContent,
|
|
2212
|
+
updatedAt: Date.now()
|
|
2213
|
+
});
|
|
2214
|
+
};
|
|
2215
|
+
const handleReplySubmit = () => {
|
|
2216
|
+
const nextReply = draftReply.trim();
|
|
2217
|
+
if (!nextReply) return;
|
|
2218
|
+
onAddReply(nextReply);
|
|
2219
|
+
setDraftReply("");
|
|
2220
|
+
};
|
|
1952
2221
|
const renderMarkupRects = () => {
|
|
1953
2222
|
if (!isMarkup) return null;
|
|
1954
2223
|
return rects.map((r, idx) => {
|
|
@@ -2053,6 +2322,7 @@ var AnnotationItem = ({ ann, isSelected, accentColor, onDelete, onSelect }) => {
|
|
|
2053
2322
|
return /* @__PURE__ */ jsxs4(
|
|
2054
2323
|
"div",
|
|
2055
2324
|
{
|
|
2325
|
+
"data-papyrus-annotation-id": ann.id,
|
|
2056
2326
|
className: `absolute pointer-events-auto transition-all ${isSelected ? "shadow-xl z-30" : "z-10"}`,
|
|
2057
2327
|
style: {
|
|
2058
2328
|
left: `${ann.rect.x * 100}%`,
|
|
@@ -2071,16 +2341,151 @@ var AnnotationItem = ({ ann, isSelected, accentColor, onDelete, onSelect }) => {
|
|
|
2071
2341
|
children: [
|
|
2072
2342
|
renderMarkupRects(),
|
|
2073
2343
|
renderInk(),
|
|
2074
|
-
isText && isSelected && /* @__PURE__ */ jsx4(
|
|
2075
|
-
"
|
|
2344
|
+
isText && !isSelected && /* @__PURE__ */ jsx4(
|
|
2345
|
+
"button",
|
|
2076
2346
|
{
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2347
|
+
type: "button",
|
|
2348
|
+
className: "absolute -top-2 -right-2 h-6 w-6 rounded-full flex items-center justify-center shadow-lg",
|
|
2349
|
+
style: {
|
|
2350
|
+
background: "var(--papyrus-surface-2-resolved, var(--papyrus-surface-2, #1f2937))",
|
|
2351
|
+
border: "1px solid var(--papyrus-border-resolved, #374151)",
|
|
2352
|
+
color: "var(--papyrus-text-resolved, #e5e7eb)"
|
|
2353
|
+
},
|
|
2354
|
+
title: "Abrir comentario",
|
|
2355
|
+
"aria-label": "Abrir comentario",
|
|
2356
|
+
onClick: (event) => {
|
|
2357
|
+
event.stopPropagation();
|
|
2358
|
+
onSelect();
|
|
2359
|
+
},
|
|
2360
|
+
children: /* @__PURE__ */ jsx4(
|
|
2361
|
+
"svg",
|
|
2362
|
+
{
|
|
2363
|
+
className: "h-3.5 w-3.5",
|
|
2364
|
+
fill: "none",
|
|
2365
|
+
stroke: "currentColor",
|
|
2366
|
+
viewBox: "0 0 24 24",
|
|
2367
|
+
children: /* @__PURE__ */ jsx4(
|
|
2368
|
+
"path",
|
|
2369
|
+
{
|
|
2370
|
+
strokeLinecap: "round",
|
|
2371
|
+
strokeLinejoin: "round",
|
|
2372
|
+
strokeWidth: 2,
|
|
2373
|
+
d: "M8 10h.01M12 10h.01M16 10h.01M7 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-4l-4 4v-4z"
|
|
2374
|
+
}
|
|
2375
|
+
)
|
|
2376
|
+
}
|
|
2377
|
+
)
|
|
2082
2378
|
}
|
|
2083
|
-
)
|
|
2379
|
+
),
|
|
2380
|
+
isText && isSelected && /* @__PURE__ */ jsxs4(
|
|
2381
|
+
"div",
|
|
2382
|
+
{
|
|
2383
|
+
className: "absolute top-full mt-2 w-72 rounded-xl p-3 z-50",
|
|
2384
|
+
style: {
|
|
2385
|
+
background: "var(--papyrus-popover-resolved, var(--papyrus-popover, #ffffff))",
|
|
2386
|
+
border: "1px solid var(--papyrus-border-resolved, #d1d5db)",
|
|
2387
|
+
color: "var(--papyrus-text-resolved, #111827)",
|
|
2388
|
+
boxShadow: "0 20px 40px var(--papyrus-shadow-resolved, rgba(0, 0, 0, 0.3))"
|
|
2389
|
+
},
|
|
2390
|
+
onClick: (event) => event.stopPropagation(),
|
|
2391
|
+
children: [
|
|
2392
|
+
/* @__PURE__ */ jsxs4("div", { className: "mb-2 flex items-center justify-between", children: [
|
|
2393
|
+
/* @__PURE__ */ jsx4("span", { className: "text-[10px] font-bold uppercase tracking-wider opacity-70", children: ann.type === "comment" ? "Comentario" : "Nota" }),
|
|
2394
|
+
ann.replies?.length ? /* @__PURE__ */ jsxs4("span", { className: "text-[10px] opacity-70", children: [
|
|
2395
|
+
ann.replies.length,
|
|
2396
|
+
" resposta",
|
|
2397
|
+
ann.replies.length > 1 ? "s" : ""
|
|
2398
|
+
] }) : null
|
|
2399
|
+
] }),
|
|
2400
|
+
/* @__PURE__ */ jsx4(
|
|
2401
|
+
"textarea",
|
|
2402
|
+
{
|
|
2403
|
+
className: "w-full rounded-md border p-2 text-xs font-medium resize-none focus:outline-none",
|
|
2404
|
+
style: {
|
|
2405
|
+
background: "var(--papyrus-surface-resolved, var(--papyrus-surface, #ffffff))",
|
|
2406
|
+
borderColor: "var(--papyrus-border-resolved, #d1d5db)",
|
|
2407
|
+
color: "var(--papyrus-text-resolved, #111827)"
|
|
2408
|
+
},
|
|
2409
|
+
placeholder: "Escreva seu comentario...",
|
|
2410
|
+
rows: 3,
|
|
2411
|
+
value: draftContent,
|
|
2412
|
+
onChange: (event) => setDraftContent(event.target.value),
|
|
2413
|
+
onKeyDown: (event) => {
|
|
2414
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
2415
|
+
event.preventDefault();
|
|
2416
|
+
handleSaveContent();
|
|
2417
|
+
}
|
|
2418
|
+
},
|
|
2419
|
+
autoFocus: true
|
|
2420
|
+
}
|
|
2421
|
+
),
|
|
2422
|
+
/* @__PURE__ */ jsx4("div", { className: "mt-2 flex justify-end", children: /* @__PURE__ */ jsx4(
|
|
2423
|
+
"button",
|
|
2424
|
+
{
|
|
2425
|
+
type: "button",
|
|
2426
|
+
className: "rounded-md px-3 py-1.5 text-[11px] font-semibold text-white",
|
|
2427
|
+
style: { backgroundColor: accentColor },
|
|
2428
|
+
onClick: (event) => {
|
|
2429
|
+
event.stopPropagation();
|
|
2430
|
+
handleSaveContent();
|
|
2431
|
+
},
|
|
2432
|
+
children: (ann.content ?? "").trim() ? "Atualizar" : "Enviar"
|
|
2433
|
+
}
|
|
2434
|
+
) }),
|
|
2435
|
+
ann.replies && ann.replies.length > 0 ? /* @__PURE__ */ jsx4("div", { className: "mt-3 space-y-2", children: ann.replies.map((reply) => /* @__PURE__ */ jsxs4(
|
|
2436
|
+
"div",
|
|
2437
|
+
{
|
|
2438
|
+
className: "rounded-md border p-2",
|
|
2439
|
+
style: {
|
|
2440
|
+
background: "var(--papyrus-surface-resolved, var(--papyrus-surface, #ffffff))",
|
|
2441
|
+
borderColor: "var(--papyrus-border-resolved, #d1d5db)"
|
|
2442
|
+
},
|
|
2443
|
+
children: [
|
|
2444
|
+
/* @__PURE__ */ jsx4("p", { className: "text-xs", children: reply.content }),
|
|
2445
|
+
/* @__PURE__ */ jsx4("p", { className: "mt-1 text-[10px] opacity-70", children: new Date(reply.createdAt).toLocaleTimeString([], {
|
|
2446
|
+
hour: "2-digit",
|
|
2447
|
+
minute: "2-digit"
|
|
2448
|
+
}) })
|
|
2449
|
+
]
|
|
2450
|
+
},
|
|
2451
|
+
reply.id
|
|
2452
|
+
)) }) : null,
|
|
2453
|
+
/* @__PURE__ */ jsxs4("div", { className: "mt-3 flex items-center gap-2", children: [
|
|
2454
|
+
/* @__PURE__ */ jsx4(
|
|
2455
|
+
"input",
|
|
2456
|
+
{
|
|
2457
|
+
type: "text",
|
|
2458
|
+
className: "flex-1 rounded-md border px-2 py-1.5 text-xs focus:outline-none",
|
|
2459
|
+
style: {
|
|
2460
|
+
background: "var(--papyrus-surface-resolved, var(--papyrus-surface, #ffffff))",
|
|
2461
|
+
borderColor: "var(--papyrus-border-resolved, #d1d5db)",
|
|
2462
|
+
color: "var(--papyrus-text-resolved, #111827)"
|
|
2463
|
+
},
|
|
2464
|
+
placeholder: "Responder...",
|
|
2465
|
+
value: draftReply,
|
|
2466
|
+
onChange: (event) => setDraftReply(event.target.value),
|
|
2467
|
+
onKeyDown: (event) => {
|
|
2468
|
+
if (event.key === "Enter") {
|
|
2469
|
+
event.preventDefault();
|
|
2470
|
+
handleReplySubmit();
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
),
|
|
2475
|
+
/* @__PURE__ */ jsx4(
|
|
2476
|
+
"button",
|
|
2477
|
+
{
|
|
2478
|
+
type: "button",
|
|
2479
|
+
className: "rounded-md px-3 py-1.5 text-[11px] font-semibold text-white",
|
|
2480
|
+
style: { backgroundColor: accentColor },
|
|
2481
|
+
onClick: handleReplySubmit,
|
|
2482
|
+
children: "Responder"
|
|
2483
|
+
}
|
|
2484
|
+
)
|
|
2485
|
+
] })
|
|
2486
|
+
]
|
|
2487
|
+
}
|
|
2488
|
+
),
|
|
2084
2489
|
isSelected && /* @__PURE__ */ jsx4(
|
|
2085
2490
|
"button",
|
|
2086
2491
|
{
|
|
@@ -2122,9 +2527,12 @@ var MIN_ZOOM = 0.2;
|
|
|
2122
2527
|
var MAX_ZOOM = 5;
|
|
2123
2528
|
var WIDTH_SNAP_PX = 4;
|
|
2124
2529
|
var WIDTH_HYSTERESIS_PX = 6;
|
|
2530
|
+
var HEIGHT_SNAP_PX = 4;
|
|
2531
|
+
var HEIGHT_HYSTERESIS_PX = 6;
|
|
2125
2532
|
var MOBILE_HEADER_HIDE_DELTA_PX = 28;
|
|
2126
2533
|
var MOBILE_HEADER_SHOW_DELTA_PX = 16;
|
|
2127
2534
|
var MOBILE_HEADER_TOP_RESET_PX = 12;
|
|
2535
|
+
var MOBILE_LANDSCAPE_MAX_HEIGHT_PX2 = 500;
|
|
2128
2536
|
var Viewer = ({ engine, style }) => {
|
|
2129
2537
|
const viewerState = useViewerStore5();
|
|
2130
2538
|
const {
|
|
@@ -2150,6 +2558,7 @@ var Viewer = ({ engine, style }) => {
|
|
|
2150
2558
|
const jumpRef = useRef4(false);
|
|
2151
2559
|
const jumpTimerRef = useRef4(null);
|
|
2152
2560
|
const lastWidthRef = useRef4(null);
|
|
2561
|
+
const lastHeightRef = useRef4(null);
|
|
2153
2562
|
const lastScrollTopRef = useRef4(0);
|
|
2154
2563
|
const scrollDownAccumulatorRef = useRef4(0);
|
|
2155
2564
|
const scrollUpAccumulatorRef = useRef4(0);
|
|
@@ -2163,11 +2572,14 @@ var Viewer = ({ engine, style }) => {
|
|
|
2163
2572
|
rafId: null
|
|
2164
2573
|
});
|
|
2165
2574
|
const [availableWidth, setAvailableWidth] = useState5(null);
|
|
2575
|
+
const [availableHeight, setAvailableHeight] = useState5(null);
|
|
2166
2576
|
const [basePageSize, setBasePageSize] = useState5(null);
|
|
2167
2577
|
const [pageSizes, setPageSizes] = useState5({});
|
|
2168
2578
|
const [colorPickerOpen, setColorPickerOpen] = useState5(false);
|
|
2169
|
-
const
|
|
2170
|
-
const
|
|
2579
|
+
const isLandscape = availableWidth !== null && availableHeight !== null && availableWidth > availableHeight;
|
|
2580
|
+
const isLandscapeShort = isLandscape && availableHeight !== null && availableHeight <= MOBILE_LANDSCAPE_MAX_HEIGHT_PX2;
|
|
2581
|
+
const isCompact = availableWidth !== null && (availableWidth < 820 || isLandscapeShort);
|
|
2582
|
+
const isMobileViewport = availableWidth !== null && (availableWidth < 640 || isLandscapeShort);
|
|
2171
2583
|
const paddingY = isCompact ? "py-10" : "py-16";
|
|
2172
2584
|
const toolDockPosition = isCompact ? "bottom-4" : "bottom-8";
|
|
2173
2585
|
const colorPalette = [
|
|
@@ -2218,21 +2630,32 @@ var Viewer = ({ engine, style }) => {
|
|
|
2218
2630
|
const measurementTarget = viewerElement.parentElement ?? viewerElement;
|
|
2219
2631
|
let rafId = null;
|
|
2220
2632
|
const normalizeWidth = (rawWidth) => Math.max(0, Math.floor(rawWidth / WIDTH_SNAP_PX) * WIDTH_SNAP_PX);
|
|
2221
|
-
const
|
|
2633
|
+
const normalizeHeight = (rawHeight) => Math.max(0, Math.floor(rawHeight / HEIGHT_SNAP_PX) * HEIGHT_SNAP_PX);
|
|
2634
|
+
const updateSize = () => {
|
|
2222
2635
|
const rawWidth = measurementTarget.getBoundingClientRect?.().width ?? measurementTarget.clientWidth ?? measurementTarget.offsetWidth;
|
|
2636
|
+
const rawHeight = measurementTarget.getBoundingClientRect?.().height ?? measurementTarget.clientHeight ?? measurementTarget.offsetHeight;
|
|
2223
2637
|
const nextWidth = normalizeWidth(rawWidth);
|
|
2224
|
-
|
|
2638
|
+
const nextHeight = normalizeHeight(rawHeight);
|
|
2639
|
+
if (nextWidth <= 0 || nextHeight <= 0) return;
|
|
2225
2640
|
const previousWidth = lastWidthRef.current;
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2641
|
+
const previousHeight = lastHeightRef.current;
|
|
2642
|
+
const widthChanged = previousWidth == null || Math.abs(nextWidth - previousWidth) >= WIDTH_HYSTERESIS_PX;
|
|
2643
|
+
const heightChanged = previousHeight == null || Math.abs(nextHeight - previousHeight) >= HEIGHT_HYSTERESIS_PX;
|
|
2644
|
+
if (!widthChanged && !heightChanged) return;
|
|
2645
|
+
if (widthChanged) {
|
|
2646
|
+
lastWidthRef.current = nextWidth;
|
|
2647
|
+
setAvailableWidth(nextWidth);
|
|
2648
|
+
}
|
|
2649
|
+
if (heightChanged) {
|
|
2650
|
+
lastHeightRef.current = nextHeight;
|
|
2651
|
+
setAvailableHeight(nextHeight);
|
|
2652
|
+
}
|
|
2230
2653
|
};
|
|
2231
2654
|
const scheduleWidthUpdate = () => {
|
|
2232
2655
|
if (rafId != null) cancelAnimationFrame(rafId);
|
|
2233
2656
|
rafId = requestAnimationFrame(() => {
|
|
2234
2657
|
rafId = null;
|
|
2235
|
-
|
|
2658
|
+
updateSize();
|
|
2236
2659
|
});
|
|
2237
2660
|
};
|
|
2238
2661
|
scheduleWidthUpdate();
|