+
+
+
+
+ openContextMenu(event, instance)"
+ >
+
+
+
+
+
+
+
+
+
-
-
- openContextMenu(event, instance)"
- >
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/app-frontend/src/components/ui/library/instance-group/index.vue b/apps/app-frontend/src/components/ui/library/instance-group/index.vue
index 8662927fd1..644246aee4 100644
--- a/apps/app-frontend/src/components/ui/library/instance-group/index.vue
+++ b/apps/app-frontend/src/components/ui/library/instance-group/index.vue
@@ -128,7 +128,9 @@ const cardWidth = computed(
() => (gridWidth.value - gap.value * (columnCount.value - 1)) / columnCount.value,
)
const cardHeight = computed(() =>
- compactMode.value ? remSize.value * 3.875 : Math.max(0, cardWidth.value) + remSize.value * 3.375,
+ compactMode.value
+ ? remSize.value * 3.875 + 2
+ : Math.max(0, cardWidth.value) + remSize.value * 3.375,
)
const gridHeight = computed(() =>
Math.max(
diff --git a/apps/app-frontend/src/components/ui/modal/AppSettingsModal.vue b/apps/app-frontend/src/components/ui/modal/AppSettingsModal.vue
index dd2218b22e..6a4503023f 100644
--- a/apps/app-frontend/src/components/ui/modal/AppSettingsModal.vue
+++ b/apps/app-frontend/src/components/ui/modal/AppSettingsModal.vue
@@ -25,8 +25,19 @@ import {
} from '@modrinth/ui'
import { getVersion } from '@tauri-apps/api/app'
import { platform as getOsPlatform, version as getOsVersion } from '@tauri-apps/plugin-os'
-import { computed, defineAsyncComponent, provide, ref, watch } from 'vue'
+import { computed, provide, ref, watch } from 'vue'
+import PrivacySettings from '@/components/ui/settings/account/PrivacySettings.vue'
+import ProfileSettings from '@/components/ui/settings/account/ProfileSettings.vue'
+import SocialSettings from '@/components/ui/settings/account/SocialSettings.vue'
+import AppearanceSettings from '@/components/ui/settings/display/AppearanceSettings.vue'
+import BehaviorSettings from '@/components/ui/settings/display/BehaviorSettings.vue'
+import FeatureFlagSettings from '@/components/ui/settings/display/FeatureFlagSettings.vue'
+import FeaturesSettings from '@/components/ui/settings/display/FeaturesSettings.vue'
+import LanguageSettings from '@/components/ui/settings/display/LanguageSettings.vue'
+import InstancesSyncedSettings from '@/components/ui/settings/instances/instances-synced-settings/index.vue'
+import JavaSettings from '@/components/ui/settings/instances/JavaSettings.vue'
+import ResourceManagementSettings from '@/components/ui/settings/instances/ResourceManagementSettings.vue'
import { useAppSettings } from '@/composables/use-app-settings.ts'
import { get, set } from '@/helpers/settings.ts'
import {
@@ -35,40 +46,6 @@ import {
} from '@/providers/app-settings-modal'
import { injectAppUpdateDownloadProgress } from '@/providers/download-progress.ts'
-const PrivacySettings = defineAsyncComponent(
- () => import('@/components/ui/settings/account/PrivacySettings.vue'),
-)
-const ProfileSettings = defineAsyncComponent(
- () => import('@/components/ui/settings/account/ProfileSettings.vue'),
-)
-const SocialSettings = defineAsyncComponent(
- () => import('@/components/ui/settings/account/SocialSettings.vue'),
-)
-const AppearanceSettings = defineAsyncComponent(
- () => import('@/components/ui/settings/display/AppearanceSettings.vue'),
-)
-const BehaviorSettings = defineAsyncComponent(
- () => import('@/components/ui/settings/display/BehaviorSettings.vue'),
-)
-const FeatureFlagSettings = defineAsyncComponent(
- () => import('@/components/ui/settings/display/FeatureFlagSettings.vue'),
-)
-const FeaturesSettings = defineAsyncComponent(
- () => import('@/components/ui/settings/display/FeaturesSettings.vue'),
-)
-const LanguageSettings = defineAsyncComponent(
- () => import('@/components/ui/settings/display/LanguageSettings.vue'),
-)
-const InstancesSyncedSettings = defineAsyncComponent(
- () => import('@/components/ui/settings/instances/instances-synced-settings/index.vue'),
-)
-const JavaSettings = defineAsyncComponent(
- () => import('@/components/ui/settings/instances/JavaSettings.vue'),
-)
-const ResourceManagementSettings = defineAsyncComponent(
- () => import('@/components/ui/settings/instances/ResourceManagementSettings.vue'),
-)
-
// TODO: Apply COMPONENT_STRUCTURE.md here and extract out common setting option components
const appSettings = useAppSettings()
diff --git a/apps/app-frontend/src/components/ui/settings/display/AppearanceSettings.vue b/apps/app-frontend/src/components/ui/settings/display/AppearanceSettings.vue
index 040cd599db..1c51953150 100644
--- a/apps/app-frontend/src/components/ui/settings/display/AppearanceSettings.vue
+++ b/apps/app-frontend/src/components/ui/settings/display/AppearanceSettings.vue
@@ -6,19 +6,20 @@ import {
provideAppearanceSettings,
useSavable,
} from '@modrinth/ui'
-import { computed, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'
+import { platform } from '@tauri-apps/plugin-os'
+import { computed, inject, onBeforeUnmount, onMounted, watch } from 'vue'
+import { useAppSettings } from '@/composables/use-app-settings.ts'
import { type ColorTheme, isDarkTheme, useTheme } from '@/composables/use-theme.ts'
import { type AppSettings, get, set } from '@/helpers/settings.ts'
-import { getOS } from '@/helpers/utils'
import { appSettingsModalContextKey } from '@/providers/app-settings-modal'
const theme = useTheme()
+const appSettings = useAppSettings()
const auth = injectAuth()
const { updatePreferences } = injectUserPreferences()
const settingsModal = inject(appSettingsModalContextKey, null)
-const os = await getOS()
-const settings = ref(await get())
+const os = platform()
type AppearanceSettingsState = {
theme: ColorTheme
@@ -27,17 +28,17 @@ type AppearanceSettingsState = {
nativeDecorations: boolean
}
-function getAppearanceSettingsState(settings: AppSettings): AppearanceSettingsState {
+function getAppearanceSettingsState(): AppearanceSettingsState {
return {
- theme: settings.theme,
- syncAcrossDevices: settings.sync_theme_across_devices,
- advancedRendering: settings.advanced_rendering,
- nativeDecorations: settings.native_decorations,
+ theme: theme.preferred,
+ syncAcrossDevices: theme.syncAcrossDevices,
+ advancedRendering: theme.advancedRendering,
+ nativeDecorations: appSettings.nativeDecorations,
}
}
const { saved, current, changes, saving, hasChanges, reset, save } = useSavable(
- () => getAppearanceSettingsState(settings.value),
+ getAppearanceSettingsState,
async (appearanceChanges) => {
const value = current.value
if (
@@ -51,7 +52,7 @@ const { saved, current, changes, saving, hasChanges, reset, save } = useSavable(
}
const nextSettings: AppSettings = {
- ...settings.value,
+ ...(await get()),
theme: value.theme,
sync_theme_across_devices: value.syncAcrossDevices,
advanced_rendering: value.advancedRendering,
@@ -59,20 +60,19 @@ const { saved, current, changes, saving, hasChanges, reset, save } = useSavable(
}
await set(nextSettings)
- settings.value = nextSettings
if (isDarkTheme(value.theme)) {
theme.preferredDark = value.theme
}
theme.preferred = value.theme
theme.syncAcrossDevices = value.syncAcrossDevices
theme.advancedRendering = value.advancedRendering
+ appSettings.nativeDecorations = value.nativeDecorations
},
)
const themeOptions = computed(() =>
theme.options.filter(
- (option) =>
- option !== 'retro' || settings.value.developer_mode || current.value.theme === 'retro',
+ (option) => option !== 'retro' || appSettings.devMode || current.value.theme === 'retro',
),
)
@@ -147,7 +147,7 @@ provideAppearanceSettings({
set: setAdvancedRendering,
},
nativeDecorations:
- os !== 'MacOS'
+ os !== 'macos'
? {
value: computed(() => current.value.nativeDecorations),
set: setNativeDecorations,
diff --git a/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/editors.ts b/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/editors.ts
index 0ccd80d64d..16908ab858 100644
--- a/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/editors.ts
+++ b/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/editors.ts
@@ -64,6 +64,11 @@ export function gameSettingChanges(
})
}
+export function gameSettingNumberScale(setting: EditableGameSetting): number {
+ if (setting.editor.unit !== 'percent') return 1
+ return setting.option_id === 'sensitivity' ? 200 : 100
+}
+
export function canonicalValueText(setting: EditableGameSetting): string {
const value = setting.canonical_value
if (!value) return ''
@@ -74,7 +79,7 @@ export function canonicalValueText(setting: EditableGameSetting): string {
case 'integer':
case 'decimal':
return setting.editor.unit === 'percent'
- ? String(Number((Number(value.value) * 100).toFixed(8)))
+ ? String(Number((Number(value.value) * gameSettingNumberScale(setting)).toFixed(8)))
: String(value.value)
case 'string_list':
return value.value.join(', ')
@@ -90,7 +95,7 @@ export function canonicalBooleanValue(setting: EditableGameSetting): boolean | u
export function isKeybindSetting(setting: EditableGameSetting): boolean {
return (
setting.editor.type === 'key_binding' ||
- (setting.editor.type === 'external_raw' && !!setting.raw_key?.startsWith('key_key'))
+ (setting.editor.type === 'external_raw' && !!setting.raw_key?.startsWith('key_'))
)
}
@@ -114,7 +119,7 @@ export function canonicalValueFromInput(
type: 'decimal',
value:
setting.editor.unit === 'percent'
- ? String(Number((parsed / 100).toFixed(8)))
+ ? String(Number((parsed / gameSettingNumberScale(setting)).toFixed(8)))
: String(value),
}
}
diff --git a/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/index.vue b/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/index.vue
index f1a826bb1d..d5d4bade03 100644
--- a/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/index.vue
+++ b/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/index.vue
@@ -29,9 +29,12 @@ import {
useVIntl,
} from '@modrinth/ui'
import type { Component } from 'vue'
-import { computed, ref } from 'vue'
+import { computed, inject, ref } from 'vue'
+import { type RouteLocationRaw, useRouter } from 'vue-router'
import type { EditableGameSetting, GameSettingCategory } from '@/helpers/game-options'
+import { injectInstanceSettings } from '@/pages/instance/components/settings-modal/instance-settings-context'
+import { appSettingsModalContextKey } from '@/providers/app-settings-modal'
import {
canonicalValueText,
@@ -47,6 +50,7 @@ import {
} from './messages'
import GameSettingRow from './row.vue'
import { useGameSettingsEditor } from './use-editor'
+import { useGameSettingLabels } from './use-labels'
const props = defineProps<{
instanceId?: string
@@ -57,6 +61,9 @@ const emit = defineEmits<{
}>()
const { formatMessage } = useVIntl()
+const router = useRouter()
+const appSettingsModal = inject(appSettingsModalContextKey, null)
+const instanceSettings = injectInstanceSettings(null)
const messages = defineMessages({
title: {
@@ -119,6 +126,7 @@ const modal = ref
| null>(null)
const confirmLeaveModal = ref | null>(null)
const activeCategoryId = ref('')
const search = ref('')
+const opened = ref(false)
let allowClose = false
const {
@@ -154,6 +162,21 @@ const categoryIcons: Record = {
custom_settings: WrenchIcon,
}
+const localeLabels = useGameSettingLabels(
+ opened,
+ () => props.instanceId,
+ () => draftState.value?.settings ?? [],
+)
+
+function settingLabel(setting: EditableGameSetting) {
+ if (setting.kind === 'external') {
+ return (
+ localeLabels.value[setting.option_id]?.label ?? formatGameSettingLabel(formatMessage, setting)
+ )
+ }
+ return formatGameSettingLabel(formatMessage, setting)
+}
+
const categories = computed(() => {
if (!draftState.value) return []
@@ -192,8 +215,12 @@ const categorySettings = computed(() => {
query &&
!settingSearchText(
setting,
- formatGameSettingLabel(formatMessage, setting),
- formatGameSettingDescription(formatMessage, setting),
+ settingLabel(setting),
+ setting.kind === 'external'
+ ? (localeLabels.value[setting.option_id]?.source?.project?.title ??
+ localeLabels.value[setting.option_id]?.source?.file_name ??
+ '')
+ : formatGameSettingDescription(formatMessage, setting),
).includes(query)
)
return false
@@ -220,7 +247,7 @@ const keybindConflicts = computed(() => {
setting.option_id,
settings
.filter((candidate) => candidate.option_id !== setting.option_id)
- .map((candidate) => formatGameSettingLabel(formatMessage, candidate)),
+ .map((candidate) => settingLabel(candidate)),
)
}
}
@@ -267,6 +294,7 @@ async function load() {
}
function show() {
+ opened.value = true
allowClose = false
search.value = ''
modal.value?.show()
@@ -278,6 +306,7 @@ function hide() {
}
function reset() {
+ opened.value = false
resetEditor()
allowClose = false
}
@@ -295,6 +324,18 @@ async function confirmDiscard() {
modal.value?.hide()
}
+async function openSource(location: RouteLocationRaw) {
+ if (isDirty.value || saving.value) return
+ if (appSettingsModal && !appSettingsModal.close()) return
+ allowClose = true
+ modal.value?.hide()
+ if (instanceSettings?.closeModal) {
+ instanceSettings.closeModal(() => void router.push(location))
+ } else {
+ await router.push(location)
+ }
+}
+
function toggleVisibleSync() {
const enabled = !allCategorySettingsSynced.value
const candidates = enabled ? enableCandidates.value : disableCandidates.value
@@ -394,8 +435,11 @@ defineExpose({ show, hide })
v-for="setting in categorySettings"
:key="setting.option_id"
:setting="setting"
+ :locale-label="localeLabels[setting.option_id]"
:keybind-conflicts="keybindConflicts.get(setting.option_id)"
:show-sync-toggle="!isLocalEditor"
+ :source-navigation-disabled="isDirty || saving"
+ @open-source="openSource"
@update:sync-enabled="setSyncEnabled([setting.option_id], $event)"
@update:canonical-value="setCanonicalValue(setting.option_id, $event)"
/>
diff --git a/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/languages.ts b/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/languages.ts
new file mode 100644
index 0000000000..752e3aa928
--- /dev/null
+++ b/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/languages.ts
@@ -0,0 +1,152 @@
+import type { ComboboxOption } from '@modrinth/ui'
+
+/** Java Edition language names and regions from https://github.com/misode/mcmeta/blob/assets/pack.mcmeta. */
+const languageNames: Record = {
+ en_us: 'English (US)',
+ af_za: 'Afrikaans (Suid-Afrika)',
+ esan: 'Andalûh (Andaluçía)',
+ enp: 'Anglish (Oned Riches)',
+ ast_es: 'Asturianu (Asturies)',
+ az_az: 'Azərbaycanca (Azərbaycan)',
+ id_id: 'Bahasa Indonesia (Indonesia)',
+ ms_my: 'Bahasa Melayu (Malaysia)',
+ tzo_mx: "Bats'i k'op (Jobel)",
+ qid: 'Bhs. Indonesia edjaän lama (Indonesia tempo doeloe)',
+ be_latn: 'Biełaruskaja (Biełaruś)',
+ bar: 'Boarisch (Bayern)',
+ bs_ba: 'Bosanski (Bosna i Hercegovina)',
+ brb: 'Braobans (Braobant)',
+ br_fr: 'Brezhoneg (Breizh)',
+ ca_es: 'Català (Catalunya)',
+ val_es: 'Català (Valencià) (País Valencià)',
+ cy_gb: 'Cymraeg (Cymru)',
+ qcb_es: 'Cántabru/Montañés (Cantabria)',
+ da_dk: 'Dansk (Danmark)',
+ se_no: 'Davvisámegiella (Sápmi)',
+ de_at: 'Deitsch (Österreich)',
+ de_de: 'Deutsch (Deutschland)',
+ et_ee: 'Eesti keel (Eesti)',
+ en_au: 'English (Australia)',
+ en_ca: 'English (Canada)',
+ en_nz: 'English (New Zealand)',
+ en_gb: 'English (United Kingdom)',
+ es_ar: 'Español (Argentina)',
+ es_cl: 'Español (Chile)',
+ es_ec: 'Español (Ecuador)',
+ es_es: 'Español (España)',
+ es_mx: 'Español (México)',
+ es_uy: 'Español (Uruguay)',
+ es_ve: 'Español (Venezuela)',
+ eo_uy: 'Esperanto (Esperantujo)',
+ eu_es: 'Euskara (Euskal Herria)',
+ fil_ph: 'Filipino (Pilipinas)',
+ fr_ca: 'Français (Canada)',
+ fr_fr: 'Français (France)',
+ fr_ch: 'Français (Suisse)',
+ fy_nl: 'Frysk (Fryslân)',
+ fra_de: 'Fränggisch (Franggn)',
+ fur_it: 'Furlan (Friûl)',
+ fo_fo: 'Føroyskt (Føroyar)',
+ ga_ie: 'Gaeilge (Éire)',
+ gl_es: 'Galego (Galicia / Galiza)',
+ go_fr: 'Galo (Bertègn)',
+ gd_gb: 'Gàidhlig (Alba)',
+ hr_hr: 'Hrvatski (Hrvatska)',
+ hn_no: 'Høgnorsk (Norig)',
+ io_en: 'Ido (Idia)',
+ ig_ng: 'Igbo (Naigeria)',
+ it_it: 'Italiano (Italia)',
+ kw_gb: 'Kernewek (Kernow)',
+ ksh: 'Kölsch/Ripoarisch (Rhingland)',
+ lol_us: 'LOLCAT (Kingdom of Cats)',
+ la_la: 'Latina (Latium)',
+ lv_lv: 'Latviešu (Latvija)',
+ lt_lt: 'Lietuvių (Lietuva)',
+ li_li: 'Limburgs (Limburg)',
+ lmo: 'Lombard (Lombardia)',
+ lb_lu: 'Lëtzebuergesch (Lëtzebuerg)',
+ hu_hu: 'Magyar (Magyarország)',
+ mt_mt: 'Malti (Malta)',
+ isv: 'Medžuslovjansky (Slovjanščina)',
+ nah: 'Mēxikatlahtōlli (Mēxiko)',
+ nl_nl: 'Nederlands (Nederland)',
+ pls: 'Ngiiwà (Ndanìꞌngà)',
+ no_no: 'Norsk bokmål (Norge)',
+ nn_no: 'Norsk nynorsk (Noreg)',
+ uz_uz: "O'zbekcha (O'zbekiston)",
+ oc_fr: 'Occitan (Occitània)',
+ en_pt: 'Pirate Speak (The Seven Seas)',
+ nds_de: 'Plattdüütsch (Düütschland)',
+ pl_pl: 'Polski (Polska)',
+ pt_br: 'Português (Brasil)',
+ pt_pt: 'Português (Portugal)',
+ qya_aa: 'Quenya (Arda)',
+ ro_ro: 'Română (România)',
+ de_ch: 'Schwiizerdütsch (Schwiiz)',
+ enws: 'Shakespearean English (Kingdom of England)',
+ sq_al: 'Shqip (Shqipëri)',
+ sk_sk: 'Slovenčina (Slovensko)',
+ sl_si: 'Slovenščina (Slovenija)',
+ so_so: 'Soomaali (Soomaaliya)',
+ sr_cs: 'Srpski (Srbija)',
+ fi_fi: 'Suomi (Suomi)',
+ sv_se: 'Svenska (Sverige)',
+ sxu: 'Säggs’sch (Saggsn)',
+ tl_ph: 'Tagalog (Pilipinas)',
+ vi_vn: 'Tiếng Việt (Việt Nam)',
+ tr_tr: 'Türkçe (Türkiye)',
+ vp_vl: 'Viossa (Vilant)',
+ nl_be: 'Vlaams (België)',
+ vec_it: 'Vèneto (Veneto)',
+ vro: 'Võro (Eesti)',
+ yo_ng: 'Yorùbá (Nàìjíríà)',
+ jbo_en: "la .lojban. (la jbogu'e)",
+ tlh_aa: "tlhIngan Hol (tlhIngan wo')",
+ tok: 'toki pona (kulupu pona)',
+ is_is: 'Íslenska (Ísland)',
+ ovd: 'Övdalska (Swerre)',
+ cs_cz: 'Čeština (Česko)',
+ szl: 'Ślōnski (Gōrny Ślōnsk)',
+ en_ud: 'ɥsᴉꞁᵷuƎ (uʍoᗡ ǝpᴉsd∩)',
+ haw_us: 'ʻŌlelo Hawaiʻi (Hawaiʻi)',
+ el_gr: 'Ελληνικά (Ελλάδα)',
+ ba_ru: 'Башҡортса (Башҡортостан, Рәсәй)',
+ be_by: 'Беларуская (Беларусь)',
+ bg_bg: 'Български (България)',
+ hal_ua: 'Галицка (Галичина, Вкраїна)',
+ ky_kg: 'Кыргызча (Кыргызстан)',
+ mk_mk: 'Македонски (Северна Македонија)',
+ mn_mn: 'Монгол (Монгол Улс)',
+ ry_ua: 'Руснацькый (Пудкарпатя, Украина)',
+ ru_ru: 'Русский (Россия)',
+ rpr: 'Русскій дореформенный (Россійская имперія)',
+ sah_sah: 'Сахалыы (Cаха Сирэ)',
+ sr_sp: 'Српски (Србија)',
+ tt_ru: 'Татарча (Татарстан, Рәсәй)',
+ uk_ua: 'Українська (Україна)',
+ cv_cu: 'Чӑвашла (Чӑваш Ен, Раҫҫей)',
+ kk_kz: 'Қазақша (Қазақстан)',
+ hy_am: 'Հայերեն (Հայաստան)',
+ yi_de: 'ייִדיש (אשכנזיש יידן)',
+ he_il: 'עברית (ישראל)',
+ ar_sa: 'العربية (العالم العربي)',
+ zlm_arab: 'بهاس ملايو (مليسيا)',
+ fa_ir: 'فارسی (ايران)',
+ hi_in: 'हिंदी (भारत)',
+ ta_in: 'தமிழ் (இந்தியா)',
+ kn_in: 'ಕನ್ನಡ (ಭಾರತ)',
+ th_th: 'ไทย (ประเทศไทย)',
+ lo_la: 'ລາວ (ປະເທດລາວ)',
+ ka_ge: 'ქართული (საქართველო)',
+ lzh: '文言 (華夏)',
+ ja_jp: '日本語 (日本)',
+ zh_cn: '简体中文 (中国大陆)',
+ zh_tw: '繁體中文 (台灣)',
+ zh_hk: '繁體中文 (香港特別行政區)',
+ ko_kr: '한국어 (대한민국)',
+ got_de: '𐌲𐌿𐍄𐍂𐌰𐌶𐌳𐌰 (𐌲𐌿𐍄𐌸𐌹𐌿𐌳𐌰)',
+}
+
+export const minecraftLanguageOptions: ComboboxOption[] = Object.entries(languageNames)
+ .map(([value, label]) => ({ value, label, searchTerms: [value] }))
+ .sort((a, b) => a.label.localeCompare(b.label))
diff --git a/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/row.vue b/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/row.vue
index 049afab5c1..3c82fe7483 100644
--- a/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/row.vue
+++ b/apps/app-frontend/src/components/ui/settings/instances/game-settings-modal/row.vue
@@ -1,6 +1,7 @@
diff --git a/apps/app-frontend/src/pages/instance/components/settings-modal/java-settings.vue b/apps/app-frontend/src/pages/instance/components/settings-modal/java-settings.vue
index a660b09eaf..c94f3b01a3 100644
--- a/apps/app-frontend/src/pages/instance/components/settings-modal/java-settings.vue
+++ b/apps/app-frontend/src/pages/instance/components/settings-modal/java-settings.vue
@@ -228,6 +228,8 @@ const messages = defineMessages({
:step="64"
:snap-points="snapPoints"
:snap-range="512"
+ min-label="512 MB"
+ :max-label="`${Number((maxMemory / 1024).toFixed(1))} GB`"
unit="MB"
/>
diff --git a/apps/app-frontend/src/pages/instance/content/index.vue b/apps/app-frontend/src/pages/instance/content/index.vue
index 04e2d2df4d..347c4081b3 100644
--- a/apps/app-frontend/src/pages/instance/content/index.vue
+++ b/apps/app-frontend/src/pages/instance/content/index.vue
@@ -1,6 +1,6 @@