commands refactor
This commit is contained in:
@@ -1,13 +1,12 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
lock_r,
|
|
||||||
models::dolls::{CreateDollDto, DollDto, UpdateDollDto},
|
models::dolls::{CreateDollDto, DollDto, UpdateDollDto},
|
||||||
remotes::{
|
remotes::{
|
||||||
dolls::DollsRemote,
|
dolls::DollsRemote,
|
||||||
user::UserRemote,
|
user::UserRemote,
|
||||||
},
|
},
|
||||||
state::{init_app_data_scoped, AppDataRefreshScope, FDOLL},
|
state::AppDataRefreshScope,
|
||||||
|
commands::{refresh_app_data, refresh_app_data_conditionally, is_active_doll},
|
||||||
};
|
};
|
||||||
use tauri::async_runtime;
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn get_dolls() -> Result<Vec<DollDto>, String> {
|
pub async fn get_dolls() -> Result<Vec<DollDto>, String> {
|
||||||
@@ -32,10 +31,7 @@ pub async fn create_doll(dto: CreateDollDto) -> Result<DollDto, String> {
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// Refresh dolls list in background (deduped inside init_app_data_scoped)
|
refresh_app_data(&[AppDataRefreshScope::Dolls]).await;
|
||||||
async_runtime::spawn(async {
|
|
||||||
init_app_data_scoped(AppDataRefreshScope::Dolls).await;
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
@@ -48,60 +44,32 @@ pub async fn update_doll(id: String, dto: UpdateDollDto) -> Result<DollDto, Stri
|
|||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// Check if this was the active doll (after update completes to avoid stale reads)
|
// Check if this was the active doll (after update completes to avoid stale reads)
|
||||||
let is_active_doll = {
|
let is_active = is_active_doll(&id);
|
||||||
let guard = lock_r!(FDOLL);
|
|
||||||
guard
|
|
||||||
.ui
|
|
||||||
.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
|
refresh_app_data_conditionally(
|
||||||
async_runtime::spawn(async move {
|
&[AppDataRefreshScope::Dolls],
|
||||||
init_app_data_scoped(AppDataRefreshScope::Dolls).await;
|
is_active.then_some(&[AppDataRefreshScope::User, AppDataRefreshScope::Friends]),
|
||||||
if is_active_doll {
|
).await;
|
||||||
init_app_data_scoped(AppDataRefreshScope::User).await;
|
|
||||||
init_app_data_scoped(AppDataRefreshScope::Friends).await;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn delete_doll(id: String) -> Result<(), String> {
|
pub async fn delete_doll(id: String) -> Result<(), String> {
|
||||||
DollsRemote::new()
|
let result = DollsRemote::new()
|
||||||
.delete_doll(&id)
|
.delete_doll(&id)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// Check if this was the active doll (after delete completes to avoid stale reads)
|
// Check if this was the active doll (after delete completes to avoid stale reads)
|
||||||
let is_active_doll = {
|
let is_active = is_active_doll(&id);
|
||||||
let guard = lock_r!(FDOLL);
|
|
||||||
guard
|
|
||||||
.ui
|
|
||||||
.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
|
refresh_app_data_conditionally(
|
||||||
async_runtime::spawn(async move {
|
&[AppDataRefreshScope::Dolls],
|
||||||
init_app_data_scoped(AppDataRefreshScope::Dolls).await;
|
is_active.then_some(&[AppDataRefreshScope::User, AppDataRefreshScope::Friends]),
|
||||||
if is_active_doll {
|
).await;
|
||||||
init_app_data_scoped(AppDataRefreshScope::User).await;
|
|
||||||
init_app_data_scoped(AppDataRefreshScope::Friends).await;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(())
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -111,12 +79,7 @@ pub async fn set_active_doll(doll_id: String) -> Result<(), String> {
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// Refresh User (for active_doll_id) + Friends (so friends see your active doll)
|
refresh_app_data(&[AppDataRefreshScope::User, AppDataRefreshScope::Friends]).await;
|
||||||
// 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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -128,11 +91,7 @@ pub async fn remove_active_doll() -> Result<(), String> {
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// Refresh User (for active_doll_id) + Friends (so friends see your doll is gone)
|
refresh_app_data(&[AppDataRefreshScope::User, AppDataRefreshScope::Friends]).await;
|
||||||
async_runtime::spawn(async {
|
|
||||||
init_app_data_scoped(AppDataRefreshScope::User).await;
|
|
||||||
init_app_data_scoped(AppDataRefreshScope::Friends).await;
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ use crate::remotes::friends::FriendRemote;
|
|||||||
use crate::models::friends::{
|
use crate::models::friends::{
|
||||||
FriendRequestResponseDto, FriendshipResponseDto, SendFriendRequestDto, UserBasicDto,
|
FriendRequestResponseDto, FriendshipResponseDto, SendFriendRequestDto, UserBasicDto,
|
||||||
};
|
};
|
||||||
|
use crate::state::AppDataRefreshScope;
|
||||||
|
use crate::commands::refresh_app_data;
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn list_friends() -> Result<Vec<FriendshipResponseDto>, String> {
|
pub async fn list_friends() -> Result<Vec<FriendshipResponseDto>, String> {
|
||||||
@@ -31,10 +33,14 @@ pub async fn search_users(username: Option<String>) -> Result<Vec<UserBasicDto>,
|
|||||||
pub async fn send_friend_request(
|
pub async fn send_friend_request(
|
||||||
request: SendFriendRequestDto,
|
request: SendFriendRequestDto,
|
||||||
) -> Result<FriendRequestResponseDto, String> {
|
) -> Result<FriendRequestResponseDto, String> {
|
||||||
FriendRemote::new()
|
let result = FriendRemote::new()
|
||||||
.send_friend_request(request)
|
.send_friend_request(request)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
refresh_app_data(&[AppDataRefreshScope::Friends]).await;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -55,18 +61,26 @@ pub async fn sent_friend_requests() -> Result<Vec<FriendRequestResponseDto>, Str
|
|||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn accept_friend_request(request_id: String) -> Result<FriendRequestResponseDto, String> {
|
pub async fn accept_friend_request(request_id: String) -> Result<FriendRequestResponseDto, String> {
|
||||||
FriendRemote::new()
|
let result = FriendRemote::new()
|
||||||
.accept_friend_request(&request_id)
|
.accept_friend_request(&request_id)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
refresh_app_data(&[AppDataRefreshScope::Friends]).await;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn deny_friend_request(request_id: String) -> Result<FriendRequestResponseDto, String> {
|
pub async fn deny_friend_request(request_id: String) -> Result<FriendRequestResponseDto, String> {
|
||||||
FriendRemote::new()
|
let result = FriendRemote::new()
|
||||||
.deny_friend_request(&request_id)
|
.deny_friend_request(&request_id)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
refresh_app_data(&[AppDataRefreshScope::Friends]).await;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -74,5 +88,9 @@ pub async fn unfriend(friend_id: String) -> Result<(), String> {
|
|||||||
FriendRemote::new()
|
FriendRemote::new()
|
||||||
.unfriend(&friend_id)
|
.unfriend(&friend_id)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
refresh_app_data(&[AppDataRefreshScope::Friends]).await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,3 +6,61 @@ pub mod dolls;
|
|||||||
pub mod friends;
|
pub mod friends;
|
||||||
pub mod interaction;
|
pub mod interaction;
|
||||||
pub mod sprite;
|
pub mod sprite;
|
||||||
|
|
||||||
|
use crate::state::{init_app_data_scoped, AppDataRefreshScope, FDOLL};
|
||||||
|
use crate::lock_r;
|
||||||
|
use tauri::async_runtime;
|
||||||
|
|
||||||
|
/// Helper to execute a mutation operation and refresh app data scopes in the background.
|
||||||
|
/// Returns the result of the operation after mapping errors to strings.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```ignore
|
||||||
|
/// 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_app_data(&[AppDataRefreshScope::Dolls]).await;
|
||||||
|
/// Ok(result)
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub async fn refresh_app_data(scopes: &[AppDataRefreshScope]) {
|
||||||
|
let scopes = scopes.to_vec();
|
||||||
|
async_runtime::spawn(async move {
|
||||||
|
for scope in scopes {
|
||||||
|
init_app_data_scoped(scope).await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper to execute a mutation operation with conditional refresh.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```ignore
|
||||||
|
/// pub async fn delete_doll(id: String) -> Result<(), String> {
|
||||||
|
/// let result = DollsRemote::new().delete_doll(&id).await.map_err(|e| e.to_string())?;
|
||||||
|
/// let is_active = is_active_doll(&id);
|
||||||
|
/// refresh_app_data_conditionally(&[AppDataRefreshScope::Dolls],
|
||||||
|
/// is_active.then_some(&[AppDataRefreshScope::User, AppDataRefreshScope::Friends]));
|
||||||
|
/// Ok(result)
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub async fn refresh_app_data_conditionally(base_scopes: &[AppDataRefreshScope], conditional_scopes: Option<&[AppDataRefreshScope]>) {
|
||||||
|
let mut all_scopes = base_scopes.to_vec();
|
||||||
|
if let Some(extra_scopes) = conditional_scopes {
|
||||||
|
all_scopes.extend_from_slice(extra_scopes);
|
||||||
|
}
|
||||||
|
refresh_app_data(&all_scopes).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper to check if a doll is currently the active doll.
|
||||||
|
/// Used in doll mutation operations to determine if additional refreshes are needed.
|
||||||
|
pub fn is_active_doll(doll_id: &str) -> bool {
|
||||||
|
let guard = lock_r!(FDOLL);
|
||||||
|
guard
|
||||||
|
.ui
|
||||||
|
.app_data
|
||||||
|
.user
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|u| u.active_doll_id.as_ref())
|
||||||
|
.map(|active_id| active_id == doll_id)
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user