@blocklet/discuss-kit-ux 2.4.122 → 2.4.124
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/components/chat/chat-input.mjs +0 -1
- package/dist/components/chat/chat-room.mjs +2 -2
- package/dist/components/chat/context.mjs +1 -1
- package/dist/components/default-editor-config-provider.d.ts +3 -1
- package/dist/components/default-editor-config-provider.mjs +4 -3
- package/dist/components/editor/editor.d.ts +2 -4
- package/dist/components/editor/editor.mjs +4 -12
- package/dist/components/editor/index.d.ts +1 -2
- package/dist/components/editor/index.mjs +1 -2
- package/dist/components/editor/lazy-editor.d.ts +1 -1
- package/dist/components/editor/lazy-editor.mjs +1 -1
- package/dist/components/editor/viewer.d.ts +3 -0
- package/dist/components/editor/viewer.mjs +2 -15
- package/dist/components/input/input.mjs +4 -8
- package/dist/components/lexical.d.ts +3 -13
- package/dist/components/lexical.mjs +38 -51
- package/dist/components/point-up/index.mjs +2 -2
- package/dist/components/posts/post-content.mjs +5 -16
- package/dist/components/utils.d.ts +0 -1
- package/dist/components/utils.mjs +0 -36
- package/package.json +3 -3
- package/dist/components/editor/plugins/video-path-fixer-plugin.d.ts +0 -1
- package/dist/components/editor/plugins/video-path-fixer-plugin.mjs +0 -29
- package/dist/components/editor/preview.d.ts +0 -10
- package/dist/components/editor/preview.mjs +0 -31
- package/dist/components/input/image-path-fixer-plugin.d.ts +0 -1
- package/dist/components/input/image-path-fixer-plugin.mjs +0 -29
|
@@ -218,7 +218,6 @@ export function ChatInput({ initialContent, send, onContentChange, onFocusChange
|
|
|
218
218
|
children: /* @__PURE__ */ jsxs(
|
|
219
219
|
LazyEditor,
|
|
220
220
|
{
|
|
221
|
-
enableSaveAreaPlugin: false,
|
|
222
221
|
initialContent: initialContent || "",
|
|
223
222
|
onChange: ({ content: contentStr, isEmpty }) => {
|
|
224
223
|
const value = isEmpty ? "" : contentStr;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useRef } from "react";
|
|
2
|
+
import { lazy, useEffect, useRef } from "react";
|
|
3
3
|
import Box from "@mui/material/Box";
|
|
4
4
|
import Button from "@mui/material/Button";
|
|
5
5
|
import CircularProgress from "@mui/material/CircularProgress";
|
|
@@ -18,8 +18,8 @@ import { Menu } from "../posts/index.mjs";
|
|
|
18
18
|
import { useConfirm } from "../confirm.mjs";
|
|
19
19
|
import { Back } from "../back.mjs";
|
|
20
20
|
import { useChatInWallet } from "./hooks.mjs";
|
|
21
|
-
import { ChatInput } from "./chat-input.mjs";
|
|
22
21
|
import { Avatar } from "../avatars/index.mjs";
|
|
22
|
+
const ChatInput = lazy(() => import("./chat-input.mjs").then((mod) => ({ default: mod.ChatInput })));
|
|
23
23
|
function getLineClamp(count) {
|
|
24
24
|
return {
|
|
25
25
|
display: "-webkit-box",
|
|
@@ -6,7 +6,7 @@ import uniqBy from "lodash/uniqBy";
|
|
|
6
6
|
import orderBy from "lodash/orderBy";
|
|
7
7
|
import { useSessionContext } from "../hooks/index.mjs";
|
|
8
8
|
import { useUnreadNotification } from "./unread-notification.mjs";
|
|
9
|
-
import { getExcerptFromLexicalContent } from "../
|
|
9
|
+
import { getExcerptFromLexicalContent } from "../lexical.mjs";
|
|
10
10
|
const ChatContext = createContext({});
|
|
11
11
|
export const useChatContext = () => useContext(ChatContext);
|
|
12
12
|
const uniqAndSort = (list, order = "asc") => {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { AxiosInstance } from 'axios';
|
|
3
|
-
|
|
3
|
+
import type { EditorConfig } from '@blocklet/editor/lib/config';
|
|
4
|
+
export default function DefaultEditorConfigProvider({ request, children, editorConfig, }: {
|
|
4
5
|
request: AxiosInstance;
|
|
5
6
|
children: React.ReactNode;
|
|
7
|
+
editorConfig?: EditorConfig;
|
|
6
8
|
}): import("react").JSX.Element;
|
|
@@ -11,7 +11,8 @@ const baseURL = joinURL(window.location.origin, discussKitMountPoint || "");
|
|
|
11
11
|
let cachedTemplateList = null;
|
|
12
12
|
export default function DefaultEditorConfigProvider({
|
|
13
13
|
request,
|
|
14
|
-
children
|
|
14
|
+
children,
|
|
15
|
+
editorConfig
|
|
15
16
|
}) {
|
|
16
17
|
const downMd = useMediaQuery((theme) => theme.breakpoints.down("md"));
|
|
17
18
|
const { session } = useSessionContext();
|
|
@@ -101,7 +102,7 @@ export default function DefaultEditorConfigProvider({
|
|
|
101
102
|
alignLeft: true
|
|
102
103
|
}
|
|
103
104
|
};
|
|
104
|
-
return value;
|
|
105
|
-
}, [isAdmin, request, session?.user?.did, downMd]);
|
|
105
|
+
return { ...value, ...editorConfig };
|
|
106
|
+
}, [isAdmin, request, session?.user?.did, downMd, editorConfig]);
|
|
106
107
|
return /* @__PURE__ */ jsx(EditorConfigProvider, { value: config, children });
|
|
107
108
|
}
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { BlockletEditorProps } from '@blocklet/editor';
|
|
3
3
|
import type { EditorState, LexicalEditor } from 'lexical';
|
|
4
|
-
export type OnChangeHandler = ({ content, editorState, editor, isEmpty,
|
|
4
|
+
export type OnChangeHandler = ({ content, editorState, editor, isEmpty, }: {
|
|
5
5
|
content: string;
|
|
6
6
|
editorState: EditorState;
|
|
7
7
|
editor: LexicalEditor;
|
|
8
8
|
isEmpty: boolean;
|
|
9
|
-
getExcerpt: () => string;
|
|
10
9
|
}) => void;
|
|
11
10
|
export interface EditorProps extends Omit<BlockletEditorProps, 'onChange' | 'ref'> {
|
|
12
11
|
initialContent?: string;
|
|
13
12
|
onChange?: OnChangeHandler;
|
|
14
13
|
children?: React.ReactNode;
|
|
15
14
|
onSave?: () => void;
|
|
16
|
-
enableSaveAreaPlugin?: boolean;
|
|
17
15
|
ignoreInitialChange?: boolean;
|
|
18
16
|
}
|
|
19
|
-
export default function Editor({ initialContent, onChange, children, onSave,
|
|
17
|
+
export default function Editor({ initialContent, onChange, children, onSave, ignoreInitialChange, ...rest }: EditorProps): import("react").JSX.Element;
|
|
@@ -2,10 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Box, styled } from "@mui/material";
|
|
3
3
|
import { OnContentChangePlugin } from "@blocklet/editor/lib/ext/OnContentChangePlugin";
|
|
4
4
|
import { CtrlsShortcutPlugin } from "@blocklet/editor/lib/ext/ShortcutPlugin";
|
|
5
|
-
import {
|
|
6
|
-
import { isEmptyContent, inferInitialEditorState, stringify, getExcerptSync } from "../lexical.mjs";
|
|
7
|
-
import ImagePathFixerPlugin from "../input/image-path-fixer-plugin.mjs";
|
|
8
|
-
import { VideoPathFixerPlugin } from "./plugins/video-path-fixer-plugin.mjs";
|
|
5
|
+
import { isEmptyContent, stringify } from "../lexical.mjs";
|
|
9
6
|
import { BlockletEditor } from "./blocklet-editor.mjs";
|
|
10
7
|
const Root = styled(Box)`
|
|
11
8
|
.be-editable,
|
|
@@ -18,26 +15,21 @@ export default function Editor({
|
|
|
18
15
|
onChange,
|
|
19
16
|
children,
|
|
20
17
|
onSave,
|
|
21
|
-
enableSaveAreaPlugin = true,
|
|
22
18
|
ignoreInitialChange = true,
|
|
23
19
|
...rest
|
|
24
20
|
}) {
|
|
25
21
|
const handleChange = async (editorState, editor) => {
|
|
26
|
-
const isEmpty = await isEmptyContent(editorState
|
|
22
|
+
const isEmpty = await isEmptyContent(editorState);
|
|
27
23
|
onChange?.({
|
|
28
24
|
content: isEmpty ? "" : stringify(editorState),
|
|
29
25
|
editorState,
|
|
30
26
|
editor,
|
|
31
|
-
isEmpty
|
|
32
|
-
getExcerpt: () => getExcerptSync(editorState)
|
|
27
|
+
isEmpty
|
|
33
28
|
});
|
|
34
29
|
};
|
|
35
|
-
return /* @__PURE__ */ jsx(Root, { children: /* @__PURE__ */ jsxs(BlockletEditor, { editorState:
|
|
36
|
-
/* @__PURE__ */ jsx(ImagePathFixerPlugin, {}),
|
|
37
|
-
/* @__PURE__ */ jsx(VideoPathFixerPlugin, {}),
|
|
30
|
+
return /* @__PURE__ */ jsx(Root, { children: /* @__PURE__ */ jsxs(BlockletEditor, { editorState: initialContent, ...rest, children: [
|
|
38
31
|
/* @__PURE__ */ jsx(OnContentChangePlugin, { onChange: handleChange, ignoreInitialChange }),
|
|
39
32
|
onSave && /* @__PURE__ */ jsx(CtrlsShortcutPlugin, { callback: onSave }),
|
|
40
|
-
enableSaveAreaPlugin && /* @__PURE__ */ jsx(SafeAreaPlugin, {}),
|
|
41
33
|
children
|
|
42
34
|
] }) });
|
|
43
35
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { LazyEditor } from './lazy-editor';
|
|
2
2
|
export type { OnChangeHandler, EditorProps } from './editor';
|
|
3
|
-
export { EditorPreview } from './preview';
|
|
4
3
|
export { BlockletEditor, useBlockletEditorLoaded } from './blocklet-editor';
|
|
5
4
|
export { BlockletEditorViewer, useBlockletEditorViewerLoaded } from './viewer';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { EditorPreview } from "./preview.mjs";
|
|
1
|
+
export { LazyEditor } from "./lazy-editor.mjs";
|
|
3
2
|
export { BlockletEditor, useBlockletEditorLoaded } from "./blocklet-editor.mjs";
|
|
4
3
|
export { BlockletEditorViewer, useBlockletEditorViewerLoaded } from "./viewer.mjs";
|
|
@@ -3,7 +3,7 @@ import { Suspense } from "react";
|
|
|
3
3
|
import { lazyRetry as lazy } from "@arcblock/ux/lib/Util";
|
|
4
4
|
import { Box, Skeleton } from "@mui/material";
|
|
5
5
|
const Editor = lazy(() => import("./editor.mjs"));
|
|
6
|
-
export
|
|
6
|
+
export function LazyEditor(props) {
|
|
7
7
|
const fallback = /* @__PURE__ */ jsxs(Box, { sx: { px: 3 }, children: [
|
|
8
8
|
/* @__PURE__ */ jsx(Skeleton, {}),
|
|
9
9
|
/* @__PURE__ */ jsx(Skeleton, { width: "80%" }),
|
|
@@ -4,4 +4,7 @@ export interface EditorProps extends Omit<EditorViewerProps, 'editorState'> {
|
|
|
4
4
|
content: string;
|
|
5
5
|
}
|
|
6
6
|
export declare function BlockletEditorViewer({ content, prepend, ...rest }: EditorProps): import("react").JSX.Element;
|
|
7
|
+
export declare namespace BlockletEditorViewer {
|
|
8
|
+
var fallback: import("react").JSX.Element;
|
|
9
|
+
}
|
|
7
10
|
export { useBlockletEditorViewerLoaded };
|
|
@@ -5,9 +5,6 @@ import {
|
|
|
5
5
|
BlockletEditorViewer as InternalBlockletEditorViewer,
|
|
6
6
|
useBlockletEditorViewerLoaded
|
|
7
7
|
} from "@blocklet/editor/lib/blocklet-editor-viewer";
|
|
8
|
-
import { inferInitialEditorState } from "../lexical.mjs";
|
|
9
|
-
import ImagePathFixerPlugin from "../input/image-path-fixer-plugin.mjs";
|
|
10
|
-
import { VideoPathFixerPlugin } from "./plugins/video-path-fixer-plugin.mjs";
|
|
11
8
|
const fallback = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12
9
|
/* @__PURE__ */ jsx(Skeleton, {}),
|
|
13
10
|
/* @__PURE__ */ jsx(Skeleton, { width: "80%" }),
|
|
@@ -15,17 +12,7 @@ const fallback = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
|
15
12
|
/* @__PURE__ */ jsx(Skeleton, { width: "40%" })
|
|
16
13
|
] });
|
|
17
14
|
export function BlockletEditorViewer({ content, prepend, ...rest }) {
|
|
18
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback, children: /* @__PURE__ */ jsx(
|
|
19
|
-
InternalBlockletEditorViewer,
|
|
20
|
-
{
|
|
21
|
-
editorState: inferInitialEditorState(content),
|
|
22
|
-
prepend: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
23
|
-
prepend,
|
|
24
|
-
/* @__PURE__ */ jsx(ImagePathFixerPlugin, {}),
|
|
25
|
-
/* @__PURE__ */ jsx(VideoPathFixerPlugin, {})
|
|
26
|
-
] }),
|
|
27
|
-
...rest
|
|
28
|
-
}
|
|
29
|
-
) });
|
|
15
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback, children: /* @__PURE__ */ jsx(InternalBlockletEditorViewer, { editorState: content, prepend, ...rest }) });
|
|
30
16
|
}
|
|
17
|
+
BlockletEditorViewer.fallback = fallback;
|
|
31
18
|
export { useBlockletEditorViewerLoaded };
|
|
@@ -4,10 +4,8 @@ import { useState, useRef } from "react";
|
|
|
4
4
|
import { Box } from "@mui/material";
|
|
5
5
|
import isNil from "lodash/isNil";
|
|
6
6
|
import { EditorConfigProvider, useEditorConfig } from "@blocklet/editor/lib/config";
|
|
7
|
-
import { isEmptyContent
|
|
7
|
+
import { isEmptyContent } from "../lexical.mjs";
|
|
8
8
|
import ShortcutPlugin from "./shortcut-plugin.mjs";
|
|
9
|
-
import ImagePathFixerPlugin from "./image-path-fixer-plugin.mjs";
|
|
10
|
-
import { VideoPathFixerPlugin } from "../editor/plugins/video-path-fixer-plugin.mjs";
|
|
11
9
|
import AutoClearPlugin from "./auto-clear-plugin.mjs";
|
|
12
10
|
import useMeasure from "../hooks/measure.mjs";
|
|
13
11
|
import { mergeSx } from "../utils.mjs";
|
|
@@ -50,8 +48,8 @@ const Input = ({
|
|
|
50
48
|
sessionStorage.removeItem(`${sessionKey}:title`);
|
|
51
49
|
}
|
|
52
50
|
};
|
|
53
|
-
const handleChange = async (state
|
|
54
|
-
const isEmpty = await isEmptyContent(state
|
|
51
|
+
const handleChange = async (state) => {
|
|
52
|
+
const isEmpty = await isEmptyContent(state);
|
|
55
53
|
if (isEmpty) {
|
|
56
54
|
setContent(null);
|
|
57
55
|
onChange?.(null);
|
|
@@ -112,7 +110,7 @@ const Input = ({
|
|
|
112
110
|
alignLeft: false
|
|
113
111
|
}
|
|
114
112
|
};
|
|
115
|
-
const editorState = draftKey && draftContent && !initialContent ? draftContent :
|
|
113
|
+
const editorState = draftKey && draftContent && !initialContent ? draftContent : initialContent;
|
|
116
114
|
const mergedSx = mergeSx(
|
|
117
115
|
{
|
|
118
116
|
position: "relative",
|
|
@@ -138,8 +136,6 @@ const Input = ({
|
|
|
138
136
|
autoFocus,
|
|
139
137
|
children: [
|
|
140
138
|
!disableCmdEnter && /* @__PURE__ */ jsx(ShortcutPlugin, { shortcut, callback: handleCmdEnterPressed }),
|
|
141
|
-
/* @__PURE__ */ jsx(ImagePathFixerPlugin, {}),
|
|
142
|
-
/* @__PURE__ */ jsx(VideoPathFixerPlugin, {}),
|
|
143
139
|
/* @__PURE__ */ jsx(AutoClearPlugin, { value: content, isChanged: isChanged.current }),
|
|
144
140
|
children,
|
|
145
141
|
renderInnerFooter?.({ submit, content, loading, error, inSmallView })
|
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
import { EditorState
|
|
2
|
-
export declare const
|
|
1
|
+
import type { EditorState } from 'lexical';
|
|
2
|
+
export declare const getExcerptFromLexicalContent: (content: any, size?: number) => string;
|
|
3
3
|
/**
|
|
4
4
|
* 检查 editor 内容是否为空
|
|
5
5
|
* - 从 editor state strcuture 判断是否为空
|
|
6
6
|
* - 检查是否只有 text node, 如果不是说明不为空 (仅输入一张图片的情况)
|
|
7
7
|
* - 检查 text content 空白/空行 的情况 (trim)
|
|
8
8
|
*/
|
|
9
|
-
export declare const isEmptyContent: (editorState: EditorState
|
|
10
|
-
/**
|
|
11
|
-
* 推断 editor 初始 state, 如果是有效的 json string 直接返回, 否则返回一个 function (参考 InitialEditorStateType), 则插一个段落
|
|
12
|
-
* 注意: str 默认值需要为空字符串, 否则如果传入并返回 null, editor placeholder 光标存在位置问题
|
|
13
|
-
*
|
|
14
|
-
* @param str 串行化的 editor state 或普通字符串
|
|
15
|
-
* @returns initial editor state
|
|
16
|
-
*/
|
|
17
|
-
export declare const inferInitialEditorState: (str: string) => string | (() => void);
|
|
18
|
-
export declare const getExcerpt: (editorState: EditorState | null | undefined) => "" | Promise<string>;
|
|
19
|
-
export declare const getExcerptSync: (editorState: EditorState | null | undefined) => string;
|
|
9
|
+
export declare const isEmptyContent: (editorState: EditorState) => boolean;
|
|
20
10
|
export declare const stringify: (editorState: EditorState | null | undefined) => string;
|
|
@@ -1,16 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
function lexicalRootToText(data) {
|
|
2
|
+
let parsedRoot = data;
|
|
3
|
+
if (typeof data === "string") {
|
|
4
|
+
try {
|
|
5
|
+
parsedRoot = JSON.parse(data).root;
|
|
6
|
+
if (typeof parsedRoot !== "object") {
|
|
7
|
+
return data;
|
|
8
|
+
}
|
|
9
|
+
} catch {
|
|
10
|
+
parsedRoot = {};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
let text = "";
|
|
14
|
+
if (parsedRoot?.children) {
|
|
15
|
+
try {
|
|
16
|
+
parsedRoot.children.forEach((e) => {
|
|
17
|
+
if (e.text) {
|
|
18
|
+
text += e.text;
|
|
19
|
+
} else {
|
|
20
|
+
if (e.direction && text !== "") {
|
|
21
|
+
text += "\n";
|
|
22
|
+
}
|
|
23
|
+
text += lexicalRootToText(e);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
} catch (err) {
|
|
27
|
+
console.error(`lexicalRootToText ${err?.toString()}`);
|
|
28
|
+
console.error(err);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return text;
|
|
32
|
+
}
|
|
33
|
+
export const getExcerptFromLexicalContent = (content, size = 150) => {
|
|
34
|
+
const textContent = (lexicalRootToText(content) || "").trim();
|
|
35
|
+
return textContent.length > size ? `${textContent.slice(0, size)}` : textContent;
|
|
12
36
|
};
|
|
13
|
-
export const isEmptyContent = (editorState
|
|
37
|
+
export const isEmptyContent = (editorState) => {
|
|
14
38
|
const data = editorState.toJSON();
|
|
15
39
|
if (data.root.children?.length === 1 && !data.root.children[0].children?.length) {
|
|
16
40
|
return true;
|
|
@@ -24,45 +48,8 @@ export const isEmptyContent = (editorState, editor) => {
|
|
|
24
48
|
if (!textOnly) {
|
|
25
49
|
return false;
|
|
26
50
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
resolve($isRootTextContentEmpty(editor.isComposing(), true));
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
};
|
|
33
|
-
export const inferInitialEditorState = (str) => {
|
|
34
|
-
str = str ?? "";
|
|
35
|
-
if (typeof str === "string" && !tryParseJSONObject(str)) {
|
|
36
|
-
return () => {
|
|
37
|
-
const paragraph = $createParagraphNode();
|
|
38
|
-
const text = $createTextNode(str);
|
|
39
|
-
paragraph.append(text);
|
|
40
|
-
$getRoot().append(paragraph);
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
return str;
|
|
44
|
-
};
|
|
45
|
-
export const getExcerpt = (editorState) => {
|
|
46
|
-
if (!editorState) {
|
|
47
|
-
return "";
|
|
48
|
-
}
|
|
49
|
-
return new Promise((resolve) => {
|
|
50
|
-
editorState.read(() => {
|
|
51
|
-
const root = $getRoot();
|
|
52
|
-
const text = root.getTextContent();
|
|
53
|
-
resolve(text.replace(/\n/g, "").slice(0, 150));
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
};
|
|
57
|
-
export const getExcerptSync = (editorState) => {
|
|
58
|
-
if (!editorState) {
|
|
59
|
-
return "";
|
|
60
|
-
}
|
|
61
|
-
return editorState.read(() => {
|
|
62
|
-
const root = $getRoot();
|
|
63
|
-
const text = root.getTextContent();
|
|
64
|
-
return text.replace(/\n/g, "").slice(0, 150);
|
|
65
|
-
});
|
|
51
|
+
const text = lexicalRootToText(data.root);
|
|
52
|
+
return !text.trim();
|
|
66
53
|
};
|
|
67
54
|
export const stringify = (editorState) => {
|
|
68
55
|
return editorState ? JSON.stringify(editorState) : "";
|
|
@@ -4,7 +4,7 @@ import { createPortal } from "react-dom";
|
|
|
4
4
|
import { useReactive } from "ahooks";
|
|
5
5
|
import Box from "@mui/material/Box";
|
|
6
6
|
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
7
|
-
import
|
|
7
|
+
import { joinURL } from "ufo";
|
|
8
8
|
import LottieComponent from "./lottie-component.mjs";
|
|
9
9
|
import boxAnimation from "./box-animation.json";
|
|
10
10
|
import { getWsClient, useSubscription } from "../../ws.mjs";
|
|
@@ -126,7 +126,7 @@ export function PointUpProvider({ children }) {
|
|
|
126
126
|
Box,
|
|
127
127
|
{
|
|
128
128
|
onClick: () => {
|
|
129
|
-
window.open(
|
|
129
|
+
window.open(joinURL(window.location.origin, pointUpComponent.mountPoint, "my"));
|
|
130
130
|
},
|
|
131
131
|
id,
|
|
132
132
|
sx: {
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Suspense } from "react";
|
|
3
3
|
import CheckboxPlugin from "@blocklet/editor/lib/ext/CheckboxPlugin";
|
|
4
4
|
import { styled } from "@mui/material/styles";
|
|
5
5
|
import Box from "@mui/material/Box";
|
|
6
6
|
import { Skeleton } from "@mui/material";
|
|
7
|
-
import { inferInitialEditorState } from "../lexical.mjs";
|
|
8
7
|
import { ViewMore } from "../view-more.mjs";
|
|
9
8
|
import PostEdit from "../input/post-edit.mjs";
|
|
10
|
-
import ImagePathFixerPlugin from "../input/image-path-fixer-plugin.mjs";
|
|
11
|
-
import { VideoPathFixerPlugin } from "../editor/plugins/video-path-fixer-plugin.mjs";
|
|
12
9
|
import { BlockletEditor } from "../editor/blocklet-editor.mjs";
|
|
13
10
|
const StyledBlockletEditor = styled(BlockletEditor)`
|
|
14
11
|
.editor-scroller {
|
|
@@ -57,14 +54,10 @@ export default function PostContent({
|
|
|
57
54
|
StyledBlockletEditor,
|
|
58
55
|
{
|
|
59
56
|
editable: false,
|
|
60
|
-
editorState:
|
|
57
|
+
editorState: content,
|
|
61
58
|
enableHeadingsIdPlugin,
|
|
62
59
|
onReady,
|
|
63
|
-
prepend:
|
|
64
|
-
/* @__PURE__ */ jsx(ImagePathFixerPlugin, {}),
|
|
65
|
-
/* @__PURE__ */ jsx(VideoPathFixerPlugin, {}),
|
|
66
|
-
editorPrepend
|
|
67
|
-
] }),
|
|
60
|
+
prepend: editorPrepend,
|
|
68
61
|
children: [
|
|
69
62
|
/* @__PURE__ */ jsx(CheckboxPlugin, { send: onSubmit }),
|
|
70
63
|
children
|
|
@@ -76,14 +69,10 @@ export default function PostContent({
|
|
|
76
69
|
StyledBlockletEditor,
|
|
77
70
|
{
|
|
78
71
|
editable: false,
|
|
79
|
-
editorState:
|
|
72
|
+
editorState: content,
|
|
80
73
|
enableHeadingsIdPlugin,
|
|
81
74
|
onReady,
|
|
82
|
-
prepend:
|
|
83
|
-
editorPrepend,
|
|
84
|
-
/* @__PURE__ */ jsx(ImagePathFixerPlugin, {}),
|
|
85
|
-
/* @__PURE__ */ jsx(VideoPathFixerPlugin, {})
|
|
86
|
-
] }),
|
|
75
|
+
prepend: editorPrepend,
|
|
87
76
|
children: [
|
|
88
77
|
/* @__PURE__ */ jsx(CheckboxPlugin, { send: onSubmit }),
|
|
89
78
|
children
|
|
@@ -11,7 +11,6 @@ export declare function tryParseJSONObject(str: string): boolean;
|
|
|
11
11
|
export declare const getPreference: (key: string) => any;
|
|
12
12
|
export declare const getBlockletMountPointInfo: (name: string) => any;
|
|
13
13
|
export declare const blockletExists: (name: string) => boolean;
|
|
14
|
-
export declare const getExcerptFromLexicalContent: (content: any, size?: number) => string;
|
|
15
14
|
export declare const mergeSx: (initial: SystemStyleObject<Theme>, sx?: SxProps<Theme>) => any[];
|
|
16
15
|
export declare const discussKitMountPoint: string | undefined;
|
|
17
16
|
export declare const discussKitApiBaseUrl: string;
|
|
@@ -77,42 +77,6 @@ export const blockletExists = (name) => {
|
|
|
77
77
|
const info = getBlockletMountPointInfo(name);
|
|
78
78
|
return info?.status === "running";
|
|
79
79
|
};
|
|
80
|
-
function lexicalRootToText(data) {
|
|
81
|
-
let parsedRoot = data;
|
|
82
|
-
if (typeof data === "string") {
|
|
83
|
-
try {
|
|
84
|
-
parsedRoot = JSON.parse(data).root;
|
|
85
|
-
if (typeof parsedRoot !== "object") {
|
|
86
|
-
return data;
|
|
87
|
-
}
|
|
88
|
-
} catch {
|
|
89
|
-
parsedRoot = {};
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
let text = "";
|
|
93
|
-
if (parsedRoot?.children) {
|
|
94
|
-
try {
|
|
95
|
-
parsedRoot.children.forEach((e) => {
|
|
96
|
-
if (e.text) {
|
|
97
|
-
text += e.text;
|
|
98
|
-
} else {
|
|
99
|
-
if (e.direction && text !== "") {
|
|
100
|
-
text += "\n";
|
|
101
|
-
}
|
|
102
|
-
text += lexicalRootToText(e);
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
} catch (err) {
|
|
106
|
-
console.error(`lexicalRootToText ${err?.toString()}`);
|
|
107
|
-
console.error(err);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return text;
|
|
111
|
-
}
|
|
112
|
-
export const getExcerptFromLexicalContent = (content, size = 150) => {
|
|
113
|
-
const textContent = (lexicalRootToText(content) || "").trim();
|
|
114
|
-
return textContent.length > size ? `${textContent.slice(0, size)}` : textContent;
|
|
115
|
-
};
|
|
116
80
|
export const mergeSx = (initial, sx) => {
|
|
117
81
|
const mergedSx = [initial, ...Array.isArray(sx) ? sx : [sx]];
|
|
118
82
|
return mergedSx;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/discuss-kit-ux",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.124",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist"
|
|
6
6
|
],
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"unstated-next": "^1.1.0",
|
|
48
48
|
"url-join": "^4.0.1",
|
|
49
49
|
"zustand": "^4.5.5",
|
|
50
|
-
"@blocklet/
|
|
51
|
-
"@blocklet/
|
|
50
|
+
"@blocklet/editor": "2.4.124",
|
|
51
|
+
"@blocklet/labels": "2.4.124"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"@arcblock/did-connect-react": "^3.1.5",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function VideoPathFixerPlugin(): null;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { useLayoutEffect } from "react";
|
|
2
|
-
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
3
|
-
import { VideoNode } from "@blocklet/editor/lib/ext/VideoPlugin/VideoNode";
|
|
4
|
-
import { joinURL } from "ufo";
|
|
5
|
-
import { discussKitUploadsUrl } from "../../utils.mjs";
|
|
6
|
-
const originalExportJSON = VideoNode.prototype.exportJSON;
|
|
7
|
-
const ensureLeadingSlash = (str) => str.startsWith("/") ? str : `/${str}`;
|
|
8
|
-
VideoNode.prototype.exportJSON = function exportJSON() {
|
|
9
|
-
const json = originalExportJSON.call(this);
|
|
10
|
-
if (json.src && json.src.startsWith(discussKitUploadsUrl)) {
|
|
11
|
-
json.src = json.src.replace(discussKitUploadsUrl, "");
|
|
12
|
-
json.src = ensureLeadingSlash(json.src);
|
|
13
|
-
}
|
|
14
|
-
return json;
|
|
15
|
-
};
|
|
16
|
-
function VideoNodeTransform(node) {
|
|
17
|
-
const targetNode = node;
|
|
18
|
-
const src = targetNode.getSrc();
|
|
19
|
-
if (src?.startsWith("/") && !src.startsWith(discussKitUploadsUrl)) {
|
|
20
|
-
targetNode.setSrc(joinURL(discussKitUploadsUrl, src));
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
export function VideoPathFixerPlugin() {
|
|
24
|
-
const [editor] = useLexicalComposerContext();
|
|
25
|
-
useLayoutEffect(() => {
|
|
26
|
-
return editor.registerNodeTransform(VideoNode, VideoNodeTransform);
|
|
27
|
-
}, [editor]);
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
import type { BlockletEditorProps } from '@blocklet/editor';
|
|
3
|
-
export interface EditorProps extends Omit<BlockletEditorProps, 'onChange' | 'ref'> {
|
|
4
|
-
content: string;
|
|
5
|
-
children?: React.ReactNode;
|
|
6
|
-
}
|
|
7
|
-
export declare function EditorPreview({ content, children, prepend, ...rest }: EditorProps): import("react").JSX.Element;
|
|
8
|
-
export declare namespace EditorPreview {
|
|
9
|
-
var fallback: import("react").JSX.Element;
|
|
10
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Suspense } from "react";
|
|
3
|
-
import { Skeleton } from "@mui/material";
|
|
4
|
-
import { inferInitialEditorState } from "../lexical.mjs";
|
|
5
|
-
import ImagePathFixerPlugin from "../input/image-path-fixer-plugin.mjs";
|
|
6
|
-
import { VideoPathFixerPlugin } from "./plugins/video-path-fixer-plugin.mjs";
|
|
7
|
-
import { BlockletEditor } from "./blocklet-editor.mjs";
|
|
8
|
-
const fallback = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9
|
-
/* @__PURE__ */ jsx(Skeleton, {}),
|
|
10
|
-
/* @__PURE__ */ jsx(Skeleton, { width: "80%" }),
|
|
11
|
-
/* @__PURE__ */ jsx(Skeleton, { width: "60%" }),
|
|
12
|
-
/* @__PURE__ */ jsx(Skeleton, { width: "40%" })
|
|
13
|
-
] });
|
|
14
|
-
export function EditorPreview({ content, children, prepend, ...rest }) {
|
|
15
|
-
return /* @__PURE__ */ jsx(Suspense, { fallback, children: /* @__PURE__ */ jsx(
|
|
16
|
-
BlockletEditor,
|
|
17
|
-
{
|
|
18
|
-
editorState: inferInitialEditorState(content),
|
|
19
|
-
editable: false,
|
|
20
|
-
enableHeadingsIdPlugin: true,
|
|
21
|
-
prepend: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22
|
-
prepend,
|
|
23
|
-
/* @__PURE__ */ jsx(ImagePathFixerPlugin, {}),
|
|
24
|
-
/* @__PURE__ */ jsx(VideoPathFixerPlugin, {})
|
|
25
|
-
] }),
|
|
26
|
-
...rest,
|
|
27
|
-
children
|
|
28
|
-
}
|
|
29
|
-
) });
|
|
30
|
-
}
|
|
31
|
-
EditorPreview.fallback = fallback;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function ImagePathFixerPlugin(): null;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { useLayoutEffect } from "react";
|
|
2
|
-
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
3
|
-
import { ImageNode } from "@blocklet/editor/lib/main/nodes/ImageNode";
|
|
4
|
-
import { joinURL } from "ufo";
|
|
5
|
-
import { discussKitUploadsUrl } from "../utils.mjs";
|
|
6
|
-
const originalExportJSON = ImageNode.prototype.exportJSON;
|
|
7
|
-
const ensureLeadingSlash = (str) => str.startsWith("/") ? str : `/${str}`;
|
|
8
|
-
ImageNode.prototype.exportJSON = function exportJSON() {
|
|
9
|
-
const json = originalExportJSON.call(this);
|
|
10
|
-
if (json.src && json.src.startsWith(discussKitUploadsUrl)) {
|
|
11
|
-
json.src = json.src.replace(discussKitUploadsUrl, "");
|
|
12
|
-
json.src = ensureLeadingSlash(json.src);
|
|
13
|
-
}
|
|
14
|
-
return json;
|
|
15
|
-
};
|
|
16
|
-
function imageNodeTransform(node) {
|
|
17
|
-
const targetNode = node;
|
|
18
|
-
const src = targetNode.getSrc();
|
|
19
|
-
if (src?.startsWith("/") && !src.startsWith(discussKitUploadsUrl)) {
|
|
20
|
-
targetNode.setSrc(joinURL(discussKitUploadsUrl, src));
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
export default function ImagePathFixerPlugin() {
|
|
24
|
-
const [editor] = useLexicalComposerContext();
|
|
25
|
-
useLayoutEffect(() => {
|
|
26
|
-
return editor.registerNodeTransform(ImageNode, imageNodeTransform);
|
|
27
|
-
}, [editor]);
|
|
28
|
-
return null;
|
|
29
|
-
}
|