fix(desktop): serialize tray channel actions for frontend (#4762)

## Summary
- serialize native `openChannel` tray actions with the camelCase field
names consumed by the TypeScript frontend
- prevent a valid tray channel ID from becoming `/channels/undefined`
- add a Rust serialization contract test covering the complete frontend
payload shape


### Root cause
`TrayAction` renamed the enum variant to `openChannel`, but its struct
fields still serialized as `channel_id` and `community_generation`. The
frontend reads `action.channelId`, so tray navigation called
`goChannel(undefined)`.


### Testing
- manually verified the corrected runtime payload and tray navigation
before removing temporary logging
- `just desktop-ci`
- pre-push hooks (desktop checks/tests, Tauri checks, and Rust tests)

---------

Signed-off-by: Kalvin Chau <kalvin@block.xyz>
Signed-off-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
Co-authored-by: npub122y0pqkertljmedu303rl0aqrj3w8pvu43t6jxm6875lzg6f2pwqegc3xc <5288f082d91aff2de5bc8be23fbfa01ca2e3859cac57a91b7a3fa9f12349505c@buzz.block.builderlab.xyz>
Co-authored-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
This commit is contained in:
Kalvin C
2026-08-04 21:43:21 +00:00
committed by GitHub
co-authored by npub122y0pqkertljmedu303rl0aqrj3w8pvu43t6jxm6875lzg6f2pwqegc3xc npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7
parent b948c54792
commit 4c665aeac3
+19
View File
@@ -213,7 +213,9 @@ struct TrayMenuState<R: Runtime> {
pub enum TrayAction {
NewChannel,
OpenChannel {
#[serde(rename = "channelId")]
channel_id: String,
#[serde(rename = "communityGeneration")]
community_generation: u64,
},
}
@@ -614,6 +616,23 @@ pub fn update_tray_agent_activity<R: Runtime>(
mod tests {
use super::{requeue_actions, TrayAction, TrayActionQueue};
#[test]
fn open_channel_action_serializes_with_frontend_field_names() {
let action = TrayAction::OpenChannel {
channel_id: "channel-123".into(),
community_generation: 7,
};
assert_eq!(
serde_json::to_value(action).expect("tray action should serialize"),
serde_json::json!({
"kind": "openChannel",
"channelId": "channel-123",
"communityGeneration": 7,
})
);
}
#[test]
fn stale_channel_actions_are_not_requeued_after_community_change() {
let mut queue = TrayActionQueue {