Improved tauri events type safety
This commit is contained in:
@@ -41,4 +41,4 @@ pub struct DollDto {
|
||||
pub configuration: DollConfigurationDto,
|
||||
pub created_at: String,
|
||||
pub updated_at: String,
|
||||
}
|
||||
}
|
||||
|
||||
79
src-tauri/src/models/event_payloads.rs
Normal file
79
src-tauri/src/models/event_payloads.rs
Normal file
@@ -0,0 +1,79 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
|
||||
use super::dolls::DollDto;
|
||||
use super::friends::UserBasicDto;
|
||||
use crate::services::presence_modules::models::PresenceStatus;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[ts(export)]
|
||||
pub enum UserStatusState {
|
||||
Idle,
|
||||
Resting,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct UserStatusPayload {
|
||||
pub presence_status: PresenceStatus,
|
||||
pub state: UserStatusState,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FriendUserStatusPayload {
|
||||
pub user_id: String,
|
||||
pub status: UserStatusPayload,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FriendDisconnectedPayload {
|
||||
pub user_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FriendActiveDollChangedPayload {
|
||||
pub friend_id: String,
|
||||
pub doll: Option<DollDto>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, TS)]
|
||||
#[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)]
|
||||
#[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)]
|
||||
#[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)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct UnfriendedPayload {
|
||||
pub friend_id: String,
|
||||
}
|
||||
@@ -25,4 +25,4 @@ pub enum HealthError {
|
||||
NonOkStatus(String),
|
||||
#[error("health response decode failed: {0}")]
|
||||
Decode(reqwest::Error),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
pub mod app_data;
|
||||
pub mod remote_error;
|
||||
pub mod dolls;
|
||||
pub mod event_payloads;
|
||||
pub mod friends;
|
||||
pub mod health;
|
||||
pub mod interaction;
|
||||
pub mod remote_error;
|
||||
pub mod user;
|
||||
|
||||
@@ -3,7 +3,8 @@ use std::{path::Path, thread, time::Duration};
|
||||
use tokio::runtime::Runtime;
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
use crate::services::ws::user_status::{report_user_status, UserStatusPayload};
|
||||
use crate::models::event_payloads::{UserStatusPayload, UserStatusState};
|
||||
use crate::services::ws::user_status::report_user_status;
|
||||
use crate::services::ws::{ws_emit_soft, WS_EVENT};
|
||||
|
||||
use super::models::PresenceStatus;
|
||||
@@ -45,7 +46,7 @@ impl UserData for Engine {
|
||||
async fn update_status(status: PresenceStatus) {
|
||||
let user_status = UserStatusPayload {
|
||||
presence_status: status,
|
||||
state: String::from("idle"),
|
||||
state: UserStatusState::Idle,
|
||||
};
|
||||
report_user_status(user_status).await;
|
||||
}
|
||||
@@ -53,7 +54,7 @@ async fn update_status(status: PresenceStatus) {
|
||||
async fn update_status_async(status: PresenceStatus) {
|
||||
let payload = UserStatusPayload {
|
||||
presence_status: status,
|
||||
state: String::from("idle"),
|
||||
state: UserStatusState::Idle,
|
||||
};
|
||||
if let Err(e) = ws_emit_soft(WS_EVENT::CLIENT_REPORT_USER_STATUS, payload).await {
|
||||
warn!("User status report failed: {}", e);
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
use rust_socketio::{Payload, RawClient};
|
||||
use tracing::info;
|
||||
|
||||
use crate::models::event_payloads::{
|
||||
FriendActiveDollChangedPayload, FriendDisconnectedPayload, FriendRequestAcceptedPayload,
|
||||
FriendRequestDeniedPayload, FriendRequestReceivedPayload, FriendUserStatusPayload,
|
||||
UnfriendedPayload,
|
||||
};
|
||||
use crate::services::app_events::AppEvents;
|
||||
use crate::services::cursor::{normalized_to_absolute, CursorPositions};
|
||||
use crate::state::AppDataRefreshScope;
|
||||
@@ -13,30 +18,36 @@ use super::{
|
||||
|
||||
/// Handler for friend-request-received event
|
||||
pub fn on_friend_request_received(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(value) = utils::extract_text_value(payload, "friend-request-received") {
|
||||
emitter::emit_to_frontend(AppEvents::FriendRequestReceived.as_str(), value);
|
||||
if let Ok(data) =
|
||||
utils::extract_and_parse::<FriendRequestReceivedPayload>(payload, "friend-request-received")
|
||||
{
|
||||
emitter::emit_to_frontend(AppEvents::FriendRequestReceived.as_str(), data);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handler for friend-request-accepted event
|
||||
pub fn on_friend_request_accepted(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(value) = utils::extract_text_value(payload, "friend-request-accepted") {
|
||||
emitter::emit_to_frontend(AppEvents::FriendRequestAccepted.as_str(), value);
|
||||
if let Ok(data) =
|
||||
utils::extract_and_parse::<FriendRequestAcceptedPayload>(payload, "friend-request-accepted")
|
||||
{
|
||||
emitter::emit_to_frontend(AppEvents::FriendRequestAccepted.as_str(), data);
|
||||
refresh::refresh_app_data(AppDataRefreshScope::Friends);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handler for friend-request-denied event
|
||||
pub fn on_friend_request_denied(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(value) = utils::extract_text_value(payload, "friend-request-denied") {
|
||||
emitter::emit_to_frontend(AppEvents::FriendRequestDenied.as_str(), value);
|
||||
if let Ok(data) =
|
||||
utils::extract_and_parse::<FriendRequestDeniedPayload>(payload, "friend-request-denied")
|
||||
{
|
||||
emitter::emit_to_frontend(AppEvents::FriendRequestDenied.as_str(), data);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handler for unfriended event
|
||||
pub fn on_unfriended(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(value) = utils::extract_text_value(payload, "unfriended") {
|
||||
emitter::emit_to_frontend(AppEvents::Unfriended.as_str(), value);
|
||||
if let Ok(data) = utils::extract_and_parse::<UnfriendedPayload>(payload, "unfriended") {
|
||||
emitter::emit_to_frontend(AppEvents::Unfriended.as_str(), data);
|
||||
refresh::refresh_app_data(AppDataRefreshScope::Friends);
|
||||
}
|
||||
}
|
||||
@@ -63,8 +74,10 @@ pub fn on_friend_cursor_position(payload: Payload, _socket: RawClient) {
|
||||
|
||||
/// Handler for friend-disconnected event
|
||||
pub fn on_friend_disconnected(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(value) = utils::extract_text_value(payload, "friend-disconnected") {
|
||||
emitter::emit_to_frontend(AppEvents::FriendDisconnected.as_str(), value);
|
||||
if let Ok(data) =
|
||||
utils::extract_and_parse::<FriendDisconnectedPayload>(payload, "friend-disconnected")
|
||||
{
|
||||
emitter::emit_to_frontend(AppEvents::FriendDisconnected.as_str(), data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,15 +106,20 @@ fn handle_friend_doll_change(event_name: &str, payload: Payload) {
|
||||
|
||||
/// Handler for friend-active-doll-changed event
|
||||
pub fn on_friend_active_doll_changed(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(value) = utils::extract_text_value(payload, "friend-active-doll-changed") {
|
||||
emitter::emit_to_frontend(AppEvents::FriendActiveDollChanged.as_str(), value);
|
||||
if let Ok(data) = utils::extract_and_parse::<FriendActiveDollChangedPayload>(
|
||||
payload,
|
||||
"friend-active-doll-changed",
|
||||
) {
|
||||
emitter::emit_to_frontend(AppEvents::FriendActiveDollChanged.as_str(), data);
|
||||
refresh::refresh_app_data(AppDataRefreshScope::Friends);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handler for friend-user-status event
|
||||
pub fn on_friend_user_status(payload: Payload, _socket: RawClient) {
|
||||
if let Ok(value) = utils::extract_text_value(payload, "friend-user-status") {
|
||||
emitter::emit_to_frontend(AppEvents::FriendUserStatus.as_str(), value);
|
||||
if let Ok(data) =
|
||||
utils::extract_and_parse::<FriendUserStatusPayload>(payload, "friend-user-status")
|
||||
{
|
||||
emitter::emit_to_frontend(AppEvents::FriendUserStatus.as_str(), data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::Serialize;
|
||||
use tauri::async_runtime::{self, JoinHandle};
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::time::Duration;
|
||||
use tracing::warn;
|
||||
|
||||
use crate::services::presence_modules::models::PresenceStatus;
|
||||
use crate::models::event_payloads::UserStatusPayload;
|
||||
|
||||
use crate::services::app_events::AppEvents;
|
||||
|
||||
use super::{emitter, types::WS_EVENT};
|
||||
|
||||
/// User status payload sent to WebSocket server
|
||||
#[derive(Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UserStatusPayload {
|
||||
pub presence_status: PresenceStatus,
|
||||
pub state: String,
|
||||
}
|
||||
|
||||
/// Debouncer for user status reports
|
||||
static USER_STATUS_REPORT_DEBOUNCE: Lazy<Mutex<Option<JoinHandle<()>>>> =
|
||||
Lazy::new(|| Mutex::new(None));
|
||||
|
||||
Reference in New Issue
Block a user