@blocklet/discuss-kit-ux 1.6.63 → 1.6.64

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.
@@ -1,4 +1,4 @@
1
- /// <reference types="react" />
1
+ import React from 'react';
2
2
  import type { Post, Target, CommentAPI } from '../../../types';
3
3
  type Order = 'asc' | 'desc';
4
4
  interface CommentsProviderProps {
@@ -12,6 +12,7 @@ interface CommentsProviderProps {
12
12
  allowCopyLink?: boolean;
13
13
  showProfileCard?: boolean;
14
14
  interactive?: boolean;
15
+ containerRef: React.RefObject<HTMLDivElement>;
15
16
  }
16
17
  interface State {
17
18
  comments: Post[];
@@ -49,7 +50,7 @@ interface CommentsContextValue {
49
50
  reply: CommentAPI['reply'];
50
51
  findById: (id: string) => Post | undefined;
51
52
  }
52
- export declare const CommentsContext: import("react").Context<CommentsContextValue>;
53
+ export declare const CommentsContext: React.Context<CommentsContextValue>;
53
54
  export declare const useCommentsContext: () => CommentsContextValue;
54
- export declare function CommentsProvider({ target, api, flatView, children, order, autoLoadComments, autoCollapse, allowCopyLink, showProfileCard, interactive, }: CommentsProviderProps): import("react/jsx-runtime").JSX.Element;
55
+ export declare function CommentsProvider({ target, api, flatView, children, order, autoLoadComments, autoCollapse, allowCopyLink, showProfileCard, interactive, containerRef, }: CommentsProviderProps): import("react/jsx-runtime").JSX.Element;
55
56
  export {};
@@ -4,7 +4,7 @@ import { OnContentChangePlugin } from "@blocklet/editor/lib/ext/OnContentChangeP
4
4
  import { CtrlsShortcutPlugin } from "@blocklet/editor/lib/ext/ShortcutPlugin";
5
5
  import { SafeAreaPlugin } from "@blocklet/editor/lib/ext/SafeAreaPlugin";
6
6
  import { lazy } from "react";
7
- import { i as inferInitialEditorState, I as ImagePathFixerPlugin, V as VideoPathFixerPlugin, a as isEmptyContent, s as stringify, g as getExcerptSync } from "./index-NFPPoDc-.mjs";
7
+ import { i as inferInitialEditorState, I as ImagePathFixerPlugin, V as VideoPathFixerPlugin, a as isEmptyContent, s as stringify, g as getExcerptSync } from "./index-GBSsS-kJ.mjs";
8
8
  import "@blocklet/labels";
9
9
  import "@mui/material/styles";
10
10
  import "@mui/material/Box";
@@ -19,7 +19,7 @@ import joinUrl from "url-join";
19
19
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
20
20
  import { ImageNode } from "@blocklet/editor/lib/main/nodes/ImageNode";
21
21
  import { VideoNode } from "@blocklet/editor/lib/ext/VideoPlugin/VideoNode";
22
- import { useSize, useSetState, useGetState, useReactive } from "ahooks";
22
+ import { useSize, useInViewport, useSetState, useGetState, useReactive } from "ahooks";
23
23
  import LoadingButton from "@mui/lab/LoadingButton";
24
24
  import { Send, Save, ChatBubbleOutlineOutlined, MoreVert, AddReactionOutlined, NavigateNext, DeleteOutlineOutlined, ContentCopy, ArrowUpward, ArrowDownward, ArrowBackIos, Add } from "@mui/icons-material";
25
25
  import { LocaleContext, useLocaleContext } from "@arcblock/ux/lib/Locale/context";
@@ -1296,9 +1296,12 @@ function PostComponent({
1296
1296
  var _a2;
1297
1297
  const { session, isAdmin } = useSessionContext();
1298
1298
  const isAuthor = post.author.did === ((_a2 = session == null ? void 0 : session.user) == null ? void 0 : _a2.did);
1299
+ const commentUrl = window.location.hash.substring(1);
1299
1300
  const { t } = useLocaleContext();
1300
1301
  const [editing, setEditing] = useState(false);
1301
1302
  const postContext = { isAdmin, isAuthor, interactive, post };
1303
+ const [inViewport] = useInViewport(() => document == null ? void 0 : document.getElementById(post.id));
1304
+ const [hasEnteredViewport, setHasEnteredViewport] = useState(false);
1302
1305
  let menuItems = [];
1303
1306
  if (isAuthor && !post.deletedAt) {
1304
1307
  menuItems.push(
@@ -1319,7 +1322,7 @@ function PostComponent({
1319
1322
  )
1320
1323
  );
1321
1324
  }
1322
- const isTargetPost = window.location.hash.substring(1) === post.id;
1325
+ const isTargetPost = commentUrl === post.id;
1323
1326
  menuItems = customMenu ? customMenu(menuItems, postContext) : menuItems;
1324
1327
  const renderTime = () => {
1325
1328
  if (allowCopyLink) {
@@ -1334,8 +1337,13 @@ function PostComponent({
1334
1337
  systemTip = t("emptyContent");
1335
1338
  }
1336
1339
  const showSystemTip = systemTip && !editing;
1340
+ useEffect(() => {
1341
+ if (inViewport) {
1342
+ setHasEnteredViewport(inViewport);
1343
+ }
1344
+ }, [inViewport]);
1337
1345
  return /* @__PURE__ */ jsxs(Root$1, { sx: { position: "relative", mt: 2, py: 1 }, ...rest, children: [
1338
- /* @__PURE__ */ jsxs(Box, { id: post.id, flex: "1", className: clsx({ "post-highlighted": isTargetPost }), children: [
1346
+ /* @__PURE__ */ jsxs(Box, { id: post.id, flex: "1", className: clsx({ "post-highlighted": isTargetPost && hasEnteredViewport }), children: [
1339
1347
  /* @__PURE__ */ jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "start", children: [
1340
1348
  /* @__PURE__ */ jsx(AuthorInfo, { user: post.author, createdAt: renderTime(), showProfileCard }),
1341
1349
  /* @__PURE__ */ jsx(Menu, { items: menuItems, style: { position: "absolute", right: 0, top: 0 } })
@@ -2036,8 +2044,10 @@ const uniqAndSort$1 = (list, order) => {
2036
2044
  const sorted = orderBy(unique, ["createdAt", "id"], [order, order]);
2037
2045
  return sorted;
2038
2046
  };
2039
- const useAutoScroll = (data) => {
2047
+ const useAutoScroll = (data, containerHeight) => {
2040
2048
  const highlightedRef = useRef(window.location.hash.substring(1));
2049
+ const lastHeightRef = useRef(containerHeight);
2050
+ const autoScrolledRef = useRef(false);
2041
2051
  const matchTargetedPost = (posts) => {
2042
2052
  return posts.some((item) => {
2043
2053
  var _a2;
@@ -2050,13 +2060,33 @@ const useAutoScroll = (data) => {
2050
2060
  return false;
2051
2061
  });
2052
2062
  };
2063
+ const stableHeight = () => {
2064
+ if (lastHeightRef.current === containerHeight) {
2065
+ return true;
2066
+ }
2067
+ lastHeightRef.current = containerHeight;
2068
+ return false;
2069
+ };
2053
2070
  useEffect(() => {
2054
- var _a2;
2055
- if (highlightedRef.current && matchTargetedPost(data)) {
2056
- (_a2 = document.getElementById(highlightedRef.current)) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth", block: "center" });
2057
- highlightedRef.current = null;
2071
+ let interval;
2072
+ if (containerHeight && !autoScrolledRef.current) {
2073
+ interval = window.setInterval(() => {
2074
+ if (stableHeight()) {
2075
+ clearInterval(interval);
2076
+ if (highlightedRef.current && matchTargetedPost(data)) {
2077
+ const element = document.getElementById(highlightedRef.current);
2078
+ element == null ? void 0 : element.scrollIntoView({ behavior: "smooth", block: "center" });
2079
+ autoScrolledRef.current = true;
2080
+ }
2081
+ }
2082
+ }, 200);
2058
2083
  }
2059
- }, [data]);
2084
+ return () => {
2085
+ if (interval) {
2086
+ clearInterval(interval);
2087
+ }
2088
+ };
2089
+ }, [containerHeight]);
2060
2090
  };
2061
2091
  const CommentsContext = createContext({});
2062
2092
  const useCommentsContext = () => useContext(CommentsContext);
@@ -2070,14 +2100,17 @@ function CommentsProvider({
2070
2100
  autoCollapse,
2071
2101
  allowCopyLink,
2072
2102
  showProfileCard,
2073
- interactive
2103
+ interactive,
2104
+ containerRef
2074
2105
  }) {
2106
+ var _a2;
2075
2107
  const [state, setState] = useSetState(getInitialState(order ? { order } : {}));
2108
+ const containerHeight = (_a2 = useSize(containerRef)) == null ? void 0 : _a2.height;
2076
2109
  const commentsKeyById = useMemo(() => {
2077
2110
  return state.comments.reduce((acc, cur) => {
2078
- var _a2;
2111
+ var _a3;
2079
2112
  acc[cur.id] = cur;
2080
- if ((_a2 = cur.replies) == null ? void 0 : _a2.length) {
2113
+ if ((_a3 = cur.replies) == null ? void 0 : _a3.length) {
2081
2114
  cur.replies.forEach((item) => {
2082
2115
  acc[item.id] = item;
2083
2116
  });
@@ -2148,12 +2181,12 @@ function CommentsProvider({
2148
2181
  };
2149
2182
  init();
2150
2183
  }, [target.id, state.order, setState]);
2151
- useAutoScroll(state.comments);
2184
+ useAutoScroll(state.comments, containerHeight);
2152
2185
  const updateCommentState = (id2, mapper) => {
2153
- var _a2;
2186
+ var _a3;
2154
2187
  const comment = commentsKeyById[id2];
2155
2188
  const root = commentsKeyById[comment.rootId];
2156
- if ((_a2 = root == null ? void 0 : root.replies) == null ? void 0 : _a2.length) {
2189
+ if ((_a3 = root == null ? void 0 : root.replies) == null ? void 0 : _a3.length) {
2157
2190
  root.replies = root.replies.map((item) => item.id === id2 ? mapper(item) : item);
2158
2191
  updateCommentState(root.id, (current) => ({ ...current }));
2159
2192
  } else {
@@ -2189,10 +2222,10 @@ function CommentsProvider({
2189
2222
  setState({ comments: sorted, total, highlighted: { ...state.highlighted, nextCursor } });
2190
2223
  };
2191
2224
  const loadMoreReplies = async (rootId) => {
2192
- var _a2;
2225
+ var _a3;
2193
2226
  const root = commentsKeyById[rootId];
2194
2227
  if (root.replies) {
2195
- const cursor = state.replyCursors[root.id] || ((_a2 = getLastItem(root.replies)) == null ? void 0 : _a2.id);
2228
+ const cursor = state.replyCursors[root.id] || ((_a3 = getLastItem(root.replies)) == null ? void 0 : _a3.id);
2196
2229
  const { data, total, nextCursor } = await api.fetchComments({
2197
2230
  objectId: target.id,
2198
2231
  rootId,
@@ -2214,14 +2247,14 @@ function CommentsProvider({
2214
2247
  localStorage.setItem(KEY_LS_ORDER, order2);
2215
2248
  };
2216
2249
  const add = (post) => {
2217
- var _a2;
2250
+ var _a3;
2218
2251
  if (flatView || !post.rootId) {
2219
2252
  setState({ comments: uniqAndSort$1([...state.comments, post], state.order) });
2220
2253
  } else {
2221
2254
  const root = commentsKeyById[post.rootId];
2222
2255
  if (root) {
2223
2256
  if (!state.replyCursors[root.id] && root.replies) {
2224
- state.replyCursors[root.id] = (_a2 = getLastItem(root.replies)) == null ? void 0 : _a2.id;
2257
+ state.replyCursors[root.id] = (_a3 = getLastItem(root.replies)) == null ? void 0 : _a3.id;
2225
2258
  }
2226
2259
  const sorted = uniqAndSort$1([...root.replies || [], post], "asc");
2227
2260
  updateCommentState(post.rootId, (current) => ({
@@ -4461,7 +4494,7 @@ function Pagination({ page, size = 20, total, onChange, routerMode = true, ...re
4461
4494
  }
4462
4495
  );
4463
4496
  }
4464
- const Editor = lazy(() => import("./editor-EfzFR9YD.mjs"));
4497
+ const Editor = lazy(() => import("./editor-XEL58tBE.mjs"));
4465
4498
  function LazyEditor(props) {
4466
4499
  const fallback = /* @__PURE__ */ jsxs(Fragment, { children: [
4467
4500
  /* @__PURE__ */ jsx(Skeleton, {}),
package/dist/index.es.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from "@blocklet/labels";
2
- import { K, j, N, A, h, a6, B, z, y, E, Q, O, T, W, o, C, q, v, x, _, $, aa, a1, H, J, D, a9, a8, G, c, b, a7, M, P, ah, n, m, a5, R, S, a2, k, X, Z, ab, ae, ad, af, ai, F, aj, l, p, r, t, d, a3, L, e, U, w, a0, a4, u, ag, ak, Y, ac, f } from "./index-NFPPoDc-.mjs";
2
+ import { K, j, N, A, h, a6, B, z, y, E, Q, O, T, W, o, C, q, v, x, _, $, aa, a1, H, J, D, a9, a8, G, c, b, a7, M, P, ah, n, m, a5, R, S, a2, k, X, Z, ab, ae, ad, af, ai, F, aj, l, p, r, t, d, a3, L, e, U, w, a0, a4, u, ag, ak, Y, ac, f } from "./index-GBSsS-kJ.mjs";
3
3
  import "react/jsx-runtime";
4
4
  import "react";
5
5
  import "@mui/material/Box";
package/dist/index.umd.js CHANGED
@@ -1236,9 +1236,12 @@ var __publicField = (obj, key, value) => {
1236
1236
  var _a2;
1237
1237
  const { session, isAdmin } = useSessionContext();
1238
1238
  const isAuthor = post.author.did === ((_a2 = session == null ? void 0 : session.user) == null ? void 0 : _a2.did);
1239
+ const commentUrl = window.location.hash.substring(1);
1239
1240
  const { t } = context.useLocaleContext();
1240
1241
  const [editing, setEditing] = react.useState(false);
1241
1242
  const postContext = { isAdmin, isAuthor, interactive, post };
1243
+ const [inViewport] = ahooks.useInViewport(() => document == null ? void 0 : document.getElementById(post.id));
1244
+ const [hasEnteredViewport, setHasEnteredViewport] = react.useState(false);
1242
1245
  let menuItems = [];
1243
1246
  if (isAuthor && !post.deletedAt) {
1244
1247
  menuItems.push(
@@ -1259,7 +1262,7 @@ var __publicField = (obj, key, value) => {
1259
1262
  )
1260
1263
  );
1261
1264
  }
1262
- const isTargetPost = window.location.hash.substring(1) === post.id;
1265
+ const isTargetPost = commentUrl === post.id;
1263
1266
  menuItems = customMenu ? customMenu(menuItems, postContext) : menuItems;
1264
1267
  const renderTime = () => {
1265
1268
  if (allowCopyLink) {
@@ -1274,8 +1277,13 @@ var __publicField = (obj, key, value) => {
1274
1277
  systemTip = t("emptyContent");
1275
1278
  }
1276
1279
  const showSystemTip = systemTip && !editing;
1280
+ react.useEffect(() => {
1281
+ if (inViewport) {
1282
+ setHasEnteredViewport(inViewport);
1283
+ }
1284
+ }, [inViewport]);
1277
1285
  return /* @__PURE__ */ jsxRuntime.jsxs(Root$2, { sx: { position: "relative", mt: 2, py: 1 }, ...rest, children: [
1278
- /* @__PURE__ */ jsxRuntime.jsxs(Box, { id: post.id, flex: "1", className: clsx({ "post-highlighted": isTargetPost }), children: [
1286
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { id: post.id, flex: "1", className: clsx({ "post-highlighted": isTargetPost && hasEnteredViewport }), children: [
1279
1287
  /* @__PURE__ */ jsxRuntime.jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "start", children: [
1280
1288
  /* @__PURE__ */ jsxRuntime.jsx(AuthorInfo, { user: post.author, createdAt: renderTime(), showProfileCard }),
1281
1289
  /* @__PURE__ */ jsxRuntime.jsx(Menu, { items: menuItems, style: { position: "absolute", right: 0, top: 0 } })
@@ -1976,8 +1984,10 @@ var __publicField = (obj, key, value) => {
1976
1984
  const sorted = orderBy(unique, ["createdAt", "id"], [order, order]);
1977
1985
  return sorted;
1978
1986
  };
1979
- const useAutoScroll = (data) => {
1987
+ const useAutoScroll = (data, containerHeight) => {
1980
1988
  const highlightedRef = react.useRef(window.location.hash.substring(1));
1989
+ const lastHeightRef = react.useRef(containerHeight);
1990
+ const autoScrolledRef = react.useRef(false);
1981
1991
  const matchTargetedPost = (posts) => {
1982
1992
  return posts.some((item) => {
1983
1993
  var _a2;
@@ -1990,13 +2000,33 @@ var __publicField = (obj, key, value) => {
1990
2000
  return false;
1991
2001
  });
1992
2002
  };
2003
+ const stableHeight = () => {
2004
+ if (lastHeightRef.current === containerHeight) {
2005
+ return true;
2006
+ }
2007
+ lastHeightRef.current = containerHeight;
2008
+ return false;
2009
+ };
1993
2010
  react.useEffect(() => {
1994
- var _a2;
1995
- if (highlightedRef.current && matchTargetedPost(data)) {
1996
- (_a2 = document.getElementById(highlightedRef.current)) == null ? void 0 : _a2.scrollIntoView({ behavior: "smooth", block: "center" });
1997
- highlightedRef.current = null;
2011
+ let interval;
2012
+ if (containerHeight && !autoScrolledRef.current) {
2013
+ interval = window.setInterval(() => {
2014
+ if (stableHeight()) {
2015
+ clearInterval(interval);
2016
+ if (highlightedRef.current && matchTargetedPost(data)) {
2017
+ const element = document.getElementById(highlightedRef.current);
2018
+ element == null ? void 0 : element.scrollIntoView({ behavior: "smooth", block: "center" });
2019
+ autoScrolledRef.current = true;
2020
+ }
2021
+ }
2022
+ }, 200);
1998
2023
  }
1999
- }, [data]);
2024
+ return () => {
2025
+ if (interval) {
2026
+ clearInterval(interval);
2027
+ }
2028
+ };
2029
+ }, [containerHeight]);
2000
2030
  };
2001
2031
  const CommentsContext = react.createContext({});
2002
2032
  const useCommentsContext = () => react.useContext(CommentsContext);
@@ -2010,14 +2040,17 @@ var __publicField = (obj, key, value) => {
2010
2040
  autoCollapse,
2011
2041
  allowCopyLink,
2012
2042
  showProfileCard,
2013
- interactive
2043
+ interactive,
2044
+ containerRef
2014
2045
  }) {
2046
+ var _a2;
2015
2047
  const [state, setState] = ahooks.useSetState(getInitialState(order ? { order } : {}));
2048
+ const containerHeight = (_a2 = ahooks.useSize(containerRef)) == null ? void 0 : _a2.height;
2016
2049
  const commentsKeyById = react.useMemo(() => {
2017
2050
  return state.comments.reduce((acc, cur) => {
2018
- var _a2;
2051
+ var _a3;
2019
2052
  acc[cur.id] = cur;
2020
- if ((_a2 = cur.replies) == null ? void 0 : _a2.length) {
2053
+ if ((_a3 = cur.replies) == null ? void 0 : _a3.length) {
2021
2054
  cur.replies.forEach((item) => {
2022
2055
  acc[item.id] = item;
2023
2056
  });
@@ -2088,12 +2121,12 @@ var __publicField = (obj, key, value) => {
2088
2121
  };
2089
2122
  init();
2090
2123
  }, [target.id, state.order, setState]);
2091
- useAutoScroll(state.comments);
2124
+ useAutoScroll(state.comments, containerHeight);
2092
2125
  const updateCommentState = (id2, mapper) => {
2093
- var _a2;
2126
+ var _a3;
2094
2127
  const comment = commentsKeyById[id2];
2095
2128
  const root = commentsKeyById[comment.rootId];
2096
- if ((_a2 = root == null ? void 0 : root.replies) == null ? void 0 : _a2.length) {
2129
+ if ((_a3 = root == null ? void 0 : root.replies) == null ? void 0 : _a3.length) {
2097
2130
  root.replies = root.replies.map((item) => item.id === id2 ? mapper(item) : item);
2098
2131
  updateCommentState(root.id, (current) => ({ ...current }));
2099
2132
  } else {
@@ -2129,10 +2162,10 @@ var __publicField = (obj, key, value) => {
2129
2162
  setState({ comments: sorted, total, highlighted: { ...state.highlighted, nextCursor } });
2130
2163
  };
2131
2164
  const loadMoreReplies = async (rootId) => {
2132
- var _a2;
2165
+ var _a3;
2133
2166
  const root = commentsKeyById[rootId];
2134
2167
  if (root.replies) {
2135
- const cursor = state.replyCursors[root.id] || ((_a2 = getLastItem(root.replies)) == null ? void 0 : _a2.id);
2168
+ const cursor = state.replyCursors[root.id] || ((_a3 = getLastItem(root.replies)) == null ? void 0 : _a3.id);
2136
2169
  const { data, total, nextCursor } = await api.fetchComments({
2137
2170
  objectId: target.id,
2138
2171
  rootId,
@@ -2154,14 +2187,14 @@ var __publicField = (obj, key, value) => {
2154
2187
  localStorage.setItem(KEY_LS_ORDER, order2);
2155
2188
  };
2156
2189
  const add = (post) => {
2157
- var _a2;
2190
+ var _a3;
2158
2191
  if (flatView || !post.rootId) {
2159
2192
  setState({ comments: uniqAndSort$1([...state.comments, post], state.order) });
2160
2193
  } else {
2161
2194
  const root = commentsKeyById[post.rootId];
2162
2195
  if (root) {
2163
2196
  if (!state.replyCursors[root.id] && root.replies) {
2164
- state.replyCursors[root.id] = (_a2 = getLastItem(root.replies)) == null ? void 0 : _a2.id;
2197
+ state.replyCursors[root.id] = (_a3 = getLastItem(root.replies)) == null ? void 0 : _a3.id;
2165
2198
  }
2166
2199
  const sorted = uniqAndSort$1([...root.replies || [], post], "asc");
2167
2200
  updateCommentState(post.rootId, (current) => ({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/discuss-kit-ux",
3
- "version": "1.6.63",
3
+ "version": "1.6.64",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -29,8 +29,8 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@arcblock/ws": "^1.18.108",
32
- "@blocklet/editor": "1.6.63",
33
- "@blocklet/labels": "1.6.63",
32
+ "@blocklet/editor": "1.6.64",
33
+ "@blocklet/labels": "1.6.64",
34
34
  "@blocklet/uploader": "^0.0.63",
35
35
  "@emotion/css": "^11.10.5",
36
36
  "@emotion/react": "^11.10.5",
@@ -93,5 +93,5 @@
93
93
  "resolutions": {
94
94
  "react": "^18.2.0"
95
95
  },
96
- "gitHead": "6654a90b799b661e5f9ffb543a67d831208ba415"
96
+ "gitHead": "455036419d403c12937a586732caff277ea399c9"
97
97
  }