feat: fetch siteData from remote (#27543)

This commit is contained in:
Kermit Xuan 2020-11-05 15:22:59 +08:00 committed by GitHub
parent edb39437f3
commit d862b688d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 125 deletions

View File

@ -1,61 +1,24 @@
import * as React from 'react';
import { Card, Row, Col } from 'antd';
import { useIntl } from 'react-intl';
import { Card, Row, Col, Spin } from 'antd';
import { useSiteData } from './util';
import './MorePage.less';
type SourceType = 'zhihu' | 'yuque';
type Icons = Record<SourceType, string>;
interface MoreProps {
title: string;
description: string;
date: string;
img: string;
source: 'zhihu' | 'yuque';
source: SourceType;
href: string;
icons?: Icons;
}
const SourceImages = {
zhihu: 'https://gw.alipayobjects.com/zos/basement_prod/5f4e1fd0-d255-4309-b181-a3715a720ebe.svg',
yuque: 'https://gw.alipayobjects.com/zos/basement_prod/53e7a5b8-c9f4-45a4-8378-cbf50f2dd0d0.svg',
};
const MORE_LIST: MoreProps[] = [
{
title: '智能组件探索:这个工具栏会自动布局',
description:
'工程师只需要选择「我要展示哪些元素、每个元素有多少」,而「这些元素怎么摆」、「间距是多少」等细节问题都会根据规则自动生成。',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*A_F0SL5shbEAAAAAAAAAAAAAARQnAQ',
date: '2020-08-19',
source: 'zhihu',
href: 'https://zhuanlan.zhihu.com/p/188693322',
},
{
title: '一个好用的智能栅格工具是如何诞生的?',
description:
'和大家分享一下整个智能栅格的设计开发过程,并从中感受到设计的「穿透力」,聊聊如何打破界限、从表面到内核、从表象到本质。',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*hk19TqWVSDsAAAAAAAAAAAAAARQnAQ',
date: '2020-08-09',
source: 'zhihu',
href: 'https://zhuanlan.zhihu.com/p/176534657',
},
{
title: '设计体系的响应式设计',
description:
'在蚂蚁内部有着数量繁多且复杂的中后台业务系统Ant Design 一直以来致力于从设计策略和资产的角度解决这些产品的体验一致性问题。',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*zk6CQphLepQAAAAAAAAAAAAAARQnAQ',
date: '2020-03-24',
source: 'zhihu',
href: 'https://zhuanlan.zhihu.com/p/109781992',
},
{
title: '我的按钮究竟该放哪儿!?',
description:
'按钮是一种使用广泛的基础界面元素,正因其使用的普遍性和重要性,我们需要并一直在探索建立按钮设计规范。',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*d595RpGKQ_IAAAAAAAAAAAAAARQnAQ',
date: '2020-02-29',
source: 'zhihu',
href: 'https://zhuanlan.zhihu.com/p/109644406',
},
];
const MoreCard = ({ title, description, date, img, source, href }: MoreProps) => {
const MoreCard = ({ title, description, date, img, source, href, icons }: MoreProps) => {
return (
<Col xs={24} sm={6}>
<a
@ -63,12 +26,10 @@ const MoreCard = ({ title, description, date, img, source, href }: MoreProps) =>
target="_blank"
rel="noopener noreferrer"
onClick={() => {
if (window.gtag) {
window.gtag('event', '点击', {
window?.gtag('event', '点击', {
event_category: '首页文章',
event_label: href,
});
}
}}
>
<Card hoverable cover={<img alt={title} src={img} />} className="more-card">
@ -76,7 +37,7 @@ const MoreCard = ({ title, description, date, img, source, href }: MoreProps) =>
<div>
{date}
<span className="more-card-source">
<img src={SourceImages[source]} alt={source} />
{icons ? <img src={icons[source]} alt={source} /> : <Spin />}
</span>
</div>
</Card>
@ -86,11 +47,13 @@ const MoreCard = ({ title, description, date, img, source, href }: MoreProps) =>
};
export default function MorePage() {
const { locale } = useIntl();
const isZhCN = locale === 'zh-CN';
const list = useSiteData<MoreProps[]>('extras', isZhCN ? 'cn' : 'en');
const icons = useSiteData<Icons>('icons');
return (
<Row gutter={[24, 32]}>
{MORE_LIST.map(more => (
<MoreCard key={more.title} {...more} />
))}
{list ? list.map(more => <MoreCard key={more.title} {...more} icons={icons} />) : <Spin />}
</Row>
);
}

View File

@ -1,7 +1,8 @@
import * as React from 'react';
import classNames from 'classnames';
import { FormattedMessage, useIntl } from 'react-intl';
import { Row, Col, Typography } from 'antd';
import { Row, Col, Typography, Spin } from 'antd';
import { useSiteData } from './util';
import './RecommendPage.less';
const { Title, Paragraph } = Typography;
@ -14,57 +15,8 @@ interface Recommend {
description: string;
}
const LIST_CN: Recommend[] = [
{
title: '新一代 Ant Design未来已来邀你共建',
description: '欢迎加入Ant Designers',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*yGcPRroihLQAAAAAAAAAAAAAARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/269789439',
popularize: true,
},
{
title: '在Ant Design 4.0里,我们如何追求快乐的工作?',
description: '蚂蚁集团高级体验设计专家林外在上海外滩大会上分享 Ant Design4.0 背后的设计理念',
img: 'https://gw.alipayobjects.com/mdn/rms_b56775/afts/img/A*psuyRqopCIEAAAAAAAAAAAAAARQnAQ',
href: 'https://mp.weixin.qq.com/s/QUqy1-g0FElqOs9cQFFWHA',
},
{
title: '第十五届 D2 前端技术论坛 - 无界',
description: '前端热爱,技术无界,第十五届 D2 前端技术论坛,我们云端相聚!',
img: 'https://img.alicdn.com/tfs/TB1R39KnSR26e4jSZFEXXbwuXXa-1960-768.png',
href: 'http://d2forum.alibaba-inc.com/',
},
];
const LIST_EN: Recommend[] = [
{
title: 'New generation of Ant Design, the future is coming, let us create it together!',
description:
'Welcome to join us, Ant Designers!',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*yGcPRroihLQAAAAAAAAAAAAAARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/269789439',
popularize: true,
},
{
title: 'How do we pursue happy work in Ant Design 4.0?',
description:
'Ant group senior experience design expert Lin Wai shares the design concept behind Ant Design 4.0',
img: 'https://gw.alipayobjects.com/mdn/rms_b56775/afts/img/A*psuyRqopCIEAAAAAAAAAAAAAARQnAQ',
href: 'https://mp.weixin.qq.com/s/QUqy1-g0FElqOs9cQFFWHA',
},
{
title: 'Stories about Ant Design 4.0: VirtualList',
description:
"🏃 In React, usually you don't need to focus on performance problems. However, as a component library, we have to think about it.",
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*ULOBQroFRMQAAAAAAAAAAAAAARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/237996796',
},
];
interface RecommendBlockProps extends Recommend {
main?: boolean;
img: string;
href: string;
}
const RecommendBlock = ({
@ -82,12 +34,10 @@ const RecommendBlock = ({
target="_blank"
rel="noopener noreferrer"
onClick={() => {
if (window.gtag) {
window.gtag('event', '点击', {
window?.gtag('event', '点击', {
event_category: '首页推广',
event_label: href,
});
}
}}
>
<img src={img} alt={title} />
@ -107,22 +57,28 @@ const RecommendBlock = ({
export default function RecommendPageo() {
const { locale } = useIntl();
const isZhCN = locale === 'zh-CN';
const LIST = isZhCN ? LIST_CN : LIST_EN;
const list = useSiteData<Recommend[]>('recommendations', isZhCN ? 'cn' : 'en');
return (
<Row gutter={[24, 24]} style={{ marginBottom: -36 }}>
{list ? (
<>
<Col xs={24} sm={14}>
<RecommendBlock {...LIST[0]} main />
<RecommendBlock {...list[0]} main />
</Col>
<Col xs={24} sm={10}>
<Row gutter={[24, 24]}>
<Col span={24}>
<RecommendBlock {...LIST[1]} />
<RecommendBlock {...list[1]} />
</Col>
<Col span={24}>
<RecommendBlock {...LIST[2]} />
<RecommendBlock {...list[2]} />
</Col>
</Row>
</Col>
</>
) : (
<Spin />
)}
</Row>
);
}

View File

@ -1,4 +1,5 @@
/* eslint-disable import/prefer-default-export */
import * as React from 'react';
export function preLoad(list: string[]) {
if (typeof window !== 'undefined') {
@ -13,3 +14,27 @@ export function preLoad(list: string[]) {
});
}
}
const siteData: Record<string, any> = {};
export function useSiteData<T>(endpoint: string, language?: 'cn' | 'en'): T {
const getData = () => {
const endpointData = siteData[endpoint];
if (!endpointData) return null;
return language ? endpointData[language] : endpointData;
};
const [data, setData] = React.useState<any>(getData());
React.useEffect(() => {
if (!data && typeof fetch !== 'undefined') {
fetch(`https://my-json-server.typicode.com/ant-design/website-data/${endpoint}`)
.then(res => res.json())
.then((res: any) => {
siteData[endpoint] = res;
setData(getData());
});
}
}, [endpoint]);
return data;
}