Onboarding (#132)
* Initial onboarding * Update OnboardingModal.vue * Add finish * Animation * Automatic opening * Move onboarding icon to outside of main appbar * Run lint * run fmt * mostly finish * Finish onboarding * fix onboarding bug + linux build * fix build again * Add back window shadows --------- Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com> Co-authored-by: Jai A <jaiagr+gpg@pm.me> Co-authored-by: Jai A <jai@modrinth.com>
This commit is contained in:
27 files changed
+635
-248
No files matched your search
Generated
+16
-3
@@ -4567,7 +4567,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "theseus"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"async-tungstenite",
|
||||
"async_zip",
|
||||
@@ -4608,7 +4608,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "theseus_cli"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"argh",
|
||||
"color-eyre",
|
||||
@@ -4660,6 +4660,7 @@ dependencies = [
|
||||
"tracing-subscriber 0.2.25",
|
||||
"url",
|
||||
"uuid",
|
||||
"window-shadows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4672,7 +4673,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "theseus_playground"
|
||||
version = "0.1.0"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"daedalus",
|
||||
"dunce",
|
||||
@@ -5484,6 +5485,18 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "window-shadows"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29d30320647cfc3dc45554c8ad825b84831def81f967a2f7589931328ff9b16d"
|
||||
dependencies = [
|
||||
"cocoa",
|
||||
"objc",
|
||||
"raw-window-handle",
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.37.0"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "theseus"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
authors = ["Jai A <jaiagr+gpg@pm.me>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
+34
-55
@@ -18,9 +18,9 @@ pub const JAVA_18PLUS_KEY: &str = "JAVA_18PLUS";
|
||||
// Autodetect JavaSettings default
|
||||
// Make a guess for what the default Java global settings should be
|
||||
pub async fn autodetect_java_globals() -> crate::Result<JavaGlobals> {
|
||||
let mut java_8 = find_java8_jres().await?;
|
||||
let mut java_17 = find_java17_jres().await?;
|
||||
let mut java_18plus = find_java18plus_jres().await?;
|
||||
let mut java_8 = find_filtered_jres("1.8").await?;
|
||||
let mut java_17 = find_filtered_jres("1.17").await?;
|
||||
let mut java_18plus = find_filtered_jres("1.18").await?;
|
||||
|
||||
// Simply select last one found for initial guess
|
||||
let mut java_globals = JavaGlobals::new();
|
||||
@@ -37,11 +37,13 @@ pub async fn autodetect_java_globals() -> crate::Result<JavaGlobals> {
|
||||
Ok(java_globals)
|
||||
}
|
||||
|
||||
// Searches for jres on the system that are 1.18 or higher
|
||||
pub async fn find_java18plus_jres() -> crate::Result<Vec<JavaVersion>> {
|
||||
let version = extract_java_majorminor_version("1.18")?;
|
||||
// Searches for jres on the system given a java version (ex: 1.8, 1.17, 1.18)
|
||||
pub async fn find_filtered_jres(
|
||||
version: &str,
|
||||
) -> crate::Result<Vec<JavaVersion>> {
|
||||
let version = extract_java_majorminor_version(version)?;
|
||||
let jres = jre::get_all_jre().await?;
|
||||
// Filter out JREs that are not 1.17 or higher
|
||||
|
||||
Ok(jres
|
||||
.into_iter()
|
||||
.filter(|jre| {
|
||||
@@ -55,44 +57,6 @@ pub async fn find_java18plus_jres() -> crate::Result<Vec<JavaVersion>> {
|
||||
.collect())
|
||||
}
|
||||
|
||||
// Searches for jres on the system that are 1.8 exactly
|
||||
pub async fn find_java8_jres() -> crate::Result<Vec<JavaVersion>> {
|
||||
let version = extract_java_majorminor_version("1.8")?;
|
||||
let jres = jre::get_all_jre().await?;
|
||||
|
||||
// Filter out JREs that are not 1.8
|
||||
Ok(jres
|
||||
.into_iter()
|
||||
.filter(|jre| {
|
||||
let jre_version = extract_java_majorminor_version(&jre.version);
|
||||
if let Ok(jre_version) = jre_version {
|
||||
jre_version == version
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
// Searches for jres on the system that are 1.17 exactly
|
||||
pub async fn find_java17_jres() -> crate::Result<Vec<JavaVersion>> {
|
||||
let version = extract_java_majorminor_version("1.17")?;
|
||||
let jres = jre::get_all_jre().await?;
|
||||
|
||||
// Filter out JREs that are not 1.8
|
||||
Ok(jres
|
||||
.into_iter()
|
||||
.filter(|jre| {
|
||||
let jre_version = extract_java_majorminor_version(&jre.version);
|
||||
if let Ok(jre_version) = jre_version {
|
||||
jre_version == version
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
#[theseus_macros::debug_pin]
|
||||
pub async fn auto_install_java(java_version: u32) -> crate::Result<PathBuf> {
|
||||
let state = State::get().await?;
|
||||
@@ -157,16 +121,31 @@ pub async fn auto_install_java(java_version: u32) -> crate::Result<PathBuf> {
|
||||
))
|
||||
})?;
|
||||
emit_loading(&loading_bar, 10.0, Some("Done extracting java")).await?;
|
||||
Ok(path
|
||||
.join(
|
||||
download
|
||||
.name
|
||||
.file_stem()
|
||||
.unwrap_or_default()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
)
|
||||
.join(format!("zulu-{}.jre/Contents/Home/bin/java", java_version)))
|
||||
let mut base_path = path.join(
|
||||
download
|
||||
.name
|
||||
.file_stem()
|
||||
.unwrap_or_default()
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
);
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
base_path = base_path
|
||||
.join(format!("zulu-{}.jre", java_version))
|
||||
.join("Contents")
|
||||
.join("Home")
|
||||
.join("bin")
|
||||
.join("java")
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
base_path = base_path.join("bin").join(jre::JAVA_BIN)
|
||||
}
|
||||
|
||||
Ok(base_path)
|
||||
} else {
|
||||
Err(crate::ErrorKind::LauncherError(format!(
|
||||
"No Java Version found for Java version {}, OS {}, and Architecture {}",
|
||||
|
||||
@@ -32,6 +32,8 @@ pub struct Settings {
|
||||
pub opt_out_analytics: bool,
|
||||
#[serde(default)]
|
||||
pub advanced_rendering: bool,
|
||||
#[serde(default)]
|
||||
pub onboarded: bool,
|
||||
}
|
||||
|
||||
impl Default for Settings {
|
||||
@@ -52,6 +54,7 @@ impl Default for Settings {
|
||||
developer_mode: false,
|
||||
opt_out_analytics: false,
|
||||
advanced_rendering: true,
|
||||
onboarded: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+64
-63
@@ -31,7 +31,7 @@ pub async fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
||||
let mut jre_paths = HashSet::new();
|
||||
|
||||
// Add JRES directly on PATH
|
||||
jre_paths.extend(get_all_jre_path().await?);
|
||||
jre_paths.extend(get_all_jre_path().await);
|
||||
jre_paths.extend(get_all_autoinstalled_jre_path().await?);
|
||||
if let Ok(java_home) = env::var("JAVA_HOME") {
|
||||
jre_paths.insert(PathBuf::from(java_home));
|
||||
@@ -47,8 +47,10 @@ pub async fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
||||
for java_path in java_paths {
|
||||
let Ok(java_subpaths) = std::fs::read_dir(java_path) else {continue };
|
||||
for java_subpath in java_subpaths {
|
||||
let path = java_subpath?.path();
|
||||
jre_paths.insert(path.join("bin"));
|
||||
if let Ok(java_subpath) = java_subpath {
|
||||
let path = java_subpath.path();
|
||||
jre_paths.insert(path.join("bin"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,18 +70,18 @@ pub async fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
||||
if let Ok(jre_key) = RegKey::predef(HKEY_LOCAL_MACHINE)
|
||||
.open_subkey_with_flags(key, KEY_READ | KEY_WOW64_32KEY)
|
||||
{
|
||||
jre_paths.extend(get_paths_from_jre_winregkey(jre_key)?);
|
||||
jre_paths.extend(get_paths_from_jre_winregkey(jre_key));
|
||||
}
|
||||
if let Ok(jre_key) = RegKey::predef(HKEY_LOCAL_MACHINE)
|
||||
.open_subkey_with_flags(key, KEY_READ | KEY_WOW64_64KEY)
|
||||
{
|
||||
jre_paths.extend(get_paths_from_jre_winregkey(jre_key)?);
|
||||
jre_paths.extend(get_paths_from_jre_winregkey(jre_key));
|
||||
}
|
||||
}
|
||||
|
||||
// Get JRE versions from potential paths concurrently
|
||||
let j = check_java_at_filepaths(jre_paths)
|
||||
.await?
|
||||
.await
|
||||
.into_iter()
|
||||
.collect();
|
||||
Ok(j)
|
||||
@@ -88,27 +90,26 @@ pub async fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
||||
// Gets paths rather than search directly as RegKeys should not be passed asynchronously (do not impl Send)
|
||||
#[cfg(target_os = "windows")]
|
||||
#[tracing::instrument]
|
||||
pub fn get_paths_from_jre_winregkey(
|
||||
jre_key: RegKey,
|
||||
) -> Result<HashSet<PathBuf>, JREError> {
|
||||
pub fn get_paths_from_jre_winregkey(jre_key: RegKey) -> HashSet<PathBuf> {
|
||||
let mut jre_paths = HashSet::new();
|
||||
|
||||
for subkey in jre_key.enum_keys() {
|
||||
let subkey = subkey?;
|
||||
let subkey = jre_key.open_subkey(subkey)?;
|
||||
if let Ok(subkey) = subkey {
|
||||
if let Ok(subkey) = jre_key.open_subkey(subkey) {
|
||||
let subkey_value_names =
|
||||
[r"JavaHome", r"InstallationPath", r"\\hotspot\\MSI"];
|
||||
|
||||
let subkey_value_names =
|
||||
[r"JavaHome", r"InstallationPath", r"\\hotspot\\MSI"];
|
||||
for subkey_value in subkey_value_names {
|
||||
let path: Result<String, std::io::Error> =
|
||||
subkey.get_value(subkey_value);
|
||||
let Ok(path) = path else {continue};
|
||||
|
||||
for subkey_value in subkey_value_names {
|
||||
let path: Result<String, std::io::Error> =
|
||||
subkey.get_value(subkey_value);
|
||||
let Ok(path) = path else {continue};
|
||||
|
||||
jre_paths.insert(PathBuf::from(path).join("bin"));
|
||||
jre_paths.insert(PathBuf::from(path).join("bin"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(jre_paths)
|
||||
jre_paths
|
||||
}
|
||||
|
||||
// Entrypoint function (Mac)
|
||||
@@ -120,7 +121,7 @@ pub async fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
||||
let mut jre_paths = HashSet::new();
|
||||
|
||||
// Add JREs directly on PATH
|
||||
jre_paths.extend(get_all_jre_path().await?);
|
||||
jre_paths.extend(get_all_jre_path().await);
|
||||
jre_paths.extend(get_all_autoinstalled_jre_path().await?);
|
||||
|
||||
// Hard paths for locations for commonly installed .exes
|
||||
@@ -134,16 +135,18 @@ pub async fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
||||
}
|
||||
// Iterate over JavaVirtualMachines/(something)/Contents/Home/bin
|
||||
let base_path = PathBuf::from("/Library/Java/JavaVirtualMachines/");
|
||||
if base_path.is_dir() {
|
||||
for entry in std::fs::read_dir(base_path)? {
|
||||
let entry = entry?.path().join("Contents/Home/bin");
|
||||
jre_paths.insert(entry);
|
||||
if let Ok(dir) = std::fs::read_dir(base_path) {
|
||||
for entry in dir {
|
||||
if let Ok(entry) = entry {
|
||||
let entry = entry.path().join("Contents/Home/bin");
|
||||
jre_paths.insert(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get JRE versions from potential paths concurrently
|
||||
let j = check_java_at_filepaths(jre_paths)
|
||||
.await?
|
||||
.await
|
||||
.into_iter()
|
||||
.collect();
|
||||
Ok(j)
|
||||
@@ -158,7 +161,7 @@ pub async fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
||||
let mut jre_paths = HashSet::new();
|
||||
|
||||
// Add JREs directly on PATH
|
||||
jre_paths.extend(get_all_jre_path().await?);
|
||||
jre_paths.extend(get_all_jre_path().await);
|
||||
jre_paths.extend(get_all_autoinstalled_jre_path().await?);
|
||||
|
||||
// Hard paths for locations for commonly installed locations
|
||||
@@ -174,18 +177,20 @@ pub async fn get_all_jre() -> Result<Vec<JavaVersion>, JREError> {
|
||||
let path = PathBuf::from(path);
|
||||
jre_paths.insert(PathBuf::from(&path).join("jre").join("bin"));
|
||||
jre_paths.insert(PathBuf::from(&path).join("bin"));
|
||||
if path.is_dir() {
|
||||
for entry in std::fs::read_dir(&path)? {
|
||||
let entry_path = entry?.path();
|
||||
jre_paths.insert(entry_path.join("jre").join("bin"));
|
||||
jre_paths.insert(entry_path.join("bin"));
|
||||
if let Ok(dir) = std::fs::read_dir(path) {
|
||||
for entry in dir {
|
||||
if let Ok(entry) = entry {
|
||||
let entry_path = entry.path();
|
||||
jre_paths.insert(entry_path.join("jre").join("bin"));
|
||||
jre_paths.insert(entry_path.join("bin"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get JRE versions from potential paths concurrently
|
||||
let j = check_java_at_filepaths(jre_paths)
|
||||
.await?
|
||||
.await
|
||||
.into_iter()
|
||||
.collect();
|
||||
Ok(j)
|
||||
@@ -203,13 +208,25 @@ async fn get_all_autoinstalled_jre_path() -> Result<HashSet<PathBuf>, JREError>
|
||||
let base_path = state.directories.java_versions_dir();
|
||||
|
||||
if base_path.is_dir() {
|
||||
for entry in std::fs::read_dir(base_path)? {
|
||||
let entry = entry?;
|
||||
let file_path = entry.path().join("bin");
|
||||
let contents = std::fs::read_to_string(file_path)?;
|
||||
if let Ok(dir) = std::fs::read_dir(base_path) {
|
||||
for entry in dir {
|
||||
if let Ok(entry) = entry {
|
||||
let file_path = entry.path().join("bin");
|
||||
|
||||
let entry = entry.path().join(contents);
|
||||
jre_paths.insert(entry);
|
||||
if let Ok(contents) =
|
||||
std::fs::read_to_string(file_path.clone())
|
||||
{
|
||||
let entry = entry.path().join(contents);
|
||||
jre_paths.insert(entry);
|
||||
} else {
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
let file_path = file_path.join(JAVA_BIN);
|
||||
jre_paths.insert(file_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,26 +237,27 @@ async fn get_all_autoinstalled_jre_path() -> Result<HashSet<PathBuf>, JREError>
|
||||
|
||||
// Gets all JREs from the PATH env variable
|
||||
#[tracing::instrument]
|
||||
async fn get_all_jre_path() -> Result<HashSet<PathBuf>, JREError> {
|
||||
async fn get_all_jre_path() -> HashSet<PathBuf> {
|
||||
// Iterate over values in PATH variable, where accessible JREs are referenced
|
||||
let paths = env::var("PATH")?;
|
||||
Ok(env::split_paths(&paths).collect())
|
||||
let paths =
|
||||
env::var("PATH").map(|x| env::split_paths(&x).collect::<HashSet<_>>());
|
||||
paths.unwrap_or_else(|_| HashSet::new())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[allow(dead_code)]
|
||||
const JAVA_BIN: &str = "javaw.exe";
|
||||
pub const JAVA_BIN: &str = "javaw.exe";
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[allow(dead_code)]
|
||||
const JAVA_BIN: &str = "java";
|
||||
pub const JAVA_BIN: &str = "java";
|
||||
|
||||
// For each example filepath in 'paths', perform check_java_at_filepath, checking each one concurrently
|
||||
// and returning a JavaVersion for every valid path that points to a java bin
|
||||
#[tracing::instrument]
|
||||
pub async fn check_java_at_filepaths(
|
||||
paths: HashSet<PathBuf>,
|
||||
) -> Result<HashSet<JavaVersion>, JREError> {
|
||||
) -> HashSet<JavaVersion> {
|
||||
let jres = stream::iter(paths.into_iter())
|
||||
.map(|p: PathBuf| {
|
||||
tokio::task::spawn(async move { check_java_at_filepath(&p).await })
|
||||
@@ -248,8 +266,7 @@ pub async fn check_java_at_filepaths(
|
||||
.collect::<Vec<_>>()
|
||||
.await;
|
||||
|
||||
let jres: Result<Vec<_>, JoinError> = jres.into_iter().collect();
|
||||
Ok(jres?.into_iter().flatten().collect())
|
||||
jres.into_iter().flat_map(|x| x.ok()).flatten().collect()
|
||||
}
|
||||
|
||||
// For example filepath 'path', attempt to resolve it and get a Java version at this path
|
||||
@@ -380,19 +397,3 @@ pub enum JREError {
|
||||
#[error("Error getting launcher sttae")]
|
||||
StateError,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::extract_java_majorminor_version;
|
||||
|
||||
#[test]
|
||||
pub fn java_version_parsing() {
|
||||
assert_eq!(extract_java_majorminor_version("1.8").unwrap(), (1, 8));
|
||||
assert_eq!(extract_java_majorminor_version("17.0.6").unwrap(), (1, 17));
|
||||
assert_eq!(extract_java_majorminor_version("20").unwrap(), (1, 20));
|
||||
assert_eq!(
|
||||
extract_java_majorminor_version("1.8.0_361").unwrap(),
|
||||
(1, 8)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "theseus_cli"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
authors = ["Jai A <jaiagr+gpg@pm.me>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
"floating-vue": "^2.0.0-beta.20",
|
||||
"mixpanel-browser": "^2.47.0",
|
||||
"ofetch": "^1.0.1",
|
||||
"omorphia": "^0.4.28",
|
||||
"omorphia": "^0.4.31",
|
||||
"pinia": "^2.1.3",
|
||||
"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",
|
||||
|
||||
Generated
+15
-4
@@ -17,11 +17,14 @@ dependencies:
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1
|
||||
omorphia:
|
||||
specifier: ^0.4.28
|
||||
version: 0.4.28
|
||||
specifier: ^0.4.31
|
||||
version: 0.4.31
|
||||
pinia:
|
||||
specifier: ^2.1.3
|
||||
version: 2.1.3(vue@3.3.4)
|
||||
tauri-plugin-window-state-api:
|
||||
specifier: github:tauri-apps/tauri-plugin-window-state#v1
|
||||
version: github.com/tauri-apps/tauri-plugin-window-state/56fd671f8d5ac2d8b826a358af486f220a125c3d
|
||||
vite-svg-loader:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
@@ -1333,8 +1336,8 @@ packages:
|
||||
ufo: 1.1.2
|
||||
dev: false
|
||||
|
||||
/omorphia@0.4.28:
|
||||
resolution: {integrity: sha512-ZTUgBD3ZL+aymS7u5pLaPo8I5FUI8fkoz2dZLtAS5ksGRI5wrWkwIi/kxjpC95A2oDxNQvZaylfwUTK3Z6a2Sw==}
|
||||
/omorphia@0.4.31:
|
||||
resolution: {integrity: sha512-xeb9bD42VFRDKCkKz678hBYCIS//Atd4/hx6/YmboJLMEIjIJfS2Ocf9G53G52XkfS4DWs9CIzKz71NDh86kxQ==}
|
||||
dependencies:
|
||||
dayjs: 1.11.7
|
||||
floating-vue: 2.0.0-beta.20(vue@3.3.4)
|
||||
@@ -1787,3 +1790,11 @@ packages:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
github.com/tauri-apps/tauri-plugin-window-state/56fd671f8d5ac2d8b826a358af486f220a125c3d:
|
||||
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-window-state/tar.gz/56fd671f8d5ac2d8b826a358af486f220a125c3d}
|
||||
name: tauri-plugin-window-state-api
|
||||
version: 0.0.0
|
||||
dependencies:
|
||||
'@tauri-apps/api': 1.3.0
|
||||
dev: false
|
||||
@@ -18,7 +18,7 @@ theseus = { path = "../../theseus", features = ["tauri"] }
|
||||
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
tauri = { version = "1.3", features = ["devtools", "dialog", "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.3", features = ["app-all", "devtools", "dialog", "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" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
@@ -39,6 +39,8 @@ tracing-error = "0.1"
|
||||
sentry = "0.30"
|
||||
sentry-rust-minidump = "0.5"
|
||||
|
||||
window-shadows = "0.2.1"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
cocoa = "0.24.1"
|
||||
objc = "0.2.7"
|
||||
|
||||
@@ -10,22 +10,22 @@ pub async fn jre_get_all_jre() -> Result<Vec<JavaVersion>> {
|
||||
Ok(jre::get_all_jre().await?)
|
||||
}
|
||||
|
||||
// Finds the isntallation of Java 7, if it exists
|
||||
// Finds the installation of Java 8, if it exists
|
||||
#[tauri::command]
|
||||
pub async fn jre_find_jre_8_jres() -> Result<Vec<JavaVersion>> {
|
||||
Ok(jre::find_java8_jres().await?)
|
||||
Ok(jre::find_filtered_jres("1.8").await?)
|
||||
}
|
||||
|
||||
// finds the installation of Java 17, if it exists
|
||||
#[tauri::command]
|
||||
pub async fn jre_find_jre_17_jres() -> Result<Vec<JavaVersion>> {
|
||||
Ok(jre::find_java17_jres().await?)
|
||||
Ok(jre::find_filtered_jres("1.17").await?)
|
||||
}
|
||||
|
||||
// Finds the highest version of Java 18+, if it exists
|
||||
#[tauri::command]
|
||||
pub async fn jre_find_jre_18plus_jres() -> Result<Vec<JavaVersion>> {
|
||||
Ok(jre::find_java18plus_jres().await?)
|
||||
Ok(jre::find_filtered_jres("1.18").await?)
|
||||
}
|
||||
|
||||
// Autodetect Java globals, by searching the users computer.
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
|
||||
use theseus::prelude::*;
|
||||
|
||||
use tauri::{Manager, WindowEvent};
|
||||
use tauri::Manager;
|
||||
|
||||
use window_shadows::set_shadow;
|
||||
|
||||
use tracing_error::ErrorLayer;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
@@ -78,13 +81,21 @@ fn main() {
|
||||
{
|
||||
builder = builder.setup(|app| {
|
||||
let win = app.get_window("main").unwrap();
|
||||
win.set_decorations(false);
|
||||
win.set_decorations(false).unwrap();
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
builder = builder.setup(|app| {
|
||||
let win = app.get_window("main").unwrap();
|
||||
set_shadow(&win, true).unwrap();
|
||||
Ok(())
|
||||
});
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use tauri::WindowEvent;
|
||||
|
||||
builder = builder
|
||||
.setup(|app| {
|
||||
use api::window_ext::WindowExt;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"package": {
|
||||
"productName": "Modrinth App",
|
||||
"version": "0.0.1"
|
||||
"version": "0.2.0"
|
||||
},
|
||||
"tauri": {
|
||||
"allowlist": {
|
||||
@@ -40,6 +40,9 @@
|
||||
},
|
||||
"os": {
|
||||
"all": true
|
||||
},
|
||||
"app": {
|
||||
"all": true
|
||||
}
|
||||
},
|
||||
"macOSPrivateApi": true,
|
||||
@@ -72,7 +75,7 @@
|
||||
"windows": {
|
||||
"certificateThumbprint": null,
|
||||
"digestAlgorithm": "sha256",
|
||||
"timestampUrl": ""
|
||||
"timestampUrl": "http://timestamp.digicert.com"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
@@ -92,7 +95,7 @@
|
||||
"height": 650,
|
||||
"resizable": true,
|
||||
"title": "Modrinth App",
|
||||
"width": 1140,
|
||||
"width": 1280,
|
||||
"minHeight": 630,
|
||||
"minWidth": 1100
|
||||
}
|
||||
|
||||
+35
-26
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { handleError, onMounted, ref, watch } from 'vue'
|
||||
import { ref, watch } from 'vue'
|
||||
import { RouterView, RouterLink, useRouter } from 'vue-router'
|
||||
import {
|
||||
HomeIcon,
|
||||
@@ -26,35 +26,20 @@ import { type } from '@tauri-apps/api/os'
|
||||
import { appWindow } from '@tauri-apps/api/window'
|
||||
import { isDev } from '@/helpers/utils.js'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
import { saveWindowState, StateFlags } from 'tauri-plugin-window-state-api'
|
||||
import OnboardingModal from '@/components/OnboardingModal.vue'
|
||||
import { getVersion } from '@tauri-apps/api/app'
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
const isLoading = ref(true)
|
||||
onMounted(async () => {
|
||||
const { settings, collapsed_navigation } = await get().catch(handleError)
|
||||
themeStore.setThemeState(settings)
|
||||
themeStore.collapsedNavigation = collapsed_navigation
|
||||
|
||||
await warning_listener((e) =>
|
||||
notificationsWrapper.value.addNotification({
|
||||
title: 'Warning',
|
||||
text: e.message,
|
||||
type: 'warn',
|
||||
})
|
||||
)
|
||||
|
||||
if ((await type()) === 'Darwin') {
|
||||
document.getElementsByTagName('html')[0].classList.add('mac')
|
||||
} else {
|
||||
document.getElementsByTagName('html')[0].classList.add('windows')
|
||||
}
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
initialize: async () => {
|
||||
isLoading.value = false
|
||||
const { theme, opt_out_analytics, collapsed_navigation, advanced_rendering } = await get()
|
||||
const { theme, opt_out_analytics, collapsed_navigation, advanced_rendering, onboarded } =
|
||||
await get()
|
||||
const dev = await isDev()
|
||||
const version = await getVersion()
|
||||
|
||||
themeStore.setThemeState(theme)
|
||||
themeStore.collapsedNavigation = collapsed_navigation
|
||||
@@ -64,10 +49,16 @@ defineExpose({
|
||||
if (opt_out_analytics) {
|
||||
mixpanel.opt_out_tracking()
|
||||
}
|
||||
mixpanel.track('Launched')
|
||||
mixpanel.track('Launched', { version, dev, onboarded })
|
||||
|
||||
if (!dev) document.addEventListener('contextmenu', (event) => event.preventDefault())
|
||||
|
||||
if ((await type()) === 'Darwin') {
|
||||
document.getElementsByTagName('html')[0].classList.add('mac')
|
||||
} else {
|
||||
document.getElementsByTagName('html')[0].classList.add('windows')
|
||||
}
|
||||
|
||||
await warning_listener((e) =>
|
||||
notificationsWrapper.value.addNotification({
|
||||
title: 'Warning',
|
||||
@@ -119,15 +110,23 @@ document.querySelector('body').addEventListener('click', function (e) {
|
||||
target = target.parentElement
|
||||
}
|
||||
})
|
||||
|
||||
const accounts = ref(null)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SplashScreen v-if="isLoading" app-loading />
|
||||
<div v-else class="container">
|
||||
<suspense>
|
||||
<OnboardingModal ref="testModal" :accounts="accounts" />
|
||||
</suspense>
|
||||
<div class="nav-container" :class="{ expanded: !themeStore.collapsedNavigation }">
|
||||
<div class="nav-section">
|
||||
<suspense>
|
||||
<AccountsCard ref="accounts" :expanded="!themeStore.collapsedNavigation" />
|
||||
<AccountsCard
|
||||
ref="accounts"
|
||||
:mode="themeStore.collapsedNavigation ? 'small' : 'expanded'"
|
||||
/>
|
||||
</suspense>
|
||||
<div class="pages-list">
|
||||
<RouterLink
|
||||
@@ -215,7 +214,16 @@ document.querySelector('body').addEventListener('click', function (e) {
|
||||
<Button class="titlebar-button" icon-only @click="() => appWindow.toggleMaximize()">
|
||||
<MaximizeIcon />
|
||||
</Button>
|
||||
<Button class="titlebar-button close" icon-only @click="() => appWindow.close()">
|
||||
<Button
|
||||
class="titlebar-button close"
|
||||
icon-only
|
||||
@click="
|
||||
() => {
|
||||
saveWindowState(StateFlags.ALL)
|
||||
appWindow.close()
|
||||
}
|
||||
"
|
||||
>
|
||||
<XIcon />
|
||||
</Button>
|
||||
</section>
|
||||
@@ -250,10 +258,11 @@ document.querySelector('body').addEventListener('click', function (e) {
|
||||
}
|
||||
|
||||
.window-controls {
|
||||
z-index: 20;
|
||||
display: none;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
gap: 0.25rem;
|
||||
|
||||
.titlebar-button {
|
||||
display: flex;
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB |
-1
@@ -4,4 +4,3 @@ export { default as KoFiIcon } from './kofi.svg'
|
||||
export { default as PatreonIcon } from './patreon.svg'
|
||||
export { default as PaypalIcon } from './paypal.svg'
|
||||
export { default as OpenCollectiveIcon } from './opencollective.svg'
|
||||
export { default as Default } from './default.png'
|
||||
@@ -0,0 +1,336 @@
|
||||
<template>
|
||||
<Modal
|
||||
ref="onboardingModal"
|
||||
:header="['Getting started', 'Sign into Minecraft', 'Install java'][page - 1]"
|
||||
:closable="false"
|
||||
>
|
||||
<div class="modal-body">
|
||||
<div v-if="page === 1" key="1" class="content">
|
||||
<svg
|
||||
class="app-logo"
|
||||
viewBox="0 0 1215 175"
|
||||
xml:space="preserve"
|
||||
style="
|
||||
fill-rule: evenodd;
|
||||
clip-rule: evenodd;
|
||||
stroke-linejoin: round;
|
||||
stroke-miterlimit: 2;
|
||||
"
|
||||
color="var(--color-contrast)"
|
||||
>
|
||||
<g transform="matrix(1,0,0,1,-3395.45,-1175)">
|
||||
<g transform="matrix(0.632704,0,0,0.161619,3395.45,1175)">
|
||||
<rect
|
||||
id="modrinth-app-logo"
|
||||
x="0"
|
||||
y="0"
|
||||
width="1920"
|
||||
height="1080"
|
||||
style="fill: none"
|
||||
/>
|
||||
<g id="modrinth-app-logo1">
|
||||
<g transform="matrix(1.26353,0,0,3.23025,-514.757,-837.171)">
|
||||
<g transform="matrix(1.25087,0,0,1.91545,-240.84,-608.008)">
|
||||
<g transform="matrix(0.273005,0,0,0.273005,523.782,459.389)">
|
||||
<path
|
||||
d="M1053.02,205.51C1088.61,205.51 1117.29,215.61 1138,236.32C1158.72,257.57 1169.34,288.37 1169.34,329.8L1169.34,492.33L1102.94,492.33L1102.94,338.3C1102.94,313.34 1097.64,294.75 1086.48,282C1075.33,269.78 1059.93,263.4 1039.21,263.4C1016.91,263.4 998.84,270.85 985.56,285.19C972.29,300.06 965.38,321.3 965.38,348.39L965.38,492.33L898.98,492.33L898.98,338.3C898.98,313.34 893.68,294.75 882.52,282C871.37,269.78 855.96,263.4 835.25,263.4C812.41,263.4 794.88,270.85 781.6,285.19C768.33,299.53 761.42,320.77 761.42,348.39L761.42,492.33L695.02,492.33L695.02,208.7L758.23,208.7L758.23,244.82C768.86,232.07 782.13,222.52 798.07,215.61C814,208.71 831.53,205.51 851.18,205.51C872.43,205.51 891.55,209.23 908.02,217.2C924.48,225.7 937.23,237.38 946.79,252.79C958.48,237.91 973.35,226.23 991.94,217.73C1010.53,209.76 1030.71,205.51 1053.02,205.51ZM1382.86,496.05C1354.18,496.05 1328.16,489.68 1305.32,477.46C1282.84,465.588 1264.22,447.523 1251.67,425.41C1238.39,403.63 1232.02,378.67 1232.02,350.51C1232.02,322.37 1238.39,297.41 1251.67,275.63C1264.39,253.783 1282.98,235.93 1305.32,224.1C1328.16,211.89 1354.18,205.51 1382.86,205.51C1412.08,205.51 1438.1,211.89 1460.94,224.11C1483.78,236.32 1501.84,253.85 1515.12,275.63C1527.87,297.4 1534.24,322.37 1534.24,350.52C1534.24,378.67 1527.87,403.63 1515.12,425.41C1501.84,447.71 1483.78,465.24 1460.94,477.46C1438.1,489.68 1412.08,496.06 1382.86,496.06L1382.86,496.05ZM1382.86,439.22C1407.3,439.22 1427.48,431.25 1443.41,414.79C1459.35,398.32 1467.31,377.07 1467.31,350.52C1467.31,323.96 1459.35,302.72 1443.41,286.25C1427.48,269.78 1407.3,261.82 1382.86,261.82C1358.43,261.82 1338.25,269.78 1322.84,286.25C1306.91,302.71 1298.94,323.96 1298.94,350.52C1298.94,377.07 1306.91,398.32 1322.84,414.79C1338.24,431.25 1358.44,439.22 1382.86,439.22ZM1874.18,98.22L1874.18,492.33L1810.44,492.33L1810.44,455.68C1799.56,468.819 1785.73,479.196 1770.07,485.96C1753.61,492.86 1736.07,496.06 1716.42,496.06C1689.34,496.06 1664.9,490.21 1643.12,477.99C1621.35,465.78 1603.82,448.78 1591.6,426.47C1579.39,404.69 1573.01,379.2 1573.01,350.52C1573.01,321.84 1579.39,296.34 1591.61,274.56C1603.82,252.79 1621.35,235.79 1643.13,223.57C1664.9,211.36 1689.33,205.51 1716.43,205.51C1735.02,205.51 1752.54,208.71 1767.95,215.07C1783.28,221.396 1796.92,231.222 1807.78,243.76L1807.78,98.22L1874.18,98.22ZM1724.39,439.22C1740.33,439.22 1754.67,435.5 1767.42,428.06C1780.16,421.16 1790.25,410.54 1797.69,397.26C1805.13,383.98 1808.84,368.05 1808.84,350.52C1808.84,332.99 1805.13,317.06 1797.69,303.78C1790.25,290.5 1780.16,279.88 1767.42,272.44C1754.67,265.54 1740.32,261.82 1724.39,261.82C1708.46,261.82 1694.12,265.53 1681.37,272.44C1668.62,279.87 1658.53,290.5 1651.09,303.78C1643.66,317.06 1639.94,332.98 1639.94,350.52C1639.94,368.05 1643.66,383.98 1651.09,397.26C1658.53,410.54 1668.62,421.16 1681.37,428.06C1694.12,435.5 1708.46,439.22 1724.39,439.22ZM2022.9,250.13C2042.02,220.39 2075.48,205.51 2123.82,205.51L2123.82,268.72C2118.75,267.715 2113.59,267.18 2108.42,267.12C2082.39,267.12 2062.2,274.56 2047.86,289.44C2033.52,304.84 2026.08,326.62 2026.08,354.77L2026.08,492.33L1959.69,492.33L1959.69,208.7L2022.89,208.7L2022.89,250.13L2022.9,250.13ZM2178.52,208.7L2244.92,208.7L2244.92,492.33L2178.52,492.33L2178.52,208.7ZM2211.99,161.96C2199.77,161.96 2189.68,158.24 2181.71,150.28C2173.8,143.08 2169.35,132.817 2169.5,122.12C2169.5,110.97 2173.75,101.41 2181.71,93.44C2189.68,86.01 2199.77,82.29 2211.99,82.29C2224.2,82.29 2234.29,86.01 2242.26,92.91C2250.23,100.35 2254.48,109.38 2254.48,120.53C2254.48,132.22 2250.76,141.78 2242.79,149.74C2234.83,157.71 2224.2,161.96 2211.99,161.96ZM2491.37,205.51C2526.96,205.51 2555.64,216.14 2577.42,236.85C2599.2,257.57 2609.82,288.9 2609.82,329.8L2609.82,492.33L2543.42,492.33L2543.42,338.3C2543.42,313.34 2537.58,294.75 2525.9,282C2514.21,269.78 2497.75,263.4 2475.97,263.4C2451.54,263.4 2432.42,270.85 2418.07,285.19C2403.73,300.06 2396.83,321.3 2396.83,348.92L2396.83,492.33L2330.43,492.33L2330.43,208.7L2393.64,208.7L2393.64,245.35C2404.8,232.07 2418.61,222.51 2435.07,215.61C2451.54,208.71 2470.66,205.51 2491.37,205.51ZM2863.18,476.93C2854.87,483.572 2845.29,488.451 2835.03,491.27C2823.44,494.492 2811.46,496.101 2799.43,496.05C2768.1,496.05 2744.2,488.08 2727.2,471.62C2710.2,455.15 2701.7,431.78 2701.7,400.45L2701.7,263.94L2654.97,263.94L2654.97,210.83L2701.71,210.83L2701.71,146.03L2768.11,146.03L2768.11,210.83L2844.06,210.83L2844.06,263.94L2768.1,263.94L2768.1,398.85C2768.1,412.66 2771.29,423.28 2778.2,430.19C2785.1,437.63 2794.66,441.34 2807.4,441.34C2822.28,441.34 2834.5,437.63 2844.59,429.66L2863.18,476.93ZM3077.23,205.51C3112.82,205.51 3141.5,216.14 3163.28,236.85C3185.05,257.57 3195.68,288.9 3195.68,329.8L3195.68,492.33L3129.28,492.33L3129.28,338.3C3129.28,313.34 3123.44,294.75 3111.75,282C3100.07,269.78 3083.6,263.4 3061.83,263.4C3037.39,263.4 3018.27,270.85 3003.93,285.19C2989.59,300.06 2982.69,321.3 2982.69,348.92L2982.69,492.33L2916.29,492.33L2916.29,98.23L2982.69,98.23L2982.69,24Line truncated
|
||||
style="fill: currentColor; fill-rule: nonzero"
|
||||
/>
|
||||
</g>
|
||||
<g transform="matrix(0.273005,0,0,0.273005,523.782,459.389)">
|
||||
<path
|
||||
d="M29,424.4L217.2,311.45L200.05,265.97L253.8,210.76L321.73,196.12L341.4,220.33L310.08,252.05L282.78,260.65L263.26,280.7L272.82,307.3L292.22,327.9L319.58,320.62L339.05,299.24L381.56,285.77L394.23,314.27L350.36,368.05L276.86,391.32L243.89,354.62L55.06,467.94C46.1,456.41 35.67,440.08 29,424.4ZM572.03,194.15L422.53,234.47C430.77,256.39 433.48,269.27 435.76,283.47L584.99,243.21C582.61,227.27 578.34,211.04 572.03,194.15Z"
|
||||
style="fill: var(--color-brand)"
|
||||
/>
|
||||
<path
|
||||
d="M51.28,316.13C61.87,441.13 166.82,539.43 294.55,539.43C391.06,539.43 474.57,483.31 514.18,401.97L562.79,418.8C516.01,520.14 413.44,590.55 294.55,590.55C138.6,590.55 10.71,469.38 0,316.13L51.28,316.13ZM0.78,265.24C15.86,116.36 141.73,0 294.56,0C457.53,0 589.84,132.31 589.84,295.28C589.84,321.42 586.44,346.77 580.04,370.91L531.56,354.13C536.324,334.876 538.725,315.114 538.71,295.28C538.71,160.53 429.31,51.13 294.56,51.13C169.98,51.13 67.07,144.63 52.24,265.24L0.78,265.24Z"
|
||||
style="fill: var(--color-brand)"
|
||||
/>
|
||||
<path
|
||||
d="M293.77,153.17C215.28,153.24 151.57,217 151.57,295.51C151.57,374.07 215.36,437.85 293.92,437.85C297.9,437.85 301.85,437.69 305.75,437.36L319.97,487.12C311.335,488.282 302.632,488.864 293.92,488.86C187.2,488.86 100.56,402.22 100.56,295.51C100.56,188.79 187.2,102.16 293.92,102.16C296.56,102.16 299.2,102.21 301.82,102.32L293.77,153.17ZM351.97,111.04C430.36,135.71 487.27,209.02 487.27,295.51C487.27,375.58 438.5,444.34 369.07,473.69L354.9,424.14C402.98,401.29 436.26,352.25 436.26,295.51C436.26,234.52 397.82,182.44 343.87,162.19L351.97,111.04Z"
|
||||
style="fill: var(--color-brand)"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1.25498,0,0,1.92174,1126.78,-2077.58)">
|
||||
<path
|
||||
d="M411.597,1355.36L411.597,1339.8L410.589,1336.49L410.589,1309.28C410.589,1304 409.005,1299.89 405.837,1296.96C402.669,1294.04 397.869,1292.57 391.437,1292.57C387.117,1292.57 382.869,1293.24 378.693,1294.59C374.517,1295.93 370.989,1297.8 368.109,1300.2L361.053,1287.1C365.181,1283.93 370.101,1281.56 375.813,1279.97C381.525,1278.39 387.453,1277.6 393.597,1277.6C404.733,1277.6 413.349,1280.26 419.445,1285.59C425.541,1290.91 428.589,1299.15 428.589,1310.28L428.589,1355.36L411.597,1355.36ZM387.405,1356.36C381.645,1356.36 376.605,1355.38 372.285,1353.41C367.965,1351.44 364.629,1348.71 362.277,1345.2C359.925,1341.7 358.749,1337.74 358.749,1333.32C358.749,1329 359.781,1325.12 361.845,1321.66C363.909,1318.2 367.293,1315.47 371.997,1313.45C376.701,1311.43 382.941,1310.43 390.717,1310.43L413.037,1310.43L413.037,1322.38L392.013,1322.38C385.869,1322.38 381.741,1323.36 379.629,1325.33C377.517,1327.3 376.461,1329.72 376.461,1332.6C376.461,1335.87 377.757,1338.46 380.349,1340.38C382.941,1342.3 386.541,1343.26 391.149,1343.26C395.565,1343.26 399.525,1342.25 403.029,1340.24C406.533,1338.22 409.053,1335.24 410.589,1331.31L413.613,1342.11C411.885,1346.62 408.789,1350.12 404.325,1352.62C399.861,1355.12 394.221,1356.36 387.405,1356.36Z"
|
||||
style="fill: var(--color-brand); fill-rule: nonzero"
|
||||
/>
|
||||
<path
|
||||
d="M494.253,1356.36C488.013,1356.36 482.325,1354.92 477.189,1352.04C472.053,1349.16 467.973,1344.82 464.949,1339.01C461.925,1333.2 460.413,1325.84 460.413,1316.91C460.413,1307.88 461.877,1300.49 464.805,1294.73C467.733,1288.97 471.741,1284.67 476.829,1281.84C481.917,1279.01 487.725,1277.6 494.253,1277.6C501.837,1277.6 508.533,1279.23 514.341,1282.49C520.149,1285.76 524.757,1290.32 528.165,1296.17C531.573,1302.03 533.277,1308.94 533.277,1316.91C533.277,1324.88 531.573,1331.81 528.165,1337.71C524.757,1343.62 520.149,1348.2 514.341,1351.47C508.533,1354.73 501.837,1356.36 494.253,1356.36ZM451.629,1383.29L451.629,1278.46L468.765,1278.46L468.765,1296.6L468.189,1317.05L469.629,1337.5L469.629,1383.29L451.629,1383.29ZM492.237,1340.95C496.557,1340.95 500.421,1340 503.829,1338.08C507.237,1336.15 509.949,1333.37 511.965,1329.72C513.981,1326.08 514.989,1321.8 514.989,1316.91C514.989,1311.91 513.981,1307.62 511.965,1304.02C509.949,1300.42 507.237,1297.66 503.829,1295.74C500.421,1293.82 496.557,1292.86 492.237,1292.86C487.917,1292.86 484.029,1293.82 480.573,1295.74C477.117,1297.66 474.381,1300.42 472.365,1304.02C470.349,1307.62 469.341,1311.91 469.341,1316.91C469.341,1321.8 470.349,1326.08 472.365,1329.72C474.381,1333.37 477.117,1336.15 480.573,1338.08C484.029,1340 487.917,1340.95 492.237,1340.95Z"
|
||||
style="fill: var(--color-brand); fill-rule: nonzero"
|
||||
/>
|
||||
<path
|
||||
d="M593.037,1356.36C586.797,1356.36 581.109,1354.92 575.973,1352.04C570.837,1349.16 566.757,1344.82 563.733,1339.01C560.709,1333.2 559.197,1325.84 559.197,1316.91C559.197,1307.88 560.661,1300.49 563.589,1294.73C566.517,1288.97 570.525,1284.67 575.613,1281.84C580.701,1279.01 586.509,1277.6 593.037,1277.6C600.621,1277.6 607.317,1279.23 613.125,1282.49C618.933,1285.76 623.541,1290.32 626.949,1296.17C630.357,1302.03 632.061,1308.94 632.061,1316.91C632.061,1324.88 630.357,1331.81 626.949,1337.71C623.541,1343.62 618.933,1348.2 613.125,1351.47C607.317,1354.73 600.621,1356.36 593.037,1356.36ZM550.413,1383.29L550.413,1278.46L567.549,1278.46L567.549,1296.6L566.973,1317.05L568.413,1337.5L568.413,1383.29L550.413,1383.29ZM591.021,1340.95C595.341,1340.95 599.205,1340 602.613,1338.08C606.021,1336.15 608.733,1333.37 610.749,1329.72C612.765,1326.08 613.773,1321.8 613.773,1316.91C613.773,1311.91 612.765,1307.62 610.749,1304.02C608.733,1300.42 606.021,1297.66 602.613,1295.74C599.205,1293.82 595.341,1292.86 591.021,1292.86C586.701,1292.86 582.813,1293.82 579.357,1295.74C575.901,1297.66 573.165,1300.42 571.149,1304.02C569.133,1307.62 568.125,1311.91 568.125,1316.91C568.125,1321.8 569.133,1326.08 571.149,1329.72C573.165,1333.37 575.901,1336.15 579.357,1338.08C582.813,1340 586.701,1340.95 591.021,1340.95Z"
|
||||
style="fill: var(--color-brand); fill-rule: nonzero"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<div class="markdown-body">
|
||||
<p>
|
||||
Welcome to the Modrinth App: a desktop application that allows you to easily install and
|
||||
manage Minecraft modpacks.
|
||||
</p>
|
||||
<p>
|
||||
Please keep in mind that this is an <strong>early alpha</strong>. Many features are
|
||||
subject to change and there may be various issues you may come across.
|
||||
</p>
|
||||
<p>
|
||||
If you do come across any issues or have a feature request, please report it on our
|
||||
<a href="https://github.com/modrinth/theseus/issues">GitHub Issues page</a>. Please make
|
||||
sure that your issue has not already been reported before creating a new issue!
|
||||
</p>
|
||||
<p>
|
||||
For support, please join our <a href="https://discord.gg/EUHuJHt">Discord</a> and select
|
||||
the Test Subject role. Ask your questions in the relevant thread and we will do our best
|
||||
to help you!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="page === 2" key="2" class="content">
|
||||
<div class="markdown-body">
|
||||
<p>
|
||||
The Modrinth App requires a Minecraft account. Click the sign in button below and you
|
||||
will be prompted to log into your Microsoft account.
|
||||
</p>
|
||||
<p>
|
||||
<span>
|
||||
If you do not have a Minecraft account already, visit
|
||||
<a href="https://www.minecraft.net/en-us/store/minecraft-java-bedrock-edition-pc">
|
||||
the Minecraft website
|
||||
</a>
|
||||
to purchase the game.
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="center-grow">
|
||||
<AccountsCard ref="accountsCard" mode="isolated" @change="fetchSettings" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="page === 3" key="3" class="content">
|
||||
<div class="markdown-body">
|
||||
<p>
|
||||
The Modrinth App requires a Java installation to run Minecraft. You can let us
|
||||
automatically install Java for you or select an existing installation below.
|
||||
</p>
|
||||
</div>
|
||||
<Chips
|
||||
v-model="javaSelectionType"
|
||||
:items="['automatically install', 'use existing installation']"
|
||||
/>
|
||||
<div v-if="javaSelectionType === 'use existing installation'" class="settings-group">
|
||||
<h3>Java location</h3>
|
||||
<JavaSelector v-model="settings.java_globals.JAVA_17" compact />
|
||||
</div>
|
||||
<div v-else class="center-grow">
|
||||
<div v-if="javaLoadingEvent">
|
||||
<ProgressBar :progress="Math.floor(javaLoadingEvent.fraction * 100)" />
|
||||
<div class="row">
|
||||
{{ Math.floor(javaLoadingEvent.fraction * 100) }}% {{ javaLoadingEvent.message }}
|
||||
</div>
|
||||
</div>
|
||||
<Button v-else @click="autoInstallJava"> <PlayIcon /> Begin java installation </Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="button-row">
|
||||
<Button v-if="page !== 1" @click="page--"> Back </Button>
|
||||
<div class="page-indicator">
|
||||
<span class="circle" :class="{ active: page === 1 }" @click="page = 1" />
|
||||
<span class="circle" :class="{ active: page === 2 }" @click="page = 2" />
|
||||
<span class="circle" :class="{ active: page === 3 }" @click="page = 3" />
|
||||
</div>
|
||||
<Button class="forward" color="primary" @click="pageTurn()">
|
||||
{{ page === 3 ? 'Finish' : 'Continue' }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { Button, Chips, Modal, PlayIcon } from 'omorphia'
|
||||
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import AccountsCard from '@/components/ui/AccountsCard.vue'
|
||||
import JavaSelector from '@/components/ui/JavaSelector.vue'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { get, set } from '@/helpers/settings.js'
|
||||
import { auto_install_java, get_jre } from '@/helpers/jre.js'
|
||||
import { loading_listener } from '@/helpers/events.js'
|
||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
|
||||
const onboardingModal = ref(null)
|
||||
const accountsCard = ref(null)
|
||||
const page = ref(1)
|
||||
|
||||
const props = defineProps({
|
||||
accounts: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
})
|
||||
|
||||
async function fetchSettings() {
|
||||
const fetchSettings = await get().catch(handleError)
|
||||
|
||||
if (!fetchSettings.java_globals.JAVA_17)
|
||||
fetchSettings.java_globals.JAVA_17 = { path: '', version: '' }
|
||||
|
||||
settings.value = fetchSettings
|
||||
if (props.accounts) {
|
||||
await props.accounts.refreshValues()
|
||||
}
|
||||
}
|
||||
const settings = ref(null)
|
||||
await fetchSettings()
|
||||
|
||||
watch([settings, settings.value], async () => {
|
||||
const setSettings = JSON.parse(JSON.stringify(settings.value))
|
||||
|
||||
if (setSettings.java_globals.JAVA_17?.path === '') {
|
||||
setSettings.java_globals.JAVA_17 = undefined
|
||||
}
|
||||
if (setSettings.java_globals.JAVA_17?.path) {
|
||||
setSettings.java_globals.JAVA_17.path = setSettings.java_globals.JAVA_17.path.replace(
|
||||
'java.exe',
|
||||
'javaw.exe'
|
||||
)
|
||||
}
|
||||
|
||||
await set(setSettings)
|
||||
if (accountsCard.value) {
|
||||
await accountsCard.value.refreshValues()
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (!settings.value.onboarded) {
|
||||
onboardingModal.value.show()
|
||||
}
|
||||
})
|
||||
|
||||
async function pageTurn() {
|
||||
if (page.value === 3) {
|
||||
settings.value.onboarded = true
|
||||
onboardingModal.value.hide()
|
||||
mixpanel.track('OnboardingFinish')
|
||||
return
|
||||
}
|
||||
page.value++
|
||||
mixpanel.track('OnboardingPage', { page: page.value })
|
||||
|
||||
if (accountsCard.value) {
|
||||
await accountsCard.value.refreshValues()
|
||||
}
|
||||
}
|
||||
|
||||
const javaSelectionType = ref('automatically install')
|
||||
|
||||
async function autoInstallJava() {
|
||||
const path = await auto_install_java(17).catch(handleError)
|
||||
if (!settings.value.java_globals) settings.value.java_globals = {}
|
||||
const version = await get_jre(path).catch(handleError)
|
||||
// weird vue bug, ignore
|
||||
settings.value.java_globals.JAVA_17 = version
|
||||
settings.value.java_globals.JAVA_17 = version
|
||||
mixpanel.track('OnboardingAutoInstallJava')
|
||||
}
|
||||
|
||||
const javaLoadingEvent = ref(null)
|
||||
const unlistenLoading = await loading_listener(async (event) => {
|
||||
if (event.event.type === 'java_download') {
|
||||
javaLoadingEvent.value = event
|
||||
if (!event.fraction) {
|
||||
javaLoadingEvent.value.fraction = 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
unlistenLoading()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.modal-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
padding: var(--gap-lg);
|
||||
|
||||
height: min(70vh, 450px);
|
||||
|
||||
h2 {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
|
||||
.center-grow {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-group {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.button-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.back {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.page-indicator {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
.circle {
|
||||
width: 0.75rem;
|
||||
height: 0.75rem;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 0.5rem;
|
||||
background-color: var(--color-base);
|
||||
transition: all 0.3s ease-in-out;
|
||||
cursor: pointer !important;
|
||||
|
||||
&.active {
|
||||
background-color: var(--color-brand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.forward {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.app-logo {
|
||||
width: 20rem;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -1,12 +1,16 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="mode !== 'isolated'"
|
||||
ref="button"
|
||||
class="button-base avatar-button"
|
||||
:class="{ expanded: expanded }"
|
||||
@click="toggle()"
|
||||
:class="{ expanded: mode === 'expanded' }"
|
||||
@click="showCard = !showCard"
|
||||
>
|
||||
<Avatar :size="expanded ? 'xs' : 'sm'" :src="selectedAccount?.profile_picture ?? ''" />
|
||||
<div v-show="expanded" class="avatar-text">
|
||||
<Avatar
|
||||
:size="mode === 'expanded' ? 'xs' : 'sm'"
|
||||
:src="selectedAccount ? `https://mc-heads.net/avatar/${selectedAccount.id}/128` : ''"
|
||||
/>
|
||||
<div v-show="mode === 'expanded'" class="avatar-text">
|
||||
<div class="text no-select">
|
||||
{{ selectedAccount ? selectedAccount.username : 'Offline' }}
|
||||
</div>
|
||||
@@ -17,9 +21,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<transition name="fade">
|
||||
<Card v-if="showCard" ref="card" class="account-card" :class="{ expanded: expanded }">
|
||||
<Card
|
||||
v-if="showCard || mode === 'isolated'"
|
||||
ref="card"
|
||||
class="account-card"
|
||||
:class="{ expanded: mode === 'expanded', isolated: mode === 'isolated' }"
|
||||
>
|
||||
<div v-if="selectedAccount" class="selected account">
|
||||
<Avatar size="xs" :src="selectedAccount.profile_picture" />
|
||||
<Avatar size="xs" :src="`https://mc-heads.net/avatar/${selectedAccount.id}/128`" />
|
||||
<div>
|
||||
<h4>{{ selectedAccount.username }}</h4>
|
||||
<p>Selected</p>
|
||||
@@ -37,7 +46,7 @@
|
||||
<div v-if="displayAccounts.length > 0" class="account-group">
|
||||
<div v-for="account in displayAccounts" :key="account.id" class="account-row">
|
||||
<Button class="option account" @click="setAccount(account)">
|
||||
<Avatar :src="account.profile_picture" class="icon" />
|
||||
<Avatar :src="`https://mc-heads.net/avatar/${account.id}/128`" class="icon" />
|
||||
<p>{{ account.username }}</p>
|
||||
</Button>
|
||||
<Button v-tooltip="'Log out'" icon-only @click="logout(account.id)">
|
||||
@@ -55,7 +64,7 @@
|
||||
|
||||
<script setup>
|
||||
import { Avatar, Button, Card, PlusIcon, TrashIcon, UsersIcon, LogInIcon } from 'omorphia'
|
||||
import { ref, defineProps, computed, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
|
||||
import {
|
||||
users,
|
||||
remove_user,
|
||||
@@ -68,51 +77,41 @@ import { handleError } from '@/store/state.js'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
|
||||
defineProps({
|
||||
expanded: {
|
||||
type: Boolean,
|
||||
mode: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: 'normal',
|
||||
},
|
||||
})
|
||||
|
||||
const settings = ref(await get().catch(handleError))
|
||||
const emit = defineEmits(['change'])
|
||||
|
||||
const appendProfiles = (accounts) => {
|
||||
return accounts.map((account) => {
|
||||
return {
|
||||
...account,
|
||||
profile_picture: `https://mc-heads.net/avatar/${account.id}/128`,
|
||||
}
|
||||
})
|
||||
const settings = ref({})
|
||||
const accounts = ref([])
|
||||
async function refreshValues() {
|
||||
settings.value = await get().catch(handleError)
|
||||
accounts.value = await users().catch(handleError)
|
||||
}
|
||||
|
||||
const accounts = ref(await users().then(appendProfiles).catch(handleError))
|
||||
defineExpose({
|
||||
refreshValues,
|
||||
})
|
||||
await refreshValues()
|
||||
|
||||
const displayAccounts = computed(() =>
|
||||
accounts.value.filter((account) => settings.value.default_user !== account.id)
|
||||
)
|
||||
|
||||
const selectedAccount = ref(
|
||||
const selectedAccount = computed(() =>
|
||||
accounts.value.find((account) => account.id === settings.value.default_user)
|
||||
)
|
||||
|
||||
const refreshValues = async () => {
|
||||
accounts.value = await users().then(appendProfiles).catch(handleError)
|
||||
selectedAccount.value = accounts.value.find(
|
||||
(account) => account.id === settings.value.default_user
|
||||
)
|
||||
}
|
||||
|
||||
let showCard = ref(false)
|
||||
let card = ref(null)
|
||||
let button = ref(null)
|
||||
|
||||
const setAccount = async (account) => {
|
||||
async function setAccount(account) {
|
||||
settings.value.default_user = account.id
|
||||
selectedAccount.value = account
|
||||
await set(settings.value).catch(handleError)
|
||||
emit('change')
|
||||
}
|
||||
|
||||
const login = async () => {
|
||||
async function login() {
|
||||
const url = await authenticate_begin_flow().catch(handleError)
|
||||
|
||||
const window = new WebviewWindow('loginWindow', {
|
||||
@@ -120,14 +119,6 @@ const login = async () => {
|
||||
url: url,
|
||||
})
|
||||
|
||||
window.once('tauri://created', function () {
|
||||
console.log('webview created')
|
||||
})
|
||||
|
||||
window.once('tauri://error', function (e) {
|
||||
console.log('webview error', e)
|
||||
})
|
||||
|
||||
const loggedIn = await authenticate_await_completion().catch(handleError)
|
||||
await setAccount(loggedIn)
|
||||
await refreshValues()
|
||||
@@ -141,14 +132,15 @@ const logout = async (id) => {
|
||||
if (!selectedAccount.value && accounts.value.length > 0) {
|
||||
await setAccount(accounts.value[0])
|
||||
await refreshValues()
|
||||
} else {
|
||||
emit('change')
|
||||
}
|
||||
mixpanel.track('AccountLogOut')
|
||||
}
|
||||
|
||||
const toggle = () => {
|
||||
showCard.value = !showCard.value
|
||||
}
|
||||
|
||||
let showCard = ref(false)
|
||||
let card = ref(null)
|
||||
let button = ref(null)
|
||||
const handleClickOutside = (event) => {
|
||||
const elements = document.elementsFromPoint(event.clientX, event.clientY)
|
||||
if (
|
||||
@@ -219,6 +211,12 @@ onBeforeUnmount(() => {
|
||||
&.expanded {
|
||||
left: 13.5rem;
|
||||
}
|
||||
|
||||
&.isolated {
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.accounts-title {
|
||||
|
||||
@@ -61,7 +61,6 @@ const hideContextMenu = () => {
|
||||
}
|
||||
|
||||
const optionClicked = (option) => {
|
||||
console.log('item check', item.value)
|
||||
emit('option-clicked', {
|
||||
item: item.value,
|
||||
option: option,
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<script setup>
|
||||
import { Button, Modal, XIcon, DownloadIcon, DropdownSelect, formatCategory } from 'omorphia'
|
||||
import { add_project_from_version as installMod } from '@/helpers/profile'
|
||||
import { defineExpose, ref } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { handleError, useTheming } from '@/store/state.js'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<JavaDetectionModal ref="detectJavaModal" @submit="(val) => emit('update:modelValue', val)" />
|
||||
<div class="toggle-setting">
|
||||
<div class="toggle-setting" :class="{ compact }">
|
||||
<input
|
||||
autocomplete="off"
|
||||
:disabled="props.disabled"
|
||||
@@ -18,10 +18,7 @@
|
||||
"
|
||||
/>
|
||||
<span class="installation-buttons">
|
||||
<Button
|
||||
:disabled="props.disabled"
|
||||
@click="$refs.detectJavaModal.show(props.version, props.modelValue)"
|
||||
>
|
||||
<Button :disabled="props.disabled" @click="autoDetect">
|
||||
<SearchIcon />
|
||||
Auto detect
|
||||
</Button>
|
||||
@@ -48,11 +45,12 @@
|
||||
|
||||
<script setup>
|
||||
import { Button, SearchIcon, PlayIcon, CheckIcon, XIcon, FolderSearchIcon } from 'omorphia'
|
||||
import { get_jre } from '@/helpers/jre.js'
|
||||
import { find_jre_17_jres, get_jre } from '@/helpers/jre.js'
|
||||
import { ref } from 'vue'
|
||||
import { open } from '@tauri-apps/api/dialog'
|
||||
import JavaDetectionModal from '@/components/ui/JavaDetectionModal.vue'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
import { handleError } from '@/store/state.js'
|
||||
|
||||
const props = defineProps({
|
||||
version: {
|
||||
@@ -74,6 +72,10 @@ const props = defineProps({
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
compact: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
@@ -117,6 +119,18 @@ async function handleJavaFileInput() {
|
||||
emit('update:modelValue', result)
|
||||
}
|
||||
}
|
||||
|
||||
const detectJavaModal = ref(null)
|
||||
async function autoDetect() {
|
||||
if (!props.compact) {
|
||||
detectJavaModal.value.show(props.version, props.modelValue)
|
||||
} else {
|
||||
let versions = await find_jre_17_jres().catch(handleError)
|
||||
if (versions.length > 0) {
|
||||
emit('update:modelValue', versions[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -131,12 +145,15 @@ async function handleJavaFileInput() {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
&.compact {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.installation-buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin: 0;
|
||||
|
||||
@@ -47,18 +47,7 @@
|
||||
<Card v-if="showCard === true" ref="card" class="info-card">
|
||||
<div v-for="loadingBar in currentLoadingBars" :key="loadingBar.id" class="info-text">
|
||||
<h3 class="info-title">
|
||||
{{ loadingBar.bar_type.pack_name ?? 'Installing Modpack' }}
|
||||
</h3>
|
||||
<ProgressBar :progress="Math.floor(loadingBar.current)" />
|
||||
<div class="row">{{ Math.floor(loadingBar.current) }}% {{ loadingBar.message }}</div>
|
||||
</div>
|
||||
</Card>
|
||||
</transition>
|
||||
<transition name="download">
|
||||
<Card v-if="showCard === true" ref="card" class="info-card">
|
||||
<div v-for="loadingBar in currentLoadingBars" :key="loadingBar.id" class="info-text">
|
||||
<h3 class="info-title">
|
||||
{{ loadingBar.bar_type.pack_name ?? 'Installing Modpack' }}
|
||||
{{ loadingBar.title }}
|
||||
</h3>
|
||||
<ProgressBar :progress="Math.floor(loadingBar.current)" />
|
||||
<div class="row">{{ Math.floor(loadingBar.current) }}% {{ loadingBar.message }}</div>
|
||||
@@ -123,6 +112,7 @@ const profiles = ref(null)
|
||||
const infoButton = ref(null)
|
||||
const profileButton = ref(null)
|
||||
const showCard = ref(false)
|
||||
|
||||
const showProfiles = ref(false)
|
||||
|
||||
const currentProcesses = ref(await getRunningProfiles().catch(handleError))
|
||||
@@ -159,15 +149,25 @@ const goToTerminal = (path) => {
|
||||
router.push(`/instance/${encodeURIComponent(path ?? selectedProfile.value.path)}/logs`)
|
||||
}
|
||||
|
||||
const currentLoadingBars = ref(Object.values(await progress_bars_list().catch(handleError)))
|
||||
|
||||
const unlistenLoading = await loading_listener(async () => {
|
||||
await refreshInfo()
|
||||
})
|
||||
const currentLoadingBars = ref([])
|
||||
|
||||
const refreshInfo = async () => {
|
||||
const currentLoadingBarCount = currentLoadingBars.value.length
|
||||
currentLoadingBars.value = Object.values(await progress_bars_list().catch(handleError))
|
||||
currentLoadingBars.value = Object.values(await progress_bars_list().catch(handleError)).map(
|
||||
(x) => {
|
||||
if (x.bar_type.type === 'java_download') {
|
||||
x.title = 'Downloading Java ' + x.bar_type.version
|
||||
}
|
||||
if (x.bar_type.profile_name) {
|
||||
x.title = x.bar_type.profile_name
|
||||
}
|
||||
if (x.bar_type.pack_name) {
|
||||
x.title = x.bar_type.pack_name
|
||||
}
|
||||
|
||||
return x
|
||||
}
|
||||
)
|
||||
if (currentLoadingBars.value.length === 0) {
|
||||
showCard.value = false
|
||||
} else if (currentLoadingBarCount < currentLoadingBars.value.length) {
|
||||
@@ -175,6 +175,11 @@ const refreshInfo = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
await refreshInfo()
|
||||
const unlistenLoading = await loading_listener(async () => {
|
||||
await refreshInfo()
|
||||
})
|
||||
|
||||
const selectProfile = (profile) => {
|
||||
selectedProfile.value = profile
|
||||
showProfiles.value = false
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { ofetch } from 'ofetch'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { getVersion } from '@tauri-apps/api/app'
|
||||
|
||||
export const useFetch = async (url, item) => {
|
||||
try {
|
||||
const version = await getVersion()
|
||||
|
||||
return await ofetch(url, {
|
||||
headers: { 'User-Agent': 'modrinth/theseus (support@modrinth.com)' },
|
||||
headers: { 'User-Agent': `modrinth/theseus/${version} (support@modrinth.com)` },
|
||||
})
|
||||
} catch (err) {
|
||||
handleError({ message: `Error fetching ${item}` })
|
||||
|
||||
@@ -52,12 +52,12 @@ export async function get_jre(path) {
|
||||
|
||||
// Autodetect Java globals, by searching the users computer.
|
||||
// Returns a *NEW* JavaGlobals that can be put into Settings
|
||||
export async function autodetect_java_globals(path) {
|
||||
return await invoke('jre_autodetect_java_globals', { path })
|
||||
export async function autodetect_java_globals() {
|
||||
return await invoke('jre_autodetect_java_globals')
|
||||
}
|
||||
|
||||
// Automatically installs specified java version
|
||||
export async function jre_auto_install_java(javaVersion) {
|
||||
export async function auto_install_java(javaVersion) {
|
||||
return await invoke('jre_auto_install_java', { javaVersion })
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,7 @@ breadcrumbs.setRootContext({ name: 'Home', link: route.path })
|
||||
const recentInstances = shallowRef([])
|
||||
|
||||
const getInstances = async () => {
|
||||
console.log('aa')
|
||||
const profiles = await list(true).catch(handleError)
|
||||
console.log(profiles)
|
||||
recentInstances.value = Object.values(profiles).sort((a, b) => {
|
||||
return dayjs(b.metadata.last_played ?? 0).diff(dayjs(a.metadata.last_played ?? 0))
|
||||
})
|
||||
|
||||
@@ -221,7 +221,6 @@ const handleRightClick = (event) => {
|
||||
}
|
||||
|
||||
const handleOptionsClick = async (args) => {
|
||||
console.log(args)
|
||||
switch (args.option) {
|
||||
case 'play':
|
||||
await startInstance('InstancePageContextMenu')
|
||||
|
||||
@@ -192,7 +192,7 @@ import {
|
||||
renderString,
|
||||
} from 'omorphia'
|
||||
import { releaseColor } from '@/helpers/utils'
|
||||
import { ref, defineProps, watch, computed } from 'vue'
|
||||
import { ref, watch, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "theseus_playground"
|
||||
version = "0.1.0"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
Reference in new issue
Block a user