@select-org/select-post-builder 1.1.1 → 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 +585 -351
- package/dist/post-builder.js +586 -352
- 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) => {
|
|
@@ -30731,6 +30770,15 @@ const getPollItemsPayload = (json) => {
|
|
|
30731
30770
|
const items = poll[0].attrs?.choices;
|
|
30732
30771
|
return { items };
|
|
30733
30772
|
};
|
|
30773
|
+
const isValidItem = (item) => {
|
|
30774
|
+
if (!item) return false;
|
|
30775
|
+
const linkItem = item;
|
|
30776
|
+
const mediaItem = item;
|
|
30777
|
+
const isValidLinkItem = linkItem?.linkUrl;
|
|
30778
|
+
const mediaItemSources = mediaItem?.sources;
|
|
30779
|
+
const isValidMediaItem = mediaItemSources?.original?.url || mediaItemSources?.thumbnail?.url;
|
|
30780
|
+
return Boolean(isValidLinkItem || isValidMediaItem);
|
|
30781
|
+
};
|
|
30734
30782
|
const generateHtmlPostPayload = ({
|
|
30735
30783
|
editor,
|
|
30736
30784
|
sendCrossMention
|
|
@@ -30747,13 +30795,12 @@ const generateHtmlPostPayload = ({
|
|
|
30747
30795
|
(node) => node?.type === "text" && (node?.marks?.some((val) => val?.type !== "customLink") ?? true)
|
|
30748
30796
|
)?.at(0);
|
|
30749
30797
|
const isEmbedOnly = isOnlyContentNode(json, "iframe");
|
|
30750
|
-
const body = isEmbedOnly ? previewItemEmbed?.attrs?.previewPayload?.linkTitle ?? "" : secondaryText?.text ?? firstText?.text ?? "";
|
|
30751
|
-
console.log({ firstText });
|
|
30798
|
+
const body = isEmbedOnly ? previewItemEmbed?.attrs?.previewPayload?.linkTitle ?? previewItemEmbed?.attrs?.src ?? "" : secondaryText?.text ?? firstText?.text ?? "";
|
|
30752
30799
|
const items = [
|
|
30753
30800
|
previewItemMedia?.attrs?.payload,
|
|
30754
30801
|
previewItemEmbed?.attrs?.previewPayload,
|
|
30755
30802
|
linkPreviewItem
|
|
30756
|
-
]?.filter(
|
|
30803
|
+
]?.filter(isValidItem)?.filter((_, index2) => index2 === 0);
|
|
30757
30804
|
const htmlBody = html2;
|
|
30758
30805
|
return {
|
|
30759
30806
|
...commons,
|
|
@@ -30775,11 +30822,14 @@ const generateMediaPostPayload = ({
|
|
|
30775
30822
|
const { mentionData } = getMentionDataPayload(json);
|
|
30776
30823
|
const { items: mediaItems } = getMediaItemsPayload(json);
|
|
30777
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." };
|
|
30778
30828
|
return {
|
|
30779
30829
|
...commons,
|
|
30780
30830
|
type: mediaItems?.length > 0 ? NewPostType.NEW_POST_MEDIA : linkItems?.length > 0 ? NewPostType.NEW_POST_LINK : NewPostType.NEW_POST_MESSAGE,
|
|
30781
30831
|
body,
|
|
30782
|
-
items
|
|
30832
|
+
items,
|
|
30783
30833
|
mentionData,
|
|
30784
30834
|
sendCrossMention
|
|
30785
30835
|
};
|
|
@@ -30799,7 +30849,6 @@ const generatePollPostPayload = ({
|
|
|
30799
30849
|
option_id: index2 === 0 ? item.option_id : v4(),
|
|
30800
30850
|
option_color: OPTION_COLORS[index2 % OPTION_COLORS.length]
|
|
30801
30851
|
})) : items;
|
|
30802
|
-
console.log({ polls });
|
|
30803
30852
|
return {
|
|
30804
30853
|
...commons,
|
|
30805
30854
|
type: NewPostType.NEW_POST_POLL,
|
|
@@ -30836,6 +30885,7 @@ const PostBuilderEditorInstance = ({
|
|
|
30836
30885
|
const [isDragging, setIsDragging] = useState(false);
|
|
30837
30886
|
const { trackPublish } = usePostBuilderAnalytics();
|
|
30838
30887
|
const { clearContent } = usePersistence();
|
|
30888
|
+
useHostAnalyticsBridge();
|
|
30839
30889
|
const handleDragOver = (e) => {
|
|
30840
30890
|
e.preventDefault();
|
|
30841
30891
|
setIsDragging(true);
|
|
@@ -30855,10 +30905,24 @@ const PostBuilderEditorInstance = ({
|
|
|
30855
30905
|
const text2 = editor?.getText();
|
|
30856
30906
|
const payload = generateCreatePostPayload(editorTab, { editor, sendCrossMention });
|
|
30857
30907
|
const isPollType = payload?.type === NewPostType.NEW_POST_POLL;
|
|
30858
|
-
if (
|
|
30908
|
+
if (payload?.error) {
|
|
30909
|
+
toast.error(payload.error);
|
|
30910
|
+
return;
|
|
30911
|
+
}
|
|
30912
|
+
if (!payload?.postId) return;
|
|
30859
30913
|
if (isPollType && payload.items?.length === 0)
|
|
30860
30914
|
return toast.warning(`At least ${POLL_LIMITS.MIN} option is mandatory to create a poll post`);
|
|
30861
|
-
|
|
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 });
|
|
30862
30926
|
onCreatePost?.({ payload, html: html2, json, text: text2 });
|
|
30863
30927
|
if (!clearOnSuccess) return;
|
|
30864
30928
|
clearContent();
|
|
@@ -31032,7 +31096,6 @@ class SessionManager {
|
|
|
31032
31096
|
}, SESSION_TIMEOUT_MS);
|
|
31033
31097
|
}
|
|
31034
31098
|
endSession(reason) {
|
|
31035
|
-
console.log({ reason });
|
|
31036
31099
|
if (this.inactivityTimer) {
|
|
31037
31100
|
clearTimeout(this.inactivityTimer);
|
|
31038
31101
|
}
|
|
@@ -31093,7 +31156,7 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31093
31156
|
const featureTracker = useRef(new FeatureTracker()).current;
|
|
31094
31157
|
const logEvent = useAnalyticsLogEvent();
|
|
31095
31158
|
const trackEvent = useCallback(
|
|
31096
|
-
(name, properties
|
|
31159
|
+
({ name, properties }) => {
|
|
31097
31160
|
const fullConfig = { ...DEFAULT_CONFIG, ...config };
|
|
31098
31161
|
if (!fullConfig.enabled) return;
|
|
31099
31162
|
sessionManager.updateActivity();
|
|
@@ -31101,30 +31164,32 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31101
31164
|
session_id: sessionManager.getSessionId(),
|
|
31102
31165
|
timestamp: Date.now(),
|
|
31103
31166
|
editor_type: editorTab,
|
|
31104
|
-
...properties
|
|
31167
|
+
...properties ?? {}
|
|
31105
31168
|
};
|
|
31106
|
-
|
|
31107
|
-
|
|
31108
|
-
}
|
|
31109
|
-
if (fullConfig.debug) {
|
|
31110
|
-
console.log("[Analytics]", name, enrichedProperties);
|
|
31111
|
-
}
|
|
31169
|
+
const cleanProps = pickBy(enrichedProperties, (value) => value != null);
|
|
31170
|
+
if (logEvent) logEvent(name, cleanProps);
|
|
31112
31171
|
},
|
|
31113
31172
|
[config, editorTab, logEvent, sessionManager]
|
|
31114
31173
|
);
|
|
31115
31174
|
useEffect(() => {
|
|
31116
31175
|
const sessionId = sessionManager.startSession();
|
|
31117
|
-
trackEvent(
|
|
31118
|
-
|
|
31119
|
-
|
|
31120
|
-
|
|
31176
|
+
trackEvent({
|
|
31177
|
+
name: ANALYTICS_EVENTS.SESSION.STARTED,
|
|
31178
|
+
properties: {
|
|
31179
|
+
session_id: sessionId,
|
|
31180
|
+
timestamp: Date.now(),
|
|
31181
|
+
editor_type: editorTab
|
|
31182
|
+
}
|
|
31121
31183
|
});
|
|
31122
31184
|
const handleUnload = () => {
|
|
31123
|
-
trackEvent(
|
|
31124
|
-
|
|
31125
|
-
|
|
31126
|
-
|
|
31127
|
-
|
|
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
|
+
}
|
|
31128
31193
|
});
|
|
31129
31194
|
};
|
|
31130
31195
|
window.addEventListener("beforeunload", handleUnload);
|
|
@@ -31134,60 +31199,88 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31134
31199
|
};
|
|
31135
31200
|
}, []);
|
|
31136
31201
|
const trackFeature = useCallback(
|
|
31137
|
-
(featureName) => {
|
|
31202
|
+
({ featureName }) => {
|
|
31138
31203
|
const { isFirstUse, usageCount } = featureTracker.trackUsage(featureName);
|
|
31139
|
-
trackEvent(
|
|
31140
|
-
|
|
31141
|
-
|
|
31142
|
-
|
|
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
|
+
}
|
|
31143
31211
|
});
|
|
31144
31212
|
},
|
|
31145
31213
|
[trackEvent, featureTracker]
|
|
31146
31214
|
);
|
|
31147
31215
|
const trackPublish = useCallback(
|
|
31148
|
-
(status, data) => {
|
|
31216
|
+
({ status, data }) => {
|
|
31149
31217
|
const eventMap = {
|
|
31150
31218
|
attempted: ANALYTICS_EVENTS.PUBLISH.ATTEMPTED,
|
|
31151
31219
|
success: ANALYTICS_EVENTS.PUBLISH.SUCCESS,
|
|
31152
31220
|
failed: ANALYTICS_EVENTS.PUBLISH.FAILED
|
|
31153
31221
|
};
|
|
31154
|
-
|
|
31222
|
+
const properties = {
|
|
31155
31223
|
editor_type: editorTab,
|
|
31156
31224
|
session_duration_ms: sessionManager.getSessionDuration(),
|
|
31157
31225
|
...data
|
|
31226
|
+
};
|
|
31227
|
+
trackEvent({
|
|
31228
|
+
name: eventMap[status],
|
|
31229
|
+
properties
|
|
31158
31230
|
});
|
|
31159
31231
|
sessionManager.endSession("completed");
|
|
31160
31232
|
},
|
|
31161
31233
|
[trackEvent, editorTab, sessionManager]
|
|
31162
31234
|
);
|
|
31163
31235
|
const trackAbandon = useCallback(
|
|
31164
|
-
(
|
|
31165
|
-
|
|
31166
|
-
|
|
31167
|
-
|
|
31168
|
-
|
|
31169
|
-
|
|
31170
|
-
|
|
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
|
+
}
|
|
31171
31259
|
});
|
|
31172
31260
|
sessionManager.endSession("abandoned");
|
|
31173
31261
|
},
|
|
31174
31262
|
[trackEvent, sessionManager]
|
|
31175
31263
|
);
|
|
31176
31264
|
const trackTabSwitch = useCallback(
|
|
31177
|
-
(oldTab, newTab) => {
|
|
31178
|
-
trackEvent(
|
|
31179
|
-
|
|
31180
|
-
|
|
31181
|
-
|
|
31265
|
+
({ oldTab, newTab }) => {
|
|
31266
|
+
trackEvent({
|
|
31267
|
+
name: ANALYTICS_EVENTS.EDITOR.FOCUSED,
|
|
31268
|
+
properties: {
|
|
31269
|
+
from_tab: oldTab,
|
|
31270
|
+
to_tab: newTab
|
|
31271
|
+
}
|
|
31182
31272
|
});
|
|
31183
31273
|
},
|
|
31184
|
-
[trackEvent
|
|
31274
|
+
[trackEvent]
|
|
31185
31275
|
);
|
|
31186
31276
|
const trackEditorFocus = useCallback(
|
|
31187
|
-
(context) => {
|
|
31188
|
-
trackEvent(
|
|
31189
|
-
|
|
31190
|
-
|
|
31277
|
+
({ context }) => {
|
|
31278
|
+
trackEvent({
|
|
31279
|
+
name: ANALYTICS_EVENTS.EDITOR.FOCUSED,
|
|
31280
|
+
properties: {
|
|
31281
|
+
context,
|
|
31282
|
+
editor_type: editorTab
|
|
31283
|
+
}
|
|
31191
31284
|
});
|
|
31192
31285
|
},
|
|
31193
31286
|
[trackEvent, editorTab]
|
|
@@ -31221,19 +31314,91 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31221
31314
|
]
|
|
31222
31315
|
);
|
|
31223
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
|
+
}
|
|
31224
31391
|
function useEditorAnalytics({
|
|
31225
31392
|
editor,
|
|
31226
31393
|
editorType,
|
|
31227
31394
|
context,
|
|
31228
31395
|
idleTimeout = 3e5,
|
|
31229
|
-
// 5 minutes
|
|
31230
31396
|
trackBlur = false
|
|
31231
|
-
// Default: don't track every blur
|
|
31232
31397
|
}) {
|
|
31233
31398
|
const analytics = useAnalytics({
|
|
31234
31399
|
editorTab: editorType,
|
|
31235
31400
|
config: {
|
|
31236
|
-
debug:
|
|
31401
|
+
debug: true,
|
|
31237
31402
|
enabled: true
|
|
31238
31403
|
}
|
|
31239
31404
|
});
|
|
@@ -31241,6 +31406,7 @@ function useEditorAnalytics({
|
|
|
31241
31406
|
const idleTimer = useRef();
|
|
31242
31407
|
const hasFocusedOnce = useRef(false);
|
|
31243
31408
|
const hasAbandonedSession = useRef(false);
|
|
31409
|
+
const userHistory = useRef(new UserHistoryTracker()).current;
|
|
31244
31410
|
const getEditorMetrics = useCallback(() => {
|
|
31245
31411
|
if (!editor) return null;
|
|
31246
31412
|
const json = editor.getJSON();
|
|
@@ -31280,7 +31446,6 @@ function useEditorAnalytics({
|
|
|
31280
31446
|
linkCount,
|
|
31281
31447
|
formattingFeatures: Array.from(formattingFeatures),
|
|
31282
31448
|
hasUnsavedChanges: editor.state.doc.content.size > 2,
|
|
31283
|
-
// Has content beyond empty doc
|
|
31284
31449
|
isEmpty: editor.isEmpty
|
|
31285
31450
|
};
|
|
31286
31451
|
}, [editor, analytics]);
|
|
@@ -31291,16 +31456,29 @@ function useEditorAnalytics({
|
|
|
31291
31456
|
idleTimer.current = setTimeout(() => {
|
|
31292
31457
|
const metrics = getEditorMetrics();
|
|
31293
31458
|
if (metrics && !metrics.isEmpty) {
|
|
31294
|
-
|
|
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();
|
|
31295
31473
|
hasAbandonedSession.current = true;
|
|
31296
31474
|
}
|
|
31297
31475
|
}, idleTimeout);
|
|
31298
|
-
}, [editor, idleTimeout, analytics, getEditorMetrics]);
|
|
31476
|
+
}, [editor, idleTimeout, analytics, getEditorMetrics, userHistory]);
|
|
31299
31477
|
useEffect(() => {
|
|
31300
31478
|
if (!editor) return;
|
|
31301
31479
|
const handleFocus = () => {
|
|
31302
31480
|
if (!hasFocusedOnce.current) {
|
|
31303
|
-
analytics.trackEditorFocus(context);
|
|
31481
|
+
analytics.trackEditorFocus({ context });
|
|
31304
31482
|
hasFocusedOnce.current = true;
|
|
31305
31483
|
}
|
|
31306
31484
|
resetIdleTimer();
|
|
@@ -31311,9 +31489,12 @@ function useEditorAnalytics({
|
|
|
31311
31489
|
if (trackBlur) {
|
|
31312
31490
|
const metrics = getEditorMetrics();
|
|
31313
31491
|
if (metrics && !metrics.isEmpty) {
|
|
31314
|
-
analytics.trackEvent(
|
|
31315
|
-
|
|
31316
|
-
|
|
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
|
+
}
|
|
31317
31498
|
});
|
|
31318
31499
|
}
|
|
31319
31500
|
}
|
|
@@ -31332,7 +31513,20 @@ function useEditorAnalytics({
|
|
|
31332
31513
|
if (hasAbandonedSession.current) return;
|
|
31333
31514
|
const metrics = getEditorMetrics();
|
|
31334
31515
|
if (metrics && !metrics.isEmpty) {
|
|
31335
|
-
|
|
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();
|
|
31336
31530
|
hasAbandonedSession.current = true;
|
|
31337
31531
|
}
|
|
31338
31532
|
};
|
|
@@ -31343,46 +31537,76 @@ function useEditorAnalytics({
|
|
|
31343
31537
|
clearTimeout(idleTimer.current);
|
|
31344
31538
|
}
|
|
31345
31539
|
};
|
|
31346
|
-
}, [editor, analytics, getEditorMetrics]);
|
|
31540
|
+
}, [editor, analytics, getEditorMetrics, userHistory]);
|
|
31347
31541
|
const trackFeature = useCallback(
|
|
31348
|
-
(featureName) => {
|
|
31349
|
-
analytics.trackFeature(featureName);
|
|
31542
|
+
({ featureName }) => {
|
|
31543
|
+
analytics.trackFeature({ featureName });
|
|
31350
31544
|
resetIdleTimer();
|
|
31351
31545
|
},
|
|
31352
31546
|
[analytics, resetIdleTimer]
|
|
31353
31547
|
);
|
|
31354
31548
|
const trackPublish = useCallback(
|
|
31355
|
-
(status, failureReason) => {
|
|
31549
|
+
({ sessionId, groupId, postId, status, failureReason, postType }) => {
|
|
31356
31550
|
const metrics = getEditorMetrics();
|
|
31357
31551
|
if (!metrics) return;
|
|
31358
|
-
|
|
31359
|
-
|
|
31360
|
-
|
|
31361
|
-
|
|
31362
|
-
|
|
31363
|
-
|
|
31364
|
-
|
|
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
|
+
}
|
|
31365
31572
|
});
|
|
31366
31573
|
if (status === "success") {
|
|
31574
|
+
userHistory.recordPublish();
|
|
31367
31575
|
hasAbandonedSession.current = true;
|
|
31368
31576
|
}
|
|
31369
31577
|
},
|
|
31370
|
-
[analytics, getEditorMetrics]
|
|
31578
|
+
[analytics, getEditorMetrics, userHistory]
|
|
31371
31579
|
);
|
|
31372
31580
|
const trackExplicitAbandon = useCallback(() => {
|
|
31373
31581
|
if (hasAbandonedSession.current) return;
|
|
31374
31582
|
const metrics = getEditorMetrics();
|
|
31375
31583
|
if (metrics && !metrics.isEmpty) {
|
|
31376
|
-
|
|
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();
|
|
31377
31598
|
hasAbandonedSession.current = true;
|
|
31378
31599
|
}
|
|
31379
|
-
}, [analytics, getEditorMetrics]);
|
|
31600
|
+
}, [analytics, getEditorMetrics, userHistory]);
|
|
31380
31601
|
return {
|
|
31381
31602
|
trackFeature,
|
|
31382
31603
|
trackPublish,
|
|
31383
31604
|
trackExplicitAbandon,
|
|
31384
31605
|
trackTabSwitch: analytics.trackTabSwitch,
|
|
31385
|
-
getEditorMetrics
|
|
31606
|
+
getEditorMetrics,
|
|
31607
|
+
// Expose user history for debugging
|
|
31608
|
+
getUserHistory: () => userHistory.getHistory(),
|
|
31609
|
+
currentSessionId: analytics.getSessionId()
|
|
31386
31610
|
};
|
|
31387
31611
|
}
|
|
31388
31612
|
const PostBuilderAnalyticsProvider = ({
|
|
@@ -31448,58 +31672,68 @@ const PostBuilderEditor = ({
|
|
|
31448
31672
|
isSubmitting,
|
|
31449
31673
|
clearOnSuccess
|
|
31450
31674
|
}
|
|
31451
|
-
) : (
|
|
31452
|
-
|
|
31453
|
-
|
|
31454
|
-
|
|
31455
|
-
|
|
31456
|
-
|
|
31457
|
-
|
|
31458
|
-
|
|
31459
|
-
|
|
31460
|
-
|
|
31461
|
-
|
|
31462
|
-
|
|
31463
|
-
|
|
31464
|
-
|
|
31465
|
-
|
|
31466
|
-
// </DialogClose>
|
|
31467
|
-
// </div>
|
|
31468
|
-
// )}
|
|
31469
|
-
// </DialogHeader>
|
|
31470
|
-
// <PostBuilderEditorInstance
|
|
31471
|
-
// editor={editor}
|
|
31472
|
-
// actions={actions}
|
|
31473
|
-
// editorTab={editorTab}
|
|
31474
|
-
// onSwitchEditor={setEditorTab}
|
|
31475
|
-
// isSubmitting={isSubmitting}
|
|
31476
|
-
// onCreatePost={onCreatePost}
|
|
31477
|
-
// clearOnSuccess={clearOnSuccess}
|
|
31478
|
-
// />
|
|
31479
|
-
// </DialogContent>
|
|
31480
|
-
// </Dialog>
|
|
31481
|
-
/* @__PURE__ */ jsxs("div", { className: "prose-blockquote: flex-1 flex flex-col space-y-3 max-w-full max-h-[calc(100dvh-7rem)]", children: [
|
|
31482
|
-
!hideGroupSelector && /* @__PURE__ */ jsx(GroupSelector, { user, store }),
|
|
31483
|
-
/* @__PURE__ */ jsx(
|
|
31484
|
-
PostBuilderEditorInstance,
|
|
31485
|
-
{
|
|
31486
|
-
editor,
|
|
31487
|
-
actions,
|
|
31488
|
-
editorTab,
|
|
31489
|
-
onSwitchEditor: setEditorTab,
|
|
31490
|
-
isSubmitting,
|
|
31491
|
-
onCreatePost,
|
|
31492
|
-
clearOnSuccess
|
|
31493
|
-
}
|
|
31494
|
-
)
|
|
31495
|
-
] })
|
|
31496
|
-
) }),
|
|
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
|
+
] }) }),
|
|
31497
31690
|
/* @__PURE__ */ jsx(Toaster2, { position: "top-center" })
|
|
31498
31691
|
] })
|
|
31499
31692
|
}
|
|
31500
31693
|
);
|
|
31501
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
|
+
};
|
|
31502
31735
|
export {
|
|
31503
31736
|
PostBuilderEditor,
|
|
31737
|
+
PostBuilderEvents,
|
|
31504
31738
|
PostBuilderProvider
|
|
31505
31739
|
};
|