1. Fix collect function;
2. Show single duration;
mack-mac
mackt 8 months ago
parent 065b894e56
commit b433662dba

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="#C43737" xmlns="http://www.w3.org/2000/svg">
<path d="M20.5 12C20.5034 13.3199 20.195 14.6219 19.6 15.8C18.8944 17.2117 17.8097 18.3992 16.4674 19.2293C15.1251 20.0594 13.5782 20.4994 12 20.5C10.6801 20.5034 9.37812 20.195 8.20001 19.6L4.10714 19.8929L4.40003 15.8C3.80496 14.6219 3.49659 13.3199 3.50003 12C3.50064 10.4218 3.94064 8.87486 4.77074 7.53257C5.60085 6.19027 6.78827 5.10559 8.20001 4.40003C9.37812 3.80496 10.6801 3.49659 12 3.50003H12.5C14.5843 3.61502 16.553 4.49479 18.0291 5.97088C19.5052 7.44697 20.385 9.41566 20.5 11.5V12Z" stroke="#C43737" stroke-opacity="1" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 710 B

@ -2,7 +2,7 @@
import Link from 'next/link'; import Link from 'next/link';
import { notFound } from 'next/navigation'; import { notFound } from 'next/navigation';
import { JournalCard, SongCardList, JournalRecommendList, Comment, Collect } from '@/components'; import { JournalCard, SongCardList, JournalRecommendList, Comment, ButtonCollect } from '@/components';
import { apiGetJournalInfoById, apiGetSongsByJournalNo, apiGetJournalRecommendById } from '@/services'; import { apiGetJournalInfoById, apiGetSongsByJournalNo, apiGetJournalRecommendById } from '@/services';
export async function generateMetadata({ params: { journalId } }: { params: { journalId: string } }) { export async function generateMetadata({ params: { journalId } }: { params: { journalId: string } }) {
@ -57,11 +57,15 @@ export default async function JournalDetail({ params: { journalId } }: { params:
</div> </div>
</div> </div>
{/* 收藏 */} {/* 收藏 */}
<Collect <ButtonCollect
showText
journalId={journalInfo.id}
active={journalInfo.haveCollect} active={journalInfo.haveCollect}
text={journalInfo.userCollectCount ? `${journalInfo.userCollectCount}人收藏` : ''} count={journalInfo.userCollectCount}
id={journalInfo.id} text="人收藏"
type="1" collectType="1"
iconPosition="right"
gap={9}
/> />
</div> </div>
{/* 内容 */} {/* 内容 */}

@ -0,0 +1,90 @@
/** 收藏期刊按钮 */
'use client';
import { useEffect, useState } from 'react';
import { apiCollect } from '@/services';
interface Props {
/** 是否显示文案 */
showText?: boolean;
journalId: string;
active: boolean;
count?: number;
text?: string;
/** 收藏类型 0:歌曲1:期刊2:关注3:黑名单 */
collectType: CollectType;
iconPosition?: 'left' | 'right';
className?: string;
textClassName?: string;
/** 文字跟图标之间的间隔 单位px */
gap?: number;
}
export default function ButtonCollect({
journalId,
active,
count = 0,
text = '',
collectType,
iconPosition = 'left',
gap = 9,
className = '',
textClassName = '',
showText = false,
}: Props) {
const [state, setState] = useState<boolean>(false); // 收藏状态
const [hover, setHover] = useState<boolean>(false);
const [currentCount, setCurrentCount] = useState<number>(0);
// 收藏/取消收藏
const handleCollect = async () => {
setState(!state); // 更新收藏状态
setCurrentCount((currentCount) => currentCount + (state ? -1 : 1)); // 如果当前为收藏状态,-1否则+1
const res = await apiCollect({ isAdd: !state, objectId: journalId, collectType });
// 如果请求失败,回退状态
if (res.code !== 200) {
setState(!state);
setCurrentCount((currentCount) => currentCount + (state ? 1 : -1));
}
};
useEffect(() => {
setState(active);
}, [active]);
useEffect(() => {
setCurrentCount(count);
}, []);
const Icon = () => {
return (
<div
className={`w-[24px] h-[24px] ${hover || state ? 'bg-[url(/img/icon/love-active.svg)]' : 'bg-[url(/img/icon/love.svg)]'}`}
/>
);
};
return (
<div
className={`flex flex-row items-center gap-[${gap}px] cursor-pointer ${className}`}
onClick={handleCollect}
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
>
{iconPosition === 'left' && <Icon />}
{/* 文案 */}
{!!(showText && currentCount) && (
<p
className={`${hover || state ? 'text-brand' : 'text-[rgba(0,0,0,0.4)]'} text-[13px] leading-[18.2px] ${textClassName}`}
>
{`${currentCount || ''}${text || ''}`}
</p>
)}
{/* 图标 */}
{iconPosition === 'right' && <Icon />}
</div>
);
}

@ -1,42 +0,0 @@
// 期刊收藏
'use client';
import { useEffect, useState } from 'react';
import { apiCollect } from '@/services';
interface Props {
active: boolean;
id: string;
type: string;
size?: number;
text?: string;
}
export default function Collect({ active, id, type, size = 24, text = '' }: Props) {
const [state, setState] = useState<boolean>(false); // 收藏状态
useEffect(() => {
setState(active);
}, [active]);
// 收藏/取消收藏
const handleCollect = async () => {
setState(!state); // 更新收藏状态
const res = await apiCollect({ isAdd: !state, objectId: id, collectType: type });
if (res.code !== 200) setState(!state); // 如果请求失败,回退状态
};
return (
<div className="flex flex-row items-center gap-[9px] cursor-pointer group" onClick={handleCollect}>
{/* 文案 */}
{!!text && <p className="text-[rgba(0,0,0,0.4)] text-[13px] leading-[18.2px] group-hover:text-brand">{text}</p>}
{/* 图标 */}
<div
className={`w-[${size}px] h-[${size}px] ${state ? 'bg-[url(/img/icon/love-active.svg)]' : 'bg-[url(/img/icon/love.svg)]'} group-hover:bg-[url(/img/icon/love-active.svg)]`}
/>
</div>
);
}

@ -74,7 +74,7 @@ export default function Comment({ journalId, className, totalCommentReply, total
}, [handleLoadMore]); }, [handleLoadMore]);
return ( return (
<div className={className}> <div className={className} id="comment">
<CommentForm onSubmit={handleSubmit} /> <CommentForm onSubmit={handleSubmit} />
{!!totalCommentReply && ( {!!totalCommentReply && (
<> <>

@ -1,16 +1,16 @@
import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import { Avatar, JournalCard } from '@/components'; import { Avatar, JournalCard, ButtonCollect } from '@/components';
export default function JournalItem({ export default function JournalItem({
journalNo, journalNo,
id,
title, title,
image, image,
summary, summary,
commentList,
haveCollect, haveCollect,
totalCommentReply, totalCommentReply,
commentList,
userCollectCount, userCollectCount,
}: JournalInfo) { }: JournalInfo) {
return ( return (
@ -39,22 +39,27 @@ export default function JournalItem({
</div> </div>
)} )}
{/* 评论 & 收藏 */}
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
<Image width={24} height={24} src={'/img/icon/comment.svg'} alt="comment" unoptimized /> {/* 评论 */}
<p className="w-[42px] ml-[6px] mr-[24px] text-[14px] leading-[16px] text-[rgba(0,0,0,0.4) cursor-pointer hover:text-brand"> <Link className="flex flex-row items-center group" href={`/vol/${journalNo}#comment`}>
{totalCommentReply} <div
</p> className={`w-[24px] h-[24px] bg-[url(/img/icon/comment.svg)] group-hover:bg-[url(/img/icon/comment-active.svg)]`}
<Image />
width={24} <p className="w-[42px] ml-[6px] mr-[24px] text-[14px] leading-[16px] text-[rgba(0,0,0,0.4)] group-hover:text-brand">
height={24} {totalCommentReply}
src={haveCollect ? '/img/icon/love-active.svg' : '/img/icon/love.svg'} </p>
alt="love" </Link>
unoptimized {/* 收藏 */}
<ButtonCollect
showText
iconPosition="left"
journalId={id}
active={haveCollect}
count={userCollectCount}
collectType="1"
gap={6}
textClassName="w-[42px] ml-[6px] mr-[24px] text-[14px] leading-[16px]"
/> />
<p className="ml-[6px] text-[14px] leading-[16px] text-[rgba(0,0,0,0.4) cursor-pointer hover:text-brand">
{userCollectCount}
</p>
</div> </div>
</div> </div>
); );

@ -1,11 +1,14 @@
import Image from 'next/image'; import Image from 'next/image';
import { ButtonCollect } from '@/components';
export default function JournalItem({ export default function JournalItem({
id, id,
title, title,
pic, pic,
artist, artist,
haveCollect, haveCollect,
duration,
onPlay, onPlay,
}: SongInfo & { onPlay: (id: string) => void }) { }: SongInfo & { onPlay: (id: string) => void }) {
return ( return (
@ -32,14 +35,13 @@ export default function JournalItem({
className="w-[24px] h-[24px] overflow-hidden" className="w-[24px] h-[24px] overflow-hidden"
/> />
<p className="ml-[30px] mr-[13px] text-[12px] leading-[16.8px] text-[rgba(0,0,0,0.4)]">05:09</p> <p className="ml-[30px] mr-[13px] text-[12px] leading-[16.8px] text-[rgba(0,0,0,0.4)]">{duration || '00:00'}</p>
<Image <ButtonCollect
width={24} journalId={id}
height={24} active={haveCollect}
src={haveCollect ? '/img/icon/love-active.svg' : '/img/icon/love.svg'} collectType="0"
alt={title} textClassName="w-[42px] ml-[6px] mr-[24px] text-[14px] leading-[16px]"
className="w-[24px] h-[24px] overflow-hidden"
/> />
</div> </div>
</div> </div>

@ -22,6 +22,7 @@ export { default as Input } from './common/Input';
export { default as Button } from './common/Button'; export { default as Button } from './common/Button';
export { default as AutoScrollContainer } from './common/AutoScrollContainer'; export { default as AutoScrollContainer } from './common/AutoScrollContainer';
export { default as Avatar } from './Avatar'; export { default as Avatar } from './Avatar';
export { default as ButtonCollect } from './ButtonCollect';
// Audio Player // Audio Player
export { default as PlayerBar } from './AudioPlayer/PlayerBar'; export { default as PlayerBar } from './AudioPlayer/PlayerBar';
@ -37,5 +38,4 @@ export { default as CommentHeader } from './Comment/CommentHeader';
export { default as CommentForm } from './Comment/CommentForm'; export { default as CommentForm } from './Comment/CommentForm';
export { default as CommentItem } from './Comment/CommentItem'; export { default as CommentItem } from './Comment/CommentItem';
export { default as CommentList } from './Comment/CommentList'; export { default as CommentList } from './Comment/CommentList';
export { default as Collect } from './Collect';
export { default as Thumb } from './Thumb'; export { default as Thumb } from './Thumb';

@ -5,7 +5,7 @@ import clientHttp from '@/utils/request/client';
* @objectId ///id * @objectId ///id
* @collectType 0:1:2:3: * @collectType 0:1:2:3:
*/ */
export const apiCollectAdd = async (params: { objectId: string; collectType: string }) => { export const apiCollectAdd = async (params: { objectId: string; collectType: CollectType }) => {
const result: FetchResponse<string> = await clientHttp.post('/queyueapi/user/collect', params); const result: FetchResponse<string> = await clientHttp.post('/queyueapi/user/collect', params);
return result; return result;
}; };
@ -15,7 +15,7 @@ export const apiCollectAdd = async (params: { objectId: string; collectType: str
* @objectId ///id * @objectId ///id
* @collectType 0:1:2:3: * @collectType 0:1:2:3:
*/ */
export const apiCollectRemove = async ({ objectId, collectType }: { objectId: string; collectType: string }) => { export const apiCollectRemove = async ({ objectId, collectType }: { objectId: string; collectType: CollectType }) => {
const result: FetchResponse<string> = await clientHttp.delete( const result: FetchResponse<string> = await clientHttp.delete(
`/queyueapi/user/collect?objectId=${objectId}&collectType=${collectType}`, `/queyueapi/user/collect?objectId=${objectId}&collectType=${collectType}`,
); );
@ -35,7 +35,7 @@ export const apiCollect = async ({
}: { }: {
isAdd: boolean; isAdd: boolean;
objectId: string; objectId: string;
collectType: string; collectType: CollectType;
}) => { }) => {
if (isAdd) { if (isAdd) {
return await apiCollectAdd({ objectId, collectType }); return await apiCollectAdd({ objectId, collectType });

@ -51,6 +51,8 @@ declare interface SongInfo {
pic: string; pic: string;
/** 歌曲链接 */ /** 歌曲链接 */
src: string; src: string;
/** 歌曲时长 */
duration: string;
} }
/** /**
@ -174,3 +176,8 @@ interface Comment {
/** 徽章列表 */ /** 徽章列表 */
badgeList: number[]; badgeList: number[];
} }
/**
* 0:1:2:3:
*/
type CollectType = '0' | '1' | '2' | '3';

Loading…
Cancel
Save