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_json = "1.0"
serde_ini = "0.2.0"
toml = "0.7.3"
sha1 = { version = "0.6.1", features = ["std"]}
sha2 = "0.9.9"
toml = "0.8.12"
sha1_smol = { version = "1.0.0", features = ["std"] }
sha2 = "0.10.8"
url = "2.2"
uuid = { version = "1.1", features = ["serde", "v4"] }
zip = "0.6.5"
async_zip = { version = "0.0.13", features = ["full"] }
flate2 = "1.0.27"
async_zip = { version = "0.0.17", features = ["full"] }
flate2 = "1.0.28"
tempfile = "3.5.0"
urlencoding = "2.1.3"
@@ -31,28 +31,28 @@ dirs = "5.0.1"
regex = "1.5"
sys-info = "0.9.0"
sysinfo = "0.29.9"
sysinfo = "0.30.8"
thiserror = "1.0"
tracing = "0.1.37"
tracing-subscriber = {version = "0.2", features = ["chrono"]}
tracing-error = "0.1.0"
tracing-appender = "0.1"
tracing-subscriber = { version = "0.3.18", features = ["chrono"] }
tracing-error = "0.2.0"
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 }
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"
reqwest = { version = "0.11", features = ["json", "stream"] }
reqwest = { version = "0.12.3", features = ["json", "stream"] }
tokio = { version = "1", features = ["full"] }
tokio-stream = { version = "0.1", features = ["fs"] }
async-recursion = "1.0.4"
notify = { version = "5.1.0", default-features = false }
notify-debouncer-mini = { version = "0.2.1", default-features = false }
notify = { version = "6.1.1", default-features = false }
notify-debouncer-mini = { version = "0.4.1", default-features = false }
lazy_static = "1.4.0"
dunce = "1.0.3"
@@ -61,8 +61,8 @@ whoami = "1.4.0"
discord-rich-presence = "0.2.3"
[target.'cfg(windows)'.dependencies]
winreg = "0.50.0"
[target.'cfg(windows)'.dependencies]
winreg = "0.52.0"
[features]
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::io;
use crate::{profile, State};
use async_zip::tokio::read::seek::ZipFileReader;
use async_zip::base::read::seek::ZipFileReader;
use reqwest::Method;
use serde_json::json;
@@ -93,29 +93,21 @@ pub async fn install_zipped_mrpack_files(
let reader: Cursor<&bytes::Bytes> = Cursor::new(&file);
// Create zip reader around file
let mut zip_reader = ZipFileReader::new(reader).await.map_err(|_| {
crate::Error::from(crate::ErrorKind::InputError(
"Failed to read input modpack zip".to_string(),
))
})?;
let mut zip_reader =
ZipFileReader::with_tokio(reader).await.map_err(|_| {
crate::Error::from(crate::ErrorKind::InputError(
"Failed to read input modpack zip".to_string(),
))
})?;
// Extract index of modrinth.index.json
let zip_index_option = zip_reader
.file()
.entries()
.iter()
.position(|f| f.entry().filename() == "modrinth.index.json");
let zip_index_option = zip_reader.file().entries().iter().position(|f| {
f.filename().as_str().unwrap_or_default() == "modrinth.index.json"
});
if let Some(zip_index) = zip_index_option {
let mut manifest = String::new();
let entry = zip_reader
.file()
.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 mut reader = zip_reader.reader_with_entry(zip_index).await?;
reader.read_to_string_checked(&mut manifest).await?;
let pack: PackFormat = serde_json::from_str(&manifest)?;
@@ -217,34 +209,31 @@ pub async fn install_zipped_mrpack_files(
let mut total_len = 0;
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")
|| file.filename().starts_with("client_overrides"))
&& !file.filename().ends_with('/')
if (filename.starts_with("overrides")
|| filename.starts_with("client_overrides"))
&& !filename.ends_with('/')
{
total_len += 1;
}
}
for index in 0..zip_reader.file().entries().len() {
let file = zip_reader
.file()
.entries()
.get(index)
.unwrap()
.entry()
.clone();
let file = zip_reader.file().entries().get(index).unwrap();
let file_path = PathBuf::from(file.filename());
if (file.filename().starts_with("overrides")
|| file.filename().starts_with("client_overrides"))
&& !file.filename().ends_with('/')
let filename = file.filename().as_str().unwrap_or_default();
let file_path = PathBuf::from(filename);
if (filename.starts_with("overrides")
|| filename.starts_with("client_overrides"))
&& !filename.ends_with('/')
{
// Reads the file into the 'content' variable
let mut content = Vec::new();
let mut reader = zip_reader.entry(index).await?;
reader.read_to_end_checked(&mut content, &file).await?;
let mut reader = zip_reader.reader_with_entry(index).await?;
reader.read_to_end_checked(&mut content).await?;
let mut new_path = PathBuf::new();
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);
// Create zip reader around file
let mut zip_reader = ZipFileReader::new(reader).await.map_err(|_| {
crate::Error::from(crate::ErrorKind::InputError(
"Failed to read input modpack zip".to_string(),
))
})?;
let mut zip_reader =
ZipFileReader::with_tokio(reader).await.map_err(|_| {
crate::Error::from(crate::ErrorKind::InputError(
"Failed to read input modpack zip".to_string(),
))
})?;
// Extract index of modrinth.index.json
let zip_index_option = zip_reader
.file()
.entries()
.iter()
.position(|f| f.entry().filename() == "modrinth.index.json");
let zip_index_option = zip_reader.file().entries().iter().position(|f| {
f.filename().as_str().unwrap_or_default() == "modrinth.index.json"
});
if let Some(zip_index) = zip_index_option {
let mut manifest = String::new();
let entry = zip_reader
.file()
.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 mut reader = zip_reader.reader_with_entry(zip_index).await?;
reader.read_to_string_checked(&mut manifest).await?;
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
for index in 0..zip_reader.file().entries().len() {
let file = zip_reader
.file()
.entries()
.get(index)
.unwrap()
.entry()
.clone();
let file = zip_reader.file().entries().get(index).unwrap();
let file_path = PathBuf::from(file.filename());
if (file.filename().starts_with("overrides")
|| file.filename().starts_with("client_overrides"))
&& !file.filename().ends_with('/')
let filename = file.filename().as_str().unwrap_or_default();
let file_path = PathBuf::from(filename);
if (filename.starts_with("overrides")
|| filename.starts_with("client_overrides"))
&& !filename.ends_with('/')
{
let mut new_path = PathBuf::new();
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)
.await
.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
let version_id = version_id.unwrap_or("1.0.0".to_string());
@@ -660,7 +660,7 @@ pub async fn export_mrpack(
.await
.map_err(|e| IOError::with_path(e, &path))?;
let builder = ZipEntryBuilder::new(
format!("overrides/{relative_path}"),
format!("overrides/{relative_path}").into(),
Compression::Deflate,
);
writer.write_entry_whole(builder, &data).await?;
@@ -670,7 +670,7 @@ pub async fn export_mrpack(
// Add modrinth json to the zip
let data = serde_json::to_vec_pretty(&packfile)?;
let builder = ZipEntryBuilder::new(
"modrinth.index.json".to_string(),
"modrinth.index.json".to_string().into(),
Compression::Deflate,
);
writer.write_entry_whole(builder, &data).await?;

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,6 @@ use chrono::{DateTime, Utc};
use serde::Deserialize;
use serde::Serialize;
use std::{collections::HashMap, sync::Arc};
use sysinfo::PidExt;
use tokio::process::Child;
use tokio::process::Command;
use tokio::sync::RwLock;
@@ -13,7 +12,6 @@ use crate::event::ProcessPayloadType;
use crate::util::fetch::read_json;
use crate::util::io::IOError;
use crate::{profile, ErrorKind};
use sysinfo::{ProcessExt, SystemExt};
use tokio::task::JoinHandle;
use uuid::Uuid;
@@ -117,7 +115,16 @@ impl ChildType {
})?;
let start_time = process.start_time();
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 {
pid,
@@ -357,8 +364,16 @@ impl Children {
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());
}
if cached_process.exe != process.exe().to_string_lossy() {
return Err(ErrorKind::LauncherError(format!("Cached process {} has different exe than actual process {}", cached_process.pid, process.exe().to_string_lossy())).into());
if let Some(path) = process.exe() {
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(
Duration::from_secs_f32(2.0),
None,
move |res: DebounceEventResult| {
futures::executor::block_on(async {
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| {
tracing::warn!("Unable to watch file: {err}")
}),
Err(error) => tracing::warn!("Unable to watch file: {error}"),
}
}
});

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
// 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 tokio::task::spawn_blocking;
@@ -137,12 +137,13 @@ fn sync_write(
data: impl AsRef<[u8]>,
path: impl AsRef<Path>,
) -> Result<(), std::io::Error> {
let mut tempfile = NamedTempFile::new_in(path.as_ref().parent().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::Other,
"could not get parent directory for temporary file",
)
})?)?;
let mut tempfile =
NamedTempFile::new_in(path.as_ref().parent().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::Other,
"could not get parent directory for temporary file",
)
})?)?;
tempfile.write_all(data.as_ref())?;
let tmp_path = tempfile.into_temp_path();
let path = path.as_ref();

View File

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

View File

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

View File

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

View File

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

View File

@@ -13,31 +13,31 @@
"fix": "eslint --fix --ext .js,.vue,.ts,.jsx,.tsx,.html,.vue . && prettier --write ."
},
"dependencies": {
"@tauri-apps/api": "^1.3.0",
"dayjs": "^1.11.7",
"floating-vue": "^2.0.0-beta.20",
"mixpanel-browser": "^2.47.0",
"ofetch": "^1.0.1",
"omorphia": "^0.4.38",
"pinia": "^2.1.3",
"qrcode.vue": "^3.4.0",
"@tauri-apps/api": "^1.5.3",
"dayjs": "^1.11.10",
"floating-vue": "^5.2.2",
"mixpanel-browser": "^2.49.0",
"ofetch": "^1.3.4",
"omorphia": "^0.4.41",
"pinia": "^2.1.7",
"qrcode.vue": "^3.4.1",
"tauri-plugin-window-state-api": "github:tauri-apps/tauri-plugin-window-state#v1",
"vite-svg-loader": "^4.0.0",
"vue": "^3.3.4",
"vue-multiselect": "^3.0.0-beta.2",
"vue-router": "4.2.1",
"vite-svg-loader": "^5.1.0",
"vue": "^3.4.21",
"vue-multiselect": "3.0.0-beta.3",
"vue-router": "4.3.0",
"vue-virtual-scroller": "2.0.0-beta.8"
},
"devDependencies": {
"@rollup/plugin-alias": "^4.0.4",
"@tauri-apps/cli": "^1.3.1",
"@vitejs/plugin-vue": "^4.2.3",
"eslint": "^8.41.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-vue": "^9.14.1",
"prettier": "^2.8.8",
"sass": "^1.62.1",
"vite": "^4.3.9",
"@rollup/plugin-alias": "^5.1.0",
"@tauri-apps/cli": "^1.5.11",
"@vitejs/plugin-vue": "^5.0.4",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-vue": "^9.24.0",
"prettier": "^3.2.5",
"sass": "^1.74.1",
"vite": "^5.2.8",
"vite-plugin-eslint": "^1.8.1"
},
"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 = { 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-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"] }
thiserror = "1.0"
@@ -38,10 +38,10 @@ uuid = { version = "1.1", features = ["serde", "v4"] }
os_info = "3.7.0"
tracing = "0.1.37"
tracing-error = "0.1"
tracing-error = "0.2.0"
sentry = "0.30"
sentry-rust-minidump = "0.5"
sentry = "0.32.2"
sentry-rust-minidump = "0.7.0"
lazy_static = "1"
once_cell = "1"
@@ -50,7 +50,7 @@ once_cell = "1"
window-shadows = "0.2.1"
[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.24.1"
cocoa = "0.25.0"
objc = "0.2.7"
[features]

View File

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

View File

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

View File

@@ -50,7 +50,7 @@ const props = defineProps({
})
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)
@@ -171,7 +171,7 @@ const handleOptionsClick = async (args) => {
case 'install': {
const versions = await useFetch(
`https://api.modrinth.com/v2/project/${args.item.project_id}/version`,
'project versions'
'project versions',
)
if (args.item.project_type === 'modpack') {
@@ -179,7 +179,7 @@ const handleOptionsClick = async (args) => {
args.item.project_id,
versions[0].id,
args.item.title,
args.item.icon_url
args.item.icon_url,
)
} else {
modInstallModal.value.show(args.item.project_id, versions)
@@ -197,7 +197,7 @@ const handleOptionsClick = async (args) => {
break
case 'copy_link':
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
}

View File

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

View File

@@ -147,11 +147,11 @@ defineExpose({
await refreshValues()
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(() =>
accounts.value.find((account) => account.id === settings.value.default_user)
accounts.value.find((account) => account.id === settings.value.default_user),
)
async function setAccount(account) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -136,7 +136,7 @@ async function install() {
installing.value = true
const versions = await useFetch(
`https://api.modrinth.com/v2/project/${props.project.project_id}/version`,
'project versions'
'project versions',
)
let queuedVersionData
@@ -146,7 +146,8 @@ async function install() {
queuedVersionData = versions.find(
(v) =>
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,
queuedVersionData.id,
props.project.title,
props.project.icon_url
props.project.icon_url,
).catch(handleError)
mixpanel_track('PackInstall', {
@@ -176,7 +177,7 @@ async function install() {
props.project.project_id,
queuedVersionData.id,
props.project.title,
props.project.icon_url
props.project.icon_url,
)
}
} else {
@@ -188,7 +189,7 @@ async function install() {
versions,
() => (installed.value = true),
props.project.project_id,
props.project.project_type
props.project.project_type,
)
installing.value = false
return
@@ -211,7 +212,7 @@ async function install() {
props.project.project_id,
versions,
props.project.title,
props.project.project_type
props.project.project_type,
)
installing.value = false
return

View File

@@ -21,28 +21,28 @@ defineExpose({
if (event.event === 'InstallVersion') {
version.value = await useFetch(
`https://api.modrinth.com/v2/version/${encodeURIComponent(event.id)}`,
'version'
'version',
)
project.value = await useFetch(
`https://api.modrinth.com/v2/project/${encodeURIComponent(version.value.project_id)}`,
'project'
'project',
)
} else {
project.value = await useFetch(
`https://api.modrinth.com/v2/project/${encodeURIComponent(event.id)}`,
'project'
'project',
)
version.value = await useFetch(
`https://api.modrinth.com/v2/version/${encodeURIComponent(project.value.versions[0])}`,
'version'
'version',
)
}
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()
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()
},
@@ -55,7 +55,7 @@ async function install() {
project.value.id,
version.value.id,
project.value.title,
project.value.icon_url
project.value.icon_url,
).catch(handleError)
mixpanel.track('PackInstall', {
@@ -69,7 +69,7 @@ async function install() {
project.value.id,
[version.value],
project.value.title,
project.value.project_type
project.value.project_type,
)
}
}

View File

@@ -100,7 +100,7 @@ defineProps({
v-for="loader in loaders.filter(
(l) =>
(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"
>

View File

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

View File

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

View File

@@ -489,7 +489,8 @@ onMounted(async () => {
}
.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);
background-size: cover;
height: 100vh;

View File

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

View File

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

View File

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

View File

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

View File

@@ -75,7 +75,7 @@ const ignoreInstanceGameVersions = ref(false)
const results = shallowRef([])
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) {
@@ -179,7 +179,9 @@ async function refreshSearch() {
formattedFacets.push(orFacets.value)
} else if (projectType.value === 'mod') {
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') {
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) =>
Object.values(x.projects)
.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))
console.log(`facets=${JSON.stringify(formattedFacets)}`)
@@ -262,7 +264,7 @@ async function refreshSearch() {
if (instanceContext.value) {
for (val of rawResults.hits) {
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 values = new Map()
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)) {
values.set(category.header, [])
@@ -478,7 +480,7 @@ watch(
loading.value = true
await clearFilters()
loading.value = false
}
},
)
const [categories, loaders, availableGameVersions] = await Promise.all([
@@ -500,7 +502,7 @@ const selectableProjectTypes = computed(() => {
if (instanceContext.value) {
if (
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')
) {
values.unshift({ label: 'Data Packs', href: `/browse/datapack` })
@@ -519,7 +521,7 @@ const selectableProjectTypes = computed(() => {
})
const showVersions = computed(
() => instanceContext.value === null || ignoreInstanceGameVersions.value
() => instanceContext.value === null || ignoreInstanceGameVersions.value,
)
const showLoaders = computed(
() =>
@@ -527,7 +529,7 @@ const showLoaders = computed(
projectType.value !== 'resourcepack' &&
projectType.value !== 'shader' &&
instanceContext.value === null) ||
ignoreInstanceLoaders.value
ignoreInstanceLoaders.value,
)
onUnmounted(() => unlistenOffline())
@@ -605,7 +607,8 @@ onUnmounted(() => unlistenOffline())
v-for="loader in loaders.filter(
(l) =>
(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"
>
@@ -752,12 +755,12 @@ onUnmounted(() => unlistenOffline())
:categories="[
...categories.filter(
(cat) =>
result?.display_categories.includes(cat.name) && cat.project_type === projectType
result?.display_categories.includes(cat.name) && cat.project_type === projectType,
),
...loaders.filter(
(loader) =>
result?.display_categories.includes(loader.name) &&
loader.supported_project_types?.includes(projectType)
loader.supported_project_types?.includes(projectType),
),
]"
:confirm-modal="confirmModal"

View File

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

View File

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

View File

@@ -165,7 +165,7 @@ breadcrumbs.setName(
'Instance',
instance.value.metadata.name.length > 40
? instance.value.metadata.name.substring(0, 40) + '...'
: instance.value.metadata.name
: instance.value.metadata.name,
)
breadcrumbs.setContext({
@@ -212,7 +212,7 @@ const modrinthVersions = ref([])
if (!(await isOffline()) && instance.value.metadata.linked_data?.project_id) {
modrinthVersions.value = await useFetch(
`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',
},
...baseOptions,
]
],
)
}

View File

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

View File

@@ -505,7 +505,7 @@ const initProjects = (initInstance) => {
selectionMap.value.get(project.path) ??
selectionMap.value.get(project.path.slice(0, -9)) ??
selectionMap.value.get(project.path + '.disabled') ??
false
false,
)
}
selectionMap.value = newSelectionMap
@@ -517,14 +517,14 @@ watch(
() => props.instance.projects,
() => {
initProjects(props.instance)
}
},
)
watch(
() => props.offline,
() => {
if (props.instance) initProjects(props.instance)
}
},
)
const modpackVersionModal = ref(null)
@@ -551,11 +551,11 @@ const selected = computed(() =>
})
.map((args) => {
return projects.value.find((x) => x.path === args[0])
})
}),
)
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(() => {
@@ -781,7 +781,7 @@ const shareUrls = async () => {
functionValues.value
.filter((x) => 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
})
.join('\n')
.join('\n'),
)
}
@@ -839,7 +839,7 @@ const handleRightClick = (event, mod) => {
{
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(
instancesList.reduce((acc, obj) => {
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 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)
@@ -688,7 +690,7 @@ watch(
async () => {
await edit(props.instance.path, editProfileObject.value)
},
{ deep: true }
{ deep: true },
)
const getLocalVersion = (path) => {
@@ -716,7 +718,7 @@ const editProfileObject = computed(() => {
editProfile.java.override_version = javaInstall.value
editProfile.java.override_version.path = editProfile.java.override_version.path.replace(
'java.exe',
'javaw.exe'
'javaw.exe',
)
}
}
@@ -848,7 +850,7 @@ const [
.then((value) =>
value
.filter((item) => item.supported_project_types.includes('modpack'))
.map((item) => item.name.toLowerCase())
.map((item) => item.name.toLowerCase()),
)
.then(ref)
.catch(handleError),
@@ -893,8 +895,8 @@ const selectableLoaderVersions = computed(() => {
})
const loaderVersionIndex = ref(
selectableLoaderVersions.value.findIndex(
(x) => x.id === props.instance.metadata.loader_version?.id
)
(x) => x.id === props.instance.metadata.loader_version?.id,
),
)
const isValid = computed(() => {

View File

@@ -276,7 +276,9 @@ const expandImage = (item, index) => {
display: flex;
flex-direction: column;
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;
margin-bottom: 0.25rem;
gap: 0.5rem;
@@ -297,7 +299,9 @@ const expandImage = (item, index) => {
background-color: var(--color-raised-bg);
padding: var(--gap-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"
:categories="
categories.filter(
(cat) => data.categories.includes(cat.name) && cat.project_type === 'mod'
(cat) => data.categories.includes(cat.name) && cat.project_type === 'mod',
)
"
type="ignored"
@@ -328,7 +328,7 @@ async function fetchProjectData() {
breadcrumbs.setName('Project', data.value.title)
installedVersion.value = instance.value
? 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
: null
}
@@ -341,7 +341,7 @@ watch(
if (route.params.id && route.path.startsWith('/project')) {
await fetchProjectData()
}
}
},
)
dayjs.extend(relativeTime)
@@ -380,7 +380,7 @@ async function install(version) {
queuedVersionData = versions.value[0]
} else {
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,
queuedVersionData.id,
data.value.title,
data.value.icon_url
data.value.icon_url,
).catch(handleError)
mixpanel_track('PackInstall', {
@@ -411,7 +411,7 @@ async function install(version) {
data.value.id,
queuedVersionData.id,
data.value.title,
data.value.icon_url
data.value.icon_url,
)
}
} else {
@@ -424,7 +424,7 @@ async function install(version) {
v.game_versions.includes(gameVersion) &&
(data.value.project_type === 'mod'
? v.loaders.includes(loader) || v.loaders.includes('minecraft')
: true)
: true),
)
if (!selectedVersion) {
incompatibilityWarning.value.show(
@@ -433,7 +433,7 @@ async function install(version) {
versions.value,
markInstalled,
data.value.id,
data.value.project_type
data.value.project_type,
)
installing.value = false
return
@@ -460,7 +460,7 @@ async function install(version) {
v.game_versions.includes(gameVersion) &&
(data.value.project_type === 'mod'
? v.loaders.includes(loader) || v.loaders.includes('minecraft')
: true)
: true),
)
if (compatible) {
await installMod(instance.value.path, queuedVersionData.id).catch(handleError)
@@ -482,7 +482,7 @@ async function install(version) {
[queuedVersionData],
markInstalled,
data.value.id,
data.value.project_type
data.value.project_type,
)
installing.value = false
return
@@ -494,7 +494,7 @@ async function install(version) {
data.value.id,
version ? [versions.value.find((v) => v.id === queuedVersionData.id)] : versions.value,
data.value.title,
data.value.project_type
data.value.project_type,
)
}
}
@@ -527,7 +527,7 @@ const handleOptionsClick = (args) => {
break
case 'copy_link':
navigator.clipboard.writeText(
`https://modrinth.com/${args.item.project_type}/${args.item.slug}`
`https://modrinth.com/${args.item.project_type}/${args.item.slug}`,
)
break
}

View File

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

View File

@@ -210,12 +210,12 @@ const filteredVersions = computed(() => {
(projectVersion) =>
(filterGameVersions.value.length === 0 ||
filterGameVersions.value.some((gameVersion) =>
projectVersion.game_versions.includes(gameVersion)
projectVersion.game_versions.includes(gameVersion),
)) &&
(filterLoader.value.length === 0 ||
filterLoader.value.some((loader) => projectVersion.loaders.includes(loader))) &&
(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
[dependencies]
syn = { version = "1.0", features = ["full"] }
syn = { version = "2.0.58", features = ["full"] }
quote = "1.0"

View File

@@ -10,11 +10,11 @@ theseus = { path = "../theseus", features = ["cli"] }
serde_json = "1.0"
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"] }
thiserror = "1.0"
url = "2.2"
webbrowser = "0.7"
webbrowser = "0.8.13"
dunce = "1.0.3"
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"] }
tracing = "0.1.37"
tracing-subscriber = "0.2"
tracing-error = "0.1"
tracing-subscriber = "0.3.18"
tracing-error = "0.2.0"