expo-popcore-app/hooks/use-template-like.ts

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,
}
}