You've already forked AstralRinth
forked from didirus/AstralRinth
feat: frontend explicit imports + error page fix (#4184)
* feat: frontend explicit imports * fix: error handling * fix: dashboard missing import * fix: error page issues * fix: exclude RouterView * feat: fix lint issues * fix: lint issues * fix: import issues * add getVersionLink * make articles.json use tabs on generation so it doesn't have to be reformatted * fix: lint issues --------- Signed-off-by: Cal H. <hendersoncal117@gmail.com> Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
This commit is contained in:
@@ -2,8 +2,9 @@
|
||||
::backdrop,
|
||||
:root[data-theme='light'],
|
||||
[data-theme='light'] ::backdrop {
|
||||
--sl-font-system: Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Roboto,
|
||||
Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
--sl-font-system:
|
||||
Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Roboto, Cantarell,
|
||||
Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
|
||||
--sl-color-white: var(--color-contrast); /* “white” */
|
||||
--sl-color-gray-1: var(--color-base);
|
||||
|
||||
@@ -331,7 +331,19 @@ import {
|
||||
VersionIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { injectNotificationManager, useRelativeTime } from '@modrinth/ui'
|
||||
import {
|
||||
Avatar,
|
||||
Categories,
|
||||
CopyCode,
|
||||
DoubleIcon,
|
||||
injectNotificationManager,
|
||||
ProjectStatusBadge,
|
||||
useRelativeTime,
|
||||
} from '@modrinth/ui'
|
||||
|
||||
import { getProjectLink, getVersionLink } from '~/helpers/projects'
|
||||
|
||||
import ThreadSummary from './thread/ThreadSummary.vue'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const emit = defineEmits(['update:notifications'])
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="flex gap-2">
|
||||
<ButtonStyled>
|
||||
<button size="sm" @click="$emit('refetch')">
|
||||
<UiServersIconsLoadingIcon class="h-5 w-5" />
|
||||
<LoadingIcon class="h-5 w-5" />
|
||||
Try again
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
@@ -28,6 +28,8 @@
|
||||
import { FileIcon, HomeIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled } from '@modrinth/ui'
|
||||
|
||||
import LoadingIcon from './icons/LoadingIcon.vue'
|
||||
|
||||
defineProps<{
|
||||
title: string
|
||||
message: string
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
}"
|
||||
data-pyro-files-virtual-list
|
||||
>
|
||||
<UiServersFileItem
|
||||
<FileItem
|
||||
v-for="item in visibleItems"
|
||||
:key="item.path"
|
||||
:count="item.count"
|
||||
@@ -45,6 +45,8 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
import FileItem from './FileItem.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
items: any[]
|
||||
}>()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
v-if="state.hasError"
|
||||
class="flex h-full w-full flex-col items-center justify-center gap-8"
|
||||
>
|
||||
<UiServersIconsPanelErrorIcon />
|
||||
<PanelErrorIcon />
|
||||
<p class="m-0">{{ state.errorMessage || 'Invalid or empty image file.' }}</p>
|
||||
</div>
|
||||
<img
|
||||
@@ -57,6 +57,8 @@ import { ZoomInIcon, ZoomOutIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled } from '@modrinth/ui'
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
import PanelErrorIcon from './icons/PanelErrorIcon.vue'
|
||||
|
||||
const ZOOM_MIN = 0.1
|
||||
const ZOOM_MAX = 5
|
||||
const ZOOM_IN_FACTOR = 1.2
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
>
|
||||
<div class="flex flex-1 items-center gap-2 truncate">
|
||||
<transition-group name="status-icon" mode="out-in">
|
||||
<UiServersPanelSpinner
|
||||
<PanelSpinner
|
||||
v-show="item.status === 'uploading'"
|
||||
key="spinner"
|
||||
class="absolute !size-4"
|
||||
@@ -107,6 +107,8 @@ import { computed, nextTick, ref, watch } from 'vue'
|
||||
|
||||
import type { FSModule } from '~/composables/servers/modules/fs.ts'
|
||||
|
||||
import PanelSpinner from './PanelSpinner.vue'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
interface UploadItem {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:key="loader.name"
|
||||
class="group relative flex items-center justify-between rounded-2xl p-2 pr-2.5 hover:bg-bg"
|
||||
>
|
||||
<UiServersLoaderSelectorCard
|
||||
<LoaderSelectorCard
|
||||
:loader="loader"
|
||||
:is-current="isCurrentLoader(loader.name)"
|
||||
:loader-version="data.loader_version"
|
||||
@@ -24,7 +24,7 @@
|
||||
:key="loader.name"
|
||||
class="group relative flex items-center justify-between rounded-2xl p-2 pr-2.5 hover:bg-bg"
|
||||
>
|
||||
<UiServersLoaderSelectorCard
|
||||
<LoaderSelectorCard
|
||||
:loader="loader"
|
||||
:is-current="isCurrentLoader(loader.name)"
|
||||
:loader-version="data.loader_version"
|
||||
@@ -44,7 +44,7 @@
|
||||
:key="loader.name"
|
||||
class="group relative flex items-center justify-between rounded-2xl p-2 pr-2.5 hover:bg-bg"
|
||||
>
|
||||
<UiServersLoaderSelectorCard
|
||||
<LoaderSelectorCard
|
||||
:loader="loader"
|
||||
:is-current="isCurrentLoader(loader.name)"
|
||||
:loader-version="data.loader_version"
|
||||
@@ -58,6 +58,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import LoaderSelectorCard from './LoaderSelectorCard.vue'
|
||||
const props = defineProps<{
|
||||
data: {
|
||||
loader: string | null
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
class="grid size-10 place-content-center rounded-xl border-[1px] border-solid border-button-border bg-button-bg shadow-sm"
|
||||
:class="isCurrentLoader ? '[&&]:bg-bg-green' : ''"
|
||||
>
|
||||
<UiServersIconsLoaderIcon
|
||||
<LoaderIcon
|
||||
:loader="loader.name"
|
||||
class="[&&]:size-6"
|
||||
:class="isCurrentLoader ? 'text-brand' : ''"
|
||||
@@ -43,6 +43,8 @@
|
||||
import { CheckIcon, DownloadIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled } from '@modrinth/ui'
|
||||
|
||||
import LoaderIcon from './icons/LoaderIcon.vue'
|
||||
|
||||
interface LoaderInfo {
|
||||
name: 'Vanilla' | 'Fabric' | 'Forge' | 'Quilt' | 'Paper' | 'NeoForge' | 'Purpur'
|
||||
displayName: string
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
Are you sure you want to
|
||||
<span class="lowercase">{{ confirmActionText }}</span> the server?
|
||||
</p>
|
||||
<UiCheckbox
|
||||
<Checkbox
|
||||
v-model="dontAskAgain"
|
||||
label="Don't ask me again"
|
||||
class="text-sm"
|
||||
@@ -34,7 +34,7 @@
|
||||
:header="`All of ${serverName || 'Server'} info`"
|
||||
@close="closeDetailsModal"
|
||||
>
|
||||
<UiServersServerInfoLabels
|
||||
<ServerInfoLabels
|
||||
:server-data="serverData"
|
||||
:show-game-label="true"
|
||||
:show-loader-label="true"
|
||||
@@ -53,7 +53,7 @@
|
||||
<div class="flex flex-row items-center gap-2 rounded-lg">
|
||||
<ButtonStyled v-if="isInstalling" type="standard" color="brand">
|
||||
<button disabled class="flex-shrink-0">
|
||||
<UiServersPanelSpinner class="size-5" /> Installing...
|
||||
<PanelSpinner class="size-5" /> Installing...
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
<ButtonStyled type="standard" color="brand">
|
||||
<button :disabled="!canTakeAction" @click="handlePrimaryAction">
|
||||
<div v-if="isTransitionState" class="grid place-content-center">
|
||||
<UiServersIconsLoadingIcon />
|
||||
<LoadingIcon />
|
||||
</div>
|
||||
<component :is="isRunning ? UpdatedIcon : PlayIcon" v-else />
|
||||
<span>{{ primaryActionText }}</span>
|
||||
@@ -116,12 +116,16 @@ import {
|
||||
UpdatedIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { ButtonStyled, NewModal } from '@modrinth/ui'
|
||||
import { ButtonStyled, Checkbox, NewModal } from '@modrinth/ui'
|
||||
import type { PowerAction as ServerPowerAction, ServerState } from '@modrinth/utils'
|
||||
import { useStorage } from '@vueuse/core'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import LoadingIcon from './icons/LoadingIcon.vue'
|
||||
import PanelSpinner from './PanelSpinner.vue'
|
||||
import ServerInfoLabels from './ServerInfoLabels.vue'
|
||||
|
||||
const flags = useFeatureFlags()
|
||||
|
||||
interface PowerAction {
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
class="group"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<UiServersLogLine :log="item" @show-full-log="showFullLogMessage" />
|
||||
<LogLine :log="item" @show-full-log="showFullLogMessage" />
|
||||
<div @mousedown.stop @click.stop>
|
||||
<button
|
||||
v-if="searchInput"
|
||||
@@ -223,8 +223,8 @@
|
||||
:class="{ hidden: searchInput || hasSelection || isSingleLineSelected }"
|
||||
@click="toggleFullscreen"
|
||||
>
|
||||
<LazyUiServersIconsMinimizeIconVue v-if="isFullScreen" />
|
||||
<LazyUiServersIconsFullscreenIcon v-else />
|
||||
<MinimizeIconVue v-if="isFullScreen" />
|
||||
<FullscreenIcon v-else />
|
||||
</button>
|
||||
|
||||
<Transition name="fade">
|
||||
@@ -306,6 +306,10 @@ import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
import { useModrinthServersConsole } from '~/store/console.ts'
|
||||
|
||||
import FullscreenIcon from './icons/FullscreenIcon.vue'
|
||||
import MinimizeIconVue from './icons/MinimizeIcon.vue.vue'
|
||||
import LogLine from './LogLine.vue'
|
||||
|
||||
const { $cosmetics } = useNuxtApp()
|
||||
const cosmetics = $cosmetics
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<div
|
||||
class="grid size-16 place-content-center rounded-2xl border-[2px] border-solid border-button-border bg-button-bg shadow-sm"
|
||||
>
|
||||
<UiServersIconsLoaderIcon class="size-10" :loader="selectedLoader" />
|
||||
<LoaderIcon class="size-10" :loader="selectedLoader" />
|
||||
</div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
<div class="flex w-full flex-col gap-2 rounded-2xl bg-table-alternateRow p-4">
|
||||
<div class="text-lg font-bold text-contrast">Minecraft version</div>
|
||||
<UiServersTeleportDropdownMenu
|
||||
<TeleportDropdownMenu
|
||||
v-model="selectedMCVersion"
|
||||
name="mcVersion"
|
||||
:options="mcVersions"
|
||||
@@ -102,13 +102,13 @@
|
||||
<div
|
||||
class="relative flex h-9 w-full items-center rounded-xl bg-button-bg px-4 opacity-50"
|
||||
>
|
||||
<UiServersIconsLoadingIcon class="mr-2 animate-spin" />
|
||||
<LoadingIcon class="mr-2 animate-spin" />
|
||||
Loading versions...
|
||||
<DropdownIcon class="absolute right-4" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="selectedLoaderVersions.length > 0">
|
||||
<UiServersTeleportDropdownMenu
|
||||
<TeleportDropdownMenu
|
||||
v-model="selectedLoaderVersion"
|
||||
name="loaderVersion"
|
||||
:options="selectedLoaderVersions"
|
||||
@@ -211,6 +211,9 @@ import { $fetch } from 'ofetch'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
import type { BackupInProgressReason } from '~/pages/servers/manage/[id].vue'
|
||||
|
||||
import LoaderIcon from './icons/LoaderIcon.vue'
|
||||
import LoadingIcon from './icons/LoadingIcon.vue'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
<template>
|
||||
<div>
|
||||
<UiServersServerGameLabel
|
||||
<ServerGameLabel
|
||||
v-if="showGameLabel"
|
||||
:game="serverData.game"
|
||||
:mc-version="serverData.mc_version ?? ''"
|
||||
:is-link="linked"
|
||||
/>
|
||||
<UiServersServerLoaderLabel
|
||||
<ServerLoaderLabel
|
||||
:loader="serverData.loader"
|
||||
:loader-version="serverData.loader_version ?? ''"
|
||||
:no-separator="column"
|
||||
:is-link="linked"
|
||||
/>
|
||||
<UiServersServerSubdomainLabel
|
||||
<ServerSubdomainLabel
|
||||
v-if="serverData.net?.domain"
|
||||
:subdomain="serverData.net.domain"
|
||||
:no-separator="column"
|
||||
:is-link="linked"
|
||||
/>
|
||||
<UiServersServerUptimeLabel
|
||||
<ServerUptimeLabel
|
||||
v-if="uptimeSeconds"
|
||||
:uptime-seconds="uptimeSeconds"
|
||||
:no-separator="column"
|
||||
@@ -27,6 +27,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ServerGameLabel from './ServerGameLabel.vue'
|
||||
import ServerLoaderLabel from './ServerLoaderLabel.vue'
|
||||
import ServerSubdomainLabel from './ServerSubdomainLabel.vue'
|
||||
import ServerUptimeLabel from './ServerUptimeLabel.vue'
|
||||
|
||||
interface ServerInfoLabelsProps {
|
||||
serverData: Record<string, any>
|
||||
showGameLabel: boolean
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<LazyUiServersPlatformVersionSelectModal
|
||||
<PlatformVersionSelectModal
|
||||
ref="versionSelectModal"
|
||||
:server="props.server"
|
||||
:current-loader="ignoreCurrentInstallation ? undefined : (data?.loader as Loaders)"
|
||||
@@ -8,13 +8,13 @@
|
||||
@reinstall="emit('reinstall', $event)"
|
||||
/>
|
||||
|
||||
<LazyUiServersPlatformMrpackModal
|
||||
<PlatformMrpackModal
|
||||
ref="mrpackModal"
|
||||
:server="props.server"
|
||||
@reinstall="emit('reinstall', $event)"
|
||||
/>
|
||||
|
||||
<LazyUiServersPlatformChangeModpackVersionModal
|
||||
<PlatformChangeModpackVersionModal
|
||||
ref="modpackVersionModal"
|
||||
:server="props.server"
|
||||
:project="data?.project"
|
||||
@@ -137,7 +137,7 @@
|
||||
}"
|
||||
:tabindex="props.server.general?.status === 'installing' ? -1 : 0"
|
||||
>
|
||||
<UiServersLoaderSelector
|
||||
<LoaderSelector
|
||||
:data="
|
||||
ignoreCurrentInstallation
|
||||
? {
|
||||
@@ -165,6 +165,11 @@ import type { Loaders } from '@modrinth/utils'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
import type { BackupInProgressReason } from '~/pages/servers/manage/[id].vue'
|
||||
|
||||
import LoaderSelector from './LoaderSelector.vue'
|
||||
import PlatformChangeModpackVersionModal from './PlatformChangeModpackVersionModal.vue'
|
||||
import PlatformMrpackModal from './PlatformMrpackModal.vue'
|
||||
import PlatformVersionSelectModal from './PlatformVersionSelectModal.vue'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
data-pyro-server-listing
|
||||
:data-pyro-server-listing-id="server_id"
|
||||
>
|
||||
<UiServersServerIcon v-if="status !== 'suspended'" :image="image" />
|
||||
<ServerIcon v-if="status !== 'suspended'" :image="image" />
|
||||
<div
|
||||
v-else
|
||||
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"
|
||||
@@ -49,7 +49,7 @@
|
||||
>
|
||||
<SparklesIcon class="size-5 shrink-0" /> New server
|
||||
</div>
|
||||
<UiServersServerInfoLabels
|
||||
<ServerInfoLabels
|
||||
v-else
|
||||
:server-data="{ game, mc_version, loader, loader_version, net }"
|
||||
:show-game-label="showGameLabel"
|
||||
@@ -63,7 +63,7 @@
|
||||
v-if="status === 'suspended' && suspension_reason === 'upgrading'"
|
||||
class="relative -mt-4 flex w-full flex-row items-center gap-2 rounded-b-3xl bg-bg-blue p-4 text-sm font-bold text-contrast"
|
||||
>
|
||||
<UiServersPanelSpinner />
|
||||
<PanelSpinner />
|
||||
Your server's hardware is currently being upgraded and will be back online shortly.
|
||||
</div>
|
||||
<div
|
||||
@@ -71,8 +71,8 @@
|
||||
class="relative -mt-4 flex w-full flex-col gap-2 rounded-b-3xl bg-bg-red p-4 text-sm font-bold text-contrast"
|
||||
>
|
||||
<div class="flex flex-row gap-2">
|
||||
<UiServersIconsPanelErrorIcon class="!size-5" /> Your server has been cancelled. Please
|
||||
update your billing information or contact Modrinth Support for more information.
|
||||
<PanelErrorIcon class="!size-5" /> Your server has been cancelled. Please update your
|
||||
billing information or contact Modrinth Support for more information.
|
||||
</div>
|
||||
<CopyCode :text="`${props.server_id}`" class="ml-auto" />
|
||||
</div>
|
||||
@@ -81,9 +81,8 @@
|
||||
class="relative -mt-4 flex w-full flex-col gap-2 rounded-b-3xl bg-bg-red p-4 text-sm font-bold text-contrast"
|
||||
>
|
||||
<div class="flex flex-row gap-2">
|
||||
<UiServersIconsPanelErrorIcon class="!size-5" /> Your server has been suspended:
|
||||
{{ suspension_reason }}. Please update your billing information or contact Modrinth Support
|
||||
for more information.
|
||||
<PanelErrorIcon class="!size-5" /> Your server has been suspended: {{ suspension_reason }}.
|
||||
Please update your billing information or contact Modrinth Support for more information.
|
||||
</div>
|
||||
<CopyCode :text="`${props.server_id}`" class="ml-auto" />
|
||||
</div>
|
||||
@@ -92,8 +91,8 @@
|
||||
class="relative -mt-4 flex w-full flex-col gap-2 rounded-b-3xl bg-bg-red p-4 text-sm font-bold text-contrast"
|
||||
>
|
||||
<div class="flex flex-row gap-2">
|
||||
<UiServersIconsPanelErrorIcon class="!size-5" /> Your server has been suspended. Please
|
||||
update your billing information or contact Modrinth Support for more information.
|
||||
<PanelErrorIcon class="!size-5" /> Your server has been suspended. Please update your
|
||||
billing information or contact Modrinth Support for more information.
|
||||
</div>
|
||||
<CopyCode :text="`${props.server_id}`" class="ml-auto" />
|
||||
</div>
|
||||
@@ -107,6 +106,11 @@ import type { Project, Server } from '@modrinth/utils'
|
||||
|
||||
import { useModrinthServers } from '~/composables/servers/modrinth-servers.ts'
|
||||
|
||||
import PanelErrorIcon from './icons/PanelErrorIcon.vue'
|
||||
import PanelSpinner from './PanelSpinner.vue'
|
||||
import ServerIcon from './ServerIcon.vue'
|
||||
import ServerInfoLabels from './ServerInfoLabels.vue'
|
||||
|
||||
const props = defineProps<Partial<Server>>()
|
||||
|
||||
if (props.server_id && props.status === 'available') {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
src="~/assets/images/servers/minecraft_server_icon.png"
|
||||
/>
|
||||
<div class="absolute inset-0 grid place-content-center">
|
||||
<UiServersIconsLoadingIcon class="size-8 animate-spin text-contrast" />
|
||||
<LoadingIcon class="size-8 animate-spin text-contrast" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
@@ -18,3 +18,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import LoadingIcon from './icons/LoadingIcon.vue'
|
||||
</script>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div v-tooltip="'Change server loader'" class="flex min-w-0 flex-row items-center gap-4 truncate">
|
||||
<div v-if="!noSeparator" class="experimental-styles-within h-6 w-0.5 bg-button-border"></div>
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<UiServersIconsLoaderIcon v-if="loader" :loader="loader" class="flex shrink-0 [&&]:size-5" />
|
||||
<LoaderIcon v-if="loader" :loader="loader" class="flex shrink-0 [&&]:size-5" />
|
||||
<div v-else class="size-5 shrink-0 animate-pulse rounded-full bg-button-border"></div>
|
||||
<NuxtLink
|
||||
v-if="isLink"
|
||||
@@ -34,6 +34,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import LoaderIcon from './icons/LoaderIcon.vue'
|
||||
defineProps<{
|
||||
noSeparator?: boolean
|
||||
loader?: 'Fabric' | 'Quilt' | 'Forge' | 'NeoForge' | 'Paper' | 'Spigot' | 'Bukkit' | 'Vanilla'
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div v-if="!noSeparator" class="experimental-styles-within h-6 w-0.5 bg-button-border"></div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<UiServersIconsTimer class="flex size-5 shrink-0" />
|
||||
<Timer class="flex size-5 shrink-0" />
|
||||
<time class="truncate text-sm font-semibold" :aria-label="verboseUptime">
|
||||
{{ formattedUptime }}
|
||||
</time>
|
||||
@@ -19,6 +19,8 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
import Timer from './icons/Timer.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
uptimeSeconds: number
|
||||
noSeparator?: boolean
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<template>
|
||||
<NuxtLayout>
|
||||
<ModrinthLoadingIndicator />
|
||||
<NotificationPanel />
|
||||
<div class="main experimental-styles-within">
|
||||
<div v-if="is404" class="error-graphic">
|
||||
<Logo404 />
|
||||
@@ -50,10 +52,16 @@
|
||||
|
||||
<script setup>
|
||||
import { SadRinthbot } from '@modrinth/assets'
|
||||
import { NotificationPanel, provideNotificationManager } from '@modrinth/ui'
|
||||
import { defineMessage, useVIntl } from '@vintl/vintl'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
|
||||
import Logo404 from '~/assets/images/404.svg'
|
||||
|
||||
import ModrinthLoadingIndicator from './components/ui/modrinth-loading-indicator.ts'
|
||||
import { FrontendNotificationManager } from './providers/frontend-notifications.ts'
|
||||
|
||||
provideNotificationManager(new FrontendNotificationManager())
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
>
|
||||
<div>
|
||||
<NuxtLink to="/" aria-label="Modrinth home page">
|
||||
<BrandTextLogo aria-hidden="true" class="h-7 w-auto text-contrast" />
|
||||
<TextLogo aria-hidden="true" class="h-7 w-auto text-contrast" />
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div
|
||||
@@ -450,8 +450,7 @@
|
||||
</div>
|
||||
</NuxtLink>
|
||||
<nuxt-link v-else class="iconified-button brand-button" to="/auth/sign-in">
|
||||
<LogInIcon aria-hidden="true" />
|
||||
{{ formatMessage(commonMessages.signInButton) }}
|
||||
<LogInIcon aria-hidden="true" /> {{ formatMessage(commonMessages.signInButton) }}
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<div class="links">
|
||||
@@ -590,7 +589,7 @@
|
||||
role="region"
|
||||
aria-label="Modrinth information"
|
||||
>
|
||||
<BrandTextLogo
|
||||
<TextLogo
|
||||
aria-hidden="true"
|
||||
class="text-logo button-base h-6 w-auto text-contrast lg:h-8"
|
||||
@click="developerModeIncrement()"
|
||||
@@ -716,7 +715,9 @@ import {
|
||||
PagewideBanner,
|
||||
} from '@modrinth/ui'
|
||||
import { isAdmin, isStaff } from '@modrinth/utils'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
|
||||
import TextLogo from '~/components/brand/TextLogo.vue'
|
||||
import CollectionCreateModal from '~/components/ui/CollectionCreateModal.vue'
|
||||
import ModalCreation from '~/components/ui/ModalCreation.vue'
|
||||
import OrganizationCreateModal from '~/components/ui/OrganizationCreateModal.vue'
|
||||
@@ -724,12 +725,13 @@ import TeleportOverflowMenu from '~/components/ui/servers/TeleportOverflowMenu.v
|
||||
import { errors as generatedStateErrors } from '~/generated/state.json'
|
||||
import { getProjectTypeMessage } from '~/utils/i18n-project-type.ts'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const auth = await useAuth()
|
||||
const user = await useUser()
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
const cosmetics = useCosmetics()
|
||||
const flags = useFeatureFlags()
|
||||
|
||||
@@ -739,6 +741,22 @@ const router = useNativeRouter()
|
||||
const link = config.public.siteUrl + route.path.replace(/\/+$/, '')
|
||||
|
||||
const basePopoutId = useId()
|
||||
async function handleResendEmailVerification() {
|
||||
try {
|
||||
await resendVerifyEmail()
|
||||
addNotification({
|
||||
title: 'Verification email sent',
|
||||
text: 'Please check your inbox for the verification email.',
|
||||
type: 'success',
|
||||
})
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
title: 'An error occurred',
|
||||
text: err.data.description,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const verifyEmailBannerMessages = defineMessages({
|
||||
title: {
|
||||
@@ -854,23 +872,6 @@ const footerMessages = defineMessages({
|
||||
},
|
||||
})
|
||||
|
||||
async function handleResendEmailVerification() {
|
||||
try {
|
||||
await resendVerifyEmail()
|
||||
addNotification({
|
||||
title: 'Email sent',
|
||||
text: `An email with a link to verify your account has been sent to ${auth.value.user.email}.`,
|
||||
type: 'success',
|
||||
})
|
||||
} catch (err) {
|
||||
addNotification({
|
||||
title: 'An error occurred',
|
||||
text: err.data.description,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
useHead({
|
||||
link: [
|
||||
{
|
||||
@@ -1211,10 +1212,7 @@ const footerLinks = [
|
||||
{
|
||||
href: '/news/changelog',
|
||||
label: formatMessage(
|
||||
defineMessage({
|
||||
id: 'layout.footer.about.changelog',
|
||||
defaultMessage: 'Changelog',
|
||||
}),
|
||||
defineMessage({ id: 'layout.footer.about.changelog', defaultMessage: 'Changelog' }),
|
||||
),
|
||||
},
|
||||
{
|
||||
@@ -1248,19 +1246,13 @@ const footerLinks = [
|
||||
{
|
||||
href: '/plus',
|
||||
label: formatMessage(
|
||||
defineMessage({
|
||||
id: 'layout.footer.products.plus',
|
||||
defaultMessage: 'Modrinth+',
|
||||
}),
|
||||
defineMessage({ id: 'layout.footer.products.plus', defaultMessage: 'Modrinth+' }),
|
||||
),
|
||||
},
|
||||
{
|
||||
href: '/app',
|
||||
label: formatMessage(
|
||||
defineMessage({
|
||||
id: 'layout.footer.products.app',
|
||||
defaultMessage: 'Modrinth App',
|
||||
}),
|
||||
defineMessage({ id: 'layout.footer.products.app', defaultMessage: 'Modrinth App' }),
|
||||
),
|
||||
},
|
||||
{
|
||||
@@ -1291,10 +1283,7 @@ const footerLinks = [
|
||||
{
|
||||
href: 'https://crowdin.com/project/modrinth',
|
||||
label: formatMessage(
|
||||
defineMessage({
|
||||
id: 'layout.footer.resources.translate',
|
||||
defaultMessage: 'Translate',
|
||||
}),
|
||||
defineMessage({ id: 'layout.footer.resources.translate', defaultMessage: 'Translate' }),
|
||||
),
|
||||
},
|
||||
{
|
||||
@@ -1323,19 +1312,13 @@ const footerLinks = [
|
||||
{
|
||||
href: '/legal/rules',
|
||||
label: formatMessage(
|
||||
defineMessage({
|
||||
id: 'layout.footer.legal.rules',
|
||||
defaultMessage: 'Content Rules',
|
||||
}),
|
||||
defineMessage({ id: 'layout.footer.legal.rules', defaultMessage: 'Content Rules' }),
|
||||
),
|
||||
},
|
||||
{
|
||||
href: '/legal/terms',
|
||||
label: formatMessage(
|
||||
defineMessage({
|
||||
id: 'layout.footer.legal.terms-of-use',
|
||||
defaultMessage: 'Terms of Use',
|
||||
}),
|
||||
defineMessage({ id: 'layout.footer.legal.terms-of-use', defaultMessage: 'Terms of Use' }),
|
||||
),
|
||||
},
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -82,6 +82,7 @@
|
||||
<script setup>
|
||||
import { CheckIcon, XIcon } from '@modrinth/assets'
|
||||
import { Avatar, Button, commonMessages, injectNotificationManager } from '@modrinth/ui'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
|
||||
import { useAuth } from '@/composables/auth.js'
|
||||
import { useScopes } from '@/composables/auth/scopes.ts'
|
||||
|
||||
@@ -141,6 +141,7 @@ import {
|
||||
SSOSteamIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { commonMessages, injectNotificationManager } from '@modrinth/ui'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
|
||||
import HCaptcha from '@/components/ui/HCaptcha.vue'
|
||||
|
||||
|
||||
@@ -146,6 +146,7 @@ import {
|
||||
UserIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Checkbox, commonMessages, injectNotificationManager } from '@modrinth/ui'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
|
||||
import HCaptcha from '@/components/ui/HCaptcha.vue'
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
<script setup>
|
||||
import { RightArrowIcon, WavingRinthbot } from '@modrinth/assets'
|
||||
import { Checkbox, commonMessages } from '@modrinth/ui'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
|
||||
@@ -407,6 +407,7 @@ import {
|
||||
useRelativeTime,
|
||||
} from '@modrinth/ui'
|
||||
import { isAdmin } from '@modrinth/utils'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
import UpToDate from 'assets/images/illustrations/up_to_date.svg'
|
||||
|
||||
import AdPlaceholder from '~/components/ui/AdPlaceholder.vue'
|
||||
|
||||
@@ -292,6 +292,7 @@ import {
|
||||
} from '@modrinth/ui'
|
||||
import type { Project, Report, User, Version } from '@modrinth/utils'
|
||||
import { defineMessages, type MessageDescriptor, useVIntl } from '@vintl/vintl'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
|
||||
import { useImageUpload } from '~/composables/image-upload.ts'
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
}"
|
||||
>
|
||||
<div class="flex w-full min-w-0 select-none flex-col items-center gap-6 pt-4 sm:flex-row">
|
||||
<UiServersServerIcon :image="serverData.image" class="drop-shadow-lg sm:drop-shadow-none" />
|
||||
<ServerIcon :image="serverData.image" class="drop-shadow-lg sm:drop-shadow-none" />
|
||||
<div
|
||||
class="flex min-w-0 flex-1 flex-col-reverse items-center gap-2 sm:flex-col sm:items-start"
|
||||
>
|
||||
@@ -137,7 +137,7 @@
|
||||
data-pyro-server-action-buttons
|
||||
class="server-action-buttons-anim flex w-fit flex-shrink-0"
|
||||
>
|
||||
<UiServersPanelServerActionButton
|
||||
<PanelServerActionButton
|
||||
v-if="!serverData.flows?.intro"
|
||||
class="flex-shrink-0"
|
||||
:is-online="isServerRunning"
|
||||
@@ -158,7 +158,7 @@
|
||||
>
|
||||
<SettingsIcon /> Configuring server...
|
||||
</div>
|
||||
<UiServersServerInfoLabels
|
||||
<ServerInfoLabels
|
||||
v-else
|
||||
:server-data="serverData"
|
||||
:show-game-label="showGameLabel"
|
||||
@@ -175,7 +175,7 @@
|
||||
v-if="serverData?.status === 'installing'"
|
||||
class="w-50 h-50 flex items-center justify-center gap-2 text-center text-lg font-bold"
|
||||
>
|
||||
<LazyUiServersPanelSpinner class="size-10 animate-spin" /> Setting up your server...
|
||||
<PanelSpinner class="size-10 animate-spin" /> Setting up your server...
|
||||
</div>
|
||||
<div v-else>
|
||||
<h2 class="my-4 text-xl font-extrabold">
|
||||
@@ -196,7 +196,7 @@
|
||||
data-pyro-navigation
|
||||
class="isolate flex w-full select-none flex-col justify-between gap-4 overflow-auto md:flex-row md:items-center"
|
||||
>
|
||||
<UiNavTabs :links="navLinks" />
|
||||
<NavTabs :links="navLinks" />
|
||||
</div>
|
||||
|
||||
<div data-pyro-mount class="h-full w-full flex-1">
|
||||
@@ -304,7 +304,7 @@
|
||||
data-pyro-server-ws-reconnecting
|
||||
class="mb-4 flex w-full flex-row items-center gap-4 rounded-2xl bg-bg-orange p-4 text-sm text-contrast"
|
||||
>
|
||||
<UiServersPanelSpinner />
|
||||
<PanelSpinner />
|
||||
Hang on, we're reconnecting to your server.
|
||||
</div>
|
||||
|
||||
@@ -313,13 +313,13 @@
|
||||
data-pyro-server-installing
|
||||
class="mb-4 flex w-full flex-row items-center gap-4 rounded-2xl bg-bg-blue p-4 text-sm text-contrast"
|
||||
>
|
||||
<UiServersServerIcon :image="serverData.image" class="!h-10 !w-10" />
|
||||
<ServerIcon :image="serverData.image" class="!h-10 !w-10" />
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<span class="text-lg font-bold"> We're preparing your server! </span>
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<UiServersPanelSpinner class="!h-3 !w-3" />
|
||||
<LazyUiServersInstallingTicker />
|
||||
<PanelSpinner class="!h-3 !w-3" />
|
||||
<InstallingTicker />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -382,7 +382,13 @@ import DOMPurify from 'dompurify'
|
||||
import { computed, onMounted, onUnmounted, type Reactive, ref } from 'vue'
|
||||
|
||||
import { reloadNuxtApp } from '#app'
|
||||
import NavTabs from '~/components/ui/NavTabs.vue'
|
||||
import PanelErrorIcon from '~/components/ui/servers/icons/PanelErrorIcon.vue'
|
||||
import InstallingTicker from '~/components/ui/servers/InstallingTicker.vue'
|
||||
import PanelServerActionButton from '~/components/ui/servers/PanelServerActionButton.vue'
|
||||
import PanelSpinner from '~/components/ui/servers/PanelSpinner.vue'
|
||||
import ServerIcon from '~/components/ui/servers/ServerIcon.vue'
|
||||
import ServerInfoLabels from '~/components/ui/servers/ServerInfoLabels.vue'
|
||||
import ServerInstallation from '~/components/ui/servers/ServerInstallation.vue'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
import { useModrinthServers } from '~/composables/servers/modrinth-servers.ts'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<UiServersContentVersionEditModal
|
||||
<ContentVersionEditModal
|
||||
v-if="!invalidModal"
|
||||
ref="versionEditModal"
|
||||
:type="type"
|
||||
@@ -59,7 +59,7 @@
|
||||
/>
|
||||
</div>
|
||||
<ButtonStyled>
|
||||
<UiServersTeleportOverflowMenu
|
||||
<TeleportOverflowMenu
|
||||
position="bottom"
|
||||
direction="left"
|
||||
:aria-label="`Filter ${type}s`"
|
||||
@@ -77,8 +77,8 @@
|
||||
<template #all> All {{ type.toLocaleLowerCase() }}s </template>
|
||||
<template #enabled> Only enabled </template>
|
||||
<template #disabled> Only disabled </template>
|
||||
</UiServersTeleportOverflowMenu>
|
||||
</ButtonStyled>
|
||||
</TeleportOverflowMenu></ButtonStyled
|
||||
>
|
||||
</div>
|
||||
<div v-if="hasMods" class="flex w-full items-center gap-2 sm:w-fit">
|
||||
<ButtonStyled>
|
||||
@@ -202,7 +202,7 @@
|
||||
@click="showVersionModal(mod)"
|
||||
>
|
||||
<template v-if="mod.changing">
|
||||
<UiServersIconsLoadingIcon class="animate-spin" />
|
||||
<LoadingIcon class="animate-spin" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<EditIcon />
|
||||
@@ -212,13 +212,13 @@
|
||||
|
||||
<!-- Dropdown for mobile -->
|
||||
<div class="mr-2 flex items-center sm:hidden">
|
||||
<UiServersIconsLoadingIcon
|
||||
<LoadingIcon
|
||||
v-if="mod.changing"
|
||||
class="mr-2 h-5 w-5 animate-spin"
|
||||
style="color: var(--color-base)"
|
||||
/>
|
||||
<ButtonStyled v-else circular type="transparent">
|
||||
<UiServersTeleportOverflowMenu
|
||||
<TeleportOverflowMenu
|
||||
:options="[
|
||||
{
|
||||
id: 'edit',
|
||||
@@ -240,8 +240,8 @@
|
||||
<TrashIcon class="h-5 w-5" />
|
||||
<span>Delete</span>
|
||||
</template>
|
||||
</UiServersTeleportOverflowMenu>
|
||||
</ButtonStyled>
|
||||
</TeleportOverflowMenu></ButtonStyled
|
||||
>
|
||||
</div>
|
||||
|
||||
<input
|
||||
@@ -312,7 +312,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="mt-4 flex h-full flex-col items-center justify-center gap-4 text-center">
|
||||
<UiServersIconsLoaderIcon loader="Vanilla" class="size-24" />
|
||||
<LoaderIcon loader="Vanilla" class="size-24" />
|
||||
<p class="m-0 pt-3 font-bold text-contrast">Your server is running Vanilla Minecraft</p>
|
||||
<p class="m-0">
|
||||
Add content to your server by installing a modpack or choosing a different platform that
|
||||
@@ -359,8 +359,11 @@ import { Avatar, ButtonStyled, injectNotificationManager } from '@modrinth/ui'
|
||||
import type { Mod } from '@modrinth/utils'
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
import ContentVersionEditModal from '~/components/ui/servers/ContentVersionEditModal.vue'
|
||||
import FilesUploadDragAndDrop from '~/components/ui/servers/FilesUploadDragAndDrop.vue'
|
||||
import FilesUploadDropdown from '~/components/ui/servers/FilesUploadDropdown.vue'
|
||||
import LoaderIcon from '~/components/ui/servers/icons/LoaderIcon.vue'
|
||||
import LoadingIcon from '~/components/ui/servers/icons/LoadingIcon.vue'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
import { acceptFileFromProjectType } from '~/helpers/fileUtils.js'
|
||||
|
||||
|
||||
@@ -1,31 +1,19 @@
|
||||
<template>
|
||||
<div data-pyro-file-manager-root class="contents">
|
||||
<LazyUiServersFilesCreateItemModal
|
||||
ref="createItemModal"
|
||||
:type="newItemType"
|
||||
@create="handleCreateNewItem"
|
||||
/>
|
||||
<FilesCreateItemModal ref="createItemModal" :type="newItemType" @create="handleCreateNewItem" />
|
||||
<FilesUploadZipUrlModal ref="uploadZipModal" :server="server" />
|
||||
<FilesUploadConflictModal ref="uploadConflictModal" @proceed="extractItem" />
|
||||
|
||||
<LazyUiServersFilesRenameItemModal
|
||||
ref="renameItemModal"
|
||||
:item="selectedItem"
|
||||
@rename="handleRenameItem"
|
||||
/>
|
||||
<FilesRenameItemModal ref="renameItemModal" :item="selectedItem" @rename="handleRenameItem" />
|
||||
|
||||
<LazyUiServersFilesMoveItemModal
|
||||
<FilesMoveItemModal
|
||||
ref="moveItemModal"
|
||||
:item="selectedItem"
|
||||
:current-path="currentPath"
|
||||
@move="handleMoveItem"
|
||||
/>
|
||||
|
||||
<LazyUiServersFilesDeleteItemModal
|
||||
ref="deleteItemModal"
|
||||
:item="selectedItem"
|
||||
@delete="handleDeleteItem"
|
||||
/>
|
||||
<FilesDeleteItemModal ref="deleteItemModal" :item="selectedItem" @delete="handleDeleteItem" />
|
||||
|
||||
<FilesUploadDragAndDrop
|
||||
class="relative flex w-full flex-col rounded-2xl border border-solid border-bg-raised"
|
||||
@@ -33,7 +21,7 @@
|
||||
>
|
||||
<div ref="mainContent" class="relative isolate flex w-full flex-col">
|
||||
<div v-if="!isEditing" class="contents">
|
||||
<UiServersFilesBrowseNavbar
|
||||
<FilesBrowseNavbar
|
||||
:breadcrumb-segments="breadcrumbSegments"
|
||||
:search-query="searchQuery"
|
||||
:current-filter="viewFilter"
|
||||
@@ -46,11 +34,7 @@
|
||||
@filter="handleFilter"
|
||||
@update:search-query="searchQuery = $event"
|
||||
/>
|
||||
<UiServersFilesLabelBar
|
||||
:sort-field="sortMethod"
|
||||
:sort-desc="sortDesc"
|
||||
@sort="handleSort"
|
||||
/>
|
||||
<FilesLabelBar :sort-field="sortMethod" :sort-desc="sortDesc" @sort="handleSort" />
|
||||
<div
|
||||
v-for="op in ops"
|
||||
:key="`fs-op-${op.op}-${op.src}`"
|
||||
@@ -172,7 +156,7 @@
|
||||
@upload-complete="refreshList()"
|
||||
/>
|
||||
</div>
|
||||
<UiServersFilesEditingNavbar
|
||||
<FilesEditingNavbar
|
||||
v-else
|
||||
:file-name="editingFile?.name"
|
||||
:is-image="isEditingImage"
|
||||
@@ -211,10 +195,10 @@
|
||||
class="ace_editor ace_hidpi ace-one-dark ace_dark rounded-b-lg"
|
||||
@init="onInit"
|
||||
/>
|
||||
<UiServersFilesImageViewer v-else :image-blob="imagePreview" />
|
||||
<FilesImageViewer v-else :image-blob="imagePreview" />
|
||||
</div>
|
||||
<div v-else-if="items.length > 0" class="h-full w-full overflow-hidden rounded-b-2xl">
|
||||
<UiServersFileVirtualList
|
||||
<FileVirtualList
|
||||
:items="filteredItems"
|
||||
@extract="handleExtractItem"
|
||||
@delete="showDeleteModal"
|
||||
@@ -239,7 +223,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<LazyUiServersFileManagerError
|
||||
<FileManagerError
|
||||
v-else-if="loadError"
|
||||
title="Unable to load files"
|
||||
message="The folder may not exist."
|
||||
@@ -259,7 +243,7 @@
|
||||
</div>
|
||||
</FilesUploadDragAndDrop>
|
||||
|
||||
<UiServersFilesContextMenu
|
||||
<FilesContextMenu
|
||||
ref="contextMenu"
|
||||
:item="contextMenuInfo.item"
|
||||
:x="contextMenuInfo.x"
|
||||
@@ -289,10 +273,21 @@ import { formatBytes, ModrinthServersFetchError } from '@modrinth/utils'
|
||||
import { useInfiniteScroll } from '@vueuse/core'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import FileManagerError from '~/components/ui/servers/FileManagerError.vue'
|
||||
import FilesBrowseNavbar from '~/components/ui/servers/FilesBrowseNavbar.vue'
|
||||
import FilesContextMenu from '~/components/ui/servers/FilesContextMenu.vue'
|
||||
import FilesCreateItemModal from '~/components/ui/servers/FilesCreateItemModal.vue'
|
||||
import FilesDeleteItemModal from '~/components/ui/servers/FilesDeleteItemModal.vue'
|
||||
import FilesEditingNavbar from '~/components/ui/servers/FilesEditingNavbar.vue'
|
||||
import FilesImageViewer from '~/components/ui/servers/FilesImageViewer.vue'
|
||||
import FilesLabelBar from '~/components/ui/servers/FilesLabelBar.vue'
|
||||
import FilesMoveItemModal from '~/components/ui/servers/FilesMoveItemModal.vue'
|
||||
import FilesRenameItemModal from '~/components/ui/servers/FilesRenameItemModal.vue'
|
||||
import FilesUploadConflictModal from '~/components/ui/servers/FilesUploadConflictModal.vue'
|
||||
import FilesUploadDragAndDrop from '~/components/ui/servers/FilesUploadDragAndDrop.vue'
|
||||
import FilesUploadDropdown from '~/components/ui/servers/FilesUploadDropdown.vue'
|
||||
import FilesUploadZipUrlModal from '~/components/ui/servers/FilesUploadZipUrlModal.vue'
|
||||
import FileVirtualList from '~/components/ui/servers/FileVirtualList.vue'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
import { handleServersError } from '~/composables/servers/modrinth-servers.ts'
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col-reverse gap-6 md:flex-col">
|
||||
<UiServersServerStats
|
||||
<ServerStats
|
||||
:data="isConnected && !isWsAuthIncorrect ? stats : undefined"
|
||||
:loading="!isConnected || isWsAuthIncorrect"
|
||||
/>
|
||||
@@ -87,17 +87,11 @@
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-4">
|
||||
<h2 class="m-0 text-3xl font-extrabold text-contrast">Console</h2>
|
||||
<UiServersPanelServerStatus
|
||||
v-if="isConnected && !isWsAuthIncorrect"
|
||||
:state="serverPowerState"
|
||||
/>
|
||||
<PanelServerStatus v-if="isConnected && !isWsAuthIncorrect" :state="serverPowerState" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<UiServersPanelTerminal
|
||||
:full-screen="fullScreen"
|
||||
:loading="!isConnected || isWsAuthIncorrect"
|
||||
>
|
||||
<PanelTerminal :full-screen="fullScreen" :loading="!isConnected || isWsAuthIncorrect">
|
||||
<div class="relative w-full px-4 pt-4">
|
||||
<ul
|
||||
v-if="suggestions.length && isConnected && !isWsAuthIncorrect"
|
||||
@@ -169,7 +163,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</UiServersPanelTerminal>
|
||||
</PanelTerminal>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -191,6 +185,9 @@ import { IssuesIcon, TerminalSquareIcon, XIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled } from '@modrinth/ui'
|
||||
import type { ServerState, Stats } from '@modrinth/utils'
|
||||
|
||||
import PanelServerStatus from '~/components/ui/servers/PanelServerStatus.vue'
|
||||
import PanelTerminal from '~/components/ui/servers/PanelTerminal.vue'
|
||||
import ServerStats from '~/components/ui/servers/ServerStats.vue'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
|
||||
type ServerProps = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<UiServersServerSidebar
|
||||
<ServerSidebar
|
||||
:route="route"
|
||||
:nav-links="navLinks"
|
||||
:server="server"
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
} from '@modrinth/assets'
|
||||
import { isAdmin as isUserAdmin, type User } from '@modrinth/utils'
|
||||
|
||||
import ServerSidebar from '~/components/ui/servers/ServerSidebar.vue'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
import type { BackupInProgressReason } from '~/pages/servers/manage/[id].vue'
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
>
|
||||
<EditIcon class="h-8 w-8 text-contrast" />
|
||||
</div>
|
||||
<UiServersServerIcon :image="icon" />
|
||||
<ServerIcon :image="icon" />
|
||||
</div>
|
||||
<ButtonStyled>
|
||||
<button v-tooltip="'Synchronize icon with installed modpack'" @click="resetIcon">
|
||||
@@ -101,7 +101,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-else />
|
||||
<UiServersSaveBanner
|
||||
<SaveBanner
|
||||
:is-visible="!!hasUnsavedChanges && !!isValidServerName"
|
||||
:server="props.server"
|
||||
:is-updating="isUpdating"
|
||||
@@ -116,6 +116,8 @@ import { EditIcon, TransferIcon } from '@modrinth/assets'
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import ButtonStyled from '@modrinth/ui/src/components/base/ButtonStyled.vue'
|
||||
|
||||
import SaveBanner from '~/components/ui/servers/SaveBanner.vue'
|
||||
import ServerIcon from '~/components/ui/servers/ServerIcon.vue'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
@@ -251,7 +251,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<UiServersSaveBanner
|
||||
<SaveBanner
|
||||
:is-visible="!!hasUnsavedChanges && !!isValidSubdomain"
|
||||
:server="props.server"
|
||||
:is-updating="isUpdating"
|
||||
@@ -282,6 +282,7 @@ import {
|
||||
} from '@modrinth/ui'
|
||||
import { computed, nextTick, ref } from 'vue'
|
||||
|
||||
import SaveBanner from '~/components/ui/servers/SaveBanner.vue'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<UiServersSaveBanner
|
||||
<SaveBanner
|
||||
:is-visible="hasUnsavedChanges"
|
||||
:server="props.server"
|
||||
:is-updating="false"
|
||||
@@ -45,6 +45,7 @@
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import { useStorage } from '@vueuse/core'
|
||||
|
||||
import SaveBanner from '~/components/ui/servers/SaveBanner.vue'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<UiServersSaveBanner
|
||||
<SaveBanner
|
||||
:is-visible="hasUnsavedChanges"
|
||||
:server="props.server"
|
||||
:is-updating="isUpdating"
|
||||
@@ -144,10 +144,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { EyeIcon, IssuesIcon, SearchIcon } from '@modrinth/assets'
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import { ButtonStyled, injectNotificationManager } from '@modrinth/ui'
|
||||
import Fuse from 'fuse.js'
|
||||
import { computed, inject, ref, watch } from 'vue'
|
||||
|
||||
import SaveBanner from '~/components/ui/servers/SaveBanner.vue'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<UiServersSaveBanner
|
||||
<SaveBanner
|
||||
:is-visible="!!hasUnsavedChanges"
|
||||
:server="props.server"
|
||||
:is-updating="isUpdating"
|
||||
@@ -115,6 +115,7 @@
|
||||
import { IssuesIcon, UpdatedIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, injectNotificationManager } from '@modrinth/ui'
|
||||
|
||||
import SaveBanner from '~/components/ui/servers/SaveBanner.vue'
|
||||
import type { ModrinthServer } from '~/composables/servers/modrinth-servers.ts'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<LazyUiServersServerManageEmptyState
|
||||
<ServerManageEmptyState
|
||||
v-else-if="serverList.length === 0 && !isPollingForNewServers && !hasError"
|
||||
/>
|
||||
|
||||
@@ -93,12 +93,8 @@
|
||||
v-if="filteredData.length > 0 || isPollingForNewServers"
|
||||
class="m-0 flex flex-col gap-4 p-0"
|
||||
>
|
||||
<UiServersServerListing
|
||||
v-for="server in filteredData"
|
||||
:key="server.server_id"
|
||||
v-bind="server"
|
||||
/>
|
||||
<LazyUiServersServerListingSkeleton v-if="isPollingForNewServers" />
|
||||
<ServerListing v-for="server in filteredData" :key="server.server_id" v-bind="server" />
|
||||
<ServerListingSkeleton v-if="isPollingForNewServers" />
|
||||
</ul>
|
||||
<div v-else class="flex h-full items-center justify-center">
|
||||
<p class="text-contrast">No servers found.</p>
|
||||
@@ -115,6 +111,9 @@ import Fuse from 'fuse.js'
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
import { reloadNuxtApp } from '#app'
|
||||
import ServerListing from '~/components/ui/servers/ServerListing.vue'
|
||||
import ServerListingSkeleton from '~/components/ui/servers/ServerListingSkeleton.vue'
|
||||
import ServerManageEmptyState from '~/components/ui/servers/ServerManageEmptyState.vue'
|
||||
import { useServersFetch } from '~/composables/servers/servers-fetch.ts'
|
||||
|
||||
definePageMeta({
|
||||
|
||||
@@ -205,12 +205,9 @@
|
||||
>
|
||||
<div class="flex flex-col justify-between gap-4">
|
||||
<div class="flex flex-col gap-4">
|
||||
<LazyUiServersModrinthServersIcon class="flex h-8 w-fit" />
|
||||
<ModrinthServersIcon class="flex h-8 w-fit" />
|
||||
<div class="flex flex-col gap-2">
|
||||
<UiServersServerListing
|
||||
v-if="subscription.serverInfo"
|
||||
v-bind="subscription.serverInfo"
|
||||
/>
|
||||
<ServerListing v-if="subscription.serverInfo" v-bind="subscription.serverInfo" />
|
||||
<div v-else class="w-fit">
|
||||
<p>
|
||||
A linked server couldn't be found for this subscription. There are a few possible
|
||||
@@ -588,6 +585,8 @@ import {
|
||||
import { calculateSavings, formatPrice, getCurrency } from '@modrinth/utils'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import ModrinthServersIcon from '~/components/ui/servers/ModrinthServersIcon.vue'
|
||||
import ServerListing from '~/components/ui/servers/ServerListing.vue'
|
||||
import { useServersFetch } from '~/composables/servers/servers-fetch.ts'
|
||||
import { products } from '~/generated/state.json'
|
||||
|
||||
|
||||
@@ -207,6 +207,8 @@
|
||||
import { CodeIcon, RadioButtonCheckedIcon, RadioButtonIcon } from '@modrinth/assets'
|
||||
import { Button, injectNotificationManager, ThemeSelector } from '@modrinth/ui'
|
||||
import { formatProjectType } from '@modrinth/utils'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
|
||||
import MessageBanner from '~/components/ui/MessageBanner.vue'
|
||||
import type { DisplayLocation } from '~/plugins/cosmetics'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { IssuesIcon, RadioButtonCheckedIcon, RadioButtonIcon } from '@modrinth/assets'
|
||||
import { commonSettingsMessages } from '@modrinth/ui'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
import Fuse from 'fuse.js/dist/fuse.basic'
|
||||
|
||||
import { isModifierKeyDown } from '~/helpers/events.ts'
|
||||
|
||||
@@ -212,6 +212,7 @@ import {
|
||||
injectNotificationManager,
|
||||
useRelativeTime,
|
||||
} from '@modrinth/ui'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
|
||||
import Modal from '~/components/ui/Modal.vue'
|
||||
import {
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
<script setup>
|
||||
import { SaveIcon, TrashIcon, UndoIcon, UploadIcon, UserIcon, XIcon } from '@modrinth/assets'
|
||||
import { Avatar, Button, commonMessages, FileInput, injectNotificationManager } from '@modrinth/ui'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
@@ -366,6 +366,7 @@ import {
|
||||
OverflowMenu,
|
||||
useRelativeTime,
|
||||
} from '@modrinth/ui'
|
||||
import { IntlFormatted } from '@vintl/vintl/components'
|
||||
|
||||
import TenMClubBadge from '~/assets/images/badges/10m-club.svg?component'
|
||||
import AlphaTesterBadge from '~/assets/images/badges/alpha-tester.svg?component'
|
||||
|
||||
5
apps/frontend/src/plugins/error-handling.ts
Normal file
5
apps/frontend/src/plugins/error-handling.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export default defineNuxtPlugin((nuxtApp) => {
|
||||
nuxtApp.hook('app:error', (error: any) => {
|
||||
console.error('An error occurred:', error)
|
||||
})
|
||||
})
|
||||
@@ -1,186 +1,186 @@
|
||||
{
|
||||
"articles": [
|
||||
{
|
||||
"title": "Skins — Now in Modrinth App!",
|
||||
"summary": "Customize your look, save your favorite skins, and swap them out in a flash, all within Modrinth App.",
|
||||
"thumbnail": "https://modrinth.com/news/article/skins-now-in-modrinth-app/thumbnail.webp",
|
||||
"date": "2025-07-06T23:45:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/skins-now-in-modrinth-app"
|
||||
},
|
||||
{
|
||||
"title": "Creator Updates, July 2025",
|
||||
"summary": "Addressing recent growth and growing pains that have been affecting creators.",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2025-07-02T04:20:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/creator-updates-july-2025"
|
||||
},
|
||||
{
|
||||
"title": "A Pride Month Success: Over $8,400 Raised for The Trevor Project!",
|
||||
"summary": "Reflecting on our Pride Month fundraiser campaign for LGBTQ+ youth.",
|
||||
"thumbnail": "https://modrinth.com/news/article/pride-campaign-2025/thumbnail.webp",
|
||||
"date": "2025-07-01T18:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/pride-campaign-2025"
|
||||
},
|
||||
{
|
||||
"title": "A New Chapter for Modrinth Servers",
|
||||
"summary": "Modrinth Servers is now fully operated in-house by the Modrinth Team.",
|
||||
"thumbnail": "https://modrinth.com/news/article/a-new-chapter-for-modrinth-servers/thumbnail.webp",
|
||||
"date": "2025-03-13T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/a-new-chapter-for-modrinth-servers"
|
||||
},
|
||||
{
|
||||
"title": "Host your own server with Modrinth Servers — now in beta",
|
||||
"summary": "Fast, simple, reliable servers directly integrated into Modrinth.",
|
||||
"thumbnail": "https://modrinth.com/news/article/modrinth-servers-beta/thumbnail.webp",
|
||||
"date": "2024-11-03T06:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/modrinth-servers-beta"
|
||||
},
|
||||
{
|
||||
"title": "Quintupling Creator Revenue and Becoming Sustainable",
|
||||
"summary": "Announcing an update to our monetization program, creator split, and more!",
|
||||
"thumbnail": "https://modrinth.com/news/article/becoming-sustainable/thumbnail.webp",
|
||||
"date": "2024-09-13T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/becoming-sustainable"
|
||||
},
|
||||
{
|
||||
"title": "Introducing Modrinth+, a refreshed site look, and a new advertising system!",
|
||||
"summary": "Learn about this major update to Modrinth.",
|
||||
"thumbnail": "https://modrinth.com/news/article/design-refresh/thumbnail.webp",
|
||||
"date": "2024-08-21T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/design-refresh"
|
||||
},
|
||||
{
|
||||
"title": "Malware Discovery Disclosure: \"Windows Borderless\" mod",
|
||||
"summary": "Threat Analysis and Plan of Action",
|
||||
"thumbnail": "https://modrinth.com/news/article/windows-borderless-malware-disclosure/thumbnail.webp",
|
||||
"date": "2024-05-07T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/windows-borderless-malware-disclosure"
|
||||
},
|
||||
{
|
||||
"title": "A Sustainable Path Forward for Modrinth",
|
||||
"summary": "Our capital return and what’s next.",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2024-04-04T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/capital-return"
|
||||
},
|
||||
{
|
||||
"title": "Creator Update: Analytics, Organizations, Collections, and more",
|
||||
"summary": "December may be over, but we’re not done giving gifts.",
|
||||
"thumbnail": "https://modrinth.com/news/article/creator-update/thumbnail.webp",
|
||||
"date": "2024-01-06T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/creator-update"
|
||||
},
|
||||
{
|
||||
"title": "Correcting Inflated Download Counts due to Rate Limiting Issue",
|
||||
"summary": "A rate limiting issue caused inflated download counts in certain countries.",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2023-11-10T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/download-adjustment"
|
||||
},
|
||||
{
|
||||
"title": "Introducing Modrinth App Beta",
|
||||
"summary": "Changing the modded Minecraft landscape with the new Modrinth App, alongside several other major features.",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2023-08-05T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/modrinth-app-beta"
|
||||
},
|
||||
{
|
||||
"title": "(April Fools 2023) Powering up your experience: Modrinth Technologies™️ beta launch!",
|
||||
"summary": "Welcome to the new era of Modrinth. We can't wait to hear your feedback.",
|
||||
"thumbnail": "https://modrinth.com/news/article/new-site-beta/thumbnail.webp",
|
||||
"date": "2023-04-01T08:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/new-site-beta"
|
||||
},
|
||||
{
|
||||
"title": "Accelerating Modrinth's Development",
|
||||
"summary": "Our fundraiser and the future of Modrinth!",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2023-02-01T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/accelerating-development"
|
||||
},
|
||||
{
|
||||
"title": "Modrinth's Anniversary Update",
|
||||
"summary": "Marking two years of Modrinth and discussing our New Year's Resolutions for 2023.",
|
||||
"thumbnail": "https://modrinth.com/news/article/two-years-of-modrinth/thumbnail.webp",
|
||||
"date": "2023-01-07T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/two-years-of-modrinth"
|
||||
},
|
||||
{
|
||||
"title": "Two years of Modrinth: a retrospective",
|
||||
"summary": "The history of Modrinth as we know it from December 2020 to December 2022.",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2023-01-07T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/two-years-of-modrinth-history"
|
||||
},
|
||||
{
|
||||
"title": "Creators can now make money on Modrinth!",
|
||||
"summary": "Introducing the Creator Monetization Program allowing creators to earn revenue from their projects.",
|
||||
"thumbnail": "https://modrinth.com/news/article/creator-monetization/thumbnail.webp",
|
||||
"date": "2022-11-12T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/creator-monetization"
|
||||
},
|
||||
{
|
||||
"title": "Modrinth's Carbon Ads experiment",
|
||||
"summary": "Experimenting with a different ad providers to find one which one works for us.",
|
||||
"thumbnail": "https://modrinth.com/news/article/carbon-ads/thumbnail.webp",
|
||||
"date": "2022-09-08T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/carbon-ads"
|
||||
},
|
||||
{
|
||||
"title": "Plugins and Resource Packs now have a home on Modrinth",
|
||||
"summary": "A small update with a big impact: plugins and resource packs are now available on Modrinth!",
|
||||
"thumbnail": "https://modrinth.com/news/article/plugins-resource-packs/thumbnail.webp",
|
||||
"date": "2022-08-27T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/plugins-resource-packs"
|
||||
},
|
||||
{
|
||||
"title": "Changes to Modrinth Modpacks",
|
||||
"summary": "CurseForge CDN links requested to be removed by the end of the month",
|
||||
"thumbnail": "https://modrinth.com/news/article/modpack-changes/thumbnail.webp",
|
||||
"date": "2022-05-28T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/modpack-changes"
|
||||
},
|
||||
{
|
||||
"title": "Modrinth Modpacks: Now in alpha testing",
|
||||
"summary": "After over a year of development, we're happy to announce that modpack support is now in alpha testing.",
|
||||
"thumbnail": "https://modrinth.com/news/article/modpacks-alpha/thumbnail.webp",
|
||||
"date": "2022-05-15T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/modpacks-alpha"
|
||||
},
|
||||
{
|
||||
"title": "This week in Modrinth development: Filters and Fixes",
|
||||
"summary": "Continuing to improve the user interface after a great first week since Modrinth launched out of beta.",
|
||||
"thumbnail": "https://modrinth.com/news/article/knossos-v2.1.0/thumbnail.webp",
|
||||
"date": "2022-03-09T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/knossos-v2.1.0"
|
||||
},
|
||||
{
|
||||
"title": "Now showing on Modrinth: A new look!",
|
||||
"summary": "Releasing many new features and improvements, including a redesign!",
|
||||
"thumbnail": "https://modrinth.com/news/article/redesign/thumbnail.webp",
|
||||
"date": "2022-02-27T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/redesign"
|
||||
},
|
||||
{
|
||||
"title": "Beginner's Guide to Licensing your Mods",
|
||||
"summary": "Software licenses; the nitty-gritty legal aspect of software development. They're more important than you think.",
|
||||
"thumbnail": "https://modrinth.com/news/article/licensing-guide/thumbnail.webp",
|
||||
"date": "2021-05-16T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/licensing-guide"
|
||||
},
|
||||
{
|
||||
"title": "Welcome to Modrinth Beta",
|
||||
"summary": "After six months of work, Modrinth enters Beta, helping modders host their mods with ease!",
|
||||
"thumbnail": "https://modrinth.com/news/article/modrinth-beta/thumbnail.webp",
|
||||
"date": "2020-12-01T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/modrinth-beta"
|
||||
},
|
||||
{
|
||||
"title": "What is Modrinth?",
|
||||
"summary": "Hello, we are Modrinth – an open source mods hosting platform. Sounds dry, doesn't it? So let me tell you our story – and I promise, it won't be boring!",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2020-11-27T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/whats-modrinth"
|
||||
}
|
||||
]
|
||||
"articles": [
|
||||
{
|
||||
"title": "Skins — Now in Modrinth App!",
|
||||
"summary": "Customize your look, save your favorite skins, and swap them out in a flash, all within Modrinth App.",
|
||||
"thumbnail": "https://modrinth.com/news/article/skins-now-in-modrinth-app/thumbnail.webp",
|
||||
"date": "2025-07-06T23:45:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/skins-now-in-modrinth-app"
|
||||
},
|
||||
{
|
||||
"title": "Creator Updates, July 2025",
|
||||
"summary": "Addressing recent growth and growing pains that have been affecting creators.",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2025-07-02T04:20:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/creator-updates-july-2025"
|
||||
},
|
||||
{
|
||||
"title": "A Pride Month Success: Over $8,400 Raised for The Trevor Project!",
|
||||
"summary": "Reflecting on our Pride Month fundraiser campaign for LGBTQ+ youth.",
|
||||
"thumbnail": "https://modrinth.com/news/article/pride-campaign-2025/thumbnail.webp",
|
||||
"date": "2025-07-01T18:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/pride-campaign-2025"
|
||||
},
|
||||
{
|
||||
"title": "A New Chapter for Modrinth Servers",
|
||||
"summary": "Modrinth Servers is now fully operated in-house by the Modrinth Team.",
|
||||
"thumbnail": "https://modrinth.com/news/article/a-new-chapter-for-modrinth-servers/thumbnail.webp",
|
||||
"date": "2025-03-13T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/a-new-chapter-for-modrinth-servers"
|
||||
},
|
||||
{
|
||||
"title": "Host your own server with Modrinth Servers — now in beta",
|
||||
"summary": "Fast, simple, reliable servers directly integrated into Modrinth.",
|
||||
"thumbnail": "https://modrinth.com/news/article/modrinth-servers-beta/thumbnail.webp",
|
||||
"date": "2024-11-03T06:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/modrinth-servers-beta"
|
||||
},
|
||||
{
|
||||
"title": "Quintupling Creator Revenue and Becoming Sustainable",
|
||||
"summary": "Announcing an update to our monetization program, creator split, and more!",
|
||||
"thumbnail": "https://modrinth.com/news/article/becoming-sustainable/thumbnail.webp",
|
||||
"date": "2024-09-13T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/becoming-sustainable"
|
||||
},
|
||||
{
|
||||
"title": "Introducing Modrinth+, a refreshed site look, and a new advertising system!",
|
||||
"summary": "Learn about this major update to Modrinth.",
|
||||
"thumbnail": "https://modrinth.com/news/article/design-refresh/thumbnail.webp",
|
||||
"date": "2024-08-21T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/design-refresh"
|
||||
},
|
||||
{
|
||||
"title": "Malware Discovery Disclosure: \"Windows Borderless\" mod",
|
||||
"summary": "Threat Analysis and Plan of Action",
|
||||
"thumbnail": "https://modrinth.com/news/article/windows-borderless-malware-disclosure/thumbnail.webp",
|
||||
"date": "2024-05-07T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/windows-borderless-malware-disclosure"
|
||||
},
|
||||
{
|
||||
"title": "A Sustainable Path Forward for Modrinth",
|
||||
"summary": "Our capital return and what’s next.",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2024-04-04T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/capital-return"
|
||||
},
|
||||
{
|
||||
"title": "Creator Update: Analytics, Organizations, Collections, and more",
|
||||
"summary": "December may be over, but we’re not done giving gifts.",
|
||||
"thumbnail": "https://modrinth.com/news/article/creator-update/thumbnail.webp",
|
||||
"date": "2024-01-06T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/creator-update"
|
||||
},
|
||||
{
|
||||
"title": "Correcting Inflated Download Counts due to Rate Limiting Issue",
|
||||
"summary": "A rate limiting issue caused inflated download counts in certain countries.",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2023-11-10T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/download-adjustment"
|
||||
},
|
||||
{
|
||||
"title": "Introducing Modrinth App Beta",
|
||||
"summary": "Changing the modded Minecraft landscape with the new Modrinth App, alongside several other major features.",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2023-08-05T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/modrinth-app-beta"
|
||||
},
|
||||
{
|
||||
"title": "(April Fools 2023) Powering up your experience: Modrinth Technologies™️ beta launch!",
|
||||
"summary": "Welcome to the new era of Modrinth. We can't wait to hear your feedback.",
|
||||
"thumbnail": "https://modrinth.com/news/article/new-site-beta/thumbnail.webp",
|
||||
"date": "2023-04-01T08:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/new-site-beta"
|
||||
},
|
||||
{
|
||||
"title": "Accelerating Modrinth's Development",
|
||||
"summary": "Our fundraiser and the future of Modrinth!",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2023-02-01T20:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/accelerating-development"
|
||||
},
|
||||
{
|
||||
"title": "Modrinth's Anniversary Update",
|
||||
"summary": "Marking two years of Modrinth and discussing our New Year's Resolutions for 2023.",
|
||||
"thumbnail": "https://modrinth.com/news/article/two-years-of-modrinth/thumbnail.webp",
|
||||
"date": "2023-01-07T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/two-years-of-modrinth"
|
||||
},
|
||||
{
|
||||
"title": "Two years of Modrinth: a retrospective",
|
||||
"summary": "The history of Modrinth as we know it from December 2020 to December 2022.",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2023-01-07T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/two-years-of-modrinth-history"
|
||||
},
|
||||
{
|
||||
"title": "Creators can now make money on Modrinth!",
|
||||
"summary": "Introducing the Creator Monetization Program allowing creators to earn revenue from their projects.",
|
||||
"thumbnail": "https://modrinth.com/news/article/creator-monetization/thumbnail.webp",
|
||||
"date": "2022-11-12T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/creator-monetization"
|
||||
},
|
||||
{
|
||||
"title": "Modrinth's Carbon Ads experiment",
|
||||
"summary": "Experimenting with a different ad providers to find one which one works for us.",
|
||||
"thumbnail": "https://modrinth.com/news/article/carbon-ads/thumbnail.webp",
|
||||
"date": "2022-09-08T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/carbon-ads"
|
||||
},
|
||||
{
|
||||
"title": "Plugins and Resource Packs now have a home on Modrinth",
|
||||
"summary": "A small update with a big impact: plugins and resource packs are now available on Modrinth!",
|
||||
"thumbnail": "https://modrinth.com/news/article/plugins-resource-packs/thumbnail.webp",
|
||||
"date": "2022-08-27T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/plugins-resource-packs"
|
||||
},
|
||||
{
|
||||
"title": "Changes to Modrinth Modpacks",
|
||||
"summary": "CurseForge CDN links requested to be removed by the end of the month",
|
||||
"thumbnail": "https://modrinth.com/news/article/modpack-changes/thumbnail.webp",
|
||||
"date": "2022-05-28T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/modpack-changes"
|
||||
},
|
||||
{
|
||||
"title": "Modrinth Modpacks: Now in alpha testing",
|
||||
"summary": "After over a year of development, we're happy to announce that modpack support is now in alpha testing.",
|
||||
"thumbnail": "https://modrinth.com/news/article/modpacks-alpha/thumbnail.webp",
|
||||
"date": "2022-05-15T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/modpacks-alpha"
|
||||
},
|
||||
{
|
||||
"title": "This week in Modrinth development: Filters and Fixes",
|
||||
"summary": "Continuing to improve the user interface after a great first week since Modrinth launched out of beta.",
|
||||
"thumbnail": "https://modrinth.com/news/article/knossos-v2.1.0/thumbnail.webp",
|
||||
"date": "2022-03-09T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/knossos-v2.1.0"
|
||||
},
|
||||
{
|
||||
"title": "Now showing on Modrinth: A new look!",
|
||||
"summary": "Releasing many new features and improvements, including a redesign!",
|
||||
"thumbnail": "https://modrinth.com/news/article/redesign/thumbnail.webp",
|
||||
"date": "2022-02-27T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/redesign"
|
||||
},
|
||||
{
|
||||
"title": "Beginner's Guide to Licensing your Mods",
|
||||
"summary": "Software licenses; the nitty-gritty legal aspect of software development. They're more important than you think.",
|
||||
"thumbnail": "https://modrinth.com/news/article/licensing-guide/thumbnail.webp",
|
||||
"date": "2021-05-16T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/licensing-guide"
|
||||
},
|
||||
{
|
||||
"title": "Welcome to Modrinth Beta",
|
||||
"summary": "After six months of work, Modrinth enters Beta, helping modders host their mods with ease!",
|
||||
"thumbnail": "https://modrinth.com/news/article/modrinth-beta/thumbnail.webp",
|
||||
"date": "2020-12-01T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/modrinth-beta"
|
||||
},
|
||||
{
|
||||
"title": "What is Modrinth?",
|
||||
"summary": "Hello, we are Modrinth – an open source mods hosting platform. Sounds dry, doesn't it? So let me tell you our story – and I promise, it won't be boring!",
|
||||
"thumbnail": "https://modrinth.com/news/default.webp",
|
||||
"date": "2020-11-27T00:00:00.000Z",
|
||||
"link": "https://modrinth.com/news/article/whats-modrinth"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user