@blocklet/ui-react 2.11.29 → 2.11.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,46 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import Badge from "@mui/material/Badge";
3
3
  import PropTypes from "prop-types";
4
+ import { useCallback, useEffect } from "react";
4
5
  import { temp as colors } from "@arcblock/ux/lib/Colors";
5
6
  import { IconButton } from "@mui/material";
6
7
  import NotificationsOutlinedIcon from "@arcblock/icons/lib/Notification";
7
8
  import { useCreation } from "ahooks";
9
+ import { EVENTS } from "@abtnode/constant";
10
+ import { useListenWsClient } from "./ws.js";
8
11
  export default function NotificationAddon({ session = {} }) {
9
- const { unReadCount } = session;
12
+ const { unReadCount, user, setUnReadCount } = session;
13
+ const userDid = useCreation(() => user?.did, [user]);
10
14
  const viewAllUrl = useCreation(() => {
11
15
  const { navigation } = window.blocklet ?? {};
12
16
  const notification = navigation?.find((x) => x.id === "/userCenter/notification");
13
17
  return notification?.link;
14
18
  });
19
+ const wsClient = useListenWsClient("user");
20
+ const listenEvent = useCreation(
21
+ () => `${window.blocklet.did}/${userDid}/${EVENTS.NOTIFICATION_BLOCKLET_CREATE}`,
22
+ [userDid]
23
+ );
24
+ const listenCallback = useCallback(
25
+ (notification) => {
26
+ const { receivers } = notification ?? {};
27
+ const { receiver: notificationReceiver } = receivers[0] ?? {};
28
+ if (notificationReceiver === userDid) {
29
+ setUnReadCount((x) => x + 1);
30
+ }
31
+ },
32
+ [userDid, setUnReadCount]
33
+ );
34
+ useEffect(() => {
35
+ if (wsClient) {
36
+ wsClient.on(listenEvent, listenCallback);
37
+ }
38
+ return () => {
39
+ if (wsClient) {
40
+ wsClient.off(listenEvent, listenCallback);
41
+ }
42
+ };
43
+ }, [wsClient, setUnReadCount, listenCallback, listenEvent]);
15
44
  if (!session.user || !viewAllUrl) {
16
45
  return null;
17
46
  }
@@ -28,7 +57,7 @@ export default function NotificationAddon({ session = {} }) {
28
57
  borderRadius: "50%"
29
58
  }
30
59
  },
31
- children: /* @__PURE__ */ jsx(Badge, { variant: "dot", color: "error", invisible: unReadCount === 0, children: /* @__PURE__ */ jsx(NotificationsOutlinedIcon, { style: { width: "auto", height: 24 } }) })
60
+ children: /* @__PURE__ */ jsx(Badge, { badgeContent: unReadCount, color: "error", invisible: unReadCount === 0, children: /* @__PURE__ */ jsx(NotificationsOutlinedIcon, { style: { width: "auto", height: 24 } }) })
32
61
  }
33
62
  );
34
63
  }
@@ -0,0 +1,3 @@
1
+ export function create(endpoint?: string): any;
2
+ export default function getWsClient(endpoint?: string): any;
3
+ export function useListenWsClient(endpoint?: string): any;
@@ -0,0 +1,37 @@
1
+ import { useContext } from 'react';
2
+ import Cookie from 'js-cookie';
3
+ import { WsClient } from '@arcblock/ws';
4
+ import { SessionContext } from '@arcblock/did-connect/lib/Session';
5
+
6
+ const client = {};
7
+
8
+ export function create(endpoint = 'admin') {
9
+ const pathPrefix = (window.env && window.env.apiPrefix ? window.env.apiPrefix : '/').replace(/\/$/, '');
10
+ const url = `//${window.location.host}${pathPrefix}/.well-known/service/${endpoint}`;
11
+ return new WsClient(url, {
12
+ heartbeatIntervalMs: 100 * 1000,
13
+ params: () => ({
14
+ token: Cookie.get('login_token'),
15
+ }),
16
+ });
17
+ }
18
+
19
+ export default function getWsClient(endpoint = 'admin') {
20
+ if (!client[endpoint]) {
21
+ client[endpoint] = create(endpoint);
22
+ }
23
+
24
+ return client[endpoint];
25
+ }
26
+
27
+ export const useListenWsClient = (endpoint = 'admin') => {
28
+ const sessionCtx = useContext(SessionContext);
29
+ const { session } = sessionCtx ?? {};
30
+
31
+ if (!client[endpoint] && session.user) {
32
+ client[endpoint] = getWsClient(endpoint);
33
+ client[endpoint].connect();
34
+ }
35
+
36
+ return client[endpoint];
37
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/ui-react",
3
- "version": "2.11.29",
3
+ "version": "2.11.31",
4
4
  "description": "Some useful front-end web components that can be used in Blocklets.",
5
5
  "keywords": [
6
6
  "react",
@@ -32,9 +32,11 @@
32
32
  "url": "https://github.com/ArcBlock/ux/issues"
33
33
  },
34
34
  "dependencies": {
35
- "@arcblock/bridge": "^2.11.29",
36
- "@arcblock/react-hooks": "^2.11.29",
37
- "@blocklet/did-space-react": "^1.0.2",
35
+ "@abtnode/constant": "^1.16.38",
36
+ "@arcblock/bridge": "^2.11.31",
37
+ "@arcblock/react-hooks": "^2.11.31",
38
+ "@arcblock/ws": "^1.19.9",
39
+ "@blocklet/did-space-react": "^1.0.9",
38
40
  "@iconify-icons/logos": "^1.2.36",
39
41
  "@iconify-icons/material-symbols": "^1.2.58",
40
42
  "@iconify/react": "^4.1.1",
@@ -45,6 +47,7 @@
45
47
  "iconify-icon": "^1.0.8",
46
48
  "iconify-icons-material-symbols-400": "^0.0.1",
47
49
  "is-url": "^1.2.4",
50
+ "js-cookie": "^2.2.1",
48
51
  "lodash": "^4.17.21",
49
52
  "p-all": "^5.0.0",
50
53
  "p-queue": "^6.6.2",
@@ -57,9 +60,9 @@
57
60
  "ufo": "^1.5.3"
58
61
  },
59
62
  "peerDependencies": {
60
- "@arcblock/did-connect": "^2.11.22",
61
- "@arcblock/ux": "^2.11.22",
62
- "@blocklet/js-sdk": "^1.16.37",
63
+ "@arcblock/did-connect": "^2.11.30",
64
+ "@arcblock/ux": "^2.11.30",
65
+ "@blocklet/js-sdk": "^1.16.38",
63
66
  "@emotion/react": "^11.10.4",
64
67
  "@emotion/styled": "^11.10.4",
65
68
  "@mui/icons-material": "^5.15.0",
@@ -81,5 +84,5 @@
81
84
  "jest": "^29.7.0",
82
85
  "unbuild": "^2.0.0"
83
86
  },
84
- "gitHead": "adc33bd4f0d0dab0dbae75fbcddd585b0433c00f"
87
+ "gitHead": "31368d3bf32245481ff96e7946ade7062df01e6e"
85
88
  }
@@ -1,14 +1,18 @@
1
1
  import Badge from '@mui/material/Badge';
2
2
  import PropTypes from 'prop-types';
3
+ import { useCallback, useEffect } from 'react';
3
4
  import { temp as colors } from '@arcblock/ux/lib/Colors';
4
5
  import { IconButton } from '@mui/material';
5
6
 
6
7
  // eslint-disable-next-line import/no-extraneous-dependencies
7
8
  import NotificationsOutlinedIcon from '@arcblock/icons/lib/Notification';
8
9
  import { useCreation } from 'ahooks';
10
+ import { EVENTS } from '@abtnode/constant';
11
+ import { useListenWsClient } from './ws';
9
12
 
10
13
  export default function NotificationAddon({ session = {} }) {
11
- const { unReadCount } = session;
14
+ const { unReadCount, user, setUnReadCount } = session;
15
+ const userDid = useCreation(() => user?.did, [user]);
12
16
 
13
17
  const viewAllUrl = useCreation(() => {
14
18
  const { navigation } = window.blocklet ?? {};
@@ -16,6 +20,37 @@ export default function NotificationAddon({ session = {} }) {
16
20
  return notification?.link;
17
21
  });
18
22
 
23
+ const wsClient = useListenWsClient('user');
24
+
25
+ const listenEvent = useCreation(
26
+ () => `${window.blocklet.did}/${userDid}/${EVENTS.NOTIFICATION_BLOCKLET_CREATE}`,
27
+ [userDid]
28
+ );
29
+
30
+ const listenCallback = useCallback(
31
+ (notification) => {
32
+ const { receivers } = notification ?? {};
33
+
34
+ const { receiver: notificationReceiver } = receivers[0] ?? {};
35
+ // 更新列表
36
+ if (notificationReceiver === userDid) {
37
+ setUnReadCount((x) => x + 1);
38
+ }
39
+ },
40
+ [userDid, setUnReadCount]
41
+ );
42
+
43
+ useEffect(() => {
44
+ if (wsClient) {
45
+ wsClient.on(listenEvent, listenCallback);
46
+ }
47
+ return () => {
48
+ if (wsClient) {
49
+ wsClient.off(listenEvent, listenCallback);
50
+ }
51
+ };
52
+ }, [wsClient, setUnReadCount, listenCallback, listenEvent]);
53
+
19
54
  if (!session.user || !viewAllUrl) {
20
55
  return null;
21
56
  }
@@ -32,7 +67,7 @@ export default function NotificationAddon({ session = {} }) {
32
67
  borderRadius: '50%',
33
68
  },
34
69
  }}>
35
- <Badge variant="dot" color="error" invisible={unReadCount === 0}>
70
+ <Badge badgeContent={unReadCount} color="error" invisible={unReadCount === 0}>
36
71
  <NotificationsOutlinedIcon style={{ width: 'auto', height: 24 }} />
37
72
  </Badge>
38
73
  </IconButton>
@@ -0,0 +1,37 @@
1
+ import { useContext } from 'react';
2
+ import Cookie from 'js-cookie';
3
+ import { WsClient } from '@arcblock/ws';
4
+ import { SessionContext } from '@arcblock/did-connect/lib/Session';
5
+
6
+ const client = {};
7
+
8
+ export function create(endpoint = 'admin') {
9
+ const pathPrefix = (window.env && window.env.apiPrefix ? window.env.apiPrefix : '/').replace(/\/$/, '');
10
+ const url = `//${window.location.host}${pathPrefix}/.well-known/service/${endpoint}`;
11
+ return new WsClient(url, {
12
+ heartbeatIntervalMs: 100 * 1000,
13
+ params: () => ({
14
+ token: Cookie.get('login_token'),
15
+ }),
16
+ });
17
+ }
18
+
19
+ export default function getWsClient(endpoint = 'admin') {
20
+ if (!client[endpoint]) {
21
+ client[endpoint] = create(endpoint);
22
+ }
23
+
24
+ return client[endpoint];
25
+ }
26
+
27
+ export const useListenWsClient = (endpoint = 'admin') => {
28
+ const sessionCtx = useContext(SessionContext);
29
+ const { session } = sessionCtx ?? {};
30
+
31
+ if (!client[endpoint] && session.user) {
32
+ client[endpoint] = getWsClient(endpoint);
33
+ client[endpoint].connect();
34
+ }
35
+
36
+ return client[endpoint];
37
+ };