# 通知

このセクションでは、リアルタイムのユーザー通知システムを実装するために利用可能なコンポーネントとユーティリティに関する詳細なガイドを提供します。このシステムは、専用のUIコンポーネントとトーストメッセージを通じて、ユーザーにタイムリーな更新を配信するように設計されています。

通知システムの中心はWebSocket接続を中心に構築されており、サーバーがクライアントに即座に更新をプッシュできるようにします。これにより、ユーザーはアプリケーションをリフレッシュすることなく、常に重要なイベントについて知ることができます。

## アーキテクチャ概要

通知システムは、直接的でイベント駆動型のアーキテクチャに従います。バックエンドで注目すべきイベントが発生すると、通知が生成され、WebSocketチャネルを通じてブロードキャストされます。フロントエンドクライアントはこのチャネルをリッスンし、通知を受信して、UIを適宜更新します。

<!-- DIAGRAM_IMAGE_START:architecture:16:9:1765962229 -->
![Notifications](assets/diagram/notifications-diagram-0.ja.jpg)
<!-- DIAGRAM_IMAGE_END -->

## コアコンポーネント

通知システムは、主に `NotificationAddon` と `NotificationSnackbar` の2つのReactコンポーネントで構成されています。

### NotificationAddon

`NotificationAddon` コンポーネントは、通知の主要なユーザーインターフェース要素として機能します。未読通知の数を示すバッジ付きのベルアイコンをレンダリングします。

#### 機能

-   **未読件数**: 未読通知の数をリアルタイムで表示します。
-   **WebSocket統合**: 通知用のWebSocketチャネルに自動的に接続し、受信メッセージをリッスンします。
-   **トースト通知**: 新しいコンポーネントレベルの通知に対してトーストメッセージをトリガーします。
-   **直接ナビゲーション**: メインの通知ページへのリンクとして機能します。

#### 使用方法

このコンポーネントを使用するには、インポートしてアプリケーションヘッダーなどのレイアウトコンポーネント内に配置します。正しく機能するためには、通常セッションコンテキストから取得される `session` オブジェクトが必要です。

```javascript "title=Example: Integrating NotificationAddon" icon=logos:javascript
import NotificationAddon from '@arcblock/ux/lib/common/notification-addon';
import { useSessionContext } from '@arcblock/did-connect-react';

export default function AppHeader() {
  const { session } = useSessionContext();

  return (
    <header>
      {/* 他のヘッダーコンテンツ */}
      <NotificationAddon session={session} />
    </header>
  );
}
```

**重要**: トースト通知が機能するためには、アプリケーションが `notistack` ライブラリの `SnackbarProvider` でラップされている必要があります。

```javascript "title=Example: App wrapped in SnackbarProvider" icon=logos:javascript
import { SnackbarProvider } from 'notistack';
import App from './App';

function Root() {
  return (
    <SnackbarProvider maxSnack={3}>
      <App />
    </SnackbarProvider>
  );
}
```

#### Props

<x-field-group>
  <x-field data-name="session" data-type="object" data-required="true">
    <x-field-desc markdown>ユーザーおよび通知データを含むセッションオブジェクト。コンポーネントは `session.user`、`session.unReadCount`、および `session.setUnReadCount` に依存します。</x-field-desc>
  </x-field>
</x-field-group>

### NotificationSnackbar

このコンポーネントは、トースト通知のためのリッチで標準化されたUIを提供します。`NotificationAddon` によって `notistack` の `enqueueSnackbar` 関数を介して内部的に使用され、直接使用することを意図していません。

#### 機能

-   **重要度に基づくスタイリング**: 通知の重要度レベル（`success`、`info`、`warning`、`error`）に基づいてスナックバーの外観が変わります。
-   **リッチコンテンツ表示**: 単純なタイトルや説明に加えて、構造化されたアクティビティ通知（例：「ユーザーXがあなたの投稿に「いいね！」しました」）を表示できます。
-   **インタラクティブリンク**: 説明文中の認識されたパターン（ユーザーDIDやDAppアドレスなど）を自動的にクリック可能なリンクに変換します。
-   **クリックして開く**: スナックバーをクリックすると、ユーザーは詳細な通知ビューに移動します。

## WebSocket統合

リアルタイム機能は、`useListenWsClient` フックによって管理されるWebSocketクライアントによって提供されます。このフックは、ログインしているユーザーの接続を確立し、特定のイベントをリッスンします。

### `useListenWsClient` フック

このフックは、WebSocket接続の作成と管理の複雑さを抽象化します。現在のユーザーセッションを取得し、指定されたエンドポイントに接続されたクライアントを初期化します。

```javascript "title=Hook Usage" icon=logos:javascript
const wsClient = useListenWsClient('user');
```

### イベント

`NotificationAddon` コンポーネントは、`user` チャネルで以下のイベントを購読します。

| Event Name                                       | Description                                                                                                                              |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `notification:blocklet:create`                   | ユーザーに対して新しい通知が作成されたときに発行されます。コンポーネントは未読件数をインクリメントし、トーストメッセージを表示する場合があります。          |
| `notification:blocklet:read`                     | 1つ以上の通知が既読になったときに発行されます。コンポーネントは既読になった通知の数だけ未読件数をデクリメントします。 |

完全なイベント名は、blockletのDIDとユーザーのDIDを使用して動的に構築されます。例：`{blocklet.did}/{user.did}/notification:blocklet:create`。

## 主要なユーティリティ

いくつかのユーティリティ関数が、通知データを処理およびフォーマットすることで通知システムをサポートしています。

### `mergeAdjacentNotifications`

この関数は、連続する類似の通知を1つの集約されたエントリにまとめます。例えば、ユーザーが異なるユーザーから複数の「いいね！」通知を連続して受け取った場合、この関数はそれらを「アリス、ボブ、他2人があなたの投稿に「いいね！」しました」のような1つの通知にまとめることができます。

### `toClickableSpan`

このユーティリティは、プレーンテキストをリッチでインタラクティブなコンテンツに変換することで、通知の説明を強化する役割を担います。入力文字列を解析し、ユーザーDIDやDAppアドレスなどの特殊なエンティティを識別し、それらをクリック可能なHTMLの `<a>` タグに変換します。これにより、ユーザーは通知内から直接ユーザーのプロフィールやDAppのページに移動できます。

### `sanitize`

`DOMPurify` のラッパーで、レンダリング前にHTMLコンテンツをクリーンアップおよびサニタイズします。これは、ユーザー生成データを含む可能性のある通知コンテンツを表示する際のクロスサイトスクリプティング（XSS）攻撃を防ぐためのセキュリティ対策です。

## まとめ

通知システムは、ユーザーに情報を提供するための堅牢でリアルタイムなソリューションを提供します。`NotificationAddon` コンポーネントを活用し、アプリケーションが `SnackbarProvider` で設定されていることを確認することで、フル機能の通知センターをblockletに簡単に統合できます。基礎となるWebSocketアーキテクチャにより、更新が即座に配信され、ダイナミックで応答性の高いユーザーエクスペリエンスが生まれます。