chore: move onelauncher apps into its own folder

This commit is contained in:
LynithDev 2025-05-02 10:41:55 +02:00
parent 81aa87afdd
commit 37e8e1eaf8
215 changed files with 707 additions and 1103 deletions

10
.vscode/settings.json vendored
View file

@ -20,12 +20,14 @@
"**/.cargo": true,
"**/.crates": true
},
"rust-analyzer.procMacro.enable": true,
"rust-analyzer.procMacro.attributes.enable": true,
"rust-analyzer.procMacro.enable": false,
"rust-analyzer.procMacro.attributes.enable": false,
"rust-analyzer.procMacro.ignored": {
"async-trait": ["async_trait"]
"async-trait": ["async_trait"],
"specta": ["specta"],
"tauri-specta": ["command"]
},
"rust-analyzer.check.command": "clippy",
"rust-analyzer.check.command": "check",
"rust-analyzer.diagnostics.experimental.enable": false,
"rust-analyzer.linkedProjects": [],
"rust-analyzer.cargo.extraEnv": {},

View file

@ -1,6 +1,6 @@
[workspace]
members = [
"apps/desktop",
"apps/onelauncher/desktop",
"packages/core",
"packages/entity",
"packages/gamemode",

View file

@ -1,217 +0,0 @@
use std::collections::HashMap;
use std::path::PathBuf;
use std::str::FromStr;
use onelauncher_core::cluster::content::logger;
use onelauncher_core::cluster::{self};
use onelauncher_core::data::{Loader, PackageData};
use onelauncher_core::processor::DetailedProcess;
use onelauncher_core::store::{Cluster, ClusterPath};
use onelauncher_core::api::java::JavaInfo;
use onelauncher_core::store::State;
use serde::{Deserialize, Serialize};
use specta::Type;
use uuid::Uuid;
#[specta::specta]
#[tauri::command]
pub async fn get_cluster(uuid: Uuid) -> Result<Cluster, String> {
(cluster::get_by_uuid(uuid).await?).map_or_else(|| Err("Cluster does not exist".into()), Ok)
}
#[specta::specta]
#[tauri::command]
pub async fn get_clusters() -> Result<Vec<Cluster>, String> {
Ok(cluster::list().await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_clusters_grouped() -> Result<HashMap<String, Vec<Cluster>>, String> {
Ok(cluster::list_grouped().await?)
}
#[derive(Serialize, Deserialize, Type)]
pub struct CreateCluster {
name: String,
mc_version: String,
mod_loader: Loader,
loader_version: Option<String>,
icon: Option<PathBuf>,
icon_url: Option<String>,
package_data: Option<PackageData>,
skip: Option<bool>,
skip_watch: Option<bool>,
}
#[specta::specta]
#[tauri::command]
pub async fn create_cluster(props: CreateCluster) -> Result<Uuid, String> {
let path = cluster::create::create_cluster(
props.name,
props.mc_version,
props.mod_loader,
props.loader_version,
props.icon,
props.icon_url,
props.package_data,
props.skip,
props.skip_watch,
)
.await?;
if let Some(cluster) = cluster::get(&path).await? {
Ok(cluster.uuid)
} else {
Err("Cluster does not exist".to_string())
}
}
/// Updates the cluster with the given UUID. The cluster only updates game setting fields
#[specta::specta]
#[tauri::command]
pub async fn edit_game_settings(uuid: Uuid, new_cluster: Cluster) -> Result<(), String> {
let cluster_path = ClusterPath::find_by_uuid(uuid).await?;
cluster::edit(&cluster_path, |old| {
old.force_fullscreen = new_cluster.force_fullscreen;
old.resolution = new_cluster.resolution;
old.memory = new_cluster.memory;
old.init_hooks.clone_from(&new_cluster.init_hooks);
old.java.clone_from(&new_cluster.java);
async move { Ok(()) }
})
.await?;
State::sync().await?;
Ok(())
}
#[specta::specta]
#[tauri::command]
pub async fn edit_cluster_meta(
uuid: Uuid,
name: Option<String>,
icon_path: Option<String>,
) -> Result<(), String> {
let cluster = cluster::get_by_uuid(uuid)
.await?
.ok_or("cluster does not exist")?;
cluster::edit(&cluster.cluster_path(), move |cluster| {
if let Some(name) = name.clone() {
cluster.meta.name = name;
}
async move { Ok(()) }
})
.await?;
let icon_path = icon_path.and_then(|x| PathBuf::from_str(x.as_str()).ok());
cluster::edit_icon(&cluster.cluster_path(), icon_path.as_deref()).await?;
State::sync().await?;
Ok(())
}
#[specta::specta]
#[tauri::command]
pub async fn remove_cluster(uuid: Uuid) -> Result<(), String> {
let path = ClusterPath::find_by_uuid(uuid).await?;
Ok(cluster::remove(&path).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn run_cluster(uuid: Uuid) -> Result<DetailedProcess, String> {
let path = ClusterPath::find_by_uuid(uuid).await?;
let c_lock = cluster::run_default(&path).await?;
let child = &*c_lock.read().await;
Ok(DetailedProcess::from_processor_child(child).await)
}
#[specta::specta]
#[tauri::command]
pub async fn get_cluster_logs(uuid: Uuid) -> Result<Vec<String>, String> {
let cluster = cluster::get_by_uuid(uuid)
.await?
.ok_or("cluster not found")?;
let logs = logger::get_logs(&cluster.cluster_path(), None)
.await?
.iter()
.map(|x| x.log_file.clone())
.collect();
Ok(logs)
}
#[specta::specta]
#[tauri::command]
pub async fn get_cluster_log(uuid: Uuid, log_name: String) -> Result<String, String> {
let cluster = cluster::get_by_uuid(uuid)
.await?
.ok_or("cluster not found")?;
let log = logger::get_output_by_file(&cluster.cluster_path(), logger::LogType::Info, &log_name)
.await?;
Ok(log.0)
}
#[specta::specta]
#[tauri::command]
pub async fn upload_log(uuid: Uuid, log_name: String) -> Result<String, String> {
let cluster = cluster::get_by_uuid(uuid)
.await?
.ok_or("cluster not found")?;
let log = logger::get_output_by_file(&cluster.cluster_path(), logger::LogType::Info, &log_name)
.await?;
let id = logger::upload_log(&cluster.cluster_path(), log).await?;
Ok(id)
}
#[specta::specta]
#[tauri::command]
pub async fn get_screenshots(uuid: Uuid) -> Result<Vec<String>, String> {
let cluster = cluster::get_by_uuid(uuid)
.await?
.ok_or("cluster not found")?;
let screenshots =
cluster::content::screenshots::get_screenshots(&cluster.cluster_path()).await?;
Ok(screenshots)
}
#[specta::specta]
#[tauri::command]
pub async fn get_worlds(uuid: Uuid) -> Result<Vec<String>, String> {
let cluster = cluster::get_by_uuid(uuid)
.await?
.ok_or("cluster not found")?;
let screenshots = cluster::content::worlds::get_worlds(&cluster.cluster_path()).await?;
Ok(screenshots)
}
#[specta::specta]
#[tauri::command]
pub async fn get_optimal_java_version(uuid: Uuid) -> Result<JavaVersion, String> {
let cluster_path = cluster::get_by_uuid(uuid).await?.ok_or("Cluster not found")?.cluster_path();
Ok(cluster::get_optimal_java_version(&cluster_path).await?.ok_or("No Java version found")?)
}
#[specta::specta]
#[tauri::command]
pub async fn repair_cluster(uuid: Uuid) -> Result<(), String> {
let cluster = cluster::get_by_uuid(uuid)
.await?
.ok_or("cluster not found")?;
cluster::repair_cluster(&cluster.cluster_path()).await?;
Ok(())
}

View file

@ -1,234 +0,0 @@
use std::path::PathBuf;
use onelauncher::cluster::content::package;
use onelauncher::data::{Loader, ManagedPackage, ManagedUser, ManagedVersion, PackageType};
use onelauncher::package::content::Providers;
use onelauncher::package::import::ImportType;
use onelauncher::store::{
Author, ClusterPath, Package, PackageBody, PackagePath, ProviderSearchResults,
};
use onelauncher::utils::pagination::Pagination;
use uuid::Uuid;
#[specta::specta]
#[tauri::command]
pub async fn get_launcher_instances(
launcher: ImportType,
path: Option<PathBuf>,
) -> Result<(String, Vec<String>), String> {
let (dir, instances) = onelauncher::api::package::import::get_launcher_instances(launcher, path).await?;
Ok((
dir.to_str().ok_or("could not convert pathbuf to string")?.to_string(),
instances
))
}
#[specta::specta]
#[tauri::command]
pub async fn import_instances(
launcher: ImportType,
base_path: PathBuf,
instances: Vec<String>,
) -> Result<(), String> {
onelauncher::api::package::import::import_instances(launcher, base_path, instances).await?;
Ok(())
}
#[specta::specta]
#[tauri::command]
pub async fn get_provider_package(
provider: Providers,
project_id: String,
) -> Result<ManagedPackage, String> {
Ok(provider.get(&project_id).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_provider_packages(
provider: Providers,
project_ids: Vec<String>,
) -> Result<Vec<ManagedPackage>, String> {
Ok(provider.get_multiple(&project_ids).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_all_provider_package_versions(
provider: Providers,
project_id: String,
game_versions: Option<Vec<String>>,
loaders: Option<Vec<Loader>>,
page: Option<u32>,
page_size: Option<u16>,
) -> Result<(Vec<ManagedVersion>, Pagination), String> {
Ok(provider
.get_all_versions(&project_id, game_versions, loaders, page, page_size)
.await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_provider_package_versions(
provider: Providers,
versions: Vec<String>,
) -> Result<Vec<ManagedVersion>, String> {
Ok(provider.get_versions(versions).await?)
}
#[derive(specta::Type, serde::Deserialize, serde::Serialize)]
pub struct ProviderSearchQuery {
query: Option<String>,
limit: Option<u8>,
offset: Option<u32>,
game_versions: Option<Vec<String>>,
categories: Option<Vec<String>>,
loaders: Option<Vec<Loader>>,
package_types: Option<Vec<PackageType>>,
open_source: Option<bool>,
}
#[specta::specta]
#[tauri::command]
pub async fn search_provider_packages(
provider: Providers,
query: ProviderSearchQuery,
) -> Result<ProviderSearchResults, String> {
Ok(provider
.search(
query.query,
query.limit,
query.offset,
query.game_versions,
query.categories,
query.loaders,
query.package_types,
query.open_source,
)
.await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_provider_authors(
provider: Providers,
author: Author,
) -> Result<Vec<ManagedUser>, String> {
Ok(provider.get_authors(&author).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_package_body(provider: Providers, body: PackageBody) -> Result<String, String> {
Ok(provider.get_package_body(&body).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn download_provider_package(
provider: Providers,
package_id: String,
cluster_id: Uuid,
game_version: Option<String>,
loader: Option<Loader>,
package_version: Option<String>,
) -> Result<(), String> {
let mut cluster = onelauncher::cluster::get_by_uuid(cluster_id)
.await?
.ok_or("cluster not found")?;
let mgd_pkg = provider.get(&package_id).await?;
let (pkg_path, pkg) = package::download_package(
&mgd_pkg,
&mut cluster,
game_version,
loader,
package_version,
)
.await?;
package::add_package(
&cluster.cluster_path(),
pkg_path,
pkg,
)
.await?;
Ok(())
}
#[specta::specta]
#[tauri::command]
pub async fn get_cluster_package(
cluster_path: ClusterPath,
package_path: PackagePath,
package_type: PackageType,
) -> Result<Package, String> {
Ok(package::get_package(&cluster_path, &package_path, package_type).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_cluster_packages(
cluster_path: ClusterPath,
package_type: PackageType,
) -> Result<Vec<Package>, String> {
Ok(package::get_packages(&cluster_path, package_type).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn add_cluster_package(
cluster_path: ClusterPath,
file_name: String,
package_type: PackageType,
pkg: Package,
) -> Result<(), String> {
let package_path = PackagePath::new(package_type, file_name)?;
package::add_package(&cluster_path, package_path, pkg).await?;
Ok(())
}
#[specta::specta]
#[tauri::command]
pub async fn remove_cluster_package(
cluster_path: ClusterPath,
file_name: String,
package_type: PackageType,
) -> Result<(), String> {
let package_path = PackagePath::new(package_type, file_name)?;
package::remove_package(&cluster_path, &package_path).await?;
Ok(())
}
#[specta::specta]
#[tauri::command]
pub async fn set_cluster_package_enabled(
cluster_path: ClusterPath,
file_name: String,
package_type: PackageType,
enabled: bool,
) -> Result<(), String> {
let package_path = PackagePath::new(package_type, file_name)?;
package::set_package_enabled(&cluster_path, &package_path, enabled).await?;
Ok(())
}
#[specta::specta]
#[tauri::command]
pub async fn sync_cluster_packages(cluster_path: ClusterPath) -> Result<(), String> {
package::sync_packages(&cluster_path).await?;
Ok(())
}
#[specta::specta]
#[tauri::command]
pub async fn sync_cluster_packages_by_type(
cluster_path: ClusterPath,
package_type: PackageType,
clear: Option<bool>,
) -> Result<(), String> {
package::sync_packages_by_type(&cluster_path, package_type, clear).await?;
Ok(())
}

View file

@ -1,61 +0,0 @@
use chrono::{DateTime, Utc};
use onelauncher::processor::{self, DetailedProcess};
use onelauncher::store::{Cluster, ClusterPath};
use uuid::Uuid;
#[specta::specta]
#[tauri::command]
pub async fn get_running_clusters() -> Result<Vec<Cluster>, String> {
Ok(processor::get_running_clusters().await?)
}
#[specta::specta]
#[tauri::command]
pub async fn is_cluster_running(uuid: Uuid) -> Result<bool, String> {
Ok(processor::is_cluster_running(uuid).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_processes_by_path(path: ClusterPath) -> Result<Vec<Uuid>, String> {
Ok(processor::get_uuids_by_cluster_path(path).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_processes_detailed_by_path(
path: ClusterPath,
) -> Result<Vec<DetailedProcess>, String> {
Ok(processor::get_processes_detailed_by_path(path).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_process_detailed_by_id(uuid: Uuid) -> Result<DetailedProcess, String> {
Ok(processor::get_process_detailed_by_id(uuid).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_user_by_process(uuid: Uuid) -> Result<Option<Uuid>, String> {
Ok(processor::get_user_by_process(uuid).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_process_started_at(uuid: Uuid) -> Result<DateTime<Utc>, String> {
Ok(processor::get_process_started_at(uuid).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_pid_by_uuid(uuid: Uuid) -> Result<u32, String> {
Ok(processor::get_pid_by_uuid(uuid).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn kill_process(uuid: Uuid) -> Result<(), String> {
processor::kill_by_uuid(uuid).await?;
Ok(())
}

View file

@ -1,119 +0,0 @@
use onelauncher::data::MinecraftCredentials;
use onelauncher::minecraft;
use onelauncher::store::MinecraftLogin;
use tauri::{AppHandle, Manager};
use uuid::Uuid;
#[specta::specta]
#[tauri::command]
pub async fn get_users() -> Result<Vec<MinecraftCredentials>, String> {
Ok(minecraft::users().await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_user(uuid: Uuid) -> Result<MinecraftCredentials, String> {
Ok(minecraft::get_user(uuid).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn remove_user(uuid: Uuid) -> Result<(), String> {
Ok(minecraft::remove_user(uuid).await?)
}
#[specta::specta]
#[tauri::command]
pub async fn get_default_user(
fallback: Option<bool>,
) -> Result<Option<MinecraftCredentials>, String> {
let uuid = minecraft::get_default_user().await?;
if let Some(fallback) = fallback {
if fallback && uuid.is_none() {
return Ok(minecraft::users().await?.first().cloned());
}
}
match uuid {
Some(uuid) => Ok(Some(minecraft::get_user(uuid).await?)),
None => Ok(None),
}
}
#[specta::specta]
#[tauri::command]
pub async fn set_default_user(uuid: Option<Uuid>) -> Result<(), String> {
minecraft::set_default_user(uuid).await?;
Ok(())
}
#[specta::specta]
#[tauri::command]
pub async fn auth_login(handle: AppHandle) -> Result<Option<MinecraftCredentials>, String> {
let flow = minecraft::begin().await?;
let result = spawn_webview(handle, flow).await?;
Ok(result)
}
async fn spawn_webview(
handle: AppHandle,
flow: MinecraftLogin,
) -> Result<Option<MinecraftCredentials>, String> {
let now = chrono::Utc::now();
if let Some(win) = handle.get_webview_window("login") {
win.close().map_err(|err| err.to_string())?;
}
let win = tauri::WebviewWindowBuilder::new(
&handle,
"login",
tauri::WebviewUrl::External(
flow.redirect_uri
.parse()
.map_err(|_| anyhow::anyhow!("failed to parse auth redirect url"))
.map_err(|err| err.to_string())?,
),
)
.title("Log into OneLauncher")
.always_on_top(true)
.center()
.build()
.map_err(|err| err.to_string())?;
win.request_user_attention(Some(tauri::UserAttentionType::Critical))
.map_err(|err| err.to_string())?;
while (chrono::Utc::now() - now) < chrono::Duration::minutes(10) {
if win.title().is_err() {
return Ok(None);
}
if win
.url()
.map_err(|err| err.to_string())?
.as_str()
.starts_with("https://login.live.com/oauth20_desktop.srf")
{
if let Some((_, code)) = win
.url()
.map_err(|err| err.to_string())?
.query_pairs()
.find(|x| x.0 == "code")
{
win.close().map_err(|err| err.to_string())?;
let value = minecraft::finish(&code.clone(), flow).await?;
return Ok(Some(value));
}
}
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
}
win.close().map_err(|err| err.to_string())?;
Ok(None)
}

View file

@ -19,8 +19,6 @@
"tauri-ext": "pnpm --filter @onelauncher/scripts -- tauri"
},
"dependencies": {
"@onelauncher/core": "workspace:*",
"@onelauncher/distribution": "workspace:*",
"@onelauncher/frontend": "workspace:*"
},
"devDependencies": {

View file

@ -1,23 +1,23 @@
use interpulse::api::minecraft::Version;
use tauri::{AppHandle, Manager};
// use interpulse::api::minecraft::Version;
// use tauri::{AppHandle, Manager};
mod cluster;
pub use crate::api::commands::cluster::*;
// pub use crate::api::commands::cluster::*;
mod users;
pub use crate::api::commands::users::*;
// pub use crate::api::commands::users::*;
mod processor;
pub use crate::api::commands::processor::*;
// pub use crate::api::commands::processor::*;
mod package;
pub use crate::api::commands::package::*;
// pub use crate::api::commands::package::*;
#[macro_export]
macro_rules! collect_commands {
() => {{
use $crate::api::commands::*;
use $crate::ext::updater::*;
// use $crate::api::commands::*;
// use $crate::ext::updater::*;
tauri_specta::collect_commands![
// User
// auth_login,
@ -92,9 +92,10 @@ macro_rules! collect_commands {
}
#[onelauncher_core::command]
pub fn open_dev_tools(_webview: tauri::WebviewWindow) {
#[allow(unused_parens)]
pub fn open_dev_tools(webview: &tauri::WebviewWindow) {
#[cfg(feature = "devtools")]
_webview.open_devtools();
webview.open_devtools();
}
// #[onelauncher_core::command]
@ -102,40 +103,40 @@ pub fn open_dev_tools(_webview: tauri::WebviewWindow) {
// Ok(onelauncher::java::get_zulu_packages().await?)
// }
#[onelauncher_core::command]
pub async fn install_java_from_package(download: onelauncher::java::JavaZuluPackage) -> Result<std::path::PathBuf, String> {
Ok(onelauncher::java::install_java_from_package(download).await?)
}
// #[onelauncher_core::command]
// pub async fn install_java_from_package(download: onelauncher::java::JavaZuluPackage) -> Result<std::path::PathBuf, String> {
// Ok(onelauncher::java::install_java_from_package(download).await?)
// }
#[onelauncher_core::command]
pub async fn get_featured_packages() -> Result<Vec<onelauncher::package::content::FeaturedPackage>, String> {
Ok(onelauncher::package::content::get_featured_packages().await?)
}
// #[onelauncher_core::command]
// pub async fn get_featured_packages() -> Result<Vec<onelauncher::package::content::FeaturedPackage>, String> {
// Ok(onelauncher::package::content::get_featured_packages().await?)
// }
#[onelauncher_core::command]
pub fn get_program_info() -> Result<super::statics::ProgramInfo, String> {
Ok(super::statics::get_program_info())
}
// #[onelauncher_core::command]
// pub fn get_program_info() -> Result<super::statics::ProgramInfo, String> {
// Ok(super::statics::get_program_info())
// }
#[onelauncher_core::command]
pub async fn get_minecraft_versions() -> Result<Vec<Version>, String> {
Ok(onelauncher::api::metadata::get_minecraft_versions()
.await?
.versions)
}
// #[onelauncher_core::command]
// pub async fn get_minecraft_versions() -> Result<Vec<Version>, String> {
// Ok(onelauncher::api::metadata::get_minecraft_versions()
// .await?
// .versions)
// }
#[onelauncher_core::command]
pub async fn get_settings() -> Result<Settings, String> {
Ok(settings::get().await?)
}
// #[onelauncher_core::command]
// pub async fn get_settings() -> Result<Settings, String> {
// Ok(settings::get().await?)
// }
#[onelauncher_core::command]
pub async fn set_settings(settings: Settings) -> Result<(), String> {
Ok(settings::set(settings).await?)
}
// #[onelauncher_core::command]
// pub async fn set_settings(settings: Settings) -> Result<(), String> {
// Ok(settings::set(settings).await?)
// }
#[onelauncher_core::command]
pub fn set_window_style(handle: AppHandle, custom: bool) -> Result<(), String> {
let window = handle.get_webview_window("main").unwrap();
onelauncher::utils::window::set_window_styling(&window, custom).map_err(|e| e.to_string())
}
// #[onelauncher_core::command]
// pub fn set_window_style(handle: AppHandle, custom: bool) -> Result<(), String> {
// let window = handle.get_webview_window("main").unwrap();
// onelauncher::utils::window::set_window_styling(&window, custom).map_err(|e| e.to_string())
// }

View file

@ -0,0 +1,217 @@
// use std::collections::HashMap;
// use std::path::PathBuf;
// use std::str::FromStr;
// use onelauncher_core::cluster::content::logger;
// use onelauncher_core::cluster::{self};
// use onelauncher_core::data::{Loader, PackageData};
// use onelauncher_core::processor::DetailedProcess;
// use onelauncher_core::store::{Cluster, ClusterPath};
// use onelauncher_core::api::java::JavaInfo;
// use onelauncher_core::store::State;
// use serde::{Deserialize, Serialize};
// use specta::Type;
// use uuid::Uuid;
// #[specta::specta]
// #[tauri::command]
// pub async fn get_cluster(uuid: Uuid) -> Result<Cluster, String> {
// (cluster::get_by_uuid(uuid).await?).map_or_else(|| Err("Cluster does not exist".into()), Ok)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_clusters() -> Result<Vec<Cluster>, String> {
// Ok(cluster::list().await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_clusters_grouped() -> Result<HashMap<String, Vec<Cluster>>, String> {
// Ok(cluster::list_grouped().await?)
// }
// #[derive(Serialize, Deserialize, Type)]
// pub struct CreateCluster {
// name: String,
// mc_version: String,
// mod_loader: Loader,
// loader_version: Option<String>,
// icon: Option<PathBuf>,
// icon_url: Option<String>,
// package_data: Option<PackageData>,
// skip: Option<bool>,
// skip_watch: Option<bool>,
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn create_cluster(props: CreateCluster) -> Result<Uuid, String> {
// let path = cluster::create::create_cluster(
// props.name,
// props.mc_version,
// props.mod_loader,
// props.loader_version,
// props.icon,
// props.icon_url,
// props.package_data,
// props.skip,
// props.skip_watch,
// )
// .await?;
// if let Some(cluster) = cluster::get(&path).await? {
// Ok(cluster.uuid)
// } else {
// Err("Cluster does not exist".to_string())
// }
// }
// /// Updates the cluster with the given UUID. The cluster only updates game setting fields
// #[specta::specta]
// #[tauri::command]
// pub async fn edit_game_settings(uuid: Uuid, new_cluster: Cluster) -> Result<(), String> {
// let cluster_path = ClusterPath::find_by_uuid(uuid).await?;
// cluster::edit(&cluster_path, |old| {
// old.force_fullscreen = new_cluster.force_fullscreen;
// old.resolution = new_cluster.resolution;
// old.memory = new_cluster.memory;
// old.init_hooks.clone_from(&new_cluster.init_hooks);
// old.java.clone_from(&new_cluster.java);
// async move { Ok(()) }
// })
// .await?;
// State::sync().await?;
// Ok(())
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn edit_cluster_meta(
// uuid: Uuid,
// name: Option<String>,
// icon_path: Option<String>,
// ) -> Result<(), String> {
// let cluster = cluster::get_by_uuid(uuid)
// .await?
// .ok_or("cluster does not exist")?;
// cluster::edit(&cluster.cluster_path(), move |cluster| {
// if let Some(name) = name.clone() {
// cluster.meta.name = name;
// }
// async move { Ok(()) }
// })
// .await?;
// let icon_path = icon_path.and_then(|x| PathBuf::from_str(x.as_str()).ok());
// cluster::edit_icon(&cluster.cluster_path(), icon_path.as_deref()).await?;
// State::sync().await?;
// Ok(())
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn remove_cluster(uuid: Uuid) -> Result<(), String> {
// let path = ClusterPath::find_by_uuid(uuid).await?;
// Ok(cluster::remove(&path).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn run_cluster(uuid: Uuid) -> Result<DetailedProcess, String> {
// let path = ClusterPath::find_by_uuid(uuid).await?;
// let c_lock = cluster::run_default(&path).await?;
// let child = &*c_lock.read().await;
// Ok(DetailedProcess::from_processor_child(child).await)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_cluster_logs(uuid: Uuid) -> Result<Vec<String>, String> {
// let cluster = cluster::get_by_uuid(uuid)
// .await?
// .ok_or("cluster not found")?;
// let logs = logger::get_logs(&cluster.cluster_path(), None)
// .await?
// .iter()
// .map(|x| x.log_file.clone())
// .collect();
// Ok(logs)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_cluster_log(uuid: Uuid, log_name: String) -> Result<String, String> {
// let cluster = cluster::get_by_uuid(uuid)
// .await?
// .ok_or("cluster not found")?;
// let log = logger::get_output_by_file(&cluster.cluster_path(), logger::LogType::Info, &log_name)
// .await?;
// Ok(log.0)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn upload_log(uuid: Uuid, log_name: String) -> Result<String, String> {
// let cluster = cluster::get_by_uuid(uuid)
// .await?
// .ok_or("cluster not found")?;
// let log = logger::get_output_by_file(&cluster.cluster_path(), logger::LogType::Info, &log_name)
// .await?;
// let id = logger::upload_log(&cluster.cluster_path(), log).await?;
// Ok(id)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_screenshots(uuid: Uuid) -> Result<Vec<String>, String> {
// let cluster = cluster::get_by_uuid(uuid)
// .await?
// .ok_or("cluster not found")?;
// let screenshots =
// cluster::content::screenshots::get_screenshots(&cluster.cluster_path()).await?;
// Ok(screenshots)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_worlds(uuid: Uuid) -> Result<Vec<String>, String> {
// let cluster = cluster::get_by_uuid(uuid)
// .await?
// .ok_or("cluster not found")?;
// let screenshots = cluster::content::worlds::get_worlds(&cluster.cluster_path()).await?;
// Ok(screenshots)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_optimal_java_version(uuid: Uuid) -> Result<JavaVersion, String> {
// let cluster_path = cluster::get_by_uuid(uuid).await?.ok_or("Cluster not found")?.cluster_path();
// Ok(cluster::get_optimal_java_version(&cluster_path).await?.ok_or("No Java version found")?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn repair_cluster(uuid: Uuid) -> Result<(), String> {
// let cluster = cluster::get_by_uuid(uuid)
// .await?
// .ok_or("cluster not found")?;
// cluster::repair_cluster(&cluster.cluster_path()).await?;
// Ok(())
// }

View file

@ -0,0 +1,234 @@
// use std::path::PathBuf;
// use onelauncher::cluster::content::package;
// use onelauncher::data::{Loader, ManagedPackage, ManagedUser, ManagedVersion, PackageType};
// use onelauncher::package::content::Providers;
// use onelauncher::package::import::ImportType;
// use onelauncher::store::{
// Author, ClusterPath, Package, PackageBody, PackagePath, ProviderSearchResults,
// };
// use onelauncher::utils::pagination::Pagination;
// use uuid::Uuid;
// #[specta::specta]
// #[tauri::command]
// pub async fn get_launcher_instances(
// launcher: ImportType,
// path: Option<PathBuf>,
// ) -> Result<(String, Vec<String>), String> {
// let (dir, instances) = onelauncher::api::package::import::get_launcher_instances(launcher, path).await?;
// Ok((
// dir.to_str().ok_or("could not convert pathbuf to string")?.to_string(),
// instances
// ))
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn import_instances(
// launcher: ImportType,
// base_path: PathBuf,
// instances: Vec<String>,
// ) -> Result<(), String> {
// onelauncher::api::package::import::import_instances(launcher, base_path, instances).await?;
// Ok(())
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_provider_package(
// provider: Providers,
// project_id: String,
// ) -> Result<ManagedPackage, String> {
// Ok(provider.get(&project_id).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_provider_packages(
// provider: Providers,
// project_ids: Vec<String>,
// ) -> Result<Vec<ManagedPackage>, String> {
// Ok(provider.get_multiple(&project_ids).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_all_provider_package_versions(
// provider: Providers,
// project_id: String,
// game_versions: Option<Vec<String>>,
// loaders: Option<Vec<Loader>>,
// page: Option<u32>,
// page_size: Option<u16>,
// ) -> Result<(Vec<ManagedVersion>, Pagination), String> {
// Ok(provider
// .get_all_versions(&project_id, game_versions, loaders, page, page_size)
// .await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_provider_package_versions(
// provider: Providers,
// versions: Vec<String>,
// ) -> Result<Vec<ManagedVersion>, String> {
// Ok(provider.get_versions(versions).await?)
// }
// #[derive(specta::Type, serde::Deserialize, serde::Serialize)]
// pub struct ProviderSearchQuery {
// query: Option<String>,
// limit: Option<u8>,
// offset: Option<u32>,
// game_versions: Option<Vec<String>>,
// categories: Option<Vec<String>>,
// loaders: Option<Vec<Loader>>,
// package_types: Option<Vec<PackageType>>,
// open_source: Option<bool>,
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn search_provider_packages(
// provider: Providers,
// query: ProviderSearchQuery,
// ) -> Result<ProviderSearchResults, String> {
// Ok(provider
// .search(
// query.query,
// query.limit,
// query.offset,
// query.game_versions,
// query.categories,
// query.loaders,
// query.package_types,
// query.open_source,
// )
// .await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_provider_authors(
// provider: Providers,
// author: Author,
// ) -> Result<Vec<ManagedUser>, String> {
// Ok(provider.get_authors(&author).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_package_body(provider: Providers, body: PackageBody) -> Result<String, String> {
// Ok(provider.get_package_body(&body).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn download_provider_package(
// provider: Providers,
// package_id: String,
// cluster_id: Uuid,
// game_version: Option<String>,
// loader: Option<Loader>,
// package_version: Option<String>,
// ) -> Result<(), String> {
// let mut cluster = onelauncher::cluster::get_by_uuid(cluster_id)
// .await?
// .ok_or("cluster not found")?;
// let mgd_pkg = provider.get(&package_id).await?;
// let (pkg_path, pkg) = package::download_package(
// &mgd_pkg,
// &mut cluster,
// game_version,
// loader,
// package_version,
// )
// .await?;
// package::add_package(
// &cluster.cluster_path(),
// pkg_path,
// pkg,
// )
// .await?;
// Ok(())
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_cluster_package(
// cluster_path: ClusterPath,
// package_path: PackagePath,
// package_type: PackageType,
// ) -> Result<Package, String> {
// Ok(package::get_package(&cluster_path, &package_path, package_type).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_cluster_packages(
// cluster_path: ClusterPath,
// package_type: PackageType,
// ) -> Result<Vec<Package>, String> {
// Ok(package::get_packages(&cluster_path, package_type).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn add_cluster_package(
// cluster_path: ClusterPath,
// file_name: String,
// package_type: PackageType,
// pkg: Package,
// ) -> Result<(), String> {
// let package_path = PackagePath::new(package_type, file_name)?;
// package::add_package(&cluster_path, package_path, pkg).await?;
// Ok(())
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn remove_cluster_package(
// cluster_path: ClusterPath,
// file_name: String,
// package_type: PackageType,
// ) -> Result<(), String> {
// let package_path = PackagePath::new(package_type, file_name)?;
// package::remove_package(&cluster_path, &package_path).await?;
// Ok(())
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn set_cluster_package_enabled(
// cluster_path: ClusterPath,
// file_name: String,
// package_type: PackageType,
// enabled: bool,
// ) -> Result<(), String> {
// let package_path = PackagePath::new(package_type, file_name)?;
// package::set_package_enabled(&cluster_path, &package_path, enabled).await?;
// Ok(())
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn sync_cluster_packages(cluster_path: ClusterPath) -> Result<(), String> {
// package::sync_packages(&cluster_path).await?;
// Ok(())
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn sync_cluster_packages_by_type(
// cluster_path: ClusterPath,
// package_type: PackageType,
// clear: Option<bool>,
// ) -> Result<(), String> {
// package::sync_packages_by_type(&cluster_path, package_type, clear).await?;
// Ok(())
// }

View file

@ -0,0 +1,61 @@
// use chrono::{DateTime, Utc};
// use onelauncher::processor::{self, DetailedProcess};
// use onelauncher::store::{Cluster, ClusterPath};
// use uuid::Uuid;
// #[specta::specta]
// #[tauri::command]
// pub async fn get_running_clusters() -> Result<Vec<Cluster>, String> {
// Ok(processor::get_running_clusters().await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn is_cluster_running(uuid: Uuid) -> Result<bool, String> {
// Ok(processor::is_cluster_running(uuid).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_processes_by_path(path: ClusterPath) -> Result<Vec<Uuid>, String> {
// Ok(processor::get_uuids_by_cluster_path(path).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_processes_detailed_by_path(
// path: ClusterPath,
// ) -> Result<Vec<DetailedProcess>, String> {
// Ok(processor::get_processes_detailed_by_path(path).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_process_detailed_by_id(uuid: Uuid) -> Result<DetailedProcess, String> {
// Ok(processor::get_process_detailed_by_id(uuid).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_user_by_process(uuid: Uuid) -> Result<Option<Uuid>, String> {
// Ok(processor::get_user_by_process(uuid).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_process_started_at(uuid: Uuid) -> Result<DateTime<Utc>, String> {
// Ok(processor::get_process_started_at(uuid).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_pid_by_uuid(uuid: Uuid) -> Result<u32, String> {
// Ok(processor::get_pid_by_uuid(uuid).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn kill_process(uuid: Uuid) -> Result<(), String> {
// processor::kill_by_uuid(uuid).await?;
// Ok(())
// }

View file

@ -0,0 +1,119 @@
// use onelauncher::data::MinecraftCredentials;
// use onelauncher::minecraft;
// use onelauncher::store::MinecraftLogin;
// use tauri::{AppHandle, Manager};
// use uuid::Uuid;
// #[specta::specta]
// #[tauri::command]
// pub async fn get_users() -> Result<Vec<MinecraftCredentials>, String> {
// Ok(minecraft::users().await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_user(uuid: Uuid) -> Result<MinecraftCredentials, String> {
// Ok(minecraft::get_user(uuid).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn remove_user(uuid: Uuid) -> Result<(), String> {
// Ok(minecraft::remove_user(uuid).await?)
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn get_default_user(
// fallback: Option<bool>,
// ) -> Result<Option<MinecraftCredentials>, String> {
// let uuid = minecraft::get_default_user().await?;
// if let Some(fallback) = fallback {
// if fallback && uuid.is_none() {
// return Ok(minecraft::users().await?.first().cloned());
// }
// }
// match uuid {
// Some(uuid) => Ok(Some(minecraft::get_user(uuid).await?)),
// None => Ok(None),
// }
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn set_default_user(uuid: Option<Uuid>) -> Result<(), String> {
// minecraft::set_default_user(uuid).await?;
// Ok(())
// }
// #[specta::specta]
// #[tauri::command]
// pub async fn auth_login(handle: AppHandle) -> Result<Option<MinecraftCredentials>, String> {
// let flow = minecraft::begin().await?;
// let result = spawn_webview(handle, flow).await?;
// Ok(result)
// }
// async fn spawn_webview(
// handle: AppHandle,
// flow: MinecraftLogin,
// ) -> Result<Option<MinecraftCredentials>, String> {
// let now = chrono::Utc::now();
// if let Some(win) = handle.get_webview_window("login") {
// win.close().map_err(|err| err.to_string())?;
// }
// let win = tauri::WebviewWindowBuilder::new(
// &handle,
// "login",
// tauri::WebviewUrl::External(
// flow.redirect_uri
// .parse()
// .map_err(|_| anyhow::anyhow!("failed to parse auth redirect url"))
// .map_err(|err| err.to_string())?,
// ),
// )
// .title("Log into OneLauncher")
// .always_on_top(true)
// .center()
// .build()
// .map_err(|err| err.to_string())?;
// win.request_user_attention(Some(tauri::UserAttentionType::Critical))
// .map_err(|err| err.to_string())?;
// while (chrono::Utc::now() - now) < chrono::Duration::minutes(10) {
// if win.title().is_err() {
// return Ok(None);
// }
// if win
// .url()
// .map_err(|err| err.to_string())?
// .as_str()
// .starts_with("https://login.live.com/oauth20_desktop.srf")
// {
// if let Some((_, code)) = win
// .url()
// .map_err(|err| err.to_string())?
// .query_pairs()
// .find(|x| x.0 == "code")
// {
// win.close().map_err(|err| err.to_string())?;
// let value = minecraft::finish(&code.clone(), flow).await?;
// return Ok(Some(value));
// }
// }
// tokio::time::sleep(std::time::Duration::from_millis(50)).await;
// }
// win.close().map_err(|err| err.to_string())?;
// Ok(None)
// }

View file

@ -11,7 +11,7 @@ pub fn formatter(file: &Path) -> io::Result<()> {
.arg(file)
.output()
.map(|_| ())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
.map_err(io::Error::other)
}
const _: specta_typescript::FormatterFn = formatter;

View file

@ -1,9 +1,13 @@
use onelauncher_core::{api::proxy::ProxyTauri, error::LauncherResult, store::{proxy::ProxyState, semaphore::SemaphoreStore, Core, CoreOptions, Dirs, State}};
use onelauncher_core::api::proxy::ProxyTauri;
use onelauncher_core::error::LauncherResult;
use onelauncher_core::store::proxy::ProxyState;
use onelauncher_core::store::semaphore::SemaphoreStore;
use onelauncher_core::store::{Core, CoreOptions, Dirs, State};
use tauri::{Emitter, Manager};
pub mod api;
pub mod ext;
pub mod constants;
pub mod ext;
#[derive(Clone, serde::Serialize)]
pub struct SingleInstancePayload {
@ -44,7 +48,7 @@ async fn initialize_tauri(builder: tauri::Builder<tauri::Wry>) -> LauncherResult
specta_typescript::Typescript::default()
.bigint(specta_typescript::BigIntExportBehavior::BigInt)
.formatter(ext::specta::formatter),
"../../packages/client/src/bindings.ts",
"../../frontend/src/bindings.ts",
)
.expect("failed to export debug bindings!");
@ -65,7 +69,7 @@ async fn initialize_tauri(builder: tauri::Builder<tauri::Wry>) -> LauncherResult
.invoke_handler(prebuild.invoke_handler())
.setup(move |app| {
prebuild.mount_events(app.handle());
setup_window(app.handle());
setup_window(app.handle()).expect("failed to setup main window");
Ok(())
});
@ -89,14 +93,20 @@ async fn initialize_state(handle: &tauri::AppHandle) -> LauncherResult<()> {
pub async fn run() {
initialize_core().await.expect("failed to initialize core");
let app = initialize_tauri(tauri::Builder::default()).await.expect("failed to initialize tauri");
initialize_state(app.handle()).await.expect("failed to initialize state");
let app = initialize_tauri(tauri::Builder::default())
.await
.expect("failed to initialize tauri");
initialize_state(app.handle())
.await
.expect("failed to initialize state");
app.run(|_, _| {});
}
fn setup_window(handle: &tauri::AppHandle) -> Result<(), Box<dyn std::error::Error>> {
let win = handle.get_webview_window("main").unwrap();
let win = handle
.get_webview_window("main")
.ok_or_else(|| anyhow::anyhow!("no window called main was found"))?;
// tokio::task::spawn(async move {
// // let state = State::get().await.expect("failed to get state");
@ -104,8 +114,7 @@ fn setup_window(handle: &tauri::AppHandle) -> Result<(), Box<dyn std::error::Err
// // win.set_decorations(settings.);
// });
win.show().unwrap();
win.show()?;
Ok(())
}
}

View file

@ -55,11 +55,11 @@
],
"category": "Game",
"icon": [
"../../packages/distribution/icons/32x32.png",
"../../packages/distribution/icons/128x128.png",
"../../packages/distribution/icons/128x128@2x.png",
"../../packages/distribution/icons/icon.icns",
"../../packages/distribution/icons/icon.ico"
"../distribution/icons/32x32.png",
"../distribution/icons/128x128.png",
"../distribution/icons/128x128@2x.png",
"../distribution/icons/icon.icns",
"../distribution/icons/icon.ico"
],
"copyright": "Polyfrost",
"publisher": "Polyfrost",
@ -72,10 +72,10 @@
"linux": {
"deb": {
"depends": [],
"desktopTemplate": "../../packages/distribution/linux/org.polyfrost.launcher.desktop.template"
"desktopTemplate": "../distribution/linux/org.polyfrost.launcher.desktop.template"
},
"rpm": {
"desktopTemplate": "../../packages/distribution/linux/org.polyfrost.launcher.desktop.template"
"desktopTemplate": "../distribution/linux/org.polyfrost.launcher.desktop.template"
},
"appimage": {

View file

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 6 KiB

View file

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View file

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

View file

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

Before

Width:  |  Height:  |  Size: 469 KiB

After

Width:  |  Height:  |  Size: 469 KiB

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 321 KiB

After

Width:  |  Height:  |  Size: 321 KiB

View file

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View file

Before

Width:  |  Height:  |  Size: 340 KiB

After

Width:  |  Height:  |  Size: 340 KiB

View file

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

Before

Width:  |  Height:  |  Size: 529 B

After

Width:  |  Height:  |  Size: 529 B

View file

Before

Width:  |  Height:  |  Size: 769 B

After

Width:  |  Height:  |  Size: 769 B

View file

Before

Width:  |  Height:  |  Size: 952 B

After

Width:  |  Height:  |  Size: 952 B

View file

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View file

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View file

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View file

Before

Width:  |  Height:  |  Size: 269 B

After

Width:  |  Height:  |  Size: 269 B

View file

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View file

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View file

Before

Width:  |  Height:  |  Size: 751 B

After

Width:  |  Height:  |  Size: 751 B

Some files were not shown because too many files have changed in this diff Show more