chore: add cancel query model
This commit is contained in:
@@ -1,20 +1,51 @@
|
||||
import HighlightCode from '@/components/highlight-code';
|
||||
import IconFont from '@/components/icon-font';
|
||||
import { downloadFile } from '@huggingface/hub';
|
||||
import { Button, Empty, Tag } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { queryHuggingfaceModelDetail } from '../apis';
|
||||
import useRequestToken from '@/hooks/use-request-token';
|
||||
import {
|
||||
DownOutlined,
|
||||
FileTextOutlined,
|
||||
RightOutlined
|
||||
} from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Empty, Tag, Tooltip } from 'antd';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import SimpleBar from 'simplebar-react';
|
||||
import 'simplebar-react/dist/simplebar.min.css';
|
||||
import { downloadModelFile, queryHuggingfaceModelDetail } from '../apis';
|
||||
import '../style/model-card.less';
|
||||
import TitleWrapper from './title-wrapper';
|
||||
|
||||
const ModelCard: React.FC<{ repo: string }> = (props) => {
|
||||
const { repo } = props;
|
||||
const ModelCard: React.FC<{
|
||||
repo: string;
|
||||
onCollapse: (flag: boolean) => void;
|
||||
collapsed: boolean;
|
||||
}> = (props) => {
|
||||
const { repo, onCollapse, collapsed } = props;
|
||||
const intl = useIntl();
|
||||
const requestSource = useRequestToken();
|
||||
const [modelData, setModelData] = useState<any>({});
|
||||
const [readmeText, setReadmeText] = useState<string | null>(null);
|
||||
const requestToken = useRef<any>(null);
|
||||
const axiosTokenRef = useRef<any>(null);
|
||||
|
||||
const loadFile = async (repo: string, sha: string) => {
|
||||
const res = await (
|
||||
await downloadFile({ repo, revision: sha, path: 'README.md' })
|
||||
)?.text();
|
||||
return res;
|
||||
try {
|
||||
axiosTokenRef.current?.abort?.();
|
||||
axiosTokenRef.current = new AbortController();
|
||||
const res = await downloadModelFile(
|
||||
{
|
||||
repo,
|
||||
revision: sha,
|
||||
path: 'README.md'
|
||||
},
|
||||
{
|
||||
signal: axiosTokenRef.current.signal
|
||||
}
|
||||
);
|
||||
return res || '';
|
||||
} catch (error) {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const getModelCardData = async () => {
|
||||
@@ -22,42 +53,110 @@ const ModelCard: React.FC<{ repo: string }> = (props) => {
|
||||
setModelData(null);
|
||||
return;
|
||||
}
|
||||
requestToken.current?.cancel?.();
|
||||
requestToken.current = requestSource();
|
||||
try {
|
||||
const res = await queryHuggingfaceModelDetail({ repo });
|
||||
const [modelcard, readme] = await Promise.all([
|
||||
queryHuggingfaceModelDetail(
|
||||
{ repo },
|
||||
{
|
||||
token: requestToken.current.token
|
||||
}
|
||||
),
|
||||
loadFile(repo, 'main')
|
||||
]);
|
||||
|
||||
setModelData(res);
|
||||
setModelData(modelcard);
|
||||
setReadmeText(readme);
|
||||
} catch (error) {
|
||||
setModelData({});
|
||||
}
|
||||
};
|
||||
|
||||
const handleCollapse = useCallback(() => {
|
||||
onCollapse(!collapsed);
|
||||
}, [collapsed]);
|
||||
|
||||
useEffect(() => {
|
||||
getModelCardData();
|
||||
}, [repo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!readmeText) {
|
||||
onCollapse(false);
|
||||
}
|
||||
}, [readmeText]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
requestToken.current?.cancel?.();
|
||||
axiosTokenRef.current?.abort?.();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TitleWrapper>
|
||||
<span>Model Card</span>
|
||||
<span>{intl.formatMessage({ id: 'models.data.card' })}</span>
|
||||
</TitleWrapper>
|
||||
<div className="wrapper">
|
||||
{modelData ? (
|
||||
<div className="model-card-wrap">
|
||||
<div className="title">{modelData.id}</div>
|
||||
<div className="flex-between flex-center">
|
||||
<Tag className="tag-item">
|
||||
<span className="m-r-5">Architecture:</span>
|
||||
{modelData.config?.model_type}
|
||||
</Tag>
|
||||
<Button
|
||||
type="link"
|
||||
target="_blank"
|
||||
href={`https://huggingface.co/${modelData.id}`}
|
||||
>
|
||||
View in Hugging Face
|
||||
<IconFont type="icon-external-link"></IconFont>
|
||||
</Button>
|
||||
<div className="title">
|
||||
{modelData.id}{' '}
|
||||
<Tooltip title={intl.formatMessage({ id: 'models.viewin.hf' })}>
|
||||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
target="_blank"
|
||||
href={`https://huggingface.co/${modelData.id}`}
|
||||
>
|
||||
<IconFont type="icon-external-link"></IconFont>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="flex-between flex-center">
|
||||
{modelData.config?.model_type && (
|
||||
<Tag className="tag-item" color="gold">
|
||||
<span style={{ opacity: 0.65 }}>
|
||||
<span className="m-r-5">
|
||||
{intl.formatMessage({ id: 'models.architecture' })}:
|
||||
</span>
|
||||
{modelData.config?.model_type}
|
||||
</span>
|
||||
</Tag>
|
||||
)}
|
||||
</div>
|
||||
{readmeText && (
|
||||
<div
|
||||
style={{
|
||||
borderRadius: 4,
|
||||
backgroundColor: '#282c34',
|
||||
marginTop: 16,
|
||||
overflow: 'hidden'
|
||||
}}
|
||||
>
|
||||
<span className="mkd-title" onClick={handleCollapse}>
|
||||
<span>
|
||||
<FileTextOutlined className="m-r-5" /> README.md
|
||||
</span>
|
||||
<span>
|
||||
{collapsed ? <DownOutlined /> : <RightOutlined />}
|
||||
</span>
|
||||
</span>
|
||||
<SimpleBar
|
||||
style={{
|
||||
maxHeight: collapsed ? 300 : 0
|
||||
}}
|
||||
>
|
||||
<HighlightCode
|
||||
code={readmeText}
|
||||
lang="markdown"
|
||||
copyable={false}
|
||||
></HighlightCode>
|
||||
</SimpleBar>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}></Empty>
|
||||
|
||||
Reference in New Issue
Block a user