119 lines
2.9 KiB
TypeScript
119 lines
2.9 KiB
TypeScript
import React, { useEffect, useState } from 'react'
|
|
import { search as SearchRepository } from '../api/repository'
|
|
import RepopositoryItem from './RepositoryItem'
|
|
import { RepositorySearchResultItem } from '../api/api'
|
|
import classes from './style/RepositoryList.module.css'
|
|
import { RepositorySearchCache } from '../utils/cache/RepositorySearch'
|
|
|
|
interface RepositoryListProps {
|
|
|
|
/** 搜索关键词 */
|
|
keyword:string
|
|
|
|
/** 最多允许缓存多少页 */
|
|
max_cache_page:number
|
|
}
|
|
|
|
/**
|
|
* 默认每一页多少条记录
|
|
* https://docs.github.com/en/rest/reference/repos
|
|
*/
|
|
const DEFAULT_PER_PAGE = 30
|
|
|
|
export default function RepositoryList (props:RepositoryListProps) {
|
|
const cache = RepositorySearchCache(props.keyword, props.max_cache_page)
|
|
|
|
/** 当前页 */
|
|
const [current_page, setCurrentPage] = useState(1)
|
|
|
|
/** 总页码 */
|
|
const [total_page, setTotalPage] = useState(0)
|
|
|
|
/** 接口加载中 */
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
const [list, setList] = useState<RepositorySearchResultItem[]>([])
|
|
|
|
/**
|
|
* 调用搜索接口
|
|
* @param {number} page 页码
|
|
* @returns {Promise<void>}
|
|
*/
|
|
async function search (page:number):Promise<void> {
|
|
setLoading(true)
|
|
|
|
const cache_list = cache.read(page)
|
|
|
|
let _total_page = 0
|
|
|
|
// 有缓存
|
|
if (cache_list) {
|
|
setList(cache_list)
|
|
_total_page = cache.getTotalPage()
|
|
} else {
|
|
// 没有缓存,调用接口
|
|
try {
|
|
/* eslint-disable */
|
|
var result = await SearchRepository(props.keyword, page)
|
|
|
|
} catch (err) {
|
|
console.log('fetch',err);
|
|
alert(err.message)
|
|
setLoading(false)
|
|
return
|
|
}
|
|
|
|
_total_page = Math.ceil(result.total_count / DEFAULT_PER_PAGE)
|
|
|
|
setList(result.items)
|
|
|
|
cache.add(page,result.items)
|
|
cache.updateTotalPage(_total_page)
|
|
}
|
|
|
|
setTotalPage(_total_page)
|
|
|
|
setCurrentPage(page)
|
|
|
|
setLoading(false)
|
|
|
|
}
|
|
|
|
useEffect(() => {
|
|
search(1)
|
|
}, [])
|
|
|
|
function onClickPrev(){
|
|
search(current_page-1)
|
|
}
|
|
|
|
function onClickNext(){
|
|
search(current_page+1)
|
|
}
|
|
|
|
return (
|
|
<div className={classes.wrapper}>
|
|
<div className={classes['list-wrapper']}>
|
|
<ul className={classes.list}>
|
|
{
|
|
list.map(item => <RepopositoryItem key={item.id} name={item.name} star_count={item.stargazers_count} fork_count={item.forks_count} />)
|
|
}
|
|
</ul>
|
|
{
|
|
list.length===0 && <span>暂无数据</span>
|
|
}
|
|
{
|
|
loading && <div className={classes.loading}></div>
|
|
}
|
|
</div>
|
|
|
|
<div className="action-bar">
|
|
<button disabled={loading || current_page<=1} onClick={onClickPrev}>上一页</button>
|
|
<button disabled={loading || current_page>=total_page} onClick={onClickNext}>下一页</button>
|
|
<span> {current_page} / {total_page}</span>
|
|
</div>
|
|
|
|
</div>
|
|
)
|
|
}
|