@blocklet/discuss-kit-ux 2.0.65 → 2.0.67

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.
@@ -4,7 +4,7 @@ interface Props extends EditorProps {
4
4
  initialContent?: string;
5
5
  send: (content: string) => Promise<void>;
6
6
  onContentChange?: (content: string) => void;
7
- onInputFocus?: (v: boolean) => void;
7
+ onFocusChange?: (focused: boolean) => void;
8
8
  }
9
- export declare function ChatInput({ initialContent, send, onContentChange, onInputFocus }: Props): import("react/jsx-runtime").JSX.Element;
9
+ export declare function ChatInput({ initialContent, send, onContentChange, onFocusChange }: Props): import("react/jsx-runtime").JSX.Element;
10
10
  export {};
@@ -3,3 +3,4 @@ export { useChanged } from './changed';
3
3
  export { useNow } from './now';
4
4
  export { useInterval } from './interval';
5
5
  export { useDownBreakpoint, useUpBreakpoint } from './responsive';
6
+ export { useNotification } from './notification';
@@ -0,0 +1,9 @@
1
+ interface UseNotificationProps {
2
+ title: string;
3
+ options?: NotificationOptions;
4
+ onclick?: () => void;
5
+ }
6
+ export declare const useNotification: () => {
7
+ show: ({ title, options, onclick }: UseNotificationProps) => Promise<void>;
8
+ };
9
+ export {};
@@ -61,6 +61,7 @@ declare const _default: {
61
61
  mentionInPost: string;
62
62
  replyYourComment: string;
63
63
  replyComment: string;
64
+ newMsg: string;
64
65
  deleteChannelTitle: string;
65
66
  deleteChannelDesc: string;
66
67
  leaveChannel: string;
@@ -63,6 +63,7 @@ export declare const translations: {
63
63
  mentionInPost: string;
64
64
  replyYourComment: string;
65
65
  replyComment: string;
66
+ newMsg: string;
66
67
  deleteChannelTitle: string;
67
68
  deleteChannelDesc: string;
68
69
  leaveChannel: string;
@@ -150,6 +151,7 @@ export declare const translations: {
150
151
  mentionInPost: string;
151
152
  replyYourComment: string;
152
153
  replyComment: string;
154
+ newMsg: string;
153
155
  deleteChannelTitle: string;
154
156
  deleteChannelDesc: string;
155
157
  leaveChannel: string;
@@ -62,6 +62,7 @@ declare const _default: {
62
62
  mentionInPost: string;
63
63
  replyYourComment: string;
64
64
  replyComment: string;
65
+ newMsg: string;
65
66
  deleteChannelTitle: string;
66
67
  deleteChannelDesc: string;
67
68
  leaveChannel: string;
@@ -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-CGs-Yy3L.mjs";
7
+ import { i as inferInitialEditorState, I as ImagePathFixerPlugin, V as VideoPathFixerPlugin, a as isEmptyContent, s as stringify, g as getExcerptSync } from "./index-7KXsY2Zx.mjs";
8
8
  const BlockletEditor = lazy(() => import("@blocklet/editor"));
9
9
  const Root = styled(Box)`
10
10
  .be-editable,
@@ -1126,6 +1126,23 @@ const useResponsiveValue = (values2) => {
1126
1126
  const r = useResponsive();
1127
1127
  return r(values2);
1128
1128
  };
1129
+ const useNotification = () => {
1130
+ const show = async ({ title, options, onclick }) => {
1131
+ if (!("Notification" in window))
1132
+ return;
1133
+ if (Notification.permission === "granted") {
1134
+ const notification = new Notification(title, options);
1135
+ notification.onclick = onclick ?? null;
1136
+ return;
1137
+ }
1138
+ if (Notification.permission !== "denied") {
1139
+ const permission = await Notification.requestPermission();
1140
+ if (permission === "granted")
1141
+ show({ title, options, onclick });
1142
+ }
1143
+ };
1144
+ return { show };
1145
+ };
1129
1146
  function ProfileCard({ user, click, ...rest }) {
1130
1147
  var _a2, _b2, _c2;
1131
1148
  const { session } = useSessionContext();
@@ -1196,7 +1213,7 @@ function ProfileCard({ user, click, ...rest }) {
1196
1213
  /* @__PURE__ */ jsx(Box$1, { sx: { mt: 1 }, children: /* @__PURE__ */ jsx(Badge, { passports: (user == null ? void 0 : user.passports) || [], pointInfo: (user == null ? void 0 : user.pointInfo) || {}, did: user == null ? void 0 : user.did }) })
1197
1214
  ] })
1198
1215
  ] }),
1199
- chatUrl && ((_b2 = session == null ? void 0 : session.user) == null ? void 0 : _b2.did) && ((_c2 = session == null ? void 0 : session.user) == null ? void 0 : _c2.did) !== user.did && /* @__PURE__ */ jsxs(Fragment, { children: [
1216
+ chatUrl && (user == null ? void 0 : user.did) !== window.blocklet.appId && ((_b2 = session == null ? void 0 : session.user) == null ? void 0 : _b2.did) && ((_c2 = session == null ? void 0 : session.user) == null ? void 0 : _c2.did) !== user.did && /* @__PURE__ */ jsxs(Fragment, { children: [
1200
1217
  /* @__PURE__ */ jsx(Box$1, { sx: { my: 2, borderTop: "1px solid #eee" } }),
1201
1218
  /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(
1202
1219
  Button,
@@ -1312,9 +1329,10 @@ function AuthorInfo({
1312
1329
  createdAt = typeof createdAt === "string" ? new Date(createdAt) : createdAt;
1313
1330
  return /* @__PURE__ */ jsx(Box$1, { component: RelativeTime, sx: { color: "text.secondary" }, value: createdAt });
1314
1331
  };
1332
+ const canClick = linkToProfile && (user == null ? void 0 : user.did) && (user == null ? void 0 : user.did) !== window.blocklet.appId;
1315
1333
  const click = (e) => {
1316
1334
  var _a2, _b2;
1317
- if (!linkToProfile) {
1335
+ if (!canClick) {
1318
1336
  return;
1319
1337
  }
1320
1338
  (_a2 = e == null ? void 0 : e.stopPropagation) == null ? void 0 : _a2.call(e);
@@ -1338,20 +1356,27 @@ function AuthorInfo({
1338
1356
  onOpen: () => setOpen(true),
1339
1357
  PopperProps: { disablePortal: false },
1340
1358
  title: /* @__PURE__ */ jsx(ProfileCard, { user, click }),
1341
- children: /* @__PURE__ */ jsx(Box$1, { sx: { display: "flex", cursor: "pointer", width: avatarSize, height: avatarSize }, onClick: click, children: /* @__PURE__ */ jsx(
1342
- Avatar,
1359
+ children: /* @__PURE__ */ jsx(
1360
+ Box$1,
1343
1361
  {
1344
- did: user == null ? void 0 : user.did,
1345
- src: user == null ? void 0 : user.avatar,
1346
- size: avatarSize,
1347
- shape: "circle",
1348
- variant: "circle",
1349
- sx: {
1350
- width: "100%",
1351
- height: "100%"
1352
- }
1362
+ sx: { display: "flex", cursor: canClick ? "pointer" : "auto", width: avatarSize, height: avatarSize },
1363
+ onClick: click,
1364
+ children: /* @__PURE__ */ jsx(
1365
+ Avatar,
1366
+ {
1367
+ did: user == null ? void 0 : user.did,
1368
+ src: user == null ? void 0 : user.avatar,
1369
+ size: avatarSize,
1370
+ shape: "circle",
1371
+ variant: "circle",
1372
+ sx: {
1373
+ width: "100%",
1374
+ height: "100%"
1375
+ }
1376
+ }
1377
+ )
1353
1378
  }
1354
- ) })
1379
+ )
1355
1380
  }
1356
1381
  );
1357
1382
  }
@@ -3720,6 +3745,9 @@ function ChatProvider({ client: client2, activeChatId, children, isInWallet }) {
3720
3745
  activeChatId: void 0,
3721
3746
  error: void 0
3722
3747
  });
3748
+ const chatById = useMemo(() => {
3749
+ return state.chats.reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {});
3750
+ }, [state.chats]);
3723
3751
  const { markAsUnread } = useUnreadNotification();
3724
3752
  const navigate = useNavigate();
3725
3753
  const { session } = useSessionContext();
@@ -3931,9 +3959,42 @@ function ChatProvider({ client: client2, activeChatId, children, isInWallet }) {
3931
3959
  setState((prev) => ({ ...prev, activeChatId: void 0 }));
3932
3960
  }
3933
3961
  }, [state, activeChatId]);
3962
+ const { t } = useLocaleContext();
3963
+ const { show } = useNotification();
3964
+ const resolveChatNotification = (chatId, { id: id2, content, sender, type, link, sourceUser, comment, reply, post }) => {
3965
+ if (isInWallet || sender.did === currentUser.did)
3966
+ return;
3967
+ const chat = chatById[chatId];
3968
+ if (!chat)
3969
+ return;
3970
+ const isSystem = chat.type === "notification";
3971
+ const isChannel = chat.type === "channel";
3972
+ const getNotificationMeta = () => {
3973
+ const getOpener = (url) => () => window.open(url, "_blank");
3974
+ const getTitle = (i18nKey) => `${sourceUser == null ? void 0 : sourceUser.fullName} ${t(`chat.${i18nKey}`)}`;
3975
+ const onclick2 = getOpener(link);
3976
+ const map = {
3977
+ message: {
3978
+ title: `${t("chat.newMsg")} ${isChannel ? chat.name : sender.fullName}`,
3979
+ body: getExcerptFromLexicalContent(content),
3980
+ onclick: getOpener(joinURL("/chat", chatId))
3981
+ },
3982
+ comment: { title: getTitle("commentedYourPost"), body: comment == null ? void 0 : comment.excerpt, onclick: onclick2 },
3983
+ reply: { title: getTitle("replyYourComment"), body: reply == null ? void 0 : reply.excerpt, onclick: onclick2 },
3984
+ mentionInComment: { title: getTitle("mentionInComment"), body: comment == null ? void 0 : comment.excerpt, onclick: onclick2 },
3985
+ mentionInPost: { title: getTitle("mentionInPost"), body: post == null ? void 0 : post.excerpt, onclick: onclick2 }
3986
+ };
3987
+ return map[type];
3988
+ };
3989
+ const icon = isSystem ? sourceUser == null ? void 0 : sourceUser.avatar : sender.avatar;
3990
+ const { title, body, onclick } = getNotificationMeta();
3991
+ if (title)
3992
+ show({ title, onclick, options: { tag: id2, icon, body } });
3993
+ };
3934
3994
  useEffect(() => {
3935
3995
  const cancels = [
3936
3996
  client2.onMessage(({ chatId, message }) => {
3997
+ resolveChatNotification(chatId, message);
3937
3998
  addMessage(chatId, message);
3938
3999
  if (message.sender.did === (currentUser == null ? void 0 : currentUser.did)) {
3939
4000
  updateLastAckTime(chatId, true);
@@ -4741,7 +4802,7 @@ function Back({ url, fallbackUrl, iconOnly, sx, ...rest }) {
4741
4802
  }
4742
4803
  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" }) });
4743
4804
  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" }) });
4744
- const Editor = lazy(() => import("./editor-Bmjq1QtI.mjs"));
4805
+ const Editor = lazy(() => import("./editor-TZZey5Q7.mjs"));
4745
4806
  function LazyEditor(props) {
4746
4807
  const fallback2 = /* @__PURE__ */ jsxs(Box, { sx: { px: 3 }, children: [
4747
4808
  /* @__PURE__ */ jsx(Skeleton, {}),
@@ -4876,7 +4937,7 @@ function ShortcutPlugin({ callback }) {
4876
4937
  }, [editor, callback, mobile.any]);
4877
4938
  return null;
4878
4939
  }
4879
- function ChatInput({ initialContent, send, onContentChange, onInputFocus }) {
4940
+ function ChatInput({ initialContent, send, onContentChange, onFocusChange }) {
4880
4941
  const { t } = useLocaleContext();
4881
4942
  const [content, setContent] = useState("");
4882
4943
  const [lastSent, setLastSent] = useState(0);
@@ -4885,23 +4946,26 @@ function ChatInput({ initialContent, send, onContentChange, onInputFocus }) {
4885
4946
  });
4886
4947
  const { mobile } = useBrowser();
4887
4948
  const [focused, setFocused] = useState(false);
4888
- const onFocusWrapper = (v2) => {
4949
+ const FocusCallback = (v2) => {
4889
4950
  setFocused(v2);
4890
- onInputFocus == null ? void 0 : onInputFocus(v2);
4951
+ onFocusChange == null ? void 0 : onFocusChange(v2);
4891
4952
  };
4892
4953
  const onToolbarBtnMouseDown = (e) => {
4893
4954
  e.preventDefault();
4894
4955
  setToolbarVisible((x) => !x);
4895
4956
  };
4896
4957
  const compactView = mobile.any && !focused;
4897
- const handleSend = () => {
4898
- if (!content) {
4958
+ const handleSend = async () => {
4959
+ if (!content)
4899
4960
  return;
4900
- }
4901
- send(content);
4961
+ await send(content);
4902
4962
  setContent("");
4903
4963
  setLastSent(Date.now());
4904
4964
  };
4965
+ const onSendBtnMouseDown = (e) => {
4966
+ e.preventDefault();
4967
+ handleSend();
4968
+ };
4905
4969
  return /* @__PURE__ */ jsxs(
4906
4970
  Box,
4907
4971
  {
@@ -4977,7 +5041,7 @@ function ChatInput({ initialContent, send, onContentChange, onInputFocus }) {
4977
5041
  /* @__PURE__ */ jsx(AutoClearPlugin, { clearKey: lastSent }),
4978
5042
  /* @__PURE__ */ jsx(ShortcutPlugin, { callback: handleSend }),
4979
5043
  /* @__PURE__ */ jsx(DraggerPlugin, {}),
4980
- /* @__PURE__ */ jsx(FocusPlugin, { callback: onFocusWrapper })
5044
+ /* @__PURE__ */ jsx(FocusPlugin, { callback: FocusCallback })
4981
5045
  ]
4982
5046
  }
4983
5047
  ) })
@@ -5024,7 +5088,7 @@ function ChatInput({ initialContent, send, onContentChange, onInputFocus }) {
5024
5088
  color: "primary",
5025
5089
  variant: "contained",
5026
5090
  disabled: !content,
5027
- onClick: handleSend,
5091
+ onMouseDown: onSendBtnMouseDown,
5028
5092
  startIcon: /* @__PURE__ */ jsx(Box, { component: tablerSend, sx: { fontSize: "14px !important" } }),
5029
5093
  sx: { height: 28 },
5030
5094
  children: t("chat.send")
@@ -5077,9 +5141,10 @@ function ChatRoom({ chat, inWallet, ...rest }) {
5077
5141
  deleteChannel(chat.id);
5078
5142
  }
5079
5143
  };
5080
- const onInputFocus = () => {
5144
+ const onFocusChange = (focused) => {
5081
5145
  var _a3;
5082
- (_a3 = messageListRef.current) == null ? void 0 : _a3.scrollToBottom();
5146
+ if (downSm && focused)
5147
+ (_a3 = messageListRef.current) == null ? void 0 : _a3.scrollToBottom();
5083
5148
  };
5084
5149
  const renderRoomHeader = () => {
5085
5150
  if (chat.type === "notification") {
@@ -5182,7 +5247,7 @@ function ChatRoom({ chat, inWallet, ...rest }) {
5182
5247
  {
5183
5248
  initialContent: input,
5184
5249
  onContentChange: (v2) => setInput(v2),
5185
- onInputFocus,
5250
+ onFocusChange,
5186
5251
  send: (content) => sendMessage(chat.id, content)
5187
5252
  }
5188
5253
  ) }),
@@ -6193,6 +6258,7 @@ const en = {
6193
6258
  mentionInPost: "mentioned you in a post",
6194
6259
  replyYourComment: "replied to your comment",
6195
6260
  replyComment: "replied to a comment",
6261
+ newMsg: "New message from",
6196
6262
  deleteChannelTitle: "Delete this channel?",
6197
6263
  deleteChannelDesc: "If you delete this channel, all messages in the channel will be deleted immediately.",
6198
6264
  leaveChannel: "Leave channel",
@@ -6281,6 +6347,7 @@ const zh = {
6281
6347
  mentionInPost: "在帖子里提及了你",
6282
6348
  replyYourComment: "回复了你的评论",
6283
6349
  replyComment: "回复了评论",
6350
+ newMsg: "新消息来自",
6284
6351
  deleteChannelTitle: "确认删除这个频道?",
6285
6352
  deleteChannelDesc: "如果你要删除这个频道, 频道内所有的消息都会立刻消除。",
6286
6353
  leaveChannel: "离开频道",
@@ -12204,88 +12271,89 @@ function SegmentedControl({ value, options, onChange, sx, ...rest }) {
12204
12271
  ) });
12205
12272
  }
12206
12273
  export {
12207
- ChatHeaderAddon as $,
12274
+ ChatListInWallet as $,
12208
12275
  Avatar as A,
12209
12276
  Badge as B,
12210
12277
  CommentInput as C,
12211
12278
  DefaultEditorConfigProvider as D,
12212
- CommentsProvider as E,
12213
- BinaryThumb as F,
12214
- GithubReaction as G,
12215
- EmptyStatus as H,
12279
+ useCommentsContext as E,
12280
+ CommentsProvider as F,
12281
+ BinaryThumb as G,
12282
+ GithubReaction as H,
12216
12283
  ImagePathFixerPlugin as I,
12217
- BlogListWrapper as J,
12218
- BlogCard as K,
12219
- BlogPermaLink as L,
12284
+ EmptyStatus as J,
12285
+ BlogListWrapper as K,
12286
+ BlogCard as L,
12220
12287
  Menu as M,
12221
- getBlogLink as N,
12222
- CoverImage as O,
12288
+ BlogPermaLink as N,
12289
+ getBlogLink as O,
12223
12290
  Pagination as P,
12224
- CoverImageUpload as Q,
12291
+ CoverImage as Q,
12225
12292
  RelativeTime as R,
12226
12293
  ScrollableEditorWrapper as S,
12227
- AccessControl as T,
12228
- useAuthzContext as U,
12294
+ CoverImageUpload as T,
12295
+ AccessControl as U,
12229
12296
  VideoPathFixerPlugin as V,
12230
- AuthzProvider as W,
12231
- ChatClient as X,
12232
- Chat as Y,
12233
- ChatInWallet as Z,
12234
- ChatListInWallet as _,
12297
+ useAuthzContext as W,
12298
+ AuthzProvider as X,
12299
+ ChatClient as Y,
12300
+ Chat as Z,
12301
+ ChatInWallet as _,
12235
12302
  isEmptyContent as a,
12236
- useChatContext as a0,
12237
- ChatProvider as a1,
12238
- UnreadNotificationContext as a2,
12239
- useUnreadNotification as a3,
12240
- UnreadNotificationProvider as a4,
12241
- Confirm as a5,
12242
- ConfirmContext as a6,
12243
- useConfirm as a7,
12244
- ConfirmProvider as a8,
12245
- SecureLabelPicker as a9,
12246
- useApiErrorHandler as aa,
12247
- useDefaultApiErrorHandler as ab,
12248
- DefaultApiErrorHandler as ac,
12249
- Back as ad,
12250
- LazyEditor as ae,
12251
- EditorPreview as af,
12252
- DirtyPromptContainer as ag,
12253
- ConfirmNavigation as ah,
12254
- UploaderContext as ai,
12255
- useUploader as aj,
12256
- UploaderTrigger as ak,
12257
- UploaderProvider as al,
12258
- composeImageUrl as am,
12259
- usePointUpContext as an,
12260
- PointUpProvider as ao,
12261
- ButtonGroup as ap,
12262
- SegmentedControl as aq,
12263
- create as ar,
12264
- getWsClient as as,
12265
- useSubscription as at,
12303
+ ChatHeaderAddon as a0,
12304
+ useChatContext as a1,
12305
+ ChatProvider as a2,
12306
+ UnreadNotificationContext as a3,
12307
+ useUnreadNotification as a4,
12308
+ UnreadNotificationProvider as a5,
12309
+ Confirm as a6,
12310
+ ConfirmContext as a7,
12311
+ useConfirm as a8,
12312
+ ConfirmProvider as a9,
12313
+ SecureLabelPicker as aa,
12314
+ useApiErrorHandler as ab,
12315
+ useDefaultApiErrorHandler as ac,
12316
+ DefaultApiErrorHandler as ad,
12317
+ Back as ae,
12318
+ LazyEditor as af,
12319
+ EditorPreview as ag,
12320
+ DirtyPromptContainer as ah,
12321
+ ConfirmNavigation as ai,
12322
+ UploaderContext as aj,
12323
+ useUploader as ak,
12324
+ UploaderTrigger as al,
12325
+ UploaderProvider as am,
12326
+ composeImageUrl as an,
12327
+ usePointUpContext as ao,
12328
+ PointUpProvider as ap,
12329
+ ButtonGroup as aq,
12330
+ SegmentedControl as ar,
12331
+ create as as,
12332
+ getWsClient as at,
12333
+ useSubscription as au,
12266
12334
  Input as b,
12267
12335
  useChanged as c,
12268
12336
  useSessionContext as d,
12269
- utils as e,
12270
- preferences as f,
12337
+ useNotification as e,
12338
+ utils as f,
12271
12339
  getExcerptSync as g,
12272
- typography as h,
12340
+ preferences as h,
12273
12341
  inferInitialEditorState as i,
12274
- themeOverrides as j,
12275
- InternalThemeProvider as k,
12342
+ typography as j,
12343
+ themeOverrides as k,
12276
12344
  lexical as l,
12277
- Avatars as m,
12278
- AuthorInfo as n,
12279
- SystemUser as o,
12345
+ InternalThemeProvider as m,
12346
+ Avatars as n,
12347
+ AuthorInfo as o,
12280
12348
  preloadInput as p,
12281
- PostContent as q,
12349
+ SystemUser as q,
12282
12350
  routes as r,
12283
12351
  stringify as s,
12284
12352
  translations as t,
12285
12353
  useNow as u,
12286
- PostComponent as v,
12287
- Comment as w,
12288
- CommentList as x,
12289
- CommentsContext as y,
12290
- useCommentsContext as z
12354
+ PostContent as v,
12355
+ PostComponent as w,
12356
+ Comment as x,
12357
+ CommentList as y,
12358
+ CommentsContext as z
12291
12359
  };
package/dist/index.d.ts CHANGED
@@ -18,7 +18,7 @@ export * from './components/editor';
18
18
  export * as lexicalUtils from './components/lexical';
19
19
  export * from './components/dirty-prompt';
20
20
  export { translations } from './components/locale';
21
- export { useNow, useChanged, useSessionContext } from './components/hooks';
21
+ export { useNow, useChanged, useSessionContext, useNotification } from './components/hooks';
22
22
  export * as utils from './components/utils';
23
23
  export * as routes from './components/routes';
24
24
  export { default as preferences } from './preferences';
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, am, ar, N, as, l, f, p, r, j, t, h, aa, U, c, a0, z, a7, ab, u, an, d, at, a3, aj, e } from "./index-CGs-Yy3L.mjs";
2
+ import { U, o, X, A, n, ae, B, G, L, K, N, aq, Z, Y, a0, _, $, a2, x, C, y, z, F, a6, a7, ai, a9, Q, T, ad, D, ah, ag, J, H, b, m, af, M, P, ap, w, v, R, S, aa, ar, q, a3, a5, aj, am, al, an, as, O, at, l, h, p, r, k, t, j, ab, W, c, a1, E, a8, ac, e, u, ao, d, au, a4, ak, f } from "./index-7KXsY2Zx.mjs";
3
3
  import "react/jsx-runtime";
4
4
  import "react";
5
5
  import "@mui/material/Box";
@@ -9,82 +9,83 @@ import "@mui/icons-material";
9
9
  import "@arcblock/ux/lib/Locale/context";
10
10
  import "@mui/material";
11
11
  export {
12
- T as AccessControl,
13
- n as AuthorInfo,
14
- W as AuthzProvider,
12
+ U as AccessControl,
13
+ o as AuthorInfo,
14
+ X as AuthzProvider,
15
15
  A as Avatar,
16
- m as Avatars,
17
- ad as Back,
16
+ n as Avatars,
17
+ ae as Back,
18
18
  B as Badge,
19
- F as BinaryThumb,
20
- K as BlogCard,
21
- J as BlogList,
22
- L as BlogPermaLink,
23
- ap as ButtonGroup,
24
- Y as Chat,
25
- X as ChatClient,
26
- $ as ChatHeaderAddon,
27
- Z as ChatInWallet,
28
- _ as ChatListInWallet,
29
- a1 as ChatProvider,
30
- w as Comment,
19
+ G as BinaryThumb,
20
+ L as BlogCard,
21
+ K as BlogList,
22
+ N as BlogPermaLink,
23
+ aq as ButtonGroup,
24
+ Z as Chat,
25
+ Y as ChatClient,
26
+ a0 as ChatHeaderAddon,
27
+ _ as ChatInWallet,
28
+ $ as ChatListInWallet,
29
+ a2 as ChatProvider,
30
+ x as Comment,
31
31
  C as CommentInput,
32
- x as CommentList,
33
- y as CommentsContext,
34
- E as CommentsProvider,
35
- a5 as Confirm,
36
- a6 as ConfirmContext,
37
- ah as ConfirmNavigation,
38
- a8 as ConfirmProvider,
39
- O as CoverImage,
40
- Q as CoverImageUpload,
41
- ac as DefaultApiErrorHandler,
32
+ y as CommentList,
33
+ z as CommentsContext,
34
+ F as CommentsProvider,
35
+ a6 as Confirm,
36
+ a7 as ConfirmContext,
37
+ ai as ConfirmNavigation,
38
+ a9 as ConfirmProvider,
39
+ Q as CoverImage,
40
+ T as CoverImageUpload,
41
+ ad as DefaultApiErrorHandler,
42
42
  D as DefaultEditorConfigProvider,
43
- ag as DirtyPromptContainer,
44
- af as EditorPreview,
45
- H as EmptyStatus,
46
- G as GithubReaction,
43
+ ah as DirtyPromptContainer,
44
+ ag as EditorPreview,
45
+ J as EmptyStatus,
46
+ H as GithubReaction,
47
47
  b as Input,
48
- k as InternalThemeProvider,
49
- ae as LazyEditor,
48
+ m as InternalThemeProvider,
49
+ af as LazyEditor,
50
50
  M as Menu,
51
51
  P as Pagination,
52
- ao as PointUpProvider,
53
- v as Post,
54
- q as PostContent,
52
+ ap as PointUpProvider,
53
+ w as Post,
54
+ v as PostContent,
55
55
  R as RelativeTime,
56
56
  S as ScrollableEditorWrapper,
57
- a9 as SecureLabelPicker,
58
- aq as SegmentedControl,
59
- o as SystemUser,
60
- a2 as UnreadNotificationContext,
61
- a4 as UnreadNotificationProvider,
62
- ai as UploaderContext,
63
- al as UploaderProvider,
64
- ak as UploaderTrigger,
65
- am as composeImageUrl,
66
- ar as create,
67
- N as getBlogLink,
68
- as as getWsClient,
57
+ aa as SecureLabelPicker,
58
+ ar as SegmentedControl,
59
+ q as SystemUser,
60
+ a3 as UnreadNotificationContext,
61
+ a5 as UnreadNotificationProvider,
62
+ aj as UploaderContext,
63
+ am as UploaderProvider,
64
+ al as UploaderTrigger,
65
+ an as composeImageUrl,
66
+ as as create,
67
+ O as getBlogLink,
68
+ at as getWsClient,
69
69
  l as lexicalUtils,
70
- f as preferences,
70
+ h as preferences,
71
71
  p as preloadInput,
72
72
  r as routes,
73
- j as themeOverrides,
73
+ k as themeOverrides,
74
74
  t as translations,
75
- h as typography,
76
- aa as useApiErrorHandler,
77
- U as useAuthzContext,
75
+ j as typography,
76
+ ab as useApiErrorHandler,
77
+ W as useAuthzContext,
78
78
  c as useChanged,
79
- a0 as useChatContext,
80
- z as useCommentsContext,
81
- a7 as useConfirm,
82
- ab as useDefaultApiErrorHandler,
79
+ a1 as useChatContext,
80
+ E as useCommentsContext,
81
+ a8 as useConfirm,
82
+ ac as useDefaultApiErrorHandler,
83
+ e as useNotification,
83
84
  u as useNow,
84
- an as usePointUpContext,
85
+ ao as usePointUpContext,
85
86
  d as useSessionContext,
86
- at as useSubscription,
87
- a3 as useUnreadNotification,
88
- aj as useUploader,
89
- e as utils
87
+ au as useSubscription,
88
+ a4 as useUnreadNotification,
89
+ ak as useUploader,
90
+ f as utils
90
91
  };
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("@mui/material/Box"), require("@mui/lab/LoadingButton"), require("@mui/icons-material"), require("@arcblock/ux/lib/Locale/context"), require("@mui/material/Alert"), 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("@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("@arcblock/ux/lib/Dialog"), require("lodash/orderBy"), require("@mui/material/Typography"), require("@mui/material/Skeleton"), require("react-dom"), require("url-join"), require("dayjs"), require("dayjs/plugin/relativeTime"), 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("@mui/material/TextField"), require("@mui/icons-material/Add"), 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("ufo"), 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", "@mui/material/Box", "@mui/lab/LoadingButton", "@mui/icons-material", "@arcblock/ux/lib/Locale/context", "@mui/material/Alert", "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", "@blocklet/editor/lib/ext/CheckboxPlugin", "@arcblock/did-connect/lib/Address", "@mui/material/MenuItem", "clsx", "@mui/material/IconButton", "@mui/material/Menu", "@arcblock/ux/lib/Dialog", "lodash/orderBy", "@mui/material/Typography", "@mui/material/Skeleton", "react-dom", "url-join", "dayjs", "dayjs/plugin/relativeTime", "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", "@mui/material/TextField", "@mui/icons-material/Add", "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", "ufo", "@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.Box, global.LoadingButton, global.iconsMaterial, global.context, global.Alert, 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.CheckboxPlugin, global.DIDAddress, global.MuiMenuItem, global.clsx, global.IconButton$1, global.MuiMenu, global.Dialog, global.orderBy, global.Typography, global.Skeleton, global.ReactDOM, global.joinUrl, global.dayjs, global.relativeTime, global.mitt, global.CircularProgress, global.reactHelmet, global.reactFlipToolkit, global.grey, global.editor$1, global.Fab, global.debounce, global.useIsFocused, global.TextField, global.AddIcon, global.axios, global.Toast, global.MuiPagination, global.unstatedNext, global.Cookie, global.ws, global.css, global.OnContentChangePlugin, global.ShortcutPlugin$1, global.SafeAreaPlugin, global.text, global.ufo, global.ImageNode, global.VideoNode));
3
- })(this, function(exports2, labels, jsxRuntime, styles, Theme, react, material, isNil, config, reactLazyWithPreload, LexicalComposerContext, lexical$1, ahooks, Box, LoadingButton, iconsMaterial, context, Alert, 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, CheckboxPlugin, DIDAddress, MuiMenuItem, clsx, IconButton$1, MuiMenu, Dialog, orderBy, Typography, Skeleton, ReactDOM, joinUrl, dayjs, relativeTime, mitt, CircularProgress, reactHelmet, reactFlipToolkit, grey, editor$1, Fab, debounce, useIsFocused, TextField, AddIcon, axios, Toast, MuiPagination, unstatedNext, Cookie, ws, css, OnContentChangePlugin, ShortcutPlugin$1, SafeAreaPlugin, text, ufo, 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("@mui/material/Box"), require("@mui/lab/LoadingButton"), require("@mui/icons-material"), require("@arcblock/ux/lib/Locale/context"), require("@mui/material/Alert"), 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("@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("@arcblock/ux/lib/Dialog"), require("lodash/orderBy"), require("@mui/material/Typography"), require("@mui/material/Skeleton"), require("react-dom"), require("url-join"), require("dayjs"), require("dayjs/plugin/relativeTime"), require("mitt"), require("@mui/material/CircularProgress"), require("react-helmet"), require("react-flip-toolkit"), require("@mui/material/colors/grey"), require("ufo"), require("@blocklet/editor"), require("@mui/material/Fab"), require("lodash/debounce"), require("@blocklet/editor/lib/main/hooks/useIsFocused"), require("@mui/material/TextField"), require("@mui/icons-material/Add"), 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", "@mui/material/Box", "@mui/lab/LoadingButton", "@mui/icons-material", "@arcblock/ux/lib/Locale/context", "@mui/material/Alert", "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", "@blocklet/editor/lib/ext/CheckboxPlugin", "@arcblock/did-connect/lib/Address", "@mui/material/MenuItem", "clsx", "@mui/material/IconButton", "@mui/material/Menu", "@arcblock/ux/lib/Dialog", "lodash/orderBy", "@mui/material/Typography", "@mui/material/Skeleton", "react-dom", "url-join", "dayjs", "dayjs/plugin/relativeTime", "mitt", "@mui/material/CircularProgress", "react-helmet", "react-flip-toolkit", "@mui/material/colors/grey", "ufo", "@blocklet/editor", "@mui/material/Fab", "lodash/debounce", "@blocklet/editor/lib/main/hooks/useIsFocused", "@mui/material/TextField", "@mui/icons-material/Add", "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.Box, global.LoadingButton, global.iconsMaterial, global.context, global.Alert, 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.CheckboxPlugin, global.DIDAddress, global.MuiMenuItem, global.clsx, global.IconButton$1, global.MuiMenu, global.Dialog, global.orderBy, global.Typography, global.Skeleton, global.ReactDOM, global.joinUrl, global.dayjs, global.relativeTime, global.mitt, global.CircularProgress, global.reactHelmet, global.reactFlipToolkit, global.grey, global.ufo, global.editor$1, global.Fab, global.debounce, global.useIsFocused, global.TextField, global.AddIcon, 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, Box, LoadingButton, iconsMaterial, context, Alert, 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, CheckboxPlugin, DIDAddress, MuiMenuItem, clsx, IconButton$1, MuiMenu, Dialog, orderBy, Typography, Skeleton, ReactDOM, joinUrl, dayjs, relativeTime, mitt, CircularProgress, reactHelmet, reactFlipToolkit, grey, ufo, editor$1, Fab, debounce, useIsFocused, TextField, AddIcon, 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) => {
@@ -1052,6 +1052,23 @@ var __publicField = (obj, key, value) => {
1052
1052
  const r = useResponsive();
1053
1053
  return r(values2);
1054
1054
  };
1055
+ const useNotification = () => {
1056
+ const show = async ({ title, options, onclick }) => {
1057
+ if (!("Notification" in window))
1058
+ return;
1059
+ if (Notification.permission === "granted") {
1060
+ const notification = new Notification(title, options);
1061
+ notification.onclick = onclick ?? null;
1062
+ return;
1063
+ }
1064
+ if (Notification.permission !== "denied") {
1065
+ const permission = await Notification.requestPermission();
1066
+ if (permission === "granted")
1067
+ show({ title, options, onclick });
1068
+ }
1069
+ };
1070
+ return { show };
1071
+ };
1055
1072
  function ProfileCard({ user, click, ...rest }) {
1056
1073
  var _a2, _b2, _c2;
1057
1074
  const { session } = useSessionContext();
@@ -1122,7 +1139,7 @@ var __publicField = (obj, key, value) => {
1122
1139
  /* @__PURE__ */ jsxRuntime.jsx(Box, { sx: { mt: 1 }, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { passports: (user == null ? void 0 : user.passports) || [], pointInfo: (user == null ? void 0 : user.pointInfo) || {}, did: user == null ? void 0 : user.did }) })
1123
1140
  ] })
1124
1141
  ] }),
1125
- chatUrl && ((_b2 = session == null ? void 0 : session.user) == null ? void 0 : _b2.did) && ((_c2 = session == null ? void 0 : session.user) == null ? void 0 : _c2.did) !== user.did && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1142
+ chatUrl && (user == null ? void 0 : user.did) !== window.blocklet.appId && ((_b2 = session == null ? void 0 : session.user) == null ? void 0 : _b2.did) && ((_c2 = session == null ? void 0 : session.user) == null ? void 0 : _c2.did) !== user.did && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1126
1143
  /* @__PURE__ */ jsxRuntime.jsx(Box, { sx: { my: 2, borderTop: "1px solid #eee" } }),
1127
1144
  /* @__PURE__ */ jsxRuntime.jsx(Box, { children: /* @__PURE__ */ jsxRuntime.jsx(
1128
1145
  Button,
@@ -1238,9 +1255,10 @@ var __publicField = (obj, key, value) => {
1238
1255
  createdAt = typeof createdAt === "string" ? new Date(createdAt) : createdAt;
1239
1256
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { component: RelativeTime, sx: { color: "text.secondary" }, value: createdAt });
1240
1257
  };
1258
+ const canClick = linkToProfile && (user == null ? void 0 : user.did) && (user == null ? void 0 : user.did) !== window.blocklet.appId;
1241
1259
  const click = (e) => {
1242
1260
  var _a2, _b2;
1243
- if (!linkToProfile) {
1261
+ if (!canClick) {
1244
1262
  return;
1245
1263
  }
1246
1264
  (_a2 = e == null ? void 0 : e.stopPropagation) == null ? void 0 : _a2.call(e);
@@ -1264,20 +1282,27 @@ var __publicField = (obj, key, value) => {
1264
1282
  onOpen: () => setOpen(true),
1265
1283
  PopperProps: { disablePortal: false },
1266
1284
  title: /* @__PURE__ */ jsxRuntime.jsx(ProfileCard, { user, click }),
1267
- children: /* @__PURE__ */ jsxRuntime.jsx(Box, { sx: { display: "flex", cursor: "pointer", width: avatarSize, height: avatarSize }, onClick: click, children: /* @__PURE__ */ jsxRuntime.jsx(
1268
- Avatar,
1285
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1286
+ Box,
1269
1287
  {
1270
- did: user == null ? void 0 : user.did,
1271
- src: user == null ? void 0 : user.avatar,
1272
- size: avatarSize,
1273
- shape: "circle",
1274
- variant: "circle",
1275
- sx: {
1276
- width: "100%",
1277
- height: "100%"
1278
- }
1288
+ sx: { display: "flex", cursor: canClick ? "pointer" : "auto", width: avatarSize, height: avatarSize },
1289
+ onClick: click,
1290
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1291
+ Avatar,
1292
+ {
1293
+ did: user == null ? void 0 : user.did,
1294
+ src: user == null ? void 0 : user.avatar,
1295
+ size: avatarSize,
1296
+ shape: "circle",
1297
+ variant: "circle",
1298
+ sx: {
1299
+ width: "100%",
1300
+ height: "100%"
1301
+ }
1302
+ }
1303
+ )
1279
1304
  }
1280
- ) })
1305
+ )
1281
1306
  }
1282
1307
  );
1283
1308
  }
@@ -3646,6 +3671,9 @@ var __publicField = (obj, key, value) => {
3646
3671
  activeChatId: void 0,
3647
3672
  error: void 0
3648
3673
  });
3674
+ const chatById = react.useMemo(() => {
3675
+ return state.chats.reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {});
3676
+ }, [state.chats]);
3649
3677
  const { markAsUnread } = useUnreadNotification();
3650
3678
  const navigate = reactRouterDom.useNavigate();
3651
3679
  const { session } = useSessionContext();
@@ -3857,9 +3885,42 @@ var __publicField = (obj, key, value) => {
3857
3885
  setState((prev) => ({ ...prev, activeChatId: void 0 }));
3858
3886
  }
3859
3887
  }, [state, activeChatId]);
3888
+ const { t } = context.useLocaleContext();
3889
+ const { show } = useNotification();
3890
+ const resolveChatNotification = (chatId, { id: id2, content, sender, type, link, sourceUser, comment, reply, post }) => {
3891
+ if (isInWallet || sender.did === currentUser.did)
3892
+ return;
3893
+ const chat = chatById[chatId];
3894
+ if (!chat)
3895
+ return;
3896
+ const isSystem = chat.type === "notification";
3897
+ const isChannel = chat.type === "channel";
3898
+ const getNotificationMeta = () => {
3899
+ const getOpener = (url) => () => window.open(url, "_blank");
3900
+ const getTitle = (i18nKey) => `${sourceUser == null ? void 0 : sourceUser.fullName} ${t(`chat.${i18nKey}`)}`;
3901
+ const onclick2 = getOpener(link);
3902
+ const map = {
3903
+ message: {
3904
+ title: `${t("chat.newMsg")} ${isChannel ? chat.name : sender.fullName}`,
3905
+ body: getExcerptFromLexicalContent(content),
3906
+ onclick: getOpener(ufo.joinURL("/chat", chatId))
3907
+ },
3908
+ comment: { title: getTitle("commentedYourPost"), body: comment == null ? void 0 : comment.excerpt, onclick: onclick2 },
3909
+ reply: { title: getTitle("replyYourComment"), body: reply == null ? void 0 : reply.excerpt, onclick: onclick2 },
3910
+ mentionInComment: { title: getTitle("mentionInComment"), body: comment == null ? void 0 : comment.excerpt, onclick: onclick2 },
3911
+ mentionInPost: { title: getTitle("mentionInPost"), body: post == null ? void 0 : post.excerpt, onclick: onclick2 }
3912
+ };
3913
+ return map[type];
3914
+ };
3915
+ const icon = isSystem ? sourceUser == null ? void 0 : sourceUser.avatar : sender.avatar;
3916
+ const { title, body, onclick } = getNotificationMeta();
3917
+ if (title)
3918
+ show({ title, onclick, options: { tag: id2, icon, body } });
3919
+ };
3860
3920
  react.useEffect(() => {
3861
3921
  const cancels = [
3862
3922
  client2.onMessage(({ chatId, message }) => {
3923
+ resolveChatNotification(chatId, message);
3863
3924
  addMessage(chatId, message);
3864
3925
  if (message.sender.did === (currentUser == null ? void 0 : currentUser.did)) {
3865
3926
  updateLastAckTime(chatId, true);
@@ -4802,7 +4863,7 @@ var __publicField = (obj, key, value) => {
4802
4863
  }, [editor2, callback, mobile.any]);
4803
4864
  return null;
4804
4865
  }
4805
- function ChatInput({ initialContent, send, onContentChange, onInputFocus }) {
4866
+ function ChatInput({ initialContent, send, onContentChange, onFocusChange }) {
4806
4867
  const { t } = context.useLocaleContext();
4807
4868
  const [content, setContent] = react.useState("");
4808
4869
  const [lastSent, setLastSent] = react.useState(0);
@@ -4811,23 +4872,26 @@ var __publicField = (obj, key, value) => {
4811
4872
  });
4812
4873
  const { mobile } = reactHooks.useBrowser();
4813
4874
  const [focused, setFocused] = react.useState(false);
4814
- const onFocusWrapper = (v2) => {
4875
+ const FocusCallback = (v2) => {
4815
4876
  setFocused(v2);
4816
- onInputFocus == null ? void 0 : onInputFocus(v2);
4877
+ onFocusChange == null ? void 0 : onFocusChange(v2);
4817
4878
  };
4818
4879
  const onToolbarBtnMouseDown = (e) => {
4819
4880
  e.preventDefault();
4820
4881
  setToolbarVisible((x) => !x);
4821
4882
  };
4822
4883
  const compactView = mobile.any && !focused;
4823
- const handleSend = () => {
4824
- if (!content) {
4884
+ const handleSend = async () => {
4885
+ if (!content)
4825
4886
  return;
4826
- }
4827
- send(content);
4887
+ await send(content);
4828
4888
  setContent("");
4829
4889
  setLastSent(Date.now());
4830
4890
  };
4891
+ const onSendBtnMouseDown = (e) => {
4892
+ e.preventDefault();
4893
+ handleSend();
4894
+ };
4831
4895
  return /* @__PURE__ */ jsxRuntime.jsxs(
4832
4896
  material.Box,
4833
4897
  {
@@ -4903,7 +4967,7 @@ var __publicField = (obj, key, value) => {
4903
4967
  /* @__PURE__ */ jsxRuntime.jsx(AutoClearPlugin, { clearKey: lastSent }),
4904
4968
  /* @__PURE__ */ jsxRuntime.jsx(ShortcutPlugin, { callback: handleSend }),
4905
4969
  /* @__PURE__ */ jsxRuntime.jsx(DraggerPlugin, {}),
4906
- /* @__PURE__ */ jsxRuntime.jsx(FocusPlugin, { callback: onFocusWrapper })
4970
+ /* @__PURE__ */ jsxRuntime.jsx(FocusPlugin, { callback: FocusCallback })
4907
4971
  ]
4908
4972
  }
4909
4973
  ) })
@@ -4950,7 +5014,7 @@ var __publicField = (obj, key, value) => {
4950
5014
  color: "primary",
4951
5015
  variant: "contained",
4952
5016
  disabled: !content,
4953
- onClick: handleSend,
5017
+ onMouseDown: onSendBtnMouseDown,
4954
5018
  startIcon: /* @__PURE__ */ jsxRuntime.jsx(material.Box, { component: tablerSend, sx: { fontSize: "14px !important" } }),
4955
5019
  sx: { height: 28 },
4956
5020
  children: t("chat.send")
@@ -5003,9 +5067,10 @@ var __publicField = (obj, key, value) => {
5003
5067
  deleteChannel(chat.id);
5004
5068
  }
5005
5069
  };
5006
- const onInputFocus = () => {
5070
+ const onFocusChange = (focused) => {
5007
5071
  var _a3;
5008
- (_a3 = messageListRef.current) == null ? void 0 : _a3.scrollToBottom();
5072
+ if (downSm && focused)
5073
+ (_a3 = messageListRef.current) == null ? void 0 : _a3.scrollToBottom();
5009
5074
  };
5010
5075
  const renderRoomHeader = () => {
5011
5076
  if (chat.type === "notification") {
@@ -5108,7 +5173,7 @@ var __publicField = (obj, key, value) => {
5108
5173
  {
5109
5174
  initialContent: input,
5110
5175
  onContentChange: (v2) => setInput(v2),
5111
- onInputFocus,
5176
+ onFocusChange,
5112
5177
  send: (content) => sendMessage(chat.id, content)
5113
5178
  }
5114
5179
  ) }),
@@ -6119,6 +6184,7 @@ var __publicField = (obj, key, value) => {
6119
6184
  mentionInPost: "mentioned you in a post",
6120
6185
  replyYourComment: "replied to your comment",
6121
6186
  replyComment: "replied to a comment",
6187
+ newMsg: "New message from",
6122
6188
  deleteChannelTitle: "Delete this channel?",
6123
6189
  deleteChannelDesc: "If you delete this channel, all messages in the channel will be deleted immediately.",
6124
6190
  leaveChannel: "Leave channel",
@@ -6207,6 +6273,7 @@ var __publicField = (obj, key, value) => {
6207
6273
  mentionInPost: "在帖子里提及了你",
6208
6274
  replyYourComment: "回复了你的评论",
6209
6275
  replyComment: "回复了评论",
6276
+ newMsg: "新消息来自",
6210
6277
  deleteChannelTitle: "确认删除这个频道?",
6211
6278
  deleteChannelDesc: "如果你要删除这个频道, 频道内所有的消息都会立刻消除。",
6212
6279
  leaveChannel: "离开频道",
@@ -12239,6 +12306,7 @@ var __publicField = (obj, key, value) => {
12239
12306
  exports2.useCommentsContext = useCommentsContext;
12240
12307
  exports2.useConfirm = useConfirm;
12241
12308
  exports2.useDefaultApiErrorHandler = useDefaultApiErrorHandler;
12309
+ exports2.useNotification = useNotification;
12242
12310
  exports2.useNow = useNow;
12243
12311
  exports2.usePointUpContext = usePointUpContext;
12244
12312
  exports2.useSessionContext = useSessionContext;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/discuss-kit-ux",
3
- "version": "2.0.65",
3
+ "version": "2.0.67",
4
4
  "files": [
5
5
  "dist"
6
6
  ],
@@ -31,8 +31,8 @@
31
31
  "@arcblock/bridge": "^2.10.5",
32
32
  "@arcblock/react-hooks": "^2.10.5",
33
33
  "@arcblock/ws": "^1.18.126",
34
- "@blocklet/editor": "2.0.65",
35
- "@blocklet/labels": "2.0.65",
34
+ "@blocklet/editor": "2.0.67",
35
+ "@blocklet/labels": "2.0.67",
36
36
  "@blocklet/uploader": "^0.1.19",
37
37
  "@emotion/css": "^11.10.5",
38
38
  "@emotion/react": "^11.10.5",
@@ -100,5 +100,5 @@
100
100
  "resolutions": {
101
101
  "react": "^18.2.0"
102
102
  },
103
- "gitHead": "3e7d1e73283113ea9c13fbc5d33fffaf001640db"
103
+ "gitHead": "138f22fa2ed3d57c2a184c6db5b083fa3b9d8749"
104
104
  }