返回 AiToEarn
hooks.ts
根目录 / project / aitoearn-web / src / store / plugin / hooks.ts
1 /**
2 * 浏览器插件相关的自定义 Hooks
3 */
4
5 'use client'
6
7 import type {
8 OperationResult,
9 PluginPlatformType,
10 ProgressCallback,
11 PublishParams,
12 } from './types/baseTypes'
13 import { useCallback, useEffect } from 'react'
14 import { DEFAULT_POLLING_INTERVAL } from './constants'
15 import { usePluginStore } from './store'
16 import { PluginStatus } from './types/baseTypes'
17
18 /**
19 * 使用插件状态和方法的 Hook
20 * @param autoPolling 是否自动轮询插件状态,默认 true
21 * @param pollingInterval 轮询间隔(毫秒),默认 2000ms
22 */
23 export function usePlugin(autoPolling = true, pollingInterval = DEFAULT_POLLING_INTERVAL) {
24 const {
25 status,
26 isPublishing,
27 publishProgress,
28 checkPlugin,
29 startPolling,
30 stopPolling,
31 login,
32 publish,
33 resetPublishState,
34 } = usePluginStore()
35
36 // 自动轮询
37 useEffect(() => {
38 if (autoPolling) {
39 startPolling(pollingInterval)
40 return () => {
41 stopPolling()
42 }
43 }
44 }, [autoPolling, pollingInterval, startPolling, stopPolling])
45
46 // 判断插件是否已就绪
47 const isReady = status === PluginStatus.READY
48
49 // 判断插件是否已连接(兼容旧代码)
50 const isConnected = isReady
51
52 // 判断插件是否未安装
53 const isNotInstalled = status === PluginStatus.NOT_INSTALLED
54
55 // 判断是否正在检测
56 const isChecking = status === PluginStatus.CHECKING
57
58 // 判断插件是否已安装但未授权
59 const isInstalledNoPermission = status === PluginStatus.INSTALLED_NO_PERMISSION
60
61 return {
62 // 状态
63 status,
64 isReady,
65 isConnected,
66 isNotInstalled,
67 isChecking,
68 isInstalledNoPermission,
69 isPublishing,
70 publishProgress,
71
72 // 方法
73 checkPlugin,
74 startPolling,
75 stopPolling,
76 login,
77 publish,
78 resetPublishState,
79 }
80 }
81
82 /**
83 * 使用平台登录的 Hook
84 */
85 export function usePluginLogin() {
86 const { login } = usePluginStore()
87
88 /**
89 * 登录到指定平台
90 * @param platform 平台类型
91 * @returns Promise<账号信息>
92 */
93 const loginToPlatform = useCallback(
94 async (platform: PluginPlatformType) => {
95 try {
96 const accountInfo = await login(platform)
97 return { success: true, data: accountInfo } as OperationResult
98 }
99 catch (error) {
100 return {
101 success: false,
102 error: error instanceof Error ? error.message : '登录失败',
103 } as OperationResult
104 }
105 },
106 [login],
107 )
108
109 return {
110 login: loginToPlatform,
111 }
112 }
113
114 /**
115 * 使用发布功能的 Hook
116 */
117 export function usePluginPublish() {
118 const { publish, isPublishing, publishProgress, resetPublishState } = usePluginStore()
119
120 /**
121 * 发布内容
122 * @param params 发布参数
123 * @param onProgress 进度回调
124 * @returns Promise<发布结果>
125 */
126 const publishContent = useCallback(
127 async (params: PublishParams, onProgress?: ProgressCallback) => {
128 try {
129 const result = await publish(params, onProgress)
130 return { success: true, data: result } as OperationResult
131 }
132 catch (error) {
133 return {
134 success: false,
135 error: error instanceof Error ? error.message : '发布失败',
136 } as OperationResult
137 }
138 },
139 [publish],
140 )
141
142 /**
143 * 发布视频
144 */
145 const publishVideo = useCallback(
146 async (
147 platform: PluginPlatformType,
148 video: File | string,
149 cover: File | string,
150 options: {
151 title?: string
152 desc?: string
153 topics?: string[]
154 visibility?: 'public' | 'private' | 'friends'
155 } = {},
156 onProgress?: ProgressCallback,
157 ) => {
158 return publishContent(
159 {
160 platform,
161 type: 'video',
162 video,
163 cover,
164 ...options,
165 },
166 onProgress,
167 )
168 },
169 [publishContent],
170 )
171
172 /**
173 * 发布图文
174 */
175 const publishImages = useCallback(
176 async (
177 platform: PluginPlatformType,
178 images: (File | string)[],
179 options: {
180 title?: string
181 desc?: string
182 topics?: string[]
183 visibility?: 'public' | 'private' | 'friends'
184 } = {},
185 onProgress?: ProgressCallback,
186 ) => {
187 return publishContent(
188 {
189 platform,
190 type: 'image',
191 images,
192 ...options,
193 },
194 onProgress,
195 )
196 },
197 [publishContent],
198 )
199
200 return {
201 publish: publishContent,
202 publishVideo,
203 publishImages,
204 isPublishing,
205 publishProgress,
206 resetPublishState,
207 }
208 }
209
210 /**
211 * 完整的插件工作流 Hook(登录 + 发布)
212 */
213 export function usePluginWorkflow() {
214 const { isReady } = usePlugin()
215 const { login } = usePluginLogin()
216 const { publishVideo, publishImages } = usePluginPublish()
217
218 /**
219 * 登录并发布视频
220 */
221 const loginAndPublishVideo = useCallback(
222 async (
223 platform: PluginPlatformType,
224 video: File | string,
225 cover: File | string,
226 options: {
227 title?: string
228 desc?: string
229 topics?: string[]
230 } = {},
231 onProgress?: ProgressCallback,
232 ) => {
233 // 第一步:登录
234 const loginResult = await login(platform)
235 if (!loginResult.success) {
236 return loginResult
237 }
238
239 // 第二步:发布
240 return publishVideo(platform, video, cover, options, onProgress)
241 },
242 [login, publishVideo],
243 )
244
245 /**
246 * 登录并发布图文
247 */
248 const loginAndPublishImages = useCallback(
249 async (
250 platform: PluginPlatformType,
251 images: (File | string)[],
252 options: {
253 title?: string
254 desc?: string
255 topics?: string[]
256 } = {},
257 onProgress?: ProgressCallback,
258 ) => {
259 // 第一步:登录
260 const loginResult = await login(platform)
261 if (!loginResult.success) {
262 return loginResult
263 }
264
265 // 第二步:发布
266 return publishImages(platform, images, options, onProgress)
267 },
268 [login, publishImages],
269 )
270
271 return {
272 isReady,
273 loginAndPublishVideo,
274 loginAndPublishImages,
275 }
276 }
277
277 lines TYPESCRIPT