Add colors for new loaders, reduce utility redundancy (#3820)

* Add colors to some newer loaders

* Make loader formatting consistent everywhere, remove redundant utilities
This commit is contained in:
Prospector 2025-06-21 07:35:42 -07:00 committed by GitHub
parent cc34e69524
commit ced073d26c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 87 additions and 132 deletions

View File

@ -57,7 +57,7 @@
<div class="table-cell"> <div class="table-cell">
<BoxIcon /> <BoxIcon />
<span>{{ <span>{{
$formatProjectType( formatProjectType(
$getProjectTypeForDisplay( $getProjectTypeForDisplay(
project.project_types?.[0] ?? "project", project.project_types?.[0] ?? "project",
project.loaders, project.loaders,
@ -111,6 +111,7 @@
<script setup> <script setup>
import { BoxIcon, SettingsIcon, TransferIcon, XIcon } from "@modrinth/assets"; import { BoxIcon, SettingsIcon, TransferIcon, XIcon } from "@modrinth/assets";
import { Button, Modal, Checkbox, CopyCode, Avatar } from "@modrinth/ui"; import { Button, Modal, Checkbox, CopyCode, Avatar } from "@modrinth/ui";
import { formatProjectType } from "@modrinth/utils";
const modalOpen = ref(null); const modalOpen = ref(null);

View File

@ -118,7 +118,7 @@ import {
ScaleIcon, ScaleIcon,
DropdownIcon, DropdownIcon,
} from "@modrinth/assets"; } from "@modrinth/assets";
import { formatProjectType } from "~/plugins/shorthands.js"; import { formatProjectType } from "@modrinth/utils";
import { acceptTeamInvite, removeTeamMember } from "~/helpers/teams.js"; import { acceptTeamInvite, removeTeamMember } from "~/helpers/teams.js";
const props = defineProps({ const props = defineProps({

View File

@ -11,8 +11,8 @@
<div class="stacked"> <div class="stacked">
<span class="title">{{ report.project.title }}</span> <span class="title">{{ report.project.title }}</span>
<span>{{ <span>{{
$formatProjectType( formatProjectType(
$getProjectTypeForUrl(report.project.project_type, report.project.loaders), getProjectTypeForUrl(report.project.project_type, report.project.loaders),
) )
}}</span> }}</span>
</div> </div>
@ -53,8 +53,8 @@
<div class="stacked"> <div class="stacked">
<span class="title">{{ report.project.title }}</span> <span class="title">{{ report.project.title }}</span>
<span>{{ <span>{{
$formatProjectType( formatProjectType(
$getProjectTypeForUrl(report.project.project_type, report.project.loaders), getProjectTypeForUrl(report.project.project_type, report.project.loaders),
) )
}}</span> }}</span>
</div> </div>
@ -105,8 +105,10 @@
<script setup> <script setup>
import { ReportIcon, UnknownIcon, VersionIcon } from "@modrinth/assets"; import { ReportIcon, UnknownIcon, VersionIcon } from "@modrinth/assets";
import { Avatar, Badge, CopyCode, useRelativeTime } from "@modrinth/ui"; import { Avatar, Badge, CopyCode, useRelativeTime } from "@modrinth/ui";
import { formatProjectType } from "@modrinth/utils";
import { renderHighlightedString } from "~/helpers/highlight.js"; import { renderHighlightedString } from "~/helpers/highlight.js";
import ThreadSummary from "~/components/ui/thread/ThreadSummary.vue"; import ThreadSummary from "~/components/ui/thread/ThreadSummary.vue";
import { getProjectTypeForUrl } from "~/helpers/projects.js";
const formatRelativeTime = useRelativeTime(); const formatRelativeTime = useRelativeTime();

View File

@ -4,12 +4,14 @@
<span <span
v-for="category in categoriesFiltered" v-for="category in categoriesFiltered"
:key="category.name" :key="category.name"
v-html="category.icon + $formatCategory(category.name)" v-html="category.icon + formatCategory(category.name)"
/> />
</div> </div>
</template> </template>
<script> <script>
import { formatCategory } from "@modrinth/utils";
export default { export default {
props: { props: {
categories: { categories: {
@ -38,6 +40,7 @@ export default {
); );
}, },
}, },
methods: { formatCategory },
}; };
</script> </script>

View File

@ -1,4 +1,4 @@
import { formatBytes } from "~/plugins/shorthands.js"; import { formatBytes } from "@modrinth/utils";
export const fileIsValid = (file, validationOptions) => { export const fileIsValid = (file, validationOptions) => {
const { maxSize, alertOnInvalid } = validationOptions; const { maxSize, alertOnInvalid } = validationOptions;

View File

@ -875,7 +875,14 @@ import {
useRelativeTime, useRelativeTime,
} from "@modrinth/ui"; } from "@modrinth/ui";
import VersionSummary from "@modrinth/ui/src/components/version/VersionSummary.vue"; import VersionSummary from "@modrinth/ui/src/components/version/VersionSummary.vue";
import { formatCategory, isRejected, isStaff, isUnderReview, renderString } from "@modrinth/utils"; import {
formatCategory,
formatProjectType,
isRejected,
isStaff,
isUnderReview,
renderString,
} from "@modrinth/utils";
import { navigateTo } from "#app"; import { navigateTo } from "#app";
import dayjs from "dayjs"; import dayjs from "dayjs";
import Accordion from "~/components/ui/Accordion.vue"; import Accordion from "~/components/ui/Accordion.vue";
@ -1286,7 +1293,7 @@ featuredVersions.value.sort((a, b) => {
}); });
const projectTypeDisplay = computed(() => const projectTypeDisplay = computed(() =>
data.$formatProjectType( formatProjectType(
data.$getProjectTypeForDisplay(project.value.project_type, project.value.loaders), data.$getProjectTypeForDisplay(project.value.project_type, project.value.loaders),
), ),
); );

View File

@ -104,7 +104,7 @@
<span class="label__title">Client-side</span> <span class="label__title">Client-side</span>
<span class="label__description"> <span class="label__description">
Select based on if the Select based on if the
{{ $formatProjectType(project.project_type).toLowerCase() }} has functionality on the {{ formatProjectType(project.project_type).toLowerCase() }} has functionality on the
client side. Just because a mod works in Singleplayer doesn't mean it has actual client side. Just because a mod works in Singleplayer doesn't mean it has actual
client-side functionality. client-side functionality.
</span> </span>
@ -128,7 +128,7 @@
<span class="label__title">Server-side</span> <span class="label__title">Server-side</span>
<span class="label__description"> <span class="label__description">
Select based on if the Select based on if the
{{ $formatProjectType(project.project_type).toLowerCase() }} has functionality on the {{ formatProjectType(project.project_type).toLowerCase() }} has functionality on the
<strong>logical</strong> server. Remember that Singleplayer contains an integrated <strong>logical</strong> server. Remember that Singleplayer contains an integrated
server. server.
</span> </span>
@ -239,7 +239,7 @@
</template> </template>
<script setup> <script setup>
import { formatProjectStatus } from "@modrinth/utils"; import { formatProjectStatus, formatProjectType } from "@modrinth/utils";
import { UploadIcon, SaveIcon, TrashIcon, XIcon, IssuesIcon, CheckIcon } from "@modrinth/assets"; import { UploadIcon, SaveIcon, TrashIcon, XIcon, IssuesIcon, CheckIcon } from "@modrinth/assets";
import { Multiselect } from "vue-multiselect"; import { Multiselect } from "vue-multiselect";
import { ConfirmModal, Avatar } from "@modrinth/ui"; import { ConfirmModal, Avatar } from "@modrinth/ui";

View File

@ -8,7 +8,7 @@
</div> </div>
<p> <p>
Accurate tagging is important to help people find your Accurate tagging is important to help people find your
{{ $formatProjectType(project.project_type).toLowerCase() }}. Make sure to select all tags {{ formatProjectType(project.project_type).toLowerCase() }}. Make sure to select all tags
that apply. that apply.
</p> </p>
<p v-if="project.versions.length === 0" class="known-errors"> <p v-if="project.versions.length === 0" class="known-errors">
@ -18,25 +18,25 @@
<template v-for="header in Object.keys(categoryLists)" :key="`categories-${header}`"> <template v-for="header in Object.keys(categoryLists)" :key="`categories-${header}`">
<div class="label"> <div class="label">
<h4> <h4>
<span class="label__title">{{ $formatCategoryHeader(header) }}</span> <span class="label__title">{{ formatCategoryHeader(header) }}</span>
</h4> </h4>
<span class="label__description"> <span class="label__description">
<template v-if="header === 'categories'"> <template v-if="header === 'categories'">
Select all categories that reflect the themes or function of your Select all categories that reflect the themes or function of your
{{ $formatProjectType(project.project_type).toLowerCase() }}. {{ formatProjectType(project.project_type).toLowerCase() }}.
</template> </template>
<template v-else-if="header === 'features'"> <template v-else-if="header === 'features'">
Select all of the features that your Select all of the features that your
{{ $formatProjectType(project.project_type).toLowerCase() }} makes use of. {{ formatProjectType(project.project_type).toLowerCase() }} makes use of.
</template> </template>
<template v-else-if="header === 'resolutions'"> <template v-else-if="header === 'resolutions'">
Select the resolution(s) of textures in your Select the resolution(s) of textures in your
{{ $formatProjectType(project.project_type).toLowerCase() }}. {{ formatProjectType(project.project_type).toLowerCase() }}.
</template> </template>
<template v-else-if="header === 'performance impact'"> <template v-else-if="header === 'performance impact'">
Select the realistic performance impact of your Select the realistic performance impact of your
{{ $formatProjectType(project.project_type).toLowerCase() }}. Select multiple if the {{ formatProjectType(project.project_type).toLowerCase() }}. Select multiple if the
{{ $formatProjectType(project.project_type).toLowerCase() }} is configurable to {{ formatProjectType(project.project_type).toLowerCase() }} is configurable to
different levels of performance impact. different levels of performance impact.
</template> </template>
</span> </span>
@ -46,7 +46,7 @@
v-for="category in categoryLists[header]" v-for="category in categoryLists[header]"
:key="`category-${header}-${category.name}`" :key="`category-${header}-${category.name}`"
:model-value="selectedTags.includes(category)" :model-value="selectedTags.includes(category)"
:description="$formatCategory(category.name)" :description="formatCategory(category.name)"
class="category-selector" class="category-selector"
@update:model-value="toggleCategory(category)" @update:model-value="toggleCategory(category)"
> >
@ -57,7 +57,7 @@
class="icon" class="icon"
v-html="category.icon" v-html="category.icon"
/> />
<span aria-hidden="true"> {{ $formatCategory(category.name) }}</span> <span aria-hidden="true"> {{ formatCategory(category.name) }}</span>
</div> </div>
</Checkbox> </Checkbox>
</div> </div>
@ -80,7 +80,7 @@
:key="`featured-category-${category.name}`" :key="`featured-category-${category.name}`"
class="category-selector" class="category-selector"
:model-value="featuredTags.includes(category)" :model-value="featuredTags.includes(category)"
:description="$formatCategory(category.name)" :description="formatCategory(category.name)"
:disabled="featuredTags.length >= 3 && !featuredTags.includes(category)" :disabled="featuredTags.length >= 3 && !featuredTags.includes(category)"
@update:model-value="toggleFeaturedCategory(category)" @update:model-value="toggleFeaturedCategory(category)"
> >
@ -91,7 +91,7 @@
class="icon" class="icon"
v-html="category.icon" v-html="category.icon"
/> />
<span aria-hidden="true"> {{ $formatCategory(category.name) }}</span> <span aria-hidden="true"> {{ formatCategory(category.name) }}</span>
</div> </div>
</Checkbox> </Checkbox>
</div> </div>
@ -114,6 +114,7 @@
<script> <script>
import { StarIcon, SaveIcon } from "@modrinth/assets"; import { StarIcon, SaveIcon } from "@modrinth/assets";
import { formatCategory, formatCategoryHeader, formatProjectType } from "@modrinth/utils";
import Checkbox from "~/components/ui/Checkbox.vue"; import Checkbox from "~/components/ui/Checkbox.vue";
export default defineNuxtComponent({ export default defineNuxtComponent({
@ -222,6 +223,9 @@ export default defineNuxtComponent({
}, },
}, },
methods: { methods: {
formatProjectType,
formatCategoryHeader,
formatCategory,
toggleCategory(category) { toggleCategory(category) {
if (this.selectedTags.includes(category)) { if (this.selectedTags.includes(category)) {
this.selectedTags = this.selectedTags.filter((x) => x !== category); this.selectedTags = this.selectedTags.filter((x) => x !== category);

View File

@ -144,7 +144,7 @@
<div v-else class="input-group"> <div v-else class="input-group">
<ButtonStyled v-if="primaryFile" color="brand"> <ButtonStyled v-if="primaryFile" color="brand">
<a <a
v-tooltip="primaryFile.filename + ' (' + $formatBytes(primaryFile.size) + ')'" v-tooltip="primaryFile.filename + ' (' + formatBytes(primaryFile.size) + ')'"
:href="primaryFile.url" :href="primaryFile.url"
@click="emit('onDownload')" @click="emit('onDownload')"
> >
@ -320,7 +320,7 @@
<FileIcon aria-hidden="true" /> <FileIcon aria-hidden="true" />
<span class="filename"> <span class="filename">
<strong>{{ replaceFile.name }}</strong> <strong>{{ replaceFile.name }}</strong>
<span class="file-size">({{ $formatBytes(replaceFile.size) }})</span> <span class="file-size">({{ formatBytes(replaceFile.size) }})</span>
</span> </span>
<FileInput <FileInput
class="iconified-button raised-button" class="iconified-button raised-button"
@ -345,7 +345,7 @@
<FileIcon aria-hidden="true" /> <FileIcon aria-hidden="true" />
<span class="filename"> <span class="filename">
<strong>{{ file.filename }}</strong> <strong>{{ file.filename }}</strong>
<span class="file-size">({{ $formatBytes(file.size) }})</span> <span class="file-size">({{ formatBytes(file.size) }})</span>
<span v-if="primaryFile.hashes.sha1 === file.hashes.sha1" class="file-type"> <span v-if="primaryFile.hashes.sha1 === file.hashes.sha1" class="file-type">
Primary Primary
</span> </span>
@ -412,7 +412,7 @@
<FileIcon aria-hidden="true" /> <FileIcon aria-hidden="true" />
<span class="filename"> <span class="filename">
<strong>{{ file.name }}</strong> <strong>{{ file.name }}</strong>
<span class="file-size">({{ $formatBytes(file.size) }})</span> <span class="file-size">({{ formatBytes(file.size) }})</span>
</span> </span>
<multiselect <multiselect
v-if="version.loaders.some((x) => tags.loaderData.dataPackLoaders.includes(x))" v-if="version.loaders.some((x) => tags.loaderData.dataPackLoaders.includes(x))"
@ -533,7 +533,7 @@
) )
.map((it) => it.name) .map((it) => it.name)
" "
:custom-label="(value) => $formatCategory(value)" :custom-label="formatCategory"
:loading="tags.loaders.length === 0" :loading="tags.loaders.length === 0"
:multiple="true" :multiple="true"
:searchable="true" :searchable="true"
@ -657,6 +657,7 @@ import {
ChevronRightIcon, ChevronRightIcon,
} from "@modrinth/assets"; } from "@modrinth/assets";
import { Multiselect } from "vue-multiselect"; import { Multiselect } from "vue-multiselect";
import { formatBytes, formatCategory } from "@modrinth/utils";
import { acceptFileFromProjectType } from "~/helpers/fileUtils.js"; import { acceptFileFromProjectType } from "~/helpers/fileUtils.js";
import { inferVersionInfo } from "~/helpers/infer.js"; import { inferVersionInfo } from "~/helpers/infer.js";
import { createDataPackVersion } from "~/helpers/package.js"; import { createDataPackVersion } from "~/helpers/package.js";
@ -962,6 +963,8 @@ export default defineNuxtComponent({
}, },
}, },
methods: { methods: {
formatBytes,
formatCategory,
async onImageUpload(file) { async onImageUpload(file) {
const response = await useImageUpload(file, { context: "version" }); const response = await useImageUpload(file, { context: "version" });

View File

@ -26,7 +26,7 @@
v-if="notifTypes.length > 1" v-if="notifTypes.length > 1"
v-model="selectedType" v-model="selectedType"
:items="notifTypes" :items="notifTypes"
:format-label="(x) => (x === 'all' ? 'All' : $formatProjectType(x).replace('_', ' ') + 's')" :format-label="(x) => (x === 'all' ? 'All' : formatProjectType(x).replace('_', ' ') + 's')"
:capitalize="false" :capitalize="false"
/> />
<p v-if="pending">Loading notifications...</p> <p v-if="pending">Loading notifications...</p>
@ -58,6 +58,7 @@
<script setup> <script setup>
import { Button, Pagination, Chips } from "@modrinth/ui"; import { Button, Pagination, Chips } from "@modrinth/ui";
import { HistoryIcon, CheckCheckIcon } from "@modrinth/assets"; import { HistoryIcon, CheckCheckIcon } from "@modrinth/assets";
import { formatProjectType } from "@modrinth/utils";
import { import {
fetchExtraNotificationData, fetchExtraNotificationData,
groupNotifications, groupNotifications,

View File

@ -239,7 +239,7 @@
<div> <div>
<nuxt-link <nuxt-link
tabindex="-1" tabindex="-1"
:to="`/${$getProjectTypeForUrl(project.project_type, project.loaders)}/${ :to="`/${getProjectTypeForUrl(project.project_type, project.loaders)}/${
project.slug ? project.slug : project.id project.slug ? project.slug : project.id
}`" }`"
> >
@ -261,7 +261,7 @@
<nuxt-link <nuxt-link
class="hover-link wrap-as-needed" class="hover-link wrap-as-needed"
:to="`/${$getProjectTypeForUrl(project.project_type, project.loaders)}/${ :to="`/${getProjectTypeForUrl(project.project_type, project.loaders)}/${
project.slug ? project.slug : project.id project.slug ? project.slug : project.id
}`" }`"
> >
@ -275,7 +275,7 @@
</div> </div>
<div> <div>
{{ $formatProjectType($getProjectTypeForUrl(project.project_type, project.loaders)) }} {{ formatProjectType(getProjectTypeForUrl(project.project_type, project.loaders)) }}
</div> </div>
<div> <div>
@ -285,7 +285,7 @@
<div> <div>
<ButtonStyled circular> <ButtonStyled circular>
<nuxt-link <nuxt-link
:to="`/${$getProjectTypeForUrl(project.project_type, project.loaders)}/${ :to="`/${getProjectTypeForUrl(project.project_type, project.loaders)}/${
project.slug ? project.slug : project.id project.slug ? project.slug : project.id
}/settings`" }/settings`"
> >
@ -321,9 +321,11 @@ import {
ProjectStatusBadge, ProjectStatusBadge,
commonMessages, commonMessages,
} from "@modrinth/ui"; } from "@modrinth/ui";
import { formatProjectType } from "@modrinth/utils";
import Modal from "~/components/ui/Modal.vue"; import Modal from "~/components/ui/Modal.vue";
import ModalCreation from "~/components/ui/ModalCreation.vue"; import ModalCreation from "~/components/ui/ModalCreation.vue";
import { getProjectTypeForUrl } from "~/helpers/projects.js";
export default defineNuxtComponent({ export default defineNuxtComponent({
components: { components: {
@ -395,6 +397,8 @@ export default defineNuxtComponent({
this.DELETE_PROJECT = 1 << 7; this.DELETE_PROJECT = 1 << 7;
}, },
methods: { methods: {
getProjectTypeForUrl,
formatProjectType,
updateDescending() { updateDescending() {
this.descending = !this.descending; this.descending = !this.descending;
this.projects = this.updateSort(this.projects, this.sortBy, this.descending); this.projects = this.updateSort(this.projects, this.sortBy, this.descending);

View File

@ -76,7 +76,7 @@
</span> </span>
<template v-if="payout.method"> <template v-if="payout.method">
<span></span> <span></span>
<span>{{ $formatWallet(payout.method) }} ({{ payout.method_address }})</span> <span>{{ formatWallet(payout.method) }} ({{ payout.method_address }})</span>
</template> </template>
</div> </div>
</div> </div>
@ -95,7 +95,7 @@
</template> </template>
<script setup> <script setup>
import { XIcon, PayPalIcon, UnknownIcon } from "@modrinth/assets"; import { XIcon, PayPalIcon, UnknownIcon } from "@modrinth/assets";
import { capitalizeString } from "@modrinth/utils"; import { capitalizeString, formatWallet } from "@modrinth/utils";
import { Badge, Breadcrumbs, DropdownSelect } from "@modrinth/ui"; import { Badge, Breadcrumbs, DropdownSelect } from "@modrinth/ui";
import dayjs from "dayjs"; import dayjs from "dayjs";
import TremendousIcon from "~/assets/images/external/tremendous.svg?component"; import TremendousIcon from "~/assets/images/external/tremendous.svg?component";

View File

@ -139,8 +139,8 @@
<template v-if="knownErrors.length === 0 && amount"> <template v-if="knownErrors.length === 0 && amount">
<Checkbox v-if="fees > 0" v-model="agreedFees" description="Consent to fee"> <Checkbox v-if="fees > 0" v-model="agreedFees" description="Consent to fee">
I acknowledge that an estimated I acknowledge that an estimated
{{ $formatMoney(fees) }} will be deducted from the amount I receive to cover {{ formatMoney(fees) }} will be deducted from the amount I receive to cover
{{ $formatWallet(selectedMethod.type) }} processing fees. {{ formatWallet(selectedMethod.type) }} processing fees.
</Checkbox> </Checkbox>
<Checkbox v-model="agreedTransfer" description="Confirm transfer"> <Checkbox v-model="agreedTransfer" description="Confirm transfer">
<template v-if="selectedMethod.type === 'tremendous'"> <template v-if="selectedMethod.type === 'tremendous'">
@ -149,7 +149,7 @@
</template> </template>
<template v-else> <template v-else>
I confirm that I am initiating a transfer to the following I confirm that I am initiating a transfer to the following
{{ $formatWallet(selectedMethod.type) }} account: {{ withdrawAccount }} {{ formatWallet(selectedMethod.type) }} account: {{ withdrawAccount }}
</template> </template>
</Checkbox> </Checkbox>
<Checkbox v-model="agreedTerms" class="rewards-checkbox"> <Checkbox v-model="agreedTerms" class="rewards-checkbox">
@ -198,6 +198,7 @@ import {
} from "@modrinth/assets"; } from "@modrinth/assets";
import { Chips, Checkbox, Breadcrumbs } from "@modrinth/ui"; import { Chips, Checkbox, Breadcrumbs } from "@modrinth/ui";
import { all } from "iso-3166-1"; import { all } from "iso-3166-1";
import { formatMoney, formatWallet } from "@modrinth/utils";
import VenmoIcon from "~/assets/images/external/venmo.svg?component"; import VenmoIcon from "~/assets/images/external/venmo.svg?component";
const auth = await useAuth(); const auth = await useAuth();
@ -360,9 +361,7 @@ async function withdraw() {
text: text:
selectedMethod.value.type === "tremendous" selectedMethod.value.type === "tremendous"
? "An email has been sent to your account with further instructions on how to redeem your payout!" ? "An email has been sent to your account with further instructions on how to redeem your payout!"
: `Payment has been sent to your ${data.$formatWallet( : `Payment has been sent to your ${formatWallet(selectedMethod.value.type)} account!`,
selectedMethod.value.type,
)} account!`,
type: "success", type: "success",
}); });
} catch (err) { } catch (err) {

View File

@ -32,7 +32,7 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { formatNumber } from "~/plugins/shorthands.js"; import { formatNumber } from "@modrinth/utils";
useHead({ useHead({
title: "Staff overview - Modrinth", title: "Staff overview - Modrinth",

View File

@ -5,7 +5,7 @@
<Chips <Chips
v-model="projectType" v-model="projectType"
:items="projectTypes" :items="projectTypes"
:format-label="(x) => (x === 'all' ? 'All' : $formatProjectType(x) + 's')" :format-label="(x) => (x === 'all' ? 'All' : formatProjectType(x) + 's')"
/> />
<button v-if="oldestFirst" class="iconified-button push-right" @click="oldestFirst = false"> <button v-if="oldestFirst" class="iconified-button push-right" @click="oldestFirst = false">
<SortDescendingIcon /> <SortDescendingIcon />
@ -56,7 +56,7 @@
<Avatar :src="project.icon_url" size="xs" no-shadow raised /> <Avatar :src="project.icon_url" size="xs" no-shadow raised />
<span class="stacked"> <span class="stacked">
<span class="title">{{ project.name }}</span> <span class="title">{{ project.name }}</span>
<span>{{ $formatProjectType(project.inferred_project_type) }}</span> <span>{{ formatProjectType(project.inferred_project_type) }}</span>
</span> </span>
</nuxt-link> </nuxt-link>
</div> </div>
@ -114,7 +114,7 @@ import {
IssuesIcon, IssuesIcon,
ScaleIcon, ScaleIcon,
} from "@modrinth/assets"; } from "@modrinth/assets";
import { formatProjectType } from "~/plugins/shorthands.js"; import { formatProjectType } from "@modrinth/utils";
import { asEncodedJsonArray, fetchSegmented } from "~/utils/fetch-helpers.ts"; import { asEncodedJsonArray, fetchSegmented } from "~/utils/fetch-helpers.ts";
useHead({ useHead({

View File

@ -272,7 +272,7 @@
<div class="table-cell"> <div class="table-cell">
<BoxIcon /> <BoxIcon />
<span>{{ <span>{{
$formatProjectType( formatProjectType(
$getProjectTypeForDisplay(project.project_types[0] ?? "project", project.loaders), $getProjectTypeForDisplay(project.project_types[0] ?? "project", project.loaders),
) )
}}</span> }}</span>
@ -313,6 +313,7 @@ import {
} from "@modrinth/assets"; } from "@modrinth/assets";
import { Button, Modal, Avatar, CopyCode, Badge, Checkbox, commonMessages } from "@modrinth/ui"; import { Button, Modal, Avatar, CopyCode, Badge, Checkbox, commonMessages } from "@modrinth/ui";
import { formatProjectType } from "@modrinth/utils";
import ModalCreation from "~/components/ui/ModalCreation.vue"; import ModalCreation from "~/components/ui/ModalCreation.vue";
import OrganizationProjectTransferModal from "~/components/ui/OrganizationProjectTransferModal.vue"; import OrganizationProjectTransferModal from "~/components/ui/OrganizationProjectTransferModal.vue";

View File

@ -200,9 +200,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { CodeIcon, RadioButtonCheckedIcon, RadioButtonIcon } from "@modrinth/assets"; import { CodeIcon, RadioButtonCheckedIcon, RadioButtonIcon } from "@modrinth/assets";
import { Button, ThemeSelector } from "@modrinth/ui"; import { Button, ThemeSelector } from "@modrinth/ui";
import { formatProjectType } from "@modrinth/utils";
import MessageBanner from "~/components/ui/MessageBanner.vue"; import MessageBanner from "~/components/ui/MessageBanner.vue";
import type { DisplayLocation } from "~/plugins/cosmetics"; import type { DisplayLocation } from "~/plugins/cosmetics";
import { formatProjectType } from "~/plugins/shorthands.js";
import { isDarkTheme, type Theme } from "~/plugins/theme/index.ts"; import { isDarkTheme, type Theme } from "~/plugins/theme/index.ts";
useHead({ useHead({

View File

@ -13,11 +13,6 @@ export default defineNuxtPlugin((nuxtApp) => {
return cosmeticsStore.externalLinksNewTab ? "_blank" : ""; return cosmeticsStore.externalLinksNewTab ? "_blank" : "";
}); });
nuxtApp.provide("formatBytes", formatBytes);
nuxtApp.provide("formatWallet", formatWallet);
nuxtApp.provide("formatProjectType", formatProjectType);
nuxtApp.provide("formatCategory", formatCategory);
nuxtApp.provide("formatCategoryHeader", formatCategoryHeader);
/* /*
Only use on the complete list of versions for a project, partial lists will generate Only use on the complete list of versions for a project, partial lists will generate
@ -156,89 +151,10 @@ export const formatMoney = (number, abbreviate = false) => {
} }
}; };
export const formatBytes = (bytes, decimals = 2) => {
if (bytes === 0) {
return "0 Bytes";
}
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ["Bytes", "KiB", "MiB", "GiB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
};
export const capitalizeString = (name) => { export const capitalizeString = (name) => {
return name ? name.charAt(0).toUpperCase() + name.slice(1) : name; return name ? name.charAt(0).toUpperCase() + name.slice(1) : name;
}; };
export const formatWallet = (name) => {
if (name === "paypal") {
return "PayPal";
}
return capitalizeString(name);
};
export const formatProjectType = (name) => {
if (name === "resourcepack") {
return "Resource Pack";
} else if (name === "datapack") {
return "Data Pack";
}
return capitalizeString(name);
};
export const formatCategory = (name) => {
if (name === "modloader") {
return "Risugami's ModLoader";
} else if (name === "bungeecord") {
return "BungeeCord";
} else if (name === "liteloader") {
return "LiteLoader";
} else if (name === "neoforge") {
return "NeoForge";
} else if (name === "game-mechanics") {
return "Game Mechanics";
} else if (name === "worldgen") {
return "World Generation";
} else if (name === "core-shaders") {
return "Core Shaders";
} else if (name === "gui") {
return "GUI";
} else if (name === "8x-") {
return "8x or lower";
} else if (name === "512x+") {
return "512x or higher";
} else if (name === "kitchen-sink") {
return "Kitchen Sink";
} else if (name === "path-tracing") {
return "Path Tracing";
} else if (name === "pbr") {
return "PBR";
} else if (name === "datapack") {
return "Data Pack";
} else if (name === "colored-lighting") {
return "Colored Lighting";
} else if (name === "optifine") {
return "OptiFine";
} else if (name === "mrpack") {
return "Modpack";
} else if (name === "minecraft") {
return "Resource Pack";
} else if (name === "vanilla") {
return "Vanilla Shader";
}
return capitalizeString(name);
};
export const formatCategoryHeader = (name) => {
return capitalizeString(name);
};
export const formatVersions = (tag, versionArray) => { export const formatVersions = (tag, versionArray) => {
const allVersions = tag.value.gameVersions.slice().reverse(); const allVersions = tag.value.gameVersions.slice().reverse();
const allReleases = allVersions.filter((x) => x.version_type === "release"); const allReleases = allVersions.filter((x) => x.version_type === "release");

View File

@ -84,6 +84,10 @@
--color-platform-velocity: #4b98b0; --color-platform-velocity: #4b98b0;
--color-platform-waterfall: #5f83cb; --color-platform-waterfall: #5f83cb;
--color-platform-sponge: #c49528; --color-platform-sponge: #c49528;
--color-platform-ornithe: #6097ca;
--color-platform-bta-babric: #5ba938;
--color-platform-legacy-fabric: #6879f6;
--color-platform-nilloader: #dd5088;
--hover-brightness: 0.9; --hover-brightness: 0.9;
} }
@ -198,6 +202,10 @@ html {
--color-platform-velocity: #83d5ef; --color-platform-velocity: #83d5ef;
--color-platform-waterfall: #78a4fb; --color-platform-waterfall: #78a4fb;
--color-platform-sponge: #f9e580; --color-platform-sponge: #f9e580;
--color-platform-ornithe: #87c7ff;
--color-platform-bta-babric: #72cc4a;
--color-platform-legacy-fabric: #6879f6;
--color-platform-nilloader: #f45e9a;
--hover-brightness: 1.25; --hover-brightness: 1.25;

View File

@ -185,6 +185,12 @@ export const formatCategory = (name) => {
return 'Java Agent' return 'Java Agent'
} else if (name === 'nilloader') { } else if (name === 'nilloader') {
return 'NilLoader' return 'NilLoader'
} else if (name === 'mrpack') {
return 'Modpack'
} else if (name === 'minecraft') {
return 'Resource Pack'
} else if (name === 'vanilla') {
return 'Vanilla Shader'
} }
return capitalizeString(name) return capitalizeString(name)
} }