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
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
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"