include full appmetadata object in user status broadcasts

This commit is contained in:
2026-02-04 19:15:15 +08:00
parent 547baaceb8
commit 4152491ca4
5 changed files with 37 additions and 16 deletions

View File

@@ -1,9 +1,10 @@
use crate::services::active_app::AppMetadata;
use crate::services::ws::UserStatusPayload; use crate::services::ws::UserStatusPayload;
use crate::services::ws::report_user_status; use crate::services::ws::report_user_status;
#[tauri::command] #[tauri::command]
pub async fn send_user_status_cmd(active_app: String, state: String) -> Result<(), String> { pub async fn send_user_status_cmd(app_metadata: AppMetadata, state: String) -> Result<(), String> {
let payload = UserStatusPayload { active_app, state }; let payload = UserStatusPayload { app_metadata, state };
report_user_status(payload).await; report_user_status(payload).await;
Ok(()) Ok(())
} }

View File

@@ -52,7 +52,7 @@ pub static ACTIVE_APP_CHANGED: &str = "active-app-changed";
/// Used for app to emit user foreground app to peers. /// Used for app to emit user foreground app to peers.
pub fn init_foreground_app_change_listener() { pub fn init_foreground_app_change_listener() {
let app_handle = get_app_handle(); let app_handle = get_app_handle();
listen_for_active_app_changes(|app_names: AppMetadata| { listen_for_active_app_changes(|app_metadata: AppMetadata| {
{ {
let guard = lock_r!(FDOLL); let guard = lock_r!(FDOLL);
if guard if guard
@@ -62,15 +62,17 @@ pub fn init_foreground_app_change_listener() {
.map(|c| c.is_ws_initialized) .map(|c| c.is_ws_initialized)
.unwrap_or(false) .unwrap_or(false)
{ {
let active_app_value = app_names // Check if app metadata has valid data
let has_valid_name = app_metadata
.localized .localized
.as_ref() .as_ref()
.or(app_names.unlocalized.as_ref()) .or(app_metadata.unlocalized.as_ref())
.unwrap_or(&String::new()) .map(|s| !s.trim().is_empty())
.clone(); .unwrap_or(false);
if !active_app_value.trim().is_empty() {
if has_valid_name {
let payload = crate::services::ws::UserStatusPayload { let payload = crate::services::ws::UserStatusPayload {
active_app: active_app_value, app_metadata: app_metadata.clone(),
state: "idle".to_string(), state: "idle".to_string(),
}; };
tauri::async_runtime::spawn(async move { tauri::async_runtime::spawn(async move {
@@ -79,7 +81,7 @@ pub fn init_foreground_app_change_listener() {
} }
} }
}; };
if let Err(e) = app_handle.emit(ACTIVE_APP_CHANGED, app_names) { if let Err(e) = app_handle.emit(ACTIVE_APP_CHANGED, app_metadata) {
error!("Failed to emit active app changed event: {}", e); error!("Failed to emit active app changed event: {}", e);
}; };
}); });

View File

@@ -7,13 +7,14 @@ use tokio::time::Duration;
use tracing::error; use tracing::error;
use crate::{init::lifecycle::handle_disasterous_failure, lock_r, state::FDOLL}; use crate::{init::lifecycle::handle_disasterous_failure, lock_r, state::FDOLL};
use crate::services::active_app::AppMetadata;
use super::WS_EVENT; use super::WS_EVENT;
#[derive(Clone, serde::Serialize)] #[derive(Clone, serde::Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct UserStatusPayload { pub struct UserStatusPayload {
pub active_app: String, pub app_metadata: AppMetadata,
pub state: String, pub state: String,
} }

View File

@@ -1,8 +1,9 @@
import { listen, type UnlistenFn } from "@tauri-apps/api/event"; import { listen, type UnlistenFn } from "@tauri-apps/api/event";
import { writable } from "svelte/store"; import { writable } from "svelte/store";
import type { AppMetadata } from "../types/bindings/AppMetadata";
export type FriendUserStatus = { export type FriendUserStatus = {
activeApp: string; appMetadata: AppMetadata;
state: "idle" | "resting"; state: "idle" | "resting";
}; };
@@ -31,13 +32,20 @@ export async function initUserStatusListeners() {
const status = payload?.status as FriendUserStatus | undefined; const status = payload?.status as FriendUserStatus | undefined;
if (!userId || !status) return; if (!userId || !status) return;
if (typeof status.activeApp !== "string" || status.activeApp.trim() === "") return; if (!status.appMetadata) return;
// Validate that appMetadata has at least one valid name
const hasValidName =
(typeof status.appMetadata.localized === "string" && status.appMetadata.localized.trim() !== "") ||
(typeof status.appMetadata.unlocalized === "string" && status.appMetadata.unlocalized.trim() !== "");
if (!hasValidName) return;
if (status.state !== "idle" && status.state !== "resting") return; if (status.state !== "idle" && status.state !== "resting") return;
friendsUserStatuses.update((current) => ({ friendsUserStatuses.update((current) => ({
...current, ...current,
[userId]: { [userId]: {
activeApp: status.activeApp, appMetadata: status.appMetadata,
state: status.state, state: status.state,
}, },
})); }));

View File

@@ -106,8 +106,17 @@
)}) )})
</span> </span>
{#if status} {#if status}
<span> <span class="flex items-center gap-1">
{status.state} in {status.activeApp} {status.state} in
{#if status.appMetadata.appIconB64}
<img
src={`data:image/png;base64,${status.appMetadata.appIconB64}`}
alt="Friend's active app icon"
class="size-4"
/>
{/if}
{status.appMetadata.localized ||
status.appMetadata.unlocalized}
</span> </span>
{/if} {/if}
</div> </div>