chore: refactored lib.rs to move commands into separate folder

This commit is contained in:
2026-01-15 16:17:06 +08:00
parent 7ae501aaf0
commit 86d964943e
11 changed files with 352 additions and 315 deletions

View File

@@ -0,0 +1,14 @@
use crate::get_app_handle;
#[tauri::command]
pub fn quit_app() -> Result<(), String> {
let app_handle = get_app_handle();
app_handle.exit(0);
Ok(())
}
#[tauri::command]
pub fn restart_app() {
let app_handle = get_app_handle();
app_handle.restart();
}

View File

@@ -0,0 +1,18 @@
use crate::{
lock_r,
models::app_data::AppData,
state::{init_app_data, FDOLL},
};
#[tauri::command]
pub fn get_app_data() -> Result<AppData, String> {
let guard = lock_r!(FDOLL);
return Ok(guard.app_data.clone());
}
#[tauri::command]
pub async fn refresh_app_data() -> Result<AppData, String> {
init_app_data().await;
let guard = lock_r!(FDOLL);
Ok(guard.app_data.clone())
}

View File

@@ -0,0 +1,25 @@
use tauri;
use tracing;
#[tauri::command]
pub async fn logout_and_restart() -> Result<(), String> {
crate::services::auth::logout_and_restart()
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
pub fn start_auth_flow() -> Result<(), String> {
// Cancel any in-flight auth listener/state before starting a new one
crate::services::auth::cancel_auth_flow();
crate::services::auth::init_auth_code_retrieval(|| {
tracing::info!("Authentication successful, creating scene...");
// Close welcome window if it's still open
crate::services::welcome::close_welcome_window();
tauri::async_runtime::spawn(async {
crate::app::bootstrap().await;
});
})
.map_err(|e| e.to_string())
}

View File

@@ -0,0 +1,31 @@
use crate::{
services::client_config_manager::{
load_app_config, open_config_manager_window, save_app_config, AppConfig,
},
state::FDOLL,
lock_w,
};
#[tauri::command]
pub fn get_client_config() -> AppConfig {
let mut guard = lock_w!(FDOLL);
guard.app_config = load_app_config();
guard.app_config.clone()
}
#[tauri::command]
pub fn save_client_config(config: AppConfig) -> Result<(), String> {
match save_app_config(config) {
Ok(saved) => {
let mut guard = lock_w!(FDOLL);
guard.app_config = saved;
Ok(())
}
Err(e) => Err(e.to_string()),
}
}
#[tauri::command]
pub async fn open_client_config_manager() -> Result<(), String> {
open_config_manager_window().map_err(|e| e.to_string())
}

View File

@@ -0,0 +1,135 @@
use crate::{
remotes::{
dolls::{CreateDollDto, DollDto, DollsRemote, UpdateDollDto},
user::UserRemote,
},
state::{init_app_data_scoped, AppDataRefreshScope, FDOLL},
lock_r,
};
use tauri::async_runtime;
#[tauri::command]
pub async fn get_dolls() -> Result<Vec<DollDto>, String> {
DollsRemote::new()
.get_dolls()
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
pub async fn get_doll(id: String) -> Result<DollDto, String> {
DollsRemote::new()
.get_doll(&id)
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
pub async fn create_doll(dto: CreateDollDto) -> Result<DollDto, String> {
let result = DollsRemote::new()
.create_doll(dto)
.await
.map_err(|e| e.to_string())?;
// Refresh dolls list in background (deduped inside init_app_data_scoped)
async_runtime::spawn(async {
init_app_data_scoped(AppDataRefreshScope::Dolls).await;
});
Ok(result)
}
#[tauri::command]
pub async fn update_doll(id: String, dto: UpdateDollDto) -> Result<DollDto, String> {
let result = DollsRemote::new()
.update_doll(&id, dto)
.await
.map_err(|e| e.to_string())?;
// Check if this was the active doll (after update completes to avoid stale reads)
let is_active_doll = {
let guard = lock_r!(FDOLL);
guard
.app_data
.user
.as_ref()
.and_then(|u| u.active_doll_id.as_ref())
.map(|active_id| active_id == &id)
.unwrap_or(false)
};
// Refresh dolls list + User/Friends if this was the active doll
async_runtime::spawn(async move {
init_app_data_scoped(AppDataRefreshScope::Dolls).await;
if is_active_doll {
init_app_data_scoped(AppDataRefreshScope::User).await;
init_app_data_scoped(AppDataRefreshScope::Friends).await;
}
});
Ok(result)
}
#[tauri::command]
pub async fn delete_doll(id: String) -> Result<(), String> {
DollsRemote::new()
.delete_doll(&id)
.await
.map_err(|e| e.to_string())?;
// Check if this was the active doll (after delete completes to avoid stale reads)
let is_active_doll = {
let guard = lock_r!(FDOLL);
guard
.app_data
.user
.as_ref()
.and_then(|u| u.active_doll_id.as_ref())
.map(|active_id| active_id == &id)
.unwrap_or(false)
};
// Refresh dolls list + User/Friends if the deleted doll was active
async_runtime::spawn(async move {
init_app_data_scoped(AppDataRefreshScope::Dolls).await;
if is_active_doll {
init_app_data_scoped(AppDataRefreshScope::User).await;
init_app_data_scoped(AppDataRefreshScope::Friends).await;
}
});
Ok(())
}
#[tauri::command]
pub async fn set_active_doll(doll_id: String) -> Result<(), String> {
UserRemote::new()
.set_active_doll(&doll_id)
.await
.map_err(|e| e.to_string())?;
// Refresh User (for active_doll_id) + Friends (so friends see your active doll)
// We don't need to refresh Dolls since the doll itself hasn't changed
async_runtime::spawn(async {
init_app_data_scoped(AppDataRefreshScope::User).await;
init_app_data_scoped(AppDataRefreshScope::Friends).await;
});
Ok(())
}
#[tauri::command]
pub async fn remove_active_doll() -> Result<(), String> {
UserRemote::new()
.remove_active_doll()
.await
.map_err(|e| e.to_string())?;
// Refresh User (for active_doll_id) + Friends (so friends see your doll is gone)
async_runtime::spawn(async {
init_app_data_scoped(AppDataRefreshScope::User).await;
init_app_data_scoped(AppDataRefreshScope::Friends).await;
});
Ok(())
}

View File

@@ -0,0 +1,78 @@
use crate::remotes::friends::{
FriendRemote, FriendRequestResponseDto, FriendshipResponseDto, SendFriendRequestDto,
UserBasicDto,
};
#[tauri::command]
pub async fn list_friends() -> Result<Vec<FriendshipResponseDto>, String> {
FriendRemote::new()
.get_friends()
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
pub async fn search_users(username: Option<String>) -> Result<Vec<UserBasicDto>, String> {
tracing::info!(
"Tauri command search_users called with username: {:?}",
username
);
let remote = FriendRemote::new();
tracing::info!("FriendRemote instance created for search_users");
let result = remote.search_users(username.as_deref()).await;
tracing::info!("FriendRemote::search_users result: {:?}", result);
result.map_err(|e| {
tracing::error!("search_users command error: {}", e);
e.to_string()
})
}
#[tauri::command]
pub async fn send_friend_request(
request: SendFriendRequestDto,
) -> Result<FriendRequestResponseDto, String> {
FriendRemote::new()
.send_friend_request(request)
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
pub async fn received_friend_requests() -> Result<Vec<FriendRequestResponseDto>, String> {
FriendRemote::new()
.get_received_requests()
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
pub async fn sent_friend_requests() -> Result<Vec<FriendRequestResponseDto>, String> {
FriendRemote::new()
.get_sent_requests()
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
pub async fn accept_friend_request(request_id: String) -> Result<FriendRequestResponseDto, String> {
FriendRemote::new()
.accept_friend_request(&request_id)
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
pub async fn deny_friend_request(request_id: String) -> Result<FriendRequestResponseDto, String> {
FriendRemote::new()
.deny_friend_request(&request_id)
.await
.map_err(|e| e.to_string())
}
#[tauri::command]
pub async fn unfriend(friend_id: String) -> Result<(), String> {
FriendRemote::new()
.unfriend(&friend_id)
.await
.map_err(|e| e.to_string())
}

View File

@@ -0,0 +1,9 @@
use crate::{
models::interaction::SendInteractionDto,
services::interaction::send_interaction,
};
#[tauri::command]
pub async fn send_interaction_cmd(dto: SendInteractionDto) -> Result<(), String> {
send_interaction(dto).await
}

View File

@@ -0,0 +1,8 @@
pub mod app;
pub mod app_data;
pub mod auth;
pub mod config;
pub mod dolls;
pub mod friends;
pub mod interaction;
pub mod sprite;

View File

@@ -0,0 +1,15 @@
use crate::services::sprite_recolor;
#[tauri::command]
pub fn recolor_gif_base64(
white_color_hex: String,
black_color_hex: String,
apply_texture: bool,
) -> Result<String, String> {
sprite_recolor::recolor_gif_base64(
white_color_hex.as_str(),
black_color_hex.as_str(),
apply_texture,
)
.map_err(|e: Box<dyn std::error::Error>| e.to_string())
}