Skip to content

Commit 5331681

Browse files
committed
重写download-section-launcher.tsx组件部分功能与样式
1 parent 912c3a2 commit 5331681

1 file changed

Lines changed: 80 additions & 79 deletions

File tree

components/download-section-launcher.tsx

Lines changed: 80 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export function DownloadSection({
113113
const [loading, setLoading] = useState(true);
114114
const [search, setSearch] = useState("");
115115
const [sortBy, setSortBy] = useState<"semantic" | "releaseDate" | "downloadCount">("semantic");
116-
const [sortOrder, setSortOrder] = useState("desc");
116+
const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc");
117117
const [tags, setTags] = useState<string[]>([]);
118118
const [selectedTag, setSelectedTag] = useState<string | null>(null);
119119
const [currentPage, setCurrentPage] = useState(1);
@@ -260,8 +260,10 @@ export function DownloadSection({
260260
// Filter out prereleases if not needed
261261
const filteredData = showPrereleases ? data : data.filter(release => !release.prerelease);
262262

263-
// 修复:正确识别最新版本
264-
const latestRelease = filteredData.find(release => !release.prerelease)?.id || null;
263+
// 修复:正确识别最新版本(按发布时间排序取最新正式版)
264+
const latestRelease = filteredData
265+
.filter(release => !release.prerelease)
266+
.sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime())[0]?.id || null;
265267

266268
const parsedReleases: ParsedRelease[] = filteredData.map((release) => {
267269
const mcVersionMatch = release.tag_name.match(/^(\d+\.\d+\.\d+)/);
@@ -329,82 +331,53 @@ export function DownloadSection({
329331
}
330332
}
331333

332-
const compareVersionStrings = (v1: string, v2: string) => {
334+
// 🌟 核心修复:完整语义化版本比较(支持正式版 > 预发布版,解决2.0排在1.x前面的问题)
335+
const compareSemanticVersions = (v1: string, v2: string): number => {
336+
// 解析版本:分离 主版本号 + 预发布后缀(如 v9-2.0 → [9,2,0], 无后缀;v9-b2 → [9], 后缀 b2)
333337
const parseVersion = (version: string) => {
334-
const match = version.match(/^EndlessPixel-(\d+\.\d+\.\d+)-v(\d+)-(.*)$/i);
335-
336-
if (!match) {
337-
return {
338-
mcVersion: "0.0.0",
339-
modVersion: 0,
340-
buildType: "",
341-
buildNum: 0,
342-
fullVersion: version
343-
};
344-
}
345-
346-
const [, mcVersion, modVersionStr, buildInfo] = match;
347-
const modVersion = parseInt(modVersionStr, 10);
348-
349-
let buildType = "release";
350-
let buildNum = 0;
351-
352-
const betaMatch = buildInfo.match(/^b(\d+)$/i);
353-
if (betaMatch) {
354-
buildType = "beta";
355-
buildNum = parseInt(betaMatch[1], 10);
356-
} else {
357-
const releaseMatch = buildInfo.match(/^(\d+(?:\.\d+)*)$/);
358-
if (releaseMatch) {
359-
const versionParts = releaseMatch[1].split(".").map(Number);
360-
buildNum = versionParts[0] * 1000 + (versionParts[1] || 0) * 10 + (versionParts[2] || 0);
361-
}
362-
}
363-
364-
return {
365-
mcVersion,
366-
modVersion,
367-
buildType,
368-
buildNum,
369-
fullVersion: version
370-
};
338+
// 匹配预发布后缀(-b/-beta/-rc 等开头)
339+
const preReleaseMatch = version.match(/-([a-zA-Z]+.*)$/);
340+
const preRelease = preReleaseMatch ? preReleaseMatch[1] : '';
341+
// 提取主版本号的数字部分(忽略前缀,只取数字序列)
342+
const mainParts = (preRelease ? version.replace(/-[a-zA-Z]+.*$/, '') : version)
343+
.match(/\d+/g)?.map(Number) || [];
344+
return { mainParts, preRelease };
371345
};
372346

373-
const v1Info = parseVersion(v1);
374-
const v2Info = parseVersion(v2);
375-
376-
if (v1Info.mcVersion !== v2Info.mcVersion) {
377-
const mcParts1 = v1Info.mcVersion.split(".").map(Number);
378-
const mcParts2 = v2Info.mcVersion.split(".").map(Number);
347+
const { mainParts: p1, preRelease: pr1 } = parseVersion(v1);
348+
const { mainParts: p2, preRelease: pr2 } = parseVersion(v2);
379349

380-
for (let i = 0; i < 3; i++) {
381-
if (mcParts1[i] !== mcParts2[i]) {
382-
return mcParts2[i] - mcParts1[i];
383-
}
384-
}
385-
}
386-
387-
if (v1Info.modVersion !== v2Info.modVersion) {
388-
return v2Info.modVersion - v1Info.modVersion;
350+
// 1. 先比较主版本号(核心逻辑)
351+
const maxLen = Math.max(p1.length, p2.length);
352+
for (let i = 0; i < maxLen; i++) {
353+
const num1 = p1[i] || 0;
354+
const num2 = p2[i] || 0;
355+
if (num1 > num2) return 1;
356+
if (num1 < num2) return -1;
389357
}
390358

391-
if (v1Info.buildType !== v2Info.buildType) {
392-
if (v1Info.buildType === "release") return -1;
393-
if (v2Info.buildType === "release") return 1;
394-
}
359+
// 2. 主版本号相同 → 正式版 > 预发布版
360+
if (!pr1 && pr2) return 1; // v1是正式版,v2是预发布版 → v1大
361+
if (pr1 && !pr2) return -1; // v1是预发布版,v2是正式版 → v2大
395362

396-
if (v1Info.buildNum !== v2Info.buildNum) {
397-
return v2Info.buildNum - v1Info.buildNum;
363+
// 3. 都是预发布版 → 比较后缀(如 b2 > b1)
364+
if (pr1 && pr2) {
365+
// 提取后缀里的数字(b2 → 2, b10 →10)
366+
const getPreNum = (pr: string) => Number(pr.match(/\d+/)?.[0] || 0);
367+
return getPreNum(pr1) - getPreNum(pr2);
398368
}
399369

400-
return v1Info.fullVersion.localeCompare(v2Info.fullVersion);
370+
// 版本完全相同
371+
return 0;
401372
};
402373

374+
// 修复语义化排序逻辑
403375
const semanticCompare = (a: ParsedRelease, b: ParsedRelease) => {
404376
if (a.isLatest && !b.isLatest) return -1;
405377
if (!a.isLatest && b.isLatest) return 1;
406378

407-
return compareVersionStrings(a.version, b.version); // 修复:使用version而不是name
379+
// 使用修复后的语义化比较函数
380+
return compareSemanticVersions(a.version, b.version);
408381
};
409382

410383
const filteredReleases = releases
@@ -416,7 +389,8 @@ export function DownloadSection({
416389
.filter((release) => (selectedTag ? release.tags?.includes(selectedTag) : true))
417390
.sort((a, b) => {
418391
if (sortBy === "semantic") {
419-
return sortOrder === "asc" ? -semanticCompare(a, b) : semanticCompare(a, b);
392+
// 排序方向:desc → 新版本在前,asc → 旧版本在前
393+
return sortOrder === "asc" ? semanticCompare(a, b) : -semanticCompare(a, b);
420394
}
421395

422396
const compare = (key: "releaseDate" | "downloadCount") => {
@@ -776,14 +750,36 @@ export function DownloadSection({
776750

777751
{/* Footer Note */}
778752
<div className="text-center text-sm text-slate-500 dark:text-slate-400 mt-8 p-4 bg-slate-50 dark:bg-slate-800/30 rounded-lg border border-slate-200 dark:border-slate-700">
779-
<p>
780-
加速下载由
781-
<a href="https://gh-proxy.com/ " target="_blank" rel="noopener noreferrer" className="text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300 underline">gh-proxy.com </a>
782-
<a href="https://gh.imixc.top/ " target="_blank" rel="noopener noreferrer" className="text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300 underline"> gh.imixc.top </a>
783-
<a href="https://gh.jasonzeng.dev/ " target="_blank" rel="noopener noreferrer" className="text-blue-500 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300 underline"> gh.jasonzeng.dev</a>
784-
提供。
785-
如遇下载问题,请尝试不同的镜像链接。
753+
<p className="mb-3">
754+
加速下载服务由以下镜像站点提供:
786755
</p>
756+
757+
<div className="flex flex-wrap gap-2">
758+
<a
759+
href="https://gh-proxy.com/"
760+
target="_blank"
761+
rel="noopener noreferrer"
762+
className="px-4 py-2 bg-blue-500 text-white hover:bg-blue-600 dark:bg-blue-600 dark:hover:bg-blue-700 rounded-md transition-colors duration-200"
763+
>
764+
gh-proxy.com
765+
</a>
766+
<a
767+
href="https://gh.imixc.top/"
768+
target="_blank"
769+
rel="noopener noreferrer"
770+
className="px-4 py-2 bg-blue-500 text-white hover:bg-blue-600 dark:bg-blue-600 dark:hover:bg-blue-700 rounded-md transition-colors duration-200"
771+
>
772+
gh.imixc.top
773+
</a>
774+
<a
775+
href="https://gh.jasonzeng.dev/"
776+
target="_blank"
777+
rel="noopener noreferrer"
778+
className="px-4 py-2 bg-blue-500 text-white hover:bg-blue-600 dark:bg-blue-600 dark:hover:bg-blue-700 rounded-md transition-colors duration-200"
779+
>
780+
gh.jasonzeng.dev
781+
</a>
782+
</div>
787783
</div>
788784
</div>
789785
);
@@ -810,6 +806,11 @@ function ReleaseCard({ release, isExpanded, onToggleExpand }: ReleaseCardProps)
810806
return "bg-blue-100 text-blue-800 border-blue-300 dark:bg-blue-900/30 dark:text-blue-300";
811807
}
812808

809+
// 🌟 修复:镜像链接拼接(去掉多余空格,和官网格式一致)
810+
const getMirrorUrl = (host: string, originalUrl: string) => {
811+
return `${host}/${originalUrl}`;
812+
};
813+
813814
return (
814815
<Card className={`
815816
relative overflow-hidden transition-all duration-300 hover:shadow-lg
@@ -874,32 +875,32 @@ function ReleaseCard({ release, isExpanded, onToggleExpand }: ReleaseCardProps)
874875
const mirrors = [
875876
{
876877
name: "Cloudflare 主站(全球加速)",
877-
url: `https://gh-proxy.com/ ${file.downloadUrl}`,
878+
url: getMirrorUrl("https://gh-proxy.org", file.downloadUrl),
878879
tag: "Cloudflare",
879880
},
880881
{
881882
name: "Fastly CDN",
882-
url: `https://cdn.gh-proxy.com/ ${file.downloadUrl}`,
883+
url: getMirrorUrl("https://cdn.gh-proxy.org", file.downloadUrl),
883884
tag: "Fastly",
884885
},
885886
{
886887
name: "Edgeone 全球加速",
887-
url: `https://edgeone.gh-proxy.com/ ${file.downloadUrl}`,
888+
url: getMirrorUrl("https://edgeone.gh-proxy.org", file.downloadUrl),
888889
tag: "Edgeone",
889890
},
890891
{
891892
name: "Jasonzeng 文件代理加速",
892-
url: `https://gh.xmly.dev/ ${file.downloadUrl}`,
893+
url: getMirrorUrl("https://gh.xmly.dev", file.downloadUrl),
893894
tag: "Jasonzeng",
894895
},
895896
{
896897
name: "Imixc 国内高速下载",
897-
url: `https://gh.imixc.top/ ${file.downloadUrl}`,
898+
url: getMirrorUrl("https://gh.imixc.top", file.downloadUrl),
898899
tag: "Imixc",
899900
},
900901
{
901902
name: "香港 国内线路优化,secbit.ai&Sharon CDN赞助",
902-
url: `https://hk.gh-proxy.com/ ${file.downloadUrl}`,
903+
url: getMirrorUrl("https://hk.gh-proxy.org", file.downloadUrl),
903904
tag: "香港",
904905
tip: "大文件下载不建议使用!",
905906
},
@@ -995,7 +996,7 @@ function ReleaseCard({ release, isExpanded, onToggleExpand }: ReleaseCardProps)
995996
</Button>
996997

997998
{showChangelog && (
998-
<div className="mt-4 p-4 bg-slate-50 dark:bg-slate-800/50 rounded-xl border border-slate-200 dark:border-slate-700 prose prose-sm max-w-none dark:prose-invert wrap-break-word">
999+
<div className="mt-4 p-4 bg-slate-50 dark:bg-slate-800/50 rounded-xl border border-slate-200 dark:border-slate-700 prose prose-sm max-w-none dark:prose-invert wrap-break-word overflow-auto max-h-60">
9991000
<ReactMarkdown
10001001
rehypePlugins={[rehypeRaw]}
10011002
remarkPlugins={[remarkGfm]}

0 commit comments

Comments
 (0)