chore: refactored lib.rs to move commands into separate folder
This commit is contained in:
@@ -13,9 +13,8 @@ use crate::{
|
|||||||
welcome::open_welcome_window,
|
welcome::open_welcome_window,
|
||||||
ws::init_ws_client,
|
ws::init_ws_client,
|
||||||
},
|
},
|
||||||
state::init_app_data,
|
state::{init_app_data, FDOLL},
|
||||||
system_tray::{init_system_tray, update_system_tray},
|
system_tray::{init_system_tray, update_system_tray},
|
||||||
FDOLL,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub async fn start_fdoll() {
|
pub async fn start_fdoll() {
|
||||||
|
|||||||
14
src-tauri/src/commands/app.rs
Normal file
14
src-tauri/src/commands/app.rs
Normal 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();
|
||||||
|
}
|
||||||
18
src-tauri/src/commands/app_data.rs
Normal file
18
src-tauri/src/commands/app_data.rs
Normal 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())
|
||||||
|
}
|
||||||
25
src-tauri/src/commands/auth.rs
Normal file
25
src-tauri/src/commands/auth.rs
Normal 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())
|
||||||
|
}
|
||||||
31
src-tauri/src/commands/config.rs
Normal file
31
src-tauri/src/commands/config.rs
Normal 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())
|
||||||
|
}
|
||||||
135
src-tauri/src/commands/dolls.rs
Normal file
135
src-tauri/src/commands/dolls.rs
Normal 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(())
|
||||||
|
}
|
||||||
78
src-tauri/src/commands/friends.rs
Normal file
78
src-tauri/src/commands/friends.rs
Normal 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())
|
||||||
|
}
|
||||||
9
src-tauri/src/commands/interaction.rs
Normal file
9
src-tauri/src/commands/interaction.rs
Normal 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
|
||||||
|
}
|
||||||
8
src-tauri/src/commands/mod.rs
Normal file
8
src-tauri/src/commands/mod.rs
Normal 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;
|
||||||
15
src-tauri/src/commands/sprite.rs
Normal file
15
src-tauri/src/commands/sprite.rs
Normal 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())
|
||||||
|
}
|
||||||
@@ -1,25 +1,21 @@
|
|||||||
use crate::{
|
use crate::services::{
|
||||||
models::app_data::AppData,
|
cursor::start_cursor_tracking,
|
||||||
models::interaction::SendInteractionDto,
|
doll_editor::open_doll_editor_window,
|
||||||
remotes::{
|
scene::{open_splash_window, set_pet_menu_state, set_scene_interactive},
|
||||||
dolls::{CreateDollDto, DollDto, DollsRemote, UpdateDollDto},
|
|
||||||
friends::{
|
|
||||||
FriendRemote, FriendRequestResponseDto, FriendshipResponseDto, SendFriendRequestDto,
|
|
||||||
UserBasicDto,
|
|
||||||
},
|
|
||||||
user::UserRemote,
|
|
||||||
},
|
|
||||||
services::{
|
|
||||||
client_config_manager::{
|
|
||||||
load_app_config, open_config_manager_window, save_app_config, AppConfig,
|
|
||||||
},
|
|
||||||
cursor::start_cursor_tracking,
|
|
||||||
doll_editor::open_doll_editor_window,
|
|
||||||
interaction::send_interaction,
|
|
||||||
scene::{open_splash_window, set_pet_menu_state, set_scene_interactive},
|
|
||||||
},
|
|
||||||
state::{init_app_data, init_app_data_scoped, AppDataRefreshScope, FDOLL},
|
|
||||||
};
|
};
|
||||||
|
use commands::app::{quit_app, restart_app};
|
||||||
|
use commands::app_data::{get_app_data, refresh_app_data};
|
||||||
|
use commands::auth::{logout_and_restart, start_auth_flow};
|
||||||
|
use commands::config::{get_client_config, open_client_config_manager, save_client_config};
|
||||||
|
use commands::dolls::{
|
||||||
|
create_doll, delete_doll, get_doll, get_dolls, remove_active_doll, set_active_doll, update_doll,
|
||||||
|
};
|
||||||
|
use commands::friends::{
|
||||||
|
accept_friend_request, deny_friend_request, list_friends, received_friend_requests,
|
||||||
|
search_users, send_friend_request, sent_friend_requests, unfriend,
|
||||||
|
};
|
||||||
|
use commands::interaction::send_interaction_cmd;
|
||||||
|
use commands::sprite::recolor_gif_base64;
|
||||||
use tauri::async_runtime;
|
use tauri::async_runtime;
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
use tracing_subscriber::{self, util::SubscriberInitExt};
|
use tracing_subscriber::{self, util::SubscriberInitExt};
|
||||||
@@ -27,6 +23,7 @@ use tracing_subscriber::{self, util::SubscriberInitExt};
|
|||||||
static APP_HANDLE: std::sync::OnceLock<tauri::AppHandle<tauri::Wry>> = std::sync::OnceLock::new();
|
static APP_HANDLE: std::sync::OnceLock<tauri::AppHandle<tauri::Wry>> = std::sync::OnceLock::new();
|
||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
|
mod commands;
|
||||||
mod models;
|
mod models;
|
||||||
mod remotes;
|
mod remotes;
|
||||||
mod services;
|
mod services;
|
||||||
@@ -106,298 +103,6 @@ fn register_app_events(event: tauri::RunEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn get_app_data() -> Result<AppData, String> {
|
|
||||||
let guard = lock_r!(FDOLL);
|
|
||||||
return Ok(guard.app_data.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn refresh_app_data() -> Result<AppData, String> {
|
|
||||||
init_app_data().await;
|
|
||||||
let guard = lock_r!(FDOLL);
|
|
||||||
Ok(guard.app_data.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn list_friends() -> Result<Vec<FriendshipResponseDto>, String> {
|
|
||||||
FriendRemote::new()
|
|
||||||
.get_friends()
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
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]
|
|
||||||
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]
|
|
||||||
async fn received_friend_requests() -> Result<Vec<FriendRequestResponseDto>, String> {
|
|
||||||
FriendRemote::new()
|
|
||||||
.get_received_requests()
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn sent_friend_requests() -> Result<Vec<FriendRequestResponseDto>, String> {
|
|
||||||
FriendRemote::new()
|
|
||||||
.get_sent_requests()
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
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]
|
|
||||||
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]
|
|
||||||
async fn unfriend(friend_id: String) -> Result<(), String> {
|
|
||||||
FriendRemote::new()
|
|
||||||
.unfriend(&friend_id)
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn get_dolls() -> Result<Vec<DollDto>, String> {
|
|
||||||
DollsRemote::new()
|
|
||||||
.get_dolls()
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn get_doll(id: String) -> Result<DollDto, String> {
|
|
||||||
DollsRemote::new()
|
|
||||||
.get_doll(&id)
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
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]
|
|
||||||
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]
|
|
||||||
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]
|
|
||||||
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]
|
|
||||||
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(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn recolor_gif_base64(
|
|
||||||
white_color_hex: String,
|
|
||||||
black_color_hex: String,
|
|
||||||
apply_texture: bool,
|
|
||||||
) -> Result<String, String> {
|
|
||||||
services::sprite_recolor::recolor_gif_base64(
|
|
||||||
white_color_hex.as_str(),
|
|
||||||
black_color_hex.as_str(),
|
|
||||||
apply_texture,
|
|
||||||
)
|
|
||||||
.map_err(|e| e.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn quit_app() -> Result<(), String> {
|
|
||||||
let app_handle = get_app_handle();
|
|
||||||
app_handle.exit(0);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn restart_app() {
|
|
||||||
let app_handle = get_app_handle();
|
|
||||||
app_handle.restart();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
fn get_client_config() -> AppConfig {
|
|
||||||
let mut guard = lock_w!(FDOLL);
|
|
||||||
guard.app_config = load_app_config();
|
|
||||||
guard.app_config.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
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]
|
|
||||||
async fn open_client_config_manager() -> Result<(), String> {
|
|
||||||
open_config_manager_window().map_err(|e| e.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn logout_and_restart() -> Result<(), String> {
|
|
||||||
crate::services::auth::logout_and_restart()
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
async fn send_interaction_cmd(dto: SendInteractionDto) -> Result<(), String> {
|
|
||||||
send_interaction(dto).await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
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())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
|||||||
Reference in New Issue
Block a user