Show better versions number on mc mod page
This commit is contained in:
parent
a5b429c1bb
commit
15878b70c6
|
@ -31,5 +31,8 @@
|
|||
"typescript": "^4.6.4",
|
||||
"vite": "^3.2.0",
|
||||
"vite-plugin-ssr": "^0.4.90"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": "^7.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export type ButtonData = {
|
||||
id: string;
|
||||
cfId: string;
|
||||
modrinth: string;
|
||||
curseforge: string;
|
||||
github: string;
|
||||
|
|
|
@ -40,3 +40,10 @@ export type GalleryItem = {
|
|||
description: string;
|
||||
created: Date;
|
||||
};
|
||||
|
||||
export type VersionData = {
|
||||
id: string;
|
||||
version_number: string;
|
||||
game_versions: Array<string>;
|
||||
loaders: Array<string>;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import type {ModData} from "~/api/modrinth";
|
||||
import type {ModData, VersionData} from "~/api/modrinth";
|
||||
import type {Project} from "~/api/timeline";
|
||||
import type {ButtonData} from "~/api/button";
|
||||
import LazyComponent from "~/lib/LazyComponent.svelte";
|
||||
|
@ -17,6 +17,7 @@
|
|||
let modData: ModData;
|
||||
let buttonData: ButtonData;
|
||||
let updateData: Promise<Project> = new Promise((res, rej) => {});
|
||||
let versionData: Promise<VersionData[]> = new Promise((res, rej) => {});
|
||||
|
||||
onMount(() => {
|
||||
updateData = new Promise((res, rej) => {
|
||||
|
@ -33,11 +34,77 @@
|
|||
} else if (x) {
|
||||
modData = x.projectsSlugMap[__.routeParams.project];
|
||||
buttonData = modData ? x.modAlias[modData.id] : null;
|
||||
versionData = new Promise((res, rej) => {
|
||||
fetch(`https://api.modrinth.com/v2/versions?ids=${JSON.stringify(modData.versions)}`)
|
||||
.then(resp => res(resp.json()))
|
||||
.catch(err => rej(err));
|
||||
});
|
||||
} else {
|
||||
modData = null;
|
||||
buttonData = null;
|
||||
}
|
||||
});
|
||||
|
||||
type Version = {type: "version"; value: number[]};
|
||||
|
||||
type Range = {type: "range"; min: number[]; max: number[]};
|
||||
|
||||
function parseVersion(a: string): Version {
|
||||
let v = a.split(".").map(x => parseInt(x));
|
||||
if (v.length == 2) v.push(0);
|
||||
return {type: "version", value: v};
|
||||
}
|
||||
|
||||
function mergeVersions(a: Version | Range, b: Version): Range {
|
||||
if (a.type === "version") {
|
||||
let z = [...a.value];
|
||||
z[z.length - 1]++;
|
||||
if (arrayEquals(z, b.value)) return {type: "range", min: a.value, max: b.value};
|
||||
} else if (a.type === "range") {
|
||||
let z = [...a.max];
|
||||
z[z.length - 1]++;
|
||||
if (arrayEquals(z, b.value)) return {type: "range", min: a.min, max: b.value};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function squashVersions(a: Version[]): Array<Version | Range> {
|
||||
if (a.length == 0) return [];
|
||||
let out: Array<Version | Range> = [];
|
||||
let z: Version | Range = a[0];
|
||||
for (let i = 1; i < a.length; i++) {
|
||||
let m = mergeVersions(z, a[i]);
|
||||
if (m == null) {
|
||||
out.push(z);
|
||||
z = a[i];
|
||||
} else {
|
||||
z = m;
|
||||
}
|
||||
}
|
||||
out.push(z);
|
||||
return out;
|
||||
}
|
||||
|
||||
function renderGameVersions(a: string[]) {
|
||||
let b = a.map(x => parseVersion(x));
|
||||
if (b.length == 0) return "";
|
||||
let squash = squashVersions(b);
|
||||
return squash.map(x => renderVersion(x)).join(", ");
|
||||
}
|
||||
|
||||
function renderVersion(a: Version | Range): string {
|
||||
if (a.type === "version") {
|
||||
if (a.value[a.value.length - 1] === 0) a.value.splice(a.value.length - 1, 1);
|
||||
return a.value.map(x => x.toString()).join(".");
|
||||
} else if (a.type === "range") {
|
||||
return renderVersion({type: "version", value: a.min}) + " - " + renderVersion({type: "version", value: a.max});
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
function arrayEquals(a, b) {
|
||||
return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((val, index) => val === b[index]);
|
||||
}
|
||||
</script>
|
||||
|
||||
<MetaTags
|
||||
|
@ -52,6 +119,10 @@
|
|||
<div class="mod-meta">
|
||||
<img class="title-img" src={modData.icon_url} alt={modData.title} />
|
||||
<h1 class="title-text">{modData.title}</h1>
|
||||
<div class="platform-text">
|
||||
<div>Modrinth ID: {buttonData.id}</div>
|
||||
<div>CurseForge ID: {buttonData.cfId}</div>
|
||||
</div>
|
||||
{#if buttonData}
|
||||
<div class="link-buttons">
|
||||
<a href={buttonData.github} class="brand-button-wrapper" rel="noreferrer" target="_blank">
|
||||
|
@ -77,11 +148,15 @@
|
|||
<div class="buttons-loading" />
|
||||
{/if}
|
||||
<div class="game-versions">
|
||||
{#each modData.game_versions as v, i}
|
||||
<a class="version-pill" rel="noreferrer" target="_blank" href="https://modrinth.com/mod/{modData.slug}/version/{modData.versions[i]}">
|
||||
<span>{v}</span>
|
||||
</a>
|
||||
{/each}
|
||||
{#await versionData then w}
|
||||
{#each w as v, i}
|
||||
<a class="version-pill" rel="noreferrer" target="_blank" href="https://modrinth.com/mod/{modData.slug}/version/{v.id}">
|
||||
<span>{renderGameVersions(v.game_versions)}</span>
|
||||
</a>
|
||||
{/each}
|
||||
{:catch}
|
||||
<div data-text="No version data" />
|
||||
{/await}
|
||||
</div>
|
||||
{#await updateData}
|
||||
<div class="progress">
|
||||
|
@ -99,6 +174,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:catch}
|
||||
<div data-text="No update data" />
|
||||
{/await}
|
||||
</div>
|
||||
<div class="body-text">
|
||||
|
@ -125,11 +202,15 @@
|
|||
}
|
||||
|
||||
.title-text {
|
||||
margin: 0 0 24px 0;
|
||||
margin: 0 0 16px 0;
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.platform-text {
|
||||
margin: 0 0 16px 0;
|
||||
}
|
||||
|
||||
.progress {
|
||||
margin-bottom: 32px;
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ export interface ModStoreItem {
|
|||
id: string;
|
||||
github: string;
|
||||
modrinth: string;
|
||||
cfId: string;
|
||||
curseforge: string;
|
||||
}
|
||||
|
||||
|
|
19
yarn.lock
19
yarn.lock
|
@ -654,6 +654,13 @@ lower-case@^2.0.2:
|
|||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
lru-cache@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
|
||||
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
magic-string@^0.25.7:
|
||||
version "0.25.9"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c"
|
||||
|
@ -882,6 +889,13 @@ sass@^1.56.0:
|
|||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
semver@^7.5.3:
|
||||
version "7.5.3"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e"
|
||||
integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
sirv@^2.0.0:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.2.tgz#128b9a628d77568139cff85703ad5497c46a4760"
|
||||
|
@ -1035,3 +1049,8 @@ wrappy@1:
|
|||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
||||
|
||||
yallist@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||
|
|
Loading…
Reference in New Issue