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
Generated
+1668 -1194
View File
File diff suppressed because it is too large Load Diff
+17 -17
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"
@@ -61,8 +61,8 @@ 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"]
+45 -67
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);
+3 -3
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?;
+12 -10
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 {
+1 -1
View File
@@ -31,7 +31,7 @@ impl EventState {
})) }))
}) })
.await .await
.map(Arc::clone) .cloned()
} }
#[cfg(not(feature = "tauri"))] #[cfg(not(feature = "tauri"))]
+1 -1
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());
+20 -5
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());
} }
} }
+1 -4
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}")
}),
} }
} }
}); });
+53 -71
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()
{ {
+1 -1
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?;
+8 -7
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();
+5 -5
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"
+10 -10
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(())
+4 -4
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 {
+1 -1
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" />
+21 -21
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"
+678 -460
View File
File diff suppressed because it is too large Load Diff
+6 -6
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]
+2 -2
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
} }
+2 -2
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,
] ],
) )
} }
+4 -4
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
} }
@@ -66,7 +66,7 @@ export default defineComponent({
zIndex: 6, zIndex: 6,
}, },
}, },
slots slots,
) )
}, },
}) })
@@ -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) {
@@ -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>
@@ -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()
} }
@@ -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
@@ -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,
+10 -7
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);
@@ -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, [])
@@ -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
@@ -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>
@@ -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)
@@ -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
+7 -6
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
@@ -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,
) )
} }
} }
@@ -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"
> >
@@ -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>
@@ -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()
@@ -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;
+2 -2
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
+2 -2
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 })
} }
+1 -1
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,
+2 -2
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)
+15 -12
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"
+2 -2
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
+3 -3
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))
+3 -3
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,
] ],
) )
} }
+4 -4
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()
} }
+8 -8
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' }],
) )
} }
} }
+9 -7
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(() => {
+6 -2
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;
} }
} }
} }
+12 -12
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
} }
+6 -6
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>
+2 -2
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)),
) )
}) })
+1 -1
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"
+4 -4
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"