magic-editor-x 1.4.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-ByYQ99dO.js → App-DImBvISP.js} +59 -59
- package/dist/_chunks/{App-C8q91Ico.mjs → App-iNfbV7cz.mjs} +32 -32
- package/dist/_chunks/{CustomBlocksPage-rLRB05j0.mjs → CustomBlocksPage-COPOZ2-_.mjs} +2 -1
- package/dist/_chunks/{CustomBlocksPage-BkmF2iOQ.js → CustomBlocksPage-Cj-0TTUs.js} +14 -13
- package/dist/_chunks/{LicensePage-Bdn7zWU2.js → LicensePage-CmvILX9m.js} +43 -43
- package/dist/_chunks/{LicensePage-DR_Cwyfw.mjs → LicensePage-gLRoo8WJ.mjs} +38 -38
- package/dist/_chunks/{LiveCollaborationPanel-BUHIq0CQ.js → LiveCollaborationPanel-BFybu8h0.js} +7 -7
- package/dist/_chunks/{LiveCollaborationPanel-0tplv17N.mjs → LiveCollaborationPanel-CVgl4IyR.mjs} +3 -3
- package/dist/_chunks/{Settings-FfpVHlpw.mjs → Settings-ButYcfrm.mjs} +82 -82
- package/dist/_chunks/Settings-BzGqgrxD.js +440 -0
- package/dist/_chunks/{getTranslation-DOJ3x1SL.js → getTranslation-BADoesEn.js} +19120 -12315
- package/dist/_chunks/{getTranslation-Bk8tKbUs.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-DzixAi6O.js → index-DDFAuQNT.js} +360 -180
- package/dist/_chunks/{index-zOiCW1bZ.mjs → index-DEi6nwfM.mjs} +215 -35
- 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-B5mffA2O.js +0 -440
- package/dist/_chunks/index-C5DuaTDl.js +0 -2550
- package/dist/_chunks/index-DkpTkVe7.mjs +0 -2551
|
@@ -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);
|
|
@@ -2343,6 +2343,9 @@ function createSimpleBlock(config) {
|
|
|
2343
2343
|
this.data[field.name] = input.value;
|
|
2344
2344
|
});
|
|
2345
2345
|
break;
|
|
2346
|
+
case "image":
|
|
2347
|
+
input = this._createImageField(field);
|
|
2348
|
+
break;
|
|
2346
2349
|
default:
|
|
2347
2350
|
input = document.createElement("input");
|
|
2348
2351
|
input.type = field.type || "text";
|
|
@@ -2365,6 +2368,146 @@ function createSimpleBlock(config) {
|
|
|
2365
2368
|
container.appendChild(input);
|
|
2366
2369
|
return container;
|
|
2367
2370
|
}
|
|
2371
|
+
/**
|
|
2372
|
+
* Create image field with Media Library integration
|
|
2373
|
+
* @param {object} field - Field configuration
|
|
2374
|
+
* @returns {HTMLElement}
|
|
2375
|
+
*/
|
|
2376
|
+
_createImageField(field) {
|
|
2377
|
+
const wrapper = document.createElement("div");
|
|
2378
|
+
wrapper.style.cssText = `
|
|
2379
|
+
border: 2px dashed #e2e8f0;
|
|
2380
|
+
border-radius: 8px;
|
|
2381
|
+
padding: 16px;
|
|
2382
|
+
text-align: center;
|
|
2383
|
+
background: #fafbfc;
|
|
2384
|
+
transition: all 0.2s ease;
|
|
2385
|
+
`;
|
|
2386
|
+
const preview = document.createElement("div");
|
|
2387
|
+
preview.className = "image-preview";
|
|
2388
|
+
preview.style.cssText = `
|
|
2389
|
+
margin-bottom: 12px;
|
|
2390
|
+
min-height: 60px;
|
|
2391
|
+
display: flex;
|
|
2392
|
+
align-items: center;
|
|
2393
|
+
justify-content: center;
|
|
2394
|
+
`;
|
|
2395
|
+
const img = document.createElement("img");
|
|
2396
|
+
img.style.cssText = `
|
|
2397
|
+
max-width: 100%;
|
|
2398
|
+
max-height: 150px;
|
|
2399
|
+
border-radius: 6px;
|
|
2400
|
+
display: none;
|
|
2401
|
+
`;
|
|
2402
|
+
const placeholder = document.createElement("div");
|
|
2403
|
+
placeholder.innerHTML = `
|
|
2404
|
+
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#94a3b8" stroke-width="1.5">
|
|
2405
|
+
<rect x="3" y="3" width="18" height="18" rx="2"/>
|
|
2406
|
+
<circle cx="8.5" cy="8.5" r="1.5"/>
|
|
2407
|
+
<path d="M21 15l-5-5L5 21"/>
|
|
2408
|
+
</svg>
|
|
2409
|
+
<p style="margin: 8px 0 0; color: #94a3b8; font-size: 13px;">No image selected</p>
|
|
2410
|
+
`;
|
|
2411
|
+
placeholder.style.cssText = "text-align: center;";
|
|
2412
|
+
preview.appendChild(img);
|
|
2413
|
+
preview.appendChild(placeholder);
|
|
2414
|
+
const updatePreview = (url) => {
|
|
2415
|
+
if (url) {
|
|
2416
|
+
img.src = url;
|
|
2417
|
+
img.style.display = "block";
|
|
2418
|
+
placeholder.style.display = "none";
|
|
2419
|
+
wrapper.style.borderStyle = "solid";
|
|
2420
|
+
wrapper.style.borderColor = "#c4b5fd";
|
|
2421
|
+
} else {
|
|
2422
|
+
img.style.display = "none";
|
|
2423
|
+
placeholder.style.display = "block";
|
|
2424
|
+
wrapper.style.borderStyle = "dashed";
|
|
2425
|
+
wrapper.style.borderColor = "#e2e8f0";
|
|
2426
|
+
}
|
|
2427
|
+
};
|
|
2428
|
+
const currentValue = this.data[field.name];
|
|
2429
|
+
if (currentValue && typeof currentValue === "object") {
|
|
2430
|
+
updatePreview(currentValue.url);
|
|
2431
|
+
} else if (typeof currentValue === "string" && currentValue) {
|
|
2432
|
+
updatePreview(currentValue);
|
|
2433
|
+
}
|
|
2434
|
+
const buttons = document.createElement("div");
|
|
2435
|
+
buttons.style.cssText = "display: flex; gap: 8px; justify-content: center;";
|
|
2436
|
+
const selectBtn = document.createElement("button");
|
|
2437
|
+
selectBtn.type = "button";
|
|
2438
|
+
selectBtn.textContent = "Select Image";
|
|
2439
|
+
selectBtn.style.cssText = `
|
|
2440
|
+
padding: 8px 16px;
|
|
2441
|
+
background: linear-gradient(135deg, #7c3aed 0%, #6d28d9 100%);
|
|
2442
|
+
color: white;
|
|
2443
|
+
border: none;
|
|
2444
|
+
border-radius: 6px;
|
|
2445
|
+
font-size: 13px;
|
|
2446
|
+
font-weight: 600;
|
|
2447
|
+
cursor: pointer;
|
|
2448
|
+
transition: all 0.2s ease;
|
|
2449
|
+
`;
|
|
2450
|
+
selectBtn.addEventListener("mouseenter", () => {
|
|
2451
|
+
selectBtn.style.transform = "translateY(-1px)";
|
|
2452
|
+
selectBtn.style.boxShadow = "0 4px 12px rgba(124, 58, 237, 0.35)";
|
|
2453
|
+
});
|
|
2454
|
+
selectBtn.addEventListener("mouseleave", () => {
|
|
2455
|
+
selectBtn.style.transform = "translateY(0)";
|
|
2456
|
+
selectBtn.style.boxShadow = "none";
|
|
2457
|
+
});
|
|
2458
|
+
const removeBtn = document.createElement("button");
|
|
2459
|
+
removeBtn.type = "button";
|
|
2460
|
+
removeBtn.textContent = "Remove";
|
|
2461
|
+
removeBtn.style.cssText = `
|
|
2462
|
+
padding: 8px 16px;
|
|
2463
|
+
background: transparent;
|
|
2464
|
+
color: #ef4444;
|
|
2465
|
+
border: 1px solid #fecaca;
|
|
2466
|
+
border-radius: 6px;
|
|
2467
|
+
font-size: 13px;
|
|
2468
|
+
font-weight: 600;
|
|
2469
|
+
cursor: pointer;
|
|
2470
|
+
transition: all 0.2s ease;
|
|
2471
|
+
display: ${this.data[field.name] ? "inline-block" : "none"};
|
|
2472
|
+
`;
|
|
2473
|
+
removeBtn.addEventListener("click", () => {
|
|
2474
|
+
this.data[field.name] = null;
|
|
2475
|
+
updatePreview(null);
|
|
2476
|
+
removeBtn.style.display = "none";
|
|
2477
|
+
});
|
|
2478
|
+
selectBtn.addEventListener("click", () => {
|
|
2479
|
+
if (this.readOnly) return;
|
|
2480
|
+
const callbackId = `image_field_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
2481
|
+
window.__MAGIC_EDITOR_IMAGE_CALLBACKS__ = window.__MAGIC_EDITOR_IMAGE_CALLBACKS__ || {};
|
|
2482
|
+
window.__MAGIC_EDITOR_IMAGE_CALLBACKS__[callbackId] = (files) => {
|
|
2483
|
+
if (files && files.length > 0) {
|
|
2484
|
+
const file = files[0];
|
|
2485
|
+
const imageData = {
|
|
2486
|
+
url: file.url,
|
|
2487
|
+
alt: file.alt || file.name || "",
|
|
2488
|
+
width: file.width,
|
|
2489
|
+
height: file.height,
|
|
2490
|
+
id: file.id,
|
|
2491
|
+
documentId: file.documentId
|
|
2492
|
+
};
|
|
2493
|
+
this.data[field.name] = imageData;
|
|
2494
|
+
updatePreview(imageData.url);
|
|
2495
|
+
removeBtn.style.display = "inline-block";
|
|
2496
|
+
}
|
|
2497
|
+
delete window.__MAGIC_EDITOR_IMAGE_CALLBACKS__[callbackId];
|
|
2498
|
+
};
|
|
2499
|
+
window.dispatchEvent(new CustomEvent("magic-editor-open-media-lib", {
|
|
2500
|
+
detail: { callbackId, fieldName: field.name, allowedTypes: ["images"] }
|
|
2501
|
+
}));
|
|
2502
|
+
});
|
|
2503
|
+
buttons.appendChild(selectBtn);
|
|
2504
|
+
buttons.appendChild(removeBtn);
|
|
2505
|
+
wrapper.appendChild(preview);
|
|
2506
|
+
if (!this.readOnly) {
|
|
2507
|
+
wrapper.appendChild(buttons);
|
|
2508
|
+
}
|
|
2509
|
+
return wrapper;
|
|
2510
|
+
}
|
|
2368
2511
|
/**
|
|
2369
2512
|
* Escape HTML special characters
|
|
2370
2513
|
* @param {string} text - Text to escape
|
|
@@ -2418,11 +2561,11 @@ function createBlockClasses(blockConfigs) {
|
|
|
2418
2561
|
}
|
|
2419
2562
|
function useCustomBlocks() {
|
|
2420
2563
|
const { get } = admin.useFetchClient();
|
|
2421
|
-
const [customBlocks, setCustomBlocks] =
|
|
2422
|
-
const [isLoading, setIsLoading] =
|
|
2423
|
-
const [error, setError] =
|
|
2424
|
-
const [lastFetched, setLastFetched] =
|
|
2425
|
-
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 () => {
|
|
2426
2569
|
try {
|
|
2427
2570
|
setIsLoading(true);
|
|
2428
2571
|
setError(null);
|
|
@@ -2441,10 +2584,10 @@ function useCustomBlocks() {
|
|
|
2441
2584
|
setIsLoading(false);
|
|
2442
2585
|
}
|
|
2443
2586
|
}, [get]);
|
|
2444
|
-
const refresh =
|
|
2587
|
+
const refresh = m.useCallback(() => {
|
|
2445
2588
|
return fetchCustomBlocks();
|
|
2446
2589
|
}, [fetchCustomBlocks]);
|
|
2447
|
-
|
|
2590
|
+
m.useEffect(() => {
|
|
2448
2591
|
fetchCustomBlocks();
|
|
2449
2592
|
}, [fetchCustomBlocks]);
|
|
2450
2593
|
return {
|
|
@@ -2696,14 +2839,14 @@ const SparklesIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "24",
|
|
|
2696
2839
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M17 19h4" })
|
|
2697
2840
|
] });
|
|
2698
2841
|
const AIAssistantPopup = ({ selectedText, licenseKey, onClose, onApply }) => {
|
|
2699
|
-
const [activeType, setActiveType] =
|
|
2700
|
-
const [isLoading, setIsLoading] =
|
|
2701
|
-
const [result, setResult] =
|
|
2702
|
-
const [error, setError] =
|
|
2703
|
-
const [credits, setCredits] =
|
|
2704
|
-
const [usage, setUsage] =
|
|
2705
|
-
const [apiClient, setApiClient] =
|
|
2706
|
-
|
|
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(() => {
|
|
2707
2850
|
if (licenseKey) {
|
|
2708
2851
|
const client = new tools.MagicEditorAPI(licenseKey);
|
|
2709
2852
|
setApiClient(client);
|
|
@@ -2715,7 +2858,7 @@ const AIAssistantPopup = ({ selectedText, licenseKey, onClose, onApply }) => {
|
|
|
2715
2858
|
});
|
|
2716
2859
|
}
|
|
2717
2860
|
}, [licenseKey]);
|
|
2718
|
-
const handleCorrection =
|
|
2861
|
+
const handleCorrection = m.useCallback(async (type) => {
|
|
2719
2862
|
if (!apiClient || !selectedText) return;
|
|
2720
2863
|
setActiveType(type);
|
|
2721
2864
|
setIsLoading(true);
|
|
@@ -2745,7 +2888,7 @@ const AIAssistantPopup = ({ selectedText, licenseKey, onClose, onApply }) => {
|
|
|
2745
2888
|
setIsLoading(false);
|
|
2746
2889
|
}
|
|
2747
2890
|
}, [apiClient, selectedText]);
|
|
2748
|
-
const handleApply =
|
|
2891
|
+
const handleApply = m.useCallback(() => {
|
|
2749
2892
|
if (result?.corrected) {
|
|
2750
2893
|
onApply(result.corrected);
|
|
2751
2894
|
}
|
|
@@ -2755,7 +2898,7 @@ const AIAssistantPopup = ({ selectedText, licenseKey, onClose, onApply }) => {
|
|
|
2755
2898
|
onClose();
|
|
2756
2899
|
}
|
|
2757
2900
|
};
|
|
2758
|
-
|
|
2901
|
+
m.useEffect(() => {
|
|
2759
2902
|
const handleKeyDown = (e) => {
|
|
2760
2903
|
if (e.key === "Escape") {
|
|
2761
2904
|
onClose();
|
|
@@ -2864,7 +3007,7 @@ const AIAssistantPopup = ({ selectedText, licenseKey, onClose, onApply }) => {
|
|
|
2864
3007
|
] })
|
|
2865
3008
|
] }) });
|
|
2866
3009
|
};
|
|
2867
|
-
const PanelWrapper = styled__default.default(getTranslation.
|
|
3010
|
+
const PanelWrapper = styled__default.default(getTranslation.R)`
|
|
2868
3011
|
width: 320px;
|
|
2869
3012
|
background: ${({ theme }) => theme.colors.neutral0};
|
|
2870
3013
|
border: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
@@ -2874,25 +3017,25 @@ const PanelWrapper = styled__default.default(getTranslation.Box)`
|
|
|
2874
3017
|
flex-direction: column;
|
|
2875
3018
|
max-height: 70vh;
|
|
2876
3019
|
`;
|
|
2877
|
-
const Header$1 = styled__default.default(getTranslation.
|
|
3020
|
+
const Header$1 = styled__default.default(getTranslation.T)`
|
|
2878
3021
|
padding: 12px 16px;
|
|
2879
3022
|
border-bottom: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
2880
3023
|
`;
|
|
2881
|
-
const Content$1 = styled__default.default(getTranslation.
|
|
3024
|
+
const Content$1 = styled__default.default(getTranslation.R)`
|
|
2882
3025
|
padding: 12px 16px;
|
|
2883
3026
|
overflow-y: auto;
|
|
2884
3027
|
`;
|
|
2885
|
-
const Item = styled__default.default(getTranslation.
|
|
3028
|
+
const Item = styled__default.default(getTranslation.R)`
|
|
2886
3029
|
padding: 10px 12px;
|
|
2887
3030
|
border: 1px solid ${({ theme }) => theme.colors.neutral150};
|
|
2888
3031
|
border-radius: 6px;
|
|
2889
3032
|
margin-bottom: 10px;
|
|
2890
3033
|
`;
|
|
2891
|
-
const Meta = styled__default.default(getTranslation.
|
|
3034
|
+
const Meta = styled__default.default(getTranslation.I)`
|
|
2892
3035
|
color: ${({ theme }) => theme.colors.neutral500};
|
|
2893
3036
|
font-size: 12px;
|
|
2894
3037
|
`;
|
|
2895
|
-
const PremiumBadge = styled__default.default(getTranslation.
|
|
3038
|
+
const PremiumBadge = styled__default.default(getTranslation.R)`
|
|
2896
3039
|
background: ${({ theme }) => theme.colors.primary100};
|
|
2897
3040
|
color: ${({ theme }) => theme.colors.primary600};
|
|
2898
3041
|
border-radius: 6px;
|
|
@@ -2941,33 +3084,33 @@ const VersionHistoryPanel = ({
|
|
|
2941
3084
|
);
|
|
2942
3085
|
return /* @__PURE__ */ jsxRuntime.jsxs(PanelWrapper, { "data-testid": "version-history-panel", children: [
|
|
2943
3086
|
/* @__PURE__ */ jsxRuntime.jsxs(Header$1, { justifyContent: "space-between", alignItems: "center", children: [
|
|
2944
|
-
/* @__PURE__ */ jsxRuntime.jsxs(getTranslation.
|
|
3087
|
+
/* @__PURE__ */ jsxRuntime.jsxs(getTranslation.T, { gap: 8, alignItems: "center", children: [
|
|
2945
3088
|
/* @__PURE__ */ jsxRuntime.jsx(outline.ClockIcon, { width: 18 }),
|
|
2946
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3089
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.I, { fontWeight: "bold", children: t("versionHistory.title", "Version History") })
|
|
2947
3090
|
] }),
|
|
2948
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3091
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.zn, { size: "S", variant: "tertiary", onClick: onClose, children: t("versionHistory.close", "Close") })
|
|
2949
3092
|
] }),
|
|
2950
3093
|
/* @__PURE__ */ jsxRuntime.jsxs(Content$1, { children: [
|
|
2951
|
-
loading && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
2952
|
-
error && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
2953
|
-
!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") }),
|
|
2954
3097
|
!loading && !error && snapshots.map((snap) => /* @__PURE__ */ jsxRuntime.jsxs(Item, { children: [
|
|
2955
|
-
/* @__PURE__ */ jsxRuntime.jsxs(getTranslation.
|
|
2956
|
-
/* @__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: [
|
|
2957
3100
|
t("versionHistory.version", "Version"),
|
|
2958
3101
|
" ",
|
|
2959
3102
|
snap.version
|
|
2960
3103
|
] }),
|
|
2961
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
3104
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.I, { variant: "pi", children: formatDate(snap.createdAt) })
|
|
2962
3105
|
] }),
|
|
2963
3106
|
/* @__PURE__ */ jsxRuntime.jsxs(Meta, { children: [
|
|
2964
3107
|
t("versionHistory.createdBy", "By"),
|
|
2965
3108
|
" ",
|
|
2966
3109
|
snap.createdBy?.firstname ? `${snap.createdBy.firstname} ${snap.createdBy.lastname || ""}`.trim() : "—"
|
|
2967
3110
|
] }),
|
|
2968
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
2969
|
-
canRestore ? /* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
2970
|
-
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,
|
|
2971
3114
|
{
|
|
2972
3115
|
size: "S",
|
|
2973
3116
|
variant: "secondary",
|
|
@@ -2979,9 +3122,9 @@ const VersionHistoryPanel = ({
|
|
|
2979
3122
|
t("versionHistory.premiumOnly", "Premium feature")
|
|
2980
3123
|
] })
|
|
2981
3124
|
] }, snap.documentId || snap.id)),
|
|
2982
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
2983
|
-
canRestore ? /* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
2984
|
-
/* @__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") }),
|
|
2985
3128
|
/* @__PURE__ */ jsxRuntime.jsxs(PremiumBadge, { style: { marginTop: "8px", width: "100%", justifyContent: "center" }, children: [
|
|
2986
3129
|
/* @__PURE__ */ jsxRuntime.jsx(outline.ExclamationTriangleIcon, { width: 16 }),
|
|
2987
3130
|
t("versionHistory.premiumOnly", "Premium feature")
|
|
@@ -5170,7 +5313,7 @@ const getPeerName = (user = {}) => {
|
|
|
5170
5313
|
}
|
|
5171
5314
|
return user.email?.split("@")[0] || "Anonymous";
|
|
5172
5315
|
};
|
|
5173
|
-
const Editor =
|
|
5316
|
+
const Editor = m.forwardRef(({
|
|
5174
5317
|
name,
|
|
5175
5318
|
value,
|
|
5176
5319
|
onChange,
|
|
@@ -5189,14 +5332,14 @@ const Editor = React.forwardRef(({
|
|
|
5189
5332
|
const { licenseData, tier: licenseTier } = useLicense();
|
|
5190
5333
|
const { isAvailable: isWebtoolsAvailable, openLinkPicker: webtoolsOpenLinkPicker } = useWebtoolsLinks();
|
|
5191
5334
|
const { customBlocks, isLoading: isLoadingCustomBlocks } = useCustomBlocks();
|
|
5192
|
-
const editorRef =
|
|
5193
|
-
const editorInstanceRef =
|
|
5194
|
-
const containerRef =
|
|
5195
|
-
const webtoolsSelectionRef =
|
|
5196
|
-
const isReadyRef =
|
|
5197
|
-
const [isReady, setIsReady] =
|
|
5198
|
-
const [showCreditsModal, setShowCreditsModal] =
|
|
5199
|
-
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);
|
|
5200
5343
|
const { handleAIAction } = useAIActions({
|
|
5201
5344
|
licenseKey: licenseData?.licenseKey,
|
|
5202
5345
|
editorInstanceRef,
|
|
@@ -5206,7 +5349,7 @@ const Editor = React.forwardRef(({
|
|
|
5206
5349
|
setShowCreditsModal(true);
|
|
5207
5350
|
}
|
|
5208
5351
|
});
|
|
5209
|
-
|
|
5352
|
+
m.useEffect(() => {
|
|
5210
5353
|
if (licenseData?.licenseKey) {
|
|
5211
5354
|
window.__MAGIC_EDITOR_LICENSE_KEY__ = licenseData.licenseKey;
|
|
5212
5355
|
}
|
|
@@ -5214,22 +5357,22 @@ const Editor = React.forwardRef(({
|
|
|
5214
5357
|
delete window.__MAGIC_EDITOR_LICENSE_KEY__;
|
|
5215
5358
|
};
|
|
5216
5359
|
}, [licenseData?.licenseKey]);
|
|
5217
|
-
const [blocksCount, setBlocksCount] =
|
|
5218
|
-
const [wordCount, setWordCount] =
|
|
5219
|
-
const [charCount, setCharCount] =
|
|
5220
|
-
const [isFocused, setIsFocused] =
|
|
5221
|
-
const [isFullscreen, setIsFullscreen] =
|
|
5222
|
-
const [editorHeight, setEditorHeight] =
|
|
5223
|
-
const [mediaLibBlockIndex, setMediaLibBlockIndex] =
|
|
5224
|
-
const [isMediaLibOpen, setIsMediaLibOpen] =
|
|
5225
|
-
const [showAIPopup, setShowAIPopup] =
|
|
5226
|
-
const [showAIToolbar, setShowAIToolbar] =
|
|
5227
|
-
const [aiToolbarPosition, setAIToolbarPosition] =
|
|
5228
|
-
const [aiSelectedText, setAISelectedText] =
|
|
5229
|
-
const aiSelectionRangeRef =
|
|
5230
|
-
const [aiLoading, setAILoading] =
|
|
5231
|
-
const [showVersionHistory, setShowVersionHistory] =
|
|
5232
|
-
|
|
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(() => {
|
|
5233
5376
|
if (!isWebtoolsAvailable || !editorRef.current) return;
|
|
5234
5377
|
const updateWebtoolsSelection = () => {
|
|
5235
5378
|
const selection = window.getSelection();
|
|
@@ -5273,13 +5416,13 @@ const Editor = React.forwardRef(({
|
|
|
5273
5416
|
document.removeEventListener("selectionchange", updateWebtoolsSelection);
|
|
5274
5417
|
};
|
|
5275
5418
|
}, [isWebtoolsAvailable, isReady]);
|
|
5276
|
-
const serializedInitialValue =
|
|
5419
|
+
const serializedInitialValue = m.useMemo(() => {
|
|
5277
5420
|
if (!value) {
|
|
5278
5421
|
return "";
|
|
5279
5422
|
}
|
|
5280
5423
|
return typeof value === "string" ? value : JSON.stringify(value);
|
|
5281
5424
|
}, [value]);
|
|
5282
|
-
const serializeForCompare =
|
|
5425
|
+
const serializeForCompare = m.useCallback((payload) => {
|
|
5283
5426
|
if (!payload) return "";
|
|
5284
5427
|
try {
|
|
5285
5428
|
const dataObj = typeof payload === "string" ? JSON.parse(payload) : payload;
|
|
@@ -5294,9 +5437,9 @@ const Editor = React.forwardRef(({
|
|
|
5294
5437
|
return "";
|
|
5295
5438
|
}
|
|
5296
5439
|
}, []);
|
|
5297
|
-
const collabRoomId =
|
|
5440
|
+
const collabRoomId = m.useMemo(() => buildRoomId(name), [name]);
|
|
5298
5441
|
const collabEnabled = (attribute?.options?.collaboration?.enabled ?? true) && !disabled;
|
|
5299
|
-
const renderFromYDocRef =
|
|
5442
|
+
const renderFromYDocRef = m.useRef(null);
|
|
5300
5443
|
const {
|
|
5301
5444
|
doc: yDoc,
|
|
5302
5445
|
blocksMap: yBlocksMap,
|
|
@@ -5333,8 +5476,8 @@ const Editor = React.forwardRef(({
|
|
|
5333
5476
|
}
|
|
5334
5477
|
}
|
|
5335
5478
|
});
|
|
5336
|
-
const yTextBindingsRef =
|
|
5337
|
-
const bindBlockToYText =
|
|
5479
|
+
const yTextBindingsRef = m.useRef(/* @__PURE__ */ new Map());
|
|
5480
|
+
const bindBlockToYText = m.useCallback((blockId, element) => {
|
|
5338
5481
|
if (!collabEnabled || !blockId || !element || !yTextMap) return;
|
|
5339
5482
|
if (yTextBindingsRef.current.has(blockId)) {
|
|
5340
5483
|
const existing = yTextBindingsRef.current.get(blockId);
|
|
@@ -5409,7 +5552,7 @@ const Editor = React.forwardRef(({
|
|
|
5409
5552
|
});
|
|
5410
5553
|
console.log("[Magic Editor X] [CHAR-SYNC] Bound block to Y.Text:", blockId);
|
|
5411
5554
|
}, [collabEnabled, yTextMap, yDoc, getBlockText, collabHtmlToDelta, collabDeltaToHtml]);
|
|
5412
|
-
const unbindBlockFromYText =
|
|
5555
|
+
const unbindBlockFromYText = m.useCallback((blockId) => {
|
|
5413
5556
|
const binding = yTextBindingsRef.current.get(blockId);
|
|
5414
5557
|
if (!binding) return;
|
|
5415
5558
|
binding.ytext.unobserve(binding.ytextObserver);
|
|
@@ -5417,7 +5560,7 @@ const Editor = React.forwardRef(({
|
|
|
5417
5560
|
yTextBindingsRef.current.delete(blockId);
|
|
5418
5561
|
console.log("[Magic Editor X] [CHAR-SYNC] Unbound block from Y.Text:", blockId);
|
|
5419
5562
|
}, []);
|
|
5420
|
-
const bindAllBlocksToYText =
|
|
5563
|
+
const bindAllBlocksToYText = m.useCallback(() => {
|
|
5421
5564
|
if (!collabEnabled || !editorInstanceRef.current || !yTextMap) return;
|
|
5422
5565
|
const editor = editorInstanceRef.current;
|
|
5423
5566
|
if (!editor.blocks || typeof editor.blocks.getBlocksCount !== "function") return;
|
|
@@ -5445,8 +5588,8 @@ const Editor = React.forwardRef(({
|
|
|
5445
5588
|
}
|
|
5446
5589
|
}
|
|
5447
5590
|
}, [collabEnabled, yTextMap, getBlockText, setBlockText, bindBlockToYText]);
|
|
5448
|
-
const blockObserverRef =
|
|
5449
|
-
|
|
5591
|
+
const blockObserverRef = m.useRef(null);
|
|
5592
|
+
m.useEffect(() => {
|
|
5450
5593
|
if (!collabEnabled || !editorRef.current || !yTextMap) return;
|
|
5451
5594
|
const observer = new MutationObserver((mutations) => {
|
|
5452
5595
|
let hasNewBlocks = false;
|
|
@@ -5477,7 +5620,7 @@ const Editor = React.forwardRef(({
|
|
|
5477
5620
|
blockObserverRef.current = null;
|
|
5478
5621
|
};
|
|
5479
5622
|
}, [collabEnabled, yTextMap, bindAllBlocksToYText]);
|
|
5480
|
-
|
|
5623
|
+
m.useEffect(() => {
|
|
5481
5624
|
return () => {
|
|
5482
5625
|
yTextBindingsRef.current.forEach((binding, blockId) => {
|
|
5483
5626
|
binding.ytext.unobserve(binding.ytextObserver);
|
|
@@ -5494,12 +5637,12 @@ const Editor = React.forwardRef(({
|
|
|
5494
5637
|
restoreSnapshot,
|
|
5495
5638
|
createSnapshot
|
|
5496
5639
|
} = useVersionHistory();
|
|
5497
|
-
|
|
5640
|
+
m.useEffect(() => {
|
|
5498
5641
|
if (showVersionHistory && collabRoomId) {
|
|
5499
5642
|
fetchSnapshots(collabRoomId);
|
|
5500
5643
|
}
|
|
5501
5644
|
}, [showVersionHistory, collabRoomId, fetchSnapshots]);
|
|
5502
|
-
|
|
5645
|
+
m.useMemo(() => {
|
|
5503
5646
|
switch (collabRole) {
|
|
5504
5647
|
case "viewer":
|
|
5505
5648
|
return { icon: "V", text: "Viewer", color: "#3b82f6" };
|
|
@@ -5511,7 +5654,7 @@ const Editor = React.forwardRef(({
|
|
|
5511
5654
|
return null;
|
|
5512
5655
|
}
|
|
5513
5656
|
}, [collabRole]);
|
|
5514
|
-
|
|
5657
|
+
m.useMemo(() => {
|
|
5515
5658
|
switch (collabStatus) {
|
|
5516
5659
|
case "connected":
|
|
5517
5660
|
if (collabRole === "viewer") {
|
|
@@ -5535,15 +5678,15 @@ const Editor = React.forwardRef(({
|
|
|
5535
5678
|
return "Bereit";
|
|
5536
5679
|
}
|
|
5537
5680
|
}, [collabStatus, collabRole]);
|
|
5538
|
-
|
|
5539
|
-
const activeEditors =
|
|
5681
|
+
m.useMemo(() => collabPeers.slice(0, 3), [collabPeers]);
|
|
5682
|
+
const activeEditors = m.useMemo(() => {
|
|
5540
5683
|
return Object.values(collabAwareness || {}).filter(
|
|
5541
5684
|
(entry) => entry?.user && Date.now() - entry.lastUpdate < 3e4
|
|
5542
5685
|
);
|
|
5543
5686
|
}, [collabAwareness]);
|
|
5544
|
-
const lastCursorUpdateRef =
|
|
5545
|
-
const lastEmittedPositionRef =
|
|
5546
|
-
const getAbsoluteOffset =
|
|
5687
|
+
const lastCursorUpdateRef = m.useRef(0);
|
|
5688
|
+
const lastEmittedPositionRef = m.useRef(null);
|
|
5689
|
+
const getAbsoluteOffset = m.useCallback((container, node, offset) => {
|
|
5547
5690
|
if (!container || !node) return 0;
|
|
5548
5691
|
let absoluteOffset = 0;
|
|
5549
5692
|
const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT, null, false);
|
|
@@ -5557,7 +5700,7 @@ const Editor = React.forwardRef(({
|
|
|
5557
5700
|
}
|
|
5558
5701
|
return absoluteOffset + offset;
|
|
5559
5702
|
}, []);
|
|
5560
|
-
const emitCursorPosition =
|
|
5703
|
+
const emitCursorPosition = m.useCallback(() => {
|
|
5561
5704
|
if (!collabEnabled || !emitAwareness || collabStatus !== "connected") {
|
|
5562
5705
|
return;
|
|
5563
5706
|
}
|
|
@@ -5607,7 +5750,7 @@ const Editor = React.forwardRef(({
|
|
|
5607
5750
|
} catch (err) {
|
|
5608
5751
|
}
|
|
5609
5752
|
}, [collabEnabled, emitAwareness, collabStatus, getAbsoluteOffset]);
|
|
5610
|
-
|
|
5753
|
+
m.useEffect(() => {
|
|
5611
5754
|
if (!collabEnabled || !editorRef.current) {
|
|
5612
5755
|
return void 0;
|
|
5613
5756
|
}
|
|
@@ -5647,7 +5790,7 @@ const Editor = React.forwardRef(({
|
|
|
5647
5790
|
}
|
|
5648
5791
|
};
|
|
5649
5792
|
}, [collabEnabled, emitCursorPosition]);
|
|
5650
|
-
const findTextPosition =
|
|
5793
|
+
const findTextPosition = m.useCallback((container, targetOffset) => {
|
|
5651
5794
|
if (!container || targetOffset === null || targetOffset === void 0) {
|
|
5652
5795
|
return null;
|
|
5653
5796
|
}
|
|
@@ -5677,8 +5820,8 @@ const Editor = React.forwardRef(({
|
|
|
5677
5820
|
}
|
|
5678
5821
|
return null;
|
|
5679
5822
|
}, []);
|
|
5680
|
-
|
|
5681
|
-
|
|
5823
|
+
m.useRef(null);
|
|
5824
|
+
m.useEffect(() => {
|
|
5682
5825
|
if (!collabEnabled || !editorRef.current || !isReady) {
|
|
5683
5826
|
return void 0;
|
|
5684
5827
|
}
|
|
@@ -5788,7 +5931,7 @@ const Editor = React.forwardRef(({
|
|
|
5788
5931
|
cursors?.forEach((el) => el.remove());
|
|
5789
5932
|
};
|
|
5790
5933
|
}, [collabEnabled, activeEditors, isReady, findTextPosition]);
|
|
5791
|
-
|
|
5934
|
+
m.useEffect(() => {
|
|
5792
5935
|
const state = {
|
|
5793
5936
|
status: collabStatus,
|
|
5794
5937
|
peers: collabPeers,
|
|
@@ -5805,13 +5948,13 @@ const Editor = React.forwardRef(({
|
|
|
5805
5948
|
}));
|
|
5806
5949
|
};
|
|
5807
5950
|
}, [collabStatus, collabPeers, collabError]);
|
|
5808
|
-
const isApplyingRemoteRef =
|
|
5809
|
-
const pendingRenderRef =
|
|
5810
|
-
const lastSerializedValueRef =
|
|
5811
|
-
|
|
5951
|
+
const isApplyingRemoteRef = m.useRef(false);
|
|
5952
|
+
const pendingRenderRef = m.useRef(null);
|
|
5953
|
+
const lastSerializedValueRef = m.useRef(serializeForCompare(serializedInitialValue || null));
|
|
5954
|
+
m.useEffect(() => {
|
|
5812
5955
|
lastSerializedValueRef.current = serializeForCompare(serializedInitialValue || null);
|
|
5813
5956
|
}, [serializedInitialValue, serializeForCompare]);
|
|
5814
|
-
const calculateStats =
|
|
5957
|
+
const calculateStats = m.useCallback((data) => {
|
|
5815
5958
|
if (!data?.blocks) {
|
|
5816
5959
|
setWordCount(0);
|
|
5817
5960
|
setCharCount(0);
|
|
@@ -5831,7 +5974,7 @@ const Editor = React.forwardRef(({
|
|
|
5831
5974
|
setCharCount(plainText.length);
|
|
5832
5975
|
setWordCount(plainText.split(/\s+/).filter((w) => w.length > 0).length);
|
|
5833
5976
|
}, []);
|
|
5834
|
-
const renderFromYDoc =
|
|
5977
|
+
const renderFromYDoc = m.useCallback(async () => {
|
|
5835
5978
|
if (!collabEnabled || !yBlocksMap || !yDoc) {
|
|
5836
5979
|
return;
|
|
5837
5980
|
}
|
|
@@ -5946,10 +6089,10 @@ const Editor = React.forwardRef(({
|
|
|
5946
6089
|
isApplyingRemoteRef.current = false;
|
|
5947
6090
|
}
|
|
5948
6091
|
}, [collabEnabled, yBlocksMap, yDoc, yMetaMap]);
|
|
5949
|
-
|
|
6092
|
+
m.useEffect(() => {
|
|
5950
6093
|
renderFromYDocRef.current = renderFromYDoc;
|
|
5951
6094
|
}, [renderFromYDoc]);
|
|
5952
|
-
const pushLocalToCollab =
|
|
6095
|
+
const pushLocalToCollab = m.useCallback((payload) => {
|
|
5953
6096
|
console.log("[Magic Editor X] [PUSH] pushLocalToCollab called, enabled:", collabEnabled, "yDoc:", !!yDoc, "yBlocksMap:", !!yBlocksMap);
|
|
5954
6097
|
if (!collabEnabled || !yDoc || !yBlocksMap) {
|
|
5955
6098
|
console.log("[Magic Editor X] [SKIP] Skipping push - not enabled or missing yDoc/yBlocksMap");
|
|
@@ -5994,20 +6137,20 @@ const Editor = React.forwardRef(({
|
|
|
5994
6137
|
console.error("[Magic Editor X] Failed to push local update", error2);
|
|
5995
6138
|
}
|
|
5996
6139
|
}, [collabEnabled, yDoc, yBlocksMap, yMetaMap]);
|
|
5997
|
-
const pushLocalToCollabRef =
|
|
5998
|
-
|
|
6140
|
+
const pushLocalToCollabRef = m.useRef(pushLocalToCollab);
|
|
6141
|
+
m.useEffect(() => {
|
|
5999
6142
|
pushLocalToCollabRef.current = pushLocalToCollab;
|
|
6000
6143
|
}, [pushLocalToCollab]);
|
|
6001
6144
|
const customPlaceholder = attribute?.options?.placeholder || placeholder || "Start writing your amazing content...";
|
|
6002
6145
|
attribute?.options?.minHeight || 400;
|
|
6003
|
-
const mediaLibToggleFunc =
|
|
6146
|
+
const mediaLibToggleFunc = m.useCallback(
|
|
6004
6147
|
getToggleFunc({
|
|
6005
6148
|
openStateSetter: setIsMediaLibOpen,
|
|
6006
6149
|
indexStateSetter: setMediaLibBlockIndex
|
|
6007
6150
|
}),
|
|
6008
6151
|
[]
|
|
6009
6152
|
);
|
|
6010
|
-
const handleMediaLibChange =
|
|
6153
|
+
const handleMediaLibChange = m.useCallback(
|
|
6011
6154
|
(data) => {
|
|
6012
6155
|
changeFunc({
|
|
6013
6156
|
indexStateSetter: setMediaLibBlockIndex,
|
|
@@ -6019,7 +6162,38 @@ const Editor = React.forwardRef(({
|
|
|
6019
6162
|
},
|
|
6020
6163
|
[mediaLibBlockIndex, mediaLibToggleFunc]
|
|
6021
6164
|
);
|
|
6022
|
-
const
|
|
6165
|
+
const [customBlockImageCallback, setCustomBlockImageCallback] = m.useState(null);
|
|
6166
|
+
const handleCustomBlockMediaLibChange = m.useCallback((data) => {
|
|
6167
|
+
if (customBlockImageCallback && window.__MAGIC_EDITOR_IMAGE_CALLBACKS__) {
|
|
6168
|
+
const callback = window.__MAGIC_EDITOR_IMAGE_CALLBACKS__[customBlockImageCallback];
|
|
6169
|
+
if (callback) {
|
|
6170
|
+
const formattedData = data.map((file) => ({
|
|
6171
|
+
url: file.url,
|
|
6172
|
+
alt: file.alt || file.name || "",
|
|
6173
|
+
width: file.width,
|
|
6174
|
+
height: file.height,
|
|
6175
|
+
id: file.id,
|
|
6176
|
+
documentId: file.documentId,
|
|
6177
|
+
name: file.name
|
|
6178
|
+
}));
|
|
6179
|
+
callback(formattedData);
|
|
6180
|
+
}
|
|
6181
|
+
}
|
|
6182
|
+
setCustomBlockImageCallback(null);
|
|
6183
|
+
setIsMediaLibOpen(false);
|
|
6184
|
+
}, [customBlockImageCallback]);
|
|
6185
|
+
m.useEffect(() => {
|
|
6186
|
+
const handleOpenMediaLib = (event) => {
|
|
6187
|
+
const { callbackId, allowedTypes } = event.detail || {};
|
|
6188
|
+
if (callbackId) {
|
|
6189
|
+
setCustomBlockImageCallback(callbackId);
|
|
6190
|
+
setIsMediaLibOpen(true);
|
|
6191
|
+
}
|
|
6192
|
+
};
|
|
6193
|
+
window.addEventListener("magic-editor-open-media-lib", handleOpenMediaLib);
|
|
6194
|
+
return () => window.removeEventListener("magic-editor-open-media-lib", handleOpenMediaLib);
|
|
6195
|
+
}, []);
|
|
6196
|
+
const toggleFullscreen = m.useCallback(() => {
|
|
6023
6197
|
setIsFullscreen((prev) => {
|
|
6024
6198
|
if (!prev) {
|
|
6025
6199
|
document.body.classList.add("editor-fullscreen");
|
|
@@ -6029,7 +6203,7 @@ const Editor = React.forwardRef(({
|
|
|
6029
6203
|
return !prev;
|
|
6030
6204
|
});
|
|
6031
6205
|
}, []);
|
|
6032
|
-
|
|
6206
|
+
m.useEffect(() => {
|
|
6033
6207
|
const handleKeyDown = (e) => {
|
|
6034
6208
|
if (e.key === "Escape" && isFullscreen) {
|
|
6035
6209
|
toggleFullscreen();
|
|
@@ -6041,7 +6215,7 @@ const Editor = React.forwardRef(({
|
|
|
6041
6215
|
window.addEventListener("keydown", handleKeyDown);
|
|
6042
6216
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
6043
6217
|
}, [isFullscreen, toggleFullscreen]);
|
|
6044
|
-
const handleAIAssistant =
|
|
6218
|
+
const handleAIAssistant = m.useCallback(() => {
|
|
6045
6219
|
const selection = window.getSelection();
|
|
6046
6220
|
let text = selection?.toString().trim();
|
|
6047
6221
|
if (!text && editorInstanceRef.current && isReady) {
|
|
@@ -6082,7 +6256,7 @@ const Editor = React.forwardRef(({
|
|
|
6082
6256
|
setAISelectedText(text);
|
|
6083
6257
|
setShowAIToolbar(true);
|
|
6084
6258
|
}, [isReady]);
|
|
6085
|
-
const handleInsertBlock =
|
|
6259
|
+
const handleInsertBlock = m.useCallback((blockType) => {
|
|
6086
6260
|
if (!editorInstanceRef.current || !isReady) return;
|
|
6087
6261
|
if (blockType === "mediaLib") {
|
|
6088
6262
|
if (collabEnabled && collabCanEdit === false) {
|
|
@@ -6102,7 +6276,7 @@ const Editor = React.forwardRef(({
|
|
|
6102
6276
|
editor.blocks.insert(blockType, {}, {}, lastIndex, true);
|
|
6103
6277
|
editor.caret.setToBlock(lastIndex);
|
|
6104
6278
|
}, [isReady, collabEnabled, collabCanEdit]);
|
|
6105
|
-
const handleClear =
|
|
6279
|
+
const handleClear = m.useCallback(async () => {
|
|
6106
6280
|
if (!editorInstanceRef.current || !isReady) return;
|
|
6107
6281
|
if (window.confirm("Clear all content? This cannot be undone.")) {
|
|
6108
6282
|
await editorInstanceRef.current.clear();
|
|
@@ -6115,12 +6289,12 @@ const Editor = React.forwardRef(({
|
|
|
6115
6289
|
setCharCount(0);
|
|
6116
6290
|
}
|
|
6117
6291
|
}, [isReady, name, onChange, pushLocalToCollab]);
|
|
6118
|
-
const handleCopy =
|
|
6292
|
+
const handleCopy = m.useCallback(async () => {
|
|
6119
6293
|
if (!editorInstanceRef.current || !isReady) return;
|
|
6120
6294
|
const data = await editorInstanceRef.current.save();
|
|
6121
6295
|
await navigator.clipboard.writeText(JSON.stringify(data, null, 2));
|
|
6122
6296
|
}, [isReady]);
|
|
6123
|
-
|
|
6297
|
+
m.useEffect(() => {
|
|
6124
6298
|
if (isLoadingCustomBlocks) {
|
|
6125
6299
|
console.log("[Magic Editor X] Waiting for custom blocks to load...");
|
|
6126
6300
|
return;
|
|
@@ -6317,7 +6491,7 @@ const Editor = React.forwardRef(({
|
|
|
6317
6491
|
document.body.classList.remove("editor-fullscreen");
|
|
6318
6492
|
};
|
|
6319
6493
|
}, [isLoadingCustomBlocks, customBlocks]);
|
|
6320
|
-
|
|
6494
|
+
m.useEffect(() => {
|
|
6321
6495
|
const editor = editorInstanceRef.current;
|
|
6322
6496
|
if (!editor || !isReady) return;
|
|
6323
6497
|
const shouldBeReadOnly = disabled || collabEnabled && collabCanEdit === false;
|
|
@@ -6355,11 +6529,11 @@ const Editor = React.forwardRef(({
|
|
|
6355
6529
|
{ icon: outline.ExclamationTriangleIcon, label: "Warning", block: "warning" },
|
|
6356
6530
|
{ icon: outline.MinusIcon, label: "Divider", block: "delimiter" }
|
|
6357
6531
|
];
|
|
6358
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.
|
|
6532
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(getTranslation.Hm.Root, { name, id: name, error, required, hint, children: [
|
|
6359
6533
|
/* @__PURE__ */ jsxRuntime.jsx(FullscreenGlobalStyle, {}),
|
|
6360
6534
|
/* @__PURE__ */ jsxRuntime.jsx(EditorJSGlobalStyles, {}),
|
|
6361
6535
|
/* @__PURE__ */ jsxRuntime.jsx(tools.AIToast, {}),
|
|
6362
|
-
label && !isFullscreen && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
6536
|
+
label && !isFullscreen && /* @__PURE__ */ jsxRuntime.jsx(getTranslation.Hm.Label, { action: labelAction, children: label }),
|
|
6363
6537
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6364
6538
|
EditorContainer,
|
|
6365
6539
|
{
|
|
@@ -6573,7 +6747,7 @@ const Editor = React.forwardRef(({
|
|
|
6573
6747
|
onBlur: () => setIsFocused(false),
|
|
6574
6748
|
children: [
|
|
6575
6749
|
!isReady && /* @__PURE__ */ jsxRuntime.jsxs(LoadingOverlay, { children: [
|
|
6576
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
6750
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.Vd, { small: true }),
|
|
6577
6751
|
/* @__PURE__ */ jsxRuntime.jsx(LoadingText, { children: "Initializing editor..." })
|
|
6578
6752
|
] }),
|
|
6579
6753
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6658,15 +6832,21 @@ const Editor = React.forwardRef(({
|
|
|
6658
6832
|
}
|
|
6659
6833
|
),
|
|
6660
6834
|
!isFullscreen && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6661
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
6662
|
-
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.
|
|
6835
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.Hm.Hint, {}),
|
|
6836
|
+
/* @__PURE__ */ jsxRuntime.jsx(getTranslation.Hm.Error, {})
|
|
6663
6837
|
] }),
|
|
6664
6838
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6665
6839
|
MediaLibComponent,
|
|
6666
6840
|
{
|
|
6667
6841
|
isOpen: isMediaLibOpen,
|
|
6668
|
-
onChange: handleMediaLibChange,
|
|
6669
|
-
onToggle:
|
|
6842
|
+
onChange: customBlockImageCallback ? handleCustomBlockMediaLibChange : handleMediaLibChange,
|
|
6843
|
+
onToggle: () => {
|
|
6844
|
+
if (customBlockImageCallback) {
|
|
6845
|
+
setCustomBlockImageCallback(null);
|
|
6846
|
+
}
|
|
6847
|
+
mediaLibToggleFunc();
|
|
6848
|
+
},
|
|
6849
|
+
multiple: !customBlockImageCallback
|
|
6670
6850
|
}
|
|
6671
6851
|
),
|
|
6672
6852
|
showAIToolbar && /* @__PURE__ */ jsxRuntime.jsx(
|