@select-org/select-post-builder 1.1.2 → 1.1.3
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/index.d.ts +51 -25
- package/dist/post-builder.cjs.js +575 -350
- package/dist/post-builder.js +576 -351
- package/package.json +1 -1
package/dist/post-builder.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import React__default, { createContext, useContext,
|
|
2
|
+
import React__default, { createContext, useContext, useLayoutEffect, useState, forwardRef, createElement, useEffect, useMemo, useRef, Component, useCallback, useImperativeHandle } from "react";
|
|
3
3
|
import * as ReactDOM from "react-dom";
|
|
4
4
|
import ReactDOM__default from "react-dom";
|
|
5
5
|
import { jsx, Fragment as Fragment$1, jsxs } from "react/jsx-runtime";
|
|
@@ -2053,19 +2053,12 @@ validators$1.transitional = function transitional(validator2, version, message)
|
|
|
2053
2053
|
}
|
|
2054
2054
|
if (version && !deprecatedWarnings[opt]) {
|
|
2055
2055
|
deprecatedWarnings[opt] = true;
|
|
2056
|
-
console.warn(
|
|
2057
|
-
formatMessage(
|
|
2058
|
-
opt,
|
|
2059
|
-
" has been deprecated since v" + version + " and will be removed in the near future"
|
|
2060
|
-
)
|
|
2061
|
-
);
|
|
2062
2056
|
}
|
|
2063
2057
|
return validator2 ? validator2(value, opt, opts) : true;
|
|
2064
2058
|
};
|
|
2065
2059
|
};
|
|
2066
2060
|
validators$1.spelling = function spelling(correctSpelling) {
|
|
2067
2061
|
return (value, opt) => {
|
|
2068
|
-
console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);
|
|
2069
2062
|
return true;
|
|
2070
2063
|
};
|
|
2071
2064
|
};
|
|
@@ -3924,7 +3917,6 @@ const Toaster$1 = /* @__PURE__ */ React__default.forwardRef(function Toaster(pro
|
|
|
3924
3917
|
setActualTheme("light");
|
|
3925
3918
|
}
|
|
3926
3919
|
} catch (e) {
|
|
3927
|
-
console.error(e);
|
|
3928
3920
|
}
|
|
3929
3921
|
});
|
|
3930
3922
|
}
|
|
@@ -4592,46 +4584,6 @@ const useAnalyticsLogEvent = () => {
|
|
|
4592
4584
|
const { logEvent } = usePostBuilder();
|
|
4593
4585
|
return logEvent;
|
|
4594
4586
|
};
|
|
4595
|
-
const PostBuilderProvider = ({
|
|
4596
|
-
children,
|
|
4597
|
-
apiBaseURL,
|
|
4598
|
-
authToken,
|
|
4599
|
-
toI18N,
|
|
4600
|
-
i18nKeys,
|
|
4601
|
-
logEvent
|
|
4602
|
-
}) => {
|
|
4603
|
-
const t = useCallback(
|
|
4604
|
-
(key, fallback) => {
|
|
4605
|
-
const message = toI18N(i18nKeys[key]);
|
|
4606
|
-
if (message) return message;
|
|
4607
|
-
return fallback || key;
|
|
4608
|
-
},
|
|
4609
|
-
[toI18N, i18nKeys]
|
|
4610
|
-
);
|
|
4611
|
-
const api = useMemo(() => {
|
|
4612
|
-
const core = new CoreApi(apiBaseURL.core, authToken, toI18N);
|
|
4613
|
-
const mfs = new MFSApi(apiBaseURL.mfs, authToken, toI18N);
|
|
4614
|
-
const fileStore = new FilestoreApi(apiBaseURL.fileStore, authToken, toI18N);
|
|
4615
|
-
core.initApi();
|
|
4616
|
-
mfs.initApi();
|
|
4617
|
-
fileStore.initApi();
|
|
4618
|
-
return {
|
|
4619
|
-
core,
|
|
4620
|
-
mfs,
|
|
4621
|
-
fileStore
|
|
4622
|
-
};
|
|
4623
|
-
}, [authToken, apiBaseURL, toI18N]);
|
|
4624
|
-
const value = useMemo(() => {
|
|
4625
|
-
return {
|
|
4626
|
-
authToken,
|
|
4627
|
-
t,
|
|
4628
|
-
i18nKeys,
|
|
4629
|
-
api,
|
|
4630
|
-
logEvent
|
|
4631
|
-
};
|
|
4632
|
-
}, [authToken, t, i18nKeys, api, logEvent]);
|
|
4633
|
-
return /* @__PURE__ */ jsx(PostBuilderContext.Provider, { value, children });
|
|
4634
|
-
};
|
|
4635
4587
|
function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
|
|
4636
4588
|
return function handleEvent(event) {
|
|
4637
4589
|
originalEventHandler?.(event);
|
|
@@ -4975,9 +4927,6 @@ function useControllableState({
|
|
|
4975
4927
|
if (wasControlled !== isControlled) {
|
|
4976
4928
|
const from = wasControlled ? "controlled" : "uncontrolled";
|
|
4977
4929
|
const to = isControlled ? "controlled" : "uncontrolled";
|
|
4978
|
-
console.warn(
|
|
4979
|
-
`${caller} is changing from ${from} to ${to}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`
|
|
4980
|
-
);
|
|
4981
4930
|
}
|
|
4982
4931
|
isControlledRef.current = isControlled;
|
|
4983
4932
|
}, [isControlled, caller]);
|
|
@@ -8582,7 +8531,7 @@ const EditorTypeTabs = ({ editorTab, onSwitchEditorTab }) => {
|
|
|
8582
8531
|
const { trackTabSwitch } = usePostBuilderAnalytics();
|
|
8583
8532
|
const handleSwitchTab = (newTab) => {
|
|
8584
8533
|
const oldTab = editorTab;
|
|
8585
|
-
trackTabSwitch(oldTab, newTab);
|
|
8534
|
+
trackTabSwitch({ oldTab, newTab });
|
|
8586
8535
|
onSwitchEditorTab(newTab);
|
|
8587
8536
|
};
|
|
8588
8537
|
return /* @__PURE__ */ jsx(
|
|
@@ -11304,7 +11253,6 @@ var correctTargets = function(parent2, targets) {
|
|
|
11304
11253
|
if (correctedTarget && parent2.contains(correctedTarget)) {
|
|
11305
11254
|
return correctedTarget;
|
|
11306
11255
|
}
|
|
11307
|
-
console.error("aria-hidden", target, "in not contained inside", parent2, ". Doing nothing");
|
|
11308
11256
|
return null;
|
|
11309
11257
|
}).filter(function(x2) {
|
|
11310
11258
|
return Boolean(x2);
|
|
@@ -11353,7 +11301,6 @@ var applyAttributeToOthers = function(originalTarget, parentNode, markerName, co
|
|
|
11353
11301
|
node.setAttribute(controlAttribute, "true");
|
|
11354
11302
|
}
|
|
11355
11303
|
} catch (e) {
|
|
11356
|
-
console.error("aria-hidden: cannot operate on ", node, e);
|
|
11357
11304
|
}
|
|
11358
11305
|
}
|
|
11359
11306
|
});
|
|
@@ -13991,15 +13938,11 @@ function requireUseSyncExternalStoreShim_development() {
|
|
|
13991
13938
|
return x2 === y && (0 !== x2 || 1 / x2 === 1 / y) || x2 !== x2 && y !== y;
|
|
13992
13939
|
}
|
|
13993
13940
|
function useSyncExternalStore$2(subscribe2, getSnapshot) {
|
|
13994
|
-
didWarnOld18Alpha || void 0 === React2.startTransition || (didWarnOld18Alpha = true,
|
|
13995
|
-
"You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."
|
|
13996
|
-
));
|
|
13941
|
+
didWarnOld18Alpha || void 0 === React2.startTransition || (didWarnOld18Alpha = true, void 0);
|
|
13997
13942
|
var value = getSnapshot();
|
|
13998
13943
|
if (!didWarnUncachedGetSnapshot) {
|
|
13999
13944
|
var cachedValue = getSnapshot();
|
|
14000
|
-
objectIs(value, cachedValue) || (
|
|
14001
|
-
"The result of getSnapshot should be cached to avoid an infinite loop"
|
|
14002
|
-
), didWarnUncachedGetSnapshot = true);
|
|
13945
|
+
objectIs(value, cachedValue) || (void 0, didWarnUncachedGetSnapshot = true);
|
|
14003
13946
|
}
|
|
14004
13947
|
cachedValue = useState2({
|
|
14005
13948
|
inst: { value, getSnapshot }
|
|
@@ -14231,9 +14174,6 @@ const GroupSelector = ({ store }) => {
|
|
|
14231
14174
|
setGroups(response.entries ?? []);
|
|
14232
14175
|
}
|
|
14233
14176
|
} catch (error) {
|
|
14234
|
-
if (!cancelled) {
|
|
14235
|
-
console.error("Failed to fetch groups:", error);
|
|
14236
|
-
}
|
|
14237
14177
|
} finally {
|
|
14238
14178
|
if (!cancelled) {
|
|
14239
14179
|
setIsLoading(false);
|
|
@@ -14882,7 +14822,7 @@ const ToolbarButton = forwardRef(
|
|
|
14882
14822
|
const { trackFeature } = usePostBuilderAnalytics();
|
|
14883
14823
|
const handleClick = (e) => {
|
|
14884
14824
|
onClick?.(e);
|
|
14885
|
-
if (id) trackFeature(id);
|
|
14825
|
+
if (id) trackFeature({ featureName: id });
|
|
14886
14826
|
if (!editor) return;
|
|
14887
14827
|
requestAnimationFrame(editor?.chain()?.focus);
|
|
14888
14828
|
};
|
|
@@ -15186,7 +15126,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
15186
15126
|
React.useEffect(() => {
|
|
15187
15127
|
if (titleId) {
|
|
15188
15128
|
const hasTitle = document.getElementById(titleId);
|
|
15189
|
-
if (!hasTitle)
|
|
15129
|
+
if (!hasTitle) ;
|
|
15190
15130
|
}
|
|
15191
15131
|
}, [MESSAGE, titleId]);
|
|
15192
15132
|
return null;
|
|
@@ -15199,7 +15139,7 @@ var DescriptionWarning = ({ contentRef, descriptionId }) => {
|
|
|
15199
15139
|
const describedById = contentRef.current?.getAttribute("aria-describedby");
|
|
15200
15140
|
if (descriptionId && describedById) {
|
|
15201
15141
|
const hasDescription = document.getElementById(descriptionId);
|
|
15202
|
-
if (!hasDescription)
|
|
15142
|
+
if (!hasDescription) ;
|
|
15203
15143
|
}
|
|
15204
15144
|
}, [MESSAGE, contentRef, descriptionId]);
|
|
15205
15145
|
return null;
|
|
@@ -15585,7 +15525,6 @@ const InputGroupText = forwardRef(
|
|
|
15585
15525
|
InputGroupText.displayName = "InputGroupText";
|
|
15586
15526
|
const InputGroupInput = forwardRef(
|
|
15587
15527
|
({ className, ref: legacyRef, ...props }, ref) => {
|
|
15588
|
-
console.log({ legacyRef });
|
|
15589
15528
|
return /* @__PURE__ */ jsx(
|
|
15590
15529
|
Input,
|
|
15591
15530
|
{
|
|
@@ -16206,7 +16145,6 @@ const resolveUrlType = async (url) => {
|
|
|
16206
16145
|
if (mime?.startsWith("video/")) return { type: MediaNodeTypes.Video, src: url };
|
|
16207
16146
|
if (mime?.startsWith("audio/")) return { type: MediaNodeTypes.Audio, src: url };
|
|
16208
16147
|
} catch (error) {
|
|
16209
|
-
console.warn("HEAD request failed, falling back to mime detection:", error);
|
|
16210
16148
|
}
|
|
16211
16149
|
const ext = url.split(".").pop()?.toLowerCase();
|
|
16212
16150
|
if (ext) {
|
|
@@ -16345,11 +16283,9 @@ const LinkDecoratorModal = ({
|
|
|
16345
16283
|
setIsValid(isValid2);
|
|
16346
16284
|
};
|
|
16347
16285
|
const handleInsertLink = (link2, text22, uid2) => {
|
|
16348
|
-
console.log("HANDLE INSERT LINK::", { link: link2, text: text22 });
|
|
16349
16286
|
setIsLoading(true);
|
|
16350
16287
|
let metadata;
|
|
16351
|
-
core?.resolveUrl(link2)?.then((res) => metadata = res)?.catch((err) =>
|
|
16352
|
-
console.log({ metadata });
|
|
16288
|
+
core?.resolveUrl(link2)?.then((res) => metadata = res)?.catch((err) => void 0)?.finally(() => {
|
|
16353
16289
|
const previewPayload = convertLinkMetaToPreviewItem(metadata);
|
|
16354
16290
|
setIsLoading(false);
|
|
16355
16291
|
onInsertLink(link2, text22, uid2, previewPayload);
|
|
@@ -16361,12 +16297,10 @@ const LinkDecoratorModal = ({
|
|
|
16361
16297
|
e.preventDefault();
|
|
16362
16298
|
const isTextInput = textInputRef.current === e.target;
|
|
16363
16299
|
if (isTextInput || hideTextInput) return handleInsertLink(link, text2, uid ?? void 0);
|
|
16364
|
-
console.log("Enter", isTextInput);
|
|
16365
16300
|
textInputRef?.current?.focus();
|
|
16366
16301
|
}
|
|
16367
16302
|
};
|
|
16368
16303
|
useEffect(() => {
|
|
16369
|
-
console.log({ defaultValues });
|
|
16370
16304
|
if (!defaultValues?.link) return;
|
|
16371
16305
|
const isValid2 = isValidUrl(defaultValues?.link);
|
|
16372
16306
|
setIsValid(isValid2);
|
|
@@ -16375,7 +16309,6 @@ const LinkDecoratorModal = ({
|
|
|
16375
16309
|
setLink(defaultValues?.link ?? "");
|
|
16376
16310
|
setText(defaultValues?.text || "");
|
|
16377
16311
|
}, [defaultValues]);
|
|
16378
|
-
console.log("TEXT INSIDE LINK DECORATOR::", { isValid, text: text2 });
|
|
16379
16312
|
return /* @__PURE__ */ jsxs(Dialog, { open, onOpenChange: handleOpenChange, children: [
|
|
16380
16313
|
children ? /* @__PURE__ */ jsx(DialogTrigger, { asChild: true, children }) : null,
|
|
16381
16314
|
/* @__PURE__ */ jsxs(DialogContent, { className: "-translate-1/2", children: [
|
|
@@ -16560,10 +16493,8 @@ function parseThreshold(scrollThreshold) {
|
|
|
16560
16493
|
value: parseFloat(scrollThreshold)
|
|
16561
16494
|
};
|
|
16562
16495
|
}
|
|
16563
|
-
console.warn('scrollThreshold format is invalid. Valid formats: "120px", "50%"...');
|
|
16564
16496
|
return defaultThreshold;
|
|
16565
16497
|
}
|
|
16566
|
-
console.warn("scrollThreshold should be string or number");
|
|
16567
16498
|
return defaultThreshold;
|
|
16568
16499
|
}
|
|
16569
16500
|
var InfiniteScroll = (
|
|
@@ -16585,7 +16516,6 @@ var InfiniteScroll = (
|
|
|
16585
16516
|
return document.getElementById(_this.props.scrollableTarget);
|
|
16586
16517
|
}
|
|
16587
16518
|
if (_this.props.scrollableTarget === null) {
|
|
16588
|
-
console.warn("You are trying to pass scrollableTarget but it is null. This might\n happen because the element may not have been added to DOM yet.\n See https://github.com/ankeetmaini/react-infinite-scroll-component/issues/59 for more info.\n ");
|
|
16589
16519
|
}
|
|
16590
16520
|
return null;
|
|
16591
16521
|
};
|
|
@@ -16830,7 +16760,6 @@ function useMediaSearch(type) {
|
|
|
16830
16760
|
setItems((prev) => reset2 ? data : [...prev, ...data]);
|
|
16831
16761
|
}
|
|
16832
16762
|
} catch (error) {
|
|
16833
|
-
console.error("Error fetching images:", error);
|
|
16834
16763
|
pagination.setHasMore(false);
|
|
16835
16764
|
} finally {
|
|
16836
16765
|
pagination.setLoading(false);
|
|
@@ -16849,7 +16778,6 @@ function useMediaSearch(type) {
|
|
|
16849
16778
|
setItems((prev) => reset2 ? data : [...prev, ...data]);
|
|
16850
16779
|
}
|
|
16851
16780
|
} catch (error) {
|
|
16852
|
-
console.error("Error fetching gifs:", error);
|
|
16853
16781
|
pagination.setHasMore(false);
|
|
16854
16782
|
} finally {
|
|
16855
16783
|
pagination.setLoading(false);
|
|
@@ -18424,8 +18352,8 @@ function ImageSearchModal({
|
|
|
18424
18352
|
setSearchQuery("");
|
|
18425
18353
|
return;
|
|
18426
18354
|
}
|
|
18427
|
-
gifSearch.fetch(withInitialQuery).catch((err) =>
|
|
18428
|
-
imageSearch.fetch(withInitialQuery).catch((err) =>
|
|
18355
|
+
gifSearch.fetch(withInitialQuery).catch((err) => void 0);
|
|
18356
|
+
imageSearch.fetch(withInitialQuery).catch((err) => void 0);
|
|
18429
18357
|
};
|
|
18430
18358
|
const debouncedSearch = useMemo(
|
|
18431
18359
|
() => debounce$2(async (query) => {
|
|
@@ -18443,7 +18371,7 @@ function ImageSearchModal({
|
|
|
18443
18371
|
const handleSearch = useCallback(
|
|
18444
18372
|
(query) => {
|
|
18445
18373
|
setSearchQuery(query);
|
|
18446
|
-
debouncedSearch(query)?.catch((err) =>
|
|
18374
|
+
debouncedSearch(query)?.catch((err) => void 0);
|
|
18447
18375
|
},
|
|
18448
18376
|
[debouncedSearch]
|
|
18449
18377
|
);
|
|
@@ -20397,7 +20325,9 @@ const Toolbar = ({
|
|
|
20397
20325
|
};
|
|
20398
20326
|
const handleImageClick = (imageUrl, searchFrom) => {
|
|
20399
20327
|
if (searchFrom) {
|
|
20400
|
-
trackFeature(
|
|
20328
|
+
trackFeature({
|
|
20329
|
+
featureName: searchFrom === ImageSearchFrom.Gif ? "gif_search" : "image_search"
|
|
20330
|
+
});
|
|
20401
20331
|
}
|
|
20402
20332
|
editor?.commands.insertMediaWithUpload({
|
|
20403
20333
|
source: imageUrl,
|
|
@@ -20810,6 +20740,79 @@ const Toolbar = ({
|
|
|
20810
20740
|
] });
|
|
20811
20741
|
};
|
|
20812
20742
|
const VerticalSeparator = () => /* @__PURE__ */ jsx("div", { className: "h-3 w-px bg-border" });
|
|
20743
|
+
var PostBuilderEvents = /* @__PURE__ */ ((PostBuilderEvents2) => {
|
|
20744
|
+
PostBuilderEvents2["POST_PUBLISH_ATTEMPTED"] = "select:post_publish_attempted";
|
|
20745
|
+
PostBuilderEvents2["POST_PUBLISH_SUCCESSFUL"] = "select:post_publish_success";
|
|
20746
|
+
PostBuilderEvents2["POST_PUBLISH_FAILED"] = "select:post_publish_failed";
|
|
20747
|
+
return PostBuilderEvents2;
|
|
20748
|
+
})(PostBuilderEvents || {});
|
|
20749
|
+
const useHostAnalyticsBridge = () => {
|
|
20750
|
+
const analytics = usePostBuilderAnalytics();
|
|
20751
|
+
const sessionIdRef = useRef(null);
|
|
20752
|
+
const processedRequestIds = useRef(/* @__PURE__ */ new Set());
|
|
20753
|
+
useEffect(() => {
|
|
20754
|
+
const onPublishSuccess = (e) => {
|
|
20755
|
+
const { postId, postType, groupId, failureReason } = e.detail;
|
|
20756
|
+
if (!postId || processedRequestIds.current.has(postId)) return;
|
|
20757
|
+
processedRequestIds.current.add(postId);
|
|
20758
|
+
analytics.trackPublish({
|
|
20759
|
+
sessionId: sessionIdRef.current ?? analytics.currentSessionId,
|
|
20760
|
+
status: "success",
|
|
20761
|
+
postId,
|
|
20762
|
+
groupId,
|
|
20763
|
+
postType,
|
|
20764
|
+
failureReason
|
|
20765
|
+
});
|
|
20766
|
+
sessionIdRef.current = null;
|
|
20767
|
+
};
|
|
20768
|
+
const onPublishFailed = (e) => {
|
|
20769
|
+
const { postId, postType, groupId, failureReason } = e.detail;
|
|
20770
|
+
if (!postId || processedRequestIds.current.has(postId)) return;
|
|
20771
|
+
processedRequestIds.current.add(postId);
|
|
20772
|
+
analytics.trackPublish({
|
|
20773
|
+
sessionId: sessionIdRef.current ?? analytics.currentSessionId,
|
|
20774
|
+
status: "failed",
|
|
20775
|
+
postId,
|
|
20776
|
+
groupId,
|
|
20777
|
+
postType,
|
|
20778
|
+
failureReason
|
|
20779
|
+
});
|
|
20780
|
+
sessionIdRef.current = null;
|
|
20781
|
+
};
|
|
20782
|
+
const lockSession = () => {
|
|
20783
|
+
if (!sessionIdRef.current) {
|
|
20784
|
+
sessionIdRef.current = analytics.currentSessionId;
|
|
20785
|
+
}
|
|
20786
|
+
};
|
|
20787
|
+
window.addEventListener(
|
|
20788
|
+
PostBuilderEvents.POST_PUBLISH_SUCCESSFUL,
|
|
20789
|
+
onPublishSuccess
|
|
20790
|
+
);
|
|
20791
|
+
window.addEventListener(
|
|
20792
|
+
PostBuilderEvents.POST_PUBLISH_FAILED,
|
|
20793
|
+
onPublishFailed
|
|
20794
|
+
);
|
|
20795
|
+
const handlePublishAttempt = () => lockSession();
|
|
20796
|
+
window.addEventListener(
|
|
20797
|
+
PostBuilderEvents.POST_PUBLISH_ATTEMPTED,
|
|
20798
|
+
handlePublishAttempt
|
|
20799
|
+
);
|
|
20800
|
+
return () => {
|
|
20801
|
+
window.removeEventListener(
|
|
20802
|
+
PostBuilderEvents.POST_PUBLISH_SUCCESSFUL,
|
|
20803
|
+
onPublishSuccess
|
|
20804
|
+
);
|
|
20805
|
+
window.removeEventListener(
|
|
20806
|
+
PostBuilderEvents.POST_PUBLISH_FAILED,
|
|
20807
|
+
onPublishFailed
|
|
20808
|
+
);
|
|
20809
|
+
window.removeEventListener(
|
|
20810
|
+
PostBuilderEvents.POST_PUBLISH_ATTEMPTED,
|
|
20811
|
+
handlePublishAttempt
|
|
20812
|
+
);
|
|
20813
|
+
};
|
|
20814
|
+
}, [analytics]);
|
|
20815
|
+
};
|
|
20813
20816
|
const usePersistence = () => {
|
|
20814
20817
|
const saveCurrentTabContent = (editorType, editor) => {
|
|
20815
20818
|
if (typeof window === "undefined" || typeof localStorage === "undefined" || !editor || editor.isEmpty)
|
|
@@ -21066,11 +21069,9 @@ var Progress$1 = React.forwardRef(
|
|
|
21066
21069
|
...progressProps
|
|
21067
21070
|
} = props;
|
|
21068
21071
|
if ((maxProp || maxProp === 0) && !isValidMaxNumber(maxProp)) {
|
|
21069
|
-
console.error(getInvalidMaxError(`${maxProp}`, "Progress"));
|
|
21070
21072
|
}
|
|
21071
21073
|
const max2 = isValidMaxNumber(maxProp) ? maxProp : DEFAULT_MAX;
|
|
21072
21074
|
if (valueProp !== null && !isValidValueNumber(valueProp, max2)) {
|
|
21073
|
-
console.error(getInvalidValueError(`${valueProp}`, "Progress"));
|
|
21074
21075
|
}
|
|
21075
21076
|
const value = isValidValueNumber(valueProp, max2) ? valueProp : null;
|
|
21076
21077
|
const valueLabel = isNumber(value) ? getValueLabel(value, max2) : void 0;
|
|
@@ -21390,13 +21391,7 @@ const createUpdateMarkByUidCommand = (markName) => {
|
|
|
21390
21391
|
state,
|
|
21391
21392
|
dispatch
|
|
21392
21393
|
}) => {
|
|
21393
|
-
console.log("=== UPDATE MARK COMMAND START ===");
|
|
21394
|
-
console.log("markName:", markName);
|
|
21395
|
-
console.log("uid:", uid);
|
|
21396
|
-
console.log("attrs:", attrs);
|
|
21397
|
-
console.log("state.doc:", state.doc.toJSON());
|
|
21398
21394
|
if (!dispatch) {
|
|
21399
|
-
console.log("No dispatch, returning false");
|
|
21400
21395
|
return false;
|
|
21401
21396
|
}
|
|
21402
21397
|
const { doc, schema } = state;
|
|
@@ -21406,13 +21401,6 @@ const createUpdateMarkByUidCommand = (markName) => {
|
|
|
21406
21401
|
doc.descendants((node, pos) => {
|
|
21407
21402
|
if (node.isText && node.marks?.length) {
|
|
21408
21403
|
node.marks.forEach((mark) => {
|
|
21409
|
-
console.log("Checking mark:", {
|
|
21410
|
-
markType: mark.type.name,
|
|
21411
|
-
markUid: mark.attrs.uid,
|
|
21412
|
-
targetMarkName: markName,
|
|
21413
|
-
targetUid: uid,
|
|
21414
|
-
matches: mark.type.name === markName && mark.attrs.uid === uid
|
|
21415
|
-
});
|
|
21416
21404
|
if (mark.type.name === markName && mark.attrs.uid === uid) {
|
|
21417
21405
|
positions.push({
|
|
21418
21406
|
from: pos,
|
|
@@ -21420,33 +21408,21 @@ const createUpdateMarkByUidCommand = (markName) => {
|
|
|
21420
21408
|
mark
|
|
21421
21409
|
});
|
|
21422
21410
|
found2 = true;
|
|
21423
|
-
console.log("Found matching mark at:", { from: pos, to: pos + node.nodeSize });
|
|
21424
21411
|
}
|
|
21425
21412
|
});
|
|
21426
21413
|
}
|
|
21427
21414
|
});
|
|
21428
|
-
console.log("Total positions found:", positions.length);
|
|
21429
|
-
console.log("Positions:", positions);
|
|
21430
21415
|
if (found2) {
|
|
21431
21416
|
positions.forEach(({ from, to, mark }) => {
|
|
21432
21417
|
const newAttrs = { ...mark.attrs, ...attrs };
|
|
21433
21418
|
const markType = schema.marks[markName];
|
|
21434
|
-
console.log("Applying update:", { from, to, oldAttrs: mark.attrs, newAttrs });
|
|
21435
21419
|
if (markType) {
|
|
21436
|
-
console.log("Before removeMark - tr.doc:", tr.doc.toJSON());
|
|
21437
21420
|
tr = tr.removeMark(from, to, markType);
|
|
21438
|
-
console.log("After removeMark - tr.doc:", tr.doc.toJSON());
|
|
21439
21421
|
tr = tr.addMark(from, to, markType.create(newAttrs));
|
|
21440
|
-
console.log("After addMark - tr.doc:", tr.doc.toJSON());
|
|
21441
21422
|
}
|
|
21442
21423
|
});
|
|
21443
|
-
console.log("About to dispatch transaction");
|
|
21444
|
-
console.log("Final tr.doc:", tr.doc.toJSON());
|
|
21445
|
-
console.log("Original state.doc:", state.doc.toJSON());
|
|
21446
21424
|
dispatch(tr);
|
|
21447
|
-
console.log("Transaction dispatched successfully");
|
|
21448
21425
|
}
|
|
21449
|
-
console.log("=== UPDATE MARK COMMAND END ===");
|
|
21450
21426
|
return found2;
|
|
21451
21427
|
};
|
|
21452
21428
|
};
|
|
@@ -22464,7 +22440,6 @@ let warnedAboutTextSelection = false;
|
|
|
22464
22440
|
function checkTextSelection($pos) {
|
|
22465
22441
|
if (!warnedAboutTextSelection && !$pos.parent.inlineContent) {
|
|
22466
22442
|
warnedAboutTextSelection = true;
|
|
22467
|
-
console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")");
|
|
22468
22443
|
}
|
|
22469
22444
|
}
|
|
22470
22445
|
class TextSelection extends Selection {
|
|
@@ -23189,7 +23164,6 @@ const PollCreator = ({ choices, onChange }) => {
|
|
|
23189
23164
|
const result = await fileStore.uploadImage(file);
|
|
23190
23165
|
return createPollMediaOption(result, startIndex + index2);
|
|
23191
23166
|
} catch (error) {
|
|
23192
|
-
console.error("Upload failed for", file.name, error);
|
|
23193
23167
|
return null;
|
|
23194
23168
|
}
|
|
23195
23169
|
});
|
|
@@ -23209,7 +23183,6 @@ const PollCreator = ({ choices, onChange }) => {
|
|
|
23209
23183
|
return final;
|
|
23210
23184
|
});
|
|
23211
23185
|
} catch (error) {
|
|
23212
|
-
console.error("Unexpected error during file upload:", error);
|
|
23213
23186
|
setInternalChoices((current) => {
|
|
23214
23187
|
const withoutPlaceholders = current.filter((c) => !isPlaceholder(c));
|
|
23215
23188
|
setTimeout(() => {
|
|
@@ -23242,7 +23215,6 @@ const PollCreator = ({ choices, onChange }) => {
|
|
|
23242
23215
|
return updated;
|
|
23243
23216
|
});
|
|
23244
23217
|
} catch (error) {
|
|
23245
|
-
console.error("URL upload failed:", error);
|
|
23246
23218
|
setInternalChoices((current) => {
|
|
23247
23219
|
const withoutPlaceholder = current.filter((c) => !isPlaceholder(c));
|
|
23248
23220
|
setTimeout(() => {
|
|
@@ -23783,7 +23755,6 @@ const LinkMarkView = ({ mark, editor }) => {
|
|
|
23783
23755
|
};
|
|
23784
23756
|
const handleUpdateLink = (link, text2, uid, previewPayload) => {
|
|
23785
23757
|
if (!editor.view) return;
|
|
23786
|
-
console.log("UPDATE LINK IN VIEW::", { text: text2 });
|
|
23787
23758
|
const newText = mark?.attrs?.isLinkMode ? link : text2 || link;
|
|
23788
23759
|
if (uid) {
|
|
23789
23760
|
editor.commands.updateLink(uid, { href: link, text: newText, previewPayload });
|
|
@@ -23843,25 +23814,66 @@ const LinkMarkView = ({ mark, editor }) => {
|
|
|
23843
23814
|
)
|
|
23844
23815
|
] });
|
|
23845
23816
|
};
|
|
23817
|
+
function isValidUrlFormat(text2) {
|
|
23818
|
+
return isValidUrl(normalizeUrl(text2.trim()));
|
|
23819
|
+
}
|
|
23846
23820
|
function doesPreviewExist(editor, uid) {
|
|
23847
|
-
|
|
23848
|
-
|
|
23849
|
-
|
|
23850
|
-
|
|
23851
|
-
|
|
23852
|
-
|
|
23853
|
-
|
|
23854
|
-
|
|
23821
|
+
if (!editor || !uid) {
|
|
23822
|
+
return false;
|
|
23823
|
+
}
|
|
23824
|
+
try {
|
|
23825
|
+
let exists = false;
|
|
23826
|
+
editor.state.doc.descendants((node) => {
|
|
23827
|
+
if (node && node.type && node.type.name === "linkPreview" && node.attrs?.uid === uid) {
|
|
23828
|
+
exists = true;
|
|
23829
|
+
return false;
|
|
23830
|
+
}
|
|
23831
|
+
});
|
|
23832
|
+
return exists;
|
|
23833
|
+
} catch (err) {
|
|
23834
|
+
return false;
|
|
23835
|
+
}
|
|
23855
23836
|
}
|
|
23856
23837
|
function findExistingPreview(editor) {
|
|
23857
|
-
|
|
23858
|
-
|
|
23859
|
-
|
|
23860
|
-
|
|
23861
|
-
|
|
23838
|
+
if (!editor) {
|
|
23839
|
+
return null;
|
|
23840
|
+
}
|
|
23841
|
+
try {
|
|
23842
|
+
let result = null;
|
|
23843
|
+
editor.state.doc.descendants((node, pos) => {
|
|
23844
|
+
if (node && node.type && node.type.name === "linkPreview") {
|
|
23845
|
+
result = { node, pos };
|
|
23846
|
+
return false;
|
|
23847
|
+
}
|
|
23848
|
+
});
|
|
23849
|
+
return result;
|
|
23850
|
+
} catch (err) {
|
|
23851
|
+
return null;
|
|
23852
|
+
}
|
|
23853
|
+
}
|
|
23854
|
+
function removePreviewByUid(editor, uid) {
|
|
23855
|
+
if (!editor || !uid) {
|
|
23856
|
+
return;
|
|
23857
|
+
}
|
|
23858
|
+
try {
|
|
23859
|
+
let previewPos = null;
|
|
23860
|
+
let previewSize = 0;
|
|
23861
|
+
editor.state.doc.descendants((node, pos) => {
|
|
23862
|
+
if (node && node.type && node.type.name === "linkPreview" && node.attrs?.uid === uid) {
|
|
23863
|
+
previewPos = pos;
|
|
23864
|
+
previewSize = node.nodeSize;
|
|
23865
|
+
return false;
|
|
23866
|
+
}
|
|
23867
|
+
});
|
|
23868
|
+
if (previewPos !== null && previewSize > 0) {
|
|
23869
|
+
const tr = editor.state.tr;
|
|
23870
|
+
if (tr) {
|
|
23871
|
+
tr.delete(previewPos, Number(previewPos) + previewSize);
|
|
23872
|
+
editor.view.dispatch(tr);
|
|
23873
|
+
}
|
|
23862
23874
|
}
|
|
23863
|
-
})
|
|
23864
|
-
|
|
23875
|
+
} catch (err) {
|
|
23876
|
+
}
|
|
23865
23877
|
}
|
|
23866
23878
|
function extractBestImage(metadata) {
|
|
23867
23879
|
return metadata?.image?.high_resolution ?? metadata?.image?.url ?? metadata?.image?.thumbnail ?? metadata?.image?.placeholder ?? null;
|
|
@@ -23886,6 +23898,76 @@ function collectAllLinkMarks(state, linkMark) {
|
|
|
23886
23898
|
});
|
|
23887
23899
|
return links;
|
|
23888
23900
|
}
|
|
23901
|
+
function syncLinkHrefWithText(newState, linkMark, editor, singlePreviewMode, pluginState) {
|
|
23902
|
+
if (!newState || !linkMark || !editor || !pluginState) {
|
|
23903
|
+
return null;
|
|
23904
|
+
}
|
|
23905
|
+
let tr = null;
|
|
23906
|
+
let hasChanges = false;
|
|
23907
|
+
try {
|
|
23908
|
+
newState.doc.descendants((node, pos) => {
|
|
23909
|
+
if (!node || !node.isText || !node.marks?.length) return;
|
|
23910
|
+
node.marks.forEach((mark) => {
|
|
23911
|
+
if (!mark || !mark.type || !mark.attrs) return;
|
|
23912
|
+
if (mark.type === linkMark && mark.attrs?.uid) {
|
|
23913
|
+
const currentText = node.text || "";
|
|
23914
|
+
const currentHref = mark.attrs.href || "";
|
|
23915
|
+
if (currentText !== currentHref) {
|
|
23916
|
+
const isValidUrl2 = isValidUrlFormat(currentText);
|
|
23917
|
+
if (!tr) {
|
|
23918
|
+
tr = newState.tr;
|
|
23919
|
+
}
|
|
23920
|
+
if (!tr) {
|
|
23921
|
+
return;
|
|
23922
|
+
}
|
|
23923
|
+
if (isValidUrl2) {
|
|
23924
|
+
const newMark = linkMark.create({
|
|
23925
|
+
...mark.attrs,
|
|
23926
|
+
href: normalizeUrl(currentText)
|
|
23927
|
+
});
|
|
23928
|
+
if (!newMark) {
|
|
23929
|
+
return;
|
|
23930
|
+
}
|
|
23931
|
+
tr = tr.removeMark(pos, pos + node.nodeSize, linkMark);
|
|
23932
|
+
tr = tr.addMark(pos, pos + node.nodeSize, newMark);
|
|
23933
|
+
hasChanges = true;
|
|
23934
|
+
pluginState.processedLinks.delete(mark.attrs.uid);
|
|
23935
|
+
if (singlePreviewMode) {
|
|
23936
|
+
queueMicrotask(() => {
|
|
23937
|
+
try {
|
|
23938
|
+
const existingPreview = findExistingPreview(editor);
|
|
23939
|
+
if (existingPreview && mark.attrs?.uid) {
|
|
23940
|
+
}
|
|
23941
|
+
} catch (err) {
|
|
23942
|
+
}
|
|
23943
|
+
});
|
|
23944
|
+
} else {
|
|
23945
|
+
}
|
|
23946
|
+
} else {
|
|
23947
|
+
tr = tr.removeMark(pos, pos + node.nodeSize, linkMark);
|
|
23948
|
+
hasChanges = true;
|
|
23949
|
+
queueMicrotask(() => {
|
|
23950
|
+
try {
|
|
23951
|
+
if (mark.attrs?.uid) {
|
|
23952
|
+
removePreviewByUid(editor, mark.attrs.uid);
|
|
23953
|
+
}
|
|
23954
|
+
} catch (err) {
|
|
23955
|
+
}
|
|
23956
|
+
});
|
|
23957
|
+
if (mark.attrs?.uid) {
|
|
23958
|
+
pluginState.processedLinks.delete(mark.attrs.uid);
|
|
23959
|
+
pluginState.resolvingLinks.delete(mark.attrs.uid);
|
|
23960
|
+
}
|
|
23961
|
+
}
|
|
23962
|
+
}
|
|
23963
|
+
}
|
|
23964
|
+
});
|
|
23965
|
+
});
|
|
23966
|
+
} catch (err) {
|
|
23967
|
+
return null;
|
|
23968
|
+
}
|
|
23969
|
+
return hasChanges ? tr : null;
|
|
23970
|
+
}
|
|
23889
23971
|
function assignUidsToLinks(newState, linkMark) {
|
|
23890
23972
|
const newUids = /* @__PURE__ */ new Map();
|
|
23891
23973
|
let tr = null;
|
|
@@ -23895,11 +23977,6 @@ function assignUidsToLinks(newState, linkMark) {
|
|
|
23895
23977
|
node.marks.forEach((mark) => {
|
|
23896
23978
|
if (mark.type === linkMark && mark.attrs?.href && !mark.attrs.uid) {
|
|
23897
23979
|
const newUid = v4();
|
|
23898
|
-
console.log("🔧 Assigning UID to autolinked URL:", {
|
|
23899
|
-
href: mark.attrs.href,
|
|
23900
|
-
uid: newUid,
|
|
23901
|
-
pos
|
|
23902
|
-
});
|
|
23903
23980
|
const newMark = linkMark.create({
|
|
23904
23981
|
...mark.attrs,
|
|
23905
23982
|
uid: newUid
|
|
@@ -23926,25 +24003,14 @@ function resolveLinkAndHandlePreview(link, options, singlePreviewMode, pluginSta
|
|
|
23926
24003
|
const { api, editor } = options;
|
|
23927
24004
|
const mediaGroup = findByType(editor?.getJSON(), "mediaGroup");
|
|
23928
24005
|
if (!api) {
|
|
23929
|
-
console.warn("⚠️ No API provided to resolve link");
|
|
23930
24006
|
return;
|
|
23931
24007
|
}
|
|
23932
24008
|
if (singlePreviewMode && mediaGroup.length >= 1) return;
|
|
23933
24009
|
pluginState.resolvingLinks.add(link.uid);
|
|
23934
|
-
console.log("🌐 Resolving link metadata:", {
|
|
23935
|
-
uid: link.uid,
|
|
23936
|
-
href: link.href,
|
|
23937
|
-
singlePreviewMode
|
|
23938
|
-
});
|
|
23939
24010
|
api.resolveUrl(normalizeUrl(link.href)).then((metadata) => {
|
|
23940
24011
|
pluginState.resolvingLinks.delete(link.uid);
|
|
23941
24012
|
pluginState.processedLinks.add(link.uid);
|
|
23942
|
-
console.log("✅ Link metadata resolved:", {
|
|
23943
|
-
uid: link.uid,
|
|
23944
|
-
metadata
|
|
23945
|
-
});
|
|
23946
24013
|
if (!metadata) {
|
|
23947
|
-
console.warn("⚠️ No metadata returned for:", link.href);
|
|
23948
24014
|
return;
|
|
23949
24015
|
}
|
|
23950
24016
|
const previewData = {
|
|
@@ -23959,13 +24025,11 @@ function resolveLinkAndHandlePreview(link, options, singlePreviewMode, pluginSta
|
|
|
23959
24025
|
if (singlePreviewMode) {
|
|
23960
24026
|
const existingPreview = findExistingPreview(editor);
|
|
23961
24027
|
if (existingPreview) {
|
|
23962
|
-
console.log("🔄 Updating existing preview in single mode");
|
|
23963
24028
|
const { pos } = existingPreview;
|
|
23964
24029
|
const tr = editor.state.tr;
|
|
23965
24030
|
tr.setNodeMarkup(pos, void 0, previewData);
|
|
23966
24031
|
editor.view.dispatch(tr);
|
|
23967
24032
|
} else {
|
|
23968
|
-
console.log("➕ Creating first preview in single mode");
|
|
23969
24033
|
editor.commands.setLinkPreview(previewData);
|
|
23970
24034
|
}
|
|
23971
24035
|
editor.commands.updateLinkByUid(link.uid, {
|
|
@@ -23973,16 +24037,12 @@ function resolveLinkAndHandlePreview(link, options, singlePreviewMode, pluginSta
|
|
|
23973
24037
|
});
|
|
23974
24038
|
} else {
|
|
23975
24039
|
if (!doesPreviewExist(editor, link.uid)) {
|
|
23976
|
-
console.log("➕ Creating new preview in multi mode");
|
|
23977
24040
|
editor.chain().updateLinkByUid(link.uid, {
|
|
23978
24041
|
previewPayload: convertLinkMetaToPreviewItem(metadata)
|
|
23979
24042
|
}).setLinkPreview(previewData).run();
|
|
23980
|
-
} else {
|
|
23981
|
-
console.log("⏭️ Preview already exists, skipping");
|
|
23982
24043
|
}
|
|
23983
24044
|
}
|
|
23984
24045
|
}).catch((err) => {
|
|
23985
|
-
console.error("❌ Failed to resolve link:", err);
|
|
23986
24046
|
pluginState.resolvingLinks.delete(link.uid);
|
|
23987
24047
|
});
|
|
23988
24048
|
}
|
|
@@ -23992,10 +24052,6 @@ function createLinkAutoResolvePlugin(options, singlePreviewMode = false) {
|
|
|
23992
24052
|
key: pluginKey,
|
|
23993
24053
|
state: {
|
|
23994
24054
|
init() {
|
|
23995
|
-
console.log("🔌 LinkAutoResolve plugin initialized", {
|
|
23996
|
-
singlePreviewMode,
|
|
23997
|
-
hasApi: !!options.api
|
|
23998
|
-
});
|
|
23999
24055
|
return {
|
|
24000
24056
|
resolvingLinks: /* @__PURE__ */ new Set(),
|
|
24001
24057
|
processedLinks: /* @__PURE__ */ new Set()
|
|
@@ -24025,27 +24081,22 @@ function createLinkAutoResolvePlugin(options, singlePreviewMode = false) {
|
|
|
24025
24081
|
appendTransaction: (transactions, oldState, newState) => {
|
|
24026
24082
|
const linkMark = newState.schema.marks["customLink"];
|
|
24027
24083
|
if (!linkMark) {
|
|
24028
|
-
console.warn("⚠️ customLink mark not found in schema");
|
|
24029
24084
|
return null;
|
|
24030
24085
|
}
|
|
24031
24086
|
if (!transactions.some((tr) => tr.docChanged)) {
|
|
24032
24087
|
return null;
|
|
24033
24088
|
}
|
|
24034
|
-
console.log("📝 Document changed, checking for new links...");
|
|
24035
24089
|
const pluginState = pluginKey.getState(newState);
|
|
24090
|
+
if (!pluginState) {
|
|
24091
|
+
return null;
|
|
24092
|
+
}
|
|
24093
|
+
const syncTr = singlePreviewMode ? syncLinkHrefWithText(newState, linkMark, options.editor, singlePreviewMode, pluginState) : null;
|
|
24036
24094
|
const oldLinks = collectAllLinkMarks(oldState, linkMark);
|
|
24037
24095
|
const newLinks = collectAllLinkMarks(newState, linkMark);
|
|
24038
|
-
console.log("📊 Link count:", {
|
|
24039
|
-
old: oldLinks.size,
|
|
24040
|
-
new: newLinks.size,
|
|
24041
|
-
processed: pluginState.processedLinks.size,
|
|
24042
|
-
resolving: pluginState.resolvingLinks.size
|
|
24043
|
-
});
|
|
24044
24096
|
const { tr: uidTr, newUids } = assignUidsToLinks(newState, linkMark);
|
|
24045
24097
|
const linksToResolve = [];
|
|
24046
24098
|
newUids.forEach((linkData) => {
|
|
24047
24099
|
if (!pluginState.processedLinks.has(linkData.uid) && !pluginState.resolvingLinks.has(linkData.uid)) {
|
|
24048
|
-
console.log("🆕 New autolinked URL detected:", linkData);
|
|
24049
24100
|
linksToResolve.push(linkData);
|
|
24050
24101
|
}
|
|
24051
24102
|
});
|
|
@@ -24058,21 +24109,33 @@ function createLinkAutoResolvePlugin(options, singlePreviewMode = false) {
|
|
|
24058
24109
|
return;
|
|
24059
24110
|
}
|
|
24060
24111
|
if (!oldLinks.has(uid)) {
|
|
24061
|
-
console.log("🆕 New link detected (with UID):", linkData);
|
|
24062
24112
|
linksToResolve.push(linkData);
|
|
24063
24113
|
}
|
|
24064
24114
|
});
|
|
24065
24115
|
if (linksToResolve.length > 0) {
|
|
24066
|
-
console.log("🚀 Processing", linksToResolve.length, "new link(s)");
|
|
24067
24116
|
queueMicrotask(() => {
|
|
24068
24117
|
linksToResolve.forEach((link) => {
|
|
24069
24118
|
resolveLinkAndHandlePreview(link, options, singlePreviewMode, pluginState);
|
|
24070
24119
|
});
|
|
24071
24120
|
});
|
|
24072
|
-
} else {
|
|
24073
|
-
console.log("✓ No new links to process");
|
|
24074
24121
|
}
|
|
24075
|
-
|
|
24122
|
+
if (syncTr && uidTr) {
|
|
24123
|
+
try {
|
|
24124
|
+
uidTr.steps.forEach((step, i) => {
|
|
24125
|
+
if (step && syncTr) {
|
|
24126
|
+
syncTr.step(step);
|
|
24127
|
+
const map = uidTr.mapping.maps[i];
|
|
24128
|
+
if (map) {
|
|
24129
|
+
syncTr.mapping.appendMap(map);
|
|
24130
|
+
}
|
|
24131
|
+
}
|
|
24132
|
+
});
|
|
24133
|
+
return syncTr;
|
|
24134
|
+
} catch (err) {
|
|
24135
|
+
return syncTr;
|
|
24136
|
+
}
|
|
24137
|
+
}
|
|
24138
|
+
return syncTr ?? uidTr ?? null;
|
|
24076
24139
|
}
|
|
24077
24140
|
});
|
|
24078
24141
|
}
|
|
@@ -24168,7 +24231,6 @@ const CustomLink = Link$1.extend({
|
|
|
24168
24231
|
this?.options?.api?.resolveUrl(normalizeUrl(href))?.then((metadata) => {
|
|
24169
24232
|
if (metadata) {
|
|
24170
24233
|
const previewPayload = convertLinkMetaToPreviewItem(metadata);
|
|
24171
|
-
console.log({ href, text: text2 });
|
|
24172
24234
|
editor?.chain()?.updateLinkByUid(uid, { href, text: text2, previewPayload })?.updateLinkPreviewByUid(uid, {
|
|
24173
24235
|
// Now using correct UID
|
|
24174
24236
|
loading: false,
|
|
@@ -24227,7 +24289,6 @@ const CustomLink = Link$1.extend({
|
|
|
24227
24289
|
if (attrs.href) {
|
|
24228
24290
|
queueMicrotask(() => {
|
|
24229
24291
|
this.options.api?.resolveUrl(normalizeUrl(attrs.href))?.then((metadata) => {
|
|
24230
|
-
console.log({ metadata });
|
|
24231
24292
|
if (metadata) {
|
|
24232
24293
|
const previewPayload = convertLinkMetaToPreviewItem(metadata);
|
|
24233
24294
|
let linkPreviewExists = false;
|
|
@@ -24256,7 +24317,6 @@ const CustomLink = Link$1.extend({
|
|
|
24256
24317
|
editor.commands.deleteLinkPreviewByUid(uid);
|
|
24257
24318
|
}
|
|
24258
24319
|
}).catch((err) => {
|
|
24259
|
-
console.log("LINK UPDATE ERR::", { err });
|
|
24260
24320
|
editor.commands.deleteLinkPreviewByUid(uid);
|
|
24261
24321
|
});
|
|
24262
24322
|
});
|
|
@@ -24336,7 +24396,6 @@ const IframeView = ({
|
|
|
24336
24396
|
setPreviewData(previewPayload);
|
|
24337
24397
|
updateAttributes({ previewPayload });
|
|
24338
24398
|
}).catch((error) => {
|
|
24339
|
-
console.error("Failed to fetch preview:", error);
|
|
24340
24399
|
}).finally(() => {
|
|
24341
24400
|
});
|
|
24342
24401
|
}
|
|
@@ -24581,7 +24640,6 @@ const _createTrustedTypesPolicy = function _createTrustedTypesPolicy2(trustedTyp
|
|
|
24581
24640
|
}
|
|
24582
24641
|
});
|
|
24583
24642
|
} catch (_) {
|
|
24584
|
-
console.warn("TrustedTypes policy " + policyName + " could not be created.");
|
|
24585
24643
|
return null;
|
|
24586
24644
|
}
|
|
24587
24645
|
};
|
|
@@ -25418,7 +25476,6 @@ const configureDOMPurify = () => {
|
|
|
25418
25476
|
const element = node;
|
|
25419
25477
|
const src = element.getAttribute("src") || "";
|
|
25420
25478
|
if (!isAllowedDomain(src)) {
|
|
25421
|
-
console.warn("🚨 Blocked iframe from non-allowed domain:", src);
|
|
25422
25479
|
node.parentNode?.removeChild(node);
|
|
25423
25480
|
}
|
|
25424
25481
|
}
|
|
@@ -25430,7 +25487,6 @@ function sanitizeIframeHTML(html2) {
|
|
|
25430
25487
|
const config = configureDOMPurify();
|
|
25431
25488
|
const cleaned = purify.sanitize(html2, config);
|
|
25432
25489
|
if (!cleaned.includes("<iframe")) {
|
|
25433
|
-
console.warn("⚠️ No valid iframe found after sanitization");
|
|
25434
25490
|
return null;
|
|
25435
25491
|
}
|
|
25436
25492
|
const match = cleaned.match(/<iframe[^>]*src=["']([^"']+)["']/i);
|
|
@@ -25442,7 +25498,6 @@ function sanitizeIframeHTML(html2) {
|
|
|
25442
25498
|
}
|
|
25443
25499
|
return match[1];
|
|
25444
25500
|
} catch (error) {
|
|
25445
|
-
console.error("🚨 Error sanitizing iframe:", error);
|
|
25446
25501
|
return null;
|
|
25447
25502
|
} finally {
|
|
25448
25503
|
purify.removeAllHooks();
|
|
@@ -25480,7 +25535,6 @@ const createFinder = (regex) => {
|
|
|
25480
25535
|
match
|
|
25481
25536
|
});
|
|
25482
25537
|
}
|
|
25483
|
-
console.log({ match, matches });
|
|
25484
25538
|
return matches.length > 0 ? matches : null;
|
|
25485
25539
|
};
|
|
25486
25540
|
};
|
|
@@ -25532,11 +25586,9 @@ const Iframe = Node$1.create({
|
|
|
25532
25586
|
const iframeHTML = match[0];
|
|
25533
25587
|
const safeSrc = sanitizeIframeHTML(iframeHTML);
|
|
25534
25588
|
if (!safeSrc) {
|
|
25535
|
-
console.warn("🚨 Blocked unsafe iframe paste");
|
|
25536
25589
|
toast.error("🚨 Your pasted iframe is not safe to render");
|
|
25537
25590
|
return;
|
|
25538
25591
|
}
|
|
25539
|
-
console.log("✅ Safe iframe URL validated:", safeSrc);
|
|
25540
25592
|
const node = this.type.create({ src: safeSrc, previewPayload: null });
|
|
25541
25593
|
state.tr.replaceRangeWith(range.from, range.to, node);
|
|
25542
25594
|
}
|
|
@@ -25547,7 +25599,6 @@ const Iframe = Node$1.create({
|
|
|
25547
25599
|
handler: ({ state, range, match }) => {
|
|
25548
25600
|
const fullUrl = match[0];
|
|
25549
25601
|
const embedUrl = getEmbedUrl(fullUrl);
|
|
25550
|
-
console.log({ match, fullUrl, embedUrl });
|
|
25551
25602
|
if (!embedUrl) return;
|
|
25552
25603
|
const node = this.type.create({ src: embedUrl });
|
|
25553
25604
|
state.tr.replaceRangeWith(range.from, range.to, node);
|
|
@@ -25593,10 +25644,9 @@ const handleUrlWithoutSelection = (editor, url, event, autoDetectMedia) => {
|
|
|
25593
25644
|
mediaType: MediaItemType.MEDIA_ITEM
|
|
25594
25645
|
});
|
|
25595
25646
|
}).catch(
|
|
25596
|
-
(e) =>
|
|
25647
|
+
(e) => void 0
|
|
25597
25648
|
);
|
|
25598
25649
|
}
|
|
25599
|
-
console.log("[SmartLinkPaste] Inserting as link node");
|
|
25600
25650
|
editor.chain().focus().insertLink({ href: normalizedUrl, text: url }).run();
|
|
25601
25651
|
return true;
|
|
25602
25652
|
};
|
|
@@ -25618,7 +25668,6 @@ const createPasteHandler = (editor, options) => {
|
|
|
25618
25668
|
return false;
|
|
25619
25669
|
}
|
|
25620
25670
|
const trimmedText = pasteText.trim();
|
|
25621
|
-
console.log("[SmartLinkPaste] Valid URL detected:", isEmbeddableUrl(trimmedText));
|
|
25622
25671
|
if (isEmbeddableUrl(trimmedText) && options?.autoEmbed) {
|
|
25623
25672
|
event.preventDefault();
|
|
25624
25673
|
return false;
|
|
@@ -25635,7 +25684,6 @@ const createPasteHandler = (editor, options) => {
|
|
|
25635
25684
|
options?.autoDetectMedia ?? true
|
|
25636
25685
|
);
|
|
25637
25686
|
} catch (error) {
|
|
25638
|
-
console.error("[SmartLinkPaste] Error:", error);
|
|
25639
25687
|
return false;
|
|
25640
25688
|
}
|
|
25641
25689
|
};
|
|
@@ -25647,10 +25695,8 @@ const createTransformHandler = (editor) => {
|
|
|
25647
25695
|
return slice;
|
|
25648
25696
|
}
|
|
25649
25697
|
try {
|
|
25650
|
-
console.log("[SmartLinkPaste] Transforming inline URLs in pasted content");
|
|
25651
25698
|
return transformUrlsInSlice(editor, slice);
|
|
25652
25699
|
} catch (error) {
|
|
25653
|
-
console.error("[SmartLinkPaste] Transform error:", error);
|
|
25654
25700
|
return slice;
|
|
25655
25701
|
}
|
|
25656
25702
|
};
|
|
@@ -25757,7 +25803,6 @@ const SmartMediaUpload = Extension.create({
|
|
|
25757
25803
|
const uid = v4();
|
|
25758
25804
|
const options = this.options;
|
|
25759
25805
|
if (!options.api) {
|
|
25760
|
-
console.error("API instance not provided to SmartMediaUpload");
|
|
25761
25806
|
return false;
|
|
25762
25807
|
}
|
|
25763
25808
|
if (isFileOrBlob(source)) {
|
|
@@ -25767,7 +25812,6 @@ const SmartMediaUpload = Extension.create({
|
|
|
25767
25812
|
options.allowedFileTypes
|
|
25768
25813
|
);
|
|
25769
25814
|
if (!validation.valid) {
|
|
25770
|
-
console.error("File validation failed:", validation.error);
|
|
25771
25815
|
options.onUploadError?.(uid, new Error(validation.error));
|
|
25772
25816
|
return false;
|
|
25773
25817
|
}
|
|
@@ -25851,7 +25895,6 @@ const SmartMediaUpload = Extension.create({
|
|
|
25851
25895
|
} else editor.commands.deleteMediaByUid(item.uid);
|
|
25852
25896
|
options.onUploadComplete?.(item.uid, hostedUrl);
|
|
25853
25897
|
} catch (error) {
|
|
25854
|
-
console.error("Upload failed:", error);
|
|
25855
25898
|
const blobUrl = this.storage.blobUrls.get(item.uid);
|
|
25856
25899
|
if (blobUrl) {
|
|
25857
25900
|
URL.revokeObjectURL(blobUrl);
|
|
@@ -25863,7 +25906,7 @@ const SmartMediaUpload = Extension.create({
|
|
|
25863
25906
|
this.storage.activeUploads--;
|
|
25864
25907
|
this.storage.processUploadQueue(editor);
|
|
25865
25908
|
}
|
|
25866
|
-
})().catch((err) =>
|
|
25909
|
+
})().catch((err) => void 0);
|
|
25867
25910
|
if (this.storage.uploadQueue.length > 0) {
|
|
25868
25911
|
this.storage.processUploadQueue(editor);
|
|
25869
25912
|
}
|
|
@@ -28563,7 +28606,6 @@ function getSuggestionOptions({
|
|
|
28563
28606
|
const text2 = editor.getText();
|
|
28564
28607
|
const trimmed = text2?.replace(WHITESPACE_REGEX, " ")?.trim();
|
|
28565
28608
|
const matchStartPosition = trimmed?.lastIndexOf(char);
|
|
28566
|
-
console.log({ matchStartPosition });
|
|
28567
28609
|
const nodeAfter = editor.view.state.selection.$to.nodeAfter;
|
|
28568
28610
|
const overrideSpace = nodeAfter?.text?.startsWith(" ");
|
|
28569
28611
|
if (overrideSpace) {
|
|
@@ -28677,7 +28719,6 @@ const Mention = Node$1.create({
|
|
|
28677
28719
|
renderHTML({ node, HTMLAttributes }) {
|
|
28678
28720
|
const suggestion = getSuggestionFromChar(this, node.attrs.mentionSuggestionChar);
|
|
28679
28721
|
if (this.options.renderLabel !== void 0) {
|
|
28680
|
-
console.warn("renderLabel is deprecated use renderText and renderHTML instead");
|
|
28681
28722
|
return [
|
|
28682
28723
|
"span",
|
|
28683
28724
|
mergeAttributes({ "data-type": this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
|
@@ -28717,7 +28758,6 @@ const Mention = Node$1.create({
|
|
|
28717
28758
|
suggestion: getSuggestionFromChar(this, node.attrs.mentionSuggestionChar)
|
|
28718
28759
|
};
|
|
28719
28760
|
if (this.options.renderLabel !== void 0) {
|
|
28720
|
-
console.warn("renderLabel is deprecated use renderText and renderHTML instead");
|
|
28721
28761
|
return this.options.renderLabel(args);
|
|
28722
28762
|
}
|
|
28723
28763
|
return this.options.renderText(args);
|
|
@@ -29706,11 +29746,9 @@ const mentionService = (api, mfs, store) => {
|
|
|
29706
29746
|
const fetchMentions = async () => {
|
|
29707
29747
|
const params = store.getState().getMentionParams();
|
|
29708
29748
|
if (!params) {
|
|
29709
|
-
console.error("DEBUG MENTION SERVICE::", "No group id or post id has been provided");
|
|
29710
29749
|
return [];
|
|
29711
29750
|
}
|
|
29712
29751
|
const { groupId, postId } = params;
|
|
29713
|
-
console.log({ groupId, postId });
|
|
29714
29752
|
const response = postId ? await mfs.getRecommendationPost(groupId, postId, 0, 999) : await mfs.getRecommendationGroup(groupId, 0, 999);
|
|
29715
29753
|
return response.entries?.filter((item) => Boolean(item?.user_data))?.map(
|
|
29716
29754
|
(item) => ({
|
|
@@ -29729,7 +29767,6 @@ const mentionService = (api, mfs, store) => {
|
|
|
29729
29767
|
const { selectedGroupId, groupId } = store.getState();
|
|
29730
29768
|
const activeGroupId = selectedGroupId ?? groupId;
|
|
29731
29769
|
if (!activeGroupId) {
|
|
29732
|
-
console.warn("DEBUG HASHTAG SERVICE::", "No active group selected or provided");
|
|
29733
29770
|
return [];
|
|
29734
29771
|
}
|
|
29735
29772
|
const response = await api.fetchGroupConversations(999, 0);
|
|
@@ -29931,8 +29968,8 @@ const LinkPreviewExtended = ({
|
|
|
29931
29968
|
title,
|
|
29932
29969
|
description,
|
|
29933
29970
|
image,
|
|
29934
|
-
domain
|
|
29935
|
-
|
|
29971
|
+
domain,
|
|
29972
|
+
onClickDelete
|
|
29936
29973
|
}) => {
|
|
29937
29974
|
const safeDomain = useMemo(() => {
|
|
29938
29975
|
try {
|
|
@@ -29941,6 +29978,11 @@ const LinkPreviewExtended = ({
|
|
|
29941
29978
|
return "unknown";
|
|
29942
29979
|
}
|
|
29943
29980
|
}, [href, domain]);
|
|
29981
|
+
const handleDelete = (e) => {
|
|
29982
|
+
e.preventDefault();
|
|
29983
|
+
e.stopPropagation();
|
|
29984
|
+
onClickDelete();
|
|
29985
|
+
};
|
|
29944
29986
|
return /* @__PURE__ */ jsxs(
|
|
29945
29987
|
"div",
|
|
29946
29988
|
{
|
|
@@ -29949,18 +29991,32 @@ const LinkPreviewExtended = ({
|
|
|
29949
29991
|
selected ? "ring-2 ring-blue-500 ring-offset-2 rounded-lg" : ""
|
|
29950
29992
|
),
|
|
29951
29993
|
children: [
|
|
29952
|
-
/* @__PURE__ */
|
|
29953
|
-
|
|
29954
|
-
|
|
29955
|
-
|
|
29956
|
-
|
|
29957
|
-
|
|
29958
|
-
|
|
29959
|
-
/* @__PURE__ */
|
|
29960
|
-
|
|
29961
|
-
|
|
29962
|
-
|
|
29963
|
-
|
|
29994
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 absolute z-50 right-3 top-3", children: [
|
|
29995
|
+
/* @__PURE__ */ jsx(
|
|
29996
|
+
ToolbarButton,
|
|
29997
|
+
{
|
|
29998
|
+
asChild: true,
|
|
29999
|
+
tooltip: "Visit Link",
|
|
30000
|
+
className: "cursor-pointer backdrop-blur-2xl size-6 shadow-none group-hover:bg-accent/70 group-hover:text-accent-foreground text-primary-send",
|
|
30001
|
+
children: /* @__PURE__ */ jsxs("span", { className: "relative", children: [
|
|
30002
|
+
/* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noopener noreferrer", className: "absolute inset-0" }),
|
|
30003
|
+
/* @__PURE__ */ jsx(ExternalLink, {})
|
|
30004
|
+
] })
|
|
30005
|
+
}
|
|
30006
|
+
),
|
|
30007
|
+
/* @__PURE__ */ jsx(
|
|
30008
|
+
ToolbarButton,
|
|
30009
|
+
{
|
|
30010
|
+
tooltip: "Remove Link Preview",
|
|
30011
|
+
onClick: handleDelete,
|
|
30012
|
+
"aria-label": "Delete link preview",
|
|
30013
|
+
type: "button",
|
|
30014
|
+
size: "icon",
|
|
30015
|
+
className: "cursor-pointer backdrop-blur-2xl size-6 shadow-none bg-transparent group-hover:bg-red-50/70 hover:bg-red-50 text-destructive hover:text-destructive",
|
|
30016
|
+
children: /* @__PURE__ */ jsx(Trash2, {})
|
|
30017
|
+
}
|
|
30018
|
+
)
|
|
30019
|
+
] }),
|
|
29964
30020
|
/* @__PURE__ */ jsx("div", { className: "relative z-0 w-full", children: /* @__PURE__ */ jsxs("div", { className: "group overflow-hidden flex flex-col rounded-lg border bg-accent/30 transition-all hover:border-foreground/20 hover:shadow-sm", children: [
|
|
29965
30021
|
/* @__PURE__ */ jsx("div", { className: "relative h-80 w-full shrink-0 overflow-hidden bg-muted border-b", children: /* @__PURE__ */ jsx(
|
|
29966
30022
|
"img",
|
|
@@ -30081,7 +30137,6 @@ const LinkPreview = Node$1.create({
|
|
|
30081
30137
|
},
|
|
30082
30138
|
renderHTML({ node }) {
|
|
30083
30139
|
const { href, uid, title, description, image, domain } = node.attrs;
|
|
30084
|
-
console.log("INSIDE RENDER HTML::", { href, image });
|
|
30085
30140
|
if (!href) return ["div", {}];
|
|
30086
30141
|
const content = [
|
|
30087
30142
|
// Link overlay
|
|
@@ -30216,11 +30271,6 @@ const MediaGroupView = ({ node, editor }) => {
|
|
|
30216
30271
|
editor.commands.deleteMediaByUid(uid);
|
|
30217
30272
|
};
|
|
30218
30273
|
const mediaNodes = node?.content?.content || [];
|
|
30219
|
-
console.log("MediaGroupView render:", {
|
|
30220
|
-
contentSize: node?.content?.size,
|
|
30221
|
-
mediaCount: mediaNodes?.length,
|
|
30222
|
-
nodes: mediaNodes?.map((n) => ({ type: n?.type?.name, uid: n?.attrs?.uid }))
|
|
30223
|
-
});
|
|
30224
30274
|
return /* @__PURE__ */ jsx(
|
|
30225
30275
|
NodeViewWrapper,
|
|
30226
30276
|
{
|
|
@@ -30322,14 +30372,12 @@ const createMediaModePlugin = () => {
|
|
|
30322
30372
|
child.marks.forEach((mark) => {
|
|
30323
30373
|
if (mark.type.name === "customLink" && mark.attrs.previewPayload) {
|
|
30324
30374
|
lastLinkPreviewData = mark.attrs.previewPayload;
|
|
30325
|
-
console.log("Found link with previewPayload:", lastLinkPreviewData);
|
|
30326
30375
|
}
|
|
30327
30376
|
});
|
|
30328
30377
|
}
|
|
30329
30378
|
});
|
|
30330
30379
|
}
|
|
30331
30380
|
});
|
|
30332
|
-
console.log("Cleanup check:", { modified, hasMediaGroup, lastLinkPreviewData });
|
|
30333
30381
|
if (modified && hasMediaGroup && lastLinkPreviewData) {
|
|
30334
30382
|
let hasLinkPreview = false;
|
|
30335
30383
|
tr.doc.forEach((node) => {
|
|
@@ -30337,10 +30385,6 @@ const createMediaModePlugin = () => {
|
|
|
30337
30385
|
hasLinkPreview = true;
|
|
30338
30386
|
}
|
|
30339
30387
|
});
|
|
30340
|
-
console.log("Creating linkPreview:", {
|
|
30341
|
-
hasLinkPreview,
|
|
30342
|
-
schemaHasLinkPreview: !!newState.schema.nodes.linkPreview
|
|
30343
|
-
});
|
|
30344
30388
|
if (!hasLinkPreview && newState.schema.nodes.linkPreview) {
|
|
30345
30389
|
const preview = lastLinkPreviewData;
|
|
30346
30390
|
const linkPreviewNode = newState.schema.nodes.linkPreview.create({
|
|
@@ -30351,7 +30395,6 @@ const createMediaModePlugin = () => {
|
|
|
30351
30395
|
image: preview.linkImage?.url ?? "",
|
|
30352
30396
|
variant: LinkPreviewType.Extended
|
|
30353
30397
|
});
|
|
30354
|
-
console.log("Inserting linkPreview node:", { lastLinkPreviewData, linkPreviewNode });
|
|
30355
30398
|
tr.insert(tr.doc.content.size, linkPreviewNode);
|
|
30356
30399
|
modified = true;
|
|
30357
30400
|
}
|
|
@@ -30411,7 +30454,6 @@ const createMediaModePlugin = () => {
|
|
|
30411
30454
|
}
|
|
30412
30455
|
const mediaNodes = updatedTopLevelMedia.map((m) => m.node);
|
|
30413
30456
|
if (mediaNodes.some((n) => !n || n.type.name !== "media")) {
|
|
30414
|
-
console.warn("Invalid media nodes detected, skipping group creation");
|
|
30415
30457
|
return null;
|
|
30416
30458
|
}
|
|
30417
30459
|
const mediaGroup = newState.schema.nodes.mediaGroup.create({}, mediaNodes);
|
|
@@ -30429,7 +30471,6 @@ const createMediaModePlugin = () => {
|
|
|
30429
30471
|
const $pos = tr.doc.resolve(endPos);
|
|
30430
30472
|
tr.setSelection(TextSelection$1.near($pos));
|
|
30431
30473
|
} catch (e) {
|
|
30432
|
-
console.warn("Could not set selection:", e);
|
|
30433
30474
|
}
|
|
30434
30475
|
}
|
|
30435
30476
|
tr.setMeta("addToHistory", false);
|
|
@@ -30437,7 +30478,6 @@ const createMediaModePlugin = () => {
|
|
|
30437
30478
|
}
|
|
30438
30479
|
return modified ? tr : null;
|
|
30439
30480
|
} catch (error) {
|
|
30440
|
-
console.error("MediaMode plugin error:", error);
|
|
30441
30481
|
return null;
|
|
30442
30482
|
} finally {
|
|
30443
30483
|
isProcessing = false;
|
|
@@ -30579,7 +30619,7 @@ const getMediaExtensions = ({ api, store, user }) => {
|
|
|
30579
30619
|
}),
|
|
30580
30620
|
LinkPreview.configure({
|
|
30581
30621
|
variant: LinkPreviewType.Extended,
|
|
30582
|
-
selectable: false,
|
|
30622
|
+
// selectable: false,
|
|
30583
30623
|
draggable: false
|
|
30584
30624
|
}),
|
|
30585
30625
|
getMentionExtension(core, mfs, store),
|
|
@@ -30723,7 +30763,6 @@ const isLinkMarkWithPayload = (node) => isLinkMark(node) && Boolean(node?.attrs?
|
|
|
30723
30763
|
const getLinkItemsPayload = (json) => {
|
|
30724
30764
|
const links = find(json, (node) => isLinkMarkWithPayload(node));
|
|
30725
30765
|
const items = links?.at(-1);
|
|
30726
|
-
console.log("Link Items Payload::", { items });
|
|
30727
30766
|
return { items };
|
|
30728
30767
|
};
|
|
30729
30768
|
const getPollItemsPayload = (json) => {
|
|
@@ -30737,7 +30776,7 @@ const isValidItem = (item) => {
|
|
|
30737
30776
|
const mediaItem = item;
|
|
30738
30777
|
const isValidLinkItem = linkItem?.linkUrl;
|
|
30739
30778
|
const mediaItemSources = mediaItem?.sources;
|
|
30740
|
-
const isValidMediaItem = mediaItemSources?.original?.url || mediaItemSources?.thumbnail?.url
|
|
30779
|
+
const isValidMediaItem = mediaItemSources?.original?.url || mediaItemSources?.thumbnail?.url;
|
|
30741
30780
|
return Boolean(isValidLinkItem || isValidMediaItem);
|
|
30742
30781
|
};
|
|
30743
30782
|
const generateHtmlPostPayload = ({
|
|
@@ -30757,7 +30796,6 @@ const generateHtmlPostPayload = ({
|
|
|
30757
30796
|
)?.at(0);
|
|
30758
30797
|
const isEmbedOnly = isOnlyContentNode(json, "iframe");
|
|
30759
30798
|
const body = isEmbedOnly ? previewItemEmbed?.attrs?.previewPayload?.linkTitle ?? previewItemEmbed?.attrs?.src ?? "" : secondaryText?.text ?? firstText?.text ?? "";
|
|
30760
|
-
console.log({ firstText });
|
|
30761
30799
|
const items = [
|
|
30762
30800
|
previewItemMedia?.attrs?.payload,
|
|
30763
30801
|
previewItemEmbed?.attrs?.previewPayload,
|
|
@@ -30784,11 +30822,14 @@ const generateMediaPostPayload = ({
|
|
|
30784
30822
|
const { mentionData } = getMentionDataPayload(json);
|
|
30785
30823
|
const { items: mediaItems } = getMediaItemsPayload(json);
|
|
30786
30824
|
const { items: linkItems } = getLinkItemsPayload(json);
|
|
30825
|
+
const items = mediaItems?.length > 0 ? mediaItems : linkItems?.length > 0 ? linkItems : [];
|
|
30826
|
+
if (!body && mediaItems.length === 0)
|
|
30827
|
+
return { error: "Your post is empty. Add text or media to share your thoughts." };
|
|
30787
30828
|
return {
|
|
30788
30829
|
...commons,
|
|
30789
30830
|
type: mediaItems?.length > 0 ? NewPostType.NEW_POST_MEDIA : linkItems?.length > 0 ? NewPostType.NEW_POST_LINK : NewPostType.NEW_POST_MESSAGE,
|
|
30790
30831
|
body,
|
|
30791
|
-
items
|
|
30832
|
+
items,
|
|
30792
30833
|
mentionData,
|
|
30793
30834
|
sendCrossMention
|
|
30794
30835
|
};
|
|
@@ -30808,7 +30849,6 @@ const generatePollPostPayload = ({
|
|
|
30808
30849
|
option_id: index2 === 0 ? item.option_id : v4(),
|
|
30809
30850
|
option_color: OPTION_COLORS[index2 % OPTION_COLORS.length]
|
|
30810
30851
|
})) : items;
|
|
30811
|
-
console.log({ polls });
|
|
30812
30852
|
return {
|
|
30813
30853
|
...commons,
|
|
30814
30854
|
type: NewPostType.NEW_POST_POLL,
|
|
@@ -30845,6 +30885,7 @@ const PostBuilderEditorInstance = ({
|
|
|
30845
30885
|
const [isDragging, setIsDragging] = useState(false);
|
|
30846
30886
|
const { trackPublish } = usePostBuilderAnalytics();
|
|
30847
30887
|
const { clearContent } = usePersistence();
|
|
30888
|
+
useHostAnalyticsBridge();
|
|
30848
30889
|
const handleDragOver = (e) => {
|
|
30849
30890
|
e.preventDefault();
|
|
30850
30891
|
setIsDragging(true);
|
|
@@ -30864,10 +30905,24 @@ const PostBuilderEditorInstance = ({
|
|
|
30864
30905
|
const text2 = editor?.getText();
|
|
30865
30906
|
const payload = generateCreatePostPayload(editorTab, { editor, sendCrossMention });
|
|
30866
30907
|
const isPollType = payload?.type === NewPostType.NEW_POST_POLL;
|
|
30867
|
-
if (
|
|
30908
|
+
if (payload?.error) {
|
|
30909
|
+
toast.error(payload.error);
|
|
30910
|
+
return;
|
|
30911
|
+
}
|
|
30912
|
+
if (!payload?.postId) return;
|
|
30868
30913
|
if (isPollType && payload.items?.length === 0)
|
|
30869
30914
|
return toast.warning(`At least ${POLL_LIMITS.MIN} option is mandatory to create a poll post`);
|
|
30870
|
-
|
|
30915
|
+
if (typeof window !== "undefined") {
|
|
30916
|
+
window.dispatchEvent(
|
|
30917
|
+
new CustomEvent(PostBuilderEvents.POST_PUBLISH_ATTEMPTED, {
|
|
30918
|
+
detail: {
|
|
30919
|
+
postId: payload.postId,
|
|
30920
|
+
postType: payload.type
|
|
30921
|
+
}
|
|
30922
|
+
})
|
|
30923
|
+
);
|
|
30924
|
+
}
|
|
30925
|
+
trackPublish({ status: "attempted", postId: payload?.postId, postType: payload?.type });
|
|
30871
30926
|
onCreatePost?.({ payload, html: html2, json, text: text2 });
|
|
30872
30927
|
if (!clearOnSuccess) return;
|
|
30873
30928
|
clearContent();
|
|
@@ -31041,7 +31096,6 @@ class SessionManager {
|
|
|
31041
31096
|
}, SESSION_TIMEOUT_MS);
|
|
31042
31097
|
}
|
|
31043
31098
|
endSession(reason) {
|
|
31044
|
-
console.log({ reason });
|
|
31045
31099
|
if (this.inactivityTimer) {
|
|
31046
31100
|
clearTimeout(this.inactivityTimer);
|
|
31047
31101
|
}
|
|
@@ -31102,7 +31156,7 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31102
31156
|
const featureTracker = useRef(new FeatureTracker()).current;
|
|
31103
31157
|
const logEvent = useAnalyticsLogEvent();
|
|
31104
31158
|
const trackEvent = useCallback(
|
|
31105
|
-
(name, properties
|
|
31159
|
+
({ name, properties }) => {
|
|
31106
31160
|
const fullConfig = { ...DEFAULT_CONFIG, ...config };
|
|
31107
31161
|
if (!fullConfig.enabled) return;
|
|
31108
31162
|
sessionManager.updateActivity();
|
|
@@ -31110,30 +31164,32 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31110
31164
|
session_id: sessionManager.getSessionId(),
|
|
31111
31165
|
timestamp: Date.now(),
|
|
31112
31166
|
editor_type: editorTab,
|
|
31113
|
-
...properties
|
|
31167
|
+
...properties ?? {}
|
|
31114
31168
|
};
|
|
31115
|
-
|
|
31116
|
-
|
|
31117
|
-
}
|
|
31118
|
-
if (fullConfig.debug) {
|
|
31119
|
-
console.log("[Analytics]", name, enrichedProperties);
|
|
31120
|
-
}
|
|
31169
|
+
const cleanProps = pickBy(enrichedProperties, (value) => value != null);
|
|
31170
|
+
if (logEvent) logEvent(name, cleanProps);
|
|
31121
31171
|
},
|
|
31122
31172
|
[config, editorTab, logEvent, sessionManager]
|
|
31123
31173
|
);
|
|
31124
31174
|
useEffect(() => {
|
|
31125
31175
|
const sessionId = sessionManager.startSession();
|
|
31126
|
-
trackEvent(
|
|
31127
|
-
|
|
31128
|
-
|
|
31129
|
-
|
|
31176
|
+
trackEvent({
|
|
31177
|
+
name: ANALYTICS_EVENTS.SESSION.STARTED,
|
|
31178
|
+
properties: {
|
|
31179
|
+
session_id: sessionId,
|
|
31180
|
+
timestamp: Date.now(),
|
|
31181
|
+
editor_type: editorTab
|
|
31182
|
+
}
|
|
31130
31183
|
});
|
|
31131
31184
|
const handleUnload = () => {
|
|
31132
|
-
trackEvent(
|
|
31133
|
-
|
|
31134
|
-
|
|
31135
|
-
|
|
31136
|
-
|
|
31185
|
+
trackEvent({
|
|
31186
|
+
name: ANALYTICS_EVENTS.SESSION.COMPLETED,
|
|
31187
|
+
properties: {
|
|
31188
|
+
session_id: sessionManager.getSessionId(),
|
|
31189
|
+
timestamp: Date.now(),
|
|
31190
|
+
editor_type: editorTab,
|
|
31191
|
+
session_duration_ms: sessionManager.getSessionDuration()
|
|
31192
|
+
}
|
|
31137
31193
|
});
|
|
31138
31194
|
};
|
|
31139
31195
|
window.addEventListener("beforeunload", handleUnload);
|
|
@@ -31143,60 +31199,88 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31143
31199
|
};
|
|
31144
31200
|
}, []);
|
|
31145
31201
|
const trackFeature = useCallback(
|
|
31146
|
-
(featureName) => {
|
|
31202
|
+
({ featureName }) => {
|
|
31147
31203
|
const { isFirstUse, usageCount } = featureTracker.trackUsage(featureName);
|
|
31148
|
-
trackEvent(
|
|
31149
|
-
|
|
31150
|
-
|
|
31151
|
-
|
|
31204
|
+
trackEvent({
|
|
31205
|
+
name: isFirstUse ? ANALYTICS_EVENTS.FEATURE.DISCOVERED : ANALYTICS_EVENTS.FEATURE.USED,
|
|
31206
|
+
properties: {
|
|
31207
|
+
feature_name: featureName,
|
|
31208
|
+
is_first_use: isFirstUse,
|
|
31209
|
+
usage_count: usageCount
|
|
31210
|
+
}
|
|
31152
31211
|
});
|
|
31153
31212
|
},
|
|
31154
31213
|
[trackEvent, featureTracker]
|
|
31155
31214
|
);
|
|
31156
31215
|
const trackPublish = useCallback(
|
|
31157
|
-
(status, data) => {
|
|
31216
|
+
({ status, data }) => {
|
|
31158
31217
|
const eventMap = {
|
|
31159
31218
|
attempted: ANALYTICS_EVENTS.PUBLISH.ATTEMPTED,
|
|
31160
31219
|
success: ANALYTICS_EVENTS.PUBLISH.SUCCESS,
|
|
31161
31220
|
failed: ANALYTICS_EVENTS.PUBLISH.FAILED
|
|
31162
31221
|
};
|
|
31163
|
-
|
|
31222
|
+
const properties = {
|
|
31164
31223
|
editor_type: editorTab,
|
|
31165
31224
|
session_duration_ms: sessionManager.getSessionDuration(),
|
|
31166
31225
|
...data
|
|
31226
|
+
};
|
|
31227
|
+
trackEvent({
|
|
31228
|
+
name: eventMap[status],
|
|
31229
|
+
properties
|
|
31167
31230
|
});
|
|
31168
31231
|
sessionManager.endSession("completed");
|
|
31169
31232
|
},
|
|
31170
31233
|
[trackEvent, editorTab, sessionManager]
|
|
31171
31234
|
);
|
|
31172
31235
|
const trackAbandon = useCallback(
|
|
31173
|
-
(
|
|
31174
|
-
|
|
31175
|
-
|
|
31176
|
-
|
|
31177
|
-
|
|
31178
|
-
|
|
31179
|
-
|
|
31236
|
+
({
|
|
31237
|
+
contentLength,
|
|
31238
|
+
hasUnsavedChanges,
|
|
31239
|
+
abandonReason,
|
|
31240
|
+
postType,
|
|
31241
|
+
userHistoryData
|
|
31242
|
+
}) => {
|
|
31243
|
+
trackEvent({
|
|
31244
|
+
name: ANALYTICS_EVENTS.SESSION.ABANDONED,
|
|
31245
|
+
properties: {
|
|
31246
|
+
session_duration_ms: sessionManager.getSessionDuration(),
|
|
31247
|
+
post_type: postType,
|
|
31248
|
+
content_length: contentLength,
|
|
31249
|
+
has_unsaved_changes: hasUnsavedChanges,
|
|
31250
|
+
abandon_reason: abandonReason,
|
|
31251
|
+
// Include user history if provided
|
|
31252
|
+
...userHistoryData && {
|
|
31253
|
+
previous_abandon_count: userHistoryData.previous_abandon_count,
|
|
31254
|
+
previous_publish_count: userHistoryData.previous_publish_count,
|
|
31255
|
+
time_since_last_publish_ms: userHistoryData.time_since_last_publish_ms,
|
|
31256
|
+
is_returning_user: userHistoryData.is_returning_user
|
|
31257
|
+
}
|
|
31258
|
+
}
|
|
31180
31259
|
});
|
|
31181
31260
|
sessionManager.endSession("abandoned");
|
|
31182
31261
|
},
|
|
31183
31262
|
[trackEvent, sessionManager]
|
|
31184
31263
|
);
|
|
31185
31264
|
const trackTabSwitch = useCallback(
|
|
31186
|
-
(oldTab, newTab) => {
|
|
31187
|
-
trackEvent(
|
|
31188
|
-
|
|
31189
|
-
|
|
31190
|
-
|
|
31265
|
+
({ oldTab, newTab }) => {
|
|
31266
|
+
trackEvent({
|
|
31267
|
+
name: ANALYTICS_EVENTS.EDITOR.FOCUSED,
|
|
31268
|
+
properties: {
|
|
31269
|
+
from_tab: oldTab,
|
|
31270
|
+
to_tab: newTab
|
|
31271
|
+
}
|
|
31191
31272
|
});
|
|
31192
31273
|
},
|
|
31193
|
-
[trackEvent
|
|
31274
|
+
[trackEvent]
|
|
31194
31275
|
);
|
|
31195
31276
|
const trackEditorFocus = useCallback(
|
|
31196
|
-
(context) => {
|
|
31197
|
-
trackEvent(
|
|
31198
|
-
|
|
31199
|
-
|
|
31277
|
+
({ context }) => {
|
|
31278
|
+
trackEvent({
|
|
31279
|
+
name: ANALYTICS_EVENTS.EDITOR.FOCUSED,
|
|
31280
|
+
properties: {
|
|
31281
|
+
context,
|
|
31282
|
+
editor_type: editorTab
|
|
31283
|
+
}
|
|
31200
31284
|
});
|
|
31201
31285
|
},
|
|
31202
31286
|
[trackEvent, editorTab]
|
|
@@ -31230,19 +31314,91 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31230
31314
|
]
|
|
31231
31315
|
);
|
|
31232
31316
|
}
|
|
31317
|
+
const STORAGE_KEY = "pb_user_history";
|
|
31318
|
+
class UserHistoryTracker {
|
|
31319
|
+
history;
|
|
31320
|
+
constructor() {
|
|
31321
|
+
this.history = this.loadHistory();
|
|
31322
|
+
}
|
|
31323
|
+
loadHistory() {
|
|
31324
|
+
try {
|
|
31325
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
31326
|
+
if (stored) {
|
|
31327
|
+
return JSON.parse(stored);
|
|
31328
|
+
}
|
|
31329
|
+
} catch (error) {
|
|
31330
|
+
}
|
|
31331
|
+
return {
|
|
31332
|
+
previous_abandon_count: 0,
|
|
31333
|
+
previous_publish_count: 0,
|
|
31334
|
+
last_publish_timestamp: null,
|
|
31335
|
+
last_abandon_timestamp: null,
|
|
31336
|
+
first_session_timestamp: Date.now()
|
|
31337
|
+
};
|
|
31338
|
+
}
|
|
31339
|
+
saveHistory() {
|
|
31340
|
+
try {
|
|
31341
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(this.history));
|
|
31342
|
+
} catch (error) {
|
|
31343
|
+
}
|
|
31344
|
+
}
|
|
31345
|
+
/**
|
|
31346
|
+
* Record a successful publish
|
|
31347
|
+
*/
|
|
31348
|
+
recordPublish() {
|
|
31349
|
+
this.history.previous_publish_count += 1;
|
|
31350
|
+
this.history.last_publish_timestamp = Date.now();
|
|
31351
|
+
this.saveHistory();
|
|
31352
|
+
}
|
|
31353
|
+
/**
|
|
31354
|
+
* Record an abandonment
|
|
31355
|
+
*/
|
|
31356
|
+
recordAbandon() {
|
|
31357
|
+
this.history.previous_abandon_count += 1;
|
|
31358
|
+
this.history.last_abandon_timestamp = Date.now();
|
|
31359
|
+
this.saveHistory();
|
|
31360
|
+
}
|
|
31361
|
+
/**
|
|
31362
|
+
* Get current user history for analytics
|
|
31363
|
+
*/
|
|
31364
|
+
getHistory() {
|
|
31365
|
+
const now2 = Date.now();
|
|
31366
|
+
const daysSinceFirstSession = Math.floor(
|
|
31367
|
+
(now2 - this.history.first_session_timestamp) / (1e3 * 60 * 60 * 24)
|
|
31368
|
+
);
|
|
31369
|
+
return {
|
|
31370
|
+
previous_abandon_count: this.history.previous_abandon_count,
|
|
31371
|
+
previous_publish_count: this.history.previous_publish_count,
|
|
31372
|
+
time_since_last_publish_ms: this.history.last_publish_timestamp ? now2 - this.history.last_publish_timestamp : null,
|
|
31373
|
+
is_returning_user: daysSinceFirstSession > 0.5,
|
|
31374
|
+
days_since_first_session: daysSinceFirstSession
|
|
31375
|
+
};
|
|
31376
|
+
}
|
|
31377
|
+
/**
|
|
31378
|
+
* Clear history (for testing or user request)
|
|
31379
|
+
*/
|
|
31380
|
+
clearHistory() {
|
|
31381
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
31382
|
+
this.history = {
|
|
31383
|
+
previous_abandon_count: 0,
|
|
31384
|
+
previous_publish_count: 0,
|
|
31385
|
+
last_publish_timestamp: null,
|
|
31386
|
+
last_abandon_timestamp: null,
|
|
31387
|
+
first_session_timestamp: Date.now()
|
|
31388
|
+
};
|
|
31389
|
+
}
|
|
31390
|
+
}
|
|
31233
31391
|
function useEditorAnalytics({
|
|
31234
31392
|
editor,
|
|
31235
31393
|
editorType,
|
|
31236
31394
|
context,
|
|
31237
31395
|
idleTimeout = 3e5,
|
|
31238
|
-
// 5 minutes
|
|
31239
31396
|
trackBlur = false
|
|
31240
|
-
// Default: don't track every blur
|
|
31241
31397
|
}) {
|
|
31242
31398
|
const analytics = useAnalytics({
|
|
31243
31399
|
editorTab: editorType,
|
|
31244
31400
|
config: {
|
|
31245
|
-
debug:
|
|
31401
|
+
debug: true,
|
|
31246
31402
|
enabled: true
|
|
31247
31403
|
}
|
|
31248
31404
|
});
|
|
@@ -31250,6 +31406,7 @@ function useEditorAnalytics({
|
|
|
31250
31406
|
const idleTimer = useRef();
|
|
31251
31407
|
const hasFocusedOnce = useRef(false);
|
|
31252
31408
|
const hasAbandonedSession = useRef(false);
|
|
31409
|
+
const userHistory = useRef(new UserHistoryTracker()).current;
|
|
31253
31410
|
const getEditorMetrics = useCallback(() => {
|
|
31254
31411
|
if (!editor) return null;
|
|
31255
31412
|
const json = editor.getJSON();
|
|
@@ -31289,7 +31446,6 @@ function useEditorAnalytics({
|
|
|
31289
31446
|
linkCount,
|
|
31290
31447
|
formattingFeatures: Array.from(formattingFeatures),
|
|
31291
31448
|
hasUnsavedChanges: editor.state.doc.content.size > 2,
|
|
31292
|
-
// Has content beyond empty doc
|
|
31293
31449
|
isEmpty: editor.isEmpty
|
|
31294
31450
|
};
|
|
31295
31451
|
}, [editor, analytics]);
|
|
@@ -31300,16 +31456,29 @@ function useEditorAnalytics({
|
|
|
31300
31456
|
idleTimer.current = setTimeout(() => {
|
|
31301
31457
|
const metrics = getEditorMetrics();
|
|
31302
31458
|
if (metrics && !metrics.isEmpty) {
|
|
31303
|
-
|
|
31459
|
+
const history = userHistory.getHistory();
|
|
31460
|
+
analytics.trackAbandon({
|
|
31461
|
+
contentLength: metrics.characterCount,
|
|
31462
|
+
hasUnsavedChanges: metrics.hasUnsavedChanges,
|
|
31463
|
+
abandonReason: "idle_timeout",
|
|
31464
|
+
postType: void 0,
|
|
31465
|
+
userHistoryData: {
|
|
31466
|
+
previous_abandon_count: history.previous_abandon_count,
|
|
31467
|
+
previous_publish_count: history.previous_publish_count,
|
|
31468
|
+
time_since_last_publish_ms: history.time_since_last_publish_ms,
|
|
31469
|
+
is_returning_user: history.is_returning_user
|
|
31470
|
+
}
|
|
31471
|
+
});
|
|
31472
|
+
userHistory.recordAbandon();
|
|
31304
31473
|
hasAbandonedSession.current = true;
|
|
31305
31474
|
}
|
|
31306
31475
|
}, idleTimeout);
|
|
31307
|
-
}, [editor, idleTimeout, analytics, getEditorMetrics]);
|
|
31476
|
+
}, [editor, idleTimeout, analytics, getEditorMetrics, userHistory]);
|
|
31308
31477
|
useEffect(() => {
|
|
31309
31478
|
if (!editor) return;
|
|
31310
31479
|
const handleFocus = () => {
|
|
31311
31480
|
if (!hasFocusedOnce.current) {
|
|
31312
|
-
analytics.trackEditorFocus(context);
|
|
31481
|
+
analytics.trackEditorFocus({ context });
|
|
31313
31482
|
hasFocusedOnce.current = true;
|
|
31314
31483
|
}
|
|
31315
31484
|
resetIdleTimer();
|
|
@@ -31320,9 +31489,12 @@ function useEditorAnalytics({
|
|
|
31320
31489
|
if (trackBlur) {
|
|
31321
31490
|
const metrics = getEditorMetrics();
|
|
31322
31491
|
if (metrics && !metrics.isEmpty) {
|
|
31323
|
-
analytics.trackEvent(
|
|
31324
|
-
|
|
31325
|
-
|
|
31492
|
+
analytics.trackEvent({
|
|
31493
|
+
name: ANALYTICS_EVENTS.EDITOR.BLURRED,
|
|
31494
|
+
properties: {
|
|
31495
|
+
content_length: metrics.characterCount,
|
|
31496
|
+
session_duration_ms: Date.now() - lastActivity.current
|
|
31497
|
+
}
|
|
31326
31498
|
});
|
|
31327
31499
|
}
|
|
31328
31500
|
}
|
|
@@ -31341,7 +31513,20 @@ function useEditorAnalytics({
|
|
|
31341
31513
|
if (hasAbandonedSession.current) return;
|
|
31342
31514
|
const metrics = getEditorMetrics();
|
|
31343
31515
|
if (metrics && !metrics.isEmpty) {
|
|
31344
|
-
|
|
31516
|
+
const history = userHistory.getHistory();
|
|
31517
|
+
analytics.trackAbandon({
|
|
31518
|
+
contentLength: metrics.characterCount,
|
|
31519
|
+
hasUnsavedChanges: metrics.hasUnsavedChanges,
|
|
31520
|
+
abandonReason: "navigation",
|
|
31521
|
+
postType: void 0,
|
|
31522
|
+
userHistoryData: {
|
|
31523
|
+
previous_abandon_count: history.previous_abandon_count,
|
|
31524
|
+
previous_publish_count: history.previous_publish_count,
|
|
31525
|
+
time_since_last_publish_ms: history.time_since_last_publish_ms,
|
|
31526
|
+
is_returning_user: history.is_returning_user
|
|
31527
|
+
}
|
|
31528
|
+
});
|
|
31529
|
+
userHistory.recordAbandon();
|
|
31345
31530
|
hasAbandonedSession.current = true;
|
|
31346
31531
|
}
|
|
31347
31532
|
};
|
|
@@ -31352,46 +31537,76 @@ function useEditorAnalytics({
|
|
|
31352
31537
|
clearTimeout(idleTimer.current);
|
|
31353
31538
|
}
|
|
31354
31539
|
};
|
|
31355
|
-
}, [editor, analytics, getEditorMetrics]);
|
|
31540
|
+
}, [editor, analytics, getEditorMetrics, userHistory]);
|
|
31356
31541
|
const trackFeature = useCallback(
|
|
31357
|
-
(featureName) => {
|
|
31358
|
-
analytics.trackFeature(featureName);
|
|
31542
|
+
({ featureName }) => {
|
|
31543
|
+
analytics.trackFeature({ featureName });
|
|
31359
31544
|
resetIdleTimer();
|
|
31360
31545
|
},
|
|
31361
31546
|
[analytics, resetIdleTimer]
|
|
31362
31547
|
);
|
|
31363
31548
|
const trackPublish = useCallback(
|
|
31364
|
-
(status, failureReason) => {
|
|
31549
|
+
({ sessionId, groupId, postId, status, failureReason, postType }) => {
|
|
31365
31550
|
const metrics = getEditorMetrics();
|
|
31366
31551
|
if (!metrics) return;
|
|
31367
|
-
|
|
31368
|
-
|
|
31369
|
-
|
|
31370
|
-
|
|
31371
|
-
|
|
31372
|
-
|
|
31373
|
-
|
|
31552
|
+
const history = userHistory.getHistory();
|
|
31553
|
+
analytics.trackPublish({
|
|
31554
|
+
status,
|
|
31555
|
+
data: {
|
|
31556
|
+
...sessionId ? { session_id: sessionId } : {},
|
|
31557
|
+
group_id: groupId,
|
|
31558
|
+
post_id: postId,
|
|
31559
|
+
post_type: postType,
|
|
31560
|
+
word_count: metrics.wordCount,
|
|
31561
|
+
character_count: metrics.characterCount,
|
|
31562
|
+
media_count: metrics.mediaCount,
|
|
31563
|
+
link_count: metrics.linkCount,
|
|
31564
|
+
formatting_features: metrics.formattingFeatures,
|
|
31565
|
+
failure_reason: failureReason,
|
|
31566
|
+
// Include user history
|
|
31567
|
+
previous_abandon_count: history.previous_abandon_count,
|
|
31568
|
+
previous_publish_count: history.previous_publish_count,
|
|
31569
|
+
time_since_last_publish_ms: history.time_since_last_publish_ms,
|
|
31570
|
+
is_returning_user: history.is_returning_user
|
|
31571
|
+
}
|
|
31374
31572
|
});
|
|
31375
31573
|
if (status === "success") {
|
|
31574
|
+
userHistory.recordPublish();
|
|
31376
31575
|
hasAbandonedSession.current = true;
|
|
31377
31576
|
}
|
|
31378
31577
|
},
|
|
31379
|
-
[analytics, getEditorMetrics]
|
|
31578
|
+
[analytics, getEditorMetrics, userHistory]
|
|
31380
31579
|
);
|
|
31381
31580
|
const trackExplicitAbandon = useCallback(() => {
|
|
31382
31581
|
if (hasAbandonedSession.current) return;
|
|
31383
31582
|
const metrics = getEditorMetrics();
|
|
31384
31583
|
if (metrics && !metrics.isEmpty) {
|
|
31385
|
-
|
|
31584
|
+
const history = userHistory.getHistory();
|
|
31585
|
+
analytics.trackAbandon({
|
|
31586
|
+
contentLength: metrics.characterCount,
|
|
31587
|
+
hasUnsavedChanges: metrics.hasUnsavedChanges,
|
|
31588
|
+
abandonReason: "user_closed",
|
|
31589
|
+
postType: void 0,
|
|
31590
|
+
userHistoryData: {
|
|
31591
|
+
previous_abandon_count: history.previous_abandon_count,
|
|
31592
|
+
previous_publish_count: history.previous_publish_count,
|
|
31593
|
+
time_since_last_publish_ms: history.time_since_last_publish_ms,
|
|
31594
|
+
is_returning_user: history.is_returning_user
|
|
31595
|
+
}
|
|
31596
|
+
});
|
|
31597
|
+
userHistory.recordAbandon();
|
|
31386
31598
|
hasAbandonedSession.current = true;
|
|
31387
31599
|
}
|
|
31388
|
-
}, [analytics, getEditorMetrics]);
|
|
31600
|
+
}, [analytics, getEditorMetrics, userHistory]);
|
|
31389
31601
|
return {
|
|
31390
31602
|
trackFeature,
|
|
31391
31603
|
trackPublish,
|
|
31392
31604
|
trackExplicitAbandon,
|
|
31393
31605
|
trackTabSwitch: analytics.trackTabSwitch,
|
|
31394
|
-
getEditorMetrics
|
|
31606
|
+
getEditorMetrics,
|
|
31607
|
+
// Expose user history for debugging
|
|
31608
|
+
getUserHistory: () => userHistory.getHistory(),
|
|
31609
|
+
currentSessionId: analytics.getSessionId()
|
|
31395
31610
|
};
|
|
31396
31611
|
}
|
|
31397
31612
|
const PostBuilderAnalyticsProvider = ({
|
|
@@ -31457,58 +31672,68 @@ const PostBuilderEditor = ({
|
|
|
31457
31672
|
isSubmitting,
|
|
31458
31673
|
clearOnSuccess
|
|
31459
31674
|
}
|
|
31460
|
-
) : (
|
|
31461
|
-
|
|
31462
|
-
|
|
31463
|
-
|
|
31464
|
-
|
|
31465
|
-
|
|
31466
|
-
|
|
31467
|
-
|
|
31468
|
-
|
|
31469
|
-
|
|
31470
|
-
|
|
31471
|
-
|
|
31472
|
-
|
|
31473
|
-
|
|
31474
|
-
|
|
31475
|
-
// </DialogClose>
|
|
31476
|
-
// </div>
|
|
31477
|
-
// )}
|
|
31478
|
-
// </DialogHeader>
|
|
31479
|
-
// <PostBuilderEditorInstance
|
|
31480
|
-
// editor={editor}
|
|
31481
|
-
// actions={actions}
|
|
31482
|
-
// editorTab={editorTab}
|
|
31483
|
-
// onSwitchEditor={setEditorTab}
|
|
31484
|
-
// isSubmitting={isSubmitting}
|
|
31485
|
-
// onCreatePost={onCreatePost}
|
|
31486
|
-
// clearOnSuccess={clearOnSuccess}
|
|
31487
|
-
// />
|
|
31488
|
-
// </DialogContent>
|
|
31489
|
-
// </Dialog>
|
|
31490
|
-
/* @__PURE__ */ jsxs("div", { className: "prose-blockquote: flex-1 flex flex-col space-y-3 max-w-full max-h-[calc(100dvh-7rem)]", children: [
|
|
31491
|
-
!hideGroupSelector && /* @__PURE__ */ jsx(GroupSelector, { user, store }),
|
|
31492
|
-
/* @__PURE__ */ jsx(
|
|
31493
|
-
PostBuilderEditorInstance,
|
|
31494
|
-
{
|
|
31495
|
-
editor,
|
|
31496
|
-
actions,
|
|
31497
|
-
editorTab,
|
|
31498
|
-
onSwitchEditor: setEditorTab,
|
|
31499
|
-
isSubmitting,
|
|
31500
|
-
onCreatePost,
|
|
31501
|
-
clearOnSuccess
|
|
31502
|
-
}
|
|
31503
|
-
)
|
|
31504
|
-
] })
|
|
31505
|
-
) }),
|
|
31675
|
+
) : /* @__PURE__ */ jsxs("div", { className: "prose-blockquote: flex-1 flex flex-col space-y-3 max-w-full max-h-[calc(100dvh-7rem)]", children: [
|
|
31676
|
+
!hideGroupSelector && /* @__PURE__ */ jsx(GroupSelector, { user, store }),
|
|
31677
|
+
/* @__PURE__ */ jsx(
|
|
31678
|
+
PostBuilderEditorInstance,
|
|
31679
|
+
{
|
|
31680
|
+
editor,
|
|
31681
|
+
actions,
|
|
31682
|
+
editorTab,
|
|
31683
|
+
onSwitchEditor: setEditorTab,
|
|
31684
|
+
isSubmitting,
|
|
31685
|
+
onCreatePost,
|
|
31686
|
+
clearOnSuccess
|
|
31687
|
+
}
|
|
31688
|
+
)
|
|
31689
|
+
] }) }),
|
|
31506
31690
|
/* @__PURE__ */ jsx(Toaster2, { position: "top-center" })
|
|
31507
31691
|
] })
|
|
31508
31692
|
}
|
|
31509
31693
|
);
|
|
31510
31694
|
};
|
|
31695
|
+
const PostBuilderProvider = ({
|
|
31696
|
+
children,
|
|
31697
|
+
apiBaseURL,
|
|
31698
|
+
authToken,
|
|
31699
|
+
toI18N,
|
|
31700
|
+
i18nKeys,
|
|
31701
|
+
logEvent
|
|
31702
|
+
}) => {
|
|
31703
|
+
const t = useCallback(
|
|
31704
|
+
(key, fallback) => {
|
|
31705
|
+
const message = toI18N(i18nKeys[key]);
|
|
31706
|
+
if (message) return message;
|
|
31707
|
+
return fallback || key;
|
|
31708
|
+
},
|
|
31709
|
+
[toI18N, i18nKeys]
|
|
31710
|
+
);
|
|
31711
|
+
const api = useMemo(() => {
|
|
31712
|
+
const core = new CoreApi(apiBaseURL.core, authToken, toI18N);
|
|
31713
|
+
const mfs = new MFSApi(apiBaseURL.mfs, authToken, toI18N);
|
|
31714
|
+
const fileStore = new FilestoreApi(apiBaseURL.fileStore, authToken, toI18N);
|
|
31715
|
+
core.initApi();
|
|
31716
|
+
mfs.initApi();
|
|
31717
|
+
fileStore.initApi();
|
|
31718
|
+
return {
|
|
31719
|
+
core,
|
|
31720
|
+
mfs,
|
|
31721
|
+
fileStore
|
|
31722
|
+
};
|
|
31723
|
+
}, [authToken, apiBaseURL, toI18N]);
|
|
31724
|
+
const value = useMemo(() => {
|
|
31725
|
+
return {
|
|
31726
|
+
authToken,
|
|
31727
|
+
t,
|
|
31728
|
+
i18nKeys,
|
|
31729
|
+
api,
|
|
31730
|
+
logEvent
|
|
31731
|
+
};
|
|
31732
|
+
}, [authToken, t, i18nKeys, api, logEvent]);
|
|
31733
|
+
return /* @__PURE__ */ jsx(PostBuilderContext.Provider, { value, children });
|
|
31734
|
+
};
|
|
31511
31735
|
export {
|
|
31512
31736
|
PostBuilderEditor,
|
|
31737
|
+
PostBuilderEvents,
|
|
31513
31738
|
PostBuilderProvider
|
|
31514
31739
|
};
|