fix: misc issues in app & website (#5512)

* fix: debug info copy button overflowing badly

* fix: updating instance's disabled mods re-enables them

* fix: modpack update enables previous disabled mods

* fix: add more languages #5508
This commit is contained in:
Truman Gao
2026-03-09 15:10:32 -07:00
committed by GitHub
parent f62c60a681
commit 9a8712c76e
6 changed files with 170 additions and 61 deletions

View File

@@ -10,6 +10,7 @@ import {
import { Admonition, ButtonStyled, Collapsible, NewModal } from '@modrinth/ui' import { Admonition, ButtonStyled, Collapsible, NewModal } from '@modrinth/ui'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { hide_ads_window, show_ads_window } from '@/helpers/ads.js'
import { login as login_flow, set_default_user } from '@/helpers/auth.js' import { login as login_flow, set_default_user } from '@/helpers/auth.js'
import { handleSevereError } from '@/store/error.js' import { handleSevereError } from '@/store/error.js'
@@ -28,13 +29,19 @@ function show(errorVal: { message?: string }) {
matchedError.value = minecraftAuthErrors.find((e) => rawError.value.includes(e.errorCode)) ?? null matchedError.value = minecraftAuthErrors.find((e) => rawError.value.includes(e.errorCode)) ?? null
debugCollapsed.value = true debugCollapsed.value = true
hide_ads_window()
modal.value?.show() modal.value?.show()
} }
function hide() { function hide() {
onModalHide()
modal.value?.hide() modal.value?.hide()
} }
function onModalHide() {
show_ads_window()
}
defineExpose({ defineExpose({
show, show,
hide, hide,
@@ -67,7 +74,7 @@ async function copyToClipboard(text: string) {
</script> </script>
<template> <template>
<NewModal ref="modal" header="Sign in Failed" :max-width="'548px'"> <NewModal ref="modal" header="Sign in Failed" :max-width="'548px'" @hide="onModalHide">
<div class="flex flex-col gap-6"> <div class="flex flex-col gap-6">
<Admonition <Admonition
type="warning" type="warning"
@@ -161,8 +168,12 @@ async function copyToClipboard(text: string) {
/> />
</button> </button>
<Collapsible :collapsed="debugCollapsed"> <Collapsible :collapsed="debugCollapsed">
<div class="p-3 bg-surface-2 rounded-2xl text-xs flex items-start"> <div
<div class="m-0 p-0 rounded-none bg-transparent text-sm font-mono"> class="p-3 bg-surface-2 rounded-2xl text-xs grid grid-cols-[1fr_auto] max-w-full items-start"
>
<div
class="m-0 p-0 rounded-none bg-transparent text-sm font-mono break-words overflow-auto"
>
{{ debugInfo }} {{ debugInfo }}
</div> </div>
<ButtonStyled circular> <ButtonStyled circular>

View File

@@ -166,6 +166,8 @@ import {
injectModrinthClient, injectModrinthClient,
injectNotificationManager, injectNotificationManager,
injectProjectPageContext, injectProjectPageContext,
SERVER_LANGUAGES,
SERVER_REGIONS,
StyledInput, StyledInput,
UnsavedChangesPopup, UnsavedChangesPopup,
} from '@modrinth/ui' } from '@modrinth/ui'
@@ -262,58 +264,15 @@ if (projectV3.value) {
) )
} }
const regionOptions = [ const regionOptions = SERVER_REGIONS.map((region) => ({
{ value: 'us_east', label: 'US East' }, value: region.code,
{ value: 'us_west', label: 'US West' }, label: region.name,
{ value: 'europe', label: 'Europe' }, }))
{ value: 'asia', label: 'Asia' },
{ value: 'australia', label: 'Australia' },
{ value: 'south_america', label: 'South America' },
{ value: 'middle_east', label: 'Middle East' },
{ value: 'russia', label: 'Russia' },
]
const languageOptions = [ const languageOptions = SERVER_LANGUAGES.map((language) => ({
{ value: 'en', label: 'English' }, value: language.code,
{ value: 'es', label: 'Spanish' }, label: language.name,
{ value: 'pt', label: 'Portuguese' }, }))
{ value: 'fr', label: 'French' },
{ value: 'de', label: 'German' },
{ value: 'it', label: 'Italian' },
{ value: 'nl', label: 'Dutch' },
{ value: 'ru', label: 'Russian' },
{ value: 'uk', label: 'Ukrainian' },
{ value: 'pl', label: 'Polish' },
{ value: 'cs', label: 'Czech' },
{ value: 'sk', label: 'Slovak' },
{ value: 'hu', label: 'Hungarian' },
{ value: 'ro', label: 'Romanian' },
{ value: 'bg', label: 'Bulgarian' },
{ value: 'hr', label: 'Croatian' },
{ value: 'sr', label: 'Serbian' },
{ value: 'el', label: 'Greek' },
{ value: 'tr', label: 'Turkish' },
{ value: 'ar', label: 'Arabic' },
{ value: 'he', label: 'Hebrew' },
{ value: 'hi', label: 'Hindi' },
{ value: 'bn', label: 'Bengali' },
{ value: 'ur', label: 'Urdu' },
{ value: 'zh', label: 'Chinese' },
{ value: 'ja', label: 'Japanese' },
{ value: 'ko', label: 'Korean' },
{ value: 'th', label: 'Thai' },
{ value: 'vi', label: 'Vietnamese' },
{ value: 'id', label: 'Indonesian' },
{ value: 'ms', label: 'Malay' },
{ value: 'tl', label: 'Filipino' },
{ value: 'sv', label: 'Swedish' },
{ value: 'no', label: 'Norwegian' },
{ value: 'da', label: 'Danish' },
{ value: 'fi', label: 'Finnish' },
{ value: 'lt', label: 'Lithuanian' },
{ value: 'lv', label: 'Latvian' },
{ value: 'et', label: 'Estonian' },
]
const javaServerPatchData = computed(() => { const javaServerPatchData = computed(() => {
const addressChanged = const addressChanged =

View File

@@ -72,6 +72,40 @@ pub enum Language {
Lt, Lt,
Lv, Lv,
Et, Et,
Af,
Am,
Az,
Be,
Bs,
Ca,
Eo,
Eu,
Fa,
Ga,
Gl,
Hy,
Is,
Ka,
Kk,
Km,
Kn,
Lo,
Mk,
Ml,
Mn,
Mr,
My,
Ne,
Pa,
Si,
Sl,
Sq,
Sw,
Ta,
Te,
Uz,
Yo,
Zu,
} }
component::define! { component::define! {

View File

@@ -342,7 +342,7 @@ pub async fn update_project(
.remove(project_path) .remove(project_path)
&& let Some(update_version) = &file.update_version_id && let Some(update_version) = &file.update_version_id
{ {
let path = Profile::add_project_version( let mut path = Profile::add_project_version(
profile_path, profile_path,
update_version, update_version,
&state.pool, &state.pool,
@@ -351,6 +351,11 @@ pub async fn update_project(
) )
.await?; .await?;
if project_path.ends_with(".disabled") {
path = Profile::toggle_disable_project(profile_path, &path)
.await?;
}
if path != project_path { if path != project_path {
Profile::remove_project(profile_path, project_path).await?; Profile::remove_project(profile_path, project_path).await?;
} }

View File

@@ -10,6 +10,7 @@ use crate::{
state::ProfileInstallStage, state::ProfileInstallStage,
}; };
use futures::try_join; use futures::try_join;
use std::collections::HashSet;
/// Updates a managed modrinth pack to the version specified by new_version_id /// Updates a managed modrinth pack to the version specified by new_version_id
#[tracing::instrument] #[tracing::instrument]
@@ -110,6 +111,22 @@ async fn replace_managed_modrinth(
new_version_id: Option<&String>, new_version_id: Option<&String>,
ignore_lock: bool, ignore_lock: bool,
) -> crate::Result<()> { ) -> crate::Result<()> {
// get disabled project ids to re-disable after update
let state = crate::State::get().await?;
let disabled_project_ids = profile
.get_projects(
Some(CacheBehaviour::MustRevalidate),
&state.pool,
&state.api_semaphore,
)
.await?
.into_iter()
.filter_map(|(file_path, project)| {
(file_path.ends_with(".disabled"))
.then_some(project.metadata?.project_id)
})
.collect::<HashSet<_>>();
crate::profile::edit(profile_path, |profile| { crate::profile::edit(profile_path, |profile| {
profile.install_stage = ProfileInstallStage::MinecraftInstalling; profile.install_stage = ProfileInstallStage::MinecraftInstalling;
async { Ok(()) } async { Ok(()) }
@@ -191,5 +208,30 @@ async fn replace_managed_modrinth(
) )
.await?; .await?;
// re-enable previously disabled project
if !disabled_project_ids.is_empty()
&& let Some(updated_profile) = get(profile_path).await?
{
for (file_path, project) in updated_profile
.get_projects(
Some(CacheBehaviour::MustRevalidate),
&state.pool,
&state.api_semaphore,
)
.await?
{
if !file_path.ends_with(".disabled")
&& let Some(metadata) = &project.metadata
&& disabled_project_ids.contains(&metadata.project_id)
{
crate::state::Profile::toggle_disable_project(
profile_path,
&file_path,
)
.await?;
}
}
}
Ok(()) Ok(())
} }

View File

@@ -19,20 +19,78 @@ export const SERVER_REGIONS = [
export const SERVER_LANGUAGES = [ export const SERVER_LANGUAGES = [
{ code: 'en', name: 'English' }, { code: 'en', name: 'English' },
{ code: 'de', name: 'German' },
{ code: 'fr', name: 'French' },
{ code: 'es', name: 'Spanish' }, { code: 'es', name: 'Spanish' },
{ code: 'pt', name: 'Portuguese' }, { code: 'pt', name: 'Portuguese' },
{ code: 'fr', name: 'French' },
{ code: 'de', name: 'German' },
{ code: 'it', name: 'Italian' },
{ code: 'nl', name: 'Dutch' },
{ code: 'ru', name: 'Russian' }, { code: 'ru', name: 'Russian' },
{ code: 'uk', name: 'Ukrainian' },
{ code: 'pl', name: 'Polish' },
{ code: 'cs', name: 'Czech' },
{ code: 'sk', name: 'Slovak' },
{ code: 'hu', name: 'Hungarian' },
{ code: 'ro', name: 'Romanian' },
{ code: 'bg', name: 'Bulgarian' },
{ code: 'hr', name: 'Croatian' },
{ code: 'sr', name: 'Serbian' },
{ code: 'el', name: 'Greek' },
{ code: 'tr', name: 'Turkish' },
{ code: 'ar', name: 'Arabic' },
{ code: 'he', name: 'Hebrew' },
{ code: 'hi', name: 'Hindi' },
{ code: 'bn', name: 'Bengali' },
{ code: 'ur', name: 'Urdu' },
{ code: 'zh', name: 'Chinese' }, { code: 'zh', name: 'Chinese' },
{ code: 'ja', name: 'Japanese' }, { code: 'ja', name: 'Japanese' },
{ code: 'ko', name: 'Korean' }, { code: 'ko', name: 'Korean' },
{ code: 'nl', name: 'Dutch' }, { code: 'th', name: 'Thai' },
{ code: 'pl', name: 'Polish' }, { code: 'vi', name: 'Vietnamese' },
{ code: 'it', name: 'Italian' }, { code: 'id', name: 'Indonesian' },
{ code: 'tr', name: 'Turkish' }, { code: 'ms', name: 'Malay' },
{ code: 'tl', name: 'Filipino' },
{ code: 'sv', name: 'Swedish' }, { code: 'sv', name: 'Swedish' },
{ code: 'no', name: 'Norwegian' },
{ code: 'da', name: 'Danish' },
{ code: 'fi', name: 'Finnish' }, { code: 'fi', name: 'Finnish' },
{ code: 'lt', name: 'Lithuanian' },
{ code: 'lv', name: 'Latvian' },
{ code: 'et', name: 'Estonian' },
{ code: 'af', name: 'Afrikaans' },
{ code: 'am', name: 'Amharic' },
{ code: 'az', name: 'Azerbaijani' },
{ code: 'be', name: 'Belarusian' },
{ code: 'bs', name: 'Bosnian' },
{ code: 'ca', name: 'Catalan' },
{ code: 'eo', name: 'Esperanto' },
{ code: 'eu', name: 'Basque' },
{ code: 'fa', name: 'Persian' },
{ code: 'ga', name: 'Irish' },
{ code: 'gl', name: 'Galician' },
{ code: 'hy', name: 'Armenian' },
{ code: 'is', name: 'Icelandic' },
{ code: 'ka', name: 'Georgian' },
{ code: 'kk', name: 'Kazakh' },
{ code: 'km', name: 'Khmer' },
{ code: 'kn', name: 'Kannada' },
{ code: 'lo', name: 'Lao' },
{ code: 'mk', name: 'Macedonian' },
{ code: 'ml', name: 'Malayalam' },
{ code: 'mn', name: 'Mongolian' },
{ code: 'mr', name: 'Marathi' },
{ code: 'my', name: 'Burmese' },
{ code: 'ne', name: 'Nepali' },
{ code: 'pa', name: 'Punjabi' },
{ code: 'si', name: 'Sinhala' },
{ code: 'sl', name: 'Slovenian' },
{ code: 'sq', name: 'Albanian' },
{ code: 'sw', name: 'Swahili' },
{ code: 'ta', name: 'Tamil' },
{ code: 'te', name: 'Telugu' },
{ code: 'uz', name: 'Uzbek' },
{ code: 'yo', name: 'Yoruba' },
{ code: 'zu', name: 'Zulu' },
] ]
export const SERVER_SORT_TYPES: SortType[] = [ export const SERVER_SORT_TYPES: SortType[] = [