@blocklet/discuss-kit-ux 2.1.106 → 2.1.108

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.
@@ -86,5 +86,8 @@ declare const _default: {
86
86
  edited: string;
87
87
  created: string;
88
88
  };
89
+ pin: string;
90
+ unpin: string;
91
+ pinned: string;
89
92
  };
90
93
  export default _default;
@@ -89,6 +89,9 @@ export declare const translations: {
89
89
  edited: string;
90
90
  created: string;
91
91
  };
92
+ pin: string;
93
+ unpin: string;
94
+ pinned: string;
92
95
  };
93
96
  en: {
94
97
  cancel: string;
@@ -178,5 +181,8 @@ export declare const translations: {
178
181
  edited: string;
179
182
  created: string;
180
183
  };
184
+ pin: string;
185
+ unpin: string;
186
+ pinned: string;
181
187
  };
182
188
  };
@@ -88,5 +88,8 @@ declare const _default: {
88
88
  edited: string;
89
89
  created: string;
90
90
  };
91
+ pin: string;
92
+ unpin: string;
93
+ pinned: string;
91
94
  };
92
95
  export default _default;
@@ -45,6 +45,8 @@ interface CommentsContextValue {
45
45
  target: Target;
46
46
  api: CommentAPI;
47
47
  state: State;
48
+ comments: Post[];
49
+ pinned: Post[];
48
50
  flatView?: boolean;
49
51
  autoCollapse?: boolean;
50
52
  allowCopyLink?: boolean;
@@ -58,6 +60,7 @@ interface CommentsContextValue {
58
60
  updateComment: CommentAPI['updateComment'];
59
61
  deleteComment: CommentAPI['deleteComment'];
60
62
  reply: CommentAPI['reply'];
63
+ togglePin: CommentAPI['togglePin'];
61
64
  findById: (id: string) => Post | undefined;
62
65
  renderComments?: CommentsRender;
63
66
  renderDonation?: (post: Post) => React.ReactNode;
@@ -5,9 +5,10 @@ export interface CommentProps {
5
5
  onRate: CommentAPI['rate'];
6
6
  onUnrate: CommentAPI['unrate'];
7
7
  onReply: CommentAPI['reply'];
8
+ onTogglePin: CommentAPI['togglePin'];
8
9
  onLoadMoreReplies: (rootId: string) => void;
9
10
  renderDonation?: (post: Post) => React.ReactNode;
10
11
  renderActions?: (post: Post) => React.ReactNode;
11
12
  renderEditorPlugins?: (post: Post) => React.ReactNode;
12
13
  }
13
- export default function Comment({ onDelete, onRate, onUnrate, onReply, onContentUpdate, onLoadMoreReplies, renderDonation, renderActions, renderEditorPlugins, ...rest }: PostProps & CommentProps): import("react/jsx-runtime").JSX.Element;
14
+ export default function Comment({ onDelete, onRate, onUnrate, onReply, onTogglePin, onContentUpdate, onLoadMoreReplies, renderDonation, renderActions, renderEditorPlugins, ...rest }: PostProps & CommentProps): import("react/jsx-runtime").JSX.Element;
@@ -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 { lazyRetry } from "@arcblock/ux/lib/Util";
7
- import { i as inferInitialEditorState, I as ImagePathFixerPlugin, V as VideoPathFixerPlugin, a as isEmptyContent, s as stringify, g as getExcerptSync } from "./index-DXCcMmcr.mjs";
7
+ import { i as inferInitialEditorState, I as ImagePathFixerPlugin, V as VideoPathFixerPlugin, a as isEmptyContent, s as stringify, g as getExcerptSync } from "./index-BXFZiIgf.mjs";
8
8
  const BlockletEditor = lazyRetry(() => import("@blocklet/editor"));
9
9
  const Root = styled(Box)`
10
10
  .be-editable,
@@ -56,6 +56,7 @@ import clsx from "clsx";
56
56
  import IconButton$1 from "@mui/material/IconButton";
57
57
  import MuiMenu from "@mui/material/Menu";
58
58
  import { EditorHolderProvider } from "@blocklet/editor/lib/ext/EditorHolderPlugin";
59
+ import red from "@mui/material/colors/red";
59
60
  import Dialog from "@arcblock/ux/lib/Dialog";
60
61
  import orderBy from "lodash/orderBy";
61
62
  import Typography from "@mui/material/Typography";
@@ -1804,6 +1805,7 @@ function PostComponent({
1804
1805
  ] });
1805
1806
  }
1806
1807
  const tablerMessageCircle = (props) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "data-iconify": "tabler", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsx("path", { fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "m3 20l1.3-3.9C1.976 12.663 2.874 8.228 6.4 5.726c3.526-2.501 8.59-2.296 11.845.48c3.255 2.777 3.695 7.266 1.029 10.501S11.659 20.922 7.7 19z" }) });
1808
+ const tablerPinned = (props) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "data-iconify": "tabler", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsx("path", { fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 4v6l-2 4v2h10v-2l-2-4V4m-3 12v5M8 4h8" }) });
1807
1809
  const iconoirThumbsUp = (props) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsxs("g", { fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeWidth: 1.5, children: [
1808
1810
  /* @__PURE__ */ jsx("path", { d: "M16.472 20H4.1a.6.6 0 0 1-.6-.6V9.6a.6.6 0 0 1 .6-.6h2.768a2 2 0 0 0 1.715-.971l2.71-4.517a1.631 1.631 0 0 1 2.961 1.308l-1.022 3.408a.6.6 0 0 0 .574.772h4.576a2 2 0 0 1 1.929 2.526l-1.91 7A2 2 0 0 1 16.473 20Z" }),
1809
1811
  /* @__PURE__ */ jsx("path", { strokeLinejoin: "round", d: "M7 20V9" })
@@ -2349,6 +2351,7 @@ function Comment({
2349
2351
  onRate,
2350
2352
  onUnrate,
2351
2353
  onReply,
2354
+ onTogglePin,
2352
2355
  onContentUpdate,
2353
2356
  onLoadMoreReplies,
2354
2357
  renderDonation,
@@ -2371,6 +2374,11 @@ function Comment({
2371
2374
  }
2372
2375
  };
2373
2376
  const customMenu = (items, { isAuthor, isAdmin, post }) => {
2377
+ if (isAdmin && !post.parentId) {
2378
+ items.push(
2379
+ /* @__PURE__ */ jsx(MuiMenuItem, { onClick: () => onTogglePin({ post, value: !post.pinnedAt }), children: t(post.pinnedAt ? "unpin" : "pin") }, "pin")
2380
+ );
2381
+ }
2374
2382
  if ((isAdmin || isAuthor) && !post.deletedAt) {
2375
2383
  items.push(
2376
2384
  /* @__PURE__ */ jsx(MuiMenuItem, { onClick: () => handleDelete(post), children: /* @__PURE__ */ jsx(Box$1, { component: "span", sx: { color: "error.main" }, children: t("delete") }) }, "delete")
@@ -2380,6 +2388,29 @@ function Comment({
2380
2388
  };
2381
2389
  const render = ({ post, interactive }) => {
2382
2390
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2391
+ post.pinnedAt && /* @__PURE__ */ jsx(Box$1, { sx: { display: "flex", alignItems: "end", gap: 3, mt: 1 }, children: /* @__PURE__ */ jsxs(
2392
+ Box$1,
2393
+ {
2394
+ component: "span",
2395
+ sx: {
2396
+ display: "inline-flex",
2397
+ alignItems: "center",
2398
+ gap: 0.25,
2399
+ fontSize: 12,
2400
+ color: red[700],
2401
+ fontWeight: "bold",
2402
+ bgcolor: red[50],
2403
+ border: `1px solid ${red[100]}`,
2404
+ borderRadius: 1,
2405
+ px: 1.75,
2406
+ py: 0.25
2407
+ },
2408
+ children: [
2409
+ /* @__PURE__ */ jsx(Box$1, { component: tablerPinned, sx: { fontSize: 12 } }),
2410
+ t("pinned")
2411
+ ]
2412
+ }
2413
+ ) }),
2383
2414
  /* @__PURE__ */ jsxs(Box$1, { sx: { display: "flex", alignItems: "end", gap: 3, mt: 1 }, children: [
2384
2415
  /* @__PURE__ */ jsx(
2385
2416
  GithubReaction,
@@ -2446,6 +2477,7 @@ function Comment({
2446
2477
  onRate,
2447
2478
  onUnrate,
2448
2479
  onReply,
2480
+ onTogglePin,
2449
2481
  onLoadMoreReplies,
2450
2482
  allowCopyLink: rest.allowCopyLink,
2451
2483
  showProfileCard: rest.showProfileCard,
@@ -2580,6 +2612,8 @@ function CommentsProvider({
2580
2612
  }) {
2581
2613
  var _a2;
2582
2614
  const [state, setState] = useSetState(getInitialState(order ? { order } : {}));
2615
+ const comments = useMemo(() => state.comments.filter((item) => !item.pinnedAt), [state.comments]);
2616
+ const pinned = useMemo(() => state.comments.filter((item) => item.pinnedAt), [state.comments]);
2583
2617
  const containerHeight = (_a2 = useSize(containerRef)) == null ? void 0 : _a2.height;
2584
2618
  const commentsKeyById = useMemo(() => {
2585
2619
  return state.comments.reduce((acc, cur) => {
@@ -2609,7 +2643,7 @@ function CommentsProvider({
2609
2643
  order: state.order,
2610
2644
  includeReplies: flatView ? 1 : null
2611
2645
  });
2612
- const [{ data, total, nextCursor }, positionRes] = await Promise.all([
2646
+ const [{ data, total, nextCursor }, positionRes, pinnedComments] = await Promise.all([
2613
2647
  api.fetchComments({
2614
2648
  objectId: target.id,
2615
2649
  limit,
@@ -2617,7 +2651,8 @@ function CommentsProvider({
2617
2651
  includeReplies: flatView ? 1 : null,
2618
2652
  initialRepliesLimit
2619
2653
  }),
2620
- highlightedRef.current ? fetchCommentPosition() : -1
2654
+ highlightedRef.current ? fetchCommentPosition() : -1,
2655
+ api.fetchPinnedComments(target.id)
2621
2656
  ]);
2622
2657
  let position = -1;
2623
2658
  let cursor = highlightedRef.current;
@@ -2638,7 +2673,7 @@ function CommentsProvider({
2638
2673
  initialRepliesLimit
2639
2674
  });
2640
2675
  setState({
2641
- comments: [...data, ...result.data],
2676
+ comments: [...data, ...result.data, ...pinnedComments],
2642
2677
  nextCursor,
2643
2678
  total,
2644
2679
  initialized: true,
@@ -2651,7 +2686,12 @@ function CommentsProvider({
2651
2686
  }
2652
2687
  });
2653
2688
  } else {
2654
- setState({ comments: data, nextCursor, total, initialized: true });
2689
+ setState({
2690
+ comments: [...data, ...pinnedComments],
2691
+ nextCursor,
2692
+ total,
2693
+ initialized: true
2694
+ });
2655
2695
  }
2656
2696
  };
2657
2697
  init();
@@ -2756,11 +2796,17 @@ function CommentsProvider({
2756
2796
  const result = await api.reply(post, content);
2757
2797
  setTimeout(() => add(result), 800);
2758
2798
  };
2799
+ const togglePin = async ({ post, value: value2 }) => {
2800
+ await api.togglePin({ post, value: value2 });
2801
+ updateCommentState(post.id, (current) => ({ ...current, pinnedAt: value2 ? /* @__PURE__ */ new Date() : null }));
2802
+ };
2759
2803
  const findById = (id2) => commentsKeyById[id2];
2760
2804
  const value = useMemo(
2761
2805
  () => ({
2762
2806
  target,
2763
2807
  state,
2808
+ pinned,
2809
+ comments,
2764
2810
  flatView,
2765
2811
  autoCollapse,
2766
2812
  allowCopyLink,
@@ -2775,6 +2821,7 @@ function CommentsProvider({
2775
2821
  updateComment,
2776
2822
  deleteComment,
2777
2823
  reply,
2824
+ togglePin,
2778
2825
  loadMoreReplies,
2779
2826
  findById,
2780
2827
  renderComments,
@@ -2806,6 +2853,7 @@ function SegmentalList({ ...rest }) {
2806
2853
  updateComment,
2807
2854
  deleteComment,
2808
2855
  reply,
2856
+ togglePin,
2809
2857
  loadMoreReplies,
2810
2858
  api
2811
2859
  } = useCommentsContext();
@@ -2851,6 +2899,7 @@ function SegmentalList({ ...rest }) {
2851
2899
  onRate: api.rate,
2852
2900
  onUnrate: api.unrate,
2853
2901
  onReply: reply,
2902
+ onTogglePin: togglePin,
2854
2903
  onLoadMoreReplies: loadMoreReplies,
2855
2904
  autoCollapse,
2856
2905
  allowCopyLink,
@@ -2876,7 +2925,9 @@ function SegmentalList({ ...rest }) {
2876
2925
  function CommentList(props) {
2877
2926
  const { t } = useLocaleContext();
2878
2927
  const {
2879
- state: { comments, order, nextCursor, highlighted },
2928
+ state: { order, nextCursor, highlighted },
2929
+ comments,
2930
+ pinned,
2880
2931
  autoCollapse,
2881
2932
  allowCopyLink,
2882
2933
  showProfileCard,
@@ -2885,6 +2936,7 @@ function CommentList(props) {
2885
2936
  updateComment,
2886
2937
  deleteComment,
2887
2938
  reply,
2939
+ togglePin,
2888
2940
  loadMoreReplies,
2889
2941
  api,
2890
2942
  renderComments,
@@ -2904,6 +2956,7 @@ function CommentList(props) {
2904
2956
  onRate: api.rate,
2905
2957
  onUnrate: api.unrate,
2906
2958
  onReply: reply,
2959
+ onTogglePin: togglePin,
2907
2960
  onLoadMoreReplies: loadMoreReplies,
2908
2961
  autoCollapse,
2909
2962
  allowCopyLink,
@@ -2916,7 +2969,12 @@ function CommentList(props) {
2916
2969
  },
2917
2970
  comment.id
2918
2971
  );
2972
+ const sortedPinned = pinned.sort((a, b) => {
2973
+ var _a2, _b2;
2974
+ return (((_a2 = b.pinnedAt) == null ? void 0 : _a2.getTime()) ?? 0) - (((_b2 = a.pinnedAt) == null ? void 0 : _b2.getTime()) ?? 0);
2975
+ });
2919
2976
  return /* @__PURE__ */ jsxs("div", { ...props, children: [
2977
+ /* @__PURE__ */ jsx(Box$1, { children: sortedPinned.map((post) => renderComment(post, {})) }),
2920
2978
  renderComments ? renderComments({ order, comments, renderComment }) : comments == null ? void 0 : comments.map(renderComment),
2921
2979
  nextCursor && /* @__PURE__ */ jsx(Box$1, { sx: { my: 2, textAlign: "center" }, children: /* @__PURE__ */ jsx(
2922
2980
  Button,
@@ -4724,7 +4782,7 @@ function Back({ url, fallbackUrl, iconOnly, sx, ...rest }) {
4724
4782
  }
4725
4783
  const tablerSend = (props) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "data-iconify": "tabler", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsx("path", { fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10 14L21 3m0 0l-6.5 18a.55.55 0 0 1-1 0L10 14l-7-3.5a.55.55 0 0 1 0-1z" }) });
4726
4784
  const tablerLetterCase = (props) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", "data-iconify": "tabler", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsx("path", { fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M14 15.5a3.5 3.5 0 1 0 7 0a3.5 3.5 0 1 0-7 0M3 19V8.5a3.5 3.5 0 0 1 7 0V19m-7-6h7m11-1v7" }) });
4727
- const Editor = lazyRetry(() => import("./editor-DdY8k2T0.mjs"));
4785
+ const Editor = lazyRetry(() => import("./editor-BvoQGKvy.mjs"));
4728
4786
  function LazyEditor(props) {
4729
4787
  const fallback2 = /* @__PURE__ */ jsxs(Box, { sx: { px: 3 }, children: [
4730
4788
  /* @__PURE__ */ jsx(Skeleton, {}),
@@ -6193,7 +6251,10 @@ const en = {
6193
6251
  mostRecent: "most recent",
6194
6252
  edited: "edited",
6195
6253
  created: "created"
6196
- }
6254
+ },
6255
+ pin: "Pin",
6256
+ unpin: "Unpin",
6257
+ pinned: "Pinned"
6197
6258
  };
6198
6259
  const zh = {
6199
6260
  cancel: "取消",
@@ -6284,7 +6345,10 @@ const zh = {
6284
6345
  mostRecent: "最近",
6285
6346
  edited: "编辑",
6286
6347
  created: "创建"
6287
- }
6348
+ },
6349
+ pin: "置顶",
6350
+ unpin: "取消置顶",
6351
+ pinned: "置顶"
6288
6352
  };
6289
6353
  const translations = { zh, en };
6290
6354
  const Lottie = lazyRetry(() => import("lottie-react"));
package/dist/index.es.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from "@blocklet/labels";
2
- import { T, n, W, A, m, ad, B, F, K, J, L, ap, Y, X, $, Z, _, a1, w, C, x, y, E, a5, a6, ah, a8, O, Q, ac, D, ag, af, H, G, b, k, ae, M, P, ao, v, q, R, S, a9, aq, o, a2, a4, ai, al, ak, ar, N, am, as, l, f, p, r, j, t, h, aa, U, c, a0, z, a7, ab, u, an, d, at, a3, aj, e } from "./index-DXCcMmcr.mjs";
2
+ import { T, n, W, A, m, ad, B, F, K, J, L, ap, Y, X, $, Z, _, a1, w, C, x, y, E, a5, a6, ah, a8, O, Q, ac, D, ag, af, H, G, b, k, ae, M, P, ao, v, q, R, S, a9, aq, o, a2, a4, ai, al, ak, ar, N, am, as, l, f, p, r, j, t, h, aa, U, c, a0, z, a7, ab, u, an, d, at, a3, aj, e } from "./index-BXFZiIgf.mjs";
3
3
  import "react/jsx-runtime";
4
4
  import "react";
5
5
  import "@mui/material/Box";
package/dist/index.umd.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function(global, factory) {
2
- typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@blocklet/labels"), require("react/jsx-runtime"), require("@mui/material/styles"), require("@arcblock/ux/lib/Theme"), require("react"), require("@mui/material"), require("lodash/isNil"), require("@blocklet/editor/lib/config"), require("react-lazy-with-preload"), require("@lexical/react/LexicalComposerContext"), require("lexical"), require("ahooks"), require("@arcblock/ux/lib/Locale/context"), require("@mui/icons-material"), require("@mui/lab/LoadingButton"), require("@mui/material/Alert"), require("@mui/material/Box"), require("lodash/isBoolean"), require("@mui/material/Button"), require("@arcblock/did-connect/lib/Avatar"), require("@mui/material/AvatarGroup"), require("@mui/material/colors"), require("@mui/material/useMediaQuery"), require("@arcblock/ux/lib/DID"), require("@mui/material/Tooltip"), require("react-router-dom"), require("@arcblock/react-hooks"), require("@arcblock/ux/lib/RelativeTime"), require("@mui/material/Chip"), require("@mui/material/Stack"), require("lodash/groupBy"), require("lodash/flatMap"), require("lodash/uniqBy"), require("lodash/trim"), require("@mui/material/Avatar"), require("@mui/icons-material/BrokenImage"), require("@iconify/react"), require("@arcblock/ux/lib/Empty"), require("@arcblock/did-connect/lib/Session"), require("semver-compare"), require("@arcblock/bridge"), require("@mui/icons-material/NotificationsActiveOutlined"), require("@arcblock/ux/lib/Util"), require("@blocklet/editor/lib/ext/CheckboxPlugin"), require("@arcblock/did-connect/lib/Address"), require("@mui/material/MenuItem"), require("clsx"), require("@mui/material/IconButton"), require("@mui/material/Menu"), require("@blocklet/editor/lib/ext/EditorHolderPlugin"), require("@arcblock/ux/lib/Dialog"), require("lodash/orderBy"), require("@mui/material/Typography"), require("@mui/material/Skeleton"), require("react-dom"), require("ufo"), require("dayjs"), require("dayjs/plugin/relativeTime"), require("url-join"), require("mitt"), require("@mui/material/CircularProgress"), require("react-helmet"), require("react-flip-toolkit"), require("@mui/material/colors/grey"), require("@blocklet/editor"), require("@mui/material/Fab"), require("lodash/debounce"), require("@blocklet/editor/lib/main/hooks/useIsFocused"), require("@blocklet/editor/lib/ext/BusyPlugin"), require("@mui/icons-material/ArrowBackIos"), require("axios"), require("@arcblock/ux/lib/Toast"), require("@mui/material/Pagination"), require("unstated-next"), require("js-cookie"), require("@arcblock/ws"), require("@emotion/css"), require("@blocklet/editor/lib/ext/OnContentChangePlugin"), require("@blocklet/editor/lib/ext/ShortcutPlugin"), require("@blocklet/editor/lib/ext/SafeAreaPlugin"), require("@lexical/text"), require("@blocklet/editor/lib/main/nodes/ImageNode"), require("@blocklet/editor/lib/ext/VideoPlugin/VideoNode")) : typeof define === "function" && define.amd ? define(["exports", "@blocklet/labels", "react/jsx-runtime", "@mui/material/styles", "@arcblock/ux/lib/Theme", "react", "@mui/material", "lodash/isNil", "@blocklet/editor/lib/config", "react-lazy-with-preload", "@lexical/react/LexicalComposerContext", "lexical", "ahooks", "@arcblock/ux/lib/Locale/context", "@mui/icons-material", "@mui/lab/LoadingButton", "@mui/material/Alert", "@mui/material/Box", "lodash/isBoolean", "@mui/material/Button", "@arcblock/did-connect/lib/Avatar", "@mui/material/AvatarGroup", "@mui/material/colors", "@mui/material/useMediaQuery", "@arcblock/ux/lib/DID", "@mui/material/Tooltip", "react-router-dom", "@arcblock/react-hooks", "@arcblock/ux/lib/RelativeTime", "@mui/material/Chip", "@mui/material/Stack", "lodash/groupBy", "lodash/flatMap", "lodash/uniqBy", "lodash/trim", "@mui/material/Avatar", "@mui/icons-material/BrokenImage", "@iconify/react", "@arcblock/ux/lib/Empty", "@arcblock/did-connect/lib/Session", "semver-compare", "@arcblock/bridge", "@mui/icons-material/NotificationsActiveOutlined", "@arcblock/ux/lib/Util", "@blocklet/editor/lib/ext/CheckboxPlugin", "@arcblock/did-connect/lib/Address", "@mui/material/MenuItem", "clsx", "@mui/material/IconButton", "@mui/material/Menu", "@blocklet/editor/lib/ext/EditorHolderPlugin", "@arcblock/ux/lib/Dialog", "lodash/orderBy", "@mui/material/Typography", "@mui/material/Skeleton", "react-dom", "ufo", "dayjs", "dayjs/plugin/relativeTime", "url-join", "mitt", "@mui/material/CircularProgress", "react-helmet", "react-flip-toolkit", "@mui/material/colors/grey", "@blocklet/editor", "@mui/material/Fab", "lodash/debounce", "@blocklet/editor/lib/main/hooks/useIsFocused", "@blocklet/editor/lib/ext/BusyPlugin", "@mui/icons-material/ArrowBackIos", "axios", "@arcblock/ux/lib/Toast", "@mui/material/Pagination", "unstated-next", "js-cookie", "@arcblock/ws", "@emotion/css", "@blocklet/editor/lib/ext/OnContentChangePlugin", "@blocklet/editor/lib/ext/ShortcutPlugin", "@blocklet/editor/lib/ext/SafeAreaPlugin", "@lexical/text", "@blocklet/editor/lib/main/nodes/ImageNode", "@blocklet/editor/lib/ext/VideoPlugin/VideoNode"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.DiscussKitComponents = {}, global.labels, global.jsxRuntime, global.styles, global.Theme, global.react, global.material, global.isNil, global.config, global.reactLazyWithPreload, global.LexicalComposerContext, global.lexical$1, global.ahooks, global.context, global.iconsMaterial, global.LoadingButton, global.Alert, global.Box, global.isBoolean, global.Button, global.DidAvatar, global.AvatarGroup, global.colors, global.useMediaQuery, global.DID, global.Tooltip, global.reactRouterDom, global.reactHooks, global.UxRelativeTime, global.Chip, global.Stack, global.groupBy, global.flatMap, global.uniqBy, global.trim, global.Avatar$1, global.BrokenImageIcon, global.react$1, global.Empty$3, global.Session, global.cmp, global.bridge, global.NotificationsActiveOutlinedIcon, global.Util, global.CheckboxPlugin, global.DIDAddress, global.MuiMenuItem, global.clsx, global.IconButton$1, global.MuiMenu, global.EditorHolderPlugin, global.Dialog, global.orderBy, global.Typography, global.Skeleton, global.ReactDOM, global.ufo, global.dayjs, global.relativeTime, global.joinUrl, global.mitt, global.CircularProgress, global.reactHelmet, global.reactFlipToolkit, global.grey, global.editor$1, global.Fab, global.debounce, global.useIsFocused, global.BusyPlugin, global.ArrowBackIosIcon, global.axios, global.Toast, global.MuiPagination, global.unstatedNext, global.Cookie, global.ws, global.css, global.OnContentChangePlugin, global.ShortcutPlugin$1, global.SafeAreaPlugin, global.text, global.ImageNode, global.VideoNode));
3
- })(this, function(exports2, labels, jsxRuntime, styles, Theme, react, material, isNil, config, reactLazyWithPreload, LexicalComposerContext, lexical$1, ahooks, context, iconsMaterial, LoadingButton, Alert, Box, isBoolean, Button, DidAvatar, AvatarGroup, colors, useMediaQuery, DID, Tooltip, reactRouterDom, reactHooks, UxRelativeTime, Chip, Stack, groupBy, flatMap, uniqBy, trim, Avatar$1, BrokenImageIcon, react$1, Empty$3, Session, cmp, bridge, NotificationsActiveOutlinedIcon, Util, CheckboxPlugin, DIDAddress, MuiMenuItem, clsx, IconButton$1, MuiMenu, EditorHolderPlugin, Dialog, orderBy, Typography, Skeleton, ReactDOM, ufo, dayjs, relativeTime, joinUrl, mitt, CircularProgress, reactHelmet, reactFlipToolkit, grey, editor$1, Fab, debounce, useIsFocused, BusyPlugin, ArrowBackIosIcon, axios, Toast, MuiPagination, unstatedNext, Cookie, ws, css, OnContentChangePlugin, ShortcutPlugin$1, SafeAreaPlugin, text, ImageNode, VideoNode) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@blocklet/labels"), require("react/jsx-runtime"), require("@mui/material/styles"), require("@arcblock/ux/lib/Theme"), require("react"), require("@mui/material"), require("lodash/isNil"), require("@blocklet/editor/lib/config"), require("react-lazy-with-preload"), require("@lexical/react/LexicalComposerContext"), require("lexical"), require("ahooks"), require("@arcblock/ux/lib/Locale/context"), require("@mui/icons-material"), require("@mui/lab/LoadingButton"), require("@mui/material/Alert"), require("@mui/material/Box"), require("lodash/isBoolean"), require("@mui/material/Button"), require("@arcblock/did-connect/lib/Avatar"), require("@mui/material/AvatarGroup"), require("@mui/material/colors"), require("@mui/material/useMediaQuery"), require("@arcblock/ux/lib/DID"), require("@mui/material/Tooltip"), require("react-router-dom"), require("@arcblock/react-hooks"), require("@arcblock/ux/lib/RelativeTime"), require("@mui/material/Chip"), require("@mui/material/Stack"), require("lodash/groupBy"), require("lodash/flatMap"), require("lodash/uniqBy"), require("lodash/trim"), require("@mui/material/Avatar"), require("@mui/icons-material/BrokenImage"), require("@iconify/react"), require("@arcblock/ux/lib/Empty"), require("@arcblock/did-connect/lib/Session"), require("semver-compare"), require("@arcblock/bridge"), require("@mui/icons-material/NotificationsActiveOutlined"), require("@arcblock/ux/lib/Util"), require("@blocklet/editor/lib/ext/CheckboxPlugin"), require("@arcblock/did-connect/lib/Address"), require("@mui/material/MenuItem"), require("clsx"), require("@mui/material/IconButton"), require("@mui/material/Menu"), require("@blocklet/editor/lib/ext/EditorHolderPlugin"), require("@mui/material/colors/red"), require("@arcblock/ux/lib/Dialog"), require("lodash/orderBy"), require("@mui/material/Typography"), require("@mui/material/Skeleton"), require("react-dom"), require("ufo"), require("dayjs"), require("dayjs/plugin/relativeTime"), require("url-join"), require("mitt"), require("@mui/material/CircularProgress"), require("react-helmet"), require("react-flip-toolkit"), require("@mui/material/colors/grey"), require("@blocklet/editor"), require("@mui/material/Fab"), require("lodash/debounce"), require("@blocklet/editor/lib/main/hooks/useIsFocused"), require("@blocklet/editor/lib/ext/BusyPlugin"), require("@mui/icons-material/ArrowBackIos"), require("axios"), require("@arcblock/ux/lib/Toast"), require("@mui/material/Pagination"), require("unstated-next"), require("js-cookie"), require("@arcblock/ws"), require("@emotion/css"), require("@blocklet/editor/lib/ext/OnContentChangePlugin"), require("@blocklet/editor/lib/ext/ShortcutPlugin"), require("@blocklet/editor/lib/ext/SafeAreaPlugin"), require("@lexical/text"), require("@blocklet/editor/lib/main/nodes/ImageNode"), require("@blocklet/editor/lib/ext/VideoPlugin/VideoNode")) : typeof define === "function" && define.amd ? define(["exports", "@blocklet/labels", "react/jsx-runtime", "@mui/material/styles", "@arcblock/ux/lib/Theme", "react", "@mui/material", "lodash/isNil", "@blocklet/editor/lib/config", "react-lazy-with-preload", "@lexical/react/LexicalComposerContext", "lexical", "ahooks", "@arcblock/ux/lib/Locale/context", "@mui/icons-material", "@mui/lab/LoadingButton", "@mui/material/Alert", "@mui/material/Box", "lodash/isBoolean", "@mui/material/Button", "@arcblock/did-connect/lib/Avatar", "@mui/material/AvatarGroup", "@mui/material/colors", "@mui/material/useMediaQuery", "@arcblock/ux/lib/DID", "@mui/material/Tooltip", "react-router-dom", "@arcblock/react-hooks", "@arcblock/ux/lib/RelativeTime", "@mui/material/Chip", "@mui/material/Stack", "lodash/groupBy", "lodash/flatMap", "lodash/uniqBy", "lodash/trim", "@mui/material/Avatar", "@mui/icons-material/BrokenImage", "@iconify/react", "@arcblock/ux/lib/Empty", "@arcblock/did-connect/lib/Session", "semver-compare", "@arcblock/bridge", "@mui/icons-material/NotificationsActiveOutlined", "@arcblock/ux/lib/Util", "@blocklet/editor/lib/ext/CheckboxPlugin", "@arcblock/did-connect/lib/Address", "@mui/material/MenuItem", "clsx", "@mui/material/IconButton", "@mui/material/Menu", "@blocklet/editor/lib/ext/EditorHolderPlugin", "@mui/material/colors/red", "@arcblock/ux/lib/Dialog", "lodash/orderBy", "@mui/material/Typography", "@mui/material/Skeleton", "react-dom", "ufo", "dayjs", "dayjs/plugin/relativeTime", "url-join", "mitt", "@mui/material/CircularProgress", "react-helmet", "react-flip-toolkit", "@mui/material/colors/grey", "@blocklet/editor", "@mui/material/Fab", "lodash/debounce", "@blocklet/editor/lib/main/hooks/useIsFocused", "@blocklet/editor/lib/ext/BusyPlugin", "@mui/icons-material/ArrowBackIos", "axios", "@arcblock/ux/lib/Toast", "@mui/material/Pagination", "unstated-next", "js-cookie", "@arcblock/ws", "@emotion/css", "@blocklet/editor/lib/ext/OnContentChangePlugin", "@blocklet/editor/lib/ext/ShortcutPlugin", "@blocklet/editor/lib/ext/SafeAreaPlugin", "@lexical/text", "@blocklet/editor/lib/main/nodes/ImageNode", "@blocklet/editor/lib/ext/VideoPlugin/VideoNode"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.DiscussKitComponents = {}, global.labels, global.jsxRuntime, global.styles, global.Theme, global.react, global.material, global.isNil, global.config, global.reactLazyWithPreload, global.LexicalComposerContext, global.lexical$1, global.ahooks, global.context, global.iconsMaterial, global.LoadingButton, global.Alert, global.Box, global.isBoolean, global.Button, global.DidAvatar, global.AvatarGroup, global.colors, global.useMediaQuery, global.DID, global.Tooltip, global.reactRouterDom, global.reactHooks, global.UxRelativeTime, global.Chip, global.Stack, global.groupBy, global.flatMap, global.uniqBy, global.trim, global.Avatar$1, global.BrokenImageIcon, global.react$1, global.Empty$3, global.Session, global.cmp, global.bridge, global.NotificationsActiveOutlinedIcon, global.Util, global.CheckboxPlugin, global.DIDAddress, global.MuiMenuItem, global.clsx, global.IconButton$1, global.MuiMenu, global.EditorHolderPlugin, global.red, global.Dialog, global.orderBy, global.Typography, global.Skeleton, global.ReactDOM, global.ufo, global.dayjs, global.relativeTime, global.joinUrl, global.mitt, global.CircularProgress, global.reactHelmet, global.reactFlipToolkit, global.grey, global.editor$1, global.Fab, global.debounce, global.useIsFocused, global.BusyPlugin, global.ArrowBackIosIcon, global.axios, global.Toast, global.MuiPagination, global.unstatedNext, global.Cookie, global.ws, global.css, global.OnContentChangePlugin, global.ShortcutPlugin$1, global.SafeAreaPlugin, global.text, global.ImageNode, global.VideoNode));
3
+ })(this, function(exports2, labels, jsxRuntime, styles, Theme, react, material, isNil, config, reactLazyWithPreload, LexicalComposerContext, lexical$1, ahooks, context, iconsMaterial, LoadingButton, Alert, Box, isBoolean, Button, DidAvatar, AvatarGroup, colors, useMediaQuery, DID, Tooltip, reactRouterDom, reactHooks, UxRelativeTime, Chip, Stack, groupBy, flatMap, uniqBy, trim, Avatar$1, BrokenImageIcon, react$1, Empty$3, Session, cmp, bridge, NotificationsActiveOutlinedIcon, Util, CheckboxPlugin, DIDAddress, MuiMenuItem, clsx, IconButton$1, MuiMenu, EditorHolderPlugin, red, Dialog, orderBy, Typography, Skeleton, ReactDOM, ufo, dayjs, relativeTime, joinUrl, mitt, CircularProgress, reactHelmet, reactFlipToolkit, grey, editor$1, Fab, debounce, useIsFocused, BusyPlugin, ArrowBackIosIcon, axios, Toast, MuiPagination, unstatedNext, Cookie, ws, css, OnContentChangePlugin, ShortcutPlugin$1, SafeAreaPlugin, text, ImageNode, VideoNode) {
4
4
  "use strict";var __defProp = Object.defineProperty;
5
5
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
6
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -1728,6 +1728,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
1728
1728
  ] });
1729
1729
  }
1730
1730
  const tablerMessageCircle = (props) => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", "data-iconify": "tabler", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "m3 20l1.3-3.9C1.976 12.663 2.874 8.228 6.4 5.726c3.526-2.501 8.59-2.296 11.845.48c3.255 2.777 3.695 7.266 1.029 10.501S11.659 20.922 7.7 19z" }) });
1731
+ const tablerPinned = (props) => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", "data-iconify": "tabler", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 4v6l-2 4v2h10v-2l-2-4V4m-3 12v5M8 4h8" }) });
1731
1732
  const iconoirThumbsUp = (props) => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsxRuntime.jsxs("g", { fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeWidth: 1.5, children: [
1732
1733
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16.472 20H4.1a.6.6 0 0 1-.6-.6V9.6a.6.6 0 0 1 .6-.6h2.768a2 2 0 0 0 1.715-.971l2.71-4.517a1.631 1.631 0 0 1 2.961 1.308l-1.022 3.408a.6.6 0 0 0 .574.772h4.576a2 2 0 0 1 1.929 2.526l-1.91 7A2 2 0 0 1 16.473 20Z" }),
1733
1734
  /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinejoin: "round", d: "M7 20V9" })
@@ -2273,6 +2274,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2273
2274
  onRate,
2274
2275
  onUnrate,
2275
2276
  onReply,
2277
+ onTogglePin,
2276
2278
  onContentUpdate,
2277
2279
  onLoadMoreReplies,
2278
2280
  renderDonation,
@@ -2295,6 +2297,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2295
2297
  }
2296
2298
  };
2297
2299
  const customMenu = (items, { isAuthor, isAdmin, post }) => {
2300
+ if (isAdmin && !post.parentId) {
2301
+ items.push(
2302
+ /* @__PURE__ */ jsxRuntime.jsx(MuiMenuItem, { onClick: () => onTogglePin({ post, value: !post.pinnedAt }), children: t(post.pinnedAt ? "unpin" : "pin") }, "pin")
2303
+ );
2304
+ }
2298
2305
  if ((isAdmin || isAuthor) && !post.deletedAt) {
2299
2306
  items.push(
2300
2307
  /* @__PURE__ */ jsxRuntime.jsx(MuiMenuItem, { onClick: () => handleDelete(post), children: /* @__PURE__ */ jsxRuntime.jsx(Box, { component: "span", sx: { color: "error.main" }, children: t("delete") }) }, "delete")
@@ -2304,6 +2311,29 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2304
2311
  };
2305
2312
  const render = ({ post, interactive }) => {
2306
2313
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2314
+ post.pinnedAt && /* @__PURE__ */ jsxRuntime.jsx(Box, { sx: { display: "flex", alignItems: "end", gap: 3, mt: 1 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
2315
+ Box,
2316
+ {
2317
+ component: "span",
2318
+ sx: {
2319
+ display: "inline-flex",
2320
+ alignItems: "center",
2321
+ gap: 0.25,
2322
+ fontSize: 12,
2323
+ color: red[700],
2324
+ fontWeight: "bold",
2325
+ bgcolor: red[50],
2326
+ border: `1px solid ${red[100]}`,
2327
+ borderRadius: 1,
2328
+ px: 1.75,
2329
+ py: 0.25
2330
+ },
2331
+ children: [
2332
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { component: tablerPinned, sx: { fontSize: 12 } }),
2333
+ t("pinned")
2334
+ ]
2335
+ }
2336
+ ) }),
2307
2337
  /* @__PURE__ */ jsxRuntime.jsxs(Box, { sx: { display: "flex", alignItems: "end", gap: 3, mt: 1 }, children: [
2308
2338
  /* @__PURE__ */ jsxRuntime.jsx(
2309
2339
  GithubReaction,
@@ -2370,6 +2400,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2370
2400
  onRate,
2371
2401
  onUnrate,
2372
2402
  onReply,
2403
+ onTogglePin,
2373
2404
  onLoadMoreReplies,
2374
2405
  allowCopyLink: rest.allowCopyLink,
2375
2406
  showProfileCard: rest.showProfileCard,
@@ -2504,6 +2535,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2504
2535
  }) {
2505
2536
  var _a2;
2506
2537
  const [state, setState] = ahooks.useSetState(getInitialState(order ? { order } : {}));
2538
+ const comments = react.useMemo(() => state.comments.filter((item) => !item.pinnedAt), [state.comments]);
2539
+ const pinned = react.useMemo(() => state.comments.filter((item) => item.pinnedAt), [state.comments]);
2507
2540
  const containerHeight = (_a2 = ahooks.useSize(containerRef)) == null ? void 0 : _a2.height;
2508
2541
  const commentsKeyById = react.useMemo(() => {
2509
2542
  return state.comments.reduce((acc, cur) => {
@@ -2533,7 +2566,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2533
2566
  order: state.order,
2534
2567
  includeReplies: flatView ? 1 : null
2535
2568
  });
2536
- const [{ data, total, nextCursor }, positionRes] = await Promise.all([
2569
+ const [{ data, total, nextCursor }, positionRes, pinnedComments] = await Promise.all([
2537
2570
  api.fetchComments({
2538
2571
  objectId: target.id,
2539
2572
  limit,
@@ -2541,7 +2574,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2541
2574
  includeReplies: flatView ? 1 : null,
2542
2575
  initialRepliesLimit
2543
2576
  }),
2544
- highlightedRef.current ? fetchCommentPosition() : -1
2577
+ highlightedRef.current ? fetchCommentPosition() : -1,
2578
+ api.fetchPinnedComments(target.id)
2545
2579
  ]);
2546
2580
  let position = -1;
2547
2581
  let cursor = highlightedRef.current;
@@ -2562,7 +2596,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2562
2596
  initialRepliesLimit
2563
2597
  });
2564
2598
  setState({
2565
- comments: [...data, ...result.data],
2599
+ comments: [...data, ...result.data, ...pinnedComments],
2566
2600
  nextCursor,
2567
2601
  total,
2568
2602
  initialized: true,
@@ -2575,7 +2609,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2575
2609
  }
2576
2610
  });
2577
2611
  } else {
2578
- setState({ comments: data, nextCursor, total, initialized: true });
2612
+ setState({
2613
+ comments: [...data, ...pinnedComments],
2614
+ nextCursor,
2615
+ total,
2616
+ initialized: true
2617
+ });
2579
2618
  }
2580
2619
  };
2581
2620
  init();
@@ -2680,11 +2719,17 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2680
2719
  const result = await api.reply(post, content);
2681
2720
  setTimeout(() => add(result), 800);
2682
2721
  };
2722
+ const togglePin = async ({ post, value: value2 }) => {
2723
+ await api.togglePin({ post, value: value2 });
2724
+ updateCommentState(post.id, (current) => ({ ...current, pinnedAt: value2 ? /* @__PURE__ */ new Date() : null }));
2725
+ };
2683
2726
  const findById = (id2) => commentsKeyById[id2];
2684
2727
  const value = react.useMemo(
2685
2728
  () => ({
2686
2729
  target,
2687
2730
  state,
2731
+ pinned,
2732
+ comments,
2688
2733
  flatView,
2689
2734
  autoCollapse,
2690
2735
  allowCopyLink,
@@ -2699,6 +2744,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2699
2744
  updateComment,
2700
2745
  deleteComment,
2701
2746
  reply,
2747
+ togglePin,
2702
2748
  loadMoreReplies,
2703
2749
  findById,
2704
2750
  renderComments,
@@ -2730,6 +2776,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2730
2776
  updateComment,
2731
2777
  deleteComment,
2732
2778
  reply,
2779
+ togglePin,
2733
2780
  loadMoreReplies,
2734
2781
  api
2735
2782
  } = useCommentsContext();
@@ -2775,6 +2822,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2775
2822
  onRate: api.rate,
2776
2823
  onUnrate: api.unrate,
2777
2824
  onReply: reply,
2825
+ onTogglePin: togglePin,
2778
2826
  onLoadMoreReplies: loadMoreReplies,
2779
2827
  autoCollapse,
2780
2828
  allowCopyLink,
@@ -2800,7 +2848,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2800
2848
  function CommentList(props) {
2801
2849
  const { t } = context.useLocaleContext();
2802
2850
  const {
2803
- state: { comments, order, nextCursor, highlighted },
2851
+ state: { order, nextCursor, highlighted },
2852
+ comments,
2853
+ pinned,
2804
2854
  autoCollapse,
2805
2855
  allowCopyLink,
2806
2856
  showProfileCard,
@@ -2809,6 +2859,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2809
2859
  updateComment,
2810
2860
  deleteComment,
2811
2861
  reply,
2862
+ togglePin,
2812
2863
  loadMoreReplies,
2813
2864
  api,
2814
2865
  renderComments,
@@ -2828,6 +2879,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2828
2879
  onRate: api.rate,
2829
2880
  onUnrate: api.unrate,
2830
2881
  onReply: reply,
2882
+ onTogglePin: togglePin,
2831
2883
  onLoadMoreReplies: loadMoreReplies,
2832
2884
  autoCollapse,
2833
2885
  allowCopyLink,
@@ -2840,7 +2892,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
2840
2892
  },
2841
2893
  comment.id
2842
2894
  );
2895
+ const sortedPinned = pinned.sort((a, b) => {
2896
+ var _a2, _b2;
2897
+ return (((_a2 = b.pinnedAt) == null ? void 0 : _a2.getTime()) ?? 0) - (((_b2 = a.pinnedAt) == null ? void 0 : _b2.getTime()) ?? 0);
2898
+ });
2843
2899
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { ...props, children: [
2900
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { children: sortedPinned.map((post) => renderComment(post, {})) }),
2844
2901
  renderComments ? renderComments({ order, comments, renderComment }) : comments == null ? void 0 : comments.map(renderComment),
2845
2902
  nextCursor && /* @__PURE__ */ jsxRuntime.jsx(Box, { sx: { my: 2, textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
2846
2903
  Button,
@@ -6117,7 +6174,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6117
6174
  mostRecent: "most recent",
6118
6175
  edited: "edited",
6119
6176
  created: "created"
6120
- }
6177
+ },
6178
+ pin: "Pin",
6179
+ unpin: "Unpin",
6180
+ pinned: "Pinned"
6121
6181
  };
6122
6182
  const zh = {
6123
6183
  cancel: "取消",
@@ -6208,7 +6268,10 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6208
6268
  mostRecent: "最近",
6209
6269
  edited: "编辑",
6210
6270
  created: "创建"
6211
- }
6271
+ },
6272
+ pin: "置顶",
6273
+ unpin: "取消置顶",
6274
+ pinned: "置顶"
6212
6275
  };
6213
6276
  const translations = { zh, en };
6214
6277
  const Lottie = Util.lazyRetry(() => import("lottie-react"));
package/dist/types.d.ts CHANGED
@@ -21,6 +21,7 @@ export interface Post {
21
21
  parentId?: string;
22
22
  rootId?: string;
23
23
  synced?: number;
24
+ pinnedAt?: Date | null;
24
25
  }
25
26
  export interface Target {
26
27
  id: string;
@@ -65,12 +66,17 @@ export type Rating = {
65
66
  export type FetchRatings = (id: string) => Promise<Rating[]>;
66
67
  export interface CommentAPI {
67
68
  fetchComments: FetchComments;
69
+ fetchPinnedComments: (id: string) => Promise<Post[]>;
68
70
  fetchCommentPosition: FetchCommentPosition;
69
71
  deleteComment: DeleteComment;
70
72
  updateComment: UpdateComment;
71
73
  rate: Rate;
72
74
  unrate: Unrate;
73
75
  reply: Reply;
76
+ togglePin: ({ post, value }: {
77
+ post: Post;
78
+ value: boolean;
79
+ }) => Promise<void>;
74
80
  }
75
81
  export type WithRequiredProperty<Type, Key extends keyof Type> = Type & {
76
82
  [Property in Key]-?: Type[Property];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/discuss-kit-ux",
3
- "version": "2.1.106",
3
+ "version": "2.1.108",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -44,8 +44,8 @@
44
44
  "ufo": "^1.5.4",
45
45
  "unstated-next": "^1.1.0",
46
46
  "url-join": "^4.0.1",
47
- "@blocklet/editor": "^2.1.106",
48
- "@blocklet/labels": "^2.1.106"
47
+ "@blocklet/editor": "^2.1.108",
48
+ "@blocklet/labels": "^2.1.108"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "@arcblock/did-connect": "^2.10.36",