You've already forked AstralRinth
forked from didirus/AstralRinth
Performance improvements (#114)
* Performance improvements * run fmt * optimize creation modal * remove print, fix mod loader editing * Fix library update * update extract loading bar * Update theseus_gui/src-tauri/src/api/metadata.rs Co-authored-by: triphora <emma@modrinth.com> * fix cli --------- Co-authored-by: triphora <emma@modrinth.com>
This commit is contained in:
@@ -25,3 +25,11 @@ pub async fn get_forge_versions() -> crate::Result<Manifest> {
|
|||||||
|
|
||||||
Ok(tags)
|
Ok(tags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument]
|
||||||
|
pub async fn get_quilt_versions() -> crate::Result<Manifest> {
|
||||||
|
let state = State::get().await?;
|
||||||
|
let tags = state.metadata.read().await.quilt.clone();
|
||||||
|
|
||||||
|
Ok(tags)
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ pub mod tags;
|
|||||||
pub mod data {
|
pub mod data {
|
||||||
pub use crate::state::{
|
pub use crate::state::{
|
||||||
DirectoryInfo, Hooks, JavaSettings, MemorySettings, ModLoader,
|
DirectoryInfo, Hooks, JavaSettings, MemorySettings, ModLoader,
|
||||||
ProfileMetadata, Settings, Theme, WindowSize,
|
ModrinthProject, ModrinthTeamMember, ModrinthUser, ModrinthVersion,
|
||||||
|
ProfileMetadata, ProjectMetadata, Settings, Theme, WindowSize,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ use crate::event::emit::{
|
|||||||
};
|
};
|
||||||
use crate::event::{LoadingBarId, LoadingBarType};
|
use crate::event::{LoadingBarId, LoadingBarType};
|
||||||
use crate::state::{
|
use crate::state::{
|
||||||
LinkedData, ModrinthProject, ModrinthVersion, ProfileInstallStage, SideType,
|
LinkedData, ModrinthProject, ModrinthVersion, Profile, ProfileInstallStage,
|
||||||
|
SideType,
|
||||||
};
|
};
|
||||||
use crate::util::fetch::{
|
use crate::util::fetch::{
|
||||||
fetch, fetch_advanced, fetch_json, fetch_mirrors, write, write_cached_icon,
|
fetch, fetch_advanced, fetch_json, fetch_mirrors, write, write_cached_icon,
|
||||||
@@ -325,6 +326,7 @@ async fn install_pack(
|
|||||||
prof.metadata.icon = icon.clone();
|
prof.metadata.icon = icon.clone();
|
||||||
prof.metadata.game_version = game_version.clone();
|
prof.metadata.game_version = game_version.clone();
|
||||||
prof.metadata.loader_version = loader_version.clone();
|
prof.metadata.loader_version = loader_version.clone();
|
||||||
|
prof.metadata.loader = mod_loader.unwrap_or(ModLoader::Vanilla);
|
||||||
|
|
||||||
async { Ok(()) }
|
async { Ok(()) }
|
||||||
})
|
})
|
||||||
@@ -409,83 +411,79 @@ async fn install_pack(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let extract_overrides = |overrides: String| async {
|
|
||||||
let reader = Cursor::new(&file);
|
|
||||||
|
|
||||||
let mut overrides_zip =
|
|
||||||
ZipFileReader::new(reader).await.map_err(|_| {
|
|
||||||
crate::Error::from(crate::ErrorKind::InputError(
|
|
||||||
"Failed extract overrides Zip".to_string(),
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let profile = profile.clone();
|
|
||||||
async move {
|
|
||||||
for index in 0..overrides_zip.file().entries().len() {
|
|
||||||
let file = overrides_zip
|
|
||||||
.file()
|
|
||||||
.entries()
|
|
||||||
.get(index)
|
|
||||||
.unwrap()
|
|
||||||
.entry()
|
|
||||||
.clone();
|
|
||||||
|
|
||||||
let file_path = PathBuf::from(file.filename());
|
|
||||||
if file.filename().starts_with(&overrides)
|
|
||||||
&& !file.filename().ends_with('/')
|
|
||||||
{
|
|
||||||
// Reads the file into the 'content' variable
|
|
||||||
let mut content = Vec::new();
|
|
||||||
let mut reader =
|
|
||||||
overrides_zip.entry(index).await?;
|
|
||||||
reader
|
|
||||||
.read_to_end_checked(&mut content, &file)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let mut new_path = PathBuf::new();
|
|
||||||
let components = file_path.components().skip(1);
|
|
||||||
|
|
||||||
for component in components {
|
|
||||||
new_path.push(component);
|
|
||||||
}
|
|
||||||
|
|
||||||
if new_path.file_name().is_some() {
|
|
||||||
write(
|
|
||||||
&profile.join(new_path),
|
|
||||||
&content,
|
|
||||||
&state.io_semaphore,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok::<(), crate::Error>(())
|
|
||||||
}
|
|
||||||
.await
|
|
||||||
};
|
|
||||||
|
|
||||||
emit_loading(&loading_bar, 0.0, Some("Extracting overrides"))
|
emit_loading(&loading_bar, 0.0, Some("Extracting overrides"))
|
||||||
.await?;
|
.await?;
|
||||||
extract_overrides("overrides".to_string()).await?;
|
|
||||||
extract_overrides("client_overrides".to_string()).await?;
|
|
||||||
emit_loading(
|
|
||||||
&loading_bar,
|
|
||||||
29.9,
|
|
||||||
Some("Done extracting overrides"),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if let Some(profile) =
|
let mut total_len = 0;
|
||||||
crate::api::profile::get(&profile).await?
|
|
||||||
|
for index in 0..zip_reader.file().entries().len() {
|
||||||
|
let file =
|
||||||
|
zip_reader.file().entries().get(index).unwrap().entry();
|
||||||
|
|
||||||
|
if (file.filename().starts_with("overrides")
|
||||||
|
|| file.filename().starts_with("client_overrides"))
|
||||||
|
&& !file.filename().ends_with('/')
|
||||||
|
{
|
||||||
|
total_len += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for index in 0..zip_reader.file().entries().len() {
|
||||||
|
let file = zip_reader
|
||||||
|
.file()
|
||||||
|
.entries()
|
||||||
|
.get(index)
|
||||||
|
.unwrap()
|
||||||
|
.entry()
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
let file_path = PathBuf::from(file.filename());
|
||||||
|
if (file.filename().starts_with("overrides")
|
||||||
|
|| file.filename().starts_with("client_overrides"))
|
||||||
|
&& !file.filename().ends_with('/')
|
||||||
|
{
|
||||||
|
// Reads the file into the 'content' variable
|
||||||
|
let mut content = Vec::new();
|
||||||
|
let mut reader = zip_reader.entry(index).await?;
|
||||||
|
reader.read_to_end_checked(&mut content, &file).await?;
|
||||||
|
|
||||||
|
let mut new_path = PathBuf::new();
|
||||||
|
let components = file_path.components().skip(1);
|
||||||
|
|
||||||
|
for component in components {
|
||||||
|
new_path.push(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
if new_path.file_name().is_some() {
|
||||||
|
write(
|
||||||
|
&profile.join(new_path),
|
||||||
|
&content,
|
||||||
|
&state.io_semaphore,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit_loading(
|
||||||
|
&loading_bar,
|
||||||
|
30.0 / total_len as f64,
|
||||||
|
Some(&format!(
|
||||||
|
"Extracting override {}/{}",
|
||||||
|
index, total_len
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(profile_val) =
|
||||||
|
crate::api::profile::get(&profile, None).await?
|
||||||
{
|
{
|
||||||
tokio::try_join!(
|
Profile::sync_projects_task(profile.clone());
|
||||||
super::profile::sync(&profile.path),
|
crate::launcher::install_minecraft(
|
||||||
crate::launcher::install_minecraft(
|
&profile_val,
|
||||||
&profile,
|
Some(loading_bar),
|
||||||
Some(loading_bar)
|
)
|
||||||
),
|
.await?;
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok::<PathBuf, crate::Error>(profile.clone())
|
Ok::<PathBuf, crate::Error>(profile.clone())
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ pub use crate::{
|
|||||||
state::{JavaSettings, Profile},
|
state::{JavaSettings, Profile},
|
||||||
State,
|
State,
|
||||||
};
|
};
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
future::Future,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
@@ -40,11 +41,21 @@ pub async fn remove(path: &Path) -> crate::Result<()> {
|
|||||||
|
|
||||||
/// Get a profile by path,
|
/// Get a profile by path,
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub async fn get(path: &Path) -> crate::Result<Option<Profile>> {
|
pub async fn get(
|
||||||
|
path: &Path,
|
||||||
|
clear_projects: Option<bool>,
|
||||||
|
) -> crate::Result<Option<Profile>> {
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
let profiles = state.profiles.read().await;
|
let profiles = state.profiles.read().await;
|
||||||
|
let mut profile = profiles.0.get(path).cloned();
|
||||||
|
|
||||||
Ok(profiles.0.get(path).cloned())
|
if clear_projects.unwrap_or(false) {
|
||||||
|
if let Some(profile) = &mut profile {
|
||||||
|
profile.projects = HashMap::new();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Edit a profile using a given asynchronous closure
|
/// Edit a profile using a given asynchronous closure
|
||||||
@@ -79,11 +90,23 @@ where
|
|||||||
|
|
||||||
/// Get a copy of the profile set
|
/// Get a copy of the profile set
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub async fn list() -> crate::Result<std::collections::HashMap<PathBuf, Profile>>
|
pub async fn list(
|
||||||
{
|
clear_projects: Option<bool>,
|
||||||
|
) -> crate::Result<HashMap<PathBuf, Profile>> {
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
let profiles = state.profiles.read().await;
|
let profiles = state.profiles.read().await;
|
||||||
Ok(profiles.0.clone())
|
Ok(profiles
|
||||||
|
.0
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.map(|mut x| {
|
||||||
|
if clear_projects.unwrap_or(false) {
|
||||||
|
x.1.projects = HashMap::new();
|
||||||
|
}
|
||||||
|
|
||||||
|
x
|
||||||
|
})
|
||||||
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Query + sync profile's projects with the UI from the FS
|
/// Query + sync profile's projects with the UI from the FS
|
||||||
@@ -117,7 +140,7 @@ pub async fn sync(path: &Path) -> crate::Result<()> {
|
|||||||
/// Installs/Repairs a profile
|
/// Installs/Repairs a profile
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
pub async fn install(path: &Path) -> crate::Result<()> {
|
pub async fn install(path: &Path) -> crate::Result<()> {
|
||||||
let profile = get(path).await?;
|
let profile = get(path, None).await?;
|
||||||
|
|
||||||
if let Some(profile) = profile {
|
if let Some(profile) = profile {
|
||||||
crate::launcher::install_minecraft(&profile, None).await?;
|
crate::launcher::install_minecraft(&profile, None).await?;
|
||||||
@@ -398,7 +421,7 @@ pub async fn run_credentials(
|
|||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
let settings = state.settings.read().await;
|
let settings = state.settings.read().await;
|
||||||
let metadata = state.metadata.read().await;
|
let metadata = state.metadata.read().await;
|
||||||
let profile = get(path).await?.ok_or_else(|| {
|
let profile = get(path, None).await?.ok_or_else(|| {
|
||||||
crate::ErrorKind::OtherError(format!(
|
crate::ErrorKind::OtherError(format!(
|
||||||
"Tried to run a nonexistent or unloaded profile at path {}!",
|
"Tried to run a nonexistent or unloaded profile at path {}!",
|
||||||
path.display()
|
path.display()
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ impl Drop for LoadingBar {
|
|||||||
let loader_uuid = self.loading_bar_uuid;
|
let loader_uuid = self.loading_bar_uuid;
|
||||||
let event = self.bar_type.clone();
|
let event = self.bar_type.clone();
|
||||||
let fraction = self.current / self.total;
|
let fraction = self.current / self.total;
|
||||||
|
|
||||||
|
#[cfg(feature = "cli")]
|
||||||
let cli_progress_bar = self.cli_progress_bar.clone();
|
let cli_progress_bar = self.cli_progress_bar.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
|||||||
@@ -60,6 +60,18 @@ pub async fn install_minecraft(
|
|||||||
existing_loading_bar: Option<LoadingBarId>,
|
existing_loading_bar: Option<LoadingBarId>,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
|
let loading_bar = init_or_edit_loading(
|
||||||
|
existing_loading_bar,
|
||||||
|
LoadingBarType::MinecraftDownload {
|
||||||
|
// If we are downloading minecraft for a profile, provide its name and uuid
|
||||||
|
profile_name: profile.metadata.name.clone(),
|
||||||
|
profile_path: profile.path.clone(),
|
||||||
|
},
|
||||||
|
100.0,
|
||||||
|
"Downloading Minecraft",
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
crate::api::profile::edit(&profile.path, |prof| {
|
crate::api::profile::edit(&profile.path, |prof| {
|
||||||
prof.install_stage = ProfileInstallStage::Installing;
|
prof.install_stage = ProfileInstallStage::Installing;
|
||||||
|
|
||||||
@@ -90,18 +102,6 @@ pub async fn install_minecraft(
|
|||||||
format!("{}-{}", version.id.clone(), it.id.clone())
|
format!("{}-{}", version.id.clone(), it.id.clone())
|
||||||
});
|
});
|
||||||
|
|
||||||
let loading_bar = init_or_edit_loading(
|
|
||||||
existing_loading_bar,
|
|
||||||
LoadingBarType::MinecraftDownload {
|
|
||||||
// If we are downloading minecraft for a profile, provide its name and uuid
|
|
||||||
profile_name: profile.metadata.name.clone(),
|
|
||||||
profile_path: profile.path.clone(),
|
|
||||||
},
|
|
||||||
100.0,
|
|
||||||
"Downloading Minecraft",
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Download version info (5)
|
// Download version info (5)
|
||||||
let mut version_info = download::download_version_info(
|
let mut version_info = download::download_version_info(
|
||||||
&state,
|
&state,
|
||||||
|
|||||||
@@ -253,9 +253,11 @@ impl Children {
|
|||||||
let child = child.clone();
|
let child = child.clone();
|
||||||
let child = child.write().await;
|
let child = child.write().await;
|
||||||
if child.current_child.write().await.try_wait()?.is_none() {
|
if child.current_child.write().await.try_wait()?.is_none() {
|
||||||
if let Some(prof) =
|
if let Some(prof) = crate::api::profile::get(
|
||||||
crate::api::profile::get(&child.profile_path.clone())
|
&child.profile_path.clone(),
|
||||||
.await?
|
None,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
{
|
{
|
||||||
profiles.push(prof);
|
profiles.push(prof);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ impl Profile {
|
|||||||
tokio::task::spawn(async move {
|
tokio::task::spawn(async move {
|
||||||
let res = async {
|
let res = async {
|
||||||
let state = State::get().await?;
|
let state = State::get().await?;
|
||||||
let profile = crate::api::profile::get(&path).await?;
|
let profile = crate::api::profile::get(&path, None).await?;
|
||||||
|
|
||||||
if let Some(profile) = profile {
|
if let Some(profile) = profile {
|
||||||
let paths = profile.get_profile_project_paths()?;
|
let paths = profile.get_profile_project_paths()?;
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ impl ProfileList {
|
|||||||
_args: &crate::Args,
|
_args: &crate::Args,
|
||||||
_largs: &ProfileCommand,
|
_largs: &ProfileCommand,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let profiles = profile::list().await?;
|
let profiles = profile::list(None).await?;
|
||||||
let rows = profiles.values().map(ProfileRow::from);
|
let rows = profiles.values().map(ProfileRow::from);
|
||||||
|
|
||||||
let table = table(rows).with(
|
let table = table(rows).with(
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ tauri-build = { version = "1.2", features = [] }
|
|||||||
regex = "1.5"
|
regex = "1.5"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
theseus = { path = "../../theseus", features = ["tauri", "cli"] }
|
theseus = { path = "../../theseus", features = ["tauri"] }
|
||||||
|
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ pub async fn jre_get_optimal_jre_key(profile: Profile) -> Result<String> {
|
|||||||
// The key can be used in the hashmap contained by JavaGlobals in Settings (if it exists)
|
// The key can be used in the hashmap contained by JavaGlobals in Settings (if it exists)
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn jre_get_optimal_jre_key_by_path(path: &Path) -> Result<String> {
|
pub async fn jre_get_optimal_jre_key_by_path(path: &Path) -> Result<String> {
|
||||||
let profile = profile::get(path).await?.ok_or_else(|| {
|
let profile = profile::get(path, Some(true)).await?.ok_or_else(|| {
|
||||||
TheseusSerializableError::NoProfileFound(path.display().to_string())
|
TheseusSerializableError::NoProfileFound(path.display().to_string())
|
||||||
})?;
|
})?;
|
||||||
Ok(jre::get_optimal_jre_key(&profile).await?)
|
Ok(jre::get_optimal_jre_key(&profile).await?)
|
||||||
|
|||||||
@@ -19,3 +19,9 @@ pub async fn metadata_get_fabric_versions() -> Result<Manifest> {
|
|||||||
pub async fn metadata_get_forge_versions() -> Result<Manifest> {
|
pub async fn metadata_get_forge_versions() -> Result<Manifest> {
|
||||||
Ok(theseus::metadata::get_forge_versions().await?)
|
Ok(theseus::metadata::get_forge_versions().await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the quilt versions from daedalus
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn metadata_get_quilt_versions() -> Result<Manifest> {
|
||||||
|
Ok(theseus::metadata::get_quilt_versions().await?)
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,8 +16,11 @@ pub async fn profile_remove(path: &Path) -> Result<()> {
|
|||||||
// Get a profile by path
|
// Get a profile by path
|
||||||
// invoke('profile_add_path',path)
|
// invoke('profile_add_path',path)
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn profile_get(path: &Path) -> Result<Option<Profile>> {
|
pub async fn profile_get(
|
||||||
let res = profile::get(path).await?;
|
path: &Path,
|
||||||
|
clear_projects: Option<bool>,
|
||||||
|
) -> Result<Option<Profile>> {
|
||||||
|
let res = profile::get(path, clear_projects).await?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,11 +28,32 @@ pub async fn profile_get(path: &Path) -> Result<Option<Profile>> {
|
|||||||
// invoke('profile_list')
|
// invoke('profile_list')
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn profile_list(
|
pub async fn profile_list(
|
||||||
|
clear_projects: Option<bool>,
|
||||||
) -> Result<std::collections::HashMap<PathBuf, Profile>> {
|
) -> Result<std::collections::HashMap<PathBuf, Profile>> {
|
||||||
let res = profile::list().await?;
|
let res = profile::list(clear_projects).await?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn profile_check_installed(
|
||||||
|
path: &Path,
|
||||||
|
project_id: String,
|
||||||
|
) -> Result<bool> {
|
||||||
|
let profile = profile_get(path, None).await?;
|
||||||
|
if let Some(profile) = profile {
|
||||||
|
Ok(profile.projects.into_iter().any(|(_, project)| {
|
||||||
|
if let ProjectMetadata::Modrinth { project, .. } = &project.metadata
|
||||||
|
{
|
||||||
|
project.id == project_id
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Syncs a profile's in memory state with the state on the disk
|
/// Syncs a profile's in memory state with the state on the disk
|
||||||
/// // invoke('profile_sync')
|
/// // invoke('profile_sync')
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ fn main() {
|
|||||||
api::profile::profile_run_credentials,
|
api::profile::profile_run_credentials,
|
||||||
api::profile::profile_run_wait_credentials,
|
api::profile::profile_run_wait_credentials,
|
||||||
api::profile::profile_edit,
|
api::profile::profile_edit,
|
||||||
|
api::profile::profile_check_installed,
|
||||||
api::pack::pack_install_version_id,
|
api::pack::pack_install_version_id,
|
||||||
api::pack::pack_install_file,
|
api::pack::pack_install_file,
|
||||||
api::auth::auth_authenticate_begin_flow,
|
api::auth::auth_authenticate_begin_flow,
|
||||||
@@ -133,6 +134,7 @@ fn main() {
|
|||||||
api::metadata::metadata_get_game_versions,
|
api::metadata::metadata_get_game_versions,
|
||||||
api::metadata::metadata_get_fabric_versions,
|
api::metadata::metadata_get_fabric_versions,
|
||||||
api::metadata::metadata_get_forge_versions,
|
api::metadata::metadata_get_forge_versions,
|
||||||
|
api::metadata::metadata_get_quilt_versions,
|
||||||
api::logs::logs_get_logs,
|
api::logs::logs_get_logs,
|
||||||
api::logs::logs_get_logs_by_datetime,
|
api::logs::logs_get_logs_by_datetime,
|
||||||
api::logs::logs_get_stdout_by_datetime,
|
api::logs::logs_get_stdout_by_datetime,
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ const modsRow = ref(null)
|
|||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
margin-top: 0.8rem;
|
margin-top: 0.8rem;
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
overflow-y: scroll;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export default defineComponent({
|
|||||||
background: props.color || undefined,
|
background: props.color || undefined,
|
||||||
backgroundSize: `${(100 / indicator.progress.value) * 100}% auto`,
|
backgroundSize: `${(100 / indicator.progress.value) * 100}% auto`,
|
||||||
transition: 'width 0.1s, height 0.4s, opacity 0.4s',
|
transition: 'width 0.1s, height 0.4s, opacity 0.4s',
|
||||||
zIndex: 99,
|
zIndex: 6,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
slots
|
slots
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ const install = async (e) => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (props.instance.project_type === 'modpack') {
|
if (props.instance.project_type === 'modpack') {
|
||||||
const packs = Object.values(await list())
|
const packs = Object.values(await list(true))
|
||||||
|
|
||||||
if (
|
if (
|
||||||
packs.length === 0 ||
|
packs.length === 0 ||
|
||||||
@@ -125,9 +125,14 @@ await process_listener((e) => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="instance">
|
<div class="instance">
|
||||||
<Card v-if="props.small" class="instance-small-card button-base">
|
<Card v-if="props.small" class="instance-small-card button-base" @click="seeInstance">
|
||||||
<Avatar
|
<Avatar
|
||||||
:src="convertFileSrc(props.instance.metadata.icon)"
|
:src="
|
||||||
|
!props.instance.metadata.icon ||
|
||||||
|
(props.instance.metadata.icon && props.instance.metadata.icon.startsWith('http'))
|
||||||
|
? props.instance.metadata.icon
|
||||||
|
: convertFileSrc(instance.metadata?.icon)
|
||||||
|
"
|
||||||
:alt="props.instance.metadata.name"
|
:alt="props.instance.metadata.name"
|
||||||
size="sm"
|
size="sm"
|
||||||
/>
|
/>
|
||||||
@@ -150,9 +155,10 @@ await process_listener((e) => {
|
|||||||
size="none"
|
size="none"
|
||||||
:src="
|
:src="
|
||||||
props.instance.metadata
|
props.instance.metadata
|
||||||
? props.instance.metadata.icon && props.instance.metadata.icon.startsWith('http')
|
? !props.instance.metadata.icon ||
|
||||||
|
(props.instance.metadata.icon && props.instance.metadata.icon.startsWith('http'))
|
||||||
? props.instance.metadata.icon
|
? props.instance.metadata.icon
|
||||||
: convertFileSrc(props.instance.metadata?.icon)
|
: convertFileSrc(instance.metadata?.icon)
|
||||||
: props.instance.icon_url
|
: props.instance.icon_url
|
||||||
"
|
"
|
||||||
alt="Mod card"
|
alt="Mod card"
|
||||||
@@ -166,25 +172,27 @@ await process_listener((e) => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
<div
|
<template v-if="!props.small">
|
||||||
v-if="props.instance.metadata && playing === false && modLoading === false"
|
<div
|
||||||
class="install cta button-base"
|
v-if="props.instance.metadata && playing === false && modLoading === false"
|
||||||
@click="play"
|
class="install cta button-base"
|
||||||
>
|
@click="play"
|
||||||
<PlayIcon />
|
>
|
||||||
</div>
|
<PlayIcon />
|
||||||
<div v-else-if="modLoading === true && playing === false" class="cta loading">
|
</div>
|
||||||
<AnimatedLogo class="loading" />
|
<div v-else-if="modLoading === true && playing === false" class="cta loading">
|
||||||
</div>
|
<AnimatedLogo class="loading" />
|
||||||
<div
|
</div>
|
||||||
v-else-if="playing === true"
|
<div
|
||||||
class="stop cta button-base"
|
v-else-if="playing === true"
|
||||||
@click="stop"
|
class="stop cta button-base"
|
||||||
@mousehover="checkProcess"
|
@click="stop"
|
||||||
>
|
@mousehover="checkProcess"
|
||||||
<XIcon />
|
>
|
||||||
</div>
|
<XIcon />
|
||||||
<div v-else class="install cta buttonbase" @click="install"><SaveIcon /></div>
|
</div>
|
||||||
|
<div v-else class="install cta buttonbase" @click="install"><SaveIcon /></div>
|
||||||
|
</template>
|
||||||
<InstallConfirmModal ref="confirmModal" />
|
<InstallConfirmModal ref="confirmModal" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -209,10 +217,6 @@ await process_listener((e) => {
|
|||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cta {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance {
|
.instance {
|
||||||
|
|||||||
@@ -86,13 +86,13 @@ import {
|
|||||||
CodeIcon,
|
CodeIcon,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
} from 'omorphia'
|
} from 'omorphia'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref, shallowRef } from 'vue'
|
||||||
import { get_game_versions, get_loaders } from '@/helpers/tags'
|
import { get_game_versions, get_loaders } from '@/helpers/tags'
|
||||||
import { create } from '@/helpers/profile'
|
import { create } from '@/helpers/profile'
|
||||||
import { open } from '@tauri-apps/api/dialog'
|
import { open } from '@tauri-apps/api/dialog'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { tauri } from '@tauri-apps/api'
|
import { tauri } from '@tauri-apps/api'
|
||||||
import { get_fabric_versions, get_forge_versions } from '@/helpers/metadata'
|
import { get_fabric_versions, get_forge_versions, get_quilt_versions } from '@/helpers/metadata'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@@ -129,20 +129,27 @@ defineExpose({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const all_game_versions = ref(await get_game_versions())
|
const [fabric_versions, forge_versions, quilt_versions, all_game_versions, loaders] =
|
||||||
|
await Promise.all([
|
||||||
|
get_fabric_versions().then(shallowRef),
|
||||||
|
get_forge_versions().then(shallowRef),
|
||||||
|
get_quilt_versions().then(shallowRef),
|
||||||
|
get_game_versions().then(shallowRef),
|
||||||
|
get_loaders()
|
||||||
|
.then((value) =>
|
||||||
|
value
|
||||||
|
.filter((item) => item.supported_project_types.includes('modpack'))
|
||||||
|
.map((item) => item.name.toLowerCase())
|
||||||
|
)
|
||||||
|
.then(ref),
|
||||||
|
])
|
||||||
|
|
||||||
const game_versions = computed(() => {
|
const game_versions = computed(() => {
|
||||||
return all_game_versions.value
|
return all_game_versions.value
|
||||||
.filter((item) => item.version_type === 'release' || showSnapshots.value)
|
.filter((item) => item.version_type === 'release' || showSnapshots.value)
|
||||||
.map((item) => item.version)
|
.map((item) => item.version)
|
||||||
})
|
})
|
||||||
const loaders = ref(
|
|
||||||
await get_loaders().then((value) =>
|
|
||||||
value
|
|
||||||
.filter((item) => item.supported_project_types.includes('modpack'))
|
|
||||||
.map((item) => item.name.toLowerCase())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
const modal = ref(null)
|
const modal = ref(null)
|
||||||
|
|
||||||
const check_valid = computed(() => {
|
const check_valid = computed(() => {
|
||||||
@@ -191,9 +198,6 @@ const reset_icon = () => {
|
|||||||
display_icon.value = null
|
display_icon.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
const fabric_versions = ref(await get_fabric_versions())
|
|
||||||
const forge_versions = ref(await get_forge_versions())
|
|
||||||
|
|
||||||
const selectable_versions = computed(() => {
|
const selectable_versions = computed(() => {
|
||||||
if (game_version.value) {
|
if (game_version.value) {
|
||||||
if (loader.value === 'fabric') {
|
if (loader.value === 'fabric') {
|
||||||
@@ -202,6 +206,8 @@ const selectable_versions = computed(() => {
|
|||||||
return forge_versions.value.gameVersions
|
return forge_versions.value.gameVersions
|
||||||
.find((item) => item.id === game_version.value)
|
.find((item) => item.id === game_version.value)
|
||||||
.loaders.map((item) => item.id)
|
.loaders.map((item) => item.id)
|
||||||
|
} else if (loader.value === 'quilt') {
|
||||||
|
return quilt_versions.value.gameVersions[0].loaders.map((item) => item.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
|
|||||||
@@ -11,14 +11,15 @@ import {
|
|||||||
RightArrowIcon,
|
RightArrowIcon,
|
||||||
CheckIcon,
|
CheckIcon,
|
||||||
} from 'omorphia'
|
} from 'omorphia'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref, shallowRef } from 'vue'
|
||||||
import { add_project_from_version as installMod, list } from '@/helpers/profile'
|
import { add_project_from_version as installMod, check_installed, list } from '@/helpers/profile'
|
||||||
import { tauri } from '@tauri-apps/api'
|
import { tauri } from '@tauri-apps/api'
|
||||||
import { open } from '@tauri-apps/api/dialog'
|
import { open } from '@tauri-apps/api/dialog'
|
||||||
import { convertFileSrc } from '@tauri-apps/api/tauri'
|
import { convertFileSrc } from '@tauri-apps/api/tauri'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { create } from '@/helpers/profile'
|
import { create } from '@/helpers/profile'
|
||||||
import { checkInstalled, installVersionDependencies } from '@/helpers/utils'
|
import { installVersionDependencies } from '@/helpers/utils'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const versions = ref([])
|
const versions = ref([])
|
||||||
const project = ref('')
|
const project = ref('')
|
||||||
@@ -33,15 +34,17 @@ const gameVersion = ref(null)
|
|||||||
const creatingInstance = ref(false)
|
const creatingInstance = ref(false)
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
show: (projectId, selectedVersion) => {
|
show: async (projectId, selectedVersion) => {
|
||||||
project.value = projectId
|
project.value = projectId
|
||||||
versions.value = selectedVersion
|
versions.value = selectedVersion
|
||||||
installModal.value.show()
|
installModal.value.show()
|
||||||
searchFilter.value = ''
|
searchFilter.value = ''
|
||||||
|
|
||||||
|
profiles.value = await getData()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const profiles = ref(await list().then(Object.values))
|
const profiles = shallowRef(await getData())
|
||||||
|
|
||||||
async function install(instance) {
|
async function install(instance) {
|
||||||
instance.installing = true
|
instance.installing = true
|
||||||
@@ -59,8 +62,10 @@ async function install(instance) {
|
|||||||
instance.installing = false
|
instance.installing = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const filteredVersions = computed(() => {
|
async function getData() {
|
||||||
const filtered = profiles.value
|
const projects = await list(true).then(Object.values)
|
||||||
|
|
||||||
|
const filtered = projects
|
||||||
.filter((profile) => {
|
.filter((profile) => {
|
||||||
return profile.metadata.name.toLowerCase().includes(searchFilter.value.toLowerCase())
|
return profile.metadata.name.toLowerCase().includes(searchFilter.value.toLowerCase())
|
||||||
})
|
})
|
||||||
@@ -69,17 +74,20 @@ const filteredVersions = computed(() => {
|
|||||||
versions.value.flatMap((v) => v.game_versions).includes(profile.metadata.game_version) &&
|
versions.value.flatMap((v) => v.game_versions).includes(profile.metadata.game_version) &&
|
||||||
versions.value
|
versions.value
|
||||||
.flatMap((v) => v.loaders)
|
.flatMap((v) => v.loaders)
|
||||||
.some((value) => value === profile.metadata.loader || value === 'minecraft')
|
.some(
|
||||||
|
(value) =>
|
||||||
|
value === profile.metadata.loader || ['minecraft', 'iris', 'optifine'].includes(value)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
filtered.map((profile) => {
|
for (let profile of filtered) {
|
||||||
profile.installing = false
|
profile.installing = false
|
||||||
profile.installedMod = checkInstalled(profile, project.value)
|
profile.installedMod = await check_installed(profile.path, project.value)
|
||||||
})
|
}
|
||||||
|
|
||||||
return filtered
|
return filtered
|
||||||
})
|
}
|
||||||
|
|
||||||
const toggleCreation = () => {
|
const toggleCreation = () => {
|
||||||
showCreation.value = !showCreation.value
|
showCreation.value = !showCreation.value
|
||||||
@@ -140,7 +148,7 @@ const check_valid = computed(() => {
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<input v-model="searchFilter" type="text" class="search" placeholder="Search for a profile" />
|
<input v-model="searchFilter" type="text" class="search" placeholder="Search for a profile" />
|
||||||
<div class="profiles">
|
<div class="profiles">
|
||||||
<div v-for="profile in filteredVersions" :key="profile.metadata.name" class="option">
|
<div v-for="profile in profiles" :key="profile.metadata.name" class="option">
|
||||||
<Button
|
<Button
|
||||||
color="raised"
|
color="raised"
|
||||||
class="profile-button"
|
class="profile-button"
|
||||||
|
|||||||
@@ -17,3 +17,9 @@ export async function get_fabric_versions() {
|
|||||||
export async function get_forge_versions() {
|
export async function get_forge_versions() {
|
||||||
return await invoke('metadata_get_forge_versions')
|
return await invoke('metadata_get_forge_versions')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets the quilt versions from daedalus
|
||||||
|
// Returns Manifest
|
||||||
|
export async function get_quilt_versions() {
|
||||||
|
return await invoke('metadata_get_quilt_versions')
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,14 +32,18 @@ export async function remove(path) {
|
|||||||
|
|
||||||
// Get a profile by path
|
// Get a profile by path
|
||||||
// Returns a Profile
|
// Returns a Profile
|
||||||
export async function get(path) {
|
export async function get(path, clearProjects) {
|
||||||
return await invoke('profile_get', { path })
|
return await invoke('profile_get', { path, clearProjects })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a copy of the profile set
|
// Get a copy of the profile set
|
||||||
// Returns hashmap of path -> Profile
|
// Returns hashmap of path -> Profile
|
||||||
export async function list() {
|
export async function list(clearProjects) {
|
||||||
return await invoke('profile_list')
|
return await invoke('profile_list', { clearProjects })
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function check_installed(path, projectId) {
|
||||||
|
return await invoke('profile_check_installed', { path, projectId })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Syncs a profile with the disk
|
// Syncs a profile with the disk
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { add_project_from_version as installMod } from '@/helpers/profile'
|
import { add_project_from_version as installMod, check_installed } from '@/helpers/profile'
|
||||||
import { ofetch } from 'ofetch'
|
import { ofetch } from 'ofetch'
|
||||||
|
|
||||||
export const releaseColor = (releaseType) => {
|
export const releaseColor = (releaseType) => {
|
||||||
@@ -14,17 +14,13 @@ export const releaseColor = (releaseType) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const checkInstalled = (profile, projectId) => {
|
|
||||||
return Object.values(profile.projects).some((p) => p.metadata?.project?.id === projectId)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const installVersionDependencies = async (profile, version) => {
|
export const installVersionDependencies = async (profile, version) => {
|
||||||
for (const dep of version.dependencies) {
|
for (const dep of version.dependencies) {
|
||||||
if (dep.version_id) {
|
if (dep.version_id) {
|
||||||
if (checkInstalled(profile, dep.project_id)) continue
|
if (await check_installed(profile.path, dep.project_id)) continue
|
||||||
await installMod(profile.path, dep.version_id)
|
await installMod(profile.path, dep.version_id)
|
||||||
} else {
|
} else {
|
||||||
if (checkInstalled(profile, dep.project_id)) continue
|
if (await check_installed(profile.path, dep.project_id)) continue
|
||||||
const depVersions = await ofetch(
|
const depVersions = await ofetch(
|
||||||
`https://api.modrinth.com/v2/project/${dep.project_id}/version`
|
`https://api.modrinth.com/v2/project/${dep.project_id}/version`
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -167,15 +167,17 @@ watch(
|
|||||||
v-if="
|
v-if="
|
||||||
showLoaders &&
|
showLoaders &&
|
||||||
searchStore.projectType !== 'datapack' &&
|
searchStore.projectType !== 'datapack' &&
|
||||||
searchStore.projectType !== 'resourcepack' &&
|
searchStore.projectType !== 'resourcepack'
|
||||||
searchStore.projectType !== 'shader'
|
|
||||||
"
|
"
|
||||||
class="loaders"
|
class="loaders"
|
||||||
>
|
>
|
||||||
<h2>Loaders</h2>
|
<h2>Loaders</h2>
|
||||||
<div
|
<div
|
||||||
v-for="loader in loaders.filter((l) =>
|
v-for="loader in loaders.filter(
|
||||||
l.supported_project_types?.includes(searchStore.projectType)
|
(l) =>
|
||||||
|
(searchStore.projectType !== 'mod' &&
|
||||||
|
l.supported_project_types?.includes(searchStore.projectType)) ||
|
||||||
|
(searchStore.projectType === 'mod' && ['fabric', 'forge', 'quilt'].includes(l.name))
|
||||||
)"
|
)"
|
||||||
:key="loader"
|
:key="loader"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ const breadcrumbs = useBreadcrumbs()
|
|||||||
|
|
||||||
breadcrumbs.setRootContext({ name: 'Home', link: route.path })
|
breadcrumbs.setRootContext({ name: 'Home', link: route.path })
|
||||||
|
|
||||||
const recentInstances = shallowRef(Object.values(await list()))
|
const recentInstances = shallowRef([])
|
||||||
|
|
||||||
const getInstances = async () => {
|
const getInstances = async () => {
|
||||||
filter.value = ''
|
filter.value = ''
|
||||||
const profiles = await list()
|
const profiles = await list(true)
|
||||||
recentInstances.value = Object.values(profiles)
|
recentInstances.value = Object.values(profiles)
|
||||||
|
|
||||||
const excludeIds = recentInstances.value.map((i) => i.metadata?.linked_data?.project_id)
|
const excludeIds = recentInstances.value.map((i) => i.metadata?.linked_data?.project_id)
|
||||||
@@ -47,8 +47,8 @@ await getInstances()
|
|||||||
await Promise.all([getFeaturedModpacks(), getFeaturedMods()])
|
await Promise.all([getFeaturedModpacks(), getFeaturedMods()])
|
||||||
|
|
||||||
const unlisten = await profile_listener(async (e) => {
|
const unlisten = await profile_listener(async (e) => {
|
||||||
|
await getInstances()
|
||||||
if (e.event === 'created' || e.event === 'removed') {
|
if (e.event === 'created' || e.event === 'removed') {
|
||||||
await getInstances()
|
|
||||||
await Promise.all([getFeaturedModpacks(), getFeaturedMods()])
|
await Promise.all([getFeaturedModpacks(), getFeaturedMods()])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,21 +4,19 @@ import GridDisplay from '@/components/GridDisplay.vue'
|
|||||||
import { list } from '@/helpers/profile.js'
|
import { list } from '@/helpers/profile.js'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||||
import { loading_listener } from '@/helpers/events.js'
|
import { profile_listener } from '@/helpers/events.js'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const breadcrumbs = useBreadcrumbs()
|
const breadcrumbs = useBreadcrumbs()
|
||||||
|
|
||||||
breadcrumbs.setRootContext({ name: 'Library', link: route.path })
|
breadcrumbs.setRootContext({ name: 'Library', link: route.path })
|
||||||
|
|
||||||
const profiles = await list()
|
const profiles = await list(true)
|
||||||
const instances = shallowRef(Object.values(profiles))
|
const instances = shallowRef(Object.values(profiles))
|
||||||
|
|
||||||
loading_listener(async (profile) => {
|
profile_listener(async () => {
|
||||||
if (profile.event === 'loaded') {
|
const profiles = await list(true)
|
||||||
const profiles = await list()
|
instances.value = Object.values(profiles)
|
||||||
instances.value = Object.values(profiles)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
<Avatar
|
<Avatar
|
||||||
size="lg"
|
size="lg"
|
||||||
:src="
|
:src="
|
||||||
instance.metadata.icon && instance.metadata.icon.startsWith('http')
|
!instance.metadata.icon ||
|
||||||
|
(instance.metadata.icon && instance.metadata.icon.startsWith('http'))
|
||||||
? instance.metadata.icon
|
? instance.metadata.icon
|
||||||
: convertFileSrc(instance.metadata?.icon)
|
: convertFileSrc(instance.metadata?.icon)
|
||||||
"
|
"
|
||||||
|
|||||||
@@ -221,13 +221,13 @@ import {
|
|||||||
} from '@/assets/external'
|
} from '@/assets/external'
|
||||||
import { get_categories, get_loaders } from '@/helpers/tags'
|
import { get_categories, get_loaders } from '@/helpers/tags'
|
||||||
import { install as packInstall } from '@/helpers/pack'
|
import { install as packInstall } from '@/helpers/pack'
|
||||||
import { list, add_project_from_version as installMod } from '@/helpers/profile'
|
import { list, add_project_from_version as installMod, check_installed } from '@/helpers/profile'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||||
import { ofetch } from 'ofetch'
|
import { ofetch } from 'ofetch'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { ref, shallowRef, watch } from 'vue'
|
import { ref, shallowRef, watch } from 'vue'
|
||||||
import { checkInstalled, installVersionDependencies } from '@/helpers/utils'
|
import { installVersionDependencies } from '@/helpers/utils'
|
||||||
import InstallConfirmModal from '@/components/ui/InstallConfirmModal.vue'
|
import InstallConfirmModal from '@/components/ui/InstallConfirmModal.vue'
|
||||||
import InstanceInstallModal from '@/components/ui/InstanceInstallModal.vue'
|
import InstanceInstallModal from '@/components/ui/InstanceInstallModal.vue'
|
||||||
import Instance from '@/components/ui/Instance.vue'
|
import Instance from '@/components/ui/Instance.vue'
|
||||||
@@ -242,19 +242,19 @@ const breadcrumbs = useBreadcrumbs()
|
|||||||
|
|
||||||
const confirmModal = ref(null)
|
const confirmModal = ref(null)
|
||||||
const modInstallModal = ref(null)
|
const modInstallModal = ref(null)
|
||||||
const loaders = ref(await get_loaders())
|
|
||||||
const categories = ref(await get_categories())
|
|
||||||
const instance = ref(searchStore.instanceContext)
|
const instance = ref(searchStore.instanceContext)
|
||||||
const installing = ref(false)
|
const installing = ref(false)
|
||||||
|
|
||||||
const [data, versions, members, dependencies] = await Promise.all([
|
const [data, versions, members, dependencies, categories, loaders] = await Promise.all([
|
||||||
ofetch(`https://api.modrinth.com/v2/project/${route.params.id}`).then(shallowRef),
|
ofetch(`https://api.modrinth.com/v2/project/${route.params.id}`).then(shallowRef),
|
||||||
ofetch(`https://api.modrinth.com/v2/project/${route.params.id}/version`).then(shallowRef),
|
ofetch(`https://api.modrinth.com/v2/project/${route.params.id}/version`).then(shallowRef),
|
||||||
ofetch(`https://api.modrinth.com/v2/project/${route.params.id}/members`).then(shallowRef),
|
ofetch(`https://api.modrinth.com/v2/project/${route.params.id}/members`).then(shallowRef),
|
||||||
ofetch(`https://api.modrinth.com/v2/project/${route.params.id}/dependencies`).then(shallowRef),
|
ofetch(`https://api.modrinth.com/v2/project/${route.params.id}/dependencies`).then(shallowRef),
|
||||||
|
get_loaders().then(ref),
|
||||||
|
get_categories().then(ref),
|
||||||
])
|
])
|
||||||
|
|
||||||
const installed = ref(instance.value && checkInstalled(instance.value, data.value.id))
|
const installed = ref(instance.value && (await check_installed(instance.value.path, data.value.id)))
|
||||||
|
|
||||||
breadcrumbs.setName('Project', data.value.title)
|
breadcrumbs.setName('Project', data.value.title)
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ async function install(version) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (data.value.project_type === 'modpack') {
|
if (data.value.project_type === 'modpack') {
|
||||||
const packs = Object.values(await list())
|
const packs = Object.values(await list(true))
|
||||||
if (
|
if (
|
||||||
packs.length === 0 ||
|
packs.length === 0 ||
|
||||||
!packs
|
!packs
|
||||||
@@ -317,7 +317,7 @@ async function install(version) {
|
|||||||
await installMod(instance.value.path, queuedVersionData.id)
|
await installMod(instance.value.path, queuedVersionData.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
installVersionDependencies(instance.value, queuedVersionData)
|
await installVersionDependencies(instance.value, queuedVersionData)
|
||||||
|
|
||||||
installed.value = true
|
installed.value = true
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ async fn main() -> theseus::Result<()> {
|
|||||||
// Clear profiles
|
// Clear profiles
|
||||||
println!("Clearing profiles.");
|
println!("Clearing profiles.");
|
||||||
{
|
{
|
||||||
let h = profile::list().await?;
|
let h = profile::list(None).await?;
|
||||||
for (path, _) in h.into_iter() {
|
for (path, _) in h.into_iter() {
|
||||||
profile::remove(&path).await?;
|
profile::remove(&path).await?;
|
||||||
}
|
}
|
||||||
@@ -69,51 +69,52 @@ async fn main() -> theseus::Result<()> {
|
|||||||
|
|
||||||
println!("Creating/adding profile.");
|
println!("Creating/adding profile.");
|
||||||
|
|
||||||
let name = "Example".to_string();
|
// let name = "Example".to_string();
|
||||||
let game_version = "1.19.2".to_string();
|
// let game_version = "1.19.2".to_string();
|
||||||
let modloader = ModLoader::Vanilla;
|
// let modloader = ModLoader::Vanilla;
|
||||||
let loader_version = "stable".to_string();
|
// let loader_version = "stable".to_string();
|
||||||
|
//
|
||||||
let profile_path = profile_create(
|
// let profile_path = profile_create(
|
||||||
name.clone(),
|
// name.clone(),
|
||||||
game_version,
|
// game_version,
|
||||||
modloader,
|
// modloader,
|
||||||
Some(loader_version),
|
// Some(loader_version),
|
||||||
None,
|
// None,
|
||||||
None,
|
// None,
|
||||||
None,
|
// None,
|
||||||
None,
|
// None,
|
||||||
)
|
// )
|
||||||
.await?;
|
// .await?;
|
||||||
|
//
|
||||||
install(&profile_path).await.unwrap();
|
// install(&profile_path).await.unwrap();
|
||||||
|
|
||||||
// let mut value = list().await?;
|
// let mut value = list().await?;
|
||||||
// let profile_path = value.iter().next().map(|x| x.0).unwrap();
|
// let profile_path = value.iter().next().map(|x| x.0).unwrap();
|
||||||
|
|
||||||
println!("Adding sodium");
|
// println!("Adding sodium");
|
||||||
let sodium_path = profile::add_project_from_version(
|
// let sodium_path = profile::add_project_from_version(
|
||||||
&profile_path,
|
// &profile_path,
|
||||||
"rAfhHfow".to_string(),
|
// "rAfhHfow".to_string(),
|
||||||
)
|
// )
|
||||||
.await?;
|
// .await?;
|
||||||
|
//
|
||||||
let mod_menu_path = profile::add_project_from_version(
|
// let mod_menu_path = profile::add_project_from_version(
|
||||||
&profile_path,
|
// &profile_path,
|
||||||
"gSoPJyVn".to_string(),
|
// "gSoPJyVn".to_string(),
|
||||||
)
|
// )
|
||||||
.await?;
|
// .await?;
|
||||||
|
//
|
||||||
println!("Disabling sodium");
|
// println!("Disabling sodium");
|
||||||
profile::toggle_disable_project(&profile_path, &sodium_path).await?;
|
// profile::toggle_disable_project(&profile_path, &sodium_path).await?;
|
||||||
|
|
||||||
// profile::remove_project(&profile_path, &mod_menu_path).await?;
|
// profile::remove_project(&profile_path, &mod_menu_path).await?;
|
||||||
// let profile_path = pack::install_pack_from_version_id(
|
let profile_path = pack::install_pack_from_version_id(
|
||||||
// "zroFQG1k".to_string(),
|
"CeeCkHke".to_string(),
|
||||||
// Some("Technical Electrical".to_string()),
|
"Technical Electrical".to_string(),
|
||||||
// )
|
None,
|
||||||
// .await
|
)
|
||||||
// .unwrap();
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// async closure for testing any desired edits
|
// async closure for testing any desired edits
|
||||||
// (ie: changing the java runtime of an added profile)
|
// (ie: changing the java runtime of an added profile)
|
||||||
|
|||||||
Reference in New Issue
Block a user