migrate from ts-rs to tauri-specta
This commit is contained in:
@@ -4,6 +4,7 @@ use crate::services::auth::get_session_token;
|
||||
use tracing::info;
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn quit_app() -> Result<(), String> {
|
||||
let app_handle = get_app_handle();
|
||||
app_handle.exit(0);
|
||||
@@ -11,6 +12,7 @@ pub fn quit_app() -> Result<(), String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn restart_app() {
|
||||
let app_handle = get_app_handle();
|
||||
app_handle.restart();
|
||||
@@ -21,6 +23,7 @@ pub fn restart_app() {
|
||||
/// Validates server health, checks for a valid session token,
|
||||
/// then reconstructs the user session (re-fetches app data + WebSocket).
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn retry_connection() -> Result<(), String> {
|
||||
info!("Retrying connection...");
|
||||
|
||||
|
||||
@@ -6,12 +6,14 @@ use crate::{
|
||||
};
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn get_app_data() -> Result<UserData, String> {
|
||||
let guard = lock_r!(FDOLL);
|
||||
Ok(guard.user_data.clone())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn refresh_app_data() -> Result<UserData, String> {
|
||||
init_app_data_scoped(AppDataRefreshScope::All).await;
|
||||
let guard = lock_r!(FDOLL);
|
||||
@@ -19,6 +21,7 @@ pub async fn refresh_app_data() -> Result<UserData, String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn get_modules() -> Result<Vec<ModuleMetadata>, String> {
|
||||
let guard = lock_r!(FDOLL);
|
||||
Ok(guard.modules.metadatas.clone())
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
use crate::services::auth;
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn logout_and_restart() -> Result<(), String> {
|
||||
auth::logout_and_restart().await.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn login(email: String, password: String) -> Result<(), String> {
|
||||
auth::login_and_init_session(&email, &password)
|
||||
.await
|
||||
@@ -13,6 +15,7 @@ pub async fn login(email: String, password: String) -> Result<(), String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn register(
|
||||
email: String,
|
||||
password: String,
|
||||
@@ -30,6 +33,7 @@ pub async fn register(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn change_password(
|
||||
current_password: String,
|
||||
new_password: String,
|
||||
@@ -40,6 +44,7 @@ pub async fn change_password(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn reset_password(old_password: String, new_password: String) -> Result<(), String> {
|
||||
auth::reset_password(&old_password, &new_password)
|
||||
.await
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn get_client_config() -> AppConfig {
|
||||
let mut guard = lock_w!(FDOLL);
|
||||
guard.app_config = load_app_config();
|
||||
@@ -14,6 +15,7 @@ pub fn get_client_config() -> AppConfig {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn save_client_config(config: AppConfig) -> Result<(), String> {
|
||||
match save_app_config(config) {
|
||||
Ok(saved) => {
|
||||
@@ -26,6 +28,7 @@ pub fn save_client_config(config: AppConfig) -> Result<(), String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn open_client_config_manager() -> Result<(), String> {
|
||||
open_config_manager_window().map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn get_dolls() -> Result<Vec<DollDto>, String> {
|
||||
DollsRemote::new()
|
||||
.get_dolls()
|
||||
@@ -17,6 +18,7 @@ pub async fn get_dolls() -> Result<Vec<DollDto>, String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn get_doll(id: String) -> Result<DollDto, String> {
|
||||
DollsRemote::new()
|
||||
.get_doll(&id)
|
||||
@@ -25,6 +27,7 @@ pub async fn get_doll(id: String) -> Result<DollDto, String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn create_doll(dto: CreateDollDto) -> Result<DollDto, String> {
|
||||
let result = DollsRemote::new()
|
||||
.create_doll(dto)
|
||||
@@ -37,6 +40,7 @@ pub async fn create_doll(dto: CreateDollDto) -> Result<DollDto, String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn update_doll(id: String, dto: UpdateDollDto) -> Result<DollDto, String> {
|
||||
let result = DollsRemote::new()
|
||||
.update_doll(&id, dto)
|
||||
@@ -55,6 +59,7 @@ pub async fn update_doll(id: String, dto: UpdateDollDto) -> Result<DollDto, Stri
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn delete_doll(id: String) -> Result<(), String> {
|
||||
DollsRemote::new()
|
||||
.delete_doll(&id)
|
||||
@@ -73,6 +78,7 @@ pub async fn delete_doll(id: String) -> Result<(), String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn set_active_doll(doll_id: String) -> Result<(), String> {
|
||||
UserRemote::new()
|
||||
.set_active_doll(&doll_id)
|
||||
@@ -85,6 +91,7 @@ pub async fn set_active_doll(doll_id: String) -> Result<(), String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn remove_active_doll() -> Result<(), String> {
|
||||
UserRemote::new()
|
||||
.remove_active_doll()
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::state::AppDataRefreshScope;
|
||||
use crate::commands::refresh_app_data;
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn list_friends() -> Result<Vec<FriendshipResponseDto>, String> {
|
||||
FriendRemote::new()
|
||||
.get_friends()
|
||||
@@ -14,6 +15,7 @@ pub async fn list_friends() -> Result<Vec<FriendshipResponseDto>, String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn search_users(username: Option<String>) -> Result<Vec<UserBasicDto>, String> {
|
||||
tracing::info!(
|
||||
"Tauri command search_users called with username: {:?}",
|
||||
@@ -30,6 +32,7 @@ pub async fn search_users(username: Option<String>) -> Result<Vec<UserBasicDto>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn send_friend_request(
|
||||
request: SendFriendRequestDto,
|
||||
) -> Result<FriendRequestResponseDto, String> {
|
||||
@@ -44,6 +47,7 @@ pub async fn send_friend_request(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn received_friend_requests() -> Result<Vec<FriendRequestResponseDto>, String> {
|
||||
FriendRemote::new()
|
||||
.get_received_requests()
|
||||
@@ -52,6 +56,7 @@ pub async fn received_friend_requests() -> Result<Vec<FriendRequestResponseDto>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn sent_friend_requests() -> Result<Vec<FriendRequestResponseDto>, String> {
|
||||
FriendRemote::new()
|
||||
.get_sent_requests()
|
||||
@@ -60,6 +65,7 @@ pub async fn sent_friend_requests() -> Result<Vec<FriendRequestResponseDto>, Str
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn accept_friend_request(request_id: String) -> Result<FriendRequestResponseDto, String> {
|
||||
let result = FriendRemote::new()
|
||||
.accept_friend_request(&request_id)
|
||||
@@ -72,6 +78,7 @@ pub async fn accept_friend_request(request_id: String) -> Result<FriendRequestRe
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn deny_friend_request(request_id: String) -> Result<FriendRequestResponseDto, String> {
|
||||
let result = FriendRemote::new()
|
||||
.deny_friend_request(&request_id)
|
||||
@@ -84,6 +91,7 @@ pub async fn deny_friend_request(request_id: String) -> Result<FriendRequestResp
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn unfriend(friend_id: String) -> Result<(), String> {
|
||||
FriendRemote::new()
|
||||
.unfriend(&friend_id)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::{models::interaction::SendInteractionDto, services::interaction::send_interaction};
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn send_interaction_cmd(dto: SendInteractionDto) -> Result<(), String> {
|
||||
send_interaction(dto).await
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ use crate::models::dolls::DollDto;
|
||||
use crate::services::petpet;
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn encode_pet_doll_gif_base64(doll: DollDto) -> Result<String, String> {
|
||||
petpet::encode_pet_doll_gif_base64(doll)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::services::sprite_recolor;
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn recolor_gif_base64(
|
||||
white_color_hex: String,
|
||||
black_color_hex: String,
|
||||
|
||||
@@ -19,7 +19,17 @@ use commands::friends::{
|
||||
use commands::interaction::send_interaction_cmd;
|
||||
use commands::sprite::recolor_gif_base64;
|
||||
use commands::petpet::encode_pet_doll_gif_base64;
|
||||
use specta_typescript::Typescript;
|
||||
use tauri::async_runtime;
|
||||
use tauri_specta::{Builder as SpectaBuilder, ErrorHandlingMode, collect_commands, collect_events};
|
||||
|
||||
use crate::services::app_events::{
|
||||
AppDataRefreshed, CreateDoll, CursorMoved, EditDoll, FriendActiveDollChanged,
|
||||
FriendCursorPositionUpdated, FriendDisconnected, FriendRequestAccepted,
|
||||
FriendRequestDenied, FriendRequestReceived, FriendUserStatusChanged,
|
||||
InteractionDeliveryFailed, InteractionReceived, SceneInteractiveChanged,
|
||||
SetInteractionOverlay, Unfriended, UserStatusChanged,
|
||||
};
|
||||
|
||||
static APP_HANDLE: std::sync::OnceLock<tauri::AppHandle<tauri::Wry>> = std::sync::OnceLock::new();
|
||||
|
||||
@@ -51,12 +61,9 @@ fn register_app_events(event: tauri::RunEvent) {
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.plugin(tauri_plugin_positioner::init())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_process::init())
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
let specta_builder = SpectaBuilder::<tauri::Wry>::new()
|
||||
.error_handling(ErrorHandlingMode::Throw)
|
||||
.commands(collect_commands![
|
||||
get_app_data,
|
||||
refresh_app_data,
|
||||
list_friends,
|
||||
@@ -94,7 +101,39 @@ pub fn run() {
|
||||
send_interaction_cmd,
|
||||
get_modules
|
||||
])
|
||||
.setup(|app| {
|
||||
.events(collect_events![
|
||||
CursorMoved,
|
||||
SceneInteractiveChanged,
|
||||
AppDataRefreshed,
|
||||
SetInteractionOverlay,
|
||||
EditDoll,
|
||||
CreateDoll,
|
||||
UserStatusChanged,
|
||||
FriendCursorPositionUpdated,
|
||||
FriendDisconnected,
|
||||
FriendActiveDollChanged,
|
||||
FriendUserStatusChanged,
|
||||
InteractionReceived,
|
||||
InteractionDeliveryFailed,
|
||||
FriendRequestReceived,
|
||||
FriendRequestAccepted,
|
||||
FriendRequestDenied,
|
||||
Unfriended
|
||||
]);
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
specta_builder
|
||||
.export(Typescript::default(), "../src/lib/bindings.ts")
|
||||
.expect("Failed to export TypeScript bindings");
|
||||
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.plugin(tauri_plugin_positioner::init())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_process::init())
|
||||
.invoke_handler(specta_builder.invoke_handler())
|
||||
.setup(move |app| {
|
||||
specta_builder.mount_events(app);
|
||||
APP_HANDLE
|
||||
.set(app.handle().to_owned())
|
||||
.expect("Failed to init app handle.");
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use specta::Type;
|
||||
|
||||
use crate::models::{dolls::DollDto, friends::FriendshipResponseDto, user::UserProfile};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[ts(export)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Type)]
|
||||
pub struct DisplayData {
|
||||
pub screen_width: i32,
|
||||
pub screen_height: i32,
|
||||
@@ -21,8 +20,7 @@ impl Default for DisplayData {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[ts(export)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Type)]
|
||||
pub struct SceneData {
|
||||
pub display: DisplayData,
|
||||
pub grid_size: i32,
|
||||
@@ -37,8 +35,7 @@ impl Default for SceneData {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[ts(export)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
pub struct UserData {
|
||||
pub user: Option<UserProfile>,
|
||||
pub friends: Option<Vec<FriendshipResponseDto>>,
|
||||
|
||||
@@ -1,40 +1,35 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use specta::Type;
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct DollColorSchemeDto {
|
||||
pub outline: String,
|
||||
pub body: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct DollConfigurationDto {
|
||||
pub color_scheme: DollColorSchemeDto,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct CreateDollDto {
|
||||
pub name: String,
|
||||
pub configuration: Option<DollConfigurationDto>,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct UpdateDollDto {
|
||||
pub name: Option<String>,
|
||||
pub configuration: Option<DollConfigurationDto>,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct DollDto {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
|
||||
@@ -1,79 +1,70 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use specta::Type;
|
||||
|
||||
use super::dolls::DollDto;
|
||||
use super::friends::UserBasicDto;
|
||||
use crate::services::presence_modules::models::PresenceStatus;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[ts(export)]
|
||||
pub enum UserStatusState {
|
||||
Idle,
|
||||
Resting,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct UserStatusPayload {
|
||||
pub presence_status: PresenceStatus,
|
||||
pub state: UserStatusState,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FriendUserStatusPayload {
|
||||
pub user_id: String,
|
||||
pub status: UserStatusPayload,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FriendDisconnectedPayload {
|
||||
pub user_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FriendActiveDollChangedPayload {
|
||||
pub friend_id: String,
|
||||
pub doll: Option<DollDto>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FriendRequestReceivedPayload {
|
||||
pub id: String,
|
||||
pub sender: UserBasicDto,
|
||||
pub created_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FriendRequestAcceptedPayload {
|
||||
pub id: String,
|
||||
pub friend: UserBasicDto,
|
||||
pub accepted_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FriendRequestDeniedPayload {
|
||||
pub id: String,
|
||||
pub denier: UserBasicDto,
|
||||
pub denied_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct UnfriendedPayload {
|
||||
pub friend_id: String,
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use specta::Type;
|
||||
|
||||
use super::dolls::DollDto;
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct UserBasicDto {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
@@ -13,25 +12,22 @@ pub struct UserBasicDto {
|
||||
pub active_doll: Option<DollDto>,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FriendshipResponseDto {
|
||||
pub id: String,
|
||||
pub friend: Option<UserBasicDto>,
|
||||
pub created_at: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct SendFriendRequestDto {
|
||||
pub receiver_id: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FriendRequestResponseDto {
|
||||
pub id: String,
|
||||
pub sender: UserBasicDto,
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use reqwest::StatusCode;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
use thiserror::Error;
|
||||
use ts_rs::TS;
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct HealthResponseDto {
|
||||
pub status: String,
|
||||
pub version: String,
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use specta::Type;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[ts(export)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SendInteractionDto {
|
||||
pub recipient_user_id: String,
|
||||
@@ -11,8 +10,7 @@ pub struct SendInteractionDto {
|
||||
pub type_: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[ts(export)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InteractionPayloadDto {
|
||||
pub sender_user_id: String,
|
||||
@@ -23,8 +21,7 @@ pub struct InteractionPayloadDto {
|
||||
pub timestamp: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[ts(export)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InteractionDeliveryFailedDto {
|
||||
pub recipient_user_id: String,
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use specta::Type;
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, TS)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct UserProfile {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
|
||||
@@ -1,105 +1,84 @@
|
||||
use serde::Serialize;
|
||||
#[allow(unused_imports)]
|
||||
use std::{fs, path::Path};
|
||||
use strum::{AsRefStr, EnumIter};
|
||||
use ts_rs::TS;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
use tauri_specta::Event;
|
||||
|
||||
#[derive(Serialize, TS, EnumIter, AsRefStr)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[ts(export)]
|
||||
pub enum AppEvents {
|
||||
CursorPosition,
|
||||
SceneInteractive,
|
||||
AppDataRefreshed,
|
||||
SetInteractionOverlay,
|
||||
EditDoll,
|
||||
CreateDoll,
|
||||
UserStatusChanged,
|
||||
FriendCursorPosition,
|
||||
FriendDisconnected,
|
||||
FriendActiveDollChanged,
|
||||
FriendUserStatus,
|
||||
InteractionReceived,
|
||||
InteractionDeliveryFailed,
|
||||
FriendRequestReceived,
|
||||
FriendRequestAccepted,
|
||||
FriendRequestDenied,
|
||||
Unfriended,
|
||||
}
|
||||
use crate::{
|
||||
models::{
|
||||
app_data::UserData,
|
||||
event_payloads::{
|
||||
FriendActiveDollChangedPayload, FriendDisconnectedPayload,
|
||||
FriendRequestAcceptedPayload, FriendRequestDeniedPayload, FriendRequestReceivedPayload,
|
||||
FriendUserStatusPayload, UnfriendedPayload, UserStatusPayload,
|
||||
},
|
||||
interaction::{InteractionDeliveryFailedDto, InteractionPayloadDto},
|
||||
},
|
||||
services::{cursor::CursorPositions, ws::OutgoingFriendCursorPayload},
|
||||
};
|
||||
|
||||
impl AppEvents {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
AppEvents::CursorPosition => "cursor-position",
|
||||
AppEvents::SceneInteractive => "scene-interactive",
|
||||
AppEvents::AppDataRefreshed => "app-data-refreshed",
|
||||
AppEvents::SetInteractionOverlay => "set-interaction-overlay",
|
||||
AppEvents::EditDoll => "edit-doll",
|
||||
AppEvents::CreateDoll => "create-doll",
|
||||
AppEvents::UserStatusChanged => "user-status-changed",
|
||||
AppEvents::FriendCursorPosition => "friend-cursor-position",
|
||||
AppEvents::FriendDisconnected => "friend-disconnected",
|
||||
AppEvents::FriendActiveDollChanged => "friend-active-doll-changed",
|
||||
AppEvents::FriendUserStatus => "friend-user-status",
|
||||
AppEvents::InteractionReceived => "interaction-received",
|
||||
AppEvents::InteractionDeliveryFailed => "interaction-delivery-failed",
|
||||
AppEvents::FriendRequestReceived => "friend-request-received",
|
||||
AppEvents::FriendRequestAccepted => "friend-request-accepted",
|
||||
AppEvents::FriendRequestDenied => "friend-request-denied",
|
||||
AppEvents::Unfriended => "unfriended",
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "cursor-position")]
|
||||
pub struct CursorMoved(pub CursorPositions);
|
||||
|
||||
#[test]
|
||||
fn export_bindings_appeventsconsts() {
|
||||
use strum::IntoEnumIterator;
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "scene-interactive")]
|
||||
pub struct SceneInteractiveChanged(pub bool);
|
||||
|
||||
let some_export_dir = std::env::var("TS_RS_EXPORT_DIR")
|
||||
.ok()
|
||||
.map(|s| Path::new(&s).to_owned());
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "app-data-refreshed")]
|
||||
pub struct AppDataRefreshed(pub UserData);
|
||||
|
||||
let Some(export_dir) = some_export_dir else {
|
||||
eprintln!("TS_RS_EXPORT_DIR not set, skipping constants export");
|
||||
return;
|
||||
};
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "set-interaction-overlay")]
|
||||
pub struct SetInteractionOverlay(pub bool);
|
||||
|
||||
let to_kebab_case = |s: &str| -> String {
|
||||
let mut result = String::new();
|
||||
for (i, c) in s.chars().enumerate() {
|
||||
if c.is_uppercase() {
|
||||
if i > 0 {
|
||||
result.push('-');
|
||||
}
|
||||
result.push(c.to_lowercase().next().unwrap());
|
||||
} else {
|
||||
result.push(c);
|
||||
}
|
||||
}
|
||||
result
|
||||
};
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "edit-doll")]
|
||||
pub struct EditDoll(pub String);
|
||||
|
||||
let mut lines = vec![
|
||||
r#"// Auto-generated constants - DO NOT EDIT"#.to_string(),
|
||||
r#"// Generated from Rust AppEvents enum"#.to_string(),
|
||||
"".to_string(),
|
||||
"export const AppEvents = {".to_string(),
|
||||
];
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "create-doll")]
|
||||
pub struct CreateDoll;
|
||||
|
||||
for variant in AppEvents::iter() {
|
||||
let name = variant.as_ref();
|
||||
let kebab = to_kebab_case(name);
|
||||
lines.push(format!(" {}: \"{}\",", name, kebab));
|
||||
}
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "user-status-changed")]
|
||||
pub struct UserStatusChanged(pub UserStatusPayload);
|
||||
|
||||
lines.push("} as const;".to_string());
|
||||
lines.push("".to_string());
|
||||
lines.push("export type AppEvents = typeof AppEvents[keyof typeof AppEvents];".to_string());
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "friend-cursor-position")]
|
||||
pub struct FriendCursorPositionUpdated(pub OutgoingFriendCursorPayload);
|
||||
|
||||
let constants_content = lines.join("\n");
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "friend-disconnected")]
|
||||
pub struct FriendDisconnected(pub FriendDisconnectedPayload);
|
||||
|
||||
let constants_path = export_dir.join("AppEventsConstants.ts");
|
||||
if let Err(e) = fs::write(&constants_path, constants_content) {
|
||||
eprintln!("Failed to write {}: {}", constants_path.display(), e);
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "friend-active-doll-changed")]
|
||||
pub struct FriendActiveDollChanged(pub FriendActiveDollChangedPayload);
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "friend-user-status")]
|
||||
pub struct FriendUserStatusChanged(pub FriendUserStatusPayload);
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "interaction-received")]
|
||||
pub struct InteractionReceived(pub InteractionPayloadDto);
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "interaction-delivery-failed")]
|
||||
pub struct InteractionDeliveryFailed(pub InteractionDeliveryFailedDto);
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "friend-request-received")]
|
||||
pub struct FriendRequestReceived(pub FriendRequestReceivedPayload);
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "friend-request-accepted")]
|
||||
pub struct FriendRequestAccepted(pub FriendRequestAcceptedPayload);
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "friend-request-denied")]
|
||||
pub struct FriendRequestDenied(pub FriendRequestDeniedPayload);
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type, Event)]
|
||||
#[tauri_specta(event_name = "unfriended")]
|
||||
pub struct Unfriended(pub UnfriendedPayload);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
use tauri::Manager;
|
||||
use thiserror::Error;
|
||||
use tracing::{error, warn};
|
||||
@@ -8,7 +9,7 @@ use url::Url;
|
||||
|
||||
use crate::get_app_handle;
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug)]
|
||||
#[derive(Default, Serialize, Deserialize, Clone, Debug, Type)]
|
||||
pub struct AppConfig {
|
||||
pub api_base_url: Option<String>,
|
||||
}
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
use device_query::{DeviceEvents, DeviceEventsHandler};
|
||||
use once_cell::sync::OnceCell;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use tauri::Emitter;
|
||||
use tokio::sync::mpsc;
|
||||
use tracing::{debug, error, info, warn};
|
||||
use ts_rs::TS;
|
||||
|
||||
use crate::{get_app_handle, lock_r, services::app_events::AppEvents, state::FDOLL};
|
||||
use crate::{
|
||||
get_app_handle,
|
||||
lock_r,
|
||||
services::app_events::CursorMoved,
|
||||
state::FDOLL,
|
||||
};
|
||||
use tauri_specta::Event as _;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct CursorPosition {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, TS)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct CursorPositions {
|
||||
pub raw: CursorPosition,
|
||||
pub mapped: CursorPosition,
|
||||
@@ -103,7 +106,7 @@ async fn init_cursor_tracking_i() -> Result<(), String> {
|
||||
crate::services::ws::report_cursor_data(mapped_for_ws).await;
|
||||
|
||||
// 2. Broadcast to local windows
|
||||
if let Err(e) = app_handle.emit(AppEvents::CursorPosition.as_str(), &positions) {
|
||||
if let Err(e) = CursorMoved(positions).emit(app_handle) {
|
||||
error!("Failed to emit cursor position event: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
#[cfg(target_os = "windows")]
|
||||
use tauri::WebviewWindow;
|
||||
use tauri::{Emitter, Listener, Manager};
|
||||
use tauri::{Listener, Manager};
|
||||
use tauri_specta::Event as _;
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::{get_app_handle, services::app_events::AppEvents};
|
||||
use crate::{
|
||||
get_app_handle,
|
||||
services::app_events::{CreateDoll, EditDoll, SetInteractionOverlay},
|
||||
};
|
||||
|
||||
static APP_MENU_WINDOW_LABEL: &str = "app_menu";
|
||||
|
||||
@@ -51,6 +55,7 @@ fn set_window_interaction(window: &WebviewWindow, enable: bool) {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn open_doll_editor_window(doll_id: Option<String>) {
|
||||
let app_handle = get_app_handle().clone();
|
||||
|
||||
@@ -76,17 +81,17 @@ pub async fn open_doll_editor_window(doll_id: Option<String>) {
|
||||
// Ensure overlay is active on parent (redundancy for safety)
|
||||
#[cfg(target_os = "macos")]
|
||||
if let Some(parent) = app_handle.get_webview_window(APP_MENU_WINDOW_LABEL) {
|
||||
if let Err(e) = parent.emit(AppEvents::SetInteractionOverlay.as_str(), true) {
|
||||
if let Err(e) = SetInteractionOverlay(true).emit(&parent) {
|
||||
error!("Failed to ensure interaction overlay on parent: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Emit event to update context
|
||||
if let Some(id) = doll_id {
|
||||
if let Err(e) = window.emit(AppEvents::EditDoll.as_str(), id) {
|
||||
if let Err(e) = EditDoll(id).emit(&window) {
|
||||
error!("Failed to emit edit-doll event: {}", e);
|
||||
}
|
||||
} else if let Err(e) = window.emit(AppEvents::CreateDoll.as_str(), ()) {
|
||||
} else if let Err(e) = CreateDoll.emit(&window) {
|
||||
error!("Failed to emit create-doll event: {}", e);
|
||||
}
|
||||
|
||||
@@ -136,7 +141,7 @@ pub async fn open_doll_editor_window(doll_id: Option<String>) {
|
||||
let app_handle_clone = get_app_handle().clone();
|
||||
|
||||
// Emit event to show overlay
|
||||
if let Err(e) = parent.emit(AppEvents::SetInteractionOverlay.as_str(), true) {
|
||||
if let Err(e) = SetInteractionOverlay(true).emit(&parent) {
|
||||
error!("Failed to emit set-interaction-overlay event: {}", e);
|
||||
}
|
||||
|
||||
@@ -169,7 +174,7 @@ pub async fn open_doll_editor_window(doll_id: Option<String>) {
|
||||
parent.unlisten(id);
|
||||
}
|
||||
// Remove overlay if we failed
|
||||
let _ = parent.emit(AppEvents::SetInteractionOverlay.as_str(), false);
|
||||
let _ = SetInteractionOverlay(false).emit(&parent);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -204,9 +209,7 @@ pub async fn open_doll_editor_window(doll_id: Option<String>) {
|
||||
parent.unlisten(id);
|
||||
}
|
||||
// Remove overlay
|
||||
if let Err(e) = parent
|
||||
.emit(AppEvents::SetInteractionOverlay.as_str(), false)
|
||||
{
|
||||
if let Err(e) = SetInteractionOverlay(false).emit(&parent) {
|
||||
error!("Failed to remove interaction overlay: {}", e);
|
||||
}
|
||||
}
|
||||
@@ -232,7 +235,7 @@ pub async fn open_doll_editor_window(doll_id: Option<String>) {
|
||||
if let Some(id) = parent_focus_listener_id {
|
||||
parent.unlisten(id);
|
||||
}
|
||||
let _ = parent.emit(AppEvents::SetInteractionOverlay.as_str(), false);
|
||||
let _ = SetInteractionOverlay(false).emit(&parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use specta::Type;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct PresenceStatus {
|
||||
pub title: Option<String>,
|
||||
pub subtitle: Option<String>,
|
||||
pub graphics_b64: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, TS)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct ModuleMetadata {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
|
||||
@@ -4,11 +4,12 @@ use std::thread;
|
||||
|
||||
use device_query::{DeviceQuery, DeviceState, Keycode};
|
||||
use once_cell::sync::OnceCell;
|
||||
use tauri::{Emitter, Manager};
|
||||
use tauri::Manager;
|
||||
use tauri_plugin_positioner::WindowExt;
|
||||
use tauri_specta::Event as _;
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
use crate::{get_app_handle, services::app_events::AppEvents};
|
||||
use crate::{get_app_handle, services::app_events::SceneInteractiveChanged};
|
||||
|
||||
pub static SCENE_WINDOW_LABEL: &str = "scene";
|
||||
pub static SPLASH_WINDOW_LABEL: &str = "splash";
|
||||
@@ -69,7 +70,7 @@ pub fn update_scene_interactive(interactive: bool, should_click: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = window.emit(AppEvents::SceneInteractive.as_str(), &interactive) {
|
||||
if let Err(e) = SceneInteractiveChanged(interactive).emit(&window) {
|
||||
error!("Failed to emit scene interactive event: {}", e);
|
||||
}
|
||||
} else {
|
||||
@@ -78,16 +79,19 @@ pub fn update_scene_interactive(interactive: bool, should_click: bool) {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn set_scene_interactive(interactive: bool, should_click: bool) {
|
||||
update_scene_interactive(interactive, should_click);
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn get_scene_interactive() -> Result<bool, String> {
|
||||
Ok(scene_interactive_state().load(Ordering::SeqCst))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn set_pet_menu_state(id: String, open: bool) {
|
||||
let menus_arc = get_open_pet_menus();
|
||||
let should_update = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use rust_socketio::Payload;
|
||||
use serde::Serialize;
|
||||
use tauri::{async_runtime, Emitter};
|
||||
use tauri::async_runtime;
|
||||
use tauri_specta::Event;
|
||||
use tracing::{error, warn};
|
||||
|
||||
use crate::{
|
||||
@@ -110,11 +111,8 @@ pub async fn ws_emit_soft<T: Serialize + Send + 'static>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit event to frontend (Tauri window)
|
||||
///
|
||||
/// Handles error logging consistently.
|
||||
pub fn emit_to_frontend<T: Serialize + Clone>(event: &str, payload: T) {
|
||||
if let Err(e) = get_app_handle().emit(event, payload) {
|
||||
error!("Failed to emit {} event to frontend: {:?}", event, e);
|
||||
pub fn emit_to_frontend_typed<E: Event + Serialize + Clone>(event: &E) {
|
||||
if let Err(e) = event.emit(get_app_handle()) {
|
||||
error!("Failed to emit {} event to frontend: {:?}", E::NAME, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,11 @@ use crate::models::event_payloads::{
|
||||
FriendRequestDeniedPayload, FriendRequestReceivedPayload, FriendUserStatusPayload,
|
||||
UnfriendedPayload,
|
||||
};
|
||||
use crate::services::app_events::AppEvents;
|
||||
use crate::services::app_events::{
|
||||
FriendActiveDollChanged, FriendCursorPositionUpdated, FriendDisconnected,
|
||||
FriendRequestAccepted, FriendRequestDenied, FriendRequestReceived, FriendUserStatusChanged,
|
||||
Unfriended,
|
||||
};
|
||||
use crate::services::cursor::{normalized_to_absolute, CursorPositions};
|
||||
use crate::state::AppDataRefreshScope;
|
||||
|
||||
@@ -21,7 +25,7 @@ pub fn on_friend_request_received(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(data) =
|
||||
utils::extract_and_parse::<FriendRequestReceivedPayload>(payload, "friend-request-received")
|
||||
{
|
||||
emitter::emit_to_frontend(AppEvents::FriendRequestReceived.as_str(), data);
|
||||
emitter::emit_to_frontend_typed(&FriendRequestReceived(data));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +34,7 @@ pub fn on_friend_request_accepted(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(data) =
|
||||
utils::extract_and_parse::<FriendRequestAcceptedPayload>(payload, "friend-request-accepted")
|
||||
{
|
||||
emitter::emit_to_frontend(AppEvents::FriendRequestAccepted.as_str(), data);
|
||||
emitter::emit_to_frontend_typed(&FriendRequestAccepted(data));
|
||||
refresh::refresh_app_data(AppDataRefreshScope::Friends);
|
||||
}
|
||||
}
|
||||
@@ -40,14 +44,14 @@ pub fn on_friend_request_denied(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(data) =
|
||||
utils::extract_and_parse::<FriendRequestDeniedPayload>(payload, "friend-request-denied")
|
||||
{
|
||||
emitter::emit_to_frontend(AppEvents::FriendRequestDenied.as_str(), data);
|
||||
emitter::emit_to_frontend_typed(&FriendRequestDenied(data));
|
||||
}
|
||||
}
|
||||
|
||||
/// Handler for unfriended event
|
||||
pub fn on_unfriended(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(data) = utils::extract_and_parse::<UnfriendedPayload>(payload, "unfriended") {
|
||||
emitter::emit_to_frontend(AppEvents::Unfriended.as_str(), data);
|
||||
emitter::emit_to_frontend_typed(&Unfriended(data));
|
||||
refresh::refresh_app_data(AppDataRefreshScope::Friends);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +72,7 @@ pub fn on_friend_cursor_position(payload: Payload, _socket: RawClient) {
|
||||
},
|
||||
};
|
||||
|
||||
emitter::emit_to_frontend(AppEvents::FriendCursorPosition.as_str(), outgoing_payload);
|
||||
emitter::emit_to_frontend_typed(&FriendCursorPositionUpdated(outgoing_payload));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +81,7 @@ pub fn on_friend_disconnected(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(data) =
|
||||
utils::extract_and_parse::<FriendDisconnectedPayload>(payload, "friend-disconnected")
|
||||
{
|
||||
emitter::emit_to_frontend(AppEvents::FriendDisconnected.as_str(), data);
|
||||
emitter::emit_to_frontend_typed(&FriendDisconnected(data));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +114,7 @@ pub fn on_friend_active_doll_changed(payload: Payload, _socket: RawClient) {
|
||||
payload,
|
||||
"friend-active-doll-changed",
|
||||
) {
|
||||
emitter::emit_to_frontend(AppEvents::FriendActiveDollChanged.as_str(), data);
|
||||
emitter::emit_to_frontend_typed(&FriendActiveDollChanged(data));
|
||||
refresh::refresh_app_data(AppDataRefreshScope::Friends);
|
||||
}
|
||||
}
|
||||
@@ -120,6 +124,6 @@ pub fn on_friend_user_status(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(data) =
|
||||
utils::extract_and_parse::<FriendUserStatusPayload>(payload, "friend-user-status")
|
||||
{
|
||||
emitter::emit_to_frontend(AppEvents::FriendUserStatus.as_str(), data);
|
||||
emitter::emit_to_frontend_typed(&FriendUserStatusChanged(data));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use rust_socketio::{Payload, RawClient};
|
||||
|
||||
use crate::models::interaction::{InteractionDeliveryFailedDto, InteractionPayloadDto};
|
||||
use crate::services::app_events::AppEvents;
|
||||
use crate::services::app_events::{InteractionDeliveryFailed, InteractionReceived};
|
||||
|
||||
use super::{emitter, utils};
|
||||
|
||||
@@ -10,7 +10,7 @@ pub fn on_interaction_received(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(data) =
|
||||
utils::extract_and_parse::<InteractionPayloadDto>(payload, "interaction-received")
|
||||
{
|
||||
emitter::emit_to_frontend(AppEvents::InteractionReceived.as_str(), data);
|
||||
emitter::emit_to_frontend_typed(&InteractionReceived(data));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,6 @@ pub fn on_interaction_delivery_failed(payload: Payload, _socket: RawClient) {
|
||||
payload,
|
||||
"interaction-delivery-failed",
|
||||
) {
|
||||
emitter::emit_to_frontend(AppEvents::InteractionDeliveryFailed.as_str(), data);
|
||||
emitter::emit_to_frontend_typed(&InteractionDeliveryFailed(data));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,4 +29,5 @@ pub mod client;
|
||||
// Re-export public API
|
||||
pub use cursor::report_cursor_data;
|
||||
pub use emitter::ws_emit_soft;
|
||||
pub use types::OutgoingFriendCursorPayload;
|
||||
pub use types::WS_EVENT;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
|
||||
/// WebSocket event constants
|
||||
#[allow(non_camel_case_types)]
|
||||
@@ -37,7 +38,7 @@ pub struct IncomingFriendCursorPayload {
|
||||
}
|
||||
|
||||
/// Outgoing friend cursor position to frontend
|
||||
#[derive(Clone, Serialize)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct OutgoingFriendCursorPayload {
|
||||
pub user_id: String,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use once_cell::sync::Lazy;
|
||||
use tauri_specta::Event as _;
|
||||
use tauri::async_runtime::{self, JoinHandle};
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::time::Duration;
|
||||
@@ -6,7 +7,7 @@ use tracing::warn;
|
||||
|
||||
use crate::models::event_payloads::UserStatusPayload;
|
||||
|
||||
use crate::services::app_events::AppEvents;
|
||||
use crate::services::app_events::UserStatusChanged;
|
||||
|
||||
use super::{emitter, types::WS_EVENT};
|
||||
|
||||
@@ -23,7 +24,9 @@ pub async fn report_user_status(status: UserStatusPayload) {
|
||||
handle.abort();
|
||||
}
|
||||
|
||||
emitter::emit_to_frontend(AppEvents::UserStatusChanged.as_str(), &status);
|
||||
if let Err(e) = UserStatusChanged(status.clone()).emit(crate::get_app_handle()) {
|
||||
warn!("Failed to emit user-status-changed event: {e}");
|
||||
}
|
||||
|
||||
// Schedule new report after 500ms
|
||||
let handle = async_runtime::spawn(async move {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use crate::{
|
||||
get_app_handle, lock_r, lock_w,
|
||||
remotes::{dolls::DollsRemote, friends::FriendRemote, user::UserRemote},
|
||||
services::app_events::AppEvents,
|
||||
services::app_events::AppDataRefreshed,
|
||||
state::FDOLL,
|
||||
};
|
||||
use std::{collections::HashSet, sync::LazyLock};
|
||||
use tauri::Emitter;
|
||||
use tokio::sync::Mutex;
|
||||
use tauri_specta::Event as _;
|
||||
use tracing::{info, warn};
|
||||
|
||||
pub fn update_display_dimensions_for_scene_state() {
|
||||
@@ -211,9 +211,7 @@ pub async fn init_app_data_scoped(scope: AppDataRefreshScope) {
|
||||
let app_data_clone = guard.user_data.clone();
|
||||
drop(guard); // Drop lock before emitting to prevent potential deadlocks
|
||||
|
||||
if let Err(e) =
|
||||
get_app_handle().emit(AppEvents::AppDataRefreshed.as_str(), &app_data_clone)
|
||||
{
|
||||
if let Err(e) = AppDataRefreshed(app_data_clone).emit(get_app_handle()) {
|
||||
warn!("Failed to emit app-data-refreshed event: {}", e);
|
||||
use tauri_plugin_dialog::MessageDialogBuilder;
|
||||
use tauri_plugin_dialog::{DialogExt, MessageDialogKind};
|
||||
|
||||
Reference in New Issue
Block a user