Files
some-stars/index.html
T
2025-09-08 21:56:40 +08:00

271 lines
8.6 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ZSCGR Star 导航</title>
<link href="https://fastly.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
<style>
/* 其他样式 */
body {
background-image: url('https://pic.chgr.cc/random?dir=cover&type=img');
background-size: 100% 100%;
background-position: center;
background-attachment: fixed;
}
.repo-card {
@apply flex-grow flex-shrink-0 w-full sm:w-1/2 md:w-1/3 lg:w-1/3 xl:w-1/4 2xl:w-1/5 p-4;
}
.repo-card .px-6.pt-4.pb-2 {
display: flex; /* 将父元素改为 flex 布局 */
flex-wrap: wrap; /* 允许标签换行 */
}
/* 标签容器样式 */
.topics-container {
display: -webkit-box; /* 启用 WebKit 特性 */
-webkit-box-orient: vertical; /* 设置垂直方向 */
-webkit-line-clamp: 3; /* 限制显示三行 */
overflow: hidden; /* 隐藏溢出内容 */
position: relative; /* 使伪元素相对于容器定位 */
max-height: 6em; /* 三行高度,根据实际情况调整 */
line-height: 2em; /* 行高,根据实际情况调整 */
text-overflow: ellipsis; /* 在截断处显示省略号 */
}
/* 伪元素样式 */
.topics-container::after {
content: "...";
position: absolute; /* 绝对定位 */
bottom: 0; /* 与容器底部对齐 */
right: 0; /* 与容器右侧对齐 */
padding-left: 0.25rem; /* 添加左边距 */
background-color: white; /* 背景色,与容器背景色相同 */
}
.topic {
@apply inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2;
flex: 0 1 auto;
box-sizing: border-box;
line-height: 2; /* 设置您想要的行高 */
}
.repo-card {
flex-basis: calc(33.333% - 2rem);
height: 66vh;
overflow: hidden;
}
@media (max-width: 768px) {
.repo-card {
flex-basis: calc(50% - 2rem);
}
}
@media (max-width: 480px) {
.repo-card {
flex-basis: 100%;
}
}
.repo-card .text-gray-700 {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
#back-to-top {
position: fixed;
bottom: 20px;
right: 20px;
display: none;
padding: 10px 15px;
background-color: tan;
color: white;
border-radius: 5px;
cursor: pointer;
}
#sidebar {
position: fixed;
top: 0;
left: 0;
height: 100%;
overflow-y: auto;
background-color: tan;
padding: 20px;
width: 167px;
}
#main-content {
margin-left: 167px;
padding-top: 0;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 4px 12px;
background-color: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 100;
background-color: tan;
padding: 4px 12px;
}
.header h1 {
margin: 0;
}
.search-container {
margin-left: auto;
}
#search {
width: 300px;
}
.repo-card .repo-stats {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
</head>
<body class="bg-gray-100">
<div class="header flex justify-between items-center px-4 py-2 bg-white shadow-md">
<h1 class="text-2xl font-bold">
<a href="/" class="text-blue-500 hover:underline">ZSCGR github Star 导航</a>
</h1>
<input id="search" type="text" placeholder="Search repositories..." class="p-2 border rounded w-1/3 mx-auto">
</div>
<div class="container mx-auto p-4">
<div class="flex">
<div id="sidebar">
<h2 class="text-xl font-bold mb-4">语言分类</h2>
<ul id="sidebarLinks">
<!-- 语言分类链接将在这里动态生成 -->
</ul>
</div>
<div id="main-content">
<div id="categories-container">
<!-- 仓库卡片将在这里动态生成 -->
</div>
</div>
</div>
</div>
<button id="back-to-top"></button>
<script>
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('search');
const categoriesContainer = document.getElementById('categories-container');
const sidebarLinks = document.getElementById('sidebarLinks');
const backToTopButton = document.getElementById('back-to-top');
fetch('https://raw.githubusercontent.com/ZSCGR/some-stars/main/data.json')
.then(response => response.json())
.then(data => {
generateContent(data);
searchInput.addEventListener('input', function() {
const query = this.value.trim().toLowerCase();
searchAndDisplay(query, data);
});
});
function generateContent(data) {
let categoriesHtml = '';
let sidebarLinksHtml = '';
for (const language in data) {
categoriesHtml += `
<div id="${language}" class="mb-8 category">
<h2 class="text-2xl font-bold mb-4">${language} Repositories</h2>
<div class="flex flex-wrap justify-center">
${generateRepoCards(data[language])}
</div>
</div>
`;
sidebarLinksHtml += `
<li class="mb-2"><a href="#${language}" class="text-blue-500 hover:underline">${language}</a></li>
`;
}
categoriesContainer.innerHTML = categoriesHtml;
sidebarLinks.innerHTML = sidebarLinksHtml;
}
function generateRepoCards(repos) {
return repos.map(repo => `
<div class="repo-card max-w-sm rounded-2xl overflow-hidden shadow-lg m-4 bg-white transition-transform transform hover:scale-105">
<div class="h-48 overflow-hidden flex items-center justify-center mt-4 rounded-t-2xl">
<img class="object-contain h-full w-full rounded-t-2xl" src="${repo.owner.avatar_url}" alt="${repo.owner.login}">
</div>
<div class="px-6 py-4">
<div class="font-bold text-xl mb-2">
<a href="${repo.html_url}" class="text-blue-500">${repo.full_name}</a>
</div>
<p class="text-gray-700 text-base">${truncateDescription(repo.description)}</p>
</div>
<div class="px-6 pt-4 pb-2 topics-container">
${repo.topics.map(topic => `<span class="topic inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#${topic}</span>`).join('')}
</div>
<div class="px-6 pt-4 pb-2">
<span class="inline-block bg-blue-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">Stars: ${repo.stargazers_count}</span>
<span class="inline-block bg-green-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">Watchers: ${repo.watchers_count}</span>
</div>
</div>
`).join('');
}
function truncateDescription(description) {
return description && description.length > 200 ? description.slice(0, 200) + '...' : description;
}
function searchAndDisplay(query, data) {
if (query) {
const matchedRepos = [];
for (const language in data) {
matchedRepos.push(...data[language].filter(repo => {
return repo.full_name.toLowerCase().includes(query) ||
(repo.description && repo.description.toLowerCase().includes(query)) ||
repo.topics.some(topic => topic.toLowerCase().includes(query));
}));
}
categoriesContainer.innerHTML = `
<div class="mb-8">
<h2 class="text-2xl font-bold mb-4">Search Results</h2>
<div class="flex flex-wrap justify-center">
${generateRepoCards(matchedRepos)}
</div>
</div>
`;
} else {
generateContent(data);
}
}
window.addEventListener('scroll', function() {
if (window.scrollY > 200) {
backToTopButton.style.display = 'block';
} else {
backToTopButton.style.display = 'none';
}
});
backToTopButton.addEventListener('click', function() {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
});
</script>
</body>
</html>