feat: 联调点赞功能
This commit is contained in:
parent
3ed5f603c4
commit
e6b28751bd
|
|
@ -5,7 +5,7 @@ import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
|||
import { IconButton } from '@/components/ui/button';
|
||||
import Link from 'next/link';
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
import LikedIcon from '@/components/features/LikedIcon';
|
||||
import LikedButton from '@/components/features/LikeButton';
|
||||
import { LikeTargetType } from '@/services/editor/type';
|
||||
|
||||
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
|
||||
|
|
@ -20,11 +20,7 @@ export default async function Page({ params }: { params: Promise<{ id: string }>
|
|||
<Link href="/home">
|
||||
<IconButton variant="ghost" size="large" iconfont="icon-arrow-left" />
|
||||
</Link>
|
||||
<LikedIcon
|
||||
iconProps={{ size: 'large' }}
|
||||
objectId={id}
|
||||
objectType={LikeTargetType.Character}
|
||||
/>
|
||||
<LikedButton size="large" objectId={id} objectType={LikeTargetType.Character} />
|
||||
</div>
|
||||
{/* 内容区 */}
|
||||
<div className="mx-auto flex-1 overflow-auto pb-4 w-full">
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import IconFont from '@/components/ui/iconFont';
|
|||
import MaskCreate from './MaskCreate';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useParams } from 'next/navigation';
|
||||
import LikedIcon from '@/components/features/LikedIcon';
|
||||
import LikedButton from '@/components/features/LikeButton';
|
||||
import { LikeTargetType } from '@/services/editor/type';
|
||||
|
||||
type SettingProps = {
|
||||
|
|
@ -71,7 +71,7 @@ export default function SettingDialog({ open, onOpenChange }: SettingProps) {
|
|||
<AlertDialogContent className="max-w-[500px]" showCloseButton={activeTab === 'profile'}>
|
||||
<AlertDialogTitle className="flex justify-between">
|
||||
{activeTab === 'profile' ? (
|
||||
<LikedIcon objectId={characterId} objectType={LikeTargetType.Character} />
|
||||
<LikedButton objectId={characterId} objectType={LikeTargetType.Character} />
|
||||
) : (
|
||||
titleMap[activeTab]
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -4,29 +4,31 @@ import { LikeTargetType, LikeType } from '@/services/editor/type';
|
|||
import { IconButton } from '../ui/button';
|
||||
import { useThmubObject } from '@/hooks/services/common';
|
||||
import React from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
type LikedIconProps = {
|
||||
objectId: string;
|
||||
objectType: LikeTargetType;
|
||||
iconProps?: React.ComponentProps<typeof IconButton>;
|
||||
};
|
||||
} & React.ComponentProps<typeof IconButton>;
|
||||
|
||||
const LikedIcon = React.memo((props: LikedIconProps) => {
|
||||
const { objectId, objectType, iconProps } = props;
|
||||
const LikedButton = React.memo((props: LikedIconProps) => {
|
||||
const { objectId, objectType, ...iconProps } = props;
|
||||
const { thumb, handleThumb, loading } = useThmubObject({ objectId, objectType });
|
||||
const isLiked = thumb === LikeType.Liked;
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
variant="tertiary"
|
||||
size="small"
|
||||
{...iconProps}
|
||||
iconfont={thumb === LikeType.Liked ? 'icon-Like-fill' : 'icon-Like'}
|
||||
iconfont={isLiked ? 'icon-Like-fill' : 'icon-Like'}
|
||||
className={cn(iconProps?.className, isLiked && 'text-red-500')}
|
||||
onClick={() => {
|
||||
if (loading) return;
|
||||
handleThumb(thumb === LikeType.Liked ? LikeType.Canceled : LikeType.Liked);
|
||||
handleThumb(isLiked ? LikeType.Canceled : LikeType.Liked);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export default LikedIcon;
|
||||
export default LikedButton;
|
||||
|
|
@ -1,30 +1,35 @@
|
|||
import { getLikeStatus, thmubObject } from '@/services/editor';
|
||||
import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { authKeys } from '@/lib/query-keys';
|
||||
import { LikeObjectParamsType, LikeType } from '@/services/editor/type';
|
||||
import { useAsyncFn } from '../tools';
|
||||
import { useCurrentUser } from '../auth';
|
||||
|
||||
export function useThmubObject(props: Pick<LikeObjectParamsType, 'objectId' | 'objectType'>) {
|
||||
const queryClient = useQueryClient();
|
||||
const [thumb, setThumb] = useState<LikeType>();
|
||||
const user = queryClient.getQueryData(authKeys.currentUser()) as any;
|
||||
const { data: user } = useCurrentUser();
|
||||
|
||||
useQuery({
|
||||
queryKey: ['likeStatus', props.objectId, user.userId],
|
||||
enabled: !!props.objectId && !!user.userId,
|
||||
queryFn: () => {
|
||||
return getLikeStatus({ objectId: props.objectId, userId: user.userId });
|
||||
const { data: likeStatus, refetch: refetchLikeStatus } = useQuery({
|
||||
queryKey: ['likeStatus', props.objectId, user?.userId],
|
||||
enabled: !!props.objectId && !!user?.userId,
|
||||
queryFn: async () => {
|
||||
const { data } = await getLikeStatus({ objectId: props.objectId, userId: user?.userId });
|
||||
return data.likeStatus;
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof likeStatus === 'number') {
|
||||
setThumb(likeStatus);
|
||||
}
|
||||
}, [likeStatus]);
|
||||
|
||||
const { run: handleThumb, loading } = useAsyncFn(async (likeType: LikeType) => {
|
||||
setThumb(likeType);
|
||||
const user = queryClient.getQueryData(authKeys.currentUser()) as any;
|
||||
const { data } = await thmubObject({ ...props, likeType, userId: user?.userId });
|
||||
if (data.code === 200) {
|
||||
} else {
|
||||
setThumb(undefined);
|
||||
const { code } = await thmubObject({ ...props, likeType, userId: user?.userId });
|
||||
if (code === 200) {
|
||||
refetchLikeStatus();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,5 @@ export async function thmubObject(params: LikeObjectParamsType) {
|
|||
}
|
||||
|
||||
export async function getLikeStatus(params: Pick<LikeObjectParamsType, 'objectId' | 'userId'>) {
|
||||
const { data } = await editorRequest('/api/like/getLikeStatus', { method: 'POST', data: params });
|
||||
return data;
|
||||
return editorRequest('/api/like/getLikeStatus', { method: 'POST', data: params });
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue