pptx-react-viewer 1.0.11 → 1.0.12
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.js
CHANGED
|
@@ -43328,7 +43328,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43328
43328
|
return x2 === y && (0 !== x2 || 1 / x2 === 1 / y) || x2 !== x2 && y !== y;
|
|
43329
43329
|
}
|
|
43330
43330
|
function useSyncExternalStore$2(subscribe3, getSnapshot2) {
|
|
43331
|
-
didWarnOld18Alpha || void 0 ===
|
|
43331
|
+
didWarnOld18Alpha || void 0 === React96.startTransition || (didWarnOld18Alpha = true, console.error(
|
|
43332
43332
|
"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."
|
|
43333
43333
|
));
|
|
43334
43334
|
var value = getSnapshot2();
|
|
@@ -43338,7 +43338,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43338
43338
|
"The result of getSnapshot should be cached to avoid an infinite loop"
|
|
43339
43339
|
), didWarnUncachedGetSnapshot = true);
|
|
43340
43340
|
}
|
|
43341
|
-
cachedValue =
|
|
43341
|
+
cachedValue = useState85({
|
|
43342
43342
|
inst: { value, getSnapshot: getSnapshot2 }
|
|
43343
43343
|
});
|
|
43344
43344
|
var inst = cachedValue[0].inst, forceUpdate = cachedValue[1];
|
|
@@ -43350,7 +43350,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43350
43350
|
},
|
|
43351
43351
|
[subscribe3, value, getSnapshot2]
|
|
43352
43352
|
);
|
|
43353
|
-
|
|
43353
|
+
useEffect71(
|
|
43354
43354
|
function() {
|
|
43355
43355
|
checkIfSnapshotChanged(inst) && forceUpdate({ inst });
|
|
43356
43356
|
return subscribe3(function() {
|
|
@@ -43376,8 +43376,8 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43376
43376
|
return getSnapshot2();
|
|
43377
43377
|
}
|
|
43378
43378
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
43379
|
-
var
|
|
43380
|
-
exports$1.useSyncExternalStore = void 0 !==
|
|
43379
|
+
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;
|
|
43380
|
+
exports$1.useSyncExternalStore = void 0 !== React96.useSyncExternalStore ? React96.useSyncExternalStore : shim;
|
|
43381
43381
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
43382
43382
|
})();
|
|
43383
43383
|
}
|
|
@@ -43400,9 +43400,9 @@ var require_with_selector_development = __commonJS({
|
|
|
43400
43400
|
return x2 === y && (0 !== x2 || 1 / x2 === 1 / y) || x2 !== x2 && y !== y;
|
|
43401
43401
|
}
|
|
43402
43402
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
43403
|
-
var
|
|
43403
|
+
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;
|
|
43404
43404
|
exports$1.useSyncExternalStoreWithSelector = function(subscribe3, getSnapshot2, getServerSnapshot2, selector, isEqual) {
|
|
43405
|
-
var instRef =
|
|
43405
|
+
var instRef = useRef72(null);
|
|
43406
43406
|
if (null === instRef.current) {
|
|
43407
43407
|
var inst = { hasValue: false, value: null };
|
|
43408
43408
|
instRef.current = inst;
|
|
@@ -43443,7 +43443,7 @@ var require_with_selector_development = __commonJS({
|
|
|
43443
43443
|
[getSnapshot2, getServerSnapshot2, selector, isEqual]
|
|
43444
43444
|
);
|
|
43445
43445
|
var value = useSyncExternalStore3(subscribe3, instRef[0], instRef[1]);
|
|
43446
|
-
|
|
43446
|
+
useEffect71(
|
|
43447
43447
|
function() {
|
|
43448
43448
|
inst.hasValue = true;
|
|
43449
43449
|
inst.value = value;
|
|
@@ -91117,6 +91117,637 @@ function useVirtualizedSlides({
|
|
|
91117
91117
|
scrollToIndex
|
|
91118
91118
|
};
|
|
91119
91119
|
}
|
|
91120
|
+
|
|
91121
|
+
// src/viewer/hooks/collaboration/sanitize.ts
|
|
91122
|
+
var ROOM_ID_REGEX = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
91123
|
+
function validateRoomId(roomId) {
|
|
91124
|
+
if (!ROOM_ID_REGEX.test(roomId)) {
|
|
91125
|
+
throw new Error(
|
|
91126
|
+
`Invalid collaboration room ID: "${roomId}". Must be 1-128 alphanumeric characters, hyphens, or underscores.`
|
|
91127
|
+
);
|
|
91128
|
+
}
|
|
91129
|
+
return roomId;
|
|
91130
|
+
}
|
|
91131
|
+
function sanitizeUserName(name) {
|
|
91132
|
+
if (typeof name !== "string") {
|
|
91133
|
+
return "Anonymous";
|
|
91134
|
+
}
|
|
91135
|
+
const stripped = name.replace(/<[^>]*>/g, "");
|
|
91136
|
+
const trimmed = stripped.trim().slice(0, 64);
|
|
91137
|
+
return trimmed || "Anonymous";
|
|
91138
|
+
}
|
|
91139
|
+
function clampCursorPosition(value, min2, max2) {
|
|
91140
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
91141
|
+
return 0;
|
|
91142
|
+
}
|
|
91143
|
+
const margin = 20;
|
|
91144
|
+
return Math.max(min2 - margin, Math.min(max2 + margin, value));
|
|
91145
|
+
}
|
|
91146
|
+
var HEX_COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
|
|
91147
|
+
function sanitizeColor(color, fallback = "#6366f1") {
|
|
91148
|
+
if (typeof color !== "string") {
|
|
91149
|
+
return fallback;
|
|
91150
|
+
}
|
|
91151
|
+
return HEX_COLOR_REGEX.test(color) ? color : fallback;
|
|
91152
|
+
}
|
|
91153
|
+
function sanitizeAvatarUrl(url) {
|
|
91154
|
+
if (typeof url !== "string") {
|
|
91155
|
+
return void 0;
|
|
91156
|
+
}
|
|
91157
|
+
try {
|
|
91158
|
+
const parsed = new URL(url);
|
|
91159
|
+
if (parsed.protocol === "https:" || parsed.protocol === "http:" || parsed.protocol === "data:") {
|
|
91160
|
+
return url;
|
|
91161
|
+
}
|
|
91162
|
+
} catch {
|
|
91163
|
+
}
|
|
91164
|
+
return void 0;
|
|
91165
|
+
}
|
|
91166
|
+
function sanitizeSlideIndex(value) {
|
|
91167
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
91168
|
+
return 0;
|
|
91169
|
+
}
|
|
91170
|
+
return Math.max(0, Math.floor(value));
|
|
91171
|
+
}
|
|
91172
|
+
function sanitizePresence(raw, canvasWidth, canvasHeight) {
|
|
91173
|
+
if (typeof raw.clientId !== "number") {
|
|
91174
|
+
return null;
|
|
91175
|
+
}
|
|
91176
|
+
return {
|
|
91177
|
+
clientId: raw.clientId,
|
|
91178
|
+
userName: sanitizeUserName(raw.userName),
|
|
91179
|
+
userAvatar: sanitizeAvatarUrl(raw.userAvatar),
|
|
91180
|
+
userColor: sanitizeColor(raw.userColor),
|
|
91181
|
+
activeSlideIndex: sanitizeSlideIndex(raw.activeSlideIndex),
|
|
91182
|
+
cursorX: clampCursorPosition(raw.cursorX, 0, canvasWidth),
|
|
91183
|
+
cursorY: clampCursorPosition(raw.cursorY, 0, canvasHeight),
|
|
91184
|
+
lastUpdated: typeof raw.lastUpdated === "string" ? raw.lastUpdated : (/* @__PURE__ */ new Date()).toISOString(),
|
|
91185
|
+
selectedElementId: typeof raw.selectedElementId === "string" ? raw.selectedElementId.slice(0, 128) : void 0,
|
|
91186
|
+
role: raw.role === "broadcaster" || raw.role === "viewer" || raw.role === "collaborator" ? raw.role : void 0
|
|
91187
|
+
};
|
|
91188
|
+
}
|
|
91189
|
+
var BROADCAST_THROTTLE_MS = 50;
|
|
91190
|
+
var STALE_PRESENCE_MS = 3e4;
|
|
91191
|
+
function usePresenceTracking({
|
|
91192
|
+
awareness,
|
|
91193
|
+
localClientId,
|
|
91194
|
+
userName,
|
|
91195
|
+
userColor,
|
|
91196
|
+
userAvatar,
|
|
91197
|
+
role,
|
|
91198
|
+
canvasWidth,
|
|
91199
|
+
canvasHeight
|
|
91200
|
+
}) {
|
|
91201
|
+
const [remoteUsers, setRemoteUsers] = React10.useState([]);
|
|
91202
|
+
const lastBroadcastRef = React10.useRef(0);
|
|
91203
|
+
const pendingBroadcastRef = React10.useRef(null);
|
|
91204
|
+
const latestLocalState = React10.useRef({});
|
|
91205
|
+
const broadcastPresence = React10.useCallback(
|
|
91206
|
+
(update2) => {
|
|
91207
|
+
if (!awareness) {
|
|
91208
|
+
return;
|
|
91209
|
+
}
|
|
91210
|
+
Object.assign(latestLocalState.current, update2);
|
|
91211
|
+
const now = Date.now();
|
|
91212
|
+
const elapsed = now - lastBroadcastRef.current;
|
|
91213
|
+
const flush = () => {
|
|
91214
|
+
const state2 = {
|
|
91215
|
+
...latestLocalState.current,
|
|
91216
|
+
userName,
|
|
91217
|
+
userColor,
|
|
91218
|
+
userAvatar,
|
|
91219
|
+
role,
|
|
91220
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
91221
|
+
};
|
|
91222
|
+
awareness.setLocalStateField("presence", state2);
|
|
91223
|
+
lastBroadcastRef.current = Date.now();
|
|
91224
|
+
};
|
|
91225
|
+
if (elapsed >= BROADCAST_THROTTLE_MS) {
|
|
91226
|
+
if (pendingBroadcastRef.current) {
|
|
91227
|
+
clearTimeout(pendingBroadcastRef.current);
|
|
91228
|
+
pendingBroadcastRef.current = null;
|
|
91229
|
+
}
|
|
91230
|
+
flush();
|
|
91231
|
+
} else if (!pendingBroadcastRef.current) {
|
|
91232
|
+
pendingBroadcastRef.current = setTimeout(() => {
|
|
91233
|
+
pendingBroadcastRef.current = null;
|
|
91234
|
+
flush();
|
|
91235
|
+
}, BROADCAST_THROTTLE_MS - elapsed);
|
|
91236
|
+
}
|
|
91237
|
+
},
|
|
91238
|
+
[awareness, userName, userColor, userAvatar, role]
|
|
91239
|
+
);
|
|
91240
|
+
React10.useEffect(() => {
|
|
91241
|
+
if (!awareness) {
|
|
91242
|
+
return;
|
|
91243
|
+
}
|
|
91244
|
+
awareness.setLocalStateField("presence", {
|
|
91245
|
+
userName,
|
|
91246
|
+
userColor,
|
|
91247
|
+
userAvatar,
|
|
91248
|
+
role,
|
|
91249
|
+
activeSlideIndex: 0,
|
|
91250
|
+
cursorX: 0,
|
|
91251
|
+
cursorY: 0,
|
|
91252
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
91253
|
+
});
|
|
91254
|
+
}, [awareness, userName, userColor, userAvatar, role]);
|
|
91255
|
+
React10.useEffect(() => {
|
|
91256
|
+
if (!awareness || localClientId === null) {
|
|
91257
|
+
return;
|
|
91258
|
+
}
|
|
91259
|
+
const handleChange = () => {
|
|
91260
|
+
const now = Date.now();
|
|
91261
|
+
const states = awareness.getStates();
|
|
91262
|
+
const users = [];
|
|
91263
|
+
states.forEach((state2, cid) => {
|
|
91264
|
+
if (cid === localClientId) {
|
|
91265
|
+
return;
|
|
91266
|
+
}
|
|
91267
|
+
const raw = state2?.presence;
|
|
91268
|
+
if (!raw || typeof raw !== "object") {
|
|
91269
|
+
return;
|
|
91270
|
+
}
|
|
91271
|
+
const sanitized = sanitizePresence({ ...raw, clientId: cid }, canvasWidth, canvasHeight);
|
|
91272
|
+
if (!sanitized) {
|
|
91273
|
+
return;
|
|
91274
|
+
}
|
|
91275
|
+
const updatedAt = new Date(sanitized.lastUpdated).getTime();
|
|
91276
|
+
if (Number.isNaN(updatedAt) || now - updatedAt > STALE_PRESENCE_MS) {
|
|
91277
|
+
return;
|
|
91278
|
+
}
|
|
91279
|
+
users.push(sanitized);
|
|
91280
|
+
});
|
|
91281
|
+
setRemoteUsers(users);
|
|
91282
|
+
};
|
|
91283
|
+
awareness.on("change", handleChange);
|
|
91284
|
+
awareness.on("update", handleChange);
|
|
91285
|
+
handleChange();
|
|
91286
|
+
return () => {
|
|
91287
|
+
awareness.off("change", handleChange);
|
|
91288
|
+
awareness.off("update", handleChange);
|
|
91289
|
+
};
|
|
91290
|
+
}, [awareness, localClientId, canvasWidth, canvasHeight]);
|
|
91291
|
+
React10.useEffect(() => {
|
|
91292
|
+
if (!awareness) {
|
|
91293
|
+
return;
|
|
91294
|
+
}
|
|
91295
|
+
const interval = setInterval(() => {
|
|
91296
|
+
awareness.setLocalStateField("presence", {
|
|
91297
|
+
...latestLocalState.current,
|
|
91298
|
+
userName,
|
|
91299
|
+
userColor,
|
|
91300
|
+
userAvatar,
|
|
91301
|
+
role,
|
|
91302
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
91303
|
+
});
|
|
91304
|
+
}, 1e4);
|
|
91305
|
+
return () => clearInterval(interval);
|
|
91306
|
+
}, [awareness, userName, userColor, userAvatar, role]);
|
|
91307
|
+
React10.useEffect(() => {
|
|
91308
|
+
return () => {
|
|
91309
|
+
if (pendingBroadcastRef.current) {
|
|
91310
|
+
clearTimeout(pendingBroadcastRef.current);
|
|
91311
|
+
}
|
|
91312
|
+
};
|
|
91313
|
+
}, []);
|
|
91314
|
+
return { remoteUsers, broadcastPresence };
|
|
91315
|
+
}
|
|
91316
|
+
function useYjsProvider({ config }) {
|
|
91317
|
+
const [status, setStatus] = React10.useState("disconnected");
|
|
91318
|
+
const [awareness, setAwareness] = React10.useState(null);
|
|
91319
|
+
const [doc2, setDoc] = React10.useState(null);
|
|
91320
|
+
const [clientId, setClientId] = React10.useState(null);
|
|
91321
|
+
const cleanupRef = React10.useRef(null);
|
|
91322
|
+
const init = React10.useCallback(async () => {
|
|
91323
|
+
const roomId = validateRoomId(config.roomId);
|
|
91324
|
+
setStatus("connecting");
|
|
91325
|
+
try {
|
|
91326
|
+
const [Y, { WebsocketProvider: WebsocketProvider2 }] = await Promise.all([Promise.resolve().then(() => (init_yjs(), yjs_exports)), Promise.resolve().then(() => (init_y_websocket(), y_websocket_exports))]);
|
|
91327
|
+
const yDoc = new Y.Doc();
|
|
91328
|
+
const provider = new WebsocketProvider2(
|
|
91329
|
+
config.serverUrl,
|
|
91330
|
+
roomId,
|
|
91331
|
+
yDoc,
|
|
91332
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
91333
|
+
{
|
|
91334
|
+
params: config.authToken ? { token: config.authToken } : void 0
|
|
91335
|
+
}
|
|
91336
|
+
);
|
|
91337
|
+
const handleStatus = (event) => {
|
|
91338
|
+
if (event.status === "connected") {
|
|
91339
|
+
setStatus("connected");
|
|
91340
|
+
} else if (event.status === "disconnected") {
|
|
91341
|
+
setStatus("disconnected");
|
|
91342
|
+
}
|
|
91343
|
+
};
|
|
91344
|
+
provider.on("status", handleStatus);
|
|
91345
|
+
if (provider.wsconnected) {
|
|
91346
|
+
setStatus("connected");
|
|
91347
|
+
}
|
|
91348
|
+
setDoc(yDoc);
|
|
91349
|
+
setAwareness(provider.awareness);
|
|
91350
|
+
setClientId(provider.awareness.clientID);
|
|
91351
|
+
cleanupRef.current = () => {
|
|
91352
|
+
provider.off("status", handleStatus);
|
|
91353
|
+
provider.destroy();
|
|
91354
|
+
yDoc.destroy();
|
|
91355
|
+
setDoc(null);
|
|
91356
|
+
setAwareness(null);
|
|
91357
|
+
setClientId(null);
|
|
91358
|
+
setStatus("disconnected");
|
|
91359
|
+
};
|
|
91360
|
+
} catch (err) {
|
|
91361
|
+
console.warn(
|
|
91362
|
+
"[pptx-viewer] Collaboration packages not available:",
|
|
91363
|
+
err instanceof Error ? err.message : err
|
|
91364
|
+
);
|
|
91365
|
+
setStatus("error");
|
|
91366
|
+
}
|
|
91367
|
+
}, [config.roomId, config.serverUrl, config.authToken]);
|
|
91368
|
+
React10.useEffect(() => {
|
|
91369
|
+
init();
|
|
91370
|
+
return () => {
|
|
91371
|
+
cleanupRef.current?.();
|
|
91372
|
+
cleanupRef.current = null;
|
|
91373
|
+
};
|
|
91374
|
+
}, [init]);
|
|
91375
|
+
return { status, awareness, doc: doc2, clientId };
|
|
91376
|
+
}
|
|
91377
|
+
|
|
91378
|
+
// src/viewer/hooks/collaboration/useCollaborativeState.ts
|
|
91379
|
+
function useCollaborativeState({
|
|
91380
|
+
config,
|
|
91381
|
+
canvasWidth,
|
|
91382
|
+
canvasHeight
|
|
91383
|
+
}) {
|
|
91384
|
+
const userColor = sanitizeColor(config.userColor, "#6366f1");
|
|
91385
|
+
const { status, awareness, doc: doc2, clientId } = useYjsProvider({ config });
|
|
91386
|
+
const { remoteUsers, broadcastPresence } = usePresenceTracking({
|
|
91387
|
+
awareness,
|
|
91388
|
+
localClientId: clientId,
|
|
91389
|
+
userName: config.userName,
|
|
91390
|
+
userColor,
|
|
91391
|
+
userAvatar: config.userAvatar,
|
|
91392
|
+
role: config.role,
|
|
91393
|
+
canvasWidth,
|
|
91394
|
+
canvasHeight
|
|
91395
|
+
});
|
|
91396
|
+
const connectedCount = status === "connected" ? remoteUsers.length + 1 : remoteUsers.length;
|
|
91397
|
+
return {
|
|
91398
|
+
status,
|
|
91399
|
+
remoteUsers,
|
|
91400
|
+
broadcastPresence,
|
|
91401
|
+
connectedCount,
|
|
91402
|
+
config,
|
|
91403
|
+
doc: doc2
|
|
91404
|
+
};
|
|
91405
|
+
}
|
|
91406
|
+
var CollaborationContext = React10.createContext(null);
|
|
91407
|
+
function useCollaboration() {
|
|
91408
|
+
return React10.useContext(CollaborationContext);
|
|
91409
|
+
}
|
|
91410
|
+
function CollaborationProvider({
|
|
91411
|
+
config,
|
|
91412
|
+
canvasWidth,
|
|
91413
|
+
canvasHeight,
|
|
91414
|
+
children
|
|
91415
|
+
}) {
|
|
91416
|
+
const value = useCollaborativeState({
|
|
91417
|
+
config,
|
|
91418
|
+
canvasWidth,
|
|
91419
|
+
canvasHeight
|
|
91420
|
+
});
|
|
91421
|
+
return /* @__PURE__ */ jsxRuntime.jsx(CollaborationContext.Provider, { value, children });
|
|
91422
|
+
}
|
|
91423
|
+
function RemoteUserCursors({
|
|
91424
|
+
remoteUsers,
|
|
91425
|
+
activeSlideIndex,
|
|
91426
|
+
canvasWidth,
|
|
91427
|
+
canvasHeight
|
|
91428
|
+
}) {
|
|
91429
|
+
const visibleUsers = remoteUsers.filter((u2) => u2.activeSlideIndex === activeSlideIndex);
|
|
91430
|
+
if (visibleUsers.length === 0) {
|
|
91431
|
+
return null;
|
|
91432
|
+
}
|
|
91433
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
91434
|
+
"svg",
|
|
91435
|
+
{
|
|
91436
|
+
"data-testid": "remote-user-cursors",
|
|
91437
|
+
"data-export-ignore": "true",
|
|
91438
|
+
className: "absolute inset-0 pointer-events-none",
|
|
91439
|
+
style: { zIndex: 9999 },
|
|
91440
|
+
width: canvasWidth,
|
|
91441
|
+
height: canvasHeight,
|
|
91442
|
+
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
91443
|
+
"aria-hidden": "true",
|
|
91444
|
+
children: visibleUsers.map((user) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
91445
|
+
"g",
|
|
91446
|
+
{
|
|
91447
|
+
transform: `translate(${user.cursorX}, ${user.cursorY})`,
|
|
91448
|
+
"data-testid": `remote-cursor-${user.clientId}`,
|
|
91449
|
+
children: [
|
|
91450
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
91451
|
+
"path",
|
|
91452
|
+
{
|
|
91453
|
+
d: "M0 0 L0 16 L4.5 12.5 L8 20 L10.5 19 L7 11.5 L12 11 Z",
|
|
91454
|
+
fill: user.userColor,
|
|
91455
|
+
stroke: "#fff",
|
|
91456
|
+
strokeWidth: 1,
|
|
91457
|
+
opacity: 0.9
|
|
91458
|
+
}
|
|
91459
|
+
),
|
|
91460
|
+
/* @__PURE__ */ jsxRuntime.jsxs("g", { transform: "translate(14, 18)", children: [
|
|
91461
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
91462
|
+
"rect",
|
|
91463
|
+
{
|
|
91464
|
+
rx: 3,
|
|
91465
|
+
ry: 3,
|
|
91466
|
+
x: -2,
|
|
91467
|
+
y: -10,
|
|
91468
|
+
width: Math.min(user.userName.length * 7 + 8, 150),
|
|
91469
|
+
height: 16,
|
|
91470
|
+
fill: user.userColor,
|
|
91471
|
+
opacity: 0.85
|
|
91472
|
+
}
|
|
91473
|
+
),
|
|
91474
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
91475
|
+
"text",
|
|
91476
|
+
{
|
|
91477
|
+
fill: "#fff",
|
|
91478
|
+
fontSize: 10,
|
|
91479
|
+
fontFamily: "system-ui, sans-serif",
|
|
91480
|
+
fontWeight: 500,
|
|
91481
|
+
dominantBaseline: "central",
|
|
91482
|
+
y: -2,
|
|
91483
|
+
x: 2,
|
|
91484
|
+
children: user.userName.length > 20 ? `${user.userName.slice(0, 18)}...` : user.userName
|
|
91485
|
+
}
|
|
91486
|
+
)
|
|
91487
|
+
] })
|
|
91488
|
+
]
|
|
91489
|
+
},
|
|
91490
|
+
user.clientId
|
|
91491
|
+
))
|
|
91492
|
+
}
|
|
91493
|
+
);
|
|
91494
|
+
}
|
|
91495
|
+
function getInitials(name) {
|
|
91496
|
+
const parts = name.trim().split(/\s+/);
|
|
91497
|
+
if (parts.length >= 2) {
|
|
91498
|
+
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
91499
|
+
}
|
|
91500
|
+
return name.slice(0, 2).toUpperCase();
|
|
91501
|
+
}
|
|
91502
|
+
function AvatarCircle({
|
|
91503
|
+
name,
|
|
91504
|
+
color,
|
|
91505
|
+
avatar,
|
|
91506
|
+
isLocal
|
|
91507
|
+
}) {
|
|
91508
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
91509
|
+
const initials = getInitials(name);
|
|
91510
|
+
const title = isLocal ? t2("pptx.collaboration.youLabel", { name }) : name;
|
|
91511
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
91512
|
+
"div",
|
|
91513
|
+
{
|
|
91514
|
+
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",
|
|
91515
|
+
style: {
|
|
91516
|
+
backgroundColor: color,
|
|
91517
|
+
borderColor: isLocal ? "#fff" : color
|
|
91518
|
+
},
|
|
91519
|
+
title,
|
|
91520
|
+
"aria-label": title,
|
|
91521
|
+
children: avatar ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
91522
|
+
"img",
|
|
91523
|
+
{
|
|
91524
|
+
src: avatar,
|
|
91525
|
+
alt: "",
|
|
91526
|
+
className: "w-full h-full rounded-full object-cover",
|
|
91527
|
+
onError: (e2) => {
|
|
91528
|
+
e2.target.style.display = "none";
|
|
91529
|
+
}
|
|
91530
|
+
}
|
|
91531
|
+
) : initials
|
|
91532
|
+
}
|
|
91533
|
+
);
|
|
91534
|
+
}
|
|
91535
|
+
function UserAvatarBar({
|
|
91536
|
+
remoteUsers,
|
|
91537
|
+
localUserName,
|
|
91538
|
+
localUserColor,
|
|
91539
|
+
localUserAvatar,
|
|
91540
|
+
status,
|
|
91541
|
+
maxVisible = 5
|
|
91542
|
+
}) {
|
|
91543
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
91544
|
+
if (status === "disconnected" || status === "error") {
|
|
91545
|
+
return null;
|
|
91546
|
+
}
|
|
91547
|
+
const allUsers = [
|
|
91548
|
+
{ name: localUserName, color: localUserColor, avatar: localUserAvatar, isLocal: true },
|
|
91549
|
+
...remoteUsers.map((u2) => ({
|
|
91550
|
+
name: u2.userName,
|
|
91551
|
+
color: u2.userColor,
|
|
91552
|
+
avatar: u2.userAvatar,
|
|
91553
|
+
isLocal: false
|
|
91554
|
+
}))
|
|
91555
|
+
];
|
|
91556
|
+
const visible = allUsers.slice(0, maxVisible);
|
|
91557
|
+
const overflow = allUsers.length - maxVisible;
|
|
91558
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
91559
|
+
"div",
|
|
91560
|
+
{
|
|
91561
|
+
"data-testid": "user-avatar-bar",
|
|
91562
|
+
className: "flex items-center px-2",
|
|
91563
|
+
"aria-label": t2("pptx.collaboration.usersConnected", { count: allUsers.length }),
|
|
91564
|
+
children: [
|
|
91565
|
+
visible.map((user, i3) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
91566
|
+
AvatarCircle,
|
|
91567
|
+
{
|
|
91568
|
+
name: user.name,
|
|
91569
|
+
color: user.color,
|
|
91570
|
+
avatar: user.avatar,
|
|
91571
|
+
isLocal: user.isLocal
|
|
91572
|
+
},
|
|
91573
|
+
user.isLocal ? "local" : `remote-${i3}`
|
|
91574
|
+
)),
|
|
91575
|
+
overflow > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
91576
|
+
"div",
|
|
91577
|
+
{
|
|
91578
|
+
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",
|
|
91579
|
+
title: t2("pptx.collaboration.moreUsers", { count: overflow }),
|
|
91580
|
+
children: [
|
|
91581
|
+
"+",
|
|
91582
|
+
overflow
|
|
91583
|
+
]
|
|
91584
|
+
}
|
|
91585
|
+
)
|
|
91586
|
+
]
|
|
91587
|
+
}
|
|
91588
|
+
);
|
|
91589
|
+
}
|
|
91590
|
+
var STATUS_STYLES = {
|
|
91591
|
+
connected: {
|
|
91592
|
+
dot: "bg-green-400",
|
|
91593
|
+
text: "text-green-400",
|
|
91594
|
+
label: "Connected"
|
|
91595
|
+
},
|
|
91596
|
+
connecting: {
|
|
91597
|
+
dot: "bg-yellow-400 animate-pulse",
|
|
91598
|
+
text: "text-yellow-400",
|
|
91599
|
+
label: "Connecting..."
|
|
91600
|
+
},
|
|
91601
|
+
disconnected: {
|
|
91602
|
+
dot: "bg-gray-500",
|
|
91603
|
+
text: "text-gray-500",
|
|
91604
|
+
label: "Disconnected"
|
|
91605
|
+
},
|
|
91606
|
+
error: {
|
|
91607
|
+
dot: "bg-red-400",
|
|
91608
|
+
text: "text-red-400",
|
|
91609
|
+
label: "Connection error"
|
|
91610
|
+
}
|
|
91611
|
+
};
|
|
91612
|
+
function CollaborationStatusIndicator({
|
|
91613
|
+
status,
|
|
91614
|
+
connectedCount
|
|
91615
|
+
}) {
|
|
91616
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
91617
|
+
const style = STATUS_STYLES[status];
|
|
91618
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
91619
|
+
"div",
|
|
91620
|
+
{
|
|
91621
|
+
"data-testid": "collaboration-status",
|
|
91622
|
+
className: "flex items-center gap-1.5",
|
|
91623
|
+
"aria-label": t2("pptx.collaboration.statusAriaLabel", {
|
|
91624
|
+
status: t2(`pptx.collaboration.status.${status}`),
|
|
91625
|
+
count: connectedCount
|
|
91626
|
+
}),
|
|
91627
|
+
children: [
|
|
91628
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-block w-2 h-2 rounded-full ${style.dot}`, "aria-hidden": "true" }),
|
|
91629
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-[10px] ${style.text}`, children: status === "connected" ? t2("pptx.collaboration.userCount", { count: connectedCount }) : t2(`pptx.collaboration.status.${status}`) })
|
|
91630
|
+
]
|
|
91631
|
+
}
|
|
91632
|
+
);
|
|
91633
|
+
}
|
|
91634
|
+
function CollaborationCursorOverlay({
|
|
91635
|
+
activeSlideIndex,
|
|
91636
|
+
canvasWidth,
|
|
91637
|
+
canvasHeight,
|
|
91638
|
+
selectedElementId
|
|
91639
|
+
}) {
|
|
91640
|
+
const collab = useCollaboration();
|
|
91641
|
+
const containerRef = React10.useRef(null);
|
|
91642
|
+
const prevSelectionRef = React10.useRef(selectedElementId);
|
|
91643
|
+
React10.useEffect(() => {
|
|
91644
|
+
if (!collab || selectedElementId === prevSelectionRef.current) {
|
|
91645
|
+
return;
|
|
91646
|
+
}
|
|
91647
|
+
prevSelectionRef.current = selectedElementId;
|
|
91648
|
+
collab.broadcastPresence({
|
|
91649
|
+
selectedElementId: selectedElementId ?? void 0,
|
|
91650
|
+
activeSlideIndex
|
|
91651
|
+
});
|
|
91652
|
+
}, [collab, selectedElementId, activeSlideIndex]);
|
|
91653
|
+
React10.useEffect(() => {
|
|
91654
|
+
if (!collab) {
|
|
91655
|
+
return;
|
|
91656
|
+
}
|
|
91657
|
+
const parent = containerRef.current?.parentElement;
|
|
91658
|
+
if (!parent) {
|
|
91659
|
+
return;
|
|
91660
|
+
}
|
|
91661
|
+
const handler = (e2) => {
|
|
91662
|
+
const rect = parent.getBoundingClientRect();
|
|
91663
|
+
const x2 = (e2.clientX - rect.left) / rect.width * canvasWidth;
|
|
91664
|
+
const y = (e2.clientY - rect.top) / rect.height * canvasHeight;
|
|
91665
|
+
collab.broadcastPresence({
|
|
91666
|
+
cursorX: x2,
|
|
91667
|
+
cursorY: y,
|
|
91668
|
+
activeSlideIndex
|
|
91669
|
+
});
|
|
91670
|
+
};
|
|
91671
|
+
parent.addEventListener("pointermove", handler);
|
|
91672
|
+
return () => parent.removeEventListener("pointermove", handler);
|
|
91673
|
+
}, [collab, canvasWidth, canvasHeight, activeSlideIndex]);
|
|
91674
|
+
if (!collab) {
|
|
91675
|
+
return null;
|
|
91676
|
+
}
|
|
91677
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
91678
|
+
"div",
|
|
91679
|
+
{
|
|
91680
|
+
ref: containerRef,
|
|
91681
|
+
"data-testid": "collab-pointer-tracker",
|
|
91682
|
+
"data-export-ignore": "true",
|
|
91683
|
+
style: { display: "contents" },
|
|
91684
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
91685
|
+
RemoteUserCursors,
|
|
91686
|
+
{
|
|
91687
|
+
remoteUsers: collab.remoteUsers,
|
|
91688
|
+
activeSlideIndex,
|
|
91689
|
+
canvasWidth,
|
|
91690
|
+
canvasHeight
|
|
91691
|
+
}
|
|
91692
|
+
)
|
|
91693
|
+
}
|
|
91694
|
+
);
|
|
91695
|
+
}
|
|
91696
|
+
function RemoteSelectionOverlay({
|
|
91697
|
+
elements,
|
|
91698
|
+
activeSlideIndex
|
|
91699
|
+
}) {
|
|
91700
|
+
const collab = useCollaboration();
|
|
91701
|
+
if (!collab) {
|
|
91702
|
+
return null;
|
|
91703
|
+
}
|
|
91704
|
+
const elementMap = /* @__PURE__ */ new Map();
|
|
91705
|
+
for (const el of elements) {
|
|
91706
|
+
elementMap.set(el.id, el);
|
|
91707
|
+
}
|
|
91708
|
+
const selections = [];
|
|
91709
|
+
for (const user of collab.remoteUsers) {
|
|
91710
|
+
if (user.activeSlideIndex === activeSlideIndex && user.selectedElementId) {
|
|
91711
|
+
const el = elementMap.get(user.selectedElementId);
|
|
91712
|
+
if (el) {
|
|
91713
|
+
selections.push({
|
|
91714
|
+
userName: user.userName,
|
|
91715
|
+
userColor: user.userColor,
|
|
91716
|
+
element: el
|
|
91717
|
+
});
|
|
91718
|
+
}
|
|
91719
|
+
}
|
|
91720
|
+
}
|
|
91721
|
+
if (selections.length === 0) {
|
|
91722
|
+
return null;
|
|
91723
|
+
}
|
|
91724
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: selections.map((sel) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
91725
|
+
"div",
|
|
91726
|
+
{
|
|
91727
|
+
"data-testid": `remote-selection-${sel.element.id}`,
|
|
91728
|
+
"data-export-ignore": "true",
|
|
91729
|
+
className: "absolute pointer-events-none",
|
|
91730
|
+
style: {
|
|
91731
|
+
left: sel.element.x,
|
|
91732
|
+
top: sel.element.y,
|
|
91733
|
+
width: sel.element.width,
|
|
91734
|
+
height: sel.element.height,
|
|
91735
|
+
zIndex: 9997,
|
|
91736
|
+
border: `2px solid ${sel.userColor}`,
|
|
91737
|
+
borderRadius: 2
|
|
91738
|
+
},
|
|
91739
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
91740
|
+
"span",
|
|
91741
|
+
{
|
|
91742
|
+
className: "absolute -top-5 left-0 px-1 py-0.5 text-[9px] font-medium text-white rounded-sm whitespace-nowrap leading-none",
|
|
91743
|
+
style: { backgroundColor: sel.userColor },
|
|
91744
|
+
children: sel.userName
|
|
91745
|
+
}
|
|
91746
|
+
)
|
|
91747
|
+
},
|
|
91748
|
+
`remote-sel-${sel.element.id}`
|
|
91749
|
+
)) });
|
|
91750
|
+
}
|
|
91120
91751
|
function SectionContextMenu({
|
|
91121
91752
|
state: state2,
|
|
91122
91753
|
sectionGroups,
|
|
@@ -91398,6 +92029,7 @@ function SlideItemInner({
|
|
|
91398
92029
|
canvasSize,
|
|
91399
92030
|
canEdit,
|
|
91400
92031
|
rehearsalTimings,
|
|
92032
|
+
presenceUsers,
|
|
91401
92033
|
onSelectSlide,
|
|
91402
92034
|
onSlideContextMenu,
|
|
91403
92035
|
onAddSection,
|
|
@@ -91440,16 +92072,27 @@ function SlideItemInner({
|
|
|
91440
92072
|
onDragOver,
|
|
91441
92073
|
onDrop: (e2) => onDrop(e2, slideIndex),
|
|
91442
92074
|
children: [
|
|
91443
|
-
/* @__PURE__ */ jsxRuntime.
|
|
91444
|
-
|
|
91445
|
-
|
|
91446
|
-
|
|
91447
|
-
|
|
91448
|
-
|
|
91449
|
-
|
|
91450
|
-
|
|
91451
|
-
|
|
91452
|
-
|
|
92075
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5 w-5 shrink-0", children: [
|
|
92076
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
92077
|
+
"span",
|
|
92078
|
+
{
|
|
92079
|
+
className: cn(
|
|
92080
|
+
"text-[10px] tabular-nums text-right select-none w-full",
|
|
92081
|
+
isActive ? "text-primary font-medium" : "text-muted-foreground"
|
|
92082
|
+
),
|
|
92083
|
+
children: slideIndex + 1
|
|
92084
|
+
}
|
|
92085
|
+
),
|
|
92086
|
+
presenceUsers && presenceUsers.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap justify-center gap-px", children: presenceUsers.slice(0, 4).map((u2, i3) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
92087
|
+
"span",
|
|
92088
|
+
{
|
|
92089
|
+
className: "w-[6px] h-[6px] rounded-full",
|
|
92090
|
+
style: { backgroundColor: u2.userColor },
|
|
92091
|
+
title: u2.userName
|
|
92092
|
+
},
|
|
92093
|
+
i3
|
|
92094
|
+
)) })
|
|
92095
|
+
] }),
|
|
91453
92096
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
91454
92097
|
"div",
|
|
91455
92098
|
{
|
|
@@ -91599,8 +92242,26 @@ function SlidesPaneSidebar({
|
|
|
91599
92242
|
panelWidth
|
|
91600
92243
|
}) {
|
|
91601
92244
|
const { t: t2 } = reactI18next.useTranslation();
|
|
92245
|
+
const collab = useCollaboration();
|
|
91602
92246
|
const slideRefs = React10.useRef(/* @__PURE__ */ new Map());
|
|
91603
92247
|
const renameInputRef = React10.useRef(null);
|
|
92248
|
+
const slidePresenceMap = React10.useMemo(() => {
|
|
92249
|
+
if (!collab || collab.remoteUsers.length === 0) {
|
|
92250
|
+
return void 0;
|
|
92251
|
+
}
|
|
92252
|
+
const map3 = /* @__PURE__ */ new Map();
|
|
92253
|
+
for (const user of collab.remoteUsers) {
|
|
92254
|
+
const idx = user.activeSlideIndex;
|
|
92255
|
+
const existing = map3.get(idx);
|
|
92256
|
+
const entry = { userName: user.userName, userColor: user.userColor };
|
|
92257
|
+
if (existing) {
|
|
92258
|
+
existing.push(entry);
|
|
92259
|
+
} else {
|
|
92260
|
+
map3.set(idx, [entry]);
|
|
92261
|
+
}
|
|
92262
|
+
}
|
|
92263
|
+
return map3;
|
|
92264
|
+
}, [collab]);
|
|
91604
92265
|
const estimatedItemHeight = React10.useMemo(
|
|
91605
92266
|
() => estimateSlideItemHeight(canvasSize.width, canvasSize.height),
|
|
91606
92267
|
[canvasSize.width, canvasSize.height]
|
|
@@ -91722,6 +92383,7 @@ function SlidesPaneSidebar({
|
|
|
91722
92383
|
canvasSize,
|
|
91723
92384
|
canEdit,
|
|
91724
92385
|
rehearsalTimings,
|
|
92386
|
+
presenceUsers: slidePresenceMap?.get(item.slideIndex),
|
|
91725
92387
|
onSelectSlide,
|
|
91726
92388
|
onSlideContextMenu,
|
|
91727
92389
|
onAddSection,
|
|
@@ -91775,6 +92437,7 @@ function SlidesPaneSidebar({
|
|
|
91775
92437
|
canvasSize,
|
|
91776
92438
|
canEdit,
|
|
91777
92439
|
rehearsalTimings,
|
|
92440
|
+
presenceUsers: slidePresenceMap?.get(idx),
|
|
91778
92441
|
onSelectSlide,
|
|
91779
92442
|
onSlideContextMenu,
|
|
91780
92443
|
onAddSection,
|
|
@@ -96541,16 +97204,31 @@ var ALIGN_BTNS = [
|
|
|
96541
97204
|
{ k: "bottom", el: /* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronDown, { className: ic2 }) }
|
|
96542
97205
|
];
|
|
96543
97206
|
var DRAW_TOOLS = [
|
|
96544
|
-
{
|
|
96545
|
-
|
|
97207
|
+
{
|
|
97208
|
+
id: "select",
|
|
97209
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lu.LuMoveRight, { className: ic2 }),
|
|
97210
|
+
t: "Select",
|
|
97211
|
+
ac: "bg-primary text-primary-foreground"
|
|
97212
|
+
},
|
|
97213
|
+
{
|
|
97214
|
+
id: "pen",
|
|
97215
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPencil, { className: ic2 }),
|
|
97216
|
+
t: "Pen",
|
|
97217
|
+
ac: "bg-primary text-primary-foreground"
|
|
97218
|
+
},
|
|
96546
97219
|
{
|
|
96547
97220
|
id: "highlighter",
|
|
96548
97221
|
icon: /* @__PURE__ */ jsxRuntime.jsx(lu.LuType, { className: ic2 }),
|
|
96549
97222
|
t: "Highlighter",
|
|
96550
97223
|
ac: "bg-yellow-600 text-white"
|
|
96551
97224
|
},
|
|
96552
|
-
{ id: "eraser", icon: /* @__PURE__ */ jsxRuntime.jsx(lu.LuMinus, { className: ic2 }), t: "Eraser" },
|
|
96553
|
-
{
|
|
97225
|
+
{ id: "eraser", icon: /* @__PURE__ */ jsxRuntime.jsx(lu.LuMinus, { className: ic2 }), t: "Eraser", ac: "bg-red-600 text-white" },
|
|
97226
|
+
{
|
|
97227
|
+
id: "freeform",
|
|
97228
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lu.LuSpline, { className: ic2 }),
|
|
97229
|
+
t: "Freeform",
|
|
97230
|
+
ac: "bg-primary text-primary-foreground"
|
|
97231
|
+
}
|
|
96554
97232
|
];
|
|
96555
97233
|
var OV = [
|
|
96556
97234
|
{
|
|
@@ -96756,7 +97434,7 @@ function AnimationsSection(p3) {
|
|
|
96756
97434
|
"button",
|
|
96757
97435
|
{
|
|
96758
97436
|
type: "button",
|
|
96759
|
-
onClick: p3.onToggleInspector,
|
|
97437
|
+
onClick: p3.onOpenAnimationPanel ?? p3.onToggleInspector,
|
|
96760
97438
|
className: cn(
|
|
96761
97439
|
pill,
|
|
96762
97440
|
p3.isInspectorPaneOpen ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
|
|
@@ -97855,413 +98533,106 @@ function SlideShowSection(p3) {
|
|
|
97855
98533
|
/* @__PURE__ */ jsxRuntime.jsx(lu.LuSettings, { className: ic2 }),
|
|
97856
98534
|
"Set Up Slide Show"
|
|
97857
98535
|
] }),
|
|
97858
|
-
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onOpenBroadcastDialog, className: pill, title: "Broadcast slide show", children: [
|
|
97859
|
-
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCast, { className: ic2 }),
|
|
97860
|
-
"Broadcast"
|
|
97861
|
-
] }),
|
|
97862
|
-
sep,
|
|
97863
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
97864
|
-
"button",
|
|
97865
|
-
{
|
|
97866
|
-
onClick: p3.onToggleSubtitles,
|
|
97867
|
-
className: cn(
|
|
97868
|
-
pill,
|
|
97869
|
-
p3.showSubtitles ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
|
|
97870
|
-
),
|
|
97871
|
-
title: "Toggle subtitles",
|
|
97872
|
-
children: [
|
|
97873
|
-
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCaptions, { className: ic2 }),
|
|
97874
|
-
"Subtitles"
|
|
97875
|
-
]
|
|
97876
|
-
}
|
|
97877
|
-
)
|
|
97878
|
-
] });
|
|
97879
|
-
}
|
|
97880
|
-
var FONT_COLOR_PRESETS = [
|
|
97881
|
-
"#000000",
|
|
97882
|
-
"#ffffff",
|
|
97883
|
-
"#ff0000",
|
|
97884
|
-
"#00aa00",
|
|
97885
|
-
"#0000ff",
|
|
97886
|
-
"#ff8800",
|
|
97887
|
-
"#8800cc",
|
|
97888
|
-
"#00cccc",
|
|
97889
|
-
"#ff69b4",
|
|
97890
|
-
"#808080"
|
|
97891
|
-
];
|
|
97892
|
-
var HIGHLIGHT_COLOR_PRESETS = [
|
|
97893
|
-
"#ffff00",
|
|
97894
|
-
"#00ff00",
|
|
97895
|
-
"#00ffff",
|
|
97896
|
-
"#ff00ff",
|
|
97897
|
-
"#0000ff",
|
|
97898
|
-
"#ff0000",
|
|
97899
|
-
"#000080",
|
|
97900
|
-
"#008080",
|
|
97901
|
-
"#008000",
|
|
97902
|
-
"#800080"
|
|
97903
|
-
];
|
|
97904
|
-
function TextSection(p3) {
|
|
97905
|
-
const hasSel = Boolean(p3.selectedElement);
|
|
97906
|
-
const canMut = hasSel && p3.canEdit;
|
|
97907
|
-
const isTextEl = hasSel && p3.selectedElement !== null && pptxViewerCore.hasTextProperties(p3.selectedElement);
|
|
97908
|
-
const isTable = hasSel && p3.selectedElement?.type === "table";
|
|
97909
|
-
const canFormat = isTextEl || isTable;
|
|
97910
|
-
const currentColor = isTextEl && p3.selectedElement && pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textSegments?.[0]?.style?.color ?? p3.selectedElement.textStyle?.color ?? "#000000" : "#000000";
|
|
97911
|
-
const currentHighlight = isTextEl && p3.selectedElement && pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textSegments?.[0]?.style?.highlightColor ?? p3.selectedElement.textStyle?.highlightColor ?? "#ffff00" : "#ffff00";
|
|
97912
|
-
const colorInputRef = React10.useRef(null);
|
|
97913
|
-
const highlightInputRef = React10.useRef(null);
|
|
97914
|
-
const handleColorChange = React10.useCallback(
|
|
97915
|
-
(color) => {
|
|
97916
|
-
if (!canFormat) {
|
|
97917
|
-
return;
|
|
97918
|
-
}
|
|
97919
|
-
p3.onUpdateTextStyle({ color });
|
|
97920
|
-
},
|
|
97921
|
-
[canFormat, p3]
|
|
97922
|
-
);
|
|
97923
|
-
const handleHighlightChange = React10.useCallback(
|
|
97924
|
-
(highlightColor) => {
|
|
97925
|
-
if (!canFormat) {
|
|
97926
|
-
return;
|
|
97927
|
-
}
|
|
97928
|
-
p3.onUpdateTextStyle({ highlightColor });
|
|
97929
|
-
},
|
|
97930
|
-
[canFormat, p3]
|
|
97931
|
-
);
|
|
97932
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
97933
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
97934
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
97935
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: grp, children: FMT.map((b2, i3, a2) => {
|
|
97936
|
-
const handleClick = () => {
|
|
97937
|
-
if (!canFormat || !p3.selectedElement) {
|
|
97938
|
-
return;
|
|
97939
|
-
}
|
|
97940
|
-
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
97941
|
-
switch (b2.t) {
|
|
97942
|
-
case "Bold":
|
|
97943
|
-
p3.onUpdateTextStyle({ bold: !ts?.bold });
|
|
97944
|
-
break;
|
|
97945
|
-
case "Italic":
|
|
97946
|
-
p3.onUpdateTextStyle({ italic: !ts?.italic });
|
|
97947
|
-
break;
|
|
97948
|
-
case "Underline":
|
|
97949
|
-
p3.onUpdateTextStyle({
|
|
97950
|
-
underline: !ts?.underline
|
|
97951
|
-
});
|
|
97952
|
-
break;
|
|
97953
|
-
case "Strikethrough":
|
|
97954
|
-
p3.onUpdateTextStyle({
|
|
97955
|
-
strikethrough: !ts?.strikethrough
|
|
97956
|
-
});
|
|
97957
|
-
break;
|
|
97958
|
-
}
|
|
97959
|
-
};
|
|
97960
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
97961
|
-
"button",
|
|
97962
|
-
{
|
|
97963
|
-
type: "button",
|
|
97964
|
-
disabled: !canMut,
|
|
97965
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
97966
|
-
onClick: handleClick,
|
|
97967
|
-
className: i3 < a2.length - 1 ? gB : gL,
|
|
97968
|
-
title: b2.t,
|
|
97969
|
-
children: b2.i
|
|
97970
|
-
},
|
|
97971
|
-
b2.t
|
|
97972
|
-
);
|
|
97973
|
-
}) }),
|
|
97974
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: grp, children: [
|
|
97975
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97976
|
-
"button",
|
|
97977
|
-
{
|
|
97978
|
-
type: "button",
|
|
97979
|
-
disabled: !canMut,
|
|
97980
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
97981
|
-
onClick: () => {
|
|
97982
|
-
if (!canFormat || !p3.selectedElement) {
|
|
97983
|
-
return;
|
|
97984
|
-
}
|
|
97985
|
-
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
97986
|
-
const current = ts?.fontSize ?? 18;
|
|
97987
|
-
p3.onUpdateTextStyle({ fontSize: current + 2 });
|
|
97988
|
-
},
|
|
97989
|
-
className: gB,
|
|
97990
|
-
title: "Increase Font Size",
|
|
97991
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAArrowUp, { className: ic2 })
|
|
97992
|
-
}
|
|
97993
|
-
),
|
|
97994
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97995
|
-
"button",
|
|
97996
|
-
{
|
|
97997
|
-
type: "button",
|
|
97998
|
-
disabled: !canMut,
|
|
97999
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98000
|
-
onClick: () => {
|
|
98001
|
-
if (!canFormat || !p3.selectedElement) {
|
|
98002
|
-
return;
|
|
98003
|
-
}
|
|
98004
|
-
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98005
|
-
const current = ts?.fontSize ?? 18;
|
|
98006
|
-
p3.onUpdateTextStyle({ fontSize: Math.max(1, current - 2) });
|
|
98007
|
-
},
|
|
98008
|
-
className: gB,
|
|
98009
|
-
title: "Decrease Font Size",
|
|
98010
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAArrowDown, { className: ic2 })
|
|
98011
|
-
}
|
|
98012
|
-
),
|
|
98013
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98014
|
-
"button",
|
|
98015
|
-
{
|
|
98016
|
-
type: "button",
|
|
98017
|
-
disabled: !canMut,
|
|
98018
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98019
|
-
onClick: () => {
|
|
98020
|
-
if (!canFormat) {
|
|
98021
|
-
return;
|
|
98022
|
-
}
|
|
98023
|
-
p3.onUpdateTextStyle({
|
|
98024
|
-
bold: false,
|
|
98025
|
-
italic: false,
|
|
98026
|
-
underline: false,
|
|
98027
|
-
strikethrough: false,
|
|
98028
|
-
highlightColor: void 0
|
|
98029
|
-
});
|
|
98030
|
-
},
|
|
98031
|
-
className: gL,
|
|
98032
|
-
title: "Clear Formatting",
|
|
98033
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuRemoveFormatting, { className: ic2 })
|
|
98034
|
-
}
|
|
98035
|
-
)
|
|
98036
|
-
] }),
|
|
98037
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group", children: [
|
|
98038
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
98039
|
-
"button",
|
|
98040
|
-
{
|
|
98041
|
-
type: "button",
|
|
98042
|
-
disabled: !canMut,
|
|
98043
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98044
|
-
className: pill,
|
|
98045
|
-
title: "Font Color",
|
|
98046
|
-
children: [
|
|
98047
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98048
|
-
"svg",
|
|
98049
|
-
{
|
|
98050
|
-
className: ic2,
|
|
98051
|
-
viewBox: "0 0 24 24",
|
|
98052
|
-
fill: "none",
|
|
98053
|
-
stroke: "currentColor",
|
|
98054
|
-
strokeWidth: "2",
|
|
98055
|
-
strokeLinecap: "round",
|
|
98056
|
-
strokeLinejoin: "round",
|
|
98057
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 20h12M9.5 4h5L18 16H6L9.5 4z" })
|
|
98058
|
-
}
|
|
98059
|
-
),
|
|
98060
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98061
|
-
"div",
|
|
98062
|
-
{
|
|
98063
|
-
className: "w-4 h-1 rounded-sm -mt-0.5",
|
|
98064
|
-
style: { backgroundColor: currentColor }
|
|
98065
|
-
}
|
|
98066
|
-
)
|
|
98067
|
-
]
|
|
98068
|
-
}
|
|
98069
|
-
),
|
|
98070
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-full z-50 hidden group-hover:block pt-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl p-2 w-36", children: [
|
|
98071
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5 gap-1.5 mb-2", children: FONT_COLOR_PRESETS.map((c2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
98072
|
-
"button",
|
|
98073
|
-
{
|
|
98074
|
-
type: "button",
|
|
98075
|
-
className: `w-5 h-5 rounded-full border transition-transform hover:scale-125 ${currentColor?.toLowerCase() === c2 ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
98076
|
-
style: { backgroundColor: c2 },
|
|
98077
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98078
|
-
onClick: () => handleColorChange(c2)
|
|
98079
|
-
},
|
|
98080
|
-
c2
|
|
98081
|
-
)) }),
|
|
98082
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98083
|
-
"button",
|
|
98084
|
-
{
|
|
98085
|
-
type: "button",
|
|
98086
|
-
className: "w-full text-[10px] text-muted-foreground hover:text-foreground py-1 transition-colors",
|
|
98087
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98088
|
-
onClick: () => colorInputRef.current?.click(),
|
|
98089
|
-
children: "Custom colour..."
|
|
98090
|
-
}
|
|
98091
|
-
),
|
|
98092
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98093
|
-
"input",
|
|
98094
|
-
{
|
|
98095
|
-
ref: colorInputRef,
|
|
98096
|
-
type: "color",
|
|
98097
|
-
className: "sr-only",
|
|
98098
|
-
value: currentColor,
|
|
98099
|
-
onChange: (e2) => handleColorChange(e2.target.value)
|
|
98100
|
-
}
|
|
98101
|
-
)
|
|
98102
|
-
] }) })
|
|
98103
|
-
] }),
|
|
98104
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group", children: [
|
|
98105
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
98106
|
-
"button",
|
|
98107
|
-
{
|
|
98108
|
-
type: "button",
|
|
98109
|
-
disabled: !canMut,
|
|
98110
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98111
|
-
className: pill,
|
|
98112
|
-
title: "Text Highlight Color",
|
|
98113
|
-
children: [
|
|
98114
|
-
/* @__PURE__ */ jsxRuntime.jsx(lu.LuHighlighter, { className: ic2 }),
|
|
98115
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98116
|
-
"div",
|
|
98117
|
-
{
|
|
98118
|
-
className: "w-4 h-1 rounded-sm -mt-0.5",
|
|
98119
|
-
style: { backgroundColor: currentHighlight }
|
|
98120
|
-
}
|
|
98121
|
-
)
|
|
98122
|
-
]
|
|
98123
|
-
}
|
|
98124
|
-
),
|
|
98125
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-full z-50 hidden group-hover:block pt-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl p-2 w-36", children: [
|
|
98126
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5 gap-1.5 mb-2", children: HIGHLIGHT_COLOR_PRESETS.map((c2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
98127
|
-
"button",
|
|
98128
|
-
{
|
|
98129
|
-
type: "button",
|
|
98130
|
-
className: `w-5 h-5 rounded-full border transition-transform hover:scale-125 ${currentHighlight?.toLowerCase() === c2 ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
98131
|
-
style: { backgroundColor: c2 },
|
|
98132
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98133
|
-
onClick: () => handleHighlightChange(c2)
|
|
98134
|
-
},
|
|
98135
|
-
c2
|
|
98136
|
-
)) }),
|
|
98137
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98138
|
-
"button",
|
|
98139
|
-
{
|
|
98140
|
-
type: "button",
|
|
98141
|
-
className: "w-full text-[10px] text-muted-foreground hover:text-foreground py-1 transition-colors",
|
|
98142
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98143
|
-
onClick: () => highlightInputRef.current?.click(),
|
|
98144
|
-
children: "Custom colour..."
|
|
98145
|
-
}
|
|
98146
|
-
),
|
|
98147
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98148
|
-
"input",
|
|
98149
|
-
{
|
|
98150
|
-
ref: highlightInputRef,
|
|
98151
|
-
type: "color",
|
|
98152
|
-
className: "sr-only",
|
|
98153
|
-
value: currentHighlight,
|
|
98154
|
-
onChange: (e2) => handleHighlightChange(e2.target.value)
|
|
98155
|
-
}
|
|
98156
|
-
)
|
|
98157
|
-
] }) })
|
|
98158
|
-
] })
|
|
98159
|
-
] }),
|
|
98160
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Font" })
|
|
98161
|
-
] }),
|
|
98536
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onOpenBroadcastDialog, className: pill, title: "Broadcast slide show", children: [
|
|
98537
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCast, { className: ic2 }),
|
|
98538
|
+
"Broadcast"
|
|
98539
|
+
] }),
|
|
98162
98540
|
sep,
|
|
98541
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
98542
|
+
"button",
|
|
98543
|
+
{
|
|
98544
|
+
onClick: p3.onToggleSubtitles,
|
|
98545
|
+
className: cn(
|
|
98546
|
+
pill,
|
|
98547
|
+
p3.showSubtitles ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
|
|
98548
|
+
),
|
|
98549
|
+
title: "Toggle subtitles",
|
|
98550
|
+
children: [
|
|
98551
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCaptions, { className: ic2 }),
|
|
98552
|
+
"Subtitles"
|
|
98553
|
+
]
|
|
98554
|
+
}
|
|
98555
|
+
)
|
|
98556
|
+
] });
|
|
98557
|
+
}
|
|
98558
|
+
var FONT_COLOR_PRESETS = [
|
|
98559
|
+
"#000000",
|
|
98560
|
+
"#ffffff",
|
|
98561
|
+
"#ff0000",
|
|
98562
|
+
"#00aa00",
|
|
98563
|
+
"#0000ff",
|
|
98564
|
+
"#ff8800",
|
|
98565
|
+
"#8800cc",
|
|
98566
|
+
"#00cccc",
|
|
98567
|
+
"#ff69b4",
|
|
98568
|
+
"#808080"
|
|
98569
|
+
];
|
|
98570
|
+
var HIGHLIGHT_COLOR_PRESETS = [
|
|
98571
|
+
"#ffff00",
|
|
98572
|
+
"#00ff00",
|
|
98573
|
+
"#00ffff",
|
|
98574
|
+
"#ff00ff",
|
|
98575
|
+
"#0000ff",
|
|
98576
|
+
"#ff0000",
|
|
98577
|
+
"#000080",
|
|
98578
|
+
"#008080",
|
|
98579
|
+
"#008000",
|
|
98580
|
+
"#800080"
|
|
98581
|
+
];
|
|
98582
|
+
function TextSection(p3) {
|
|
98583
|
+
const hasSel = Boolean(p3.selectedElement);
|
|
98584
|
+
const canMut = hasSel && p3.canEdit;
|
|
98585
|
+
const isTextEl = hasSel && p3.selectedElement !== null && pptxViewerCore.hasTextProperties(p3.selectedElement);
|
|
98586
|
+
const isTable = hasSel && p3.selectedElement?.type === "table";
|
|
98587
|
+
const canFormat = isTextEl || isTable;
|
|
98588
|
+
const currentColor = isTextEl && p3.selectedElement && pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textSegments?.[0]?.style?.color ?? p3.selectedElement.textStyle?.color ?? "#000000" : "#000000";
|
|
98589
|
+
const currentHighlight = isTextEl && p3.selectedElement && pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textSegments?.[0]?.style?.highlightColor ?? p3.selectedElement.textStyle?.highlightColor ?? "#ffff00" : "#ffff00";
|
|
98590
|
+
const colorInputRef = React10.useRef(null);
|
|
98591
|
+
const highlightInputRef = React10.useRef(null);
|
|
98592
|
+
const handleColorChange = React10.useCallback(
|
|
98593
|
+
(color) => {
|
|
98594
|
+
if (!canFormat) {
|
|
98595
|
+
return;
|
|
98596
|
+
}
|
|
98597
|
+
p3.onUpdateTextStyle({ color });
|
|
98598
|
+
},
|
|
98599
|
+
[canFormat, p3]
|
|
98600
|
+
);
|
|
98601
|
+
const handleHighlightChange = React10.useCallback(
|
|
98602
|
+
(highlightColor) => {
|
|
98603
|
+
if (!canFormat) {
|
|
98604
|
+
return;
|
|
98605
|
+
}
|
|
98606
|
+
p3.onUpdateTextStyle({ highlightColor });
|
|
98607
|
+
},
|
|
98608
|
+
[canFormat, p3]
|
|
98609
|
+
);
|
|
98610
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
98163
98611
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
98164
98612
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
98165
|
-
/* @__PURE__ */ jsxRuntime.
|
|
98166
|
-
|
|
98167
|
-
|
|
98168
|
-
|
|
98169
|
-
type: "button",
|
|
98170
|
-
disabled: !canMut,
|
|
98171
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98172
|
-
onClick: () => {
|
|
98173
|
-
if (!canFormat || !p3.selectedElement) {
|
|
98174
|
-
return;
|
|
98175
|
-
}
|
|
98176
|
-
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98177
|
-
p3.onUpdateTextStyle({
|
|
98178
|
-
listType: ts?.listType === "bullet" ? "none" : "bullet"
|
|
98179
|
-
});
|
|
98180
|
-
},
|
|
98181
|
-
className: gB,
|
|
98182
|
-
title: "Bullet List",
|
|
98183
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuList, { className: ic2 })
|
|
98184
|
-
}
|
|
98185
|
-
),
|
|
98186
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98187
|
-
"button",
|
|
98188
|
-
{
|
|
98189
|
-
type: "button",
|
|
98190
|
-
disabled: !canMut,
|
|
98191
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98192
|
-
onClick: () => {
|
|
98193
|
-
if (!canFormat || !p3.selectedElement) {
|
|
98194
|
-
return;
|
|
98195
|
-
}
|
|
98196
|
-
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98197
|
-
p3.onUpdateTextStyle({
|
|
98198
|
-
listType: ts?.listType === "numbered" ? "none" : "numbered"
|
|
98199
|
-
});
|
|
98200
|
-
},
|
|
98201
|
-
className: gL,
|
|
98202
|
-
title: "Numbered List",
|
|
98203
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuListOrdered, { className: ic2 })
|
|
98613
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: grp, children: FMT.map((b2, i3, a2) => {
|
|
98614
|
+
const handleClick = () => {
|
|
98615
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98616
|
+
return;
|
|
98204
98617
|
}
|
|
98205
|
-
|
|
98206
|
-
|
|
98207
|
-
|
|
98208
|
-
|
|
98209
|
-
|
|
98210
|
-
|
|
98211
|
-
|
|
98212
|
-
|
|
98213
|
-
|
|
98214
|
-
onClick: () => {
|
|
98215
|
-
if (!canFormat || !p3.selectedElement) {
|
|
98216
|
-
return;
|
|
98217
|
-
}
|
|
98218
|
-
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98219
|
-
const current = ts?.paragraphMarginLeft ?? 0;
|
|
98618
|
+
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98619
|
+
switch (b2.t) {
|
|
98620
|
+
case "Bold":
|
|
98621
|
+
p3.onUpdateTextStyle({ bold: !ts?.bold });
|
|
98622
|
+
break;
|
|
98623
|
+
case "Italic":
|
|
98624
|
+
p3.onUpdateTextStyle({ italic: !ts?.italic });
|
|
98625
|
+
break;
|
|
98626
|
+
case "Underline":
|
|
98220
98627
|
p3.onUpdateTextStyle({
|
|
98221
|
-
|
|
98628
|
+
underline: !ts?.underline
|
|
98222
98629
|
});
|
|
98223
|
-
|
|
98224
|
-
|
|
98225
|
-
title: "Decrease Indent",
|
|
98226
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuIndentDecrease, { className: ic2 })
|
|
98227
|
-
}
|
|
98228
|
-
),
|
|
98229
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98230
|
-
"button",
|
|
98231
|
-
{
|
|
98232
|
-
type: "button",
|
|
98233
|
-
disabled: !canMut,
|
|
98234
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
98235
|
-
onClick: () => {
|
|
98236
|
-
if (!canFormat || !p3.selectedElement) {
|
|
98237
|
-
return;
|
|
98238
|
-
}
|
|
98239
|
-
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98240
|
-
const current = ts?.paragraphMarginLeft ?? 0;
|
|
98630
|
+
break;
|
|
98631
|
+
case "Strikethrough":
|
|
98241
98632
|
p3.onUpdateTextStyle({
|
|
98242
|
-
|
|
98633
|
+
strikethrough: !ts?.strikethrough
|
|
98243
98634
|
});
|
|
98244
|
-
|
|
98245
|
-
className: gL,
|
|
98246
|
-
title: "Increase Indent",
|
|
98247
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuIndentIncrease, { className: ic2 })
|
|
98248
|
-
}
|
|
98249
|
-
)
|
|
98250
|
-
] }),
|
|
98251
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: grp, children: ATXT.map((b2, i3, a2) => {
|
|
98252
|
-
const handleClick = () => {
|
|
98253
|
-
if (!canFormat) {
|
|
98254
|
-
return;
|
|
98255
|
-
}
|
|
98256
|
-
const alignMap = {
|
|
98257
|
-
"Align left": "left",
|
|
98258
|
-
"Align center": "center",
|
|
98259
|
-
"Align right": "right",
|
|
98260
|
-
Justify: "justify"
|
|
98261
|
-
};
|
|
98262
|
-
const align = alignMap[b2.t];
|
|
98263
|
-
if (align) {
|
|
98264
|
-
p3.onUpdateTextStyle({ align });
|
|
98635
|
+
break;
|
|
98265
98636
|
}
|
|
98266
98637
|
};
|
|
98267
98638
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -98277,518 +98648,318 @@ function TextSection(p3) {
|
|
|
98277
98648
|
},
|
|
98278
98649
|
b2.t
|
|
98279
98650
|
);
|
|
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
|
-
|
|
98364
|
-
})
|
|
98365
|
-
|
|
98366
|
-
|
|
98367
|
-
|
|
98368
|
-
|
|
98369
|
-
|
|
98370
|
-
|
|
98371
|
-
|
|
98372
|
-
|
|
98373
|
-
|
|
98374
|
-
|
|
98375
|
-
|
|
98376
|
-
|
|
98377
|
-
|
|
98378
|
-
|
|
98379
|
-
|
|
98380
|
-
|
|
98381
|
-
|
|
98382
|
-
|
|
98383
|
-
|
|
98384
|
-
|
|
98385
|
-
|
|
98386
|
-
|
|
98387
|
-
|
|
98388
|
-
|
|
98389
|
-
if (pendingBroadcastRef.current) {
|
|
98390
|
-
clearTimeout(pendingBroadcastRef.current);
|
|
98391
|
-
pendingBroadcastRef.current = null;
|
|
98392
|
-
}
|
|
98393
|
-
flush();
|
|
98394
|
-
} else if (!pendingBroadcastRef.current) {
|
|
98395
|
-
pendingBroadcastRef.current = setTimeout(() => {
|
|
98396
|
-
pendingBroadcastRef.current = null;
|
|
98397
|
-
flush();
|
|
98398
|
-
}, BROADCAST_THROTTLE_MS - elapsed);
|
|
98399
|
-
}
|
|
98400
|
-
},
|
|
98401
|
-
[awareness, userName, userColor, userAvatar]
|
|
98402
|
-
);
|
|
98403
|
-
React10.useEffect(() => {
|
|
98404
|
-
if (!awareness) {
|
|
98405
|
-
return;
|
|
98406
|
-
}
|
|
98407
|
-
awareness.setLocalStateField("presence", {
|
|
98408
|
-
userName,
|
|
98409
|
-
userColor,
|
|
98410
|
-
userAvatar,
|
|
98411
|
-
activeSlideIndex: 0,
|
|
98412
|
-
cursorX: 0,
|
|
98413
|
-
cursorY: 0,
|
|
98414
|
-
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
98415
|
-
});
|
|
98416
|
-
}, [awareness, userName, userColor, userAvatar]);
|
|
98417
|
-
React10.useEffect(() => {
|
|
98418
|
-
if (!awareness || localClientId === null) {
|
|
98419
|
-
return;
|
|
98420
|
-
}
|
|
98421
|
-
const handleChange = () => {
|
|
98422
|
-
const now = Date.now();
|
|
98423
|
-
const states = awareness.getStates();
|
|
98424
|
-
const users = [];
|
|
98425
|
-
states.forEach((state2, cid) => {
|
|
98426
|
-
if (cid === localClientId) {
|
|
98427
|
-
return;
|
|
98428
|
-
}
|
|
98429
|
-
const raw = state2?.presence;
|
|
98430
|
-
if (!raw || typeof raw !== "object") {
|
|
98431
|
-
return;
|
|
98432
|
-
}
|
|
98433
|
-
const sanitized = sanitizePresence({ ...raw, clientId: cid }, canvasWidth, canvasHeight);
|
|
98434
|
-
if (!sanitized) {
|
|
98435
|
-
return;
|
|
98436
|
-
}
|
|
98437
|
-
const updatedAt = new Date(sanitized.lastUpdated).getTime();
|
|
98438
|
-
if (Number.isNaN(updatedAt) || now - updatedAt > STALE_PRESENCE_MS) {
|
|
98439
|
-
return;
|
|
98440
|
-
}
|
|
98441
|
-
users.push(sanitized);
|
|
98442
|
-
});
|
|
98443
|
-
setRemoteUsers(users);
|
|
98444
|
-
};
|
|
98445
|
-
awareness.on("change", handleChange);
|
|
98446
|
-
awareness.on("update", handleChange);
|
|
98447
|
-
handleChange();
|
|
98448
|
-
return () => {
|
|
98449
|
-
awareness.off("change", handleChange);
|
|
98450
|
-
awareness.off("update", handleChange);
|
|
98451
|
-
};
|
|
98452
|
-
}, [awareness, localClientId, canvasWidth, canvasHeight]);
|
|
98453
|
-
React10.useEffect(() => {
|
|
98454
|
-
if (!awareness) {
|
|
98455
|
-
return;
|
|
98456
|
-
}
|
|
98457
|
-
const interval = setInterval(() => {
|
|
98458
|
-
awareness.setLocalStateField("presence", {
|
|
98459
|
-
...latestLocalState.current,
|
|
98460
|
-
userName,
|
|
98461
|
-
userColor,
|
|
98462
|
-
userAvatar,
|
|
98463
|
-
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
98464
|
-
});
|
|
98465
|
-
}, 1e4);
|
|
98466
|
-
return () => clearInterval(interval);
|
|
98467
|
-
}, [awareness, userName, userColor, userAvatar]);
|
|
98468
|
-
React10.useEffect(() => {
|
|
98469
|
-
return () => {
|
|
98470
|
-
if (pendingBroadcastRef.current) {
|
|
98471
|
-
clearTimeout(pendingBroadcastRef.current);
|
|
98472
|
-
}
|
|
98473
|
-
};
|
|
98474
|
-
}, []);
|
|
98475
|
-
return { remoteUsers, broadcastPresence };
|
|
98476
|
-
}
|
|
98477
|
-
function useYjsProvider({ config }) {
|
|
98478
|
-
const [status, setStatus] = React10.useState("disconnected");
|
|
98479
|
-
const [awareness, setAwareness] = React10.useState(null);
|
|
98480
|
-
const [doc2, setDoc] = React10.useState(null);
|
|
98481
|
-
const [clientId, setClientId] = React10.useState(null);
|
|
98482
|
-
const cleanupRef = React10.useRef(null);
|
|
98483
|
-
const init = React10.useCallback(async () => {
|
|
98484
|
-
const roomId = validateRoomId(config.roomId);
|
|
98485
|
-
setStatus("connecting");
|
|
98486
|
-
try {
|
|
98487
|
-
const [Y, { WebsocketProvider: WebsocketProvider2 }] = await Promise.all([Promise.resolve().then(() => (init_yjs(), yjs_exports)), Promise.resolve().then(() => (init_y_websocket(), y_websocket_exports))]);
|
|
98488
|
-
const yDoc = new Y.Doc();
|
|
98489
|
-
const provider = new WebsocketProvider2(
|
|
98490
|
-
config.serverUrl,
|
|
98491
|
-
roomId,
|
|
98492
|
-
yDoc,
|
|
98493
|
-
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
98494
|
-
{
|
|
98495
|
-
params: config.authToken ? { token: config.authToken } : void 0
|
|
98496
|
-
}
|
|
98497
|
-
);
|
|
98498
|
-
const handleStatus = (event) => {
|
|
98499
|
-
if (event.status === "connected") {
|
|
98500
|
-
setStatus("connected");
|
|
98501
|
-
} else if (event.status === "disconnected") {
|
|
98502
|
-
setStatus("disconnected");
|
|
98503
|
-
}
|
|
98504
|
-
};
|
|
98505
|
-
provider.on("status", handleStatus);
|
|
98506
|
-
if (provider.wsconnected) {
|
|
98507
|
-
setStatus("connected");
|
|
98508
|
-
}
|
|
98509
|
-
setDoc(yDoc);
|
|
98510
|
-
setAwareness(provider.awareness);
|
|
98511
|
-
setClientId(provider.awareness.clientID);
|
|
98512
|
-
cleanupRef.current = () => {
|
|
98513
|
-
provider.off("status", handleStatus);
|
|
98514
|
-
provider.destroy();
|
|
98515
|
-
yDoc.destroy();
|
|
98516
|
-
setDoc(null);
|
|
98517
|
-
setAwareness(null);
|
|
98518
|
-
setClientId(null);
|
|
98519
|
-
setStatus("disconnected");
|
|
98520
|
-
};
|
|
98521
|
-
} catch (err) {
|
|
98522
|
-
console.warn(
|
|
98523
|
-
"[pptx-viewer] Collaboration packages not available:",
|
|
98524
|
-
err instanceof Error ? err.message : err
|
|
98525
|
-
);
|
|
98526
|
-
setStatus("error");
|
|
98527
|
-
}
|
|
98528
|
-
}, [config.roomId, config.serverUrl, config.authToken]);
|
|
98529
|
-
React10.useEffect(() => {
|
|
98530
|
-
init();
|
|
98531
|
-
return () => {
|
|
98532
|
-
cleanupRef.current?.();
|
|
98533
|
-
cleanupRef.current = null;
|
|
98534
|
-
};
|
|
98535
|
-
}, [init]);
|
|
98536
|
-
return { status, awareness, doc: doc2, clientId };
|
|
98537
|
-
}
|
|
98538
|
-
|
|
98539
|
-
// src/viewer/hooks/collaboration/useCollaborativeState.ts
|
|
98540
|
-
function useCollaborativeState({
|
|
98541
|
-
config,
|
|
98542
|
-
canvasWidth,
|
|
98543
|
-
canvasHeight
|
|
98544
|
-
}) {
|
|
98545
|
-
const userColor = sanitizeColor(config.userColor, "#6366f1");
|
|
98546
|
-
const { status, awareness, doc: doc2, clientId } = useYjsProvider({ config });
|
|
98547
|
-
const { remoteUsers, broadcastPresence } = usePresenceTracking({
|
|
98548
|
-
awareness,
|
|
98549
|
-
localClientId: clientId,
|
|
98550
|
-
userName: config.userName,
|
|
98551
|
-
userColor,
|
|
98552
|
-
userAvatar: config.userAvatar,
|
|
98553
|
-
canvasWidth,
|
|
98554
|
-
canvasHeight
|
|
98555
|
-
});
|
|
98556
|
-
const connectedCount = status === "connected" ? remoteUsers.length + 1 : remoteUsers.length;
|
|
98557
|
-
return {
|
|
98558
|
-
status,
|
|
98559
|
-
remoteUsers,
|
|
98560
|
-
broadcastPresence,
|
|
98561
|
-
connectedCount,
|
|
98562
|
-
config,
|
|
98563
|
-
doc: doc2
|
|
98564
|
-
};
|
|
98565
|
-
}
|
|
98566
|
-
var CollaborationContext = React10.createContext(null);
|
|
98567
|
-
function useCollaboration() {
|
|
98568
|
-
return React10.useContext(CollaborationContext);
|
|
98569
|
-
}
|
|
98570
|
-
function CollaborationProvider({
|
|
98571
|
-
config,
|
|
98572
|
-
canvasWidth,
|
|
98573
|
-
canvasHeight,
|
|
98574
|
-
children
|
|
98575
|
-
}) {
|
|
98576
|
-
const value = useCollaborativeState({
|
|
98577
|
-
config,
|
|
98578
|
-
canvasWidth,
|
|
98579
|
-
canvasHeight
|
|
98580
|
-
});
|
|
98581
|
-
return /* @__PURE__ */ jsxRuntime.jsx(CollaborationContext.Provider, { value, children });
|
|
98582
|
-
}
|
|
98583
|
-
function RemoteUserCursors({
|
|
98584
|
-
remoteUsers,
|
|
98585
|
-
activeSlideIndex,
|
|
98586
|
-
canvasWidth,
|
|
98587
|
-
canvasHeight
|
|
98588
|
-
}) {
|
|
98589
|
-
const visibleUsers = remoteUsers.filter((u2) => u2.activeSlideIndex === activeSlideIndex);
|
|
98590
|
-
if (visibleUsers.length === 0) {
|
|
98591
|
-
return null;
|
|
98592
|
-
}
|
|
98593
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
98594
|
-
"svg",
|
|
98595
|
-
{
|
|
98596
|
-
"data-testid": "remote-user-cursors",
|
|
98597
|
-
className: "absolute inset-0 pointer-events-none",
|
|
98598
|
-
style: { zIndex: 9999 },
|
|
98599
|
-
width: canvasWidth,
|
|
98600
|
-
height: canvasHeight,
|
|
98601
|
-
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
98602
|
-
"aria-hidden": "true",
|
|
98603
|
-
children: visibleUsers.map((user) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
98604
|
-
"g",
|
|
98605
|
-
{
|
|
98606
|
-
transform: `translate(${user.cursorX}, ${user.cursorY})`,
|
|
98607
|
-
"data-testid": `remote-cursor-${user.clientId}`,
|
|
98608
|
-
children: [
|
|
98651
|
+
}) }),
|
|
98652
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: grp, children: [
|
|
98653
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98654
|
+
"button",
|
|
98655
|
+
{
|
|
98656
|
+
type: "button",
|
|
98657
|
+
disabled: !canMut,
|
|
98658
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98659
|
+
onClick: () => {
|
|
98660
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98661
|
+
return;
|
|
98662
|
+
}
|
|
98663
|
+
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98664
|
+
const current = ts?.fontSize ?? 18;
|
|
98665
|
+
p3.onUpdateTextStyle({ fontSize: current + 2 });
|
|
98666
|
+
},
|
|
98667
|
+
className: gB,
|
|
98668
|
+
title: "Increase Font Size",
|
|
98669
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAArrowUp, { className: ic2 })
|
|
98670
|
+
}
|
|
98671
|
+
),
|
|
98672
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98673
|
+
"button",
|
|
98674
|
+
{
|
|
98675
|
+
type: "button",
|
|
98676
|
+
disabled: !canMut,
|
|
98677
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98678
|
+
onClick: () => {
|
|
98679
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98680
|
+
return;
|
|
98681
|
+
}
|
|
98682
|
+
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98683
|
+
const current = ts?.fontSize ?? 18;
|
|
98684
|
+
p3.onUpdateTextStyle({ fontSize: Math.max(1, current - 2) });
|
|
98685
|
+
},
|
|
98686
|
+
className: gB,
|
|
98687
|
+
title: "Decrease Font Size",
|
|
98688
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAArrowDown, { className: ic2 })
|
|
98689
|
+
}
|
|
98690
|
+
),
|
|
98691
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98692
|
+
"button",
|
|
98693
|
+
{
|
|
98694
|
+
type: "button",
|
|
98695
|
+
disabled: !canMut,
|
|
98696
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98697
|
+
onClick: () => {
|
|
98698
|
+
if (!canFormat) {
|
|
98699
|
+
return;
|
|
98700
|
+
}
|
|
98701
|
+
p3.onUpdateTextStyle({
|
|
98702
|
+
bold: false,
|
|
98703
|
+
italic: false,
|
|
98704
|
+
underline: false,
|
|
98705
|
+
strikethrough: false,
|
|
98706
|
+
highlightColor: void 0
|
|
98707
|
+
});
|
|
98708
|
+
},
|
|
98709
|
+
className: gL,
|
|
98710
|
+
title: "Clear Formatting",
|
|
98711
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuRemoveFormatting, { className: ic2 })
|
|
98712
|
+
}
|
|
98713
|
+
)
|
|
98714
|
+
] }),
|
|
98715
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group", children: [
|
|
98716
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
98717
|
+
"button",
|
|
98718
|
+
{
|
|
98719
|
+
type: "button",
|
|
98720
|
+
disabled: !canMut,
|
|
98721
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98722
|
+
className: pill,
|
|
98723
|
+
title: "Font Color",
|
|
98724
|
+
children: [
|
|
98725
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98726
|
+
"svg",
|
|
98727
|
+
{
|
|
98728
|
+
className: ic2,
|
|
98729
|
+
viewBox: "0 0 24 24",
|
|
98730
|
+
fill: "none",
|
|
98731
|
+
stroke: "currentColor",
|
|
98732
|
+
strokeWidth: "2",
|
|
98733
|
+
strokeLinecap: "round",
|
|
98734
|
+
strokeLinejoin: "round",
|
|
98735
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 20h12M9.5 4h5L18 16H6L9.5 4z" })
|
|
98736
|
+
}
|
|
98737
|
+
),
|
|
98738
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98739
|
+
"div",
|
|
98740
|
+
{
|
|
98741
|
+
className: "w-4 h-1 rounded-sm -mt-0.5",
|
|
98742
|
+
style: { backgroundColor: currentColor }
|
|
98743
|
+
}
|
|
98744
|
+
)
|
|
98745
|
+
]
|
|
98746
|
+
}
|
|
98747
|
+
),
|
|
98748
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-full z-50 hidden group-hover:block pt-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl p-2 w-36", children: [
|
|
98749
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5 gap-1.5 mb-2", children: FONT_COLOR_PRESETS.map((c2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
98750
|
+
"button",
|
|
98751
|
+
{
|
|
98752
|
+
type: "button",
|
|
98753
|
+
className: `w-5 h-5 rounded-full border transition-transform hover:scale-125 ${currentColor?.toLowerCase() === c2 ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
98754
|
+
style: { backgroundColor: c2 },
|
|
98755
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98756
|
+
onClick: () => handleColorChange(c2)
|
|
98757
|
+
},
|
|
98758
|
+
c2
|
|
98759
|
+
)) }),
|
|
98609
98760
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98610
|
-
"
|
|
98761
|
+
"button",
|
|
98611
98762
|
{
|
|
98612
|
-
|
|
98613
|
-
|
|
98614
|
-
|
|
98615
|
-
|
|
98616
|
-
|
|
98763
|
+
type: "button",
|
|
98764
|
+
className: "w-full text-[10px] text-muted-foreground hover:text-foreground py-1 transition-colors",
|
|
98765
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98766
|
+
onClick: () => colorInputRef.current?.click(),
|
|
98767
|
+
children: "Custom colour..."
|
|
98617
98768
|
}
|
|
98618
98769
|
),
|
|
98619
|
-
/* @__PURE__ */ jsxRuntime.
|
|
98620
|
-
|
|
98621
|
-
|
|
98622
|
-
|
|
98623
|
-
|
|
98624
|
-
|
|
98625
|
-
|
|
98626
|
-
|
|
98627
|
-
|
|
98628
|
-
|
|
98629
|
-
|
|
98630
|
-
|
|
98770
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98771
|
+
"input",
|
|
98772
|
+
{
|
|
98773
|
+
ref: colorInputRef,
|
|
98774
|
+
type: "color",
|
|
98775
|
+
className: "sr-only",
|
|
98776
|
+
value: currentColor,
|
|
98777
|
+
onChange: (e2) => handleColorChange(e2.target.value)
|
|
98778
|
+
}
|
|
98779
|
+
)
|
|
98780
|
+
] }) })
|
|
98781
|
+
] }),
|
|
98782
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group", children: [
|
|
98783
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
98784
|
+
"button",
|
|
98785
|
+
{
|
|
98786
|
+
type: "button",
|
|
98787
|
+
disabled: !canMut,
|
|
98788
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98789
|
+
className: pill,
|
|
98790
|
+
title: "Text Highlight Color",
|
|
98791
|
+
children: [
|
|
98792
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuHighlighter, { className: ic2 }),
|
|
98793
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98794
|
+
"div",
|
|
98795
|
+
{
|
|
98796
|
+
className: "w-4 h-1 rounded-sm -mt-0.5",
|
|
98797
|
+
style: { backgroundColor: currentHighlight }
|
|
98798
|
+
}
|
|
98799
|
+
)
|
|
98800
|
+
]
|
|
98801
|
+
}
|
|
98802
|
+
),
|
|
98803
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-full z-50 hidden group-hover:block pt-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl p-2 w-36", children: [
|
|
98804
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5 gap-1.5 mb-2", children: HIGHLIGHT_COLOR_PRESETS.map((c2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
98805
|
+
"button",
|
|
98806
|
+
{
|
|
98807
|
+
type: "button",
|
|
98808
|
+
className: `w-5 h-5 rounded-full border transition-transform hover:scale-125 ${currentHighlight?.toLowerCase() === c2 ? "border-primary ring-1 ring-primary" : "border-border"}`,
|
|
98809
|
+
style: { backgroundColor: c2 },
|
|
98810
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98811
|
+
onClick: () => handleHighlightChange(c2)
|
|
98812
|
+
},
|
|
98813
|
+
c2
|
|
98814
|
+
)) }),
|
|
98815
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98816
|
+
"button",
|
|
98817
|
+
{
|
|
98818
|
+
type: "button",
|
|
98819
|
+
className: "w-full text-[10px] text-muted-foreground hover:text-foreground py-1 transition-colors",
|
|
98820
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98821
|
+
onClick: () => highlightInputRef.current?.click(),
|
|
98822
|
+
children: "Custom colour..."
|
|
98823
|
+
}
|
|
98824
|
+
),
|
|
98825
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98826
|
+
"input",
|
|
98827
|
+
{
|
|
98828
|
+
ref: highlightInputRef,
|
|
98829
|
+
type: "color",
|
|
98830
|
+
className: "sr-only",
|
|
98831
|
+
value: currentHighlight,
|
|
98832
|
+
onChange: (e2) => handleHighlightChange(e2.target.value)
|
|
98833
|
+
}
|
|
98834
|
+
)
|
|
98835
|
+
] }) })
|
|
98836
|
+
] })
|
|
98837
|
+
] }),
|
|
98838
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Font" })
|
|
98839
|
+
] }),
|
|
98840
|
+
sep,
|
|
98841
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
98842
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
98843
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: grp, children: [
|
|
98844
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98845
|
+
"button",
|
|
98846
|
+
{
|
|
98847
|
+
type: "button",
|
|
98848
|
+
disabled: !canMut,
|
|
98849
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98850
|
+
onClick: () => {
|
|
98851
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98852
|
+
return;
|
|
98631
98853
|
}
|
|
98632
|
-
|
|
98633
|
-
|
|
98634
|
-
|
|
98635
|
-
|
|
98636
|
-
|
|
98637
|
-
|
|
98638
|
-
|
|
98639
|
-
|
|
98640
|
-
|
|
98641
|
-
|
|
98642
|
-
|
|
98643
|
-
|
|
98854
|
+
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98855
|
+
p3.onUpdateTextStyle({
|
|
98856
|
+
listType: ts?.listType === "bullet" ? "none" : "bullet"
|
|
98857
|
+
});
|
|
98858
|
+
},
|
|
98859
|
+
className: gB,
|
|
98860
|
+
title: "Bullet List",
|
|
98861
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuList, { className: ic2 })
|
|
98862
|
+
}
|
|
98863
|
+
),
|
|
98864
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98865
|
+
"button",
|
|
98866
|
+
{
|
|
98867
|
+
type: "button",
|
|
98868
|
+
disabled: !canMut,
|
|
98869
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98870
|
+
onClick: () => {
|
|
98871
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98872
|
+
return;
|
|
98644
98873
|
}
|
|
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
|
-
|
|
98709
|
-
|
|
98710
|
-
|
|
98711
|
-
|
|
98712
|
-
|
|
98713
|
-
|
|
98714
|
-
|
|
98715
|
-
|
|
98716
|
-
|
|
98717
|
-
|
|
98718
|
-
|
|
98719
|
-
|
|
98720
|
-
|
|
98721
|
-
|
|
98722
|
-
|
|
98723
|
-
|
|
98724
|
-
|
|
98725
|
-
|
|
98726
|
-
|
|
98727
|
-
|
|
98728
|
-
|
|
98729
|
-
|
|
98730
|
-
|
|
98731
|
-
|
|
98732
|
-
|
|
98733
|
-
|
|
98734
|
-
overflow > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
98735
|
-
"div",
|
|
98736
|
-
{
|
|
98737
|
-
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",
|
|
98738
|
-
title: t2("pptx.collaboration.moreUsers", { count: overflow }),
|
|
98739
|
-
children: [
|
|
98740
|
-
"+",
|
|
98741
|
-
overflow
|
|
98742
|
-
]
|
|
98743
|
-
}
|
|
98744
|
-
)
|
|
98745
|
-
]
|
|
98746
|
-
}
|
|
98747
|
-
);
|
|
98748
|
-
}
|
|
98749
|
-
var STATUS_STYLES = {
|
|
98750
|
-
connected: {
|
|
98751
|
-
dot: "bg-green-400",
|
|
98752
|
-
text: "text-green-400",
|
|
98753
|
-
label: "Connected"
|
|
98754
|
-
},
|
|
98755
|
-
connecting: {
|
|
98756
|
-
dot: "bg-yellow-400 animate-pulse",
|
|
98757
|
-
text: "text-yellow-400",
|
|
98758
|
-
label: "Connecting..."
|
|
98759
|
-
},
|
|
98760
|
-
disconnected: {
|
|
98761
|
-
dot: "bg-gray-500",
|
|
98762
|
-
text: "text-gray-500",
|
|
98763
|
-
label: "Disconnected"
|
|
98764
|
-
},
|
|
98765
|
-
error: {
|
|
98766
|
-
dot: "bg-red-400",
|
|
98767
|
-
text: "text-red-400",
|
|
98768
|
-
label: "Connection error"
|
|
98769
|
-
}
|
|
98770
|
-
};
|
|
98771
|
-
function CollaborationStatusIndicator({
|
|
98772
|
-
status,
|
|
98773
|
-
connectedCount
|
|
98774
|
-
}) {
|
|
98775
|
-
const { t: t2 } = reactI18next.useTranslation();
|
|
98776
|
-
const style = STATUS_STYLES[status];
|
|
98777
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
98778
|
-
"div",
|
|
98779
|
-
{
|
|
98780
|
-
"data-testid": "collaboration-status",
|
|
98781
|
-
className: "flex items-center gap-1.5",
|
|
98782
|
-
"aria-label": t2("pptx.collaboration.statusAriaLabel", {
|
|
98783
|
-
status: t2(`pptx.collaboration.status.${status}`),
|
|
98784
|
-
count: connectedCount
|
|
98785
|
-
}),
|
|
98786
|
-
children: [
|
|
98787
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-block w-2 h-2 rounded-full ${style.dot}`, "aria-hidden": "true" }),
|
|
98788
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-[10px] ${style.text}`, children: status === "connected" ? t2("pptx.collaboration.userCount", { count: connectedCount }) : t2(`pptx.collaboration.status.${status}`) })
|
|
98789
|
-
]
|
|
98790
|
-
}
|
|
98791
|
-
);
|
|
98874
|
+
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98875
|
+
p3.onUpdateTextStyle({
|
|
98876
|
+
listType: ts?.listType === "numbered" ? "none" : "numbered"
|
|
98877
|
+
});
|
|
98878
|
+
},
|
|
98879
|
+
className: gL,
|
|
98880
|
+
title: "Numbered List",
|
|
98881
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuListOrdered, { className: ic2 })
|
|
98882
|
+
}
|
|
98883
|
+
)
|
|
98884
|
+
] }),
|
|
98885
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: grp, children: [
|
|
98886
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98887
|
+
"button",
|
|
98888
|
+
{
|
|
98889
|
+
type: "button",
|
|
98890
|
+
disabled: !canMut,
|
|
98891
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98892
|
+
onClick: () => {
|
|
98893
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98894
|
+
return;
|
|
98895
|
+
}
|
|
98896
|
+
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98897
|
+
const current = ts?.paragraphMarginLeft ?? 0;
|
|
98898
|
+
p3.onUpdateTextStyle({
|
|
98899
|
+
paragraphMarginLeft: Math.max(0, current - 24)
|
|
98900
|
+
});
|
|
98901
|
+
},
|
|
98902
|
+
className: gB,
|
|
98903
|
+
title: "Decrease Indent",
|
|
98904
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuIndentDecrease, { className: ic2 })
|
|
98905
|
+
}
|
|
98906
|
+
),
|
|
98907
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98908
|
+
"button",
|
|
98909
|
+
{
|
|
98910
|
+
type: "button",
|
|
98911
|
+
disabled: !canMut,
|
|
98912
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98913
|
+
onClick: () => {
|
|
98914
|
+
if (!canFormat || !p3.selectedElement) {
|
|
98915
|
+
return;
|
|
98916
|
+
}
|
|
98917
|
+
const ts = pptxViewerCore.hasTextProperties(p3.selectedElement) ? p3.selectedElement.textStyle : void 0;
|
|
98918
|
+
const current = ts?.paragraphMarginLeft ?? 0;
|
|
98919
|
+
p3.onUpdateTextStyle({
|
|
98920
|
+
paragraphMarginLeft: current + 24
|
|
98921
|
+
});
|
|
98922
|
+
},
|
|
98923
|
+
className: gL,
|
|
98924
|
+
title: "Increase Indent",
|
|
98925
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuIndentIncrease, { className: ic2 })
|
|
98926
|
+
}
|
|
98927
|
+
)
|
|
98928
|
+
] }),
|
|
98929
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: grp, children: ATXT.map((b2, i3, a2) => {
|
|
98930
|
+
const handleClick = () => {
|
|
98931
|
+
if (!canFormat) {
|
|
98932
|
+
return;
|
|
98933
|
+
}
|
|
98934
|
+
const alignMap = {
|
|
98935
|
+
"Align left": "left",
|
|
98936
|
+
"Align center": "center",
|
|
98937
|
+
"Align right": "right",
|
|
98938
|
+
Justify: "justify"
|
|
98939
|
+
};
|
|
98940
|
+
const align = alignMap[b2.t];
|
|
98941
|
+
if (align) {
|
|
98942
|
+
p3.onUpdateTextStyle({ align });
|
|
98943
|
+
}
|
|
98944
|
+
};
|
|
98945
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
98946
|
+
"button",
|
|
98947
|
+
{
|
|
98948
|
+
type: "button",
|
|
98949
|
+
disabled: !canMut,
|
|
98950
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98951
|
+
onClick: handleClick,
|
|
98952
|
+
className: i3 < a2.length - 1 ? gB : gL,
|
|
98953
|
+
title: b2.t,
|
|
98954
|
+
children: b2.i
|
|
98955
|
+
},
|
|
98956
|
+
b2.t
|
|
98957
|
+
);
|
|
98958
|
+
}) })
|
|
98959
|
+
] }),
|
|
98960
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Paragraph" })
|
|
98961
|
+
] })
|
|
98962
|
+
] });
|
|
98792
98963
|
}
|
|
98793
98964
|
function CustomShowsControls({
|
|
98794
98965
|
customShows,
|
|
@@ -99228,29 +99399,38 @@ function ToolbarPrimaryRow(p3) {
|
|
|
99228
99399
|
]
|
|
99229
99400
|
}
|
|
99230
99401
|
),
|
|
99231
|
-
collab && (collab.status === "connected" || collab.status === "connecting") && collab.remoteUsers.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
99232
|
-
|
|
99233
|
-
|
|
99234
|
-
|
|
99235
|
-
|
|
99236
|
-
|
|
99237
|
-
|
|
99238
|
-
|
|
99239
|
-
|
|
99402
|
+
collab && (collab.status === "connected" || collab.status === "connecting") && collab.remoteUsers.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
99403
|
+
"button",
|
|
99404
|
+
{
|
|
99405
|
+
type: "button",
|
|
99406
|
+
onClick: p3.onOpenShareDialog,
|
|
99407
|
+
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",
|
|
99408
|
+
title: t2("pptx.toolbar.sharingUsers", { count: collab.connectedCount }),
|
|
99409
|
+
children: [
|
|
99410
|
+
collab.remoteUsers.slice(0, 4).map((user) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
99411
|
+
"div",
|
|
99240
99412
|
{
|
|
99241
|
-
|
|
99242
|
-
|
|
99243
|
-
|
|
99244
|
-
|
|
99245
|
-
|
|
99246
|
-
|
|
99247
|
-
|
|
99248
|
-
|
|
99249
|
-
|
|
99250
|
-
|
|
99251
|
-
|
|
99252
|
-
|
|
99253
|
-
|
|
99413
|
+
className: "w-6 h-6 rounded-full border-2 border-background flex items-center justify-center text-[8px] font-semibold text-white shrink-0",
|
|
99414
|
+
style: { backgroundColor: user.userColor },
|
|
99415
|
+
title: user.userName,
|
|
99416
|
+
children: user.userAvatar ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
99417
|
+
"img",
|
|
99418
|
+
{
|
|
99419
|
+
src: user.userAvatar,
|
|
99420
|
+
alt: user.userName,
|
|
99421
|
+
className: "w-full h-full rounded-full object-cover"
|
|
99422
|
+
}
|
|
99423
|
+
) : user.userName.slice(0, 2).toUpperCase()
|
|
99424
|
+
},
|
|
99425
|
+
user.clientId
|
|
99426
|
+
)),
|
|
99427
|
+
collab.remoteUsers.length > 4 && /* @__PURE__ */ jsxRuntime.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: [
|
|
99428
|
+
"+",
|
|
99429
|
+
collab.remoteUsers.length - 4
|
|
99430
|
+
] })
|
|
99431
|
+
]
|
|
99432
|
+
}
|
|
99433
|
+
),
|
|
99254
99434
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
99255
99435
|
ModeSwitcher,
|
|
99256
99436
|
{
|
|
@@ -99627,7 +99807,8 @@ function Toolbar(p3) {
|
|
|
99627
99807
|
canEdit: p3.canEdit,
|
|
99628
99808
|
selectedElement: p3.selectedElement,
|
|
99629
99809
|
isInspectorPaneOpen: p3.isInspectorPaneOpen,
|
|
99630
|
-
onToggleInspector: p3.onToggleInspector
|
|
99810
|
+
onToggleInspector: p3.onToggleInspector,
|
|
99811
|
+
onOpenAnimationPanel: p3.onOpenAnimationPanel
|
|
99631
99812
|
}
|
|
99632
99813
|
),
|
|
99633
99814
|
sSlw && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -107072,9 +107253,75 @@ function SetUpSlideShowDialog({
|
|
|
107072
107253
|
}
|
|
107073
107254
|
function BroadcastDialog({
|
|
107074
107255
|
open,
|
|
107075
|
-
onClose
|
|
107256
|
+
onClose,
|
|
107257
|
+
onStartBroadcast,
|
|
107258
|
+
onStopBroadcast,
|
|
107259
|
+
onStartPresenting,
|
|
107260
|
+
defaultRoomId,
|
|
107261
|
+
defaultUserName,
|
|
107262
|
+
defaultServerUrl
|
|
107076
107263
|
}) {
|
|
107077
107264
|
const { t: t2 } = reactI18next.useTranslation();
|
|
107265
|
+
const collab = useCollaboration();
|
|
107266
|
+
const isBroadcasting = collab !== null && collab.status !== "disconnected" && collab.status !== "error" && collab.config.role === "broadcaster";
|
|
107267
|
+
const [roomId, setRoomId] = React10.useState("");
|
|
107268
|
+
const [userName, setUserName] = React10.useState("");
|
|
107269
|
+
const [serverUrl, setServerUrl] = React10.useState("");
|
|
107270
|
+
const [copied, setCopied] = React10.useState(false);
|
|
107271
|
+
const dialogRef = React10.useRef(null);
|
|
107272
|
+
React10.useEffect(() => {
|
|
107273
|
+
if (open && !isBroadcasting) {
|
|
107274
|
+
const broadcastRoom = defaultRoomId ? `broadcast-${defaultRoomId}` : `broadcast-${Math.random().toString(36).slice(2, 10)}`;
|
|
107275
|
+
setRoomId(broadcastRoom);
|
|
107276
|
+
setUserName(defaultUserName ?? "");
|
|
107277
|
+
setServerUrl(defaultServerUrl ?? "ws://localhost:1234");
|
|
107278
|
+
}
|
|
107279
|
+
}, [open, isBroadcasting, defaultRoomId, defaultUserName, defaultServerUrl]);
|
|
107280
|
+
React10.useEffect(() => {
|
|
107281
|
+
if (!open) {
|
|
107282
|
+
return;
|
|
107283
|
+
}
|
|
107284
|
+
function handleKeyDown(e2) {
|
|
107285
|
+
if (e2.key === "Escape") {
|
|
107286
|
+
onClose();
|
|
107287
|
+
}
|
|
107288
|
+
}
|
|
107289
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
107290
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
107291
|
+
}, [open, onClose]);
|
|
107292
|
+
React10.useEffect(() => {
|
|
107293
|
+
if (open && dialogRef.current) {
|
|
107294
|
+
dialogRef.current.focus();
|
|
107295
|
+
}
|
|
107296
|
+
}, [open]);
|
|
107297
|
+
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;
|
|
107298
|
+
const handleCopyUrl = React10.useCallback(() => {
|
|
107299
|
+
void navigator.clipboard.writeText(broadcastUrl).then(() => {
|
|
107300
|
+
setCopied(true);
|
|
107301
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
107302
|
+
return void 0;
|
|
107303
|
+
});
|
|
107304
|
+
}, [broadcastUrl]);
|
|
107305
|
+
const handleStartBroadcast = React10.useCallback(() => {
|
|
107306
|
+
if (!roomId.trim() || !userName.trim()) {
|
|
107307
|
+
return;
|
|
107308
|
+
}
|
|
107309
|
+
onStartBroadcast?.({
|
|
107310
|
+
roomId: roomId.trim(),
|
|
107311
|
+
serverUrl: serverUrl.trim(),
|
|
107312
|
+
userName: userName.trim(),
|
|
107313
|
+
role: "broadcaster"
|
|
107314
|
+
});
|
|
107315
|
+
setTimeout(() => {
|
|
107316
|
+
onStartPresenting?.();
|
|
107317
|
+
}, 100);
|
|
107318
|
+
onClose();
|
|
107319
|
+
}, [roomId, userName, serverUrl, onStartBroadcast, onStartPresenting, onClose]);
|
|
107320
|
+
const handleStopBroadcast = React10.useCallback(() => {
|
|
107321
|
+
onStopBroadcast?.();
|
|
107322
|
+
onClose();
|
|
107323
|
+
}, [onStopBroadcast, onClose]);
|
|
107324
|
+
const canStart = roomId.trim().length > 0 && userName.trim().length > 0 && serverUrl.trim().length > 0;
|
|
107078
107325
|
if (!open) {
|
|
107079
107326
|
return null;
|
|
107080
107327
|
}
|
|
@@ -107088,42 +107335,225 @@ function BroadcastDialog({
|
|
|
107088
107335
|
onClick: onClose
|
|
107089
107336
|
}
|
|
107090
107337
|
),
|
|
107091
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-[201] flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
107092
|
-
|
|
107093
|
-
|
|
107338
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-[201] flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
107339
|
+
"div",
|
|
107340
|
+
{
|
|
107341
|
+
ref: dialogRef,
|
|
107342
|
+
role: "dialog",
|
|
107343
|
+
"aria-modal": "true",
|
|
107344
|
+
"aria-label": t2("pptx.broadcast.title"),
|
|
107345
|
+
tabIndex: -1,
|
|
107346
|
+
className: "pointer-events-auto w-full max-w-md rounded-xl border border-border bg-popover text-foreground shadow-2xl outline-none",
|
|
107347
|
+
children: [
|
|
107348
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-5 py-3 border-b border-border", children: [
|
|
107349
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-sm font-semibold text-foreground flex items-center gap-2", children: [
|
|
107350
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCast, { className: "w-4 h-4" }),
|
|
107351
|
+
isBroadcasting ? t2("pptx.broadcast.broadcasting") : t2("pptx.broadcast.title")
|
|
107352
|
+
] }),
|
|
107353
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107354
|
+
"button",
|
|
107355
|
+
{
|
|
107356
|
+
type: "button",
|
|
107357
|
+
onClick: onClose,
|
|
107358
|
+
className: "text-muted-foreground hover:text-foreground text-lg leading-none",
|
|
107359
|
+
"aria-label": "Close",
|
|
107360
|
+
children: "\xD7"
|
|
107361
|
+
}
|
|
107362
|
+
)
|
|
107363
|
+
] }),
|
|
107364
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-5 py-4", children: isBroadcasting ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
107365
|
+
ActiveBroadcastView,
|
|
107366
|
+
{
|
|
107367
|
+
collab,
|
|
107368
|
+
broadcastUrl,
|
|
107369
|
+
copied,
|
|
107370
|
+
onCopyUrl: handleCopyUrl,
|
|
107371
|
+
onStopBroadcast: handleStopBroadcast
|
|
107372
|
+
}
|
|
107373
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
107374
|
+
StartBroadcastForm,
|
|
107375
|
+
{
|
|
107376
|
+
roomId,
|
|
107377
|
+
userName,
|
|
107378
|
+
serverUrl,
|
|
107379
|
+
onRoomIdChange: setRoomId,
|
|
107380
|
+
onUserNameChange: setUserName,
|
|
107381
|
+
onServerUrlChange: setServerUrl
|
|
107382
|
+
}
|
|
107383
|
+
) }),
|
|
107384
|
+
!isBroadcasting && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 px-5 py-3 border-t border-border", children: [
|
|
107385
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107386
|
+
"button",
|
|
107387
|
+
{
|
|
107388
|
+
type: "button",
|
|
107389
|
+
onClick: onClose,
|
|
107390
|
+
className: "px-3 py-1.5 rounded bg-muted hover:bg-accent text-[12px] text-foreground transition-colors",
|
|
107391
|
+
children: t2("common.close")
|
|
107392
|
+
}
|
|
107393
|
+
),
|
|
107394
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107395
|
+
"button",
|
|
107396
|
+
{
|
|
107397
|
+
type: "button",
|
|
107398
|
+
disabled: !canStart,
|
|
107399
|
+
onClick: handleStartBroadcast,
|
|
107400
|
+
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",
|
|
107401
|
+
children: t2("pptx.broadcast.startBroadcast")
|
|
107402
|
+
}
|
|
107403
|
+
)
|
|
107404
|
+
] })
|
|
107405
|
+
]
|
|
107406
|
+
}
|
|
107407
|
+
) })
|
|
107408
|
+
] });
|
|
107409
|
+
}
|
|
107410
|
+
function StartBroadcastForm({
|
|
107411
|
+
roomId,
|
|
107412
|
+
userName,
|
|
107413
|
+
serverUrl,
|
|
107414
|
+
onRoomIdChange,
|
|
107415
|
+
onUserNameChange,
|
|
107416
|
+
onServerUrlChange
|
|
107417
|
+
}) {
|
|
107418
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
107419
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
107420
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[13px] text-muted-foreground leading-relaxed", children: t2("pptx.broadcast.description") }),
|
|
107421
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
107422
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107423
|
+
"label",
|
|
107424
|
+
{
|
|
107425
|
+
htmlFor: "broadcast-room-id",
|
|
107426
|
+
className: "block text-[12px] font-medium text-foreground",
|
|
107427
|
+
children: t2("pptx.broadcast.sessionName")
|
|
107428
|
+
}
|
|
107429
|
+
),
|
|
107430
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107431
|
+
"input",
|
|
107432
|
+
{
|
|
107433
|
+
id: "broadcast-room-id",
|
|
107434
|
+
type: "text",
|
|
107435
|
+
value: roomId,
|
|
107436
|
+
onChange: (e2) => onRoomIdChange(e2.target.value),
|
|
107437
|
+
placeholder: "broadcast-abc123",
|
|
107438
|
+
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"
|
|
107439
|
+
}
|
|
107440
|
+
)
|
|
107441
|
+
] }),
|
|
107442
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
107443
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107444
|
+
"label",
|
|
107445
|
+
{
|
|
107446
|
+
htmlFor: "broadcast-user-name",
|
|
107447
|
+
className: "block text-[12px] font-medium text-foreground",
|
|
107448
|
+
children: t2("pptx.broadcast.displayName")
|
|
107449
|
+
}
|
|
107450
|
+
),
|
|
107451
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107452
|
+
"input",
|
|
107453
|
+
{
|
|
107454
|
+
id: "broadcast-user-name",
|
|
107455
|
+
type: "text",
|
|
107456
|
+
value: userName,
|
|
107457
|
+
onChange: (e2) => onUserNameChange(e2.target.value),
|
|
107458
|
+
placeholder: "Presenter",
|
|
107459
|
+
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"
|
|
107460
|
+
}
|
|
107461
|
+
)
|
|
107462
|
+
] }),
|
|
107463
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
107464
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107465
|
+
"label",
|
|
107466
|
+
{
|
|
107467
|
+
htmlFor: "broadcast-server-url",
|
|
107468
|
+
className: "block text-[12px] font-medium text-foreground",
|
|
107469
|
+
children: t2("pptx.broadcast.serverLabel")
|
|
107470
|
+
}
|
|
107471
|
+
),
|
|
107472
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107473
|
+
"input",
|
|
107474
|
+
{
|
|
107475
|
+
id: "broadcast-server-url",
|
|
107476
|
+
type: "text",
|
|
107477
|
+
value: serverUrl,
|
|
107478
|
+
onChange: (e2) => onServerUrlChange(e2.target.value),
|
|
107479
|
+
placeholder: "ws://localhost:1234",
|
|
107480
|
+
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"
|
|
107481
|
+
}
|
|
107482
|
+
)
|
|
107483
|
+
] }),
|
|
107484
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-muted-foreground/70 leading-relaxed", children: t2("pptx.broadcast.hint") })
|
|
107485
|
+
] });
|
|
107486
|
+
}
|
|
107487
|
+
function ActiveBroadcastView({
|
|
107488
|
+
collab,
|
|
107489
|
+
broadcastUrl,
|
|
107490
|
+
copied,
|
|
107491
|
+
onCopyUrl,
|
|
107492
|
+
onStopBroadcast
|
|
107493
|
+
}) {
|
|
107494
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
107495
|
+
const statusColor = collab.status === "connected" ? "text-green-400" : collab.status === "connecting" ? "text-yellow-400" : "text-red-400";
|
|
107496
|
+
const statusIcon = collab.status === "connected" || collab.status === "connecting" ? /* @__PURE__ */ jsxRuntime.jsx(lu.LuWifi, { className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lu.LuWifiOff, { className: "w-4 h-4" });
|
|
107497
|
+
const viewerCount = collab.remoteUsers.filter((u2) => u2.role === "viewer").length;
|
|
107498
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
107499
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
107500
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: statusColor, children: statusIcon }),
|
|
107501
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[13px] font-medium text-foreground capitalize", children: collab.status }),
|
|
107502
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[12px] text-muted-foreground ml-auto flex items-center gap-1", children: [
|
|
107503
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuUsers, { className: "w-3.5 h-3.5" }),
|
|
107504
|
+
t2("pptx.broadcast.viewerCount", { count: viewerCount })
|
|
107505
|
+
] })
|
|
107506
|
+
] }),
|
|
107507
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
107508
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-[12px] font-medium text-foreground", children: t2("pptx.broadcast.viewerLink") }),
|
|
107509
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
107510
|
+
/* @__PURE__ */ jsxRuntime.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 }),
|
|
107094
107511
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107095
107512
|
"button",
|
|
107096
107513
|
{
|
|
107097
107514
|
type: "button",
|
|
107098
|
-
onClick:
|
|
107099
|
-
className: "
|
|
107100
|
-
|
|
107101
|
-
children:
|
|
107515
|
+
onClick: onCopyUrl,
|
|
107516
|
+
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",
|
|
107517
|
+
title: t2("pptx.broadcast.copyLink"),
|
|
107518
|
+
children: copied ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
107519
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCheck, { className: "w-3.5 h-3.5 text-green-400" }),
|
|
107520
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: t2("pptx.share.copied") })
|
|
107521
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
107522
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCopy, { className: "w-3.5 h-3.5" }),
|
|
107523
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: t2("pptx.share.copyUrl") })
|
|
107524
|
+
] })
|
|
107102
107525
|
}
|
|
107103
107526
|
)
|
|
107104
107527
|
] }),
|
|
107105
|
-
/* @__PURE__ */ jsxRuntime.jsx("
|
|
107106
|
-
|
|
107528
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-muted-foreground", children: t2("pptx.broadcast.shareHint") })
|
|
107529
|
+
] }),
|
|
107530
|
+
collab.remoteUsers.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
107531
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-[12px] font-medium text-foreground", children: t2("pptx.broadcast.viewers") }),
|
|
107532
|
+
/* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3 py-2", children: [
|
|
107107
107533
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107108
|
-
"
|
|
107534
|
+
"div",
|
|
107109
107535
|
{
|
|
107110
|
-
|
|
107111
|
-
|
|
107112
|
-
|
|
107113
|
-
children: t2("common.close")
|
|
107536
|
+
className: "w-5 h-5 rounded-full flex items-center justify-center text-[8px] font-semibold text-white shrink-0",
|
|
107537
|
+
style: { backgroundColor: user.userColor },
|
|
107538
|
+
children: user.userName.slice(0, 2).toUpperCase()
|
|
107114
107539
|
}
|
|
107115
107540
|
),
|
|
107116
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107117
|
-
|
|
107118
|
-
|
|
107119
|
-
|
|
107120
|
-
|
|
107121
|
-
|
|
107122
|
-
|
|
107123
|
-
|
|
107124
|
-
|
|
107125
|
-
|
|
107126
|
-
|
|
107541
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[12px] text-foreground truncate", children: user.userName }),
|
|
107542
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground ml-auto", children: [
|
|
107543
|
+
"Slide ",
|
|
107544
|
+
user.activeSlideIndex + 1
|
|
107545
|
+
] })
|
|
107546
|
+
] }, user.clientId)) })
|
|
107547
|
+
] }),
|
|
107548
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107549
|
+
"button",
|
|
107550
|
+
{
|
|
107551
|
+
type: "button",
|
|
107552
|
+
onClick: onStopBroadcast,
|
|
107553
|
+
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",
|
|
107554
|
+
children: t2("pptx.broadcast.stopBroadcast")
|
|
107555
|
+
}
|
|
107556
|
+
)
|
|
107127
107557
|
] });
|
|
107128
107558
|
}
|
|
107129
107559
|
function getInitials2(name) {
|
|
@@ -108707,7 +109137,8 @@ function useDrawingOverlay({
|
|
|
108707
109137
|
drawingWidth,
|
|
108708
109138
|
isDrawingRef,
|
|
108709
109139
|
onAddInkElement,
|
|
108710
|
-
onAddFreeformShape
|
|
109140
|
+
onAddFreeformShape,
|
|
109141
|
+
onEraseInkElement
|
|
108711
109142
|
}) {
|
|
108712
109143
|
const isDrawing = activeTool !== "select";
|
|
108713
109144
|
const [currentStrokePoints, setCurrentStrokePoints] = React10.useState(
|
|
@@ -108756,6 +109187,7 @@ function useDrawingOverlay({
|
|
|
108756
109187
|
continue;
|
|
108757
109188
|
}
|
|
108758
109189
|
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) {
|
|
109190
|
+
onEraseInkElement?.(el.id);
|
|
108759
109191
|
break;
|
|
108760
109192
|
}
|
|
108761
109193
|
}
|
|
@@ -108774,7 +109206,7 @@ function useDrawingOverlay({
|
|
|
108774
109206
|
isDrawingRef.current = true;
|
|
108775
109207
|
}
|
|
108776
109208
|
},
|
|
108777
|
-
[activeTool, activeSlide, pointerToCanvasCoords, isDrawingRef]
|
|
109209
|
+
[activeTool, activeSlide, pointerToCanvasCoords, isDrawingRef, onEraseInkElement]
|
|
108778
109210
|
);
|
|
108779
109211
|
const handleDrawPointerMove = React10.useCallback(
|
|
108780
109212
|
(e2) => {
|
|
@@ -108844,6 +109276,9 @@ function useDrawingOverlay({
|
|
|
108844
109276
|
i3 === 0 ? { type: "moveTo", pt: scaledPt } : { type: "lineTo", pt: scaledPt }
|
|
108845
109277
|
);
|
|
108846
109278
|
}
|
|
109279
|
+
if (segments.length > 2) {
|
|
109280
|
+
segments.push({ type: "close" });
|
|
109281
|
+
}
|
|
108847
109282
|
const freeformShape = {
|
|
108848
109283
|
id: `shape-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
108849
109284
|
type: "shape",
|
|
@@ -108853,7 +109288,7 @@ function useDrawingOverlay({
|
|
|
108853
109288
|
height: h2,
|
|
108854
109289
|
shapeType: "custom",
|
|
108855
109290
|
shapeStyle: {
|
|
108856
|
-
fillColor:
|
|
109291
|
+
fillColor: "transparent",
|
|
108857
109292
|
strokeColor: drawingColor,
|
|
108858
109293
|
strokeWidth: drawingWidth
|
|
108859
109294
|
},
|
|
@@ -109003,6 +109438,7 @@ function SlideCanvas({
|
|
|
109003
109438
|
isDrawingRef,
|
|
109004
109439
|
onAddInkElement,
|
|
109005
109440
|
onAddFreeformShape,
|
|
109441
|
+
onEraseInkElement,
|
|
109006
109442
|
onActionClick,
|
|
109007
109443
|
onHyperlinkClick,
|
|
109008
109444
|
comments,
|
|
@@ -109088,7 +109524,8 @@ function SlideCanvas({
|
|
|
109088
109524
|
drawingWidth,
|
|
109089
109525
|
isDrawingRef,
|
|
109090
109526
|
onAddInkElement,
|
|
109091
|
-
onAddFreeformShape
|
|
109527
|
+
onAddFreeformShape,
|
|
109528
|
+
onEraseInkElement
|
|
109092
109529
|
});
|
|
109093
109530
|
const rulerOffset = showRulers ? RULER_THICKNESS : 0;
|
|
109094
109531
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -109584,6 +110021,10 @@ function ViewerToolbarSection(props) {
|
|
|
109584
110021
|
onSetMode,
|
|
109585
110022
|
onToggleSidebar: () => s.setIsSlidesPaneOpen((p3) => !p3),
|
|
109586
110023
|
onToggleInspector: () => s.setIsInspectorPaneOpen((p3) => !p3),
|
|
110024
|
+
onOpenAnimationPanel: () => {
|
|
110025
|
+
s.setIsInspectorPaneOpen(true);
|
|
110026
|
+
s.setSidebarPanelMode("properties");
|
|
110027
|
+
},
|
|
109587
110028
|
onToggleCompactToolbar: () => s.setIsCompactToolbarOpen((p3) => !p3),
|
|
109588
110029
|
onSetToolbarSection: s.setToolbarSection,
|
|
109589
110030
|
onZoomIn: zoom.handleZoomIn,
|
|
@@ -111255,13 +111696,6 @@ function ViewerDialogGroup(props) {
|
|
|
111255
111696
|
slideCount: slides.length
|
|
111256
111697
|
}
|
|
111257
111698
|
),
|
|
111258
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
111259
|
-
BroadcastDialog,
|
|
111260
|
-
{
|
|
111261
|
-
open: dialogs.isBroadcastDialogOpen,
|
|
111262
|
-
onClose: () => dialogs.setIsBroadcastDialogOpen(false)
|
|
111263
|
-
}
|
|
111264
|
-
),
|
|
111265
111699
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
111266
111700
|
PrintDialog,
|
|
111267
111701
|
{
|
|
@@ -111504,6 +111938,7 @@ function ViewerCanvasArea(props) {
|
|
|
111504
111938
|
isDrawingRef: s.isDrawingRef,
|
|
111505
111939
|
onAddInkElement: insertHandlers.handleAddInkElement,
|
|
111506
111940
|
onAddFreeformShape: insertHandlers.handleAddFreeformShape,
|
|
111941
|
+
onEraseInkElement: insertHandlers.handleEraseInkElement,
|
|
111507
111942
|
onActionClick: handleActionClick,
|
|
111508
111943
|
onHyperlinkClick: handleHyperlinkClick,
|
|
111509
111944
|
allSlides: mode === "present" ? slides : void 0,
|
|
@@ -111511,6 +111946,24 @@ function ViewerCanvasArea(props) {
|
|
|
111511
111946
|
sourceSlideIndex: mode === "present" ? activeSlideIndex : void 0,
|
|
111512
111947
|
fieldContext,
|
|
111513
111948
|
tableStyleContext,
|
|
111949
|
+
collaborationOverlay: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
111950
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
111951
|
+
RemoteSelectionOverlay,
|
|
111952
|
+
{
|
|
111953
|
+
elements: effectiveSlide?.elements ?? [],
|
|
111954
|
+
activeSlideIndex
|
|
111955
|
+
}
|
|
111956
|
+
),
|
|
111957
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
111958
|
+
CollaborationCursorOverlay,
|
|
111959
|
+
{
|
|
111960
|
+
activeSlideIndex,
|
|
111961
|
+
canvasWidth: canvasSize.width,
|
|
111962
|
+
canvasHeight: canvasSize.height,
|
|
111963
|
+
selectedElementId: s.selectedElementId
|
|
111964
|
+
}
|
|
111965
|
+
)
|
|
111966
|
+
] }),
|
|
111514
111967
|
comments: activeSlide?.comments,
|
|
111515
111968
|
showCommentMarkers: s.sidebarPanelMode === "comments",
|
|
111516
111969
|
onCommentMarkerClick: () => s.setSidebarPanelMode("comments"),
|
|
@@ -113121,6 +113574,37 @@ function useYjsDocumentSync({
|
|
|
113121
113574
|
};
|
|
113122
113575
|
}, [doc2, isConnected, getDocMap, setSlides]);
|
|
113123
113576
|
}
|
|
113577
|
+
function useBroadcastFollower({
|
|
113578
|
+
collab,
|
|
113579
|
+
activeSlideIndex,
|
|
113580
|
+
setActiveSlideIndex,
|
|
113581
|
+
slideCount
|
|
113582
|
+
}) {
|
|
113583
|
+
const lastBroadcasterSlide = React10.useRef(-1);
|
|
113584
|
+
React10.useEffect(() => {
|
|
113585
|
+
if (!collab) {
|
|
113586
|
+
return;
|
|
113587
|
+
}
|
|
113588
|
+
if (collab.config.role !== "viewer") {
|
|
113589
|
+
return;
|
|
113590
|
+
}
|
|
113591
|
+
const broadcaster = collab.remoteUsers.find((u2) => u2.role === "broadcaster");
|
|
113592
|
+
if (!broadcaster) {
|
|
113593
|
+
return;
|
|
113594
|
+
}
|
|
113595
|
+
const targetSlide = broadcaster.activeSlideIndex;
|
|
113596
|
+
if (targetSlide < 0 || targetSlide >= slideCount) {
|
|
113597
|
+
return;
|
|
113598
|
+
}
|
|
113599
|
+
if (targetSlide === lastBroadcasterSlide.current) {
|
|
113600
|
+
return;
|
|
113601
|
+
}
|
|
113602
|
+
lastBroadcasterSlide.current = targetSlide;
|
|
113603
|
+
if (targetSlide !== activeSlideIndex) {
|
|
113604
|
+
setActiveSlideIndex(targetSlide);
|
|
113605
|
+
}
|
|
113606
|
+
}, [collab, activeSlideIndex, setActiveSlideIndex, slideCount]);
|
|
113607
|
+
}
|
|
113124
113608
|
function computeGridSpacingPx(presentationGridSpacing) {
|
|
113125
113609
|
if (presentationGridSpacing) {
|
|
113126
113610
|
const px2 = Math.round(presentationGridSpacing.cx / EMU_PER_PX);
|
|
@@ -115461,6 +115945,17 @@ function useInsertElements(input) {
|
|
|
115461
115945
|
}
|
|
115462
115946
|
addElement(shape);
|
|
115463
115947
|
};
|
|
115948
|
+
const handleEraseInkElement = (elementId) => {
|
|
115949
|
+
if (!activeSlide) {
|
|
115950
|
+
return;
|
|
115951
|
+
}
|
|
115952
|
+
ops.updateSlides(
|
|
115953
|
+
(prev) => prev.map(
|
|
115954
|
+
(s, i3) => i3 === activeSlideIndex ? { ...s, elements: s.elements.filter((el) => el.id !== elementId) } : s
|
|
115955
|
+
)
|
|
115956
|
+
);
|
|
115957
|
+
history.markDirty();
|
|
115958
|
+
};
|
|
115464
115959
|
return {
|
|
115465
115960
|
handleAddTextBox,
|
|
115466
115961
|
handleAddShape,
|
|
@@ -115468,6 +115963,7 @@ function useInsertElements(input) {
|
|
|
115468
115963
|
...structured,
|
|
115469
115964
|
handleAddInkElement,
|
|
115470
115965
|
handleAddFreeformShape,
|
|
115966
|
+
handleEraseInkElement,
|
|
115471
115967
|
...fileHandlers
|
|
115472
115968
|
};
|
|
115473
115969
|
}
|
|
@@ -116297,7 +116793,8 @@ function useEditorOperations(input) {
|
|
|
116297
116793
|
selectedElementIds,
|
|
116298
116794
|
canvasSize,
|
|
116299
116795
|
dialogs,
|
|
116300
|
-
presentation
|
|
116796
|
+
presentation,
|
|
116797
|
+
userName
|
|
116301
116798
|
} = input;
|
|
116302
116799
|
const ops = useElementOperations({
|
|
116303
116800
|
activeSlide,
|
|
@@ -116331,6 +116828,7 @@ function useEditorOperations(input) {
|
|
|
116331
116828
|
const comments = useComments({
|
|
116332
116829
|
slides,
|
|
116333
116830
|
canEdit,
|
|
116831
|
+
userName,
|
|
116334
116832
|
selectedElementId: state2.selectedElementId,
|
|
116335
116833
|
onUpdateSlides: ops.updateSlides,
|
|
116336
116834
|
onMarkDirty: history.markDirty
|
|
@@ -123104,6 +123602,7 @@ var PowerPointViewer = React10.forwardRef(
|
|
|
123104
123602
|
onDirtyChange,
|
|
123105
123603
|
onActiveSlideChange,
|
|
123106
123604
|
theme,
|
|
123605
|
+
authorName,
|
|
123107
123606
|
collaboration,
|
|
123108
123607
|
onStartCollaboration,
|
|
123109
123608
|
onStopCollaboration,
|
|
@@ -123261,7 +123760,8 @@ var PowerPointViewer = React10.forwardRef(
|
|
|
123261
123760
|
selectedElementIds,
|
|
123262
123761
|
canvasSize,
|
|
123263
123762
|
dialogs,
|
|
123264
|
-
presentation
|
|
123763
|
+
presentation,
|
|
123764
|
+
userName: authorName ?? collaboration?.userName
|
|
123265
123765
|
});
|
|
123266
123766
|
const {
|
|
123267
123767
|
exportHandlers,
|
|
@@ -123464,6 +123964,19 @@ var PowerPointViewer = React10.forwardRef(
|
|
|
123464
123964
|
defaultServerUrl: shareDefaults?.serverUrl
|
|
123465
123965
|
}
|
|
123466
123966
|
),
|
|
123967
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
123968
|
+
BroadcastDialog,
|
|
123969
|
+
{
|
|
123970
|
+
open: dialogs.isBroadcastDialogOpen,
|
|
123971
|
+
onClose: () => dialogs.setIsBroadcastDialogOpen(false),
|
|
123972
|
+
onStartBroadcast: onStartCollaboration,
|
|
123973
|
+
onStopBroadcast: onStopCollaboration,
|
|
123974
|
+
onStartPresenting: () => handleSetMode("present"),
|
|
123975
|
+
defaultRoomId: shareDefaults?.roomId,
|
|
123976
|
+
defaultUserName: shareDefaults?.userName,
|
|
123977
|
+
defaultServerUrl: shareDefaults?.serverUrl
|
|
123978
|
+
}
|
|
123979
|
+
),
|
|
123467
123980
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
123468
123981
|
ViewerOverlays,
|
|
123469
123982
|
{
|
|
@@ -123513,6 +124026,14 @@ var PowerPointViewer = React10.forwardRef(
|
|
|
123513
124026
|
canvasHeight: canvasSize.height,
|
|
123514
124027
|
children: [
|
|
123515
124028
|
/* @__PURE__ */ jsxRuntime.jsx(CollaborationDocumentSync, { slides, setSlides: state2.setSlides }),
|
|
124029
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
124030
|
+
BroadcastFollowerSync,
|
|
124031
|
+
{
|
|
124032
|
+
activeSlideIndex,
|
|
124033
|
+
setActiveSlideIndex: state2.setActiveSlideIndex,
|
|
124034
|
+
slideCount: slides.length
|
|
124035
|
+
}
|
|
124036
|
+
),
|
|
123516
124037
|
viewerContent
|
|
123517
124038
|
]
|
|
123518
124039
|
}
|
|
@@ -123540,6 +124061,20 @@ function CollaborationDocumentSync({
|
|
|
123540
124061
|
});
|
|
123541
124062
|
return null;
|
|
123542
124063
|
}
|
|
124064
|
+
function BroadcastFollowerSync({
|
|
124065
|
+
activeSlideIndex,
|
|
124066
|
+
setActiveSlideIndex,
|
|
124067
|
+
slideCount
|
|
124068
|
+
}) {
|
|
124069
|
+
const collab = useCollaboration();
|
|
124070
|
+
useBroadcastFollower({
|
|
124071
|
+
collab,
|
|
124072
|
+
activeSlideIndex,
|
|
124073
|
+
setActiveSlideIndex,
|
|
124074
|
+
slideCount
|
|
124075
|
+
});
|
|
124076
|
+
return null;
|
|
124077
|
+
}
|
|
123543
124078
|
function colorSchemesMatch(a2, b2) {
|
|
123544
124079
|
if (!a2) {
|
|
123545
124080
|
return false;
|