You've already forked AstralRinth
forked from didirus/AstralRinth
* fix(content): changing mod versions works again * chore(assets): update pyro logo * fix(properties): deprecate fetchconfigfile * Revert "fix(content): changing mod versions works again" This reverts commit d7c0d1196f8c1850fd7ccbc1644941c6db4dc306. * feat(files): ability to sort via column click * chore(startup): update clunky wording * feat(serverListing): server icons SSR friendly * fix(servers): if archon fails, display err in listing * chore(serverlisting): use pyroserver hook to init icon * chore(servers): much more graceful reinstall * fix(servers): tw warn * fix(platform): correctly react when pack reinstalled * fix(serversroot): explicitly import navigateTo Signed-off-by: Evan Song <theevansong@gmail.com> * chore(serverlabels): show skeleton instead of hiding Signed-off-by: Evan Song <theevansong@gmail.com> * feat(platform): install-aware controls Signed-off-by: Evan Song <theevansong@gmail.com> * refactor!(platform): rewrite platform page * fix(platform): regression in autoselecting loader * chore(platform): prefer version over project modification date * fix(platform): permanent hang after initial mount * chore(platform): do not silently fail and hang if modpack fails loading * oops: remove hardcoded error causer * fix(platform): switch modpack btn while installing doesnt need class Signed-off-by: Evan Song <theevansong@gmail.com> * chore(platform): adjust styling in version modal Signed-off-by: Evan Song <theevansong@gmail.com> * chore(platform): prevent changing project card style Signed-off-by: Evan Song <theevansong@gmail.com> * refactor(pyrodropdown): rewrite Signed-off-by: Evan Song <theevansong@gmail.com> * fix(pyrodropdown): do nopt use deprecated substr Signed-off-by: Evan Song <theevansong@gmail.com> * chore: clean Signed-off-by: Evan Song <theevansong@gmail.com> * fix(network): sentence case Signed-off-by: Evan Song <theevansong@gmail.com> * refactor(terminal): initial batch Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminal): fulllog over fullscreen Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminal): fullscreen conflict with body scroll Signed-off-by: Evan Song <theevansong@gmail.com> * feat(terminal): init drag select * feat(terminal): shift click support Signed-off-by: Evan Song <theevansong@gmail.com> * chore(terminal): double lines limit Signed-off-by: Evan Song <theevansong@gmail.com> * feat(terminal): copy button Signed-off-by: Evan Song <theevansong@gmail.com> * chore(terminal): protip style Signed-off-by: Evan Song <theevansong@gmail.com> * chore(terminal): improve styles Signed-off-by: Evan Song <theevansong@gmail.com> * feat(terminal): regex search Signed-off-by: Evan Song <theevansong@gmail.com> * chore(terminal): move icons to icons dir Signed-off-by: Evan Song <theevansong@gmail.com> * chore(terminal): improve drag select autoscroll inertia Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminal): cancel selection on right click Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminal): progblur and stb btn disappearing Signed-off-by: Evan Song <theevansong@gmail.com> * refactor(serverstats): power efficiency * fix(subdomainlabel): correct tooltip terminology Signed-off-by: Evan Song <theevansong@gmail.com> * feat(preferences): users hide subdomain label Signed-off-by: Evan Song <theevansong@gmail.com> * chore(servers): clean Signed-off-by: Evan Song <theevansong@gmail.com> * chore(terminal): deselect lines on escape Signed-off-by: Evan Song <theevansong@gmail.com> * fix(serversidebar): type err Signed-off-by: Evan Song <theevansong@gmail.com> * fix(fileitem): vue server render type Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminal): disable pointer events on lines if scrolling Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminal): search result counts style Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminal): plural Signed-off-by: Evan Song <theevansong@gmail.com> * chore(terminal): clean Signed-off-by: Evan Song <theevansong@gmail.com> * feat(terminal): view selection Signed-off-by: Evan Song <theevansong@gmail.com> * feat(terminal): show actively selected lines in scrollbar Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminallog): btn color Signed-off-by: Evan Song <theevansong@gmail.com> * chore: clean Signed-off-by: Evan Song <theevansong@gmail.com> * fix(gamelabel): align to text Signed-off-by: Evan Song <theevansong@gmail.com> * fix(gamelabel): align to text Signed-off-by: Evan Song <theevansong@gmail.com> * fix(listing): remove deadcode Signed-off-by: Evan Song <theevansong@gmail.com> * fix(serverlisting): deprecated process.server Signed-off-by: Evan Song <theevansong@gmail.com> * fix(platform): correctly disable button Signed-off-by: Evan Song <theevansong@gmail.com> * fix(backups): do not allow backup creation during server installation Signed-off-by: Evan Song <theevansong@gmail.com> * fix(platform): flush stale currentversion data on successful install Signed-off-by: Evan Song <theevansong@gmail.com> * fix(gamelabel): fix gap Signed-off-by: Evan Song <theevansong@gmail.com> * chore(network): vaporize uppercase Signed-off-by: Evan Song <theevansong@gmail.com> * chore(info): vaporize uppercase Signed-off-by: Evan Song <theevansong@gmail.com> * chore(backups): style unification Signed-off-by: Evan Song <theevansong@gmail.com> * chore(backups): finalize style change Signed-off-by: Evan Song <theevansong@gmail.com> * fix(servers): catch pyro servers fetch errors during ssr Signed-off-by: Evan Song <theevansong@gmail.com> * fix(serverstats): ram as bytes graph now works Signed-off-by: Evan Song <theevansong@gmail.com> * fix(platform): unify attempts and refresh interval Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminal): input Signed-off-by: Evan Song <theevansong@gmail.com> * feat(servers): installing ticket + update available notice back in platform Signed-off-by: Evan Song <theevansong@gmail.com> * chore(terminal): dont add bg to scroll track Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminal): preserve whitespace Signed-off-by: Evan Song <theevansong@gmail.com> * chore(serversroot): unnest blurred icon query Signed-off-by: Evan Song <theevansong@gmail.com> * fix(serverstats): clamp memory usage to 100% no matter what Signed-off-by: Evan Song <theevansong@gmail.com> * feat(terminal): allow copy of single lines, show btn Signed-off-by: Evan Song <theevansong@gmail.com> * chore(terminal): animate copy>view transition Signed-off-by: Evan Song <theevansong@gmail.com> * init: search improvements Signed-off-by: Evan Song <theevansong@gmail.com> * fix: lint Signed-off-by: Evan Song <theevansong@gmail.com> * chore: change log modal title Signed-off-by: Evan Song <theevansong@gmail.com> * fix: hide fullscreen when selecting and cancel selection on clickout Signed-off-by: Evan Song <theevansong@gmail.com> * refactor(terminal): more reliable jumpToLine Signed-off-by: Evan Song <theevansong@gmail.com> * feat: search results separator Signed-off-by: Evan Song <theevansong@gmail.com> * chore: remove buggy isScrollable check Signed-off-by: Evan Song <theevansong@gmail.com> * fix: style Signed-off-by: Evan Song <theevansong@gmail.com> * refactor: correctly store pos to make jump reliable Signed-off-by: Evan Song <theevansong@gmail.com> * fix: disparity between search/log dragselect Signed-off-by: Evan Song <theevansong@gmail.com> * fix: prevent propagation of click events when clicking on jump btn Signed-off-by: Evan Song <theevansong@gmail.com> * fix: switch selection strategies depending on terminal mode Signed-off-by: Evan Song <theevansong@gmail.com> * chore: smarter esc handling Signed-off-by: Evan Song <theevansong@gmail.com> * finalize Signed-off-by: Evan Song <theevansong@gmail.com> * run fix * fix: ensure lines between cannot be selected Signed-off-by: Evan Song <theevansong@gmail.com> * fix: increase initial log batch to 256 Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminal): click on scroll track should take user to new scroll position Signed-off-by: Evan Song <theevansong@gmail.com> * fix(terminal): update aria label for view selected logs btn Signed-off-by: Evan Song <theevansong@gmail.com> * chore: clean Signed-off-by: Evan Song <theevansong@gmail.com> --------- Signed-off-by: Evan Song <theevansong@gmail.com>
206 lines
6.8 KiB
Vue
206 lines
6.8 KiB
Vue
<template>
|
|
<div
|
|
data-pyro-server-list-root
|
|
class="experimental-styles-within relative mx-auto flex min-h-screen w-full max-w-[1280px] flex-col px-6"
|
|
>
|
|
<div
|
|
v-if="hasError || fetchError"
|
|
class="mx-auto flex h-full min-h-[calc(100vh-4rem)] flex-col items-center justify-center gap-4 text-left"
|
|
>
|
|
<div class="flex max-w-lg flex-col items-center rounded-3xl bg-bg-raised p-6 shadow-xl">
|
|
<div class="flex flex-col items-center text-center">
|
|
<div class="flex flex-col items-center gap-4">
|
|
<div class="grid place-content-center rounded-full bg-bg-blue p-4">
|
|
<HammerIcon class="size-12 text-blue" />
|
|
</div>
|
|
<h1 class="m-0 w-fit text-3xl font-bold">Servers could not be loaded</h1>
|
|
</div>
|
|
<p class="text-lg text-secondary">We may have temporary issues with our servers.</p>
|
|
<ul class="m-0 list-disc space-y-4 p-0 pl-4 text-left text-sm leading-[170%]">
|
|
<li>
|
|
Our systems automatically alert our team when there's an issue. We are already working
|
|
on getting them back online.
|
|
</li>
|
|
<li>
|
|
If you recently purchased your Modrinth Server, it is currently in a queue and will
|
|
appear here as soon as it's ready. <br />
|
|
<span class="font-medium text-contrast"
|
|
>Do not attempt to purchase a new server.</span
|
|
>
|
|
</li>
|
|
<li>
|
|
If you require personalized support regarding the status of your server, please
|
|
contact Modrinth Support.
|
|
</li>
|
|
|
|
<li v-if="fetchError" class="text-red">
|
|
<p>Error details:</p>
|
|
<UiCopyCode
|
|
:text="(fetchError as PyroFetchError).message || 'Unknown error'"
|
|
:copyable="false"
|
|
:selectable="false"
|
|
:language="'json'"
|
|
/>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<ButtonStyled size="large" type="standard" color="brand">
|
|
<a class="mt-6 !w-full" href="https://support.modrinth.com">Contact Modrinth Support</a>
|
|
</ButtonStyled>
|
|
<ButtonStyled size="large" @click="() => reloadNuxtApp()">
|
|
<button class="mt-3 !w-full">Reload</button>
|
|
</ButtonStyled>
|
|
</div>
|
|
</div>
|
|
|
|
<LazyUiServersServerManageEmptyState
|
|
v-else-if="serverList.length === 0 && !isPollingForNewServers && !hasError"
|
|
/>
|
|
|
|
<template v-else>
|
|
<div class="relative flex h-fit w-full flex-col items-center justify-between md:flex-row">
|
|
<h1 class="w-full text-4xl font-bold text-contrast">Servers</h1>
|
|
<div class="mb-4 flex w-full flex-row items-center justify-end gap-2 md:mb-0 md:gap-4">
|
|
<div class="relative w-full text-sm md:w-72">
|
|
<label class="sr-only" for="search">Search</label>
|
|
<SearchIcon
|
|
class="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2"
|
|
aria-hidden="true"
|
|
/>
|
|
<input
|
|
id="search"
|
|
v-model="searchInput"
|
|
class="w-full border-[1px] border-solid border-button-border pl-9"
|
|
type="search"
|
|
name="search"
|
|
autocomplete="off"
|
|
placeholder="Search servers..."
|
|
/>
|
|
</div>
|
|
<ButtonStyled type="standard">
|
|
<NuxtLink
|
|
class="!h-10 whitespace-pre !border-[1px] !border-solid !border-button-border text-sm !font-medium"
|
|
:to="{ path: '/servers', hash: '#plan' }"
|
|
>
|
|
<PlusIcon class="size-4" />
|
|
New server
|
|
</NuxtLink>
|
|
</ButtonStyled>
|
|
</div>
|
|
</div>
|
|
|
|
<ul v-if="filteredData.length > 0" class="m-0 flex flex-col gap-4 p-0">
|
|
<UiServersServerListing
|
|
v-for="server in filteredData"
|
|
:key="server.server_id"
|
|
:server_id="server.server_id"
|
|
:name="server.name"
|
|
:status="server.status"
|
|
:game="server.game"
|
|
:loader="server.loader"
|
|
:loader_version="server.loader_version"
|
|
:mc_version="server.mc_version"
|
|
:upstream="server.upstream"
|
|
:net="server.net"
|
|
/>
|
|
<LazyUiServersServerListingSkeleton v-if="isPollingForNewServers" />
|
|
</ul>
|
|
<div v-else class="flex h-full items-center justify-center">
|
|
<p class="text-contrast">No servers found.</p>
|
|
</div>
|
|
</template>
|
|
|
|
<UiServersPoweredByPyro />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, computed, onMounted, onUnmounted, watch } from "vue";
|
|
import Fuse from "fuse.js";
|
|
import { HammerIcon, PlusIcon, SearchIcon } from "@modrinth/assets";
|
|
import { ButtonStyled } from "@modrinth/ui";
|
|
import { reloadNuxtApp } from "#app";
|
|
import type { PyroFetchError } from "~/composables/pyroFetch";
|
|
import type { Server } from "~/types/servers";
|
|
|
|
definePageMeta({
|
|
middleware: "auth",
|
|
});
|
|
|
|
useHead({
|
|
title: "Servers - Modrinth",
|
|
});
|
|
|
|
interface ServerResponse {
|
|
servers: Server[];
|
|
}
|
|
|
|
const route = useRoute();
|
|
const hasError = ref(false);
|
|
const isPollingForNewServers = ref(false);
|
|
|
|
const {
|
|
data: serverResponse,
|
|
error: fetchError,
|
|
refresh,
|
|
} = await useAsyncData<ServerResponse>("ServerList", () => usePyroFetch<ServerResponse>("servers"));
|
|
|
|
watch([fetchError, serverResponse], ([error, response]) => {
|
|
hasError.value = !!error || !response;
|
|
});
|
|
|
|
const serverList = computed(() => {
|
|
if (!serverResponse.value) return [];
|
|
return serverResponse.value.servers;
|
|
});
|
|
|
|
const searchInput = ref("");
|
|
|
|
const fuse = computed(() => {
|
|
if (serverList.value.length === 0) return null;
|
|
return new Fuse(serverList.value, {
|
|
keys: ["name", "loader", "mc_version", "game", "state"],
|
|
includeScore: true,
|
|
threshold: 0.4,
|
|
});
|
|
});
|
|
|
|
const filteredData = computed(() => {
|
|
if (!searchInput.value.trim()) {
|
|
return serverList.value;
|
|
}
|
|
return fuse.value ? fuse.value.search(searchInput.value).map((result) => result.item) : [];
|
|
});
|
|
|
|
const previousServerList = ref<Server[]>([]);
|
|
const refreshCount = ref(0);
|
|
|
|
const checkForNewServers = async () => {
|
|
await refresh();
|
|
refreshCount.value += 1;
|
|
if (JSON.stringify(previousServerList.value) !== JSON.stringify(serverList.value)) {
|
|
isPollingForNewServers.value = false;
|
|
clearInterval(intervalId);
|
|
} else if (refreshCount.value >= 5) {
|
|
isPollingForNewServers.value = false;
|
|
clearInterval(intervalId);
|
|
}
|
|
};
|
|
|
|
let intervalId: ReturnType<typeof setInterval> | undefined;
|
|
|
|
onMounted(() => {
|
|
if (route.query.redirect_status === "succeeded") {
|
|
isPollingForNewServers.value = true;
|
|
previousServerList.value = [...serverList.value];
|
|
intervalId = setInterval(checkForNewServers, 5000);
|
|
}
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
if (intervalId) {
|
|
clearInterval(intervalId);
|
|
}
|
|
});
|
|
</script>
|