From e8dc3c3150ee5f8b3f9a0731c9de12c78002cfae Mon Sep 17 00:00:00 2001 From: aecsocket Date: Thu, 7 May 2026 14:07:20 +0100 Subject: [PATCH] Add update download reason to analytics (#6023) * Add download reason to analytics * mark modpack updates as actual updates in analytics * fmt --- apps/app-frontend/src/helpers/profile.ts | 2 +- apps/app-frontend/src/pages/instance/Mods.vue | 4 ++-- apps/app-frontend/src/providers/content-install.ts | 4 +++- apps/app-frontend/src/store/install.js | 4 ++-- apps/labrinth/src/models/v3/analytics.rs | 2 ++ packages/app-lib/src/api/pack/install_from.rs | 5 ++--- packages/app-lib/src/api/pack/install_mrpack.rs | 11 +++++++++-- packages/app-lib/src/api/profile/mod.rs | 2 +- packages/app-lib/src/api/profile/update.rs | 9 +++++++-- packages/app-lib/src/util/fetch.rs | 1 + 10 files changed, 30 insertions(+), 14 deletions(-) diff --git a/apps/app-frontend/src/helpers/profile.ts b/apps/app-frontend/src/helpers/profile.ts index 89c43c8e4..2f865f736 100644 --- a/apps/app-frontend/src/helpers/profile.ts +++ b/apps/app-frontend/src/helpers/profile.ts @@ -184,7 +184,7 @@ export async function update_project(path: string, projectPath: string): Promise // Add a project to a profile from a version // Returns a path to the new project file -export type DownloadReason = 'standalone' | 'dependency' | 'modpack' +export type DownloadReason = 'standalone' | 'dependency' | 'modpack' | 'update' export async function add_project_from_version( path: string, diff --git a/apps/app-frontend/src/pages/instance/Mods.vue b/apps/app-frontend/src/pages/instance/Mods.vue index 8a5a8ffe6..12469f5c2 100644 --- a/apps/app-frontend/src/pages/instance/Mods.vue +++ b/apps/app-frontend/src/pages/instance/Mods.vue @@ -311,7 +311,7 @@ async function updateProject(mod: ContentItem) { const profile = await get(props.instance.path).catch(handleError) if (profile) { - await installVersionDependencies(profile, versionData).catch(handleError) + await installVersionDependencies(profile, versionData, 'update').catch(handleError) } } } @@ -347,7 +347,7 @@ async function switchProjectVersion(mod: ContentItem, version: Labrinth.Versions const profile = await get(props.instance.path).catch(handleError) if (profile) { - await installVersionDependencies(profile, version).catch(handleError) + await installVersionDependencies(profile, version, 'update').catch(handleError) } mod.file_path = newPath diff --git a/apps/app-frontend/src/providers/content-install.ts b/apps/app-frontend/src/providers/content-install.ts index f69ddd402..a4968614a 100644 --- a/apps/app-frontend/src/providers/content-install.ts +++ b/apps/app-frontend/src/providers/content-install.ts @@ -430,6 +430,7 @@ export function createContentInstall(opts: { await installVersionDependencies( profile, version, + 'dependency', (depProject: Labrinth.Projects.v2.Project, depVersion?: Labrinth.Versions.v2.Version) => { addInstallingItem(instance.id, depProject, depVersion) installedProjectIds.push(depProject.id) @@ -488,7 +489,7 @@ export function createContentInstall(opts: { await opts.router.push(`/instance/${encodeURIComponent(id)}/`) const instance = await get(id) - await installVersionDependencies(instance, version) + await installVersionDependencies(instance, version, 'dependency') trackEvent('InstanceCreate', { source: 'ProjectInstallModal', @@ -589,6 +590,7 @@ export function createContentInstall(opts: { await installVersionDependencies( instance, version, + 'dependency', ( depProject: Labrinth.Projects.v2.Project, depVersion?: Labrinth.Versions.v2.Version, diff --git a/apps/app-frontend/src/store/install.js b/apps/app-frontend/src/store/install.js index 0ed2f8a8c..3a5e8394b 100644 --- a/apps/app-frontend/src/store/install.js +++ b/apps/app-frontend/src/store/install.js @@ -48,7 +48,7 @@ export const isVersionCompatible = (version, project, instance) => { ) } -export const installVersionDependencies = async (profile, version, onDepInstalling) => { +export const installVersionDependencies = async (profile, version, reason, onDepInstalling) => { const projectNames = new Map() const storeProjectName = (p) => { if (p?.id && p.title) projectNames.set(p.id, p.title) @@ -177,7 +177,7 @@ export const installVersionDependencies = async (profile, version, onDepInstalli const batch = queuedInstalls.slice(i, i + batchSize) await Promise.all( batch.map(async ({ versionId }) => { - await add_project_from_version(profile.path, versionId, 'dependency') + await add_project_from_version(profile.path, versionId, reason) }), ) } diff --git a/apps/labrinth/src/models/v3/analytics.rs b/apps/labrinth/src/models/v3/analytics.rs index a71ba26c0..105d74da4 100644 --- a/apps/labrinth/src/models/v3/analytics.rs +++ b/apps/labrinth/src/models/v3/analytics.rs @@ -54,6 +54,8 @@ pub enum DownloadReason { Dependency, /// Project was downloaded as part of a modpack. Modpack, + /// Project was re-downloaded due to an update. + Update, } impl std::str::FromStr for DownloadReason { diff --git a/packages/app-lib/src/api/pack/install_from.rs b/packages/app-lib/src/api/pack/install_from.rs index 324b89e9f..378e0969e 100644 --- a/packages/app-lib/src/api/pack/install_from.rs +++ b/packages/app-lib/src/api/pack/install_from.rs @@ -218,9 +218,8 @@ pub async fn generate_pack_from_version_id( icon_url: Option, profile_path: String, - // Existing loading bar. Unlike when existing_loading_bar is used, this one is pre-initialized with PackFileDownload - // For example, you might use this if multiple packs are being downloaded at once and you want to use the same loading bar initialized_loading_bar: Option, + reason: DownloadReason, ) -> crate::Result { let state = State::get().await?; let has_icon_url = icon_url.is_some(); @@ -301,7 +300,7 @@ pub async fn generate_pack_from_version_id( })?; let download_meta = DownloadMeta { - reason: DownloadReason::Modpack, + reason, game_version: profile.game_version.clone(), loader: profile.loader.as_str().to_string(), }; diff --git a/packages/app-lib/src/api/pack/install_mrpack.rs b/packages/app-lib/src/api/pack/install_mrpack.rs index a00c45af7..fd5bc21ef 100644 --- a/packages/app-lib/src/api/pack/install_mrpack.rs +++ b/packages/app-lib/src/api/pack/install_mrpack.rs @@ -48,6 +48,7 @@ pub async fn install_zipped_mrpack( icon_url, profile_path.clone(), None, + DownloadReason::Modpack, ) .await? } @@ -57,7 +58,12 @@ pub async fn install_zipped_mrpack( }; // Install pack files, and if it fails, fail safely by removing the profile - let result = install_zipped_mrpack_files(create_pack, false).await; + let result = install_zipped_mrpack_files( + create_pack, + false, + DownloadReason::Modpack, + ) + .await; match result { Ok(profile) => Ok(profile), @@ -74,6 +80,7 @@ pub async fn install_zipped_mrpack( pub async fn install_zipped_mrpack_files( create_pack: CreatePack, ignore_lock: bool, + reason: DownloadReason, ) -> crate::Result { let state = &State::get().await?; @@ -221,7 +228,7 @@ pub async fn install_zipped_mrpack_files( })?; let download_meta = DownloadMeta { - reason: DownloadReason::Modpack, + reason, game_version: profile.game_version.clone(), loader: profile.loader.as_str().to_string(), }; diff --git a/packages/app-lib/src/api/profile/mod.rs b/packages/app-lib/src/api/profile/mod.rs index d7e12139a..31b3a965d 100644 --- a/packages/app-lib/src/api/profile/mod.rs +++ b/packages/app-lib/src/api/profile/mod.rs @@ -461,7 +461,7 @@ pub async fn update_project( let mut path = Profile::add_project_version( profile_path, update_version, - fetch::DownloadReason::Standalone, + fetch::DownloadReason::Update, &state.pool, &state.fetch_semaphore, &state.io_semaphore, diff --git a/packages/app-lib/src/api/profile/update.rs b/packages/app-lib/src/api/profile/update.rs index 6ab70aadc..fcf74e7c6 100644 --- a/packages/app-lib/src/api/profile/update.rs +++ b/packages/app-lib/src/api/profile/update.rs @@ -1,4 +1,5 @@ use crate::state::CacheBehaviour; +use crate::util::fetch::DownloadReason; use crate::{ LoadingBarType, event::{ @@ -162,7 +163,8 @@ async fn replace_managed_modrinth( profile.name.clone(), None, profile_path.to_string(), - Some(shared_loading_bar.clone()) + Some(shared_loading_bar.clone()), + DownloadReason::Update, ), generate_pack_from_version_id( project_id.clone(), @@ -170,7 +172,8 @@ async fn replace_managed_modrinth( profile.name.clone(), None, profile_path.to_string(), - Some(shared_loading_bar) + Some(shared_loading_bar), + DownloadReason::Update, ) )? } else { @@ -182,6 +185,7 @@ async fn replace_managed_modrinth( None, profile_path.to_string(), None, + DownloadReason::Update, ) .await?; old_pack_creator.description.existing_loading_bar = None; @@ -205,6 +209,7 @@ async fn replace_managed_modrinth( pack::install_mrpack::install_zipped_mrpack_files( new_pack_creator, ignore_lock, + DownloadReason::Update, ) .await?; diff --git a/packages/app-lib/src/util/fetch.rs b/packages/app-lib/src/util/fetch.rs index d380bea94..1dfdb7135 100644 --- a/packages/app-lib/src/util/fetch.rs +++ b/packages/app-lib/src/util/fetch.rs @@ -27,6 +27,7 @@ pub enum DownloadReason { Standalone, Dependency, Modpack, + Update, } #[derive(Debug, Clone, Serialize)]