@blocklet/ui-react 3.1.47 → 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
|
+
# 定义通知流程
|
|
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
|
+
通知系统主要由两个 React 组件组成:`NotificationAddon` 和 `NotificationSnackbar`。
|
|
66
|
+
|
|
67
|
+
### NotificationAddon
|
|
68
|
+
|
|
69
|
+
`NotificationAddon` 组件是通知的主要用户界面元素。它渲染一个铃铛图标,上面带有一个徽章,显示未读通知的数量。
|
|
70
|
+
|
|
71
|
+
#### 功能
|
|
72
|
+
|
|
73
|
+
- **未读计数**:实时显示未读通知的数量。
|
|
74
|
+
- **WebSocket 集成**:自动连接到通知 WebSocket 通道并监听传入消息。
|
|
75
|
+
- **浮动提示通知**:为新的组件级通知触发浮动提示消息。
|
|
76
|
+
- **直接导航**:作为指向主通知页面的链接。
|
|
77
|
+
|
|
78
|
+
#### 用法
|
|
79
|
+
|
|
80
|
+
要使用此组件,请将其导入并放置在布局组件(如应用头部)中。它需要一个 `session` 对象才能正常工作,该对象通常从会话上下文中获取。
|
|
81
|
+
|
|
82
|
+
```javascript "title=示例:集成 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
|
+
**重要提示**:为使浮动提示通知正常工作,您的应用程序必须被 `notistack` 库中的 `SnackbarProvider` 包裹。
|
|
99
|
+
|
|
100
|
+
```javascript "title=示例:应用被 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=钩子用法" icon=logos:javascript
|
|
141
|
+
const wsClient = useListenWsClient('user');
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 事件
|
|
145
|
+
|
|
146
|
+
`NotificationAddon` 组件在 `user` 通道上订阅以下事件:
|
|
147
|
+
|
|
148
|
+
| 事件名称 | 描述 |
|
|
149
|
+
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
150
|
+
| `notification:blocklet:create` | 当为用户创建新通知时触发。该组件会增加未读计数,并可能显示一条浮动提示消息。 |
|
|
151
|
+
| `notification:blocklet:read` | 当一个或多个通知被阅读时触发。该组件会将未读计数减去已读通知的数量。 |
|
|
152
|
+
|
|
153
|
+
完整的事件名称是使用 blocklet 的 DID 和用户的 DID 动态构建的,例如:`{blocklet.did}/{user.did}/notification:blocklet:create`。
|
|
154
|
+
|
|
155
|
+
## 关键实用工具
|
|
156
|
+
|
|
157
|
+
几个实用工具函数通过处理和格式化通知数据来支持通知系统。
|
|
158
|
+
|
|
159
|
+
### `mergeAdjacentNotifications`
|
|
160
|
+
|
|
161
|
+
此函数将连续的相似通知分组为一个聚合条目。例如,如果一个用户连续收到来自不同用户的多个“赞”通知,此函数可以将它们合并为一条通知,如“Alice、Bob 和另外 2 人赞了你的帖子”。
|
|
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,183 @@
|
|
|
1
|
+
# UserCenter
|
|
2
|
+
|
|
3
|
+
`UserCenter`コンポーネントは、完全なユーザープロファイルと設定管理ページを提供する、包括的な構築済みインターフェースです。ユーザー情報の表示、パスポート管理、プライバシー制御、通知設定、DIDストレージ管理など、さまざまな機能を統合し、ユーザーに一元化されたハブを提供します。
|
|
4
|
+
|
|
5
|
+
このコンポーネントは高度に拡張可能に設計されており、開発者はブロックレットのメタデータを通じてカスタムタブやコンテンツを追加でき、異なるアプリケーション間で一貫したユーザーエクスペリエンスを保証します。
|
|
6
|
+
|
|
7
|
+
```d2
|
|
8
|
+
direction: down
|
|
9
|
+
|
|
10
|
+
UserCenter: {
|
|
11
|
+
label: "UserCenter コンポーネントのレイアウト"
|
|
12
|
+
shape: rectangle
|
|
13
|
+
|
|
14
|
+
Header: { shape: rectangle }
|
|
15
|
+
|
|
16
|
+
Main: {
|
|
17
|
+
direction: right
|
|
18
|
+
shape: rectangle
|
|
19
|
+
|
|
20
|
+
Sidebar: {
|
|
21
|
+
label: "UserBasicInfo\n(プロファイルサイドバー)"
|
|
22
|
+
shape: rectangle
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Content: {
|
|
26
|
+
label: "コンテンツエリア"
|
|
27
|
+
shape: rectangle
|
|
28
|
+
|
|
29
|
+
Tabs: {
|
|
30
|
+
label: "タブナビゲーション"
|
|
31
|
+
shape: rectangle
|
|
32
|
+
}
|
|
33
|
+
TabPanel: {
|
|
34
|
+
label: "アクティブなタブのコンテンツ"
|
|
35
|
+
shape: rectangle
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
Footer: { shape: rectangle }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
UserCenter.Main.Content.Tabs -> UserCenter.Main.Content.TabPanel: "コンテンツを制御"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 基本的な使用法
|
|
47
|
+
|
|
48
|
+
`UserCenter`を使用するには、どのセクションがアクティブであるかを決定する`currentTab`プロパティを提供する必要があります。これは通常、アプリケーションのルーターから取得されます。
|
|
49
|
+
|
|
50
|
+
```javascript UserCenter Example icon=logos:react
|
|
51
|
+
import React from 'react';
|
|
52
|
+
import { UserCenter } from '@blocklet/ui-react';
|
|
53
|
+
|
|
54
|
+
export default function ProfilePage() {
|
|
55
|
+
// 実際のアプリケーションでは、この値をルーターから取得します。
|
|
56
|
+
// 例えば、URLが /profile/settings の場合、currentTabは'/profile/settings'になります。
|
|
57
|
+
const currentTab = '/profile/nfts';
|
|
58
|
+
|
|
59
|
+
return <UserCenter currentTab={currentTab} />;
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## プロパティ
|
|
64
|
+
|
|
65
|
+
`UserCenter`コンポーネントは、その動作と外観をカスタマイズするためにいくつかのプロパティを受け入れます。
|
|
66
|
+
|
|
67
|
+
<x-field-group>
|
|
68
|
+
<x-field data-name="children" data-type="React.ReactNode" data-required="false">
|
|
69
|
+
<x-field-desc markdown>ブロックレットのナビゲーション設定で定義されたカスタムタブのコンテンツをレンダリングするために使用されます。`currentTab`がカスタムタブのURLと一致する場合、`UserCenter`は子要素を表示します。</x-field-desc>
|
|
70
|
+
</x-field>
|
|
71
|
+
<x-field data-name="currentTab" data-type="string" data-required="true">
|
|
72
|
+
<x-field-desc markdown>現在アクティブなタブの値。これは、利用可能なタブ(デフォルトまたはカスタム)のいずれかの`value`プロパティと一致する必要があります。正しいタブを強調表示し、対応するコンテンツを表示するために使用されます。</x-field-desc>
|
|
73
|
+
</x-field>
|
|
74
|
+
<x-field data-name="userDid" data-type="string" data-required="false">
|
|
75
|
+
<x-field-desc markdown>プロファイルを表示するユーザーのDID。省略された場合、コンポーネントはURLクエリパラメータ(`?did=...`)からDIDを取得しようと試みるか、現在ログインしているユーザーをデフォルトとします。</x-field-desc>
|
|
76
|
+
</x-field>
|
|
77
|
+
<x-field data-name="embed" data-type="boolean" data-default="false" data-required="false">
|
|
78
|
+
<x-field-desc markdown>`true`に設定すると、コンポーネントはメインの`Header`と`Footer`なしの埋め込みモードでレンダリングされ、他のレイアウトやページ内への統合に適しています。</x-field-desc>
|
|
79
|
+
</x-field>
|
|
80
|
+
<x-field data-name="onlyProfile" data-type="boolean" data-default="false" data-required="false">
|
|
81
|
+
<x-field-desc markdown>`true`に設定すると、タブやコンテンツセクションなしで`UserBasicInfo`プロファイルカードのみが表示されます。これは、コンパクトなユーザープロファイルのみが必要なコンテキストで役立ちます。</x-field-desc>
|
|
82
|
+
</x-field>
|
|
83
|
+
<x-field data-name="hideFooter" data-type="boolean" data-default="false" data-required="false">
|
|
84
|
+
<x-field-desc markdown>`true`に設定すると、`Footer`コンポーネントはレンダリングされません。</x-field-desc>
|
|
85
|
+
</x-field>
|
|
86
|
+
<x-field data-name="headerProps" data-type="object" data-required="false">
|
|
87
|
+
<x-field-desc markdown>カスタマイズのために、基礎となる`Header`コンポーネントに渡されるプロパティ。</x-field-desc>
|
|
88
|
+
</x-field>
|
|
89
|
+
<x-field data-name="footerProps" data-type="object" data-required="false">
|
|
90
|
+
<x-field-desc markdown>カスタマイズのために、基礎となる`Footer`コンポーネントに渡されるプロパティ。</x-field-desc>
|
|
91
|
+
</x-field>
|
|
92
|
+
<x-field data-name="onDestroySelf" data-type="() => void" data-required="false">
|
|
93
|
+
<x-field-desc markdown>非所有者ユーザーが設定の「危険ゾーン」からアカウント削除プロセスを開始したときにトリガーされるコールバック関数。</x-field-desc>
|
|
94
|
+
</x-field>
|
|
95
|
+
<x-field data-name="notLoginContent" data-type="React.ReactNode" data-required="false">
|
|
96
|
+
<x-field-desc markdown>ユーザーがログインしておらず、`userDid`も提供されていない場合に表示するカスタムコンテンツ。設定されていない場合、デフォルトのログインプロンプトが表示されます。</x-field-desc>
|
|
97
|
+
</x-field>
|
|
98
|
+
</x-field-group>
|
|
99
|
+
|
|
100
|
+
## コア機能
|
|
101
|
+
|
|
102
|
+
`UserCenter`は、すぐに使えるリッチなユーザーエクスペリエンスを提供する、いくつかの主要なセクションとコンポーネントで構成されています。
|
|
103
|
+
|
|
104
|
+
### デフォルトのタブ
|
|
105
|
+
|
|
106
|
+
デフォルトでは、`UserCenter`にはすべてのユーザーに対して以下のタブが含まれています:
|
|
107
|
+
|
|
108
|
+
| タブ | 説明 | 可視性 |
|
|
109
|
+
| ------------------- | ------------------------------------------------------------------------------ | --------------- |
|
|
110
|
+
| **NFTs** | ユーザーのNFTコレクションを表示します。 | 公開 |
|
|
111
|
+
| **ソーシャルアクティビティ** | ソーシャル機能が有効な場合、ユーザーのフォロワーとフォロー中のリストを表示します。 | 公開 |
|
|
112
|
+
| **設定** | プロファイル、プライバシー、通知、セッション管理へのアクセス。 | 所有者のみ |
|
|
113
|
+
| **ストレージ** | 分散ストレージのためのDID Spacesへの接続を管理するインターフェース。 | 所有者のみ |
|
|
114
|
+
|
|
115
|
+
### ユーザープロファイル (`UserBasicInfo`)
|
|
116
|
+
|
|
117
|
+
`UserBasicInfo`コンポーネントは、ユーザーの基本情報を表示する専用のセクション(デスクトップでは通常サイドバー)です:
|
|
118
|
+
- **アバターと名前**:ユーザーのプロフィール写真と氏名を表示します。所有者はアバターをクリックしてプロファイルスイッチャーを開くことができます。
|
|
119
|
+
- **DID**:ユーザーの分散型識別子を表示し、コピーしたりQRコードを表示したりするオプションがあります。
|
|
120
|
+
- **ソーシャルアクション**:公開プロファイルの場合、「フォロー」または「フォロー解除」ボタンが表示されます。
|
|
121
|
+
- **メタデータ**:自己紹介、場所、ソーシャルリンクなど、ユーザーが提供した情報を表示します。
|
|
122
|
+
- **個人情報**:所有者には、メールアドレスや電話番号などの個人情報が表示されます。
|
|
123
|
+
|
|
124
|
+
### パスポート管理
|
|
125
|
+
|
|
126
|
+
メインのプロファイルタブ(NFTs)では、現在ログインしているユーザーは自身のDIDパスポート専用のセクションを見ることができます。このエリアには、関連付けられたすべてのパスポートがリスト表示され、そのステータス(例:アクティブ、失効済み)が示され、現在使用中のものが強調表示されます。
|
|
127
|
+
|
|
128
|
+
### 設定
|
|
129
|
+
|
|
130
|
+
「設定」タブは、プロファイルを所有するユーザーのみが利用できる包括的なパネルです。いくつかのサブセクションに分かれています:
|
|
131
|
+
|
|
132
|
+
- **共通設定**:ユーザーが名前、自己紹介、ソーシャルリンクなどの公開プロファイル情報を更新できます。
|
|
133
|
+
- **通知管理**:通知の受信方法(ウォレット、メール、プッシュ)を設定し、Webhookを管理します。
|
|
134
|
+
- **サードパーティログイン**:Google、GitHub、Passkeysなどの他のIDプロバイダーとの接続を管理します。
|
|
135
|
+
- **プライバシー管理**:ユーザープロファイル上のさまざまなタブの可視性を制御し、公開または非公開に設定します。
|
|
136
|
+
- **セッション管理**:さまざまなデバイスでのアクティブなログインセッションを表示し、取り消します。
|
|
137
|
+
- **危険ゾーン**:非所有者ロールの場合、自身のアカウントを削除するオプションを提供します。
|
|
138
|
+
|
|
139
|
+
## カスタマイズ
|
|
140
|
+
|
|
141
|
+
ブロックレットの設定を通じて新しいタブを追加することで、`UserCenter`を拡張できます。
|
|
142
|
+
|
|
143
|
+
1. **`blocklet.yml` でカスタムタブを定義する**
|
|
144
|
+
|
|
145
|
+
`blocklet.yml`ファイルの`navigation.userCenter`配列にエントリを追加します。各エントリは新しいタブを表します。
|
|
146
|
+
|
|
147
|
+
```yaml blocklet.yml icon=mdi:code-block-tags
|
|
148
|
+
navigation:
|
|
149
|
+
- title: ユーザーセンター
|
|
150
|
+
role: guest
|
|
151
|
+
userCenter:
|
|
152
|
+
- title: マイアクティビティ
|
|
153
|
+
link: /profile/activity
|
|
154
|
+
icon: 'material-symbols:history'
|
|
155
|
+
# このタブをプロファイルの所有者にのみ表示する場合は true に設定
|
|
156
|
+
private: false
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
2. **カスタムタブのコンテンツをレンダリングする**
|
|
160
|
+
|
|
161
|
+
コンポーネントで、`currentTab`プロパティが定義した`link`と一致するときにレンダリングされる子要素を渡します。
|
|
162
|
+
|
|
163
|
+
```javascript MyActivity.js icon=logos:react
|
|
164
|
+
import React from 'react';
|
|
165
|
+
import { UserCenter } from '@blocklet/ui-react';
|
|
166
|
+
|
|
167
|
+
function MyActivityComponent() {
|
|
168
|
+
return <div>これはカスタムアクティビティのコンテンツです。</div>;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export default function ProfilePageWithActivity() {
|
|
172
|
+
// この値はルーターから取得されます。例:'/profile/activity'
|
|
173
|
+
const currentTab = '/profile/activity';
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<UserCenter currentTab={currentTab}>
|
|
177
|
+
{currentTab === '/profile/activity' && <MyActivityComponent />}
|
|
178
|
+
</UserCenter>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
このアプローチにより、アプリケーション固有のページを標準の`UserCenter`レイアウトにシームレスに統合できます。
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# UserCenter
|
|
2
|
+
|
|
3
|
+
The `UserCenter` component is a comprehensive, pre-built interface that provides a complete user profile and settings management page. It integrates various functionalities, including user information display, passport management, privacy controls, notification settings, and DID storage management, offering a centralized hub for users.
|
|
4
|
+
|
|
5
|
+
This component is designed to be highly extensible, allowing developers to add custom tabs and content through the blocklet's metadata, ensuring a consistent user experience across different applications.
|
|
6
|
+
|
|
7
|
+
```d2
|
|
8
|
+
direction: down
|
|
9
|
+
|
|
10
|
+
UserCenter: {
|
|
11
|
+
label: "UserCenter Component Layout"
|
|
12
|
+
shape: rectangle
|
|
13
|
+
|
|
14
|
+
Header: { shape: rectangle }
|
|
15
|
+
|
|
16
|
+
Main: {
|
|
17
|
+
direction: right
|
|
18
|
+
shape: rectangle
|
|
19
|
+
|
|
20
|
+
Sidebar: {
|
|
21
|
+
label: "UserBasicInfo\n(Profile Sidebar)"
|
|
22
|
+
shape: rectangle
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Content: {
|
|
26
|
+
label: "Content Area"
|
|
27
|
+
shape: rectangle
|
|
28
|
+
|
|
29
|
+
Tabs: {
|
|
30
|
+
label: "Tabs Navigation"
|
|
31
|
+
shape: rectangle
|
|
32
|
+
}
|
|
33
|
+
TabPanel: {
|
|
34
|
+
label: "Active Tab Content"
|
|
35
|
+
shape: rectangle
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
Footer: { shape: rectangle }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
UserCenter.Main.Content.Tabs -> UserCenter.Main.Content.TabPanel: "Controls Content"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Basic Usage
|
|
47
|
+
|
|
48
|
+
To use the `UserCenter`, you need to provide the `currentTab` prop, which determines which section is active. This is typically derived from the application's router.
|
|
49
|
+
|
|
50
|
+
```javascript UserCenter Example icon=logos:react
|
|
51
|
+
import React from 'react';
|
|
52
|
+
import { UserCenter } from '@blocklet/ui-react';
|
|
53
|
+
|
|
54
|
+
export default function ProfilePage() {
|
|
55
|
+
// In a real application, you would get this value from your router.
|
|
56
|
+
// For example, if the URL is /profile/settings, currentTab would be '/profile/settings'.
|
|
57
|
+
const currentTab = '/profile/nfts';
|
|
58
|
+
|
|
59
|
+
return <UserCenter currentTab={currentTab} />;
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Props
|
|
64
|
+
|
|
65
|
+
The `UserCenter` component accepts several props to customize its behavior and appearance.
|
|
66
|
+
|
|
67
|
+
<x-field-group>
|
|
68
|
+
<x-field data-name="children" data-type="React.ReactNode" data-required="false">
|
|
69
|
+
<x-field-desc markdown>Used to render content for custom tabs defined in the blocklet's navigation settings. The `UserCenter` will display the children when `currentTab` matches a custom tab's URL.</x-field-desc>
|
|
70
|
+
</x-field>
|
|
71
|
+
<x-field data-name="currentTab" data-type="string" data-required="true">
|
|
72
|
+
<x-field-desc markdown>The value of the currently active tab. This should match the `value` property of one of the available tabs (either default or custom). It is used to highlight the correct tab and display its corresponding content.</x-field-desc>
|
|
73
|
+
</x-field>
|
|
74
|
+
<x-field data-name="userDid" data-type="string" data-required="false">
|
|
75
|
+
<x-field-desc markdown>The DID of the user whose profile is to be displayed. If omitted, the component will attempt to get the DID from the URL query parameter (`?did=...`) or default to the currently logged-in user.</x-field-desc>
|
|
76
|
+
</x-field>
|
|
77
|
+
<x-field data-name="embed" data-type="boolean" data-default="false" data-required="false">
|
|
78
|
+
<x-field-desc markdown>If set to `true`, the component renders in an embedded mode without the main `Header` and `Footer`, making it suitable for integration within other layouts or pages.</x-field-desc>
|
|
79
|
+
</x-field>
|
|
80
|
+
<x-field data-name="onlyProfile" data-type="boolean" data-default="false" data-required="false">
|
|
81
|
+
<x-field-desc markdown>If set to `true`, only the `UserBasicInfo` profile card is displayed, without any tabs or content sections. This is useful for contexts where only a compact user profile is needed.</x-field-desc>
|
|
82
|
+
</x-field>
|
|
83
|
+
<x-field data-name="hideFooter" data-type="boolean" data-default="false" data-required="false">
|
|
84
|
+
<x-field-desc markdown>If set to `true`, the `Footer` component will not be rendered.</x-field-desc>
|
|
85
|
+
</x-field>
|
|
86
|
+
<x-field data-name="headerProps" data-type="object" data-required="false">
|
|
87
|
+
<x-field-desc markdown>Props to be passed down to the underlying `Header` component for customization.</x-field-desc>
|
|
88
|
+
</x-field>
|
|
89
|
+
<x-field data-name="footerProps" data-type="object" data-required="false">
|
|
90
|
+
<x-field-desc markdown>Props to be passed down to the underlying `Footer` component for customization.</x-field-desc>
|
|
91
|
+
</x-field>
|
|
92
|
+
<x-field data-name="onDestroySelf" data-type="() => void" data-required="false">
|
|
93
|
+
<x-field-desc markdown>A callback function that is triggered when a non-owner user initiates the account deletion process from the "Danger Zone" in the settings.</x-field-desc>
|
|
94
|
+
</x-field>
|
|
95
|
+
<x-field data-name="notLoginContent" data-type="React.ReactNode" data-required="false">
|
|
96
|
+
<x-field-desc markdown>Custom content to display when no user is logged in and no `userDid` is provided. If not set, a default login prompt is shown.</x-field-desc>
|
|
97
|
+
</x-field>
|
|
98
|
+
</x-field-group>
|
|
99
|
+
|
|
100
|
+
## Core Features
|
|
101
|
+
|
|
102
|
+
The `UserCenter` is composed of several key sections and components that provide a rich user experience out of the box.
|
|
103
|
+
|
|
104
|
+
### Default Tabs
|
|
105
|
+
|
|
106
|
+
By default, the `UserCenter` includes the following tabs for every user:
|
|
107
|
+
|
|
108
|
+
| Tab | Description | Visibility |
|
|
109
|
+
| ------------------- | ------------------------------------------------------------------------------ | --------------- |
|
|
110
|
+
| **NFTs** | Displays the user's NFT collections. | Public |
|
|
111
|
+
| **Social Activity** | Shows the user's followers and following lists if social features are enabled. | Public |
|
|
112
|
+
| **Settings** | Access to profile, privacy, notification, and session management. | Owner Only |
|
|
113
|
+
| **Storage** | Interface for managing connections to DID Spaces for decentralized storage. | Owner Only |
|
|
114
|
+
|
|
115
|
+
### User Profile (`UserBasicInfo`)
|
|
116
|
+
|
|
117
|
+
The `UserBasicInfo` component is a dedicated section (typically a sidebar on desktop) that displays essential user details:
|
|
118
|
+
- **Avatar and Name**: Shows the user's profile picture and full name. The owner can click the avatar to open the profile switcher.
|
|
119
|
+
- **DID**: Displays the user's Decentralized Identifier, with options to copy it or view its QR code.
|
|
120
|
+
- **Social Actions**: For public profiles, it shows "Follow" or "Unfollow" buttons.
|
|
121
|
+
- **Metadata**: Displays user-provided information such as bio, location, and social links.
|
|
122
|
+
- **Private Information**: For the owner, it shows private details like email and phone number.
|
|
123
|
+
|
|
124
|
+
### Passport Management
|
|
125
|
+
|
|
126
|
+
On the main profile tab (NFTs), the currently logged-in user will see a section dedicated to their DID Passports. This area lists all associated passports, indicating their status (e.g., active, revoked) and highlighting the one currently in use.
|
|
127
|
+
|
|
128
|
+
### Settings
|
|
129
|
+
|
|
130
|
+
The "Settings" tab is a comprehensive panel available only to the user who owns the profile. It is organized into several sub-sections:
|
|
131
|
+
|
|
132
|
+
- **Common Settings**: Allows users to update their public profile information like name, bio, and social links.
|
|
133
|
+
- **Notification Management**: Configure how to receive notifications (Wallet, Email, Push) and manage webhooks.
|
|
134
|
+
- **Third-Party Login**: Manage connections to other identity providers like Google, GitHub, or Passkeys.
|
|
135
|
+
- **Privacy Management**: Control the visibility of different tabs on the user profile, making them public or private.
|
|
136
|
+
- **Session Management**: View and revoke active login sessions across different devices.
|
|
137
|
+
- **Danger Zone**: For non-owner roles, provides an option to delete their own account.
|
|
138
|
+
|
|
139
|
+
## Customization
|
|
140
|
+
|
|
141
|
+
You can extend the `UserCenter` by adding new tabs through your blocklet's configuration.
|
|
142
|
+
|
|
143
|
+
1. **Define Custom Tabs in `blocklet.yml`**
|
|
144
|
+
|
|
145
|
+
Add entries to the `navigation.userCenter` array in your `blocklet.yml` file. Each entry represents a new tab.
|
|
146
|
+
|
|
147
|
+
```yaml blocklet.yml icon=mdi:code-block-tags
|
|
148
|
+
navigation:
|
|
149
|
+
- title: User Center
|
|
150
|
+
role: guest
|
|
151
|
+
userCenter:
|
|
152
|
+
- title: My Activity
|
|
153
|
+
link: /profile/activity
|
|
154
|
+
icon: 'material-symbols:history'
|
|
155
|
+
# Set to true if this tab should only be visible to the profile owner
|
|
156
|
+
private: false
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
2. **Render Content for the Custom Tab**
|
|
160
|
+
|
|
161
|
+
In your component, pass a child element that will be rendered when the `currentTab` prop matches the `link` you defined.
|
|
162
|
+
|
|
163
|
+
```javascript MyActivity.js icon=logos:react
|
|
164
|
+
import React from 'react';
|
|
165
|
+
import { UserCenter } from '@blocklet/ui-react';
|
|
166
|
+
|
|
167
|
+
function MyActivityComponent() {
|
|
168
|
+
return <div>This is the custom activity content.</div>;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export default function ProfilePageWithActivity() {
|
|
172
|
+
// This value would come from your router, e.g., '/profile/activity'
|
|
173
|
+
const currentTab = '/profile/activity';
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<UserCenter currentTab={currentTab}>
|
|
177
|
+
{currentTab === '/profile/activity' && <MyActivityComponent />}
|
|
178
|
+
</UserCenter>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
This approach allows you to seamlessly integrate application-specific pages into the standard `UserCenter` layout.
|