mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-13 16:22:43 +10:00
refactor: Improvements to src-tauri
Signed-off-by: quexeky <git@quexeky.dev>
This commit is contained in:
@ -80,11 +80,12 @@ bytes = "1.10.1"
|
||||
|
||||
|
||||
# Workspaces
|
||||
client = { path = "../client" }
|
||||
client = { version = "0.1.0", path = "../client" }
|
||||
database = { path = "../database" }
|
||||
process = { path = "../process" }
|
||||
remote = { path = "../remote" }
|
||||
remote = { version = "0.1.0", path = "../remote" }
|
||||
utils = { path = "../utils" }
|
||||
games = { version = "0.1.0", path = "../games" }
|
||||
|
||||
[dependencies.dynfmt]
|
||||
version = "0.1.5"
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
use crate::{lock, AppState};
|
||||
use database::{borrow_db_checked, borrow_db_mut_checked};
|
||||
use log::{debug, error};
|
||||
use tauri::AppHandle;
|
||||
use tauri_plugin_autostart::ManagerExt;
|
||||
use utils::lock;
|
||||
|
||||
use crate::{AppState};
|
||||
|
||||
#[tauri::command]
|
||||
pub fn fetch_state(
|
||||
@ -31,10 +37,39 @@ pub fn cleanup_and_exit(app: &AppHandle, state: &tauri::State<'_, std::sync::Mut
|
||||
|
||||
#[tauri::command]
|
||||
pub fn toggle_autostart(app: AppHandle, enabled: bool) -> Result<(), String> {
|
||||
toggle_autostart_logic(app, enabled)
|
||||
let manager = app.autolaunch();
|
||||
if enabled {
|
||||
manager.enable().map_err(|e| e.to_string())?;
|
||||
debug!("enabled autostart");
|
||||
} else {
|
||||
manager.disable().map_err(|e| e.to_string())?;
|
||||
debug!("eisabled autostart");
|
||||
}
|
||||
|
||||
// Store the state in DB
|
||||
let mut db_handle = borrow_db_mut_checked();
|
||||
db_handle.settings.autostart = enabled;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_autostart_enabled(app: AppHandle) -> Result<bool, tauri_plugin_autostart::Error> {
|
||||
get_autostart_enabled_logic(app)
|
||||
let db_handle = borrow_db_checked();
|
||||
let db_state = db_handle.settings.autostart;
|
||||
drop(db_handle);
|
||||
|
||||
// Get actual system state
|
||||
let manager = app.autolaunch();
|
||||
let system_state = manager.is_enabled()?;
|
||||
|
||||
// If they don't match, sync to DB state
|
||||
if db_state != system_state {
|
||||
if db_state {
|
||||
manager.enable()?;
|
||||
} else {
|
||||
manager.disable()?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(db_state)
|
||||
}
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
use std::{fmt::Display, io, sync::mpsc::SendError};
|
||||
|
||||
use serde_with::SerializeDisplay;
|
||||
|
||||
#[derive(SerializeDisplay)]
|
||||
pub enum DownloadManagerError<T> {
|
||||
IOError(io::Error),
|
||||
SignalError(SendError<T>),
|
||||
}
|
||||
impl<T> Display for DownloadManagerError<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
DownloadManagerError::IOError(error) => write!(f, "{error}"),
|
||||
DownloadManagerError::SignalError(send_error) => write!(f, "{send_error}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T> From<SendError<T>> for DownloadManagerError<T> {
|
||||
fn from(value: SendError<T>) -> Self {
|
||||
DownloadManagerError::SignalError(value)
|
||||
}
|
||||
}
|
||||
impl<T> From<io::Error> for DownloadManagerError<T> {
|
||||
fn from(value: io::Error) -> Self {
|
||||
DownloadManagerError::IOError(value)
|
||||
}
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
pub mod application_download_error;
|
||||
pub mod download_manager_error;
|
||||
pub mod drop_server_error;
|
||||
pub mod library_error;
|
||||
pub mod process_error;
|
||||
pub mod remote_access_error;
|
||||
pub mod cache_error;
|
||||
@ -1,28 +1,15 @@
|
||||
use std::sync::Mutex;
|
||||
|
||||
use database::{borrow_db_checked, borrow_db_mut_checked, GameDownloadStatus, GameVersion};
|
||||
use games::{downloads::error::LibraryError, library::{get_current_meta, uninstall_game_logic, FetchGameStruct, Game}, state::{GameStatusManager, GameStatusWithTransient}};
|
||||
use log::warn;
|
||||
use process::PROCESS_MANAGER;
|
||||
use remote::{auth::generate_authorization_header, cache::{cache_object, cache_object_db, get_cached_object, get_cached_object_db}, error::{DropServerError, RemoteAccessError}, offline, requests::generate_url, utils::DROP_CLIENT_ASYNC};
|
||||
use tauri::AppHandle;
|
||||
use utils::lock;
|
||||
|
||||
use crate::{
|
||||
AppState,
|
||||
database::{
|
||||
db::borrow_db_checked,
|
||||
models::data::GameVersion,
|
||||
},
|
||||
error::{library_error::LibraryError, remote_access_error::RemoteAccessError},
|
||||
games::library::{
|
||||
fetch_game_logic_offline, fetch_library_logic_offline, get_current_meta,
|
||||
uninstall_game_logic,
|
||||
},
|
||||
offline,
|
||||
};
|
||||
use crate::AppState;
|
||||
|
||||
use super::{
|
||||
library::{
|
||||
FetchGameStruct, Game, fetch_game_logic, fetch_game_version_options_logic,
|
||||
fetch_library_logic,
|
||||
},
|
||||
state::{GameStatusManager, GameStatusWithTransient},
|
||||
};
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn fetch_library(
|
||||
@ -72,18 +59,18 @@ pub async fn fetch_library_logic(
|
||||
let mut db_handle = borrow_db_mut_checked();
|
||||
|
||||
for game in &games {
|
||||
handle.games.insert(game.id.clone(), game.clone());
|
||||
if !db_handle.applications.game_statuses.contains_key(&game.id) {
|
||||
handle.games.insert(game.id().clone(), game.clone());
|
||||
if !db_handle.applications.game_statuses.contains_key(game.id()) {
|
||||
db_handle
|
||||
.applications
|
||||
.game_statuses
|
||||
.insert(game.id.clone(), GameDownloadStatus::Remote {});
|
||||
.insert(game.id().clone(), GameDownloadStatus::Remote {});
|
||||
}
|
||||
}
|
||||
|
||||
// Add games that are installed but no longer in library
|
||||
for meta in db_handle.applications.installed_game_version.values() {
|
||||
if games.iter().any(|e| e.id == meta.id) {
|
||||
if games.iter().any(|e| *e.id() == meta.id) {
|
||||
continue;
|
||||
}
|
||||
// We should always have a cache of the object
|
||||
@ -120,7 +107,7 @@ pub async fn fetch_library_logic_offline(
|
||||
&db_handle
|
||||
.applications
|
||||
.game_statuses
|
||||
.get(&game.id)
|
||||
.get(game.id())
|
||||
.unwrap_or(&GameDownloadStatus::Remote {}),
|
||||
GameDownloadStatus::Installed { .. } | GameDownloadStatus::SetupRequired { .. }
|
||||
)
|
||||
@ -152,11 +139,7 @@ pub async fn fetch_game_logic(
|
||||
if let Some(game) = game {
|
||||
let status = GameStatusManager::fetch_state(&id, &db_lock);
|
||||
|
||||
let data = FetchGameStruct {
|
||||
game: game.clone(),
|
||||
status,
|
||||
version,
|
||||
};
|
||||
let data = FetchGameStruct::new(game.clone(), status, version);
|
||||
|
||||
cache_object_db(&id, game, &db_lock)?;
|
||||
|
||||
@ -205,11 +188,7 @@ pub async fn fetch_game_logic(
|
||||
|
||||
drop(db_handle);
|
||||
|
||||
let data = FetchGameStruct {
|
||||
game: game.clone(),
|
||||
status,
|
||||
version,
|
||||
};
|
||||
let data = FetchGameStruct::new(game.clone(), status, version);
|
||||
|
||||
cache_object(&id, &game)?;
|
||||
|
||||
@ -238,10 +217,10 @@ pub async fn fetch_game_version_options_logic(
|
||||
let data: Vec<GameVersion> = response.json().await?;
|
||||
|
||||
let state_lock = lock!(state);
|
||||
let process_manager_lock = lock!(state_lock.process_manager);
|
||||
let process_manager_lock = PROCESS_MANAGER.lock();
|
||||
let data: Vec<GameVersion> = data
|
||||
.into_iter()
|
||||
.filter(|v| process_manager_lock.valid_platform(&v.platform, &state_lock))
|
||||
.filter(|v| process_manager_lock.valid_platform(&v.platform))
|
||||
.collect();
|
||||
drop(process_manager_lock);
|
||||
drop(state_lock);
|
||||
@ -271,11 +250,7 @@ pub async fn fetch_game_logic_offline(
|
||||
|
||||
drop(db_handle);
|
||||
|
||||
Ok(FetchGameStruct {
|
||||
game,
|
||||
status,
|
||||
version,
|
||||
})
|
||||
Ok(FetchGameStruct::new(game, status, version))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
@ -3,12 +3,21 @@
|
||||
#![feature(duration_constructors)]
|
||||
#![feature(duration_millis_float)]
|
||||
#![feature(iterator_try_collect)]
|
||||
#![feature(nonpoison_mutex)]
|
||||
#![deny(clippy::all)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use ::client::{app_status::AppStatus, compat::CompatInfo, user::User};
|
||||
use database::{borrow_db_checked, GameDownloadStatus};
|
||||
use ::games::library::Game;
|
||||
use ::remote::auth;
|
||||
use serde::Serialize;
|
||||
use tauri::AppHandle;
|
||||
|
||||
mod games;
|
||||
|
||||
mod client;
|
||||
mod error;
|
||||
mod process;
|
||||
mod remote;
|
||||
|
||||
@ -19,13 +28,6 @@ pub struct AppState<'a> {
|
||||
status: AppStatus,
|
||||
user: Option<User>,
|
||||
games: HashMap<String, Game>,
|
||||
|
||||
#[serde(skip_serializing)]
|
||||
download_manager: Arc<DownloadManager>,
|
||||
#[serde(skip_serializing)]
|
||||
process_manager: Arc<Mutex<ProcessManager<'a>>>,
|
||||
#[serde(skip_serializing)]
|
||||
compat_info: Option<CompatInfo>,
|
||||
}
|
||||
|
||||
async fn setup(handle: AppHandle) -> AppState<'static> {
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
use std::sync::Mutex;
|
||||
|
||||
use crate::{AppState, error::process_error::ProcessError, lock};
|
||||
use process::{error::ProcessError, PROCESS_MANAGER};
|
||||
use tauri::AppHandle;
|
||||
use tauri_plugin_opener::OpenerExt;
|
||||
use utils::lock;
|
||||
|
||||
use crate::AppState;
|
||||
|
||||
#[tauri::command]
|
||||
pub fn launch_game(
|
||||
@ -8,8 +13,7 @@ pub fn launch_game(
|
||||
state: tauri::State<'_, Mutex<AppState>>,
|
||||
) -> Result<(), ProcessError> {
|
||||
let state_lock = lock!(state);
|
||||
let mut process_manager_lock = lock!(state_lock.process_manager);
|
||||
|
||||
let process_manager_lock = PROCESS_MANAGER.lock();
|
||||
//let meta = DownloadableMetadata {
|
||||
// id,
|
||||
// version: Some(version),
|
||||
@ -30,11 +34,9 @@ pub fn launch_game(
|
||||
#[tauri::command]
|
||||
pub fn kill_game(
|
||||
game_id: String,
|
||||
state: tauri::State<'_, Mutex<AppState>>,
|
||||
) -> Result<(), ProcessError> {
|
||||
let state_lock = lock!(state);
|
||||
let mut process_manager_lock = lock!(state_lock.process_manager);
|
||||
process_manager_lock
|
||||
PROCESS_MANAGER
|
||||
.lock()
|
||||
.kill_game(game_id)
|
||||
.map_err(ProcessError::IOError)
|
||||
}
|
||||
@ -42,17 +44,13 @@ pub fn kill_game(
|
||||
#[tauri::command]
|
||||
pub fn open_process_logs(
|
||||
game_id: String,
|
||||
state: tauri::State<'_, Mutex<AppState>>,
|
||||
app_handle: AppHandle
|
||||
) -> Result<(), ProcessError> {
|
||||
let state_lock = lock!(state);
|
||||
let mut process_manager_lock = lock!(state_lock.process_manager);
|
||||
let process_manager_lock = PROCESS_MANAGER.lock();
|
||||
|
||||
let dir = process_manager_lock.get_log_dir(game_id);
|
||||
state
|
||||
.handle()
|
||||
app_handle
|
||||
.opener()
|
||||
.open_path(dir.display().to_string(), None::<&str>)
|
||||
.map_err(ProcessError::OpenerError)?;
|
||||
|
||||
process_manager_lock.open_process_logs(game_id)
|
||||
.map_err(ProcessError::OpenerError)
|
||||
}
|
||||
|
||||
@ -1,30 +1,17 @@
|
||||
use std::sync::Mutex;
|
||||
use std::{sync::Mutex, time::Duration};
|
||||
|
||||
use client::app_status::AppStatus;
|
||||
use database::{borrow_db_checked, borrow_db_mut_checked};
|
||||
use futures_lite::StreamExt;
|
||||
use log::{debug, warn};
|
||||
use remote::{auth::{auth_initiate_logic, generate_authorization_header}, cache::{cache_object, get_cached_object}, error::RemoteAccessError, requests::generate_url, setup, utils::{DropHealthcheck, DROP_CLIENT_ASYNC, DROP_CLIENT_WS_CLIENT}};
|
||||
use reqwest_websocket::{Message, RequestBuilderExt};
|
||||
use serde::Deserialize;
|
||||
use tauri::{AppHandle, Emitter, Manager};
|
||||
use url::Url;
|
||||
use utils::{app_emit, lock, webbrowser_open::webbrowser_open};
|
||||
|
||||
use crate::{
|
||||
AppState, AppStatus, app_emit,
|
||||
database::db::{borrow_db_checked, borrow_db_mut_checked},
|
||||
error::remote_access_error::RemoteAccessError,
|
||||
lock,
|
||||
remote::{
|
||||
auth::generate_authorization_header,
|
||||
requests::generate_url,
|
||||
utils::{DROP_CLIENT_SYNC, DROP_CLIENT_WS_CLIENT},
|
||||
},
|
||||
utils::webbrowser_open::webbrowser_open,
|
||||
};
|
||||
|
||||
use super::{
|
||||
auth::{auth_initiate_logic, recieve_handshake, setup},
|
||||
cache::{cache_object, get_cached_object},
|
||||
utils::use_remote_logic,
|
||||
};
|
||||
use crate::{recieve_handshake, AppState};
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn use_remote(
|
||||
@ -45,7 +32,7 @@ pub async fn use_remote(
|
||||
|
||||
let result: DropHealthcheck = response.json().await?;
|
||||
|
||||
if result.app_name != "Drop" {
|
||||
if result.app_name() != "Drop" {
|
||||
warn!("user entered drop endpoint that connected, but wasn't identified as Drop");
|
||||
return Err(RemoteAccessError::InvalidEndpoint);
|
||||
}
|
||||
@ -77,7 +64,7 @@ pub fn gen_drop_url(path: String) -> Result<String, RemoteAccessError> {
|
||||
pub fn fetch_drop_object(path: String) -> Result<Vec<u8>, RemoteAccessError> {
|
||||
let _drop_url = gen_drop_url(path.clone())?;
|
||||
let req = generate_url(&[&path], &[])?;
|
||||
let req = DROP_CLIENT_SYNC
|
||||
let req = remote::utils::DROP_CLIENT_SYNC
|
||||
.get(req)
|
||||
.header("Authorization", generate_authorization_header())
|
||||
.send();
|
||||
|
||||
Reference in New Issue
Block a user