From 71cf2c53f5cb3798097c3ea09f60d9f734de2fc4 Mon Sep 17 00:00:00 2001 From: "Adrian O.V" <83074853+CodexAdrian@users.noreply.github.com> Date: Wed, 10 May 2023 18:50:42 -0400 Subject: [PATCH] Implement loading (#104) * Implement loading * LoadingBar * Run linter * Update App.vue * Loading bar all the things * Update SplashScreen.vue * Update SplashScreen.vue * Update App.vue * initial revert * Update Instance.vue * revert css * Fix instance * More reverting * Run lint * Finalize changes * Revert "Merge branch 'master' into loading" This reverts commit 3014e765fb6fb343f3030fd8a822edd97fb2af41, reversing changes made to b780e859d2b53a203eb3561ba3be88af083d9c15. * Fix loading issues * fix lint * Revert "Revert "Merge branch 'master' into loading"" This reverts commit 971ef8466613579b7f523edbd25b692df62d0f86. --------- Co-authored-by: Jai A --- theseus/src/api/profile_create.rs | 32 ++-- theseus/src/event/emit.rs | 63 ++++--- theseus/src/event/mod.rs | 2 + theseus/src/launcher/download.rs | 63 +++---- theseus/src/launcher/mod.rs | 93 ++++----- theseus/src/state/metadata.rs | 8 +- theseus_gui/src/App.vue | 16 +- theseus_gui/src/components/RowDisplay.vue | 4 +- .../src/components/ui/AccountsCard.vue | 2 +- theseus_gui/src/components/ui/Instance.vue | 44 +++-- theseus_gui/src/components/ui/ProgressBar.vue | 33 ++++ .../src/components/ui/RunningAppBar.vue | 176 +++++++++++++++++- .../src/components/ui/SplashScreen.vue | 40 ++++ theseus_gui/src/main.js | 4 +- theseus_gui/src/pages/Browse.vue | 33 ++-- theseus_gui/src/pages/Index.vue | 4 +- theseus_gui/src/pages/Library.vue | 14 +- theseus_gui/src/pages/Settings.vue | 2 +- theseus_gui/src/pages/instance/Index.vue | 14 +- theseus_gui/src/pages/project/Gallery.vue | 2 +- theseus_gui/src/pages/project/Index.vue | 2 +- 21 files changed, 463 insertions(+), 188 deletions(-) create mode 100644 theseus_gui/src/components/ui/ProgressBar.vue create mode 100644 theseus_gui/src/components/ui/SplashScreen.vue diff --git a/theseus/src/api/profile_create.rs b/theseus/src/api/profile_create.rs index 3d12197b8..62f6733f5 100644 --- a/theseus/src/api/profile_create.rs +++ b/theseus/src/api/profile_create.rs @@ -66,7 +66,7 @@ pub async fn profile_create( ) .into()); } - + if ReadDirStream::new(fs::read_dir(&path).await?) .next() .await @@ -77,25 +77,26 @@ pub async fn profile_create( } else { fs::create_dir_all(&path).await?; } - + info!( "Creating profile at path {}", &canonicalize(&path)?.display() ); - + let loader = modloader; let loader = if loader != ModLoader::Vanilla { let version = loader_version.unwrap_or_else(|| "latest".to_string()); - + let filter = |it: &LoaderVersion| match version.as_str() { "latest" => true, "stable" => it.stable, id => it.id == *id || format!("{}-{}", game_version, id) == it.id, }; - + let loader_data = match loader { ModLoader::Forge => &metadata.forge, ModLoader::Fabric => &metadata.fabric, + ModLoader::Quilt => &metadata.quilt, _ => { return Err(ProfileCreationError::NoManifest( loader.to_string(), @@ -103,7 +104,7 @@ pub async fn profile_create( .into()) } }; - + let loaders = &loader_data .game_versions .iter() @@ -120,7 +121,7 @@ pub async fn profile_create( ) })? .loaders; - + let loader_version = loaders .iter() .cloned() @@ -139,12 +140,12 @@ pub async fn profile_create( loader.to_string(), ) })?; - + Some((loader_version, loader)) } else { None }; - + // Fully canonicalize now that its created for storing purposes let path = canonicalize(&path)?; let mut profile = @@ -164,9 +165,9 @@ pub async fn profile_create( profile.metadata.loader = loader; profile.metadata.loader_version = Some(loader_version); } - + profile.metadata.linked_data = linked_data; - + // Attempts to find optimal JRE for the profile from the JavaGlobals // Finds optimal key, and see if key has been set in JavaGlobals let settings = state.settings.read().await; @@ -179,7 +180,7 @@ pub async fn profile_create( } else { emit_warning(&format!("Could not detect optimal JRE: {optimal_version_key}, falling back to system default.")).await?; } - + emit_profile( uuid, path.clone(), @@ -187,19 +188,18 @@ pub async fn profile_create( ProfilePayloadType::Created, ) .await?; - + { let mut profiles = state.profiles.write().await; profiles.insert(profile.clone()).await?; } - + if !skip_install_profile.unwrap_or(false) { crate::launcher::install_minecraft(&profile, None).await?; } State::sync().await?; - + Ok(path) - }).await } diff --git a/theseus/src/event/emit.rs b/theseus/src/event/emit.rs index 160190fb4..49aaea192 100644 --- a/theseus/src/event/emit.rs +++ b/theseus/src/event/emit.rs @@ -61,6 +61,7 @@ pub async fn init_loading( message: title.to_string(), total, current: 0.0, + last_sent: 0.0, bar_type, #[cfg(feature = "cli")] cli_progress_bar: { @@ -115,6 +116,7 @@ pub async fn edit_loading( bar.total = total; bar.message = title.to_string(); bar.current = 0.0; + bar.last_sent = 0.0; #[cfg(feature = "cli")] { bar.cli_progress_bar.reset(); // indicatif::ProgressBar::new(CLI_PROGRESS_BAR_TOTAL as u64); @@ -150,42 +152,47 @@ pub async fn emit_loading( // Tick up loading bar loading_bar.current += increment_frac; let display_frac = loading_bar.current / loading_bar.total; - let display_frac = if display_frac >= 1.0 { + let opt_display_frac = if display_frac >= 1.0 { None // by convention, when its done, we submit None // any further updates will be ignored (also sending None) } else { Some(display_frac) }; - // Emit event to indicatif progress bar - #[cfg(feature = "cli")] - { - loading_bar.cli_progress_bar.set_message( - message - .map(|x| x.to_string()) - .unwrap_or(loading_bar.message.clone()), - ); - loading_bar.cli_progress_bar.set_position( - ((loading_bar.current / loading_bar.total) - * CLI_PROGRESS_BAR_TOTAL as f64) - .round() as u64, - ); + if f64::abs(display_frac - loading_bar.last_sent) > 0.005 { + // Emit event to indicatif progress bar + #[cfg(feature = "cli")] + { + loading_bar.cli_progress_bar.set_message( + message + .map(|x| x.to_string()) + .unwrap_or(loading_bar.message.clone()), + ); + loading_bar.cli_progress_bar.set_position( + (display_frac * CLI_PROGRESS_BAR_TOTAL as f64).round() as u64, + ); + } + + // Emit event to tauri + #[cfg(feature = "tauri")] + event_state + .app + .emit_all( + "loading", + LoadingPayload { + fraction: opt_display_frac, + message: message + .unwrap_or(&loading_bar.message) + .to_string(), + event: loading_bar.bar_type.clone(), + loader_uuid: loading_bar.loading_bar_uuid, + }, + ) + .map_err(EventError::from)?; + + loading_bar.last_sent = display_frac; } - // Emit event to tauri - #[cfg(feature = "tauri")] - event_state - .app - .emit_all( - "loading", - LoadingPayload { - fraction: display_frac, - message: message.unwrap_or(&loading_bar.message).to_string(), - event: loading_bar.bar_type.clone(), - loader_uuid: loading_bar.loading_bar_uuid, - }, - ) - .map_err(EventError::from)?; Ok(()) } diff --git a/theseus/src/event/mod.rs b/theseus/src/event/mod.rs index 9a88666af..e05a4f6bf 100644 --- a/theseus/src/event/mod.rs +++ b/theseus/src/event/mod.rs @@ -76,6 +76,8 @@ pub struct LoadingBar { pub message: String, pub total: f64, pub current: f64, + #[serde(skip)] + pub last_sent: f64, pub bar_type: LoadingBarType, #[cfg(feature = "cli")] #[serde(skip)] diff --git a/theseus/src/launcher/download.rs b/theseus/src/launcher/download.rs index db7baddfb..174b4aff3 100644 --- a/theseus/src/launcher/download.rs +++ b/theseus/src/launcher/download.rs @@ -30,11 +30,22 @@ pub async fn download_minecraft( let assets_index = download_assets_index(st, version, Some(loading_bar)).await?; + let amount = if version + .processors + .as_ref() + .map(|x| !x.is_empty()) + .unwrap_or(false) + { + 25.0 + } else { + 40.0 + }; + tokio::try_join! { - // Total loading sums to 80 + // Total loading sums to 90/60 download_client(st, version, Some(loading_bar)), // 10 - download_assets(st, version.assets == "legacy", &assets_index, Some(loading_bar)), // 35 - download_libraries(st, version.libraries.as_slice(), &version.id, Some(loading_bar)) // 35 + download_assets(st, version.assets == "legacy", &assets_index, Some(loading_bar), amount), // 40 + download_libraries(st, version.libraries.as_slice(), &version.id, Some(loading_bar), amount) // 40 }?; tracing::info!("Done downloading Minecraft!"); @@ -83,21 +94,7 @@ pub async fn download_version_info( }?; if let Some(loading_bar) = loading_bar { - emit_loading( - loading_bar, - if res - .processors - .as_ref() - .map(|x| !x.is_empty()) - .unwrap_or(false) - { - 5.0 - } else { - 15.0 - }, - None, - ) - .await?; + emit_loading(loading_bar, 5.0, None).await?; } tracing::debug!("Loaded version info for Minecraft {version_id}"); @@ -140,7 +137,7 @@ pub async fn download_client( tracing::trace!("Fetched client version {version}"); } if let Some(loading_bar) = loading_bar { - emit_loading(loading_bar, 10.0, None).await?; + emit_loading(loading_bar, 9.0, None).await?; } tracing::debug!("Client loaded for version {version}!"); @@ -186,17 +183,18 @@ pub async fn download_assets( with_legacy: bool, index: &AssetsIndex, loading_bar: Option<&LoadingBarId>, + loading_amount: f64, ) -> crate::Result<()> { Box::pin(async move { tracing::debug!("Loading assets"); let num_futs = index.objects.len(); let assets = stream::iter(index.objects.iter()) .map(Ok::<(&String, &Asset), crate::Error>); - + loading_try_for_each_concurrent(assets, None, loading_bar, - 35.0, + loading_amount, num_futs, None, |(name, asset)| async move { @@ -206,7 +204,7 @@ pub async fn download_assets( "https://resources.download.minecraft.net/{sub_hash}/{hash}", sub_hash = &hash[..2] ); - + let fetch_cell = OnceCell::::new(); tokio::try_join! { async { @@ -233,14 +231,12 @@ pub async fn download_assets( Ok::<_, crate::Error>(()) }, }?; - + tracing::trace!("Loaded asset with hash {hash}"); Ok(()) }).await?; - tracing::debug!("Done loading assets!"); Ok(()) - }).await } @@ -250,6 +246,7 @@ pub async fn download_libraries( libraries: &[Library], version: &str, loading_bar: Option<&LoadingBarId>, + loading_amount: f64, ) -> crate::Result<()> { Box::pin(async move { tracing::debug!("Loading libraries"); @@ -261,7 +258,7 @@ pub async fn download_libraries( let num_files = libraries.len(); loading_try_for_each_concurrent( stream::iter(libraries.iter()) - .map(Ok::<&Library, crate::Error>), None, loading_bar,35.0,num_files, None,|library| async move { + .map(Ok::<&Library, crate::Error>), None, loading_bar,loading_amount,num_files, None,|library| async move { if let Some(rules) = &library.rules { if !rules.iter().all(super::parse_rule) { return Ok(()); @@ -271,7 +268,7 @@ pub async fn download_libraries( async { let artifact_path = d::get_path_from_artifact(&library.name)?; let path = st.directories.libraries_dir().join(&artifact_path); - + match library.downloads { _ if path.exists() => Ok(()), Some(d::minecraft::LibraryDownloads { @@ -292,7 +289,7 @@ pub async fn download_libraries( .unwrap_or("https://libraries.minecraft.net"), &artifact_path ].concat(); - + let bytes = fetch(&url, None, &st.fetch_semaphore).await?; write(&path, &bytes, &st.io_semaphore).await?; tracing::trace!("Fetched library {}", &library.name); @@ -318,7 +315,7 @@ pub async fn download_libraries( "${arch}", crate::util::platform::ARCH_WIDTH, ); - + if let Some(native) = classifiers.get(&parsed_key) { let data = fetch(&native.url, Some(&native.sha1), &st.fetch_semaphore).await?; let reader = std::io::Cursor::new(&data); @@ -332,18 +329,18 @@ pub async fn download_libraries( } } } - + Ok(()) } }?; - + tracing::debug!("Loaded library {}", library.name); Ok(()) } ).await?; - + tracing::debug!("Done loading libraries!"); Ok(()) - + }).await } diff --git a/theseus/src/launcher/mod.rs b/theseus/src/launcher/mod.rs index ea5780842..ecfb2bdfe 100644 --- a/theseus/src/launcher/mod.rs +++ b/theseus/src/launcher/mod.rs @@ -62,7 +62,6 @@ pub async fn install_minecraft( let state = State::get().await?; let instance_path = &canonicalize(&profile.path)?; let metadata = state.metadata.read().await; - let version = metadata .minecraft .versions @@ -72,7 +71,7 @@ pub async fn install_minecraft( "Invalid game version: {}", profile.metadata.game_version )))?; - + let version_jar = profile .metadata .loader_version @@ -80,7 +79,7 @@ pub async fn install_minecraft( .map_or(version.id.clone(), |it| { format!("{}-{}", version.id.clone(), it.id.clone()) }); - + let loading_bar = init_or_edit_loading( existing_loading_bar, LoadingBarType::MinecraftDownload { @@ -92,8 +91,8 @@ pub async fn install_minecraft( "Downloading Minecraft", ) .await?; - - // Download version info + + // Download version info (5) let mut version_info = download::download_version_info( &state, version, @@ -102,16 +101,16 @@ pub async fn install_minecraft( Some(&loading_bar), ) .await?; - + // Download minecraft (5-90) download::download_minecraft(&state, &version_info, &loading_bar).await?; - - let client_path = state - .directories - .version_dir(&version_jar) - .join(format!("{version_jar}.jar")); - + if let Some(processors) = &version_info.processors { + let client_path = state + .directories + .version_dir(&version_jar) + .join(format!("{version_jar}.jar")); + if let Some(ref mut data) = version_info.data { processor_rules! { data; @@ -131,33 +130,23 @@ pub async fn install_minecraft( client => state.directories.libraries_dir().to_string_lossy(), server => ""; } - + emit_loading(&loading_bar, 0.0, Some("Running forge processors")) .await?; let total_length = processors.len(); - + // Forge processors (90-100) for (index, processor) in processors.iter().enumerate() { - emit_loading( - &loading_bar, - 10.0 / total_length as f64, - Some(&format!( - "Running forge processor {}/{}", - index, total_length - )), - ) - .await?; - if let Some(sides) = &processor.sides { if !sides.contains(&String::from("client")) { continue; } } - + let cp = wrap_ref_builder!(cp = processor.classpath.clone() => { cp.push(processor.jar.clone()) }); - + let child = Command::new("java") .arg("-cp") .arg(args::get_class_paths_jar( @@ -190,7 +179,7 @@ pub async fn install_minecraft( "Error running processor: {err}", )) })?; - + if !child.status.success() { return Err(crate::ErrorKind::LauncherError(format!( "Processor error: {}", @@ -198,20 +187,35 @@ pub async fn install_minecraft( )) .as_error()); } + + emit_loading( + &loading_bar, + 30.0 / total_length as f64, + Some(&format!( + "Running forge processor {}/{}", + index, total_length + )), + ) + .await?; } } } - + crate::api::profile::edit(&profile.path, |prof| { prof.installed = true; - + async { Ok(()) } }) .await?; State::sync().await?; - + emit_loading( + &loading_bar, + 1.0, + Some("Finished installing"), + ) + .await?; + Ok(()) - }).await } @@ -231,11 +235,11 @@ pub async fn launch_minecraft( if !profile.installed { install_minecraft(profile, None).await?; } - + let state = State::get().await?; let metadata = state.metadata.read().await; let instance_path = &canonicalize(&profile.path)?; - + let version = metadata .minecraft .versions @@ -245,7 +249,7 @@ pub async fn launch_minecraft( "Invalid game version: {}", profile.metadata.game_version )))?; - + let version_jar = profile .metadata .loader_version @@ -253,7 +257,7 @@ pub async fn launch_minecraft( .map_or(version.id.clone(), |it| { format!("{}-{}", version.id.clone(), it.id.clone()) }); - + let version_info = download::download_version_info( &state, version, @@ -262,12 +266,12 @@ pub async fn launch_minecraft( None, ) .await?; - + let client_path = state .directories .version_dir(&version_jar) .join(format!("{version_jar}.jar")); - + let args = version_info.arguments.clone().unwrap_or_default(); let mut command = match wrapper { Some(hook) => { @@ -275,9 +279,9 @@ pub async fn launch_minecraft( } None => Command::new(String::from(java_install.to_string_lossy())), }; - + let env_args = Vec::from(env_args); - + // Check if profile has a running profile, and reject running the command if it does // Done late so a quick double call doesn't launch two instances let existing_processes = @@ -289,7 +293,7 @@ pub async fn launch_minecraft( )) .as_error()); } - + command .args( args::get_jvm_arguments( @@ -329,14 +333,14 @@ pub async fn launch_minecraft( .current_dir(instance_path.clone()) .stdout(Stdio::piped()) .stderr(Stdio::piped()); - + // CARGO-set DYLD_LIBRARY_PATH breaks Minecraft on macOS during testing on playground #[cfg(target_os = "macos")] if std::env::var("CARGO").is_ok() { command.env_remove("DYLD_FALLBACK_LIBRARY_PATH"); } command.envs(env_args); - + // Get Modrinth logs directories let datetime_string = chrono::Local::now().format("%Y%m%y_%H%M%S").to_string(); @@ -347,10 +351,10 @@ pub async fn launch_minecraft( .join(&datetime_string) }; fs::create_dir_all(&logs_dir)?; - + let stdout_log_path = logs_dir.join("stdout.log"); let stderr_log_path = logs_dir.join("stderr.log"); - + // Create Minecraft child by inserting it into the state // This also spawns the process and prepares the subsequent processes let mut state_children = state.children.write().await; @@ -364,6 +368,5 @@ pub async fn launch_minecraft( post_exit_hook, ) .await - }).await } diff --git a/theseus/src/state/metadata.rs b/theseus/src/state/metadata.rs index f79b8d717..8dc8bac37 100644 --- a/theseus/src/state/metadata.rs +++ b/theseus/src/state/metadata.rs @@ -17,6 +17,7 @@ pub struct Metadata { pub minecraft: MinecraftManifest, pub forge: LoaderManifest, pub fabric: LoaderManifest, + pub quilt: LoaderManifest, } impl Metadata { @@ -25,7 +26,7 @@ impl Metadata { } pub async fn fetch() -> crate::Result { - let (minecraft, forge, fabric) = tokio::try_join! { + let (minecraft, forge, fabric, quilt) = tokio::try_join! { async { let url = Self::get_manifest("minecraft"); fetch_version_manifest(Some(&url)).await @@ -37,6 +38,10 @@ impl Metadata { async { let url = Self::get_manifest("fabric"); fetch_loader_manifest(&url).await + }, + async { + let url = Self::get_manifest("quilt"); + fetch_loader_manifest(&url).await } }?; @@ -44,6 +49,7 @@ impl Metadata { minecraft, forge, fabric, + quilt, }) } diff --git a/theseus_gui/src/App.vue b/theseus_gui/src/App.vue index 315452d98..a8880b6a7 100644 --- a/theseus_gui/src/App.vue +++ b/theseus_gui/src/App.vue @@ -1,5 +1,5 @@ diff --git a/theseus_gui/src/components/ui/SplashScreen.vue b/theseus_gui/src/components/ui/SplashScreen.vue new file mode 100644 index 000000000..0c612f0fe --- /dev/null +++ b/theseus_gui/src/components/ui/SplashScreen.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/theseus_gui/src/main.js b/theseus_gui/src/main.js index e79e06b15..75c8357db 100644 --- a/theseus_gui/src/main.js +++ b/theseus_gui/src/main.js @@ -16,8 +16,10 @@ app.use(pinia) app.use(FloatingVue) app.mixin(loadCssMixin) +const mountedApp = app.mount('#app') + initialize_state() - .then(() => app.mount('#app')) + .then(() => mountedApp.initialize()) .catch((err) => { console.error(err) }) diff --git a/theseus_gui/src/pages/Browse.vue b/theseus_gui/src/pages/Browse.vue index fc42b1da7..da378b43f 100644 --- a/theseus_gui/src/pages/Browse.vue +++ b/theseus_gui/src/pages/Browse.vue @@ -13,7 +13,6 @@ import { Card, ClientIcon, ServerIcon, - AnimatedLogo, NavRow, formatCategoryHeader, } from 'omorphia' @@ -23,6 +22,7 @@ import { useBreadcrumbs } from '@/store/breadcrumbs' import { get_categories, get_loaders, get_game_versions } from '@/helpers/tags' import { useRoute } from 'vue-router' import Instance from '@/components/ui/Instance.vue' +import SplashScreen from '@/components/ui/SplashScreen.vue' const route = useRoute() @@ -36,25 +36,28 @@ const breadcrumbs = useBreadcrumbs() const showSnapshots = ref(false) const loading = ref(true) -const [categories, loaders, availableGameVersions] = await Promise.all([ - get_categories(), - get_loaders(), - get_game_versions(), -]) +const categories = ref([]) +const loaders = ref([]) +const availableGameVersions = ref([]) -onMounted(() => { +onMounted(async () => { + ;[categories.value, loaders.value, availableGameVersions.value] = await Promise.all([ + get_categories(), + get_loaders(), + get_game_versions(), + ]) breadcrumbs.setContext({ name: 'Browse', link: route.path }) if (searchStore.projectType === 'modpack') { searchStore.instanceContext = null } searchStore.searchInput = '' - handleReset() - switchPage(1) + await handleReset() + loading.value = false }) const sortedCategories = computed(() => { const values = new Map() - for (const category of categories.filter( + for (const category of categories.value.filter( (cat) => cat.project_type === (searchStore.projectType === 'datapack' ? 'mod' : searchStore.projectType) @@ -67,7 +70,7 @@ const sortedCategories = computed(() => { return values }) -const getSearchResults = async (shouldLoad = false) => { +const getSearchResults = async () => { const queryString = searchStore.getQueryString() if (searchStore.instanceContext) { showVersions.value = false @@ -75,16 +78,10 @@ const getSearchResults = async (shouldLoad = false) => { searchStore.projectType === 'mod' || searchStore.projectType === 'resourcepack' ) } - if (shouldLoad === true) { - loading.value = true - } const response = await ofetch(`https://api.modrinth.com/v2/search${queryString}`) - loading.value = false searchStore.setSearchResults(response) } -getSearchResults(true) - const handleReset = async () => { searchStore.currentPage = 1 searchStore.offset = 0 @@ -309,7 +306,7 @@ watch( :count="searchStore.pageCount" @switch-page="switchPage" /> - +
-import { ref, shallowRef, onUnmounted } from 'vue' +import { ref, onUnmounted, shallowRef } from 'vue' import { ofetch } from 'ofetch' import { useRoute } from 'vue-router' import RowDisplay from '@/components/RowDisplay.vue' @@ -16,7 +16,7 @@ const breadcrumbs = useBreadcrumbs() breadcrumbs.setRootContext({ name: 'Home', link: route.path }) -const recentInstances = shallowRef() +const recentInstances = shallowRef(Object.values(await list())) const getInstances = async () => { filter.value = '' diff --git a/theseus_gui/src/pages/Library.vue b/theseus_gui/src/pages/Library.vue index c01a0713d..64bbfdf82 100644 --- a/theseus_gui/src/pages/Library.vue +++ b/theseus_gui/src/pages/Library.vue @@ -4,6 +4,7 @@ import GridDisplay from '@/components/GridDisplay.vue' import { list } from '@/helpers/profile.js' import { useRoute } from 'vue-router' import { useBreadcrumbs } from '@/store/breadcrumbs' +import { loading_listener } from '@/helpers/events.js' const route = useRoute() const breadcrumbs = useBreadcrumbs() @@ -17,12 +18,21 @@ const instances = shallowRef( const modpacks = shallowRef( Object.values(profiles).filter((prof) => prof.metadata.linked_project_id) ) + +loading_listener(async (profile) => { + console.log(profile) + if (profile.event === 'loaded') { + const profiles = await list() + instances.value = Object.values(profiles).filter((prof) => !prof.metadata.linked_project_id) + modpacks.value = Object.values(profiles).filter((prof) => prof.metadata.linked_project_id) + } +}) diff --git a/theseus_gui/src/pages/Settings.vue b/theseus_gui/src/pages/Settings.vue index 75f15a9e3..788b1fae8 100644 --- a/theseus_gui/src/pages/Settings.vue +++ b/theseus_gui/src/pages/Settings.vue @@ -28,8 +28,8 @@ if (!fetchSettings.java_globals?.JAVA_8) fetchSettings.java_globals.JAVA_8 = { path: '', version: '' } if (!fetchSettings.java_globals?.JAVA_17) fetchSettings.java_globals.JAVA_17 = { path: '', version: '' } - const settings = ref(fetchSettings) + const chosenInstallOptions = ref([]) const browsingInstall = ref(0) diff --git a/theseus_gui/src/pages/instance/Index.vue b/theseus_gui/src/pages/instance/Index.vue index e41d83595..225b383ae 100644 --- a/theseus_gui/src/pages/instance/Index.vue +++ b/theseus_gui/src/pages/instance/Index.vue @@ -68,9 +68,9 @@ import { get_uuids_by_profile_path, kill_by_uuid, } from '@/helpers/process' -import { process_listener } from '@/helpers/events' +import { process_listener, profile_listener } from '@/helpers/events' import { useRoute } from 'vue-router' -import { shallowRef, ref, onUnmounted } from 'vue' +import { ref, onUnmounted } from 'vue' import { convertFileSrc } from '@tauri-apps/api/tauri' import { open } from '@tauri-apps/api/dialog' import { useBreadcrumbs, useSearch } from '@/store/state' @@ -79,15 +79,21 @@ const route = useRoute() const searchStore = useSearch() const breadcrumbs = useBreadcrumbs() -const instance = shallowRef(await get(route.params.id)) -searchStore.instanceContext = instance.value +const instance = ref(await get(route.params.id)) +searchStore.instanceContext = instance.value breadcrumbs.setName('Instance', instance.value.metadata.name) breadcrumbs.setContext({ name: instance.value.metadata.name, link: route.path, }) +profile_listener(async (event) => { + if (event.profile_path === route.params.id) { + instance.value = await get(route.params.id) + } +}) + const uuid = ref(null) const playing = ref(false) const loading = ref(false) diff --git a/theseus_gui/src/pages/project/Gallery.vue b/theseus_gui/src/pages/project/Gallery.vue index 2ed4f4436..6705822d5 100644 --- a/theseus_gui/src/pages/project/Gallery.vue +++ b/theseus_gui/src/pages/project/Gallery.vue @@ -164,7 +164,7 @@ const expandImage = (item, index) => { .expanded-image-modal { position: fixed; - z-index: 20; + z-index: 10; overflow: auto; top: 0; left: 0; diff --git a/theseus_gui/src/pages/project/Index.vue b/theseus_gui/src/pages/project/Index.vue index 65bcdb2bb..07a1e0d56 100644 --- a/theseus_gui/src/pages/project/Index.vue +++ b/theseus_gui/src/pages/project/Index.vue @@ -291,7 +291,7 @@ async function install(version) { .map((value) => value.metadata) .find((pack) => pack.linked_data?.project_id === data.value.id) ) { - let id = await packInstall(queuedVersionData.id) + let id = await packInstall(queuedVersionData.id, data.value.title) await router.push({ path: `/instance/${encodeURIComponent(id)}` }) } else { confirmModal.value.show(queuedVersionData.id)