magic-editor-x 1.5.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{App-3CjSGQyL.js → App-DImBvISP.js} +59 -59
- package/dist/_chunks/{App-CKlB5p92.mjs → App-iNfbV7cz.mjs} +32 -32
- package/dist/_chunks/{CustomBlocksPage-CnJxygIw.js → CustomBlocksPage-Cj-0TTUs.js} +12 -12
- package/dist/_chunks/{LicensePage-vJxKYZGQ.js → LicensePage-CmvILX9m.js} +43 -43
- package/dist/_chunks/{LicensePage-B2STSez2.mjs → LicensePage-gLRoo8WJ.mjs} +38 -38
- package/dist/_chunks/{LiveCollaborationPanel-D70o6EGf.js → LiveCollaborationPanel-BFybu8h0.js} +7 -7
- package/dist/_chunks/{LiveCollaborationPanel-uLIJs5z_.mjs → LiveCollaborationPanel-CVgl4IyR.mjs} +3 -3
- package/dist/_chunks/{Settings-CdGL1OCi.mjs → Settings-ButYcfrm.mjs} +82 -82
- package/dist/_chunks/Settings-BzGqgrxD.js +440 -0
- package/dist/_chunks/{getTranslation--JcqVOd5.js → getTranslation-BADoesEn.js} +19120 -12315
- package/dist/_chunks/{getTranslation-bLklCCaI.mjs → getTranslation-D3h3Z3gU.mjs} +18708 -11903
- package/dist/_chunks/index-BXBnwuRw.js +2158 -0
- package/dist/_chunks/index-BvEdg518.mjs +2159 -0
- package/dist/_chunks/{index-CRALSDLD.js → index-DDFAuQNT.js} +181 -181
- package/dist/_chunks/{index-CdFFlQdx.mjs → index-DEi6nwfM.mjs} +33 -33
- package/dist/_chunks/{tools-uudZx91W.mjs → tools-BXzd0lx5.mjs} +3 -3
- package/dist/_chunks/{tools-BSMn5LLQ.js → tools-Q0uwDS9E.js} +10 -10
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +2 -2
- package/dist/server/index.js +142 -135
- package/dist/server/index.mjs +142 -135
- package/package.json +7 -7
- package/dist/_chunks/Settings-CwSNO4_t.js +0 -440
- package/dist/_chunks/index-CAPc_Y1F.mjs +0 -2551
- package/dist/_chunks/index-CPs6WJDY.js +0 -2550
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
-
const
|
|
5
|
-
const getTranslation = require("./getTranslation
|
|
4
|
+
const m = require("react");
|
|
5
|
+
const getTranslation = require("./getTranslation-BADoesEn.js");
|
|
6
6
|
const styled = require("styled-components");
|
|
7
7
|
const outline = require("@heroicons/react/24/outline");
|
|
8
8
|
const EditorJS = require("@editorjs/editorjs");
|
|
9
|
-
const tools = require("./tools-
|
|
9
|
+
const tools = require("./tools-Q0uwDS9E.js");
|
|
10
10
|
const admin = require("@strapi/strapi/admin");
|
|
11
|
-
const index = require("./index-
|
|
11
|
+
const index = require("./index-BXBnwuRw.js");
|
|
12
12
|
const socket_ioClient = require("socket.io-client");
|
|
13
13
|
const Y = require("yjs");
|
|
14
14
|
const yIndexeddb = require("y-indexeddb");
|
|
@@ -31,7 +31,7 @@ function _interopNamespace(e) {
|
|
|
31
31
|
n.default = e;
|
|
32
32
|
return Object.freeze(n);
|
|
33
33
|
}
|
|
34
|
-
const
|
|
34
|
+
const m__default = /* @__PURE__ */ _interopDefault(m);
|
|
35
35
|
const styled__default = /* @__PURE__ */ _interopDefault(styled);
|
|
36
36
|
const EditorJS__default = /* @__PURE__ */ _interopDefault(EditorJS);
|
|
37
37
|
const Y__namespace = /* @__PURE__ */ _interopNamespace(Y);
|
|
@@ -780,11 +780,11 @@ const MediaLibComponent = ({
|
|
|
780
780
|
allowedTypes = ["images", "files", "videos", "audios"],
|
|
781
781
|
multiple = true
|
|
782
782
|
}) => {
|
|
783
|
-
const [isLoading, setIsLoading] =
|
|
784
|
-
const [retryCount, setRetryCount] =
|
|
783
|
+
const [isLoading, setIsLoading] = m.useState(true);
|
|
784
|
+
const [retryCount, setRetryCount] = m.useState(0);
|
|
785
785
|
const components = admin.useStrapiApp("MediaLibComponent", (state) => state.components);
|
|
786
786
|
const MediaLibraryDialog = components?.["media-library"];
|
|
787
|
-
|
|
787
|
+
m.useEffect(() => {
|
|
788
788
|
if (isOpen && !MediaLibraryDialog && retryCount < 5) {
|
|
789
789
|
const timer = setTimeout(() => {
|
|
790
790
|
setRetryCount((prev) => prev + 1);
|
|
@@ -793,13 +793,13 @@ const MediaLibComponent = ({
|
|
|
793
793
|
}
|
|
794
794
|
setIsLoading(false);
|
|
795
795
|
}, [isOpen, MediaLibraryDialog, retryCount]);
|
|
796
|
-
|
|
796
|
+
m.useEffect(() => {
|
|
797
797
|
if (!isOpen) {
|
|
798
798
|
setRetryCount(0);
|
|
799
799
|
setIsLoading(true);
|
|
800
800
|
}
|
|
801
801
|
}, [isOpen]);
|
|
802
|
-
|
|
802
|
+
m.useEffect(() => {
|
|
803
803
|
if (isOpen) {
|
|
804
804
|
console.log("[Magic Editor X] MediaLib opened");
|
|
805
805
|
console.log("[Magic Editor X] Available components:", Object.keys(components || {}));
|
|
@@ -807,7 +807,7 @@ const MediaLibComponent = ({
|
|
|
807
807
|
console.log("[Magic Editor X] Retry count:", retryCount);
|
|
808
808
|
}
|
|
809
809
|
}, [isOpen, components, MediaLibraryDialog, retryCount]);
|
|
810
|
-
const handleSelectAssets =
|
|
810
|
+
const handleSelectAssets = m.useCallback((files) => {
|
|
811
811
|
console.log("[Magic Editor X] Selected assets:", files);
|
|
812
812
|
if (!files || files.length === 0) {
|
|
813
813
|
onToggle();
|
|
@@ -829,7 +829,7 @@ const MediaLibComponent = ({
|
|
|
829
829
|
console.log("[Magic Editor X] Formatted files:", formattedFiles);
|
|
830
830
|
onChange(formattedFiles);
|
|
831
831
|
}, [onChange, onToggle]);
|
|
832
|
-
const handleClose =
|
|
832
|
+
const handleClose = m.useCallback(() => {
|
|
833
833
|
console.log("[Magic Editor X] MediaLib closing");
|
|
834
834
|
onToggle();
|
|
835
835
|
}, [onToggle]);
|
|
@@ -994,7 +994,7 @@ const MediaLibComponent = ({
|
|
|
994
994
|
}
|
|
995
995
|
) });
|
|
996
996
|
};
|
|
997
|
-
class MediaLibErrorBoundary extends
|
|
997
|
+
class MediaLibErrorBoundary extends m__default.default.Component {
|
|
998
998
|
constructor(props) {
|
|
999
999
|
super(props);
|
|
1000
1000
|
this.state = { hasError: false, error: null };
|
|
@@ -1268,20 +1268,20 @@ const useMagicCollaboration = ({
|
|
|
1268
1268
|
const { get, post } = admin.useFetchClient();
|
|
1269
1269
|
const authContext = admin.useAuth("useMagicCollaboration", (state) => state);
|
|
1270
1270
|
const user = authContext?.user || null;
|
|
1271
|
-
const [status, setStatus] =
|
|
1272
|
-
const [error, setError] =
|
|
1273
|
-
const [peers, setPeers] =
|
|
1274
|
-
const [awareness, setAwareness] =
|
|
1275
|
-
const [collabRole, setCollabRole] =
|
|
1276
|
-
const [canEdit, setCanEdit] =
|
|
1277
|
-
const socketRef =
|
|
1278
|
-
const persistenceRef =
|
|
1279
|
-
const bootstrappedRef =
|
|
1280
|
-
const onRemoteUpdateRef =
|
|
1281
|
-
|
|
1271
|
+
const [status, setStatus] = m.useState(enabled ? "idle" : "disabled");
|
|
1272
|
+
const [error, setError] = m.useState(null);
|
|
1273
|
+
const [peers, setPeers] = m.useState([]);
|
|
1274
|
+
const [awareness, setAwareness] = m.useState({});
|
|
1275
|
+
const [collabRole, setCollabRole] = m.useState(null);
|
|
1276
|
+
const [canEdit, setCanEdit] = m.useState(null);
|
|
1277
|
+
const socketRef = m.useRef(null);
|
|
1278
|
+
const persistenceRef = m.useRef(null);
|
|
1279
|
+
const bootstrappedRef = m.useRef(false);
|
|
1280
|
+
const onRemoteUpdateRef = m.useRef(onRemoteUpdate);
|
|
1281
|
+
m.useEffect(() => {
|
|
1282
1282
|
onRemoteUpdateRef.current = onRemoteUpdate;
|
|
1283
1283
|
}, [onRemoteUpdate]);
|
|
1284
|
-
const { doc, blocksMap, textMap, metaMap } =
|
|
1284
|
+
const { doc, blocksMap, textMap, metaMap } = m.useMemo(() => {
|
|
1285
1285
|
const yDoc = new Y__namespace.Doc();
|
|
1286
1286
|
return {
|
|
1287
1287
|
doc: yDoc,
|
|
@@ -1293,7 +1293,7 @@ const useMagicCollaboration = ({
|
|
|
1293
1293
|
// Document metadata (time, blockOrder)
|
|
1294
1294
|
};
|
|
1295
1295
|
}, [roomId]);
|
|
1296
|
-
const getBlockText =
|
|
1296
|
+
const getBlockText = m.useCallback((blockId) => {
|
|
1297
1297
|
if (!blockId) return null;
|
|
1298
1298
|
let ytext = textMap.get(blockId);
|
|
1299
1299
|
if (!ytext) {
|
|
@@ -1302,7 +1302,7 @@ const useMagicCollaboration = ({
|
|
|
1302
1302
|
}
|
|
1303
1303
|
return ytext;
|
|
1304
1304
|
}, [textMap]);
|
|
1305
|
-
const setBlockText =
|
|
1305
|
+
const setBlockText = m.useCallback((blockId, html) => {
|
|
1306
1306
|
if (!blockId) return;
|
|
1307
1307
|
const ytext = getBlockText(blockId);
|
|
1308
1308
|
if (!ytext) return;
|
|
@@ -1316,18 +1316,18 @@ const useMagicCollaboration = ({
|
|
|
1316
1316
|
}
|
|
1317
1317
|
}, "local");
|
|
1318
1318
|
}, [doc, getBlockText]);
|
|
1319
|
-
const getBlockTextHtml =
|
|
1319
|
+
const getBlockTextHtml = m.useCallback((blockId) => {
|
|
1320
1320
|
if (!blockId) return "";
|
|
1321
1321
|
const ytext = textMap.get(blockId);
|
|
1322
1322
|
if (!ytext) return "";
|
|
1323
1323
|
return deltaToHtml(ytext.toDelta());
|
|
1324
1324
|
}, [textMap]);
|
|
1325
|
-
|
|
1325
|
+
m.useEffect(() => {
|
|
1326
1326
|
return () => {
|
|
1327
1327
|
doc.destroy();
|
|
1328
1328
|
};
|
|
1329
1329
|
}, [doc]);
|
|
1330
|
-
|
|
1330
|
+
m.useEffect(() => {
|
|
1331
1331
|
bootstrappedRef.current = false;
|
|
1332
1332
|
setPeers([]);
|
|
1333
1333
|
setAwareness({});
|
|
@@ -1342,7 +1342,7 @@ const useMagicCollaboration = ({
|
|
|
1342
1342
|
}
|
|
1343
1343
|
};
|
|
1344
1344
|
}, [roomId]);
|
|
1345
|
-
|
|
1345
|
+
m.useEffect(() => {
|
|
1346
1346
|
if (!enabled) return void 0;
|
|
1347
1347
|
const cleanupInterval = setInterval(() => {
|
|
1348
1348
|
const now = Date.now();
|
|
@@ -1361,14 +1361,14 @@ const useMagicCollaboration = ({
|
|
|
1361
1361
|
}, 1e4);
|
|
1362
1362
|
return () => clearInterval(cleanupInterval);
|
|
1363
1363
|
}, [enabled]);
|
|
1364
|
-
|
|
1364
|
+
m.useEffect(() => {
|
|
1365
1365
|
if (!enabled) {
|
|
1366
1366
|
setStatus("disabled");
|
|
1367
1367
|
} else if (status === "disabled") {
|
|
1368
1368
|
setStatus("idle");
|
|
1369
1369
|
}
|
|
1370
1370
|
}, [enabled, status]);
|
|
1371
|
-
|
|
1371
|
+
m.useEffect(() => {
|
|
1372
1372
|
if (!enabled || !roomId) {
|
|
1373
1373
|
return void 0;
|
|
1374
1374
|
}
|
|
@@ -1376,7 +1376,7 @@ const useMagicCollaboration = ({
|
|
|
1376
1376
|
console.log("[Magic Collab] [READY] Client ready, waiting for server sync...");
|
|
1377
1377
|
return void 0;
|
|
1378
1378
|
}, [enabled, roomId]);
|
|
1379
|
-
|
|
1379
|
+
m.useEffect(() => {
|
|
1380
1380
|
if (!enabled || !roomId || !doc) {
|
|
1381
1381
|
return void 0;
|
|
1382
1382
|
}
|
|
@@ -1402,11 +1402,11 @@ const useMagicCollaboration = ({
|
|
|
1402
1402
|
}
|
|
1403
1403
|
};
|
|
1404
1404
|
}, [enabled, roomId, doc]);
|
|
1405
|
-
const initialValueRef =
|
|
1406
|
-
|
|
1405
|
+
const initialValueRef = m.useRef(initialValue);
|
|
1406
|
+
m.useEffect(() => {
|
|
1407
1407
|
initialValueRef.current = initialValue;
|
|
1408
1408
|
}, [initialValue]);
|
|
1409
|
-
|
|
1409
|
+
m.useEffect(() => {
|
|
1410
1410
|
if (!enabled || !roomId || !user) {
|
|
1411
1411
|
return void 0;
|
|
1412
1412
|
}
|
|
@@ -1583,7 +1583,7 @@ const useMagicCollaboration = ({
|
|
|
1583
1583
|
setPeers([]);
|
|
1584
1584
|
};
|
|
1585
1585
|
}, [enabled, post, fieldName, roomId, user]);
|
|
1586
|
-
|
|
1586
|
+
m.useEffect(() => {
|
|
1587
1587
|
if (!enabled) {
|
|
1588
1588
|
console.log("[Magic Collab] [SKIP] Update handler not registered (disabled)");
|
|
1589
1589
|
return void 0;
|
|
@@ -1611,12 +1611,12 @@ const useMagicCollaboration = ({
|
|
|
1611
1611
|
doc.off("update", handler);
|
|
1612
1612
|
};
|
|
1613
1613
|
}, [doc, enabled]);
|
|
1614
|
-
const emitAwareness =
|
|
1614
|
+
const emitAwareness = m.useCallback((payload) => {
|
|
1615
1615
|
if (socketRef.current?.connected) {
|
|
1616
1616
|
socketRef.current.emit("collab:awareness", payload);
|
|
1617
1617
|
}
|
|
1618
1618
|
}, []);
|
|
1619
|
-
const localUserColor =
|
|
1619
|
+
const localUserColor = m.useMemo(() => {
|
|
1620
1620
|
return user ? getUserColor(user.id) : CURSOR_COLORS[0];
|
|
1621
1621
|
}, [user]);
|
|
1622
1622
|
return {
|
|
@@ -1658,15 +1658,15 @@ const useMagicCollaboration = ({
|
|
|
1658
1658
|
};
|
|
1659
1659
|
const useLicense = () => {
|
|
1660
1660
|
const { get } = admin.useFetchClient();
|
|
1661
|
-
const [isPremium, setIsPremium] =
|
|
1662
|
-
const [isAdvanced, setIsAdvanced] =
|
|
1663
|
-
const [isEnterprise, setIsEnterprise] =
|
|
1664
|
-
const [tier, setTier] =
|
|
1665
|
-
const [loading, setLoading] =
|
|
1666
|
-
const [error, setError] =
|
|
1667
|
-
const [licenseData, setLicenseData] =
|
|
1668
|
-
const [limits, setLimits] =
|
|
1669
|
-
|
|
1661
|
+
const [isPremium, setIsPremium] = m.useState(false);
|
|
1662
|
+
const [isAdvanced, setIsAdvanced] = m.useState(false);
|
|
1663
|
+
const [isEnterprise, setIsEnterprise] = m.useState(false);
|
|
1664
|
+
const [tier, setTier] = m.useState("free");
|
|
1665
|
+
const [loading, setLoading] = m.useState(true);
|
|
1666
|
+
const [error, setError] = m.useState(null);
|
|
1667
|
+
const [licenseData, setLicenseData] = m.useState(null);
|
|
1668
|
+
const [limits, setLimits] = m.useState(null);
|
|
1669
|
+
m.useEffect(() => {
|
|
1670
1670
|
let mounted = true;
|
|
1671
1671
|
const fetchLicense = async () => {
|
|
1672
1672
|
if (mounted) {
|
|
@@ -1787,13 +1787,13 @@ const useLicense = () => {
|
|
|
1787
1787
|
};
|
|
1788
1788
|
};
|
|
1789
1789
|
const useAIActions = ({ licenseKey, editorInstanceRef, isReady, onNoCredits }) => {
|
|
1790
|
-
const apiClientRef =
|
|
1791
|
-
|
|
1790
|
+
const apiClientRef = m__default.default.useRef(null);
|
|
1791
|
+
m__default.default.useEffect(() => {
|
|
1792
1792
|
if (licenseKey && !apiClientRef.current) {
|
|
1793
1793
|
apiClientRef.current = new tools.MagicEditorAPI(licenseKey);
|
|
1794
1794
|
}
|
|
1795
1795
|
}, [licenseKey]);
|
|
1796
|
-
const replaceText =
|
|
1796
|
+
const replaceText = m.useCallback((range, newText) => {
|
|
1797
1797
|
if (!range) return false;
|
|
1798
1798
|
try {
|
|
1799
1799
|
const selection = window.getSelection();
|
|
@@ -1812,7 +1812,7 @@ const useAIActions = ({ licenseKey, editorInstanceRef, isReady, onNoCredits }) =
|
|
|
1812
1812
|
return false;
|
|
1813
1813
|
}
|
|
1814
1814
|
}, [editorInstanceRef, isReady]);
|
|
1815
|
-
const appendText =
|
|
1815
|
+
const appendText = m.useCallback((range, additionalText) => {
|
|
1816
1816
|
if (!range) return false;
|
|
1817
1817
|
try {
|
|
1818
1818
|
const selection = window.getSelection();
|
|
@@ -1833,7 +1833,7 @@ const useAIActions = ({ licenseKey, editorInstanceRef, isReady, onNoCredits }) =
|
|
|
1833
1833
|
return false;
|
|
1834
1834
|
}
|
|
1835
1835
|
}, [editorInstanceRef, isReady]);
|
|
1836
|
-
const handleAIAction =
|
|
1836
|
+
const handleAIAction = m.useCallback(async (action, options, { text, range }) => {
|
|
1837
1837
|
if (!apiClientRef.current || !text) return;
|
|
1838
1838
|
const originalText = text;
|
|
1839
1839
|
const langNames = { en: "Englisch", de: "Deutsch", fr: "Französisch", es: "Spanisch" };
|
|
@@ -1943,14 +1943,14 @@ const useAIActions = ({ licenseKey, editorInstanceRef, isReady, onNoCredits }) =
|
|
|
1943
1943
|
};
|
|
1944
1944
|
const useWebtoolsLinks = () => {
|
|
1945
1945
|
const getPlugin = admin.useStrapiApp("WebtoolsLinks", (state) => state.getPlugin);
|
|
1946
|
-
const linksPlugin =
|
|
1946
|
+
const linksPlugin = m.useMemo(() => {
|
|
1947
1947
|
try {
|
|
1948
1948
|
return getPlugin?.("webtools-addon-links");
|
|
1949
1949
|
} catch (e) {
|
|
1950
1950
|
return null;
|
|
1951
1951
|
}
|
|
1952
1952
|
}, [getPlugin]);
|
|
1953
|
-
const isAvailable =
|
|
1953
|
+
const isAvailable = m.useMemo(() => {
|
|
1954
1954
|
const available = !!linksPlugin?.apis?.openLinkPicker;
|
|
1955
1955
|
if (typeof window !== "undefined" && !window.__WEBTOOLS_LINKS_CHECKED__) {
|
|
1956
1956
|
window.__WEBTOOLS_LINKS_CHECKED__ = true;
|
|
@@ -1962,7 +1962,7 @@ const useWebtoolsLinks = () => {
|
|
|
1962
1962
|
}
|
|
1963
1963
|
return available;
|
|
1964
1964
|
}, [linksPlugin]);
|
|
1965
|
-
const openLinkPicker =
|
|
1965
|
+
const openLinkPicker = m.useCallback(async ({ initialHref = "", initialText = "" } = {}) => {
|
|
1966
1966
|
if (!linksPlugin?.apis?.openLinkPicker) {
|
|
1967
1967
|
console.warn("[Magic Editor X] Webtools Link Picker not available");
|
|
1968
1968
|
return null;
|
|
@@ -2002,10 +2002,10 @@ const apiBase = "/magic-editor-x";
|
|
|
2002
2002
|
const useVersionHistory = () => {
|
|
2003
2003
|
const { get, post } = admin.useFetchClient();
|
|
2004
2004
|
const { tier } = useLicense();
|
|
2005
|
-
const [snapshots, setSnapshots] =
|
|
2006
|
-
const [loading, setLoading] =
|
|
2007
|
-
const [error, setError] =
|
|
2008
|
-
const fetchSnapshots =
|
|
2005
|
+
const [snapshots, setSnapshots] = m.useState([]);
|
|
2006
|
+
const [loading, setLoading] = m.useState(false);
|
|
2007
|
+
const [error, setError] = m.useState(null);
|
|
2008
|
+
const fetchSnapshots = m.useCallback(
|
|
2009
2009
|
async (roomId) => {
|
|
2010
2010
|
if (!roomId) return;
|
|
2011
2011
|
setLoading(true);
|
|
@@ -2021,7 +2021,7 @@ const useVersionHistory = () => {
|
|
|
2021
2021
|
},
|
|
2022
2022
|
[get]
|
|
2023
2023
|
);
|
|
2024
|
-
const restoreSnapshot =
|
|
2024
|
+
const restoreSnapshot = m.useCallback(
|
|
2025
2025
|
async (documentId, roomId) => {
|
|
2026
2026
|
if (!documentId) return;
|
|
2027
2027
|
setLoading(true);
|
|
@@ -2038,7 +2038,7 @@ const useVersionHistory = () => {
|
|
|
2038
2038
|
},
|
|
2039
2039
|
[get]
|
|
2040
2040
|
);
|
|
2041
|
-
const createSnapshot =
|
|
2041
|
+
const createSnapshot = m.useCallback(
|
|
2042
2042
|
async ({ roomId, contentType, entryId, fieldName, content }) => {
|
|
2043
2043
|
if (!roomId || !contentType || !entryId || !fieldName) return;
|
|
2044
2044
|
setLoading(true);
|
|
@@ -2561,11 +2561,11 @@ function createBlockClasses(blockConfigs) {
|
|
|
2561
2561
|
}
|
|
2562
2562
|
function useCustomBlocks() {
|
|
2563
2563
|
const { get } = admin.useFetchClient();
|
|
2564
|
-
const [customBlocks, setCustomBlocks] =
|
|
2565
|
-
const [isLoading, setIsLoading] =
|
|
2566
|
-
const [error, setError] =
|
|
2567
|
-
const [lastFetched, setLastFetched] =
|
|
2568
|
-
const fetchCustomBlocks =
|
|
2564
|
+
const [customBlocks, setCustomBlocks] = m.useState([]);
|
|
2565
|
+
const [isLoading, setIsLoading] = m.useState(true);
|
|
2566
|
+
const [error, setError] = m.useState(null);
|
|
2567
|
+
const [lastFetched, setLastFetched] = m.useState(null);
|
|
2568
|
+
const fetchCustomBlocks = m.useCallback(async () => {
|
|
2569
2569
|
try {
|
|
2570
2570
|
setIsLoading(true);
|
|
2571
2571
|
setError(null);
|
|
@@ -2584,10 +2584,10 @@ function useCustomBlocks() {
|
|
|
2584
2584
|
setIsLoading(false);
|
|
2585
2585
|
}
|
|
2586
2586
|
}, [get]);
|
|
2587
|
-
const refresh =
|
|
2587
|
+
const refresh = m.useCallback(() => {
|
|
2588
2588
|
return fetchCustomBlocks();
|
|
2589
2589
|
}, [fetchCustomBlocks]);
|
|
2590
|
-
|
|
2590
|
+
m.useEffect(() => {
|
|
2591
2591
|
fetchCustomBlocks();
|
|
2592
2592
|
}, [fetchCustomBlocks]);
|
|
2593
2593
|
return {
|
|
@@ -2839,14 +2839,14 @@ const SparklesIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "24",
|
|
|
2839
2839
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M17 19h4" })
|
|
2840
2840
|
] });
|
|
2841
2841
|
const AIAssistantPopup = ({ selectedText, licenseKey, onClose, onApply }) => {
|
|
2842
|
-
const [activeType, setActiveType] =
|
|
2843
|
-
const [isLoading, setIsLoading] =
|
|
2844
|
-
const [result, setResult] =
|
|
2845
|
-
const [error, setError] =
|
|
2846
|
-
const [credits, setCredits] =
|
|
2847
|
-
const [usage, setUsage] =
|
|
2848
|
-
const [apiClient, setApiClient] =
|
|
2849
|
-
|
|
2842
|
+
const [activeType, setActiveType] = m.useState(null);
|
|
2843
|
+
const [isLoading, setIsLoading] = m.useState(false);
|
|
2844
|
+
const [result, setResult] = m.useState(null);
|
|
2845
|
+
const [error, setError] = m.useState(null);
|
|
2846
|
+
const [credits, setCredits] = m.useState(0);
|
|
2847
|
+
const [usage, setUsage] = m.useState(null);
|
|
2848
|
+
const [apiClient, setApiClient] = m.useState(null);
|
|
2849
|
+
m.useEffect(() => {
|
|
2850
2850
|
if (licenseKey) {
|
|
2851
2851
|
const client = new tools.MagicEditorAPI(licenseKey);
|
|
2852
2852
|
setApiClient(client);
|
|
@@ -2858,7 +2858,7 @@ const AIAssistantPopup = ({ selectedText, licenseKey, onClose, onApply }) => {
|
|
|
2858
2858
|
});
|
|
2859
2859
|
}
|
|
2860
2860
|
}, [licenseKey]);
|
|
2861
|
-
const handleCorrection =
|
|
2861
|
+
const handleCorrection = m.useCallback(async (type) => {
|
|
2862
2862
|
if (!apiClient || !selectedText) return;
|
|
2863
2863
|
setActiveType(type);
|
|
2864
2864
|
setIsLoading(true);
|
|
@@ -2888,7 +2888,7 @@ const AIAssistantPopup = ({ selectedText, licenseKey, onClose, onApply }) => {
|
|
|
2888
2888
|
setIsLoading(false);
|
|
2889
2889
|
}
|
|
2890
2890
|
}, [apiClient, selectedText]);
|
|
2891
|
-
const handleApply =
|
|
2891
|
+
const handleApply = m.useCallback(() => {
|
|
2892
2892
|
if (result?.corrected) {
|
|
2893
2893
|
onApply(result.corrected);
|
|
2894
2894
|
}
|
|
@@ -2898,7 +2898,7 @@ const AIAssistantPopup = ({ selectedText, licenseKey, onClose, onApply }) => {
|
|
|
2898
2898
|
onClose();
|
|
2899
2899
|
}
|
|
2900
2900
|
};
|
|
2901
|
-
|
|
2901
|
+
m.useEffect(() => {
|
|
2902
2902
|
const handleKeyDown = (e) => {
|
|
2903
2903
|
if (e.key === "Escape") {
|
|
2904
2904
|
onClose();
|
|
@@ -3007,7 +3007,7 @@ const AIAssistantPopup = ({ selectedText, licenseKey, onClose, onApply }) => {
|
|
|
3007
3007
|
] })
|
|
3008
3008
|
] }) });
|
|
3009
3009
|
};
|
|
3010
|
-
const PanelWrapper = styled__default.default(getTranslation.
|
|
3010
|
+
const PanelWrapper = styled__default.default(getTranslation.R)`
|
|
3011
3011
|
width: 320px;
|
|
3012
3012
|
background: ${({ theme }) => theme.colors.neutral0};
|
|
3013
3013
|
border: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
@@ -3017,25 +3017,25 @@ const PanelWrapper = styled__default.default(getTranslation.Box)`
|
|
|
3017
3017
|
flex-direction: column;
|
|
3018
3018
|
max-height: 70vh;
|
|
3019
3019
|
`;
|
|
3020
|
-
const Header$1 = styled__default.default(getTranslation.
|
|
3020
|
+
const Header$1 = styled__default.default(getTranslation.T)`
|
|
3021
3021
|
padding: 12px 16px;
|
|
3022
3022
|
border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
3023
3023
|
`;
|
|
3024
|
-
const Content$1 = styled__default.default(getTranslation.
|
|
3024
|
+
const Content$1 = styled__default.default(getTranslation.R)`
|
|
3025
3025
|
padding: 12px 16px;
|
|
3026
3026
|
overflow-y: auto;
|
|
3027
3027
|
`;
|
|
3028
|
-
const Item = styled__default.default(getTranslation.
|
|
3028
|
+
const Item = styled__default.default(getTranslation.R)`
|
|
3029
3029
|
padding: 10px 12px;
|
|
3030
3030
|
border: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
3031
3031
|
border-radius: 6px;
|
|
3032
3032
|
margin-bottom: 10px;
|
|
3033
3033
|
`;
|
|
3034
|
-
const Meta = styled__default.default(getTranslation.
|
|
3034
|
+
const Meta = styled__default.default(getTranslation.I)`
|
|
3035
3035
|
color: ${({ theme }) => theme.colors.neutral500};
|
|
3036
3036
|
font-size: 12px;
|
|
3037
3037
|
`;
|
|
3038
|
-
const PremiumBadge = styled__default.default(getTranslation.
|
|
3038
|
+
const PremiumBadge = styled__default.default(getTranslation.R)`
|
|
3039
3039
|
background: ${({ theme }) => theme.colors.primary100};
|
|
3040
3040
|
color: ${({ theme }) => theme.colors.primary600};
|
|
3041
3041
|
border-radius: 6px;
|
|
@@ -3084,33 +3084,33 @@ const VersionHistoryPanel = ({
|
|
|
3084
3084
|
);
|
|
3085
3085
|
return /* @__PURE__ */ jsxRuntime.jsxs(PanelWrapper, { "data-testid": "version-history-panel", children: [
|
|
3086
3086
|
/* @__PURE__ */ jsxRuntime.jsxs(Header$1, { justifyContent: "space-between", alignItems: "center", children: [
|
|
3087
|
-
/* @__PURE__ */ jsxRuntime.jsxs(getTranslation.
|
|
3087
|
+
/* @__PURE__ */ jsxRuntime.jsxs(getTranslation.T, { gap: 8, alignItems: "center", children: [
|
|
3088
3088
|
/* @__PURE__ */ jsxRuntime.jsx(outline.ClockIcon, { width: 18 }),
|
|
3089
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3089
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.I, { fontWeight: "bold", children: t("versionHistory.title", "Version History") })
|
|
3090
3090
|
] }),
|
|
3091
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3091
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.zn, { size: "S", variant: "tertiary", onClick: onClose, children: t("versionHistory.close", "Close") })
|
|
3092
3092
|
] }),
|
|
3093
3093
|
/* @__PURE__ */ jsxRuntime.jsxs(Content$1, { children: [
|
|
3094
|
-
loading && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3095
|
-
error && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3096
|
-
!loading && !error && snapshots.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3094
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.I, { children: t("versionHistory.loading", "Loading versions...") }),
|
|
3095
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.I, { textColor: "danger600", children: error }),
|
|
3096
|
+
!loading && !error && snapshots.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.I, { children: t("versionHistory.noSnapshots", "No versions saved yet") }),
|
|
3097
3097
|
!loading && !error && snapshots.map((snap) => /* @__PURE__ */ jsxRuntime.jsxs(Item, { children: [
|
|
3098
|
-
/* @__PURE__ */ jsxRuntime.jsxs(getTranslation.
|
|
3099
|
-
/* @__PURE__ */ jsxRuntime.jsxs(getTranslation.
|
|
3098
|
+
/* @__PURE__ */ jsxRuntime.jsxs(getTranslation.T, { justifyContent: "space-between", alignItems: "center", children: [
|
|
3099
|
+
/* @__PURE__ */ jsxRuntime.jsxs(getTranslation.I, { fontWeight: "bold", children: [
|
|
3100
3100
|
t("versionHistory.version", "Version"),
|
|
3101
3101
|
" ",
|
|
3102
3102
|
snap.version
|
|
3103
3103
|
] }),
|
|
3104
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3104
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.I, { variant: "pi", children: formatDate(snap.createdAt) })
|
|
3105
3105
|
] }),
|
|
3106
3106
|
/* @__PURE__ */ jsxRuntime.jsxs(Meta, { children: [
|
|
3107
3107
|
t("versionHistory.createdBy", "By"),
|
|
3108
3108
|
" ",
|
|
3109
3109
|
snap.createdBy?.firstname ? `${snap.createdBy.firstname} ${snap.createdBy.lastname || ""}`.trim() : "—"
|
|
3110
3110
|
] }),
|
|
3111
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3112
|
-
canRestore ? /* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3113
|
-
getTranslation.
|
|
3111
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.bl, { marginTop: 2, marginBottom: 2 }),
|
|
3112
|
+
canRestore ? /* @__PURE__ */ jsxRuntime.jsx(getTranslation.T, { gap: 8, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3113
|
+
getTranslation.zn,
|
|
3114
3114
|
{
|
|
3115
3115
|
size: "S",
|
|
3116
3116
|
variant: "secondary",
|
|
@@ -3122,9 +3122,9 @@ const VersionHistoryPanel = ({
|
|
|
3122
3122
|
t("versionHistory.premiumOnly", "Premium feature")
|
|
3123
3123
|
] })
|
|
3124
3124
|
] }, snap.documentId || snap.id)),
|
|
3125
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3126
|
-
canRestore ? /* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3127
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3125
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.bl, { marginTop: 4, marginBottom: 4 }),
|
|
3126
|
+
canRestore ? /* @__PURE__ */ jsxRuntime.jsx(getTranslation.zn, { size: "S", fullWidth: true, variant: "default", onClick: onCreate, disabled: loading, children: t("versionHistory.create", "Create Snapshot") }) : /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.R, { children: [
|
|
3127
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.zn, { size: "S", fullWidth: true, variant: "default", disabled: true, children: t("versionHistory.create", "Create Snapshot") }),
|
|
3128
3128
|
/* @__PURE__ */ jsxRuntime.jsxs(PremiumBadge, { style: { marginTop: "8px", width: "100%", justifyContent: "center" }, children: [
|
|
3129
3129
|
/* @__PURE__ */ jsxRuntime.jsx(outline.ExclamationTriangleIcon, { width: 16 }),
|
|
3130
3130
|
t("versionHistory.premiumOnly", "Premium feature")
|
|
@@ -5313,7 +5313,7 @@ const getPeerName = (user = {}) => {
|
|
|
5313
5313
|
}
|
|
5314
5314
|
return user.email?.split("@")[0] || "Anonymous";
|
|
5315
5315
|
};
|
|
5316
|
-
const Editor =
|
|
5316
|
+
const Editor = m.forwardRef(({
|
|
5317
5317
|
name,
|
|
5318
5318
|
value,
|
|
5319
5319
|
onChange,
|
|
@@ -5332,14 +5332,14 @@ const Editor = React.forwardRef(({
|
|
|
5332
5332
|
const { licenseData, tier: licenseTier } = useLicense();
|
|
5333
5333
|
const { isAvailable: isWebtoolsAvailable, openLinkPicker: webtoolsOpenLinkPicker } = useWebtoolsLinks();
|
|
5334
5334
|
const { customBlocks, isLoading: isLoadingCustomBlocks } = useCustomBlocks();
|
|
5335
|
-
const editorRef =
|
|
5336
|
-
const editorInstanceRef =
|
|
5337
|
-
const containerRef =
|
|
5338
|
-
const webtoolsSelectionRef =
|
|
5339
|
-
const isReadyRef =
|
|
5340
|
-
const [isReady, setIsReady] =
|
|
5341
|
-
const [showCreditsModal, setShowCreditsModal] =
|
|
5342
|
-
const [creditsUpgradeInfo, setCreditsUpgradeInfo] =
|
|
5335
|
+
const editorRef = m.useRef(null);
|
|
5336
|
+
const editorInstanceRef = m.useRef(null);
|
|
5337
|
+
const containerRef = m.useRef(null);
|
|
5338
|
+
const webtoolsSelectionRef = m.useRef({ text: "", range: null, blockIndex: -1, existingAnchor: null, existingHref: "" });
|
|
5339
|
+
const isReadyRef = m.useRef(false);
|
|
5340
|
+
const [isReady, setIsReady] = m.useState(false);
|
|
5341
|
+
const [showCreditsModal, setShowCreditsModal] = m.useState(false);
|
|
5342
|
+
const [creditsUpgradeInfo, setCreditsUpgradeInfo] = m.useState(null);
|
|
5343
5343
|
const { handleAIAction } = useAIActions({
|
|
5344
5344
|
licenseKey: licenseData?.licenseKey,
|
|
5345
5345
|
editorInstanceRef,
|
|
@@ -5349,7 +5349,7 @@ const Editor = React.forwardRef(({
|
|
|
5349
5349
|
setShowCreditsModal(true);
|
|
5350
5350
|
}
|
|
5351
5351
|
});
|
|
5352
|
-
|
|
5352
|
+
m.useEffect(() => {
|
|
5353
5353
|
if (licenseData?.licenseKey) {
|
|
5354
5354
|
window.__MAGIC_EDITOR_LICENSE_KEY__ = licenseData.licenseKey;
|
|
5355
5355
|
}
|
|
@@ -5357,22 +5357,22 @@ const Editor = React.forwardRef(({
|
|
|
5357
5357
|
delete window.__MAGIC_EDITOR_LICENSE_KEY__;
|
|
5358
5358
|
};
|
|
5359
5359
|
}, [licenseData?.licenseKey]);
|
|
5360
|
-
const [blocksCount, setBlocksCount] =
|
|
5361
|
-
const [wordCount, setWordCount] =
|
|
5362
|
-
const [charCount, setCharCount] =
|
|
5363
|
-
const [isFocused, setIsFocused] =
|
|
5364
|
-
const [isFullscreen, setIsFullscreen] =
|
|
5365
|
-
const [editorHeight, setEditorHeight] =
|
|
5366
|
-
const [mediaLibBlockIndex, setMediaLibBlockIndex] =
|
|
5367
|
-
const [isMediaLibOpen, setIsMediaLibOpen] =
|
|
5368
|
-
const [showAIPopup, setShowAIPopup] =
|
|
5369
|
-
const [showAIToolbar, setShowAIToolbar] =
|
|
5370
|
-
const [aiToolbarPosition, setAIToolbarPosition] =
|
|
5371
|
-
const [aiSelectedText, setAISelectedText] =
|
|
5372
|
-
const aiSelectionRangeRef =
|
|
5373
|
-
const [aiLoading, setAILoading] =
|
|
5374
|
-
const [showVersionHistory, setShowVersionHistory] =
|
|
5375
|
-
|
|
5360
|
+
const [blocksCount, setBlocksCount] = m.useState(0);
|
|
5361
|
+
const [wordCount, setWordCount] = m.useState(0);
|
|
5362
|
+
const [charCount, setCharCount] = m.useState(0);
|
|
5363
|
+
const [isFocused, setIsFocused] = m.useState(false);
|
|
5364
|
+
const [isFullscreen, setIsFullscreen] = m.useState(false);
|
|
5365
|
+
const [editorHeight, setEditorHeight] = m.useState(400);
|
|
5366
|
+
const [mediaLibBlockIndex, setMediaLibBlockIndex] = m.useState(-1);
|
|
5367
|
+
const [isMediaLibOpen, setIsMediaLibOpen] = m.useState(false);
|
|
5368
|
+
const [showAIPopup, setShowAIPopup] = m.useState(false);
|
|
5369
|
+
const [showAIToolbar, setShowAIToolbar] = m.useState(false);
|
|
5370
|
+
const [aiToolbarPosition, setAIToolbarPosition] = m.useState({ top: 0, left: 0 });
|
|
5371
|
+
const [aiSelectedText, setAISelectedText] = m.useState("");
|
|
5372
|
+
const aiSelectionRangeRef = m.useRef(null);
|
|
5373
|
+
const [aiLoading, setAILoading] = m.useState(false);
|
|
5374
|
+
const [showVersionHistory, setShowVersionHistory] = m.useState(false);
|
|
5375
|
+
m.useEffect(() => {
|
|
5376
5376
|
if (!isWebtoolsAvailable || !editorRef.current) return;
|
|
5377
5377
|
const updateWebtoolsSelection = () => {
|
|
5378
5378
|
const selection = window.getSelection();
|
|
@@ -5416,13 +5416,13 @@ const Editor = React.forwardRef(({
|
|
|
5416
5416
|
document.removeEventListener("selectionchange", updateWebtoolsSelection);
|
|
5417
5417
|
};
|
|
5418
5418
|
}, [isWebtoolsAvailable, isReady]);
|
|
5419
|
-
const serializedInitialValue =
|
|
5419
|
+
const serializedInitialValue = m.useMemo(() => {
|
|
5420
5420
|
if (!value) {
|
|
5421
5421
|
return "";
|
|
5422
5422
|
}
|
|
5423
5423
|
return typeof value === "string" ? value : JSON.stringify(value);
|
|
5424
5424
|
}, [value]);
|
|
5425
|
-
const serializeForCompare =
|
|
5425
|
+
const serializeForCompare = m.useCallback((payload) => {
|
|
5426
5426
|
if (!payload) return "";
|
|
5427
5427
|
try {
|
|
5428
5428
|
const dataObj = typeof payload === "string" ? JSON.parse(payload) : payload;
|
|
@@ -5437,9 +5437,9 @@ const Editor = React.forwardRef(({
|
|
|
5437
5437
|
return "";
|
|
5438
5438
|
}
|
|
5439
5439
|
}, []);
|
|
5440
|
-
const collabRoomId =
|
|
5440
|
+
const collabRoomId = m.useMemo(() => buildRoomId(name), [name]);
|
|
5441
5441
|
const collabEnabled = (attribute?.options?.collaboration?.enabled ?? true) && !disabled;
|
|
5442
|
-
const renderFromYDocRef =
|
|
5442
|
+
const renderFromYDocRef = m.useRef(null);
|
|
5443
5443
|
const {
|
|
5444
5444
|
doc: yDoc,
|
|
5445
5445
|
blocksMap: yBlocksMap,
|
|
@@ -5476,8 +5476,8 @@ const Editor = React.forwardRef(({
|
|
|
5476
5476
|
}
|
|
5477
5477
|
}
|
|
5478
5478
|
});
|
|
5479
|
-
const yTextBindingsRef =
|
|
5480
|
-
const bindBlockToYText =
|
|
5479
|
+
const yTextBindingsRef = m.useRef(/* @__PURE__ */ new Map());
|
|
5480
|
+
const bindBlockToYText = m.useCallback((blockId, element) => {
|
|
5481
5481
|
if (!collabEnabled || !blockId || !element || !yTextMap) return;
|
|
5482
5482
|
if (yTextBindingsRef.current.has(blockId)) {
|
|
5483
5483
|
const existing = yTextBindingsRef.current.get(blockId);
|
|
@@ -5552,7 +5552,7 @@ const Editor = React.forwardRef(({
|
|
|
5552
5552
|
});
|
|
5553
5553
|
console.log("[Magic Editor X] [CHAR-SYNC] Bound block to Y.Text:", blockId);
|
|
5554
5554
|
}, [collabEnabled, yTextMap, yDoc, getBlockText, collabHtmlToDelta, collabDeltaToHtml]);
|
|
5555
|
-
const unbindBlockFromYText =
|
|
5555
|
+
const unbindBlockFromYText = m.useCallback((blockId) => {
|
|
5556
5556
|
const binding = yTextBindingsRef.current.get(blockId);
|
|
5557
5557
|
if (!binding) return;
|
|
5558
5558
|
binding.ytext.unobserve(binding.ytextObserver);
|
|
@@ -5560,7 +5560,7 @@ const Editor = React.forwardRef(({
|
|
|
5560
5560
|
yTextBindingsRef.current.delete(blockId);
|
|
5561
5561
|
console.log("[Magic Editor X] [CHAR-SYNC] Unbound block from Y.Text:", blockId);
|
|
5562
5562
|
}, []);
|
|
5563
|
-
const bindAllBlocksToYText =
|
|
5563
|
+
const bindAllBlocksToYText = m.useCallback(() => {
|
|
5564
5564
|
if (!collabEnabled || !editorInstanceRef.current || !yTextMap) return;
|
|
5565
5565
|
const editor = editorInstanceRef.current;
|
|
5566
5566
|
if (!editor.blocks || typeof editor.blocks.getBlocksCount !== "function") return;
|
|
@@ -5588,8 +5588,8 @@ const Editor = React.forwardRef(({
|
|
|
5588
5588
|
}
|
|
5589
5589
|
}
|
|
5590
5590
|
}, [collabEnabled, yTextMap, getBlockText, setBlockText, bindBlockToYText]);
|
|
5591
|
-
const blockObserverRef =
|
|
5592
|
-
|
|
5591
|
+
const blockObserverRef = m.useRef(null);
|
|
5592
|
+
m.useEffect(() => {
|
|
5593
5593
|
if (!collabEnabled || !editorRef.current || !yTextMap) return;
|
|
5594
5594
|
const observer = new MutationObserver((mutations) => {
|
|
5595
5595
|
let hasNewBlocks = false;
|
|
@@ -5620,7 +5620,7 @@ const Editor = React.forwardRef(({
|
|
|
5620
5620
|
blockObserverRef.current = null;
|
|
5621
5621
|
};
|
|
5622
5622
|
}, [collabEnabled, yTextMap, bindAllBlocksToYText]);
|
|
5623
|
-
|
|
5623
|
+
m.useEffect(() => {
|
|
5624
5624
|
return () => {
|
|
5625
5625
|
yTextBindingsRef.current.forEach((binding, blockId) => {
|
|
5626
5626
|
binding.ytext.unobserve(binding.ytextObserver);
|
|
@@ -5637,12 +5637,12 @@ const Editor = React.forwardRef(({
|
|
|
5637
5637
|
restoreSnapshot,
|
|
5638
5638
|
createSnapshot
|
|
5639
5639
|
} = useVersionHistory();
|
|
5640
|
-
|
|
5640
|
+
m.useEffect(() => {
|
|
5641
5641
|
if (showVersionHistory && collabRoomId) {
|
|
5642
5642
|
fetchSnapshots(collabRoomId);
|
|
5643
5643
|
}
|
|
5644
5644
|
}, [showVersionHistory, collabRoomId, fetchSnapshots]);
|
|
5645
|
-
|
|
5645
|
+
m.useMemo(() => {
|
|
5646
5646
|
switch (collabRole) {
|
|
5647
5647
|
case "viewer":
|
|
5648
5648
|
return { icon: "V", text: "Viewer", color: "#3b82f6" };
|
|
@@ -5654,7 +5654,7 @@ const Editor = React.forwardRef(({
|
|
|
5654
5654
|
return null;
|
|
5655
5655
|
}
|
|
5656
5656
|
}, [collabRole]);
|
|
5657
|
-
|
|
5657
|
+
m.useMemo(() => {
|
|
5658
5658
|
switch (collabStatus) {
|
|
5659
5659
|
case "connected":
|
|
5660
5660
|
if (collabRole === "viewer") {
|
|
@@ -5678,15 +5678,15 @@ const Editor = React.forwardRef(({
|
|
|
5678
5678
|
return "Bereit";
|
|
5679
5679
|
}
|
|
5680
5680
|
}, [collabStatus, collabRole]);
|
|
5681
|
-
|
|
5682
|
-
const activeEditors =
|
|
5681
|
+
m.useMemo(() => collabPeers.slice(0, 3), [collabPeers]);
|
|
5682
|
+
const activeEditors = m.useMemo(() => {
|
|
5683
5683
|
return Object.values(collabAwareness || {}).filter(
|
|
5684
5684
|
(entry) => entry?.user && Date.now() - entry.lastUpdate < 3e4
|
|
5685
5685
|
);
|
|
5686
5686
|
}, [collabAwareness]);
|
|
5687
|
-
const lastCursorUpdateRef =
|
|
5688
|
-
const lastEmittedPositionRef =
|
|
5689
|
-
const getAbsoluteOffset =
|
|
5687
|
+
const lastCursorUpdateRef = m.useRef(0);
|
|
5688
|
+
const lastEmittedPositionRef = m.useRef(null);
|
|
5689
|
+
const getAbsoluteOffset = m.useCallback((container, node, offset) => {
|
|
5690
5690
|
if (!container || !node) return 0;
|
|
5691
5691
|
let absoluteOffset = 0;
|
|
5692
5692
|
const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, null, false);
|
|
@@ -5700,7 +5700,7 @@ const Editor = React.forwardRef(({
|
|
|
5700
5700
|
}
|
|
5701
5701
|
return absoluteOffset + offset;
|
|
5702
5702
|
}, []);
|
|
5703
|
-
const emitCursorPosition =
|
|
5703
|
+
const emitCursorPosition = m.useCallback(() => {
|
|
5704
5704
|
if (!collabEnabled || !emitAwareness || collabStatus !== "connected") {
|
|
5705
5705
|
return;
|
|
5706
5706
|
}
|
|
@@ -5750,7 +5750,7 @@ const Editor = React.forwardRef(({
|
|
|
5750
5750
|
} catch (err) {
|
|
5751
5751
|
}
|
|
5752
5752
|
}, [collabEnabled, emitAwareness, collabStatus, getAbsoluteOffset]);
|
|
5753
|
-
|
|
5753
|
+
m.useEffect(() => {
|
|
5754
5754
|
if (!collabEnabled || !editorRef.current) {
|
|
5755
5755
|
return void 0;
|
|
5756
5756
|
}
|
|
@@ -5790,7 +5790,7 @@ const Editor = React.forwardRef(({
|
|
|
5790
5790
|
}
|
|
5791
5791
|
};
|
|
5792
5792
|
}, [collabEnabled, emitCursorPosition]);
|
|
5793
|
-
const findTextPosition =
|
|
5793
|
+
const findTextPosition = m.useCallback((container, targetOffset) => {
|
|
5794
5794
|
if (!container || targetOffset === null || targetOffset === void 0) {
|
|
5795
5795
|
return null;
|
|
5796
5796
|
}
|
|
@@ -5820,8 +5820,8 @@ const Editor = React.forwardRef(({
|
|
|
5820
5820
|
}
|
|
5821
5821
|
return null;
|
|
5822
5822
|
}, []);
|
|
5823
|
-
|
|
5824
|
-
|
|
5823
|
+
m.useRef(null);
|
|
5824
|
+
m.useEffect(() => {
|
|
5825
5825
|
if (!collabEnabled || !editorRef.current || !isReady) {
|
|
5826
5826
|
return void 0;
|
|
5827
5827
|
}
|
|
@@ -5931,7 +5931,7 @@ const Editor = React.forwardRef(({
|
|
|
5931
5931
|
cursors?.forEach((el) => el.remove());
|
|
5932
5932
|
};
|
|
5933
5933
|
}, [collabEnabled, activeEditors, isReady, findTextPosition]);
|
|
5934
|
-
|
|
5934
|
+
m.useEffect(() => {
|
|
5935
5935
|
const state = {
|
|
5936
5936
|
status: collabStatus,
|
|
5937
5937
|
peers: collabPeers,
|
|
@@ -5948,13 +5948,13 @@ const Editor = React.forwardRef(({
|
|
|
5948
5948
|
}));
|
|
5949
5949
|
};
|
|
5950
5950
|
}, [collabStatus, collabPeers, collabError]);
|
|
5951
|
-
const isApplyingRemoteRef =
|
|
5952
|
-
const pendingRenderRef =
|
|
5953
|
-
const lastSerializedValueRef =
|
|
5954
|
-
|
|
5951
|
+
const isApplyingRemoteRef = m.useRef(false);
|
|
5952
|
+
const pendingRenderRef = m.useRef(null);
|
|
5953
|
+
const lastSerializedValueRef = m.useRef(serializeForCompare(serializedInitialValue || null));
|
|
5954
|
+
m.useEffect(() => {
|
|
5955
5955
|
lastSerializedValueRef.current = serializeForCompare(serializedInitialValue || null);
|
|
5956
5956
|
}, [serializedInitialValue, serializeForCompare]);
|
|
5957
|
-
const calculateStats =
|
|
5957
|
+
const calculateStats = m.useCallback((data) => {
|
|
5958
5958
|
if (!data?.blocks) {
|
|
5959
5959
|
setWordCount(0);
|
|
5960
5960
|
setCharCount(0);
|
|
@@ -5974,7 +5974,7 @@ const Editor = React.forwardRef(({
|
|
|
5974
5974
|
setCharCount(plainText.length);
|
|
5975
5975
|
setWordCount(plainText.split(/\s+/).filter((w) => w.length > 0).length);
|
|
5976
5976
|
}, []);
|
|
5977
|
-
const renderFromYDoc =
|
|
5977
|
+
const renderFromYDoc = m.useCallback(async () => {
|
|
5978
5978
|
if (!collabEnabled || !yBlocksMap || !yDoc) {
|
|
5979
5979
|
return;
|
|
5980
5980
|
}
|
|
@@ -6089,10 +6089,10 @@ const Editor = React.forwardRef(({
|
|
|
6089
6089
|
isApplyingRemoteRef.current = false;
|
|
6090
6090
|
}
|
|
6091
6091
|
}, [collabEnabled, yBlocksMap, yDoc, yMetaMap]);
|
|
6092
|
-
|
|
6092
|
+
m.useEffect(() => {
|
|
6093
6093
|
renderFromYDocRef.current = renderFromYDoc;
|
|
6094
6094
|
}, [renderFromYDoc]);
|
|
6095
|
-
const pushLocalToCollab =
|
|
6095
|
+
const pushLocalToCollab = m.useCallback((payload) => {
|
|
6096
6096
|
console.log("[Magic Editor X] [PUSH] pushLocalToCollab called, enabled:", collabEnabled, "yDoc:", !!yDoc, "yBlocksMap:", !!yBlocksMap);
|
|
6097
6097
|
if (!collabEnabled || !yDoc || !yBlocksMap) {
|
|
6098
6098
|
console.log("[Magic Editor X] [SKIP] Skipping push - not enabled or missing yDoc/yBlocksMap");
|
|
@@ -6137,20 +6137,20 @@ const Editor = React.forwardRef(({
|
|
|
6137
6137
|
console.error("[Magic Editor X] Failed to push local update", error2);
|
|
6138
6138
|
}
|
|
6139
6139
|
}, [collabEnabled, yDoc, yBlocksMap, yMetaMap]);
|
|
6140
|
-
const pushLocalToCollabRef =
|
|
6141
|
-
|
|
6140
|
+
const pushLocalToCollabRef = m.useRef(pushLocalToCollab);
|
|
6141
|
+
m.useEffect(() => {
|
|
6142
6142
|
pushLocalToCollabRef.current = pushLocalToCollab;
|
|
6143
6143
|
}, [pushLocalToCollab]);
|
|
6144
6144
|
const customPlaceholder = attribute?.options?.placeholder || placeholder || "Start writing your amazing content...";
|
|
6145
6145
|
attribute?.options?.minHeight || 400;
|
|
6146
|
-
const mediaLibToggleFunc =
|
|
6146
|
+
const mediaLibToggleFunc = m.useCallback(
|
|
6147
6147
|
getToggleFunc({
|
|
6148
6148
|
openStateSetter: setIsMediaLibOpen,
|
|
6149
6149
|
indexStateSetter: setMediaLibBlockIndex
|
|
6150
6150
|
}),
|
|
6151
6151
|
[]
|
|
6152
6152
|
);
|
|
6153
|
-
const handleMediaLibChange =
|
|
6153
|
+
const handleMediaLibChange = m.useCallback(
|
|
6154
6154
|
(data) => {
|
|
6155
6155
|
changeFunc({
|
|
6156
6156
|
indexStateSetter: setMediaLibBlockIndex,
|
|
@@ -6162,8 +6162,8 @@ const Editor = React.forwardRef(({
|
|
|
6162
6162
|
},
|
|
6163
6163
|
[mediaLibBlockIndex, mediaLibToggleFunc]
|
|
6164
6164
|
);
|
|
6165
|
-
const [customBlockImageCallback, setCustomBlockImageCallback] =
|
|
6166
|
-
const handleCustomBlockMediaLibChange =
|
|
6165
|
+
const [customBlockImageCallback, setCustomBlockImageCallback] = m.useState(null);
|
|
6166
|
+
const handleCustomBlockMediaLibChange = m.useCallback((data) => {
|
|
6167
6167
|
if (customBlockImageCallback && window.__MAGIC_EDITOR_IMAGE_CALLBACKS__) {
|
|
6168
6168
|
const callback = window.__MAGIC_EDITOR_IMAGE_CALLBACKS__[customBlockImageCallback];
|
|
6169
6169
|
if (callback) {
|
|
@@ -6182,7 +6182,7 @@ const Editor = React.forwardRef(({
|
|
|
6182
6182
|
setCustomBlockImageCallback(null);
|
|
6183
6183
|
setIsMediaLibOpen(false);
|
|
6184
6184
|
}, [customBlockImageCallback]);
|
|
6185
|
-
|
|
6185
|
+
m.useEffect(() => {
|
|
6186
6186
|
const handleOpenMediaLib = (event) => {
|
|
6187
6187
|
const { callbackId, allowedTypes } = event.detail || {};
|
|
6188
6188
|
if (callbackId) {
|
|
@@ -6193,7 +6193,7 @@ const Editor = React.forwardRef(({
|
|
|
6193
6193
|
window.addEventListener("magic-editor-open-media-lib", handleOpenMediaLib);
|
|
6194
6194
|
return () => window.removeEventListener("magic-editor-open-media-lib", handleOpenMediaLib);
|
|
6195
6195
|
}, []);
|
|
6196
|
-
const toggleFullscreen =
|
|
6196
|
+
const toggleFullscreen = m.useCallback(() => {
|
|
6197
6197
|
setIsFullscreen((prev) => {
|
|
6198
6198
|
if (!prev) {
|
|
6199
6199
|
document.body.classList.add("editor-fullscreen");
|
|
@@ -6203,7 +6203,7 @@ const Editor = React.forwardRef(({
|
|
|
6203
6203
|
return !prev;
|
|
6204
6204
|
});
|
|
6205
6205
|
}, []);
|
|
6206
|
-
|
|
6206
|
+
m.useEffect(() => {
|
|
6207
6207
|
const handleKeyDown = (e) => {
|
|
6208
6208
|
if (e.key === "Escape" && isFullscreen) {
|
|
6209
6209
|
toggleFullscreen();
|
|
@@ -6215,7 +6215,7 @@ const Editor = React.forwardRef(({
|
|
|
6215
6215
|
window.addEventListener("keydown", handleKeyDown);
|
|
6216
6216
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
6217
6217
|
}, [isFullscreen, toggleFullscreen]);
|
|
6218
|
-
const handleAIAssistant =
|
|
6218
|
+
const handleAIAssistant = m.useCallback(() => {
|
|
6219
6219
|
const selection = window.getSelection();
|
|
6220
6220
|
let text = selection?.toString().trim();
|
|
6221
6221
|
if (!text && editorInstanceRef.current && isReady) {
|
|
@@ -6256,7 +6256,7 @@ const Editor = React.forwardRef(({
|
|
|
6256
6256
|
setAISelectedText(text);
|
|
6257
6257
|
setShowAIToolbar(true);
|
|
6258
6258
|
}, [isReady]);
|
|
6259
|
-
const handleInsertBlock =
|
|
6259
|
+
const handleInsertBlock = m.useCallback((blockType) => {
|
|
6260
6260
|
if (!editorInstanceRef.current || !isReady) return;
|
|
6261
6261
|
if (blockType === "mediaLib") {
|
|
6262
6262
|
if (collabEnabled && collabCanEdit === false) {
|
|
@@ -6276,7 +6276,7 @@ const Editor = React.forwardRef(({
|
|
|
6276
6276
|
editor.blocks.insert(blockType, {}, {}, lastIndex, true);
|
|
6277
6277
|
editor.caret.setToBlock(lastIndex);
|
|
6278
6278
|
}, [isReady, collabEnabled, collabCanEdit]);
|
|
6279
|
-
const handleClear =
|
|
6279
|
+
const handleClear = m.useCallback(async () => {
|
|
6280
6280
|
if (!editorInstanceRef.current || !isReady) return;
|
|
6281
6281
|
if (window.confirm("Clear all content? This cannot be undone.")) {
|
|
6282
6282
|
await editorInstanceRef.current.clear();
|
|
@@ -6289,12 +6289,12 @@ const Editor = React.forwardRef(({
|
|
|
6289
6289
|
setCharCount(0);
|
|
6290
6290
|
}
|
|
6291
6291
|
}, [isReady, name, onChange, pushLocalToCollab]);
|
|
6292
|
-
const handleCopy =
|
|
6292
|
+
const handleCopy = m.useCallback(async () => {
|
|
6293
6293
|
if (!editorInstanceRef.current || !isReady) return;
|
|
6294
6294
|
const data = await editorInstanceRef.current.save();
|
|
6295
6295
|
await navigator.clipboard.writeText(JSON.stringify(data, null, 2));
|
|
6296
6296
|
}, [isReady]);
|
|
6297
|
-
|
|
6297
|
+
m.useEffect(() => {
|
|
6298
6298
|
if (isLoadingCustomBlocks) {
|
|
6299
6299
|
console.log("[Magic Editor X] Waiting for custom blocks to load...");
|
|
6300
6300
|
return;
|
|
@@ -6491,7 +6491,7 @@ const Editor = React.forwardRef(({
|
|
|
6491
6491
|
document.body.classList.remove("editor-fullscreen");
|
|
6492
6492
|
};
|
|
6493
6493
|
}, [isLoadingCustomBlocks, customBlocks]);
|
|
6494
|
-
|
|
6494
|
+
m.useEffect(() => {
|
|
6495
6495
|
const editor = editorInstanceRef.current;
|
|
6496
6496
|
if (!editor || !isReady) return;
|
|
6497
6497
|
const shouldBeReadOnly = disabled || collabEnabled && collabCanEdit === false;
|
|
@@ -6529,11 +6529,11 @@ const Editor = React.forwardRef(({
|
|
|
6529
6529
|
{ icon: outline.ExclamationTriangleIcon, label: "Warning", block: "warning" },
|
|
6530
6530
|
{ icon: outline.MinusIcon, label: "Divider", block: "delimiter" }
|
|
6531
6531
|
];
|
|
6532
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.
|
|
6532
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Hm.Root, { name, id: name, error, required, hint, children: [
|
|
6533
6533
|
/* @__PURE__ */ jsxRuntime.jsx(FullscreenGlobalStyle, {}),
|
|
6534
6534
|
/* @__PURE__ */ jsxRuntime.jsx(EditorJSGlobalStyles, {}),
|
|
6535
6535
|
/* @__PURE__ */ jsxRuntime.jsx(tools.AIToast, {}),
|
|
6536
|
-
label && !isFullscreen && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
6536
|
+
label && !isFullscreen && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Hm.Label, { action: labelAction, children: label }),
|
|
6537
6537
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6538
6538
|
EditorContainer,
|
|
6539
6539
|
{
|
|
@@ -6747,7 +6747,7 @@ const Editor = React.forwardRef(({
|
|
|
6747
6747
|
onBlur: () => setIsFocused(false),
|
|
6748
6748
|
children: [
|
|
6749
6749
|
!isReady && /* @__PURE__ */ jsxRuntime.jsxs(LoadingOverlay, { children: [
|
|
6750
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
6750
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.Vd, { small: true }),
|
|
6751
6751
|
/* @__PURE__ */ jsxRuntime.jsx(LoadingText, { children: "Initializing editor..." })
|
|
6752
6752
|
] }),
|
|
6753
6753
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6832,8 +6832,8 @@ const Editor = React.forwardRef(({
|
|
|
6832
6832
|
}
|
|
6833
6833
|
),
|
|
6834
6834
|
!isFullscreen && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6835
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
6836
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
6835
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.Hm.Hint, {}),
|
|
6836
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.Hm.Error, {})
|
|
6837
6837
|
] }),
|
|
6838
6838
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6839
6839
|
MediaLibComponent,
|