Skip to content

Commit 742c0ed

Browse files
thewander02ferothefoxGeometrically
authored
Paper and Purpur + Backups (#3004)
* feat: init selecting paper+purpur on purchase flow Signed-off-by: Evan Song <theevansong@gmail.com> * feat: properly implement Paper/Purpur in Platform Signed-off-by: Evan Song <theevansong@gmail.com> * chore: correct wording Signed-off-by: Evan Song <theevansong@gmail.com> * feat: redo platform modal Signed-off-by: Evan Song <theevansong@gmail.com> * Switch to HCaptcha for Auth-related captchas (#2945) * Switch to HCaptcha for Auth-related captchas * run fmt * fix hcaptcha not loading * fix: more robust loader dropdown logic Signed-off-by: Evan Song <theevansong@gmail.com> * fix: handle "not yet supported" install err Signed-off-by: Evan Song <theevansong@gmail.com> * chore: fix icon kerfuffles Signed-off-by: Evan Song <theevansong@gmail.com> * chore: improve vanilla install modal title Signed-off-by: Evan Song <theevansong@gmail.com> * fix: spacing Signed-off-by: Evan Song <theevansong@gmail.com> * chore: improve no loader state Signed-off-by: Evan Song <theevansong@gmail.com> * fix: type error Signed-off-by: Evan Song <theevansong@gmail.com> * chore: adjust mod version modal title Signed-off-by: Evan Song <theevansong@gmail.com> * chore: adjust modpack warning copy Signed-off-by: Evan Song <theevansong@gmail.com> * feat: vanilla empty state in content page Signed-off-by: Evan Song <theevansong@gmail.com> * chore: adjust copy Signed-off-by: Evan Song <theevansong@gmail.com> * chore: update icon Signed-off-by: Evan Song <theevansong@gmail.com> * fix: loader type Signed-off-by: Evan Song <theevansong@gmail.com> * fix: loader type Signed-off-by: Evan Song <theevansong@gmail.com> * feat: always show dropdown if possible Signed-off-by: Evan Song <theevansong@gmail.com> * chore: improve spacing Signed-off-by: Evan Song <theevansong@gmail.com> * chore: appear disabled Signed-off-by: Evan Song <theevansong@gmail.com> * h Signed-off-by: Evan Song <theevansong@gmail.com> * chore: if reinstalling, show it on the modal title Signed-off-by: Evan Song <theevansong@gmail.com> * feat: put it in the dropdown, they said Signed-off-by: Evan Song <theevansong@gmail.com> * chore: adjust style Signed-off-by: Evan Song <theevansong@gmail.com> * chore: sort paper-purpur versions desc Signed-off-by: Evan Song <theevansong@gmail.com> * fix: do not consider backup limit in reinstall prompt Signed-off-by: Evan Song <theevansong@gmail.com> * feat: backup locking, plugin support * fix: content type error Signed-off-by: Evan Song <theevansong@gmail.com> * fix: casing Signed-off-by: Evan Song <theevansong@gmail.com> * fix: plugins pt 2 * feat: backups, mrpack * fix: type errors come on Signed-off-by: Evan Song <theevansong@gmail.com> * fix: spacing Signed-off-by: Evan Song <theevansong@gmail.com> * fix: type maxing * chore: show copy button on allocation rows Signed-off-by: Evan Song <theevansong@gmail.com> * feat: suspend improvement --------- Signed-off-by: Evan Song <theevansong@gmail.com> Co-authored-by: Evan Song <theevansong@gmail.com> Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com> Co-authored-by: Jai A <jaiagr+gpg@pm.me> Co-authored-by: Evan Song <52982404+ferothefox@users.noreply.github.com>
1 parent eff3189 commit 742c0ed

File tree

26 files changed

+951
-247
lines changed

26 files changed

+951
-247
lines changed

apps/frontend/src/components/ui/servers/BackupCreateModal.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import { ButtonStyled, NewModal } from "@modrinth/ui";
4444
import { PlusIcon, XIcon, InfoIcon } from "@modrinth/assets";
4545
4646
const props = defineProps<{
47-
server: Server<["general", "mods", "backups", "network", "startup", "ws", "fs"]>;
47+
server: Server<["general", "content", "backups", "network", "startup", "ws", "fs"]>;
4848
}>();
4949
5050
const emit = defineEmits(["backupCreated"]);

apps/frontend/src/components/ui/servers/BackupSettingsModal.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ const modal = ref<InstanceType<typeof NewModal>>();
104104
105105
const initialSettings = ref<{ interval: number; enabled: boolean } | null>(null);
106106
const autoBackupEnabled = ref(false);
107-
const autoBackupInterval = ref(1);
107+
const autoBackupInterval = ref(6);
108108
const isLoadingSettings = ref(true);
109109
const isSaving = ref(false);
110110
@@ -134,7 +134,7 @@ const fetchSettings = async () => {
134134
const settings = await props.server.backups?.getAutoBackup();
135135
initialSettings.value = settings as { interval: number; enabled: boolean };
136136
autoBackupEnabled.value = settings?.enabled ?? false;
137-
autoBackupInterval.value = settings?.interval || 1;
137+
autoBackupInterval.value = settings?.interval || 6;
138138
} catch (error) {
139139
console.error("Error fetching backup settings:", error);
140140
addNotification({

apps/frontend/src/components/ui/servers/LoaderSelector.vue

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,60 @@
11
<template>
2-
<div
3-
v-for="loader in loaders"
4-
:key="loader.name"
5-
class="group relative flex items-center justify-between rounded-2xl p-2 pr-2.5 hover:bg-bg"
6-
>
7-
<div class="flex items-center gap-4">
2+
<div class="flex w-full flex-col gap-1 rounded-2xl bg-table-alternateRow p-2">
3+
<div
4+
v-for="loader in vanillaLoaders"
5+
:key="loader.name"
6+
class="group relative flex items-center justify-between rounded-2xl p-2 pr-2.5 hover:bg-bg"
7+
>
8+
<UiServersLoaderSelectorCard
9+
:loader="loader"
10+
:is-current="isCurrentLoader(loader.name)"
11+
:loader-version="data.loader_version"
12+
:current-loader="data.loader"
13+
@select="selectLoader"
14+
/>
15+
</div>
16+
</div>
17+
18+
<div class="mt-4">
19+
<h2 class="mb-2 px-2 text-lg font-bold text-contrast">Mod loaders</h2>
20+
<div class="flex w-full flex-col gap-1 rounded-2xl bg-table-alternateRow p-2">
821
<div
9-
class="grid size-10 place-content-center rounded-xl border-[1px] border-solid border-button-border bg-button-bg shadow-sm"
10-
:class="isCurrentLoader(loader.name) ? '[&&]:bg-bg-green' : ''"
22+
v-for="loader in modLoaders"
23+
:key="loader.name"
24+
class="group relative flex items-center justify-between rounded-2xl p-2 pr-2.5 hover:bg-bg"
1125
>
12-
<UiServersIconsLoaderIcon
13-
:loader="loader.name"
14-
class="[&&]:size-6"
15-
:class="isCurrentLoader(loader.name) ? 'text-brand' : ''"
26+
<UiServersLoaderSelectorCard
27+
:loader="loader"
28+
:is-current="isCurrentLoader(loader.name)"
29+
:loader-version="data.loader_version"
30+
:current-loader="data.loader"
31+
@select="selectLoader"
1632
/>
1733
</div>
18-
<div class="flex flex-col gap-0.5">
19-
<div class="flex flex-row items-center gap-2">
20-
<h1 class="m-0 text-xl font-bold leading-none text-contrast">
21-
{{ loader.displayName }}
22-
</h1>
23-
<span
24-
v-if="isCurrentLoader(loader.name)"
25-
class="hidden items-center gap-1 rounded-full bg-bg-green p-1 px-1.5 text-xs font-semibold text-brand sm:flex"
26-
>
27-
<CheckIcon class="h-4 w-4" />
28-
Current
29-
</span>
30-
</div>
31-
<p v-if="isCurrentLoader(loader.name)" class="m-0 text-xs text-secondary">
32-
{{ data.loader_version }}
33-
</p>
34-
</div>
3534
</div>
35+
</div>
3636

37-
<ButtonStyled>
38-
<button @click="selectLoader(loader.name)">
39-
<DownloadIcon class="h-5 w-5" />
40-
{{ isCurrentLoader(loader.name) ? "Reinstall" : "Install" }}
41-
</button>
42-
</ButtonStyled>
37+
<div class="mt-4">
38+
<h2 class="mb-2 px-2 text-lg font-bold text-contrast">Plugin loaders</h2>
39+
<div class="flex w-full flex-col gap-1 rounded-2xl bg-table-alternateRow p-2">
40+
<div
41+
v-for="loader in pluginLoaders"
42+
:key="loader.name"
43+
class="group relative flex items-center justify-between rounded-2xl p-2 pr-2.5 hover:bg-bg"
44+
>
45+
<UiServersLoaderSelectorCard
46+
:loader="loader"
47+
:is-current="isCurrentLoader(loader.name)"
48+
:loader-version="data.loader_version"
49+
:current-loader="data.loader"
50+
@select="selectLoader"
51+
/>
52+
</div>
53+
</div>
4354
</div>
4455
</template>
4556

4657
<script setup lang="ts">
47-
import { CheckIcon, DownloadIcon } from "@modrinth/assets";
48-
import { ButtonStyled } from "@modrinth/ui";
49-
5058
const props = defineProps<{
5159
data: {
5260
loader: string | null;
@@ -58,14 +66,20 @@ const emit = defineEmits<{
5866
(e: "selectLoader", loader: string): void;
5967
}>();
6068
61-
const loaders = [
62-
{ name: "Vanilla" as const, displayName: "Vanilla" },
69+
const vanillaLoaders = [{ name: "Vanilla" as const, displayName: "Vanilla" }];
70+
71+
const modLoaders = [
6372
{ name: "Fabric" as const, displayName: "Fabric" },
6473
{ name: "Quilt" as const, displayName: "Quilt" },
6574
{ name: "Forge" as const, displayName: "Forge" },
6675
{ name: "NeoForge" as const, displayName: "NeoForge" },
6776
];
6877
78+
const pluginLoaders = [
79+
{ name: "Paper" as const, displayName: "Paper" },
80+
{ name: "Purpur" as const, displayName: "Purpur" },
81+
];
82+
6983
const isCurrentLoader = (loaderName: string) => {
7084
return props.data.loader?.toLowerCase() === loaderName.toLowerCase();
7185
};
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<template>
2+
<div class="flex w-full items-center justify-between">
3+
<div class="flex items-center gap-4">
4+
<div
5+
class="grid size-10 place-content-center rounded-xl border-[1px] border-solid border-button-border bg-button-bg shadow-sm"
6+
:class="isCurrentLoader ? '[&&]:bg-bg-green' : ''"
7+
>
8+
<UiServersIconsLoaderIcon
9+
:loader="loader.name"
10+
class="[&&]:size-6"
11+
:class="isCurrentLoader ? 'text-brand' : ''"
12+
/>
13+
</div>
14+
<div class="flex flex-col gap-0.5">
15+
<div class="flex flex-row items-center gap-2">
16+
<h1 class="m-0 text-xl font-bold leading-none text-contrast">
17+
{{ loader.displayName }}
18+
</h1>
19+
<span
20+
v-if="isCurrentLoader"
21+
class="hidden items-center gap-1 rounded-full bg-bg-green p-1 px-1.5 text-xs font-semibold text-brand sm:flex"
22+
>
23+
<CheckIcon class="h-4 w-4" />
24+
Current
25+
</span>
26+
</div>
27+
<p v-if="isCurrentLoader" class="m-0 text-xs text-secondary">
28+
{{ loaderVersion }}
29+
</p>
30+
</div>
31+
</div>
32+
33+
<ButtonStyled>
34+
<button @click="onSelect">
35+
<DownloadIcon class="h-5 w-5" />
36+
{{ isCurrentLoader ? "Reinstall" : "Install" }}
37+
</button>
38+
</ButtonStyled>
39+
</div>
40+
</template>
41+
42+
<script setup lang="ts">
43+
import { CheckIcon, DownloadIcon } from "@modrinth/assets";
44+
import { ButtonStyled } from "@modrinth/ui";
45+
46+
interface LoaderInfo {
47+
name: "Vanilla" | "Fabric" | "Forge" | "Quilt" | "Paper" | "NeoForge" | "Purpur";
48+
displayName: string;
49+
}
50+
51+
interface Props {
52+
loader: LoaderInfo;
53+
currentLoader: string | null;
54+
loaderVersion: string | null;
55+
}
56+
57+
const props = defineProps<Props>();
58+
59+
const emit = defineEmits<{
60+
(e: "select", loader: string): void;
61+
}>();
62+
63+
const isCurrentLoader = computed(() => {
64+
return props.currentLoader?.toLowerCase() === props.loader.name.toLowerCase();
65+
});
66+
67+
const onSelect = () => {
68+
emit("select", props.loader.name);
69+
};
70+
</script>

apps/frontend/src/components/ui/servers/ServerListing.vue

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
11
<template>
2-
<NuxtLink class="contents" :to="`/servers/manage/${props.server_id}`">
2+
<NuxtLink
3+
class="contents"
4+
:to="status === 'suspended' ? '' : `/servers/manage/${props.server_id}`"
5+
>
36
<div
4-
class="flex cursor-pointer flex-row items-center overflow-x-hidden rounded-3xl bg-bg-raised p-4 transition-transform duration-100 active:scale-95"
7+
v-tooltip="
8+
status === 'suspended'
9+
? `This server is suspended visit the billing page to learn more`
10+
: ''
11+
"
12+
class="flex cursor-pointer flex-row items-center overflow-x-hidden rounded-3xl bg-bg-raised p-4 transition-transform duration-100"
13+
:class="status === 'suspended' ? 'opacity-50' : 'active:scale-95'"
514
data-pyro-server-listing
615
:data-pyro-server-listing-id="server_id"
716
>
8-
<UiServersServerIcon :image="image" />
17+
<UiServersServerIcon v-if="status !== 'suspended'" :image="image" />
18+
<div
19+
v-else
20+
class="bg-bg-secondary flex size-24 items-center justify-center rounded-xl border-[1px] border-solid border-button-border bg-button-bg shadow-sm"
21+
>
22+
<LockIcon class="size-20 text-secondary" />
23+
</div>
924
<div class="ml-8 flex flex-col gap-2.5">
1025
<div class="flex flex-row items-center gap-2">
1126
<h2 class="m-0 text-xl font-bold text-contrast">{{ name }}</h2>
@@ -40,7 +55,7 @@
4055
</template>
4156

4257
<script setup lang="ts">
43-
import { ChevronRightIcon } from "@modrinth/assets";
58+
import { ChevronRightIcon, LockIcon } from "@modrinth/assets";
4459
import type { Project, Server } from "~/types/servers";
4560
4661
const props = defineProps<Partial<Server>>();

apps/frontend/src/components/ui/servers/icons/LoaderIcon.vue

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,65 @@
153153
/>
154154
</g>
155155
</svg>
156+
<svg
157+
v-else-if="loader === 'Purpur'"
158+
xml:space="preserve"
159+
fill-rule="evenodd"
160+
stroke-linecap="round"
161+
stroke-linejoin="round"
162+
stroke-miterlimit="1.5"
163+
clip-rule="evenodd"
164+
viewBox="0 0 24 24"
165+
>
166+
<defs>
167+
<path
168+
id="purpur"
169+
fill="none"
170+
stroke="currentColor"
171+
stroke-width="1.68"
172+
d="m264 41.95 8-4v8l-8 4v-8Z"
173+
></path>
174+
</defs>
175+
<path fill="none" d="M0 0h24v24H0z"></path>
176+
<path
177+
fill="none"
178+
stroke="currentColor"
179+
stroke-width="1.77"
180+
d="m264 29.95-8 4 8 4.42 8-4.42-8-4Z"
181+
transform="matrix(1.125 0 0 1.1372 -285 -31.69)"
182+
></path>
183+
<path
184+
fill="none"
185+
stroke="currentColor"
186+
stroke-width="1.77"
187+
d="m272 38.37-8 4.42-8-4.42"
188+
transform="matrix(1.125 0 0 1.1372 -285 -31.69)"
189+
></path>
190+
<path
191+
fill="none"
192+
stroke="currentColor"
193+
stroke-width="1.77"
194+
d="m260 31.95 8 4.21V45"
195+
transform="matrix(1.125 0 0 1.1372 -285 -31.69)"
196+
></path>
197+
<path
198+
fill="none"
199+
stroke="currentColor"
200+
stroke-width="1.77"
201+
d="M260 45v-8.84l8-4.21"
202+
transform="matrix(1.125 0 0 1.1372 -285 -31.69)"
203+
></path>
204+
<use
205+
xlink:href="#purpur"
206+
stroke-width="1.68"
207+
transform="matrix(1.125 0 0 1.2569 -285 -40.78)"
208+
></use>
209+
<use
210+
xlink:href="#purpur"
211+
stroke-width="1.68"
212+
transform="matrix(-1.125 0 0 1.2569 309 -40.78)"
213+
></use>
214+
</svg>
156215
<svg v-else-if="loader === 'Vanilla'" viewBox="0 0 20 20" fill="currentColor">
157216
<path
158217
fill-rule="evenodd"
@@ -165,8 +224,9 @@
165224

166225
<script setup lang="ts">
167226
import { LoaderIcon } from "@modrinth/assets";
227+
import type { Loaders } from "~/types/servers";
168228
169229
defineProps<{
170-
loader: "Fabric" | "Quilt" | "Forge" | "NeoForge" | "Paper" | "Spigot" | "Bukkit" | "Vanilla";
230+
loader: Loaders;
171231
}>();
172232
</script>

0 commit comments

Comments
 (0)