view/download: Fallback to the previous build if the current build is still in progress (#41)

This commit is contained in:
jduncanator 2024-03-21 22:50:47 +11:00 committed by GitHub
parent 1c16d602bb
commit b5c18c1fa2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 41 deletions

View File

@ -5,7 +5,7 @@ VITE_FAQ_URL=https://ryujinx.org/faq
VITE_COMPATIBILITY_URL=https://github.com/Ryujinx/Ryujinx-Games-List/issues VITE_COMPATIBILITY_URL=https://github.com/Ryujinx/Ryujinx-Games-List/issues
VITE_GUIDE_URL=https://github.com/Ryujinx/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide VITE_GUIDE_URL=https://github.com/Ryujinx/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide
VITE_DISCORD_URL=https://discord.gg/VkQYXAZ VITE_DISCORD_URL=https://discord.gg/VkQYXAZ
VITE_RELEASE_URL=https://api.github.com/repos/Ryujinx/release-channel-master/releases/latest VITE_RELEASE_URL="https://api.github.com/repos/Ryujinx/release-channel-master/releases?per_page=2"
VITE_OLDER_BUILDS_URL=https://github.com/Ryujinx/release-channel-master/releases VITE_OLDER_BUILDS_URL=https://github.com/Ryujinx/release-channel-master/releases
VITE_LDN_BUILD_URL=https://www.patreon.com/posts/ldn-2-5-vulkan-70757628 VITE_LDN_BUILD_URL=https://www.patreon.com/posts/ldn-2-5-vulkan-70757628
VITE_PATREON_URL=https://patreon.com/Ryujinx VITE_PATREON_URL=https://patreon.com/Ryujinx

View File

@ -5,7 +5,7 @@ VITE_FAQ_URL=https://ryujinx.org/faq
VITE_COMPATIBILITY_URL=https://github.com/Ryujinx/Ryujinx-Games-List/issues VITE_COMPATIBILITY_URL=https://github.com/Ryujinx/Ryujinx-Games-List/issues
VITE_GUIDE_URL=https://github.com/Ryujinx/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide VITE_GUIDE_URL=https://github.com/Ryujinx/Ryujinx/wiki/Ryujinx-Setup-&-Configuration-Guide
VITE_DISCORD_URL=https://discord.gg/VkQYXAZ VITE_DISCORD_URL=https://discord.gg/VkQYXAZ
VITE_RELEASE_URL=https://api.github.com/repos/Ryujinx/release-channel-master/releases/latest VITE_RELEASE_URL="https://api.github.com/repos/Ryujinx/release-channel-master/releases?per_page=2"
VITE_OLDER_BUILDS_URL=https://github.com/Ryujinx/release-channel-master/releases VITE_OLDER_BUILDS_URL=https://github.com/Ryujinx/release-channel-master/releases
VITE_LDN_BUILD_URL=https://www.patreon.com/posts/introducing-ldn3-74910544 VITE_LDN_BUILD_URL=https://www.patreon.com/posts/introducing-ldn3-74910544
VITE_PATREON_URL=https://patreon.com/Ryujinx VITE_PATREON_URL=https://patreon.com/Ryujinx

View File

@ -9,51 +9,66 @@ import {
InformationCircleIcon, InformationCircleIcon,
} from "@heroicons/vue/solid"; } from "@heroicons/vue/solid";
import { DownloadRelease } from "@/types"; import { DownloadAsset, DownloadRelease } from "@/types";
const GUIDE_URL = import.meta.env.VITE_GUIDE_URL as string; const GUIDE_URL = import.meta.env.VITE_GUIDE_URL as string;
const LDN_BUILD_URL = import.meta.env.VITE_LDN_BUILD_URL as string; const LDN_BUILD_URL = import.meta.env.VITE_LDN_BUILD_URL as string;
const OLDER_BUILD_URL = import.meta.env.VITE_OLDER_BUILDS_URL as string; const OLDER_BUILD_URL = import.meta.env.VITE_OLDER_BUILDS_URL as string;
const { t } = useI18n(); const { t } = useI18n();
const isLoading = ref(true); const isLoading = ref(true);
const downloadRelease = ref<DownloadRelease>({} as DownloadRelease);
const macosBuildUrl = ref(""); type Release = {
const linuxIntelBuildUrl = ref(""); release: DownloadRelease;
const linuxArm64BuildUrl = ref(""); asset: DownloadAsset;
const windowBuildUrl = ref(""); };
const releaseMap = {
"win-x64": /win_x64\.zip/,
"lin-x64": /linux_x64\.tar\.gz/,
"lin-arm64": /linux_arm64\.tar\.gz/,
"macos": /macos_universal\.app\.tar\.gz/
}
type ReleaseTargets = keyof typeof releaseMap;
const downloadReleases = ref<DownloadRelease[]>([]);
const releases = ref<{ [K in ReleaseTargets]?: Release }>({});
onMounted(() => { onMounted(() => {
fetchBuilds(); fetchBuilds();
}); });
const totalDownload = computed(() => { const totalDownload = computed(() => {
let total = 0; return downloadReleases.value[0]
.assets.reduce((total, asset) => total + asset.download_count, 0)
downloadRelease.value?.assets.forEach((a) => (total += a.download_count));
return total;
}); });
const fetchBuilds = async () => { const fetchBuilds = async () => {
try { try {
const result = await axios.get<DownloadRelease>( const result = await axios.get<DownloadRelease[]>(
import.meta.env.VITE_RELEASE_URL import.meta.env.VITE_RELEASE_URL
); );
downloadRelease.value = result.data; downloadReleases.value = result.data;
downloadRelease.value?.assets.forEach((asset) => { const targets = Object.keys(releaseMap) as Array<ReleaseTargets>;
if (asset.name.startsWith("ryujinx")) { result.data.forEach(release => {
if (asset.name.endsWith("win_x64.zip")) { targets.forEach(target => {
windowBuildUrl.value = asset.browser_download_url; if(releases.value[target]) {
} else if (asset.name.endsWith("linux_x64.tar.gz")) { return;
linuxIntelBuildUrl.value = asset.browser_download_url;
} else if (asset.name.endsWith("linux_arm64.tar.gz")) {
linuxArm64BuildUrl.value = asset.browser_download_url;
} else if (asset.name.endsWith("macos_universal.app.tar.gz")) {
macosBuildUrl.value = asset.browser_download_url;
} }
}
const asset = release.assets
.filter(asset => asset.name.startsWith("ryujinx"))
.find(asset => asset.name.match(releaseMap[target]));
if(asset) {
releases.value[target] = {
release,
asset
};
}
});
}); });
} catch (err) { } catch (err) {
console.error(err); console.error(err);
@ -85,14 +100,14 @@ const fetchBuilds = async () => {
<!-- Features --> <!-- Features -->
<div v-if="!isLoading" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6"> <div v-if="!isLoading" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6">
<!-- Windows --> <!-- Windows -->
<a :href="windowBuildUrl" <a v-if="releases['win-x64']" :href="releases['win-x64']!.asset.browser_download_url"
class="group relative p-4 lg:p-6 bg-white rounded-xl transition duration-150 shadow-md shadow-gray-100"> class="group relative p-4 lg:p-6 bg-white rounded-xl transition duration-150 shadow-md shadow-gray-100">
<div <div
class="absolute inset-0 bg-white rounded-xl shadow-md shadow-gray-200 transition duration-100 scale-100 opacity-0 group-hover:opacity-100 group-hover:scale-105 group-active:scale-100 group-active:opacity-0"> class="absolute inset-0 bg-white rounded-xl shadow-md shadow-gray-200 transition duration-100 scale-100 opacity-0 group-hover:opacity-100 group-hover:scale-105 group-active:scale-100 group-active:opacity-0">
</div> </div>
<div class="relative text-center"> <div class="relative text-center">
<div class="text-xs uppercase text-gray-400 font-semibold tracking-wider mb-4"> <div class="text-xs uppercase text-gray-400 font-semibold tracking-wider mb-4">
{{ downloadRelease.tag_name }} {{ releases['win-x64']!.release.tag_name }}
</div> </div>
<div class="relative w-12 mb-8 text-indigo-500 mx-auto"> <div class="relative w-12 mb-8 text-indigo-500 mx-auto">
<img alt="windows logo" src="/assets/images/icons/windows.png" /> <img alt="windows logo" src="/assets/images/icons/windows.png" />
@ -109,14 +124,14 @@ const fetchBuilds = async () => {
</a> </a>
<!-- Mac OS --> <!-- Mac OS -->
<a :href="macosBuildUrl" <a v-if="releases['macos']" :href="releases['macos']!.asset.browser_download_url"
class="group relative p-4 lg:p-6 bg-white rounded-xl transition duration-150 shadow-md shadow-gray-100"> class="group relative p-4 lg:p-6 bg-white rounded-xl transition duration-150 shadow-md shadow-gray-100">
<div <div
class="absolute inset-0 bg-white rounded-xl shadow-md shadow-gray-200 transition duration-100 scale-100 opacity-0 group-hover:opacity-100 group-hover:scale-105 group-active:scale-100 group-active:opacity-0"> class="absolute inset-0 bg-white rounded-xl shadow-md shadow-gray-200 transition duration-100 scale-100 opacity-0 group-hover:opacity-100 group-hover:scale-105 group-active:scale-100 group-active:opacity-0">
</div> </div>
<div class="relative text-center"> <div class="relative text-center">
<div class="text-xs uppercase text-gray-400 font-semibold tracking-wider mb-4"> <div class="text-xs uppercase text-gray-400 font-semibold tracking-wider mb-4">
{{ downloadRelease.tag_name }} {{ releases['macos']!.release.tag_name }}
</div> </div>
<div class="relative w-12 mb-8 text-indigo-500 mx-auto"> <div class="relative w-12 mb-8 text-indigo-500 mx-auto">
<img alt="macos logo" src="/assets/images/icons/macos.png" /> <img alt="macos logo" src="/assets/images/icons/macos.png" />
@ -133,14 +148,14 @@ const fetchBuilds = async () => {
</a> </a>
<!-- Linux x86_64 --> <!-- Linux x86_64 -->
<a :href="linuxIntelBuildUrl" <a v-if="releases['lin-x64']" :href="releases['lin-x64']!.asset.browser_download_url"
class="group relative p-4 lg:p-6 bg-white rounded-xl transition duration-150 shadow-md shadow-gray-100"> class="group relative p-4 lg:p-6 bg-white rounded-xl transition duration-150 shadow-md shadow-gray-100">
<div <div
class="absolute inset-0 bg-white rounded-xl shadow-md shadow-gray-200 transition duration-100 scale-100 opacity-0 group-hover:opacity-100 group-hover:scale-105 group-active:scale-100 group-active:opacity-0"> class="absolute inset-0 bg-white rounded-xl shadow-md shadow-gray-200 transition duration-100 scale-100 opacity-0 group-hover:opacity-100 group-hover:scale-105 group-active:scale-100 group-active:opacity-0">
</div> </div>
<div class="relative text-center"> <div class="relative text-center">
<div class="text-xs uppercase text-gray-400 font-semibold tracking-wider mb-4"> <div class="text-xs uppercase text-gray-400 font-semibold tracking-wider mb-4">
{{ downloadRelease.tag_name }} {{ releases['lin-x64']!.release.tag_name }}
</div> </div>
<div class="relative w-12 mb-8 text-indigo-500 mx-auto"> <div class="relative w-12 mb-8 text-indigo-500 mx-auto">
<img alt="linux logo" src="/assets/images/icons/linux.png" /> <img alt="linux logo" src="/assets/images/icons/linux.png" />
@ -157,14 +172,14 @@ const fetchBuilds = async () => {
</a> </a>
<!-- Linux arm64 --> <!-- Linux arm64 -->
<a :href="linuxArm64BuildUrl" <a v-if="releases['lin-arm64']" :href="releases['lin-arm64']!.asset.browser_download_url"
class="group relative p-4 lg:p-6 bg-white rounded-xl transition duration-150 shadow-md shadow-gray-100"> class="group relative p-4 lg:p-6 bg-white rounded-xl transition duration-150 shadow-md shadow-gray-100">
<div <div
class="absolute inset-0 bg-white rounded-xl shadow-md shadow-gray-200 transition duration-100 scale-100 opacity-0 group-hover:opacity-100 group-hover:scale-105 group-active:scale-100 group-active:opacity-0"> class="absolute inset-0 bg-white rounded-xl shadow-md shadow-gray-200 transition duration-100 scale-100 opacity-0 group-hover:opacity-100 group-hover:scale-105 group-active:scale-100 group-active:opacity-0">
</div> </div>
<div class="relative text-center"> <div class="relative text-center">
<div class="text-xs uppercase text-gray-400 font-semibold tracking-wider mb-4"> <div class="text-xs uppercase text-gray-400 font-semibold tracking-wider mb-4">
{{ downloadRelease.tag_name }} {{ releases["lin-arm64"]!.release.tag_name }}
</div> </div>
<div class="relative w-12 mb-8 text-indigo-500 mx-auto"> <div class="relative w-12 mb-8 text-indigo-500 mx-auto">
<img alt="linux logo" src="/assets/images/icons/linux.png" /> <img alt="linux logo" src="/assets/images/icons/linux.png" />
@ -221,7 +236,7 @@ const fetchBuilds = async () => {
</h4> </h4>
<i18n-t class="leading-relaxed text-gray-500 mb-5" keypath="views.download.buildRelease" tag="p"> <i18n-t class="leading-relaxed text-gray-500 mb-5" keypath="views.download.buildRelease" tag="p">
<span class="font-semibold"> <span class="font-semibold">
{{ dayjs(downloadRelease.published_at).format("YYYY-MM-DD") }} {{ dayjs(downloadReleases[0].published_at).format("YYYY-MM-DD") }}
</span> </span>
</i18n-t> </i18n-t>
<h5 class="flex items-center my-8"> <h5 class="flex items-center my-8">
@ -239,7 +254,7 @@ const fetchBuilds = async () => {
<CogIcon class="text-sky-500 inline-block w-5 h-5" /> <CogIcon class="text-sky-500 inline-block w-5 h-5" />
<span> <span>
<span class="font-bold uppercase"> <span class="font-bold uppercase">
{{ downloadRelease.assets.length }} {{ downloadReleases[0].assets.length }}
</span> </span>
{{ t("views.download.assets") }} {{ t("views.download.assets") }}
</span> </span>
@ -250,7 +265,7 @@ const fetchBuilds = async () => {
<CogIcon class="text-sky-500 inline-block w-5 h-5" /> <CogIcon class="text-sky-500 inline-block w-5 h-5" />
<span> <span>
{{ t("views.download.tag") }}: {{ t("views.download.tag") }}:
<strong>{{ downloadRelease.tag_name }}</strong> <strong>{{ downloadReleases[0].tag_name }}</strong>
</span> </span>
</li> </li>
</ul> </ul>
@ -265,7 +280,7 @@ const fetchBuilds = async () => {
</li> </li>
</ul> </ul>
<div> <div>
<GButton :href="downloadRelease.html_url" rounded variant="sky" size="lg" extra-class="space-x-2 w-full"> <GButton :href="downloadReleases[0].html_url" rounded variant="sky" size="lg" extra-class="space-x-2 w-full">
<template #icon> <template #icon>
<ExternalLinkIcon class="opacity-50 inline-block w-5 h-5" /> <ExternalLinkIcon class="opacity-50 inline-block w-5 h-5" />
</template> </template>
@ -286,13 +301,13 @@ const fetchBuilds = async () => {
<!-- Author info --> <!-- Author info -->
<div class="flex-none relative md:w-72 p-5"> <div class="flex-none relative md:w-72 p-5">
<div class="p-5 lg:p-6 text-center rounded-lg bg-sky-50"> <div class="p-5 lg:p-6 text-center rounded-lg bg-sky-50">
<a :href="downloadRelease.author.html_url"> <a :href="downloadReleases[0].author.html_url">
<div> <div>
<img :src="downloadRelease.author.avatar_url" alt="Author avatar" class="w-16 h-16 inline-block" /> <img :src="downloadReleases[0].author.avatar_url" alt="Author avatar" class="w-16 h-16 inline-block" />
</div> </div>
<div <div
class="inline-flex space-x-1 items-center text-xs uppercase tracking-wider font-semibold px-3 py-1 bg-indigo-200 bg-opacity-50 text-sky-600 rounded-full mb-4"> class="inline-flex space-x-1 items-center text-xs uppercase tracking-wider font-semibold px-3 py-1 bg-indigo-200 bg-opacity-50 text-sky-600 rounded-full mb-4">
<span>{{ downloadRelease.author.login }}</span> <span>{{ downloadReleases[0].author.login }}</span>
</div> </div>
</a> </a>
</div> </div>