expo-popcore-app/stores/templateSocialStore.ts

174 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { create } from 'zustand'
import { devtools } from 'zustand/middleware'
interface TemplateSocialState {
// 点赞状态缓存: templateId -> boolean
likedMap: Record<string, boolean>
// 收藏状态缓存: templateId -> boolean
favoritedMap: Record<string, boolean>
// 点赞数量缓存: templateId -> number
likeCountMap: Record<string, number>
// 批量更新点赞状态
setLikedStates: (states: Record<string, boolean>) => void
// 批量更新收藏状态
setFavoritedStates: (states: Record<string, boolean>) => void
// 批量更新点赞数量
setLikeCountStates: (states: Record<string, number>) => void
// 更新单个点赞状态
setLiked: (templateId: string, liked: boolean) => void
// 更新单个收藏状态
setFavorited: (templateId: string, favorited: boolean) => void
// 更新单个点赞数量
setLikeCount: (templateId: string, count: number) => void
// 增加点赞数量(乐观更新)
incrementLikeCount: (templateId: string) => void
// 减少点赞数量(乐观更新)
decrementLikeCount: (templateId: string) => void
// 获取点赞状态(如果不存在返回 undefined
getLiked: (templateId: string) => boolean | undefined
// 获取收藏状态(如果不存在返回 undefined
getFavorited: (templateId: string) => boolean | undefined
// 获取点赞数量(如果不存在返回 undefined
getLikeCount: (templateId: string) => number | undefined
// 获取点赞状态(如果不存在返回 false
isLiked: (templateId: string) => boolean
// 获取收藏状态(如果不存在返回 false
isFavorited: (templateId: string) => boolean
// 清空所有缓存
clear: () => void
}
export const useTemplateSocialStore = create<TemplateSocialState>()(
devtools(
(set, get) => ({
// State
likedMap: {},
favoritedMap: {},
likeCountMap: {},
// Actions
setLikedStates: (states) => {
set((state) => ({
likedMap: { ...state.likedMap, ...states },
}))
},
setFavoritedStates: (states) => {
set((state) => ({
favoritedMap: { ...state.favoritedMap, ...states },
}))
},
setLikeCountStates: (states) => {
set((state) => ({
likeCountMap: { ...state.likeCountMap, ...states },
}))
},
setLiked: (templateId, liked) => {
set((state) => ({
likedMap: { ...state.likedMap, [templateId]: liked },
}))
},
setFavorited: (templateId, favorited) => {
set((state) => ({
favoritedMap: { ...state.favoritedMap, [templateId]: favorited },
}))
},
setLikeCount: (templateId, count) => {
set((state) => ({
likeCountMap: { ...state.likeCountMap, [templateId]: count },
}))
},
incrementLikeCount: (templateId) => {
set((state) => ({
likeCountMap: {
...state.likeCountMap,
[templateId]: (state.likeCountMap[templateId] || 0) + 1,
},
}))
},
decrementLikeCount: (templateId) => {
set((state) => {
const currentCount = state.likeCountMap[templateId] || 0
return {
likeCountMap: {
...state.likeCountMap,
[templateId]: Math.max(0, currentCount - 1),
},
}
})
},
getLiked: (templateId) => {
return get().likedMap[templateId]
},
getFavorited: (templateId) => {
return get().favoritedMap[templateId]
},
getLikeCount: (templateId) => {
return get().likeCountMap[templateId]
},
isLiked: (templateId) => {
return get().likedMap[templateId] || false
},
isFavorited: (templateId) => {
return get().favoritedMap[templateId] || false
},
clear: () => {
set({
likedMap: {},
favoritedMap: {},
likeCountMap: {},
})
},
}),
{ name: 'TemplateSocialStore' }
)
)
// 选择器 hook只订阅特定模板的状态
// 当该模板的状态变化时才会触发重新渲染
export function useTemplateLiked(templateId: string | undefined) {
return useTemplateSocialStore((state) =>
templateId ? state.likedMap[templateId] : undefined
)
}
export function useTemplateFavorited(templateId: string | undefined) {
return useTemplateSocialStore((state) =>
templateId ? state.favoritedMap[templateId] : undefined
)
}
export function useTemplateLikeCount(templateId: string | undefined) {
return useTemplateSocialStore((state) =>
templateId ? state.likeCountMap[templateId] : undefined
)
}