@blocklet/discuss-kit-ux 1.6.174 → 1.6.176

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.
@@ -27,10 +27,12 @@ import Alert from "@mui/material/Alert";
27
27
  import isBoolean from "lodash/isBoolean";
28
28
  import Button from "@mui/material/Button";
29
29
  import DidAvatar from "@arcblock/did-connect/lib/Avatar";
30
+ import AvatarGroup from "@mui/material/AvatarGroup";
31
+ import { grey, green, amber } from "@mui/material/colors";
30
32
  import useMediaQuery$1 from "@mui/material/useMediaQuery";
31
33
  import DID from "@arcblock/ux/lib/DID";
32
34
  import Tooltip, { tooltipClasses } from "@mui/material/Tooltip";
33
- import { Link, useNavigate, useLocation, useSearchParams, unstable_useBlocker, useParams } from "react-router-dom";
35
+ import { Link, useNavigate, useLocation, useSearchParams, useBlocker, useParams } from "react-router-dom";
34
36
  import UxRelativeTime from "@arcblock/ux/lib/RelativeTime";
35
37
  import Chip from "@mui/material/Chip";
36
38
  import Stack from "@mui/material/Stack";
@@ -42,10 +44,11 @@ import Avatar$1 from "@mui/material/Avatar";
42
44
  import BrokenImageIcon from "@mui/icons-material/BrokenImage";
43
45
  import { Icon } from "@iconify/react";
44
46
  import Empty$1 from "@arcblock/ux/lib/Empty";
45
- import { green } from "@mui/material/colors";
46
47
  import { SessionContext } from "@arcblock/did-connect/lib/Session";
47
- import { useTheme as useTheme$1, useMediaQuery, Box as Box$1, Tooltip as Tooltip$1, Chip as Chip$1, alpha, ClickAwayListener, Dialog as Dialog$1, DialogTitle, DialogContent, DialogActions, DialogContentText, Button as Button$1, Skeleton, IconButton as IconButton$2, InputBase, tooltipClasses as tooltipClasses$1, Badge as Badge$1 } from "@mui/material";
48
+ import { useTheme as useTheme$1, useMediaQuery, Box as Box$1, Tooltip as Tooltip$1, Chip as Chip$1, alpha, ClickAwayListener, Dialog as Dialog$1, DialogTitle, DialogContent, DialogActions, DialogContentText, Button as Button$1, Skeleton, IconButton as IconButton$2, InputBase, tooltipClasses as tooltipClasses$1, Badge as Badge$1, Paper, ToggleButtonGroup, ToggleButton } from "@mui/material";
48
49
  import DIDAddress from "@arcblock/did-connect/lib/Address";
50
+ import NotificationsActiveOutlinedIcon from "@mui/icons-material/NotificationsActiveOutlined";
51
+ import Groups2RoundedIcon from "@mui/icons-material/Groups2Rounded";
49
52
  import CheckboxPlugin from "@blocklet/editor/lib/ext/CheckboxPlugin";
50
53
  import MuiMenuItem from "@mui/material/MenuItem";
51
54
  import clsx from "clsx";
@@ -65,6 +68,7 @@ import { Flipper, Flipped } from "react-flip-toolkit";
65
68
  import Fab from "@mui/material/Fab";
66
69
  import debounce from "lodash/debounce";
67
70
  import TextField from "@mui/material/TextField";
71
+ import AddIcon from "@mui/icons-material/Add";
68
72
  import { AxiosError } from "axios";
69
73
  import Toast from "@arcblock/ux/lib/Toast";
70
74
  import MuiPagination from "@mui/material/Pagination";
@@ -190,16 +194,58 @@ const inferDiscussKitApiPrefix = () => {
190
194
  const getDraftSessionKeyPrefix = () => {
191
195
  return "comment-draft-";
192
196
  };
197
+ function lexicalRootToText(data) {
198
+ let parsedRoot = data;
199
+ if (typeof data === "string") {
200
+ try {
201
+ parsedRoot = JSON.parse(data).root;
202
+ if (typeof parsedRoot !== "object") {
203
+ return data;
204
+ }
205
+ } catch {
206
+ parsedRoot = {};
207
+ }
208
+ }
209
+ let text = "";
210
+ if (parsedRoot == null ? void 0 : parsedRoot.children) {
211
+ try {
212
+ parsedRoot.children.forEach((e) => {
213
+ if (e.text) {
214
+ text += e.text;
215
+ } else {
216
+ if (e.direction && text !== "") {
217
+ text += "\n";
218
+ }
219
+ text += lexicalRootToText(e);
220
+ }
221
+ });
222
+ } catch (err) {
223
+ console.error(`lexicalRootToText ${err == null ? void 0 : err.toString()}`);
224
+ console.error(err);
225
+ }
226
+ }
227
+ return text;
228
+ }
229
+ const getExcerptFromLexicalContent = (content, size = 150) => {
230
+ const textContent = (lexicalRootToText(content) || "").trim();
231
+ return textContent.length > size ? `${textContent.slice(0, size)}` : textContent;
232
+ };
233
+ const mergeSx = (initial, sx) => {
234
+ const mergedSx = [initial, ...Array.isArray(sx) ? sx : [sx]];
235
+ return mergedSx;
236
+ };
193
237
  const utils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
194
238
  __proto__: null,
195
239
  blockletExists,
196
240
  copy,
197
241
  getBlockletMountPointInfo,
198
242
  getDraftSessionKeyPrefix,
243
+ getExcerptFromLexicalContent,
199
244
  getLastItem,
200
245
  getPreference,
201
246
  getResizedAvatar,
202
247
  inferDiscussKitApiPrefix,
248
+ mergeSx,
203
249
  minDelay,
204
250
  protectLogin,
205
251
  repairBase64Avatar,
@@ -647,28 +693,47 @@ function Avatar({ src, ...rest }) {
647
693
  }
648
694
  return /* @__PURE__ */ jsx(DidAvatar, { src: src ? getResizedAvatar(src) : src, ...rest });
649
695
  }
650
- const Root$3 = styled(Box)`
696
+ const Root$3 = styled(AvatarGroup)`
651
697
  display: flex;
698
+ align-items: center;
652
699
  position: relative;
653
700
  z-index: 0;
654
701
  line-height: 1;
655
702
  .avatars-item {
656
703
  width: 16px;
657
704
  transition: width 0.1s ease-in-out;
705
+ & .image {
706
+ box-shadow: 0 0 0 2px #fff !important;
707
+ }
658
708
  }
659
- .avatars-item:last-child {
660
- width: 22px;
709
+
710
+ // use avatarGroup first is last
711
+ .avatars-item:first-child {
712
+ width: 24px;
713
+ }
714
+
715
+ .MuiAvatar-root {
716
+ width: 24px;
717
+ height: 24px;
718
+ z-index: 100;
719
+ margin-left: 0px;
720
+ font-size: 12px;
721
+ background-color: ${grey[400]};
722
+ font-weight: 500;
723
+ border: none;
724
+ box-shadow: 0 0 0 2px #fff !important;
661
725
  }
726
+
662
727
  /* &:hover {
663
728
  gap: 4px;
664
729
  .avatars-item {
665
- width: 22px;
730
+ width: 24px;
666
731
  }
667
732
  } */
668
733
  `;
669
- function Avatars({ users, variant = "circle" }) {
670
- return /* @__PURE__ */ jsx(Root$3, { sx: { ".avatars-item + .avatars-item .image": { boxShadow: "0 0 0 2px #fff" } }, children: users.map((user, index) => {
671
- return /* @__PURE__ */ jsx(Box, { className: "avatars-item", sx: { position: "relative", zIndex: index + 1 }, children: /* @__PURE__ */ jsx(Avatar, { did: user.did, src: user.avatar, size: 22, shape: "circle", variant }) }, index);
734
+ function Avatars({ users, variant = "circle", ...restProps }) {
735
+ return /* @__PURE__ */ jsx(Root$3, { sx: { ".avatars-item + .avatars-item .image": { boxShadow: "0 0 0 2px #fff" } }, max: 999, ...restProps, children: users.map((user, index) => {
736
+ return /* @__PURE__ */ jsx(Box, { className: "avatars-item", sx: { position: "relative", zIndex: index + 1 }, children: /* @__PURE__ */ jsx(Avatar, { did: user.did, src: user.avatar, size: 24, shape: "circle", variant }) }, index);
672
737
  }) });
673
738
  }
674
739
  function RelativeTime({ value, ...rest }) {
@@ -1033,7 +1098,7 @@ function AuthorInfo({
1033
1098
  return createdAt;
1034
1099
  }
1035
1100
  createdAt = typeof createdAt === "string" ? new Date(createdAt) : createdAt;
1036
- return /* @__PURE__ */ jsx(RelativeTime, { value: createdAt });
1101
+ return /* @__PURE__ */ jsx(Box, { component: RelativeTime, sx: { color: "text.secondary" }, value: createdAt });
1037
1102
  };
1038
1103
  const click = () => {
1039
1104
  setOpen(false);
@@ -1109,16 +1174,22 @@ function AuthorInfo({
1109
1174
  }
1110
1175
  ),
1111
1176
  showBadge && downMd && /* @__PURE__ */ jsx(Box, { mt: 0.5, children: BadgeRender }),
1112
- showDID && !(responsive && downMd) && /* @__PURE__ */ jsx(DID, { style: { lineHeight: 1.5, minHeight: 20, maxWidth: 250 }, size: 14, did: user == null ? void 0 : user.did })
1177
+ showDID && !(responsive && downMd) && /* @__PURE__ */ jsx(DID, { style: { lineHeight: 1.4, minHeight: 20, maxWidth: 250 }, size: 14, did: user == null ? void 0 : user.did })
1113
1178
  ] })
1114
1179
  ] });
1115
1180
  }
1116
- const mdiBullhornVariantOutline = (props) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsx("path", { fill: "currentColor", d: "M20 2v2L4 8V6H2v12h2v-2l2 .5v2C6 20.4 7.6 22 9.5 22s3.5-1.6 3.5-3.5v-.2l7 1.7v2h2V2h-2m-9 16.5c0 .8-.7 1.5-1.5 1.5S8 19.3 8 18.5V17l3 .8v.7m9-.5L4 14v-4l16-4v12Z" }) });
1117
- function SystemUser({ name = "System", showDidAddress = true, size = "normal", icon, ...rest }) {
1181
+ function SystemUser({
1182
+ name = "System",
1183
+ showDidAddress = true,
1184
+ showIcon = true,
1185
+ size = "normal",
1186
+ icon,
1187
+ ...rest
1188
+ }) {
1118
1189
  const sm = size === "sm";
1119
- const iconSize = sm ? 32 : 36;
1190
+ const iconSize = sm ? 36 : 40;
1120
1191
  return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1, fontSize: 14 }, ...rest, children: [
1121
- /* @__PURE__ */ jsx(
1192
+ showIcon && /* @__PURE__ */ jsx(
1122
1193
  Box,
1123
1194
  {
1124
1195
  sx: {
@@ -1128,10 +1199,10 @@ function SystemUser({ name = "System", showDidAddress = true, size = "normal", i
1128
1199
  width: iconSize,
1129
1200
  height: iconSize,
1130
1201
  color: "#fff",
1131
- bgcolor: "primary.dark",
1202
+ bgcolor: "secondary.main",
1132
1203
  borderRadius: "100%"
1133
1204
  },
1134
- children: icon || /* @__PURE__ */ jsx(mdiBullhornVariantOutline, { style: { fontSize: size === "sm" ? 14 : 16 } })
1205
+ children: icon || /* @__PURE__ */ jsx(NotificationsActiveOutlinedIcon, { sx: { fontSize: size === "sm" ? 16 : 18 } })
1135
1206
  }
1136
1207
  ),
1137
1208
  /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "column" }, children: [
@@ -1140,6 +1211,49 @@ function SystemUser({ name = "System", showDidAddress = true, size = "normal", i
1140
1211
  ] })
1141
1212
  ] });
1142
1213
  }
1214
+ function ChannelGroup({ size = "normal", chat, ...rest }) {
1215
+ var _a2;
1216
+ const sm = size === "sm";
1217
+ const iconSize = sm ? 36 : 40;
1218
+ const lastMessage = chat && chat.messages && chat.messages[chat.messages.length - 1];
1219
+ const messageText = lastMessage ? `${(_a2 = lastMessage == null ? void 0 : lastMessage.sender) == null ? void 0 : _a2.fullName}: ${getExcerptFromLexicalContent(lastMessage == null ? void 0 : lastMessage.content)}` : "";
1220
+ return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1, fontSize: 14 }, ...rest, children: [
1221
+ /* @__PURE__ */ jsx(
1222
+ Box,
1223
+ {
1224
+ sx: {
1225
+ display: "flex",
1226
+ justifyContent: "center",
1227
+ alignItems: "center",
1228
+ width: iconSize,
1229
+ height: iconSize,
1230
+ color: "#fff",
1231
+ bgcolor: amber[200],
1232
+ borderRadius: "100%"
1233
+ },
1234
+ children: /* @__PURE__ */ jsx(Groups2RoundedIcon, { sx: { fontSize: size === "sm" ? 16 : 18, color: amber[700] } })
1235
+ }
1236
+ ),
1237
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "column", height: "100%", justifyContent: "space-between" }, children: [
1238
+ /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center" }, lineHeight: 1, children: /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontWeight: "bold" }, children: chat == null ? void 0 : chat.name }) }),
1239
+ /* @__PURE__ */ jsx(
1240
+ Box,
1241
+ {
1242
+ className: "message-content-text",
1243
+ sx: {
1244
+ overflow: "hidden",
1245
+ textOverflow: "ellipsis",
1246
+ whiteSpace: "nowrap",
1247
+ width: 220,
1248
+ fontWeight: "regular",
1249
+ fontSize: 14
1250
+ },
1251
+ children: messageText
1252
+ }
1253
+ )
1254
+ ] })
1255
+ ] });
1256
+ }
1143
1257
  const MAX_HEIGHT = 200;
1144
1258
  const Root$2 = styled("div")`
1145
1259
  &.markdown-viewer-collapsed .markdown-viewer-md-wrapper {
@@ -1366,7 +1480,7 @@ function PostComponent({
1366
1480
  menuItems = customMenu ? customMenu(menuItems, postContext) : menuItems;
1367
1481
  const renderTime = () => {
1368
1482
  if (allowCopyLink) {
1369
- return /* @__PURE__ */ jsx(Box, { component: "a", href: `#${post.id}`, sx: { color: "inherit", textDecoration: "none" }, children: /* @__PURE__ */ jsx(RelativeTime, { value: post.createdAt }) });
1483
+ return /* @__PURE__ */ jsx(Box, { component: "a", href: `#${post.id}`, sx: { color: "text.secondary", textDecoration: "none" }, children: /* @__PURE__ */ jsx(RelativeTime, { value: post.createdAt }) });
1370
1484
  }
1371
1485
  return /* @__PURE__ */ jsx(RelativeTime, { value: post.createdAt });
1372
1486
  };
@@ -2173,7 +2287,7 @@ function CommentsProvider({
2173
2287
  setState({ initialized: true });
2174
2288
  return;
2175
2289
  }
2176
- setState({ ...getInitialState(order ? { order } : {}), initialized: false });
2290
+ setState({ ...getInitialState(), order: state.order, initialized: false });
2177
2291
  const fetchCommentPosition = () => api.fetchCommentPosition({
2178
2292
  id: highlightedRef.current,
2179
2293
  objectId: target.id,
@@ -2617,7 +2731,8 @@ function CoverImage({
2617
2731
  }
2618
2732
  }
2619
2733
  ),
2620
- !!url && /* @__PURE__ */ jsx(
2734
+ !!url && // add box because img can't add :after
2735
+ /* @__PURE__ */ jsx(Box$1, { children: /* @__PURE__ */ jsx(
2621
2736
  "img",
2622
2737
  {
2623
2738
  src: url ? composeImageUrl(url, width) : "",
@@ -2637,7 +2752,7 @@ function CoverImage({
2637
2752
  onLoad: () => setLoaded(true),
2638
2753
  onError: () => setErrored(true)
2639
2754
  }
2640
- ),
2755
+ ) }),
2641
2756
  (!url || errored) && /* @__PURE__ */ jsx(
2642
2757
  Box$1,
2643
2758
  {
@@ -3585,20 +3700,18 @@ function ChatProvider({ client: client2, activeChatId, children }) {
3585
3700
  return /* @__PURE__ */ jsx(ChatContext.Provider, { value, children });
3586
3701
  }
3587
3702
  function ChatList(props) {
3703
+ const { t } = useLocaleContext();
3588
3704
  const { orderedChats, activeChatId, setActiveChat, getOppositeUser, hasUnreadMessages } = useChatContext();
3589
3705
  const renderItem = (chat) => {
3590
3706
  if (chat.type === "notification") {
3591
- return /* @__PURE__ */ jsx(SystemUser, { name: "Notification" });
3707
+ return /* @__PURE__ */ jsx(SystemUser, { name: t("chat.notification") });
3592
3708
  }
3593
3709
  if (chat.type === "dm") {
3594
3710
  const oppositeUser = getOppositeUser(chat);
3595
- return /* @__PURE__ */ jsx(AuthorInfo, { user: oppositeUser, showProfileCard: false });
3711
+ return /* @__PURE__ */ jsx(AuthorInfo, { user: oppositeUser, showProfileCard: false, showBadge: false, showDID: false });
3596
3712
  }
3597
3713
  if (chat.type === "channel") {
3598
- return /* @__PURE__ */ jsxs(Box, { component: "span", sx: { fontSize: 14 }, children: [
3599
- "# ",
3600
- chat.name
3601
- ] });
3714
+ return /* @__PURE__ */ jsx(Box, { component: "span", children: /* @__PURE__ */ jsx(ChannelGroup, { chat }) });
3602
3715
  }
3603
3716
  return null;
3604
3717
  };
@@ -3610,13 +3723,18 @@ function ChatList(props) {
3610
3723
  {
3611
3724
  sx: {
3612
3725
  position: "relative",
3613
- p: 2,
3726
+ m: 1,
3727
+ py: 1.5,
3728
+ px: 2,
3614
3729
  fontWeight: "bold",
3615
- color: isActiveChat ? "primary.contrastText" : "grey.700",
3616
- bgcolor: isActiveChat ? "primary.light" : "",
3617
- borderRadius: 2,
3730
+ color: isActiveChat ? "secondary.main" : "grey.700",
3731
+ bgcolor: isActiveChat ? "action.selected" : "",
3732
+ borderRadius: 1,
3618
3733
  cursor: "pointer",
3619
- ...isActiveChat && { ".did-address-text": { color: "#fff!important" } }
3734
+ ...isActiveChat && {
3735
+ ".did-address-text": { color: "grey.500" },
3736
+ ".message-content-text": { color: "grey.500" }
3737
+ }
3620
3738
  },
3621
3739
  onClick: () => setActiveChat(chat),
3622
3740
  children: [
@@ -3685,21 +3803,12 @@ function Message({ message, showTime = true, ...rest }) {
3685
3803
  }
3686
3804
  );
3687
3805
  }
3688
- const getUrlHost = (url) => {
3689
- try {
3690
- const { host } = new URL(url);
3691
- return host;
3692
- } catch (e) {
3693
- return url;
3694
- }
3695
- };
3696
3806
  function NotificationMessage({ chat, message, prevMessage, ...rest }) {
3697
3807
  const { session } = useSessionContext();
3698
3808
  const { t } = useLocaleContext();
3699
3809
  const renderQuote = ({ title, excerpt, cover }) => {
3700
3810
  if ("post" in message) {
3701
- return /* @__PURE__ */ jsxs(Box, { sx: { mt: 1.5, pl: 1, borderLeft: "4px solid #ddd", color: 14 }, children: [
3702
- /* @__PURE__ */ jsx(Box, { sx: { fontSize: 13, color: "grey.500" }, children: getUrlHost(message.link) }),
3811
+ return /* @__PURE__ */ jsxs(Box, { sx: { color: 14, mt: 1 }, children: [
3703
3812
  title && /* @__PURE__ */ jsx(
3704
3813
  Typography,
3705
3814
  {
@@ -3707,11 +3816,10 @@ function NotificationMessage({ chat, message, prevMessage, ...rest }) {
3707
3816
  variant: "h6",
3708
3817
  href: message.link,
3709
3818
  target: "_blank",
3710
- style: { fontSize: 14, color: "#2fafff" },
3819
+ style: { fontSize: 14, color: "#2fafff", textDecoration: "none" },
3711
3820
  children: title
3712
3821
  }
3713
3822
  ),
3714
- excerpt && /* @__PURE__ */ jsx(Box, { sx: { overflow: "hidden" }, children: excerpt }),
3715
3823
  cover && // cover image
3716
3824
  /* @__PURE__ */ jsx(Box, { sx: { maxWidth: 200, mt: 1 }, children: /* @__PURE__ */ jsx(
3717
3825
  Box,
@@ -3736,58 +3844,138 @@ function NotificationMessage({ chat, message, prevMessage, ...rest }) {
3736
3844
  return null;
3737
3845
  };
3738
3846
  const render = () => {
3739
- var _a2, _b2, _c;
3847
+ var _a2, _b2, _c, _d, _e, _f, _g;
3740
3848
  if (message.type === "post_create") {
3741
- return /* @__PURE__ */ jsxs(Box, { children: [
3742
- /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontWeight: "bold" }, children: message.sourceUser.fullName }),
3743
- /* @__PURE__ */ jsx("span", { children: t("message.newPost") }),
3744
- renderQuote(message.post)
3745
- ] });
3849
+ return /* @__PURE__ */ jsxs(
3850
+ Box,
3851
+ {
3852
+ sx: {
3853
+ py: 1.5,
3854
+ px: 2,
3855
+ background: "#fff",
3856
+ width: "fit-content",
3857
+ maxWidth: "calc(100% - 16px)",
3858
+ wordWrap: "break-word",
3859
+ borderRadius: 1
3860
+ },
3861
+ children: [
3862
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "row", alignItems: "center", color: "primary.light" }, children: [
3863
+ /* @__PURE__ */ jsx(Icon, { icon: "tabler:news", style: { height: 15, width: 15, marginRight: 4 } }),
3864
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { mr: 0.5 }, children: message.sourceUser.fullName }),
3865
+ /* @__PURE__ */ jsx("span", { children: t("chat.newPost") })
3866
+ ] }),
3867
+ renderQuote(message.post)
3868
+ ]
3869
+ }
3870
+ );
3746
3871
  }
3747
3872
  if (message.type === "comment") {
3748
- return /* @__PURE__ */ jsxs(Box, { children: [
3749
- /* @__PURE__ */ jsxs(Box, { children: [
3750
- /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontWeight: "bold" }, children: message.sourceUser.fullName }),
3751
- /* @__PURE__ */ jsx("span", { children: ((_a2 = message == null ? void 0 : message.sourceUser) == null ? void 0 : _a2.did) === ((_b2 = session == null ? void 0 : session.user) == null ? void 0 : _b2.did) ? " commented your post:" : " commented post:" })
3752
- ] }),
3753
- /* @__PURE__ */ jsx(Typography, { variant: "body1", children: message.comment.excerpt }),
3754
- renderQuote(message.post)
3755
- ] });
3873
+ return /* @__PURE__ */ jsxs(
3874
+ Box,
3875
+ {
3876
+ sx: {
3877
+ py: 1.5,
3878
+ px: 2,
3879
+ background: "#fff",
3880
+ width: "fit-content",
3881
+ maxWidth: "calc(100% - 16px)",
3882
+ wordWrap: "break-word",
3883
+ borderRadius: 1
3884
+ },
3885
+ children: [
3886
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "row", alignItems: "center", color: "primary.light" }, children: [
3887
+ /* @__PURE__ */ jsx(Icon, { icon: "tabler:message-circle-2", style: { height: 15, width: 15, marginRight: 4 } }),
3888
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { mr: 0.5 }, children: message.sourceUser.fullName }),
3889
+ /* @__PURE__ */ jsx("span", { children: ((_a2 = message == null ? void 0 : message.sourceUser) == null ? void 0 : _a2.did) === ((_b2 = session == null ? void 0 : session.user) == null ? void 0 : _b2.did) ? t("chat.commentedYourPost") : t("chat.commentedPost") })
3890
+ ] }),
3891
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", sx: { fontSize: 16 }, children: (_c = message == null ? void 0 : message.comment) == null ? void 0 : _c.excerpt }),
3892
+ renderQuote(message.post)
3893
+ ]
3894
+ }
3895
+ );
3756
3896
  }
3757
3897
  if (message.type === "reply") {
3758
- return /* @__PURE__ */ jsxs(Box, { children: [
3759
- /* @__PURE__ */ jsxs(Box, { children: [
3760
- /* @__PURE__ */ jsx(Box, { component: "span", sx: { color: "grey.600", fontWeight: "bold" }, children: message.sourceUser.fullName }),
3761
- /* @__PURE__ */ jsx("span", { children: (message == null ? void 0 : message.recipient) === ((_c = session == null ? void 0 : session.user) == null ? void 0 : _c.did) ? " replied your comment:" : " replied comment:" })
3762
- ] }),
3763
- /* @__PURE__ */ jsx(Typography, { variant: "body1", children: message.reply.excerpt }),
3764
- renderQuote({ title: message.post.title, excerpt: message.comment.excerpt })
3765
- ] });
3898
+ return /* @__PURE__ */ jsxs(
3899
+ Box,
3900
+ {
3901
+ sx: {
3902
+ py: 1.5,
3903
+ px: 2,
3904
+ background: "#fff",
3905
+ width: "fit-content",
3906
+ maxWidth: "calc(100% - 16px)",
3907
+ wordWrap: "break-word",
3908
+ borderRadius: 1
3909
+ },
3910
+ children: [
3911
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "row", alignItems: "center", color: "primary.light" }, children: [
3912
+ /* @__PURE__ */ jsx(Icon, { icon: "tabler:message-circle-2", style: { height: 15, width: 15, marginRight: 4 } }),
3913
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { mr: 0.5 }, children: message.sourceUser.fullName }),
3914
+ /* @__PURE__ */ jsx("span", { children: (message == null ? void 0 : message.recipient) === ((_d = session == null ? void 0 : session.user) == null ? void 0 : _d.did) ? t("chat.replyYourComment") : t("chat.replyComment") })
3915
+ ] }),
3916
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", children: message.reply.excerpt }),
3917
+ renderQuote({ title: message.post.title, excerpt: message.comment.excerpt })
3918
+ ]
3919
+ }
3920
+ );
3766
3921
  }
3767
3922
  if (message.type === "mentionInComment") {
3768
- return /* @__PURE__ */ jsxs(Box, { children: [
3769
- /* @__PURE__ */ jsxs(Box, { children: [
3770
- /* @__PURE__ */ jsx(Box, { component: "span", sx: { color: "grey.600", fontWeight: "bold" }, children: message.sourceUser.fullName }),
3771
- /* @__PURE__ */ jsx("span", { children: " mentioned you in a comment:" })
3772
- ] }),
3773
- /* @__PURE__ */ jsx(Typography, { variant: "body1", children: message.comment.excerpt }),
3774
- renderQuote(message.post)
3775
- ] });
3923
+ return /* @__PURE__ */ jsxs(
3924
+ Box,
3925
+ {
3926
+ sx: {
3927
+ py: 1.5,
3928
+ px: 2,
3929
+ background: "#fff",
3930
+ width: "fit-content",
3931
+ maxWidth: "calc(100% - 16px)",
3932
+ wordWrap: "break-word",
3933
+ borderRadius: 1
3934
+ },
3935
+ children: [
3936
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "row", alignItems: "center", color: "primary.light" }, children: [
3937
+ /* @__PURE__ */ jsx(Icon, { icon: "tabler:message-circle-2", style: { height: 15, width: 15, marginRight: 4 } }),
3938
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { mr: 0.5 }, children: message.sourceUser.fullName }),
3939
+ /* @__PURE__ */ jsxs("span", { children: [
3940
+ " ",
3941
+ t("chat.mentionInComment")
3942
+ ] })
3943
+ ] }),
3944
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", sx: { fontSize: 16 }, children: (_g = (_e = message == null ? void 0 : message.comment) == null ? void 0 : _e.excerpt) == null ? void 0 : _g.replace((_f = session == null ? void 0 : session.user) == null ? void 0 : _f.fullName, "") }),
3945
+ renderQuote(message.post)
3946
+ ]
3947
+ }
3948
+ );
3776
3949
  }
3777
3950
  if (message.type === "mentionInPost") {
3778
- return /* @__PURE__ */ jsxs(Box, { children: [
3779
- /* @__PURE__ */ jsxs(Box, { children: [
3780
- /* @__PURE__ */ jsx(Box, { component: "span", sx: { color: "grey.600", fontWeight: "bold" }, children: message.sourceUser.fullName }),
3781
- /* @__PURE__ */ jsx("span", { children: " mentioned you in a post:" })
3782
- ] }),
3783
- renderQuote(message.post)
3784
- ] });
3951
+ return /* @__PURE__ */ jsxs(
3952
+ Box,
3953
+ {
3954
+ sx: {
3955
+ py: 1.5,
3956
+ px: 2,
3957
+ borderRadius: 1,
3958
+ background: "#fff",
3959
+ width: "fit-content",
3960
+ maxWidth: "calc(100% - 16px)",
3961
+ wordWrap: "break-word"
3962
+ },
3963
+ children: [
3964
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "row", alignItems: "center", color: "primary.light" }, children: [
3965
+ /* @__PURE__ */ jsx(Icon, { icon: "tabler:message-circle-2", style: { height: 15, width: 15, marginRight: 4 } }),
3966
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { mr: 0.5 }, children: message.sourceUser.fullName }),
3967
+ /* @__PURE__ */ jsx("span", { children: t("chat.mentionInPost") })
3968
+ ] }),
3969
+ renderQuote(message.post)
3970
+ ]
3971
+ }
3972
+ );
3785
3973
  }
3786
3974
  if (message.type === "pointUp") {
3787
3975
  const { points, post, comment, eventKey = "" } = message;
3788
- const unit = points > 1 ? "points" : "point";
3976
+ const unit = points > 1 ? t("chat.points") : t("chat.point");
3789
3977
  const event = eventKey ? `for ${eventKey.toLowerCase().replaceAll("-", " ")}: ` : ": ";
3790
- const tip = `🎉 You got ${points} ${unit} ${event}`;
3978
+ const tip = t("chat.pointUp", { points, unit, event });
3791
3979
  return /* @__PURE__ */ jsxs(Box, { children: [
3792
3980
  /* @__PURE__ */ jsx(Box, { component: "span", sx: { color: "grey.600" }, children: tip }),
3793
3981
  comment && /* @__PURE__ */ jsx(Typography, { variant: "body1", children: comment.excerpt }),
@@ -3796,24 +3984,39 @@ function NotificationMessage({ chat, message, prevMessage, ...rest }) {
3796
3984
  }
3797
3985
  if (message.type === "task") {
3798
3986
  const titles = {
3799
- open: " opened a post",
3800
- close: " closed a post",
3801
- assign: " assigned you to a post",
3802
- unassign: " unassigned you from a post"
3987
+ open: t("chat.openTask"),
3988
+ close: t("chat.closeTask"),
3989
+ assign: t("chat.assignTask"),
3990
+ unassign: t("chat.unassignTask")
3803
3991
  };
3804
- return /* @__PURE__ */ jsxs(Box, { children: [
3805
- /* @__PURE__ */ jsxs(Box, { children: [
3806
- /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontWeight: "bold" }, children: message.sourceUser.fullName }),
3807
- /* @__PURE__ */ jsx("span", { children: titles[message.subtype] })
3808
- ] }),
3809
- renderQuote(message.post)
3810
- ] });
3992
+ return /* @__PURE__ */ jsxs(
3993
+ Box,
3994
+ {
3995
+ sx: {
3996
+ py: 1.5,
3997
+ px: 2,
3998
+ borderRadius: 1,
3999
+ background: "#fff",
4000
+ width: "fit-content",
4001
+ maxWidth: "calc(100% - 16px)",
4002
+ wordWrap: "break-word"
4003
+ },
4004
+ children: [
4005
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", flexDirection: "row", alignItems: "center", color: "primary.light" }, children: [
4006
+ /* @__PURE__ */ jsx(Icon, { icon: "tabler:arrow-forward-up", style: { height: 15, width: 15, marginRight: 4 } }),
4007
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { mr: 0.5 }, children: message.sourceUser.fullName }),
4008
+ /* @__PURE__ */ jsx("span", { children: titles[message.subtype] })
4009
+ ] }),
4010
+ renderQuote(message.post)
4011
+ ]
4012
+ }
4013
+ );
3811
4014
  }
3812
4015
  return /* @__PURE__ */ jsx(Message, { message, showTime: false });
3813
4016
  };
3814
4017
  const messageInterval = message.createdAt.getTime() - ((prevMessage == null ? void 0 : prevMessage.createdAt.getTime()) || 0);
3815
4018
  return /* @__PURE__ */ jsxs(Box, { ...rest, sx: { mt: 2 }, children: [
3816
- messageInterval > 6e4 && /* @__PURE__ */ jsx(Box, { sx: { my: 2, textAlign: "center" }, children: /* @__PURE__ */ jsx(Box, { sx: { display: "inline-block", px: 1, fontSize: 12, bgcolor: "grey.300", borderRadius: "4px" }, children: dayjs(message.createdAt).format("MM-DD HH:mm") }) }),
4019
+ messageInterval > 6e4 && /* @__PURE__ */ jsx(Box, { sx: { my: 2, textAlign: "center" }, children: /* @__PURE__ */ jsx(Box, { sx: { display: "inline-block", px: 1, fontSize: 12, bgcolor: "grey.300", borderRadius: 0.5 }, children: dayjs(message.createdAt).format("MM-DD HH:mm") }) }),
3817
4020
  /* @__PURE__ */ jsx(Box, { sx: { p: 2, fontSize: 14, "&:hover": { bgcolor: "grey.50" } }, children: render() })
3818
4021
  ] });
3819
4022
  }
@@ -3981,7 +4184,9 @@ function Back({ url, fallbackUrl, iconOnly, sx, ...rest }) {
3981
4184
  }
3982
4185
  function ChatRoom({ chat, ...rest }) {
3983
4186
  var _a2;
3984
- const downSm = useMediaQuery((theme) => theme.breakpoints.down("sm"));
4187
+ const { t } = useLocaleContext();
4188
+ const theme = useTheme();
4189
+ const downSm = useMediaQuery((currentTheme) => currentTheme.breakpoints.down("sm"));
3985
4190
  const { initChatRoom, isActiveChat, getOppositeUser, sendMessage, joinChannel, leaveChannel, deleteChannel } = useChatContext();
3986
4191
  const { confirm } = useConfirm();
3987
4192
  const isActive = isActiveChat(chat.id);
@@ -3994,8 +4199,8 @@ function ChatRoom({ chat, ...rest }) {
3994
4199
  }, [chat.isActivated]);
3995
4200
  const handleDeleteChannel = async () => {
3996
4201
  const proceed = await confirm({
3997
- title: "Delete this channel?",
3998
- description: "If you delete this channel, all messages in the channel will be deleted immediately.",
4202
+ title: t("chat.deleteChannelTitle"),
4203
+ description: t("chat.deleteChannelDesc"),
3999
4204
  okButtonProps: { color: "error" }
4000
4205
  });
4001
4206
  if (proceed) {
@@ -4004,38 +4209,32 @@ function ChatRoom({ chat, ...rest }) {
4004
4209
  };
4005
4210
  const renderRoomHeader = () => {
4006
4211
  if (chat.type === "notification") {
4007
- return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", gap: 1, flex: 1 }, children: /* @__PURE__ */ jsx(SystemUser, { name: "Notification", showDidAddress: false, size: "sm" }) });
4212
+ return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", gap: 1, flex: 1 }, children: /* @__PURE__ */ jsx(SystemUser, { name: t("chat.notification"), showDidAddress: false, size: "sm", showIcon: false }) });
4008
4213
  }
4009
4214
  if (chat.type === "dm") {
4010
4215
  const oppositeUser = getOppositeUser(chat);
4011
- return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1, flex: 1 }, children: [
4012
- /* @__PURE__ */ jsx(Avatar, { did: oppositeUser.did, src: oppositeUser.avatar, size: 28, shape: "circle", variant: "circle" }),
4013
- /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontSize: 14, color: "grey.600", fontWeight: "bold" }, children: oppositeUser.fullName })
4014
- ] });
4216
+ return /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", gap: 1, flex: 1 }, children: /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontSize: 14, color: "grey.600", fontWeight: "bold" }, children: oppositeUser.fullName }) });
4015
4217
  }
4016
4218
  if (chat.type === "channel") {
4017
4219
  const menuItems = [];
4018
4220
  if (chat.hasJoined && !isCreator) {
4019
4221
  menuItems.push(
4020
- /* @__PURE__ */ jsx(Menu.Item, { onClick: () => leaveChannel(chat.id), children: /* @__PURE__ */ jsx(Box, { component: "span", sx: { color: "error.main" }, children: "Leave channel" }) }, "leave")
4222
+ /* @__PURE__ */ jsx(Menu.Item, { onClick: () => leaveChannel(chat.id), children: /* @__PURE__ */ jsx(Box, { component: "span", sx: { color: "error.main" }, children: t("chat.leaveChannel") }) }, "leave")
4021
4223
  );
4022
4224
  }
4023
4225
  if (isAdmin || isCreator) {
4024
4226
  menuItems.push(
4025
- /* @__PURE__ */ jsx(Menu.Item, { onClick: handleDeleteChannel, children: /* @__PURE__ */ jsx(Box, { component: "span", sx: { color: "error.main" }, children: "Delete channel" }) }, "delete")
4227
+ /* @__PURE__ */ jsx(Menu.Item, { onClick: handleDeleteChannel, children: /* @__PURE__ */ jsx(Box, { component: "span", sx: { color: "error.main" }, children: t("chat.deleteChannel") }) }, "delete")
4026
4228
  );
4027
4229
  }
4028
4230
  return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", width: 1, flex: 1 }, children: [
4029
4231
  /* @__PURE__ */ jsxs(Box, { children: [
4030
- /* @__PURE__ */ jsxs(Box, { component: "span", sx: { fontSize: 14, fontWeight: "bold", color: "grey.700" }, children: [
4031
- "# ",
4032
- chat.name
4033
- ] }),
4232
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontSize: 14, fontWeight: "bold", color: "grey.700" }, children: chat.name }),
4034
4233
  /* @__PURE__ */ jsx(Box, { sx: { fontSize: 12, color: "grey.500" }, children: chat.description })
4035
4234
  ] }),
4036
4235
  /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
4037
- !chat.hasJoined && /* @__PURE__ */ jsx(Button, { variant: "contained", color: "primary", onClick: () => joinChannel(chat.id), children: "Join channel" }),
4038
- !!chat.hasJoined && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Participants, { users: chat.participants }) }),
4236
+ !chat.hasJoined && /* @__PURE__ */ jsx(Button, { variant: "contained", color: "primary", onClick: () => joinChannel(chat.id), children: t("chat.joinChannel") }),
4237
+ chat.hasJoined && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Participants, { users: chat.participants, sx: { border: "none" } }) }),
4039
4238
  /* @__PURE__ */ jsx(Menu, { items: menuItems })
4040
4239
  ] })
4041
4240
  ] });
@@ -4063,7 +4262,7 @@ function ChatRoom({ chat, ...rest }) {
4063
4262
  ]
4064
4263
  }
4065
4264
  ),
4066
- /* @__PURE__ */ jsx(Box, { sx: { flex: 1, overflow: "hidden" }, children: /* @__PURE__ */ jsx(MessageList, { chat }) }),
4265
+ /* @__PURE__ */ jsx(Box, { sx: { flex: 1, overflow: "hidden", background: theme.palette.grey[50] }, children: /* @__PURE__ */ jsx(MessageList, { chat }) }),
4067
4266
  /* @__PURE__ */ jsx(
4068
4267
  Box,
4069
4268
  {
@@ -4090,6 +4289,8 @@ function NewChannelDialog({ open, onSubmit, onClose, ...rest }) {
4090
4289
  name: "",
4091
4290
  description: ""
4092
4291
  });
4292
+ const { t } = useLocaleContext();
4293
+ const theme = useTheme();
4093
4294
  const canSubmit = useMemo(() => {
4094
4295
  return state.name;
4095
4296
  }, [state]);
@@ -4102,35 +4303,70 @@ function NewChannelDialog({ open, onSubmit, onClose, ...rest }) {
4102
4303
  open,
4103
4304
  showCloseButton: true,
4104
4305
  maxWidth: "lg",
4105
- title: "New channel",
4106
- actions: /* @__PURE__ */ jsxs(Fragment, { children: [
4107
- /* @__PURE__ */ jsx(Button, { color: "inherit", variant: "contained", size: "small", onClick: onClose, children: "Cancel" }),
4108
- /* @__PURE__ */ jsx(Button, { color: "primary", variant: "contained", size: "small", onClick: handleSubmit, disabled: !canSubmit, children: "Create" })
4109
- ] }),
4306
+ title: t("chat.newChannel"),
4307
+ sx: {
4308
+ "& .MuiDialogContent-root": {
4309
+ borderTop: `1px solid ${theme.palette.divider}`,
4310
+ borderBottom: `1px solid ${theme.palette.divider}`
4311
+ }
4312
+ },
4313
+ actions: /* @__PURE__ */ jsxs(
4314
+ Button,
4315
+ {
4316
+ color: "primary",
4317
+ sx: { mt: 1 },
4318
+ variant: "contained",
4319
+ size: "small",
4320
+ onClick: handleSubmit,
4321
+ disabled: !canSubmit,
4322
+ children: [
4323
+ /* @__PURE__ */ jsx(AddIcon, { sx: { mr: 0.375 } }),
4324
+ t("chat.create")
4325
+ ]
4326
+ }
4327
+ ),
4110
4328
  onClose,
4111
4329
  ...rest,
4112
- children: /* @__PURE__ */ jsxs(Box, { width: { xs: "100%", md: 600 }, minHeight: 140, children: [
4330
+ children: /* @__PURE__ */ jsxs(Box, { width: { xs: "100%", md: 560 }, minHeight: 140, children: [
4331
+ /* @__PURE__ */ jsx(Box, { sx: { fontSize: 14, lineHeight: 3, fontWeight: "medium", mb: 1 }, children: t("chat.channel") }),
4113
4332
  /* @__PURE__ */ jsx(
4114
4333
  TextField,
4115
4334
  {
4116
- label: "Name",
4117
4335
  value: state.name,
4118
- placeholder: "Channel name",
4336
+ placeholder: t("chat.channelName"),
4119
4337
  size: "small",
4120
4338
  fullWidth: true,
4339
+ sx: {
4340
+ "& .MuiInputBase-root": {
4341
+ height: 40,
4342
+ backgroundColor: theme.palette.grey[100]
4343
+ }
4344
+ },
4121
4345
  onChange: (e) => setState({ name: e.target.value })
4122
4346
  }
4123
4347
  ),
4348
+ /* @__PURE__ */ jsx(Box, { sx: { fontSize: 14, lineHeight: 3, fontWeight: "medium", mt: 1 }, children: t("chat.description") }),
4124
4349
  /* @__PURE__ */ jsx(
4125
4350
  TextField,
4126
4351
  {
4127
- label: "Description",
4128
4352
  value: state.description,
4129
- placeholder: "Channel description",
4130
- size: "small",
4353
+ placeholder: t("chat.channelDescription"),
4131
4354
  fullWidth: true,
4355
+ multiline: true,
4132
4356
  onChange: (e) => setState({ description: e.target.value }),
4133
- sx: { mt: 2 }
4357
+ sx: {
4358
+ my: 1,
4359
+ "& .MuiInputBase-root": {
4360
+ height: 64,
4361
+ display: "flex",
4362
+ alignItems: "flex-start",
4363
+ backgroundColor: theme.palette.grey[100]
4364
+ },
4365
+ "& .MuiInputBase-inputMultiline": {
4366
+ maxHeight: "100%",
4367
+ overflowY: "auto"
4368
+ }
4369
+ }
4134
4370
  }
4135
4371
  )
4136
4372
  ] })
@@ -4138,6 +4374,7 @@ function NewChannelDialog({ open, onSubmit, onClose, ...rest }) {
4138
4374
  );
4139
4375
  }
4140
4376
  function Empty({ sx }) {
4377
+ const { t } = useLocaleContext();
4141
4378
  const mergedSx = [
4142
4379
  {
4143
4380
  display: "flex",
@@ -4151,26 +4388,27 @@ function Empty({ sx }) {
4151
4388
  ];
4152
4389
  return /* @__PURE__ */ jsxs(Box, { sx: mergedSx, children: [
4153
4390
  /* @__PURE__ */ jsx(iconoirChatBubbleEmpty, { style: { fontSize: 32 } }),
4154
- /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontSize: 14, fontWeight: "bold" }, children: "No chats" })
4391
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontSize: 14, fontWeight: "bold" }, children: t("chat.noChats") })
4155
4392
  ] });
4156
4393
  }
4157
4394
  function Chat({ sx, ...rest }) {
4158
4395
  const { client: client2, initialized, chats, activeChatId, addChat, setActiveChat, refresh, getOppositeUser } = useChatContext();
4159
4396
  const [newChannelVisible, setNewChannelVisible] = useState(false);
4160
4397
  const downMd = useMediaQuery((theme) => theme.breakpoints.down("sm"));
4398
+ const { t } = useLocaleContext();
4161
4399
  const activeChat = chats.filter((chat) => (chat == null ? void 0 : chat.id) === activeChatId)[0];
4162
4400
  const webTitleMap = {
4163
4401
  dm: () => {
4164
4402
  var _a2;
4165
- return ((_a2 = getOppositeUser(activeChat)) == null ? void 0 : _a2.fullName) || "Unknown";
4403
+ return ((_a2 = getOppositeUser(activeChat)) == null ? void 0 : _a2.fullName) || t("chat.unknown");
4166
4404
  },
4167
- notification: () => "Notification",
4168
- channel: () => (activeChat == null ? void 0 : activeChat.type) === "channel" ? `#${activeChat.name}` : "Unknown Channel",
4169
- default: () => "Chats"
4405
+ notification: () => t("chat.notification"),
4406
+ channel: () => (activeChat == null ? void 0 : activeChat.type) === "channel" ? `#${activeChat.name}` : t("chat.unknownChannel"),
4407
+ default: () => t("chat.chats")
4170
4408
  };
4171
4409
  const getWebTitle = () => {
4172
4410
  if (!activeChat) {
4173
- return "Chats";
4411
+ return t("chat.chats");
4174
4412
  }
4175
4413
  const getTitle = webTitleMap[activeChat.type] || webTitleMap.default;
4176
4414
  return getTitle();
@@ -4193,10 +4431,7 @@ function Chat({ sx, ...rest }) {
4193
4431
  if (!initialized) {
4194
4432
  return /* @__PURE__ */ jsx(CircularProgress, {});
4195
4433
  }
4196
- const mergedSx = [
4197
- { display: "flex", height: "100%", bgcolor: "#fff", borderRadius: 1 },
4198
- ...Array.isArray(sx) ? sx : [sx]
4199
- ];
4434
+ const mergedSx = [{ display: "flex", height: "100%", bgcolor: "#fff" }, ...Array.isArray(sx) ? sx : [sx]];
4200
4435
  const handleNewChannel = async ({ name, description }) => {
4201
4436
  const saved = await client2.createChannel(name, description);
4202
4437
  const newChannel = { ...saved, hasJoined: true };
@@ -4228,11 +4463,15 @@ function Chat({ sx, ...rest }) {
4228
4463
  borderBottom: "1px solid #e5e5e5"
4229
4464
  },
4230
4465
  children: [
4231
- /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
4232
- /* @__PURE__ */ jsx(Back, { iconOnly: true, fallbackUrl: "/discussions" }),
4233
- /* @__PURE__ */ jsx(Typography, { component: "span", variant: "subtitle1", sx: { fontSize: 16, fontWeight: "bold" }, children: "Chats" })
4234
- ] }),
4235
- /* @__PURE__ */ jsx(AccessControl, { roles: ["owner", "admin"], children: /* @__PURE__ */ jsx(IconButton$1, { onClick: () => setNewChannelVisible(true), children: /* @__PURE__ */ jsx(Add, {}) }) })
4466
+ /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: /* @__PURE__ */ jsx(Typography, { component: "span", variant: "subtitle1", sx: { fontSize: 16, fontWeight: "bold" }, children: t("chat.chats") }) }),
4467
+ /* @__PURE__ */ jsx(AccessControl, { roles: ["owner", "admin"], children: /* @__PURE__ */ jsx(
4468
+ IconButton$1,
4469
+ {
4470
+ onClick: () => setNewChannelVisible(true),
4471
+ sx: { p: 1, borderRadius: 1, border: `1px solid ${grey[200]}` },
4472
+ children: /* @__PURE__ */ jsx(Add, { sx: { color: "#000" } })
4473
+ }
4474
+ ) })
4236
4475
  ]
4237
4476
  }
4238
4477
  ),
@@ -4583,7 +4822,7 @@ function Pagination({
4583
4822
  }
4584
4823
  );
4585
4824
  }
4586
- const Editor = lazy(() => import("./editor-8X1A2syI.mjs"));
4825
+ const Editor = lazy(() => import("./editor-tuTpD7pf.mjs"));
4587
4826
  function LazyEditor(props) {
4588
4827
  const fallback = /* @__PURE__ */ jsxs(Fragment, { children: [
4589
4828
  /* @__PURE__ */ jsx(Skeleton, {}),
@@ -4659,7 +4898,7 @@ const DirtyPromptContainer = createContainer(useDirtyPrompt);
4659
4898
  function ConfirmNavigation() {
4660
4899
  const { t } = useLocaleContext();
4661
4900
  const { dirty, reset } = DirtyPromptContainer.useContainer();
4662
- const blocker = unstable_useBlocker(dirty);
4901
+ const blocker = useBlocker(dirty);
4663
4902
  useEffect(() => {
4664
4903
  if (blocker.state === "blocked" && !dirty) {
4665
4904
  blocker.reset();
@@ -4732,8 +4971,37 @@ const en = {
4732
4971
  timeout: "Request timeout: please retry the request later",
4733
4972
  error: "Oops, your request failed. Please try again"
4734
4973
  },
4735
- message: {
4736
- newPost: " create a new post:"
4974
+ chat: {
4975
+ notification: "Notification",
4976
+ unknown: "Unknown",
4977
+ chats: "Chats",
4978
+ create: "Create",
4979
+ channel: "Channel",
4980
+ description: "Description",
4981
+ newChannel: "New channel",
4982
+ noChats: "No chats",
4983
+ unknownChannel: "Unknown Channel",
4984
+ channelDescription: "Channel Description",
4985
+ channelName: "Channel Name",
4986
+ deleteChannel: "Delete Channel",
4987
+ commentedYourPost: "commented your post",
4988
+ commentedPost: "commented post",
4989
+ newPost: "create a new post",
4990
+ mentionInComment: "mentioned you in a comment",
4991
+ mentionInPost: "mentioned you in a post",
4992
+ replyYourComment: "replied your comment",
4993
+ replyComment: "replied comment",
4994
+ deleteChannelTitle: "Delete this channel?",
4995
+ deleteChannelDesc: "If you delete this channel, all messages in the channel will be deleted immediately.",
4996
+ leaveChannel: "Leave channel",
4997
+ joinChannel: "Join channel",
4998
+ openTask: "opened a post",
4999
+ closeTask: "closed a post",
5000
+ assignTask: "assigned you to a post",
5001
+ unassignTask: "unassigned you from a post",
5002
+ points: "points",
5003
+ point: "point",
5004
+ pointUp: "🎉 You got {points} {unit} {event}"
4737
5005
  }
4738
5006
  };
4739
5007
  const zh = {
@@ -4778,8 +5046,37 @@ const zh = {
4778
5046
  timeout: "请求超时: 请稍后重试",
4779
5047
  error: "哎呀,您的请求失败了,请稍后重试"
4780
5048
  },
4781
- message: {
4782
- newPost: " 创建了一个新的帖子:"
5049
+ chat: {
5050
+ notification: "通知",
5051
+ unknown: "未命名",
5052
+ chats: "聊天",
5053
+ create: "创建",
5054
+ channel: "频道",
5055
+ description: "描述",
5056
+ newChannel: "新的频道",
5057
+ noChats: "暂无对话",
5058
+ unknownChannel: "未命名的频道",
5059
+ channelDescription: "频道描述",
5060
+ channelName: "频道名称",
5061
+ deleteChannel: "删除频道",
5062
+ commentedYourPost: "评论了你的帖子",
5063
+ commentedPost: "评论了帖子",
5064
+ newPost: "创建了一个新的帖子:",
5065
+ mentionInComment: "在评论里提及了你",
5066
+ mentionInPost: "在帖子里提及了你",
5067
+ replyYourComment: "回复了你的评论",
5068
+ replyComment: "回复了评论",
5069
+ deleteChannelTitle: "确认删除这个频道?",
5070
+ deleteChannelDesc: "如果你要删除这个频道, 所有频道的消息都会立刻消除。",
5071
+ leaveChannel: "离开频道",
5072
+ joinChannel: "加入频道",
5073
+ openTask: "创建了一个任务",
5074
+ closeTask: "关闭了一个任务",
5075
+ assignTask: "分配给你一个任务",
5076
+ unassignTask: "取消给你分配的一个任务",
5077
+ points: "分",
5078
+ point: "分",
5079
+ pointUp: "🎉 您获得了 {points} {unit} {event}"
4783
5080
  }
4784
5081
  };
4785
5082
  const translations = { zh, en };
@@ -10636,60 +10933,106 @@ const Group = css`
10636
10933
  display: none; /* Chrome, Safari and Opera */
10637
10934
  }
10638
10935
  `;
10936
+ function SegmentedControl({ value, options, onChange, sx, ...rest }) {
10937
+ const mergedSx = mergeSx(
10938
+ {
10939
+ display: "inline-flex",
10940
+ borderRadius: "100vh",
10941
+ bgcolor: "grey.100"
10942
+ },
10943
+ sx
10944
+ );
10945
+ return /* @__PURE__ */ jsx(Paper, { elevation: 0, sx: mergedSx, ...rest, children: /* @__PURE__ */ jsx(
10946
+ ToggleButtonGroup,
10947
+ {
10948
+ size: "small",
10949
+ value,
10950
+ exclusive: true,
10951
+ onChange: (_, v2) => onChange == null ? void 0 : onChange(v2),
10952
+ sx: {
10953
+ ".MuiToggleButtonGroup-grouped": {
10954
+ m: 0.5,
10955
+ px: 1.5,
10956
+ border: 0,
10957
+ borderRadius: "100vh",
10958
+ lineHeight: 1.3,
10959
+ textTransform: "none"
10960
+ },
10961
+ ".MuiToggleButtonGroup-grouped.Mui-selected": {
10962
+ bgcolor: "#fff",
10963
+ border: 1,
10964
+ borderColor: "divider",
10965
+ ":hover": {
10966
+ bgcolor: "grey.50"
10967
+ }
10968
+ },
10969
+ ".MuiToggleButtonGroup-middleButton, .MuiToggleButtonGroup-lastButton": {
10970
+ marginLeft: "-1px",
10971
+ borderLeft: "1px solid transparent"
10972
+ }
10973
+ },
10974
+ children: options.map((x) => {
10975
+ return /* @__PURE__ */ jsx(ToggleButton, { value: x.value, children: x.label }, x.value);
10976
+ })
10977
+ }
10978
+ ) });
10979
+ }
10639
10980
  export {
10640
- UnreadNotificationProvider as $,
10981
+ useUnreadNotification as $,
10641
10982
  Avatar as A,
10642
10983
  Badge as B,
10643
10984
  CommentInput as C,
10644
10985
  DefaultEditorConfigProvider as D,
10645
10986
  EmptyStatus as E,
10646
- BlogCard as F,
10987
+ BlogListWrapper as F,
10647
10988
  GithubReaction as G,
10648
- BlogPermaLink as H,
10989
+ BlogCard as H,
10649
10990
  ImagePathFixerPlugin as I,
10650
- getBlogLink as J,
10651
- CoverImage as K,
10652
- CoverImageUpload as L,
10991
+ BlogPermaLink as J,
10992
+ getBlogLink as K,
10993
+ CoverImage as L,
10653
10994
  Menu as M,
10654
- AccessControl as N,
10655
- useAuthzContext as O,
10995
+ CoverImageUpload as N,
10996
+ AccessControl as O,
10656
10997
  Pagination as P,
10657
- AuthzProvider as Q,
10998
+ useAuthzContext as Q,
10658
10999
  RelativeTime as R,
10659
11000
  ScrollableEditorWrapper as S,
10660
- ChatClient as T,
10661
- Chat as U,
11001
+ AuthzProvider as T,
11002
+ ChatClient as U,
10662
11003
  VideoPathFixerPlugin as V,
10663
- ChatHeaderAddon as W,
10664
- useChatContext as X,
10665
- ChatProvider as Y,
10666
- UnreadNotificationContext as Z,
10667
- useUnreadNotification as _,
11004
+ Chat as W,
11005
+ ChatHeaderAddon as X,
11006
+ useChatContext as Y,
11007
+ ChatProvider as Z,
11008
+ UnreadNotificationContext as _,
10668
11009
  isEmptyContent as a,
10669
- Confirm as a0,
10670
- ConfirmContext as a1,
10671
- useConfirm as a2,
10672
- ConfirmProvider as a3,
10673
- SecureLabelPicker as a4,
10674
- useApiErrorHandler as a5,
10675
- useDefaultApiErrorHandler as a6,
10676
- PreviousLocationRecorder as a7,
10677
- Back as a8,
10678
- LazyEditor as a9,
10679
- EditorPreview as aa,
10680
- DirtyPromptContainer as ab,
10681
- ConfirmNavigation as ac,
10682
- UploaderContext as ad,
10683
- useUploader as ae,
10684
- UploaderTrigger as af,
10685
- UploaderProvider as ag,
10686
- composeImageUrl as ah,
10687
- usePointUpContext as ai,
10688
- PointUpProvider as aj,
10689
- ButtonGroup as ak,
10690
- create as al,
10691
- getWsClient as am,
10692
- useSubscription as an,
11010
+ UnreadNotificationProvider as a0,
11011
+ Confirm as a1,
11012
+ ConfirmContext as a2,
11013
+ useConfirm as a3,
11014
+ ConfirmProvider as a4,
11015
+ SecureLabelPicker as a5,
11016
+ useApiErrorHandler as a6,
11017
+ useDefaultApiErrorHandler as a7,
11018
+ PreviousLocationRecorder as a8,
11019
+ Back as a9,
11020
+ LazyEditor as aa,
11021
+ EditorPreview as ab,
11022
+ DirtyPromptContainer as ac,
11023
+ ConfirmNavigation as ad,
11024
+ UploaderContext as ae,
11025
+ useUploader as af,
11026
+ UploaderTrigger as ag,
11027
+ UploaderProvider as ah,
11028
+ composeImageUrl as ai,
11029
+ usePointUpContext as aj,
11030
+ PointUpProvider as ak,
11031
+ ButtonGroup as al,
11032
+ SegmentedControl as am,
11033
+ create as an,
11034
+ getWsClient as ao,
11035
+ useSubscription as ap,
10693
11036
  Input as b,
10694
11037
  useChanged as c,
10695
11038
  utils as d,
@@ -10701,18 +11044,18 @@ export {
10701
11044
  AuthorInfo as j,
10702
11045
  SystemUser as k,
10703
11046
  lexical as l,
10704
- PostContent as m,
10705
- PostComponent as n,
10706
- Comment as o,
11047
+ ChannelGroup as m,
11048
+ PostContent as n,
11049
+ PostComponent as o,
10707
11050
  preferences as p,
10708
- CommentList as q,
11051
+ Comment as q,
10709
11052
  routes as r,
10710
11053
  stringify as s,
10711
11054
  translations as t,
10712
11055
  useNow as u,
10713
- CommentsContext as v,
10714
- useCommentsContext as w,
10715
- CommentsProvider as x,
10716
- BinaryThumb as y,
10717
- BlogListWrapper as z
11056
+ CommentList as v,
11057
+ CommentsContext as w,
11058
+ useCommentsContext as x,
11059
+ CommentsProvider as y,
11060
+ BinaryThumb as z
10718
11061
  };