chore: update dependencies (#1103)

* update trivial dependencies

* switch to sha1_smol

* update async_zip

* fix cli

* clippy & fmt

* js lints

* fix build for ci
This commit is contained in:
ToBinio
2024-04-07 21:13:35 +02:00
committed by GitHub
parent 6699b4cb33
commit 3e7fd80824
57 changed files with 2720 additions and 2038 deletions

2862
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,14 +13,14 @@ bytes = "1"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
serde_ini = "0.2.0" serde_ini = "0.2.0"
toml = "0.7.3" toml = "0.8.12"
sha1 = { version = "0.6.1", features = ["std"]} sha1_smol = { version = "1.0.0", features = ["std"] }
sha2 = "0.9.9" sha2 = "0.10.8"
url = "2.2" url = "2.2"
uuid = { version = "1.1", features = ["serde", "v4"] } uuid = { version = "1.1", features = ["serde", "v4"] }
zip = "0.6.5" zip = "0.6.5"
async_zip = { version = "0.0.13", features = ["full"] } async_zip = { version = "0.0.17", features = ["full"] }
flate2 = "1.0.27" flate2 = "1.0.28"
tempfile = "3.5.0" tempfile = "3.5.0"
urlencoding = "2.1.3" urlencoding = "2.1.3"
@@ -31,28 +31,28 @@ dirs = "5.0.1"
regex = "1.5" regex = "1.5"
sys-info = "0.9.0" sys-info = "0.9.0"
sysinfo = "0.29.9" sysinfo = "0.30.8"
thiserror = "1.0" thiserror = "1.0"
tracing = "0.1.37" tracing = "0.1.37"
tracing-subscriber = {version = "0.2", features = ["chrono"]} tracing-subscriber = { version = "0.3.18", features = ["chrono"] }
tracing-error = "0.1.0" tracing-error = "0.2.0"
tracing-appender = "0.1" tracing-appender = "0.2.3"
paste = { version = "1.0"} paste = { version = "1.0" }
tauri = { version = "1.2", optional = true} tauri = { version = "1.6.1", optional = true }
indicatif = { version = "0.17.3", optional = true } indicatif = { version = "0.17.3", optional = true }
async-tungstenite = { version = "0.22.1", features = ["tokio-runtime", "tokio-native-tls"] } async-tungstenite = { version = "0.25.1", features = ["tokio-runtime", "tokio-native-tls"] }
futures = "0.3" futures = "0.3"
reqwest = { version = "0.11", features = ["json", "stream"] } reqwest = { version = "0.12.3", features = ["json", "stream"] }
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
tokio-stream = { version = "0.1", features = ["fs"] } tokio-stream = { version = "0.1", features = ["fs"] }
async-recursion = "1.0.4" async-recursion = "1.0.4"
notify = { version = "5.1.0", default-features = false } notify = { version = "6.1.1", default-features = false }
notify-debouncer-mini = { version = "0.2.1", default-features = false } notify-debouncer-mini = { version = "0.4.1", default-features = false }
lazy_static = "1.4.0" lazy_static = "1.4.0"
dunce = "1.0.3" dunce = "1.0.3"
@@ -62,7 +62,7 @@ whoami = "1.4.0"
discord-rich-presence = "0.2.3" discord-rich-presence = "0.2.3"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winreg = "0.50.0" winreg = "0.52.0"
[features] [features]
tauri = ["dep:tauri"] tauri = ["dep:tauri"]

View File

@@ -11,7 +11,7 @@ use crate::state::{ProfileInstallStage, Profiles, SideType};
use crate::util::fetch::{fetch_json, fetch_mirrors, write}; use crate::util::fetch::{fetch_json, fetch_mirrors, write};
use crate::util::io; use crate::util::io;
use crate::{profile, State}; use crate::{profile, State};
use async_zip::tokio::read::seek::ZipFileReader; use async_zip::base::read::seek::ZipFileReader;
use reqwest::Method; use reqwest::Method;
use serde_json::json; use serde_json::json;
@@ -93,29 +93,21 @@ pub async fn install_zipped_mrpack_files(
let reader: Cursor<&bytes::Bytes> = Cursor::new(&file); let reader: Cursor<&bytes::Bytes> = Cursor::new(&file);
// Create zip reader around file // Create zip reader around file
let mut zip_reader = ZipFileReader::new(reader).await.map_err(|_| { let mut zip_reader =
crate::Error::from(crate::ErrorKind::InputError( ZipFileReader::with_tokio(reader).await.map_err(|_| {
"Failed to read input modpack zip".to_string(), crate::Error::from(crate::ErrorKind::InputError(
)) "Failed to read input modpack zip".to_string(),
})?; ))
})?;
// Extract index of modrinth.index.json // Extract index of modrinth.index.json
let zip_index_option = zip_reader let zip_index_option = zip_reader.file().entries().iter().position(|f| {
.file() f.filename().as_str().unwrap_or_default() == "modrinth.index.json"
.entries() });
.iter()
.position(|f| f.entry().filename() == "modrinth.index.json");
if let Some(zip_index) = zip_index_option { if let Some(zip_index) = zip_index_option {
let mut manifest = String::new(); let mut manifest = String::new();
let entry = zip_reader let mut reader = zip_reader.reader_with_entry(zip_index).await?;
.file() reader.read_to_string_checked(&mut manifest).await?;
.entries()
.get(zip_index)
.unwrap()
.entry()
.clone();
let mut reader = zip_reader.entry(zip_index).await?;
reader.read_to_string_checked(&mut manifest, &entry).await?;
let pack: PackFormat = serde_json::from_str(&manifest)?; let pack: PackFormat = serde_json::from_str(&manifest)?;
@@ -217,34 +209,31 @@ pub async fn install_zipped_mrpack_files(
let mut total_len = 0; let mut total_len = 0;
for index in 0..zip_reader.file().entries().len() { for index in 0..zip_reader.file().entries().len() {
let file = zip_reader.file().entries().get(index).unwrap().entry(); let file = zip_reader.file().entries().get(index).unwrap();
let filename = file.filename().as_str().unwrap_or_default();
if (file.filename().starts_with("overrides") if (filename.starts_with("overrides")
|| file.filename().starts_with("client_overrides")) || filename.starts_with("client_overrides"))
&& !file.filename().ends_with('/') && !filename.ends_with('/')
{ {
total_len += 1; total_len += 1;
} }
} }
for index in 0..zip_reader.file().entries().len() { for index in 0..zip_reader.file().entries().len() {
let file = zip_reader let file = zip_reader.file().entries().get(index).unwrap();
.file()
.entries()
.get(index)
.unwrap()
.entry()
.clone();
let file_path = PathBuf::from(file.filename()); let filename = file.filename().as_str().unwrap_or_default();
if (file.filename().starts_with("overrides")
|| file.filename().starts_with("client_overrides")) let file_path = PathBuf::from(filename);
&& !file.filename().ends_with('/') if (filename.starts_with("overrides")
|| filename.starts_with("client_overrides"))
&& !filename.ends_with('/')
{ {
// Reads the file into the 'content' variable // Reads the file into the 'content' variable
let mut content = Vec::new(); let mut content = Vec::new();
let mut reader = zip_reader.entry(index).await?; let mut reader = zip_reader.reader_with_entry(index).await?;
reader.read_to_end_checked(&mut content, &file).await?; reader.read_to_end_checked(&mut content).await?;
let mut new_path = PathBuf::new(); let mut new_path = PathBuf::new();
let components = file_path.components().skip(1); let components = file_path.components().skip(1);
@@ -310,29 +299,22 @@ pub async fn remove_all_related_files(
let reader: Cursor<&bytes::Bytes> = Cursor::new(&mrpack_file); let reader: Cursor<&bytes::Bytes> = Cursor::new(&mrpack_file);
// Create zip reader around file // Create zip reader around file
let mut zip_reader = ZipFileReader::new(reader).await.map_err(|_| { let mut zip_reader =
crate::Error::from(crate::ErrorKind::InputError( ZipFileReader::with_tokio(reader).await.map_err(|_| {
"Failed to read input modpack zip".to_string(), crate::Error::from(crate::ErrorKind::InputError(
)) "Failed to read input modpack zip".to_string(),
})?; ))
})?;
// Extract index of modrinth.index.json // Extract index of modrinth.index.json
let zip_index_option = zip_reader let zip_index_option = zip_reader.file().entries().iter().position(|f| {
.file() f.filename().as_str().unwrap_or_default() == "modrinth.index.json"
.entries() });
.iter()
.position(|f| f.entry().filename() == "modrinth.index.json");
if let Some(zip_index) = zip_index_option { if let Some(zip_index) = zip_index_option {
let mut manifest = String::new(); let mut manifest = String::new();
let entry = zip_reader
.file() let mut reader = zip_reader.reader_with_entry(zip_index).await?;
.entries() reader.read_to_string_checked(&mut manifest).await?;
.get(zip_index)
.unwrap()
.entry()
.clone();
let mut reader = zip_reader.entry(zip_index).await?;
reader.read_to_string_checked(&mut manifest, &entry).await?;
let pack: PackFormat = serde_json::from_str(&manifest)?; let pack: PackFormat = serde_json::from_str(&manifest)?;
@@ -415,18 +397,14 @@ pub async fn remove_all_related_files(
// Iterate over each 'overrides' file and remove it // Iterate over each 'overrides' file and remove it
for index in 0..zip_reader.file().entries().len() { for index in 0..zip_reader.file().entries().len() {
let file = zip_reader let file = zip_reader.file().entries().get(index).unwrap();
.file()
.entries()
.get(index)
.unwrap()
.entry()
.clone();
let file_path = PathBuf::from(file.filename()); let filename = file.filename().as_str().unwrap_or_default();
if (file.filename().starts_with("overrides")
|| file.filename().starts_with("client_overrides")) let file_path = PathBuf::from(filename);
&& !file.filename().ends_with('/') if (filename.starts_with("overrides")
|| filename.starts_with("client_overrides"))
&& !filename.ends_with('/')
{ {
let mut new_path = PathBuf::new(); let mut new_path = PathBuf::new();
let components = file_path.components().skip(1); let components = file_path.components().skip(1);

View File

@@ -608,7 +608,7 @@ pub async fn export_mrpack(
let mut file = File::create(&export_path) let mut file = File::create(&export_path)
.await .await
.map_err(|e| IOError::with_path(e, &export_path))?; .map_err(|e| IOError::with_path(e, &export_path))?;
let mut writer = ZipFileWriter::new(&mut file); let mut writer = ZipFileWriter::with_tokio(&mut file);
// Create mrpack json configuration file // Create mrpack json configuration file
let version_id = version_id.unwrap_or("1.0.0".to_string()); let version_id = version_id.unwrap_or("1.0.0".to_string());
@@ -660,7 +660,7 @@ pub async fn export_mrpack(
.await .await
.map_err(|e| IOError::with_path(e, &path))?; .map_err(|e| IOError::with_path(e, &path))?;
let builder = ZipEntryBuilder::new( let builder = ZipEntryBuilder::new(
format!("overrides/{relative_path}"), format!("overrides/{relative_path}").into(),
Compression::Deflate, Compression::Deflate,
); );
writer.write_entry_whole(builder, &data).await?; writer.write_entry_whole(builder, &data).await?;
@@ -670,7 +670,7 @@ pub async fn export_mrpack(
// Add modrinth json to the zip // Add modrinth json to the zip
let data = serde_json::to_vec_pretty(&packfile)?; let data = serde_json::to_vec_pretty(&packfile)?;
let builder = ZipEntryBuilder::new( let builder = ZipEntryBuilder::new(
"modrinth.index.json".to_string(), "modrinth.index.json".to_string().into(),
Compression::Deflate, Compression::Deflate,
); );
writer.write_entry_whole(builder, &data).await?; writer.write_entry_whole(builder, &data).await?;

View File

@@ -1,6 +1,6 @@
//! Theseus profile management interface //! Theseus profile management interface
use std::path::{PathBuf, Path}; use std::path::{Path, PathBuf};
use tokio::fs; use tokio::fs;
use io::IOError; use io::IOError;
@@ -10,7 +10,7 @@ use crate::{
event::emit::{emit_loading, init_loading}, event::emit::{emit_loading, init_loading},
prelude::DirectoryInfo, prelude::DirectoryInfo,
state::{self, Profiles}, state::{self, Profiles},
util::{io, fetch}, util::{fetch, io},
}; };
pub use crate::{ pub use crate::{
state::{ state::{
@@ -109,7 +109,6 @@ pub async fn set_config_dir(new_config_dir: PathBuf) -> crate::Result<()> {
let old_config_dir = let old_config_dir =
state_write.directories.config_dir.read().await.clone(); state_write.directories.config_dir.read().await.clone();
// Reset file watcher // Reset file watcher
tracing::trace!("Reset file watcher"); tracing::trace!("Reset file watcher");
let file_watcher = state::init_watcher().await?; let file_watcher = state::init_watcher().await?;
@@ -125,13 +124,17 @@ pub async fn set_config_dir(new_config_dir: PathBuf) -> crate::Result<()> {
.await .await
.map_err(|e| IOError::with_path(e, &old_config_dir))? .map_err(|e| IOError::with_path(e, &old_config_dir))?
{ {
let entry_path = entry.path(); let entry_path = entry.path();
if let Some(file_name) = entry_path.file_name() { if let Some(file_name) = entry_path.file_name() {
// We are only moving the profiles and metadata folders // We are only moving the profiles and metadata folders
if file_name == state::PROFILES_FOLDER_NAME || file_name == state::METADATA_FOLDER_NAME { if file_name == state::PROFILES_FOLDER_NAME
|| file_name == state::METADATA_FOLDER_NAME
{
if across_drives { if across_drives {
entries.extend(crate::pack::import::get_all_subfiles(&entry_path).await?); entries.extend(
crate::pack::import::get_all_subfiles(&entry_path)
.await?,
);
deletable_entries.push(entry_path.clone()); deletable_entries.push(entry_path.clone());
} else { } else {
entries.push(entry_path.clone()); entries.push(entry_path.clone());
@@ -151,8 +154,7 @@ pub async fn set_config_dir(new_config_dir: PathBuf) -> crate::Result<()> {
} else { } else {
io::rename(entry_path.clone(), new_path.clone()).await?; io::rename(entry_path.clone(), new_path.clone()).await?;
} }
emit_loading(&loading_bar, 80.0 * (1.0 / num_entries), None) emit_loading(&loading_bar, 80.0 * (1.0 / num_entries), None).await?;
.await?;
} }
tracing::trace!("Setting configuration setting"); tracing::trace!("Setting configuration setting");
@@ -199,7 +201,8 @@ pub async fn set_config_dir(new_config_dir: PathBuf) -> crate::Result<()> {
&loading_bar, &loading_bar,
10.0 * (1.0 / deletable_entries_len as f64), 10.0 * (1.0 / deletable_entries_len as f64),
None, None,
).await?; )
.await?;
} }
// Reset file watcher // Reset file watcher
@@ -228,7 +231,6 @@ fn is_different_drive(path1: &Path, path2: &Path) -> bool {
root1 != root2 root1 != root2
} }
pub async fn is_dir_writeable(new_config_dir: PathBuf) -> crate::Result<bool> { pub async fn is_dir_writeable(new_config_dir: PathBuf) -> crate::Result<bool> {
let temp_path = new_config_dir.join(".tmp"); let temp_path = new_config_dir.join(".tmp");
match fs::write(temp_path.clone(), "test").await { match fs::write(temp_path.clone(), "test").await {

View File

@@ -31,7 +31,7 @@ impl EventState {
})) }))
}) })
.await .await
.map(Arc::clone) .cloned()
} }
#[cfg(not(feature = "tauri"))] #[cfg(not(feature = "tauri"))]

View File

@@ -65,7 +65,7 @@ pub fn start_logger() -> Option<WorkerGuard> {
tracing_subscriber::fmt::layer() tracing_subscriber::fmt::layer()
.with_writer(non_blocking) .with_writer(non_blocking)
.with_ansi(false) // disable ANSI escape codes .with_ansi(false) // disable ANSI escape codes
.with_timer(ChronoLocal::rfc3339()), .with_timer(ChronoLocal::rfc_3339()),
) )
.with(filter) .with(filter)
.with(tracing_error::ErrorLayer::default()); .with(tracing_error::ErrorLayer::default());

View File

@@ -3,7 +3,6 @@ use chrono::{DateTime, Utc};
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
use sysinfo::PidExt;
use tokio::process::Child; use tokio::process::Child;
use tokio::process::Command; use tokio::process::Command;
use tokio::sync::RwLock; use tokio::sync::RwLock;
@@ -13,7 +12,6 @@ use crate::event::ProcessPayloadType;
use crate::util::fetch::read_json; use crate::util::fetch::read_json;
use crate::util::io::IOError; use crate::util::io::IOError;
use crate::{profile, ErrorKind}; use crate::{profile, ErrorKind};
use sysinfo::{ProcessExt, SystemExt};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use uuid::Uuid; use uuid::Uuid;
@@ -117,7 +115,16 @@ impl ChildType {
})?; })?;
let start_time = process.start_time(); let start_time = process.start_time();
let name = process.name().to_string(); let name = process.name().to_string();
let exe = process.exe().to_string_lossy().to_string();
let Some(path) = process.exe() else {
return Err(ErrorKind::LauncherError(format!(
"Cached process {} has no accessable path",
pid
))
.into());
};
let exe = path.to_string_lossy().to_string();
let cached_process = ProcessCache { let cached_process = ProcessCache {
pid, pid,
@@ -357,8 +364,16 @@ impl Children {
if cached_process.name != process.name() { if cached_process.name != process.name() {
return Err(ErrorKind::LauncherError(format!("Cached process {} has different name than actual process {}", cached_process.pid, process.name())).into()); return Err(ErrorKind::LauncherError(format!("Cached process {} has different name than actual process {}", cached_process.pid, process.name())).into());
} }
if cached_process.exe != process.exe().to_string_lossy() { if let Some(path) = process.exe() {
return Err(ErrorKind::LauncherError(format!("Cached process {} has different exe than actual process {}", cached_process.pid, process.exe().to_string_lossy())).into()); if cached_process.exe != path.to_string_lossy() {
return Err(ErrorKind::LauncherError(format!("Cached process {} has different exe than actual process {}", cached_process.pid, path.to_string_lossy())).into());
}
} else {
return Err(ErrorKind::LauncherError(format!(
"Cached process {} has no accessable path",
cached_process.pid
))
.into());
} }
} }

View File

@@ -348,7 +348,6 @@ pub async fn init_watcher() -> crate::Result<Debouncer<RecommendedWatcher>> {
let file_watcher = new_debouncer( let file_watcher = new_debouncer(
Duration::from_secs_f32(2.0), Duration::from_secs_f32(2.0),
None,
move |res: DebounceEventResult| { move |res: DebounceEventResult| {
futures::executor::block_on(async { futures::executor::block_on(async {
tx.send(res).await.unwrap(); tx.send(res).await.unwrap();
@@ -411,9 +410,7 @@ pub async fn init_watcher() -> crate::Result<Debouncer<RecommendedWatcher>> {
} }
}); });
} }
Err(errors) => errors.iter().for_each(|err| { Err(error) => tracing::warn!("Unable to watch file: {error}"),
tracing::warn!("Unable to watch file: {err}")
}),
} }
} }
}); });

View File

@@ -228,38 +228,29 @@ async fn read_icon_from_file(
let zip_file_reader = ZipFileReader::new(path).await; let zip_file_reader = ZipFileReader::new(path).await;
if let Ok(zip_file_reader) = zip_file_reader { if let Ok(zip_file_reader) = zip_file_reader {
// Get index of icon file and open it // Get index of icon file and open it
let zip_index_option = zip_file_reader let zip_index_option =
.file() zip_file_reader.file().entries().iter().position(|f| {
.entries() f.filename().as_str().unwrap_or_default() == icon_path
.iter() });
.position(|f| f.entry().filename() == icon_path); let mut bytes = Vec::new();
if let Some(index) = zip_index_option { if zip_file_reader
let entry = zip_file_reader .reader_with_entry(zip_index_option.unwrap())
.file() .await?
.entries() .read_to_end_checked(&mut bytes)
.get(index) .await
.unwrap() .is_ok()
.entry(); {
let mut bytes = Vec::new(); let bytes = bytes::Bytes::from(bytes);
if zip_file_reader let path = write_cached_icon(
.entry(zip_index_option.unwrap()) &icon_path,
.await? cache_dir,
.read_to_end_checked(&mut bytes, entry) bytes,
.await io_semaphore,
.is_ok() )
{ .await?;
let bytes = bytes::Bytes::from(bytes);
let path = write_cached_icon(
&icon_path,
cache_dir,
bytes,
io_semaphore,
)
.await?;
return Ok(Some(path)); return Ok(Some(path));
} }
};
} }
} }
@@ -464,13 +455,12 @@ pub async fn infer_data_from_files(
}; };
// Forge // Forge
let zip_index_option = zip_file_reader let zip_index_option =
.file() zip_file_reader.file().entries().iter().position(|f| {
.entries() f.filename().as_str().unwrap_or_default()
.iter() == "META-INF/mods.toml"
.position(|f| f.entry().filename() == "META-INF/mods.toml"); });
if let Some(index) = zip_index_option { if let Some(index) = zip_index_option {
let file = zip_file_reader.file().entries().get(index).unwrap();
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
struct ForgeModInfo { struct ForgeModInfo {
@@ -489,9 +479,9 @@ pub async fn infer_data_from_files(
let mut file_str = String::new(); let mut file_str = String::new();
if zip_file_reader if zip_file_reader
.entry(index) .reader_with_entry(index)
.await? .await?
.read_to_string_checked(&mut file_str, file.entry()) .read_to_string_checked(&mut file_str)
.await .await
.is_ok() .is_ok()
{ {
@@ -538,13 +528,11 @@ pub async fn infer_data_from_files(
} }
// Forge // Forge
let zip_index_option = zip_file_reader let zip_index_option =
.file() zip_file_reader.file().entries().iter().position(|f| {
.entries() f.filename().as_str().unwrap_or_default() == "mcmod.info"
.iter() });
.position(|f| f.entry().filename() == "mcmod.info");
if let Some(index) = zip_index_option { if let Some(index) = zip_index_option {
let file = zip_file_reader.file().entries().get(index).unwrap();
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
struct ForgeMod { struct ForgeMod {
@@ -558,9 +546,9 @@ pub async fn infer_data_from_files(
let mut file_str = String::new(); let mut file_str = String::new();
if zip_file_reader if zip_file_reader
.entry(index) .reader_with_entry(index)
.await? .await?
.read_to_string_checked(&mut file_str, file.entry()) .read_to_string_checked(&mut file_str)
.await .await
.is_ok() .is_ok()
{ {
@@ -599,13 +587,11 @@ pub async fn infer_data_from_files(
} }
// Fabric // Fabric
let zip_index_option = zip_file_reader let zip_index_option =
.file() zip_file_reader.file().entries().iter().position(|f| {
.entries() f.filename().as_str().unwrap_or_default() == "fabric.mod.json"
.iter() });
.position(|f| f.entry().filename() == "fabric.mod.json");
if let Some(index) = zip_index_option { if let Some(index) = zip_index_option {
let file = zip_file_reader.file().entries().get(index).unwrap();
#[derive(Deserialize)] #[derive(Deserialize)]
#[serde(untagged)] #[serde(untagged)]
enum FabricAuthor { enum FabricAuthor {
@@ -625,9 +611,9 @@ pub async fn infer_data_from_files(
let mut file_str = String::new(); let mut file_str = String::new();
if zip_file_reader if zip_file_reader
.entry(index) .reader_with_entry(index)
.await? .await?
.read_to_string_checked(&mut file_str, file.entry()) .read_to_string_checked(&mut file_str)
.await .await
.is_ok() .is_ok()
{ {
@@ -669,13 +655,11 @@ pub async fn infer_data_from_files(
} }
// Quilt // Quilt
let zip_index_option = zip_file_reader let zip_index_option =
.file() zip_file_reader.file().entries().iter().position(|f| {
.entries() f.filename().as_str().unwrap_or_default() == "quilt.mod.json"
.iter() });
.position(|f| f.entry().filename() == "quilt.mod.json");
if let Some(index) = zip_index_option { if let Some(index) = zip_index_option {
let file = zip_file_reader.file().entries().get(index).unwrap();
#[derive(Deserialize)] #[derive(Deserialize)]
struct QuiltMetadata { struct QuiltMetadata {
pub name: Option<String>, pub name: Option<String>,
@@ -692,9 +676,9 @@ pub async fn infer_data_from_files(
let mut file_str = String::new(); let mut file_str = String::new();
if zip_file_reader if zip_file_reader
.entry(index) .reader_with_entry(index)
.await? .await?
.read_to_string_checked(&mut file_str, file.entry()) .read_to_string_checked(&mut file_str)
.await .await
.is_ok() .is_ok()
{ {
@@ -746,13 +730,11 @@ pub async fn infer_data_from_files(
} }
// Other // Other
let zip_index_option = zip_file_reader let zip_index_option =
.file() zip_file_reader.file().entries().iter().position(|f| {
.entries() f.filename().as_str().unwrap_or_default() == "pack.mcmeta"
.iter() });
.position(|f| f.entry().filename() == "pack.mcmeta");
if let Some(index) = zip_index_option { if let Some(index) = zip_index_option {
let file = zip_file_reader.file().entries().get(index).unwrap();
#[derive(Deserialize)] #[derive(Deserialize)]
struct Pack { struct Pack {
description: Option<String>, description: Option<String>,
@@ -760,9 +742,9 @@ pub async fn infer_data_from_files(
let mut file_str = String::new(); let mut file_str = String::new();
if zip_file_reader if zip_file_reader
.entry(index) .reader_with_entry(index)
.await? .await?
.read_to_string_checked(&mut file_str, file.entry()) .read_to_string_checked(&mut file_str)
.await .await
.is_ok() .is_ok()
{ {

View File

@@ -337,7 +337,7 @@ pub async fn write_cached_icon(
async fn sha1_async(bytes: Bytes) -> crate::Result<String> { async fn sha1_async(bytes: Bytes) -> crate::Result<String> {
let hash = tokio::task::spawn_blocking(move || { let hash = tokio::task::spawn_blocking(move || {
sha1::Sha1::from(bytes).hexdigest() sha1_smol::Sha1::from(bytes).hexdigest()
}) })
.await?; .await?;

View File

@@ -1,7 +1,7 @@
// IO error // IO error
// A wrapper around the tokio IO functions that adds the path to the error message, instead of the uninformative std::io::Error. // A wrapper around the tokio IO functions that adds the path to the error message, instead of the uninformative std::io::Error.
use std::{path::Path, io::Write}; use std::{io::Write, path::Path};
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
use tokio::task::spawn_blocking; use tokio::task::spawn_blocking;
@@ -137,12 +137,13 @@ fn sync_write(
data: impl AsRef<[u8]>, data: impl AsRef<[u8]>,
path: impl AsRef<Path>, path: impl AsRef<Path>,
) -> Result<(), std::io::Error> { ) -> Result<(), std::io::Error> {
let mut tempfile = NamedTempFile::new_in(path.as_ref().parent().ok_or_else(|| { let mut tempfile =
std::io::Error::new( NamedTempFile::new_in(path.as_ref().parent().ok_or_else(|| {
std::io::ErrorKind::Other, std::io::Error::new(
"could not get parent directory for temporary file", std::io::ErrorKind::Other,
) "could not get parent directory for temporary file",
})?)?; )
})?)?;
tempfile.write_all(data.as_ref())?; tempfile.write_all(data.as_ref())?;
let tmp_path = tempfile.into_temp_path(); let tmp_path = tempfile.into_temp_path();
let path = path.as_ref(); let path = path.as_ref();

View File

@@ -14,9 +14,9 @@ tokio-stream = { version = "0.1", features = ["fs"] }
futures = "0.3" futures = "0.3"
argh = "0.1" argh = "0.1"
paris = { version = "1.5", features = ["macros", "no_logger"] } paris = { version = "1.5", features = ["macros", "no_logger"] }
dialoguer = "0.10" dialoguer = "0.11.0"
tabled = "0.5" tabled = "0.15.0"
dirs = "4.0" dirs = "5.0.1"
uuid = {version = "1.1", features = ["v4", "serde"]} uuid = {version = "1.1", features = ["v4", "serde"]}
url = "2.2" url = "2.2"
@@ -28,7 +28,7 @@ tracing-futures = "0.2"
tracing-subscriber = {version = "0.3", features = ["env-filter"]} tracing-subscriber = {version = "0.3", features = ["env-filter"]}
dunce = "1.0.3" dunce = "1.0.3"
webbrowser = "0.7" webbrowser = "0.8.13"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winreg = "0.11.0" winreg = "0.52.0"

View File

@@ -1,13 +1,14 @@
//! Profile management subcommand //! Profile management subcommand
use crate::util::{ use crate::util::table_path_display;
confirm_async, prompt_async, select_async, table, table_path_display, use crate::util::{confirm_async, prompt_async, select_async, table};
};
use daedalus::modded::LoaderVersion; use daedalus::modded::LoaderVersion;
use dunce::canonicalize; use dunce::canonicalize;
use eyre::{ensure, Result}; use eyre::{ensure, Result};
use futures::prelude::*; use futures::prelude::*;
use paris::*; use paris::*;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use tabled::settings::object::Columns;
use tabled::settings::{Modify, Width};
use tabled::Tabled; use tabled::Tabled;
use theseus::prelude::*; use theseus::prelude::*;
use theseus::profile::create::profile_create; use theseus::profile::create::profile_create;
@@ -216,12 +217,12 @@ pub struct ProfileList {}
#[derive(Tabled)] #[derive(Tabled)]
struct ProfileRow<'a> { struct ProfileRow<'a> {
name: &'a str, name: &'a str,
#[field(display_with = "table_path_display")] #[tabled(display_with = "table_path_display")]
path: &'a Path, path: &'a Path,
#[header("game version")] #[tabled(rename = "game version")]
game_version: &'a str, game_version: &'a str,
loader: &'a ModLoader, loader: &'a ModLoader,
#[header("loader version")] #[tabled(rename = "loader version")]
loader_version: &'a str, loader_version: &'a str,
} }
@@ -262,10 +263,9 @@ impl ProfileList {
let profiles = profile::list(None).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 mut table = table(rows);
tabled::Modify::new(tabled::Column(1..=1)) table.with(Modify::new(Columns::new(1..=1)).with(Width::wrap(40)));
.with(tabled::MaxWidth::wrapping(40)),
);
println!("{table}"); println!("{table}");
Ok(()) Ok(())

View File

@@ -1,6 +1,7 @@
use dialoguer::{Confirm, Input, Select}; use dialoguer::{Confirm, Input, Select};
use eyre::Result; use eyre::Result;
use std::{borrow::Cow, path::Path}; use std::{borrow::Cow, path::Path};
use tabled::settings::Style;
use tabled::{Table, Tabled}; use tabled::{Table, Tabled};
// TODO: make primarily async to avoid copies // TODO: make primarily async to avoid copies
@@ -14,11 +15,10 @@ pub fn prompt(prompt: &str, default: Option<String>) -> Result<String> {
}; };
print_prompt(&prompt); print_prompt(&prompt);
let mut input = Input::<String>::new(); let mut input = Input::<String>::new().with_prompt("").show_default(false);
input.with_prompt("").show_default(false);
if let Some(default) = default { if let Some(default) = default {
input.default(default); input = input.default(default);
} }
Ok(input.interact_text()?.trim().to_owned()) Ok(input.interact_text()?.trim().to_owned())
@@ -59,7 +59,7 @@ pub async fn confirm_async(prompt: String, default: bool) -> Result<bool> {
// Table helpers // Table helpers
pub fn table<T: Tabled>(rows: impl IntoIterator<Item = T>) -> Table { pub fn table<T: Tabled>(rows: impl IntoIterator<Item = T>) -> Table {
Table::new(rows).with(tabled::Style::psql()) Table::new(rows).with(Style::psql()).clone()
} }
pub fn table_path_display(path: &Path) -> String { pub fn table_path_display(path: &Path) -> String {

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />

View File

@@ -13,31 +13,31 @@
"fix": "eslint --fix --ext .js,.vue,.ts,.jsx,.tsx,.html,.vue . && prettier --write ." "fix": "eslint --fix --ext .js,.vue,.ts,.jsx,.tsx,.html,.vue . && prettier --write ."
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "^1.3.0", "@tauri-apps/api": "^1.5.3",
"dayjs": "^1.11.7", "dayjs": "^1.11.10",
"floating-vue": "^2.0.0-beta.20", "floating-vue": "^5.2.2",
"mixpanel-browser": "^2.47.0", "mixpanel-browser": "^2.49.0",
"ofetch": "^1.0.1", "ofetch": "^1.3.4",
"omorphia": "^0.4.38", "omorphia": "^0.4.41",
"pinia": "^2.1.3", "pinia": "^2.1.7",
"qrcode.vue": "^3.4.0", "qrcode.vue": "^3.4.1",
"tauri-plugin-window-state-api": "github:tauri-apps/tauri-plugin-window-state#v1", "tauri-plugin-window-state-api": "github:tauri-apps/tauri-plugin-window-state#v1",
"vite-svg-loader": "^4.0.0", "vite-svg-loader": "^5.1.0",
"vue": "^3.3.4", "vue": "^3.4.21",
"vue-multiselect": "^3.0.0-beta.2", "vue-multiselect": "3.0.0-beta.3",
"vue-router": "4.2.1", "vue-router": "4.3.0",
"vue-virtual-scroller": "2.0.0-beta.8" "vue-virtual-scroller": "2.0.0-beta.8"
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-alias": "^4.0.4", "@rollup/plugin-alias": "^5.1.0",
"@tauri-apps/cli": "^1.3.1", "@tauri-apps/cli": "^1.5.11",
"@vitejs/plugin-vue": "^4.2.3", "@vitejs/plugin-vue": "^5.0.4",
"eslint": "^8.41.0", "eslint": "^8.57.0",
"eslint-config-prettier": "^8.8.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-vue": "^9.14.1", "eslint-plugin-vue": "^9.24.0",
"prettier": "^2.8.8", "prettier": "^3.2.5",
"sass": "^1.62.1", "sass": "^1.74.1",
"vite": "^4.3.9", "vite": "^5.2.8",
"vite-plugin-eslint": "^1.8.1" "vite-plugin-eslint": "^1.8.1"
}, },
"packageManager": "pnpm@8.6.0" "packageManager": "pnpm@8.6.0"

File diff suppressed because it is too large Load Diff

View File

@@ -19,10 +19,10 @@ 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"] }
tauri = { version = "1.3", features = ["app-all", "devtools", "dialog", "dialog-confirm", "dialog-open", "macos-private-api", "os-all", "protocol-asset", "shell-open", "updater", "window-close", "window-create", "window-hide", "window-maximize", "window-minimize", "window-set-decorations", "window-show", "window-start-dragging", "window-unmaximize", "window-unminimize"] } tauri = { version = "1.6", features = ["app-all", "devtools", "dialog", "dialog-confirm", "dialog-open", "macos-private-api", "os-all", "protocol-asset", "shell-open", "updater", "window-close", "window-create", "window-hide", "window-maximize", "window-minimize", "window-set-decorations", "window-show", "window-start-dragging", "window-unmaximize", "window-unminimize"] }
tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
tauri-plugin-deep-link = "0.1.1" tauri-plugin-deep-link = "0.1.2"
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
thiserror = "1.0" thiserror = "1.0"
@@ -38,10 +38,10 @@ uuid = { version = "1.1", features = ["serde", "v4"] }
os_info = "3.7.0" os_info = "3.7.0"
tracing = "0.1.37" tracing = "0.1.37"
tracing-error = "0.1" tracing-error = "0.2.0"
sentry = "0.30" sentry = "0.32.2"
sentry-rust-minidump = "0.5" sentry-rust-minidump = "0.7.0"
lazy_static = "1" lazy_static = "1"
once_cell = "1" once_cell = "1"
@@ -50,7 +50,7 @@ once_cell = "1"
window-shadows = "0.2.1" window-shadows = "0.2.1"
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.24.1" cocoa = "0.25.0"
objc = "0.2.7" objc = "0.2.7"
[features] [features]

View File

@@ -107,7 +107,7 @@ defineExpose({
title: 'Warning', title: 'Warning',
text: e.message, text: e.message,
type: 'warn', type: 'warn',
}) }),
) )
if (showOnboarding.value) { if (showOnboarding.value) {
@@ -127,7 +127,7 @@ const confirmClose = async () => {
{ {
title: 'Modrinth', title: 'Modrinth',
type: 'warning', type: 'warning',
} },
) )
return confirmed return confirmed
} }

View File

@@ -45,7 +45,7 @@ const confirmModal = ref(null)
async function deleteProfile() { async function deleteProfile() {
if (currentDeleteInstance.value) { if (currentDeleteInstance.value) {
instanceComponents.value = instanceComponents.value.filter( instanceComponents.value = instanceComponents.value.filter(
(x) => x.instance.path !== currentDeleteInstance.value (x) => x.instance.path !== currentDeleteInstance.value,
) )
await remove(currentDeleteInstance.value).catch(handleError) await remove(currentDeleteInstance.value).catch(handleError)
} }
@@ -88,7 +88,7 @@ const handleRightClick = (event, profilePathId) => {
color: 'primary', color: 'primary',
}, },
...baseOptions, ...baseOptions,
] ],
) )
} }

View File

@@ -50,7 +50,7 @@ const props = defineProps({
}) })
const actualInstances = computed(() => const actualInstances = computed(() =>
props.instances.filter((x) => x && x.instances && x.instances[0]) props.instances.filter((x) => x && x.instances && x.instances[0]),
) )
const modsRow = ref(null) const modsRow = ref(null)
@@ -171,7 +171,7 @@ const handleOptionsClick = async (args) => {
case 'install': { case 'install': {
const versions = await useFetch( const versions = await useFetch(
`https://api.modrinth.com/v2/project/${args.item.project_id}/version`, `https://api.modrinth.com/v2/project/${args.item.project_id}/version`,
'project versions' 'project versions',
) )
if (args.item.project_type === 'modpack') { if (args.item.project_type === 'modpack') {
@@ -179,7 +179,7 @@ const handleOptionsClick = async (args) => {
args.item.project_id, args.item.project_id,
versions[0].id, versions[0].id,
args.item.title, args.item.title,
args.item.icon_url args.item.icon_url,
) )
} else { } else {
modInstallModal.value.show(args.item.project_id, versions) modInstallModal.value.show(args.item.project_id, versions)
@@ -197,7 +197,7 @@ const handleOptionsClick = async (args) => {
break break
case 'copy_link': case 'copy_link':
await navigator.clipboard.writeText( await navigator.clipboard.writeText(
`https://modrinth.com/${args.item.project_type}/${args.item.slug}` `https://modrinth.com/${args.item.project_type}/${args.item.slug}`,
) )
break break
} }

View File

@@ -66,7 +66,7 @@ export default defineComponent({
zIndex: 6, zIndex: 6,
}, },
}, },
slots slots,
) )
}, },
}) })

View File

@@ -147,11 +147,11 @@ defineExpose({
await refreshValues() await refreshValues()
const displayAccounts = computed(() => const displayAccounts = computed(() =>
accounts.value.filter((account) => settings.value.default_user !== account.id) accounts.value.filter((account) => settings.value.default_user !== account.id),
) )
const selectedAccount = computed(() => const selectedAccount = computed(() =>
accounts.value.find((account) => account.id === settings.value.default_user) accounts.value.find((account) => account.id === settings.value.default_user),
) )
async function setAccount(account) { async function setAccount(account) {

View File

@@ -44,8 +44,8 @@ const breadcrumbs = computed(() => {
route.meta.useContext === true route.meta.useContext === true
? breadcrumbData.context ? breadcrumbData.context
: route.meta.useRootContext === true : route.meta.useRootContext === true
? breadcrumbData.rootContext ? breadcrumbData.rootContext
: null : null
return additionalContext ? [additionalContext, ...route.meta.breadcrumb] : route.meta.breadcrumb return additionalContext ? [additionalContext, ...route.meta.breadcrumb] : route.meta.breadcrumb
}) })
</script> </script>

View File

@@ -63,7 +63,7 @@ const initFiles = async () => {
} else { } else {
files.value.push(pathData) files.value.push(pathData)
} }
}) }),
) )
folders.value = [...newFolders.entries()].map(([name, value]) => [ folders.value = [...newFolders.entries()].map(([name, value]) => [
{ {
@@ -97,7 +97,7 @@ const exportPack = async () => {
filesToExport, filesToExport,
versionInput.value, versionInput.value,
exportDescription.value, exportDescription.value,
nameInput.value nameInput.value,
).catch((err) => handleError(err)) ).catch((err) => handleError(err))
exportModal.value.hide() exportModal.value.hide()
} }

View File

@@ -82,7 +82,7 @@ defineExpose({
selectedVersions, selectedVersions,
extMarkInstalled, extMarkInstalled,
projectIdVal, projectIdVal,
projectTypeVal projectTypeVal,
) => { ) => {
instance.value = instanceVal instance.value = instanceVal
projectTitle.value = projectTitleVal projectTitle.value = projectTitleVal

View File

@@ -36,7 +36,7 @@ async function install() {
projectId.value, projectId.value,
version.value, version.value,
title.value, title.value,
icon.value ? icon.value : null icon.value ? icon.value : null,
).catch(handleError) ).catch(handleError)
mixpanel_track('PackInstall', { mixpanel_track('PackInstall', {
id: projectId.value, id: projectId.value,

View File

@@ -33,7 +33,7 @@ const playing = ref(false)
const uuid = ref(null) const uuid = ref(null)
const modLoading = ref( const modLoading = ref(
props.instance.install_stage ? props.instance.install_stage !== 'installed' : false props.instance.install_stage ? props.instance.install_stage !== 'installed' : false,
) )
watch( watch(
@@ -42,7 +42,7 @@ watch(
modLoading.value = props.instance.install_stage modLoading.value = props.instance.install_stage
? props.instance.install_stage !== 'installed' ? props.instance.install_stage !== 'installed'
: false : false
} },
) )
const router = useRouter() const router = useRouter()
@@ -72,7 +72,7 @@ const install = async (e) => {
modLoading.value = true modLoading.value = true
const versions = await useFetch( const versions = await useFetch(
`https://api.modrinth.com/v2/project/${props.instance.project_id}/version`, `https://api.modrinth.com/v2/project/${props.instance.project_id}/version`,
'project versions' 'project versions',
) )
if (props.instance.project_type === 'modpack') { if (props.instance.project_type === 'modpack') {
@@ -89,7 +89,7 @@ const install = async (e) => {
props.instance.project_id, props.instance.project_id,
versions[0].id, versions[0].id,
props.instance.title, props.instance.title,
props.instance.icon_url props.instance.icon_url,
).catch(handleError) ).catch(handleError)
modLoading.value = false modLoading.value = false
@@ -104,14 +104,14 @@ const install = async (e) => {
props.instance.project_id, props.instance.project_id,
versions[0].id, versions[0].id,
props.instance.title, props.instance.title,
props.instance.icon_url props.instance.icon_url,
) )
} else { } else {
modInstallModal.value.show( modInstallModal.value.show(
props.instance.project_id, props.instance.project_id,
versions, versions,
props.instance.title, props.instance.title,
props.instance.project_type props.instance.project_type,
) )
} }
@@ -267,7 +267,10 @@ onUnmounted(() => unlisten())
right: calc(var(--gap-md) * 2); right: calc(var(--gap-md) * 2);
bottom: 3.25rem; bottom: 3.25rem;
opacity: 0; opacity: 0;
transition: 0.2s ease-in-out bottom, 0.2s ease-in-out opacity, 0.1s ease-in-out filter !important; transition:
0.2s ease-in-out bottom,
0.2s ease-in-out opacity,
0.1s ease-in-out filter !important;
cursor: pointer; cursor: pointer;
box-shadow: var(--shadow-floating); box-shadow: var(--shadow-floating);

View File

@@ -177,14 +177,14 @@
loading loading
? 'Importing...' ? 'Importing...'
: Array.from(profiles.values()) : Array.from(profiles.values())
.flatMap((e) => e)
.some((e) => e.selected)
? `Import ${
Array.from(profiles.values())
.flatMap((e) => e) .flatMap((e) => e)
.filter((e) => e.selected).length .some((e) => e.selected)
} profiles` ? `Import ${
: 'Select profiles to import' Array.from(profiles.values())
.flatMap((e) => e)
.filter((e) => e.selected).length
} profiles`
: 'Select profiles to import'
}} }}
</Button> </Button>
<ProgressBar <ProgressBar
@@ -317,7 +317,7 @@ const [
.then((value) => .then((value) =>
value value
.filter((item) => item.supported_project_types.includes('modpack')) .filter((item) => item.supported_project_types.includes('modpack'))
.map((item) => item.name.toLowerCase()) .map((item) => item.name.toLowerCase()),
) )
.then(ref) .then(ref)
.catch(handleError), .catch(handleError),
@@ -367,7 +367,7 @@ const create_instance = async () => {
game_version.value, game_version.value,
loader.value, loader.value,
loader.value === 'vanilla' ? null : loader_version_value ?? 'stable', loader.value === 'vanilla' ? null : loader_version_value ?? 'stable',
icon.value icon.value,
).catch(handleError) ).catch(handleError)
mixpanel_track('InstanceCreate', { mixpanel_track('InstanceCreate', {
@@ -441,7 +441,7 @@ const profiles = ref(
['ATLauncher', []], ['ATLauncher', []],
['Curseforge', []], ['Curseforge', []],
['PrismLauncher', []], ['PrismLauncher', []],
]) ]),
) )
const loading = ref(false) const loading = ref(false)
@@ -470,7 +470,7 @@ const promises = profileOptions.value.map(async (option) => {
profileOptions.value.find((profile) => profile.name === option.name).path = path profileOptions.value.find((profile) => profile.name === option.name).path = path
profiles.value.set( profiles.value.set(
option.name, option.name,
instances.map((name) => ({ name, selected: false })) instances.map((name) => ({ name, selected: false })),
) )
} catch (error) { } catch (error) {
// Allow failure silently // Allow failure silently
@@ -489,12 +489,12 @@ const selectLauncherPath = async () => {
const reload = async () => { const reload = async () => {
const instances = await get_importable_instances( const instances = await get_importable_instances(
selectedProfileType.value.name, selectedProfileType.value.name,
selectedProfileType.value.path selectedProfileType.value.path,
).catch(handleError) ).catch(handleError)
if (instances) { if (instances) {
profiles.value.set( profiles.value.set(
selectedProfileType.value.name, selectedProfileType.value.name,
instances.map((name) => ({ name, selected: false })) instances.map((name) => ({ name, selected: false })),
) )
} else { } else {
profiles.value.set(selectedProfileType.value.name, []) profiles.value.set(selectedProfileType.value.name, [])

View File

@@ -112,7 +112,7 @@ async function testJava() {
testingJavaSuccess.value = await test_jre( testingJavaSuccess.value = await test_jre(
props.modelValue ? props.modelValue.path : '', props.modelValue ? props.modelValue.path : '',
1, 1,
props.version props.version,
) )
testingJava.value = false testingJava.value = false

View File

@@ -112,7 +112,8 @@ async function getData() {
.flatMap((v) => v.loaders) .flatMap((v) => v.loaders)
.some( .some(
(value) => (value) =>
value === profile.metadata.loader || ['minecraft', 'iris', 'optifine'].includes(value) value === profile.metadata.loader ||
['minecraft', 'iris', 'optifine'].includes(value),
) )
) )
}) })
@@ -175,7 +176,7 @@ const createInstance = async () => {
versions.value[0].game_versions[0], versions.value[0].game_versions[0],
loader, loader,
'latest', 'latest',
icon.value icon.value,
).catch(handleError) ).catch(handleError)
await installMod(id, versions.value[0].id).catch(handleError) await installMod(id, versions.value[0].id).catch(handleError)
@@ -264,10 +265,10 @@ const check_valid = computed(() => {
profile.installing profile.installing
? 'Installing...' ? 'Installing...'
: profile.installedMod : profile.installedMod
? 'Installed' ? 'Installed'
: profile.metadata.linked_data && profile.metadata.linked_data.locked : profile.metadata.linked_data && profile.metadata.linked_data.locked
? 'Paired' ? 'Paired'
: 'Install' : 'Install'
}} }}
</Button> </Button>
</div> </div>

View File

@@ -74,7 +74,7 @@ const install = async (e) => {
installing.value = true installing.value = true
const versions = await useFetch( const versions = await useFetch(
`https://api.modrinth.com/v2/project/${props.project.project_id}/version`, `https://api.modrinth.com/v2/project/${props.project.project_id}/version`,
'project versions' 'project versions',
) )
if (props.project.project_type === 'modpack') { if (props.project.project_type === 'modpack') {
@@ -91,7 +91,7 @@ const install = async (e) => {
props.project.project_id, props.project.project_id,
versions[0].id, versions[0].id,
props.project.title, props.project.title,
props.project.icon_url props.project.icon_url,
).catch(handleError) ).catch(handleError)
installing.value = false installing.value = false
} else } else
@@ -99,7 +99,7 @@ const install = async (e) => {
props.project.project_id, props.project.project_id,
versions[0].id, versions[0].id,
props.project.title, props.project.title,
props.project.icon_url props.project.icon_url,
) )
} else { } else {
props.modInstallModal.show(props.project.project_id, versions) props.modInstallModal.show(props.project.project_id, versions)

View File

@@ -196,7 +196,7 @@ const refreshInfo = async () => {
} }
return x return x
} },
) )
if (currentLoadingBars.value.length === 0) { if (currentLoadingBars.value.length === 0) {
showCard.value = false showCard.value = false

View File

@@ -136,7 +136,7 @@ async function install() {
installing.value = true installing.value = true
const versions = await useFetch( const versions = await useFetch(
`https://api.modrinth.com/v2/project/${props.project.project_id}/version`, `https://api.modrinth.com/v2/project/${props.project.project_id}/version`,
'project versions' 'project versions',
) )
let queuedVersionData let queuedVersionData
@@ -146,7 +146,8 @@ async function install() {
queuedVersionData = versions.find( queuedVersionData = versions.find(
(v) => (v) =>
v.game_versions.includes(props.instance.metadata.game_version) && v.game_versions.includes(props.instance.metadata.game_version) &&
(props.project.project_type !== 'mod' || v.loaders.includes(props.instance.metadata.loader)) (props.project.project_type !== 'mod' ||
v.loaders.includes(props.instance.metadata.loader)),
) )
} }
@@ -162,7 +163,7 @@ async function install() {
props.project.project_id, props.project.project_id,
queuedVersionData.id, queuedVersionData.id,
props.project.title, props.project.title,
props.project.icon_url props.project.icon_url,
).catch(handleError) ).catch(handleError)
mixpanel_track('PackInstall', { mixpanel_track('PackInstall', {
@@ -176,7 +177,7 @@ async function install() {
props.project.project_id, props.project.project_id,
queuedVersionData.id, queuedVersionData.id,
props.project.title, props.project.title,
props.project.icon_url props.project.icon_url,
) )
} }
} else { } else {
@@ -188,7 +189,7 @@ async function install() {
versions, versions,
() => (installed.value = true), () => (installed.value = true),
props.project.project_id, props.project.project_id,
props.project.project_type props.project.project_type,
) )
installing.value = false installing.value = false
return return
@@ -211,7 +212,7 @@ async function install() {
props.project.project_id, props.project.project_id,
versions, versions,
props.project.title, props.project.title,
props.project.project_type props.project.project_type,
) )
installing.value = false installing.value = false
return return

View File

@@ -21,28 +21,28 @@ defineExpose({
if (event.event === 'InstallVersion') { if (event.event === 'InstallVersion') {
version.value = await useFetch( version.value = await useFetch(
`https://api.modrinth.com/v2/version/${encodeURIComponent(event.id)}`, `https://api.modrinth.com/v2/version/${encodeURIComponent(event.id)}`,
'version' 'version',
) )
project.value = await useFetch( project.value = await useFetch(
`https://api.modrinth.com/v2/project/${encodeURIComponent(version.value.project_id)}`, `https://api.modrinth.com/v2/project/${encodeURIComponent(version.value.project_id)}`,
'project' 'project',
) )
} else { } else {
project.value = await useFetch( project.value = await useFetch(
`https://api.modrinth.com/v2/project/${encodeURIComponent(event.id)}`, `https://api.modrinth.com/v2/project/${encodeURIComponent(event.id)}`,
'project' 'project',
) )
version.value = await useFetch( version.value = await useFetch(
`https://api.modrinth.com/v2/version/${encodeURIComponent(project.value.versions[0])}`, `https://api.modrinth.com/v2/version/${encodeURIComponent(project.value.versions[0])}`,
'version' 'version',
) )
} }
categories.value = (await get_categories().catch(handleError)).filter( categories.value = (await get_categories().catch(handleError)).filter(
(cat) => project.value.categories.includes(cat.name) && cat.project_type === 'mod' (cat) => project.value.categories.includes(cat.name) && cat.project_type === 'mod',
) )
confirmModal.value.show() confirmModal.value.show()
categories.value = (await get_categories().catch(handleError)).filter( categories.value = (await get_categories().catch(handleError)).filter(
(cat) => project.value.categories.includes(cat.name) && cat.project_type === 'mod' (cat) => project.value.categories.includes(cat.name) && cat.project_type === 'mod',
) )
confirmModal.value.show() confirmModal.value.show()
}, },
@@ -55,7 +55,7 @@ async function install() {
project.value.id, project.value.id,
version.value.id, version.value.id,
project.value.title, project.value.title,
project.value.icon_url project.value.icon_url,
).catch(handleError) ).catch(handleError)
mixpanel.track('PackInstall', { mixpanel.track('PackInstall', {
@@ -69,7 +69,7 @@ async function install() {
project.value.id, project.value.id,
[version.value], [version.value],
project.value.title, project.value.title,
project.value.project_type project.value.project_type,
) )
} }
} }

View File

@@ -100,7 +100,7 @@ defineProps({
v-for="loader in loaders.filter( v-for="loader in loaders.filter(
(l) => (l) =>
(projectType !== 'mod' && l.supported_project_types?.includes(projectType)) || (projectType !== 'mod' && l.supported_project_types?.includes(projectType)) ||
(projectType === 'mod' && ['fabric', 'forge', 'quilt'].includes(l.name)) (projectType === 'mod' && ['fabric', 'forge', 'quilt'].includes(l.name)),
)" )"
:key="loader" :key="loader"
> >

View File

@@ -36,7 +36,7 @@ const profiles = ref(
['ATLauncher', []], ['ATLauncher', []],
['Curseforge', []], ['Curseforge', []],
['PrismLauncher', []], ['PrismLauncher', []],
]) ]),
) )
const loading = ref(false) const loading = ref(false)
@@ -63,7 +63,7 @@ const promises = profileOptions.value.map(async (option) => {
profileOptions.value.find((profile) => profile.name === option.name).path = path profileOptions.value.find((profile) => profile.name === option.name).path = path
profiles.value.set( profiles.value.set(
option.name, option.name,
instances.map((name) => ({ name, selected: false })) instances.map((name) => ({ name, selected: false })),
) )
} catch (error) { } catch (error) {
// Allow failure silently // Allow failure silently
@@ -82,11 +82,11 @@ const selectLauncherPath = async () => {
const reload = async () => { const reload = async () => {
const instances = await get_importable_instances( const instances = await get_importable_instances(
selectedProfileType.value.name, selectedProfileType.value.name,
selectedProfileType.value.path selectedProfileType.value.path,
).catch(handleError) ).catch(handleError)
profiles.value.set( profiles.value.set(
selectedProfileType.value.name, selectedProfileType.value.name,
instances.map((name) => ({ name, selected: false })) instances.map((name) => ({ name, selected: false })),
) )
} }
@@ -198,14 +198,14 @@ const next = async () => {
loading loading
? 'Importing...' ? 'Importing...'
: Array.from(profiles.values()) : Array.from(profiles.values())
.flatMap((e) => e)
.some((e) => e.selected)
? `Import ${
Array.from(profiles.values())
.flatMap((e) => e) .flatMap((e) => e)
.filter((e) => e.selected).length .some((e) => e.selected)
} profiles` ? `Import ${
: 'Select profiles to import' Array.from(profiles.values())
.flatMap((e) => e)
.filter((e) => e.selected).length
} profiles`
: 'Select profiles to import'
}} }}
</Button> </Button>
<Button class="transparent" @click="nextPage"> Next </Button> <Button class="transparent" @click="nextPage"> Next </Button>

View File

@@ -75,7 +75,7 @@ async function signIn() {
const creds = await login_pass( const creds = await login_pass(
username.value, username.value,
password.value, password.value,
window.turnstile.getResponse() window.turnstile.getResponse(),
).catch(handleError) ).catch(handleError)
window.turnstile.reset() window.turnstile.reset()
@@ -102,7 +102,7 @@ async function createAccount() {
email.value, email.value,
password.value, password.value,
window.turnstile.getResponse(), window.turnstile.getResponse(),
subscribe.value subscribe.value,
).catch(handleError) ).catch(handleError)
window.turnstile.reset() window.turnstile.reset()

View File

@@ -489,7 +489,8 @@ onMounted(async () => {
} }
.onboarding { .onboarding {
background: top linear-gradient(0deg, #31375f, rgba(8, 14, 55, 0)), background:
top linear-gradient(0deg, #31375f, rgba(8, 14, 55, 0)),
url(https://cdn.modrinth.com/landing-new/landing-lower.webp); url(https://cdn.modrinth.com/landing-new/landing-lower.webp);
background-size: cover; background-size: cover;
height: 100vh; height: 100vh;

View File

@@ -23,7 +23,7 @@ function optOutTrackingWrapper(originalOptOutTracking) {
} }
} }
export const mixpanel_opt_out_tracking = optOutTrackingWrapper( export const mixpanel_opt_out_tracking = optOutTrackingWrapper(
mixpanel.opt_out_tracking.bind(mixpanel) mixpanel.opt_out_tracking.bind(mixpanel),
) )
// mixpanel_opt_in_tracking() // mixpanel_opt_in_tracking()
@@ -37,7 +37,7 @@ function optInTrackingWrapper(originalOptInTracking) {
} }
} }
export const mixpanel_opt_in_tracking = optInTrackingWrapper( export const mixpanel_opt_in_tracking = optInTrackingWrapper(
mixpanel.opt_in_tracking.bind(mixpanel) mixpanel.opt_in_tracking.bind(mixpanel),
) )
// mixpanel_init // mixpanel_init

View File

@@ -21,7 +21,7 @@ export async function install(projectId, versionId, packTitle, iconUrl) {
profile_creator.gameVersion, profile_creator.gameVersion,
profile_creator.modloader, profile_creator.modloader,
profile_creator.loaderVersion, profile_creator.loaderVersion,
profile_creator.icon profile_creator.icon,
) )
return await invoke('plugin:pack|pack_install', { location, profile }) return await invoke('plugin:pack|pack_install', { location, profile })
@@ -39,7 +39,7 @@ export async function install_from_file(path) {
profile_creator.gameVersion, profile_creator.gameVersion,
profile_creator.modloader, profile_creator.modloader,
profile_creator.loaderVersion, profile_creator.loaderVersion,
profile_creator.icon profile_creator.icon,
) )
return await invoke('plugin:pack|pack_install', { location, profile }) return await invoke('plugin:pack|pack_install', { location, profile })
} }

View File

@@ -133,7 +133,7 @@ export async function export_profile_mrpack(
includedOverrides, includedOverrides,
versionId, versionId,
description, description,
name name,
) { ) {
return await invoke('plugin:profile|profile_export_mrpack', { return await invoke('plugin:profile|profile_export_mrpack', {
path, path,

View File

@@ -69,12 +69,12 @@ export const installVersionDependencies = async (profile, version) => {
continue continue
const depVersions = await useFetch( const depVersions = await useFetch(
`https://api.modrinth.com/v2/project/${dep.project_id}/version`, `https://api.modrinth.com/v2/project/${dep.project_id}/version`,
'dependency versions' 'dependency versions',
) )
const latest = depVersions.find( const latest = depVersions.find(
(v) => (v) =>
v.game_versions.includes(profile.metadata.game_version) && v.game_versions.includes(profile.metadata.game_version) &&
v.loaders.includes(profile.metadata.loader) v.loaders.includes(profile.metadata.loader),
) )
if (latest) { if (latest) {
await installMod(profile.path, latest.id).catch(handleError) await installMod(profile.path, latest.id).catch(handleError)

View File

@@ -75,7 +75,7 @@ const ignoreInstanceGameVersions = ref(false)
const results = shallowRef([]) const results = shallowRef([])
const pageCount = computed(() => const pageCount = computed(() =>
results.value ? Math.ceil(results.value.total_hits / results.value.limit) : 1 results.value ? Math.ceil(results.value.total_hits / results.value.limit) : 1,
) )
function getArrayOrString(x) { function getArrayOrString(x) {
@@ -179,7 +179,9 @@ async function refreshSearch() {
formattedFacets.push(orFacets.value) formattedFacets.push(orFacets.value)
} else if (projectType.value === 'mod') { } else if (projectType.value === 'mod') {
formattedFacets.push( formattedFacets.push(
['forge', 'fabric', 'quilt', 'neoforge'].map((x) => `categories:'${encodeURIComponent(x)}'`) ['forge', 'fabric', 'quilt', 'neoforge'].map(
(x) => `categories:'${encodeURIComponent(x)}'`,
),
) )
} else if (projectType.value === 'datapack') { } else if (projectType.value === 'datapack') {
formattedFacets.push(['datapack'].map((x) => `categories:'${encodeURIComponent(x)}'`)) formattedFacets.push(['datapack'].map((x) => `categories:'${encodeURIComponent(x)}'`))
@@ -230,7 +232,7 @@ async function refreshSearch() {
const installedMods = await get(instanceContext.value.path, false).then((x) => const installedMods = await get(instanceContext.value.path, false).then((x) =>
Object.values(x.projects) Object.values(x.projects)
.filter((x) => x.metadata.project) .filter((x) => x.metadata.project)
.map((x) => x.metadata.project.id) .map((x) => x.metadata.project.id),
) )
installedMods.map((x) => [`project_id != ${x}`]).forEach((x) => formattedFacets.push(x)) installedMods.map((x) => [`project_id != ${x}`]).forEach((x) => formattedFacets.push(x))
console.log(`facets=${JSON.stringify(formattedFacets)}`) console.log(`facets=${JSON.stringify(formattedFacets)}`)
@@ -262,7 +264,7 @@ async function refreshSearch() {
if (instanceContext.value) { if (instanceContext.value) {
for (val of rawResults.hits) { for (val of rawResults.hits) {
val.installed = await check_installed(instanceContext.value.path, val.project_id).then( val.installed = await check_installed(instanceContext.value.path, val.project_id).then(
(x) => (val.installed = x) (x) => (val.installed = x),
) )
} }
} }
@@ -374,7 +376,7 @@ function getSearchUrl(offset, useObj) {
const sortedCategories = computed(() => { const sortedCategories = computed(() => {
const values = new Map() const values = new Map()
for (const category of categories.value.filter( for (const category of categories.value.filter(
(cat) => cat.project_type === (projectType.value === 'datapack' ? 'mod' : projectType.value) (cat) => cat.project_type === (projectType.value === 'datapack' ? 'mod' : projectType.value),
)) { )) {
if (!values.has(category.header)) { if (!values.has(category.header)) {
values.set(category.header, []) values.set(category.header, [])
@@ -478,7 +480,7 @@ watch(
loading.value = true loading.value = true
await clearFilters() await clearFilters()
loading.value = false loading.value = false
} },
) )
const [categories, loaders, availableGameVersions] = await Promise.all([ const [categories, loaders, availableGameVersions] = await Promise.all([
@@ -500,7 +502,7 @@ const selectableProjectTypes = computed(() => {
if (instanceContext.value) { if (instanceContext.value) {
if ( if (
availableGameVersions.value.findIndex( availableGameVersions.value.findIndex(
(x) => x.version === instanceContext.value.metadata.game_version (x) => x.version === instanceContext.value.metadata.game_version,
) <= availableGameVersions.value.findIndex((x) => x.version === '1.13') ) <= availableGameVersions.value.findIndex((x) => x.version === '1.13')
) { ) {
values.unshift({ label: 'Data Packs', href: `/browse/datapack` }) values.unshift({ label: 'Data Packs', href: `/browse/datapack` })
@@ -519,7 +521,7 @@ const selectableProjectTypes = computed(() => {
}) })
const showVersions = computed( const showVersions = computed(
() => instanceContext.value === null || ignoreInstanceGameVersions.value () => instanceContext.value === null || ignoreInstanceGameVersions.value,
) )
const showLoaders = computed( const showLoaders = computed(
() => () =>
@@ -527,7 +529,7 @@ const showLoaders = computed(
projectType.value !== 'resourcepack' && projectType.value !== 'resourcepack' &&
projectType.value !== 'shader' && projectType.value !== 'shader' &&
instanceContext.value === null) || instanceContext.value === null) ||
ignoreInstanceLoaders.value ignoreInstanceLoaders.value,
) )
onUnmounted(() => unlistenOffline()) onUnmounted(() => unlistenOffline())
@@ -605,7 +607,8 @@ onUnmounted(() => unlistenOffline())
v-for="loader in loaders.filter( v-for="loader in loaders.filter(
(l) => (l) =>
(projectType !== 'mod' && l.supported_project_types?.includes(projectType)) || (projectType !== 'mod' && l.supported_project_types?.includes(projectType)) ||
(projectType === 'mod' && ['fabric', 'forge', 'quilt', 'neoforge'].includes(l.name)) (projectType === 'mod' &&
['fabric', 'forge', 'quilt', 'neoforge'].includes(l.name)),
)" )"
:key="loader" :key="loader"
> >
@@ -752,12 +755,12 @@ onUnmounted(() => unlistenOffline())
:categories="[ :categories="[
...categories.filter( ...categories.filter(
(cat) => (cat) =>
result?.display_categories.includes(cat.name) && cat.project_type === projectType result?.display_categories.includes(cat.name) && cat.project_type === projectType,
), ),
...loaders.filter( ...loaders.filter(
(loader) => (loader) =>
result?.display_categories.includes(loader.name) && result?.display_categories.includes(loader.name) &&
loader.supported_project_types?.includes(projectType) loader.supported_project_types?.includes(projectType),
), ),
]" ]"
:confirm-modal="confirmModal" :confirm-modal="confirmModal"

View File

@@ -42,7 +42,7 @@ const getFeaturedModpacks = async () => {
const response = await useFetch( const response = await useFetch(
`https://api.modrinth.com/v2/search?facets=[["project_type:modpack"]]&limit=10&index=follows&filters=${filter.value}`, `https://api.modrinth.com/v2/search?facets=[["project_type:modpack"]]&limit=10&index=follows&filters=${filter.value}`,
'featured modpacks', 'featured modpacks',
offline.value offline.value,
) )
if (response) { if (response) {
featuredModpacks.value = response.hits featuredModpacks.value = response.hits
@@ -54,7 +54,7 @@ const getFeaturedMods = async () => {
const response = await useFetch( const response = await useFetch(
'https://api.modrinth.com/v2/search?facets=[["project_type:mod"]]&limit=10&index=follows', 'https://api.modrinth.com/v2/search?facets=[["project_type:mod"]]&limit=10&index=follows',
'featured mods', 'featured mods',
offline.value offline.value,
) )
if (response) { if (response) {
featuredMods.value = response.hits featuredMods.value = response.hits

View File

@@ -73,13 +73,13 @@ watch(
if (setSettings.java_globals.JAVA_8?.path) { if (setSettings.java_globals.JAVA_8?.path) {
setSettings.java_globals.JAVA_8.path = setSettings.java_globals.JAVA_8.path.replace( setSettings.java_globals.JAVA_8.path = setSettings.java_globals.JAVA_8.path.replace(
'java.exe', 'java.exe',
'javaw.exe' 'javaw.exe',
) )
} }
if (setSettings.java_globals.JAVA_17?.path) { if (setSettings.java_globals.JAVA_17?.path) {
setSettings.java_globals.JAVA_17.path = setSettings.java_globals.JAVA_17?.path.replace( setSettings.java_globals.JAVA_17.path = setSettings.java_globals.JAVA_17?.path.replace(
'java.exe', 'java.exe',
'javaw.exe' 'javaw.exe',
) )
} }
@@ -102,7 +102,7 @@ watch(
await set(setSettings) await set(setSettings)
}, },
{ deep: true } { deep: true },
) )
const credentials = ref(await getCreds().catch(handleError)) const credentials = ref(await getCreds().catch(handleError))

View File

@@ -165,7 +165,7 @@ breadcrumbs.setName(
'Instance', 'Instance',
instance.value.metadata.name.length > 40 instance.value.metadata.name.length > 40
? instance.value.metadata.name.substring(0, 40) + '...' ? instance.value.metadata.name.substring(0, 40) + '...'
: instance.value.metadata.name : instance.value.metadata.name,
) )
breadcrumbs.setContext({ breadcrumbs.setContext({
@@ -212,7 +212,7 @@ const modrinthVersions = ref([])
if (!(await isOffline()) && instance.value.metadata.linked_data?.project_id) { if (!(await isOffline()) && instance.value.metadata.linked_data?.project_id) {
modrinthVersions.value = await useFetch( modrinthVersions.value = await useFetch(
`https://api.modrinth.com/v2/project/${instance.value.metadata.linked_data.project_id}/version`, `https://api.modrinth.com/v2/project/${instance.value.metadata.linked_data.project_id}/version`,
'project' 'project',
) )
} }
@@ -259,7 +259,7 @@ const handleRightClick = (event) => {
color: 'primary', color: 'primary',
}, },
...baseOptions, ...baseOptions,
] ],
) )
} }

View File

@@ -225,7 +225,7 @@ async function getLiveStdLog() {
} else { } else {
const logCursor = await get_latest_log_cursor( const logCursor = await get_latest_log_cursor(
props.instance.path, props.instance.path,
currentLiveLogCursor.value currentLiveLogCursor.value,
).catch(handleError) ).catch(handleError)
if (logCursor.new_file) { if (logCursor.new_file) {
currentLiveLog.value = '' currentLiveLog.value = ''
@@ -248,7 +248,7 @@ async function getLogs() {
log.filename !== 'latest_stdout.log' && log.filename !== 'latest_stdout.log' &&
log.filename !== 'latest_stdout' && log.filename !== 'latest_stdout' &&
log.stdout !== '' && log.stdout !== '' &&
log.filename.includes('.log') log.filename.includes('.log'),
) )
.map((log) => { .map((log) => {
log.name = log.filename || 'Unknown' log.name = log.filename || 'Unknown'
@@ -291,7 +291,7 @@ watch(selectedLogIndex, async (newIndex) => {
logs.value[newIndex].stdout = 'Loading...' logs.value[newIndex].stdout = 'Loading...'
logs.value[newIndex].stdout = await get_output_by_filename( logs.value[newIndex].stdout = await get_output_by_filename(
props.instance.path, props.instance.path,
logs.value[newIndex].filename logs.value[newIndex].filename,
).catch(handleError) ).catch(handleError)
} }
}) })
@@ -307,7 +307,7 @@ const deleteLog = async () => {
let deleteIndex = selectedLogIndex.value let deleteIndex = selectedLogIndex.value
selectedLogIndex.value = deleteIndex - 1 selectedLogIndex.value = deleteIndex - 1
await delete_logs_by_filename(props.instance.path, logs.value[deleteIndex].filename).catch( await delete_logs_by_filename(props.instance.path, logs.value[deleteIndex].filename).catch(
handleError handleError,
) )
await setLogs() await setLogs()
} }

View File

@@ -505,7 +505,7 @@ const initProjects = (initInstance) => {
selectionMap.value.get(project.path) ?? selectionMap.value.get(project.path) ??
selectionMap.value.get(project.path.slice(0, -9)) ?? selectionMap.value.get(project.path.slice(0, -9)) ??
selectionMap.value.get(project.path + '.disabled') ?? selectionMap.value.get(project.path + '.disabled') ??
false false,
) )
} }
selectionMap.value = newSelectionMap selectionMap.value = newSelectionMap
@@ -517,14 +517,14 @@ watch(
() => props.instance.projects, () => props.instance.projects,
() => { () => {
initProjects(props.instance) initProjects(props.instance)
} },
) )
watch( watch(
() => props.offline, () => props.offline,
() => { () => {
if (props.instance) initProjects(props.instance) if (props.instance) initProjects(props.instance)
} },
) )
const modpackVersionModal = ref(null) const modpackVersionModal = ref(null)
@@ -551,11 +551,11 @@ const selected = computed(() =>
}) })
.map((args) => { .map((args) => {
return projects.value.find((x) => x.path === args[0]) return projects.value.find((x) => x.path === args[0])
}) }),
) )
const functionValues = computed(() => const functionValues = computed(() =>
selected.value.length > 0 ? selected.value : Array.from(projects.value.values()) selected.value.length > 0 ? selected.value : Array.from(projects.value.values()),
) )
const selectableProjectTypes = computed(() => { const selectableProjectTypes = computed(() => {
@@ -781,7 +781,7 @@ const shareUrls = async () => {
functionValues.value functionValues.value
.filter((x) => x.slug) .filter((x) => x.slug)
.map((x) => `https://modrinth.com/${x.project_type}/${x.slug}`) .map((x) => `https://modrinth.com/${x.project_type}/${x.slug}`)
.join('\n') .join('\n'),
) )
} }
@@ -794,7 +794,7 @@ const shareMarkdown = async () => {
} }
return x.name return x.name
}) })
.join('\n') .join('\n'),
) )
} }
@@ -839,7 +839,7 @@ const handleRightClick = (event, mod) => {
{ {
link: `https://modrinth.com/${mod.project_type}/${mod.slug}`, link: `https://modrinth.com/${mod.project_type}/${mod.slug}`,
}, },
[{ name: 'open_link' }, { name: 'copy_link' }] [{ name: 'open_link' }, { name: 'copy_link' }],
) )
} }
} }

View File

@@ -596,7 +596,7 @@ const availableGroups = ref([
...new Set( ...new Set(
instancesList.reduce((acc, obj) => { instancesList.reduce((acc, obj) => {
return acc.concat(obj.metadata.groups) return acc.concat(obj.metadata.groups)
}, []) }, []),
), ),
]) ])
@@ -641,7 +641,9 @@ const javaArgs = ref((javaSettings.extra_arguments ?? globalSettings.custom_java
const overrideEnvVars = ref(!!javaSettings.custom_env_args) const overrideEnvVars = ref(!!javaSettings.custom_env_args)
const envVars = ref( const envVars = ref(
(javaSettings.custom_env_args ?? globalSettings.custom_env_args).map((x) => x.join('=')).join(' ') (javaSettings.custom_env_args ?? globalSettings.custom_env_args)
.map((x) => x.join('='))
.join(' '),
) )
const overrideMemorySettings = ref(!!props.instance.memory) const overrideMemorySettings = ref(!!props.instance.memory)
@@ -688,7 +690,7 @@ watch(
async () => { async () => {
await edit(props.instance.path, editProfileObject.value) await edit(props.instance.path, editProfileObject.value)
}, },
{ deep: true } { deep: true },
) )
const getLocalVersion = (path) => { const getLocalVersion = (path) => {
@@ -716,7 +718,7 @@ const editProfileObject = computed(() => {
editProfile.java.override_version = javaInstall.value editProfile.java.override_version = javaInstall.value
editProfile.java.override_version.path = editProfile.java.override_version.path.replace( editProfile.java.override_version.path = editProfile.java.override_version.path.replace(
'java.exe', 'java.exe',
'javaw.exe' 'javaw.exe',
) )
} }
} }
@@ -848,7 +850,7 @@ const [
.then((value) => .then((value) =>
value value
.filter((item) => item.supported_project_types.includes('modpack')) .filter((item) => item.supported_project_types.includes('modpack'))
.map((item) => item.name.toLowerCase()) .map((item) => item.name.toLowerCase()),
) )
.then(ref) .then(ref)
.catch(handleError), .catch(handleError),
@@ -893,8 +895,8 @@ const selectableLoaderVersions = computed(() => {
}) })
const loaderVersionIndex = ref( const loaderVersionIndex = ref(
selectableLoaderVersions.value.findIndex( selectableLoaderVersions.value.findIndex(
(x) => x.id === props.instance.metadata.loader_version?.id (x) => x.id === props.instance.metadata.loader_version?.id,
) ),
) )
const isValid = computed(() => { const isValid = computed(() => {

View File

@@ -276,7 +276,9 @@ const expandImage = (item, index) => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
max-width: 40rem; max-width: 40rem;
transition: opacity 0.25s ease-in-out, transform 0.25s ease-in-out; transition:
opacity 0.25s ease-in-out,
transform 0.25s ease-in-out;
text-shadow: 1px 1px 10px #000000d4; text-shadow: 1px 1px 10px #000000d4;
margin-bottom: 0.25rem; margin-bottom: 0.25rem;
gap: 0.5rem; gap: 0.5rem;
@@ -297,7 +299,9 @@ const expandImage = (item, index) => {
background-color: var(--color-raised-bg); background-color: var(--color-raised-bg);
padding: var(--gap-md); padding: var(--gap-md);
border-radius: var(--radius-md); border-radius: var(--radius-md);
transition: opacity 0.25s ease-in-out, transform 0.25s ease-in-out; transition:
opacity 0.25s ease-in-out,
transform 0.25s ease-in-out;
} }
} }
} }

View File

@@ -38,7 +38,7 @@
class="tags" class="tags"
:categories=" :categories="
categories.filter( categories.filter(
(cat) => data.categories.includes(cat.name) && cat.project_type === 'mod' (cat) => data.categories.includes(cat.name) && cat.project_type === 'mod',
) )
" "
type="ignored" type="ignored"
@@ -328,7 +328,7 @@ async function fetchProjectData() {
breadcrumbs.setName('Project', data.value.title) breadcrumbs.setName('Project', data.value.title)
installedVersion.value = instance.value installedVersion.value = instance.value
? Object.values(instance.value.projects).find( ? Object.values(instance.value.projects).find(
(p) => p?.metadata?.version?.project_id === data.value.id (p) => p?.metadata?.version?.project_id === data.value.id,
)?.metadata?.version?.id )?.metadata?.version?.id
: null : null
} }
@@ -341,7 +341,7 @@ watch(
if (route.params.id && route.path.startsWith('/project')) { if (route.params.id && route.path.startsWith('/project')) {
await fetchProjectData() await fetchProjectData()
} }
} },
) )
dayjs.extend(relativeTime) dayjs.extend(relativeTime)
@@ -380,7 +380,7 @@ async function install(version) {
queuedVersionData = versions.value[0] queuedVersionData = versions.value[0]
} else { } else {
queuedVersionData = versions.value.find((v) => queuedVersionData = versions.value.find((v) =>
v.game_versions.includes(data.value.game_versions[0]) v.game_versions.includes(data.value.game_versions[0]),
) )
} }
} }
@@ -397,7 +397,7 @@ async function install(version) {
data.value.id, data.value.id,
queuedVersionData.id, queuedVersionData.id,
data.value.title, data.value.title,
data.value.icon_url data.value.icon_url,
).catch(handleError) ).catch(handleError)
mixpanel_track('PackInstall', { mixpanel_track('PackInstall', {
@@ -411,7 +411,7 @@ async function install(version) {
data.value.id, data.value.id,
queuedVersionData.id, queuedVersionData.id,
data.value.title, data.value.title,
data.value.icon_url data.value.icon_url,
) )
} }
} else { } else {
@@ -424,7 +424,7 @@ async function install(version) {
v.game_versions.includes(gameVersion) && v.game_versions.includes(gameVersion) &&
(data.value.project_type === 'mod' (data.value.project_type === 'mod'
? v.loaders.includes(loader) || v.loaders.includes('minecraft') ? v.loaders.includes(loader) || v.loaders.includes('minecraft')
: true) : true),
) )
if (!selectedVersion) { if (!selectedVersion) {
incompatibilityWarning.value.show( incompatibilityWarning.value.show(
@@ -433,7 +433,7 @@ async function install(version) {
versions.value, versions.value,
markInstalled, markInstalled,
data.value.id, data.value.id,
data.value.project_type data.value.project_type,
) )
installing.value = false installing.value = false
return return
@@ -460,7 +460,7 @@ async function install(version) {
v.game_versions.includes(gameVersion) && v.game_versions.includes(gameVersion) &&
(data.value.project_type === 'mod' (data.value.project_type === 'mod'
? v.loaders.includes(loader) || v.loaders.includes('minecraft') ? v.loaders.includes(loader) || v.loaders.includes('minecraft')
: true) : true),
) )
if (compatible) { if (compatible) {
await installMod(instance.value.path, queuedVersionData.id).catch(handleError) await installMod(instance.value.path, queuedVersionData.id).catch(handleError)
@@ -482,7 +482,7 @@ async function install(version) {
[queuedVersionData], [queuedVersionData],
markInstalled, markInstalled,
data.value.id, data.value.id,
data.value.project_type data.value.project_type,
) )
installing.value = false installing.value = false
return return
@@ -494,7 +494,7 @@ async function install(version) {
data.value.id, data.value.id,
version ? [versions.value.find((v) => v.id === queuedVersionData.id)] : versions.value, version ? [versions.value.find((v) => v.id === queuedVersionData.id)] : versions.value,
data.value.title, data.value.title,
data.value.project_type data.value.project_type,
) )
} }
} }
@@ -527,7 +527,7 @@ const handleOptionsClick = (args) => {
break break
case 'copy_link': case 'copy_link':
navigator.clipboard.writeText( navigator.clipboard.writeText(
`https://modrinth.com/${args.item.project_type}/${args.item.slug}` `https://modrinth.com/${args.item.project_type}/${args.item.slug}`,
) )
break break
} }

View File

@@ -26,8 +26,8 @@
installing installing
? 'Installing...' ? 'Installing...'
: installed && installedVersion === version.id : installed && installedVersion === version.id
? 'Installed' ? 'Installed'
: 'Install' : 'Install'
}} }}
</Button> </Button>
<Button> <Button>
@@ -252,11 +252,11 @@ watch(
version.value = props.versions.find((version) => version.id === route.params.version) version.value = props.versions.find((version) => version.id === route.params.version)
breadcrumbs.setName('Version', version.value.name) breadcrumbs.setName('Version', version.value.name)
} }
} },
) )
const author = computed(() => const author = computed(() =>
props.members.find((member) => member.user.id === version.value.author_id) props.members.find((member) => member.user.id === version.value.author_id),
) )
const displayDependencies = computed(() => const displayDependencies = computed(() =>
@@ -264,7 +264,7 @@ const displayDependencies = computed(() =>
const version = props.dependencies.versions.find((obj) => obj.id === dependency.version_id) const version = props.dependencies.versions.find((obj) => obj.id === dependency.version_id)
if (version) { if (version) {
const project = props.dependencies.projects.find( const project = props.dependencies.projects.find(
(obj) => obj.id === version.project_id || obj.id === dependency.project_id (obj) => obj.id === version.project_id || obj.id === dependency.project_id,
) )
return { return {
icon: project?.icon_url, icon: project?.icon_url,
@@ -291,7 +291,7 @@ const displayDependencies = computed(() =>
} }
} }
} }
}) }),
) )
</script> </script>

View File

@@ -210,12 +210,12 @@ const filteredVersions = computed(() => {
(projectVersion) => (projectVersion) =>
(filterGameVersions.value.length === 0 || (filterGameVersions.value.length === 0 ||
filterGameVersions.value.some((gameVersion) => filterGameVersions.value.some((gameVersion) =>
projectVersion.game_versions.includes(gameVersion) projectVersion.game_versions.includes(gameVersion),
)) && )) &&
(filterLoader.value.length === 0 || (filterLoader.value.length === 0 ||
filterLoader.value.some((loader) => projectVersion.loaders.includes(loader))) && filterLoader.value.some((loader) => projectVersion.loaders.includes(loader))) &&
(filterVersions.value.length === 0 || (filterVersions.value.length === 0 ||
filterVersions.value.includes(projectVersion.version_type)) filterVersions.value.includes(projectVersion.version_type)),
) )
}) })

View File

@@ -7,5 +7,5 @@ edition = "2021"
proc-macro = true proc-macro = true
[dependencies] [dependencies]
syn = { version = "1.0", features = ["full"] } syn = { version = "2.0.58", features = ["full"] }
quote = "1.0" quote = "1.0"

View File

@@ -10,11 +10,11 @@ theseus = { path = "../theseus", features = ["cli"] }
serde_json = "1.0" serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.2", features = ["shell-open"] } tauri = { version = "1.6", features = ["shell-open"] }
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
thiserror = "1.0" thiserror = "1.0"
url = "2.2" url = "2.2"
webbrowser = "0.7" webbrowser = "0.8.13"
dunce = "1.0.3" dunce = "1.0.3"
tokio-stream = { version = "0.1", features = ["fs"] } tokio-stream = { version = "0.1", features = ["fs"] }
@@ -23,5 +23,5 @@ daedalus = {version = "0.1.15", features = ["bincode"] }
uuid = { version = "1.1", features = ["serde", "v4"] } uuid = { version = "1.1", features = ["serde", "v4"] }
tracing = "0.1.37" tracing = "0.1.37"
tracing-subscriber = "0.2" tracing-subscriber = "0.3.18"
tracing-error = "0.1" tracing-error = "0.2.0"