@taskon/widget-react 0.0.1-beta.1
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/README.md +1065 -0
- package/dist/CommunityTaskList.css +4893 -0
- package/dist/EligibilityInfo.css +2337 -0
- package/dist/LeaderboardWidget.css +815 -0
- package/dist/PageBuilder.css +54 -0
- package/dist/Quest.css +4214 -0
- package/dist/TaskOnProvider.css +163 -0
- package/dist/TipPopover.css +210 -0
- package/dist/UserCenterWidget.css +297 -0
- package/dist/UserCenterWidget2.css +3519 -0
- package/dist/WidgetShell.css +182 -0
- package/dist/chunks/CommunityTaskList-DoPGZsw1.js +6813 -0
- package/dist/chunks/EligibilityInfo-C7GZ2G5u.js +22228 -0
- package/dist/chunks/LeaderboardWidget-CmYfDeHV.js +1068 -0
- package/dist/chunks/PageBuilder-Tmhf2GTS.js +150 -0
- package/dist/chunks/Quest-DKFZ-pPU.js +8839 -0
- package/dist/chunks/TaskOnProvider-BD6Vp2x8.js +1435 -0
- package/dist/chunks/ThemeProvider-wnSXrNQb.js +1118 -0
- package/dist/chunks/TipPopover-BrW8jo71.js +2926 -0
- package/dist/chunks/UserCenterWidget-BE329iS7.js +3546 -0
- package/dist/chunks/UserCenterWidget-BVw_IEEd.js +3989 -0
- package/dist/chunks/WidgetShell-D_5OjvNZ.js +1517 -0
- package/dist/chunks/common-ja-DWhTaFHb.js +23 -0
- package/dist/chunks/common-ko-80ezXsMG.js +23 -0
- package/dist/chunks/dynamic-import-helper-DxEFwm31.js +537 -0
- package/dist/chunks/index-CwMvO_wZ.js +777 -0
- package/dist/chunks/leaderboardwidget-ja-Bj6gz6y1.js +119 -0
- package/dist/chunks/leaderboardwidget-ko-f1cLO9ic.js +119 -0
- package/dist/chunks/useToast-B-wyO5zL.js +93 -0
- package/dist/chunks/useWidgetLocale-JDelxtt8.js +74 -0
- package/dist/chunks/usercenter-ja-uu-XfVF9.js +332 -0
- package/dist/chunks/usercenter-ko-DYgUOVzd.js +332 -0
- package/dist/community-task.d.ts +451 -0
- package/dist/community-task.js +9 -0
- package/dist/core.d.ts +803 -0
- package/dist/core.js +22 -0
- package/dist/dynamic-import-helper.css +389 -0
- package/dist/index.d.ts +1660 -0
- package/dist/index.js +41 -0
- package/dist/leaderboard.d.ts +547 -0
- package/dist/leaderboard.js +18 -0
- package/dist/page-builder.d.ts +20 -0
- package/dist/page-builder.js +4 -0
- package/dist/quest.d.ts +400 -0
- package/dist/quest.js +8 -0
- package/dist/user-center.d.ts +1780 -0
- package/dist/user-center.js +713 -0
- package/package.json +105 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1660 @@
|
|
|
1
|
+
import { CampaignStatusInfo } from '@taskon/core';
|
|
2
|
+
import { CampaignWinnerReward } from '@taskon/core';
|
|
3
|
+
import { ChainInfo } from '@taskon/core';
|
|
4
|
+
import { ChainType } from '@taskon/core';
|
|
5
|
+
import { CommunityInfo } from '@taskon/core';
|
|
6
|
+
import { CommunityTaskInfo } from '@taskon/core';
|
|
7
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
8
|
+
import { default as default_2 } from 'react';
|
|
9
|
+
import { ForwardRefExoticComponent } from 'react';
|
|
10
|
+
import { GtcUserTaskStatus } from '@taskon/core';
|
|
11
|
+
import { LeaderboardContentConfig } from '@taskon/core';
|
|
12
|
+
import { LoginResult } from '@taskon/core';
|
|
13
|
+
import { MeetCondition } from '@taskon/core';
|
|
14
|
+
import { PageBuilderConfig } from '@taskon/core';
|
|
15
|
+
import { QuestApi } from '@taskon/core';
|
|
16
|
+
import { QuestCampaignInfo } from '@taskon/core';
|
|
17
|
+
import { ReactNode } from 'react';
|
|
18
|
+
import { RecurrenceType } from '@taskon/core';
|
|
19
|
+
import { RefAttributes } from 'react';
|
|
20
|
+
import { RewardDisplayMode } from '@taskon/core';
|
|
21
|
+
import { RewardType } from '@taskon/core';
|
|
22
|
+
import { RewardValueInfo } from '@taskon/core';
|
|
23
|
+
import { SnsType } from '@taskon/core';
|
|
24
|
+
import { TaskOnClient } from '@taskon/core';
|
|
25
|
+
import { TaskReviewResult } from '@taskon/core';
|
|
26
|
+
import { UserCampaignStatusInfo } from '@taskon/core';
|
|
27
|
+
import { UserCenterConfig } from '@taskon/core';
|
|
28
|
+
import { UserCenterRewardCardType } from '@taskon/core';
|
|
29
|
+
import { UserCenterTabType } from '@taskon/core';
|
|
30
|
+
import { UserInfo } from '@taskon/core';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Button 通用按钮组件
|
|
34
|
+
*
|
|
35
|
+
* 基于 Radix UI Slot 实现,支持 asChild 模式
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* // 基础用法
|
|
40
|
+
* <Button>点击我</Button>
|
|
41
|
+
*
|
|
42
|
+
* // 不同变体
|
|
43
|
+
* <Button variant="primary">主要按钮</Button>
|
|
44
|
+
* <Button variant="secondary">次要按钮</Button>
|
|
45
|
+
* <Button variant="outline">描边按钮</Button>
|
|
46
|
+
* <Button variant="ghost">幽灵按钮</Button>
|
|
47
|
+
* <Button variant="danger">危险按钮</Button>
|
|
48
|
+
*
|
|
49
|
+
* // 不同尺寸
|
|
50
|
+
* <Button size="small">小按钮</Button>
|
|
51
|
+
* <Button size="medium">中等按钮</Button>
|
|
52
|
+
* <Button size="large">大按钮</Button>
|
|
53
|
+
*
|
|
54
|
+
* // 加载状态
|
|
55
|
+
* <Button loading>加载中</Button>
|
|
56
|
+
*
|
|
57
|
+
* // 带图标
|
|
58
|
+
* <Button leftIcon={<Icon />}>左侧图标</Button>
|
|
59
|
+
* <Button rightIcon={<Icon />}>右侧图标</Button>
|
|
60
|
+
*
|
|
61
|
+
* // 禁用状态
|
|
62
|
+
* <Button disabled>禁用按钮</Button>
|
|
63
|
+
*
|
|
64
|
+
* // asChild 模式(将 Button 样式应用到子元素)
|
|
65
|
+
* <Button asChild>
|
|
66
|
+
* <a href="/about">链接按钮</a>
|
|
67
|
+
* </Button>
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare const Button: ForwardRefExoticComponent<ButtonProps & RefAttributes<HTMLButtonElement>>;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Button 组件属性
|
|
74
|
+
*/
|
|
75
|
+
export declare interface ButtonProps extends ComponentPropsWithoutRef<"button"> {
|
|
76
|
+
/**
|
|
77
|
+
* 按钮尺寸
|
|
78
|
+
* @default "medium"
|
|
79
|
+
*/
|
|
80
|
+
size?: ButtonSize;
|
|
81
|
+
/**
|
|
82
|
+
* 按钮变体
|
|
83
|
+
* @default "primary"
|
|
84
|
+
*/
|
|
85
|
+
variant?: ButtonVariant;
|
|
86
|
+
/**
|
|
87
|
+
* 是否为加载状态
|
|
88
|
+
* @default false
|
|
89
|
+
*/
|
|
90
|
+
loading?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* 图标位置
|
|
93
|
+
*/
|
|
94
|
+
iconPosition?: "left" | "right" | "only";
|
|
95
|
+
/**
|
|
96
|
+
* 左侧图标
|
|
97
|
+
*/
|
|
98
|
+
leftIcon?: ReactNode;
|
|
99
|
+
/**
|
|
100
|
+
* 右侧图标
|
|
101
|
+
*/
|
|
102
|
+
rightIcon?: ReactNode;
|
|
103
|
+
/**
|
|
104
|
+
* 是否作为子元素渲染(使用 Radix Slot)
|
|
105
|
+
* 当为 true 时,Button 会将所有属性传递给第一个子元素
|
|
106
|
+
* @default false
|
|
107
|
+
*/
|
|
108
|
+
asChild?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* 按钮内容
|
|
111
|
+
*/
|
|
112
|
+
children?: ReactNode;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Button 尺寸类型
|
|
117
|
+
*/
|
|
118
|
+
export declare type ButtonSize = "small" | "medium" | "large";
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Button 变体类型
|
|
122
|
+
*/
|
|
123
|
+
export declare type ButtonVariant = "primary" | "secondary" | "outline" | "ghost" | "danger";
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* CardSelector 组件
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```tsx
|
|
130
|
+
* const options = [
|
|
131
|
+
* { value: 'all', label: 'All Tasks' },
|
|
132
|
+
* { value: 1, label: 'Daily Tasks' },
|
|
133
|
+
* { value: 2, label: 'Weekly Tasks' },
|
|
134
|
+
* ];
|
|
135
|
+
*
|
|
136
|
+
* <CardSelector
|
|
137
|
+
* options={options}
|
|
138
|
+
* value={selectedValue}
|
|
139
|
+
* onChange={setSelectedValue}
|
|
140
|
+
* allowDeselect
|
|
141
|
+
* />
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
export declare function CardSelector<T extends string | number = string | number>({ options, value, onChange, allowDeselect, className, itemClassName, }: CardSelectorProps<T>): default_2.ReactElement;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* 选项配置
|
|
148
|
+
*/
|
|
149
|
+
export declare interface CardSelectorOption<T = string | number> {
|
|
150
|
+
/** 选项的值 */
|
|
151
|
+
value: T;
|
|
152
|
+
/** 选项的显示文本 */
|
|
153
|
+
label: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* CardSelector 组件属性
|
|
158
|
+
*/
|
|
159
|
+
export declare interface CardSelectorProps<T = string | number> {
|
|
160
|
+
/** 选项列表 */
|
|
161
|
+
options: CardSelectorOption<T>[];
|
|
162
|
+
/** 当前选中的值 */
|
|
163
|
+
value?: T;
|
|
164
|
+
/** 值变化回调 */
|
|
165
|
+
onChange?: (value: T | undefined) => void;
|
|
166
|
+
/** 是否允许取消选择(点击已选中项取消选择)
|
|
167
|
+
* @default true
|
|
168
|
+
*/
|
|
169
|
+
allowDeselect?: boolean;
|
|
170
|
+
/** 自定义根容器类名 */
|
|
171
|
+
className?: string;
|
|
172
|
+
/** 自定义选项类名 */
|
|
173
|
+
itemClassName?: string;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Clear the locale cache
|
|
178
|
+
* Useful for testing or when you need to force reload locales
|
|
179
|
+
*/
|
|
180
|
+
export declare function clearLocaleCache(): void;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Common messages type definition
|
|
184
|
+
*
|
|
185
|
+
* These are shared messages used across multiple widgets.
|
|
186
|
+
* All language files must implement this interface.
|
|
187
|
+
*/
|
|
188
|
+
export declare interface CommonMessages {
|
|
189
|
+
/** Loading state text */
|
|
190
|
+
loading: string;
|
|
191
|
+
/** Generic error message */
|
|
192
|
+
error: string;
|
|
193
|
+
/** Retry action text */
|
|
194
|
+
retry: string;
|
|
195
|
+
/** Success message */
|
|
196
|
+
success: string;
|
|
197
|
+
/** Cancel action text */
|
|
198
|
+
cancel: string;
|
|
199
|
+
/** Confirm action text */
|
|
200
|
+
confirm: string;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* BaseTask 组件
|
|
205
|
+
* @description 基础任务卡片,职责:
|
|
206
|
+
* - 卡片布局(flex 容器)
|
|
207
|
+
* - 周期标签显示
|
|
208
|
+
* - 任务标题显示
|
|
209
|
+
* - 有效时间显示
|
|
210
|
+
* - 按钮区域管理
|
|
211
|
+
* - 完成状态样式
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```tsx
|
|
215
|
+
* <BaseTask
|
|
216
|
+
* title="Follow @TaskOn_xyz"
|
|
217
|
+
* isWon={false}
|
|
218
|
+
* isCompleted={false}
|
|
219
|
+
* isPeriodic={true}
|
|
220
|
+
* recurrenceLabel="Daily"
|
|
221
|
+
* taskId={123}
|
|
222
|
+
* actionLabel="Follow"
|
|
223
|
+
* actionLink="https://twitter.com/TaskOn_xyz"
|
|
224
|
+
* reward={{ type: 'points', amount: 100, name: 'Points', icon: '/icon.png' }}
|
|
225
|
+
* onClick={() => console.log('卡片被点击')}
|
|
226
|
+
* onClaim={() => console.log('Claim 按钮被点击')}
|
|
227
|
+
* >
|
|
228
|
+
* <div>额外的任务描述内容</div>
|
|
229
|
+
* </BaseTask>
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
export declare function CommunityTask(props: CommunityTaskProps): default_2.ReactElement;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* CommunityTaskList outer wrapper
|
|
236
|
+
*
|
|
237
|
+
* Handles cloud config loading + ThemeProvider wrapping via WidgetShell.
|
|
238
|
+
* Merges cloud function config with local props, then renders inner component.
|
|
239
|
+
*/
|
|
240
|
+
export declare function CommunityTaskList(props: CommunityTaskListProps): default_2.ReactElement;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* CommunityTaskList component props
|
|
244
|
+
*/
|
|
245
|
+
export declare interface CommunityTaskListProps {
|
|
246
|
+
/**
|
|
247
|
+
* Widget ID - load configuration (theme + function) from cloud
|
|
248
|
+
* Cloud config includes display options, sector filtering, etc.
|
|
249
|
+
*/
|
|
250
|
+
widgetId?: number;
|
|
251
|
+
/** Whether in preview mode */
|
|
252
|
+
isPreview?: boolean;
|
|
253
|
+
/** 社区信息(用于前置任务链接跳转) */
|
|
254
|
+
communityInfo?: {
|
|
255
|
+
community_key?: string;
|
|
256
|
+
dapp_domain?: string;
|
|
257
|
+
};
|
|
258
|
+
/**
|
|
259
|
+
* Initial task ID from URL (passed by host after parsing URL)
|
|
260
|
+
* Used to auto-open task dialog on page refresh or shared links
|
|
261
|
+
* @example
|
|
262
|
+
* ```tsx
|
|
263
|
+
* const searchParams = useSearchParams();
|
|
264
|
+
* <CommunityTaskList initialTaskId={Number(searchParams.get('task')) || undefined} />
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
initialTaskId?: number;
|
|
268
|
+
/**
|
|
269
|
+
* Callback when dialog opens (host can use to update URL params)
|
|
270
|
+
* @param taskId Currently opened task ID
|
|
271
|
+
* @example
|
|
272
|
+
* ```tsx
|
|
273
|
+
* onTaskOpen={(taskId) => router.replace(`?task=${taskId}`)}
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
onTaskOpen?: (taskId: number) => void;
|
|
277
|
+
/**
|
|
278
|
+
* Callback when dialog closes (host can use to clear URL params)
|
|
279
|
+
* @example
|
|
280
|
+
* ```tsx
|
|
281
|
+
* onTaskClose={() => router.replace(pathname)}
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
284
|
+
onTaskClose?: () => void;
|
|
285
|
+
/** Sector IDs to display; undefined means show all */
|
|
286
|
+
sectorIds?: number[];
|
|
287
|
+
/** Whether to show sector tab selector (default: true) */
|
|
288
|
+
showSectorTab?: boolean;
|
|
289
|
+
/** Whether to show sector name (default: true) */
|
|
290
|
+
showSectorName?: boolean;
|
|
291
|
+
/** Whether to show sector description (default: true) */
|
|
292
|
+
showSectorDescription?: boolean;
|
|
293
|
+
/** Whether to show sector reward (default: true) */
|
|
294
|
+
showSectorReward?: boolean;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* 任务卡片基础 Props(最小知识原则)
|
|
299
|
+
* BaseTask 只需要知道这些信息
|
|
300
|
+
*/
|
|
301
|
+
export declare interface CommunityTaskProps {
|
|
302
|
+
/** 任务名称/标题(字符串或自定义渲染节点) */
|
|
303
|
+
title: string | React.ReactNode;
|
|
304
|
+
/** 是否已中奖/完成 */
|
|
305
|
+
isWon: boolean;
|
|
306
|
+
/** 是否已提交(可能未中奖) */
|
|
307
|
+
isCompleted: boolean;
|
|
308
|
+
/** 是否是周期任务 */
|
|
309
|
+
isPeriodic: boolean;
|
|
310
|
+
/** 操作按钮文案(如 "Follow"、"Join") */
|
|
311
|
+
actionLabel?: string;
|
|
312
|
+
/** 操作按钮链接(默认在新标签页打开) */
|
|
313
|
+
actionLink?: string;
|
|
314
|
+
/** 点击操作按钮后是否自动验证 */
|
|
315
|
+
actionAutoVerify?: boolean;
|
|
316
|
+
/**
|
|
317
|
+
* 点击 Action 按钮时自动打开弹窗
|
|
318
|
+
* 用于 PowTask、InviteFriends 等需要在弹窗中填写内容的任务
|
|
319
|
+
*/
|
|
320
|
+
actionAutoDialog?: boolean;
|
|
321
|
+
/** 是否总是显示操作按钮(即使已完成) */
|
|
322
|
+
alwaysShowAction?: boolean;
|
|
323
|
+
/**
|
|
324
|
+
* 标题跳转链接
|
|
325
|
+
* 如果提供,标题将变成可点击的链接,在新标签页打开
|
|
326
|
+
*/
|
|
327
|
+
targetLink?: string;
|
|
328
|
+
/** 是否隐藏 Claim 按钮 */
|
|
329
|
+
noClaim?: boolean;
|
|
330
|
+
/**
|
|
331
|
+
* 是否需要验证后才能 Claim
|
|
332
|
+
* - true: 显示 "Verify & Claim"
|
|
333
|
+
* - false: 显示 "Claim"
|
|
334
|
+
*/
|
|
335
|
+
verifyClaim?: boolean;
|
|
336
|
+
/**
|
|
337
|
+
* 点击 Claim 仅打开弹窗(不提交)
|
|
338
|
+
* 用于 QuizTask、SurveyTask 等需要在弹窗中选择答案的任务
|
|
339
|
+
*/
|
|
340
|
+
claimDialog?: boolean;
|
|
341
|
+
/**
|
|
342
|
+
* 社交账号类型(用于 OAuth 绑定)
|
|
343
|
+
* 决定 Claim 时需要绑定哪种社交账号
|
|
344
|
+
*/
|
|
345
|
+
snsType?: SnsType;
|
|
346
|
+
/**
|
|
347
|
+
* 链类型(用于钱包绑定)
|
|
348
|
+
* 决定 Claim 时需要绑定哪种链的钱包
|
|
349
|
+
*/
|
|
350
|
+
chainType?: ChainType;
|
|
351
|
+
/** 周期标签文本(如 "Daily"、"Weekly") */
|
|
352
|
+
recurrenceLabel?: string;
|
|
353
|
+
/** 任务重复类型(用于 Claim 按钮文案逻辑) */
|
|
354
|
+
recurrence?: RecurrenceType;
|
|
355
|
+
/** 是否隐藏周期标签 */
|
|
356
|
+
noRecurrence?: boolean;
|
|
357
|
+
/**
|
|
358
|
+
* Unlimited 任务是否显示大的 Claim 按钮
|
|
359
|
+
* - true: 显示正常大小的 Claim 按钮
|
|
360
|
+
* - false: 显示小的 Update 按钮(已有积分)
|
|
361
|
+
* @default true
|
|
362
|
+
*/
|
|
363
|
+
showUnlimitedClaim?: boolean;
|
|
364
|
+
/** 任务 ID */
|
|
365
|
+
taskId: number;
|
|
366
|
+
/** 有效时间相关 */
|
|
367
|
+
validTime?: {
|
|
368
|
+
/** 开始时间(格式化字符串) */
|
|
369
|
+
startTime?: string;
|
|
370
|
+
/** 结束时间(格式化字符串) */
|
|
371
|
+
endTime?: string;
|
|
372
|
+
/** 是否已过期 */
|
|
373
|
+
isExpired?: boolean;
|
|
374
|
+
};
|
|
375
|
+
/**
|
|
376
|
+
* 验证时间范围(OnChain 任务专用)
|
|
377
|
+
* 显示 "This task only verify action during {start} - {end}(UTC)"
|
|
378
|
+
*/
|
|
379
|
+
validationTimeFrame?: {
|
|
380
|
+
/** 开始时间(毫秒或秒时间戳) */
|
|
381
|
+
start_time: number;
|
|
382
|
+
/** 结束时间(毫秒或秒时间戳) */
|
|
383
|
+
end_time: number;
|
|
384
|
+
};
|
|
385
|
+
/** 奖励信息 */
|
|
386
|
+
reward?: {
|
|
387
|
+
/** 奖励类型 */
|
|
388
|
+
type: "points" | "token" | "none";
|
|
389
|
+
/** 积分数量(points 类型,单次奖励) */
|
|
390
|
+
amount?: number;
|
|
391
|
+
/** 积分名称(points 类型) */
|
|
392
|
+
name?: string;
|
|
393
|
+
/** 积分图标(points 类型) */
|
|
394
|
+
icon?: string;
|
|
395
|
+
/** 累计积分(周期任务完成时显示) */
|
|
396
|
+
totalAmount?: number;
|
|
397
|
+
/** Token 信息(token 类型) */
|
|
398
|
+
token?: {
|
|
399
|
+
/** Token 名称 */
|
|
400
|
+
name: string;
|
|
401
|
+
/** 每次奖励数量 */
|
|
402
|
+
amount: string;
|
|
403
|
+
/** Token 图标 */
|
|
404
|
+
icon?: string;
|
|
405
|
+
/** 链名称 */
|
|
406
|
+
chain?: string;
|
|
407
|
+
/** 链图标 */
|
|
408
|
+
chainIcon?: string;
|
|
409
|
+
/** 总奖励单位数 */
|
|
410
|
+
totalUnit?: number;
|
|
411
|
+
/** 可用单位数 */
|
|
412
|
+
availableUnit?: number;
|
|
413
|
+
};
|
|
414
|
+
};
|
|
415
|
+
/** 卡片内容(由具体任务组件提供,用于展示任务特定内容) */
|
|
416
|
+
children?: React.ReactNode;
|
|
417
|
+
/**
|
|
418
|
+
* 自定义 Action 按钮区域
|
|
419
|
+
* 如果提供,将替换默认的 Action 按钮
|
|
420
|
+
* @example
|
|
421
|
+
* ```tsx
|
|
422
|
+
* <BaseTask
|
|
423
|
+
* actionSlot={<CustomActionButton onClick={handleAction} />}
|
|
424
|
+
* />
|
|
425
|
+
* ```
|
|
426
|
+
*/
|
|
427
|
+
actionSlot?: React.ReactNode;
|
|
428
|
+
/**
|
|
429
|
+
* 自定义奖励展示(已完成状态)
|
|
430
|
+
* 如果提供,将替换默认的 Won 奖励显示
|
|
431
|
+
* @example
|
|
432
|
+
* ```tsx
|
|
433
|
+
* <BaseTask
|
|
434
|
+
* rewardSlot={<CustomRewardDisplay amount={100} />}
|
|
435
|
+
* />
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
rewardSlot?: React.ReactNode;
|
|
439
|
+
/**
|
|
440
|
+
* 是否已登录
|
|
441
|
+
* - true: 正常显示卡片
|
|
442
|
+
* - false/undefined: 显示登录遮层,点击触发 onLogin
|
|
443
|
+
* @default true
|
|
444
|
+
*/
|
|
445
|
+
isLoggedIn?: boolean;
|
|
446
|
+
/** 点击卡片回调(用于打开弹窗) */
|
|
447
|
+
onClick?: () => void;
|
|
448
|
+
/**
|
|
449
|
+
* 点击 Claim 按钮回调
|
|
450
|
+
* @param token - 可选的 OAuth token(reAuth 成功后传入)
|
|
451
|
+
* @returns 可选返回 Promise,包含结果信息用于 reAuth 判断和 coolDown 更新
|
|
452
|
+
*/
|
|
453
|
+
onClaim?: (token?: string) => void | Promise<{
|
|
454
|
+
successful: boolean;
|
|
455
|
+
errorCode?: string;
|
|
456
|
+
cool_down?: number;
|
|
457
|
+
}>;
|
|
458
|
+
/**
|
|
459
|
+
* 点击登录遮层回调
|
|
460
|
+
* 未登录时(isLoggedIn=false)点击卡片会触发此回调
|
|
461
|
+
*/
|
|
462
|
+
onLogin?: () => void;
|
|
463
|
+
/** 是否正在提交 */
|
|
464
|
+
isSubmitting?: boolean;
|
|
465
|
+
/** 冷却时间(毫秒) */
|
|
466
|
+
coolDown?: number;
|
|
467
|
+
/** 冷却结束回调(用于重置 coolDown 状态) */
|
|
468
|
+
onCoolDownComplete?: () => void;
|
|
469
|
+
/** 是否禁用交互 */
|
|
470
|
+
disabled?: boolean;
|
|
471
|
+
/**
|
|
472
|
+
* 审核结果状态
|
|
473
|
+
* - Passed: 审核通过
|
|
474
|
+
* - Failed: 审核失败(显示 "Oops! Failed")
|
|
475
|
+
* - UnReviewed: 审核中(显示 "Under Review")
|
|
476
|
+
*/
|
|
477
|
+
reviewResult?: TaskReviewResult;
|
|
478
|
+
/**
|
|
479
|
+
* CheckProgressTip 需要的社区信息
|
|
480
|
+
* 用于显示 "Contact {name} to check your progress"
|
|
481
|
+
*/
|
|
482
|
+
communityInfo?: {
|
|
483
|
+
/** 社区名称 */
|
|
484
|
+
name?: string;
|
|
485
|
+
/** 社区联系链接(Discord/Telegram/Twitter) */
|
|
486
|
+
contactLink?: string;
|
|
487
|
+
};
|
|
488
|
+
/**
|
|
489
|
+
* 周期任务:当前周期是否已完成
|
|
490
|
+
* 配合 nextTime 用于显示 DoneCountdown
|
|
491
|
+
*/
|
|
492
|
+
currentCompleted?: boolean;
|
|
493
|
+
/**
|
|
494
|
+
* 周期任务:下次可完成的时间戳(毫秒)
|
|
495
|
+
* 用于显示 DoneCountdown 倒计时
|
|
496
|
+
*/
|
|
497
|
+
nextTime?: number;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Create a locale loader function for a widget
|
|
502
|
+
*
|
|
503
|
+
* @template T - The shape of the messages object
|
|
504
|
+
* @param defaultMessages - English messages (used as fallback)
|
|
505
|
+
* @param imports - Map of locale codes to dynamic import functions
|
|
506
|
+
* @returns A function that loads messages for a given locale
|
|
507
|
+
*
|
|
508
|
+
* @example
|
|
509
|
+
* ```ts
|
|
510
|
+
* import enMessages from './locales/en';
|
|
511
|
+
*
|
|
512
|
+
* const loadMessages = createLocaleLoader(enMessages, {
|
|
513
|
+
* ko: () => import('./locales/ko'),
|
|
514
|
+
* ja: () => import('./locales/ja'),
|
|
515
|
+
* });
|
|
516
|
+
* ```
|
|
517
|
+
*/
|
|
518
|
+
export declare function createLocaleLoader<T>(defaultMessages: T, imports: LocaleImportMap<T>): (locale: Locale) => Promise<{
|
|
519
|
+
default: T;
|
|
520
|
+
}>;
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Create a translation function from a messages object
|
|
524
|
+
*
|
|
525
|
+
* @param messages - Object containing translation strings
|
|
526
|
+
* @returns A function that retrieves and interpolates translations
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* ```ts
|
|
530
|
+
* const messages = {
|
|
531
|
+
* greeting: 'Hello, {name}!',
|
|
532
|
+
* points: 'You have {count} points',
|
|
533
|
+
* };
|
|
534
|
+
*
|
|
535
|
+
* const t = createT(messages);
|
|
536
|
+
*
|
|
537
|
+
* t('greeting', { name: 'John' }) // => 'Hello, John!'
|
|
538
|
+
* t('points', { count: 100 }) // => 'You have 100 points'
|
|
539
|
+
* t('greeting') // => 'Hello, {name}!' (no params)
|
|
540
|
+
* ```
|
|
541
|
+
*/
|
|
542
|
+
export declare function createT<T extends Record<string, string>>(messages: T): <K extends keyof T>(key: K, params?: InterpolationParams) => string;
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Interpolate a string with parameters
|
|
546
|
+
*
|
|
547
|
+
* @param template - String template with {key} placeholders
|
|
548
|
+
* @param params - Object containing values to replace placeholders
|
|
549
|
+
* @returns Interpolated string
|
|
550
|
+
*
|
|
551
|
+
* @example
|
|
552
|
+
* ```ts
|
|
553
|
+
* interpolate('Hello, {name}!', { name: 'John' })
|
|
554
|
+
* // => 'Hello, John!'
|
|
555
|
+
*
|
|
556
|
+
* interpolate('You have {count} points', { count: 100 })
|
|
557
|
+
* // => 'You have 100 points'
|
|
558
|
+
*
|
|
559
|
+
* interpolate('{a} + {b} = {result}', { a: 1, b: 2, result: 3 })
|
|
560
|
+
* // => '1 + 2 = 3'
|
|
561
|
+
* ```
|
|
562
|
+
*/
|
|
563
|
+
export declare function interpolate(template: string, params?: InterpolationParams): string;
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* interpolate - Simple string interpolation utility
|
|
567
|
+
*
|
|
568
|
+
* Replaces placeholders in the format {key} with values from the params object.
|
|
569
|
+
* This is a lightweight alternative to full i18n libraries when only simple
|
|
570
|
+
* variable replacement is needed.
|
|
571
|
+
*/
|
|
572
|
+
/**
|
|
573
|
+
* Params object type for interpolation
|
|
574
|
+
*/
|
|
575
|
+
export declare type InterpolationParams = Record<string, string | number | undefined>;
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Parameters for contract invocation
|
|
579
|
+
*/
|
|
580
|
+
declare interface InvokeContractParams {
|
|
581
|
+
/** Contract address */
|
|
582
|
+
contract: string;
|
|
583
|
+
/** Contract ABI (Application Binary Interface) */
|
|
584
|
+
abi: unknown[];
|
|
585
|
+
/** Method name to call */
|
|
586
|
+
method: string;
|
|
587
|
+
/** Method parameters */
|
|
588
|
+
params: unknown[];
|
|
589
|
+
/** Target chain ID (optional, will switch network if needed) */
|
|
590
|
+
chainId?: number;
|
|
591
|
+
/** Transaction value in wei (for payable methods) */
|
|
592
|
+
value?: string;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Check if a locale has full translation support
|
|
597
|
+
*/
|
|
598
|
+
export declare function isSupportedLocale(locale: Locale): locale is SupportedLocale;
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* 排行榜 Widget 外层组件
|
|
602
|
+
*
|
|
603
|
+
* Handles cloud config loading + ThemeProvider wrapping via WidgetShell.
|
|
604
|
+
* Merges cloud function config with local props, then renders inner component.
|
|
605
|
+
*
|
|
606
|
+
* @example
|
|
607
|
+
* ```tsx
|
|
608
|
+
* // Pure props mode
|
|
609
|
+
* <LeaderboardWidget config={config} />
|
|
610
|
+
*
|
|
611
|
+
* // Pure widgetId mode (config from cloud)
|
|
612
|
+
* <LeaderboardWidget widgetId={456} />
|
|
613
|
+
*
|
|
614
|
+
* // Mixed mode (props override cloud)
|
|
615
|
+
* <LeaderboardWidget widgetId={456} defaultTabId="sprint-1" />
|
|
616
|
+
* ```
|
|
617
|
+
*/
|
|
618
|
+
export declare function LeaderboardWidget(props: LeaderboardWidgetProps): default_2.ReactElement | null;
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* LeaderboardWidget 组件 Props
|
|
622
|
+
*/
|
|
623
|
+
export declare interface LeaderboardWidgetProps {
|
|
624
|
+
/**
|
|
625
|
+
* Widget ID - load configuration (theme + function) from cloud
|
|
626
|
+
* Cloud config provides leaderboard tabs, display options, etc.
|
|
627
|
+
*/
|
|
628
|
+
widgetId?: number;
|
|
629
|
+
/**
|
|
630
|
+
* 排行榜配置
|
|
631
|
+
* 包含所有 Tab 的配置和显示选项
|
|
632
|
+
* 如果传入 widgetId,可从云端获取;如果同时传入则 props 优先
|
|
633
|
+
*/
|
|
634
|
+
config?: LeaderboardContentConfig;
|
|
635
|
+
/** 默认激活的 Tab ID(不传则默认第一个) */
|
|
636
|
+
defaultTabId?: string;
|
|
637
|
+
/** Tab 切换回调 */
|
|
638
|
+
onTabChange?: (tabId: string) => void;
|
|
639
|
+
/** 用户点击回调 */
|
|
640
|
+
onUserClick?: (userId: number, userName: string) => void;
|
|
641
|
+
/** 自定义类名 */
|
|
642
|
+
className?: string;
|
|
643
|
+
/** 自定义样式 */
|
|
644
|
+
style?: default_2.CSSProperties;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
export declare type Locale = "en" | "ko" | "ja" | "ru" | "es";
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Locale import map type
|
|
651
|
+
* Maps supported locales to their dynamic import functions
|
|
652
|
+
*/
|
|
653
|
+
export declare type LocaleImportMap<T> = {
|
|
654
|
+
[K in Exclude<SupportedLocale, "en">]?: () => Promise<{
|
|
655
|
+
default: T;
|
|
656
|
+
}>;
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Supported login methods
|
|
661
|
+
*/
|
|
662
|
+
export declare type LoginMethod = "evm_wallet" | "email" | "discord" | "twitter" | "telegram";
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Unified login parameters
|
|
666
|
+
*/
|
|
667
|
+
export declare interface LoginParams {
|
|
668
|
+
/** Login method */
|
|
669
|
+
method: LoginMethod;
|
|
670
|
+
/** Value: wallet address / email / OAuth token */
|
|
671
|
+
value: string;
|
|
672
|
+
/** Signature from backend */
|
|
673
|
+
sign: string;
|
|
674
|
+
/** Timestamp used for signing (seconds) */
|
|
675
|
+
timestamp: number;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
export { LoginResult }
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Map Token - Can override derived values
|
|
682
|
+
*/
|
|
683
|
+
export declare interface MapToken {
|
|
684
|
+
colorPrimary?: string;
|
|
685
|
+
colorPrimaryHover?: string;
|
|
686
|
+
colorPrimaryActive?: string;
|
|
687
|
+
colorPrimaryBg?: string;
|
|
688
|
+
colorSecondary?: string;
|
|
689
|
+
colorSuccess?: string;
|
|
690
|
+
colorWarning?: string;
|
|
691
|
+
colorError?: string;
|
|
692
|
+
colorBg?: string;
|
|
693
|
+
colorBgElevated?: string;
|
|
694
|
+
colorBgSpotlight?: string;
|
|
695
|
+
colorText?: string;
|
|
696
|
+
colorTextSecondary?: string;
|
|
697
|
+
colorTextTertiary?: string;
|
|
698
|
+
colorTextDisabled?: string;
|
|
699
|
+
colorBorder?: string;
|
|
700
|
+
colorBorderSecondary?: string;
|
|
701
|
+
borderRadius?: number;
|
|
702
|
+
borderRadiusSm?: number;
|
|
703
|
+
borderRadiusLg?: number;
|
|
704
|
+
fontSize?: number;
|
|
705
|
+
fontSizeSm?: number;
|
|
706
|
+
fontSizeLg?: number;
|
|
707
|
+
spacing?: number;
|
|
708
|
+
spacingXs?: number;
|
|
709
|
+
spacingSm?: number;
|
|
710
|
+
spacingMd?: number;
|
|
711
|
+
spacingLg?: number;
|
|
712
|
+
spacingXl?: number;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Mode-specific configuration
|
|
717
|
+
*/
|
|
718
|
+
declare interface ModeThemeConfig {
|
|
719
|
+
seed?: SeedToken;
|
|
720
|
+
map?: MapToken;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* PageBuilder - Render a composed page from PageBuilder config
|
|
725
|
+
*/
|
|
726
|
+
export declare function PageBuilder(props: PageBuilderProps): default_2.ReactElement;
|
|
727
|
+
|
|
728
|
+
export declare interface PageBuilderProps {
|
|
729
|
+
/** PageBuilder ID (load config from API) */
|
|
730
|
+
pageId?: number;
|
|
731
|
+
/** Local config (skip API request) */
|
|
732
|
+
config?: PageBuilderConfig;
|
|
733
|
+
/** Custom className for root */
|
|
734
|
+
className?: string;
|
|
735
|
+
/** Custom style for root */
|
|
736
|
+
style?: default_2.CSSProperties;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* Quest Widget 主组件
|
|
741
|
+
*
|
|
742
|
+
* @description
|
|
743
|
+
* 将 taskon-website 中的 Quest (Campaign) 详情页迁移为 React Widget 组件
|
|
744
|
+
* 供第三方项目嵌入使用
|
|
745
|
+
*
|
|
746
|
+
* 架构原则:只在根组件访问 context,子组件通过 props 接收数据
|
|
747
|
+
*
|
|
748
|
+
* @example
|
|
749
|
+
* ```tsx
|
|
750
|
+
* import { QuestWidget } from '@taskon/widget-react';
|
|
751
|
+
*
|
|
752
|
+
* function App() {
|
|
753
|
+
* return (
|
|
754
|
+
* <TaskOnProvider config={{ ... }}>
|
|
755
|
+
* <QuestWidget
|
|
756
|
+
* campaignId={123}
|
|
757
|
+
* showBanner={true}
|
|
758
|
+
* onLoaded={(campaign) => console.log('Quest loaded:', campaign.name)}
|
|
759
|
+
* onSubmitSuccess={() => console.log('Quest completed!')}
|
|
760
|
+
* />
|
|
761
|
+
* </TaskOnProvider>
|
|
762
|
+
* );
|
|
763
|
+
* }
|
|
764
|
+
* ```
|
|
765
|
+
*/
|
|
766
|
+
declare function QuestWidget(props: QuestWidgetProps): default_2.ReactElement;
|
|
767
|
+
export { QuestWidget as Quest }
|
|
768
|
+
export { QuestWidget }
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Quest Widget 主组件 Props
|
|
772
|
+
*/
|
|
773
|
+
export declare interface QuestWidgetProps {
|
|
774
|
+
/**
|
|
775
|
+
* Widget ID - 传入后从云端加载配置(theme + function)
|
|
776
|
+
* 云端配置包含 campaignId、显示选项、自定义分享文案等
|
|
777
|
+
*/
|
|
778
|
+
widgetId?: number;
|
|
779
|
+
/**
|
|
780
|
+
* Campaign ID
|
|
781
|
+
* - 如果传入 widgetId,campaignId 可从云端配置获取
|
|
782
|
+
* - 如果同时传入 widgetId 和 campaignId,本地 props 优先
|
|
783
|
+
*/
|
|
784
|
+
campaignId?: number;
|
|
785
|
+
/** 渠道标识(可选) */
|
|
786
|
+
channel?: string;
|
|
787
|
+
/** KOL 标识(可选) */
|
|
788
|
+
kolHandle?: string;
|
|
789
|
+
/** 邀请码(可选) */
|
|
790
|
+
inviteCode?: string;
|
|
791
|
+
/** Boost ID(可选) */
|
|
792
|
+
boostId?: number;
|
|
793
|
+
/** 是否为预览模式 */
|
|
794
|
+
isPreview?: boolean;
|
|
795
|
+
/** 是否显示 Banner */
|
|
796
|
+
showBanner?: boolean;
|
|
797
|
+
/** 是否显示标题 */
|
|
798
|
+
showTitle?: boolean;
|
|
799
|
+
/** 是否显示描述 */
|
|
800
|
+
showDescription?: boolean;
|
|
801
|
+
/** 是否显示参与人数 */
|
|
802
|
+
showParticipants?: boolean;
|
|
803
|
+
/** 加载完成回调 */
|
|
804
|
+
onLoaded?: (campaign: QuestCampaignInfo) => void;
|
|
805
|
+
/** 任务完成回调 */
|
|
806
|
+
onTaskCompleted?: (taskId: number) => void;
|
|
807
|
+
/** Quest 提交成功回调 */
|
|
808
|
+
onSubmitSuccess?: () => void;
|
|
809
|
+
/** 错误回调 */
|
|
810
|
+
onError?: (error: Error) => void;
|
|
811
|
+
/** 连接钱包回调(未登录时触发) */
|
|
812
|
+
onConnectWallet?: () => void;
|
|
813
|
+
/** 领取 NFT 回调 (NFT/MintedNft/Cap) */
|
|
814
|
+
onClaimNft?: (reward: RewardValueInfo, layer: CampaignWinnerReward) => Promise<void>;
|
|
815
|
+
/** 领取 Discord 角色回调 */
|
|
816
|
+
onClaimDiscordRole?: (reward: RewardValueInfo, layer: CampaignWinnerReward) => Promise<void>;
|
|
817
|
+
/**
|
|
818
|
+
* @deprecated 绑定现在由 Widget 内部处理,此回调不再使用
|
|
819
|
+
* 需要绑定链地址时的回调
|
|
820
|
+
*/
|
|
821
|
+
onBindChainRequired?: (chainTypes: ChainType[]) => void;
|
|
822
|
+
/**
|
|
823
|
+
* @deprecated 绑定现在由 Widget 内部处理,此回调不再使用
|
|
824
|
+
* 需要绑定 SNS 时的回调
|
|
825
|
+
*/
|
|
826
|
+
onBindSnsRequired?: (snsTypes: SnsType[]) => void;
|
|
827
|
+
/** 是否显示分享按钮(默认 true) */
|
|
828
|
+
showShare?: boolean;
|
|
829
|
+
/** 分享链接(未配置时回退到当前页面 URL) */
|
|
830
|
+
shareUrl?: string;
|
|
831
|
+
/** Twitter 分享文案(可选,有默认文案) */
|
|
832
|
+
shareText?: string;
|
|
833
|
+
/** 是否在 Twitter 分享文案末尾自动追加带 utm_source=x 的链接(默认 true) */
|
|
834
|
+
shareAutoAppendLink?: boolean;
|
|
835
|
+
/** 奖励详情展示模式:popup 弹窗 / redirect 跳转(默认 popup) */
|
|
836
|
+
rewardDisplayMode?: RewardDisplayMode;
|
|
837
|
+
/** 跳转 URL(当 rewardDisplayMode 为 'redirect' 时使用) */
|
|
838
|
+
rewardRedirectUrl?: string;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
export { RewardType }
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* Seed Token - Input values that auto-derive other tokens
|
|
845
|
+
*/
|
|
846
|
+
export declare interface SeedToken {
|
|
847
|
+
/** Primary color */
|
|
848
|
+
colorPrimary?: string;
|
|
849
|
+
/** Secondary color */
|
|
850
|
+
colorSecondary?: string;
|
|
851
|
+
/** Success color */
|
|
852
|
+
colorSuccess?: string;
|
|
853
|
+
/** Warning color */
|
|
854
|
+
colorWarning?: string;
|
|
855
|
+
/** Error color */
|
|
856
|
+
colorError?: string;
|
|
857
|
+
/** Base border radius */
|
|
858
|
+
borderRadius?: number;
|
|
859
|
+
/** Base font size */
|
|
860
|
+
fontSize?: number;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* Locales that have full translation support in all widgets
|
|
865
|
+
* Other locales in the Locale type will fallback to English
|
|
866
|
+
*/
|
|
867
|
+
export declare type SupportedLocale = "en" | "ko" | "ja";
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* TaskOn Context value
|
|
871
|
+
*/
|
|
872
|
+
export declare interface TaskOnContextValue {
|
|
873
|
+
/**
|
|
874
|
+
* Provider configuration
|
|
875
|
+
*/
|
|
876
|
+
config: TaskOnProviderConfig;
|
|
877
|
+
/**
|
|
878
|
+
* TaskOn client instance from @taskon/core
|
|
879
|
+
*/
|
|
880
|
+
client: TaskOnClient | null;
|
|
881
|
+
/**
|
|
882
|
+
* Whether the provider is initializing
|
|
883
|
+
*/
|
|
884
|
+
isInitializing: boolean;
|
|
885
|
+
/**
|
|
886
|
+
* Resolved locale
|
|
887
|
+
*/
|
|
888
|
+
locale: Locale;
|
|
889
|
+
/**
|
|
890
|
+
* TaskOn user ID, null if not logged in
|
|
891
|
+
*/
|
|
892
|
+
userId: number | null;
|
|
893
|
+
/**
|
|
894
|
+
* Current user info, null if not logged in
|
|
895
|
+
*/
|
|
896
|
+
userInfo: UserInfo | null;
|
|
897
|
+
/**
|
|
898
|
+
* Current user token, null if not logged in
|
|
899
|
+
*/
|
|
900
|
+
userToken: string | null;
|
|
901
|
+
/**
|
|
902
|
+
* Whether user is logged in
|
|
903
|
+
*/
|
|
904
|
+
isLoggedIn: boolean;
|
|
905
|
+
/**
|
|
906
|
+
* Unified login method
|
|
907
|
+
*/
|
|
908
|
+
login: (params: LoginParams) => Promise<void>;
|
|
909
|
+
/**
|
|
910
|
+
* Logout current user
|
|
911
|
+
*/
|
|
912
|
+
logout: () => void;
|
|
913
|
+
/**
|
|
914
|
+
* Request login callback
|
|
915
|
+
* Triggers config.onRequestLogin if provided
|
|
916
|
+
*/
|
|
917
|
+
requestLogin: () => void;
|
|
918
|
+
/**
|
|
919
|
+
* Refresh user info from server
|
|
920
|
+
* Call this after binding social accounts to update userInfo
|
|
921
|
+
*/
|
|
922
|
+
refreshUserInfo: () => Promise<void>;
|
|
923
|
+
/**
|
|
924
|
+
* Chain info list (loaded on init)
|
|
925
|
+
* Used for determining chain types for wallet binding
|
|
926
|
+
*/
|
|
927
|
+
chains: ChainInfo[];
|
|
928
|
+
/**
|
|
929
|
+
* Community info (auto-loaded on init based on apiKey)
|
|
930
|
+
* Used for displaying community logo and name in reward cards
|
|
931
|
+
*/
|
|
932
|
+
communityInfo: CommunityInfo | null;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* TaskOn Provider Component
|
|
937
|
+
*
|
|
938
|
+
* Root component for TaskOn Widget, providing:
|
|
939
|
+
* - TaskOn client management (based on @taskon/core)
|
|
940
|
+
* - User authentication (login/logout)
|
|
941
|
+
* - Locale configuration
|
|
942
|
+
* - Wallet management (uses window.ethereum adapter)
|
|
943
|
+
* - Widget locale preloading (optional)
|
|
944
|
+
* - Toast notifications (internal, user-transparent)
|
|
945
|
+
*/
|
|
946
|
+
export declare function TaskOnProvider({ config, children, preloadLocales, }: TaskOnProviderProps): ReactNode;
|
|
947
|
+
|
|
948
|
+
/**
|
|
949
|
+
* TaskOn Provider configuration
|
|
950
|
+
*/
|
|
951
|
+
export declare interface TaskOnProviderConfig {
|
|
952
|
+
/**
|
|
953
|
+
* API Key for authentication (X-API-Key header)
|
|
954
|
+
* Note: apiKey already contains community info, no need to configure communityId/communityKey separately
|
|
955
|
+
*/
|
|
956
|
+
apiKey: string;
|
|
957
|
+
/**
|
|
958
|
+
* API base URL (optional)
|
|
959
|
+
* @default https://white-label-api.taskon.xyz
|
|
960
|
+
*/
|
|
961
|
+
baseURL?: string;
|
|
962
|
+
/**
|
|
963
|
+
* Locale setting for internationalization
|
|
964
|
+
* @default auto-detect from browser
|
|
965
|
+
*/
|
|
966
|
+
locale?: Locale;
|
|
967
|
+
/**
|
|
968
|
+
* Wallet configuration for blockchain interactions
|
|
969
|
+
*
|
|
970
|
+
* When not provided, TaskOn will use built-in window.ethereum adapter
|
|
971
|
+
* for EVM wallet connections (MetaMask, etc.)
|
|
972
|
+
*/
|
|
973
|
+
walletConfig?: WalletConfig;
|
|
974
|
+
/**
|
|
975
|
+
* Callback when user requests to login
|
|
976
|
+
*
|
|
977
|
+
* This is triggered when user clicks on login overlay in widgets.
|
|
978
|
+
* Use this to show your login modal or redirect to login page.
|
|
979
|
+
*
|
|
980
|
+
* @example
|
|
981
|
+
* ```tsx
|
|
982
|
+
* <TaskOnProvider
|
|
983
|
+
* config={{
|
|
984
|
+
* apiKey: 'your-api-key',
|
|
985
|
+
* onRequestLogin: () => {
|
|
986
|
+
* setShowLoginModal(true);
|
|
987
|
+
* },
|
|
988
|
+
* }}
|
|
989
|
+
* >
|
|
990
|
+
* ```
|
|
991
|
+
*/
|
|
992
|
+
onRequestLogin?: () => void;
|
|
993
|
+
/**
|
|
994
|
+
* OAuth tool URL for social account binding
|
|
995
|
+
*
|
|
996
|
+
* When users need to bind Twitter/Discord/Telegram accounts,
|
|
997
|
+
* this URL will be used to open the OAuth authorization popup.
|
|
998
|
+
*
|
|
999
|
+
* @default https://generalauthservice.com (main environment)
|
|
1000
|
+
*
|
|
1001
|
+
* For stage/test environment, use: https://stage.generalauthservice.com
|
|
1002
|
+
*/
|
|
1003
|
+
oauthToolUrl?: string;
|
|
1004
|
+
/**
|
|
1005
|
+
* WalletConnect Project ID
|
|
1006
|
+
*
|
|
1007
|
+
* Required for WalletConnect functionality.
|
|
1008
|
+
* Get your project ID at https://cloud.walletconnect.com
|
|
1009
|
+
*
|
|
1010
|
+
* If not provided, WalletConnect option will be disabled in the wallet dialog.
|
|
1011
|
+
*/
|
|
1012
|
+
walletConnectProjectId?: string;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
export declare interface TaskOnProviderProps {
|
|
1016
|
+
/**
|
|
1017
|
+
* TaskOn configuration object
|
|
1018
|
+
*/
|
|
1019
|
+
config: TaskOnProviderConfig;
|
|
1020
|
+
/**
|
|
1021
|
+
* Child components
|
|
1022
|
+
*/
|
|
1023
|
+
children: ReactNode;
|
|
1024
|
+
/**
|
|
1025
|
+
* List of widgets to preload locales for
|
|
1026
|
+
*/
|
|
1027
|
+
preloadLocales?: WidgetName[];
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* Resolved theme object (returned by useTaskOnTheme)
|
|
1032
|
+
*/
|
|
1033
|
+
export declare interface TaskOnTheme {
|
|
1034
|
+
/** Current mode (resolved, never "auto") */
|
|
1035
|
+
mode: "light" | "dark";
|
|
1036
|
+
/** Whether compact mode is enabled */
|
|
1037
|
+
compact: boolean;
|
|
1038
|
+
/** All tokens (resolved) */
|
|
1039
|
+
tokens: Required<MapToken>;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Theme configuration
|
|
1044
|
+
*/
|
|
1045
|
+
export declare interface TaskOnThemeConfig {
|
|
1046
|
+
/** Theme mode */
|
|
1047
|
+
mode?: ThemeMode;
|
|
1048
|
+
/** Compact mode */
|
|
1049
|
+
compact?: boolean;
|
|
1050
|
+
/** Seed tokens */
|
|
1051
|
+
seed?: SeedToken;
|
|
1052
|
+
/** Map tokens (override derived values) */
|
|
1053
|
+
map?: MapToken;
|
|
1054
|
+
/** Light mode specific configuration */
|
|
1055
|
+
light?: ModeThemeConfig;
|
|
1056
|
+
/** Dark mode specific configuration */
|
|
1057
|
+
dark?: ModeThemeConfig;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* TemplateTask 组件
|
|
1062
|
+
*
|
|
1063
|
+
* @description 通用模版任务组件,负责:
|
|
1064
|
+
* - 解析 task.template.params 获取任务参数
|
|
1065
|
+
* - 使用 BaseTask 展示任务卡片
|
|
1066
|
+
* - 渲染描述字段(desc、desc_fields)
|
|
1067
|
+
* - 处理 Action 按钮(action_label、action_link)
|
|
1068
|
+
*
|
|
1069
|
+
* @example
|
|
1070
|
+
* ```tsx
|
|
1071
|
+
* <TemplateTask
|
|
1072
|
+
* task={taskInfo}
|
|
1073
|
+
* userStatus={userStatus}
|
|
1074
|
+
* onClick={() => console.log('卡片点击')}
|
|
1075
|
+
* onClaim={() => console.log('Claim 点击')}
|
|
1076
|
+
* />
|
|
1077
|
+
* ```
|
|
1078
|
+
*/
|
|
1079
|
+
export declare function TemplateTask({ task, userStatus, meetConditions, communityInfo, disabled, onClick, onClaim, onUpdate, onEligTaskClick, coolDown: sharedCoolDown, onCoolDownComplete: sharedOnCoolDownComplete, }: TemplateTaskProps): default_2.ReactElement;
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* TemplateTask 组件属性
|
|
1083
|
+
*/
|
|
1084
|
+
export declare interface TemplateTaskProps {
|
|
1085
|
+
/** 任务信息 */
|
|
1086
|
+
task: CommunityTaskInfo;
|
|
1087
|
+
/** 用户状态 */
|
|
1088
|
+
userStatus?: GtcUserTaskStatus;
|
|
1089
|
+
/** 资格条件列表(有值时显示遮罩) */
|
|
1090
|
+
meetConditions?: MeetCondition[];
|
|
1091
|
+
/** 社区信息(用于前置任务链接跳转) */
|
|
1092
|
+
communityInfo?: {
|
|
1093
|
+
community_key?: string;
|
|
1094
|
+
dapp_domain?: string;
|
|
1095
|
+
};
|
|
1096
|
+
/** 是否禁用交互 */
|
|
1097
|
+
disabled?: boolean;
|
|
1098
|
+
/** 点击卡片回调 */
|
|
1099
|
+
onClick?: () => void;
|
|
1100
|
+
/**
|
|
1101
|
+
* 点击 Claim 回调
|
|
1102
|
+
* @param token 可选的 OAuth token(reAuth 成功后传入)
|
|
1103
|
+
*/
|
|
1104
|
+
onClaim?: (token?: string) => void | Promise<{
|
|
1105
|
+
successful: boolean;
|
|
1106
|
+
errorCode?: string;
|
|
1107
|
+
cool_down?: number;
|
|
1108
|
+
}>;
|
|
1109
|
+
/** 任务更新回调(完成/验证成功后) */
|
|
1110
|
+
onUpdate?: () => void;
|
|
1111
|
+
/** 点击资格条件中的前置任务回调(用于打开任务弹窗) */
|
|
1112
|
+
onEligTaskClick?: (taskId: number) => void;
|
|
1113
|
+
/** 共享的 coolDown 值(来自父组件) */
|
|
1114
|
+
coolDown?: number;
|
|
1115
|
+
/** coolDown 倒计时结束回调 */
|
|
1116
|
+
onCoolDownComplete?: () => void;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
/**
|
|
1120
|
+
* Translation function type
|
|
1121
|
+
*/
|
|
1122
|
+
export declare type TFunction<T> = <K extends keyof T>(key: K, params?: InterpolationParams) => string;
|
|
1123
|
+
|
|
1124
|
+
/**
|
|
1125
|
+
* Theme mode
|
|
1126
|
+
* - light: Light mode
|
|
1127
|
+
* - dark: Dark mode
|
|
1128
|
+
* - auto: Follow system preference
|
|
1129
|
+
*/
|
|
1130
|
+
export declare type ThemeMode = "light" | "dark" | "auto";
|
|
1131
|
+
|
|
1132
|
+
/**
|
|
1133
|
+
* Theme Provider Component
|
|
1134
|
+
*
|
|
1135
|
+
* Provides theme configuration with support for:
|
|
1136
|
+
* - light/dark/auto modes
|
|
1137
|
+
* - Seed token derivation
|
|
1138
|
+
* - Map token overrides
|
|
1139
|
+
*
|
|
1140
|
+
* @example
|
|
1141
|
+
* ```tsx
|
|
1142
|
+
* <ThemeProvider theme={{ mode: 'dark', seed: { colorPrimary: '#6366f1' } }}>
|
|
1143
|
+
* <App />
|
|
1144
|
+
* </ThemeProvider>
|
|
1145
|
+
* ```
|
|
1146
|
+
*/
|
|
1147
|
+
export declare function ThemeProvider({ theme: themeConfig, children, }: ThemeProviderProps): ReactNode;
|
|
1148
|
+
|
|
1149
|
+
/**
|
|
1150
|
+
* ThemeProvider Props
|
|
1151
|
+
*/
|
|
1152
|
+
export declare interface ThemeProviderProps {
|
|
1153
|
+
/** Theme configuration */
|
|
1154
|
+
theme?: TaskOnThemeConfig;
|
|
1155
|
+
/** Child components */
|
|
1156
|
+
children: React.ReactNode;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
/**
|
|
1160
|
+
* Hook for loading common locale messages
|
|
1161
|
+
*
|
|
1162
|
+
* @returns Object containing common messages and loading state
|
|
1163
|
+
*
|
|
1164
|
+
* @example
|
|
1165
|
+
* ```tsx
|
|
1166
|
+
* function MyWidget() {
|
|
1167
|
+
* const { messages: common, isLoading } = useCommonLocale();
|
|
1168
|
+
*
|
|
1169
|
+
* if (isLoading) return <div>{common.loading}</div>;
|
|
1170
|
+
*
|
|
1171
|
+
* return <button onClick={retry}>{common.retry}</button>;
|
|
1172
|
+
* }
|
|
1173
|
+
* ```
|
|
1174
|
+
*/
|
|
1175
|
+
export declare function useCommonLocale(): UseWidgetLocaleResult<CommonMessages>;
|
|
1176
|
+
|
|
1177
|
+
/**
|
|
1178
|
+
* Hook to access EVM wallet
|
|
1179
|
+
*/
|
|
1180
|
+
export declare function useEvmWallet(): {
|
|
1181
|
+
adapter: WalletAdapter | null;
|
|
1182
|
+
address: string | null;
|
|
1183
|
+
chainId: number | null;
|
|
1184
|
+
isConnected: boolean;
|
|
1185
|
+
connect: () => Promise<string | null>;
|
|
1186
|
+
disconnect: () => Promise<void>;
|
|
1187
|
+
signMessage: (message: string) => Promise<string | null>;
|
|
1188
|
+
};
|
|
1189
|
+
|
|
1190
|
+
/**
|
|
1191
|
+
* 获取 Quest 详情 Hook
|
|
1192
|
+
*
|
|
1193
|
+
* @param options Hook 配置(包含从根组件传入的 api 实例)
|
|
1194
|
+
* @returns Quest 详情、加载状态、错误信息、重新加载方法
|
|
1195
|
+
*/
|
|
1196
|
+
export declare function useQuestDetail(options: UseQuestDetailOptions): UseQuestDetailReturn;
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* useQuestDetail Hook 参数
|
|
1200
|
+
*/
|
|
1201
|
+
declare interface UseQuestDetailOptions {
|
|
1202
|
+
/** Quest API 实例(从根组件传入) */
|
|
1203
|
+
api: QuestApi | null;
|
|
1204
|
+
/** Campaign ID */
|
|
1205
|
+
campaignId: number;
|
|
1206
|
+
/** 渠道标识(可选) */
|
|
1207
|
+
channel?: string;
|
|
1208
|
+
/** KOL 标识(可选) */
|
|
1209
|
+
kolHandle?: string;
|
|
1210
|
+
/** 邀请码(可选) */
|
|
1211
|
+
inviteCode?: string;
|
|
1212
|
+
/** Boost ID(可选) */
|
|
1213
|
+
boostId?: number;
|
|
1214
|
+
/** 是否启用(默认 true) */
|
|
1215
|
+
enabled?: boolean;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
/**
|
|
1219
|
+
* useQuestDetail Hook 返回值
|
|
1220
|
+
*/
|
|
1221
|
+
declare interface UseQuestDetailReturn {
|
|
1222
|
+
/** Campaign 详情数据 */
|
|
1223
|
+
data: QuestCampaignInfo | null;
|
|
1224
|
+
/** 是否加载中 */
|
|
1225
|
+
isLoading: boolean;
|
|
1226
|
+
/** 错误信息 */
|
|
1227
|
+
error: string | null;
|
|
1228
|
+
/** 重新加载 */
|
|
1229
|
+
refetch: () => void;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
/**
|
|
1233
|
+
* 获取 Quest 状态信息 Hook
|
|
1234
|
+
*
|
|
1235
|
+
* @param options Hook 配置(包含从根组件传入的 api 实例)
|
|
1236
|
+
* @returns Quest 状态、加载状态、错误信息、重新加载方法
|
|
1237
|
+
*/
|
|
1238
|
+
export declare function useQuestStatus(options: UseQuestStatusOptions): UseQuestStatusReturn;
|
|
1239
|
+
|
|
1240
|
+
/**
|
|
1241
|
+
* useQuestStatus Hook 参数
|
|
1242
|
+
*/
|
|
1243
|
+
declare interface UseQuestStatusOptions {
|
|
1244
|
+
/** Quest API 实例(从根组件传入) */
|
|
1245
|
+
api: QuestApi | null;
|
|
1246
|
+
/** Campaign ID */
|
|
1247
|
+
campaignId: number;
|
|
1248
|
+
/** 渠道标识 */
|
|
1249
|
+
channel?: string;
|
|
1250
|
+
/** KOL 句柄 */
|
|
1251
|
+
kolHandle?: string;
|
|
1252
|
+
/** 是否启用(默认 true) */
|
|
1253
|
+
enabled?: boolean;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
/**
|
|
1257
|
+
* useQuestStatus Hook 返回值
|
|
1258
|
+
*/
|
|
1259
|
+
declare interface UseQuestStatusReturn {
|
|
1260
|
+
/** Campaign 状态数据 */
|
|
1261
|
+
data: CampaignStatusInfo | null;
|
|
1262
|
+
/** 是否加载中 */
|
|
1263
|
+
isLoading: boolean;
|
|
1264
|
+
/** 错误信息 */
|
|
1265
|
+
error: string | null;
|
|
1266
|
+
/** 重新加载 */
|
|
1267
|
+
refetch: () => void;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
/**
|
|
1271
|
+
* 获取用户 Quest 状态 Hook
|
|
1272
|
+
*
|
|
1273
|
+
* @param options Hook 配置(包含从根组件传入的 api 实例)
|
|
1274
|
+
* @returns 用户状态、加载状态、错误信息、重新加载方法
|
|
1275
|
+
*/
|
|
1276
|
+
export declare function useQuestUserStatus(options: UseQuestUserStatusOptions): UseQuestUserStatusReturn;
|
|
1277
|
+
|
|
1278
|
+
/**
|
|
1279
|
+
* useQuestUserStatus Hook 参数
|
|
1280
|
+
*/
|
|
1281
|
+
declare interface UseQuestUserStatusOptions {
|
|
1282
|
+
/** Quest API 实例(从根组件传入) */
|
|
1283
|
+
api: QuestApi | null;
|
|
1284
|
+
/** Campaign ID */
|
|
1285
|
+
campaignId: number;
|
|
1286
|
+
/** 渠道标识(可选) */
|
|
1287
|
+
channel?: string;
|
|
1288
|
+
/** KOL 标识(可选) */
|
|
1289
|
+
kolHandle?: string;
|
|
1290
|
+
/** 是否启用(默认 true) */
|
|
1291
|
+
enabled?: boolean;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
/**
|
|
1295
|
+
* useQuestUserStatus Hook 返回值
|
|
1296
|
+
*/
|
|
1297
|
+
declare interface UseQuestUserStatusReturn {
|
|
1298
|
+
/** 用户状态数据 */
|
|
1299
|
+
data: UserCampaignStatusInfo | null;
|
|
1300
|
+
/** 是否加载中 */
|
|
1301
|
+
isLoading: boolean;
|
|
1302
|
+
/** 错误信息 */
|
|
1303
|
+
error: string | null;
|
|
1304
|
+
/** 重新加载 */
|
|
1305
|
+
refetch: () => void;
|
|
1306
|
+
/**
|
|
1307
|
+
* 立即更新指定任务的本地状态(乐观更新)
|
|
1308
|
+
* @param taskId 任务 ID
|
|
1309
|
+
* @param isAsync 是否为异步任务(异步任务只更新 is_submitter)
|
|
1310
|
+
*/
|
|
1311
|
+
updateTaskStatus: (taskId: number, isAsync?: boolean) => void;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
/**
|
|
1315
|
+
* UserCenterWidget 外层组件
|
|
1316
|
+
*
|
|
1317
|
+
* Handles cloud config loading + ThemeProvider wrapping via WidgetShell.
|
|
1318
|
+
* Merges cloud function config with local props, then renders inner component.
|
|
1319
|
+
*
|
|
1320
|
+
* @example
|
|
1321
|
+
* ```tsx
|
|
1322
|
+
* // Pure props mode (existing behavior)
|
|
1323
|
+
* <UserCenterWidget config={tabConfig} />
|
|
1324
|
+
*
|
|
1325
|
+
* // Pure widgetId mode (config from cloud)
|
|
1326
|
+
* <UserCenterWidget widgetId={456} />
|
|
1327
|
+
*
|
|
1328
|
+
* // Mixed mode (props override cloud)
|
|
1329
|
+
* <UserCenterWidget widgetId={456} defaultTab={UserCenterTabType.Identity} />
|
|
1330
|
+
* ```
|
|
1331
|
+
*/
|
|
1332
|
+
export declare function UserCenterWidget(props: UserCenterWidgetProps): default_2.ReactElement;
|
|
1333
|
+
|
|
1334
|
+
/**
|
|
1335
|
+
* UserCenterWidget 属性
|
|
1336
|
+
*/
|
|
1337
|
+
export declare interface UserCenterWidgetProps {
|
|
1338
|
+
/**
|
|
1339
|
+
* Widget ID - load configuration (theme + function) from cloud
|
|
1340
|
+
* Cloud config provides tab options, display settings, etc.
|
|
1341
|
+
*/
|
|
1342
|
+
widgetId?: number;
|
|
1343
|
+
/** Widget 配置 */
|
|
1344
|
+
config?: UserCenterConfig;
|
|
1345
|
+
/** 默认选中的 Tab */
|
|
1346
|
+
defaultTab?: UserCenterTabType;
|
|
1347
|
+
/** 默认选中的奖励卡片(MyRewards 内部) */
|
|
1348
|
+
defaultRewardCard?: UserCenterRewardCardType;
|
|
1349
|
+
/** 默认 Points ID(仅当 defaultRewardCard=Points 时使用) */
|
|
1350
|
+
defaultPointId?: number;
|
|
1351
|
+
/** Tab 切换回调 */
|
|
1352
|
+
onTabChange?: (tab: UserCenterTabType) => void;
|
|
1353
|
+
/** 自定义类名 */
|
|
1354
|
+
className?: string;
|
|
1355
|
+
/** 自定义样式 */
|
|
1356
|
+
style?: default_2.CSSProperties;
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
export { UserInfo }
|
|
1360
|
+
|
|
1361
|
+
/**
|
|
1362
|
+
* Public hook for TaskOn authentication
|
|
1363
|
+
*
|
|
1364
|
+
* @example
|
|
1365
|
+
* ```tsx
|
|
1366
|
+
* const { login, logout, userId, isLoggedIn, requestLogin } = useTaskOnAuth();
|
|
1367
|
+
*
|
|
1368
|
+
* // EVM wallet login
|
|
1369
|
+
* await login({ method: 'evm_wallet', value: '0x...', sign, timestamp });
|
|
1370
|
+
*
|
|
1371
|
+
* // Email login
|
|
1372
|
+
* await login({ method: 'email', value: 'user@example.com', sign, timestamp });
|
|
1373
|
+
*
|
|
1374
|
+
* // Discord login
|
|
1375
|
+
* await login({ method: 'discord', value: oauthToken, sign, timestamp });
|
|
1376
|
+
*
|
|
1377
|
+
* // Request login (triggers config.onRequestLogin)
|
|
1378
|
+
* requestLogin();
|
|
1379
|
+
* ```
|
|
1380
|
+
*/
|
|
1381
|
+
export declare function useTaskOnAuth(): {
|
|
1382
|
+
userId: number | null;
|
|
1383
|
+
isLoggedIn: boolean;
|
|
1384
|
+
isInitializing: boolean;
|
|
1385
|
+
login: (params: LoginParams) => Promise<void>;
|
|
1386
|
+
logout: () => void;
|
|
1387
|
+
requestLogin: () => void;
|
|
1388
|
+
};
|
|
1389
|
+
|
|
1390
|
+
/**
|
|
1391
|
+
* Get current theme
|
|
1392
|
+
* Must be used within a ThemeProvider
|
|
1393
|
+
*/
|
|
1394
|
+
export declare function useTaskOnTheme(): TaskOnTheme;
|
|
1395
|
+
|
|
1396
|
+
/**
|
|
1397
|
+
* Hook for widget translations with interpolation support
|
|
1398
|
+
*
|
|
1399
|
+
* This is a higher-level hook that wraps useWidgetLocale and adds
|
|
1400
|
+
* a `t` function for convenient string interpolation.
|
|
1401
|
+
*
|
|
1402
|
+
* @template T - The shape of the messages object
|
|
1403
|
+
* @param options - Same options as useWidgetLocale
|
|
1404
|
+
* @returns Object containing t function, messages, and loading state
|
|
1405
|
+
*
|
|
1406
|
+
* @example
|
|
1407
|
+
* ```tsx
|
|
1408
|
+
* // messages/en.ts
|
|
1409
|
+
* export default {
|
|
1410
|
+
* greeting: 'Hello, {name}!',
|
|
1411
|
+
* points: 'You have {count} points',
|
|
1412
|
+
* title: 'Task Widget',
|
|
1413
|
+
* };
|
|
1414
|
+
*
|
|
1415
|
+
* // Component
|
|
1416
|
+
* function TaskWidget() {
|
|
1417
|
+
* const { t, isLoading } = useTranslation({
|
|
1418
|
+
* widgetId: 'TaskWidget',
|
|
1419
|
+
* defaultMessages: enMessages,
|
|
1420
|
+
* loadMessages,
|
|
1421
|
+
* });
|
|
1422
|
+
*
|
|
1423
|
+
* if (isLoading) return <div>Loading...</div>;
|
|
1424
|
+
*
|
|
1425
|
+
* return (
|
|
1426
|
+
* <div>
|
|
1427
|
+
* <h1>{t('title')}</h1>
|
|
1428
|
+
* <p>{t('greeting', { name: 'John' })}</p>
|
|
1429
|
+
* <p>{t('points', { count: 100 })}</p>
|
|
1430
|
+
* </div>
|
|
1431
|
+
* );
|
|
1432
|
+
* }
|
|
1433
|
+
* ```
|
|
1434
|
+
*/
|
|
1435
|
+
export declare function useTranslation<T>(options: UseWidgetLocaleOptions<T>): UseTranslationResult<T>;
|
|
1436
|
+
|
|
1437
|
+
/**
|
|
1438
|
+
* Return type for useTranslation hook
|
|
1439
|
+
*/
|
|
1440
|
+
export declare interface UseTranslationResult<T> {
|
|
1441
|
+
/**
|
|
1442
|
+
* Translation function with interpolation support
|
|
1443
|
+
*
|
|
1444
|
+
* @example
|
|
1445
|
+
* ```ts
|
|
1446
|
+
* t('greeting', { name: 'John' }) // => 'Hello, John!'
|
|
1447
|
+
* t('points', { count: 100 }) // => 'You have 100 points'
|
|
1448
|
+
* ```
|
|
1449
|
+
*/
|
|
1450
|
+
t: TFunction<T>;
|
|
1451
|
+
/**
|
|
1452
|
+
* Raw messages object (without interpolation)
|
|
1453
|
+
* Useful when you need direct access to message strings
|
|
1454
|
+
*/
|
|
1455
|
+
messages: T;
|
|
1456
|
+
/**
|
|
1457
|
+
* Whether translations are currently loading
|
|
1458
|
+
*/
|
|
1459
|
+
isLoading: boolean;
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
/**
|
|
1463
|
+
* Hook to access wallet context
|
|
1464
|
+
* Returns wallet state and actions for EVM
|
|
1465
|
+
*
|
|
1466
|
+
* @example
|
|
1467
|
+
* ```tsx
|
|
1468
|
+
* const { evmAddress, isEvmConnected, connectEvm, signEvmMessage } = useWallet();
|
|
1469
|
+
*
|
|
1470
|
+
* // Connect EVM wallet
|
|
1471
|
+
* const address = await connectEvm();
|
|
1472
|
+
*
|
|
1473
|
+
* // Sign message
|
|
1474
|
+
* const signature = await signEvmMessage("Hello World");
|
|
1475
|
+
* ```
|
|
1476
|
+
*/
|
|
1477
|
+
export declare function useWallet(): WalletContextValue;
|
|
1478
|
+
|
|
1479
|
+
/**
|
|
1480
|
+
* Hook for loading widget-specific locale messages
|
|
1481
|
+
*
|
|
1482
|
+
* @template T - The shape of the messages object
|
|
1483
|
+
* @param options - Configuration options
|
|
1484
|
+
* @param options.defaultMessages - English messages (inlined, no loading needed)
|
|
1485
|
+
* @param options.loadMessages - Function to dynamically import other locales
|
|
1486
|
+
* @returns Object containing messages and loading state
|
|
1487
|
+
*
|
|
1488
|
+
* @example
|
|
1489
|
+
* ```tsx
|
|
1490
|
+
* import enMessages from './locales/en';
|
|
1491
|
+
*
|
|
1492
|
+
* function TaskWidget() {
|
|
1493
|
+
* const { messages, isLoading } = useWidgetLocale({
|
|
1494
|
+
* defaultMessages: enMessages,
|
|
1495
|
+
* loadMessages: (locale) => import(`./locales/${locale}.ts`),
|
|
1496
|
+
* });
|
|
1497
|
+
*
|
|
1498
|
+
* if (isLoading) return <div>Loading...</div>;
|
|
1499
|
+
*
|
|
1500
|
+
* return <button>{messages.claim}</button>;
|
|
1501
|
+
* }
|
|
1502
|
+
* ```
|
|
1503
|
+
*/
|
|
1504
|
+
export declare function useWidgetLocale<T>(options: UseWidgetLocaleOptions<T>): UseWidgetLocaleResult<T>;
|
|
1505
|
+
|
|
1506
|
+
/**
|
|
1507
|
+
* Options for useWidgetLocale hook
|
|
1508
|
+
*
|
|
1509
|
+
* @template T - The shape of the messages object
|
|
1510
|
+
*/
|
|
1511
|
+
export declare interface UseWidgetLocaleOptions<T> {
|
|
1512
|
+
/**
|
|
1513
|
+
* Unique identifier for this widget
|
|
1514
|
+
* Used as cache key prefix to avoid conflicts between widgets
|
|
1515
|
+
*
|
|
1516
|
+
* @example "TaskWidget", "WalletWidget"
|
|
1517
|
+
*/
|
|
1518
|
+
widgetId: string;
|
|
1519
|
+
/**
|
|
1520
|
+
* Default messages (English) - inlined in bundle
|
|
1521
|
+
* These are used immediately without any loading
|
|
1522
|
+
*/
|
|
1523
|
+
defaultMessages: T;
|
|
1524
|
+
/**
|
|
1525
|
+
* Function to dynamically load messages for other locales
|
|
1526
|
+
* Should return a dynamic import promise
|
|
1527
|
+
*
|
|
1528
|
+
* @example
|
|
1529
|
+
* ```ts
|
|
1530
|
+
* loadMessages: (locale) => import(`./locales/${locale}.ts`)
|
|
1531
|
+
* ```
|
|
1532
|
+
*/
|
|
1533
|
+
loadMessages: (locale: Locale) => Promise<{
|
|
1534
|
+
default: T;
|
|
1535
|
+
}>;
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
/**
|
|
1539
|
+
* Return type for useWidgetLocale hook
|
|
1540
|
+
*
|
|
1541
|
+
* @template T - The shape of the messages object
|
|
1542
|
+
*/
|
|
1543
|
+
export declare interface UseWidgetLocaleResult<T> {
|
|
1544
|
+
/**
|
|
1545
|
+
* Current messages object based on active locale
|
|
1546
|
+
* Falls back to default (English) messages if loading fails
|
|
1547
|
+
*/
|
|
1548
|
+
messages: T;
|
|
1549
|
+
/**
|
|
1550
|
+
* Whether the locale messages are currently loading
|
|
1551
|
+
* Only true when switching to a non-default locale
|
|
1552
|
+
*/
|
|
1553
|
+
isLoading: boolean;
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
/**
|
|
1557
|
+
* Wallet adapter interface for blockchain interactions
|
|
1558
|
+
*
|
|
1559
|
+
* This interface abstracts wallet operations, allowing widgets to work with
|
|
1560
|
+
* different wallet providers (custom implementations or built-in adapters)
|
|
1561
|
+
*/
|
|
1562
|
+
export declare interface WalletAdapter {
|
|
1563
|
+
/**
|
|
1564
|
+
* Connect to wallet and return the connected address
|
|
1565
|
+
* Should open wallet selection UI if needed
|
|
1566
|
+
*/
|
|
1567
|
+
connect: () => Promise<string>;
|
|
1568
|
+
/**
|
|
1569
|
+
* Disconnect from wallet
|
|
1570
|
+
*/
|
|
1571
|
+
disconnect: () => Promise<void>;
|
|
1572
|
+
/**
|
|
1573
|
+
* Sign a message with the connected wallet
|
|
1574
|
+
* @param message - The message to sign
|
|
1575
|
+
* @returns The signature
|
|
1576
|
+
*/
|
|
1577
|
+
signMessage: (message: string) => Promise<string>;
|
|
1578
|
+
/**
|
|
1579
|
+
* Get the currently connected address
|
|
1580
|
+
* @returns The address or null if not connected
|
|
1581
|
+
*/
|
|
1582
|
+
getAddress: () => string | null;
|
|
1583
|
+
/**
|
|
1584
|
+
* Get the current chain ID
|
|
1585
|
+
* @returns The chain ID or null if not available
|
|
1586
|
+
*/
|
|
1587
|
+
getChainId?: () => number | null;
|
|
1588
|
+
/**
|
|
1589
|
+
* Switch to a different network
|
|
1590
|
+
* @param chainId - The target chain ID
|
|
1591
|
+
*/
|
|
1592
|
+
switchNetwork?: (chainId: number) => Promise<void>;
|
|
1593
|
+
/**
|
|
1594
|
+
* Invoke a smart contract method
|
|
1595
|
+
* @param params - Contract invocation parameters
|
|
1596
|
+
* @returns Transaction hash
|
|
1597
|
+
*/
|
|
1598
|
+
invokeContract?: (params: InvokeContractParams) => Promise<string>;
|
|
1599
|
+
/**
|
|
1600
|
+
* Get wallet's native token balance (for gas estimation)
|
|
1601
|
+
* @returns Balance in wei (string)
|
|
1602
|
+
*/
|
|
1603
|
+
getBalance?: () => Promise<string>;
|
|
1604
|
+
/**
|
|
1605
|
+
* Subscribe to account changes
|
|
1606
|
+
* @param callback - Called when account changes
|
|
1607
|
+
* @returns Unsubscribe function
|
|
1608
|
+
*/
|
|
1609
|
+
onAccountChange?: (callback: (address: string | null) => void) => () => void;
|
|
1610
|
+
/**
|
|
1611
|
+
* Subscribe to chain/network changes
|
|
1612
|
+
* @param callback - Called when chain changes
|
|
1613
|
+
* @returns Unsubscribe function
|
|
1614
|
+
*/
|
|
1615
|
+
onChainChange?: (callback: (chainId: number) => void) => () => void;
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
/**
|
|
1619
|
+
* Wallet configuration for TaskOnProvider
|
|
1620
|
+
*/
|
|
1621
|
+
export declare interface WalletConfig {
|
|
1622
|
+
/**
|
|
1623
|
+
* Custom EVM wallet adapter
|
|
1624
|
+
* If not provided, uses built-in window.ethereum adapter
|
|
1625
|
+
*/
|
|
1626
|
+
evmAdapter?: WalletAdapter;
|
|
1627
|
+
/**
|
|
1628
|
+
* Disable auto-detection of wallet providers
|
|
1629
|
+
* When true, only uses adapter explicitly provided above
|
|
1630
|
+
* @default false
|
|
1631
|
+
*/
|
|
1632
|
+
disableAutoDetect?: boolean;
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
/**
|
|
1636
|
+
* Wallet context value type
|
|
1637
|
+
*/
|
|
1638
|
+
declare interface WalletContextValue extends WalletState {
|
|
1639
|
+
connectEvm: () => Promise<string | null>;
|
|
1640
|
+
disconnectEvm: () => Promise<void>;
|
|
1641
|
+
signEvmMessage: (message: string) => Promise<string | null>;
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
/**
|
|
1645
|
+
* Wallet state exposed through context
|
|
1646
|
+
*/
|
|
1647
|
+
export declare interface WalletState {
|
|
1648
|
+
evmAdapter: WalletAdapter | null;
|
|
1649
|
+
evmAddress: string | null;
|
|
1650
|
+
evmChainId: number | null;
|
|
1651
|
+
isEvmConnected: boolean;
|
|
1652
|
+
isDetecting: boolean;
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
/**
|
|
1656
|
+
* Supported widget names for preloading
|
|
1657
|
+
*/
|
|
1658
|
+
export declare type WidgetName = "CommunityTask";
|
|
1659
|
+
|
|
1660
|
+
export { }
|