@@ -109,6 +109,7 @@ mod imp {
109109 pub list : RefCell < Vec < Terminal > > ,
110110 pub custom_list_path : PathBuf ,
111111 pub command_runner : OnceCell < CommandRunner > ,
112+ pub json_terminals_query : Query < Vec < Terminal > > ,
112113 pub flatpak_terminals_query : Query < Vec < Terminal > > ,
113114 }
114115
@@ -119,6 +120,7 @@ mod imp {
119120 list : RefCell :: new ( vec ! [ ] ) ,
120121 custom_list_path,
121122 command_runner : OnceCell :: new ( ) ,
123+ json_terminals_query : Query :: new ( "json_terminals" . into ( ) , || async { Ok ( vec ! [ ] ) } ) ,
122124 flatpak_terminals_query : Query :: new ( "flatpak_terminals" . into ( ) , || async {
123125 Ok ( vec ! [ ] )
124126 } ) ,
@@ -154,30 +156,48 @@ impl TerminalRepository {
154156 . unwrap ( ) ;
155157
156158 let mut list = SUPPORTED_TERMINALS . clone ( ) ;
157- if let Ok ( loaded_list) = Self :: load_terminals_from_json ( & this. imp ( ) . custom_list_path ) {
158- list. extend ( loaded_list) ;
159- } else {
160- warn ! (
161- "Failed to load custom terminals from JSON file {:?}" ,
162- & this. imp( ) . custom_list_path
163- ) ;
164- }
165-
166159 list. sort_by ( |a, b| a. name . cmp ( & b. name ) ) ;
167160 this. imp ( ) . list . replace ( list) ;
168161
162+ // Set up the json terminals query fetcher
163+ let custom_list_path = this. imp ( ) . custom_list_path . clone ( ) ;
164+ this. imp ( ) . json_terminals_query . set_fetcher ( move || {
165+ let custom_list_path = custom_list_path. clone ( ) ;
166+ async move {
167+ match Self :: load_terminals_from_json ( & custom_list_path) {
168+ Ok ( terminals) => Ok ( terminals) ,
169+ Err ( e) if !custom_list_path. exists ( ) => Ok ( vec ! [ ] ) ,
170+ Err ( e) => {
171+ warn ! (
172+ "Failed to load custom terminals from JSON file {:?}: {}" ,
173+ custom_list_path,
174+ e
175+ ) ;
176+ Err ( e)
177+ }
178+ }
179+ }
180+ } ) ;
181+
169182 // Set up the flatpak terminals query fetcher
170183 let runner = command_runner. clone ( ) ;
171184 this. imp ( ) . flatpak_terminals_query . set_fetcher ( move || {
172185 let runner = runner. clone ( ) ;
173186 async move { Self :: fetch_flatpak_terminals ( & runner) . await }
174187 } ) ;
175188
189+ let this_clone = this. clone ( ) ;
190+ this. json_terminals_query ( ) . connect_success ( move |terminals| {
191+ this_clone. apply_custom_terminals ( terminals. clone ( ) ) ;
192+ this_clone. emit_by_name :: < ( ) > ( "terminals-changed" , & [ ] ) ;
193+ } ) ;
194+
176195 // Connect to query success to update the terminal list
177196 let this_clone = this. clone ( ) ;
178197 this. flatpak_terminals_query ( )
179198 . connect_success ( move |terminals| {
180- this_clone. merge_flatpak_terminals ( terminals. clone ( ) ) ;
199+ this_clone. apply_flatpak_terminals ( terminals. clone ( ) ) ;
200+ this_clone. emit_by_name :: < ( ) > ( "terminals-changed" , & [ ] ) ;
181201 } ) ;
182202
183203 this
@@ -205,27 +225,42 @@ impl TerminalRepository {
205225 Ok ( found_terminals)
206226 }
207227
208- fn merge_flatpak_terminals ( & self , terminals : Vec < Terminal > ) {
209- if terminals. is_empty ( ) {
210- return ;
211- }
228+ fn apply_custom_terminals ( & self , terminals : Vec < Terminal > ) {
229+ let mut list = self . imp ( ) . list . borrow_mut ( ) ;
230+ list. retain ( |terminal| terminal. read_only ) ;
231+ list. extend ( terminals. into_iter ( ) . map ( |mut terminal| {
232+ terminal. read_only = false ;
233+ terminal
234+ } ) ) ;
235+ list. sort_by ( |a, b| a. name . cmp ( & b. name ) ) ;
236+ }
212237
238+ fn apply_flatpak_terminals ( & self , terminals : Vec < Terminal > ) {
213239 let mut list = self . imp ( ) . list . borrow_mut ( ) ;
214- // Build a set of existing terminal identifiers to avoid duplicates
215- let existing_ids: HashSet < String > = list. iter ( ) . map ( |t| t. full_command_id ( ) ) . collect ( ) ;
216240
217- // Only add terminals that don't already exist
241+ let flatpak_candidate_ids: HashSet < String > = FLATPAK_TERMINAL_CANDIDATES
242+ . iter ( )
243+ . map ( |terminal| terminal. full_command_id ( ) )
244+ . collect ( ) ;
245+ list. retain ( |terminal| !flatpak_candidate_ids. contains ( & terminal. full_command_id ( ) ) ) ;
246+
247+ let existing_ids: HashSet < String > = list. iter ( ) . map ( |t| t. full_command_id ( ) ) . collect ( ) ;
218248 let new_terminals: Vec < Terminal > = terminals
219249 . into_iter ( )
220250 . filter ( |t| !existing_ids. contains ( & t. full_command_id ( ) ) )
221251 . collect ( ) ;
222252
223- if !new_terminals. is_empty ( ) {
224- list. extend ( new_terminals) ;
225- list. sort_by ( |a, b| a. name . cmp ( & b. name ) ) ;
226- drop ( list) ;
227- self . emit_by_name :: < ( ) > ( "terminals-changed" , & [ ] ) ;
228- }
253+ list. extend ( new_terminals) ;
254+ list. sort_by ( |a, b| a. name . cmp ( & b. name ) ) ;
255+ }
256+
257+ pub fn load_all ( & self ) {
258+ self . json_terminals_query ( ) . refetch ( ) ;
259+ self . flatpak_terminals_query ( ) . refetch ( ) ;
260+ }
261+
262+ pub fn json_terminals_query ( & self ) -> Query < Vec < Terminal > > {
263+ self . imp ( ) . json_terminals_query . clone ( )
229264 }
230265
231266 pub fn flatpak_terminals_query ( & self ) -> Query < Vec < Terminal > > {
0 commit comments