@blocklet/discuss-kit-ux 2.0.66 → 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-BHaorx7Z.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();
@@ -3728,6 +3745,9 @@ function ChatProvider({ client: client2, activeChatId, children, isInWallet }) {
3728
3745
  activeChatId: void 0,
3729
3746
  error: void 0
3730
3747
  });
3748
+ const chatById = useMemo(() => {
3749
+ return state.chats.reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {});
3750
+ }, [state.chats]);
3731
3751
  const { markAsUnread } = useUnreadNotification();
3732
3752
  const navigate = useNavigate();
3733
3753
  const { session } = useSessionContext();
@@ -3939,9 +3959,42 @@ function ChatProvider({ client: client2, activeChatId, children, isInWallet }) {
3939
3959
  setState((prev) => ({ ...prev, activeChatId: void 0 }));
3940
3960
  }
3941
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
+ };
3942
3994
  useEffect(() => {
3943
3995
  const cancels = [
3944
3996
  client2.onMessage(({ chatId, message }) => {
3997
+ resolveChatNotification(chatId, message);
3945
3998
  addMessage(chatId, message);
3946
3999
  if (message.sender.did === (currentUser == null ? void 0 : currentUser.did)) {
3947
4000
  updateLastAckTime(chatId, true);
@@ -4749,7 +4802,7 @@ function Back({ url, fallbackUrl, iconOnly, sx, ...rest }) {
4749
4802
  }
4750
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" }) });
4751
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" }) });
4752
- const Editor = lazy(() => import("./editor-DVoJ3SEG.mjs"));
4805
+ const Editor = lazy(() => import("./editor-TZZey5Q7.mjs"));
4753
4806
  function LazyEditor(props) {
4754
4807
  const fallback2 = /* @__PURE__ */ jsxs(Box, { sx: { px: 3 }, children: [
4755
4808
  /* @__PURE__ */ jsx(Skeleton, {}),
@@ -4884,7 +4937,7 @@ function ShortcutPlugin({ callback }) {
4884
4937
  }, [editor, callback, mobile.any]);
4885
4938
  return null;
4886
4939
  }
4887
- function ChatInput({ initialContent, send, onContentChange, onInputFocus }) {
4940
+ function ChatInput({ initialContent, send, onContentChange, onFocusChange }) {
4888
4941
  const { t } = useLocaleContext();
4889
4942
  const [content, setContent] = useState("");
4890
4943
  const [lastSent, setLastSent] = useState(0);
@@ -4893,23 +4946,26 @@ function ChatInput({ initialContent, send, onContentChange, onInputFocus }) {
4893
4946
  });
4894
4947
  const { mobile } = useBrowser();
4895
4948
  const [focused, setFocused] = useState(false);
4896
- const onFocusWrapper = (v2) => {
4949
+ const FocusCallback = (v2) => {
4897
4950
  setFocused(v2);
4898
- onInputFocus == null ? void 0 : onInputFocus(v2);
4951
+ onFocusChange == null ? void 0 : onFocusChange(v2);
4899
4952
  };
4900
4953
  const onToolbarBtnMouseDown = (e) => {
4901
4954
  e.preventDefault();
4902
4955
  setToolbarVisible((x) => !x);
4903
4956
  };
4904
4957
  const compactView = mobile.any && !focused;
4905
- const handleSend = () => {
4906
- if (!content) {
4958
+ const handleSend = async () => {
4959
+ if (!content)
4907
4960
  return;
4908
- }
4909
- send(content);
4961
+ await send(content);
4910
4962
  setContent("");
4911
4963
  setLastSent(Date.now());
4912
4964
  };
4965
+ const onSendBtnMouseDown = (e) => {
4966
+ e.preventDefault();
4967
+ handleSend();
4968
+ };
4913
4969
  return /* @__PURE__ */ jsxs(
4914
4970
  Box,
4915
4971
  {
@@ -4985,7 +5041,7 @@ function ChatInput({ initialContent, send, onContentChange, onInputFocus }) {
4985
5041
  /* @__PURE__ */ jsx(AutoClearPlugin, { clearKey: lastSent }),
4986
5042
  /* @__PURE__ */ jsx(ShortcutPlugin, { callback: handleSend }),
4987
5043
  /* @__PURE__ */ jsx(DraggerPlugin, {}),
4988
- /* @__PURE__ */ jsx(FocusPlugin, { callback: onFocusWrapper })
5044
+ /* @__PURE__ */ jsx(FocusPlugin, { callback: FocusCallback })
4989
5045
  ]
4990
5046
  }
4991
5047
  ) })
@@ -5032,7 +5088,7 @@ function ChatInput({ initialContent, send, onContentChange, onInputFocus }) {
5032
5088
  color: "primary",
5033
5089
  variant: "contained",
5034
5090
  disabled: !content,
5035
- onClick: handleSend,
5091
+ onMouseDown: onSendBtnMouseDown,
5036
5092
  startIcon: /* @__PURE__ */ jsx(Box, { component: tablerSend, sx: { fontSize: "14px !important" } }),
5037
5093
  sx: { height: 28 },
5038
5094
  children: t("chat.send")
@@ -5085,9 +5141,10 @@ function ChatRoom({ chat, inWallet, ...rest }) {
5085
5141
  deleteChannel(chat.id);
5086
5142
  }
5087
5143
  };
5088
- const onInputFocus = () => {
5144
+ const onFocusChange = (focused) => {
5089
5145
  var _a3;
5090
- (_a3 = messageListRef.current) == null ? void 0 : _a3.scrollToBottom();
5146
+ if (downSm && focused)
5147
+ (_a3 = messageListRef.current) == null ? void 0 : _a3.scrollToBottom();
5091
5148
  };
5092
5149
  const renderRoomHeader = () => {
5093
5150
  if (chat.type === "notification") {
@@ -5190,7 +5247,7 @@ function ChatRoom({ chat, inWallet, ...rest }) {
5190
5247
  {
5191
5248
  initialContent: input,
5192
5249
  onContentChange: (v2) => setInput(v2),
5193
- onInputFocus,
5250
+ onFocusChange,
5194
5251
  send: (content) => sendMessage(chat.id, content)
5195
5252
  }
5196
5253
  ) }),
@@ -6201,6 +6258,7 @@ const en = {
6201
6258
  mentionInPost: "mentioned you in a post",
6202
6259
  replyYourComment: "replied to your comment",
6203
6260
  replyComment: "replied to a comment",
6261
+ newMsg: "New message from",
6204
6262
  deleteChannelTitle: "Delete this channel?",
6205
6263
  deleteChannelDesc: "If you delete this channel, all messages in the channel will be deleted immediately.",
6206
6264
  leaveChannel: "Leave channel",
@@ -6289,6 +6347,7 @@ const zh = {
6289
6347
  mentionInPost: "在帖子里提及了你",
6290
6348
  replyYourComment: "回复了你的评论",
6291
6349
  replyComment: "回复了评论",
6350
+ newMsg: "新消息来自",
6292
6351
  deleteChannelTitle: "确认删除这个频道?",
6293
6352
  deleteChannelDesc: "如果你要删除这个频道, 频道内所有的消息都会立刻消除。",
6294
6353
  leaveChannel: "离开频道",
@@ -12212,88 +12271,89 @@ function SegmentedControl({ value, options, onChange, sx, ...rest }) {
12212
12271
  ) });
12213
12272
  }
12214
12273
  export {
12215
- ChatHeaderAddon as $,
12274
+ ChatListInWallet as $,
12216
12275
  Avatar as A,
12217
12276
  Badge as B,
12218
12277
  CommentInput as C,
12219
12278
  DefaultEditorConfigProvider as D,
12220
- CommentsProvider as E,
12221
- BinaryThumb as F,
12222
- GithubReaction as G,
12223
- EmptyStatus as H,
12279
+ useCommentsContext as E,
12280
+ CommentsProvider as F,
12281
+ BinaryThumb as G,
12282
+ GithubReaction as H,
12224
12283
  ImagePathFixerPlugin as I,
12225
- BlogListWrapper as J,
12226
- BlogCard as K,
12227
- BlogPermaLink as L,
12284
+ EmptyStatus as J,
12285
+ BlogListWrapper as K,
12286
+ BlogCard as L,
12228
12287
  Menu as M,
12229
- getBlogLink as N,
12230
- CoverImage as O,
12288
+ BlogPermaLink as N,
12289
+ getBlogLink as O,
12231
12290
  Pagination as P,
12232
- CoverImageUpload as Q,
12291
+ CoverImage as Q,
12233
12292
  RelativeTime as R,
12234
12293
  ScrollableEditorWrapper as S,
12235
- AccessControl as T,
12236
- useAuthzContext as U,
12294
+ CoverImageUpload as T,
12295
+ AccessControl as U,
12237
12296
  VideoPathFixerPlugin as V,
12238
- AuthzProvider as W,
12239
- ChatClient as X,
12240
- Chat as Y,
12241
- ChatInWallet as Z,
12242
- ChatListInWallet as _,
12297
+ useAuthzContext as W,
12298
+ AuthzProvider as X,
12299
+ ChatClient as Y,
12300
+ Chat as Z,
12301
+ ChatInWallet as _,
12243
12302
  isEmptyContent as a,
12244
- useChatContext as a0,
12245
- ChatProvider as a1,
12246
- UnreadNotificationContext as a2,
12247
- useUnreadNotification as a3,
12248
- UnreadNotificationProvider as a4,
12249
- Confirm as a5,
12250
- ConfirmContext as a6,
12251
- useConfirm as a7,
12252
- ConfirmProvider as a8,
12253
- SecureLabelPicker as a9,
12254
- useApiErrorHandler as aa,
12255
- useDefaultApiErrorHandler as ab,
12256
- DefaultApiErrorHandler as ac,
12257
- Back as ad,
12258
- LazyEditor as ae,
12259
- EditorPreview as af,
12260
- DirtyPromptContainer as ag,
12261
- ConfirmNavigation as ah,
12262
- UploaderContext as ai,
12263
- useUploader as aj,
12264
- UploaderTrigger as ak,
12265
- UploaderProvider as al,
12266
- composeImageUrl as am,
12267
- usePointUpContext as an,
12268
- PointUpProvider as ao,
12269
- ButtonGroup as ap,
12270
- SegmentedControl as aq,
12271
- create as ar,
12272
- getWsClient as as,
12273
- 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,
12274
12334
  Input as b,
12275
12335
  useChanged as c,
12276
12336
  useSessionContext as d,
12277
- utils as e,
12278
- preferences as f,
12337
+ useNotification as e,
12338
+ utils as f,
12279
12339
  getExcerptSync as g,
12280
- typography as h,
12340
+ preferences as h,
12281
12341
  inferInitialEditorState as i,
12282
- themeOverrides as j,
12283
- InternalThemeProvider as k,
12342
+ typography as j,
12343
+ themeOverrides as k,
12284
12344
  lexical as l,
12285
- Avatars as m,
12286
- AuthorInfo as n,
12287
- SystemUser as o,
12345
+ InternalThemeProvider as m,
12346
+ Avatars as n,
12347
+ AuthorInfo as o,
12288
12348
  preloadInput as p,
12289
- PostContent as q,
12349
+ SystemUser as q,
12290
12350
  routes as r,
12291
12351
  stringify as s,
12292
12352
  translations as t,
12293
12353
  useNow as u,
12294
- PostComponent as v,
12295
- Comment as w,
12296
- CommentList as x,
12297
- CommentsContext as y,
12298
- useCommentsContext as z
12354
+ PostContent as v,
12355
+ PostComponent as w,
12356
+ Comment as x,
12357
+ CommentList as y,
12358
+ CommentsContext as z
12299
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-BHaorx7Z.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();
@@ -3654,6 +3671,9 @@ var __publicField = (obj, key, value) => {
3654
3671
  activeChatId: void 0,
3655
3672
  error: void 0
3656
3673
  });
3674
+ const chatById = react.useMemo(() => {
3675
+ return state.chats.reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {});
3676
+ }, [state.chats]);
3657
3677
  const { markAsUnread } = useUnreadNotification();
3658
3678
  const navigate = reactRouterDom.useNavigate();
3659
3679
  const { session } = useSessionContext();
@@ -3865,9 +3885,42 @@ var __publicField = (obj, key, value) => {
3865
3885
  setState((prev) => ({ ...prev, activeChatId: void 0 }));
3866
3886
  }
3867
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
+ };
3868
3920
  react.useEffect(() => {
3869
3921
  const cancels = [
3870
3922
  client2.onMessage(({ chatId, message }) => {
3923
+ resolveChatNotification(chatId, message);
3871
3924
  addMessage(chatId, message);
3872
3925
  if (message.sender.did === (currentUser == null ? void 0 : currentUser.did)) {
3873
3926
  updateLastAckTime(chatId, true);
@@ -4810,7 +4863,7 @@ var __publicField = (obj, key, value) => {
4810
4863
  }, [editor2, callback, mobile.any]);
4811
4864
  return null;
4812
4865
  }
4813
- function ChatInput({ initialContent, send, onContentChange, onInputFocus }) {
4866
+ function ChatInput({ initialContent, send, onContentChange, onFocusChange }) {
4814
4867
  const { t } = context.useLocaleContext();
4815
4868
  const [content, setContent] = react.useState("");
4816
4869
  const [lastSent, setLastSent] = react.useState(0);
@@ -4819,23 +4872,26 @@ var __publicField = (obj, key, value) => {
4819
4872
  });
4820
4873
  const { mobile } = reactHooks.useBrowser();
4821
4874
  const [focused, setFocused] = react.useState(false);
4822
- const onFocusWrapper = (v2) => {
4875
+ const FocusCallback = (v2) => {
4823
4876
  setFocused(v2);
4824
- onInputFocus == null ? void 0 : onInputFocus(v2);
4877
+ onFocusChange == null ? void 0 : onFocusChange(v2);
4825
4878
  };
4826
4879
  const onToolbarBtnMouseDown = (e) => {
4827
4880
  e.preventDefault();
4828
4881
  setToolbarVisible((x) => !x);
4829
4882
  };
4830
4883
  const compactView = mobile.any && !focused;
4831
- const handleSend = () => {
4832
- if (!content) {
4884
+ const handleSend = async () => {
4885
+ if (!content)
4833
4886
  return;
4834
- }
4835
- send(content);
4887
+ await send(content);
4836
4888
  setContent("");
4837
4889
  setLastSent(Date.now());
4838
4890
  };
4891
+ const onSendBtnMouseDown = (e) => {
4892
+ e.preventDefault();
4893
+ handleSend();
4894
+ };
4839
4895
  return /* @__PURE__ */ jsxRuntime.jsxs(
4840
4896
  material.Box,
4841
4897
  {
@@ -4911,7 +4967,7 @@ var __publicField = (obj, key, value) => {
4911
4967
  /* @__PURE__ */ jsxRuntime.jsx(AutoClearPlugin, { clearKey: lastSent }),
4912
4968
  /* @__PURE__ */ jsxRuntime.jsx(ShortcutPlugin, { callback: handleSend }),
4913
4969
  /* @__PURE__ */ jsxRuntime.jsx(DraggerPlugin, {}),
4914
- /* @__PURE__ */ jsxRuntime.jsx(FocusPlugin, { callback: onFocusWrapper })
4970
+ /* @__PURE__ */ jsxRuntime.jsx(FocusPlugin, { callback: FocusCallback })
4915
4971
  ]
4916
4972
  }
4917
4973
  ) })
@@ -4958,7 +5014,7 @@ var __publicField = (obj, key, value) => {
4958
5014
  color: "primary",
4959
5015
  variant: "contained",
4960
5016
  disabled: !content,
4961
- onClick: handleSend,
5017
+ onMouseDown: onSendBtnMouseDown,
4962
5018
  startIcon: /* @__PURE__ */ jsxRuntime.jsx(material.Box, { component: tablerSend, sx: { fontSize: "14px !important" } }),
4963
5019
  sx: { height: 28 },
4964
5020
  children: t("chat.send")
@@ -5011,9 +5067,10 @@ var __publicField = (obj, key, value) => {
5011
5067
  deleteChannel(chat.id);
5012
5068
  }
5013
5069
  };
5014
- const onInputFocus = () => {
5070
+ const onFocusChange = (focused) => {
5015
5071
  var _a3;
5016
- (_a3 = messageListRef.current) == null ? void 0 : _a3.scrollToBottom();
5072
+ if (downSm && focused)
5073
+ (_a3 = messageListRef.current) == null ? void 0 : _a3.scrollToBottom();
5017
5074
  };
5018
5075
  const renderRoomHeader = () => {
5019
5076
  if (chat.type === "notification") {
@@ -5116,7 +5173,7 @@ var __publicField = (obj, key, value) => {
5116
5173
  {
5117
5174
  initialContent: input,
5118
5175
  onContentChange: (v2) => setInput(v2),
5119
- onInputFocus,
5176
+ onFocusChange,
5120
5177
  send: (content) => sendMessage(chat.id, content)
5121
5178
  }
5122
5179
  ) }),
@@ -6127,6 +6184,7 @@ var __publicField = (obj, key, value) => {
6127
6184
  mentionInPost: "mentioned you in a post",
6128
6185
  replyYourComment: "replied to your comment",
6129
6186
  replyComment: "replied to a comment",
6187
+ newMsg: "New message from",
6130
6188
  deleteChannelTitle: "Delete this channel?",
6131
6189
  deleteChannelDesc: "If you delete this channel, all messages in the channel will be deleted immediately.",
6132
6190
  leaveChannel: "Leave channel",
@@ -6215,6 +6273,7 @@ var __publicField = (obj, key, value) => {
6215
6273
  mentionInPost: "在帖子里提及了你",
6216
6274
  replyYourComment: "回复了你的评论",
6217
6275
  replyComment: "回复了评论",
6276
+ newMsg: "新消息来自",
6218
6277
  deleteChannelTitle: "确认删除这个频道?",
6219
6278
  deleteChannelDesc: "如果你要删除这个频道, 频道内所有的消息都会立刻消除。",
6220
6279
  leaveChannel: "离开频道",
@@ -12247,6 +12306,7 @@ var __publicField = (obj, key, value) => {
12247
12306
  exports2.useCommentsContext = useCommentsContext;
12248
12307
  exports2.useConfirm = useConfirm;
12249
12308
  exports2.useDefaultApiErrorHandler = useDefaultApiErrorHandler;
12309
+ exports2.useNotification = useNotification;
12250
12310
  exports2.useNow = useNow;
12251
12311
  exports2.usePointUpContext = usePointUpContext;
12252
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.66",
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.66",
35
- "@blocklet/labels": "2.0.66",
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": "af63285a90fe7f83f565db17a3e0ea338f7c3c89"
103
+ "gitHead": "138f22fa2ed3d57c2a184c6db5b083fa3b9d8749"
104
104
  }