pptx-react-viewer 1.0.11 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PowerPointViewer-gSKLhZDo.d.mts → PowerPointViewer-DtLlYf0r.d.mts} +12 -1
- package/dist/{PowerPointViewer-gSKLhZDo.d.ts → PowerPointViewer-DtLlYf0r.d.ts} +12 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1032 -426
- package/dist/index.mjs +1033 -427
- package/dist/pptx-viewer.css +1 -1
- package/dist/viewer/index.d.mts +5 -3
- package/dist/viewer/index.d.ts +5 -3
- package/dist/viewer/index.js +1525 -990
- package/dist/viewer/index.mjs +1526 -991
- package/node_modules/emf-converter/package.json +1 -1
- package/node_modules/mtx-decompressor/package.json +1 -1
- package/node_modules/pptx-viewer-core/package.json +1 -1
- package/package.json +4 -4
package/dist/viewer/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
4
4
|
import * as ReactDOM from 'react-dom/client';
|
|
5
5
|
import { clsx } from 'clsx';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
|
-
import { LuMessageSquare, LuEyeOff, LuSettings, LuX, LuShieldCheck, LuPlus, LuPanelLeftClose, LuStickyNote, LuMonitor, LuColumns2, LuPresentation, LuMinus, LuClock, LuDownload, LuTrash2, LuCheck, LuLock, LuEye, LuFileText, LuType, LuLoader, LuShieldAlert, LuSignature, LuInfo, LuTriangleAlert, LuPrinter, LuPenTool, LuWifi, LuWifiOff, LuUsers, LuCopy, LuMonitorOff, LuChevronLeft, LuChevronRight, LuPlay, LuPause, LuPanelLeft, LuUndo, LuRedo, LuSearch, LuShare2, LuPanelRight, LuFolderOpen, LuVideo, LuImage, LuClipboardPaste, LuScissors, LuPaintbrush, LuChevronDown, LuSquare, LuDatabase, LuLayers, LuAArrowUp, LuAArrowDown, LuRemoveFormatting, LuHighlighter, LuList, LuListOrdered, LuIndentDecrease, LuIndentIncrease, LuChevronUp, LuPalette, LuPencil, LuPaintBucket, LuSparkles,
|
|
7
|
+
import { LuMessageSquare, LuEyeOff, LuSettings, LuX, LuCast, LuShieldCheck, LuPlus, LuPanelLeftClose, LuStickyNote, LuMonitor, LuColumns2, LuPresentation, LuMinus, LuClock, LuDownload, LuTrash2, LuCheck, LuLock, LuEye, LuFileText, LuType, LuLoader, LuShieldAlert, LuSignature, LuInfo, LuTriangleAlert, LuPrinter, LuPenTool, LuWifi, LuWifiOff, LuUsers, LuCopy, LuMonitorOff, LuChevronLeft, LuChevronRight, LuPlay, LuPause, LuPanelLeft, LuUndo, LuRedo, LuSearch, LuShare2, LuPanelRight, LuFolderOpen, LuVideo, LuImage, LuClipboardPaste, LuScissors, LuPaintbrush, LuChevronDown, LuSquare, LuDatabase, LuLayers, LuAArrowUp, LuAArrowDown, LuRemoveFormatting, LuHighlighter, LuList, LuListOrdered, LuIndentDecrease, LuIndentIncrease, LuChevronUp, LuPalette, LuPencil, LuPaintBucket, LuSparkles, LuCaptions, LuSpellCheck, LuGitCompare, LuPipette, LuCaseSensitive, LuReplace, LuTimer, LuMousePointer2, LuEraser, LuGripVertical, LuUpload, LuBold, LuItalic, LuUnderline, LuStrikethrough, LuLink, LuGrid2X2, LuCopyPlus, LuEllipsis, LuCircle, LuMoveRight, LuTriangle, LuDiamond, LuAlignLeft, LuAlignCenter, LuAlignRight, LuAlignJustify, LuSpline, LuSettings2, LuMove, LuRadio, LuArrowDown, LuArrowUp, LuArrowRight, LuArrowLeft, LuReply, LuRotateCw, LuBookmark } from 'react-icons/lu';
|
|
8
8
|
import { hasShapeProperties, hasTextProperties, SWITCHABLE_LAYOUT_TYPES, isCalloutShape, getCalloutLeaderLineGeometry, buildCalloutLeaderLineSvgPath, getCalloutViewBoxBounds, isInkElement, getLinkedTextBoxSegments, isImageLikeElement, getSubstituteFontFamily, PptxHandler, EncryptedFileError, guidePxToEmu, guideEmuToPx, THEME_COLOR_SCHEME_KEYS, hslToRgb, PRESET_COLOR_MAP, elementActionToPptxAction, mergeShapes, SvgExporter, applyDrawingColorTransforms as applyDrawingColorTransforms$1, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, EMU_PER_PX as EMU_PER_PX$1, chartDataChangeType, chartDataUpdatePoint, chartDataAddCategory, chartDataRemoveCategory, chartDataAddSeries, chartDataRemoveSeries, getOleObjectTypeLabel, pptxActionToElementAction, hasNonTrivialOverride, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, addSmartArtNodeAsChild, updateSmartArtNodeText, removeSmartArtNode, switchSmartArtLayout, applyThemeToData, THEME_PRESETS } from 'pptx-viewer-core';
|
|
9
9
|
import { useTranslation } from 'react-i18next';
|
|
10
10
|
import html2canvasPro from 'html2canvas-pro';
|
|
@@ -43302,7 +43302,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43302
43302
|
return x2 === y && (0 !== x2 || 1 / x2 === 1 / y) || x2 !== x2 && y !== y;
|
|
43303
43303
|
}
|
|
43304
43304
|
function useSyncExternalStore$2(subscribe3, getSnapshot2) {
|
|
43305
|
-
didWarnOld18Alpha || void 0 ===
|
|
43305
|
+
didWarnOld18Alpha || void 0 === React96.startTransition || (didWarnOld18Alpha = true, console.error(
|
|
43306
43306
|
"You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."
|
|
43307
43307
|
));
|
|
43308
43308
|
var value = getSnapshot2();
|
|
@@ -43312,7 +43312,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43312
43312
|
"The result of getSnapshot should be cached to avoid an infinite loop"
|
|
43313
43313
|
), didWarnUncachedGetSnapshot = true);
|
|
43314
43314
|
}
|
|
43315
|
-
cachedValue =
|
|
43315
|
+
cachedValue = useState85({
|
|
43316
43316
|
inst: { value, getSnapshot: getSnapshot2 }
|
|
43317
43317
|
});
|
|
43318
43318
|
var inst = cachedValue[0].inst, forceUpdate = cachedValue[1];
|
|
@@ -43324,7 +43324,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43324
43324
|
},
|
|
43325
43325
|
[subscribe3, value, getSnapshot2]
|
|
43326
43326
|
);
|
|
43327
|
-
|
|
43327
|
+
useEffect71(
|
|
43328
43328
|
function() {
|
|
43329
43329
|
checkIfSnapshotChanged(inst) && forceUpdate({ inst });
|
|
43330
43330
|
return subscribe3(function() {
|
|
@@ -43350,8 +43350,8 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43350
43350
|
return getSnapshot2();
|
|
43351
43351
|
}
|
|
43352
43352
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
43353
|
-
var
|
|
43354
|
-
exports$1.useSyncExternalStore = void 0 !==
|
|
43353
|
+
var React96 = __require("react"), objectIs = "function" === typeof Object.is ? Object.is : is2, useState85 = React96.useState, useEffect71 = React96.useEffect, useLayoutEffect7 = React96.useLayoutEffect, useDebugValue = React96.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
|
|
43354
|
+
exports$1.useSyncExternalStore = void 0 !== React96.useSyncExternalStore ? React96.useSyncExternalStore : shim;
|
|
43355
43355
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
43356
43356
|
})();
|
|
43357
43357
|
}
|
|
@@ -43374,9 +43374,9 @@ var require_with_selector_development = __commonJS({
|
|
|
43374
43374
|
return x2 === y && (0 !== x2 || 1 / x2 === 1 / y) || x2 !== x2 && y !== y;
|
|
43375
43375
|
}
|
|
43376
43376
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
43377
|
-
var
|
|
43377
|
+
var React96 = __require("react"), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is2, useSyncExternalStore3 = shim.useSyncExternalStore, useRef72 = React96.useRef, useEffect71 = React96.useEffect, useMemo42 = React96.useMemo, useDebugValue = React96.useDebugValue;
|
|
43378
43378
|
exports$1.useSyncExternalStoreWithSelector = function(subscribe3, getSnapshot2, getServerSnapshot2, selector, isEqual) {
|
|
43379
|
-
var instRef =
|
|
43379
|
+
var instRef = useRef72(null);
|
|
43380
43380
|
if (null === instRef.current) {
|
|
43381
43381
|
var inst = { hasValue: false, value: null };
|
|
43382
43382
|
instRef.current = inst;
|
|
@@ -43417,7 +43417,7 @@ var require_with_selector_development = __commonJS({
|
|
|
43417
43417
|
[getSnapshot2, getServerSnapshot2, selector, isEqual]
|
|
43418
43418
|
);
|
|
43419
43419
|
var value = useSyncExternalStore3(subscribe3, instRef[0], instRef[1]);
|
|
43420
|
-
|
|
43420
|
+
useEffect71(
|
|
43421
43421
|
function() {
|
|
43422
43422
|
inst.hasValue = true;
|
|
43423
43423
|
inst.value = value;
|
|
@@ -91091,6 +91091,637 @@ function useVirtualizedSlides({
|
|
|
91091
91091
|
scrollToIndex
|
|
91092
91092
|
};
|
|
91093
91093
|
}
|
|
91094
|
+
|
|
91095
|
+
// src/viewer/hooks/collaboration/sanitize.ts
|
|
91096
|
+
var ROOM_ID_REGEX = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
91097
|
+
function validateRoomId(roomId) {
|
|
91098
|
+
if (!ROOM_ID_REGEX.test(roomId)) {
|
|
91099
|
+
throw new Error(
|
|
91100
|
+
`Invalid collaboration room ID: "${roomId}". Must be 1-128 alphanumeric characters, hyphens, or underscores.`
|
|
91101
|
+
);
|
|
91102
|
+
}
|
|
91103
|
+
return roomId;
|
|
91104
|
+
}
|
|
91105
|
+
function sanitizeUserName(name) {
|
|
91106
|
+
if (typeof name !== "string") {
|
|
91107
|
+
return "Anonymous";
|
|
91108
|
+
}
|
|
91109
|
+
const stripped = name.replace(/<[^>]*>/g, "");
|
|
91110
|
+
const trimmed = stripped.trim().slice(0, 64);
|
|
91111
|
+
return trimmed || "Anonymous";
|
|
91112
|
+
}
|
|
91113
|
+
function clampCursorPosition(value, min2, max2) {
|
|
91114
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
91115
|
+
return 0;
|
|
91116
|
+
}
|
|
91117
|
+
const margin = 20;
|
|
91118
|
+
return Math.max(min2 - margin, Math.min(max2 + margin, value));
|
|
91119
|
+
}
|
|
91120
|
+
var HEX_COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
|
|
91121
|
+
function sanitizeColor(color, fallback = "#6366f1") {
|
|
91122
|
+
if (typeof color !== "string") {
|
|
91123
|
+
return fallback;
|
|
91124
|
+
}
|
|
91125
|
+
return HEX_COLOR_REGEX.test(color) ? color : fallback;
|
|
91126
|
+
}
|
|
91127
|
+
function sanitizeAvatarUrl(url) {
|
|
91128
|
+
if (typeof url !== "string") {
|
|
91129
|
+
return void 0;
|
|
91130
|
+
}
|
|
91131
|
+
try {
|
|
91132
|
+
const parsed = new URL(url);
|
|
91133
|
+
if (parsed.protocol === "https:" || parsed.protocol === "http:" || parsed.protocol === "data:") {
|
|
91134
|
+
return url;
|
|
91135
|
+
}
|
|
91136
|
+
} catch {
|
|
91137
|
+
}
|
|
91138
|
+
return void 0;
|
|
91139
|
+
}
|
|
91140
|
+
function sanitizeSlideIndex(value) {
|
|
91141
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
91142
|
+
return 0;
|
|
91143
|
+
}
|
|
91144
|
+
return Math.max(0, Math.floor(value));
|
|
91145
|
+
}
|
|
91146
|
+
function sanitizePresence(raw, canvasWidth, canvasHeight) {
|
|
91147
|
+
if (typeof raw.clientId !== "number") {
|
|
91148
|
+
return null;
|
|
91149
|
+
}
|
|
91150
|
+
return {
|
|
91151
|
+
clientId: raw.clientId,
|
|
91152
|
+
userName: sanitizeUserName(raw.userName),
|
|
91153
|
+
userAvatar: sanitizeAvatarUrl(raw.userAvatar),
|
|
91154
|
+
userColor: sanitizeColor(raw.userColor),
|
|
91155
|
+
activeSlideIndex: sanitizeSlideIndex(raw.activeSlideIndex),
|
|
91156
|
+
cursorX: clampCursorPosition(raw.cursorX, 0, canvasWidth),
|
|
91157
|
+
cursorY: clampCursorPosition(raw.cursorY, 0, canvasHeight),
|
|
91158
|
+
lastUpdated: typeof raw.lastUpdated === "string" ? raw.lastUpdated : (/* @__PURE__ */ new Date()).toISOString(),
|
|
91159
|
+
selectedElementId: typeof raw.selectedElementId === "string" ? raw.selectedElementId.slice(0, 128) : void 0,
|
|
91160
|
+
role: raw.role === "broadcaster" || raw.role === "viewer" || raw.role === "collaborator" ? raw.role : void 0
|
|
91161
|
+
};
|
|
91162
|
+
}
|
|
91163
|
+
var BROADCAST_THROTTLE_MS = 50;
|
|
91164
|
+
var STALE_PRESENCE_MS = 3e4;
|
|
91165
|
+
function usePresenceTracking({
|
|
91166
|
+
awareness,
|
|
91167
|
+
localClientId,
|
|
91168
|
+
userName,
|
|
91169
|
+
userColor,
|
|
91170
|
+
userAvatar,
|
|
91171
|
+
role,
|
|
91172
|
+
canvasWidth,
|
|
91173
|
+
canvasHeight
|
|
91174
|
+
}) {
|
|
91175
|
+
const [remoteUsers, setRemoteUsers] = useState([]);
|
|
91176
|
+
const lastBroadcastRef = useRef(0);
|
|
91177
|
+
const pendingBroadcastRef = useRef(null);
|
|
91178
|
+
const latestLocalState = useRef({});
|
|
91179
|
+
const broadcastPresence = useCallback(
|
|
91180
|
+
(update2) => {
|
|
91181
|
+
if (!awareness) {
|
|
91182
|
+
return;
|
|
91183
|
+
}
|
|
91184
|
+
Object.assign(latestLocalState.current, update2);
|
|
91185
|
+
const now = Date.now();
|
|
91186
|
+
const elapsed = now - lastBroadcastRef.current;
|
|
91187
|
+
const flush = () => {
|
|
91188
|
+
const state2 = {
|
|
91189
|
+
...latestLocalState.current,
|
|
91190
|
+
userName,
|
|
91191
|
+
userColor,
|
|
91192
|
+
userAvatar,
|
|
91193
|
+
role,
|
|
91194
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
91195
|
+
};
|
|
91196
|
+
awareness.setLocalStateField("presence", state2);
|
|
91197
|
+
lastBroadcastRef.current = Date.now();
|
|
91198
|
+
};
|
|
91199
|
+
if (elapsed >= BROADCAST_THROTTLE_MS) {
|
|
91200
|
+
if (pendingBroadcastRef.current) {
|
|
91201
|
+
clearTimeout(pendingBroadcastRef.current);
|
|
91202
|
+
pendingBroadcastRef.current = null;
|
|
91203
|
+
}
|
|
91204
|
+
flush();
|
|
91205
|
+
} else if (!pendingBroadcastRef.current) {
|
|
91206
|
+
pendingBroadcastRef.current = setTimeout(() => {
|
|
91207
|
+
pendingBroadcastRef.current = null;
|
|
91208
|
+
flush();
|
|
91209
|
+
}, BROADCAST_THROTTLE_MS - elapsed);
|
|
91210
|
+
}
|
|
91211
|
+
},
|
|
91212
|
+
[awareness, userName, userColor, userAvatar, role]
|
|
91213
|
+
);
|
|
91214
|
+
useEffect(() => {
|
|
91215
|
+
if (!awareness) {
|
|
91216
|
+
return;
|
|
91217
|
+
}
|
|
91218
|
+
awareness.setLocalStateField("presence", {
|
|
91219
|
+
userName,
|
|
91220
|
+
userColor,
|
|
91221
|
+
userAvatar,
|
|
91222
|
+
role,
|
|
91223
|
+
activeSlideIndex: 0,
|
|
91224
|
+
cursorX: 0,
|
|
91225
|
+
cursorY: 0,
|
|
91226
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
91227
|
+
});
|
|
91228
|
+
}, [awareness, userName, userColor, userAvatar, role]);
|
|
91229
|
+
useEffect(() => {
|
|
91230
|
+
if (!awareness || localClientId === null) {
|
|
91231
|
+
return;
|
|
91232
|
+
}
|
|
91233
|
+
const handleChange = () => {
|
|
91234
|
+
const now = Date.now();
|
|
91235
|
+
const states = awareness.getStates();
|
|
91236
|
+
const users = [];
|
|
91237
|
+
states.forEach((state2, cid) => {
|
|
91238
|
+
if (cid === localClientId) {
|
|
91239
|
+
return;
|
|
91240
|
+
}
|
|
91241
|
+
const raw = state2?.presence;
|
|
91242
|
+
if (!raw || typeof raw !== "object") {
|
|
91243
|
+
return;
|
|
91244
|
+
}
|
|
91245
|
+
const sanitized = sanitizePresence({ ...raw, clientId: cid }, canvasWidth, canvasHeight);
|
|
91246
|
+
if (!sanitized) {
|
|
91247
|
+
return;
|
|
91248
|
+
}
|
|
91249
|
+
const updatedAt = new Date(sanitized.lastUpdated).getTime();
|
|
91250
|
+
if (Number.isNaN(updatedAt) || now - updatedAt > STALE_PRESENCE_MS) {
|
|
91251
|
+
return;
|
|
91252
|
+
}
|
|
91253
|
+
users.push(sanitized);
|
|
91254
|
+
});
|
|
91255
|
+
setRemoteUsers(users);
|
|
91256
|
+
};
|
|
91257
|
+
awareness.on("change", handleChange);
|
|
91258
|
+
awareness.on("update", handleChange);
|
|
91259
|
+
handleChange();
|
|
91260
|
+
return () => {
|
|
91261
|
+
awareness.off("change", handleChange);
|
|
91262
|
+
awareness.off("update", handleChange);
|
|
91263
|
+
};
|
|
91264
|
+
}, [awareness, localClientId, canvasWidth, canvasHeight]);
|
|
91265
|
+
useEffect(() => {
|
|
91266
|
+
if (!awareness) {
|
|
91267
|
+
return;
|
|
91268
|
+
}
|
|
91269
|
+
const interval = setInterval(() => {
|
|
91270
|
+
awareness.setLocalStateField("presence", {
|
|
91271
|
+
...latestLocalState.current,
|
|
91272
|
+
userName,
|
|
91273
|
+
userColor,
|
|
91274
|
+
userAvatar,
|
|
91275
|
+
role,
|
|
91276
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
91277
|
+
});
|
|
91278
|
+
}, 1e4);
|
|
91279
|
+
return () => clearInterval(interval);
|
|
91280
|
+
}, [awareness, userName, userColor, userAvatar, role]);
|
|
91281
|
+
useEffect(() => {
|
|
91282
|
+
return () => {
|
|
91283
|
+
if (pendingBroadcastRef.current) {
|
|
91284
|
+
clearTimeout(pendingBroadcastRef.current);
|
|
91285
|
+
}
|
|
91286
|
+
};
|
|
91287
|
+
}, []);
|
|
91288
|
+
return { remoteUsers, broadcastPresence };
|
|
91289
|
+
}
|
|
91290
|
+
function useYjsProvider({ config }) {
|
|
91291
|
+
const [status, setStatus] = useState("disconnected");
|
|
91292
|
+
const [awareness, setAwareness] = useState(null);
|
|
91293
|
+
const [doc2, setDoc] = useState(null);
|
|
91294
|
+
const [clientId, setClientId] = useState(null);
|
|
91295
|
+
const cleanupRef = useRef(null);
|
|
91296
|
+
const init = useCallback(async () => {
|
|
91297
|
+
const roomId = validateRoomId(config.roomId);
|
|
91298
|
+
setStatus("connecting");
|
|
91299
|
+
try {
|
|
91300
|
+
const [Y, { WebsocketProvider: WebsocketProvider2 }] = await Promise.all([Promise.resolve().then(() => (init_yjs(), yjs_exports)), Promise.resolve().then(() => (init_y_websocket(), y_websocket_exports))]);
|
|
91301
|
+
const yDoc = new Y.Doc();
|
|
91302
|
+
const provider = new WebsocketProvider2(
|
|
91303
|
+
config.serverUrl,
|
|
91304
|
+
roomId,
|
|
91305
|
+
yDoc,
|
|
91306
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
91307
|
+
{
|
|
91308
|
+
params: config.authToken ? { token: config.authToken } : void 0
|
|
91309
|
+
}
|
|
91310
|
+
);
|
|
91311
|
+
const handleStatus = (event) => {
|
|
91312
|
+
if (event.status === "connected") {
|
|
91313
|
+
setStatus("connected");
|
|
91314
|
+
} else if (event.status === "disconnected") {
|
|
91315
|
+
setStatus("disconnected");
|
|
91316
|
+
}
|
|
91317
|
+
};
|
|
91318
|
+
provider.on("status", handleStatus);
|
|
91319
|
+
if (provider.wsconnected) {
|
|
91320
|
+
setStatus("connected");
|
|
91321
|
+
}
|
|
91322
|
+
setDoc(yDoc);
|
|
91323
|
+
setAwareness(provider.awareness);
|
|
91324
|
+
setClientId(provider.awareness.clientID);
|
|
91325
|
+
cleanupRef.current = () => {
|
|
91326
|
+
provider.off("status", handleStatus);
|
|
91327
|
+
provider.destroy();
|
|
91328
|
+
yDoc.destroy();
|
|
91329
|
+
setDoc(null);
|
|
91330
|
+
setAwareness(null);
|
|
91331
|
+
setClientId(null);
|
|
91332
|
+
setStatus("disconnected");
|
|
91333
|
+
};
|
|
91334
|
+
} catch (err) {
|
|
91335
|
+
console.warn(
|
|
91336
|
+
"[pptx-viewer] Collaboration packages not available:",
|
|
91337
|
+
err instanceof Error ? err.message : err
|
|
91338
|
+
);
|
|
91339
|
+
setStatus("error");
|
|
91340
|
+
}
|
|
91341
|
+
}, [config.roomId, config.serverUrl, config.authToken]);
|
|
91342
|
+
useEffect(() => {
|
|
91343
|
+
init();
|
|
91344
|
+
return () => {
|
|
91345
|
+
cleanupRef.current?.();
|
|
91346
|
+
cleanupRef.current = null;
|
|
91347
|
+
};
|
|
91348
|
+
}, [init]);
|
|
91349
|
+
return { status, awareness, doc: doc2, clientId };
|
|
91350
|
+
}
|
|
91351
|
+
|
|
91352
|
+
// src/viewer/hooks/collaboration/useCollaborativeState.ts
|
|
91353
|
+
function useCollaborativeState({
|
|
91354
|
+
config,
|
|
91355
|
+
canvasWidth,
|
|
91356
|
+
canvasHeight
|
|
91357
|
+
}) {
|
|
91358
|
+
const userColor = sanitizeColor(config.userColor, "#6366f1");
|
|
91359
|
+
const { status, awareness, doc: doc2, clientId } = useYjsProvider({ config });
|
|
91360
|
+
const { remoteUsers, broadcastPresence } = usePresenceTracking({
|
|
91361
|
+
awareness,
|
|
91362
|
+
localClientId: clientId,
|
|
91363
|
+
userName: config.userName,
|
|
91364
|
+
userColor,
|
|
91365
|
+
userAvatar: config.userAvatar,
|
|
91366
|
+
role: config.role,
|
|
91367
|
+
canvasWidth,
|
|
91368
|
+
canvasHeight
|
|
91369
|
+
});
|
|
91370
|
+
const connectedCount = status === "connected" ? remoteUsers.length + 1 : remoteUsers.length;
|
|
91371
|
+
return {
|
|
91372
|
+
status,
|
|
91373
|
+
remoteUsers,
|
|
91374
|
+
broadcastPresence,
|
|
91375
|
+
connectedCount,
|
|
91376
|
+
config,
|
|
91377
|
+
doc: doc2
|
|
91378
|
+
};
|
|
91379
|
+
}
|
|
91380
|
+
var CollaborationContext = createContext(null);
|
|
91381
|
+
function useCollaboration() {
|
|
91382
|
+
return useContext(CollaborationContext);
|
|
91383
|
+
}
|
|
91384
|
+
function CollaborationProvider({
|
|
91385
|
+
config,
|
|
91386
|
+
canvasWidth,
|
|
91387
|
+
canvasHeight,
|
|
91388
|
+
children
|
|
91389
|
+
}) {
|
|
91390
|
+
const value = useCollaborativeState({
|
|
91391
|
+
config,
|
|
91392
|
+
canvasWidth,
|
|
91393
|
+
canvasHeight
|
|
91394
|
+
});
|
|
91395
|
+
return /* @__PURE__ */ jsx(CollaborationContext.Provider, { value, children });
|
|
91396
|
+
}
|
|
91397
|
+
function RemoteUserCursors({
|
|
91398
|
+
remoteUsers,
|
|
91399
|
+
activeSlideIndex,
|
|
91400
|
+
canvasWidth,
|
|
91401
|
+
canvasHeight
|
|
91402
|
+
}) {
|
|
91403
|
+
const visibleUsers = remoteUsers.filter((u2) => u2.activeSlideIndex === activeSlideIndex);
|
|
91404
|
+
if (visibleUsers.length === 0) {
|
|
91405
|
+
return null;
|
|
91406
|
+
}
|
|
91407
|
+
return /* @__PURE__ */ jsx(
|
|
91408
|
+
"svg",
|
|
91409
|
+
{
|
|
91410
|
+
"data-testid": "remote-user-cursors",
|
|
91411
|
+
"data-export-ignore": "true",
|
|
91412
|
+
className: "absolute inset-0 pointer-events-none",
|
|
91413
|
+
style: { zIndex: 9999 },
|
|
91414
|
+
width: canvasWidth,
|
|
91415
|
+
height: canvasHeight,
|
|
91416
|
+
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
91417
|
+
"aria-hidden": "true",
|
|
91418
|
+
children: visibleUsers.map((user) => /* @__PURE__ */ jsxs(
|
|
91419
|
+
"g",
|
|
91420
|
+
{
|
|
91421
|
+
transform: `translate(${user.cursorX}, ${user.cursorY})`,
|
|
91422
|
+
"data-testid": `remote-cursor-${user.clientId}`,
|
|
91423
|
+
children: [
|
|
91424
|
+
/* @__PURE__ */ jsx(
|
|
91425
|
+
"path",
|
|
91426
|
+
{
|
|
91427
|
+
d: "M0 0 L0 16 L4.5 12.5 L8 20 L10.5 19 L7 11.5 L12 11 Z",
|
|
91428
|
+
fill: user.userColor,
|
|
91429
|
+
stroke: "#fff",
|
|
91430
|
+
strokeWidth: 1,
|
|
91431
|
+
opacity: 0.9
|
|
91432
|
+
}
|
|
91433
|
+
),
|
|
91434
|
+
/* @__PURE__ */ jsxs("g", { transform: "translate(14, 18)", children: [
|
|
91435
|
+
/* @__PURE__ */ jsx(
|
|
91436
|
+
"rect",
|
|
91437
|
+
{
|
|
91438
|
+
rx: 3,
|
|
91439
|
+
ry: 3,
|
|
91440
|
+
x: -2,
|
|
91441
|
+
y: -10,
|
|
91442
|
+
width: Math.min(user.userName.length * 7 + 8, 150),
|
|
91443
|
+
height: 16,
|
|
91444
|
+
fill: user.userColor,
|
|
91445
|
+
opacity: 0.85
|
|
91446
|
+
}
|
|
91447
|
+
),
|
|
91448
|
+
/* @__PURE__ */ jsx(
|
|
91449
|
+
"text",
|
|
91450
|
+
{
|
|
91451
|
+
fill: "#fff",
|
|
91452
|
+
fontSize: 10,
|
|
91453
|
+
fontFamily: "system-ui, sans-serif",
|
|
91454
|
+
fontWeight: 500,
|
|
91455
|
+
dominantBaseline: "central",
|
|
91456
|
+
y: -2,
|
|
91457
|
+
x: 2,
|
|
91458
|
+
children: user.userName.length > 20 ? `${user.userName.slice(0, 18)}...` : user.userName
|
|
91459
|
+
}
|
|
91460
|
+
)
|
|
91461
|
+
] })
|
|
91462
|
+
]
|
|
91463
|
+
},
|
|
91464
|
+
user.clientId
|
|
91465
|
+
))
|
|
91466
|
+
}
|
|
91467
|
+
);
|
|
91468
|
+
}
|
|
91469
|
+
function getInitials(name) {
|
|
91470
|
+
const parts = name.trim().split(/\s+/);
|
|
91471
|
+
if (parts.length >= 2) {
|
|
91472
|
+
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
91473
|
+
}
|
|
91474
|
+
return name.slice(0, 2).toUpperCase();
|
|
91475
|
+
}
|
|
91476
|
+
function AvatarCircle({
|
|
91477
|
+
name,
|
|
91478
|
+
color,
|
|
91479
|
+
avatar,
|
|
91480
|
+
isLocal
|
|
91481
|
+
}) {
|
|
91482
|
+
const { t: t2 } = useTranslation();
|
|
91483
|
+
const initials = getInitials(name);
|
|
91484
|
+
const title = isLocal ? t2("pptx.collaboration.youLabel", { name }) : name;
|
|
91485
|
+
return /* @__PURE__ */ jsx(
|
|
91486
|
+
"div",
|
|
91487
|
+
{
|
|
91488
|
+
className: "relative w-7 h-7 rounded-full flex items-center justify-center text-[10px] font-semibold text-white border-2 -ml-1 first:ml-0",
|
|
91489
|
+
style: {
|
|
91490
|
+
backgroundColor: color,
|
|
91491
|
+
borderColor: isLocal ? "#fff" : color
|
|
91492
|
+
},
|
|
91493
|
+
title,
|
|
91494
|
+
"aria-label": title,
|
|
91495
|
+
children: avatar ? /* @__PURE__ */ jsx(
|
|
91496
|
+
"img",
|
|
91497
|
+
{
|
|
91498
|
+
src: avatar,
|
|
91499
|
+
alt: "",
|
|
91500
|
+
className: "w-full h-full rounded-full object-cover",
|
|
91501
|
+
onError: (e2) => {
|
|
91502
|
+
e2.target.style.display = "none";
|
|
91503
|
+
}
|
|
91504
|
+
}
|
|
91505
|
+
) : initials
|
|
91506
|
+
}
|
|
91507
|
+
);
|
|
91508
|
+
}
|
|
91509
|
+
function UserAvatarBar({
|
|
91510
|
+
remoteUsers,
|
|
91511
|
+
localUserName,
|
|
91512
|
+
localUserColor,
|
|
91513
|
+
localUserAvatar,
|
|
91514
|
+
status,
|
|
91515
|
+
maxVisible = 5
|
|
91516
|
+
}) {
|
|
91517
|
+
const { t: t2 } = useTranslation();
|
|
91518
|
+
if (status === "disconnected" || status === "error") {
|
|
91519
|
+
return null;
|
|
91520
|
+
}
|
|
91521
|
+
const allUsers = [
|
|
91522
|
+
{ name: localUserName, color: localUserColor, avatar: localUserAvatar, isLocal: true },
|
|
91523
|
+
...remoteUsers.map((u2) => ({
|
|
91524
|
+
name: u2.userName,
|
|
91525
|
+
color: u2.userColor,
|
|
91526
|
+
avatar: u2.userAvatar,
|
|
91527
|
+
isLocal: false
|
|
91528
|
+
}))
|
|
91529
|
+
];
|
|
91530
|
+
const visible = allUsers.slice(0, maxVisible);
|
|
91531
|
+
const overflow = allUsers.length - maxVisible;
|
|
91532
|
+
return /* @__PURE__ */ jsxs(
|
|
91533
|
+
"div",
|
|
91534
|
+
{
|
|
91535
|
+
"data-testid": "user-avatar-bar",
|
|
91536
|
+
className: "flex items-center px-2",
|
|
91537
|
+
"aria-label": t2("pptx.collaboration.usersConnected", { count: allUsers.length }),
|
|
91538
|
+
children: [
|
|
91539
|
+
visible.map((user, i3) => /* @__PURE__ */ jsx(
|
|
91540
|
+
AvatarCircle,
|
|
91541
|
+
{
|
|
91542
|
+
name: user.name,
|
|
91543
|
+
color: user.color,
|
|
91544
|
+
avatar: user.avatar,
|
|
91545
|
+
isLocal: user.isLocal
|
|
91546
|
+
},
|
|
91547
|
+
user.isLocal ? "local" : `remote-${i3}`
|
|
91548
|
+
)),
|
|
91549
|
+
overflow > 0 && /* @__PURE__ */ jsxs(
|
|
91550
|
+
"div",
|
|
91551
|
+
{
|
|
91552
|
+
className: "w-7 h-7 rounded-full flex items-center justify-center text-[10px] font-semibold text-gray-300 bg-gray-700 border-2 border-gray-600 -ml-1",
|
|
91553
|
+
title: t2("pptx.collaboration.moreUsers", { count: overflow }),
|
|
91554
|
+
children: [
|
|
91555
|
+
"+",
|
|
91556
|
+
overflow
|
|
91557
|
+
]
|
|
91558
|
+
}
|
|
91559
|
+
)
|
|
91560
|
+
]
|
|
91561
|
+
}
|
|
91562
|
+
);
|
|
91563
|
+
}
|
|
91564
|
+
var STATUS_STYLES = {
|
|
91565
|
+
connected: {
|
|
91566
|
+
dot: "bg-green-400",
|
|
91567
|
+
text: "text-green-400",
|
|
91568
|
+
label: "Connected"
|
|
91569
|
+
},
|
|
91570
|
+
connecting: {
|
|
91571
|
+
dot: "bg-yellow-400 animate-pulse",
|
|
91572
|
+
text: "text-yellow-400",
|
|
91573
|
+
label: "Connecting..."
|
|
91574
|
+
},
|
|
91575
|
+
disconnected: {
|
|
91576
|
+
dot: "bg-gray-500",
|
|
91577
|
+
text: "text-gray-500",
|
|
91578
|
+
label: "Disconnected"
|
|
91579
|
+
},
|
|
91580
|
+
error: {
|
|
91581
|
+
dot: "bg-red-400",
|
|
91582
|
+
text: "text-red-400",
|
|
91583
|
+
label: "Connection error"
|
|
91584
|
+
}
|
|
91585
|
+
};
|
|
91586
|
+
function CollaborationStatusIndicator({
|
|
91587
|
+
status,
|
|
91588
|
+
connectedCount
|
|
91589
|
+
}) {
|
|
91590
|
+
const { t: t2 } = useTranslation();
|
|
91591
|
+
const style = STATUS_STYLES[status];
|
|
91592
|
+
return /* @__PURE__ */ jsxs(
|
|
91593
|
+
"div",
|
|
91594
|
+
{
|
|
91595
|
+
"data-testid": "collaboration-status",
|
|
91596
|
+
className: "flex items-center gap-1.5",
|
|
91597
|
+
"aria-label": t2("pptx.collaboration.statusAriaLabel", {
|
|
91598
|
+
status: t2(`pptx.collaboration.status.${status}`),
|
|
91599
|
+
count: connectedCount
|
|
91600
|
+
}),
|
|
91601
|
+
children: [
|
|
91602
|
+
/* @__PURE__ */ jsx("span", { className: `inline-block w-2 h-2 rounded-full ${style.dot}`, "aria-hidden": "true" }),
|
|
91603
|
+
/* @__PURE__ */ jsx("span", { className: `text-[10px] ${style.text}`, children: status === "connected" ? t2("pptx.collaboration.userCount", { count: connectedCount }) : t2(`pptx.collaboration.status.${status}`) })
|
|
91604
|
+
]
|
|
91605
|
+
}
|
|
91606
|
+
);
|
|
91607
|
+
}
|
|
91608
|
+
function CollaborationCursorOverlay({
|
|
91609
|
+
activeSlideIndex,
|
|
91610
|
+
canvasWidth,
|
|
91611
|
+
canvasHeight,
|
|
91612
|
+
selectedElementId
|
|
91613
|
+
}) {
|
|
91614
|
+
const collab = useCollaboration();
|
|
91615
|
+
const containerRef = useRef(null);
|
|
91616
|
+
const prevSelectionRef = useRef(selectedElementId);
|
|
91617
|
+
useEffect(() => {
|
|
91618
|
+
if (!collab || selectedElementId === prevSelectionRef.current) {
|
|
91619
|
+
return;
|
|
91620
|
+
}
|
|
91621
|
+
prevSelectionRef.current = selectedElementId;
|
|
91622
|
+
collab.broadcastPresence({
|
|
91623
|
+
selectedElementId: selectedElementId ?? void 0,
|
|
91624
|
+
activeSlideIndex
|
|
91625
|
+
});
|
|
91626
|
+
}, [collab, selectedElementId, activeSlideIndex]);
|
|
91627
|
+
useEffect(() => {
|
|
91628
|
+
if (!collab) {
|
|
91629
|
+
return;
|
|
91630
|
+
}
|
|
91631
|
+
const parent = containerRef.current?.parentElement;
|
|
91632
|
+
if (!parent) {
|
|
91633
|
+
return;
|
|
91634
|
+
}
|
|
91635
|
+
const handler = (e2) => {
|
|
91636
|
+
const rect = parent.getBoundingClientRect();
|
|
91637
|
+
const x2 = (e2.clientX - rect.left) / rect.width * canvasWidth;
|
|
91638
|
+
const y = (e2.clientY - rect.top) / rect.height * canvasHeight;
|
|
91639
|
+
collab.broadcastPresence({
|
|
91640
|
+
cursorX: x2,
|
|
91641
|
+
cursorY: y,
|
|
91642
|
+
activeSlideIndex
|
|
91643
|
+
});
|
|
91644
|
+
};
|
|
91645
|
+
parent.addEventListener("pointermove", handler);
|
|
91646
|
+
return () => parent.removeEventListener("pointermove", handler);
|
|
91647
|
+
}, [collab, canvasWidth, canvasHeight, activeSlideIndex]);
|
|
91648
|
+
if (!collab) {
|
|
91649
|
+
return null;
|
|
91650
|
+
}
|
|
91651
|
+
return /* @__PURE__ */ jsx(
|
|
91652
|
+
"div",
|
|
91653
|
+
{
|
|
91654
|
+
ref: containerRef,
|
|
91655
|
+
"data-testid": "collab-pointer-tracker",
|
|
91656
|
+
"data-export-ignore": "true",
|
|
91657
|
+
style: { display: "contents" },
|
|
91658
|
+
children: /* @__PURE__ */ jsx(
|
|
91659
|
+
RemoteUserCursors,
|
|
91660
|
+
{
|
|
91661
|
+
remoteUsers: collab.remoteUsers,
|
|
91662
|
+
activeSlideIndex,
|
|
91663
|
+
canvasWidth,
|
|
91664
|
+
canvasHeight
|
|
91665
|
+
}
|
|
91666
|
+
)
|
|
91667
|
+
}
|
|
91668
|
+
);
|
|
91669
|
+
}
|
|
91670
|
+
function RemoteSelectionOverlay({
|
|
91671
|
+
elements,
|
|
91672
|
+
activeSlideIndex
|
|
91673
|
+
}) {
|
|
91674
|
+
const collab = useCollaboration();
|
|
91675
|
+
if (!collab) {
|
|
91676
|
+
return null;
|
|
91677
|
+
}
|
|
91678
|
+
const elementMap = /* @__PURE__ */ new Map();
|
|
91679
|
+
for (const el of elements) {
|
|
91680
|
+
elementMap.set(el.id, el);
|
|
91681
|
+
}
|
|
91682
|
+
const selections = [];
|
|
91683
|
+
for (const user of collab.remoteUsers) {
|
|
91684
|
+
if (user.activeSlideIndex === activeSlideIndex && user.selectedElementId) {
|
|
91685
|
+
const el = elementMap.get(user.selectedElementId);
|
|
91686
|
+
if (el) {
|
|
91687
|
+
selections.push({
|
|
91688
|
+
userName: user.userName,
|
|
91689
|
+
userColor: user.userColor,
|
|
91690
|
+
element: el
|
|
91691
|
+
});
|
|
91692
|
+
}
|
|
91693
|
+
}
|
|
91694
|
+
}
|
|
91695
|
+
if (selections.length === 0) {
|
|
91696
|
+
return null;
|
|
91697
|
+
}
|
|
91698
|
+
return /* @__PURE__ */ jsx(Fragment, { children: selections.map((sel) => /* @__PURE__ */ jsx(
|
|
91699
|
+
"div",
|
|
91700
|
+
{
|
|
91701
|
+
"data-testid": `remote-selection-${sel.element.id}`,
|
|
91702
|
+
"data-export-ignore": "true",
|
|
91703
|
+
className: "absolute pointer-events-none",
|
|
91704
|
+
style: {
|
|
91705
|
+
left: sel.element.x,
|
|
91706
|
+
top: sel.element.y,
|
|
91707
|
+
width: sel.element.width,
|
|
91708
|
+
height: sel.element.height,
|
|
91709
|
+
zIndex: 9997,
|
|
91710
|
+
border: `2px solid ${sel.userColor}`,
|
|
91711
|
+
borderRadius: 2
|
|
91712
|
+
},
|
|
91713
|
+
children: /* @__PURE__ */ jsx(
|
|
91714
|
+
"span",
|
|
91715
|
+
{
|
|
91716
|
+
className: "absolute -top-5 left-0 px-1 py-0.5 text-[9px] font-medium text-white rounded-sm whitespace-nowrap leading-none",
|
|
91717
|
+
style: { backgroundColor: sel.userColor },
|
|
91718
|
+
children: sel.userName
|
|
91719
|
+
}
|
|
91720
|
+
)
|
|
91721
|
+
},
|
|
91722
|
+
`remote-sel-${sel.element.id}`
|
|
91723
|
+
)) });
|
|
91724
|
+
}
|
|
91094
91725
|
function SectionContextMenu({
|
|
91095
91726
|
state: state2,
|
|
91096
91727
|
sectionGroups,
|
|
@@ -91372,6 +92003,7 @@ function SlideItemInner({
|
|
|
91372
92003
|
canvasSize,
|
|
91373
92004
|
canEdit,
|
|
91374
92005
|
rehearsalTimings,
|
|
92006
|
+
presenceUsers,
|
|
91375
92007
|
onSelectSlide,
|
|
91376
92008
|
onSlideContextMenu,
|
|
91377
92009
|
onAddSection,
|
|
@@ -91414,16 +92046,27 @@ function SlideItemInner({
|
|
|
91414
92046
|
onDragOver,
|
|
91415
92047
|
onDrop: (e2) => onDrop(e2, slideIndex),
|
|
91416
92048
|
children: [
|
|
91417
|
-
/* @__PURE__ */
|
|
91418
|
-
|
|
91419
|
-
|
|
91420
|
-
|
|
91421
|
-
|
|
91422
|
-
|
|
91423
|
-
|
|
91424
|
-
|
|
91425
|
-
|
|
91426
|
-
|
|
92049
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5 w-5 shrink-0", children: [
|
|
92050
|
+
/* @__PURE__ */ jsx(
|
|
92051
|
+
"span",
|
|
92052
|
+
{
|
|
92053
|
+
className: cn(
|
|
92054
|
+
"text-[10px] tabular-nums text-right select-none w-full",
|
|
92055
|
+
isActive ? "text-primary font-medium" : "text-muted-foreground"
|
|
92056
|
+
),
|
|
92057
|
+
children: slideIndex + 1
|
|
92058
|
+
}
|
|
92059
|
+
),
|
|
92060
|
+
presenceUsers && presenceUsers.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap justify-center gap-px", children: presenceUsers.slice(0, 4).map((u2, i3) => /* @__PURE__ */ jsx(
|
|
92061
|
+
"span",
|
|
92062
|
+
{
|
|
92063
|
+
className: "w-[6px] h-[6px] rounded-full",
|
|
92064
|
+
style: { backgroundColor: u2.userColor },
|
|
92065
|
+
title: u2.userName
|
|
92066
|
+
},
|
|
92067
|
+
i3
|
|
92068
|
+
)) })
|
|
92069
|
+
] }),
|
|
91427
92070
|
/* @__PURE__ */ jsxs(
|
|
91428
92071
|
"div",
|
|
91429
92072
|
{
|
|
@@ -91573,8 +92216,26 @@ function SlidesPaneSidebar({
|
|
|
91573
92216
|
panelWidth
|
|
91574
92217
|
}) {
|
|
91575
92218
|
const { t: t2 } = useTranslation();
|
|
92219
|
+
const collab = useCollaboration();
|
|
91576
92220
|
const slideRefs = useRef(/* @__PURE__ */ new Map());
|
|
91577
92221
|
const renameInputRef = useRef(null);
|
|
92222
|
+
const slidePresenceMap = useMemo(() => {
|
|
92223
|
+
if (!collab || collab.remoteUsers.length === 0) {
|
|
92224
|
+
return void 0;
|
|
92225
|
+
}
|
|
92226
|
+
const map3 = /* @__PURE__ */ new Map();
|
|
92227
|
+
for (const user of collab.remoteUsers) {
|
|
92228
|
+
const idx = user.activeSlideIndex;
|
|
92229
|
+
const existing = map3.get(idx);
|
|
92230
|
+
const entry = { userName: user.userName, userColor: user.userColor };
|
|
92231
|
+
if (existing) {
|
|
92232
|
+
existing.push(entry);
|
|
92233
|
+
} else {
|
|
92234
|
+
map3.set(idx, [entry]);
|
|
92235
|
+
}
|
|
92236
|
+
}
|
|
92237
|
+
return map3;
|
|
92238
|
+
}, [collab]);
|
|
91578
92239
|
const estimatedItemHeight = useMemo(
|
|
91579
92240
|
() => estimateSlideItemHeight(canvasSize.width, canvasSize.height),
|
|
91580
92241
|
[canvasSize.width, canvasSize.height]
|
|
@@ -91696,6 +92357,7 @@ function SlidesPaneSidebar({
|
|
|
91696
92357
|
canvasSize,
|
|
91697
92358
|
canEdit,
|
|
91698
92359
|
rehearsalTimings,
|
|
92360
|
+
presenceUsers: slidePresenceMap?.get(item.slideIndex),
|
|
91699
92361
|
onSelectSlide,
|
|
91700
92362
|
onSlideContextMenu,
|
|
91701
92363
|
onAddSection,
|
|
@@ -91749,6 +92411,7 @@ function SlidesPaneSidebar({
|
|
|
91749
92411
|
canvasSize,
|
|
91750
92412
|
canEdit,
|
|
91751
92413
|
rehearsalTimings,
|
|
92414
|
+
presenceUsers: slidePresenceMap?.get(idx),
|
|
91752
92415
|
onSelectSlide,
|
|
91753
92416
|
onSlideContextMenu,
|
|
91754
92417
|
onAddSection,
|
|
@@ -96515,16 +97178,31 @@ var ALIGN_BTNS = [
|
|
|
96515
97178
|
{ k: "bottom", el: /* @__PURE__ */ jsx(LuChevronDown, { className: ic2 }) }
|
|
96516
97179
|
];
|
|
96517
97180
|
var DRAW_TOOLS = [
|
|
96518
|
-
{
|
|
96519
|
-
|
|
97181
|
+
{
|
|
97182
|
+
id: "select",
|
|
97183
|
+
icon: /* @__PURE__ */ jsx(LuMoveRight, { className: ic2 }),
|
|
97184
|
+
t: "Select",
|
|
97185
|
+
ac: "bg-primary text-primary-foreground"
|
|
97186
|
+
},
|
|
97187
|
+
{
|
|
97188
|
+
id: "pen",
|
|
97189
|
+
icon: /* @__PURE__ */ jsx(LuPencil, { className: ic2 }),
|
|
97190
|
+
t: "Pen",
|
|
97191
|
+
ac: "bg-primary text-primary-foreground"
|
|
97192
|
+
},
|
|
96520
97193
|
{
|
|
96521
97194
|
id: "highlighter",
|
|
96522
97195
|
icon: /* @__PURE__ */ jsx(LuType, { className: ic2 }),
|
|
96523
97196
|
t: "Highlighter",
|
|
96524
97197
|
ac: "bg-yellow-600 text-white"
|
|
96525
97198
|
},
|
|
96526
|
-
{ id: "eraser", icon: /* @__PURE__ */ jsx(LuMinus, { className: ic2 }), t: "Eraser" },
|
|
96527
|
-
{
|
|
97199
|
+
{ id: "eraser", icon: /* @__PURE__ */ jsx(LuMinus, { className: ic2 }), t: "Eraser", ac: "bg-red-600 text-white" },
|
|
97200
|
+
{
|
|
97201
|
+
id: "freeform",
|
|
97202
|
+
icon: /* @__PURE__ */ jsx(LuSpline, { className: ic2 }),
|
|
97203
|
+
t: "Freeform",
|
|
97204
|
+
ac: "bg-primary text-primary-foreground"
|
|
97205
|
+
}
|
|
96528
97206
|
];
|
|
96529
97207
|
var OV = [
|
|
96530
97208
|
{
|
|
@@ -96730,7 +97408,7 @@ function AnimationsSection(p3) {
|
|
|
96730
97408
|
"button",
|
|
96731
97409
|
{
|
|
96732
97410
|
type: "button",
|
|
96733
|
-
onClick: p3.onToggleInspector,
|
|
97411
|
+
onClick: p3.onOpenAnimationPanel ?? p3.onToggleInspector,
|
|
96734
97412
|
className: cn(
|
|
96735
97413
|
pill,
|
|
96736
97414
|
p3.isInspectorPaneOpen ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
|
|
@@ -97829,413 +98507,106 @@ function SlideShowSection(p3) {
|
|
|
97829
98507
|
/* @__PURE__ */ jsx(LuSettings, { className: ic2 }),
|
|
97830
98508
|
"Set Up Slide Show"
|
|
97831
98509
|
] }),
|
|
97832
|
-
/* @__PURE__ */ jsxs("button", { onClick: p3.onOpenBroadcastDialog, className: pill, title: "Broadcast slide show", children: [
|
|
97833
|
-
/* @__PURE__ */ jsx(LuCast, { className: ic2 }),
|
|
97834
|
-
"Broadcast"
|
|
97835
|
-
] }),
|
|
97836
|
-
sep,
|
|
97837
|
-
/* @__PURE__ */ jsxs(
|
|
97838
|
-
"button",
|
|
97839
|
-
{
|
|
97840
|
-
onClick: p3.onToggleSubtitles,
|
|
97841
|
-
className: cn(
|
|
97842
|
-
pill,
|
|
97843
|
-
p3.showSubtitles ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
|
|
97844
|
-
),
|
|
97845
|
-
title: "Toggle subtitles",
|
|
97846
|
-
children: [
|
|
97847
|
-
/* @__PURE__ */ jsx(LuCaptions, { className: ic2 }),
|
|
97848
|
-
"Subtitles"
|
|
97849
|
-
]
|
|
97850
|
-
}
|
|
97851
|
-
)
|
|
97852
|
-
] });
|
|
97853
|
-
}
|
|
97854
|
-
var FONT_COLOR_PRESETS = [
|
|
97855
|
-
"#000000",
|
|
97856
|
-
"#ffffff",
|
|
97857
|
-
"#ff0000",
|
|
97858
|
-
"#00aa00",
|
|
97859
|
-
"#0000ff",
|
|
97860
|
-
"#ff8800",
|
|
97861
|
-
"#8800cc",
|
|
97862
|
-
"#00cccc",
|
|
97863
|
-
"#ff69b4",
|
|
97864
|
-
"#808080"
|
|
97865
|
-
];
|
|
97866
|
-
var HIGHLIGHT_COLOR_PRESETS = [
|
|
97867
|
-
"#ffff00",
|
|
97868
|
-
"#00ff00",
|
|
97869
|
-
"#00ffff",
|
|
97870
|
-
"#ff00ff",
|
|
97871
|
-
"#0000ff",
|
|
97872
|
-
"#ff0000",
|
|
97873
|
-
"#000080",
|
|
97874
|
-
"#008080",
|
|
97875
|
-
"#008000",
|
|
97876
|
-
"#800080"
|
|
97877
|
-
];
|
|
97878
|
-
function TextSection(p3) {
|
|
97879
|
-
const hasSel = Boolean(p3.selectedElement);
|
|
97880
|
-
const canMut = hasSel && p3.canEdit;
|
|
97881
|
-
const isTextEl = hasSel && p3.selectedElement !== null && hasTextProperties(p3.selectedElement);
|
|
97882
|
-
const isTable = hasSel && p3.selectedElement?.type === "table";
|
|
97883
|
-
const canFormat = isTextEl || isTable;
|
|
97884
|
-
const currentColor = isTextEl && p3.selectedElement && hasTextProperties(p3.selectedElement) ? p3.selectedElement.textSegments?.[0]?.style?.color ?? p3.selectedElement.textStyle?.color ?? "#000000" : "#000000";
|
|
97885
|
-
const currentHighlight = isTextEl && p3.selectedElement && hasTextProperties(p3.selectedElement) ? p3.selectedElement.textSegments?.[0]?.style?.highlightColor ?? p3.selectedElement.textStyle?.highlightColor ?? "#ffff00" : "#ffff00";
|
|
97886
|
-
const colorInputRef = useRef(null);
|
|
97887
|
-
const highlightInputRef = useRef(null);
|
|
97888
|
-
const handleColorChange = useCallback(
|
|
97889
|
-
(color) => {
|
|
97890
|
-
if (!canFormat) {
|
|
97891
|
-
return;
|
|
97892
|
-
}
|
|
97893
|
-
p3.onUpdateTextStyle({ color });
|
|
97894
|
-
},
|
|
97895
|
-
[canFormat, p3]
|
|
97896
|
-
);
|
|
97897
|
-
const handleHighlightChange = useCallback(
|
|
97898
|
-
(highlightColor) => {
|
|
97899
|
-
if (!canFormat) {
|
|
97900
|
-
return;
|
|
97901
|
-
}
|
|
97902
|
-
p3.onUpdateTextStyle({ highlightColor });
|
|
97903
|
-
},
|
|
97904
|
-
[canFormat, p3]
|
|
97905
|
-
);
|
|
97906
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
97907
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
97908
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
97909
|
-
/* @__PURE__ */ jsx("div", { className: grp, children: FMT.map((b2, i3, a2) => {
|
|
97910
|
-
const handleClick = () => {
|
|
97911
|
-
if (!canFormat || !p3.selectedElement) {
|
|
97912
|
-
return;
|
|
97913
|
-
}
|
|
97914
|
-
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
97915
|
-
switch (b2.t) {
|
|
97916
|
-
case "Bold":
|
|
97917
|
-
p3.onUpdateTextStyle({ bold: !ts?.bold });
|
|
97918
|
-
break;
|
|
97919
|
-
case "Italic":
|
|
97920
|
-
p3.onUpdateTextStyle({ italic: !ts?.italic });
|
|
97921
|
-
break;
|
|
97922
|
-
case "Underline":
|
|
97923
|
-
p3.onUpdateTextStyle({
|
|
97924
|
-
underline: !ts?.underline
|
|
97925
|
-
});
|
|
97926
|
-
break;
|
|
97927
|
-
case "Strikethrough":
|
|
97928
|
-
p3.onUpdateTextStyle({
|
|
97929
|
-
strikethrough: !ts?.strikethrough
|
|
97930
|
-
});
|
|
97931
|
-
break;
|
|
97932
|
-
}
|
|
97933
|
-
};
|
|
97934
|
-
return /* @__PURE__ */ jsx(
|
|
97935
|
-
"button",
|
|
97936
|
-
{
|
|
97937
|
-
type: "button",
|
|
97938
|
-
disabled: !canMut,
|
|
97939
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
97940
|
-
onClick: handleClick,
|
|
97941
|
-
className: i3 < a2.length - 1 ? gB : gL,
|
|
97942
|
-
title: b2.t,
|
|
97943
|
-
children: b2.i
|
|
97944
|
-
},
|
|
97945
|
-
b2.t
|
|
97946
|
-
);
|
|
97947
|
-
}) }),
|
|
97948
|
-
/* @__PURE__ */ jsxs("div", { className: grp, children: [
|
|
97949
|
-
/* @__PURE__ */ jsx(
|
|
97950
|
-
"button",
|
|
97951
|
-
{
|
|
97952
|
-
type: "button",
|
|
97953
|
-
disabled: !canMut,
|
|
97954
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
97955
|
-
onClick: () => {
|
|
97956
|
-
if (!canFormat || !p3.selectedElement) {
|
|
97957
|
-
return;
|
|
97958
|
-
}
|
|
97959
|
-
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
97960
|
-
const current = ts?.fontSize ?? 18;
|
|
97961
|
-
p3.onUpdateTextStyle({ fontSize: current + 2 });
|
|
97962
|
-
},
|
|
97963
|
-
className: gB,
|
|
97964
|
-
title: "Increase Font Size",
|
|
97965
|
-
children: /* @__PURE__ */ jsx(LuAArrowUp, { className: ic2 })
|
|
97966
|
-
}
|
|
97967
|
-
),
|
|
97968
|
-
/* @__PURE__ */ jsx(
|
|
97969
|
-
"button",
|
|
97970
|
-
{
|
|
97971
|
-
type: "button",
|
|
97972
|
-
disabled: !canMut,
|
|
97973
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
97974
|
-
onClick: () => {
|
|
97975
|
-
if (!canFormat || !p3.selectedElement) {
|
|
97976
|
-
return;
|
|
97977
|
-
}
|
|
97978
|
-
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
97979
|
-
const current = ts?.fontSize ?? 18;
|
|
97980
|
-
p3.onUpdateTextStyle({ fontSize: Math.max(1, current - 2) });
|
|
97981
|
-
},
|
|
97982
|
-
className: gB,
|
|
97983
|
-
title: "Decrease Font Size",
|
|
97984
|
-
children: /* @__PURE__ */ jsx(LuAArrowDown, { className: ic2 })
|
|
97985
|
-
}
|
|
97986
|
-
),
|
|
97987
|
-
/* @__PURE__ */ jsx(
|
|
97988
|
-
"button",
|
|
97989
|
-
{
|
|
97990
|
-
type: "button",
|
|
97991
|
-
disabled: !canMut,
|
|
97992
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
97993
|
-
onClick: () => {
|
|
97994
|
-
if (!canFormat) {
|
|
97995
|
-
return;
|
|
97996
|
-
}
|
|
97997
|
-
p3.onUpdateTextStyle({
|
|
97998
|
-
bold: false,
|
|
97999
|
-
italic: false,
|
|
98000
|
-
underline: false,
|
|
98001
|
-
strikethrough: false,
|
|
98002
|
-
highlightColor: void 0
|
|
98003
|
-
});
|
|
98004
|
-
},
|
|
98005
|
-
className: gL,
|
|
98006
|
-
title: "Clear Formatting",
|
|
98007
|
-
children: /* @__PURE__ */ jsx(LuRemoveFormatting, { className: ic2 })
|
|
98008
|
-
}
|
|
98009
|
-
)
|
|
98010
|
-
] }),
|
|
98011
|
-
/* @__PURE__ */ jsxs("div", { className: "relative group", children: [
|
|
98012
|
-
/* @__PURE__ */ jsxs(
|
|
98013
|
-
"button",
|
|
98014
|
-
{
|
|
98015
|
-
type: "button",
|
|
98016
|
-
disabled: !canMut,
|
|
98017
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98018
|
-
className: pill,
|
|
98019
|
-
title: "Font Color",
|
|
98020
|
-
children: [
|
|
98021
|
-
/* @__PURE__ */ jsx(
|
|
98022
|
-
"svg",
|
|
98023
|
-
{
|
|
98024
|
-
className: ic2,
|
|
98025
|
-
viewBox: "0 0 24 24",
|
|
98026
|
-
fill: "none",
|
|
98027
|
-
stroke: "currentColor",
|
|
98028
|
-
strokeWidth: "2",
|
|
98029
|
-
strokeLinecap: "round",
|
|
98030
|
-
strokeLinejoin: "round",
|
|
98031
|
-
children: /* @__PURE__ */ jsx("path", { d: "M6 20h12M9.5 4h5L18 16H6L9.5 4z" })
|
|
98032
|
-
}
|
|
98033
|
-
),
|
|
98034
|
-
/* @__PURE__ */ jsx(
|
|
98035
|
-
"div",
|
|
98036
|
-
{
|
|
98037
|
-
className: "w-4 h-1 rounded-sm -mt-0.5",
|
|
98038
|
-
style: { backgroundColor: currentColor }
|
|
98039
|
-
}
|
|
98040
|
-
)
|
|
98041
|
-
]
|
|
98042
|
-
}
|
|
98043
|
-
),
|
|
98044
|
-
/* @__PURE__ */ jsx("div", { className: "absolute left-0 top-full z-50 hidden group-hover:block pt-1", children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl p-2 w-36", children: [
|
|
98045
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1.5 mb-2", children: FONT_COLOR_PRESETS.map((c2) => /* @__PURE__ */ jsx(
|
|
98046
|
-
"button",
|
|
98047
|
-
{
|
|
98048
|
-
type: "button",
|
|
98049
|
-
className: `w-5 h-5 rounded-full border transition-transform hover:scale-125 ${currentColor?.toLowerCase() === c2 ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
98050
|
-
style: { backgroundColor: c2 },
|
|
98051
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98052
|
-
onClick: () => handleColorChange(c2)
|
|
98053
|
-
},
|
|
98054
|
-
c2
|
|
98055
|
-
)) }),
|
|
98056
|
-
/* @__PURE__ */ jsx(
|
|
98057
|
-
"button",
|
|
98058
|
-
{
|
|
98059
|
-
type: "button",
|
|
98060
|
-
className: "w-full text-[10px] text-muted-foreground hover:text-foreground py-1 transition-colors",
|
|
98061
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98062
|
-
onClick: () => colorInputRef.current?.click(),
|
|
98063
|
-
children: "Custom colour..."
|
|
98064
|
-
}
|
|
98065
|
-
),
|
|
98066
|
-
/* @__PURE__ */ jsx(
|
|
98067
|
-
"input",
|
|
98068
|
-
{
|
|
98069
|
-
ref: colorInputRef,
|
|
98070
|
-
type: "color",
|
|
98071
|
-
className: "sr-only",
|
|
98072
|
-
value: currentColor,
|
|
98073
|
-
onChange: (e2) => handleColorChange(e2.target.value)
|
|
98074
|
-
}
|
|
98075
|
-
)
|
|
98076
|
-
] }) })
|
|
98077
|
-
] }),
|
|
98078
|
-
/* @__PURE__ */ jsxs("div", { className: "relative group", children: [
|
|
98079
|
-
/* @__PURE__ */ jsxs(
|
|
98080
|
-
"button",
|
|
98081
|
-
{
|
|
98082
|
-
type: "button",
|
|
98083
|
-
disabled: !canMut,
|
|
98084
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98085
|
-
className: pill,
|
|
98086
|
-
title: "Text Highlight Color",
|
|
98087
|
-
children: [
|
|
98088
|
-
/* @__PURE__ */ jsx(LuHighlighter, { className: ic2 }),
|
|
98089
|
-
/* @__PURE__ */ jsx(
|
|
98090
|
-
"div",
|
|
98091
|
-
{
|
|
98092
|
-
className: "w-4 h-1 rounded-sm -mt-0.5",
|
|
98093
|
-
style: { backgroundColor: currentHighlight }
|
|
98094
|
-
}
|
|
98095
|
-
)
|
|
98096
|
-
]
|
|
98097
|
-
}
|
|
98098
|
-
),
|
|
98099
|
-
/* @__PURE__ */ jsx("div", { className: "absolute left-0 top-full z-50 hidden group-hover:block pt-1", children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl p-2 w-36", children: [
|
|
98100
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1.5 mb-2", children: HIGHLIGHT_COLOR_PRESETS.map((c2) => /* @__PURE__ */ jsx(
|
|
98101
|
-
"button",
|
|
98102
|
-
{
|
|
98103
|
-
type: "button",
|
|
98104
|
-
className: `w-5 h-5 rounded-full border transition-transform hover:scale-125 ${currentHighlight?.toLowerCase() === c2 ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
98105
|
-
style: { backgroundColor: c2 },
|
|
98106
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98107
|
-
onClick: () => handleHighlightChange(c2)
|
|
98108
|
-
},
|
|
98109
|
-
c2
|
|
98110
|
-
)) }),
|
|
98111
|
-
/* @__PURE__ */ jsx(
|
|
98112
|
-
"button",
|
|
98113
|
-
{
|
|
98114
|
-
type: "button",
|
|
98115
|
-
className: "w-full text-[10px] text-muted-foreground hover:text-foreground py-1 transition-colors",
|
|
98116
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98117
|
-
onClick: () => highlightInputRef.current?.click(),
|
|
98118
|
-
children: "Custom colour..."
|
|
98119
|
-
}
|
|
98120
|
-
),
|
|
98121
|
-
/* @__PURE__ */ jsx(
|
|
98122
|
-
"input",
|
|
98123
|
-
{
|
|
98124
|
-
ref: highlightInputRef,
|
|
98125
|
-
type: "color",
|
|
98126
|
-
className: "sr-only",
|
|
98127
|
-
value: currentHighlight,
|
|
98128
|
-
onChange: (e2) => handleHighlightChange(e2.target.value)
|
|
98129
|
-
}
|
|
98130
|
-
)
|
|
98131
|
-
] }) })
|
|
98132
|
-
] })
|
|
98133
|
-
] }),
|
|
98134
|
-
/* @__PURE__ */ jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Font" })
|
|
98135
|
-
] }),
|
|
98510
|
+
/* @__PURE__ */ jsxs("button", { onClick: p3.onOpenBroadcastDialog, className: pill, title: "Broadcast slide show", children: [
|
|
98511
|
+
/* @__PURE__ */ jsx(LuCast, { className: ic2 }),
|
|
98512
|
+
"Broadcast"
|
|
98513
|
+
] }),
|
|
98136
98514
|
sep,
|
|
98515
|
+
/* @__PURE__ */ jsxs(
|
|
98516
|
+
"button",
|
|
98517
|
+
{
|
|
98518
|
+
onClick: p3.onToggleSubtitles,
|
|
98519
|
+
className: cn(
|
|
98520
|
+
pill,
|
|
98521
|
+
p3.showSubtitles ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
|
|
98522
|
+
),
|
|
98523
|
+
title: "Toggle subtitles",
|
|
98524
|
+
children: [
|
|
98525
|
+
/* @__PURE__ */ jsx(LuCaptions, { className: ic2 }),
|
|
98526
|
+
"Subtitles"
|
|
98527
|
+
]
|
|
98528
|
+
}
|
|
98529
|
+
)
|
|
98530
|
+
] });
|
|
98531
|
+
}
|
|
98532
|
+
var FONT_COLOR_PRESETS = [
|
|
98533
|
+
"#000000",
|
|
98534
|
+
"#ffffff",
|
|
98535
|
+
"#ff0000",
|
|
98536
|
+
"#00aa00",
|
|
98537
|
+
"#0000ff",
|
|
98538
|
+
"#ff8800",
|
|
98539
|
+
"#8800cc",
|
|
98540
|
+
"#00cccc",
|
|
98541
|
+
"#ff69b4",
|
|
98542
|
+
"#808080"
|
|
98543
|
+
];
|
|
98544
|
+
var HIGHLIGHT_COLOR_PRESETS = [
|
|
98545
|
+
"#ffff00",
|
|
98546
|
+
"#00ff00",
|
|
98547
|
+
"#00ffff",
|
|
98548
|
+
"#ff00ff",
|
|
98549
|
+
"#0000ff",
|
|
98550
|
+
"#ff0000",
|
|
98551
|
+
"#000080",
|
|
98552
|
+
"#008080",
|
|
98553
|
+
"#008000",
|
|
98554
|
+
"#800080"
|
|
98555
|
+
];
|
|
98556
|
+
function TextSection(p3) {
|
|
98557
|
+
const hasSel = Boolean(p3.selectedElement);
|
|
98558
|
+
const canMut = hasSel && p3.canEdit;
|
|
98559
|
+
const isTextEl = hasSel && p3.selectedElement !== null && hasTextProperties(p3.selectedElement);
|
|
98560
|
+
const isTable = hasSel && p3.selectedElement?.type === "table";
|
|
98561
|
+
const canFormat = isTextEl || isTable;
|
|
98562
|
+
const currentColor = isTextEl && p3.selectedElement && hasTextProperties(p3.selectedElement) ? p3.selectedElement.textSegments?.[0]?.style?.color ?? p3.selectedElement.textStyle?.color ?? "#000000" : "#000000";
|
|
98563
|
+
const currentHighlight = isTextEl && p3.selectedElement && hasTextProperties(p3.selectedElement) ? p3.selectedElement.textSegments?.[0]?.style?.highlightColor ?? p3.selectedElement.textStyle?.highlightColor ?? "#ffff00" : "#ffff00";
|
|
98564
|
+
const colorInputRef = useRef(null);
|
|
98565
|
+
const highlightInputRef = useRef(null);
|
|
98566
|
+
const handleColorChange = useCallback(
|
|
98567
|
+
(color) => {
|
|
98568
|
+
if (!canFormat) {
|
|
98569
|
+
return;
|
|
98570
|
+
}
|
|
98571
|
+
p3.onUpdateTextStyle({ color });
|
|
98572
|
+
},
|
|
98573
|
+
[canFormat, p3]
|
|
98574
|
+
);
|
|
98575
|
+
const handleHighlightChange = useCallback(
|
|
98576
|
+
(highlightColor) => {
|
|
98577
|
+
if (!canFormat) {
|
|
98578
|
+
return;
|
|
98579
|
+
}
|
|
98580
|
+
p3.onUpdateTextStyle({ highlightColor });
|
|
98581
|
+
},
|
|
98582
|
+
[canFormat, p3]
|
|
98583
|
+
);
|
|
98584
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
98137
98585
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
98138
98586
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
98139
|
-
/* @__PURE__ */
|
|
98140
|
-
|
|
98141
|
-
|
|
98142
|
-
|
|
98143
|
-
type: "button",
|
|
98144
|
-
disabled: !canMut,
|
|
98145
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98146
|
-
onClick: () => {
|
|
98147
|
-
if (!canFormat || !p3.selectedElement) {
|
|
98148
|
-
return;
|
|
98149
|
-
}
|
|
98150
|
-
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98151
|
-
p3.onUpdateTextStyle({
|
|
98152
|
-
listType: ts?.listType === "bullet" ? "none" : "bullet"
|
|
98153
|
-
});
|
|
98154
|
-
},
|
|
98155
|
-
className: gB,
|
|
98156
|
-
title: "Bullet List",
|
|
98157
|
-
children: /* @__PURE__ */ jsx(LuList, { className: ic2 })
|
|
98158
|
-
}
|
|
98159
|
-
),
|
|
98160
|
-
/* @__PURE__ */ jsx(
|
|
98161
|
-
"button",
|
|
98162
|
-
{
|
|
98163
|
-
type: "button",
|
|
98164
|
-
disabled: !canMut,
|
|
98165
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98166
|
-
onClick: () => {
|
|
98167
|
-
if (!canFormat || !p3.selectedElement) {
|
|
98168
|
-
return;
|
|
98169
|
-
}
|
|
98170
|
-
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98171
|
-
p3.onUpdateTextStyle({
|
|
98172
|
-
listType: ts?.listType === "numbered" ? "none" : "numbered"
|
|
98173
|
-
});
|
|
98174
|
-
},
|
|
98175
|
-
className: gL,
|
|
98176
|
-
title: "Numbered List",
|
|
98177
|
-
children: /* @__PURE__ */ jsx(LuListOrdered, { className: ic2 })
|
|
98587
|
+
/* @__PURE__ */ jsx("div", { className: grp, children: FMT.map((b2, i3, a2) => {
|
|
98588
|
+
const handleClick = () => {
|
|
98589
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98590
|
+
return;
|
|
98178
98591
|
}
|
|
98179
|
-
|
|
98180
|
-
|
|
98181
|
-
|
|
98182
|
-
|
|
98183
|
-
|
|
98184
|
-
|
|
98185
|
-
|
|
98186
|
-
|
|
98187
|
-
|
|
98188
|
-
onClick: () => {
|
|
98189
|
-
if (!canFormat || !p3.selectedElement) {
|
|
98190
|
-
return;
|
|
98191
|
-
}
|
|
98192
|
-
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98193
|
-
const current = ts?.paragraphMarginLeft ?? 0;
|
|
98592
|
+
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98593
|
+
switch (b2.t) {
|
|
98594
|
+
case "Bold":
|
|
98595
|
+
p3.onUpdateTextStyle({ bold: !ts?.bold });
|
|
98596
|
+
break;
|
|
98597
|
+
case "Italic":
|
|
98598
|
+
p3.onUpdateTextStyle({ italic: !ts?.italic });
|
|
98599
|
+
break;
|
|
98600
|
+
case "Underline":
|
|
98194
98601
|
p3.onUpdateTextStyle({
|
|
98195
|
-
|
|
98602
|
+
underline: !ts?.underline
|
|
98196
98603
|
});
|
|
98197
|
-
|
|
98198
|
-
|
|
98199
|
-
title: "Decrease Indent",
|
|
98200
|
-
children: /* @__PURE__ */ jsx(LuIndentDecrease, { className: ic2 })
|
|
98201
|
-
}
|
|
98202
|
-
),
|
|
98203
|
-
/* @__PURE__ */ jsx(
|
|
98204
|
-
"button",
|
|
98205
|
-
{
|
|
98206
|
-
type: "button",
|
|
98207
|
-
disabled: !canMut,
|
|
98208
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98209
|
-
onClick: () => {
|
|
98210
|
-
if (!canFormat || !p3.selectedElement) {
|
|
98211
|
-
return;
|
|
98212
|
-
}
|
|
98213
|
-
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98214
|
-
const current = ts?.paragraphMarginLeft ?? 0;
|
|
98604
|
+
break;
|
|
98605
|
+
case "Strikethrough":
|
|
98215
98606
|
p3.onUpdateTextStyle({
|
|
98216
|
-
|
|
98607
|
+
strikethrough: !ts?.strikethrough
|
|
98217
98608
|
});
|
|
98218
|
-
|
|
98219
|
-
className: gL,
|
|
98220
|
-
title: "Increase Indent",
|
|
98221
|
-
children: /* @__PURE__ */ jsx(LuIndentIncrease, { className: ic2 })
|
|
98222
|
-
}
|
|
98223
|
-
)
|
|
98224
|
-
] }),
|
|
98225
|
-
/* @__PURE__ */ jsx("div", { className: grp, children: ATXT.map((b2, i3, a2) => {
|
|
98226
|
-
const handleClick = () => {
|
|
98227
|
-
if (!canFormat) {
|
|
98228
|
-
return;
|
|
98229
|
-
}
|
|
98230
|
-
const alignMap = {
|
|
98231
|
-
"Align left": "left",
|
|
98232
|
-
"Align center": "center",
|
|
98233
|
-
"Align right": "right",
|
|
98234
|
-
Justify: "justify"
|
|
98235
|
-
};
|
|
98236
|
-
const align = alignMap[b2.t];
|
|
98237
|
-
if (align) {
|
|
98238
|
-
p3.onUpdateTextStyle({ align });
|
|
98609
|
+
break;
|
|
98239
98610
|
}
|
|
98240
98611
|
};
|
|
98241
98612
|
return /* @__PURE__ */ jsx(
|
|
@@ -98251,518 +98622,318 @@ function TextSection(p3) {
|
|
|
98251
98622
|
},
|
|
98252
98623
|
b2.t
|
|
98253
98624
|
);
|
|
98254
|
-
}) })
|
|
98255
|
-
|
|
98256
|
-
|
|
98257
|
-
|
|
98258
|
-
|
|
98259
|
-
|
|
98260
|
-
|
|
98261
|
-
|
|
98262
|
-
|
|
98263
|
-
|
|
98264
|
-
|
|
98265
|
-
|
|
98266
|
-
|
|
98267
|
-
|
|
98268
|
-
|
|
98269
|
-
|
|
98270
|
-
|
|
98271
|
-
|
|
98272
|
-
|
|
98273
|
-
|
|
98274
|
-
|
|
98275
|
-
|
|
98276
|
-
|
|
98277
|
-
|
|
98278
|
-
|
|
98279
|
-
|
|
98280
|
-
|
|
98281
|
-
|
|
98282
|
-
|
|
98283
|
-
|
|
98284
|
-
|
|
98285
|
-
|
|
98286
|
-
|
|
98287
|
-
|
|
98288
|
-
|
|
98289
|
-
|
|
98290
|
-
|
|
98291
|
-
|
|
98292
|
-
}
|
|
98293
|
-
|
|
98294
|
-
|
|
98295
|
-
|
|
98296
|
-
|
|
98297
|
-
|
|
98298
|
-
|
|
98299
|
-
|
|
98300
|
-
|
|
98301
|
-
|
|
98302
|
-
|
|
98303
|
-
|
|
98304
|
-
|
|
98305
|
-
|
|
98306
|
-
|
|
98307
|
-
|
|
98308
|
-
|
|
98309
|
-
|
|
98310
|
-
|
|
98311
|
-
}
|
|
98312
|
-
|
|
98313
|
-
|
|
98314
|
-
|
|
98315
|
-
|
|
98316
|
-
|
|
98317
|
-
|
|
98318
|
-
|
|
98319
|
-
|
|
98320
|
-
|
|
98321
|
-
|
|
98322
|
-
|
|
98323
|
-
|
|
98324
|
-
|
|
98325
|
-
|
|
98326
|
-
|
|
98327
|
-
|
|
98328
|
-
|
|
98329
|
-
|
|
98330
|
-
|
|
98331
|
-
|
|
98332
|
-
|
|
98333
|
-
|
|
98334
|
-
|
|
98335
|
-
|
|
98336
|
-
|
|
98337
|
-
|
|
98338
|
-
})
|
|
98339
|
-
|
|
98340
|
-
|
|
98341
|
-
|
|
98342
|
-
|
|
98343
|
-
|
|
98344
|
-
|
|
98345
|
-
|
|
98346
|
-
|
|
98347
|
-
|
|
98348
|
-
|
|
98349
|
-
|
|
98350
|
-
|
|
98351
|
-
|
|
98352
|
-
|
|
98353
|
-
|
|
98354
|
-
|
|
98355
|
-
|
|
98356
|
-
|
|
98357
|
-
|
|
98358
|
-
|
|
98359
|
-
|
|
98360
|
-
|
|
98361
|
-
|
|
98362
|
-
|
|
98363
|
-
if (pendingBroadcastRef.current) {
|
|
98364
|
-
clearTimeout(pendingBroadcastRef.current);
|
|
98365
|
-
pendingBroadcastRef.current = null;
|
|
98366
|
-
}
|
|
98367
|
-
flush();
|
|
98368
|
-
} else if (!pendingBroadcastRef.current) {
|
|
98369
|
-
pendingBroadcastRef.current = setTimeout(() => {
|
|
98370
|
-
pendingBroadcastRef.current = null;
|
|
98371
|
-
flush();
|
|
98372
|
-
}, BROADCAST_THROTTLE_MS - elapsed);
|
|
98373
|
-
}
|
|
98374
|
-
},
|
|
98375
|
-
[awareness, userName, userColor, userAvatar]
|
|
98376
|
-
);
|
|
98377
|
-
useEffect(() => {
|
|
98378
|
-
if (!awareness) {
|
|
98379
|
-
return;
|
|
98380
|
-
}
|
|
98381
|
-
awareness.setLocalStateField("presence", {
|
|
98382
|
-
userName,
|
|
98383
|
-
userColor,
|
|
98384
|
-
userAvatar,
|
|
98385
|
-
activeSlideIndex: 0,
|
|
98386
|
-
cursorX: 0,
|
|
98387
|
-
cursorY: 0,
|
|
98388
|
-
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
98389
|
-
});
|
|
98390
|
-
}, [awareness, userName, userColor, userAvatar]);
|
|
98391
|
-
useEffect(() => {
|
|
98392
|
-
if (!awareness || localClientId === null) {
|
|
98393
|
-
return;
|
|
98394
|
-
}
|
|
98395
|
-
const handleChange = () => {
|
|
98396
|
-
const now = Date.now();
|
|
98397
|
-
const states = awareness.getStates();
|
|
98398
|
-
const users = [];
|
|
98399
|
-
states.forEach((state2, cid) => {
|
|
98400
|
-
if (cid === localClientId) {
|
|
98401
|
-
return;
|
|
98402
|
-
}
|
|
98403
|
-
const raw = state2?.presence;
|
|
98404
|
-
if (!raw || typeof raw !== "object") {
|
|
98405
|
-
return;
|
|
98406
|
-
}
|
|
98407
|
-
const sanitized = sanitizePresence({ ...raw, clientId: cid }, canvasWidth, canvasHeight);
|
|
98408
|
-
if (!sanitized) {
|
|
98409
|
-
return;
|
|
98410
|
-
}
|
|
98411
|
-
const updatedAt = new Date(sanitized.lastUpdated).getTime();
|
|
98412
|
-
if (Number.isNaN(updatedAt) || now - updatedAt > STALE_PRESENCE_MS) {
|
|
98413
|
-
return;
|
|
98414
|
-
}
|
|
98415
|
-
users.push(sanitized);
|
|
98416
|
-
});
|
|
98417
|
-
setRemoteUsers(users);
|
|
98418
|
-
};
|
|
98419
|
-
awareness.on("change", handleChange);
|
|
98420
|
-
awareness.on("update", handleChange);
|
|
98421
|
-
handleChange();
|
|
98422
|
-
return () => {
|
|
98423
|
-
awareness.off("change", handleChange);
|
|
98424
|
-
awareness.off("update", handleChange);
|
|
98425
|
-
};
|
|
98426
|
-
}, [awareness, localClientId, canvasWidth, canvasHeight]);
|
|
98427
|
-
useEffect(() => {
|
|
98428
|
-
if (!awareness) {
|
|
98429
|
-
return;
|
|
98430
|
-
}
|
|
98431
|
-
const interval = setInterval(() => {
|
|
98432
|
-
awareness.setLocalStateField("presence", {
|
|
98433
|
-
...latestLocalState.current,
|
|
98434
|
-
userName,
|
|
98435
|
-
userColor,
|
|
98436
|
-
userAvatar,
|
|
98437
|
-
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
98438
|
-
});
|
|
98439
|
-
}, 1e4);
|
|
98440
|
-
return () => clearInterval(interval);
|
|
98441
|
-
}, [awareness, userName, userColor, userAvatar]);
|
|
98442
|
-
useEffect(() => {
|
|
98443
|
-
return () => {
|
|
98444
|
-
if (pendingBroadcastRef.current) {
|
|
98445
|
-
clearTimeout(pendingBroadcastRef.current);
|
|
98446
|
-
}
|
|
98447
|
-
};
|
|
98448
|
-
}, []);
|
|
98449
|
-
return { remoteUsers, broadcastPresence };
|
|
98450
|
-
}
|
|
98451
|
-
function useYjsProvider({ config }) {
|
|
98452
|
-
const [status, setStatus] = useState("disconnected");
|
|
98453
|
-
const [awareness, setAwareness] = useState(null);
|
|
98454
|
-
const [doc2, setDoc] = useState(null);
|
|
98455
|
-
const [clientId, setClientId] = useState(null);
|
|
98456
|
-
const cleanupRef = useRef(null);
|
|
98457
|
-
const init = useCallback(async () => {
|
|
98458
|
-
const roomId = validateRoomId(config.roomId);
|
|
98459
|
-
setStatus("connecting");
|
|
98460
|
-
try {
|
|
98461
|
-
const [Y, { WebsocketProvider: WebsocketProvider2 }] = await Promise.all([Promise.resolve().then(() => (init_yjs(), yjs_exports)), Promise.resolve().then(() => (init_y_websocket(), y_websocket_exports))]);
|
|
98462
|
-
const yDoc = new Y.Doc();
|
|
98463
|
-
const provider = new WebsocketProvider2(
|
|
98464
|
-
config.serverUrl,
|
|
98465
|
-
roomId,
|
|
98466
|
-
yDoc,
|
|
98467
|
-
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
98468
|
-
{
|
|
98469
|
-
params: config.authToken ? { token: config.authToken } : void 0
|
|
98470
|
-
}
|
|
98471
|
-
);
|
|
98472
|
-
const handleStatus = (event) => {
|
|
98473
|
-
if (event.status === "connected") {
|
|
98474
|
-
setStatus("connected");
|
|
98475
|
-
} else if (event.status === "disconnected") {
|
|
98476
|
-
setStatus("disconnected");
|
|
98477
|
-
}
|
|
98478
|
-
};
|
|
98479
|
-
provider.on("status", handleStatus);
|
|
98480
|
-
if (provider.wsconnected) {
|
|
98481
|
-
setStatus("connected");
|
|
98482
|
-
}
|
|
98483
|
-
setDoc(yDoc);
|
|
98484
|
-
setAwareness(provider.awareness);
|
|
98485
|
-
setClientId(provider.awareness.clientID);
|
|
98486
|
-
cleanupRef.current = () => {
|
|
98487
|
-
provider.off("status", handleStatus);
|
|
98488
|
-
provider.destroy();
|
|
98489
|
-
yDoc.destroy();
|
|
98490
|
-
setDoc(null);
|
|
98491
|
-
setAwareness(null);
|
|
98492
|
-
setClientId(null);
|
|
98493
|
-
setStatus("disconnected");
|
|
98494
|
-
};
|
|
98495
|
-
} catch (err) {
|
|
98496
|
-
console.warn(
|
|
98497
|
-
"[pptx-viewer] Collaboration packages not available:",
|
|
98498
|
-
err instanceof Error ? err.message : err
|
|
98499
|
-
);
|
|
98500
|
-
setStatus("error");
|
|
98501
|
-
}
|
|
98502
|
-
}, [config.roomId, config.serverUrl, config.authToken]);
|
|
98503
|
-
useEffect(() => {
|
|
98504
|
-
init();
|
|
98505
|
-
return () => {
|
|
98506
|
-
cleanupRef.current?.();
|
|
98507
|
-
cleanupRef.current = null;
|
|
98508
|
-
};
|
|
98509
|
-
}, [init]);
|
|
98510
|
-
return { status, awareness, doc: doc2, clientId };
|
|
98511
|
-
}
|
|
98512
|
-
|
|
98513
|
-
// src/viewer/hooks/collaboration/useCollaborativeState.ts
|
|
98514
|
-
function useCollaborativeState({
|
|
98515
|
-
config,
|
|
98516
|
-
canvasWidth,
|
|
98517
|
-
canvasHeight
|
|
98518
|
-
}) {
|
|
98519
|
-
const userColor = sanitizeColor(config.userColor, "#6366f1");
|
|
98520
|
-
const { status, awareness, doc: doc2, clientId } = useYjsProvider({ config });
|
|
98521
|
-
const { remoteUsers, broadcastPresence } = usePresenceTracking({
|
|
98522
|
-
awareness,
|
|
98523
|
-
localClientId: clientId,
|
|
98524
|
-
userName: config.userName,
|
|
98525
|
-
userColor,
|
|
98526
|
-
userAvatar: config.userAvatar,
|
|
98527
|
-
canvasWidth,
|
|
98528
|
-
canvasHeight
|
|
98529
|
-
});
|
|
98530
|
-
const connectedCount = status === "connected" ? remoteUsers.length + 1 : remoteUsers.length;
|
|
98531
|
-
return {
|
|
98532
|
-
status,
|
|
98533
|
-
remoteUsers,
|
|
98534
|
-
broadcastPresence,
|
|
98535
|
-
connectedCount,
|
|
98536
|
-
config,
|
|
98537
|
-
doc: doc2
|
|
98538
|
-
};
|
|
98539
|
-
}
|
|
98540
|
-
var CollaborationContext = createContext(null);
|
|
98541
|
-
function useCollaboration() {
|
|
98542
|
-
return useContext(CollaborationContext);
|
|
98543
|
-
}
|
|
98544
|
-
function CollaborationProvider({
|
|
98545
|
-
config,
|
|
98546
|
-
canvasWidth,
|
|
98547
|
-
canvasHeight,
|
|
98548
|
-
children
|
|
98549
|
-
}) {
|
|
98550
|
-
const value = useCollaborativeState({
|
|
98551
|
-
config,
|
|
98552
|
-
canvasWidth,
|
|
98553
|
-
canvasHeight
|
|
98554
|
-
});
|
|
98555
|
-
return /* @__PURE__ */ jsx(CollaborationContext.Provider, { value, children });
|
|
98556
|
-
}
|
|
98557
|
-
function RemoteUserCursors({
|
|
98558
|
-
remoteUsers,
|
|
98559
|
-
activeSlideIndex,
|
|
98560
|
-
canvasWidth,
|
|
98561
|
-
canvasHeight
|
|
98562
|
-
}) {
|
|
98563
|
-
const visibleUsers = remoteUsers.filter((u2) => u2.activeSlideIndex === activeSlideIndex);
|
|
98564
|
-
if (visibleUsers.length === 0) {
|
|
98565
|
-
return null;
|
|
98566
|
-
}
|
|
98567
|
-
return /* @__PURE__ */ jsx(
|
|
98568
|
-
"svg",
|
|
98569
|
-
{
|
|
98570
|
-
"data-testid": "remote-user-cursors",
|
|
98571
|
-
className: "absolute inset-0 pointer-events-none",
|
|
98572
|
-
style: { zIndex: 9999 },
|
|
98573
|
-
width: canvasWidth,
|
|
98574
|
-
height: canvasHeight,
|
|
98575
|
-
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
98576
|
-
"aria-hidden": "true",
|
|
98577
|
-
children: visibleUsers.map((user) => /* @__PURE__ */ jsxs(
|
|
98578
|
-
"g",
|
|
98579
|
-
{
|
|
98580
|
-
transform: `translate(${user.cursorX}, ${user.cursorY})`,
|
|
98581
|
-
"data-testid": `remote-cursor-${user.clientId}`,
|
|
98582
|
-
children: [
|
|
98625
|
+
}) }),
|
|
98626
|
+
/* @__PURE__ */ jsxs("div", { className: grp, children: [
|
|
98627
|
+
/* @__PURE__ */ jsx(
|
|
98628
|
+
"button",
|
|
98629
|
+
{
|
|
98630
|
+
type: "button",
|
|
98631
|
+
disabled: !canMut,
|
|
98632
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98633
|
+
onClick: () => {
|
|
98634
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98635
|
+
return;
|
|
98636
|
+
}
|
|
98637
|
+
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98638
|
+
const current = ts?.fontSize ?? 18;
|
|
98639
|
+
p3.onUpdateTextStyle({ fontSize: current + 2 });
|
|
98640
|
+
},
|
|
98641
|
+
className: gB,
|
|
98642
|
+
title: "Increase Font Size",
|
|
98643
|
+
children: /* @__PURE__ */ jsx(LuAArrowUp, { className: ic2 })
|
|
98644
|
+
}
|
|
98645
|
+
),
|
|
98646
|
+
/* @__PURE__ */ jsx(
|
|
98647
|
+
"button",
|
|
98648
|
+
{
|
|
98649
|
+
type: "button",
|
|
98650
|
+
disabled: !canMut,
|
|
98651
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98652
|
+
onClick: () => {
|
|
98653
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98654
|
+
return;
|
|
98655
|
+
}
|
|
98656
|
+
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98657
|
+
const current = ts?.fontSize ?? 18;
|
|
98658
|
+
p3.onUpdateTextStyle({ fontSize: Math.max(1, current - 2) });
|
|
98659
|
+
},
|
|
98660
|
+
className: gB,
|
|
98661
|
+
title: "Decrease Font Size",
|
|
98662
|
+
children: /* @__PURE__ */ jsx(LuAArrowDown, { className: ic2 })
|
|
98663
|
+
}
|
|
98664
|
+
),
|
|
98665
|
+
/* @__PURE__ */ jsx(
|
|
98666
|
+
"button",
|
|
98667
|
+
{
|
|
98668
|
+
type: "button",
|
|
98669
|
+
disabled: !canMut,
|
|
98670
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98671
|
+
onClick: () => {
|
|
98672
|
+
if (!canFormat) {
|
|
98673
|
+
return;
|
|
98674
|
+
}
|
|
98675
|
+
p3.onUpdateTextStyle({
|
|
98676
|
+
bold: false,
|
|
98677
|
+
italic: false,
|
|
98678
|
+
underline: false,
|
|
98679
|
+
strikethrough: false,
|
|
98680
|
+
highlightColor: void 0
|
|
98681
|
+
});
|
|
98682
|
+
},
|
|
98683
|
+
className: gL,
|
|
98684
|
+
title: "Clear Formatting",
|
|
98685
|
+
children: /* @__PURE__ */ jsx(LuRemoveFormatting, { className: ic2 })
|
|
98686
|
+
}
|
|
98687
|
+
)
|
|
98688
|
+
] }),
|
|
98689
|
+
/* @__PURE__ */ jsxs("div", { className: "relative group", children: [
|
|
98690
|
+
/* @__PURE__ */ jsxs(
|
|
98691
|
+
"button",
|
|
98692
|
+
{
|
|
98693
|
+
type: "button",
|
|
98694
|
+
disabled: !canMut,
|
|
98695
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98696
|
+
className: pill,
|
|
98697
|
+
title: "Font Color",
|
|
98698
|
+
children: [
|
|
98699
|
+
/* @__PURE__ */ jsx(
|
|
98700
|
+
"svg",
|
|
98701
|
+
{
|
|
98702
|
+
className: ic2,
|
|
98703
|
+
viewBox: "0 0 24 24",
|
|
98704
|
+
fill: "none",
|
|
98705
|
+
stroke: "currentColor",
|
|
98706
|
+
strokeWidth: "2",
|
|
98707
|
+
strokeLinecap: "round",
|
|
98708
|
+
strokeLinejoin: "round",
|
|
98709
|
+
children: /* @__PURE__ */ jsx("path", { d: "M6 20h12M9.5 4h5L18 16H6L9.5 4z" })
|
|
98710
|
+
}
|
|
98711
|
+
),
|
|
98712
|
+
/* @__PURE__ */ jsx(
|
|
98713
|
+
"div",
|
|
98714
|
+
{
|
|
98715
|
+
className: "w-4 h-1 rounded-sm -mt-0.5",
|
|
98716
|
+
style: { backgroundColor: currentColor }
|
|
98717
|
+
}
|
|
98718
|
+
)
|
|
98719
|
+
]
|
|
98720
|
+
}
|
|
98721
|
+
),
|
|
98722
|
+
/* @__PURE__ */ jsx("div", { className: "absolute left-0 top-full z-50 hidden group-hover:block pt-1", children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl p-2 w-36", children: [
|
|
98723
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1.5 mb-2", children: FONT_COLOR_PRESETS.map((c2) => /* @__PURE__ */ jsx(
|
|
98724
|
+
"button",
|
|
98725
|
+
{
|
|
98726
|
+
type: "button",
|
|
98727
|
+
className: `w-5 h-5 rounded-full border transition-transform hover:scale-125 ${currentColor?.toLowerCase() === c2 ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
98728
|
+
style: { backgroundColor: c2 },
|
|
98729
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98730
|
+
onClick: () => handleColorChange(c2)
|
|
98731
|
+
},
|
|
98732
|
+
c2
|
|
98733
|
+
)) }),
|
|
98583
98734
|
/* @__PURE__ */ jsx(
|
|
98584
|
-
"
|
|
98735
|
+
"button",
|
|
98585
98736
|
{
|
|
98586
|
-
|
|
98587
|
-
|
|
98588
|
-
|
|
98589
|
-
|
|
98590
|
-
|
|
98737
|
+
type: "button",
|
|
98738
|
+
className: "w-full text-[10px] text-muted-foreground hover:text-foreground py-1 transition-colors",
|
|
98739
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98740
|
+
onClick: () => colorInputRef.current?.click(),
|
|
98741
|
+
children: "Custom colour..."
|
|
98591
98742
|
}
|
|
98592
98743
|
),
|
|
98593
|
-
/* @__PURE__ */
|
|
98594
|
-
|
|
98595
|
-
|
|
98596
|
-
|
|
98597
|
-
|
|
98598
|
-
|
|
98599
|
-
|
|
98600
|
-
|
|
98601
|
-
|
|
98602
|
-
|
|
98603
|
-
|
|
98604
|
-
|
|
98744
|
+
/* @__PURE__ */ jsx(
|
|
98745
|
+
"input",
|
|
98746
|
+
{
|
|
98747
|
+
ref: colorInputRef,
|
|
98748
|
+
type: "color",
|
|
98749
|
+
className: "sr-only",
|
|
98750
|
+
value: currentColor,
|
|
98751
|
+
onChange: (e2) => handleColorChange(e2.target.value)
|
|
98752
|
+
}
|
|
98753
|
+
)
|
|
98754
|
+
] }) })
|
|
98755
|
+
] }),
|
|
98756
|
+
/* @__PURE__ */ jsxs("div", { className: "relative group", children: [
|
|
98757
|
+
/* @__PURE__ */ jsxs(
|
|
98758
|
+
"button",
|
|
98759
|
+
{
|
|
98760
|
+
type: "button",
|
|
98761
|
+
disabled: !canMut,
|
|
98762
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98763
|
+
className: pill,
|
|
98764
|
+
title: "Text Highlight Color",
|
|
98765
|
+
children: [
|
|
98766
|
+
/* @__PURE__ */ jsx(LuHighlighter, { className: ic2 }),
|
|
98767
|
+
/* @__PURE__ */ jsx(
|
|
98768
|
+
"div",
|
|
98769
|
+
{
|
|
98770
|
+
className: "w-4 h-1 rounded-sm -mt-0.5",
|
|
98771
|
+
style: { backgroundColor: currentHighlight }
|
|
98772
|
+
}
|
|
98773
|
+
)
|
|
98774
|
+
]
|
|
98775
|
+
}
|
|
98776
|
+
),
|
|
98777
|
+
/* @__PURE__ */ jsx("div", { className: "absolute left-0 top-full z-50 hidden group-hover:block pt-1", children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl p-2 w-36", children: [
|
|
98778
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 gap-1.5 mb-2", children: HIGHLIGHT_COLOR_PRESETS.map((c2) => /* @__PURE__ */ jsx(
|
|
98779
|
+
"button",
|
|
98780
|
+
{
|
|
98781
|
+
type: "button",
|
|
98782
|
+
className: `w-5 h-5 rounded-full border transition-transform hover:scale-125 ${currentHighlight?.toLowerCase() === c2 ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
98783
|
+
style: { backgroundColor: c2 },
|
|
98784
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98785
|
+
onClick: () => handleHighlightChange(c2)
|
|
98786
|
+
},
|
|
98787
|
+
c2
|
|
98788
|
+
)) }),
|
|
98789
|
+
/* @__PURE__ */ jsx(
|
|
98790
|
+
"button",
|
|
98791
|
+
{
|
|
98792
|
+
type: "button",
|
|
98793
|
+
className: "w-full text-[10px] text-muted-foreground hover:text-foreground py-1 transition-colors",
|
|
98794
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98795
|
+
onClick: () => highlightInputRef.current?.click(),
|
|
98796
|
+
children: "Custom colour..."
|
|
98797
|
+
}
|
|
98798
|
+
),
|
|
98799
|
+
/* @__PURE__ */ jsx(
|
|
98800
|
+
"input",
|
|
98801
|
+
{
|
|
98802
|
+
ref: highlightInputRef,
|
|
98803
|
+
type: "color",
|
|
98804
|
+
className: "sr-only",
|
|
98805
|
+
value: currentHighlight,
|
|
98806
|
+
onChange: (e2) => handleHighlightChange(e2.target.value)
|
|
98807
|
+
}
|
|
98808
|
+
)
|
|
98809
|
+
] }) })
|
|
98810
|
+
] })
|
|
98811
|
+
] }),
|
|
98812
|
+
/* @__PURE__ */ jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Font" })
|
|
98813
|
+
] }),
|
|
98814
|
+
sep,
|
|
98815
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
98816
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
98817
|
+
/* @__PURE__ */ jsxs("div", { className: grp, children: [
|
|
98818
|
+
/* @__PURE__ */ jsx(
|
|
98819
|
+
"button",
|
|
98820
|
+
{
|
|
98821
|
+
type: "button",
|
|
98822
|
+
disabled: !canMut,
|
|
98823
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98824
|
+
onClick: () => {
|
|
98825
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98826
|
+
return;
|
|
98605
98827
|
}
|
|
98606
|
-
|
|
98607
|
-
|
|
98608
|
-
|
|
98609
|
-
|
|
98610
|
-
|
|
98611
|
-
|
|
98612
|
-
|
|
98613
|
-
|
|
98614
|
-
|
|
98615
|
-
|
|
98616
|
-
|
|
98617
|
-
|
|
98828
|
+
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98829
|
+
p3.onUpdateTextStyle({
|
|
98830
|
+
listType: ts?.listType === "bullet" ? "none" : "bullet"
|
|
98831
|
+
});
|
|
98832
|
+
},
|
|
98833
|
+
className: gB,
|
|
98834
|
+
title: "Bullet List",
|
|
98835
|
+
children: /* @__PURE__ */ jsx(LuList, { className: ic2 })
|
|
98836
|
+
}
|
|
98837
|
+
),
|
|
98838
|
+
/* @__PURE__ */ jsx(
|
|
98839
|
+
"button",
|
|
98840
|
+
{
|
|
98841
|
+
type: "button",
|
|
98842
|
+
disabled: !canMut,
|
|
98843
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98844
|
+
onClick: () => {
|
|
98845
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98846
|
+
return;
|
|
98618
98847
|
}
|
|
98619
|
-
|
|
98620
|
-
|
|
98621
|
-
|
|
98622
|
-
|
|
98623
|
-
|
|
98624
|
-
|
|
98625
|
-
|
|
98626
|
-
|
|
98627
|
-
}
|
|
98628
|
-
|
|
98629
|
-
|
|
98630
|
-
|
|
98631
|
-
|
|
98632
|
-
|
|
98633
|
-
|
|
98634
|
-
|
|
98635
|
-
|
|
98636
|
-
|
|
98637
|
-
|
|
98638
|
-
|
|
98639
|
-
|
|
98640
|
-
}
|
|
98641
|
-
|
|
98642
|
-
|
|
98643
|
-
|
|
98644
|
-
|
|
98645
|
-
|
|
98646
|
-
|
|
98647
|
-
|
|
98648
|
-
|
|
98649
|
-
|
|
98650
|
-
|
|
98651
|
-
|
|
98652
|
-
|
|
98653
|
-
|
|
98654
|
-
|
|
98655
|
-
|
|
98656
|
-
|
|
98657
|
-
|
|
98658
|
-
|
|
98659
|
-
|
|
98660
|
-
|
|
98661
|
-
|
|
98662
|
-
|
|
98663
|
-
|
|
98664
|
-
|
|
98665
|
-
|
|
98666
|
-
|
|
98667
|
-
}
|
|
98668
|
-
|
|
98669
|
-
|
|
98670
|
-
|
|
98671
|
-
|
|
98672
|
-
|
|
98673
|
-
|
|
98674
|
-
|
|
98675
|
-
|
|
98676
|
-
|
|
98677
|
-
|
|
98678
|
-
|
|
98679
|
-
|
|
98680
|
-
|
|
98681
|
-
|
|
98682
|
-
|
|
98683
|
-
|
|
98684
|
-
|
|
98685
|
-
|
|
98686
|
-
|
|
98687
|
-
|
|
98688
|
-
|
|
98689
|
-
|
|
98690
|
-
|
|
98691
|
-
|
|
98692
|
-
|
|
98693
|
-
|
|
98694
|
-
|
|
98695
|
-
|
|
98696
|
-
|
|
98697
|
-
|
|
98698
|
-
|
|
98699
|
-
|
|
98700
|
-
|
|
98701
|
-
|
|
98702
|
-
|
|
98703
|
-
|
|
98704
|
-
|
|
98705
|
-
|
|
98706
|
-
|
|
98707
|
-
|
|
98708
|
-
overflow > 0 && /* @__PURE__ */ jsxs(
|
|
98709
|
-
"div",
|
|
98710
|
-
{
|
|
98711
|
-
className: "w-7 h-7 rounded-full flex items-center justify-center text-[10px] font-semibold text-gray-300 bg-gray-700 border-2 border-gray-600 -ml-1",
|
|
98712
|
-
title: t2("pptx.collaboration.moreUsers", { count: overflow }),
|
|
98713
|
-
children: [
|
|
98714
|
-
"+",
|
|
98715
|
-
overflow
|
|
98716
|
-
]
|
|
98717
|
-
}
|
|
98718
|
-
)
|
|
98719
|
-
]
|
|
98720
|
-
}
|
|
98721
|
-
);
|
|
98722
|
-
}
|
|
98723
|
-
var STATUS_STYLES = {
|
|
98724
|
-
connected: {
|
|
98725
|
-
dot: "bg-green-400",
|
|
98726
|
-
text: "text-green-400",
|
|
98727
|
-
label: "Connected"
|
|
98728
|
-
},
|
|
98729
|
-
connecting: {
|
|
98730
|
-
dot: "bg-yellow-400 animate-pulse",
|
|
98731
|
-
text: "text-yellow-400",
|
|
98732
|
-
label: "Connecting..."
|
|
98733
|
-
},
|
|
98734
|
-
disconnected: {
|
|
98735
|
-
dot: "bg-gray-500",
|
|
98736
|
-
text: "text-gray-500",
|
|
98737
|
-
label: "Disconnected"
|
|
98738
|
-
},
|
|
98739
|
-
error: {
|
|
98740
|
-
dot: "bg-red-400",
|
|
98741
|
-
text: "text-red-400",
|
|
98742
|
-
label: "Connection error"
|
|
98743
|
-
}
|
|
98744
|
-
};
|
|
98745
|
-
function CollaborationStatusIndicator({
|
|
98746
|
-
status,
|
|
98747
|
-
connectedCount
|
|
98748
|
-
}) {
|
|
98749
|
-
const { t: t2 } = useTranslation();
|
|
98750
|
-
const style = STATUS_STYLES[status];
|
|
98751
|
-
return /* @__PURE__ */ jsxs(
|
|
98752
|
-
"div",
|
|
98753
|
-
{
|
|
98754
|
-
"data-testid": "collaboration-status",
|
|
98755
|
-
className: "flex items-center gap-1.5",
|
|
98756
|
-
"aria-label": t2("pptx.collaboration.statusAriaLabel", {
|
|
98757
|
-
status: t2(`pptx.collaboration.status.${status}`),
|
|
98758
|
-
count: connectedCount
|
|
98759
|
-
}),
|
|
98760
|
-
children: [
|
|
98761
|
-
/* @__PURE__ */ jsx("span", { className: `inline-block w-2 h-2 rounded-full ${style.dot}`, "aria-hidden": "true" }),
|
|
98762
|
-
/* @__PURE__ */ jsx("span", { className: `text-[10px] ${style.text}`, children: status === "connected" ? t2("pptx.collaboration.userCount", { count: connectedCount }) : t2(`pptx.collaboration.status.${status}`) })
|
|
98763
|
-
]
|
|
98764
|
-
}
|
|
98765
|
-
);
|
|
98848
|
+
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98849
|
+
p3.onUpdateTextStyle({
|
|
98850
|
+
listType: ts?.listType === "numbered" ? "none" : "numbered"
|
|
98851
|
+
});
|
|
98852
|
+
},
|
|
98853
|
+
className: gL,
|
|
98854
|
+
title: "Numbered List",
|
|
98855
|
+
children: /* @__PURE__ */ jsx(LuListOrdered, { className: ic2 })
|
|
98856
|
+
}
|
|
98857
|
+
)
|
|
98858
|
+
] }),
|
|
98859
|
+
/* @__PURE__ */ jsxs("div", { className: grp, children: [
|
|
98860
|
+
/* @__PURE__ */ jsx(
|
|
98861
|
+
"button",
|
|
98862
|
+
{
|
|
98863
|
+
type: "button",
|
|
98864
|
+
disabled: !canMut,
|
|
98865
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98866
|
+
onClick: () => {
|
|
98867
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98868
|
+
return;
|
|
98869
|
+
}
|
|
98870
|
+
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98871
|
+
const current = ts?.paragraphMarginLeft ?? 0;
|
|
98872
|
+
p3.onUpdateTextStyle({
|
|
98873
|
+
paragraphMarginLeft: Math.max(0, current - 24)
|
|
98874
|
+
});
|
|
98875
|
+
},
|
|
98876
|
+
className: gB,
|
|
98877
|
+
title: "Decrease Indent",
|
|
98878
|
+
children: /* @__PURE__ */ jsx(LuIndentDecrease, { className: ic2 })
|
|
98879
|
+
}
|
|
98880
|
+
),
|
|
98881
|
+
/* @__PURE__ */ jsx(
|
|
98882
|
+
"button",
|
|
98883
|
+
{
|
|
98884
|
+
type: "button",
|
|
98885
|
+
disabled: !canMut,
|
|
98886
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98887
|
+
onClick: () => {
|
|
98888
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98889
|
+
return;
|
|
98890
|
+
}
|
|
98891
|
+
const ts = hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98892
|
+
const current = ts?.paragraphMarginLeft ?? 0;
|
|
98893
|
+
p3.onUpdateTextStyle({
|
|
98894
|
+
paragraphMarginLeft: current + 24
|
|
98895
|
+
});
|
|
98896
|
+
},
|
|
98897
|
+
className: gL,
|
|
98898
|
+
title: "Increase Indent",
|
|
98899
|
+
children: /* @__PURE__ */ jsx(LuIndentIncrease, { className: ic2 })
|
|
98900
|
+
}
|
|
98901
|
+
)
|
|
98902
|
+
] }),
|
|
98903
|
+
/* @__PURE__ */ jsx("div", { className: grp, children: ATXT.map((b2, i3, a2) => {
|
|
98904
|
+
const handleClick = () => {
|
|
98905
|
+
if (!canFormat) {
|
|
98906
|
+
return;
|
|
98907
|
+
}
|
|
98908
|
+
const alignMap = {
|
|
98909
|
+
"Align left": "left",
|
|
98910
|
+
"Align center": "center",
|
|
98911
|
+
"Align right": "right",
|
|
98912
|
+
Justify: "justify"
|
|
98913
|
+
};
|
|
98914
|
+
const align = alignMap[b2.t];
|
|
98915
|
+
if (align) {
|
|
98916
|
+
p3.onUpdateTextStyle({ align });
|
|
98917
|
+
}
|
|
98918
|
+
};
|
|
98919
|
+
return /* @__PURE__ */ jsx(
|
|
98920
|
+
"button",
|
|
98921
|
+
{
|
|
98922
|
+
type: "button",
|
|
98923
|
+
disabled: !canMut,
|
|
98924
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98925
|
+
onClick: handleClick,
|
|
98926
|
+
className: i3 < a2.length - 1 ? gB : gL,
|
|
98927
|
+
title: b2.t,
|
|
98928
|
+
children: b2.i
|
|
98929
|
+
},
|
|
98930
|
+
b2.t
|
|
98931
|
+
);
|
|
98932
|
+
}) })
|
|
98933
|
+
] }),
|
|
98934
|
+
/* @__PURE__ */ jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Paragraph" })
|
|
98935
|
+
] })
|
|
98936
|
+
] });
|
|
98766
98937
|
}
|
|
98767
98938
|
function CustomShowsControls({
|
|
98768
98939
|
customShows,
|
|
@@ -99202,29 +99373,38 @@ function ToolbarPrimaryRow(p3) {
|
|
|
99202
99373
|
]
|
|
99203
99374
|
}
|
|
99204
99375
|
),
|
|
99205
|
-
collab && (collab.status === "connected" || collab.status === "connecting") && collab.remoteUsers.length > 0 && /* @__PURE__ */ jsxs(
|
|
99206
|
-
|
|
99207
|
-
|
|
99208
|
-
|
|
99209
|
-
|
|
99210
|
-
|
|
99211
|
-
|
|
99212
|
-
|
|
99213
|
-
|
|
99376
|
+
collab && (collab.status === "connected" || collab.status === "connecting") && collab.remoteUsers.length > 0 && /* @__PURE__ */ jsxs(
|
|
99377
|
+
"button",
|
|
99378
|
+
{
|
|
99379
|
+
type: "button",
|
|
99380
|
+
onClick: p3.onOpenShareDialog,
|
|
99381
|
+
className: "flex items-center -space-x-1.5 mx-1 rounded-sm px-1 py-0.5 hover:bg-accent/60 transition-colors cursor-pointer",
|
|
99382
|
+
title: t2("pptx.toolbar.sharingUsers", { count: collab.connectedCount }),
|
|
99383
|
+
children: [
|
|
99384
|
+
collab.remoteUsers.slice(0, 4).map((user) => /* @__PURE__ */ jsx(
|
|
99385
|
+
"div",
|
|
99214
99386
|
{
|
|
99215
|
-
|
|
99216
|
-
|
|
99217
|
-
|
|
99218
|
-
|
|
99219
|
-
|
|
99220
|
-
|
|
99221
|
-
|
|
99222
|
-
|
|
99223
|
-
|
|
99224
|
-
|
|
99225
|
-
|
|
99226
|
-
|
|
99227
|
-
|
|
99387
|
+
className: "w-6 h-6 rounded-full border-2 border-background flex items-center justify-center text-[8px] font-semibold text-white shrink-0",
|
|
99388
|
+
style: { backgroundColor: user.userColor },
|
|
99389
|
+
title: user.userName,
|
|
99390
|
+
children: user.userAvatar ? /* @__PURE__ */ jsx(
|
|
99391
|
+
"img",
|
|
99392
|
+
{
|
|
99393
|
+
src: user.userAvatar,
|
|
99394
|
+
alt: user.userName,
|
|
99395
|
+
className: "w-full h-full rounded-full object-cover"
|
|
99396
|
+
}
|
|
99397
|
+
) : user.userName.slice(0, 2).toUpperCase()
|
|
99398
|
+
},
|
|
99399
|
+
user.clientId
|
|
99400
|
+
)),
|
|
99401
|
+
collab.remoteUsers.length > 4 && /* @__PURE__ */ jsxs("div", { className: "w-6 h-6 rounded-full border-2 border-background bg-muted flex items-center justify-center text-[8px] text-muted-foreground shrink-0", children: [
|
|
99402
|
+
"+",
|
|
99403
|
+
collab.remoteUsers.length - 4
|
|
99404
|
+
] })
|
|
99405
|
+
]
|
|
99406
|
+
}
|
|
99407
|
+
),
|
|
99228
99408
|
/* @__PURE__ */ jsx(
|
|
99229
99409
|
ModeSwitcher,
|
|
99230
99410
|
{
|
|
@@ -99601,7 +99781,8 @@ function Toolbar(p3) {
|
|
|
99601
99781
|
canEdit: p3.canEdit,
|
|
99602
99782
|
selectedElement: p3.selectedElement,
|
|
99603
99783
|
isInspectorPaneOpen: p3.isInspectorPaneOpen,
|
|
99604
|
-
onToggleInspector: p3.onToggleInspector
|
|
99784
|
+
onToggleInspector: p3.onToggleInspector,
|
|
99785
|
+
onOpenAnimationPanel: p3.onOpenAnimationPanel
|
|
99605
99786
|
}
|
|
99606
99787
|
),
|
|
99607
99788
|
sSlw && /* @__PURE__ */ jsx(
|
|
@@ -107046,9 +107227,75 @@ function SetUpSlideShowDialog({
|
|
|
107046
107227
|
}
|
|
107047
107228
|
function BroadcastDialog({
|
|
107048
107229
|
open,
|
|
107049
|
-
onClose
|
|
107230
|
+
onClose,
|
|
107231
|
+
onStartBroadcast,
|
|
107232
|
+
onStopBroadcast,
|
|
107233
|
+
onStartPresenting,
|
|
107234
|
+
defaultRoomId,
|
|
107235
|
+
defaultUserName,
|
|
107236
|
+
defaultServerUrl
|
|
107050
107237
|
}) {
|
|
107051
107238
|
const { t: t2 } = useTranslation();
|
|
107239
|
+
const collab = useCollaboration();
|
|
107240
|
+
const isBroadcasting = collab !== null && collab.status !== "disconnected" && collab.status !== "error" && collab.config.role === "broadcaster";
|
|
107241
|
+
const [roomId, setRoomId] = useState("");
|
|
107242
|
+
const [userName, setUserName] = useState("");
|
|
107243
|
+
const [serverUrl, setServerUrl] = useState("");
|
|
107244
|
+
const [copied, setCopied] = useState(false);
|
|
107245
|
+
const dialogRef = useRef(null);
|
|
107246
|
+
useEffect(() => {
|
|
107247
|
+
if (open && !isBroadcasting) {
|
|
107248
|
+
const broadcastRoom = defaultRoomId ? `broadcast-${defaultRoomId}` : `broadcast-${Math.random().toString(36).slice(2, 10)}`;
|
|
107249
|
+
setRoomId(broadcastRoom);
|
|
107250
|
+
setUserName(defaultUserName ?? "");
|
|
107251
|
+
setServerUrl(defaultServerUrl ?? "ws://localhost:1234");
|
|
107252
|
+
}
|
|
107253
|
+
}, [open, isBroadcasting, defaultRoomId, defaultUserName, defaultServerUrl]);
|
|
107254
|
+
useEffect(() => {
|
|
107255
|
+
if (!open) {
|
|
107256
|
+
return;
|
|
107257
|
+
}
|
|
107258
|
+
function handleKeyDown(e2) {
|
|
107259
|
+
if (e2.key === "Escape") {
|
|
107260
|
+
onClose();
|
|
107261
|
+
}
|
|
107262
|
+
}
|
|
107263
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
107264
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
107265
|
+
}, [open, onClose]);
|
|
107266
|
+
useEffect(() => {
|
|
107267
|
+
if (open && dialogRef.current) {
|
|
107268
|
+
dialogRef.current.focus();
|
|
107269
|
+
}
|
|
107270
|
+
}, [open]);
|
|
107271
|
+
const broadcastUrl = typeof window !== "undefined" ? `${window.location.origin}${window.location.pathname}?broadcast=${encodeURIComponent(isBroadcasting ? collab.config.roomId : roomId)}&server=${encodeURIComponent(isBroadcasting ? collab.config.serverUrl : serverUrl)}` : roomId;
|
|
107272
|
+
const handleCopyUrl = useCallback(() => {
|
|
107273
|
+
void navigator.clipboard.writeText(broadcastUrl).then(() => {
|
|
107274
|
+
setCopied(true);
|
|
107275
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
107276
|
+
return void 0;
|
|
107277
|
+
});
|
|
107278
|
+
}, [broadcastUrl]);
|
|
107279
|
+
const handleStartBroadcast = useCallback(() => {
|
|
107280
|
+
if (!roomId.trim() || !userName.trim()) {
|
|
107281
|
+
return;
|
|
107282
|
+
}
|
|
107283
|
+
onStartBroadcast?.({
|
|
107284
|
+
roomId: roomId.trim(),
|
|
107285
|
+
serverUrl: serverUrl.trim(),
|
|
107286
|
+
userName: userName.trim(),
|
|
107287
|
+
role: "broadcaster"
|
|
107288
|
+
});
|
|
107289
|
+
setTimeout(() => {
|
|
107290
|
+
onStartPresenting?.();
|
|
107291
|
+
}, 100);
|
|
107292
|
+
onClose();
|
|
107293
|
+
}, [roomId, userName, serverUrl, onStartBroadcast, onStartPresenting, onClose]);
|
|
107294
|
+
const handleStopBroadcast = useCallback(() => {
|
|
107295
|
+
onStopBroadcast?.();
|
|
107296
|
+
onClose();
|
|
107297
|
+
}, [onStopBroadcast, onClose]);
|
|
107298
|
+
const canStart = roomId.trim().length > 0 && userName.trim().length > 0 && serverUrl.trim().length > 0;
|
|
107052
107299
|
if (!open) {
|
|
107053
107300
|
return null;
|
|
107054
107301
|
}
|
|
@@ -107062,42 +107309,225 @@ function BroadcastDialog({
|
|
|
107062
107309
|
onClick: onClose
|
|
107063
107310
|
}
|
|
107064
107311
|
),
|
|
107065
|
-
/* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-[201] flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs(
|
|
107066
|
-
|
|
107067
|
-
|
|
107312
|
+
/* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-[201] flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs(
|
|
107313
|
+
"div",
|
|
107314
|
+
{
|
|
107315
|
+
ref: dialogRef,
|
|
107316
|
+
role: "dialog",
|
|
107317
|
+
"aria-modal": "true",
|
|
107318
|
+
"aria-label": t2("pptx.broadcast.title"),
|
|
107319
|
+
tabIndex: -1,
|
|
107320
|
+
className: "pointer-events-auto w-full max-w-md rounded-xl border border-border bg-popover text-foreground shadow-2xl outline-none",
|
|
107321
|
+
children: [
|
|
107322
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-5 py-3 border-b border-border", children: [
|
|
107323
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-sm font-semibold text-foreground flex items-center gap-2", children: [
|
|
107324
|
+
/* @__PURE__ */ jsx(LuCast, { className: "w-4 h-4" }),
|
|
107325
|
+
isBroadcasting ? t2("pptx.broadcast.broadcasting") : t2("pptx.broadcast.title")
|
|
107326
|
+
] }),
|
|
107327
|
+
/* @__PURE__ */ jsx(
|
|
107328
|
+
"button",
|
|
107329
|
+
{
|
|
107330
|
+
type: "button",
|
|
107331
|
+
onClick: onClose,
|
|
107332
|
+
className: "text-muted-foreground hover:text-foreground text-lg leading-none",
|
|
107333
|
+
"aria-label": "Close",
|
|
107334
|
+
children: "\xD7"
|
|
107335
|
+
}
|
|
107336
|
+
)
|
|
107337
|
+
] }),
|
|
107338
|
+
/* @__PURE__ */ jsx("div", { className: "px-5 py-4", children: isBroadcasting ? /* @__PURE__ */ jsx(
|
|
107339
|
+
ActiveBroadcastView,
|
|
107340
|
+
{
|
|
107341
|
+
collab,
|
|
107342
|
+
broadcastUrl,
|
|
107343
|
+
copied,
|
|
107344
|
+
onCopyUrl: handleCopyUrl,
|
|
107345
|
+
onStopBroadcast: handleStopBroadcast
|
|
107346
|
+
}
|
|
107347
|
+
) : /* @__PURE__ */ jsx(
|
|
107348
|
+
StartBroadcastForm,
|
|
107349
|
+
{
|
|
107350
|
+
roomId,
|
|
107351
|
+
userName,
|
|
107352
|
+
serverUrl,
|
|
107353
|
+
onRoomIdChange: setRoomId,
|
|
107354
|
+
onUserNameChange: setUserName,
|
|
107355
|
+
onServerUrlChange: setServerUrl
|
|
107356
|
+
}
|
|
107357
|
+
) }),
|
|
107358
|
+
!isBroadcasting && /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2 px-5 py-3 border-t border-border", children: [
|
|
107359
|
+
/* @__PURE__ */ jsx(
|
|
107360
|
+
"button",
|
|
107361
|
+
{
|
|
107362
|
+
type: "button",
|
|
107363
|
+
onClick: onClose,
|
|
107364
|
+
className: "px-3 py-1.5 rounded bg-muted hover:bg-accent text-[12px] text-foreground transition-colors",
|
|
107365
|
+
children: t2("common.close")
|
|
107366
|
+
}
|
|
107367
|
+
),
|
|
107368
|
+
/* @__PURE__ */ jsx(
|
|
107369
|
+
"button",
|
|
107370
|
+
{
|
|
107371
|
+
type: "button",
|
|
107372
|
+
disabled: !canStart,
|
|
107373
|
+
onClick: handleStartBroadcast,
|
|
107374
|
+
className: "px-3 py-1.5 rounded bg-primary hover:bg-primary/90 text-[12px] text-primary-foreground transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
|
|
107375
|
+
children: t2("pptx.broadcast.startBroadcast")
|
|
107376
|
+
}
|
|
107377
|
+
)
|
|
107378
|
+
] })
|
|
107379
|
+
]
|
|
107380
|
+
}
|
|
107381
|
+
) })
|
|
107382
|
+
] });
|
|
107383
|
+
}
|
|
107384
|
+
function StartBroadcastForm({
|
|
107385
|
+
roomId,
|
|
107386
|
+
userName,
|
|
107387
|
+
serverUrl,
|
|
107388
|
+
onRoomIdChange,
|
|
107389
|
+
onUserNameChange,
|
|
107390
|
+
onServerUrlChange
|
|
107391
|
+
}) {
|
|
107392
|
+
const { t: t2 } = useTranslation();
|
|
107393
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
107394
|
+
/* @__PURE__ */ jsx("p", { className: "text-[13px] text-muted-foreground leading-relaxed", children: t2("pptx.broadcast.description") }),
|
|
107395
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
107396
|
+
/* @__PURE__ */ jsx(
|
|
107397
|
+
"label",
|
|
107398
|
+
{
|
|
107399
|
+
htmlFor: "broadcast-room-id",
|
|
107400
|
+
className: "block text-[12px] font-medium text-foreground",
|
|
107401
|
+
children: t2("pptx.broadcast.sessionName")
|
|
107402
|
+
}
|
|
107403
|
+
),
|
|
107404
|
+
/* @__PURE__ */ jsx(
|
|
107405
|
+
"input",
|
|
107406
|
+
{
|
|
107407
|
+
id: "broadcast-room-id",
|
|
107408
|
+
type: "text",
|
|
107409
|
+
value: roomId,
|
|
107410
|
+
onChange: (e2) => onRoomIdChange(e2.target.value),
|
|
107411
|
+
placeholder: "broadcast-abc123",
|
|
107412
|
+
className: "w-full px-3 py-1.5 rounded border border-border bg-background text-foreground text-[13px] placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary"
|
|
107413
|
+
}
|
|
107414
|
+
)
|
|
107415
|
+
] }),
|
|
107416
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
107417
|
+
/* @__PURE__ */ jsx(
|
|
107418
|
+
"label",
|
|
107419
|
+
{
|
|
107420
|
+
htmlFor: "broadcast-user-name",
|
|
107421
|
+
className: "block text-[12px] font-medium text-foreground",
|
|
107422
|
+
children: t2("pptx.broadcast.displayName")
|
|
107423
|
+
}
|
|
107424
|
+
),
|
|
107425
|
+
/* @__PURE__ */ jsx(
|
|
107426
|
+
"input",
|
|
107427
|
+
{
|
|
107428
|
+
id: "broadcast-user-name",
|
|
107429
|
+
type: "text",
|
|
107430
|
+
value: userName,
|
|
107431
|
+
onChange: (e2) => onUserNameChange(e2.target.value),
|
|
107432
|
+
placeholder: "Presenter",
|
|
107433
|
+
className: "w-full px-3 py-1.5 rounded border border-border bg-background text-foreground text-[13px] placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary"
|
|
107434
|
+
}
|
|
107435
|
+
)
|
|
107436
|
+
] }),
|
|
107437
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
107438
|
+
/* @__PURE__ */ jsx(
|
|
107439
|
+
"label",
|
|
107440
|
+
{
|
|
107441
|
+
htmlFor: "broadcast-server-url",
|
|
107442
|
+
className: "block text-[12px] font-medium text-foreground",
|
|
107443
|
+
children: t2("pptx.broadcast.serverLabel")
|
|
107444
|
+
}
|
|
107445
|
+
),
|
|
107446
|
+
/* @__PURE__ */ jsx(
|
|
107447
|
+
"input",
|
|
107448
|
+
{
|
|
107449
|
+
id: "broadcast-server-url",
|
|
107450
|
+
type: "text",
|
|
107451
|
+
value: serverUrl,
|
|
107452
|
+
onChange: (e2) => onServerUrlChange(e2.target.value),
|
|
107453
|
+
placeholder: "ws://localhost:1234",
|
|
107454
|
+
className: "w-full px-3 py-1.5 rounded border border-border bg-background text-foreground text-[13px] placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary"
|
|
107455
|
+
}
|
|
107456
|
+
)
|
|
107457
|
+
] }),
|
|
107458
|
+
/* @__PURE__ */ jsx("p", { className: "text-[11px] text-muted-foreground/70 leading-relaxed", children: t2("pptx.broadcast.hint") })
|
|
107459
|
+
] });
|
|
107460
|
+
}
|
|
107461
|
+
function ActiveBroadcastView({
|
|
107462
|
+
collab,
|
|
107463
|
+
broadcastUrl,
|
|
107464
|
+
copied,
|
|
107465
|
+
onCopyUrl,
|
|
107466
|
+
onStopBroadcast
|
|
107467
|
+
}) {
|
|
107468
|
+
const { t: t2 } = useTranslation();
|
|
107469
|
+
const statusColor = collab.status === "connected" ? "text-green-400" : collab.status === "connecting" ? "text-yellow-400" : "text-red-400";
|
|
107470
|
+
const statusIcon = collab.status === "connected" || collab.status === "connecting" ? /* @__PURE__ */ jsx(LuWifi, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx(LuWifiOff, { className: "w-4 h-4" });
|
|
107471
|
+
const viewerCount = collab.remoteUsers.filter((u2) => u2.role === "viewer").length;
|
|
107472
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
107473
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
107474
|
+
/* @__PURE__ */ jsx("span", { className: statusColor, children: statusIcon }),
|
|
107475
|
+
/* @__PURE__ */ jsx("span", { className: "text-[13px] font-medium text-foreground capitalize", children: collab.status }),
|
|
107476
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[12px] text-muted-foreground ml-auto flex items-center gap-1", children: [
|
|
107477
|
+
/* @__PURE__ */ jsx(LuUsers, { className: "w-3.5 h-3.5" }),
|
|
107478
|
+
t2("pptx.broadcast.viewerCount", { count: viewerCount })
|
|
107479
|
+
] })
|
|
107480
|
+
] }),
|
|
107481
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
107482
|
+
/* @__PURE__ */ jsx("label", { className: "block text-[12px] font-medium text-foreground", children: t2("pptx.broadcast.viewerLink") }),
|
|
107483
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
107484
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 px-3 py-1.5 rounded border border-border bg-background text-[11px] text-foreground select-all font-mono truncate", children: broadcastUrl }),
|
|
107068
107485
|
/* @__PURE__ */ jsx(
|
|
107069
107486
|
"button",
|
|
107070
107487
|
{
|
|
107071
107488
|
type: "button",
|
|
107072
|
-
onClick:
|
|
107073
|
-
className: "
|
|
107074
|
-
|
|
107075
|
-
children:
|
|
107489
|
+
onClick: onCopyUrl,
|
|
107490
|
+
className: "flex items-center gap-1 px-2.5 py-1.5 rounded border border-border bg-muted hover:bg-accent text-[12px] text-foreground transition-colors shrink-0",
|
|
107491
|
+
title: t2("pptx.broadcast.copyLink"),
|
|
107492
|
+
children: copied ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
107493
|
+
/* @__PURE__ */ jsx(LuCheck, { className: "w-3.5 h-3.5 text-green-400" }),
|
|
107494
|
+
/* @__PURE__ */ jsx("span", { children: t2("pptx.share.copied") })
|
|
107495
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
107496
|
+
/* @__PURE__ */ jsx(LuCopy, { className: "w-3.5 h-3.5" }),
|
|
107497
|
+
/* @__PURE__ */ jsx("span", { children: t2("pptx.share.copyUrl") })
|
|
107498
|
+
] })
|
|
107076
107499
|
}
|
|
107077
107500
|
)
|
|
107078
107501
|
] }),
|
|
107079
|
-
/* @__PURE__ */ jsx("
|
|
107080
|
-
|
|
107502
|
+
/* @__PURE__ */ jsx("p", { className: "text-[11px] text-muted-foreground", children: t2("pptx.broadcast.shareHint") })
|
|
107503
|
+
] }),
|
|
107504
|
+
collab.remoteUsers.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
107505
|
+
/* @__PURE__ */ jsx("label", { className: "block text-[12px] font-medium text-foreground", children: t2("pptx.broadcast.viewers") }),
|
|
107506
|
+
/* @__PURE__ */ jsx("div", { className: "rounded border border-border bg-background divide-y divide-border max-h-[120px] overflow-y-auto", children: collab.remoteUsers.map((user) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2", children: [
|
|
107081
107507
|
/* @__PURE__ */ jsx(
|
|
107082
|
-
"
|
|
107508
|
+
"div",
|
|
107083
107509
|
{
|
|
107084
|
-
|
|
107085
|
-
|
|
107086
|
-
|
|
107087
|
-
children: t2("common.close")
|
|
107510
|
+
className: "w-5 h-5 rounded-full flex items-center justify-center text-[8px] font-semibold text-white shrink-0",
|
|
107511
|
+
style: { backgroundColor: user.userColor },
|
|
107512
|
+
children: user.userName.slice(0, 2).toUpperCase()
|
|
107088
107513
|
}
|
|
107089
107514
|
),
|
|
107090
|
-
/* @__PURE__ */ jsx(
|
|
107091
|
-
|
|
107092
|
-
|
|
107093
|
-
|
|
107094
|
-
|
|
107095
|
-
|
|
107096
|
-
|
|
107097
|
-
|
|
107098
|
-
|
|
107099
|
-
|
|
107100
|
-
|
|
107515
|
+
/* @__PURE__ */ jsx("span", { className: "text-[12px] text-foreground truncate", children: user.userName }),
|
|
107516
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground ml-auto", children: [
|
|
107517
|
+
"Slide ",
|
|
107518
|
+
user.activeSlideIndex + 1
|
|
107519
|
+
] })
|
|
107520
|
+
] }, user.clientId)) })
|
|
107521
|
+
] }),
|
|
107522
|
+
/* @__PURE__ */ jsx(
|
|
107523
|
+
"button",
|
|
107524
|
+
{
|
|
107525
|
+
type: "button",
|
|
107526
|
+
onClick: onStopBroadcast,
|
|
107527
|
+
className: "w-full px-3 py-2 rounded border border-red-500/30 bg-red-500/10 hover:bg-red-500/20 text-[12px] text-red-400 font-medium transition-colors",
|
|
107528
|
+
children: t2("pptx.broadcast.stopBroadcast")
|
|
107529
|
+
}
|
|
107530
|
+
)
|
|
107101
107531
|
] });
|
|
107102
107532
|
}
|
|
107103
107533
|
function getInitials2(name) {
|
|
@@ -108681,7 +109111,8 @@ function useDrawingOverlay({
|
|
|
108681
109111
|
drawingWidth,
|
|
108682
109112
|
isDrawingRef,
|
|
108683
109113
|
onAddInkElement,
|
|
108684
|
-
onAddFreeformShape
|
|
109114
|
+
onAddFreeformShape,
|
|
109115
|
+
onEraseInkElement
|
|
108685
109116
|
}) {
|
|
108686
109117
|
const isDrawing = activeTool !== "select";
|
|
108687
109118
|
const [currentStrokePoints, setCurrentStrokePoints] = useState(
|
|
@@ -108730,6 +109161,7 @@ function useDrawingOverlay({
|
|
|
108730
109161
|
continue;
|
|
108731
109162
|
}
|
|
108732
109163
|
if (pt2.x >= el.x - HIT_RADIUS && pt2.x <= el.x + el.width + HIT_RADIUS && pt2.y >= el.y - HIT_RADIUS && pt2.y <= el.y + el.height + HIT_RADIUS) {
|
|
109164
|
+
onEraseInkElement?.(el.id);
|
|
108733
109165
|
break;
|
|
108734
109166
|
}
|
|
108735
109167
|
}
|
|
@@ -108748,7 +109180,7 @@ function useDrawingOverlay({
|
|
|
108748
109180
|
isDrawingRef.current = true;
|
|
108749
109181
|
}
|
|
108750
109182
|
},
|
|
108751
|
-
[activeTool, activeSlide, pointerToCanvasCoords, isDrawingRef]
|
|
109183
|
+
[activeTool, activeSlide, pointerToCanvasCoords, isDrawingRef, onEraseInkElement]
|
|
108752
109184
|
);
|
|
108753
109185
|
const handleDrawPointerMove = useCallback(
|
|
108754
109186
|
(e2) => {
|
|
@@ -108818,6 +109250,9 @@ function useDrawingOverlay({
|
|
|
108818
109250
|
i3 === 0 ? { type: "moveTo", pt: scaledPt } : { type: "lineTo", pt: scaledPt }
|
|
108819
109251
|
);
|
|
108820
109252
|
}
|
|
109253
|
+
if (segments.length > 2) {
|
|
109254
|
+
segments.push({ type: "close" });
|
|
109255
|
+
}
|
|
108821
109256
|
const freeformShape = {
|
|
108822
109257
|
id: `shape-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
108823
109258
|
type: "shape",
|
|
@@ -108827,7 +109262,7 @@ function useDrawingOverlay({
|
|
|
108827
109262
|
height: h2,
|
|
108828
109263
|
shapeType: "custom",
|
|
108829
109264
|
shapeStyle: {
|
|
108830
|
-
fillColor:
|
|
109265
|
+
fillColor: "transparent",
|
|
108831
109266
|
strokeColor: drawingColor,
|
|
108832
109267
|
strokeWidth: drawingWidth
|
|
108833
109268
|
},
|
|
@@ -108977,6 +109412,7 @@ function SlideCanvas({
|
|
|
108977
109412
|
isDrawingRef,
|
|
108978
109413
|
onAddInkElement,
|
|
108979
109414
|
onAddFreeformShape,
|
|
109415
|
+
onEraseInkElement,
|
|
108980
109416
|
onActionClick,
|
|
108981
109417
|
onHyperlinkClick,
|
|
108982
109418
|
comments,
|
|
@@ -109062,7 +109498,8 @@ function SlideCanvas({
|
|
|
109062
109498
|
drawingWidth,
|
|
109063
109499
|
isDrawingRef,
|
|
109064
109500
|
onAddInkElement,
|
|
109065
|
-
onAddFreeformShape
|
|
109501
|
+
onAddFreeformShape,
|
|
109502
|
+
onEraseInkElement
|
|
109066
109503
|
});
|
|
109067
109504
|
const rulerOffset = showRulers ? RULER_THICKNESS : 0;
|
|
109068
109505
|
return /* @__PURE__ */ jsx(
|
|
@@ -109558,6 +109995,10 @@ function ViewerToolbarSection(props) {
|
|
|
109558
109995
|
onSetMode,
|
|
109559
109996
|
onToggleSidebar: () => s.setIsSlidesPaneOpen((p3) => !p3),
|
|
109560
109997
|
onToggleInspector: () => s.setIsInspectorPaneOpen((p3) => !p3),
|
|
109998
|
+
onOpenAnimationPanel: () => {
|
|
109999
|
+
s.setIsInspectorPaneOpen(true);
|
|
110000
|
+
s.setSidebarPanelMode("properties");
|
|
110001
|
+
},
|
|
109561
110002
|
onToggleCompactToolbar: () => s.setIsCompactToolbarOpen((p3) => !p3),
|
|
109562
110003
|
onSetToolbarSection: s.setToolbarSection,
|
|
109563
110004
|
onZoomIn: zoom.handleZoomIn,
|
|
@@ -111229,13 +111670,6 @@ function ViewerDialogGroup(props) {
|
|
|
111229
111670
|
slideCount: slides.length
|
|
111230
111671
|
}
|
|
111231
111672
|
),
|
|
111232
|
-
/* @__PURE__ */ jsx(
|
|
111233
|
-
BroadcastDialog,
|
|
111234
|
-
{
|
|
111235
|
-
open: dialogs.isBroadcastDialogOpen,
|
|
111236
|
-
onClose: () => dialogs.setIsBroadcastDialogOpen(false)
|
|
111237
|
-
}
|
|
111238
|
-
),
|
|
111239
111673
|
/* @__PURE__ */ jsx(
|
|
111240
111674
|
PrintDialog,
|
|
111241
111675
|
{
|
|
@@ -111478,6 +111912,7 @@ function ViewerCanvasArea(props) {
|
|
|
111478
111912
|
isDrawingRef: s.isDrawingRef,
|
|
111479
111913
|
onAddInkElement: insertHandlers.handleAddInkElement,
|
|
111480
111914
|
onAddFreeformShape: insertHandlers.handleAddFreeformShape,
|
|
111915
|
+
onEraseInkElement: insertHandlers.handleEraseInkElement,
|
|
111481
111916
|
onActionClick: handleActionClick,
|
|
111482
111917
|
onHyperlinkClick: handleHyperlinkClick,
|
|
111483
111918
|
allSlides: mode === "present" ? slides : void 0,
|
|
@@ -111485,6 +111920,24 @@ function ViewerCanvasArea(props) {
|
|
|
111485
111920
|
sourceSlideIndex: mode === "present" ? activeSlideIndex : void 0,
|
|
111486
111921
|
fieldContext,
|
|
111487
111922
|
tableStyleContext,
|
|
111923
|
+
collaborationOverlay: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
111924
|
+
/* @__PURE__ */ jsx(
|
|
111925
|
+
RemoteSelectionOverlay,
|
|
111926
|
+
{
|
|
111927
|
+
elements: effectiveSlide?.elements ?? [],
|
|
111928
|
+
activeSlideIndex
|
|
111929
|
+
}
|
|
111930
|
+
),
|
|
111931
|
+
/* @__PURE__ */ jsx(
|
|
111932
|
+
CollaborationCursorOverlay,
|
|
111933
|
+
{
|
|
111934
|
+
activeSlideIndex,
|
|
111935
|
+
canvasWidth: canvasSize.width,
|
|
111936
|
+
canvasHeight: canvasSize.height,
|
|
111937
|
+
selectedElementId: s.selectedElementId
|
|
111938
|
+
}
|
|
111939
|
+
)
|
|
111940
|
+
] }),
|
|
111488
111941
|
comments: activeSlide?.comments,
|
|
111489
111942
|
showCommentMarkers: s.sidebarPanelMode === "comments",
|
|
111490
111943
|
onCommentMarkerClick: () => s.setSidebarPanelMode("comments"),
|
|
@@ -113095,6 +113548,37 @@ function useYjsDocumentSync({
|
|
|
113095
113548
|
};
|
|
113096
113549
|
}, [doc2, isConnected, getDocMap, setSlides]);
|
|
113097
113550
|
}
|
|
113551
|
+
function useBroadcastFollower({
|
|
113552
|
+
collab,
|
|
113553
|
+
activeSlideIndex,
|
|
113554
|
+
setActiveSlideIndex,
|
|
113555
|
+
slideCount
|
|
113556
|
+
}) {
|
|
113557
|
+
const lastBroadcasterSlide = useRef(-1);
|
|
113558
|
+
useEffect(() => {
|
|
113559
|
+
if (!collab) {
|
|
113560
|
+
return;
|
|
113561
|
+
}
|
|
113562
|
+
if (collab.config.role !== "viewer") {
|
|
113563
|
+
return;
|
|
113564
|
+
}
|
|
113565
|
+
const broadcaster = collab.remoteUsers.find((u2) => u2.role === "broadcaster");
|
|
113566
|
+
if (!broadcaster) {
|
|
113567
|
+
return;
|
|
113568
|
+
}
|
|
113569
|
+
const targetSlide = broadcaster.activeSlideIndex;
|
|
113570
|
+
if (targetSlide < 0 || targetSlide >= slideCount) {
|
|
113571
|
+
return;
|
|
113572
|
+
}
|
|
113573
|
+
if (targetSlide === lastBroadcasterSlide.current) {
|
|
113574
|
+
return;
|
|
113575
|
+
}
|
|
113576
|
+
lastBroadcasterSlide.current = targetSlide;
|
|
113577
|
+
if (targetSlide !== activeSlideIndex) {
|
|
113578
|
+
setActiveSlideIndex(targetSlide);
|
|
113579
|
+
}
|
|
113580
|
+
}, [collab, activeSlideIndex, setActiveSlideIndex, slideCount]);
|
|
113581
|
+
}
|
|
113098
113582
|
function computeGridSpacingPx(presentationGridSpacing) {
|
|
113099
113583
|
if (presentationGridSpacing) {
|
|
113100
113584
|
const px2 = Math.round(presentationGridSpacing.cx / EMU_PER_PX);
|
|
@@ -115435,6 +115919,17 @@ function useInsertElements(input) {
|
|
|
115435
115919
|
}
|
|
115436
115920
|
addElement(shape);
|
|
115437
115921
|
};
|
|
115922
|
+
const handleEraseInkElement = (elementId) => {
|
|
115923
|
+
if (!activeSlide) {
|
|
115924
|
+
return;
|
|
115925
|
+
}
|
|
115926
|
+
ops.updateSlides(
|
|
115927
|
+
(prev) => prev.map(
|
|
115928
|
+
(s, i3) => i3 === activeSlideIndex ? { ...s, elements: s.elements.filter((el) => el.id !== elementId) } : s
|
|
115929
|
+
)
|
|
115930
|
+
);
|
|
115931
|
+
history.markDirty();
|
|
115932
|
+
};
|
|
115438
115933
|
return {
|
|
115439
115934
|
handleAddTextBox,
|
|
115440
115935
|
handleAddShape,
|
|
@@ -115442,6 +115937,7 @@ function useInsertElements(input) {
|
|
|
115442
115937
|
...structured,
|
|
115443
115938
|
handleAddInkElement,
|
|
115444
115939
|
handleAddFreeformShape,
|
|
115940
|
+
handleEraseInkElement,
|
|
115445
115941
|
...fileHandlers
|
|
115446
115942
|
};
|
|
115447
115943
|
}
|
|
@@ -116271,7 +116767,8 @@ function useEditorOperations(input) {
|
|
|
116271
116767
|
selectedElementIds,
|
|
116272
116768
|
canvasSize,
|
|
116273
116769
|
dialogs,
|
|
116274
|
-
presentation
|
|
116770
|
+
presentation,
|
|
116771
|
+
userName
|
|
116275
116772
|
} = input;
|
|
116276
116773
|
const ops = useElementOperations({
|
|
116277
116774
|
activeSlide,
|
|
@@ -116305,6 +116802,7 @@ function useEditorOperations(input) {
|
|
|
116305
116802
|
const comments = useComments({
|
|
116306
116803
|
slides,
|
|
116307
116804
|
canEdit,
|
|
116805
|
+
userName,
|
|
116308
116806
|
selectedElementId: state2.selectedElementId,
|
|
116309
116807
|
onUpdateSlides: ops.updateSlides,
|
|
116310
116808
|
onMarkDirty: history.markDirty
|
|
@@ -123078,6 +123576,7 @@ var PowerPointViewer = forwardRef(
|
|
|
123078
123576
|
onDirtyChange,
|
|
123079
123577
|
onActiveSlideChange,
|
|
123080
123578
|
theme,
|
|
123579
|
+
authorName,
|
|
123081
123580
|
collaboration,
|
|
123082
123581
|
onStartCollaboration,
|
|
123083
123582
|
onStopCollaboration,
|
|
@@ -123235,7 +123734,8 @@ var PowerPointViewer = forwardRef(
|
|
|
123235
123734
|
selectedElementIds,
|
|
123236
123735
|
canvasSize,
|
|
123237
123736
|
dialogs,
|
|
123238
|
-
presentation
|
|
123737
|
+
presentation,
|
|
123738
|
+
userName: authorName ?? collaboration?.userName
|
|
123239
123739
|
});
|
|
123240
123740
|
const {
|
|
123241
123741
|
exportHandlers,
|
|
@@ -123438,6 +123938,19 @@ var PowerPointViewer = forwardRef(
|
|
|
123438
123938
|
defaultServerUrl: shareDefaults?.serverUrl
|
|
123439
123939
|
}
|
|
123440
123940
|
),
|
|
123941
|
+
/* @__PURE__ */ jsx(
|
|
123942
|
+
BroadcastDialog,
|
|
123943
|
+
{
|
|
123944
|
+
open: dialogs.isBroadcastDialogOpen,
|
|
123945
|
+
onClose: () => dialogs.setIsBroadcastDialogOpen(false),
|
|
123946
|
+
onStartBroadcast: onStartCollaboration,
|
|
123947
|
+
onStopBroadcast: onStopCollaboration,
|
|
123948
|
+
onStartPresenting: () => handleSetMode("present"),
|
|
123949
|
+
defaultRoomId: shareDefaults?.roomId,
|
|
123950
|
+
defaultUserName: shareDefaults?.userName,
|
|
123951
|
+
defaultServerUrl: shareDefaults?.serverUrl
|
|
123952
|
+
}
|
|
123953
|
+
),
|
|
123441
123954
|
/* @__PURE__ */ jsx(
|
|
123442
123955
|
ViewerOverlays,
|
|
123443
123956
|
{
|
|
@@ -123487,6 +124000,14 @@ var PowerPointViewer = forwardRef(
|
|
|
123487
124000
|
canvasHeight: canvasSize.height,
|
|
123488
124001
|
children: [
|
|
123489
124002
|
/* @__PURE__ */ jsx(CollaborationDocumentSync, { slides, setSlides: state2.setSlides }),
|
|
124003
|
+
/* @__PURE__ */ jsx(
|
|
124004
|
+
BroadcastFollowerSync,
|
|
124005
|
+
{
|
|
124006
|
+
activeSlideIndex,
|
|
124007
|
+
setActiveSlideIndex: state2.setActiveSlideIndex,
|
|
124008
|
+
slideCount: slides.length
|
|
124009
|
+
}
|
|
124010
|
+
),
|
|
123490
124011
|
viewerContent
|
|
123491
124012
|
]
|
|
123492
124013
|
}
|
|
@@ -123514,6 +124035,20 @@ function CollaborationDocumentSync({
|
|
|
123514
124035
|
});
|
|
123515
124036
|
return null;
|
|
123516
124037
|
}
|
|
124038
|
+
function BroadcastFollowerSync({
|
|
124039
|
+
activeSlideIndex,
|
|
124040
|
+
setActiveSlideIndex,
|
|
124041
|
+
slideCount
|
|
124042
|
+
}) {
|
|
124043
|
+
const collab = useCollaboration();
|
|
124044
|
+
useBroadcastFollower({
|
|
124045
|
+
collab,
|
|
124046
|
+
activeSlideIndex,
|
|
124047
|
+
setActiveSlideIndex,
|
|
124048
|
+
slideCount
|
|
124049
|
+
});
|
|
124050
|
+
return null;
|
|
124051
|
+
}
|
|
123517
124052
|
function colorSchemesMatch(a2, b2) {
|
|
123518
124053
|
if (!a2) {
|
|
123519
124054
|
return false;
|