pptx-react-viewer 1.0.10 → 1.0.11
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/README.md +68 -0
- package/dist/{PowerPointViewer-K2URyPlJ.d.mts → PowerPointViewer-gSKLhZDo.d.mts} +35 -1
- package/dist/{PowerPointViewer-K2URyPlJ.d.ts → PowerPointViewer-gSKLhZDo.d.ts} +35 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2532 -882
- package/dist/index.mjs +2533 -883
- package/dist/pptx-viewer.css +1 -1
- package/dist/viewer/index.d.mts +15 -3
- package/dist/viewer/index.d.ts +15 -3
- package/dist/viewer/index.js +2731 -985
- package/dist/viewer/index.mjs +2732 -987
- package/node_modules/emf-converter/package.json +1 -1
- package/node_modules/mtx-decompressor/package.json +1 -1
- package/node_modules/pptx-viewer-core/dist/{SvgExporter-DqcmwxFu.d.mts → SvgExporter-B4-1_Hjp.d.mts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{SvgExporter-BZJguJbp.d.ts → SvgExporter-CPr1npgo.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/dist/cli/index.d.mts +2 -2
- package/node_modules/pptx-viewer-core/dist/cli/index.d.ts +2 -2
- package/node_modules/pptx-viewer-core/dist/converter/index.d.mts +3 -3
- package/node_modules/pptx-viewer-core/dist/converter/index.d.ts +3 -3
- package/node_modules/pptx-viewer-core/dist/index.d.mts +5 -5
- package/node_modules/pptx-viewer-core/dist/index.d.ts +5 -5
- package/node_modules/pptx-viewer-core/dist/{presentation-Bo7cMMCe.d.mts → presentation-DgkIYhXo.d.mts} +6 -0
- package/node_modules/pptx-viewer-core/dist/{presentation-Bo7cMMCe.d.ts → presentation-DgkIYhXo.d.ts} +6 -0
- package/node_modules/pptx-viewer-core/dist/{text-operations-D0f1jred.d.ts → text-operations-B6U6XxWt.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{text-operations-Bo-WG-Z8.d.mts → text-operations-dYKZp3zE.d.mts} +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 === React95.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 = useState84({
|
|
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
|
+
useEffect68(
|
|
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 React95 = __require("react"), objectIs = "function" === typeof Object.is ? Object.is : is2, useState84 = React95.useState, useEffect68 = React95.useEffect, useLayoutEffect7 = React95.useLayoutEffect, useDebugValue = React95.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 !== React95.useSyncExternalStore ? React95.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 React95 = __require("react"), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is2, useSyncExternalStore3 = shim.useSyncExternalStore, useRef69 = React95.useRef, useEffect68 = React95.useEffect, useMemo42 = React95.useMemo, useDebugValue = React95.useDebugValue;
|
|
43404
43404
|
exports$1.useSyncExternalStoreWithSelector = function(subscribe3, getSnapshot2, getServerSnapshot2, selector, isEqual) {
|
|
43405
|
-
var instRef =
|
|
43405
|
+
var instRef = useRef69(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
|
+
useEffect68(
|
|
43447
43447
|
function() {
|
|
43448
43448
|
inst.hasValue = true;
|
|
43449
43449
|
inst.value = value;
|
|
@@ -69731,6 +69731,7 @@ var UNGROUPED_SECTION_ID = "__ungrouped__";
|
|
|
69731
69731
|
|
|
69732
69732
|
// src/viewer/constants/toolbar.ts
|
|
69733
69733
|
var TOOLBAR_SECTIONS = [
|
|
69734
|
+
{ id: "file", label: "File" },
|
|
69734
69735
|
{ id: "home", label: "Home" },
|
|
69735
69736
|
{ id: "insert", label: "Insert" },
|
|
69736
69737
|
{ id: "text", label: "Text" },
|
|
@@ -69738,8 +69739,11 @@ var TOOLBAR_SECTIONS = [
|
|
|
69738
69739
|
{ id: "arrange", label: "Arrange" },
|
|
69739
69740
|
{ id: "design", label: "Design" },
|
|
69740
69741
|
{ id: "transitions", label: "Transitions" },
|
|
69742
|
+
{ id: "animations", label: "Animations" },
|
|
69743
|
+
{ id: "slideShow", label: "Slide Show" },
|
|
69741
69744
|
{ id: "review", label: "Review" },
|
|
69742
|
-
{ id: "view", label: "View" }
|
|
69745
|
+
{ id: "view", label: "View" },
|
|
69746
|
+
{ id: "help", label: "Help" }
|
|
69743
69747
|
];
|
|
69744
69748
|
var SHORTCUT_REFERENCE_ITEMS = [
|
|
69745
69749
|
{ action: "Undo", shortcut: "Ctrl/Cmd+Z" },
|
|
@@ -85777,6 +85781,7 @@ function AccessibilityPanel({
|
|
|
85777
85781
|
reducedMotion,
|
|
85778
85782
|
onToggleReducedMotion
|
|
85779
85783
|
}) {
|
|
85784
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
85780
85785
|
if (!isOpen) {
|
|
85781
85786
|
return null;
|
|
85782
85787
|
}
|
|
@@ -85784,31 +85789,27 @@ function AccessibilityPanel({
|
|
|
85784
85789
|
"div",
|
|
85785
85790
|
{
|
|
85786
85791
|
role: "dialog",
|
|
85787
|
-
"aria-label": "
|
|
85792
|
+
"aria-label": t2("pptx.accessibility.title"),
|
|
85788
85793
|
className: "absolute top-14 right-3 z-40 w-[min(28rem,calc(100%-1.5rem))] rounded border border-border bg-popover shadow-2xl",
|
|
85789
85794
|
children: [
|
|
85790
85795
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-b border-border px-3 py-2", children: [
|
|
85791
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs uppercase tracking-wide text-foreground", children: "
|
|
85796
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs uppercase tracking-wide text-foreground", children: t2("pptx.accessibility.title") }),
|
|
85792
85797
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
85793
|
-
/* @__PURE__ */ jsxRuntime.
|
|
85794
|
-
issues.length,
|
|
85795
|
-
" issue",
|
|
85796
|
-
issues.length !== 1 ? "s" : ""
|
|
85797
|
-
] }),
|
|
85798
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: t2("pptx.accessibility.issueCount", { count: issues.length }) }),
|
|
85798
85799
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
85799
85800
|
"button",
|
|
85800
85801
|
{
|
|
85801
85802
|
type: "button",
|
|
85802
85803
|
onClick: onClose,
|
|
85803
|
-
"aria-label": "
|
|
85804
|
+
"aria-label": t2("pptx.accessibility.closePanel"),
|
|
85804
85805
|
className: "rounded px-2 py-1 text-[11px] text-foreground hover:bg-muted hover:text-foreground",
|
|
85805
|
-
children: "
|
|
85806
|
+
children: t2("pptx.accessibility.close")
|
|
85806
85807
|
}
|
|
85807
85808
|
)
|
|
85808
85809
|
] })
|
|
85809
85810
|
] }),
|
|
85810
85811
|
onToggleReducedMotion !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-b border-border px-3 py-2", children: [
|
|
85811
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "reduced-motion-toggle", className: "text-xs text-foreground", children: "
|
|
85812
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "reduced-motion-toggle", className: "text-xs text-foreground", children: t2("pptx.accessibility.reduceMotion") }),
|
|
85812
85813
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
85813
85814
|
"button",
|
|
85814
85815
|
{
|
|
@@ -85837,9 +85838,9 @@ function AccessibilityPanel({
|
|
|
85837
85838
|
"div",
|
|
85838
85839
|
{
|
|
85839
85840
|
role: "list",
|
|
85840
|
-
"aria-label": "
|
|
85841
|
+
"aria-label": t2("pptx.accessibility.issuesList"),
|
|
85841
85842
|
className: "max-h-72 overflow-y-auto p-2 space-y-1",
|
|
85842
|
-
children: issues.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { role: "listitem", className: "text-center text-xs text-muted-foreground py-4", children: "
|
|
85843
|
+
children: issues.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { role: "listitem", className: "text-center text-xs text-muted-foreground py-4", children: t2("pptx.accessibility.noIssues") }) : issues.map((issue, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
85843
85844
|
"div",
|
|
85844
85845
|
{
|
|
85845
85846
|
role: "listitem",
|
|
@@ -85851,7 +85852,7 @@ function AccessibilityPanel({
|
|
|
85851
85852
|
children: [
|
|
85852
85853
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 mt-0.5", "aria-hidden": "true", children: issue.severity === "error" ? "\u25CF" : issue.severity === "warning" ? "\u25B2" : "\u2139" }),
|
|
85853
85854
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
85854
|
-
issue.severity === "error" ? "
|
|
85855
|
+
issue.severity === "error" ? t2("pptx.accessibility.error") : issue.severity === "warning" ? t2("pptx.accessibility.warning") : t2("pptx.accessibility.info"),
|
|
85855
85856
|
issue.message
|
|
85856
85857
|
] })
|
|
85857
85858
|
]
|
|
@@ -85903,22 +85904,32 @@ function ExportProgressModal({
|
|
|
85903
85904
|
) })
|
|
85904
85905
|
] }) });
|
|
85905
85906
|
}
|
|
85906
|
-
function formatAutosaveAge(timestamp) {
|
|
85907
|
+
function formatAutosaveAge(timestamp, t2) {
|
|
85907
85908
|
const diff = Date.now() - timestamp;
|
|
85908
85909
|
const minutes = Math.floor(diff / 6e4);
|
|
85909
85910
|
if (minutes < 1) {
|
|
85910
|
-
return "
|
|
85911
|
+
return t2("pptx.autosave.justNow");
|
|
85911
85912
|
}
|
|
85912
85913
|
if (minutes === 1) {
|
|
85913
|
-
return "
|
|
85914
|
+
return t2("pptx.autosave.oneMinAgo");
|
|
85914
85915
|
}
|
|
85915
|
-
return
|
|
85916
|
+
return t2("pptx.autosave.minutesAgo", { count: minutes });
|
|
85916
85917
|
}
|
|
85917
85918
|
function StatusBar({
|
|
85918
85919
|
slideCount,
|
|
85919
85920
|
activeSlideIndex,
|
|
85920
85921
|
isDirty,
|
|
85921
|
-
autosaveStatus
|
|
85922
|
+
autosaveStatus,
|
|
85923
|
+
scale,
|
|
85924
|
+
onZoomIn,
|
|
85925
|
+
onZoomOut,
|
|
85926
|
+
onZoomToFit,
|
|
85927
|
+
isNotesExpanded,
|
|
85928
|
+
onToggleNotes,
|
|
85929
|
+
mode,
|
|
85930
|
+
onSetMode,
|
|
85931
|
+
onToggleSlideSorter,
|
|
85932
|
+
collaborationSlot
|
|
85922
85933
|
}) {
|
|
85923
85934
|
const { t: t2 } = reactI18next.useTranslation();
|
|
85924
85935
|
let statusText;
|
|
@@ -85926,7 +85937,7 @@ function StatusBar({
|
|
|
85926
85937
|
statusText = t2("pptx.autosave.saving");
|
|
85927
85938
|
} else if (autosaveStatus?.state === "saved") {
|
|
85928
85939
|
statusText = t2("pptx.autosave.saved", {
|
|
85929
|
-
time: formatAutosaveAge(autosaveStatus.timestamp)
|
|
85940
|
+
time: formatAutosaveAge(autosaveStatus.timestamp, t2)
|
|
85930
85941
|
});
|
|
85931
85942
|
} else if (autosaveStatus?.state === "error") {
|
|
85932
85943
|
statusText = t2("pptx.autosave.error");
|
|
@@ -85935,15 +85946,124 @@ function StatusBar({
|
|
|
85935
85946
|
} else {
|
|
85936
85947
|
statusText = t2("pptx.statusBar.allSaved");
|
|
85937
85948
|
}
|
|
85938
|
-
|
|
85939
|
-
|
|
85949
|
+
const vb = "p-1 rounded-sm transition-colors hover:bg-accent/60 text-muted-foreground active:scale-95 active:opacity-80";
|
|
85950
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full px-2 py-0.5 border-t border-border bg-secondary/50 text-[10px] text-muted-foreground flex items-center gap-1", children: [
|
|
85951
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", children: slideCount > 0 ? t2("pptx.statusBar.slideOf", {
|
|
85952
|
+
current: Math.min(activeSlideIndex + 1, slideCount),
|
|
85953
|
+
total: slideCount
|
|
85954
|
+
}) : t2("pptx.statusBar.noSlides") }),
|
|
85955
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-3 bg-border/40 mx-1 max-md:hidden" }),
|
|
85956
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 max-md:hidden text-[10px]", children: t2("pptx.statusBar.language") }),
|
|
85957
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-3 bg-border/60 mx-1 max-md:hidden" }),
|
|
85940
85958
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
85941
85959
|
"span",
|
|
85942
85960
|
{
|
|
85943
|
-
className:
|
|
85961
|
+
className: cn(
|
|
85962
|
+
"shrink-0 max-md:hidden",
|
|
85963
|
+
autosaveStatus?.state === "error" ? "text-red-400" : autosaveStatus?.state === "saving" ? "text-yellow-400" : ""
|
|
85964
|
+
),
|
|
85944
85965
|
children: statusText
|
|
85945
85966
|
}
|
|
85946
|
-
)
|
|
85967
|
+
),
|
|
85968
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
|
|
85969
|
+
onToggleNotes && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
85970
|
+
"button",
|
|
85971
|
+
{
|
|
85972
|
+
type: "button",
|
|
85973
|
+
onClick: onToggleNotes,
|
|
85974
|
+
className: cn(
|
|
85975
|
+
vb,
|
|
85976
|
+
"flex items-center gap-1 text-[10px]",
|
|
85977
|
+
isNotesExpanded && "text-primary"
|
|
85978
|
+
),
|
|
85979
|
+
title: t2("pptx.statusBar.toggleNotes"),
|
|
85980
|
+
"aria-label": t2("pptx.statusBar.toggleNotes"),
|
|
85981
|
+
children: [
|
|
85982
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuStickyNote, { className: "w-3 h-3" }),
|
|
85983
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-md:hidden", children: t2("pptx.notes.title") })
|
|
85984
|
+
]
|
|
85985
|
+
}
|
|
85986
|
+
),
|
|
85987
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-3 bg-border/60 mx-0.5" }),
|
|
85988
|
+
onSetMode && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
85989
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
85990
|
+
"button",
|
|
85991
|
+
{
|
|
85992
|
+
type: "button",
|
|
85993
|
+
onClick: () => onSetMode("edit"),
|
|
85994
|
+
className: cn(vb, mode === "edit" && "text-primary"),
|
|
85995
|
+
title: t2("pptx.statusBar.normalView"),
|
|
85996
|
+
"aria-label": t2("pptx.statusBar.normalView"),
|
|
85997
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuMonitor, { className: "w-3.5 h-3.5" })
|
|
85998
|
+
}
|
|
85999
|
+
),
|
|
86000
|
+
onToggleSlideSorter && /* @__PURE__ */ jsxRuntime.jsx(
|
|
86001
|
+
"button",
|
|
86002
|
+
{
|
|
86003
|
+
type: "button",
|
|
86004
|
+
onClick: onToggleSlideSorter,
|
|
86005
|
+
className: vb,
|
|
86006
|
+
title: t2("pptx.statusBar.slideSorter"),
|
|
86007
|
+
"aria-label": t2("pptx.statusBar.slideSorter"),
|
|
86008
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuColumns2, { className: "w-3.5 h-3.5" })
|
|
86009
|
+
}
|
|
86010
|
+
),
|
|
86011
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
86012
|
+
"button",
|
|
86013
|
+
{
|
|
86014
|
+
type: "button",
|
|
86015
|
+
onClick: () => onSetMode("present"),
|
|
86016
|
+
className: cn(vb, mode === "present" && "text-primary"),
|
|
86017
|
+
title: t2("pptx.statusBar.slideShow"),
|
|
86018
|
+
"aria-label": t2("pptx.statusBar.slideShow"),
|
|
86019
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPresentation, { className: "w-3.5 h-3.5" })
|
|
86020
|
+
}
|
|
86021
|
+
)
|
|
86022
|
+
] }),
|
|
86023
|
+
collaborationSlot && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
86024
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-3 bg-border/40 mx-0.5" }),
|
|
86025
|
+
collaborationSlot
|
|
86026
|
+
] }),
|
|
86027
|
+
scale !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
86028
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-3 bg-border/60 mx-0.5" }),
|
|
86029
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
86030
|
+
onZoomOut && /* @__PURE__ */ jsxRuntime.jsx(
|
|
86031
|
+
"button",
|
|
86032
|
+
{
|
|
86033
|
+
type: "button",
|
|
86034
|
+
onClick: onZoomOut,
|
|
86035
|
+
className: vb,
|
|
86036
|
+
title: t2("pptx.statusBar.zoomOut"),
|
|
86037
|
+
"aria-label": t2("pptx.statusBar.zoomOut"),
|
|
86038
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuMinus, { className: "w-3 h-3" })
|
|
86039
|
+
}
|
|
86040
|
+
),
|
|
86041
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
86042
|
+
"button",
|
|
86043
|
+
{
|
|
86044
|
+
type: "button",
|
|
86045
|
+
onClick: onZoomToFit,
|
|
86046
|
+
className: "px-1.5 py-0.5 rounded-sm hover:bg-accent/60 text-[10px] text-muted-foreground tabular-nums min-w-[3rem] text-center transition-colors",
|
|
86047
|
+
title: t2("pptx.statusBar.zoomToFit"),
|
|
86048
|
+
children: [
|
|
86049
|
+
Math.round((scale ?? 1) * 100),
|
|
86050
|
+
"%"
|
|
86051
|
+
]
|
|
86052
|
+
}
|
|
86053
|
+
),
|
|
86054
|
+
onZoomIn && /* @__PURE__ */ jsxRuntime.jsx(
|
|
86055
|
+
"button",
|
|
86056
|
+
{
|
|
86057
|
+
type: "button",
|
|
86058
|
+
onClick: onZoomIn,
|
|
86059
|
+
className: vb,
|
|
86060
|
+
title: t2("pptx.statusBar.zoomIn"),
|
|
86061
|
+
"aria-label": t2("pptx.statusBar.zoomIn"),
|
|
86062
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPlus, { className: "w-3 h-3" })
|
|
86063
|
+
}
|
|
86064
|
+
)
|
|
86065
|
+
] })
|
|
86066
|
+
] })
|
|
85947
86067
|
] });
|
|
85948
86068
|
}
|
|
85949
86069
|
function ResizeHandle({
|
|
@@ -90759,6 +90879,7 @@ function FindReplacePanel({
|
|
|
90759
90879
|
onReplaceAll,
|
|
90760
90880
|
onClose
|
|
90761
90881
|
}) {
|
|
90882
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
90762
90883
|
const searchInputRef = React10.useRef(null);
|
|
90763
90884
|
React10.useEffect(() => {
|
|
90764
90885
|
searchInputRef.current?.focus();
|
|
@@ -90791,12 +90912,12 @@ function FindReplacePanel({
|
|
|
90791
90912
|
[onClose, onReplace]
|
|
90792
90913
|
);
|
|
90793
90914
|
const hasResults = findResults.length > 0;
|
|
90794
|
-
const matchCountLabel = hasResults ?
|
|
90915
|
+
const matchCountLabel = hasResults ? t2("pptx.findReplace.matchCount", { current: findResultIndex + 1, total: findResults.length }) : findQuery.length > 0 ? t2("pptx.findReplace.noMatches") : "";
|
|
90795
90916
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-2 right-2 z-40 bg-popover border border-border rounded-lg shadow-lg p-3 text-xs text-foreground w-80 backdrop-blur", children: [
|
|
90796
90917
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
|
|
90797
90918
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-sm inline-flex items-center gap-1.5", children: [
|
|
90798
90919
|
/* @__PURE__ */ jsxRuntime.jsx(lu.LuSearch, { className: ic }),
|
|
90799
|
-
"
|
|
90920
|
+
t2("pptx.findReplace.title")
|
|
90800
90921
|
] }),
|
|
90801
90922
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
90802
90923
|
"button",
|
|
@@ -90804,8 +90925,8 @@ function FindReplacePanel({
|
|
|
90804
90925
|
type: "button",
|
|
90805
90926
|
className: btnGhost,
|
|
90806
90927
|
onClick: onClose,
|
|
90807
|
-
title: "
|
|
90808
|
-
"aria-label": "
|
|
90928
|
+
title: t2("pptx.findReplace.closeEscape"),
|
|
90929
|
+
"aria-label": t2("pptx.findReplace.closeAriaLabel"),
|
|
90809
90930
|
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuX, { className: ic })
|
|
90810
90931
|
}
|
|
90811
90932
|
)
|
|
@@ -90820,9 +90941,9 @@ function FindReplacePanel({
|
|
|
90820
90941
|
value: findQuery,
|
|
90821
90942
|
onChange: (e2) => onSetFindQuery(e2.target.value),
|
|
90822
90943
|
onKeyDown: handleSearchKeyDown,
|
|
90823
|
-
placeholder: "
|
|
90944
|
+
placeholder: t2("pptx.findReplace.findPlaceholder"),
|
|
90824
90945
|
className: "w-full bg-muted border border-border rounded px-2 py-1 pr-7 text-xs text-foreground placeholder-muted-foreground focus:border-primary focus:outline-none",
|
|
90825
|
-
"aria-label": "
|
|
90946
|
+
"aria-label": t2("pptx.findReplace.searchText")
|
|
90826
90947
|
}
|
|
90827
90948
|
),
|
|
90828
90949
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -90831,8 +90952,8 @@ function FindReplacePanel({
|
|
|
90831
90952
|
type: "button",
|
|
90832
90953
|
className: `absolute right-1 top-1/2 -translate-y-1/2 p-0.5 rounded transition-colors ${findMatchCase ? "bg-primary/80 text-white" : "text-muted-foreground hover:text-foreground hover:bg-accent"}`,
|
|
90833
90954
|
onClick: () => onSetFindMatchCase(!findMatchCase),
|
|
90834
|
-
title: "
|
|
90835
|
-
"aria-label": "
|
|
90955
|
+
title: t2("pptx.findReplace.matchCase"),
|
|
90956
|
+
"aria-label": t2("pptx.findReplace.toggleMatchCase"),
|
|
90836
90957
|
"aria-pressed": findMatchCase,
|
|
90837
90958
|
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuCaseSensitive, { className: ic })
|
|
90838
90959
|
}
|
|
@@ -90845,8 +90966,8 @@ function FindReplacePanel({
|
|
|
90845
90966
|
className: btnGhost,
|
|
90846
90967
|
onClick: () => onNavigateResult(-1),
|
|
90847
90968
|
disabled: !hasResults,
|
|
90848
|
-
title: "
|
|
90849
|
-
"aria-label": "
|
|
90969
|
+
title: t2("pptx.findReplace.previousMatch"),
|
|
90970
|
+
"aria-label": t2("pptx.findReplace.previousMatch"),
|
|
90850
90971
|
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronUp, { className: ic })
|
|
90851
90972
|
}
|
|
90852
90973
|
),
|
|
@@ -90857,8 +90978,8 @@ function FindReplacePanel({
|
|
|
90857
90978
|
className: btnGhost,
|
|
90858
90979
|
onClick: () => onNavigateResult(1),
|
|
90859
90980
|
disabled: !hasResults,
|
|
90860
|
-
title: "
|
|
90861
|
-
"aria-label": "
|
|
90981
|
+
title: t2("pptx.findReplace.nextMatch"),
|
|
90982
|
+
"aria-label": t2("pptx.findReplace.nextMatch"),
|
|
90862
90983
|
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronDown, { className: ic })
|
|
90863
90984
|
}
|
|
90864
90985
|
)
|
|
@@ -90873,9 +90994,9 @@ function FindReplacePanel({
|
|
|
90873
90994
|
value: replaceQuery,
|
|
90874
90995
|
onChange: (e2) => onSetReplaceQuery(e2.target.value),
|
|
90875
90996
|
onKeyDown: handleReplaceKeyDown,
|
|
90876
|
-
placeholder: "
|
|
90997
|
+
placeholder: t2("pptx.findReplace.replacePlaceholder"),
|
|
90877
90998
|
className: "w-full bg-muted border border-border rounded pl-7 pr-2 py-1 text-xs text-foreground placeholder-muted-foreground focus:border-primary focus:outline-none",
|
|
90878
|
-
"aria-label": "
|
|
90999
|
+
"aria-label": t2("pptx.findReplace.replacementText")
|
|
90879
91000
|
}
|
|
90880
91001
|
)
|
|
90881
91002
|
] }) }),
|
|
@@ -90887,8 +91008,8 @@ function FindReplacePanel({
|
|
|
90887
91008
|
className: btnAction,
|
|
90888
91009
|
onClick: onReplace,
|
|
90889
91010
|
disabled: !hasResults,
|
|
90890
|
-
title: "
|
|
90891
|
-
children: "
|
|
91011
|
+
title: t2("pptx.findReplace.replaceCurrent"),
|
|
91012
|
+
children: t2("pptx.findReplace.replace")
|
|
90892
91013
|
}
|
|
90893
91014
|
),
|
|
90894
91015
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -90898,8 +91019,8 @@ function FindReplacePanel({
|
|
|
90898
91019
|
className: btnAction,
|
|
90899
91020
|
onClick: onReplaceAll,
|
|
90900
91021
|
disabled: !hasResults,
|
|
90901
|
-
title: "
|
|
90902
|
-
children: "
|
|
91022
|
+
title: t2("pptx.findReplace.replaceAllMatches"),
|
|
91023
|
+
children: t2("pptx.findReplace.replaceAll")
|
|
90903
91024
|
}
|
|
90904
91025
|
)
|
|
90905
91026
|
] })
|
|
@@ -91308,8 +91429,8 @@ function SlideItemInner({
|
|
|
91308
91429
|
{
|
|
91309
91430
|
ref: slideRef,
|
|
91310
91431
|
className: cn(
|
|
91311
|
-
"group relative cursor-pointer
|
|
91312
|
-
isActive
|
|
91432
|
+
"group relative flex items-center gap-1 cursor-pointer py-0.5 px-1 transition-all",
|
|
91433
|
+
isActive && "bg-accent/40 before:absolute before:left-0 before:top-1 before:bottom-1 before:w-[3px] before:bg-primary before:rounded-r",
|
|
91313
91434
|
isHidden && "opacity-50"
|
|
91314
91435
|
),
|
|
91315
91436
|
draggable: canEdit,
|
|
@@ -91319,21 +91440,35 @@ function SlideItemInner({
|
|
|
91319
91440
|
onDragOver,
|
|
91320
91441
|
onDrop: (e2) => onDrop(e2, slideIndex),
|
|
91321
91442
|
children: [
|
|
91322
|
-
|
|
91323
|
-
|
|
91324
|
-
|
|
91325
|
-
|
|
91326
|
-
|
|
91327
|
-
|
|
91328
|
-
|
|
91329
|
-
|
|
91330
|
-
|
|
91331
|
-
|
|
91332
|
-
|
|
91333
|
-
|
|
91334
|
-
|
|
91335
|
-
|
|
91336
|
-
|
|
91443
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
91444
|
+
"span",
|
|
91445
|
+
{
|
|
91446
|
+
className: cn(
|
|
91447
|
+
"text-[10px] tabular-nums w-5 text-right shrink-0 select-none",
|
|
91448
|
+
isActive ? "text-primary font-medium" : "text-muted-foreground"
|
|
91449
|
+
),
|
|
91450
|
+
children: slideIndex + 1
|
|
91451
|
+
}
|
|
91452
|
+
),
|
|
91453
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
91454
|
+
"div",
|
|
91455
|
+
{
|
|
91456
|
+
className: cn(
|
|
91457
|
+
"relative flex-1 overflow-hidden border transition-colors bg-white",
|
|
91458
|
+
isActive ? "border-primary/60" : "border-transparent group-hover:border-border/40"
|
|
91459
|
+
),
|
|
91460
|
+
children: [
|
|
91461
|
+
isHidden && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 pointer-events-none z-10 bg-[repeating-linear-gradient(135deg,transparent,transparent_4px,rgba(255,255,255,0.04)_4px,rgba(255,255,255,0.04)_8px)]" }),
|
|
91462
|
+
/* @__PURE__ */ jsxRuntime.jsx(LazyThumbnail, { slide, canvasSize, previewHeight }),
|
|
91463
|
+
(slide.comments?.length ?? 0) > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-0.5 right-0.5 flex items-center gap-0.5 rounded bg-amber-500/90 px-1 py-0.5 text-[8px] font-medium text-white leading-none z-10", children: [
|
|
91464
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuMessageSquare, { className: "w-2 h-2" }),
|
|
91465
|
+
slide.comments?.length
|
|
91466
|
+
] }),
|
|
91467
|
+
isHidden && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0.5 right-0.5 z-10", children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuEyeOff, { className: "w-3 h-3 text-muted-foreground" }) }),
|
|
91468
|
+
rehearsalTimings && typeof rehearsalTimings[slideIndex] === "number" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0.5 left-0.5 z-10", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[8px] font-mono text-amber-400/80 tabular-nums bg-black/50 px-0.5 rounded", children: formatTimingMs(rehearsalTimings[slideIndex]) }) })
|
|
91469
|
+
]
|
|
91470
|
+
}
|
|
91471
|
+
)
|
|
91337
91472
|
]
|
|
91338
91473
|
}
|
|
91339
91474
|
);
|
|
@@ -91454,7 +91589,7 @@ function SlidesPaneSidebar({
|
|
|
91454
91589
|
onSlideContextMenu,
|
|
91455
91590
|
onMoveSlide,
|
|
91456
91591
|
onAddSlide,
|
|
91457
|
-
onCollapse,
|
|
91592
|
+
onCollapse: _onCollapse,
|
|
91458
91593
|
onAddSection,
|
|
91459
91594
|
onRenameSection,
|
|
91460
91595
|
onDeleteSection,
|
|
@@ -91659,50 +91794,23 @@ function SlidesPaneSidebar({
|
|
|
91659
91794
|
{
|
|
91660
91795
|
role: "navigation",
|
|
91661
91796
|
"aria-label": "Slides",
|
|
91662
|
-
className: "flex h-full flex-col border-r border-border bg-
|
|
91797
|
+
className: "flex h-full flex-col border-r border-border bg-secondary/30",
|
|
91663
91798
|
style: panelWidth ? { width: panelWidth, flexShrink: 0 } : void 0,
|
|
91664
91799
|
children: [
|
|
91665
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-3 py-2", children: [
|
|
91666
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs uppercase tracking-wide text-muted-foreground", children: t2("pptx.sections.slides") }),
|
|
91667
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
91668
|
-
"button",
|
|
91669
|
-
{
|
|
91670
|
-
type: "button",
|
|
91671
|
-
className: "rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
91672
|
-
title: t2("pptx.sections.collapsePane"),
|
|
91673
|
-
onClick: onCollapse,
|
|
91674
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPanelLeftClose, { className: "h-3.5 w-3.5" })
|
|
91675
|
-
}
|
|
91676
|
-
)
|
|
91677
|
-
] }),
|
|
91678
91800
|
shouldVirtualize ? renderVirtualized() : renderNonVirtualized(),
|
|
91679
|
-
/* @__PURE__ */ jsxRuntime.
|
|
91680
|
-
|
|
91681
|
-
|
|
91682
|
-
|
|
91683
|
-
|
|
91684
|
-
|
|
91685
|
-
|
|
91686
|
-
|
|
91687
|
-
|
|
91688
|
-
|
|
91689
|
-
|
|
91690
|
-
|
|
91691
|
-
|
|
91692
|
-
),
|
|
91693
|
-
canEdit && onAddSection && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
91694
|
-
"button",
|
|
91695
|
-
{
|
|
91696
|
-
type: "button",
|
|
91697
|
-
className: "flex w-full items-center justify-center gap-1 rounded bg-muted/50 px-2 py-1 text-[11px] text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
91698
|
-
onClick: () => onAddSection(t2("pptx.sections.defaultName"), activeSlideIndex),
|
|
91699
|
-
children: [
|
|
91700
|
-
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPlus, { className: "h-3 w-3" }),
|
|
91701
|
-
t2("pptx.sections.addSection")
|
|
91702
|
-
]
|
|
91703
|
-
}
|
|
91704
|
-
)
|
|
91705
|
-
] }),
|
|
91801
|
+
canEdit && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border/60 px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
91802
|
+
"button",
|
|
91803
|
+
{
|
|
91804
|
+
type: "button",
|
|
91805
|
+
className: "flex w-full items-center justify-center gap-1 rounded-sm px-2 py-1 text-[11px] text-muted-foreground hover:bg-accent hover:text-foreground transition-colors disabled:cursor-not-allowed disabled:opacity-40",
|
|
91806
|
+
disabled: !canEdit,
|
|
91807
|
+
onClick: onAddSlide,
|
|
91808
|
+
children: [
|
|
91809
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPlus, { className: "h-3 w-3" }),
|
|
91810
|
+
t2("pptx.sections.addSlide")
|
|
91811
|
+
]
|
|
91812
|
+
}
|
|
91813
|
+
) }),
|
|
91706
91814
|
sectionContextMenu && /* @__PURE__ */ jsxRuntime.jsx(
|
|
91707
91815
|
SectionContextMenu,
|
|
91708
91816
|
{
|
|
@@ -94137,23 +94245,18 @@ var SlideNotesPanel = ({
|
|
|
94137
94245
|
});
|
|
94138
94246
|
const hasNotes = draft.trim().length > 0;
|
|
94139
94247
|
const slideLabel = activeSlide ? t2("pptx.notes.slideN", { n: activeSlide.slideNumber }) : t2("pptx.notes.noSlide");
|
|
94140
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col border-t border-border/60 bg-background
|
|
94248
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col border-t border-border/60 bg-background select-none", children: [
|
|
94141
94249
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
94142
94250
|
"button",
|
|
94143
94251
|
{
|
|
94144
94252
|
type: "button",
|
|
94145
94253
|
onClick: onToggle,
|
|
94146
|
-
className: "flex items-center gap-
|
|
94254
|
+
className: "flex items-center gap-1.5 px-3 py-1 text-[11px] text-muted-foreground hover:text-foreground hover:bg-accent/30 transition-colors w-full text-left shrink-0",
|
|
94147
94255
|
"aria-expanded": isExpanded,
|
|
94148
94256
|
"aria-controls": "slide-notes-content",
|
|
94149
94257
|
children: [
|
|
94150
|
-
|
|
94151
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "
|
|
94152
|
-
!isExpanded && hasNotes && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-1 truncate max-w-[240px] text-muted-foreground font-normal normal-case", children: [
|
|
94153
|
-
"- ",
|
|
94154
|
-
draft.trim().split("\n")[0]
|
|
94155
|
-
] }),
|
|
94156
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto shrink-0", children: isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronDown, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronUp, { className: "w-3.5 h-3.5" }) })
|
|
94258
|
+
"Notes",
|
|
94259
|
+
!isExpanded && hasNotes && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/50 text-[10px]", children: "(has notes)" })
|
|
94157
94260
|
]
|
|
94158
94261
|
}
|
|
94159
94262
|
),
|
|
@@ -96421,15 +96524,14 @@ function SelectionPane({
|
|
|
96421
96524
|
}) })
|
|
96422
96525
|
] });
|
|
96423
96526
|
}
|
|
96424
|
-
var _b = "inline-flex items-center justify-center px-2.5 py-1.5 max-md:min-h-[44px] max-md:min-w-[44px]";
|
|
96527
|
+
var _b = "inline-flex items-center justify-center px-2.5 py-1.5 max-md:min-h-[44px] max-md:min-w-[44px] active:scale-95 active:opacity-80";
|
|
96425
96528
|
var gB = `${_b} border-r border-border hover:bg-accent disabled:opacity-40 disabled:cursor-not-allowed`;
|
|
96426
96529
|
var gL = `${_b} hover:bg-accent disabled:opacity-40 disabled:cursor-not-allowed`;
|
|
96427
96530
|
var grp = "inline-flex items-center rounded bg-muted text-xs overflow-hidden";
|
|
96428
|
-
var pill = "inline-flex items-center gap-1.5 px-2.5 py-1.5 max-md:min-h-[44px] rounded bg-muted hover:bg-accent text-xs transition-colors";
|
|
96429
|
-
var sep = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px
|
|
96531
|
+
var pill = "inline-flex items-center gap-1.5 px-2.5 py-1.5 max-md:min-h-[44px] rounded bg-muted hover:bg-accent text-xs transition-colors active:scale-95 active:opacity-80";
|
|
96532
|
+
var sep = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px self-stretch bg-border/40 mx-1 max-md:hidden" });
|
|
96430
96533
|
var ic2 = "w-4 h-4";
|
|
96431
96534
|
var ics = "w-3.5 h-3.5";
|
|
96432
|
-
var MODES = ["edit", "preview", "present"];
|
|
96433
96535
|
var ALIGN_BTNS = [
|
|
96434
96536
|
{ k: "left", el: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignLeft, { className: ic2 }) },
|
|
96435
96537
|
{ k: "center", el: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignCenter, { className: ic2 }) },
|
|
@@ -96548,7 +96650,128 @@ var ATXT = [
|
|
|
96548
96650
|
{ i: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignRight, { className: ic2 }), t: "Align right" },
|
|
96549
96651
|
{ i: /* @__PURE__ */ jsxRuntime.jsx(lu.LuAlignJustify, { className: ic2 }), t: "Justify" }
|
|
96550
96652
|
];
|
|
96653
|
+
var ANIMATION_PRESETS = [
|
|
96654
|
+
{
|
|
96655
|
+
group: "Entrance",
|
|
96656
|
+
items: [
|
|
96657
|
+
{ value: "appear", label: "Appear" },
|
|
96658
|
+
{ value: "fadeIn", label: "Fade In" },
|
|
96659
|
+
{ value: "flyIn", label: "Fly In" }
|
|
96660
|
+
]
|
|
96661
|
+
},
|
|
96662
|
+
{
|
|
96663
|
+
group: "Emphasis",
|
|
96664
|
+
items: [
|
|
96665
|
+
{ value: "pulse", label: "Pulse" },
|
|
96666
|
+
{ value: "spin", label: "Spin" }
|
|
96667
|
+
]
|
|
96668
|
+
},
|
|
96669
|
+
{
|
|
96670
|
+
group: "Exit",
|
|
96671
|
+
items: [
|
|
96672
|
+
{ value: "disappear", label: "Disappear" },
|
|
96673
|
+
{ value: "fadeOut", label: "Fade Out" }
|
|
96674
|
+
]
|
|
96675
|
+
}
|
|
96676
|
+
];
|
|
96677
|
+
function AnimationsSection(p3) {
|
|
96678
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
96679
|
+
const [previewActive, setPreviewActive] = React10.useState(false);
|
|
96680
|
+
const hasElement = p3.selectedElement !== null;
|
|
96681
|
+
const disabled = !p3.canEdit || !hasElement;
|
|
96682
|
+
const handlePreview = () => {
|
|
96683
|
+
if (disabled) {
|
|
96684
|
+
return;
|
|
96685
|
+
}
|
|
96686
|
+
setPreviewActive(true);
|
|
96687
|
+
setTimeout(() => setPreviewActive(false), 1200);
|
|
96688
|
+
};
|
|
96689
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
96690
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
96691
|
+
"button",
|
|
96692
|
+
{
|
|
96693
|
+
type: "button",
|
|
96694
|
+
onClick: handlePreview,
|
|
96695
|
+
disabled,
|
|
96696
|
+
className: cn(
|
|
96697
|
+
pill,
|
|
96698
|
+
previewActive ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
|
|
96699
|
+
),
|
|
96700
|
+
title: t2("pptx.animations.previewTooltip"),
|
|
96701
|
+
children: [
|
|
96702
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPlay, { className: ic2 }),
|
|
96703
|
+
t2("pptx.animations.preview")
|
|
96704
|
+
]
|
|
96705
|
+
}
|
|
96706
|
+
),
|
|
96707
|
+
sep,
|
|
96708
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group", children: [
|
|
96709
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
96710
|
+
"button",
|
|
96711
|
+
{
|
|
96712
|
+
type: "button",
|
|
96713
|
+
disabled,
|
|
96714
|
+
className: pill,
|
|
96715
|
+
title: t2("pptx.animations.addTooltip"),
|
|
96716
|
+
children: [
|
|
96717
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuSparkles, { className: ic2 }),
|
|
96718
|
+
t2("pptx.animations.addAnimation"),
|
|
96719
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronDown, { className: "w-3 h-3" })
|
|
96720
|
+
]
|
|
96721
|
+
}
|
|
96722
|
+
),
|
|
96723
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-full z-50 hidden group-hover:flex flex-col w-44 pt-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl py-1", children: ANIMATION_PRESETS.map((group) => /* @__PURE__ */ jsxRuntime.jsxs(React10__namespace.default.Fragment, { children: [
|
|
96724
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pt-1.5 pb-0.5 text-[10px] font-semibold text-muted-foreground uppercase tracking-wider", children: t2(`pptx.animations.group.${group.group.toLowerCase()}`) }),
|
|
96725
|
+
group.items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
96726
|
+
"button",
|
|
96727
|
+
{
|
|
96728
|
+
type: "button",
|
|
96729
|
+
disabled,
|
|
96730
|
+
className: "flex items-center gap-2 w-full px-3 py-1.5 text-xs text-foreground hover:bg-muted transition-colors disabled:opacity-40 disabled:cursor-not-allowed",
|
|
96731
|
+
title: t2("pptx.animations.applyAnimation", {
|
|
96732
|
+
name: t2(`pptx.animations.preset.${item.value}`)
|
|
96733
|
+
}),
|
|
96734
|
+
children: t2(`pptx.animations.preset.${item.value}`)
|
|
96735
|
+
},
|
|
96736
|
+
item.value
|
|
96737
|
+
))
|
|
96738
|
+
] }, group.group)) }) })
|
|
96739
|
+
] }),
|
|
96740
|
+
sep,
|
|
96741
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
96742
|
+
"button",
|
|
96743
|
+
{
|
|
96744
|
+
type: "button",
|
|
96745
|
+
disabled,
|
|
96746
|
+
className: pill,
|
|
96747
|
+
title: t2("pptx.animations.removeTooltip"),
|
|
96748
|
+
children: [
|
|
96749
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuTrash2, { className: ic2 }),
|
|
96750
|
+
t2("pptx.animations.remove")
|
|
96751
|
+
]
|
|
96752
|
+
}
|
|
96753
|
+
),
|
|
96754
|
+
sep,
|
|
96755
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
96756
|
+
"button",
|
|
96757
|
+
{
|
|
96758
|
+
type: "button",
|
|
96759
|
+
onClick: p3.onToggleInspector,
|
|
96760
|
+
className: cn(
|
|
96761
|
+
pill,
|
|
96762
|
+
p3.isInspectorPaneOpen ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
|
|
96763
|
+
),
|
|
96764
|
+
title: t2("pptx.animations.openPanelTooltip"),
|
|
96765
|
+
children: [
|
|
96766
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPanelRight, { className: ic2 }),
|
|
96767
|
+
t2("pptx.animations.animationPanel")
|
|
96768
|
+
]
|
|
96769
|
+
}
|
|
96770
|
+
)
|
|
96771
|
+
] });
|
|
96772
|
+
}
|
|
96551
96773
|
function ArrangeSection(p3) {
|
|
96774
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
96552
96775
|
const hasSel = Boolean(p3.selectedElement);
|
|
96553
96776
|
const canMut = hasSel && p3.canEdit;
|
|
96554
96777
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -96559,21 +96782,21 @@ function ArrangeSection(p3) {
|
|
|
96559
96782
|
onClick: () => p3.onAlignElements(a2.k),
|
|
96560
96783
|
disabled: !canMut,
|
|
96561
96784
|
className: i3 < arr.length - 1 ? gB : gL,
|
|
96562
|
-
title:
|
|
96785
|
+
title: t2("pptx.arrange.align", { direction: a2.k }),
|
|
96563
96786
|
children: a2.el
|
|
96564
96787
|
},
|
|
96565
96788
|
a2.k
|
|
96566
96789
|
)) }),
|
|
96567
96790
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: grp, children: [
|
|
96568
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: p3.onCopy, disabled: !hasSel, className: gB, title: "
|
|
96569
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: p3.onCut, disabled: !canMut, className: gB, title: "
|
|
96791
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: p3.onCopy, disabled: !hasSel, className: gB, title: t2("pptx.arrange.copy"), children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuCopy, { className: ic2 }) }),
|
|
96792
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: p3.onCut, disabled: !canMut, className: gB, title: t2("pptx.arrange.cut"), children: t2("pptx.arrange.cut") }),
|
|
96570
96793
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
96571
96794
|
"button",
|
|
96572
96795
|
{
|
|
96573
96796
|
onClick: p3.onPaste,
|
|
96574
96797
|
disabled: !p3.clipboardPayload || !p3.canEdit,
|
|
96575
96798
|
className: gL,
|
|
96576
|
-
title: "
|
|
96799
|
+
title: t2("pptx.arrange.paste"),
|
|
96577
96800
|
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuClipboardPaste, { className: ic2 })
|
|
96578
96801
|
}
|
|
96579
96802
|
)
|
|
@@ -96588,10 +96811,10 @@ function ArrangeSection(p3) {
|
|
|
96588
96811
|
pill,
|
|
96589
96812
|
p3.formatPainterActive ? "bg-amber-600 hover:bg-amber-500 text-amber-50" : ""
|
|
96590
96813
|
),
|
|
96591
|
-
title: "
|
|
96814
|
+
title: t2("pptx.arrange.formatPainter"),
|
|
96592
96815
|
children: [
|
|
96593
96816
|
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPaintbrush, { className: ic2 }),
|
|
96594
|
-
"
|
|
96817
|
+
t2("pptx.arrange.format")
|
|
96595
96818
|
]
|
|
96596
96819
|
}
|
|
96597
96820
|
),
|
|
@@ -96603,8 +96826,8 @@ function ArrangeSection(p3) {
|
|
|
96603
96826
|
onClick: () => p3.onFlip("horizontal"),
|
|
96604
96827
|
disabled: !canMut,
|
|
96605
96828
|
className: gB,
|
|
96606
|
-
title: "
|
|
96607
|
-
children: "
|
|
96829
|
+
title: t2("pptx.arrange.flipHorizontally"),
|
|
96830
|
+
children: t2("pptx.arrange.flipH")
|
|
96608
96831
|
}
|
|
96609
96832
|
),
|
|
96610
96833
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -96614,8 +96837,8 @@ function ArrangeSection(p3) {
|
|
|
96614
96837
|
onClick: () => p3.onFlip("vertical"),
|
|
96615
96838
|
disabled: !canMut,
|
|
96616
96839
|
className: gL,
|
|
96617
|
-
title: "
|
|
96618
|
-
children: "
|
|
96840
|
+
title: t2("pptx.arrange.flipVertically"),
|
|
96841
|
+
children: t2("pptx.arrange.flipV")
|
|
96619
96842
|
}
|
|
96620
96843
|
)
|
|
96621
96844
|
] }),
|
|
@@ -96626,7 +96849,7 @@ function ArrangeSection(p3) {
|
|
|
96626
96849
|
onClick: () => p3.onMoveLayer("backward"),
|
|
96627
96850
|
disabled: !canMut,
|
|
96628
96851
|
className: gB,
|
|
96629
|
-
title: "
|
|
96852
|
+
title: t2("pptx.arrange.sendBackward"),
|
|
96630
96853
|
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronDown, { className: ic2 })
|
|
96631
96854
|
}
|
|
96632
96855
|
),
|
|
@@ -96636,7 +96859,7 @@ function ArrangeSection(p3) {
|
|
|
96636
96859
|
onClick: () => p3.onMoveLayer("forward"),
|
|
96637
96860
|
disabled: !canMut,
|
|
96638
96861
|
className: gB,
|
|
96639
|
-
title: "
|
|
96862
|
+
title: t2("pptx.arrange.bringForward"),
|
|
96640
96863
|
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronUp, { className: ic2 })
|
|
96641
96864
|
}
|
|
96642
96865
|
),
|
|
@@ -96646,8 +96869,8 @@ function ArrangeSection(p3) {
|
|
|
96646
96869
|
onClick: () => p3.onMoveLayerToEdge("back"),
|
|
96647
96870
|
disabled: !canMut,
|
|
96648
96871
|
className: gB,
|
|
96649
|
-
title: "
|
|
96650
|
-
children: "
|
|
96872
|
+
title: t2("pptx.arrange.sendToBack"),
|
|
96873
|
+
children: t2("pptx.arrange.back")
|
|
96651
96874
|
}
|
|
96652
96875
|
),
|
|
96653
96876
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -96656,25 +96879,34 @@ function ArrangeSection(p3) {
|
|
|
96656
96879
|
onClick: () => p3.onMoveLayerToEdge("front"),
|
|
96657
96880
|
disabled: !canMut,
|
|
96658
96881
|
className: gL,
|
|
96659
|
-
title: "
|
|
96660
|
-
children: "
|
|
96882
|
+
title: t2("pptx.arrange.bringToFront"),
|
|
96883
|
+
children: t2("pptx.arrange.front")
|
|
96661
96884
|
}
|
|
96662
96885
|
)
|
|
96663
96886
|
] }),
|
|
96664
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
96665
|
-
|
|
96666
|
-
|
|
96667
|
-
|
|
96887
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
96888
|
+
"button",
|
|
96889
|
+
{
|
|
96890
|
+
onClick: p3.onDuplicate,
|
|
96891
|
+
disabled: !canMut,
|
|
96892
|
+
className: pill,
|
|
96893
|
+
title: t2("pptx.arrange.duplicate"),
|
|
96894
|
+
children: [
|
|
96895
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCopy, { className: ic2 }),
|
|
96896
|
+
t2("pptx.arrange.duplicate")
|
|
96897
|
+
]
|
|
96898
|
+
}
|
|
96899
|
+
),
|
|
96668
96900
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
96669
96901
|
"button",
|
|
96670
96902
|
{
|
|
96671
96903
|
onClick: p3.onDelete,
|
|
96672
96904
|
disabled: !canMut,
|
|
96673
96905
|
className: "inline-flex items-center gap-1.5 px-2.5 py-1.5 rounded bg-red-700/80 hover:bg-red-600 disabled:opacity-40 disabled:cursor-not-allowed text-xs transition-colors",
|
|
96674
|
-
title: "
|
|
96906
|
+
title: t2("pptx.arrange.delete"),
|
|
96675
96907
|
children: [
|
|
96676
96908
|
/* @__PURE__ */ jsxRuntime.jsx(lu.LuTrash2, { className: ic2 }),
|
|
96677
|
-
"
|
|
96909
|
+
t2("pptx.arrange.delete")
|
|
96678
96910
|
]
|
|
96679
96911
|
}
|
|
96680
96912
|
)
|
|
@@ -96713,12 +96945,91 @@ function DesignSection(p3) {
|
|
|
96713
96945
|
"Edit Theme"
|
|
96714
96946
|
]
|
|
96715
96947
|
}
|
|
96948
|
+
),
|
|
96949
|
+
sep,
|
|
96950
|
+
p3.onOpenDocumentProperties && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
96951
|
+
"button",
|
|
96952
|
+
{
|
|
96953
|
+
onClick: p3.onOpenDocumentProperties,
|
|
96954
|
+
className: pill,
|
|
96955
|
+
title: "Change slide dimensions (16:9, 4:3, custom)",
|
|
96956
|
+
children: [
|
|
96957
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuMonitor, { className: ics }),
|
|
96958
|
+
"Slide Size"
|
|
96959
|
+
]
|
|
96960
|
+
}
|
|
96961
|
+
),
|
|
96962
|
+
p3.onToggleInspector && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
96963
|
+
"button",
|
|
96964
|
+
{
|
|
96965
|
+
onClick: p3.onToggleInspector,
|
|
96966
|
+
className: cn(
|
|
96967
|
+
pill,
|
|
96968
|
+
p3.isInspectorPaneOpen ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
|
|
96969
|
+
),
|
|
96970
|
+
title: "Open inspector to edit slide background",
|
|
96971
|
+
children: [
|
|
96972
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPaintBucket, { className: ics }),
|
|
96973
|
+
"Format Background"
|
|
96974
|
+
]
|
|
96975
|
+
}
|
|
96716
96976
|
)
|
|
96717
96977
|
] });
|
|
96718
96978
|
}
|
|
96979
|
+
var TRANSITION_PRESETS = [
|
|
96980
|
+
{ value: "none", label: "None" },
|
|
96981
|
+
{ value: "fade", label: "Fade" },
|
|
96982
|
+
{ value: "push", label: "Push" },
|
|
96983
|
+
{ value: "wipe", label: "Wipe" },
|
|
96984
|
+
{ value: "split", label: "Split" },
|
|
96985
|
+
{ value: "reveal", label: "Reveal" },
|
|
96986
|
+
{ value: "cut", label: "Cut" },
|
|
96987
|
+
{ value: "cover", label: "Cover" },
|
|
96988
|
+
{ value: "uncover", label: "Uncover" }
|
|
96989
|
+
];
|
|
96719
96990
|
function TransitionsSection(p3) {
|
|
96991
|
+
const [selected, setSelected] = React10__namespace.default.useState("none");
|
|
96992
|
+
const [duration, setDuration] = React10__namespace.default.useState("00.50");
|
|
96720
96993
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
96721
|
-
/* @__PURE__ */ jsxRuntime.
|
|
96994
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: pill, title: "Preview transition", children: [
|
|
96995
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPlay, { className: ics }),
|
|
96996
|
+
"Preview"
|
|
96997
|
+
] }),
|
|
96998
|
+
sep,
|
|
96999
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex items-center gap-0.5 overflow-x-auto max-w-[420px]", children: TRANSITION_PRESETS.map((t2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
97000
|
+
"button",
|
|
97001
|
+
{
|
|
97002
|
+
type: "button",
|
|
97003
|
+
onClick: () => setSelected(t2.value),
|
|
97004
|
+
className: cn(
|
|
97005
|
+
"flex-shrink-0 px-2 py-1 max-md:min-h-[44px] rounded border text-[11px] leading-tight transition-colors",
|
|
97006
|
+
selected === t2.value ? "border-primary bg-primary/10 text-primary font-medium" : "border-border bg-muted hover:bg-accent text-foreground"
|
|
97007
|
+
),
|
|
97008
|
+
title: `${t2.label} transition`,
|
|
97009
|
+
children: t2.label
|
|
97010
|
+
},
|
|
97011
|
+
t2.value
|
|
97012
|
+
)) }),
|
|
97013
|
+
sep,
|
|
97014
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { className: "inline-flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
97015
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap", children: "Duration:" }),
|
|
97016
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97017
|
+
"input",
|
|
97018
|
+
{
|
|
97019
|
+
type: "text",
|
|
97020
|
+
value: duration,
|
|
97021
|
+
onChange: (e2) => setDuration(e2.target.value),
|
|
97022
|
+
className: "w-14 px-1.5 py-1 rounded border border-border bg-muted text-xs text-foreground text-center",
|
|
97023
|
+
title: "Transition duration in seconds"
|
|
97024
|
+
}
|
|
97025
|
+
)
|
|
97026
|
+
] }),
|
|
97027
|
+
sep,
|
|
97028
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: pill, title: "Apply transition to all slides", children: [
|
|
97029
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCopy, { className: ics }),
|
|
97030
|
+
"Apply to All"
|
|
97031
|
+
] }),
|
|
97032
|
+
sep,
|
|
96722
97033
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
96723
97034
|
"button",
|
|
96724
97035
|
{
|
|
@@ -96728,7 +97039,7 @@ function TransitionsSection(p3) {
|
|
|
96728
97039
|
pill,
|
|
96729
97040
|
p3.isInspectorPaneOpen ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
|
|
96730
97041
|
),
|
|
96731
|
-
title: "Open Inspector
|
|
97042
|
+
title: "Open Inspector for full transition options",
|
|
96732
97043
|
children: [
|
|
96733
97044
|
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPanelRight, { className: ic2 }),
|
|
96734
97045
|
"Inspector"
|
|
@@ -96839,6 +97150,321 @@ function DrawSection(p3) {
|
|
|
96839
97150
|
] })
|
|
96840
97151
|
] });
|
|
96841
97152
|
}
|
|
97153
|
+
function FileSection(p3) {
|
|
97154
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
97155
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onSaveAsPpsx, className: pill, title: "Save as Slide Show (.ppsx)", children: [
|
|
97156
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPlay, { className: ic2 }),
|
|
97157
|
+
"Save .ppsx"
|
|
97158
|
+
] }),
|
|
97159
|
+
p3.hasMacros && /* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onSaveAsPptm, className: pill, title: "Save as Macro-Enabled (.pptm)", children: [
|
|
97160
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuFileText, { className: ic2 }),
|
|
97161
|
+
"Save .pptm"
|
|
97162
|
+
] }),
|
|
97163
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onPackageForSharing, className: pill, title: "Package for Sharing", children: [
|
|
97164
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuFolderOpen, { className: ic2 }),
|
|
97165
|
+
"Package"
|
|
97166
|
+
] }),
|
|
97167
|
+
sep,
|
|
97168
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onExportPng, className: pill, title: "Export as PNG", children: [
|
|
97169
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuDownload, { className: ic2 }),
|
|
97170
|
+
"PNG"
|
|
97171
|
+
] }),
|
|
97172
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onExportPdf, className: pill, title: "Export as PDF", children: [
|
|
97173
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuFileText, { className: ic2 }),
|
|
97174
|
+
"PDF"
|
|
97175
|
+
] }),
|
|
97176
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onExportVideo, className: pill, title: "Export as Video", children: [
|
|
97177
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuVideo, { className: ic2 }),
|
|
97178
|
+
"Video"
|
|
97179
|
+
] }),
|
|
97180
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onExportGif, className: pill, title: "Export as GIF", children: [
|
|
97181
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuImage, { className: ic2 }),
|
|
97182
|
+
"GIF"
|
|
97183
|
+
] }),
|
|
97184
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onCopySlideAsImage, className: pill, title: "Copy Slide as Image", children: [
|
|
97185
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCopy, { className: ic2 }),
|
|
97186
|
+
"Copy Image"
|
|
97187
|
+
] }),
|
|
97188
|
+
sep,
|
|
97189
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onPrint, className: pill, title: "Print", children: [
|
|
97190
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPrinter, { className: ic2 }),
|
|
97191
|
+
"Print"
|
|
97192
|
+
] }),
|
|
97193
|
+
sep,
|
|
97194
|
+
p3.onOpenDocumentProperties && /* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onOpenDocumentProperties, className: pill, title: "Document Properties", children: [
|
|
97195
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuInfo, { className: ic2 }),
|
|
97196
|
+
"Properties"
|
|
97197
|
+
] }),
|
|
97198
|
+
p3.onOpenPasswordProtection && /* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onOpenPasswordProtection, className: pill, title: "Protect Presentation", children: [
|
|
97199
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuLock, { className: ic2 }),
|
|
97200
|
+
"Protect"
|
|
97201
|
+
] }),
|
|
97202
|
+
p3.onOpenFontEmbedding && /* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onOpenFontEmbedding, className: pill, title: "Embed Fonts", children: [
|
|
97203
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuType, { className: ic2 }),
|
|
97204
|
+
"Fonts"
|
|
97205
|
+
] }),
|
|
97206
|
+
p3.onOpenDigitalSignatures && /* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onOpenDigitalSignatures, className: pill, title: "Digital Signatures", children: [
|
|
97207
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuShieldAlert, { className: ic2 }),
|
|
97208
|
+
"Signatures"
|
|
97209
|
+
] })
|
|
97210
|
+
] });
|
|
97211
|
+
}
|
|
97212
|
+
function extractFontInfo(element2) {
|
|
97213
|
+
const defaults = { fontFamily: "Segoe UI", fontSize: "24" };
|
|
97214
|
+
if (!element2) {
|
|
97215
|
+
return defaults;
|
|
97216
|
+
}
|
|
97217
|
+
if (!pptxViewerCore.hasTextProperties(element2)) {
|
|
97218
|
+
return defaults;
|
|
97219
|
+
}
|
|
97220
|
+
const segStyle = element2.textSegments?.[0]?.style;
|
|
97221
|
+
const textStyle = element2.textStyle;
|
|
97222
|
+
const fontFamily = segStyle?.fontFamily ?? textStyle?.fontFamily ?? defaults.fontFamily;
|
|
97223
|
+
const fontSize = segStyle?.fontSize ?? textStyle?.fontSize;
|
|
97224
|
+
return {
|
|
97225
|
+
fontFamily,
|
|
97226
|
+
fontSize: fontSize !== void 0 && fontSize !== null ? String(fontSize) : defaults.fontSize
|
|
97227
|
+
};
|
|
97228
|
+
}
|
|
97229
|
+
var COMMON_FONTS = [
|
|
97230
|
+
"Arial",
|
|
97231
|
+
"Calibri",
|
|
97232
|
+
"Cambria",
|
|
97233
|
+
"Comic Sans MS",
|
|
97234
|
+
"Courier New",
|
|
97235
|
+
"Georgia",
|
|
97236
|
+
"Helvetica",
|
|
97237
|
+
"Impact",
|
|
97238
|
+
"Segoe UI",
|
|
97239
|
+
"Tahoma",
|
|
97240
|
+
"Times New Roman",
|
|
97241
|
+
"Trebuchet MS",
|
|
97242
|
+
"Verdana"
|
|
97243
|
+
];
|
|
97244
|
+
var COMMON_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 44, 48, 54, 60, 72, 96];
|
|
97245
|
+
function HomeSection(p3) {
|
|
97246
|
+
const [layoutMenuOpen, setLayoutMenuOpen] = React10.useState(false);
|
|
97247
|
+
const [fontMenuOpen, setFontMenuOpen] = React10.useState(false);
|
|
97248
|
+
const [sizeMenuOpen, setSizeMenuOpen] = React10.useState(false);
|
|
97249
|
+
const [copiedFeedback, setCopiedFeedback] = React10.useState(false);
|
|
97250
|
+
const [cutFeedback, setCutFeedback] = React10.useState(false);
|
|
97251
|
+
const layoutMenuRef = React10.useRef(null);
|
|
97252
|
+
const fontMenuRef = React10.useRef(null);
|
|
97253
|
+
const sizeMenuRef = React10.useRef(null);
|
|
97254
|
+
const { fontFamily, fontSize } = extractFontInfo(p3.selectedElement);
|
|
97255
|
+
const handleNewSlide = React10.useCallback(() => {
|
|
97256
|
+
if (p3.layoutOptions.length > 0) {
|
|
97257
|
+
p3.onInsertSlideFromLayout(p3.layoutOptions[0].path);
|
|
97258
|
+
}
|
|
97259
|
+
}, [p3]);
|
|
97260
|
+
React10.useEffect(() => {
|
|
97261
|
+
if (!layoutMenuOpen) {
|
|
97262
|
+
return;
|
|
97263
|
+
}
|
|
97264
|
+
const handler = (e2) => {
|
|
97265
|
+
if (layoutMenuRef.current && !layoutMenuRef.current.contains(e2.target)) {
|
|
97266
|
+
setLayoutMenuOpen(false);
|
|
97267
|
+
}
|
|
97268
|
+
};
|
|
97269
|
+
document.addEventListener("mousedown", handler);
|
|
97270
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
97271
|
+
}, [layoutMenuOpen]);
|
|
97272
|
+
React10.useEffect(() => {
|
|
97273
|
+
if (!fontMenuOpen) {
|
|
97274
|
+
return;
|
|
97275
|
+
}
|
|
97276
|
+
const handler = (e2) => {
|
|
97277
|
+
if (fontMenuRef.current && !fontMenuRef.current.contains(e2.target)) {
|
|
97278
|
+
setFontMenuOpen(false);
|
|
97279
|
+
}
|
|
97280
|
+
};
|
|
97281
|
+
document.addEventListener("mousedown", handler);
|
|
97282
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
97283
|
+
}, [fontMenuOpen]);
|
|
97284
|
+
React10.useEffect(() => {
|
|
97285
|
+
if (!sizeMenuOpen) {
|
|
97286
|
+
return;
|
|
97287
|
+
}
|
|
97288
|
+
const handler = (e2) => {
|
|
97289
|
+
if (sizeMenuRef.current && !sizeMenuRef.current.contains(e2.target)) {
|
|
97290
|
+
setSizeMenuOpen(false);
|
|
97291
|
+
}
|
|
97292
|
+
};
|
|
97293
|
+
document.addEventListener("mousedown", handler);
|
|
97294
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
97295
|
+
}, [sizeMenuOpen]);
|
|
97296
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
97297
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
97298
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: grp, children: [
|
|
97299
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97300
|
+
"button",
|
|
97301
|
+
{
|
|
97302
|
+
type: "button",
|
|
97303
|
+
onClick: p3.onPaste,
|
|
97304
|
+
disabled: !p3.clipboardPayload || !p3.canEdit,
|
|
97305
|
+
className: gB,
|
|
97306
|
+
title: "Paste",
|
|
97307
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuClipboardPaste, { className: ic2 })
|
|
97308
|
+
}
|
|
97309
|
+
),
|
|
97310
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97311
|
+
"button",
|
|
97312
|
+
{
|
|
97313
|
+
type: "button",
|
|
97314
|
+
onClick: () => {
|
|
97315
|
+
p3.onCut();
|
|
97316
|
+
setCutFeedback(true);
|
|
97317
|
+
setTimeout(() => setCutFeedback(false), 600);
|
|
97318
|
+
},
|
|
97319
|
+
disabled: !p3.canEdit,
|
|
97320
|
+
className: cn(gB, cutFeedback && "bg-green-600/20 text-green-400"),
|
|
97321
|
+
title: "Cut",
|
|
97322
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuScissors, { className: ic2 })
|
|
97323
|
+
}
|
|
97324
|
+
),
|
|
97325
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97326
|
+
"button",
|
|
97327
|
+
{
|
|
97328
|
+
type: "button",
|
|
97329
|
+
onClick: () => {
|
|
97330
|
+
p3.onCopy();
|
|
97331
|
+
setCopiedFeedback(true);
|
|
97332
|
+
setTimeout(() => setCopiedFeedback(false), 600);
|
|
97333
|
+
},
|
|
97334
|
+
className: cn(gB, copiedFeedback && "bg-green-600/20 text-green-400"),
|
|
97335
|
+
title: "Copy",
|
|
97336
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuCopy, { className: ic2 })
|
|
97337
|
+
}
|
|
97338
|
+
),
|
|
97339
|
+
p3.onToggleFormatPainter && /* @__PURE__ */ jsxRuntime.jsx(
|
|
97340
|
+
"button",
|
|
97341
|
+
{
|
|
97342
|
+
type: "button",
|
|
97343
|
+
onClick: p3.onToggleFormatPainter,
|
|
97344
|
+
disabled: !p3.canEdit,
|
|
97345
|
+
className: cn(
|
|
97346
|
+
gL,
|
|
97347
|
+
p3.formatPainterActive ? "bg-amber-600 hover:bg-amber-500 text-amber-50" : ""
|
|
97348
|
+
),
|
|
97349
|
+
title: "Format Painter",
|
|
97350
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPaintbrush, { className: ic2 })
|
|
97351
|
+
}
|
|
97352
|
+
)
|
|
97353
|
+
] }),
|
|
97354
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Clipboard" })
|
|
97355
|
+
] }),
|
|
97356
|
+
sep,
|
|
97357
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
97358
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative inline-flex items-center", ref: layoutMenuRef, children: [
|
|
97359
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
97360
|
+
"button",
|
|
97361
|
+
{
|
|
97362
|
+
type: "button",
|
|
97363
|
+
onClick: handleNewSlide,
|
|
97364
|
+
disabled: !p3.canEdit || p3.layoutOptions.length === 0,
|
|
97365
|
+
className: cn(
|
|
97366
|
+
pill,
|
|
97367
|
+
"whitespace-nowrap",
|
|
97368
|
+
p3.layoutOptions.length > 0 ? "rounded-r-none" : ""
|
|
97369
|
+
),
|
|
97370
|
+
title: "New Slide",
|
|
97371
|
+
children: [
|
|
97372
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPlus, { className: ic2 }),
|
|
97373
|
+
"New Slide"
|
|
97374
|
+
]
|
|
97375
|
+
}
|
|
97376
|
+
),
|
|
97377
|
+
p3.layoutOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
97378
|
+
"button",
|
|
97379
|
+
{
|
|
97380
|
+
type: "button",
|
|
97381
|
+
disabled: !p3.canEdit,
|
|
97382
|
+
className: "inline-flex items-center justify-center self-stretch px-1 rounded-r bg-muted hover:bg-accent text-xs transition-colors border-l border-border/40 active:scale-95 active:opacity-80",
|
|
97383
|
+
title: "Choose layout",
|
|
97384
|
+
onClick: () => setLayoutMenuOpen((v) => !v),
|
|
97385
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronDown, { className: "w-3 h-3" })
|
|
97386
|
+
}
|
|
97387
|
+
),
|
|
97388
|
+
layoutMenuOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-full z-50 flex flex-col w-48 pt-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl py-1 max-h-60 overflow-y-auto", children: p3.layoutOptions.map((lo) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
97389
|
+
"button",
|
|
97390
|
+
{
|
|
97391
|
+
type: "button",
|
|
97392
|
+
className: "flex items-center gap-2 w-full px-3 py-1.5 text-xs text-foreground hover:bg-muted transition-colors",
|
|
97393
|
+
onClick: () => {
|
|
97394
|
+
p3.onInsertSlideFromLayout(lo.path);
|
|
97395
|
+
setLayoutMenuOpen(false);
|
|
97396
|
+
},
|
|
97397
|
+
children: lo.name
|
|
97398
|
+
},
|
|
97399
|
+
lo.path
|
|
97400
|
+
)) }) })
|
|
97401
|
+
] }),
|
|
97402
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Slides" })
|
|
97403
|
+
] }),
|
|
97404
|
+
sep,
|
|
97405
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
97406
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
97407
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", ref: fontMenuRef, children: [
|
|
97408
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
97409
|
+
"button",
|
|
97410
|
+
{
|
|
97411
|
+
type: "button",
|
|
97412
|
+
onClick: () => setFontMenuOpen((v) => !v),
|
|
97413
|
+
className: "inline-flex items-center justify-between px-2 py-1 rounded-sm border border-border/60 bg-background/60 text-[11px] text-foreground min-w-[120px] truncate hover:bg-accent/40 transition-colors cursor-pointer",
|
|
97414
|
+
children: [
|
|
97415
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: fontFamily }),
|
|
97416
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronDown, { className: "w-3 h-3 ml-1 shrink-0 text-muted-foreground" })
|
|
97417
|
+
]
|
|
97418
|
+
}
|
|
97419
|
+
),
|
|
97420
|
+
fontMenuOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-full z-50 flex flex-col w-48 pt-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl py-1 max-h-60 overflow-y-auto", children: COMMON_FONTS.map((f) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
97421
|
+
"button",
|
|
97422
|
+
{
|
|
97423
|
+
type: "button",
|
|
97424
|
+
className: "flex items-center gap-2 w-full px-3 py-1.5 text-xs text-foreground hover:bg-muted transition-colors",
|
|
97425
|
+
style: { fontFamily: f },
|
|
97426
|
+
onClick: () => {
|
|
97427
|
+
p3.onUpdateTextStyle?.({ fontFamily: f });
|
|
97428
|
+
setFontMenuOpen(false);
|
|
97429
|
+
},
|
|
97430
|
+
children: f
|
|
97431
|
+
},
|
|
97432
|
+
f
|
|
97433
|
+
)) }) })
|
|
97434
|
+
] }),
|
|
97435
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", ref: sizeMenuRef, children: [
|
|
97436
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
97437
|
+
"button",
|
|
97438
|
+
{
|
|
97439
|
+
type: "button",
|
|
97440
|
+
onClick: () => setSizeMenuOpen((v) => !v),
|
|
97441
|
+
className: "inline-flex items-center justify-between px-2 py-1 rounded-sm border border-border/60 bg-background/60 text-[11px] text-foreground min-w-[50px] text-center hover:bg-accent/40 transition-colors cursor-pointer",
|
|
97442
|
+
children: [
|
|
97443
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: fontSize }),
|
|
97444
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronDown, { className: "w-3 h-3 ml-1 shrink-0 text-muted-foreground" })
|
|
97445
|
+
]
|
|
97446
|
+
}
|
|
97447
|
+
),
|
|
97448
|
+
sizeMenuOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 top-full z-50 flex flex-col w-48 pt-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-border bg-popover backdrop-blur-lg shadow-2xl py-1 max-h-60 overflow-y-auto", children: COMMON_SIZES.map((s) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
97449
|
+
"button",
|
|
97450
|
+
{
|
|
97451
|
+
type: "button",
|
|
97452
|
+
className: "flex items-center gap-2 w-full px-3 py-1.5 text-xs text-foreground hover:bg-muted transition-colors",
|
|
97453
|
+
onClick: () => {
|
|
97454
|
+
p3.onUpdateTextStyle?.({ fontSize: s });
|
|
97455
|
+
setSizeMenuOpen(false);
|
|
97456
|
+
},
|
|
97457
|
+
children: s
|
|
97458
|
+
},
|
|
97459
|
+
s
|
|
97460
|
+
)) }) })
|
|
97461
|
+
] })
|
|
97462
|
+
] }),
|
|
97463
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Font" })
|
|
97464
|
+
] }),
|
|
97465
|
+
sep
|
|
97466
|
+
] });
|
|
97467
|
+
}
|
|
96842
97468
|
function InsertSection(p3) {
|
|
96843
97469
|
const { t: t2 } = reactI18next.useTranslation();
|
|
96844
97470
|
const { canEdit } = p3;
|
|
@@ -97197,6 +97823,60 @@ function InsertSection(p3) {
|
|
|
97197
97823
|
)
|
|
97198
97824
|
] });
|
|
97199
97825
|
}
|
|
97826
|
+
function SlideShowSection(p3) {
|
|
97827
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
97828
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
97829
|
+
"button",
|
|
97830
|
+
{
|
|
97831
|
+
onClick: () => p3.onSetMode("present"),
|
|
97832
|
+
className: pill,
|
|
97833
|
+
title: "Start slide show from beginning",
|
|
97834
|
+
children: [
|
|
97835
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPlay, { className: ic2 }),
|
|
97836
|
+
"From Beginning"
|
|
97837
|
+
]
|
|
97838
|
+
}
|
|
97839
|
+
),
|
|
97840
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onPresent, className: pill, title: "Start slide show from current slide", children: [
|
|
97841
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuPlay, { className: ic2 }),
|
|
97842
|
+
"From Current Slide"
|
|
97843
|
+
] }),
|
|
97844
|
+
sep,
|
|
97845
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onEnterPresenterView, className: pill, title: "Presenter view", children: [
|
|
97846
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuMonitor, { className: ic2 }),
|
|
97847
|
+
"Presenter View"
|
|
97848
|
+
] }),
|
|
97849
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onEnterRehearsalMode, className: pill, title: "Rehearse timings", children: [
|
|
97850
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuClock, { className: ic2 }),
|
|
97851
|
+
"Rehearse Timings"
|
|
97852
|
+
] }),
|
|
97853
|
+
sep,
|
|
97854
|
+
/* @__PURE__ */ jsxRuntime.jsxs("button", { onClick: p3.onOpenSetUpSlideShow, className: pill, title: "Set up slide show", children: [
|
|
97855
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuSettings, { className: ic2 }),
|
|
97856
|
+
"Set Up Slide Show"
|
|
97857
|
+
] }),
|
|
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
|
+
}
|
|
97200
97880
|
var FONT_COLOR_PRESETS = [
|
|
97201
97881
|
"#000000",
|
|
97202
97882
|
"#ffffff",
|
|
@@ -97209,6 +97889,18 @@ var FONT_COLOR_PRESETS = [
|
|
|
97209
97889
|
"#ff69b4",
|
|
97210
97890
|
"#808080"
|
|
97211
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
|
+
];
|
|
97212
97904
|
function TextSection(p3) {
|
|
97213
97905
|
const hasSel = Boolean(p3.selectedElement);
|
|
97214
97906
|
const canMut = hasSel && p3.canEdit;
|
|
@@ -97216,7 +97908,9 @@ function TextSection(p3) {
|
|
|
97216
97908
|
const isTable = hasSel && p3.selectedElement?.type === "table";
|
|
97217
97909
|
const canFormat = isTextEl || isTable;
|
|
97218
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";
|
|
97219
97912
|
const colorInputRef = React10.useRef(null);
|
|
97913
|
+
const highlightInputRef = React10.useRef(null);
|
|
97220
97914
|
const handleColorChange = React10.useCallback(
|
|
97221
97915
|
(color) => {
|
|
97222
97916
|
if (!canFormat) {
|
|
@@ -97226,138 +97920,875 @@ function TextSection(p3) {
|
|
|
97226
97920
|
},
|
|
97227
97921
|
[canFormat, p3]
|
|
97228
97922
|
);
|
|
97923
|
+
const handleHighlightChange = React10.useCallback(
|
|
97924
|
+
(highlightColor) => {
|
|
97925
|
+
if (!canFormat) {
|
|
97926
|
+
return;
|
|
97927
|
+
}
|
|
97928
|
+
p3.onUpdateTextStyle({ highlightColor });
|
|
97929
|
+
},
|
|
97930
|
+
[canFormat, p3]
|
|
97931
|
+
);
|
|
97229
97932
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
97230
|
-
/* @__PURE__ */ jsxRuntime.
|
|
97231
|
-
|
|
97232
|
-
|
|
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
|
+
] }),
|
|
98162
|
+
sep,
|
|
98163
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
98164
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
98165
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: grp, children: [
|
|
98166
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98167
|
+
"button",
|
|
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 })
|
|
98204
|
+
}
|
|
98205
|
+
)
|
|
98206
|
+
] }),
|
|
98207
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: grp, children: [
|
|
98208
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98209
|
+
"button",
|
|
98210
|
+
{
|
|
98211
|
+
type: "button",
|
|
98212
|
+
disabled: !canMut,
|
|
98213
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
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;
|
|
98220
|
+
p3.onUpdateTextStyle({
|
|
98221
|
+
paragraphMarginLeft: Math.max(0, current - 24)
|
|
98222
|
+
});
|
|
98223
|
+
},
|
|
98224
|
+
className: gB,
|
|
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;
|
|
98241
|
+
p3.onUpdateTextStyle({
|
|
98242
|
+
paragraphMarginLeft: current + 24
|
|
98243
|
+
});
|
|
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 });
|
|
98265
|
+
}
|
|
98266
|
+
};
|
|
98267
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
98268
|
+
"button",
|
|
98269
|
+
{
|
|
98270
|
+
type: "button",
|
|
98271
|
+
disabled: !canMut,
|
|
98272
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
98273
|
+
onClick: handleClick,
|
|
98274
|
+
className: i3 < a2.length - 1 ? gB : gL,
|
|
98275
|
+
title: b2.t,
|
|
98276
|
+
children: b2.i
|
|
98277
|
+
},
|
|
98278
|
+
b2.t
|
|
98279
|
+
);
|
|
98280
|
+
}) })
|
|
98281
|
+
] }),
|
|
98282
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Paragraph" })
|
|
98283
|
+
] })
|
|
98284
|
+
] });
|
|
98285
|
+
}
|
|
98286
|
+
|
|
98287
|
+
// src/viewer/hooks/collaboration/sanitize.ts
|
|
98288
|
+
var ROOM_ID_REGEX = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
98289
|
+
function validateRoomId(roomId) {
|
|
98290
|
+
if (!ROOM_ID_REGEX.test(roomId)) {
|
|
98291
|
+
throw new Error(
|
|
98292
|
+
`Invalid collaboration room ID: "${roomId}". Must be 1-128 alphanumeric characters, hyphens, or underscores.`
|
|
98293
|
+
);
|
|
98294
|
+
}
|
|
98295
|
+
return roomId;
|
|
98296
|
+
}
|
|
98297
|
+
function sanitizeUserName(name) {
|
|
98298
|
+
if (typeof name !== "string") {
|
|
98299
|
+
return "Anonymous";
|
|
98300
|
+
}
|
|
98301
|
+
const stripped = name.replace(/<[^>]*>/g, "");
|
|
98302
|
+
const trimmed = stripped.trim().slice(0, 64);
|
|
98303
|
+
return trimmed || "Anonymous";
|
|
98304
|
+
}
|
|
98305
|
+
function clampCursorPosition(value, min2, max2) {
|
|
98306
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
98307
|
+
return 0;
|
|
98308
|
+
}
|
|
98309
|
+
const margin = 20;
|
|
98310
|
+
return Math.max(min2 - margin, Math.min(max2 + margin, value));
|
|
98311
|
+
}
|
|
98312
|
+
var HEX_COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
|
|
98313
|
+
function sanitizeColor(color, fallback = "#6366f1") {
|
|
98314
|
+
if (typeof color !== "string") {
|
|
98315
|
+
return fallback;
|
|
98316
|
+
}
|
|
98317
|
+
return HEX_COLOR_REGEX.test(color) ? color : fallback;
|
|
98318
|
+
}
|
|
98319
|
+
function sanitizeAvatarUrl(url) {
|
|
98320
|
+
if (typeof url !== "string") {
|
|
98321
|
+
return void 0;
|
|
98322
|
+
}
|
|
98323
|
+
try {
|
|
98324
|
+
const parsed = new URL(url);
|
|
98325
|
+
if (parsed.protocol === "https:" || parsed.protocol === "http:" || parsed.protocol === "data:") {
|
|
98326
|
+
return url;
|
|
98327
|
+
}
|
|
98328
|
+
} catch {
|
|
98329
|
+
}
|
|
98330
|
+
return void 0;
|
|
98331
|
+
}
|
|
98332
|
+
function sanitizeSlideIndex(value) {
|
|
98333
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
98334
|
+
return 0;
|
|
98335
|
+
}
|
|
98336
|
+
return Math.max(0, Math.floor(value));
|
|
98337
|
+
}
|
|
98338
|
+
function sanitizePresence(raw, canvasWidth, canvasHeight) {
|
|
98339
|
+
if (typeof raw.clientId !== "number") {
|
|
98340
|
+
return null;
|
|
98341
|
+
}
|
|
98342
|
+
return {
|
|
98343
|
+
clientId: raw.clientId,
|
|
98344
|
+
userName: sanitizeUserName(raw.userName),
|
|
98345
|
+
userAvatar: sanitizeAvatarUrl(raw.userAvatar),
|
|
98346
|
+
userColor: sanitizeColor(raw.userColor),
|
|
98347
|
+
activeSlideIndex: sanitizeSlideIndex(raw.activeSlideIndex),
|
|
98348
|
+
cursorX: clampCursorPosition(raw.cursorX, 0, canvasWidth),
|
|
98349
|
+
cursorY: clampCursorPosition(raw.cursorY, 0, canvasHeight),
|
|
98350
|
+
lastUpdated: typeof raw.lastUpdated === "string" ? raw.lastUpdated : (/* @__PURE__ */ new Date()).toISOString(),
|
|
98351
|
+
selectedElementId: typeof raw.selectedElementId === "string" ? raw.selectedElementId.slice(0, 128) : void 0
|
|
98352
|
+
};
|
|
98353
|
+
}
|
|
98354
|
+
var BROADCAST_THROTTLE_MS = 50;
|
|
98355
|
+
var STALE_PRESENCE_MS = 3e4;
|
|
98356
|
+
function usePresenceTracking({
|
|
98357
|
+
awareness,
|
|
98358
|
+
localClientId,
|
|
98359
|
+
userName,
|
|
98360
|
+
userColor,
|
|
98361
|
+
userAvatar,
|
|
98362
|
+
canvasWidth,
|
|
98363
|
+
canvasHeight
|
|
98364
|
+
}) {
|
|
98365
|
+
const [remoteUsers, setRemoteUsers] = React10.useState([]);
|
|
98366
|
+
const lastBroadcastRef = React10.useRef(0);
|
|
98367
|
+
const pendingBroadcastRef = React10.useRef(null);
|
|
98368
|
+
const latestLocalState = React10.useRef({});
|
|
98369
|
+
const broadcastPresence = React10.useCallback(
|
|
98370
|
+
(update2) => {
|
|
98371
|
+
if (!awareness) {
|
|
98372
|
+
return;
|
|
98373
|
+
}
|
|
98374
|
+
Object.assign(latestLocalState.current, update2);
|
|
98375
|
+
const now = Date.now();
|
|
98376
|
+
const elapsed = now - lastBroadcastRef.current;
|
|
98377
|
+
const flush = () => {
|
|
98378
|
+
const state2 = {
|
|
98379
|
+
...latestLocalState.current,
|
|
98380
|
+
userName,
|
|
98381
|
+
userColor,
|
|
98382
|
+
userAvatar,
|
|
98383
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
98384
|
+
};
|
|
98385
|
+
awareness.setLocalStateField("presence", state2);
|
|
98386
|
+
lastBroadcastRef.current = Date.now();
|
|
98387
|
+
};
|
|
98388
|
+
if (elapsed >= BROADCAST_THROTTLE_MS) {
|
|
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) {
|
|
97233
98427
|
return;
|
|
97234
98428
|
}
|
|
97235
|
-
const
|
|
97236
|
-
|
|
97237
|
-
|
|
97238
|
-
p3.onUpdateTextStyle({ bold: !ts?.bold });
|
|
97239
|
-
break;
|
|
97240
|
-
case "Italic":
|
|
97241
|
-
p3.onUpdateTextStyle({ italic: !ts?.italic });
|
|
97242
|
-
break;
|
|
97243
|
-
case "Underline":
|
|
97244
|
-
p3.onUpdateTextStyle({
|
|
97245
|
-
underline: !ts?.underline
|
|
97246
|
-
});
|
|
97247
|
-
break;
|
|
97248
|
-
case "Strikethrough":
|
|
97249
|
-
p3.onUpdateTextStyle({
|
|
97250
|
-
strikethrough: !ts?.strikethrough
|
|
97251
|
-
});
|
|
97252
|
-
break;
|
|
98429
|
+
const raw = state2?.presence;
|
|
98430
|
+
if (!raw || typeof raw !== "object") {
|
|
98431
|
+
return;
|
|
97253
98432
|
}
|
|
97254
|
-
|
|
97255
|
-
|
|
97256
|
-
|
|
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
|
|
97257
98494
|
{
|
|
97258
|
-
|
|
97259
|
-
|
|
97260
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
97261
|
-
onClick: handleClick,
|
|
97262
|
-
className: i3 < a2.length - 1 ? gB : gL,
|
|
97263
|
-
title: b2.t,
|
|
97264
|
-
children: b2.i
|
|
97265
|
-
},
|
|
97266
|
-
b2.t
|
|
98495
|
+
params: config.authToken ? { token: config.authToken } : void 0
|
|
98496
|
+
}
|
|
97267
98497
|
);
|
|
97268
|
-
|
|
97269
|
-
|
|
97270
|
-
|
|
97271
|
-
"
|
|
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",
|
|
97272
98605
|
{
|
|
97273
|
-
|
|
97274
|
-
|
|
97275
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
97276
|
-
className: pill,
|
|
97277
|
-
title: "Font color",
|
|
98606
|
+
transform: `translate(${user.cursorX}, ${user.cursorY})`,
|
|
98607
|
+
"data-testid": `remote-cursor-${user.clientId}`,
|
|
97278
98608
|
children: [
|
|
97279
98609
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97280
|
-
"
|
|
98610
|
+
"path",
|
|
97281
98611
|
{
|
|
97282
|
-
|
|
97283
|
-
|
|
97284
|
-
|
|
97285
|
-
|
|
97286
|
-
|
|
97287
|
-
strokeLinecap: "round",
|
|
97288
|
-
strokeLinejoin: "round",
|
|
97289
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 20h12M9.5 4h5L18 16H6L9.5 4z" })
|
|
98612
|
+
d: "M0 0 L0 16 L4.5 12.5 L8 20 L10.5 19 L7 11.5 L12 11 Z",
|
|
98613
|
+
fill: user.userColor,
|
|
98614
|
+
stroke: "#fff",
|
|
98615
|
+
strokeWidth: 1,
|
|
98616
|
+
opacity: 0.9
|
|
97290
98617
|
}
|
|
97291
98618
|
),
|
|
97292
|
-
/* @__PURE__ */ jsxRuntime.
|
|
98619
|
+
/* @__PURE__ */ jsxRuntime.jsxs("g", { transform: "translate(14, 18)", children: [
|
|
98620
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98621
|
+
"rect",
|
|
98622
|
+
{
|
|
98623
|
+
rx: 3,
|
|
98624
|
+
ry: 3,
|
|
98625
|
+
x: -2,
|
|
98626
|
+
y: -10,
|
|
98627
|
+
width: Math.min(user.userName.length * 7 + 8, 150),
|
|
98628
|
+
height: 16,
|
|
98629
|
+
fill: user.userColor,
|
|
98630
|
+
opacity: 0.85
|
|
98631
|
+
}
|
|
98632
|
+
),
|
|
98633
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98634
|
+
"text",
|
|
98635
|
+
{
|
|
98636
|
+
fill: "#fff",
|
|
98637
|
+
fontSize: 10,
|
|
98638
|
+
fontFamily: "system-ui, sans-serif",
|
|
98639
|
+
fontWeight: 500,
|
|
98640
|
+
dominantBaseline: "central",
|
|
98641
|
+
y: -2,
|
|
98642
|
+
x: 2,
|
|
98643
|
+
children: user.userName.length > 20 ? `${user.userName.slice(0, 18)}...` : user.userName
|
|
98644
|
+
}
|
|
98645
|
+
)
|
|
98646
|
+
] })
|
|
97293
98647
|
]
|
|
98648
|
+
},
|
|
98649
|
+
user.clientId
|
|
98650
|
+
))
|
|
98651
|
+
}
|
|
98652
|
+
);
|
|
98653
|
+
}
|
|
98654
|
+
function getInitials(name) {
|
|
98655
|
+
const parts = name.trim().split(/\s+/);
|
|
98656
|
+
if (parts.length >= 2) {
|
|
98657
|
+
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
98658
|
+
}
|
|
98659
|
+
return name.slice(0, 2).toUpperCase();
|
|
98660
|
+
}
|
|
98661
|
+
function AvatarCircle({
|
|
98662
|
+
name,
|
|
98663
|
+
color,
|
|
98664
|
+
avatar,
|
|
98665
|
+
isLocal
|
|
98666
|
+
}) {
|
|
98667
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
98668
|
+
const initials = getInitials(name);
|
|
98669
|
+
const title = isLocal ? t2("pptx.collaboration.youLabel", { name }) : name;
|
|
98670
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
98671
|
+
"div",
|
|
98672
|
+
{
|
|
98673
|
+
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",
|
|
98674
|
+
style: {
|
|
98675
|
+
backgroundColor: color,
|
|
98676
|
+
borderColor: isLocal ? "#fff" : color
|
|
98677
|
+
},
|
|
98678
|
+
title,
|
|
98679
|
+
"aria-label": title,
|
|
98680
|
+
children: avatar ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
98681
|
+
"img",
|
|
98682
|
+
{
|
|
98683
|
+
src: avatar,
|
|
98684
|
+
alt: "",
|
|
98685
|
+
className: "w-full h-full rounded-full object-cover",
|
|
98686
|
+
onError: (e2) => {
|
|
98687
|
+
e2.target.style.display = "none";
|
|
98688
|
+
}
|
|
97294
98689
|
}
|
|
97295
|
-
)
|
|
97296
|
-
|
|
97297
|
-
|
|
97298
|
-
|
|
98690
|
+
) : initials
|
|
98691
|
+
}
|
|
98692
|
+
);
|
|
98693
|
+
}
|
|
98694
|
+
function UserAvatarBar({
|
|
98695
|
+
remoteUsers,
|
|
98696
|
+
localUserName,
|
|
98697
|
+
localUserColor,
|
|
98698
|
+
localUserAvatar,
|
|
98699
|
+
status,
|
|
98700
|
+
maxVisible = 5
|
|
98701
|
+
}) {
|
|
98702
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
98703
|
+
if (status === "disconnected" || status === "error") {
|
|
98704
|
+
return null;
|
|
98705
|
+
}
|
|
98706
|
+
const allUsers = [
|
|
98707
|
+
{ name: localUserName, color: localUserColor, avatar: localUserAvatar, isLocal: true },
|
|
98708
|
+
...remoteUsers.map((u2) => ({
|
|
98709
|
+
name: u2.userName,
|
|
98710
|
+
color: u2.userColor,
|
|
98711
|
+
avatar: u2.userAvatar,
|
|
98712
|
+
isLocal: false
|
|
98713
|
+
}))
|
|
98714
|
+
];
|
|
98715
|
+
const visible = allUsers.slice(0, maxVisible);
|
|
98716
|
+
const overflow = allUsers.length - maxVisible;
|
|
98717
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
98718
|
+
"div",
|
|
98719
|
+
{
|
|
98720
|
+
"data-testid": "user-avatar-bar",
|
|
98721
|
+
className: "flex items-center px-2",
|
|
98722
|
+
"aria-label": t2("pptx.collaboration.usersConnected", { count: allUsers.length }),
|
|
98723
|
+
children: [
|
|
98724
|
+
visible.map((user, i3) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
98725
|
+
AvatarCircle,
|
|
97299
98726
|
{
|
|
97300
|
-
|
|
97301
|
-
|
|
97302
|
-
|
|
97303
|
-
|
|
97304
|
-
onClick: () => handleColorChange(c2)
|
|
98727
|
+
name: user.name,
|
|
98728
|
+
color: user.color,
|
|
98729
|
+
avatar: user.avatar,
|
|
98730
|
+
isLocal: user.isLocal
|
|
97305
98731
|
},
|
|
97306
|
-
|
|
97307
|
-
))
|
|
97308
|
-
/* @__PURE__ */ jsxRuntime.
|
|
97309
|
-
"
|
|
97310
|
-
{
|
|
97311
|
-
type: "button",
|
|
97312
|
-
className: "w-full text-[10px] text-muted-foreground hover:text-foreground py-1 transition-colors",
|
|
97313
|
-
onMouseDown: (e2) => e2.preventDefault(),
|
|
97314
|
-
onClick: () => colorInputRef.current?.click(),
|
|
97315
|
-
children: "Custom colour\u2026"
|
|
97316
|
-
}
|
|
97317
|
-
),
|
|
97318
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97319
|
-
"input",
|
|
98732
|
+
user.isLocal ? "local" : `remote-${i3}`
|
|
98733
|
+
)),
|
|
98734
|
+
overflow > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
98735
|
+
"div",
|
|
97320
98736
|
{
|
|
97321
|
-
|
|
97322
|
-
|
|
97323
|
-
|
|
97324
|
-
|
|
97325
|
-
|
|
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
|
+
]
|
|
97326
98743
|
}
|
|
97327
98744
|
)
|
|
97328
|
-
]
|
|
97329
|
-
|
|
97330
|
-
|
|
97331
|
-
|
|
97332
|
-
|
|
97333
|
-
|
|
97334
|
-
|
|
97335
|
-
|
|
97336
|
-
|
|
97337
|
-
|
|
97338
|
-
|
|
97339
|
-
|
|
97340
|
-
|
|
97341
|
-
|
|
97342
|
-
|
|
97343
|
-
|
|
97344
|
-
|
|
97345
|
-
|
|
97346
|
-
|
|
97347
|
-
|
|
97348
|
-
|
|
97349
|
-
|
|
97350
|
-
|
|
97351
|
-
|
|
97352
|
-
|
|
97353
|
-
|
|
97354
|
-
|
|
97355
|
-
|
|
97356
|
-
|
|
97357
|
-
|
|
97358
|
-
|
|
97359
|
-
|
|
97360
|
-
|
|
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
|
+
);
|
|
97361
98792
|
}
|
|
97362
98793
|
function CustomShowsControls({
|
|
97363
98794
|
customShows,
|
|
@@ -97605,7 +99036,6 @@ function ModeSwitcher({
|
|
|
97605
99036
|
mode,
|
|
97606
99037
|
onSetMode,
|
|
97607
99038
|
onCloseMasterView,
|
|
97608
|
-
onToggleSlideSorter,
|
|
97609
99039
|
onEnterPresenterView,
|
|
97610
99040
|
onEnterRehearsalMode,
|
|
97611
99041
|
onOpenSetUpSlideShow,
|
|
@@ -97614,64 +99044,33 @@ function ModeSwitcher({
|
|
|
97614
99044
|
showSubtitles
|
|
97615
99045
|
}) {
|
|
97616
99046
|
if (mode === "master") {
|
|
97617
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center gap-
|
|
97618
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center px-2 py-
|
|
99047
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center gap-1.5", children: [
|
|
99048
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center px-2 py-0.5 rounded-sm bg-amber-600/90 text-[10px] text-amber-50", children: "Master View" }),
|
|
97619
99049
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97620
99050
|
"button",
|
|
97621
99051
|
{
|
|
97622
99052
|
type: "button",
|
|
97623
99053
|
onClick: onCloseMasterView,
|
|
97624
|
-
className: "px-2
|
|
99054
|
+
className: "px-2 py-0.5 rounded-sm hover:bg-accent text-[10px] text-foreground transition-colors",
|
|
97625
99055
|
title: "Close master view",
|
|
97626
|
-
children: "Close
|
|
99056
|
+
children: "Close"
|
|
97627
99057
|
}
|
|
97628
99058
|
)
|
|
97629
99059
|
] });
|
|
97630
99060
|
}
|
|
97631
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
97632
|
-
|
|
97633
|
-
|
|
97634
|
-
|
|
97635
|
-
|
|
97636
|
-
|
|
97637
|
-
|
|
97638
|
-
|
|
97639
|
-
|
|
97640
|
-
|
|
97641
|
-
|
|
97642
|
-
|
|
97643
|
-
|
|
97644
|
-
},
|
|
97645
|
-
m2
|
|
97646
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
97647
|
-
"button",
|
|
97648
|
-
{
|
|
97649
|
-
type: "button",
|
|
97650
|
-
onClick: () => onSetMode(m2),
|
|
97651
|
-
className: cn(
|
|
97652
|
-
"px-2 py-1 transition-colors border-l border-border first:border-l-0",
|
|
97653
|
-
mode === m2 ? "bg-primary text-primary-foreground" : "hover:bg-accent text-foreground"
|
|
97654
|
-
),
|
|
97655
|
-
title: `${m2[0].toUpperCase()}${m2.slice(1)} mode`,
|
|
97656
|
-
children: [
|
|
97657
|
-
m2[0].toUpperCase(),
|
|
97658
|
-
m2.slice(1)
|
|
97659
|
-
]
|
|
97660
|
-
},
|
|
97661
|
-
m2
|
|
97662
|
-
)
|
|
97663
|
-
),
|
|
97664
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97665
|
-
"button",
|
|
97666
|
-
{
|
|
97667
|
-
type: "button",
|
|
97668
|
-
onClick: onToggleSlideSorter,
|
|
97669
|
-
className: "px-2 py-1 border-l border-border hover:bg-accent text-foreground transition-colors",
|
|
97670
|
-
title: "Slide sorter",
|
|
97671
|
-
children: "Sorter"
|
|
97672
|
-
}
|
|
97673
|
-
)
|
|
97674
|
-
] });
|
|
99061
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
99062
|
+
PresentDropdown,
|
|
99063
|
+
{
|
|
99064
|
+
isActive: mode === "present",
|
|
99065
|
+
onPresent: () => onSetMode("present"),
|
|
99066
|
+
onPresenterView: onEnterPresenterView,
|
|
99067
|
+
onRehearse: onEnterRehearsalMode,
|
|
99068
|
+
onSetUpSlideShow: onOpenSetUpSlideShow,
|
|
99069
|
+
onBroadcast: onOpenBroadcastDialog,
|
|
99070
|
+
onToggleSubtitles,
|
|
99071
|
+
showSubtitles
|
|
99072
|
+
}
|
|
99073
|
+
);
|
|
97675
99074
|
}
|
|
97676
99075
|
function OverflowMenu(p3) {
|
|
97677
99076
|
const ovAct = (k2) => {
|
|
@@ -97739,14 +99138,12 @@ function OverflowMenu(p3) {
|
|
|
97739
99138
|
] });
|
|
97740
99139
|
}
|
|
97741
99140
|
function ToolbarPrimaryRow(p3) {
|
|
99141
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
97742
99142
|
const {
|
|
97743
99143
|
mode,
|
|
97744
99144
|
canEdit,
|
|
97745
|
-
isNarrowViewport,
|
|
97746
99145
|
isSidebarCollapsed,
|
|
97747
99146
|
isInspectorPaneOpen,
|
|
97748
|
-
isCompactToolbarOpen,
|
|
97749
|
-
scale,
|
|
97750
99147
|
canUndo,
|
|
97751
99148
|
canRedo,
|
|
97752
99149
|
undoLabel,
|
|
@@ -97754,26 +99151,21 @@ function ToolbarPrimaryRow(p3) {
|
|
|
97754
99151
|
findReplaceOpen,
|
|
97755
99152
|
onToggleSidebar,
|
|
97756
99153
|
onToggleInspector,
|
|
97757
|
-
onToggleCompactToolbar,
|
|
97758
|
-
onZoomIn,
|
|
97759
|
-
onZoomOut,
|
|
97760
|
-
onZoomToFit,
|
|
97761
99154
|
onUndo,
|
|
97762
99155
|
onRedo,
|
|
97763
99156
|
onToggleFindReplace
|
|
97764
99157
|
} = p3;
|
|
97765
|
-
|
|
99158
|
+
const collab = useCollaboration();
|
|
99159
|
+
const qab = "p-1 max-md:p-2 max-md:min-h-[40px] max-md:min-w-[40px] rounded-sm transition-colors hover:bg-accent/60 disabled:opacity-40 disabled:cursor-not-allowed active:scale-90 active:opacity-70";
|
|
99160
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5 max-md:gap-0 px-1.5 py-0.5 max-md:px-1", children: [
|
|
97766
99161
|
mode !== "present" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
97767
99162
|
"button",
|
|
97768
99163
|
{
|
|
97769
99164
|
type: "button",
|
|
97770
99165
|
onClick: onToggleSidebar,
|
|
97771
|
-
className: cn(
|
|
97772
|
-
|
|
97773
|
-
|
|
97774
|
-
),
|
|
97775
|
-
title: "Toggle slides panel",
|
|
97776
|
-
"aria-label": "Toggle slides panel",
|
|
99166
|
+
className: cn(qab, !isSidebarCollapsed ? "text-foreground" : "text-muted-foreground"),
|
|
99167
|
+
title: t2("pptx.toolbar.toggleSlidesPanel"),
|
|
99168
|
+
"aria-label": t2("pptx.toolbar.toggleSlidesPanel"),
|
|
97777
99169
|
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPanelLeft, { className: ic2 })
|
|
97778
99170
|
}
|
|
97779
99171
|
),
|
|
@@ -97781,77 +99173,84 @@ function ToolbarPrimaryRow(p3) {
|
|
|
97781
99173
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97782
99174
|
"button",
|
|
97783
99175
|
{
|
|
97784
|
-
|
|
97785
|
-
|
|
97786
|
-
|
|
97787
|
-
|
|
97788
|
-
|
|
97789
|
-
|
|
97790
|
-
|
|
97791
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
97792
|
-
"button",
|
|
97793
|
-
{
|
|
97794
|
-
onClick: onZoomToFit,
|
|
97795
|
-
className: "px-1.5 py-1 max-md:min-h-[44px] rounded bg-muted hover:bg-accent text-[11px] text-muted-foreground tabular-nums min-w-[3rem] text-center transition-colors",
|
|
97796
|
-
title: "Zoom to fit",
|
|
97797
|
-
children: [
|
|
97798
|
-
Math.round(scale * 100),
|
|
97799
|
-
"%"
|
|
97800
|
-
]
|
|
99176
|
+
type: "button",
|
|
99177
|
+
onClick: onUndo,
|
|
99178
|
+
disabled: !canEdit || !canUndo,
|
|
99179
|
+
className: cn(qab, "text-muted-foreground"),
|
|
99180
|
+
title: undoLabel ? t2("pptx.toolbar.undoAction", { action: undoLabel }) : t2("pptx.toolbar.undo"),
|
|
99181
|
+
"aria-label": t2("pptx.toolbar.undo"),
|
|
99182
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuUndo, { className: ics })
|
|
97801
99183
|
}
|
|
97802
99184
|
),
|
|
97803
99185
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97804
99186
|
"button",
|
|
97805
99187
|
{
|
|
97806
|
-
|
|
97807
|
-
|
|
97808
|
-
|
|
97809
|
-
|
|
97810
|
-
|
|
99188
|
+
type: "button",
|
|
99189
|
+
onClick: onRedo,
|
|
99190
|
+
disabled: !canEdit || !canRedo,
|
|
99191
|
+
className: cn(qab, "text-muted-foreground"),
|
|
99192
|
+
title: redoLabel ? t2("pptx.toolbar.redoAction", { action: redoLabel }) : t2("pptx.toolbar.redo"),
|
|
99193
|
+
"aria-label": t2("pptx.toolbar.redo"),
|
|
99194
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuRedo, { className: ics })
|
|
97811
99195
|
}
|
|
97812
99196
|
),
|
|
97813
|
-
sep,
|
|
97814
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: grp, children: [
|
|
97815
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97816
|
-
"button",
|
|
97817
|
-
{
|
|
97818
|
-
type: "button",
|
|
97819
|
-
onClick: onUndo,
|
|
97820
|
-
disabled: !canEdit || !canUndo,
|
|
97821
|
-
className: gB,
|
|
97822
|
-
title: undoLabel ? `Undo: ${undoLabel}` : "Undo",
|
|
97823
|
-
"aria-label": "Undo",
|
|
97824
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuUndo, { className: ics })
|
|
97825
|
-
}
|
|
97826
|
-
),
|
|
97827
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97828
|
-
"button",
|
|
97829
|
-
{
|
|
97830
|
-
type: "button",
|
|
97831
|
-
onClick: onRedo,
|
|
97832
|
-
disabled: !canEdit || !canRedo,
|
|
97833
|
-
className: gL,
|
|
97834
|
-
title: redoLabel ? `Redo: ${redoLabel}` : "Redo",
|
|
97835
|
-
"aria-label": "Redo",
|
|
97836
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuRedo, { className: ics })
|
|
97837
|
-
}
|
|
97838
|
-
)
|
|
97839
|
-
] }),
|
|
97840
99197
|
(mode === "edit" || mode === "master") && /* @__PURE__ */ jsxRuntime.jsx(
|
|
97841
99198
|
"button",
|
|
97842
99199
|
{
|
|
97843
99200
|
type: "button",
|
|
97844
99201
|
onClick: onToggleFindReplace,
|
|
97845
99202
|
className: cn(
|
|
97846
|
-
|
|
97847
|
-
|
|
99203
|
+
qab,
|
|
99204
|
+
"max-md:hidden",
|
|
99205
|
+
findReplaceOpen ? "text-foreground" : "text-muted-foreground"
|
|
97848
99206
|
),
|
|
97849
|
-
title: "
|
|
97850
|
-
"aria-label": "
|
|
99207
|
+
title: t2("pptx.findReplace.title"),
|
|
99208
|
+
"aria-label": t2("pptx.findReplace.title"),
|
|
97851
99209
|
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuSearch, { className: ics })
|
|
97852
99210
|
}
|
|
97853
99211
|
),
|
|
97854
99212
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-2 max-md:min-w-1" }),
|
|
99213
|
+
(mode === "edit" || mode === "master") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
99214
|
+
"button",
|
|
99215
|
+
{
|
|
99216
|
+
type: "button",
|
|
99217
|
+
onClick: p3.onToggleComments,
|
|
99218
|
+
className: cn(
|
|
99219
|
+
qab,
|
|
99220
|
+
"max-md:hidden",
|
|
99221
|
+
p3.isCommentsPanelOpen ? "text-foreground" : "text-muted-foreground"
|
|
99222
|
+
),
|
|
99223
|
+
title: t2("pptx.toolbar.comments"),
|
|
99224
|
+
"aria-label": t2("pptx.toolbar.comments"),
|
|
99225
|
+
children: [
|
|
99226
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuMessageSquare, { className: ics }),
|
|
99227
|
+
(p3.slideCommentCount ?? 0) > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 flex items-center justify-center w-3.5 h-3.5 rounded-full bg-primary text-[8px] text-primary-foreground leading-none", children: p3.slideCommentCount })
|
|
99228
|
+
]
|
|
99229
|
+
}
|
|
99230
|
+
),
|
|
99231
|
+
collab && (collab.status === "connected" || collab.status === "connecting") && collab.remoteUsers.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center -space-x-1.5 mx-1", children: [
|
|
99232
|
+
collab.remoteUsers.slice(0, 4).map((user) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
99233
|
+
"div",
|
|
99234
|
+
{
|
|
99235
|
+
className: "w-6 h-6 rounded-full border-2 border-background flex items-center justify-center text-[8px] font-semibold text-white shrink-0",
|
|
99236
|
+
style: { backgroundColor: user.userColor },
|
|
99237
|
+
title: user.userName,
|
|
99238
|
+
children: user.userAvatar ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
99239
|
+
"img",
|
|
99240
|
+
{
|
|
99241
|
+
src: user.userAvatar,
|
|
99242
|
+
alt: user.userName,
|
|
99243
|
+
className: "w-full h-full rounded-full object-cover"
|
|
99244
|
+
}
|
|
99245
|
+
) : user.userName.slice(0, 2).toUpperCase()
|
|
99246
|
+
},
|
|
99247
|
+
user.clientId
|
|
99248
|
+
)),
|
|
99249
|
+
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: [
|
|
99250
|
+
"+",
|
|
99251
|
+
collab.remoteUsers.length - 4
|
|
99252
|
+
] })
|
|
99253
|
+
] }),
|
|
97855
99254
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97856
99255
|
ModeSwitcher,
|
|
97857
99256
|
{
|
|
@@ -97882,40 +99281,80 @@ function ToolbarPrimaryRow(p3) {
|
|
|
97882
99281
|
}
|
|
97883
99282
|
),
|
|
97884
99283
|
sep,
|
|
97885
|
-
(mode === "edit" || mode === "master") && /* @__PURE__ */ jsxRuntime.
|
|
99284
|
+
(mode === "edit" || mode === "master") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
97886
99285
|
"button",
|
|
97887
99286
|
{
|
|
97888
99287
|
type: "button",
|
|
97889
|
-
onClick:
|
|
99288
|
+
onClick: p3.onOpenShareDialog ?? p3.onPackageForSharing,
|
|
97890
99289
|
className: cn(
|
|
97891
|
-
"
|
|
97892
|
-
|
|
99290
|
+
"relative inline-flex items-center gap-1 px-2.5 py-1 rounded-sm text-[11px] font-medium transition-colors",
|
|
99291
|
+
collab && collab.status === "connected" ? "bg-green-600 hover:bg-green-500 text-white" : "bg-primary hover:bg-primary/90 text-primary-foreground"
|
|
97893
99292
|
),
|
|
97894
|
-
title: "
|
|
97895
|
-
"aria-label": "
|
|
99293
|
+
title: collab && collab.status === "connected" ? t2("pptx.toolbar.sharingUsers", { count: collab.connectedCount }) : t2("pptx.toolbar.share"),
|
|
99294
|
+
"aria-label": t2("pptx.toolbar.share"),
|
|
99295
|
+
children: [
|
|
99296
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuShare2, { className: "w-3 h-3" }),
|
|
99297
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-md:hidden", children: collab && collab.status === "connected" ? t2("pptx.toolbar.sharingCount", { count: collab.connectedCount }) : t2("pptx.toolbar.share") })
|
|
99298
|
+
]
|
|
99299
|
+
}
|
|
99300
|
+
),
|
|
99301
|
+
(mode === "edit" || mode === "master") && /* @__PURE__ */ jsxRuntime.jsx(
|
|
99302
|
+
"button",
|
|
99303
|
+
{
|
|
99304
|
+
type: "button",
|
|
99305
|
+
onClick: onToggleInspector,
|
|
99306
|
+
className: cn(qab, isInspectorPaneOpen ? "text-foreground" : "text-muted-foreground"),
|
|
99307
|
+
title: t2("pptx.toolbar.toggleInspector"),
|
|
99308
|
+
"aria-label": t2("pptx.toolbar.toggleInspector"),
|
|
97896
99309
|
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPanelRight, { className: ic2 })
|
|
97897
99310
|
}
|
|
97898
99311
|
),
|
|
97899
|
-
|
|
97900
|
-
/* @__PURE__ */ jsxRuntime.jsx(OverflowMenu, { ...p3 }),
|
|
97901
|
-
isNarrowViewport && (mode === "edit" || mode === "master") && /* @__PURE__ */ jsxRuntime.jsx(
|
|
99312
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97902
99313
|
"button",
|
|
97903
99314
|
{
|
|
97904
99315
|
type: "button",
|
|
97905
|
-
onClick:
|
|
97906
|
-
className: cn(
|
|
97907
|
-
|
|
97908
|
-
|
|
97909
|
-
)
|
|
97910
|
-
title: "Toggle editing tools",
|
|
97911
|
-
children: isCompactToolbarOpen ? "Less" : "Tools"
|
|
99316
|
+
onClick: p3.onOpenSettings ?? p3.onToggleShortcuts,
|
|
99317
|
+
className: cn(qab, "text-muted-foreground"),
|
|
99318
|
+
title: t2("pptx.toolbar.settingsShortcuts"),
|
|
99319
|
+
"aria-label": t2("pptx.toolbar.settings"),
|
|
99320
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuSettings, { className: ics })
|
|
97912
99321
|
}
|
|
97913
|
-
)
|
|
99322
|
+
),
|
|
99323
|
+
!canEdit && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center px-2 py-0.5 rounded-sm bg-amber-600/90 text-[10px] text-amber-50", children: t2("pptx.toolbar.readOnly") }),
|
|
99324
|
+
/* @__PURE__ */ jsxRuntime.jsx(OverflowMenu, { ...p3 })
|
|
97914
99325
|
] });
|
|
97915
99326
|
}
|
|
97916
99327
|
function ViewSection(p3) {
|
|
97917
99328
|
const { t: t2 } = reactI18next.useTranslation();
|
|
97918
99329
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
99330
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
99331
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
99332
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, title: "Normal view", children: "Normal" }),
|
|
99333
|
+
p3.onToggleSlideSorter ? /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, onClick: p3.onToggleSlideSorter, title: "Slide Sorter view", children: "Slide Sorter" }) : /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, title: "Slide Sorter view", children: "Slide Sorter" }),
|
|
99334
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, title: "Reading View", children: "Reading View" })
|
|
99335
|
+
] }),
|
|
99336
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Presentation Views" })
|
|
99337
|
+
] }),
|
|
99338
|
+
sep,
|
|
99339
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
99340
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
99341
|
+
"button",
|
|
99342
|
+
{
|
|
99343
|
+
onClick: p3.onEnterMasterView,
|
|
99344
|
+
disabled: !p3.canEdit,
|
|
99345
|
+
className: pill,
|
|
99346
|
+
title: "Edit slide masters and layouts",
|
|
99347
|
+
children: "Slide Master"
|
|
99348
|
+
}
|
|
99349
|
+
) }),
|
|
99350
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Master Views" })
|
|
99351
|
+
] }),
|
|
99352
|
+
sep,
|
|
99353
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
|
|
99354
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", children: p3.onZoomToFit && /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, onClick: p3.onZoomToFit, title: "Zoom to fit slide in window", children: "Zoom to Fit" }) }),
|
|
99355
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Zoom" })
|
|
99356
|
+
] }),
|
|
99357
|
+
sep,
|
|
97919
99358
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97920
99359
|
"button",
|
|
97921
99360
|
{
|
|
@@ -98008,60 +99447,105 @@ function ViewSection(p3) {
|
|
|
98008
99447
|
title: "Toggle spell check",
|
|
98009
99448
|
children: "Spell"
|
|
98010
99449
|
}
|
|
98011
|
-
),
|
|
98012
|
-
sep,
|
|
98013
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
98014
|
-
"button",
|
|
98015
|
-
{
|
|
98016
|
-
onClick: p3.onEnterMasterView,
|
|
98017
|
-
disabled: !p3.canEdit,
|
|
98018
|
-
className: pill,
|
|
98019
|
-
title: "Edit slide masters and layouts",
|
|
98020
|
-
children: "Slide Master"
|
|
98021
|
-
}
|
|
98022
99450
|
)
|
|
98023
99451
|
] });
|
|
98024
99452
|
}
|
|
98025
99453
|
function Toolbar(p3) {
|
|
98026
99454
|
const { mode, isNarrowViewport, isCompactToolbarOpen, toolbarSection, onSetToolbarSection } = p3;
|
|
99455
|
+
const sFil = toolbarSection === "file";
|
|
98027
99456
|
const sHome = toolbarSection === "home";
|
|
98028
|
-
const sIns =
|
|
99457
|
+
const sIns = toolbarSection === "insert";
|
|
98029
99458
|
const sTxt = sHome || toolbarSection === "text";
|
|
98030
99459
|
const sArr = toolbarSection === "arrange";
|
|
98031
99460
|
const sDrw = toolbarSection === "draw";
|
|
98032
99461
|
const sDes = toolbarSection === "design";
|
|
98033
99462
|
const sTrn = toolbarSection === "transitions";
|
|
99463
|
+
const sAni = toolbarSection === "animations";
|
|
99464
|
+
const sSlw = toolbarSection === "slideShow";
|
|
98034
99465
|
const sRev = toolbarSection === "review";
|
|
98035
99466
|
const sViw = toolbarSection === "view";
|
|
99467
|
+
const sHlp = toolbarSection === "help";
|
|
99468
|
+
const showRibbon = mode === "edit" || mode === "master";
|
|
98036
99469
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
98037
99470
|
"div",
|
|
98038
99471
|
{
|
|
98039
99472
|
role: "toolbar",
|
|
98040
99473
|
"aria-label": "Presentation toolbar",
|
|
98041
|
-
className: "relative z-20
|
|
99474
|
+
className: "relative z-20 border-b border-border bg-secondary/50 overflow-visible",
|
|
98042
99475
|
children: [
|
|
98043
99476
|
/* @__PURE__ */ jsxRuntime.jsx(ToolbarPrimaryRow, { ...p3 }),
|
|
98044
|
-
|
|
99477
|
+
showRibbon && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center border-b border-border/60 px-1 max-md:overflow-x-auto max-md:scrollbar-none", children: [
|
|
99478
|
+
TOOLBAR_SECTIONS.map((s) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
99479
|
+
"button",
|
|
99480
|
+
{
|
|
99481
|
+
type: "button",
|
|
99482
|
+
onClick: () => onSetToolbarSection(s.id),
|
|
99483
|
+
className: cn(
|
|
99484
|
+
"relative px-3.5 py-2 text-[12px] font-medium whitespace-nowrap transition-colors max-md:min-h-[36px] max-md:px-3",
|
|
99485
|
+
toolbarSection === s.id ? s.id === "file" ? "text-primary-foreground bg-primary/80 rounded-sm" : "text-foreground after:absolute after:-bottom-px after:left-0 after:right-0 after:h-[2.5px] after:bg-primary" : s.id === "file" ? "text-primary hover:bg-primary/15 rounded-sm" : "text-muted-foreground hover:text-foreground hover:bg-accent/30"
|
|
99486
|
+
),
|
|
99487
|
+
children: s.label
|
|
99488
|
+
},
|
|
99489
|
+
s.id
|
|
99490
|
+
)),
|
|
99491
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
|
|
99492
|
+
isNarrowViewport && /* @__PURE__ */ jsxRuntime.jsx(
|
|
99493
|
+
"button",
|
|
99494
|
+
{
|
|
99495
|
+
type: "button",
|
|
99496
|
+
onClick: p3.onToggleCompactToolbar,
|
|
99497
|
+
className: cn(
|
|
99498
|
+
"px-2 py-1 rounded text-[11px] transition-colors mr-1",
|
|
99499
|
+
isCompactToolbarOpen ? "bg-primary/80 text-primary-foreground" : "text-muted-foreground hover:text-foreground"
|
|
99500
|
+
),
|
|
99501
|
+
title: "Toggle ribbon",
|
|
99502
|
+
children: isCompactToolbarOpen ? "Collapse" : "Expand"
|
|
99503
|
+
}
|
|
99504
|
+
)
|
|
99505
|
+
] }),
|
|
99506
|
+
showRibbon && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
98045
99507
|
"div",
|
|
98046
99508
|
{
|
|
98047
99509
|
className: cn(
|
|
98048
|
-
"flex items-center gap-1.5
|
|
99510
|
+
"flex items-center gap-1.5 px-2 py-1 max-md:px-1 max-md:py-0.5 overflow-visible flex-nowrap",
|
|
98049
99511
|
isNarrowViewport && !isCompactToolbarOpen && "hidden"
|
|
98050
99512
|
),
|
|
98051
99513
|
children: [
|
|
98052
|
-
|
|
98053
|
-
|
|
99514
|
+
sFil && /* @__PURE__ */ jsxRuntime.jsx(
|
|
99515
|
+
FileSection,
|
|
98054
99516
|
{
|
|
98055
|
-
|
|
98056
|
-
|
|
98057
|
-
|
|
98058
|
-
|
|
98059
|
-
|
|
98060
|
-
|
|
98061
|
-
|
|
98062
|
-
|
|
98063
|
-
|
|
98064
|
-
|
|
99517
|
+
onExportPng: p3.onExportPng,
|
|
99518
|
+
onExportPdf: p3.onExportPdf,
|
|
99519
|
+
onExportVideo: p3.onExportVideo,
|
|
99520
|
+
onExportGif: p3.onExportGif,
|
|
99521
|
+
onPackageForSharing: p3.onPackageForSharing,
|
|
99522
|
+
onSaveAsPpsx: p3.onSaveAsPpsx,
|
|
99523
|
+
onSaveAsPptm: p3.onSaveAsPptm,
|
|
99524
|
+
hasMacros: p3.hasMacros,
|
|
99525
|
+
onCopySlideAsImage: p3.onCopySlideAsImage,
|
|
99526
|
+
onPrint: p3.onPrint,
|
|
99527
|
+
onOpenDocumentProperties: p3.onOpenDocumentProperties,
|
|
99528
|
+
onOpenPasswordProtection: p3.onOpenPasswordProtection,
|
|
99529
|
+
onOpenFontEmbedding: p3.onOpenFontEmbedding,
|
|
99530
|
+
onOpenDigitalSignatures: p3.onOpenDigitalSignatures
|
|
99531
|
+
}
|
|
99532
|
+
),
|
|
99533
|
+
sHome && /* @__PURE__ */ jsxRuntime.jsx(
|
|
99534
|
+
HomeSection,
|
|
99535
|
+
{
|
|
99536
|
+
canEdit: p3.canEdit,
|
|
99537
|
+
clipboardPayload: p3.clipboardPayload,
|
|
99538
|
+
formatPainterActive: p3.formatPainterActive,
|
|
99539
|
+
onCopy: p3.onCopy,
|
|
99540
|
+
onCut: p3.onCut,
|
|
99541
|
+
onPaste: p3.onPaste,
|
|
99542
|
+
onToggleFormatPainter: p3.onToggleFormatPainter,
|
|
99543
|
+
layoutOptions: p3.layoutOptions,
|
|
99544
|
+
onInsertSlideFromLayout: p3.onInsertSlideFromLayout,
|
|
99545
|
+
selectedElement: p3.selectedElement,
|
|
99546
|
+
onUpdateTextStyle: p3.onUpdateTextStyle
|
|
99547
|
+
}
|
|
99548
|
+
),
|
|
98065
99549
|
sIns && /* @__PURE__ */ jsxRuntime.jsx(
|
|
98066
99550
|
InsertSection,
|
|
98067
99551
|
{
|
|
@@ -98124,7 +99608,10 @@ function Toolbar(p3) {
|
|
|
98124
99608
|
onToggleThemeGallery: p3.onToggleThemeGallery,
|
|
98125
99609
|
isThemeGalleryOpen: p3.isThemeGalleryOpen,
|
|
98126
99610
|
onToggleThemeEditor: p3.onToggleThemeEditor,
|
|
98127
|
-
isThemeEditorOpen: p3.isThemeEditorOpen
|
|
99611
|
+
isThemeEditorOpen: p3.isThemeEditorOpen,
|
|
99612
|
+
onOpenDocumentProperties: p3.onOpenDocumentProperties,
|
|
99613
|
+
onToggleInspector: p3.onToggleInspector,
|
|
99614
|
+
isInspectorPaneOpen: p3.isInspectorPaneOpen
|
|
98128
99615
|
}
|
|
98129
99616
|
),
|
|
98130
99617
|
sTrn && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -98134,6 +99621,33 @@ function Toolbar(p3) {
|
|
|
98134
99621
|
onToggleInspector: p3.onToggleInspector
|
|
98135
99622
|
}
|
|
98136
99623
|
),
|
|
99624
|
+
sAni && /* @__PURE__ */ jsxRuntime.jsx(
|
|
99625
|
+
AnimationsSection,
|
|
99626
|
+
{
|
|
99627
|
+
canEdit: p3.canEdit,
|
|
99628
|
+
selectedElement: p3.selectedElement,
|
|
99629
|
+
isInspectorPaneOpen: p3.isInspectorPaneOpen,
|
|
99630
|
+
onToggleInspector: p3.onToggleInspector
|
|
99631
|
+
}
|
|
99632
|
+
),
|
|
99633
|
+
sSlw && /* @__PURE__ */ jsxRuntime.jsx(
|
|
99634
|
+
SlideShowSection,
|
|
99635
|
+
{
|
|
99636
|
+
onPresent: () => p3.onSetMode("present"),
|
|
99637
|
+
onEnterPresenterView: p3.onEnterPresenterView ?? (() => {
|
|
99638
|
+
}),
|
|
99639
|
+
onEnterRehearsalMode: p3.onEnterRehearsalMode ?? (() => {
|
|
99640
|
+
}),
|
|
99641
|
+
onOpenSetUpSlideShow: p3.onOpenSetUpSlideShow ?? (() => {
|
|
99642
|
+
}),
|
|
99643
|
+
onOpenBroadcastDialog: p3.onOpenBroadcastDialog ?? (() => {
|
|
99644
|
+
}),
|
|
99645
|
+
onToggleSubtitles: p3.onToggleSubtitles ?? (() => {
|
|
99646
|
+
}),
|
|
99647
|
+
showSubtitles: p3.showSubtitles ?? false,
|
|
99648
|
+
onSetMode: p3.onSetMode
|
|
99649
|
+
}
|
|
99650
|
+
),
|
|
98137
99651
|
sRev && /* @__PURE__ */ jsxRuntime.jsx(
|
|
98138
99652
|
ReviewSection,
|
|
98139
99653
|
{
|
|
@@ -98169,7 +99683,29 @@ function Toolbar(p3) {
|
|
|
98169
99683
|
eyedropperActive: p3.eyedropperActive,
|
|
98170
99684
|
onToggleEyedropper: p3.onToggleEyedropper
|
|
98171
99685
|
}
|
|
98172
|
-
)
|
|
99686
|
+
),
|
|
99687
|
+
sHlp && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
99688
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
99689
|
+
"button",
|
|
99690
|
+
{
|
|
99691
|
+
type: "button",
|
|
99692
|
+
onClick: p3.onToggleShortcuts,
|
|
99693
|
+
className: pill,
|
|
99694
|
+
title: "Keyboard shortcuts",
|
|
99695
|
+
children: "Keyboard Shortcuts"
|
|
99696
|
+
}
|
|
99697
|
+
),
|
|
99698
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
99699
|
+
"button",
|
|
99700
|
+
{
|
|
99701
|
+
type: "button",
|
|
99702
|
+
onClick: p3.onRunAccessibilityCheck,
|
|
99703
|
+
className: pill,
|
|
99704
|
+
title: "Accessibility check",
|
|
99705
|
+
children: "Accessibility"
|
|
99706
|
+
}
|
|
99707
|
+
)
|
|
99708
|
+
] })
|
|
98173
99709
|
]
|
|
98174
99710
|
}
|
|
98175
99711
|
)
|
|
@@ -105590,6 +107126,333 @@ function BroadcastDialog({
|
|
|
105590
107126
|
] }) })
|
|
105591
107127
|
] });
|
|
105592
107128
|
}
|
|
107129
|
+
function getInitials2(name) {
|
|
107130
|
+
const parts = name.trim().split(/\s+/);
|
|
107131
|
+
if (parts.length >= 2) {
|
|
107132
|
+
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
107133
|
+
}
|
|
107134
|
+
return name.slice(0, 2).toUpperCase();
|
|
107135
|
+
}
|
|
107136
|
+
function ShareDialog({
|
|
107137
|
+
open,
|
|
107138
|
+
onClose,
|
|
107139
|
+
activeCollaboration,
|
|
107140
|
+
onStartCollaboration,
|
|
107141
|
+
onStopCollaboration,
|
|
107142
|
+
preconfigured,
|
|
107143
|
+
defaultRoomId,
|
|
107144
|
+
defaultUserName,
|
|
107145
|
+
defaultServerUrl
|
|
107146
|
+
}) {
|
|
107147
|
+
const collab = useCollaboration();
|
|
107148
|
+
const isActive = collab !== null && collab.status !== "disconnected" && collab.status !== "error";
|
|
107149
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
107150
|
+
const [roomId, setRoomId] = React10.useState(defaultRoomId ?? "");
|
|
107151
|
+
const [userName, setUserName] = React10.useState(defaultUserName ?? "");
|
|
107152
|
+
const [serverUrl, setServerUrl] = React10.useState(defaultServerUrl ?? "");
|
|
107153
|
+
const [copied, setCopied] = React10.useState(false);
|
|
107154
|
+
const dialogRef = React10.useRef(null);
|
|
107155
|
+
React10.useEffect(() => {
|
|
107156
|
+
if (activeCollaboration) {
|
|
107157
|
+
setRoomId(activeCollaboration.roomId);
|
|
107158
|
+
setUserName(activeCollaboration.userName);
|
|
107159
|
+
setServerUrl(activeCollaboration.serverUrl);
|
|
107160
|
+
}
|
|
107161
|
+
}, [activeCollaboration]);
|
|
107162
|
+
React10.useEffect(() => {
|
|
107163
|
+
if (!open) {
|
|
107164
|
+
return;
|
|
107165
|
+
}
|
|
107166
|
+
function handleKeyDown(e2) {
|
|
107167
|
+
if (e2.key === "Escape") {
|
|
107168
|
+
onClose();
|
|
107169
|
+
}
|
|
107170
|
+
}
|
|
107171
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
107172
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
107173
|
+
}, [open, onClose]);
|
|
107174
|
+
React10.useEffect(() => {
|
|
107175
|
+
if (open && dialogRef.current) {
|
|
107176
|
+
dialogRef.current.focus();
|
|
107177
|
+
}
|
|
107178
|
+
}, [open]);
|
|
107179
|
+
const handleCopyRoomId = React10.useCallback(() => {
|
|
107180
|
+
const config = activeCollaboration ?? { roomId, serverUrl };
|
|
107181
|
+
const shareUrl = typeof window !== "undefined" ? `${window.location.origin}${window.location.pathname}?room=${encodeURIComponent(config.roomId)}&server=${encodeURIComponent(config.serverUrl)}` : config.roomId;
|
|
107182
|
+
void navigator.clipboard.writeText(shareUrl).then(() => {
|
|
107183
|
+
setCopied(true);
|
|
107184
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
107185
|
+
return void 0;
|
|
107186
|
+
});
|
|
107187
|
+
}, [activeCollaboration, roomId, serverUrl]);
|
|
107188
|
+
const handleStartSharing = React10.useCallback(() => {
|
|
107189
|
+
if (!roomId.trim() || !userName.trim()) {
|
|
107190
|
+
return;
|
|
107191
|
+
}
|
|
107192
|
+
onStartCollaboration?.({
|
|
107193
|
+
roomId: roomId.trim(),
|
|
107194
|
+
serverUrl: serverUrl.trim(),
|
|
107195
|
+
userName: userName.trim()
|
|
107196
|
+
});
|
|
107197
|
+
}, [roomId, userName, serverUrl, onStartCollaboration]);
|
|
107198
|
+
const canStart = roomId.trim().length > 0 && userName.trim().length > 0 && serverUrl.trim().length > 0;
|
|
107199
|
+
if (!open) {
|
|
107200
|
+
return null;
|
|
107201
|
+
}
|
|
107202
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
107203
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107204
|
+
"button",
|
|
107205
|
+
{
|
|
107206
|
+
type: "button",
|
|
107207
|
+
className: "fixed inset-0 z-[200] bg-black/50",
|
|
107208
|
+
"aria-label": t2("pptx.share.closeDialog"),
|
|
107209
|
+
onClick: onClose
|
|
107210
|
+
}
|
|
107211
|
+
),
|
|
107212
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-[201] flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
107213
|
+
"div",
|
|
107214
|
+
{
|
|
107215
|
+
ref: dialogRef,
|
|
107216
|
+
role: "dialog",
|
|
107217
|
+
"aria-modal": "true",
|
|
107218
|
+
"aria-label": t2("pptx.share.title"),
|
|
107219
|
+
tabIndex: -1,
|
|
107220
|
+
className: "pointer-events-auto w-full max-w-md rounded-xl border border-border bg-popover text-foreground shadow-2xl outline-none",
|
|
107221
|
+
children: [
|
|
107222
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-5 py-3 border-b border-border", children: [
|
|
107223
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold text-foreground", children: isActive ? t2("pptx.share.collaborationActive") : t2("pptx.share.title") }),
|
|
107224
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107225
|
+
"button",
|
|
107226
|
+
{
|
|
107227
|
+
type: "button",
|
|
107228
|
+
onClick: onClose,
|
|
107229
|
+
className: "text-muted-foreground hover:text-foreground text-lg leading-none",
|
|
107230
|
+
"aria-label": t2("pptx.share.close"),
|
|
107231
|
+
children: "\xD7"
|
|
107232
|
+
}
|
|
107233
|
+
)
|
|
107234
|
+
] }),
|
|
107235
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-5 py-4", children: isActive ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
107236
|
+
ActiveSessionView,
|
|
107237
|
+
{
|
|
107238
|
+
collab,
|
|
107239
|
+
activeCollaboration,
|
|
107240
|
+
copied,
|
|
107241
|
+
onCopyRoomId: handleCopyRoomId,
|
|
107242
|
+
onStopCollaboration
|
|
107243
|
+
}
|
|
107244
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
107245
|
+
StartSessionForm,
|
|
107246
|
+
{
|
|
107247
|
+
roomId,
|
|
107248
|
+
userName,
|
|
107249
|
+
serverUrl,
|
|
107250
|
+
onRoomIdChange: setRoomId,
|
|
107251
|
+
onUserNameChange: setUserName,
|
|
107252
|
+
onServerUrlChange: setServerUrl,
|
|
107253
|
+
preconfigured
|
|
107254
|
+
}
|
|
107255
|
+
) }),
|
|
107256
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 px-5 py-3 border-t border-border", children: [
|
|
107257
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107258
|
+
"button",
|
|
107259
|
+
{
|
|
107260
|
+
type: "button",
|
|
107261
|
+
onClick: onClose,
|
|
107262
|
+
className: "px-3 py-1.5 rounded bg-muted hover:bg-accent text-[12px] text-foreground transition-colors",
|
|
107263
|
+
children: isActive ? t2("pptx.share.close") : t2("pptx.share.cancel")
|
|
107264
|
+
}
|
|
107265
|
+
),
|
|
107266
|
+
!isActive && /* @__PURE__ */ jsxRuntime.jsx(
|
|
107267
|
+
"button",
|
|
107268
|
+
{
|
|
107269
|
+
type: "button",
|
|
107270
|
+
disabled: !canStart,
|
|
107271
|
+
onClick: handleStartSharing,
|
|
107272
|
+
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",
|
|
107273
|
+
children: t2("pptx.share.startSharing")
|
|
107274
|
+
}
|
|
107275
|
+
)
|
|
107276
|
+
] })
|
|
107277
|
+
]
|
|
107278
|
+
}
|
|
107279
|
+
) })
|
|
107280
|
+
] });
|
|
107281
|
+
}
|
|
107282
|
+
function StartSessionForm({
|
|
107283
|
+
roomId,
|
|
107284
|
+
userName,
|
|
107285
|
+
serverUrl,
|
|
107286
|
+
onRoomIdChange,
|
|
107287
|
+
onUserNameChange,
|
|
107288
|
+
onServerUrlChange,
|
|
107289
|
+
preconfigured
|
|
107290
|
+
}) {
|
|
107291
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
107292
|
+
const inputReadOnlyClass = preconfigured ? " opacity-70 cursor-not-allowed" : "";
|
|
107293
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
107294
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[13px] text-muted-foreground leading-relaxed", children: preconfigured ? t2("pptx.share.preconfiguredDescription") : t2("pptx.share.description") }),
|
|
107295
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
107296
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "share-room-id", className: "block text-[12px] font-medium text-foreground", children: t2("pptx.share.sessionName") }),
|
|
107297
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107298
|
+
"input",
|
|
107299
|
+
{
|
|
107300
|
+
id: "share-room-id",
|
|
107301
|
+
type: "text",
|
|
107302
|
+
value: roomId,
|
|
107303
|
+
onChange: (e2) => onRoomIdChange(e2.target.value),
|
|
107304
|
+
readOnly: preconfigured,
|
|
107305
|
+
placeholder: t2("pptx.share.sessionPlaceholder"),
|
|
107306
|
+
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${inputReadOnlyClass}`
|
|
107307
|
+
}
|
|
107308
|
+
),
|
|
107309
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-muted-foreground", children: t2("pptx.share.sessionHint") })
|
|
107310
|
+
] }),
|
|
107311
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
107312
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "share-user-name", className: "block text-[12px] font-medium text-foreground", children: t2("pptx.share.displayName") }),
|
|
107313
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107314
|
+
"input",
|
|
107315
|
+
{
|
|
107316
|
+
id: "share-user-name",
|
|
107317
|
+
type: "text",
|
|
107318
|
+
value: userName,
|
|
107319
|
+
onChange: (e2) => onUserNameChange(e2.target.value),
|
|
107320
|
+
readOnly: preconfigured,
|
|
107321
|
+
placeholder: t2("pptx.share.namePlaceholder"),
|
|
107322
|
+
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${inputReadOnlyClass}`
|
|
107323
|
+
}
|
|
107324
|
+
)
|
|
107325
|
+
] }),
|
|
107326
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
107327
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "share-server-url", className: "block text-[12px] font-medium text-foreground", children: t2("pptx.share.serverLabel") }),
|
|
107328
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107329
|
+
"input",
|
|
107330
|
+
{
|
|
107331
|
+
id: "share-server-url",
|
|
107332
|
+
type: "text",
|
|
107333
|
+
value: serverUrl,
|
|
107334
|
+
onChange: (e2) => onServerUrlChange(e2.target.value),
|
|
107335
|
+
readOnly: preconfigured,
|
|
107336
|
+
placeholder: t2("pptx.share.serverPlaceholder"),
|
|
107337
|
+
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${inputReadOnlyClass}`
|
|
107338
|
+
}
|
|
107339
|
+
)
|
|
107340
|
+
] }),
|
|
107341
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[11px] text-muted-foreground/70 leading-relaxed", children: [
|
|
107342
|
+
"Run",
|
|
107343
|
+
" ",
|
|
107344
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "px-1 py-0.5 rounded bg-muted text-[10px] font-mono", children: "bun run collab" }),
|
|
107345
|
+
" ",
|
|
107346
|
+
"to start the server. Others can join at",
|
|
107347
|
+
" ",
|
|
107348
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "px-1 py-0.5 rounded bg-muted text-[10px] font-mono", children: "?room=SESSION_NAME" })
|
|
107349
|
+
] })
|
|
107350
|
+
] });
|
|
107351
|
+
}
|
|
107352
|
+
function ActiveSessionView({
|
|
107353
|
+
collab,
|
|
107354
|
+
activeCollaboration,
|
|
107355
|
+
copied,
|
|
107356
|
+
onCopyRoomId,
|
|
107357
|
+
onStopCollaboration
|
|
107358
|
+
}) {
|
|
107359
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
107360
|
+
const statusColor = collab.status === "connected" ? "text-green-400" : collab.status === "connecting" ? "text-yellow-400" : "text-red-400";
|
|
107361
|
+
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" });
|
|
107362
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
107363
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
107364
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: statusColor, children: statusIcon }),
|
|
107365
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[13px] font-medium text-foreground capitalize", children: collab.status }),
|
|
107366
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[12px] text-muted-foreground ml-auto flex items-center gap-1", children: [
|
|
107367
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuUsers, { className: "w-3.5 h-3.5" }),
|
|
107368
|
+
t2("pptx.collaboration.userCount", { count: collab.connectedCount })
|
|
107369
|
+
] })
|
|
107370
|
+
] }),
|
|
107371
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
107372
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-[12px] font-medium text-foreground", children: t2("pptx.share.shareLink") }),
|
|
107373
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
107374
|
+
/* @__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: typeof window !== "undefined" ? `${window.location.origin}${window.location.pathname}?room=${encodeURIComponent(collab.config.roomId)}&server=${encodeURIComponent(collab.config.serverUrl)}` : collab.config.roomId }),
|
|
107375
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107376
|
+
"button",
|
|
107377
|
+
{
|
|
107378
|
+
type: "button",
|
|
107379
|
+
onClick: onCopyRoomId,
|
|
107380
|
+
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",
|
|
107381
|
+
title: t2("pptx.share.copyLink"),
|
|
107382
|
+
children: copied ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
107383
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCheck, { className: "w-3.5 h-3.5 text-green-400" }),
|
|
107384
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: t2("pptx.share.copied") })
|
|
107385
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
107386
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuCopy, { className: "w-3.5 h-3.5" }),
|
|
107387
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: t2("pptx.share.copyUrl") })
|
|
107388
|
+
] })
|
|
107389
|
+
}
|
|
107390
|
+
)
|
|
107391
|
+
] }),
|
|
107392
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-muted-foreground", children: t2("pptx.share.shareHint") })
|
|
107393
|
+
] }),
|
|
107394
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 text-[11px] text-muted-foreground", children: [
|
|
107395
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
107396
|
+
t2("pptx.share.room"),
|
|
107397
|
+
" ",
|
|
107398
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-foreground", children: collab.config.roomId })
|
|
107399
|
+
] }),
|
|
107400
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
107401
|
+
t2("pptx.share.server"),
|
|
107402
|
+
" ",
|
|
107403
|
+
/* @__PURE__ */ jsxRuntime.jsx("code", { className: "font-mono text-foreground", children: collab.config.serverUrl })
|
|
107404
|
+
] })
|
|
107405
|
+
] }),
|
|
107406
|
+
collab.remoteUsers.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
107407
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-[12px] font-medium text-foreground", children: t2("pptx.share.connectedUsers") }),
|
|
107408
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded border border-border bg-background divide-y divide-border max-h-[140px] overflow-y-auto", children: [
|
|
107409
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3 py-2", children: [
|
|
107410
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107411
|
+
"div",
|
|
107412
|
+
{
|
|
107413
|
+
className: "w-6 h-6 rounded-full flex items-center justify-center text-[9px] font-semibold text-white shrink-0",
|
|
107414
|
+
style: { backgroundColor: collab.config.userColor ?? "#6366f1" },
|
|
107415
|
+
children: getInitials2(activeCollaboration?.userName ?? collab.config.userName)
|
|
107416
|
+
}
|
|
107417
|
+
),
|
|
107418
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[12px] text-foreground truncate", children: activeCollaboration?.userName ?? collab.config.userName }),
|
|
107419
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground ml-auto", children: t2("pptx.share.you") })
|
|
107420
|
+
] }),
|
|
107421
|
+
collab.remoteUsers.map((user) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-3 py-2", children: [
|
|
107422
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107423
|
+
"div",
|
|
107424
|
+
{
|
|
107425
|
+
className: "w-6 h-6 rounded-full flex items-center justify-center text-[9px] font-semibold text-white shrink-0",
|
|
107426
|
+
style: { backgroundColor: user.userColor },
|
|
107427
|
+
children: user.userAvatar ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
107428
|
+
"img",
|
|
107429
|
+
{
|
|
107430
|
+
src: user.userAvatar,
|
|
107431
|
+
alt: "",
|
|
107432
|
+
className: "w-full h-full rounded-full object-cover"
|
|
107433
|
+
}
|
|
107434
|
+
) : getInitials2(user.userName)
|
|
107435
|
+
}
|
|
107436
|
+
),
|
|
107437
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[12px] text-foreground truncate", children: user.userName }),
|
|
107438
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground ml-auto", children: [
|
|
107439
|
+
"Slide ",
|
|
107440
|
+
user.activeSlideIndex + 1
|
|
107441
|
+
] })
|
|
107442
|
+
] }, user.clientId))
|
|
107443
|
+
] })
|
|
107444
|
+
] }),
|
|
107445
|
+
onStopCollaboration && /* @__PURE__ */ jsxRuntime.jsx(
|
|
107446
|
+
"button",
|
|
107447
|
+
{
|
|
107448
|
+
type: "button",
|
|
107449
|
+
onClick: onStopCollaboration,
|
|
107450
|
+
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",
|
|
107451
|
+
children: t2("pptx.share.stopSharing")
|
|
107452
|
+
}
|
|
107453
|
+
)
|
|
107454
|
+
] });
|
|
107455
|
+
}
|
|
105593
107456
|
|
|
105594
107457
|
// src/viewer/components/hyperlink-edit-types.ts
|
|
105595
107458
|
var ACTION_VERB_MAP = {
|
|
@@ -107490,7 +109353,14 @@ function ViewerBottomPanels({
|
|
|
107490
109353
|
onUpdateNotes,
|
|
107491
109354
|
collaborationSlot,
|
|
107492
109355
|
notesPanelHeight,
|
|
107493
|
-
onResizeBottom
|
|
109356
|
+
onResizeBottom,
|
|
109357
|
+
scale,
|
|
109358
|
+
onZoomIn,
|
|
109359
|
+
onZoomOut,
|
|
109360
|
+
onZoomToFit,
|
|
109361
|
+
mode,
|
|
109362
|
+
onSetMode,
|
|
109363
|
+
onToggleSlideSorter
|
|
107494
109364
|
}) {
|
|
107495
109365
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
107496
109366
|
onResizeBottom && !isSlideNotesCollapsed && /* @__PURE__ */ jsxRuntime.jsx(ResizeHandle, { direction: "vertical", onResize: onResizeBottom }),
|
|
@@ -107506,18 +109376,25 @@ function ViewerBottomPanels({
|
|
|
107506
109376
|
panelHeight: notesPanelHeight
|
|
107507
109377
|
}
|
|
107508
109378
|
),
|
|
107509
|
-
/* @__PURE__ */ jsxRuntime.
|
|
107510
|
-
|
|
107511
|
-
|
|
107512
|
-
|
|
107513
|
-
|
|
107514
|
-
|
|
107515
|
-
|
|
107516
|
-
|
|
107517
|
-
|
|
107518
|
-
|
|
107519
|
-
|
|
107520
|
-
|
|
109379
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
109380
|
+
StatusBar,
|
|
109381
|
+
{
|
|
109382
|
+
slideCount,
|
|
109383
|
+
activeSlideIndex,
|
|
109384
|
+
isDirty,
|
|
109385
|
+
autosaveStatus,
|
|
109386
|
+
scale,
|
|
109387
|
+
onZoomIn,
|
|
109388
|
+
onZoomOut,
|
|
109389
|
+
onZoomToFit,
|
|
109390
|
+
isNotesExpanded: !isSlideNotesCollapsed,
|
|
109391
|
+
onToggleNotes,
|
|
109392
|
+
mode,
|
|
109393
|
+
onSetMode,
|
|
109394
|
+
onToggleSlideSorter,
|
|
109395
|
+
collaborationSlot
|
|
109396
|
+
}
|
|
109397
|
+
)
|
|
107521
109398
|
] });
|
|
107522
109399
|
}
|
|
107523
109400
|
function ViewerInspector({
|
|
@@ -107676,7 +109553,9 @@ function ViewerToolbarSection(props) {
|
|
|
107676
109553
|
ops,
|
|
107677
109554
|
onSetMode,
|
|
107678
109555
|
onEnterPresenterView,
|
|
107679
|
-
onEnterRehearsalMode
|
|
109556
|
+
onEnterRehearsalMode,
|
|
109557
|
+
onOpenSettings,
|
|
109558
|
+
onOpenShareDialog
|
|
107680
109559
|
} = props;
|
|
107681
109560
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
107682
109561
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -107755,12 +109634,14 @@ function ViewerToolbarSection(props) {
|
|
|
107755
109634
|
onExportVideo: exportHandlers.handleExportVideo,
|
|
107756
109635
|
onExportGif: exportHandlers.handleExportGif,
|
|
107757
109636
|
onPackageForSharing: exportHandlers.handlePackageForSharing,
|
|
109637
|
+
onOpenShareDialog,
|
|
107758
109638
|
onSaveAsPpsx: exportHandlers.handleSaveAsPpsx,
|
|
107759
109639
|
onSaveAsPptm: exportHandlers.handleSaveAsPptm,
|
|
107760
109640
|
hasMacros: s.hasMacros,
|
|
107761
109641
|
onCopySlideAsImage: exportHandlers.handleCopySlideAsImage,
|
|
107762
109642
|
onPrint: printHandlers.handlePrint,
|
|
107763
109643
|
onToggleShortcuts: () => s.setIsShortcutHelpOpen((p3) => !p3),
|
|
109644
|
+
onOpenSettings,
|
|
107764
109645
|
onRunAccessibilityCheck: dialogs.handleRunAccessibilityCheck,
|
|
107765
109646
|
onToggleSlideSorter: () => s.setShowSlideSorter((p3) => !p3),
|
|
107766
109647
|
onUpdateTextStyle: ops.updateSelectedTextStyle,
|
|
@@ -107790,7 +109671,12 @@ function ViewerToolbarSection(props) {
|
|
|
107790
109671
|
onToggleThemeGallery: () => s.setIsThemeGalleryOpen((p3) => !p3),
|
|
107791
109672
|
isThemeGalleryOpen: s.isThemeGalleryOpen,
|
|
107792
109673
|
onCompare: propertyHandlers.handleCompare,
|
|
107793
|
-
onToggleComments: () =>
|
|
109674
|
+
onToggleComments: () => {
|
|
109675
|
+
s.setSidebarPanelMode("comments");
|
|
109676
|
+
if (!s.isInspectorPaneOpen) {
|
|
109677
|
+
s.setIsInspectorPaneOpen(true);
|
|
109678
|
+
}
|
|
109679
|
+
},
|
|
107794
109680
|
isCommentsPanelOpen: s.isInspectorPaneOpen,
|
|
107795
109681
|
slideCommentCount: activeSlide?.comments?.length ?? 0,
|
|
107796
109682
|
formatPainterActive: s.formatPainterActive,
|
|
@@ -109537,7 +111423,7 @@ function ViewerCanvasArea(props) {
|
|
|
109537
111423
|
const handleToolbarMouseLeave = React10.useCallback(() => {
|
|
109538
111424
|
toolbarHoveringRef.current = false;
|
|
109539
111425
|
}, []);
|
|
109540
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("main", { "aria-label": "Slide editor", className: "flex-1 min-w-0 relative flex flex-col", children: [
|
|
111426
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("main", { "aria-label": "Slide editor", className: "flex-1 min-w-0 relative flex flex-col bg-background", children: [
|
|
109541
111427
|
findReplace.findReplaceOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
109542
111428
|
FindReplacePanel,
|
|
109543
111429
|
{
|
|
@@ -109907,7 +111793,7 @@ var PRESET_THEMES = [
|
|
|
109907
111793
|
minorFont: "Gill Sans MT"
|
|
109908
111794
|
}
|
|
109909
111795
|
];
|
|
109910
|
-
var
|
|
111796
|
+
var COMMON_FONTS2 = [
|
|
109911
111797
|
"Arial",
|
|
109912
111798
|
"Calibri",
|
|
109913
111799
|
"Calibri Light",
|
|
@@ -110012,15 +111898,15 @@ function ThemeColorSchemeEditor({
|
|
|
110012
111898
|
{
|
|
110013
111899
|
className: THEME_EDITOR_INPUT,
|
|
110014
111900
|
disabled: !canEdit,
|
|
110015
|
-
value:
|
|
111901
|
+
value: COMMON_FONTS2.includes(majorFont) ? majorFont : "__custom__",
|
|
110016
111902
|
onChange: (e2) => {
|
|
110017
111903
|
if (e2.target.value !== "__custom__") {
|
|
110018
111904
|
onMajorFontChange(e2.target.value);
|
|
110019
111905
|
}
|
|
110020
111906
|
},
|
|
110021
111907
|
children: [
|
|
110022
|
-
|
|
110023
|
-
!
|
|
111908
|
+
COMMON_FONTS2.map((f) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: f, children: f }, f)),
|
|
111909
|
+
!COMMON_FONTS2.includes(majorFont) && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "__custom__", children: majorFont })
|
|
110024
111910
|
]
|
|
110025
111911
|
}
|
|
110026
111912
|
)
|
|
@@ -110032,15 +111918,15 @@ function ThemeColorSchemeEditor({
|
|
|
110032
111918
|
{
|
|
110033
111919
|
className: THEME_EDITOR_INPUT,
|
|
110034
111920
|
disabled: !canEdit,
|
|
110035
|
-
value:
|
|
111921
|
+
value: COMMON_FONTS2.includes(minorFont) ? minorFont : "__custom__",
|
|
110036
111922
|
onChange: (e2) => {
|
|
110037
111923
|
if (e2.target.value !== "__custom__") {
|
|
110038
111924
|
onMinorFontChange(e2.target.value);
|
|
110039
111925
|
}
|
|
110040
111926
|
},
|
|
110041
111927
|
children: [
|
|
110042
|
-
|
|
110043
|
-
!
|
|
111928
|
+
COMMON_FONTS2.map((f) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: f, children: f }, f)),
|
|
111929
|
+
!COMMON_FONTS2.includes(minorFont) && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "__custom__", children: minorFont })
|
|
110044
111930
|
]
|
|
110045
111931
|
}
|
|
110046
111932
|
)
|
|
@@ -110906,486 +112792,334 @@ function ViewerMainContent(props) {
|
|
|
110906
112792
|
activeSlideIndex,
|
|
110907
112793
|
selectedElement,
|
|
110908
112794
|
state: state2,
|
|
110909
|
-
comments,
|
|
110910
|
-
ops,
|
|
110911
|
-
manipulation,
|
|
110912
|
-
propertyHandlers,
|
|
110913
|
-
themeHandlers,
|
|
110914
|
-
history,
|
|
110915
|
-
panelWidth: rightPanelWidth,
|
|
110916
|
-
onResizeRight
|
|
110917
|
-
}
|
|
110918
|
-
)
|
|
110919
|
-
] });
|
|
110920
|
-
}
|
|
110921
|
-
|
|
110922
|
-
// src/viewer/hooks/collaboration/sanitize.ts
|
|
110923
|
-
var ROOM_ID_REGEX = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
110924
|
-
function validateRoomId(roomId) {
|
|
110925
|
-
if (!ROOM_ID_REGEX.test(roomId)) {
|
|
110926
|
-
throw new Error(
|
|
110927
|
-
`Invalid collaboration room ID: "${roomId}". Must be 1-128 alphanumeric characters, hyphens, or underscores.`
|
|
110928
|
-
);
|
|
110929
|
-
}
|
|
110930
|
-
return roomId;
|
|
110931
|
-
}
|
|
110932
|
-
function sanitizeUserName(name) {
|
|
110933
|
-
if (typeof name !== "string") {
|
|
110934
|
-
return "Anonymous";
|
|
110935
|
-
}
|
|
110936
|
-
const stripped = name.replace(/<[^>]*>/g, "");
|
|
110937
|
-
const trimmed = stripped.trim().slice(0, 64);
|
|
110938
|
-
return trimmed || "Anonymous";
|
|
110939
|
-
}
|
|
110940
|
-
function clampCursorPosition(value, min2, max2) {
|
|
110941
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
110942
|
-
return 0;
|
|
110943
|
-
}
|
|
110944
|
-
const margin = 20;
|
|
110945
|
-
return Math.max(min2 - margin, Math.min(max2 + margin, value));
|
|
110946
|
-
}
|
|
110947
|
-
var HEX_COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
|
|
110948
|
-
function sanitizeColor(color, fallback = "#6366f1") {
|
|
110949
|
-
if (typeof color !== "string") {
|
|
110950
|
-
return fallback;
|
|
110951
|
-
}
|
|
110952
|
-
return HEX_COLOR_REGEX.test(color) ? color : fallback;
|
|
110953
|
-
}
|
|
110954
|
-
function sanitizeAvatarUrl(url) {
|
|
110955
|
-
if (typeof url !== "string") {
|
|
110956
|
-
return void 0;
|
|
110957
|
-
}
|
|
110958
|
-
try {
|
|
110959
|
-
const parsed = new URL(url);
|
|
110960
|
-
if (parsed.protocol === "https:" || parsed.protocol === "http:" || parsed.protocol === "data:") {
|
|
110961
|
-
return url;
|
|
110962
|
-
}
|
|
110963
|
-
} catch {
|
|
110964
|
-
}
|
|
110965
|
-
return void 0;
|
|
110966
|
-
}
|
|
110967
|
-
function sanitizeSlideIndex(value) {
|
|
110968
|
-
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
110969
|
-
return 0;
|
|
110970
|
-
}
|
|
110971
|
-
return Math.max(0, Math.floor(value));
|
|
110972
|
-
}
|
|
110973
|
-
function sanitizePresence(raw, canvasWidth, canvasHeight) {
|
|
110974
|
-
if (typeof raw.clientId !== "number") {
|
|
110975
|
-
return null;
|
|
110976
|
-
}
|
|
110977
|
-
return {
|
|
110978
|
-
clientId: raw.clientId,
|
|
110979
|
-
userName: sanitizeUserName(raw.userName),
|
|
110980
|
-
userAvatar: sanitizeAvatarUrl(raw.userAvatar),
|
|
110981
|
-
userColor: sanitizeColor(raw.userColor),
|
|
110982
|
-
activeSlideIndex: sanitizeSlideIndex(raw.activeSlideIndex),
|
|
110983
|
-
cursorX: clampCursorPosition(raw.cursorX, 0, canvasWidth),
|
|
110984
|
-
cursorY: clampCursorPosition(raw.cursorY, 0, canvasHeight),
|
|
110985
|
-
lastUpdated: typeof raw.lastUpdated === "string" ? raw.lastUpdated : (/* @__PURE__ */ new Date()).toISOString(),
|
|
110986
|
-
selectedElementId: typeof raw.selectedElementId === "string" ? raw.selectedElementId.slice(0, 128) : void 0
|
|
110987
|
-
};
|
|
110988
|
-
}
|
|
110989
|
-
var BROADCAST_THROTTLE_MS = 50;
|
|
110990
|
-
var STALE_PRESENCE_MS = 3e4;
|
|
110991
|
-
function usePresenceTracking({
|
|
110992
|
-
awareness,
|
|
110993
|
-
localClientId,
|
|
110994
|
-
userName,
|
|
110995
|
-
userColor,
|
|
110996
|
-
userAvatar,
|
|
110997
|
-
canvasWidth,
|
|
110998
|
-
canvasHeight
|
|
110999
|
-
}) {
|
|
111000
|
-
const [remoteUsers, setRemoteUsers] = React10.useState([]);
|
|
111001
|
-
const lastBroadcastRef = React10.useRef(0);
|
|
111002
|
-
const pendingBroadcastRef = React10.useRef(null);
|
|
111003
|
-
const latestLocalState = React10.useRef({});
|
|
111004
|
-
const broadcastPresence = React10.useCallback(
|
|
111005
|
-
(update2) => {
|
|
111006
|
-
if (!awareness) {
|
|
111007
|
-
return;
|
|
111008
|
-
}
|
|
111009
|
-
Object.assign(latestLocalState.current, update2);
|
|
111010
|
-
const now = Date.now();
|
|
111011
|
-
const elapsed = now - lastBroadcastRef.current;
|
|
111012
|
-
const flush = () => {
|
|
111013
|
-
const state2 = {
|
|
111014
|
-
...latestLocalState.current,
|
|
111015
|
-
userName,
|
|
111016
|
-
userColor,
|
|
111017
|
-
userAvatar,
|
|
111018
|
-
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
111019
|
-
};
|
|
111020
|
-
awareness.setLocalStateField("presence", state2);
|
|
111021
|
-
lastBroadcastRef.current = Date.now();
|
|
111022
|
-
};
|
|
111023
|
-
if (elapsed >= BROADCAST_THROTTLE_MS) {
|
|
111024
|
-
if (pendingBroadcastRef.current) {
|
|
111025
|
-
clearTimeout(pendingBroadcastRef.current);
|
|
111026
|
-
pendingBroadcastRef.current = null;
|
|
111027
|
-
}
|
|
111028
|
-
flush();
|
|
111029
|
-
} else if (!pendingBroadcastRef.current) {
|
|
111030
|
-
pendingBroadcastRef.current = setTimeout(() => {
|
|
111031
|
-
pendingBroadcastRef.current = null;
|
|
111032
|
-
flush();
|
|
111033
|
-
}, BROADCAST_THROTTLE_MS - elapsed);
|
|
111034
|
-
}
|
|
111035
|
-
},
|
|
111036
|
-
[awareness, userName, userColor, userAvatar]
|
|
111037
|
-
);
|
|
111038
|
-
React10.useEffect(() => {
|
|
111039
|
-
if (!awareness || localClientId === null) {
|
|
111040
|
-
return;
|
|
111041
|
-
}
|
|
111042
|
-
const handleChange = () => {
|
|
111043
|
-
const now = Date.now();
|
|
111044
|
-
const states = awareness.getStates();
|
|
111045
|
-
const users = [];
|
|
111046
|
-
states.forEach((state2, cid) => {
|
|
111047
|
-
if (cid === localClientId) {
|
|
111048
|
-
return;
|
|
111049
|
-
}
|
|
111050
|
-
const raw = state2?.presence;
|
|
111051
|
-
if (!raw || typeof raw !== "object") {
|
|
111052
|
-
return;
|
|
111053
|
-
}
|
|
111054
|
-
const sanitized = sanitizePresence({ ...raw, clientId: cid }, canvasWidth, canvasHeight);
|
|
111055
|
-
if (!sanitized) {
|
|
111056
|
-
return;
|
|
111057
|
-
}
|
|
111058
|
-
const updatedAt = new Date(sanitized.lastUpdated).getTime();
|
|
111059
|
-
if (Number.isNaN(updatedAt) || now - updatedAt > STALE_PRESENCE_MS) {
|
|
111060
|
-
return;
|
|
111061
|
-
}
|
|
111062
|
-
users.push(sanitized);
|
|
111063
|
-
});
|
|
111064
|
-
setRemoteUsers(users);
|
|
111065
|
-
};
|
|
111066
|
-
awareness.on("change", handleChange);
|
|
111067
|
-
handleChange();
|
|
111068
|
-
return () => {
|
|
111069
|
-
awareness.off("change", handleChange);
|
|
111070
|
-
};
|
|
111071
|
-
}, [awareness, localClientId, canvasWidth, canvasHeight]);
|
|
111072
|
-
React10.useEffect(() => {
|
|
111073
|
-
return () => {
|
|
111074
|
-
if (pendingBroadcastRef.current) {
|
|
111075
|
-
clearTimeout(pendingBroadcastRef.current);
|
|
111076
|
-
}
|
|
111077
|
-
};
|
|
111078
|
-
}, []);
|
|
111079
|
-
return { remoteUsers, broadcastPresence };
|
|
111080
|
-
}
|
|
111081
|
-
function useYjsProvider({ config }) {
|
|
111082
|
-
const [status, setStatus] = React10.useState("disconnected");
|
|
111083
|
-
const [awareness, setAwareness] = React10.useState(null);
|
|
111084
|
-
const [doc2, setDoc] = React10.useState(null);
|
|
111085
|
-
const [clientId, setClientId] = React10.useState(null);
|
|
111086
|
-
const cleanupRef = React10.useRef(null);
|
|
111087
|
-
const init = React10.useCallback(async () => {
|
|
111088
|
-
const roomId = validateRoomId(config.roomId);
|
|
111089
|
-
setStatus("connecting");
|
|
111090
|
-
try {
|
|
111091
|
-
const [Y, { WebsocketProvider: WebsocketProvider2 }] = await Promise.all([Promise.resolve().then(() => (init_yjs(), yjs_exports)), Promise.resolve().then(() => (init_y_websocket(), y_websocket_exports))]);
|
|
111092
|
-
const yDoc = new Y.Doc();
|
|
111093
|
-
const provider = new WebsocketProvider2(
|
|
111094
|
-
config.serverUrl,
|
|
111095
|
-
roomId,
|
|
111096
|
-
yDoc,
|
|
111097
|
-
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
111098
|
-
{
|
|
111099
|
-
params: config.authToken ? { token: config.authToken } : void 0
|
|
111100
|
-
}
|
|
111101
|
-
);
|
|
111102
|
-
const handleStatus = (event) => {
|
|
111103
|
-
if (event.status === "connected") {
|
|
111104
|
-
setStatus("connected");
|
|
111105
|
-
} else if (event.status === "disconnected") {
|
|
111106
|
-
setStatus("disconnected");
|
|
111107
|
-
}
|
|
111108
|
-
};
|
|
111109
|
-
provider.on("status", handleStatus);
|
|
111110
|
-
if (provider.wsconnected) {
|
|
111111
|
-
setStatus("connected");
|
|
112795
|
+
comments,
|
|
112796
|
+
ops,
|
|
112797
|
+
manipulation,
|
|
112798
|
+
propertyHandlers,
|
|
112799
|
+
themeHandlers,
|
|
112800
|
+
history,
|
|
112801
|
+
panelWidth: rightPanelWidth,
|
|
112802
|
+
onResizeRight
|
|
111112
112803
|
}
|
|
111113
|
-
|
|
111114
|
-
|
|
111115
|
-
setClientId(provider.awareness.clientID);
|
|
111116
|
-
cleanupRef.current = () => {
|
|
111117
|
-
provider.off("status", handleStatus);
|
|
111118
|
-
provider.destroy();
|
|
111119
|
-
yDoc.destroy();
|
|
111120
|
-
setDoc(null);
|
|
111121
|
-
setAwareness(null);
|
|
111122
|
-
setClientId(null);
|
|
111123
|
-
setStatus("disconnected");
|
|
111124
|
-
};
|
|
111125
|
-
} catch (err) {
|
|
111126
|
-
console.warn(
|
|
111127
|
-
"[pptx-viewer] Collaboration packages not available:",
|
|
111128
|
-
err instanceof Error ? err.message : err
|
|
111129
|
-
);
|
|
111130
|
-
setStatus("error");
|
|
111131
|
-
}
|
|
111132
|
-
}, [config.roomId, config.serverUrl, config.authToken]);
|
|
111133
|
-
React10.useEffect(() => {
|
|
111134
|
-
init();
|
|
111135
|
-
return () => {
|
|
111136
|
-
cleanupRef.current?.();
|
|
111137
|
-
cleanupRef.current = null;
|
|
111138
|
-
};
|
|
111139
|
-
}, [init]);
|
|
111140
|
-
return { status, awareness, doc: doc2, clientId };
|
|
111141
|
-
}
|
|
111142
|
-
|
|
111143
|
-
// src/viewer/hooks/collaboration/useCollaborativeState.ts
|
|
111144
|
-
function useCollaborativeState({
|
|
111145
|
-
config,
|
|
111146
|
-
canvasWidth,
|
|
111147
|
-
canvasHeight
|
|
111148
|
-
}) {
|
|
111149
|
-
const userColor = sanitizeColor(config.userColor, "#6366f1");
|
|
111150
|
-
const { status, awareness, clientId } = useYjsProvider({ config });
|
|
111151
|
-
const { remoteUsers, broadcastPresence } = usePresenceTracking({
|
|
111152
|
-
awareness,
|
|
111153
|
-
localClientId: clientId,
|
|
111154
|
-
userName: config.userName,
|
|
111155
|
-
userColor,
|
|
111156
|
-
userAvatar: config.userAvatar,
|
|
111157
|
-
canvasWidth,
|
|
111158
|
-
canvasHeight
|
|
111159
|
-
});
|
|
111160
|
-
const connectedCount = status === "connected" ? remoteUsers.length + 1 : remoteUsers.length;
|
|
111161
|
-
return {
|
|
111162
|
-
status,
|
|
111163
|
-
remoteUsers,
|
|
111164
|
-
broadcastPresence,
|
|
111165
|
-
connectedCount,
|
|
111166
|
-
config
|
|
111167
|
-
};
|
|
111168
|
-
}
|
|
111169
|
-
var CollaborationContext = React10.createContext(null);
|
|
111170
|
-
function useCollaboration() {
|
|
111171
|
-
return React10.useContext(CollaborationContext);
|
|
112804
|
+
)
|
|
112805
|
+
] });
|
|
111172
112806
|
}
|
|
111173
|
-
function
|
|
111174
|
-
|
|
111175
|
-
|
|
111176
|
-
|
|
111177
|
-
children
|
|
112807
|
+
function ToggleSwitch({
|
|
112808
|
+
label,
|
|
112809
|
+
enabled,
|
|
112810
|
+
onToggle
|
|
111178
112811
|
}) {
|
|
111179
|
-
|
|
111180
|
-
|
|
111181
|
-
|
|
111182
|
-
|
|
111183
|
-
|
|
111184
|
-
|
|
112812
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between py-2.5 px-3", children: [
|
|
112813
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-foreground", children: label }),
|
|
112814
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112815
|
+
"button",
|
|
112816
|
+
{
|
|
112817
|
+
type: "button",
|
|
112818
|
+
onClick: onToggle,
|
|
112819
|
+
className: cn(
|
|
112820
|
+
"relative inline-flex h-5 w-9 items-center rounded-full transition-colors",
|
|
112821
|
+
enabled ? "bg-primary" : "bg-muted-foreground/30"
|
|
112822
|
+
),
|
|
112823
|
+
role: "switch",
|
|
112824
|
+
"aria-checked": enabled,
|
|
112825
|
+
"aria-label": label,
|
|
112826
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
112827
|
+
"span",
|
|
112828
|
+
{
|
|
112829
|
+
className: cn(
|
|
112830
|
+
"inline-block h-3.5 w-3.5 rounded-full bg-white transition-transform",
|
|
112831
|
+
enabled ? "translate-x-[18px]" : "translate-x-[3px]"
|
|
112832
|
+
)
|
|
112833
|
+
}
|
|
112834
|
+
)
|
|
112835
|
+
}
|
|
112836
|
+
)
|
|
112837
|
+
] });
|
|
111185
112838
|
}
|
|
111186
|
-
function
|
|
111187
|
-
|
|
111188
|
-
|
|
111189
|
-
|
|
111190
|
-
|
|
112839
|
+
function SettingsDialog({
|
|
112840
|
+
isOpen,
|
|
112841
|
+
onClose,
|
|
112842
|
+
spellCheckEnabled = false,
|
|
112843
|
+
onSetSpellCheckEnabled,
|
|
112844
|
+
showGrid = false,
|
|
112845
|
+
onSetShowGrid,
|
|
112846
|
+
showRulers = false,
|
|
112847
|
+
onSetShowRulers,
|
|
112848
|
+
snapToGrid = false,
|
|
112849
|
+
onSetSnapToGrid,
|
|
112850
|
+
reducedMotion = false,
|
|
112851
|
+
onToggleReducedMotion
|
|
111191
112852
|
}) {
|
|
111192
|
-
const
|
|
111193
|
-
|
|
111194
|
-
|
|
111195
|
-
|
|
111196
|
-
|
|
111197
|
-
|
|
111198
|
-
|
|
111199
|
-
|
|
111200
|
-
|
|
111201
|
-
|
|
111202
|
-
width: canvasWidth,
|
|
111203
|
-
height: canvasHeight,
|
|
111204
|
-
viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
|
|
111205
|
-
"aria-hidden": "true",
|
|
111206
|
-
children: visibleUsers.map((user) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
111207
|
-
"g",
|
|
111208
|
-
{
|
|
111209
|
-
transform: `translate(${user.cursorX}, ${user.cursorY})`,
|
|
111210
|
-
"data-testid": `remote-cursor-${user.clientId}`,
|
|
111211
|
-
children: [
|
|
111212
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
111213
|
-
"path",
|
|
111214
|
-
{
|
|
111215
|
-
d: "M0 0 L0 16 L4.5 12.5 L8 20 L10.5 19 L7 11.5 L12 11 Z",
|
|
111216
|
-
fill: user.userColor,
|
|
111217
|
-
stroke: "#fff",
|
|
111218
|
-
strokeWidth: 1,
|
|
111219
|
-
opacity: 0.9
|
|
111220
|
-
}
|
|
111221
|
-
),
|
|
111222
|
-
/* @__PURE__ */ jsxRuntime.jsxs("g", { transform: "translate(14, 18)", children: [
|
|
111223
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
111224
|
-
"rect",
|
|
111225
|
-
{
|
|
111226
|
-
rx: 3,
|
|
111227
|
-
ry: 3,
|
|
111228
|
-
x: -2,
|
|
111229
|
-
y: -10,
|
|
111230
|
-
width: Math.min(user.userName.length * 7 + 8, 150),
|
|
111231
|
-
height: 16,
|
|
111232
|
-
fill: user.userColor,
|
|
111233
|
-
opacity: 0.85
|
|
111234
|
-
}
|
|
111235
|
-
),
|
|
111236
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
111237
|
-
"text",
|
|
111238
|
-
{
|
|
111239
|
-
fill: "#fff",
|
|
111240
|
-
fontSize: 10,
|
|
111241
|
-
fontFamily: "system-ui, sans-serif",
|
|
111242
|
-
fontWeight: 500,
|
|
111243
|
-
dominantBaseline: "central",
|
|
111244
|
-
y: -2,
|
|
111245
|
-
x: 2,
|
|
111246
|
-
children: user.userName.length > 20 ? `${user.userName.slice(0, 18)}...` : user.userName
|
|
111247
|
-
}
|
|
111248
|
-
)
|
|
111249
|
-
] })
|
|
111250
|
-
]
|
|
111251
|
-
},
|
|
111252
|
-
user.clientId
|
|
111253
|
-
))
|
|
111254
|
-
}
|
|
112853
|
+
const [activeTab, setActiveTab] = React10.useState("general");
|
|
112854
|
+
const [autoSave, setAutoSave] = React10.useState(true);
|
|
112855
|
+
const { t: t2 } = reactI18next.useTranslation();
|
|
112856
|
+
const handleKeyDown = React10.useCallback(
|
|
112857
|
+
(e2) => {
|
|
112858
|
+
if (e2.key === "Escape") {
|
|
112859
|
+
onClose();
|
|
112860
|
+
}
|
|
112861
|
+
},
|
|
112862
|
+
[onClose]
|
|
111255
112863
|
);
|
|
111256
|
-
|
|
111257
|
-
|
|
111258
|
-
|
|
111259
|
-
|
|
111260
|
-
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
111261
|
-
}
|
|
111262
|
-
return name.slice(0, 2).toUpperCase();
|
|
111263
|
-
}
|
|
111264
|
-
function AvatarCircle({
|
|
111265
|
-
name,
|
|
111266
|
-
color,
|
|
111267
|
-
avatar,
|
|
111268
|
-
isLocal
|
|
111269
|
-
}) {
|
|
111270
|
-
const initials = getInitials(name);
|
|
111271
|
-
const title = isLocal ? `${name} (you)` : name;
|
|
111272
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
111273
|
-
"div",
|
|
111274
|
-
{
|
|
111275
|
-
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",
|
|
111276
|
-
style: {
|
|
111277
|
-
backgroundColor: color,
|
|
111278
|
-
borderColor: isLocal ? "#fff" : color
|
|
111279
|
-
},
|
|
111280
|
-
title,
|
|
111281
|
-
"aria-label": title,
|
|
111282
|
-
children: avatar ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
111283
|
-
"img",
|
|
111284
|
-
{
|
|
111285
|
-
src: avatar,
|
|
111286
|
-
alt: "",
|
|
111287
|
-
className: "w-full h-full rounded-full object-cover",
|
|
111288
|
-
onError: (e2) => {
|
|
111289
|
-
e2.target.style.display = "none";
|
|
111290
|
-
}
|
|
111291
|
-
}
|
|
111292
|
-
) : initials
|
|
112864
|
+
React10.useEffect(() => {
|
|
112865
|
+
if (isOpen) {
|
|
112866
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
112867
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
111293
112868
|
}
|
|
111294
|
-
);
|
|
111295
|
-
|
|
111296
|
-
function UserAvatarBar({
|
|
111297
|
-
remoteUsers,
|
|
111298
|
-
localUserName,
|
|
111299
|
-
localUserColor,
|
|
111300
|
-
localUserAvatar,
|
|
111301
|
-
status,
|
|
111302
|
-
maxVisible = 5
|
|
111303
|
-
}) {
|
|
111304
|
-
if (status === "disconnected" || status === "error") {
|
|
112869
|
+
}, [isOpen, handleKeyDown]);
|
|
112870
|
+
if (!isOpen) {
|
|
111305
112871
|
return null;
|
|
111306
112872
|
}
|
|
111307
|
-
const
|
|
111308
|
-
{
|
|
111309
|
-
|
|
111310
|
-
name: u2.userName,
|
|
111311
|
-
color: u2.userColor,
|
|
111312
|
-
avatar: u2.userAvatar,
|
|
111313
|
-
isLocal: false
|
|
111314
|
-
}))
|
|
112873
|
+
const tabs = [
|
|
112874
|
+
{ id: "general", label: t2("pptx.settings.general") },
|
|
112875
|
+
{ id: "shortcuts", label: t2("pptx.settings.keyboardShortcuts") }
|
|
111315
112876
|
];
|
|
111316
|
-
|
|
111317
|
-
|
|
111318
|
-
|
|
111319
|
-
|
|
111320
|
-
|
|
111321
|
-
|
|
111322
|
-
|
|
111323
|
-
|
|
111324
|
-
|
|
111325
|
-
|
|
111326
|
-
|
|
112877
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
112878
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112879
|
+
"button",
|
|
112880
|
+
{
|
|
112881
|
+
type: "button",
|
|
112882
|
+
className: "fixed inset-0 z-50 bg-black/60",
|
|
112883
|
+
"aria-label": t2("pptx.settings.closeSettings"),
|
|
112884
|
+
onClick: onClose
|
|
112885
|
+
}
|
|
112886
|
+
),
|
|
112887
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pointer-events-auto w-[min(32rem,calc(100%-2rem))] rounded-xl border border-border bg-popover backdrop-blur-xl shadow-2xl", children: [
|
|
112888
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-5 py-4 border-b border-border/60", children: [
|
|
112889
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
112890
|
+
/* @__PURE__ */ jsxRuntime.jsx(lu.LuSettings, { className: "w-5 h-5 text-primary" }),
|
|
112891
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold text-foreground", children: t2("pptx.settings.title") })
|
|
112892
|
+
] }),
|
|
112893
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112894
|
+
"button",
|
|
111327
112895
|
{
|
|
111328
|
-
|
|
111329
|
-
|
|
111330
|
-
|
|
111331
|
-
|
|
111332
|
-
|
|
111333
|
-
|
|
111334
|
-
)
|
|
111335
|
-
|
|
112896
|
+
type: "button",
|
|
112897
|
+
onClick: onClose,
|
|
112898
|
+
className: "p-1 rounded hover:bg-accent transition-colors",
|
|
112899
|
+
"aria-label": t2("pptx.settings.close"),
|
|
112900
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuX, { className: "w-4 h-4 text-muted-foreground" })
|
|
112901
|
+
}
|
|
112902
|
+
)
|
|
112903
|
+
] }),
|
|
112904
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex border-b border-border/60 px-5", children: tabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
112905
|
+
"button",
|
|
112906
|
+
{
|
|
112907
|
+
type: "button",
|
|
112908
|
+
onClick: () => setActiveTab(tab.id),
|
|
112909
|
+
className: cn(
|
|
112910
|
+
"px-3 py-2 text-xs font-medium transition-colors relative",
|
|
112911
|
+
activeTab === tab.id ? "text-primary" : "text-muted-foreground hover:text-foreground"
|
|
112912
|
+
),
|
|
112913
|
+
children: [
|
|
112914
|
+
tab.label,
|
|
112915
|
+
activeTab === tab.id && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute bottom-0 left-0 right-0 h-0.5 bg-primary rounded-full" })
|
|
112916
|
+
]
|
|
112917
|
+
},
|
|
112918
|
+
tab.id
|
|
112919
|
+
)) }),
|
|
112920
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-5 py-4 max-h-[60vh] overflow-y-auto", children: [
|
|
112921
|
+
activeTab === "general" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0.5", children: [
|
|
112922
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112923
|
+
ToggleSwitch,
|
|
112924
|
+
{
|
|
112925
|
+
label: t2("pptx.settings.autoSave"),
|
|
112926
|
+
enabled: autoSave,
|
|
112927
|
+
onToggle: () => setAutoSave(!autoSave)
|
|
112928
|
+
}
|
|
112929
|
+
),
|
|
112930
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112931
|
+
ToggleSwitch,
|
|
112932
|
+
{
|
|
112933
|
+
label: t2("pptx.settings.spellCheck"),
|
|
112934
|
+
enabled: spellCheckEnabled,
|
|
112935
|
+
onToggle: () => onSetSpellCheckEnabled?.(!spellCheckEnabled)
|
|
112936
|
+
}
|
|
112937
|
+
),
|
|
112938
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112939
|
+
ToggleSwitch,
|
|
112940
|
+
{
|
|
112941
|
+
label: t2("pptx.settings.showGrid"),
|
|
112942
|
+
enabled: showGrid,
|
|
112943
|
+
onToggle: () => onSetShowGrid?.(!showGrid)
|
|
112944
|
+
}
|
|
112945
|
+
),
|
|
112946
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112947
|
+
ToggleSwitch,
|
|
112948
|
+
{
|
|
112949
|
+
label: t2("pptx.settings.showRulers"),
|
|
112950
|
+
enabled: showRulers,
|
|
112951
|
+
onToggle: () => onSetShowRulers?.(!showRulers)
|
|
112952
|
+
}
|
|
112953
|
+
),
|
|
112954
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112955
|
+
ToggleSwitch,
|
|
112956
|
+
{
|
|
112957
|
+
label: t2("pptx.settings.snapToGrid"),
|
|
112958
|
+
enabled: snapToGrid,
|
|
112959
|
+
onToggle: () => onSetSnapToGrid?.(!snapToGrid)
|
|
112960
|
+
}
|
|
112961
|
+
),
|
|
112962
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112963
|
+
ToggleSwitch,
|
|
112964
|
+
{
|
|
112965
|
+
label: t2("pptx.settings.reducedMotion"),
|
|
112966
|
+
enabled: reducedMotion,
|
|
112967
|
+
onToggle: () => onToggleReducedMotion?.()
|
|
112968
|
+
}
|
|
112969
|
+
)
|
|
112970
|
+
] }),
|
|
112971
|
+
activeTab === "shortcuts" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-0.5", children: SHORTCUT_REFERENCE_ITEMS.map((shortcut, i3) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
111336
112972
|
"div",
|
|
111337
112973
|
{
|
|
111338
|
-
className:
|
|
111339
|
-
|
|
112974
|
+
className: cn(
|
|
112975
|
+
"flex items-center justify-between gap-3 rounded px-3 py-2",
|
|
112976
|
+
i3 % 2 === 0 ? "bg-muted/60" : ""
|
|
112977
|
+
),
|
|
111340
112978
|
children: [
|
|
111341
|
-
"
|
|
111342
|
-
|
|
112979
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-foreground", children: shortcut.action }),
|
|
112980
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-[11px] text-muted-foreground whitespace-nowrap", children: shortcut.shortcut })
|
|
111343
112981
|
]
|
|
111344
|
-
}
|
|
111345
|
-
|
|
111346
|
-
|
|
112982
|
+
},
|
|
112983
|
+
shortcut.action
|
|
112984
|
+
)) })
|
|
112985
|
+
] })
|
|
112986
|
+
] }) })
|
|
112987
|
+
] });
|
|
112988
|
+
}
|
|
112989
|
+
function useCollaborativeHistory({
|
|
112990
|
+
localClientId: _localClientId,
|
|
112991
|
+
handleUndo,
|
|
112992
|
+
handleRedo,
|
|
112993
|
+
canUndo,
|
|
112994
|
+
canRedo
|
|
112995
|
+
}) {
|
|
112996
|
+
const localChangeCountRef = React10.useRef(0);
|
|
112997
|
+
const wrappedUndo = React10.useCallback(() => {
|
|
112998
|
+
if (!canUndo) {
|
|
112999
|
+
return;
|
|
111347
113000
|
}
|
|
111348
|
-
|
|
113001
|
+
handleUndo();
|
|
113002
|
+
localChangeCountRef.current = Math.max(0, localChangeCountRef.current - 1);
|
|
113003
|
+
}, [handleUndo, canUndo]);
|
|
113004
|
+
const wrappedRedo = React10.useCallback(() => {
|
|
113005
|
+
if (!canRedo) {
|
|
113006
|
+
return;
|
|
113007
|
+
}
|
|
113008
|
+
handleRedo();
|
|
113009
|
+
localChangeCountRef.current += 1;
|
|
113010
|
+
}, [handleRedo, canRedo]);
|
|
113011
|
+
return {
|
|
113012
|
+
handleUndo: wrappedUndo,
|
|
113013
|
+
handleRedo: wrappedRedo,
|
|
113014
|
+
canUndo,
|
|
113015
|
+
canRedo
|
|
113016
|
+
};
|
|
111349
113017
|
}
|
|
111350
|
-
|
|
111351
|
-
|
|
111352
|
-
|
|
111353
|
-
|
|
111354
|
-
|
|
111355
|
-
},
|
|
111356
|
-
connecting: {
|
|
111357
|
-
dot: "bg-yellow-400 animate-pulse",
|
|
111358
|
-
text: "text-yellow-400",
|
|
111359
|
-
label: "Connecting..."
|
|
111360
|
-
},
|
|
111361
|
-
disconnected: {
|
|
111362
|
-
dot: "bg-gray-500",
|
|
111363
|
-
text: "text-gray-500",
|
|
111364
|
-
label: "Disconnected"
|
|
111365
|
-
},
|
|
111366
|
-
error: {
|
|
111367
|
-
dot: "bg-red-400",
|
|
111368
|
-
text: "text-red-400",
|
|
111369
|
-
label: "Connection error"
|
|
111370
|
-
}
|
|
111371
|
-
};
|
|
111372
|
-
function CollaborationStatusIndicator({
|
|
111373
|
-
status,
|
|
111374
|
-
connectedCount
|
|
113018
|
+
function useYjsDocumentSync({
|
|
113019
|
+
doc: doc2,
|
|
113020
|
+
slides,
|
|
113021
|
+
setSlides,
|
|
113022
|
+
isConnected
|
|
111375
113023
|
}) {
|
|
111376
|
-
const
|
|
111377
|
-
|
|
111378
|
-
|
|
111379
|
-
|
|
111380
|
-
|
|
111381
|
-
|
|
111382
|
-
"aria-label": `Collaboration: ${style.label}. ${connectedCount} user${connectedCount !== 1 ? "s" : ""} connected.`,
|
|
111383
|
-
children: [
|
|
111384
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-block w-2 h-2 rounded-full ${style.dot}`, "aria-hidden": "true" }),
|
|
111385
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-[10px] ${style.text}`, children: status === "connected" ? `${connectedCount} user${connectedCount !== 1 ? "s" : ""}` : style.label })
|
|
111386
|
-
]
|
|
113024
|
+
const isApplyingRemoteRef = React10.useRef(false);
|
|
113025
|
+
const lastSyncedRef = React10.useRef("");
|
|
113026
|
+
const hasInitializedRef = React10.useRef(false);
|
|
113027
|
+
const getDocMap = React10.useCallback(() => {
|
|
113028
|
+
if (!doc2 || typeof doc2 !== "object") {
|
|
113029
|
+
return null;
|
|
111387
113030
|
}
|
|
111388
|
-
|
|
113031
|
+
const d = doc2;
|
|
113032
|
+
if (typeof d.getMap !== "function") {
|
|
113033
|
+
return null;
|
|
113034
|
+
}
|
|
113035
|
+
return d.getMap("slides-data");
|
|
113036
|
+
}, [doc2]);
|
|
113037
|
+
React10.useEffect(() => {
|
|
113038
|
+
if (!isConnected || !doc2) {
|
|
113039
|
+
return;
|
|
113040
|
+
}
|
|
113041
|
+
if (isApplyingRemoteRef.current) {
|
|
113042
|
+
return;
|
|
113043
|
+
}
|
|
113044
|
+
if (slides.length === 0) {
|
|
113045
|
+
return;
|
|
113046
|
+
}
|
|
113047
|
+
const map3 = getDocMap();
|
|
113048
|
+
if (!map3) {
|
|
113049
|
+
return;
|
|
113050
|
+
}
|
|
113051
|
+
const serialized = JSON.stringify(slides);
|
|
113052
|
+
if (serialized === lastSyncedRef.current) {
|
|
113053
|
+
return;
|
|
113054
|
+
}
|
|
113055
|
+
lastSyncedRef.current = serialized;
|
|
113056
|
+
const d = doc2;
|
|
113057
|
+
d.transact(() => {
|
|
113058
|
+
const currentCount = map3.get("count");
|
|
113059
|
+
if (currentCount && currentCount > slides.length) {
|
|
113060
|
+
for (let i3 = slides.length; i3 < currentCount; i3++) {
|
|
113061
|
+
map3.delete(`slide-${i3}`);
|
|
113062
|
+
}
|
|
113063
|
+
}
|
|
113064
|
+
map3.set("count", slides.length);
|
|
113065
|
+
for (let i3 = 0; i3 < slides.length; i3++) {
|
|
113066
|
+
const slideJson = JSON.stringify(slides[i3]);
|
|
113067
|
+
const existing = map3.get(`slide-${i3}`);
|
|
113068
|
+
if (existing !== slideJson) {
|
|
113069
|
+
map3.set(`slide-${i3}`, slideJson);
|
|
113070
|
+
}
|
|
113071
|
+
}
|
|
113072
|
+
});
|
|
113073
|
+
}, [doc2, slides, isConnected, getDocMap]);
|
|
113074
|
+
React10.useEffect(() => {
|
|
113075
|
+
if (!isConnected || !doc2) {
|
|
113076
|
+
return;
|
|
113077
|
+
}
|
|
113078
|
+
const map3 = getDocMap();
|
|
113079
|
+
if (!map3) {
|
|
113080
|
+
return;
|
|
113081
|
+
}
|
|
113082
|
+
const handleUpdate = () => {
|
|
113083
|
+
const count = map3.get("count");
|
|
113084
|
+
if (!count || count === 0) {
|
|
113085
|
+
return;
|
|
113086
|
+
}
|
|
113087
|
+
const remoteSlides = [];
|
|
113088
|
+
for (let i3 = 0; i3 < count; i3++) {
|
|
113089
|
+
const slideJson = map3.get(`slide-${i3}`);
|
|
113090
|
+
if (slideJson) {
|
|
113091
|
+
try {
|
|
113092
|
+
remoteSlides.push(JSON.parse(slideJson));
|
|
113093
|
+
} catch {
|
|
113094
|
+
}
|
|
113095
|
+
}
|
|
113096
|
+
}
|
|
113097
|
+
if (remoteSlides.length === 0) {
|
|
113098
|
+
return;
|
|
113099
|
+
}
|
|
113100
|
+
const serialized = JSON.stringify(remoteSlides);
|
|
113101
|
+
if (serialized === lastSyncedRef.current) {
|
|
113102
|
+
return;
|
|
113103
|
+
}
|
|
113104
|
+
lastSyncedRef.current = serialized;
|
|
113105
|
+
isApplyingRemoteRef.current = true;
|
|
113106
|
+
setSlides(remoteSlides);
|
|
113107
|
+
requestAnimationFrame(() => {
|
|
113108
|
+
isApplyingRemoteRef.current = false;
|
|
113109
|
+
});
|
|
113110
|
+
};
|
|
113111
|
+
map3.observe(handleUpdate);
|
|
113112
|
+
if (!hasInitializedRef.current) {
|
|
113113
|
+
hasInitializedRef.current = true;
|
|
113114
|
+
const count = map3.get("count");
|
|
113115
|
+
if (count && count > 0) {
|
|
113116
|
+
handleUpdate();
|
|
113117
|
+
}
|
|
113118
|
+
}
|
|
113119
|
+
return () => {
|
|
113120
|
+
map3.unobserve(handleUpdate);
|
|
113121
|
+
};
|
|
113122
|
+
}, [doc2, isConnected, getDocMap, setSlides]);
|
|
111389
113123
|
}
|
|
111390
113124
|
function computeGridSpacingPx(presentationGridSpacing) {
|
|
111391
113125
|
if (presentationGridSpacing) {
|
|
@@ -121087,7 +122821,7 @@ function useViewerUIState() {
|
|
|
121087
122821
|
const [isCompactToolbarOpen, setIsCompactToolbarOpen] = React10.useState(false);
|
|
121088
122822
|
const [toolbarSection, setToolbarSection] = React10.useState("home");
|
|
121089
122823
|
const [isSlidesPaneOpen, setIsSlidesPaneOpen] = React10.useState(true);
|
|
121090
|
-
const [isInspectorPaneOpen, setIsInspectorPaneOpen] = React10.useState(
|
|
122824
|
+
const [isInspectorPaneOpen, setIsInspectorPaneOpen] = React10.useState(false);
|
|
121091
122825
|
const [isSlideNotesCollapsed, setIsSlideNotesCollapsed] = React10.useState(true);
|
|
121092
122826
|
const [isOverflowMenuOpen, setIsOverflowMenuOpen] = React10.useState(false);
|
|
121093
122827
|
const [isSidebarCollapsed, setIsSidebarCollapsed] = React10.useState(false);
|
|
@@ -121370,13 +123104,18 @@ var PowerPointViewer = React10.forwardRef(
|
|
|
121370
123104
|
onDirtyChange,
|
|
121371
123105
|
onActiveSlideChange,
|
|
121372
123106
|
theme,
|
|
121373
|
-
collaboration
|
|
123107
|
+
collaboration,
|
|
123108
|
+
onStartCollaboration,
|
|
123109
|
+
onStopCollaboration,
|
|
123110
|
+
shareDefaults
|
|
121374
123111
|
} = props;
|
|
121375
123112
|
const themeStyle = useThemeStyle(theme);
|
|
121376
123113
|
const [content, setContent] = React10.useState(incomingContent);
|
|
121377
123114
|
React10.useEffect(() => {
|
|
121378
123115
|
setContent(incomingContent);
|
|
121379
123116
|
}, [incomingContent]);
|
|
123117
|
+
const [isSettingsOpen, setIsSettingsOpen] = React10.useState(false);
|
|
123118
|
+
const [isShareDialogOpen, setIsShareDialogOpen] = React10.useState(false);
|
|
121380
123119
|
const { reducedMotion, toggleReducedMotion } = useReducedMotion();
|
|
121381
123120
|
const state2 = useViewerState();
|
|
121382
123121
|
const {
|
|
@@ -121577,36 +123316,35 @@ var PowerPointViewer = React10.forwardRef(
|
|
|
121577
123316
|
ref: containerRef,
|
|
121578
123317
|
tabIndex: 0,
|
|
121579
123318
|
style: themeStyle,
|
|
123319
|
+
"data-pptx-viewer": "",
|
|
121580
123320
|
className: "h-full w-full bg-background text-foreground flex flex-col relative overflow-hidden outline-none",
|
|
121581
123321
|
children: [
|
|
121582
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
121583
|
-
|
|
121584
|
-
|
|
121585
|
-
|
|
121586
|
-
|
|
121587
|
-
|
|
121588
|
-
|
|
121589
|
-
|
|
121590
|
-
|
|
121591
|
-
|
|
121592
|
-
|
|
121593
|
-
|
|
121594
|
-
|
|
121595
|
-
|
|
121596
|
-
|
|
121597
|
-
|
|
121598
|
-
|
|
121599
|
-
|
|
121600
|
-
|
|
121601
|
-
|
|
121602
|
-
|
|
121603
|
-
|
|
121604
|
-
|
|
121605
|
-
|
|
121606
|
-
|
|
121607
|
-
|
|
121608
|
-
collaboration && /* @__PURE__ */ jsxRuntime.jsx(CollaborationToolbarStrip, { collaboration })
|
|
121609
|
-
] }),
|
|
123322
|
+
mode !== "present" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
123323
|
+
ViewerToolbarSection,
|
|
123324
|
+
{
|
|
123325
|
+
mode,
|
|
123326
|
+
canEdit,
|
|
123327
|
+
state: state2,
|
|
123328
|
+
selectedElement,
|
|
123329
|
+
activeSlide,
|
|
123330
|
+
zoom,
|
|
123331
|
+
history,
|
|
123332
|
+
findReplace: editorOps.findReplace,
|
|
123333
|
+
manipulation: editorOps.manipulation,
|
|
123334
|
+
insertHandlers: editorOps.insertHandlers,
|
|
123335
|
+
exportHandlers,
|
|
123336
|
+
printHandlers,
|
|
123337
|
+
propertyHandlers,
|
|
123338
|
+
dialogs,
|
|
123339
|
+
slideOps: editorOps.slideOps,
|
|
123340
|
+
ops: editorOps.ops,
|
|
123341
|
+
onSetMode: handleSetMode,
|
|
123342
|
+
onEnterPresenterView: handleEnterPresenterView,
|
|
123343
|
+
onEnterRehearsalMode: handleEnterRehearsalMode,
|
|
123344
|
+
onOpenSettings: () => setIsSettingsOpen(true),
|
|
123345
|
+
onOpenShareDialog: () => setIsShareDialogOpen(true)
|
|
123346
|
+
}
|
|
123347
|
+
),
|
|
121610
123348
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
121611
123349
|
ViewerMainContent,
|
|
121612
123350
|
{
|
|
@@ -121656,7 +123394,14 @@ var PowerPointViewer = React10.forwardRef(
|
|
|
121656
123394
|
onUpdateNotes: propertyHandlers.handleUpdateNotes,
|
|
121657
123395
|
collaborationSlot: collaboration ? /* @__PURE__ */ jsxRuntime.jsx(CollaborationStatusStrip, {}) : void 0,
|
|
121658
123396
|
notesPanelHeight: isMobile ? void 0 : resizablePanels.bottomHeight,
|
|
121659
|
-
onResizeBottom: isMobile ? void 0 : resizablePanels.onResizeBottom
|
|
123397
|
+
onResizeBottom: isMobile ? void 0 : resizablePanels.onResizeBottom,
|
|
123398
|
+
scale: zoom.scale,
|
|
123399
|
+
onZoomIn: zoom.handleZoomIn,
|
|
123400
|
+
onZoomOut: zoom.handleZoomOut,
|
|
123401
|
+
onZoomToFit: zoom.handleZoomToFit,
|
|
123402
|
+
mode,
|
|
123403
|
+
onSetMode: handleSetMode,
|
|
123404
|
+
onToggleSlideSorter: () => state2.setShowSlideSorter((p3) => !p3)
|
|
121660
123405
|
}
|
|
121661
123406
|
),
|
|
121662
123407
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -121688,6 +123433,37 @@ var PowerPointViewer = React10.forwardRef(
|
|
|
121688
123433
|
onDiscardAnnotations: handleDiscardAnnotations
|
|
121689
123434
|
}
|
|
121690
123435
|
),
|
|
123436
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
123437
|
+
SettingsDialog,
|
|
123438
|
+
{
|
|
123439
|
+
isOpen: isSettingsOpen,
|
|
123440
|
+
onClose: () => setIsSettingsOpen(false),
|
|
123441
|
+
spellCheckEnabled: state2.spellCheckEnabled,
|
|
123442
|
+
onSetSpellCheckEnabled: state2.setSpellCheckEnabled,
|
|
123443
|
+
showGrid: state2.showGrid,
|
|
123444
|
+
onSetShowGrid: state2.setShowGrid,
|
|
123445
|
+
showRulers: state2.showRulers,
|
|
123446
|
+
onSetShowRulers: state2.setShowRulers,
|
|
123447
|
+
snapToGrid: state2.snapToGrid,
|
|
123448
|
+
onSetSnapToGrid: state2.setSnapToGrid,
|
|
123449
|
+
reducedMotion,
|
|
123450
|
+
onToggleReducedMotion: toggleReducedMotion
|
|
123451
|
+
}
|
|
123452
|
+
),
|
|
123453
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
123454
|
+
ShareDialog,
|
|
123455
|
+
{
|
|
123456
|
+
open: isShareDialogOpen,
|
|
123457
|
+
onClose: () => setIsShareDialogOpen(false),
|
|
123458
|
+
activeCollaboration: collaboration,
|
|
123459
|
+
onStartCollaboration,
|
|
123460
|
+
onStopCollaboration,
|
|
123461
|
+
preconfigured: Boolean(collaboration),
|
|
123462
|
+
defaultRoomId: shareDefaults?.roomId,
|
|
123463
|
+
defaultUserName: shareDefaults?.userName,
|
|
123464
|
+
defaultServerUrl: shareDefaults?.serverUrl
|
|
123465
|
+
}
|
|
123466
|
+
),
|
|
121691
123467
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
121692
123468
|
ViewerOverlays,
|
|
121693
123469
|
{
|
|
@@ -121729,36 +123505,21 @@ var PowerPointViewer = React10.forwardRef(
|
|
|
121729
123505
|
]
|
|
121730
123506
|
}
|
|
121731
123507
|
);
|
|
121732
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ViewerThemeProvider, { theme, children: collaboration ? /* @__PURE__ */ jsxRuntime.
|
|
123508
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ViewerThemeProvider, { theme, children: collaboration ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
121733
123509
|
CollaborationProvider,
|
|
121734
123510
|
{
|
|
121735
123511
|
config: collaboration,
|
|
121736
123512
|
canvasWidth: canvasSize.width,
|
|
121737
123513
|
canvasHeight: canvasSize.height,
|
|
121738
|
-
children:
|
|
123514
|
+
children: [
|
|
123515
|
+
/* @__PURE__ */ jsxRuntime.jsx(CollaborationDocumentSync, { slides, setSlides: state2.setSlides }),
|
|
123516
|
+
viewerContent
|
|
123517
|
+
]
|
|
121739
123518
|
}
|
|
121740
123519
|
) : viewerContent });
|
|
121741
123520
|
}
|
|
121742
123521
|
);
|
|
121743
123522
|
PowerPointViewer.displayName = "PowerPointViewer";
|
|
121744
|
-
function CollaborationToolbarStrip({
|
|
121745
|
-
collaboration
|
|
121746
|
-
}) {
|
|
121747
|
-
const collab = useCollaboration();
|
|
121748
|
-
if (!collab) {
|
|
121749
|
-
return null;
|
|
121750
|
-
}
|
|
121751
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end px-2 py-0.5 border-b border-border bg-background/30 z-10", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
121752
|
-
UserAvatarBar,
|
|
121753
|
-
{
|
|
121754
|
-
remoteUsers: collab.remoteUsers,
|
|
121755
|
-
localUserName: collaboration.userName,
|
|
121756
|
-
localUserColor: collab.config.userColor ?? "#6366f1",
|
|
121757
|
-
localUserAvatar: collaboration.userAvatar,
|
|
121758
|
-
status: collab.status
|
|
121759
|
-
}
|
|
121760
|
-
) });
|
|
121761
|
-
}
|
|
121762
123523
|
function CollaborationStatusStrip() {
|
|
121763
123524
|
const collab = useCollaboration();
|
|
121764
123525
|
if (!collab) {
|
|
@@ -121766,6 +123527,19 @@ function CollaborationStatusStrip() {
|
|
|
121766
123527
|
}
|
|
121767
123528
|
return /* @__PURE__ */ jsxRuntime.jsx(CollaborationStatusIndicator, { status: collab.status, connectedCount: collab.connectedCount });
|
|
121768
123529
|
}
|
|
123530
|
+
function CollaborationDocumentSync({
|
|
123531
|
+
slides,
|
|
123532
|
+
setSlides
|
|
123533
|
+
}) {
|
|
123534
|
+
const collab = useCollaboration();
|
|
123535
|
+
useYjsDocumentSync({
|
|
123536
|
+
doc: collab?.doc ?? null,
|
|
123537
|
+
slides,
|
|
123538
|
+
setSlides,
|
|
123539
|
+
isConnected: collab?.status === "connected"
|
|
123540
|
+
});
|
|
123541
|
+
return null;
|
|
123542
|
+
}
|
|
121769
123543
|
function colorSchemesMatch(a2, b2) {
|
|
121770
123544
|
if (!a2) {
|
|
121771
123545
|
return false;
|
|
@@ -121821,35 +123595,6 @@ function useThemeSwitching(input) {
|
|
|
121821
123595
|
currentPreset
|
|
121822
123596
|
};
|
|
121823
123597
|
}
|
|
121824
|
-
function useCollaborativeHistory({
|
|
121825
|
-
localClientId: _localClientId,
|
|
121826
|
-
handleUndo,
|
|
121827
|
-
handleRedo,
|
|
121828
|
-
canUndo,
|
|
121829
|
-
canRedo
|
|
121830
|
-
}) {
|
|
121831
|
-
const localChangeCountRef = React10.useRef(0);
|
|
121832
|
-
const wrappedUndo = React10.useCallback(() => {
|
|
121833
|
-
if (!canUndo) {
|
|
121834
|
-
return;
|
|
121835
|
-
}
|
|
121836
|
-
handleUndo();
|
|
121837
|
-
localChangeCountRef.current = Math.max(0, localChangeCountRef.current - 1);
|
|
121838
|
-
}, [handleUndo, canUndo]);
|
|
121839
|
-
const wrappedRedo = React10.useCallback(() => {
|
|
121840
|
-
if (!canRedo) {
|
|
121841
|
-
return;
|
|
121842
|
-
}
|
|
121843
|
-
handleRedo();
|
|
121844
|
-
localChangeCountRef.current += 1;
|
|
121845
|
-
}, [handleRedo, canRedo]);
|
|
121846
|
-
return {
|
|
121847
|
-
handleUndo: wrappedUndo,
|
|
121848
|
-
handleRedo: wrappedRedo,
|
|
121849
|
-
canUndo,
|
|
121850
|
-
canRedo
|
|
121851
|
-
};
|
|
121852
|
-
}
|
|
121853
123598
|
/*! Bundled license information:
|
|
121854
123599
|
|
|
121855
123600
|
three/build/three.core.js:
|
|
@@ -121940,6 +123685,7 @@ exports.clearAudienceContent = clearAudienceContent;
|
|
|
121940
123685
|
exports.getAnimationInitialStyle = getAnimationInitialStyle;
|
|
121941
123686
|
exports.isAudienceTab = isAudienceTab;
|
|
121942
123687
|
exports.loadAudienceContent = loadAudienceContent;
|
|
123688
|
+
exports.storeAudienceContent = storeAudienceContent;
|
|
121943
123689
|
exports.useCollaborativeHistory = useCollaborativeHistory;
|
|
121944
123690
|
exports.useCollaborativeState = useCollaborativeState;
|
|
121945
123691
|
exports.usePresenceTracking = usePresenceTracking;
|