Skip to content

Commit

Permalink
feat: perf ad、recommend
Browse files Browse the repository at this point in the history
  • Loading branch information
521xueweihan committed Jun 13, 2024
1 parent da32bc6 commit e98abb8
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 140 deletions.
171 changes: 89 additions & 82 deletions src/components/side/Ad.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,30 @@ interface Props {
className?: string;
}

export default function Ad(props: Props) {
interface RewardAdContentProps {
data: AdvertItem;
}

interface ImageAdContentProps {
data: AdvertItem;
handleClose: MouseEventHandler<HTMLDivElement>;
}

const ImageAdContent = ({ data, handleClose }: ImageAdContentProps) => (
<div className='group relative h-full'>
<img className='h-full w-full' src={data.image_url} alt='ad' />
<div
className='absolute top-0 right-0 hidden cursor-pointer p-1.5 text-inherit opacity-30 group-hover:block'
onClick={handleClose}
>
<VscClose size={20} />
</div>
</div>
);

export default function Ad({ data, className }: Props) {
const [visible, setVisible] = useState(true);

const handleClose: MouseEventHandler<HTMLDivElement> = (e) => {
e.preventDefault();
setVisible(false);
Expand All @@ -22,95 +44,80 @@ export default function Ad(props: Props) {
redirectRecord('', aid, 'ad');
};

if (!visible) return null;

const ProgressBar = ({ percent }: { percent: number }) => (
<div className='flex h-1 w-full overflow-hidden rounded-full bg-gray-200 dark:bg-gray-700'>
<div
className='flex flex-col justify-center overflow-hidden bg-blue-500'
style={{ width: `${percent}%` }}
/>
</div>
);

const AdTargetInfo = ({ data }: { data: AdvertItem }) => (
<div className='mt-1.5 mb-1 text-xs text-gray-500'>
<span>
{data.year ? '距离下个目标还差' : '距离目标还差'}
<strong className='mx-1'>{100 - data.percent}%</strong>
</span>
<ProgressBar percent={data.percent} />
</div>
);

const AdServerInfo = ({ data }: { data: AdvertItem }) => (
<div className='mt-1.5 mb-1 text-xs text-gray-500'>
<span>
服务器还剩<strong className='mx-1'>{data.day}</strong>
</span>
<div className='relative left-0.5 bottom-1 inline-flex w-fit'>
<span className='text-xs font-medium text-blue-500'>
<span className='mr-[0.5px]'>+{data.year}</span>
</span>
</div>
<ProgressBar percent={data.percent} />
</div>
);

const RewardAdDetail = ({ data }: { data: AdvertItem }) => (
<>
<div className='group-hover:hidden'>
<AdServerInfo data={data} />
</div>
<div className='hidden group-hover:block'>
<AdTargetInfo data={data} />
</div>
</>
);

const RewardAdContent = ({ data }: RewardAdContentProps) => (
<div className='group flex flex-row p-3'>
<img className='h-[55px] w-[55px]' src={data.image_url} alt='ad' />
<div className='ml-3'>
<div className='font-medium tracking-wider md:text-sm lg:w-[135px] lg:truncate lg:whitespace-nowrap lg:text-base'>
微信扫码赞助本站
</div>
<div className='hidden lg:block'>
<RewardAdDetail data={data} />
</div>
</div>
</div>
);

return (
<div
className={`${props.className} relative h-20 overflow-hidden rounded-lg bg-white dark:bg-gray-800`}
hidden={!visible}
className={`relative h-20 overflow-hidden rounded-lg bg-white dark:bg-gray-800 ${className}`}
>
<Link href={props.data.url}>
<Link href={data.url}>
<a
target='_blank'
onClick={() => onClickLink(props.data.aid)}
onClick={() => onClickLink(data.aid)}
rel='noreferrer'
>
{props.data.is_reward ? (
<div className='group flex flex-row p-3'>
<img
className='h-[55px] w-[55px]'
src={props.data.image_url}
alt='ad'
/>
<div className='ml-3'>
<div className='font-medium tracking-wider md:text-sm lg:w-[135px] lg:truncate lg:whitespace-nowrap lg:text-base'>
微信扫码赞助本站
</div>
<div className='hidden lg:block'>
<div className='group-hover:hidden'>
<div className='mt-1.5 mb-1 text-xs text-gray-500'>
<span>
服务器还剩
<strong className='mx-1'>{props.data.day}</strong>
</span>
<div className='relative left-0.5 bottom-1 inline-flex w-fit'>
<span className='text-xs font-medium text-blue-500 '>
<span className='mr-[0.5px]'>+{props.data.year}</span>
</span>
</div>
</div>
<div className='flex h-1 w-full overflow-hidden rounded-full bg-gray-200 dark:bg-gray-700'>
<div
className='flex flex-col justify-center overflow-hidden bg-blue-500'
style={{
width: `${props.data.percent}%`,
}}
/>
</div>
</div>
<div className='hidden group-hover:block'>
<div className='mt-1.5 mb-1 text-xs text-gray-500'>
{props.data.year ? (
<span>
距离下个目标还差
<strong className='mx-1'>
{100 - props.data.percent}%
</strong>
</span>
) : (
<span>
距离目标还差
<strong className='mx-1'>
{100 - props.data.percent}%
</strong>
</span>
)}
</div>
<div className='flex h-1 w-full overflow-hidden rounded-full bg-gray-200 dark:bg-gray-700'>
<div
className='flex flex-col justify-center overflow-hidden bg-blue-500'
style={{
width: `${props.data.percent}%`,
}}
/>
</div>
</div>
</div>
</div>
</div>
{data.is_reward ? (
<RewardAdContent data={data} />
) : (
<div className='group relative h-full'>
<img
className='h-full w-full'
src={props.data.image_url}
alt='ad'
/>
<div
className='absolute top-0 right-0 hidden cursor-pointer p-1.5 text-inherit opacity-30 group-hover:block'
onClick={handleClose}
>
<VscClose size={20} />
</div>
</div>
<ImageAdContent data={data} handleClose={handleClose} />
)}
</a>
</Link>
Expand Down
106 changes: 53 additions & 53 deletions src/components/side/Recommend.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,77 @@
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useEffect, useMemo, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { AiOutlineStar } from 'react-icons/ai';
import { MdRefresh } from 'react-icons/md';

import { getRecommend } from '@/services/home';

import { RecommendSkeleton } from '../loading/skeleton';

import { RecomemndItem } from '@/types/home';
import { RecommendItem } from '@/types/home';

const RecommendList = ({ repositories }: { repositories: RecommendItem[] }) => (
<div className='dark:text-gray-300'>
{repositories.map((item) => (
<Link prefetch={false} href={`/repository/${item.rid}/`} key={item.rid}>
<div className='flex cursor-pointer flex-row rounded-md py-2 hover:bg-gray-50 hover:text-blue-400 dark:text-gray-200 dark:hover:bg-gray-700 dark:hover:text-blue-400'>
<div className='flex w-full items-center px-1'>
<img
className='w-10 rounded-full border border-gray-100 dark:border-gray-900'
src={item.author_avatar}
width='40'
height='40'
alt='repo_avatar'
/>
<div className='flex w-4/5 flex-col pl-2'>
<div className='truncate text-ellipsis text-sm capitalize'>
{item.full_name}
</div>
<div className='flex flex-row pt-1 text-xs text-gray-400'>
<div className='flex items-center pr-4'>
<AiOutlineStar size={14} />
<span className='pl-0.5'>{item.stars_str}</span>
</div>
<div className='truncate text-ellipsis'>
<span
style={{ backgroundColor: `${item.lang_color}` }}
className='relative box-border inline-block h-3 w-3 rounded-full border border-gray-100 align-[-1.5px] dark:border-gray-600'
></span>
<span className='whitespace-nowrap pl-0.5'>
{item.primary_lang}
</span>
</div>
</div>
</div>
</div>
</div>
</Link>
))}
</div>
);

const isLicenseDetailPath = (pathname: string) => pathname === '/license/[lid]';

export default function Recommend() {
const router = useRouter();
const { pathname, query } = router;
const [repositories, setRepositories] = useState<RecomemndItem[]>([]);

const isLicenseDetail = useMemo(() => {
return pathname === '/license/[lid]';
}, [pathname]);
const [repositories, setRepositories] = useState<RecommendItem[]>([]);

const refreshRecommend = async () => {
const refreshRecommend = useCallback(async () => {
setRepositories([]);
const lid = query?.lid as string;
const res = await getRecommend(lid);
if (res?.success) {
setRepositories(res.data);
}
};
}, [query?.lid]);

useEffect(() => {
// path 变化就会刷新推荐项目列表
refreshRecommend();
}, [pathname]);
}, [pathname, refreshRecommend]);

const ShowIsLicenseDetail = isLicenseDetailPath(pathname);

return (
<>
Expand All @@ -48,53 +88,13 @@ export default function Recommend() {
<span className='pl-0.5'>换一换</span>
</div>
</div>
{repositories.length == 0 ? (
{repositories.length === 0 ? (
<RecommendSkeleton loop={3} />
) : (
<div className='dark:text-gray-300'>
{repositories.map((item) => (
<Link
prefetch={false}
href={`/repository/${item.rid}/`}
key={item.rid}
>
<div className='flex cursor-pointer flex-row rounded-md py-2 hover:bg-gray-50 hover:text-blue-400 dark:text-gray-200 dark:hover:bg-gray-700 dark:hover:text-blue-400'>
<div className='flex w-full items-center px-1'>
<img
className='w-10 rounded-full border border-gray-100 dark:border-gray-900'
src={item.author_avatar}
width='40'
height='40'
alt='repo_avatar'
/>
<div className='flex w-4/5 flex-col pl-2'>
<div className='truncate text-ellipsis text-sm capitalize'>
{item.full_name}
</div>
<div className='flex flex-row pt-1 text-xs text-gray-400 '>
<div className='flex items-center pr-4'>
<AiOutlineStar size={14} />
<span className='pl-0.5'>{item.stars_str}</span>
</div>
<div className='truncate text-ellipsis'>
<span
style={{ backgroundColor: `${item.lang_color}` }}
className='relative box-border inline-block h-3 w-3 rounded-full border border-gray-100 align-[-1.5px] dark:border-gray-600'
></span>
<span className='whitespace-nowrap pl-0.5'>
{item.primary_lang}
</span>
</div>
</div>
</div>
</div>
</div>
</Link>
))}
</div>
<RecommendList repositories={repositories} />
)}
</div>
{isLicenseDetail && (
{ShowIsLicenseDetail && (
<div className='space-y-1.5 rounded-lg bg-white px-4 pt-3 pb-2 text-sm dark:bg-gray-800'>
内容整理自 spdx 和 GitHub 网站,并遵循
<a
Expand Down
4 changes: 2 additions & 2 deletions src/services/home.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { makeUrl } from '@/utils/api';

import { fetcher } from './base';

import { HomeItem, HomeItems, RecomemndItems, Stats } from '@/types/home';
import { HomeItem, HomeItems, RecommendItems, Stats } from '@/types/home';
import { TagItems } from '@/types/tag';

export const getItems = async (
Expand All @@ -25,7 +25,7 @@ export const getRecommend = async (lid?: string): Promise<any> => {
if (lid) {
url = `/repository/recommend/?lid=${lid}`;
}
const data = await fetcher<RecomemndItems>(makeUrl(url));
const data = await fetcher<RecommendItems>(makeUrl(url));
return data;
} catch (error) {
console.error(error);
Expand Down
6 changes: 3 additions & 3 deletions src/types/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export interface Stats {
user_total: number;
}

export interface RecomemndItem {
export interface RecommendItem {
rid: string;
name: string;
full_name: string;
Expand All @@ -46,10 +46,10 @@ export interface RecomemndItem {
stars_str: string;
}

export interface RecomemndItems {
export interface RecommendItems {
success: boolean;
total: number;
data: RecomemndItem[];
data: RecommendItem[];
}

export interface AdvertItem {
Expand Down

0 comments on commit e98abb8

Please sign in to comment.