diff --git a/apps/app-frontend/package.json b/apps/app-frontend/package.json
index 44439c7976..a0468e289a 100644
--- a/apps/app-frontend/package.json
+++ b/apps/app-frontend/package.json
@@ -28,7 +28,8 @@
"@tauri-apps/plugin-updater": "^2.7.1",
"@tauri-apps/plugin-window-state": "^2.2.2",
"@types/three": "^0.172.0",
- "@vintl/vintl": "^4.4.1",
+ "intl-messageformat": "^10.7.7",
+ "vue-i18n": "^9.14.0",
"@vueuse/core": "^11.1.0",
"dayjs": "^1.11.10",
"floating-vue": "^5.2.2",
diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue
index 26f041fd68..4901748de8 100644
--- a/apps/app-frontend/src/App.vue
+++ b/apps/app-frontend/src/App.vue
@@ -31,6 +31,7 @@ import {
Button,
ButtonStyled,
commonMessages,
+ defineMessages,
NewsArticleCard,
NotificationPanel,
OverflowMenu,
@@ -39,6 +40,7 @@ import {
provideNotificationManager,
providePageContext,
useDebugLogger,
+ useVIntl,
} from '@modrinth/ui'
import { renderString } from '@modrinth/utils'
import { useQuery } from '@tanstack/vue-query'
@@ -48,7 +50,6 @@ import { getCurrentWindow } from '@tauri-apps/api/window'
import { openUrl } from '@tauri-apps/plugin-opener'
import { type } from '@tauri-apps/plugin-os'
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
-import { defineMessages, useVIntl } from '@vintl/vintl'
import { $fetch } from 'ofetch'
import { computed, onMounted, onUnmounted, provide, ref, watch } from 'vue'
import { RouterView, useRoute, useRouter } from 'vue-router'
diff --git a/apps/app-frontend/src/components/ui/UpdateToast.vue b/apps/app-frontend/src/components/ui/UpdateToast.vue
index af9676080d..b9b95f235a 100644
--- a/apps/app-frontend/src/components/ui/UpdateToast.vue
+++ b/apps/app-frontend/src/components/ui/UpdateToast.vue
@@ -1,8 +1,7 @@
@@ -298,7 +188,7 @@ function getItemLabel(locale: Locale) {
-
+
@@ -306,7 +196,7 @@ function getItemLabel(locale: Locale) {
-
+
-
- {{ formatMessage(messages.searchFieldDescription) }}
-
-
{{
isQueryEmpty()
@@ -335,59 +220,46 @@ function getItemLabel(locale: Locale) {
-
+
{{ formatMessage(categoryNames[category]) }}
{{ formatMessage(messages.noResults) }}
-
+
onItemClick(e, locale)"
- @keydown="(e) => onItemKeydown(e, locale)"
+ :aria-label="getItemLabel(loc)"
+ @click="(e) => onItemClick(e, loc)"
+ @keydown="(e) => onItemKeydown(e, loc)"
>
-
+
- {{ locale.auto ? formatMessage(messages.automaticLocale) : locale.displayName }}
+ {{ loc.displayName }}
-
- {{ locale.translatedName }}
+
+ {{ loc.nativeName }}
-
-
-
- {{ formatMessage(messages.loadFailed) }}
-
@@ -423,14 +295,6 @@ function getItemLabel(locale: Locale) {
outline: 2px solid var(--color-brand);
}
- &.errored {
- border-color: var(--color-red);
-
- &:hover {
- border-color: var(--color-red);
- }
- }
-
&.pending::after {
content: '';
position: absolute;
@@ -482,15 +346,6 @@ function getItemLabel(locale: Locale) {
}
}
-.language-load-error {
- color: var(--color-red);
- font-size: var(--font-size-sm);
- margin-left: 0.3rem;
- display: flex;
- align-items: center;
- gap: 0.3rem;
-}
-
.radio {
width: 24px;
height: 24px;
@@ -534,4 +389,9 @@ function getItemLabel(locale: Locale) {
.category-name {
margin-top: var(--spacing-card-md);
}
+
+.no-results {
+ padding: var(--spacing-card-md);
+ color: var(--color-text-secondary);
+}
diff --git a/apps/frontend/src/pages/settings/pats.vue b/apps/frontend/src/pages/settings/pats.vue
index bf55bb70e6..8294f2ae59 100644
--- a/apps/frontend/src/pages/settings/pats.vue
+++ b/apps/frontend/src/pages/settings/pats.vue
@@ -209,10 +209,12 @@ import {
commonSettingsMessages,
ConfirmModal,
CopyCode,
+ defineMessages,
injectNotificationManager,
+ IntlFormatted,
useRelativeTime,
+ useVIntl,
} from '@modrinth/ui'
-import { IntlFormatted } from '@vintl/vintl/components'
import Modal from '~/components/ui/Modal.vue'
import {
diff --git a/apps/frontend/src/pages/settings/profile.vue b/apps/frontend/src/pages/settings/profile.vue
index 12be87ddba..b898d5c8d1 100644
--- a/apps/frontend/src/pages/settings/profile.vue
+++ b/apps/frontend/src/pages/settings/profile.vue
@@ -91,8 +91,16 @@
+
+
+
+
+ {{ part }}
+
+
diff --git a/packages/ui/src/components/base/MarkdownEditor.vue b/packages/ui/src/components/base/MarkdownEditor.vue
index 5cd84290b5..90217e25c5 100644
--- a/packages/ui/src/components/base/MarkdownEditor.vue
+++ b/packages/ui/src/components/base/MarkdownEditor.vue
@@ -292,11 +292,11 @@ import {
XIcon,
YouTubeIcon,
} from '@modrinth/assets'
-import NewModal from '@modrinth/ui/src/components/modal/NewModal.vue'
import { markdownCommands, modrinthMarkdownEditorKeymap } from '@modrinth/utils/codemirror'
import { renderHighlightedString } from '@modrinth/utils/highlightjs'
import { type Component, computed, onBeforeUnmount, onMounted, ref, toRef, watch } from 'vue'
+import NewModal from '../modal/NewModal.vue'
import Button from './Button.vue'
import Chips from './Chips.vue'
import FileInput from './FileInput.vue'
diff --git a/packages/ui/src/components/base/OptionGroup.vue b/packages/ui/src/components/base/OptionGroup.vue
index 556e2cdbb4..d14c4e0a75 100644
--- a/packages/ui/src/components/base/OptionGroup.vue
+++ b/packages/ui/src/components/base/OptionGroup.vue
@@ -31,7 +31,7 @@