@blocklet/ui-react 3.1.48 → 3.1.49
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.
- package/.aigne/doc-smith/config.yaml +76 -0
- package/.aigne/doc-smith/history.yaml +9 -0
- package/.aigne/doc-smith/output/structure-plan.json +249 -0
- package/.aigne/doc-smith/upload-cache.yaml +528 -0
- package/docs/_sidebar.md +19 -0
- package/docs/components-component-management-blocklet-studio.ja.md +194 -0
- package/docs/components-component-management-blocklet-studio.md +194 -0
- package/docs/components-component-management-blocklet-studio.zh-TW.md +194 -0
- package/docs/components-component-management-blocklet-studio.zh.md +194 -0
- package/docs/components-component-management-component-installer.ja.md +256 -0
- package/docs/components-component-management-component-installer.md +256 -0
- package/docs/components-component-management-component-installer.zh-TW.md +256 -0
- package/docs/components-component-management-component-installer.zh.md +256 -0
- package/docs/components-component-management.ja.md +59 -0
- package/docs/components-component-management.md +59 -0
- package/docs/components-component-management.zh-TW.md +59 -0
- package/docs/components-component-management.zh.md +59 -0
- package/docs/components-layout-dashboard.ja.md +231 -0
- package/docs/components-layout-dashboard.md +231 -0
- package/docs/components-layout-dashboard.zh-TW.md +231 -0
- package/docs/components-layout-dashboard.zh.md +231 -0
- package/docs/components-layout-footer.ja.md +165 -0
- package/docs/components-layout-footer.md +165 -0
- package/docs/components-layout-footer.zh-TW.md +165 -0
- package/docs/components-layout-footer.zh.md +165 -0
- package/docs/components-layout-header.ja.md +233 -0
- package/docs/components-layout-header.md +233 -0
- package/docs/components-layout-header.zh-TW.md +233 -0
- package/docs/components-layout-header.zh.md +233 -0
- package/docs/components-layout.ja.md +50 -0
- package/docs/components-layout.md +50 -0
- package/docs/components-layout.zh-TW.md +50 -0
- package/docs/components-layout.zh.md +50 -0
- package/docs/components-notifications.ja.md +173 -0
- package/docs/components-notifications.md +173 -0
- package/docs/components-notifications.zh-TW.md +174 -0
- package/docs/components-notifications.zh.md +173 -0
- package/docs/components-user-management-user-center.ja.md +183 -0
- package/docs/components-user-management-user-center.md +183 -0
- package/docs/components-user-management-user-center.zh-TW.md +183 -0
- package/docs/components-user-management-user-center.zh.md +183 -0
- package/docs/components-user-management-user-sessions.ja.md +164 -0
- package/docs/components-user-management-user-sessions.md +164 -0
- package/docs/components-user-management-user-sessions.zh-TW.md +164 -0
- package/docs/components-user-management-user-sessions.zh.md +164 -0
- package/docs/components-user-management.ja.md +76 -0
- package/docs/components-user-management.md +76 -0
- package/docs/components-user-management.zh-TW.md +76 -0
- package/docs/components-user-management.zh.md +76 -0
- package/docs/components-utilities-icon.ja.md +106 -0
- package/docs/components-utilities-icon.md +106 -0
- package/docs/components-utilities-icon.zh-TW.md +106 -0
- package/docs/components-utilities-icon.zh.md +106 -0
- package/docs/components-utilities.ja.md +136 -0
- package/docs/components-utilities.md +136 -0
- package/docs/components-utilities.zh-TW.md +136 -0
- package/docs/components-utilities.zh.md +136 -0
- package/docs/components.ja.md +27 -0
- package/docs/components.md +27 -0
- package/docs/components.zh-TW.md +27 -0
- package/docs/components.zh.md +27 -0
- package/docs/core-concepts.ja.md +164 -0
- package/docs/core-concepts.md +164 -0
- package/docs/core-concepts.zh-TW.md +164 -0
- package/docs/core-concepts.zh.md +164 -0
- package/docs/getting-started.ja.md +132 -0
- package/docs/getting-started.md +132 -0
- package/docs/getting-started.zh-TW.md +132 -0
- package/docs/getting-started.zh.md +132 -0
- package/docs/hooks-api.ja.md +214 -0
- package/docs/hooks-api.md +214 -0
- package/docs/hooks-api.zh-TW.md +214 -0
- package/docs/hooks-api.zh.md +214 -0
- package/docs/how-to-guides.ja.md +413 -0
- package/docs/how-to-guides.md +413 -0
- package/docs/how-to-guides.zh-TW.md +413 -0
- package/docs/how-to-guides.zh.md +413 -0
- package/docs/overview.ja.md +91 -0
- package/docs/overview.md +91 -0
- package/docs/overview.zh-TW.md +91 -0
- package/docs/overview.zh.md +91 -0
- package/glossary.md +12 -0
- package/lib/Dashboard/index.js +46 -42
- package/lib/Footer/index.js +51 -36
- package/lib/Header/index.js +48 -44
- package/lib/UserCenter/components/settings.js +1 -0
- package/lib/UserCenter/components/user-center.js +133 -133
- package/lib/blocklets.d.ts +13 -2
- package/lib/blocklets.js +40 -40
- package/lib/common/header-addons.js +37 -33
- package/package.json +7 -7
- package/src/Dashboard/index.jsx +8 -3
- package/src/Footer/index.jsx +22 -4
- package/src/Header/index.tsx +7 -2
- package/src/UserCenter/components/settings.tsx +1 -0
- package/src/UserCenter/components/user-center.tsx +6 -6
- package/src/blocklets.js +18 -9
- package/src/common/header-addons.jsx +7 -2
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# 通知
|
|
2
|
+
|
|
3
|
+
このセクションでは、リアルタイムのユーザー通知システムを実装するために利用可能なコンポーネントとユーティリティに関する詳細なガイドを提供します。このシステムは、専用のUIコンポーネントとトーストメッセージを通じて、ユーザーにタイムリーな更新を配信するように設計されています。
|
|
4
|
+
|
|
5
|
+
通知システムの中心はWebSocket接続を中心に構築されており、サーバーがクライアントに即座に更新をプッシュできるようにします。これにより、ユーザーはアプリケーションをリフレッシュすることなく、常に重要なイベントについて知ることができます。
|
|
6
|
+
|
|
7
|
+
## アーキテクチャ概要
|
|
8
|
+
|
|
9
|
+
通知システムは、直接的でイベント駆動型のアーキテクチャに従います。バックエンドで注目すべきイベントが発生すると、通知が生成され、WebSocketチャネルを通じてブロードキャストされます。フロントエンドクライアントはこのチャネルをリッスンし、通知を受信して、UIを適宜更新します。
|
|
10
|
+
|
|
11
|
+
```d2
|
|
12
|
+
direction: down
|
|
13
|
+
|
|
14
|
+
User: {
|
|
15
|
+
shape: c4-person
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Backend: {
|
|
19
|
+
label: "Blocklet バックエンド"
|
|
20
|
+
shape: rectangle
|
|
21
|
+
|
|
22
|
+
Event-Trigger: {
|
|
23
|
+
label: "イベント発生"
|
|
24
|
+
shape: oval
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Notification-Service: {
|
|
28
|
+
label: "通知サービス"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
WebSocket-Server: {
|
|
33
|
+
label: "WebSocket サーバー"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
Frontend: {
|
|
37
|
+
label: "フロントエンドアプリケーション"
|
|
38
|
+
shape: rectangle
|
|
39
|
+
|
|
40
|
+
WebSocket-Client: {
|
|
41
|
+
label: "WebSocket クライアント"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
NotificationAddon: {
|
|
45
|
+
label: "NotificationAddon"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
SnackbarProvider: {
|
|
49
|
+
label: "SnackbarProvider"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Defines the flow of the notification process
|
|
54
|
+
Backend.Event-Trigger -> Backend.Notification-Service: "1. 通知をトリガー"
|
|
55
|
+
Backend.Notification-Service -> WebSocket-Server: "2. メッセージをプッシュ"
|
|
56
|
+
WebSocket-Server -> Frontend.WebSocket-Client: "3. クライアントにブロードキャスト"
|
|
57
|
+
Frontend.WebSocket-Client -> Frontend.NotificationAddon: "4. メッセージを転送"
|
|
58
|
+
Frontend.NotificationAddon -> Frontend.NotificationAddon: "5a. 未読件数を更新"
|
|
59
|
+
Frontend.NotificationAddon -> Frontend.SnackbarProvider: "5b. トースト通知を表示"
|
|
60
|
+
Frontend.SnackbarProvider -> User: "6. ユーザーに表示"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## コアコンポーネント
|
|
64
|
+
|
|
65
|
+
通知システムは、主に `NotificationAddon` と `NotificationSnackbar` の2つのReactコンポーネントで構成されています。
|
|
66
|
+
|
|
67
|
+
### NotificationAddon
|
|
68
|
+
|
|
69
|
+
`NotificationAddon` コンポーネントは、通知の主要なユーザーインターフェース要素として機能します。未読通知の数を示すバッジ付きのベルアイコンをレンダリングします。
|
|
70
|
+
|
|
71
|
+
#### 機能
|
|
72
|
+
|
|
73
|
+
- **未読件数**: 未読通知の数をリアルタイムで表示します。
|
|
74
|
+
- **WebSocket統合**: 通知用のWebSocketチャネルに自動的に接続し、受信メッセージをリッスンします。
|
|
75
|
+
- **トースト通知**: 新しいコンポーネントレベルの通知に対してトーストメッセージをトリガーします。
|
|
76
|
+
- **直接ナビゲーション**: メインの通知ページへのリンクとして機能します。
|
|
77
|
+
|
|
78
|
+
#### 使用方法
|
|
79
|
+
|
|
80
|
+
このコンポーネントを使用するには、インポートしてアプリケーションヘッダーなどのレイアウトコンポーネント内に配置します。正しく機能するためには、通常セッションコンテキストから取得される `session` オブジェクトが必要です。
|
|
81
|
+
|
|
82
|
+
```javascript "title=Example: Integrating NotificationAddon" icon=logos:javascript
|
|
83
|
+
import NotificationAddon from '@arcblock/ux/lib/common/notification-addon';
|
|
84
|
+
import { useSessionContext } from '@arcblock/did-connect-react';
|
|
85
|
+
|
|
86
|
+
export default function AppHeader() {
|
|
87
|
+
const { session } = useSessionContext();
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<header>
|
|
91
|
+
{/* 他のヘッダーコンテンツ */}
|
|
92
|
+
<NotificationAddon session={session} />
|
|
93
|
+
</header>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**重要**: トースト通知が機能するためには、アプリケーションが `notistack` ライブラリの `SnackbarProvider` でラップされている必要があります。
|
|
99
|
+
|
|
100
|
+
```javascript "title=Example: App wrapped in SnackbarProvider" icon=logos:javascript
|
|
101
|
+
import { SnackbarProvider } from 'notistack';
|
|
102
|
+
import App from './App';
|
|
103
|
+
|
|
104
|
+
function Root() {
|
|
105
|
+
return (
|
|
106
|
+
<SnackbarProvider maxSnack={3}>
|
|
107
|
+
<App />
|
|
108
|
+
</SnackbarProvider>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### Props
|
|
114
|
+
|
|
115
|
+
<x-field-group>
|
|
116
|
+
<x-field data-name="session" data-type="object" data-required="true">
|
|
117
|
+
<x-field-desc markdown>ユーザーおよび通知データを含むセッションオブジェクト。コンポーネントは `session.user`、`session.unReadCount`、および `session.setUnReadCount` に依存します。</x-field-desc>
|
|
118
|
+
</x-field>
|
|
119
|
+
</x-field-group>
|
|
120
|
+
|
|
121
|
+
### NotificationSnackbar
|
|
122
|
+
|
|
123
|
+
このコンポーネントは、トースト通知のためのリッチで標準化されたUIを提供します。`NotificationAddon` によって `notistack` の `enqueueSnackbar` 関数を介して内部的に使用され、直接使用することを意図していません。
|
|
124
|
+
|
|
125
|
+
#### 機能
|
|
126
|
+
|
|
127
|
+
- **重要度に基づくスタイリング**: 通知の重要度レベル(`success`、`info`、`warning`、`error`)に基づいてスナックバーの外観が変わります。
|
|
128
|
+
- **リッチコンテンツ表示**: 単純なタイトルや説明に加えて、構造化されたアクティビティ通知(例:「ユーザーXがあなたの投稿に「いいね!」しました」)を表示できます。
|
|
129
|
+
- **インタラクティブリンク**: 説明文中の認識されたパターン(ユーザーDIDやDAppアドレスなど)を自動的にクリック可能なリンクに変換します。
|
|
130
|
+
- **クリックして開く**: スナックバーをクリックすると、ユーザーは詳細な通知ビューに移動します。
|
|
131
|
+
|
|
132
|
+
## WebSocket統合
|
|
133
|
+
|
|
134
|
+
リアルタイム機能は、`useListenWsClient` フックによって管理されるWebSocketクライアントによって提供されます。このフックは、ログインしているユーザーの接続を確立し、特定のイベントをリッスンします。
|
|
135
|
+
|
|
136
|
+
### `useListenWsClient` フック
|
|
137
|
+
|
|
138
|
+
このフックは、WebSocket接続の作成と管理の複雑さを抽象化します。現在のユーザーセッションを取得し、指定されたエンドポイントに接続されたクライアントを初期化します。
|
|
139
|
+
|
|
140
|
+
```javascript "title=Hook Usage" icon=logos:javascript
|
|
141
|
+
const wsClient = useListenWsClient('user');
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### イベント
|
|
145
|
+
|
|
146
|
+
`NotificationAddon` コンポーネントは、`user` チャネルで以下のイベントを購読します。
|
|
147
|
+
|
|
148
|
+
| Event Name | Description |
|
|
149
|
+
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
150
|
+
| `notification:blocklet:create` | ユーザーに対して新しい通知が作成されたときに発行されます。コンポーネントは未読件数をインクリメントし、トーストメッセージを表示する場合があります。 |
|
|
151
|
+
| `notification:blocklet:read` | 1つ以上の通知が既読になったときに発行されます。コンポーネントは既読になった通知の数だけ未読件数をデクリメントします。 |
|
|
152
|
+
|
|
153
|
+
完全なイベント名は、blockletのDIDとユーザーのDIDを使用して動的に構築されます。例:`{blocklet.did}/{user.did}/notification:blocklet:create`。
|
|
154
|
+
|
|
155
|
+
## 主要なユーティリティ
|
|
156
|
+
|
|
157
|
+
いくつかのユーティリティ関数が、通知データを処理およびフォーマットすることで通知システムをサポートしています。
|
|
158
|
+
|
|
159
|
+
### `mergeAdjacentNotifications`
|
|
160
|
+
|
|
161
|
+
この関数は、連続する類似の通知を1つの集約されたエントリにまとめます。例えば、ユーザーが異なるユーザーから複数の「いいね!」通知を連続して受け取った場合、この関数はそれらを「アリス、ボブ、他2人があなたの投稿に「いいね!」しました」のような1つの通知にまとめることができます。
|
|
162
|
+
|
|
163
|
+
### `toClickableSpan`
|
|
164
|
+
|
|
165
|
+
このユーティリティは、プレーンテキストをリッチでインタラクティブなコンテンツに変換することで、通知の説明を強化する役割を担います。入力文字列を解析し、ユーザーDIDやDAppアドレスなどの特殊なエンティティを識別し、それらをクリック可能なHTMLの `<a>` タグに変換します。これにより、ユーザーは通知内から直接ユーザーのプロフィールやDAppのページに移動できます。
|
|
166
|
+
|
|
167
|
+
### `sanitize`
|
|
168
|
+
|
|
169
|
+
`DOMPurify` のラッパーで、レンダリング前にHTMLコンテンツをクリーンアップおよびサニタイズします。これは、ユーザー生成データを含む可能性のある通知コンテンツを表示する際のクロスサイトスクリプティング(XSS)攻撃を防ぐためのセキュリティ対策です。
|
|
170
|
+
|
|
171
|
+
## まとめ
|
|
172
|
+
|
|
173
|
+
通知システムは、ユーザーに情報を提供するための堅牢でリアルタイムなソリューションを提供します。`NotificationAddon` コンポーネントを活用し、アプリケーションが `SnackbarProvider` で設定されていることを確認することで、フル機能の通知センターをblockletに簡単に統合できます。基礎となるWebSocketアーキテクチャにより、更新が即座に配信され、ダイナミックで応答性の高いユーザーエクスペリエンスが生まれます。
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Notifications
|
|
2
|
+
|
|
3
|
+
This section provides a detailed guide to the components and utilities available for implementing a real-time user notification system. The system is designed to deliver timely updates to users through a dedicated UI component and toast messages.
|
|
4
|
+
|
|
5
|
+
The core of the notification system is built around a WebSocket connection, enabling the server to push updates to the client instantly. This ensures that users are always informed of important events without needing to refresh the application.
|
|
6
|
+
|
|
7
|
+
## Architecture Overview
|
|
8
|
+
|
|
9
|
+
The notification system follows a straightforward, event-driven architecture. When a notable event occurs in the backend, a notification is generated and broadcasted through a WebSocket channel. The frontend client listens on this channel, receives the notification, and updates the UI accordingly.
|
|
10
|
+
|
|
11
|
+
```d2
|
|
12
|
+
direction: down
|
|
13
|
+
|
|
14
|
+
User: {
|
|
15
|
+
shape: c4-person
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Backend: {
|
|
19
|
+
label: "Blocklet Backend"
|
|
20
|
+
shape: rectangle
|
|
21
|
+
|
|
22
|
+
Event-Trigger: {
|
|
23
|
+
label: "Event Occurs"
|
|
24
|
+
shape: oval
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Notification-Service: {
|
|
28
|
+
label: "Notification Service"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
WebSocket-Server: {
|
|
33
|
+
label: "WebSocket Server"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
Frontend: {
|
|
37
|
+
label: "Frontend Application"
|
|
38
|
+
shape: rectangle
|
|
39
|
+
|
|
40
|
+
WebSocket-Client: {
|
|
41
|
+
label: "WebSocket Client"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
NotificationAddon: {
|
|
45
|
+
label: "NotificationAddon"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
SnackbarProvider: {
|
|
49
|
+
label: "SnackbarProvider"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Defines the flow of the notification process
|
|
54
|
+
Backend.Event-Trigger -> Backend.Notification-Service: "1. Triggers notification"
|
|
55
|
+
Backend.Notification-Service -> WebSocket-Server: "2. Pushes message"
|
|
56
|
+
WebSocket-Server -> Frontend.WebSocket-Client: "3. Broadcasts to client"
|
|
57
|
+
Frontend.WebSocket-Client -> Frontend.NotificationAddon: "4. Forwards message"
|
|
58
|
+
Frontend.NotificationAddon -> Frontend.NotificationAddon: "5a. Updates unread count"
|
|
59
|
+
Frontend.NotificationAddon -> Frontend.SnackbarProvider: "5b. Shows toast notification"
|
|
60
|
+
Frontend.SnackbarProvider -> User: "6. Displays to user"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Core Components
|
|
64
|
+
|
|
65
|
+
The notification system is primarily composed of two React components: `NotificationAddon` and `NotificationSnackbar`.
|
|
66
|
+
|
|
67
|
+
### NotificationAddon
|
|
68
|
+
|
|
69
|
+
The `NotificationAddon` component serves as the main user interface element for notifications. It renders a bell icon that displays a badge indicating the number of unread notifications.
|
|
70
|
+
|
|
71
|
+
#### Features
|
|
72
|
+
|
|
73
|
+
- **Unread Count**: Displays a real-time count of unread notifications.
|
|
74
|
+
- **WebSocket Integration**: Automatically connects to the notification WebSocket channel and listens for incoming messages.
|
|
75
|
+
- **Toast Notifications**: Triggers toast messages for new component-level notifications.
|
|
76
|
+
- **Direct Navigation**: Functions as a link to the main notifications page.
|
|
77
|
+
|
|
78
|
+
#### Usage
|
|
79
|
+
|
|
80
|
+
To use this component, import it and place it within a layout component, such as an application header. It requires a `session` object, typically obtained from a session context, to function correctly.
|
|
81
|
+
|
|
82
|
+
```javascript "title=Example: Integrating NotificationAddon" icon=logos:javascript
|
|
83
|
+
import NotificationAddon from '@arcblock/ux/lib/common/notification-addon';
|
|
84
|
+
import { useSessionContext } from '@arcblock/did-connect-react';
|
|
85
|
+
|
|
86
|
+
export default function AppHeader() {
|
|
87
|
+
const { session } = useSessionContext();
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<header>
|
|
91
|
+
{/* Other header content */}
|
|
92
|
+
<NotificationAddon session={session} />
|
|
93
|
+
</header>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Important**: For the toast notifications to work, your application must be wrapped in a `SnackbarProvider` from the `notistack` library.
|
|
99
|
+
|
|
100
|
+
```javascript "title=Example: App wrapped in SnackbarProvider" icon=logos:javascript
|
|
101
|
+
import { SnackbarProvider } from 'notistack';
|
|
102
|
+
import App from './App';
|
|
103
|
+
|
|
104
|
+
function Root() {
|
|
105
|
+
return (
|
|
106
|
+
<SnackbarProvider maxSnack={3}>
|
|
107
|
+
<App />
|
|
108
|
+
</SnackbarProvider>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### Props
|
|
114
|
+
|
|
115
|
+
<x-field-group>
|
|
116
|
+
<x-field data-name="session" data-type="object" data-required="true">
|
|
117
|
+
<x-field-desc markdown>The session object containing user and notification data. The component relies on `session.user`, `session.unReadCount`, and `session.setUnReadCount`.</x-field-desc>
|
|
118
|
+
</x-field>
|
|
119
|
+
</x-field-group>
|
|
120
|
+
|
|
121
|
+
### NotificationSnackbar
|
|
122
|
+
|
|
123
|
+
This component provides a rich, standardized UI for toast notifications. It is used internally by `NotificationAddon` via `notistack`'s `enqueueSnackbar` function and is not intended for direct use.
|
|
124
|
+
|
|
125
|
+
#### Features
|
|
126
|
+
|
|
127
|
+
- **Severity-Based Styling**: The appearance of the snackbar changes based on the notification's severity level (`success`, `info`, `warning`, `error`).
|
|
128
|
+
- **Rich Content Display**: Capable of displaying structured activity notifications (e.g., "User X liked your post") in addition to simple titles and descriptions.
|
|
129
|
+
- **Interactive Links**: Automatically converts recognized patterns in the description (like user DIDs or DApp addresses) into clickable links.
|
|
130
|
+
- **Click-to-Open**: Clicking the snackbar navigates the user to the detailed notification view.
|
|
131
|
+
|
|
132
|
+
## WebSocket Integration
|
|
133
|
+
|
|
134
|
+
Real-time functionality is powered by a WebSocket client managed by the `useListenWsClient` hook. This hook establishes a connection for the logged-in user and listens for specific events.
|
|
135
|
+
|
|
136
|
+
### `useListenWsClient` Hook
|
|
137
|
+
|
|
138
|
+
This hook abstracts the complexity of creating and managing the WebSocket connection. It retrieves the current user session and initializes a client connected to a specified endpoint.
|
|
139
|
+
|
|
140
|
+
```javascript "title=Hook Usage" icon=logos:javascript
|
|
141
|
+
const wsClient = useListenWsClient('user');
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Events
|
|
145
|
+
|
|
146
|
+
The `NotificationAddon` component subscribes to the following events on the `user` channel:
|
|
147
|
+
|
|
148
|
+
| Event Name | Description |
|
|
149
|
+
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
150
|
+
| `notification:blocklet:create` | Fired when a new notification is created for the user. The component increments the unread count and may display a toast message. |
|
|
151
|
+
| `notification:blocklet:read` | Fired when one or more notifications have been read. The component decrements the unread count by the number of notifications that were read. |
|
|
152
|
+
|
|
153
|
+
The full event name is dynamically constructed using the blocklet's DID and the user's DID, for example: `{blocklet.did}/{user.did}/notification:blocklet:create`.
|
|
154
|
+
|
|
155
|
+
## Key Utilities
|
|
156
|
+
|
|
157
|
+
Several utility functions support the notification system by processing and formatting notification data.
|
|
158
|
+
|
|
159
|
+
### `mergeAdjacentNotifications`
|
|
160
|
+
|
|
161
|
+
This function groups consecutive, similar notifications into a single, aggregated entry. For example, if a user receives multiple "like" notifications in a row from different users, this function can merge them into a single notification like "Alice, Bob, and 2 others liked your post."
|
|
162
|
+
|
|
163
|
+
### `toClickableSpan`
|
|
164
|
+
|
|
165
|
+
This utility is responsible for enhancing notification descriptions by converting plain text into rich, interactive content. It parses the input string, identifies special entities like user DIDs or DApp addresses, and transforms them into clickable HTML `<a>` tags. This allows users to navigate directly to a user's profile or a DApp's page from within a notification.
|
|
166
|
+
|
|
167
|
+
### `sanitize`
|
|
168
|
+
|
|
169
|
+
A wrapper around `DOMPurify` that cleans and sanitizes HTML content before it is rendered. This is a security measure to prevent cross-site scripting (XSS) attacks when displaying notification content that may contain user-generated data.
|
|
170
|
+
|
|
171
|
+
## Summary
|
|
172
|
+
|
|
173
|
+
The notification system provides a robust and real-time solution for keeping users informed. By leveraging the `NotificationAddon` component and ensuring your application is configured with the `SnackbarProvider`, you can easily integrate a full-featured notification center into your blocklet. The underlying WebSocket architecture ensures that updates are delivered instantly, creating a dynamic and responsive user experience.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# 通知
|
|
2
|
+
|
|
3
|
+
本節詳細介紹了可用於實作即時使用者通知系統的元件和工具。該系統旨在透過專用的 UI 元件和快顯訊息,向使用者及時傳遞更新。
|
|
4
|
+
|
|
5
|
+
通知系統的核心圍繞 WebSocket 連線建構,使伺服器能夠即時向用戶端推送更新。這確保了使用者無需刷新應用程式即可隨時了解重要事件。
|
|
6
|
+
|
|
7
|
+
## 架構概覽
|
|
8
|
+
|
|
9
|
+
通知系統遵循一個直接的、事件驅動的架構。當後端發生值得注意的事件時,會產生一則通知並透過 WebSocket 通道廣播。前端用戶端會監聽此通道,接收通知,並相應地更新 UI。
|
|
10
|
+
|
|
11
|
+
```d2
|
|
12
|
+
direction: down
|
|
13
|
+
|
|
14
|
+
User: {
|
|
15
|
+
label: "使用者"
|
|
16
|
+
shape: c4-person
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
Backend: {
|
|
20
|
+
label: "Blocklet 後端"
|
|
21
|
+
shape: rectangle
|
|
22
|
+
|
|
23
|
+
Event-Trigger: {
|
|
24
|
+
label: "事件發生"
|
|
25
|
+
shape: oval
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
Notification-Service: {
|
|
29
|
+
label: "通知服務"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
WebSocket-Server: {
|
|
34
|
+
label: "WebSocket 伺服器"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
Frontend: {
|
|
38
|
+
label: "前端應用程式"
|
|
39
|
+
shape: rectangle
|
|
40
|
+
|
|
41
|
+
WebSocket-Client: {
|
|
42
|
+
label: "WebSocket 客戶端"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
NotificationAddon: {
|
|
46
|
+
label: "NotificationAddon"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
SnackbarProvider: {
|
|
50
|
+
label: "SnackbarProvider"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# 定義通知流程
|
|
55
|
+
Backend.Event-Trigger -> Backend.Notification-Service: "1. 觸發通知"
|
|
56
|
+
Backend.Notification-Service -> WebSocket-Server: "2. 推送訊息"
|
|
57
|
+
WebSocket-Server -> Frontend.WebSocket-Client: "3. 廣播至客戶端"
|
|
58
|
+
Frontend.WebSocket-Client -> Frontend.NotificationAddon: "4. 轉發訊息"
|
|
59
|
+
Frontend.NotificationAddon -> Frontend.NotificationAddon: "5a. 更新未讀計數"
|
|
60
|
+
Frontend.NotificationAddon -> Frontend.SnackbarProvider: "5b. 顯示快顯通知"
|
|
61
|
+
Frontend.SnackbarProvider -> User: "6. 向使用者顯示"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## 核心元件
|
|
65
|
+
|
|
66
|
+
通知系統主要由兩個 React 元件組成:`NotificationAddon` 和 `NotificationSnackbar`。
|
|
67
|
+
|
|
68
|
+
### NotificationAddon
|
|
69
|
+
|
|
70
|
+
`NotificationAddon` 元件是通知的主要使用者介面元素。它會渲染一個鈴鐺圖示,並帶有一個徽章,顯示未讀通知的數量。
|
|
71
|
+
|
|
72
|
+
#### 功能
|
|
73
|
+
|
|
74
|
+
- **未讀計數**:即時顯示未讀通知的數量。
|
|
75
|
+
- **WebSocket 整合**:自動連線到通知 WebSocket 通道並監聽傳入的訊息。
|
|
76
|
+
- **快顯通知**:針對新的元件級別通知觸發快顯訊息。
|
|
77
|
+
- **直接導覽**:作為連結,可導向主通知頁面。
|
|
78
|
+
|
|
79
|
+
#### 用法
|
|
80
|
+
|
|
81
|
+
若要使用此元件,請將其匯入並放置在佈局元件中,例如應用程式的標頭。它需要一個 `session` 物件才能正常運作,該物件通常從 session context 中獲取。
|
|
82
|
+
|
|
83
|
+
```javascript "title=範例:整合 NotificationAddon" icon=logos:javascript
|
|
84
|
+
import NotificationAddon from '@arcblock/ux/lib/common/notification-addon';
|
|
85
|
+
import { useSessionContext } from '@arcblock/did-connect-react';
|
|
86
|
+
|
|
87
|
+
export default function AppHeader() {
|
|
88
|
+
const { session } = useSessionContext();
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<header>
|
|
92
|
+
{/* 其他標頭內容 */}
|
|
93
|
+
<NotificationAddon session={session} />
|
|
94
|
+
</header>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**重要**:為了讓快顯通知正常運作,您的應用程式必須被 `notistack` 函式庫的 `SnackbarProvider` 包裹。
|
|
100
|
+
|
|
101
|
+
```javascript "title=範例:被 SnackbarProvider 包裹的 App" icon=logos:javascript
|
|
102
|
+
import { SnackbarProvider } from 'notistack';
|
|
103
|
+
import App from './App';
|
|
104
|
+
|
|
105
|
+
function Root() {
|
|
106
|
+
return (
|
|
107
|
+
<SnackbarProvider maxSnack={3}>
|
|
108
|
+
<App />
|
|
109
|
+
</SnackbarProvider>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### Props
|
|
115
|
+
|
|
116
|
+
<x-field-group>
|
|
117
|
+
<x-field data-name="session" data-type="object" data-required="true">
|
|
118
|
+
<x-field-desc markdown>包含使用者和通知資料的 session 物件。該元件依賴 `session.user`、`session.unReadCount` 和 `session.setUnReadCount`。</x-field-desc>
|
|
119
|
+
</x-field>
|
|
120
|
+
</x-field-group>
|
|
121
|
+
|
|
122
|
+
### NotificationSnackbar
|
|
123
|
+
|
|
124
|
+
此元件為快顯通知提供了一個豐富且標準化的 UI。它由 `NotificationAddon` 透過 `notistack` 的 `enqueueSnackbar` 函式在內部使用,不適合直接使用。
|
|
125
|
+
|
|
126
|
+
#### 功能
|
|
127
|
+
|
|
128
|
+
- **基於嚴重性等級的樣式**:快顯通知的外觀會根據通知的嚴重性等級(`success`、`info`、`warning`、`error`)而改變。
|
|
129
|
+
- **豐富的內容顯示**:除了簡單的標題和描述外,還能顯示結構化的活動通知(例如,「使用者 X 喜歡了您的貼文」)。
|
|
130
|
+
- **互動式連結**:自動將描述中可識別的模式(如使用者 DID 或 DApp 地址)轉換為可點擊的連結。
|
|
131
|
+
- **點擊開啟**:點擊快顯通知可將使用者導覽至詳細的通知檢視。
|
|
132
|
+
|
|
133
|
+
## WebSocket 整合
|
|
134
|
+
|
|
135
|
+
即時功能由 `useListenWsClient` hook 管理的 WebSocket 用戶端提供支援。此 hook 為登入的使用者建立連線,並監聽特定事件。
|
|
136
|
+
|
|
137
|
+
### `useListenWsClient` Hook
|
|
138
|
+
|
|
139
|
+
此 hook 抽象化了建立和管理 WebSocket 連線的複雜性。它會獲取目前的使用者 session,並初始化一個連線到指定端點的用戶端。
|
|
140
|
+
|
|
141
|
+
```javascript "title=Hook 用法" icon=logos:javascript
|
|
142
|
+
const wsClient = useListenWsClient('user');
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 事件
|
|
146
|
+
|
|
147
|
+
`NotificationAddon` 元件在 `user` 通道上訂閱以下事件:
|
|
148
|
+
|
|
149
|
+
| Event Name | Description |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `notification:blocklet:create` | 當為使用者建立新通知時觸發。該元件會增加未讀計數,並可能顯示一則快顯訊息。 |
|
|
152
|
+
| `notification:blocklet:read` | 當一則或多則通知被讀取時觸發。該元件會將未讀計數減去已讀通知的數量。 |
|
|
153
|
+
|
|
154
|
+
完整的事件名稱是使用 blocklet 的 DID 和使用者的 DID 動態建構的,例如:`{blocklet.did}/{user.did}/notification:blocklet:create`。
|
|
155
|
+
|
|
156
|
+
## 關鍵工具
|
|
157
|
+
|
|
158
|
+
幾個工具函式透過處理和格式化通知資料來支援通知系統。
|
|
159
|
+
|
|
160
|
+
### `mergeAdjacentNotifications`
|
|
161
|
+
|
|
162
|
+
此函式將連續的、相似的通知分組為一個單一的、聚合的條目。例如,如果一位使用者連續收到來自不同使用者的多個「喜歡」通知,此函式可以將它們合併為一則通知,如「Alice、Bob 和另外 2 人喜歡了您的貼文」。
|
|
163
|
+
|
|
164
|
+
### `toClickableSpan`
|
|
165
|
+
|
|
166
|
+
此工具負責透過將純文字轉換為豐富的互動式內容來增強通知描述。它會解析輸入的字串,識別如使用者 DID 或 DApp 地址等特殊實體,並將它們轉換為可點擊的 HTML `<a>` 標籤。這允許使用者從通知內部直接導覽至使用者的個人資料頁面或 DApp 的頁面。
|
|
167
|
+
|
|
168
|
+
### `sanitize`
|
|
169
|
+
|
|
170
|
+
一個圍繞 `DOMPurify` 的封裝函式,用於在渲染 HTML 內容之前對其進行清理和消毒。這是一項安全措施,旨在防止在顯示可能包含使用者生成資料的通知內容時發生跨站腳本(XSS)攻擊。
|
|
171
|
+
|
|
172
|
+
## 總結
|
|
173
|
+
|
|
174
|
+
通知系統為保持使用者資訊同步提供了一個強大且即時的解決方案。透過利用 `NotificationAddon` 元件並確保您的應用程式已配置 `SnackbarProvider`,您可以輕鬆地將一個功能齊全的通知中心整合到您的 blocklet 中。底層的 WebSocket 架構確保了更新的即時傳遞,創造出一個動態且反應迅速的使用者體驗。
|