119 lines
3.7 KiB
TypeScript
119 lines
3.7 KiB
TypeScript
import { root } from '@repo/core'
|
|
import { TemplateSocialController } from '@repo/sdk'
|
|
import { useCallback, useState } from 'react'
|
|
|
|
import { type ApiError } from '@/lib/types'
|
|
import { handleError } from './use-error'
|
|
import { templateSocialStore } from '@/stores/templateSocialStore'
|
|
|
|
export const useTemplateLike = (templateId?: string, initialLikeCount?: number) => {
|
|
const [loading, setLoading] = useState<boolean>(false)
|
|
const [error, setError] = useState<ApiError | null>(null)
|
|
|
|
const like = useCallback(async (): Promise<{ error?: ApiError }> => {
|
|
if (!templateId) {
|
|
return { error: { message: 'TemplateId is required' } as ApiError }
|
|
}
|
|
|
|
setLoading(true)
|
|
setError(null)
|
|
|
|
// 乐观更新:立即更新状态
|
|
const currentCount = templateSocialStore.getLikeCount(templateId) ?? initialLikeCount ?? 0
|
|
templateSocialStore.setLiked(templateId, true)
|
|
templateSocialStore.setLikeCount(templateId, currentCount + 1)
|
|
|
|
const social = root.get(TemplateSocialController)
|
|
const { data, error } = await handleError(
|
|
async () => await social.like({ templateId })
|
|
)
|
|
|
|
setLoading(false)
|
|
|
|
if (error) {
|
|
// 回滚乐观更新
|
|
templateSocialStore.setLiked(templateId, false)
|
|
templateSocialStore.setLikeCount(templateId, currentCount)
|
|
setError(error)
|
|
return { error }
|
|
}
|
|
|
|
// 使用服务器返回的准确数量
|
|
if (data?.likeCount !== undefined) {
|
|
templateSocialStore.setLikeCount(templateId, data.likeCount)
|
|
}
|
|
|
|
return {}
|
|
}, [templateId, initialLikeCount])
|
|
|
|
const unlike = useCallback(async (): Promise<{ error?: ApiError }> => {
|
|
if (!templateId) {
|
|
return { error: { message: 'TemplateId is required' } as ApiError }
|
|
}
|
|
|
|
setLoading(true)
|
|
setError(null)
|
|
|
|
// 乐观更新:立即更新状态
|
|
const currentCount = templateSocialStore.getLikeCount(templateId) ?? initialLikeCount ?? 0
|
|
templateSocialStore.setLiked(templateId, false)
|
|
templateSocialStore.setLikeCount(templateId, Math.max(0, currentCount - 1))
|
|
|
|
const social = root.get(TemplateSocialController)
|
|
const { data, error } = await handleError(
|
|
async () => await social.unlike({ templateId })
|
|
)
|
|
|
|
setLoading(false)
|
|
|
|
if (error) {
|
|
// 回滚乐观更新
|
|
templateSocialStore.setLiked(templateId, true)
|
|
templateSocialStore.setLikeCount(templateId, currentCount)
|
|
setError(error)
|
|
return { error }
|
|
}
|
|
|
|
// 使用服务器返回的准确数量
|
|
if (data?.likeCount !== undefined) {
|
|
templateSocialStore.setLikeCount(templateId, data.likeCount)
|
|
}
|
|
|
|
return {}
|
|
}, [templateId, initialLikeCount])
|
|
|
|
const checkLiked = useCallback(async (): Promise<{ error?: ApiError }> => {
|
|
if (!templateId) {
|
|
return { error: { message: 'TemplateId is required' } as ApiError }
|
|
}
|
|
|
|
setLoading(true)
|
|
setError(null)
|
|
|
|
const social = root.get(TemplateSocialController)
|
|
const { data, error } = await handleError(
|
|
async () => await social.checkLiked({ templateId })
|
|
)
|
|
|
|
setLoading(false)
|
|
|
|
if (error) {
|
|
setError(error)
|
|
return { error }
|
|
}
|
|
|
|
if (data?.liked !== undefined) {
|
|
templateSocialStore.setLiked(templateId, data.liked)
|
|
}
|
|
return {}
|
|
}, [templateId, initialLikeCount])
|
|
|
|
return {
|
|
loading,
|
|
error,
|
|
like,
|
|
unlike,
|
|
checkLiked,
|
|
}
|
|
}
|