feat: sort out desktop app base
This commit is contained in:
parent
cb1c8d54de
commit
c81d7a6eeb
26 changed files with 266 additions and 395 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -6070,6 +6070,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"specta",
|
||||
"specta-typescript",
|
||||
"tauri",
|
||||
"tauri-specta-macros",
|
||||
"thiserror 2.0.12",
|
||||
|
|
|
|||
|
|
@ -63,7 +63,10 @@ specta = { version = "=2.0.0-rc.22", features = [
|
|||
"tokio"
|
||||
] }
|
||||
specta-typescript = { version = "=0.0.9" }
|
||||
tauri-specta = { version = "=2.0.0-rc.21", features = [ "derive" ] }
|
||||
tauri-specta = { version = "=2.0.0-rc.21", features = [
|
||||
"derive",
|
||||
"typescript"
|
||||
] }
|
||||
|
||||
# logging
|
||||
tracing = { version = "0.1" }
|
||||
|
|
|
|||
141
apps/desktop/src/api/commands.rs
Normal file
141
apps/desktop/src/api/commands.rs
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
use interpulse::api::minecraft::Version;
|
||||
use tauri::{AppHandle, Manager};
|
||||
|
||||
mod cluster;
|
||||
pub use crate::api::commands::cluster::*;
|
||||
|
||||
mod users;
|
||||
pub use crate::api::commands::users::*;
|
||||
|
||||
mod processor;
|
||||
pub use crate::api::commands::processor::*;
|
||||
|
||||
mod package;
|
||||
pub use crate::api::commands::package::*;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! collect_commands {
|
||||
() => {{
|
||||
use $crate::api::commands::*;
|
||||
use $crate::ext::updater::*;
|
||||
tauri_specta::collect_commands![
|
||||
// User
|
||||
// auth_login,
|
||||
// get_users,
|
||||
// get_user,
|
||||
// get_default_user,
|
||||
// set_default_user,
|
||||
// remove_user,
|
||||
// Cluster
|
||||
// create_cluster,
|
||||
// edit_game_settings,
|
||||
// edit_cluster_meta,
|
||||
// remove_cluster,
|
||||
// get_cluster,
|
||||
// get_clusters,
|
||||
// get_clusters_grouped,
|
||||
// run_cluster,
|
||||
// get_cluster_logs,
|
||||
// get_cluster_log,
|
||||
// upload_log,
|
||||
// get_screenshots,
|
||||
// get_worlds,
|
||||
// get_optimal_java_version,
|
||||
// repair_cluster,
|
||||
// Processor
|
||||
// get_running_clusters,
|
||||
// get_processes_by_path,
|
||||
// kill_process,
|
||||
// is_cluster_running,
|
||||
// get_pid_by_uuid,
|
||||
// get_user_by_process,
|
||||
// get_process_started_at,
|
||||
// get_processes_detailed_by_path,
|
||||
// get_process_detailed_by_id,
|
||||
// Settings
|
||||
// get_settings,
|
||||
// set_settings,
|
||||
// Metadata
|
||||
// get_minecraft_versions,
|
||||
// Launcher Packages (Instances)
|
||||
// get_launcher_instances,
|
||||
// import_instances,
|
||||
// Provider Packages
|
||||
// get_provider_package,
|
||||
// get_provider_packages,
|
||||
// get_all_provider_package_versions,
|
||||
// get_provider_package_versions,
|
||||
// search_provider_packages,
|
||||
// get_provider_authors,
|
||||
// get_package_body,
|
||||
// download_provider_package,
|
||||
// Cluster Packages
|
||||
// get_cluster_package,
|
||||
// get_cluster_packages,
|
||||
// add_cluster_package,
|
||||
// remove_cluster_package,
|
||||
// set_cluster_package_enabled,
|
||||
// sync_cluster_packages,
|
||||
// sync_cluster_packages_by_type,
|
||||
// updater
|
||||
// check_for_update,
|
||||
// install_update,
|
||||
// other
|
||||
// set_window_style,
|
||||
// get_program_info,
|
||||
// get_featured_packages,
|
||||
// get_zulu_packages,
|
||||
// install_java_from_package,
|
||||
// open_dev_tools,
|
||||
]
|
||||
}};
|
||||
}
|
||||
|
||||
#[onelauncher_core::command]
|
||||
pub fn open_dev_tools(_webview: tauri::WebviewWindow) {
|
||||
#[cfg(feature = "devtools")]
|
||||
_webview.open_devtools();
|
||||
}
|
||||
|
||||
// #[onelauncher_core::command]
|
||||
// pub async fn get_zulu_packages() -> Result<Vec<onelauncher::java::JavaZuluPackage>, String> {
|
||||
// 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 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 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 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())
|
||||
}
|
||||
|
|
@ -2,13 +2,13 @@ use std::collections::HashMap;
|
|||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use onelauncher::cluster::content::logger;
|
||||
use onelauncher::cluster::{self};
|
||||
use onelauncher::data::{Loader, PackageData};
|
||||
use onelauncher::processor::DetailedProcess;
|
||||
use onelauncher::store::{Cluster, ClusterPath};
|
||||
use onelauncher::utils::java::JavaVersion;
|
||||
use onelauncher::State;
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -1,152 +0,0 @@
|
|||
use interpulse::api::minecraft::Version;
|
||||
use onelauncher::data::Settings;
|
||||
use onelauncher::settings;
|
||||
use tauri::{AppHandle, Manager};
|
||||
|
||||
mod cluster;
|
||||
pub use crate::api::commands::cluster::*;
|
||||
|
||||
mod users;
|
||||
pub use crate::api::commands::users::*;
|
||||
|
||||
mod processor;
|
||||
pub use crate::api::commands::processor::*;
|
||||
|
||||
mod package;
|
||||
pub use crate::api::commands::package::*;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! collect_commands {
|
||||
() => {{
|
||||
use $crate::api::commands::*;
|
||||
use $crate::ext::updater::*;
|
||||
tauri_specta::collect_commands![
|
||||
// User
|
||||
auth_login,
|
||||
get_users,
|
||||
get_user,
|
||||
get_default_user,
|
||||
set_default_user,
|
||||
remove_user,
|
||||
// Cluster
|
||||
create_cluster,
|
||||
edit_game_settings,
|
||||
edit_cluster_meta,
|
||||
remove_cluster,
|
||||
get_cluster,
|
||||
get_clusters,
|
||||
get_clusters_grouped,
|
||||
run_cluster,
|
||||
get_cluster_logs,
|
||||
get_cluster_log,
|
||||
upload_log,
|
||||
get_screenshots,
|
||||
get_worlds,
|
||||
get_optimal_java_version,
|
||||
repair_cluster,
|
||||
// Processor
|
||||
get_running_clusters,
|
||||
get_processes_by_path,
|
||||
kill_process,
|
||||
is_cluster_running,
|
||||
get_pid_by_uuid,
|
||||
get_user_by_process,
|
||||
get_process_started_at,
|
||||
get_processes_detailed_by_path,
|
||||
get_process_detailed_by_id,
|
||||
// Settings
|
||||
get_settings,
|
||||
set_settings,
|
||||
// Metadata
|
||||
get_minecraft_versions,
|
||||
// Launcher Packages (Instances)
|
||||
get_launcher_instances,
|
||||
import_instances,
|
||||
// Provider Packages
|
||||
get_provider_package,
|
||||
get_provider_packages,
|
||||
get_all_provider_package_versions,
|
||||
get_provider_package_versions,
|
||||
search_provider_packages,
|
||||
get_provider_authors,
|
||||
get_package_body,
|
||||
download_provider_package,
|
||||
// Cluster Packages
|
||||
get_cluster_package,
|
||||
get_cluster_packages,
|
||||
add_cluster_package,
|
||||
remove_cluster_package,
|
||||
set_cluster_package_enabled,
|
||||
sync_cluster_packages,
|
||||
sync_cluster_packages_by_type,
|
||||
// Updater
|
||||
check_for_update,
|
||||
install_update,
|
||||
// Other
|
||||
set_window_style,
|
||||
get_program_info,
|
||||
get_featured_packages,
|
||||
get_zulu_packages,
|
||||
install_java_from_package,
|
||||
open_dev_tools,
|
||||
]
|
||||
}};
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub fn open_dev_tools(_webview: tauri::WebviewWindow) {
|
||||
#[cfg(feature = "devtools")]
|
||||
_webview.open_devtools();
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn get_zulu_packages() -> Result<Vec<onelauncher::java::JavaZuluPackage>, String> {
|
||||
Ok(onelauncher::java::get_zulu_packages().await?)
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::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?)
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn get_featured_packages() -> Result<Vec<onelauncher::package::content::FeaturedPackage>, String> {
|
||||
Ok(onelauncher::package::content::get_featured_packages().await?)
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub fn get_program_info() -> Result<super::statics::ProgramInfo, String> {
|
||||
Ok(super::statics::get_program_info())
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn get_minecraft_versions() -> Result<Vec<Version>, String> {
|
||||
Ok(onelauncher::api::metadata::get_minecraft_versions()
|
||||
.await?
|
||||
.versions)
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn get_settings() -> Result<Settings, String> {
|
||||
Ok(settings::get().await?)
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
pub async fn set_settings(settings: Settings) -> Result<(), String> {
|
||||
Ok(settings::set(settings).await?)
|
||||
}
|
||||
|
||||
#[specta::specta]
|
||||
#[tauri::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())
|
||||
}
|
||||
|
|
@ -1,14 +1,8 @@
|
|||
#[macro_export]
|
||||
macro_rules! collect_events {
|
||||
() => {{
|
||||
use onelauncher::api::proxy::*;
|
||||
tauri_specta::collect_events![
|
||||
ClusterPayload,
|
||||
IngressPayload,
|
||||
MessagePayload,
|
||||
ProcessPayload,
|
||||
InternetPayload,
|
||||
OfflinePayload,
|
||||
]
|
||||
tauri_specta::collect_events! {
|
||||
onelauncher_core::api::proxy::event::LauncherEvent
|
||||
}
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,103 +1,3 @@
|
|||
use onelauncher::State;
|
||||
use serde::{Serialize, Serializer};
|
||||
use tauri::plugin::TauriPlugin;
|
||||
use tauri::Manager;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
pub mod commands;
|
||||
pub mod events;
|
||||
pub mod statics;
|
||||
|
||||
#[must_use]
|
||||
pub fn init<R: tauri::Runtime>() -> TauriPlugin<R> {
|
||||
tauri::plugin::Builder::new("onelauncher")
|
||||
.setup(|app, _| {
|
||||
app.manage(Mutex::new(State::get()));
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.build()
|
||||
}
|
||||
|
||||
// TODO: fix the error system/rspc
|
||||
pub type Result<T> = std::result::Result<T, OneLauncherSerializableError>;
|
||||
|
||||
#[derive(thiserror::Error, Debug, Serialize, specta::Type)]
|
||||
pub enum OneLauncherSerializableError {
|
||||
#[error("{0}")]
|
||||
CommonError(String),
|
||||
}
|
||||
|
||||
impl From<OneLauncherError> for OneLauncherSerializableError {
|
||||
fn from(value: OneLauncherError) -> Self {
|
||||
Self::CommonError(value.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<onelauncher::Error> for OneLauncherSerializableError {
|
||||
fn from(value: onelauncher::Error) -> Self {
|
||||
Self::CommonError(value.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum OneLauncherError {
|
||||
#[error("{0}")]
|
||||
OneLauncher(#[from] onelauncher::Error),
|
||||
|
||||
#[error("failed to handle io management: {0}")]
|
||||
IO(#[from] std::io::Error),
|
||||
|
||||
#[error("failed to handle tauri management: {0}")]
|
||||
Tauri(#[from] tauri::Error),
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[error("failed to handle callback: {0}")]
|
||||
Callback(String),
|
||||
}
|
||||
|
||||
// serialization code from https://github.com/modrinth/theseus/blob/master/theseus_gui/src-tauri/src/api/mod.rs
|
||||
// (yoinked under MIT license)
|
||||
macro_rules! impl_serialize_err {
|
||||
($($variant:ident),* $(,)?) => {
|
||||
impl Serialize for OneLauncherError {
|
||||
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
use serde::ser::SerializeStruct;
|
||||
match self {
|
||||
OneLauncherError::OneLauncher(onelauncher_error) => {
|
||||
$crate::error::display_tracing_error(onelauncher_error);
|
||||
|
||||
let mut state = serializer.serialize_struct("OneLauncher", 2)?;
|
||||
state.serialize_field("field_name", "OneLauncher")?;
|
||||
state.serialize_field("message", &onelauncher_error.to_string())?;
|
||||
state.end()
|
||||
}
|
||||
$(
|
||||
OneLauncherError::$variant(message) => {
|
||||
let mut state = serializer.serialize_struct(stringify!($variant), 2)?;
|
||||
state.serialize_field("field_name", stringify!($variant))?;
|
||||
state.serialize_field("message", &message.to_string())?;
|
||||
state.end()
|
||||
},
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
impl_serialize_err! {
|
||||
IO,
|
||||
Tauri,
|
||||
Callback
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
impl_serialize_err! {
|
||||
IO,
|
||||
Tauri,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use onelauncher::constants::{NATIVE_ARCH, TARGET_OS, VERSION};
|
||||
use onelauncher_core::{constants::{NATIVE_ARCH, TARGET_OS}, store::Core};
|
||||
use serde::Serialize;
|
||||
use specta::Type;
|
||||
|
||||
|
|
@ -14,15 +14,12 @@ pub struct ProgramInfo {
|
|||
|
||||
#[must_use]
|
||||
pub fn get_program_info() -> ProgramInfo {
|
||||
let webview_version = tauri::webview_version().unwrap_or_else(|_| "UNKNOWN".into());
|
||||
let tauri_version = tauri::VERSION;
|
||||
let dev_build = tauri::is_dev();
|
||||
|
||||
ProgramInfo {
|
||||
launcher_version: VERSION.into(),
|
||||
webview_version,
|
||||
tauri_version: tauri_version.into(),
|
||||
dev_build,
|
||||
launcher_version: Core::get().launcher_version.clone(),
|
||||
webview_version: tauri::webview_version().unwrap_or_else(|_| "UNKNOWN".into()),
|
||||
tauri_version: tauri::VERSION.into(),
|
||||
dev_build: tauri::is_dev(),
|
||||
platform: TARGET_OS.into(),
|
||||
arch: NATIVE_ARCH.into(),
|
||||
}
|
||||
|
|
|
|||
3
apps/desktop/src/constants.rs
Normal file
3
apps/desktop/src/constants.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
// === API ===
|
||||
pub const CURSEFORGE_API_KEY: &str = "$2a$10$6utA1UNSmFPrE/Lh7b7ndeeGmiOkjKNY8kpFB0fsmE/d42ZAfFgCe";
|
||||
pub const DISCORD_CLIENT_ID: &str = "1274084193193955408";
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
use tracing_error::ExtractSpanTrace;
|
||||
|
||||
pub fn display_tracing_error(err: &onelauncher::Error) {
|
||||
match get_span_trace(err) {
|
||||
Some(span_trace) => {
|
||||
tracing::error!(error = %err, span_trace = %span_trace);
|
||||
}
|
||||
None => {
|
||||
tracing::error!(error = %err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_span_trace<'a>(
|
||||
error: &'a (dyn std::error::Error + 'static),
|
||||
) -> Option<&'a tracing_error::SpanTrace> {
|
||||
error.source().and_then(|e| e.span_trace())
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// TODO: this should be a specta event
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, specta::Type, tauri_specta::Event)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DeepLinkEvent {
|
||||
data: String,
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -1,5 +1,2 @@
|
|||
pub mod deeplink;
|
||||
pub mod macos;
|
||||
pub mod menu;
|
||||
pub mod specta;
|
||||
pub mod updater;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use onelauncher_core::store::Core;
|
||||
use tauri::plugin::TauriPlugin;
|
||||
use tauri::{Emitter, Runtime};
|
||||
use tauri_plugin_updater::{Update as TauriPluginUpdate, UpdaterExt};
|
||||
|
|
@ -32,7 +33,6 @@ async fn get_update(app: tauri::AppHandle) -> Result<Option<TauriPluginUpdate>,
|
|||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
// TODO: this should be a specta event
|
||||
#[derive(Debug, Clone, serde::Serialize, specta::Type, tauri_specta::Event)]
|
||||
#[serde(rename_all = "camelCase", tag = "status")]
|
||||
pub enum UpdateEvent {
|
||||
|
|
@ -111,7 +111,7 @@ pub fn plugin<R: Runtime>() -> TauriPlugin<R> {
|
|||
})
|
||||
.js_init_script(format!(
|
||||
r#"window.__ONELAUNCHER_VERSION__ = "{}";"#,
|
||||
onelauncher::constants::VERSION,
|
||||
Core::get().launcher_version,
|
||||
))
|
||||
.build()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
#![allow(trivial_casts)]
|
||||
use onelauncher::utils::window::set_window_styling;
|
||||
use onelauncher_core::{api::proxy::ProxyTauri, error::LauncherResult, store::{proxy::ProxyState, semaphore::SemaphoreStore, Core, CoreOptions, Dirs, State}};
|
||||
use tauri::{Emitter, Manager};
|
||||
|
||||
pub mod api;
|
||||
pub mod error;
|
||||
pub mod ext;
|
||||
pub mod constants;
|
||||
|
||||
#[derive(Clone, serde::Serialize)]
|
||||
pub struct SingleInstancePayload {
|
||||
|
|
@ -12,37 +11,29 @@ pub struct SingleInstancePayload {
|
|||
cwd: String,
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn initialize_state(handle: &tauri::AppHandle) -> api::Result<()> {
|
||||
onelauncher::ProxyState::initialize(handle).await?;
|
||||
let s = onelauncher::State::get().await?;
|
||||
onelauncher::State::update();
|
||||
s.processor.write().await.restore().await?;
|
||||
#[tracing::instrument]
|
||||
async fn initialize_core() -> LauncherResult<()> {
|
||||
let opts = CoreOptions {
|
||||
curseforge_api_key: Some(constants::CURSEFORGE_API_KEY.to_string()),
|
||||
launcher_name: "OneLauncher".to_string(),
|
||||
launcher_version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
launcher_website: "https://polyfrost.org/".to_string(),
|
||||
discord_client_id: Some(constants::DISCORD_CLIENT_ID.to_string()),
|
||||
fetch_attempts: 3,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Core::initialize(opts).await?;
|
||||
Dirs::get().await?;
|
||||
onelauncher_core::start_logger().await;
|
||||
SemaphoreStore::get().await;
|
||||
tracing::info!("initialized core modules");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// the main entrypoint to the desktop add (initializes the logger and runs the app)
|
||||
///
|
||||
/// if the logger fails to initialize then we will panic because
|
||||
/// nothing else can be debugged once the logger fails.
|
||||
///
|
||||
/// the only thing that can fail before the logger should be our [`tokio::main`] loop.
|
||||
pub async fn run() {
|
||||
let _log_guard = onelauncher::start_logger();
|
||||
tracing::info!("initialized logger. loading onelauncher/tauri...");
|
||||
|
||||
run_app(tauri::Builder::default(), |app| {
|
||||
if let Err(err) = setup(app) {
|
||||
tracing::error!("failed to setup app: {:?}", err);
|
||||
}
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn run_app<F: FnOnce(&tauri::AppHandle<tauri::Wry>) + Send + 'static>(
|
||||
builder: tauri::Builder<tauri::Wry>,
|
||||
setup: F,
|
||||
) {
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn initialize_tauri(builder: tauri::Builder<tauri::Wry>) -> LauncherResult<tauri::App> {
|
||||
let prebuild = tauri_specta::Builder::<tauri::Wry>::new()
|
||||
.commands(collect_commands!())
|
||||
.events(collect_events!());
|
||||
|
|
@ -58,7 +49,6 @@ pub async fn run_app<F: FnOnce(&tauri::AppHandle<tauri::Wry>) + Send + 'static>(
|
|||
.expect("failed to export debug bindings!");
|
||||
|
||||
let builder = builder
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_single_instance::init(|app, argv, cwd| {
|
||||
println!("{}, {argv:?}, {cwd}", app.package_info().name);
|
||||
app.emit("single-instance", SingleInstancePayload { args: argv, cwd })
|
||||
|
|
@ -70,12 +60,12 @@ pub async fn run_app<F: FnOnce(&tauri::AppHandle<tauri::Wry>) + Send + 'static>(
|
|||
.manage(ext::updater::State::default())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_deep_link::init())
|
||||
.plugin(api::init())
|
||||
// .plugin(api::init())
|
||||
.menu(tauri::menu::Menu::new)
|
||||
.invoke_handler(prebuild.invoke_handler())
|
||||
.setup(move |app| {
|
||||
prebuild.mount_events(app.handle());
|
||||
setup(app.handle());
|
||||
setup_window(app.handle());
|
||||
Ok(())
|
||||
});
|
||||
|
||||
|
|
@ -83,54 +73,39 @@ pub async fn run_app<F: FnOnce(&tauri::AppHandle<tauri::Wry>) + Send + 'static>(
|
|||
.build(tauri::generate_context!())
|
||||
.expect("failed to build tauri application");
|
||||
|
||||
if let Err(err) = initialize_state(app.handle()).await {
|
||||
tracing::error!("{err}");
|
||||
};
|
||||
Ok(app)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
async fn initialize_state(handle: &tauri::AppHandle) -> LauncherResult<()> {
|
||||
let proxy = ProxyTauri::new(handle.clone());
|
||||
ProxyState::initialize(proxy).await?;
|
||||
|
||||
State::get().await?;
|
||||
|
||||
tracing::info!("initialized launcher successfully");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
app.run(|_, _| {});
|
||||
}
|
||||
|
||||
fn setup(handle: &tauri::AppHandle) -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn setup_window(handle: &tauri::AppHandle) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let win = handle.get_webview_window("main").unwrap();
|
||||
|
||||
tokio::task::spawn(async move {
|
||||
let state = onelauncher::State::get();
|
||||
let state = match state.await {
|
||||
Ok(state) => state,
|
||||
Err(err) => {
|
||||
tracing::error!("{err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
// tokio::task::spawn(async move {
|
||||
// // let state = State::get().await.expect("failed to get state");
|
||||
// // let settings = state.settings.read().await;
|
||||
// // win.set_decorations(settings.);
|
||||
// });
|
||||
|
||||
let settings = state.settings.read().await;
|
||||
|
||||
if let Err(err) = set_window_styling(&win, settings.custom_frame) {
|
||||
tracing::error!(err);
|
||||
};
|
||||
|
||||
win.show().unwrap();
|
||||
});
|
||||
win.show().unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: Add tests
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use tauri::Manager;
|
||||
|
||||
// #[tokio::test]
|
||||
// async fn run_app() {
|
||||
// super::run_app(tauri::test::mock_builder(), |app| {
|
||||
// super::setup(app);
|
||||
|
||||
// let win = app.get_webview_window("main").unwrap();
|
||||
// tokio::spawn(async move {
|
||||
// tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
|
||||
// win.close().unwrap();
|
||||
// });
|
||||
// })
|
||||
// .await
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
@ -1,9 +1,6 @@
|
|||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
#[global_allocator]
|
||||
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
onelauncher_gui::run().await;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
"license": "GPL-3.0-only",
|
||||
"homepage": "https://polyfrost.org/",
|
||||
"longDescription": "Next-generation open source Minecraft launcher",
|
||||
"createUpdaterArtifacts": false,
|
||||
"createUpdaterArtifacts": true,
|
||||
"resources": [],
|
||||
"externalBin": [],
|
||||
"linux": {
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@ tauri = [
|
|||
"dep:tauri",
|
||||
"dep:tauri-specta",
|
||||
"specta",
|
||||
"gui"
|
||||
"gui",
|
||||
"onelauncher_macro/tauri",
|
||||
]
|
||||
specta = [
|
||||
"dep:specta",
|
||||
"interpulse/specta",
|
||||
"onelauncher_entity/specta"
|
||||
"onelauncher_entity/specta",
|
||||
"onelauncher_macro/specta",
|
||||
]
|
||||
cli = [ "dep:indicatif" ]
|
||||
gui = []
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
use api::proxy::LauncherProxy;
|
||||
use store::{proxy::ProxyState, semaphore::SemaphoreStore, Core, CoreOptions, Dirs, State};
|
||||
use error::LauncherResult;
|
||||
use logger::start_logger;
|
||||
pub use logger::start_logger;
|
||||
|
||||
pub mod api;
|
||||
pub mod constants;
|
||||
|
|
@ -14,7 +14,7 @@ pub mod utils;
|
|||
|
||||
mod logger;
|
||||
|
||||
pub use onelauncher_macro as macros;
|
||||
pub use onelauncher_macro::*;
|
||||
pub use onelauncher_entity as entity;
|
||||
pub use onelauncher_migration as migration;
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ impl Core {
|
|||
Ok::<_, LauncherError>(Self::new(options))
|
||||
}).await?;
|
||||
|
||||
tracing::info!("core initialized successfully");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ impl Dirs {
|
|||
.or_else(|| Some(dirs::data_dir()?.join(Core::get().launcher_name.clone())))
|
||||
.ok_or(DirectoryError::BaseDir)?;
|
||||
|
||||
tracing::info!("using base directory '{}'", base_dir.display());
|
||||
|
||||
Ok(Self {
|
||||
base_dir
|
||||
})
|
||||
|
|
|
|||
|
|
@ -16,7 +16,11 @@ path = "src/lib.rs"
|
|||
|
||||
[features]
|
||||
default = []
|
||||
specta = [ "dep:specta", "interpulse/specta" ]
|
||||
specta = [
|
||||
"onelauncher_macro/specta",
|
||||
"dep:specta",
|
||||
"interpulse/specta"
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
onelauncher_macro = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ proc-macro = true
|
|||
|
||||
[features]
|
||||
default = []
|
||||
tauri = [ "specta" ]
|
||||
specta = []
|
||||
|
||||
[dependencies]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
#[cfg(feature = "specta")]
|
||||
mod specta;
|
||||
|
||||
#[cfg(feature = "tauri")]
|
||||
mod tauri;
|
||||
|
||||
mod pin;
|
||||
|
||||
/// This macro is used to derive the `specta::Type` trait for the annotated item.
|
||||
|
|
@ -18,10 +23,23 @@ mod pin;
|
|||
/// #[cfg_attr(feature = "tauri", derive(tauri_specta::Event))]
|
||||
/// ```
|
||||
#[proc_macro_attribute]
|
||||
#[cfg(feature = "specta")]
|
||||
pub fn specta(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
specta::specta(attr, item)
|
||||
}
|
||||
|
||||
/// This macro is used to derive the `tauri::command` as well as the `specta::specta` attribute for the annotated item.
|
||||
/// #### Expands to:
|
||||
/// ```
|
||||
/// #[specta::specta]
|
||||
/// #[tauri::command]
|
||||
/// ```
|
||||
#[proc_macro_attribute]
|
||||
#[cfg(feature = "tauri")]
|
||||
pub fn command(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
tauri::tauri_command(attr, item)
|
||||
}
|
||||
|
||||
/// This macro Box::Pin a function
|
||||
#[proc_macro_attribute]
|
||||
pub fn pin(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
|
|
|
|||
14
packages/macro/src/tauri.rs
Normal file
14
packages/macro/src/tauri.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use quote::quote;
|
||||
use syn::{parse_macro_input, Item};
|
||||
|
||||
pub fn tauri_command(_attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(item as Item);
|
||||
|
||||
let expanded = quote! {
|
||||
#[specta::specta]
|
||||
#[tauri::command]
|
||||
#input
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue