11//! Soft dialog tracking for MCP context tools.
22//!
3- //! Tracks in-page overlay dialogs (about, license, copy-confirmation, mkdir-confirmation ).
3+ //! Tracks in-page overlay dialogs (about, license, copy-confirmation, etc. ).
44//! Window-based dialogs (settings, file viewers) are derived from Tauri's window manager
55//! in resources.rs — no manual tracking needed for those.
6+ //!
7+ //! The frontend registers all known soft dialog IDs at startup via
8+ //! `register_known_dialogs`, so the MCP "available dialogs" resource
9+ //! stays in sync with the actual Svelte components automatically.
610
711use std:: collections:: HashSet ;
812use std:: sync:: RwLock ;
13+ use serde:: Deserialize ;
914use tauri:: { AppHandle , Manager } ;
1015
11- /// Tracks which soft (overlay) dialogs are currently open.
12- /// Uses a simple set of dialog type strings.
16+ /// A dialog type registered by the frontend at startup.
17+ #[ derive( Debug , Clone , Deserialize ) ]
18+ pub struct KnownDialog {
19+ pub id : String ,
20+ pub description : Option < String > ,
21+ }
22+
23+ /// Tracks which soft (overlay) dialogs are currently open,
24+ /// and which dialog types are known (registered at startup).
1325#[ derive( Debug , Default ) ]
1426pub struct SoftDialogTracker {
1527 open : RwLock < HashSet < String > > ,
28+ known : RwLock < Vec < KnownDialog > > ,
1629}
1730
1831impl SoftDialogTracker {
1932 pub fn new ( ) -> Self {
2033 Self {
2134 open : RwLock :: new ( HashSet :: new ( ) ) ,
35+ known : RwLock :: new ( Vec :: new ( ) ) ,
2236 }
2337 }
2438
@@ -33,6 +47,14 @@ impl SoftDialogTracker {
3347 pub fn get_open_types ( & self ) -> Vec < String > {
3448 self . open . read ( ) . unwrap ( ) . iter ( ) . cloned ( ) . collect ( )
3549 }
50+
51+ pub fn register_known ( & self , dialogs : Vec < KnownDialog > ) {
52+ * self . known . write ( ) . unwrap ( ) = dialogs;
53+ }
54+
55+ pub fn get_known_dialogs ( & self ) -> Vec < KnownDialog > {
56+ self . known . read ( ) . unwrap ( ) . clone ( )
57+ }
3658}
3759
3860/// Tauri command: frontend notifies that a soft dialog opened.
@@ -51,6 +73,14 @@ pub fn notify_dialog_closed(app: AppHandle, dialog_type: String) {
5173 }
5274}
5375
76+ /// Tauri command: frontend registers all known soft dialog types at startup.
77+ #[ tauri:: command]
78+ pub fn register_known_dialogs ( app : AppHandle , dialogs : Vec < KnownDialog > ) {
79+ if let Some ( tracker) = app. try_state :: < SoftDialogTracker > ( ) {
80+ tracker. register_known ( dialogs) ;
81+ }
82+ }
83+
5484#[ cfg( test) ]
5585mod tests {
5686 use super :: * ;
@@ -87,4 +117,41 @@ mod tests {
87117 tracker. close ( "nonexistent" ) ; // Should not panic
88118 assert ! ( tracker. get_open_types( ) . is_empty( ) ) ;
89119 }
120+
121+ #[ test]
122+ fn test_register_known_dialogs ( ) {
123+ let tracker = SoftDialogTracker :: new ( ) ;
124+ assert ! ( tracker. get_known_dialogs( ) . is_empty( ) ) ;
125+
126+ let dialogs = vec ! [
127+ KnownDialog { id: "about" . to_string( ) , description: None } ,
128+ KnownDialog { id: "alert" . to_string( ) , description: None } ,
129+ KnownDialog {
130+ id: "copy-confirmation" . to_string( ) ,
131+ description: Some ( "Opened by the copy tool" . to_string( ) ) ,
132+ } ,
133+ ] ;
134+ tracker. register_known ( dialogs) ;
135+
136+ let known = tracker. get_known_dialogs ( ) ;
137+ assert_eq ! ( known. len( ) , 3 ) ;
138+ assert_eq ! ( known[ 0 ] . id, "about" ) ;
139+ assert_eq ! ( known[ 2 ] . description. as_deref( ) , Some ( "Opened by the copy tool" ) ) ;
140+ }
141+
142+ #[ test]
143+ fn test_register_known_replaces_previous ( ) {
144+ let tracker = SoftDialogTracker :: new ( ) ;
145+
146+ tracker. register_known ( vec ! [
147+ KnownDialog { id: "about" . to_string( ) , description: None } ,
148+ ] ) ;
149+ assert_eq ! ( tracker. get_known_dialogs( ) . len( ) , 1 ) ;
150+
151+ tracker. register_known ( vec ! [
152+ KnownDialog { id: "about" . to_string( ) , description: None } ,
153+ KnownDialog { id: "alert" . to_string( ) , description: None } ,
154+ ] ) ;
155+ assert_eq ! ( tracker. get_known_dialogs( ) . len( ) , 2 ) ;
156+ }
90157}
0 commit comments