@select-org/select-post-builder 1.1.2 → 1.1.4
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 +576 -352
- package/dist/post-builder.js +577 -353
- 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,10 +20740,82 @@ 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
|
-
if (typeof window === "undefined" || typeof localStorage === "undefined" || !editor
|
|
20816
|
-
return;
|
|
20818
|
+
if (typeof window === "undefined" || typeof localStorage === "undefined" || !editor) return;
|
|
20817
20819
|
const json = editor?.getJSON();
|
|
20818
20820
|
const filteredJson = filterNodes(json, (node) => !node?.attrs?.uploading);
|
|
20819
20821
|
if (filteredJson) {
|
|
@@ -21066,11 +21068,9 @@ var Progress$1 = React.forwardRef(
|
|
|
21066
21068
|
...progressProps
|
|
21067
21069
|
} = props;
|
|
21068
21070
|
if ((maxProp || maxProp === 0) && !isValidMaxNumber(maxProp)) {
|
|
21069
|
-
console.error(getInvalidMaxError(`${maxProp}`, "Progress"));
|
|
21070
21071
|
}
|
|
21071
21072
|
const max2 = isValidMaxNumber(maxProp) ? maxProp : DEFAULT_MAX;
|
|
21072
21073
|
if (valueProp !== null && !isValidValueNumber(valueProp, max2)) {
|
|
21073
|
-
console.error(getInvalidValueError(`${valueProp}`, "Progress"));
|
|
21074
21074
|
}
|
|
21075
21075
|
const value = isValidValueNumber(valueProp, max2) ? valueProp : null;
|
|
21076
21076
|
const valueLabel = isNumber(value) ? getValueLabel(value, max2) : void 0;
|
|
@@ -21390,13 +21390,7 @@ const createUpdateMarkByUidCommand = (markName) => {
|
|
|
21390
21390
|
state,
|
|
21391
21391
|
dispatch
|
|
21392
21392
|
}) => {
|
|
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
21393
|
if (!dispatch) {
|
|
21399
|
-
console.log("No dispatch, returning false");
|
|
21400
21394
|
return false;
|
|
21401
21395
|
}
|
|
21402
21396
|
const { doc, schema } = state;
|
|
@@ -21406,13 +21400,6 @@ const createUpdateMarkByUidCommand = (markName) => {
|
|
|
21406
21400
|
doc.descendants((node, pos) => {
|
|
21407
21401
|
if (node.isText && node.marks?.length) {
|
|
21408
21402
|
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
21403
|
if (mark.type.name === markName && mark.attrs.uid === uid) {
|
|
21417
21404
|
positions.push({
|
|
21418
21405
|
from: pos,
|
|
@@ -21420,33 +21407,21 @@ const createUpdateMarkByUidCommand = (markName) => {
|
|
|
21420
21407
|
mark
|
|
21421
21408
|
});
|
|
21422
21409
|
found2 = true;
|
|
21423
|
-
console.log("Found matching mark at:", { from: pos, to: pos + node.nodeSize });
|
|
21424
21410
|
}
|
|
21425
21411
|
});
|
|
21426
21412
|
}
|
|
21427
21413
|
});
|
|
21428
|
-
console.log("Total positions found:", positions.length);
|
|
21429
|
-
console.log("Positions:", positions);
|
|
21430
21414
|
if (found2) {
|
|
21431
21415
|
positions.forEach(({ from, to, mark }) => {
|
|
21432
21416
|
const newAttrs = { ...mark.attrs, ...attrs };
|
|
21433
21417
|
const markType = schema.marks[markName];
|
|
21434
|
-
console.log("Applying update:", { from, to, oldAttrs: mark.attrs, newAttrs });
|
|
21435
21418
|
if (markType) {
|
|
21436
|
-
console.log("Before removeMark - tr.doc:", tr.doc.toJSON());
|
|
21437
21419
|
tr = tr.removeMark(from, to, markType);
|
|
21438
|
-
console.log("After removeMark - tr.doc:", tr.doc.toJSON());
|
|
21439
21420
|
tr = tr.addMark(from, to, markType.create(newAttrs));
|
|
21440
|
-
console.log("After addMark - tr.doc:", tr.doc.toJSON());
|
|
21441
21421
|
}
|
|
21442
21422
|
});
|
|
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
21423
|
dispatch(tr);
|
|
21447
|
-
console.log("Transaction dispatched successfully");
|
|
21448
21424
|
}
|
|
21449
|
-
console.log("=== UPDATE MARK COMMAND END ===");
|
|
21450
21425
|
return found2;
|
|
21451
21426
|
};
|
|
21452
21427
|
};
|
|
@@ -22464,7 +22439,6 @@ let warnedAboutTextSelection = false;
|
|
|
22464
22439
|
function checkTextSelection($pos) {
|
|
22465
22440
|
if (!warnedAboutTextSelection && !$pos.parent.inlineContent) {
|
|
22466
22441
|
warnedAboutTextSelection = true;
|
|
22467
|
-
console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")");
|
|
22468
22442
|
}
|
|
22469
22443
|
}
|
|
22470
22444
|
class TextSelection extends Selection {
|
|
@@ -23189,7 +23163,6 @@ const PollCreator = ({ choices, onChange }) => {
|
|
|
23189
23163
|
const result = await fileStore.uploadImage(file);
|
|
23190
23164
|
return createPollMediaOption(result, startIndex + index2);
|
|
23191
23165
|
} catch (error) {
|
|
23192
|
-
console.error("Upload failed for", file.name, error);
|
|
23193
23166
|
return null;
|
|
23194
23167
|
}
|
|
23195
23168
|
});
|
|
@@ -23209,7 +23182,6 @@ const PollCreator = ({ choices, onChange }) => {
|
|
|
23209
23182
|
return final;
|
|
23210
23183
|
});
|
|
23211
23184
|
} catch (error) {
|
|
23212
|
-
console.error("Unexpected error during file upload:", error);
|
|
23213
23185
|
setInternalChoices((current) => {
|
|
23214
23186
|
const withoutPlaceholders = current.filter((c) => !isPlaceholder(c));
|
|
23215
23187
|
setTimeout(() => {
|
|
@@ -23242,7 +23214,6 @@ const PollCreator = ({ choices, onChange }) => {
|
|
|
23242
23214
|
return updated;
|
|
23243
23215
|
});
|
|
23244
23216
|
} catch (error) {
|
|
23245
|
-
console.error("URL upload failed:", error);
|
|
23246
23217
|
setInternalChoices((current) => {
|
|
23247
23218
|
const withoutPlaceholder = current.filter((c) => !isPlaceholder(c));
|
|
23248
23219
|
setTimeout(() => {
|
|
@@ -23783,7 +23754,6 @@ const LinkMarkView = ({ mark, editor }) => {
|
|
|
23783
23754
|
};
|
|
23784
23755
|
const handleUpdateLink = (link, text2, uid, previewPayload) => {
|
|
23785
23756
|
if (!editor.view) return;
|
|
23786
|
-
console.log("UPDATE LINK IN VIEW::", { text: text2 });
|
|
23787
23757
|
const newText = mark?.attrs?.isLinkMode ? link : text2 || link;
|
|
23788
23758
|
if (uid) {
|
|
23789
23759
|
editor.commands.updateLink(uid, { href: link, text: newText, previewPayload });
|
|
@@ -23843,25 +23813,66 @@ const LinkMarkView = ({ mark, editor }) => {
|
|
|
23843
23813
|
)
|
|
23844
23814
|
] });
|
|
23845
23815
|
};
|
|
23816
|
+
function isValidUrlFormat(text2) {
|
|
23817
|
+
return isValidUrl(normalizeUrl(text2.trim()));
|
|
23818
|
+
}
|
|
23846
23819
|
function doesPreviewExist(editor, uid) {
|
|
23847
|
-
|
|
23848
|
-
|
|
23849
|
-
|
|
23850
|
-
|
|
23851
|
-
|
|
23852
|
-
|
|
23853
|
-
|
|
23854
|
-
|
|
23820
|
+
if (!editor || !uid) {
|
|
23821
|
+
return false;
|
|
23822
|
+
}
|
|
23823
|
+
try {
|
|
23824
|
+
let exists = false;
|
|
23825
|
+
editor.state.doc.descendants((node) => {
|
|
23826
|
+
if (node && node.type && node.type.name === "linkPreview" && node.attrs?.uid === uid) {
|
|
23827
|
+
exists = true;
|
|
23828
|
+
return false;
|
|
23829
|
+
}
|
|
23830
|
+
});
|
|
23831
|
+
return exists;
|
|
23832
|
+
} catch (err) {
|
|
23833
|
+
return false;
|
|
23834
|
+
}
|
|
23855
23835
|
}
|
|
23856
23836
|
function findExistingPreview(editor) {
|
|
23857
|
-
|
|
23858
|
-
|
|
23859
|
-
|
|
23860
|
-
|
|
23861
|
-
|
|
23837
|
+
if (!editor) {
|
|
23838
|
+
return null;
|
|
23839
|
+
}
|
|
23840
|
+
try {
|
|
23841
|
+
let result = null;
|
|
23842
|
+
editor.state.doc.descendants((node, pos) => {
|
|
23843
|
+
if (node && node.type && node.type.name === "linkPreview") {
|
|
23844
|
+
result = { node, pos };
|
|
23845
|
+
return false;
|
|
23846
|
+
}
|
|
23847
|
+
});
|
|
23848
|
+
return result;
|
|
23849
|
+
} catch (err) {
|
|
23850
|
+
return null;
|
|
23851
|
+
}
|
|
23852
|
+
}
|
|
23853
|
+
function removePreviewByUid(editor, uid) {
|
|
23854
|
+
if (!editor || !uid) {
|
|
23855
|
+
return;
|
|
23856
|
+
}
|
|
23857
|
+
try {
|
|
23858
|
+
let previewPos = null;
|
|
23859
|
+
let previewSize = 0;
|
|
23860
|
+
editor.state.doc.descendants((node, pos) => {
|
|
23861
|
+
if (node && node.type && node.type.name === "linkPreview" && node.attrs?.uid === uid) {
|
|
23862
|
+
previewPos = pos;
|
|
23863
|
+
previewSize = node.nodeSize;
|
|
23864
|
+
return false;
|
|
23865
|
+
}
|
|
23866
|
+
});
|
|
23867
|
+
if (previewPos !== null && previewSize > 0) {
|
|
23868
|
+
const tr = editor.state.tr;
|
|
23869
|
+
if (tr) {
|
|
23870
|
+
tr.delete(previewPos, Number(previewPos) + previewSize);
|
|
23871
|
+
editor.view.dispatch(tr);
|
|
23872
|
+
}
|
|
23862
23873
|
}
|
|
23863
|
-
})
|
|
23864
|
-
|
|
23874
|
+
} catch (err) {
|
|
23875
|
+
}
|
|
23865
23876
|
}
|
|
23866
23877
|
function extractBestImage(metadata) {
|
|
23867
23878
|
return metadata?.image?.high_resolution ?? metadata?.image?.url ?? metadata?.image?.thumbnail ?? metadata?.image?.placeholder ?? null;
|
|
@@ -23886,6 +23897,76 @@ function collectAllLinkMarks(state, linkMark) {
|
|
|
23886
23897
|
});
|
|
23887
23898
|
return links;
|
|
23888
23899
|
}
|
|
23900
|
+
function syncLinkHrefWithText(newState, linkMark, editor, singlePreviewMode, pluginState) {
|
|
23901
|
+
if (!newState || !linkMark || !editor || !pluginState) {
|
|
23902
|
+
return null;
|
|
23903
|
+
}
|
|
23904
|
+
let tr = null;
|
|
23905
|
+
let hasChanges = false;
|
|
23906
|
+
try {
|
|
23907
|
+
newState.doc.descendants((node, pos) => {
|
|
23908
|
+
if (!node || !node.isText || !node.marks?.length) return;
|
|
23909
|
+
node.marks.forEach((mark) => {
|
|
23910
|
+
if (!mark || !mark.type || !mark.attrs) return;
|
|
23911
|
+
if (mark.type === linkMark && mark.attrs?.uid) {
|
|
23912
|
+
const currentText = node.text || "";
|
|
23913
|
+
const currentHref = mark.attrs.href || "";
|
|
23914
|
+
if (currentText !== currentHref) {
|
|
23915
|
+
const isValidUrl2 = isValidUrlFormat(currentText);
|
|
23916
|
+
if (!tr) {
|
|
23917
|
+
tr = newState.tr;
|
|
23918
|
+
}
|
|
23919
|
+
if (!tr) {
|
|
23920
|
+
return;
|
|
23921
|
+
}
|
|
23922
|
+
if (isValidUrl2) {
|
|
23923
|
+
const newMark = linkMark.create({
|
|
23924
|
+
...mark.attrs,
|
|
23925
|
+
href: normalizeUrl(currentText)
|
|
23926
|
+
});
|
|
23927
|
+
if (!newMark) {
|
|
23928
|
+
return;
|
|
23929
|
+
}
|
|
23930
|
+
tr = tr.removeMark(pos, pos + node.nodeSize, linkMark);
|
|
23931
|
+
tr = tr.addMark(pos, pos + node.nodeSize, newMark);
|
|
23932
|
+
hasChanges = true;
|
|
23933
|
+
pluginState.processedLinks.delete(mark.attrs.uid);
|
|
23934
|
+
if (singlePreviewMode) {
|
|
23935
|
+
queueMicrotask(() => {
|
|
23936
|
+
try {
|
|
23937
|
+
const existingPreview = findExistingPreview(editor);
|
|
23938
|
+
if (existingPreview && mark.attrs?.uid) {
|
|
23939
|
+
}
|
|
23940
|
+
} catch (err) {
|
|
23941
|
+
}
|
|
23942
|
+
});
|
|
23943
|
+
} else {
|
|
23944
|
+
}
|
|
23945
|
+
} else {
|
|
23946
|
+
tr = tr.removeMark(pos, pos + node.nodeSize, linkMark);
|
|
23947
|
+
hasChanges = true;
|
|
23948
|
+
queueMicrotask(() => {
|
|
23949
|
+
try {
|
|
23950
|
+
if (mark.attrs?.uid) {
|
|
23951
|
+
removePreviewByUid(editor, mark.attrs.uid);
|
|
23952
|
+
}
|
|
23953
|
+
} catch (err) {
|
|
23954
|
+
}
|
|
23955
|
+
});
|
|
23956
|
+
if (mark.attrs?.uid) {
|
|
23957
|
+
pluginState.processedLinks.delete(mark.attrs.uid);
|
|
23958
|
+
pluginState.resolvingLinks.delete(mark.attrs.uid);
|
|
23959
|
+
}
|
|
23960
|
+
}
|
|
23961
|
+
}
|
|
23962
|
+
}
|
|
23963
|
+
});
|
|
23964
|
+
});
|
|
23965
|
+
} catch (err) {
|
|
23966
|
+
return null;
|
|
23967
|
+
}
|
|
23968
|
+
return hasChanges ? tr : null;
|
|
23969
|
+
}
|
|
23889
23970
|
function assignUidsToLinks(newState, linkMark) {
|
|
23890
23971
|
const newUids = /* @__PURE__ */ new Map();
|
|
23891
23972
|
let tr = null;
|
|
@@ -23895,11 +23976,6 @@ function assignUidsToLinks(newState, linkMark) {
|
|
|
23895
23976
|
node.marks.forEach((mark) => {
|
|
23896
23977
|
if (mark.type === linkMark && mark.attrs?.href && !mark.attrs.uid) {
|
|
23897
23978
|
const newUid = v4();
|
|
23898
|
-
console.log("🔧 Assigning UID to autolinked URL:", {
|
|
23899
|
-
href: mark.attrs.href,
|
|
23900
|
-
uid: newUid,
|
|
23901
|
-
pos
|
|
23902
|
-
});
|
|
23903
23979
|
const newMark = linkMark.create({
|
|
23904
23980
|
...mark.attrs,
|
|
23905
23981
|
uid: newUid
|
|
@@ -23926,25 +24002,14 @@ function resolveLinkAndHandlePreview(link, options, singlePreviewMode, pluginSta
|
|
|
23926
24002
|
const { api, editor } = options;
|
|
23927
24003
|
const mediaGroup = findByType(editor?.getJSON(), "mediaGroup");
|
|
23928
24004
|
if (!api) {
|
|
23929
|
-
console.warn("⚠️ No API provided to resolve link");
|
|
23930
24005
|
return;
|
|
23931
24006
|
}
|
|
23932
24007
|
if (singlePreviewMode && mediaGroup.length >= 1) return;
|
|
23933
24008
|
pluginState.resolvingLinks.add(link.uid);
|
|
23934
|
-
console.log("🌐 Resolving link metadata:", {
|
|
23935
|
-
uid: link.uid,
|
|
23936
|
-
href: link.href,
|
|
23937
|
-
singlePreviewMode
|
|
23938
|
-
});
|
|
23939
24009
|
api.resolveUrl(normalizeUrl(link.href)).then((metadata) => {
|
|
23940
24010
|
pluginState.resolvingLinks.delete(link.uid);
|
|
23941
24011
|
pluginState.processedLinks.add(link.uid);
|
|
23942
|
-
console.log("✅ Link metadata resolved:", {
|
|
23943
|
-
uid: link.uid,
|
|
23944
|
-
metadata
|
|
23945
|
-
});
|
|
23946
24012
|
if (!metadata) {
|
|
23947
|
-
console.warn("⚠️ No metadata returned for:", link.href);
|
|
23948
24013
|
return;
|
|
23949
24014
|
}
|
|
23950
24015
|
const previewData = {
|
|
@@ -23959,13 +24024,11 @@ function resolveLinkAndHandlePreview(link, options, singlePreviewMode, pluginSta
|
|
|
23959
24024
|
if (singlePreviewMode) {
|
|
23960
24025
|
const existingPreview = findExistingPreview(editor);
|
|
23961
24026
|
if (existingPreview) {
|
|
23962
|
-
console.log("🔄 Updating existing preview in single mode");
|
|
23963
24027
|
const { pos } = existingPreview;
|
|
23964
24028
|
const tr = editor.state.tr;
|
|
23965
24029
|
tr.setNodeMarkup(pos, void 0, previewData);
|
|
23966
24030
|
editor.view.dispatch(tr);
|
|
23967
24031
|
} else {
|
|
23968
|
-
console.log("➕ Creating first preview in single mode");
|
|
23969
24032
|
editor.commands.setLinkPreview(previewData);
|
|
23970
24033
|
}
|
|
23971
24034
|
editor.commands.updateLinkByUid(link.uid, {
|
|
@@ -23973,16 +24036,12 @@ function resolveLinkAndHandlePreview(link, options, singlePreviewMode, pluginSta
|
|
|
23973
24036
|
});
|
|
23974
24037
|
} else {
|
|
23975
24038
|
if (!doesPreviewExist(editor, link.uid)) {
|
|
23976
|
-
console.log("➕ Creating new preview in multi mode");
|
|
23977
24039
|
editor.chain().updateLinkByUid(link.uid, {
|
|
23978
24040
|
previewPayload: convertLinkMetaToPreviewItem(metadata)
|
|
23979
24041
|
}).setLinkPreview(previewData).run();
|
|
23980
|
-
} else {
|
|
23981
|
-
console.log("⏭️ Preview already exists, skipping");
|
|
23982
24042
|
}
|
|
23983
24043
|
}
|
|
23984
24044
|
}).catch((err) => {
|
|
23985
|
-
console.error("❌ Failed to resolve link:", err);
|
|
23986
24045
|
pluginState.resolvingLinks.delete(link.uid);
|
|
23987
24046
|
});
|
|
23988
24047
|
}
|
|
@@ -23992,10 +24051,6 @@ function createLinkAutoResolvePlugin(options, singlePreviewMode = false) {
|
|
|
23992
24051
|
key: pluginKey,
|
|
23993
24052
|
state: {
|
|
23994
24053
|
init() {
|
|
23995
|
-
console.log("🔌 LinkAutoResolve plugin initialized", {
|
|
23996
|
-
singlePreviewMode,
|
|
23997
|
-
hasApi: !!options.api
|
|
23998
|
-
});
|
|
23999
24054
|
return {
|
|
24000
24055
|
resolvingLinks: /* @__PURE__ */ new Set(),
|
|
24001
24056
|
processedLinks: /* @__PURE__ */ new Set()
|
|
@@ -24025,27 +24080,22 @@ function createLinkAutoResolvePlugin(options, singlePreviewMode = false) {
|
|
|
24025
24080
|
appendTransaction: (transactions, oldState, newState) => {
|
|
24026
24081
|
const linkMark = newState.schema.marks["customLink"];
|
|
24027
24082
|
if (!linkMark) {
|
|
24028
|
-
console.warn("⚠️ customLink mark not found in schema");
|
|
24029
24083
|
return null;
|
|
24030
24084
|
}
|
|
24031
24085
|
if (!transactions.some((tr) => tr.docChanged)) {
|
|
24032
24086
|
return null;
|
|
24033
24087
|
}
|
|
24034
|
-
console.log("📝 Document changed, checking for new links...");
|
|
24035
24088
|
const pluginState = pluginKey.getState(newState);
|
|
24089
|
+
if (!pluginState) {
|
|
24090
|
+
return null;
|
|
24091
|
+
}
|
|
24092
|
+
const syncTr = singlePreviewMode ? syncLinkHrefWithText(newState, linkMark, options.editor, singlePreviewMode, pluginState) : null;
|
|
24036
24093
|
const oldLinks = collectAllLinkMarks(oldState, linkMark);
|
|
24037
24094
|
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
24095
|
const { tr: uidTr, newUids } = assignUidsToLinks(newState, linkMark);
|
|
24045
24096
|
const linksToResolve = [];
|
|
24046
24097
|
newUids.forEach((linkData) => {
|
|
24047
24098
|
if (!pluginState.processedLinks.has(linkData.uid) && !pluginState.resolvingLinks.has(linkData.uid)) {
|
|
24048
|
-
console.log("🆕 New autolinked URL detected:", linkData);
|
|
24049
24099
|
linksToResolve.push(linkData);
|
|
24050
24100
|
}
|
|
24051
24101
|
});
|
|
@@ -24058,21 +24108,33 @@ function createLinkAutoResolvePlugin(options, singlePreviewMode = false) {
|
|
|
24058
24108
|
return;
|
|
24059
24109
|
}
|
|
24060
24110
|
if (!oldLinks.has(uid)) {
|
|
24061
|
-
console.log("🆕 New link detected (with UID):", linkData);
|
|
24062
24111
|
linksToResolve.push(linkData);
|
|
24063
24112
|
}
|
|
24064
24113
|
});
|
|
24065
24114
|
if (linksToResolve.length > 0) {
|
|
24066
|
-
console.log("🚀 Processing", linksToResolve.length, "new link(s)");
|
|
24067
24115
|
queueMicrotask(() => {
|
|
24068
24116
|
linksToResolve.forEach((link) => {
|
|
24069
24117
|
resolveLinkAndHandlePreview(link, options, singlePreviewMode, pluginState);
|
|
24070
24118
|
});
|
|
24071
24119
|
});
|
|
24072
|
-
} else {
|
|
24073
|
-
console.log("✓ No new links to process");
|
|
24074
24120
|
}
|
|
24075
|
-
|
|
24121
|
+
if (syncTr && uidTr) {
|
|
24122
|
+
try {
|
|
24123
|
+
uidTr.steps.forEach((step, i) => {
|
|
24124
|
+
if (step && syncTr) {
|
|
24125
|
+
syncTr.step(step);
|
|
24126
|
+
const map = uidTr.mapping.maps[i];
|
|
24127
|
+
if (map) {
|
|
24128
|
+
syncTr.mapping.appendMap(map);
|
|
24129
|
+
}
|
|
24130
|
+
}
|
|
24131
|
+
});
|
|
24132
|
+
return syncTr;
|
|
24133
|
+
} catch (err) {
|
|
24134
|
+
return syncTr;
|
|
24135
|
+
}
|
|
24136
|
+
}
|
|
24137
|
+
return syncTr ?? uidTr ?? null;
|
|
24076
24138
|
}
|
|
24077
24139
|
});
|
|
24078
24140
|
}
|
|
@@ -24168,7 +24230,6 @@ const CustomLink = Link$1.extend({
|
|
|
24168
24230
|
this?.options?.api?.resolveUrl(normalizeUrl(href))?.then((metadata) => {
|
|
24169
24231
|
if (metadata) {
|
|
24170
24232
|
const previewPayload = convertLinkMetaToPreviewItem(metadata);
|
|
24171
|
-
console.log({ href, text: text2 });
|
|
24172
24233
|
editor?.chain()?.updateLinkByUid(uid, { href, text: text2, previewPayload })?.updateLinkPreviewByUid(uid, {
|
|
24173
24234
|
// Now using correct UID
|
|
24174
24235
|
loading: false,
|
|
@@ -24227,7 +24288,6 @@ const CustomLink = Link$1.extend({
|
|
|
24227
24288
|
if (attrs.href) {
|
|
24228
24289
|
queueMicrotask(() => {
|
|
24229
24290
|
this.options.api?.resolveUrl(normalizeUrl(attrs.href))?.then((metadata) => {
|
|
24230
|
-
console.log({ metadata });
|
|
24231
24291
|
if (metadata) {
|
|
24232
24292
|
const previewPayload = convertLinkMetaToPreviewItem(metadata);
|
|
24233
24293
|
let linkPreviewExists = false;
|
|
@@ -24256,7 +24316,6 @@ const CustomLink = Link$1.extend({
|
|
|
24256
24316
|
editor.commands.deleteLinkPreviewByUid(uid);
|
|
24257
24317
|
}
|
|
24258
24318
|
}).catch((err) => {
|
|
24259
|
-
console.log("LINK UPDATE ERR::", { err });
|
|
24260
24319
|
editor.commands.deleteLinkPreviewByUid(uid);
|
|
24261
24320
|
});
|
|
24262
24321
|
});
|
|
@@ -24336,7 +24395,6 @@ const IframeView = ({
|
|
|
24336
24395
|
setPreviewData(previewPayload);
|
|
24337
24396
|
updateAttributes({ previewPayload });
|
|
24338
24397
|
}).catch((error) => {
|
|
24339
|
-
console.error("Failed to fetch preview:", error);
|
|
24340
24398
|
}).finally(() => {
|
|
24341
24399
|
});
|
|
24342
24400
|
}
|
|
@@ -24581,7 +24639,6 @@ const _createTrustedTypesPolicy = function _createTrustedTypesPolicy2(trustedTyp
|
|
|
24581
24639
|
}
|
|
24582
24640
|
});
|
|
24583
24641
|
} catch (_) {
|
|
24584
|
-
console.warn("TrustedTypes policy " + policyName + " could not be created.");
|
|
24585
24642
|
return null;
|
|
24586
24643
|
}
|
|
24587
24644
|
};
|
|
@@ -25418,7 +25475,6 @@ const configureDOMPurify = () => {
|
|
|
25418
25475
|
const element = node;
|
|
25419
25476
|
const src = element.getAttribute("src") || "";
|
|
25420
25477
|
if (!isAllowedDomain(src)) {
|
|
25421
|
-
console.warn("🚨 Blocked iframe from non-allowed domain:", src);
|
|
25422
25478
|
node.parentNode?.removeChild(node);
|
|
25423
25479
|
}
|
|
25424
25480
|
}
|
|
@@ -25430,7 +25486,6 @@ function sanitizeIframeHTML(html2) {
|
|
|
25430
25486
|
const config = configureDOMPurify();
|
|
25431
25487
|
const cleaned = purify.sanitize(html2, config);
|
|
25432
25488
|
if (!cleaned.includes("<iframe")) {
|
|
25433
|
-
console.warn("⚠️ No valid iframe found after sanitization");
|
|
25434
25489
|
return null;
|
|
25435
25490
|
}
|
|
25436
25491
|
const match = cleaned.match(/<iframe[^>]*src=["']([^"']+)["']/i);
|
|
@@ -25442,7 +25497,6 @@ function sanitizeIframeHTML(html2) {
|
|
|
25442
25497
|
}
|
|
25443
25498
|
return match[1];
|
|
25444
25499
|
} catch (error) {
|
|
25445
|
-
console.error("🚨 Error sanitizing iframe:", error);
|
|
25446
25500
|
return null;
|
|
25447
25501
|
} finally {
|
|
25448
25502
|
purify.removeAllHooks();
|
|
@@ -25480,7 +25534,6 @@ const createFinder = (regex) => {
|
|
|
25480
25534
|
match
|
|
25481
25535
|
});
|
|
25482
25536
|
}
|
|
25483
|
-
console.log({ match, matches });
|
|
25484
25537
|
return matches.length > 0 ? matches : null;
|
|
25485
25538
|
};
|
|
25486
25539
|
};
|
|
@@ -25532,11 +25585,9 @@ const Iframe = Node$1.create({
|
|
|
25532
25585
|
const iframeHTML = match[0];
|
|
25533
25586
|
const safeSrc = sanitizeIframeHTML(iframeHTML);
|
|
25534
25587
|
if (!safeSrc) {
|
|
25535
|
-
console.warn("🚨 Blocked unsafe iframe paste");
|
|
25536
25588
|
toast.error("🚨 Your pasted iframe is not safe to render");
|
|
25537
25589
|
return;
|
|
25538
25590
|
}
|
|
25539
|
-
console.log("✅ Safe iframe URL validated:", safeSrc);
|
|
25540
25591
|
const node = this.type.create({ src: safeSrc, previewPayload: null });
|
|
25541
25592
|
state.tr.replaceRangeWith(range.from, range.to, node);
|
|
25542
25593
|
}
|
|
@@ -25547,7 +25598,6 @@ const Iframe = Node$1.create({
|
|
|
25547
25598
|
handler: ({ state, range, match }) => {
|
|
25548
25599
|
const fullUrl = match[0];
|
|
25549
25600
|
const embedUrl = getEmbedUrl(fullUrl);
|
|
25550
|
-
console.log({ match, fullUrl, embedUrl });
|
|
25551
25601
|
if (!embedUrl) return;
|
|
25552
25602
|
const node = this.type.create({ src: embedUrl });
|
|
25553
25603
|
state.tr.replaceRangeWith(range.from, range.to, node);
|
|
@@ -25593,10 +25643,9 @@ const handleUrlWithoutSelection = (editor, url, event, autoDetectMedia) => {
|
|
|
25593
25643
|
mediaType: MediaItemType.MEDIA_ITEM
|
|
25594
25644
|
});
|
|
25595
25645
|
}).catch(
|
|
25596
|
-
(e) =>
|
|
25646
|
+
(e) => void 0
|
|
25597
25647
|
);
|
|
25598
25648
|
}
|
|
25599
|
-
console.log("[SmartLinkPaste] Inserting as link node");
|
|
25600
25649
|
editor.chain().focus().insertLink({ href: normalizedUrl, text: url }).run();
|
|
25601
25650
|
return true;
|
|
25602
25651
|
};
|
|
@@ -25618,7 +25667,6 @@ const createPasteHandler = (editor, options) => {
|
|
|
25618
25667
|
return false;
|
|
25619
25668
|
}
|
|
25620
25669
|
const trimmedText = pasteText.trim();
|
|
25621
|
-
console.log("[SmartLinkPaste] Valid URL detected:", isEmbeddableUrl(trimmedText));
|
|
25622
25670
|
if (isEmbeddableUrl(trimmedText) && options?.autoEmbed) {
|
|
25623
25671
|
event.preventDefault();
|
|
25624
25672
|
return false;
|
|
@@ -25635,7 +25683,6 @@ const createPasteHandler = (editor, options) => {
|
|
|
25635
25683
|
options?.autoDetectMedia ?? true
|
|
25636
25684
|
);
|
|
25637
25685
|
} catch (error) {
|
|
25638
|
-
console.error("[SmartLinkPaste] Error:", error);
|
|
25639
25686
|
return false;
|
|
25640
25687
|
}
|
|
25641
25688
|
};
|
|
@@ -25647,10 +25694,8 @@ const createTransformHandler = (editor) => {
|
|
|
25647
25694
|
return slice;
|
|
25648
25695
|
}
|
|
25649
25696
|
try {
|
|
25650
|
-
console.log("[SmartLinkPaste] Transforming inline URLs in pasted content");
|
|
25651
25697
|
return transformUrlsInSlice(editor, slice);
|
|
25652
25698
|
} catch (error) {
|
|
25653
|
-
console.error("[SmartLinkPaste] Transform error:", error);
|
|
25654
25699
|
return slice;
|
|
25655
25700
|
}
|
|
25656
25701
|
};
|
|
@@ -25757,7 +25802,6 @@ const SmartMediaUpload = Extension.create({
|
|
|
25757
25802
|
const uid = v4();
|
|
25758
25803
|
const options = this.options;
|
|
25759
25804
|
if (!options.api) {
|
|
25760
|
-
console.error("API instance not provided to SmartMediaUpload");
|
|
25761
25805
|
return false;
|
|
25762
25806
|
}
|
|
25763
25807
|
if (isFileOrBlob(source)) {
|
|
@@ -25767,7 +25811,6 @@ const SmartMediaUpload = Extension.create({
|
|
|
25767
25811
|
options.allowedFileTypes
|
|
25768
25812
|
);
|
|
25769
25813
|
if (!validation.valid) {
|
|
25770
|
-
console.error("File validation failed:", validation.error);
|
|
25771
25814
|
options.onUploadError?.(uid, new Error(validation.error));
|
|
25772
25815
|
return false;
|
|
25773
25816
|
}
|
|
@@ -25851,7 +25894,6 @@ const SmartMediaUpload = Extension.create({
|
|
|
25851
25894
|
} else editor.commands.deleteMediaByUid(item.uid);
|
|
25852
25895
|
options.onUploadComplete?.(item.uid, hostedUrl);
|
|
25853
25896
|
} catch (error) {
|
|
25854
|
-
console.error("Upload failed:", error);
|
|
25855
25897
|
const blobUrl = this.storage.blobUrls.get(item.uid);
|
|
25856
25898
|
if (blobUrl) {
|
|
25857
25899
|
URL.revokeObjectURL(blobUrl);
|
|
@@ -25863,7 +25905,7 @@ const SmartMediaUpload = Extension.create({
|
|
|
25863
25905
|
this.storage.activeUploads--;
|
|
25864
25906
|
this.storage.processUploadQueue(editor);
|
|
25865
25907
|
}
|
|
25866
|
-
})().catch((err) =>
|
|
25908
|
+
})().catch((err) => void 0);
|
|
25867
25909
|
if (this.storage.uploadQueue.length > 0) {
|
|
25868
25910
|
this.storage.processUploadQueue(editor);
|
|
25869
25911
|
}
|
|
@@ -28563,7 +28605,6 @@ function getSuggestionOptions({
|
|
|
28563
28605
|
const text2 = editor.getText();
|
|
28564
28606
|
const trimmed = text2?.replace(WHITESPACE_REGEX, " ")?.trim();
|
|
28565
28607
|
const matchStartPosition = trimmed?.lastIndexOf(char);
|
|
28566
|
-
console.log({ matchStartPosition });
|
|
28567
28608
|
const nodeAfter = editor.view.state.selection.$to.nodeAfter;
|
|
28568
28609
|
const overrideSpace = nodeAfter?.text?.startsWith(" ");
|
|
28569
28610
|
if (overrideSpace) {
|
|
@@ -28677,7 +28718,6 @@ const Mention = Node$1.create({
|
|
|
28677
28718
|
renderHTML({ node, HTMLAttributes }) {
|
|
28678
28719
|
const suggestion = getSuggestionFromChar(this, node.attrs.mentionSuggestionChar);
|
|
28679
28720
|
if (this.options.renderLabel !== void 0) {
|
|
28680
|
-
console.warn("renderLabel is deprecated use renderText and renderHTML instead");
|
|
28681
28721
|
return [
|
|
28682
28722
|
"span",
|
|
28683
28723
|
mergeAttributes({ "data-type": this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
|
@@ -28717,7 +28757,6 @@ const Mention = Node$1.create({
|
|
|
28717
28757
|
suggestion: getSuggestionFromChar(this, node.attrs.mentionSuggestionChar)
|
|
28718
28758
|
};
|
|
28719
28759
|
if (this.options.renderLabel !== void 0) {
|
|
28720
|
-
console.warn("renderLabel is deprecated use renderText and renderHTML instead");
|
|
28721
28760
|
return this.options.renderLabel(args);
|
|
28722
28761
|
}
|
|
28723
28762
|
return this.options.renderText(args);
|
|
@@ -29706,11 +29745,9 @@ const mentionService = (api, mfs, store) => {
|
|
|
29706
29745
|
const fetchMentions = async () => {
|
|
29707
29746
|
const params = store.getState().getMentionParams();
|
|
29708
29747
|
if (!params) {
|
|
29709
|
-
console.error("DEBUG MENTION SERVICE::", "No group id or post id has been provided");
|
|
29710
29748
|
return [];
|
|
29711
29749
|
}
|
|
29712
29750
|
const { groupId, postId } = params;
|
|
29713
|
-
console.log({ groupId, postId });
|
|
29714
29751
|
const response = postId ? await mfs.getRecommendationPost(groupId, postId, 0, 999) : await mfs.getRecommendationGroup(groupId, 0, 999);
|
|
29715
29752
|
return response.entries?.filter((item) => Boolean(item?.user_data))?.map(
|
|
29716
29753
|
(item) => ({
|
|
@@ -29729,7 +29766,6 @@ const mentionService = (api, mfs, store) => {
|
|
|
29729
29766
|
const { selectedGroupId, groupId } = store.getState();
|
|
29730
29767
|
const activeGroupId = selectedGroupId ?? groupId;
|
|
29731
29768
|
if (!activeGroupId) {
|
|
29732
|
-
console.warn("DEBUG HASHTAG SERVICE::", "No active group selected or provided");
|
|
29733
29769
|
return [];
|
|
29734
29770
|
}
|
|
29735
29771
|
const response = await api.fetchGroupConversations(999, 0);
|
|
@@ -29931,8 +29967,8 @@ const LinkPreviewExtended = ({
|
|
|
29931
29967
|
title,
|
|
29932
29968
|
description,
|
|
29933
29969
|
image,
|
|
29934
|
-
domain
|
|
29935
|
-
|
|
29970
|
+
domain,
|
|
29971
|
+
onClickDelete
|
|
29936
29972
|
}) => {
|
|
29937
29973
|
const safeDomain = useMemo(() => {
|
|
29938
29974
|
try {
|
|
@@ -29941,6 +29977,11 @@ const LinkPreviewExtended = ({
|
|
|
29941
29977
|
return "unknown";
|
|
29942
29978
|
}
|
|
29943
29979
|
}, [href, domain]);
|
|
29980
|
+
const handleDelete = (e) => {
|
|
29981
|
+
e.preventDefault();
|
|
29982
|
+
e.stopPropagation();
|
|
29983
|
+
onClickDelete();
|
|
29984
|
+
};
|
|
29944
29985
|
return /* @__PURE__ */ jsxs(
|
|
29945
29986
|
"div",
|
|
29946
29987
|
{
|
|
@@ -29949,18 +29990,32 @@ const LinkPreviewExtended = ({
|
|
|
29949
29990
|
selected ? "ring-2 ring-blue-500 ring-offset-2 rounded-lg" : ""
|
|
29950
29991
|
),
|
|
29951
29992
|
children: [
|
|
29952
|
-
/* @__PURE__ */
|
|
29953
|
-
|
|
29954
|
-
|
|
29955
|
-
|
|
29956
|
-
|
|
29957
|
-
|
|
29958
|
-
|
|
29959
|
-
/* @__PURE__ */
|
|
29960
|
-
|
|
29961
|
-
|
|
29962
|
-
|
|
29963
|
-
|
|
29993
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 absolute z-50 right-3 top-3", children: [
|
|
29994
|
+
/* @__PURE__ */ jsx(
|
|
29995
|
+
ToolbarButton,
|
|
29996
|
+
{
|
|
29997
|
+
asChild: true,
|
|
29998
|
+
tooltip: "Visit Link",
|
|
29999
|
+
className: "cursor-pointer backdrop-blur-2xl size-6 shadow-none group-hover:bg-accent/70 group-hover:text-accent-foreground text-primary-send",
|
|
30000
|
+
children: /* @__PURE__ */ jsxs("span", { className: "relative", children: [
|
|
30001
|
+
/* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noopener noreferrer", className: "absolute inset-0" }),
|
|
30002
|
+
/* @__PURE__ */ jsx(ExternalLink, {})
|
|
30003
|
+
] })
|
|
30004
|
+
}
|
|
30005
|
+
),
|
|
30006
|
+
/* @__PURE__ */ jsx(
|
|
30007
|
+
ToolbarButton,
|
|
30008
|
+
{
|
|
30009
|
+
tooltip: "Remove Link Preview",
|
|
30010
|
+
onClick: handleDelete,
|
|
30011
|
+
"aria-label": "Delete link preview",
|
|
30012
|
+
type: "button",
|
|
30013
|
+
size: "icon",
|
|
30014
|
+
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",
|
|
30015
|
+
children: /* @__PURE__ */ jsx(Trash2, {})
|
|
30016
|
+
}
|
|
30017
|
+
)
|
|
30018
|
+
] }),
|
|
29964
30019
|
/* @__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
30020
|
/* @__PURE__ */ jsx("div", { className: "relative h-80 w-full shrink-0 overflow-hidden bg-muted border-b", children: /* @__PURE__ */ jsx(
|
|
29966
30021
|
"img",
|
|
@@ -30081,7 +30136,6 @@ const LinkPreview = Node$1.create({
|
|
|
30081
30136
|
},
|
|
30082
30137
|
renderHTML({ node }) {
|
|
30083
30138
|
const { href, uid, title, description, image, domain } = node.attrs;
|
|
30084
|
-
console.log("INSIDE RENDER HTML::", { href, image });
|
|
30085
30139
|
if (!href) return ["div", {}];
|
|
30086
30140
|
const content = [
|
|
30087
30141
|
// Link overlay
|
|
@@ -30216,11 +30270,6 @@ const MediaGroupView = ({ node, editor }) => {
|
|
|
30216
30270
|
editor.commands.deleteMediaByUid(uid);
|
|
30217
30271
|
};
|
|
30218
30272
|
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
30273
|
return /* @__PURE__ */ jsx(
|
|
30225
30274
|
NodeViewWrapper,
|
|
30226
30275
|
{
|
|
@@ -30322,14 +30371,12 @@ const createMediaModePlugin = () => {
|
|
|
30322
30371
|
child.marks.forEach((mark) => {
|
|
30323
30372
|
if (mark.type.name === "customLink" && mark.attrs.previewPayload) {
|
|
30324
30373
|
lastLinkPreviewData = mark.attrs.previewPayload;
|
|
30325
|
-
console.log("Found link with previewPayload:", lastLinkPreviewData);
|
|
30326
30374
|
}
|
|
30327
30375
|
});
|
|
30328
30376
|
}
|
|
30329
30377
|
});
|
|
30330
30378
|
}
|
|
30331
30379
|
});
|
|
30332
|
-
console.log("Cleanup check:", { modified, hasMediaGroup, lastLinkPreviewData });
|
|
30333
30380
|
if (modified && hasMediaGroup && lastLinkPreviewData) {
|
|
30334
30381
|
let hasLinkPreview = false;
|
|
30335
30382
|
tr.doc.forEach((node) => {
|
|
@@ -30337,10 +30384,6 @@ const createMediaModePlugin = () => {
|
|
|
30337
30384
|
hasLinkPreview = true;
|
|
30338
30385
|
}
|
|
30339
30386
|
});
|
|
30340
|
-
console.log("Creating linkPreview:", {
|
|
30341
|
-
hasLinkPreview,
|
|
30342
|
-
schemaHasLinkPreview: !!newState.schema.nodes.linkPreview
|
|
30343
|
-
});
|
|
30344
30387
|
if (!hasLinkPreview && newState.schema.nodes.linkPreview) {
|
|
30345
30388
|
const preview = lastLinkPreviewData;
|
|
30346
30389
|
const linkPreviewNode = newState.schema.nodes.linkPreview.create({
|
|
@@ -30351,7 +30394,6 @@ const createMediaModePlugin = () => {
|
|
|
30351
30394
|
image: preview.linkImage?.url ?? "",
|
|
30352
30395
|
variant: LinkPreviewType.Extended
|
|
30353
30396
|
});
|
|
30354
|
-
console.log("Inserting linkPreview node:", { lastLinkPreviewData, linkPreviewNode });
|
|
30355
30397
|
tr.insert(tr.doc.content.size, linkPreviewNode);
|
|
30356
30398
|
modified = true;
|
|
30357
30399
|
}
|
|
@@ -30411,7 +30453,6 @@ const createMediaModePlugin = () => {
|
|
|
30411
30453
|
}
|
|
30412
30454
|
const mediaNodes = updatedTopLevelMedia.map((m) => m.node);
|
|
30413
30455
|
if (mediaNodes.some((n) => !n || n.type.name !== "media")) {
|
|
30414
|
-
console.warn("Invalid media nodes detected, skipping group creation");
|
|
30415
30456
|
return null;
|
|
30416
30457
|
}
|
|
30417
30458
|
const mediaGroup = newState.schema.nodes.mediaGroup.create({}, mediaNodes);
|
|
@@ -30429,7 +30470,6 @@ const createMediaModePlugin = () => {
|
|
|
30429
30470
|
const $pos = tr.doc.resolve(endPos);
|
|
30430
30471
|
tr.setSelection(TextSelection$1.near($pos));
|
|
30431
30472
|
} catch (e) {
|
|
30432
|
-
console.warn("Could not set selection:", e);
|
|
30433
30473
|
}
|
|
30434
30474
|
}
|
|
30435
30475
|
tr.setMeta("addToHistory", false);
|
|
@@ -30437,7 +30477,6 @@ const createMediaModePlugin = () => {
|
|
|
30437
30477
|
}
|
|
30438
30478
|
return modified ? tr : null;
|
|
30439
30479
|
} catch (error) {
|
|
30440
|
-
console.error("MediaMode plugin error:", error);
|
|
30441
30480
|
return null;
|
|
30442
30481
|
} finally {
|
|
30443
30482
|
isProcessing = false;
|
|
@@ -30579,7 +30618,7 @@ const getMediaExtensions = ({ api, store, user }) => {
|
|
|
30579
30618
|
}),
|
|
30580
30619
|
LinkPreview.configure({
|
|
30581
30620
|
variant: LinkPreviewType.Extended,
|
|
30582
|
-
selectable: false,
|
|
30621
|
+
// selectable: false,
|
|
30583
30622
|
draggable: false
|
|
30584
30623
|
}),
|
|
30585
30624
|
getMentionExtension(core, mfs, store),
|
|
@@ -30723,7 +30762,6 @@ const isLinkMarkWithPayload = (node) => isLinkMark(node) && Boolean(node?.attrs?
|
|
|
30723
30762
|
const getLinkItemsPayload = (json) => {
|
|
30724
30763
|
const links = find(json, (node) => isLinkMarkWithPayload(node));
|
|
30725
30764
|
const items = links?.at(-1);
|
|
30726
|
-
console.log("Link Items Payload::", { items });
|
|
30727
30765
|
return { items };
|
|
30728
30766
|
};
|
|
30729
30767
|
const getPollItemsPayload = (json) => {
|
|
@@ -30737,7 +30775,7 @@ const isValidItem = (item) => {
|
|
|
30737
30775
|
const mediaItem = item;
|
|
30738
30776
|
const isValidLinkItem = linkItem?.linkUrl;
|
|
30739
30777
|
const mediaItemSources = mediaItem?.sources;
|
|
30740
|
-
const isValidMediaItem = mediaItemSources?.original?.url || mediaItemSources?.thumbnail?.url
|
|
30778
|
+
const isValidMediaItem = mediaItemSources?.original?.url || mediaItemSources?.thumbnail?.url;
|
|
30741
30779
|
return Boolean(isValidLinkItem || isValidMediaItem);
|
|
30742
30780
|
};
|
|
30743
30781
|
const generateHtmlPostPayload = ({
|
|
@@ -30757,7 +30795,6 @@ const generateHtmlPostPayload = ({
|
|
|
30757
30795
|
)?.at(0);
|
|
30758
30796
|
const isEmbedOnly = isOnlyContentNode(json, "iframe");
|
|
30759
30797
|
const body = isEmbedOnly ? previewItemEmbed?.attrs?.previewPayload?.linkTitle ?? previewItemEmbed?.attrs?.src ?? "" : secondaryText?.text ?? firstText?.text ?? "";
|
|
30760
|
-
console.log({ firstText });
|
|
30761
30798
|
const items = [
|
|
30762
30799
|
previewItemMedia?.attrs?.payload,
|
|
30763
30800
|
previewItemEmbed?.attrs?.previewPayload,
|
|
@@ -30784,11 +30821,14 @@ const generateMediaPostPayload = ({
|
|
|
30784
30821
|
const { mentionData } = getMentionDataPayload(json);
|
|
30785
30822
|
const { items: mediaItems } = getMediaItemsPayload(json);
|
|
30786
30823
|
const { items: linkItems } = getLinkItemsPayload(json);
|
|
30824
|
+
const items = mediaItems?.length > 0 ? mediaItems : linkItems?.length > 0 ? linkItems : [];
|
|
30825
|
+
if (!body && mediaItems.length === 0)
|
|
30826
|
+
return { error: "Your post is empty. Add text or media to share your thoughts." };
|
|
30787
30827
|
return {
|
|
30788
30828
|
...commons,
|
|
30789
30829
|
type: mediaItems?.length > 0 ? NewPostType.NEW_POST_MEDIA : linkItems?.length > 0 ? NewPostType.NEW_POST_LINK : NewPostType.NEW_POST_MESSAGE,
|
|
30790
30830
|
body,
|
|
30791
|
-
items
|
|
30831
|
+
items,
|
|
30792
30832
|
mentionData,
|
|
30793
30833
|
sendCrossMention
|
|
30794
30834
|
};
|
|
@@ -30808,7 +30848,6 @@ const generatePollPostPayload = ({
|
|
|
30808
30848
|
option_id: index2 === 0 ? item.option_id : v4(),
|
|
30809
30849
|
option_color: OPTION_COLORS[index2 % OPTION_COLORS.length]
|
|
30810
30850
|
})) : items;
|
|
30811
|
-
console.log({ polls });
|
|
30812
30851
|
return {
|
|
30813
30852
|
...commons,
|
|
30814
30853
|
type: NewPostType.NEW_POST_POLL,
|
|
@@ -30845,6 +30884,7 @@ const PostBuilderEditorInstance = ({
|
|
|
30845
30884
|
const [isDragging, setIsDragging] = useState(false);
|
|
30846
30885
|
const { trackPublish } = usePostBuilderAnalytics();
|
|
30847
30886
|
const { clearContent } = usePersistence();
|
|
30887
|
+
useHostAnalyticsBridge();
|
|
30848
30888
|
const handleDragOver = (e) => {
|
|
30849
30889
|
e.preventDefault();
|
|
30850
30890
|
setIsDragging(true);
|
|
@@ -30864,10 +30904,24 @@ const PostBuilderEditorInstance = ({
|
|
|
30864
30904
|
const text2 = editor?.getText();
|
|
30865
30905
|
const payload = generateCreatePostPayload(editorTab, { editor, sendCrossMention });
|
|
30866
30906
|
const isPollType = payload?.type === NewPostType.NEW_POST_POLL;
|
|
30867
|
-
if (
|
|
30907
|
+
if (payload?.error) {
|
|
30908
|
+
toast.error(payload.error);
|
|
30909
|
+
return;
|
|
30910
|
+
}
|
|
30911
|
+
if (!payload?.postId) return;
|
|
30868
30912
|
if (isPollType && payload.items?.length === 0)
|
|
30869
30913
|
return toast.warning(`At least ${POLL_LIMITS.MIN} option is mandatory to create a poll post`);
|
|
30870
|
-
|
|
30914
|
+
if (typeof window !== "undefined") {
|
|
30915
|
+
window.dispatchEvent(
|
|
30916
|
+
new CustomEvent(PostBuilderEvents.POST_PUBLISH_ATTEMPTED, {
|
|
30917
|
+
detail: {
|
|
30918
|
+
postId: payload.postId,
|
|
30919
|
+
postType: payload.type
|
|
30920
|
+
}
|
|
30921
|
+
})
|
|
30922
|
+
);
|
|
30923
|
+
}
|
|
30924
|
+
trackPublish({ status: "attempted", postId: payload?.postId, postType: payload?.type });
|
|
30871
30925
|
onCreatePost?.({ payload, html: html2, json, text: text2 });
|
|
30872
30926
|
if (!clearOnSuccess) return;
|
|
30873
30927
|
clearContent();
|
|
@@ -31041,7 +31095,6 @@ class SessionManager {
|
|
|
31041
31095
|
}, SESSION_TIMEOUT_MS);
|
|
31042
31096
|
}
|
|
31043
31097
|
endSession(reason) {
|
|
31044
|
-
console.log({ reason });
|
|
31045
31098
|
if (this.inactivityTimer) {
|
|
31046
31099
|
clearTimeout(this.inactivityTimer);
|
|
31047
31100
|
}
|
|
@@ -31102,7 +31155,7 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31102
31155
|
const featureTracker = useRef(new FeatureTracker()).current;
|
|
31103
31156
|
const logEvent = useAnalyticsLogEvent();
|
|
31104
31157
|
const trackEvent = useCallback(
|
|
31105
|
-
(name, properties
|
|
31158
|
+
({ name, properties }) => {
|
|
31106
31159
|
const fullConfig = { ...DEFAULT_CONFIG, ...config };
|
|
31107
31160
|
if (!fullConfig.enabled) return;
|
|
31108
31161
|
sessionManager.updateActivity();
|
|
@@ -31110,30 +31163,32 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31110
31163
|
session_id: sessionManager.getSessionId(),
|
|
31111
31164
|
timestamp: Date.now(),
|
|
31112
31165
|
editor_type: editorTab,
|
|
31113
|
-
...properties
|
|
31166
|
+
...properties ?? {}
|
|
31114
31167
|
};
|
|
31115
|
-
|
|
31116
|
-
|
|
31117
|
-
}
|
|
31118
|
-
if (fullConfig.debug) {
|
|
31119
|
-
console.log("[Analytics]", name, enrichedProperties);
|
|
31120
|
-
}
|
|
31168
|
+
const cleanProps = pickBy(enrichedProperties, (value) => value != null);
|
|
31169
|
+
if (logEvent) logEvent(name, cleanProps);
|
|
31121
31170
|
},
|
|
31122
31171
|
[config, editorTab, logEvent, sessionManager]
|
|
31123
31172
|
);
|
|
31124
31173
|
useEffect(() => {
|
|
31125
31174
|
const sessionId = sessionManager.startSession();
|
|
31126
|
-
trackEvent(
|
|
31127
|
-
|
|
31128
|
-
|
|
31129
|
-
|
|
31175
|
+
trackEvent({
|
|
31176
|
+
name: ANALYTICS_EVENTS.SESSION.STARTED,
|
|
31177
|
+
properties: {
|
|
31178
|
+
session_id: sessionId,
|
|
31179
|
+
timestamp: Date.now(),
|
|
31180
|
+
editor_type: editorTab
|
|
31181
|
+
}
|
|
31130
31182
|
});
|
|
31131
31183
|
const handleUnload = () => {
|
|
31132
|
-
trackEvent(
|
|
31133
|
-
|
|
31134
|
-
|
|
31135
|
-
|
|
31136
|
-
|
|
31184
|
+
trackEvent({
|
|
31185
|
+
name: ANALYTICS_EVENTS.SESSION.COMPLETED,
|
|
31186
|
+
properties: {
|
|
31187
|
+
session_id: sessionManager.getSessionId(),
|
|
31188
|
+
timestamp: Date.now(),
|
|
31189
|
+
editor_type: editorTab,
|
|
31190
|
+
session_duration_ms: sessionManager.getSessionDuration()
|
|
31191
|
+
}
|
|
31137
31192
|
});
|
|
31138
31193
|
};
|
|
31139
31194
|
window.addEventListener("beforeunload", handleUnload);
|
|
@@ -31143,60 +31198,88 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31143
31198
|
};
|
|
31144
31199
|
}, []);
|
|
31145
31200
|
const trackFeature = useCallback(
|
|
31146
|
-
(featureName) => {
|
|
31201
|
+
({ featureName }) => {
|
|
31147
31202
|
const { isFirstUse, usageCount } = featureTracker.trackUsage(featureName);
|
|
31148
|
-
trackEvent(
|
|
31149
|
-
|
|
31150
|
-
|
|
31151
|
-
|
|
31203
|
+
trackEvent({
|
|
31204
|
+
name: isFirstUse ? ANALYTICS_EVENTS.FEATURE.DISCOVERED : ANALYTICS_EVENTS.FEATURE.USED,
|
|
31205
|
+
properties: {
|
|
31206
|
+
feature_name: featureName,
|
|
31207
|
+
is_first_use: isFirstUse,
|
|
31208
|
+
usage_count: usageCount
|
|
31209
|
+
}
|
|
31152
31210
|
});
|
|
31153
31211
|
},
|
|
31154
31212
|
[trackEvent, featureTracker]
|
|
31155
31213
|
);
|
|
31156
31214
|
const trackPublish = useCallback(
|
|
31157
|
-
(status, data) => {
|
|
31215
|
+
({ status, data }) => {
|
|
31158
31216
|
const eventMap = {
|
|
31159
31217
|
attempted: ANALYTICS_EVENTS.PUBLISH.ATTEMPTED,
|
|
31160
31218
|
success: ANALYTICS_EVENTS.PUBLISH.SUCCESS,
|
|
31161
31219
|
failed: ANALYTICS_EVENTS.PUBLISH.FAILED
|
|
31162
31220
|
};
|
|
31163
|
-
|
|
31221
|
+
const properties = {
|
|
31164
31222
|
editor_type: editorTab,
|
|
31165
31223
|
session_duration_ms: sessionManager.getSessionDuration(),
|
|
31166
31224
|
...data
|
|
31225
|
+
};
|
|
31226
|
+
trackEvent({
|
|
31227
|
+
name: eventMap[status],
|
|
31228
|
+
properties
|
|
31167
31229
|
});
|
|
31168
31230
|
sessionManager.endSession("completed");
|
|
31169
31231
|
},
|
|
31170
31232
|
[trackEvent, editorTab, sessionManager]
|
|
31171
31233
|
);
|
|
31172
31234
|
const trackAbandon = useCallback(
|
|
31173
|
-
(
|
|
31174
|
-
|
|
31175
|
-
|
|
31176
|
-
|
|
31177
|
-
|
|
31178
|
-
|
|
31179
|
-
|
|
31235
|
+
({
|
|
31236
|
+
contentLength,
|
|
31237
|
+
hasUnsavedChanges,
|
|
31238
|
+
abandonReason,
|
|
31239
|
+
postType,
|
|
31240
|
+
userHistoryData
|
|
31241
|
+
}) => {
|
|
31242
|
+
trackEvent({
|
|
31243
|
+
name: ANALYTICS_EVENTS.SESSION.ABANDONED,
|
|
31244
|
+
properties: {
|
|
31245
|
+
session_duration_ms: sessionManager.getSessionDuration(),
|
|
31246
|
+
post_type: postType,
|
|
31247
|
+
content_length: contentLength,
|
|
31248
|
+
has_unsaved_changes: hasUnsavedChanges,
|
|
31249
|
+
abandon_reason: abandonReason,
|
|
31250
|
+
// Include user history if provided
|
|
31251
|
+
...userHistoryData && {
|
|
31252
|
+
previous_abandon_count: userHistoryData.previous_abandon_count,
|
|
31253
|
+
previous_publish_count: userHistoryData.previous_publish_count,
|
|
31254
|
+
time_since_last_publish_ms: userHistoryData.time_since_last_publish_ms,
|
|
31255
|
+
is_returning_user: userHistoryData.is_returning_user
|
|
31256
|
+
}
|
|
31257
|
+
}
|
|
31180
31258
|
});
|
|
31181
31259
|
sessionManager.endSession("abandoned");
|
|
31182
31260
|
},
|
|
31183
31261
|
[trackEvent, sessionManager]
|
|
31184
31262
|
);
|
|
31185
31263
|
const trackTabSwitch = useCallback(
|
|
31186
|
-
(oldTab, newTab) => {
|
|
31187
|
-
trackEvent(
|
|
31188
|
-
|
|
31189
|
-
|
|
31190
|
-
|
|
31264
|
+
({ oldTab, newTab }) => {
|
|
31265
|
+
trackEvent({
|
|
31266
|
+
name: ANALYTICS_EVENTS.EDITOR.FOCUSED,
|
|
31267
|
+
properties: {
|
|
31268
|
+
from_tab: oldTab,
|
|
31269
|
+
to_tab: newTab
|
|
31270
|
+
}
|
|
31191
31271
|
});
|
|
31192
31272
|
},
|
|
31193
|
-
[trackEvent
|
|
31273
|
+
[trackEvent]
|
|
31194
31274
|
);
|
|
31195
31275
|
const trackEditorFocus = useCallback(
|
|
31196
|
-
(context) => {
|
|
31197
|
-
trackEvent(
|
|
31198
|
-
|
|
31199
|
-
|
|
31276
|
+
({ context }) => {
|
|
31277
|
+
trackEvent({
|
|
31278
|
+
name: ANALYTICS_EVENTS.EDITOR.FOCUSED,
|
|
31279
|
+
properties: {
|
|
31280
|
+
context,
|
|
31281
|
+
editor_type: editorTab
|
|
31282
|
+
}
|
|
31200
31283
|
});
|
|
31201
31284
|
},
|
|
31202
31285
|
[trackEvent, editorTab]
|
|
@@ -31230,19 +31313,91 @@ function useAnalytics({ editorTab, config }) {
|
|
|
31230
31313
|
]
|
|
31231
31314
|
);
|
|
31232
31315
|
}
|
|
31316
|
+
const STORAGE_KEY = "pb_user_history";
|
|
31317
|
+
class UserHistoryTracker {
|
|
31318
|
+
history;
|
|
31319
|
+
constructor() {
|
|
31320
|
+
this.history = this.loadHistory();
|
|
31321
|
+
}
|
|
31322
|
+
loadHistory() {
|
|
31323
|
+
try {
|
|
31324
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
31325
|
+
if (stored) {
|
|
31326
|
+
return JSON.parse(stored);
|
|
31327
|
+
}
|
|
31328
|
+
} catch (error) {
|
|
31329
|
+
}
|
|
31330
|
+
return {
|
|
31331
|
+
previous_abandon_count: 0,
|
|
31332
|
+
previous_publish_count: 0,
|
|
31333
|
+
last_publish_timestamp: null,
|
|
31334
|
+
last_abandon_timestamp: null,
|
|
31335
|
+
first_session_timestamp: Date.now()
|
|
31336
|
+
};
|
|
31337
|
+
}
|
|
31338
|
+
saveHistory() {
|
|
31339
|
+
try {
|
|
31340
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(this.history));
|
|
31341
|
+
} catch (error) {
|
|
31342
|
+
}
|
|
31343
|
+
}
|
|
31344
|
+
/**
|
|
31345
|
+
* Record a successful publish
|
|
31346
|
+
*/
|
|
31347
|
+
recordPublish() {
|
|
31348
|
+
this.history.previous_publish_count += 1;
|
|
31349
|
+
this.history.last_publish_timestamp = Date.now();
|
|
31350
|
+
this.saveHistory();
|
|
31351
|
+
}
|
|
31352
|
+
/**
|
|
31353
|
+
* Record an abandonment
|
|
31354
|
+
*/
|
|
31355
|
+
recordAbandon() {
|
|
31356
|
+
this.history.previous_abandon_count += 1;
|
|
31357
|
+
this.history.last_abandon_timestamp = Date.now();
|
|
31358
|
+
this.saveHistory();
|
|
31359
|
+
}
|
|
31360
|
+
/**
|
|
31361
|
+
* Get current user history for analytics
|
|
31362
|
+
*/
|
|
31363
|
+
getHistory() {
|
|
31364
|
+
const now2 = Date.now();
|
|
31365
|
+
const daysSinceFirstSession = Math.floor(
|
|
31366
|
+
(now2 - this.history.first_session_timestamp) / (1e3 * 60 * 60 * 24)
|
|
31367
|
+
);
|
|
31368
|
+
return {
|
|
31369
|
+
previous_abandon_count: this.history.previous_abandon_count,
|
|
31370
|
+
previous_publish_count: this.history.previous_publish_count,
|
|
31371
|
+
time_since_last_publish_ms: this.history.last_publish_timestamp ? now2 - this.history.last_publish_timestamp : null,
|
|
31372
|
+
is_returning_user: daysSinceFirstSession > 0.5,
|
|
31373
|
+
days_since_first_session: daysSinceFirstSession
|
|
31374
|
+
};
|
|
31375
|
+
}
|
|
31376
|
+
/**
|
|
31377
|
+
* Clear history (for testing or user request)
|
|
31378
|
+
*/
|
|
31379
|
+
clearHistory() {
|
|
31380
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
31381
|
+
this.history = {
|
|
31382
|
+
previous_abandon_count: 0,
|
|
31383
|
+
previous_publish_count: 0,
|
|
31384
|
+
last_publish_timestamp: null,
|
|
31385
|
+
last_abandon_timestamp: null,
|
|
31386
|
+
first_session_timestamp: Date.now()
|
|
31387
|
+
};
|
|
31388
|
+
}
|
|
31389
|
+
}
|
|
31233
31390
|
function useEditorAnalytics({
|
|
31234
31391
|
editor,
|
|
31235
31392
|
editorType,
|
|
31236
31393
|
context,
|
|
31237
31394
|
idleTimeout = 3e5,
|
|
31238
|
-
// 5 minutes
|
|
31239
31395
|
trackBlur = false
|
|
31240
|
-
// Default: don't track every blur
|
|
31241
31396
|
}) {
|
|
31242
31397
|
const analytics = useAnalytics({
|
|
31243
31398
|
editorTab: editorType,
|
|
31244
31399
|
config: {
|
|
31245
|
-
debug:
|
|
31400
|
+
debug: true,
|
|
31246
31401
|
enabled: true
|
|
31247
31402
|
}
|
|
31248
31403
|
});
|
|
@@ -31250,6 +31405,7 @@ function useEditorAnalytics({
|
|
|
31250
31405
|
const idleTimer = useRef();
|
|
31251
31406
|
const hasFocusedOnce = useRef(false);
|
|
31252
31407
|
const hasAbandonedSession = useRef(false);
|
|
31408
|
+
const userHistory = useRef(new UserHistoryTracker()).current;
|
|
31253
31409
|
const getEditorMetrics = useCallback(() => {
|
|
31254
31410
|
if (!editor) return null;
|
|
31255
31411
|
const json = editor.getJSON();
|
|
@@ -31289,7 +31445,6 @@ function useEditorAnalytics({
|
|
|
31289
31445
|
linkCount,
|
|
31290
31446
|
formattingFeatures: Array.from(formattingFeatures),
|
|
31291
31447
|
hasUnsavedChanges: editor.state.doc.content.size > 2,
|
|
31292
|
-
// Has content beyond empty doc
|
|
31293
31448
|
isEmpty: editor.isEmpty
|
|
31294
31449
|
};
|
|
31295
31450
|
}, [editor, analytics]);
|
|
@@ -31300,16 +31455,29 @@ function useEditorAnalytics({
|
|
|
31300
31455
|
idleTimer.current = setTimeout(() => {
|
|
31301
31456
|
const metrics = getEditorMetrics();
|
|
31302
31457
|
if (metrics && !metrics.isEmpty) {
|
|
31303
|
-
|
|
31458
|
+
const history = userHistory.getHistory();
|
|
31459
|
+
analytics.trackAbandon({
|
|
31460
|
+
contentLength: metrics.characterCount,
|
|
31461
|
+
hasUnsavedChanges: metrics.hasUnsavedChanges,
|
|
31462
|
+
abandonReason: "idle_timeout",
|
|
31463
|
+
postType: void 0,
|
|
31464
|
+
userHistoryData: {
|
|
31465
|
+
previous_abandon_count: history.previous_abandon_count,
|
|
31466
|
+
previous_publish_count: history.previous_publish_count,
|
|
31467
|
+
time_since_last_publish_ms: history.time_since_last_publish_ms,
|
|
31468
|
+
is_returning_user: history.is_returning_user
|
|
31469
|
+
}
|
|
31470
|
+
});
|
|
31471
|
+
userHistory.recordAbandon();
|
|
31304
31472
|
hasAbandonedSession.current = true;
|
|
31305
31473
|
}
|
|
31306
31474
|
}, idleTimeout);
|
|
31307
|
-
}, [editor, idleTimeout, analytics, getEditorMetrics]);
|
|
31475
|
+
}, [editor, idleTimeout, analytics, getEditorMetrics, userHistory]);
|
|
31308
31476
|
useEffect(() => {
|
|
31309
31477
|
if (!editor) return;
|
|
31310
31478
|
const handleFocus = () => {
|
|
31311
31479
|
if (!hasFocusedOnce.current) {
|
|
31312
|
-
analytics.trackEditorFocus(context);
|
|
31480
|
+
analytics.trackEditorFocus({ context });
|
|
31313
31481
|
hasFocusedOnce.current = true;
|
|
31314
31482
|
}
|
|
31315
31483
|
resetIdleTimer();
|
|
@@ -31320,9 +31488,12 @@ function useEditorAnalytics({
|
|
|
31320
31488
|
if (trackBlur) {
|
|
31321
31489
|
const metrics = getEditorMetrics();
|
|
31322
31490
|
if (metrics && !metrics.isEmpty) {
|
|
31323
|
-
analytics.trackEvent(
|
|
31324
|
-
|
|
31325
|
-
|
|
31491
|
+
analytics.trackEvent({
|
|
31492
|
+
name: ANALYTICS_EVENTS.EDITOR.BLURRED,
|
|
31493
|
+
properties: {
|
|
31494
|
+
content_length: metrics.characterCount,
|
|
31495
|
+
session_duration_ms: Date.now() - lastActivity.current
|
|
31496
|
+
}
|
|
31326
31497
|
});
|
|
31327
31498
|
}
|
|
31328
31499
|
}
|
|
@@ -31341,7 +31512,20 @@ function useEditorAnalytics({
|
|
|
31341
31512
|
if (hasAbandonedSession.current) return;
|
|
31342
31513
|
const metrics = getEditorMetrics();
|
|
31343
31514
|
if (metrics && !metrics.isEmpty) {
|
|
31344
|
-
|
|
31515
|
+
const history = userHistory.getHistory();
|
|
31516
|
+
analytics.trackAbandon({
|
|
31517
|
+
contentLength: metrics.characterCount,
|
|
31518
|
+
hasUnsavedChanges: metrics.hasUnsavedChanges,
|
|
31519
|
+
abandonReason: "navigation",
|
|
31520
|
+
postType: void 0,
|
|
31521
|
+
userHistoryData: {
|
|
31522
|
+
previous_abandon_count: history.previous_abandon_count,
|
|
31523
|
+
previous_publish_count: history.previous_publish_count,
|
|
31524
|
+
time_since_last_publish_ms: history.time_since_last_publish_ms,
|
|
31525
|
+
is_returning_user: history.is_returning_user
|
|
31526
|
+
}
|
|
31527
|
+
});
|
|
31528
|
+
userHistory.recordAbandon();
|
|
31345
31529
|
hasAbandonedSession.current = true;
|
|
31346
31530
|
}
|
|
31347
31531
|
};
|
|
@@ -31352,46 +31536,76 @@ function useEditorAnalytics({
|
|
|
31352
31536
|
clearTimeout(idleTimer.current);
|
|
31353
31537
|
}
|
|
31354
31538
|
};
|
|
31355
|
-
}, [editor, analytics, getEditorMetrics]);
|
|
31539
|
+
}, [editor, analytics, getEditorMetrics, userHistory]);
|
|
31356
31540
|
const trackFeature = useCallback(
|
|
31357
|
-
(featureName) => {
|
|
31358
|
-
analytics.trackFeature(featureName);
|
|
31541
|
+
({ featureName }) => {
|
|
31542
|
+
analytics.trackFeature({ featureName });
|
|
31359
31543
|
resetIdleTimer();
|
|
31360
31544
|
},
|
|
31361
31545
|
[analytics, resetIdleTimer]
|
|
31362
31546
|
);
|
|
31363
31547
|
const trackPublish = useCallback(
|
|
31364
|
-
(status, failureReason) => {
|
|
31548
|
+
({ sessionId, groupId, postId, status, failureReason, postType }) => {
|
|
31365
31549
|
const metrics = getEditorMetrics();
|
|
31366
31550
|
if (!metrics) return;
|
|
31367
|
-
|
|
31368
|
-
|
|
31369
|
-
|
|
31370
|
-
|
|
31371
|
-
|
|
31372
|
-
|
|
31373
|
-
|
|
31551
|
+
const history = userHistory.getHistory();
|
|
31552
|
+
analytics.trackPublish({
|
|
31553
|
+
status,
|
|
31554
|
+
data: {
|
|
31555
|
+
...sessionId ? { session_id: sessionId } : {},
|
|
31556
|
+
group_id: groupId,
|
|
31557
|
+
post_id: postId,
|
|
31558
|
+
post_type: postType,
|
|
31559
|
+
word_count: metrics.wordCount,
|
|
31560
|
+
character_count: metrics.characterCount,
|
|
31561
|
+
media_count: metrics.mediaCount,
|
|
31562
|
+
link_count: metrics.linkCount,
|
|
31563
|
+
formatting_features: metrics.formattingFeatures,
|
|
31564
|
+
failure_reason: failureReason,
|
|
31565
|
+
// Include user history
|
|
31566
|
+
previous_abandon_count: history.previous_abandon_count,
|
|
31567
|
+
previous_publish_count: history.previous_publish_count,
|
|
31568
|
+
time_since_last_publish_ms: history.time_since_last_publish_ms,
|
|
31569
|
+
is_returning_user: history.is_returning_user
|
|
31570
|
+
}
|
|
31374
31571
|
});
|
|
31375
31572
|
if (status === "success") {
|
|
31573
|
+
userHistory.recordPublish();
|
|
31376
31574
|
hasAbandonedSession.current = true;
|
|
31377
31575
|
}
|
|
31378
31576
|
},
|
|
31379
|
-
[analytics, getEditorMetrics]
|
|
31577
|
+
[analytics, getEditorMetrics, userHistory]
|
|
31380
31578
|
);
|
|
31381
31579
|
const trackExplicitAbandon = useCallback(() => {
|
|
31382
31580
|
if (hasAbandonedSession.current) return;
|
|
31383
31581
|
const metrics = getEditorMetrics();
|
|
31384
31582
|
if (metrics && !metrics.isEmpty) {
|
|
31385
|
-
|
|
31583
|
+
const history = userHistory.getHistory();
|
|
31584
|
+
analytics.trackAbandon({
|
|
31585
|
+
contentLength: metrics.characterCount,
|
|
31586
|
+
hasUnsavedChanges: metrics.hasUnsavedChanges,
|
|
31587
|
+
abandonReason: "user_closed",
|
|
31588
|
+
postType: void 0,
|
|
31589
|
+
userHistoryData: {
|
|
31590
|
+
previous_abandon_count: history.previous_abandon_count,
|
|
31591
|
+
previous_publish_count: history.previous_publish_count,
|
|
31592
|
+
time_since_last_publish_ms: history.time_since_last_publish_ms,
|
|
31593
|
+
is_returning_user: history.is_returning_user
|
|
31594
|
+
}
|
|
31595
|
+
});
|
|
31596
|
+
userHistory.recordAbandon();
|
|
31386
31597
|
hasAbandonedSession.current = true;
|
|
31387
31598
|
}
|
|
31388
|
-
}, [analytics, getEditorMetrics]);
|
|
31599
|
+
}, [analytics, getEditorMetrics, userHistory]);
|
|
31389
31600
|
return {
|
|
31390
31601
|
trackFeature,
|
|
31391
31602
|
trackPublish,
|
|
31392
31603
|
trackExplicitAbandon,
|
|
31393
31604
|
trackTabSwitch: analytics.trackTabSwitch,
|
|
31394
|
-
getEditorMetrics
|
|
31605
|
+
getEditorMetrics,
|
|
31606
|
+
// Expose user history for debugging
|
|
31607
|
+
getUserHistory: () => userHistory.getHistory(),
|
|
31608
|
+
currentSessionId: analytics.getSessionId()
|
|
31395
31609
|
};
|
|
31396
31610
|
}
|
|
31397
31611
|
const PostBuilderAnalyticsProvider = ({
|
|
@@ -31457,58 +31671,68 @@ const PostBuilderEditor = ({
|
|
|
31457
31671
|
isSubmitting,
|
|
31458
31672
|
clearOnSuccess
|
|
31459
31673
|
}
|
|
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
|
-
) }),
|
|
31674
|
+
) : /* @__PURE__ */ jsxs("div", { className: "prose-blockquote: flex-1 flex flex-col space-y-3 max-w-full max-h-[calc(100dvh-7rem)]", children: [
|
|
31675
|
+
!hideGroupSelector && /* @__PURE__ */ jsx(GroupSelector, { user, store }),
|
|
31676
|
+
/* @__PURE__ */ jsx(
|
|
31677
|
+
PostBuilderEditorInstance,
|
|
31678
|
+
{
|
|
31679
|
+
editor,
|
|
31680
|
+
actions,
|
|
31681
|
+
editorTab,
|
|
31682
|
+
onSwitchEditor: setEditorTab,
|
|
31683
|
+
isSubmitting,
|
|
31684
|
+
onCreatePost,
|
|
31685
|
+
clearOnSuccess
|
|
31686
|
+
}
|
|
31687
|
+
)
|
|
31688
|
+
] }) }),
|
|
31506
31689
|
/* @__PURE__ */ jsx(Toaster2, { position: "top-center" })
|
|
31507
31690
|
] })
|
|
31508
31691
|
}
|
|
31509
31692
|
);
|
|
31510
31693
|
};
|
|
31694
|
+
const PostBuilderProvider = ({
|
|
31695
|
+
children,
|
|
31696
|
+
apiBaseURL,
|
|
31697
|
+
authToken,
|
|
31698
|
+
toI18N,
|
|
31699
|
+
i18nKeys,
|
|
31700
|
+
logEvent
|
|
31701
|
+
}) => {
|
|
31702
|
+
const t = useCallback(
|
|
31703
|
+
(key, fallback) => {
|
|
31704
|
+
const message = toI18N(i18nKeys[key]);
|
|
31705
|
+
if (message) return message;
|
|
31706
|
+
return fallback || key;
|
|
31707
|
+
},
|
|
31708
|
+
[toI18N, i18nKeys]
|
|
31709
|
+
);
|
|
31710
|
+
const api = useMemo(() => {
|
|
31711
|
+
const core = new CoreApi(apiBaseURL.core, authToken, toI18N);
|
|
31712
|
+
const mfs = new MFSApi(apiBaseURL.mfs, authToken, toI18N);
|
|
31713
|
+
const fileStore = new FilestoreApi(apiBaseURL.fileStore, authToken, toI18N);
|
|
31714
|
+
core.initApi();
|
|
31715
|
+
mfs.initApi();
|
|
31716
|
+
fileStore.initApi();
|
|
31717
|
+
return {
|
|
31718
|
+
core,
|
|
31719
|
+
mfs,
|
|
31720
|
+
fileStore
|
|
31721
|
+
};
|
|
31722
|
+
}, [authToken, apiBaseURL, toI18N]);
|
|
31723
|
+
const value = useMemo(() => {
|
|
31724
|
+
return {
|
|
31725
|
+
authToken,
|
|
31726
|
+
t,
|
|
31727
|
+
i18nKeys,
|
|
31728
|
+
api,
|
|
31729
|
+
logEvent
|
|
31730
|
+
};
|
|
31731
|
+
}, [authToken, t, i18nKeys, api, logEvent]);
|
|
31732
|
+
return /* @__PURE__ */ jsx(PostBuilderContext.Provider, { value, children });
|
|
31733
|
+
};
|
|
31511
31734
|
export {
|
|
31512
31735
|
PostBuilderEditor,
|
|
31736
|
+
PostBuilderEvents,
|
|
31513
31737
|
PostBuilderProvider
|
|
31514
31738
|
};
|