diff --git a/Cargo.lock b/Cargo.lock index 6418e594..e88d03e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5099,10 +5099,13 @@ dependencies = [ "derive_more 2.0.1", "dotenvy", "eyre", + "rust_decimal", "serde", + "serde_json", "tracing", "tracing-ecs", "tracing-subscriber", + "utoipa", ] [[package]] diff --git a/apps/app-frontend/src/pages/instance/Mods.vue b/apps/app-frontend/src/pages/instance/Mods.vue index 91b9f70f..a2c3c80e 100644 --- a/apps/app-frontend/src/pages/instance/Mods.vue +++ b/apps/app-frontend/src/pages/instance/Mods.vue @@ -301,11 +301,13 @@ import { get_organization_many, get_project_many, get_team_many, + get_version, get_version_many, } from '@/helpers/cache.js' import { profile_listener } from '@/helpers/events.js' import { add_project_from_path, + get, get_projects, remove_project, toggle_disable_project, @@ -314,6 +316,7 @@ import { } from '@/helpers/profile.js' import type { CacheBehaviour, ContentFile, GameInstance } from '@/helpers/types' import { highlightModInProfile } from '@/helpers/utils.js' +import { installVersionDependencies } from '@/store/install' const { handleError } = injectNotificationManager() @@ -627,10 +630,15 @@ const sortProjects = (filter: string) => { const updateAll = async () => { const setProjects = [] + const outdatedProjects = [] + for (const [i, project] of projects.value.entries()) { if (project.outdated) { project.updating = true setProjects.push(i) + if (project.updateVersion) { + outdatedProjects.push(project.updateVersion) + } } } @@ -646,6 +654,21 @@ const updateAll = async () => { projects.value[index].updateVersion = undefined } } + + if (outdatedProjects.length > 0) { + const profile = await get(props.instance.path).catch(handleError) + + if (profile) { + for (const versionId of outdatedProjects) { + const versionData = await get_version(versionId, 'must_revalidate').catch(handleError) + + if (versionData) { + await installVersionDependencies(profile, versionData).catch(handleError) + } + } + } + } + for (const project of setProjects) { projects.value[project].updating = false } @@ -662,6 +685,19 @@ const updateProject = async (mod: ProjectListEntry) => { mod.updating = true await new Promise((resolve) => setTimeout(resolve, 0)) mod.path = await update_project(props.instance.path, mod.path).catch(handleError) + + if (mod.updateVersion) { + const versionData = await get_version(mod.updateVersion, 'must_revalidate').catch(handleError) + + if (versionData) { + const profile = await get(props.instance.path).catch(handleError) + + if (profile) { + await installVersionDependencies(profile, versionData).catch(handleError) + } + } + } + mod.updating = false mod.outdated = false diff --git a/apps/app/src/main.rs b/apps/app/src/main.rs index b354b8d7..9ee5e0a9 100644 --- a/apps/app/src/main.rs +++ b/apps/app/src/main.rs @@ -2,6 +2,7 @@ all(not(debug_assertions), target_os = "windows"), windows_subsystem = "windows" )] +#![recursion_limit = "256"] use native_dialog::{DialogBuilder, MessageLevel}; use std::env; diff --git a/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue b/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue index 2b427934..6d8135de 100644 --- a/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue +++ b/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue @@ -85,6 +85,7 @@ @@ -446,6 +447,11 @@ function resetProgress() { localStorage.removeItem(`modpack-permissions-${props.project.id}`) localStorage.removeItem(`modpack-permissions-index-${props.project.id}`) + + sessionStorage.removeItem(`modpack-permissions-data-${props.project.id}`) + sessionStorage.removeItem(`modpack-permissions-permanent-no-${props.project.id}`) + sessionStorage.removeItem(`modpack-permissions-updated-${props.project.id}`) + modpackPermissionsComplete.value = false modpackJudgements.value = {} @@ -1331,6 +1337,11 @@ function clearProjectLocalStorage() { localStorage.removeItem(`moderation-actions-${props.project.slug}`) localStorage.removeItem(`moderation-inputs-${props.project.slug}`) localStorage.removeItem(`moderation-stage-${props.project.slug}`) + + sessionStorage.removeItem(`modpack-permissions-data-${props.project.id}`) + sessionStorage.removeItem(`modpack-permissions-permanent-no-${props.project.id}`) + sessionStorage.removeItem(`modpack-permissions-updated-${props.project.id}`) + actionStates.value = {} } diff --git a/apps/frontend/src/components/ui/moderation/checklist/ModpackPermissionsFlow.vue b/apps/frontend/src/components/ui/moderation/checklist/ModpackPermissionsFlow.vue index 8cdbdbe1..4f96a4b7 100644 --- a/apps/frontend/src/components/ui/moderation/checklist/ModpackPermissionsFlow.vue +++ b/apps/frontend/src/components/ui/moderation/checklist/ModpackPermissionsFlow.vue @@ -161,6 +161,7 @@ import { computed, onMounted, ref, watch } from 'vue' const props = defineProps<{ projectId: string + projectUpdated: string modelValue?: ModerationJudgements }>() @@ -202,6 +203,10 @@ const permanentNoFiles = useSessionStorage( }, }, ) +const cachedProjectUpdated = useSessionStorage( + `modpack-permissions-updated-${props.projectId}`, + null, +) const currentIndex = ref(0) const fileApprovalTypes: ModerationModpackPermissionApprovalType[] = [ @@ -363,11 +368,13 @@ async function fetchModPackData(): Promise { } modPackData.value = sortedData + cachedProjectUpdated.value = props.projectUpdated persistAll() } catch (error) { console.error('Failed to fetch modpack data:', error) modPackData.value = [] permanentNoFiles.value = [] + cachedProjectUpdated.value = props.projectUpdated persistAll() } } @@ -457,7 +464,10 @@ function getJudgements(): ModerationJudgements { onMounted(() => { loadPersistedData() - if (!modPackData.value) { + + const isStale = cachedProjectUpdated.value !== props.projectUpdated + + if (!modPackData.value || isStale) { fetchModPackData() } }) @@ -477,6 +487,7 @@ watch( () => props.projectId, () => { clearPersistedData() + cachedProjectUpdated.value = null loadPersistedData() if (!modPackData.value) { fetchModPackData() diff --git a/apps/frontend/src/pages/servers/manage/[id]/options/index.vue b/apps/frontend/src/pages/servers/manage/[id]/options/index.vue index ec7e8047..9f228d4b 100644 --- a/apps/frontend/src/pages/servers/manage/[id]/options/index.vue +++ b/apps/frontend/src/pages/servers/manage/[id]/options/index.vue @@ -84,16 +84,19 @@ @change="uploadFile" /> - + - @@ -112,8 +115,8 @@